From 7712b59706923b7fc323ba19f7dfde3aa37610ef Mon Sep 17 00:00:00 2001 From: Frank Shaka Date: Thu, 19 Oct 2017 15:04:05 +0800 Subject: [PATCH 01/10] Release 3.7.1.201612151837 --- bundles/org.xmind.cathy.fonts/.gitignore | 30 +- bundles/org.xmind.cathy.fonts/.project | 44 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../META-INF/MANIFEST.MF | 12 +- .../OSGI-INF/l10n/bundle.properties | 4 +- bundles/org.xmind.cathy.fonts/README | 6 +- bundles/org.xmind.cathy.fonts/about.html | 40 +- .../org.xmind.cathy.fonts/build.properties | 4 +- bundles/org.xmind.cathy.fonts/pom.xml | 32 +- bundles/org.xmind.cathy.win32/.classpath | 24 +- bundles/org.xmind.cathy.win32/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 26 +- bundles/org.xmind.cathy.win32/about.html | 44 +- .../fragment_win32.properties | 4 +- bundles/org.xmind.cathy.win32/pom.xml | 72 +- .../xmind/cathy/internal/win32/Startup.java | 204 +- bundles/org.xmind.cathy/.classpath | 40 +- bundles/org.xmind.cathy/.gitignore | 30 +- bundles/org.xmind.cathy/.options | 6 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- bundles/org.xmind.cathy/Application.e4xmi | 170 +- bundles/org.xmind.cathy/META-INF/MANIFEST.MF | 106 +- .../OSGI-INF/l10n/bundle.properties | 207 +- .../OSGI-INF/serviceManager.xml | 14 +- bundles/org.xmind.cathy/about.html | 44 +- bundles/org.xmind.cathy/about.mappings | 14 +- bundles/org.xmind.cathy/build.properties | 36 +- bundles/org.xmind.cathy/css/default.css | 392 +- bundles/org.xmind.cathy/css/default_gtk.css | 54 +- bundles/org.xmind.cathy/css/default_mac.css | 52 +- bundles/org.xmind.cathy/css/default_win.css | 54 +- bundles/org.xmind.cathy/css/default_win7.css | 54 +- bundles/org.xmind.cathy/css/default_win8.css | 54 +- bundles/org.xmind.cathy/dashboard/back.png | Bin 1582 -> 968 bytes bundles/org.xmind.cathy/dashboard/back@2x.png | Bin 4278 -> 2557 bytes .../dashboard/dashboard.properties | 13 +- .../org.xmind.cathy/dashboard/dashboard.xml | 99 +- .../dashboard/new/structures.properties | 32 +- .../dashboard/new/structures.xml | 198 +- .../icons/toolbar/d/dashboard.png | Bin 986 -> 971 bytes .../icons/toolbar/d/dashboard@2x.png | Bin 2218 -> 2241 bytes .../icons/toolbar/d/export.png | Bin 668 -> 662 bytes .../icons/toolbar/d/export@2x.png | Bin 1299 -> 1459 bytes .../org.xmind.cathy/icons/toolbar/d/redo.png | Bin 821 -> 761 bytes .../org.xmind.cathy/icons/toolbar/d/save.png | Bin 574 -> 629 bytes .../icons/toolbar/d/save@2x.png | Bin 1117 -> 1613 bytes .../org.xmind.cathy/icons/toolbar/d/undo.png | Bin 855 -> 860 bytes .../icons/toolbar/d/undo@2x.png | Bin 1596 -> 1701 bytes .../icons/toolbar/e/dashboard.png | Bin 1036 -> 1066 bytes .../icons/toolbar/e/dashboard@2x.png | Bin 2523 -> 2628 bytes .../icons/toolbar/e/export.png | Bin 732 -> 740 bytes .../icons/toolbar/e/export@2x.png | Bin 1665 -> 1865 bytes .../org.xmind.cathy/icons/toolbar/e/redo.png | Bin 867 -> 790 bytes .../org.xmind.cathy/icons/toolbar/e/save.png | Bin 632 -> 700 bytes .../icons/toolbar/e/save@2x.png | Bin 1704 -> 1979 bytes bundles/org.xmind.cathy/plugin.properties | 146 +- bundles/org.xmind.cathy/plugin.xml | 2624 ++-- bundles/org.xmind.cathy/pom.xml | 32 +- .../org.xmind.cathy/resource/langs.properties | 30 +- .../internal/AbstractCheckFilesProcess.java | 190 +- .../cathy/internal/AutoBackupIndicator.java | 574 +- .../AutoBackupIndicatorToolControl.java | 482 +- .../xmind/cathy/internal/AutoSaveService.java | 176 +- .../xmind/cathy/internal/BetaVerifier.java | 244 +- .../cathy/internal/CathyApplication.java | 605 +- .../org/xmind/cathy/internal/CathyPlugin.java | 1060 +- .../cathy/internal/CathyPrefInitializer.java | 108 +- .../cathy/internal/CathySplashHandler.java | 278 +- .../cathy/internal/CathyStatusHandler.java | 328 +- .../internal/CathyWorkbenchActionBuilder.java | 354 +- .../cathy/internal/CathyWorkbenchAdvisor.java | 837 +- .../internal/CathyWorkbenchWindowAdvisor.java | 708 +- .../cathy/internal/CheckOpenFilesProcess.java | 70 +- .../cathy/internal/CommandLabelUpdater.java | 444 +- .../xmind/cathy/internal/ConstantsHacker.java | 36 +- .../internal/EditorStatePersistance.java | 616 +- .../xmind/cathy/internal/GeneralPrefPage.java | 1232 +- .../GeneralPreferencePageSection.java | 436 +- .../cathy/internal/HandledItemMatcher.java | 52 +- .../cathy/internal/IApplicationValidator.java | 38 +- .../xmind/cathy/internal/ICathyConstants.java | 256 +- .../src/org/xmind/cathy/internal/ILogger.java | 124 +- .../cathy/internal/LanguagePrefPage.java | 748 +- .../LanguagePreferencePageSection.java | 696 +- .../cathy/internal/LicenseAgentProxy.java | 260 +- .../src/org/xmind/cathy/internal/Log.java | 416 +- .../cathy/internal/OpenDocumentQueue.java | 168 +- .../internal/OpenFileCommandHandler.java | 106 +- .../cathy/internal/OpenFilesProcess.java | 396 +- .../internal/RecentFilePropertyTester.java | 80 +- .../RecentFilesPreferencePageSection.java | 136 +- .../SaveBackupPreferencePageSection.java | 262 +- .../internal/SaveCommandLabelUpdater.java | 524 +- .../xmind/cathy/internal/ServiceManager.java | 250 +- .../cathy/internal/ShowWelcomeService.java | 174 +- .../xmind/cathy/internal/StartUpProcess.java | 442 +- .../StartupPreferencePageSection.java | 298 +- .../internal/UndoRedoActionToolControl.java | 254 +- .../xmind/cathy/internal/WelcomeDialog.java | 1106 +- .../cathy/internal/WindowPropertyTester.java | 88 +- .../cathy/internal/WorkbenchMessages.java | 446 +- ...SSPropertyCTabFolderRenderNoneHandler.java | 84 +- ...SSPropertyCTabFolderToolBarSWTHandler.java | 162 +- .../css/CSSPropertyFormHeadingHandler.java | 172 +- .../css/CSSPropertyFormTextHandler.java | 96 +- .../css/CSSPropertyHoverTabSWTHandler.java | 126 +- .../css/CSSPropertyMTabBarHandler.java | 80 +- .../css/CSSPropertyMTabFolderHandler.java | 80 +- .../css/CSSPropertyMarginXHandler.java | 284 +- .../CSSPropertyMaxMinVisibleSWTHandler.java | 216 +- .../css/CSSPropertyScrolledFormHandler.java | 88 +- .../css/CSSPropertySectionHandler.java | 108 +- .../CSSPropertySelectedTabAreaSWTHandler.java | 126 +- ...CSSPropertyTabBorderVisibleSWTHandler.java | 94 +- ...SPropertyTabIconTextVisibleSWTHandler.java | 82 +- .../css/CSSPropertyToolBarSWTHandler.java | 174 +- ...PropertyUnselectedTabsColorSWTHandler.java | 252 +- ...tyUnselectedTabsFillVisibleSWTHandler.java | 86 +- .../css/CSSPropertyXShowCloseHandler.java | 298 +- .../css/CathyCTabFolderRendering.java | 3903 +++--- .../internal/css/FormHeadingElement.java | 28 +- .../cathy/internal/css/FormTextElement.java | 28 +- .../internal/css/ICTabFolderRendering.java | 76 +- .../cathy/internal/css/MTabBarElement.java | 28 +- .../cathy/internal/css/MTabFolderElement.java | 28 +- .../cathy/internal/css/ReflectionSupport.java | 172 +- .../cathy/internal/css/SashWidthHandler.java | 142 +- .../internal/css/ScrolledFormElement.java | 26 +- .../cathy/internal/css/SectionElement.java | 28 +- .../internal/css/XSWTElementProvider.java | 58 +- .../dashboard/CategorizedTemplateViewer.java | 782 +- .../dashboard/DashboardAutomationAddon.java | 620 +- .../internal/dashboard/DashboardContent.java | 851 +- .../internal/dashboard/DashboardPart.java | 944 +- .../dashboard/DashboardStyleProvider.java | 248 +- .../dashboard/NewFileDashboardPage.java | 912 +- .../NewFromStructuresDashboardPage.java | 327 +- .../NewFromTemplatesDashboardPage.java | 349 +- .../dashboard/RecentContainerLayout.java | 212 +- .../dashboard/RecentFileBlankPage.java | 162 +- .../RecentFileGridDashboardPage.java | 240 +- .../dashboard/RecentFileGridPage.java | 336 +- .../internal/dashboard/RecentFileViewer.java | 420 +- .../dashboard/RecentFilesContentProvider.java | 254 +- .../RecentFilesGalleryPartFactory.java | 280 +- .../dashboard/RecentFilesLabelProvider.java | 482 +- .../StructureListContentProvider.java | 620 +- .../dashboard/TemplatePropertyTester.java | 64 +- .../dashboard/ThemeChooserDialog.java | 334 +- .../handlers/ClearRecentFileHandler.java | 48 +- .../handlers/DeleteRecentFileHandler.java | 48 +- .../handlers/DeleteTemplateHandler.java | 82 +- .../handlers/DuplicateTemplateHandler.java | 60 +- .../handlers/HideDashboardHandler.java | 48 +- .../internal/handlers/NewWizardHandler.java | 54 +- .../handlers/PinRecentFileHanlder.java | 46 +- .../handlers/RenameTemplateHandler.java | 46 +- .../handlers/ShowAllPreferencesHandler.java | 64 +- .../handlers/ShowCloudPageHandler.java | 60 +- .../handlers/ShowDashboardPageHandler.java | 54 +- .../handlers/ToggleDashboardHandler.java | 40 +- .../handlers/UnpinRecentFileHandler.java | 46 +- .../handlers/WelcomeToXMindHandler.java | 91 +- .../internal/handlers/XMindHelpHandler.java | 90 +- .../internal/jobs/AbstractCheckFilesJob.java | 272 +- .../internal/jobs/DownloadAndOpenFileJob.java | 522 +- .../cathy/internal/jobs/OpenFilesJob.java | 554 +- .../jobs/OpenXMindCommandFileJob.java | 278 +- .../xmind/cathy/internal/messages.properties | 360 +- .../internal/renderer/XDialogRenderer.java | 926 +- .../renderer/XEditorStackRenderer.java | 131 + .../renderer/XMenuManagerRenderer.java | 130 +- .../renderer/XRightStackRenderer.java | 116 - .../renderer/XRightTrimBarLayout.java | 254 +- .../cathy/internal/renderer/XSashLayout.java | 382 +- .../internal/renderer/XSashRenderer.java | 346 +- .../internal/renderer/XStackRenderer.java | 243 +- .../renderer/XToolBarManagerRenderer.java | 260 +- .../internal/renderer/XTrimmedPartLayout.java | 436 +- .../cathy/internal/renderer/XWBWRenderer.java | 446 +- .../renderer/XWorkbenchRendererFactory.java | 155 +- .../workbench/addons/minmax/MinMaxAddon.java | 1600 +-- .../workbench/addons/minmax/XTrimStack.java | 1216 +- .../internal/e4handlers/DisabledHandler.java | 132 +- .../e4handlers/HideDashboardHandler.java | 42 +- .../e4handlers/ShowDashboardPageHandler.java | 144 +- .../e4handlers/ToggleDashboardHandler.java | 54 +- .../internal/e4handlers/XResourceHandler.java | 710 +- .../thirdPartySoftwareProviders.txt | 26 +- .../org.xmind.core.command.remote/.classpath | 22 +- .../org.xmind.core.command.remote/.gitignore | 30 +- .../org.xmind.core.command.remote/.options | 10 +- .../org.xmind.core.command.remote/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 644 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../META-INF/MANIFEST.MF | 32 +- .../org.xmind.core.command.remote/about.html | 44 +- .../build.properties | 18 +- .../plugin.properties | 8 +- .../org.xmind.core.command.remote/plugin.xml | 12 +- bundles/org.xmind.core.command.remote/pom.xml | 32 +- .../schema/domains.exsd | 368 +- .../AbstractCommandServerAdvertiser.java | 132 +- ...bstractRemoteCommandServiceDiscoverer.java | 308 +- .../command/remote/CommandServiceInfo.java | 286 +- .../core/command/remote/ICommandServer.java | 156 +- .../remote/ICommandServerAdvertiser.java | 154 +- .../command/remote/ICommandServiceDomain.java | 180 +- .../remote/ICommandServiceDomainDirector.java | 156 +- .../remote/ICommandServiceDomainManager.java | 94 +- .../command/remote/ICommandServiceInfo.java | 216 +- .../core/command/remote/IDomainService.java | 74 +- .../command/remote/IDomainServiceFactory.java | 58 +- .../core/command/remote/IIdentifier.java | 118 +- .../command/remote/IRemoteCommandService.java | 140 +- .../IRemoteCommandServiceDiscoverer.java | 210 +- .../remote/IRemoteCommandServiceListener.java | 90 +- .../xmind/core/command/remote/Identifier.java | 176 +- .../xmind/core/command/remote/Options.java | 160 +- .../core/command/remote/RemoteCommandJob.java | 238 +- .../command/remote/socket/ISocketAddress.java | 76 +- .../socket/IncomingSocketCommandHandler.java | 308 +- .../socket/OutgoingSocketCommandHandler.java | 378 +- .../command/remote/socket/SocketAddress.java | 162 +- .../remote/socket/SocketCommandServer.java | 734 +- .../socket/SocketCommandServiceInfo.java | 154 +- .../command/remote/socket/SocketPool.java | 140 +- .../core/command/transfer/ChunkReader.java | 746 +- .../core/command/transfer/ChunkWriter.java | 470 +- .../command/transfer/CommandTransferUtil.java | 298 +- .../transfer/IncomingCommandHandler.java | 676 +- .../transfer/OutgoingCommandHandler.java | 740 +- .../remote/CommandServiceDomainImpl.java | 332 +- .../CommandServiceDomainManagerImpl.java | 400 +- .../DefaultCommandServiceDomainDirector.java | 532 +- .../remote/IDomainsExtensionConstants.java | 88 +- .../internal/command/remote/Messages.java | 82 +- .../command/remote/NullDomainService.java | 288 +- .../command/remote/RemoteCommandPlugin.java | 208 +- .../command/remote/messages.properties | 46 +- bundles/org.xmind.core.command/.classpath | 14 +- bundles/org.xmind.core.command/.gitignore | 30 +- bundles/org.xmind.core.command/.options | 2 +- bundles/org.xmind.core.command/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 820 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 6 +- .../org.eclipse.ltk.core.refactoring.prefs | 4 +- .../META-INF/MANIFEST.MF | 30 +- bundles/org.xmind.core.command/about.html | 44 +- .../org.xmind.core.command/build.properties | 20 +- .../org.xmind.core.command/plugin.properties | 6 +- bundles/org.xmind.core.command/plugin.xml | 10 +- bundles/org.xmind.core.command/pom.xml | 32 +- .../schema/handlers.exsd | 230 +- .../src/org/xmind/core/command/Command.java | 446 +- .../org/xmind/core/command/CommandJob.java | 92 +- .../src/org/xmind/core/command/ICommand.java | 194 +- .../xmind/core/command/ICommandHandler.java | 98 +- .../xmind/core/command/ICommandService.java | 220 +- .../core/command/IReturnValueConsumer.java | 80 +- .../org/xmind/core/command/ReturnValue.java | 244 +- .../core/command/XMindCommandCenter.java | 98 +- .../core/command/arguments/ArrayMapper.java | 566 +- .../core/command/arguments/Attributes.java | 326 +- .../core/command/binary/BinaryStore.java | 432 +- .../core/command/binary/ByteArrayEntry.java | 100 +- .../xmind/core/command/binary/FileEntry.java | 96 +- .../core/command/binary/IBinaryEntry.java | 156 +- .../command/binary/IBinaryEntryDelegate.java | 40 +- .../core/command/binary/IBinaryStore.java | 300 +- .../core/command/binary/INamedEntry.java | 40 +- .../xmind/core/command/binary/NamedEntry.java | 102 +- .../core/internal/command/BinaryUtil.java | 68 +- .../xmind/core/internal/command/Logger.java | 90 +- .../xmind/core/internal/command/Messages.java | 58 +- .../command/XMindCommandHandlerRegistry.java | 464 +- .../internal/command/XMindCommandPlugin.java | 290 +- .../internal/command/XMindCommandService.java | 384 +- .../core/internal/command/messages.properties | 16 +- bundles/org.xmind.core.io/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../org.xmind.core.io/META-INF/MANIFEST.MF | 28 +- bundles/org.xmind.core.io/about.html | 44 +- bundles/org.xmind.core.io/plugin.properties | 4 +- bundles/org.xmind.core.io/pom.xml | 32 +- .../core/io/ResourceMappingConstants.java | 48 +- .../xmind/core/io/ResourceMappingManager.java | 304 +- .../core/io/freemind/FreeMindConstants.java | 38 +- bundles/org.xmind.core.licensing/.classpath | 14 +- bundles/org.xmind.core.licensing/.gitignore | 30 +- bundles/org.xmind.core.licensing/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 832 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../org.eclipse.ltk.core.refactoring.prefs | 4 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 16 +- bundles/org.xmind.core.licensing/about.html | 44 +- .../org.xmind.core.licensing/build.properties | 8 +- bundles/org.xmind.core.licensing/pom.xml | 32 +- .../xmind/core/licensing/ILicenseAgent.java | 146 +- .../licensing/ILicenseChangedListener.java | 54 +- .../core/licensing/ILicenseKeyHeader.java | 452 +- bundles/org.xmind.core.net/.classpath | 14 +- bundles/org.xmind.core.net/.gitignore | 30 +- bundles/org.xmind.core.net/.options | 6 +- bundles/org.xmind.core.net/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 822 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../org.eclipse.ltk.core.refactoring.prefs | 4 +- .../org.xmind.core.net/META-INF/MANIFEST.MF | 28 +- .../OSGI-INF/l10n/bundle.properties | 4 +- bundles/org.xmind.core.net/build.properties | 10 +- bundles/org.xmind.core.net/pom.xml | 32 +- .../src/org/xmind/core/net/Entity.java | 60 +- .../src/org/xmind/core/net/Field.java | 136 +- .../src/org/xmind/core/net/FieldSet.java | 598 +- .../src/org/xmind/core/net/IDataStore.java | 134 +- .../src/org/xmind/core/net/JSONStore.java | 230 +- .../org/xmind/core/net/http/FileEntity.java | 124 +- .../org/xmind/core/net/http/FormEntity.java | 232 +- .../org/xmind/core/net/http/HttpEntity.java | 154 +- .../xmind/core/net/http/HttpEntityProxy.java | 144 +- .../xmind/core/net/http/HttpException.java | 156 +- .../org/xmind/core/net/http/HttpRequest.java | 1797 ++- .../xmind/core/net/http/IResponseHandler.java | 64 +- .../org/xmind/core/net/http/JSONEntity.java | 198 +- .../xmind/core/net/http/MultipartEntity.java | 478 +- .../xmind/core/net/http/StreamedEntity.java | 174 +- .../net/http/StreamedResponseHandler.java | 104 +- .../xmind/core/net/internal/Activator.java | 258 +- .../core/net/internal/EncodingUtils.java | 336 +- .../net/internal/FixedLengthInputStream.java | 260 +- .../IRequestStatusChangeListener.java | 44 +- .../net/internal/LoggingOutputStream.java | 274 +- .../net/internal/MonitoredInputStream.java | 202 +- .../net/internal/MonitoredOutputStream.java | 164 +- .../core/net/internal/TeeInputStream.java | 158 +- .../core/net/internal/TeeOutputStream.java | 158 +- .../core/net/internal/XMindNetRequest.java | 2732 ++--- bundles/org.xmind.core.runtime/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../META-INF/MANIFEST.MF | 46 +- bundles/org.xmind.core.runtime/about.html | 44 +- .../org.xmind.core.runtime/plugin.properties | 4 +- bundles/org.xmind.core.runtime/plugin.xml | 76 +- bundles/org.xmind.core.runtime/pom.xml | 32 +- .../xmind/core/internal/CoreAxisProvider.java | 280 +- .../core/internal/StylePropertyTester.java | 96 +- .../core/internal/TopicPropertyTester.java | 698 +- .../org/xmind/core/internal/XmindCore.java | 144 +- .../runtime/BundleResourceFinder.java | 182 +- .../core/internal/runtime/RuntimeLogger.java | 120 +- .../internal/runtime/WorkspaceConfigurer.java | 240 +- .../internal/runtime/WorkspaceSession.java | 388 +- .../xmind/core/internal/security/Base64.java | 476 +- .../internal/security/PKCS12KeyGenerator.java | 476 +- .../security/PasswordProtectedNormalizer.java | 626 +- .../xmind/core/internal/xpath/Evaluator.java | 1806 +-- .../core/internal/xpath/IAxisProvider.java | 30 +- .../src/org/xmind/core/io/BundleResource.java | 210 +- .../core/io/BundleResourceInputSource.java | 288 +- .../org/xmind/core/util/ProgressReporter.java | 126 +- bundles/org.xmind.core.usagedata/.classpath | 14 +- bundles/org.xmind.core.usagedata/.gitignore | 30 +- bundles/org.xmind.core.usagedata/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 808 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 19 +- bundles/org.xmind.core.usagedata/about.html | 44 +- .../org.xmind.core.usagedata/build.properties | 10 +- bundles/org.xmind.core.usagedata/pom.xml | 32 +- .../core/internal/UserDataConstants.java | 246 + .../core/usagedata/IUsageDataSampler.java | 238 +- .../core/usagedata/IUsageDataUploader.java | 60 +- bundles/org.xmind.core/.classpath | 14 +- bundles/org.xmind.core/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 830 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 112 +- bundles/org.xmind.core/META-INF/MANIFEST.MF | 40 +- bundles/org.xmind.core/about.html | 44 +- bundles/org.xmind.core/plugin.properties | 4 +- bundles/org.xmind.core/pom.xml | 32 +- .../src/org/xmind/core/Core.java | 2376 ++-- .../src/org/xmind/core/IAdaptable.java | 88 +- .../src/org/xmind/core/IBoundary.java | 48 +- .../src/org/xmind/core/IComment.java | 144 +- .../src/org/xmind/core/ICommentManager.java | 272 +- .../src/org/xmind/core/IDeserializer.java | 330 +- .../src/org/xmind/core/IEncryptionData.java | 186 +- .../xmind/core/IEntryStreamNormalizer.java | 174 +- .../src/org/xmind/core/IExtensionElement.java | 86 +- .../src/org/xmind/core/IFileEntry.java | 440 +- .../src/org/xmind/core/IFileEntryFilter.java | 28 +- .../src/org/xmind/core/IHtmlNotesContent.java | 66 +- .../src/org/xmind/core/IIdFactory.java | 38 +- .../src/org/xmind/core/IIdentifiable.java | 38 +- .../src/org/xmind/core/IImageSpan.java | 42 +- .../src/org/xmind/core/IManifest.java | 518 +- .../src/org/xmind/core/IMeta.java | 230 +- .../src/org/xmind/core/IModifiable.java | 54 +- .../src/org/xmind/core/INamed.java | 42 +- .../src/org/xmind/core/IParagraph.java | 40 +- .../org/xmind/core/IPlainNotesContent.java | 42 +- .../src/org/xmind/core/IPositioned.java | 82 +- .../src/org/xmind/core/IRelationship.java | 142 +- .../src/org/xmind/core/IRelationshipEnd.java | 42 +- .../src/org/xmind/core/IResourceRef.java | 80 +- .../src/org/xmind/core/IRevision.java | 194 +- .../src/org/xmind/core/IRevisionManager.java | 328 +- .../src/org/xmind/core/ISerializer.java | 322 +- .../org/xmind/core/ISerializerFactory.java | 62 +- .../src/org/xmind/core/ISerializingBase.java | 184 +- .../src/org/xmind/core/ISettingEntry.java | 40 +- .../src/org/xmind/core/ISheet.java | 192 +- .../src/org/xmind/core/ISheetComponent.java | 38 +- .../src/org/xmind/core/ISheetSetting.java | 28 +- .../src/org/xmind/core/ISheetSettings.java | 76 +- .../src/org/xmind/core/ISpan.java | 38 +- .../src/org/xmind/core/ISpanList.java | 26 +- .../src/org/xmind/core/ITextSpan.java | 42 +- .../src/org/xmind/core/ITopic.java | 584 +- .../src/org/xmind/core/ITopicComponent.java | 38 +- .../xmind/core/ITopicExtensionElement.java | 44 +- .../src/org/xmind/core/ITopicRange.java | 46 +- .../src/org/xmind/core/IWorkbook.java | 912 +- .../src/org/xmind/core/IWorkbookBuilder.java | 1034 +- .../org/xmind/core/IWorkbookComponent.java | 84 +- .../org/xmind/core/IWorkbookExtension.java | 44 +- .../xmind/core/IWorkbookExtensionElement.java | 38 +- .../xmind/core/IWorkbookExtensionManager.java | 40 +- .../src/org/xmind/core/IWorkspace.java | 296 +- .../src/org/xmind/core/event/CoreEvent.java | 344 +- .../xmind/core/event/ICoreEventListener.java | 72 +- .../core/event/ICoreEventRegistration.java | 62 +- .../xmind/core/event/ICoreEventSource.java | 70 +- .../xmind/core/event/ICoreEventSource2.java | 54 +- .../xmind/core/event/ICoreEventSupport.java | 94 +- .../internal/AbstractSerializingBase.java | 132 +- .../internal/AbstractWorkbookBuilder.java | 642 +- .../internal/AbstractWorkbookComponent.java | 34 +- .../src/org/xmind/core/internal/Boundary.java | 232 +- .../org/xmind/core/internal/ControlPoint.java | 38 +- .../xmind/core/internal/EncryptionData.java | 64 +- .../org/xmind/core/internal/FileEntry.java | 88 +- .../core/internal/ICloneDataListener.java | 42 +- .../org/xmind/core/internal/IDFactory.java | 98 +- .../src/org/xmind/core/internal/Image.java | 60 +- .../org/xmind/core/internal/InternalCore.java | 294 +- .../xmind/core/internal/MarkerVariation.java | 78 +- .../src/org/xmind/core/internal/Meta.java | 38 +- .../src/org/xmind/core/internal/MetaData.java | 48 +- .../org/xmind/core/internal/Relationship.java | 212 +- .../src/org/xmind/core/internal/Revision.java | 78 +- .../xmind/core/internal/RevisionManager.java | 136 +- .../org/xmind/core/internal/SettingEntry.java | 30 +- .../src/org/xmind/core/internal/Sheet.java | 170 +- .../xmind/core/internal/SheetSettings.java | 24 +- .../src/org/xmind/core/internal/Summary.java | 190 +- .../core/internal/TopicExtensionElement.java | 58 +- .../core/internal/WorkbookExtension.java | 48 +- .../internal/WorkbookExtensionElement.java | 40 +- .../internal/WorkbookExtensionManager.java | 22 +- .../org/xmind/core/internal/Workspace.java | 282 +- .../internal/compatibility/Compatibility.java | 132 +- .../internal/compatibility/FileFormat.java | 68 +- .../xmind/core/internal/dom/BoundaryImpl.java | 582 +- .../xmind/core/internal/dom/CommentImpl.java | 350 +- .../core/internal/dom/CommentManagerImpl.java | 730 +- .../xmind/core/internal/dom/DOMConstants.java | 476 +- .../core/internal/dom/DeserializerImpl.java | 892 +- .../core/internal/dom/EncryptionDataImpl.java | 316 +- .../core/internal/dom/FileEntryImpl.java | 680 +- .../core/internal/dom/FileFormat_0_1.java | 106 +- .../xmind/core/internal/dom/FileFormat_1.java | 1660 +-- .../internal/dom/HtmlNotesContentImpl.java | 318 +- .../org/xmind/core/internal/dom/IDKey.java | 118 +- .../internal/dom/INodeAdaptableFactory.java | 44 +- .../internal/dom/INodeAdaptableProvider.java | 44 +- .../xmind/core/internal/dom/ImageImpl.java | 454 +- .../core/internal/dom/ImageSpanImpl.java | 96 +- .../core/internal/dom/InternalDOMUtils.java | 434 +- .../internal/dom/InternalHyperlinkUtils.java | 312 +- .../xmind/core/internal/dom/ManifestImpl.java | 1142 +- .../core/internal/dom/MarkerGroupImpl.java | 388 +- .../xmind/core/internal/dom/MarkerImpl.java | 306 +- .../core/internal/dom/MarkerResource.java | 100 +- .../internal/dom/MarkerSheetBuilderImpl.java | 290 +- .../core/internal/dom/MarkerSheetImpl.java | 1140 +- .../org/xmind/core/internal/dom/MetaImpl.java | 558 +- .../src/org/xmind/core/internal/dom/NS.java | 160 +- .../internal/dom/NodeAdaptableRegistry.java | 406 +- .../xmind/core/internal/dom/NotesImpl.java | 414 +- .../xmind/core/internal/dom/NumberUtils.java | 208 +- .../core/internal/dom/NumberingImpl.java | 484 +- .../core/internal/dom/ParagraphImpl.java | 262 +- .../internal/dom/PlainNotesContentImpl.java | 82 +- .../core/internal/dom/RelationshipImpl.java | 742 +- .../xmind/core/internal/dom/RevisionImpl.java | 392 +- .../internal/dom/RevisionManagerImpl.java | 676 +- .../core/internal/dom/SerializerImpl.java | 1166 +- .../core/internal/dom/SettingEntryImpl.java | 216 +- .../xmind/core/internal/dom/SheetImpl.java | 802 +- .../xmind/core/internal/dom/SheetSetting.java | 238 +- .../core/internal/dom/SheetSettingsImpl.java | 440 +- .../xmind/core/internal/dom/SpanImplBase.java | 238 +- .../xmind/core/internal/dom/StyleImpl.java | 814 +- .../internal/dom/StyleSheetBuilderImpl.java | 328 +- .../core/internal/dom/StyleSheetImpl.java | 608 +- .../xmind/core/internal/dom/SummaryImpl.java | 526 +- .../xmind/core/internal/dom/TempSaver.java | 452 +- .../xmind/core/internal/dom/TextSpanImpl.java | 182 +- .../dom/TopicExtensionElementImpl.java | 450 +- .../core/internal/dom/TopicExtensionImpl.java | 384 +- .../xmind/core/internal/dom/TopicImpl.java | 2728 ++--- .../core/internal/dom/TopicPathImpl.java | 124 +- .../internal/dom/WorkbookBuilderImpl.java | 566 +- .../dom/WorkbookExtensionElementImpl.java | 452 +- .../internal/dom/WorkbookExtensionImpl.java | 420 +- .../dom/WorkbookExtensionManagerImpl.java | 296 +- .../xmind/core/internal/dom/WorkbookImpl.java | 1686 +-- .../core/internal/dom/WorkbookLoader.java | 588 +- .../internal/dom/WorkbookMarkerResource.java | 150 +- .../core/internal/dom/WorkbookSaver.java | 978 +- .../core/internal/dom/WorkbookUtilsImpl.java | 166 +- .../xmind/core/internal/dom/XMLLoader.java | 122 +- .../internal/event/CoreEventListenerList.java | 152 +- .../internal/event/CoreEventRegistration.java | 164 +- .../event/CoreEventRegistrationList.java | 194 +- .../core/internal/event/CoreEventSupport.java | 722 +- .../event/NullCoreEventRegistration.java | 74 +- .../internal/event/NullCoreEventSupport.java | 228 +- .../zip/AbstractArchivedWorkbook.java | 94 +- .../core/internal/zip/ArchiveConstants.java | 172 +- .../core/internal/zip/ArchivedWorkbook.java | 1032 +- .../core/internal/zip/IArchivedWorkbook.java | 156 +- .../internal/zip/TempArchivedWorkbook.java | 298 +- .../core/internal/zip/ZipFileInputSource.java | 338 +- .../internal/zip/ZipStreamOutputTarget.java | 262 +- .../org/xmind/core/io/ByteArrayStorage.java | 588 +- .../core/io/ChecksumTrackingOutputStream.java | 176 +- .../core/io/ChecksumVerifiedInputStream.java | 158 +- .../org/xmind/core/io/CoreIOException.java | 76 +- .../xmind/core/io/DirectoryInputSource.java | 388 +- .../xmind/core/io/DirectoryOutputTarget.java | 218 +- .../org/xmind/core/io/DirectoryStorage.java | 286 +- .../xmind/core/io/ICloseableOutputTarget.java | 42 +- .../src/org/xmind/core/io/IInputSource.java | 178 +- .../src/org/xmind/core/io/IOutputTarget.java | 156 +- .../src/org/xmind/core/io/IStorage.java | 126 +- .../core/io/InvalidChecksumException.java | 72 +- .../org/xmind/core/io/PrefixedStorage.java | 428 +- .../core/marker/AbstractMarkerResource.java | 282 +- .../core/marker/IMarkerResourceAllocator.java | 80 +- .../core/marker/IMarkerResourceProvider.java | 42 +- .../org/xmind/core/marker/IMarkerSheet.java | 380 +- .../xmind/core/marker/IMarkerVariation.java | 44 +- .../src/org/xmind/core/style/IStyle.java | 254 +- .../src/org/xmind/core/style/IStyleRef.java | 38 +- .../src/org/xmind/core/util/CloneHandler.java | 2025 +-- .../src/org/xmind/core/util/Codec.java | 166 +- .../src/org/xmind/core/util/DOMUtils.java | 1524 +-- .../src/org/xmind/core/util/FileUtils.java | 694 +- .../org/xmind/core/util/HyperlinkUtils.java | 374 +- .../org/xmind/core/util/ILabelRefCounter.java | 34 +- .../xmind/core/util/IProgressReporter.java | 58 +- .../xmind/core/util/IPropertiesProvider.java | 48 +- .../src/org/xmind/core/util/IRefCounter.java | 106 +- .../org/xmind/core/util/IStyleRefCounter.java | 34 +- .../org/xmind/core/util/TopicIterator.java | 272 +- .../.classpath | 14 +- .../.gitignore | 30 +- .../.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 216 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 20 +- .../OSGI-INF/l10n/bundle.properties | 6 +- .../about.html | 44 +- .../build.properties | 14 +- .../pom.xml | 32 +- .../vectorgraphics2d/PDFGraphics2D.java | 1436 +-- .../vectorgraphics2d/SVGGraphics2D.java | 876 +- .../vectorgraphics2d/VectorGraphics2D.java | 2032 ++-- .../vectorgraphics2d/util/DataUtils.java | 440 +- .../vectorgraphics2d/util/GraphicsUtils.java | 382 +- bundles/org.xmind.gef.ui/.classpath | 14 +- bundles/org.xmind.gef.ui/.gitignore | 30 +- bundles/org.xmind.gef.ui/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF | 50 +- bundles/org.xmind.gef.ui/about.html | 44 +- bundles/org.xmind.gef.ui/build.properties | 16 +- bundles/org.xmind.gef.ui/plugin.properties | 4 +- bundles/org.xmind.gef.ui/plugin.xml | 114 +- bundles/org.xmind.gef.ui/pom.xml | 32 +- .../xmind/gef/ui/actions/ActionRegistry.java | 7 +- .../gef/ui/actions/ICommandStackAction.java | 42 +- .../gef/ui/actions/ISelectionAction.java | 42 +- .../org/xmind/gef/ui/actions/PageAction.java | 190 +- .../org/xmind/gef/ui/actions/RedoAction.java | 110 +- .../org/xmind/gef/ui/actions/UndoAction.java | 112 +- .../src/org/xmind/gef/ui/editor/Editable.java | 1359 +-- .../ui/editor/GlobalActionHandlerService.java | 202 +- .../xmind/gef/ui/editor/GraphicalEditor.java | 1708 +-- .../GraphicalEditorActionBarContributor.java | 8 +- .../gef/ui/editor/GraphicalEditorPage.java | 820 +- ...GraphicalEditorPagePopupPreviewHelper.java | 16 +- .../org/xmind/gef/ui/editor/IEditable.java | 608 +- .../xmind/gef/ui/editor/IEditableCleaner.java | 60 +- .../xmind/gef/ui/editor/IEditingContext.java | 62 +- .../editor/IGlobalActionHandlerService.java | 58 +- .../editor/IGlobalActionHandlerUpdater.java | 54 +- .../gef/ui/editor/IInteractiveMessage.java | 64 +- .../src/org/xmind/gef/ui/editor/IMiniBar.java | 54 +- .../gef/ui/editor/IMiniBarContributor.java | 64 +- .../gef/ui/editor/InteractiveMessage.java | 172 +- .../MultiGraphicalPageSelectionProvider.java | 328 +- .../src/org/xmind/gef/ui/editor/Panel.java | 542 +- .../internal/CommandStackPropertyTester.java | 94 +- .../internal/ModelToPartAdapterFactory.java | 124 +- .../ui/internal/SpaceCollaborativeEngine.java | 116 +- .../gef/ui/outline/GraphicalOutlinePage.java | 582 +- .../GraphicalPropertySheetPage.java | 906 +- .../org/xmind/gef/ui/properties/Messages.java | 64 +- .../gef/ui/properties/messages.properties | 2 +- .../xmind/ui/animation/AnimationService.java | 790 +- .../org/xmind/ui/datepicker/ArrowFigure.java | 148 +- .../org/xmind/ui/datepicker/BaseFigure.java | 396 +- .../ui/datepicker/CalendarAnimation.java | 378 +- .../ui/datepicker/ConstraintStackLayout.java | 80 +- .../ui/datepicker/DateLabelProvider.java | 54 +- .../xmind/ui/datepicker/DatePanelLayout.java | 212 +- .../org/xmind/ui/datepicker/DatePicker.java | 3390 +++--- .../org/xmind/ui/datepicker/DatePicker2.java | 2800 ++--- .../xmind/ui/datepicker/DateSelection.java | 70 +- .../org/xmind/ui/datepicker/DayFigure.java | 50 +- .../xmind/ui/datepicker/HorizontalLine.java | 62 +- .../org/xmind/ui/datepicker/HourFigure.java | 74 +- .../ui/datepicker/IAnimationAdvisor.java | 82 +- .../ui/datepicker/LastMonthAnimation.java | 160 +- .../ui/datepicker/LastYearAnimation.java | 158 +- .../src/org/xmind/ui/datepicker/Messages.java | 126 +- .../xmind/ui/datepicker/MinutesFigure.java | 52 +- .../org/xmind/ui/datepicker/MonthFigure.java | 48 +- .../ui/datepicker/NextMonthAnimation.java | 158 +- .../ui/datepicker/NextYearAnimation.java | 160 +- .../ui/datepicker/PreselectFeedbackLayer.java | 60 +- .../ui/datepicker/PressFeedbackLayer.java | 60 +- .../ui/datepicker/SelectFeedbackLayer.java | 60 +- .../org/xmind/ui/datepicker/TextLayer.java | 226 +- .../org/xmind/ui/datepicker/YearFigure.java | 46 +- .../xmind/ui/datepicker/messages.properties | 58 +- .../ui/gallery/CategorizedGalleryViewer.java | 842 +- .../src/org/xmind/ui/gallery/ContentPane.java | 708 +- .../org/xmind/ui/gallery/FrameDecorator.java | 244 +- .../src/org/xmind/ui/gallery/FrameFigure.java | 636 +- .../src/org/xmind/ui/gallery/FramePart.java | 466 +- .../ui/gallery/GalleryMovablePolicy.java | 50 +- .../ui/gallery/GalleryNavigablePolicy.java | 420 +- .../xmind/ui/gallery/GallerySelectTool.java | 326 +- .../org/xmind/ui/gallery/GalleryViewer.java | 786 +- .../xmind/ui/gallery/IDecorationContext.java | 14 +- .../org/xmind/ui/gallery/ILabelDecorator.java | 20 +- .../gallery/NavigationAnimationService.java | 674 +- .../ui/gallery/NavigationContentPart.java | 164 +- .../ui/gallery/NavigationItemFigure.java | 532 +- .../ui/gallery/NavigationItemLayout.java | 338 +- .../NavigationItemNavigablePolicy.java | 250 +- .../xmind/ui/gallery/NavigationItemPart.java | 304 +- .../xmind/ui/gallery/NavigationViewer.java | 572 +- .../ui/texteditor/FloatingTextEditTool.java | 1026 +- bundles/org.xmind.gef/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- bundles/org.xmind.gef/META-INF/MANIFEST.MF | 70 +- bundles/org.xmind.gef/about.html | 44 +- bundles/org.xmind.gef/plugin.properties | 4 +- bundles/org.xmind.gef/pom.xml | 32 +- .../src/org/xmind/gef/AbstractViewer.java | 2210 ++-- .../org/xmind/gef/ArraySourceProvider.java | 176 +- .../src/org/xmind/gef/Disposable.java | 64 +- .../src/org/xmind/gef/EditDomain.java | 632 +- .../org.xmind.gef/src/org/xmind/gef/GEF.java | 874 +- .../src/org/xmind/gef/GraphicalViewer.java | 1184 +- .../src/org/xmind/gef/IDisposable.java | 48 +- .../src/org/xmind/gef/IDisposable2.java | 38 +- .../org/xmind/gef/IEditDomainListener.java | 48 +- .../src/org/xmind/gef/IGraphicalViewer.java | 234 +- .../org/xmind/gef/IInputChangedListener.java | 50 +- .../src/org/xmind/gef/ISourceProvider2.java | 42 +- .../src/org/xmind/gef/IViewer.java | 280 +- .../src/org/xmind/gef/IZoomListener.java | 44 +- .../src/org/xmind/gef/Request.java | 574 +- .../src/org/xmind/gef/SelectionStack.java | 372 +- .../src/org/xmind/gef/ZoomManager.java | 326 +- .../org/xmind/gef/command/CommandStack.java | 728 +- .../xmind/gef/command/CommandStackBase.java | 390 +- .../xmind/gef/command/CompoundCommand.java | 400 +- .../org/xmind/gef/command/ICommandStack2.java | 42 +- .../org/xmind/gef/command/ICommandStack3.java | 42 +- .../gef/command/ICommandStackCallback.java | 38 +- .../gef/command/ICommandStackDelegate.java | 38 +- .../gef/command/ICommandStackListener.java | 46 +- .../org/xmind/gef/command/ModifyCommand.java | 264 +- .../org/xmind/gef/draw2d/AbstractAnchor.java | 448 +- .../org/xmind/gef/draw2d/IAnchorListener.java | 38 +- .../gef/draw2d/IAnchorableFigureListener.java | 40 +- .../gef/draw2d/IDecoratedFigureListener.java | 44 +- .../src/org/xmind/gef/draw2d/IHasCorner.java | 42 +- .../org/xmind/gef/draw2d/IOriginBased.java | 48 +- .../org/xmind/gef/draw2d/IOriginBased2.java | 46 +- .../gef/draw2d/IReferenceDescriptor.java | 44 +- .../xmind/gef/draw2d/IReferencedFigure.java | 268 +- .../src/org/xmind/gef/draw2d/IRotatable.java | 48 +- .../draw2d/IRotatableReferenceDescriptor.java | 44 +- .../org/xmind/gef/draw2d/IShadowedFigure.java | 46 +- .../org/xmind/gef/draw2d/ISkylightLayer.java | 48 +- .../org/xmind/gef/draw2d/ITitledFigure.java | 46 +- .../org/xmind/gef/draw2d/ITitledFigure2.java | 42 +- .../gef/draw2d/ITransparentableFigure.java | 44 +- .../src/org/xmind/gef/draw2d/IWrapFigure.java | 46 +- .../gef/draw2d/KeepVisibleToolTipHelper.java | 186 +- .../src/org/xmind/gef/draw2d/PathFigure.java | 376 +- .../xmind/gef/draw2d/ReferencedFigure.java | 368 +- .../org/xmind/gef/draw2d/ReferencedLayer.java | 360 +- .../draw2d/RotatableSizeableImageFigure.java | 224 +- .../xmind/gef/draw2d/RotatableWrapLabel.java | 1936 ++- .../decoration/AbstractLineDecoration.java | 236 +- .../decoration/IConnectionDecorationEx.java | 48 +- .../decoration/ICorneredDecoration.java | 46 +- .../decoration/IShadowedDecoration.java | 44 +- .../decoration/PathConnectionDecoration.java | 228 +- .../decoration/PathShapeDecoration.java | 302 +- .../xmind/gef/draw2d/geometry/Geometry.java | 2236 ++-- .../gef/draw2d/geometry/IBoundsProvider.java | 44 +- .../gef/draw2d/graphics/AlphaGraphics.java | 926 +- .../draw2d/graphics/ColorMaskGraphics.java | 1118 +- .../gef/draw2d/graphics/GradientPattern.java | 124 +- .../gef/draw2d/graphics/GraphicsUtils.java | 450 +- .../gef/draw2d/graphics/GrayedGraphics.java | 68 +- .../org/xmind/gef/draw2d/graphics/Path.java | 526 +- .../gef/draw2d/graphics/Rotate90Graphics.java | 1334 +- .../gef/draw2d/graphics/ScaledGraphics.java | 2552 ++-- .../graphics/SimpleColorMaskGraphics.java | 116 +- .../org/xmind/gef/event/MouseDragEvent.java | 194 +- .../src/org/xmind/gef/event/MouseEvent.java | 226 +- .../org/xmind/gef/event/MouseWheelEvent.java | 92 +- .../xmind/gef/event/PartsEventDispatcher.java | 2841 ++--- .../gef/event/ViewerEventDispatcher.java | 284 +- .../AbstractStyleSelector.java | 142 +- .../graphicalpolicy/IStyleValueProvider.java | 46 +- .../org/xmind/gef/image/FigureRenderer.java | 416 +- .../xmind/gef/image/IExportAreaProvider.java | 46 +- .../gef/image/IExportSourceProvider.java | 66 +- .../src/org/xmind/gef/image/IRenderer.java | 54 +- .../org/xmind/gef/image/ImageExportUtils.java | 312 +- .../org/xmind/gef/image/ResizeConstants.java | 104 +- .../gef/image/ViewerExportSourceProvider.java | 302 +- .../gef/internal/image/ImageConverter.java | 874 +- .../image/MaxPixelsExportAreaProvider.java | 100 +- .../org/xmind/gef/part/GraphicalEditPart.java | 474 +- .../src/org/xmind/gef/part/IPartFactory.java | 44 +- .../org/xmind/gef/part/IPartListener2.java | 36 + .../org/xmind/gef/part/NullGraphicalPart.java | 48 +- .../src/org/xmind/gef/part/Part.java | 826 +- .../src/org/xmind/gef/part/PartRoles.java | 214 +- .../org/xmind/gef/policy/NavigablePolicy.java | 194 +- .../xmind/gef/policy/ScalableEditPolicy.java | 37 +- .../gef/service/AbstractViewerService.java | 188 +- .../xmind/gef/service/BaseRevealService.java | 178 +- .../service/CenterPreservationService.java | 536 +- .../xmind/gef/service/FeedbackService.java | 964 +- .../org/xmind/gef/service/IPointProvider.java | 42 +- .../xmind/gef/service/IRectangleProvider.java | 42 +- .../org/xmind/gef/service/IRevealService.java | 50 +- .../gef/service/IRevealServiceListener.java | 58 +- .../xmind/gef/service/IViewerService2.java | 40 +- .../org/xmind/gef/service/RevealEvent.java | 100 +- .../gef/service/StyleOverrideService.java | 60 +- .../ZoomingAndPanningRevealService.java | 888 +- .../org/xmind/gef/status/IStatusListener.java | 46 +- .../src/org/xmind/gef/tool/AbstractTool.java | 1176 +- .../src/org/xmind/gef/tool/BrowsingTool.java | 238 +- .../src/org/xmind/gef/tool/EditTool.java | 560 +- .../src/org/xmind/gef/tool/IEditTool.java | 60 +- .../src/org/xmind/gef/tool/ISourceTool.java | 46 +- .../src/org/xmind/gef/tool/ITextEditTool.java | 46 +- .../src/org/xmind/gef/tool/SelectTool.java | 1100 +- .../src/org/xmind/gef/tree/ITreeRootPart.java | 42 +- .../xmind/gef/util/EventListenerSupport.java | 160 +- .../src/org/xmind/gef/util/GEFUtils.java | 212 +- .../org/xmind/gef/util/IEventDispatcher.java | 36 +- .../src/org/xmind/gef/util/Properties.java | 354 +- bundles/org.xmind.neuquant/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 6 +- .../org.xmind.neuquant/META-INF/MANIFEST.MF | 20 +- bundles/org.xmind.neuquant/about.html | 68 +- bundles/org.xmind.neuquant/plugin.properties | 4 +- bundles/org.xmind.neuquant/pom.xml | 32 +- .../.classpath | 14 +- .../.gitignore | 30 +- .../.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 46 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 34 +- .../OSGI-INF/l10n/bundle.properties | 6 +- .../about.html | 1258 +- .../build.properties | 14 +- .../pom.xml | 32 +- .../graphics2d/AbstractVectorGraphics.java | 1634 +-- .../org/freehep/graphics2d/ArrayPath.java | 394 +- .../freehep/graphics2d/GenericTagHandler.java | 668 +- .../freehep/graphics2d/PixelGraphics2D.java | 1294 +- .../org/freehep/graphics2d/PrintColor.java | 322 +- .../org/freehep/graphics2d/SymbolShape.java | 800 +- .../org/freehep/graphics2d/TagHandler.java | 314 +- .../org/freehep/graphics2d/TagString.java | 58 +- .../freehep/graphics2d/VectorGraphics.java | 1294 +- .../graphics2d/VectorGraphicsConstants.java | 256 +- .../org/freehep/graphics2d/WebColor.java | 192 +- .../graphics2d/font/AbstractCharTable.java | 72 +- .../freehep/graphics2d/font/CharTable.java | 178 +- .../org/freehep/graphics2d/font/Expert.java | 1748 +-- .../freehep/graphics2d/font/FontEncoder.java | 62 +- .../graphics2d/font/FontUtilities.java | 342 +- .../org/freehep/graphics2d/font/ISOLatin.java | 2272 ++-- .../org/freehep/graphics2d/font/Lookup.java | 238 +- .../org/freehep/graphics2d/font/MACLatin.java | 2300 ++-- .../org/freehep/graphics2d/font/PDFLatin.java | 2388 ++-- .../org/freehep/graphics2d/font/STDLatin.java | 2068 ++-- .../org/freehep/graphics2d/font/Symbol.java | 1988 +-- .../org/freehep/graphics2d/font/WINLatin.java | 2336 ++-- .../freehep/graphics2d/font/Zapfdingbats.java | 1978 +-- .../graphicsio/AbstractPathConstructor.java | 152 +- .../graphicsio/AbstractVectorGraphicsIO.java | 3060 ++--- .../org/freehep/graphicsio/FontConstants.java | 56 +- .../freehep/graphicsio/ImageConstants.java | 318 +- .../freehep/graphicsio/ImageGraphics2D.java | 1204 +- .../graphicsio/ImageParamConverter.java | 46 +- .../org/freehep/graphicsio/InfoConstants.java | 52 +- .../freehep/graphicsio/MultiPageDocument.java | 56 +- .../org/freehep/graphicsio/PageConstants.java | 66 +- .../freehep/graphicsio/PathConstructor.java | 146 +- .../QuadToCubicPathConstructor.java | 106 +- .../freehep/graphicsio/VectorGraphicsIO.java | 150 +- .../graphicsio/font/CharstringEncoder.java | 354 +- .../freehep/graphicsio/font/FontEmbedder.java | 338 +- .../graphicsio/font/FontEmbedderType1.java | 458 +- .../freehep/graphicsio/font/FontIncluder.java | 308 +- .../freehep/graphicsio/font/FontTable.java | 470 +- .../freehep/graphicsio/pdf/ImageBytes.java | 264 +- .../xmind/org/freehep/graphicsio/pdf/PDF.java | 238 +- .../freehep/graphicsio/pdf/PDFByteWriter.java | 216 +- .../freehep/graphicsio/pdf/PDFCatalog.java | 150 +- .../graphicsio/pdf/PDFCharTableWriter.java | 84 +- .../freehep/graphicsio/pdf/PDFConstants.java | 110 +- .../freehep/graphicsio/pdf/PDFDictionary.java | 326 +- .../freehep/graphicsio/pdf/PDFDocInfo.java | 112 +- .../graphicsio/pdf/PDFFontEmbedder.java | 242 +- .../graphicsio/pdf/PDFFontEmbedderType1.java | 272 +- .../graphicsio/pdf/PDFFontEmbedderType3.java | 174 +- .../graphicsio/pdf/PDFFontIncluder.java | 254 +- .../freehep/graphicsio/pdf/PDFFontTable.java | 250 +- .../freehep/graphicsio/pdf/PDFGraphics2D.java | 1920 +-- .../graphicsio/pdf/PDFImageDelayQueue.java | 232 +- .../org/freehep/graphicsio/pdf/PDFName.java | 40 +- .../org/freehep/graphicsio/pdf/PDFObject.java | 352 +- .../freehep/graphicsio/pdf/PDFOutline.java | 110 +- .../graphicsio/pdf/PDFOutlineList.java | 52 +- .../org/freehep/graphicsio/pdf/PDFPage.java | 184 +- .../freehep/graphicsio/pdf/PDFPageBase.java | 88 +- .../freehep/graphicsio/pdf/PDFPageTree.java | 70 +- .../graphicsio/pdf/PDFPaintDelayQueue.java | 524 +- .../graphicsio/pdf/PDFPathConstructor.java | 80 +- .../graphicsio/pdf/PDFRedundanceTracker.java | 252 +- .../org/freehep/graphicsio/pdf/PDFRef.java | 82 +- .../org/freehep/graphicsio/pdf/PDFStream.java | 1520 +-- .../org/freehep/graphicsio/pdf/PDFUtil.java | 142 +- .../graphicsio/pdf/PDFViewerPreferences.java | 94 +- .../org/freehep/graphicsio/pdf/PDFWriter.java | 454 +- .../graphicsio/raw/RawImageWriteParam.java | 142 +- .../graphicsio/raw/RawImageWriter.java | 146 +- .../graphicsio/raw/RawImageWriterSpi.java | 82 +- .../org/freehep/util/DoubleWithError.java | 188 +- .../org/freehep/util/ScientificFormat.java | 500 +- .../org/freehep/util/UserProperties.java | 626 +- .../freehep/util/images/ImageUtilities.java | 344 +- .../xmind/org/freehep/util/io/ASCII85.java | 76 +- .../freehep/util/io/ASCII85OutputStream.java | 268 +- .../freehep/util/io/ASCIIHexOutputStream.java | 190 +- .../util/io/CountedByteOutputStream.java | 108 +- .../org/freehep/util/io/EEXECConstants.java | 76 +- .../org/freehep/util/io/EEXECEncryption.java | 266 +- .../util/io/FinishableOutputStream.java | 50 +- .../freehep/util/io/FlateOutputStream.java | 74 +- bundles/org.xmind.ui.browser/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../org.xmind.ui.browser/META-INF/MANIFEST.MF | 50 +- bundles/org.xmind.ui.browser/about.html | 44 +- .../org.xmind.ui.browser/plugin.properties | 12 +- bundles/org.xmind.ui.browser/plugin.xml | 10 +- bundles/org.xmind.ui.browser/pom.xml | 32 +- .../org/xmind/ui/browser/BrowserDialog.java | 444 +- .../org/xmind/ui/browser/IBrowserViewer.java | 110 +- .../ui/browser/IBrowserViewerContainer.java | 108 +- .../browser/IBrowserViewerContribution.java | 66 +- .../browser/IBrowserViewerContribution2.java | 72 +- .../ui/browser/IPropertyChangingListener.java | 50 +- .../ui/browser/PropertyChangingEvent.java | 88 +- .../BrowserEditorActionContributor.java | 278 +- .../ui/internal/browser/BrowserImages.java | 182 +- .../ui/internal/browser/BrowserMessages.java | 96 +- .../ui/internal/browser/BrowserPref.java | 268 +- .../ui/internal/browser/BrowserPrefPage.java | 242 +- .../internal/browser/BrowserSupportImpl.java | 318 +- .../ui/internal/browser/BrowserUtil.java | 404 +- .../ui/internal/browser/BrowserViewer.java | 2818 ++--- .../internal/browser/ExternalWebBrowser.java | 108 +- .../ui/internal/browser/InternalBrowser.java | 462 +- .../browser/InternalBrowserEditor.java | 666 +- .../internal/browser/InternalBrowserView.java | 612 +- .../internal/browser/actions/CutAction.java | 56 +- bundles/org.xmind.ui.dashboard/.classpath | 14 +- bundles/org.xmind.ui.dashboard/.gitignore | 30 +- bundles/org.xmind.ui.dashboard/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 770 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 110 +- .../META-INF/MANIFEST.MF | 28 +- .../org.xmind.ui.dashboard/build.properties | 10 +- bundles/org.xmind.ui.dashboard/pom.xml | 32 +- .../internal/dashboard/DashboardPlugin.java | 100 +- .../dashboard/pages/DashboardPage.java | 36 +- .../dashboard/pages/IDashboardContext.java | 196 +- .../dashboard/pages/IDashboardPage.java | 22 +- .../.classpath | 32 +- .../.gitignore | 32 +- .../org.xmind.ui.exports.vector.svg/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 822 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../META-INF/MANIFEST.MF | 40 +- .../about.html | 36 +- .../build.properties | 18 +- .../plugin.properties | 6 +- .../plugin.xml | 28 +- .../org.xmind.ui.exports.vector.svg/pom.xml | 32 +- .../ui/exports/vector/svg/SVGGenerator.java | 265 +- .../internal/exports/vector/svg/Messages.java | 90 +- .../exports/vector/svg/SVGExportWizard.java | 624 +- .../exports/vector/svg/SVGExporter.java | 404 +- .../exports/vector/svg/SvgPlugin.java | 202 +- .../exports/vector/svg/messages.properties | 22 +- .../org.xmind.ui.exports.vector/.classpath | 32 +- .../org.xmind.ui.exports.vector/.gitignore | 32 +- bundles/org.xmind.ui.exports.vector/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 822 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../META-INF/MANIFEST.MF | 30 +- .../org.xmind.ui.exports.vector/about.html | 36 +- .../build.properties | 14 +- .../plugin.properties | 4 +- bundles/org.xmind.ui.exports.vector/pom.xml | 32 +- .../xmind/ui/exports/vector/VectorPlugin.java | 176 +- .../ui/exports/vector/graphics/GdiFont.java | 222 +- .../graphics/GraphicsToGraphics2DAdaptor.java | 3430 +++--- .../vector/graphics/ImageConverter.java | 364 +- bundles/org.xmind.ui.fishbone/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../META-INF/MANIFEST.MF | 30 +- bundles/org.xmind.ui.fishbone/about.html | 44 +- .../org.xmind.ui.fishbone/build.properties | 18 +- .../org.xmind.ui.fishbone/plugin.properties | 22 +- bundles/org.xmind.ui.fishbone/plugin.xml | 2050 ++-- bundles/org.xmind.ui.fishbone/pom.xml | 32 +- .../decorations/FishboneBranchConnection.java | 326 +- .../decorations/FishboneTopicDecoration.java | 346 +- .../LeftFishheadTopicDecoration.java | 98 +- .../MainFishboneBranchDecoration.java | 530 +- .../RightFishheadTopicDecoration.java | 98 +- .../AbstractSubFishboneDirection.java | 200 +- .../structures/FishboneBranchHook.java | 382 +- .../fishbone/structures/FishboneData.java | 140 +- .../fishbone/structures/ISubDirection.java | 154 +- .../structures/LeftHeadedStructure.java | 42 +- .../fishbone/structures/MainFishboneData.java | 168 +- .../structures/MainFishboneStructure.java | 1320 +- .../structures/NENormalStructure.java | 42 +- .../structures/NERotatedStructure.java | 42 +- .../structures/NWNormalStructure.java | 42 +- .../structures/NWRotatedStructure.java | 42 +- .../fishbone/structures/NorthEastNormal.java | 532 +- .../fishbone/structures/NorthEastRotated.java | 470 +- .../fishbone/structures/NorthWestNormal.java | 88 +- .../fishbone/structures/NorthWestRotated.java | 90 +- .../structures/RightHeadedStructure.java | 42 +- .../structures/SENormalStructure.java | 42 +- .../structures/SERotatedStructure.java | 42 +- .../structures/SWNormalStructure.java | 42 +- .../structures/SWRotatedStructure.java | 42 +- .../ui/internal/fishbone/structures/Side.java | 64 +- .../fishbone/structures/SouthEastNormal.java | 562 +- .../fishbone/structures/SouthEastRotated.java | 460 +- .../fishbone/structures/SouthWestNormal.java | 88 +- .../fishbone/structures/SouthWestRotated.java | 90 +- .../fishbone/structures/SubFishboneData.java | 290 +- .../structures/SubFishboneStructure.java | 1412 +-- bundles/org.xmind.ui.imports/.classpath | 2 +- bundles/org.xmind.ui.imports/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../org.xmind.ui.imports/META-INF/MANIFEST.MF | 40 +- bundles/org.xmind.ui.imports/about.html | 44 +- .../org.xmind.ui.imports/plugin.properties | 18 +- bundles/org.xmind.ui.imports/plugin.xml | 104 +- bundles/org.xmind.ui.imports/pom.xml | 32 +- .../freemind/FreeMindImportWizard.java | 214 +- .../imports/freemind/FreeMindImporter.java | 1491 +-- .../imports/lighten/LightenConstants.java | 120 +- .../imports/lighten/LightenImportWizard.java | 158 +- .../imports/lighten/LightenImporter.java | 813 +- .../imports/mm/MindManagerImportWizard.java | 214 +- .../imports/mm/MindManagerImporter.java | 4239 +++---- .../imports/novamind/NMConstants.java | 22 +- .../novamind/NovaMindImportWizard.java | 204 +- .../imports/novamind/NovaMindImporter.java | 4005 +++--- .../NovaMindResourceMappingManager.java | 52 +- .../ui/internal/imports/novamind/mappings.xml | 242 +- .../internal/imports/opml/OpmlConstants.java | 22 +- .../imports/opml/OpmlImportWizard.java | 152 +- .../internal/imports/opml/OpmlImporter.java | 365 +- bundles/org.xmind.ui.menus/.classpath | 22 +- bundles/org.xmind.ui.menus/.gitignore | 30 +- bundles/org.xmind.ui.menus/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 620 +- .../.settings/org.eclipse.jdt.ui.prefs | 6 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../org.xmind.ui.menus/META-INF/MANIFEST.MF | 36 +- .../OSGI-INF/l10n/bundle.properties | 522 +- bundles/org.xmind.ui.menus/about.html | 44 +- bundles/org.xmind.ui.menus/build.properties | 22 +- bundles/org.xmind.ui.menus/fragment.e4xmi | 134 +- .../icons/toolbar/d/boundary.png | Bin 982 -> 1079 bytes .../icons/toolbar/d/boundary@2x.png | Bin 1914 -> 2434 bytes .../icons/toolbar/d/insert.png | Bin 670 -> 246 bytes .../icons/toolbar/d/insert@2x.png | Bin 1589 -> 558 bytes .../icons/toolbar/d/share.png | Bin 1235 -> 1228 bytes .../icons/toolbar/d/share@2x.png | Bin 2866 -> 3144 bytes .../icons/toolbar/d/summary.png | Bin 676 -> 744 bytes .../icons/toolbar/d/summary@2x.png | Bin 1548 -> 1765 bytes .../icons/toolbar/d/topic.png | Bin 660 -> 554 bytes .../icons/toolbar/d/topic@2x.png | Bin 1318 -> 1165 bytes .../icons/toolbar/e/boundary.png | Bin 1051 -> 1137 bytes .../icons/toolbar/e/boundary@2x.png | Bin 2211 -> 2756 bytes .../icons/toolbar/e/insert.png | Bin 1053 -> 250 bytes .../icons/toolbar/e/insert@2x.png | Bin 2792 -> 606 bytes .../icons/toolbar/e/insert_disable.png | Bin 959 -> 0 bytes .../icons/toolbar/e/insert_disable@2x.png | Bin 2367 -> 0 bytes .../icons/toolbar/e/share.png | Bin 1354 -> 1338 bytes .../icons/toolbar/e/share@2x.png | Bin 3409 -> 3561 bytes .../icons/toolbar/e/summary.png | Bin 731 -> 769 bytes .../icons/toolbar/e/summary@2x.png | Bin 1723 -> 1980 bytes .../icons/toolbar/e/topic.png | Bin 660 -> 564 bytes .../icons/toolbar/e/topic@2x.png | Bin 1573 -> 1394 bytes bundles/org.xmind.ui.menus/plugin.xml | 4465 ++++--- bundles/org.xmind.ui.menus/pom.xml | 32 +- .../src/org/xmind/ui/menus/MenusPlugin.java | 112 +- bundles/org.xmind.ui.mindmap/.classpath | 32 +- bundles/org.xmind.ui.mindmap/.gitignore | 30 +- bundles/org.xmind.ui.mindmap/.options | 8 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../org.eclipse.wst.validation.prefs | 18 +- .../org.xmind.ui.mindmap/META-INF/MANIFEST.MF | 168 +- .../OSGI-INF/serviceManager.xml | 10 +- bundles/org.xmind.ui.mindmap/about.html | 44 +- .../icons/emotion_angry@16.svg | 58 +- .../org.xmind.ui.mindmap/parts_fragment.e4xmi | 127 +- .../org.xmind.ui.mindmap/plugin.properties | 150 +- bundles/org.xmind.ui.mindmap/plugin.xml | 759 +- bundles/org.xmind.ui.mindmap/pom.xml | 32 +- .../src/org/xmind/ui/IEditorHistory.java | 90 +- .../xmind/ui/IPreSaveInteractiveFeedback.java | 104 +- .../xmind/ui/IPreSaveInteractiveProvider.java | 88 +- .../src/org/xmind/ui/IPreSaveListener.java | 52 +- .../src/org/xmind/ui/ISaveablePart3.java | 60 +- .../ui/actions/MindMapActionFactory.java | 1601 +-- .../src/org/xmind/ui/blackbox/BlackBox.java | 84 +- .../xmind/ui/blackbox/BlackBoxLibrary.java | 612 +- .../xmind/ui/blackbox/BlackBoxManager.java | 526 +- .../org/xmind/ui/blackbox/BlackBoxMap.java | 96 +- .../xmind/ui/blackbox/BlackBoxVersion.java | 116 +- .../xmind/ui/blackbox/IBlackBoxLibrary.java | 48 +- .../org/xmind/ui/blackbox/IBlackBoxMap.java | 36 +- .../xmind/ui/blackbox/IBlackBoxVersion.java | 44 +- .../ui/branch/AbstractBranchStructure.java | 2616 ++-- .../xmind/ui/branch/BoundaryLayoutHelper.java | 794 +- .../xmind/ui/branch/BranchStructureData.java | 176 +- .../ui/branch/IBranchDoubleClickSupport.java | 44 +- .../xmind/ui/branch/IBranchMoveSupport.java | 48 +- .../xmind/ui/branch/IBranchPolicyAdvisor.java | 46 +- .../ui/branch/IBranchPropertyTester.java | 204 +- .../xmind/ui/branch/IBranchStyleSelector.java | 44 +- .../ui/branch/IBranchStyleValueProvider.java | 42 +- .../ICreatableBranchStructureExtension.java | 46 +- .../ILockableBranchStructureExtension.java | 44 +- .../xmind/ui/commands/AddCommentCommand.java | 112 +- .../xmind/ui/commands/AddMarkerCommand.java | 142 +- .../xmind/ui/commands/CloneTopicCommand.java | 94 +- .../xmind/ui/commands/CommandMessages.java | 312 +- .../ui/commands/CreateBoundaryCommand.java | 3 +- .../ui/commands/CreateCommentCommand.java | 42 +- .../xmind/ui/commands/CreateSheetCommand.java | 160 +- .../ui/commands/CreateSummaryCommand.java | 3 +- .../xmind/ui/commands/CreateTopicCommand.java | 86 +- .../ui/commands/DeleteCommentCommand.java | 54 +- .../ui/commands/DeleteMarkerCommand.java | 118 +- .../xmind/ui/commands/DeleteNotesCommand.java | 92 +- .../ui/commands/MindMapCommandConstants.java | 66 +- .../ui/commands/ModifyCommentCommand.java | 78 +- .../ui/commands/ModifyFoldedCommand.java | 266 +- .../commands/ModifyImageAlignmentCommand.java | 134 +- .../ui/commands/ModifyImageSizeCommand.java | 144 +- .../ui/commands/ModifyImageSourceCommand.java | 136 +- .../xmind/ui/commands/ModifyLabelCommand.java | 110 +- .../ModifyLegendVisibilityCommand.java | 3 +- .../ui/commands/ModifyMetadataCommand.java | 66 +- .../xmind/ui/commands/ModifyNotesCommand.java | 134 +- .../commands/ModifyNumberingDepthCommand.java | 88 +- .../ui/commands/ModifyPositionCommand.java | 104 +- ...ghtNumberOfUnbalancedStructureCommand.java | 122 +- .../commands/ModifySheetTabColorCommand.java | 116 +- .../xmind/ui/commands/ModifyStyleCommand.java | 130 +- .../ui/commands/ModifyTitleTextCommand.java | 106 +- .../commands/ModifyTopicHyperlinkCommand.java | 102 +- .../commands/ModifyTopicStructureCommand.java | 229 +- .../ModifyTopicTitleWidthCommand.java | 116 +- .../org/xmind/ui/commands/messages.properties | 250 +- .../AbstractBoundaryDecoration.java | 276 +- .../decorations/AbstractBranchConnection.java | 638 +- .../AbstractCalloutTopicDecoration.java | 178 +- .../AbstractRelationshipDecoration.java | 944 +- .../ui/decorations/IBoundaryDecoration.java | 38 +- .../ui/decorations/IBranchConnections2.java | 62 +- .../ui/decorations/IBranchDecoration.java | 46 +- .../decorations/ICalloutTopicDecoration.java | 66 +- .../ui/decorations/IDecorationFactory.java | 44 +- .../ui/decorations/IDecorationManager.java | 80 +- .../ui/decorations/ILineDecoration2.java | 92 +- .../decorations/IRelationshipDecoration.java | 88 +- .../xmind/ui/dialogs/IDialogConstants.java | 52 +- .../xmind/ui/editor/EditorHistoryItem.java | 216 +- .../org/xmind/ui/editor/IEditorHistory.java | 438 +- .../xmind/ui/editor/IEditorHistoryItem.java | 22 +- .../ui/editor/PageTitleTabFolderRenderer.java | 402 +- .../internal/AttachmentImageDescriptor.java | 252 +- .../xmind/ui/internal/CategoryManager.java | 438 +- .../org/xmind/ui/internal/ClonedTemplate.java | 138 +- .../xmind/ui/internal/ColorfulSheetMenu.java | 296 +- .../ui/internal/DndClientDescriptor.java | 162 +- .../org/xmind/ui/internal/EditorHistory.java | 582 +- .../EditorHistoryPersistenceService.java | 464 +- .../ui/internal/EmptyControlContribution.java | 56 +- .../internal/IconTipContributorManager.java | 164 +- .../internal/ImageActionExtensionManager.java | 612 +- .../internal/InfoItemContributorManager.java | 192 +- .../ui/internal/InfoItemContributorProxy.java | 456 +- .../xmind/ui/internal/InternalMindMapUI.java | 488 +- .../xmind/ui/internal/MarkerImpExpUtils.java | 228 +- .../MindMapContributedContentPageFactory.java | 82 +- .../org/xmind/ui/internal/MindMapImages.java | 454 +- .../xmind/ui/internal/MindMapMessages.java | 1566 +-- .../ui/internal/MindMapResourceManager.java | 2858 ++--- .../ui/internal/MindMapTemplateManager.java | 718 +- .../xmind/ui/internal/MindMapUIPlugin.java | 556 +- .../internal/MindMapWordContextProvider.java | 996 +- .../internal/MindMappingServiceFactory.java | 110 +- .../xmind/ui/internal/ModelCacheManager.java | 144 +- .../NumberFormatExtensionManager.java | 466 +- .../xmind/ui/internal/RegistryConstants.java | 250 +- .../SeparatorControlContribution.java | 72 +- .../org/xmind/ui/internal/ServiceManager.java | 102 +- .../org/xmind/ui/internal/ShareOption.java | 184 +- .../ui/internal/ShareOptionRegistry.java | 196 +- .../ShareOptionRegistryPropertyTester.java | 44 +- .../ui/internal/StyleSheetPropertyTester.java | 106 +- .../ui/internal/TemplateManagerImpl.java | 540 +- .../internal/TopicBranchAdapterFactory.java | 124 +- .../ui/internal/TopicContextService.java | 110 +- .../ui/internal/actions/ActionConstants.java | 344 +- .../ui/internal/actions/AlignmentAction.java | 114 +- .../ui/internal/actions/AllMarkersMenu.java | 182 +- .../actions/AllowManualLayoutAction.java | 49 +- .../actions/AllowManualLayoutMenu.java | 166 +- .../internal/actions/AllowOverlapsAction.java | 75 +- .../internal/actions/AllowOverlapsMenu.java | 184 +- .../actions/BaseNewFromTemplateAction.java | 210 +- .../actions/CancelHyperlinkAction.java | 164 +- .../internal/actions/CollapseAllAction.java | 144 +- .../actions/CopiedSheetStorageSupport.java | 108 +- .../ui/internal/actions/CopySheetAction.java | 72 +- .../internal/actions/CreateCommentAction.java | 128 +- .../actions/CreateRelationshipAction.java | 4 +- .../internal/actions/CreateSheetAction.java | 179 +- .../actions/CreateSheetFromTopicAction.java | 11 +- .../xmind/ui/internal/actions/CutAction.java | 64 +- .../internal/actions/DeleteCommentAction.java | 102 +- .../internal/actions/DeleteNotesAction.java | 106 +- .../actions/DeleteOtherSheetsAction.java | 136 +- .../internal/actions/DeleteSheetAction.java | 130 +- .../ui/internal/actions/DrillDownAction.java | 89 +- .../actions/DropDownInsertImageAction.java | 217 +- .../ui/internal/actions/DuplicateAction.java | 46 +- .../internal/actions/EditCommentsAction.java | 138 +- .../ui/internal/actions/EditLabelAction.java | 3 +- .../ui/internal/actions/EditNotesAction.java | 163 +- .../ui/internal/actions/ExtendAllAction.java | 142 +- .../internal/actions/FindReplaceAction.java | 106 +- .../ui/internal/actions/FitMapAction.java | 30 +- .../internal/actions/FitSelectionAction.java | 32 +- .../ui/internal/actions/GroupMarkers.java | 386 +- .../actions/InsertAttachmentAction.java | 3 +- .../actions/InsertFloatingTopicAction.java | 110 +- .../internal/actions/InsertImageAction.java | 254 +- .../ui/internal/actions/InsertImageMenu.java | 182 +- .../actions/InsertParentTopicAction.java | 288 +- .../actions/InsertSubtopicAction.java | 86 +- .../internal/actions/InsertTopicAction.java | 114 +- .../actions/InsertTopicBeforeAction.java | 92 +- .../actions/MarkerParameterValues.java | 92 +- .../actions/ModifyHyperlinkAction.java | 130 +- .../actions/NewFromMoreTemplateAction.java | 110 +- .../actions/NewFromTemplateFileAction.java | 92 +- .../actions/NewFromTemplateURLAction.java | 86 +- .../internal/actions/NewWorkbookAction.java | 122 +- .../actions/NewWorkbookWizardAction.java | 78 +- .../internal/actions/OpenHomeMapAction.java | 194 +- .../internal/actions/OpenHyperlinkAction.java | 70 +- .../internal/actions/OpenWorkbookAction.java | 106 +- .../ui/internal/actions/PasteSheetAction.java | 82 +- .../RecentFileListContributionItem.java | 203 +- .../internal/actions/RenameSheetAction.java | 8 +- .../internal/actions/ReopenWorkbookMenu.java | 642 +- .../internal/actions/ReplaceMarkerAction.java | 236 +- .../internal/actions/ResetPositionAction.java | 149 +- .../internal/actions/SaveSheetAsAction.java | 238 +- .../internal/actions/ShowAllNotesAction.java | 104 +- .../actions/ShowRevisionsActionDelegate.java | 78 +- .../xmind/ui/internal/actions/SortAction.java | 44 +- .../internal/actions/SortRequestAction.java | 66 +- .../ui/internal/actions/StructureMenu.java | 312 +- .../actions/StructureMenuDynamic.java | 402 +- .../xmind/ui/internal/actions/TileAction.java | 3 +- .../ui/internal/actions/TryProAction.java | 602 +- .../ui/internal/actions/ViewerAction.java | 126 +- .../internal/branch/AbstractBranchPolicy.java | 660 +- .../branch/AbstractBranchStyleSelector.java | 306 +- .../branch/AntiClockwiseRadialStructure.java | 850 +- .../internal/branch/BaseRadialStructure.java | 1054 +- .../internal/branch/BranchPolicyManager.java | 942 +- .../branch/ClockwiseRadialStructure.java | 476 +- .../ContributedBranchStyleSelector.java | 302 +- .../internal/branch/DefaultBranchPolicy.java | 206 +- .../branch/DefaultBranchStyleSelector.java | 72 +- .../ui/internal/branch/DownStructure.java | 42 +- .../branch/FloatingMapBranchHook.java | 393 +- .../internal/branch/LeftRightStructure.java | 732 +- .../ui/internal/branch/LeftStructure.java | 42 +- .../ui/internal/branch/LeftTreeStructure.java | 42 +- .../ui/internal/branch/MapBranchHook.java | 389 +- .../branch/MapBranchPropertyTester.java | 98 +- .../ui/internal/branch/OverridedStyle.java | 314 +- .../internal/branch/ParentValueProvider.java | 238 +- .../ui/internal/branch/RadialStructure.java | 462 +- .../ui/internal/branch/RightStructure.java | 42 +- .../internal/branch/RightTreeStructure.java | 40 +- .../internal/branch/TimelineBranchHook.java | 186 +- .../branch/TimelineHorizontalData.java | 96 +- .../TimelineHorizontalDownStructure.java | 20 +- .../TimelineHorizontalHeadStructure.java | 728 +- .../TimelineHorizontalPropertyTester.java | 72 +- .../branch/TimelineHorizontalStructure.java | 808 +- .../branch/TimelineHorizontalUpStructure.java | 18 +- .../internal/branch/TimelineVerticalData.java | 96 +- .../branch/TimelineVerticalHeadStructure.java | 728 +- .../TimelineVerticalPropertyTester.java | 72 +- .../ui/internal/branch/UnbalancedData.java | 98 +- .../internal/branch/UnbalancedStructure.java | 358 +- .../ui/internal/branch/UpDownStructure.java | 976 +- .../xmind/ui/internal/branch/UpStructure.java | 42 +- .../ui/internal/comments/CommentAction.java | 90 +- .../internal/comments/CommentTextViewer.java | 2645 ++-- .../CommentsActionBarContributor.java | 190 +- .../internal/comments/CommentsConstants.java | 22 +- .../comments/CommentsInfoItemContributor.java | 382 +- .../CommentsPartActionBarContributor.java | 56 +- .../ui/internal/comments/CommentsPopup.java | 1624 ++- .../CommentsPopupActionBarContributor.java | 340 +- .../comments/CommentsSelectionProvider.java | 110 +- .../ui/internal/comments/CommentsUtils.java | 200 +- .../ui/internal/comments/ICommentAction.java | 22 +- .../comments/ICommentTextViewerContainer.java | 74 +- .../ICommentsActionBarContributor.java | 54 +- .../comments/SheetCommentsViewer.java | 1452 +-- .../comments/ShowNextTopicCommentsAction.java | 178 +- .../comments/ShowPreTopicCommentsAction.java | 184 +- .../comments/TopicCommentsViewer.java | 712 +- .../AbstractCalloutBranchConnection.java | 224 +- .../decorations/CalloutBranchConnections.java | 602 +- .../CalloutEllipseBalloonDecoration.java | 146 +- .../CalloutRectangleDecoration.java | 46 +- .../CalloutRoundedRectDecoration.java | 122 +- .../decorations/CircleTopicDecoration.java | 92 +- .../decorations/CloudDecorationFactory.java | 76 +- .../decorations/CloudTopicDecoration.java | 292 +- .../CurvedRelationshipDecoration.java | 230 +- .../decorations/DefaultBranchDecoration.java | 174 +- ...EllipseBalloonCalloutBranchConnection.java | 74 +- .../EllipseCalloutTopicDecoration.java | 80 +- .../ParallelogramTopicDecoration.java | 160 +- .../PolygonBoundaryDecoration.java | 1180 +- .../PolygonBoundaryDecorationFactory.java | 28 +- ...ctangleBalloonCalloutBranchConnection.java | 368 +- .../RoundedPolygonBoundaryDecoration.java | 276 +- ...undedPolygonBoundaryDecorationFactory.java | 30 +- ...dedRectBalloonCalloutBranchConnection.java | 524 +- .../RoundedRectCalloutTopicDecoration.java | 288 +- .../SegmentedBoundaryDecoration.java | 234 +- .../decorations/StraightBranchConnection.java | 166 +- .../StraightRelationshipDecoration.java | 102 +- .../StrokeCircleDecorationFactory.java | 96 +- .../StrokeCircleTopicDecoration.java | 242 +- .../TimelineHorizontalConnection.java | 186 +- .../TimelineHorizontalConnectionFactory.java | 28 +- .../decorations/UnderlineTopicDecoration.java | 148 +- .../BoundaryTitleTextDecorator.java | 192 +- .../decorators/InfoItemContentDecorator.java | 140 +- .../decorators/InfoItemIconDecorator.java | 84 +- .../decorators/InformationDecorator.java | 184 +- .../decorators/LegendItemDecorator.java | 124 +- .../decorators/PlusMinusDecorator.java | 202 +- .../decorators/RelTitleTextDecorator.java | 274 +- .../decorators/RelationshipDecorator.java | 352 +- .../internal/decorators/SheetDecorator.java | 578 +- .../decorators/TitleTextDecorator.java | 292 +- .../internal/decorators/TopicDecorator.java | 374 +- .../ui/internal/dialogs/BlackBoxDialog.java | 1198 +- .../ui/internal/dialogs/DialogMessages.java | 446 +- .../ui/internal/dialogs/DialogUtils.java | 492 +- .../dialogs/NewSheetFromTemplateDialog.java | 350 +- .../internal/dialogs/OpenWorkbookDialog.java | 318 +- .../internal/dialogs/ProgressDialogPart.java | 1347 +- .../dialogs/RevisionPreviewDialog.java | 1282 +- .../ui/internal/dialogs/SaveWizardDialog.java | 404 +- .../ui/internal/dialogs/ShareDialog.java | 538 +- .../internal/dialogs/TopicHyperlinkPage.java | 482 +- .../ui/internal/dialogs/WallpaperDialog.java | 1865 +-- .../dialogs/WorkbookMetaInspectorDialog.java | 4546 +++---- .../dialogs/WorkbookRevisionDialog.java | 1766 +-- .../ui/internal/dialogs/messages.properties | 352 +- .../xmind/ui/internal/dnd/ImageDndClient.java | 226 +- .../ui/internal/dnd/MindMapDNDClientBase.java | 758 +- .../internal/dnd/MindMapElementTransfer.java | 312 +- .../xmind/ui/internal/dnd/TextDndClient.java | 332 +- .../xmind/ui/internal/dnd/URLDndClient.java | 188 +- .../e4handlers/DeleteResourceHandler.java | 58 +- .../e4handlers/DialogPartHandler.java | 302 +- .../e4handlers/DuplicateResourceHandler.java | 58 +- .../e4handlers/EditResourceHandler.java | 58 +- .../internal/e4handlers/ModelPartHandler.java | 183 +- .../e4handlers/NewDefaultWorkbookHandler.java | 62 +- .../e4handlers/OpenHomeMapHandler.java | 104 +- .../e4handlers/OpenLocalFileHandler.java | 69 - .../e4handlers/OpenPopoverHandler.java | 173 +- .../e4handlers/OpenWorkbooksHandler.java | 214 +- .../e4handlers/RenameResourceHandler.java | 60 +- .../e4handlers/SaveWorkbookAsHandler.java | 946 +- .../e4handlers/SetDefaultThemeHandler.java | 152 +- .../e4handlers/ToggleModelPartHandler.java | 238 +- .../ui/internal/e4models/CommentsPart.java | 1543 +-- .../ui/internal/e4models/IModelConstants.java | 177 +- .../xmind/ui/internal/e4models/ImagePart.java | 20 +- .../e4models/LocalImageModelPage.java | 678 +- .../e4models/LocalImageProcessor.java | 74 +- .../ui/internal/e4models/MarkerPart.java | 1518 +-- .../xmind/ui/internal/e4models/NotesPart.java | 2449 ++-- .../internal/e4models/ProgressProcessor.java | 297 +- .../ui/internal/e4models/ThemesPart.java | 661 +- .../internal/editor/AbstractWorkbookRef.java | 1549 +-- .../ui/internal/editor/AuthorInfoEditor.java | 160 +- .../editor/BackgroundSaveWorkbook.java | 352 +- .../ui/internal/editor/ClonedWorkbookRef.java | 254 +- .../internal/editor/CreatedWorkbookRef.java | 204 +- .../ui/internal/editor/DecryptionDialog.java | 476 +- .../internal/editor/DecryptionDialogPane.java | 382 +- .../internal/editor/DefaultEditorLayout.java | 80 +- .../DefaultMindMapPreviewGenerator.java | 202 +- .../xmind/ui/internal/editor/DialogPane.java | 824 +- .../internal/editor/DialogPaneContainer.java | 304 +- .../ui/internal/editor/EditorHistoryImpl.java | 602 +- .../EditorHistoryPersistenceHelper.java | 1196 +- .../internal/editor/EditorHistoryProxy.java | 188 +- .../internal/editor/EditorInputMonitor.java | 288 +- .../internal/editor/EditorLayoutManager.java | 86 +- .../internal/editor/EncryptionDailogPane.java | 820 +- .../ui/internal/editor/EncryptionDialog.java | 934 +- .../xmind/ui/internal/editor/ErrorDialog.java | 402 +- .../ui/internal/editor/ErrorDialogPane.java | 298 +- .../ui/internal/editor/ErrorDialogPane2.java | 424 +- .../ui/internal/editor/FileEditorInput.java | 48 +- .../editor/FileEditorInputFactory.java | 158 +- .../xmind/ui/internal/editor/IDialogPane.java | 98 +- .../internal/editor/IDialogPaneContainer.java | 104 +- .../internal/editor/IEditorHistoryLoader.java | 96 +- .../ui/internal/editor/IEditorLayout.java | 34 +- .../internal/editor/IEditorLayoutManager.java | 28 +- .../ui/internal/editor/IEncryptable.java | 136 +- .../xmind/ui/internal/editor/IMESupport.java | 1154 +- .../editor/IMindMapPreviewGenerator.java | 106 +- .../ui/internal/editor/IPasswordProvider.java | 52 +- .../ui/internal/editor/IWorkbookReferrer.java | 78 +- .../ui/internal/editor/IWorkbookSaver.java | 76 +- .../ui/internal/editor/LoadWorkbookJob.java | 312 +- .../internal/editor/LocalFileSaveWizard.java | 174 +- .../internal/editor/LocalFileWorkbookRef.java | 1495 +-- .../editor/LocalFileWorkbookRefFactory.java | 64 +- .../src/org/xmind/ui/internal/editor/MME.java | 820 +- .../internal/editor/MindMapContributor.java | 1020 +- .../ui/internal/editor/MindMapEditor.java | 4296 +++---- .../internal/editor/MindMapEditorInput.java | 324 +- .../editor/MindMapEditorInputFactory.java | 132 +- .../ui/internal/editor/MindMapEditorPage.java | 1491 ++- .../MindMapEditorPagePanelContributor.java | 1452 +-- .../MindMapEditorPagePopupPreviewHelper.java | 118 +- .../MindMapFindReplaceOperationProvider.java | 1780 +-- .../editor/MindMapMiniBarContributor.java | 118 +- .../editor/MindMapPageTitleEditor.java | 288 +- .../editor/MindMapPreviewOptions.java | 50 +- .../internal/editor/MiniZoomContribution.java | 1198 +- .../editor/OverviewCheckContribution.java | 296 +- .../internal/editor/PreLoadedWorkbookRef.java | 316 +- .../editor/ResourceFileOutputStream.java | 160 +- .../ui/internal/editor/SaveActionUpdater.java | 280 +- .../ui/internal/editor/SaveWizardManager.java | 366 +- .../editor/TempWorkbookRefFactory.java | 64 +- .../xmind/ui/internal/editor/URIParser.java | 262 +- .../ui/internal/editor/URLWorkbookRef.java | 462 +- .../editor/WorkbookBackupManager.java | 310 +- .../internal/editor/WorkbookEditorInput.java | 198 +- .../ui/internal/editor/WorkbookHistory.java | 576 +- .../internal/editor/WorkbookHistoryItem.java | 168 +- .../xmind/ui/internal/editor/WorkbookRef.java | 1042 +- .../editor/WorkbookRefEncryptable.java | 474 +- .../editor/WorkbookRefFactoryManager.java | 390 +- .../internal/editor/WorkbookRefManager.java | 102 +- .../editor/WorkbookRefPropertyTester.java | 128 +- .../editor/XMindFileBrowserContribution.java | 490 +- .../CreateSheetFromTopicCommandBuilder.java | 286 +- .../CreateTopicCommandBuilder.java | 678 +- .../editpolicies/DeletablePolicy.java | 388 +- .../editpolicies/DeleteCommandBuilder.java | 736 +- .../internal/editpolicies/EditablePolicy.java | 1142 +- .../ui/internal/editpolicies/MapPolicy.java | 286 +- .../MindMapNavigablePolicyBase.java | 280 +- .../editpolicies/MindMapPolicyBase.java | 196 +- .../editpolicies/ModifiablePolicy.java | 1174 +- .../ModifyStyleCommandBuilder.java | 628 +- .../ModifyThemeCommandBuilder.java | 274 +- .../editpolicies/PropertyCommandBuilder.java | 472 +- .../RelationshipCreateCommandBuilder.java | 196 +- .../editpolicies/SheetCreatablePolicy.java | 432 +- .../editpolicies/SortTopicCommandBuilder.java | 686 +- .../editpolicies/TopicCreatablePolicy.java | 2261 ++-- .../editpolicies/TopicMovablePolicy.java | 894 +- .../editpolicies/TopicMoveCommandBuilder.java | 916 +- .../editpolicies/TopicNavigablePolicy.java | 690 +- .../ui/internal/figures/BoundaryFigure.java | 252 +- .../internal/figures/BoundaryTitleFigure.java | 338 +- .../ui/internal/figures/BranchFigure.java | 636 +- .../internal/figures/InformationFigure.java | 170 +- .../figures/InformationItemFigure.java | 304 +- .../ui/internal/figures/LegendItemFigure.java | 348 +- .../figures/LegendSeparatorFigure.java | 88 +- .../internal/figures/RelationshipFigure.java | 240 +- .../ui/internal/figures/SheetFigure.java | 38 +- .../ui/internal/figures/TopicFigure.java | 568 +- .../AbstractFindReplaceOperationProvider.java | 372 +- .../findreplace/FindReplaceDialog.java | 1622 +-- .../IFindReplaceOperationProvider.java | 192 +- .../graphicalpolicies/SheetStyleSelector.java | 48 +- .../internal/handlers/AddMarkerHandler.java | 96 +- .../internal/handlers/AlignmentHandler.java | 130 +- .../internal/handlers/ApplyStyleHandler.java | 116 +- .../handlers/ClearMarkersHandler.java | 114 +- .../handlers/ClearWorkbookHistoryHandler.java | 122 +- .../handlers/ColorfulSheetHandler.java | 144 +- .../internal/handlers/CopyStyleHandler.java | 199 +- .../CreateSheetFromTemplateHandler.java | 292 +- .../handlers/DeleteRevisionHandler.java | 128 +- .../internal/handlers/DeleteStyleHandler.java | 202 +- .../handlers/EditCommentsHandler.java | 164 +- .../handlers/ExportMarkerHandler.java | 66 +- .../handlers/IMindMapCommandConstants.java | 118 +- .../handlers/ImportFromWorkbookHandler.java | 200 +- .../handlers/ImportMarkerHandler.java | 66 +- .../internal/handlers/MindMapHandlerUtil.java | 454 +- .../handlers/NewDefaultWorkbookHandler.java | 44 +- .../handlers/OpenBlackBoxDialogHandler.java | 96 +- .../internal/handlers/OpenHomeMapHandler.java | 40 +- .../handlers/OpenWorkbooksHandler.java | 122 +- .../internal/handlers/PasteStyleHandler.java | 92 +- .../handlers/PreviewRevisionHandler.java | 114 +- .../handlers/ReduceFileSizeHandler.java | 73 +- .../RemoveMarkerFromAllTopicsHandler.java | 162 +- .../internal/handlers/ResetStyleHandler.java | 112 +- .../handlers/RevertToRevisionHandler.java | 192 +- .../handlers/SaveAsTemplateHandler.java | 338 +- .../handlers/SaveAttachmentAsHandler.java | 204 +- .../handlers/SaveAudioNoteAsHandler.java | 250 +- .../internal/handlers/SaveImageAsHandler.java | 230 +- .../internal/handlers/SaveSheetAsHandler.java | 198 +- .../handlers/SaveWorkbookAsHandler.java | 298 +- .../internal/handlers/SendRequestHandler.java | 194 +- .../handlers/ShowEditingHistoryHandler.java | 162 +- .../handlers/ShowMarkerManagerHandler.java | 42 +- .../ShowResourceManagerDialogHanlder.java | 46 +- .../handlers/ShowShareOptionsHandler.java | 98 +- .../ShowWorkbookMetaInspectorHandler.java | 78 +- .../ui/internal/handlers/SortHandler.java | 108 +- .../ui/internal/layers/BackgroundLayer.java | 100 +- .../ui/internal/layers/MindMapViewport.java | 46 +- .../ui/internal/layers/PresentationLayer.java | 42 +- .../ui/internal/layers/UndoRedoTipsLayer.java | 42 +- .../internal/layouts/InformationLayout.java | 170 +- .../ui/internal/layouts/LegendLayout.java | 190 +- .../layouts/SheetIntersectionSolver.java | 312 +- .../ui/internal/layouts/SheetLayout.java | 268 +- .../ui/internal/layouts/TopicLayout.java | 766 +- .../org/xmind/ui/internal/messages.properties | 1172 +- .../mindmap/ArabicNumberingFormat.java | 46 +- .../ui/internal/mindmap/BoundaryPart.java | 784 +- .../mindmap/BoundaryTitleTextPart.java | 144 +- .../xmind/ui/internal/mindmap/BranchPart.java | 2138 ++-- .../mindmap/DecoratedRelFeedback.java | 164 +- .../mindmap/DrillDownTraceService.java | 294 +- .../internal/mindmap/EditorInputFactory.java | 118 +- .../ui/internal/mindmap/HighlightService.java | 30 +- .../mindmap/HyperlinkInfoItemContributor.java | 522 +- .../ui/internal/mindmap/IconTipPart.java | 628 +- .../internal/mindmap/ImageDownloadCenter.java | 526 +- .../ui/internal/mindmap/ImageDownloader.java | 606 +- .../xmind/ui/internal/mindmap/ImagePart.java | 678 +- .../mindmap/ImageSelectionHelper.java | 74 +- .../ui/internal/mindmap/InfoItemContent.java | 92 +- .../internal/mindmap/InfoItemContentPart.java | 116 +- .../ui/internal/mindmap/InfoItemIcon.java | 92 +- .../ui/internal/mindmap/InfoItemIconPart.java | 590 +- .../xmind/ui/internal/mindmap/InfoPart.java | 578 +- .../mindmap/LabelInfoItemContributor.java | 394 +- .../xmind/ui/internal/mindmap/LabelPart.java | 306 +- .../xmind/ui/internal/mindmap/LegendItem.java | 240 +- .../ui/internal/mindmap/LegendItemPart.java | 380 +- .../xmind/ui/internal/mindmap/LegendPart.java | 474 +- .../internal/mindmap/LegendSeparatorPart.java | 78 +- .../internal/mindmap/LegendTitleTextPart.java | 76 +- .../mindmap/LowerCaseNumberFormat.java | 50 +- .../internal/mindmap/MindMapEditDomain.java | 368 +- .../ui/internal/mindmap/MindMapPartBase.java | 38 +- .../mindmap/MindMapRevealService.java | 186 +- .../ui/internal/mindmap/MindMapRootPart.java | 488 +- .../ui/internal/mindmap/MindMapState.java | 518 +- .../ui/internal/mindmap/MindMapViewer.java | 769 +- .../ui/internal/mindmap/NoneNumberFormat.java | 46 +- .../xmind/ui/internal/mindmap/Overview.java | 888 +- .../ui/internal/mindmap/PlusMinusPart.java | 242 +- .../ui/internal/mindmap/RelTitleTextPart.java | 110 +- .../ui/internal/mindmap/RelationshipPart.java | 632 +- .../mindmap/RelationshipSelectionHelper.java | 190 +- .../internal/mindmap/RomanNumberFormat.java | 48 +- .../mindmap/SelectionFeedbackHelper.java | 18 +- .../xmind/ui/internal/mindmap/SheetPart.java | 764 +- .../mindmap/SimpleChineseNumberFormat.java | 26 +- .../ui/internal/mindmap/SummaryPart.java | 1238 +- .../ui/internal/mindmap/TitleTextPart.java | 170 +- .../mindmap/ToolExtensionRegistry.java | 256 +- .../ui/internal/mindmap/TopicContext.java | 140 +- .../xmind/ui/internal/mindmap/TopicPart.java | 1482 +-- .../TraditionalChineseNumberFormat.java | 26 +- .../internal/mindmap/UndoRedoTipsService.java | 1212 +- .../mindmap/UpperCaseNumberFormat.java | 50 +- .../notes/HtmlNotesContentBuilder.java | 928 +- .../internal/notes/INotesContentViewer.java | 32 +- .../NotesFindReplaceOperationProvider.java | 372 +- .../notes/NotesHyperlinkDetector.java | 30 +- .../notes/NotesInfoItemContributor.java | 369 +- .../xmind/ui/internal/notes/NotesPopup.java | 1564 +-- .../internal/notes/NotesTextEditViewer.java | 1838 +-- .../ui/internal/notes/NotesTextViewer.java | 40 +- .../xmind/ui/internal/notes/NotesUtils.java | 126 +- .../internal/notes/RichDocumentBuilder.java | 976 +- .../notes/RichDocumentNotesAdapter.java | 432 +- .../ui/internal/notes/SheetNotesViewer.java | 1670 +-- .../ui/internal/notes/TopicNotesViewer.java | 622 +- .../internal/outline/MindMapOutlinePage.java | 732 +- .../internal/outline/MindMapTreeRootPart.java | 38 +- .../outline/OutlineIndexModelPart.java | 2483 ++-- .../ui/internal/outline/OutlineType.java | 118 +- .../ui/internal/outline/OutlineViewer.java | 874 +- .../ui/internal/outline/SheetTreePart.java | 154 +- .../ui/internal/outline/TopicTreePart.java | 168 +- .../outline/resource/AZResourceForSheet.java | 118 +- .../resource/AZResourceForWorkbook.java | 118 +- .../resource/AbstractIndexResource.java | 70 +- .../resource/AssigneeResourceForSheet.java | 170 +- .../resource/AssigneeResourceForWorkbook.java | 172 +- .../outline/resource/IAZResource.java | 30 +- .../outline/resource/IAssigneeResource.java | 26 +- .../outline/resource/ILabelResource.java | 26 +- .../outline/resource/IMarkerResource.java | 32 +- .../outline/resource/IOutlineResource.java | 16 +- .../outline/resource/ITaskDateResource.java | 42 +- .../resource/LabelResourceForSheet.java | 142 +- .../resource/LabelResourceForWorkbook.java | 142 +- .../resource/MarkerResourceForSheet.java | 178 +- .../resource/MarkerResourceForWorkbook.java | 180 +- .../outline/resource/OutlineResources.java | 420 +- .../resource/TaskDateResourceForSheet.java | 342 +- .../resource/TaskDateResourceForWorkbook.java | 344 +- .../popover/MarkerPopoverMenuToolItem.java | 1465 ++- .../internal/popover/PopoverMenuToolItem.java | 288 +- .../popover/ThemePopoverMenuToolItem.java | 1278 +- .../ui/internal/prefs/AuthorInfoPrefPage.java | 448 +- .../prefs/AuthorInfoPreferenceSection.java | 430 +- .../xmind/ui/internal/prefs/DnDPrefPage.java | 244 +- .../prefs/DnDPreferencePageSection.java | 84 +- .../ui/internal/prefs/EditorPrefPage.java | 420 +- .../internal/prefs/MarkerManagerPrefPage.java | 1304 +- .../prefs/OthersPreferenceSection.java | 162 +- .../xmind/ui/internal/prefs/PrefMessages.java | 164 +- .../internal/prefs/PreferenceInitializer.java | 118 +- .../prefs/ThemePreferencePageSection.java | 100 +- .../prefs/TopicPositionPreferenceSection.java | 140 +- .../prefs/UndoRedoPreferencePageSection.java | 108 +- .../ui/internal/prefs/messages.properties | 92 +- .../xmind/ui/internal/print/PrintClient.java | 1172 +- .../ui/internal/print/PrintConstants.java | 256 +- .../xmind/ui/internal/print/PrintUtils.java | 168 +- .../multipage/DialogSettingsDecorator.java | 264 +- .../MultipageImagePreviewViewer.java | 1914 +-- .../print/multipage/MultipagePrintClient.java | 1258 +- .../print/multipage/MultipageSetupDialog.java | 3608 +++--- .../print/multipage/PrintDialogLayout.java | 216 +- .../print/multipage/PrintMapAction2.java | 296 +- .../multipage/PrintMultipageMapHandler.java | 286 +- .../PrintMultipagePreviewImageCreator.java | 1370 +-- .../print/multipage/PrintMultipageUtils.java | 62 +- .../BoundaryShapePropertySectionPart.java | 824 +- .../properties/FontPropertySectionPart.java | 1339 +- .../properties/IStyleEditingDelegate.java | 14 +- .../properties/IStyleEditingSectionPart.java | 18 +- .../ImageSizePropertySectionPart.java | 576 +- .../properties/LegendPropertySectionPart.java | 3 +- .../LinePropertySectionPartBase.java | 302 +- .../ui/internal/properties/LineWidth.java | 158 +- .../properties/MindMapPropertySheetPage.java | 616 +- .../NumberingPropertySectionPart.java | 1115 +- .../internal/properties/PropertiesPart.java | 1565 +-- .../internal/properties/PropertyMessages.java | 232 +- ...SheetAdvancedStylePropertySectionPart.java | 237 +- .../SheetInfoCardPropertySectionPart.java | 390 +- ...iBranchColorsStylePropertySectionPart.java | 569 +- .../StructurePropertySectionPart.java | 552 +- .../properties/StylesPropertySectionPart.java | 926 +- .../TopicShapePropertySectionPart.java | 774 +- .../WallpaperPropertySectionPart.java | 808 +- .../internal/properties/messages.properties | 176 +- .../protocols/AttachmentProtocol.java | 556 +- .../ui/internal/protocols/FilePathParser.java | 1088 +- .../ui/internal/protocols/FileProtocol.java | 296 +- .../internal/protocols/ProtocolManager.java | 518 +- .../ui/internal/protocols/WebProtocol.java | 632 +- .../IResourceManagerDialogPage.java | 62 +- .../MarkerResourceManagerPage.java | 453 +- .../MarkerResourceManagerViewer.java | 921 +- .../ResourceManagerDialogPage.java | 376 +- .../ResourceManagerDialogPart.java | 658 +- .../ResourceManagerStyleProvider.java | 284 +- .../ResourceManagerViewer.java | 494 +- .../StyleResourceManagerPage.java | 524 +- .../StyleResourceManagerViewer.java | 872 +- .../TemplateResourceManagerPage.java | 562 +- .../TemplateResourceManagerViewer.java | 644 +- .../ThemeResourceManagerViewer.java | 492 +- .../svgsupport/ColorName2HexRGBValue.java | 360 +- .../internal/svgsupport/ColorRecognizer.java | 184 +- .../svgsupport/FontResourceDescriptor.java | 164 +- .../internal/svgsupport/LinearGradient.java | 434 +- .../ui/internal/svgsupport/PathElement.java | 446 +- .../internal/svgsupport/PathLocationInfo.java | 150 +- .../ui/internal/svgsupport/PathParser.java | 498 +- .../svgsupport/PatternResourceDescriptor.java | 156 +- .../internal/svgsupport/SVGCircleShape.java | 192 +- .../ui/internal/svgsupport/SVGColor.java | 156 +- .../ui/internal/svgsupport/SVGDefinition.java | 18 +- .../svgsupport/SVGDefinitionConstants.java | 142 +- .../internal/svgsupport/SVGEllipseShape.java | 208 +- .../ui/internal/svgsupport/SVGGroup.java | 250 +- .../ui/internal/svgsupport/SVGImageData.java | 610 +- .../internal/svgsupport/SVGImageFigure.java | 262 +- .../ui/internal/svgsupport/SVGLineShape.java | 190 +- .../xmind/ui/internal/svgsupport/SVGPath.java | 196 +- .../internal/svgsupport/SVGPolyLineShape.java | 234 +- .../internal/svgsupport/SVGPolygonShape.java | 244 +- .../svgsupport/SVGRectangleShape.java | 228 +- .../ui/internal/svgsupport/SVGReference.java | 44 +- .../ui/internal/svgsupport/SVGShape.java | 488 +- .../internal/svgsupport/SVGShapeFactory.java | 64 +- .../internal/svgsupport/SVGShapeInfoMap.java | 740 +- .../internal/svgsupport/SVGTextElement.java | 322 +- .../ui/internal/svgsupport/SVGTransform.java | 362 +- .../ui/internal/svgsupport/SVGUseElement.java | 220 +- .../ui/internal/svgsupport/SvgFileLoader.java | 204 +- .../ui/internal/svgsupport/SvgPathParser.java | 610 +- .../internal/svgsupport/TransformElement.java | 26 +- .../xmind/ui/internal/tools/BranchDummy.java | 642 +- .../tools/FloatingTopicCreateTool.java | 428 +- .../ui/internal/tools/ImageMoveTool.java | 270 +- .../internal/tools/ImageMoveToolHelper.java | 504 +- .../ui/internal/tools/LabelEditTool.java | 358 +- .../internal/tools/LabelProposalProvider.java | 408 +- .../ui/internal/tools/LegendItemEditTool.java | 118 +- .../ui/internal/tools/MarkerMoveTool.java | 274 +- .../ui/internal/tools/MindMapDndTool.java | 852 +- .../ui/internal/tools/MindMapSelectTool.java | 2814 +++-- .../internal/tools/MindMapTraverseTool.java | 48 +- .../ui/internal/tools/QuickOpenHelper.java | 184 +- .../ui/internal/tools/RangeResizeTool.java | 488 +- .../tools/RelationshipCreateTool.java | 474 +- .../ui/internal/tools/RelationshipDummy.java | 652 +- .../ui/internal/tools/SheetTitleEditTool.java | 270 +- .../ui/internal/tools/StyleCopyPasteTool.java | 62 +- .../internal/tools/TopicAreaSelectTool.java | 154 +- .../ui/internal/tools/TopicMoveTool.java | 1458 +-- .../internal/tools/TopicMoveToolHelper.java | 1008 +- .../ui/internal/tools/TopicTitleEditTool.java | 605 +- .../xmind/ui/internal/utils/CommandUtils.java | 68 +- .../org/xmind/ui/internal/utils/E4Utils.java | 160 +- .../ui/internal/utils/ResourceUtils.java | 590 +- .../views/AttachmentsInspectorSection.java | 300 +- .../views/AuthorInfoInspectorSection.java | 472 +- .../ui/internal/views/AuthorInfoViewer.java | 344 +- .../xmind/ui/internal/views/BlackBoxView.java | 998 +- .../views/CategorizedThemeViewer.java | 825 +- .../xmind/ui/internal/views/CommentsView.java | 1362 +-- .../ui/internal/views/ContentListViewer.java | 1428 +-- .../internal/views/DefaultOverviewPage.java | 104 +- .../views/ExternalFilesInspectorSection.java | 356 +- .../views/FileInfoInspectorSection.java | 1034 +- .../views/HyperlinkInspectorSection.java | 294 +- .../internal/views/ImageInspectorSection.java | 338 +- .../views/ImageInspectorSection2.java | 390 +- .../views/InspectorContentSection.java | 114 +- .../ui/internal/views/InspectorSection.java | 570 +- .../ui/internal/views/InspectorView.java | 308 +- .../ui/internal/views/InspectorViewer.java | 404 +- .../xmind/ui/internal/views/MarkerView.java | 1880 +-- .../org/xmind/ui/internal/views/Messages.java | 124 +- .../internal/views/NotesHyperlinkDialog.java | 300 +- .../xmind/ui/internal/views/NotesView.java | 2320 ++-- .../xmind/ui/internal/views/OverviewView.java | 156 +- .../ui/internal/views/RevisionsPage.java | 786 +- .../ui/internal/views/RevisionsView.java | 436 +- .../ui/internal/views/SheetOverviewPage.java | 748 +- .../xmind/ui/internal/views/StyleFigure.java | 184 +- .../ui/internal/views/StyleFigureUtils.java | 2792 ++--- .../xmind/ui/internal/views/ThemeFigure.java | 624 +- .../ui/internal/views/ThemeGroupCore.java | 514 +- .../ui/internal/views/ThemeLabelProvider.java | 1470 +-- .../internal/views/ThemeOverrideDialog.java | 322 +- .../xmind/ui/internal/views/ThemeUICore.java | 466 +- .../xmind/ui/internal/views/ThemesView.java | 824 +- .../xmind/ui/internal/views/ThemesViewer.java | 292 +- .../internal/views/WorkbookMetadataPage.java | 4354 +++---- .../internal/views/WorkbookOverviewPage.java | 190 +- .../internal/views/WorkbookRevisionsPage.java | 618 +- .../ui/internal/views/messages.properties | 92 +- .../xmind/ui/internal/wizards/ExportPage.java | 550 +- .../wizards/FreeMindExportWizard.java | 261 +- .../ui/internal/wizards/FreeMindExporter.java | 1356 +-- .../ui/internal/wizards/HtmlExportWizard.java | 242 +- .../ui/internal/wizards/HtmlExporter.java | 2160 ++-- .../ui/internal/wizards/ITextExportPart.java | 46 +- .../internal/wizards/ImageExportWizard.java | 1789 +-- .../ui/internal/wizards/ImportExportPage.java | 1666 +-- .../internal/wizards/ImportExportWizard.java | 192 +- .../xmind/ui/internal/wizards/ImportPage.java | 212 +- .../internal/wizards/MarkerExportWizard.java | 326 +- .../wizards/MarkerGroupLabelProvider.java | 92 +- .../internal/wizards/MarkerImportWizard.java | 932 +- .../internal/wizards/TemplateImageLoader.java | 528 +- .../wizards/TemplateLabelProvider.java | 920 +- .../ui/internal/wizards/TextExportWizard.java | 754 +- .../ui/internal/wizards/WizardHandler.java | 504 +- .../ui/internal/wizards/WizardMessages.java | 437 +- .../ui/internal/wizards/WorkbookImporter.java | 82 +- .../wizards/XMind2008ExportWizard.java | 370 +- .../internal/wizards/XMind2008Exporter.java | 1836 +-- .../wizards/XMind2008ImportWizard.java | 208 +- .../internal/wizards/XMind2008Importer.java | 129 +- .../ui/internal/wizards/messages.properties | 380 +- .../ui/internal/wizards/wizards_order.xml | 98 +- .../ui/internal/workbench/Perspective.java | 287 +- .../org/xmind/ui/internal/workbench/Util.java | 80 +- .../mindmap/AbstractInfoItemContributor.java | 280 +- .../xmind/ui/mindmap/GhostShellProvider.java | 184 +- .../org/xmind/ui/mindmap/IAnimatablePart.java | 48 +- .../org/xmind/ui/mindmap/IBoundaryPart.java | 46 +- .../src/org/xmind/ui/mindmap/IBranchPart.java | 246 +- .../xmind/ui/mindmap/IBranchRangePart.java | 62 +- .../xmind/ui/mindmap/ICacheValueProvider.java | 42 +- .../ui/mindmap/IDrillDownTraceListener.java | 38 +- .../ui/mindmap/IDrillDownTraceService.java | 78 +- .../xmind/ui/mindmap/IEditPolicyManager.java | 42 +- .../xmind/ui/mindmap/IEditorInputFactory.java | 64 +- .../ui/mindmap/IElementLabelProvider.java | 46 +- .../ui/mindmap/IGlobalCoreEventHandler.java | 44 +- .../ui/mindmap/IInfoItemContributor.java | 72 +- .../org/xmind/ui/mindmap/IInfoItemPart.java | 70 +- .../src/org/xmind/ui/mindmap/IInfoPart.java | 66 +- .../src/org/xmind/ui/mindmap/ILegendPart.java | 66 +- .../src/org/xmind/ui/mindmap/IMindMap.java | 48 +- .../xmind/ui/mindmap/IMindMapDndClient.java | 68 +- .../ui/mindmap/IMindMapEditorConfigurer.java | 48 +- .../org/xmind/ui/mindmap/IMindMapImages.java | 568 +- .../org/xmind/ui/mindmap/IMindMapViewer.java | 250 +- .../ui/mindmap/INumberFormatDescriptor.java | 46 +- .../org/xmind/ui/mindmap/IPlusMinusPart.java | 48 +- .../src/org/xmind/ui/mindmap/IProtocol.java | 94 +- .../xmind/ui/mindmap/IProtocolManager.java | 88 +- .../xmind/ui/mindmap/IResourceManager.java | 384 +- .../ui/mindmap/IResourceManagerListener.java | 28 +- .../src/org/xmind/ui/mindmap/ISheetPart.java | 74 +- .../src/org/xmind/ui/mindmap/ITemplate.java | 60 +- .../org/xmind/ui/mindmap/ITitleTextPart.java | 44 +- .../org/xmind/ui/mindmap/IViewerModel.java | 48 +- .../org/xmind/ui/mindmap/IWorkbookRef.java | 180 +- .../xmind/ui/mindmap/IWorkbookRefFactory.java | 44 +- .../ui/mindmap/IWorkbookRefListener.java | 20 +- .../xmind/ui/mindmap/IWorkbookRefManager.java | 94 +- .../mindmap/MindMapExportContentProvider.java | 560 +- .../xmind/ui/mindmap/MindMapExportViewer.java | 176 +- .../xmind/ui/mindmap/MindMapExtractor.java | 242 +- .../ui/mindmap/MindMapImageExporter.java | 870 +- .../ui/mindmap/MindMapImageExtractor.java | 364 +- .../ui/mindmap/MindMapPreviewBuilder.java | 602 +- .../src/org/xmind/ui/mindmap/MindMapUI.java | 1472 +-- .../MindMapViewerExportSourceProvider.java | 210 +- .../xmind/ui/mindmap/WorkbookInitializer.java | 200 +- .../src/org/xmind/ui/prefs/PrefConstants.java | 302 +- .../properties/StyledPropertySectionPart.java | 364 +- .../xmind/ui/style/LayeredStyleSelector.java | 158 +- .../ui/style/MindMapStyleSelectorBase.java | 456 +- .../ui/style/PredefinedStyleSelector.java | 184 +- .../src/org/xmind/ui/style/StyleUtils.java | 1452 +-- .../src/org/xmind/ui/style/Styles.java | 1150 +- .../src/org/xmind/ui/style/TextStyleData.java | 318 +- .../org/xmind/ui/tools/GalleryMoveTool.java | 590 +- .../src/org/xmind/ui/tools/IToolHelper.java | 48 +- .../xmind/ui/tools/ITopicMoveToolHelper.java | 54 +- .../xmind/ui/tools/MindMapEditToolBase.java | 216 +- .../org/xmind/ui/util/CollectionUtils.java | 230 +- .../xmind/ui/util/MarkerImageDescriptor.java | 664 +- .../src/org/xmind/ui/util/MindMapUtils.java | 2092 ++-- .../src/org/xmind/ui/util/ResourceFinder.java | 384 +- .../xmind/ui/wizards/AbstractExportPage.java | 523 +- .../ui/wizards/AbstractExportWizard.java | 590 +- .../ui/wizards/AbstractMindMapExportPage.java | 144 +- .../wizards/AbstractMindMapExportWizard.java | 581 +- .../wizards/AbstractMindMapImportWizard.java | 496 +- .../ui/wizards/DocumentExportPageBase.java | 2180 ++-- .../org/xmind/ui/wizards/ExportContants.java | 102 +- .../src/org/xmind/ui/wizards/ExportUtils.java | 192 +- .../org/xmind/ui/wizards/ISaveContext.java | 58 +- .../src/org/xmind/ui/wizards/ISaveWizard.java | 78 +- .../org/xmind/ui/wizards/MindMapImporter.java | 296 +- .../src/org/xmind/ui/wizards/SaveOptions.java | 172 +- bundles/org.xmind.ui.resources/.gitignore | 36 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../org.eclipse.ltk.core.refactoring.prefs | 4 +- .../META-INF/MANIFEST.MF | 20 +- bundles/org.xmind.ui.resources/about.html | 44 +- bundles/org.xmind.ui.resources/check.py | 52 +- .../fragment_resources.properties | 4 +- .../markers/arrow_down@16.svg | 32 +- .../markers/arrow_down_left@16.svg | 32 +- .../markers/arrow_down_right@16.svg | 32 +- .../markers/arrow_left@16.svg | 32 +- .../markers/arrow_refresh@16.svg | 36 +- .../markers/arrow_right@16.svg | 32 +- .../markers/arrow_up@16.svg | 32 +- .../markers/arrow_up_left@16.svg | 32 +- .../markers/arrow_up_right@16.svg | 32 +- .../markers/c_simbol_exclamation@16.svg | 20 +- .../markers/c_simbol_information@16.svg | 20 +- .../markers/c_simbol_minus@16.svg | 20 +- .../markers/c_simbol_pause@16.svg | 20 +- .../markers/c_simbol_plus@16.svg | 20 +- .../markers/c_simbol_question@16.svg | 20 +- .../markers/c_simbol_right@16.svg | 20 +- .../markers/c_simbol_wrong@16.svg | 20 +- .../markers/emotion_angry@16.svg | 42 +- .../markers/emotion_boring@16.svg | 64 +- .../markers/emotion_cry@16.svg | 68 +- .../markers/emotion_embarrass.svg | 44 +- .../markers/emotion_laugh@16.svg | 48 +- .../markers/emotion_smile@16.svg | 44 +- .../markers/emotion_surprise@16.svg | 46 +- .../markers/face laugh.svg | 42 +- .../markers/flag_blue@16.svg | 32 +- .../markers/flag_dark_gray@16.svg | 40 +- .../markers/flag_dark_green@16.svg | 32 +- .../markers/flag_gray@16.svg | 46 +- .../markers/flag_green@16.svg | 32 +- .../markers/flag_orange@16.svg | 32 +- .../markers/flag_purple@16.svg | 32 +- .../markers/flag_red@16.svg | 40 +- .../markers/flag_yellow@16.svg | 46 +- .../markers/markerSheet.properties | 262 +- .../markers/markerSheet.xml | 340 +- .../markers/month_apr@16.svg | 64 +- .../markers/month_aug@16.svg | 64 +- .../markers/month_dec@16.svg | 64 +- .../markers/month_feb@16.svg | 64 +- .../markers/month_jan@16.svg | 64 +- .../markers/month_jul@16.svg | 48 +- .../markers/month_jun@16.svg | 64 +- .../markers/month_mar@16.svg | 64 +- .../markers/month_may@16.svg | 64 +- .../markers/month_nov@16.svg | 72 +- .../markers/month_oct@16.svg | 72 +- .../markers/month_sep@16.svg | 72 +- .../markers/people_blue@16.svg | 32 +- .../markers/people_dark_gray@16.svg | 40 +- .../markers/people_dark_green@16.svg | 32 +- .../markers/people_gray@16.svg | 36 +- .../markers/people_green@16.svg | 32 +- .../markers/people_orange@16.svg | 32 +- .../markers/people_purple@16.svg | 32 +- .../markers/people_red@16.svg | 40 +- .../markers/people_yellow@16.svg | 36 +- .../markers/priority_1@16.svg | 46 +- .../markers/priority_2@16.svg | 38 +- .../markers/priority_3@16.svg | 38 +- .../markers/priority_4@16.svg | 38 +- .../markers/priority_5@16.svg | 38 +- .../markers/priority_6@16.svg | 38 +- .../markers/priority_7@16.svg | 38 +- .../markers/priority_8@16.svg | 38 +- .../markers/priority_9@16.svg | 38 +- .../markers/progress_1o@16.svg | 54 +- .../markers/progress_1q@16.svg | 44 +- .../markers/progress_3o@16.svg | 52 +- .../markers/progress_3q@16.svg | 42 +- .../markers/progress_5o@16.svg | 46 +- .../markers/progress_7o@16.svg | 48 +- .../markers/progress_done@16.svg | 60 +- .../markers/progress_half@16.svg | 50 +- .../markers/progress_start@16.svg | 58 +- .../markers/star_blue@16.svg | 32 +- .../markers/star_dark_gray@16.svg | 40 +- .../markers/star_dark_green@16.svg | 32 +- .../markers/star_gray@16.svg | 36 +- .../markers/star_green@16.svg | 32 +- .../markers/star_orange@16.svg | 32 +- .../markers/star_purple@16.svg | 32 +- .../markers/star_red@16.svg | 40 +- .../markers/star_yellow@16.svg | 36 +- .../markers/symbol_attention@16.svg | 46 +- .../markers/symbol_bar_chart.svg | 46 +- .../markers/symbol_contact.svg | 40 +- .../markers/symbol_dislike.svg | 54 +- .../markers/symbol_drink.svg | 46 +- .../markers/symbol_exclamation@16.svg | 20 +- .../markers/symbol_exercise.svg | 38 +- .../markers/symbol_flight.svg | 38 +- .../markers/symbol_heart.svg | 54 +- .../markers/symbol_information@16.svg | 46 +- .../markers/symbol_like.svg | 54 +- .../markers/symbol_line_graph.svg | 46 +- .../markers/symbol_medals.svg | 38 +- .../markers/symbol_minus@16.svg | 38 +- .../markers/symbol_money.svg | 38 +- .../markers/symbol_music.svg | 54 +- .../markers/symbol_pause@16.svg | 46 +- .../markers/symbol_pen.svg | 38 +- .../markers/symbol_pie_chart.svg | 46 +- .../markers/symbol_plus@16.svg | 38 +- .../markers/symbol_question@16.svg | 38 +- .../markers/symbol_right@16.svg | 38 +- .../markers/symbol_shopping_cart.svg | 46 +- .../markers/symbol_telephone.svg | 38 +- .../markers/symbol_thermometer.svg | 54 +- .../markers/symbol_trophy.svg | 38 +- .../markers/symbol_wrong@16.svg | 46 +- .../markers/week_fri@16.svg | 38 +- .../markers/week_mon@16.svg | 38 +- .../markers/week_sat@16.svg | 38 +- .../markers/week_sun@16.svg | 38 +- .../markers/week_thu@16.svg | 38 +- .../markers/week_tue@16.svg | 38 +- .../markers/week_wed@16.svg | 38 +- bundles/org.xmind.ui.resources/normalize.py | 534 +- bundles/org.xmind.ui.resources/pom.xml | 32 +- .../styles/defaultStyles.xml | 208 +- .../styles/styles.properties | 68 +- .../org.xmind.ui.resources/styles/styles.xml | 254 +- .../styles/styles_zh_CN.xml | 254 +- .../styles/styles_zh_TW.xml | 254 +- .../styles/themeGroups.properties | 4 +- .../styles/themeGroups.xml | 86 +- .../styles/themePopover.xml | 30 +- .../styles/themes.properties | 58 +- .../org.xmind.ui.resources/styles/themes.xml | 2576 ++-- .../styles/themes_zh_CN.xml | 2576 ++-- .../styles/themes_zh_TW.xml | 2576 ++-- .../business/Balance Sheet.xmt/content.xml | 40 +- .../business/Cause and Effect.xmt/content.xml | 4 +- .../Company Hierarchy.xmt/content.xml | 158 +- .../Meeting Management.xmt/content.xml | 116 +- .../business/Sales Management.xmt/content.xml | 2 +- .../XMind 10 Years.xmt/META-INF/manifest.xml | 0 .../Thumbnails/thumbnail.png | Bin .../XMind 10 Years.xmt/content.xml | 0 .../XMind 10 Years.xmt/meta.xml | 0 .../XMind 10 Years.xmt/styles.xml | 0 .../education/Book Report.xmt/content.xml | 2 +- .../education/Paper Outline.xmt/content.xml | 4 +- .../education/Syllabus.xmt/content.xml | 12 +- .../templates/templates.xml | 72 +- bundles/org.xmind.ui.spelling/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 770 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../META-INF/MANIFEST.MF | 38 +- bundles/org.xmind.ui.spelling/about.html | 44 +- .../org.xmind.ui.spelling/build.properties | 18 +- bundles/org.xmind.ui.spelling/dict/xmind.dict | 2 +- .../org.xmind.ui.spelling/plugin.properties | 34 +- bundles/org.xmind.ui.spelling/plugin.xml | 178 +- bundles/org.xmind.ui.spelling/pom.xml | 32 +- .../src/org/xmind/ui/IWordContext.java | 74 +- .../org/xmind/ui/IWordContextProvider.java | 54 +- .../handlers/CheckSpellingForAllHandler.java | 82 +- .../handlers/CheckSpellingHandler.java | 86 +- .../spelling/CheckSpellingAction.java | 80 +- .../spelling/ISpellCheckerDescriptor.java | 68 +- .../spelling/ISpellCheckerVisitor.java | 42 +- .../spelling/JazzySpellingSupport.java | 194 +- .../xmind/ui/internal/spelling/Messages.java | 178 +- .../OpenSpellingCheckDialogHandler.java | 82 +- .../internal/spelling/SpellCheckerAgent.java | 644 +- .../spelling/SpellCheckerRegistry.java | 560 +- .../spelling/SpellingCheckDialog.java | 1923 +-- .../spelling/SpellingCheckPrefPage.java | 1444 +-- .../internal/spelling/SpellingCheckView.java | 2063 ++-- .../SpellingDictionPreferencePageSection.java | 1226 +- .../ui/internal/spelling/SpellingHelper.java | 1014 +- .../SpellingOptionsPreferencePageSection.java | 222 +- .../ui/internal/spelling/SpellingPlugin.java | 238 +- bundles/org.xmind.ui.spreadsheet/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 794 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../META-INF/MANIFEST.MF | 33 +- bundles/org.xmind.ui.spreadsheet/about.html | 44 +- .../plugin.properties | 28 +- bundles/org.xmind.ui.spreadsheet/plugin.xml | 1222 +- bundles/org.xmind.ui.spreadsheet/pom.xml | 32 +- .../spreadsheet/ColumnHeadEditTool.java | 398 +- .../internal/spreadsheet/ColumnMoveTool.java | 282 +- .../ui/internal/spreadsheet/Messages.java | 68 +- .../internal/spreadsheet/RowHeadEditTool.java | 390 +- .../SheetHeadModifiablePolicy.java | 268 +- .../ui/internal/spreadsheet/Spreadsheet.java | 170 +- .../spreadsheet/SpreadsheetBranchHook.java | 142 +- .../spreadsheet/SpreadsheetPolicyAdvisor.java | 3 +- .../SpreadsheetBranchDecoration.java | 1074 +- .../internal/spreadsheet/messages.properties | 12 +- .../internal/spreadsheet/structures/Cell.java | 488 +- .../spreadsheet/structures/Cell2.java | 536 +- .../spreadsheet/structures/Chart.java | 808 +- .../spreadsheet/structures/Chart2.java | 776 +- .../spreadsheet/structures/ColumnHead.java | 244 +- .../structures/ColumnStructure.java | 1264 +- .../spreadsheet/structures/RowHead.java | 244 +- .../spreadsheet/structures/RowStructure.java | 1300 +- .../structures/SpreadsheetStructure.java | 880 +- bundles/org.xmind.ui.toolkit/.classpath | 24 +- bundles/org.xmind.ui.toolkit/.gitignore | 30 +- bundles/org.xmind.ui.toolkit/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 774 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../org.xmind.ui.toolkit/META-INF/MANIFEST.MF | 102 +- bundles/org.xmind.ui.toolkit/about.html | 44 +- bundles/org.xmind.ui.toolkit/build.properties | 18 +- .../org.xmind.ui.toolkit/plugin.properties | 30 +- bundles/org.xmind.ui.toolkit/plugin.xml | 376 +- bundles/org.xmind.ui.toolkit/pom.xml | 32 +- .../schema/applicationValidators.exsd | 178 +- .../schema/contributedContentsViews.exsd | 254 +- .../schema/preferencePageSections.exsd | 240 +- .../xmind/ui/animation/AnimationViewer.java | 670 +- .../animation/IAnimationContentProvider.java | 46 +- .../ui/color/ColorBlockImageDescriptor.java | 220 +- .../src/org/xmind/ui/color/ColorPicker.java | 2644 ++-- .../xmind/ui/color/ColorPickerConfigurer.java | 278 +- .../org/xmind/ui/color/PaletteContents.java | 568 +- .../src/org/xmind/ui/color/PaletteItem.java | 638 +- .../org/xmind/ui/color/PaletteMessages.java | 320 +- .../src/org/xmind/ui/color/PaletteViewer.java | 1592 +-- .../org/xmind/ui/color/messages.properties | 258 +- .../src/org/xmind/ui/dialogs/Messages.java | 90 +- .../org/xmind/ui/dialogs/Notification.java | 1008 +- .../xmind/ui/dialogs/NotificationWindow.java | 1428 +-- .../src/org/xmind/ui/dialogs/Polygon.java | 226 +- .../src/org/xmind/ui/dialogs/PopupDialog.java | 3218 ++--- .../src/org/xmind/ui/dialogs/Promotion.java | 902 +- .../xmind/ui/dialogs/SmoothPopupDialog.java | 1788 +-- .../src/org/xmind/ui/dialogs/StyledLink.java | 938 +- .../org/xmind/ui/dialogs/messages.properties | 18 +- .../src/org/xmind/ui/font/FontDialog.java | 1392 +-- .../xmind/ui/font/IFontChooserListener.java | 44 +- .../src/org/xmind/ui/font/Messages.java | 74 +- .../src/org/xmind/ui/forms/BellowsData.java | 184 +- .../src/org/xmind/ui/forms/BellowsLayout.java | 892 +- .../org/xmind/ui/internal/ToolkitImages.java | 216 +- .../ui/internal/app/ApplicationConstants.java | 94 +- .../internal/app/IApplicationValidator.java | 84 +- .../internal/e4handlers/DirectToolItem.java | 258 +- .../e4handlers/ShowPullDownMenuToolItem.java | 42 +- .../internal/e4models/IContextRunnable.java | 22 +- .../e4models/IModelPageContainer.java | 14 +- .../internal/e4models/IModelPartContext.java | 28 +- .../xmind/ui/internal/e4models/ModelPage.java | 68 +- .../internal/e4models/ModelPageContainer.java | 158 +- .../xmind/ui/internal/e4models/ModelPart.java | 650 +- .../internal/e4models/MultiPageModelPart.java | 408 +- .../e4models/ViewModelFolderRenderer.java | 504 +- .../ui/internal/e4models/ViewModelPart.java | 726 +- .../handlers/ResetPropertyHandler.java | 122 +- .../statushandlers/DefaultErrorReporter.java | 82 +- .../statushandlers/IErrorReporter.java | 72 +- .../IRuntimeErrorDialogExtension.java | 16 +- .../statushandlers/RuntimeErrorDialog.java | 316 +- .../statushandlers/StatusDetails.java | 492 +- .../statushandlers/StatusHandlerMessages.java | 64 +- .../statushandlers/messages.properties | 10 +- .../src/org/xmind/ui/io/DownloadJob.java | 628 +- .../org/xmind/ui/io/FileDownloadTarget.java | 118 +- .../src/org/xmind/ui/io/IDownloadTarget.java | 138 +- .../org/xmind/ui/io/MonitoredInputStream.java | 190 +- .../xmind/ui/io/MonitoredOutputStream.java | 154 +- .../ui/io/StreamInterruptedException.java | 104 +- .../org/xmind/ui/io/UIJobChangeListener.java | 370 +- .../src/org/xmind/ui/io/WebImageManager.java | 394 +- .../src/org/xmind/ui/io/messages.properties | 10 +- .../ui/preference/IPreferenceSection.java | 28 +- .../MultiSectionPreferencePage.java | 368 +- .../PreferenceFieldEditorPageSection.java | 102 +- .../properties/ColorPropertyDescriptor.java | 112 +- .../ui/properties/ColorPropertyEditor.java | 772 +- ...lterableMultiChoicePropertyDescriptor.java | 200 +- .../xmind/ui/properties/IEditingListener.java | 74 +- .../ui/properties/IPropertyDescriptor.java | 198 +- .../ui/properties/IPropertyEditingEntry.java | 142 +- .../xmind/ui/properties/IPropertySource.java | 292 +- .../ui/properties/IPropertyTransfer.java | 56 +- .../src/org/xmind/ui/properties/Messages.java | 68 +- .../MultiChoicePropertyDescriptor.java | 146 +- .../properties/MultiChoicePropertyEditor.java | 822 +- .../xmind/ui/properties/PropertiesEditor.java | 1326 +- .../ui/properties/PropertyDescriptor.java | 222 +- .../ui/properties/PropertyEditingEntry.java | 1532 +-- .../PropertyEditingEntryPropertyTester.java | 178 +- .../ui/properties/PropertyEditingSection.java | 546 +- .../xmind/ui/properties/PropertyEditor.java | 670 +- .../ui/properties/TextPropertyDescriptor.java | 70 +- .../ui/properties/TextPropertyEditor.java | 280 +- .../xmind/ui/properties/messages.properties | 2 +- .../org/xmind/ui/resources/ColorUtils.java | 586 +- .../ui/resources/ErrorImageDescriptor.java | 186 +- .../src/org/xmind/ui/resources/FontUtils.java | 1976 +-- .../ui/resources/ImageDescriptorProvider.java | 22 +- .../xmind/ui/resources/ImageReference.java | 524 +- .../src/org/xmind/ui/resources/Messages.java | 44 +- .../xmind/ui/resources/messages.properties | 4 +- .../xmind/ui/richtext/AlignCenterAction.java | 112 +- .../xmind/ui/richtext/AlignLeftAction.java | 112 +- .../xmind/ui/richtext/AlignRightAction.java | 112 +- .../org/xmind/ui/richtext/AlignmentGroup.java | 912 +- .../src/org/xmind/ui/richtext/BoldAction.java | 106 +- .../org/xmind/ui/richtext/BulletAction.java | 118 +- .../src/org/xmind/ui/richtext/FontAction.java | 272 +- .../FullRichTextActionBarContributor.java | 832 +- .../org/xmind/ui/richtext/IRichDocument.java | 120 +- .../ui/richtext/IRichDocumentListener.java | 62 +- .../xmind/ui/richtext/IRichTextAction.java | 48 +- .../IRichTextActionBarContributor.java | 72 +- .../ui/richtext/IRichTextEditViewer.java | 178 +- .../xmind/ui/richtext/IRichTextRenderer.java | 184 +- .../ui/richtext/IStyleRangeModifier.java | 48 +- .../xmind/ui/richtext/ImagePlaceHolder.java | 102 +- .../org/xmind/ui/richtext/IndentAction.java | 104 +- .../org/xmind/ui/richtext/ItalicAction.java | 108 +- .../src/org/xmind/ui/richtext/LineStyle.java | 218 +- .../org/xmind/ui/richtext/NumberAction.java | 80 +- .../org/xmind/ui/richtext/OutdentAction.java | 104 +- .../org/xmind/ui/richtext/RichDocument.java | 432 +- .../ui/richtext/RichDocumentUndoManager.java | 3102 ++--- .../RichTextActionBarContributor.java | 146 +- .../xmind/ui/richtext/RichTextEditViewer.java | 836 +- .../xmind/ui/richtext/RichTextMessages.java | 112 +- .../xmind/ui/richtext/RichTextRenderer.java | 2312 ++-- .../org/xmind/ui/richtext/RichTextUtils.java | 1738 +-- .../SimpleRichTextActionBarContributor.java | 446 +- .../xmind/ui/richtext/StrikeoutAction.java | 108 +- .../xmind/ui/richtext/UnderlineAction.java | 108 +- .../IDelegatedSelectionProvider.java | 54 +- .../ui/tabfolder/IPageClosedListener.java | 40 +- .../xmind/ui/tabfolder/IPageMoveListener.java | 44 +- .../tabfolder/IPageTitleChangedListener.java | 38 +- .../src/org/xmind/ui/tabfolder/MTabBar.java | 2477 ++-- .../org/xmind/ui/tabfolder/MTabBarItem.java | 427 +- .../org/xmind/ui/tabfolder/MTabFolder.java | 555 +- .../src/org/xmind/ui/tabfolder/MTabItem.java | 94 +- .../org/xmind/ui/tabfolder/PageBookPage.java | 528 +- .../ui/texteditor/FloatingTextEditor.java | 1548 +-- .../texteditor/IControlContentAdapter2.java | 82 +- .../xmind/ui/texteditor/ISpellingSupport.java | 156 +- .../xmind/ui/texteditor/MEmbeddedEditor.java | 456 +- .../org/xmind/ui/texteditor/MTextEditor.java | 376 +- .../ui/texteditor/SimpleTextSelection.java | 134 +- .../texteditor/StyledTextContentAdapter.java | 192 +- .../src/org/xmind/ui/util/Chainability.java | 266 +- .../src/org/xmind/ui/util/EncodingUtils.java | 130 +- .../src/org/xmind/ui/util/ICancelable.java | 42 +- .../src/org/xmind/ui/util/IChained.java | 92 +- .../src/org/xmind/ui/util/IStyleProvider.java | 154 +- .../org/xmind/ui/util/ITimerValidator.java | 44 +- .../src/org/xmind/ui/util/ImageFormat.java | 190 +- .../src/org/xmind/ui/util/Messages.java | 42 +- .../src/org/xmind/ui/util/PrefUtils.java | 130 +- .../src/org/xmind/ui/util/RegionUtils.java | 304 +- .../src/org/xmind/ui/util/StyleProvider.java | 90 +- .../src/org/xmind/ui/util/TextFormatter.java | 232 +- .../src/org/xmind/ui/util/messages.properties | 6 +- .../AbstractSnapSliderContentProvider.java | 334 +- .../org/xmind/ui/viewers/AdaptiveLabel.java | 174 +- .../xmind/ui/viewers/CachedLabelProvider.java | 390 +- .../xmind/ui/viewers/CategorizedViewer.java | 1132 +- .../xmind/ui/viewers/HintedListLayout.java | 80 +- .../viewers/ICategorizedContentProvider.java | 48 +- .../xmind/ui/viewers/ICompositeProvider.java | 42 +- .../ui/viewers/IGraphicalToolTipProvider.java | 56 +- .../xmind/ui/viewers/ILabelDescriptor.java | 140 +- .../src/org/xmind/ui/viewers/IListLayout.java | 62 +- .../org/xmind/ui/viewers/IListRenderer.java | 70 +- .../xmind/ui/viewers/IToolTipProvider.java | 38 +- .../src/org/xmind/ui/viewers/ImageLabel.java | 480 +- .../org/xmind/ui/viewers/ImageListViewer.java | 1042 +- .../xmind/ui/viewers/ImagePreviewViewer.java | 1430 +-- .../src/org/xmind/ui/viewers/MButton.java | 1512 +-- .../org/xmind/ui/viewers/MComboViewer.java | 1576 +-- .../src/org/xmind/ui/viewers/MListViewer.java | 1074 +- .../src/org/xmind/ui/viewers/Messages.java | 48 +- .../ui/viewers/SameCompositeProvider.java | 60 +- .../ui/viewers/SelectionSynchronizer.java | 272 +- .../org/xmind/ui/viewers/SliderViewer.java | 1386 +-- .../xmind/ui/viewers/StraightListLayout.java | 498 +- .../org/xmind/ui/viewers/messages.properties | 10 +- .../ui/views/ContributedContentsView.java | 424 +- .../views/ContributedContentsViewTester.java | 262 +- .../views/DefaultContributedContentPage.java | 150 +- .../views/IContributedContentPageFactory.java | 26 +- .../src/org/xmind/ui/views/IPage.java | 80 +- .../src/org/xmind/ui/views/Page.java | 92 +- .../src/org/xmind/ui/views/PageStack.java | 228 +- bundles/org.xmind.ui/.classpath | 22 +- bundles/org.xmind.ui/.gitignore | 30 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 102 +- .../.settings/org.eclipse.pde.prefs | 64 +- bundles/org.xmind.ui/META-INF/MANIFEST.MF | 32 +- bundles/org.xmind.ui/about.html | 44 +- bundles/org.xmind.ui/icons/d/insertafter.png | Bin 321 -> 308 bytes .../org.xmind.ui/icons/d/insertafter@2x.png | Bin 690 -> 629 bytes bundles/org.xmind.ui/icons/d/insertbefore.png | Bin 331 -> 314 bytes .../org.xmind.ui/icons/d/insertbefore@2x.png | Bin 687 -> 625 bytes bundles/org.xmind.ui/icons/d/insertparent.png | Bin 367 -> 359 bytes .../org.xmind.ui/icons/d/insertparent@2x.png | Bin 732 -> 672 bytes bundles/org.xmind.ui/icons/d/insertsub.png | Bin 365 -> 363 bytes bundles/org.xmind.ui/icons/d/insertsub@2x.png | Bin 715 -> 681 bytes bundles/org.xmind.ui/icons/e/insertafter.png | Bin 325 -> 332 bytes .../org.xmind.ui/icons/e/insertafter@2x.png | Bin 794 -> 766 bytes bundles/org.xmind.ui/icons/e/insertbefore.png | Bin 333 -> 331 bytes .../org.xmind.ui/icons/e/insertbefore@2x.png | Bin 761 -> 757 bytes bundles/org.xmind.ui/icons/e/insertparent.png | Bin 367 -> 352 bytes .../org.xmind.ui/icons/e/insertparent@2x.png | Bin 749 -> 717 bytes bundles/org.xmind.ui/icons/e/insertsub.png | Bin 387 -> 368 bytes bundles/org.xmind.ui/icons/e/insertsub@2x.png | Bin 781 -> 755 bytes bundles/org.xmind.ui/plugin.properties | 944 +- bundles/org.xmind.ui/plugin.xml | 10138 ++++++++-------- bundles/org.xmind.ui/pom.xml | 32 +- .../org.xmind.ui/schema/branchPolicies.exsd | 1094 +- bundles/org.xmind.ui/schema/decorations.exsd | 486 +- bundles/org.xmind.ui/schema/dndClients.exsd | 258 +- bundles/org.xmind.ui/schema/editPolicies.exsd | 224 +- .../org.xmind.ui/schema/hyperlinkPages.exsd | 278 +- bundles/org.xmind.ui/schema/iconTips.exsd | 288 +- bundles/org.xmind.ui/schema/imageActions.exsd | 320 +- .../org.xmind.ui/schema/numberFormats.exsd | 258 +- bundles/org.xmind.ui/schema/protocols.exsd | 252 +- .../org.xmind.ui/schema/resourceManager.exsd | 256 +- bundles/org.xmind.ui/schema/saveWizards.exsd | 210 +- bundles/org.xmind.ui/schema/shareOptions.exsd | 276 +- .../schema/workbookRefFactories.exsd | 202 +- .../org.xmind.ui/shapes/topic-shape-cloud.svg | 26 +- .../shapes/topic-shape-stroke-circle.svg | 42 +- .../shapes/topic-shape-stroke-circle2.svg | 56 +- features/org.xmind.cathy.feature/.gitignore | 30 +- features/org.xmind.cathy.feature/.project | 34 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../org.xmind.cathy.feature/build.properties | 8 +- features/org.xmind.cathy.feature/epl-v10.html | 638 +- features/org.xmind.cathy.feature/feature.xml | 178 +- .../org.xmind.cathy.feature/lgpl-3.0.html | 366 +- features/org.xmind.cathy.feature/license.html | 44 +- features/org.xmind.cathy.feature/pom.xml | 32 +- .../.gitignore | 30 +- .../org.xmind.cathy.platform.feature/.project | 34 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../build.properties | 8 +- .../epl-v10.html | 638 +- .../feature.xml | 1836 +-- .../lgpl-3.0.html | 366 +- .../license.html | 44 +- .../org.xmind.cathy.platform.feature/pom.xml | 32 +- .../org.xmind.graphicsio.feature/.gitignore | 30 +- .../org.xmind.graphicsio.feature/.project | 34 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../build.properties | 8 +- .../org.xmind.graphicsio.feature/epl-v10.html | 638 +- .../org.xmind.graphicsio.feature/feature.xml | 104 +- .../lgpl-3.0.html | 366 +- .../org.xmind.graphicsio.feature/license.html | 44 +- features/org.xmind.graphicsio.feature/pom.xml | 32 +- features/org.xmind.hebe.feature/.gitignore | 30 +- features/org.xmind.hebe.feature/.project | 34 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../org.xmind.hebe.feature/build.properties | 8 +- features/org.xmind.hebe.feature/epl-v10.html | 638 +- features/org.xmind.hebe.feature/feature.xml | 316 +- features/org.xmind.hebe.feature/lgpl-3.0.html | 366 +- features/org.xmind.hebe.feature/license.html | 44 +- features/org.xmind.hebe.feature/pom.xml | 32 +- others/xmind-formatter-long.xml | 590 +- others/xmind-formatter.xml | 590 +- others/xmind-templates.xml | 68 +- pom.xml | 352 +- releng/org.xmind.cathy.product/.gitignore | 30 +- releng/org.xmind.cathy.product/.project | 44 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 12 +- .../org.xmind.cathy.product/build.properties | 4 +- releng/org.xmind.cathy.product/cathy.product | 172 +- releng/org.xmind.cathy.product/pom.xml | 64 +- releng/org.xmind.cathy.repository/.gitignore | 30 +- releng/org.xmind.cathy.repository/.project | 22 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../org.xmind.cathy.repository/category.xml | 32 +- releng/org.xmind.cathy.repository/pom.xml | 28 +- releng/org.xmind.cathy.target/.gitignore | 30 +- releng/org.xmind.cathy.target/.project | 22 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- releng/org.xmind.cathy.target/cathy.target | 40 +- releng/org.xmind.cathy.target/pom.xml | 28 +- tests/org.xmind.core.runtime.tests/.classpath | 22 +- tests/org.xmind.core.runtime.tests/.gitignore | 24 +- tests/org.xmind.core.runtime.tests/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 798 +- .../.settings/org.eclipse.jdt.ui.prefs | 124 +- .../.settings/org.eclipse.pde.prefs | 64 +- .../META-INF/MANIFEST.MF | 22 +- .../OSGI-INF/l10n/bundle.properties | 4 +- .../build.properties | 10 +- tests/org.xmind.core.runtime.tests/pom.xml | 30 +- .../samples/markers.xml | 282 +- .../7m88qhg5999hg1ik0npek5nhq6.txt | 12 +- .../samples/sample1.xmind/styles.xml | 48 +- .../runtime/test/CoreEvaluatorTestCase.java | 594 +- .../test/XMindCoreRuntimeTestSuite.java | 22 +- tests/org.xmind.core.tests/.classpath | 22 +- tests/org.xmind.core.tests/.gitignore | 24 +- tests/org.xmind.core.tests/.project | 56 +- .../org.eclipse.core.resources.prefs | 4 +- .../.settings/org.eclipse.core.runtime.prefs | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 832 +- .../.settings/org.eclipse.jdt.launching.prefs | 4 +- .../.settings/org.eclipse.jdt.ui.prefs | 132 +- .../org.xmind.core.tests/META-INF/MANIFEST.MF | 30 +- .../OSGI-INF/l10n/bundle.properties | 4 +- tests/org.xmind.core.tests/build.properties | 10 +- tests/org.xmind.core.tests/pom.xml | 30 +- .../internal/experiments/CompressionTest.java | 228 +- .../ConcurrentModificationTest.java | 470 +- .../tests/TestPluginForXMindCore.java | 60 +- .../xmind/core/internal/tests/TestUtil.java | 86 +- .../internal/tests/WorkbookTestCaseBase.java | 72 +- .../org/xmind/core/tests/CommentTestCase.java | 564 +- .../org/xmind/core/tests/MarkerTestCase.java | 1064 +- .../xmind/core/tests/RevisionTestCase.java | 100 +- .../org/xmind/core/tests/StyleTestCase.java | 142 +- .../core/tests/TopicIteratorTestCase.java | 146 +- .../core/tests/WorkbookExtensionTestCase.java | 392 +- .../xmind/core/tests/WorkbookTestCase.java | 468 +- 2496 files changed, 389526 insertions(+), 388587 deletions(-) create mode 100644 bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XEditorStackRenderer.java delete mode 100644 bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightStackRenderer.java create mode 100644 bundles/org.xmind.core.usagedata/src/org/xmind/core/internal/UserDataConstants.java create mode 100644 bundles/org.xmind.gef/src/org/xmind/gef/part/IPartListener2.java delete mode 100644 bundles/org.xmind.ui.menus/icons/toolbar/e/insert_disable.png delete mode 100644 bundles/org.xmind.ui.menus/icons/toolbar/e/insert_disable@2x.png delete mode 100644 bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenLocalFileHandler.java rename bundles/org.xmind.ui.resources/templates/{education => business}/XMind 10 Years.xmt/META-INF/manifest.xml (100%) rename bundles/org.xmind.ui.resources/templates/{education => business}/XMind 10 Years.xmt/Thumbnails/thumbnail.png (100%) rename bundles/org.xmind.ui.resources/templates/{education => business}/XMind 10 Years.xmt/content.xml (100%) rename bundles/org.xmind.ui.resources/templates/{education => business}/XMind 10 Years.xmt/meta.xml (100%) rename bundles/org.xmind.ui.resources/templates/{education => business}/XMind 10 Years.xmt/styles.xml (100%) diff --git a/bundles/org.xmind.cathy.fonts/.gitignore b/bundles/org.xmind.cathy.fonts/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.cathy.fonts/.gitignore +++ b/bundles/org.xmind.cathy.fonts/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.cathy.fonts/.project b/bundles/org.xmind.cathy.fonts/.project index 8bf2e3897..49b3d3299 100644 --- a/bundles/org.xmind.cathy.fonts/.project +++ b/bundles/org.xmind.cathy.fonts/.project @@ -1,22 +1,22 @@ - - - org.xmind.cathy.fonts - - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - - + + + org.xmind.cathy.fonts + + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + + diff --git a/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.cathy.fonts/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF index 1a96f3eb9..6eff57e48 100644 --- a/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name -Bundle-SymbolicName: org.xmind.cathy.fonts -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %Bundle-Vendor +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.xmind.cathy.fonts +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %Bundle-Vendor diff --git a/bundles/org.xmind.cathy.fonts/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.cathy.fonts/OSGI-INF/l10n/bundle.properties index 4e2900fed..79659b9c5 100644 --- a/bundles/org.xmind.cathy.fonts/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.cathy.fonts/OSGI-INF/l10n/bundle.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.cathy.fonts -Bundle-Vendor = XMind Ltd. +#Properties file for org.xmind.cathy.fonts +Bundle-Vendor = XMind Ltd. Bundle-Name = Additional Fonts For XMind \ No newline at end of file diff --git a/bundles/org.xmind.cathy.fonts/README b/bundles/org.xmind.cathy.fonts/README index fbf4c43f4..3b537de10 100644 --- a/bundles/org.xmind.cathy.fonts/README +++ b/bundles/org.xmind.cathy.fonts/README @@ -1,3 +1,3 @@ -This plugin does not provide font files directly, but provides legal -information in about.html for custom fonts bundled with XMind RCP product -distribution. +This plugin does not provide font files directly, but provides legal +information in about.html for custom fonts bundled with XMind RCP product +distribution. diff --git a/bundles/org.xmind.cathy.fonts/about.html b/bundles/org.xmind.cathy.fonts/about.html index 7820c2dcf..c9a97bc34 100644 --- a/bundles/org.xmind.cathy.fonts/about.html +++ b/bundles/org.xmind.cathy.fonts/about.html @@ -1,20 +1,20 @@ - - - - -About - - -

About This Content

- -

Oct 12, 2015

- -

-This software include open source fonts which are available with -Apache License 2.0 or SIL Open Font License. - -

- - - + + + + +About + + +

About This Content

+ +

Oct 12, 2015

+ +

+This software include open source fonts which are available with +Apache License 2.0 or SIL Open Font License. + +

+ + + diff --git a/bundles/org.xmind.cathy.fonts/build.properties b/bundles/org.xmind.cathy.fonts/build.properties index 3d1164dce..7f8c70717 100644 --- a/bundles/org.xmind.cathy.fonts/build.properties +++ b/bundles/org.xmind.cathy.fonts/build.properties @@ -1,2 +1,2 @@ -bin.includes = META-INF/,\ - OSGI-INF/ +bin.includes = META-INF/,\ + OSGI-INF/ diff --git a/bundles/org.xmind.cathy.fonts/pom.xml b/bundles/org.xmind.cathy.fonts/pom.xml index 57e73351d..1de51ffa0 100644 --- a/bundles/org.xmind.cathy.fonts/pom.xml +++ b/bundles/org.xmind.cathy.fonts/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.cathy.fonts - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.cathy.fonts + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.cathy.win32/.classpath b/bundles/org.xmind.cathy.win32/.classpath index 9643481c7..68de192ec 100644 --- a/bundles/org.xmind.cathy.win32/.classpath +++ b/bundles/org.xmind.cathy.win32/.classpath @@ -1,12 +1,12 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/bundles/org.xmind.cathy.win32/.gitignore b/bundles/org.xmind.cathy.win32/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.cathy.win32/.gitignore +++ b/bundles/org.xmind.cathy.win32/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.pde.prefs index 050e14d72..9ba90cb01 100644 --- a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=2 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=1 -compilers.p.discouraged-class=1 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=2 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF index 3b2247e59..c48ae1554 100644 --- a/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.cathy.win32;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %providerName -Fragment-Host: org.xmind.cathy -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-ClassPath: . -Bundle-Localization: fragment_win32 -Export-Package: org.xmind.cathy.internal;x-internal:=true, - org.xmind.cathy.internal.win32;x-internal:=true -Eclipse-PlatformFilter: (osgi.ws=win32) +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.cathy.win32;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %providerName +Fragment-Host: org.xmind.cathy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ClassPath: . +Bundle-Localization: fragment_win32 +Export-Package: org.xmind.cathy.internal;x-internal:=true, + org.xmind.cathy.internal.win32;x-internal:=true +Eclipse-PlatformFilter: (osgi.ws=win32) diff --git a/bundles/org.xmind.cathy.win32/about.html b/bundles/org.xmind.cathy.win32/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.cathy.win32/about.html +++ b/bundles/org.xmind.cathy.win32/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.cathy.win32/fragment_win32.properties b/bundles/org.xmind.cathy.win32/fragment_win32.properties index f7dcb8cc1..90072c547 100644 --- a/bundles/org.xmind.cathy.win32/fragment_win32.properties +++ b/bundles/org.xmind.cathy.win32/fragment_win32.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.cathy.win32 -providerName = XMind Ltd. +#Properties file for org.xmind.cathy.win32 +providerName = XMind Ltd. pluginName = Cathy Win32 Fragment \ No newline at end of file diff --git a/bundles/org.xmind.cathy.win32/pom.xml b/bundles/org.xmind.cathy.win32/pom.xml index e14039d05..4b4d00313 100644 --- a/bundles/org.xmind.cathy.win32/pom.xml +++ b/bundles/org.xmind.cathy.win32/pom.xml @@ -1,36 +1,36 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.cathy.win32 - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - - - - - org.eclipse.tycho - target-platform-configuration - ${tycho.version} - - p2 - - - win32 - win32 - x86 - - - - - - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.cathy.win32 + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + + + + + org.eclipse.tycho + target-platform-configuration + ${tycho.version} + + p2 + + + win32 + win32 + x86 + + + + + + + diff --git a/bundles/org.xmind.cathy.win32/src/org/xmind/cathy/internal/win32/Startup.java b/bundles/org.xmind.cathy.win32/src/org/xmind/cathy/internal/win32/Startup.java index 4805f5823..f1caaec72 100644 --- a/bundles/org.xmind.cathy.win32/src/org/xmind/cathy/internal/win32/Startup.java +++ b/bundles/org.xmind.cathy.win32/src/org/xmind/cathy/internal/win32/Startup.java @@ -1,103 +1,103 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.cathy.internal.win32; - -import java.lang.reflect.Field; - -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IStartup; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.Log; - -public class Startup implements IStartup { - - public void earlyStartup() { - final IWorkbench workbench = PlatformUI.getWorkbench(); - final Display display = workbench.getDisplay(); - display.syncExec(new Runnable() { - public void run() { - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window != null) { - hookWindow(window); - } - } - }); - } - - private void hookWindow(IWorkbenchWindow window) { - Shell shell = window.getShell(); - if (shell != null && !shell.isDisposed()) { - int hWnd = findWindowHandle(shell); - logPrimaryWindow(hWnd); - shell.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - Log.get(Log.SINGLETON).delete(); - e.display.asyncExec(new Runnable() { - public void run() { - checkRemainingWindow(); - } - }); - } - }); - } - } - - /** - * Obtain shell.handle using reflection. - * - * @param shell - * @return - */ - private int findWindowHandle(Shell shell) { - try { - Field handleField = shell.getClass().getField("handle"); //$NON-NLS-1$ - Object handle = handleField.get(shell); - if (handle instanceof Integer) { - return ((Integer) handle).intValue(); - } - } catch (Exception e) { - //ignore - } - return 0; - } - - private void checkRemainingWindow() { - if (!PlatformUI.isWorkbenchRunning()) - return; - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window == null) { - IWorkbenchWindow[] windows = PlatformUI.getWorkbench() - .getWorkbenchWindows(); - if (windows == null || windows.length <= 0) - return; - window = windows[0]; - } - hookWindow(window); - } - - private void logPrimaryWindow(int hWnd) { - Log log = Log.get(Log.SINGLETON); - if (log.exists()) { - log.delete(); - } - log.getProperties().setProperty(Log.K_PRIMARY_WINDOW, - String.valueOf(hWnd)); - log.saveProperties(); - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.cathy.internal.win32; + +import java.lang.reflect.Field; + +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.Log; + +public class Startup implements IStartup { + + public void earlyStartup() { + final IWorkbench workbench = PlatformUI.getWorkbench(); + final Display display = workbench.getDisplay(); + display.syncExec(new Runnable() { + public void run() { + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window != null) { + hookWindow(window); + } + } + }); + } + + private void hookWindow(IWorkbenchWindow window) { + Shell shell = window.getShell(); + if (shell != null && !shell.isDisposed()) { + int hWnd = findWindowHandle(shell); + logPrimaryWindow(hWnd); + shell.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + Log.get(Log.SINGLETON).delete(); + e.display.asyncExec(new Runnable() { + public void run() { + checkRemainingWindow(); + } + }); + } + }); + } + } + + /** + * Obtain shell.handle using reflection. + * + * @param shell + * @return + */ + private int findWindowHandle(Shell shell) { + try { + Field handleField = shell.getClass().getField("handle"); //$NON-NLS-1$ + Object handle = handleField.get(shell); + if (handle instanceof Integer) { + return ((Integer) handle).intValue(); + } + } catch (Exception e) { + //ignore + } + return 0; + } + + private void checkRemainingWindow() { + if (!PlatformUI.isWorkbenchRunning()) + return; + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) { + IWorkbenchWindow[] windows = PlatformUI.getWorkbench() + .getWorkbenchWindows(); + if (windows == null || windows.length <= 0) + return; + window = windows[0]; + } + hookWindow(window); + } + + private void logPrimaryWindow(int hWnd) { + Log log = Log.get(Log.SINGLETON); + if (log.exists()) { + log.delete(); + } + log.getProperties().setProperty(Log.K_PRIMARY_WINDOW, + String.valueOf(hWnd)); + log.saveProperties(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/.classpath b/bundles/org.xmind.cathy/.classpath index 6e9b53707..362f47e08 100644 --- a/bundles/org.xmind.cathy/.classpath +++ b/bundles/org.xmind.cathy/.classpath @@ -1,20 +1,20 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.cathy/.gitignore b/bundles/org.xmind.cathy/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.cathy/.gitignore +++ b/bundles/org.xmind.cathy/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.cathy/.options b/bundles/org.xmind.cathy/.options index bfc5774a6..162403b0c 100644 --- a/bundles/org.xmind.cathy/.options +++ b/bundles/org.xmind.cathy/.options @@ -1,3 +1,3 @@ -org.xmind.cathy/debug/checkopenfile=false -org.xmind.cathy/debug/udc/showUploadButton=false -org.xmind.cathy/debug/notshowwelcome=false +org.xmind.cathy/debug/checkopenfile=false +org.xmind.cathy/debug/udc/showUploadButton=false +org.xmind.cathy/debug/notshowwelcome=false diff --git a/bundles/org.xmind.cathy/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.cathy/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.cathy/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.cathy/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.cathy/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.cathy/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.cathy/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.cathy/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.cathy/Application.e4xmi b/bundles/org.xmind.cathy/Application.e4xmi index d61b8d70c..bf3b138d1 100644 --- a/bundles/org.xmind.cathy/Application.e4xmi +++ b/bundles/org.xmind.cathy/Application.e4xmi @@ -1,85 +1,85 @@ - - - - CathyShowDashboard - - - - - - - - - - - - - - - - stretch - - - - - - - - - - - - - - - - - - - - - - - - stretch - - - - - - - - - TrimBarLayout:begining - - - TrimBarLayout:center - - - TrimBarLayout:end - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + CathyShowDashboard + + + + + + + + + + + + + + + + stretch + + + + + + + + + + + + + + + + + + + + + + + + stretch + + + + + + + + + TrimBarLayout:begining + + + TrimBarLayout:center + + + TrimBarLayout:end + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.cathy/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy/META-INF/MANIFEST.MF index bc188f91b..62a1336b7 100644 --- a/bundles/org.xmind.cathy/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy/META-INF/MANIFEST.MF @@ -1,53 +1,53 @@ -Manifest-Version: 1.0 -Bundle-SymbolicName: org.xmind.cathy;singleton:=true -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.ui, - org.xmind.ui;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.imports;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.command;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.command.remote;bundle-version="[3.7.0,3.8.0)", - org.eclipse.e4.ui.workbench, - org.eclipse.ui.themes, - org.eclipse.e4.ui.model.workbench, - org.eclipse.e4.core.di, - javax.inject, - org.eclipse.e4.ui.css.swt.theme, - org.eclipse.e4.core.contexts, - org.eclipse.e4.ui.css.swt, - org.eclipse.e4.ui.css.core, - org.eclipse.e4.ui.workbench.renderers.swt, - org.eclipse.e4.ui.workbench.swt, - javax.annotation, - org.eclipse.e4.core.services, - org.eclipse.e4.ui.services, - org.eclipse.e4.ui.di, - org.eclipse.osgi.services, - org.eclipse.e4.core.di.extensions, - org.eclipse.core.expressions, - org.eclipse.e4.core.commands, - org.xmind.ui.dashboard, - org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", - org.json, - org.xmind.ui.browser;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.licensing;bundle-version="[3.7.0,3.8.0)", - org.eclipse.e4.ui.workbench.addons.swt, - org.xmind.ui.mindmap;bundle-version="3.7.0", - org.eclipse.ui.net;bundle-version="1.3.0", - org.eclipse.emf.ecore.xmi -Bundle-ManifestVersion: 2 -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-ActivationPolicy: lazy -Bundle-Vendor: %providerName -Import-Package: javax.annotation;version="1.0.0";resolution:=optional, - javax.inject;version="1.0.0" -Service-Component: OSGI-INF/serviceManager.xml -Export-Package: org.xmind.cathy.internal;x-internal:=true,org.xmind.ca - thy.internal.css;x-internal:=true,org.xmind.cathy.internal.dashboard; - x-internal:=true,org.xmind.cathy.internal.handlers;x-internal:=true,o - rg.xmind.cathy.internal.jobs;x-internal:=true,org.xmind.cathy.interna - l.renderer;x-internal:=true,org.xmind.ui.internal.e4handlers;x-intern - al:=true -Bundle-Name: %pluginName -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.cathy.internal.CathyPlugin +Manifest-Version: 1.0 +Bundle-SymbolicName: org.xmind.cathy;singleton:=true +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ui, + org.xmind.ui;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.imports;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.command;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.command.remote;bundle-version="[3.7.0,3.8.0)", + org.eclipse.e4.ui.workbench, + org.eclipse.ui.themes, + org.eclipse.e4.ui.model.workbench, + org.eclipse.e4.core.di, + javax.inject, + org.eclipse.e4.ui.css.swt.theme, + org.eclipse.e4.core.contexts, + org.eclipse.e4.ui.css.swt, + org.eclipse.e4.ui.css.core, + org.eclipse.e4.ui.workbench.renderers.swt, + org.eclipse.e4.ui.workbench.swt, + javax.annotation, + org.eclipse.e4.core.services, + org.eclipse.e4.ui.services, + org.eclipse.e4.ui.di, + org.eclipse.osgi.services, + org.eclipse.e4.core.di.extensions, + org.eclipse.core.expressions, + org.eclipse.e4.core.commands, + org.xmind.ui.dashboard, + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", + org.json, + org.xmind.ui.browser;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.licensing;bundle-version="[3.7.0,3.8.0)", + org.eclipse.e4.ui.workbench.addons.swt, + org.xmind.ui.mindmap;bundle-version="3.7.0", + org.eclipse.ui.net;bundle-version="1.3.0", + org.eclipse.emf.ecore.xmi +Bundle-ManifestVersion: 2 +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Bundle-Vendor: %providerName +Import-Package: javax.annotation;version="1.0.0";resolution:=optional, + javax.inject;version="1.0.0" +Service-Component: OSGI-INF/serviceManager.xml +Export-Package: org.xmind.cathy.internal;x-internal:=true,org.xmind.ca + thy.internal.css;x-internal:=true,org.xmind.cathy.internal.dashboard; + x-internal:=true,org.xmind.cathy.internal.handlers;x-internal:=true,o + rg.xmind.cathy.internal.jobs;x-internal:=true,org.xmind.cathy.interna + l.renderer;x-internal:=true,org.xmind.ui.internal.e4handlers;x-intern + al:=true +Bundle-Name: %pluginName +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.cathy.internal.CathyPlugin diff --git a/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties index dd6c0e9ac..9812f9eec 100644 --- a/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties @@ -1,103 +1,104 @@ -productName = XMind -providerName = XMind Ltd. -pluginName = XMind Application -prefPage.general.name = General -prefPage.share.name = Share -prefPage.spelling.name = Spelling -prefPage.keys.name = Keys -prefPage.language.name = Language -prefPage.advanced.name = Advanced -prefPage.appearance.name = Appearance -view.progress.name = Progress -productBlurb=Version: XMind{0} ({1})\n\ -\n\ -{2}{3}{4}\n\ -{5}\n\ -\n\ -Official Website: {6} - -view.outline.name = Outline -view.properties.name = Properties -command.showHome.description = Show the Home UI -command.showHome.name = Show Home UI -commandParameter.homePage.name = Home Page Id -command.toggleHome.description = Show/Hide the Home UI -command.toggleHome.name = Toggle Home -command.welcome.description = Show welcome information -command.welcome.name = Welcome to XMind -menu.file.new.label = &New... -menu.file.close.label = &Close -menu.file.closeAll.label = C&lose All -menu.file.save.label = &Save -menu.file.saveAs.label = Save &As... -menu.file.saveall.label = Sa&ve All -menu.file.print.label = &Print -menu.file.import.label = &Import... -menu.file.export.label = &Export... -menu.file.share.label = S&hare -menu.file.exit.label = E&xit -menu.edit.undo.label = &Undo -menu.edit.redo.label = &Redo -menu.edit.cut.label = Cu&t -menu.edit.copy.label = &Copy -menu.edit.paste.label = &Paste -menu.edit.delete.label = &Delete -menu.edit.selectAll.label = Select &All -menu.edit.find.label = &Find/Replace... -menu.edit.preference.label = &Preferences... -menu.help.welcome.label = &Welcome to XMind -menu.help.xmindHelp.label = XMind &Help -menu.help.keyAssist.label = &Key Assist -menu.help.about.label = &About XMind -context.showHome.name = Home UI Is Shown -toolbar.dashboard.home.label = Home -toolbar.dashboard.home.tooltip = Show Home -toolbar.edit.save.label = Save -toolbar.edit.save.tooltip = Save -toolbar.edit.undo.label = Undo -toolbar.edit.undo.tooltip = Undo -toolbar.edit.redo.label = Redo -toolbar.edit.redo.tooltip = Redo -toolbar.export.label=Export -toolbar.export.tooltip=Export -toolbar.share.label=Share -toolbar.share.tooltip=Share -toolbar.export.more.label=More... -toolbar.export.more.tooltip=Show all export options... - -command.showDashboard.label = More... -command.pinRecent.name = Pin Recent File -command.unpinRecent.name = Unpin Recent File -command.clearRecent.name = Clear Recent File -command.pinThis.label = Pin This Map -command.unpinThis.label = Unpin This Map -command.clearUnpinned.label = Clear Unpinned Maps -command.home.label = Home -command.openCloud.name = Open Cloud Page -theme.cathy.name = Cathy - -command.pinRecentFile.name = Pin Recent File -command.unpinRecentFile.name = Unpin Recent File -command.clearRecentFile.name = Clear Recent File - -command.duplicateTemplate.name = Duplicate Template -command.renameTemplate.name = Rename Template -command.deleteTemplate.name = Delete Template - -command.openCloudPage.name = Open Cloud Page -category.cloud.name = Cloud - -prefPage.section.startup.label = Startup -prefPage.section.fileList.label = File List -prefPage.section.saveBackup.label = Save and Backup - - -product.name = XMind -command.showDashboard.name = More... -command.pinMap.name = Pin This Map -command.unpinMap.name = Unpin This Map -command.clearUnpinnedMap.name = Clear Unpinned Maps -command.home.name = Home -command.rename.name = Rename -command.duplicate.name = Duplicate -command.delete.name = Delete \ No newline at end of file +productName = XMind +providerName = XMind Ltd. +pluginName = XMind Application +prefPage.general.name = General +prefPage.share.name = Share +prefPage.spelling.name = Spelling +prefPage.keys.name = Keys +prefPage.language.name = Language +prefPage.advanced.name = Advanced +prefPage.appearance.name = Appearance +view.progress.name = Progress +productBlurb=Version: XMind{0} ({1})\n\ +\n\ +{2}{3}{4}\n\ +{5}\n\ +\n\ +Official Website: {6} + +view.outline.name = Outline +view.properties.name = Properties +command.showHome.description = Show the Home UI +command.showHome.name = Show Home UI +commandParameter.homePage.name = Home Page Id +command.toggleHome.description = Show/Hide the Home UI +command.toggleHome.name = Toggle Home +command.welcome.description = Show welcome information +command.welcome.name = Welcome to XMind +menu.file.new.label = &New... +menu.file.close.label = &Close +menu.file.closeAll.label = C&lose All +menu.file.save.label = &Save +menu.file.saveAs.label = Save &As... +menu.file.saveall.label = Sa&ve All +menu.file.print.label = &Print +menu.file.import.label = &Import... +menu.file.export.label = &Export... +menu.file.share.label = S&hare +menu.file.exit.label = E&xit +menu.edit.undo.label = &Undo +menu.edit.redo.label = &Redo +menu.edit.cut.label = Cu&t +menu.edit.copy.label = &Copy +menu.edit.paste.label = &Paste +menu.edit.delete.label = &Delete +menu.edit.selectAll.label = Select &All +menu.edit.find.label = &Find/Replace... +menu.edit.preference.label = &Preferences... +menu.help.welcome.label = &Welcome to XMind +menu.help.xmindHelp.label = XMind &Help +menu.help.keyAssist.label = &Key Assist +menu.help.about.label = &About XMind +context.showHome.name = Home UI Is Shown +toolbar.dashboard.home.label = Home +toolbar.dashboard.home.tooltip = Show Home +toolbar.edit.save.label = Save +toolbar.edit.save.tooltip = Save +toolbar.edit.undo.label = Undo +toolbar.edit.undo.tooltip = Undo +toolbar.edit.redo.label = Redo +toolbar.edit.redo.tooltip = Redo +toolbar.export.label=Export +toolbar.export.tooltip=Export +toolbar.share.label=Share +toolbar.share.tooltip=Share +toolbar.export.more.label=More... +toolbar.export.more.tooltip=Show all export options... + +command.showDashboard.label = More... +command.pinRecent.name = Pin Recent File +command.unpinRecent.name = Unpin Recent File +command.clearRecent.name = Clear Recent File +command.pinThis.label = Pin This Map +command.unpinThis.label = Unpin This Map +command.clearUnpinned.label = Clear Unpinned Maps +command.home.label = Home +command.openCloud.name = Open Cloud Page +theme.cathy.name = Cathy + +command.pinRecentFile.name = Pin Recent File +command.unpinRecentFile.name = Unpin Recent File +command.clearRecentFile.name = Clear Recent File + +command.duplicateTemplate.name = Duplicate Template +command.renameTemplate.name = Rename Template +command.deleteTemplate.name = Delete Template + +command.openCloudPage.name = Open Cloud Page +category.cloud.name = Cloud + +prefPage.section.startup.label = Startup +prefPage.section.fileList.label = File List +prefPage.section.saveBackup.label = Save and Backup + + +product.name = XMind +command.showDashboard.name = More... +command.pinMap.name = Pin This Map +command.unpinMap.name = Unpin This Map +command.clearUnpinnedMap.name = Clear Unpinned Maps +command.home.name = Home +command.rename.name = Rename +command.duplicate.name = Duplicate +command.delete.name = Delete +xmind.product.name = XMind \ No newline at end of file diff --git a/bundles/org.xmind.cathy/OSGI-INF/serviceManager.xml b/bundles/org.xmind.cathy/OSGI-INF/serviceManager.xml index 6e162e2f3..291e29b14 100644 --- a/bundles/org.xmind.cathy/OSGI-INF/serviceManager.xml +++ b/bundles/org.xmind.cathy/OSGI-INF/serviceManager.xml @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.cathy/about.html b/bundles/org.xmind.cathy/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.cathy/about.html +++ b/bundles/org.xmind.cathy/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.cathy/about.mappings b/bundles/org.xmind.cathy/about.mappings index 7b9d202ed..129c9dab7 100644 --- a/bundles/org.xmind.cathy/about.mappings +++ b/bundles/org.xmind.cathy/about.mappings @@ -1,7 +1,7 @@ -0=$org.xmind.product.brandingVersion$ -1=$org.xmind.product.buildid$ -2=$org.xmind.product.license.restrictions$ -3=$org.xmind.product.license.type$ -4=$org.xmind.product.license.licensee$ -5=$org.xmind.product.about.copyright$ -6=$org.xmind.product.about.homepage$ +0=$org.xmind.product.brandingVersion$ +1=$org.xmind.product.buildid$ +2=$org.xmind.product.license.restrictions$ +3=$org.xmind.product.license.type$ +4=$org.xmind.product.license.licensee$ +5=$org.xmind.product.about.copyright$ +6=$org.xmind.product.about.homepage$ diff --git a/bundles/org.xmind.cathy/build.properties b/bundles/org.xmind.cathy/build.properties index 4dd15c799..8cc524132 100644 --- a/bundles/org.xmind.cathy/build.properties +++ b/bundles/org.xmind.cathy/build.properties @@ -1,18 +1,18 @@ -output.. = bin/ -bin.includes = plugin.xml,\ - META-INF/,\ - .,\ - plugin_customization.ini,\ - icons/,\ - splash.bmp,\ - about.html,\ - about.mappings,\ - resource/,\ - Application.e4xmi,\ - css/,\ - dashboard/,\ - images/,\ - OSGI-INF/,\ - OSGI-INF/l10n/bundle.properties -src.includes = about.html -source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + plugin_customization.ini,\ + icons/,\ + splash.bmp,\ + about.html,\ + about.mappings,\ + resource/,\ + Application.e4xmi,\ + css/,\ + dashboard/,\ + images/,\ + OSGI-INF/,\ + OSGI-INF/l10n/bundle.properties +src.includes = about.html +source.. = src/ diff --git a/bundles/org.xmind.cathy/css/default.css b/bundles/org.xmind.cathy/css/default.css index c6897e959..fc8e36f7b 100644 --- a/bundles/org.xmind.cathy/css/default.css +++ b/bundles/org.xmind.cathy/css/default.css @@ -1,196 +1,196 @@ -.MPartStack{ - swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); - /*outer border */ - xmind-swt-outer-border-visible:true; - swt-outer-keyline-color:#9f9f9f; - - /*inner border */ - xmind-swt-inner-border-visible:true; - swt-inner-keyline-color:#9f9f9f; - - /*shadow */ - swt-shadow-visible:false; - - /*corner radius */ - swt-corner-radius:0px; - - /*selected tab color */ - swt-selected-tab-fill:#ffffff 100%; - - /*selected tab area color */ - xmind-swt-selected-tab-area-color:#ffffff 100%; - - /*unselected tab color */ - xmind-swt-unselected-tabs-color:#35a6b9 100%; - - /*hover tab color */ - xmind-swt-hover-tab-color:#ffffff; - - xmind-swt-image-visible:false; - - xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:false; - - /*visibility of unselected tabs bg */ - xmind-swt-unselected-tabs-bg-visible:false; - /* - * xswt-chevron-visible:false; - * - */ - - /*custom maximize image */ - /*xmind-swt-maximize-image:url("platform:/plugin/org.xmind.ui.menus/icons/export.png");*/ - - xmind-swt-minimize-image:url("platform:/plugin/org.xmind.cathy/icons/views/view_minimize.png"); - - /*tab height */ - swt-tab-height:20px; - - xmind-swt-close-image:url("platform:/plugin/org.xmind.cathy/icons/views/close.png"); - xmind-swt-close-hover-image:url("platform:/plugin/org.xmind.cathy/icons/views/close_hover.png"); -} - -.MPartStack.active{ - swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); - xmind-swt-outer-border-visible:true; - swt-outer-keyline-color:#35a6d9; - - xmind-swt-inner-border-visible:true; - swt-inner-keyline-color:#35a6d9; - - swt-shadow-visible:false; - swt-corner-radius:0px; - /*swt-selected-tab-fill:#35a6d9 100%;*/ - xmind-swt-selected-tab-area-color:#35a6d9 100%; - xmind-swt-unselected-tabs-color:#35a6d9 #35a6d9 100%; - xmind-swt-hover-tab-color:#ffffff; - xmind-swt-image-visible:false; - - xmind-swt-minimize-visible:fasle; - xmind-swt-maximize-visible:false; - - xmind-swt-minimize-image:url("platform:/plugin/org.xmind.cathy/icons/views/view_minimize.png"); - - xmind-swt-unselected-tabs-bg-visible:false; - /* - * xswt-chevron-visible:false; - */ - - swt-tab-height:20px; -} - -.MPartStack>CTabItem { - /* unselected tab text */ - color: #2c3e50; - xmind-swt-show-close:false; -} - -.MPartStack>CTabItem:selected { - /* selected tab text */ - color: #2c3e50; - xmind-swt-show-close:false; -} - -.MPartStack.active>CTabItem:selected { - /* text color of active and selected tab */ - color: #ffffff; - xmind-swt-show-close:false; -} - -#org-eclipse-ui-editorss .MPartStack>CTabItem { - xmind-swt-show-close:true; -} - -#org-eclipse-ui-editorss .MPartStack>CTabItem:selected { - xmind-swt-show-close:true; -} - -#org-eclipse-ui-editorss .MPartStack{ - xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:false; -} - -#org-eclipse-ui-editorss .MPartStack.active{ - xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:false; -} - -#org-eclipse-ui-editorss .MArea{ - swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); - /*xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:false;*/ - swt-tab-height:0px; - xmind-ctabfolder-render-none:true; -} - -#org-eclipse-ui-editorss .MArea.active{ - swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); - /*xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:false;*/ - swt-tab-height:0px; - xmind-ctabfolder-render-none:true; -} - -.MPartStack .MPart>Composite{ - background-color: #ffffff; -} - -CTabFolder{ - swt-simple:true; -} - -ToolBar{ - xmind-swt-view-menu-image:url("platform:/plugin/org.xmind.cathy/images/viewmenu.png"); -} - -/************************************************** - * Window - **************************************************/ -Shell.MTrimmedWindow { - margin-top: 0px; - margin-right: 0px; - margin-bottom: 0px; - margin-left: 0px; -} - -.MPartSashContainer { - xmind-sash-width : 0px; -} - -/************************************************** - * Main ToolBar - **************************************************/ -#org-eclipse-ui-main-toolbar { - xmind-margin-top:4pt; - xmind-margin-bottom:4pt; -} - -/** - * Status Bar - */ -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #ffffff; -} - -/** - * Form - */ -.MPart Form { - text-background-color: #ecf0f1 #ecf0f1 100%; - color : #000000; - h-bottom-keyline-1-color: #ffffff; - h-bottom-keyline-2-color: #b1d1f3; -} -.MPart Section { - background-color-titlebar: #ffffff; - border-color-titlebar: #ffffff; - xmind-title-bar-text-color : #216592; - xmind-title-bar-active-text-color : #7b8fa5; -} -.MPart FormText { - xmind-hyperlink-color: #1949d9; - xmind-active-hyperlink-color: #11149b; -} - +.MPartStack{ + swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); + /*outer border */ + xmind-swt-outer-border-visible:true; + swt-outer-keyline-color:#9f9f9f; + + /*inner border */ + xmind-swt-inner-border-visible:true; + swt-inner-keyline-color:#9f9f9f; + + /*shadow */ + swt-shadow-visible:false; + + /*corner radius */ + swt-corner-radius:0px; + + /*selected tab color */ + swt-selected-tab-fill:#ffffff 100%; + + /*selected tab area color */ + xmind-swt-selected-tab-area-color:#ffffff 100%; + + /*unselected tab color */ + xmind-swt-unselected-tabs-color:#35a6b9 100%; + + /*hover tab color */ + xmind-swt-hover-tab-color:#ffffff; + + xmind-swt-image-visible:false; + + xmind-swt-minimize-visible:false; + xmind-swt-maximize-visible:false; + + /*visibility of unselected tabs bg */ + xmind-swt-unselected-tabs-bg-visible:false; + /* + * xswt-chevron-visible:false; + * + */ + + /*custom maximize image */ + /*xmind-swt-maximize-image:url("platform:/plugin/org.xmind.ui.menus/icons/export.png");*/ + + xmind-swt-minimize-image:url("platform:/plugin/org.xmind.cathy/icons/views/view_minimize.png"); + + /*tab height */ + swt-tab-height:20px; + + xmind-swt-close-image:url("platform:/plugin/org.xmind.cathy/icons/views/close.png"); + xmind-swt-close-hover-image:url("platform:/plugin/org.xmind.cathy/icons/views/close_hover.png"); +} + +.MPartStack.active{ + swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); + xmind-swt-outer-border-visible:true; + swt-outer-keyline-color:#35a6d9; + + xmind-swt-inner-border-visible:true; + swt-inner-keyline-color:#35a6d9; + + swt-shadow-visible:false; + swt-corner-radius:0px; + /*swt-selected-tab-fill:#35a6d9 100%;*/ + xmind-swt-selected-tab-area-color:#35a6d9 100%; + xmind-swt-unselected-tabs-color:#35a6d9 #35a6d9 100%; + xmind-swt-hover-tab-color:#ffffff; + xmind-swt-image-visible:false; + + xmind-swt-minimize-visible:fasle; + xmind-swt-maximize-visible:false; + + xmind-swt-minimize-image:url("platform:/plugin/org.xmind.cathy/icons/views/view_minimize.png"); + + xmind-swt-unselected-tabs-bg-visible:false; + /* + * xswt-chevron-visible:false; + */ + + swt-tab-height:20px; +} + +.MPartStack>CTabItem { + /* unselected tab text */ + color: #2c3e50; + xmind-swt-show-close:false; +} + +.MPartStack>CTabItem:selected { + /* selected tab text */ + color: #2c3e50; + xmind-swt-show-close:false; +} + +.MPartStack.active>CTabItem:selected { + /* text color of active and selected tab */ + color: #ffffff; + xmind-swt-show-close:false; +} + +#org-eclipse-ui-editorss .MPartStack>CTabItem { + xmind-swt-show-close:true; +} + +#org-eclipse-ui-editorss .MPartStack>CTabItem:selected { + xmind-swt-show-close:true; +} + +#org-eclipse-ui-editorss .MPartStack{ + xmind-swt-minimize-visible:false; + xmind-swt-maximize-visible:false; +} + +#org-eclipse-ui-editorss .MPartStack.active{ + xmind-swt-minimize-visible:false; + xmind-swt-maximize-visible:false; +} + +#org-eclipse-ui-editorss .MArea{ + swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); + /*xmind-swt-minimize-visible:false; + xmind-swt-maximize-visible:false;*/ + swt-tab-height:0px; + xmind-ctabfolder-render-none:true; +} + +#org-eclipse-ui-editorss .MArea.active{ + swt-tab-renderer:url("bundleclass://org.xmind.cathy/org.xmind.cathy.internal.css.CathyCTabFolderRendering"); + /*xmind-swt-minimize-visible:false; + xmind-swt-maximize-visible:false;*/ + swt-tab-height:0px; + xmind-ctabfolder-render-none:true; +} + +.MPartStack .MPart>Composite{ + background-color: #ffffff; +} + +CTabFolder{ + swt-simple:true; +} + +ToolBar{ + xmind-swt-view-menu-image:url("platform:/plugin/org.xmind.cathy/images/viewmenu.png"); +} + +/************************************************** + * Window + **************************************************/ +Shell.MTrimmedWindow { + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + margin-left: 0px; +} + +.MPartSashContainer { + xmind-sash-width : 0px; +} + +/************************************************** + * Main ToolBar + **************************************************/ +#org-eclipse-ui-main-toolbar { + xmind-margin-top:4pt; + xmind-margin-bottom:4pt; +} + +/** + * Status Bar + */ +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #ffffff; +} + +/** + * Form + */ +.MPart Form { + text-background-color: #ecf0f1 #ecf0f1 100%; + color : #000000; + h-bottom-keyline-1-color: #ffffff; + h-bottom-keyline-2-color: #b1d1f3; +} +.MPart Section { + background-color-titlebar: #ffffff; + border-color-titlebar: #ffffff; + xmind-title-bar-text-color : #216592; + xmind-title-bar-active-text-color : #7b8fa5; +} +.MPart FormText { + xmind-hyperlink-color: #1949d9; + xmind-active-hyperlink-color: #11149b; +} + diff --git a/bundles/org.xmind.cathy/css/default_gtk.css b/bundles/org.xmind.cathy/css/default_gtk.css index 88b2b32d9..1caeb82f4 100644 --- a/bundles/org.xmind.cathy/css/default_gtk.css +++ b/bundles/org.xmind.cathy/css/default_gtk.css @@ -1,27 +1,27 @@ -@import url("platform:/plugin/org.xmind.cathy/css/default.css"); - -.MPartStack{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d9; -} - -.MPartStack.active{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d9; - swt-selected-tab-fill:#35a6d9 100%; -} - -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #000000; -} - -Shell.MTrimmedWindow { - background-color:#ffffff #e8e8e8 100%; -} - -MTabFolder{ - xmind-tab-folder-bg:#5f5f5f; -} - +@import url("platform:/plugin/org.xmind.cathy/css/default.css"); + +.MPartStack{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d9; +} + +.MPartStack.active{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d9; + swt-selected-tab-fill:#35a6d9 100%; +} + +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #000000; +} + +Shell.MTrimmedWindow { + background-color:#ffffff #e8e8e8 100%; +} + +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; +} + diff --git a/bundles/org.xmind.cathy/css/default_mac.css b/bundles/org.xmind.cathy/css/default_mac.css index 31ddb5cfc..25b1526af 100644 --- a/bundles/org.xmind.cathy/css/default_mac.css +++ b/bundles/org.xmind.cathy/css/default_mac.css @@ -1,26 +1,26 @@ -@import url("platform:/plugin/org.xmind.cathy/css/default.css"); - -.MPartStack{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d7; -} - -.MPartStack.active{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d7; - swt-selected-tab-fill:#35a6d9 100%; -} - -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #000000; -} - -Shell.MTrimmedWindow { - background-color:#f7f7f7 #e5e5e5 100%; -} - -MTabFolder{ - xmind-tab-folder-bg:#5f5f5f; -} +@import url("platform:/plugin/org.xmind.cathy/css/default.css"); + +.MPartStack{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d7; +} + +.MPartStack.active{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d7; + swt-selected-tab-fill:#35a6d9 100%; +} + +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #000000; +} + +Shell.MTrimmedWindow { + background-color:#f7f7f7 #e5e5e5 100%; +} + +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; +} diff --git a/bundles/org.xmind.cathy/css/default_win.css b/bundles/org.xmind.cathy/css/default_win.css index 88b2b32d9..1caeb82f4 100644 --- a/bundles/org.xmind.cathy/css/default_win.css +++ b/bundles/org.xmind.cathy/css/default_win.css @@ -1,27 +1,27 @@ -@import url("platform:/plugin/org.xmind.cathy/css/default.css"); - -.MPartStack{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d9; -} - -.MPartStack.active{ - /*hover tab color */ - xmind-swt-hover-tab-color:#d9d9d9; - swt-selected-tab-fill:#35a6d9 100%; -} - -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #000000; -} - -Shell.MTrimmedWindow { - background-color:#ffffff #e8e8e8 100%; -} - -MTabFolder{ - xmind-tab-folder-bg:#5f5f5f; -} - +@import url("platform:/plugin/org.xmind.cathy/css/default.css"); + +.MPartStack{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d9; +} + +.MPartStack.active{ + /*hover tab color */ + xmind-swt-hover-tab-color:#d9d9d9; + swt-selected-tab-fill:#35a6d9 100%; +} + +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #000000; +} + +Shell.MTrimmedWindow { + background-color:#ffffff #e8e8e8 100%; +} + +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; +} + diff --git a/bundles/org.xmind.cathy/css/default_win7.css b/bundles/org.xmind.cathy/css/default_win7.css index d04b4993e..e1724f189 100644 --- a/bundles/org.xmind.cathy/css/default_win7.css +++ b/bundles/org.xmind.cathy/css/default_win7.css @@ -1,27 +1,27 @@ -@import url("platform:/plugin/org.xmind.cathy/css/default.css"); - -.MPartStack{ - /*hover tab color */ - xmind-swt-hover-tab-color:#ffffff; -} - -.MPartStack.active{ - /*hover tab color */ - xmind-swt-hover-tab-color:#ffffff; - swt-selected-tab-fill:#35a6d9 100%; -} - -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #000000; -} - -Shell.MTrimmedWindow { - background-color:#ffffff #e8e8e8 100%; -} - -MTabFolder{ - xmind-tab-folder-bg:#5f5f5f; -} - +@import url("platform:/plugin/org.xmind.cathy/css/default.css"); + +.MPartStack{ + /*hover tab color */ + xmind-swt-hover-tab-color:#ffffff; +} + +.MPartStack.active{ + /*hover tab color */ + xmind-swt-hover-tab-color:#ffffff; + swt-selected-tab-fill:#35a6d9 100%; +} + +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #000000; +} + +Shell.MTrimmedWindow { + background-color:#ffffff #e8e8e8 100%; +} + +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; +} + diff --git a/bundles/org.xmind.cathy/css/default_win8.css b/bundles/org.xmind.cathy/css/default_win8.css index b9776f710..3213c25c5 100644 --- a/bundles/org.xmind.cathy/css/default_win8.css +++ b/bundles/org.xmind.cathy/css/default_win8.css @@ -1,27 +1,27 @@ -@import url("platform:/plugin/org.xmind.cathy/css/default.css"); - -.MPartStack{ - /*hover tab color */ - xmind-swt-hover-tab-color:#e9e9e9; -} - -.MPartStack.active{ - /*hover tab color */ - xmind-swt-hover-tab-color:#e9e9e9; - swt-selected-tab-fill:#228edc 100%; -} - -#org-eclipse-ui-trim-status, -#org-eclipse-ui-trim-status * -{ - color : #000000; -} - -Shell.MTrimmedWindow { - background-color:#ffffff #e8e8e8 100%; -} - -MTabFolder{ - xmind-tab-folder-bg:#5f5f5f; -} - +@import url("platform:/plugin/org.xmind.cathy/css/default.css"); + +.MPartStack{ + /*hover tab color */ + xmind-swt-hover-tab-color:#e9e9e9; +} + +.MPartStack.active{ + /*hover tab color */ + xmind-swt-hover-tab-color:#e9e9e9; + swt-selected-tab-fill:#228edc 100%; +} + +#org-eclipse-ui-trim-status, +#org-eclipse-ui-trim-status * +{ + color : #000000; +} + +Shell.MTrimmedWindow { + background-color:#ffffff #e8e8e8 100%; +} + +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; +} + diff --git a/bundles/org.xmind.cathy/dashboard/back.png b/bundles/org.xmind.cathy/dashboard/back.png index 2b59437f8a9152d8316fea4df2199633164e600b..5e6ffafe1667b3dc4182b3e78550b001c1b86784 100644 GIT binary patch delta 934 zcmV;X16lm849EwNFn_wdcCZeMZjL8(Olix*%@P5b|MrCRg1R&9r<;W$wa49DU?p9Q9K$oigjXW zXy_7VPVI0w){l>m5eUa|FNGYaD*Vvj-!J2N{z@Pa`1K7TiGrdY4i68*)JND6zR-re z1Nh^b0|V7PJw4AXH2p2d0x*Fk7K;foK_a(rY}m8e zEF$uqVN8RAgOn&>G70F`>2%ky6VEMXGm}at5r~iz1boA0vuE&@WilC*#p3mP7a^FE z5>d#B6flvO6ZznfF8~hW^>|7LKaUAIj|pG{oapTARDVLkt>ef6oFuKM9NK;B2@}9bsosC)*K0zMZf^jFb0X{RfkvyL>)E& z4jpc6bboZNxw-kI!)-d9n?9c}d859*1_0%9dCP;gwnmDgJ}xgWmxqbG$n9(_hS+#K zCtqEzMO=b+pjnw$Ru~SmLKulgB7z;WkeLe^Ad!!bjQr{CQmMqhx3{F9nCQg^&4EIp z@R(^je!HRJJ}?1iFEG*8+S*8|RHZX<61mlCkAEEL5%cFhe=P zj6}j=(M+6T2F`PBcei>Cz@t$F4uH6}woZW)qkJb;@piyg5D6a~7>ha!V6v{OtM0wg z`1vRjftH(-Z2@p0CrGXU8~8%K06fTKD<=ORpv;duL{5 zVt+z)4t+wcR_`m7%6D(4rry|WHYR5eKRkaE)OpXDB;4KIMGFfHS+~c7b4W#n_V+(b z84OP^0w)VY>Gk#Xalv5FZM9f}xM5L<=dE_9b8>cemL>D@^|=>D*i(jKF5{aKIGCKC zo=yoxp1&9wgT34BR^cj9;7d$uetw=S#vh)nQ_&R${s{v=0b%zGSq4xiz5oCK07*qo IM6N<$f*R|#H~;_u delta 1553 zcmV+s2JZRD2d)f|FnAZoIa@%3NnguJ&iv>6*YEu2pMORWmdA1imNW2%41egl9*>#$2DSezj^maH zB4VARs%jxkNs{cC`QYVhn&zsktSq{6<%%qdqRwrWqVQ*(o}RW#x?U(s(z}8rrDOlY z>eZ{;7x;i;o}wtffzDvQG7ww`ApKf%^P#%BI`dLNgTdg=P$=|kC>V5wWm%I$A)O}n zY`R>o`xO-xD}UzukR~Q3a!n@F7BG{!04Rj{llb<+!kV$Mu_Ugun4UOsLQV$j@f|6*2ZB-Cme~0;3WY7ZP}1;s>s8K4}ULl2EpcrSTHs{HJqrlwDjDD z4IA_>n`OKL!U-kC(4sas| z!cfsQjX5A*Qet9i*~X0yzsFO9Oe7d8jKKEoj8&_Skq?8x2!IR3X}fpt`JLOh?_=q| zd-tx&gnxLjla!a2o0F1~imI!t&u!bb?E~B)iq|+jC<8QaPsS)*zp80}NrDhTm1m=l zN>H%a&JD6hAx8TL2gh#Ty5;Kc@9#AU!jJhyMZEy8a6JY9%HqC#`^+;lGwS<+pVeUFtXSsm`v>e>Bm(?40ntG zlpvfuc~a=<=}~s=+BG`(=uu}|Tid`N?d@Syj3s^LN^7FULd}TXqaccNbTI&u8=fVT zNy2scBeHzzZ@2rZtm}Qn#l_(|xz&AuG8&y?R7QFkZlBU^3lWF75%F2&- z?0?u%%&#Jr2?K;-$J}rkZEz(KT*IZw>FHB8n{8-817g}n4H)YMgn%48crc-$pdbUU z&6hdZ*)^oV1918}UQG6HmZHH>sOhQGd919gY;ryjRs#zn8yh&Wg+rlw6xgR=#kvd_atE$S6=G5`P&9_-Q^R?Oxo4ll{FoQ{uHQGZTO z&WE-8_g7?QWu-BzdA9RG&^j88hPyjEw>;?T`ZERqC)|(CcL+x9lG$*IkI48J$B&;^ zG_5fsBO}n**r@P(#8=V;5N4|=rdrd}w|{>0=;_SN%vBr&Q3}Eu8r~p2#>U5=)*m@i z$~YqGlHw|mm* zbWY%BVjM0U$tzaKF;7b@sIn6h5_;ds&22@I+I>D>(1W0^p`l5i-#-P@FCE_#DfddEP(JS856lFUY zVWiWmOOh9BKm5)Dn1WBYg5r&`{NSC8!w)+9`c!PLVtB`qyY!P}wo2DFs@vh4qrfqwvQGuE-=B_Q4a015yANkvXXu0mjf DTWS!g diff --git a/bundles/org.xmind.cathy/dashboard/back@2x.png b/bundles/org.xmind.cathy/dashboard/back@2x.png index 152f1c38163e5a5732fe6c8ca7044e961366b04a..3943ebbbb239aebad252f5ff73efbd6c5921318c 100644 GIT binary patch delta 2535 zcmVlTFgDvS?JYnM&DAx~PyUC26X3Q^SNXNhbUaEd~+@ z5WpD!zkcWPuIJj=aE+fwUA!yV_rCY;z2|)2IrqH#&U+@4QGW~u3FX{o=9MpK;w$Xsll6iTu;2PdfsEz`jU0{Fih( ztT3qrly}Xx3>OCF`Mfl*hD|G+5Ay59{&>UvXMYm zfA;K|%Vx8+ocj3VFC7&Xzvc2#H(0IKFHk#W@$i091Q7Feb#+d#+|=IQ{%fnn;sxrh zIZ!i2Os1pdB7wliVlkJ`=WF%*{a;j7SN}qj&U7I8@PCAc&CSi9a$vHx6afz(K2)r+ zm^&ShH-9@h$t(}l8R67`7noGD`6!lyuAacbA2@KJwY$6fPOaDbJ|kR{&-EbrZ%|}` z^L|nUVC|b?R;w+oDDJ7LDbvvK@Ej>Yg)BiWu9R6(bR$6o|NDy<2Yy&v`yR<+WTR%_ z$rGW=@_*9OU(cRBJ4dIBDN+Q$15A!&GGS5GFeYFBdB(GN3hyj0`9P1&_u{ zj0qz6ivaH>@EYk1`@bHt{gu`y=PC@2Hxv^FEcNZfFJWe)PFNGGvgP#y8MgN(~F~{qp3_k$%YgG zu&BDYxEQrYqw@$hqhNm&7M|_ZNXP=ODMuD!o={{=;NV+ZTU(gr0iJtS1{1kGN@#X= z;!00X*IFd<+~M`ElA$tvBpXr$&|EZmmCv_|=A_wT3Bn3bMG~lwNCdU%MgsvyPolV07rp*z-hZM9paC)@XqKn$Sp`rA9eGID2A=jC4LnULy#zQCD5KuGbt{RD(F%Z$tBR7n9LB~nfsv2lHFl5NmV*es%kRJA(E=XX zU9=7zhv4>lS)S`8%HZdu>fJn{y{(Nc2WH8wSit7h9GZE;i4!N1w8NuK&V>sX27j>0 z*>ZdC?leMc&yw3;y{e1bivTU+K{0IvAX6|HRPW!vAK%#6h~V}ZGpnj4l}@|<_4sl4 z;K74f#ac=zl9oU9!^ zp}YGKo*ill7{vv#&^ZLLe{M#jm49UU+-uaI`urE*@$^>~@FcTj0%(%mNNB@y;MV0e z2T0=!l^M8wIl+_MqJv;QWdW*iUJ>zxI8ACmnS001gJq7v3je zIglqXp>XYdg?k6B`9N=P+1y@~onI5NN0IG9B-rfsCOpo5ATEb|Q`08r`+ovY@~!!l zDCHb22b3gsj4RkNjw`CF;4#{Y^A*TiFyF^@CW0(ZZEkrw>2kSND=RCXBlA0Kc=_I5 zi2mFQ@)05sQFan^xebc!=L1jIk-yG#W2|HS)9rEW<;!Ir6Ich3#Fhe$QPrc-NJQ#U zIx~5Z4P6Nk!Jmia@tnTxc^;_P`bTbYuD7r6QD0x*5D~#i;IV<%@PCG~lAs#_x!@_8 z!7R<)UW@o-Al&Dt`uh8CAffUVB~|)*dxH~rie#3jJpzr<#xWx3DY8tSz;rCqYqoXI z1@Eb;*`Cb6C=y1`^8nwyy1F_Az*V?uz6&eALrE3n{10_>bkq`Pt{7_*DO6N-(CKpN z8W>CVfGqIm&J7TFO@CPm`K-y0HSqp$I6Q>h;<(f4e1@mUe*+jxul4u$2geHJ6W9_d z!*VEzfGqHze3Du71e+|ES=Vsq(A*qZo^5Xt8|JXlS+A<9q5zncR3Q?^X*uMK=XVC2 z*EJ^WnSgEJ>5*2mI0w!wkH1;CJ%DBH?eE^bn<|u9;w13#RDWm92~UV@Z0K@#5PVb= zw{tred<{i=4LqBW+FB5!Oiusx>sjE%1SWtLe1M{u(5B@R_?A%Xgm z!i;2rj8aIDj(-94iX2hfiL`d(?@pci14VlX&Rv_#D!aKo2QAhJas`tr?CzkwhRb-E zCYyAi%@Sh5Epa~CwiE$mou#EE8@>;yL$dQ%jXqx|MP({NbY|sgWU{%!;eW`oye6Ev<_x0!^*w^;O7BVn z?GwoQ+JKCF7(_{@eS99-T8aQ9Hq7a8xWbf5)jb^@rEG4D3+96K0MF;zk%Vj4f@73p z+_F0JKx!k0@aF!bN8j){WNRq`_+)9U)6GaEdHeS5CwLbSClbgK*tm?8YI!b$*M&%k zB@!W84uAMaW1h)}4mh_K92z=z@7}#AA1_-=rNrFJ8Qu z$G+XRzP>*8?bOsiEOz_XrM{@lRhmdZ`7XU?wW_9MGKIHE@tZeptTp(2&c^-wS0^VY z2bY(ZAJ^B{7yWu%>NW@^%*T!$!}E&09$#bq7=MbkV=w;$xX&t{@+Wa_f?iRV@|HFi zym(CV>8&(^Tn*&5;J5?%MIR9a_YWyH+Y9LSAH0MKi<>NQjzVoI0%$PZ2JtG(4)&|@ zjiA?xPvX)ROVpl7tl;aBHQXIy#R@N^RKD|^goT9#H}1wYSo2lX4|k?@ zo?v9Yu{)iUCV(a(CGbwrf;)l*$xem7$)V3u=;H}yjh!Uvbd5G+n92gsEPf#tr9pnO xoaF1Ix-pHxfWd&lfWd&lfWd&l!2cHm{{xFPOrUq`_vios002ovPDHLkV1iY(?+X9` delta 4270 zcmV;f5K-^_6Sg6cFnBzWtnI}s2EBROEe{as7W*x1WdGyT9pb|uz_eal~N8hC8Cy`#Vv@7vRT+=@B7}l z@AvZidS1VMJ3F%rgvwDhUHhiHzyA6=e%<}O?tZJ&B~ucCB!2=)1d<3O5lAACL?DSk z5`iQFNd%Gz+!_M1Ea%{vh(~{G68=wm!9lyv=UWhoM4k$V!*5HHbP}{4S(5N4$)Qka z^UE*4Ec`dzfgM(l$8(p*;aKi-xfY?GawB%c9WitkgTY`i1e6GZFkP?LPe(ot`Pf*Y z;8jULq2t#tzJEB$YPEU*grqjy#sc&i+-^77HiOxw(~*7CP%gwEME!wHk}O}^yKmq8 zwQJV~(B5xkJX;`C9|#0~j8WYKA>X4O#4}`~5vPZbKCf3)RQ&XjM;y^RB9-`tK%_ zX}`f>c%0Bg2XUxQ+BOa?(9+S9lauo}z%-*AcXny}CMwf1a=Ba&TP>DGgCHEx>GfMM z!fU`k6LQVGAJ?hoN(0p?$&tvtMMXs>)Dzkwj2Sb=3WE!jzC&iJB1HjbCOUwFMp-v< z2Cw`N&J#w$G-bw&KcYV5`s4iC z9DgxMLYxajMxd#&u}RxTWvxzanc5g2%2K4Z`o_j)1ZR#Du?$KABEQEV%bg#6^2rHw z($1)URCzZAX{u@&smvcf0v3zq-qO<2SD$?H$swaK7tQm{n>WiwqcI>G3=X`Con#U> zi|34&o62*tLBksfheOAY9{moqNP2p@)_+{CiseFTYN|&simj(kow|7X^yx~q6~g$M z=QNVS*BN(|8>NMr8$o$Hd`1`-;1R*LZPW3a9-w-vgSFB z@#2Tt&YnH{O>2952bMsfva&KU02rwtm^z@iddH3(hpMZqJ4q1r;LfqSf;4wdOMlar zsUHJF84Zio`uoog9{lsCpMGj3z8g*J*RP*Cdi3Zi9B6GnZWqs~jh87eyL`E>bocJh z0b&=Le6*~z{k3HQN+O~tI?%Bu6bMxO?v+;#RaI3n5I7?j&gb-mS4*7b#c=4hYvu53W3x5{u!k{qTL~>Pd_}~DC^XJahzWL^x2hry`mUnw@ zZmxf*T`9AlrYNSHT@D5(O9sQ;AeKDw#1lVUwrm-_iy067@L9pj%t0Dy6yni%JIj^e zgrL-ldHxX$JcnS{3~)q@R3^goDCk;**|-EeHr6NhN71Fqr6m9wbjuZ2uYY#!{qV!` zs_N5v7&gL>}F}hh7BTiUl};i6iMOmY@mPV;w4LFKK9sS zC03iw#L(_n$ed;!wE&>Z(*RIncpzJyvc%6vSaF5|fl5>5MIBZ3(mos;CdapBWgUoL zO&#s+?U37yxn6-F`W;5Uu79MY#DUQda~bh+6#yvLsk0K!2du7Pg^j05~5F zld+$k0%yl%W@e7YA*cA>dGp2~aMCW1^<#!n3H2x?S|)(BpfF~oPn2EdW=)A`T6#l$ zeea7ey>tYUd!fGW?IVCc%q%5os;2ag{=KIF)Ar2_!qM2ZP^yWL_o zo3n7pA14XIBy1}uK!4$A6KG2xc%X36!i5F-1qJq4CkFsR4r_qm@;P|CPI)YCKwSY2 z(xk&jj(q;!d+&XK0cyd7>_N=v(|bH_w@&AsJ$rT#`-lka9E`43nWh{U0BXnd5xTp( z#jd)#w4lk91yVjh7!Sn9VtI^$ff+@`#iJfrwrt#-IdgI?DSs*ItRU?S2pA4ym~)&) zvbD}>%i1;-NFpL}KBD9BR@Lip{9)(LogdWJ)&@X|;O!#ajN>GeQbGWz5lSg8&_3D( zv~371nV1oIfOrgu1&9&35Riqvd-}=;ADpye#fk|jW;2Tu++anH3Ix?DQ9FUd%d8Ns zL}|RN07#r{SbzIx0|}{($nsmb3Hl3O=U&$FCVz$mfXgBv=y+RLSZKud)Pm_Z0(mwZ z$OTV6;shP1^NNd##&6lS?LOjXeaS%>%)#KZf!a8Y@oDPJQF2lNhxO-7ln(@ewSc=L z916Ye_IlqgC@Ao0*@r79JSAy6($u1$^6tCu`ftm*CjfcT}qygL@$4L)?!Fkvyqdx-(bk-JSVrAB@)K!plx*TjL-WX}OS37!p ze{t;Cu^T>r+|UdleX$9Kv00IpmS)*emY|j~t#`UPD zvC$>vQH@I0?+Uimk&~xRHGlQR7xfK|jSjSgz|A%%08Ri(qDd4@(@RRS=iGHy_RLwc za({6&SGU|zv4{;QsJgU{5kN}PwsRWgj83^ERdu(wub41p%Jo+IpbWi`gF5 z1%u=e9dk_)L9l_If%Z|T=Yc;L`;DyCt5?rhvUu@$@JH<<=lC+v=vKWTLo|SB!GEA8 zN@O4SYg?{gpLgfnxpZ)1-Q&J4Xcq_vewJ#p?SkWU#~+n~Uv&f&p;~1m^qqI!Iq7t} zFCsX8k87=3d~fIih+fDGFu zmX(#YJhO4*-MCPpdqq`01wrmC<$qfJ1Ni!TuoCg1=lGnlV@t8Q`w4hMWN#E<4Kofr z2HfR6ZL?bGQd6CFtgJDFlxdYyJHEs;ZQZhEC-wyA@Xo)6IM4&fgLp5;-JcWC=qBJ; z%Qjdz-DN;#K1RNn4qO8-X1Av>;GvVC;AIX*JX<)8?21jzt$(enH*Vax zpY}EbW&k!pDytJBRgNj%i$p<^6W5bSC$(p1Wc&sf zKy+*5QH9cIU@xCDxw!Zs-hZKKs=FE`995o^FkZ%pOM7OfKB)ggSeAWXuTr$13(dbbkeSh2*Di4?9@mOrO`S{FkV*sFFT(f4)92_Wei8;2zAZ3bDb!DTD zPu3oNIP8VdEV>S7)Nt(t0^Sh*5hF&l!k%lV&z?Qi($dmBTt8}0WWTmAme^=4tyIh~ zS&yJ6!f^U5J|J;HJf}uh=A*CS?(FJn!t@Wq=IGkcwB2fvZhv#}%Jkx9stJQoec|h` z%eXB(k0+ZCSiH7CFc`wlwC%{@!~3v|t;Q`|wqW4GW^|(e^I?7HmqwQaaoPZ33LpAK zu*Y{}Ej3}Ceg>W(?%{760HhONcEb$~4SgY>ukq~Z(`Qz$T)7B#v6&0wSWsiOY0Dts z$Sz?}yzQ;6Zhy=icVlCttGcGf+0oJA#G9%E0rnds&Lu_!9RaTd5!+U5(V~f*C&vi@ zCCPY2`N`Sl=4Lkxa^ot>f%mr)j2`gRW1ZF@fVvS2ZYuz^6!3Zu2qsfUTSrILmGbh+ z>C>i7W_H0o*eLh)^^t8JauhpJ7ui+c(BQ)V2l%lC4}SnAKX$WpBBaLy=i9MEtulyW zAKM4OaN(ahcH;HiRJv=|KjzP$?}k$;?HwJyn(Np5u-Wnhi2&KAanwtL zgCTUmUVjJLUHVAG1)JUY`sxrvpnpm8At7qX!Ta^xuVlcVG? zMR^yTbs~3?Feq>n&5)APhqd1~bLLF<&ECqAgTp20rn^b{udlI~+IPdAsj$P2oWS;> z?7>L8$XRR}9L!Nsbip<{fcdc2{Rr@W%+3J%2Y)j%GD3xgg>*8NjP&6U|3Kh3ghFlD zeO18u9yCO-opqt36OqyhP~7;0PD*?_lgS4mev`%G#~wdGdwkUC`(gyn-_p%2^bMKd zhzvW)=yn9fGAS7B)*Fo$*cyb59*nw25JfLJiqGPH{Fj;!b_eMzGXf~ZDH)GMzQRV} z)qlT11Bl8OAsk0BigX~cfEK}a)=!R_ArR66^m@Zmp{OijN)l-DtzJbB>1~2WvJ(N@ zaOu(|yuxi()D3#CH)77npiyPE;p>=u&pr1N5`iQFNd%GzBoRm=@NXmVFU_{AMAf3% Q3jhEB07*qoM6N<$f+*Wgx&QzG diff --git a/bundles/org.xmind.cathy/dashboard/dashboard.properties b/bundles/org.xmind.cathy/dashboard/dashboard.properties index a4db2ccf7..6e3307213 100644 --- a/bundles/org.xmind.cathy/dashboard/dashboard.properties +++ b/bundles/org.xmind.cathy/dashboard/dashboard.properties @@ -1,6 +1,7 @@ -new=New -open=Open -recent=Recent -cloud=Cloud -preferences=Preferences -back=Workspace +back_tooltip=Close home +new=New +open=Open +recent=Recent +cloud=Cloud +preferences=Preferences +back=Close diff --git a/bundles/org.xmind.cathy/dashboard/dashboard.xml b/bundles/org.xmind.cathy/dashboard/dashboard.xml index 0fabd475a..0955ee516 100644 --- a/bundles/org.xmind.cathy/dashboard/dashboard.xml +++ b/bundles/org.xmind.cathy/dashboard/dashboard.xml @@ -1,54 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.cathy/dashboard/new/structures.properties b/bundles/org.xmind.cathy/dashboard/new/structures.properties index 58158eb9d..bba7b80cf 100644 --- a/bundles/org.xmind.cathy/dashboard/new/structures.properties +++ b/bundles/org.xmind.cathy/dashboard/new/structures.properties @@ -1,16 +1,16 @@ -map=Map -map_uptodown=Balanced Map (Up to down) -map_clockwise=Balanced Map (Clockwise) -map_anticlockwise=Balanced Map (Anticlockwise) -orgchart_uptodown=Org Chart (Up to down) -orgchart_downtoup=Org Chart (Down to up) -treechart_right=Tree Chart (Right) -treechart_left=Tree Chart (Left) -logicchart_right=Logic Chart (Right) -logicchart_left=Logic Chart (Left) -timeline_horizontal=Timeline (Horizontal) -timeline_vertical=Timeline (Vertical) -fishbone_right=Fishbone (Right Headed) -fishbone_left=Fishbone (Left Headed) -matrix_row=Matrix (Row) -matrix_column=Matrix (Column) +map=Map +map_uptodown=Balanced Map (Up to down) +map_clockwise=Balanced Map (Clockwise) +map_anticlockwise=Balanced Map (Anticlockwise) +orgchart_uptodown=Org Chart (Up to down) +orgchart_downtoup=Org Chart (Down to up) +treechart_right=Tree Chart (Right) +treechart_left=Tree Chart (Left) +logicchart_right=Logic Chart (Right) +logicchart_left=Logic Chart (Left) +timeline_horizontal=Timeline (Horizontal) +timeline_vertical=Timeline (Vertical) +fishbone_right=Fishbone (Right Headed) +fishbone_left=Fishbone (Left Headed) +matrix_row=Matrix (Row) +matrix_column=Matrix (Column) diff --git a/bundles/org.xmind.cathy/dashboard/new/structures.xml b/bundles/org.xmind.cathy/dashboard/new/structures.xml index 48c3d8c62..696e4a3e7 100644 --- a/bundles/org.xmind.cathy/dashboard/new/structures.xml +++ b/bundles/org.xmind.cathy/dashboard/new/structures.xml @@ -1,100 +1,100 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.cathy/icons/toolbar/d/dashboard.png b/bundles/org.xmind.cathy/icons/toolbar/d/dashboard.png index 76a1b042b7e22fa8a125ae6535ac241a7a10a5d9..d8503bc2f3a8012cacd5dc5fc55f61018a37554c 100644 GIT binary patch delta 936 zcmV;Z16Tao2g?VLF@J?gL_t(o3GI|YYZE~f$KOsiA;h3*Ot-adNIi%b55+?ji`Oa@ zd#E(E6%oa&P%7dVP>Qr_FJ43xk5=kIA(TSDfQTT7o)ps5v`u4(A(W7Ac71PlH|}m@ zve`yY8Ax_!-kbmX&3|SWpxxRIv>j-P142twP()Q#A$mJG27l$<6I|2h{hWFjdm{*f z+KL)20p*Z0>o*h+L`z-WoXfwp39JIC)T6%V25kSG^?{0_c-Q8mAB;Jto7gv~2AM=i zPqcWX8yF}63IpswU?YvNYU<{p*o$ZR9ZfCjM zlq>s0j42=p{}_}*PUDM%P8K@D=wul|GBAsfmrnlkUh-biyLkR z*3quakbgOZ^vN=We&*mlIyr@R(n(uGIJ!PN9)VCc2W+rEPXrr7GW<^0QFY2g!=!EK$8poU&j~KdnENbE>z&`(x{>r zrX!(#8Q_(4)s2w-X{ujJ)Twn&k<-nLH!-)ReU~Q{c5JDQ$S;h zV}DR%!Ja2MOW#Loy35)?`{&MM+&BSqteL)hP&1U?H@jI3Y0OHPAo6?*ny1irgo`r4*UlCn1D7+g*mkV0000< KMNUMnLSTZqDz`)c delta 951 zcmV;o14#VK2igaaF@KavL_t(o3GJ89YZE~f$KP%?i_}nQ8%r-CQ9%(rNDuxvD4wcR ztTkwA1;zFsu-!I+VUe-A zCSY|y^99(%@C1q%B4&q}j~>N_u0}ddIxO6$f(BQIgYbm;!Qau#+ASbqO_1 z*fg}+P@9Uy_HZLPy+SD}A?=8gh;+orGEFkECK)nw2&y5yCUw%ar{76yhq8d>HA|L7 z7Ox2#e|46+LEVrVAZZhj`2vj%IFLNP1)#ozm;l!6b$^D9w?bL?vZ07eQR@b+EA?ea z>~5{C#evKfXp|w30K`-JyJIwdxf2tCnwSu8B;ITgG|I6&?p0p{gSsJARtL(klB0uh zy6A>v)wu8zSGv1}?!(8#ge-=QVn~Iy;iwv}2R6{Gwm?EjwMYW;-awo#0g}<=jAgxq zE9_i<@qea3x1QxlZAbs8hBaNlF@VpsW`<@xy)8Q-s6*pnk)Puobh%IRjvwF2Ef z8{4X+PXq~k9-HjWIZP_QA(Z7<9Ft@FblqYO1d4+?MJ>8Ww}o_P_N~}gPsBwa3BpfN zN4n)xq@TS?%i+rLIA!*)*bFN+6=I6mB2x8RpnqMjE9%^z_1_r=(6#96qg}baa#)7I zCYha`Et}kxQ$0P-YY7&8mFfB9D=_2dxyb1msm<2LeZ_<`&xteX20 z%?w|<@;Q7$(bv;0&}*P?y*E-eo8625c`*91lkrUrUKkR;8>Z9g^ylEcnx0JsnhG>j ZfxnK$j;t%05B&fD002ovPDHLkV1nc;)29Fc diff --git a/bundles/org.xmind.cathy/icons/toolbar/d/dashboard@2x.png b/bundles/org.xmind.cathy/icons/toolbar/d/dashboard@2x.png index c2d8fcd493bdc27b7cd8ae0319019e98a586eec4..d226fd7cb376682e5a4dd0ea81d400157eb45edd 100644 GIT binary patch delta 2216 zcmV;Z2v_&25y26VF@JkWL_t(|0qvXHZyQAvhsSHjHExu|Nt!yLaovkhDXoN}svv|w zMOB}8;Q?My1yzYEfhyD&p7Vqd7xfX9r~(N=RVw%oP`QaqBwmUt5LB(}rWZjQJHd6` z*j{sfvwPO#&8~Ct?#5I*seR7QoH=vm+cUH4wJSteLINRykbgi(AS4hH2nmD)LINRy z|2=_7H_u?}Te(MTRqa_(uMNpKqp>@&9{t;^?`D7R*0{S8=+sn0o1V`fjx_Xbi>X1O zCzC>_zgVRr;&IYtQSo`fi~&v`9}+Zd?~%{d98tUW*eS54sAd1yj>T%MXvW zop#az>ez|g>mnK*sSFJZLFXYpzaV1w%9Wk{+4sMhiqzUV^r*3GfLbsqGs~2j%NJcF zuip|8-N@8WD!ELpB3>Oz!9)1pCrrfG|))*{<$$%O1B?Xc^TeU0|tMnliAFTdrw165%H z5Q>CG3?&$XqSa`%(glf&Y=<4aN~0qZYUFuIL)RjKt;BT&YQW4*BFoAI z#;L^06@SrpeOC0{yd~nLl7opRq1HCUH7lzD69tl9I;E&Q4&W^oz!;80NSKA(WW6Uw z%bZ~v^X3GL6U^R!Zi~~$#>8+^6EB>+Ar{EnA}wQ$uKt{<$Vm8zSIWeXGMfHa%E6<- z0bQ32Wta_yX^R3|W)o&w9Nd)1XN#vw!qv(PmM5LlOs!9 zfUwM`kFE|TGk=mY^$ca|0A(tCp|EdA3|FMF>vTecfa=>P2!>fjX3~V5O8h=$CV>FV zgSY_Mo-8@_ajX0B&x&~Y!&{;_I3N}`#K{b~VxB#8A{8etTBpzcscg$rDl~gle18Gj z0&|F9I;?{hn0s*lNHb=jtaGZZaJD}X)WfI#R-oECl0R$@Jw8J99HrT1qos zrDZ<1U}Yxf(o#zs5Vu2|2=gR-M^Im(Or4`lt@R*Nsi*_^4AoPhO_*Y|h|F{-@hUI# zv^ZqmXJTRUoY94KNECa!QS1H=sDDRJ5!3-*{!4AK{Cn!c^X1PmFCB3WH6InO9H~YL zW{NTs6l_JpyiI%Nkr4?KCTzwMU0COK6)*?P685Y^;`PiU3GwlbVozScU9Wv%_Ke&fgUJLtjVI0BVG$g_2yNfj~m0z`WzLxTej0#eo4Ie*(is(QP2 zK%G8HSAPk$B4d%;0=5Rzi9GQXvy7dcbtpOh4&6|U(dw>BA}(WvQ@~_EFxzP=?((>b%J7mZ^J)-w4leVh?!zvwR4vao&k*r{Vu*hLs6l` zsx>huMEI1+TX zftV4y;h^((&w&0qHC7hAiO*8Sf9u0^1syKT3FzV>@px8tw2@tMPSB0L3(KumyFpkKwC zQp|-ZFILcbd9d!*u79|Y>T>q>cC~-I_*A>K>Yf8_7YGA{jg!uG?SOD!w&C%(FCVX$ z3=}9JELZaR{BkBO?U_ub<(LmvG8WrSPCL74_sOKCJeDmGuF-!bvhXmguJH(hWmoxkBH5neoZ@%YSEn84{$bcjndC z-rbp@3=dORbbjE%TLP0o)*>@Fds$zPY*`ne%K>083`~_yZ48bj>{VUu@3$T(P!)!% zcQQ#wKgepnSbufmd<}gA1?m=`T*3svTFT}!2P|ZoBQ(Vs+i+ImclojoPy;T(kLdLT z3BCkwN>!KpuX%F39@foYuo>EJa!Q+(shqW(X|RE=*jmT-dez2l_CC}H3v{&;U??on zU)9xPd;Mz1^2olcmpt#CkgD#{+v4fT*fNFXE- q5(o)|1R+8KA%T!UNFXF&C-5I<5L<-J3IW>y0000=Vkbe=#2xJ5@0vUmf!2h0r z(a1B{^G@Np1;csODVH}RPQ$VuH95vNcRuR*rBUNsJ-|;x&B(ckAw22K=k7FMu2~6~oBot|q z0^LMi!xM!8^by}TZ;YNHgPzZIwy#^?nQyW!YtJ9{{JFz}PEKr+mJO4k3MK<02IXev z5>scsDpSjDrVbYi-DKM*o4Yn~RtJ6O|1Of@IA7mCzklnypf)*88#=i`mh$Ywv;ec+ z1tJNF&Z0w#&T4ZfZwcH7nQD=-i&}WEMG-reW@|Iqj??WnB>%bQKtnJ)879(8pm|{I zQi<&Ol260-+97y(6S8`tTz+}ccI)*pO(V6HxTZjTm<&XL@z$#C5rwqp_+;lpNc}#Z z4Y784VSi6;C$q^kgZtoW$`7ly<2U&?B`GDf%{n>(A0{u^TppQ;#1tf+K3AgB_!M0l z*hX90OnUwN1C_ugKSr7SBlhT(W2iPiR=IW3=H`n*PT*LLl-$RfWT*@C-T?MLfbbGC zm?fsK!92RJg%0+#(3kISCwqLF?8hEB*lDN$+J7xl=^&oR`Z3sv0+%m95wYJN~}azDHLgl6bsn2YbHTDH8*hXw$% z)dLPnTolx1x~fA}P5dF!Pg%E*jUk@I3>BFCupMNkq7;0%FsBvFqXH8gJrhX$_VqN= zm4CC_+)SNw4=OBfX@|M=f%3%dp*qZFUgk1c7lQj);?o@aBQjHm2{@I?3%gqA^S1$Y zM(ww-!9gX5l}OY(j%(nW-6HOX|6RdOa1=#ESg3w&=SUp09_1ICZ_>qn0Wjd0?hpk0q>LY?tdsc z2hWggUhY_f706zg#VyLGRf*L!}5X=tFOrA$D9gmKJIYSp2<}rTGtbp4ytW)4d zcsJqt?HPLO!b76=Rx;OBei1~bCIvNCpp{?(NeC!ljx$U?&5z@uJ=)IKQNW@8sz>dQ zZ#h%@IaA4B{$YE(*_S4hfr{8;D}SF%+&@Kz(PehHr#X^FR;`i(v;Qdt6QJ;mB2w3- zT?Z@yi-f)CkobM&*%rEVW-IT{{7A)PqKFN2JnSPz?C&aORK`^FaaQHB_w1eBj#J)Y z@}rR|%Cm=r1r8uQGhSqv$9T`w0ZI^%x-J2Ut>;ZuOC2sm*V_Sgh{sY;@qdgfcUMW* zGoT`7#O~It{!`*#wWkF#_fm`OS?pG&q>IQs&1dMsDHmpRuu4FrE^51+YrMMR2HM40 zKU2f~IX;eA#U5^0@l|X<4a@$QN`fJf9!%%-fdU=JX`V(=HeItT<^7aP3} zdbCL2D)#$%Y{Wq0vySYk$^~NOm{sgipDVnM4d_pU+h&^DjLXi{T-koaZ!P?2;uPn~ zx%K8}g%5ZBs^Y`rjXZ0LL_-va_86q>(JpnmZM8{@Z%9u^42T6WA%8Z+h*%LbVz1_E zx%IN?Ew^7q`+M*A-sQiIzc+I8_ih**eCe67t8W@*-&kOvLf3r*Pmwl}QG2NuSx-CL zjDE2DPAI-Zk@&pfS0iEtiaxy zw4T66MnCN+$p;J`&>>MqM@Oj|(25RHs7x2A93lV$-2>z6UVC3(U*)MwAI}az zLw&_x<=&~(rVCW2`NGhpB72I*?RVI8SjU+XK3Yz82ZC zCP0@05XJ>WL8;Ux;6%b&*Mr{4YpDX&Vd(m5rdiPsvRV$S)i_^4-&BECi%*^E3_wnI zS>}L+Osfb@bAKi_l9e|5Qgwiua!G&0xF^WjsDOJ?*VT>D_TadOuH-M>46QXet%Vh^Z6f+967>&OU_D0AR~|w$OvQvG6ETaj6g;pBajiOgTQ~?4I<+Z TY?RIb015yANkvXXu0mjfHYhc3 diff --git a/bundles/org.xmind.cathy/icons/toolbar/d/export.png b/bundles/org.xmind.cathy/icons/toolbar/d/export.png index aa344887b61591094e499e093f885b77c6b42622..e6e7903555394600e08ab777d159cb49f127c278 100644 GIT binary patch delta 624 zcmV-$0+0Qi1(pSnF@I1=L_t(o3GJ6XOC&)MhI<-!7{tH>1JTUra51{bd3Z>DFb8iwP78Ca^i z>Yb{mt9$)mta_>mR1+v=0v@%>U@+JbLab2qp66Y(+wF6TmVc_5qY431HZPR-`+XJ! z!6w);VR>O^ia>}&rEH_os43Vj%Ig%38z_LJprDDu)Hd*aRyM2?C;-JD39GFFmsdj% z20XuHSSL_TLUhW6C4ZS_vcWXD+_ReMa5zlMYclXze$LYg>e>y|I9{^>95t6Yu&q{$ z!7;@#6v<6k;D0eovTmR`CGq~CMM$vmle0lgQ>+uHZcM1`q9v4zPl=*))8GWbqVHBA zqsG(9B&-2!Tx8*86VUMMhm$Y$Uy*OEKO^V{stVz;f;IgaeRL{fVkx?ve69a@Ue-Z^ z;{-|tGvUp5fCqjth%ofS=Rdn2kDfje7-I?fucuzG*MDs`n@L?bO5^9I*=*zZMK1I9 z57>~yt#BxFb-n+gZ`QE+PT%^xduJ9-uH#gN5K4i^OW34Jiz$mZ4S}XINu-~h%X@6R zH=j}`%hS<_bvm8y+QDO22_m1@POtYDFRd@6f=-}#U{J&KQ#CWozqNuzVe~p5@So#v ziw_xbPHDgiRM$w|Q3OG&b?Cr-R!W1)K$tF@IJ`L_t(o3GJ7?Yui8+z;)MHC?7)xHFQoOG-T`)Fa>uurr6Mb zp-aaQXvkn_AP_Qk>d-%+VB;ZV%+RrO4iv;35 zz0cphI|(}os;innHGxtlAh=cf{rkDxl z7pCY11yK}jfh-eN7Ir00nB+{zB)N|?ve9VN4D1V1;-6GDXxarpa!_D5n3;^iFen?= z3lxCTTf=73fa{5;YeDd^WLPiIjD)F_3Cn(&3fW+qQm@%ebubv@!)w~`T;Hd82lv?z zlx#0;0Glqg4}WB<)e2ynQX2;8MOfg`%aVSeGfLw5L5Ywc(`&{8(an)wpjl%^WuI6^ zxpbE}aegs4L6E5XRhWv#-I{V(4cOQvA(;XaeQp2h&E_W+TI&}W{Xk72+*XiOFX)rG zloIjy@_Kvo@ajosWGG&sTrdhxbC5?U5#Ih0ub&=_o`0duCE358dc9t^*=*j|gRLar zP11KIM3!1Lj9g!fBfP6mAFG2NBV)1@8QIGb#)?nKlWDMyTWb$ho#!Q#3rR2 z4~Iiy;j6>ZNPi^cn4d8n$)2cEYVhUkjP>U(-v%HdKX0#|s|i#S_zx5K3%o$wa}^A3 QvH$=807*qoM6N<$f@(%JRsaA1 diff --git a/bundles/org.xmind.cathy/icons/toolbar/d/export@2x.png b/bundles/org.xmind.cathy/icons/toolbar/d/export@2x.png index ce22fa24340ef1b6bcbc48c41521c8ed78292dfc..ccb6bfd51da744c857989573ba0156ab8d724e69 100644 GIT binary patch delta 1429 zcmV;G1#0?}3bPB4FnLO?PCc-3fYJ1H*<9Y1y zc(-1!cbuinNcQ{g`!zGaot@dJuIIVt2si?cfFs}tI0BA|TQW%ES$*c7%h?+mGtgPJZTk@#|Sq}>^7Zw((v$M0Al@>S2t5hnlK;|8) zpV_QcA*{?SVRC$ni;E=%^$ptcC^H9YYmx${x3sjBd#HARhN0)-gGSlC8vLd&VSKq< z&OKB+Kz&hGe1F8_-;+|8d=+S*MI2>#YJU{++fT|Ve1DMbu@c|G@=;nt$#xqw! zSGlm|`SG^`6l+j^01di=2QbiM8-0+-=_bhVULA3T8bJ``a-~`UN?Wgm?)dB(?&@!lxYCz^>v+nOj}w38aD|} zm@+Eve!i&qyxF)o@;0vj?0D<|#X-Ttf-(vbeM#e^YUIpj2Pj^5^jDrZV0?c}8b9g= z(0_uE?Eob}9jdO=Z%TmBp-^YsxPB2ocjeC8?|*#VDI#?m%??nG+yEjE9ASgx;X}!k z%w@az!p}eMym#T#UuQC}9Z}FOP@_Y32C3@|Biy9Glg5|N%sg>)7`%V(jm`{=El_< z@~i#1U!kjE*OohX;CrV8RR46z+P<3kZ=2TF*RL)wFRPh|Df4uPg*s%yHvh@*2_xgf zDo;P&b>a@FW!?JwFl^P28bPt})txV%-G7bG9?vt?KRt(rhSf>PL(aaTa(2SsN$F34 zTGqiM72iMQSC9AVm!G+^{ljl-7qr15}5k>nR3^lzVsgQf7A3%1@~kF2^FM3fcOn5r*~SMyXhQfFAh-n16OY zpGy!m7;^o_4R3XI^(w4$A8ZTBH7*Qc%WM91)a*3w?VWx&{BrxV=j({es@Ykg8I5k# z6C39@yYKy4r5$?h+CejHcW%A>`uz28-YvAv*h#Og0yQT*YOv-Ohif#-IGuj>CzFh? z@VMo*_YaySulW5R*UtZP_nHxq(SM~?pqwZrCk%-OJ8ih8PCsmV8x>E#o&z2GrB`n@ zN~LV~OS2zbTLId8#P~|2y?5%cWSsEn@w8!Z1O$mT1Y8_0A^U(|(`5p`>c@ZD*e_XL zmsWtvcT4nwQ#Edq@Y4s0X2cVal*&(=jE~EgPW4svZ@u*D`R{D(mwGqU?SB9T7&cv} zjgme}*rW6)n;skI7cskQ^WW~SA$U5CPt$aI`yce;fM$G?9nic36~ARVtnKe-Jj~?f zYPA}EE`E?aBiqQ#52a40v$?gkmHB^7Oge4A6gM^TZy%G^b#ab>Bj5-)0*-(q;0QPZ jj({WJ2si?13H%GP#h-=?Rt_1v00000NkvXXu0mjf@)5^n delta 1267 zcmVMSOme_dT|YlG1shw z1Xj!~yDY4Spf|yb7g6>S4PkYEz^>iaw^H9pO-)y(r@P;z zT&kewy?*c2t9qa5uByO9snimIL?97J1QLNnAQ4Ce5`jb@5r0So`UzzHx6SW1H#e_j zS+t5vs2U4)2*e}Uy_=foV)=UJJe2VRog^( zGTVg7`OVGEow87G(-xy_9jH{18m5|`pN}4@4A4AR3KtsX;a&eHeHG&;CMKeXDg(5m z)9OpV{yk}Q!++O;23o{XR)|LqK#lqJmjP;@xDJ469TFFSP(t@F`WVl?2DtNB(dV#(3Ge06cgWH0cB6b!MSv0*lS8^X{k|k>1J62X!>yYG zx>-{r+x$x$XG=^MWn*LM zD<4opEdZ<+Uhxa*#g9Re0cs%`aDZwHAxt9l0T1|fUt_cRe7{L+ebAZD4tF9#2B0)Ivt#=1IfettXbi3$;*D3s0BX`>_<$~u7D{I1S1#w|sFhKgXplx1C4{vOvAzI2fd>GmLPn0G*hIvruNy)P5%e`hVl*g?fTrGW$;dNU2XlhO&c2)`+#l3$u8{ydA66@;N&S$1F z7a&WejrU);lmY5Oa`nhy;gz47Z1q+RgZpKJ^#VAH`SvCid~#XBNR%V3xCKz3`!?c&o6yDz5UBv_TRABQT?Jo{ep*0 z&Id+tl;~fk)5h^a<76H6sVLO;t9uuoy$S_2w2J~|p_D8b5)F3Ra8I3n*xWWOo_~I~ z4|R$4lDSy@H@KcU_YeROLq+FB0$Xn z9wT6f4-{!8Kp!NU7f(P&T0dVWZ(b* diff --git a/bundles/org.xmind.cathy/icons/toolbar/d/redo.png b/bundles/org.xmind.cathy/icons/toolbar/d/redo.png index 460d5733b90a55cceb1825725fd70b1ff024398f..93bdf9b7dde2349c5d124d147ac0efa5bb93957f 100644 GIT binary patch delta 724 zcmV;_0xSKs2Kfb$F@Lj3L_t(o3GJ25i&9Y-#_yNpC!r*h&cL*Yh9E)(H*SRffP}UM zK^sLBbLG~p|AFpmQIv~X6tkLz;It8ia9U(ELyJiB`-5@(xO#hz%!P~1r1z>3bPqV^ z&N=74=l4G6dC#RNwW$iI3aASFKMMH${s)2}(Cf^YS!XaYmVaKa-wg(X4^yd>MjTtU z-v}s8(}LY@zga96AID;`tE)ni_csDM3(PPSV0VVY;iEtxaD$Ak(pL6SI2^t*nN04& zliN^|nNFvi)oQ)2)oLvwSQo9+=^Q4L$(%SQw^s~GiX{{Z-P7rGw~a>QHI3%acI@~2 zqk6r51lae)8h?KU6p##x`~d*6F_G7B791TKUkqs ztyVLwR_i4^c!*>=;vDIFyx>RCJ(GLE?K^?Hv z*5cZ6&Vz2^{|k?9(MI`vzUp?nyHi2f0<^{B@l71%aye2%8*7R{2@PO>!UmsFSUaQ9 z$m#R>K4mf)d7r9{rFBW*bUMvOqfy-@)9SFQfU3a1q`)tARX_%;nc6x400007Lr*SG94OhJ zot<^w-`~GqTU)a|@uzt^6`($!PxN}d7C{i+ZEtTs*Nm?3;#7c={kge0wz#-xYBU;e zHa9n4_4(AaoJi7xH7nS_-RfUP5@)u1Fv4u6}?CRnXj(PT0)r_(tA0Y8Fevsqp$l^&q@a(sN;95^t>Ml(>fArC5i z+3j|lP&{L}V(jMTrgMFL-L%{7pQ6!dd8|wS4r$8Kt*xyWq9`u={r<5*l0W3FD9iG* zN~Pjg1Cq|F28tY$kZ-R&9uJ~yVieYKzFMuulF1~F@_&oN!^3Y=2bxGE790+TI5RUd z;ETYP%VmcCIUuJE$y2EmN3s1pI5)PwJ5fYda7Ke2&Fp^+%8-Z?{<{li?_uJbLHJ-rinS z(P^EvguV%YGO4I7R!(lJQ9nRE4?`kH_nwP{`hF zHf>;2L>h3ktSiOJ+1c3u!-`z*teR1Bh|qpVp*-ND2gZCP5|Q-+8FgP1P~;z?E}WuZ z{?OkJ^wE`3j`Zp^KS~tGc*Q&Ldh%hMPh-SV@o|c?hdu z=|hN>SojnnMd}njh1f+=!A4Lb7U6Ve?*6+q7cVzS=^dOqJNxg>cmM8Pkf^u{2MP!N zmjfls<8F2CPbv7`w9FB0$$j4rulEMldA`2vcV@;6`M$do%YWX^;*cl^h@7Ktx2wr^ zyREtPtAMJ*$NlZj9W4Uuyiz$s1|q&0ERcIV4sXeFj7!H<>FA@;s08I@fjz{ywY7sr zoKi?3rS)RT%Y_Hf4m2>?<+V;4GAZw?#aZiR22H@=(O*Rc4VrLP(z9X`nL)E0O_zs{`iaG-HZ9AM zF@s{w(fJBOQ(L|GH0dEWgW_#Qi-r6aTRiPhBs=2In13CcLE|$j75Sy;^?I|bu;QfE zigd|w$Tcw%%>f$D)N%~liUG3A#&~g%t)CpVgQ5^aBFx%qDJVKeAyA~R@gBd;Z}O$LBlczJvWQBvKPbFBfg`CBvSFGr&~sEtPpX>FR$i*MW*sE(bLp?kt`f2 e94H)62Yvt`wCyEMK_IOF0000dI`%CpqzsYr46rhy zN{9i8y%HPmfYgBp=~$^!8F&XotAx~_lS@p1;7f)MwI#=wyR-ev7sm!6Y_SSh1^$-; z4(D;lb`1$HK`p zSfKjYP&AQXKvXriDM!Vm4|%9 z1H>pF;B8=idVf{i7L&d%mqj-MQA!rx(m+1tU>R(;+Xopn-U-->VlslEw!|qdfT5t( zZStug`p!9_5 z6!N^{$SnLY!&}2#{;9e#qQ{x)f)Fs*eaGHQi4e z_G5v%uKV*H#~mDrFVpFz2RHIz*guZMu5ZdSv7L-YR1PXydpb#hovVRiT%aQ%#r@wx(xVf2+ zudnZ>@_+OB&nff9wy%EtG{h{&duR9GfA{;JoXeDaPEJm0)_?hY9>zQkiw_Pb&Uo0pT+QuPp=U>DEX@eok60p%+Y1=>YKXNRRE z0$}H1b!$_*UL@Q};15okw<61~q1sxx-CiWi^Ihgf4nTOA6^Kr{(%EBaTvt@V<^m`s z7*9wdPk(;R%h|zXac?)*)GWV;u2dcy0GGeWQ`e4Ladn2HM~`Y|oESM&c!28CU;|X= z;qLx_W&J%hTZd|c)C<>|MF2_wLkikl&H)x$DQ$QceHWcNNQd74ZrX)MLkw`EFNmFb zx>szcx}X;gNjsaR`&9SFJ#tzj&oEVQ?Ib^8?2Dt8&3Xry^mVPQFEpiYD7Q!4C#2jt($tbe{ zWj)xt)mLgE2}%htUbIu1sYccMQm2gbHzw&eq35|>cKB5!%5eBhd72aC7h_DrDBDL;u;a^I`qzG>z6Mom``U|$}PwJA29@={3)|e_AP$|?cOR$vK zNevb!D8&I!4F~-w;bwH^rj%(j-;lL8vw!wQZ}}35SPi7r6Ru*iK31o{wOPGs9zLlD z{ri>qIyAt;hFSP%^yXRmi@ScysF6ec zcP(Sy!f~N9cMOEkJyk2>*2RZh%#S24A(z3>>KONZWCKc`{tl#7>F(vNpwj{G_<#7g z*P7%jW>C|^ujNlfWuw-=%m%d0R#CS7j=fDxH=hdd`qx0W>^2HblIcJZEQB&zik$>$ z^~fy@t&i2|U~SYn7i7a;!u)nh{tm_daoSi%T&Nk#^%1UWV_5C18~@}W+lff7{`M19L=;i~e6|w;Tj=HhzRucqEi6E<| zlE}PtZ3XeRm{gv&wroHxK&ywBsqXNH)6=$lZRPjHXG}F!)!p??rRl5 z+sOZ?Up}C00$${*S6t|icnTr3^?@ra$;3!%^*$Dfa^wTbg?RnayRUGzx_{Ov?)pwh z-tjPg3n_Pbx1e0dmjQ3iSNtd=P(i0SjIJ<~oH$3BblS`)FkMLPI=)$ojl8n~H3(}P zf}OoWoxXgzbG{b1#en&@NYOep8_;z-umzsJe7VkbySvqt& zotzw=|2@aQ*TglxdezTAeZ_g3#t&Xs{~SgiIpJ=P92Z##6as}nAt_J@6as}nAy5bu i0);>!Pzbz51pWh~U>o=(@H0#3jQH~~`vUo5hpo}PYxet!P(`ue(~<$pgpInm6mZC6)UvdzE4 z!^1!4=jSidIJ7>o=nyau4i0vv(`hOFcsw5U1@!*@ev|*<;bD4rclR>@%?i~7C}ySx z6Qf@)mm3JFN;DJI6SBX*kE<;^)UT<7`V4V^y0^DSsOs&;dK_jz!z>+P$41G)V3tTwK?;gdO~KAX+5%~W%s8jK-q zxuE6&id#XOJw5|$8{4Df98j|W#hsNq7_9EJ5smes=96u?YN)y=1M2SX?qClpGoV!i zBmm+gFhYtY<21=!lvOd|$v+rWlXa*zuy-~*p~C{d*ng;3Jhc%sKRQ~)@@GvfLt+W2 z!N!?tw)i)jq49u9$ACgGlp%;uc1Wq0+IKJvF;lb5&|jCA9dPv1M9$QZ@pnI2-?C%@ z`qn)r=`vjX7uhDZs%@JbZDQm8nvV0` zLz^o5qOdn%qF5Y9AzmMEn4l|%yXRz`9MXANr`Ly^t8*@=2 zR_b+ayZHQ)??SDnjRUQL)5T?e$>TfaWHKpzWM;ASL1K&JxAn81p`;m5fZ-| z90NQ)!tn$YdN_XfVNS%WCqej`r&NQXVQ`>L^F#WnQ^tT{r!AFHancgMou=lLab`d* zW`764Qeq%dmjk1&)uGuKzpXR_np)WP^>u1!Qrz+JaZ;RBPkLpw?4?bNtiBQu~ZhhQmbFC@WH!YK83!R-&wr`m7(RLL#O zfyR~KlL4)v3Zyej8b$?1gny%RfEpUs@vH+F!-rU^C!>#rCeE#;< zWw_p~Dl`vJ@itTXyQQj1Q|thU+yp85Non3kj2Y0%#k1ugnVT{Ys;r|AdP)wHk0W8J z^inmDx;Gp8AhjL!Ge#LpvI(`J#^eSq0!?OUSgQP8EEeiNe%;>QwkU7=(5I)TQZ*95 zM2#hf8=Qa>Z~{)i2{-{K-~^n26L11fzzKYO0{;QR0#~`If$vrT0000~u@QnKE(_gNx+;Z2 zDI`KR$wKJTf8c*`Q|zuS5*3nFp!5fHk#>=yCTR+>G!ha_bd(T3X2$7zLrqm?j5-s@ z!hy-$oO9=#=f3xz!$`>J8YwVR;C?C)3Wc0^LB<#vbai$0v40>4AtPh9VsWj3-sj57 z$`er(pEsLLUT-Y5_jQ9tA`#}`;NT_8vWxTc^L!?gQOl#-rVBJ24v+8c?FB6s%hcT5 z9M3R@o}`Y&4IO!HZS7G$pMUFgI%m2e=>j^k81Rp2m>A2;%U(rM-ptO<@(zciBStox zl_g1{VP%ua^nVNYw~dXB-^1i-f2Si!yF+V?qIn9)XC9A-$ChhNBPc9VsZ_}6>1jij zzXgz;ur`NO1^?Zi(apnv9v8wb)h&pJUo;E)WF4zjg6UD z*odN#CT{dv_Uh`2LBZ|!q*8GX3`%3{?Ci);H=Rf%9^e?b&1N&p0agYqwwD3$CjikS z;u@zudVikbV_24yN+kE>pm8}*gAZMZhd=X{4ANO*Xu8!=1(a3 z88MKhcK^K?CzDAQYWmjK*RA&gXaq4*V5Go*1^xm#L1033!!Ei20000|H;7C*47gvka5!ty1u^ttXi#poMy~HEPvBrFli5vUQrZ-h{I1B zYncDUjLNdiuB@!QA&`MUzz~oGd?H4p(Wn_9KiKVdhtKCT3?u;^o6(Jpjd}Qga=YD5 z0%^uXvshc)ea8Ak?uQjIj}>(P%K`av4Lh5)1|pwzs$Y4~%sD(WR@^ z)z!C%{nGFE^H!^MNE?VC6iSOwIwU16t(h#6uPg*k;XU^Zw=Kr6dT#yp87O zZmSh-1b+w20-)bCp;H;@(x}Rh*pbuebRK2s`0VUVY_(bnt7Jpv2y@2(d{8J9M6ugd z=4dm}wOJiU>v(LSg9TEl6dkaANTJuL)#Sl@>Jy2?1%TD+*aS7IwP4lwQ?INx{uneB{$83P70@EbF}WAMZQV$00YyL&Py`eKMSnmMPy`eKML-cy1QY>9 z;D1cOY2~q>oSZl|Ha0$7SXlVo%Kg;$&7r@sQo6UdH>bV5{eCPKd&5foO4S!j0`2JN zDBIuP@AP`T)u{$xwda-t+SAi>3roGdq@=`KT3TvplXTu>y3WhYR93_YJ07~bBW&S=!a;K`Q%I$JlqFc`eHsd{yJD-oTv$J2OW;z^}vqEWs z%_z{g^SKA-lYbNK<$0v-=Vi*sqw_gDJZuF>PeDP!h5cAvUA5)q<&B_hsoieRV&7mQ z!q8}cV`Jl1YinyvMt_aIDRbWR5atE+p6gOyO)ja;FEsX*J>+TMYk`vCURlbf3>Wi^lmfZAYBov^Pp4Gj%Tb8~aj zA_4Q(UW!?!L*YfKPp7Dsc&x9ZPm2N!#h|Tup?^^5J&`9vnyR6Ti;F&J$lA`%P7Rj2 z6Pja(r)M0gjZH}2h_rZ~O6u$A)B1XdRULbKd!_aD^^fM~=YuR~_GP+;4h;?c1(*|l zzdwLaOlVWefyFf#>Ps~~)#A7mZ3xM>M4D2hnGd_|0_1m@mT{S?p<)1Z3{6ctC_6tp zI~xVq2UAm1Uf8vl;G`}Mp9qN&fq;dHurby=Iy%zwusP6}h^XOgc~O@Vbz*pDU}+36kv%3pWZ*pQ7Dv3ILF4B}dUj^6-=9_&ZIg5|%>z#H0EgMT05 zcu3-)Hi-|*GmQYM_68bo~aK_2WTnE zlTn}?^uWNt0ib*i$FU-yJ_Ca{DSxi9v9T2td4e<3L`g9jl$QdrNkCP_lV|r+`t*ex?Bv1}W zI4gMY2Sx_CzP?T`uALQV4k>O!BXCsEPQR?f=8OdPMgXx4ofX7)M#}qqzCx6bqO2Ak z2`$|Vg(3j@laV&Aql~42rhhX)?35}2&Mv|w)`iKS?OdCjoRs!=NXstybYQY9?BwgP zlO9ozu_q2wBKQsKTahP2z7RmWySwwDiMP0Cr-m|)McBokmA~ol@0W70EGFxPSn>dP zmxm*~sF~QxM&R+k8W|aRBnB!=-guzU&Q}2REi88zK*j)+`_C^BdVl$3LDawJMlX3D z;lWORi~+fD;uOVlU#zaK9)c6f2uy-aI)~KLwsN|wtE(6=?;}p-pQD!Xhq7M=2M2eo z+-J-74GxHZ(7lc2USZizs*WiFihv@Z2q*%IfFhs>C<2OrBA^H;0*b(mAn+fn4SRo) T-)YPM0000{DyNV*p?uB3iGoBAgj5+WB>q)t>CrN8eby}^0 zSY1_J)m^{(>N`{`Ng@dXf`A|(2nYg#fFK|U2m*qDARq_`0)K*lAn=L_nDjjNWHM>+ z`FuZZZf<_n^LwVhn=!qhr|a?Yam&!qP|wZHO_QG9OYL2B33PID(s_G(`=O?$#-%m^ zy|wEO=-AlUo2#p<-un7_yW8#7-TSF6pjqt(E!(lhTVt_UdrM1;$!@nxxYqLV1$mY( zfRgbU85wzJG=CbKT3cI9NClZ(F$O6*(3J7{*=Dm)*=D%bjr6hA07JKWgV(99FaZ+|^< z_Oz9iiPce_eyzMOTRFW?`Zc?sTrs#;R(J{TSbv=sIadkY+1a`1>gu{ANr446l2vDV zlO{*kEU|0Wu9iQfzr*1$1Ofp^XJ_Xr-sP4(i)YSVLYJ17PAV!Y{x~~33!R^zYqs?m zw93j#@+jW2GVh$LgtC|Scs!Awo*r*77_5T7XvJ29QRcpu^5e-pgNI@7@9+0QmvTS8 z;(u=C8C1%#jpb7%M8;^HDfPCHT%{bd&j3*toCL7s!l z<+>AfWnbzH18nPzZV|yn z(&V5-7eE<2GFEVNJO}_{Da+29RDW|EzMSFcE~6f%1;V!Xs}53t8*~Mf=EEW@92$q< zkUu!GLNpeJi*#pXQ&K6b0MsY&J1qb&)gg2Tl-@YqSgFn+b;IuNt}LBQcTzQj3fC%$ z=uDIUkJ2Sjg29Xxz9;#ptd_{Z$F}}XqEq@fxVX5e$(GkNQc{DWY)?g2n}5psOl24( zdkW}1Awggehr#+MQy(66x(51~2_v?z05}7Mnk?b7Gpdr8Yiny?SRL>D-fHrG7|-#s zwd>*F-!n?koiTU~fAf5U+xr8?DFM_3^yMLp(>}RePaQko{?8UD{u8AXAK-okNK#u~eC0dUl^~p zA0Qfrhld*n2M5bvEd()fK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|zC>RKV{{Yy4{oIi< R1jGOU002ovPDHLkV1h?c@0F@NMqL_t(o3GJ54PZLoT#?P6yR0;^CEwnX?F=|};h@w>!O?>PW zO-vC@)P=YNbz$Plm5=y}F(ztU7&peG3${KME(ja{1s94UrMB{}Ep6v|&h6aEP%+L7 zEPIp7xzBTd^WATz0Mtuefw}@Kq5!T)7D^(7z%^G#pJ}Did4CW9dV}xf*!^{v5RrPz zFDn8nA+L-M>l!AC(Ws>Ir_-S6Vr1;Wx_t_E&E>D>05S0W{@SN%%^fx^lGiN@lp*5;DLj~% zi$}q;umH{D8Gpf7KOgJBioXGxexv~j7C}UQhk~1g=7GkEpPBK;8#tdKJV>80y#naGJdy&+8Q zYLe+_4IJOr1Qi`{@YPQ-(-A^mtLYWc%ETzm;p}8bib}|VFT)jt#B?MiJ-K=!D{d2H z@9t){CV!^Pcw&119-a;3>P%L!e=Foqrl-=#xtyTd1~nn+x~C)U;3<`%HIoy!dc%0S zyQ-u-n14XcNbQq50&tHk(Mqao#R8NXd{FjaFisEb1lHD5al$AkCdkQf5PWofZP`hJ z3}GL6a#3MWG9gJ@9X8r;KIP%s>#UdzwPD5QgVyXXKpjTXkJg*t*+qG3I<^#z4SspT zkiSB0D|2%D?YnofUHj+gkt5YL2JGHg4&Hq3x){n$Kj#Vh z4u4;--LtIzfg8fhm6N1WDN!sGWL+p0W#qAZJ}>KUBl4J<=g5`EIEOVK_y1RHDauJc z-oWxw$<(#-oZnAZ$%WP9mq@j(u{!$Ce8%)&!8Yh$JJo;%O8Hez8CR`Sr2mxYN6Bgy zwb_1j4{99DimGp%g5kau%c{D4w8bl3gMV5NH`@lhQc)cxA4XY04LXeOLDfMFXF!<1 zG^g6NQEhV?-GdtH$!j*+rbijv7&Bii)pts0talBnd}+N_)0Y+~si>vzlGA(-9PJ+( z8hT$Ymk&AGq?GY`KlJqU9Cov}zNfB0U4a!);17@l6IbXaB&PrX002ovPDHLkU;%>I Caqa*B delta 1001 zcmVfk<< z);gM@=S<=U_SxJ>UCWs_-{X@A9>vQ512u*hxaJg+)|CYM2c&L5Cb`B5))TH_%%fSb zCY$46hPD0vLw~3wWLDM_-=4SDy8*@f6;~|CxKL6H*88`A&LE-&{ivi4MrxBk?6V-n`9d}1K-+!P50lqX*_92>F@6D49uo=+t0rG= zSRI2(NX&(Z5)1&-O)!?z{6T+^^|qs0b`h}HCQJ45F&{i02x1s)Vi@R{Whw$gow%?I zSVy4wkbmre43OB zCL{T_HthX%1d8IE18)@oDoKz%hZp&9M@T4W+J8!trOGjbq@^|$X$Q}Sq4&rlH*8q) zDSYqEC}tgHy$XEH*w~6us;ZiH^Hf9XH9g#-5Gb~1W@fB@!S{S;r@f4J1GG1!ln2zAupSGnjIZu`XWlU{uc4YH+_ z;z4Z?QdGvPNGznG=(R8{w0zZzg)JI1cQ~q*YfBaL;0Y}MGXEb`o=CscegSg8HXJRH zW75iPZf(hmir*~5K*k|~+hcBlc3bc0!D27mtg31#CM1e0}X zX$jv=HCgD-Nnf7fWNmKE^z`%vMN!@wh7ryUI%p6iCf-nYclSpJ%PUJN3RD#M7Yh6W Xf)p!r<8$-E00000NkvXXu0mjfmEp(K diff --git a/bundles/org.xmind.cathy/icons/toolbar/e/dashboard@2x.png b/bundles/org.xmind.cathy/icons/toolbar/e/dashboard@2x.png index 236335a76e9d7c80660b0a6fe4988bc61be9025e..f90b0a77dfd36949d85523aebdc1250484965c97 100644 GIT binary patch delta 2606 zcmV+}3eol36T}pdF@OF^L_t(|0qvS?ZyZ+@$Ir|@cvG+!>7ZCB9er;4Eyqk8FAel@SA&wPYn0q5E}b|rG4lH3hSfrj z-q4bxSFu-4Elgx0=?P9)F3LF6abtl@+g0lM)tOI_ZGT-^KQzYOplY{I$J{)bmVI{q z#qo2hZ;L;w*HeqXtkLiS(=v_8yQ9M@3@XIFiNmogR{0!(rsC)bLCxn2vzHnDm$y6G z6-Hk2+>U-WZMSF0F`Ume`tGpnlVK0|-;U>pSZG|OA}6J^lJ6}GmHX^`odd{>L6?5RRsm@~X*vNChStRxqrQWtPC z*hF!Iy5{Dn`^F7Qt*@h2K@$sl>)h9BOD9>0svRm;|CF+cEW?gu|HLKRGlc@?D|v>Q zG$+?bhFtk*Wn$-qo7yN*=i+U8^_fu`IAGAJ=YQwv4!3P~bSQ<2lKF(zhleOt+E5n( z>O~tY_#1`;iAPfQM4-FzjydG7q7mMJVBNv+JEJvBln873Z|Q2)Ro zhJX6(LF!swrX)j^g5`~(mN`B#rnbBbuxETY73#rE7?W#*1Mba3O&mY~LhqTkmk2N) zzE|H%KnR8HU*Qq%}_@|`L$7@|$4bppdSk=ICZEz*S&p~u`SD5=?6<|P1Ak;C z68GSVA_}N{`C3bf@Hzy7O4U;ohp75aN= zE7PW~fqaLG=8FRLCv3X%bnkf83zgc@c30Cfg}N}OFK@Fl3xj=pYd`^#$_>NaGxKy& zEpxt`H(3NUERN%>)L(pOgnD@S<9~6>RVc*m?zsqB6 zJ3ZW<+=qRew-(+WY=@P4s3l4b9jJo2!ph{k`6@3#50Z~XYO_qe%LTf?Fn=GpFQcX% z1nvv}U{~O?{WC-T){hq`-&w zow>_c>gu)Yu!iPO|0vNDFEdnD>ZU-gigqZgpz@yD7p_u6-9vw}^6x)j&xAU#YP~&7 z`>8TuuF{3m!wRO?&Xa{NMSnb49Dad`0>q+^_^>!0`e=rJ{>(7-=2t1r-|0S)Vl4L` zqVoM&LaxXeV}w;CmtBuH`s~aJ$J)BIG}NzdKzL&=kg$KHHaDp+&&&Mu5HIuUw`md! zi{gjqR&b3hYgN(Q#~=S*q9-rjqI|ZS%Bww=QFo3C zO`*19ohtDo3-0DBT~-_{4k!~a&p%lU6X^+fQEbrqW8gPiPTrg0$FU(+>Ke821$9>q zdb3g)CSDho+Bs*=z1cB8C@wUhhUMHeEla`i14)&)Fd_T&k!gAqck?C+E&_^N5WiyK z2M@%ePKy5mo%~pa&VL-8rtHccJIzoLY3sl9VUaU(m%h8Tp#g16ny+TcTU(hD_AHe* zwPDX>n3PC-_2@vM2DX4#;r=~T`;FRbfO93^DDjiJ2r9xRK#ZZ(G58x zcjOR82@UAcDFdle?|`Si;HZ5-?5pgFV4R-@qb$+i#<~INwKKM$noZ`hvOE?FmGcB4fjfKmWtSze6s_X^@{XaAentMdXa!E4_E;g$5L9%$=Kf z^Tb1kyVHsEgE-*NpBsNeQUoMFJgE;_e~jPv;s6#!1NMC7)LtN6O~@sfA99xVFl^}m z1)~4|`)wq5{eOk(6a@}c17Fl5exvs4QCwg$2HM1LG@ifzPWk!c{#QSApgScZ6Gluu zU+RK@gJU92Vx&#_%K2W|NP&t1cbe?X?5ul(;UKyB1mm&b)lG=)_}EymS)DiYU3EL| zvNBSj&E$IZ>Q$PUn5Y{XROYp7*BSz?J3s`LkpdOf1b@NE@|E^u$BxyXI&MO|+||v9 zBLGzSQU|-oB~qX=R{jJ;BEpYIfmVUh6USU- z@?N_JgSH?%1>UDb??U+c)bv9|L?u$79vrAll*JPjUs*o)gO%;U;}HPo)$bE0QlPT; zdHbL!4S$gQfPK(B1u`)BO3l7@j2T?wLB&VOI$EH5W=%R(7b(z2`Ko2j>XPN{w>5icok5hsxn4kH zFIIJ;*gAb$RTb*XkJhG&skJN@4xJ8h=B^Y1BXD`bZTj$_pw=&B-@$`Kb=n z319X`^siAYREWM}1(0t%sfxlzs!)JbFad^r020Vz{gcLT zRk0DAM5|CeA*C|*8!C_Cpy1O0D0NoxQ71)#V|9u}z4&_pH8P+K&$2BmVVb4~sDed9 z(0`Pqz8)B96QIfpV6mvwK7QSY@2-k(;Ynmb8RVsR-hKBo{e6A<=Nye^H8V5gHp;#T zivmbe=ho2d_3PTJZ=V zkP*lTWCZ^233yw11fxHkK1yNuqcAiF5vT8aSG~ZSoIX4D##W7cO9GvoH2$S>={I35 z_*#C)cF!;7i40L#sZp(b%lP^HYtIgjeq(ad3%45BEe8}ZFP5kN=K20(h2cT+avUO} zWT3DnFjT!(W`9dpPVC%w*oA7_zC;0i(|FY5`?=S54fZ^9WpZRWE$~|kr~p}<{ww)3 z(X)F81B}A+n55x6V#8sIQ14U3rF%h?~%II8!Hs9RjwU*V*j33zwQNT zK;1GxTfx-etT;uaF%)B{GQY&@K%~@j<%&D0(<7eZx zU3B~|_T6#UbujN8h?L2|01_W25?lD1M8&M;i>&Gb)xPW(d!&c~0-}7pVgdU8oVMw< z<<)+3(?&2QDhtolLV@EKayA>&KZ0H02T;5A!9-9opUC&DD>ELIsMX&VUw7HrRD~)` zFGmvqqkn5A)P)2au2!h}-U8L;7b#d?vr1LvqLxR6T?6D7@_E&++nzf?KdG#rh-T9i zsxZkn6Zv6=$w@(|Z&s^RTev}&UKpX_KA(=i^dImeOl{q$q%MCIcJ=cHRE_#zRZ3r? zPWC-hL%lT8rYKZkE==)mZYH2ERi+LY0yPW=Fn=$;a6cVAu#FCm7U_3Cc!0vin~_o@ z<;4#H>U7so^aZH+hf`|j)zpE;FmoO&vtNcQ19t!k%Xt>Kxivq}NV=giQGs z1uJW^n`1{unOgXqA$hP~$k(Cw;Z$fN%tmF3lvtSoEAxWD+>R^(r1r6WJ@o472goc& zP=5s=bO?~q({|`;um*+;HwEUg0~RJ1MzA6ae`2hc ze*5BxKn+=`V2S+5M!mt8#Fo|j;ZmpzvoPEjt!g~l2tuT;fOm6&`RzRQIQ8pKA z;d9xi#*6gp?=#dg|ElB%frM$VQ(rCe`G4ig5ySw$+o|g}iDB{qJU?_#9ZVgZ?9M!e zF9=LNGAc~iRv!!X@W+but5YMqQQhL>6?S->SEKz$t>4#6p6@+)kvG9Kpmr5#9ZXRs zHjoITT7`N3`Dg=jW~%aDe+Zm|a#6OmhsS&Am*2ZzHmYz9GdtR()S`ZVm>(p5QGcZX zwQE2D^8yb51IZ6X(_Hok3j)3i^VoqR=X93P7D@a2G%NKN-({$*RKrV$V3#K*_@!nJ zvm*tl8XMwEEGbO9HNrqV&u3*hZ;Nmzez%FKdj8~nbnFq{fB-<(O7&I79Y*%%yQ}oA zpUsg!$o=)^aW9F+_qZcKQU|MAYW@EWBij|B$_~Qar1*kn8r!ez%XHBn0x?#BLzgyO8 zY=U@D_#lbJLy|uLa_kAE#DJQ>`!5AJSVw@=;%vwpPmSU?= zTniQg$U<=+(9w?<>Eyu@h2_=IRHI*@dgvF6m=SwIDKVhAynl%*VU^@?ZKH!KmR3S9 zm;dUcyZDc4Ou5wuwH1QvYh5=FeiLw+4f-G>v~GV74=?ew&V9u!u7+`Zc;bkaW0u&_ zaRMnZpwnl@$~m8&GJiMLmc#2e<#)OHU~Sp={V&eGJobCUiZxQ#Nwvt=!7D(N!H?@( zpEFT8Qlqu1OtpF+wR)e~pN#(ju^^_9&!XXV{t6dz)? z%@Q%qhqSxw*8ctb@91Xs$Mu~lC|7}~fqc!wwfd?q)olJIM8;1 zxPV&un%52p`bRyjqxaLcdc9dTRiJ=yyHuK)iFb6}d>Y%J7v23w_wH>hmg`RL)w1DT zW~K_XlUT1_y?;t$V`D9=HY#&!YKk@j+OmTbGE)Vrs%ZqH(^tz69Xix{=ukKg<5uYa zD!%5yZgNT$sE$>^sYQM(U#GQVlBv!x>lO|drUmUT33|`8Y^p%(zyP8hWfM3H2E|%O zsxmwQ?cG5VVuT+7?aG)|(7LQYXv3wna=YM*-Jj6H}z{UAn#7PyXu6^-3 zs7eDQ7q9~@Rv-g|FKTwm(I+01svKO^*9U{Vv{Jf2?Wh{TC?o~oLUci>!qsY-oIwHG zc|e+{b<(n_0(C*Sey4*~;A+uM`ccJhWIMe<0`*b_x>3BMNLH6B)3r@&Xp2rn;he9a zu@+07Du1>`n{H(#`f?<(AfdEIwQbZn*He|ky1w+G{cO}e;rvt;s>*9rl#Iz4cxZj7 z6TYsEXy2q*s1WtlDj?g3UZ!PJRVY9TOn_k@fE2P?ci<+p|5*)N*LUjxrnI$I`%zn0 zH-(FI6>0}0Dr0{` zu#_~v6&Nj3pkfuUT4Y*3WOd`-b@jV=ks442dHEl2zx|ovp`qyieQ7hOQmGV`>beMv z1W1|}<kA7NzV}=VkP*lTWCSt-8G(#IMj#_lN8o?igWz5i&nQ*^ O0000^;gF@K&(L_t(o3GJ7^YZO5g$7k=3yMthJAflZX0b^lhDY+tLqFd`~-fgGV%c1XcVSwEqQBB#z09Xt_t|PGK|j! zNT2M@`Fbl7cz-U>m2UzsP%6fkJY%7%kaRko$wI{ELZH4}ZxXqB^8?M8hd{IdhR=nl zDyg&iv1a=96{1U$3`ZfN!`s)1QC4XrPU0$Hjh1$@Xic~CPA-1{# zs-h^mp~CRf>cQ`=1)_`qw^c@W8pa>E6xHd1Kk{1RD6OYF@KgxL_t(o3GJ7^ixWW<$7eQ25;?BYU^*2+(ZQu1Ej_><2@3PrsvopCBn;jV5%bPbd zpZU%YvPu=DP@qsC7X`HID1*V^rZMK_WHPB`^(mD~-BzphB!4UKpS1V;{ctoInJ9`D zDlLFxu)SW-42Q#?l)sxNNZ>jcl&sh5OVf#x<6;|)#%8rzeUK-tGw77WC}pUkh=t36 znXQz|DsNaXP}*7ITdY%V!NnSkDg$30(Ab?X7Z zs>UqNZ9K+45s76u%8_!RJN|I?mBHomDqf&~aspd{K!3}+a_V6G{nGB?wH0X#O%32;N?N`s3aLQA$9LRZ8bf_z^Sre|??gc87L{?E)6sRk)PY<{F9P^W8+u^_2 z+f(g!TYsPLhTO?$J=q9?`(GZNelFv#vR2y%n0T(z(EJ-V?%TYO`l0_)0>_}UqA>KWbobr<{tK6nyX4$}ME_*G_+2Pa dDDWQ?_zSJIm3X`$CAa_p002ovPDHLkV1k5PVwC^@ diff --git a/bundles/org.xmind.cathy/icons/toolbar/e/export@2x.png b/bundles/org.xmind.cathy/icons/toolbar/e/export@2x.png index c17ef3f1e605bea45e43efcc54181b453159368c..322c213b92d5a0ad45e554f5f8a1856a4666c6da 100644 GIT binary patch delta 1838 zcmV+}2hsR}4ap9WFn93t5(Zo~G&kosYILLb+W2@Z`yp?{9eiC+fn53kx@I-prcKrf|)2tCb!% z+XtH0`Sa(qxw*L&8T*4l$2e5<10pjI9XgbhN~J{jOV2-N?fJ+p z?OPjT`zmxZ-XL%PAV4*aZVzKC(w^-lCmJ#k`SzWsv& z#rn4_gbCZ}0!+qG)57m`OLCmOJ@5!|*KlcX(iq&mZG>c{1s&#<`h${6<)6<=Y z;r54>!Vh2@@H>yY18-2E0L6DpyWrOH-BaT%>{dKrZDHuk7-`&Mq_(c19ASVuND2;6 z-P2>i%p$m`yS7VT?c>Jt`|Gf-&5o!3UAhJNQh(xFxRqfwTcv^4!UQM_3vGlE6oJ}=j?sbkG_6u@`BFpr`Vxi5Vxp+J` zvwxBC)(8C{mLNd!s)tzy0ndE-27m z4@5Yyoi4(JwVJW^i^%G>dFA9OkJOVrk3Bq^RLUP6p1t~MsB<+4P%an?gU$;ztbf&c zz-Ga|-Nxg{u&QND`s_&ZJ17aRq%xG$5AGcu8m0jE|W=(Mom6H1Yu|4ZctH;-G-^IB)eeKM|H~o&>D=sY19tFn`nY^p$?)v5{)2R^IpTt>w$(vsd4}e)g%et>~TI zg97!}>u+;iKcKobw8iIsv|dK5N%+ZMW;D`1;{Tw5~fsAi_46?>5rgYfI(I&;zvPdz_&JMt_S{TaEhs z$46kcRldG-DVdp>(KN3gRBg%iG)ezjxs#>IR|lS%IQ`wJQiCx?*)Txe z)A>MhxLlyO3I!r<1m;`3C4ZC%UHVe1l{)A1hSi2_t&ybvtlk;Ql6S73efr#uwxD7h zL4o=}xL}trc}6kLZ}*o7a2n%25Ndxszh86ZZlk%}SSnYGJum%vP!9q$|03$}-pR#d za*dN18&4nF0a~Gx%}mUV@F>NabDVKsKWrY0FCxD%-_QLP$pgh z!|8mAO|-+OV4-usMxz_bjZY?CxzUpMs3(hqaX zGc5Fs4HQs#hRR>Rz5e}`E1wnpr-}Wp-@$yX-}o382}A;sKqn*+2}A;sKqL?eL;{gO cBoLawf6Ij1;EsUQWB>pF07*qoM6N<$f`?(HWB>pF delta 1636 zcmV-q2AlcG4uK7jFnX3_zi^cl-dhelz02LyjQYapiV^m@W9X10Kx49SVctd4KT?g!DScQ|Y05oqj$C^r1jq z@7cG1C{PbYbyS^IA1Y8AB|6EOsy?(K7Ct5|y3jLqb+tF&{-Hpz{$m?qLN;B1NgwKz zu$w-VSE{~zQH20S75eHVR8|$F*W1Q5j}20DA$*Aoy*Vtp+K>^?kka@7W`N(E_Y~Gp zpa8{pOTXap^6jp17Phqn*bz6x(nki5$#f(%$`Aw8ASpONwY$fHSw%2WZylFdjj?=b zyr#7=pHJ=Q^bzu<#I2!ELpIjOge!{@wPNQDw4wxjBH#_3|6 z?g3#;VKb(Q3}R7{%z+0*8{(T{&e#?L)GxT{j5}`O)x($u1i?~z*we%Z_{0Fk!q~h{ z+esyJnZzupa?YkYeNH;ZDdR%UP*j;-SS)n6Xf7W2&1$5-w?TgqTL@6RD%F1dhN>~J zlz#xLuT&=adPV7B6RfvEXGKDKo&M(`Lx5HlCtwu<&Ny5EO9{Z}n^av0Pyz;ZNUsx= zw|Sl8ke9z1-F^GVa_DW5dI-?!h5-!CfrH)#XzbkWr_6QZpWjE1-nuhd={9q7wpgIa zoO%q14btm$^Ht_`j;GT5cs=!#{*`~r;(w>tzy0${!&s-LP@sO1(9;Vmp$~Kq89K%& z=|>6wnOa${?C&2ux_oDJW2U$nokM|6x);KMY`O>&((Cl~UqoJSn^$HTmIvkC$a6IW zC>M-{L9ZHhNUv88b%n8Q`Is3}b;(IvJyX3W`NGasJlIYf{@cv^SFet90vf;7VSk|x zIc0nEyT7LNJb~L_@a)3e-1R?hU3z?i=*Ezc3T>RJ!I)McE0MCQ;)d8xOabR=%#WV7 zT5LZ(+qn8d)`FiOOE z9sS=vdj(>q_Tb^eVsmp-59-%$?|-E!nd|XOgW~$Hw=O-Sp$i!Ulv^8j==Di=oIC)K z@J9x9C56;2pX591cnnaxi*&&i+!n|ROvVT-m3T`S5W37k zU8VFnUmFC8eqPKKH=lmKe6P*twDwS-DG)9g5={Y`L_Zye%{PEkAA2Cw(|>$ErqTn> z%PO~1LSCEr+Jl9v4r!B8qRTHV`gGc z#Z)L?+_6x;%-81~_c+$#&wnpcDG~Yr#Fr1k|2V1%IiH&=^1O7@RB8-RER4udx^2y0;qn+TKW=ln)Fd8?^XCy!^Eu;A3{a~+ zRukoswedVOz=R8lrdygm=&SWm(#Oob5S?#%`HQ#F-e^=+A*-=*wOxMOi>}pZl4l`h zV|;3qSj;W=u$K;1YFh82sKl^0@nLs9x31kA9Kqin0 iWCEE$CXfk46Zj9eOPyrodnxJw0000{_&F(Q24gMhklo zL=(6P3I#=_34|82bkU+{AtY%&a1pd|(XxgngJ?6`ptdcV!N>T($DlalqyKm7l8SfW zUKIwq2QEj?`ObHL_y7OSxtC#-rYN8&peXSFDB$z?-VBFBc7L8vteR&sA(z2mxZ?Nw z--kjWy)ZUwzYtJB4efUOjc&L5IT#GC%?e5D7X`|29LE55L!;4r@Or(DSz%|cBag>p z0?d7tO0^CcO|REmvRbW|bvoSzmSq{#D${H>59;;$vt%;)N-nT$P}(ekK;S9ranoot zUes!}JQTrAYk%!_`>0$lzfB|(0mKZa#hf-aJ?m*JFqh3{xm+&y71pl9VvfQ|IYGf` z%V`d3_X~x>C%s;OHxh|-rp1Yk$*NI6CTup_2JGetkS=OMFLpC}C_LQtR;#rm79%#U z7Ml*3xSSxjJb5pbna`Bp3zUjXDD`WT>o3G>v$ z>H}<~ZR~o#oQ*`!D_K!kZl#+G4FEp@?f^vN@7TM?TU)ox%gcNj)EkZO0DqKDr@shm zJR8HO5vg0dL*#P zCRtIZ)A<~)#2-Vb3J|=Iw5yXzVfBM~LQ;OopldFdtB<{9 delta 832 zcmV-G1Hb&12IB^hFn7j?_7|5Z=p4!r0Dix$Q=^xNb>7lnA+7d9O2uZLaiH!!ctFErv?`zqp zt4*@2x$Qu*GxKKNeEh!mW|v{KrYWE)peZnr0^xA@Z7>+r4}avO&t|sI+(1+Hdi|bG zr~4F*M#l$oB-=c6Q1WlL+pqIH{~gLs%g$3hybw^g+ijkloOFX~GZKm1Qcc&f@j^h! zzs+W2yHx+2kSPr_*TyY|n8t2Zb5wnakybd_Mmh3vU26)wAK02~{}?$h$cF zh0o`+5G460Ao(BE{yQf<9S(;XiaS`AT|0%Tuc=ptzJJTwlZ%Us*5l*jUmlO=5?b4E zMh`j4?Ck9DD6ZE~^D%yC>x?a3W<%HL9D`D+vlzcqsXBV`JkD?NQnkgW{0T*x1+z6$l+ju*G6gJUBR@YW|7woTN0_4-XF;$jcIJ zcaq8E7k{OI(t0&H>NA^6ObdVnyT89L0P-swP9vmO$T8WPuw}E^Dj?HFqwy+isv*gz zVnq>RGo)mi2sP#1(a{kHkei7_qDT&@)kTpYd8EN-Tv?%bJkI~KsQ<4R6yeO*1mUs? zs^Wc4RSm{AB%$o>?eS3iIaFN1dPPO^zn`Kw^nU>R$d}8_2Eq%)%6h&2hs=2md3qm3 z^JG|%&9 zI|*iMYbzu5hxt^jC>=gJI=WP?RyT2{Rxn(^r<`k;Q2l(V0*%FDRfKmQx%d=LS)@U% zpE>hk&MALI$W9Lg0&~dKWfT=RGc&WI_A^fARvT&xXbN1E0)GG(=4QFXlVNlK0000< KMNUMnLSTY|{g@g6 diff --git a/bundles/org.xmind.cathy/icons/toolbar/e/save.png b/bundles/org.xmind.cathy/icons/toolbar/e/save.png index 876734a2f58e03e177b654c318cd0a44d150dd18..b87ae17fc23c5bc541d8aad3c61510ff712f0809 100644 GIT binary patch delta 663 zcmV;I0%-mC1iS^1F@JVRL_t(o3GG!qZxcZf-90A-aYREEJCTqOPA-J-tTve9!BXj5+0Y1d|!kumOyVdgY z{>JXdXY^a887Kha!2mGMsS`jMH=vv92-x*rx4Z^eJJ3pi>LZLLj4Fc(qwv92#|qm3 z+g}r~OIKociGK`Or7{^mujWdBq9+I2+d5U?$)W)4Ivsb`TkEcVJpou}=~?q(I=y!{ zmPaaDpk6|F7R{r3qkmSU(SjNj-h{$V*HB<{g#+re$Fn<9z5-X-imBC7kHKl(uOaQsk z43rE1cyf!XvL=6@hP}oyM_GCCbB=Yf$qW?N4hAJlG)#-3?nZLSh+3v`v!2UmW}y7k zxPEYArqk)=6{7diXcV=X{>aKjkQpe;C^K?UMmsxM#mJ=Ir&$@ZL1v&0qXLq}*`JW} z2I3fl(|>=JVFp@-KRt@#?+y;K>OLF}wN<#etfVB!474FcSi9_)5nYQO+bV1 xyziZS+gh|}jz1LsFek2!X&Go4xTy^M2Bw=&zz{)#L(BjG002ovPDHLkV1l6$Kl%Uw delta 594 zcmV-Y0`q27=(dH-#2$>s5RJ zp?v}o>ic-|V$a1xch}CB?q}oTpB)8z=mx^fPA2BJUnW^JCT*z#sRI8?fsE#LJDpB7 z2!gjT3=5ih*=+WCGMPMT=EQSVpzU^hRV)?@`F!4FG8xnBc7M%=zqk=kV$_isI!P>)^gPc(ZUiC-LlXwUPnT!-Y#WS8Ow=@`QpwBZa`*D0 zPaM};6{!2;P!wPQMyJmlQP9SaCy*DzszC{6;T%P+f{vo1zCn!nm%^$+p%6M6K%kuM zkzcJ;47weY7=QBtOjs!gbs5}ntF#sXqw#n<4IqfY?rR(aY`I+a7K_D$GZ+jGj2sW^L8B`uuB^Mos7@TIpDNu2aDP7vyCcV+^q|q!;`+f>&t|jZ zD@3DrjfVB`wK}KiL8BVA3d*95dOgv)R2+BiIqf1)F3$SoH53Oy9&YoneYYBIZA$*1C`u^_M2ooVGY|GEr(U-D ztdTrm2qQCQ#i5ngdDiPhF^Rz?zN-3qdONeR*PikUsXN)J z>gwv6u3y*8j(6>*sjU*I1S)|_pc1GADuGI%5~u_!fl8nf2!ACoiim#g<3Db;ZTszL zI=#{t|BDZP?K3ZI`}F7c(wuf>^zg0b_4j}K>e}OET!In;^qsrE|8sct?adc&zR{b~ z?k8>2wDLk5$r7MLo}|%NK)u_;-D zK+ADaREJa@Yk>{IUohn@pU*gu2bU+~7wePjd(A$eZsc>$OAiMMG@3M|B665grKr>? z;JJhjn3M_@)m${KaQGr#E=52PNQWm5Lz;mV=|tarQBnO>G{uof>q=Tt}rY18N{p zuP}$FbX5oF4(Lldt23)uf~4e}-W~JX3byXx^7^?$4Fl>|pfZ5Y2Ax140fn*;kdAS( zOU_4EW`C;{QvV?&{#oeeVB>tDh5_~T6qY53B)b&ykji;rbo=Jb8M9U`=E=|f*AKI5EHh5^+ibWykjk**Pt z8Wc@zj$qW94vD7YZbKh$C^{PlX^iAujY^w&C_zy@9yS!`bHK2YwfPTw3;9?Y9FpB$WYe;Ew13US z3F^cF&8mQKnZwL2fPR#4%Jp(fbgZjrjhXo~HYK*ybZ)8EE0;333e*v!+$!Q8fqzKmDS7f(M0CAzup!vl#hpebQ2ACP>(`=4D*OD~fz;Uvd1 zC>KB9Kf~eF5SGr$upjw6WZ`8jhvont^H3}`~a4=PmJ%2}0wx3jY| zU^-2+y}gZlOp3`5O41J&GQ=MulGA`n7|^sv0X@gA_f9m98fC_ zTY9GF$*0RNyJYjPL#XrX5`Tp)5xv%I15kymI>dpV#k0Olavyu%V1(hx#sT%UB3V9P zzO;OTpoBx8?lyi7&)+2h7CsqhY|eFwebl|weg`qzU!6AOAq;3&HDH9Qv1KQ_XYu|0 z`$Oi_e0b;1Og!AnZ9{Dv?6X*I$&BkDoiLzWomQyOEJ1R-1VH(O#r1b zRp%8a)yn*MD}Y2(`1w7tSnQ%*#6@I_YqN8G(Re5E4+EM`&ij{2Ne%rhijs{pW6kz&;f^3n3cU_{8rQ;-D|RwU$k zv@oFa63Ek1pW+hF$A7hA0fH4vop4~MZ5}Om(Vc-0PJmqsYGFXRYCiXMcTOJ7h z!Jw(#zIDqWBPupazK2)td}9Yp>Vuxyf`tJkK&;=OW~+Cgz>42nB3|?5R%HGsRm+N% z^QcMYL!up5(B^geV;E3fITG--C5en2s8-Md8KScJWH2{n#(#!`=yo+orKXj1r=J_+ z3lb7EA2Jq4C`cR zskTa>5~u_!fl8nfs01p3N}v*`1S)|_Ae6vzMD(Mhquu-a`+uKCqtQ-R{Jp)suI{<} z&d<*qpXKG{i`CWDZ%Y(3CAZLeP z-n_xph(oI4Fl?77yw6vu}(>KN@m@;nu=f9UtTW)Y8X%|Qb|&!=m3$VS|#lxBk8%B z4HvGjtG_U_%cq7K29)GTT+)94$OA~S>*L`Pv$L-mY%7}cDWQhEhx(MLPNa4S!D!t579riKi@(%8hAqYRrYL2mTb58eXA3L1nH4e|Y`6b*{FE%yHpiF^}B6UWOCY)Mu5N zw*z&-~EvHD~Q zjF_@V_cncThUgCi%57IBGz;*o@mWdFnvd~WaUMDz_E2I$fR*%m-#7_N>Z6AAdf&L8 z!|N6(ebLAD&@#M2%LNOBlJbzeP5SB2#w2MT0yQ$8yH%&4PxHhtDLx+IZ6(bBN zlT83iAPfLNdJ?9h6sJq4Zzgc&K^E~?=YLQ#3~1ji|NY5Hv-T2p38yi9gmR+!1hY7D z9uab?YZ%bxmZUPWq_S95c}>4bK;WA?{dw84?YZDQWrMY8|H+3^Pkwg$Dk*CPFgqX9 zK(iS#$}puGjC9@SZ&gT4IppTgPyjPFv<$0IDzCh)l>lSHdUkd;Xif(Q2dzy2Ab%C= z=O1+994s8DDy;Po;yN#2Km8kfuGjH7=PIn+3~u*6`=*)|BRAVTH>awb4aH_i83vSd z$`Z(b{b=Dz6(A)rOU%JAfa$u=zH?l2enR7t3%s`0Na{lPoPUyPQ;!F;nD5Kt%cZ#G=Zi9*bsSLEK{6R| zt6HdfRaG*Dg!(%)T&1hEq@Q(XTVrK5|W`k2GsvzA+}{dY@LEw_L3UO9d3lcRu> zR7>;xZz^;G;yA^WV@lCikaPfKn?505-VFL|n%FW(_7fEf^xgoE8-EC?(3JFtySuyX zm6es|p+nUf6xIybEX%)yFheQ^zYWmWl0`hm{G8H9pFU}0J}^F{3;~)J`0Dod_Q$mN z?Q*fdzkgqLg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + +
diff --git a/bundles/org.xmind.cathy/pom.xml b/bundles/org.xmind.cathy/pom.xml index 07de990a9..2b04bf2b6 100644 --- a/bundles/org.xmind.cathy/pom.xml +++ b/bundles/org.xmind.cathy/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.cathy - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.cathy + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.cathy/resource/langs.properties b/bundles/org.xmind.cathy/resource/langs.properties index 27ccf3c60..81a7558a1 100644 --- a/bundles/org.xmind.cathy/resource/langs.properties +++ b/bundles/org.xmind.cathy/resource/langs.properties @@ -1,15 +1,15 @@ -en_US=English -ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -da=Dansk -de=Deutsch -es=Espa\u00F1ol -fr=Fran\u00e7ais -it=Italiano -ja=\u65e5\u672c\u8a9e -ko=\ud55c\uad6d\uc758 -pt_BR=Portugu\u00eas (Brasil) -ru=P\u0443\u0441\u0441\u043a\u0438\u0439 -sl=Sloven\u0161\u010dina -zh_CN=\u7b80\u4f53\u4e2d\u6587 -zh_TW=\u7e41\u9ad4\u4e2d\u6587 - +en_US=English +ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 +da=Dansk +de=Deutsch +es=Espa\u00F1ol +fr=Fran\u00e7ais +it=Italiano +ja=\u65e5\u672c\u8a9e +ko=\ud55c\uad6d\uc758 +pt_BR=Portugu\u00eas (Brasil) +ru=P\u0443\u0441\u0441\u043a\u0438\u0439 +sl=Sloven\u0161\u010dina +zh_CN=\u7b80\u4f53\u4e2d\u6587 +zh_TW=\u7e41\u9ad4\u4e2d\u6587 + diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AbstractCheckFilesProcess.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AbstractCheckFilesProcess.java index 9ff173b10..09233065d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AbstractCheckFilesProcess.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AbstractCheckFilesProcess.java @@ -1,95 +1,95 @@ -package org.xmind.cathy.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.mindmap.MindMapUI; - -public class AbstractCheckFilesProcess { - - private final IWorkbench workbench; - - private List editorsToOpen; - - public AbstractCheckFilesProcess(IWorkbench workbench) { - this.workbench = workbench; - } - - public IWorkbench getWorkbench() { - return workbench; - } - - protected void addEditorToOpen(IEditorInput input) { - if (editorsToOpen == null) - editorsToOpen = new ArrayList(); - editorsToOpen.add(input); - } - - protected void openEditors(boolean activate) { - if (editorsToOpen != null && !editorsToOpen.isEmpty()) { - openEditors(editorsToOpen, activate); - } - } - - protected void openEditors(List editorInputs, - boolean activate) { - for (final IEditorInput input : editorInputs) { - IEditorPart editor = openEditor(input, activate); - if (editor != null) - activate = false; - } - } - - protected IEditorPart openEditor(final IEditorInput input, - final boolean activate) { - if (input == null) - return null; - - Display display = workbench.getDisplay(); - if (display == null) - return null; - - final IEditorPart[] result = new IEditorPart[1]; - display.syncExec(new Runnable() { - public void run() { - IWorkbenchWindow window = getPrimaryWindow(); - if (window == null) - return; - final IWorkbenchPage page = window.getActivePage(); - if (page != null) { - SafeRunner.run(new SafeRunnable(NLS.bind( - WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, - input.getName())) { - public void run() throws Exception { - result[0] = page.openEditor(input, - MindMapUI.MINDMAP_EDITOR_ID, activate); - } - }); - } - } - - }); - return result[0]; - } - - private IWorkbenchWindow getPrimaryWindow() { - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window == null) { - IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); - if (windows != null && windows.length > 0) { - window = windows[0]; - } - } - return window; - } - -} +package org.xmind.cathy.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.ui.mindmap.MindMapUI; + +public class AbstractCheckFilesProcess { + + private final IWorkbench workbench; + + private List editorsToOpen; + + public AbstractCheckFilesProcess(IWorkbench workbench) { + this.workbench = workbench; + } + + public IWorkbench getWorkbench() { + return workbench; + } + + protected void addEditorToOpen(IEditorInput input) { + if (editorsToOpen == null) + editorsToOpen = new ArrayList(); + editorsToOpen.add(input); + } + + protected void openEditors(boolean activate) { + if (editorsToOpen != null && !editorsToOpen.isEmpty()) { + openEditors(editorsToOpen, activate); + } + } + + protected void openEditors(List editorInputs, + boolean activate) { + for (final IEditorInput input : editorInputs) { + IEditorPart editor = openEditor(input, activate); + if (editor != null) + activate = false; + } + } + + protected IEditorPart openEditor(final IEditorInput input, + final boolean activate) { + if (input == null) + return null; + + Display display = workbench.getDisplay(); + if (display == null) + return null; + + final IEditorPart[] result = new IEditorPart[1]; + display.syncExec(new Runnable() { + public void run() { + IWorkbenchWindow window = getPrimaryWindow(); + if (window == null) + return; + final IWorkbenchPage page = window.getActivePage(); + if (page != null) { + SafeRunner.run(new SafeRunnable(NLS.bind( + WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, + input.getName())) { + public void run() throws Exception { + result[0] = page.openEditor(input, + MindMapUI.MINDMAP_EDITOR_ID, activate); + } + }); + } + } + + }); + return result[0]; + } + + private IWorkbenchWindow getPrimaryWindow() { + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) { + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + if (windows != null && windows.length > 0) { + window = windows[0]; + } + } + return window; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicator.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicator.java index a49be4d75..ccd3f6b99 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicator.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicator.java @@ -1,287 +1,287 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.util.Util; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.ui.menus.WorkbenchWindowControlContribution; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.PrefUtils; - -public class AutoBackupIndicator extends WorkbenchWindowControlContribution - implements IPropertyChangeListener, Listener { - - private static final int DISABLED = 1; - - private static final int ENABLED = 2; - - private class ChangeAutoSavePrefAction extends Action { - private IPreferenceStore ps; - private int value; - - /** - * - */ - public ChangeAutoSavePrefAction(IPreferenceStore ps, String text, - int value) { - super(text); - this.ps = ps; - this.value = value; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (ps == null) - return; - - changeStatus(value); - } - - /** - * @return the value - */ - public int getValue() { - return value; - } - } - - private static class OpenPreferencePageAction extends Action { - - /** - * - */ - public OpenPreferencePageAction() { - super( - WorkbenchMessages.AutoBackupIndicator_OpenPreferenceAction_text); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - PrefUtils.openPrefDialog(null, PrefUtils.GENERAL_PREF_PAGE_ID); - } - } - - private Control control; - - private Label label; - - private MenuManager menu; - - private IPreferenceStore ps; - - public AutoBackupIndicator() { - super("org.xmind.ui.status.AutoSaveIndicator"); //$NON-NLS-1$ - } - - protected Control createControl(Composite parent) { - ps = CathyPlugin.getDefault().getPreferenceStore(); - - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 4; - composite.setLayout(layout); - -// Label sep = new Label(composite, SWT.SEPARATOR | SWT.VERTICAL); -// sep.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, true)); - - label = new Label(composite, SWT.CENTER); - label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); - label.setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, - Util.isMac() ? -2 : -1)); - label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - label.addListener(SWT.MouseDown, this); - - menu = new MenuManager(); - menu.add(new ChangeAutoSavePrefAction( - ps, - WorkbenchMessages.AutoBackupIndicator_DisableAutoSaveAction_text, - DISABLED)); - menu.add(new ChangeAutoSavePrefAction( - ps, - WorkbenchMessages.AutoBackupIndicator_EnableAutoSaveAction_text, - ENABLED)); - menu.add(new Separator()); - menu.add(new OpenPreferencePageAction()); - menu.createContextMenu(label); - label.setMenu(menu.getMenu()); - - updateEnablement(); - -// composite.setLayoutData(new StatusLineLayoutData()); - - ps.removePropertyChangeListener(this); - ps.addPropertyChangeListener(this); - - this.control = composite; - return composite; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.ContributionItem#update() - */ - @Override - public void update() { - update(null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.ContributionItem#update(java.lang.String) - */ - @Override - public void update(String id) { - super.update(id); - - if (label == null || label.isDisposed() || ps == null) - return; - - if (id == null || CathyPlugin.AUTO_SAVE_ENABLED.equals(id)) { - updateEnablement(); - updateSize(); - } - } - - private void updateSize() { - if (control == null || control.isDisposed()) - return; - - Point oldSize = control.getSize(); - control.pack(true); - Point newSize = control.getSize(); - if (oldSize.equals(newSize)) - return; - - control.getParent().layout(true, true); - } - - private void updateEnablement() { - int value = getValue(); - if (value == ENABLED) { - label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveEnabled_label); - int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS); - label.setToolTipText(NLS.bind(WorkbenchMessages.AutoSave_label2, - intervals)); - } else { - label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); - label.setToolTipText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_description); - } - if (menu != null) { - for (IContributionItem item : menu.getItems()) { - if (item instanceof ActionContributionItem) { - IAction action = ((ActionContributionItem) item) - .getAction(); - if (action instanceof ChangeAutoSavePrefAction) { - action.setChecked(((ChangeAutoSavePrefAction) action) - .getValue() == value); - } - } - } - } - } - - private int getValue() { - return ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED) ? ENABLED - : DISABLED; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.ContributionItem#dispose() - */ - @Override - public void dispose() { - if (label != null) { - label.dispose(); - label = null; - } - control = null; - if (menu != null) { - menu.dispose(); - menu = null; - } - if (ps != null) { - ps.removePropertyChangeListener(this); - ps = null; - } - super.dispose(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse - * .jface.util.PropertyChangeEvent) - */ - public void propertyChange(final PropertyChangeEvent event) { - if (control == null || control.isDisposed()) - return; - control.getDisplay().asyncExec(new Runnable() { - public void run() { - update(event.getProperty()); - } - }); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. - * Event) - */ - public void handleEvent(final Event event) { - if (event.widget == label) { - if (event.button == 1) { - event.display.timerExec(10, new Runnable() { - public void run() { - Point loc = label.getParent().toDisplay(event.x, - event.y); - updateEnablement(); - menu.getMenu().setLocation(loc); - menu.getMenu().setVisible(true); - } - }); - } - } - } - - private void changeStatus(int value) { - ps.setValue(CathyPlugin.AUTO_SAVE_ENABLED, value == ENABLED); - } -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.Util; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.menus.WorkbenchWindowControlContribution; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.PrefUtils; + +public class AutoBackupIndicator extends WorkbenchWindowControlContribution + implements IPropertyChangeListener, Listener { + + private static final int DISABLED = 1; + + private static final int ENABLED = 2; + + private class ChangeAutoSavePrefAction extends Action { + private IPreferenceStore ps; + private int value; + + /** + * + */ + public ChangeAutoSavePrefAction(IPreferenceStore ps, String text, + int value) { + super(text); + this.ps = ps; + this.value = value; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (ps == null) + return; + + changeStatus(value); + } + + /** + * @return the value + */ + public int getValue() { + return value; + } + } + + private static class OpenPreferencePageAction extends Action { + + /** + * + */ + public OpenPreferencePageAction() { + super( + WorkbenchMessages.AutoBackupIndicator_OpenPreferenceAction_text); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + PrefUtils.openPrefDialog(null, PrefUtils.GENERAL_PREF_PAGE_ID); + } + } + + private Control control; + + private Label label; + + private MenuManager menu; + + private IPreferenceStore ps; + + public AutoBackupIndicator() { + super("org.xmind.ui.status.AutoSaveIndicator"); //$NON-NLS-1$ + } + + protected Control createControl(Composite parent) { + ps = CathyPlugin.getDefault().getPreferenceStore(); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 4; + composite.setLayout(layout); + +// Label sep = new Label(composite, SWT.SEPARATOR | SWT.VERTICAL); +// sep.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, true)); + + label = new Label(composite, SWT.CENTER); + label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); + label.setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, + Util.isMac() ? -2 : -1)); + label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + label.addListener(SWT.MouseDown, this); + + menu = new MenuManager(); + menu.add(new ChangeAutoSavePrefAction( + ps, + WorkbenchMessages.AutoBackupIndicator_DisableAutoSaveAction_text, + DISABLED)); + menu.add(new ChangeAutoSavePrefAction( + ps, + WorkbenchMessages.AutoBackupIndicator_EnableAutoSaveAction_text, + ENABLED)); + menu.add(new Separator()); + menu.add(new OpenPreferencePageAction()); + menu.createContextMenu(label); + label.setMenu(menu.getMenu()); + + updateEnablement(); + +// composite.setLayoutData(new StatusLineLayoutData()); + + ps.removePropertyChangeListener(this); + ps.addPropertyChangeListener(this); + + this.control = composite; + return composite; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.ContributionItem#update() + */ + @Override + public void update() { + update(null); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.ContributionItem#update(java.lang.String) + */ + @Override + public void update(String id) { + super.update(id); + + if (label == null || label.isDisposed() || ps == null) + return; + + if (id == null || CathyPlugin.AUTO_SAVE_ENABLED.equals(id)) { + updateEnablement(); + updateSize(); + } + } + + private void updateSize() { + if (control == null || control.isDisposed()) + return; + + Point oldSize = control.getSize(); + control.pack(true); + Point newSize = control.getSize(); + if (oldSize.equals(newSize)) + return; + + control.getParent().layout(true, true); + } + + private void updateEnablement() { + int value = getValue(); + if (value == ENABLED) { + label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveEnabled_label); + int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS); + label.setToolTipText(NLS.bind(WorkbenchMessages.AutoSave_label2, + intervals)); + } else { + label.setText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); + label.setToolTipText(WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_description); + } + if (menu != null) { + for (IContributionItem item : menu.getItems()) { + if (item instanceof ActionContributionItem) { + IAction action = ((ActionContributionItem) item) + .getAction(); + if (action instanceof ChangeAutoSavePrefAction) { + action.setChecked(((ChangeAutoSavePrefAction) action) + .getValue() == value); + } + } + } + } + } + + private int getValue() { + return ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED) ? ENABLED + : DISABLED; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.ContributionItem#dispose() + */ + @Override + public void dispose() { + if (label != null) { + label.dispose(); + label = null; + } + control = null; + if (menu != null) { + menu.dispose(); + menu = null; + } + if (ps != null) { + ps.removePropertyChangeListener(this); + ps = null; + } + super.dispose(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse + * .jface.util.PropertyChangeEvent) + */ + public void propertyChange(final PropertyChangeEvent event) { + if (control == null || control.isDisposed()) + return; + control.getDisplay().asyncExec(new Runnable() { + public void run() { + update(event.getProperty()); + } + }); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. + * Event) + */ + public void handleEvent(final Event event) { + if (event.widget == label) { + if (event.button == 1) { + event.display.timerExec(10, new Runnable() { + public void run() { + Point loc = label.getParent().toDisplay(event.x, + event.y); + updateEnablement(); + menu.getMenu().setLocation(loc); + menu.getMenu().setVisible(true); + } + }); + } + } + } + + private void changeStatus(int value) { + ps.setValue(CathyPlugin.AUTO_SAVE_ENABLED, value == ENABLED); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicatorToolControl.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicatorToolControl.java index b99689f49..301dcea91 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicatorToolControl.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoBackupIndicatorToolControl.java @@ -1,242 +1,242 @@ -package org.xmind.cathy.internal; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.util.Util; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.PrefUtils; - -public class AutoBackupIndicatorToolControl - implements IPropertyChangeListener, Listener { - - private static final int DISABLED = 1; - - private static final int ENABLED = 2; - - private class ChangeAutoSavePrefAction extends Action { - private IPreferenceStore ps; - private int value; - - /** - * - */ - public ChangeAutoSavePrefAction(IPreferenceStore ps, String text, - int value) { - super(text); - this.ps = ps; - this.value = value; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (ps == null) - return; - - changeStatus(value); - } - - /** - * @return the value - */ - public int getValue() { - return value; - } - } - - private static class OpenPreferencePageAction extends Action { - - /** - * - */ - public OpenPreferencePageAction() { - super(WorkbenchMessages.AutoBackupIndicator_OpenPreferenceAction_text); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - PrefUtils.openPrefDialog(null, PrefUtils.GENERAL_PREF_PAGE_ID); - } - } - - private IPreferenceStore ps; - - private Control control; - - private Label label; - - private MenuManager menu; - - @Inject - public AutoBackupIndicatorToolControl() { - ps = CathyPlugin.getDefault().getPreferenceStore(); - } - - @PostConstruct - public void createGui(Composite parent) { - - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 4; - composite.setLayout(layout); - - label = new Label(composite, SWT.CENTER); - label.setText( - WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); - label.setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, - Util.isMac() ? -2 : -1)); - label.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, true)); - label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - label.addListener(SWT.MouseDown, this); - - menu = new MenuManager(); - menu.add(new ChangeAutoSavePrefAction(ps, - WorkbenchMessages.AutoBackupIndicator_DisableAutoSaveAction_text, - DISABLED)); - menu.add(new ChangeAutoSavePrefAction(ps, - WorkbenchMessages.AutoBackupIndicator_EnableAutoSaveAction_text, - ENABLED)); - menu.add(new Separator()); - menu.add(new OpenPreferencePageAction()); - menu.createContextMenu(label); - label.setMenu(menu.getMenu()); - - updateEnablement(); - - ps.removePropertyChangeListener(this); - ps.addPropertyChangeListener(this); - - this.control = composite; - - } - - private void updateEnablement() { - int value = getValue(); - if (value == ENABLED) { - label.setText( - WorkbenchMessages.AutoBackupIndicator_AutoSaveEnabled_label); - int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS); - label.setToolTipText( - NLS.bind(WorkbenchMessages.AutoSave_label2, intervals)); - } else { - label.setText( - WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); - label.setToolTipText( - WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_description); - } - if (menu != null) { - for (IContributionItem item : menu.getItems()) { - if (item instanceof ActionContributionItem) { - IAction action = ((ActionContributionItem) item) - .getAction(); - if (action instanceof ChangeAutoSavePrefAction) { - action.setChecked(((ChangeAutoSavePrefAction) action) - .getValue() == value); - } - } - } - } - } - - private int getValue() { - return ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED) ? ENABLED - : DISABLED; - } - - public void propertyChange(final PropertyChangeEvent event) { - if (control == null || control.isDisposed()) - return; - control.getDisplay().asyncExec(new Runnable() { - public void run() { - update(event.getProperty()); - } - }); - } - - public void update(String id) { - if (label == null || label.isDisposed() || ps == null) - return; - - if (id == null || CathyPlugin.AUTO_SAVE_ENABLED.equals(id)) { - updateEnablement(); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. - * Event) - */ - public void handleEvent(final Event event) { - if (event.widget == label) { - if (event.button == 1) { - event.display.timerExec(10, new Runnable() { - public void run() { - Point loc = label.getParent().toDisplay(event.x, - event.y); - updateEnablement(); - menu.getMenu().setLocation(loc); - menu.getMenu().setVisible(true); - } - }); - } - } - } - - private void changeStatus(int value) { - ps.setValue(CathyPlugin.AUTO_SAVE_ENABLED, value == ENABLED); - } - - @PreDestroy - private void dispose() { - if (label != null) { - label.dispose(); - label = null; - } - control = null; - if (menu != null) { - menu.dispose(); - menu = null; - } - if (ps != null) { - ps.removePropertyChangeListener(this); - ps = null; - } - } +package org.xmind.cathy.internal; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.Util; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.PrefUtils; + +public class AutoBackupIndicatorToolControl + implements IPropertyChangeListener, Listener { + + private static final int DISABLED = 1; + + private static final int ENABLED = 2; + + private class ChangeAutoSavePrefAction extends Action { + private IPreferenceStore ps; + private int value; + + /** + * + */ + public ChangeAutoSavePrefAction(IPreferenceStore ps, String text, + int value) { + super(text); + this.ps = ps; + this.value = value; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (ps == null) + return; + + changeStatus(value); + } + + /** + * @return the value + */ + public int getValue() { + return value; + } + } + + private static class OpenPreferencePageAction extends Action { + + /** + * + */ + public OpenPreferencePageAction() { + super(WorkbenchMessages.AutoBackupIndicator_OpenPreferenceAction_text); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + PrefUtils.openPrefDialog(null, PrefUtils.GENERAL_PREF_PAGE_ID); + } + } + + private IPreferenceStore ps; + + private Control control; + + private Label label; + + private MenuManager menu; + + @Inject + public AutoBackupIndicatorToolControl() { + ps = CathyPlugin.getDefault().getPreferenceStore(); + } + + @PostConstruct + public void createGui(Composite parent) { + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 4; + composite.setLayout(layout); + + label = new Label(composite, SWT.CENTER); + label.setText( + WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); + label.setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, + Util.isMac() ? -2 : -1)); + label.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, true)); + label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + label.addListener(SWT.MouseDown, this); + + menu = new MenuManager(); + menu.add(new ChangeAutoSavePrefAction(ps, + WorkbenchMessages.AutoBackupIndicator_DisableAutoSaveAction_text, + DISABLED)); + menu.add(new ChangeAutoSavePrefAction(ps, + WorkbenchMessages.AutoBackupIndicator_EnableAutoSaveAction_text, + ENABLED)); + menu.add(new Separator()); + menu.add(new OpenPreferencePageAction()); + menu.createContextMenu(label); + label.setMenu(menu.getMenu()); + + updateEnablement(); + + ps.removePropertyChangeListener(this); + ps.addPropertyChangeListener(this); + + this.control = composite; + + } + + private void updateEnablement() { + int value = getValue(); + if (value == ENABLED) { + label.setText( + WorkbenchMessages.AutoBackupIndicator_AutoSaveEnabled_label); + int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS); + label.setToolTipText( + NLS.bind(WorkbenchMessages.AutoSave_label2, intervals)); + } else { + label.setText( + WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_label); + label.setToolTipText( + WorkbenchMessages.AutoBackupIndicator_AutoSaveDisabled_description); + } + if (menu != null) { + for (IContributionItem item : menu.getItems()) { + if (item instanceof ActionContributionItem) { + IAction action = ((ActionContributionItem) item) + .getAction(); + if (action instanceof ChangeAutoSavePrefAction) { + action.setChecked(((ChangeAutoSavePrefAction) action) + .getValue() == value); + } + } + } + } + } + + private int getValue() { + return ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED) ? ENABLED + : DISABLED; + } + + public void propertyChange(final PropertyChangeEvent event) { + if (control == null || control.isDisposed()) + return; + control.getDisplay().asyncExec(new Runnable() { + public void run() { + update(event.getProperty()); + } + }); + } + + public void update(String id) { + if (label == null || label.isDisposed() || ps == null) + return; + + if (id == null || CathyPlugin.AUTO_SAVE_ENABLED.equals(id)) { + updateEnablement(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. + * Event) + */ + public void handleEvent(final Event event) { + if (event.widget == label) { + if (event.button == 1) { + event.display.timerExec(10, new Runnable() { + public void run() { + Point loc = label.getParent().toDisplay(event.x, + event.y); + updateEnablement(); + menu.getMenu().setLocation(loc); + menu.getMenu().setVisible(true); + } + }); + } + } + } + + private void changeStatus(int value) { + ps.setValue(CathyPlugin.AUTO_SAVE_ENABLED, value == ENABLED); + } + + @PreDestroy + private void dispose() { + if (label != null) { + label.dispose(); + label = null; + } + control = null; + if (menu != null) { + menu.dispose(); + menu = null; + } + if (ps != null) { + ps.removePropertyChangeListener(this); + ps = null; + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoSaveService.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoSaveService.java index 349cb576d..774fea7c2 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoSaveService.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/AutoSaveService.java @@ -1,88 +1,88 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.cathy.internal; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.ui.IStartup; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchListener; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.internal.editor.BackgroundSaveWorkbook; - -/** - * @author Frank Shaka - * - */ -public class AutoSaveService - implements IStartup, IWorkbenchListener, IPropertyChangeListener { - - private IWorkbench workbench; - - /** - * - */ - public AutoSaveService() { - } - - /** - * - */ - private void checkState() { - IPreferenceStore ps = CathyPlugin.getDefault().getPreferenceStore(); - boolean enabled = ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED); - int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS) * 60000; - BackgroundSaveWorkbook.getInstance().reset(intervals, enabled); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse - * .jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - String property = event.getProperty(); - if (CathyPlugin.AUTO_SAVE_ENABLED.equals(property) - || CathyPlugin.AUTO_SAVE_INTERVALS.equals(property)) { - checkState(); - } - } - - public void earlyStartup() { - this.workbench = PlatformUI.getWorkbench(); - this.workbench.addWorkbenchListener(this); - CathyPlugin.getDefault().getPreferenceStore() - .addPropertyChangeListener(this); - checkState(); - } - - public void postShutdown(IWorkbench workbench) { - if (this.workbench == null) - return; - this.workbench.removeWorkbenchListener(this); - this.workbench = null; - CathyPlugin.getDefault().getPreferenceStore() - .removePropertyChangeListener(this); - BackgroundSaveWorkbook.getInstance().stopAll(); - } - - public boolean preShutdown(IWorkbench workbench, boolean forced) { - return true; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.cathy.internal; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.internal.editor.BackgroundSaveWorkbook; + +/** + * @author Frank Shaka + * + */ +public class AutoSaveService + implements IStartup, IWorkbenchListener, IPropertyChangeListener { + + private IWorkbench workbench; + + /** + * + */ + public AutoSaveService() { + } + + /** + * + */ + private void checkState() { + IPreferenceStore ps = CathyPlugin.getDefault().getPreferenceStore(); + boolean enabled = ps.getBoolean(CathyPlugin.AUTO_SAVE_ENABLED); + int intervals = ps.getInt(CathyPlugin.AUTO_SAVE_INTERVALS) * 60000; + BackgroundSaveWorkbook.getInstance().reset(intervals, enabled); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse + * .jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String property = event.getProperty(); + if (CathyPlugin.AUTO_SAVE_ENABLED.equals(property) + || CathyPlugin.AUTO_SAVE_INTERVALS.equals(property)) { + checkState(); + } + } + + public void earlyStartup() { + this.workbench = PlatformUI.getWorkbench(); + this.workbench.addWorkbenchListener(this); + CathyPlugin.getDefault().getPreferenceStore() + .addPropertyChangeListener(this); + checkState(); + } + + public void postShutdown(IWorkbench workbench) { + if (this.workbench == null) + return; + this.workbench.removeWorkbenchListener(this); + this.workbench = null; + CathyPlugin.getDefault().getPreferenceStore() + .removePropertyChangeListener(this); + BackgroundSaveWorkbook.getInstance().stopAll(); + } + + public boolean preShutdown(IWorkbench workbench, boolean forced) { + return true; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/BetaVerifier.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/BetaVerifier.java index ade3ee731..362a6c4ba 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/BetaVerifier.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/BetaVerifier.java @@ -1,122 +1,122 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.IOException; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Display; - -public class BetaVerifier { - - /** - * The timestamp when the beta will expire. Beta releases will change this - * value to a valid timestamp. - */ - // Note: Not defined as 'final' to prevent compiling warning - // at expression 'BETA_EXPIRE_TIME > 0'. - private static long BETA_EXPIRY_TIME = 0L; - - private static long LAUNCH_TIME = System.currentTimeMillis(); - - private final Display display; - - private final String brandingVersion; - - private final String buildId; - - public BetaVerifier(Display display) { - this.display = display; - this.brandingVersion = System - .getProperty(CathyApplication.SYS_BRANDING_VERSION, ""); //$NON-NLS-1$ - this.buildId = System.getProperty(CathyApplication.SYS_BUILDID, - "X.x.x"); //$NON-NLS-1$ - } - - public boolean shouldExitAfterBetaExpired() { - if (isBeta() && isBetaExpired()) { - promptBetaExpiry(); - return true; - } else if (isBeta()) { - String licenseRestrictions = System - .getProperty("org.xmind.product.license.restrictions"); //$NON-NLS-1$ - if (licenseRestrictions == null || "".equals(licenseRestrictions)) { //$NON-NLS-1$ - licenseRestrictions = NLS.bind( - WorkbenchMessages.About_BetaExpiryMessage_withExpiryTime, - new SimpleDateFormat("MMM d, yyyy") //$NON-NLS-1$ - .format(new Date(BETA_EXPIRY_TIME))); - System.setProperty("org.xmind.product.license.restrictions", //$NON-NLS-1$ - licenseRestrictions); - } - } - return false; - } - - private int openMessageDialog(String message, int dialogType, - String[] buttonLabels) { - URL titleIconURL = Platform.getBundle(CathyPlugin.PLUGIN_ID) - .getResource("icons/xmind.16.png"); //$NON-NLS-1$ - Image titleIcon = null; - try { - titleIcon = new Image(display, titleIconURL.openStream()); - } catch (IOException e) { - } - - try { - MessageDialog dialog = new MessageDialog(null, - WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_windowTitle, - titleIcon, message, dialogType, buttonLabels, 0); - return dialog.open(); - } finally { - if (titleIcon != null) - titleIcon.dispose(); - } - - } - - private void promptBetaExpiry() { - int selection = openMessageDialog( - NLS.bind( - WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId, - brandingVersion, buildId), - MessageDialog.INFORMATION, - new String[] { - WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text, - WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_ExitButton_text }); - if (selection == 0) { - openDownloadSite(); - } - } - - private void openDownloadSite() { - Program.launch("http://www.xmind.net/xmind/beta-expired/" //$NON-NLS-1$ - + buildId.replace("qualifier", "000000000000")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public static boolean isBeta() { - return BETA_EXPIRY_TIME > 0; - } - - public static boolean isBetaExpired() { - return LAUNCH_TIME > BETA_EXPIRY_TIME; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.IOException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; + +public class BetaVerifier { + + /** + * The timestamp when the beta will expire. Beta releases will change this + * value to a valid timestamp. + */ + // Note: Not defined as 'final' to prevent compiling warning + // at expression 'BETA_EXPIRE_TIME > 0'. + private static long BETA_EXPIRY_TIME = 0L; + + private static long LAUNCH_TIME = System.currentTimeMillis(); + + private final Display display; + + private final String brandingVersion; + + private final String buildId; + + public BetaVerifier(Display display) { + this.display = display; + this.brandingVersion = System + .getProperty(CathyApplication.SYS_BRANDING_VERSION, ""); //$NON-NLS-1$ + this.buildId = System.getProperty(CathyApplication.SYS_BUILDID, + "X.x.x"); //$NON-NLS-1$ + } + + public boolean shouldExitAfterBetaExpired() { + if (isBeta() && isBetaExpired()) { + promptBetaExpiry(); + return true; + } else if (isBeta()) { + String licenseRestrictions = System + .getProperty("org.xmind.product.license.restrictions"); //$NON-NLS-1$ + if (licenseRestrictions == null || "".equals(licenseRestrictions)) { //$NON-NLS-1$ + licenseRestrictions = NLS.bind( + WorkbenchMessages.About_BetaExpiryMessage_withExpiryTime, + new SimpleDateFormat("MMM d, yyyy") //$NON-NLS-1$ + .format(new Date(BETA_EXPIRY_TIME))); + System.setProperty("org.xmind.product.license.restrictions", //$NON-NLS-1$ + licenseRestrictions); + } + } + return false; + } + + private int openMessageDialog(String message, int dialogType, + String[] buttonLabels) { + URL titleIconURL = Platform.getBundle(CathyPlugin.PLUGIN_ID) + .getResource("icons/xmind.16.png"); //$NON-NLS-1$ + Image titleIcon = null; + try { + titleIcon = new Image(display, titleIconURL.openStream()); + } catch (IOException e) { + } + + try { + MessageDialog dialog = new MessageDialog(null, + WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_windowTitle, + titleIcon, message, dialogType, buttonLabels, 0); + return dialog.open(); + } finally { + if (titleIcon != null) + titleIcon.dispose(); + } + + } + + private void promptBetaExpiry() { + int selection = openMessageDialog( + NLS.bind( + WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId, + brandingVersion, buildId), + MessageDialog.INFORMATION, + new String[] { + WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text, + WorkbenchMessages.BetaVerifier_BetaExpiredPromptDialog_ExitButton_text }); + if (selection == 0) { + openDownloadSite(); + } + } + + private void openDownloadSite() { + Program.launch("http://www.xmind.net/xmind/beta-expired/" //$NON-NLS-1$ + + buildId.replace("qualifier", "000000000000")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static boolean isBeta() { + return BETA_EXPIRY_TIME > 0; + } + + public static boolean isBetaExpired() { + return LAUNCH_TIME > BETA_EXPIRY_TIME; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyApplication.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyApplication.java index 0bd3431ce..ff69c1d4c 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyApplication.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyApplication.java @@ -1,300 +1,305 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.awt.Toolkit; -import java.io.File; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Platform; -import org.eclipse.equinox.app.IApplication; -import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; -import org.xmind.core.Core; -import org.xmind.core.internal.dom.DOMConstants; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.app.IApplicationValidator; -import org.xmind.ui.prefs.PrefConstants; - -/** - * This class controls all aspects of the application's execution - */ -public class CathyApplication implements IApplication { - - public static final String SYS_VERSION = "org.xmind.product.version"; //$NON-NLS-1$ - - public static final String SYS_BUILDID = "org.xmind.product.buildid"; //$NON-NLS-1$ - - public static final String SYS_BRANDING_VERSION = "org.xmind.product.brandingVersion"; //$NON-NLS-1$ - - public static final String SYS_APP_STATUS = "org.xmind.cathy.app.status"; //$NON-NLS-1$ - - /** - * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) - */ - public Object start(IApplicationContext context) throws Exception { - // Check product information. - // Product build id and version may have been set in config.ini. - // If not set, calculate them using runtime properties. - String buildId = System.getProperty(SYS_BUILDID); - if (buildId == null || "".equals(buildId)) { //$NON-NLS-1$ - buildId = calculateBuildId(context); - System.setProperty(SYS_BUILDID, buildId); - } - String appVersion = System.getProperty(SYS_VERSION); - if (appVersion == null || "".equals(appVersion)) { //$NON-NLS-1$ - appVersion = extractVersionNumber(buildId); - System.setProperty(SYS_VERSION, appVersion); - } - - System.setProperty("org.xmind.product.about.copyright", //$NON-NLS-1$ - WorkbenchMessages.About_Copyright); - System.setProperty("org.xmind.product.about.homepage", //$NON-NLS-1$ - WorkbenchMessages.About_Homepage); - - IPreferenceStore pref = MindMapUIPlugin.getDefault() - .getPreferenceStore(); - - String name = pref.getString(PrefConstants.AUTHOR_INFO_NAME); - - if (name == null || "".equals(name)) //$NON-NLS-1$ - name = System.getProperty("user.name"); //$NON-NLS-1$ - if (name != null) - System.setProperty(DOMConstants.AUTHOR_NAME, name); - - if (pref.getString(PrefConstants.AUTHOR_INFO_EMAIL) != null) - System.setProperty(DOMConstants.AUTHOR_EMAIL, - pref.getString(PrefConstants.AUTHOR_INFO_EMAIL)); - - if (pref.getString(PrefConstants.AUTHOR_INFO_ORG) != null) - System.setProperty(DOMConstants.AUTHOR_ORG, - pref.getString(PrefConstants.AUTHOR_INFO_ORG)); - - // Set Cathy product as the workbook creator. - Core.getWorkbookBuilder().setCreator("XMind", buildId); //$NON-NLS-1$ - - // Create the default display instance. - Display display = PlatformUI.createDisplay(); - - try { - // Install global OpenDocument listener: - OpenDocumentQueue.getInstance().hook(display); - - /// Activate network proxy settings. On Linux, we need a - /// UI environment to show a dialog for retrieving the master - /// password of the secure storage containing proxy server - /// credentials. - CathyPlugin.getDefault().activateNetworkSettings(); - - // Check if we are in beta and should quit due to beta expiry. - if (new BetaVerifier(display).shouldExitAfterBetaExpired()) - return EXIT_OK; - - // Check if this app session should exit early: - if (shouldExitEarly(context)) { - // Log all application arguments to local disk to exchange - // between running XMind instances: - logApplicationArgs(); - return EXIT_OK; - } - - // Log all application arguments to local disk to exchange - // between running XMind instances: - logApplicationArgs(); - - // Mark application status to 'starting': - System.setProperty(SYS_APP_STATUS, "starting"); //$NON-NLS-1$ - - // Set cookies to let web pages loaded within internal web browser - // to recognize the environment: - initializeInternalBrowserCookies(); - - //Close model's auto-save to avoid repeated model elements - //which application exits non-normally: - WorkbenchPlugin.getDefault().getPreferenceStore() - .setValue(IPreferenceConstants.WORKBENCH_SAVE_INTERVAL, 0); - - try { - captureAppSessionInfo( - CathyPlugin.getDefault().getUsageDataCollector(), - context, buildId); - - // Launch workbench and get return code: - int returnCode = PlatformUI.createAndRunWorkbench(display, - new CathyWorkbenchAdvisor()); - - if (returnCode == PlatformUI.RETURN_RESTART) { - // Restart: - return EXIT_RESTART; - } - - // Quit: - return EXIT_OK; - } finally { - CathyPlugin.getDefault().getUsageDataCollector().put( - "ShutDownTime", //$NON-NLS-1$ - System.currentTimeMillis()); - } - } finally { - display.dispose(); - } - } - - /** - * @param sampler - * @param context - * @param buildId - */ - private void captureAppSessionInfo(IUsageDataSampler sampler, - IApplicationContext context, String buildId) { - sampler.put("StartUpTime", //$NON-NLS-1$ - System.currentTimeMillis()); - sampler.put("AppId", //$NON-NLS-1$ - context.getBrandingApplication()); - sampler.put("BuildId", buildId); //$NON-NLS-1$ - sampler.put("DistributionId", //$NON-NLS-1$ - System.getProperty("org.xmind.product.distribution.id", //$NON-NLS-1$ - null)); - sampler.put("NL", Platform.getNL()); //$NON-NLS-1$ - sampler.put("OS", Platform.getOS()); //$NON-NLS-1$ - sampler.put("Arch", Platform.getOSArch()); //$NON-NLS-1$ - sampler.put("OSName", System.getProperty("os.name", null)); //$NON-NLS-1$ //$NON-NLS-2$ - sampler.put("OSVersion", System.getProperty("os.version", null)); //$NON-NLS-1$ //$NON-NLS-2$ - sampler.put("Country", System.getProperty("user.country", null)); //$NON-NLS-1$ //$NON-NLS-2$ - sampler.put("JavaVersion", System.getProperty("java.version", null)); //$NON-NLS-1$ //$NON-NLS-2$ - sampler.put("JavaVendor", System.getProperty("java.vendor", null)); //$NON-NLS-1$ //$NON-NLS-2$ - sampler.put("ScreenWidth", //$NON-NLS-1$ - Toolkit.getDefaultToolkit().getScreenSize().width); - sampler.put("ScreenHeight", //$NON-NLS-1$ - Toolkit.getDefaultToolkit().getScreenSize().height); - sampler.put("ScreenResolution", //$NON-NLS-1$ - Toolkit.getDefaultToolkit().getScreenResolution()); - - } - - private static String calculateBuildId(IApplicationContext context) { - String buildId = System.getProperty("eclipse.buildId"); //$NON-NLS-1$ - if (buildId != null && !"".equals(buildId)) //$NON-NLS-1$ - return buildId; - return context.getBrandingBundle().getVersion().toString(); - } - - private static String extractVersionNumber(String buildId) { - String[] numbers = buildId.split("\\."); //$NON-NLS-1$ - StringBuilder buffer = new StringBuilder(10); - for (int i = 0; i < 3; i++) { - if (i >= numbers.length) - break; - if (buffer.length() > 0) { - buffer.append('.'); - } - buffer.append(numbers[i]); - } - return buffer.toString(); - } - - private void initializeInternalBrowserCookies() { - String appVersion = System.getProperty(SYS_VERSION); - Browser.setCookie( - "_env=xmind_" + appVersion //$NON-NLS-1$ - + "; path=/; domain=.xmind.net", //$NON-NLS-1$ - "http://www.xmind.net/"); //$NON-NLS-1$ - } - - private void logApplicationArgs() { - final String[] args = Platform.getApplicationArgs(); - if (args == null || args.length == 0) - return; - - Log openingLog = Log.get(Log.OPENING); - for (String arg : args) { - if ("-p".equals(arg)) {//$NON-NLS-1$ - // The "-p" argument is used to start Presentation Mode - // immediately on startup: - System.setProperty("org.xmind.cathy.startup.presentation", //$NON-NLS-1$ - "true"); //$NON-NLS-1$ - } else if (arg.startsWith("xmind:") || new File(arg).exists()) { //$NON-NLS-1$ - // Add xmind command or existing file path to '.opening' log: - openingLog.append(arg); - } else if (!arg.startsWith("-psn_0_")) { //$NON-NLS-1$ - // The "-psn_0_" argument is passed in by - // Mac OS X for each GUI application. No need to log that. - // Log any other unknown command line argument for debugging: - CathyPlugin.log("Skip unrecognized command line argument: '" //$NON-NLS-1$ - + arg + "'"); //$NON-NLS-1$ - } - } - } - - private boolean shouldExitEarly(IApplicationContext appContext) - throws Exception { - IExtensionPoint extPoint = Platform.getExtensionRegistry() - .getExtensionPoint( - "org.xmind.ui.toolkit.applicationValidators"); //$NON-NLS-1$ - if (extPoint != null) { - for (IExtension ext : extPoint.getExtensions()) { - for (IConfigurationElement validatorElement : ext - .getConfigurationElements()) { - if ("applicationValidator" //$NON-NLS-1$ - .equals(validatorElement.getName())) { - Object validator = validatorElement - .createExecutableExtension( - IWorkbenchRegistryConstants.ATT_CLASS); - if (validator instanceof IApplicationValidator - && ((IApplicationValidator) validator) - .shouldApplicationExitEarly( - appContext)) { - return true; - } - } - } - } - } - - return false; - } - - /** - * @see org.eclipse.equinox.app.IApplication#stop() - */ - public void stop() { - if (!PlatformUI.isWorkbenchRunning()) - return; - - final IWorkbench workbench = PlatformUI.getWorkbench(); - if (workbench == null) - return; - - Display display = workbench.getDisplay(); - if (display == null || display.isDisposed()) - return; - - display.syncExec(new Runnable() { - public void run() { - workbench.close(); - } - }); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.awt.Toolkit; +import java.io.File; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; +import org.xmind.core.Core; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.DOMConstants; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.app.IApplicationValidator; +import org.xmind.ui.prefs.PrefConstants; + +/** + * This class controls all aspects of the application's execution + */ +public class CathyApplication implements IApplication { + + public static final String SYS_VERSION = "org.xmind.product.version"; //$NON-NLS-1$ + + public static final String SYS_BUILDID = "org.xmind.product.buildid"; //$NON-NLS-1$ + + public static final String SYS_BRANDING_VERSION = "org.xmind.product.brandingVersion"; //$NON-NLS-1$ + + public static final String SYS_APP_STATUS = "org.xmind.cathy.app.status"; //$NON-NLS-1$ + + /** + * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) + */ + public Object start(IApplicationContext context) throws Exception { + // Check product information. + // Product build id and version may have been set in config.ini. + // If not set, calculate them using runtime properties. + String buildId = System.getProperty(SYS_BUILDID); + if (buildId == null || "".equals(buildId)) { //$NON-NLS-1$ + buildId = calculateBuildId(context); + System.setProperty(SYS_BUILDID, buildId); + } + String appVersion = System.getProperty(SYS_VERSION); + if (appVersion == null || "".equals(appVersion)) { //$NON-NLS-1$ + appVersion = extractVersionNumber(buildId); + System.setProperty(SYS_VERSION, appVersion); + } + + System.setProperty("org.xmind.product.about.copyright", //$NON-NLS-1$ + WorkbenchMessages.About_Copyright); + System.setProperty("org.xmind.product.about.homepage", //$NON-NLS-1$ + WorkbenchMessages.About_Homepage); + + IPreferenceStore pref = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + + String name = pref.getString(PrefConstants.AUTHOR_INFO_NAME); + + if (name == null || "".equals(name)) //$NON-NLS-1$ + name = System.getProperty("user.name"); //$NON-NLS-1$ + if (name != null) + System.setProperty(DOMConstants.AUTHOR_NAME, name); + + if (pref.getString(PrefConstants.AUTHOR_INFO_EMAIL) != null) + System.setProperty(DOMConstants.AUTHOR_EMAIL, + pref.getString(PrefConstants.AUTHOR_INFO_EMAIL)); + + if (pref.getString(PrefConstants.AUTHOR_INFO_ORG) != null) + System.setProperty(DOMConstants.AUTHOR_ORG, + pref.getString(PrefConstants.AUTHOR_INFO_ORG)); + + // Set Cathy product as the workbook creator. + Core.getWorkbookBuilder().setCreator("XMind", buildId); //$NON-NLS-1$ + + // Create the default display instance. + Display display = PlatformUI.createDisplay(); + + try { + // Install global OpenDocument listener: + OpenDocumentQueue.getInstance().hook(display); + + /// Activate network proxy settings. On Linux, we need a + /// UI environment to show a dialog for retrieving the master + /// password of the secure storage containing proxy server + /// credentials. + CathyPlugin.getDefault().activateNetworkSettings(); + + // Check if we are in beta and should quit due to beta expiry. + if (new BetaVerifier(display).shouldExitAfterBetaExpired()) + return EXIT_OK; + + // Check if this app session should exit early: + if (shouldExitEarly(context)) { + // Log all application arguments to local disk to exchange + // between running XMind instances: + logApplicationArgs(); + return EXIT_OK; + } + + // Log all application arguments to local disk to exchange + // between running XMind instances: + logApplicationArgs(); + + // Mark application status to 'starting': + System.setProperty(SYS_APP_STATUS, "starting"); //$NON-NLS-1$ + + // Set cookies to let web pages loaded within internal web browser + // to recognize the environment: + initializeInternalBrowserCookies(); + + //Close model's auto-save to avoid repeated model elements + //which application exits non-normally: + WorkbenchPlugin.getDefault().getPreferenceStore() + .setValue(IPreferenceConstants.WORKBENCH_SAVE_INTERVAL, 0); + + try { + captureAppSessionInfo( + CathyPlugin.getDefault().getUsageDataCollector(), + context, buildId); + + // Launch workbench and get return code: + int returnCode = PlatformUI.createAndRunWorkbench(display, + new CathyWorkbenchAdvisor()); + + if (returnCode == PlatformUI.RETURN_RESTART) { + // Restart: + return EXIT_RESTART; + } + + // Quit: + return EXIT_OK; + } finally { + CathyPlugin.getDefault().getUsageDataCollector().put( + UserDataConstants.SHUT_DOWN_TIME, + System.currentTimeMillis()); + } + } finally { + display.dispose(); + } + } + + /** + * @param sampler + * @param context + * @param buildId + */ + private void captureAppSessionInfo(IUsageDataSampler sampler, + IApplicationContext context, String buildId) { + sampler.put(UserDataConstants.START_UP_TIME, + System.currentTimeMillis()); + sampler.put(UserDataConstants.APP_ID, context.getBrandingApplication()); + sampler.put(UserDataConstants.BUILD_ID, buildId); + sampler.put(UserDataConstants.DISTRIBUTION_ID, + System.getProperty("org.xmind.product.distribution.id", //$NON-NLS-1$ + null)); + sampler.put(UserDataConstants.NL, Platform.getNL()); + sampler.put(UserDataConstants.OS, Platform.getOS()); + sampler.put(UserDataConstants.ARCH, Platform.getOSArch()); + sampler.put(UserDataConstants.OS_NAME, + System.getProperty("os.name", null)); //$NON-NLS-1$ + sampler.put(UserDataConstants.OS_VERSION, + System.getProperty("os.version", null)); //$NON-NLS-1$ + sampler.put(UserDataConstants.COUNTRY, + System.getProperty("user.country", null)); //$NON-NLS-1$ + sampler.put(UserDataConstants.JAVA_VERSION, + System.getProperty("java.version", null)); //$NON-NLS-1$ + sampler.put(UserDataConstants.JAVA_VENDOR, + System.getProperty("java.vendor", null)); //$NON-NLS-1$ + sampler.put(UserDataConstants.SCREEN_WIDTH, + Toolkit.getDefaultToolkit().getScreenSize().width); + sampler.put(UserDataConstants.SCREEN_HEIGHT, + Toolkit.getDefaultToolkit().getScreenSize().height); + sampler.put(UserDataConstants.SCREEN_RESOLUTION, + Toolkit.getDefaultToolkit().getScreenResolution()); + + } + + private static String calculateBuildId(IApplicationContext context) { + String buildId = System.getProperty("eclipse.buildId"); //$NON-NLS-1$ + if (buildId != null && !"".equals(buildId)) //$NON-NLS-1$ + return buildId; + return context.getBrandingBundle().getVersion().toString(); + } + + private static String extractVersionNumber(String buildId) { + String[] numbers = buildId.split("\\."); //$NON-NLS-1$ + StringBuilder buffer = new StringBuilder(10); + for (int i = 0; i < 3; i++) { + if (i >= numbers.length) + break; + if (buffer.length() > 0) { + buffer.append('.'); + } + buffer.append(numbers[i]); + } + return buffer.toString(); + } + + private void initializeInternalBrowserCookies() { + String appVersion = System.getProperty(SYS_VERSION); + Browser.setCookie( + "_env=xmind_" + appVersion //$NON-NLS-1$ + + "; path=/; domain=.xmind.net", //$NON-NLS-1$ + "http://www.xmind.net/"); //$NON-NLS-1$ + } + + private void logApplicationArgs() { + final String[] args = Platform.getApplicationArgs(); + if (args == null || args.length == 0) + return; + + Log openingLog = Log.get(Log.OPENING); + for (String arg : args) { + if ("-p".equals(arg)) {//$NON-NLS-1$ + // The "-p" argument is used to start Presentation Mode + // immediately on startup: + System.setProperty("org.xmind.cathy.startup.presentation", //$NON-NLS-1$ + "true"); //$NON-NLS-1$ + } else if (arg.startsWith("xmind:") || new File(arg).exists()) { //$NON-NLS-1$ + // Add xmind command or existing file path to '.opening' log: + openingLog.append(arg); + } else if (!arg.startsWith("-psn_0_")) { //$NON-NLS-1$ + // The "-psn_0_" argument is passed in by + // Mac OS X for each GUI application. No need to log that. + // Log any other unknown command line argument for debugging: + CathyPlugin.log("Skip unrecognized command line argument: '" //$NON-NLS-1$ + + arg + "'"); //$NON-NLS-1$ + } + } + } + + private boolean shouldExitEarly(IApplicationContext appContext) + throws Exception { + IExtensionPoint extPoint = Platform.getExtensionRegistry() + .getExtensionPoint( + "org.xmind.ui.toolkit.applicationValidators"); //$NON-NLS-1$ + if (extPoint != null) { + for (IExtension ext : extPoint.getExtensions()) { + for (IConfigurationElement validatorElement : ext + .getConfigurationElements()) { + if ("applicationValidator" //$NON-NLS-1$ + .equals(validatorElement.getName())) { + Object validator = validatorElement + .createExecutableExtension( + IWorkbenchRegistryConstants.ATT_CLASS); + if (validator instanceof IApplicationValidator + && ((IApplicationValidator) validator) + .shouldApplicationExitEarly( + appContext)) { + return true; + } + } + } + } + } + + return false; + } + + /** + * @see org.eclipse.equinox.app.IApplication#stop() + */ + public void stop() { + if (!PlatformUI.isWorkbenchRunning()) + return; + + final IWorkbench workbench = PlatformUI.getWorkbench(); + if (workbench == null) + return; + + Display display = workbench.getDisplay(); + if (display == null || display.isDisposed()) + return; + + display.syncExec(new Runnable() { + public void run() { + workbench.close(); + } + }); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPlugin.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPlugin.java index d077c2e8a..32794f856 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPlugin.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPlugin.java @@ -1,530 +1,530 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.util.Enumeration; -import java.util.Properties; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.core.runtime.Status; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; -import org.xmind.core.Core; -import org.xmind.core.internal.runtime.WorkspaceConfigurer; -import org.xmind.core.internal.runtime.WorkspaceSession; -import org.xmind.core.licensing.ILicenseAgent; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.ui.internal.app.ApplicationConstants; -import org.xmind.ui.internal.statushandlers.DefaultErrorReporter; -import org.xmind.ui.internal.statushandlers.IErrorReporter; - -/*---- BAD BOY HANDSOME DEBUT, DO NOT TOUCH ME ----*/ -/*---- BEGIN IMPORT ----*/ -/*---- END IMPORT ----*/ -/*---- BAD BOY PERFECT CURTAIN CALL, DO NOT TOUCH ME ----*/ - -/** - * The main plugin class to be used in the desktop. - */ -public class CathyPlugin extends AbstractUIPlugin { - - public static final String PLUGIN_ID = "org.xmind.cathy"; //$NON-NLS-1$ - - /** - * Boolean value:
- *
    - *
  • true to enable auto saving service when there's opened - * workbooks
  • - *
  • false to disable this service
  • - *
- */ - public static final String AUTO_SAVE_ENABLED = "autoSaveEnabled"; //$NON-NLS-1$ - - /** - * Integer value:
- * the intervals (in minutes) between auto saving actions - */ - public static final String AUTO_SAVE_INTERVALS = "autoSaveIntervals"; //$NON-NLS-1$ - - /** - * (Deprecated, use {@link #STARTUP_ACTION} instead) Boolean value:
- *
    - *
  • true to remember unclosed workbooks when XMind quits and - * open them next time XMind starts
  • - *
  • false to always open a bootstrap workbook when XMind - * opens
  • - *
- */ - public static final String RESTORE_LAST_SESSION = "restoreLastSession"; //$NON-NLS-1$ - - /** - * Boolean value:
- *
    - *
  • true to check updates when XMind starts
  • - *
  • false to skip update checking when XMind starts
  • - *
- */ - public static final String CHECK_UPDATES_ON_STARTUP = "checkUpdatesOnStartup"; //$NON-NLS-1$ - - /** - * Integer value (enumerated):
- *
    - *
  • 0({@link #STARTUP_ACTION_WIZARD}): opens a 'New - * Workbook' wizard dialog on startup
  • - *
  • 1({@link #STARTUP_ACTION_BLANK}): opens a blank map on - * startup
  • - *
  • 2({@link #STARTUP_ACTION_HOME}): opens the home map on - * startup
  • - *
  • 3({@link #STARTUP_ACTION_LAST}): opens last session on - * startup
  • - *
- */ - public static final String STARTUP_ACTION = "startupAction2"; //$NON-NLS-1$ - - /** - * Integer preference store value for opening a 'New Workbook' wizard dialog - * on startup. (value=0) - * - * @see #STARTUP_ACTION - */ - public static final int STARTUP_ACTION_WIZARD = 0; - - /** - * Integer preference store value for opening a blank map on startup. - * (value=1) - * - * @see #STARTUP_ACTION - */ - public static final int STARTUP_ACTION_BLANK = 1; - - /** - * Integer preference store value for opening the home map on startup. - * (value=2) - * - * @see #STARTUP_ACTION - */ - public static final int STARTUP_ACTION_HOME = 2; - - /** - * Integer preference store value for opening last session on startup. - * (value=3) - * - * @see #STARTUP_ACTION - */ - public static final int STARTUP_ACTION_LAST = 3; - - /** - * Boolean value:
- *
    - *
  • true to hide system notifications (usually pushed to the - * user by pop-up windows)
  • - *
  • false to show system notifications
  • - *
- */ - //public static final String HIDE_NOTIFICATIONS = "hideNotifications"; //$NON-NLS-1$ - - /** - * String constants identifying the extension part of a XMind command file - * name. - */ - public static final String COMMAND_FILE_EXT = ".xmind-command"; //$NON-NLS-1$ - - /** - * Online help page. - */ - public static final String ONLINE_HELP_URL = "https://www.xmind.net/xmind/help"; //$NON-NLS-1$ - - /** - * Boolean value:
- *
    - *
  • true to upload usage data to XMind server
  • - *
  • false to skip uploading usage data
  • - *
- */ - public static final String USAGE_DATA_UPLOADING_ENABLED = "usageDataUploadingEnabled"; //$NON-NLS-1$ - - /** - * One minute delay between two auto save operations. - */ - public static final int AUTO_SAVE_EDITOR_STATE_INTERVALS = 60000; - public static final String OPTION_AUTO_SAVE_EDITOR_STATE_INTERVALS = "/debug/autoSaveEditorStateIntervals"; //$NON-NLS-1$ - - // The shared instance. - private static CathyPlugin plugin; - - private ServiceTracker debugTracker; - - private WorkspaceSession xmindWorkspaceSession; - - private IUsageDataSampler usageDataSampler; - - private IErrorReporter errorReporter; - - private LicenseAgentProxy licenseAgent; - - private ILogger logger; - - /** - * The constructor. - */ - public CathyPlugin() { - plugin = this; - } - - /** - * This method is called upon plug-in activation - */ - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - - /*---- BAD BOY HANDSOME DEBUT, DO NOT TOUCH ME ----*/ - /*---- BEGIN INSERT ----*/ - /*---- END INSERT ----*/ - /*---- BAD BOY PERFECT CURTAIN CALL, DO NOT TOUCH ME ----*/ - - usageDataSampler = IUsageDataSampler.NULL; - errorReporter = DefaultErrorReporter.getInstance(); - licenseAgent = new LicenseAgentProxy(); - - logger = new ILogger() { - - public void logWarning(String message, Throwable error) { - getLog().log(toStatus(IStatus.ERROR, message, error)); - } - - public void logInfo(String message, Throwable error) { - getLog().log(toStatus(IStatus.WARNING, message, error)); - } - - public void logError(String message, Throwable error) { - getLog().log(toStatus(IStatus.INFO, message, error)); - } - - private IStatus toStatus(int severity, String message, - Throwable error) { - if (message == null) { - message = error.getMessage(); - } - return new Status(severity, PLUGIN_ID, message, error); - } - }; - -// activateNetworkSettings(); - - activateXMindCore(); - - /* - * We have to manually activate 'org.xmind.ui' plugin so that command - * handler classes contributed by that plugin can be loaded upon - * startup. This ensures that IElementUpdater implementations and - * enablement updates to behave correctly. For example, the class - * org.xmind.ui.internal.handlers.ClearWorkbookHistoryHandler should be - * loaded on startup so that its enablement state can be correctly - * updated, otherwise the command in menu will be shown as enabled even - * when it should not be. - */ - activateMindMapUIContributions(); - - hackConstants(); - - upgradeWorkspace(); - - } - -// usageDataCollector.setUploadEnabled(getPreferenceStore() -// .getBoolean(USAGE_DATA_UPLOADING_ENABLED)); - - private void hackConstants() { - ConstantsHacker.hack(); - } - - /** - * This method is called when the plug-in is stopped - */ - @Override - public void stop(BundleContext context) throws Exception { - if (xmindWorkspaceSession != null) { - xmindWorkspaceSession.close(); - xmindWorkspaceSession = null; - } - - licenseAgent = null; - - super.stop(context); - plugin = null; - } - - public void activateNetworkSettings() { - Bundle networkPlugin = Platform.getBundle("org.eclipse.core.net"); //$NON-NLS-1$ - if (networkPlugin != null) { - try { - networkPlugin - .loadClass("org.eclipse.core.internal.net.Activator"); //$NON-NLS-1$ - } catch (ClassNotFoundException e) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, - "Failed to activate plugin 'org.eclipse.core.net'.", //$NON-NLS-1$ - e)); - } - } else { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, - "Plugin 'org.eclipse.core.net' not found. Network proxies may not be correct.")); //$NON-NLS-1$ - } - } - - private void activateXMindCore() throws CoreException { - WorkspaceConfigurer.setDefaultWorkspaceLocation( - WorkspaceConfigurer.INSTANCE_LOCATION); - - xmindWorkspaceSession = WorkspaceSession - .openSessionIn(new File(Core.getWorkspace().getTempDir())); - } - - private void activateMindMapUIContributions() { - Bundle uiPlugin = Platform.getBundle("org.xmind.ui"); //$NON-NLS-1$ - if (uiPlugin != null) { - try { - uiPlugin.loadClass("org.xmind.ui.internal.XmindUIPlugin"); //$NON-NLS-1$ - } catch (ClassNotFoundException e) { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, - "Failed to activate plugin 'org.xmind.ui'.", //$NON-NLS-1$ - e)); - } - } else { - getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, - "Plugin 'org.xmind.ui' is not found.")); //$NON-NLS-1$ - } - } - - /** - * @return the logger - */ - public ILogger getLogger() { - return logger; - } - - /** - * Returns the distribution identifier of this XMind product. - * - * @return the distribution identifier of this XMind product - * @deprecated Use system property - * "org.xmind.product.distribution.id" - */ - public static String getDistributionId() { - String distribId = System - .getProperty(ApplicationConstants.PRODUCT_DISTRIBITION_ID); - if (distribId == null || "".equals(distribId)) { //$NON-NLS-1$ - distribId = "cathy_portable"; //$NON-NLS-1$ - } - return distribId; - } - - public DebugOptions getDebugOptions() { - if (debugTracker == null) { - debugTracker = new ServiceTracker( - getBundle().getBundleContext(), - DebugOptions.class.getName(), null); - debugTracker.open(); - } - return debugTracker.getService(); - } - - public boolean isDebugging(String option) { - DebugOptions debugOptions = getDebugOptions(); - return debugOptions != null && debugOptions.isDebugEnabled() - && debugOptions.getBooleanOption(PLUGIN_ID + option, false); - } - - public String getDebugValue(String option) { - DebugOptions debugOptions = getDebugOptions(); - return debugOptions == null ? null - : debugOptions.getOption(PLUGIN_ID + option, null); - } - - public int getDebugValue(String option, int defaultValue) { - DebugOptions debugOptions = getDebugOptions(); - return debugOptions == null ? defaultValue - : debugOptions.getIntegerOption(PLUGIN_ID + option, - defaultValue); - } - - public Properties loadNLSProperties(String pathBase) { - return doLoadNLSProperties(getBundle(), pathBase); - } - - public IUsageDataSampler getUsageDataCollector() { - return usageDataSampler; - } - - void setUsageDataCollector(IUsageDataSampler sampler) { - this.usageDataSampler = sampler == null ? IUsageDataSampler.NULL - : sampler; - } - - /** - * @return - */ - public IErrorReporter getErrorReporter() { - return errorReporter; - } - - void setErrorReporter(IErrorReporter reporter) { - this.errorReporter = reporter == null - ? DefaultErrorReporter.getInstance() : reporter; - } - - public ILicenseAgent getLicenseAgent() { - return licenseAgent; - } - - void setLicenseAgent(ILicenseAgent agent) { - this.licenseAgent.setDelegate(agent); - } - - private void upgradeWorkspace() { - IPath stateLocation; - try { - stateLocation = Platform.getStateLocation(getBundle()); - } catch (Exception e) { - return; - } - String versionFileName = String.format("workspace-upgraded-v%s", //$NON-NLS-1$ - getBundle().getVersion().toString()); - File versionFile = stateLocation.append(versionFileName).toFile(); - if (versionFile.exists()) - return; - - /// delete old workbench state on first launch - File workbenchFile = stateLocation.removeLastSegments(1) - .append("org.eclipse.e4.workbench") //$NON-NLS-1$ - .append("workbench.xmi") //$NON-NLS-1$ - .toFile(); - if (workbenchFile.exists()) { - workbenchFile.delete(); - } - - try { - File parentDir = versionFile.getParentFile(); - if (parentDir != null) - parentDir.mkdirs(); - OutputStream output = new FileOutputStream(versionFile); - try { - output.write("done".getBytes()); //$NON-NLS-1$ - } finally { - output.close(); - } - } catch (IOException e) { - } - } - - /** - * Returns the shared instance. - * - * @return the shared instance. - */ - public static CathyPlugin getDefault() { - return plugin; - } - - public static void log(Throwable e, String message) { - if (message == null) - message = ""; //$NON-NLS-1$ - getDefault().getLog() - .log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } - - public static void log(String message) { - if (message == null) - message = ""; //$NON-NLS-1$ - getDefault().getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - - private static Properties doLoadNLSProperties(Bundle bundle, - String pathBase) { - Properties properties = new Properties(); - - String nl = Platform.getNL(); - String[] nlSegments = nl.split("_"); //$NON-NLS-1$ - URL entry; - for (int i = 0; i <= nlSegments.length; i++) { - StringBuilder nlsName = new StringBuilder(pathBase); - for (int j = 0; j < i; j++) { - nlsName.append('_'); - nlsName.append(nlSegments[j]); - } - nlsName.append(".properties"); //$NON-NLS-1$ - entry = findSingleEntry(bundle, nlsName.toString()); - if (entry != null) { - try { - InputStream stream = entry.openStream(); - try { - properties.load(stream); - } finally { - stream.close(); - } - } catch (IOException e) { - // ignore - } - } - } - - return properties; - } - - private static URL findSingleEntry(Bundle bundle, String path) { - int sepIndex = path.lastIndexOf('/'); - String dir, name; - if (sepIndex < 0) { - dir = "/"; //$NON-NLS-1$ - name = path; - } else { - dir = path.substring(0, sepIndex); - name = path.substring(sepIndex + 1); - } - Enumeration entries = bundle.findEntries(dir, name, true); - return entries != null && entries.hasMoreElements() - ? entries.nextElement() : null; - } - - public static T getAdapter(Object obj, Class adapter) { - if (adapter.isInstance(obj)) - return adapter.cast(obj); - - if (obj instanceof IAdaptable) { - T result = ((IAdaptable) obj).getAdapter(adapter); - if (result != null) - return result; - } - - if (!(obj instanceof PlatformObject)) - return Platform.getAdapterManager().getAdapter(obj, adapter); - - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.Properties; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; +import org.xmind.core.Core; +import org.xmind.core.internal.runtime.WorkspaceConfigurer; +import org.xmind.core.internal.runtime.WorkspaceSession; +import org.xmind.core.licensing.ILicenseAgent; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.ui.internal.app.ApplicationConstants; +import org.xmind.ui.internal.statushandlers.DefaultErrorReporter; +import org.xmind.ui.internal.statushandlers.IErrorReporter; + +/*---- BAD BOY HANDSOME DEBUT, DO NOT TOUCH ME ----*/ +/*---- BEGIN IMPORT ----*/ +/*---- END IMPORT ----*/ +/*---- BAD BOY PERFECT CURTAIN CALL, DO NOT TOUCH ME ----*/ + +/** + * The main plugin class to be used in the desktop. + */ +public class CathyPlugin extends AbstractUIPlugin { + + public static final String PLUGIN_ID = "org.xmind.cathy"; //$NON-NLS-1$ + + /** + * Boolean value:
+ *
    + *
  • true to enable auto saving service when there's opened + * workbooks
  • + *
  • false to disable this service
  • + *
+ */ + public static final String AUTO_SAVE_ENABLED = "autoSaveEnabled"; //$NON-NLS-1$ + + /** + * Integer value:
+ * the intervals (in minutes) between auto saving actions + */ + public static final String AUTO_SAVE_INTERVALS = "autoSaveIntervals"; //$NON-NLS-1$ + + /** + * (Deprecated, use {@link #STARTUP_ACTION} instead) Boolean value:
+ *
    + *
  • true to remember unclosed workbooks when XMind quits and + * open them next time XMind starts
  • + *
  • false to always open a bootstrap workbook when XMind + * opens
  • + *
+ */ + public static final String RESTORE_LAST_SESSION = "restoreLastSession"; //$NON-NLS-1$ + + /** + * Boolean value:
+ *
    + *
  • true to check updates when XMind starts
  • + *
  • false to skip update checking when XMind starts
  • + *
+ */ + public static final String CHECK_UPDATES_ON_STARTUP = "checkUpdatesOnStartup"; //$NON-NLS-1$ + + /** + * Integer value (enumerated):
+ *
    + *
  • 0({@link #STARTUP_ACTION_WIZARD}): opens a 'New + * Workbook' wizard dialog on startup
  • + *
  • 1({@link #STARTUP_ACTION_BLANK}): opens a blank map on + * startup
  • + *
  • 2({@link #STARTUP_ACTION_HOME}): opens the home map on + * startup
  • + *
  • 3({@link #STARTUP_ACTION_LAST}): opens last session on + * startup
  • + *
+ */ + public static final String STARTUP_ACTION = "startupAction2"; //$NON-NLS-1$ + + /** + * Integer preference store value for opening a 'New Workbook' wizard dialog + * on startup. (value=0) + * + * @see #STARTUP_ACTION + */ + public static final int STARTUP_ACTION_WIZARD = 0; + + /** + * Integer preference store value for opening a blank map on startup. + * (value=1) + * + * @see #STARTUP_ACTION + */ + public static final int STARTUP_ACTION_BLANK = 1; + + /** + * Integer preference store value for opening the home map on startup. + * (value=2) + * + * @see #STARTUP_ACTION + */ + public static final int STARTUP_ACTION_HOME = 2; + + /** + * Integer preference store value for opening last session on startup. + * (value=3) + * + * @see #STARTUP_ACTION + */ + public static final int STARTUP_ACTION_LAST = 3; + + /** + * Boolean value:
+ *
    + *
  • true to hide system notifications (usually pushed to the + * user by pop-up windows)
  • + *
  • false to show system notifications
  • + *
+ */ + //public static final String HIDE_NOTIFICATIONS = "hideNotifications"; //$NON-NLS-1$ + + /** + * String constants identifying the extension part of a XMind command file + * name. + */ + public static final String COMMAND_FILE_EXT = ".xmind-command"; //$NON-NLS-1$ + + /** + * Online help page. + */ + public static final String ONLINE_HELP_URL = "https://www.xmind.net/xmind/help"; //$NON-NLS-1$ + + /** + * Boolean value:
+ *
    + *
  • true to upload usage data to XMind server
  • + *
  • false to skip uploading usage data
  • + *
+ */ + public static final String USAGE_DATA_UPLOADING_ENABLED = "usageDataUploadingEnabled"; //$NON-NLS-1$ + + /** + * One minute delay between two auto save operations. + */ + public static final int AUTO_SAVE_EDITOR_STATE_INTERVALS = 60000; + public static final String OPTION_AUTO_SAVE_EDITOR_STATE_INTERVALS = "/debug/autoSaveEditorStateIntervals"; //$NON-NLS-1$ + + // The shared instance. + private static CathyPlugin plugin; + + private ServiceTracker debugTracker; + + private WorkspaceSession xmindWorkspaceSession; + + private IUsageDataSampler usageDataSampler; + + private IErrorReporter errorReporter; + + private LicenseAgentProxy licenseAgent; + + private ILogger logger; + + /** + * The constructor. + */ + public CathyPlugin() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + + /*---- BAD BOY HANDSOME DEBUT, DO NOT TOUCH ME ----*/ + /*---- BEGIN INSERT ----*/ + /*---- END INSERT ----*/ + /*---- BAD BOY PERFECT CURTAIN CALL, DO NOT TOUCH ME ----*/ + + usageDataSampler = IUsageDataSampler.NULL; + errorReporter = DefaultErrorReporter.getInstance(); + licenseAgent = new LicenseAgentProxy(); + + logger = new ILogger() { + + public void logWarning(String message, Throwable error) { + getLog().log(toStatus(IStatus.ERROR, message, error)); + } + + public void logInfo(String message, Throwable error) { + getLog().log(toStatus(IStatus.WARNING, message, error)); + } + + public void logError(String message, Throwable error) { + getLog().log(toStatus(IStatus.INFO, message, error)); + } + + private IStatus toStatus(int severity, String message, + Throwable error) { + if (message == null) { + message = error.getMessage(); + } + return new Status(severity, PLUGIN_ID, message, error); + } + }; + +// activateNetworkSettings(); + + activateXMindCore(); + + /* + * We have to manually activate 'org.xmind.ui' plugin so that command + * handler classes contributed by that plugin can be loaded upon + * startup. This ensures that IElementUpdater implementations and + * enablement updates to behave correctly. For example, the class + * org.xmind.ui.internal.handlers.ClearWorkbookHistoryHandler should be + * loaded on startup so that its enablement state can be correctly + * updated, otherwise the command in menu will be shown as enabled even + * when it should not be. + */ + activateMindMapUIContributions(); + + hackConstants(); + + upgradeWorkspace(); + + } + +// usageDataCollector.setUploadEnabled(getPreferenceStore() +// .getBoolean(USAGE_DATA_UPLOADING_ENABLED)); + + private void hackConstants() { + ConstantsHacker.hack(); + } + + /** + * This method is called when the plug-in is stopped + */ + @Override + public void stop(BundleContext context) throws Exception { + if (xmindWorkspaceSession != null) { + xmindWorkspaceSession.close(); + xmindWorkspaceSession = null; + } + + licenseAgent = null; + + super.stop(context); + plugin = null; + } + + public void activateNetworkSettings() { + Bundle networkPlugin = Platform.getBundle("org.eclipse.core.net"); //$NON-NLS-1$ + if (networkPlugin != null) { + try { + networkPlugin + .loadClass("org.eclipse.core.internal.net.Activator"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, + "Failed to activate plugin 'org.eclipse.core.net'.", //$NON-NLS-1$ + e)); + } + } else { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, + "Plugin 'org.eclipse.core.net' not found. Network proxies may not be correct.")); //$NON-NLS-1$ + } + } + + private void activateXMindCore() throws CoreException { + WorkspaceConfigurer.setDefaultWorkspaceLocation( + WorkspaceConfigurer.INSTANCE_LOCATION); + + xmindWorkspaceSession = WorkspaceSession + .openSessionIn(new File(Core.getWorkspace().getTempDir())); + } + + private void activateMindMapUIContributions() { + Bundle uiPlugin = Platform.getBundle("org.xmind.ui"); //$NON-NLS-1$ + if (uiPlugin != null) { + try { + uiPlugin.loadClass("org.xmind.ui.internal.XmindUIPlugin"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, + "Failed to activate plugin 'org.xmind.ui'.", //$NON-NLS-1$ + e)); + } + } else { + getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, + "Plugin 'org.xmind.ui' is not found.")); //$NON-NLS-1$ + } + } + + /** + * @return the logger + */ + public ILogger getLogger() { + return logger; + } + + /** + * Returns the distribution identifier of this XMind product. + * + * @return the distribution identifier of this XMind product + * @deprecated Use system property + * "org.xmind.product.distribution.id" + */ + public static String getDistributionId() { + String distribId = System + .getProperty(ApplicationConstants.PRODUCT_DISTRIBITION_ID); + if (distribId == null || "".equals(distribId)) { //$NON-NLS-1$ + distribId = "cathy_portable"; //$NON-NLS-1$ + } + return distribId; + } + + public DebugOptions getDebugOptions() { + if (debugTracker == null) { + debugTracker = new ServiceTracker( + getBundle().getBundleContext(), + DebugOptions.class.getName(), null); + debugTracker.open(); + } + return debugTracker.getService(); + } + + public boolean isDebugging(String option) { + DebugOptions debugOptions = getDebugOptions(); + return debugOptions != null && debugOptions.isDebugEnabled() + && debugOptions.getBooleanOption(PLUGIN_ID + option, false); + } + + public String getDebugValue(String option) { + DebugOptions debugOptions = getDebugOptions(); + return debugOptions == null ? null + : debugOptions.getOption(PLUGIN_ID + option, null); + } + + public int getDebugValue(String option, int defaultValue) { + DebugOptions debugOptions = getDebugOptions(); + return debugOptions == null ? defaultValue + : debugOptions.getIntegerOption(PLUGIN_ID + option, + defaultValue); + } + + public Properties loadNLSProperties(String pathBase) { + return doLoadNLSProperties(getBundle(), pathBase); + } + + public IUsageDataSampler getUsageDataCollector() { + return usageDataSampler; + } + + void setUsageDataCollector(IUsageDataSampler sampler) { + this.usageDataSampler = sampler == null ? IUsageDataSampler.NULL + : sampler; + } + + /** + * @return + */ + public IErrorReporter getErrorReporter() { + return errorReporter; + } + + void setErrorReporter(IErrorReporter reporter) { + this.errorReporter = reporter == null + ? DefaultErrorReporter.getInstance() : reporter; + } + + public ILicenseAgent getLicenseAgent() { + return licenseAgent; + } + + void setLicenseAgent(ILicenseAgent agent) { + this.licenseAgent.setDelegate(agent); + } + + private void upgradeWorkspace() { + IPath stateLocation; + try { + stateLocation = Platform.getStateLocation(getBundle()); + } catch (Exception e) { + return; + } + String versionFileName = String.format("workspace-upgraded-v%s", //$NON-NLS-1$ + getBundle().getVersion().toString()); + File versionFile = stateLocation.append(versionFileName).toFile(); + if (versionFile.exists()) + return; + + /// delete old workbench state on first launch + File workbenchFile = stateLocation.removeLastSegments(1) + .append("org.eclipse.e4.workbench") //$NON-NLS-1$ + .append("workbench.xmi") //$NON-NLS-1$ + .toFile(); + if (workbenchFile.exists()) { + workbenchFile.delete(); + } + + try { + File parentDir = versionFile.getParentFile(); + if (parentDir != null) + parentDir.mkdirs(); + OutputStream output = new FileOutputStream(versionFile); + try { + output.write("done".getBytes()); //$NON-NLS-1$ + } finally { + output.close(); + } + } catch (IOException e) { + } + } + + /** + * Returns the shared instance. + * + * @return the shared instance. + */ + public static CathyPlugin getDefault() { + return plugin; + } + + public static void log(Throwable e, String message) { + if (message == null) + message = ""; //$NON-NLS-1$ + getDefault().getLog() + .log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + + public static void log(String message) { + if (message == null) + message = ""; //$NON-NLS-1$ + getDefault().getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + + private static Properties doLoadNLSProperties(Bundle bundle, + String pathBase) { + Properties properties = new Properties(); + + String nl = Platform.getNL(); + String[] nlSegments = nl.split("_"); //$NON-NLS-1$ + URL entry; + for (int i = 0; i <= nlSegments.length; i++) { + StringBuilder nlsName = new StringBuilder(pathBase); + for (int j = 0; j < i; j++) { + nlsName.append('_'); + nlsName.append(nlSegments[j]); + } + nlsName.append(".properties"); //$NON-NLS-1$ + entry = findSingleEntry(bundle, nlsName.toString()); + if (entry != null) { + try { + InputStream stream = entry.openStream(); + try { + properties.load(stream); + } finally { + stream.close(); + } + } catch (IOException e) { + // ignore + } + } + } + + return properties; + } + + private static URL findSingleEntry(Bundle bundle, String path) { + int sepIndex = path.lastIndexOf('/'); + String dir, name; + if (sepIndex < 0) { + dir = "/"; //$NON-NLS-1$ + name = path; + } else { + dir = path.substring(0, sepIndex); + name = path.substring(sepIndex + 1); + } + Enumeration entries = bundle.findEntries(dir, name, true); + return entries != null && entries.hasMoreElements() + ? entries.nextElement() : null; + } + + public static T getAdapter(Object obj, Class adapter) { + if (adapter.isInstance(obj)) + return adapter.cast(obj); + + if (obj instanceof IAdaptable) { + T result = ((IAdaptable) obj).getAdapter(adapter); + if (result != null) + return result; + } + + if (!(obj instanceof PlatformObject)) + return Platform.getAdapterManager().getAdapter(obj, adapter); + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPrefInitializer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPrefInitializer.java index e84154b78..551b8a1ad 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPrefInitializer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyPrefInitializer.java @@ -1,55 +1,55 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; -import org.eclipse.core.runtime.preferences.DefaultScope; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.IScopeContext; - -public class CathyPrefInitializer extends AbstractPreferenceInitializer { - - public CathyPrefInitializer() { - } - - public void initializeDefaultPreferences() { - IScopeContext context = DefaultScope.INSTANCE; - IEclipsePreferences node = context.getNode( - CathyPlugin.getDefault().getBundle().getSymbolicName()); - node.putBoolean(CathyPlugin.AUTO_SAVE_ENABLED, false); - node.putInt(CathyPlugin.AUTO_SAVE_INTERVALS, 5); - node.putBoolean(CathyPlugin.RESTORE_LAST_SESSION, false); - node.putBoolean(CathyPlugin.CHECK_UPDATES_ON_STARTUP, true); - node.putInt(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_WIZARD); - -// ColorRegistry colorRegistry = PlatformUI.getWorkbench() -// .getThemeManager().getCurrentTheme().getColorRegistry(); -// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_END", //$NON-NLS-1$ -// new RGB(191, 205, 219)); -// colorRegistry.put( -// "org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_START", //$NON-NLS-1$ -// new RGB(191, 205, 219)); -// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END", //$NON-NLS-1$ -// new RGB(153, 180, 209)); -// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START", //$NON-NLS-1$ -// new RGB(153, 180, 209)); -// colorRegistry.put("org.eclipse.ui.workbench.INACTIVE_TAB_BG_END", //$NON-NLS-1$ -// new RGB(240, 240, 240)); -// colorRegistry.put("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", //$NON-NLS-1$ -// new RGB(240, 240, 240)); - - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; + +public class CathyPrefInitializer extends AbstractPreferenceInitializer { + + public CathyPrefInitializer() { + } + + public void initializeDefaultPreferences() { + IScopeContext context = DefaultScope.INSTANCE; + IEclipsePreferences node = context.getNode( + CathyPlugin.getDefault().getBundle().getSymbolicName()); + node.putBoolean(CathyPlugin.AUTO_SAVE_ENABLED, false); + node.putInt(CathyPlugin.AUTO_SAVE_INTERVALS, 5); + node.putBoolean(CathyPlugin.RESTORE_LAST_SESSION, false); + node.putBoolean(CathyPlugin.CHECK_UPDATES_ON_STARTUP, true); + node.putInt(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_WIZARD); + +// ColorRegistry colorRegistry = PlatformUI.getWorkbench() +// .getThemeManager().getCurrentTheme().getColorRegistry(); +// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_END", //$NON-NLS-1$ +// new RGB(191, 205, 219)); +// colorRegistry.put( +// "org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_START", //$NON-NLS-1$ +// new RGB(191, 205, 219)); +// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END", //$NON-NLS-1$ +// new RGB(153, 180, 209)); +// colorRegistry.put("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START", //$NON-NLS-1$ +// new RGB(153, 180, 209)); +// colorRegistry.put("org.eclipse.ui.workbench.INACTIVE_TAB_BG_END", //$NON-NLS-1$ +// new RGB(240, 240, 240)); +// colorRegistry.put("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", //$NON-NLS-1$ +// new RGB(240, 240, 240)); + + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathySplashHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathySplashHandler.java index b15539afc..f5db31f42 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathySplashHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathySplashHandler.java @@ -1,139 +1,139 @@ -package org.xmind.cathy.internal; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.splash.AbstractSplashHandler; - -public class CathySplashHandler extends AbstractSplashHandler { - - private GC shellGC = null; - - private Image image = null; - - private Object resourceLock = new Object(); - - public CathySplashHandler() { - } - - public void init(final Shell splash) { - super.init(splash); - final ImageLoader loader = new ImageLoader(); - final ImageData[] imageDataArray = loadAnimationImageData(loader); - if (imageDataArray == null) - return; - - if (imageDataArray.length <= 1 || loader.repeatCount != 0) { - CathyPlugin - .log("Invalid GIF format of application loading indicator."); //$NON-NLS-1$ - return; - } - - shellGC = new GC(splash); - - splash.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - releaseResources(); - } - }); - - final Display display = splash.getDisplay(); - Thread animateThread = new Thread(new Runnable() { - public void run() { - showLoadingAnimation(display, imageDataArray); - } - }, "LoadingIndicatorAnimation"); //$NON-NLS-1$ - animateThread.setDaemon(true); - animateThread.start(); - } - - private ImageData[] loadAnimationImageData(ImageLoader loader) { - URL url = FileLocator.find(Platform.getBundle(CathyPlugin.PLUGIN_ID), - new Path("icons/progress.gif"), null); //$NON-NLS-1$ - if (url == null) - return null; - InputStream imageStream = null; - try { - imageStream = url.openStream(); - return loader.load(imageStream); - } catch (IOException e) { - CathyPlugin - .log(e, - "There was an error loading GIF from " + url.toExternalForm()); //$NON-NLS-1$ - return null; - } finally { - try { - imageStream.close(); - } catch (IOException e) { - } - } - } - - private void releaseResources() { - synchronized (resourceLock) { - // Dispose of the image - if (image != null) { - if (!image.isDisposed()) { - image.dispose(); - } - image = null; - } - - // Dispose of the GC - if (shellGC != null) { - if (!shellGC.isDisposed()) { - shellGC.dispose(); - } - shellGC = null; - } - } - } - - private void showLoadingAnimation(final Display display, - final ImageData[] imageDataArray) { - int imageDataIndex = -1; - ImageData imageData; - - while (true) { - imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; - imageData = imageDataArray[imageDataIndex]; - - synchronized (resourceLock) { - if (display.isDisposed() || shellGC == null - || shellGC.isDisposed()) { - return; - } - - if (image != null && !image.isDisposed()) { - image.dispose(); - image = null; - } - image = new Image(display, imageData); - shellGC.drawImage(image, 233, 215); - } - - try { - int ms = imageData.delayTime * 10; - if (ms < 20) - ms += 30; - if (ms < 30) - ms += 10; - Thread.sleep(ms); - } catch (InterruptedException e) { - } - } - } - -} +package org.xmind.cathy.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.splash.AbstractSplashHandler; + +public class CathySplashHandler extends AbstractSplashHandler { + + private GC shellGC = null; + + private Image image = null; + + private Object resourceLock = new Object(); + + public CathySplashHandler() { + } + + public void init(final Shell splash) { + super.init(splash); + final ImageLoader loader = new ImageLoader(); + final ImageData[] imageDataArray = loadAnimationImageData(loader); + if (imageDataArray == null) + return; + + if (imageDataArray.length <= 1 || loader.repeatCount != 0) { + CathyPlugin + .log("Invalid GIF format of application loading indicator."); //$NON-NLS-1$ + return; + } + + shellGC = new GC(splash); + + splash.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + releaseResources(); + } + }); + + final Display display = splash.getDisplay(); + Thread animateThread = new Thread(new Runnable() { + public void run() { + showLoadingAnimation(display, imageDataArray); + } + }, "LoadingIndicatorAnimation"); //$NON-NLS-1$ + animateThread.setDaemon(true); + animateThread.start(); + } + + private ImageData[] loadAnimationImageData(ImageLoader loader) { + URL url = FileLocator.find(Platform.getBundle(CathyPlugin.PLUGIN_ID), + new Path("icons/progress.gif"), null); //$NON-NLS-1$ + if (url == null) + return null; + InputStream imageStream = null; + try { + imageStream = url.openStream(); + return loader.load(imageStream); + } catch (IOException e) { + CathyPlugin + .log(e, + "There was an error loading GIF from " + url.toExternalForm()); //$NON-NLS-1$ + return null; + } finally { + try { + imageStream.close(); + } catch (IOException e) { + } + } + } + + private void releaseResources() { + synchronized (resourceLock) { + // Dispose of the image + if (image != null) { + if (!image.isDisposed()) { + image.dispose(); + } + image = null; + } + + // Dispose of the GC + if (shellGC != null) { + if (!shellGC.isDisposed()) { + shellGC.dispose(); + } + shellGC = null; + } + } + } + + private void showLoadingAnimation(final Display display, + final ImageData[] imageDataArray) { + int imageDataIndex = -1; + ImageData imageData; + + while (true) { + imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; + imageData = imageDataArray[imageDataIndex]; + + synchronized (resourceLock) { + if (display.isDisposed() || shellGC == null + || shellGC.isDisposed()) { + return; + } + + if (image != null && !image.isDisposed()) { + image.dispose(); + image = null; + } + image = new Image(display, imageData); + shellGC.drawImage(image, 233, 215); + } + + try { + int ms = imageData.delayTime * 10; + if (ms < 20) + ms += 30; + if (ms < 30) + ms += 10; + Thread.sleep(ms); + } catch (InterruptedException e) { + } + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyStatusHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyStatusHandler.java index c91c20ac2..bddad2d36 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyStatusHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyStatusHandler.java @@ -1,164 +1,164 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.statushandlers.AbstractStatusHandler; -import org.eclipse.ui.statushandlers.IStatusAdapterConstants; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.eclipse.ui.statushandlers.StatusManager; -import org.eclipse.ui.statushandlers.StatusManager.INotificationTypes; -import org.xmind.ui.internal.ToolkitPlugin; -import org.xmind.ui.internal.statushandlers.RuntimeErrorDialog; - -public class CathyStatusHandler extends AbstractStatusHandler { - - private static final String PROPERTY_PREFIX = "org.xmind.cathy.statusHandlers.adapters"; //$NON-NLS-1$ - - private static final QualifiedName BLOCK = new QualifiedName( - PROPERTY_PREFIX, "block"); //$NON-NLS-1$ - - private List statusQueue = new ArrayList(4); - - private RuntimeErrorDialog currentDialog = null; - - public CathyStatusHandler() { - } - - public boolean supportsNotification(int type) { - if (type == INotificationTypes.HANDLED) { - return true; - } - return super.supportsNotification(type); - } - - public void handle(final StatusAdapter statusAdapter, final int style) { - if (((style & StatusManager.SHOW) == StatusManager.SHOW) - || ((style & StatusManager.BLOCK) == StatusManager.BLOCK)) { - - final boolean block = ((style - & StatusManager.BLOCK) == StatusManager.BLOCK); - - addProperties(statusAdapter, block); - - if (Display.getCurrent() != null) { - showStatusAdapter(statusAdapter); - } else { - if (block) { - Display.getDefault().syncExec(new Runnable() { - public void run() { - showStatusAdapter(statusAdapter); - } - }); - - } else { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - showStatusAdapter(statusAdapter); - } - }); - } - } - } - - if ((style & StatusManager.LOG) == StatusManager.LOG) { - StatusManager.getManager() - .addLoggedStatus(statusAdapter.getStatus()); - ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); - } - } - - private void addProperties(final StatusAdapter statusAdapter, - boolean block) { - // Add timestamp: - if (statusAdapter.getProperty( - IStatusAdapterConstants.TIMESTAMP_PROPERTY) == null) { - statusAdapter.setProperty( - IStatusAdapterConstants.TIMESTAMP_PROPERTY, - Long.valueOf(System.currentTimeMillis())); - } - - statusAdapter.setProperty(BLOCK, Boolean.valueOf(block)); - } - - /** - * Shows the status adapter. - * - * @param statusAdapter - * the status adapter to show - * @param block - * true to request a modal dialog and suspend the - * calling thread till the dialog is closed, false - * otherwise. - */ - private void showStatusAdapter(final StatusAdapter statusAdapter) { - if (!PlatformUI.isWorkbenchRunning()) { - // we are shutting down, so just log - ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); - return; - } - - statusQueue.add(statusAdapter); - - if (currentDialog == null) { - currentDialog = showErrorDialogFor(statusAdapter); - } - - if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { - Display display = Display.getCurrent(); - if (display != null && !display.isDisposed()) { - while (statusQueue.contains(statusAdapter) - && !display.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - } - } - } - - private RuntimeErrorDialog showErrorDialogFor( - final StatusAdapter statusAdapter) { - StatusManager.getManager().fireNotification(INotificationTypes.HANDLED, - new StatusAdapter[] { statusAdapter }); - - int style = RuntimeErrorDialog.NONE; - if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { - style |= RuntimeErrorDialog.BLOCKED; - } - RuntimeErrorDialog dialog = new RuntimeErrorDialog(style, statusAdapter, - null, CathyPlugin.getDefault().getErrorReporter()); - dialog.create(); - dialog.getShell().addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - statusQueue.remove(statusAdapter); - if (statusQueue.size() > 0) { - currentDialog = showErrorDialogFor(statusQueue.get(0)); - } else { - currentDialog = null; - } - } - }); - dialog.open(); - return dialog; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.statushandlers.AbstractStatusHandler; +import org.eclipse.ui.statushandlers.IStatusAdapterConstants; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.eclipse.ui.statushandlers.StatusManager; +import org.eclipse.ui.statushandlers.StatusManager.INotificationTypes; +import org.xmind.ui.internal.ToolkitPlugin; +import org.xmind.ui.internal.statushandlers.RuntimeErrorDialog; + +public class CathyStatusHandler extends AbstractStatusHandler { + + private static final String PROPERTY_PREFIX = "org.xmind.cathy.statusHandlers.adapters"; //$NON-NLS-1$ + + private static final QualifiedName BLOCK = new QualifiedName( + PROPERTY_PREFIX, "block"); //$NON-NLS-1$ + + private List statusQueue = new ArrayList(4); + + private RuntimeErrorDialog currentDialog = null; + + public CathyStatusHandler() { + } + + public boolean supportsNotification(int type) { + if (type == INotificationTypes.HANDLED) { + return true; + } + return super.supportsNotification(type); + } + + public void handle(final StatusAdapter statusAdapter, final int style) { + if (((style & StatusManager.SHOW) == StatusManager.SHOW) + || ((style & StatusManager.BLOCK) == StatusManager.BLOCK)) { + + final boolean block = ((style + & StatusManager.BLOCK) == StatusManager.BLOCK); + + addProperties(statusAdapter, block); + + if (Display.getCurrent() != null) { + showStatusAdapter(statusAdapter); + } else { + if (block) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + showStatusAdapter(statusAdapter); + } + }); + + } else { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + showStatusAdapter(statusAdapter); + } + }); + } + } + } + + if ((style & StatusManager.LOG) == StatusManager.LOG) { + StatusManager.getManager() + .addLoggedStatus(statusAdapter.getStatus()); + ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); + } + } + + private void addProperties(final StatusAdapter statusAdapter, + boolean block) { + // Add timestamp: + if (statusAdapter.getProperty( + IStatusAdapterConstants.TIMESTAMP_PROPERTY) == null) { + statusAdapter.setProperty( + IStatusAdapterConstants.TIMESTAMP_PROPERTY, + Long.valueOf(System.currentTimeMillis())); + } + + statusAdapter.setProperty(BLOCK, Boolean.valueOf(block)); + } + + /** + * Shows the status adapter. + * + * @param statusAdapter + * the status adapter to show + * @param block + * true to request a modal dialog and suspend the + * calling thread till the dialog is closed, false + * otherwise. + */ + private void showStatusAdapter(final StatusAdapter statusAdapter) { + if (!PlatformUI.isWorkbenchRunning()) { + // we are shutting down, so just log + ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); + return; + } + + statusQueue.add(statusAdapter); + + if (currentDialog == null) { + currentDialog = showErrorDialogFor(statusAdapter); + } + + if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { + Display display = Display.getCurrent(); + if (display != null && !display.isDisposed()) { + while (statusQueue.contains(statusAdapter) + && !display.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + } + } + + private RuntimeErrorDialog showErrorDialogFor( + final StatusAdapter statusAdapter) { + StatusManager.getManager().fireNotification(INotificationTypes.HANDLED, + new StatusAdapter[] { statusAdapter }); + + int style = RuntimeErrorDialog.NONE; + if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { + style |= RuntimeErrorDialog.BLOCKED; + } + RuntimeErrorDialog dialog = new RuntimeErrorDialog(style, statusAdapter, + null, CathyPlugin.getDefault().getErrorReporter()); + dialog.create(); + dialog.getShell().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + statusQueue.remove(statusAdapter); + if (statusQueue.size() > 0) { + currentDialog = showErrorDialogFor(statusQueue.get(0)); + } else { + currentDialog = null; + } + } + }); + dialog.open(); + return dialog; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchActionBuilder.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchActionBuilder.java index 8729cc0eb..f81eb4565 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchActionBuilder.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchActionBuilder.java @@ -1,178 +1,178 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import org.eclipse.jface.action.GroupMarker; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.application.ActionBarAdvisor; -import org.eclipse.ui.application.IActionBarConfigurer; - -/** - * Make and contribute basic actions to menus and toolbars. - * - *

- * Main Menu Bar: - *

    - *
  • File (file) - *
      - *
    • (fileStart)
    • - *
    • (new.ext)
    • - *
    • ---- (open.group)
    • - *
    • (open.ext)
    • - *
    • ---- (close.group)
    • - *
    • (close.ext)
    • - *
    • ---- (save.group)
    • - *
    • ---- (save.ext)
    • - *
    • ---- (print.group)
    • - *
    • (print.ext)
    • - *
    • ---- (import.group)
    • - *
    • (import.ext)
    • - *
    • ---- (share.group)
    • - *
    • ---- (additions)
    • - *
    • (fileEnd)
    • - *
    - *
  • - *
  • Edit (edit) - *
      - *
    • (editStart)
    • - *
    • (undo.ext)
    • - *
    • ---- (cut.group)
    • - *
    • (cut.ext)
    • - *
    • ---- (delete.group)
    • - *
    • ---- (select.group)
    • - *
    • ---- (additions)
    • - *
    • ---- (find.group)
    • - *
    • ---- (find.ext)
    • - *
    • (editEnd)
    • - *
    - *
  • - *
  • (additions)
  • - *
  • Help (help) - *
      - *
    • ---- (group.intro)
    • - *
    • (group.intro.ext)
    • - *
    • ---- (group.main)
    • - *
    • (group.assist)
    • - *
    • ---- (helpStart)
    • - *
    • (group.main.ext)
    • - *
    • ---- (group.tutorials)
    • - *
    • ---- (group.tools)
    • - *
    • ---- (group.updates)
    • - *
    • ---- (group.xmindnet)
    • - *
    • (helpEnd)
    • - *
    • ---- (additions)
    • - *
    • ---- (group.about)
    • - *
    • (about.ext)
    • - *
    - *
  • - *
- *

- * - *

- * Main Tool Bar and other trim bars are defined in 'Application.e4xmi'. - *

- * - *

- * NOTE: Up to now (4.5.0), we can't use Application.e4xmi to establish our main - * menu model because workbench will delete main menu models from each window - * model when persisting the workbench model. So we have to keep this class just - * to fill in the main menu with our group markers each time the workbench - * starts up. - *

- * - * @author Frank Shaka - */ -public class CathyWorkbenchActionBuilder extends ActionBarAdvisor { - - public CathyWorkbenchActionBuilder(IActionBarConfigurer configurer) { - super(configurer); - } - - /** - * Fill basic actions in the main menu. - */ - protected void fillMenuBar(IMenuManager menuBar) { - menuBar.add(createFileMenu()); - menuBar.add(createEditMenu()); - menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); - menuBar.add(createHelpMenu()); - } - - private MenuManager createFileMenu() { - MenuManager menu = new MenuManager(WorkbenchMessages.File_menu_text, - IWorkbenchActionConstants.M_FILE); - - menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START)); - menu.add(new GroupMarker(IWorkbenchActionConstants.NEW_EXT)); - menu.add(new Separator("open.group")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.OPEN_EXT)); - menu.add(new Separator("close.group")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.CLOSE_EXT)); - menu.add(new Separator(IWorkbenchActionConstants.SAVE_GROUP)); - menu.add(new Separator(IWorkbenchActionConstants.SAVE_EXT)); - menu.add(new Separator("print.group")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.PRINT_EXT)); - menu.add(new Separator("import.group")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.IMPORT_EXT)); - menu.add(new Separator("share.group")); //$NON-NLS-1$ - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END)); - - return menu; - } - - private MenuManager createEditMenu() { - MenuManager menu = new MenuManager(WorkbenchMessages.Edit_menu_text, - IWorkbenchActionConstants.M_EDIT); - - menu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_START)); - menu.add(new GroupMarker(IWorkbenchActionConstants.UNDO_EXT)); - menu.add(new Separator("cut.group")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.CUT_EXT)); - menu.add(new Separator("delete.group")); //$NON-NLS-1$ - menu.add(new Separator("select.group")); //$NON-NLS-1$ - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - menu.add(new Separator("find.group")); //$NON-NLS-1$ - menu.add(new Separator(IWorkbenchActionConstants.FIND_EXT)); - menu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_END)); - - return menu; - } - - private MenuManager createHelpMenu() { - MenuManager menu = new MenuManager(WorkbenchMessages.Help_menu_text, - IWorkbenchActionConstants.M_HELP); - - menu.add(new Separator("group.intro")); //$NON-NLS-1$ - menu.add(new GroupMarker("group.intro.ext")); //$NON-NLS-1$ - menu.add(new Separator("group.main")); //$NON-NLS-1$ - menu.add(new GroupMarker("group.assist")); //$NON-NLS-1$ - menu.add(new Separator(IWorkbenchActionConstants.HELP_START)); - menu.add(new GroupMarker("group.main.ext")); //$NON-NLS-1$ - menu.add(new Separator("group.tutorials")); //$NON-NLS-1$ - menu.add(new Separator("group.tools")); //$NON-NLS-1$ - menu.add(new Separator("group.updates")); //$NON-NLS-1$ - menu.add(new Separator("group.xmindnet")); //$NON-NLS-1$ - menu.add(new GroupMarker(IWorkbenchActionConstants.HELP_END)); - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - menu.add(new Separator("group.about")); //$NON-NLS-1$ - menu.add(new GroupMarker("about.ext")); //$NON-NLS-1$ - - return menu; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +/** + * Make and contribute basic actions to menus and toolbars. + * + *

+ * Main Menu Bar: + *

    + *
  • File (file) + *
      + *
    • (fileStart)
    • + *
    • (new.ext)
    • + *
    • ---- (open.group)
    • + *
    • (open.ext)
    • + *
    • ---- (close.group)
    • + *
    • (close.ext)
    • + *
    • ---- (save.group)
    • + *
    • ---- (save.ext)
    • + *
    • ---- (print.group)
    • + *
    • (print.ext)
    • + *
    • ---- (import.group)
    • + *
    • (import.ext)
    • + *
    • ---- (share.group)
    • + *
    • ---- (additions)
    • + *
    • (fileEnd)
    • + *
    + *
  • + *
  • Edit (edit) + *
      + *
    • (editStart)
    • + *
    • (undo.ext)
    • + *
    • ---- (cut.group)
    • + *
    • (cut.ext)
    • + *
    • ---- (delete.group)
    • + *
    • ---- (select.group)
    • + *
    • ---- (additions)
    • + *
    • ---- (find.group)
    • + *
    • ---- (find.ext)
    • + *
    • (editEnd)
    • + *
    + *
  • + *
  • (additions)
  • + *
  • Help (help) + *
      + *
    • ---- (group.intro)
    • + *
    • (group.intro.ext)
    • + *
    • ---- (group.main)
    • + *
    • (group.assist)
    • + *
    • ---- (helpStart)
    • + *
    • (group.main.ext)
    • + *
    • ---- (group.tutorials)
    • + *
    • ---- (group.tools)
    • + *
    • ---- (group.updates)
    • + *
    • ---- (group.xmindnet)
    • + *
    • (helpEnd)
    • + *
    • ---- (additions)
    • + *
    • ---- (group.about)
    • + *
    • (about.ext)
    • + *
    + *
  • + *
+ *

+ * + *

+ * Main Tool Bar and other trim bars are defined in 'Application.e4xmi'. + *

+ * + *

+ * NOTE: Up to now (4.5.0), we can't use Application.e4xmi to establish our main + * menu model because workbench will delete main menu models from each window + * model when persisting the workbench model. So we have to keep this class just + * to fill in the main menu with our group markers each time the workbench + * starts up. + *

+ * + * @author Frank Shaka + */ +public class CathyWorkbenchActionBuilder extends ActionBarAdvisor { + + public CathyWorkbenchActionBuilder(IActionBarConfigurer configurer) { + super(configurer); + } + + /** + * Fill basic actions in the main menu. + */ + protected void fillMenuBar(IMenuManager menuBar) { + menuBar.add(createFileMenu()); + menuBar.add(createEditMenu()); + menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + menuBar.add(createHelpMenu()); + } + + private MenuManager createFileMenu() { + MenuManager menu = new MenuManager(WorkbenchMessages.File_menu_text, + IWorkbenchActionConstants.M_FILE); + + menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START)); + menu.add(new GroupMarker(IWorkbenchActionConstants.NEW_EXT)); + menu.add(new Separator("open.group")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.OPEN_EXT)); + menu.add(new Separator("close.group")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.CLOSE_EXT)); + menu.add(new Separator(IWorkbenchActionConstants.SAVE_GROUP)); + menu.add(new Separator(IWorkbenchActionConstants.SAVE_EXT)); + menu.add(new Separator("print.group")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.PRINT_EXT)); + menu.add(new Separator("import.group")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.IMPORT_EXT)); + menu.add(new Separator("share.group")); //$NON-NLS-1$ + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END)); + + return menu; + } + + private MenuManager createEditMenu() { + MenuManager menu = new MenuManager(WorkbenchMessages.Edit_menu_text, + IWorkbenchActionConstants.M_EDIT); + + menu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_START)); + menu.add(new GroupMarker(IWorkbenchActionConstants.UNDO_EXT)); + menu.add(new Separator("cut.group")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.CUT_EXT)); + menu.add(new Separator("delete.group")); //$NON-NLS-1$ + menu.add(new Separator("select.group")); //$NON-NLS-1$ + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + menu.add(new Separator("find.group")); //$NON-NLS-1$ + menu.add(new Separator(IWorkbenchActionConstants.FIND_EXT)); + menu.add(new GroupMarker(IWorkbenchActionConstants.EDIT_END)); + + return menu; + } + + private MenuManager createHelpMenu() { + MenuManager menu = new MenuManager(WorkbenchMessages.Help_menu_text, + IWorkbenchActionConstants.M_HELP); + + menu.add(new Separator("group.intro")); //$NON-NLS-1$ + menu.add(new GroupMarker("group.intro.ext")); //$NON-NLS-1$ + menu.add(new Separator("group.main")); //$NON-NLS-1$ + menu.add(new GroupMarker("group.assist")); //$NON-NLS-1$ + menu.add(new Separator(IWorkbenchActionConstants.HELP_START)); + menu.add(new GroupMarker("group.main.ext")); //$NON-NLS-1$ + menu.add(new Separator("group.tutorials")); //$NON-NLS-1$ + menu.add(new Separator("group.tools")); //$NON-NLS-1$ + menu.add(new Separator("group.updates")); //$NON-NLS-1$ + menu.add(new Separator("group.xmindnet")); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.HELP_END)); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + menu.add(new Separator("group.about")); //$NON-NLS-1$ + menu.add(new GroupMarker("about.ext")); //$NON-NLS-1$ + + return menu; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchAdvisor.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchAdvisor.java index 6c7588fbd..55730284b 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchAdvisor.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchAdvisor.java @@ -1,417 +1,420 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.ArrayList; -import java.util.Arrays; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IPersistable; -import org.eclipse.ui.IPersistableElement; -import org.eclipse.ui.ISaveablePart2; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPreferenceConstants; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.XMLMemento; -import org.eclipse.ui.application.IWorkbenchConfigurer; -import org.eclipse.ui.application.IWorkbenchWindowConfigurer; -import org.eclipse.ui.application.WorkbenchAdvisor; -import org.eclipse.ui.application.WorkbenchWindowAdvisor; -import org.eclipse.ui.internal.IWorkbenchConstants; -import org.eclipse.ui.internal.UIPlugin; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.cathy.internal.jobs.OpenFilesJob; -import org.xmind.core.internal.InternalCore; -import org.xmind.core.licensing.ILicenseAgent; -import org.xmind.core.licensing.ILicenseChangedListener; -import org.xmind.core.licensing.ILicenseKeyHeader; -import org.xmind.gef.ui.editor.IEditingContext; -import org.xmind.ui.internal.PasswordProvider; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.editor.AbstractWorkbookRef; -import org.xmind.ui.internal.editor.DefaultMindMapPreviewGenerator; -import org.xmind.ui.internal.editor.IMindMapPreviewGenerator; -import org.xmind.ui.internal.editor.IPasswordProvider; -import org.xmind.ui.mindmap.MindMapUI; - -public class CathyWorkbenchAdvisor extends WorkbenchAdvisor - implements ILicenseChangedListener { - - public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( - IWorkbenchWindowConfigurer configurer) { - return new CathyWorkbenchWindowAdvisor(configurer); - } - - public String getInitialWindowPerspectiveId() { - return MindMapUI.PERSPECTIVE_ID; - } - - @Override - public String getMainPreferencePageId() { - return "org.xmind.ui.prefPage.General"; //$NON-NLS-1$ - } - - public void initialize(IWorkbenchConfigurer configurer) { - super.initialize(configurer); - configurer.setSaveAndRestore(true); - configurer.setExitOnLastWindowClose(true); - } - - @Override - public void preStartup() { - super.preStartup(); - - CathyPlugin.getDefault().getLicenseAgent() - .addLicenseChangedListener(this); - licenseChanged(CathyPlugin.getDefault().getLicenseAgent()); - - /** - * This hack requires workbench to exist. See - * {@link org.eclipse.ui.internal.PlatformUIPreferenceListener}. - */ - UIPlugin.getDefault().getPreferenceStore().setValue( - IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS, - true); - } - - @Override - public void postStartup() { - super.postStartup(); - - IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); - - AbstractWorkbookRef.setDefaultEditingContext( - createDefaultEditingContext(workbench)); - - new StartUpProcess(workbench).startUp(); - } - - private IEditingContext createDefaultEditingContext( - final IWorkbench workbench) { - final IMindMapPreviewGenerator previewGenerator = new DefaultMindMapPreviewGenerator( - workbench.getDisplay()); - - final IPasswordProvider passwordProvider = new PasswordProvider(); - - return new IEditingContext() { - public T getAdapter(Class adapter) { - - if (IMindMapPreviewGenerator.class.equals(adapter)) - return adapter.cast(previewGenerator); - - if (IPasswordProvider.class.equals(adapter)) - return adapter.cast(passwordProvider); - - T result; - - result = workbench.getService(adapter); - if (result != null) - return result; - - result = workbench.getAdapter(adapter); - if (result != null) - return result; - - return result; - } - }; - } - - @Override - public void postShutdown() { - CathyPlugin.getDefault().getLicenseAgent() - .removeLicenseChangedListener(this); - - AbstractWorkbookRef.setDefaultEditingContext(null); - super.postShutdown(); - } - - public boolean preShutdown() { - boolean readyToShutdown = super.preShutdown(); - if (readyToShutdown) { - readyToShutdown = saveAllEditorsOnClose(); - } - return readyToShutdown; - } - - private boolean saveAllEditorsOnClose() { - IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); - final ArrayList unClosedEditorRefs = new ArrayList(); - IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); - for (IWorkbenchWindow window : windows) { - IWorkbenchPage page = window.getActivePage(); - for (IEditorReference editorRef : page.getEditorReferences()) { - unClosedEditorRefs.add(editorRef); - final IEditorPart editor = editorRef.getEditor(false); - if (editor != null && editor.isDirty()) { - int answer = promptToSaveOnClose(window, page, editor); - if (answer == ISaveablePart2.CANCEL) - return false; - if (answer == ISaveablePart2.YES) { - if (!doSaveEditor(window, editor)) { - return false; - } - } - } - } - } - SafeRunner.run(new SafeRunnable() { - public void run() { - XMLMemento mem = recordEditorsState(unClosedEditorRefs); - saveMementoToFile(mem); - } - }); - return closeAllEditors(); - } - - private XMLMemento recordEditorsState( - ArrayList editorRefs) { - XMLMemento memento = XMLMemento.createWriteRoot("xmind"); //$NON-NLS-1$ - saveEditorsState(memento, editorRefs); - return memento; - } - - private void saveEditorsState(IMemento memento, - ArrayList editorRefs) { - IWorkbenchPage activePage = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage(); - IEditorPart activeEditor = activePage.getActiveEditor(); - - IMemento childrenMemento = memento - .createChild(IWorkbenchConstants.TAG_EDITORS); - if (!editorRefs.isEmpty()) - for (IEditorReference ref : editorRefs) { - IEditorPart editor = ref.getEditor(false); - IMemento editorMemento = childrenMemento - .createChild(IWorkbenchConstants.TAG_EDITOR); - editorMemento.putBoolean(IWorkbenchConstants.TAG_ACTIVE_PART, - editor == activeEditor); - IPersistable editorPersistable = CathyPlugin.getAdapter(editor, - IPersistable.class); - if (editorPersistable != null) { - editorPersistable.saveState(editorMemento); - } - - IEditorInput input = editor.getEditorInput(); - IMemento inputMemento = editorMemento - .createChild(IWorkbenchConstants.TAG_INPUT); - IPersistableElement inputPersistable = CathyPlugin - .getAdapter(input, IPersistableElement.class); - if (inputPersistable != null) { - inputMemento.putString(IWorkbenchConstants.TAG_FACTORY_ID, - inputPersistable.getFactoryId()); - inputPersistable.saveState(inputMemento); - } - } - } - - private boolean saveMementoToFile(XMLMemento memento) { - // Save it to a file. - File stateFile = getEditorsStateFile(); - if (stateFile == null) { - return false; - } - try { - FileOutputStream stream = new FileOutputStream(stateFile); - OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$ - memento.save(writer); - writer.close(); - } catch (IOException e) { - stateFile.delete(); - return false; - } - - // Success ! - return true; - } - - private File getEditorsStateFile() { - IPath path = WorkbenchPlugin.getDefault().getDataLocation(); - if (path == null) { - return null; - } - path = path.append("XMind_Editors.xml"); //$NON-NLS-1$ - return path.toFile(); - } - - private int promptToSaveOnClose(IWorkbenchWindow window, - IWorkbenchPage page, IEditorPart editor) { - if (editor instanceof ISaveablePart2) { - int answer = ((ISaveablePart2) editor).promptToSaveOnClose(); - if (answer != ISaveablePart2.DEFAULT) - return answer; - } - page.activate(editor); - MessageDialog dialog = new MessageDialog(window.getShell(), - DialogMessages.Save_title, null, - NLS.bind(WorkbenchMessages.PromptSaveEditorOnClosing_message, - editor.getTitle()), - MessageDialog.QUESTION, - new String[] { IDialogConstants.YES_LABEL, - IDialogConstants.NO_LABEL, - IDialogConstants.CANCEL_LABEL }, - 0); - int answerIndex = dialog.open(); - switch (answerIndex) { - case 0: - return ISaveablePart2.YES; - case 1: - return ISaveablePart2.NO; - default: - return ISaveablePart2.CANCEL; - } - } - - private boolean doSaveEditor(final IWorkbenchWindow window, - final IEditorPart editor) { - final boolean[] saved = new boolean[1]; - saved[0] = false; - window.getShell().getDisplay().syncExec(new Runnable() { - public void run() { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - final IProgressMonitor monitor = new NullProgressMonitor(); - if (InternalCore.DEBUG_WORKBOOK_SAVE) - CathyPlugin.log( - "CathyWorkbenchAdvisor: About to save workbook on workbench close: " //$NON-NLS-1$ - + editor.getEditorInput() - .toString()); - editor.doSave(monitor); - if (!monitor.isCanceled()) { - saved[0] = true; - } else { - if (InternalCore.DEBUG_WORKBOOK_SAVE) - CathyPlugin.log( - "CathyWorkbenchAdvisor: Finished saving workbook on workbench close: " //$NON-NLS-1$ - + editor.getEditorInput() - .toString()); - } - } - }); - } - }); - return saved[0]; - } - - private boolean closeAllEditors() { - boolean closed = false; - IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); - for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { - closed |= window.getActivePage().closeAllEditors(false); - } - return closed; - } - - public void licenseChanged(ILicenseAgent agent) { - int type = agent.getLicenseType(); - ILicenseKeyHeader header = agent.getLicenseKeyHeader(); - String brandingVersion = System - .getProperty("org.xmind.product.brandingVersion", ""); //$NON-NLS-1$ //$NON-NLS-2$ - String licenseType; - if ((type & ILicenseAgent.PRO_LICENSE_KEY) != 0) { - licenseType = NLS.bind(WorkbenchMessages.About_ProTitle, - brandingVersion); - } else if ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0) { - licenseType = NLS.bind(WorkbenchMessages.About_PlusTitle, - brandingVersion); - } else if ((type & ILicenseAgent.PRO_SUBSCRIPTION) != 0) { - licenseType = WorkbenchMessages.About_ProSubscriptionTitle; - } else { - licenseType = null; - } - - if (header != null && ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0 - || (type & ILicenseAgent.PRO_LICENSE_KEY) != 0)) { - String licenseeType = header.getLicenseeType(); - if (ILicenseKeyHeader.LICENSEE_FAMILY.equals(licenseeType)) { - licenseType = NLS.bind("{0} (Family License)", licenseType); //$NON-NLS-1$ - } else if (ILicenseKeyHeader.LICENSEE_EDU.equals(licenseeType)) { - licenseType = NLS.bind("{0} (Academia License)", licenseType); //$NON-NLS-1$ - } else if (ILicenseKeyHeader.LICENSEE_GOV.equals(licenseeType)) { - licenseType = NLS.bind("{0} (Gov/NPO License)", licenseType); //$NON-NLS-1$ - } else if (ILicenseKeyHeader.LICENSEE_TEAM_5U.equals(licenseeType) - || ILicenseKeyHeader.LICENSEE_TEAM_10U.equals(licenseeType) - || ILicenseKeyHeader.LICENSEE_TEAM_20U - .equals(licenseeType)) { - licenseType = NLS.bind("{0} (Team License)", licenseType); //$NON-NLS-1$ - } else if (ILicenseKeyHeader.LICENSEE_VLE.equals(licenseeType)) { - licenseType = NLS.bind("{0} (Volume License)", licenseType); //$NON-NLS-1$ - } - } - if (licenseType == null) { - licenseType = WorkbenchMessages.About_LicenseType_Unactivated; - } else { - licenseType = NLS.bind(WorkbenchMessages.About_LicenseTypePattern, - licenseType); - } - System.setProperty("org.xmind.product.license.type", //$NON-NLS-1$ - licenseType); - - String name = agent.getLicenseeName(); - if (name != null && !"".equals(name)) { //$NON-NLS-1$ - name = NLS.bind(WorkbenchMessages.About_LicensedTo, name); - } else { - name = ""; //$NON-NLS-1$ - } - System.setProperty("org.xmind.product.license.licensee", name); //$NON-NLS-1$ - } - - @Override - public void eventLoopIdle(Display display) { - String[] paths = OpenDocumentQueue.getInstance().drain(); - if (paths.length > 0) { - CathyPlugin.log("Ready to open files: " + Arrays.toString(paths)); //$NON-NLS-1$ - openFiles(paths); - IWorkbenchWindow window = getWorkbenchConfigurer().getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - Shell shell = window.getShell(); - if (shell != null && !shell.isDisposed()) { - shell.forceActive(); - } - } - } else { - super.eventLoopIdle(display); - } - } - - private void openFiles(String[] paths) { - OpenFilesJob job = new OpenFilesJob( - getWorkbenchConfigurer().getWorkbench(), - WorkbenchMessages.CheckOpenFilesJob_CheckFiles_name, - Arrays.asList(paths)); - job.setRule(Log.get(Log.OPENING)); - job.schedule(); - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistable; +import org.eclipse.ui.IPersistableElement; +import org.eclipse.ui.ISaveablePart2; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.XMLMemento; +import org.eclipse.ui.application.IWorkbenchConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; +import org.eclipse.ui.internal.IWorkbenchConstants; +import org.eclipse.ui.internal.UIPlugin; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.cathy.internal.jobs.OpenFilesJob; +import org.xmind.core.internal.InternalCore; +import org.xmind.core.licensing.ILicenseAgent; +import org.xmind.core.licensing.ILicenseChangedListener; +import org.xmind.core.licensing.ILicenseKeyHeader; +import org.xmind.gef.ui.editor.IEditingContext; +import org.xmind.ui.internal.PasswordProvider; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.editor.AbstractWorkbookRef; +import org.xmind.ui.internal.editor.DefaultMindMapPreviewGenerator; +import org.xmind.ui.internal.editor.IMindMapPreviewGenerator; +import org.xmind.ui.internal.editor.IPasswordProvider; +import org.xmind.ui.mindmap.MindMapUI; + +public class CathyWorkbenchAdvisor extends WorkbenchAdvisor + implements ILicenseChangedListener { + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + IWorkbenchWindowConfigurer configurer) { + return new CathyWorkbenchWindowAdvisor(configurer); + } + + public String getInitialWindowPerspectiveId() { + return MindMapUI.PERSPECTIVE_ID; + } + + @Override + public String getMainPreferencePageId() { + return "org.xmind.ui.prefPage.General"; //$NON-NLS-1$ + } + + public void initialize(IWorkbenchConfigurer configurer) { + super.initialize(configurer); + configurer.setSaveAndRestore(true); + configurer.setExitOnLastWindowClose(true); + } + + @Override + public void preStartup() { + super.preStartup(); + + CathyPlugin.getDefault().getLicenseAgent() + .addLicenseChangedListener(this); + licenseChanged(CathyPlugin.getDefault().getLicenseAgent()); + + /** + * This hack requires workbench to exist. See + * {@link org.eclipse.ui.internal.PlatformUIPreferenceListener}. + */ + UIPlugin.getDefault().getPreferenceStore().setValue( + IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS, + true); + } + + @Override + public void postStartup() { + super.postStartup(); + + IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); + + AbstractWorkbookRef.setDefaultEditingContext( + createDefaultEditingContext(workbench)); + + new StartUpProcess(workbench).startUp(); + } + + private IEditingContext createDefaultEditingContext( + final IWorkbench workbench) { + final IMindMapPreviewGenerator previewGenerator = new DefaultMindMapPreviewGenerator( + workbench.getDisplay()); + + final IPasswordProvider passwordProvider = new PasswordProvider(); + + return new IEditingContext() { + public T getAdapter(Class adapter) { + + if (IMindMapPreviewGenerator.class.equals(adapter)) + return adapter.cast(previewGenerator); + + if (IPasswordProvider.class.equals(adapter)) + return adapter.cast(passwordProvider); + + T result; + + result = workbench.getService(adapter); + if (result != null) + return result; + + result = workbench.getAdapter(adapter); + if (result != null) + return result; + + return result; + } + }; + } + + @Override + public void postShutdown() { + CathyPlugin.getDefault().getLicenseAgent() + .removeLicenseChangedListener(this); + + AbstractWorkbookRef.setDefaultEditingContext(null); + super.postShutdown(); + } + + public boolean preShutdown() { + boolean readyToShutdown = super.preShutdown(); + if (readyToShutdown) { + readyToShutdown = saveAllEditorsOnClose(); + } + return readyToShutdown; + } + + private boolean saveAllEditorsOnClose() { + IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); + final ArrayList unClosedEditorRefs = new ArrayList(); + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + for (IWorkbenchWindow window : windows) { + IWorkbenchPage page = window.getActivePage(); + for (IEditorReference editorRef : page.getEditorReferences()) { + unClosedEditorRefs.add(editorRef); + final IEditorPart editor = editorRef.getEditor(false); + if (editor != null && editor.isDirty()) { + int answer = promptToSaveOnClose(window, page, editor); + if (answer == ISaveablePart2.CANCEL) + return false; + if (answer == ISaveablePart2.YES) { + if (!doSaveEditor(window, editor)) { + return false; + } + } + } + } + } + SafeRunner.run(new SafeRunnable() { + public void run() { + XMLMemento mem = recordEditorsState(unClosedEditorRefs); + saveMementoToFile(mem); + } + }); + return closeAllEditors(); + } + + private XMLMemento recordEditorsState( + ArrayList editorRefs) { + XMLMemento memento = XMLMemento.createWriteRoot("xmind"); //$NON-NLS-1$ + saveEditorsState(memento, editorRefs); + return memento; + } + + private void saveEditorsState(IMemento memento, + ArrayList editorRefs) { + IWorkbenchPage activePage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + IEditorPart activeEditor = activePage.getActiveEditor(); + + IMemento childrenMemento = memento + .createChild(IWorkbenchConstants.TAG_EDITORS); + if (!editorRefs.isEmpty()) + for (IEditorReference ref : editorRefs) { + IEditorPart editor = ref.getEditor(false); + if (editor == null) { + continue; + } + IMemento editorMemento = childrenMemento + .createChild(IWorkbenchConstants.TAG_EDITOR); + editorMemento.putBoolean(IWorkbenchConstants.TAG_ACTIVE_PART, + editor == activeEditor); + IPersistable editorPersistable = CathyPlugin.getAdapter(editor, + IPersistable.class); + if (editorPersistable != null) { + editorPersistable.saveState(editorMemento); + } + + IEditorInput input = editor.getEditorInput(); + IMemento inputMemento = editorMemento + .createChild(IWorkbenchConstants.TAG_INPUT); + IPersistableElement inputPersistable = CathyPlugin + .getAdapter(input, IPersistableElement.class); + if (inputPersistable != null) { + inputMemento.putString(IWorkbenchConstants.TAG_FACTORY_ID, + inputPersistable.getFactoryId()); + inputPersistable.saveState(inputMemento); + } + } + } + + private boolean saveMementoToFile(XMLMemento memento) { + // Save it to a file. + File stateFile = getEditorsStateFile(); + if (stateFile == null) { + return false; + } + try { + FileOutputStream stream = new FileOutputStream(stateFile); + OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$ + memento.save(writer); + writer.close(); + } catch (IOException e) { + stateFile.delete(); + return false; + } + + // Success ! + return true; + } + + private File getEditorsStateFile() { + IPath path = WorkbenchPlugin.getDefault().getDataLocation(); + if (path == null) { + return null; + } + path = path.append("XMind_Editors.xml"); //$NON-NLS-1$ + return path.toFile(); + } + + private int promptToSaveOnClose(IWorkbenchWindow window, + IWorkbenchPage page, IEditorPart editor) { + if (editor instanceof ISaveablePart2) { + int answer = ((ISaveablePart2) editor).promptToSaveOnClose(); + if (answer != ISaveablePart2.DEFAULT) + return answer; + } + page.activate(editor); + MessageDialog dialog = new MessageDialog(window.getShell(), + DialogMessages.Save_title, null, + NLS.bind(WorkbenchMessages.PromptSaveEditorOnClosing_message, + editor.getTitle()), + MessageDialog.QUESTION, + new String[] { IDialogConstants.YES_LABEL, + IDialogConstants.NO_LABEL, + IDialogConstants.CANCEL_LABEL }, + 0); + int answerIndex = dialog.open(); + switch (answerIndex) { + case 0: + return ISaveablePart2.YES; + case 1: + return ISaveablePart2.NO; + default: + return ISaveablePart2.CANCEL; + } + } + + private boolean doSaveEditor(final IWorkbenchWindow window, + final IEditorPart editor) { + final boolean[] saved = new boolean[1]; + saved[0] = false; + window.getShell().getDisplay().syncExec(new Runnable() { + public void run() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + final IProgressMonitor monitor = new NullProgressMonitor(); + if (InternalCore.DEBUG_WORKBOOK_SAVE) + CathyPlugin.log( + "CathyWorkbenchAdvisor: About to save workbook on workbench close: " //$NON-NLS-1$ + + editor.getEditorInput() + .toString()); + editor.doSave(monitor); + if (!monitor.isCanceled()) { + saved[0] = true; + } else { + if (InternalCore.DEBUG_WORKBOOK_SAVE) + CathyPlugin.log( + "CathyWorkbenchAdvisor: Finished saving workbook on workbench close: " //$NON-NLS-1$ + + editor.getEditorInput() + .toString()); + } + } + }); + } + }); + return saved[0]; + } + + private boolean closeAllEditors() { + boolean closed = false; + IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); + for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { + closed |= window.getActivePage().closeAllEditors(false); + } + return closed; + } + + public void licenseChanged(ILicenseAgent agent) { + int type = agent.getLicenseType(); + ILicenseKeyHeader header = agent.getLicenseKeyHeader(); + String brandingVersion = System + .getProperty("org.xmind.product.brandingVersion", ""); //$NON-NLS-1$ //$NON-NLS-2$ + String licenseType; + if ((type & ILicenseAgent.PRO_LICENSE_KEY) != 0) { + licenseType = NLS.bind(WorkbenchMessages.About_ProTitle, + brandingVersion); + } else if ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0) { + licenseType = NLS.bind(WorkbenchMessages.About_PlusTitle, + brandingVersion); + } else if ((type & ILicenseAgent.PRO_SUBSCRIPTION) != 0) { + licenseType = WorkbenchMessages.About_ProSubscriptionTitle; + } else { + licenseType = null; + } + + if (header != null && ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0 + || (type & ILicenseAgent.PRO_LICENSE_KEY) != 0)) { + String licenseeType = header.getLicenseeType(); + if (ILicenseKeyHeader.LICENSEE_FAMILY.equals(licenseeType)) { + licenseType = NLS.bind("{0} (Family License)", licenseType); //$NON-NLS-1$ + } else if (ILicenseKeyHeader.LICENSEE_EDU.equals(licenseeType)) { + licenseType = NLS.bind("{0} (Academia License)", licenseType); //$NON-NLS-1$ + } else if (ILicenseKeyHeader.LICENSEE_GOV.equals(licenseeType)) { + licenseType = NLS.bind("{0} (Gov/NPO License)", licenseType); //$NON-NLS-1$ + } else if (ILicenseKeyHeader.LICENSEE_TEAM_5U.equals(licenseeType) + || ILicenseKeyHeader.LICENSEE_TEAM_10U.equals(licenseeType) + || ILicenseKeyHeader.LICENSEE_TEAM_20U + .equals(licenseeType)) { + licenseType = NLS.bind("{0} (Team License)", licenseType); //$NON-NLS-1$ + } else if (ILicenseKeyHeader.LICENSEE_VLE.equals(licenseeType)) { + licenseType = NLS.bind("{0} (Volume License)", licenseType); //$NON-NLS-1$ + } + } + if (licenseType == null) { + licenseType = WorkbenchMessages.About_LicenseType_Unactivated; + } else { + licenseType = NLS.bind(WorkbenchMessages.About_LicenseTypePattern, + licenseType); + } + System.setProperty("org.xmind.product.license.type", //$NON-NLS-1$ + licenseType); + + String name = agent.getLicenseeName(); + if (name != null && !"".equals(name)) { //$NON-NLS-1$ + name = NLS.bind(WorkbenchMessages.About_LicensedTo, name); + } else { + name = ""; //$NON-NLS-1$ + } + System.setProperty("org.xmind.product.license.licensee", name); //$NON-NLS-1$ + } + + @Override + public void eventLoopIdle(Display display) { + String[] paths = OpenDocumentQueue.getInstance().drain(); + if (paths.length > 0) { + CathyPlugin.log("Ready to open files: " + Arrays.toString(paths)); //$NON-NLS-1$ + openFiles(paths); + IWorkbenchWindow window = getWorkbenchConfigurer().getWorkbench() + .getActiveWorkbenchWindow(); + if (window != null) { + Shell shell = window.getShell(); + if (shell != null && !shell.isDisposed()) { + shell.forceActive(); + } + } + } else { + super.eventLoopIdle(display); + } + } + + private void openFiles(String[] paths) { + OpenFilesJob job = new OpenFilesJob( + getWorkbenchConfigurer().getWorkbench(), + WorkbenchMessages.CheckOpenFilesJob_CheckFiles_name, + Arrays.asList(paths)); + job.setRule(Log.get(Log.OPENING)); + job.schedule(); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchWindowAdvisor.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchWindowAdvisor.java index 2e884ba61..0f31b66ff 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchWindowAdvisor.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CathyWorkbenchWindowAdvisor.java @@ -1,354 +1,354 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.File; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.IPartListener; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.events.ShellAdapter; -import org.eclipse.swt.events.ShellEvent; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IPartListener2; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPartReference; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.application.ActionBarAdvisor; -import org.eclipse.ui.application.IActionBarConfigurer; -import org.eclipse.ui.application.IWorkbenchWindowConfigurer; -import org.eclipse.ui.application.WorkbenchWindowAdvisor; -import org.eclipse.ui.internal.Workbench; -import org.eclipse.ui.internal.tweaklets.TitlePathUpdater; -import org.eclipse.ui.internal.tweaklets.Tweaklets; -import org.xmind.core.licensing.ILicenseAgent; -import org.xmind.core.licensing.ILicenseChangedListener; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.editor.MME; -import org.xmind.ui.internal.workbench.Util; - -public class CathyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor - implements IPartListener2, IPropertyListener, ILicenseChangedListener { - - private String licenseName = null; - - private IWorkbenchPartReference activePartRef = null; - -// private boolean checkingNewWorkbookEditor = false; - - private TitlePathUpdater titlePathUpdater; - - private boolean homeShowing = false; - - public CathyWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { - super(configurer); - this.titlePathUpdater = (TitlePathUpdater) Tweaklets - .get(TitlePathUpdater.KEY); - } - - public ActionBarAdvisor createActionBarAdvisor( - IActionBarConfigurer configurer) { - return new CathyWorkbenchActionBuilder(configurer); - } - - public void preWindowOpen() { - IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); - configurer.setInitialSize(Util.getInitialWindowSize()); - configurer.setShowCoolBar(true); - configurer.setShowStatusLine(true); - configurer.setShowProgressIndicator(true); - configurer.setTitle(WorkbenchMessages.AppWindowTitle); - - CathyPlugin.getDefault().getLicenseAgent() - .addLicenseChangedListener(this); - } - - public void postWindowOpen() { - final IWorkbenchWindow window = getWindowConfigurer().getWindow(); - if (window != null) { - window.getPartService().addPartListener(this); - - Shell shell = window.getShell(); - if (shell != null && !shell.isDisposed()) { - shell.addShellListener(new ShellAdapter() { - @Override - public void shellActivated(ShellEvent e) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - new CheckOpenFilesProcess( - window.getWorkbench()) - .doCheckAndOpenFiles(); - } - }); - } - }); - } - }); - } - } - - addE4PartListener(); - } - - private void addE4PartListener() { - IWorkbench workbench = getWindowConfigurer().getWorkbenchConfigurer() - .getWorkbench(); - EModelService modelService = workbench.getService(EModelService.class); - MApplication application = ((Workbench) workbench).getApplication(); - - if (modelService == null || application == null) { - return; - } - - final List windows = modelService.findElements(application, - ICathyConstants.ID_MAIN_WINDOW, MWindow.class, null); - if (windows.isEmpty()) { - return; - } - for (MWindow window : windows) { - Shell shell = (Shell) window.getContext().get("localActiveShell"); //$NON-NLS-1$ - if (shell != null) - shell.setMinimumSize(1000, 700); - } - - EPartService partService = windows.get(0).getContext() - .get(EPartService.class); - if (partService == null) { - return; - } - - partService.addPartListener(new IPartListener() { - - public void partVisible(MPart part) { - } - - public void partHidden(MPart part) { - } - - public void partDeactivated(MPart part) { - if (ICathyConstants.ID_DASHBOARD_PART - .equals(part.getElementId())) { - homeShowing = false; - updateWindowTitle(); - } - } - - public void partBroughtToTop(MPart part) { - } - - public void partActivated(MPart part) { - if (ICathyConstants.ID_DASHBOARD_PART - .equals(part.getElementId())) { - homeShowing = true; - updateWindowTitle(); - } - } - }); - } - - @Override - public void postWindowClose() { - CathyPlugin.getDefault().getLicenseAgent() - .removeLicenseChangedListener(this); - } - - public void licenseChanged(ILicenseAgent agent) { - int licenseType = agent.getLicenseType(); - if ((licenseType & ILicenseAgent.PRO_LICENSE_KEY) != 0) { - licenseName = "Pro"; //$NON-NLS-1$ - } else if ((licenseType & ILicenseAgent.PLUS_LICENSE_KEY) != 0) { - licenseName = "Plus"; //$NON-NLS-1$ - } else if ((licenseType & ILicenseAgent.PRO_SUBSCRIPTION) != 0) { - licenseName = "Pro"; //$NON-NLS-1$ - } else { - licenseName = null; - } - updateWindowTitle(); - } - - public void partActivated(IWorkbenchPartReference partRef) { - if (partRef instanceof IEditorReference) { - if (activePartRef != null) { - activePartRef.removePropertyListener(this); - } - activePartRef = partRef; - activePartRef.addPropertyListener(this); - } - updateWindowTitle(); - } - - public void partBroughtToTop(IWorkbenchPartReference partRef) { - } - - public void partClosed(IWorkbenchPartReference partRef) { - if (partRef == activePartRef) { - activePartRef = null; - partRef.removePropertyListener(this); - } - updateWindowTitle(); -// checkNewWorkbookEditor(); - } - - public void partDeactivated(IWorkbenchPartReference partRef) { - } - - public void partHidden(IWorkbenchPartReference partRef) { - updateWindowTitle(); - } - - public void partInputChanged(IWorkbenchPartReference partRef) { - updateWindowTitle(); - } - - public void partOpened(IWorkbenchPartReference partRef) { -// if (partRef instanceof IEditorReference -// && !NewWorkbookEditor.EDITOR_ID.equals(partRef.getId())) { -// checkNewWorkbookEditor(); -// } - } - - public void partVisible(IWorkbenchPartReference partRef) { - updateWindowTitle(); - } - - private void updateWindowTitle() { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - public void run() { - doUpdateWindowTitle(); - } - }); - } - - private void doUpdateWindowTitle() { - IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); - IWorkbenchWindow window = configurer.getWindow(); - if (window == null) - return; - - Shell shell = window.getShell(); - if (shell == null || shell.isDisposed()) - return; - - StringBuffer sb = new StringBuffer(20); - - if (homeShowing) { - sb.append( - WorkbenchMessages.CathyWorkbenchWindowAdvisor_windowTitle_home_prefix); - } - - IWorkbenchPage page = window.getActivePage(); - IEditorPart editor = null; - if (page != null) { - editor = page.getActiveEditor(); - } - - if (editor == null) { - sb.append(WorkbenchMessages.AppWindowTitle); - if (licenseName != null) { - sb.append(' '); - sb.append(licenseName); - } - } else { - String text = editor.getClass().toString() - .contains("org.xmind.ui.internal.browser") ? null //$NON-NLS-1$ - : editor.getTitleToolTip(); - if (text == null) { - text = editor.getTitle(); - } else { - text = FileUtils.getFileName(text); - } - sb.append(text); - } - - configurer.setTitle(sb.toString()); - - if (titlePathUpdater != null) { - titlePathUpdater.updateTitlePath(shell, computeTitlePath(page)); - } - } - - private String computeTitlePath(IWorkbenchPage page) { - IEditorPart activeEditor = page.getActiveEditor(); - if (activeEditor != null) { - IEditorInput editorInput = activeEditor.getEditorInput(); - if (editorInput != null) { - File file = MME.getFile(editorInput); - if (file != null) - return file.getAbsolutePath(); - } - } - return null; - } - - public void propertyChanged(Object source, int propId) { - updateWindowTitle(); - } - -// private void checkNewWorkbookEditor() { -// if (checkingNewWorkbookEditor) -// return; -// checkingNewWorkbookEditor = true; -// Display.getCurrent().asyncExec(new Runnable() { -// public void run() { -// try { -// IWorkbenchWindow window = getWindowConfigurer().getWindow(); -// Shell shell = window.getShell(); -// if (shell == null || shell.isDisposed()) -// return; -// -// IWorkbenchPage page = window.getActivePage(); -// if (page == null) -// return; -// -// int numEditors = 0; -// IEditorReference[] editors = page.getEditorReferences(); -// for (int i = 0; i < editors.length; i++) { -// IEditorReference editor = editors[i]; -// if (!NewWorkbookEditor.EDITOR_ID -// .equals(editor.getId())) { -// numEditors++; -// } -// } -// -// if (numEditors > 0) { -// // Has normal editors, hide NewWorkbookEditor: -// NewWorkbookEditor.hideFrom(window); -// } else { -// // No normal editors, show NewWorkbookEditor: -// NewWorkbookEditor.showIn(window); -// } -// -// } finally { -// checkingNewWorkbookEditor = false; -// } -// } -// }); -// } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.File; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.IPartListener; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; +import org.eclipse.ui.internal.Workbench; +import org.eclipse.ui.internal.tweaklets.TitlePathUpdater; +import org.eclipse.ui.internal.tweaklets.Tweaklets; +import org.xmind.core.licensing.ILicenseAgent; +import org.xmind.core.licensing.ILicenseChangedListener; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.internal.workbench.Util; + +public class CathyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor + implements IPartListener2, IPropertyListener, ILicenseChangedListener { + + private String licenseName = null; + + private IWorkbenchPartReference activePartRef = null; + +// private boolean checkingNewWorkbookEditor = false; + + private TitlePathUpdater titlePathUpdater; + + private boolean homeShowing = false; + + public CathyWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { + super(configurer); + this.titlePathUpdater = (TitlePathUpdater) Tweaklets + .get(TitlePathUpdater.KEY); + } + + public ActionBarAdvisor createActionBarAdvisor( + IActionBarConfigurer configurer) { + return new CathyWorkbenchActionBuilder(configurer); + } + + public void preWindowOpen() { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setInitialSize(Util.getInitialWindowSize()); + configurer.setShowCoolBar(true); + configurer.setShowStatusLine(true); + configurer.setShowProgressIndicator(true); + configurer.setTitle(WorkbenchMessages.AppWindowTitle); + + CathyPlugin.getDefault().getLicenseAgent() + .addLicenseChangedListener(this); + } + + public void postWindowOpen() { + final IWorkbenchWindow window = getWindowConfigurer().getWindow(); + if (window != null) { + window.getPartService().addPartListener(this); + + Shell shell = window.getShell(); + if (shell != null && !shell.isDisposed()) { + shell.addShellListener(new ShellAdapter() { + @Override + public void shellActivated(ShellEvent e) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + new CheckOpenFilesProcess( + window.getWorkbench()) + .doCheckAndOpenFiles(); + } + }); + } + }); + } + }); + } + } + + addE4PartListener(); + } + + private void addE4PartListener() { + IWorkbench workbench = getWindowConfigurer().getWorkbenchConfigurer() + .getWorkbench(); + EModelService modelService = workbench.getService(EModelService.class); + MApplication application = ((Workbench) workbench).getApplication(); + + if (modelService == null || application == null) { + return; + } + + final List windows = modelService.findElements(application, + ICathyConstants.ID_MAIN_WINDOW, MWindow.class, null); + if (windows.isEmpty()) { + return; + } + for (MWindow window : windows) { + Shell shell = (Shell) window.getContext().get("localActiveShell"); //$NON-NLS-1$ + if (shell != null) + shell.setMinimumSize(1000, 700); + } + + EPartService partService = windows.get(0).getContext() + .get(EPartService.class); + if (partService == null) { + return; + } + + partService.addPartListener(new IPartListener() { + + public void partVisible(MPart part) { + } + + public void partHidden(MPart part) { + } + + public void partDeactivated(MPart part) { + if (ICathyConstants.ID_DASHBOARD_PART + .equals(part.getElementId())) { + homeShowing = false; + updateWindowTitle(); + } + } + + public void partBroughtToTop(MPart part) { + } + + public void partActivated(MPart part) { + if (ICathyConstants.ID_DASHBOARD_PART + .equals(part.getElementId())) { + homeShowing = true; + updateWindowTitle(); + } + } + }); + } + + @Override + public void postWindowClose() { + CathyPlugin.getDefault().getLicenseAgent() + .removeLicenseChangedListener(this); + } + + public void licenseChanged(ILicenseAgent agent) { + int licenseType = agent.getLicenseType(); + if ((licenseType & ILicenseAgent.PRO_LICENSE_KEY) != 0) { + licenseName = "Pro"; //$NON-NLS-1$ + } else if ((licenseType & ILicenseAgent.PLUS_LICENSE_KEY) != 0) { + licenseName = "Plus"; //$NON-NLS-1$ + } else if ((licenseType & ILicenseAgent.PRO_SUBSCRIPTION) != 0) { + licenseName = "Pro"; //$NON-NLS-1$ + } else { + licenseName = null; + } + updateWindowTitle(); + } + + public void partActivated(IWorkbenchPartReference partRef) { + if (partRef instanceof IEditorReference) { + if (activePartRef != null) { + activePartRef.removePropertyListener(this); + } + activePartRef = partRef; + activePartRef.addPropertyListener(this); + } + updateWindowTitle(); + } + + public void partBroughtToTop(IWorkbenchPartReference partRef) { + } + + public void partClosed(IWorkbenchPartReference partRef) { + if (partRef == activePartRef) { + activePartRef = null; + partRef.removePropertyListener(this); + } + updateWindowTitle(); +// checkNewWorkbookEditor(); + } + + public void partDeactivated(IWorkbenchPartReference partRef) { + } + + public void partHidden(IWorkbenchPartReference partRef) { + updateWindowTitle(); + } + + public void partInputChanged(IWorkbenchPartReference partRef) { + updateWindowTitle(); + } + + public void partOpened(IWorkbenchPartReference partRef) { +// if (partRef instanceof IEditorReference +// && !NewWorkbookEditor.EDITOR_ID.equals(partRef.getId())) { +// checkNewWorkbookEditor(); +// } + } + + public void partVisible(IWorkbenchPartReference partRef) { + updateWindowTitle(); + } + + private void updateWindowTitle() { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + public void run() { + doUpdateWindowTitle(); + } + }); + } + + private void doUpdateWindowTitle() { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + IWorkbenchWindow window = configurer.getWindow(); + if (window == null) + return; + + Shell shell = window.getShell(); + if (shell == null || shell.isDisposed()) + return; + + StringBuffer sb = new StringBuffer(20); + + if (homeShowing) { + sb.append( + WorkbenchMessages.CathyWorkbenchWindowAdvisor_windowTitle_home_prefix); + } + + IWorkbenchPage page = window.getActivePage(); + IEditorPart editor = null; + if (page != null) { + editor = page.getActiveEditor(); + } + + if (editor == null) { + sb.append(WorkbenchMessages.AppWindowTitle); + if (licenseName != null) { + sb.append(' '); + sb.append(licenseName); + } + } else { + String text = editor.getClass().toString() + .contains("org.xmind.ui.internal.browser") ? null //$NON-NLS-1$ + : editor.getTitleToolTip(); + if (text == null) { + text = editor.getTitle(); + } else { + text = FileUtils.getFileName(text); + } + sb.append(text); + } + + configurer.setTitle(sb.toString()); + + if (titlePathUpdater != null) { + titlePathUpdater.updateTitlePath(shell, computeTitlePath(page)); + } + } + + private String computeTitlePath(IWorkbenchPage page) { + IEditorPart activeEditor = page.getActiveEditor(); + if (activeEditor != null) { + IEditorInput editorInput = activeEditor.getEditorInput(); + if (editorInput != null) { + File file = MME.getFile(editorInput); + if (file != null) + return file.getAbsolutePath(); + } + } + return null; + } + + public void propertyChanged(Object source, int propId) { + updateWindowTitle(); + } + +// private void checkNewWorkbookEditor() { +// if (checkingNewWorkbookEditor) +// return; +// checkingNewWorkbookEditor = true; +// Display.getCurrent().asyncExec(new Runnable() { +// public void run() { +// try { +// IWorkbenchWindow window = getWindowConfigurer().getWindow(); +// Shell shell = window.getShell(); +// if (shell == null || shell.isDisposed()) +// return; +// +// IWorkbenchPage page = window.getActivePage(); +// if (page == null) +// return; +// +// int numEditors = 0; +// IEditorReference[] editors = page.getEditorReferences(); +// for (int i = 0; i < editors.length; i++) { +// IEditorReference editor = editors[i]; +// if (!NewWorkbookEditor.EDITOR_ID +// .equals(editor.getId())) { +// numEditors++; +// } +// } +// +// if (numEditors > 0) { +// // Has normal editors, hide NewWorkbookEditor: +// NewWorkbookEditor.hideFrom(window); +// } else { +// // No normal editors, show NewWorkbookEditor: +// NewWorkbookEditor.showIn(window); +// } +// +// } finally { +// checkingNewWorkbookEditor = false; +// } +// } +// }); +// } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CheckOpenFilesProcess.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CheckOpenFilesProcess.java index 8539206e2..8ce4fe06a 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CheckOpenFilesProcess.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CheckOpenFilesProcess.java @@ -1,35 +1,35 @@ -package org.xmind.cathy.internal; - -import java.io.File; -import java.util.List; - -import org.eclipse.ui.IWorkbench; - -public class CheckOpenFilesProcess extends OpenFilesProcess { - - public CheckOpenFilesProcess(IWorkbench workbench) { - super(workbench); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.cathy.internal.jobs.OpenFilesJob#filterFilesToOpen(java.util - * .List, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override - protected void filterFilesToOpen(List filesToOpen) { - Log opening = Log.get(Log.OPENING); - if (opening.exists()) { - String[] contents = opening.getContents(); - for (String line : contents) { - if (line.startsWith("xmind:") || new File(line).exists()) { //$NON-NLS-1$ - filesToOpen.add(line); - } - } - opening.delete(); - } - } - -} +package org.xmind.cathy.internal; + +import java.io.File; +import java.util.List; + +import org.eclipse.ui.IWorkbench; + +public class CheckOpenFilesProcess extends OpenFilesProcess { + + public CheckOpenFilesProcess(IWorkbench workbench) { + super(workbench); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.cathy.internal.jobs.OpenFilesJob#filterFilesToOpen(java.util + * .List, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected void filterFilesToOpen(List filesToOpen) { + Log opening = Log.get(Log.OPENING); + if (opening.exists()) { + String[] contents = opening.getContents(); + for (String line : contents) { + if (line.startsWith("xmind:") || new File(line).exists()) { //$NON-NLS-1$ + filesToOpen.add(line); + } + } + opening.delete(); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CommandLabelUpdater.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CommandLabelUpdater.java index 7b1e2a525..1a8a5bac0 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CommandLabelUpdater.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/CommandLabelUpdater.java @@ -1,218 +1,226 @@ - -package org.xmind.cathy.internal; - -import java.util.HashSet; -import java.util.Set; - -import javax.inject.Inject; - -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.di.extensions.EventTopic; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MItem; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.SubActionBars; -import org.eclipse.ui.actions.ActionFactory; -import org.osgi.service.event.Event; - -public class CommandLabelUpdater implements IPropertyChangeListener { - - private static final int TEXT = 1 << 1; - private static final int TOOLTIP = 1 << 2; - - private static final String DATA_ORIGINAL_TEXT = "CommandLabelUpdater:OriginalText"; //$NON-NLS-1$ - private static final String DATA_ORIGINAL_TOOLTIP = "CommandLabelUpdater:OriginalTooltip"; //$NON-NLS-1$ - - @Inject - private EModelService modelService; - - private MWindow activeWindow = null; - private IActionBars activeActionBars = null; - private Set trackedHandlers = null; - - @Inject - @Optional - public void applicationStarted( - @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) { - } - - @Inject - @Optional - public void activePartChanged( - @EventTopic(UIEvents.UILifeCycle.ACTIVATE) Event event) { - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(element instanceof MPart)) - return; - - MPart part = (MPart) element; - MWindow window = findWindowFor(part); - if (window == null) - return; - - partActivated(part, window); - } - - private void partActivated(MPart part, MWindow window) { - IWorkbenchWindow ww = window.getContext().get(IWorkbenchWindow.class); - IActionBars actionBars = findActionBars(ww); - - this.activeWindow = window; - - if (actionBars != this.activeActionBars) { - if (this.activeActionBars instanceof SubActionBars) { - ((SubActionBars) this.activeActionBars) - .removePropertyChangeListener(this); - } - this.activeActionBars = actionBars; - if (this.activeActionBars instanceof SubActionBars) { - ((SubActionBars) this.activeActionBars) - .addPropertyChangeListener(this); - } - - updateAllItemLabels(); - } - } - - private void updateAllItemLabels() { - if (activeWindow == null) - return; - - Set oldTrackedHandlers = this.trackedHandlers; - Set newTrackedHandlers = new HashSet(); - - updateItemLabel(activeActionBars, activeWindow.getMainMenu(), - ICathyConstants.ID_MENU_ITEM_UNDO, ActionFactory.UNDO.getId(), - ActionFactory.UNDO.getCommandId(), TEXT, newTrackedHandlers); - updateItemLabel(activeActionBars, activeWindow.getMainMenu(), - ICathyConstants.ID_MENU_ITEM_REDO, ActionFactory.REDO.getId(), - ActionFactory.REDO.getCommandId(), TEXT, newTrackedHandlers); - - updateItemLabel(activeActionBars, activeWindow, - ICathyConstants.ID_TOOL_ITEM_UNDO, ActionFactory.UNDO.getId(), - ActionFactory.UNDO.getCommandId(), TOOLTIP, newTrackedHandlers); - updateItemLabel(activeActionBars, activeWindow, - ICathyConstants.ID_TOOL_ITEM_REDO, ActionFactory.REDO.getId(), - ActionFactory.REDO.getCommandId(), TOOLTIP, newTrackedHandlers); - - this.trackedHandlers = newTrackedHandlers; - - if (oldTrackedHandlers != null) { - for (IAction handler : oldTrackedHandlers) { - if (!newTrackedHandlers.contains(handler)) { - handler.removePropertyChangeListener(this); - } - } - } - for (IAction handler : newTrackedHandlers) { - if (oldTrackedHandlers == null - || !oldTrackedHandlers.contains(handler)) { - handler.addPropertyChangeListener(this); - } - } - } - - private void updateItemLabel(IActionBars actionBars, MUIElement topElement, - String itemId, String actionId, String commandId, int attributes, - Set handlers) { - if (modelService == null || topElement == null) - return; - - MUIElement element = modelService.find(itemId, topElement); - if (!(element instanceof MItem)) - return; - - MItem item = (MItem) element; - - IAction handler = actionBars == null ? null - : actionBars.getGlobalActionHandler(actionId); - - if ((attributes & TEXT) != 0) { - String text = handler == null ? null : handler.getText(); - if (text != null) { - if (!item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { - item.getTransientData().put(DATA_ORIGINAL_TEXT, - item.getLabel()); - } - item.setLabel(text); - } else { - Object originalText = item.getTransientData() - .get(DATA_ORIGINAL_TEXT); - if (originalText != null && originalText instanceof String) { - item.setLabel((String) originalText); - } - } - } - if ((attributes & TOOLTIP) != 0) { - String tooltip = handler == null ? null : handler.getToolTipText(); - if (tooltip != null) { - if (!item.getTransientData() - .containsKey(DATA_ORIGINAL_TOOLTIP)) { - item.getTransientData().put(DATA_ORIGINAL_TOOLTIP, - item.getTooltip()); - } - item.setTooltip(tooltip); - } else { - Object originalTooltip = item.getTransientData() - .get(DATA_ORIGINAL_TOOLTIP); - if (originalTooltip != null - && originalTooltip instanceof String) { - item.setTooltip((String) originalTooltip); - } - } - } - - } - - private MWindow findWindowFor(MUIElement element) { - if (element == null) - return null; - if (element instanceof MWindow) - return (MWindow) element; - MPlaceholder placeholder = element.getCurSharedRef(); - if (placeholder != null) - return findWindowFor(placeholder); - MUIElement parent = element.getParent(); - if (parent != null) - return findWindowFor(parent); - return null; - } - - private IActionBars findActionBars(IWorkbenchWindow window) { - if (window == null) - return null; - - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return null; - - IWorkbenchPart activePart = page.getActivePart(); - if (activePart == null) - return null; - - IWorkbenchPartSite site = activePart.getSite(); - if (site instanceof IEditorSite) - return ((IEditorSite) site).getActionBars(); - if (site instanceof IViewSite) - return ((IViewSite) site).getActionBars(); - return null; - } - - public void propertyChange(PropertyChangeEvent event) { - updateAllItemLabels(); - } - -} + +package org.xmind.cathy.internal; + +import java.util.HashSet; +import java.util.Set; +import java.util.WeakHashMap; + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.di.extensions.EventTopic; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MItem; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.SubActionBars; +import org.eclipse.ui.actions.ActionFactory; +import org.osgi.service.event.Event; + +public class CommandLabelUpdater implements IPropertyChangeListener { + + private static final int TEXT = 1 << 1; + private static final int TOOLTIP = 1 << 2; + + private static final String DATA_ORIGINAL_TEXT = "CommandLabelUpdater:OriginalText"; //$NON-NLS-1$ + private static final String DATA_ORIGINAL_TOOLTIP = "CommandLabelUpdater:OriginalTooltip"; //$NON-NLS-1$ + private static final String WEAK_VALUE_PLACEHOLDER = "WeakValuePlaceHolder"; //$NON-NLS-1$ + + @Inject + private EModelService modelService; + + private MWindow activeWindow = null; + private WeakHashMap activeActionBarsWeakRef = new WeakHashMap(); + private Set trackedHandlers = null; + + @Inject + @Optional + public void applicationStarted( + @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) { + } + + @Inject + @Optional + public void activePartChanged( + @EventTopic(UIEvents.UILifeCycle.ACTIVATE) Event event) { + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(element instanceof MPart)) + return; + + MPart part = (MPart) element; + MWindow window = findWindowFor(part); + if (window == null) + return; + + partActivated(part, window); + } + + private void partActivated(MPart part, MWindow window) { + IWorkbenchWindow ww = window.getContext().get(IWorkbenchWindow.class); + IActionBars actionBars = findActionBars(ww); + + this.activeWindow = window; + Object[] bars = activeActionBarsWeakRef.keySet().toArray(); + IActionBars activeActionBars = bars.length > 0 ? (IActionBars) bars[0] + : null; + + if (actionBars != activeActionBars) { + if (activeActionBars instanceof SubActionBars) { + ((SubActionBars) activeActionBars) + .removePropertyChangeListener(this); + } + activeActionBarsWeakRef.put(actionBars, WEAK_VALUE_PLACEHOLDER); + if (actionBars instanceof SubActionBars) { + ((SubActionBars) actionBars).addPropertyChangeListener(this); + } + + updateAllItemLabels(); + } + } + + private void updateAllItemLabels() { + if (activeWindow == null) + return; + + Set oldTrackedHandlers = this.trackedHandlers; + Set newTrackedHandlers = new HashSet(); + + Object[] bars = activeActionBarsWeakRef.keySet().toArray(); + IActionBars activeActionBars = bars.length > 0 ? (IActionBars) bars[0] + : null; + + updateItemLabel(activeActionBars, activeWindow.getMainMenu(), + ICathyConstants.ID_MENU_ITEM_UNDO, ActionFactory.UNDO.getId(), + ActionFactory.UNDO.getCommandId(), TEXT, newTrackedHandlers); + updateItemLabel(activeActionBars, activeWindow.getMainMenu(), + ICathyConstants.ID_MENU_ITEM_REDO, ActionFactory.REDO.getId(), + ActionFactory.REDO.getCommandId(), TEXT, newTrackedHandlers); + + updateItemLabel(activeActionBars, activeWindow, + ICathyConstants.ID_TOOL_ITEM_UNDO, ActionFactory.UNDO.getId(), + ActionFactory.UNDO.getCommandId(), TOOLTIP, newTrackedHandlers); + updateItemLabel(activeActionBars, activeWindow, + ICathyConstants.ID_TOOL_ITEM_REDO, ActionFactory.REDO.getId(), + ActionFactory.REDO.getCommandId(), TOOLTIP, newTrackedHandlers); + + this.trackedHandlers = newTrackedHandlers; + + if (oldTrackedHandlers != null) { + for (IAction handler : oldTrackedHandlers) { + if (!newTrackedHandlers.contains(handler)) { + handler.removePropertyChangeListener(this); + } + } + } + for (IAction handler : newTrackedHandlers) { + if (oldTrackedHandlers == null + || !oldTrackedHandlers.contains(handler)) { + handler.addPropertyChangeListener(this); + } + } + } + + private void updateItemLabel(IActionBars actionBars, MUIElement topElement, + String itemId, String actionId, String commandId, int attributes, + Set handlers) { + if (modelService == null || topElement == null) + return; + + MUIElement element = modelService.find(itemId, topElement); + if (!(element instanceof MItem)) + return; + + MItem item = (MItem) element; + + IAction handler = actionBars == null ? null + : actionBars.getGlobalActionHandler(actionId); + + if ((attributes & TEXT) != 0) { + String text = handler == null ? null : handler.getText(); + if (text != null) { + if (!item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { + item.getTransientData().put(DATA_ORIGINAL_TEXT, + item.getLabel()); + } + item.setLabel(text); + } else { + Object originalText = item.getTransientData() + .get(DATA_ORIGINAL_TEXT); + if (originalText != null && originalText instanceof String) { + item.setLabel((String) originalText); + } + } + } + if ((attributes & TOOLTIP) != 0) { + String tooltip = handler == null ? null : handler.getToolTipText(); + if (tooltip != null) { + if (!item.getTransientData() + .containsKey(DATA_ORIGINAL_TOOLTIP)) { + item.getTransientData().put(DATA_ORIGINAL_TOOLTIP, + item.getTooltip()); + } + item.setTooltip(tooltip); + } else { + Object originalTooltip = item.getTransientData() + .get(DATA_ORIGINAL_TOOLTIP); + if (originalTooltip != null + && originalTooltip instanceof String) { + item.setTooltip((String) originalTooltip); + } + } + } + + } + + private MWindow findWindowFor(MUIElement element) { + if (element == null) + return null; + if (element instanceof MWindow) + return (MWindow) element; + MPlaceholder placeholder = element.getCurSharedRef(); + if (placeholder != null) + return findWindowFor(placeholder); + MUIElement parent = element.getParent(); + if (parent != null) + return findWindowFor(parent); + return null; + } + + private IActionBars findActionBars(IWorkbenchWindow window) { + if (window == null) + return null; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return null; + + IWorkbenchPart activePart = page.getActivePart(); + if (activePart == null) + return null; + + IWorkbenchPartSite site = activePart.getSite(); + if (site instanceof IEditorSite) + return ((IEditorSite) site).getActionBars(); + if (site instanceof IViewSite) + return ((IViewSite) site).getActionBars(); + return null; + } + + public void propertyChange(PropertyChangeEvent event) { + updateAllItemLabels(); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ConstantsHacker.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ConstantsHacker.java index fa22baef4..a09afd83b 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ConstantsHacker.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ConstantsHacker.java @@ -1,18 +1,18 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.internal.InternalPolicy; - -@SuppressWarnings("restriction") -public class ConstantsHacker { - - private ConstantsHacker() { - } - - public static void hack() { - org.eclipse.ui.internal.WorkbenchMessages.WizardHandler_menuLabel = WorkbenchMessages.ConstantsHacker_WizardHandler_menuLabel; - - // Enable loading ***@2x.png by URLImageDescriptor - InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x = true; - } - -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.internal.InternalPolicy; + +@SuppressWarnings("restriction") +public class ConstantsHacker { + + private ConstantsHacker() { + } + + public static void hack() { + org.eclipse.ui.internal.WorkbenchMessages.WizardHandler_menuLabel = WorkbenchMessages.ConstantsHacker_WizardHandler_menuLabel; + + // Enable loading ***@2x.png by URLImageDescriptor + InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x = true; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/EditorStatePersistance.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/EditorStatePersistance.java index 6d0321f23..1e7616ab5 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/EditorStatePersistance.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/EditorStatePersistance.java @@ -1,308 +1,308 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.cathy.internal; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IPath; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorDescriptor; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchListener; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.WorkbenchException; -import org.eclipse.ui.XMLMemento; -import org.eclipse.ui.dialogs.ListSelectionDialog; -import org.eclipse.ui.internal.IWorkbenchConstants; -import org.xmind.ui.util.Cancelable; -import org.xmind.ui.util.ICancelable; - -/** - * @author Frank Shaka - * - */ -public class EditorStatePersistance { - - private static final String PATH_SESSION = "editorstates.xml"; //$NON-NLS-1$ - - private class EditorStateLabelProvider extends LabelProvider { - - private LocalResourceManager resources; - - /** - * - */ - public EditorStateLabelProvider() { - this.resources = new LocalResourceManager( - JFaceResources.getResources()); - } - - public String getText(Object element) { - if (element instanceof IMemento) { - IMemento state = (IMemento) element; - String name = state.getString(IWorkbenchConstants.TAG_TITLE); - if (name == null) { - name = state.getString(IWorkbenchConstants.TAG_NAME); - } - if (name == null) { - name = state.getString(IWorkbenchConstants.TAG_PART_NAME); - } - if (name == null) { - String editorId = state - .getString(IWorkbenchConstants.TAG_ID); - if (editorId != null) { - IEditorDescriptor editor = workbench.getEditorRegistry() - .findEditor(editorId); - if (editor != null) { - name = editor.getLabel(); - } - } - } - if (name == null) { - name = ""; //$NON-NLS-1$ - } - return name; - } - return super.getText(element); - } - - public Image getImage(Object element) { - if (element instanceof IMemento) { - IMemento state = (IMemento) element; - String editorId = state.getString(IWorkbenchConstants.TAG_ID); - if (editorId != null) { - IEditorDescriptor editor = workbench.getEditorRegistry() - .findEditor(editorId); - if (editor != null) { - ImageDescriptor icon = editor.getImageDescriptor(); - if (icon != null) - return (Image) resources.get(icon); - } - } - } - return super.getImage(element); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() - */ - @Override - public void dispose() { - resources.dispose(); - super.dispose(); - } - - } - - private final IWorkbench workbench; - private final IPath basePath; - private final ILogger logger; - private final int autoSaveIntervals; - private ICancelable autoSaveTask; - - /** - * - */ - public EditorStatePersistance(IWorkbench workbench, IPath basePath, - ILogger logger, int autoSaveIntervals) { - this.workbench = workbench; - this.basePath = basePath; - this.logger = logger == null ? ILogger.DEFAULT : logger; - this.autoSaveIntervals = autoSaveIntervals; - this.autoSaveTask = null; - } - - /** - * Must be called within the UI thread. - * - * @throws WorkbenchException - */ - public void startUp() throws WorkbenchException { - final Display display = workbench.getDisplay(); - Assert.isNotNull(display); - Assert.isTrue(display == Display.getCurrent()); - - try { - recoverLastSession(); - } finally { - schedule(display); - workbench.addWorkbenchListener(new IWorkbenchListener() { - public boolean preShutdown(IWorkbench workbench, - boolean forced) { - return true; - } - - public void postShutdown(IWorkbench workbench) { - shutDown(); - } - }); - } - } - - /** - * @return - */ - private File getSessionFile() { - return basePath.append(PATH_SESSION).toFile(); - } - - /** - * @throws WorkbenchException - */ - private void recoverLastSession() throws WorkbenchException { - File sessionFile = getSessionFile(); - if (sessionFile == null || !sessionFile.exists()) - return; - - XMLMemento root; - try { - Reader reader = new BufferedReader(new FileReader(sessionFile)); - root = XMLMemento.createReadRoot(reader); - } catch (IOException e) { - logger.logError(null, e); - return; - } finally { - sessionFile.delete(); - } - - IMemento[] states = root.getChildren(IWorkbenchConstants.TAG_EDITOR); - if (states.length == 0) - return; - - ListSelectionDialog dialog = new ListSelectionDialog(null, states, - new ArrayContentProvider(), new EditorStateLabelProvider(), - WorkbenchMessages.appWindow_ListSelectionDialog_Text); - dialog.setTitle(WorkbenchMessages.appWindow_ListSelectionDialog_Title); - dialog.setInitialSelections(states); - int ret = dialog.open(); - if (ret == ListSelectionDialog.CANCEL) - return; - - Object[] result = dialog.getResult(); - if (result == null) - return; - - states = new IMemento[result.length]; - System.arraycopy(result, 0, states, 0, result.length); - - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window == null) { - window = workbench.openWorkbenchWindow(null); - } - IWorkbenchPage page = window.getActivePage(); - if (page == null) { - page = window.openPage(null); - } - page.openEditors(null, null, states, 0, 0); - } - - public void shutDown() { - ICancelable task = this.autoSaveTask; - this.autoSaveTask = null; - if (task != null) { - task.cancel(); - } - - File sessionFile = getSessionFile(); - if (sessionFile != null) { - sessionFile.delete(); - } - } - - private void schedule(final Display display) { - ICancelable oldTask = this.autoSaveTask; - ICancelable task = new Cancelable() { - @Override - protected void doJob() { - autoSave(display); - } - }; - this.autoSaveTask = task; - display.timerExec(autoSaveIntervals, task); - if (oldTask != null) { - oldTask.cancel(); - } - } - - private void autoSave(final Display display) { - try { - save(); - } catch (Throwable e) { - logger.logError(null, e); - } - - schedule(display); - } - - /** - * - */ - private void save() throws IOException { - File sessionFile = getSessionFile(); - if (sessionFile == null) - return; - - List states = new ArrayList(); - for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { - IWorkbenchPage page = window.getActivePage(); - if (page == null) - continue; - IMemento[] editorState = page - .getEditorState(page.getEditorReferences(), true); - states.addAll(Arrays.asList(editorState)); - } - - XMLMemento root = XMLMemento - .createWriteRoot(IWorkbenchConstants.TAG_EDITORS); - for (IMemento state : states) { - IMemento st = root.createChild(state.getType()); - st.putMemento(state); - } - - File dir = sessionFile.getParentFile(); - if (dir != null && !dir.exists()) { - dir.mkdirs(); - } - BufferedWriter writer = new BufferedWriter(new FileWriter(sessionFile)); - try { - root.save(writer); - } finally { - writer.close(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.cathy.internal; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.XMLMemento; +import org.eclipse.ui.dialogs.ListSelectionDialog; +import org.eclipse.ui.internal.IWorkbenchConstants; +import org.xmind.ui.util.Cancelable; +import org.xmind.ui.util.ICancelable; + +/** + * @author Frank Shaka + * + */ +public class EditorStatePersistance { + + private static final String PATH_SESSION = "editorstates.xml"; //$NON-NLS-1$ + + private class EditorStateLabelProvider extends LabelProvider { + + private LocalResourceManager resources; + + /** + * + */ + public EditorStateLabelProvider() { + this.resources = new LocalResourceManager( + JFaceResources.getResources()); + } + + public String getText(Object element) { + if (element instanceof IMemento) { + IMemento state = (IMemento) element; + String name = state.getString(IWorkbenchConstants.TAG_TITLE); + if (name == null) { + name = state.getString(IWorkbenchConstants.TAG_NAME); + } + if (name == null) { + name = state.getString(IWorkbenchConstants.TAG_PART_NAME); + } + if (name == null) { + String editorId = state + .getString(IWorkbenchConstants.TAG_ID); + if (editorId != null) { + IEditorDescriptor editor = workbench.getEditorRegistry() + .findEditor(editorId); + if (editor != null) { + name = editor.getLabel(); + } + } + } + if (name == null) { + name = ""; //$NON-NLS-1$ + } + return name; + } + return super.getText(element); + } + + public Image getImage(Object element) { + if (element instanceof IMemento) { + IMemento state = (IMemento) element; + String editorId = state.getString(IWorkbenchConstants.TAG_ID); + if (editorId != null) { + IEditorDescriptor editor = workbench.getEditorRegistry() + .findEditor(editorId); + if (editor != null) { + ImageDescriptor icon = editor.getImageDescriptor(); + if (icon != null) + return (Image) resources.get(icon); + } + } + } + return super.getImage(element); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() + */ + @Override + public void dispose() { + resources.dispose(); + super.dispose(); + } + + } + + private final IWorkbench workbench; + private final IPath basePath; + private final ILogger logger; + private final int autoSaveIntervals; + private ICancelable autoSaveTask; + + /** + * + */ + public EditorStatePersistance(IWorkbench workbench, IPath basePath, + ILogger logger, int autoSaveIntervals) { + this.workbench = workbench; + this.basePath = basePath; + this.logger = logger == null ? ILogger.DEFAULT : logger; + this.autoSaveIntervals = autoSaveIntervals; + this.autoSaveTask = null; + } + + /** + * Must be called within the UI thread. + * + * @throws WorkbenchException + */ + public void startUp() throws WorkbenchException { + final Display display = workbench.getDisplay(); + Assert.isNotNull(display); + Assert.isTrue(display == Display.getCurrent()); + + try { + recoverLastSession(); + } finally { + schedule(display); + workbench.addWorkbenchListener(new IWorkbenchListener() { + public boolean preShutdown(IWorkbench workbench, + boolean forced) { + return true; + } + + public void postShutdown(IWorkbench workbench) { + shutDown(); + } + }); + } + } + + /** + * @return + */ + private File getSessionFile() { + return basePath.append(PATH_SESSION).toFile(); + } + + /** + * @throws WorkbenchException + */ + private void recoverLastSession() throws WorkbenchException { + File sessionFile = getSessionFile(); + if (sessionFile == null || !sessionFile.exists()) + return; + + XMLMemento root; + try { + Reader reader = new BufferedReader(new FileReader(sessionFile)); + root = XMLMemento.createReadRoot(reader); + } catch (IOException e) { + logger.logError(null, e); + return; + } finally { + sessionFile.delete(); + } + + IMemento[] states = root.getChildren(IWorkbenchConstants.TAG_EDITOR); + if (states.length == 0) + return; + + ListSelectionDialog dialog = new ListSelectionDialog(null, states, + new ArrayContentProvider(), new EditorStateLabelProvider(), + WorkbenchMessages.appWindow_ListSelectionDialog_Text); + dialog.setTitle(WorkbenchMessages.appWindow_ListSelectionDialog_Title); + dialog.setInitialSelections(states); + int ret = dialog.open(); + if (ret == ListSelectionDialog.CANCEL) + return; + + Object[] result = dialog.getResult(); + if (result == null) + return; + + states = new IMemento[result.length]; + System.arraycopy(result, 0, states, 0, result.length); + + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) { + window = workbench.openWorkbenchWindow(null); + } + IWorkbenchPage page = window.getActivePage(); + if (page == null) { + page = window.openPage(null); + } + page.openEditors(null, null, states, 0, 0); + } + + public void shutDown() { + ICancelable task = this.autoSaveTask; + this.autoSaveTask = null; + if (task != null) { + task.cancel(); + } + + File sessionFile = getSessionFile(); + if (sessionFile != null) { + sessionFile.delete(); + } + } + + private void schedule(final Display display) { + ICancelable oldTask = this.autoSaveTask; + ICancelable task = new Cancelable() { + @Override + protected void doJob() { + autoSave(display); + } + }; + this.autoSaveTask = task; + display.timerExec(autoSaveIntervals, task); + if (oldTask != null) { + oldTask.cancel(); + } + } + + private void autoSave(final Display display) { + try { + save(); + } catch (Throwable e) { + logger.logError(null, e); + } + + schedule(display); + } + + /** + * + */ + private void save() throws IOException { + File sessionFile = getSessionFile(); + if (sessionFile == null) + return; + + List states = new ArrayList(); + for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { + IWorkbenchPage page = window.getActivePage(); + if (page == null) + continue; + IMemento[] editorState = page + .getEditorState(page.getEditorReferences(), true); + states.addAll(Arrays.asList(editorState)); + } + + XMLMemento root = XMLMemento + .createWriteRoot(IWorkbenchConstants.TAG_EDITORS); + for (IMemento state : states) { + IMemento st = root.createChild(state.getType()); + st.putMemento(state); + } + + File dir = sessionFile.getParentFile(); + if (dir != null && !dir.exists()) { + dir.mkdirs(); + } + BufferedWriter writer = new BufferedWriter(new FileWriter(sessionFile)); + try { + root.save(writer); + } finally { + writer.close(); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPrefPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPrefPage.java index a6b66802e..8fc1e631d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPrefPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPrefPage.java @@ -1,617 +1,617 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.FieldEditor; -import org.eclipse.jface.preference.FieldEditorPreferencePage; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.IntegerFieldEditor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.core.usagedata.IUsageDataUploader; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.util.NumberUtils; - -public class GeneralPrefPage extends FieldEditorPreferencePage - implements IWorkbenchPreferencePage, Listener { - -// private static class SoftCheckFileFieldEditor -// extends StringButtonFieldEditor { -// -// private String[] extensions = null; -// -// private String[] extensionNames = null; -// -// public SoftCheckFileFieldEditor(String name, String labelText, -// Composite parent) { -// init(name, labelText); -// setChangeButtonText(JFaceResources.getString("openBrowse"));//$NON-NLS-1$ -// createControl(parent); -// } -// -// @Override -// public void setEmptyStringAllowed(boolean b) { -// super.setEmptyStringAllowed(b); -// refreshValidState(); -// } -// -// @Override -// protected boolean checkState() { -// Text text = getTextControl(); -// if (text == null) -// return false; -// boolean validFile; -// String path = text.getText(); -// if ("".equals(path)) { //$NON-NLS-1$ -// validFile = isEmptyStringAllowed(); -// } else { -// validFile = new File(path).isFile(); -// } -// if (validFile) { -// getPage().setMessage(null); -// } else { -// getPage().setMessage(getErrorMessage(), -// IMessageProvider.WARNING); -// } -// return validFile; -// } -// -// @Override -// protected String changePressed() { -// File f = new File(getTextControl().getText()); -// if (!f.exists()) { -// f = null; -// } -// File d = getFile(f); -// if (d == null) { -// return null; -// } -// return d.getAbsolutePath(); -// } -// -// /** -// * Helper to open the file chooser dialog. -// * -// * @param startingDirectory -// * the directory to open the dialog on. -// * @return File The File the user selected or null if they -// * do not. -// */ -// private File getFile(File startingDirectory) { -// FileDialog dialog = new FileDialog(getShell(), -// SWT.OPEN | SWT.SHEET); -// if (extensions != null) { -// dialog.setFilterExtensions(extensions); -// if (extensionNames != null) { -// dialog.setFilterNames(extensionNames); -// } -// } -// if (startingDirectory != null) { -// dialog.setFileName(startingDirectory.getPath()); -// } -// String file = dialog.open(); -// if (file != null) { -// file = file.trim(); -// if (file.length() > 0) { -// return new File(file); -// } -// } -// -// return null; -// } -// -// public void setExtensions(String[] extensions) { -// this.extensions = extensions; -// } -// -// public void setExtensionNames(String[] extensionNames) { -// this.extensionNames = extensionNames; -// } -// -// } - -// private IntegerFieldEditor autoSaveIntervalsField; -// -// private Composite autoSaveIntervalsParent; - - private Text autoSaveIntervalsInput; - - private boolean autoBackup = true; - - private BooleanFieldEditor autoBackupField; - - private IntegerFieldEditor recentFilesField; - -// private Combo startupActionCombo; -// -// private SoftCheckFileFieldEditor homeMapField; -// -// private Control homeMapControl; - - private Control recentFilesControl; - - private Button startupActionButton; - - private ResourceManager resources; - - public GeneralPrefPage() { - super(WorkbenchMessages.GeneralPrefPage_title, FLAT); - } - - @Override - public void applyData(Object data) { - if (IPreferenceConstants.RECENT_FILES.equals(data)) { - if (recentFilesControl != null - && !recentFilesControl.isDisposed()) { - recentFilesControl.setFocus(); - highlight(recentFilesControl.getParent()); - } - } - } - - private void highlight(final Control control) { - final Display display = control.getDisplay(); - final Color oldBackground = control.getBackground(); - final Color c1 = oldBackground == null - ? display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND) - : oldBackground; - final int r1 = c1.getRed(), g1 = c1.getGreen(), b1 = c1.getBlue(); - final int r0 = 255, g0 = 240, b0 = 180; - final int total = 30; - final int[] step = new int[] { 0 }; - final Color[] c = new Color[1]; - display.timerExec(500, new Runnable() { - public void run() { - if (control.isDisposed()) - return; - c[0] = new Color(display, r0, g0, b0); - control.setBackground(c[0]); - display.timerExec(20, new Runnable() { - public void run() { - c[0].dispose(); - - if (control.isDisposed()) - return; - - ++step[0]; - if (step[0] > total) { - control.setBackground(null); - return; - } - - int x = step[0], y = total - step[0]; - int r = (r0 * y + r1 * x) / total; - int g = (g0 * y + g1 * x) / total; - int b = (b0 * y + b1 * x) / total; - c[0] = new Color(display, r, g, b); - control.setBackground(c[0]); - display.timerExec(20, this); - } - }); - } - }); - } - - protected IPreferenceStore doGetPreferenceStore() { - return CathyPlugin.getDefault().getPreferenceStore(); - } - - @Override - public void createControl(Composite parent) { - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - super.createControl(parent); - } - - protected Control createContents(Composite parent) { - Composite composite = (Composite) super.createContents(parent); - ((GridLayout) composite.getLayout()).verticalSpacing = 15; - return composite; - } - - protected void createFieldEditors() { - addStartupGroup(); - addRecentFileCountField(); - addAutoSaveGroup(); - addAutoBackupGroup(); - //addRememberLastSessionField(); - //addCheckUpdatesField(); - addSendUsageDataGroup(); - } - - private void addStartupGroup() { - Composite parent = createGroup(WorkbenchMessages.Startup_title); - addStartupActionField(parent); - addCheckUpdatesField(parent); - } - - private void addStartupActionField(Composite parent) { - startupActionButton = new Button(parent, SWT.CHECK); - startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); -// addField(new BooleanFieldEditor(CathyPlugin.RESTORE_LAST_SESSION, -// WorkbenchMessages.StartupAction_LastSession, -// createFieldContainer(parent, false))); -// Composite line = new Composite(parent, SWT.NONE); -// line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); -// GridLayout layout = new GridLayout(2, false); -// layout.marginHeight = 0; -// layout.marginWidth = 0; -// line.setLayout(layout); -// fillStartupActionFields(line); - } - -// private void fillStartupActionFields(Composite parent) { -// Label label = new Label(parent, SWT.NONE); -// label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); -// label.setText(WorkbenchMessages.StartupAction_label); -// -// startupActionCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); -// startupActionCombo -// .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); -// startupActionCombo.add(WorkbenchMessages.StartupAction_OpenDialog); -// startupActionCombo.add(WorkbenchMessages.StartupAction_BlankMap); -// startupActionCombo.add(WorkbenchMessages.StartupAction_HomeMap); -// startupActionCombo.add(WorkbenchMessages.StartupAction_LastSession); -// startupActionCombo.addListener(SWT.Selection, this); -// } - -// private void addHomeMapField(Composite parent) { -// Composite line = new Composite(parent, SWT.NONE); -// line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); -// GridLayout layout = new GridLayout(2, false); -// layout.marginHeight = 0; -// layout.marginWidth = 0; -// line.setLayout(layout); -// fillHomeMapFields(line); -// } - -// private void fillHomeMapFields(Composite parent) { -// Composite container = createFieldContainer(parent, true); -// addField(homeMapField = new SoftCheckFileFieldEditor( -// PrefConstants.HOME_MAP_LOCATION, -// WorkbenchMessages.HomeMap_label, container)); -// homeMapControl = homeMapField.getTextControl(container); -// homeMapField.setErrorMessage(WorkbenchMessages.HomeMap_NotFound_error); -// String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ -// homeMapField.setExtensions(new String[] { xmindExt }); -// homeMapField.setExtensionNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ -// DialogMessages.WorkbookFilterName, xmindExt) }); -// } - - private void addCheckUpdatesField(Composite parent) { - addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, - WorkbenchMessages.CheckUpdates_label, - createFieldContainer(parent, true))); - } - - private void addRecentFileCountField() { - Composite container = getFieldEditorParent(); - addField(recentFilesField = new IntegerFieldEditor( - IPreferenceConstants.RECENT_FILES, - WorkbenchMessages.RecentFiles_label, container)); - recentFilesControl = recentFilesField.getTextControl(container); - } - -// private void addRememberLastSessionField() { -// addField(new BooleanFieldEditor(CathyPlugin.RESTORE_LAST_SESSION, -// WorkbenchMessages.RestoreLastSession_label, -// getFieldEditorParent())); -// } -// -// private void addCheckUpdatesField() { -// addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, -// WorkbenchMessages.CheckUpdates_label, getFieldEditorParent())); -// } - - private void addAutoSaveGroup() { - String message = WorkbenchMessages.AutoSave_label2; - int index = message.indexOf("{0}"); //$NON-NLS-1$ - int cols = 3; - String label1, label2; - if (index >= 0) { - label1 = message.substring(0, index); - label2 = message.substring(index + 3); - if ("".equals(label2)) { //$NON-NLS-1$ - label2 = null; - cols--; - } - } else { - label1 = message; - label2 = null; - cols--; - if ("".equals(label1)) {//$NON-NLS-1$ - label1 = null; - cols--; - } - } - - Composite parent = getFieldEditorParent(); - GridLayout gridLayout = new GridLayout(cols, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - parent.setLayout(gridLayout); -// parent.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true)); -// ((GridData) composite.getLayoutData()).horizontalIndent = 10; - - Composite booleanParent = new Composite(parent, SWT.NONE); - booleanParent - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); - addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, - booleanParent)); - - autoSaveIntervalsInput = new Text(parent, - SWT.SINGLE | SWT.BORDER | SWT.CENTER); - autoSaveIntervalsInput - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); - ((GridData) autoSaveIntervalsInput.getLayoutData()).widthHint = 40; - autoSaveIntervalsInput.setEnabled( - getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED)); - - if (label2 != null) { - Label label = new Label(parent, SWT.NONE); - label.setText(label2); - label.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, false, true)); - } - } - -// private void addAutoSaveGroup() { -// Composite parent = getFieldEditorParent(); -// GridLayout gridLayout = new GridLayout(2, false); -// gridLayout.marginWidth = 0; -// gridLayout.marginHeight = 0; -// gridLayout.verticalSpacing = 0; -// gridLayout.horizontalSpacing = 0; -// parent.setLayout(gridLayout); -// -//// PreferenceLinkArea link = new PreferenceLinkArea(parent, -//// SWT.NONE, -//// "org.xmind.ui.BackupPrefPage", //$NON-NLS-1$ -//// "See
''{0}'' for auto saving and backup options.", -//// (IWorkbenchPreferenceContainer) getContainer(), null); -//// link.getControl().setLayoutData( -//// new GridData(SWT.FILL, SWT.FILL, true, false)); -// -// -// addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, -// WorkbenchMessages.AutoSave_label, createFieldContainer(parent, -// false))); -// -// autoSaveIntervalsParent = createFieldContainer(parent, true); -// -// addField(autoSaveIntervalsField = new IntegerFieldEditor( -// CathyPlugin.AUTO_SAVE_INTERVALS, "", //$NON-NLS-1$ -// autoSaveIntervalsParent)); -// -// autoSaveIntervalsField.setEnabled( -// getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), -// autoSaveIntervalsParent); -// -// Label label = new Label(parent, SWT.NONE); -// label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, -// false)); -// label.setText(WorkbenchMessages.AutoSave_Minutes); -// -// } - - private void addAutoBackupGroup() { - Composite parent = getFieldEditorParent(); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - parent.setLayout(gridLayout); - addField(autoBackupField = new BooleanFieldEditor( - PrefConstants.AUTO_BACKUP_ENABLE, - WorkbenchMessages.AutoBackup_label, - createFieldContainer(parent, true))); - } - - private void addSendUsageDataGroup() { - Composite composite = getFieldEditorParent(); - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 5; - composite.setLayout(gridLayout); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - - GridLayout gridLayout2 = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite2.setLayout(gridLayout2); - - addField(new BooleanFieldEditor( - CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, - WorkbenchMessages.GeneralPrefPage_usageData_text, composite2)); - - // - Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); - privacyHyperlink.setBackground(composite.getBackground()); - privacyHyperlink.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - privacyHyperlink - .setText(WorkbenchMessages.GeneralPrefPage_seePolicy_link); - privacyHyperlink.setUnderlined(true); - privacyHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#77afe0"))); //$NON-NLS-1$ - privacyHyperlink.addHyperlinkListener(new HyperlinkAdapter() { - public void linkActivated(HyperlinkEvent e) { - Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ - } - }); - - if (CathyPlugin.getDefault() - .isDebugging("/debug/udc/showUploadButton")) { //$NON-NLS-1$ - Button uploadButton = new Button(composite, SWT.PUSH); - GridData layoutData = new GridData(SWT.BEGINNING, SWT.CENTER, false, - false); - layoutData.horizontalSpan = 2; - layoutData.horizontalIndent = 10; - layoutData.minimumWidth = 100; - uploadButton.setLayoutData(layoutData); - uploadButton.setBackground(composite.getBackground()); - uploadButton.setText("Upload Now"); //$NON-NLS-1$ - uploadButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - IUsageDataSampler sampler = CathyPlugin.getDefault() - .getUsageDataCollector(); - if (sampler instanceof IUsageDataUploader) { - ((IUsageDataUploader) sampler).forceUpload(); - } - } - }); - } - } - - private Composite createFieldContainer(Composite parent, - boolean grabHorizontal) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, grabHorizontal, true)); - composite.setLayout(new GridLayout(1, false)); - return composite; - } - - private Composite createGroup(String groupTitle) { - Composite parent = getFieldEditorParent(); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - parent.setLayout(gridLayout); - - Group group = new Group(parent, SWT.NONE); - group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - group.setLayout(new GridLayout(1, false)); - group.setText(groupTitle); - return group; - } - - @Override - protected void initialize() { - super.initialize(); - int startupAction = getPreferenceStore() - .getInt(CathyPlugin.STARTUP_ACTION); - startupActionButton - .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); -// startupActionCombo.select(startupAction); - -// homeMapField.setPreferenceStore( -// MindMapUIPlugin.getDefault().getPreferenceStore()); -// homeMapField.setEmptyStringAllowed( -// startupAction != CathyPlugin.STARTUP_ACTION_HOME); -// homeMapField.load(); - - recentFilesField.setPreferenceStore( - WorkbenchPlugin.getDefault().getPreferenceStore()); - recentFilesField.load(); - - autoSaveIntervalsInput.setText(String.valueOf( - getPreferenceStore().getInt(CathyPlugin.AUTO_SAVE_INTERVALS))); - autoBackupField.setPreferenceStore( - MindMapUIPlugin.getDefault().getPreferenceStore()); - autoBackupField.load(); - } - - public void init(IWorkbench workbench) { - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - - if (startupActionButton.getSelection()) { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_LAST); - } else { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_WIZARD); - } - - int autoSaveIntervals = NumberUtils - .safeParseInt(autoSaveIntervalsInput.getText(), 0); - getPreferenceStore().setValue(CathyPlugin.AUTO_SAVE_INTERVALS, - autoSaveIntervals); - MindMapUIPlugin.getDefault().getPreferenceStore() - .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); - return true; - } - - public void propertyChange(PropertyChangeEvent event) { - super.propertyChange(event); - if (event.getSource() instanceof FieldEditor) { - FieldEditor fe = (FieldEditor) event.getSource(); - if (event.getProperty().equals(FieldEditor.VALUE)) { - String prefName = fe.getPreferenceName(); - if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { - autoSaveIntervalsInput.setEnabled( - ((Boolean) event.getNewValue()).booleanValue()); -// autoSaveIntervalsField.setEnabled( -// (Boolean) event.getNewValue(), -// autoSaveIntervalsParent); - } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { - autoBackup = ((Boolean) event.getNewValue()).booleanValue(); - } - } - } - } - - public void handleEvent(Event event) { -// if (event.widget == startupActionCombo) { -// int startupAction = startupActionCombo.getSelectionIndex(); -// homeMapField.setEmptyStringAllowed( -// startupAction != CathyPlugin.STARTUP_ACTION_HOME); -// checkState(); -// } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.core.usagedata.IUsageDataUploader; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.NumberUtils; + +public class GeneralPrefPage extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage, Listener { + +// private static class SoftCheckFileFieldEditor +// extends StringButtonFieldEditor { +// +// private String[] extensions = null; +// +// private String[] extensionNames = null; +// +// public SoftCheckFileFieldEditor(String name, String labelText, +// Composite parent) { +// init(name, labelText); +// setChangeButtonText(JFaceResources.getString("openBrowse"));//$NON-NLS-1$ +// createControl(parent); +// } +// +// @Override +// public void setEmptyStringAllowed(boolean b) { +// super.setEmptyStringAllowed(b); +// refreshValidState(); +// } +// +// @Override +// protected boolean checkState() { +// Text text = getTextControl(); +// if (text == null) +// return false; +// boolean validFile; +// String path = text.getText(); +// if ("".equals(path)) { //$NON-NLS-1$ +// validFile = isEmptyStringAllowed(); +// } else { +// validFile = new File(path).isFile(); +// } +// if (validFile) { +// getPage().setMessage(null); +// } else { +// getPage().setMessage(getErrorMessage(), +// IMessageProvider.WARNING); +// } +// return validFile; +// } +// +// @Override +// protected String changePressed() { +// File f = new File(getTextControl().getText()); +// if (!f.exists()) { +// f = null; +// } +// File d = getFile(f); +// if (d == null) { +// return null; +// } +// return d.getAbsolutePath(); +// } +// +// /** +// * Helper to open the file chooser dialog. +// * +// * @param startingDirectory +// * the directory to open the dialog on. +// * @return File The File the user selected or null if they +// * do not. +// */ +// private File getFile(File startingDirectory) { +// FileDialog dialog = new FileDialog(getShell(), +// SWT.OPEN | SWT.SHEET); +// if (extensions != null) { +// dialog.setFilterExtensions(extensions); +// if (extensionNames != null) { +// dialog.setFilterNames(extensionNames); +// } +// } +// if (startingDirectory != null) { +// dialog.setFileName(startingDirectory.getPath()); +// } +// String file = dialog.open(); +// if (file != null) { +// file = file.trim(); +// if (file.length() > 0) { +// return new File(file); +// } +// } +// +// return null; +// } +// +// public void setExtensions(String[] extensions) { +// this.extensions = extensions; +// } +// +// public void setExtensionNames(String[] extensionNames) { +// this.extensionNames = extensionNames; +// } +// +// } + +// private IntegerFieldEditor autoSaveIntervalsField; +// +// private Composite autoSaveIntervalsParent; + + private Text autoSaveIntervalsInput; + + private boolean autoBackup = true; + + private BooleanFieldEditor autoBackupField; + + private IntegerFieldEditor recentFilesField; + +// private Combo startupActionCombo; +// +// private SoftCheckFileFieldEditor homeMapField; +// +// private Control homeMapControl; + + private Control recentFilesControl; + + private Button startupActionButton; + + private ResourceManager resources; + + public GeneralPrefPage() { + super(WorkbenchMessages.GeneralPrefPage_title, FLAT); + } + + @Override + public void applyData(Object data) { + if (IPreferenceConstants.RECENT_FILES.equals(data)) { + if (recentFilesControl != null + && !recentFilesControl.isDisposed()) { + recentFilesControl.setFocus(); + highlight(recentFilesControl.getParent()); + } + } + } + + private void highlight(final Control control) { + final Display display = control.getDisplay(); + final Color oldBackground = control.getBackground(); + final Color c1 = oldBackground == null + ? display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND) + : oldBackground; + final int r1 = c1.getRed(), g1 = c1.getGreen(), b1 = c1.getBlue(); + final int r0 = 255, g0 = 240, b0 = 180; + final int total = 30; + final int[] step = new int[] { 0 }; + final Color[] c = new Color[1]; + display.timerExec(500, new Runnable() { + public void run() { + if (control.isDisposed()) + return; + c[0] = new Color(display, r0, g0, b0); + control.setBackground(c[0]); + display.timerExec(20, new Runnable() { + public void run() { + c[0].dispose(); + + if (control.isDisposed()) + return; + + ++step[0]; + if (step[0] > total) { + control.setBackground(null); + return; + } + + int x = step[0], y = total - step[0]; + int r = (r0 * y + r1 * x) / total; + int g = (g0 * y + g1 * x) / total; + int b = (b0 * y + b1 * x) / total; + c[0] = new Color(display, r, g, b); + control.setBackground(c[0]); + display.timerExec(20, this); + } + }); + } + }); + } + + protected IPreferenceStore doGetPreferenceStore() { + return CathyPlugin.getDefault().getPreferenceStore(); + } + + @Override + public void createControl(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + super.createControl(parent); + } + + protected Control createContents(Composite parent) { + Composite composite = (Composite) super.createContents(parent); + ((GridLayout) composite.getLayout()).verticalSpacing = 15; + return composite; + } + + protected void createFieldEditors() { + addStartupGroup(); + addRecentFileCountField(); + addAutoSaveGroup(); + addAutoBackupGroup(); + //addRememberLastSessionField(); + //addCheckUpdatesField(); + addSendUsageDataGroup(); + } + + private void addStartupGroup() { + Composite parent = createGroup(WorkbenchMessages.Startup_title); + addStartupActionField(parent); + addCheckUpdatesField(parent); + } + + private void addStartupActionField(Composite parent) { + startupActionButton = new Button(parent, SWT.CHECK); + startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); +// addField(new BooleanFieldEditor(CathyPlugin.RESTORE_LAST_SESSION, +// WorkbenchMessages.StartupAction_LastSession, +// createFieldContainer(parent, false))); +// Composite line = new Composite(parent, SWT.NONE); +// line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); +// GridLayout layout = new GridLayout(2, false); +// layout.marginHeight = 0; +// layout.marginWidth = 0; +// line.setLayout(layout); +// fillStartupActionFields(line); + } + +// private void fillStartupActionFields(Composite parent) { +// Label label = new Label(parent, SWT.NONE); +// label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); +// label.setText(WorkbenchMessages.StartupAction_label); +// +// startupActionCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); +// startupActionCombo +// .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); +// startupActionCombo.add(WorkbenchMessages.StartupAction_OpenDialog); +// startupActionCombo.add(WorkbenchMessages.StartupAction_BlankMap); +// startupActionCombo.add(WorkbenchMessages.StartupAction_HomeMap); +// startupActionCombo.add(WorkbenchMessages.StartupAction_LastSession); +// startupActionCombo.addListener(SWT.Selection, this); +// } + +// private void addHomeMapField(Composite parent) { +// Composite line = new Composite(parent, SWT.NONE); +// line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); +// GridLayout layout = new GridLayout(2, false); +// layout.marginHeight = 0; +// layout.marginWidth = 0; +// line.setLayout(layout); +// fillHomeMapFields(line); +// } + +// private void fillHomeMapFields(Composite parent) { +// Composite container = createFieldContainer(parent, true); +// addField(homeMapField = new SoftCheckFileFieldEditor( +// PrefConstants.HOME_MAP_LOCATION, +// WorkbenchMessages.HomeMap_label, container)); +// homeMapControl = homeMapField.getTextControl(container); +// homeMapField.setErrorMessage(WorkbenchMessages.HomeMap_NotFound_error); +// String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ +// homeMapField.setExtensions(new String[] { xmindExt }); +// homeMapField.setExtensionNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ +// DialogMessages.WorkbookFilterName, xmindExt) }); +// } + + private void addCheckUpdatesField(Composite parent) { + addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, + WorkbenchMessages.CheckUpdates_label, + createFieldContainer(parent, true))); + } + + private void addRecentFileCountField() { + Composite container = getFieldEditorParent(); + addField(recentFilesField = new IntegerFieldEditor( + IPreferenceConstants.RECENT_FILES, + WorkbenchMessages.RecentFiles_label, container)); + recentFilesControl = recentFilesField.getTextControl(container); + } + +// private void addRememberLastSessionField() { +// addField(new BooleanFieldEditor(CathyPlugin.RESTORE_LAST_SESSION, +// WorkbenchMessages.RestoreLastSession_label, +// getFieldEditorParent())); +// } +// +// private void addCheckUpdatesField() { +// addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, +// WorkbenchMessages.CheckUpdates_label, getFieldEditorParent())); +// } + + private void addAutoSaveGroup() { + String message = WorkbenchMessages.AutoSave_label2; + int index = message.indexOf("{0}"); //$NON-NLS-1$ + int cols = 3; + String label1, label2; + if (index >= 0) { + label1 = message.substring(0, index); + label2 = message.substring(index + 3); + if ("".equals(label2)) { //$NON-NLS-1$ + label2 = null; + cols--; + } + } else { + label1 = message; + label2 = null; + cols--; + if ("".equals(label1)) {//$NON-NLS-1$ + label1 = null; + cols--; + } + } + + Composite parent = getFieldEditorParent(); + GridLayout gridLayout = new GridLayout(cols, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + parent.setLayout(gridLayout); +// parent.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true)); +// ((GridData) composite.getLayoutData()).horizontalIndent = 10; + + Composite booleanParent = new Composite(parent, SWT.NONE); + booleanParent + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); + addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, + booleanParent)); + + autoSaveIntervalsInput = new Text(parent, + SWT.SINGLE | SWT.BORDER | SWT.CENTER); + autoSaveIntervalsInput + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); + ((GridData) autoSaveIntervalsInput.getLayoutData()).widthHint = 40; + autoSaveIntervalsInput.setEnabled( + getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED)); + + if (label2 != null) { + Label label = new Label(parent, SWT.NONE); + label.setText(label2); + label.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, false, true)); + } + } + +// private void addAutoSaveGroup() { +// Composite parent = getFieldEditorParent(); +// GridLayout gridLayout = new GridLayout(2, false); +// gridLayout.marginWidth = 0; +// gridLayout.marginHeight = 0; +// gridLayout.verticalSpacing = 0; +// gridLayout.horizontalSpacing = 0; +// parent.setLayout(gridLayout); +// +//// PreferenceLinkArea link = new PreferenceLinkArea(parent, +//// SWT.NONE, +//// "org.xmind.ui.BackupPrefPage", //$NON-NLS-1$ +//// "See ''{0}'' for auto saving and backup options.", +//// (IWorkbenchPreferenceContainer) getContainer(), null); +//// link.getControl().setLayoutData( +//// new GridData(SWT.FILL, SWT.FILL, true, false)); +// +// +// addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, +// WorkbenchMessages.AutoSave_label, createFieldContainer(parent, +// false))); +// +// autoSaveIntervalsParent = createFieldContainer(parent, true); +// +// addField(autoSaveIntervalsField = new IntegerFieldEditor( +// CathyPlugin.AUTO_SAVE_INTERVALS, "", //$NON-NLS-1$ +// autoSaveIntervalsParent)); +// +// autoSaveIntervalsField.setEnabled( +// getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), +// autoSaveIntervalsParent); +// +// Label label = new Label(parent, SWT.NONE); +// label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, +// false)); +// label.setText(WorkbenchMessages.AutoSave_Minutes); +// +// } + + private void addAutoBackupGroup() { + Composite parent = getFieldEditorParent(); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + parent.setLayout(gridLayout); + addField(autoBackupField = new BooleanFieldEditor( + PrefConstants.AUTO_BACKUP_ENABLE, + WorkbenchMessages.AutoBackup_label, + createFieldContainer(parent, true))); + } + + private void addSendUsageDataGroup() { + Composite composite = getFieldEditorParent(); + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 5; + composite.setLayout(gridLayout); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + + GridLayout gridLayout2 = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite2.setLayout(gridLayout2); + + addField(new BooleanFieldEditor( + CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, + WorkbenchMessages.GeneralPrefPage_usageData_text, composite2)); + + // + Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); + privacyHyperlink.setBackground(composite.getBackground()); + privacyHyperlink.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + privacyHyperlink + .setText(WorkbenchMessages.GeneralPrefPage_seePolicy_link); + privacyHyperlink.setUnderlined(true); + privacyHyperlink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#77afe0"))); //$NON-NLS-1$ + privacyHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ + } + }); + + if (CathyPlugin.getDefault() + .isDebugging("/debug/udc/showUploadButton")) { //$NON-NLS-1$ + Button uploadButton = new Button(composite, SWT.PUSH); + GridData layoutData = new GridData(SWT.BEGINNING, SWT.CENTER, false, + false); + layoutData.horizontalSpan = 2; + layoutData.horizontalIndent = 10; + layoutData.minimumWidth = 100; + uploadButton.setLayoutData(layoutData); + uploadButton.setBackground(composite.getBackground()); + uploadButton.setText("Upload Now"); //$NON-NLS-1$ + uploadButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + IUsageDataSampler sampler = CathyPlugin.getDefault() + .getUsageDataCollector(); + if (sampler instanceof IUsageDataUploader) { + ((IUsageDataUploader) sampler).forceUpload(); + } + } + }); + } + } + + private Composite createFieldContainer(Composite parent, + boolean grabHorizontal) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, grabHorizontal, true)); + composite.setLayout(new GridLayout(1, false)); + return composite; + } + + private Composite createGroup(String groupTitle) { + Composite parent = getFieldEditorParent(); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + parent.setLayout(gridLayout); + + Group group = new Group(parent, SWT.NONE); + group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + group.setLayout(new GridLayout(1, false)); + group.setText(groupTitle); + return group; + } + + @Override + protected void initialize() { + super.initialize(); + int startupAction = getPreferenceStore() + .getInt(CathyPlugin.STARTUP_ACTION); + startupActionButton + .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); +// startupActionCombo.select(startupAction); + +// homeMapField.setPreferenceStore( +// MindMapUIPlugin.getDefault().getPreferenceStore()); +// homeMapField.setEmptyStringAllowed( +// startupAction != CathyPlugin.STARTUP_ACTION_HOME); +// homeMapField.load(); + + recentFilesField.setPreferenceStore( + WorkbenchPlugin.getDefault().getPreferenceStore()); + recentFilesField.load(); + + autoSaveIntervalsInput.setText(String.valueOf( + getPreferenceStore().getInt(CathyPlugin.AUTO_SAVE_INTERVALS))); + autoBackupField.setPreferenceStore( + MindMapUIPlugin.getDefault().getPreferenceStore()); + autoBackupField.load(); + } + + public void init(IWorkbench workbench) { + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + + if (startupActionButton.getSelection()) { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_LAST); + } else { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_WIZARD); + } + + int autoSaveIntervals = NumberUtils + .safeParseInt(autoSaveIntervalsInput.getText(), 0); + getPreferenceStore().setValue(CathyPlugin.AUTO_SAVE_INTERVALS, + autoSaveIntervals); + MindMapUIPlugin.getDefault().getPreferenceStore() + .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); + return true; + } + + public void propertyChange(PropertyChangeEvent event) { + super.propertyChange(event); + if (event.getSource() instanceof FieldEditor) { + FieldEditor fe = (FieldEditor) event.getSource(); + if (event.getProperty().equals(FieldEditor.VALUE)) { + String prefName = fe.getPreferenceName(); + if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { + autoSaveIntervalsInput.setEnabled( + ((Boolean) event.getNewValue()).booleanValue()); +// autoSaveIntervalsField.setEnabled( +// (Boolean) event.getNewValue(), +// autoSaveIntervalsParent); + } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { + autoBackup = ((Boolean) event.getNewValue()).booleanValue(); + } + } + } + } + + public void handleEvent(Event event) { +// if (event.widget == startupActionCombo) { +// int startupAction = startupActionCombo.getSelectionIndex(); +// homeMapField.setEmptyStringAllowed( +// startupAction != CathyPlugin.STARTUP_ACTION_HOME); +// checkState(); +// } + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPreferencePageSection.java index d3a69477a..b873f536c 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPreferencePageSection.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPreferencePageSection.java @@ -1,218 +1,218 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.ComboFieldEditor; -import org.eclipse.jface.preference.FieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.preference.PreferenceFieldEditorPageSection; -import org.xmind.ui.prefs.PrefConstants; - -public class GeneralPreferencePageSection extends - PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { - - private FieldEditor autoSaveInterval; - - private String[][] saveIntervals = new String[][] { { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ - { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ - { "30", "30" }, { "60", "60" } }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ - - private String[][] filesList = new String[][] { { "4", "4" }, { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - { "10", "10" }, { "20", "20" }, //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - { "50", "50" } }; //$NON-NLS-1$//$NON-NLS-2$ - - private boolean autoBackup = true; - - private BooleanFieldEditor autoBackupField; - - private Composite autoSaveIntervalsParent; - - private Button startupActionButton; - - private Composite container; - - public void init(IWorkbench workbench) { - } - - protected IPreferenceStore doGetPreferenceStore() { - return CathyPlugin.getDefault().getPreferenceStore(); - } - - @Override - protected void createFieldEditors() { - - addStartupGroup(container); - new Label(container, SWT.NONE); - - addRecentFileCountSection(container); - addAutoSaveGroup(container); - - this.initialize(); - } - - private void addStartupGroup(Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setText(WorkbenchMessages.Startup_title); - - Composite container = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().applyTo(container); - GridData data = new GridData(); - data.horizontalIndent = 25; - data.minimumHeight = 0; - container.setLayoutData(data); - - startupActionButton = new Button(container, SWT.CHECK); - startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); - addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, - WorkbenchMessages.CheckUpdates_label, container)); - } - - private void addRecentFileCountSection(Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setText( - WorkbenchMessages.GeneralPrefPageSection_RecentFileCountSection_title); - - Composite composite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 15) - .applyTo(composite); - - Composite container = new Composite(composite, SWT.NONE); - GridData data = new GridData(); - data.horizontalIndent = 25; - container.setLayoutData(data); - GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container); - - addField(new ComboFieldEditor(IPreferenceConstants.RECENT_FILES, - WorkbenchMessages.RecentFiles_label, filesList, container)); - } - - private void addAutoSaveGroup(Composite parent) { - String message = WorkbenchMessages.AutoSave_label2; - int index = message.indexOf("{0}"); //$NON-NLS-1$ - String label1, label2; - label1 = message.substring(0, index); - label2 = message.substring(index + 3, index + 7); - if (null != saveIntervals) { - for (String[] interval : saveIntervals) { - interval[0] += " " + label2; //$NON-NLS-1$ - } - } - - Label label = new Label(parent, SWT.NONE); - label.setText( - WorkbenchMessages.GeneralPrefPageSection_AutoSaveGroup_title); - Composite container = new Composite(parent, SWT.NONE); - - GridLayoutFactory.fillDefaults().extendedMargins(23, 0, 0, 0) - .numColumns(1).applyTo(container); - - Composite saveParent = createContainer(container, 2); - Composite enableParent = createContainer(saveParent, 1); - addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, - enableParent)); - - autoSaveIntervalsParent = createContainer(saveParent, 1); - autoSaveInterval = new ComboFieldEditor(CathyPlugin.AUTO_SAVE_INTERVALS, - "", saveIntervals, autoSaveIntervalsParent); //$NON-NLS-1$ - addField(autoSaveInterval); - - autoSaveInterval.setEnabled( - getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), - autoSaveIntervalsParent); - - Composite boolParent = createContainer(container, 1); - autoBackupField = new BooleanFieldEditor( - PrefConstants.AUTO_BACKUP_ENABLE, - WorkbenchMessages.AutoBackup_label, boolParent); - autoBackupField.setPropertyChangeListener(this); - - } - - private Composite createContainer(Composite parent, int cols) { - Composite container = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(cols).applyTo(container); - - return container; - } - - @Override - protected Control createContents(Composite parent) { - if (null == container) - this.container = parent; - return super.createContents(parent); - } - - public void propertyChange(PropertyChangeEvent event) { - if (event.getSource() instanceof FieldEditor) { - FieldEditor fe = (FieldEditor) event.getSource(); - if (event.getProperty().equals(FieldEditor.VALUE)) { - String prefName = fe.getPreferenceName(); - if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { - autoSaveInterval.setEnabled( - ((Boolean) event.getNewValue()).booleanValue(), - autoSaveIntervalsParent); - } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { - autoBackup = ((Boolean) event.getNewValue()).booleanValue(); - } - } - } - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - - if (startupActionButton.getSelection()) { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_LAST); - } else { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_WIZARD); - } - - MindMapUIPlugin.getDefault().getPreferenceStore() - .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); - return true; - } - - @Override - protected void initialize() { - super.initialize(); - int startupAction = getPreferenceStore() - .getInt(CathyPlugin.STARTUP_ACTION); - startupActionButton - .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); - autoBackupField.setPreferenceStore( - MindMapUIPlugin.getDefault().getPreferenceStore()); - autoBackupField.load(); - } - - public void apply() { - this.performApply(); - } - - public boolean ok() { - return this.performOk(); - } - - public void excuteDefault() { - this.performDefaults(); - } - - public boolean cancel() { - return this.performCancel(); - } - -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.prefs.PrefConstants; + +public class GeneralPreferencePageSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private FieldEditor autoSaveInterval; + + private String[][] saveIntervals = new String[][] { { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ + { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ + { "30", "30" }, { "60", "60" } }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ + + private String[][] filesList = new String[][] { { "4", "4" }, { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + { "10", "10" }, { "20", "20" }, //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + { "50", "50" } }; //$NON-NLS-1$//$NON-NLS-2$ + + private boolean autoBackup = true; + + private BooleanFieldEditor autoBackupField; + + private Composite autoSaveIntervalsParent; + + private Button startupActionButton; + + private Composite container; + + public void init(IWorkbench workbench) { + } + + protected IPreferenceStore doGetPreferenceStore() { + return CathyPlugin.getDefault().getPreferenceStore(); + } + + @Override + protected void createFieldEditors() { + + addStartupGroup(container); + new Label(container, SWT.NONE); + + addRecentFileCountSection(container); + addAutoSaveGroup(container); + + this.initialize(); + } + + private void addStartupGroup(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText(WorkbenchMessages.Startup_title); + + Composite container = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(container); + GridData data = new GridData(); + data.horizontalIndent = 25; + data.minimumHeight = 0; + container.setLayoutData(data); + + startupActionButton = new Button(container, SWT.CHECK); + startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); + addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, + WorkbenchMessages.CheckUpdates_label, container)); + } + + private void addRecentFileCountSection(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText( + WorkbenchMessages.GeneralPrefPageSection_RecentFileCountSection_title); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 15) + .applyTo(composite); + + Composite container = new Composite(composite, SWT.NONE); + GridData data = new GridData(); + data.horizontalIndent = 25; + container.setLayoutData(data); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container); + + addField(new ComboFieldEditor(IPreferenceConstants.RECENT_FILES, + WorkbenchMessages.RecentFiles_label, filesList, container)); + } + + private void addAutoSaveGroup(Composite parent) { + String message = WorkbenchMessages.AutoSave_label2; + int index = message.indexOf("{0}"); //$NON-NLS-1$ + String label1, label2; + label1 = message.substring(0, index); + label2 = message.substring(index + 3, index + 7); + if (null != saveIntervals) { + for (String[] interval : saveIntervals) { + interval[0] += " " + label2; //$NON-NLS-1$ + } + } + + Label label = new Label(parent, SWT.NONE); + label.setText( + WorkbenchMessages.GeneralPrefPageSection_AutoSaveGroup_title); + Composite container = new Composite(parent, SWT.NONE); + + GridLayoutFactory.fillDefaults().extendedMargins(23, 0, 0, 0) + .numColumns(1).applyTo(container); + + Composite saveParent = createContainer(container, 2); + Composite enableParent = createContainer(saveParent, 1); + addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, + enableParent)); + + autoSaveIntervalsParent = createContainer(saveParent, 1); + autoSaveInterval = new ComboFieldEditor(CathyPlugin.AUTO_SAVE_INTERVALS, + "", saveIntervals, autoSaveIntervalsParent); //$NON-NLS-1$ + addField(autoSaveInterval); + + autoSaveInterval.setEnabled( + getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), + autoSaveIntervalsParent); + + Composite boolParent = createContainer(container, 1); + autoBackupField = new BooleanFieldEditor( + PrefConstants.AUTO_BACKUP_ENABLE, + WorkbenchMessages.AutoBackup_label, boolParent); + autoBackupField.setPropertyChangeListener(this); + + } + + private Composite createContainer(Composite parent, int cols) { + Composite container = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(cols).applyTo(container); + + return container; + } + + @Override + protected Control createContents(Composite parent) { + if (null == container) + this.container = parent; + return super.createContents(parent); + } + + public void propertyChange(PropertyChangeEvent event) { + if (event.getSource() instanceof FieldEditor) { + FieldEditor fe = (FieldEditor) event.getSource(); + if (event.getProperty().equals(FieldEditor.VALUE)) { + String prefName = fe.getPreferenceName(); + if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { + autoSaveInterval.setEnabled( + ((Boolean) event.getNewValue()).booleanValue(), + autoSaveIntervalsParent); + } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { + autoBackup = ((Boolean) event.getNewValue()).booleanValue(); + } + } + } + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + + if (startupActionButton.getSelection()) { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_LAST); + } else { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_WIZARD); + } + + MindMapUIPlugin.getDefault().getPreferenceStore() + .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); + return true; + } + + @Override + protected void initialize() { + super.initialize(); + int startupAction = getPreferenceStore() + .getInt(CathyPlugin.STARTUP_ACTION); + startupActionButton + .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); + autoBackupField.setPreferenceStore( + MindMapUIPlugin.getDefault().getPreferenceStore()); + autoBackupField.load(); + } + + public void apply() { + this.performApply(); + } + + public boolean ok() { + return this.performOk(); + } + + public void excuteDefault() { + this.performDefaults(); + } + + public boolean cancel() { + return this.performCancel(); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/HandledItemMatcher.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/HandledItemMatcher.java index 2c14c2ef7..f2fa91a17 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/HandledItemMatcher.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/HandledItemMatcher.java @@ -1,27 +1,27 @@ -package org.xmind.cathy.internal; - -import org.eclipse.e4.ui.model.application.MApplicationElement; -import org.eclipse.e4.ui.model.application.commands.MCommand; -import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; -import org.eclipse.e4.ui.workbench.Selector; - -public class HandledItemMatcher implements Selector { - - private String commandId; - - public HandledItemMatcher(String commandId) { - this.commandId = commandId; - } - - public boolean select(MApplicationElement element) { - if (!(element instanceof MHandledItem)) - return false; - - MHandledItem handledItem = (MHandledItem) element; - MCommand command = handledItem.getCommand(); - if (command == null) - return false; - - return this.commandId.equals(command.getElementId()); - } +package org.xmind.cathy.internal; + +import org.eclipse.e4.ui.model.application.MApplicationElement; +import org.eclipse.e4.ui.model.application.commands.MCommand; +import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; +import org.eclipse.e4.ui.workbench.Selector; + +public class HandledItemMatcher implements Selector { + + private String commandId; + + public HandledItemMatcher(String commandId) { + this.commandId = commandId; + } + + public boolean select(MApplicationElement element) { + if (!(element instanceof MHandledItem)) + return false; + + MHandledItem handledItem = (MHandledItem) element; + MCommand command = handledItem.getCommand(); + if (command == null) + return false; + + return this.commandId.equals(command.getElementId()); + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/IApplicationValidator.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/IApplicationValidator.java index bb86d66c5..51d890341 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/IApplicationValidator.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/IApplicationValidator.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -public interface IApplicationValidator { - - boolean shouldApplicationExitEarly(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +public interface IApplicationValidator { + + boolean shouldApplicationExitEarly(); + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ICathyConstants.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ICathyConstants.java index fc1cc5a5e..d4f7af414 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ICathyConstants.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ICathyConstants.java @@ -1,128 +1,128 @@ -package org.xmind.cathy.internal; - -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; - -public interface ICathyConstants { - - /* - * Element Tag Names - */ - public static final String TAG_SHOW_IMAGE = "CathyShowImage"; //$NON-NLS-1$ - public static final String TAG_SHOW_DASHBOARD = "CathyShowDashboard"; //$NON-NLS-1$ - public static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ - public static final String TAG_FORCE_TEXT = "FORCE_TEXT"; //$NON-NLS-1$ - - public static final String TAG_TRIMBAR_LAYOUT_BEGINING = "TrimBarLayout:begining"; //$NON-NLS-1$ - public static final String TAG_TRIMBAR_LAYOUT_CENTER = "TrimBarLayout:center"; //$NON-NLS-1$ - public static final String TAG_TRIMBAR_LAYOUT_END = "TrimBarLayout:end"; //$NON-NLS-1$ - - /* - * Element Ids - */ - public static final String ID_APPLICATION = "org.xmind.cathy.application"; //$NON-NLS-1$ - public static final String ID_MAIN_WINDOW = "org.xmind.cathy.window.main"; //$NON-NLS-1$ - public static final String ID_PERSPECTIVE_STACK = "org.eclipse.ui.ide.perspectivestack"; //$NON-NLS-1$ - public static final String ID_EDITOR_AREA = "org.eclipse.ui.editorss"; //$NON-NLS-1$ - public static final String ID_PRIMARY_EDITOR_STACK = "org.eclipse.e4.primaryDataStack"; //$NON-NLS-1$ - public static final String ID_MAIN_TOOLBAR = "org.eclipse.ui.main.toolbar"; //$NON-NLS-1$ - public static final String ID_STATUS_BAR = "org.eclipse.ui.trim.status"; //$NON-NLS-1$ - public static final String ID_TRIMBAR_RIGHT = "org.xmind.ui.trimbar.right"; //$NON-NLS-1$ - public static final String ID_PARTSTACK_RIGHT = "org.xmind.ui.stack.right"; //$NON-NLS-1$ - public static final String ID_DASHBOARD_PART = "org.xmind.cathy.part.dashboard"; //$NON-NLS-1$ - public static final String ID_TOOL_ITEM_TOGGLE_DASHBOARD = "org.xmind.ui.toolbar.dashboard.toggle"; //$NON-NLS-1$ - - public static final String ID_MENU_ITEM_UNDO = "undo"; //$NON-NLS-1$ - public static final String ID_MENU_ITEM_REDO = "redo"; //$NON-NLS-1$ - public static final String ID_MENU_ITEM_SAVE = "save"; //$NON-NLS-1$ - public static final String ID_TOOL_ITEM_UNDO = "org.xmind.ui.toolbar.edit.undo"; //$NON-NLS-1$ - public static final String ID_TOOL_ITEM_REDO = "org.xmind.ui.toolbar.edit.redo"; //$NON-NLS-1$ - public static final String ID_TOOL_ITEM_SAVE = "org.xmind.ui.toolbar.edit.save"; //$NON-NLS-1$ - - public static final String MB_XADDITIONS = "xadditions"; //$NON-NLS-1$ - - /* - * CSS Property Names - */ - public static final String PROPERTY_UNSELECTED_TABS_BG_VISIBLE = "xmind-swt-unselected-tabs-bg-visible"; //$NON-NLS-1$ - public static final String PROPERTY_MAXIMIZE_IMAGE = "xmind-swt-maximize-image"; //$NON-NLS-1$ - public static final String PROPERTY_MINIMIZE_IMAGE = "xmind-swt-minimize-image"; //$NON-NLS-1$ - public static final String PROPERTY_CHEVRON_VISIBLE = "xmind-swt-chevron-visible"; //$NON-NLS-1$ - public static final String PROPERTY_CLOSE_IMAGE = "xmind-swt-close-image"; //$NON-NLS-1$ - public static final String PROPERTY_CLOSE_HOVER_IMAGE = "xmind-swt-close-hover-image"; //$NON-NLS-1$ - public static final String PROPERTY_XTEXT_BACKGROUND = "xmind-text-background"; //$NON-NLS-1$ - public static final String PROPERTY_XBOTTOM_KEYLINE_1_COLOR = "xmind-bottom-keyline-1-color"; //$NON-NLS-1$ - public static final String PROPERTY_XBOTTOM_KEYLINE_2_COLOR = "xmind-bottom-keyline-2-color"; //$NON-NLS-1$ - public static final String PROPERTY_HYPERLINK_COLOR = "xmind-hyperlink-color"; //$NON-NLS-1$ - public static final String PROPERTY_ACTIVE_HYPERLINK_COLOR = "xmind-active-hyperlink-color"; //$NON-NLS-1$ - public static final String PROPERTY_MARGIN = "xmind-margin"; //$NON-NLS-1$ - public static final String PROPERTY_MARGIN_TOP = "xmind-margin-top"; //$NON-NLS-1$ - public static final String PROPERTY_MARGIN_BOTTOM = "xmind-margin-bottom"; //$NON-NLS-1$ - public static final String PROPERTY_MARGIN_LEFT = "xmind-margin-left"; //$NON-NLS-1$ - public static final String PROPERTY_MARGIN_RIGHT = "xmind-margin-right"; //$NON-NLS-1$ - public static final String PROPERTY_MINIMIZE_VISIBLE = "xmind-swt-minimize-visible"; //$NON-NLS-1$ - public static final String PROPERTY_MAXIMIZE_VISIBLE = "xmind-swt-maximize-visible"; //$NON-NLS-1$ - public static final String PROPERTY_CTABFOLDER_RENDER_NONE = "xmind-ctabfolder-render-none"; //$NON-NLS-1$ - public static final String PROPERTY_BG_COLOR = "xmind-background-color"; //$NON-NLS-1$ - public static final String PROPERTY_FG_COLOR = "xmind-foreground-color"; //$NON-NLS-1$ - public static final String PROPERTY_TITLE_BAR_TEXT_COLOR = "xmind-title-bar-text-color"; //$NON-NLS-1$ - public static final String PROPERTY_TITLE_BAR_ACTIVE_TEXT_COLOR = "xmind-title-bar-active-text-color"; //$NON-NLS-1$ - public static final String PROPERTY_OUTER_BORDER_VISIBLE = "xmind-swt-outer-border-visible"; //$NON-NLS-1$ - public static final String PROPERTY_INNER_BORDER_VISIBLE = "xmind-swt-inner-border-visible"; //$NON-NLS-1$ - public static final String PROPERTY_IMAGE_VISIBLE = "xmind-swt-image-visible"; //$NON-NLS-1$ - public static final String PROPERTY_TEXT_VISIBLE = "xmind-swt-text-visible"; //$NON-NLS-1$ - public static final String PROPERTY_TOOL_ITEM_COLOR = "xmind-swt-tool-item-color"; //$NON-NLS-1$ - public static final String PROPERTY_VIEW_MENU = "xmind-swt-view-menu-image"; //$NON-NLS-1$ - public static final String PROPERTY_UNSELECTED_TABS_COLOR = "xmind-swt-unselected-tabs-color"; //$NON-NLS-1$ - public static final String PROPERTY_SHOW_CLOSE = "xmind-swt-show-close"; //$NON-NLS-1$ - public static final String PROPERTY_TABFOLDER_BACKGROUND = "xmind-tab-folder-bg"; //$NON-NLS-1$ - public static final String PROPERTY_TABBAR_BACKGROUND = "xmind-tab-bar-bg"; //$NON-NLS-1$ - - /* - * Commmand Ids - */ - public static final String COMMAND_TOGGLE_DASHBOARD = "org.xmind.ui.command.toggleDashboard"; //$NON-NLS-1$ - public static final String COMMAND_SHOW_DASHBOARD = "org.xmind.ui.command.showDashboard"; //$NON-NLS-1$ - public static final String COMMAND_RECENTFILE_PIN = "org.xmind.ui.command.pinRecentFile"; //$NON-NLS-1$ - public static final String COMMAND_RECENTFILE_UNPIN = "org.xmind.ui.command.unpinRecentFile"; //$NON-NLS-1$ - public static final String COMMAND_RECENTFILE_CLEAR = "org.xmind.ui.command.clearRecentFile"; //$NON-NLS-1$ - - public static final String COMMAND_TEMPLATE_DUPLICATE = "org.xmind.ui.command.template.duplicate"; //$NON-NLS-1$ - public static final String COMMAND_TEMPLATE_RENAME = "org.xmind.ui.command.template.rename"; //$NON-NLS-1$ - public static final String COMMAND_TEMPLATE_DELETE = "org.xmind.ui.command.template.delete"; //$NON-NLS-1$ - - /* - * Command Parameter Ids - */ - public static final String PARAMETER_DASHBOARD_PAGE_ID = "org.xmind.ui.command.showDashboard.pageId"; //$NON-NLS-1$ - - /* - * Data Keys - */ - public static final String DATA_PART_OF_WIDGET = AbstractPartRenderer.OWNING_ME; - public static final String DATA_DASHBOARD_SELECTED_PAGE_ID = "org.xmind.ui.part.dashboard.selectedPageId"; //$NON-NLS-1$ - - /* - * Dashboard Pages - */ - public static final String DASHBOARD_PAGE_NEW = "org.xmind.ui.part.dashboard.new"; //$NON-NLS-1$ - public static final String DASHBOARD_PAGE_RECENT = "org.xmind.ui.part.dashboard.recent"; //$NON-NLS-1$ - - /* - * Popup Menu Ids - */ - public static final String POPUP_RECENTFILE = "org.xmind.ui.popup.recentFile"; //$NON-NLS-1$ - - /* - * Popup Menu Ids - */ - public static final String POPUP_TEMPLATE = "org.xmind.ui.popup.template"; //$NON-NLS-1$ - - /* - * Helper Ids - */ - public static final String HELPER_RECENTFILE_PIN = "org.xmind.ui.helper.recentFile.pin"; //$NON-NLS-1$ - public static final String HELPER_RECENTFILE_DELETE = "org.xmind.ui.helper.recentFile.delete"; //$NON-NLS-1$ - public static final String HELPER_RECENTFILE_CLEAR = "org.xmind.ui.helper.recentFile.clear"; //$NON-NLS-1$ - - public static final String HELPER_TEMPLATE_RENAME = "org.xmind.ui.helper.template.rename"; //$NON-NLS-1$ -} +package org.xmind.cathy.internal; + +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; + +public interface ICathyConstants { + + /* + * Element Tag Names + */ + public static final String TAG_SHOW_IMAGE = "CathyShowImage"; //$NON-NLS-1$ + public static final String TAG_SHOW_DASHBOARD = "CathyShowDashboard"; //$NON-NLS-1$ + public static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ + public static final String TAG_FORCE_TEXT = "FORCE_TEXT"; //$NON-NLS-1$ + + public static final String TAG_TRIMBAR_LAYOUT_BEGINING = "TrimBarLayout:begining"; //$NON-NLS-1$ + public static final String TAG_TRIMBAR_LAYOUT_CENTER = "TrimBarLayout:center"; //$NON-NLS-1$ + public static final String TAG_TRIMBAR_LAYOUT_END = "TrimBarLayout:end"; //$NON-NLS-1$ + + /* + * Element Ids + */ + public static final String ID_APPLICATION = "org.xmind.cathy.application"; //$NON-NLS-1$ + public static final String ID_MAIN_WINDOW = "org.xmind.cathy.window.main"; //$NON-NLS-1$ + public static final String ID_PERSPECTIVE_STACK = "org.eclipse.ui.ide.perspectivestack"; //$NON-NLS-1$ + public static final String ID_EDITOR_AREA = "org.eclipse.ui.editorss"; //$NON-NLS-1$ + public static final String ID_PRIMARY_EDITOR_STACK = "org.eclipse.e4.primaryDataStack"; //$NON-NLS-1$ + public static final String ID_MAIN_TOOLBAR = "org.eclipse.ui.main.toolbar"; //$NON-NLS-1$ + public static final String ID_STATUS_BAR = "org.eclipse.ui.trim.status"; //$NON-NLS-1$ + public static final String ID_TRIMBAR_RIGHT = "org.xmind.ui.trimbar.right"; //$NON-NLS-1$ + public static final String ID_PARTSTACK_RIGHT = "org.xmind.ui.stack.right"; //$NON-NLS-1$ + public static final String ID_DASHBOARD_PART = "org.xmind.cathy.part.dashboard"; //$NON-NLS-1$ + public static final String ID_TOOL_ITEM_TOGGLE_DASHBOARD = "org.xmind.ui.toolbar.dashboard.toggle"; //$NON-NLS-1$ + + public static final String ID_MENU_ITEM_UNDO = "undo"; //$NON-NLS-1$ + public static final String ID_MENU_ITEM_REDO = "redo"; //$NON-NLS-1$ + public static final String ID_MENU_ITEM_SAVE = "save"; //$NON-NLS-1$ + public static final String ID_TOOL_ITEM_UNDO = "org.xmind.ui.toolbar.edit.undo"; //$NON-NLS-1$ + public static final String ID_TOOL_ITEM_REDO = "org.xmind.ui.toolbar.edit.redo"; //$NON-NLS-1$ + public static final String ID_TOOL_ITEM_SAVE = "org.xmind.ui.toolbar.edit.save"; //$NON-NLS-1$ + + public static final String MB_XADDITIONS = "xadditions"; //$NON-NLS-1$ + + /* + * CSS Property Names + */ + public static final String PROPERTY_UNSELECTED_TABS_BG_VISIBLE = "xmind-swt-unselected-tabs-bg-visible"; //$NON-NLS-1$ + public static final String PROPERTY_MAXIMIZE_IMAGE = "xmind-swt-maximize-image"; //$NON-NLS-1$ + public static final String PROPERTY_MINIMIZE_IMAGE = "xmind-swt-minimize-image"; //$NON-NLS-1$ + public static final String PROPERTY_CHEVRON_VISIBLE = "xmind-swt-chevron-visible"; //$NON-NLS-1$ + public static final String PROPERTY_CLOSE_IMAGE = "xmind-swt-close-image"; //$NON-NLS-1$ + public static final String PROPERTY_CLOSE_HOVER_IMAGE = "xmind-swt-close-hover-image"; //$NON-NLS-1$ + public static final String PROPERTY_XTEXT_BACKGROUND = "xmind-text-background"; //$NON-NLS-1$ + public static final String PROPERTY_XBOTTOM_KEYLINE_1_COLOR = "xmind-bottom-keyline-1-color"; //$NON-NLS-1$ + public static final String PROPERTY_XBOTTOM_KEYLINE_2_COLOR = "xmind-bottom-keyline-2-color"; //$NON-NLS-1$ + public static final String PROPERTY_HYPERLINK_COLOR = "xmind-hyperlink-color"; //$NON-NLS-1$ + public static final String PROPERTY_ACTIVE_HYPERLINK_COLOR = "xmind-active-hyperlink-color"; //$NON-NLS-1$ + public static final String PROPERTY_MARGIN = "xmind-margin"; //$NON-NLS-1$ + public static final String PROPERTY_MARGIN_TOP = "xmind-margin-top"; //$NON-NLS-1$ + public static final String PROPERTY_MARGIN_BOTTOM = "xmind-margin-bottom"; //$NON-NLS-1$ + public static final String PROPERTY_MARGIN_LEFT = "xmind-margin-left"; //$NON-NLS-1$ + public static final String PROPERTY_MARGIN_RIGHT = "xmind-margin-right"; //$NON-NLS-1$ + public static final String PROPERTY_MINIMIZE_VISIBLE = "xmind-swt-minimize-visible"; //$NON-NLS-1$ + public static final String PROPERTY_MAXIMIZE_VISIBLE = "xmind-swt-maximize-visible"; //$NON-NLS-1$ + public static final String PROPERTY_CTABFOLDER_RENDER_NONE = "xmind-ctabfolder-render-none"; //$NON-NLS-1$ + public static final String PROPERTY_BG_COLOR = "xmind-background-color"; //$NON-NLS-1$ + public static final String PROPERTY_FG_COLOR = "xmind-foreground-color"; //$NON-NLS-1$ + public static final String PROPERTY_TITLE_BAR_TEXT_COLOR = "xmind-title-bar-text-color"; //$NON-NLS-1$ + public static final String PROPERTY_TITLE_BAR_ACTIVE_TEXT_COLOR = "xmind-title-bar-active-text-color"; //$NON-NLS-1$ + public static final String PROPERTY_OUTER_BORDER_VISIBLE = "xmind-swt-outer-border-visible"; //$NON-NLS-1$ + public static final String PROPERTY_INNER_BORDER_VISIBLE = "xmind-swt-inner-border-visible"; //$NON-NLS-1$ + public static final String PROPERTY_IMAGE_VISIBLE = "xmind-swt-image-visible"; //$NON-NLS-1$ + public static final String PROPERTY_TEXT_VISIBLE = "xmind-swt-text-visible"; //$NON-NLS-1$ + public static final String PROPERTY_TOOL_ITEM_COLOR = "xmind-swt-tool-item-color"; //$NON-NLS-1$ + public static final String PROPERTY_VIEW_MENU = "xmind-swt-view-menu-image"; //$NON-NLS-1$ + public static final String PROPERTY_UNSELECTED_TABS_COLOR = "xmind-swt-unselected-tabs-color"; //$NON-NLS-1$ + public static final String PROPERTY_SHOW_CLOSE = "xmind-swt-show-close"; //$NON-NLS-1$ + public static final String PROPERTY_TABFOLDER_BACKGROUND = "xmind-tab-folder-bg"; //$NON-NLS-1$ + public static final String PROPERTY_TABBAR_BACKGROUND = "xmind-tab-bar-bg"; //$NON-NLS-1$ + + /* + * Commmand Ids + */ + public static final String COMMAND_TOGGLE_DASHBOARD = "org.xmind.ui.command.toggleDashboard"; //$NON-NLS-1$ + public static final String COMMAND_SHOW_DASHBOARD = "org.xmind.ui.command.showDashboard"; //$NON-NLS-1$ + public static final String COMMAND_RECENTFILE_PIN = "org.xmind.ui.command.pinRecentFile"; //$NON-NLS-1$ + public static final String COMMAND_RECENTFILE_UNPIN = "org.xmind.ui.command.unpinRecentFile"; //$NON-NLS-1$ + public static final String COMMAND_RECENTFILE_CLEAR = "org.xmind.ui.command.clearRecentFile"; //$NON-NLS-1$ + + public static final String COMMAND_TEMPLATE_DUPLICATE = "org.xmind.ui.command.template.duplicate"; //$NON-NLS-1$ + public static final String COMMAND_TEMPLATE_RENAME = "org.xmind.ui.command.template.rename"; //$NON-NLS-1$ + public static final String COMMAND_TEMPLATE_DELETE = "org.xmind.ui.command.template.delete"; //$NON-NLS-1$ + + /* + * Command Parameter Ids + */ + public static final String PARAMETER_DASHBOARD_PAGE_ID = "org.xmind.ui.command.showDashboard.pageId"; //$NON-NLS-1$ + + /* + * Data Keys + */ + public static final String DATA_PART_OF_WIDGET = AbstractPartRenderer.OWNING_ME; + public static final String DATA_DASHBOARD_SELECTED_PAGE_ID = "org.xmind.ui.part.dashboard.selectedPageId"; //$NON-NLS-1$ + + /* + * Dashboard Pages + */ + public static final String DASHBOARD_PAGE_NEW = "org.xmind.ui.part.dashboard.new"; //$NON-NLS-1$ + public static final String DASHBOARD_PAGE_RECENT = "org.xmind.ui.part.dashboard.recent"; //$NON-NLS-1$ + + /* + * Popup Menu Ids + */ + public static final String POPUP_RECENTFILE = "org.xmind.ui.popup.recentFile"; //$NON-NLS-1$ + + /* + * Popup Menu Ids + */ + public static final String POPUP_TEMPLATE = "org.xmind.ui.popup.template"; //$NON-NLS-1$ + + /* + * Helper Ids + */ + public static final String HELPER_RECENTFILE_PIN = "org.xmind.ui.helper.recentFile.pin"; //$NON-NLS-1$ + public static final String HELPER_RECENTFILE_DELETE = "org.xmind.ui.helper.recentFile.delete"; //$NON-NLS-1$ + public static final String HELPER_RECENTFILE_CLEAR = "org.xmind.ui.helper.recentFile.clear"; //$NON-NLS-1$ + + public static final String HELPER_TEMPLATE_RENAME = "org.xmind.ui.helper.template.rename"; //$NON-NLS-1$ +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ILogger.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ILogger.java index 9523af42c..58d6db2e5 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ILogger.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ILogger.java @@ -1,62 +1,62 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.cathy.internal; - -/** - * @author Frank Shaka - * - */ -public interface ILogger { - - ILogger DEFAULT = new ILogger() { - - public void logError(String message, Throwable error) { - if (message != null) { - System.err.println(message); - } - if (error != null) { - error.printStackTrace(System.err); - } - } - - public void logWarning(String message, Throwable error) { - if (message != null) { - System.out.println(message); - } - if (error != null) { - error.printStackTrace(System.out); - } - } - - public void logInfo(String message, Throwable error) { - if (message != null) { - System.out.println(message); - } - if (error != null) { - error.printStackTrace(System.out); - } - } - - }; - - void logError(String message, Throwable error); - - void logWarning(String message, Throwable error); - - void logInfo(String message, Throwable error); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.cathy.internal; + +/** + * @author Frank Shaka + * + */ +public interface ILogger { + + ILogger DEFAULT = new ILogger() { + + public void logError(String message, Throwable error) { + if (message != null) { + System.err.println(message); + } + if (error != null) { + error.printStackTrace(System.err); + } + } + + public void logWarning(String message, Throwable error) { + if (message != null) { + System.out.println(message); + } + if (error != null) { + error.printStackTrace(System.out); + } + } + + public void logInfo(String message, Throwable error) { + if (message != null) { + System.out.println(message); + } + if (error != null) { + error.printStackTrace(System.out); + } + } + + }; + + void logError(String message, Throwable error); + + void logWarning(String message, Throwable error); + + void logInfo(String message, Throwable error); + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePrefPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePrefPage.java index 93fac3415..e1ce0e2bd 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePrefPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePrefPage.java @@ -1,374 +1,374 @@ -package org.xmind.cathy.internal; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Properties; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.preference.FieldEditorPreferencePage; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.ListViewer; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.PlatformUI; - -public class LanguagePrefPage extends FieldEditorPreferencePage implements - IWorkbenchPreferencePage { - - private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ - private static final String LOADED_LANGUAGES_URL = "platform:/plugin/org.xmind.cathy/resource/langs.properties"; //$NON-NLS-1$ - @SuppressWarnings("nls") - private static final String[] supportedLangsKey = { "en_US", "de", "fr", - "zh_CN", "zh_TW", "ja", "ko", "da", "ru", "it", "sl", "ar", "es", - "pt_BR" }; - - private class LanguageLabelProvider extends LabelProvider { - @Override - public String getText(Object element) { - if (element instanceof String) { - StringBuffer buffer = new StringBuffer(3); - - String langKey = (String) element; - String supportLang = supportLanguageProperties - .getProperty(langKey); - buffer.append(supportLang); - buffer.append(" - "); //$NON-NLS-1$ - buffer.append(supportLangsMap.get(langKey)); - return buffer.toString(); - } - return super.getText(element); - } - } - - private static String oldLangKey = null; - - private Properties configIniProperties; - - private Properties supportLanguageProperties; - - private HashMap supportLangsMap; - - private ListViewer langsViewer; - - private Label changingToLangText; - - private Button changeButton; - - public LanguagePrefPage() { - super(WorkbenchMessages.LanguagePrefPage_title, FLAT); - configIniProperties = loadProperties(getConfigFile()); - supportLanguageProperties = loadProperties(getSupportLanguageFile()); - initSupportLanguageMap(); - if (oldLangKey == null) { - String languageKey = configIniProperties - .getProperty(LANGUAGE_OSGI_NL_KEY); - oldLangKey = languageKey != null ? languageKey : System - .getProperty(LANGUAGE_OSGI_NL_KEY); - } - } - - private void initSupportLanguageMap() { - if (supportLangsMap != null) - return; - supportLangsMap = new HashMap(); - supportLangsMap.put( - "en_US", WorkbenchMessages.SupportLanguageName_English); //$NON-NLS-1$ - supportLangsMap.put("ar", WorkbenchMessages.SupportLanguageName_Arabic); //$NON-NLS-1$ - supportLangsMap.put("da", WorkbenchMessages.SupportLanguageName_Danish); //$NON-NLS-1$ - supportLangsMap.put("de", WorkbenchMessages.SupportLanguageName_German); //$NON-NLS-1$ - supportLangsMap.put( - "es", WorkbenchMessages.SupportLanguageName_Spanish); //$NON-NLS-1$ - supportLangsMap.put("fr", WorkbenchMessages.SupportLanguageName_French); //$NON-NLS-1$ - supportLangsMap - .put("it", WorkbenchMessages.SupportLanguageName_Italian); //$NON-NLS-1$ - supportLangsMap.put( - "ja", WorkbenchMessages.SupportLanguageName_Japanese); //$NON-NLS-1$ - supportLangsMap.put("ko", WorkbenchMessages.SupportLanguageName_Korean); //$NON-NLS-1$ - supportLangsMap - .put("pt_BR", WorkbenchMessages.SupportLanguageName_Portuguese_Brazilian); //$NON-NLS-1$ - supportLangsMap - .put("ru", WorkbenchMessages.SupportLanguageName_Russian); //$NON-NLS-1$ - supportLangsMap.put( - "sl", WorkbenchMessages.SupportLanguageName_Slovenian); //$NON-NLS-1$ - supportLangsMap.put( - "zh_CN", WorkbenchMessages.SupportLanguageName_SimplifiedCN); //$NON-NLS-1$ - supportLangsMap.put( - "zh_TW", WorkbenchMessages.SupportLanguageName_TraditionalCN); //$NON-NLS-1$ - } - - private Properties loadProperties(File file) { - if (file != null && file.exists() && file.canRead()) { - try { - InputStream stream = new BufferedInputStream( - new FileInputStream(file), 1024); - try { - Properties properties = new Properties(); - properties.load(stream); - return properties; - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - } - } - return null; - } - - private void storeProperties(Properties properties, File file) { - if (file != null && file.exists() && file.canWrite()) { - try { - OutputStream stream = new BufferedOutputStream( - new FileOutputStream(file), 1024); - try { - properties.store(stream, "Store properties into file."); //$NON-NLS-1$ - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - } - } - } - - private File getConfigFile() { - URL configDir = Platform.getConfigurationLocation().getURL(); - try { - URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ - File file = new File(configIni.getFile()); - return file; - } catch (MalformedURLException e) { - e.printStackTrace(); - } - return null; - } - - private File getSupportLanguageFile() { - try { - URL url = FileLocator.find(new URL(LOADED_LANGUAGES_URL)); - File supportLanguageFile = new File(FileLocator.toFileURL(url) - .getPath()); - return supportLanguageFile; - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - public void init(IWorkbench workbench) { - } - - @Override - protected void createFieldEditors() { - addLanguageGroup(); - } - - private void addLanguageGroup() { - Composite parent = getFieldEditorParent(); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - parent.setLayout(gridLayout); - addChangeLanguageField(parent); - } - - private void addChangeLanguageField(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - composite.setLayout(new GridLayout()); - - createLangsDescription(composite); - createChangeLanguageControl(parent); - } - - private void createChangeLanguageControl(Composite parent) { - Composite line = new Composite(parent, SWT.NONE); - line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - line.setLayout(new GridLayout(2, false)); - - int flags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE; - langsViewer = new ListViewer(line, flags); - GridData layoutData = new GridData(SWT.FILL, SWT.BEGINNING, true, false); - langsViewer.getControl().setLayoutData(layoutData); - langsViewer.setContentProvider(new ArrayContentProvider()); - langsViewer.setLabelProvider(new LanguageLabelProvider()); - langsViewer.setInput(supportedLangsKey); - - String languageKey = configIniProperties - .getProperty(LANGUAGE_OSGI_NL_KEY); - String currentLanguageKey = languageKey != null ? languageKey - : oldLangKey; - - langsViewer.setSelection(new StructuredSelection(currentLanguageKey)); - langsViewer - .addSelectionChangedListener(new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - ISelection langElementSelection = event.getSelection(); - if (langElementSelection instanceof StructuredSelection) { - Object langKey = ((StructuredSelection) langElementSelection) - .getFirstElement(); - - boolean isChanged = !oldLangKey.equals(langKey); - if (isChanged) { - String langSelected = ((LanguageLabelProvider) langsViewer - .getLabelProvider()).getText(langKey); - changingToLangText.setText(langSelected); - } else { - changingToLangText.setText(""); //$NON-NLS-1$ - } - changeButton.setEnabled(isChanged); - } - } - }); - - changeButton = new Button(line, SWT.NONE); - changeButton.setText(WorkbenchMessages.ChangeLanguage_button); - changeButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, - false)); - changeButton.setEnabled(!currentLanguageKey.equals(oldLangKey)); - changeButton.addSelectionListener(new SelectionListener() { - public void widgetSelected(SelectionEvent e) { - ISelection langElementSelection = langsViewer.getSelection(); - if (langElementSelection instanceof StructuredSelection) { - Object langKey = ((StructuredSelection) langElementSelection) - .getFirstElement(); - String langSelected = ((LanguageLabelProvider) langsViewer - .getLabelProvider()).getText(langKey); - String message = NLS.bind( - WorkbenchMessages.ConfirmToRestart_description, - langSelected); - MessageDialog confirmDialog = new MessageDialog( - getShell(), - WorkbenchMessages.ConfirmToRestart_title, - null, - message, - MessageDialog.CONFIRM, - new String[] { - WorkbenchMessages.ConfirmToRestart_defaultButton, - WorkbenchMessages.ConfirmToRestart_cancelButton }, - IDialogConstants.OK_ID); - int restart = confirmDialog.open(); - configIniProperties.put(LANGUAGE_OSGI_NL_KEY, langKey); - storeProperties(configIniProperties, getConfigFile()); - if (restart == 0) { - PlatformUI.getWorkbench().restart(); - } - } - } - - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }); - } - - private void createLangsDescription(Composite composite) { - Composite descriptionComposite = new Composite(composite, SWT.NONE); - descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, - true, false)); - GridLayout descriptionLayout = new GridLayout(2, false); - descriptionLayout.marginHeight = 0; - descriptionLayout.marginWidth = 0; - descriptionComposite.setLayout(descriptionLayout); - - Label langToChangeDescription = new Label(descriptionComposite, - SWT.NONE); - langToChangeDescription - .setText(WorkbenchMessages.ChangeLanguageTo_description); - langToChangeDescription.setLayoutData(new GridData(SWT.FILL)); - - changingToLangText = new Label(descriptionComposite, SWT.READ_ONLY - | SWT.SINGLE | SWT.BORDER | SWT.SHADOW_IN | SWT.LEFT); - changingToLangText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, - true, true)); - - String languageKey = configIniProperties - .getProperty(LANGUAGE_OSGI_NL_KEY); - String supportLang = supportLangsMap.get(languageKey); - if (supportLang != null) - changingToLangText.setText(supportLang); - } - - @Override - protected void performDefaults() { - configIniProperties.put(LANGUAGE_OSGI_NL_KEY, - System.getProperty(LANGUAGE_OSGI_NL_KEY)); - langsViewer.setSelection( - new StructuredSelection(System - .getProperty(LANGUAGE_OSGI_NL_KEY)), true); - storeProperties(configIniProperties, getConfigFile()); - super.performDefaults(); - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - - ISelection langElementSelection = langsViewer.getSelection(); - if (langElementSelection instanceof StructuredSelection) { - Object langKey = ((StructuredSelection) langElementSelection) - .getFirstElement(); - if (!oldLangKey.equals(langKey)) { - String message = WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_description; - MessageDialog confirmDialog = new MessageDialog( - getShell(), - WorkbenchMessages.ConfirmToRestart_title, - null, - message, - MessageDialog.CONFIRM, - new String[] { - WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_defaultButton, - WorkbenchMessages.LanguagePrefPage_ConfirmToRestart_laterButton }, - IDialogConstants.OK_ID); - int restart = confirmDialog.open(); - if (restart == -1) - return false; - - configIniProperties.put(LANGUAGE_OSGI_NL_KEY, langKey); - storeProperties(configIniProperties, getConfigFile()); - if (restart == IDialogConstants.OK_ID) { - PlatformUI.getWorkbench().restart(); - } - } - } - - return true; - } - -} +package org.xmind.cathy.internal; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Properties; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; + +public class LanguagePrefPage extends FieldEditorPreferencePage implements + IWorkbenchPreferencePage { + + private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ + private static final String LOADED_LANGUAGES_URL = "platform:/plugin/org.xmind.cathy/resource/langs.properties"; //$NON-NLS-1$ + @SuppressWarnings("nls") + private static final String[] supportedLangsKey = { "en_US", "de", "fr", + "zh_CN", "zh_TW", "ja", "ko", "da", "ru", "it", "sl", "ar", "es", + "pt_BR" }; + + private class LanguageLabelProvider extends LabelProvider { + @Override + public String getText(Object element) { + if (element instanceof String) { + StringBuffer buffer = new StringBuffer(3); + + String langKey = (String) element; + String supportLang = supportLanguageProperties + .getProperty(langKey); + buffer.append(supportLang); + buffer.append(" - "); //$NON-NLS-1$ + buffer.append(supportLangsMap.get(langKey)); + return buffer.toString(); + } + return super.getText(element); + } + } + + private static String oldLangKey = null; + + private Properties configIniProperties; + + private Properties supportLanguageProperties; + + private HashMap supportLangsMap; + + private ListViewer langsViewer; + + private Label changingToLangText; + + private Button changeButton; + + public LanguagePrefPage() { + super(WorkbenchMessages.LanguagePrefPage_title, FLAT); + configIniProperties = loadProperties(getConfigFile()); + supportLanguageProperties = loadProperties(getSupportLanguageFile()); + initSupportLanguageMap(); + if (oldLangKey == null) { + String languageKey = configIniProperties + .getProperty(LANGUAGE_OSGI_NL_KEY); + oldLangKey = languageKey != null ? languageKey : System + .getProperty(LANGUAGE_OSGI_NL_KEY); + } + } + + private void initSupportLanguageMap() { + if (supportLangsMap != null) + return; + supportLangsMap = new HashMap(); + supportLangsMap.put( + "en_US", WorkbenchMessages.SupportLanguageName_English); //$NON-NLS-1$ + supportLangsMap.put("ar", WorkbenchMessages.SupportLanguageName_Arabic); //$NON-NLS-1$ + supportLangsMap.put("da", WorkbenchMessages.SupportLanguageName_Danish); //$NON-NLS-1$ + supportLangsMap.put("de", WorkbenchMessages.SupportLanguageName_German); //$NON-NLS-1$ + supportLangsMap.put( + "es", WorkbenchMessages.SupportLanguageName_Spanish); //$NON-NLS-1$ + supportLangsMap.put("fr", WorkbenchMessages.SupportLanguageName_French); //$NON-NLS-1$ + supportLangsMap + .put("it", WorkbenchMessages.SupportLanguageName_Italian); //$NON-NLS-1$ + supportLangsMap.put( + "ja", WorkbenchMessages.SupportLanguageName_Japanese); //$NON-NLS-1$ + supportLangsMap.put("ko", WorkbenchMessages.SupportLanguageName_Korean); //$NON-NLS-1$ + supportLangsMap + .put("pt_BR", WorkbenchMessages.SupportLanguageName_Portuguese_Brazilian); //$NON-NLS-1$ + supportLangsMap + .put("ru", WorkbenchMessages.SupportLanguageName_Russian); //$NON-NLS-1$ + supportLangsMap.put( + "sl", WorkbenchMessages.SupportLanguageName_Slovenian); //$NON-NLS-1$ + supportLangsMap.put( + "zh_CN", WorkbenchMessages.SupportLanguageName_SimplifiedCN); //$NON-NLS-1$ + supportLangsMap.put( + "zh_TW", WorkbenchMessages.SupportLanguageName_TraditionalCN); //$NON-NLS-1$ + } + + private Properties loadProperties(File file) { + if (file != null && file.exists() && file.canRead()) { + try { + InputStream stream = new BufferedInputStream( + new FileInputStream(file), 1024); + try { + Properties properties = new Properties(); + properties.load(stream); + return properties; + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + } + } + return null; + } + + private void storeProperties(Properties properties, File file) { + if (file != null && file.exists() && file.canWrite()) { + try { + OutputStream stream = new BufferedOutputStream( + new FileOutputStream(file), 1024); + try { + properties.store(stream, "Store properties into file."); //$NON-NLS-1$ + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + } + } + } + + private File getConfigFile() { + URL configDir = Platform.getConfigurationLocation().getURL(); + try { + URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ + File file = new File(configIni.getFile()); + return file; + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + + private File getSupportLanguageFile() { + try { + URL url = FileLocator.find(new URL(LOADED_LANGUAGES_URL)); + File supportLanguageFile = new File(FileLocator.toFileURL(url) + .getPath()); + return supportLanguageFile; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public void init(IWorkbench workbench) { + } + + @Override + protected void createFieldEditors() { + addLanguageGroup(); + } + + private void addLanguageGroup() { + Composite parent = getFieldEditorParent(); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + parent.setLayout(gridLayout); + addChangeLanguageField(parent); + } + + private void addChangeLanguageField(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + composite.setLayout(new GridLayout()); + + createLangsDescription(composite); + createChangeLanguageControl(parent); + } + + private void createChangeLanguageControl(Composite parent) { + Composite line = new Composite(parent, SWT.NONE); + line.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + line.setLayout(new GridLayout(2, false)); + + int flags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE; + langsViewer = new ListViewer(line, flags); + GridData layoutData = new GridData(SWT.FILL, SWT.BEGINNING, true, false); + langsViewer.getControl().setLayoutData(layoutData); + langsViewer.setContentProvider(new ArrayContentProvider()); + langsViewer.setLabelProvider(new LanguageLabelProvider()); + langsViewer.setInput(supportedLangsKey); + + String languageKey = configIniProperties + .getProperty(LANGUAGE_OSGI_NL_KEY); + String currentLanguageKey = languageKey != null ? languageKey + : oldLangKey; + + langsViewer.setSelection(new StructuredSelection(currentLanguageKey)); + langsViewer + .addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + ISelection langElementSelection = event.getSelection(); + if (langElementSelection instanceof StructuredSelection) { + Object langKey = ((StructuredSelection) langElementSelection) + .getFirstElement(); + + boolean isChanged = !oldLangKey.equals(langKey); + if (isChanged) { + String langSelected = ((LanguageLabelProvider) langsViewer + .getLabelProvider()).getText(langKey); + changingToLangText.setText(langSelected); + } else { + changingToLangText.setText(""); //$NON-NLS-1$ + } + changeButton.setEnabled(isChanged); + } + } + }); + + changeButton = new Button(line, SWT.NONE); + changeButton.setText(WorkbenchMessages.ChangeLanguage_button); + changeButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, + false)); + changeButton.setEnabled(!currentLanguageKey.equals(oldLangKey)); + changeButton.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + ISelection langElementSelection = langsViewer.getSelection(); + if (langElementSelection instanceof StructuredSelection) { + Object langKey = ((StructuredSelection) langElementSelection) + .getFirstElement(); + String langSelected = ((LanguageLabelProvider) langsViewer + .getLabelProvider()).getText(langKey); + String message = NLS.bind( + WorkbenchMessages.ConfirmToRestart_description, + langSelected); + MessageDialog confirmDialog = new MessageDialog( + getShell(), + WorkbenchMessages.ConfirmToRestart_title, + null, + message, + MessageDialog.CONFIRM, + new String[] { + WorkbenchMessages.ConfirmToRestart_defaultButton, + WorkbenchMessages.ConfirmToRestart_cancelButton }, + IDialogConstants.OK_ID); + int restart = confirmDialog.open(); + configIniProperties.put(LANGUAGE_OSGI_NL_KEY, langKey); + storeProperties(configIniProperties, getConfigFile()); + if (restart == 0) { + PlatformUI.getWorkbench().restart(); + } + } + } + + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }); + } + + private void createLangsDescription(Composite composite) { + Composite descriptionComposite = new Composite(composite, SWT.NONE); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + true, false)); + GridLayout descriptionLayout = new GridLayout(2, false); + descriptionLayout.marginHeight = 0; + descriptionLayout.marginWidth = 0; + descriptionComposite.setLayout(descriptionLayout); + + Label langToChangeDescription = new Label(descriptionComposite, + SWT.NONE); + langToChangeDescription + .setText(WorkbenchMessages.ChangeLanguageTo_description); + langToChangeDescription.setLayoutData(new GridData(SWT.FILL)); + + changingToLangText = new Label(descriptionComposite, SWT.READ_ONLY + | SWT.SINGLE | SWT.BORDER | SWT.SHADOW_IN | SWT.LEFT); + changingToLangText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, + true, true)); + + String languageKey = configIniProperties + .getProperty(LANGUAGE_OSGI_NL_KEY); + String supportLang = supportLangsMap.get(languageKey); + if (supportLang != null) + changingToLangText.setText(supportLang); + } + + @Override + protected void performDefaults() { + configIniProperties.put(LANGUAGE_OSGI_NL_KEY, + System.getProperty(LANGUAGE_OSGI_NL_KEY)); + langsViewer.setSelection( + new StructuredSelection(System + .getProperty(LANGUAGE_OSGI_NL_KEY)), true); + storeProperties(configIniProperties, getConfigFile()); + super.performDefaults(); + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + + ISelection langElementSelection = langsViewer.getSelection(); + if (langElementSelection instanceof StructuredSelection) { + Object langKey = ((StructuredSelection) langElementSelection) + .getFirstElement(); + if (!oldLangKey.equals(langKey)) { + String message = WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_description; + MessageDialog confirmDialog = new MessageDialog( + getShell(), + WorkbenchMessages.ConfirmToRestart_title, + null, + message, + MessageDialog.CONFIRM, + new String[] { + WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_defaultButton, + WorkbenchMessages.LanguagePrefPage_ConfirmToRestart_laterButton }, + IDialogConstants.OK_ID); + int restart = confirmDialog.open(); + if (restart == -1) + return false; + + configIniProperties.put(LANGUAGE_OSGI_NL_KEY, langKey); + storeProperties(configIniProperties, getConfigFile()); + if (restart == IDialogConstants.OK_ID) { + PlatformUI.getWorkbench().restart(); + } + } + } + + return true; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java index 016f311ed..6fdf03c35 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java @@ -1,348 +1,348 @@ -package org.xmind.cathy.internal; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.preference.PreferenceFieldEditorPageSection; -import org.xmind.ui.resources.ColorUtils; - -public class LanguagePreferencePageSection - extends PreferenceFieldEditorPageSection - implements IWorkbenchPreferencePage, MouseListener { - - private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ - - private static final String LOADED_LANGUAGES_URL = "platform:/plugin/org.xmind.cathy/resource/langs.properties"; //$NON-NLS-1$ - - private Properties supportLanguageProperties; - - private String oldLangKey = null; - - private String newLangKey = null; - - private Properties configIniProperties; - - private Label langLabel; - - private LocalResourceManager resource; - - private static final String blue = "#0070D8"; //$NON-NLS-1$ - - private static final String[] supportedLangsKey = { "en_US", "de", "fr", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "zh_CN", "zh_TW", "ja", "ko", "da", "es" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ - - private Map langMap = null; - - public void init(IWorkbench workbench) { - configIniProperties = loadProperties(getConfigFile()); - supportLanguageProperties = loadProperties(getSupportLanguageFile()); - if (oldLangKey == null) { - String languageKey = configIniProperties - .getProperty(LANGUAGE_OSGI_NL_KEY); - oldLangKey = languageKey != null ? languageKey - : System.getProperty(LANGUAGE_OSGI_NL_KEY); - } - } - -// @Override -// public void createControl(Composite parent) { -// Control body = createContents(parent); -// setControl(body); -// } - - @Override - protected Control createContents(Composite parent) { - - if (null == resource) - resource = new LocalResourceManager(JFaceResources.getResources(), - parent); - - Composite topContainer = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().grab(true, false).applyTo(topContainer); - GridLayoutFactory.fillDefaults().numColumns(2).applyTo(topContainer); - - Label describe = new Label(topContainer, SWT.NONE); - describe.setText(WorkbenchMessages.ChangeLanguageTo_description); - - langLabel = new Label(topContainer, SWT.NONE); - langLabel.setText(supportLanguageProperties.getProperty(oldLangKey)); - GridDataFactory.fillDefaults().grab(true, false).applyTo(langLabel); - - GridLayout parentLayout = (GridLayout) parent.getLayout(); - if (parentLayout != null) { - parentLayout.verticalSpacing = 10; - } - - Composite container = createLangContainer(parent, 3); - - //firstly init language map, and init langMap by OldLangKey. - initLangMap(container); - initByOldLangKey(); - - return container; - } - - private void initLangMap(Composite container) { - if (null == langMap) - langMap = new HashMap(); - for (String lang : supportedLangsKey) { - Composite langComposite = createLang(container, - supportLanguageProperties.getProperty(lang)); - langComposite.addMouseListener(this); - Control[] children = langComposite.getChildren(); - for (Control child : children) { - child.addMouseListener(this); - } - langMap.put(langComposite, lang); - } - } - - private void initByOldLangKey() { - if (null != langMap && langMap.containsValue(oldLangKey)) { - Iterator iterator = langMap.entrySet().iterator(); - while (iterator.hasNext()) { - @SuppressWarnings("unchecked") - Map.Entry item = (Entry) iterator - .next(); - if (oldLangKey.equals(item.getValue())) { - Composite composite = item.getKey(); - changeControlBack(composite, - (Color) resource.get(ColorUtils.toDescriptor(blue)), - ColorConstants.white); - } - } - } - } - - private Composite createLangContainer(Composite parent, int cols) { - Composite container = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().grab(true, false).applyTo(container); - GridLayoutFactory.fillDefaults().equalWidth(true).spacing(8, 10) - .numColumns(cols).applyTo(container); - return container; - } - - private Composite createLang(Composite parent, String lang) { - Composite panel = new Composite(parent, SWT.BORDER); - panel.setBackground(ColorConstants.white); - GridLayoutFactory.fillDefaults().margins(5, 5).spacing(5, 5) - .applyTo(panel); - GridDataFactory.fillDefaults().grab(true, true).applyTo(panel); - - Label langLabel = new Label(panel, SWT.NONE); - langLabel.setText(lang); - langLabel.setBackground(ColorConstants.white); - return panel; - } - - private File getSupportLanguageFile() { - try { - URL url = FileLocator.find(new URL(LOADED_LANGUAGES_URL)); - File supportLanguageFile = new File( - FileLocator.toFileURL(url).getPath()); - return supportLanguageFile; - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - private Properties loadProperties(File file) { - if (file != null && file.exists() && file.canRead()) { - try { - InputStream stream = new BufferedInputStream( - new FileInputStream(file), 1024); - try { - Properties properties = new Properties(); - properties.load(stream); - return properties; - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - } - } - return null; - } - - private File getConfigFile() { - URL configDir = Platform.getConfigurationLocation().getURL(); - try { - URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ - File file = new File(configIni.getFile()); - return file; - } catch (MalformedURLException e) { - e.printStackTrace(); - } - return null; - } - - private void storeProperties(Properties properties, File file) { - if (file != null && file.exists() && file.canWrite()) { - try { - OutputStream stream = new BufferedOutputStream( - new FileOutputStream(file), 1024); - try { - properties.store(stream, "Store properties into file."); //$NON-NLS-1$ - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - } - } - } - - @Override - protected void performDefaults() { - configIniProperties.put(LANGUAGE_OSGI_NL_KEY, - System.getProperty(LANGUAGE_OSGI_NL_KEY)); - String lang = System.getProperty(LANGUAGE_OSGI_NL_KEY); - if (null != langMap && langMap.containsValue(lang)) { - clearLangSelection(); - newLangKey = lang; - Iterator iterator = langMap.entrySet().iterator(); - while (iterator.hasNext()) { - @SuppressWarnings("unchecked") - Map.Entry item = (Entry) iterator - .next(); - if (lang.equals(item.getValue())) { - Composite composite = item.getKey(); - changeControlBack(composite, - (Color) resource.get(ColorUtils.toDescriptor(blue)), - ColorConstants.white); - } - } - } - storeProperties(configIniProperties, getConfigFile()); - super.performDefaults(); - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - if (null != newLangKey && !oldLangKey.equals(newLangKey)) { - String message = WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_description; - MessageDialog confirmDialog = new MessageDialog(getShell(), - WorkbenchMessages.ConfirmToRestart_title, null, message, - MessageDialog.CONFIRM, - new String[] { - WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_defaultButton, - WorkbenchMessages.LanguagePrefPage_ConfirmToRestart_laterButton }, - IDialogConstants.OK_ID); - int restart = confirmDialog.open(); - if (restart == -1) - return false; - - configIniProperties.put(LANGUAGE_OSGI_NL_KEY, newLangKey); - storeProperties(configIniProperties, getConfigFile()); - - if (restart == IDialogConstants.OK_ID) { - PlatformUI.getWorkbench().restart(); - } - } - return true; - } - - public void mouseDoubleClick(MouseEvent e) { - mouseDown(e); - this.performOk(); - } - - public void mouseDown(MouseEvent e) { - Composite composite = null; - Object object = e.getSource(); - if (null != object && object instanceof Control) { - if (object instanceof Composite) - composite = (Composite) object; - else if (object instanceof Label) - composite = ((Label) object).getParent(); - } - changeLangSelection(composite); - } - - public void mouseUp(MouseEvent e) { - } - - private void changeLangSelection(Composite composite) { - if (null != composite) { - clearLangSelection(); - newLangKey = null; - changeControlBack(composite, - (Color) resource.get(ColorUtils.toDescriptor(blue)), - ColorConstants.white); - if (langMap.containsKey(composite)) { - newLangKey = langMap.get(composite); - langLabel.setText( - supportLanguageProperties.getProperty(newLangKey)); - } - } - } - - private void clearLangSelection() { - Iterator iterator = langMap.entrySet().iterator(); - while (iterator.hasNext()) { - @SuppressWarnings("unchecked") - Map.Entry it = (Entry) iterator - .next(); - changeControlBack(it.getKey(), ColorConstants.white, - ColorConstants.black); - } - } - - private void changeControlBack(Composite composite, Color color, - Color fontColor) { - composite.setBackground(color); - Control[] children = composite.getChildren(); - for (Control child : children) { - child.setBackground(color); - child.setForeground(fontColor); - } - } - - @Override - protected void createFieldEditors() { - } - -} +package org.xmind.cathy.internal; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.resources.ColorUtils; + +public class LanguagePreferencePageSection + extends PreferenceFieldEditorPageSection + implements IWorkbenchPreferencePage, MouseListener { + + private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ + + private static final String LOADED_LANGUAGES_URL = "platform:/plugin/org.xmind.cathy/resource/langs.properties"; //$NON-NLS-1$ + + private Properties supportLanguageProperties; + + private String oldLangKey = null; + + private String newLangKey = null; + + private Properties configIniProperties; + + private Label langLabel; + + private LocalResourceManager resource; + + private static final String blue = "#0070D8"; //$NON-NLS-1$ + + private static final String[] supportedLangsKey = { "en_US", "de", "fr", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "zh_CN", "zh_TW", "ja", "ko", "da", "es", "sl", "it" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ + + private Map langMap = null; + + public void init(IWorkbench workbench) { + configIniProperties = loadProperties(getConfigFile()); + supportLanguageProperties = loadProperties(getSupportLanguageFile()); + if (oldLangKey == null) { + String languageKey = configIniProperties + .getProperty(LANGUAGE_OSGI_NL_KEY); + oldLangKey = languageKey != null ? languageKey + : System.getProperty(LANGUAGE_OSGI_NL_KEY); + } + } + + @Override + protected Control createContents(Composite parent) { + + if (null == resource) + resource = new LocalResourceManager(JFaceResources.getResources(), + parent); + + Composite topContainer = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(topContainer); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(topContainer); + + Label describe = new Label(topContainer, SWT.NONE); + describe.setText(WorkbenchMessages.ChangeLanguageTo_description); + + langLabel = new Label(topContainer, SWT.NONE); + if (supportLanguageProperties == null) + supportLanguageProperties = loadProperties( + getSupportLanguageFile()); + String langString = supportLanguageProperties.getProperty(oldLangKey); + langString = langString != null ? langString : " "; //$NON-NLS-1$ + + langLabel.setText(langString); + GridDataFactory.fillDefaults().grab(true, false).applyTo(langLabel); + GridLayout parentLayout = (GridLayout) parent.getLayout(); + + if (parentLayout != null) { + parentLayout.verticalSpacing = 10; + } + + Composite container = createLangContainer(parent, 3); + + //firstly init language map, and init langMap by OldLangKey. + initLangMap(container); + initByOldLangKey(); + + return container; + } + + private void initLangMap(Composite container) { + if (null == langMap) + langMap = new HashMap(); + for (String lang : supportedLangsKey) { + Composite langComposite = createLang(container, + supportLanguageProperties.getProperty(lang)); + langComposite.addMouseListener(this); + Control[] children = langComposite.getChildren(); + for (Control child : children) { + child.addMouseListener(this); + } + langMap.put(langComposite, lang); + } + } + + private void initByOldLangKey() { + if (null != langMap && langMap.containsValue(oldLangKey)) { + Iterator iterator = langMap.entrySet().iterator(); + while (iterator.hasNext()) { + @SuppressWarnings("unchecked") + Map.Entry item = (Entry) iterator + .next(); + if (oldLangKey.equals(item.getValue())) { + Composite composite = item.getKey(); + changeControlBack(composite, + (Color) resource.get(ColorUtils.toDescriptor(blue)), + ColorConstants.white); + } + } + } + } + + private Composite createLangContainer(Composite parent, int cols) { + Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(container); + GridLayoutFactory.fillDefaults().equalWidth(true).spacing(8, 10) + .numColumns(cols).applyTo(container); + return container; + } + + private Composite createLang(Composite parent, String lang) { + Composite panel = new Composite(parent, SWT.BORDER); + panel.setBackground(ColorConstants.white); + GridLayoutFactory.fillDefaults().margins(5, 5).spacing(5, 5) + .applyTo(panel); + GridDataFactory.fillDefaults().grab(true, true).applyTo(panel); + + Label langLabel = new Label(panel, SWT.NONE); + langLabel.setText(lang); + langLabel.setBackground(ColorConstants.white); + return panel; + } + + private File getSupportLanguageFile() { + try { + URL url = FileLocator.find(new URL(LOADED_LANGUAGES_URL)); + File supportLanguageFile = new File( + FileLocator.toFileURL(url).getPath()); + return supportLanguageFile; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private Properties loadProperties(File file) { + if (file != null && file.exists() && file.canRead()) { + try { + InputStream stream = new BufferedInputStream( + new FileInputStream(file), 1024); + try { + Properties properties = new Properties(); + properties.load(stream); + return properties; + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + } + } + return null; + } + + private File getConfigFile() { + URL configDir = Platform.getConfigurationLocation().getURL(); + try { + URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ + File file = new File(configIni.getFile()); + return file; + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + + private void storeProperties(Properties properties, File file) { + if (file != null && file.exists() && file.canWrite()) { + try { + OutputStream stream = new BufferedOutputStream( + new FileOutputStream(file), 1024); + try { + properties.store(stream, "Store properties into file."); //$NON-NLS-1$ + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + } + } + } + + @Override + protected void performDefaults() { + configIniProperties.put(LANGUAGE_OSGI_NL_KEY, + System.getProperty(LANGUAGE_OSGI_NL_KEY)); + String lang = System.getProperty(LANGUAGE_OSGI_NL_KEY); + if (null != langMap && langMap.containsValue(lang)) { + clearLangSelection(); + newLangKey = lang; + Iterator iterator = langMap.entrySet().iterator(); + while (iterator.hasNext()) { + @SuppressWarnings("unchecked") + Map.Entry item = (Entry) iterator + .next(); + if (lang.equals(item.getValue())) { + Composite composite = item.getKey(); + changeControlBack(composite, + (Color) resource.get(ColorUtils.toDescriptor(blue)), + ColorConstants.white); + } + } + } + storeProperties(configIniProperties, getConfigFile()); + super.performDefaults(); + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + if (null != newLangKey && !oldLangKey.equals(newLangKey)) { + String message = WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_description; + MessageDialog confirmDialog = new MessageDialog(getShell(), + WorkbenchMessages.ConfirmToRestart_title, null, message, + MessageDialog.CONFIRM, + new String[] { + WorkbenchMessages.LanguagePrefPage_ConfirmToRestart2_defaultButton, + WorkbenchMessages.LanguagePrefPage_ConfirmToRestart_laterButton }, + IDialogConstants.OK_ID); + int restart = confirmDialog.open(); + if (restart == -1) + return false; + + configIniProperties.put(LANGUAGE_OSGI_NL_KEY, newLangKey); + storeProperties(configIniProperties, getConfigFile()); + + if (restart == IDialogConstants.OK_ID) { + PlatformUI.getWorkbench().restart(); + } + } + return true; + } + + public void mouseDoubleClick(MouseEvent e) { + mouseDown(e); + this.performOk(); + } + + public void mouseDown(MouseEvent e) { + Composite composite = null; + Object object = e.getSource(); + if (null != object && object instanceof Control) { + if (object instanceof Composite) + composite = (Composite) object; + else if (object instanceof Label) + composite = ((Label) object).getParent(); + } + changeLangSelection(composite); + } + + public void mouseUp(MouseEvent e) { + } + + private void changeLangSelection(Composite composite) { + if (null != composite) { + clearLangSelection(); + newLangKey = null; + changeControlBack(composite, + (Color) resource.get(ColorUtils.toDescriptor(blue)), + ColorConstants.white); + if (langMap.containsKey(composite)) { + newLangKey = langMap.get(composite); + langLabel.setText( + supportLanguageProperties.getProperty(newLangKey)); + } + } + } + + private void clearLangSelection() { + Iterator iterator = langMap.entrySet().iterator(); + while (iterator.hasNext()) { + @SuppressWarnings("unchecked") + Map.Entry it = (Entry) iterator + .next(); + changeControlBack(it.getKey(), ColorConstants.white, + ColorConstants.black); + } + } + + private void changeControlBack(Composite composite, Color color, + Color fontColor) { + composite.setBackground(color); + Control[] children = composite.getChildren(); + for (Control child : children) { + child.setBackground(color); + child.setForeground(fontColor); + } + } + + @Override + protected void createFieldEditors() { + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LicenseAgentProxy.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LicenseAgentProxy.java index f022c5de2..962f3db02 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LicenseAgentProxy.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LicenseAgentProxy.java @@ -1,130 +1,130 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.cathy.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.licensing.ILicenseAgent; -import org.xmind.core.licensing.ILicenseChangedListener; -import org.xmind.core.licensing.ILicenseKeyHeader; - -/** - * @author Frank Shaka - * - */ -public class LicenseAgentProxy implements ILicenseAgent { - - private ILicenseAgent delegate; - - private final List listeners; - - /** - * - */ - public LicenseAgentProxy() { - this.delegate = null; - this.listeners = new ArrayList(1); - } - - /** - * @param delegate - * the delegate to set - */ - public void setDelegate(ILicenseAgent delegate) { - ILicenseAgent oldDelegate = this.delegate; - if (delegate == oldDelegate) - return; - - if (oldDelegate != null) { - for (ILicenseChangedListener listener : listeners) { - oldDelegate.removeLicenseChangedListener(listener); - } - } - this.delegate = delegate; - if (delegate != null) { - for (ILicenseChangedListener listener : listeners) { - delegate.addLicenseChangedListener(listener); - } - } - - for (ILicenseChangedListener listener : listeners) { - listener.licenseChanged(this); - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.licensing.ILicenseAgent#getLicenseType() - */ - @Override - public int getLicenseType() { - return delegate == null ? NOT_LICENSED : delegate.getLicenseType(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.licensing.ILicenseAgent#getLicenseeName() - */ - @Override - public String getLicenseeName() { - return delegate == null ? null : delegate.getLicenseeName(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.licensing.ILicenseAgent#getLicenseKeyHeader() - */ - @Override - public ILicenseKeyHeader getLicenseKeyHeader() { - return delegate == null ? null : delegate.getLicenseKeyHeader(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.licensing.ILicenseAgent#addLicenseChangedListener(org. - * xmind.core.licensing.ILicenseChangedListener) - */ - @Override - public void addLicenseChangedListener(ILicenseChangedListener listener) { - listeners.add(listener); - if (delegate != null) { - delegate.addLicenseChangedListener(listener); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.licensing.ILicenseAgent#removeLicenseChangedListener(org. - * xmind.core.licensing.ILicenseChangedListener) - */ - @Override - public void removeLicenseChangedListener(ILicenseChangedListener listener) { - listeners.remove(listener); - if (delegate != null) { - delegate.removeLicenseChangedListener(listener); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.cathy.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.licensing.ILicenseAgent; +import org.xmind.core.licensing.ILicenseChangedListener; +import org.xmind.core.licensing.ILicenseKeyHeader; + +/** + * @author Frank Shaka + * + */ +public class LicenseAgentProxy implements ILicenseAgent { + + private ILicenseAgent delegate; + + private final List listeners; + + /** + * + */ + public LicenseAgentProxy() { + this.delegate = null; + this.listeners = new ArrayList(1); + } + + /** + * @param delegate + * the delegate to set + */ + public void setDelegate(ILicenseAgent delegate) { + ILicenseAgent oldDelegate = this.delegate; + if (delegate == oldDelegate) + return; + + if (oldDelegate != null) { + for (ILicenseChangedListener listener : listeners) { + oldDelegate.removeLicenseChangedListener(listener); + } + } + this.delegate = delegate; + if (delegate != null) { + for (ILicenseChangedListener listener : listeners) { + delegate.addLicenseChangedListener(listener); + } + } + + for (ILicenseChangedListener listener : listeners) { + listener.licenseChanged(this); + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.licensing.ILicenseAgent#getLicenseType() + */ + @Override + public int getLicenseType() { + return delegate == null ? NOT_LICENSED : delegate.getLicenseType(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.licensing.ILicenseAgent#getLicenseeName() + */ + @Override + public String getLicenseeName() { + return delegate == null ? null : delegate.getLicenseeName(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.licensing.ILicenseAgent#getLicenseKeyHeader() + */ + @Override + public ILicenseKeyHeader getLicenseKeyHeader() { + return delegate == null ? null : delegate.getLicenseKeyHeader(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.licensing.ILicenseAgent#addLicenseChangedListener(org. + * xmind.core.licensing.ILicenseChangedListener) + */ + @Override + public void addLicenseChangedListener(ILicenseChangedListener listener) { + listeners.add(listener); + if (delegate != null) { + delegate.addLicenseChangedListener(listener); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.licensing.ILicenseAgent#removeLicenseChangedListener(org. + * xmind.core.licensing.ILicenseChangedListener) + */ + @Override + public void removeLicenseChangedListener(ILicenseChangedListener listener) { + listeners.remove(listener); + if (delegate != null) { + delegate.removeLicenseChangedListener(listener); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/Log.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/Log.java index 0653930e3..2c45e8e8a 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/Log.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/Log.java @@ -1,209 +1,209 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.xmind.core.util.FileUtils; - -public class Log implements ISchedulingRule { - - public static final String SINGLETON = ".singleton"; //$NON-NLS-1$ - - public static final String OPENING = ".opening"; //$NON-NLS-1$ - - public static final String K_PRIMARY_WINDOW = "PRIMARY_WINDOW"; //$NON-NLS-1$ - - private static String lineSeparator = null; - - /* - * This is a former workaround. No use after SWT has OpenDocument event. - * ======================================================================== - * On Mac OS X, we use AppleScript to open .xmind file on double click. - * AppleScript supports only UTF-16. So we should do writing and reading log - * files using UTF-16 format on Mac OS X. - */ - // private static boolean ON_MAC = "macosx".equals(Platform.getOS()); //$NON-NLS-1$ - - private File file; - - private Properties properties = null; - - public Log(File file) { - this.file = file; - } - - public Properties getProperties() { - if (properties == null) { - loadProperties(); - } - return properties; - } - - private void loadProperties() { - properties = new Properties(); - - if (file.isFile() && file.canRead()) { - try { - FileInputStream is = new FileInputStream(file); - try { - properties.load(is); - } finally { - is.close(); - } - } catch (IOException e) { - CathyPlugin - .log(e, - "Failed to load properties from log file: " + file.getAbsolutePath()); //$NON-NLS-1$ - } - } - } - - public void saveProperties() { - if (properties == null) - return; - - FileUtils.ensureFileParent(file); - try { - FileOutputStream out = new FileOutputStream(file); - try { - properties.store(out, null); - } finally { - out.close(); - } - } catch (IOException e) { - CathyPlugin - .log(e, - "Failed to save properties to log file: " + file.getAbsolutePath()); //$NON-NLS-1$ - } - } - - public String[] getContents() { - if (!file.isFile() || !file.canRead()) - return new String[0]; - List lines = new ArrayList(); - try { - BufferedReader reader = new BufferedReader(new InputStreamReader( - new FileInputStream(file), "UTF-8")); //$NON-NLS-1$ - try { - String line; - while ((line = reader.readLine()) != null) { - line = line.trim(); - if (!"".equals(line)) //$NON-NLS-1$ - lines.add(line); - } - } finally { - reader.close(); - } - } catch (IOException e) { - CathyPlugin.log(e, - "Failed to read log file: " + file.getAbsolutePath()); //$NON-NLS-1$ - } - return lines.toArray(new String[lines.size()]); - } - - public void setContents(String... contents) { - write(false, contents); - } - - public void append(String... lines) { - if (lines.length == 0) - return; - write(true, lines); - } - - private void write(boolean append, String... contents) { - FileUtils.ensureFileParent(file); - try { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(file, append), "UTF-8")); //$NON-NLS-1$ - try { - for (String line : contents) { - writer.write(line); - writer.newLine(); - } - } finally { - writer.close(); - } - } catch (IOException e) { - CathyPlugin.log(e, - "Failed to write log file: " + file.getAbsolutePath()); //$NON-NLS-1$ - } - } - - public void delete() { - file.delete(); - properties = null; - } - - public boolean exists() { - return file.exists(); - } - - public static Log get(String name) { - URL url = Platform.getInstanceLocation().getURL(); - try { - url = FileLocator.toFileURL(url); - } catch (IOException e) { - //ignore this exception - } - File file = new File(url.getFile(), name); - Log log = new Log(file); - return log; - } - - public static String getLineSeparator() { - if (lineSeparator == null) - lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$ - return lineSeparator; - } - - public boolean contains(ISchedulingRule rule) { - if (rule == this) - return true; - if (rule instanceof Log) { - Log log = (Log) rule; - if (log.file == null || file == null) - return false; - return log.file.getAbsolutePath().equals(file.getAbsolutePath()); - } - return false; - } - - public boolean isConflicting(ISchedulingRule rule) { - if (rule == this) - return true; - if (rule instanceof Log) { - Log log = (Log) rule; - if (log.file == null || file == null) - return false; - return log.file.getAbsolutePath().equals(file.getAbsolutePath()); - } - return false; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.xmind.core.util.FileUtils; + +public class Log implements ISchedulingRule { + + public static final String SINGLETON = ".singleton"; //$NON-NLS-1$ + + public static final String OPENING = ".opening"; //$NON-NLS-1$ + + public static final String K_PRIMARY_WINDOW = "PRIMARY_WINDOW"; //$NON-NLS-1$ + + private static String lineSeparator = null; + + /* + * This is a former workaround. No use after SWT has OpenDocument event. + * ======================================================================== + * On Mac OS X, we use AppleScript to open .xmind file on double click. + * AppleScript supports only UTF-16. So we should do writing and reading log + * files using UTF-16 format on Mac OS X. + */ + // private static boolean ON_MAC = "macosx".equals(Platform.getOS()); //$NON-NLS-1$ + + private File file; + + private Properties properties = null; + + public Log(File file) { + this.file = file; + } + + public Properties getProperties() { + if (properties == null) { + loadProperties(); + } + return properties; + } + + private void loadProperties() { + properties = new Properties(); + + if (file.isFile() && file.canRead()) { + try { + FileInputStream is = new FileInputStream(file); + try { + properties.load(is); + } finally { + is.close(); + } + } catch (IOException e) { + CathyPlugin + .log(e, + "Failed to load properties from log file: " + file.getAbsolutePath()); //$NON-NLS-1$ + } + } + } + + public void saveProperties() { + if (properties == null) + return; + + FileUtils.ensureFileParent(file); + try { + FileOutputStream out = new FileOutputStream(file); + try { + properties.store(out, null); + } finally { + out.close(); + } + } catch (IOException e) { + CathyPlugin + .log(e, + "Failed to save properties to log file: " + file.getAbsolutePath()); //$NON-NLS-1$ + } + } + + public String[] getContents() { + if (!file.isFile() || !file.canRead()) + return new String[0]; + List lines = new ArrayList(); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader( + new FileInputStream(file), "UTF-8")); //$NON-NLS-1$ + try { + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!"".equals(line)) //$NON-NLS-1$ + lines.add(line); + } + } finally { + reader.close(); + } + } catch (IOException e) { + CathyPlugin.log(e, + "Failed to read log file: " + file.getAbsolutePath()); //$NON-NLS-1$ + } + return lines.toArray(new String[lines.size()]); + } + + public void setContents(String... contents) { + write(false, contents); + } + + public void append(String... lines) { + if (lines.length == 0) + return; + write(true, lines); + } + + private void write(boolean append, String... contents) { + FileUtils.ensureFileParent(file); + try { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(file, append), "UTF-8")); //$NON-NLS-1$ + try { + for (String line : contents) { + writer.write(line); + writer.newLine(); + } + } finally { + writer.close(); + } + } catch (IOException e) { + CathyPlugin.log(e, + "Failed to write log file: " + file.getAbsolutePath()); //$NON-NLS-1$ + } + } + + public void delete() { + file.delete(); + properties = null; + } + + public boolean exists() { + return file.exists(); + } + + public static Log get(String name) { + URL url = Platform.getInstanceLocation().getURL(); + try { + url = FileLocator.toFileURL(url); + } catch (IOException e) { + //ignore this exception + } + File file = new File(url.getFile(), name); + Log log = new Log(file); + return log; + } + + public static String getLineSeparator() { + if (lineSeparator == null) + lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$ + return lineSeparator; + } + + public boolean contains(ISchedulingRule rule) { + if (rule == this) + return true; + if (rule instanceof Log) { + Log log = (Log) rule; + if (log.file == null || file == null) + return false; + return log.file.getAbsolutePath().equals(file.getAbsolutePath()); + } + return false; + } + + public boolean isConflicting(ISchedulingRule rule) { + if (rule == this) + return true; + if (rule instanceof Log) { + Log log = (Log) rule; + if (log.file == null || file == null) + return false; + return log.file.getAbsolutePath().equals(file.getAbsolutePath()); + } + return false; + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenDocumentQueue.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenDocumentQueue.java index e2752b4bc..093876466 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenDocumentQueue.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenDocumentQueue.java @@ -1,84 +1,84 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -public class OpenDocumentQueue { - - private static final String[] EMPTY_QUEUE = new String[0]; - - private class OpenDocumentHook implements Listener { - - public void handleEvent(Event event) { - if (event.text != null && !"".equals(event.text)) //$NON-NLS-1$ - enqueue(event.text); - } - - } - - private static final OpenDocumentQueue instance = new OpenDocumentQueue(); - - private List files = new ArrayList(); - - private Listener hook = null; - - private OpenDocumentQueue() { - } - - public void hook(Display display) { - if (hook == null) { - hook = new OpenDocumentHook(); - } - display.addListener(SWT.OpenDocument, hook); - } - - public void unhook(Display display) { - if (hook != null) - display.removeListener(SWT.OpenDocument, hook); - } - - public void enqueue(String path) { - if (new File(path).exists()) { - synchronized (this) { - files.add(path); - } - CathyPlugin.log("Path queued to be opened: " + path); //$NON-NLS-1$ - } else { - CathyPlugin.log("Non-existing path skipped: " + path); //$NON-NLS-1$ - } - } - - public String[] drain() { - synchronized (this) { - if (files.isEmpty()) - return EMPTY_QUEUE; - String[] array = files.toArray(new String[files.size()]); - files.clear(); - return array; - } - } - - public static OpenDocumentQueue getInstance() { - return instance; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +public class OpenDocumentQueue { + + private static final String[] EMPTY_QUEUE = new String[0]; + + private class OpenDocumentHook implements Listener { + + public void handleEvent(Event event) { + if (event.text != null && !"".equals(event.text)) //$NON-NLS-1$ + enqueue(event.text); + } + + } + + private static final OpenDocumentQueue instance = new OpenDocumentQueue(); + + private List files = new ArrayList(); + + private Listener hook = null; + + private OpenDocumentQueue() { + } + + public void hook(Display display) { + if (hook == null) { + hook = new OpenDocumentHook(); + } + display.addListener(SWT.OpenDocument, hook); + } + + public void unhook(Display display) { + if (hook != null) + display.removeListener(SWT.OpenDocument, hook); + } + + public void enqueue(String path) { + if (new File(path).exists()) { + synchronized (this) { + files.add(path); + } + CathyPlugin.log("Path queued to be opened: " + path); //$NON-NLS-1$ + } else { + CathyPlugin.log("Non-existing path skipped: " + path); //$NON-NLS-1$ + } + } + + public String[] drain() { + synchronized (this) { + if (files.isEmpty()) + return EMPTY_QUEUE; + String[] array = files.toArray(new String[files.size()]); + files.clear(); + return array; + } + } + + public static OpenDocumentQueue getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFileCommandHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFileCommandHandler.java index 75b3bbcf9..efb93d2bd 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFileCommandHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFileCommandHandler.java @@ -1,53 +1,53 @@ -package org.xmind.cathy.internal; - -import java.util.Collections; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.jobs.DownloadAndOpenFileJob; -import org.xmind.cathy.internal.jobs.OpenFilesJob; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.ICommandHandler; - -public class OpenFileCommandHandler implements ICommandHandler { - - public OpenFileCommandHandler() { - } - - public IStatus execute(IProgressMonitor monitor, ICommand command, - String[] matches) { - IWorkbench workbench = PlatformUI.getWorkbench(); - if (workbench == null) - return null; - - String file = command.getArgument("file"); //$NON-NLS-1$ - if (file != null) - return openFile(workbench, file); - - String url = command.getArgument("url"); //$NON-NLS-1$ - if (url != null) - return openURL(workbench, url, command.getArgument("name")); //$NON-NLS-1$ - - return null; - } - - private IStatus openFile(IWorkbench workbench, String filePath) { - CathyPlugin.log("Opening file through 'xmind:' protocol: " + filePath); //$NON-NLS-1$ - OpenFilesJob openFilesJob = new OpenFilesJob(workbench, - WorkbenchMessages.CheckOpenFilesJob_CheckFiles_name, - Collections.singletonList(filePath)); - openFilesJob.setRule(Log.get(Log.OPENING)); - openFilesJob.schedule(); - return Status.OK_STATUS; - } - - private IStatus openURL(IWorkbench workbench, String url, String name) { - CathyPlugin.log("Opening URL through 'xmind:' protocol: " + url); //$NON-NLS-1$ - new DownloadAndOpenFileJob(workbench, url, name).schedule(); - return Status.OK_STATUS; - } - -} +package org.xmind.cathy.internal; + +import java.util.Collections; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.jobs.DownloadAndOpenFileJob; +import org.xmind.cathy.internal.jobs.OpenFilesJob; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.ICommandHandler; + +public class OpenFileCommandHandler implements ICommandHandler { + + public OpenFileCommandHandler() { + } + + public IStatus execute(IProgressMonitor monitor, ICommand command, + String[] matches) { + IWorkbench workbench = PlatformUI.getWorkbench(); + if (workbench == null) + return null; + + String file = command.getArgument("file"); //$NON-NLS-1$ + if (file != null) + return openFile(workbench, file); + + String url = command.getArgument("url"); //$NON-NLS-1$ + if (url != null) + return openURL(workbench, url, command.getArgument("name")); //$NON-NLS-1$ + + return null; + } + + private IStatus openFile(IWorkbench workbench, String filePath) { + CathyPlugin.log("Opening file through 'xmind:' protocol: " + filePath); //$NON-NLS-1$ + OpenFilesJob openFilesJob = new OpenFilesJob(workbench, + WorkbenchMessages.CheckOpenFilesJob_CheckFiles_name, + Collections.singletonList(filePath)); + openFilesJob.setRule(Log.get(Log.OPENING)); + openFilesJob.schedule(); + return Status.OK_STATUS; + } + + private IStatus openURL(IWorkbench workbench, String url, String name) { + CathyPlugin.log("Opening URL through 'xmind:' protocol: " + url); //$NON-NLS-1$ + new DownloadAndOpenFileJob(workbench, url, name).schedule(); + return Status.OK_STATUS; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFilesProcess.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFilesProcess.java index 1a6d0f9ae..2b7d9c8a4 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFilesProcess.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/OpenFilesProcess.java @@ -1,198 +1,198 @@ -package org.xmind.cathy.internal; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbench; -import org.xmind.cathy.internal.jobs.OpenXMindCommandFileJob; -import org.xmind.core.IWorkbook; -import org.xmind.core.command.Command; -import org.xmind.core.command.CommandJob; -import org.xmind.core.command.ICommand; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.MarkerImpExpUtils; -import org.xmind.ui.internal.editor.ClonedWorkbookRef; -import org.xmind.ui.internal.imports.freemind.FreeMindImporter; -import org.xmind.ui.internal.imports.mm.MindManagerImporter; -import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.PrefUtils; -import org.xmind.ui.wizards.MindMapImporter; - -public class OpenFilesProcess extends AbstractCheckFilesProcess { - - private List filesToOpen; - - private boolean markersImported = false; - - private List commandFilesToOpen = new ArrayList(1); - - public OpenFilesProcess(IWorkbench workbench) { - super(workbench); - this.filesToOpen = new ArrayList(); - } - - /** - * - */ - public OpenFilesProcess(IWorkbench workbench, Collection files) { - super(workbench); - this.filesToOpen = new ArrayList(files); - } - - public void doCheckAndOpenFiles() { - filterFilesToOpen(filesToOpen); - - if (filesToOpen.isEmpty()) { - - } else { - addEditors(); - openEditors(true); - } - - onFilsOpened(); - } - - /** - * - */ - protected void onFilsOpened() { - if (markersImported) - showMarkersPrefPage(); - if (!commandFilesToOpen.isEmpty()) { - openXMindCommandFiles(); - } - } - - /** - * Filters the files to open. Subclasses may add/remove files to/from the - * `filesToOpen` list. - * - * @param monitor - */ - protected void filterFilesToOpen(List filesToOpen) { - } - - /** - * Add editors to open. - * - * @param monitor - */ - protected void addEditors() { - for (final String fileName : filesToOpen) { - SafeRunner.run(new SafeRunnable(NLS.bind( - WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, - fileName)) { - public void run() throws Exception { - IEditorInput input = createEditorInput(fileName); - if (input != null) { - addEditorToOpen(input); - } - } - }); - } - } - - /** - * Create an editor input from the file, or do anything to open the file. - * - * @param fileName - * @param monitor - * @return - * @throws Exception - */ - protected IEditorInput createEditorInput(String fileName) throws Exception { - final ICommand command = Command.parseURI(fileName); - if (command != null) { - new CommandJob(command, null).schedule(); - return null; - } - - final String path = fileName; - String extension = FileUtils.getExtension(path); - - if (CathyPlugin.COMMAND_FILE_EXT.equalsIgnoreCase(extension)) { - return openXMindCommandFile(path); - } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { - return newFromTemplate(path, fileName); - } else if (".mmap".equalsIgnoreCase(extension)) { //$NON-NLS-1$ - return importMindManagerFile(path, fileName); - } else if (".mm".equalsIgnoreCase(extension)) { //$NON-NLS-1$ - return importFreeMindFile(path, fileName); - } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE - .equalsIgnoreCase(extension)) { - return importMarkers(path); - } else { - // assumes we're opening xmind files - return MindMapUI.getEditorInputFactory() - .createEditorInputForFile(new File(path)); - } - } - - protected IEditorInput newFromTemplate(String path, String fileName) - throws Exception { - IWorkbookRef ref = ClonedWorkbookRef - .createFromSourceWorkbookURI(new File(path).toURI()); - return MindMapUI.getEditorInputFactory().createEditorInput(ref); - } - - protected IEditorInput importMindManagerFile(String path, String fileName) - throws Exception { - MindMapImporter importer = new MindManagerImporter(path); - importer.build(); - IWorkbook workbook = importer.getTargetWorkbook(); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - - protected IEditorInput importFreeMindFile(String path, String fileName) - throws Exception { - FreeMindImporter importer = new FreeMindImporter(path); - importer.build(); - IWorkbook workbook = importer.getTargetWorkbook(); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - - protected IEditorInput importMarkers(String path) throws Exception { - MarkerImpExpUtils.importMarkerPackage(path); - markersImported = true; - return null; - } - - private void showMarkersPrefPage() { - Display display = getWorkbench().getDisplay(); - if (display == null || display.isDisposed()) - return; - - display.asyncExec(new Runnable() { - public void run() { - PrefUtils.openPrefDialog(null, MarkerManagerPrefPage.ID); - } - }); - } - - private IEditorInput openXMindCommandFile(String path) { - commandFilesToOpen.add(path); - return null; - } - - private void openXMindCommandFiles() { - for (String path : commandFilesToOpen) { - new OpenXMindCommandFileJob(path).schedule(500); - } - } - -} +package org.xmind.cathy.internal; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbench; +import org.xmind.cathy.internal.jobs.OpenXMindCommandFileJob; +import org.xmind.core.IWorkbook; +import org.xmind.core.command.Command; +import org.xmind.core.command.CommandJob; +import org.xmind.core.command.ICommand; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.MarkerImpExpUtils; +import org.xmind.ui.internal.editor.ClonedWorkbookRef; +import org.xmind.ui.internal.imports.freemind.FreeMindImporter; +import org.xmind.ui.internal.imports.mm.MindManagerImporter; +import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.PrefUtils; +import org.xmind.ui.wizards.MindMapImporter; + +public class OpenFilesProcess extends AbstractCheckFilesProcess { + + private List filesToOpen; + + private boolean markersImported = false; + + private List commandFilesToOpen = new ArrayList(1); + + public OpenFilesProcess(IWorkbench workbench) { + super(workbench); + this.filesToOpen = new ArrayList(); + } + + /** + * + */ + public OpenFilesProcess(IWorkbench workbench, Collection files) { + super(workbench); + this.filesToOpen = new ArrayList(files); + } + + public void doCheckAndOpenFiles() { + filterFilesToOpen(filesToOpen); + + if (filesToOpen.isEmpty()) { + + } else { + addEditors(); + openEditors(true); + } + + onFilsOpened(); + } + + /** + * + */ + protected void onFilsOpened() { + if (markersImported) + showMarkersPrefPage(); + if (!commandFilesToOpen.isEmpty()) { + openXMindCommandFiles(); + } + } + + /** + * Filters the files to open. Subclasses may add/remove files to/from the + * `filesToOpen` list. + * + * @param monitor + */ + protected void filterFilesToOpen(List filesToOpen) { + } + + /** + * Add editors to open. + * + * @param monitor + */ + protected void addEditors() { + for (final String fileName : filesToOpen) { + SafeRunner.run(new SafeRunnable(NLS.bind( + WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, + fileName)) { + public void run() throws Exception { + IEditorInput input = createEditorInput(fileName); + if (input != null) { + addEditorToOpen(input); + } + } + }); + } + } + + /** + * Create an editor input from the file, or do anything to open the file. + * + * @param fileName + * @param monitor + * @return + * @throws Exception + */ + protected IEditorInput createEditorInput(String fileName) throws Exception { + final ICommand command = Command.parseURI(fileName); + if (command != null) { + new CommandJob(command, null).schedule(); + return null; + } + + final String path = fileName; + String extension = FileUtils.getExtension(path); + + if (CathyPlugin.COMMAND_FILE_EXT.equalsIgnoreCase(extension)) { + return openXMindCommandFile(path); + } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { + return newFromTemplate(path, fileName); + } else if (".mmap".equalsIgnoreCase(extension)) { //$NON-NLS-1$ + return importMindManagerFile(path, fileName); + } else if (".mm".equalsIgnoreCase(extension)) { //$NON-NLS-1$ + return importFreeMindFile(path, fileName); + } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE + .equalsIgnoreCase(extension)) { + return importMarkers(path); + } else { + // assumes we're opening xmind files + return MindMapUI.getEditorInputFactory() + .createEditorInputForFile(new File(path)); + } + } + + protected IEditorInput newFromTemplate(String path, String fileName) + throws Exception { + IWorkbookRef ref = ClonedWorkbookRef + .createFromSourceWorkbookURI(new File(path).toURI()); + return MindMapUI.getEditorInputFactory().createEditorInput(ref); + } + + protected IEditorInput importMindManagerFile(String path, String fileName) + throws Exception { + MindMapImporter importer = new MindManagerImporter(path); + importer.build(); + IWorkbook workbook = importer.getTargetWorkbook(); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + + protected IEditorInput importFreeMindFile(String path, String fileName) + throws Exception { + FreeMindImporter importer = new FreeMindImporter(path); + importer.build(); + IWorkbook workbook = importer.getTargetWorkbook(); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + + protected IEditorInput importMarkers(String path) throws Exception { + MarkerImpExpUtils.importMarkerPackage(path); + markersImported = true; + return null; + } + + private void showMarkersPrefPage() { + Display display = getWorkbench().getDisplay(); + if (display == null || display.isDisposed()) + return; + + display.asyncExec(new Runnable() { + public void run() { + PrefUtils.openPrefDialog(null, MarkerManagerPrefPage.ID); + } + }); + } + + private IEditorInput openXMindCommandFile(String path) { + commandFilesToOpen.add(path); + return null; + } + + private void openXMindCommandFiles() { + for (String path : commandFilesToOpen) { + new OpenXMindCommandFileJob(path).schedule(500); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilePropertyTester.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilePropertyTester.java index c0c8803e5..a609e91b2 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilePropertyTester.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilePropertyTester.java @@ -1,40 +1,40 @@ -package org.xmind.cathy.internal; - -import java.net.URI; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.editor.IEditorHistory; - -public class RecentFilePropertyTester extends PropertyTester { - - private static final String P_ISPINNED = "isPinned"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof URI); - IEditorHistory editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - Assert.isLegal(editorHistory != null); - return testTag(editorHistory, (URI) receiver, property, expectedValue); - } - - private boolean testTag(IEditorHistory editorHistory, URI receiver, - String property, Object expectedValue) { - if (P_ISPINNED.equals(property)) { - boolean actualValue = editorHistory.isPinned(receiver); - if (expectedValue == null || "".equals(expectedValue)) { //$NON-NLS-1$ - return actualValue; - } else if (expectedValue instanceof Boolean) { - return ((Boolean) expectedValue) == actualValue; - } else if (expectedValue instanceof String) { - return Boolean - .parseBoolean((String) expectedValue) == actualValue; - } - } - Assert.isLegal(false, "Unrecognized value: " + expectedValue); //$NON-NLS-1$ - return false; - } - -} +package org.xmind.cathy.internal; + +import java.net.URI; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.editor.IEditorHistory; + +public class RecentFilePropertyTester extends PropertyTester { + + private static final String P_ISPINNED = "isPinned"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof URI); + IEditorHistory editorHistory = PlatformUI.getWorkbench() + .getService(IEditorHistory.class); + Assert.isLegal(editorHistory != null); + return testTag(editorHistory, (URI) receiver, property, expectedValue); + } + + private boolean testTag(IEditorHistory editorHistory, URI receiver, + String property, Object expectedValue) { + if (P_ISPINNED.equals(property)) { + boolean actualValue = editorHistory.isPinned(receiver); + if (expectedValue == null || "".equals(expectedValue)) { //$NON-NLS-1$ + return actualValue; + } else if (expectedValue instanceof Boolean) { + return ((Boolean) expectedValue) == actualValue; + } else if (expectedValue instanceof String) { + return Boolean + .parseBoolean((String) expectedValue) == actualValue; + } + } + Assert.isLegal(false, "Unrecognized value: " + expectedValue); //$NON-NLS-1$ + return false; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilesPreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilesPreferencePageSection.java index ace785d33..8484a9a91 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilesPreferencePageSection.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilesPreferencePageSection.java @@ -1,68 +1,68 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.preference.ComboFieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.ui.preference.PreferenceFieldEditorPageSection; - -public class RecentFilesPreferencePageSection extends - PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { - - private String[][] filesList = new String[][] { { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ - { "20", "20" }, //$NON-NLS-1$ //$NON-NLS-2$ - { "50", "50" } }; //$NON-NLS-1$//$NON-NLS-2$ - - private Composite container; - private ComboFieldEditor recentFilesField; - - @Override - protected Control createContents(Composite parent) { - if (null == container) - this.container = parent; - return super.createContents(parent); - } - - @Override - protected void createFieldEditors() { - addRecentFileCountSection(container); - this.initialize(); - } - - protected IPreferenceStore doGetPreferenceStore() { - return CathyPlugin.getDefault().getPreferenceStore(); - } - - private void addRecentFileCountSection(Composite parent) { - - Composite container = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().indent(25, 0).applyTo(container); - GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container); - - addField(recentFilesField = new ComboFieldEditor( - IPreferenceConstants.RECENT_FILES, - WorkbenchMessages.RecentFiles_label, filesList, container)); - } - - @Override - protected void initialize() { - recentFilesField.setPreferenceStore( - WorkbenchPlugin.getDefault().getPreferenceStore()); - recentFilesField.load(); - } - - @Override - public void init(IWorkbench workbench) { -// WorkbenchPlugin.getDefault().getPreferenceStore().setDefault( -// IPreferenceConstants.RECENT_FILES, DEFAULT_RECENT_VALUE); - super.init(workbench); - } - -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; + +public class RecentFilesPreferencePageSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private String[][] filesList = new String[][] { { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ + { "20", "20" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "50", "50" } }; //$NON-NLS-1$//$NON-NLS-2$ + + private Composite container; + private ComboFieldEditor recentFilesField; + + @Override + protected Control createContents(Composite parent) { + if (null == container) + this.container = parent; + return super.createContents(parent); + } + + @Override + protected void createFieldEditors() { + addRecentFileCountSection(container); + this.initialize(); + } + + protected IPreferenceStore doGetPreferenceStore() { + return CathyPlugin.getDefault().getPreferenceStore(); + } + + private void addRecentFileCountSection(Composite parent) { + + Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().indent(25, 0).applyTo(container); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container); + + addField(recentFilesField = new ComboFieldEditor( + IPreferenceConstants.RECENT_FILES, + WorkbenchMessages.RecentFiles_label, filesList, container)); + } + + @Override + protected void initialize() { + recentFilesField.setPreferenceStore( + WorkbenchPlugin.getDefault().getPreferenceStore()); + recentFilesField.load(); + } + + @Override + public void init(IWorkbench workbench) { +// WorkbenchPlugin.getDefault().getPreferenceStore().setDefault( +// IPreferenceConstants.RECENT_FILES, DEFAULT_RECENT_VALUE); + super.init(workbench); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveBackupPreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveBackupPreferencePageSection.java index 8940d08f1..4559ae49c 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveBackupPreferencePageSection.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveBackupPreferencePageSection.java @@ -1,131 +1,131 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.ComboFieldEditor; -import org.eclipse.jface.preference.FieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.preference.PreferenceFieldEditorPageSection; -import org.xmind.ui.prefs.PrefConstants; - -public class SaveBackupPreferencePageSection extends - PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { - - private String[][] saveIntervals = new String[][] { { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ - { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ - { "30", "30" }, { "60", "60" } }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ - - private Composite container; - - private FieldEditor autoSaveInterval; - - private boolean autoBackup = true; - - private BooleanFieldEditor autoBackupField; - - private Composite autoSaveIntervalsParent; - - @Override - protected Control createContents(Composite parent) { - if (null == container) - this.container = parent; - return super.createContents(parent); - } - - protected IPreferenceStore doGetPreferenceStore() { - return CathyPlugin.getDefault().getPreferenceStore(); - } - - @Override - protected void initialize() { - super.initialize(); - autoBackupField.setPreferenceStore( - MindMapUIPlugin.getDefault().getPreferenceStore()); - autoBackupField.load(); - } - - @Override - protected void createFieldEditors() { - addAutoSaveGroup(container); - this.initialize(); - } - - private void addAutoSaveGroup(Composite parent) { - String message = WorkbenchMessages.AutoSave_label2; - int index = message.indexOf("{0}"); //$NON-NLS-1$ - String label1, label2; - label1 = message.substring(0, index); - label2 = message.substring(index + 3); - if (null != saveIntervals) { - for (String[] interval : saveIntervals) { - interval[0] += " " + label2; //$NON-NLS-1$ - } - } - - Composite container = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().applyTo(container); - GridLayoutFactory.fillDefaults().extendedMargins(23, 0, 0, 0) - .applyTo(container); - - Composite saveParent = createContainer(container, 2); - Composite enableParent = createContainer(saveParent, 1); - addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, - enableParent)); - - autoSaveIntervalsParent = createContainer(saveParent, 1); - autoSaveInterval = new ComboFieldEditor(CathyPlugin.AUTO_SAVE_INTERVALS, - "", saveIntervals, autoSaveIntervalsParent); //$NON-NLS-1$ - addField(autoSaveInterval); - - autoSaveInterval.setEnabled( - getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), - autoSaveIntervalsParent); - - Composite boolParent = createContainer(container, 1); - autoBackupField = new BooleanFieldEditor( - PrefConstants.AUTO_BACKUP_ENABLE, - WorkbenchMessages.AutoBackup_label, boolParent); - autoBackupField.setPropertyChangeListener(this); - - } - - private Composite createContainer(Composite parent, int cols) { - Composite container = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().applyTo(container); - GridLayoutFactory.fillDefaults().numColumns(cols).applyTo(container); - - return container; - } - - public void propertyChange(PropertyChangeEvent event) { - if (event.getSource() instanceof FieldEditor) { - FieldEditor fe = (FieldEditor) event.getSource(); - if (event.getProperty().equals(FieldEditor.VALUE)) { - String prefName = fe.getPreferenceName(); - if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { - autoSaveInterval.setEnabled( - ((Boolean) event.getNewValue()).booleanValue(), - autoSaveIntervalsParent); - } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { - autoBackup = ((Boolean) event.getNewValue()).booleanValue(); - } - } - } - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - MindMapUIPlugin.getDefault().getPreferenceStore() - .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); - return true; - } -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.prefs.PrefConstants; + +public class SaveBackupPreferencePageSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private String[][] saveIntervals = new String[][] { { "5", "5" }, //$NON-NLS-1$//$NON-NLS-2$ + { "10", "10" }, //$NON-NLS-1$//$NON-NLS-2$ + { "30", "30" }, { "60", "60" } }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ + + private Composite container; + + private FieldEditor autoSaveInterval; + + private boolean autoBackup = true; + + private BooleanFieldEditor autoBackupField; + + private Composite autoSaveIntervalsParent; + + @Override + protected Control createContents(Composite parent) { + if (null == container) + this.container = parent; + return super.createContents(parent); + } + + protected IPreferenceStore doGetPreferenceStore() { + return CathyPlugin.getDefault().getPreferenceStore(); + } + + @Override + protected void initialize() { + super.initialize(); + autoBackupField.setPreferenceStore( + MindMapUIPlugin.getDefault().getPreferenceStore()); + autoBackupField.load(); + } + + @Override + protected void createFieldEditors() { + addAutoSaveGroup(container); + this.initialize(); + } + + private void addAutoSaveGroup(Composite parent) { + String message = WorkbenchMessages.AutoSave_label2; + int index = message.indexOf("{0}"); //$NON-NLS-1$ + String label1, label2; + label1 = message.substring(0, index); + label2 = message.substring(index + 3); + if (null != saveIntervals) { + for (String[] interval : saveIntervals) { + interval[0] += " " + label2; //$NON-NLS-1$ + } + } + + Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(container); + GridLayoutFactory.fillDefaults().extendedMargins(23, 0, 0, 0) + .applyTo(container); + + Composite saveParent = createContainer(container, 2); + Composite enableParent = createContainer(saveParent, 1); + addField(new BooleanFieldEditor(CathyPlugin.AUTO_SAVE_ENABLED, label1, + enableParent)); + + autoSaveIntervalsParent = createContainer(saveParent, 1); + autoSaveInterval = new ComboFieldEditor(CathyPlugin.AUTO_SAVE_INTERVALS, + "", saveIntervals, autoSaveIntervalsParent); //$NON-NLS-1$ + addField(autoSaveInterval); + + autoSaveInterval.setEnabled( + getPreferenceStore().getBoolean(CathyPlugin.AUTO_SAVE_ENABLED), + autoSaveIntervalsParent); + + Composite boolParent = createContainer(container, 1); + autoBackupField = new BooleanFieldEditor( + PrefConstants.AUTO_BACKUP_ENABLE, + WorkbenchMessages.AutoBackup_label, boolParent); + autoBackupField.setPropertyChangeListener(this); + + } + + private Composite createContainer(Composite parent, int cols) { + Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(container); + GridLayoutFactory.fillDefaults().numColumns(cols).applyTo(container); + + return container; + } + + public void propertyChange(PropertyChangeEvent event) { + if (event.getSource() instanceof FieldEditor) { + FieldEditor fe = (FieldEditor) event.getSource(); + if (event.getProperty().equals(FieldEditor.VALUE)) { + String prefName = fe.getPreferenceName(); + if (CathyPlugin.AUTO_SAVE_ENABLED.equals(prefName)) { + autoSaveInterval.setEnabled( + ((Boolean) event.getNewValue()).booleanValue(), + autoSaveIntervalsParent); + } else if (PrefConstants.AUTO_BACKUP_ENABLE.equals(prefName)) { + autoBackup = ((Boolean) event.getNewValue()).booleanValue(); + } + } + } + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + MindMapUIPlugin.getDefault().getPreferenceStore() + .setValue(PrefConstants.AUTO_BACKUP_ENABLE, autoBackup); + return true; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveCommandLabelUpdater.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveCommandLabelUpdater.java index 3a821a1f8..b26cd53c7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveCommandLabelUpdater.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveCommandLabelUpdater.java @@ -1,262 +1,262 @@ - -package org.xmind.cathy.internal; - -import javax.inject.Inject; - -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.di.extensions.EventTopic; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MItem; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.osgi.service.event.Event; -import org.xmind.core.Core; -import org.xmind.core.IMeta; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.ui.internal.MindMapMessages; - -public class SaveCommandLabelUpdater - implements IPartListener, IPropertyListener, ICoreEventListener { - - private static final String DATA_ORIGINAL_TEXT = "SaveCommandLabelUpdater:OriginalText"; //$NON-NLS-1$ - private static final String DATA_ORIGINAL_TOOLTIP = "SaveCommandLabelUpdater:OriginalTooltip"; //$NON-NLS-1$ - - @Inject - private EModelService modelService; - - @Inject - private Display display; - - private MWindow activeWindow = null; - private IEditorPart activeEditor = null; - private IWorkbook editingWorkbook = null; - private ICoreEventRegistration metadataEventRegistration = null; - - private void updateSaveCommandLabel() { - if (this.activeWindow == null) - return; - - String text; - String tooltip; - if (this.editingWorkbook != null - && isAutoGeneratingRevision(this.editingWorkbook)) { - text = MindMapMessages.SaveNewRevision_text; - tooltip = MindMapMessages.SaveNewRevision_tooltip; - } else { - text = null; - tooltip = null; - } - - MItem item = findItem(this.activeWindow.getMainMenu(), - ICathyConstants.ID_MENU_ITEM_SAVE); - if (item != null) { - if (text == null) { - if (item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { - item.setLabel((String) item.getTransientData() - .get(DATA_ORIGINAL_TEXT)); - } - } else { - if (!item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { - item.getTransientData().put(DATA_ORIGINAL_TEXT, - item.getLabel()); - } - item.setLabel(text); - } - } - - item = findItem(this.activeWindow, ICathyConstants.ID_TOOL_ITEM_SAVE); - if (item != null) { - if (tooltip == null) { - if (item.getTransientData() - .containsKey(DATA_ORIGINAL_TOOLTIP)) { - item.setTooltip((String) item.getTransientData() - .get(DATA_ORIGINAL_TOOLTIP)); - } - } else { - if (!item.getTransientData() - .containsKey(DATA_ORIGINAL_TOOLTIP)) { - item.getTransientData().put(DATA_ORIGINAL_TOOLTIP, - item.getTooltip()); - } - item.setTooltip(tooltip); - } - } - } - - @Inject - @Optional - public void applicationStarted( - @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event, - @Optional final MApplication app) { - if (app == null) - return; - - if (display == null || display.isDisposed()) - return; - - display.syncExec(new Runnable() { - public void run() { - MWindow window = app.getSelectedElement(); - setActiveWindow(window); - updateSaveCommandLabel(); - } - }); - } - - @Inject - @Optional - public void windowChanged( - @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { - Object selectedElement = event - .getProperty(UIEvents.ElementContainer.SELECTEDELEMENT); - if (!(selectedElement instanceof MWindow)) - return; - - setActiveWindow((MWindow) selectedElement); - updateSaveCommandLabel(); - } - - public void partActivated(IWorkbenchPart part) { - setActiveEditor(findActiveEditorFrom(part)); - updateSaveCommandLabel(); - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - setActiveEditor(findActiveEditorFrom(part)); - updateSaveCommandLabel(); - } - - public void partDeactivated(IWorkbenchPart part) { - } - - public void partOpened(IWorkbenchPart part) { - } - - public void propertyChanged(Object source, int propId) { - if (propId == IEditorPart.PROP_INPUT) { - setEditingWorkbook(findWorkbookIn(this.activeEditor)); - updateSaveCommandLabel(); - } - } - - public void handleCoreEvent(CoreEvent event) { - if (IMeta.CONFIG_AUTO_REVISION_GENERATION.equals(event.getTarget())) { - if (display != null) { - display.syncExec(new Runnable() { - public void run() { - updateSaveCommandLabel(); - } - }); - } - } - } - - private void setActiveWindow(MWindow window) { - if (window != this.activeWindow) { - if (this.activeWindow != null) { - IWorkbenchWindow wbWindow = this.activeWindow.getContext() - .get(IWorkbenchWindow.class); - if (wbWindow != null) - wbWindow.getPartService().removePartListener(this); - } - this.activeWindow = window; - if (this.activeWindow != null) { - IWorkbenchWindow wbWindow = this.activeWindow.getContext() - .get(IWorkbenchWindow.class); - if (wbWindow != null) - wbWindow.getPartService().addPartListener(this); - } - } - setActiveEditor(findActiveEditorIn(this.activeWindow)); - } - - private void setActiveEditor(IEditorPart editor) { - if (editor != this.activeEditor) { - if (this.activeEditor != null) - this.activeEditor.removePropertyListener(this); - this.activeEditor = editor; - if (this.activeEditor != null) - this.activeEditor.addPropertyListener(this); - } - setEditingWorkbook(findWorkbookIn(editor)); - } - - private void setEditingWorkbook(IWorkbook workbook) { - if (workbook != this.editingWorkbook) { - if (this.metadataEventRegistration != null) { - this.metadataEventRegistration.unregister(); - this.metadataEventRegistration = null; - } - this.editingWorkbook = workbook; - if (this.editingWorkbook != null && this.editingWorkbook - .getMeta() instanceof ICoreEventSource) { - this.metadataEventRegistration = ((ICoreEventSource) this.editingWorkbook - .getMeta()).registerCoreEventListener(Core.Metadata, - this); - } - } - } - - private IEditorPart findActiveEditorFrom(IWorkbenchPart referencePart) { - if (referencePart == null) - return null; - - IWorkbenchWindow window = referencePart.getSite().getWorkbenchWindow(); - return findActiveEditorIn(window); - } - - private IEditorPart findActiveEditorIn(MWindow window) { - if (window == null) - return null; - IWorkbenchWindow wbWindow = window.getContext() - .get(IWorkbenchWindow.class); - return findActiveEditorIn(wbWindow); - } - - private IEditorPart findActiveEditorIn(IWorkbenchWindow window) { - if (window == null) - return null; - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return null; - return page.getActiveEditor(); - } - - private IWorkbook findWorkbookIn(IEditorPart editor) { - if (editor == null) - return null; - return editor.getAdapter(IWorkbook.class); - } - - private MItem findItem(MUIElement rootElement, String id) { - if (this.modelService == null || rootElement == null) - return null; - MUIElement element = this.modelService.find(id, rootElement); - if (!(element instanceof MItem)) - return null; - return (MItem) element; - } - - private static final boolean isAutoGeneratingRevision(IWorkbook workbook) { - String value = workbook.getMeta() - .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); - return value == null || IMeta.V_YES.equalsIgnoreCase(value); - } - -} + +package org.xmind.cathy.internal; + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.di.extensions.EventTopic; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MItem; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.osgi.service.event.Event; +import org.xmind.core.Core; +import org.xmind.core.IMeta; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.ui.internal.MindMapMessages; + +public class SaveCommandLabelUpdater + implements IPartListener, IPropertyListener, ICoreEventListener { + + private static final String DATA_ORIGINAL_TEXT = "SaveCommandLabelUpdater:OriginalText"; //$NON-NLS-1$ + private static final String DATA_ORIGINAL_TOOLTIP = "SaveCommandLabelUpdater:OriginalTooltip"; //$NON-NLS-1$ + + @Inject + private EModelService modelService; + + @Inject + private Display display; + + private MWindow activeWindow = null; + private IEditorPart activeEditor = null; + private IWorkbook editingWorkbook = null; + private ICoreEventRegistration metadataEventRegistration = null; + + private void updateSaveCommandLabel() { + if (this.activeWindow == null) + return; + + String text; + String tooltip; + if (this.editingWorkbook != null + && isAutoGeneratingRevision(this.editingWorkbook)) { + text = MindMapMessages.SaveNewRevision_text; + tooltip = MindMapMessages.SaveNewRevision_tooltip; + } else { + text = null; + tooltip = null; + } + + MItem item = findItem(this.activeWindow.getMainMenu(), + ICathyConstants.ID_MENU_ITEM_SAVE); + if (item != null) { + if (text == null) { + if (item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { + item.setLabel((String) item.getTransientData() + .get(DATA_ORIGINAL_TEXT)); + } + } else { + if (!item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) { + item.getTransientData().put(DATA_ORIGINAL_TEXT, + item.getLabel()); + } + item.setLabel(text); + } + } + + item = findItem(this.activeWindow, ICathyConstants.ID_TOOL_ITEM_SAVE); + if (item != null) { + if (tooltip == null) { + if (item.getTransientData() + .containsKey(DATA_ORIGINAL_TOOLTIP)) { + item.setTooltip((String) item.getTransientData() + .get(DATA_ORIGINAL_TOOLTIP)); + } + } else { + if (!item.getTransientData() + .containsKey(DATA_ORIGINAL_TOOLTIP)) { + item.getTransientData().put(DATA_ORIGINAL_TOOLTIP, + item.getTooltip()); + } + item.setTooltip(tooltip); + } + } + } + + @Inject + @Optional + public void applicationStarted( + @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event, + @Optional final MApplication app) { + if (app == null) + return; + + if (display == null || display.isDisposed()) + return; + + display.syncExec(new Runnable() { + public void run() { + MWindow window = app.getSelectedElement(); + setActiveWindow(window); + updateSaveCommandLabel(); + } + }); + } + + @Inject + @Optional + public void windowChanged( + @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { + Object selectedElement = event + .getProperty(UIEvents.ElementContainer.SELECTEDELEMENT); + if (!(selectedElement instanceof MWindow)) + return; + + setActiveWindow((MWindow) selectedElement); + updateSaveCommandLabel(); + } + + public void partActivated(IWorkbenchPart part) { + setActiveEditor(findActiveEditorFrom(part)); + updateSaveCommandLabel(); + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + setActiveEditor(findActiveEditorFrom(part)); + updateSaveCommandLabel(); + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + public void propertyChanged(Object source, int propId) { + if (propId == IEditorPart.PROP_INPUT) { + setEditingWorkbook(findWorkbookIn(this.activeEditor)); + updateSaveCommandLabel(); + } + } + + public void handleCoreEvent(CoreEvent event) { + if (IMeta.CONFIG_AUTO_REVISION_GENERATION.equals(event.getTarget())) { + if (display != null) { + display.syncExec(new Runnable() { + public void run() { + updateSaveCommandLabel(); + } + }); + } + } + } + + private void setActiveWindow(MWindow window) { + if (window != this.activeWindow) { + if (this.activeWindow != null) { + IWorkbenchWindow wbWindow = this.activeWindow.getContext() + .get(IWorkbenchWindow.class); + if (wbWindow != null) + wbWindow.getPartService().removePartListener(this); + } + this.activeWindow = window; + if (this.activeWindow != null) { + IWorkbenchWindow wbWindow = this.activeWindow.getContext() + .get(IWorkbenchWindow.class); + if (wbWindow != null) + wbWindow.getPartService().addPartListener(this); + } + } + setActiveEditor(findActiveEditorIn(this.activeWindow)); + } + + private void setActiveEditor(IEditorPart editor) { + if (editor != this.activeEditor) { + if (this.activeEditor != null) + this.activeEditor.removePropertyListener(this); + this.activeEditor = editor; + if (this.activeEditor != null) + this.activeEditor.addPropertyListener(this); + } + setEditingWorkbook(findWorkbookIn(editor)); + } + + private void setEditingWorkbook(IWorkbook workbook) { + if (workbook != this.editingWorkbook) { + if (this.metadataEventRegistration != null) { + this.metadataEventRegistration.unregister(); + this.metadataEventRegistration = null; + } + this.editingWorkbook = workbook; + if (this.editingWorkbook != null && this.editingWorkbook + .getMeta() instanceof ICoreEventSource) { + this.metadataEventRegistration = ((ICoreEventSource) this.editingWorkbook + .getMeta()).registerCoreEventListener(Core.Metadata, + this); + } + } + } + + private IEditorPart findActiveEditorFrom(IWorkbenchPart referencePart) { + if (referencePart == null) + return null; + + IWorkbenchWindow window = referencePart.getSite().getWorkbenchWindow(); + return findActiveEditorIn(window); + } + + private IEditorPart findActiveEditorIn(MWindow window) { + if (window == null) + return null; + IWorkbenchWindow wbWindow = window.getContext() + .get(IWorkbenchWindow.class); + return findActiveEditorIn(wbWindow); + } + + private IEditorPart findActiveEditorIn(IWorkbenchWindow window) { + if (window == null) + return null; + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return null; + return page.getActiveEditor(); + } + + private IWorkbook findWorkbookIn(IEditorPart editor) { + if (editor == null) + return null; + return editor.getAdapter(IWorkbook.class); + } + + private MItem findItem(MUIElement rootElement, String id) { + if (this.modelService == null || rootElement == null) + return null; + MUIElement element = this.modelService.find(id, rootElement); + if (!(element instanceof MItem)) + return null; + return (MItem) element; + } + + private static final boolean isAutoGeneratingRevision(IWorkbook workbook) { + String value = workbook.getMeta() + .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); + return value == null || IMeta.V_YES.equalsIgnoreCase(value); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ServiceManager.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ServiceManager.java index e90271e22..8e9db8c93 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ServiceManager.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ServiceManager.java @@ -1,125 +1,125 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.cathy.internal; - -import org.xmind.core.licensing.ILicenseAgent; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.ui.internal.statushandlers.IErrorReporter; - -/** - * @author Frank Shaka - * - */ -public class ServiceManager { - - private boolean active; - - private IErrorReporter errorReporter; - - private IUsageDataSampler usageDataSampler; - - private ILicenseAgent licenseAgent; - - private CathyPlugin plugin; - - /** - * - */ - public ServiceManager() { - this.active = false; - this.errorReporter = null; - this.usageDataSampler = null; - this.licenseAgent = null; - this.plugin = CathyPlugin.getDefault(); - } - - public void activate() { - if (active) - return; - - plugin.setUsageDataCollector(usageDataSampler); - plugin.setErrorReporter(errorReporter); - plugin.setLicenseAgent(licenseAgent); - - active = true; - } - - public void deactivate() { - if (!active) - return; - - plugin.setUsageDataCollector(null); - plugin.setErrorReporter(null); - plugin.setLicenseAgent(null); - - active = false; - } - - public void setErrorReporter(IErrorReporter reporter) { - this.errorReporter = reporter; - - if (active) { - plugin.setErrorReporter(reporter); - } - } - - public void unsetErrorReporter(IErrorReporter reporter) { - if (reporter != this.errorReporter) - return; - this.errorReporter = null; - if (active) { - plugin.setErrorReporter(null); - } - } - - /** - * @param sampler - * the usageDataSampler to set - */ - public void setUsageDataSampler(IUsageDataSampler sampler) { - this.usageDataSampler = sampler; - if (active) { - plugin.setUsageDataCollector(sampler); - } - } - - public void unsetUsageDataSampler(IUsageDataSampler sampler) { - if (sampler == this.usageDataSampler) - return; - this.usageDataSampler = null; - if (active) { - plugin.setUsageDataCollector(null); - } - } - - public void setLicenseAgent(ILicenseAgent agent) { - this.licenseAgent = agent; - if (active) { - plugin.setLicenseAgent(agent); - } - } - - public void unsetLicenseAgent(ILicenseAgent agent) { - if (agent == this.licenseAgent) - return; - this.licenseAgent = null; - if (active) { - plugin.setLicenseAgent(null); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.cathy.internal; + +import org.xmind.core.licensing.ILicenseAgent; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.ui.internal.statushandlers.IErrorReporter; + +/** + * @author Frank Shaka + * + */ +public class ServiceManager { + + private boolean active; + + private IErrorReporter errorReporter; + + private IUsageDataSampler usageDataSampler; + + private ILicenseAgent licenseAgent; + + private CathyPlugin plugin; + + /** + * + */ + public ServiceManager() { + this.active = false; + this.errorReporter = null; + this.usageDataSampler = null; + this.licenseAgent = null; + this.plugin = CathyPlugin.getDefault(); + } + + public void activate() { + if (active) + return; + + plugin.setUsageDataCollector(usageDataSampler); + plugin.setErrorReporter(errorReporter); + plugin.setLicenseAgent(licenseAgent); + + active = true; + } + + public void deactivate() { + if (!active) + return; + + plugin.setUsageDataCollector(null); + plugin.setErrorReporter(null); + plugin.setLicenseAgent(null); + + active = false; + } + + public void setErrorReporter(IErrorReporter reporter) { + this.errorReporter = reporter; + + if (active) { + plugin.setErrorReporter(reporter); + } + } + + public void unsetErrorReporter(IErrorReporter reporter) { + if (reporter != this.errorReporter) + return; + this.errorReporter = null; + if (active) { + plugin.setErrorReporter(null); + } + } + + /** + * @param sampler + * the usageDataSampler to set + */ + public void setUsageDataSampler(IUsageDataSampler sampler) { + this.usageDataSampler = sampler; + if (active) { + plugin.setUsageDataCollector(sampler); + } + } + + public void unsetUsageDataSampler(IUsageDataSampler sampler) { + if (sampler == this.usageDataSampler) + return; + this.usageDataSampler = null; + if (active) { + plugin.setUsageDataCollector(null); + } + } + + public void setLicenseAgent(ILicenseAgent agent) { + this.licenseAgent = agent; + if (active) { + plugin.setLicenseAgent(agent); + } + } + + public void unsetLicenseAgent(ILicenseAgent agent) { + if (agent == this.licenseAgent) + return; + this.licenseAgent = null; + if (active) { + plugin.setLicenseAgent(null); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ShowWelcomeService.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ShowWelcomeService.java index 17e38ab5c..4d5b8f4ce 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ShowWelcomeService.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ShowWelcomeService.java @@ -1,87 +1,87 @@ -package org.xmind.cathy.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; - -import org.eclipse.ui.IStartup; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.util.FileUtils; - -/** - * - * @author Shawn Liu - * @since 3.6.50 - */ -public class ShowWelcomeService implements IStartup { - - private static final boolean DEBUG_NOT_SHOW_WELCOME = CathyPlugin - .getDefault().isDebugging("/debug/notshowwelcome"); //$NON-NLS-1$ - - private static final String NO_FIRST_START = System - .getProperty("org.xmind.product.buildid") //$NON-NLS-1$ - + ".noFirstStart"; //$NON-NLS-1$ - - public void earlyStartup() { - if (DEBUG_NOT_SHOW_WELCOME) { - return; - } - - final File propertiesFile = new File(getPropertiesFilePath()); - if (!propertiesFile.exists()) { - FileUtils.ensureFileParent(propertiesFile); - try { - propertiesFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - final Properties properties = new Properties(); - try { - properties.load(new FileInputStream(propertiesFile)); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } catch (IOException e1) { - e1.printStackTrace(); - } - boolean isNotFirstStart = Boolean - .valueOf(properties.getProperty(NO_FIRST_START)); - - if (!isNotFirstStart) { - final IWorkbench workbench = PlatformUI.getWorkbench(); - workbench.getDisplay().asyncExec(new Runnable() { - public void run() { - IWorkbenchWindow window = workbench - .getActiveWorkbenchWindow(); - if (window != null) { - new WelcomeDialog(window.getShell()).open(); - - //set value to properties file. - properties.setProperty(NO_FIRST_START, - Boolean.toString(true)); - try { - properties.store( - new FileOutputStream(propertiesFile), null); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - }); - } - } - - private String getPropertiesFilePath() { - return CathyPlugin.getDefault().getStateLocation() - .append("start.properties").toString(); //$NON-NLS-1$ - } - -} +package org.xmind.cathy.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; + +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.util.FileUtils; + +/** + * + * @author Shawn Liu + * @since 3.6.50 + */ +public class ShowWelcomeService implements IStartup { + + private static final boolean DEBUG_NOT_SHOW_WELCOME = CathyPlugin + .getDefault().isDebugging("/debug/notshowwelcome"); //$NON-NLS-1$ + + private static final String NO_FIRST_START = System + .getProperty("org.xmind.product.buildid") //$NON-NLS-1$ + + ".noFirstStart"; //$NON-NLS-1$ + + public void earlyStartup() { + if (DEBUG_NOT_SHOW_WELCOME) { + return; + } + + final File propertiesFile = new File(getPropertiesFilePath()); + if (!propertiesFile.exists()) { + FileUtils.ensureFileParent(propertiesFile); + try { + propertiesFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + final Properties properties = new Properties(); + try { + properties.load(new FileInputStream(propertiesFile)); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } catch (IOException e1) { + e1.printStackTrace(); + } + boolean isNotFirstStart = Boolean + .valueOf(properties.getProperty(NO_FIRST_START)); + + if (!isNotFirstStart) { + final IWorkbench workbench = PlatformUI.getWorkbench(); + workbench.getDisplay().asyncExec(new Runnable() { + public void run() { + IWorkbenchWindow window = workbench + .getActiveWorkbenchWindow(); + if (window != null) { + new WelcomeDialog(window.getShell()).open(); + + //set value to properties file. + properties.setProperty(NO_FIRST_START, + Boolean.toString(true)); + try { + properties.store( + new FileOutputStream(propertiesFile), null); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }); + } + } + + private String getPropertiesFilePath() { + return CathyPlugin.getDefault().getStateLocation() + .append("start.properties").toString(); //$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartUpProcess.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartUpProcess.java index 8aea5b567..032d37cd7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartUpProcess.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartUpProcess.java @@ -1,210 +1,232 @@ -package org.xmind.cathy.internal; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.WorkbenchException; -import org.eclipse.ui.XMLMemento; -import org.eclipse.ui.internal.IWorkbenchConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.cathy.internal.dashboard.DashboardAutomationAddon; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; - -public class StartUpProcess { - - private static final boolean DEBUG_CHECK_OPEN_FILE = CathyPlugin - .getDefault().isDebugging("/debug/checkopenfile"); //$NON-NLS-1$ - - private IWorkbench workbench; - - public StartUpProcess(IWorkbench workbench) { - this.workbench = workbench; - } - - public void startUp() { - checkAndRecoverFiles(); - - if (DEBUG_CHECK_OPEN_FILE) { - checkAndOpenFiles(); - } else { - //delete file paths which need to open from command line - Log openFile = Log.get(Log.OPENING); - if (openFile.exists()) - openFile.delete(); - } - openStartupMap(); - - Display display = workbench.getDisplay(); - if (display != null && !display.isDisposed()) { - display.asyncExec(new Runnable() { - public void run() { - System.setProperty("org.xmind.cathy.app.status", //$NON-NLS-1$ - "workbenchReady"); //$NON-NLS-1$ - } - }); - } - } - - private void checkAndOpenFiles() { - new CheckOpenFilesProcess(workbench).doCheckAndOpenFiles(); - } - - private void checkAndRecoverFiles() { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - new EditorStatePersistance(workbench, - CathyPlugin.getDefault().getStateLocation(), - CathyPlugin.getDefault().getLogger(), - CathyPlugin.getDefault().getDebugValue( - CathyPlugin.OPTION_AUTO_SAVE_EDITOR_STATE_INTERVALS, - CathyPlugin.AUTO_SAVE_EDITOR_STATE_INTERVALS)) - .startUp(); - } - }); - } - - private void openStartupMap() { - if (!hasOpenedEditors()) { - int action = CathyPlugin.getDefault().getPreferenceStore() - .getInt(CathyPlugin.STARTUP_ACTION); - if (action == CathyPlugin.STARTUP_ACTION_LAST) { - doOpenLastSession(); - } - if (!hasOpenedEditors()) { - doOpenDashboard(); - } - } - } - - private void doOpenDashboard() { - final EModelService modelService = workbench - .getService(EModelService.class); - final MApplication application = workbench - .getService(MApplication.class); - if (modelService == null || application == null) - return; - - final DashboardAutomationAddon automator = new DashboardAutomationAddon(); - automator.setModelService(modelService); - automator.setApplication(application); - workbench.getDisplay().asyncExec(new Runnable() { - public void run() { - for (MWindow window : application.getChildren()) { - automator.showDashboard(window); - } - } - }); - } - - private void doOpenLastSession() { - IPath editorStatusPath = WorkbenchPlugin.getDefault().getDataLocation() - .append("XMind_Editors.xml"); //$NON-NLS-1$ - //open unclosed editors in the last session. - final File stateFile = editorStatusPath.toFile(); - if (stateFile.exists()) - workbench.getDisplay().syncExec(new Runnable() { - public void run() { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IWorkbenchWindow window = workbench - .getActiveWorkbenchWindow(); - if (window != null) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - openUnclosedMapLastSession(stateFile, page); - } - } - } - }); - } - }); - } - - private void openUnclosedMapLastSession(File statusFile, - final IWorkbenchPage page) - throws FileNotFoundException, UnsupportedEncodingException, - WorkbenchException, CoreException, PartInitException { - FileInputStream input = new FileInputStream(statusFile); - BufferedReader reader = new BufferedReader( - new InputStreamReader(input, "utf-8")); //$NON-NLS-1$ - IMemento memento = XMLMemento.createReadRoot(reader); - IMemento childMem = memento.getChild(IWorkbenchConstants.TAG_EDITORS); - IMemento[] childrenEditor = childMem - .getChildren(IWorkbenchConstants.TAG_EDITOR); - IEditorPart activeEditorPart = null; - for (IMemento childEditor : childrenEditor) { - IMemento inputMemeto = childEditor.getChild("input"); //$NON-NLS-1$ - if (inputMemeto == null) - continue; - - String uri = inputMemeto.getString("uri"); //$NON-NLS-1$ - if (uri != null) { - IWorkbookRef workbookRef = null; - try { - workbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory() - .createWorkbookRef(new URI(uri), null); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - if (workbookRef != null) { - IEditorInput editorInput = MindMapUI.getEditorInputFactory() - .createEditorInput(workbookRef); - IEditorPart editorPart = page.openEditor(editorInput, - MindMapUI.MINDMAP_EDITOR_ID); - if ("true".equals(childEditor //$NON-NLS-1$ - .getString(IWorkbenchConstants.TAG_ACTIVE_PART))) { - activeEditorPart = editorPart; - } - } - } - } - if (activeEditorPart != null) { - page.activate(activeEditorPart); - } - } - - private boolean hasOpenedEditors() { - final boolean[] ret = new boolean[1]; - ret[0] = false; - workbench.getDisplay().syncExec(new Runnable() { - public void run() { - for (IWorkbenchWindow window : workbench - .getWorkbenchWindows()) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - if (page.getEditorReferences().length > 0) { - ret[0] = true; - return; - } - } - } - } - }); - return ret[0]; - } - -} +package org.xmind.cathy.internal; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.XMLMemento; +import org.eclipse.ui.internal.IWorkbenchConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.cathy.internal.dashboard.DashboardAutomationAddon; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; + +public class StartUpProcess { + + private static final boolean DEBUG_CHECK_OPEN_FILE = CathyPlugin + .getDefault().isDebugging("/debug/checkopenfile"); //$NON-NLS-1$ + + private IWorkbench workbench; + + public StartUpProcess(IWorkbench workbench) { + this.workbench = workbench; + } + + public void startUp() { + checkAndRecoverFiles(); + + if (DEBUG_CHECK_OPEN_FILE) { + checkAndOpenFiles(); + } else { + //delete file paths which need to open from command line + Log openFile = Log.get(Log.OPENING); + if (openFile.exists()) + openFile.delete(); + } + openStartupMap(); + + Display display = workbench.getDisplay(); + if (display != null && !display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + System.setProperty("org.xmind.cathy.app.status", //$NON-NLS-1$ + "workbenchReady"); //$NON-NLS-1$ + } + }); + } + } + + private void checkAndOpenFiles() { + new CheckOpenFilesProcess(workbench).doCheckAndOpenFiles(); + } + + private void checkAndRecoverFiles() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + new EditorStatePersistance(workbench, + CathyPlugin.getDefault().getStateLocation(), + CathyPlugin.getDefault().getLogger(), + CathyPlugin.getDefault().getDebugValue( + CathyPlugin.OPTION_AUTO_SAVE_EDITOR_STATE_INTERVALS, + CathyPlugin.AUTO_SAVE_EDITOR_STATE_INTERVALS)) + .startUp(); + } + }); + } + + private void openStartupMap() { + if (!hasOpenedEditors()) { + int action = CathyPlugin.getDefault().getPreferenceStore() + .getInt(CathyPlugin.STARTUP_ACTION); + if (action == CathyPlugin.STARTUP_ACTION_LAST) { + doOpenLastSession(); + } + if (!hasOpenedEditors()) { +// doOpenDashboard(); + closeOpenedDashboard(); + } + } + } + + private void doOpenDashboard() { + final EModelService modelService = workbench + .getService(EModelService.class); + final MApplication application = workbench + .getService(MApplication.class); + if (modelService == null || application == null) + return; + + final DashboardAutomationAddon automator = new DashboardAutomationAddon(); + automator.setModelService(modelService); + automator.setApplication(application); + workbench.getDisplay().asyncExec(new Runnable() { + public void run() { + for (MWindow window : application.getChildren()) { + automator.showDashboard(window); + } + } + }); + } + + private void closeOpenedDashboard() { + final EModelService modelService = workbench + .getService(EModelService.class); + final MApplication application = workbench + .getService(MApplication.class); + if (modelService == null || application == null) + return; + + workbench.getDisplay().asyncExec(new Runnable() { + public void run() { + for (MWindow window : application.getChildren()) { + if (window.getTags() + .contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags() + .remove(ICathyConstants.TAG_SHOW_DASHBOARD); + } + } + } + }); + } + + private void doOpenLastSession() { + IPath editorStatusPath = WorkbenchPlugin.getDefault().getDataLocation() + .append("XMind_Editors.xml"); //$NON-NLS-1$ + //open unclosed editors in the last session. + final File stateFile = editorStatusPath.toFile(); + if (stateFile.exists()) + workbench.getDisplay().syncExec(new Runnable() { + public void run() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IWorkbenchWindow window = workbench + .getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + openUnclosedMapLastSession(stateFile, page); + } + } + } + }); + } + }); + } + + private void openUnclosedMapLastSession(File statusFile, + final IWorkbenchPage page) + throws FileNotFoundException, UnsupportedEncodingException, + WorkbenchException, CoreException, PartInitException { + FileInputStream input = new FileInputStream(statusFile); + BufferedReader reader = new BufferedReader( + new InputStreamReader(input, "utf-8")); //$NON-NLS-1$ + IMemento memento = XMLMemento.createReadRoot(reader); + IMemento childMem = memento.getChild(IWorkbenchConstants.TAG_EDITORS); + IMemento[] childrenEditor = childMem + .getChildren(IWorkbenchConstants.TAG_EDITOR); + IEditorPart activeEditorPart = null; + for (IMemento childEditor : childrenEditor) { + IMemento inputMemeto = childEditor.getChild("input"); //$NON-NLS-1$ + if (inputMemeto == null) + continue; + + String uri = inputMemeto.getString("uri"); //$NON-NLS-1$ + if (uri != null) { + IWorkbookRef workbookRef = null; + try { + workbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(new URI(uri), null); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + if (workbookRef != null) { + IEditorInput editorInput = MindMapUI.getEditorInputFactory() + .createEditorInput(workbookRef); + IEditorPart editorPart = page.openEditor(editorInput, + MindMapUI.MINDMAP_EDITOR_ID); + if ("true".equals(childEditor //$NON-NLS-1$ + .getString(IWorkbenchConstants.TAG_ACTIVE_PART))) { + activeEditorPart = editorPart; + } + } + } + } + if (activeEditorPart != null) { + page.activate(activeEditorPart); + } + } + + private boolean hasOpenedEditors() { + final boolean[] ret = new boolean[1]; + ret[0] = false; + workbench.getDisplay().syncExec(new Runnable() { + public void run() { + for (IWorkbenchWindow window : workbench + .getWorkbenchWindows()) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + if (page.getEditorReferences().length > 0) { + ret[0] = true; + return; + } + } + } + } + }); + return ret[0]; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartupPreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartupPreferencePageSection.java index 124015a71..ceb0585fd 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartupPreferencePageSection.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartupPreferencePageSection.java @@ -1,149 +1,149 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.core.usagedata.IUsageDataUploader; -import org.xmind.ui.preference.PreferenceFieldEditorPageSection; -import org.xmind.ui.resources.ColorUtils; - -public class StartupPreferencePageSection extends - PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { - - private Composite container; - private Button startupActionButton; - - private LocalResourceManager resources; - - @Override - protected Control createContents(Composite parent) { - if (null == container) - this.container = parent; - return super.createContents(parent); - } - - protected IPreferenceStore doGetPreferenceStore() { - return CathyPlugin.getDefault().getPreferenceStore(); - } - - @Override - protected void initialize() { - super.initialize(); - int startupAction = getPreferenceStore() - .getInt(CathyPlugin.STARTUP_ACTION); - startupActionButton - .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); - } - - @Override - public void createControl(Composite parent) { - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - super.createControl(parent); - } - - @Override - protected void createFieldEditors() { - addStartupGroup(container); - addSendUsageDataGroup(container); - this.initialize(); - } - - private void addStartupGroup(Composite parent) { - - Composite container = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().applyTo(container); - GridDataFactory.fillDefaults().indent(25, 0).applyTo(container); - - startupActionButton = new Button(container, SWT.CHECK); - startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); - addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, - WorkbenchMessages.CheckUpdates_label, container)); - } - - private void addSendUsageDataGroup(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().indent(25, 0).applyTo(composite); - GridLayoutFactory.fillDefaults().numColumns(2).spacing(5, 0) - .applyTo(composite); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - GridLayoutFactory.fillDefaults().applyTo(composite2); - - addField(new BooleanFieldEditor( - CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, - WorkbenchMessages.GeneralPrefPage_usageData_text, composite2)); - - // - Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); - privacyHyperlink.setBackground(composite.getBackground()); - privacyHyperlink.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - privacyHyperlink - .setText(WorkbenchMessages.GeneralPrefPage_seePolicy_link); - privacyHyperlink.setUnderlined(true); - privacyHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#006CF9"))); //$NON-NLS-1$ - privacyHyperlink.addHyperlinkListener(new HyperlinkAdapter() { - public void linkActivated(HyperlinkEvent e) { - Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ - } - }); - - composite.setFocus(); - - if (CathyPlugin.getDefault() - .isDebugging("/debug/udc/showUploadButton")) { //$NON-NLS-1$ - Button uploadButton = new Button(composite, SWT.PUSH); - GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER) - .span(2, 0).indent(10, 0).minSize(100, 0) - .applyTo(uploadButton); - uploadButton.setBackground(composite.getBackground()); - uploadButton.setText("Upload Now"); //$NON-NLS-1$ - uploadButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - IUsageDataSampler sampler = CathyPlugin.getDefault() - .getUsageDataCollector(); - if (sampler instanceof IUsageDataUploader) { - ((IUsageDataUploader) sampler).forceUpload(); - } - } - }); - } - } - - @Override - public boolean performOk() { - if (!super.performOk()) - return false; - - if (startupActionButton.getSelection()) { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_LAST); - } else { - getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, - CathyPlugin.STARTUP_ACTION_WIZARD); - } - - return true; - } -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.core.usagedata.IUsageDataUploader; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.resources.ColorUtils; + +public class StartupPreferencePageSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private Composite container; + private Button startupActionButton; + + private LocalResourceManager resources; + + @Override + protected Control createContents(Composite parent) { + if (null == container) + this.container = parent; + return super.createContents(parent); + } + + protected IPreferenceStore doGetPreferenceStore() { + return CathyPlugin.getDefault().getPreferenceStore(); + } + + @Override + protected void initialize() { + super.initialize(); + int startupAction = getPreferenceStore() + .getInt(CathyPlugin.STARTUP_ACTION); + startupActionButton + .setSelection(startupAction == CathyPlugin.STARTUP_ACTION_LAST); + } + + @Override + public void createControl(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + super.createControl(parent); + } + + @Override + protected void createFieldEditors() { + addStartupGroup(container); + addSendUsageDataGroup(container); + this.initialize(); + } + + private void addStartupGroup(Composite parent) { + + Composite container = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(container); + GridDataFactory.fillDefaults().indent(25, 0).applyTo(container); + + startupActionButton = new Button(container, SWT.CHECK); + startupActionButton.setText(WorkbenchMessages.RestoreLastSession_label); + addField(new BooleanFieldEditor(CathyPlugin.CHECK_UPDATES_ON_STARTUP, + WorkbenchMessages.CheckUpdates_label, container)); + } + + private void addSendUsageDataGroup(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().indent(25, 0).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).spacing(5, 0) + .applyTo(composite); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + GridLayoutFactory.fillDefaults().applyTo(composite2); + + addField(new BooleanFieldEditor( + CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, + WorkbenchMessages.GeneralPrefPage_usageData_text, composite2)); + + // + Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); + privacyHyperlink.setBackground(composite.getBackground()); + privacyHyperlink.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + privacyHyperlink + .setText(WorkbenchMessages.GeneralPrefPage_seePolicy_link); + privacyHyperlink.setUnderlined(true); + privacyHyperlink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#006CF9"))); //$NON-NLS-1$ + privacyHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ + } + }); + + composite.setFocus(); + + if (CathyPlugin.getDefault() + .isDebugging("/debug/udc/showUploadButton")) { //$NON-NLS-1$ + Button uploadButton = new Button(composite, SWT.PUSH); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER) + .span(2, 0).indent(10, 0).minSize(100, 0) + .applyTo(uploadButton); + uploadButton.setBackground(composite.getBackground()); + uploadButton.setText("Upload Now"); //$NON-NLS-1$ + uploadButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + IUsageDataSampler sampler = CathyPlugin.getDefault() + .getUsageDataCollector(); + if (sampler instanceof IUsageDataUploader) { + ((IUsageDataUploader) sampler).forceUpload(); + } + } + }); + } + } + + @Override + public boolean performOk() { + if (!super.performOk()) + return false; + + if (startupActionButton.getSelection()) { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_LAST); + } else { + getPreferenceStore().setValue(CathyPlugin.STARTUP_ACTION, + CathyPlugin.STARTUP_ACTION_WIZARD); + } + + return true; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/UndoRedoActionToolControl.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/UndoRedoActionToolControl.java index 10a476026..a12ca57d4 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/UndoRedoActionToolControl.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/UndoRedoActionToolControl.java @@ -1,128 +1,128 @@ -package org.xmind.cathy.internal; - -import java.net.MalformedURLException; -import java.net.URL; - -import javax.annotation.PostConstruct; - -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.SideValue; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory; - -public class UndoRedoActionToolControl { - - private static class HandledAction extends Action - implements IPropertyChangeListener { - - private IAction handler; - - public HandledAction(IAction handler) { - super(handler.getText(), handler.getStyle()); - this.handler = handler; - setId(handler.getId()); - setEnabled(handler.isEnabled()); - handler.addPropertyChangeListener(this); - } - - @Override - public void runWithEvent(Event event) { - handler.runWithEvent(event); - } - - @Override - public void run() { - handler.run(); - } - - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(IAction.ENABLED)) { - Boolean bool = (Boolean) event.getNewValue(); - setEnabled(bool.booleanValue()); - } else if (event.getProperty().equals(IAction.CHECKED)) { - Boolean bool = (Boolean) event.getNewValue(); - setChecked(bool.booleanValue()); - } else if (event.getProperty().equals(IAction.TOOL_TIP_TEXT)) { - String str = (String) event.getNewValue(); - setToolTipText(str); - } - } - - } - - @PostConstruct - public void createWidget(Composite parent, MToolControl toolControl, - MWindow window) { - int orientation = getOrientation(toolControl.getParent()); - int contributionItemMode = toolControl.getTags() - .contains(ICathyConstants.TAG_FORCE_TEXT) - ? ActionContributionItem.MODE_FORCE_TEXT : 0; - - ToolBarManager toolBarManager = new ToolBarManager( - orientation | SWT.RIGHT | SWT.WRAP | SWT.FLAT); - - IWorkbenchWindow ww = window.getContext().get(IWorkbenchWindow.class); - if (ww != null) { - IAction undoAction = new HandledAction( - ActionFactory.UNDO.create(ww)); - undoAction.setImageDescriptor(imageDescriptorFor("undo.png")); //$NON-NLS-1$ - ActionContributionItem undoItem = new ActionContributionItem( - undoAction); - undoItem.setMode(contributionItemMode); - toolBarManager.add(undoItem); - - IAction redoAction = new HandledAction( - ActionFactory.REDO.create(ww)); - redoAction.setImageDescriptor(imageDescriptorFor("redo.png")); //$NON-NLS-1$ - ActionContributionItem redoItem = new ActionContributionItem( - redoAction); - redoItem.setMode(contributionItemMode); - toolBarManager.add(redoItem); - } - - toolBarManager.createControl(parent); - } - - private ImageDescriptor imageDescriptorFor(String iconName) { - try { - return ImageDescriptor.createFromURL( - new URL("platform:/plugin/org.xmind.cathy/icons/toolbar/e/" //$NON-NLS-1$ - + iconName)); - } catch (MalformedURLException e) { - return null; - } - } - - private int getOrientation(final MUIElement element) { - MTrimBar trimContainer = findTrimBar(element); - if (trimContainer != null) { - SideValue side = trimContainer.getSide(); - if (side.getValue() == SideValue.LEFT_VALUE - || side.getValue() == SideValue.RIGHT_VALUE) { - return SWT.VERTICAL; - } - } - return SWT.HORIZONTAL; - } - - private MTrimBar findTrimBar(MUIElement element) { - if (element == null) - return null; - if (element instanceof MTrimBar) - return (MTrimBar) element; - return findTrimBar(element.getParent()); - } +package org.xmind.cathy.internal; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.annotation.PostConstruct; + +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.SideValue; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; + +public class UndoRedoActionToolControl { + + private static class HandledAction extends Action + implements IPropertyChangeListener { + + private IAction handler; + + public HandledAction(IAction handler) { + super(handler.getText(), handler.getStyle()); + this.handler = handler; + setId(handler.getId()); + setEnabled(handler.isEnabled()); + handler.addPropertyChangeListener(this); + } + + @Override + public void runWithEvent(Event event) { + handler.runWithEvent(event); + } + + @Override + public void run() { + handler.run(); + } + + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(IAction.ENABLED)) { + Boolean bool = (Boolean) event.getNewValue(); + setEnabled(bool.booleanValue()); + } else if (event.getProperty().equals(IAction.CHECKED)) { + Boolean bool = (Boolean) event.getNewValue(); + setChecked(bool.booleanValue()); + } else if (event.getProperty().equals(IAction.TOOL_TIP_TEXT)) { + String str = (String) event.getNewValue(); + setToolTipText(str); + } + } + + } + + @PostConstruct + public void createWidget(Composite parent, MToolControl toolControl, + MWindow window) { + int orientation = getOrientation(toolControl.getParent()); + int contributionItemMode = toolControl.getTags() + .contains(ICathyConstants.TAG_FORCE_TEXT) + ? ActionContributionItem.MODE_FORCE_TEXT : 0; + + ToolBarManager toolBarManager = new ToolBarManager( + orientation | SWT.RIGHT | SWT.WRAP | SWT.FLAT); + + IWorkbenchWindow ww = window.getContext().get(IWorkbenchWindow.class); + if (ww != null) { + IAction undoAction = new HandledAction( + ActionFactory.UNDO.create(ww)); + undoAction.setImageDescriptor(imageDescriptorFor("undo.png")); //$NON-NLS-1$ + ActionContributionItem undoItem = new ActionContributionItem( + undoAction); + undoItem.setMode(contributionItemMode); + toolBarManager.add(undoItem); + + IAction redoAction = new HandledAction( + ActionFactory.REDO.create(ww)); + redoAction.setImageDescriptor(imageDescriptorFor("redo.png")); //$NON-NLS-1$ + ActionContributionItem redoItem = new ActionContributionItem( + redoAction); + redoItem.setMode(contributionItemMode); + toolBarManager.add(redoItem); + } + + toolBarManager.createControl(parent); + } + + private ImageDescriptor imageDescriptorFor(String iconName) { + try { + return ImageDescriptor.createFromURL( + new URL("platform:/plugin/org.xmind.cathy/icons/toolbar/e/" //$NON-NLS-1$ + + iconName)); + } catch (MalformedURLException e) { + return null; + } + } + + private int getOrientation(final MUIElement element) { + MTrimBar trimContainer = findTrimBar(element); + if (trimContainer != null) { + SideValue side = trimContainer.getSide(); + if (side.getValue() == SideValue.LEFT_VALUE + || side.getValue() == SideValue.RIGHT_VALUE) { + return SWT.VERTICAL; + } + } + return SWT.HORIZONTAL; + } + + private MTrimBar findTrimBar(MUIElement element) { + if (element == null) + return null; + if (element instanceof MTrimBar) + return (MTrimBar) element; + return findTrimBar(element.getParent()); + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WelcomeDialog.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WelcomeDialog.java index 8b3698502..464f97ce4 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WelcomeDialog.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WelcomeDialog.java @@ -1,553 +1,553 @@ -package org.xmind.cathy.internal; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.events.IHyperlinkListener; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; - -/** - * @author Shawn Liu - * @since 3.6.50 - */ -public class WelcomeDialog extends Dialog { - - private Button uploadDataCheck; - - private ResourceManager resources; - - public WelcomeDialog(Shell parent) { - super(parent); - setShellStyle(SWT.NO_TRIM | SWT.TOOL | SWT.APPLICATION_MODAL - | SWT.NO_REDRAW_RESIZE); - setBlockOnOpen(false); - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - resources = new LocalResourceManager(JFaceResources.getResources(), - newShell); - } - - @Override - protected Control createContents(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ - GridData gridData = new GridData(GridData.FILL_BOTH); - gridData.widthHint = 743; - gridData.heightHint = 432; - composite.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 1; - gridLayout.marginHeight = 1; - composite.setLayout(gridLayout); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - GridData gridData2 = new GridData(GridData.FILL_BOTH); - composite2.setLayoutData(gridData2); - - GridLayout gridLayout2 = new GridLayout(1, false); - gridLayout2.marginWidth = 0; - gridLayout2.marginHeight = 0; - gridLayout2.verticalSpacing = 0; - composite2.setLayout(gridLayout2); - - createTopSection(composite2); -// createSeperator(composite2); - createBottomSection(composite2); - - return composite; - } - - private void createTopSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); - layoutData.widthHint = 740; - layoutData.heightHint = 120; - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - createHeaderSection(composite); - createTitleSection(composite); - createPlaceholderComposite(composite); - } - - private void createPlaceholderComposite(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); - layoutData.heightHint = 33; - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(1, false); - composite.setLayout(layout); - } - - private void createHeaderSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.marginTop = 10; - layout.marginRight = 10; - composite.setLayout(layout); - - createCloseButtonSection(composite); - - //add drag function - Listener controlMovedListener = createControlMovedListener(composite); - composite.addListener(SWT.MouseDown, controlMovedListener); - composite.addListener(SWT.MouseMove, controlMovedListener); - composite.addListener(SWT.MouseUp, controlMovedListener); - } - - private void createCloseButtonSection(Composite parent) { - Composite composite2 = new Composite(parent, SWT.NONE); - composite2.setBackground(composite2.getParent().getBackground()); - GridData layoutData2 = new GridData(SWT.RIGHT, SWT.TOP, true, true); - composite2.setLayoutData(layoutData2); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 5; - layout2.marginHeight = 5; - composite2.setLayout(layout2); - - final Label close = new Label(composite2, SWT.RIGHT); - close.setBackground(composite2.getBackground()); - close.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - - final Image focusedImage = (Image) resources.get( - CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/close.png")); //$NON-NLS-1$ - final Image noFocusedImage = (Image) resources.get( - CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/close-d.png")) //$NON-NLS-1$ - ; - - close.setImage(noFocusedImage); - - MouseTrackListener mouseTrackListener = new MouseTrackListener() { - - public void mouseHover(MouseEvent e) { - } - - public void mouseExit(MouseEvent e) { - close.setImage(noFocusedImage); - } - - public void mouseEnter(MouseEvent e) { - close.setImage(focusedImage); - } - }; - - composite2.addMouseTrackListener(mouseTrackListener); - close.addMouseTrackListener(mouseTrackListener); - - MouseListener mouseListener = new MouseListener() { - - public void mouseUp(MouseEvent e) { - } - - public void mouseDown(MouseEvent e) { - close(true); - } - - public void mouseDoubleClick(MouseEvent e) { - } - }; - - composite2.addMouseListener(mouseListener); - close.addMouseListener(mouseListener); - } - - private Listener createControlMovedListener(final Control header) { - Listener listener = new Listener() { - Point point = null; - Point startLocation = null; - - public void handleEvent(Event event) { - Shell shell = getShell(); - - switch (event.type) { - case SWT.MouseDown: - if (getShell().isDisposed()) { - return; - } - point = header.toDisplay(event.x, event.y); - startLocation = shell.getLocation(); - break; - case SWT.MouseMove: - if (point == null) - return; - Point p2 = header.toDisplay(event.x, event.y); - int deltaX = p2.x - point.x; - int deltaY = p2.y - point.y; - Rectangle rect = shell.getBounds(); - rect.x = startLocation.x + deltaX; - rect.y = startLocation.y + deltaY; - shell.setLocation(rect.x, rect.y); - break; - case SWT.MouseUp: - point = null; - break; - } - } - }; - return listener; - } - - private void createTitleSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true); - composite.setLayoutData(gridData); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.horizontalSpacing = 31; - layout.marginLeft = 47; - composite.setLayout(layout); - - Label titleLabel = new Label(composite, SWT.CENTER); - titleLabel.setBackground(composite.getBackground()); - titleLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ - titleLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, true)); - - FontData[] fontData = Display.getDefault().getSystemFont() - .getFontData(); - titleLabel.setFont((Font) resources.get(FontDescriptor.createFrom( - FontUtils.bold((FontUtils.newHeight(fontData, 30)), true)))); - titleLabel.setText(WorkbenchMessages.WelcomDialog_Welcom_title); - - Label title2 = new Label(composite, SWT.BOTTOM); - title2.setBackground(composite.getBackground()); - title2.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ - GridData layoutData = new GridData(SWT.CENTER, SWT.BOTTOM, false, true); - title2.setLayoutData(layoutData); - - title2.setFont((Font) resources.get( - FontDescriptor.createFrom(FontUtils.newHeight(fontData, 15)))); - title2.setText(WorkbenchMessages.WelcomDialog_WhatIsNew_title); - -// Label imageLabel = new Label(composite, SWT.CENTER); -// imageLabel.setBackground(composite.getBackground()); -// GridData gridData2 = new GridData(SWT.CENTER, SWT.CENTER, true, true); -// imageLabel.setLayoutData(gridData2); -// imageLabel.setImage((Image) resources.get( -// CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, -// "icons/welcome/welcome-xmind-logo.png")) //$NON-NLS-1$ -// ); - } - -// private void createSeperator(Composite parent) { -// Composite composite = new Composite(parent, SWT.NONE); -// composite.setBackground(parent.getBackground()); -// GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); -// composite.setLayoutData(layoutData); -// -// GridLayout layout = new GridLayout(1, false); -// layout.marginWidth = 20; -// layout.marginHeight = 0; -// composite.setLayout(layout); -// -// Composite seperator = new Composite(composite, SWT.NONE); -// seperator.setBackground( -// (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ -// GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); -// gridData.heightHint = 1; -// seperator.setLayoutData(gridData); -// seperator.setLayout(new GridLayout()); -// } - - private void createBottomSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData gridData = new GridData(GridData.FILL_BOTH); - composite.setLayoutData(gridData); - - GridLayoutFactory.fillDefaults().applyTo(composite); - - createNewFeatureItems(composite); - createButtonSection(composite); - } - - private void createNewFeatureItems(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(4, true); - layout.marginWidth = 50; - layout.marginHeight = 0; - layout.horizontalSpacing = 10; - composite.setLayout(layout); - - createImageItem(composite, - (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( - CathyPlugin.PLUGIN_ID, "icons/welcome/slide.png")) //$NON-NLS-1$ - , WorkbenchMessages.WelcomeDialog_item_slide_title, - WorkbenchMessages.WelcomeDialog_item_slide_description, - new Runnable() { - - public void run() { - // TODO launch permalink - } - }); - - createImageItem(composite, - (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( - CathyPlugin.PLUGIN_ID, "icons/welcome/cloud.png")) //$NON-NLS-1$ - , WorkbenchMessages.WelcomeDialog_item_cloud_title, - WorkbenchMessages.WelcomeDialog_item_cloud_description, - new Runnable() { - - public void run() { - // TODO launch permalink - } - }); - - createImageItem(composite, - (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( - CathyPlugin.PLUGIN_ID, - "icons/welcome/new_workspace.png")) //$NON-NLS-1$ - , WorkbenchMessages.WelcomeDialog_item_workspace_title, - WorkbenchMessages.WelcomeDialog_item_workspace_description, - new Runnable() { - - public void run() { - // TODO launch permalink - } - }); - - createImageItem(composite, - (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( - CathyPlugin.PLUGIN_ID, "icons/welcome/high_dpi.png")) //$NON-NLS-1$ - , WorkbenchMessages.WelcomeDialog_item_high_dpi_title, - WorkbenchMessages.WelcomeDialog_item_high_dpi_description, - - new Runnable() { - - public void run() { - // TODO launch permalink - } - }); - } - - private void createImageItem(Composite parent, Image image, String title, - String description, final Runnable action) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(layoutData); - - GridLayoutFactory.fillDefaults().spacing(0, 20).applyTo(composite); - - Label imageLabel = new Label(composite, SWT.CENTER); - imageLabel.setBackground(composite.getBackground()); - GridData gridData2 = new GridData(SWT.CENTER, SWT.TOP, true, false); - imageLabel.setLayoutData(gridData2); - imageLabel.setImage(image); -// imageLabel.setCursor( -// parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - - imageLabel.addMouseListener(new MouseAdapter() { - - @Override - public void mouseDown(MouseEvent e) { - action.run(); - } - }); - - // - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground(composite.getBackground()); - GridData layoutData2 = new GridData(SWT.FILL, SWT.FILL, true, true); - composite2.setLayoutData(layoutData2); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 10; - composite2.setLayout(layout2); - - FontData[] fontData = Display.getDefault().getSystemFont() - .getFontData(); - - Label titleLabel = new Label(composite2, SWT.NONE); - titleLabel.setBackground(composite2.getBackground()); - titleLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ - titleLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, false)); - titleLabel.setText(title); - titleLabel.setFont((Font) resources.get(FontDescriptor.createFrom( - FontUtils.bold(FontUtils.newHeight(fontData, 11), true)))); - - Label descriptionLabel = new Label(composite2, SWT.WRAP); - descriptionLabel.setBackground(composite2.getBackground()); - descriptionLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ - descriptionLabel - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - descriptionLabel.setAlignment(SWT.CENTER); - descriptionLabel.setText(description); - descriptionLabel.setFont((Font) resources - .get(FontDescriptor.createFrom(FontUtils.relativeHeight( - descriptionLabel.getFont().getFontData(), 0)))); - } - - private void createButtonSection(Composite parent) { - Composite container = new Composite(parent, SWT.NONE); - GridDataFactory.fillDefaults().applyTo(container); - GridLayoutFactory.fillDefaults().margins(1, 1).applyTo(container); - container.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#e8e8e8"))); //$NON-NLS-1$ - - Composite composite = new Composite(container, SWT.NONE); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#fcfcfc"))); //$NON-NLS-1$ - GridData layoutData = new GridData(SWT.FILL, SWT.BOTTOM, true, false); - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 27; - layout.marginHeight = 10; - composite.setLayout(layout); - - createUploadDataCheck(composite); - createOkButton(composite); - } - - private void createUploadDataCheck(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.horizontalSpacing = 5; - composite.setLayout(layout); - - uploadDataCheck = new Button(composite, SWT.CHECK); - uploadDataCheck.setBackground(composite.getBackground()); - GridData gridData2 = new GridData(SWT.LEFT, SWT.CENTER, false, false); - uploadDataCheck.setLayoutData(gridData2); - uploadDataCheck - .setText(WorkbenchMessages.WelcomeDialog_uploadDataCheck_text); - uploadDataCheck.setSelection(true); - - // - Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); - privacyHyperlink.setBackground(composite.getBackground()); - privacyHyperlink.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - privacyHyperlink - .setText(WorkbenchMessages.WelcomeDialog_seePolicy_link); - privacyHyperlink.setUnderlined(true); - privacyHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#006CF9"))); //$NON-NLS-1$ - - composite.setFocus(); - - privacyHyperlink.addHyperlinkListener(new IHyperlinkListener() { - - public void linkExited(HyperlinkEvent e) { - } - - public void linkEntered(HyperlinkEvent e) { - } - - public void linkActivated(HyperlinkEvent e) { - Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ - } - }); - } - - private void createOkButton(Composite parent) { - final Button okButton = new Button(parent, SWT.PUSH); - okButton.setBackground(parent.getBackground()); - GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, true); - gridData.widthHint = 92; - okButton.setLayoutData(gridData); - okButton.setText(WorkbenchMessages.WelcomeDialog_okButton_text); - okButton.setFont( - (Font) resources.get(FontDescriptor.createFrom(FontUtils - .relativeHeight(okButton.getFont().getFontData(), 1)))); - - okButton.addMouseListener(new MouseListener() { - - public void mouseUp(MouseEvent e) { - } - - public void mouseDown(MouseEvent e) { - close(false); - } - - public void mouseDoubleClick(MouseEvent e) { - } - }); - } - - private void close(boolean restoreDefaults) { - boolean isUploadData = true; - if (!restoreDefaults) { - isUploadData = uploadDataCheck.getSelection(); - } - CathyPlugin.getDefault().getPreferenceStore().setValue( - CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, isUploadData); - - super.close(); - } - -} +package org.xmind.cathy.internal; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.events.IHyperlinkListener; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; + +/** + * @author Shawn Liu + * @since 3.6.50 + */ +public class WelcomeDialog extends Dialog { + + private Button uploadDataCheck; + + private ResourceManager resources; + + public WelcomeDialog(Shell parent) { + super(parent); + setShellStyle(SWT.NO_TRIM | SWT.TOOL | SWT.APPLICATION_MODAL + | SWT.NO_REDRAW_RESIZE); + setBlockOnOpen(false); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + resources = new LocalResourceManager(JFaceResources.getResources(), + newShell); + } + + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.widthHint = 743; + gridData.heightHint = 432; + composite.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 1; + gridLayout.marginHeight = 1; + composite.setLayout(gridLayout); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + GridData gridData2 = new GridData(GridData.FILL_BOTH); + composite2.setLayoutData(gridData2); + + GridLayout gridLayout2 = new GridLayout(1, false); + gridLayout2.marginWidth = 0; + gridLayout2.marginHeight = 0; + gridLayout2.verticalSpacing = 0; + composite2.setLayout(gridLayout2); + + createTopSection(composite2); +// createSeperator(composite2); + createBottomSection(composite2); + + return composite; + } + + private void createTopSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); + layoutData.widthHint = 740; + layoutData.heightHint = 120; + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + createHeaderSection(composite); + createTitleSection(composite); + createPlaceholderComposite(composite); + } + + private void createPlaceholderComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); + layoutData.heightHint = 33; + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(1, false); + composite.setLayout(layout); + } + + private void createHeaderSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.marginTop = 10; + layout.marginRight = 10; + composite.setLayout(layout); + + createCloseButtonSection(composite); + + //add drag function + Listener controlMovedListener = createControlMovedListener(composite); + composite.addListener(SWT.MouseDown, controlMovedListener); + composite.addListener(SWT.MouseMove, controlMovedListener); + composite.addListener(SWT.MouseUp, controlMovedListener); + } + + private void createCloseButtonSection(Composite parent) { + Composite composite2 = new Composite(parent, SWT.NONE); + composite2.setBackground(composite2.getParent().getBackground()); + GridData layoutData2 = new GridData(SWT.RIGHT, SWT.TOP, true, true); + composite2.setLayoutData(layoutData2); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 5; + layout2.marginHeight = 5; + composite2.setLayout(layout2); + + final Label close = new Label(composite2, SWT.RIGHT); + close.setBackground(composite2.getBackground()); + close.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); + + final Image focusedImage = (Image) resources.get( + CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "icons/welcome/close.png")); //$NON-NLS-1$ + final Image noFocusedImage = (Image) resources.get( + CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "icons/welcome/close-d.png")) //$NON-NLS-1$ + ; + + close.setImage(noFocusedImage); + + MouseTrackListener mouseTrackListener = new MouseTrackListener() { + + public void mouseHover(MouseEvent e) { + } + + public void mouseExit(MouseEvent e) { + close.setImage(noFocusedImage); + } + + public void mouseEnter(MouseEvent e) { + close.setImage(focusedImage); + } + }; + + composite2.addMouseTrackListener(mouseTrackListener); + close.addMouseTrackListener(mouseTrackListener); + + MouseListener mouseListener = new MouseListener() { + + public void mouseUp(MouseEvent e) { + } + + public void mouseDown(MouseEvent e) { + close(true); + } + + public void mouseDoubleClick(MouseEvent e) { + } + }; + + composite2.addMouseListener(mouseListener); + close.addMouseListener(mouseListener); + } + + private Listener createControlMovedListener(final Control header) { + Listener listener = new Listener() { + Point point = null; + Point startLocation = null; + + public void handleEvent(Event event) { + Shell shell = getShell(); + + switch (event.type) { + case SWT.MouseDown: + if (getShell().isDisposed()) { + return; + } + point = header.toDisplay(event.x, event.y); + startLocation = shell.getLocation(); + break; + case SWT.MouseMove: + if (point == null) + return; + Point p2 = header.toDisplay(event.x, event.y); + int deltaX = p2.x - point.x; + int deltaY = p2.y - point.y; + Rectangle rect = shell.getBounds(); + rect.x = startLocation.x + deltaX; + rect.y = startLocation.y + deltaY; + shell.setLocation(rect.x, rect.y); + break; + case SWT.MouseUp: + point = null; + break; + } + } + }; + return listener; + } + + private void createTitleSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 31; + layout.marginLeft = 47; + composite.setLayout(layout); + + Label titleLabel = new Label(composite, SWT.CENTER); + titleLabel.setBackground(composite.getBackground()); + titleLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ + titleLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, true)); + + FontData[] fontData = Display.getDefault().getSystemFont() + .getFontData(); + titleLabel.setFont((Font) resources.get(FontDescriptor.createFrom( + FontUtils.bold((FontUtils.newHeight(fontData, 30)), true)))); + titleLabel.setText(WorkbenchMessages.WelcomDialog_Welcom_title); + + Label title2 = new Label(composite, SWT.BOTTOM); + title2.setBackground(composite.getBackground()); + title2.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ + GridData layoutData = new GridData(SWT.CENTER, SWT.BOTTOM, false, true); + title2.setLayoutData(layoutData); + + title2.setFont((Font) resources.get( + FontDescriptor.createFrom(FontUtils.newHeight(fontData, 15)))); + title2.setText(WorkbenchMessages.WelcomDialog_WhatIsNew_title); + +// Label imageLabel = new Label(composite, SWT.CENTER); +// imageLabel.setBackground(composite.getBackground()); +// GridData gridData2 = new GridData(SWT.CENTER, SWT.CENTER, true, true); +// imageLabel.setLayoutData(gridData2); +// imageLabel.setImage((Image) resources.get( +// CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, +// "icons/welcome/welcome-xmind-logo.png")) //$NON-NLS-1$ +// ); + } + +// private void createSeperator(Composite parent) { +// Composite composite = new Composite(parent, SWT.NONE); +// composite.setBackground(parent.getBackground()); +// GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); +// composite.setLayoutData(layoutData); +// +// GridLayout layout = new GridLayout(1, false); +// layout.marginWidth = 20; +// layout.marginHeight = 0; +// composite.setLayout(layout); +// +// Composite seperator = new Composite(composite, SWT.NONE); +// seperator.setBackground( +// (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ +// GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); +// gridData.heightHint = 1; +// seperator.setLayoutData(gridData); +// seperator.setLayout(new GridLayout()); +// } + + private void createBottomSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData gridData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(gridData); + + GridLayoutFactory.fillDefaults().applyTo(composite); + + createNewFeatureItems(composite); + createButtonSection(composite); + } + + private void createNewFeatureItems(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(4, true); + layout.marginWidth = 50; + layout.marginHeight = 0; + layout.horizontalSpacing = 10; + composite.setLayout(layout); + + createImageItem(composite, + (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( + CathyPlugin.PLUGIN_ID, "icons/welcome/slide.png")) //$NON-NLS-1$ + , WorkbenchMessages.WelcomeDialog_item_slide_title, + WorkbenchMessages.WelcomeDialog_item_slide_description, + new Runnable() { + + public void run() { + // TODO launch permalink + } + }); + + createImageItem(composite, + (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( + CathyPlugin.PLUGIN_ID, "icons/welcome/cloud.png")) //$NON-NLS-1$ + , WorkbenchMessages.WelcomeDialog_item_cloud_title, + WorkbenchMessages.WelcomeDialog_item_cloud_description, + new Runnable() { + + public void run() { + // TODO launch permalink + } + }); + + createImageItem(composite, + (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( + CathyPlugin.PLUGIN_ID, + "icons/welcome/new_workspace.png")) //$NON-NLS-1$ + , WorkbenchMessages.WelcomeDialog_item_workspace_title, + WorkbenchMessages.WelcomeDialog_item_workspace_description, + new Runnable() { + + public void run() { + // TODO launch permalink + } + }); + + createImageItem(composite, + (Image) resources.get(CathyPlugin.imageDescriptorFromPlugin( + CathyPlugin.PLUGIN_ID, "icons/welcome/high_dpi.png")) //$NON-NLS-1$ + , WorkbenchMessages.WelcomeDialog_item_high_dpi_title, + WorkbenchMessages.WelcomeDialog_item_high_dpi_description, + + new Runnable() { + + public void run() { + // TODO launch permalink + } + }); + } + + private void createImageItem(Composite parent, Image image, String title, + String description, final Runnable action) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(layoutData); + + GridLayoutFactory.fillDefaults().spacing(0, 20).applyTo(composite); + + Label imageLabel = new Label(composite, SWT.CENTER); + imageLabel.setBackground(composite.getBackground()); + GridData gridData2 = new GridData(SWT.CENTER, SWT.TOP, true, false); + imageLabel.setLayoutData(gridData2); + imageLabel.setImage(image); +// imageLabel.setCursor( +// parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + + imageLabel.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + action.run(); + } + }); + + // + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(composite.getBackground()); + GridData layoutData2 = new GridData(SWT.FILL, SWT.FILL, true, true); + composite2.setLayoutData(layoutData2); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.verticalSpacing = 10; + composite2.setLayout(layout2); + + FontData[] fontData = Display.getDefault().getSystemFont() + .getFontData(); + + Label titleLabel = new Label(composite2, SWT.NONE); + titleLabel.setBackground(composite2.getBackground()); + titleLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ + titleLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, false)); + titleLabel.setText(title); + titleLabel.setFont((Font) resources.get(FontDescriptor.createFrom( + FontUtils.bold(FontUtils.newHeight(fontData, 11), true)))); + + Label descriptionLabel = new Label(composite2, SWT.WRAP); + descriptionLabel.setBackground(composite2.getBackground()); + descriptionLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#4a4a4a"))); //$NON-NLS-1$ + descriptionLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + descriptionLabel.setAlignment(SWT.CENTER); + descriptionLabel.setText(description); + descriptionLabel.setFont((Font) resources + .get(FontDescriptor.createFrom(FontUtils.relativeHeight( + descriptionLabel.getFont().getFontData(), 0)))); + } + + private void createButtonSection(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(container); + GridLayoutFactory.fillDefaults().margins(1, 1).applyTo(container); + container.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#e8e8e8"))); //$NON-NLS-1$ + + Composite composite = new Composite(container, SWT.NONE); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#fcfcfc"))); //$NON-NLS-1$ + GridData layoutData = new GridData(SWT.FILL, SWT.BOTTOM, true, false); + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 27; + layout.marginHeight = 10; + composite.setLayout(layout); + + createUploadDataCheck(composite); + createOkButton(composite); + } + + private void createUploadDataCheck(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 5; + composite.setLayout(layout); + + uploadDataCheck = new Button(composite, SWT.CHECK); + uploadDataCheck.setBackground(composite.getBackground()); + GridData gridData2 = new GridData(SWT.LEFT, SWT.CENTER, false, false); + uploadDataCheck.setLayoutData(gridData2); + uploadDataCheck + .setText(WorkbenchMessages.WelcomeDialog_uploadDataCheck_text); + uploadDataCheck.setSelection(true); + + // + Hyperlink privacyHyperlink = new Hyperlink(composite, SWT.NONE); + privacyHyperlink.setBackground(composite.getBackground()); + privacyHyperlink.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + privacyHyperlink + .setText(WorkbenchMessages.WelcomeDialog_seePolicy_link); + privacyHyperlink.setUnderlined(true); + privacyHyperlink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#006CF9"))); //$NON-NLS-1$ + + composite.setFocus(); + + privacyHyperlink.addHyperlinkListener(new IHyperlinkListener() { + + public void linkExited(HyperlinkEvent e) { + } + + public void linkEntered(HyperlinkEvent e) { + } + + public void linkActivated(HyperlinkEvent e) { + Program.launch("http://www.xmind.net/privacy/usage/"); //$NON-NLS-1$ + } + }); + } + + private void createOkButton(Composite parent) { + final Button okButton = new Button(parent, SWT.PUSH); + okButton.setBackground(parent.getBackground()); + GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, true); + gridData.widthHint = 92; + okButton.setLayoutData(gridData); + okButton.setText(WorkbenchMessages.WelcomeDialog_okButton_text); + okButton.setFont( + (Font) resources.get(FontDescriptor.createFrom(FontUtils + .relativeHeight(okButton.getFont().getFontData(), 1)))); + + okButton.addMouseListener(new MouseListener() { + + public void mouseUp(MouseEvent e) { + } + + public void mouseDown(MouseEvent e) { + close(false); + } + + public void mouseDoubleClick(MouseEvent e) { + } + }); + } + + private void close(boolean restoreDefaults) { + boolean isUploadData = true; + if (!restoreDefaults) { + isUploadData = uploadDataCheck.getSelection(); + } + CathyPlugin.getDefault().getPreferenceStore().setValue( + CathyPlugin.USAGE_DATA_UPLOADING_ENABLED, isUploadData); + + super.close(); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WindowPropertyTester.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WindowPropertyTester.java index 5c9e6fbe5..bff1f536f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WindowPropertyTester.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WindowPropertyTester.java @@ -1,44 +1,44 @@ -package org.xmind.cathy.internal; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; - -public class WindowPropertyTester extends PropertyTester { - - private static final String P_SHOWING_DASHBOARD = "showingDashboard"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof IWorkbenchWindow); - - IWorkbenchWindow window = (IWorkbenchWindow) receiver; - MWindow windowModel = window.getService(MWindow.class); - Assert.isLegal(windowModel != null); - - if (P_SHOWING_DASHBOARD.equals(property)) { - return testTag(windowModel, ICathyConstants.TAG_SHOW_DASHBOARD, - expectedValue); - } - - Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ - - return false; - } - - private boolean testTag(MWindow windowModel, String tag, - Object expectedValue) { - boolean actualValue = windowModel.getTags().contains(tag); - if (expectedValue == null || "".equals(expectedValue)) { //$NON-NLS-1$ - return actualValue; - } else if (expectedValue instanceof Boolean) { - return ((Boolean) expectedValue) == actualValue; - } else if (expectedValue instanceof String) { - return Boolean.parseBoolean((String) expectedValue) == actualValue; - } - Assert.isLegal(false, "Unrecognized value: " + expectedValue); //$NON-NLS-1$ - return false; - } - -} +package org.xmind.cathy.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; + +public class WindowPropertyTester extends PropertyTester { + + private static final String P_SHOWING_DASHBOARD = "showingDashboard"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof IWorkbenchWindow); + + IWorkbenchWindow window = (IWorkbenchWindow) receiver; + MWindow windowModel = window.getService(MWindow.class); + Assert.isLegal(windowModel != null); + + if (P_SHOWING_DASHBOARD.equals(property)) { + return testTag(windowModel, ICathyConstants.TAG_SHOW_DASHBOARD, + expectedValue); + } + + Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ + + return false; + } + + private boolean testTag(MWindow windowModel, String tag, + Object expectedValue) { + boolean actualValue = windowModel.getTags().contains(tag); + if (expectedValue == null || "".equals(expectedValue)) { //$NON-NLS-1$ + return actualValue; + } else if (expectedValue instanceof Boolean) { + return ((Boolean) expectedValue) == actualValue; + } else if (expectedValue instanceof String) { + return Boolean.parseBoolean((String) expectedValue) == actualValue; + } + Assert.isLegal(false, "Unrecognized value: " + expectedValue); //$NON-NLS-1$ + return false; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WorkbenchMessages.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WorkbenchMessages.java index 1a2402d4c..5bd862d87 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WorkbenchMessages.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/WorkbenchMessages.java @@ -1,221 +1,225 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal; - -import org.eclipse.osgi.util.NLS; - -public class WorkbenchMessages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.cathy.internal.messages"; //$NON-NLS-1$ - - public static String AppWindowTitle; - public static String ProWindowTitle; - - public static String File_menu_text; - public static String Edit_menu_text; - public static String Help_menu_text; - public static String SaveAction_text; - - public static String GeneralPrefPage_seePolicy_link; - public static String GeneralPrefPage_title; - public static String GeneralPrefPage_usageData_text; - - public static String GeneralPrefPageSection_RecentFileCountSection_title; - public static String GeneralPrefPageSection_AutoSaveGroup_title; - - public static String RecentFiles_label; - public static String RecentFileViewer_PinThisMapAction_label; - public static String RecentFileViewer_UnpinThisMap_label; - public static String RestoreLastSession_label; - public static String CathyWorkbenchWindowAdvisor_menu_lockAction_text; - - public static String CathyWorkbenchWindowAdvisor_menu_resetAction_text; - - public static String CathyWorkbenchWindowAdvisor_windowTitle_home_prefix; - - public static String ChangeLanguage_button; - - public static String ChangeLanguageTo_description; - - public static String CheckUpdates_label; - public static String AutoBackup_label; - - public static String AutoBackupIndicator_AutoSaveDisabled_description; - public static String AutoBackupIndicator_AutoSaveDisabled_label; - public static String AutoBackupIndicator_AutoSaveEnabled_label; - public static String AutoBackupIndicator_DisableAutoSaveAction_text; - public static String AutoBackupIndicator_EnableAutoSaveAction_text; - public static String AutoBackupIndicator_OpenPreferenceAction_text; - - public static String AutoSave_label; - public static String AutoSave_Minutes; - public static String AutoSave_label2; - public static String Startup_title; - public static String StartupAction_label; - public static String StartupAction_OpenDialog; - public static String StartupAction_BlankMap; - public static String StartupAction_HomeMap; - public static String StartupAction_LastSession; - public static String HomeMap_label; - public static String HomeMap_NotFound_error; - - public static String appWindow_ListSelectionDialog_Text; - public static String appWindow_ListSelectionDialog_Title; - - public static String KeyAssist_text; - - public static String Help_text; - public static String Help_toolTip; - public static String Update_text; - public static String Update_toolTip; - - public static String CheckOpenFilesJob_CheckFiles_name; - public static String CheckOpenFilesJob_OpenFiles_name; - public static String CheckOpenFilesJob_FailsToOpen_message; - public static String CheckOpenFilesJob_ShowPresentation_name; - - public static String CheckRecoverFilesJob_jobName; - public static String CheckRecoverFilesJob_LoadFiles_name; - public static String CheckRecoverFilesJob_FilterFiles_name; - public static String CheckRecoverFilesJob_RecoverFiles_name; - - public static String CheckUpdatesJob_jobName; - public static String CheckUpdatesJob_Fail_message; - public static String CheckUpdatesJob_NoUpdate_message; - public static String CheckUpdatesJob_NewUpdate_message; - public static String CheckUpdatesJob_NewUpdate_info_message; - public static String CheckUpdatesJob_NewUpdate_moreDownloads_text; - - public static String ConfirmDeleteTemplateDialog_message_withTemplateName; - public static String ConfirmDeleteTemplateDialog_title; - public static String ConfirmToRestart_cancelButton; - public static String ConfirmToRestart_defaultButton; - public static String ConfirmToRestart_description; - public static String ConfirmToRestart_title; - - public static String ConstantsHacker_WizardHandler_menuLabel; - - public static String StartupJob_jobName; - public static String StartupJob_OpenBootstrapEditor_name; - public static String StartupJob_OpenBlankMap; - public static String StartupJob_OpenHomeMap; - public static String StartupJob_OpenLastSession; - - public static String SupportLanguageName_Arabic; - public static String SupportLanguageName_Danish; - public static String SupportLanguageName_English; - public static String SupportLanguageName_Spanish; - public static String SupportLanguageName_French; - public static String SupportLanguageName_German; - public static String SupportLanguageName_Italian; - public static String SupportLanguageName_Japanese; - public static String SupportLanguageName_Korean; - public static String SupportLanguageName_Portuguese_Brazilian; - public static String SupportLanguageName_Russian; - public static String SupportLanguageName_SimplifiedCN; - public static String SupportLanguageName_Slovenian; - public static String SupportLanguageName_TraditionalCN; - - public static String PromptSaveEditorOnClosing_message; - - public static String About_LicensedTo; - public static String About_ProTitle; - public static String About_PlusTitle; - public static String About_ProSubscriptionTitle; - public static String About_LicenseTypePattern; - public static String About_LicenseType_Unactivated; - - public static String DownloadAndOpenFileJob_jobName; - public static String DownloadAndOpenFileJob_Task_Download_with_url; - public static String DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url; - public static String DownloadAndOpenFileJob_Error_FailedToCreateTempFile; - public static String DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url; - public static String DownloadAndOpenFileJob_DownloadJob_jobName; - - public static String OpenXMindCommandFileJob_failed_fileIsNotReadable; - public static String OpenXMindCommandFileJob_failed_noCommandFilePath_text; - public static String OpenXMindCommandFileJob_failed_openXMindCommandFile; - public static String OpenXMindCommandFileJob_name; - - public static String WelcomeDialog_item_slide_title; - public static String WelcomeDialog_item_slide_description; - public static String WelcomeDialog_item_cloud_description; - public static String WelcomeDialog_item_cloud_title; - public static String WelcomeDialog_item_high_dpi_description; - public static String WelcomeDialog_item_high_dpi_title; - public static String WelcomeDialog_item_workspace_description; - public static String WelcomeDialog_item_workspace_title; - public static String WelcomeDialog_okButton_text; - public static String WelcomeDialog_seePolicy_link; - public static String WelcomeDialog_uploadDataCheck_text; - public static String WelcomDialog_WhatIsNew_title; - public static String WelcomDialog_Welcom_title; - - public static String WelcomeToXMindHandler_welcomeToXMind_templatedName; - - public static String WizardHandler_menuLabel; - - public static String BetaVerifier_BetaExpiredPromptDialog_windowTitle; - public static String BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId; - public static String BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text; - public static String BetaVerifier_BetaExpiredPromptDialog_ExitButton_text; - public static String BetaVerifier_BetaExpiredPromptDialog_DownloadFailure_message; - - public static String About_Copyright; - public static String About_Homepage; - public static String About_BetaExpiryMessage_withExpiryTime; - - public static String LanguagePrefPage_ConfirmToRestart_laterButton; - public static String LanguagePrefPage_ConfirmToRestart2_defaultButton; - public static String LanguagePrefPage_ConfirmToRestart2_description; - public static String LanguagePrefPage_title; - public static String DashboardHideHome_tooltip; - public static String DashboardShowHome_tooltip; - public static String DashboardBlankPage_name; - public static String DashboardTemplatesPage_name; - public static String DashboardBlankPage_message; - public static String DashboardTemplatesPage_message; - - public static String DashboardRecentFiles_message; - - public static String DashboardThemeChoose_message; - public static String DashboardThemeCreate_label; - - public static String NewFileDashboardPage_AddTemplates_tooltip; - public static String NewFileDashboardPage_AddTemplates_label; - public static String NewFileDashboardPage_DeleteTemplate_tooltip; - public static String NewFileDashboardPage_DeleteTemplate_label; - public static String NewFileDashboardPage_ExitEditMode_tooltip; - public static String NewFileDashboardPage_ExitEditTemplatesMode_label; - public static String NewFileDashboardPage_GoIntoTemplatesManagerMode_tooltip; - public static String NewFileDashboardPage_GoToEditTemplateMode_label; - public static String NewFileDashboardPage_leftTitleBar_text; - public static String NewFileDashboardPage_TemplateFilterName_label; - public static String NewFileDashboardPage_Import_button; - - public static String TemplateViewer_SystemGroup_title; - public static String TemplateViewer_UserGroup_title; - - public static String RecentFileBlankPage_description; - - public static String RecentFilesLabelProvider_Cloud_text; - - public static String XStackRenderer_TopArea_tipLabel; - public static String XStackRenderer_BottomArea_Add_button; - - static { - NLS.initializeMessages(BUNDLE_NAME, WorkbenchMessages.class); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal; + +import org.eclipse.osgi.util.NLS; + +public class WorkbenchMessages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.cathy.internal.messages"; //$NON-NLS-1$ + + public static String AppWindowTitle; + public static String ProWindowTitle; + + public static String File_menu_text; + public static String Edit_menu_text; + public static String Help_menu_text; + public static String SaveAction_text; + + public static String GeneralPrefPage_seePolicy_link; + public static String GeneralPrefPage_title; + public static String GeneralPrefPage_usageData_text; + + public static String GeneralPrefPageSection_RecentFileCountSection_title; + public static String GeneralPrefPageSection_AutoSaveGroup_title; + + public static String RecentFiles_label; + public static String RecentFileViewer_PinThisMapAction_label; + public static String RecentFileViewer_UnpinThisMap_label; + public static String RestoreLastSession_label; + public static String CategorizedTemplateViewer_group_untitiledName; + + public static String CategorizedTemplateViewer_template_untitiledName; + + public static String CathyWorkbenchWindowAdvisor_menu_lockAction_text; + + public static String CathyWorkbenchWindowAdvisor_menu_resetAction_text; + + public static String CathyWorkbenchWindowAdvisor_windowTitle_home_prefix; + + public static String ChangeLanguage_button; + + public static String ChangeLanguageTo_description; + + public static String CheckUpdates_label; + public static String AutoBackup_label; + + public static String AutoBackupIndicator_AutoSaveDisabled_description; + public static String AutoBackupIndicator_AutoSaveDisabled_label; + public static String AutoBackupIndicator_AutoSaveEnabled_label; + public static String AutoBackupIndicator_DisableAutoSaveAction_text; + public static String AutoBackupIndicator_EnableAutoSaveAction_text; + public static String AutoBackupIndicator_OpenPreferenceAction_text; + + public static String AutoSave_label; + public static String AutoSave_Minutes; + public static String AutoSave_label2; + public static String Startup_title; + public static String StartupAction_label; + public static String StartupAction_OpenDialog; + public static String StartupAction_BlankMap; + public static String StartupAction_HomeMap; + public static String StartupAction_LastSession; + public static String HomeMap_label; + public static String HomeMap_NotFound_error; + + public static String appWindow_ListSelectionDialog_Text; + public static String appWindow_ListSelectionDialog_Title; + + public static String KeyAssist_text; + + public static String Help_text; + public static String Help_toolTip; + public static String Update_text; + public static String Update_toolTip; + + public static String CheckOpenFilesJob_CheckFiles_name; + public static String CheckOpenFilesJob_OpenFiles_name; + public static String CheckOpenFilesJob_FailsToOpen_message; + public static String CheckOpenFilesJob_ShowPresentation_name; + + public static String CheckRecoverFilesJob_jobName; + public static String CheckRecoverFilesJob_LoadFiles_name; + public static String CheckRecoverFilesJob_FilterFiles_name; + public static String CheckRecoverFilesJob_RecoverFiles_name; + + public static String CheckUpdatesJob_jobName; + public static String CheckUpdatesJob_Fail_message; + public static String CheckUpdatesJob_NoUpdate_message; + public static String CheckUpdatesJob_NewUpdate_message; + public static String CheckUpdatesJob_NewUpdate_info_message; + public static String CheckUpdatesJob_NewUpdate_moreDownloads_text; + + public static String ConfirmDeleteTemplateDialog_message_withTemplateName; + public static String ConfirmDeleteTemplateDialog_title; + public static String ConfirmToRestart_cancelButton; + public static String ConfirmToRestart_defaultButton; + public static String ConfirmToRestart_description; + public static String ConfirmToRestart_title; + + public static String ConstantsHacker_WizardHandler_menuLabel; + + public static String StartupJob_jobName; + public static String StartupJob_OpenBootstrapEditor_name; + public static String StartupJob_OpenBlankMap; + public static String StartupJob_OpenHomeMap; + public static String StartupJob_OpenLastSession; + + public static String SupportLanguageName_Arabic; + public static String SupportLanguageName_Danish; + public static String SupportLanguageName_English; + public static String SupportLanguageName_Spanish; + public static String SupportLanguageName_French; + public static String SupportLanguageName_German; + public static String SupportLanguageName_Italian; + public static String SupportLanguageName_Japanese; + public static String SupportLanguageName_Korean; + public static String SupportLanguageName_Portuguese_Brazilian; + public static String SupportLanguageName_Russian; + public static String SupportLanguageName_SimplifiedCN; + public static String SupportLanguageName_Slovenian; + public static String SupportLanguageName_TraditionalCN; + + public static String PromptSaveEditorOnClosing_message; + + public static String About_LicensedTo; + public static String About_ProTitle; + public static String About_PlusTitle; + public static String About_ProSubscriptionTitle; + public static String About_LicenseTypePattern; + public static String About_LicenseType_Unactivated; + + public static String DownloadAndOpenFileJob_jobName; + public static String DownloadAndOpenFileJob_Task_Download_with_url; + public static String DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url; + public static String DownloadAndOpenFileJob_Error_FailedToCreateTempFile; + public static String DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url; + public static String DownloadAndOpenFileJob_DownloadJob_jobName; + + public static String OpenXMindCommandFileJob_failed_fileIsNotReadable; + public static String OpenXMindCommandFileJob_failed_noCommandFilePath_text; + public static String OpenXMindCommandFileJob_failed_openXMindCommandFile; + public static String OpenXMindCommandFileJob_name; + + public static String WelcomeDialog_item_slide_title; + public static String WelcomeDialog_item_slide_description; + public static String WelcomeDialog_item_cloud_description; + public static String WelcomeDialog_item_cloud_title; + public static String WelcomeDialog_item_high_dpi_description; + public static String WelcomeDialog_item_high_dpi_title; + public static String WelcomeDialog_item_workspace_description; + public static String WelcomeDialog_item_workspace_title; + public static String WelcomeDialog_okButton_text; + public static String WelcomeDialog_seePolicy_link; + public static String WelcomeDialog_uploadDataCheck_text; + public static String WelcomDialog_WhatIsNew_title; + public static String WelcomDialog_Welcom_title; + + public static String WelcomeToXMindHandler_welcomeToXMind_templatedName; + + public static String WizardHandler_menuLabel; + + public static String BetaVerifier_BetaExpiredPromptDialog_windowTitle; + public static String BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId; + public static String BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text; + public static String BetaVerifier_BetaExpiredPromptDialog_ExitButton_text; + public static String BetaVerifier_BetaExpiredPromptDialog_DownloadFailure_message; + + public static String About_Copyright; + public static String About_Homepage; + public static String About_BetaExpiryMessage_withExpiryTime; + + public static String LanguagePrefPage_ConfirmToRestart_laterButton; + public static String LanguagePrefPage_ConfirmToRestart2_defaultButton; + public static String LanguagePrefPage_ConfirmToRestart2_description; + public static String LanguagePrefPage_title; + public static String DashboardHideHome_tooltip; + public static String DashboardShowHome_tooltip; + public static String DashboardBlankPage_name; + public static String DashboardTemplatesPage_name; + public static String DashboardBlankPage_message; + public static String DashboardTemplatesPage_message; + + public static String DashboardRecentFiles_message; + + public static String DashboardThemeChoose_message; + public static String DashboardThemeCreate_label; + + public static String NewFileDashboardPage_AddTemplates_tooltip; + public static String NewFileDashboardPage_AddTemplates_label; + public static String NewFileDashboardPage_DeleteTemplate_tooltip; + public static String NewFileDashboardPage_DeleteTemplate_label; + public static String NewFileDashboardPage_ExitEditMode_tooltip; + public static String NewFileDashboardPage_ExitEditTemplatesMode_label; + public static String NewFileDashboardPage_GoIntoTemplatesManagerMode_tooltip; + public static String NewFileDashboardPage_GoToEditTemplateMode_label; + public static String NewFileDashboardPage_leftTitleBar_text; + public static String NewFileDashboardPage_TemplateFilterName_label; + public static String NewFileDashboardPage_Import_button; + + public static String TemplateViewer_SystemGroup_title; + public static String TemplateViewer_UserGroup_title; + + public static String RecentFileBlankPage_description; + + public static String RecentFilesLabelProvider_Cloud_text; + + public static String XStackRenderer_TopArea_tipLabel; + public static String XStackRenderer_BottomArea_Add_button; + + static { + NLS.initializeMessages(BUNDLE_NAME, WorkbenchMessages.class); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderRenderNoneHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderRenderNoneHandler.java index 573d84907..78676e192 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderRenderNoneHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderRenderNoneHandler.java @@ -1,42 +1,42 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyCTabFolderRenderNoneHandler - extends AbstractCSSPropertySWTHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyCTabFolderRenderNoneHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - CTabFolder folder = (CTabFolder) control; - CTabFolderRenderer renderer = folder.getRenderer(); - if (!(renderer instanceof ICTabFolderRendering)) - return; - - boolean isNoneRender = (Boolean) engine.convert(value, Boolean.class, - null); - if (ICathyConstants.PROPERTY_CTABFOLDER_RENDER_NONE.equals(property)) { - ((ICTabFolderRendering) renderer).setNoneRender(isNoneRender); - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyCTabFolderRenderNoneHandler + extends AbstractCSSPropertySWTHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyCTabFolderRenderNoneHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + CTabFolder folder = (CTabFolder) control; + CTabFolderRenderer renderer = folder.getRenderer(); + if (!(renderer instanceof ICTabFolderRendering)) + return; + + boolean isNoneRender = (Boolean) engine.convert(value, Boolean.class, + null); + if (ICathyConstants.PROPERTY_CTABFOLDER_RENDER_NONE.equals(property)) { + ((ICTabFolderRendering) renderer).setNoneRender(isNoneRender); + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderToolBarSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderToolBarSWTHandler.java index f78f2ad6a..6767ea493 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderToolBarSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyCTabFolderToolBarSWTHandler.java @@ -1,81 +1,81 @@ -package org.xmind.cathy.internal.css; - -import java.lang.reflect.Method; -import java.net.URL; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyCTabFolderToolBarSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyCTabFolderToolBarSWTHandler(); - - private static final String METHOD_SET_CHEVRON_VISIBLE = "setChevronVisible"; //$NON-NLS-1$ - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - CTabFolder folder = (CTabFolder) control; - CTabFolderRenderer renderer = folder.getRenderer(); - if (!(renderer instanceof ICTabFolderRendering)) - return; - - ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; - - Image image = null; - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - if (((CSSPrimitiveValue) value) - .getPrimitiveType() == CSSPrimitiveValue.CSS_URI) { - String imageUrl = ((CSSPrimitiveValue) value).getStringValue(); - ImageDescriptor imageDescriptor = ImageDescriptor - .createFromURL(new URL(imageUrl.toString())); - image = JFaceResources.getResources() - .createImage(imageDescriptor); - } - } - - if (ICathyConstants.PROPERTY_MAXIMIZE_IMAGE.equals(property)) { - tabFolderRendering.setMaximizeImage(image); - } else if (ICathyConstants.PROPERTY_MINIMIZE_IMAGE.equals(property)) { - tabFolderRendering.setMinimizeImage(image); - } else if (ICathyConstants.PROPERTY_CLOSE_IMAGE.equals(property)) { - tabFolderRendering.setCloseImage(image); - } else - if (ICathyConstants.PROPERTY_CLOSE_HOVER_IMAGE.equals(property)) { - tabFolderRendering.setClsoeHoverImage(image); - } else if (ICathyConstants.PROPERTY_CHEVRON_VISIBLE.equals(property)) { - ReflectionSupport reflect = new ReflectionSupport( - CTabFolder.class); - boolean chevronVisible = (Boolean) engine.convert(value, - Boolean.class, null); - Method setChevronVisible = reflect.getMethod( - METHOD_SET_CHEVRON_VISIBLE, - new Class[] { boolean.class }); - reflect.executeMethod(setChevronVisible, folder, - new Object[] { chevronVisible }); - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import java.lang.reflect.Method; +import java.net.URL; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyCTabFolderToolBarSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyCTabFolderToolBarSWTHandler(); + + private static final String METHOD_SET_CHEVRON_VISIBLE = "setChevronVisible"; //$NON-NLS-1$ + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + CTabFolder folder = (CTabFolder) control; + CTabFolderRenderer renderer = folder.getRenderer(); + if (!(renderer instanceof ICTabFolderRendering)) + return; + + ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; + + Image image = null; + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + if (((CSSPrimitiveValue) value) + .getPrimitiveType() == CSSPrimitiveValue.CSS_URI) { + String imageUrl = ((CSSPrimitiveValue) value).getStringValue(); + ImageDescriptor imageDescriptor = ImageDescriptor + .createFromURL(new URL(imageUrl.toString())); + image = JFaceResources.getResources() + .createImage(imageDescriptor); + } + } + + if (ICathyConstants.PROPERTY_MAXIMIZE_IMAGE.equals(property)) { + tabFolderRendering.setMaximizeImage(image); + } else if (ICathyConstants.PROPERTY_MINIMIZE_IMAGE.equals(property)) { + tabFolderRendering.setMinimizeImage(image); + } else if (ICathyConstants.PROPERTY_CLOSE_IMAGE.equals(property)) { + tabFolderRendering.setCloseImage(image); + } else + if (ICathyConstants.PROPERTY_CLOSE_HOVER_IMAGE.equals(property)) { + tabFolderRendering.setClsoeHoverImage(image); + } else if (ICathyConstants.PROPERTY_CHEVRON_VISIBLE.equals(property)) { + ReflectionSupport reflect = new ReflectionSupport( + CTabFolder.class); + boolean chevronVisible = (Boolean) engine.convert(value, + Boolean.class, null); + Method setChevronVisible = reflect.getMethod( + METHOD_SET_CHEVRON_VISIBLE, + new Class[] { boolean.class }); + reflect.executeMethod(setChevronVisible, folder, + new Object[] { chevronVisible }); + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormHeadingHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormHeadingHandler.java index e86175651..04a8a7579 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormHeadingHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormHeadingHandler.java @@ -1,86 +1,86 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.Gradient; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.IFormColors; -import org.eclipse.ui.internal.forms.widgets.FormHeading; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyFormHeadingHandler - extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyFormHeadingHandler INSTANCE = new CSSPropertyFormHeadingHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof FormHeading)) - return; - - FormHeading formHeading = (FormHeading) control; - if (ICathyConstants.PROPERTY_XTEXT_BACKGROUND.equals(property)) { - applyCSSPropertyTextBackgroud(formHeading, value, engine); - } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_1_COLOR - .equals(property)) { - Color keyline1Color = (Color) engine.convert(value, Color.class, - formHeading.getDisplay()); - formHeading.putColor(IFormColors.H_BOTTOM_KEYLINE1, keyline1Color); - - } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_2_COLOR - .equals(property)) { - Color keyline2Color = (Color) engine.convert(value, Color.class, - formHeading.getDisplay()); - formHeading.putColor(IFormColors.H_BOTTOM_KEYLINE2, keyline2Color); - } - - } - - private void applyCSSPropertyTextBackgroud(FormHeading formHeading, - CSSValue value, CSSEngine engine) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - Gradient grad = (Gradient) engine.convert(value, Gradient.class, - formHeading.getDisplay()); - if (grad == null) { - return; - } - Color[] colors = null; - int[] percents = null; - if (!grad.getValues().isEmpty()) { - colors = CSSSWTColorHelper.getSWTColors(grad, - formHeading.getDisplay(), engine); - percents = CSSSWTColorHelper.getPercents(grad); - } - formHeading.setTextBackground(colors, percents, true); - } else if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - formHeading.getDisplay()); - formHeading.setTextBackground(new Color[] { color, color }, - new int[] { 100 }, true); - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - if (control instanceof FormHeading) { - if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_1_COLOR - .equals(property)) { - Color keyline1Color = ((FormHeading) control) - .getColor(IFormColors.H_BOTTOM_KEYLINE1); - return engine.convert(keyline1Color, Color.class, null); - } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_2_COLOR - .equals(property)) { - Color keyline2Color = ((FormHeading) control) - .getColor(IFormColors.H_BOTTOM_KEYLINE2); - return engine.convert(keyline2Color, Color.class, null); - } - } - return null; - } -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.Gradient; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.forms.IFormColors; +import org.eclipse.ui.internal.forms.widgets.FormHeading; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyFormHeadingHandler + extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyFormHeadingHandler INSTANCE = new CSSPropertyFormHeadingHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof FormHeading)) + return; + + FormHeading formHeading = (FormHeading) control; + if (ICathyConstants.PROPERTY_XTEXT_BACKGROUND.equals(property)) { + applyCSSPropertyTextBackgroud(formHeading, value, engine); + } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_1_COLOR + .equals(property)) { + Color keyline1Color = (Color) engine.convert(value, Color.class, + formHeading.getDisplay()); + formHeading.putColor(IFormColors.H_BOTTOM_KEYLINE1, keyline1Color); + + } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_2_COLOR + .equals(property)) { + Color keyline2Color = (Color) engine.convert(value, Color.class, + formHeading.getDisplay()); + formHeading.putColor(IFormColors.H_BOTTOM_KEYLINE2, keyline2Color); + } + + } + + private void applyCSSPropertyTextBackgroud(FormHeading formHeading, + CSSValue value, CSSEngine engine) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + Gradient grad = (Gradient) engine.convert(value, Gradient.class, + formHeading.getDisplay()); + if (grad == null) { + return; + } + Color[] colors = null; + int[] percents = null; + if (!grad.getValues().isEmpty()) { + colors = CSSSWTColorHelper.getSWTColors(grad, + formHeading.getDisplay(), engine); + percents = CSSSWTColorHelper.getPercents(grad); + } + formHeading.setTextBackground(colors, percents, true); + } else if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + formHeading.getDisplay()); + formHeading.setTextBackground(new Color[] { color, color }, + new int[] { 100 }, true); + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + if (control instanceof FormHeading) { + if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_1_COLOR + .equals(property)) { + Color keyline1Color = ((FormHeading) control) + .getColor(IFormColors.H_BOTTOM_KEYLINE1); + return engine.convert(keyline1Color, Color.class, null); + } else if (ICathyConstants.PROPERTY_XBOTTOM_KEYLINE_2_COLOR + .equals(property)) { + Color keyline2Color = ((FormHeading) control) + .getColor(IFormColors.H_BOTTOM_KEYLINE2); + return engine.convert(keyline2Color, Color.class, null); + } + } + return null; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormTextHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormTextHandler.java index f8b0c05b0..3cafbeed8 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormTextHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyFormTextHandler.java @@ -1,48 +1,48 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.HyperlinkSettings; -import org.eclipse.ui.forms.widgets.FormText; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyFormTextHandler extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyFormTextHandler INSTANCE = new CSSPropertyFormTextHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof FormText)) - return; - - FormText formText = (FormText) control; - if (ICathyConstants.PROPERTY_HYPERLINK_COLOR.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color hyperlinkColor = (Color) engine.convert(value, - Color.class, formText.getDisplay()); - HyperlinkSettings hyperlinkSettings = formText - .getHyperlinkSettings(); - hyperlinkSettings.setForeground(hyperlinkColor); - } - } else if (ICathyConstants.PROPERTY_ACTIVE_HYPERLINK_COLOR - .equals(property)) { - Color activeHyperlinkColor = (Color) engine.convert(value, - Color.class, formText.getDisplay()); - formText.getHyperlinkSettings() - .setActiveForeground(activeHyperlinkColor); - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.forms.HyperlinkSettings; +import org.eclipse.ui.forms.widgets.FormText; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyFormTextHandler extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyFormTextHandler INSTANCE = new CSSPropertyFormTextHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof FormText)) + return; + + FormText formText = (FormText) control; + if (ICathyConstants.PROPERTY_HYPERLINK_COLOR.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color hyperlinkColor = (Color) engine.convert(value, + Color.class, formText.getDisplay()); + HyperlinkSettings hyperlinkSettings = formText + .getHyperlinkSettings(); + hyperlinkSettings.setForeground(hyperlinkColor); + } + } else if (ICathyConstants.PROPERTY_ACTIVE_HYPERLINK_COLOR + .equals(property)) { + Color activeHyperlinkColor = (Color) engine.convert(value, + Color.class, formText.getDisplay()); + formText.getHyperlinkSettings() + .setActiveForeground(activeHyperlinkColor); + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyHoverTabSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyHoverTabSWTHandler.java index 9c145429f..b46f7a67a 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyHoverTabSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyHoverTabSWTHandler.java @@ -1,63 +1,63 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.Gradient; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; - -@SuppressWarnings("restriction") -public class CSSPropertyHoverTabSWTHandler extends - AbstractCSSPropertySWTHandler { - - public static final CSSPropertyHoverTabSWTHandler INSTANCE = new CSSPropertyHoverTabSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - - CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); - if (!(renderer instanceof ICTabFolderRendering)) - return; - - ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; - - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - control.getDisplay()); - tabFolderRendering.setHoverTabColor(color); - return; - } - - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - Gradient grad = (Gradient) engine.convert(value, Gradient.class, - control.getDisplay()); - if (grad == null) { - return; - } - Color[] colors = null; - int[] percents = null; - if (!grad.getValues().isEmpty()) { - colors = CSSSWTColorHelper.getSWTColors(grad, - control.getDisplay(), engine); - percents = CSSSWTColorHelper.getPercents(grad); - } - tabFolderRendering.setHoverTabColor(colors, percents); - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.Gradient; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; + +@SuppressWarnings("restriction") +public class CSSPropertyHoverTabSWTHandler extends + AbstractCSSPropertySWTHandler { + + public static final CSSPropertyHoverTabSWTHandler INSTANCE = new CSSPropertyHoverTabSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + + CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); + if (!(renderer instanceof ICTabFolderRendering)) + return; + + ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; + + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + control.getDisplay()); + tabFolderRendering.setHoverTabColor(color); + return; + } + + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + Gradient grad = (Gradient) engine.convert(value, Gradient.class, + control.getDisplay()); + if (grad == null) { + return; + } + Color[] colors = null; + int[] percents = null; + if (!grad.getValues().isEmpty()) { + colors = CSSSWTColorHelper.getSWTColors(grad, + control.getDisplay(), engine); + percents = CSSSWTColorHelper.getPercents(grad); + } + tabFolderRendering.setHoverTabColor(colors, percents); + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabBarHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabBarHandler.java index 5b5c1349d..5f8313526 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabBarHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabBarHandler.java @@ -1,40 +1,40 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.tabfolder.MTabBar; -import org.xmind.ui.tabfolder.MTabFolder; - -@SuppressWarnings("restriction") -public class CSSPropertyMTabBarHandler extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyMTabBarHandler INSTANCE = new CSSPropertyMTabBarHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof MTabBar)) - return; - - MTabBar tabBar = (MTabBar) control; - if (ICathyConstants.PROPERTY_TABFOLDER_BACKGROUND.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - tabBar.getDisplay()); - tabBar.getStyleProvider().setColor(MTabFolder.TAB_BAR, - color.getRGB()); - } - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.ui.tabfolder.MTabBar; +import org.xmind.ui.tabfolder.MTabFolder; + +@SuppressWarnings("restriction") +public class CSSPropertyMTabBarHandler extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyMTabBarHandler INSTANCE = new CSSPropertyMTabBarHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof MTabBar)) + return; + + MTabBar tabBar = (MTabBar) control; + if (ICathyConstants.PROPERTY_TABFOLDER_BACKGROUND.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + tabBar.getDisplay()); + tabBar.getStyleProvider().setColor(MTabFolder.TAB_BAR, + color.getRGB()); + } + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabFolderHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabFolderHandler.java index 26d2c1d5c..f63d757c4 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabFolderHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMTabFolderHandler.java @@ -1,40 +1,40 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.tabfolder.MTabFolder; - -@SuppressWarnings("restriction") -public class CSSPropertyMTabFolderHandler - extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyMTabBarHandler INSTANCE = new CSSPropertyMTabBarHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof MTabFolder)) - return; - - MTabFolder tabFolder = (MTabFolder) control; - if (ICathyConstants.PROPERTY_TABFOLDER_BACKGROUND.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - tabFolder.getDisplay()); - tabFolder.getStyleProvider().setColor(MTabFolder.TAB_BAR, - color.getRGB()); - } - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.ui.tabfolder.MTabFolder; + +@SuppressWarnings("restriction") +public class CSSPropertyMTabFolderHandler + extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyMTabBarHandler INSTANCE = new CSSPropertyMTabBarHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof MTabFolder)) + return; + + MTabFolder tabFolder = (MTabFolder) control; + if (ICathyConstants.PROPERTY_TABFOLDER_BACKGROUND.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + tabFolder.getDisplay()); + tabFolder.getStyleProvider().setColor(MTabFolder.TAB_BAR, + color.getRGB()); + } + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMarginXHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMarginXHandler.java index d39d4f6c3..cd84e0be8 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMarginXHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMarginXHandler.java @@ -1,142 +1,142 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.e4.ui.workbench.renderers.swt.TrimBarLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; -import org.w3c.dom.css.CSSValueList; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyMarginXHandler extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyMarginXHandler INSTANCE = new CSSPropertyMarginXHandler(); - - private final static int TOP = 0; - private final static int RIGHT = 1; - private final static int BOTTOM = 2; - private final static int LEFT = 3; - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof Composite)) - return; - - Composite composite = (Composite) control; - - if (ICathyConstants.PROPERTY_MARGIN.equals(property)) - applyCSSPropertyMargin(composite, value, pseudo, engine); - else if (ICathyConstants.PROPERTY_MARGIN_TOP.equals(property)) - applyCSSPropertyMarginTop(composite, value, pseudo, engine); - else if (ICathyConstants.PROPERTY_MARGIN_RIGHT.equals(property)) - applyCSSPropertyMarginRight(composite, value, pseudo, engine); - else if (ICathyConstants.PROPERTY_MARGIN_BOTTOM.equals(property)) - applyCSSPropertyMarginBottom(composite, value, pseudo, engine); - else if (ICathyConstants.PROPERTY_MARGIN_LEFT.equals(property)) - applyCSSPropertyMarginLeft(composite, value, pseudo, engine); - - } - - public void applyCSSPropertyMargin(Composite element, CSSValue value, - String pseudo, CSSEngine engine) throws Exception { - - // If single value then assigned to all four margins - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - setMargin(element, TOP, value, pseudo); - setMargin(element, RIGHT, value, pseudo); - setMargin(element, BOTTOM, value, pseudo); - setMargin(element, LEFT, value, pseudo); - return; - } - - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - CSSValueList valueList = (CSSValueList) value; - int length = valueList.getLength(); - - if (length < 2 || length > 4) - return; - - switch (length) { - case 4: - // If four values then assigned top/right/bottom/left - setMargin(element, TOP, valueList.item(0), pseudo); - setMargin(element, RIGHT, valueList.item(1), pseudo); - setMargin(element, BOTTOM, valueList.item(2), pseudo); - setMargin(element, LEFT, valueList.item(3), pseudo); - break; - case 3: - // If three values then assigned top=v1, left=v2, right=v2, bottom=v3 - setMargin(element, TOP, valueList.item(0), pseudo); - setMargin(element, RIGHT, valueList.item(1), pseudo); - setMargin(element, BOTTOM, valueList.item(2), pseudo); - setMargin(element, LEFT, valueList.item(1), pseudo); - case 2: - // If two values then assigned top/bottom=v1, left/right=v2 - setMargin(element, TOP, valueList.item(0), pseudo); - setMargin(element, RIGHT, valueList.item(1), pseudo); - setMargin(element, BOTTOM, valueList.item(0), pseudo); - setMargin(element, LEFT, valueList.item(1), pseudo); - } - } - } - - private void applyCSSPropertyMarginTop(Composite element, CSSValue value, - String pseudo, CSSEngine engine) throws Exception { - setMargin(element, TOP, value, pseudo); - } - - private void applyCSSPropertyMarginRight(Composite element, CSSValue value, - String pseudo, CSSEngine engine) throws Exception { - setMargin(element, RIGHT, value, pseudo); - } - - private void applyCSSPropertyMarginBottom(Composite element, CSSValue value, - String pseudo, CSSEngine engine) throws Exception { - setMargin(element, BOTTOM, value, pseudo); - } - - private void applyCSSPropertyMarginLeft(Composite element, CSSValue value, - String pseudo, CSSEngine engine) throws Exception { - setMargin(element, LEFT, value, pseudo); - } - - private void setMargin(Composite composite, int side, CSSValue value, - String pseudo) { - if (value.getCssValueType() != CSSValue.CSS_PRIMITIVE_VALUE) - return; - int pixelValue = (int) ((CSSPrimitiveValue) value) - .getFloatValue(CSSPrimitiveValue.CSS_PX); - - Layout layout = composite.getLayout(); - if (layout == null || !(layout instanceof TrimBarLayout)) - return; - - TrimBarLayout trimBarLayout = (TrimBarLayout) layout; - switch (side) { - case TOP: - trimBarLayout.marginTop = pixelValue; - break; - case RIGHT: - trimBarLayout.marginRight = pixelValue; - break; - case BOTTOM: - trimBarLayout.marginBottom = pixelValue; - break; - case LEFT: - trimBarLayout.marginLeft = pixelValue; - break; - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.e4.ui.workbench.renderers.swt.TrimBarLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; +import org.w3c.dom.css.CSSValueList; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyMarginXHandler extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyMarginXHandler INSTANCE = new CSSPropertyMarginXHandler(); + + private final static int TOP = 0; + private final static int RIGHT = 1; + private final static int BOTTOM = 2; + private final static int LEFT = 3; + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof Composite)) + return; + + Composite composite = (Composite) control; + + if (ICathyConstants.PROPERTY_MARGIN.equals(property)) + applyCSSPropertyMargin(composite, value, pseudo, engine); + else if (ICathyConstants.PROPERTY_MARGIN_TOP.equals(property)) + applyCSSPropertyMarginTop(composite, value, pseudo, engine); + else if (ICathyConstants.PROPERTY_MARGIN_RIGHT.equals(property)) + applyCSSPropertyMarginRight(composite, value, pseudo, engine); + else if (ICathyConstants.PROPERTY_MARGIN_BOTTOM.equals(property)) + applyCSSPropertyMarginBottom(composite, value, pseudo, engine); + else if (ICathyConstants.PROPERTY_MARGIN_LEFT.equals(property)) + applyCSSPropertyMarginLeft(composite, value, pseudo, engine); + + } + + public void applyCSSPropertyMargin(Composite element, CSSValue value, + String pseudo, CSSEngine engine) throws Exception { + + // If single value then assigned to all four margins + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + setMargin(element, TOP, value, pseudo); + setMargin(element, RIGHT, value, pseudo); + setMargin(element, BOTTOM, value, pseudo); + setMargin(element, LEFT, value, pseudo); + return; + } + + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + CSSValueList valueList = (CSSValueList) value; + int length = valueList.getLength(); + + if (length < 2 || length > 4) + return; + + switch (length) { + case 4: + // If four values then assigned top/right/bottom/left + setMargin(element, TOP, valueList.item(0), pseudo); + setMargin(element, RIGHT, valueList.item(1), pseudo); + setMargin(element, BOTTOM, valueList.item(2), pseudo); + setMargin(element, LEFT, valueList.item(3), pseudo); + break; + case 3: + // If three values then assigned top=v1, left=v2, right=v2, bottom=v3 + setMargin(element, TOP, valueList.item(0), pseudo); + setMargin(element, RIGHT, valueList.item(1), pseudo); + setMargin(element, BOTTOM, valueList.item(2), pseudo); + setMargin(element, LEFT, valueList.item(1), pseudo); + case 2: + // If two values then assigned top/bottom=v1, left/right=v2 + setMargin(element, TOP, valueList.item(0), pseudo); + setMargin(element, RIGHT, valueList.item(1), pseudo); + setMargin(element, BOTTOM, valueList.item(0), pseudo); + setMargin(element, LEFT, valueList.item(1), pseudo); + } + } + } + + private void applyCSSPropertyMarginTop(Composite element, CSSValue value, + String pseudo, CSSEngine engine) throws Exception { + setMargin(element, TOP, value, pseudo); + } + + private void applyCSSPropertyMarginRight(Composite element, CSSValue value, + String pseudo, CSSEngine engine) throws Exception { + setMargin(element, RIGHT, value, pseudo); + } + + private void applyCSSPropertyMarginBottom(Composite element, CSSValue value, + String pseudo, CSSEngine engine) throws Exception { + setMargin(element, BOTTOM, value, pseudo); + } + + private void applyCSSPropertyMarginLeft(Composite element, CSSValue value, + String pseudo, CSSEngine engine) throws Exception { + setMargin(element, LEFT, value, pseudo); + } + + private void setMargin(Composite composite, int side, CSSValue value, + String pseudo) { + if (value.getCssValueType() != CSSValue.CSS_PRIMITIVE_VALUE) + return; + int pixelValue = (int) ((CSSPrimitiveValue) value) + .getFloatValue(CSSPrimitiveValue.CSS_PX); + + Layout layout = composite.getLayout(); + if (layout == null || !(layout instanceof TrimBarLayout)) + return; + + TrimBarLayout trimBarLayout = (TrimBarLayout) layout; + switch (side) { + case TOP: + trimBarLayout.marginTop = pixelValue; + break; + case RIGHT: + trimBarLayout.marginRight = pixelValue; + break; + case BOTTOM: + trimBarLayout.marginBottom = pixelValue; + break; + case LEFT: + trimBarLayout.marginLeft = pixelValue; + break; + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMaxMinVisibleSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMaxMinVisibleSWTHandler.java index e4dd60ab4..c87b445fb 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMaxMinVisibleSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyMaxMinVisibleSWTHandler.java @@ -1,108 +1,108 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.w3c.dom.Element; -import org.w3c.dom.css.CSSStyleDeclaration; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyMaxMinVisibleSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyMaxMinVisibleSWTHandler(); - - private static final String CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY = "CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY"; //$NON-NLS-1$ - - @Override - public void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) - return; - - CTabFolder folder = (CTabFolder) control; - boolean visible = (Boolean) engine.convert(value, Boolean.class, null); - - ShowMaxMinVisibleListener listener = (ShowMaxMinVisibleListener) folder - .getData(CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY); - if (listener == null) { - listener = new ShowMaxMinVisibleListener(engine); - folder.addListener(SWT.Paint, listener); - folder.setData(CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY, - listener); - } else { - listener.setEngine(engine); - } - - if (ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE.equals(property)) { - folder.setMaximizeVisible(visible); - } else if (ICathyConstants.PROPERTY_MINIMIZE_VISIBLE.equals(property)) { - folder.setMinimizeVisible(visible); - } - } - - @Override - public String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - if (control instanceof CTabFolder) { - CTabFolder folder = (CTabFolder) control; - if (ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE.equals(property)) { - return Boolean.toString(folder.getMaximizeVisible()); - } else if (ICathyConstants.PROPERTY_MINIMIZE_VISIBLE - .equals(property)) { - return Boolean.toString(folder.getMinimizeVisible()); - } - } - return null; - } - - private class ShowMaxMinVisibleListener implements Listener { - - private CSSEngine engine; - - public ShowMaxMinVisibleListener(CSSEngine engine) { - this.engine = engine; - } - - public void setEngine(CSSEngine engine) { - this.engine = engine; - } - - public void handleEvent(Event e) { - - CTabFolder folder = (CTabFolder) e.widget; - if (folder == null || folder.isDisposed()) { - return; - } - - Element element = engine.getElement(folder); - CSSStyleDeclaration style = engine.getViewCSS() - .getComputedStyle(element, null); - if (style != null) { - CSSValue maximizeVisible = style.getPropertyCSSValue( - ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE); - CSSValue minimizeVisible = style.getPropertyCSSValue( - ICathyConstants.PROPERTY_MINIMIZE_VISIBLE); - if (maximizeVisible != null) { - boolean maxVisible = Boolean - .parseBoolean(maximizeVisible.getCssText()); - if (maxVisible != folder.getMaximizeVisible()) - folder.setMaximizeVisible(maxVisible); - } - if (minimizeVisible != null) { - boolean miniVisible = Boolean - .parseBoolean(minimizeVisible.getCssText()); - if (miniVisible != folder.getMinimizeVisible()) - folder.setMinimizeVisible(miniVisible); - } - } - } - } -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.w3c.dom.Element; +import org.w3c.dom.css.CSSStyleDeclaration; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyMaxMinVisibleSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyMaxMinVisibleSWTHandler(); + + private static final String CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY = "CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY"; //$NON-NLS-1$ + + @Override + public void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) + return; + + CTabFolder folder = (CTabFolder) control; + boolean visible = (Boolean) engine.convert(value, Boolean.class, null); + + ShowMaxMinVisibleListener listener = (ShowMaxMinVisibleListener) folder + .getData(CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY); + if (listener == null) { + listener = new ShowMaxMinVisibleListener(engine); + folder.addListener(SWT.Paint, listener); + folder.setData(CSS_CTABFOLDER_MAXMIN_VISIBLE_LISTENER_KEY, + listener); + } else { + listener.setEngine(engine); + } + + if (ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE.equals(property)) { + folder.setMaximizeVisible(visible); + } else if (ICathyConstants.PROPERTY_MINIMIZE_VISIBLE.equals(property)) { + folder.setMinimizeVisible(visible); + } + } + + @Override + public String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + if (control instanceof CTabFolder) { + CTabFolder folder = (CTabFolder) control; + if (ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE.equals(property)) { + return Boolean.toString(folder.getMaximizeVisible()); + } else if (ICathyConstants.PROPERTY_MINIMIZE_VISIBLE + .equals(property)) { + return Boolean.toString(folder.getMinimizeVisible()); + } + } + return null; + } + + private class ShowMaxMinVisibleListener implements Listener { + + private CSSEngine engine; + + public ShowMaxMinVisibleListener(CSSEngine engine) { + this.engine = engine; + } + + public void setEngine(CSSEngine engine) { + this.engine = engine; + } + + public void handleEvent(Event e) { + + CTabFolder folder = (CTabFolder) e.widget; + if (folder == null || folder.isDisposed()) { + return; + } + + Element element = engine.getElement(folder); + CSSStyleDeclaration style = engine.getViewCSS() + .getComputedStyle(element, null); + if (style != null) { + CSSValue maximizeVisible = style.getPropertyCSSValue( + ICathyConstants.PROPERTY_MAXIMIZE_VISIBLE); + CSSValue minimizeVisible = style.getPropertyCSSValue( + ICathyConstants.PROPERTY_MINIMIZE_VISIBLE); + if (maximizeVisible != null) { + boolean maxVisible = Boolean + .parseBoolean(maximizeVisible.getCssText()); + if (maxVisible != folder.getMaximizeVisible()) + folder.setMaximizeVisible(maxVisible); + } + if (minimizeVisible != null) { + boolean miniVisible = Boolean + .parseBoolean(minimizeVisible.getCssText()); + if (miniVisible != folder.getMinimizeVisible()) + folder.setMinimizeVisible(miniVisible); + } + } + } + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyScrolledFormHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyScrolledFormHandler.java index cbe8215f5..81c557d31 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyScrolledFormHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyScrolledFormHandler.java @@ -1,44 +1,44 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyScrolledFormHandler - extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyScrolledFormHandler INSTANCE = new CSSPropertyScrolledFormHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof ScrolledForm)) - return; - - ScrolledForm form = (ScrolledForm) control; - if (ICathyConstants.PROPERTY_FG_COLOR.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color fgColor = (Color) engine.convert(value, Color.class, - form.getDisplay()); - form.setForeground(fgColor); - } - } else if (ICathyConstants.PROPERTY_BG_COLOR.equals(property)) { - Color bgColor = (Color) engine.convert(value, Color.class, - form.getDisplay()); - form.setBackground(bgColor); - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyScrolledFormHandler + extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyScrolledFormHandler INSTANCE = new CSSPropertyScrolledFormHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof ScrolledForm)) + return; + + ScrolledForm form = (ScrolledForm) control; + if (ICathyConstants.PROPERTY_FG_COLOR.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color fgColor = (Color) engine.convert(value, Color.class, + form.getDisplay()); + form.setForeground(fgColor); + } + } else if (ICathyConstants.PROPERTY_BG_COLOR.equals(property)) { + Color bgColor = (Color) engine.convert(value, Color.class, + form.getDisplay()); + form.setBackground(bgColor); + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySectionHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySectionHandler.java index 45ee76415..2f381997c 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySectionHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySectionHandler.java @@ -1,54 +1,54 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.widgets.Section; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertySectionHandler extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertySectionHandler INSTANCE = new CSSPropertySectionHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof Section)) - return; - - Section section = (Section) control; - if (ICathyConstants.PROPERTY_TITLE_BAR_TEXT_COLOR.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color textColor = (Color) engine.convert(value, Color.class, - section.getDisplay()); - section.setTitleBarForeground(textColor); - section.setToggleColor(textColor); - } - } else if (ICathyConstants.PROPERTY_TITLE_BAR_ACTIVE_TEXT_COLOR - .equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color activeTextColor = (Color) engine.convert(value, - Color.class, section.getDisplay()); - section.setActiveToggleColor(activeTextColor); - } - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - if (control instanceof Section) { - Section section = (Section) control; - if (ICathyConstants.PROPERTY_TITLE_BAR_TEXT_COLOR - .equals(property)) { - Color textColor = section.getTitleBarForeground(); - return engine.convert(textColor, Color.class, null); - } - } - return null; - } -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.forms.widgets.Section; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertySectionHandler extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertySectionHandler INSTANCE = new CSSPropertySectionHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof Section)) + return; + + Section section = (Section) control; + if (ICathyConstants.PROPERTY_TITLE_BAR_TEXT_COLOR.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color textColor = (Color) engine.convert(value, Color.class, + section.getDisplay()); + section.setTitleBarForeground(textColor); + section.setToggleColor(textColor); + } + } else if (ICathyConstants.PROPERTY_TITLE_BAR_ACTIVE_TEXT_COLOR + .equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color activeTextColor = (Color) engine.convert(value, + Color.class, section.getDisplay()); + section.setActiveToggleColor(activeTextColor); + } + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + if (control instanceof Section) { + Section section = (Section) control; + if (ICathyConstants.PROPERTY_TITLE_BAR_TEXT_COLOR + .equals(property)) { + Color textColor = section.getTitleBarForeground(); + return engine.convert(textColor, Color.class, null); + } + } + return null; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySelectedTabAreaSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySelectedTabAreaSWTHandler.java index d99e5d022..0c37a5b44 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySelectedTabAreaSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertySelectedTabAreaSWTHandler.java @@ -1,63 +1,63 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.Gradient; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; - -@SuppressWarnings("restriction") -public class CSSPropertySelectedTabAreaSWTHandler extends - AbstractCSSPropertySWTHandler { - - public static final CSSPropertySelectedTabAreaSWTHandler INSTANCE = new CSSPropertySelectedTabAreaSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - - CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); - if (!(renderer instanceof ICTabFolderRendering)) - return; - - ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; - - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - control.getDisplay()); - tabFolderRendering.setSelectedTabAreaColor(color); - return; - } - - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - Gradient grad = (Gradient) engine.convert(value, Gradient.class, - control.getDisplay()); - if (grad == null) { - return; - } - Color[] colors = null; - int[] percents = null; - if (!grad.getValues().isEmpty()) { - colors = CSSSWTColorHelper.getSWTColors(grad, - control.getDisplay(), engine); - percents = CSSSWTColorHelper.getPercents(grad); - } - tabFolderRendering.setSelectedTabAreaColor(colors, percents); - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.Gradient; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; + +@SuppressWarnings("restriction") +public class CSSPropertySelectedTabAreaSWTHandler extends + AbstractCSSPropertySWTHandler { + + public static final CSSPropertySelectedTabAreaSWTHandler INSTANCE = new CSSPropertySelectedTabAreaSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + + CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); + if (!(renderer instanceof ICTabFolderRendering)) + return; + + ICTabFolderRendering tabFolderRendering = (ICTabFolderRendering) renderer; + + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + control.getDisplay()); + tabFolderRendering.setSelectedTabAreaColor(color); + return; + } + + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + Gradient grad = (Gradient) engine.convert(value, Gradient.class, + control.getDisplay()); + if (grad == null) { + return; + } + Color[] colors = null; + int[] percents = null; + if (!grad.getValues().isEmpty()) { + colors = CSSSWTColorHelper.getSWTColors(grad, + control.getDisplay(), engine); + percents = CSSSWTColorHelper.getPercents(grad); + } + tabFolderRendering.setSelectedTabAreaColor(colors, percents); + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabBorderVisibleSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabBorderVisibleSWTHandler.java index 95fcad352..b488c052f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabBorderVisibleSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabBorderVisibleSWTHandler.java @@ -1,47 +1,47 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyTabBorderVisibleSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyTabBorderVisibleSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - boolean borderVisible = (Boolean) engine.convert(value, Boolean.class, - null); - CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); - if (renderer instanceof ICTabFolderRendering) { - if (ICathyConstants.PROPERTY_OUTER_BORDER_VISIBLE - .equals(property)) { - ((ICTabFolderRendering) renderer) - .setOuterBorderVisible(borderVisible); - } else if (ICathyConstants.PROPERTY_INNER_BORDER_VISIBLE - .equals(property)) { - ((ICTabFolderRendering) renderer) - .setInnerBorderVisible(borderVisible); - } - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyTabBorderVisibleSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyTabBorderVisibleSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + boolean borderVisible = (Boolean) engine.convert(value, Boolean.class, + null); + CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); + if (renderer instanceof ICTabFolderRendering) { + if (ICathyConstants.PROPERTY_OUTER_BORDER_VISIBLE + .equals(property)) { + ((ICTabFolderRendering) renderer) + .setOuterBorderVisible(borderVisible); + } else if (ICathyConstants.PROPERTY_INNER_BORDER_VISIBLE + .equals(property)) { + ((ICTabFolderRendering) renderer) + .setInnerBorderVisible(borderVisible); + } + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabIconTextVisibleSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabIconTextVisibleSWTHandler.java index e2dd8cd22..df52fd81b 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabIconTextVisibleSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyTabIconTextVisibleSWTHandler.java @@ -1,41 +1,41 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyTabIconTextVisibleSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyTabIconTextVisibleSWTHandler INSTANCE = new CSSPropertyTabIconTextVisibleSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - boolean visible = (Boolean) engine.convert(value, Boolean.class, null); - CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); - if (renderer instanceof ICTabFolderRendering) { - if (ICathyConstants.PROPERTY_IMAGE_VISIBLE.equals(property)) { - ((ICTabFolderRendering) renderer).setImageVisible(visible); - } else if (ICathyConstants.PROPERTY_TEXT_VISIBLE.equals(property)) { - ((ICTabFolderRendering) renderer).setTextVisible(visible); - } - } - - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyTabIconTextVisibleSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyTabIconTextVisibleSWTHandler INSTANCE = new CSSPropertyTabIconTextVisibleSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + boolean visible = (Boolean) engine.convert(value, Boolean.class, null); + CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); + if (renderer instanceof ICTabFolderRendering) { + if (ICathyConstants.PROPERTY_IMAGE_VISIBLE.equals(property)) { + ((ICTabFolderRendering) renderer).setImageVisible(visible); + } else if (ICathyConstants.PROPERTY_TEXT_VISIBLE.equals(property)) { + ((ICTabFolderRendering) renderer).setTextVisible(visible); + } + } + + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyToolBarSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyToolBarSWTHandler.java index 18ace44bf..1ad346acc 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyToolBarSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyToolBarSWTHandler.java @@ -1,87 +1,87 @@ -package org.xmind.cathy.internal.css; - -import java.net.URL; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyToolBarSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final CSSPropertyToolBarSWTHandler INSTANCE = new CSSPropertyToolBarSWTHandler(); - - private static final String TOOLBAR_TAG_VIEW_MENU = "ViewMenu"; //$NON-NLS-1$ - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof ToolBar)) - return; - - ToolBar toolBar = (ToolBar) control; - if (ICathyConstants.PROPERTY_TOOL_ITEM_COLOR.equals(property)) { - Color color = (Color) engine.convert(value, Color.class, - toolBar.getDisplay()); - toolBar.setForeground(color); - - ToolItem[] items = toolBar.getItems(); - for (ToolItem each : items) { - String text = each.getText(); - each.setText(text); - } - } else if (ICathyConstants.PROPERTY_VIEW_MENU.equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - if (((CSSPrimitiveValue) value) - .getPrimitiveType() == CSSPrimitiveValue.CSS_URI) { - String imageUrl = ((CSSPrimitiveValue) value) - .getStringValue(); - ImageDescriptor imageDescriptor = ImageDescriptor - .createFromURL(new URL(imageUrl.toString())); - Image image = JFaceResources.getResources() - .createImage(imageDescriptor); - if (TOOLBAR_TAG_VIEW_MENU.equals(toolBar.getData())) { - toolBar.getItem(0).setImage(image); - } - - } - } - } -// else if ("xswt-view-properties-pin".equals(property)) { -// ToolItem[] items = toolBar.getItems(); -// for (ToolItem each : items) { -// Object data = each.getData(); -// if (data instanceof ActionContributionItem) { -// String id = ((ActionContributionItem) data).getId(); -// if (id.contains("org.eclipse.ui.views.properties.PinPropertySheetAction")) { -// -// } -// } -// } -// } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - if (control instanceof ToolBar) { - if (ICathyConstants.PROPERTY_TOOL_ITEM_COLOR.equals(property)) { - Color fgColor = ((ToolBar) control).getForeground(); - return engine.convert(fgColor, Color.class, null); - } - - } - return null; - } - -} +package org.xmind.cathy.internal.css; + +import java.net.URL; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyToolBarSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final CSSPropertyToolBarSWTHandler INSTANCE = new CSSPropertyToolBarSWTHandler(); + + private static final String TOOLBAR_TAG_VIEW_MENU = "ViewMenu"; //$NON-NLS-1$ + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof ToolBar)) + return; + + ToolBar toolBar = (ToolBar) control; + if (ICathyConstants.PROPERTY_TOOL_ITEM_COLOR.equals(property)) { + Color color = (Color) engine.convert(value, Color.class, + toolBar.getDisplay()); + toolBar.setForeground(color); + + ToolItem[] items = toolBar.getItems(); + for (ToolItem each : items) { + String text = each.getText(); + each.setText(text); + } + } else if (ICathyConstants.PROPERTY_VIEW_MENU.equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + if (((CSSPrimitiveValue) value) + .getPrimitiveType() == CSSPrimitiveValue.CSS_URI) { + String imageUrl = ((CSSPrimitiveValue) value) + .getStringValue(); + ImageDescriptor imageDescriptor = ImageDescriptor + .createFromURL(new URL(imageUrl.toString())); + Image image = JFaceResources.getResources() + .createImage(imageDescriptor); + if (TOOLBAR_TAG_VIEW_MENU.equals(toolBar.getData())) { + toolBar.getItem(0).setImage(image); + } + + } + } + } +// else if ("xswt-view-properties-pin".equals(property)) { +// ToolItem[] items = toolBar.getItems(); +// for (ToolItem each : items) { +// Object data = each.getData(); +// if (data instanceof ActionContributionItem) { +// String id = ((ActionContributionItem) data).getId(); +// if (id.contains("org.eclipse.ui.views.properties.PinPropertySheetAction")) { +// +// } +// } +// } +// } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + if (control instanceof ToolBar) { + if (ICathyConstants.PROPERTY_TOOL_ITEM_COLOR.equals(property)) { + Color fgColor = ((ToolBar) control).getForeground(); + return engine.convert(fgColor, Color.class, null); + } + + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsColorSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsColorSWTHandler.java index fc7aa2ac5..41d5d59b9 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsColorSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsColorSWTHandler.java @@ -1,126 +1,126 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.Gradient; -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.e4.ui.internal.css.swt.ICTabRendering; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyUnselectedTabsColorSWTHandler - extends AbstractCSSPropertySWTHandler { - - private static final String RESIZE_LISTENER = "CSSPropertyUnselectedTabsColorSWTHandler.resizeListener"; //$NON-NLS-1$ - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyUnselectedTabsColorSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder) - || !isUnselectedTabsColorProp(property)) { - return; - } - CTabFolder folder = ((CTabFolder) control); - CTabFolderRenderer renderer = folder.getRenderer(); - if (!(renderer instanceof ICTabRendering)) { - return; - } - - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - Color color = (Color) engine.convert(value, Color.class, - control.getDisplay()); - ((ICTabRendering) renderer).setUnselectedTabsColor(color); - folder.setBackground(null); - removeResizeEventListener(folder); - return; - } - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - Gradient grad = (Gradient) engine.convert(value, Gradient.class, - control.getDisplay()); - if (grad == null) { - return; - } - Color[] colors = null; - int[] percents = null; - if (!grad.getValues().isEmpty()) { - colors = CSSSWTColorHelper.getSWTColors(grad, - control.getDisplay(), engine); - percents = CSSSWTColorHelper.getPercents(grad); - } - ((ICTabRendering) renderer).setUnselectedTabsColor(colors, - percents); - folder.setBackground(null, null, false); - appendResizeEventListener(folder); - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - - private boolean isUnselectedTabsColorProp(String property) { - return ICathyConstants.PROPERTY_UNSELECTED_TABS_COLOR.equals(property); - } - - // TODO: It needs to be refactored when the Bug 33276 gets fixed - private void appendResizeEventListener(CTabFolder folder) { - if (hasResizeEventListener(folder)) { - return; - } - - final Listener resizeListener = new Listener() { - public void handleEvent(Event event) { - CTabFolder folder = (CTabFolder) event.widget; - for (Control child : folder.getChildren()) { - if (isReskinRequired(child)) { - child.reskin(SWT.NONE); - } - } - } - }; - - folder.addListener(SWT.Resize, resizeListener); - folder.setData(RESIZE_LISTENER, resizeListener); - folder.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - e.widget.removeListener(SWT.Resize, resizeListener); - } - }); - } - - private void removeResizeEventListener(CTabFolder folder) { - Object obj = folder.getData(RESIZE_LISTENER); - if (obj instanceof Listener) { - folder.removeListener(SWT.Resize, (Listener) obj); - folder.setData(RESIZE_LISTENER, null); - } - } - - private boolean hasResizeEventListener(CTabFolder folder) { - return folder.getData(RESIZE_LISTENER) instanceof Listener; - } - - private boolean isReskinRequired(Control control) { - if (control instanceof Composite) { - Composite composite = (Composite) control; - return composite.isVisible() && composite.getChildren().length > 0; - } - return false; - } -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.Gradient; +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.e4.ui.internal.css.swt.ICTabRendering; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyUnselectedTabsColorSWTHandler + extends AbstractCSSPropertySWTHandler { + + private static final String RESIZE_LISTENER = "CSSPropertyUnselectedTabsColorSWTHandler.resizeListener"; //$NON-NLS-1$ + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyUnselectedTabsColorSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder) + || !isUnselectedTabsColorProp(property)) { + return; + } + CTabFolder folder = ((CTabFolder) control); + CTabFolderRenderer renderer = folder.getRenderer(); + if (!(renderer instanceof ICTabRendering)) { + return; + } + + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + Color color = (Color) engine.convert(value, Color.class, + control.getDisplay()); + ((ICTabRendering) renderer).setUnselectedTabsColor(color); + folder.setBackground(null); + removeResizeEventListener(folder); + return; + } + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + Gradient grad = (Gradient) engine.convert(value, Gradient.class, + control.getDisplay()); + if (grad == null) { + return; + } + Color[] colors = null; + int[] percents = null; + if (!grad.getValues().isEmpty()) { + colors = CSSSWTColorHelper.getSWTColors(grad, + control.getDisplay(), engine); + percents = CSSSWTColorHelper.getPercents(grad); + } + ((ICTabRendering) renderer).setUnselectedTabsColor(colors, + percents); + folder.setBackground(null, null, false); + appendResizeEventListener(folder); + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + + private boolean isUnselectedTabsColorProp(String property) { + return ICathyConstants.PROPERTY_UNSELECTED_TABS_COLOR.equals(property); + } + + // TODO: It needs to be refactored when the Bug 33276 gets fixed + private void appendResizeEventListener(CTabFolder folder) { + if (hasResizeEventListener(folder)) { + return; + } + + final Listener resizeListener = new Listener() { + public void handleEvent(Event event) { + CTabFolder folder = (CTabFolder) event.widget; + for (Control child : folder.getChildren()) { + if (isReskinRequired(child)) { + child.reskin(SWT.NONE); + } + } + } + }; + + folder.addListener(SWT.Resize, resizeListener); + folder.setData(RESIZE_LISTENER, resizeListener); + folder.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + e.widget.removeListener(SWT.Resize, resizeListener); + } + }); + } + + private void removeResizeEventListener(CTabFolder folder) { + Object obj = folder.getData(RESIZE_LISTENER); + if (obj instanceof Listener) { + folder.removeListener(SWT.Resize, (Listener) obj); + folder.setData(RESIZE_LISTENER, null); + } + } + + private boolean hasResizeEventListener(CTabFolder folder) { + return folder.getData(RESIZE_LISTENER) instanceof Listener; + } + + private boolean isReskinRequired(Control control) { + if (control instanceof Composite) { + Composite composite = (Composite) control; + return composite.isVisible() && composite.getChildren().length > 0; + } + return false; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsFillVisibleSWTHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsFillVisibleSWTHandler.java index 432c14aff..317e78c0b 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsFillVisibleSWTHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyUnselectedTabsFillVisibleSWTHandler.java @@ -1,43 +1,43 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyUnselectedTabsFillVisibleSWTHandler - extends AbstractCSSPropertySWTHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyUnselectedTabsFillVisibleSWTHandler(); - - @Override - protected void applyCSSProperty(Control control, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(control instanceof CTabFolder)) { - return; - } - boolean unselectedTabsBackgroundVisible = (Boolean) engine - .convert(value, Boolean.class, null); - CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); - if (renderer instanceof ICTabFolderRendering) { - if (ICathyConstants.PROPERTY_UNSELECTED_TABS_BG_VISIBLE - .equals(property)) { - ((ICTabFolderRendering) renderer) - .setUnselectedTabsBackgroundVisible( - unselectedTabsBackgroundVisible); - } - } - } - - @Override - protected String retrieveCSSProperty(Control control, String property, - String pseudo, CSSEngine engine) throws Exception { - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyUnselectedTabsFillVisibleSWTHandler + extends AbstractCSSPropertySWTHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyUnselectedTabsFillVisibleSWTHandler(); + + @Override + protected void applyCSSProperty(Control control, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(control instanceof CTabFolder)) { + return; + } + boolean unselectedTabsBackgroundVisible = (Boolean) engine + .convert(value, Boolean.class, null); + CTabFolderRenderer renderer = ((CTabFolder) control).getRenderer(); + if (renderer instanceof ICTabFolderRendering) { + if (ICathyConstants.PROPERTY_UNSELECTED_TABS_BG_VISIBLE + .equals(property)) { + ((ICTabFolderRendering) renderer) + .setUnselectedTabsBackgroundVisible( + unselectedTabsBackgroundVisible); + } + } + } + + @Override + protected String retrieveCSSProperty(Control control, String property, + String pseudo, CSSEngine engine) throws Exception { + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyXShowCloseHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyXShowCloseHandler.java index 9f0194e54..9ed11430d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyXShowCloseHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CSSPropertyXShowCloseHandler.java @@ -1,149 +1,149 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers; -import org.eclipse.e4.ui.css.swt.properties.custom.CTabETabHelper; -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Widget; -import org.w3c.dom.css.CSSStyleDeclaration; -import org.w3c.dom.css.CSSValue; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CSSPropertyXShowCloseHandler extends CTabETabHelper - implements ICSSPropertyHandler { - - public static final ICSSPropertyHandler INSTANCE = new CSSPropertyXShowCloseHandler(); - - private static final String CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY = "CSS_CTABFOLDER_SELECTED_SHOW_CLOSE_LISTENER_KEY"; //$NON-NLS-1$ - - private static final String SUPPORTED_PSEUDO = "selected"; //$NON-NLS-1$ - - private static final String TAG_NOCLOSE = "NoClose"; //$NON-NLS-1$ - - public boolean applyCSSProperty(Object element, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - Widget widget = SWTElementHelpers.getWidget(element); - if (widget instanceof CTabItem) { - Item item = (Item) widget; - boolean showClose = ((Boolean) engine.convert(value, Boolean.class, - null)).booleanValue(); - - if (SUPPORTED_PSEUDO.equals(pseudo)) { - Control parent = getParent(widget); - - ShowCloseSelectionListener listener = (ShowCloseSelectionListener) parent - .getData(CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY); - if (listener == null) { - listener = new ShowCloseSelectionListener(engine); - parent.addListener(SWT.Paint, listener); - parent.setData( - CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY, - listener); - } else { - listener.setEngine(engine); - } - item = getSelection(getParent(widget)); - - if (item != null) { - internalSetShowClose(item, showClose); - } - } else { - internalSetShowClose(item, showClose); - } - return true; - } - return false; - } - - public String retrieveCSSProperty(Object element, String property, - String pseudo, CSSEngine engine) throws Exception { - Widget widget = SWTElementHelpers.getWidget(element); - if (widget instanceof CTabItem) { - CTabItem item = (CTabItem) widget; - return Boolean.toString(item.getShowClose()); - } - return null; - } - - private class ShowCloseSelectionListener implements Listener { - - private CSSEngine engine; - - public ShowCloseSelectionListener(CSSEngine engine) { - this.engine = engine; - } - - public void setEngine(CSSEngine engine) { - this.engine = engine; - } - - public void handleEvent(Event e) { - - Item selection = getSelection(e.widget); - - if (selection == null || selection.isDisposed()) { - return; - } - - Item[] items = getItems(e.widget); - int selectionIndex = getSelectionIndex(e.widget); - - boolean selectionSet = false; - - CSSStyleDeclaration selectedStyle = engine.getViewCSS() - .getComputedStyle(engine.getElement(selection), - SUPPORTED_PSEUDO); - if (selectedStyle != null) { - CSSValue value = selectedStyle.getPropertyCSSValue( - ICathyConstants.PROPERTY_SHOW_CLOSE); - if (value != null) { - internalSetShowClose(selection, - Boolean.parseBoolean(value.getCssText())); - selectionSet = true; - } - } - - CSSStyleDeclaration unselectedStyle = engine.getViewCSS() - .getComputedStyle(engine.getElement(selection), null); - if (unselectedStyle == null) { - for (int i = 0; i < items.length; i++) { - if (selectionSet && i != selectionIndex) { - internalSetShowClose(items[i], false); - } - } - } else { - CSSValue value = unselectedStyle.getPropertyCSSValue( - ICathyConstants.PROPERTY_SHOW_CLOSE); - boolean unselectedShowClose = value == null ? false - : Boolean.parseBoolean(value.getCssText()); - for (int i = 0; i < items.length; i++) { - if (selectionSet && i != selectionIndex) { - internalSetShowClose(items[i], unselectedShowClose); - } - } - } - - } - } - - private void internalSetShowClose(Item item, boolean showClose) { - Object data = item.getData(AbstractPartRenderer.OWNING_ME); - if (data instanceof MUIElement) { - boolean noClose = ((MUIElement) data).getTags() - .contains(TAG_NOCLOSE); - if (noClose) - showClose = !noClose; - } - if (item instanceof CTabItem) - ((CTabItem) item).setShowClose(showClose); - } -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers; +import org.eclipse.e4.ui.css.swt.properties.custom.CTabETabHelper; +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Widget; +import org.w3c.dom.css.CSSStyleDeclaration; +import org.w3c.dom.css.CSSValue; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CSSPropertyXShowCloseHandler extends CTabETabHelper + implements ICSSPropertyHandler { + + public static final ICSSPropertyHandler INSTANCE = new CSSPropertyXShowCloseHandler(); + + private static final String CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY = "CSS_CTABFOLDER_SELECTED_SHOW_CLOSE_LISTENER_KEY"; //$NON-NLS-1$ + + private static final String SUPPORTED_PSEUDO = "selected"; //$NON-NLS-1$ + + private static final String TAG_NOCLOSE = "NoClose"; //$NON-NLS-1$ + + public boolean applyCSSProperty(Object element, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + Widget widget = SWTElementHelpers.getWidget(element); + if (widget instanceof CTabItem) { + Item item = (Item) widget; + boolean showClose = ((Boolean) engine.convert(value, Boolean.class, + null)).booleanValue(); + + if (SUPPORTED_PSEUDO.equals(pseudo)) { + Control parent = getParent(widget); + + ShowCloseSelectionListener listener = (ShowCloseSelectionListener) parent + .getData(CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY); + if (listener == null) { + listener = new ShowCloseSelectionListener(engine); + parent.addListener(SWT.Paint, listener); + parent.setData( + CSS_CTABITEM_SELECTED_SHOW_CLOSE_LISTENER_KEY, + listener); + } else { + listener.setEngine(engine); + } + item = getSelection(getParent(widget)); + + if (item != null) { + internalSetShowClose(item, showClose); + } + } else { + internalSetShowClose(item, showClose); + } + return true; + } + return false; + } + + public String retrieveCSSProperty(Object element, String property, + String pseudo, CSSEngine engine) throws Exception { + Widget widget = SWTElementHelpers.getWidget(element); + if (widget instanceof CTabItem) { + CTabItem item = (CTabItem) widget; + return Boolean.toString(item.getShowClose()); + } + return null; + } + + private class ShowCloseSelectionListener implements Listener { + + private CSSEngine engine; + + public ShowCloseSelectionListener(CSSEngine engine) { + this.engine = engine; + } + + public void setEngine(CSSEngine engine) { + this.engine = engine; + } + + public void handleEvent(Event e) { + + Item selection = getSelection(e.widget); + + if (selection == null || selection.isDisposed()) { + return; + } + + Item[] items = getItems(e.widget); + int selectionIndex = getSelectionIndex(e.widget); + + boolean selectionSet = false; + + CSSStyleDeclaration selectedStyle = engine.getViewCSS() + .getComputedStyle(engine.getElement(selection), + SUPPORTED_PSEUDO); + if (selectedStyle != null) { + CSSValue value = selectedStyle.getPropertyCSSValue( + ICathyConstants.PROPERTY_SHOW_CLOSE); + if (value != null) { + internalSetShowClose(selection, + Boolean.parseBoolean(value.getCssText())); + selectionSet = true; + } + } + + CSSStyleDeclaration unselectedStyle = engine.getViewCSS() + .getComputedStyle(engine.getElement(selection), null); + if (unselectedStyle == null) { + for (int i = 0; i < items.length; i++) { + if (selectionSet && i != selectionIndex) { + internalSetShowClose(items[i], false); + } + } + } else { + CSSValue value = unselectedStyle.getPropertyCSSValue( + ICathyConstants.PROPERTY_SHOW_CLOSE); + boolean unselectedShowClose = value == null ? false + : Boolean.parseBoolean(value.getCssText()); + for (int i = 0; i < items.length; i++) { + if (selectionSet && i != selectionIndex) { + internalSetShowClose(items[i], unselectedShowClose); + } + } + } + + } + } + + private void internalSetShowClose(Item item, boolean showClose) { + Object data = item.getData(AbstractPartRenderer.OWNING_ME); + if (data instanceof MUIElement) { + boolean noClose = ((MUIElement) data).getTags() + .contains(TAG_NOCLOSE); + if (noClose) + showClose = !noClose; + } + if (item instanceof CTabItem) + ((CTabItem) item).setShowClose(showClose); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CathyCTabFolderRendering.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CathyCTabFolderRendering.java index 5c180f592..61e542bf6 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CathyCTabFolderRendering.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/CathyCTabFolderRendering.java @@ -1,1951 +1,1952 @@ -package org.xmind.cathy.internal.css; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import javax.inject.Inject; - -import org.eclipse.e4.ui.css.swt.dom.CTabFolderElement; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.Region; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.ToolBar; -import org.xmind.cathy.internal.ICathyConstants; - -@SuppressWarnings("restriction") -public class CathyCTabFolderRendering extends CTabFolderRenderer - implements ICTabFolderRendering { - private static final String CONTAINS_TOOLBAR = "CathyCTabFolderRendering.containsToolbar"; //$NON-NLS-1$ - - // Constants for circle drawing - final static int LEFT_TOP = 0; - final static int LEFT_BOTTOM = 1; - final static int RIGHT_TOP = 2; - final static int RIGHT_BOTTOM = 3; - - // drop shadow constants - final static int SIDE_DROP_WIDTH = 3; - final static int BOTTOM_DROP_WIDTH = 4; - - // keylines - final static int OUTER_KEYLINE = 1; - final static int INNER_KEYLINE = 0; - final static int TOP_KEYLINE = 0; - - // Item Constants - static final int ITEM_TOP_MARGIN = 2; - static final int ITEM_BOTTOM_MARGIN = 6; - static final int ITEM_LEFT_MARGIN = 8; - static final int ITEM_RIGHT_MARGIN = 4; - static final int INTERNAL_SPACING = 4; - - static final int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC; - static final String ELLIPSIS = "..."; //$NON-NLS-1$ - static final String E4_TOOLBAR_ACTIVE_IMAGE = "org.eclipse.e4.renderer.toolbar_background_active_image"; //$NON-NLS-1$ - static final String E4_TOOLBAR_INACTIVE_IMAGE = "org.eclipse.e4.renderer.toolbar_background_inactive_image"; //$NON-NLS-1$ - - static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW; - static final int BUTTON_SIZE = 16; - - static final RGB CLOSE_FILL = new RGB(252, 160, 160); - - private Color closeFillColor; - - int[] shape; - - Image shadowImage, toolbarActiveImage, toolbarInactiveImage; - - int cornerSize = 14; - - //The best value - boolean shadowEnabled = true; - Color shadowColor; - Color outerKeyline, innerKeyline; - Color[] activeToolbar; - int[] activePercents; - Color[] inactiveToolbar; - int[] inactivePercents; - boolean active; - - Color[] selectedTabFillColors; - int[] selectedTabFillPercents; - - Color[] selectedTabAreaColors; - int[] selectedTabAreaPercents; - - Color[] unselectedTabsColors; - int[] unselectedTabsPercents; - - Color[] hoverTabColors; - int[] hoverTabPercents; - - Color tabOutlineColor; - - int paddingLeft = 2, paddingRight = 2, paddingTop = 2, paddingBottom = 2; - - private CTabFolderRendererWrapper rendererWrapper; - private CTabFolderWrapper parentWrapper; - - private boolean textVisible = true; - - private boolean imageVisible = true; - - private boolean outerBorderVisible = true; - private boolean innerBorderVisible = true; - - private boolean unselectedTabsBackgroundVisible = true; - - private Image maxImage; - - private Image minImage; - - private Image closeImage; - - private Image closeHoverImage; - - private int[] tabArea; - - //temp - private boolean hoverBorderVisible = false; - - private boolean nothingToRender = false; - - @Inject - public CathyCTabFolderRendering(CTabFolder parent) { - super(parent); - parentWrapper = new CTabFolderWrapper(parent); - rendererWrapper = new CTabFolderRendererWrapper(this); - } - - @Override - protected Rectangle computeTrim(int part, int state, int x, int y, - int width, int height) { - if (!nothingToRender) { - boolean onBottom = isTabOnBottom(); - int borderTop = onBottom ? INNER_KEYLINE + OUTER_KEYLINE - : TOP_KEYLINE + OUTER_KEYLINE; - int borderBottom = onBottom ? TOP_KEYLINE + OUTER_KEYLINE - : INNER_KEYLINE + OUTER_KEYLINE; - int marginWidth = parent.marginWidth; - int marginHeight = parent.marginHeight; - int sideDropWidth = shadowEnabled ? SIDE_DROP_WIDTH : 0; - int bottomDropWidth = shadowEnabled ? BOTTOM_DROP_WIDTH : 0; - int headerBorderBottom = outerBorderVisible ? OUTER_KEYLINE : 0; - switch (part) { - //body trimmed + body client area - case PART_BODY: - if (state == SWT.FILL) { - x = x - paddingLeft - sideDropWidth - - (INNER_KEYLINE + OUTER_KEYLINE) - marginWidth; - int tabHeight = parent.getTabHeight() + 1; - y = onBottom - ? y - paddingTop - marginHeight - borderTop - - bottomDropWidth - : y - paddingTop - marginHeight - tabHeight - - borderTop - headerBorderBottom - - bottomDropWidth; - width = 2 * (INNER_KEYLINE + OUTER_KEYLINE) + paddingLeft - + paddingRight + 2 * sideDropWidth - + 2 * marginWidth; - height += paddingTop + paddingBottom + bottomDropWidth; - height += tabHeight + headerBorderBottom + borderBottom - + borderTop; - } else { - x = x - marginWidth - OUTER_KEYLINE - INNER_KEYLINE - - sideDropWidth - (cornerSize / 2) - paddingLeft; - width = width + 2 * OUTER_KEYLINE + 2 * INNER_KEYLINE - + 2 * marginWidth + 2 * sideDropWidth + cornerSize - + paddingRight + paddingLeft; - int tabHeight = parent.getTabHeight() + 1; - if (parent.getMinimized()) { - y = onBottom ? y - borderTop - 5 - : y - tabHeight - borderTop - 5; - height = borderTop + borderBottom + tabHeight; - } else { - y = onBottom - ? y - marginHeight - borderTop - paddingTop - - bottomDropWidth - : y - marginHeight - tabHeight - borderTop - - paddingTop - headerBorderBottom - - bottomDropWidth; - height = height + borderBottom + borderTop - + 2 * marginHeight + tabHeight - + headerBorderBottom + bottomDropWidth - + paddingTop + paddingBottom; - } - } - break; - case PART_HEADER: - x = x - (INNER_KEYLINE + OUTER_KEYLINE) - marginWidth - - sideDropWidth; - width = width + 2 * (INNER_KEYLINE + OUTER_KEYLINE) - + 2 * marginWidth + 2 * sideDropWidth; - y = y - borderTop - marginHeight; - break; - case PART_BORDER: - x = x - INNER_KEYLINE - OUTER_KEYLINE - sideDropWidth - - (cornerSize / 4); - width = width + 2 * (INNER_KEYLINE + OUTER_KEYLINE) - + 2 * sideDropWidth + cornerSize / 2; - height = height + borderTop + borderBottom; - y = y - borderTop; - if (onBottom) { - if (shadowEnabled) { - height += 3; - } - } - break; - default: - if (0 <= part && part < parent.getItemCount()) { - x = x - ITEM_LEFT_MARGIN;// - (CORNER_SIZE/2); - width = width + ITEM_LEFT_MARGIN + ITEM_RIGHT_MARGIN + 1; - y = y - ITEM_TOP_MARGIN; - height = height + ITEM_TOP_MARGIN + ITEM_BOTTOM_MARGIN; - } - break; - } - } - return new Rectangle(x, y, width, height); - } - - @Override - protected Point computeSize(int part, int state, GC gc, int wHint, - int hHint) { - int width = 0, height = 0; - switch (part) { - case PART_HEADER: - int fixedTabHeight = parentWrapper.getFixedTabHeight(); - if (fixedTabHeight != SWT.DEFAULT) { - //TODO use field variable instead of 1 - height = fixedTabHeight == 0 ? 0 : fixedTabHeight + 1; // +1 for line drawn across top of tab - } else { - CTabItem[] items = parent.getItems(); - if (items.length == 0) { - height = gc.textExtent("Default", FLAGS).y + ITEM_TOP_MARGIN //$NON-NLS-1$ - + ITEM_BOTTOM_MARGIN; - } else { - for (int i = 0; i < items.length; i++) { - height = Math.max(height, - computeSize(i, SWT.NONE, gc, wHint, hHint).y); - } - } - height = Math.max(height, parent.getTabHeight() + 1); -// gc.dispose(); - } - break; - case PART_MAX_BUTTON: - case PART_MIN_BUTTON: - case PART_CLOSE_BUTTON: - width = height = BUTTON_SIZE; - break; - case PART_CHEVRON_BUTTON: - width = 3 * BUTTON_SIZE / 2; - height = BUTTON_SIZE; - break; - default: - if (0 <= part && part < parent.getItemCount()) { - gc.setAdvanced(true); - - CTabItem item = parent.getItem(part); - if (item.isDisposed()) - return new Point(0, 0); - - if (imageVisible || shouldDrawImage(item)) { - Image image = item.getImage(); - if (image != null && !image.isDisposed()) { - Rectangle bounds = image.getBounds(); - if ((state & SWT.SELECTED) != 0 - || parent.getUnselectedImageVisible()) { - width += bounds.width; - } - height = bounds.height; - } - } - - if (textVisible) { - String text = null; - if ((state & MINIMUM_SIZE) != 0) { - int minChars = parent.getMinimumCharacters(); - text = minChars == 0 ? null : item.getText(); - if (text != null && text.length() > minChars) { - if (useEllipse()) { - int end = minChars < ELLIPSIS.length() + 1 - ? minChars - : minChars - ELLIPSIS.length(); - text = text.substring(0, end); - if (minChars > ELLIPSIS.length() + 1) - text += ELLIPSIS; - } else { - int end = minChars; - text = text.substring(0, end); - } - } - } else { - text = item.getText(); - } - if (text != null) { - if (width > 0) - width += INTERNAL_SPACING; - if (item.getFont() == null) { - Point size = gc.textExtent(text, FLAGS); - width += size.x; - height = Math.max(height, size.y); - } else { - Font gcFont = gc.getFont(); - gc.setFont(item.getFont()); - Point size = gc.textExtent(text, FLAGS); - width += size.x; - height = Math.max(height, size.y); - gc.setFont(gcFont); - } - } - } - - if (parentWrapper.isShowClose() || item.getShowClose()) { - if ((state & SWT.SELECTED) != 0 - || parent.getUnselectedCloseVisible()) { - if (width > 0) - width += INTERNAL_SPACING; - width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, - SWT.DEFAULT, SWT.DEFAULT).x; - } - } - } - break; - } - Rectangle trim = computeTrim(part, state, 0, 0, width, height); - width = trim.width; - height = trim.height; - return new Point(width, height); - } - - private boolean useEllipse() { - return parent.getSimple(); - } - - private Color getCloseFillColor() { - if (closeFillColor == null) { - closeFillColor = new Color(parent.getDisplay(), CLOSE_FILL); - } - return closeFillColor; - } - - @Override - protected void dispose() { - if (shadowImage != null && !shadowImage.isDisposed()) { - shadowImage.dispose(); - shadowImage = null; - } - if (closeFillColor != null) { - closeFillColor.dispose(); - closeFillColor = null; - } - super.dispose(); - } - - @Override - protected void draw(int part, int state, Rectangle bounds, GC gc) { - if (nothingToRender) { - return; - } - - switch (part) { - case PART_BACKGROUND: - this.drawCustomBackground(gc, bounds, state); - return; - case PART_BODY: - this.drawTabBody(gc, bounds, state); - return; - case PART_HEADER: - this.drawTabHeader(gc, bounds, state); - return; - case PART_MAX_BUTTON: - if (maxImage != null) { - this.drawMaximizeButton(gc, bounds, state); - return; - } - break; - case PART_MIN_BUTTON: - if (minImage != null) { - this.drawMinimizeButton(gc, bounds, state); - return; - } - break; - case PART_CLOSE_BUTTON: - if (closeImage != null) { - this.drawCloseButton(gc, bounds, state); - return; - } - break; - default: - if (0 <= part && part < parent.getItemCount()) { - gc.setAdvanced(true); - if (bounds.width == 0 || bounds.height == 0) - return; - if ((state & SWT.SELECTED) != 0) { - drawSelectedTab(part, gc, bounds, state); - state &= ~SWT.BACKGROUND; - if ((state & SWT.SELECTED) != 0) - toDrawTab(true, part, gc, bounds, state); - } else { - drawUnselectedTab(part, gc, bounds, state); - if ((state & SWT.HOT) == 0 && !active) { - gc.setAlpha(0x7f); - state &= ~SWT.BACKGROUND; - toDrawTab(false, part, gc, bounds, state); - gc.setAlpha(0xff); - } else { - state &= ~SWT.BACKGROUND; - toDrawTab(false, part, gc, bounds, state); - } - } - return; - } - } - super.draw(part, state, bounds, gc); - } - - private void drawCloseButton(GC gc, Rectangle bounds, int state) { - Image hoverImage = closeHoverImage == null ? closeImage - : closeHoverImage; - switch (state & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { - case SWT.NONE: - gc.drawImage(closeImage, bounds.x, bounds.y); - break; - case SWT.HOT: - gc.drawImage(hoverImage, bounds.x, bounds.y); - break; - case SWT.SELECTED: - gc.drawImage(hoverImage, bounds.x + 1, bounds.y + 1); - break; - case SWT.BACKGROUND: - break; - } - } - - private void drawMinimizeButton(GC gc, Rectangle bounds, int state) { - gc.drawImage(minImage, bounds.x, bounds.y); - } - - private void drawMaximizeButton(GC gc, Rectangle bounds, int state) { - gc.drawImage(maxImage, bounds.x, bounds.y); - } - - void drawTabHeader(GC gc, Rectangle bounds, int state) { - boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; - - // Fill in background - Region clipping = new Region(); - gc.getClipping(clipping); - Region region = new Region(); - region.add(shape); - region.intersect(clipping); - gc.setClipping(region); - - int header = shadowEnabled ? onBottom ? 6 : 3 : 1; - Rectangle trim = computeTrim(PART_HEADER, state, 0, 0, 0, 0); - trim.width = bounds.width - trim.width; - trim.height = computeSize(PART_HEADER, state, gc, 0, 0).y; - trim.x = -trim.x; - trim.y = onBottom ? bounds.height - parent.getTabHeight() - 1 - header - : -trim.y; - draw(PART_BACKGROUND, SWT.NONE, trim, gc); - - gc.setClipping(clipping); - clipping.dispose(); - region.dispose(); - - if (outerKeyline == null) - outerKeyline = gc.getDevice().getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(outerKeyline); - if (outerBorderVisible) { - gc.drawPolyline(tabArea); - gc.drawLine(trim.x, trim.y + trim.height, trim.x + trim.width, - trim.y + trim.height); - } - } - - void generateTabArea(Rectangle bounds) { - int[] points = new int[1024]; - int index = 0; - int radius = cornerSize / 2; - int marginWidth = parent.marginWidth; - int marginHeight = parent.marginHeight; - int delta = (INNER_KEYLINE + OUTER_KEYLINE) * 2 + marginWidth * 2; - int width = bounds.width - delta; - int height = Math.max( - parent.getTabHeight() + INNER_KEYLINE + OUTER_KEYLINE, - bounds.height - - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); - - int circX = bounds.x + radius + delta / 2; - int circY = bounds.y + radius; - - // Body - index = 0; - int[] ltt = { bounds.x + delta / 2, - bounds.y + parent.getTabHeight() + delta }; - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - int[] lbb = drawCircle(circX, circY + height - (radius * 2), radius, - LEFT_BOTTOM); - System.arraycopy(lbb, 0, points, index, lbb.length); - index += lbb.length; - - int[] rb = drawCircle(circX + width - (radius * 2), - circY + height - (radius * 2), radius, RIGHT_BOTTOM); - System.arraycopy(rb, 0, points, index, rb.length); - index += rb.length; - - int[] rt = { bounds.x + delta / 2 + width, - bounds.y + parent.getTabHeight() + delta }; - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - -// points[index++] = bounds.x + delta / 2; -// points[index++] = bounds.y + parent.getTabHeight() + 1; - - int[] tempPoints = new int[index]; - System.arraycopy(points, 0, tempPoints, 0, index); - - tabArea = tempPoints; - - } - - void drawTabBody(GC gc, Rectangle bounds, int state) { - generateTabArea(bounds); - - int[] points = new int[1024]; - int index = 0; - int radius = cornerSize / 2; - int marginWidth = parent.marginWidth; - int marginHeight = parent.marginHeight; - int delta = (INNER_KEYLINE + OUTER_KEYLINE) * 2 + marginWidth * 2; - int width = bounds.width - delta; - int height = Math.max( - parent.getTabHeight() + INNER_KEYLINE + OUTER_KEYLINE, - bounds.height - - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); - - int circX = bounds.x + radius + delta / 2; - int circY = bounds.y + radius; - - // Body - index = 0; - int[] ltt = drawCircle(circX, circY, radius, LEFT_TOP); - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - int[] lbb = drawCircle(circX, circY + height - (radius * 2), radius, - LEFT_BOTTOM); - System.arraycopy(lbb, 0, points, index, lbb.length); - index += lbb.length; - - int[] rb = drawCircle(circX + width - (radius * 2), - circY + height - (radius * 2), radius, RIGHT_BOTTOM); - System.arraycopy(rb, 0, points, index, rb.length); - index += rb.length; - - int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, - RIGHT_TOP); - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - points[index++] = circX; - points[index++] = circY - radius; - - int[] tempPoints = new int[index]; - System.arraycopy(points, 0, tempPoints, 0, index); - - // Fill in parent background for non-rectangular shape - Region r = new Region(); - r.add(bounds); - r.subtract(tempPoints); - gc.setBackground(parent.getParent().getBackground()); - Display display = parent.getDisplay(); - Region clipping = new Region(); - gc.getClipping(clipping); - r.intersect(clipping); - gc.setClipping(r); - Rectangle mappedBounds = display.map(parent, parent.getParent(), - bounds); - parent.getParent().drawBackground(gc, bounds.x, bounds.y, bounds.width, - bounds.height, mappedBounds.x, mappedBounds.y); - - // Shadow - if (shadowEnabled) - drawShadow(display, bounds, gc); - - gc.setClipping(clipping); - clipping.dispose(); - r.dispose(); - - // Remember for use in header drawing - shape = tempPoints; - } - - /* - * Draw active and unactive selected tab item - */ - void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { - if (parent.getSingle() && parent.getItem(itemIndex).isShowing()) - return; - - boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; - int header = shadowEnabled ? 2 : 0; - int width = bounds.width; - int[] points = new int[1024]; - int index = 0; - int radius = cornerSize / 2; - int circX = bounds.x + radius; - int circY = onBottom ? bounds.y + bounds.height - header - radius - : bounds.y + radius; - int selectionX1, selectionY1, selectionX2, selectionY2; - int bottomY = onBottom ? bounds.y - header : bounds.y + bounds.height; - if (itemIndex == 0 - && bounds.x == -computeTrim(CTabFolderRenderer.PART_HEADER, - SWT.NONE, 0, 0, 0, 0).x) { -// circX -= 1; -// points[index++] = circX - radius; -// points[index++] = bottomY; - - points[index++] = selectionX1 = circX - radius; - points[index++] = selectionY1 = bottomY; - } else { - if (active) { - points[index++] = shadowEnabled ? SIDE_DROP_WIDTH - : 0 + INNER_KEYLINE + OUTER_KEYLINE; - points[index++] = bottomY; - } - points[index++] = selectionX1 = bounds.x; - points[index++] = selectionY1 = bottomY; - } - - int startX = -1, endX = -1; - if (!onBottom) { - int[] ltt = drawCircle(circX, circY, radius, LEFT_TOP); - startX = ltt[6]; - for (int i = 0; i < ltt.length / 2; i += 2) { - int tmp = ltt[i]; - ltt[i] = ltt[ltt.length - i - 2]; - ltt[ltt.length - i - 2] = tmp; - tmp = ltt[i + 1]; - ltt[i + 1] = ltt[ltt.length - i - 1]; - ltt[ltt.length - i - 1] = tmp; - } - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, - RIGHT_TOP); - endX = rt[rt.length - 4]; - for (int i = 0; i < rt.length / 2; i += 2) { - int tmp = rt[i]; - rt[i] = rt[rt.length - i - 2]; - rt[rt.length - i - 2] = tmp; - tmp = rt[i + 1]; - rt[i + 1] = rt[rt.length - i - 1]; - rt[rt.length - i - 1] = tmp; - } - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - - points[index++] = selectionX2 = bounds.width + circX - radius; - points[index++] = selectionY2 = bottomY; - } else { - int[] ltt = drawCircle(circX, circY, radius, LEFT_BOTTOM); - startX = ltt[6]; - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, - RIGHT_BOTTOM); - endX = rt[rt.length - 4]; - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - - points[index++] = selectionX2 = bounds.width + circX - radius; - points[index++] = selectionY2 = bottomY; - } - - if (active) { - points[index++] = parent.getSize().x - (shadowEnabled - ? SIDE_DROP_WIDTH : 0 + INNER_KEYLINE + OUTER_KEYLINE); - points[index++] = bottomY; - } - gc.setClipping(bounds.x, onBottom ? bounds.y - header : bounds.y, - parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH - : 0 + INNER_KEYLINE + OUTER_KEYLINE), - bounds.y + bounds.height); - - Pattern backgroundPattern = null; - if (selectedTabFillColors == null) { - setSelectedTabFill(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); - } - if (selectedTabFillColors.length == 1) { - gc.setBackground(selectedTabFillColors[0]); - gc.setForeground(selectedTabFillColors[0]); - } else if (!onBottom && selectedTabFillColors.length == 2) { - // for now we support the 2-colors gradient for selected tab - backgroundPattern = new Pattern(gc.getDevice(), 0, 0, 0, - bounds.height + 1, selectedTabFillColors[0], - selectedTabFillColors[1]); - gc.setBackgroundPattern(backgroundPattern); - gc.setForeground(selectedTabFillColors[1]); - } - - int[] tmpPoints = new int[index]; - System.arraycopy(points, 0, tmpPoints, 0, index); - gc.fillPolygon(tmpPoints); - - //cover item bottom border using background color - gc.drawLine(selectionX1, selectionY1, selectionX2, selectionY2); - - gc.setClipping(bounds.x - 1, - onBottom ? bounds.y - header : bounds.y - 1, - parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH - : 0 + INNER_KEYLINE + OUTER_KEYLINE), - bounds.y + bounds.height); - if (innerBorderVisible) { - if (innerKeyline == null) - innerKeyline = gc.getDevice().getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(innerKeyline); - gc.drawPolyline(tmpPoints); - } - Rectangle rect = null; - gc.setClipping(rect); - - if (outerBorderVisible) { - if (!onBottom) { - if (outerKeyline == null) - outerKeyline = gc.getDevice() - .getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(outerKeyline); - gc.drawLine(startX + 2, 1, endX - 1, 1); - } - } - - if (backgroundPattern != null) { - backgroundPattern.dispose(); - } - } - - private boolean isTabOnBottom() { - return parent.getTabPosition() == SWT.BOTTOM; - } - - private String getShortenedText(GC gc, String text, int width) { - return useEllipse() ? getShortenedText(gc, text, width, ELLIPSIS) - : getShortenedText(gc, text, width, ""); //$NON-NLS-1$ - } - - private String getShortenedText(GC gc, String text, int width, - String ellipses) { - if (gc.textExtent(text, FLAGS).x <= width) - return text; - int ellipseWidth = gc.textExtent(ellipses, FLAGS).x; - int length = text.length(); - TextLayout layout = new TextLayout(parent.getDisplay()); - layout.setText(text); - int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER); - while (end > 0) { - text = text.substring(0, end); - int l = gc.textExtent(text, FLAGS).x; - if (l + ellipseWidth <= width) { - break; - } - end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER); - } - layout.dispose(); - return end == 0 ? text.substring(0, 1) : text + ellipses; - } - - private void toDrawTab(boolean selected, int itemIndex, GC gc, - Rectangle bounds, int state) { - CTabItem item = parent.getItem(itemIndex); - int x = bounds.x; - int y = bounds.y; - int height = bounds.height; - int width = bounds.width; - - int rightEdge = Math.min(x + width, parentWrapper.getRightItemEdge(gc)); - - if ((state & SWT.FOREGROUND) != 0) { - CTabItemWrapper itemWrapper = new CTabItemWrapper(item); - Rectangle itemCloseRect = itemWrapper.getCloseRect(); - itemCloseRect = new Rectangle(itemCloseRect.x, itemCloseRect.y, - itemCloseRect.width, itemCloseRect.height); - - // draw Image - Rectangle trim = computeTrim(itemIndex, SWT.NONE, 0, 0, 0, 0); - int xDraw = x - trim.x; - if (parent.getSingle() - && (parentWrapper.isShowClose() || item.getShowClose())) - xDraw += itemWrapper.getCloseRect().width; - if (imageVisible || shouldDrawImage(item)) { - Image image = item.getImage(); - if (image != null && !image.isDisposed()) { - Rectangle imageBounds = image.getBounds(); - // only draw image if it won't overlap with close button - int maxImageWidth = rightEdge - xDraw - - (trim.width + trim.x); - if (!parent.getSingle() && itemCloseRect.width > 0) - maxImageWidth -= itemCloseRect.width + INTERNAL_SPACING; - if (imageBounds.width < maxImageWidth) { - int imageX = xDraw; - int imageY = y + (height - imageBounds.height) / 2; - imageY += isTabOnBottom() ? -1 : 1; - gc.drawImage(image, imageX, imageY); - xDraw += imageBounds.width + INTERNAL_SPACING; - } - } - } - - if (textVisible) { - // draw Text - int textWidth = rightEdge - xDraw - (trim.width + trim.x); - if (!parent.getSingle() && itemCloseRect.width > 0) - textWidth -= itemCloseRect.width + INTERNAL_SPACING; - if (textWidth > 0) { - Font gcFont = gc.getFont(); - gc.setFont(item.getFont() == null ? parent.getFont() - : item.getFont()); - - if (itemWrapper.getShortenedText() == null || itemWrapper - .getShortenedTextWidth() != textWidth) { - itemWrapper.setShortenedText(getShortenedText(gc, - item.getText(), textWidth)); - itemWrapper.setShortenedTextWidth(textWidth); - } - Point extent = gc.textExtent(itemWrapper.getShortenedText(), - FLAGS); - int textY = y + (height - extent.y) / 2; - textY += isTabOnBottom() ? -1 : 1; - - gc.setForeground(selected ? parent.getSelectionForeground() - : parent.getForeground()); - gc.drawText(itemWrapper.getShortenedText(), xDraw, textY, - FLAGS); - gc.setFont(gcFont); - - if (selected) { - // draw a Focus rectangle - if (parent.isFocusControl()) { - Display display = parent.getDisplay(); - if (parent.getSimple() || parent.getSingle()) { - gc.setBackground(display - .getSystemColor(SWT.COLOR_BLACK)); - gc.setForeground(display - .getSystemColor(SWT.COLOR_WHITE)); - gc.drawFocus(xDraw - 1, textY - 1, extent.x + 2, - extent.y + 2); - } else { - gc.setForeground( - display.getSystemColor(BUTTON_BORDER)); - gc.drawLine(xDraw, textY + extent.y + 1, - xDraw + extent.x + 1, - textY + extent.y + 1); - } - } - } - - } - } - - if (parentWrapper.isShowClose() || item.getShowClose()) { - if (closeImage != null) { - drawCloseButton(gc, itemCloseRect, - itemWrapper.getCloseImageState()); - } else { - drawClose2(gc, itemCloseRect, - itemWrapper.getCloseImageState()); - } - } - } - } - - void drawClose2(GC gc, Rectangle closeRect, int closeImageState) { - if (closeRect.width == 0 || closeRect.height == 0) - return; - Display display = parent.getDisplay(); - - // draw X 9x9 - int x = closeRect.x + Math.max(1, (closeRect.width - 9) / 2); - int y = closeRect.y + Math.max(1, (closeRect.height - 9) / 2); - - Color closeBorder = display.getSystemColor(BUTTON_BORDER); - int[] fillShape = new int[] { x + 1, y + 1, x + 3, y + 1, x + 5, y + 3, - x + 6, y + 3, x + 8, y + 1, x + 10, y + 1, x + 10, y + 3, x + 8, - y + 5, x + 8, y + 6, x + 10, y + 8, x + 10, y + 10, x + 8, - y + 10, x + 6, y + 8, x + 5, y + 8, x + 3, y + 10, x + 1, - y + 10, x + 1, y + 8, x + 3, y + 6, x + 3, y + 5, x + 1, - y + 3 }; - int[] drawShape = new int[] { x, y, x + 2, y, x + 4, y + 2, x + 5, - y + 2, x + 7, y, x + 9, y, x + 9, y + 2, x + 7, y + 4, x + 7, - y + 5, x + 9, y + 7, x + 9, y + 9, x + 7, y + 9, x + 5, y + 7, - x + 4, y + 7, x + 2, y + 9, x, y + 9, x, y + 7, x + 2, y + 5, - x + 2, y + 4, x, y + 2 }; - switch (closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { - case SWT.NONE: { - gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - gc.fillPolygon(fillShape); - gc.setForeground(closeBorder); - gc.drawPolygon(drawShape); - break; - } - case SWT.HOT: { - gc.setBackground(getCloseFillColor()); - gc.fillPolygon(fillShape); - gc.setForeground(closeBorder); - gc.drawPolygon(drawShape); - break; - } - case SWT.SELECTED: { - gc.setBackground(getCloseFillColor()); - gc.fillPolygon(fillShape); - gc.setForeground(closeBorder); - gc.drawPolygon(drawShape); - break; - } - case SWT.BACKGROUND: { - rendererWrapper.drawClose(gc, closeRect, closeImageState); - break; - } - } - } - - private boolean shouldDrawImage(CTabItem item) { - Object model = item.getData(AbstractPartRenderer.OWNING_ME); - if (model != null && model instanceof MUIElement) { - MUIElement element = (MUIElement) model; - if (element.getTags().contains(ICathyConstants.TAG_SHOW_IMAGE)) { - return true; - } - } - return false; - } - - void drawUnselectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { - if ((state & SWT.HOT) != 0) { - int header = shadowEnabled ? 2 : 0; - int width = bounds.width; - boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; - int[] points = new int[1024]; - int[] inactive = new int[8]; - int index = 0, inactive_index = 0; - int radius = cornerSize / 2; - int circX = bounds.x + radius; - int circY = onBottom - ? bounds.y + bounds.height + 1 - header - radius - : bounds.y - 1 + radius; - int bottomY = onBottom ? bounds.y - header - : bounds.y + bounds.height; - - int leftIndex = circX; - if (itemIndex == 0) { -// if (parent.getSelectionIndex() != 0) -// leftIndex -= 1; - points[index++] = leftIndex - radius; - points[index++] = bottomY; - - } else { - points[index++] = bounds.x; - points[index++] = bottomY; - } - - if (!active) { - System.arraycopy(points, 0, inactive, 0, index); - inactive_index += 2; - } - - int rightIndex = circX - 1; - int startX = -1, endX = -1; - if (!onBottom) { - int[] ltt = drawCircle(leftIndex, circY, radius, LEFT_TOP); - startX = ltt[6]; - for (int i = 0; i < ltt.length / 2; i += 2) { - int tmp = ltt[i]; - ltt[i] = ltt[ltt.length - i - 2]; - ltt[ltt.length - i - 2] = tmp; - tmp = ltt[i + 1]; - ltt[i + 1] = ltt[ltt.length - i - 1]; - ltt[ltt.length - i - 1] = tmp; - } - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - if (!active) { - System.arraycopy(ltt, 0, inactive, inactive_index, 2); - inactive_index += 2; - } - - int[] rt = drawCircle(rightIndex + width - (radius * 2), circY, - radius, RIGHT_TOP); - endX = rt[rt.length - 4]; - for (int i = 0; i < rt.length / 2; i += 2) { - int tmp = rt[i]; - rt[i] = rt[rt.length - i - 2]; - rt[rt.length - i - 2] = tmp; - tmp = rt[i + 1]; - rt[i + 1] = rt[rt.length - i - 1]; - rt[rt.length - i - 1] = tmp; - } - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - if (!active) { - System.arraycopy(rt, rt.length - 4, inactive, - inactive_index, 2); - inactive[inactive_index] -= 1; - inactive_index += 2; - } - } else { - int[] ltt = drawCircle(leftIndex, circY, radius, LEFT_BOTTOM); - startX = ltt[6]; - System.arraycopy(ltt, 0, points, index, ltt.length); - index += ltt.length; - - if (!active) { - System.arraycopy(ltt, 0, inactive, inactive_index, 2); - inactive_index += 2; - } - - int[] rt = drawCircle(rightIndex + width - (radius * 2), circY, - radius, RIGHT_BOTTOM); - endX = rt[rt.length - 4]; - System.arraycopy(rt, 0, points, index, rt.length); - index += rt.length; - if (!active) { - System.arraycopy(rt, rt.length - 4, inactive, - inactive_index, 2); - inactive[inactive_index] -= 1; - inactive_index += 2; - } - - } - - points[index++] = bounds.width + rightIndex - radius; - points[index++] = bottomY; - - if (!active) { - System.arraycopy(points, index - 2, inactive, inactive_index, - 2); - inactive[inactive_index] -= 1; - inactive_index += 2; - } - - gc.setClipping(points[0], - onBottom ? bounds.y - header : bounds.y - 1, - parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH - : 0 + INNER_KEYLINE + OUTER_KEYLINE), - bounds.y + bounds.height); - - if (hoverTabColors == null) { - hoverTabColors = new Color[] { - gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; - hoverTabPercents = new int[] { 100 }; - } - - gc.setBackground(hoverTabColors[0]); - int[] tmpPoints = new int[index]; - System.arraycopy(points, 0, tmpPoints, 0, index); - gc.fillPolygon(tmpPoints); - Color tempBorder = new Color(gc.getDevice(), 182, 188, 204); - gc.setForeground(tempBorder); - tempBorder.dispose(); - - if (hoverBorderVisible) { - if (outerBorderVisible) { - if (outerKeyline == null) - outerKeyline = gc.getDevice() - .getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(outerKeyline); - if (active) { - gc.drawLine(startX, 1, endX, 1); - } else { - gc.drawLine(inactive[0], inactive[1], inactive[2], - inactive[3]); - gc.drawLine(inactive[4], inactive[5], inactive[6], - inactive[7]); - } - } - - if (innerBorderVisible) { - if (innerKeyline == null) - innerKeyline = gc.getDevice() - .getSystemColor(SWT.COLOR_BLACK); - gc.setForeground(innerKeyline); - gc.drawPolyline(tmpPoints); - } - } - - Rectangle rect = null; - gc.setClipping(rect); - - // gc.setForeground(outerKeyline); - // gc.drawPolyline(shape); - } - } - - static int[] drawCircle(int xC, int yC, int r, int circlePart) { - int x = 0, y = r, u = 1, v = 2 * r - 1, e = 0; - int[] points = new int[1024]; - int[] pointsMirror = new int[1024]; - int loop = 0; - int loopMirror = 0; - if (r == 0) { - for (int i = 0; i < 4; i++) { - points[loop++] = xC; - points[loop++] = yC; - } - } - while (x < y) { - if (circlePart == RIGHT_BOTTOM) { - points[loop++] = xC + x; - points[loop++] = yC + y; - } - if (circlePart == RIGHT_TOP) { - points[loop++] = xC + y; - points[loop++] = yC - x; - } - if (circlePart == LEFT_TOP) { - points[loop++] = xC - x; - points[loop++] = yC - y; - } - if (circlePart == LEFT_BOTTOM) { - points[loop++] = xC - y; - points[loop++] = yC + x; - } - x++; - e += u; - u += 2; - if (v < 2 * e) { - y--; - e -= v; - v -= 2; - } - if (x > y) - break; - if (circlePart == RIGHT_BOTTOM) { - pointsMirror[loopMirror++] = xC + y; - pointsMirror[loopMirror++] = yC + x; - } - if (circlePart == RIGHT_TOP) { - pointsMirror[loopMirror++] = xC + x; - pointsMirror[loopMirror++] = yC - y; - } - if (circlePart == LEFT_TOP) { - pointsMirror[loopMirror++] = xC - y; - pointsMirror[loopMirror++] = yC - x; - } - if (circlePart == LEFT_BOTTOM) { - pointsMirror[loopMirror++] = xC - x; - pointsMirror[loopMirror++] = yC + y; - } - // grow? - if ((loop + 1) > points.length) { - int length = points.length * 2; - int[] newPointTable = new int[length]; - int[] newPointTableMirror = new int[length]; - System.arraycopy(points, 0, newPointTable, 0, points.length); - points = newPointTable; - System.arraycopy(pointsMirror, 0, newPointTableMirror, 0, - pointsMirror.length); - pointsMirror = newPointTableMirror; - } - } - int[] finalArray = new int[loop + loopMirror]; - System.arraycopy(points, 0, finalArray, 0, loop); - for (int i = loopMirror - 1, j = loop; i > 0; i = i - 2, j = j + 2) { - int tempY = pointsMirror[i]; - int tempX = pointsMirror[i - 1]; - finalArray[j] = tempX; - finalArray[j + 1] = tempY; - } - return finalArray; - } - - static RGB blend(RGB c1, RGB c2, int ratio) { - int r = blend(c1.red, c2.red, ratio); - int g = blend(c1.green, c2.green, ratio); - int b = blend(c1.blue, c2.blue, ratio); - return new RGB(r, g, b); - } - - static int blend(int v1, int v2, int ratio) { - int b = (ratio * v1 + (100 - ratio) * v2) / 100; - return Math.min(255, b); - } - - void drawShadow(final Display display, Rectangle bounds, GC gc) { - if (shadowImage == null) { - createShadow(display); - } - int x = bounds.x; - int y = bounds.y; - int SIZE = shadowImage.getBounds().width / 3; - - int height = Math.max(bounds.height, SIZE * 2); - int width = Math.max(bounds.width, SIZE * 2); - // top left - gc.drawImage(shadowImage, 0, 0, SIZE, SIZE, 2, 10, SIZE, 20); - int fillHeight = height - SIZE * 2; - int fillWidth = width + 5 - SIZE * 2; - - int xFill = 0; - for (int i = SIZE; i < fillHeight; i += SIZE) { - xFill = i; - gc.drawImage(shadowImage, 0, SIZE, SIZE, SIZE, 2, i, SIZE, SIZE); - } - - // Pad the rest of the shadow - gc.drawImage(shadowImage, 0, SIZE, SIZE, fillHeight - xFill, 2, - xFill + SIZE, SIZE, fillHeight - xFill); - - // bl - gc.drawImage(shadowImage, 0, 40, 20, 20, 2, y + height - SIZE, 20, 20); - - int yFill = 0; - for (int i = SIZE; i <= fillWidth; i += SIZE) { - yFill = i; - gc.drawImage(shadowImage, SIZE, SIZE * 2, SIZE, SIZE, i, - y + height - SIZE, SIZE, SIZE); - } - // Pad the rest of the shadow - gc.drawImage(shadowImage, SIZE, SIZE * 2, fillWidth - yFill, SIZE, - yFill + SIZE, y + height - SIZE, fillWidth - yFill, SIZE); - - // br - gc.drawImage(shadowImage, SIZE * 2, SIZE * 2, SIZE, SIZE, - x + width - SIZE - 1, y + height - SIZE, SIZE, SIZE); - - // tr - gc.drawImage(shadowImage, (SIZE * 2), 0, SIZE, SIZE, - x + width - SIZE - 1, 10, SIZE, SIZE); - - xFill = 0; - for (int i = SIZE; i < fillHeight; i += SIZE) { - xFill = i; - gc.drawImage(shadowImage, SIZE * 2, SIZE, SIZE, SIZE, - x + width - SIZE - 1, i, SIZE, SIZE); - } - - // Pad the rest of the shadow - gc.drawImage(shadowImage, SIZE * 2, SIZE, SIZE, fillHeight - xFill, - x + width - SIZE - 1, xFill + SIZE, SIZE, fillHeight - xFill); - } - - void createShadow(final Display display) { - if (shadowImage != null) { - shadowImage.dispose(); - shadowImage = null; - } - ImageData data = new ImageData(60, 60, 32, - new PaletteData(0xFF0000, 0xFF00, 0xFF)); - Image tmpImage = shadowImage = new Image(display, data); - GC gc = new GC(tmpImage); - if (shadowColor == null) - shadowColor = gc.getDevice().getSystemColor(SWT.COLOR_GRAY); - gc.setBackground(shadowColor); - drawTabBody(gc, new Rectangle(0, 0, 60, 60), SWT.None); - ImageData blured = blur(tmpImage, 5, 25); - shadowImage = new Image(display, blured); - tmpImage.dispose(); - } - - public ImageData blur(Image src, int radius, int sigma) { - float[] kernel = create1DKernel(radius, sigma); - - ImageData imgPixels = src.getImageData(); - int width = imgPixels.width; - int height = imgPixels.height; - - int[] inPixels = new int[width * height]; - int[] outPixels = new int[width * height]; - int offset = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - RGB rgb = imgPixels.palette.getRGB(imgPixels.getPixel(x, y)); - if (rgb.red == 255 && rgb.green == 255 && rgb.blue == 255) { - inPixels[offset] = (rgb.red << 16) | (rgb.green << 8) - | rgb.blue; - } else { - inPixels[offset] = (imgPixels.getAlpha(x, y) << 24) - | (rgb.red << 16) | (rgb.green << 8) | rgb.blue; - } - offset++; - } - } - - convolve(kernel, inPixels, outPixels, width, height, true); - convolve(kernel, outPixels, inPixels, height, width, true); - - ImageData dst = new ImageData(imgPixels.width, imgPixels.height, 24, - new PaletteData(0xff0000, 0xff00, 0xff)); - - dst.setPixels(0, 0, inPixels.length, inPixels, 0); - offset = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (inPixels[offset] == -1) { - dst.setAlpha(x, y, 0); - } else { - int a = (inPixels[offset] >> 24) & 0xff; - // if (a < 150) a = 0; - dst.setAlpha(x, y, a); - } - offset++; - } - } - return dst; - } - - private void convolve(float[] kernel, int[] inPixels, int[] outPixels, - int width, int height, boolean alpha) { - int kernelWidth = kernel.length; - int kernelMid = kernelWidth / 2; - for (int y = 0; y < height; y++) { - int index = y; - int currentLine = y * width; - for (int x = 0; x < width; x++) { - // do point - float a = 0, r = 0, g = 0, b = 0; - for (int k = -kernelMid; k <= kernelMid; k++) { - float val = kernel[k + kernelMid]; - int xcoord = x + k; - if (xcoord < 0) - xcoord = 0; - if (xcoord >= width) - xcoord = width - 1; - int pixel = inPixels[currentLine + xcoord]; - // float alp = ((pixel >> 24) & 0xff); - a += val * ((pixel >> 24) & 0xff); - r += val * (((pixel >> 16) & 0xff)); - g += val * (((pixel >> 8) & 0xff)); - b += val * (((pixel) & 0xff)); - } - int ia = alpha ? clamp((int) (a + 0.5)) : 0xff; - int ir = clamp((int) (r + 0.5)); - int ig = clamp((int) (g + 0.5)); - int ib = clamp((int) (b + 0.5)); - outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib; - index += height; - } - } - - } - - private int clamp(int value) { - if (value > 255) - return 255; - if (value < 0) - return 0; - return value; - } - - private float[] create1DKernel(int radius, int sigma) { - // guideline: 3*sigma should be the radius - int size = radius * 2 + 1; - float[] kernel = new float[size]; - int radiusSquare = radius * radius; - float sigmaSquare = 2 * sigma * sigma; - float piSigma = 2 * (float) Math.PI * sigma; - float sqrtSigmaPi2 = (float) Math.sqrt(piSigma); - int start = size / 2; - int index = 0; - float total = 0; - for (int i = -start; i <= start; i++) { - float d = i * i; - if (d > radiusSquare) { - kernel[index] = 0; - } else { - kernel[index] = (float) Math.exp(-(d) / sigmaSquare) - / sqrtSigmaPi2; - } - total += kernel[index]; - index++; - } - for (int i = 0; i < size; i++) { - kernel[i] /= total; - } - return kernel; - } - - public Rectangle getPadding() { - return new Rectangle(paddingTop, paddingRight, paddingBottom, - paddingLeft); - } - - public void setPadding(int paddingLeft, int paddingRight, int paddingTop, - int paddingBottom) { - this.paddingLeft = paddingLeft; - this.paddingRight = paddingRight; - this.paddingTop = paddingTop; - this.paddingBottom = paddingBottom; - parent.redraw(); - } - - public void setCornerRadius(int radius) { - cornerSize = radius; - parent.redraw(); - } - - public void setShadowVisible(boolean visible) { - this.shadowEnabled = visible; - parent.redraw(); - } - - public void setShadowColor(Color color) { - this.shadowColor = color; - createShadow(parent.getDisplay()); - parent.redraw(); - } - - public void setOuterKeyline(Color color) { - this.outerKeyline = color; - // TODO: HACK! Should be set based on pseudo-state. - if (color != null) { - setActive(!(color.getRed() == 255 && color.getGreen() == 255 - && color.getBlue() == 255)); - } - parent.redraw(); - } - - public void setSelectedTabFill(Color color) { - setSelectedTabFill(new Color[] { color }, new int[] { 100 }); - } - - public void setSelectedTabFill(Color[] colors, int[] percents) { - selectedTabFillColors = colors; - selectedTabFillPercents = percents; - parent.redraw(); - } - - public void setSelectedTabAreaColor(Color color) { - setSelectedTabAreaColor(new Color[] { color }, new int[] { 100 }); - } - - public void setSelectedTabAreaColor(Color[] colors, int[] percents) { - selectedTabAreaColors = colors; - selectedTabAreaPercents = percents; - parent.redraw(); - } - - public void setUnselectedTabsColor(Color color) { - setUnselectedTabsColor(new Color[] { color }, new int[] { 100 }); - } - - public void setUnselectedTabsColor(Color[] colors, int[] percents) { - unselectedTabsColors = colors; - unselectedTabsPercents = percents; - - parent.redraw(); - } - - public void setUnselectedTabsBackgroundVisible(boolean visible) { - unselectedTabsBackgroundVisible = visible; - parent.redraw(); - } - - public void setUnselectedHotTabsColorBackground(Color color) { - setHoverTabColor(new Color[] { color }, new int[] { 100 }); - } - - public void setHoverTabColor(Color color) { - setHoverTabColor(new Color[] { color }, new int[] { 100 }); - - } - - public void setHoverTabColor(Color[] colors, int[] percents) { - hoverTabColors = colors; - hoverTabPercents = percents; - parent.redraw(); - } - - public void setTabOutline(Color color) { - this.tabOutlineColor = color; - parent.redraw(); - } - - public void setInnerKeyline(Color color) { - this.innerKeyline = color; - parent.redraw(); - } - - public void setTextVisible(boolean visible) { - this.textVisible = visible; - parent.redraw(); - } - - public void setImageVisible(boolean visible) { - this.imageVisible = visible; - parent.redraw(); - } - - public void setOuterBorderVisible(boolean visible) { - this.outerBorderVisible = visible; - parent.redraw(); - } - - public void setInnerBorderVisible(boolean visible) { - this.innerBorderVisible = visible; - parent.redraw(); - } - - public void setActiveToolbarGradient(Color[] color, int[] percents) { - activeToolbar = color; - activePercents = percents; - } - - public void setInactiveToolbarGradient(Color[] color, int[] percents) { - inactiveToolbar = color; - inactivePercents = percents; - } - - public void setActive(boolean active) { - this.active = active; - } - - public void setMaximizeImage(Image maxImage) { - this.maxImage = maxImage; - } - - public void setMinimizeImage(Image minImage) { - this.minImage = minImage; - } - - public void setCloseImage(Image closeImage) { - this.closeImage = closeImage; - } - - public void setClsoeHoverImage(Image closeHoverImage) { - this.closeHoverImage = closeHoverImage; - } - - public void setNoneRender(boolean nothingToRender) { - this.nothingToRender = nothingToRender; - } - - private void drawCustomBackground(GC gc, Rectangle bounds, int state) { - boolean selected = (state & SWT.SELECTED) != 0; - Color defaultBackground = selected ? parent.getSelectionBackground() - : parent.getBackground(); - boolean vertical = selected - ? parentWrapper.isSelectionGradientVertical() - : parentWrapper.isGradientVertical(); - Rectangle partHeaderBounds = bounds; - - if (unselectedTabsBackgroundVisible) { - drawUnselectedTabBackground(gc, partHeaderBounds, state, vertical, - defaultBackground); - } - drawTabAreaBackground(gc, partHeaderBounds, state, vertical, - defaultBackground); - - int borderTop = isTabOnBottom() ? INNER_KEYLINE + OUTER_KEYLINE - : TOP_KEYLINE + OUTER_KEYLINE; - int borderBottom = isTabOnBottom() ? TOP_KEYLINE + OUTER_KEYLINE - : INNER_KEYLINE + OUTER_KEYLINE; - int bottomDropWidth = shadowEnabled ? BOTTOM_DROP_WIDTH : 0; - int sideDropWidth = shadowEnabled ? SIDE_DROP_WIDTH : 0; - int headerBorderBottom = outerBorderVisible ? OUTER_KEYLINE : 0; - Rectangle underTabAreaBounds = new Rectangle( - partHeaderBounds.x + paddingLeft + sideDropWidth, - partHeaderBounds.y + partHeaderBounds.height + bottomDropWidth - + paddingTop + headerBorderBottom, - bounds.width - paddingLeft - paddingRight - 2 * sideDropWidth, - parent.getBounds().height - partHeaderBounds.height - paddingTop - - paddingBottom - headerBorderBottom - - ((cornerSize / 4) + borderBottom + borderTop) - - bottomDropWidth * 2); - drawUnderTabAreaBackground(gc, underTabAreaBounds, state, vertical, - defaultBackground); - drawChildrenBackground(partHeaderBounds); - } - - private void drawUnderTabAreaBackground(GC gc, Rectangle tabAreaBounds, - int state, boolean vertical, Color defaultBackground) { - Color[] underTabAreaColors = new Color[] { - gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; - int[] underTabAreaPercents = new int[] { 100 }; - rendererWrapper.drawBackground(gc, tabAreaBounds.x, tabAreaBounds.y, - tabAreaBounds.width, tabAreaBounds.height, defaultBackground, - underTabAreaColors, underTabAreaPercents, vertical); - } - - private void drawUnselectedTabBackground(GC gc, Rectangle partHeaderBounds, - int state, boolean vertical, Color defaultBackground) { - if (unselectedTabsColors == null) { - boolean selected = (state & SWT.SELECTED) != 0; - unselectedTabsColors = selected - ? parentWrapper.getSelectionGradientColors() - : parentWrapper.getGradientColors(); - unselectedTabsPercents = selected - ? parentWrapper.getSelectionGradientPercents() - : parentWrapper.getGradientPercents(); - } - if (unselectedTabsColors == null) { - unselectedTabsColors = new Color[] { - gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; - unselectedTabsPercents = new int[] { 100 }; - } - - rendererWrapper.drawBackground(gc, partHeaderBounds.x, - partHeaderBounds.y, partHeaderBounds.width, - partHeaderBounds.height, defaultBackground, - unselectedTabsColors, unselectedTabsPercents, vertical); - } - - private void drawTabAreaBackground(GC gc, Rectangle partHeaderBounds, - int state, boolean vertical, Color defaultBackground) { - Color[] colors = selectedTabAreaColors; - int[] percents = selectedTabAreaPercents; - - if (colors != null && colors.length == 2) { - colors = new Color[] { colors[1], colors[1] }; - } - if (colors == null) { - boolean selected = (state & SWT.SELECTED) != 0; - colors = selected ? parentWrapper.getSelectionGradientColors() - : parentWrapper.getGradientColors(); - percents = selected ? parentWrapper.getSelectionGradientPercents() - : parentWrapper.getGradientPercents(); - } - if (colors == null) { - colors = new Color[] { - gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; - percents = new int[] { 100 }; - } - - rendererWrapper.drawBackground(gc, partHeaderBounds.x, - partHeaderBounds.y + partHeaderBounds.height, - partHeaderBounds.width, parent.getBounds().height, - defaultBackground, colors, percents, vertical); - } - - // Workaround for the bug 433276. Remove it when the bug gets fixed - private void drawChildrenBackground(Rectangle partHeaderBounds) { - for (Control control : parent.getChildren()) { - if (!CompositeElement.hasBackgroundOverriddenByCSS(control) - && containsToolbar(control)) { - drawChildBackground((Composite) control, partHeaderBounds); - } - } - } - - private boolean containsToolbar(Control control) { - if (control.getData(CONTAINS_TOOLBAR) != null) { - return true; - } - - if (control instanceof ToolBar) { - control.setData(CONTAINS_TOOLBAR, true); - return true; - } - - if (control instanceof Composite) { - for (Control child : ((Composite) control).getChildren()) { - if (child instanceof ToolBar) { - control.setData(CONTAINS_TOOLBAR, true); - return true; - } - } - } - return false; - } - - private void drawChildBackground(Composite composite, - Rectangle partHeaderBounds) { - Rectangle rec = composite.getBounds(); - Color background = null; - boolean partOfHeader = rec.y >= partHeaderBounds.y - && rec.y < partHeaderBounds.height; - - if (!partOfHeader) { - background = composite.getDisplay().getSystemColor(SWT.COLOR_WHITE); - } - CTabFolderElement.setBackgroundOverriddenDuringRenderering(composite, - background); - } - - private static class CTabFolderRendererWrapper - extends ReflectionSupport { - private Method drawBackgroundMethod; - - private Method drawCloseMethod; - - public CTabFolderRendererWrapper(CTabFolderRenderer instance) { - super(instance); - } - - public void drawBackground(GC gc, int x, int y, int width, int height, - Color defaultBackground, Color[] colors, int[] percents, - boolean vertical) { - if (drawBackgroundMethod == null) { - drawBackgroundMethod = getMethod("drawBackground", //$NON-NLS-1$ - new Class[] { GC.class, int[].class, int.class, - int.class, int.class, int.class, Color.class, - Image.class, Color[].class, int[].class, - boolean.class }); - } - executeMethod(drawBackgroundMethod, - new Object[] { gc, null, x, y, width, height, - defaultBackground, null, colors, percents, - vertical }); - } - - public void drawClose(GC gc, Rectangle closeRect, int closeImageState) { - if (drawCloseMethod == null) { - drawCloseMethod = getMethod("drawClose", new Class[] { //$NON-NLS-1$ - GC.class, Rectangle.class, int.class }); - } - executeMethod(drawCloseMethod, - new Object[] { gc, closeRect, closeImageState }); - } - } - - private static class CTabItemWrapper extends ReflectionSupport { - - private Field shortenedTextField; - - private Field shortenedTextWidthField; - - private Field closeRectField; - - private Field closeImageStateField; - - public CTabItemWrapper(CTabItem instance) { - super(instance); - } - - public String getShortenedText() { - if (shortenedTextField == null) { - shortenedTextField = getField("shortenedText"); //$NON-NLS-1$ - } - return (String) getFieldValue(shortenedTextField); - } - - public void setShortenedText(String value) { - set("shortenedText", value); //$NON-NLS-1$ - } - - public Integer getShortenedTextWidth() { - if (shortenedTextWidthField == null) { - shortenedTextWidthField = getField("shortenedTextWidth"); //$NON-NLS-1$ - } - return (Integer) getFieldValue(shortenedTextWidthField); - } - - public void setShortenedTextWidth(int value) { - set("shortenedTextWidth", value); //$NON-NLS-1$ - } - - public Rectangle getCloseRect() { - if (closeRectField == null) { - closeRectField = getField("closeRect"); //$NON-NLS-1$ - } - return (Rectangle) getFieldValue(closeRectField); - } - - public int getCloseImageState() { - if (closeImageStateField == null) { - closeImageStateField = getField("closeImageState"); //$NON-NLS-1$ - } - return (Integer) getFieldValue(closeImageStateField); - } - - } - - private static class CTabFolderWrapper - extends ReflectionSupport { - private Field selectionGradientVerticalField; - - private Field gradientVerticalField; - - private Field selectionGradientColorsField; - - private Field selectionGradientPercentsField; - - private Field gradientColorsField; - - private Field gradientPercentsField; - - private Field showCloseField; - - private Field fixedTabHeightField; - - private Method getRightItemEdgeMethod; - - public CTabFolderWrapper(CTabFolder instance) { - super(instance); - } - - public boolean isShowClose() { - if (showCloseField == null) { - showCloseField = getField("showClose"); //$NON-NLS-1$ - } - Boolean result = (Boolean) getFieldValue(showCloseField); - return result != null ? result : true; - } - - public boolean isSelectionGradientVertical() { - if (selectionGradientVerticalField == null) { - selectionGradientVerticalField = getField( - "selectionGradientVertical"); //$NON-NLS-1$ - } - Boolean result = (Boolean) getFieldValue( - selectionGradientVerticalField); - return result != null ? result : true; - } - - public boolean isGradientVertical() { - if (gradientVerticalField == null) { - gradientVerticalField = getField("gradientVertical"); //$NON-NLS-1$ - } - Boolean result = (Boolean) getFieldValue(gradientVerticalField); - return result != null ? result : true; - } - - public Color[] getSelectionGradientColors() { - if (selectionGradientColorsField == null) { - selectionGradientColorsField = getField( - "selectionGradientColorsField"); //$NON-NLS-1$ - } - return (Color[]) getFieldValue(selectionGradientColorsField); - } - - public int[] getSelectionGradientPercents() { - if (selectionGradientPercentsField == null) { - selectionGradientPercentsField = getField( - "selectionGradientPercents"); //$NON-NLS-1$ - } - return (int[]) getFieldValue(selectionGradientPercentsField); - } - - public Color[] getGradientColors() { - if (gradientColorsField == null) { - gradientColorsField = getField("gradientColors"); //$NON-NLS-1$ - } - return (Color[]) getFieldValue(gradientColorsField); - } - - public int[] getGradientPercents() { - if (gradientPercentsField == null) { - gradientPercentsField = getField("gradientPercents"); //$NON-NLS-1$ - } - return (int[]) getFieldValue(gradientPercentsField); - } - - public int getRightItemEdge(GC gc) { - if (getRightItemEdgeMethod == null) { - getRightItemEdgeMethod = getMethod("getRightItemEdge", //$NON-NLS-1$ - new Class[] { GC.class }); - } - return (Integer) executeMethod(getRightItemEdgeMethod, - new Object[] { gc }); - } - - public int getFixedTabHeight() { - if (fixedTabHeightField == null) { - fixedTabHeightField = getField("fixedTabHeight"); //$NON-NLS-1$ - } - return (Integer) getFieldValue(fixedTabHeightField); - } - } - - private static class ReflectionSupport { - private T instance; - - public ReflectionSupport(T instance) { - this.instance = instance; - } - - protected Object getFieldValue(Field field) { - Object value = null; - if (field != null) { - boolean accessible = field.isAccessible(); - try { - field.setAccessible(true); - value = field.get(instance); - } catch (Exception exc) { - // do nothing - } finally { - field.setAccessible(accessible); - } - } - return value; - } - - protected Field getField(String name) { - Class cls = instance.getClass(); - while (!cls.equals(Object.class)) { - try { - return cls.getDeclaredField(name); - } catch (Exception exc) { - cls = cls.getSuperclass(); - } - } - return null; - } - - public Object set(String name, Object value) { - try { - Field field = getField(name); - boolean accessible = field.isAccessible(); - field.setAccessible(true); - field.set(instance, value); - field.setAccessible(accessible); - return value; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - protected Object executeMethod(Method method, Object... params) { - Object value = null; - if (method != null) { - boolean accessible = method.isAccessible(); - try { - method.setAccessible(true); - value = method.invoke(instance, params); - } catch (Exception exc) { - // do nothing - } finally { - method.setAccessible(accessible); - } - } - return value; - } - - protected Method getMethod(String name, Class... params) { - Class cls = instance.getClass(); - while (!cls.equals(Object.class)) { - try { - return cls.getDeclaredMethod(name, params); - } catch (Exception exc) { - cls = cls.getSuperclass(); - } - } - return null; - } - } - -} +package org.xmind.cathy.internal.css; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import javax.inject.Inject; + +import org.eclipse.e4.ui.css.swt.dom.CTabFolderElement; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.Region; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.ToolBar; +import org.xmind.cathy.internal.ICathyConstants; + +@SuppressWarnings("restriction") +public class CathyCTabFolderRendering extends CTabFolderRenderer + implements ICTabFolderRendering { + private static final String CONTAINS_TOOLBAR = "CathyCTabFolderRendering.containsToolbar"; //$NON-NLS-1$ + + // Constants for circle drawing + final static int LEFT_TOP = 0; + final static int LEFT_BOTTOM = 1; + final static int RIGHT_TOP = 2; + final static int RIGHT_BOTTOM = 3; + + // drop shadow constants + final static int SIDE_DROP_WIDTH = 3; + final static int BOTTOM_DROP_WIDTH = 4; + + // keylines + final static int OUTER_KEYLINE = 1; + final static int INNER_KEYLINE = 0; + final static int TOP_KEYLINE = 0; + + // Item Constants + static final int ITEM_TOP_MARGIN = 2; + static final int ITEM_BOTTOM_MARGIN = 6; + static final int ITEM_LEFT_MARGIN = 8; + static final int ITEM_RIGHT_MARGIN = 4; + static final int INTERNAL_SPACING = 4; + + static final int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC; + static final String ELLIPSIS = "..."; //$NON-NLS-1$ + static final String E4_TOOLBAR_ACTIVE_IMAGE = "org.eclipse.e4.renderer.toolbar_background_active_image"; //$NON-NLS-1$ + static final String E4_TOOLBAR_INACTIVE_IMAGE = "org.eclipse.e4.renderer.toolbar_background_inactive_image"; //$NON-NLS-1$ + + static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW; + static final int BUTTON_SIZE = 16; + + static final RGB CLOSE_FILL = new RGB(252, 160, 160); + + private Color closeFillColor; + + int[] shape; + + Image shadowImage, toolbarActiveImage, toolbarInactiveImage; + + int cornerSize = 14; + + //The best value + boolean shadowEnabled = true; + Color shadowColor; + Color outerKeyline, innerKeyline; + Color[] activeToolbar; + int[] activePercents; + Color[] inactiveToolbar; + int[] inactivePercents; + boolean active; + + Color[] selectedTabFillColors; + int[] selectedTabFillPercents; + + Color[] selectedTabAreaColors; + int[] selectedTabAreaPercents; + + Color[] unselectedTabsColors; + int[] unselectedTabsPercents; + + Color[] hoverTabColors; + int[] hoverTabPercents; + + Color tabOutlineColor; + + int paddingLeft = 2, paddingRight = 2, paddingTop = 2, paddingBottom = 2; + + private CTabFolderRendererWrapper rendererWrapper; + private CTabFolderWrapper parentWrapper; + + private boolean textVisible = true; + + private boolean imageVisible = true; + + private boolean outerBorderVisible = true; + private boolean innerBorderVisible = true; + + private boolean unselectedTabsBackgroundVisible = true; + + private Image maxImage; + + private Image minImage; + + private Image closeImage; + + private Image closeHoverImage; + + private int[] tabArea; + + //temp + private boolean hoverBorderVisible = false; + + private boolean nothingToRender = false; + + @Inject + public CathyCTabFolderRendering(CTabFolder parent) { + super(parent); + parentWrapper = new CTabFolderWrapper(parent); + rendererWrapper = new CTabFolderRendererWrapper(this); + } + + @Override + protected Rectangle computeTrim(int part, int state, int x, int y, + int width, int height) { + if (!nothingToRender) { + boolean onBottom = isTabOnBottom(); + int borderTop = onBottom ? INNER_KEYLINE + OUTER_KEYLINE + : TOP_KEYLINE + OUTER_KEYLINE; + int borderBottom = onBottom ? TOP_KEYLINE + OUTER_KEYLINE + : INNER_KEYLINE + OUTER_KEYLINE; + int marginWidth = parent.marginWidth; + int marginHeight = parent.marginHeight; + int sideDropWidth = shadowEnabled ? SIDE_DROP_WIDTH : 0; + int bottomDropWidth = shadowEnabled ? BOTTOM_DROP_WIDTH : 0; + int headerBorderBottom = outerBorderVisible ? OUTER_KEYLINE : 0; + switch (part) { + //body trimmed + body client area + case PART_BODY: + if (state == SWT.FILL) { + x = x - paddingLeft - sideDropWidth + - (INNER_KEYLINE + OUTER_KEYLINE) - marginWidth; + int tabHeight = parent.getTabHeight() + 1; + y = onBottom + ? y - paddingTop - marginHeight - borderTop + - bottomDropWidth + : y - paddingTop - marginHeight - tabHeight + - borderTop - headerBorderBottom + - bottomDropWidth; + width = 2 * (INNER_KEYLINE + OUTER_KEYLINE) + paddingLeft + + paddingRight + 2 * sideDropWidth + + 2 * marginWidth; + height += paddingTop + paddingBottom + bottomDropWidth; + height += tabHeight + headerBorderBottom + borderBottom + + borderTop; + } else { + x = x - marginWidth - OUTER_KEYLINE - INNER_KEYLINE + - sideDropWidth - (cornerSize / 2) - paddingLeft; + width = width + 2 * OUTER_KEYLINE + 2 * INNER_KEYLINE + + 2 * marginWidth + 2 * sideDropWidth + cornerSize + + paddingRight + paddingLeft; + int tabHeight = parent.getTabHeight() + 1; + if (parent.getMinimized()) { + y = onBottom ? y - borderTop - 5 + : y - tabHeight - borderTop - 5; + height = borderTop + borderBottom + tabHeight; + } else { + y = onBottom + ? y - marginHeight - borderTop - paddingTop + - bottomDropWidth + : y - marginHeight - tabHeight - borderTop + - paddingTop - headerBorderBottom + - bottomDropWidth; + height = height + borderBottom + borderTop + + 2 * marginHeight + tabHeight + + headerBorderBottom + bottomDropWidth + + paddingTop + paddingBottom; + } + } + break; + case PART_HEADER: + x = x - (INNER_KEYLINE + OUTER_KEYLINE) - marginWidth + - sideDropWidth; + width = width + 2 * (INNER_KEYLINE + OUTER_KEYLINE) + + 2 * marginWidth + 2 * sideDropWidth; + y = y - borderTop - marginHeight; + break; + case PART_BORDER: + x = x - INNER_KEYLINE - OUTER_KEYLINE - sideDropWidth + - (cornerSize / 4); + width = width + 2 * (INNER_KEYLINE + OUTER_KEYLINE) + + 2 * sideDropWidth + cornerSize / 2; + height = height + borderTop + borderBottom; + y = y - borderTop; + if (onBottom) { + if (shadowEnabled) { + height += 3; + } + } + break; + default: + if (0 <= part && part < parent.getItemCount()) { + x = x - ITEM_LEFT_MARGIN;// - (CORNER_SIZE/2); + width = width + ITEM_LEFT_MARGIN + ITEM_RIGHT_MARGIN + 1; + y = y - ITEM_TOP_MARGIN; + height = height + ITEM_TOP_MARGIN + ITEM_BOTTOM_MARGIN; + } + break; + } + } + return new Rectangle(x, y, width, height); + } + + @Override + protected Point computeSize(int part, int state, GC gc, int wHint, + int hHint) { + int width = 0, height = 0; + switch (part) { + case PART_HEADER: + int fixedTabHeight = parentWrapper.getFixedTabHeight(); + if (fixedTabHeight != SWT.DEFAULT) { + //TODO use field variable instead of 1 + height = fixedTabHeight == 0 ? 0 : fixedTabHeight + 1; // +1 for line drawn across top of tab + } else { + CTabItem[] items = parent.getItems(); + if (items.length == 0) { + height = gc.textExtent("Default", FLAGS).y + ITEM_TOP_MARGIN //$NON-NLS-1$ + + ITEM_BOTTOM_MARGIN; + } else { + for (int i = 0; i < items.length; i++) { + height = Math.max(height, + computeSize(i, SWT.NONE, gc, wHint, hHint).y); + } + } + height = Math.max(height, parent.getTabHeight() + 1); + gc.dispose(); + } + break; + case PART_MAX_BUTTON: + case PART_MIN_BUTTON: + case PART_CLOSE_BUTTON: + width = height = BUTTON_SIZE; + break; + case PART_CHEVRON_BUTTON: + width = 3 * BUTTON_SIZE / 2; + height = BUTTON_SIZE; + break; + default: + if (0 <= part && part < parent.getItemCount()) { + gc.setAdvanced(true); + + CTabItem item = parent.getItem(part); + if (item.isDisposed()) + return new Point(0, 0); + + if (imageVisible || shouldDrawImage(item)) { + Image image = item.getImage(); + if (image != null && !image.isDisposed()) { + Rectangle bounds = image.getBounds(); + if ((state & SWT.SELECTED) != 0 + || parent.getUnselectedImageVisible()) { + width += bounds.width; + } + height = bounds.height; + } + } + + if (textVisible) { + String text = null; + if ((state & MINIMUM_SIZE) != 0) { + int minChars = parent.getMinimumCharacters(); + text = minChars == 0 ? null : item.getText(); + if (text != null && text.length() > minChars) { + if (useEllipse()) { + int end = minChars < ELLIPSIS.length() + 1 + ? minChars + : minChars - ELLIPSIS.length(); + text = text.substring(0, end); + if (minChars > ELLIPSIS.length() + 1) + text += ELLIPSIS; + } else { + int end = minChars; + text = text.substring(0, end); + } + } + } else { + text = item.getText(); + } + if (text != null) { + if (width > 0) + width += INTERNAL_SPACING; + if (item.getFont() == null) { + Point size = gc.textExtent(text, FLAGS); + width += size.x; + height = Math.max(height, size.y); + } else { + Font gcFont = gc.getFont(); + gc.setFont(item.getFont()); + Point size = gc.textExtent(text, FLAGS); + width += size.x; + height = Math.max(height, size.y); + gc.setFont(gcFont); + } + } + } + + if (parentWrapper.isShowClose() || item.getShowClose()) { + if ((state & SWT.SELECTED) != 0 + || parent.getUnselectedCloseVisible()) { + if (width > 0) + width += INTERNAL_SPACING; + width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, + SWT.DEFAULT, SWT.DEFAULT).x; + } + } + } + break; + } + Rectangle trim = computeTrim(part, state, 0, 0, width, height); + width = trim.width; + height = trim.height; + return new Point(width, height); + } + + private boolean useEllipse() { + return parent.getSimple(); + } + + private Color getCloseFillColor() { + if (closeFillColor == null) { + closeFillColor = new Color(parent.getDisplay(), CLOSE_FILL); + } + return closeFillColor; + } + + @Override + protected void dispose() { + if (shadowImage != null && !shadowImage.isDisposed()) { + shadowImage.dispose(); + shadowImage = null; + } + if (closeFillColor != null) { + closeFillColor.dispose(); + closeFillColor = null; + } + super.dispose(); + } + + @Override + protected void draw(int part, int state, Rectangle bounds, GC gc) { + if (nothingToRender) { + return; + } + + switch (part) { + case PART_BACKGROUND: + this.drawCustomBackground(gc, bounds, state); + return; + case PART_BODY: + this.drawTabBody(gc, bounds, state); + return; + case PART_HEADER: + this.drawTabHeader(gc, bounds, state); + return; + case PART_MAX_BUTTON: + if (maxImage != null) { + this.drawMaximizeButton(gc, bounds, state); + return; + } + break; + case PART_MIN_BUTTON: + if (minImage != null) { + this.drawMinimizeButton(gc, bounds, state); + return; + } + break; + case PART_CLOSE_BUTTON: + if (closeImage != null) { + this.drawCloseButton(gc, bounds, state); + return; + } + break; + default: + if (0 <= part && part < parent.getItemCount()) { + gc.setAdvanced(true); + if (bounds.width == 0 || bounds.height == 0) + return; + if ((state & SWT.SELECTED) != 0) { + drawSelectedTab(part, gc, bounds, state); + state &= ~SWT.BACKGROUND; + if ((state & SWT.SELECTED) != 0) + toDrawTab(true, part, gc, bounds, state); + } else { + drawUnselectedTab(part, gc, bounds, state); + if ((state & SWT.HOT) == 0 && !active) { + gc.setAlpha(0x7f); + state &= ~SWT.BACKGROUND; + toDrawTab(false, part, gc, bounds, state); + gc.setAlpha(0xff); + } else { + state &= ~SWT.BACKGROUND; + toDrawTab(false, part, gc, bounds, state); + } + } + return; + } + } + super.draw(part, state, bounds, gc); + } + + private void drawCloseButton(GC gc, Rectangle bounds, int state) { + Image hoverImage = closeHoverImage == null ? closeImage + : closeHoverImage; + switch (state & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { + case SWT.NONE: + gc.drawImage(closeImage, bounds.x, bounds.y); + break; + case SWT.HOT: + gc.drawImage(hoverImage, bounds.x, bounds.y); + break; + case SWT.SELECTED: + gc.drawImage(hoverImage, bounds.x + 1, bounds.y + 1); + break; + case SWT.BACKGROUND: + break; + } + } + + private void drawMinimizeButton(GC gc, Rectangle bounds, int state) { + gc.drawImage(minImage, bounds.x, bounds.y); + } + + private void drawMaximizeButton(GC gc, Rectangle bounds, int state) { + gc.drawImage(maxImage, bounds.x, bounds.y); + } + + void drawTabHeader(GC gc, Rectangle bounds, int state) { + boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; + + // Fill in background + Region clipping = new Region(); + gc.getClipping(clipping); + Region region = new Region(); + region.add(shape); + region.intersect(clipping); + gc.setClipping(region); + + int header = shadowEnabled ? onBottom ? 6 : 3 : 1; + Rectangle trim = computeTrim(PART_HEADER, state, 0, 0, 0, 0); + trim.width = bounds.width - trim.width; + trim.height = computeSize(PART_HEADER, state, gc, 0, 0).y; + trim.x = -trim.x; + trim.y = onBottom ? bounds.height - parent.getTabHeight() - 1 - header + : -trim.y; + draw(PART_BACKGROUND, SWT.NONE, trim, gc); + + gc.setClipping(clipping); + clipping.dispose(); + region.dispose(); + + if (outerKeyline == null) + outerKeyline = gc.getDevice().getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(outerKeyline); + if (outerBorderVisible) { + gc.drawPolyline(tabArea); + gc.drawLine(trim.x, trim.y + trim.height, trim.x + trim.width, + trim.y + trim.height); + } + } + + void generateTabArea(Rectangle bounds) { + int[] points = new int[1024]; + int index = 0; + int radius = cornerSize / 2; + int marginWidth = parent.marginWidth; + int marginHeight = parent.marginHeight; + int delta = (INNER_KEYLINE + OUTER_KEYLINE) * 2 + marginWidth * 2; + int width = bounds.width - delta; + int height = Math.max( + parent.getTabHeight() + INNER_KEYLINE + OUTER_KEYLINE, + bounds.height + - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); + + int circX = bounds.x + radius + delta / 2; + int circY = bounds.y + radius; + + // Body + index = 0; + int[] ltt = { bounds.x + delta / 2, + bounds.y + parent.getTabHeight() + delta }; + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + int[] lbb = drawCircle(circX, circY + height - (radius * 2), radius, + LEFT_BOTTOM); + System.arraycopy(lbb, 0, points, index, lbb.length); + index += lbb.length; + + int[] rb = drawCircle(circX + width - (radius * 2), + circY + height - (radius * 2), radius, RIGHT_BOTTOM); + System.arraycopy(rb, 0, points, index, rb.length); + index += rb.length; + + int[] rt = { bounds.x + delta / 2 + width, + bounds.y + parent.getTabHeight() + delta }; + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + +// points[index++] = bounds.x + delta / 2; +// points[index++] = bounds.y + parent.getTabHeight() + 1; + + int[] tempPoints = new int[index]; + System.arraycopy(points, 0, tempPoints, 0, index); + + tabArea = tempPoints; + + } + + void drawTabBody(GC gc, Rectangle bounds, int state) { + generateTabArea(bounds); + + int[] points = new int[1024]; + int index = 0; + int radius = cornerSize / 2; + int marginWidth = parent.marginWidth; + int marginHeight = parent.marginHeight; + int delta = (INNER_KEYLINE + OUTER_KEYLINE) * 2 + marginWidth * 2; + int width = bounds.width - delta; + int height = Math.max( + parent.getTabHeight() + INNER_KEYLINE + OUTER_KEYLINE, + bounds.height + - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); + + int circX = bounds.x + radius + delta / 2; + int circY = bounds.y + radius; + + // Body + index = 0; + int[] ltt = drawCircle(circX, circY, radius, LEFT_TOP); + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + int[] lbb = drawCircle(circX, circY + height - (radius * 2), radius, + LEFT_BOTTOM); + System.arraycopy(lbb, 0, points, index, lbb.length); + index += lbb.length; + + int[] rb = drawCircle(circX + width - (radius * 2), + circY + height - (radius * 2), radius, RIGHT_BOTTOM); + System.arraycopy(rb, 0, points, index, rb.length); + index += rb.length; + + int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, + RIGHT_TOP); + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + points[index++] = circX; + points[index++] = circY - radius; + + int[] tempPoints = new int[index]; + System.arraycopy(points, 0, tempPoints, 0, index); + + // Fill in parent background for non-rectangular shape + Region r = new Region(); + r.add(bounds); + r.subtract(tempPoints); + gc.setBackground(parent.getParent().getBackground()); + Display display = parent.getDisplay(); + Region clipping = new Region(); + gc.getClipping(clipping); + r.intersect(clipping); + gc.setClipping(r); + Rectangle mappedBounds = display.map(parent, parent.getParent(), + bounds); + parent.getParent().drawBackground(gc, bounds.x, bounds.y, bounds.width, + bounds.height, mappedBounds.x, mappedBounds.y); + + // Shadow + if (shadowEnabled) + drawShadow(display, bounds, gc); + + gc.setClipping(clipping); + clipping.dispose(); + r.dispose(); + + // Remember for use in header drawing + shape = tempPoints; + } + + /* + * Draw active and unactive selected tab item + */ + void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { + if (parent.getSingle() && parent.getItem(itemIndex).isShowing()) + return; + + boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; + int header = shadowEnabled ? 2 : 0; + int width = bounds.width; + int[] points = new int[1024]; + int index = 0; + int radius = cornerSize / 2; + int circX = bounds.x + radius; + int circY = onBottom ? bounds.y + bounds.height - header - radius + : bounds.y + radius; + int selectionX1, selectionY1, selectionX2, selectionY2; + int bottomY = onBottom ? bounds.y - header : bounds.y + bounds.height; + if (itemIndex == 0 + && bounds.x == -computeTrim(CTabFolderRenderer.PART_HEADER, + SWT.NONE, 0, 0, 0, 0).x) { +// circX -= 1; +// points[index++] = circX - radius; +// points[index++] = bottomY; + + points[index++] = selectionX1 = circX - radius; + points[index++] = selectionY1 = bottomY; + } else { + if (active) { + points[index++] = shadowEnabled ? SIDE_DROP_WIDTH + : 0 + INNER_KEYLINE + OUTER_KEYLINE; + points[index++] = bottomY; + } + points[index++] = selectionX1 = bounds.x; + points[index++] = selectionY1 = bottomY; + } + + int startX = -1, endX = -1; + if (!onBottom) { + int[] ltt = drawCircle(circX, circY, radius, LEFT_TOP); + startX = ltt[6]; + for (int i = 0; i < ltt.length / 2; i += 2) { + int tmp = ltt[i]; + ltt[i] = ltt[ltt.length - i - 2]; + ltt[ltt.length - i - 2] = tmp; + tmp = ltt[i + 1]; + ltt[i + 1] = ltt[ltt.length - i - 1]; + ltt[ltt.length - i - 1] = tmp; + } + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, + RIGHT_TOP); + endX = rt[rt.length - 4]; + for (int i = 0; i < rt.length / 2; i += 2) { + int tmp = rt[i]; + rt[i] = rt[rt.length - i - 2]; + rt[rt.length - i - 2] = tmp; + tmp = rt[i + 1]; + rt[i + 1] = rt[rt.length - i - 1]; + rt[rt.length - i - 1] = tmp; + } + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + + points[index++] = selectionX2 = bounds.width + circX - radius; + points[index++] = selectionY2 = bottomY; + } else { + int[] ltt = drawCircle(circX, circY, radius, LEFT_BOTTOM); + startX = ltt[6]; + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + int[] rt = drawCircle(circX + width - (radius * 2), circY, radius, + RIGHT_BOTTOM); + endX = rt[rt.length - 4]; + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + + points[index++] = selectionX2 = bounds.width + circX - radius; + points[index++] = selectionY2 = bottomY; + } + + if (active) { + points[index++] = parent.getSize().x - (shadowEnabled + ? SIDE_DROP_WIDTH : 0 + INNER_KEYLINE + OUTER_KEYLINE); + points[index++] = bottomY; + } + gc.setClipping(bounds.x, onBottom ? bounds.y - header : bounds.y, + parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH + : 0 + INNER_KEYLINE + OUTER_KEYLINE), + bounds.y + bounds.height); + + Pattern backgroundPattern = null; + if (selectedTabFillColors == null) { + setSelectedTabFill(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); + } + if (selectedTabFillColors.length == 1) { + gc.setBackground(selectedTabFillColors[0]); + gc.setForeground(selectedTabFillColors[0]); + } else if (!onBottom && selectedTabFillColors.length == 2) { + // for now we support the 2-colors gradient for selected tab + backgroundPattern = new Pattern(gc.getDevice(), 0, 0, 0, + bounds.height + 1, selectedTabFillColors[0], + selectedTabFillColors[1]); + gc.setBackgroundPattern(backgroundPattern); + gc.setForeground(selectedTabFillColors[1]); + } + + int[] tmpPoints = new int[index]; + System.arraycopy(points, 0, tmpPoints, 0, index); + gc.fillPolygon(tmpPoints); + + //cover item bottom border using background color + gc.drawLine(selectionX1, selectionY1, selectionX2, selectionY2); + + gc.setClipping(bounds.x - 1, + onBottom ? bounds.y - header : bounds.y - 1, + parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH + : 0 + INNER_KEYLINE + OUTER_KEYLINE), + bounds.y + bounds.height); + if (innerBorderVisible) { + if (innerKeyline == null) + innerKeyline = gc.getDevice().getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(innerKeyline); + gc.drawPolyline(tmpPoints); + } + Rectangle rect = null; + gc.setClipping(rect); + + if (outerBorderVisible) { + if (!onBottom) { + if (outerKeyline == null) + outerKeyline = gc.getDevice() + .getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(outerKeyline); + gc.drawLine(startX + 2, 1, endX - 1, 1); + } + } + + if (backgroundPattern != null) { + backgroundPattern.dispose(); + } + } + + private boolean isTabOnBottom() { + return parent.getTabPosition() == SWT.BOTTOM; + } + + private String getShortenedText(GC gc, String text, int width) { + return useEllipse() ? getShortenedText(gc, text, width, ELLIPSIS) + : getShortenedText(gc, text, width, ""); //$NON-NLS-1$ + } + + private String getShortenedText(GC gc, String text, int width, + String ellipses) { + if (gc.textExtent(text, FLAGS).x <= width) + return text; + int ellipseWidth = gc.textExtent(ellipses, FLAGS).x; + int length = text.length(); + TextLayout layout = new TextLayout(parent.getDisplay()); + layout.setText(text); + int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER); + while (end > 0) { + text = text.substring(0, end); + int l = gc.textExtent(text, FLAGS).x; + if (l + ellipseWidth <= width) { + break; + } + end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER); + } + layout.dispose(); + return end == 0 ? text.substring(0, 1) : text + ellipses; + } + + private void toDrawTab(boolean selected, int itemIndex, GC gc, + Rectangle bounds, int state) { + CTabItem item = parent.getItem(itemIndex); + int x = bounds.x; + int y = bounds.y; + int height = bounds.height; + int width = bounds.width; + + int rightEdge = Math.min(x + width, parentWrapper.getRightItemEdge(gc)); + + if ((state & SWT.FOREGROUND) != 0) { + CTabItemWrapper itemWrapper = new CTabItemWrapper(item); + Rectangle itemCloseRect = itemWrapper.getCloseRect(); + itemCloseRect = new Rectangle(itemCloseRect.x, itemCloseRect.y, + itemCloseRect.width, itemCloseRect.height); + + // draw Image + Rectangle trim = computeTrim(itemIndex, SWT.NONE, 0, 0, 0, 0); + int xDraw = x - trim.x; + if (parent.getSingle() + && (parentWrapper.isShowClose() || item.getShowClose())) + xDraw += itemWrapper.getCloseRect().width; + if (imageVisible || shouldDrawImage(item)) { + Image image = item.getImage(); + if (image != null && !image.isDisposed()) { + Rectangle imageBounds = image.getBounds(); + // only draw image if it won't overlap with close button + int maxImageWidth = rightEdge - xDraw + - (trim.width + trim.x); + if (!parent.getSingle() && itemCloseRect.width > 0) + maxImageWidth -= itemCloseRect.width + INTERNAL_SPACING; + if (imageBounds.width < maxImageWidth) { + int imageX = xDraw; + int imageY = y + (height - imageBounds.height) / 2; + imageY += isTabOnBottom() ? -1 : 1; + gc.drawImage(image, imageX, imageY); + xDraw += imageBounds.width + INTERNAL_SPACING; + } + } + } + + if (textVisible) { + // draw Text + int textWidth = rightEdge - xDraw - (trim.width + trim.x); + if (!parent.getSingle() && itemCloseRect.width > 0) + textWidth -= itemCloseRect.width + INTERNAL_SPACING; + if (textWidth > 0) { + Font gcFont = gc.getFont(); + gc.setFont(item.getFont() == null ? parent.getFont() + : item.getFont()); + + if (itemWrapper.getShortenedText() == null || itemWrapper + .getShortenedTextWidth() != textWidth) { + itemWrapper.setShortenedText(getShortenedText(gc, + item.getText(), textWidth)); + itemWrapper.setShortenedTextWidth(textWidth); + } + Point extent = gc.textExtent(itemWrapper.getShortenedText(), + FLAGS); + int textY = y + (height - extent.y) / 2; + textY += isTabOnBottom() ? -1 : 1; + + gc.setForeground(selected ? parent.getSelectionForeground() + : parent.getForeground()); + gc.drawText(itemWrapper.getShortenedText(), xDraw, textY, + FLAGS); + gc.setFont(gcFont); + + if (selected) { + // draw a Focus rectangle + if (parent.isFocusControl()) { + Display display = parent.getDisplay(); + if (parent.getSimple() || parent.getSingle()) { + gc.setBackground(display + .getSystemColor(SWT.COLOR_BLACK)); + gc.setForeground(display + .getSystemColor(SWT.COLOR_WHITE)); + gc.drawFocus(xDraw - 1, textY - 1, extent.x + 2, + extent.y + 2); + } else { + gc.setForeground( + display.getSystemColor(BUTTON_BORDER)); + gc.drawLine(xDraw, textY + extent.y + 1, + xDraw + extent.x + 1, + textY + extent.y + 1); + } + } + } + + } + } + + if (parentWrapper.isShowClose() || item.getShowClose()) { + if (closeImage != null) { + drawCloseButton(gc, itemCloseRect, + itemWrapper.getCloseImageState()); + } else { + drawClose2(gc, itemCloseRect, + itemWrapper.getCloseImageState()); + } + } + } + } + + void drawClose2(GC gc, Rectangle closeRect, int closeImageState) { + if (closeRect.width == 0 || closeRect.height == 0) + return; + Display display = parent.getDisplay(); + + // draw X 9x9 + int x = closeRect.x + Math.max(1, (closeRect.width - 9) / 2); + int y = closeRect.y + Math.max(1, (closeRect.height - 9) / 2); + + Color closeBorder = display.getSystemColor(BUTTON_BORDER); + int[] fillShape = new int[] { x + 1, y + 1, x + 3, y + 1, x + 5, y + 3, + x + 6, y + 3, x + 8, y + 1, x + 10, y + 1, x + 10, y + 3, x + 8, + y + 5, x + 8, y + 6, x + 10, y + 8, x + 10, y + 10, x + 8, + y + 10, x + 6, y + 8, x + 5, y + 8, x + 3, y + 10, x + 1, + y + 10, x + 1, y + 8, x + 3, y + 6, x + 3, y + 5, x + 1, + y + 3 }; + int[] drawShape = new int[] { x, y, x + 2, y, x + 4, y + 2, x + 5, + y + 2, x + 7, y, x + 9, y, x + 9, y + 2, x + 7, y + 4, x + 7, + y + 5, x + 9, y + 7, x + 9, y + 9, x + 7, y + 9, x + 5, y + 7, + x + 4, y + 7, x + 2, y + 9, x, y + 9, x, y + 7, x + 2, y + 5, + x + 2, y + 4, x, y + 2 }; + switch (closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { + case SWT.NONE: { + gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + gc.fillPolygon(fillShape); + gc.setForeground(closeBorder); + gc.drawPolygon(drawShape); + break; + } + case SWT.HOT: { + gc.setBackground(getCloseFillColor()); + gc.fillPolygon(fillShape); + gc.setForeground(closeBorder); + gc.drawPolygon(drawShape); + break; + } + case SWT.SELECTED: { + gc.setBackground(getCloseFillColor()); + gc.fillPolygon(fillShape); + gc.setForeground(closeBorder); + gc.drawPolygon(drawShape); + break; + } + case SWT.BACKGROUND: { + rendererWrapper.drawClose(gc, closeRect, closeImageState); + break; + } + } + } + + private boolean shouldDrawImage(CTabItem item) { + Object model = item.getData(AbstractPartRenderer.OWNING_ME); + if (model != null && model instanceof MUIElement) { + MUIElement element = (MUIElement) model; + if (element.getTags().contains(ICathyConstants.TAG_SHOW_IMAGE)) { + return true; + } + } + return false; + } + + void drawUnselectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { + if ((state & SWT.HOT) != 0) { + int header = shadowEnabled ? 2 : 0; + int width = bounds.width; + boolean onBottom = parent.getTabPosition() == SWT.BOTTOM; + int[] points = new int[1024]; + int[] inactive = new int[8]; + int index = 0, inactive_index = 0; + int radius = cornerSize / 2; + int circX = bounds.x + radius; + int circY = onBottom + ? bounds.y + bounds.height + 1 - header - radius + : bounds.y - 1 + radius; + int bottomY = onBottom ? bounds.y - header + : bounds.y + bounds.height; + + int leftIndex = circX; + if (itemIndex == 0) { +// if (parent.getSelectionIndex() != 0) +// leftIndex -= 1; + points[index++] = leftIndex - radius; + points[index++] = bottomY; + + } else { + points[index++] = bounds.x; + points[index++] = bottomY; + } + + if (!active) { + System.arraycopy(points, 0, inactive, 0, index); + inactive_index += 2; + } + + int rightIndex = circX - 1; + int startX = -1, endX = -1; + if (!onBottom) { + int[] ltt = drawCircle(leftIndex, circY, radius, LEFT_TOP); + startX = ltt[6]; + for (int i = 0; i < ltt.length / 2; i += 2) { + int tmp = ltt[i]; + ltt[i] = ltt[ltt.length - i - 2]; + ltt[ltt.length - i - 2] = tmp; + tmp = ltt[i + 1]; + ltt[i + 1] = ltt[ltt.length - i - 1]; + ltt[ltt.length - i - 1] = tmp; + } + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + if (!active) { + System.arraycopy(ltt, 0, inactive, inactive_index, 2); + inactive_index += 2; + } + + int[] rt = drawCircle(rightIndex + width - (radius * 2), circY, + radius, RIGHT_TOP); + endX = rt[rt.length - 4]; + for (int i = 0; i < rt.length / 2; i += 2) { + int tmp = rt[i]; + rt[i] = rt[rt.length - i - 2]; + rt[rt.length - i - 2] = tmp; + tmp = rt[i + 1]; + rt[i + 1] = rt[rt.length - i - 1]; + rt[rt.length - i - 1] = tmp; + } + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + if (!active) { + System.arraycopy(rt, rt.length - 4, inactive, + inactive_index, 2); + inactive[inactive_index] -= 1; + inactive_index += 2; + } + } else { + int[] ltt = drawCircle(leftIndex, circY, radius, LEFT_BOTTOM); + startX = ltt[6]; + System.arraycopy(ltt, 0, points, index, ltt.length); + index += ltt.length; + + if (!active) { + System.arraycopy(ltt, 0, inactive, inactive_index, 2); + inactive_index += 2; + } + + int[] rt = drawCircle(rightIndex + width - (radius * 2), circY, + radius, RIGHT_BOTTOM); + endX = rt[rt.length - 4]; + System.arraycopy(rt, 0, points, index, rt.length); + index += rt.length; + if (!active) { + System.arraycopy(rt, rt.length - 4, inactive, + inactive_index, 2); + inactive[inactive_index] -= 1; + inactive_index += 2; + } + + } + + points[index++] = bounds.width + rightIndex - radius; + points[index++] = bottomY; + + if (!active) { + System.arraycopy(points, index - 2, inactive, inactive_index, + 2); + inactive[inactive_index] -= 1; + inactive_index += 2; + } + + gc.setClipping(points[0], + onBottom ? bounds.y - header : bounds.y - 1, + parent.getSize().x - (shadowEnabled ? SIDE_DROP_WIDTH + : 0 + INNER_KEYLINE + OUTER_KEYLINE), + bounds.y + bounds.height); + + if (hoverTabColors == null) { + hoverTabColors = new Color[] { + gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; + hoverTabPercents = new int[] { 100 }; + } + + gc.setBackground(hoverTabColors[0]); + int[] tmpPoints = new int[index]; + System.arraycopy(points, 0, tmpPoints, 0, index); + gc.fillPolygon(tmpPoints); + Color tempBorder = new Color(gc.getDevice(), 182, 188, 204); + gc.setForeground(tempBorder); + tempBorder.dispose(); + + if (hoverBorderVisible) { + if (outerBorderVisible) { + if (outerKeyline == null) + outerKeyline = gc.getDevice() + .getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(outerKeyline); + if (active) { + gc.drawLine(startX, 1, endX, 1); + } else { + gc.drawLine(inactive[0], inactive[1], inactive[2], + inactive[3]); + gc.drawLine(inactive[4], inactive[5], inactive[6], + inactive[7]); + } + } + + if (innerBorderVisible) { + if (innerKeyline == null) + innerKeyline = gc.getDevice() + .getSystemColor(SWT.COLOR_BLACK); + gc.setForeground(innerKeyline); + gc.drawPolyline(tmpPoints); + } + } + + Rectangle rect = null; + gc.setClipping(rect); + + // gc.setForeground(outerKeyline); + // gc.drawPolyline(shape); + } + } + + static int[] drawCircle(int xC, int yC, int r, int circlePart) { + int x = 0, y = r, u = 1, v = 2 * r - 1, e = 0; + int[] points = new int[1024]; + int[] pointsMirror = new int[1024]; + int loop = 0; + int loopMirror = 0; + if (r == 0) { + for (int i = 0; i < 4; i++) { + points[loop++] = xC; + points[loop++] = yC; + } + } + while (x < y) { + if (circlePart == RIGHT_BOTTOM) { + points[loop++] = xC + x; + points[loop++] = yC + y; + } + if (circlePart == RIGHT_TOP) { + points[loop++] = xC + y; + points[loop++] = yC - x; + } + if (circlePart == LEFT_TOP) { + points[loop++] = xC - x; + points[loop++] = yC - y; + } + if (circlePart == LEFT_BOTTOM) { + points[loop++] = xC - y; + points[loop++] = yC + x; + } + x++; + e += u; + u += 2; + if (v < 2 * e) { + y--; + e -= v; + v -= 2; + } + if (x > y) + break; + if (circlePart == RIGHT_BOTTOM) { + pointsMirror[loopMirror++] = xC + y; + pointsMirror[loopMirror++] = yC + x; + } + if (circlePart == RIGHT_TOP) { + pointsMirror[loopMirror++] = xC + x; + pointsMirror[loopMirror++] = yC - y; + } + if (circlePart == LEFT_TOP) { + pointsMirror[loopMirror++] = xC - y; + pointsMirror[loopMirror++] = yC - x; + } + if (circlePart == LEFT_BOTTOM) { + pointsMirror[loopMirror++] = xC - x; + pointsMirror[loopMirror++] = yC + y; + } + // grow? + if ((loop + 1) > points.length) { + int length = points.length * 2; + int[] newPointTable = new int[length]; + int[] newPointTableMirror = new int[length]; + System.arraycopy(points, 0, newPointTable, 0, points.length); + points = newPointTable; + System.arraycopy(pointsMirror, 0, newPointTableMirror, 0, + pointsMirror.length); + pointsMirror = newPointTableMirror; + } + } + int[] finalArray = new int[loop + loopMirror]; + System.arraycopy(points, 0, finalArray, 0, loop); + for (int i = loopMirror - 1, j = loop; i > 0; i = i - 2, j = j + 2) { + int tempY = pointsMirror[i]; + int tempX = pointsMirror[i - 1]; + finalArray[j] = tempX; + finalArray[j + 1] = tempY; + } + return finalArray; + } + + static RGB blend(RGB c1, RGB c2, int ratio) { + int r = blend(c1.red, c2.red, ratio); + int g = blend(c1.green, c2.green, ratio); + int b = blend(c1.blue, c2.blue, ratio); + return new RGB(r, g, b); + } + + static int blend(int v1, int v2, int ratio) { + int b = (ratio * v1 + (100 - ratio) * v2) / 100; + return Math.min(255, b); + } + + void drawShadow(final Display display, Rectangle bounds, GC gc) { + if (shadowImage == null) { + createShadow(display); + } + int x = bounds.x; + int y = bounds.y; + int SIZE = shadowImage.getBounds().width / 3; + + int height = Math.max(bounds.height, SIZE * 2); + int width = Math.max(bounds.width, SIZE * 2); + // top left + gc.drawImage(shadowImage, 0, 0, SIZE, SIZE, 2, 10, SIZE, 20); + int fillHeight = height - SIZE * 2; + int fillWidth = width + 5 - SIZE * 2; + + int xFill = 0; + for (int i = SIZE; i < fillHeight; i += SIZE) { + xFill = i; + gc.drawImage(shadowImage, 0, SIZE, SIZE, SIZE, 2, i, SIZE, SIZE); + } + + // Pad the rest of the shadow + gc.drawImage(shadowImage, 0, SIZE, SIZE, fillHeight - xFill, 2, + xFill + SIZE, SIZE, fillHeight - xFill); + + // bl + gc.drawImage(shadowImage, 0, 40, 20, 20, 2, y + height - SIZE, 20, 20); + + int yFill = 0; + for (int i = SIZE; i <= fillWidth; i += SIZE) { + yFill = i; + gc.drawImage(shadowImage, SIZE, SIZE * 2, SIZE, SIZE, i, + y + height - SIZE, SIZE, SIZE); + } + // Pad the rest of the shadow + gc.drawImage(shadowImage, SIZE, SIZE * 2, fillWidth - yFill, SIZE, + yFill + SIZE, y + height - SIZE, fillWidth - yFill, SIZE); + + // br + gc.drawImage(shadowImage, SIZE * 2, SIZE * 2, SIZE, SIZE, + x + width - SIZE - 1, y + height - SIZE, SIZE, SIZE); + + // tr + gc.drawImage(shadowImage, (SIZE * 2), 0, SIZE, SIZE, + x + width - SIZE - 1, 10, SIZE, SIZE); + + xFill = 0; + for (int i = SIZE; i < fillHeight; i += SIZE) { + xFill = i; + gc.drawImage(shadowImage, SIZE * 2, SIZE, SIZE, SIZE, + x + width - SIZE - 1, i, SIZE, SIZE); + } + + // Pad the rest of the shadow + gc.drawImage(shadowImage, SIZE * 2, SIZE, SIZE, fillHeight - xFill, + x + width - SIZE - 1, xFill + SIZE, SIZE, fillHeight - xFill); + } + + void createShadow(final Display display) { + if (shadowImage != null) { + shadowImage.dispose(); + shadowImage = null; + } + ImageData data = new ImageData(60, 60, 32, + new PaletteData(0xFF0000, 0xFF00, 0xFF)); + Image tmpImage = shadowImage = new Image(display, data); + GC gc = new GC(tmpImage); + if (shadowColor == null) + shadowColor = gc.getDevice().getSystemColor(SWT.COLOR_GRAY); + gc.setBackground(shadowColor); + drawTabBody(gc, new Rectangle(0, 0, 60, 60), SWT.None); + ImageData blured = blur(tmpImage, 5, 25); + shadowImage = new Image(display, blured); + tmpImage.dispose(); + gc.dispose(); + } + + public ImageData blur(Image src, int radius, int sigma) { + float[] kernel = create1DKernel(radius, sigma); + + ImageData imgPixels = src.getImageData(); + int width = imgPixels.width; + int height = imgPixels.height; + + int[] inPixels = new int[width * height]; + int[] outPixels = new int[width * height]; + int offset = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + RGB rgb = imgPixels.palette.getRGB(imgPixels.getPixel(x, y)); + if (rgb.red == 255 && rgb.green == 255 && rgb.blue == 255) { + inPixels[offset] = (rgb.red << 16) | (rgb.green << 8) + | rgb.blue; + } else { + inPixels[offset] = (imgPixels.getAlpha(x, y) << 24) + | (rgb.red << 16) | (rgb.green << 8) | rgb.blue; + } + offset++; + } + } + + convolve(kernel, inPixels, outPixels, width, height, true); + convolve(kernel, outPixels, inPixels, height, width, true); + + ImageData dst = new ImageData(imgPixels.width, imgPixels.height, 24, + new PaletteData(0xff0000, 0xff00, 0xff)); + + dst.setPixels(0, 0, inPixels.length, inPixels, 0); + offset = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (inPixels[offset] == -1) { + dst.setAlpha(x, y, 0); + } else { + int a = (inPixels[offset] >> 24) & 0xff; + // if (a < 150) a = 0; + dst.setAlpha(x, y, a); + } + offset++; + } + } + return dst; + } + + private void convolve(float[] kernel, int[] inPixels, int[] outPixels, + int width, int height, boolean alpha) { + int kernelWidth = kernel.length; + int kernelMid = kernelWidth / 2; + for (int y = 0; y < height; y++) { + int index = y; + int currentLine = y * width; + for (int x = 0; x < width; x++) { + // do point + float a = 0, r = 0, g = 0, b = 0; + for (int k = -kernelMid; k <= kernelMid; k++) { + float val = kernel[k + kernelMid]; + int xcoord = x + k; + if (xcoord < 0) + xcoord = 0; + if (xcoord >= width) + xcoord = width - 1; + int pixel = inPixels[currentLine + xcoord]; + // float alp = ((pixel >> 24) & 0xff); + a += val * ((pixel >> 24) & 0xff); + r += val * (((pixel >> 16) & 0xff)); + g += val * (((pixel >> 8) & 0xff)); + b += val * (((pixel) & 0xff)); + } + int ia = alpha ? clamp((int) (a + 0.5)) : 0xff; + int ir = clamp((int) (r + 0.5)); + int ig = clamp((int) (g + 0.5)); + int ib = clamp((int) (b + 0.5)); + outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib; + index += height; + } + } + + } + + private int clamp(int value) { + if (value > 255) + return 255; + if (value < 0) + return 0; + return value; + } + + private float[] create1DKernel(int radius, int sigma) { + // guideline: 3*sigma should be the radius + int size = radius * 2 + 1; + float[] kernel = new float[size]; + int radiusSquare = radius * radius; + float sigmaSquare = 2 * sigma * sigma; + float piSigma = 2 * (float) Math.PI * sigma; + float sqrtSigmaPi2 = (float) Math.sqrt(piSigma); + int start = size / 2; + int index = 0; + float total = 0; + for (int i = -start; i <= start; i++) { + float d = i * i; + if (d > radiusSquare) { + kernel[index] = 0; + } else { + kernel[index] = (float) Math.exp(-(d) / sigmaSquare) + / sqrtSigmaPi2; + } + total += kernel[index]; + index++; + } + for (int i = 0; i < size; i++) { + kernel[i] /= total; + } + return kernel; + } + + public Rectangle getPadding() { + return new Rectangle(paddingTop, paddingRight, paddingBottom, + paddingLeft); + } + + public void setPadding(int paddingLeft, int paddingRight, int paddingTop, + int paddingBottom) { + this.paddingLeft = paddingLeft; + this.paddingRight = paddingRight; + this.paddingTop = paddingTop; + this.paddingBottom = paddingBottom; + parent.redraw(); + } + + public void setCornerRadius(int radius) { + cornerSize = radius; + parent.redraw(); + } + + public void setShadowVisible(boolean visible) { + this.shadowEnabled = visible; + parent.redraw(); + } + + public void setShadowColor(Color color) { + this.shadowColor = color; + createShadow(parent.getDisplay()); + parent.redraw(); + } + + public void setOuterKeyline(Color color) { + this.outerKeyline = color; + // TODO: HACK! Should be set based on pseudo-state. + if (color != null) { + setActive(!(color.getRed() == 255 && color.getGreen() == 255 + && color.getBlue() == 255)); + } + parent.redraw(); + } + + public void setSelectedTabFill(Color color) { + setSelectedTabFill(new Color[] { color }, new int[] { 100 }); + } + + public void setSelectedTabFill(Color[] colors, int[] percents) { + selectedTabFillColors = colors; + selectedTabFillPercents = percents; + parent.redraw(); + } + + public void setSelectedTabAreaColor(Color color) { + setSelectedTabAreaColor(new Color[] { color }, new int[] { 100 }); + } + + public void setSelectedTabAreaColor(Color[] colors, int[] percents) { + selectedTabAreaColors = colors; + selectedTabAreaPercents = percents; + parent.redraw(); + } + + public void setUnselectedTabsColor(Color color) { + setUnselectedTabsColor(new Color[] { color }, new int[] { 100 }); + } + + public void setUnselectedTabsColor(Color[] colors, int[] percents) { + unselectedTabsColors = colors; + unselectedTabsPercents = percents; + + parent.redraw(); + } + + public void setUnselectedTabsBackgroundVisible(boolean visible) { + unselectedTabsBackgroundVisible = visible; + parent.redraw(); + } + + public void setUnselectedHotTabsColorBackground(Color color) { + setHoverTabColor(new Color[] { color }, new int[] { 100 }); + } + + public void setHoverTabColor(Color color) { + setHoverTabColor(new Color[] { color }, new int[] { 100 }); + + } + + public void setHoverTabColor(Color[] colors, int[] percents) { + hoverTabColors = colors; + hoverTabPercents = percents; + parent.redraw(); + } + + public void setTabOutline(Color color) { + this.tabOutlineColor = color; + parent.redraw(); + } + + public void setInnerKeyline(Color color) { + this.innerKeyline = color; + parent.redraw(); + } + + public void setTextVisible(boolean visible) { + this.textVisible = visible; + parent.redraw(); + } + + public void setImageVisible(boolean visible) { + this.imageVisible = visible; + parent.redraw(); + } + + public void setOuterBorderVisible(boolean visible) { + this.outerBorderVisible = visible; + parent.redraw(); + } + + public void setInnerBorderVisible(boolean visible) { + this.innerBorderVisible = visible; + parent.redraw(); + } + + public void setActiveToolbarGradient(Color[] color, int[] percents) { + activeToolbar = color; + activePercents = percents; + } + + public void setInactiveToolbarGradient(Color[] color, int[] percents) { + inactiveToolbar = color; + inactivePercents = percents; + } + + public void setActive(boolean active) { + this.active = active; + } + + public void setMaximizeImage(Image maxImage) { + this.maxImage = maxImage; + } + + public void setMinimizeImage(Image minImage) { + this.minImage = minImage; + } + + public void setCloseImage(Image closeImage) { + this.closeImage = closeImage; + } + + public void setClsoeHoverImage(Image closeHoverImage) { + this.closeHoverImage = closeHoverImage; + } + + public void setNoneRender(boolean nothingToRender) { + this.nothingToRender = nothingToRender; + } + + private void drawCustomBackground(GC gc, Rectangle bounds, int state) { + boolean selected = (state & SWT.SELECTED) != 0; + Color defaultBackground = selected ? parent.getSelectionBackground() + : parent.getBackground(); + boolean vertical = selected + ? parentWrapper.isSelectionGradientVertical() + : parentWrapper.isGradientVertical(); + Rectangle partHeaderBounds = bounds; + + if (unselectedTabsBackgroundVisible) { + drawUnselectedTabBackground(gc, partHeaderBounds, state, vertical, + defaultBackground); + } + drawTabAreaBackground(gc, partHeaderBounds, state, vertical, + defaultBackground); + + int borderTop = isTabOnBottom() ? INNER_KEYLINE + OUTER_KEYLINE + : TOP_KEYLINE + OUTER_KEYLINE; + int borderBottom = isTabOnBottom() ? TOP_KEYLINE + OUTER_KEYLINE + : INNER_KEYLINE + OUTER_KEYLINE; + int bottomDropWidth = shadowEnabled ? BOTTOM_DROP_WIDTH : 0; + int sideDropWidth = shadowEnabled ? SIDE_DROP_WIDTH : 0; + int headerBorderBottom = outerBorderVisible ? OUTER_KEYLINE : 0; + Rectangle underTabAreaBounds = new Rectangle( + partHeaderBounds.x + paddingLeft + sideDropWidth, + partHeaderBounds.y + partHeaderBounds.height + bottomDropWidth + + paddingTop + headerBorderBottom, + bounds.width - paddingLeft - paddingRight - 2 * sideDropWidth, + parent.getBounds().height - partHeaderBounds.height - paddingTop + - paddingBottom - headerBorderBottom + - ((cornerSize / 4) + borderBottom + borderTop) + - bottomDropWidth * 2); + drawUnderTabAreaBackground(gc, underTabAreaBounds, state, vertical, + defaultBackground); + drawChildrenBackground(partHeaderBounds); + } + + private void drawUnderTabAreaBackground(GC gc, Rectangle tabAreaBounds, + int state, boolean vertical, Color defaultBackground) { + Color[] underTabAreaColors = new Color[] { + gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; + int[] underTabAreaPercents = new int[] { 100 }; + rendererWrapper.drawBackground(gc, tabAreaBounds.x, tabAreaBounds.y, + tabAreaBounds.width, tabAreaBounds.height, defaultBackground, + underTabAreaColors, underTabAreaPercents, vertical); + } + + private void drawUnselectedTabBackground(GC gc, Rectangle partHeaderBounds, + int state, boolean vertical, Color defaultBackground) { + if (unselectedTabsColors == null) { + boolean selected = (state & SWT.SELECTED) != 0; + unselectedTabsColors = selected + ? parentWrapper.getSelectionGradientColors() + : parentWrapper.getGradientColors(); + unselectedTabsPercents = selected + ? parentWrapper.getSelectionGradientPercents() + : parentWrapper.getGradientPercents(); + } + if (unselectedTabsColors == null) { + unselectedTabsColors = new Color[] { + gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; + unselectedTabsPercents = new int[] { 100 }; + } + + rendererWrapper.drawBackground(gc, partHeaderBounds.x, + partHeaderBounds.y, partHeaderBounds.width, + partHeaderBounds.height, defaultBackground, + unselectedTabsColors, unselectedTabsPercents, vertical); + } + + private void drawTabAreaBackground(GC gc, Rectangle partHeaderBounds, + int state, boolean vertical, Color defaultBackground) { + Color[] colors = selectedTabAreaColors; + int[] percents = selectedTabAreaPercents; + + if (colors != null && colors.length == 2) { + colors = new Color[] { colors[1], colors[1] }; + } + if (colors == null) { + boolean selected = (state & SWT.SELECTED) != 0; + colors = selected ? parentWrapper.getSelectionGradientColors() + : parentWrapper.getGradientColors(); + percents = selected ? parentWrapper.getSelectionGradientPercents() + : parentWrapper.getGradientPercents(); + } + if (colors == null) { + colors = new Color[] { + gc.getDevice().getSystemColor(SWT.COLOR_WHITE) }; + percents = new int[] { 100 }; + } + + rendererWrapper.drawBackground(gc, partHeaderBounds.x, + partHeaderBounds.y + partHeaderBounds.height, + partHeaderBounds.width, parent.getBounds().height, + defaultBackground, colors, percents, vertical); + } + + // Workaround for the bug 433276. Remove it when the bug gets fixed + private void drawChildrenBackground(Rectangle partHeaderBounds) { + for (Control control : parent.getChildren()) { + if (!CompositeElement.hasBackgroundOverriddenByCSS(control) + && containsToolbar(control)) { + drawChildBackground((Composite) control, partHeaderBounds); + } + } + } + + private boolean containsToolbar(Control control) { + if (control.getData(CONTAINS_TOOLBAR) != null) { + return true; + } + + if (control instanceof ToolBar) { + control.setData(CONTAINS_TOOLBAR, true); + return true; + } + + if (control instanceof Composite) { + for (Control child : ((Composite) control).getChildren()) { + if (child instanceof ToolBar) { + control.setData(CONTAINS_TOOLBAR, true); + return true; + } + } + } + return false; + } + + private void drawChildBackground(Composite composite, + Rectangle partHeaderBounds) { + Rectangle rec = composite.getBounds(); + Color background = null; + boolean partOfHeader = rec.y >= partHeaderBounds.y + && rec.y < partHeaderBounds.height; + + if (!partOfHeader) { + background = composite.getDisplay().getSystemColor(SWT.COLOR_WHITE); + } + CTabFolderElement.setBackgroundOverriddenDuringRenderering(composite, + background); + } + + private static class CTabFolderRendererWrapper + extends ReflectionSupport { + private Method drawBackgroundMethod; + + private Method drawCloseMethod; + + public CTabFolderRendererWrapper(CTabFolderRenderer instance) { + super(instance); + } + + public void drawBackground(GC gc, int x, int y, int width, int height, + Color defaultBackground, Color[] colors, int[] percents, + boolean vertical) { + if (drawBackgroundMethod == null) { + drawBackgroundMethod = getMethod("drawBackground", //$NON-NLS-1$ + new Class[] { GC.class, int[].class, int.class, + int.class, int.class, int.class, Color.class, + Image.class, Color[].class, int[].class, + boolean.class }); + } + executeMethod(drawBackgroundMethod, + new Object[] { gc, null, x, y, width, height, + defaultBackground, null, colors, percents, + vertical }); + } + + public void drawClose(GC gc, Rectangle closeRect, int closeImageState) { + if (drawCloseMethod == null) { + drawCloseMethod = getMethod("drawClose", new Class[] { //$NON-NLS-1$ + GC.class, Rectangle.class, int.class }); + } + executeMethod(drawCloseMethod, + new Object[] { gc, closeRect, closeImageState }); + } + } + + private static class CTabItemWrapper extends ReflectionSupport { + + private Field shortenedTextField; + + private Field shortenedTextWidthField; + + private Field closeRectField; + + private Field closeImageStateField; + + public CTabItemWrapper(CTabItem instance) { + super(instance); + } + + public String getShortenedText() { + if (shortenedTextField == null) { + shortenedTextField = getField("shortenedText"); //$NON-NLS-1$ + } + return (String) getFieldValue(shortenedTextField); + } + + public void setShortenedText(String value) { + set("shortenedText", value); //$NON-NLS-1$ + } + + public Integer getShortenedTextWidth() { + if (shortenedTextWidthField == null) { + shortenedTextWidthField = getField("shortenedTextWidth"); //$NON-NLS-1$ + } + return (Integer) getFieldValue(shortenedTextWidthField); + } + + public void setShortenedTextWidth(int value) { + set("shortenedTextWidth", value); //$NON-NLS-1$ + } + + public Rectangle getCloseRect() { + if (closeRectField == null) { + closeRectField = getField("closeRect"); //$NON-NLS-1$ + } + return (Rectangle) getFieldValue(closeRectField); + } + + public int getCloseImageState() { + if (closeImageStateField == null) { + closeImageStateField = getField("closeImageState"); //$NON-NLS-1$ + } + return (Integer) getFieldValue(closeImageStateField); + } + + } + + private static class CTabFolderWrapper + extends ReflectionSupport { + private Field selectionGradientVerticalField; + + private Field gradientVerticalField; + + private Field selectionGradientColorsField; + + private Field selectionGradientPercentsField; + + private Field gradientColorsField; + + private Field gradientPercentsField; + + private Field showCloseField; + + private Field fixedTabHeightField; + + private Method getRightItemEdgeMethod; + + public CTabFolderWrapper(CTabFolder instance) { + super(instance); + } + + public boolean isShowClose() { + if (showCloseField == null) { + showCloseField = getField("showClose"); //$NON-NLS-1$ + } + Boolean result = (Boolean) getFieldValue(showCloseField); + return result != null ? result : true; + } + + public boolean isSelectionGradientVertical() { + if (selectionGradientVerticalField == null) { + selectionGradientVerticalField = getField( + "selectionGradientVertical"); //$NON-NLS-1$ + } + Boolean result = (Boolean) getFieldValue( + selectionGradientVerticalField); + return result != null ? result : true; + } + + public boolean isGradientVertical() { + if (gradientVerticalField == null) { + gradientVerticalField = getField("gradientVertical"); //$NON-NLS-1$ + } + Boolean result = (Boolean) getFieldValue(gradientVerticalField); + return result != null ? result : true; + } + + public Color[] getSelectionGradientColors() { + if (selectionGradientColorsField == null) { + selectionGradientColorsField = getField( + "selectionGradientColorsField"); //$NON-NLS-1$ + } + return (Color[]) getFieldValue(selectionGradientColorsField); + } + + public int[] getSelectionGradientPercents() { + if (selectionGradientPercentsField == null) { + selectionGradientPercentsField = getField( + "selectionGradientPercents"); //$NON-NLS-1$ + } + return (int[]) getFieldValue(selectionGradientPercentsField); + } + + public Color[] getGradientColors() { + if (gradientColorsField == null) { + gradientColorsField = getField("gradientColors"); //$NON-NLS-1$ + } + return (Color[]) getFieldValue(gradientColorsField); + } + + public int[] getGradientPercents() { + if (gradientPercentsField == null) { + gradientPercentsField = getField("gradientPercents"); //$NON-NLS-1$ + } + return (int[]) getFieldValue(gradientPercentsField); + } + + public int getRightItemEdge(GC gc) { + if (getRightItemEdgeMethod == null) { + getRightItemEdgeMethod = getMethod("getRightItemEdge", //$NON-NLS-1$ + new Class[] { GC.class }); + } + return (Integer) executeMethod(getRightItemEdgeMethod, + new Object[] { gc }); + } + + public int getFixedTabHeight() { + if (fixedTabHeightField == null) { + fixedTabHeightField = getField("fixedTabHeight"); //$NON-NLS-1$ + } + return (Integer) getFieldValue(fixedTabHeightField); + } + } + + private static class ReflectionSupport { + private T instance; + + public ReflectionSupport(T instance) { + this.instance = instance; + } + + protected Object getFieldValue(Field field) { + Object value = null; + if (field != null) { + boolean accessible = field.isAccessible(); + try { + field.setAccessible(true); + value = field.get(instance); + } catch (Exception exc) { + // do nothing + } finally { + field.setAccessible(accessible); + } + } + return value; + } + + protected Field getField(String name) { + Class cls = instance.getClass(); + while (!cls.equals(Object.class)) { + try { + return cls.getDeclaredField(name); + } catch (Exception exc) { + cls = cls.getSuperclass(); + } + } + return null; + } + + public Object set(String name, Object value) { + try { + Field field = getField(name); + boolean accessible = field.isAccessible(); + field.setAccessible(true); + field.set(instance, value); + field.setAccessible(accessible); + return value; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected Object executeMethod(Method method, Object... params) { + Object value = null; + if (method != null) { + boolean accessible = method.isAccessible(); + try { + method.setAccessible(true); + value = method.invoke(instance, params); + } catch (Exception exc) { + // do nothing + } finally { + method.setAccessible(accessible); + } + } + return value; + } + + protected Method getMethod(String name, Class... params) { + Class cls = instance.getClass(); + while (!cls.equals(Object.class)) { + try { + return cls.getDeclaredMethod(name, params); + } catch (Exception exc) { + cls = cls.getSuperclass(); + } + } + return null; + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormHeadingElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormHeadingElement.java index 84bfbc60d..e11061043 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormHeadingElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormHeadingElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.ui.internal.forms.widgets.FormHeading; - -@SuppressWarnings("restriction") -public class FormHeadingElement extends CompositeElement { - - public FormHeadingElement(FormHeading formHeading, CSSEngine engine) { - super(formHeading, engine); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.ui.internal.forms.widgets.FormHeading; + +@SuppressWarnings("restriction") +public class FormHeadingElement extends CompositeElement { + + public FormHeadingElement(FormHeading formHeading, CSSEngine engine) { + super(formHeading, engine); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormTextElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormTextElement.java index 44fe47159..c98c1a5d0 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormTextElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/FormTextElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.ui.forms.widgets.FormText; - -@SuppressWarnings("restriction") -public class FormTextElement extends CompositeElement { - - public FormTextElement(FormText formText, CSSEngine engine) { - super(formText, engine); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.ui.forms.widgets.FormText; + +@SuppressWarnings("restriction") +public class FormTextElement extends CompositeElement { + + public FormTextElement(FormText formText, CSSEngine engine) { + super(formText, engine); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ICTabFolderRendering.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ICTabFolderRendering.java index 899dbedef..bcdb9bb24 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ICTabFolderRendering.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ICTabFolderRendering.java @@ -1,38 +1,38 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.internal.css.swt.ICTabRendering; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; - -@SuppressWarnings("restriction") -public interface ICTabFolderRendering extends ICTabRendering { - - void setTextVisible(boolean visible); - - void setImageVisible(boolean visible); - - void setOuterBorderVisible(boolean visible); - - void setInnerBorderVisible(boolean visible); - - void setHoverTabColor(Color color); - - void setHoverTabColor(Color[] colors, int[] percents); - - void setSelectedTabAreaColor(Color color); - - void setSelectedTabAreaColor(Color[] colors, int[] percents); - - void setUnselectedTabsBackgroundVisible(boolean visible); - - void setMaximizeImage(Image maxImage); - - void setMinimizeImage(Image minImage); - - void setCloseImage(Image closeImage); - - void setClsoeHoverImage(Image closeHoverImage); - - void setNoneRender(boolean nothingToRender); - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.internal.css.swt.ICTabRendering; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +@SuppressWarnings("restriction") +public interface ICTabFolderRendering extends ICTabRendering { + + void setTextVisible(boolean visible); + + void setImageVisible(boolean visible); + + void setOuterBorderVisible(boolean visible); + + void setInnerBorderVisible(boolean visible); + + void setHoverTabColor(Color color); + + void setHoverTabColor(Color[] colors, int[] percents); + + void setSelectedTabAreaColor(Color color); + + void setSelectedTabAreaColor(Color[] colors, int[] percents); + + void setUnselectedTabsBackgroundVisible(boolean visible); + + void setMaximizeImage(Image maxImage); + + void setMinimizeImage(Image minImage); + + void setCloseImage(Image closeImage); + + void setClsoeHoverImage(Image closeHoverImage); + + void setNoneRender(boolean nothingToRender); + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabBarElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabBarElement.java index 538d43741..f49e31ef0 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabBarElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabBarElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.xmind.ui.tabfolder.MTabBar; - -@SuppressWarnings("restriction") -public class MTabBarElement extends CompositeElement { - - public MTabBarElement(MTabBar tabBar, CSSEngine engine) { - super(tabBar, engine); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.xmind.ui.tabfolder.MTabBar; + +@SuppressWarnings("restriction") +public class MTabBarElement extends CompositeElement { + + public MTabBarElement(MTabBar tabBar, CSSEngine engine) { + super(tabBar, engine); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabFolderElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabFolderElement.java index 53a5eb252..7ce8f29be 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabFolderElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/MTabFolderElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.xmind.ui.tabfolder.MTabFolder; - -@SuppressWarnings("restriction") -public class MTabFolderElement extends CompositeElement { - - public MTabFolderElement(MTabFolder tabFolder, CSSEngine engine) { - super(tabFolder, engine); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.xmind.ui.tabfolder.MTabFolder; + +@SuppressWarnings("restriction") +public class MTabFolderElement extends CompositeElement { + + public MTabFolderElement(MTabFolder tabFolder, CSSEngine engine) { + super(tabFolder, engine); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ReflectionSupport.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ReflectionSupport.java index d6ff43a35..1ae1133b7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ReflectionSupport.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ReflectionSupport.java @@ -1,86 +1,86 @@ -package org.xmind.cathy.internal.css; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -public class ReflectionSupport { - - private Class type; - - public ReflectionSupport(Class type) { - this.type = type; - } - - public Object getFieldValue(Field field, T instance) { - Object value = null; - if (field != null) { - boolean accessible = field.isAccessible(); - try { - field.setAccessible(true); - value = field.get(instance); - } catch (Exception exc) { - // do nothing - } finally { - field.setAccessible(accessible); - } - } - return value; - } - - public Object getFieldValue(String name, T instance) { - Field field = getField(name); - return getFieldValue(field, instance); - } - - public Field getField(String name) { - while (!type.equals(Object.class)) { - try { - return type.getDeclaredField(name); - } catch (Exception exc) { - type = type.getSuperclass(); - } - } - return null; - } - - public Object set(Object obj, String name, Object value) { - try { - Field field = getField(name); - boolean accessible = field.isAccessible(); - field.setAccessible(true); - field.set(obj, value); - field.setAccessible(accessible); - return value; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public Object executeMethod(Method method, T instance, Object... params) { - Object value = null; - if (method != null) { - boolean accessible = method.isAccessible(); - try { - method.setAccessible(true); - value = method.invoke(instance, params); - } catch (Exception exc) { - // do nothing - } finally { - method.setAccessible(accessible); - } - } - return value; - } - - public Method getMethod(String name, Class... params) { - while (!type.equals(Object.class)) { - try { - return type.getDeclaredMethod(name, params); - } catch (Exception exc) { - type = type.getSuperclass(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.css; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class ReflectionSupport { + + private Class type; + + public ReflectionSupport(Class type) { + this.type = type; + } + + public Object getFieldValue(Field field, T instance) { + Object value = null; + if (field != null) { + boolean accessible = field.isAccessible(); + try { + field.setAccessible(true); + value = field.get(instance); + } catch (Exception exc) { + // do nothing + } finally { + field.setAccessible(accessible); + } + } + return value; + } + + public Object getFieldValue(String name, T instance) { + Field field = getField(name); + return getFieldValue(field, instance); + } + + public Field getField(String name) { + while (!type.equals(Object.class)) { + try { + return type.getDeclaredField(name); + } catch (Exception exc) { + type = type.getSuperclass(); + } + } + return null; + } + + public Object set(Object obj, String name, Object value) { + try { + Field field = getField(name); + boolean accessible = field.isAccessible(); + field.setAccessible(true); + field.set(obj, value); + field.setAccessible(accessible); + return value; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object executeMethod(Method method, T instance, Object... params) { + Object value = null; + if (method != null) { + boolean accessible = method.isAccessible(); + try { + method.setAccessible(true); + value = method.invoke(instance, params); + } catch (Exception exc) { + // do nothing + } finally { + method.setAccessible(accessible); + } + } + return value; + } + + public Method getMethod(String name, Class... params) { + while (!type.equals(Object.class)) { + try { + return type.getDeclaredMethod(name, params); + } catch (Exception exc) { + type = type.getSuperclass(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SashWidthHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SashWidthHandler.java index 35d666330..dda1ca53d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SashWidthHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SashWidthHandler.java @@ -1,71 +1,71 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.e4.ui.workbench.renderers.swt.SashLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Layout; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; - -@SuppressWarnings("restriction") -public class SashWidthHandler implements ICSSPropertyHandler { - - private static final String FIELD_SASH_WIDTH = "sashWidth"; //$NON-NLS-1$ - - private ReflectionSupport sashLayout = new ReflectionSupport( - SashLayout.class); - - public boolean applyCSSProperty(Object element, String property, - CSSValue value, String pseudo, CSSEngine engine) throws Exception { - if (!(element instanceof CompositeElement)) { - return false; - } - CompositeElement compositeElement = (CompositeElement) element; - Object nativeWidget = compositeElement.getNativeWidget(); - if (!(nativeWidget instanceof Composite)) { - return false; - } - - Composite composite = (Composite) nativeWidget; - Layout layout = composite.getLayout(); - if (!(layout instanceof SashLayout)) { - return false; - } - - if (!(value instanceof CSSPrimitiveValue)) { - return false; - } - - int newWidth = (int) ((CSSPrimitiveValue) value) - .getFloatValue(CSSPrimitiveValue.CSS_PX); - sashLayout.set(layout, FIELD_SASH_WIDTH, newWidth); - - composite.layout(true, true); - return true; - } - - public String retrieveCSSProperty(Object element, String property, - String pseudo, CSSEngine engine) throws Exception { - if (!(element instanceof CompositeElement)) { - return null; - } - CompositeElement compositeElement = (CompositeElement) element; - Object nativeWidget = compositeElement.getNativeWidget(); - if (!(nativeWidget instanceof Composite)) { - return null; - } - - Composite composite = (Composite) nativeWidget; - Layout layout = composite.getLayout(); - if (!(layout instanceof SashLayout)) { - return null; - } - - Integer width = (Integer) sashLayout.getFieldValue(FIELD_SASH_WIDTH, - (SashLayout) layout); - return Integer.toString(width); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.e4.ui.workbench.renderers.swt.SashLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; + +@SuppressWarnings("restriction") +public class SashWidthHandler implements ICSSPropertyHandler { + + private static final String FIELD_SASH_WIDTH = "sashWidth"; //$NON-NLS-1$ + + private ReflectionSupport sashLayout = new ReflectionSupport( + SashLayout.class); + + public boolean applyCSSProperty(Object element, String property, + CSSValue value, String pseudo, CSSEngine engine) throws Exception { + if (!(element instanceof CompositeElement)) { + return false; + } + CompositeElement compositeElement = (CompositeElement) element; + Object nativeWidget = compositeElement.getNativeWidget(); + if (!(nativeWidget instanceof Composite)) { + return false; + } + + Composite composite = (Composite) nativeWidget; + Layout layout = composite.getLayout(); + if (!(layout instanceof SashLayout)) { + return false; + } + + if (!(value instanceof CSSPrimitiveValue)) { + return false; + } + + int newWidth = (int) ((CSSPrimitiveValue) value) + .getFloatValue(CSSPrimitiveValue.CSS_PX); + sashLayout.set(layout, FIELD_SASH_WIDTH, newWidth); + + composite.layout(true, true); + return true; + } + + public String retrieveCSSProperty(Object element, String property, + String pseudo, CSSEngine engine) throws Exception { + if (!(element instanceof CompositeElement)) { + return null; + } + CompositeElement compositeElement = (CompositeElement) element; + Object nativeWidget = compositeElement.getNativeWidget(); + if (!(nativeWidget instanceof Composite)) { + return null; + } + + Composite composite = (Composite) nativeWidget; + Layout layout = composite.getLayout(); + if (!(layout instanceof SashLayout)) { + return null; + } + + Integer width = (Integer) sashLayout.getFieldValue(FIELD_SASH_WIDTH, + (SashLayout) layout); + return Integer.toString(width); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ScrolledFormElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ScrolledFormElement.java index d4dfa6bc4..846f53215 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ScrolledFormElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/ScrolledFormElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -@SuppressWarnings("restriction") -public class ScrolledFormElement extends CompositeElement { - - public ScrolledFormElement(ScrolledForm scrolledForm, CSSEngine engine) { - super(scrolledForm, engine); - } - +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +@SuppressWarnings("restriction") +public class ScrolledFormElement extends CompositeElement { + + public ScrolledFormElement(ScrolledForm scrolledForm, CSSEngine engine) { + super(scrolledForm, engine); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SectionElement.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SectionElement.java index 3b085f365..1fd0a19e3 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SectionElement.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/SectionElement.java @@ -1,14 +1,14 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.swt.dom.CompositeElement; -import org.eclipse.ui.forms.widgets.Section; - -@SuppressWarnings("restriction") -public class SectionElement extends CompositeElement { - - public SectionElement(Section section, CSSEngine engine) { - super(section, engine); - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.swt.dom.CompositeElement; +import org.eclipse.ui.forms.widgets.Section; + +@SuppressWarnings("restriction") +public class SectionElement extends CompositeElement { + + public SectionElement(Section section, CSSEngine engine) { + super(section, engine); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/XSWTElementProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/XSWTElementProvider.java index b13d496fa..4481a0bab 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/XSWTElementProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/css/XSWTElementProvider.java @@ -1,29 +1,29 @@ -package org.xmind.cathy.internal.css; - -import org.eclipse.e4.ui.css.core.dom.IElementProvider; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.w3c.dom.Element; -import org.xmind.ui.tabfolder.MTabBar; -import org.xmind.ui.tabfolder.MTabFolder; - -@SuppressWarnings("restriction") -public class XSWTElementProvider implements IElementProvider { - - public static final IElementProvider INSTANCE = new XSWTElementProvider(); - - public Element getElement(Object element, CSSEngine engine) { - if (element instanceof FormText) { - return new FormTextElement((FormText) element, engine); - } else if (element instanceof ScrolledForm) { - return new ScrolledFormElement((ScrolledForm) element, engine); - } else if (element instanceof MTabBar) { - return new MTabBarElement((MTabBar) element, engine); - } else if (element instanceof MTabFolder) { - return new MTabFolderElement((MTabFolder) element, engine); - } - return null; - } - -} +package org.xmind.cathy.internal.css; + +import org.eclipse.e4.ui.css.core.dom.IElementProvider; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.ui.forms.widgets.FormText; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.w3c.dom.Element; +import org.xmind.ui.tabfolder.MTabBar; +import org.xmind.ui.tabfolder.MTabFolder; + +@SuppressWarnings("restriction") +public class XSWTElementProvider implements IElementProvider { + + public static final IElementProvider INSTANCE = new XSWTElementProvider(); + + public Element getElement(Object element, CSSEngine engine) { + if (element instanceof FormText) { + return new FormTextElement((FormText) element, engine); + } else if (element instanceof ScrolledForm) { + return new ScrolledFormElement((ScrolledForm) element, engine); + } else if (element instanceof MTabBar) { + return new MTabBarElement((MTabBar) element, engine); + } else if (element instanceof MTabFolder) { + return new MTabFolderElement((MTabFolder) element, engine); + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java index 0f5efac2d..9e2dbacd7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java @@ -1,379 +1,403 @@ -package org.xmind.cathy.internal.dashboard; - -import java.io.File; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IViewer; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.CategorizedGalleryViewer; -import org.xmind.ui.gallery.GalleryEditTool; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.ClonedTemplate; -import org.xmind.ui.internal.TemplateGroup; -import org.xmind.ui.internal.wizards.TemplateLabelProvider; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.ITemplateGroup; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.texteditor.FloatingTextEditor; - -@SuppressWarnings("restriction") -public class CategorizedTemplateViewer extends CategorizedGalleryViewer - implements IAdaptable { - - private static final int FRAME_WIDTH = 215; - - private static final int FRAME_HEIGHT = 130; - - private class CategorizedTemplateContentProvider - implements ITreeContentProvider { - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - - public Object[] getElements(Object inputElement) { - if (inputElement instanceof ITemplateGroup[]) { - return (ITemplateGroup[]) inputElement; - } - - return null; - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof ITemplateGroup) { - return ((ITemplateGroup) parentElement).getTemplates() - .toArray(); - } - return null; - } - - public Object getParent(Object element) { - if (element instanceof ITemplate) { - Object input = getInput(); - if (input instanceof ITemplateGroup[]) { - ITemplateGroup[] groups = (ITemplateGroup[]) input; - for (ITemplateGroup group : groups) { - for (ITemplate template : group.getTemplates()) { - if (template.equals(element)) { - return group; - } - } - } - } - } - - return null; - } - - public boolean hasChildren(Object element) { - return (element instanceof ITemplateGroup - && ((ITemplateGroup) element).getTemplates().size() > 0); - } - } - - private static class CategorizedTemplateLabelProvider - extends TemplateLabelProvider { - - public String getText(Object element) { - if (element instanceof ITemplateGroup) { - return ((ITemplateGroup) element).getName(); - } else if (element instanceof ITemplate) { - return ((ITemplate) element).getName(); - } - - return super.getText(element); - } - } - - private class TemplateGallerySelectTool extends GallerySelectTool { - @Override - protected boolean handleKeyUp(KeyEvent ke) { - int state = ke.getState(); - int key = ke.keyCode; - if (state == 0 && key == SWT.DEL) { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection) selection) - .getFirstElement(); - if (element instanceof ITemplate) { - ITemplate template = (ITemplate) element; - if (MindMapUI.getResourceManager() - .isUserTemplate(template)) { - if (MessageDialog.openConfirm( - getControl().getShell(), - WorkbenchMessages.ConfirmDeleteTemplateDialog_title, - NLS.bind( - WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, - template.getName()))) { - MindMapUI.getResourceManager() - .removeUserTemplate(template); - } - } - } - } - } - return super.handleKeyUp(ke); - } - } - - private class TemplateNameEditTool extends GalleryEditTool { - - protected IDocument getTextContents(IPart source) { - return new org.eclipse.jface.text.Document( - ((ITemplate) source.getModel()).getName()); - } - - protected void handleTextModified(IPart source, IDocument document) { - ITemplate template = (ITemplate) source.getModel(); - if (template != null) { - modifyTemplateName(template, document.get()); - } - } - - protected void hookEditor(FloatingTextEditor editor) { - super.hookEditor(editor); - getHelper().setPrefWidth(130); - } - } - - private List sysTemplateGroups; - - private ResourceManager localResourceManager; - - public CategorizedTemplateViewer(Composite container) { - super(); - setSectionStyle(Section.COMPACT | Section.TWISTIE | Section.EXPANDED - | Section.NO_TITLE_FOCUS_BOX); - create(container); - } - - private void create(Composite parent) { - localResourceManager = new LocalResourceManager( - JFaceResources.getResources(), parent); - - setContentProvider(new CategorizedTemplateContentProvider()); - setLabelProvider(new CategorizedTemplateLabelProvider()); - - EditDomain domain = new EditDomain(); - domain.installTool(GEF.TOOL_SELECT, new TemplateGallerySelectTool()); - domain.installTool(GEF.TOOL_EDIT, new TemplateNameEditTool()); - setEditDomain(domain); - - initProperties(); - createControl(parent, SWT.WRAP); - - setInput(getViewerInput()); - - registerHelper(parent.getShell()); - } - - private void initProperties() { - Properties properties = getProperties(); - - properties.set(GalleryViewer.Horizontal, Boolean.TRUE); - properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - - properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); - properties.set(GalleryViewer.SolidFrames, true); - properties.set(GalleryViewer.FlatFrames, true); - - properties.set(GalleryViewer.ImageConstrained, true); - properties.set(GalleryViewer.ImageStretched, true); - - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_TOPLEFT, 30, 0, - new Insets(10, 0, 20, 65))); - properties.set(GalleryViewer.ContentPaneBorderWidth, 1); - properties.set(GalleryViewer.ContentPaneBorderColor, - (Color) localResourceManager - .get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ - properties.set(GalleryViewer.FrameContentSize, - new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); - - properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, - new SpaceCollaborativeEngine()); - } - - @Override - protected void configureContainer(ScrolledForm container) { - super.configureContainer(container); - container.setBackground(container.getParent().getBackground()); - } - - private Object[] getViewerInput() { - List groups = new ArrayList(); - if (sysTemplateGroups == null || sysTemplateGroups.isEmpty()) - sysTemplateGroups = MindMapUI.getResourceManager() - .getSystemTemplateGroups(); - - groups.addAll(sysTemplateGroups); - - List userTemplates = MindMapUI.getResourceManager() - .getUserTemplates(); - if (userTemplates.size() != 0) { - ITemplateGroup userGroup = new TemplateGroup( - WorkbenchMessages.TemplateViewer_UserGroup_title, - userTemplates); - groups.add(userGroup); - } - - return groups.toArray(new ITemplateGroup[groups.size()]); - } - - @Override - protected Control createSectionContent(Composite parent, Object category) { - parent.setBackground(parent.getParent().getBackground()); - getWidgetFactory().setBackground(parent.getBackground()); - - return super.createSectionContent(parent, category); - } - - protected GalleryViewer createNestedViewer() { - return new GalleryViewer(); - } - - private void registerHelper(Shell shell) { - shell.setData(ICathyConstants.HELPER_TEMPLATE_RENAME, new Runnable() { - - public void run() { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection) - .getFirstElement(); - if (obj instanceof ITemplate) { - ITemplate template = (ITemplate) obj; - startEditing(template); - } - } - } - }); - } - - public void userTemplateAdded(ITemplate template) { - if (template == null || getControl() == null - || getControl().isDisposed()) { - return; - } - - setInput(getViewerInput()); - refresh(); - reveal(new ClonedTemplate(template.getSourceWorkbookURI(), null)); - } - - public void userTemplateRemoved(ITemplate template) { - if (template == null || getControl() == null - || getControl().isDisposed()) { - return; - } - setInput(getViewerInput()); - } - - private void startEditing(ITemplate template) { - Object input = getInput(); - if (input instanceof ITemplateGroup[]) { - ITemplateGroup[] groups = (ITemplateGroup[]) input; - for (ITemplateGroup group : groups) { - if (group.getTemplates().contains(template)) { - - GalleryViewer galleryViewer = getNestedViewer(group); - EditDomain domain = galleryViewer.getEditDomain(); - ITool tool = domain.getDefaultTool(); - - ((GallerySelectTool) tool).getStatus() - .setStatus(GEF.ST_ACTIVE, true); - domain.handleRequest(GEF.REQ_EDIT, (IViewer) galleryViewer); - break; - } - } - } - } - - private boolean modifyTemplateName(ITemplate template, String newName) { - if (template == null || newName == null || newName.equals("") //$NON-NLS-1$ - || newName.equals(template.getName())) { - return false; - } - - List userTemplates = MindMapUI.getResourceManager() - .getUserTemplates(); - for (ITemplate t : userTemplates) { - if (newName.equals(t.getName())) { - return false; - } - } - - URI uri = template.getSourceWorkbookURI(); - File sourceFile = URIUtil.toFile(uri); - - File targetFile = new File(sourceFile.getParent(), - newName + FileUtils.getExtension(sourceFile.getAbsolutePath())); - boolean renameSuccess = sourceFile.renameTo(targetFile); - if (!renameSuccess) { - //TODO - } - - Object[] input = getViewerInput(); - setInput(input); - - setSelection(new StructuredSelection( - new ClonedTemplate(targetFile.toURI(), null)), true); - - return true; - } - - public T getAdapter(Class adapter) { - if (ISelectionProvider.class.equals(adapter)) { - return adapter.cast(this); - } - - return null; - } - - @Override - protected void unmapAllElements() { - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.CategorizedGalleryViewer; +import org.xmind.ui.gallery.GalleryEditTool; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.ClonedTemplate; +import org.xmind.ui.internal.TemplateGroup; +import org.xmind.ui.internal.wizards.TemplateLabelProvider; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.ITemplateGroup; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.texteditor.FloatingTextEditor; + +@SuppressWarnings("restriction") +public class CategorizedTemplateViewer extends CategorizedGalleryViewer + implements IAdaptable { + + private static final int FRAME_WIDTH = 210; + + private static final int FRAME_HEIGHT = 130; + + private class CategorizedTemplateContentProvider + implements ITreeContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof ITemplateGroup[]) { + return (ITemplateGroup[]) inputElement; + } + + return null; + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof ITemplateGroup) { + return ((ITemplateGroup) parentElement).getTemplates() + .toArray(); + } + return null; + } + + public Object getParent(Object element) { + if (element instanceof ITemplate) { + Object input = getInput(); + if (input instanceof ITemplateGroup[]) { + ITemplateGroup[] groups = (ITemplateGroup[]) input; + for (ITemplateGroup group : groups) { + for (ITemplate template : group.getTemplates()) { + if (template.equals(element)) { + return group; + } + } + } + } + } + + return null; + } + + public boolean hasChildren(Object element) { + return (element instanceof ITemplateGroup + && ((ITemplateGroup) element).getTemplates().size() > 0); + } + } + + private static class CategorizedTemplateLabelProvider + extends TemplateLabelProvider { + + public String getText(Object element) { + if (element instanceof ITemplateGroup) { + String name = ((ITemplateGroup) element).getName(); + if (name == null) + name = WorkbenchMessages.CategorizedTemplateViewer_group_untitiledName; + return name.length() <= 20 ? name + : name.substring(0, 20) + "..."; //$NON-NLS-1$ + } else if (element instanceof ITemplate) { + String name = ((ITemplate) element).getName(); + if (name == null) + name = WorkbenchMessages.CategorizedTemplateViewer_template_untitiledName; + return name.length() <= 20 ? name + : name.substring(0, 20) + "..."; //$NON-NLS-1$ + } + + return super.getText(element); + } + } + + private class TemplateGallerySelectTool extends GallerySelectTool { + @Override + protected boolean handleKeyUp(KeyEvent ke) { + int state = ke.getState(); + int key = ke.keyCode; + if (state == 0 && key == SWT.DEL) { + ISelection selection = getSelection(); + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection) selection) + .getFirstElement(); + if (element instanceof ITemplate) { + ITemplate template = (ITemplate) element; + if (MindMapUI.getResourceManager() + .isUserTemplate(template)) { + if (MessageDialog.openConfirm( + getControl().getShell(), + WorkbenchMessages.ConfirmDeleteTemplateDialog_title, + NLS.bind( + WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, + template.getName()))) { + MindMapUI.getResourceManager() + .removeUserTemplate(template); + } + } + } + } + } + return super.handleKeyUp(ke); + } + } + + private class TemplateNameEditTool extends GalleryEditTool { + + protected IDocument getTextContents(IPart source) { + return new org.eclipse.jface.text.Document( + ((ITemplate) source.getModel()).getName()); + } + + protected void handleTextModified(IPart source, IDocument document) { + ITemplate template = (ITemplate) source.getModel(); + if (template != null) { + modifyTemplateName(template, document.get()); + } + } + + protected void hookEditor(FloatingTextEditor editor) { + super.hookEditor(editor); + getHelper().setPrefWidth(130); + } + } + + private List sysTemplateGroups; + + private ResourceManager localResourceManager; + + public CategorizedTemplateViewer(Composite container) { + super(); + setSectionStyle(Section.COMPACT | Section.TWISTIE | Section.EXPANDED + | Section.NO_TITLE_FOCUS_BOX); + create(container); + } + + private void create(Composite parent) { + localResourceManager = new LocalResourceManager( + JFaceResources.getResources(), parent); + setContentProvider(new CategorizedTemplateContentProvider()); + setLabelProvider(new CategorizedTemplateLabelProvider()); + + EditDomain domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, new TemplateGallerySelectTool()); + domain.installTool(GEF.TOOL_EDIT, new TemplateNameEditTool()); + setEditDomain(domain); + + initProperties(); + createControl(parent, SWT.WRAP); + + getControl().addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + + setInput(getViewerInput()); + + registerHelper(parent.getShell()); + } + + private void handleDispose() { + unregisterHelper(getControl().getShell()); + } + + private void initProperties() { + Properties properties = getProperties(); + + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + + properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); + properties.set(GalleryViewer.SolidFrames, true); + properties.set(GalleryViewer.FlatFrames, true); + + properties.set(GalleryViewer.ImageConstrained, true); + properties.set(GalleryViewer.ImageStretched, true); + + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_TOPLEFT, 30, 0, + new Insets(10, 0, 20, 65))); + properties.set(GalleryViewer.ContentPaneBorderWidth, 1); + properties.set(GalleryViewer.ContentPaneBorderColor, + (Color) localResourceManager + .get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + + properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, + new SpaceCollaborativeEngine()); + } + + @Override + protected void configureContainer(ScrolledForm container) { + super.configureContainer(container); + container.setBackground(container.getParent().getBackground()); + } + + private Object[] getViewerInput() { + List groups = new ArrayList(); + if (sysTemplateGroups == null || sysTemplateGroups.isEmpty()) + sysTemplateGroups = MindMapUI.getResourceManager() + .getSystemTemplateGroups(); + + groups.addAll(sysTemplateGroups); + + List userTemplates = MindMapUI.getResourceManager() + .getUserTemplates(); + if (userTemplates.size() != 0) { + ITemplateGroup userGroup = new TemplateGroup( + WorkbenchMessages.TemplateViewer_UserGroup_title, + userTemplates); + groups.add(userGroup); + } + + return groups.toArray(new ITemplateGroup[groups.size()]); + } + + @Override + protected Control createSectionContent(Composite parent, Object category) { + parent.setBackground(parent.getParent().getBackground()); + getWidgetFactory().setBackground(parent.getBackground()); + + return super.createSectionContent(parent, category); + } + + protected GalleryViewer createNestedViewer() { + return new GalleryViewer(); + } + + private void registerHelper(Shell shell) { + shell.setData(ICathyConstants.HELPER_TEMPLATE_RENAME, new Runnable() { + + public void run() { + ISelection selection = getSelection(); + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + if (obj instanceof ITemplate) { + ITemplate template = (ITemplate) obj; + startEditing(template); + } + } + } + }); + } + + private void unregisterHelper(Shell shell) { + shell.setData(ICathyConstants.HELPER_TEMPLATE_RENAME, null); + } + + public void userTemplateAdded(ITemplate template) { + if (template == null || getControl() == null + || getControl().isDisposed()) { + return; + } + + setInput(getViewerInput()); + refresh(); + reveal(new ClonedTemplate(template.getSourceWorkbookURI(), null)); + } + + public void userTemplateRemoved(ITemplate template) { + if (template == null || getControl() == null + || getControl().isDisposed()) { + return; + } + setInput(getViewerInput()); + } + + private void startEditing(ITemplate template) { + Object input = getInput(); + if (input instanceof ITemplateGroup[]) { + ITemplateGroup[] groups = (ITemplateGroup[]) input; + for (ITemplateGroup group : groups) { + if (group.getTemplates().contains(template)) { + + GalleryViewer galleryViewer = getNestedViewer(group); + EditDomain domain = galleryViewer.getEditDomain(); + ITool tool = domain.getDefaultTool(); + + ((GallerySelectTool) tool).getStatus() + .setStatus(GEF.ST_ACTIVE, true); + domain.handleRequest(GEF.REQ_EDIT, (IViewer) galleryViewer); + break; + } + } + } + } + + private boolean modifyTemplateName(ITemplate template, String newName) { + if (template == null || newName == null || newName.equals("") //$NON-NLS-1$ + || newName.equals(template.getName())) { + return false; + } + + List userTemplates = MindMapUI.getResourceManager() + .getUserTemplates(); + for (ITemplate t : userTemplates) { + if (newName.equals(t.getName())) { + return false; + } + } + + URI uri = template.getSourceWorkbookURI(); + File sourceFile = URIUtil.toFile(uri); + + File targetFile = new File(sourceFile.getParent(), + newName + FileUtils.getExtension(sourceFile.getAbsolutePath())); + boolean renameSuccess = sourceFile.renameTo(targetFile); + if (!renameSuccess) { + //TODO + } + + Object[] input = getViewerInput(); + setInput(input); + + setSelection(new StructuredSelection( + new ClonedTemplate(targetFile.toURI(), null)), true); + + return true; + } + + public T getAdapter(Class adapter) { + if (ISelectionProvider.class.equals(adapter)) { + return adapter.cast(this); + } + + return null; + } + + @Override + protected void unmapAllElements() { + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardAutomationAddon.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardAutomationAddon.java index 7bc219ab1..1876c328d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardAutomationAddon.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardAutomationAddon.java @@ -1,310 +1,310 @@ - -package org.xmind.cathy.internal.dashboard; - -import java.util.Arrays; -import java.util.List; - -import javax.inject.Inject; - -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.di.extensions.EventTopic; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.MElementContainer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; -import org.eclipse.e4.ui.workbench.Selector; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.osgi.service.event.Event; -import org.xmind.cathy.internal.HandledItemMatcher; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.cathy.internal.WorkbenchMessages; - -public class DashboardAutomationAddon { - - @Inject - private EModelService modelService; - - @Inject - private MApplication application; - - private Selector itemMatcher = new HandledItemMatcher( - ICathyConstants.COMMAND_TOGGLE_DASHBOARD); - - /** - * @param modelService - * the modelService to set - */ - public void setModelService(EModelService modelService) { - this.modelService = modelService; - } - - /** - * @param application - * the application to set - */ - public void setApplication(MApplication application) { - this.application = application; - } - - public void showDashboard(MWindow window) { - if (doShowDashboard(window)) { - updateDashboardToolItems(window); - } - - //hide right parts. - hideVisiblePart(window, "org.xmind.ui.stack.right"); //$NON-NLS-1$ - } - - @Inject - @Optional - public void updateDashboardVisibilityWhenWindowTagsChanged( - @EventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) Event event) { - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(element instanceof MWindow) || !ICathyConstants.ID_MAIN_WINDOW - .equals(((MWindow) element).getElementId())) - return; - - MWindow window = (MWindow) element; - if (UIEvents.EventTypes.ADD - .equals(event.getProperty(UIEvents.EventTags.TYPE)) - && ICathyConstants.TAG_SHOW_DASHBOARD.equals( - event.getProperty(UIEvents.EventTags.NEW_VALUE))) { - if (!doShowDashboard(window)) { - window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); - return; - } - } else if (UIEvents.EventTypes.REMOVE - .equals(event.getProperty(UIEvents.EventTags.TYPE)) - && ICathyConstants.TAG_SHOW_DASHBOARD.equals( - event.getProperty(UIEvents.EventTags.OLD_VALUE))) { - if (!doHideDashboard(window)) { - window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); - return; - } - } - - updateDashboardToolItems(window); - } - - private boolean doShowDashboard(MWindow window) { - MPart dashboardPart = findReferencedDashboardPartIn(window, true); - if (dashboardPart == null) - return false; - - EPartService partService = window.getContext().get(EPartService.class); - if (partService == null) - return false; - - partService.activate(dashboardPart, true); - return partService.getActivePart() == dashboardPart; - } - - private boolean doHideDashboard(MWindow window) { - MPart dashboardPart = findReferencedDashboardPartIn(window, false); - if (dashboardPart == null) - return true; - - EPartService partService = window.getContext().get(EPartService.class); - if (partService == null) - return false; - - partService.hidePart(dashboardPart); - return partService.getActivePart() != dashboardPart; - } - - @Inject - @Optional - public void updateWindowTagsWhenDashboardVisibilityChanged( - @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(element instanceof MElementContainer)) - return; - - MElementContainer container = (MElementContainer) element; - final MWindow window = modelService.getTopLevelWindowFor(container); - if (window == null || !ICathyConstants.ID_MAIN_WINDOW - .equals(window.getElementId())) - return; - - MPart activePart = findSelectedElementIn(window, MPart.class); - if (activePart != null && ICathyConstants.ID_DASHBOARD_PART - .equals(activePart.getElementId())) { - /* - * The Dashboard is shown, we must ensure that the - * CathyShowDashboard tag is added to window. - */ - if (!window.getTags() - .contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); - } - } else { - /* - * The Dashboard is about to be hidden, we must ensure that the - * CathyShowDashboard tag is removed from the window. - */ - if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); - } - } - } - - @Inject - @Optional - public void showDashboardWhenAllEditorsAreRemoved( - @EventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { - if (!UIEvents.isREMOVE(event)) - return; - - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(element instanceof MElementContainer)) - return; - - boolean partRemoved = false; - for (Object removed : UIEvents.asIterable(event, - UIEvents.EventTags.OLD_VALUE)) { - if (removed instanceof MPart) { - partRemoved = true; - break; - } - } - - if (!partRemoved) - return; - - MWindow window = modelService - .getTopLevelWindowFor((MUIElement) element); - if (window == null || !ICathyConstants.ID_MAIN_WINDOW - .equals(window.getElementId())) - return; - - List editors = modelService.findElements(window, null, - MPart.class, Arrays.asList(ICathyConstants.TAG_EDITOR)); - if (!editors.isEmpty()) - return; - - //hide right parts. - hideVisiblePart(window, "org.xmind.ui.stack.right"); //$NON-NLS-1$ - - if (!window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); - } - } - - private MPart findReferencedDashboardPartIn(MWindow window, - boolean createIfMissing) { - MPart dashboardPart = null; - - /* - * Find Dashboard instance in window model tree. - */ - List dashboardParts = modelService.findElements(window, - ICathyConstants.ID_DASHBOARD_PART, MPart.class, null); - if (!dashboardParts.isEmpty()) { - dashboardPart = dashboardParts.get(0); - } else { - /* - * Find Dashboard instance in shared elements. - */ - for (MUIElement p : window.getChildren()) { - if (p instanceof MPart && ICathyConstants.ID_DASHBOARD_PART - .equals(p.getElementId())) { - dashboardPart = (MPart) p; - break; - } - } - } - - if (dashboardPart == null && createIfMissing) { - /* - * Create Dashboard part from snippet. - */ - MUIElement part = modelService.cloneSnippet(application, - ICathyConstants.ID_DASHBOARD_PART, window); - if (part != null && part instanceof MPart - && ICathyConstants.ID_DASHBOARD_PART - .equals(part.getElementId())) { - dashboardPart = (MPart) part; - window.getChildren().add(dashboardPart); - } - } - - return dashboardPart; - } - - private T findSelectedElementIn(MUIElement root, - Class type) { - if (type.isInstance(root)) - return type.cast(root); - - if (root instanceof MPlaceholder) - return findSelectedElementIn(((MPlaceholder) root).getRef(), type); - - if (root instanceof MElementContainer) - return findSelectedElementIn( - ((MElementContainer) root).getSelectedElement(), type); - - return null; - } - - private void updateDashboardToolItems(MWindow window) { - String tooltip; - boolean selected; - if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - tooltip = WorkbenchMessages.DashboardHideHome_tooltip; - selected = true; - } else { - tooltip = WorkbenchMessages.DashboardShowHome_tooltip; - selected = false; - } - - List items = modelService.findElements(window, - MHandledItem.class, EModelService.ANYWHERE, itemMatcher); - for (MHandledItem item : items) { - item.setTooltip(tooltip); - item.setSelected(selected); - } - } - - private static final String hideVisiblePart(MWindow window, - String partStackId) { - if (window == null || partStackId == null) { - return null; - } - - EModelService modelService = window.getContext() - .get(EModelService.class); - EPartService partService = window.getContext().get(EPartService.class); - - List partStacks = modelService.findElements(window, - partStackId, MPartStack.class, null); - if (partStacks.isEmpty()) { - return null; - } - MPartStack partStack = partStacks.get(0); - - MPart visiblePart = null; - MStackElement selectedElement = partStack.getSelectedElement(); - if (selectedElement instanceof MPlaceholder) { - MPlaceholder placeholder = (MPlaceholder) selectedElement; - visiblePart = partService.findPart(placeholder.getElementId()); - } else if (selectedElement instanceof MPart) { - visiblePart = (MPart) selectedElement; - } - - if (visiblePart != null) { - visiblePart.setVisible(false); - partService.hidePart(visiblePart); - return visiblePart.getElementId(); - } - - return null; - } - -} + +package org.xmind.cathy.internal.dashboard; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.di.extensions.EventTopic; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MElementContainer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; +import org.eclipse.e4.ui.workbench.Selector; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.osgi.service.event.Event; +import org.xmind.cathy.internal.HandledItemMatcher; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.cathy.internal.WorkbenchMessages; + +public class DashboardAutomationAddon { + + @Inject + private EModelService modelService; + + @Inject + private MApplication application; + + private Selector itemMatcher = new HandledItemMatcher( + ICathyConstants.COMMAND_TOGGLE_DASHBOARD); + + /** + * @param modelService + * the modelService to set + */ + public void setModelService(EModelService modelService) { + this.modelService = modelService; + } + + /** + * @param application + * the application to set + */ + public void setApplication(MApplication application) { + this.application = application; + } + + public void showDashboard(MWindow window) { + if (doShowDashboard(window)) { + updateDashboardToolItems(window); + } + + //hide right parts. + hideVisiblePart(window, "org.xmind.ui.stack.right"); //$NON-NLS-1$ + } + + @Inject + @Optional + public void updateDashboardVisibilityWhenWindowTagsChanged( + @EventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) Event event) { + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(element instanceof MWindow) || !ICathyConstants.ID_MAIN_WINDOW + .equals(((MWindow) element).getElementId())) + return; + + MWindow window = (MWindow) element; + if (UIEvents.EventTypes.ADD + .equals(event.getProperty(UIEvents.EventTags.TYPE)) + && ICathyConstants.TAG_SHOW_DASHBOARD.equals( + event.getProperty(UIEvents.EventTags.NEW_VALUE))) { + if (!doShowDashboard(window)) { + window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); + return; + } + } else if (UIEvents.EventTypes.REMOVE + .equals(event.getProperty(UIEvents.EventTags.TYPE)) + && ICathyConstants.TAG_SHOW_DASHBOARD.equals( + event.getProperty(UIEvents.EventTags.OLD_VALUE))) { + if (!doHideDashboard(window)) { + window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); + return; + } + } + + updateDashboardToolItems(window); + } + + private boolean doShowDashboard(MWindow window) { + MPart dashboardPart = findReferencedDashboardPartIn(window, true); + if (dashboardPart == null) + return false; + + EPartService partService = window.getContext().get(EPartService.class); + if (partService == null) + return false; + + partService.activate(dashboardPart, true); + return partService.getActivePart() == dashboardPart; + } + + private boolean doHideDashboard(MWindow window) { + MPart dashboardPart = findReferencedDashboardPartIn(window, false); + if (dashboardPart == null) + return true; + + EPartService partService = window.getContext().get(EPartService.class); + if (partService == null) + return false; + + partService.hidePart(dashboardPart); + return partService.getActivePart() != dashboardPart; + } + + @Inject + @Optional + public void updateWindowTagsWhenDashboardVisibilityChanged( + @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(element instanceof MElementContainer)) + return; + + MElementContainer container = (MElementContainer) element; + final MWindow window = modelService.getTopLevelWindowFor(container); + if (window == null || !ICathyConstants.ID_MAIN_WINDOW + .equals(window.getElementId())) + return; + + MPart activePart = findSelectedElementIn(window, MPart.class); + if (activePart != null && ICathyConstants.ID_DASHBOARD_PART + .equals(activePart.getElementId())) { + /* + * The Dashboard is shown, we must ensure that the + * CathyShowDashboard tag is added to window. + */ + if (!window.getTags() + .contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); + } + } else { + /* + * The Dashboard is about to be hidden, we must ensure that the + * CathyShowDashboard tag is removed from the window. + */ + if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); + } + } + } + + @Inject + @Optional + public void showDashboardWhenAllEditorsAreRemoved( + @EventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { + if (!UIEvents.isREMOVE(event)) + return; + + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(element instanceof MElementContainer)) + return; + + boolean partRemoved = false; + for (Object removed : UIEvents.asIterable(event, + UIEvents.EventTags.OLD_VALUE)) { + if (removed instanceof MPart) { + partRemoved = true; + break; + } + } + + if (!partRemoved) + return; + + MWindow window = modelService + .getTopLevelWindowFor((MUIElement) element); + if (window == null || !ICathyConstants.ID_MAIN_WINDOW + .equals(window.getElementId())) + return; + + List editors = modelService.findElements(window, null, + MPart.class, Arrays.asList(ICathyConstants.TAG_EDITOR)); + if (!editors.isEmpty()) + return; + + //hide right parts. + hideVisiblePart(window, "org.xmind.ui.stack.right"); //$NON-NLS-1$ + +// if (!window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { +// window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); +// } + } + + private MPart findReferencedDashboardPartIn(MWindow window, + boolean createIfMissing) { + MPart dashboardPart = null; + + /* + * Find Dashboard instance in window model tree. + */ + List dashboardParts = modelService.findElements(window, + ICathyConstants.ID_DASHBOARD_PART, MPart.class, null); + if (!dashboardParts.isEmpty()) { + dashboardPart = dashboardParts.get(0); + } else { + /* + * Find Dashboard instance in shared elements. + */ + for (MUIElement p : window.getChildren()) { + if (p instanceof MPart && ICathyConstants.ID_DASHBOARD_PART + .equals(p.getElementId())) { + dashboardPart = (MPart) p; + break; + } + } + } + + if (dashboardPart == null && createIfMissing) { + /* + * Create Dashboard part from snippet. + */ + MUIElement part = modelService.cloneSnippet(application, + ICathyConstants.ID_DASHBOARD_PART, window); + if (part != null && part instanceof MPart + && ICathyConstants.ID_DASHBOARD_PART + .equals(part.getElementId())) { + dashboardPart = (MPart) part; + window.getChildren().add(dashboardPart); + } + } + + return dashboardPart; + } + + private T findSelectedElementIn(MUIElement root, + Class type) { + if (type.isInstance(root)) + return type.cast(root); + + if (root instanceof MPlaceholder) + return findSelectedElementIn(((MPlaceholder) root).getRef(), type); + + if (root instanceof MElementContainer) + return findSelectedElementIn( + ((MElementContainer) root).getSelectedElement(), type); + + return null; + } + + private void updateDashboardToolItems(MWindow window) { + String tooltip; + boolean selected; + if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + tooltip = WorkbenchMessages.DashboardHideHome_tooltip; + selected = true; + } else { + tooltip = WorkbenchMessages.DashboardShowHome_tooltip; + selected = false; + } + + List items = modelService.findElements(window, + MHandledItem.class, EModelService.ANYWHERE, itemMatcher); + for (MHandledItem item : items) { + item.setTooltip(tooltip); + item.setSelected(selected); + } + } + + private static final String hideVisiblePart(MWindow window, + String partStackId) { + if (window == null || partStackId == null) { + return null; + } + + EModelService modelService = window.getContext() + .get(EModelService.class); + EPartService partService = window.getContext().get(EPartService.class); + + List partStacks = modelService.findElements(window, + partStackId, MPartStack.class, null); + if (partStacks.isEmpty()) { + return null; + } + MPartStack partStack = partStacks.get(0); + + MPart visiblePart = null; + MStackElement selectedElement = partStack.getSelectedElement(); + if (selectedElement instanceof MPlaceholder) { + MPlaceholder placeholder = (MPlaceholder) selectedElement; + visiblePart = partService.findPart(placeholder.getElementId()); + } else if (selectedElement instanceof MPart) { + visiblePart = (MPart) selectedElement; + } + + if (visiblePart != null) { + visiblePart.setVisible(false); + partService.hidePart(visiblePart); + return visiblePart.getElementId(); + } + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardContent.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardContent.java index a5050ef48..accfceef9 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardContent.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardContent.java @@ -1,409 +1,442 @@ -package org.xmind.cathy.internal.dashboard; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilderFactory; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.e4.core.contexts.ContextInjectionFactory; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.osgi.framework.Bundle; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.ui.internal.dashboard.pages.IDashboardPage; -import org.xmind.ui.tabfolder.MTabFolder; -import org.xmind.ui.tabfolder.MTabItem; - -public class DashboardContent { - - private static final String CONTENT_URI = "platform:/plugin/org.xmind.cathy/dashboard/dashboard.xml"; //$NON-NLS-1$ - private static final String NLS_PATH_BASE = "dashboard/dashboard"; //$NON-NLS-1$ - - private static final String TAG_DASHBOARD = "dashboard"; //$NON-NLS-1$ - private static final String TAG_PAGE = "page"; //$NON-NLS-1$ - private static final String TAG_SPACE = "space"; //$NON-NLS-1$ - private static final String TAG_COMMAND = "command"; //$NON-NLS-1$ - private static final String TAG_PARAMETER = "parameter"; //$NON-NLS-1$ - private static final String TAG_ITEM = "item"; //$NON-NLS-1$ - private static final String ATTR_ID = "id"; //$NON-NLS-1$ - private static final String ATTR_LABEL = "label"; //$NON-NLS-1$ - private static final String ATTR_ICON_URI = "iconURI"; //$NON-NLS-1$ - private static final String ATTR_CONTRIBUTION_URI = "contributionURI"; //$NON-NLS-1$ - private static final String ATTR_COMMAND_ID = "commandId"; //$NON-NLS-1$ - private static final String ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ - private static final String ATTR_WIDTH = "width"; //$NON-NLS-1$ - - private static final String VAL_FILL = "fill"; //$NON-NLS-1$ - - private static final String DATA_ID = "org.xmind.ui.dashboard.itemId"; //$NON-NLS-1$ - private static final String DATA_PARAMETERS = "org.xmind.ui.dashboard.commandParameters"; //$NON-NLS-1$ - - private static final String STATE_SELECTED_PAGE_ID = "selectedPageId"; //$NON-NLS-1$ - - private final DashboardPart part; - - private final MTabFolder tabFolder; - - private Properties nlsProperties = new Properties(); - - public DashboardContent(final DashboardPart part, - final MTabFolder tabFolder) { - this.part = part; - this.tabFolder = tabFolder; - loadFromDefaultLocation(); - tabFolder.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - Object page = event.item.getData(); - if (page instanceof IDashboardPage) { - handlePageSelected((IDashboardPage) page); - } - } - }); - tabFolder.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - MTabItem item = tabFolder.getSelection(); - String pageId = (String) item.getData(DATA_ID); - if (pageId != null) { - part.setPersistedState(STATE_SELECTED_PAGE_ID, pageId); - } - } - }); - } - - private void loadFromDefaultLocation() { - // load NLS properties - nlsProperties = CathyPlugin.getDefault() - .loadNLSProperties(NLS_PATH_BASE); - - // load content xml - try { - URL docURL = new URL(CONTENT_URI); - loadFromURL(docURL); - } catch (Exception e) { - CathyPlugin.log(e, - "Failed to load dashboard content from " + CONTENT_URI); //$NON-NLS-1$ - } - - // set primary selection - MTabItem primarySelection = findPrimarySelection(); - tabFolder.setSelection(primarySelection); - - IDashboardPage page = getDashboardPage(primarySelection); - if (page != null) { - if (page.getControl() == null || page.getControl().isDisposed()) { - page.createControl(this.tabFolder.getBody()); - primarySelection.setControl(page.getControl()); - } - handlePageSelected(page); - } - } - - private void loadFromURL(URL docURL) throws Exception { - InputStream docStream = docURL.openStream(); - try { - Document doc = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(docStream); - - Element rootElement = doc.getDocumentElement(); - if (rootElement == null - || !TAG_DASHBOARD.equals(rootElement.getNodeName())) - throw new IllegalArgumentException( - "No 'dashboard' element in " + CONTENT_URI); //$NON-NLS-1$ - - readElement(rootElement, tabFolder); - } finally { - docStream.close(); - } - } - - private void readElement(Element element, Object parent) throws Exception { - String tagName = element.getTagName(); - Object item = parent; - if (parent instanceof MTabFolder) { - if (TAG_PAGE.equals(tagName)) { - item = readPage(element, (MTabFolder) parent); - } else if (TAG_COMMAND.equals(tagName)) { - item = readCommand(element, (MTabFolder) parent); - } else if (TAG_SPACE.equals(tagName)) { - item = readSeparator(element, (MTabFolder) parent); - } else if (TAG_ITEM.equals(tagName)) { - item = readSimpleItem(element, (MTabFolder) parent); - } - } else if (parent instanceof MTabItem) { - if (TAG_PARAMETER.equals(tagName)) { - readCommandParameter(element, (MTabItem) parent); - } - } - - readChildren(element.getChildNodes(), item); - } - - private void readChildren(NodeList children, Object parent) - throws Exception { - int length = children.getLength(); - for (int i = 0; i < length; i++) { - Node childNode = children.item(i); - if (childNode.getNodeType() == Node.ELEMENT_NODE) { - readElement((Element) childNode, parent); - } - } - } - - private MTabItem readPage(Element element, MTabFolder tabFolder) - throws Exception { - String id = element.getAttribute(ATTR_ID); - if (id == null || "".equals(id)) //$NON-NLS-1$ - throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ - - String contributionURI = element.getAttribute(ATTR_CONTRIBUTION_URI); - if (contributionURI == null - || !contributionURI.startsWith("bundleclass://")) //$NON-NLS-1$ - throw new IllegalArgumentException( - "Invalid contributionURI: " + contributionURI); //$NON-NLS-1$ - String[] contributionPaths = contributionURI.substring(14).split("/"); //$NON-NLS-1$ - if (contributionPaths.length != 2) - throw new IllegalArgumentException( - "Invalid contributionURI: " + contributionURI); //$NON-NLS-1$ - String bundleId = contributionPaths[0]; - String className = contributionPaths[1]; - Class cls; - try { - Bundle bundle = Platform.getBundle(bundleId); - if (bundle == null) - throw new ClassNotFoundException(); - cls = bundle.loadClass(className); - } catch (ClassNotFoundException e) { - // ignore errors caused contribution not found - return null; - } - - Object contribution = ContextInjectionFactory.make(cls, - part.getContext()); - if (!(contribution instanceof IDashboardPage)) - throw new IllegalArgumentException( - "Invalid contribution type: " + contribution); //$NON-NLS-1$ - - final IDashboardPage page = (IDashboardPage) contribution; - page.setContext(part); - - String label = readLabel(element); - page.setTitle(label); - - ImageDescriptor icon = readIcon(element); - page.setImageDescriptor(icon); - - // add side-bar tab - MTabItem item = new MTabItem(tabFolder, SWT.RADIO); - - item.setText(page.getTitle()); - item.setImage(page.getImage()); - -// page.createControl(this.tabFolder.getBody()); -// item.setControl(page.getControl()); - - item.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - Control pageControl = page.getControl(); - if (pageControl != null) { - pageControl.dispose(); - } - page.dispose(); - } - }); - - item.setData(page); - item.setData(DATA_ID, id); - - return item; - } - - private MTabItem readCommand(Element element, MTabFolder tabFolder) - throws Exception { - String id = element.getAttribute(ATTR_ID); - if (id == null || "".equals(id)) //$NON-NLS-1$ - throw new IllegalArgumentException("No id for command."); //$NON-NLS-1$ - final String commandId = element.getAttribute(ATTR_COMMAND_ID); - if (commandId == null || "".equals(commandId)) //$NON-NLS-1$ - throw new IllegalArgumentException( - "No command id found for command"); //$NON-NLS-1$ - - String label = readLabel(element); - ImageDescriptor icon = readIcon(element); - - MTabItem item = new MTabItem(tabFolder, SWT.PUSH); - - item.setText(label); - - final Image iconImage = icon == null ? null : icon.createImage(); - item.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - iconImage.dispose(); - } - }); - item.setImage(iconImage); - - item.setData(DATA_ID, id); - item.setData(DATA_PARAMETERS, new Properties()); - - item.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - Map parameters = new HashMap(); - Properties commandParameters = (Properties) event.widget - .getData(DATA_PARAMETERS); - if (commandParameters != null) { - for (Entry en : commandParameters - .entrySet()) { - parameters.put((String) en.getKey(), en.getValue()); - } - } - part.executeCommand(commandId, parameters); - } - }); - return item; - } - - private MTabItem readSimpleItem(Element element, MTabFolder tabFolder) - throws Exception { - String id = element.getAttribute(ATTR_ID); - if (id == null || "".equals(id)) //$NON-NLS-1$ - throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ - - String label = readLabel(element); - ImageDescriptor icon = readIcon(element); - - MTabItem item = new MTabItem(tabFolder, SWT.SIMPLE); - item.setText(label); - final Image iconImage = icon.createImage(); - item.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - iconImage.dispose(); - } - }); - item.setImage(iconImage); - - item.setData(DATA_ID, id); - - return item; - } - - private MTabItem readSeparator(Element element, MTabFolder tabFolder) - throws Exception { - String id = element.getAttribute(ATTR_ID); - if (id == null || "".equals(id)) //$NON-NLS-1$ - throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ - - MTabItem item = new MTabItem(tabFolder, SWT.SEPARATOR); - - item.setData(DATA_ID, id); - - String width = element.getAttribute(ATTR_WIDTH); - if (VAL_FILL.equals(width)) { - item.setWidth(SWT.SEPARATOR_FILL); - } else if (width != null && !"".equals(width)) { //$NON-NLS-1$ - try { - int widthValue = Integer.parseInt(width, 10); - item.setWidth(widthValue); - } catch (NumberFormatException e) { - } - } - - return item; - } - - private void readCommandParameter(Element element, MTabItem item) { - String name = element.getAttribute(ATTR_NAME); - String value = element.getAttribute(ATTR_VALUE); - if (name == null || "".equals(name) //$NON-NLS-1$ - || value == null || "".equals(value)) //$NON-NLS-1$ - return; - - Properties parameters = (Properties) item.getData(DATA_PARAMETERS); - if (parameters == null) - return; - - parameters.put(name, value); - } - - private ImageDescriptor readIcon(Element element) - throws MalformedURLException { - String iconURI = element.getAttribute(ATTR_ICON_URI); - ImageDescriptor icon = (iconURI == null || "".equals(iconURI)) //$NON-NLS-1$ - ? null : ImageDescriptor.createFromURL(new URL(iconURI)); - return icon; - } - - private String readLabel(Element element) { - String label = element.getAttribute(ATTR_LABEL); - if (label.startsWith("%")) { //$NON-NLS-1$ - String nativeLabel = nlsProperties.getProperty(label.substring(1)); - if (nativeLabel != null) { - label = nativeLabel; - } - } - return label; - } - - private MTabItem findPrimarySelection() { - String lastPageId = part.getPersistedState(STATE_SELECTED_PAGE_ID); - if (lastPageId != null) { - MTabItem item = getItemById(lastPageId); - if (item != null) - return item; - } - - int itemCount = tabFolder.getItemCount(); - for (int i = 0; i < itemCount; i++) { - MTabItem item = tabFolder.getItem(i); - if ((item.getStyle() & SWT.RADIO) != 0) { - return item; - } - } - return null; - } - - public MTabItem getItemById(String pageId) { - if (pageId == null) - return null; - int itemCount = tabFolder.getItemCount(); - for (int i = 0; i < itemCount; i++) { - MTabItem item = tabFolder.getItem(i); - if (pageId.equals(item.getData(DATA_ID))) - return item; - } - return null; - } - - public String getItemId(MTabItem item) { - return (String) item.getData(DATA_ID); - } - - public IDashboardPage getDashboardPage(MTabItem item) { - Object data = item.getData(); - return data instanceof IDashboardPage ? (IDashboardPage) data : null; - } - - protected void handlePageSelected(final IDashboardPage page) { - ISelectionProvider selectionProvider = CathyPlugin.getAdapter(page, - ISelectionProvider.class); - part.setSelectionProvider(selectionProvider); - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.ui.internal.dashboard.pages.IDashboardPage; +import org.xmind.ui.tabfolder.MTabFolder; +import org.xmind.ui.tabfolder.MTabItem; + +public class DashboardContent { + + private static final String CONTENT_URI = "platform:/plugin/org.xmind.cathy/dashboard/dashboard.xml"; //$NON-NLS-1$ + private static final String NLS_PATH_BASE = "dashboard/dashboard"; //$NON-NLS-1$ + + private static final String TAG_DASHBOARD = "dashboard"; //$NON-NLS-1$ + private static final String TAG_PAGE = "page"; //$NON-NLS-1$ + private static final String TAG_SPACE = "space"; //$NON-NLS-1$ + private static final String TAG_COMMAND = "command"; //$NON-NLS-1$ + private static final String TAG_PARAMETER = "parameter"; //$NON-NLS-1$ + private static final String TAG_ITEM = "item"; //$NON-NLS-1$ + private static final String ATTR_ID = "id"; //$NON-NLS-1$ + private static final String ATTR_LABEL = "label"; //$NON-NLS-1$ + private static final String ATTR_TOOLTIP = "tooltip"; //$NON-NLS-1$ + private static final String ATTR_ICON_URI = "iconURI"; //$NON-NLS-1$ + private static final String ATTR_CONTRIBUTION_URI = "contributionURI"; //$NON-NLS-1$ + private static final String ATTR_COMMAND_ID = "commandId"; //$NON-NLS-1$ + private static final String ATTR_NAME = "name"; //$NON-NLS-1$ + private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ + private static final String ATTR_WIDTH = "width"; //$NON-NLS-1$ + private static final String ATTR_COLOR = "color"; //$NON-NLS-1$ + + private static final String VAL_FILL = "fill"; //$NON-NLS-1$ + + private static final String DATA_ID = "org.xmind.ui.dashboard.itemId"; //$NON-NLS-1$ + private static final String DATA_PARAMETERS = "org.xmind.ui.dashboard.commandParameters"; //$NON-NLS-1$ + + private static final String STATE_SELECTED_PAGE_ID = "selectedPageId"; //$NON-NLS-1$ + + private final DashboardPart part; + + private final MTabFolder tabFolder; + + private Properties nlsProperties = new Properties(); + + public DashboardContent(final DashboardPart part, + final MTabFolder tabFolder) { + this.part = part; + this.tabFolder = tabFolder; + loadFromDefaultLocation(); + tabFolder.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + Object page = event.item.getData(); + if (page instanceof IDashboardPage) { + handlePageSelected((IDashboardPage) page); + } + } + }); + tabFolder.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + MTabItem item = tabFolder.getSelection(); + String pageId = (String) item.getData(DATA_ID); + if (pageId != null) { + part.setPersistedState(STATE_SELECTED_PAGE_ID, pageId); + } + } + }); + } + + private void loadFromDefaultLocation() { + // load NLS properties + nlsProperties = CathyPlugin.getDefault() + .loadNLSProperties(NLS_PATH_BASE); + + // load content xml + try { + URL docURL = new URL(CONTENT_URI); + loadFromURL(docURL); + } catch (Exception e) { + CathyPlugin.log(e, + "Failed to load dashboard content from " + CONTENT_URI); //$NON-NLS-1$ + } + + // set primary selection + MTabItem primarySelection = findPrimarySelection(); + tabFolder.setSelection(primarySelection); + + IDashboardPage page = getDashboardPage(primarySelection); + if (page != null) { + if (page.getControl() == null || page.getControl().isDisposed()) { + page.createControl(this.tabFolder.getBody()); + primarySelection.setControl(page.getControl()); + } + handlePageSelected(page); + } + } + + private void loadFromURL(URL docURL) throws Exception { + InputStream docStream = docURL.openStream(); + try { + Document doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(docStream); + + Element rootElement = doc.getDocumentElement(); + if (rootElement == null + || !TAG_DASHBOARD.equals(rootElement.getNodeName())) + throw new IllegalArgumentException( + "No 'dashboard' element in " + CONTENT_URI); //$NON-NLS-1$ + + readElement(rootElement, tabFolder); + } finally { + docStream.close(); + } + } + + private void readElement(Element element, Object parent) throws Exception { + String tagName = element.getTagName(); + Object item = parent; + if (parent instanceof MTabFolder) { + if (TAG_PAGE.equals(tagName)) { + item = readPage(element, (MTabFolder) parent); + } else if (TAG_COMMAND.equals(tagName)) { + item = readCommand(element, (MTabFolder) parent); + } else if (TAG_SPACE.equals(tagName)) { + item = readSeparator(element, (MTabFolder) parent); + } else if (TAG_ITEM.equals(tagName)) { + item = readSimpleItem(element, (MTabFolder) parent); + } + } else if (parent instanceof MTabItem) { + if (TAG_PARAMETER.equals(tagName)) { + readCommandParameter(element, (MTabItem) parent); + } + } + + readChildren(element.getChildNodes(), item); + } + + private void readChildren(NodeList children, Object parent) + throws Exception { + int length = children.getLength(); + for (int i = 0; i < length; i++) { + Node childNode = children.item(i); + if (childNode.getNodeType() == Node.ELEMENT_NODE) { + readElement((Element) childNode, parent); + } + } + } + + private MTabItem readPage(Element element, MTabFolder tabFolder) + throws Exception { + String id = element.getAttribute(ATTR_ID); + if (id == null || "".equals(id)) //$NON-NLS-1$ + throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ + + String contributionURI = element.getAttribute(ATTR_CONTRIBUTION_URI); + if (contributionURI == null + || !contributionURI.startsWith("bundleclass://")) //$NON-NLS-1$ + throw new IllegalArgumentException( + "Invalid contributionURI: " + contributionURI); //$NON-NLS-1$ + String[] contributionPaths = contributionURI.substring(14).split("/"); //$NON-NLS-1$ + if (contributionPaths.length != 2) + throw new IllegalArgumentException( + "Invalid contributionURI: " + contributionURI); //$NON-NLS-1$ + String bundleId = contributionPaths[0]; + String className = contributionPaths[1]; + Class cls; + try { + Bundle bundle = Platform.getBundle(bundleId); + if (bundle == null) + throw new ClassNotFoundException(); + cls = bundle.loadClass(className); + } catch (ClassNotFoundException e) { + // ignore errors caused contribution not found + return null; + } + + Object contribution = ContextInjectionFactory.make(cls, + part.getContext()); + if (!(contribution instanceof IDashboardPage)) + throw new IllegalArgumentException( + "Invalid contribution type: " + contribution); //$NON-NLS-1$ + + final IDashboardPage page = (IDashboardPage) contribution; + page.setContext(part); + + String label = readLabel(element); + page.setTitle(label); + + ImageDescriptor icon = readIcon(element); + page.setImageDescriptor(icon); + + // add side-bar tab + MTabItem item = new MTabItem(tabFolder, SWT.RADIO); + + item.setText(page.getTitle()); + String tooltip = readTooltip(element); + item.setTooltipText(tooltip); + item.setImage(page.getImage()); + +// page.createControl(this.tabFolder.getBody()); +// item.setControl(page.getControl()); + + item.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + Control pageControl = page.getControl(); + if (pageControl != null) { + pageControl.dispose(); + } + page.dispose(); + } + }); + + item.setData(page); + item.setData(DATA_ID, id); + + return item; + } + + private MTabItem readCommand(Element element, MTabFolder tabFolder) + throws Exception { + String id = element.getAttribute(ATTR_ID); + if (id == null || "".equals(id)) //$NON-NLS-1$ + throw new IllegalArgumentException("No id for command."); //$NON-NLS-1$ + final String commandId = element.getAttribute(ATTR_COMMAND_ID); + if (commandId == null || "".equals(commandId)) //$NON-NLS-1$ + throw new IllegalArgumentException( + "No command id found for command"); //$NON-NLS-1$ + + String label = readLabel(element); + String tooltip = readTooltip(element); + ImageDescriptor icon = readIcon(element); + + MTabItem item = new MTabItem(tabFolder, SWT.PUSH); + + String width = element.getAttribute(ATTR_WIDTH); + if (width != null && !"".equals(width)) { //$NON-NLS-1$ + try { + int widthValue = Integer.parseInt(width, 10); + item.setWidth(widthValue); + } catch (NumberFormatException e) { + } + } + + item.setText(label); + item.setTooltipText(tooltip); + + final Image iconImage = icon == null ? null : icon.createImage(); + item.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + iconImage.dispose(); + } + }); + item.setImage(iconImage); + + item.setData(DATA_ID, id); + item.setData(DATA_PARAMETERS, new Properties()); + + item.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + Map parameters = new HashMap(); + Properties commandParameters = (Properties) event.widget + .getData(DATA_PARAMETERS); + if (commandParameters != null) { + for (Entry en : commandParameters + .entrySet()) { + parameters.put((String) en.getKey(), en.getValue()); + } + } + part.executeCommand(commandId, parameters); + } + }); + return item; + } + + private MTabItem readSimpleItem(Element element, MTabFolder tabFolder) + throws Exception { + String id = element.getAttribute(ATTR_ID); + if (id == null || "".equals(id)) //$NON-NLS-1$ + throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ + + String label = readLabel(element); + String tooltip = readTooltip(element); + ImageDescriptor icon = readIcon(element); + + MTabItem item = new MTabItem(tabFolder, SWT.SIMPLE); + item.setText(label); + item.setTooltipText(tooltip); + final Image iconImage = icon.createImage(); + item.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + iconImage.dispose(); + } + }); + item.setImage(iconImage); + + item.setData(DATA_ID, id); + + return item; + } + + private MTabItem readSeparator(Element element, MTabFolder tabFolder) + throws Exception { + String id = element.getAttribute(ATTR_ID); + if (id == null || "".equals(id)) //$NON-NLS-1$ + throw new IllegalArgumentException("No id for page."); //$NON-NLS-1$ + + MTabItem item = new MTabItem(tabFolder, SWT.SEPARATOR); + + item.setData(DATA_ID, id); + + String width = element.getAttribute(ATTR_WIDTH); + if (VAL_FILL.equals(width)) { + item.setWidth(SWT.SEPARATOR_FILL); + } else if (width != null && !"".equals(width)) { //$NON-NLS-1$ + try { + int widthValue = Integer.parseInt(width, 10); + item.setWidth(widthValue); + } catch (NumberFormatException e) { + } + } + + String color = element.getAttribute(ATTR_COLOR); + if (color != null && !"".equals(color)) //$NON-NLS-1$ + item.setColor(color); + + return item; + } + + private void readCommandParameter(Element element, MTabItem item) { + String name = element.getAttribute(ATTR_NAME); + String value = element.getAttribute(ATTR_VALUE); + if (name == null || "".equals(name) //$NON-NLS-1$ + || value == null || "".equals(value)) //$NON-NLS-1$ + return; + + Properties parameters = (Properties) item.getData(DATA_PARAMETERS); + if (parameters == null) + return; + + parameters.put(name, value); + } + + private ImageDescriptor readIcon(Element element) + throws MalformedURLException { + String iconURI = element.getAttribute(ATTR_ICON_URI); + ImageDescriptor icon = (iconURI == null || "".equals(iconURI)) //$NON-NLS-1$ + ? null : ImageDescriptor.createFromURL(new URL(iconURI)); + return icon; + } + + private String readLabel(Element element) { + String label = element.getAttribute(ATTR_LABEL); + if (label.startsWith("%")) { //$NON-NLS-1$ + String nativeLabel = nlsProperties.getProperty(label.substring(1)); + if (nativeLabel != null) { + label = nativeLabel; + } + } + return label; + } + + private String readTooltip(Element element) { + String tooltip = element.getAttribute(ATTR_TOOLTIP); + if (tooltip.startsWith("%")) { //$NON-NLS-1$ + String nativeTooltip = nlsProperties + .getProperty(tooltip.substring(1)); + if (nativeTooltip != null) { + tooltip = nativeTooltip; + } + } + return tooltip; + } + + private MTabItem findPrimarySelection() { + String lastPageId = part.getPersistedState(STATE_SELECTED_PAGE_ID); + if (lastPageId != null) { + MTabItem item = getItemById(lastPageId); + if (item != null) + return item; + } + + int itemCount = tabFolder.getItemCount(); + for (int i = 0; i < itemCount; i++) { + MTabItem item = tabFolder.getItem(i); + if ((item.getStyle() & SWT.RADIO) != 0) { + return item; + } + } + return null; + } + + public MTabItem getItemById(String pageId) { + if (pageId == null) + return null; + int itemCount = tabFolder.getItemCount(); + for (int i = 0; i < itemCount; i++) { + MTabItem item = tabFolder.getItem(i); + if (pageId.equals(item.getData(DATA_ID))) + return item; + } + return null; + } + + public String getItemId(MTabItem item) { + return (String) item.getData(DATA_ID); + } + + public IDashboardPage getDashboardPage(MTabItem item) { + Object data = item.getData(); + return data instanceof IDashboardPage ? (IDashboardPage) data : null; + } + + protected void handlePageSelected(final IDashboardPage page) { + ISelectionProvider selectionProvider = CathyPlugin.getAdapter(page, + ISelectionProvider.class); + part.setSelectionProvider(selectionProvider); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardPart.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardPart.java index 0e6e9a83f..de5e78520 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardPart.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardPart.java @@ -1,472 +1,472 @@ -package org.xmind.cathy.internal.dashboard; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.e4.core.commands.ECommandService; -import org.eclipse.e4.core.commands.EHandlerService; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.di.extensions.EventTopic; -import org.eclipse.e4.ui.di.Focus; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.commands.MCommand; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MMenu; -import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu; -import org.eclipse.e4.ui.services.EMenuService; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.commands.IElementUpdater; -import org.eclipse.ui.internal.handlers.WizardHandler; -import org.eclipse.ui.statushandlers.StatusManager; -import org.osgi.service.event.Event; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.internal.dashboard.pages.IDashboardContext; -import org.xmind.ui.internal.dashboard.pages.IDashboardPage; -import org.xmind.ui.internal.e4handlers.DisabledHandler; -import org.xmind.ui.tabfolder.MTabFolder; -import org.xmind.ui.tabfolder.MTabItem; - -/** - * A view that shows the Dashboard for the Cathy application. - * - * @author Frank Shaka - * @since 3.6.0 - */ -public class DashboardPart implements IDashboardContext { - - private static final String PERSISTED_STATE_KEY_PREFIX = "org.xmind.cathy.dashboard/"; //$NON-NLS-1$ - - /** - * A set of identifiers of commands that the Dashboard allows to be enabled. - * All other commands registered in the application will be disabled when - * the Dashboard is showing. - * - * @see #disableUnwantedCommands() - */ - private static final String[] AVAILABLE_COMMAND_IDS = { - "org.xmind.ui.command.showDashboard", //$NON-NLS-1$ - "org.xmind.ui.command.toggleDashboard", //$NON-NLS-1$ - "org.xmind.ui.command.welcome", //$NON-NLS-1$ - "org.xmind.ui.command.openWorkbook", //$NON-NLS-1$ - "org.xmind.ui.command.openHomeMap", //$NON-NLS-1$ - "org.xmind.ui.command.newWorkbook", //$NON-NLS-1$ - "org.xmind.ui.command.newFromTemplate", //$NON-NLS-1$ - "org.xmind.ui.command.clearWorkbookHistory", //$NON-NLS-1$ - "net.xmind.ui.command.checkForUpdates", //$NON-NLS-1$ - "net.xmind.ui.command.subscribeNewsletter", //$NON-NLS-1$ - "net.xmind.ui.command.feedback", //$NON-NLS-1$ - "net.xmind.ui.command.signIn", //$NON-NLS-1$ - "net.xmind.ui.command.signOut", //$NON-NLS-1$ - "net.xmind.ui.command.activatePro", //$NON-NLS-1$ - "net.xmind.ui.command.goFeaturedMaps", //$NON-NLS-1$ - "org.xmind.ui.command.showModelPart", //$NON-NLS-1$ - IWorkbenchCommandConstants.FILE_NEW, - IWorkbenchCommandConstants.FILE_IMPORT, - IWorkbenchCommandConstants.FILE_RESTART, - IWorkbenchCommandConstants.FILE_EXIT, - IWorkbenchCommandConstants.WINDOW_CLOSE_PART, - IWorkbenchCommandConstants.WINDOW_PREFERENCES, - IWorkbenchCommandConstants.VIEWS_SHOW_VIEW, - IWorkbenchCommandConstants.WINDOW_RESET_PERSPECTIVE, - IWorkbenchCommandConstants.WINDOW_ACTIVATE_EDITOR, - IWorkbenchCommandConstants.WINDOW_NEXT_EDITOR, - IWorkbenchCommandConstants.WINDOW_NEXT_VIEW, - IWorkbenchCommandConstants.WINDOW_PREVIOUS_EDITOR, - IWorkbenchCommandConstants.WINDOW_PREVIOUS_VIEW, - IWorkbenchCommandConstants.HELP_HELP_CONTENTS, - IWorkbenchCommandConstants.HELP_ABOUT, - IWorkbenchCommandConstants.WINDOW_SHOW_KEY_ASSIST // - }; - - @Inject - private IEclipseContext context; - - @Inject - private MPart partModel; - - @Inject - private EHandlerService handlerService; - - @Inject - private ECommandService commandService; - - @Inject - private ESelectionService selectionService; - - @Inject - private EMenuService menuService; - - @Inject - private EModelService modelService; - - @Inject - private MApplication application; - - private MTabFolder tabFolder; - - private Set availableCommandIds; - - private DashboardContent content; - - private ISelectionProvider selectionProvider = null; - - private ISelectionChangedListener selectionChangedListener = new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - handleSelectionChanged(event); - } - }; - - protected IEclipseContext getContext() { - return context; - } - - @PostConstruct - public void postConstruct(Composite parent) { - - // - context.set(IDashboardContext.class, this); - - tabFolder = new MTabFolder(parent); - ResourceManager resourceManager = new LocalResourceManager( - JFaceResources.getResources(), tabFolder); - tabFolder.setStyleProvider(new DashboardStyleProvider(resourceManager)); - tabFolder.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); - tabFolder.addListener(SWT.Selection, new Listener() { - public void handleEvent(org.eclipse.swt.widgets.Event event) { - handlePageSelected(); - } - }); - - availableCommandIds = new HashSet(); - availableCommandIds.addAll(Arrays.asList(AVAILABLE_COMMAND_IDS)); - - content = new DashboardContent(this, tabFolder); - - disableUnwantedCommands(); - } - - private void handlePageSelected() { - if (tabFolder == null || content == null) { - return; - } - MTabItem item = tabFolder.getSelection(); - String pageId = item == null ? null : content.getItemId(item); - partModel.getTransientData() - .put(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID, pageId); - } - - protected void executeCommand(String commandId, - Map parameters) { - if (commandService == null || handlerService == null) - return; - - ParameterizedCommand command = commandService.createCommand(commandId, - parameters); - if (command == null) - return; - - handlerService.executeHandler(command); - } - - public void setSelectionProvider(ISelectionProvider selectionProvider) { - ISelectionProvider oldSelectionProvider = this.selectionProvider; - if (selectionProvider == oldSelectionProvider) - return; - if (oldSelectionProvider != null) { - oldSelectionProvider - .removeSelectionChangedListener(selectionChangedListener); - } - this.selectionProvider = selectionProvider; - if (selectionProvider != null) { - selectionProvider - .addSelectionChangedListener(selectionChangedListener); - } - if (selectionService != null) { - selectionService.setSelection(selectionProvider == null ? null - : selectionProvider.getSelection()); - } - } - - private void handleSelectionChanged(SelectionChangedEvent event) { - if (selectionService != null) { - selectionService.setSelection(event.getSelection()); - } - } - - /** - * Disables almost all commands unless explicitly kept enabled, to make sure - * that the user can't trigger commands that may not be appropriate during - * the appearance of the Dashboard. - *

- * We activate a {@link DisabledHandler} handler object for each command to - * be disabled. These handlers are registered within the context of this - * view only, so that they do not override real handlers when the Dashboard - * is hidden. - *

- */ - private void disableUnwantedCommands() { - if (handlerService == null || application == null) - return; - - for (MCommand command : application.getCommands()) { - String commandId = command.getElementId(); - if (!availableCommandIds.contains(commandId)) { - handlerService.activateHandler(commandId, - new DisabledHandler(findElementUpdater(commandId))); - } - } - } - - /** - * Finds an element updater that knows how to decorate UI elements like the - * real handler of the command. - * - * @param commandId - * the identifier of the command to match - * @return - */ - private IElementUpdater findElementUpdater(String commandId) { - if (IWorkbenchCommandConstants.FILE_EXPORT.equals(commandId)) { - return new WizardHandler.Export(); - } else if (IWorkbenchCommandConstants.FILE_IMPORT.equals(commandId)) { - return new WizardHandler.Import(); - } - return null; - } - - @PreDestroy - public void preDestroy() { - this.content = null; - if (this.tabFolder != null) { - this.tabFolder.dispose(); - this.tabFolder = null; - } - } - - public void hideDashboard() { - MWindow window = findWindowFor(partModel); - if (window == null) { - CathyPlugin.log("Failed to find window for Dashboard part."); //$NON-NLS-1$ - return; - } - - if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); - } - } - - private static MWindow findWindowFor(MUIElement element) { - if (element == null) - return null; - if (element instanceof MWindow) - return (MWindow) element; - MPlaceholder placeholder = element.getCurSharedRef(); - if (placeholder != null) - return findWindowFor(placeholder); - return findWindowFor(element.getParent()); - } - - @Inject - @Optional - public void subscribeDashboardTransientData( - @EventTopic(UIEvents.ApplicationElement.TOPIC_TRANSIENTDATA) Event event) { - if (partModel == null - || partModel != event.getProperty(UIEvents.EventTags.ELEMENT)) - return; - - Object selectedPageId = partModel.getTransientData() - .get(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); - if (selectedPageId == null || !(selectedPageId instanceof String)) - return; - - if (this.tabFolder == null || content == null) - return; - - MTabItem item = content.getItemById((String) selectedPageId); - IDashboardPage dashboardPage = content.getDashboardPage(item); - if (dashboardPage != null) { - Control control = dashboardPage.getControl(); - if (control == null || control.isDisposed()) { - dashboardPage.createControl(this.tabFolder.getBody()); - item.setControl(dashboardPage.getControl()); - } - dashboardPage.setFocus(); - this.tabFolder.setSelection(item); - } - } - - @Focus - public void setFocus() { - if (tabFolder != null && !tabFolder.isDisposed() && content != null) { - MTabItem item = tabFolder.getSelection(); - if (item != null) { - IDashboardPage page = content.getDashboardPage(item); - if (page != null) { - page.setFocus(); - return; - } else { - Control control = item.getControl(); - if (control != null) { - control.setFocus(); - return; - } - } - } - tabFolder.setFocus(); - } - } - - public T getAdapter(Class adapter) { - if (adapter == MPart.class) - return adapter.cast(partModel); - if (context != null) - return context.get(adapter); - return null; - } - - public void registerAvailableCommandId(String commandId) { - availableCommandIds.add(commandId); - } - - public boolean registerContextMenu(Object menuParent, final String menuId) { - if (!(menuParent instanceof Control) || menuService == null - || partModel == null) { - return false; - } - Control parentControl = (Control) menuParent; - MPopupMenu menuModel = null; - for (MMenu item : partModel.getMenus()) { - if (menuId.equals(item.getElementId()) - && item instanceof MPopupMenu) { - menuModel = (MPopupMenu) item; - break; - } - } - if (menuModel == null) { - menuModel = modelService.createModelElement(MPopupMenu.class); - menuModel.setElementId(menuId); - menuModel.getTags().add("menuContribution:popup"); //$NON-NLS-1$ - partModel.getMenus().add(menuModel); - } - - if (menuModel.getWidget() instanceof Menu) { - Menu menu = (Menu) menuModel.getWidget(); - parentControl.setMenu(menu); - return true; - } - - return menuService.registerContextMenu(parentControl, menuId); - } - - public boolean openEditor(final IEditorInput input, final String editorId) { - final IWorkbenchPage page = context.get(IWorkbenchPage.class); - if (page == null) - return false; - try { - page.openEditor(input, editorId); - return true; - } catch (PartInitException e) { - StatusManager.getManager().handle(new Status(IStatus.ERROR, - CathyPlugin.PLUGIN_ID, e.getMessage(), e), - StatusManager.SHOW); - return false; - } - } - - public boolean showView(final String viewId) { - final IWorkbenchPage page = context.get(IWorkbenchPage.class); - if (page == null) - return false; - - try { - page.showView(viewId); - return true; - } catch (PartInitException e) { - StatusManager.getManager().handle(new Status(IStatus.ERROR, - CathyPlugin.PLUGIN_ID, e.getMessage(), e), - StatusManager.SHOW); - return false; - } - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.dashboard.pages.IDashboardContext#getPersistedState - * (java.lang.String) - */ - public String getPersistedState(String key) { - Assert.isLegal(key != null); - return partModel.getPersistedState() - .get(PERSISTED_STATE_KEY_PREFIX + key); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.dashboard.pages.IDashboardContext#setPersistedState - * (java.lang.String, java.lang.String) - */ - public void setPersistedState(String key, String value) { - Assert.isLegal(key != null); - if (value == null) { - partModel.getPersistedState() - .remove(PERSISTED_STATE_KEY_PREFIX + key); - } else { - partModel.getPersistedState().put(PERSISTED_STATE_KEY_PREFIX + key, - value); - } - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# - * getContextVariable(java.lang.Class) - */ - public T getContextVariable(Class key) { - return context.get(key); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# - * getContextVariable(java.lang.String) - */ - public Object getContextVariable(String key) { - return context.get(key); - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.di.extensions.EventTopic; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.commands.MCommand; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MMenu; +import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu; +import org.eclipse.e4.ui.services.EMenuService; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.internal.handlers.WizardHandler; +import org.eclipse.ui.statushandlers.StatusManager; +import org.osgi.service.event.Event; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.ui.internal.dashboard.pages.IDashboardContext; +import org.xmind.ui.internal.dashboard.pages.IDashboardPage; +import org.xmind.ui.internal.e4handlers.DisabledHandler; +import org.xmind.ui.tabfolder.MTabFolder; +import org.xmind.ui.tabfolder.MTabItem; + +/** + * A view that shows the Dashboard for the Cathy application. + * + * @author Frank Shaka + * @since 3.6.0 + */ +public class DashboardPart implements IDashboardContext { + + private static final String PERSISTED_STATE_KEY_PREFIX = "org.xmind.cathy.dashboard/"; //$NON-NLS-1$ + + /** + * A set of identifiers of commands that the Dashboard allows to be enabled. + * All other commands registered in the application will be disabled when + * the Dashboard is showing. + * + * @see #disableUnwantedCommands() + */ + private static final String[] AVAILABLE_COMMAND_IDS = { + "org.xmind.ui.command.showDashboard", //$NON-NLS-1$ + "org.xmind.ui.command.toggleDashboard", //$NON-NLS-1$ + "org.xmind.ui.command.welcome", //$NON-NLS-1$ + "org.xmind.ui.command.openWorkbook", //$NON-NLS-1$ + "org.xmind.ui.command.openHomeMap", //$NON-NLS-1$ + "org.xmind.ui.command.newWorkbook", //$NON-NLS-1$ + "org.xmind.ui.command.newFromTemplate", //$NON-NLS-1$ + "org.xmind.ui.command.clearWorkbookHistory", //$NON-NLS-1$ + "net.xmind.ui.command.checkForUpdates", //$NON-NLS-1$ + "net.xmind.ui.command.subscribeNewsletter", //$NON-NLS-1$ + "net.xmind.ui.command.feedback", //$NON-NLS-1$ + "net.xmind.ui.command.signIn", //$NON-NLS-1$ + "net.xmind.ui.command.signOut", //$NON-NLS-1$ + "net.xmind.ui.command.activatePro", //$NON-NLS-1$ + "net.xmind.ui.command.goFeaturedMaps", //$NON-NLS-1$ + "org.xmind.ui.command.showModelPart", //$NON-NLS-1$ + IWorkbenchCommandConstants.FILE_NEW, + IWorkbenchCommandConstants.FILE_IMPORT, + IWorkbenchCommandConstants.FILE_RESTART, + IWorkbenchCommandConstants.FILE_EXIT, + IWorkbenchCommandConstants.WINDOW_CLOSE_PART, + IWorkbenchCommandConstants.WINDOW_PREFERENCES, + IWorkbenchCommandConstants.VIEWS_SHOW_VIEW, + IWorkbenchCommandConstants.WINDOW_RESET_PERSPECTIVE, + IWorkbenchCommandConstants.WINDOW_ACTIVATE_EDITOR, + IWorkbenchCommandConstants.WINDOW_NEXT_EDITOR, + IWorkbenchCommandConstants.WINDOW_NEXT_VIEW, + IWorkbenchCommandConstants.WINDOW_PREVIOUS_EDITOR, + IWorkbenchCommandConstants.WINDOW_PREVIOUS_VIEW, + IWorkbenchCommandConstants.HELP_HELP_CONTENTS, + IWorkbenchCommandConstants.HELP_ABOUT, + IWorkbenchCommandConstants.WINDOW_SHOW_KEY_ASSIST // + }; + + @Inject + private IEclipseContext context; + + @Inject + private MPart partModel; + + @Inject + private EHandlerService handlerService; + + @Inject + private ECommandService commandService; + + @Inject + private ESelectionService selectionService; + + @Inject + private EMenuService menuService; + + @Inject + private EModelService modelService; + + @Inject + private MApplication application; + + private MTabFolder tabFolder; + + private Set availableCommandIds; + + private DashboardContent content; + + private ISelectionProvider selectionProvider = null; + + private ISelectionChangedListener selectionChangedListener = new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleSelectionChanged(event); + } + }; + + protected IEclipseContext getContext() { + return context; + } + + @PostConstruct + public void postConstruct(Composite parent) { + + // + context.set(IDashboardContext.class, this); + + tabFolder = new MTabFolder(parent); + ResourceManager resourceManager = new LocalResourceManager( + JFaceResources.getResources(), tabFolder); + tabFolder.setStyleProvider(new DashboardStyleProvider(resourceManager)); + tabFolder.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); + tabFolder.addListener(SWT.Selection, new Listener() { + public void handleEvent(org.eclipse.swt.widgets.Event event) { + handlePageSelected(); + } + }); + + availableCommandIds = new HashSet(); + availableCommandIds.addAll(Arrays.asList(AVAILABLE_COMMAND_IDS)); + + content = new DashboardContent(this, tabFolder); + + disableUnwantedCommands(); + } + + private void handlePageSelected() { + if (tabFolder == null || content == null) { + return; + } + MTabItem item = tabFolder.getSelection(); + String pageId = item == null ? null : content.getItemId(item); + partModel.getTransientData() + .put(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID, pageId); + } + + protected void executeCommand(String commandId, + Map parameters) { + if (commandService == null || handlerService == null) + return; + + ParameterizedCommand command = commandService.createCommand(commandId, + parameters); + if (command == null) + return; + + handlerService.executeHandler(command); + } + + public void setSelectionProvider(ISelectionProvider selectionProvider) { + ISelectionProvider oldSelectionProvider = this.selectionProvider; + if (selectionProvider == oldSelectionProvider) + return; + if (oldSelectionProvider != null) { + oldSelectionProvider + .removeSelectionChangedListener(selectionChangedListener); + } + this.selectionProvider = selectionProvider; + if (selectionProvider != null) { + selectionProvider + .addSelectionChangedListener(selectionChangedListener); + } + if (selectionService != null) { + selectionService.setSelection(selectionProvider == null ? null + : selectionProvider.getSelection()); + } + } + + private void handleSelectionChanged(SelectionChangedEvent event) { + if (selectionService != null) { + selectionService.setSelection(event.getSelection()); + } + } + + /** + * Disables almost all commands unless explicitly kept enabled, to make sure + * that the user can't trigger commands that may not be appropriate during + * the appearance of the Dashboard. + *

+ * We activate a {@link DisabledHandler} handler object for each command to + * be disabled. These handlers are registered within the context of this + * view only, so that they do not override real handlers when the Dashboard + * is hidden. + *

+ */ + private void disableUnwantedCommands() { + if (handlerService == null || application == null) + return; + + for (MCommand command : application.getCommands()) { + String commandId = command.getElementId(); + if (!availableCommandIds.contains(commandId)) { + handlerService.activateHandler(commandId, + new DisabledHandler(findElementUpdater(commandId))); + } + } + } + + /** + * Finds an element updater that knows how to decorate UI elements like the + * real handler of the command. + * + * @param commandId + * the identifier of the command to match + * @return + */ + private IElementUpdater findElementUpdater(String commandId) { + if (IWorkbenchCommandConstants.FILE_EXPORT.equals(commandId)) { + return new WizardHandler.Export(); + } else if (IWorkbenchCommandConstants.FILE_IMPORT.equals(commandId)) { + return new WizardHandler.Import(); + } + return null; + } + + @PreDestroy + public void preDestroy() { + this.content = null; + if (this.tabFolder != null) { + this.tabFolder.dispose(); + this.tabFolder = null; + } + } + + public void hideDashboard() { + MWindow window = findWindowFor(partModel); + if (window == null) { + CathyPlugin.log("Failed to find window for Dashboard part."); //$NON-NLS-1$ + return; + } + + if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); + } + } + + private static MWindow findWindowFor(MUIElement element) { + if (element == null) + return null; + if (element instanceof MWindow) + return (MWindow) element; + MPlaceholder placeholder = element.getCurSharedRef(); + if (placeholder != null) + return findWindowFor(placeholder); + return findWindowFor(element.getParent()); + } + + @Inject + @Optional + public void subscribeDashboardTransientData( + @EventTopic(UIEvents.ApplicationElement.TOPIC_TRANSIENTDATA) Event event) { + if (partModel == null + || partModel != event.getProperty(UIEvents.EventTags.ELEMENT)) + return; + + Object selectedPageId = partModel.getTransientData() + .get(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); + if (selectedPageId == null || !(selectedPageId instanceof String)) + return; + + if (this.tabFolder == null || content == null) + return; + + MTabItem item = content.getItemById((String) selectedPageId); + IDashboardPage dashboardPage = content.getDashboardPage(item); + if (dashboardPage != null) { + Control control = dashboardPage.getControl(); + if (control == null || control.isDisposed()) { + dashboardPage.createControl(this.tabFolder.getBody()); + item.setControl(dashboardPage.getControl()); + } + dashboardPage.setFocus(); + this.tabFolder.setSelection(item); + } + } + + @Focus + public void setFocus() { + if (tabFolder != null && !tabFolder.isDisposed() && content != null) { + MTabItem item = tabFolder.getSelection(); + if (item != null) { + IDashboardPage page = content.getDashboardPage(item); + if (page != null) { + page.setFocus(); + return; + } else { + Control control = item.getControl(); + if (control != null) { + control.setFocus(); + return; + } + } + } + tabFolder.setFocus(); + } + } + + public T getAdapter(Class adapter) { + if (adapter == MPart.class) + return adapter.cast(partModel); + if (context != null) + return context.get(adapter); + return null; + } + + public void registerAvailableCommandId(String commandId) { + availableCommandIds.add(commandId); + } + + public boolean registerContextMenu(Object menuParent, final String menuId) { + if (!(menuParent instanceof Control) || menuService == null + || partModel == null) { + return false; + } + Control parentControl = (Control) menuParent; + MPopupMenu menuModel = null; + for (MMenu item : partModel.getMenus()) { + if (menuId.equals(item.getElementId()) + && item instanceof MPopupMenu) { + menuModel = (MPopupMenu) item; + break; + } + } + if (menuModel == null) { + menuModel = modelService.createModelElement(MPopupMenu.class); + menuModel.setElementId(menuId); + menuModel.getTags().add("menuContribution:popup"); //$NON-NLS-1$ + partModel.getMenus().add(menuModel); + } + + if (menuModel.getWidget() instanceof Menu) { + Menu menu = (Menu) menuModel.getWidget(); + parentControl.setMenu(menu); + return true; + } + + return menuService.registerContextMenu(parentControl, menuId); + } + + public boolean openEditor(final IEditorInput input, final String editorId) { + final IWorkbenchPage page = context.get(IWorkbenchPage.class); + if (page == null) + return false; + try { + page.openEditor(input, editorId); + return true; + } catch (PartInitException e) { + StatusManager.getManager().handle(new Status(IStatus.ERROR, + CathyPlugin.PLUGIN_ID, e.getMessage(), e), + StatusManager.SHOW); + return false; + } + } + + public boolean showView(final String viewId) { + final IWorkbenchPage page = context.get(IWorkbenchPage.class); + if (page == null) + return false; + + try { + page.showView(viewId); + return true; + } catch (PartInitException e) { + StatusManager.getManager().handle(new Status(IStatus.ERROR, + CathyPlugin.PLUGIN_ID, e.getMessage(), e), + StatusManager.SHOW); + return false; + } + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.dashboard.pages.IDashboardContext#getPersistedState + * (java.lang.String) + */ + public String getPersistedState(String key) { + Assert.isLegal(key != null); + return partModel.getPersistedState() + .get(PERSISTED_STATE_KEY_PREFIX + key); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.dashboard.pages.IDashboardContext#setPersistedState + * (java.lang.String, java.lang.String) + */ + public void setPersistedState(String key, String value) { + Assert.isLegal(key != null); + if (value == null) { + partModel.getPersistedState() + .remove(PERSISTED_STATE_KEY_PREFIX + key); + } else { + partModel.getPersistedState().put(PERSISTED_STATE_KEY_PREFIX + key, + value); + } + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# + * getContextVariable(java.lang.Class) + */ + public T getContextVariable(Class key) { + return context.get(key); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# + * getContextVariable(java.lang.String) + */ + public Object getContextVariable(String key) { + return context.get(key); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardStyleProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardStyleProvider.java index 29a4ddf55..ca16a6ea7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardStyleProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/DashboardStyleProvider.java @@ -1,125 +1,125 @@ -package org.xmind.cathy.internal.dashboard; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.resource.ColorDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.RGB; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.tabfolder.MTabFolder; -import org.xmind.ui.tabfolder.MTabItem; -import org.xmind.ui.util.StyleProvider; - -public class DashboardStyleProvider extends StyleProvider { - - private ResourceManager resourceManager; - - private Map keyToRGB = new HashMap(); - - public DashboardStyleProvider(ResourceManager resourceManager) { - this.resourceManager = resourceManager; - } - - @Override - public Color getColor(Object widget, String key) { - String defaultValue = null; - if (widget instanceof MTabItem) { - MTabItem item = (MTabItem) widget; - if (FILL.equals(key) - && (item.isSelected() || item.isPreselected())) { - defaultValue = "#FFFFFF"; //$NON-NLS-1$ - } else if (TEXT.equals(key)) { - defaultValue = "#FFFFFF"; //$NON-NLS-1$ - } - } else if (widget instanceof MTabFolder) { - if (MTabFolder.TAB_BAR.equals(key)) { - defaultValue = "#535f5e"; //$NON-NLS-1$ - } - if (MTabFolder.BODY.equals(key)) { - defaultValue = "#F2F2F2"; //$NON-NLS-1$ - } - } - if (defaultValue != null) { - RGB rgb = ColorUtils.toRGB(defaultValue); - if (keyToRGB.containsKey(key)) - rgb = keyToRGB.get(key); - return (Color) resourceManager.get(ColorDescriptor.createFrom(rgb)); - } - return super.getColor(widget, key); - } - - @Override - public int getAlpha(Object widget, String key, int defaultValue) { - if (widget instanceof MTabItem) { - MTabItem item = (MTabItem) widget; - if (FILL.equals(key)) { - if (item.isSelected()) - return 0x26; - if (item.isPreselected()) - return 0x13; - } - } - return super.getAlpha(widget, key, defaultValue); - } - - @Override - public Font getFont(Object widget, String key) { - if (widget instanceof MTabItem) { - if (TEXT.equals(key)) - return (Font) resourceManager.get(JFaceResources - .getDefaultFontDescriptor().setHeight(12)); - } - return super.getFont(widget, key); - } - - @Override - public int getWidth(Object widget, String key, int defaultValue) { - if (widget instanceof MTabItem) { - if (IMAGE.equals(key)) - return 56; - if (MARGIN.equals(key)) - return 3; - if (SEPARATOR.equals(key)) - return 2; - if (key == null) - return 72; - } - return super.getWidth(widget, key, defaultValue); - } - - @Override - public int getHeight(Object widget, String key, int defaultValue) { - if (widget instanceof MTabItem) { - if (IMAGE.equals(key)) - return 45; - if (MARGIN.equals(key)) - return 6; - if (SEPARATOR.equals(key)) - return 2; - if (key == null) - return 74; - } - return super.getHeight(widget, key, defaultValue); - } - - @Override - public int getPosition(Object widget, String key, int defaultValue) { - if (widget instanceof MTabItem) { - if (TEXT.equals(key)) - return SWT.BOTTOM; - } else if (widget instanceof MTabFolder) { - if (MTabFolder.TAB_BAR.equals(key)) - return SWT.LEFT; - } - return super.getPosition(widget, key, defaultValue); - } - - public void setColor(String key, RGB value) { - keyToRGB.put(key, value); - } +package org.xmind.cathy.internal.dashboard; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.RGB; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.tabfolder.MTabFolder; +import org.xmind.ui.tabfolder.MTabItem; +import org.xmind.ui.util.StyleProvider; + +public class DashboardStyleProvider extends StyleProvider { + + private ResourceManager resourceManager; + + private Map keyToRGB = new HashMap(); + + public DashboardStyleProvider(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + @Override + public Color getColor(Object widget, String key) { + String defaultValue = null; + if (widget instanceof MTabItem) { + MTabItem item = (MTabItem) widget; + if (FILL.equals(key) + && (item.isSelected() || item.isPreselected())) { + defaultValue = "#FFFFFF"; //$NON-NLS-1$ + } else if (TEXT.equals(key)) { + defaultValue = "#FFFFFF"; //$NON-NLS-1$ + } + } else if (widget instanceof MTabFolder) { + if (MTabFolder.TAB_BAR.equals(key)) { + defaultValue = "#535f5e"; //$NON-NLS-1$ + } + if (MTabFolder.BODY.equals(key)) { + defaultValue = "#F2F2F2"; //$NON-NLS-1$ + } + } + if (defaultValue != null) { + RGB rgb = ColorUtils.toRGB(defaultValue); + if (keyToRGB.containsKey(key)) + rgb = keyToRGB.get(key); + return (Color) resourceManager.get(ColorDescriptor.createFrom(rgb)); + } + return super.getColor(widget, key); + } + + @Override + public int getAlpha(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + MTabItem item = (MTabItem) widget; + if (FILL.equals(key)) { + if (item.isSelected()) + return 0x26; + if (item.isPreselected()) + return 0x13; + } + } + return super.getAlpha(widget, key, defaultValue); + } + + @Override + public Font getFont(Object widget, String key) { + if (widget instanceof MTabItem) { + if (TEXT.equals(key)) + return (Font) resourceManager.get(JFaceResources + .getDefaultFontDescriptor().setHeight(12)); + } + return super.getFont(widget, key); + } + + @Override + public int getWidth(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + if (IMAGE.equals(key)) + return 56; + if (MARGIN.equals(key)) + return 3; + if (SEPARATOR.equals(key)) + return 2; + if (key == null) + return 72; + } + return super.getWidth(widget, key, defaultValue); + } + + @Override + public int getHeight(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + if (IMAGE.equals(key)) + return 45; + if (MARGIN.equals(key)) + return 6; + if (SEPARATOR.equals(key)) + return 2; + if (key == null) + return 74; + } + return super.getHeight(widget, key, defaultValue); + } + + @Override + public int getPosition(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + if (TEXT.equals(key)) + return SWT.BOTTOM; + } else if (widget instanceof MTabFolder) { + if (MTabFolder.TAB_BAR.equals(key)) + return SWT.LEFT; + } + return super.getPosition(widget, key, defaultValue); + } + + public void setColor(String key, RGB value) { + keyToRGB.put(key, value); + } } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFileDashboardPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFileDashboardPage.java index 48f34610e..b49abb6fd 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFileDashboardPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFileDashboardPage.java @@ -1,450 +1,462 @@ -package org.xmind.cathy.internal.dashboard; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.PostConstruct; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.ColorDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.FormAttachment; -import org.eclipse.swt.layout.FormData; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.internal.dashboard.pages.DashboardPage; -import org.xmind.ui.internal.dashboard.pages.IDashboardContext; -import org.xmind.ui.internal.dashboard.pages.IDashboardPage; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.tabfolder.MTabBar; -import org.xmind.ui.tabfolder.MTabBarItem; -import org.xmind.ui.util.StyleProvider; - -public class NewFileDashboardPage extends DashboardPage implements IAdaptable { - - private class SegmentBarStyleProvider extends StyleProvider { - @Override - public Font getFont(Object widget, String key) { - if (widget instanceof MTabBarItem) { - if (TEXT.equals(key)) - return (Font) resourceManager - .get(JFaceResources.getDefaultFontDescriptor() - .setHeight(Util.isMac() ? 10 : 12)); - } - return super.getFont(widget, key); - } - - @Override - public int getWidth(Object widget, String key, int defaultValue) { - if (widget instanceof MTabBarItem) { - if (key == null) - return 100; - } else if (widget instanceof MTabBar) { - if (BORDER.equals(key)) - return 1; - if (SEPARATOR.equals(key)) - return 1; - if (CORNER.equals(key)) - return 6; - } - return super.getWidth(widget, key, defaultValue); - } - - @Override - public int getHeight(Object widget, String key, int defaultValue) { - if (widget instanceof MTabBarItem) { - //FIXME - if (key == null) - return 26; - } else if (widget instanceof MTabBar) { - if (BORDER.equals(key)) - return 1; - if (SEPARATOR.equals(key)) - return 1; - if (CORNER.equals(key)) - return 6; - } - return super.getHeight(widget, key, defaultValue); - } - - @Override - public int getPosition(Object widget, String key, int defaultValue) { - if (widget instanceof MTabBarItem) { - if (TEXT.equals(key)) - return SWT.BOTTOM; - } - return super.getPosition(widget, key, defaultValue); - } - - @Override - public Color getColor(Object widget, String key) { - if (widget instanceof MTabBarItem) { - MTabBarItem item = (MTabBarItem) widget; - if (FILL.equals(key)) { - if (item.isSelected()) - return (Color) resourceManager.get(ColorDescriptor - .createFrom(ColorUtils.toRGB("#6B6A6B"))); //$NON-NLS-1$ - } else if (TEXT.equals(key)) { - if (item.isSelected()) - return (Color) resourceManager.get(ColorDescriptor - .createFrom(ColorUtils.toRGB("#FFFFFF"))); //$NON-NLS-1$ - return (Color) resourceManager.get(ColorDescriptor - .createFrom(ColorUtils.toRGB("#2B2A2B"))); //$NON-NLS-1$ - } - } else if (widget instanceof MTabBar) { - if (BORDER.equals(key) || SEPARATOR.equals(key)) - return (Color) resourceManager.get(ColorDescriptor - .createFrom(ColorUtils.toRGB("#A6A6A6"))); //$NON-NLS-1$ - } - return super.getColor(widget, key); - } - - @Override - public int getAlpha(Object widget, String key, int defaultValue) { - if (widget instanceof MTabBar) { - if (BORDER.equals(key)) - return 0xC0; - } - return super.getAlpha(widget, key, defaultValue); - } - } - - private Control control = null; - - private ResourceManager resourceManager = null; - - private Composite titleBar = null; - private Composite rightBar = null; - private MTabBar tabBar = null; - - private Composite pageContainer = null; - - private List pages = new ArrayList(); - - @PostConstruct - private void init(IDashboardContext dashboardContext) { - NewFromStructuresDashboardPage structurePage = new NewFromStructuresDashboardPage(); - structurePage.setTitle(WorkbenchMessages.DashboardBlankPage_name); - structurePage - .setDescription(WorkbenchMessages.DashboardBlankPage_message); - structurePage.setContext(dashboardContext); - pages.add(structurePage); - - NewFromTemplatesDashboardPage templatePage = new NewFromTemplatesDashboardPage(); - templatePage.setTitle(WorkbenchMessages.DashboardTemplatesPage_name); - templatePage.setDescription( - WorkbenchMessages.DashboardTemplatesPage_message); - templatePage.setContext(dashboardContext); - templatePage.registerAvailableCommands(); - pages.add(templatePage); - - } - - public void createControl(Composite parent) { - final Composite composite = new Composite(parent, SWT.NONE); - - this.resourceManager = new LocalResourceManager( - JFaceResources.getResources(), composite); - - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - - GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(1) - .applyTo(composite); - - Control titleBar = createTitleBar(composite); - GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 44) - .align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(titleBar); - - Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) - .grab(true, false).applyTo(separator); - - Control pageContainer = createPageContainer(composite); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) - .grab(true, true).applyTo(pageContainer); - - this.control = composite; - - for (IDashboardPage page : pages) { - MTabBarItem item = new MTabBarItem(tabBar, SWT.RADIO); - item.setText(page.getTitle()); - item.setData(page); - } - - setTitleBarComponentLayoutData(); - - showPage(tabBar.getItem(0)); - } - - private void setTitleBarComponentLayoutData() { - FormData tabData = new FormData(); - // A side can't be attached to parent, so we have to get the size first. - // CAUTION: This depends on the fact that the size won't change. - Point tabSize = tabBar.computeSize(SWT.DEFAULT, SWT.DEFAULT); - tabData.left = new FormAttachment(50, -tabSize.x / 2); - tabData.top = new FormAttachment(50, -tabSize.y / 2); - tabData.bottom = new FormAttachment(50, tabSize.y / 2); - tabBar.setLayoutData(tabData); - - FormData rightData = new FormData(); - rightData.top = new FormAttachment(0, 0); - rightData.right = new FormAttachment(100, 0); - rightData.bottom = new FormAttachment(100, 0); - rightBar.setLayoutData(rightData); - } - - private Control createTitleBar(Composite parent) { - titleBar = new Composite(parent, SWT.NONE); - FormLayout titleBarLayout = new FormLayout(); - titleBarLayout.marginWidth = 10; - titleBarLayout.marginHeight = 0; - titleBarLayout.marginRight = 15; - titleBar.setLayout(titleBarLayout); - titleBar.setForeground(parent.getForeground()); -// titleBar.setBackground(parent.getBackground()); - titleBar.setBackground((Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#ececec"))); //$NON-NLS-1$ - - Control titleLabel = createLeftTitleBarControl(titleBar); - FormData leftData = new FormData(); - leftData.top = new FormAttachment(0, 0); - leftData.left = new FormAttachment(0, 0); - leftData.bottom = new FormAttachment(100, 0); - titleLabel.setLayoutData(leftData); - - createCentralContainer(titleBar); -// FormData tabData = new FormData(); -// // A side can't be attached to parent, so we have to get the size first. -// // CAUTION: This depends on the fact that the size won't change. -// Point tabSize = tabBar.computeSize(SWT.DEFAULT, SWT.DEFAULT); -// tabData.left = new FormAttachment(50, -tabSize.x / 2); -// tabData.top = new FormAttachment(0, 0); -// tabData.bottom = new FormAttachment(100, 0); -// tabBar.setLayoutData(tabData); - - createRightBar(titleBar); -// FormData rightData = new FormData(); -// rightData.top = new FormAttachment(0, 0); -// rightData.right = new FormAttachment(100, 0); -// rightData.bottom = new FormAttachment(100, 0); -// rightBar.setLayoutData(rightData); - - return titleBar; - } - - private Control createLeftTitleBarControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 0) - .applyTo(composite); - - Label titleNameLabel = new Label(composite, SWT.WRAP); - titleNameLabel.setBackground(composite.getBackground()); - titleNameLabel.setForeground(composite.getForeground()); - titleNameLabel.setFont((Font) JFaceResources.getResources().get( - JFaceResources.getHeaderFontDescriptor().increaseHeight(-1))); - titleNameLabel.setText( - WorkbenchMessages.NewFileDashboardPage_leftTitleBar_text); - GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER) - .grab(true, true).applyTo(titleNameLabel); - - return composite; - } - - private Control createCentralContainer(Composite parent) { - tabBar = new MTabBar(parent, SWT.NONE); - tabBar.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); - tabBar.setStyleProvider(new SegmentBarStyleProvider()); - - tabBar.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - showPage((MTabBarItem) event.item); - } - }); - return tabBar; - } - - private Control createRightBar(Composite composite) { - rightBar = new Composite(composite, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(1).applyTo(rightBar); - - createImportButton(rightBar); - - return rightBar; - } - - private void createImportButton(Composite parent) { - final Label importBtton = new Label(parent, SWT.NONE); - importBtton.setBackground(parent.getBackground()); - importBtton.setToolTipText( - WorkbenchMessages.NewFileDashboardPage_Import_button); - importBtton.setImage((Image) resourceManager.get( - CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "dashboard/new/button_import.png"))); //$NON-NLS-1$ - GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER) - .grab(true, true).applyTo(importBtton); - - final IAction addTemplateAction = getAddTemplateAction(); - - importBtton.addListener(SWT.MouseDown, new Listener() { - - @Override - public void handleEvent(Event event) { - addTemplateAction.run(); - } - }); - - importBtton.addMouseTrackListener(new MouseTrackAdapter() { - - @Override - public void mouseExit(MouseEvent e) { - importBtton.setImage((Image) resourceManager.get(CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "dashboard/new/button_import.png"))); //$NON-NLS-1$ - } - - @Override - public void mouseEnter(MouseEvent e) { - importBtton.setImage((Image) resourceManager.get(CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "dashboard/new/button_import_hover.png"))); //$NON-NLS-1$ - } - }); - } - - private IAction getAddTemplateAction() { - Action addTemplateAction = new Action( - WorkbenchMessages.NewFileDashboardPage_AddTemplates_label) { - @Override - public void run() { - FileDialog dialog = new FileDialog(getShell(), SWT.OPEN); - String ext = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ - dialog.setFilterExtensions(new String[] { ext }); - dialog.setFilterNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ - WorkbenchMessages.NewFileDashboardPage_TemplateFilterName_label, - ext) }); - String path = dialog.open(); - if (path == null) - return; - - final File templateFile = new File(path); - if (templateFile != null && templateFile.exists()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - MindMapUI.getResourceManager() - .addUserTemplateFromWorkbookURI( - templateFile.toURI()); - } - }); - } - - } - }; - addTemplateAction.setToolTipText( - WorkbenchMessages.NewFileDashboardPage_AddTemplates_tooltip); - - return addTemplateAction; - } - - private Control createPageContainer(Composite parent) { - pageContainer = new Composite(parent, SWT.NONE); - pageContainer.setBackground(parent.getBackground()); - - pageContainer.setLayout(new StackLayout()); - - return pageContainer; - } - - private void showPage(MTabBarItem item) { - if (pageContainer == null || pageContainer.isDisposed()) - return; - - StackLayout layout = (StackLayout) pageContainer.getLayout(); - - if (item == null) { - layout.topControl = null; - pageContainer.layout(true); - return; - } - - IDashboardPage page = (IDashboardPage) item.getData(); - if (page != null) { - if (page.getControl() == null) { - page.createControl(pageContainer); - } - layout.topControl = page.getControl(); - pageContainer.layout(true); - - updateTitleBar(); - } - - getContext().setSelectionProvider(getAdapter(ISelectionProvider.class)); - } - - private void updateTitleBar() { - MTabBarItem item = tabBar.getSelection(); - IDashboardPage page = (IDashboardPage) item.getData(); - if (page instanceof NewFromTemplatesDashboardPage) { - rightBar.setVisible(true); - } else if (page instanceof NewFromStructuresDashboardPage) { - rightBar.setVisible(false); - } - titleBar.layout(true); - } - - public Control getControl() { - return this.control; - } - - public void setFocus() { - MTabBarItem item = tabBar.getSelection(); - if (item != null) { - IDashboardPage page = (IDashboardPage) item.getData(); - if (page != null) { - page.setFocus(); - } - } - } - - public T getAdapter(Class adapter) { - MTabBarItem item = tabBar.getSelection(); - IDashboardPage page = (IDashboardPage) item.getData(); - if (page instanceof IAdaptable) { - return ((IAdaptable) page).getAdapter(adapter); - } - - return null; - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.internal.dashboard.pages.DashboardPage; +import org.xmind.ui.internal.dashboard.pages.IDashboardContext; +import org.xmind.ui.internal.dashboard.pages.IDashboardPage; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.tabfolder.MTabBar; +import org.xmind.ui.tabfolder.MTabBarItem; +import org.xmind.ui.util.StyleProvider; + +public class NewFileDashboardPage extends DashboardPage implements IAdaptable { + + private class SegmentBarStyleProvider extends StyleProvider { + @Override + public Font getFont(Object widget, String key) { + if (widget instanceof MTabBarItem) { + if (TEXT.equals(key)) + return (Font) resourceManager + .get(JFaceResources.getDefaultFontDescriptor() + .setHeight(Util.isMac() ? 10 : 12)); + } + return super.getFont(widget, key); + } + + @Override + public int getWidth(Object widget, String key, int defaultValue) { + if (widget instanceof MTabBarItem) { + if (key == null) + return 100; + } else if (widget instanceof MTabBar) { + if (BORDER.equals(key)) + return 1; + if (SEPARATOR.equals(key)) + return 1; + if (CORNER.equals(key)) + return 6; + } + return super.getWidth(widget, key, defaultValue); + } + + @Override + public int getHeight(Object widget, String key, int defaultValue) { + if (widget instanceof MTabBarItem) { + //FIXME + if (key == null) + return 26; + } else if (widget instanceof MTabBar) { + if (BORDER.equals(key)) + return 1; + if (SEPARATOR.equals(key)) + return 1; + if (CORNER.equals(key)) + return 6; + } + return super.getHeight(widget, key, defaultValue); + } + + @Override + public int getPosition(Object widget, String key, int defaultValue) { + if (widget instanceof MTabBarItem) { + if (TEXT.equals(key)) + return SWT.BOTTOM; + } + return super.getPosition(widget, key, defaultValue); + } + + @Override + public Color getColor(Object widget, String key) { + if (widget instanceof MTabBarItem) { + MTabBarItem item = (MTabBarItem) widget; + if (FILL.equals(key)) { + if (item.isSelected()) + return (Color) resourceManager.get(ColorDescriptor + .createFrom(ColorUtils.toRGB("#6B6A6B"))); //$NON-NLS-1$ + } else if (TEXT.equals(key)) { + if (item.isSelected()) + return (Color) resourceManager.get(ColorDescriptor + .createFrom(ColorUtils.toRGB("#FFFFFF"))); //$NON-NLS-1$ + return (Color) resourceManager.get(ColorDescriptor + .createFrom(ColorUtils.toRGB("#2B2A2B"))); //$NON-NLS-1$ + } + } else if (widget instanceof MTabBar) { + if (BORDER.equals(key) || SEPARATOR.equals(key)) + return (Color) resourceManager.get(ColorDescriptor + .createFrom(ColorUtils.toRGB("#A6A6A6"))); //$NON-NLS-1$ + } + return super.getColor(widget, key); + } + + @Override + public int getAlpha(Object widget, String key, int defaultValue) { + if (widget instanceof MTabBar) { + if (BORDER.equals(key)) + return 0xC0; + } + return super.getAlpha(widget, key, defaultValue); + } + } + + private Control control = null; + + private ResourceManager resourceManager = null; + + private Composite titleBar = null; + private Composite rightBar = null; + private MTabBar tabBar = null; + + private Composite pageContainer = null; + + private List pages = new ArrayList(); + + @PostConstruct + private void init(IDashboardContext dashboardContext) { + NewFromStructuresDashboardPage structurePage = new NewFromStructuresDashboardPage(); + structurePage.setTitle(WorkbenchMessages.DashboardBlankPage_name); + structurePage + .setDescription(WorkbenchMessages.DashboardBlankPage_message); + structurePage.setContext(dashboardContext); + pages.add(structurePage); + + NewFromTemplatesDashboardPage templatePage = new NewFromTemplatesDashboardPage(); + templatePage.setTitle(WorkbenchMessages.DashboardTemplatesPage_name); + templatePage.setDescription( + WorkbenchMessages.DashboardTemplatesPage_message); + templatePage.setContext(dashboardContext); + templatePage.registerAvailableCommands(); + pages.add(templatePage); + + } + + public void createControl(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + + this.resourceManager = new LocalResourceManager( + JFaceResources.getResources(), composite); + + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + + GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(1) + .applyTo(composite); + + Control titleBar = createTitleBar(composite); + GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 44) + .align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(titleBar); + + Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) + .grab(true, false).applyTo(separator); + + Control pageContainer = createPageContainer(composite); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) + .grab(true, true).applyTo(pageContainer); + + this.control = composite; + + for (IDashboardPage page : pages) { + MTabBarItem item = new MTabBarItem(tabBar, SWT.RADIO); + item.setText(page.getTitle()); + item.setData(page); + } + + setTitleBarComponentLayoutData(); + + showPage(tabBar.getItem(0)); + } + + private void setTitleBarComponentLayoutData() { + FormData tabData = new FormData(); + // A side can't be attached to parent, so we have to get the size first. + // CAUTION: This depends on the fact that the size won't change. + Point tabSize = tabBar.computeSize(SWT.DEFAULT, SWT.DEFAULT); + tabData.left = new FormAttachment(50, -tabSize.x / 2); + tabData.top = new FormAttachment(50, -tabSize.y / 2); + tabData.bottom = new FormAttachment(50, tabSize.y / 2); + tabBar.setLayoutData(tabData); + + FormData rightData = new FormData(); + rightData.top = new FormAttachment(0, 0); + rightData.right = new FormAttachment(100, 0); + rightData.bottom = new FormAttachment(100, 0); + rightBar.setLayoutData(rightData); + } + + private Control createTitleBar(Composite parent) { + titleBar = new Composite(parent, SWT.NONE); + FormLayout titleBarLayout = new FormLayout(); + titleBarLayout.marginWidth = 10; + titleBarLayout.marginHeight = 0; + titleBarLayout.marginRight = 15; + titleBar.setLayout(titleBarLayout); + titleBar.setForeground(parent.getForeground()); +// titleBar.setBackground(parent.getBackground()); + titleBar.setBackground((Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#ececec"))); //$NON-NLS-1$ + + Control titleLabel = createLeftTitleBarControl(titleBar); + FormData leftData = new FormData(); + leftData.top = new FormAttachment(0, 0); + leftData.left = new FormAttachment(0, 0); + leftData.bottom = new FormAttachment(100, 0); + titleLabel.setLayoutData(leftData); + + createCentralContainer(titleBar); +// FormData tabData = new FormData(); +// // A side can't be attached to parent, so we have to get the size first. +// // CAUTION: This depends on the fact that the size won't change. +// Point tabSize = tabBar.computeSize(SWT.DEFAULT, SWT.DEFAULT); +// tabData.left = new FormAttachment(50, -tabSize.x / 2); +// tabData.top = new FormAttachment(0, 0); +// tabData.bottom = new FormAttachment(100, 0); +// tabBar.setLayoutData(tabData); + + createRightBar(titleBar); +// FormData rightData = new FormData(); +// rightData.top = new FormAttachment(0, 0); +// rightData.right = new FormAttachment(100, 0); +// rightData.bottom = new FormAttachment(100, 0); +// rightBar.setLayoutData(rightData); + + return titleBar; + } + + private Control createLeftTitleBarControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 0) + .applyTo(composite); + + Label titleNameLabel = new Label(composite, SWT.WRAP); + titleNameLabel.setBackground(composite.getBackground()); + titleNameLabel.setForeground(composite.getForeground()); + titleNameLabel.setFont((Font) JFaceResources.getResources().get( + JFaceResources.getHeaderFontDescriptor().increaseHeight(-1))); + titleNameLabel.setText( + WorkbenchMessages.NewFileDashboardPage_leftTitleBar_text); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER) + .grab(true, true).applyTo(titleNameLabel); + + return composite; + } + + private Control createCentralContainer(Composite parent) { + tabBar = new MTabBar(parent, SWT.NONE); + tabBar.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); + tabBar.setStyleProvider(new SegmentBarStyleProvider()); + + tabBar.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + showPage((MTabBarItem) event.item); + } + }); + return tabBar; + } + + private Control createRightBar(Composite composite) { + rightBar = new Composite(composite, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(rightBar); + + createImportButton(rightBar); + + return rightBar; + } + + private void createImportButton(Composite parent) { + final Label importBtton = new Label(parent, SWT.NONE); + importBtton.setBackground(parent.getBackground()); + importBtton.setToolTipText( + WorkbenchMessages.NewFileDashboardPage_Import_button); + importBtton.setImage((Image) resourceManager.get( + CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "dashboard/new/button_import.png"))); //$NON-NLS-1$ + GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER) + .grab(true, true).applyTo(importBtton); + + final IAction addTemplateAction = getAddTemplateAction(); + + importBtton.addListener(SWT.MouseDown, new Listener() { + + @Override + public void handleEvent(Event event) { + addTemplateAction.run(); + } + }); + + importBtton.addMouseTrackListener(new MouseTrackAdapter() { + + @Override + public void mouseExit(MouseEvent e) { + importBtton.setImage((Image) resourceManager.get(CathyPlugin + .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "dashboard/new/button_import.png"))); //$NON-NLS-1$ + } + + @Override + public void mouseEnter(MouseEvent e) { + importBtton.setImage((Image) resourceManager.get(CathyPlugin + .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "dashboard/new/button_import_hover.png"))); //$NON-NLS-1$ + } + }); + } + + private IAction getAddTemplateAction() { + Action addTemplateAction = new Action( + WorkbenchMessages.NewFileDashboardPage_AddTemplates_label) { + @Override + public void run() { + FileDialog dialog = new FileDialog(getShell(), SWT.OPEN); + String ext = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ + dialog.setFilterExtensions(new String[] { ext }); + dialog.setFilterNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ + WorkbenchMessages.NewFileDashboardPage_TemplateFilterName_label, + ext) }); + String path = dialog.open(); + if (path == null) + return; + + final File templateFile = new File(path); + if (templateFile != null && templateFile.exists()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + MindMapUI.getResourceManager() + .addUserTemplateFromWorkbookURI( + templateFile.toURI()); + } + }); + } + + } + }; + addTemplateAction.setToolTipText( + WorkbenchMessages.NewFileDashboardPage_AddTemplates_tooltip); + + return addTemplateAction; + } + + private Control createPageContainer(Composite parent) { + pageContainer = new Composite(parent, SWT.NONE); + pageContainer.setBackground(parent.getBackground()); + + pageContainer.setLayout(new StackLayout()); + + return pageContainer; + } + + private void showPage(MTabBarItem item) { + if (pageContainer == null || pageContainer.isDisposed()) + return; + + StackLayout layout = (StackLayout) pageContainer.getLayout(); + + if (item == null) { + layout.topControl = null; + pageContainer.layout(true); + return; + } + + IDashboardPage page = (IDashboardPage) item.getData(); + if (page != null) { + if (page.getControl() == null) { + page.createControl(pageContainer); + } + layout.topControl = page.getControl(); + pageContainer.layout(true); + + updateTitleBar(); + } + + getContext().setSelectionProvider(getAdapter(ISelectionProvider.class)); + } + + @Override + public void dispose() { + if (pages != null) { + for (IDashboardPage page : pages) { + page.dispose(); + } + pages.clear(); + pages = null; + } + super.dispose(); + } + + private void updateTitleBar() { + MTabBarItem item = tabBar.getSelection(); + IDashboardPage page = (IDashboardPage) item.getData(); + if (page instanceof NewFromTemplatesDashboardPage) { + rightBar.setVisible(true); + } else if (page instanceof NewFromStructuresDashboardPage) { + rightBar.setVisible(false); + } + titleBar.layout(true); + } + + public Control getControl() { + return this.control; + } + + public void setFocus() { + MTabBarItem item = tabBar.getSelection(); + if (item != null) { + IDashboardPage page = (IDashboardPage) item.getData(); + if (page != null) { + page.setFocus(); + } + } + } + + public T getAdapter(Class adapter) { + MTabBarItem item = tabBar.getSelection(); + IDashboardPage page = (IDashboardPage) item.getData(); + if (page instanceof IAdaptable) { + return ((IAdaptable) page).getAdapter(adapter); + } + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromStructuresDashboardPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromStructuresDashboardPage.java index 7a5d1bf36..166f766c2 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromStructuresDashboardPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromStructuresDashboardPage.java @@ -1,159 +1,168 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.xmind.cathy.internal.dashboard.StructureListContentProvider.StructureDescriptor; -import org.xmind.core.style.IStyle; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dashboard.pages.DashboardPage; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.mindmap.WorkbookInitializer; -import org.xmind.ui.resources.ColorUtils; - -@SuppressWarnings("restriction") -public class NewFromStructuresDashboardPage extends DashboardPage - implements IAdaptable { - - private GalleryViewer viewer; - - private ResourceManager resources; - - public void setFocus() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.getControl().setFocus(); - } - } - - public void createControl(Composite parent) { - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - - viewer = new GalleryViewer(); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); - viewer.setEditDomain(editDomain); - - Properties properties = viewer.getProperties(); - properties.set(GalleryViewer.Horizontal, Boolean.TRUE); - properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); - properties.set(GalleryViewer.SolidFrames, true); - properties.set(GalleryViewer.FlatFrames, true); - properties.set(GalleryViewer.ImageConstrained, true); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_TOPLEFT, 30, 0, - new Insets(10, 65, 20, 65))); - properties.set(GalleryViewer.ContentPaneBorderWidth, 1); - properties.set(GalleryViewer.ContentPaneBorderColor, - (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ - - properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, - new SpaceCollaborativeEngine()); - - Control control = viewer.createControl(parent); - control.setBackground(parent.getBackground()); - control.setForeground(parent.getForeground()); - - StructureListContentProvider contentAndLabelProvider = new StructureListContentProvider(); - viewer.setContentProvider(contentAndLabelProvider); - viewer.setLabelProvider( - new StructureListContentProvider.StructureListLabelProvider()); - - viewer.setInput(StructureListContentProvider.getDefaultInput()); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - handleStructureSelected(event.getSelection()); - } - }); - - setControl(control); - } - - private void handleStructureSelected(ISelection selection) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - viewer.setSelection(StructuredSelection.EMPTY); - } - }); - - if (selection == null || selection.isEmpty() - || !(selection instanceof IStructuredSelection)) - return; - - Object selectedElement = ((IStructuredSelection) selection) - .getFirstElement(); - if (selectedElement == null - || !(selectedElement instanceof StructureDescriptor)) - return; - - final StructureDescriptor structure = (StructureDescriptor) selectedElement; - final IStyle theme = chooseTheme(viewer.getControl().getShell(), - structure.getValue()); - if (theme == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateWorkbookCount"); //$NON-NLS-1$ - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateSheetCount"); //$NON-NLS-1$ - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("StructureTypeCount:" + structure.getValue()); //$NON-NLS-1$ - WorkbookInitializer initializer = WorkbookInitializer.getDefault() - .withStructureClass(structure.getValue()).withTheme(theme); - IEditorInput editorInput = MindMapUI.getEditorInputFactory() - .createEditorInputForWorkbookInitializer(initializer, null); - getContext().openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); - } - - private IStyle chooseTheme(Shell shell, String structureClass) { - ThemeChooserDialog dialog = new ThemeChooserDialog(shell, - structureClass); - int result = dialog.open(); - if (result == ThemeChooserDialog.CANCEL) - return null; - return dialog.getSelectedTheme(); - } - - public T getAdapter(Class adapter) { - if (viewer != null) { - if (adapter.isAssignableFrom(viewer.getClass())) - return adapter.cast(viewer); - T obj = viewer.getAdapter(adapter); - if (obj != null) - return obj; - } - return null; - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.xmind.cathy.internal.dashboard.StructureListContentProvider.StructureDescriptor; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.style.IStyle; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dashboard.pages.DashboardPage; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.mindmap.WorkbookInitializer; +import org.xmind.ui.resources.ColorUtils; + +@SuppressWarnings("restriction") +public class NewFromStructuresDashboardPage extends DashboardPage + implements IAdaptable { + + private static final int FRAME_WIDTH = 210; + private static final int FRAME_HEIGHT = 130; + + private GalleryViewer viewer; + + private ResourceManager resources; + + public void setFocus() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.getControl().setFocus(); + } + } + + public void createControl(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + + viewer = new GalleryViewer(); + + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + viewer.setEditDomain(editDomain); + + Properties properties = viewer.getProperties(); + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); + properties.set(GalleryViewer.SolidFrames, true); + properties.set(GalleryViewer.FlatFrames, true); + properties.set(GalleryViewer.ImageConstrained, true); + properties.set(GalleryViewer.ImageStretched, Boolean.TRUE); + properties.set(GalleryViewer.ContentPaneBorderWidth, 1); + properties.set(GalleryViewer.ContentPaneBorderColor, + (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ + + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_TOPLEFT, 30, 0, + new Insets(10, 65, 20, 65))); + + properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, + new SpaceCollaborativeEngine()); + + Control control = viewer.createControl(parent); + control.setBackground(parent.getBackground()); + control.setForeground(parent.getForeground()); + + StructureListContentProvider contentAndLabelProvider = new StructureListContentProvider(); + viewer.setContentProvider(contentAndLabelProvider); + viewer.setLabelProvider( + new StructureListContentProvider.StructureListLabelProvider()); + + viewer.setInput(StructureListContentProvider.getDefaultInput()); + + viewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + handleStructureSelected(event.getSelection()); + } + }); + + setControl(control); + } + + private void handleStructureSelected(ISelection selection) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + viewer.setSelection(StructuredSelection.EMPTY); + } + }); + + if (selection == null || selection.isEmpty() + || !(selection instanceof IStructuredSelection)) + return; + + Object selectedElement = ((IStructuredSelection) selection) + .getFirstElement(); + if (selectedElement == null + || !(selectedElement instanceof StructureDescriptor)) + return; + + final StructureDescriptor structure = (StructureDescriptor) selectedElement; + final IStyle theme = chooseTheme(viewer.getControl().getShell(), + structure.getValue()); + if (theme == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CREATE_WORKBOOK_COUNT); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CREATE_SHEET_COUNT); + MindMapUIPlugin.getDefault().getUsageDataCollector().increase( + UserDataConstants.STRUCTURE_TYPE_COUNT + structure.getValue()); + WorkbookInitializer initializer = WorkbookInitializer.getDefault() + .withStructureClass(structure.getValue()).withTheme(theme); + IEditorInput editorInput = MindMapUI.getEditorInputFactory() + .createEditorInputForWorkbookInitializer(initializer, null); + getContext().openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); + } + + private IStyle chooseTheme(Shell shell, String structureClass) { + ThemeChooserDialog dialog = new ThemeChooserDialog(shell, + structureClass); + int result = dialog.open(); + if (result == ThemeChooserDialog.CANCEL) + return null; + return dialog.getSelectedTheme(); + } + + public T getAdapter(Class adapter) { + if (viewer != null) { + if (adapter.isAssignableFrom(viewer.getClass())) + return adapter.cast(viewer); + T obj = viewer.getAdapter(adapter); + if (obj != null) + return obj; + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromTemplatesDashboardPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromTemplatesDashboardPage.java index ac30a7657..a27612680 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromTemplatesDashboardPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/NewFromTemplatesDashboardPage.java @@ -1,172 +1,177 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dashboard.pages.DashboardPage; -import org.xmind.ui.internal.dashboard.pages.IDashboardContext; -import org.xmind.ui.mindmap.IResourceManagerListener; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.MindMapUI; - -public class NewFromTemplatesDashboardPage extends DashboardPage - implements IResourceManagerListener, IAdaptable { - - private CategorizedTemplateViewer viewer; - - private boolean templateOpening; - - public void setFocus() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.getControl().setFocus(); - } - } - - @Override - public void dispose() { - MindMapUI.getResourceManager().removeResourceManagerListener(this); - super.dispose(); - } - - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NONE); - container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout layout = new GridLayout(); - layout.marginWidth = 0; - layout.marginLeft = 60; - layout.marginRight = 0; - layout.marginHeight = 7; - container.setLayout(layout); - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ShowTemplatesCount"); //$NON-NLS-1$ - viewer = new CategorizedTemplateViewer(container); - Control control = viewer.getControl(); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - if (!templateOpening) { - handleTemplateSelected(event.getSelection()); - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateWorkbookCount"); //$NON-NLS-1$ - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateSheetCount"); //$NON-NLS-1$ - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("UseTemplatesCount"); //$NON-NLS-1$ - } - } - }); - - MindMapUI.getResourceManager().addResourceManagerListener(this); - - registerContextMenu(control); - setControl(container); - } - - public void registerAvailableCommands() { - IDashboardContext context = getContext(); - - context.registerAvailableCommandId( - ICathyConstants.COMMAND_TEMPLATE_DUPLICATE); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_TEMPLATE_RENAME); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_TEMPLATE_DELETE); - } - - private void registerContextMenu(Control control) { - getContext().registerContextMenu(control, - ICathyConstants.POPUP_TEMPLATE); - - //add context menu for nested viewers' control. - Object input = viewer.getInput(); - if (input instanceof Object[]) { - Object[] groups = (Object[]) viewer.getInput(); - for (Object group : groups) { - GalleryViewer nestedViewer = viewer.getNestedViewer(group); - if (nestedViewer != null) { - nestedViewer.getControl().setMenu(control.getMenu()); - } - } - } - } - - public void addSelectionChangedListener( - ISelectionChangedListener listener) { - if (viewer != null) { - viewer.addSelectionChangedListener(listener); - } - } - - public void userTemplateAdded(ITemplate template) { - if (viewer != null) { - viewer.userTemplateAdded(template); - } - } - - public void userTemplateRemoved(ITemplate template) { - if (viewer != null) { - viewer.userTemplateRemoved(template); - } - } - - private void handleTemplateSelected(ISelection selection) { - templateOpening = true; - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - viewer.setSelection(StructuredSelection.EMPTY); - } - }); - - if (selection == null || selection.isEmpty() - || !(selection instanceof IStructuredSelection)) { - templateOpening = false; - return; - } - - Object selectedElement = ((IStructuredSelection) selection) - .getFirstElement(); - if (selectedElement == null || !(selectedElement instanceof ITemplate)) - return; - - ITemplate template = (ITemplate) selectedElement; - IEditorInput editorInput = MindMapUI.getEditorInputFactory() - .createEditorInput(template.createWorkbookRef()); - getContext().openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); - - templateOpening = false; - } - - public T getAdapter(Class adapter) { - if (viewer != null) { - if (adapter.isAssignableFrom(viewer.getClass())) - return adapter.cast(viewer); - T obj = viewer.getAdapter(adapter); - if (obj != null) - return obj; - } - return null; - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dashboard.pages.DashboardPage; +import org.xmind.ui.internal.dashboard.pages.IDashboardContext; +import org.xmind.ui.mindmap.IResourceManagerListener; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.MindMapUI; + +public class NewFromTemplatesDashboardPage extends DashboardPage + implements IResourceManagerListener, IAdaptable { + + private CategorizedTemplateViewer viewer; + + private boolean templateOpening; + + public void setFocus() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.getControl().setFocus(); + } + } + + @Override + public void dispose() { + MindMapUI.getResourceManager().removeResourceManagerListener(this); + super.dispose(); + } + + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginLeft = 60; + layout.marginRight = 0; + layout.marginHeight = 7; + container.setLayout(layout); + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SHOW_TEMPLATES_COUNT); + viewer = new CategorizedTemplateViewer(container); + Control control = viewer.getControl(); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + viewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + if (!templateOpening) { + handleTemplateSelected(event.getSelection()); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CREATE_WORKBOOK_COUNT); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.USE_TEMPLATES_COUNT); + } + } + }); + + MindMapUI.getResourceManager().addResourceManagerListener(this); + + registerContextMenu(control); + setControl(container); + } + + public void registerAvailableCommands() { + IDashboardContext context = getContext(); + + context.registerAvailableCommandId( + ICathyConstants.COMMAND_TEMPLATE_DUPLICATE); + context.registerAvailableCommandId( + ICathyConstants.COMMAND_TEMPLATE_RENAME); + context.registerAvailableCommandId( + ICathyConstants.COMMAND_TEMPLATE_DELETE); + } + + private void registerContextMenu(Control control) { + getContext().registerContextMenu(control, + ICathyConstants.POPUP_TEMPLATE); + + //add context menu for nested viewers' control. + Object input = viewer.getInput(); + if (input instanceof Object[]) { + Object[] groups = (Object[]) viewer.getInput(); + for (Object group : groups) { + GalleryViewer nestedViewer = viewer.getNestedViewer(group); + if (nestedViewer != null) { + nestedViewer.getControl().setMenu(control.getMenu()); + } + } + } + } + + public void addSelectionChangedListener( + ISelectionChangedListener listener) { + if (viewer != null) { + viewer.addSelectionChangedListener(listener); + } + } + + public void userTemplateAdded(ITemplate template) { + if (viewer != null) { + viewer.userTemplateAdded(template); + } + } + + public void userTemplateRemoved(ITemplate template) { + if (viewer != null) { + viewer.userTemplateRemoved(template); + } + } + + private void handleTemplateSelected(ISelection selection) { + templateOpening = true; + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + viewer.setSelection(StructuredSelection.EMPTY); + } + }); + + if (selection == null || selection.isEmpty() + || !(selection instanceof IStructuredSelection)) { + templateOpening = false; + return; + } + + Object selectedElement = ((IStructuredSelection) selection) + .getFirstElement(); + if (selectedElement == null || !(selectedElement instanceof ITemplate)) + return; + + ITemplate template = (ITemplate) selectedElement; + if (template != null && null != template.getName()) + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(String.format( + UserDataConstants.USE_S_TEMPLATE_COUNT, + template.getName().replaceAll(" ", "_"))); //$NON-NLS-1$ //$NON-NLS-2$ + + IEditorInput editorInput = MindMapUI.getEditorInputFactory() + .createEditorInput(template.createWorkbookRef()); + getContext().openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); + + templateOpening = false; + } + + public T getAdapter(Class adapter) { + if (viewer != null) { + if (adapter.isAssignableFrom(viewer.getClass())) + return adapter.cast(viewer); + T obj = viewer.getAdapter(adapter); + if (obj != null) + return obj; + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentContainerLayout.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentContainerLayout.java index a5682be5e..931d6c240 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentContainerLayout.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentContainerLayout.java @@ -1,106 +1,106 @@ -package org.xmind.cathy.internal.dashboard; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.AbstractHintLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; - -public class RecentContainerLayout extends AbstractHintLayout { - private Map constraints = new HashMap(); - - public RecentContainerLayout() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d. - * IFigure, java.lang.Object) - */ - @Override - public void setConstraint(IFigure child, Object constraint) { - constraints.put(child, constraint); - super.setConstraint(child, constraint); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.AbstractLayout#getConstraint(org.eclipse.draw2d. - * IFigure) - */ - @Override - public Object getConstraint(IFigure child) { - Object constraint = constraints.get(child); - return constraint == null ? super.getConstraint(child) : constraint; - } - - public void layout(IFigure container) { - Rectangle area = container.getClientArea(); - for (Object child : container.getChildren()) { - IFigure figure = (IFigure) child; - Dimension childSize = figure.getPreferredSize(-1, -1); - int childWidth = Math.min(area.width, childSize.width); - int childHeight = Math.min(area.height, childSize.height); - - int childX, childY; - Object constraint = getConstraint(figure); - if (constraint instanceof Integer) { - int bit = ((Integer) constraint).intValue(); - if ((bit & PositionConstants.LEFT) != 0) { - childX = area.x; - } else if ((bit & PositionConstants.RIGHT) != 0) { - childX = area.x + area.width - childWidth; - } else if ((bit & PositionConstants.CENTER) != 0) { - childX = area.x + (area.width - childWidth) / 2; - } else { - childX = area.x; - childWidth = area.width; - } - if ((bit & PositionConstants.TOP) != 0) { - childY = area.y; - } else if ((bit & PositionConstants.BOTTOM) != 0) { - childY = area.y + area.height - childHeight; - } else if ((bit & PositionConstants.MIDDLE) != 0) { - childY = area.y + (area.height - childHeight) / 2; - } else { - childY = area.y; - childHeight = area.height; - } - } else { - childX = area.x; - childY = area.y; - childWidth = area.width; - childHeight = area.height; - } - - figure.setBounds( - new Rectangle(childX, childY, childWidth, childHeight)); - } - } - - @Override - protected Dimension calculatePreferredSize(IFigure figure, int wHint, - int hHint) { - if (wHint > -1) - wHint = Math.max(0, wHint - figure.getInsets().getWidth()); - if (hHint > -1) - hHint = Math.max(0, hHint - figure.getInsets().getHeight()); - - Dimension d = new Dimension(); - List children = figure.getChildren(); - IFigure child; - for (int i = 0; i < children.size(); i++) { - child = (IFigure) children.get(i); - if (!isObservingVisibility() || child.isVisible()) - d.union(child.getPreferredSize(wHint, hHint)); - } - - d.expand(figure.getInsets().getWidth(), figure.getInsets().getHeight()); - d.union(getBorderPreferredSize(figure)); - return d; - } -} +package org.xmind.cathy.internal.dashboard; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.AbstractHintLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; + +public class RecentContainerLayout extends AbstractHintLayout { + private Map constraints = new HashMap(); + + public RecentContainerLayout() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d. + * IFigure, java.lang.Object) + */ + @Override + public void setConstraint(IFigure child, Object constraint) { + constraints.put(child, constraint); + super.setConstraint(child, constraint); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.AbstractLayout#getConstraint(org.eclipse.draw2d. + * IFigure) + */ + @Override + public Object getConstraint(IFigure child) { + Object constraint = constraints.get(child); + return constraint == null ? super.getConstraint(child) : constraint; + } + + public void layout(IFigure container) { + Rectangle area = container.getClientArea(); + for (Object child : container.getChildren()) { + IFigure figure = (IFigure) child; + Dimension childSize = figure.getPreferredSize(-1, -1); + int childWidth = Math.min(area.width, childSize.width); + int childHeight = Math.min(area.height, childSize.height); + + int childX, childY; + Object constraint = getConstraint(figure); + if (constraint instanceof Integer) { + int bit = ((Integer) constraint).intValue(); + if ((bit & PositionConstants.LEFT) != 0) { + childX = area.x; + } else if ((bit & PositionConstants.RIGHT) != 0) { + childX = area.x + area.width - childWidth; + } else if ((bit & PositionConstants.CENTER) != 0) { + childX = area.x + (area.width - childWidth) / 2; + } else { + childX = area.x; + childWidth = area.width; + } + if ((bit & PositionConstants.TOP) != 0) { + childY = area.y; + } else if ((bit & PositionConstants.BOTTOM) != 0) { + childY = area.y + area.height - childHeight; + } else if ((bit & PositionConstants.MIDDLE) != 0) { + childY = area.y + (area.height - childHeight) / 2; + } else { + childY = area.y; + childHeight = area.height; + } + } else { + childX = area.x; + childY = area.y; + childWidth = area.width; + childHeight = area.height; + } + + figure.setBounds( + new Rectangle(childX, childY, childWidth, childHeight)); + } + } + + @Override + protected Dimension calculatePreferredSize(IFigure figure, int wHint, + int hHint) { + if (wHint > -1) + wHint = Math.max(0, wHint - figure.getInsets().getWidth()); + if (hHint > -1) + hHint = Math.max(0, hHint - figure.getInsets().getHeight()); + + Dimension d = new Dimension(); + List children = figure.getChildren(); + IFigure child; + for (int i = 0; i < children.size(); i++) { + child = (IFigure) children.get(i); + if (!isObservingVisibility() || child.isVisible()) + d.union(child.getPreferredSize(wHint, hHint)); + } + + d.expand(figure.getInsets().getWidth(), figure.getInsets().getHeight()); + d.union(getBorderPreferredSize(figure)); + return d; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileBlankPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileBlankPage.java index 33f7e7547..bdc90cd49 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileBlankPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileBlankPage.java @@ -1,81 +1,81 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.views.Page; - -public class RecentFileBlankPage extends Page { - - private static final String COLOR_DESCRIPTION = "#9B9B9B"; //$NON-NLS-1$ - private LocalResourceManager resources; - - @Override - protected Control doCreateControl(Composite parent) { - final Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite); - - if (resources == null) - resources = new LocalResourceManager(JFaceResources.getResources(), - composite); - return createContent(composite); - } - - private Control createContent(Composite parent) { - Composite panel = new Composite(parent, SWT.NONE); - panel.setBackground(parent.getBackground()); - GridLayoutFactory.fillDefaults().spacing(0, 24) - .extendedMargins(0, 0, 0, 100).applyTo(panel); - GridDataFactory.fillDefaults().grab(true, true) - .align(SWT.CENTER, SWT.CENTER).applyTo(panel); - - Label imageLabel = new Label(panel, SWT.NONE); - imageLabel.setImage((Image) resources.get( - CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "dashboard/recent/blank_recent.png"))); //$NON-NLS-1$ - GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER) - .grab(true, false).applyTo(imageLabel); - Point imageSize = imageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT); - - Control textArea = createTextArea(panel); - GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL) - .grab(true, false).hint(imageSize.x + 140, SWT.DEFAULT) - .applyTo(textArea); - - return parent; - } - - private Control createTextArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - GridLayoutFactory.fillDefaults().spacing(0, 24).applyTo(composite); - - Label descriptionLabel = new Label(composite, SWT.CENTER | SWT.WRAP); - descriptionLabel.setForeground((Color) resources - .get(ColorUtils.toDescriptor(COLOR_DESCRIPTION))); - descriptionLabel.setFont( - (Font) resources.get(JFaceResources.getDefaultFontDescriptor() - .setStyle(SWT.NORMAL).setHeight(12))); - descriptionLabel - .setText(WorkbenchMessages.RecentFileBlankPage_description); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) - .grab(true, false).applyTo(descriptionLabel); - - return composite; - } -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.views.Page; + +public class RecentFileBlankPage extends Page { + + private static final String COLOR_DESCRIPTION = "#9B9B9B"; //$NON-NLS-1$ + private LocalResourceManager resources; + + @Override + protected Control doCreateControl(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite); + + if (resources == null) + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + return createContent(composite); + } + + private Control createContent(Composite parent) { + Composite panel = new Composite(parent, SWT.NONE); + panel.setBackground(parent.getBackground()); + GridLayoutFactory.fillDefaults().spacing(0, 24) + .extendedMargins(0, 0, 0, 100).applyTo(panel); + GridDataFactory.fillDefaults().grab(true, true) + .align(SWT.CENTER, SWT.CENTER).applyTo(panel); + + Label imageLabel = new Label(panel, SWT.NONE); + imageLabel.setImage((Image) resources.get( + CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "dashboard/recent/blank_recent.png"))); //$NON-NLS-1$ + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER) + .grab(true, false).applyTo(imageLabel); + Point imageSize = imageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + Control textArea = createTextArea(panel); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL) + .grab(true, false).hint(imageSize.x + 140, SWT.DEFAULT) + .applyTo(textArea); + + return parent; + } + + private Control createTextArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + GridLayoutFactory.fillDefaults().spacing(0, 24).applyTo(composite); + + Label descriptionLabel = new Label(composite, SWT.CENTER | SWT.WRAP); + descriptionLabel.setForeground((Color) resources + .get(ColorUtils.toDescriptor(COLOR_DESCRIPTION))); + descriptionLabel.setFont( + (Font) resources.get(JFaceResources.getDefaultFontDescriptor() + .setStyle(SWT.NORMAL).setHeight(12))); + descriptionLabel + .setText(WorkbenchMessages.RecentFileBlankPage_description); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) + .grab(true, false).applyTo(descriptionLabel); + + return composite; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridDashboardPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridDashboardPage.java index 0d89de052..5c92cec80 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridDashboardPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridDashboardPage.java @@ -1,117 +1,123 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.dashboard.pages.DashboardPage; -import org.xmind.ui.internal.dashboard.pages.IDashboardContext; -import org.xmind.ui.views.IPage; -import org.xmind.ui.views.PageStack; - -public class RecentFileGridDashboardPage extends DashboardPage - implements IAdaptable { - - private static final String COMMAND_OPEN_SEAWIND_FILE_ID = "org.xmind.ui.seawind.command.openSeawindFile"; //$NON-NLS-1$ - - private static final String COMMAND_OPEN_LOCAL_FILE_ID = "org.xmind.ui.mindmap.command.openLocalFile"; //$NON-NLS-1$ - - private GalleryViewer viewer; - - private PageStack stack; - - IPage recentBlankPage; - - IPage recentFileGridPage; - - public void createControl(Composite parent) { - - stack = new PageStack(); - stack.createControl(parent); - stack.getControl().setBackground(parent.getBackground()); - - final IEditorHistory editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - editorHistory.addEditorHistoryListener(new IEditorHistoryListener() { - - @Override - public void editorHistoryChanged() { - if (getControl() == null || getControl().isDisposed()) - return; - if (Display.getCurrent() == null) - return; - showPage(editorHistory); - } - }); - - //do chose which viewer will show; - showPage(editorHistory); - } - - private void showPage(final IEditorHistory editorHistory) { - Composite composite = stack.getStackComposite(); - - if (editorHistory.getAllInputURIs().length == 0) { - if (recentBlankPage == null) { - recentBlankPage = new RecentFileBlankPage(); - recentBlankPage.createControl(composite); - } - stack.showPage(recentBlankPage); - } else { - if (recentFileGridPage == null) { - recentFileGridPage = new RecentFileGridPage(); - recentFileGridPage.createControl(composite); - viewer = recentFileGridPage.getAdapter(GalleryViewer.class); - } - stack.showPage(recentFileGridPage); - } - setControl(stack.getControl()); - stack.setFocus(); - } - - @Override - public void setContext(IDashboardContext context) { - super.setContext(context); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_PIN); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_UNPIN); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_CLEAR); - context.registerAvailableCommandId( - IWorkbenchCommandConstants.EDIT_DELETE); - - //register command in DashboardContext - context.registerAvailableCommandId(COMMAND_OPEN_SEAWIND_FILE_ID); - context.registerAvailableCommandId(COMMAND_OPEN_LOCAL_FILE_ID); - } - - public void setFocus() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - getContext().registerContextMenu(viewer.getControl(), - ICathyConstants.POPUP_RECENTFILE); - } - if (stack != null && stack.getControl() != null - && !stack.getControl().isDisposed()) { - stack.setFocus(); - } - } - - public T getAdapter(Class adapter) { - if (viewer != null) { - if (adapter.isAssignableFrom(viewer.getClass())) - return adapter.cast(viewer); - T obj = viewer.getAdapter(adapter); - if (obj != null) - return obj; - } - return null; - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.dashboard.pages.DashboardPage; +import org.xmind.ui.internal.dashboard.pages.IDashboardContext; +import org.xmind.ui.views.IPage; +import org.xmind.ui.views.PageStack; + +public class RecentFileGridDashboardPage extends DashboardPage + implements IAdaptable { + + private GalleryViewer viewer; + + private PageStack stack; + + IPage recentBlankPage; + + IPage recentFileGridPage; + + private IEditorHistoryListener editorHistoryListener = new IEditorHistoryListener() { + + @Override + public void editorHistoryChanged() { + if (getControl() == null || getControl().isDisposed()) + return; + if (Display.getCurrent() == null) + return; + showPage(editorHistory); + } + }; + + private IEditorHistory editorHistory; + + public void createControl(Composite parent) { + + stack = new PageStack(); + stack.createControl(parent); + stack.getControl().setBackground(parent.getBackground()); + + editorHistory = PlatformUI.getWorkbench() + .getService(IEditorHistory.class); + editorHistory.addEditorHistoryListener(editorHistoryListener); + + //do chose which viewer will show; + showPage(editorHistory); + } + + @Override + public void dispose() { + if (editorHistory != null) { + editorHistory.removeEditorHistoryListener(editorHistoryListener); + editorHistory = null; + } + super.dispose(); + } + + private void showPage(final IEditorHistory editorHistory) { + Composite composite = stack.getStackComposite(); + + if (editorHistory.getAllInputURIs().length == 0) { + if (recentBlankPage == null) { + recentBlankPage = new RecentFileBlankPage(); + recentBlankPage.createControl(composite); + } + stack.showPage(recentBlankPage); + } else { + if (recentFileGridPage == null) { + recentFileGridPage = new RecentFileGridPage(); + recentFileGridPage.createControl(composite); + viewer = recentFileGridPage.getAdapter(GalleryViewer.class); + } + stack.showPage(recentFileGridPage); + } + setControl(stack.getControl()); + stack.setFocus(); + } + + @Override + public void setContext(IDashboardContext context) { + super.setContext(context); + context.registerAvailableCommandId( + ICathyConstants.COMMAND_RECENTFILE_PIN); + context.registerAvailableCommandId( + ICathyConstants.COMMAND_RECENTFILE_UNPIN); + context.registerAvailableCommandId( + ICathyConstants.COMMAND_RECENTFILE_CLEAR); + context.registerAvailableCommandId( + IWorkbenchCommandConstants.EDIT_DELETE); + + } + + public void setFocus() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + getContext().registerContextMenu(viewer.getControl(), + ICathyConstants.POPUP_RECENTFILE); + } + if (stack != null && stack.getControl() != null + && !stack.getControl().isDisposed()) { + stack.setFocus(); + } + } + + public T getAdapter(Class adapter) { + if (viewer != null) { + if (adapter.isAssignableFrom(viewer.getClass())) + return adapter.cast(viewer); + T obj = viewer.getAdapter(adapter); + if (obj != null) + return obj; + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridPage.java index a7ddbe5c1..0c0b4c723 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridPage.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridPage.java @@ -1,177 +1,159 @@ -package org.xmind.cathy.internal.dashboard; - -import java.net.URI; - -import org.eclipse.core.commands.Command; -import org.eclipse.core.commands.IParameter; -import org.eclipse.core.commands.Parameterization; -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.core.commands.common.NotDefinedException; -import org.eclipse.e4.core.commands.ECommandService; -import org.eclipse.e4.core.commands.EHandlerService; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.views.Page; - -public class RecentFileGridPage extends Page { - - private static final String COMMANDPARAMETER_OPEN_CLOUD_FILE_URI = "org.xmind.ui.seawind.commandparameter.openCloudFile.uri"; //$NON-NLS-1$ - - private static final String COMMAND_OPEN_SEAWIND_FILE_ID = "org.xmind.ui.seawind.command.openSeawindFile"; //$NON-NLS-1$ - - private static final String COMMAND_OPEN_LOCAL_FILE_ID = "org.xmind.ui.mindmap.command.openLocalFile"; //$NON-NLS-1$ - - private static final String COMMANDPARAMETER_OPEN_LOCAL_FILE_URI = "org.xmind.ui.mindmap.commandparameter.openLocalFile.uri"; //$NON-NLS-1$ - - private GalleryViewer viewer; - - private LocalResourceManager resources; - - @Override - protected Control doCreateControl(Composite parent) { - final Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite); - GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); - - if (null == resources) - resources = new LocalResourceManager(JFaceResources.getResources(), - composite); - Composite titleBar = new Composite(composite, SWT.NONE); - titleBar.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ececec"))); //$NON-NLS-1$ - titleBar.setForeground(composite.getForeground()); - GridLayoutFactory.fillDefaults().margins(10, 10).applyTo(titleBar); - GridData titleBarData = new GridData(SWT.FILL, SWT.FILL, true, false); - titleBarData.heightHint = 44; - titleBar.setLayoutData(titleBarData); - - Label titleLabel = new Label(titleBar, SWT.NONE); - titleLabel.setBackground(titleBar.getBackground()); - titleLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - - titleLabel.setFont((Font) resources.get( - JFaceResources.getHeaderFontDescriptor().increaseHeight(-1))); - - titleLabel.setText(WorkbenchMessages.DashboardRecentFiles_message); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) - .grab(true, true).applyTo(titleLabel); - - Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); - separator.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - Composite panel = new Composite(composite, SWT.NONE); - GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(panel); - GridDataFactory.fillDefaults().grab(true, true).applyTo(panel); - - createViewer(panel); - return composite; - } - - private void createViewer(Composite parent) { - viewer = new RecentFileViewer(parent); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - handleOpenRecentFile(event.getSelection()); - } - }); - } - - private void handleOpenRecentFile(ISelection selection) { - if (!(selection instanceof IStructuredSelection)) - return; - - Object element = ((IStructuredSelection) selection).getFirstElement(); - if (!(element instanceof URI)) - return; - - URI uri = (URI) element; - if (uri.getScheme().equalsIgnoreCase("seawind")) {//$NON-NLS-1$ - // TODO do execute command openEditor by seawind plugin - openCloudFile(uri); - } else if (uri.getScheme().equalsIgnoreCase("file")) { //$NON-NLS-1$ - //TODO do execute command openEditor by mindmap plugin - openLocalFile(uri); - } - } - - private void openLocalFile(final URI uri) { - executeCommand(COMMAND_OPEN_LOCAL_FILE_ID, - COMMANDPARAMETER_OPEN_LOCAL_FILE_URI, uri); - } - - private void openCloudFile(final URI uri) { - executeCommand(COMMAND_OPEN_SEAWIND_FILE_ID, - COMMANDPARAMETER_OPEN_CLOUD_FILE_URI, uri); - } - - private void executeCommand(String commandId, String parameter, URI uri) { - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window == null) - return; - - final EHandlerService hs = window.getService(EHandlerService.class); - final ECommandService cs = window.getService(ECommandService.class); - - if (hs == null || cs == null) - return; - - final Command command = cs.getCommand(commandId); - if (command == null || !command.isDefined()) - return; - - try { - IParameter param = command.getParameter(parameter); - if (param == null) - return; - - ParameterizedCommand pc = new ParameterizedCommand(command, - new Parameterization[] { - new Parameterization(param, uri.toString()) }); - - if (!hs.canExecute(pc)) - return; - hs.executeHandler(pc); - - } catch (NotDefinedException e) { - CathyPlugin.log(e, this.getClass().getName() - + "-->execute openLocalFileHandler or openCloudFileHandler"); //$NON-NLS-1$ - } - } - - @Override - public T getAdapter(Class adapter) { - if (viewer != null) { - if (adapter.isAssignableFrom(viewer.getClass())) - return adapter.cast(viewer); - T obj = viewer.getAdapter(adapter); - if (obj != null) - return obj; - } - return super.getAdapter(adapter); - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.net.URI; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.views.Page; + +public class RecentFileGridPage extends Page { + + private GalleryViewer viewer; + + private LocalResourceManager resources; + + @Override + protected Control doCreateControl(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + + if (null == resources) + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + Composite titleBar = new Composite(composite, SWT.NONE); + titleBar.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ececec"))); //$NON-NLS-1$ + titleBar.setForeground(composite.getForeground()); + GridLayoutFactory.fillDefaults().margins(10, 10).applyTo(titleBar); + GridData titleBarData = new GridData(SWT.FILL, SWT.FILL, true, false); + titleBarData.heightHint = 44; + titleBar.setLayoutData(titleBarData); + + Label titleLabel = new Label(titleBar, SWT.NONE); + titleLabel.setBackground(titleBar.getBackground()); + titleLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ + + titleLabel.setFont((Font) resources.get( + JFaceResources.getHeaderFontDescriptor().increaseHeight(-1))); + + titleLabel.setText(WorkbenchMessages.DashboardRecentFiles_message); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) + .grab(true, true).applyTo(titleLabel); + + Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + separator.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + Composite panel = new Composite(composite, SWT.NONE); + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(panel); + GridDataFactory.fillDefaults().grab(true, true).applyTo(panel); + + createViewer(panel); + return composite; + } + + private void createViewer(Composite parent) { + viewer = new RecentFileViewer(parent); + + viewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + handleOpenRecentFile(event.getSelection()); + } + }); + } + + private void handleOpenRecentFile(ISelection selection) { + if (!(selection instanceof IStructuredSelection)) + return; + + Object element = ((IStructuredSelection) selection).getFirstElement(); + if (!(element instanceof URI)) + return; + + URI uri = (URI) element; + openFile(uri); + } + + private void openFile(final URI uri) { + executeCommand(MindMapCommandConstants.OPEN_WORKBOOK, + MindMapCommandConstants.OPEN_WORKBOOK_PARAM_URI, uri); + } + + private void executeCommand(String commandId, String parameter, URI uri) { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) + return; + + final EHandlerService hs = window.getService(EHandlerService.class); + final ECommandService cs = window.getService(ECommandService.class); + + if (hs == null || cs == null) + return; + + final Command command = cs.getCommand(commandId); + if (command == null || !command.isDefined()) + return; + + try { + IParameter param = command.getParameter(parameter); + if (param == null) + return; + + ParameterizedCommand pc = new ParameterizedCommand(command, + new Parameterization[] { + new Parameterization(param, uri.toString()) }); + + if (!hs.canExecute(pc)) + return; + hs.executeHandler(pc); + + } catch (NotDefinedException e) { + CathyPlugin.log(e, this.getClass().getName() + + "-->execute openLocalFileHandler or openCloudFileHandler"); //$NON-NLS-1$ + } + } + + @Override + public T getAdapter(Class adapter) { + if (viewer != null) { + if (adapter.isAssignableFrom(viewer.getClass())) + return adapter.cast(viewer); + T obj = viewer.getAdapter(adapter); + if (obj != null) + return obj; + } + return super.getAdapter(adapter); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileViewer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileViewer.java index f5e810997..ace73bc65 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileViewer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileViewer.java @@ -1,200 +1,220 @@ -package org.xmind.cathy.internal.dashboard; - -import java.net.URI; -import java.util.List; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.cathy.internal.dashboard.RecentFilesGalleryPartFactory.RecentFilesFramePart; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; -import org.xmind.gef.util.Properties; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GalleryNavigablePolicy; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.resources.ColorUtils; - -public class RecentFileViewer extends GalleryViewer { - - private static final int FRAME_WIDTH = 215; - private static final int FRAME_HEIGHT = 130; - private static final String COLOR_CONTENT_BORDER = "#cccccc"; //$NON-NLS-1$ - - private IEditorHistory editorHistory; - - private LocalResourceManager resources; - private Control viewerControl; - - public RecentFileViewer(Composite parent) { - editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - initViewer(parent); - registerHelper(parent.getShell()); - } - - private void registerHelper(Shell shell) { - shell.setData(ICathyConstants.HELPER_RECENTFILE_PIN, new Runnable() { - public void run() { - final ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - final List list = ((IStructuredSelection) selection) - .toList(); - for (final Object element : list) { - if (element instanceof URI) { - final boolean isChecked = editorHistory - .isPinned((URI) element); - if (isChecked) { - unPinRecentFile((URI) element); - } else { - pinRecentFile((URI) element); - } - } - } - } - - } - }); - shell.setData(ICathyConstants.HELPER_RECENTFILE_DELETE, new Runnable() { - public void run() { - final ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - final List list = ((IStructuredSelection) selection) - .toList(); - for (final Object element : list) { - if (element instanceof URI) { - deleteRecentFile((URI) element); - } - } - } - } - }); - shell.setData(ICathyConstants.HELPER_RECENTFILE_CLEAR, new Runnable() { - public void run() { - clearRecentFile(); - } - }); - } - - @SuppressWarnings("restriction") - private void initViewer(final Composite parent) { - if (resources == null) - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); - editDomain.installEditPolicy(GalleryViewer.POLICY_NAVIGABLE, - new GalleryNavigablePolicy()); - setEditDomain(editDomain); - - Properties properties = getProperties(); - properties.set(GalleryViewer.Horizontal, Boolean.TRUE); - properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); - properties.set(GalleryViewer.SolidFrames, true); - properties.set(GalleryViewer.FlatFrames, true); - properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); - properties.set(GalleryViewer.ImageStretched, Boolean.TRUE); - properties.set(GalleryViewer.ContentPaneBorderWidth, 1); - properties.set(GalleryViewer.CustomContentPaneDecorator, true); - properties.set(GalleryViewer.ContentPaneBorderColor, - resources.get(ColorUtils.toDescriptor(COLOR_CONTENT_BORDER))); - - properties.set(GalleryViewer.FrameContentSize, - new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_TOPLEFT, 30, 0, - new Insets(10, 65, 20, 65))); - properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, - new SpaceCollaborativeEngine()); - - final RecentFilesContentProvider contentProvider = new RecentFilesContentProvider(); - final RecentFilesLabelProvider labelProvider = new RecentFilesLabelProvider( - parent); - contentProvider.addContentChangeListener(new Runnable() { - public void run() { - handleRecentFileListChanged(contentProvider, labelProvider, - true); - parent.layout(true); - } - }); - - viewerControl = createControl(parent); - viewerControl.setBackground(parent.getBackground()); - viewerControl.setForeground(parent.getForeground()); - viewerControl - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - setPartFactory(new RecentFilesGalleryPartFactory()); - setContentProvider(contentProvider); - setLabelProvider(labelProvider); - - IEditorHistory editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - editorHistory.addEditorHistoryListener(contentProvider); - setInput(editorHistory); - handleRecentFileListChanged(contentProvider, labelProvider, true); - } - - @Override - public Control getControl() { - if (viewerControl != null) - return viewerControl; - return super.getControl(); - } - - private void handleRecentFileListChanged( - RecentFilesContentProvider contentProvider, - RecentFilesLabelProvider labelProvider, boolean refresh) { - if (refresh) { - setInput(getInput()); - } - } - - private void clearRecentFile() { - editorHistory.clear(); - } - - private void deleteRecentFile(URI fileURI) { - editorHistory.remove(fileURI); - } - - private void pinRecentFile(URI fileURI) { - editorHistory.pin(fileURI); - updateRecentFilePart(fileURI); - } - - private void unPinRecentFile(URI fileURI) { - editorHistory.unPin(fileURI); - updateRecentFilePart(fileURI); - } - - private void updateRecentFilePart(URI pinURI) { - RecentFilesFramePart part = findRecentFilePart(pinURI); - if (part != null) - part.update(); - } - - private RecentFilesFramePart findRecentFilePart(URI pinURI) { - if (pinURI == null) - return null; - return (RecentFilesFramePart) getPartRegistry().getPartByModel(pinURI); - } -} +package org.xmind.cathy.internal.dashboard; + +import java.net.URI; +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.cathy.internal.dashboard.RecentFilesGalleryPartFactory.RecentFilesFramePart; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; +import org.xmind.gef.util.Properties; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GalleryNavigablePolicy; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.resources.ColorUtils; + +public class RecentFileViewer extends GalleryViewer { + + private static final int FRAME_WIDTH = 210; + private static final int FRAME_HEIGHT = 130; + private static final String COLOR_CONTENT_BORDER = "#cccccc"; //$NON-NLS-1$ + + private IEditorHistory editorHistory; + + private LocalResourceManager resources; + private Control viewerControl; + private RecentFilesContentProvider contentProvider; + + public RecentFileViewer(Composite parent) { + editorHistory = PlatformUI.getWorkbench() + .getService(IEditorHistory.class); + initViewer(parent); + registerHelper(parent.getShell()); + } + + private void registerHelper(Shell shell) { + shell.setData(ICathyConstants.HELPER_RECENTFILE_PIN, new Runnable() { + public void run() { + final ISelection selection = getSelection(); + if (selection instanceof IStructuredSelection) { + final List list = ((IStructuredSelection) selection) + .toList(); + for (final Object element : list) { + if (element instanceof URI) { + final boolean isChecked = editorHistory + .isPinned((URI) element); + if (isChecked) { + unPinRecentFile((URI) element); + } else { + pinRecentFile((URI) element); + } + } + } + } + + } + }); + shell.setData(ICathyConstants.HELPER_RECENTFILE_DELETE, new Runnable() { + public void run() { + final ISelection selection = getSelection(); + if (selection instanceof IStructuredSelection) { + final List list = ((IStructuredSelection) selection) + .toList(); + for (final Object element : list) { + if (element instanceof URI) { + deleteRecentFile((URI) element); + } + } + } + } + }); + shell.setData(ICathyConstants.HELPER_RECENTFILE_CLEAR, new Runnable() { + public void run() { + clearRecentFile(); + } + }); + } + + private void unregisterHelper(Shell shell) { + shell.setData(ICathyConstants.HELPER_RECENTFILE_CLEAR, null); + shell.setData(ICathyConstants.HELPER_RECENTFILE_DELETE, null); + shell.setData(ICathyConstants.HELPER_RECENTFILE_PIN, null); + } + + private void handleDispose() { + if (viewerControl != null && !viewerControl.isDisposed()) + unregisterHelper(viewerControl.getShell()); + if (editorHistory != null) + editorHistory.removeEditorHistoryListener(contentProvider); + } + + @SuppressWarnings("restriction") + private void initViewer(final Composite parent) { + if (resources == null) + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + editDomain.installEditPolicy(GalleryViewer.POLICY_NAVIGABLE, + new GalleryNavigablePolicy()); + setEditDomain(editDomain); + + Properties properties = getProperties(); + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); + properties.set(GalleryViewer.SolidFrames, true); + properties.set(GalleryViewer.FlatFrames, true); + properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); + properties.set(GalleryViewer.ImageStretched, Boolean.TRUE); + properties.set(GalleryViewer.ContentPaneBorderWidth, 1); + properties.set(GalleryViewer.CustomContentPaneDecorator, true); + properties.set(GalleryViewer.ContentPaneBorderColor, + resources.get(ColorUtils.toDescriptor(COLOR_CONTENT_BORDER))); + + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_TOPLEFT, 30, 0, + new Insets(10, 65, 20, 65))); + properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, + new SpaceCollaborativeEngine()); + + contentProvider = new RecentFilesContentProvider(); + final RecentFilesLabelProvider labelProvider = new RecentFilesLabelProvider( + parent); + contentProvider.addContentChangeListener(new Runnable() { + public void run() { + handleRecentFileListChanged(contentProvider, labelProvider, + true); + parent.layout(true); + } + }); + + viewerControl = createControl(parent); + viewerControl.setBackground(parent.getBackground()); + viewerControl.setForeground(parent.getForeground()); + viewerControl + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + viewerControl.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + + setPartFactory(new RecentFilesGalleryPartFactory()); + setContentProvider(contentProvider); + setLabelProvider(labelProvider); + + editorHistory.addEditorHistoryListener(contentProvider); + setInput(editorHistory); + handleRecentFileListChanged(contentProvider, labelProvider, true); + } + + @Override + public Control getControl() { + if (viewerControl != null) + return viewerControl; + return super.getControl(); + } + + private void handleRecentFileListChanged( + RecentFilesContentProvider contentProvider, + RecentFilesLabelProvider labelProvider, boolean refresh) { + if (refresh) { + setInput(getInput()); + } + } + + private void clearRecentFile() { + editorHistory.clear(); + } + + private void deleteRecentFile(URI fileURI) { + editorHistory.remove(fileURI); + } + + private void pinRecentFile(URI fileURI) { + editorHistory.pin(fileURI); + updateRecentFilePart(fileURI); + } + + private void unPinRecentFile(URI fileURI) { + editorHistory.unPin(fileURI); + updateRecentFilePart(fileURI); + } + + private void updateRecentFilePart(URI pinURI) { + RecentFilesFramePart part = findRecentFilePart(pinURI); + if (part != null) + part.update(); + } + + private RecentFilesFramePart findRecentFilePart(URI pinURI) { + if (pinURI == null) + return null; + return (RecentFilesFramePart) getPartRegistry().getPartByModel(pinURI); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java index ec9e6a664..4ba0bdb62 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java @@ -1,127 +1,127 @@ -package org.xmind.cathy.internal.dashboard; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.commands.common.EventManager; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; - -public class RecentFilesContentProvider extends EventManager - implements IStructuredContentProvider, IEditorHistoryListener, - IPropertyChangeListener { - - private static final int DEFAULT_ITEM_COUNT = 20; - - private IEditorHistory history = null; - - private IPreferenceStore preferenceStore = null; - - public void dispose() { - clearListeners(); - if (preferenceStore != null) { - preferenceStore.removePropertyChangeListener(this); - preferenceStore = null; - } - if (history != null) { - history.removeEditorHistoryListener(this); - history = null; - } - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput != history) { - if (history != null) { - history.removeEditorHistoryListener(this); - } - history = (newInput instanceof IEditorHistory) - ? (IEditorHistory) newInput : null; - if (history != null) { - history.addEditorHistoryListener(this); - } - - if (history != null) { - if (preferenceStore == null) { - preferenceStore = WorkbenchPlugin.getDefault() - .getPreferenceStore(); - preferenceStore.addPropertyChangeListener(this); - } - } else { - if (preferenceStore != null) { - preferenceStore.removePropertyChangeListener(this); - preferenceStore = null; - } - } - } - } - - public Object[] getElements(Object inputElement) { - if (inputElement != history) - return new Object[0]; - return getRecentInput(); - } - - public URI[] getRecentInput() { - if (history == null) - return new URI[0]; - int itemsToShow = getItemCount(); - if (itemsToShow <= 0) - return new URI[0]; - - URI[] uncheckedURIs = history.getAllInputURIs(); - List recentInputURIs = new ArrayList(); - int count = 0; - for (URI uri : uncheckedURIs) { - if (!recentInputURIs.contains(uri)) { - recentInputURIs.add(uri); - count++; - } else { - history.remove(uri); - } - if (count == itemsToShow) - break; - } - - return recentInputURIs.toArray(new URI[recentInputURIs.size()]); - } - - private int getItemCount() { - if (preferenceStore == null) - return DEFAULT_ITEM_COUNT; - return preferenceStore.getInt(IPreferenceConstants.RECENT_FILES); - } - - private void fireContentChanged() { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - ((Runnable) listeners[i]).run(); - } - } - - public void editorHistoryChanged() { - fireContentChanged(); - } - - public void propertyChange(PropertyChangeEvent event) { - if (IPreferenceConstants.RECENT_FILES.equals(event.getProperty())) { - fireContentChanged(); - } - } - - public void addContentChangeListener(Runnable listener) { - addListenerObject(listener); - } - - public void removeContentChangeListener(Runnable listener) { - removeListenerObject(listener); - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.common.EventManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; + +public class RecentFilesContentProvider extends EventManager + implements IStructuredContentProvider, IEditorHistoryListener, + IPropertyChangeListener { + + private static final int DEFAULT_ITEM_COUNT = 20; + + private IEditorHistory history = null; + + private IPreferenceStore preferenceStore = null; + + public void dispose() { + clearListeners(); + if (preferenceStore != null) { + preferenceStore.removePropertyChangeListener(this); + preferenceStore = null; + } + if (history != null) { + history.removeEditorHistoryListener(this); + history = null; + } + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput != history) { + if (history != null) { + history.removeEditorHistoryListener(this); + } + history = (newInput instanceof IEditorHistory) + ? (IEditorHistory) newInput : null; + if (history != null) { + history.addEditorHistoryListener(this); + } + + if (history != null) { + if (preferenceStore == null) { + preferenceStore = WorkbenchPlugin.getDefault() + .getPreferenceStore(); + preferenceStore.addPropertyChangeListener(this); + } + } else { + if (preferenceStore != null) { + preferenceStore.removePropertyChangeListener(this); + preferenceStore = null; + } + } + } + } + + public Object[] getElements(Object inputElement) { + if (inputElement != history) + return new Object[0]; + return getRecentInput(); + } + + public URI[] getRecentInput() { + if (history == null) + return new URI[0]; + int itemsToShow = getItemCount(); + if (itemsToShow <= 0) + return new URI[0]; + + URI[] uncheckedURIs = history.getAllInputURIs(); + List recentInputURIs = new ArrayList(); + int count = 0; + for (URI uri : uncheckedURIs) { + if (!recentInputURIs.contains(uri)) { + recentInputURIs.add(uri); + count++; + } else { + history.remove(uri); + } + if (count == itemsToShow) + break; + } + + return recentInputURIs.toArray(new URI[recentInputURIs.size()]); + } + + private int getItemCount() { + if (preferenceStore == null) + return DEFAULT_ITEM_COUNT; + return preferenceStore.getInt(IPreferenceConstants.RECENT_FILES); + } + + private void fireContentChanged() { + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + ((Runnable) listeners[i]).run(); + } + } + + public void editorHistoryChanged() { + fireContentChanged(); + } + + public void propertyChange(PropertyChangeEvent event) { + if (IPreferenceConstants.RECENT_FILES.equals(event.getProperty())) { + fireContentChanged(); + } + } + + public void addContentChangeListener(Runnable listener) { + addListenerObject(listener); + } + + public void removeContentChangeListener(Runnable listener) { + removeListenerObject(listener); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesGalleryPartFactory.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesGalleryPartFactory.java index 69bbf7e50..45a060c0d 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesGalleryPartFactory.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesGalleryPartFactory.java @@ -1,140 +1,140 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.FrameBorderLayout; -import org.xmind.ui.gallery.FrameDecorator; -import org.xmind.ui.gallery.FrameFigure; -import org.xmind.ui.gallery.FramePart; -import org.xmind.ui.gallery.GalleryPartFactory; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; - -public class RecentFilesGalleryPartFactory extends GalleryPartFactory { - public static class RecentFilesFramePart extends FramePart { - RecentFilesFrameFigure figure; - - public RecentFilesFramePart(Object model) { - super(model); - setDecorator(RecentFilesFrameDecorator.DEFAULT); - } - - @Override - protected IFigure createFigure() { - figure = new RecentFilesFrameFigure(); - Properties properties = getSite().getViewer().getProperties(); - boolean useAdvancedRenderer = properties.getBoolean( - IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); - figure.setTitleRenderStyle(useAdvancedRenderer - ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); - - return figure; - } - - @Override - protected void updateChildren() { - super.updateChildren(); - boolean isSelected = figure.isSelected(); - if (isSelected) { - figure.setForegroundColor(ColorConstants.white); - figure.subTitle.setForegroundColor(ColorConstants.white); - } - } - } - - private static class RecentFilesFrameDecorator extends FrameDecorator { - - public static final RecentFilesFrameDecorator DEFAULT = new RecentFilesFrameDecorator(); - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - - IFigure f = part.getFigure(); - Object model = part.getModel(); - - IViewer viewer = part.getSite().getViewer(); - IBaseLabelProvider labelProvider = viewer - .getAdapter(IBaseLabelProvider.class); - - if (f instanceof RecentFilesFrameFigure - && labelProvider instanceof RecentFilesLabelProvider) { - decorateSubTitle(((RecentFilesFrameFigure) f).getSubTitle(), - model, (RecentFilesLabelProvider) labelProvider); - } - } - - private void decorateSubTitle(ITextFigure subTitle, Object model, - RecentFilesLabelProvider labelProvider) { - if (model == null) - return; - String text = labelProvider.getSubtitle(model); - if (text == null) - return; - - subTitle.setText(text); - subTitle.setForegroundColor((Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#8f8f8f"))); //$NON-NLS-1$ - Font countFont = subTitle.getFont(); - if (countFont != null) { - FontData[] fontData = countFont.getFontData(); - FontData[] newFontData = FontUtils.newHeight(fontData, - Util.isMac() ? 9 : 7); - subTitle.setFont((Font) JFaceResources.getResources() - .get(FontDescriptor.createFrom(newFontData))); - } - } - } - - private static class RecentFilesFrameFigure extends FrameFigure { - - private RotatableWrapLabel subTitle; - - Color subTitleColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#8f8f8f")); //$NON-NLS-1$ - - public RecentFilesFrameFigure() { - super(); - - subTitle = new RotatableWrapLabel(RotatableWrapLabel.NORMAL); - subTitle.setTextAlignment(PositionConstants.CENTER); - subTitle.setEnabled(false); - subTitle.setAbbreviated(true); - subTitle.setForegroundColor(subTitleColor); - getTitleContainer().add(subTitle, FrameBorderLayout.BOTTOM); - - } - - public ITextFigure getSubTitle() { - return subTitle; - } - - @Override - public void setSelected(boolean selected) { - super.setSelected(selected); - subTitle.setForegroundColor( - selected ? ColorConstants.white : subTitleColor); - } - } - - @Override - protected IPart createFramePart(IPart parent, Object model) { - return new RecentFilesFramePart(model); - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.FrameBorderLayout; +import org.xmind.ui.gallery.FrameDecorator; +import org.xmind.ui.gallery.FrameFigure; +import org.xmind.ui.gallery.FramePart; +import org.xmind.ui.gallery.GalleryPartFactory; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; + +public class RecentFilesGalleryPartFactory extends GalleryPartFactory { + public static class RecentFilesFramePart extends FramePart { + RecentFilesFrameFigure figure; + + public RecentFilesFramePart(Object model) { + super(model); + setDecorator(RecentFilesFrameDecorator.DEFAULT); + } + + @Override + protected IFigure createFigure() { + figure = new RecentFilesFrameFigure(); + Properties properties = getSite().getViewer().getProperties(); + boolean useAdvancedRenderer = properties.getBoolean( + IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); + figure.setTitleRenderStyle(useAdvancedRenderer + ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); + + return figure; + } + + @Override + protected void updateChildren() { + super.updateChildren(); + boolean isSelected = figure.isSelected(); + if (isSelected) { + figure.setForegroundColor(ColorConstants.white); + figure.subTitle.setForegroundColor(ColorConstants.white); + } + } + } + + private static class RecentFilesFrameDecorator extends FrameDecorator { + + public static final RecentFilesFrameDecorator DEFAULT = new RecentFilesFrameDecorator(); + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + + IFigure f = part.getFigure(); + Object model = part.getModel(); + + IViewer viewer = part.getSite().getViewer(); + IBaseLabelProvider labelProvider = viewer + .getAdapter(IBaseLabelProvider.class); + + if (f instanceof RecentFilesFrameFigure + && labelProvider instanceof RecentFilesLabelProvider) { + decorateSubTitle(((RecentFilesFrameFigure) f).getSubTitle(), + model, (RecentFilesLabelProvider) labelProvider); + } + } + + private void decorateSubTitle(ITextFigure subTitle, Object model, + RecentFilesLabelProvider labelProvider) { + if (model == null) + return; + String text = labelProvider.getSubtitle(model); + if (text == null) + return; + + subTitle.setText(text); + subTitle.setForegroundColor((Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#8f8f8f"))); //$NON-NLS-1$ + Font countFont = subTitle.getFont(); + if (countFont != null) { + FontData[] fontData = countFont.getFontData(); + FontData[] newFontData = FontUtils.newHeight(fontData, + Util.isMac() ? 9 : 7); + subTitle.setFont((Font) JFaceResources.getResources() + .get(FontDescriptor.createFrom(newFontData))); + } + } + } + + private static class RecentFilesFrameFigure extends FrameFigure { + + private RotatableWrapLabel subTitle; + + Color subTitleColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#8f8f8f")); //$NON-NLS-1$ + + public RecentFilesFrameFigure() { + super(); + + subTitle = new RotatableWrapLabel(RotatableWrapLabel.NORMAL); + subTitle.setTextAlignment(PositionConstants.CENTER); + subTitle.setEnabled(false); + subTitle.setAbbreviated(true); + subTitle.setForegroundColor(subTitleColor); + getTitleContainer().add(subTitle, FrameBorderLayout.BOTTOM); + + } + + public ITextFigure getSubTitle() { + return subTitle; + } + + @Override + public void setSelected(boolean selected) { + super.setSelected(selected); + subTitle.setForegroundColor( + selected ? ColorConstants.white : subTitleColor); + } + } + + @Override + protected IPart createFramePart(IPart parent, Object model) { + return new RecentFilesFramePart(model); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesLabelProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesLabelProvider.java index d3925b3fc..79eaf13cc 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesLabelProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesLabelProvider.java @@ -1,241 +1,241 @@ -package org.xmind.cathy.internal.dashboard; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.sql.Date; -import java.text.DateFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.gef.draw2d.SizeableImageFigure; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistoryItem; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.gallery.IDecorationContext; -import org.xmind.ui.gallery.ILabelDecorator; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -public class RecentFilesLabelProvider extends LabelProvider - implements ILabelDecorator { - - Image pinImage; - - protected static class RecentFrameContentLayout - extends RecentContainerLayout { - - private IDecorationContext context; - - public RecentFrameContentLayout(IDecorationContext context) { - this.context = context; - } - - @Override - protected Dimension calculatePreferredSize(IFigure figure, int wHint, - int hHint) { - if (context != null) { - Insets insets = figure.getInsets(); - Dimension contentSize = (Dimension) context - .getProperty(GalleryViewer.FrameContentSize, null); - if (contentSize != null) - return new Dimension(contentSize.width + insets.getWidth(), - contentSize.height + insets.getHeight()); - } - return super.calculatePreferredSize(figure, wHint, hHint); - } - } - - protected static final String COLOR_NONEXISTING_WORKBOOK_COVER = "#DDDDDD"; //$NON-NLS-1$ - protected static final String COLOR_NONEXISTING_WORKBOOK_TEXT = "#CCCCCC"; //$NON-NLS-1$ - - private LocalResourceManager resources; - private IEditorHistory editorHistory; - private Map images; - - public RecentFilesLabelProvider(Composite parent) { - this.images = new HashMap(); - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - } - - public void clear() { - Object[] imageArray = images.values().toArray(); - images.clear(); - for (Object image : imageArray) { - ((Image) image).dispose(); - } - } - - @Override - public void dispose() { - resources.dispose(); - clear(); - super.dispose(); - } - - @Override - public String getText(Object element) { - if (!(element instanceof URI)) - return super.getText(element); - URI uri = (URI) element; - IEditorHistoryItem item = editorHistory.getItem(uri); - if (item != null) { - String name = item.getName(); - Assert.isTrue(name != null); - - StringBuffer buf = new StringBuffer(); - if (name.length() > 20) - name = name.substring(0, 20) + "..."; //$NON-NLS-1$ - buf.append(name); - if (uri.getScheme().equalsIgnoreCase("seawind")) { //$NON-NLS-1$ - buf.append(" "); //$NON-NLS-1$ - buf.append( - WorkbenchMessages.RecentFilesLabelProvider_Cloud_text); - } - return buf.toString(); - } - return uri.toString(); - } - - @Override - public Image getImage(Object element) { - if (element instanceof URI) { - URI uri = (URI) element; - Image image = images.get(uri); - if (image != null && !image.isDisposed()) - return image; - - image = getImageByThumb(uri); - if (image != null && !image.isDisposed()) { - images.put(uri, image); - } - return image; - } - return resources.createImage( - MindMapUI.getImages().get(IMindMapImages.THUMBNAIL_LOST, true)); - } - - private Image getImageByThumb(URI uri) { - InputStream thumbnailData = null; - try { - thumbnailData = editorHistory.loadThumbnailData(uri); - if (thumbnailData != null) { - return new Image(resources.getDevice(), thumbnailData); - } - } catch (IOException e) { - CathyPlugin.log(e, String.format( - "Failed to load preview image for recent page uri == %s", //$NON-NLS-1$ - uri)); - } catch (SWTException e) { - CathyPlugin.log(e, String.format( - "Failed to load preview image for recent page uri == %s", //$NON-NLS-1$ - uri)); - } finally { - try { - if (thumbnailData != null) - thumbnailData.close(); - } catch (IOException e) { - } - } - return resources.createImage( - MindMapUI.getImages().get(IMindMapImages.THUMBNAIL_LOST, true)); - } - - public IFigure decorateFigure(IFigure figure, Object element, - IDecorationContext context) { - if (!(element instanceof URI)) - return figure; - - return decorateFrameFigure(figure, (URI) element, context); - } - - protected IFigure decorateFrameFigure(IFigure contentPane, URI uri, - IDecorationContext context) { - SizeableImageFigure thumbnailFigure; - SizeableImageFigure pinIcon; - - List figures = contentPane.getChildren(); - boolean needInitFigureContent = figures.isEmpty(); - if (needInitFigureContent) { - contentPane.setLayoutManager(new RecentFrameContentLayout(context)); - - thumbnailFigure = new SizeableImageFigure(getImage(uri)); - pinIcon = new SizeableImageFigure(getPinImage(uri)); - - contentPane.add(thumbnailFigure); - contentPane.add(pinIcon, Integer - .valueOf(PositionConstants.LEFT | PositionConstants.TOP)); - - if (context != null) { - boolean imageConstrained = Boolean.TRUE.equals(context - .getProperty(GalleryViewer.ImageConstrained, false)); - boolean imageStretched = Boolean.TRUE.equals(context - .getProperty(GalleryViewer.ImageStretched, false)); - thumbnailFigure.setConstrained(imageConstrained); - thumbnailFigure.setStretched(imageStretched); - } - } else { - thumbnailFigure = (SizeableImageFigure) figures.get(0); - pinIcon = (SizeableImageFigure) figures.get(1); - } - - thumbnailFigure.setImage(getImage(uri)); - pinIcon.setImage(getPinImage(uri)); - - return contentPane; - } - - private Image getPinImage(URI uri) { - boolean isPin = editorHistory.isPinned(uri); - return isPin ? getPinImage() : null; - } - - private Image getPinImage() { - if (pinImage == null) { - ImageDescriptor desc = MindMapUI.getImages().get(IMindMapImages.PIN, - true); - if (desc != null) { - try { - pinImage = resources.createImage(desc); - } catch (Throwable e) { - //e.printStackTrace(); - } - } - } - return pinImage; - } - - public String getSubtitle(Object element) { - if (element instanceof URI) { - IEditorHistoryItem item = editorHistory.getItem((URI) element); - long t = item.getOpenedTime(); - Date date = new Date(t); - return DateFormat - .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT) - .format(date); - } - Date newDate = new Date(System.currentTimeMillis()); - return DateFormat - .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT) - .format(newDate); - } -} +package org.xmind.cathy.internal.dashboard; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.sql.Date; +import java.text.DateFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.gef.draw2d.SizeableImageFigure; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistoryItem; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.gallery.IDecorationContext; +import org.xmind.ui.gallery.ILabelDecorator; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +public class RecentFilesLabelProvider extends LabelProvider + implements ILabelDecorator { + + Image pinImage; + + protected static class RecentFrameContentLayout + extends RecentContainerLayout { + + private IDecorationContext context; + + public RecentFrameContentLayout(IDecorationContext context) { + this.context = context; + } + + @Override + protected Dimension calculatePreferredSize(IFigure figure, int wHint, + int hHint) { + if (context != null) { + Insets insets = figure.getInsets(); + Dimension contentSize = (Dimension) context + .getProperty(GalleryViewer.FrameContentSize, null); + if (contentSize != null) + return new Dimension(contentSize.width + insets.getWidth(), + contentSize.height + insets.getHeight()); + } + return super.calculatePreferredSize(figure, wHint, hHint); + } + } + + protected static final String COLOR_NONEXISTING_WORKBOOK_COVER = "#DDDDDD"; //$NON-NLS-1$ + protected static final String COLOR_NONEXISTING_WORKBOOK_TEXT = "#CCCCCC"; //$NON-NLS-1$ + + private LocalResourceManager resources; + private IEditorHistory editorHistory; + private Map images; + + public RecentFilesLabelProvider(Composite parent) { + this.images = new HashMap(); + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + editorHistory = PlatformUI.getWorkbench() + .getService(IEditorHistory.class); + } + + public void clear() { + Object[] imageArray = images.values().toArray(); + images.clear(); + for (Object image : imageArray) { + ((Image) image).dispose(); + } + } + + @Override + public void dispose() { + resources.dispose(); + clear(); + super.dispose(); + } + + @Override + public String getText(Object element) { + if (!(element instanceof URI)) + return super.getText(element); + URI uri = (URI) element; + IEditorHistoryItem item = editorHistory.getItem(uri); + if (item != null) { + String name = item.getName(); + Assert.isTrue(name != null); + + StringBuffer buf = new StringBuffer(); + if (name.length() > 20) + name = name.substring(0, 20) + "..."; //$NON-NLS-1$ + buf.append(name); + if (uri.getScheme().equalsIgnoreCase("seawind")) { //$NON-NLS-1$ + buf.append(" "); //$NON-NLS-1$ + buf.append( + WorkbenchMessages.RecentFilesLabelProvider_Cloud_text); + } + return buf.toString(); + } + return uri.toString(); + } + + @Override + public Image getImage(Object element) { + if (element instanceof URI) { + URI uri = (URI) element; + Image image = images.get(uri); + if (image != null && !image.isDisposed()) + return image; + + image = getImageByThumb(uri); + if (image != null && !image.isDisposed()) { + images.put(uri, image); + } + return image; + } + return resources.createImage( + MindMapUI.getImages().get(IMindMapImages.THUMBNAIL_LOST, true)); + } + + private Image getImageByThumb(URI uri) { + InputStream thumbnailData = null; + try { + thumbnailData = editorHistory.loadThumbnailData(uri); + if (thumbnailData != null) { + return new Image(resources.getDevice(), thumbnailData); + } + } catch (IOException e) { + CathyPlugin.log(e, String.format( + "Failed to load preview image for recent page uri == %s", //$NON-NLS-1$ + uri)); + } catch (SWTException e) { + CathyPlugin.log(e, String.format( + "Failed to load preview image for recent page uri == %s", //$NON-NLS-1$ + uri)); + } finally { + try { + if (thumbnailData != null) + thumbnailData.close(); + } catch (IOException e) { + } + } + return resources.createImage( + MindMapUI.getImages().get(IMindMapImages.THUMBNAIL_LOST, true)); + } + + public IFigure decorateFigure(IFigure figure, Object element, + IDecorationContext context) { + if (!(element instanceof URI)) + return figure; + + return decorateFrameFigure(figure, (URI) element, context); + } + + protected IFigure decorateFrameFigure(IFigure contentPane, URI uri, + IDecorationContext context) { + SizeableImageFigure thumbnailFigure; + SizeableImageFigure pinIcon; + + List figures = contentPane.getChildren(); + boolean needInitFigureContent = figures.isEmpty(); + if (needInitFigureContent) { + contentPane.setLayoutManager(new RecentFrameContentLayout(context)); + + thumbnailFigure = new SizeableImageFigure(getImage(uri)); + pinIcon = new SizeableImageFigure(getPinImage(uri)); + + contentPane.add(thumbnailFigure); + contentPane.add(pinIcon, Integer + .valueOf(PositionConstants.LEFT | PositionConstants.TOP)); + + if (context != null) { + boolean imageConstrained = Boolean.TRUE.equals(context + .getProperty(GalleryViewer.ImageConstrained, false)); + boolean imageStretched = Boolean.TRUE.equals(context + .getProperty(GalleryViewer.ImageStretched, false)); + thumbnailFigure.setConstrained(imageConstrained); + thumbnailFigure.setStretched(imageStretched); + } + } else { + thumbnailFigure = (SizeableImageFigure) figures.get(0); + pinIcon = (SizeableImageFigure) figures.get(1); + } + + thumbnailFigure.setImage(getImage(uri)); + pinIcon.setImage(getPinImage(uri)); + + return contentPane; + } + + private Image getPinImage(URI uri) { + boolean isPin = editorHistory.isPinned(uri); + return isPin ? getPinImage() : null; + } + + private Image getPinImage() { + if (pinImage == null) { + ImageDescriptor desc = MindMapUI.getImages().get(IMindMapImages.PIN, + true); + if (desc != null) { + try { + pinImage = resources.createImage(desc); + } catch (Throwable e) { + //e.printStackTrace(); + } + } + } + return pinImage; + } + + public String getSubtitle(Object element) { + if (element instanceof URI) { + IEditorHistoryItem item = editorHistory.getItem((URI) element); + long t = item.getOpenedTime(); + Date date = new Date(t); + return DateFormat + .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT) + .format(date); + } + Date newDate = new Date(System.currentTimeMillis()); + return DateFormat + .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT) + .format(newDate); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/StructureListContentProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/StructureListContentProvider.java index 72e1bfd0b..fdd2c3f50 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/StructureListContentProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/StructureListContentProvider.java @@ -1,310 +1,310 @@ -package org.xmind.cathy.internal.dashboard; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilderFactory; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.graphics.Image; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.viewers.ImageCachedLabelProvider; - -public class StructureListContentProvider - implements IStructuredContentProvider { - - public static final String CONTENT_URI = "platform:/plugin/org.xmind.cathy/dashboard/new/structures.xml"; //$NON-NLS-1$ - public static final String NLS_PATH_BASE = "dashboard/new/structures"; //$NON-NLS-1$ - - private static final String TAG_STRUCTURE_LIST = "structure-list"; //$NON-NLS-1$ - private static final String TAG_STRUCTURE = "structure"; //$NON-NLS-1$ - private static final String ATTR_ID = "id"; //$NON-NLS-1$ - private static final String ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String ATTR_ICON = "icon"; //$NON-NLS-1$ - private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ - private static final String ATTR_ICON_HEIGHT = "icon-height"; //$NON-NLS-1$ - private static final String ATTR_ICON_WIDTH = "icon-width"; //$NON-NLS-1$ - - public static final class ContentSource { - - public final String contentURI; - - public final String nlsPathBase; - - public ContentSource(String contentURI, String nlsPathBase) { - this.contentURI = contentURI; - this.nlsPathBase = nlsPathBase; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof ContentSource)) - return false; - ContentSource that = (ContentSource) obj; - return (this.contentURI == that.contentURI - || (this.contentURI != null - && this.contentURI.equals(that.contentURI))) - && (this.nlsPathBase == that.nlsPathBase - || (this.nlsPathBase != null && this.nlsPathBase - .equals(that.nlsPathBase))); - } - - @Override - public int hashCode() { - int x = 37; - if (contentURI != null) { - x = x ^ contentURI.hashCode(); - } - if (nlsPathBase != null) { - x = x ^ nlsPathBase.hashCode(); - } - return x; - } - - } - - static class StructureDescriptor { - private String id; - private String value; - private String name; - private ImageDescriptor icon; - - public StructureDescriptor(String id, String value, String name, - ImageDescriptor icon) { - super(); - Assert.isNotNull(id); - Assert.isNotNull(value); - this.id = id; - this.value = value; - this.name = name; - this.icon = icon; - } - - public int hashCode() { - return id.hashCode(); - } - - public String getId() { - return id; - } - - public String getName() { - return this.name; - } - - public String getValue() { - return this.value; - } - - public ImageDescriptor getIcon() { - return this.icon; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof StructureDescriptor)) - return false; - StructureDescriptor that = (StructureDescriptor) obj; - return this.id.equals(that.id); - } - - } - - static class StructureListLabelProvider extends ImageCachedLabelProvider { - - @Override - public String getText(Object element) { - if (element instanceof StructureDescriptor) - return ((StructureDescriptor) element).getName(); - return super.getText(element); - } - - @Override - protected Image createImage(Object element) { - if (element instanceof StructureDescriptor) { - ImageDescriptor icon = ((StructureDescriptor) element) - .getIcon(); - if (icon != null) - return icon.createImage(); - } - return null; - } - } - - private ContentSource source = null; - - private List structureDescriptors = new ArrayList(); - - private Dimension iconSizeHints = new Dimension(); - - public void dispose() { - structureDescriptors.clear(); - source = null; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - ContentSource newSource = toContentSource(newInput); - if (newSource == source - || (newSource != null && newSource.equals(source))) - return; - - source = newSource; - structureDescriptors.clear(); - iconSizeHints = new Dimension(); - - if (source != null) { - readTemplatesFromSource(source); - } - - if (viewer instanceof GalleryViewer) { - ((GalleryViewer) viewer).getProperties() - .set(GalleryViewer.FrameContentSize, iconSizeHints); - } - } - - private ContentSource toContentSource(Object input) { - ContentSource newSource; - if (input instanceof ContentSource) { - newSource = (ContentSource) input; - } else if (input instanceof String) { - newSource = new ContentSource((String) input, null); - } else { - newSource = null; - } - return newSource; - } - - public Object[] getElements(Object inputElement) { - ContentSource inputSource = toContentSource(inputElement); - if (inputSource == source - || (inputSource != null && inputSource.equals(source))) { - return structureDescriptors.toArray(); - } - return new Object[0]; - } - - private void readTemplatesFromSource(ContentSource source) { - Properties nlsProperties; - if (source.nlsPathBase != null) { - nlsProperties = CathyPlugin.getDefault() - .loadNLSProperties(source.nlsPathBase); - } else { - nlsProperties = new Properties(); - } - - if (source.contentURI != null) { - try { - URL contentURL = new URL(source.contentURI); - URL locatedURL = FileLocator.find(contentURL); - if (locatedURL != null) - contentURL = locatedURL; - InputStream contentStream = contentURL.openStream(); - try { - Document doc = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(contentStream); - readElement(doc.getDocumentElement(), nlsProperties); - } finally { - contentStream.close(); - } - } catch (Exception e) { - CathyPlugin.log(e, - "Failed to load content for structure list from: " //$NON-NLS-1$ - + source.contentURI); - } - } - - } - - private void readElement(Element element, Properties nlsProperties) { - String tagName = element.getTagName(); - if (TAG_STRUCTURE.equals(tagName)) { - readTemplate(element, nlsProperties); - } else if (TAG_STRUCTURE_LIST.equals(tagName)) { - readGlobalAttributes(element); - } - - readChildren(element.getChildNodes(), nlsProperties); - } - - private void readChildren(NodeList children, Properties nlsProperties) { - int length = children.getLength(); - for (int i = 0; i < length; i++) { - Node node = children.item(i); - if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { - readElement((Element) node, nlsProperties); - } - } - } - - private void readTemplate(Element element, Properties nlsProperties) { - String id = element.getAttribute(ATTR_ID); - String name = element.getAttribute(ATTR_NAME); - String iconURI = element.getAttribute(ATTR_ICON); - String structureClass = element.getAttribute(ATTR_VALUE); - - if (id == null || "".equals(id)) //$NON-NLS-1$ - throw new IllegalArgumentException("Missing 'id' attribute"); //$NON-NLS-1$ - - if (name == null) { - name = ""; //$NON-NLS-1$ - } else if (name.startsWith("%")) { //$NON-NLS-1$ - String nativeName = nlsProperties.getProperty(name.substring(1)); - if (nativeName != null) { - name = nativeName; - } - } - - ImageDescriptor icon; - if (iconURI == null) { - icon = null; - } else { - try { - icon = ImageDescriptor.createFromURL(new URL(iconURI)); - } catch (MalformedURLException e) { - CathyPlugin.log(e, "Invalid icon URI: '" + iconURI + "'"); //$NON-NLS-1$ //$NON-NLS-2$ - icon = null; - } - } - - StructureDescriptor structureDescriptor = new StructureDescriptor(id, - structureClass, name, icon); - structureDescriptors.add(structureDescriptor); - } - - private void readGlobalAttributes(Element element) { - String iconWidth = element.getAttribute(ATTR_ICON_WIDTH); - String iconHeight = element.getAttribute(ATTR_ICON_HEIGHT); - - if (iconWidth != null && iconHeight != null) { - try { - int width = Integer.parseInt(iconWidth, 10); - int height = Integer.parseInt(iconHeight, 10); - iconSizeHints.width = width; - iconSizeHints.height = height; - } catch (NumberFormatException e) { - } - } - } - - public static final ContentSource getDefaultInput() { - return new ContentSource(CONTENT_URI, NLS_PATH_BASE); - } - -} +package org.xmind.cathy.internal.dashboard; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.viewers.ImageCachedLabelProvider; + +public class StructureListContentProvider + implements IStructuredContentProvider { + + public static final String CONTENT_URI = "platform:/plugin/org.xmind.cathy/dashboard/new/structures.xml"; //$NON-NLS-1$ + public static final String NLS_PATH_BASE = "dashboard/new/structures"; //$NON-NLS-1$ + + private static final String TAG_STRUCTURE_LIST = "structure-list"; //$NON-NLS-1$ + private static final String TAG_STRUCTURE = "structure"; //$NON-NLS-1$ + private static final String ATTR_ID = "id"; //$NON-NLS-1$ + private static final String ATTR_NAME = "name"; //$NON-NLS-1$ + private static final String ATTR_ICON = "icon"; //$NON-NLS-1$ + private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ + private static final String ATTR_ICON_HEIGHT = "icon-height"; //$NON-NLS-1$ + private static final String ATTR_ICON_WIDTH = "icon-width"; //$NON-NLS-1$ + + public static final class ContentSource { + + public final String contentURI; + + public final String nlsPathBase; + + public ContentSource(String contentURI, String nlsPathBase) { + this.contentURI = contentURI; + this.nlsPathBase = nlsPathBase; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof ContentSource)) + return false; + ContentSource that = (ContentSource) obj; + return (this.contentURI == that.contentURI + || (this.contentURI != null + && this.contentURI.equals(that.contentURI))) + && (this.nlsPathBase == that.nlsPathBase + || (this.nlsPathBase != null && this.nlsPathBase + .equals(that.nlsPathBase))); + } + + @Override + public int hashCode() { + int x = 37; + if (contentURI != null) { + x = x ^ contentURI.hashCode(); + } + if (nlsPathBase != null) { + x = x ^ nlsPathBase.hashCode(); + } + return x; + } + + } + + static class StructureDescriptor { + private String id; + private String value; + private String name; + private ImageDescriptor icon; + + public StructureDescriptor(String id, String value, String name, + ImageDescriptor icon) { + super(); + Assert.isNotNull(id); + Assert.isNotNull(value); + this.id = id; + this.value = value; + this.name = name; + this.icon = icon; + } + + public int hashCode() { + return id.hashCode(); + } + + public String getId() { + return id; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + public ImageDescriptor getIcon() { + return this.icon; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof StructureDescriptor)) + return false; + StructureDescriptor that = (StructureDescriptor) obj; + return this.id.equals(that.id); + } + + } + + static class StructureListLabelProvider extends ImageCachedLabelProvider { + + @Override + public String getText(Object element) { + if (element instanceof StructureDescriptor) + return ((StructureDescriptor) element).getName(); + return super.getText(element); + } + + @Override + protected Image createImage(Object element) { + if (element instanceof StructureDescriptor) { + ImageDescriptor icon = ((StructureDescriptor) element) + .getIcon(); + if (icon != null) + return icon.createImage(); + } + return null; + } + } + + private ContentSource source = null; + + private List structureDescriptors = new ArrayList(); + + private Dimension iconSizeHints = new Dimension(); + + public void dispose() { + structureDescriptors.clear(); + source = null; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + ContentSource newSource = toContentSource(newInput); + if (newSource == source + || (newSource != null && newSource.equals(source))) + return; + + source = newSource; + structureDescriptors.clear(); + iconSizeHints = new Dimension(); + + if (source != null) { + readTemplatesFromSource(source); + } + + if (viewer instanceof GalleryViewer) { + ((GalleryViewer) viewer).getProperties() + .set(GalleryViewer.FrameContentSize, iconSizeHints); + } + } + + private ContentSource toContentSource(Object input) { + ContentSource newSource; + if (input instanceof ContentSource) { + newSource = (ContentSource) input; + } else if (input instanceof String) { + newSource = new ContentSource((String) input, null); + } else { + newSource = null; + } + return newSource; + } + + public Object[] getElements(Object inputElement) { + ContentSource inputSource = toContentSource(inputElement); + if (inputSource == source + || (inputSource != null && inputSource.equals(source))) { + return structureDescriptors.toArray(); + } + return new Object[0]; + } + + private void readTemplatesFromSource(ContentSource source) { + Properties nlsProperties; + if (source.nlsPathBase != null) { + nlsProperties = CathyPlugin.getDefault() + .loadNLSProperties(source.nlsPathBase); + } else { + nlsProperties = new Properties(); + } + + if (source.contentURI != null) { + try { + URL contentURL = new URL(source.contentURI); + URL locatedURL = FileLocator.find(contentURL); + if (locatedURL != null) + contentURL = locatedURL; + InputStream contentStream = contentURL.openStream(); + try { + Document doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(contentStream); + readElement(doc.getDocumentElement(), nlsProperties); + } finally { + contentStream.close(); + } + } catch (Exception e) { + CathyPlugin.log(e, + "Failed to load content for structure list from: " //$NON-NLS-1$ + + source.contentURI); + } + } + + } + + private void readElement(Element element, Properties nlsProperties) { + String tagName = element.getTagName(); + if (TAG_STRUCTURE.equals(tagName)) { + readTemplate(element, nlsProperties); + } else if (TAG_STRUCTURE_LIST.equals(tagName)) { + readGlobalAttributes(element); + } + + readChildren(element.getChildNodes(), nlsProperties); + } + + private void readChildren(NodeList children, Properties nlsProperties) { + int length = children.getLength(); + for (int i = 0; i < length; i++) { + Node node = children.item(i); + if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { + readElement((Element) node, nlsProperties); + } + } + } + + private void readTemplate(Element element, Properties nlsProperties) { + String id = element.getAttribute(ATTR_ID); + String name = element.getAttribute(ATTR_NAME); + String iconURI = element.getAttribute(ATTR_ICON); + String structureClass = element.getAttribute(ATTR_VALUE); + + if (id == null || "".equals(id)) //$NON-NLS-1$ + throw new IllegalArgumentException("Missing 'id' attribute"); //$NON-NLS-1$ + + if (name == null) { + name = ""; //$NON-NLS-1$ + } else if (name.startsWith("%")) { //$NON-NLS-1$ + String nativeName = nlsProperties.getProperty(name.substring(1)); + if (nativeName != null) { + name = nativeName; + } + } + + ImageDescriptor icon; + if (iconURI == null) { + icon = null; + } else { + try { + icon = ImageDescriptor.createFromURL(new URL(iconURI)); + } catch (MalformedURLException e) { + CathyPlugin.log(e, "Invalid icon URI: '" + iconURI + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + icon = null; + } + } + + StructureDescriptor structureDescriptor = new StructureDescriptor(id, + structureClass, name, icon); + structureDescriptors.add(structureDescriptor); + } + + private void readGlobalAttributes(Element element) { + String iconWidth = element.getAttribute(ATTR_ICON_WIDTH); + String iconHeight = element.getAttribute(ATTR_ICON_HEIGHT); + + if (iconWidth != null && iconHeight != null) { + try { + int width = Integer.parseInt(iconWidth, 10); + int height = Integer.parseInt(iconHeight, 10); + iconSizeHints.width = width; + iconSizeHints.height = height; + } catch (NumberFormatException e) { + } + } + } + + public static final ContentSource getDefaultInput() { + return new ContentSource(CONTENT_URI, NLS_PATH_BASE); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/TemplatePropertyTester.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/TemplatePropertyTester.java index 11d461945..7623c078a 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/TemplatePropertyTester.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/TemplatePropertyTester.java @@ -1,32 +1,32 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.MindMapUI; - -public class TemplatePropertyTester extends PropertyTester { - - private static final String PROP_SYSTEM = "system"; //$NON-NLS-1$ - - private static final String PROP_USER = "user"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof ITemplate, - "Receiver is not an ITemplate object: " + receiver); //$NON-NLS-1$ - - ITemplate template = (ITemplate) receiver; - - if (PROP_SYSTEM.equals(property)) { - return MindMapUI.getResourceManager().isSystemTemplate(template); - } else if (PROP_USER.equals(property)) { - return MindMapUI.getResourceManager().isUserTemplate(template); - } - - Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ - - return false; - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.MindMapUI; + +public class TemplatePropertyTester extends PropertyTester { + + private static final String PROP_SYSTEM = "system"; //$NON-NLS-1$ + + private static final String PROP_USER = "user"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof ITemplate, + "Receiver is not an ITemplate object: " + receiver); //$NON-NLS-1$ + + ITemplate template = (ITemplate) receiver; + + if (PROP_SYSTEM.equals(property)) { + return MindMapUI.getResourceManager().isSystemTemplate(template); + } else if (PROP_USER.equals(property)) { + return MindMapUI.getResourceManager().isUserTemplate(template); + } + + Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ + + return false; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/ThemeChooserDialog.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/ThemeChooserDialog.java index 5262ce44c..64be6fcd6 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/ThemeChooserDialog.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/ThemeChooserDialog.java @@ -1,167 +1,167 @@ -package org.xmind.cathy.internal.dashboard; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.core.style.IStyle; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.views.CategorizedThemeViewer; -import org.xmind.ui.internal.views.ThemeLabelProvider; -import org.xmind.ui.mindmap.IResourceManager; -import org.xmind.ui.mindmap.MindMapUI; - -public class ThemeChooserDialog extends Dialog { - - private IStyle selectedTheme = null; - - private String structureClass; - - protected ThemeChooserDialog(Shell parentShell) { - super(parentShell); - setShellStyle(getShellStyle() | SWT.SHEET); - } - - protected ThemeChooserDialog(Shell parentShell, String structureClass) { - this(parentShell); - this.structureClass = structureClass; - } - - @Override - protected boolean isResizable() { - return true; - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(WorkbenchMessages.DashboardThemeChoose_message); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - - composite.setLayout(new FillLayout()); - GridData parentData = (GridData) composite.getLayoutData(); - parentData.widthHint = 940; - parentData.heightHint = 500; - doCreateViewer(composite); - return composite; - } - - private void doCreateViewer(Composite parent) { - - CategorizedThemeViewer viewer = doCreatePartControlViewer(parent); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - selectedTheme = (IStyle) ((IStructuredSelection) event - .getSelection()).getFirstElement(); - setButtonEnabled(IDialogConstants.OK_ID, - !event.getSelection().isEmpty()); - } - }); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - ISelection selection = event.getSelection(); - selectedTheme = selection.isEmpty() ? null - : (IStyle) ((IStructuredSelection) selection) - .getFirstElement(); - setReturnCode(OK); - close(); - } - }); - IResourceManager rm = MindMapUI.getResourceManager(); - IStyle defaultTheme = rm.getDefaultTheme(); - viewer.setSelection(new StructuredSelection(defaultTheme)); - - } - - private CategorizedThemeViewer doCreatePartControlViewer(Composite parent) { - Composite container = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - container.setLayout(layout); - - CategorizedThemeViewer viewer = new CategorizedThemeViewer(container) { - - @Override - protected void postInit() { - // cancel change theme listener - } - - @Override - protected void initGalleryViewer(GalleryViewer galleryViewerer) { - galleryViewerer.setLabelProvider( - new ThemeLabelProvider(structureClass)); - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, - new GallerySelectTool()); - galleryViewerer.setEditDomain(editDomain); - - Properties properties = galleryViewerer.getProperties(); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.HideTitle, false); - properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); - properties.set(GalleryViewer.SolidFrames, true); - properties.set(GalleryViewer.FlatFrames, true); - properties.set(GalleryViewer.ImageConstrained, true); - properties.set(GalleryViewer.CustomContentPaneDecorator, true); - } - }; - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - return viewer; - } - - @Override - protected Button createButton(Composite parent, int id, String label, - boolean defaultButton) { - if (id == IDialogConstants.OK_ID) - label = WorkbenchMessages.DashboardThemeCreate_label; - return super.createButton(parent, id, label, defaultButton); - } - - @Override - protected void cancelPressed() { - super.cancelPressed(); - selectedTheme = null; - } - - public IStyle getSelectedTheme() { - return selectedTheme; - } - - private void setButtonEnabled(int id, boolean enabled) { - Button button = getButton(id); - if (button == null || button.isDisposed()) - return; - button.setEnabled(enabled); - } - -} +package org.xmind.cathy.internal.dashboard; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.style.IStyle; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.views.CategorizedThemeViewer; +import org.xmind.ui.internal.views.ThemeLabelProvider; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.MindMapUI; + +public class ThemeChooserDialog extends Dialog { + + private IStyle selectedTheme = null; + + private String structureClass; + + protected ThemeChooserDialog(Shell parentShell) { + super(parentShell); + setShellStyle(getShellStyle() | SWT.SHEET); + } + + protected ThemeChooserDialog(Shell parentShell, String structureClass) { + this(parentShell); + this.structureClass = structureClass; + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(WorkbenchMessages.DashboardThemeChoose_message); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + composite.setLayout(new FillLayout()); + GridData parentData = (GridData) composite.getLayoutData(); + parentData.widthHint = 940; + parentData.heightHint = 500; + doCreateViewer(composite); + return composite; + } + + private void doCreateViewer(Composite parent) { + + CategorizedThemeViewer viewer = doCreatePartControlViewer(parent); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + selectedTheme = (IStyle) ((IStructuredSelection) event + .getSelection()).getFirstElement(); + setButtonEnabled(IDialogConstants.OK_ID, + !event.getSelection().isEmpty()); + } + }); + + viewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + ISelection selection = event.getSelection(); + selectedTheme = selection.isEmpty() ? null + : (IStyle) ((IStructuredSelection) selection) + .getFirstElement(); + setReturnCode(OK); + close(); + } + }); + IResourceManager rm = MindMapUI.getResourceManager(); + IStyle defaultTheme = rm.getDefaultTheme(); + viewer.setSelection(new StructuredSelection(defaultTheme)); + + } + + private CategorizedThemeViewer doCreatePartControlViewer(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + container.setLayout(layout); + + CategorizedThemeViewer viewer = new CategorizedThemeViewer(container) { + + @Override + protected void postInit() { + // cancel change theme listener + } + + @Override + protected void initGalleryViewer(GalleryViewer galleryViewerer) { + galleryViewerer.setLabelProvider( + new ThemeLabelProvider(structureClass)); + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, + new GallerySelectTool()); + galleryViewerer.setEditDomain(editDomain); + + Properties properties = galleryViewerer.getProperties(); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.HideTitle, false); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); + properties.set(GalleryViewer.SolidFrames, true); + properties.set(GalleryViewer.FlatFrames, true); + properties.set(GalleryViewer.ImageConstrained, true); + properties.set(GalleryViewer.CustomContentPaneDecorator, true); + } + }; + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + return viewer; + } + + @Override + protected Button createButton(Composite parent, int id, String label, + boolean defaultButton) { + if (id == IDialogConstants.OK_ID) + label = WorkbenchMessages.DashboardThemeCreate_label; + return super.createButton(parent, id, label, defaultButton); + } + + @Override + protected void cancelPressed() { + super.cancelPressed(); + selectedTheme = null; + } + + public IStyle getSelectedTheme() { + return selectedTheme; + } + + private void setButtonEnabled(int id, boolean enabled) { + Button button = getButton(id); + if (button == null || button.isDisposed()) + return; + button.setEnabled(enabled); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ClearRecentFileHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ClearRecentFileHandler.java index eecc5839f..dde6544f0 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ClearRecentFileHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ClearRecentFileHandler.java @@ -1,24 +1,24 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class ClearRecentFileHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - Shell shell = HandlerUtil.getActiveShell(event); - if (shell != null) { - Object data = shell - .getData(ICathyConstants.HELPER_RECENTFILE_CLEAR); - if (data instanceof Runnable) { - ((Runnable) data).run(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class ClearRecentFileHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + if (shell != null) { + Object data = shell + .getData(ICathyConstants.HELPER_RECENTFILE_CLEAR); + if (data instanceof Runnable) { + ((Runnable) data).run(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteRecentFileHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteRecentFileHandler.java index db2971313..e4e38fb6f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteRecentFileHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteRecentFileHandler.java @@ -1,24 +1,24 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class DeleteRecentFileHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - Shell shell = HandlerUtil.getActiveShell(event); - if (shell != null) { - Object data = shell - .getData(ICathyConstants.HELPER_RECENTFILE_DELETE); - if (data instanceof Runnable) { - ((Runnable) data).run(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class DeleteRecentFileHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + if (shell != null) { + Object data = shell + .getData(ICathyConstants.HELPER_RECENTFILE_DELETE); + if (data instanceof Runnable) { + ((Runnable) data).run(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteTemplateHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteTemplateHandler.java index f156c64b5..57b11750f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteTemplateHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteTemplateHandler.java @@ -1,41 +1,41 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.MindMapUI; - -public class DeleteTemplateHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (obj instanceof ITemplate) { - ITemplate template = (ITemplate) obj; - Shell activeShell = HandlerUtil.getActiveShell(event); - - if (!MessageDialog.openConfirm(activeShell, - WorkbenchMessages.ConfirmDeleteTemplateDialog_title, - NLS.bind( - WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, - template.getName()))) { - return null; - } - MindMapUI.getResourceManager().removeUserTemplate(template); - } - } - - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.MindMapUI; + +public class DeleteTemplateHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof ITemplate) { + ITemplate template = (ITemplate) obj; + Shell activeShell = HandlerUtil.getActiveShell(event); + + if (!MessageDialog.openConfirm(activeShell, + WorkbenchMessages.ConfirmDeleteTemplateDialog_title, + NLS.bind( + WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, + template.getName()))) { + return null; + } + MindMapUI.getResourceManager().removeUserTemplate(template); + } + } + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DuplicateTemplateHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DuplicateTemplateHandler.java index db879371b..722ffefa5 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DuplicateTemplateHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DuplicateTemplateHandler.java @@ -1,30 +1,30 @@ -package org.xmind.cathy.internal.handlers; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.ui.internal.utils.ResourceUtils; -import org.xmind.ui.mindmap.ITemplate; - -public class DuplicateTemplateHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - List templates = new ArrayList(); - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (obj instanceof ITemplate) { - templates.add((ITemplate) obj); - } - } - ResourceUtils.duplicateTemplates(templates); - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.ITemplate; + +public class DuplicateTemplateHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + List templates = new ArrayList(); + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof ITemplate) { + templates.add((ITemplate) obj); + } + } + ResourceUtils.duplicateTemplates(templates); + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/HideDashboardHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/HideDashboardHandler.java index a2668f681..68153da98 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/HideDashboardHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/HideDashboardHandler.java @@ -1,24 +1,24 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; - -public class HideDashboardHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); - if (wbWindow != null) { - MWindow window = wbWindow.getService(MWindow.class); - if (window != null) { - new org.xmind.ui.internal.e4handlers.HideDashboardHandler() - .execute(window); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +public class HideDashboardHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); + if (wbWindow != null) { + MWindow window = wbWindow.getService(MWindow.class); + if (window != null) { + new org.xmind.ui.internal.e4handlers.HideDashboardHandler() + .execute(window); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/NewWizardHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/NewWizardHandler.java index 71dc521f0..4c00d0287 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/NewWizardHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/NewWizardHandler.java @@ -1,27 +1,27 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class NewWizardHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); - if (wbWindow != null) { - MWindow window = wbWindow.getService(MWindow.class); - if (window != null) { - org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler - .showDashboardPage(window, - ICathyConstants.DASHBOARD_PAGE_NEW); - } - } - - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class NewWizardHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); + if (wbWindow != null) { + MWindow window = wbWindow.getService(MWindow.class); + if (window != null) { + org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler + .showDashboardPage(window, + ICathyConstants.DASHBOARD_PAGE_NEW); + } + } + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/PinRecentFileHanlder.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/PinRecentFileHanlder.java index 8e0299585..0ca5390e7 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/PinRecentFileHanlder.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/PinRecentFileHanlder.java @@ -1,23 +1,23 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class PinRecentFileHanlder extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - Shell shell = HandlerUtil.getActiveShell(event); - if (shell != null) { - Object data = shell.getData(ICathyConstants.HELPER_RECENTFILE_PIN); - if (data instanceof Runnable) { - ((Runnable) data).run(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class PinRecentFileHanlder extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + if (shell != null) { + Object data = shell.getData(ICathyConstants.HELPER_RECENTFILE_PIN); + if (data instanceof Runnable) { + ((Runnable) data).run(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/RenameTemplateHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/RenameTemplateHandler.java index ae13f7001..9aed96ba9 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/RenameTemplateHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/RenameTemplateHandler.java @@ -1,23 +1,23 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class RenameTemplateHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - Shell shell = HandlerUtil.getActiveShell(event); - if (shell != null) { - Object data = shell.getData(ICathyConstants.HELPER_TEMPLATE_RENAME); - if (data instanceof Runnable) { - ((Runnable) data).run(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class RenameTemplateHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + if (shell != null) { + Object data = shell.getData(ICathyConstants.HELPER_TEMPLATE_RENAME); + if (data instanceof Runnable) { + ((Runnable) data).run(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowAllPreferencesHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowAllPreferencesHandler.java index d45d910cb..bd47e7705 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowAllPreferencesHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowAllPreferencesHandler.java @@ -1,32 +1,32 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.ui.util.PrefUtils; - -public class ShowAllPreferencesHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - final String preferencePageId = event - .getParameter(IWorkbenchCommandConstants.WINDOW_PREFERENCES_PARM_PAGEID); - final IWorkbenchWindow activeWorkbenchWindow = HandlerUtil - .getActiveWorkbenchWindow(event); - - final Shell shell; - if (activeWorkbenchWindow == null) { - shell = null; - } else { - shell = activeWorkbenchWindow.getShell(); - } - - PrefUtils.openPrefDialog(shell, preferencePageId); - - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.util.PrefUtils; + +public class ShowAllPreferencesHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + final String preferencePageId = event + .getParameter(IWorkbenchCommandConstants.WINDOW_PREFERENCES_PARM_PAGEID); + final IWorkbenchWindow activeWorkbenchWindow = HandlerUtil + .getActiveWorkbenchWindow(event); + + final Shell shell; + if (activeWorkbenchWindow == null) { + shell = null; + } else { + shell = activeWorkbenchWindow.getShell(); + } + + PrefUtils.openPrefDialog(shell, preferencePageId); + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowCloudPageHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowCloudPageHandler.java index 0e1c742e1..3803d4632 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowCloudPageHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowCloudPageHandler.java @@ -1,30 +1,30 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class ShowCloudPageHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); - if (wbWindow != null) { - MWindow window = wbWindow.getService(MWindow.class); - if (window != null) { - String pageId = "org.xmind.ui.part.dashboard.cloud"; //$NON-NLS-1$ - org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler - .showDashboardPage(window, pageId); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class ShowCloudPageHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); + if (wbWindow != null) { + MWindow window = wbWindow.getService(MWindow.class); + if (window != null) { + String pageId = "org.xmind.ui.part.dashboard.cloud"; //$NON-NLS-1$ + org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler + .showDashboardPage(window, pageId); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowDashboardPageHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowDashboardPageHandler.java index 0c01853b2..fa785c203 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowDashboardPageHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ShowDashboardPageHandler.java @@ -1,28 +1,28 @@ - -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class ShowDashboardPageHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); - if (wbWindow != null) { - MWindow window = wbWindow.getService(MWindow.class); - if (window != null) { - String pageId = event.getParameter( - ICathyConstants.PARAMETER_DASHBOARD_PAGE_ID); - org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler - .showDashboardPage(window, pageId); - } - } - return null; - } - + +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class ShowDashboardPageHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow wbWindow = HandlerUtil.getActiveWorkbenchWindow(event); + if (wbWindow != null) { + MWindow window = wbWindow.getService(MWindow.class); + if (window != null) { + String pageId = event.getParameter( + ICathyConstants.PARAMETER_DASHBOARD_PAGE_ID); + org.xmind.ui.internal.e4handlers.ShowDashboardPageHandler + .showDashboardPage(window, pageId); + } + } + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ToggleDashboardHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ToggleDashboardHandler.java index 2a10921b1..fa876be02 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ToggleDashboardHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/ToggleDashboardHandler.java @@ -1,20 +1,20 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; - -public class ToggleDashboardHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow wbw = HandlerUtil - .getActiveWorkbenchWindowChecked(event); - new org.xmind.ui.internal.e4handlers.ToggleDashboardHandler() - .execute(wbw.getService(MWindow.class)); - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ToggleDashboardHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow wbw = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + new org.xmind.ui.internal.e4handlers.ToggleDashboardHandler() + .execute(wbw.getService(MWindow.class)); + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/UnpinRecentFileHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/UnpinRecentFileHandler.java index f0e42f45d..0378d8cf0 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/UnpinRecentFileHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/UnpinRecentFileHandler.java @@ -1,23 +1,23 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.ICathyConstants; - -public class UnpinRecentFileHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - Shell shell = HandlerUtil.getActiveShell(event); - if (shell != null) { - Object data = shell.getData(ICathyConstants.HELPER_RECENTFILE_PIN); - if (data instanceof Runnable) { - ((Runnable) data).run(); - } - } - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.ICathyConstants; + +public class UnpinRecentFileHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + if (shell != null) { + Object data = shell.getData(ICathyConstants.HELPER_RECENTFILE_PIN); + if (data instanceof Runnable) { + ((Runnable) data).run(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/WelcomeToXMindHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/WelcomeToXMindHandler.java index 29ca952c4..d6cae492f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/WelcomeToXMindHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/WelcomeToXMindHandler.java @@ -1,45 +1,46 @@ -package org.xmind.cathy.internal.handlers; - -import java.net.URI; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; - -public class WelcomeToXMindHandler extends AbstractHandler { - - private static final String URL_WELCOME_FILE = "platform:/plugin/org.xmind.cathy/$nl$/resource/Welcome%20to%20XMind.xmind"; //$NON-NLS-1$ - - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); - if (window == null) - return null; - - final IWorkbenchPage activePage = window.getActivePage(); - if (activePage == null) - return null; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("WelcomeToXmindCount"); //$NON-NLS-1$ - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInput(new URI(URL_WELCOME_FILE), - WorkbenchMessages.WelcomeToXMindHandler_welcomeToXMind_templatedName); - activePage.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); - } - }); - - return null; - } - -} +package org.xmind.cathy.internal.handlers; + +import java.net.URI; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; + +public class WelcomeToXMindHandler extends AbstractHandler { + + private static final String URL_WELCOME_FILE = "platform:/plugin/org.xmind.cathy/$nl$/resource/Welcome%20to%20XMind.xmind"; //$NON-NLS-1$ + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window == null) + return null; + + final IWorkbenchPage activePage = window.getActivePage(); + if (activePage == null) + return null; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.WELCOME_TO_XMIND_COUNT); + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IEditorInput input = MindMapUI.getEditorInputFactory() + .createEditorInput(new URI(URL_WELCOME_FILE), + WorkbenchMessages.WelcomeToXMindHandler_welcomeToXMind_templatedName); + activePage.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); + } + }); + + return null; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/XMindHelpHandler.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/XMindHelpHandler.java index fbe9f3834..1d8f97fea 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/XMindHelpHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/XMindHelpHandler.java @@ -1,45 +1,45 @@ -package org.xmind.cathy.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.ui.browser.BrowserSupport; - -public class XMindHelpHandler extends AbstractHandler { - - public Object execute(ExecutionEvent event) throws ExecutionException { - SafeRunner.run(new SafeRunnable() { - @Override - public void run() throws Exception { -// String internalURL = findInternalHelpURL(); -// if (internalURL != null) { -// BrowserSupport.getInstance().createBrowser() -// .openURL(internalURL); -// } else { - BrowserSupport.getInstance().createBrowser() - .openURL(CathyPlugin.ONLINE_HELP_URL); -// } - } - }); - return null; - } - -// private String findInternalHelpURL() { -// Bundle helpBundle = Platform.getBundle("org.xmind.ui.help"); //$NON-NLS-1$ -// if (helpBundle != null) { -// URL url = FileLocator.find(helpBundle, -// new Path("$nl$/contents/index.html"), null); //$NON-NLS-1$ -// if (url != null) { -// try { -// url = FileLocator.toFileURL(url); -// return url.toExternalForm(); -// } catch (IOException e) { -// } -// } -// } -// return null; -// } -} +package org.xmind.cathy.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.ui.browser.BrowserSupport; + +public class XMindHelpHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { +// String internalURL = findInternalHelpURL(); +// if (internalURL != null) { +// BrowserSupport.getInstance().createBrowser() +// .openURL(internalURL); +// } else { + BrowserSupport.getInstance().createBrowser() + .openURL(CathyPlugin.ONLINE_HELP_URL); +// } + } + }); + return null; + } + +// private String findInternalHelpURL() { +// Bundle helpBundle = Platform.getBundle("org.xmind.ui.help"); //$NON-NLS-1$ +// if (helpBundle != null) { +// URL url = FileLocator.find(helpBundle, +// new Path("$nl$/contents/index.html"), null); //$NON-NLS-1$ +// if (url != null) { +// try { +// url = FileLocator.toFileURL(url); +// return url.toExternalForm(); +// } catch (IOException e) { +// } +// } +// } +// return null; +// } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/AbstractCheckFilesJob.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/AbstractCheckFilesJob.java index 7d1505912..28f7d3e72 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/AbstractCheckFilesJob.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/AbstractCheckFilesJob.java @@ -1,136 +1,136 @@ -package org.xmind.cathy.internal.jobs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.mindmap.MindMapUI; - -public abstract class AbstractCheckFilesJob extends Job { - - private final IWorkbench workbench; - - private List editorsToOpen; - - public AbstractCheckFilesJob(IWorkbench workbench, String jobName) { - super(jobName); - this.workbench = workbench; - addJobChangeListener(new JobChangeAdapter() { - @Override - public void aboutToRun(IJobChangeEvent event) { - prepare(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse - * .core.runtime.jobs.IJobChangeEvent) - */ - @Override - public void done(IJobChangeEvent event) { - finish(); - } - }); - } - - protected void prepare() { - editorsToOpen = null; - } - - protected void finish() { - editorsToOpen = null; - } - - public IWorkbench getWorkbench() { - return workbench; - } - - protected void addEditorToOpen(IEditorInput input) { - if (editorsToOpen == null) - editorsToOpen = new ArrayList(); - editorsToOpen.add(input); - } - - protected void openEditors(IProgressMonitor monitor, String taskName, - int ticks, boolean activate) { - if (editorsToOpen != null && !editorsToOpen.isEmpty()) { - monitor = new SubProgressMonitor(monitor, ticks); - monitor.beginTask(taskName, editorsToOpen.size()); - openEditors(monitor, editorsToOpen, activate); - monitor.done(); - } else { - monitor.worked(ticks); - } - } - - protected void openEditors(IProgressMonitor monitor, - List editorInputs, boolean activate) { - for (final IEditorInput input : editorInputs) { - monitor.subTask(input.getName()); - IEditorPart editor = openEditor(input, activate); - if (editor != null) - activate = false; - monitor.worked(1); - } - } - - protected IEditorPart openEditor(final IEditorInput input, - final boolean activate) { - if (input == null) - return null; - - Display display = workbench.getDisplay(); - if (display == null) - return null; - - final IEditorPart[] result = new IEditorPart[1]; - display.syncExec(new Runnable() { - public void run() { - IWorkbenchWindow window = getPrimaryWindow(); - if (window == null) - return; - final IWorkbenchPage page = window.getActivePage(); - if (page != null) { - SafeRunner.run(new SafeRunnable( - NLS.bind( - WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, - input.getName())) { - public void run() throws Exception { - result[0] = page.openEditor(input, - MindMapUI.MINDMAP_EDITOR_ID, activate); - } - }); - } - } - - }); - return result[0]; - } - - private IWorkbenchWindow getPrimaryWindow() { - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window == null) { - IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); - if (windows != null && windows.length > 0) { - window = windows[0]; - } - } - return window; - } -} +package org.xmind.cathy.internal.jobs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.mindmap.MindMapUI; + +public abstract class AbstractCheckFilesJob extends Job { + + private final IWorkbench workbench; + + private List editorsToOpen; + + public AbstractCheckFilesJob(IWorkbench workbench, String jobName) { + super(jobName); + this.workbench = workbench; + addJobChangeListener(new JobChangeAdapter() { + @Override + public void aboutToRun(IJobChangeEvent event) { + prepare(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse + * .core.runtime.jobs.IJobChangeEvent) + */ + @Override + public void done(IJobChangeEvent event) { + finish(); + } + }); + } + + protected void prepare() { + editorsToOpen = null; + } + + protected void finish() { + editorsToOpen = null; + } + + public IWorkbench getWorkbench() { + return workbench; + } + + protected void addEditorToOpen(IEditorInput input) { + if (editorsToOpen == null) + editorsToOpen = new ArrayList(); + editorsToOpen.add(input); + } + + protected void openEditors(IProgressMonitor monitor, String taskName, + int ticks, boolean activate) { + if (editorsToOpen != null && !editorsToOpen.isEmpty()) { + monitor = new SubProgressMonitor(monitor, ticks); + monitor.beginTask(taskName, editorsToOpen.size()); + openEditors(monitor, editorsToOpen, activate); + monitor.done(); + } else { + monitor.worked(ticks); + } + } + + protected void openEditors(IProgressMonitor monitor, + List editorInputs, boolean activate) { + for (final IEditorInput input : editorInputs) { + monitor.subTask(input.getName()); + IEditorPart editor = openEditor(input, activate); + if (editor != null) + activate = false; + monitor.worked(1); + } + } + + protected IEditorPart openEditor(final IEditorInput input, + final boolean activate) { + if (input == null) + return null; + + Display display = workbench.getDisplay(); + if (display == null) + return null; + + final IEditorPart[] result = new IEditorPart[1]; + display.syncExec(new Runnable() { + public void run() { + IWorkbenchWindow window = getPrimaryWindow(); + if (window == null) + return; + final IWorkbenchPage page = window.getActivePage(); + if (page != null) { + SafeRunner.run(new SafeRunnable( + NLS.bind( + WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, + input.getName())) { + public void run() throws Exception { + result[0] = page.openEditor(input, + MindMapUI.MINDMAP_EDITOR_ID, activate); + } + }); + } + } + + }); + return result[0]; + } + + private IWorkbenchWindow getPrimaryWindow() { + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) { + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + if (windows != null && windows.length > 0) { + window = windows[0]; + } + } + return window; + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/DownloadAndOpenFileJob.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/DownloadAndOpenFileJob.java index eaa73ed56..ad461860a 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/DownloadAndOpenFileJob.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/DownloadAndOpenFileJob.java @@ -1,261 +1,261 @@ -package org.xmind.cathy.internal.jobs; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.core.Core; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.imports.freemind.FreeMindImporter; -import org.xmind.ui.internal.imports.mm.MindManagerImporter; -import org.xmind.ui.io.DownloadJob; -import org.xmind.ui.mindmap.MindMapUI; - -public class DownloadAndOpenFileJob extends Job { - - private IWorkbench workbench; - - private String url; - - private String targetName; - - private File tempFile; - - public DownloadAndOpenFileJob(IWorkbench workbench, String url, - String targetName) { - super(WorkbenchMessages.DownloadAndOpenFileJob_jobName); - Assert.isNotNull(workbench); - Assert.isNotNull(url); - this.workbench = workbench; - this.url = url; - this.targetName = targetName; - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - monitor.beginTask(null, 2); - - IStatus downloaded = download(monitor); - if (!downloaded.isOK()) - return downloaded; - - monitor.worked(1); - - IStatus opened = open(monitor); - if (!opened.isOK()) - return opened; - - monitor.done(); - - return Status.OK_STATUS; - } - - private IStatus download(IProgressMonitor monitor) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - monitor.subTask(NLS.bind( - WorkbenchMessages.DownloadAndOpenFileJob_Task_Download_with_url, - url)); - tempFile = createTempPath(url); - if (tempFile.getParentFile() == null - || !tempFile.getParentFile().isDirectory()) { - return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, - WorkbenchMessages.DownloadAndOpenFileJob_Error_FailedToCreateTempFile); - } - - DownloadJob downloadJob = new DownloadJob( - WorkbenchMessages.DownloadAndOpenFileJob_DownloadJob_jobName, - url, tempFile.getAbsolutePath(), MindMapUI.PLUGIN_ID); - downloadJob.setUser(true); - downloadJob.schedule(); - try { - downloadJob.join(); - } catch (InterruptedException e) { - } - - if (monitor.isCanceled()) { - downloadJob.cancel(); - return Status.CANCEL_STATUS; - } - - IStatus downloaded = downloadJob.getResult(); - if (downloaded == null) - // This should never happen? - return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, - "No result retrieved from download job."); //$NON-NLS-1$ - return downloaded; - } - - private IStatus open(IProgressMonitor monitor) { - monitor.subTask(NLS.bind( - WorkbenchMessages.DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url, - url)); - - try { - IStorage tempStorage = createTempStorage(); - final IWorkbook workbook = loadWorkbook(monitor, tempStorage); - if (workbook != null) { - return openMindMapEditor(monitor, workbook); - } - } catch (Throwable e) { - return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, - NLS.bind( - WorkbenchMessages.DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url, - url), - e); - } - return Status.CANCEL_STATUS; - } - - private IWorkbook loadWorkbook(IProgressMonitor monitor, - IStorage tempStorage) throws Exception { - String ext = FileUtils.getExtension(tempFile.getAbsolutePath()); - if (MindMapUI.FILE_EXT_XMIND.equalsIgnoreCase(ext)) { - return loadWorkbookFromXMindFile(monitor, tempStorage); - } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(ext)) { - return loadWorkbookFromTemplate(monitor, tempStorage); - } else if (".mmap".equalsIgnoreCase(ext)) { //$NON-NLS-1$ - return loadWorkbookFromMindManagerFile(monitor, tempStorage); - } else if (".mm".equalsIgnoreCase(ext)) { //$NON-NLS-1$ - return loadWorkbookFromFreeMindFile(monitor, tempStorage); - } - return null; - } - - private IWorkbook loadWorkbookFromXMindFile(IProgressMonitor monitor, - IStorage tempStorage) throws Exception { - return Core.getWorkbookBuilder().loadFromFile(tempFile, tempStorage, - null); - } - - private IWorkbook loadWorkbookFromTemplate(IProgressMonitor monitor, - IStorage tempStorage) throws Exception { - return Core.getWorkbookBuilder().loadFromFile(tempFile, tempStorage, - null); - } - - private IWorkbook loadWorkbookFromMindManagerFile(IProgressMonitor monitor, - IStorage tempStorage) throws Exception { - MindManagerImporter importer = new MindManagerImporter( - tempFile.getAbsolutePath()); - importer.build(); - return importer.getTargetWorkbook(); - } - - private IWorkbook loadWorkbookFromFreeMindFile(IProgressMonitor monitor, - IStorage tempStorage) throws Exception { - FreeMindImporter importer = new FreeMindImporter( - tempFile.getAbsolutePath()); - importer.build(); - return importer.getTargetWorkbook(); - } - - private IStatus openMindMapEditor(final IProgressMonitor monitor, - final IWorkbook workbook) { - final IStatus[] result = new IStatus[1]; - result[0] = null; - Display display = workbench.getDisplay(); - if (display == null || display.isDisposed()) { - monitor.setCanceled(true); - return Status.CANCEL_STATUS; - } - display.syncExec(new Runnable() { - public void run() { - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window == null) - return; - - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return; - - String name = targetName == null ? getFileName(url) - : targetName; - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, name); - try { - page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID, true); - } catch (PartInitException e) { - result[0] = e.getStatus(); - return; - } - - if (workbook instanceof ICoreEventSource2) { - ((ICoreEventSource2) workbook) - .registerOnceCoreEventListener( - Core.WorkbookPreSaveOnce, - ICoreEventListener.NULL); - } - - result[0] = Status.OK_STATUS; - } - }); - if (result[0] == null) - return Status.CANCEL_STATUS; - return result[0]; - } - - @Override - protected void canceling() { - super.canceling(); - Thread thread = getThread(); - if (thread != null) { - thread.interrupt(); - } - } - - private static File createTempPath(String url) { - String fileName = getFileName(url); - String ext = FileUtils.getExtension(fileName); - String prefix = fileName.substring(0, fileName.length() - ext.length()); - return Core.getWorkspace().createTempFile("download", prefix + "_", //$NON-NLS-1$//$NON-NLS-2$ - ext); - } - - private static IStorage createTempStorage() { - File tempDir = Core.getWorkspace() - .createTempFile("openFromDownloadedFile", "", ".temp"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - tempDir.mkdirs(); - return new DirectoryStorage(tempDir); - } - - private static String getFileName(String url) { - String path; - try { - path = new URI(url).getPath(); - } catch (URISyntaxException e) { - int j = url.lastIndexOf('?'); - if (j < 0) - path = url; - else - path = url.substring(0, j); - } - int i = path.lastIndexOf('/'); - if (i < 0) - return path; - return path.substring(i + 1); - } - -} +package org.xmind.cathy.internal.jobs; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.Core; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.imports.freemind.FreeMindImporter; +import org.xmind.ui.internal.imports.mm.MindManagerImporter; +import org.xmind.ui.io.DownloadJob; +import org.xmind.ui.mindmap.MindMapUI; + +public class DownloadAndOpenFileJob extends Job { + + private IWorkbench workbench; + + private String url; + + private String targetName; + + private File tempFile; + + public DownloadAndOpenFileJob(IWorkbench workbench, String url, + String targetName) { + super(WorkbenchMessages.DownloadAndOpenFileJob_jobName); + Assert.isNotNull(workbench); + Assert.isNotNull(url); + this.workbench = workbench; + this.url = url; + this.targetName = targetName; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + monitor.beginTask(null, 2); + + IStatus downloaded = download(monitor); + if (!downloaded.isOK()) + return downloaded; + + monitor.worked(1); + + IStatus opened = open(monitor); + if (!opened.isOK()) + return opened; + + monitor.done(); + + return Status.OK_STATUS; + } + + private IStatus download(IProgressMonitor monitor) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + monitor.subTask(NLS.bind( + WorkbenchMessages.DownloadAndOpenFileJob_Task_Download_with_url, + url)); + tempFile = createTempPath(url); + if (tempFile.getParentFile() == null + || !tempFile.getParentFile().isDirectory()) { + return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, + WorkbenchMessages.DownloadAndOpenFileJob_Error_FailedToCreateTempFile); + } + + DownloadJob downloadJob = new DownloadJob( + WorkbenchMessages.DownloadAndOpenFileJob_DownloadJob_jobName, + url, tempFile.getAbsolutePath(), MindMapUI.PLUGIN_ID); + downloadJob.setUser(true); + downloadJob.schedule(); + try { + downloadJob.join(); + } catch (InterruptedException e) { + } + + if (monitor.isCanceled()) { + downloadJob.cancel(); + return Status.CANCEL_STATUS; + } + + IStatus downloaded = downloadJob.getResult(); + if (downloaded == null) + // This should never happen? + return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, + "No result retrieved from download job."); //$NON-NLS-1$ + return downloaded; + } + + private IStatus open(IProgressMonitor monitor) { + monitor.subTask(NLS.bind( + WorkbenchMessages.DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url, + url)); + + try { + IStorage tempStorage = createTempStorage(); + final IWorkbook workbook = loadWorkbook(monitor, tempStorage); + if (workbook != null) { + return openMindMapEditor(monitor, workbook); + } + } catch (Throwable e) { + return new Status(IStatus.ERROR, MindMapUI.PLUGIN_ID, + NLS.bind( + WorkbenchMessages.DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url, + url), + e); + } + return Status.CANCEL_STATUS; + } + + private IWorkbook loadWorkbook(IProgressMonitor monitor, + IStorage tempStorage) throws Exception { + String ext = FileUtils.getExtension(tempFile.getAbsolutePath()); + if (MindMapUI.FILE_EXT_XMIND.equalsIgnoreCase(ext)) { + return loadWorkbookFromXMindFile(monitor, tempStorage); + } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(ext)) { + return loadWorkbookFromTemplate(monitor, tempStorage); + } else if (".mmap".equalsIgnoreCase(ext)) { //$NON-NLS-1$ + return loadWorkbookFromMindManagerFile(monitor, tempStorage); + } else if (".mm".equalsIgnoreCase(ext)) { //$NON-NLS-1$ + return loadWorkbookFromFreeMindFile(monitor, tempStorage); + } + return null; + } + + private IWorkbook loadWorkbookFromXMindFile(IProgressMonitor monitor, + IStorage tempStorage) throws Exception { + return Core.getWorkbookBuilder().loadFromFile(tempFile, tempStorage, + null); + } + + private IWorkbook loadWorkbookFromTemplate(IProgressMonitor monitor, + IStorage tempStorage) throws Exception { + return Core.getWorkbookBuilder().loadFromFile(tempFile, tempStorage, + null); + } + + private IWorkbook loadWorkbookFromMindManagerFile(IProgressMonitor monitor, + IStorage tempStorage) throws Exception { + MindManagerImporter importer = new MindManagerImporter( + tempFile.getAbsolutePath()); + importer.build(); + return importer.getTargetWorkbook(); + } + + private IWorkbook loadWorkbookFromFreeMindFile(IProgressMonitor monitor, + IStorage tempStorage) throws Exception { + FreeMindImporter importer = new FreeMindImporter( + tempFile.getAbsolutePath()); + importer.build(); + return importer.getTargetWorkbook(); + } + + private IStatus openMindMapEditor(final IProgressMonitor monitor, + final IWorkbook workbook) { + final IStatus[] result = new IStatus[1]; + result[0] = null; + Display display = workbench.getDisplay(); + if (display == null || display.isDisposed()) { + monitor.setCanceled(true); + return Status.CANCEL_STATUS; + } + display.syncExec(new Runnable() { + public void run() { + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) + return; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return; + + String name = targetName == null ? getFileName(url) + : targetName; + IEditorInput input = MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, name); + try { + page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID, true); + } catch (PartInitException e) { + result[0] = e.getStatus(); + return; + } + + if (workbook instanceof ICoreEventSource2) { + ((ICoreEventSource2) workbook) + .registerOnceCoreEventListener( + Core.WorkbookPreSaveOnce, + ICoreEventListener.NULL); + } + + result[0] = Status.OK_STATUS; + } + }); + if (result[0] == null) + return Status.CANCEL_STATUS; + return result[0]; + } + + @Override + protected void canceling() { + super.canceling(); + Thread thread = getThread(); + if (thread != null) { + thread.interrupt(); + } + } + + private static File createTempPath(String url) { + String fileName = getFileName(url); + String ext = FileUtils.getExtension(fileName); + String prefix = fileName.substring(0, fileName.length() - ext.length()); + return Core.getWorkspace().createTempFile("download", prefix + "_", //$NON-NLS-1$//$NON-NLS-2$ + ext); + } + + private static IStorage createTempStorage() { + File tempDir = Core.getWorkspace() + .createTempFile("openFromDownloadedFile", "", ".temp"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + tempDir.mkdirs(); + return new DirectoryStorage(tempDir); + } + + private static String getFileName(String url) { + String path; + try { + path = new URI(url).getPath(); + } catch (URISyntaxException e) { + int j = url.lastIndexOf('?'); + if (j < 0) + path = url; + else + path = url.substring(0, j); + } + int i = path.lastIndexOf('/'); + if (i < 0) + return path; + return path.substring(i + 1); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenFilesJob.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenFilesJob.java index ccffbb816..2edb02e58 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenFilesJob.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenFilesJob.java @@ -1,277 +1,277 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.cathy.internal.jobs; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbench; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.core.Core; -import org.xmind.core.IWorkbook; -import org.xmind.core.command.Command; -import org.xmind.core.command.CommandJob; -import org.xmind.core.command.ICommand; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.MarkerImpExpUtils; -import org.xmind.ui.internal.imports.freemind.FreeMindImporter; -import org.xmind.ui.internal.imports.mm.MindManagerImporter; -import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.PrefUtils; -import org.xmind.ui.wizards.MindMapImporter; - -/** - * @author Frank Shaka - * - */ -public class OpenFilesJob extends AbstractCheckFilesJob { - - private List filesToOpen; - - private boolean markersImported = false; - - private List commandFilesToOpen = new ArrayList(1); - - public OpenFilesJob(IWorkbench workbench, String jobName) { - super(workbench, jobName); - this.filesToOpen = new ArrayList(); - } - - /** - * - */ - public OpenFilesJob(IWorkbench workbench, String jobName, - Collection files) { - super(workbench, jobName); - this.filesToOpen = new ArrayList(files); - } - - @Override - protected void prepare() { - markersImported = false; - super.prepare(); - } - - @Override - protected void finish() { - filesToOpen.clear(); - markersImported = false; - super.finish(); - } - - protected IStatus run(IProgressMonitor monitor) { - monitor.beginTask(null, getTotalSteps()); - doCheckAndOpenFiles(monitor); - monitor.done(); - return Status.OK_STATUS; - } - - /** - * Number of ticks that this job is going to consume. - * - * @return - */ - protected int getTotalSteps() { - return 4; - } - - /** - * Opens files. - * - * @param monitor - * the progress monitor - */ - protected void doCheckAndOpenFiles(IProgressMonitor monitor) { - filterFilesToOpen(filesToOpen, new SubProgressMonitor(monitor, 1)); - - if (filesToOpen.isEmpty()) { - monitor.worked(2); - } else { - addEditors(new SubProgressMonitor(monitor, 1)); - openEditors(monitor, - WorkbenchMessages.CheckOpenFilesJob_OpenFiles_name, 1, - true); - } - - onFilsOpened(new SubProgressMonitor(monitor, 1)); - } - - /** - * - */ - protected void onFilsOpened(IProgressMonitor monitor) { - monitor.beginTask(null, 1); - if (markersImported) - showMarkersPrefPage(); - if (!commandFilesToOpen.isEmpty()) { - openXMindCommandFiles(); - } - monitor.done(); - } - - /** - * Filters the files to open. Subclasses may add/remove files to/from the - * `filesToOpen` list. - * - * @param monitor - */ - protected void filterFilesToOpen(List filesToOpen, - IProgressMonitor monitor) { - monitor.beginTask(null, 1); - monitor.done(); - } - - /** - * Add editors to open. - * - * @param monitor - */ - protected void addEditors(final IProgressMonitor monitor) { - monitor.beginTask(WorkbenchMessages.CheckOpenFilesJob_OpenFiles_name, - filesToOpen.size()); - for (final String fileName : filesToOpen) { - SafeRunner.run(new SafeRunnable(NLS.bind( - WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, - fileName)) { - public void run() throws Exception { - monitor.subTask(fileName); - IEditorInput input = createEditorInput(fileName, monitor); - if (input != null) { - addEditorToOpen(input); - } - monitor.worked(1); - } - }); - } - monitor.done(); - } - - /** - * Create an editor input from the file, or do anything to open the file. - * - * @param fileName - * @param monitor - * @return - * @throws Exception - */ - protected IEditorInput createEditorInput(String fileName, - IProgressMonitor monitor) throws Exception { - final ICommand command = Command.parseURI(fileName); - if (command != null) { - new CommandJob(command, null).schedule(); - return null; - } - - final String path = fileName; - String extension = FileUtils.getExtension(path); - - if (CathyPlugin.COMMAND_FILE_EXT.equalsIgnoreCase(extension)) { - return openXMindCommandFile(path); - } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { - return newFromTemplate(path, fileName); - } else if (".mmap".equalsIgnoreCase(extension)) { //$NON-NLS-1$ - return importMindManagerFile(path, fileName); - } else if (".mm".equalsIgnoreCase(extension)) { //$NON-NLS-1$ - return importFreeMindFile(path, fileName); - } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE - .equalsIgnoreCase(extension)) { - return importMarkers(path); - } else if (new File(path).exists()) { - return MindMapUI.getEditorInputFactory() - .createEditorInputForFile(new File(path)); - } else { - // assumes we're opening xmind files - IWorkbook workbook = Core.getWorkbookBuilder().loadFromPath(path); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - } - - protected IEditorInput newFromTemplate(String path, String fileName) - throws Exception { - IWorkbook workbook = Core.getWorkbookBuilder().loadFromPath(path); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - - protected IEditorInput importMindManagerFile(String path, String fileName) - throws Exception { - MindMapImporter importer = new MindManagerImporter(path); - importer.build(); - IWorkbook workbook = importer.getTargetWorkbook(); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - - protected IEditorInput importFreeMindFile(String path, String fileName) - throws Exception { - FreeMindImporter importer = new FreeMindImporter(path); - importer.build(); - IWorkbook workbook = importer.getTargetWorkbook(); - return workbook == null ? null - : MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - fileName); - } - - protected IEditorInput importMarkers(String path) throws Exception { - MarkerImpExpUtils.importMarkerPackage(path); - markersImported = true; - return null; - } - - private void showMarkersPrefPage() { - Display display = getWorkbench().getDisplay(); - if (display == null || display.isDisposed()) - return; - - display.asyncExec(new Runnable() { - public void run() { - PrefUtils.openPrefDialog(null, MarkerManagerPrefPage.ID); - } - }); - } - - private IEditorInput openXMindCommandFile(String path) { - commandFilesToOpen.add(path); - return null; - } - - private void openXMindCommandFiles() { - for (String path : commandFilesToOpen) { - new OpenXMindCommandFileJob(path).schedule(500); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.cathy.internal.jobs; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbench; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.Core; +import org.xmind.core.IWorkbook; +import org.xmind.core.command.Command; +import org.xmind.core.command.CommandJob; +import org.xmind.core.command.ICommand; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.MarkerImpExpUtils; +import org.xmind.ui.internal.imports.freemind.FreeMindImporter; +import org.xmind.ui.internal.imports.mm.MindManagerImporter; +import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.PrefUtils; +import org.xmind.ui.wizards.MindMapImporter; + +/** + * @author Frank Shaka + * + */ +public class OpenFilesJob extends AbstractCheckFilesJob { + + private List filesToOpen; + + private boolean markersImported = false; + + private List commandFilesToOpen = new ArrayList(1); + + public OpenFilesJob(IWorkbench workbench, String jobName) { + super(workbench, jobName); + this.filesToOpen = new ArrayList(); + } + + /** + * + */ + public OpenFilesJob(IWorkbench workbench, String jobName, + Collection files) { + super(workbench, jobName); + this.filesToOpen = new ArrayList(files); + } + + @Override + protected void prepare() { + markersImported = false; + super.prepare(); + } + + @Override + protected void finish() { + filesToOpen.clear(); + markersImported = false; + super.finish(); + } + + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(null, getTotalSteps()); + doCheckAndOpenFiles(monitor); + monitor.done(); + return Status.OK_STATUS; + } + + /** + * Number of ticks that this job is going to consume. + * + * @return + */ + protected int getTotalSteps() { + return 4; + } + + /** + * Opens files. + * + * @param monitor + * the progress monitor + */ + protected void doCheckAndOpenFiles(IProgressMonitor monitor) { + filterFilesToOpen(filesToOpen, new SubProgressMonitor(monitor, 1)); + + if (filesToOpen.isEmpty()) { + monitor.worked(2); + } else { + addEditors(new SubProgressMonitor(monitor, 1)); + openEditors(monitor, + WorkbenchMessages.CheckOpenFilesJob_OpenFiles_name, 1, + true); + } + + onFilsOpened(new SubProgressMonitor(monitor, 1)); + } + + /** + * + */ + protected void onFilsOpened(IProgressMonitor monitor) { + monitor.beginTask(null, 1); + if (markersImported) + showMarkersPrefPage(); + if (!commandFilesToOpen.isEmpty()) { + openXMindCommandFiles(); + } + monitor.done(); + } + + /** + * Filters the files to open. Subclasses may add/remove files to/from the + * `filesToOpen` list. + * + * @param monitor + */ + protected void filterFilesToOpen(List filesToOpen, + IProgressMonitor monitor) { + monitor.beginTask(null, 1); + monitor.done(); + } + + /** + * Add editors to open. + * + * @param monitor + */ + protected void addEditors(final IProgressMonitor monitor) { + monitor.beginTask(WorkbenchMessages.CheckOpenFilesJob_OpenFiles_name, + filesToOpen.size()); + for (final String fileName : filesToOpen) { + SafeRunner.run(new SafeRunnable(NLS.bind( + WorkbenchMessages.CheckOpenFilesJob_FailsToOpen_message, + fileName)) { + public void run() throws Exception { + monitor.subTask(fileName); + IEditorInput input = createEditorInput(fileName, monitor); + if (input != null) { + addEditorToOpen(input); + } + monitor.worked(1); + } + }); + } + monitor.done(); + } + + /** + * Create an editor input from the file, or do anything to open the file. + * + * @param fileName + * @param monitor + * @return + * @throws Exception + */ + protected IEditorInput createEditorInput(String fileName, + IProgressMonitor monitor) throws Exception { + final ICommand command = Command.parseURI(fileName); + if (command != null) { + new CommandJob(command, null).schedule(); + return null; + } + + final String path = fileName; + String extension = FileUtils.getExtension(path); + + if (CathyPlugin.COMMAND_FILE_EXT.equalsIgnoreCase(extension)) { + return openXMindCommandFile(path); + } else if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { + return newFromTemplate(path, fileName); + } else if (".mmap".equalsIgnoreCase(extension)) { //$NON-NLS-1$ + return importMindManagerFile(path, fileName); + } else if (".mm".equalsIgnoreCase(extension)) { //$NON-NLS-1$ + return importFreeMindFile(path, fileName); + } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE + .equalsIgnoreCase(extension)) { + return importMarkers(path); + } else if (new File(path).exists()) { + return MindMapUI.getEditorInputFactory() + .createEditorInputForFile(new File(path)); + } else { + // assumes we're opening xmind files + IWorkbook workbook = Core.getWorkbookBuilder().loadFromPath(path); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + } + + protected IEditorInput newFromTemplate(String path, String fileName) + throws Exception { + IWorkbook workbook = Core.getWorkbookBuilder().loadFromPath(path); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + + protected IEditorInput importMindManagerFile(String path, String fileName) + throws Exception { + MindMapImporter importer = new MindManagerImporter(path); + importer.build(); + IWorkbook workbook = importer.getTargetWorkbook(); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + + protected IEditorInput importFreeMindFile(String path, String fileName) + throws Exception { + FreeMindImporter importer = new FreeMindImporter(path); + importer.build(); + IWorkbook workbook = importer.getTargetWorkbook(); + return workbook == null ? null + : MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + fileName); + } + + protected IEditorInput importMarkers(String path) throws Exception { + MarkerImpExpUtils.importMarkerPackage(path); + markersImported = true; + return null; + } + + private void showMarkersPrefPage() { + Display display = getWorkbench().getDisplay(); + if (display == null || display.isDisposed()) + return; + + display.asyncExec(new Runnable() { + public void run() { + PrefUtils.openPrefDialog(null, MarkerManagerPrefPage.ID); + } + }); + } + + private IEditorInput openXMindCommandFile(String path) { + commandFilesToOpen.add(path); + return null; + } + + private void openXMindCommandFiles() { + for (String path : commandFilesToOpen) { + new OpenXMindCommandFileJob(path).schedule(500); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenXMindCommandFileJob.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenXMindCommandFileJob.java index 5e555541e..c6bb40bc4 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenXMindCommandFileJob.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/jobs/OpenXMindCommandFileJob.java @@ -1,139 +1,139 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.cathy.internal.jobs; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.osgi.util.NLS; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.core.command.transfer.IncomingCommandHandler; - -public class OpenXMindCommandFileJob extends Job { - - private static final String DEBUG_OPTION = "/debug/openXMindCommandFile"; //$NON-NLS-1$ - - private static boolean DEBUGGING = CathyPlugin.getDefault() - .isDebugging(DEBUG_OPTION); - - private static class InternalOpenXMindCommandFileHandler - extends IncomingCommandHandler { - - protected IStatus createReadingErrorStatus(Throwable e) { - return super.createReadingErrorStatus(e); - } - - protected IStatus createWritingErrorStatus(Throwable e) { - return super.createWritingErrorStatus(e); - } - - } - - private static class NullOutputStream extends OutputStream { - - public void write(int b) throws IOException { - // ignore all bits - } - - public void write(byte[] b) throws IOException { - // ignore all bits - } - - public void write(byte[] b, int off, int len) throws IOException { - // ignore all bits - } - - } - - private String commandFilePath; - - public OpenXMindCommandFileJob(String commandFilePath) { - super(NLS.bind(WorkbenchMessages.OpenXMindCommandFileJob_name, - commandFilePath)); - this.commandFilePath = commandFilePath; - setUser(false); - } - - protected IStatus run(IProgressMonitor monitor) { - if (commandFilePath == null) - return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, - WorkbenchMessages.OpenXMindCommandFileJob_failed_noCommandFilePath_text); - - File commandFile = new File(commandFilePath); - if (!commandFile.exists() || !commandFile.isFile() - || !commandFile.canRead()) - return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, - NLS.bind( - WorkbenchMessages.OpenXMindCommandFileJob_failed_fileIsNotReadable, - commandFilePath)); - - try { - InputStream input = new FileInputStream(commandFile); - try { - OutputStream output = createOutputStream(); - try { - IncomingCommandHandler handler = new InternalOpenXMindCommandFileHandler(); - handler.setPluginId(CathyPlugin.PLUGIN_ID); - IStatus result = handler.handleIncomingCommand(monitor, - input, output); - if (DEBUGGING) { - logOutput(output); - } - return result; - } finally { - output.close(); - } - } finally { - input.close(); - } - } catch (IOException e) { - return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, - NLS.bind( - WorkbenchMessages.OpenXMindCommandFileJob_failed_openXMindCommandFile, - e.getLocalizedMessage()), - e); - } - } - - private void logOutput(OutputStream output) { - if (!(output instanceof ByteArrayOutputStream)) - return; - try { - String outputText = ((ByteArrayOutputStream) output) - .toString("UTF-8"); //$NON-NLS-1$ - System.out.println("Response of XMind command file: " //$NON-NLS-1$ - + commandFilePath); - System.out.println(outputText); - } catch (UnsupportedEncodingException e2) { - // Ignore encoding error - } - } - - private OutputStream createOutputStream() { - if (DEBUGGING) - return new ByteArrayOutputStream(4096); - return new NullOutputStream(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.cathy.internal.jobs; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.osgi.util.NLS; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.core.command.transfer.IncomingCommandHandler; + +public class OpenXMindCommandFileJob extends Job { + + private static final String DEBUG_OPTION = "/debug/openXMindCommandFile"; //$NON-NLS-1$ + + private static boolean DEBUGGING = CathyPlugin.getDefault() + .isDebugging(DEBUG_OPTION); + + private static class InternalOpenXMindCommandFileHandler + extends IncomingCommandHandler { + + protected IStatus createReadingErrorStatus(Throwable e) { + return super.createReadingErrorStatus(e); + } + + protected IStatus createWritingErrorStatus(Throwable e) { + return super.createWritingErrorStatus(e); + } + + } + + private static class NullOutputStream extends OutputStream { + + public void write(int b) throws IOException { + // ignore all bits + } + + public void write(byte[] b) throws IOException { + // ignore all bits + } + + public void write(byte[] b, int off, int len) throws IOException { + // ignore all bits + } + + } + + private String commandFilePath; + + public OpenXMindCommandFileJob(String commandFilePath) { + super(NLS.bind(WorkbenchMessages.OpenXMindCommandFileJob_name, + commandFilePath)); + this.commandFilePath = commandFilePath; + setUser(false); + } + + protected IStatus run(IProgressMonitor monitor) { + if (commandFilePath == null) + return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, + WorkbenchMessages.OpenXMindCommandFileJob_failed_noCommandFilePath_text); + + File commandFile = new File(commandFilePath); + if (!commandFile.exists() || !commandFile.isFile() + || !commandFile.canRead()) + return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, + NLS.bind( + WorkbenchMessages.OpenXMindCommandFileJob_failed_fileIsNotReadable, + commandFilePath)); + + try { + InputStream input = new FileInputStream(commandFile); + try { + OutputStream output = createOutputStream(); + try { + IncomingCommandHandler handler = new InternalOpenXMindCommandFileHandler(); + handler.setPluginId(CathyPlugin.PLUGIN_ID); + IStatus result = handler.handleIncomingCommand(monitor, + input, output); + if (DEBUGGING) { + logOutput(output); + } + return result; + } finally { + output.close(); + } + } finally { + input.close(); + } + } catch (IOException e) { + return new Status(IStatus.WARNING, CathyPlugin.PLUGIN_ID, + NLS.bind( + WorkbenchMessages.OpenXMindCommandFileJob_failed_openXMindCommandFile, + e.getLocalizedMessage()), + e); + } + } + + private void logOutput(OutputStream output) { + if (!(output instanceof ByteArrayOutputStream)) + return; + try { + String outputText = ((ByteArrayOutputStream) output) + .toString("UTF-8"); //$NON-NLS-1$ + System.out.println("Response of XMind command file: " //$NON-NLS-1$ + + commandFilePath); + System.out.println(outputText); + } catch (UnsupportedEncodingException e2) { + // Ignore encoding error + } + } + + private OutputStream createOutputStream() { + if (DEBUGGING) + return new ByteArrayOutputStream(4096); + return new NullOutputStream(); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/messages.properties b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/messages.properties index f2bff5c55..6bf60a363 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/messages.properties +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/messages.properties @@ -1,179 +1,181 @@ -AppWindowTitle=XMind -ProWindowTitle=XMind Pro - -File_menu_text=&File -Edit_menu_text=&Edit -Help_menu_text=&Help -SaveAction_text=&Save New Revision - -GeneralPrefPage_seePolicy_link=See Policy -GeneralPrefPage_title=General -GeneralPrefPage_usageData_text=Send usage data. (NO PRIVATE DATA\!) -GeneralPrefPageSection_RecentFileCountSection_title=Files List -GeneralPrefPageSection_AutoSaveGroup_title=Save & Backup -RecentFiles_label=Size of the recently opened files list: -RecentFileViewer_PinThisMapAction_label=Pin This Map -RecentFileViewer_UnpinThisMap_label=Unpin This Map -RestoreLastSession_label=Restore last session on startup -CathyWorkbenchWindowAdvisor_menu_lockAction_text=Lock the Toolbars -CathyWorkbenchWindowAdvisor_menu_resetAction_text=Reset -CathyWorkbenchWindowAdvisor_windowTitle_home_prefix=Home - -ChangeLanguage_button=&Change Now -ChangeLanguageTo_description=Change language to: -CheckUpdates_label=Check updates and news on startup -AutoBackup_label=Auto backup editing files to Black Box -AutoBackupIndicator_AutoSaveDisabled_description=Do not save opened workbooks automatically -AutoBackupIndicator_AutoSaveDisabled_label=Auto Save: OFF -AutoBackupIndicator_AutoSaveEnabled_label=Auto Save: ON -AutoBackupIndicator_DisableAutoSaveAction_text=Disable Auto Save -AutoBackupIndicator_EnableAutoSaveAction_text=Enable Auto Save -AutoBackupIndicator_OpenPreferenceAction_text=Preference... -AutoSave_label=Automatically save all workbooks every -AutoSave_Minutes=minutes -AutoSave_label2=Automatically save all opened workbooks every {0} minutes -KeyAssist_text=&Key Assist... -Help_text=XMind Help -Help_toolTip=Help contents of XMind -Update_text=Check For Updates... -Update_toolTip=Find and Update... -Startup_title=Startup -StartupAction_label=When XMind starts: -StartupAction_OpenDialog=Show templates and themes -StartupAction_BlankMap=Open a blank map -StartupAction_HomeMap=Open my home map -StartupAction_LastSession=Open maps unclosed last time -HomeMap_label=Home map: -HomeMap_NotFound_error=Home map not found. - -appWindow_ListSelectionDialog_Text=XMind didn't shut down correctly. To reopen workbooks you had opened, select from the list below: -appWindow_ListSelectionDialog_Title=Recover From Crash - -CheckOpenFilesJob_CheckFiles_name=Check for files to open -CheckOpenFilesJob_OpenFiles_name=Open files -CheckOpenFilesJob_ShowPresentation_name=Show presentation -CheckOpenFilesJob_FailsToOpen_message=Fails to open file: {0} - -CheckRecoverFilesJob_jobName=Check And Recover Files -CheckRecoverFilesJob_LoadFiles_name=Load information of files to recover -CheckRecoverFilesJob_FilterFiles_name=Filter files to recover -CheckRecoverFilesJob_RecoverFiles_name=Open recovered files - -CheckUpdatesJob_jobName=Find updates -CheckUpdatesJob_Fail_message=Fail to find new updates of XMind. Please check your network connection and try again. -CheckUpdatesJob_NoUpdate_message=No updates found. You are using the latest version of XMind. -CheckUpdatesJob_NewUpdate_message=A new version of XMind is available. Download now? -CheckUpdatesJob_NewUpdate_info_message=Version: {0}, Size: {1} -CheckUpdatesJob_NewUpdate_moreDownloads_text=More downloads -ConfirmDeleteTemplateDialog_message_withTemplateName=You are deleting the template ''{0}''. -ConfirmDeleteTemplateDialog_title=XMind - Delete Template -ConfirmToRestart_cancelButton=Cancel -ConfirmToRestart_defaultButton=Restart -ConfirmToRestart_description=Are you sure to change language to "{0}"? Restart to change now. -ConfirmToRestart_title=Confirm to Restart -ConstantsHacker_WizardHandler_menuLabel=Export {0}... - -StartupJob_jobName=Initializing XMind Workbench -StartupJob_OpenBootstrapEditor_name=Open a bootstrap editor -StartupJob_OpenBlankMap=Open a blank map -StartupJob_OpenHomeMap=Open the home map -StartupJob_OpenLastSession=Open maps unclosed last time -SupportLanguageName_Arabic=Arabic -SupportLanguageName_Danish=Danish -SupportLanguageName_English=English -SupportLanguageName_Spanish=Spanish -SupportLanguageName_French=French -SupportLanguageName_German=German -SupportLanguageName_Italian=Italian -SupportLanguageName_Japanese=Japanese -SupportLanguageName_Korean=Korean -SupportLanguageName_Portuguese_Brazilian=Portuguese(Brazilian) -SupportLanguageName_Russian=Russian -SupportLanguageName_SimplifiedCN=Simplified Chinese -SupportLanguageName_Slovenian=Slovenian -SupportLanguageName_TraditionalCN=Traditional Chinese - -PromptSaveEditorOnClosing_message=''{0}'' has unsaved changes. Save it before closing? - -About_LicensedTo=Licensed to {0}\n -About_ProTitle={0} Pro -About_PlusTitle={0} Plus -About_ProSubscriptionTitle=\ Pro Subscription -About_LicenseTypePattern=Activated as XMind{0}.\n -About_LicenseType_Unactivated=Unactivated.\n - -DownloadAndOpenFileJob_jobName=Download And Open File -DownloadAndOpenFileJob_Task_Download_with_url=Downloading from {0} -DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url=Opening file donwloaded from {0} -DownloadAndOpenFileJob_Error_FailedToCreateTempFile=Failed to make temporary location to receive downloaded file. -DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url=Failed to load workbook from url: {0} -DownloadAndOpenFileJob_DownloadJob_jobName=Download File -OpenXMindCommandFileJob_failed_fileIsNotReadable=Failed to open XMind command file: File is not readable: {0} -OpenXMindCommandFileJob_failed_noCommandFilePath_text=Failed to open XMind command file: No command file path specified. -OpenXMindCommandFileJob_failed_openXMindCommandFile=Failed to open XMind command file: {0} -OpenXMindCommandFileJob_name=Opening command file: {0} -WelcomeDialog_item_slide_title=Slide-based Story -WelcomeDialog_item_slide_description=Create slideshows from mind maps -WelcomeDialog_item_cloud_title=XMind Cloud -WelcomeDialog_item_cloud_description=Create folders and sort files in Cloud -WelcomeDialog_item_high_dpi_title=High DPI Support -WelcomeDialog_item_high_dpi_description=Better experience on high resolution screens -WelcomeDialog_item_workspace_description=New design for more efficient map editing -WelcomeDialog_item_workspace_title=New Workspace -WelcomeDialog_okButton_text=OK -WelcomeDialog_seePolicy_link=See Policy -WelcomeDialog_uploadDataCheck_text=Send usage data. (NO PRIVATE DATA\!) -WelcomDialog_Welcom_title=Welcome to XMind 8 -WelcomDialog_WhatIsNew_title=What's new? -WelcomeToXMindHandler_welcomeToXMind_templatedName=Welcome to XMind -WizardHandler_menuLabel= - - -BetaVerifier_BetaExpiredPromptDialog_windowTitle=XMind Beta Expired -BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId=XMind{0} (v{1}) Beta Edition has expired. You can check and install the latest release now, or visit www.xmind.net and download by your self. Thank you for your trial. -BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text=&Check and Install -BetaVerifier_BetaExpiredPromptDialog_ExitButton_text=&Exit -BetaVerifier_BetaExpiredPromptDialog_DownloadFailure_message=Oops! An error occurred. Please try again later, or visit www.xmind.net and download the latest release manually. - - -About_Copyright=Copyright (C) 2006 - 2016, XMind Ltd. All rights reserved. -About_Homepage=http://www.xmind.net/ -About_BetaExpiryMessage_withExpiryTime=This beta edition will expire at {0}.\n - -LanguagePrefPage_ConfirmToRestart_laterButton=Restart Later -LanguagePrefPage_ConfirmToRestart2_defaultButton=Restart Now -LanguagePrefPage_ConfirmToRestart2_description=You need to restart XMind to change the language. Do you want to restart now? -LanguagePrefPage_title=Language - -DashboardHideHome_tooltip=Hide Home -DashboardShowHome_tooltip=Show Home - -DashboardBlankPage_name=Blank -DashboardTemplatesPage_name=Templates -DashboardBlankPage_message=Choose a Type -DashboardTemplatesPage_message=Choose a Template - -DashboardRecentFiles_message=Recent - -DashboardThemeChoose_message=Choose a Theme -DashboardThemeCreate_label=Create -NewFileDashboardPage_AddTemplates_tooltip=Add Template... -NewFileDashboardPage_AddTemplates_label=Add -NewFileDashboardPage_DeleteTemplate_tooltip=Delete Template -NewFileDashboardPage_DeleteTemplate_label=Delete -NewFileDashboardPage_ExitEditMode_tooltip=Exit Templates Management Mode -NewFileDashboardPage_ExitEditTemplatesMode_label=Done -NewFileDashboardPage_GoIntoTemplatesManagerMode_tooltip=Manage Templates -NewFileDashboardPage_GoToEditTemplateMode_label=Manage -NewFileDashboardPage_leftTitleBar_text=New -NewFileDashboardPage_TemplateFilterName_label=XMind Template -NewFileDashboardPage_Import_button=Import - -TemplateViewer_SystemGroup_title=Build-in -TemplateViewer_UserGroup_title=User - -RecentFileBlankPage_description=Recent files will appear as icons here. - -RecentFilesLabelProvider_Cloud_text=[Cloud] - -XStackRenderer_TopArea_tipLabel=Please open a map to continue the Operation. -XStackRenderer_BottomArea_Add_button=New Blank Map +AppWindowTitle=XMind +ProWindowTitle=XMind Pro + +File_menu_text=&File +Edit_menu_text=&Edit +Help_menu_text=&Help +SaveAction_text=&Save New Revision + +GeneralPrefPage_seePolicy_link=See Policy +GeneralPrefPage_title=General +GeneralPrefPage_usageData_text=Send usage data. (NO PRIVATE DATA\!) +GeneralPrefPageSection_RecentFileCountSection_title=Files List +GeneralPrefPageSection_AutoSaveGroup_title=Save & Backup +RecentFiles_label=Size of the recently opened files list: +RecentFileViewer_PinThisMapAction_label=Pin This Map +RecentFileViewer_UnpinThisMap_label=Unpin This Map +RestoreLastSession_label=Restore last session on startup +CategorizedTemplateViewer_group_untitiledName=Untitled +CategorizedTemplateViewer_template_untitiledName=Untitled +CathyWorkbenchWindowAdvisor_menu_lockAction_text=Lock the Toolbars +CathyWorkbenchWindowAdvisor_menu_resetAction_text=Reset +CathyWorkbenchWindowAdvisor_windowTitle_home_prefix=Home - +ChangeLanguage_button=&Change Now +ChangeLanguageTo_description=Change language to: +CheckUpdates_label=Check updates and news on startup +AutoBackup_label=Auto backup editing files to Black Box +AutoBackupIndicator_AutoSaveDisabled_description=Do not save opened workbooks automatically +AutoBackupIndicator_AutoSaveDisabled_label=Auto Save: OFF +AutoBackupIndicator_AutoSaveEnabled_label=Auto Save: ON +AutoBackupIndicator_DisableAutoSaveAction_text=Disable Auto Save +AutoBackupIndicator_EnableAutoSaveAction_text=Enable Auto Save +AutoBackupIndicator_OpenPreferenceAction_text=Preference... +AutoSave_label=Automatically save all workbooks every +AutoSave_Minutes=minutes +AutoSave_label2=Automatically save all opened workbooks every {0} minutes +KeyAssist_text=&Key Assist... +Help_text=XMind Help +Help_toolTip=Help contents of XMind +Update_text=Check For Updates... +Update_toolTip=Find and Update... +Startup_title=Startup +StartupAction_label=When XMind starts: +StartupAction_OpenDialog=Show templates and themes +StartupAction_BlankMap=Open a blank map +StartupAction_HomeMap=Open my home map +StartupAction_LastSession=Open maps unclosed last time +HomeMap_label=Home map: +HomeMap_NotFound_error=Home map not found. + +appWindow_ListSelectionDialog_Text=XMind didn't shut down correctly. To reopen workbooks you had opened, select from the list below: +appWindow_ListSelectionDialog_Title=Recover From Crash + +CheckOpenFilesJob_CheckFiles_name=Check for files to open +CheckOpenFilesJob_OpenFiles_name=Open files +CheckOpenFilesJob_ShowPresentation_name=Show presentation +CheckOpenFilesJob_FailsToOpen_message=Fails to open file: {0} + +CheckRecoverFilesJob_jobName=Check And Recover Files +CheckRecoverFilesJob_LoadFiles_name=Load information of files to recover +CheckRecoverFilesJob_FilterFiles_name=Filter files to recover +CheckRecoverFilesJob_RecoverFiles_name=Open recovered files + +CheckUpdatesJob_jobName=Find updates +CheckUpdatesJob_Fail_message=Fail to find new updates of XMind. Please check your network connection and try again. +CheckUpdatesJob_NoUpdate_message=No updates found. You are using the latest version of XMind. +CheckUpdatesJob_NewUpdate_message=A new version of XMind is available. Download now? +CheckUpdatesJob_NewUpdate_info_message=Version: {0}, Size: {1} +CheckUpdatesJob_NewUpdate_moreDownloads_text=More downloads +ConfirmDeleteTemplateDialog_message_withTemplateName=You are deleting the template ''{0}''. +ConfirmDeleteTemplateDialog_title=XMind - Delete Template +ConfirmToRestart_cancelButton=Cancel +ConfirmToRestart_defaultButton=Restart +ConfirmToRestart_description=Are you sure to change language to "{0}"? Restart to change now. +ConfirmToRestart_title=Confirm to Restart +ConstantsHacker_WizardHandler_menuLabel=Export {0}... + +StartupJob_jobName=Initializing XMind Workbench +StartupJob_OpenBootstrapEditor_name=Open a bootstrap editor +StartupJob_OpenBlankMap=Open a blank map +StartupJob_OpenHomeMap=Open the home map +StartupJob_OpenLastSession=Open maps unclosed last time +SupportLanguageName_Arabic=Arabic +SupportLanguageName_Danish=Danish +SupportLanguageName_English=English +SupportLanguageName_Spanish=Spanish +SupportLanguageName_French=French +SupportLanguageName_German=German +SupportLanguageName_Italian=Italian +SupportLanguageName_Japanese=Japanese +SupportLanguageName_Korean=Korean +SupportLanguageName_Portuguese_Brazilian=Portuguese(Brazilian) +SupportLanguageName_Russian=Russian +SupportLanguageName_SimplifiedCN=Simplified Chinese +SupportLanguageName_Slovenian=Slovenian +SupportLanguageName_TraditionalCN=Traditional Chinese + +PromptSaveEditorOnClosing_message=''{0}'' has unsaved changes. Save it before closing? + +About_LicensedTo=Licensed to {0}\n +About_ProTitle={0} Pro +About_PlusTitle={0} Plus +About_ProSubscriptionTitle=\ Pro Subscription +About_LicenseTypePattern=Activated as XMind{0}.\n +About_LicenseType_Unactivated=Unactivated.\n + +DownloadAndOpenFileJob_jobName=Download And Open File +DownloadAndOpenFileJob_Task_Download_with_url=Downloading from {0} +DownloadAndOpenFileJob_Task_OpenDownloadedFile_with_url=Opening file donwloaded from {0} +DownloadAndOpenFileJob_Error_FailedToCreateTempFile=Failed to make temporary location to receive downloaded file. +DownloadAndOpenFileJob_Error_FailedToLoadWorkbook_with_url=Failed to load workbook from url: {0} +DownloadAndOpenFileJob_DownloadJob_jobName=Download File +OpenXMindCommandFileJob_failed_fileIsNotReadable=Failed to open XMind command file: File is not readable: {0} +OpenXMindCommandFileJob_failed_noCommandFilePath_text=Failed to open XMind command file: No command file path specified. +OpenXMindCommandFileJob_failed_openXMindCommandFile=Failed to open XMind command file: {0} +OpenXMindCommandFileJob_name=Opening command file: {0} +WelcomeDialog_item_slide_title=Slide-based Story +WelcomeDialog_item_slide_description=Create slideshows from mind maps +WelcomeDialog_item_cloud_title=XMind Cloud +WelcomeDialog_item_cloud_description=Create folders and sort files in Cloud +WelcomeDialog_item_high_dpi_title=High DPI Support +WelcomeDialog_item_high_dpi_description=Better experience on high resolution screens +WelcomeDialog_item_workspace_description=New design for more efficient map editing +WelcomeDialog_item_workspace_title=New Workspace +WelcomeDialog_okButton_text=OK +WelcomeDialog_seePolicy_link=See Policy +WelcomeDialog_uploadDataCheck_text=Send usage data. (NO PRIVATE DATA\!) +WelcomDialog_Welcom_title=Welcome to XMind 8 +WelcomDialog_WhatIsNew_title=What's new? +WelcomeToXMindHandler_welcomeToXMind_templatedName=Welcome to XMind +WizardHandler_menuLabel= + + +BetaVerifier_BetaExpiredPromptDialog_windowTitle=XMind Beta Expired +BetaVerifier_BetaExpiredPromptDialog_message_withBrandingVersion_andBuildId=XMind{0} (v{1}) Beta Edition has expired. You can check and install the latest release now, or visit www.xmind.net and download by your self. Thank you for your trial. +BetaVerifier_BetaExpiredPromptDialog_CheckAndInstallButton_text=&Check and Install +BetaVerifier_BetaExpiredPromptDialog_ExitButton_text=&Exit +BetaVerifier_BetaExpiredPromptDialog_DownloadFailure_message=Oops! An error occurred. Please try again later, or visit www.xmind.net and download the latest release manually. + + +About_Copyright=Copyright (C) 2006 - 2016, XMind Ltd. All rights reserved. +About_Homepage=http://www.xmind.net/ +About_BetaExpiryMessage_withExpiryTime=This beta edition will expire at {0}.\n + +LanguagePrefPage_ConfirmToRestart_laterButton=Restart Later +LanguagePrefPage_ConfirmToRestart2_defaultButton=Restart Now +LanguagePrefPage_ConfirmToRestart2_description=You need to restart XMind to change the language. Do you want to restart now? +LanguagePrefPage_title=Language + +DashboardHideHome_tooltip=Hide Home +DashboardShowHome_tooltip=Show Home + +DashboardBlankPage_name=Blank +DashboardTemplatesPage_name=Templates +DashboardBlankPage_message=Choose a Type +DashboardTemplatesPage_message=Choose a Template + +DashboardRecentFiles_message=Recent + +DashboardThemeChoose_message=Choose a Theme +DashboardThemeCreate_label=Create +NewFileDashboardPage_AddTemplates_tooltip=Add Template... +NewFileDashboardPage_AddTemplates_label=Add +NewFileDashboardPage_DeleteTemplate_tooltip=Delete Template +NewFileDashboardPage_DeleteTemplate_label=Delete +NewFileDashboardPage_ExitEditMode_tooltip=Exit Templates Management Mode +NewFileDashboardPage_ExitEditTemplatesMode_label=Done +NewFileDashboardPage_GoIntoTemplatesManagerMode_tooltip=Manage Templates +NewFileDashboardPage_GoToEditTemplateMode_label=Manage +NewFileDashboardPage_leftTitleBar_text=New +NewFileDashboardPage_TemplateFilterName_label=XMind Template +NewFileDashboardPage_Import_button=Import + +TemplateViewer_SystemGroup_title=Build-in +TemplateViewer_UserGroup_title=User + +RecentFileBlankPage_description=Recent files will appear as icons here. + +RecentFilesLabelProvider_Cloud_text=[Cloud] + +XStackRenderer_TopArea_tipLabel=Please open a map to continue the Operation. +XStackRenderer_BottomArea_Add_button=New Blank Map diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XDialogRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XDialogRenderer.java index 0536e8188..149a8fee9 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XDialogRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XDialogRenderer.java @@ -1,463 +1,463 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.di.UIEventTopic; -import org.eclipse.e4.ui.internal.workbench.E4Workbench; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.MElementContainer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MDialog; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.UIEvents.ElementContainer; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.IWindowCloseHandler; -import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer; -import org.eclipse.jface.util.Geometry; -import org.eclipse.jface.window.IShellProvider; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; -import org.osgi.service.event.Event; -import org.xmind.ui.internal.e4models.IModelConstants; - -public class XDialogRenderer extends SWTPartRenderer { - - private class WindowSizeUpdateJob implements Runnable { - public List windowsToUpdate = new ArrayList(); - - public void run() { - boundsJob = null; - while (!windowsToUpdate.isEmpty()) { - MWindow window = windowsToUpdate.remove(0); - Shell shell = (Shell) window.getWidget(); - if (shell == null || shell.isDisposed()) - continue; - shell.setBounds(window.getX(), window.getY(), window.getWidth(), - window.getHeight()); - } - } - } - - WindowSizeUpdateJob boundsJob; - - @Inject - private IEclipseContext context; - - @Inject - private Display display; - - @Inject - private MApplication application; - - @Inject - @Optional - @Named("localActiveShell") - private Shell parentShell; - - @SuppressWarnings("unchecked") - @Inject - @Optional - private void subscribeTopicChildAdded( - @UIEventTopic(ElementContainer.TOPIC_CHILDREN) Event event) { - Object changedObject = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(changedObject instanceof MDialog)) { - return; - } - if (UIEvents.isADD(event)) { - processContents((MElementContainer) changedObject); - postProcess((MDialog) changedObject); - } - } - - @Inject - @Optional - private void subscribeTopicWindowChanged( - @UIEventTopic(UIEvents.Window.TOPIC_ALL) Event event) { - Object objElement = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(objElement instanceof MDialog)) { - return; - } - - // Is this listener interested ? - MDialog dialogModel = (MDialog) objElement; - if (dialogModel.getRenderer() != XDialogRenderer.this) { - return; - } - - // No widget == nothing to update - Shell theShell = (Shell) dialogModel.getWidget(); - if (theShell == null) { - return; - } - - String attName = (String) event.getProperty(UIEvents.EventTags.ATTNAME); - - if (UIEvents.Window.X.equals(attName) - || UIEvents.Window.Y.equals(attName) - || UIEvents.Window.WIDTH.equals(attName) - || UIEvents.Window.HEIGHT.equals(attName)) { - if (boundsJob == null) { - boundsJob = new WindowSizeUpdateJob(); - boundsJob.windowsToUpdate.add(dialogModel); - theShell.getDisplay().asyncExec(boundsJob); - } else { - if (!boundsJob.windowsToUpdate.contains(dialogModel)) - boundsJob.windowsToUpdate.add(dialogModel); - } - } - } - - @Override - public Object createWidget(MUIElement element, Object parent) { - final Widget newWidget; - - if (!(element instanceof MDialog) - || (parent != null && !(parent instanceof Control))) - return null; - - MDialog dialogModel = (MDialog) element; - - MApplication appModel = dialogModel.getContext() - .get(MApplication.class); - Boolean rtlMode = (Boolean) appModel.getTransientData() - .get(E4Workbench.RTL_MODE); - int rtlStyle = (rtlMode != null && rtlMode.booleanValue()) - ? SWT.RIGHT_TO_LEFT : 0; - - Shell parentShell = parent == null ? null - : ((Control) parent).getShell(); - - final Shell wbwShell; - - int styleOverride = getStyleOverride(dialogModel) | rtlStyle; - if (parentShell == null) { - int style = styleOverride == -1 ? SWT.SHELL_TRIM | rtlStyle - : styleOverride; - wbwShell = new Shell(display, style); - dialogModel.getTags().add("topLevel"); //$NON-NLS-1$ - } else { - int style = SWT.TITLE | SWT.RESIZE | SWT.MAX | SWT.CLOSE | rtlStyle; - style = styleOverride == -1 ? style : styleOverride; - if (dialogModel.getTags() - .contains(IPresentationEngine.WINDOW_TOP_LEVEL)) - wbwShell = new Shell(display, style); - else - wbwShell = new Shell(parentShell, style); - } - - wbwShell.setBackgroundMode(SWT.INHERIT_DEFAULT); - - Rectangle modelBounds = wbwShell.getBounds(); - modelBounds.x = dialogModel.getX(); - modelBounds.y = dialogModel.getY(); - modelBounds.height = dialogModel.getHeight(); - modelBounds.width = dialogModel.getWidth(); - - // Force the shell onto the display if it would be invisible otherwise - Rectangle displayBounds = Display.getCurrent().getPrimaryMonitor() - .getBounds(); - if (!modelBounds.intersects(displayBounds)) { - Rectangle clientArea = Display.getCurrent().getPrimaryMonitor() - .getClientArea(); - modelBounds.x = clientArea.x; - modelBounds.y = clientArea.y; - } - wbwShell.setBounds(modelBounds); - - setCSSInfo(dialogModel, wbwShell); - - wbwShell.setLayout(new FillLayout(SWT.VERTICAL)); - newWidget = wbwShell; - bindWidget(element, newWidget); - - // set up context - IEclipseContext localContext = getContext(dialogModel); - localContext.set(Shell.class, wbwShell); - localContext.set(E4Workbench.LOCAL_ACTIVE_SHELL, wbwShell); - localContext.set(IShellProvider.class, new IShellProvider() { - public Shell getShell() { - return wbwShell; - } - }); - localContext.set(IWindowCloseHandler.class, new IWindowCloseHandler() { - public boolean close(MWindow window) { - return closeDetachedWindow(window); - } - }); - - if (dialogModel.getLabel() != null) - wbwShell.setText(dialogModel.getLocalizedLabel()); - - if (dialogModel.getIconURI() != null - && dialogModel.getIconURI().length() > 0) { - wbwShell.setImage(getImage(dialogModel)); - } else { - wbwShell.setImages(Window.getDefaultImages()); - } - - return newWidget; - } - - private boolean closeDetachedWindow(MWindow window) { - EPartService partService = window.getContext().get(EPartService.class); - List parts = modelService.findElements(window, null, MPart.class, - null); - // this saves one part at a time, not ideal but better than not saving - // at all - for (MPart part : parts) { - if (!partService.savePart(part, true)) { - // user cancelled the operation, return false - return false; - } - } - - // hide every part individually, following 3.x behaviour - for (MPart part : parts) { - partService.hidePart(part); - } - return true; - } - - @Override - public void hookControllerLogic(final MUIElement me) { - super.hookControllerLogic(me); - Widget widget = (Widget) me.getWidget(); - - if (widget instanceof Shell && me instanceof MWindow) { - final Shell shell = (Shell) widget; - shell.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - //Save user dialog bounds - String splitSymbol = ","; //$NON-NLS-1$ - Rectangle bounds = shell.getBounds(); - String location = bounds.x + splitSymbol + bounds.y - + splitSymbol + bounds.width + splitSymbol - + bounds.height; - me.getPersistedState().put( - IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, - location); - - MWindow window = (MWindow) me; - IWindowCloseHandler closeHandler = window.getContext() - .get(IWindowCloseHandler.class); - // if there's no handler or the handler permits the close - // request, clean-up as necessary - if (closeHandler == null || closeHandler.close(window)) { - Object parentModel = shell.getParent() - .getData(OWNING_ME); - if (parentModel instanceof MWindow) { - List children = ((MWindow) parentModel) - .getChildren(); - if (children.contains(window)) { - children.remove(window); - } - } else { - MWindow trimmedWindow = application.getChildren() - .get(0); - List windows = trimmedWindow.getWindows(); - if (windows.contains(window)) { - windows.remove(window); - } - } - } - } - }); - } - } - - @Override - public void processContents(MElementContainer me) { - if (!(((MUIElement) me) instanceof MDialog)) - return; - MDialog wbwModel = (MDialog) ((MUIElement) me); - super.processContents(me); - - // Populate the main menu - IPresentationEngine renderer = context.get(IPresentationEngine.class); - if (wbwModel.getMainMenu() != null) { - renderer.createGui(wbwModel.getMainMenu(), me.getWidget(), null); - Shell shell = (Shell) me.getWidget(); - shell.setMenuBar((Menu) wbwModel.getMainMenu().getWidget()); - } - - // create Detached Windows - for (MWindow dw : wbwModel.getWindows()) { - renderer.createGui(dw, me.getWidget(), wbwModel.getContext()); - } - } - - @Override - public void postProcess(MUIElement shellME) { - if (!(shellME instanceof MDialog)) - return; - MDialog dialogModel = (MDialog) shellME; - super.postProcess(shellME); - - Shell shell = (Shell) shellME.getWidget(); - String location = shellME.getPersistedState() - .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); - location = location == null ? "" : location; //$NON-NLS-1$ - String[] locations = location.split(","); //$NON-NLS-1$ - - if (locations.length < 4) { - String[] tempLocations = new String[4]; - for (int i = 0; i < locations.length; i++) - tempLocations[i] = locations[i]; - locations = tempLocations; - } - - Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - if (isNone(locations[2])) { - locations[2] = String.valueOf(size.x); - } - if (isNone(locations[3])) { - locations[3] = String.valueOf(size.y); - } - size = new Point(Integer.valueOf(locations[2]), - Integer.valueOf(locations[3])); - Point initLocation = getInitialLocation(shell, size); - Rectangle bounds = getConstrainedShellBounds(shell, - new Rectangle(initLocation.x, initLocation.y, size.x, size.y)); - if (isNone(locations[0]) && isNone(locations[1])) { - locations[0] = String.valueOf(bounds.x); - locations[1] = String.valueOf(bounds.y); - } - - dialogModel.setX(Integer.valueOf(locations[0])); - dialogModel.setY(Integer.valueOf(locations[1])); - dialogModel.setWidth(Integer.valueOf(locations[2])); - dialogModel.setHeight(Integer.valueOf(locations[3])); - - StringBuffer sb = new StringBuffer(); - sb.append(locations[0]); - sb.append(","); //$NON-NLS-1$ - sb.append(locations[1]); - sb.append(","); //$NON-NLS-1$ - sb.append(locations[2]); - sb.append(","); //$NON-NLS-1$ - sb.append(locations[3]); - - dialogModel.getPersistedState().put( - IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, sb.toString()); - - shell.layout(true); - forceLayout(shell); - if (shellME.isVisible()) { - shell.open(); - } else { - shell.setVisible(false); - } - } - - private boolean isNone(String value) { - return value == null || "".equals(value); //$NON-NLS-1$ - } - - private Point getInitialLocation(Shell shell, Point initialSize) { - Composite parent = shell.getParent(); - - Monitor monitor = shell.getDisplay().getPrimaryMonitor(); - if (parent != null) { - monitor = parent.getMonitor(); - } - - Rectangle monitorBounds = monitor.getClientArea(); - Point centerPoint; - if (parent != null) { - centerPoint = Geometry.centerPoint(parent.getBounds()); - } else { - centerPoint = Geometry.centerPoint(monitorBounds); - } - - return new Point(centerPoint.x - (initialSize.x / 2), - centerPoint.y - (initialSize.y / 2)); - } - - protected Rectangle getConstrainedShellBounds(Shell shell, - Rectangle preferredSize) { - Rectangle result = new Rectangle(preferredSize.x, preferredSize.y, - preferredSize.width, preferredSize.height); - - Monitor mon = getClosestMonitor(shell.getDisplay(), - Geometry.centerPoint(result)); - - Rectangle bounds = mon.getClientArea(); - - if (result.height > bounds.height) { - result.height = bounds.height; - } - - if (result.width > bounds.width) { - result.width = bounds.width; - } - - result.x = Math.max(bounds.x, - Math.min(result.x, bounds.x + bounds.width - result.width)); - result.y = Math.max(bounds.y, - Math.min(result.y, bounds.y + bounds.height - result.height)); - - return result; - } - - private static Monitor getClosestMonitor(Display toSearch, Point toFind) { - int closest = Integer.MAX_VALUE; - - Monitor[] monitors = toSearch.getMonitors(); - Monitor result = monitors[0]; - - for (int idx = 0; idx < monitors.length; idx++) { - Monitor current = monitors[idx]; - - Rectangle clientArea = current.getClientArea(); - - if (clientArea.contains(toFind)) { - return current; - } - - int distance = Geometry - .distanceSquared(Geometry.centerPoint(clientArea), toFind); - if (distance < closest) { - closest = distance; - result = current; - } - } - - return result; - } - - private void forceLayout(Shell shell) { - int i = 0; - while (shell.isLayoutDeferred()) { - shell.setLayoutDeferred(false); - i++; - } - while (i > 0) { - shell.setLayoutDeferred(true); - i--; - } - } - -} +package org.xmind.cathy.internal.renderer; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.internal.workbench.E4Workbench; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MElementContainer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MDialog; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.UIEvents.ElementContainer; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.modeling.IWindowCloseHandler; +import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer; +import org.eclipse.jface.util.Geometry; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Monitor; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; +import org.osgi.service.event.Event; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class XDialogRenderer extends SWTPartRenderer { + + private class WindowSizeUpdateJob implements Runnable { + public List windowsToUpdate = new ArrayList(); + + public void run() { + boundsJob = null; + while (!windowsToUpdate.isEmpty()) { + MWindow window = windowsToUpdate.remove(0); + Shell shell = (Shell) window.getWidget(); + if (shell == null || shell.isDisposed()) + continue; + shell.setBounds(window.getX(), window.getY(), window.getWidth(), + window.getHeight()); + } + } + } + + WindowSizeUpdateJob boundsJob; + + @Inject + private IEclipseContext context; + + @Inject + private Display display; + + @Inject + private MApplication application; + + @Inject + @Optional + @Named("localActiveShell") + private Shell parentShell; + + @SuppressWarnings("unchecked") + @Inject + @Optional + private void subscribeTopicChildAdded( + @UIEventTopic(ElementContainer.TOPIC_CHILDREN) Event event) { + Object changedObject = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(changedObject instanceof MDialog)) { + return; + } + if (UIEvents.isADD(event)) { + processContents((MElementContainer) changedObject); + postProcess((MDialog) changedObject); + } + } + + @Inject + @Optional + private void subscribeTopicWindowChanged( + @UIEventTopic(UIEvents.Window.TOPIC_ALL) Event event) { + Object objElement = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(objElement instanceof MDialog)) { + return; + } + + // Is this listener interested ? + MDialog dialogModel = (MDialog) objElement; + if (dialogModel.getRenderer() != XDialogRenderer.this) { + return; + } + + // No widget == nothing to update + Shell theShell = (Shell) dialogModel.getWidget(); + if (theShell == null) { + return; + } + + String attName = (String) event.getProperty(UIEvents.EventTags.ATTNAME); + + if (UIEvents.Window.X.equals(attName) + || UIEvents.Window.Y.equals(attName) + || UIEvents.Window.WIDTH.equals(attName) + || UIEvents.Window.HEIGHT.equals(attName)) { + if (boundsJob == null) { + boundsJob = new WindowSizeUpdateJob(); + boundsJob.windowsToUpdate.add(dialogModel); + theShell.getDisplay().asyncExec(boundsJob); + } else { + if (!boundsJob.windowsToUpdate.contains(dialogModel)) + boundsJob.windowsToUpdate.add(dialogModel); + } + } + } + + @Override + public Object createWidget(MUIElement element, Object parent) { + final Widget newWidget; + + if (!(element instanceof MDialog) + || (parent != null && !(parent instanceof Control))) + return null; + + MDialog dialogModel = (MDialog) element; + + MApplication appModel = dialogModel.getContext() + .get(MApplication.class); + Boolean rtlMode = (Boolean) appModel.getTransientData() + .get(E4Workbench.RTL_MODE); + int rtlStyle = (rtlMode != null && rtlMode.booleanValue()) + ? SWT.RIGHT_TO_LEFT : 0; + + Shell parentShell = parent == null ? null + : ((Control) parent).getShell(); + + final Shell wbwShell; + + int styleOverride = getStyleOverride(dialogModel) | rtlStyle; + if (parentShell == null) { + int style = styleOverride == -1 ? SWT.SHELL_TRIM | rtlStyle + : styleOverride; + wbwShell = new Shell(display, style); + dialogModel.getTags().add("topLevel"); //$NON-NLS-1$ + } else { + int style = SWT.TITLE | SWT.RESIZE | SWT.MAX | SWT.CLOSE | rtlStyle; + style = styleOverride == -1 ? style : styleOverride; + if (dialogModel.getTags() + .contains(IPresentationEngine.WINDOW_TOP_LEVEL)) + wbwShell = new Shell(display, style); + else + wbwShell = new Shell(parentShell, style); + } + + wbwShell.setBackgroundMode(SWT.INHERIT_DEFAULT); + + Rectangle modelBounds = wbwShell.getBounds(); + modelBounds.x = dialogModel.getX(); + modelBounds.y = dialogModel.getY(); + modelBounds.height = dialogModel.getHeight(); + modelBounds.width = dialogModel.getWidth(); + + // Force the shell onto the display if it would be invisible otherwise + Rectangle displayBounds = Display.getCurrent().getPrimaryMonitor() + .getBounds(); + if (!modelBounds.intersects(displayBounds)) { + Rectangle clientArea = Display.getCurrent().getPrimaryMonitor() + .getClientArea(); + modelBounds.x = clientArea.x; + modelBounds.y = clientArea.y; + } + wbwShell.setBounds(modelBounds); + + setCSSInfo(dialogModel, wbwShell); + + wbwShell.setLayout(new FillLayout(SWT.VERTICAL)); + newWidget = wbwShell; + bindWidget(element, newWidget); + + // set up context + IEclipseContext localContext = getContext(dialogModel); + localContext.set(Shell.class, wbwShell); + localContext.set(E4Workbench.LOCAL_ACTIVE_SHELL, wbwShell); + localContext.set(IShellProvider.class, new IShellProvider() { + public Shell getShell() { + return wbwShell; + } + }); + localContext.set(IWindowCloseHandler.class, new IWindowCloseHandler() { + public boolean close(MWindow window) { + return closeDetachedWindow(window); + } + }); + + if (dialogModel.getLabel() != null) + wbwShell.setText(dialogModel.getLocalizedLabel()); + + if (dialogModel.getIconURI() != null + && dialogModel.getIconURI().length() > 0) { + wbwShell.setImage(getImage(dialogModel)); + } else { + wbwShell.setImages(Window.getDefaultImages()); + } + + return newWidget; + } + + private boolean closeDetachedWindow(MWindow window) { + EPartService partService = window.getContext().get(EPartService.class); + List parts = modelService.findElements(window, null, MPart.class, + null); + // this saves one part at a time, not ideal but better than not saving + // at all + for (MPart part : parts) { + if (!partService.savePart(part, true)) { + // user cancelled the operation, return false + return false; + } + } + + // hide every part individually, following 3.x behaviour + for (MPart part : parts) { + partService.hidePart(part); + } + return true; + } + + @Override + public void hookControllerLogic(final MUIElement me) { + super.hookControllerLogic(me); + Widget widget = (Widget) me.getWidget(); + + if (widget instanceof Shell && me instanceof MWindow) { + final Shell shell = (Shell) widget; + shell.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + //Save user dialog bounds + String splitSymbol = ","; //$NON-NLS-1$ + Rectangle bounds = shell.getBounds(); + String location = bounds.x + splitSymbol + bounds.y + + splitSymbol + bounds.width + splitSymbol + + bounds.height; + me.getPersistedState().put( + IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, + location); + + MWindow window = (MWindow) me; + IWindowCloseHandler closeHandler = window.getContext() + .get(IWindowCloseHandler.class); + // if there's no handler or the handler permits the close + // request, clean-up as necessary + if (closeHandler == null || closeHandler.close(window)) { + Object parentModel = shell.getParent() + .getData(OWNING_ME); + if (parentModel instanceof MWindow) { + List children = ((MWindow) parentModel) + .getChildren(); + if (children.contains(window)) { + children.remove(window); + } + } else { + MWindow trimmedWindow = application.getChildren() + .get(0); + List windows = trimmedWindow.getWindows(); + if (windows.contains(window)) { + windows.remove(window); + } + } + } + } + }); + } + } + + @Override + public void processContents(MElementContainer me) { + if (!(((MUIElement) me) instanceof MDialog)) + return; + MDialog wbwModel = (MDialog) ((MUIElement) me); + super.processContents(me); + + // Populate the main menu + IPresentationEngine renderer = context.get(IPresentationEngine.class); + if (wbwModel.getMainMenu() != null) { + renderer.createGui(wbwModel.getMainMenu(), me.getWidget(), null); + Shell shell = (Shell) me.getWidget(); + shell.setMenuBar((Menu) wbwModel.getMainMenu().getWidget()); + } + + // create Detached Windows + for (MWindow dw : wbwModel.getWindows()) { + renderer.createGui(dw, me.getWidget(), wbwModel.getContext()); + } + } + + @Override + public void postProcess(MUIElement shellME) { + if (!(shellME instanceof MDialog)) + return; + MDialog dialogModel = (MDialog) shellME; + super.postProcess(shellME); + + Shell shell = (Shell) shellME.getWidget(); + String location = shellME.getPersistedState() + .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); + location = location == null ? "" : location; //$NON-NLS-1$ + String[] locations = location.split(","); //$NON-NLS-1$ + + if (locations.length < 4) { + String[] tempLocations = new String[4]; + for (int i = 0; i < locations.length; i++) + tempLocations[i] = locations[i]; + locations = tempLocations; + } + + Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + if (isNone(locations[2])) { + locations[2] = String.valueOf(size.x); + } + if (isNone(locations[3])) { + locations[3] = String.valueOf(size.y); + } + size = new Point(Integer.valueOf(locations[2]), + Integer.valueOf(locations[3])); + Point initLocation = getInitialLocation(shell, size); + Rectangle bounds = getConstrainedShellBounds(shell, + new Rectangle(initLocation.x, initLocation.y, size.x, size.y)); + if (isNone(locations[0]) && isNone(locations[1])) { + locations[0] = String.valueOf(bounds.x); + locations[1] = String.valueOf(bounds.y); + } + + dialogModel.setX(Integer.valueOf(locations[0])); + dialogModel.setY(Integer.valueOf(locations[1])); + dialogModel.setWidth(Integer.valueOf(locations[2])); + dialogModel.setHeight(Integer.valueOf(locations[3])); + + StringBuffer sb = new StringBuffer(); + sb.append(locations[0]); + sb.append(","); //$NON-NLS-1$ + sb.append(locations[1]); + sb.append(","); //$NON-NLS-1$ + sb.append(locations[2]); + sb.append(","); //$NON-NLS-1$ + sb.append(locations[3]); + + dialogModel.getPersistedState().put( + IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, sb.toString()); + + shell.layout(true); + forceLayout(shell); + if (shellME.isVisible()) { + shell.open(); + } else { + shell.setVisible(false); + } + } + + private boolean isNone(String value) { + return value == null || "".equals(value); //$NON-NLS-1$ + } + + private Point getInitialLocation(Shell shell, Point initialSize) { + Composite parent = shell.getParent(); + + Monitor monitor = shell.getDisplay().getPrimaryMonitor(); + if (parent != null) { + monitor = parent.getMonitor(); + } + + Rectangle monitorBounds = monitor.getClientArea(); + Point centerPoint; + if (parent != null) { + centerPoint = Geometry.centerPoint(parent.getBounds()); + } else { + centerPoint = Geometry.centerPoint(monitorBounds); + } + + return new Point(centerPoint.x - (initialSize.x / 2), + centerPoint.y - (initialSize.y / 2)); + } + + protected Rectangle getConstrainedShellBounds(Shell shell, + Rectangle preferredSize) { + Rectangle result = new Rectangle(preferredSize.x, preferredSize.y, + preferredSize.width, preferredSize.height); + + Monitor mon = getClosestMonitor(shell.getDisplay(), + Geometry.centerPoint(result)); + + Rectangle bounds = mon.getClientArea(); + + if (result.height > bounds.height) { + result.height = bounds.height; + } + + if (result.width > bounds.width) { + result.width = bounds.width; + } + + result.x = Math.max(bounds.x, + Math.min(result.x, bounds.x + bounds.width - result.width)); + result.y = Math.max(bounds.y, + Math.min(result.y, bounds.y + bounds.height - result.height)); + + return result; + } + + private static Monitor getClosestMonitor(Display toSearch, Point toFind) { + int closest = Integer.MAX_VALUE; + + Monitor[] monitors = toSearch.getMonitors(); + Monitor result = monitors[0]; + + for (int idx = 0; idx < monitors.length; idx++) { + Monitor current = monitors[idx]; + + Rectangle clientArea = current.getClientArea(); + + if (clientArea.contains(toFind)) { + return current; + } + + int distance = Geometry + .distanceSquared(Geometry.centerPoint(clientArea), toFind); + if (distance < closest) { + closest = distance; + result = current; + } + } + + return result; + } + + private void forceLayout(Shell shell) { + int i = 0; + while (shell.isLayoutDeferred()) { + shell.setLayoutDeferred(false); + i++; + } + while (i > 0) { + shell.setLayoutDeferred(true); + i--; + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XEditorStackRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XEditorStackRenderer.java new file mode 100644 index 000000000..896401e2d --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XEditorStackRenderer.java @@ -0,0 +1,131 @@ +package org.xmind.cathy.internal.renderer; + +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.PlatformUI; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.WorkbenchMessages; +import org.xmind.ui.internal.utils.CommandUtils; +import org.xmind.ui.resources.ColorUtils; + +public class XEditorStackRenderer extends StackRenderer { + + private ResourceManager resources; + + private Composite nullContent; + + @Override + public Object createWidget(MUIElement element, Object parent) { + final CTabFolder ctf = (CTabFolder) super.createWidget(element, parent); + resources = new LocalResourceManager(JFaceResources.getResources(), + ctf); + nullContent = createNullContentTipArea(ctf); + nullContent.moveBelow(null); + + ctf.addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + nullContent.moveBelow(null); + + /// Set focus with no edit content, let the dashboard lose focus (Shift + Command + C key binding ) + if (ctf.getItemCount() == 0) + ctf.setFocus(); + } + }); + + ctf.addControlListener(new ControlListener() { + + @Override + public void controlResized(ControlEvent e) { + nullContent.setBounds(ctf.getClientArea()); + } + + @Override + public void controlMoved(ControlEvent e) { + nullContent.setBounds(ctf.getClientArea()); + } + }); + + return ctf; + } + + private Composite createNullContentTipArea(CTabFolder parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + GridLayout layout = new GridLayout(1, false); + composite.setLayout(layout); + + Composite centerArea = new Composite(composite, SWT.NONE); + centerArea.setBackground(composite.getBackground()); + centerArea.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, true)); + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.verticalSpacing = 40; + centerArea.setLayout(layout2); + + createTopArea(centerArea); + createBottomArea(centerArea); + + return composite; + } + + private void createTopArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 20; + composite.setLayout(layout); + + Label imageLabel = new Label(composite, SWT.NONE); + imageLabel.setBackground(composite.getBackground()); + imageLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, false)); + imageLabel.setImage((Image) resources.get( + CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, + "icons/views/null_editor_tip.png"))); //$NON-NLS-1$ + + } + + private void createBottomArea(Composite parent) { + Button button = new Button(parent, SWT.PUSH); + button.setText(WorkbenchMessages.XStackRenderer_BottomArea_Add_button); + GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, false, + false); + layoutData.widthHint = Math.max(128, + button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 10); + button.setLayoutData(layoutData); + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + CommandUtils.executeCommand("org.xmind.ui.command.newWorkbook", //$NON-NLS-1$ + PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } + }); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XMenuManagerRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XMenuManagerRenderer.java index 8a6712a3e..48232a507 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XMenuManagerRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XMenuManagerRenderer.java @@ -1,65 +1,65 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.inject.Inject; - -import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.menu.MMenu; -import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution; -import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement; -import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer; - -public class XMenuManagerRenderer extends MenuManagerRenderer { - - private static final String[] retainedIconMenus = { - "org.xmind.ui.toolbar.mindmap.topic.menu", //$NON-NLS-1$ - "org.xmind.ui.toolbar.export.export.menu", //$NON-NLS-1$ - "org.xmind.ui.toolbar.mindmap.insert.menu" //$NON-NLS-1$ - }; - - @Inject - private MApplication application; - - @Override - public void processContributions(MMenu menuModel, String elementId, - boolean isMenuBar, boolean isPopup) { - if (elementId == null) { - return; - } - - List elements = menuModel.getChildren(); - for (MMenuElement menuItem : elements) { - if (menuItem instanceof MMenuElement) { - if (!checkRetainedIconMenu(menuModel)) { - ((MMenuElement) menuItem).setIconURI(null); - } - menuItem.setTooltip(""); //$NON-NLS-1$ - } - } - - final ArrayList toContribute = new ArrayList(); - ContributionsAnalyzer.XXXgatherMenuContributions(menuModel, - application.getMenuContributions(), elementId, toContribute, - null, isPopup); - for (MMenuContribution contri : toContribute) { - List children = contri.getChildren(); - for (MMenuElement me : children) { - if (!checkRetainedIconMenu(menuModel)) { - ((MMenuElement) me).setIconURI(null); - } - me.setTooltip(""); //$NON-NLS-1$ - } - } - super.processContributions(menuModel, elementId, isMenuBar, isPopup); - } - - private boolean checkRetainedIconMenu(MMenu menuModel) { - return Arrays.asList(retainedIconMenus) - .contains(menuModel.getElementId()); - } - -} +package org.xmind.cathy.internal.renderer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; + +import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.menu.MMenu; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement; +import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer; + +public class XMenuManagerRenderer extends MenuManagerRenderer { + + private static final String[] retainedIconMenus = { + "org.xmind.ui.toolbar.mindmap.topic.menu", //$NON-NLS-1$ + "org.xmind.ui.toolbar.export.export.menu", //$NON-NLS-1$ + "org.xmind.ui.toolbar.mindmap.insert.menu" //$NON-NLS-1$ + }; + + @Inject + private MApplication application; + + @Override + public void processContributions(MMenu menuModel, String elementId, + boolean isMenuBar, boolean isPopup) { + if (elementId == null) { + return; + } + + List elements = menuModel.getChildren(); + for (MMenuElement menuItem : elements) { + if (menuItem instanceof MMenuElement) { + if (!checkRetainedIconMenu(menuModel)) { + ((MMenuElement) menuItem).setIconURI(null); + } + menuItem.setTooltip(""); //$NON-NLS-1$ + } + } + + final ArrayList toContribute = new ArrayList(); + ContributionsAnalyzer.XXXgatherMenuContributions(menuModel, + application.getMenuContributions(), elementId, toContribute, + null, isPopup); + for (MMenuContribution contri : toContribute) { + List children = contri.getChildren(); + for (MMenuElement me : children) { + if (!checkRetainedIconMenu(menuModel)) { + ((MMenuElement) me).setIconURI(null); + } + me.setTooltip(""); //$NON-NLS-1$ + } + } + super.processContributions(menuModel, elementId, isMenuBar, isPopup); + } + + private boolean checkRetainedIconMenu(MMenu menuModel) { + return Arrays.asList(retainedIconMenus) + .contains(menuModel.getElementId()); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightStackRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightStackRenderer.java deleted file mode 100644 index a3606e2e0..000000000 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightStackRenderer.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.xmind.cathy.internal.renderer; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.eclipse.e4.core.services.events.IEventBroker; -import org.eclipse.e4.ui.model.application.ui.MElementContainer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -public class XRightStackRenderer extends LazyStackRenderer { - - @Inject - private IPresentationEngine renderer; - - @Inject - private IEventBroker eventBroker; - - @Override - public Object createWidget(MUIElement element, Object parent) { - if (!(element instanceof MPartStack) || !(parent instanceof Composite)) - return null; - - MPartStack viewStack = (MPartStack) element; - - Composite parentComposite = (Composite) parent; - Composite viewContainer = null; - - // Ensure that all rendered PartStacks have an Id - if (element.getElementId() == null - || element.getElementId().length() == 0) { - String generatedId = "RightStack@" //$NON-NLS-1$ - + Integer.toHexString(element.hashCode()); - element.setElementId(generatedId); - } - - int styleOverride = getStyleOverride(viewStack); - int style = styleOverride == -1 ? SWT.NONE : styleOverride; - //TODO Should use custom composite? - viewContainer = new Composite(parentComposite, style); - viewContainer.setLayout(new StackLayout()); - - bindWidget(element, viewContainer); - - return viewContainer; - } - - @Override - protected void showTab(MUIElement element) { - super.showTab(element); - - if (element instanceof MPartStack - && element.getRenderer() == XRightStackRenderer.this) { - MPartStack stackModel = (MPartStack) element; - MUIElement curSel = stackModel.getSelectedElement(); - MPart part = (MPart) ((curSel instanceof MPlaceholder) - ? ((MPlaceholder) curSel).getRef() : curSel); - if (curSel instanceof MPlaceholder) { - part.setCurSharedRef((MPlaceholder) curSel); - } - } - - // an invisible element won't have the correct widget hierarchy - if (!element.isVisible()) { - return; - } - - final Composite viewContainer = (Composite) getParentWidget(element); - Control ctrl = (Control) element.getWidget(); - if (ctrl != null && ctrl.getParent() != viewContainer) { - ctrl.setParent(viewContainer); - } else if (ctrl == null) { - renderer.createGui(element); - } - - ctrl = (Control) element.getWidget(); - - if (ctrl instanceof Composite) { - ((Composite) ctrl).layout(false, true); - } - ((StackLayout) viewContainer.getLayout()).topControl = ctrl; - viewContainer.layout(true, true); - - } - - @Override - public void childRendered(final MElementContainer parentElement, - MUIElement element) { - super.childRendered(parentElement, element); - - if (!(((MUIElement) parentElement) instanceof MPartStack) - || !(element instanceof MStackElement)) - return; - showTab(element); - } - - @PostConstruct - public void init() { - super.init(eventBroker); - } - - @PreDestroy - public void contextDisposed() { - super.contextDisposed(eventBroker); - } -} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightTrimBarLayout.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightTrimBarLayout.java index bf400bf0f..aeadd6103 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightTrimBarLayout.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightTrimBarLayout.java @@ -1,127 +1,127 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; -import org.xmind.cathy.internal.ICathyConstants; - -public class XRightTrimBarLayout extends Layout { - - private static final int MARGIN_LEFT = -2; - private static final int MARGIN_RIGHT = -2; - private static final int MARGIN_TOP = 20; - private static final int MARGIN_BOTTOM = 0; - - @Override - protected Point computeSize(Composite composite, int wHint, int hHint, - boolean flushCache) { - int width = 0; - Control[] children = composite.getChildren(); - for (Control child : children) { - Point size = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - width = Math.max(width, size.x); - } - width = width + MARGIN_LEFT + MARGIN_RIGHT; - return new Point(width, hHint); - } - - @Override - protected void layout(Composite composite, boolean flushCache) { - Rectangle bounds = composite.getBounds(); - bounds.x = MARGIN_LEFT; - bounds.y = MARGIN_TOP; - bounds.width -= (MARGIN_LEFT + MARGIN_RIGHT); - bounds.height -= (MARGIN_TOP + MARGIN_BOTTOM); - - int curX = bounds.x; - int curY = bounds.y; - - List beginingControls = new ArrayList(); - List centerControls = new ArrayList(); - List endControls = new ArrayList(); - - int centerControlsHeight = 0; - int endControlsHeight = 0; - - Control[] children = composite.getChildren(); - for (Control child : children) { - if (isBegining(child)) { - beginingControls.add(child); - } else if (isCenter(child)) { - centerControls.add(child); - centerControlsHeight += child.computeSize(SWT.DEFAULT, - SWT.DEFAULT).y; - } else if (isEnd(child)) { - endControls.add(child); - endControlsHeight += child.computeSize(SWT.DEFAULT, - SWT.DEFAULT).y; - } else { - centerControls.add(child); - centerControlsHeight += child.computeSize(SWT.DEFAULT, - SWT.DEFAULT).y; - } - } - - for (Control bc : beginingControls) { - Point size = bc.computeSize(SWT.DEFAULT, SWT.DEFAULT); - bc.setBounds(curX, curY, size.x, size.y); - curY += size.y; - } - - curY = Math.max(curY, (bounds.height - centerControlsHeight) / 2); - - for (Control cc : centerControls) { - Point size = cc.computeSize(SWT.DEFAULT, SWT.DEFAULT); - cc.setBounds(curX, curY, size.x, size.y); - curY += size.y; - } - - curY = Math.max(curY, bounds.y + bounds.height - endControlsHeight); - - for (Control ec : endControls) { - Point size = ec.computeSize(SWT.DEFAULT, SWT.DEFAULT); - ec.setBounds(curX, curY, size.x, size.y); - curY += size.y; - } - - } - - private boolean isBegining(Control ctrl) { - MUIElement element = (MUIElement) ctrl - .getData(AbstractPartRenderer.OWNING_ME); - if (element != null && element.getTags() - .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_BEGINING)) - return true; - - return false; - } - - private boolean isCenter(Control ctrl) { - MUIElement element = (MUIElement) ctrl - .getData(AbstractPartRenderer.OWNING_ME); - if (element != null && element.getTags() - .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_CENTER)) - return true; - - return false; - } - - private boolean isEnd(Control ctrl) { - MUIElement element = (MUIElement) ctrl - .getData(AbstractPartRenderer.OWNING_ME); - if (element != null && element.getTags() - .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_END)) - return true; - - return false; - } - -} +package org.xmind.cathy.internal.renderer; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.xmind.cathy.internal.ICathyConstants; + +public class XRightTrimBarLayout extends Layout { + + private static final int MARGIN_LEFT = -2; + private static final int MARGIN_RIGHT = -2; + private static final int MARGIN_TOP = 20; + private static final int MARGIN_BOTTOM = 0; + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, + boolean flushCache) { + int width = 0; + Control[] children = composite.getChildren(); + for (Control child : children) { + Point size = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + width = Math.max(width, size.x); + } + width = width + MARGIN_LEFT + MARGIN_RIGHT; + return new Point(width, hHint); + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + Rectangle bounds = composite.getBounds(); + bounds.x = MARGIN_LEFT; + bounds.y = MARGIN_TOP; + bounds.width -= (MARGIN_LEFT + MARGIN_RIGHT); + bounds.height -= (MARGIN_TOP + MARGIN_BOTTOM); + + int curX = bounds.x; + int curY = bounds.y; + + List beginingControls = new ArrayList(); + List centerControls = new ArrayList(); + List endControls = new ArrayList(); + + int centerControlsHeight = 0; + int endControlsHeight = 0; + + Control[] children = composite.getChildren(); + for (Control child : children) { + if (isBegining(child)) { + beginingControls.add(child); + } else if (isCenter(child)) { + centerControls.add(child); + centerControlsHeight += child.computeSize(SWT.DEFAULT, + SWT.DEFAULT).y; + } else if (isEnd(child)) { + endControls.add(child); + endControlsHeight += child.computeSize(SWT.DEFAULT, + SWT.DEFAULT).y; + } else { + centerControls.add(child); + centerControlsHeight += child.computeSize(SWT.DEFAULT, + SWT.DEFAULT).y; + } + } + + for (Control bc : beginingControls) { + Point size = bc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + bc.setBounds(curX, curY, size.x, size.y); + curY += size.y; + } + + curY = Math.max(curY, (bounds.height - centerControlsHeight) / 2); + + for (Control cc : centerControls) { + Point size = cc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + cc.setBounds(curX, curY, size.x, size.y); + curY += size.y; + } + + curY = Math.max(curY, bounds.y + bounds.height - endControlsHeight); + + for (Control ec : endControls) { + Point size = ec.computeSize(SWT.DEFAULT, SWT.DEFAULT); + ec.setBounds(curX, curY, size.x, size.y); + curY += size.y; + } + + } + + private boolean isBegining(Control ctrl) { + MUIElement element = (MUIElement) ctrl + .getData(AbstractPartRenderer.OWNING_ME); + if (element != null && element.getTags() + .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_BEGINING)) + return true; + + return false; + } + + private boolean isCenter(Control ctrl) { + MUIElement element = (MUIElement) ctrl + .getData(AbstractPartRenderer.OWNING_ME); + if (element != null && element.getTags() + .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_CENTER)) + return true; + + return false; + } + + private boolean isEnd(Control ctrl) { + MUIElement element = (MUIElement) ctrl + .getData(AbstractPartRenderer.OWNING_ME); + if (element != null && element.getTags() + .contains(ICathyConstants.TAG_TRIMBAR_LAYOUT_END)) + return true; + + return false; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashLayout.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashLayout.java index 4d9e8027d..71283ceb1 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashLayout.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashLayout.java @@ -1,191 +1,191 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.e4.ui.model.application.ui.MGenericTile; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Shell; - -public class XSashLayout extends Layout { - - int suggestedSizeForViewStack = 310; - int suggestedDownDistanceForViewStack = 22; - - int marginLeft = 0; - int marginRight = 0; - int marginTop = 0; - int marginBottom = 0; - int sashWidth = 0; - - MUIElement root; - - class SashRect { - Rectangle rect; - MGenericTile container; - MUIElement left; - MUIElement right; - - public SashRect(Rectangle rect, MGenericTile container, - MUIElement left, MUIElement right) { - this.container = container; - this.rect = rect; - this.left = left; - this.right = right; - } - } - - public XSashLayout(MUIElement root) { - this.root = root; - } - - @Override - protected void layout(Composite composite, boolean flushCache) { - if (root == null) - return; - - Rectangle bounds = composite.getBounds(); - if (composite instanceof Shell) - bounds = ((Shell) composite).getClientArea(); - else { - bounds.x = 0; - bounds.y = 0; - } - - bounds.width -= (marginLeft + marginRight); - bounds.height -= (marginTop + marginBottom); - bounds.x += marginLeft; - bounds.y += marginTop; - - tileSubNodes(bounds, root); - } - - @Override - protected Point computeSize(Composite composite, int wHint, int hHint, - boolean flushCache) { - return new Point(600, 400); - } - - private int totalScalableSectionWeight(MGenericTile node) { - int total = 0; - for (MUIElement subNode : node.getChildren()) { - if (subNode.isToBeRendered() && subNode.isVisible()) { - Object renderer = subNode.getRenderer(); - if (renderer != null - && renderer.getClass() != XRightStackRenderer.class) { - total += getWeight(subNode); - } - } - } - return total; - } - - private void tileSubNodes(Rectangle bounds, MUIElement node) { - if (node != root) - setRectangle(node, bounds); - - if (!(node instanceof MGenericTile)) - return; - - MGenericTile sashContainer = (MGenericTile) node; - List visibleChildren = getVisibleChildren(sashContainer); - int childCount = visibleChildren.size(); - - // How many pixels do we have? - int availableWidth = sashContainer.isHorizontal() ? bounds.width - : bounds.height; - - // Subtract off the room for the sashes - availableWidth -= ((childCount - 1) * sashWidth); - - int availableScalableSectionWidth = availableWidth; - - // Get the total of the weights - double totalScalableSectionWeight = totalScalableSectionWeight( - sashContainer); - for (MUIElement subNode : visibleChildren) { - Object renderer = subNode.getRenderer(); - if (renderer != null - && renderer.getClass() == XRightStackRenderer.class) { - availableScalableSectionWidth -= suggestedSizeForViewStack; - } - } - int tilePos = sashContainer.isHorizontal() ? bounds.x : bounds.y; - - MUIElement prev = null; - for (MUIElement subNode : visibleChildren) { - // Add a 'sash' between this node and the 'prev' - if (prev != null) { - tilePos += sashWidth; - } - - // Calc the new size as a %'age of the total - int weight = getWeight(subNode); - double ratio = weight / totalScalableSectionWeight; - int newSize = (int) ((availableScalableSectionWidth * ratio) + 0.5); - Object renderer = subNode.getRenderer(); - - int y = bounds.y; - int height = bounds.height; - if (renderer != null - && renderer.getClass() == XRightStackRenderer.class) { - newSize = suggestedSizeForViewStack; - y = y + suggestedDownDistanceForViewStack; - height = height - suggestedDownDistanceForViewStack - 1; - } - - Rectangle subBounds = sashContainer.isHorizontal() - ? new Rectangle(tilePos, y, newSize, height) - : new Rectangle(bounds.x, tilePos, bounds.width, newSize); - tilePos += newSize; - - tileSubNodes(subBounds, subNode); - prev = subNode; - } - } - - /** - * @param node - * @param bounds - */ - private void setRectangle(MUIElement node, Rectangle bounds) { - if (node.getWidget() instanceof Control) { - Control ctrl = (Control) node.getWidget(); - ctrl.setBounds(bounds); - } else if (node.getWidget() instanceof Rectangle) { - Rectangle theRect = (Rectangle) node.getWidget(); - theRect.x = bounds.x; - theRect.y = bounds.y; - theRect.width = bounds.width; - theRect.height = bounds.height; - } - } - - private List getVisibleChildren(MGenericTile sashContainer) { - List visKids = new ArrayList(); - for (MUIElement child : sashContainer.getChildren()) { - if (child.isToBeRendered() && child.isVisible()) - visKids.add(child); - } - return visKids; - } - - private static int getWeight(MUIElement element) { - String info = element.getContainerData(); - if (info == null || info.length() == 0) { - return 0; - } - - try { - int value = Integer.parseInt(info); - return value; - } catch (NumberFormatException e) { - return 0; - } - } -} +package org.xmind.cathy.internal.renderer; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.e4.ui.model.application.ui.MGenericTile; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; + +public class XSashLayout extends Layout { + + int suggestedSizeForViewStack = 310; + int suggestedDownDistanceForViewStack = 22; + + int marginLeft = 0; + int marginRight = 0; + int marginTop = 0; + int marginBottom = 0; + int sashWidth = 0; + + MUIElement root; + + class SashRect { + Rectangle rect; + MGenericTile container; + MUIElement left; + MUIElement right; + + public SashRect(Rectangle rect, MGenericTile container, + MUIElement left, MUIElement right) { + this.container = container; + this.rect = rect; + this.left = left; + this.right = right; + } + } + + public XSashLayout(MUIElement root) { + this.root = root; + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + if (root == null) + return; + + Rectangle bounds = composite.getBounds(); + if (composite instanceof Shell) + bounds = ((Shell) composite).getClientArea(); + else { + bounds.x = 0; + bounds.y = 0; + } + + bounds.width -= (marginLeft + marginRight); + bounds.height -= (marginTop + marginBottom); + bounds.x += marginLeft; + bounds.y += marginTop; + + tileSubNodes(bounds, root); + } + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, + boolean flushCache) { + return new Point(600, 400); + } + + private int totalScalableSectionWeight(MGenericTile node) { + int total = 0; + for (MUIElement subNode : node.getChildren()) { + if (subNode.isToBeRendered() && subNode.isVisible()) { + Object renderer = subNode.getRenderer(); + if (renderer != null + && renderer.getClass() != XStackRenderer.class) { + total += getWeight(subNode); + } + } + } + return total; + } + + private void tileSubNodes(Rectangle bounds, MUIElement node) { + if (node != root) + setRectangle(node, bounds); + + if (!(node instanceof MGenericTile)) + return; + + MGenericTile sashContainer = (MGenericTile) node; + List visibleChildren = getVisibleChildren(sashContainer); + int childCount = visibleChildren.size(); + + // How many pixels do we have? + int availableWidth = sashContainer.isHorizontal() ? bounds.width + : bounds.height; + + // Subtract off the room for the sashes + availableWidth -= ((childCount - 1) * sashWidth); + + int availableScalableSectionWidth = availableWidth; + + // Get the total of the weights + double totalScalableSectionWeight = totalScalableSectionWeight( + sashContainer); + for (MUIElement subNode : visibleChildren) { + Object renderer = subNode.getRenderer(); + if (renderer != null + && renderer.getClass() == XStackRenderer.class) { + availableScalableSectionWidth -= suggestedSizeForViewStack; + } + } + int tilePos = sashContainer.isHorizontal() ? bounds.x : bounds.y; + + MUIElement prev = null; + for (MUIElement subNode : visibleChildren) { + // Add a 'sash' between this node and the 'prev' + if (prev != null) { + tilePos += sashWidth; + } + + // Calc the new size as a %'age of the total + int weight = getWeight(subNode); + double ratio = weight / totalScalableSectionWeight; + int newSize = (int) ((availableScalableSectionWidth * ratio) + 0.5); + Object renderer = subNode.getRenderer(); + + int y = bounds.y; + int height = bounds.height; + if (renderer != null + && renderer.getClass() == XStackRenderer.class) { + newSize = suggestedSizeForViewStack; + y = y + suggestedDownDistanceForViewStack; + height = height - suggestedDownDistanceForViewStack - 1; + } + + Rectangle subBounds = sashContainer.isHorizontal() + ? new Rectangle(tilePos, y, newSize, height) + : new Rectangle(bounds.x, tilePos, bounds.width, newSize); + tilePos += newSize; + + tileSubNodes(subBounds, subNode); + prev = subNode; + } + } + + /** + * @param node + * @param bounds + */ + private void setRectangle(MUIElement node, Rectangle bounds) { + if (node.getWidget() instanceof Control) { + Control ctrl = (Control) node.getWidget(); + ctrl.setBounds(bounds); + } else if (node.getWidget() instanceof Rectangle) { + Rectangle theRect = (Rectangle) node.getWidget(); + theRect.x = bounds.x; + theRect.y = bounds.y; + theRect.width = bounds.width; + theRect.height = bounds.height; + } + } + + private List getVisibleChildren(MGenericTile sashContainer) { + List visKids = new ArrayList(); + for (MUIElement child : sashContainer.getChildren()) { + if (child.isToBeRendered() && child.isVisible()) + visKids.add(child); + } + return visKids; + } + + private static int getWeight(MUIElement element) { + String info = element.getContainerData(); + if (info == null || info.length() == 0) { + return 0; + } + + try { + int value = Integer.parseInt(info); + return value; + } catch (NumberFormatException e) { + return 0; + } + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashRenderer.java index b0cac9c09..3b0055b83 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashRenderer.java @@ -1,173 +1,173 @@ -package org.xmind.cathy.internal.renderer; - -import javax.inject.Inject; - -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.di.UIEventTopic; -import org.eclipse.e4.ui.model.application.ui.MElementContainer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; -import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.osgi.service.event.Event; - -public class XSashRenderer extends SWTPartRenderer { - - private static final int UNDEFINED_WEIGHT = -1; - private static final int DEFAULT_WEIGHT = 5000; - - private int processedContent = 0; - - @SuppressWarnings("unchecked") - @Inject - @Optional - private void subscribeTopicOrientationChanged( - @UIEventTopic(UIEvents.GenericTile.TOPIC_HORIZONTAL) Event event) { - // Ensure that this event is for a MPartSashContainer - MUIElement element = (MUIElement) event - .getProperty(UIEvents.EventTags.ELEMENT); - if (element.getRenderer() != XSashRenderer.this) { - return; - } - forceLayout((MElementContainer) element); - } - - @SuppressWarnings("unchecked") - @Inject - @Optional - private void subscribeTopicSashWeightChanged( - @UIEventTopic(UIEvents.UIElement.TOPIC_CONTAINERDATA) Event event) { - // Ensure that this event is for a MPartSashContainer - MUIElement element = (MUIElement) event - .getProperty(UIEvents.EventTags.ELEMENT); - if (element.getRenderer() != XSashRenderer.this) { - return; - } - forceLayout((MElementContainer) element); - } - - /** - * @param pscModel - */ - protected void forceLayout(MElementContainer pscModel) { - if (processedContent != 0) { - return; - } - // layout the containing Composite - while (!(pscModel.getWidget() instanceof Composite)) - pscModel = pscModel.getParent(); - - Composite s = (Composite) pscModel.getWidget(); - s.layout(true, true); - } - - @Override - public Object createWidget(final MUIElement element, Object parent) { - MUIElement elementParent = element.getParent(); - if (elementParent == null && element.getCurSharedRef() != null) - elementParent = element.getCurSharedRef(); - - if (elementParent != null && elementParent.getRenderer() == this) { - Rectangle newRect = new Rectangle(0, 0, 0, 0); - - // If my layout's container gets disposed 'unbind' the sash elements - if (parent instanceof Composite) { - ((Composite) parent).addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - element.setWidget(null); - element.setRenderer(null); - } - }); - } - return newRect; - } - - // Check to see if this is a new PSC added 'above' the previous 'root' - // sash - Composite sashComposite = null; - MPartSashContainer psc = (MPartSashContainer) element; - for (MPartSashContainerElement psce : psc.getChildren()) { - if (psce instanceof MPartSashContainer - && psce.getWidget() instanceof Composite) { - // 'Adopt' the previous root's layout / composite - sashComposite = (Composite) psce.getWidget(); - bindWidget(psce, new Rectangle(0, 0, 0, 0)); - } - } - // This is a 'root' sash container, create a composite - if (sashComposite == null) - sashComposite = new Composite((Composite) parent, SWT.NONE); - sashComposite.setLayout(new XSashLayout(element)); - - return sashComposite; - } - - @Override - public void childRendered(MElementContainer parentElement, - MUIElement element) { - super.childRendered(parentElement, element); - - // Ensure that the element's 'containerInfo' is initialized - int weight = getWeight(element); - if (weight == UNDEFINED_WEIGHT) { - element.setContainerData(Integer.toString(DEFAULT_WEIGHT)); - } - forceLayout(parentElement); - } - - @Override - public void processContents(MElementContainer container) { - try { - processedContent++; - super.processContents(container); - } finally { - processedContent--; - if (processedContent == 0) { - forceLayout(container); - } - } - } - - @Override - public void hideChild(MElementContainer parentElement, - MUIElement child) { - super.hideChild(parentElement, child); - - forceLayout(parentElement); - } - - @Override - public Object getUIContainer(MUIElement element) { - // OK, find the 'root' of the sash container - MUIElement parentElement = element.getParent(); - while (parentElement.getRenderer() == this - && !(parentElement.getWidget() instanceof Composite)) - parentElement = parentElement.getParent(); - - if (parentElement.getWidget() instanceof Composite) - return parentElement.getWidget(); - - return null; - } - - private static int getWeight(MUIElement element) { - String info = element.getContainerData(); - if (info == null || info.length() == 0) { - element.setContainerData(Integer.toString(10000)); - info = element.getContainerData(); - } - - try { - int value = Integer.parseInt(info); - return value; - } catch (NumberFormatException e) { - return UNDEFINED_WEIGHT; - } - } -} +package org.xmind.cathy.internal.renderer; + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.model.application.ui.MElementContainer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.osgi.service.event.Event; + +public class XSashRenderer extends SWTPartRenderer { + + private static final int UNDEFINED_WEIGHT = -1; + private static final int DEFAULT_WEIGHT = 5000; + + private int processedContent = 0; + + @SuppressWarnings("unchecked") + @Inject + @Optional + private void subscribeTopicOrientationChanged( + @UIEventTopic(UIEvents.GenericTile.TOPIC_HORIZONTAL) Event event) { + // Ensure that this event is for a MPartSashContainer + MUIElement element = (MUIElement) event + .getProperty(UIEvents.EventTags.ELEMENT); + if (element.getRenderer() != XSashRenderer.this) { + return; + } + forceLayout((MElementContainer) element); + } + + @SuppressWarnings("unchecked") + @Inject + @Optional + private void subscribeTopicSashWeightChanged( + @UIEventTopic(UIEvents.UIElement.TOPIC_CONTAINERDATA) Event event) { + // Ensure that this event is for a MPartSashContainer + MUIElement element = (MUIElement) event + .getProperty(UIEvents.EventTags.ELEMENT); + if (element.getRenderer() != XSashRenderer.this) { + return; + } + forceLayout((MElementContainer) element); + } + + /** + * @param pscModel + */ + protected void forceLayout(MElementContainer pscModel) { + if (processedContent != 0) { + return; + } + // layout the containing Composite + while (!(pscModel.getWidget() instanceof Composite)) + pscModel = pscModel.getParent(); + + Composite s = (Composite) pscModel.getWidget(); + s.layout(true, true); + } + + @Override + public Object createWidget(final MUIElement element, Object parent) { + MUIElement elementParent = element.getParent(); + if (elementParent == null && element.getCurSharedRef() != null) + elementParent = element.getCurSharedRef(); + + if (elementParent != null && elementParent.getRenderer() == this) { + Rectangle newRect = new Rectangle(0, 0, 0, 0); + + // If my layout's container gets disposed 'unbind' the sash elements + if (parent instanceof Composite) { + ((Composite) parent).addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + element.setWidget(null); + element.setRenderer(null); + } + }); + } + return newRect; + } + + // Check to see if this is a new PSC added 'above' the previous 'root' + // sash + Composite sashComposite = null; + MPartSashContainer psc = (MPartSashContainer) element; + for (MPartSashContainerElement psce : psc.getChildren()) { + if (psce instanceof MPartSashContainer + && psce.getWidget() instanceof Composite) { + // 'Adopt' the previous root's layout / composite + sashComposite = (Composite) psce.getWidget(); + bindWidget(psce, new Rectangle(0, 0, 0, 0)); + } + } + // This is a 'root' sash container, create a composite + if (sashComposite == null) + sashComposite = new Composite((Composite) parent, SWT.NONE); + sashComposite.setLayout(new XSashLayout(element)); + + return sashComposite; + } + + @Override + public void childRendered(MElementContainer parentElement, + MUIElement element) { + super.childRendered(parentElement, element); + + // Ensure that the element's 'containerInfo' is initialized + int weight = getWeight(element); + if (weight == UNDEFINED_WEIGHT) { + element.setContainerData(Integer.toString(DEFAULT_WEIGHT)); + } + forceLayout(parentElement); + } + + @Override + public void processContents(MElementContainer container) { + try { + processedContent++; + super.processContents(container); + } finally { + processedContent--; + if (processedContent == 0) { + forceLayout(container); + } + } + } + + @Override + public void hideChild(MElementContainer parentElement, + MUIElement child) { + super.hideChild(parentElement, child); + + forceLayout(parentElement); + } + + @Override + public Object getUIContainer(MUIElement element) { + // OK, find the 'root' of the sash container + MUIElement parentElement = element.getParent(); + while (parentElement.getRenderer() == this + && !(parentElement.getWidget() instanceof Composite)) + parentElement = parentElement.getParent(); + + if (parentElement.getWidget() instanceof Composite) + return parentElement.getWidget(); + + return null; + } + + private static int getWeight(MUIElement element) { + String info = element.getContainerData(); + if (info == null || info.length() == 0) { + element.setContainerData(Integer.toString(10000)); + info = element.getContainerData(); + } + + try { + int value = Integer.parseInt(info); + return value; + } catch (NumberFormatException e) { + return UNDEFINED_WEIGHT; + } + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XStackRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XStackRenderer.java index 34db2368d..4b0821fc6 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XStackRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XStackRenderer.java @@ -1,127 +1,116 @@ -package org.xmind.cathy.internal.renderer; - -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.PlatformUI; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.ui.internal.utils.CommandUtils; -import org.xmind.ui.resources.ColorUtils; - -public class XStackRenderer extends StackRenderer { - - private ResourceManager resources; - - private Composite nullContent; - - @Override - public Object createWidget(MUIElement element, Object parent) { - final CTabFolder ctf = (CTabFolder) super.createWidget(element, parent); - resources = new LocalResourceManager(JFaceResources.getResources(), - ctf); - nullContent = createNullContentTipArea(ctf); - nullContent.moveBelow(null); - - ctf.addPaintListener(new PaintListener() { - - @Override - public void paintControl(PaintEvent e) { - nullContent.moveBelow(null); - } - }); - - ctf.addControlListener(new ControlListener() { - - @Override - public void controlResized(ControlEvent e) { - nullContent.setBounds(ctf.getClientArea()); - } - - @Override - public void controlMoved(ControlEvent e) { - nullContent.setBounds(ctf.getClientArea()); - } - }); - - return ctf; - } - - private Composite createNullContentTipArea(CTabFolder parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - GridLayout layout = new GridLayout(1, false); - composite.setLayout(layout); - - Composite centerArea = new Composite(composite, SWT.NONE); - centerArea.setBackground(composite.getBackground()); - centerArea.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, true)); - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 40; - centerArea.setLayout(layout2); - - createTopArea(centerArea); - createBottomArea(centerArea); - - return composite; - } - - private void createTopArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 20; - composite.setLayout(layout); - - Label imageLabel = new Label(composite, SWT.NONE); - imageLabel.setBackground(composite.getBackground()); - imageLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, false)); - imageLabel.setImage((Image) resources.get( - CathyPlugin.imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/views/null_editor_tip.png"))); //$NON-NLS-1$ - - } - - private void createBottomArea(Composite parent) { - Button button = new Button(parent, SWT.PUSH); - button.setText(WorkbenchMessages.XStackRenderer_BottomArea_Add_button); - GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, false, - false); - layoutData.widthHint = Math.max(128, - button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 10); - button.setLayoutData(layoutData); - button.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - CommandUtils.executeCommand("org.xmind.ui.command.newWorkbook", //$NON-NLS-1$ - PlatformUI.getWorkbench().getActiveWorkbenchWindow()); - } - }); - } - -} +package org.xmind.cathy.internal.renderer; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.model.application.ui.MElementContainer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public class XStackRenderer extends LazyStackRenderer { + + @Inject + private IPresentationEngine renderer; + + @Inject + private IEventBroker eventBroker; + + @Override + public Object createWidget(MUIElement element, Object parent) { + if (!(element instanceof MPartStack) || !(parent instanceof Composite)) + return null; + + MPartStack viewStack = (MPartStack) element; + + Composite parentComposite = (Composite) parent; + Composite viewContainer = null; + + // Ensure that all rendered PartStacks have an Id + if (element.getElementId() == null + || element.getElementId().length() == 0) { + String generatedId = "RightStack@" //$NON-NLS-1$ + + Integer.toHexString(element.hashCode()); + element.setElementId(generatedId); + } + + int styleOverride = getStyleOverride(viewStack); + int style = styleOverride == -1 ? SWT.NONE : styleOverride; + //TODO Should use custom composite? + viewContainer = new Composite(parentComposite, style); + viewContainer.setLayout(new StackLayout()); + + bindWidget(element, viewContainer); + + return viewContainer; + } + + @Override + protected void showTab(MUIElement element) { + super.showTab(element); + + if (element instanceof MPartStack + && element.getRenderer() == XStackRenderer.this) { + MPartStack stackModel = (MPartStack) element; + MUIElement curSel = stackModel.getSelectedElement(); + MPart part = (MPart) ((curSel instanceof MPlaceholder) + ? ((MPlaceholder) curSel).getRef() : curSel); + if (curSel instanceof MPlaceholder) { + part.setCurSharedRef((MPlaceholder) curSel); + } + } + + // an invisible element won't have the correct widget hierarchy + if (!element.isVisible()) { + return; + } + + final Composite viewContainer = (Composite) getParentWidget(element); + Control ctrl = (Control) element.getWidget(); + if (ctrl != null && ctrl.getParent() != viewContainer) { + ctrl.setParent(viewContainer); + } else if (ctrl == null) { + renderer.createGui(element); + } + + ctrl = (Control) element.getWidget(); + + if (ctrl instanceof Composite) { + ((Composite) ctrl).layout(false, true); + } + ((StackLayout) viewContainer.getLayout()).topControl = ctrl; + viewContainer.layout(true, true); + + } + + @Override + public void childRendered(final MElementContainer parentElement, + MUIElement element) { + super.childRendered(parentElement, element); + + if (!(((MUIElement) parentElement) instanceof MPartStack) + || !(element instanceof MStackElement)) + return; + showTab(element); + } + + @PostConstruct + public void init() { + super.init(eventBroker); + } + + @PreDestroy + public void contextDisposed() { + super.contextDisposed(eventBroker); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XToolBarManagerRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XToolBarManagerRenderer.java index 0396de0ae..8d7cd65ad 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XToolBarManagerRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XToolBarManagerRenderer.java @@ -1,130 +1,130 @@ -package org.xmind.cathy.internal.renderer; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.internal.workbench.swt.CSSRenderingUtils; -import org.eclipse.e4.ui.model.application.MApplicationElement; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.SideValue; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; -import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer; -import org.eclipse.jface.action.IContributionManagerOverrides; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.ToolBar; - -public class XToolBarManagerRenderer extends ToolBarManagerRenderer { - - public Object createWidget(final MUIElement element, Object parent) { - if (!(element instanceof MToolBar) || !(parent instanceof Composite)) - return null; - - final MToolBar toolbarModel = (MToolBar) element; - ToolBar newTB = createToolbar(toolbarModel, (Composite) parent); - bindWidget(element, newTB); - processContribution(toolbarModel, toolbarModel.getElementId()); - - Control renderedCtrl = newTB; - MUIElement parentElement = element.getParent(); - if (parentElement instanceof MTrimBar) { - //default can't be draggable -// if (!element.getTags().contains(IPresentationEngine.NO_MOVE)) { -// element.getTags().add(IPresentationEngine.DRAGGABLE); -// } - - setCSSInfo(element, newTB); - - boolean vertical = false; - MTrimBar bar = (MTrimBar) parentElement; - vertical = bar.getSide() == SideValue.LEFT - || bar.getSide() == SideValue.RIGHT; - IEclipseContext parentContext = getContextForParent(element); - CSSRenderingUtils cssUtils = parentContext - .get(CSSRenderingUtils.class); - if (cssUtils != null) { - MUIElement modelElement = (MUIElement) newTB - .getData(AbstractPartRenderer.OWNING_ME); - boolean draggable = ((modelElement != null) && (modelElement - .getTags().contains(IPresentationEngine.DRAGGABLE))); - renderedCtrl = cssUtils.frameMeIfPossible(newTB, null, vertical, - draggable); - } - } - - return renderedCtrl; - } - - @Override - public Object getUIContainer(MUIElement childElement) { - Composite intermediate = (Composite) super.getUIContainer(childElement); - if (intermediate == null || intermediate.isDisposed()) { - return null; - } - if (intermediate instanceof ToolBar) { - return intermediate; - } - ToolBar toolbar = findToolbar(intermediate); - if (toolbar == null) { - toolbar = createToolbar(childElement.getParent(), intermediate); - } - return toolbar; - } - - private ToolBar findToolbar(Composite intermediate) { - for (Control child : intermediate.getChildren()) { - if (child.getData() instanceof ToolBarManager) { - return (ToolBar) child; - } - } - return null; - } - - private ToolBar createToolbar(final MUIElement element, Composite parent) { - int orientation = getOrientationStyle(element); - int style = orientation | SWT.WRAP | SWT.FLAT | SWT.RIGHT; - ToolBarManager manager = getManager((MToolBar) element); - if (manager == null) { - manager = new ToolBarManager(style); - IContributionManagerOverrides overrides = null; - MApplicationElement parentElement = element.getParent(); - - if (parentElement != null) { - overrides = (IContributionManagerOverrides) parentElement - .getTransientData() - .get(IContributionManagerOverrides.class.getName()); - } - - manager.setOverrides(overrides); - linkModelToManager((MToolBar) element, manager); - } else { - ToolBar toolBar = manager.getControl(); - if (toolBar != null && !toolBar.isDisposed() - && (toolBar.getStyle() & orientation) == 0) { - toolBar.dispose(); - } - manager.setStyle(style); - } - ToolBar bar = manager.createControl(parent); - bar.setData(manager); - bar.setData(AbstractPartRenderer.OWNING_ME, element); - bar.getShell().layout(new Control[] { bar }, SWT.DEFER); - return bar; - } - - private int getOrientationStyle(final MUIElement element) { - MUIElement theParent = element.getParent(); - if (theParent instanceof MTrimBar) { - MTrimBar trimContainer = (MTrimBar) theParent; - SideValue side = trimContainer.getSide(); - if (side.getValue() == SideValue.LEFT_VALUE - || side.getValue() == SideValue.RIGHT_VALUE) - return SWT.VERTICAL; - } - return SWT.HORIZONTAL; - } - -} +package org.xmind.cathy.internal.renderer; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.internal.workbench.swt.CSSRenderingUtils; +import org.eclipse.e4.ui.model.application.MApplicationElement; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.SideValue; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; +import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer; +import org.eclipse.jface.action.IContributionManagerOverrides; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; + +public class XToolBarManagerRenderer extends ToolBarManagerRenderer { + + public Object createWidget(final MUIElement element, Object parent) { + if (!(element instanceof MToolBar) || !(parent instanceof Composite)) + return null; + + final MToolBar toolbarModel = (MToolBar) element; + ToolBar newTB = createToolbar(toolbarModel, (Composite) parent); + bindWidget(element, newTB); + processContribution(toolbarModel, toolbarModel.getElementId()); + + Control renderedCtrl = newTB; + MUIElement parentElement = element.getParent(); + if (parentElement instanceof MTrimBar) { + //default can't be draggable +// if (!element.getTags().contains(IPresentationEngine.NO_MOVE)) { +// element.getTags().add(IPresentationEngine.DRAGGABLE); +// } + + setCSSInfo(element, newTB); + + boolean vertical = false; + MTrimBar bar = (MTrimBar) parentElement; + vertical = bar.getSide() == SideValue.LEFT + || bar.getSide() == SideValue.RIGHT; + IEclipseContext parentContext = getContextForParent(element); + CSSRenderingUtils cssUtils = parentContext + .get(CSSRenderingUtils.class); + if (cssUtils != null) { + MUIElement modelElement = (MUIElement) newTB + .getData(AbstractPartRenderer.OWNING_ME); + boolean draggable = ((modelElement != null) && (modelElement + .getTags().contains(IPresentationEngine.DRAGGABLE))); + renderedCtrl = cssUtils.frameMeIfPossible(newTB, null, vertical, + draggable); + } + } + + return renderedCtrl; + } + + @Override + public Object getUIContainer(MUIElement childElement) { + Composite intermediate = (Composite) super.getUIContainer(childElement); + if (intermediate == null || intermediate.isDisposed()) { + return null; + } + if (intermediate instanceof ToolBar) { + return intermediate; + } + ToolBar toolbar = findToolbar(intermediate); + if (toolbar == null) { + toolbar = createToolbar(childElement.getParent(), intermediate); + } + return toolbar; + } + + private ToolBar findToolbar(Composite intermediate) { + for (Control child : intermediate.getChildren()) { + if (child.getData() instanceof ToolBarManager) { + return (ToolBar) child; + } + } + return null; + } + + private ToolBar createToolbar(final MUIElement element, Composite parent) { + int orientation = getOrientationStyle(element); + int style = orientation | SWT.WRAP | SWT.FLAT | SWT.RIGHT; + ToolBarManager manager = getManager((MToolBar) element); + if (manager == null) { + manager = new ToolBarManager(style); + IContributionManagerOverrides overrides = null; + MApplicationElement parentElement = element.getParent(); + + if (parentElement != null) { + overrides = (IContributionManagerOverrides) parentElement + .getTransientData() + .get(IContributionManagerOverrides.class.getName()); + } + + manager.setOverrides(overrides); + linkModelToManager((MToolBar) element, manager); + } else { + ToolBar toolBar = manager.getControl(); + if (toolBar != null && !toolBar.isDisposed() + && (toolBar.getStyle() & orientation) == 0) { + toolBar.dispose(); + } + manager.setStyle(style); + } + ToolBar bar = manager.createControl(parent); + bar.setData(manager); + bar.setData(AbstractPartRenderer.OWNING_ME, element); + bar.getShell().layout(new Control[] { bar }, SWT.DEFER); + return bar; + } + + private int getOrientationStyle(final MUIElement element) { + MUIElement theParent = element.getParent(); + if (theParent instanceof MTrimBar) { + MTrimBar trimContainer = (MTrimBar) theParent; + SideValue side = trimContainer.getSide(); + if (side.getValue() == SideValue.LEFT_VALUE + || side.getValue() == SideValue.RIGHT_VALUE) + return SWT.VERTICAL; + } + return SWT.HORIZONTAL; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XTrimmedPartLayout.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XTrimmedPartLayout.java index 3f51a339a..2da7da7b5 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XTrimmedPartLayout.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XTrimmedPartLayout.java @@ -1,218 +1,218 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; - -public class XTrimmedPartLayout extends TrimmedPartLayout { - - public Control headerSeparator; - public Control footerSeparator; - - public Map containers = new HashMap(); - - public XTrimmedPartLayout(Composite parent) { - super(parent); - clientArea.setVisible(false); - } - - public void createHeaderSeparator(Composite parent) { - if (headerSeparator != null) - return; - - headerSeparator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - headerSeparator.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - headerSeparator = null; - } - }); - } - - public void createFooterSeparator(Composite parent) { - if (footerSeparator != null) - return; - - footerSeparator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - footerSeparator.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - footerSeparator = null; - } - }); - } - - @Override - protected void layout(Composite composite, boolean flushCache) { - Rectangle ca = composite.getClientArea(); - Rectangle caRect = new Rectangle(ca.x, ca.y, ca.width, ca.height); - - // 'Top' spans the entire area - if (top != null && top.isVisible()) { - Point topSize = top.computeSize( - caRect.width - (Util.isMac() ? 12 : 0), SWT.DEFAULT, true); /// -12 for mac margin - caRect.y += topSize.y; - caRect.height -= topSize.y; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(ca.x, ca.y, caRect.width, - topSize.y); - if (!newBounds.equals(top.getBounds())) { - top.setBounds(newBounds); - } - } - - // 'Header Separator' spans the entire area - if (headerSeparator != null && headerSeparator.isVisible()) { - Point underTopSize = headerSeparator.computeSize(caRect.width, - SWT.DEFAULT, true); - caRect.y += underTopSize.y; - caRect.height -= underTopSize.y; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(caRect.x, - caRect.y - underTopSize.y, caRect.width, underTopSize.y); - if (!newBounds.equals(headerSeparator.getBounds())) { - headerSeparator.setBounds(newBounds); - } - } - - // Include the gutter whether there is a top area or not. - caRect.y += gutterTop; - caRect.height -= gutterTop; - - // 'Bottom' spans the entire area - if (bottom != null && bottom.isVisible()) { - Point bottomSize = bottom.computeSize(caRect.width, SWT.DEFAULT, - true); - caRect.height -= bottomSize.y; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(caRect.x, - caRect.y + caRect.height, caRect.width, bottomSize.y); - if (!newBounds.equals(bottom.getBounds())) { - bottom.setBounds(newBounds); - } - } - - // 'Footer Separator' spans the entire area - if (footerSeparator != null && footerSeparator.isVisible()) { - Point aboveBottomSize = footerSeparator.computeSize(caRect.width, - SWT.DEFAULT, true); - caRect.height -= aboveBottomSize.y; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(caRect.x, - caRect.y + caRect.height, caRect.width, aboveBottomSize.y); - if (!newBounds.equals(footerSeparator.getBounds())) { - footerSeparator.setBounds(newBounds); - } - } - - caRect.height -= gutterBottom; - - // 'Left' spans between 'top' and 'bottom' - if (left != null && left.isVisible()) { - Point leftSize = left.computeSize(SWT.DEFAULT, caRect.height, true); - caRect.x += leftSize.x; - caRect.width -= leftSize.x; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(caRect.x - leftSize.x, caRect.y, - leftSize.x, caRect.height); - if (!newBounds.equals(left.getBounds())) { - left.setBounds(newBounds); - } - } - caRect.x += gutterLeft; - caRect.width -= gutterLeft; - - // 'Right' spans between 'top' and 'bottom' - if (right != null && right.isVisible()) { - Point rightSize = right.computeSize(SWT.DEFAULT, caRect.height, - true); - caRect.width -= rightSize.x; - - // Don't layout unless we've changed - Rectangle newBounds = new Rectangle(caRect.x + caRect.width, - caRect.y, rightSize.x, caRect.height); - if (!newBounds.equals(right.getBounds())) { - right.setBounds(newBounds); - } - } - caRect.width -= gutterRight; - - // Don't layout unless we've changed - if (clientArea.isVisible()) { - if (!caRect.equals(clientArea.getBounds())) { - clientArea.setBounds(caRect); - } - } - - for (Composite container : containers.values()) { - if (container != null && !container.isDisposed() - && container.isVisible()) { - if (!ca.equals(container.getBounds())) { - container.setBounds(ca); - } - } - } - - } - - public Composite getContainer(Composite parent, final Object child) { - Composite container = containers.get(child); - if (container == null || container.isDisposed()) { - container = new Composite(parent, SWT.NONE); - container.setLayout(new FillLayout()); - container.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - Composite c = containers.get(child); - if (c != e.widget) { - containers.remove(child); - } - } - }); - containers.put(child, container); - } - return container; - } - - public void removeContainer(Object child) { - Composite container = containers.remove(child); - if (container != null) { - container.dispose(); - } - } - - @Override - public Composite getTrimComposite(Composite parent, int side) { - if (side == SWT.RIGHT) { - if (right == null) { - right = new Composite(parent, SWT.NONE); - right.setLayout(new XRightTrimBarLayout()); - right.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - right = null; - } - }); - } - return right; - } - Composite trim = super.getTrimComposite(parent, side); - if (trim != null && clientArea != null && !clientArea.isDisposed()) { - trim.setVisible(clientArea.isVisible()); - } - return trim; - } - -} +package org.xmind.cathy.internal.renderer; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +public class XTrimmedPartLayout extends TrimmedPartLayout { + + public Control headerSeparator; + public Control footerSeparator; + + public Map containers = new HashMap(); + + public XTrimmedPartLayout(Composite parent) { + super(parent); + clientArea.setVisible(false); + } + + public void createHeaderSeparator(Composite parent) { + if (headerSeparator != null) + return; + + headerSeparator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + headerSeparator.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + headerSeparator = null; + } + }); + } + + public void createFooterSeparator(Composite parent) { + if (footerSeparator != null) + return; + + footerSeparator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + footerSeparator.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + footerSeparator = null; + } + }); + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + Rectangle ca = composite.getClientArea(); + Rectangle caRect = new Rectangle(ca.x, ca.y, ca.width, ca.height); + + // 'Top' spans the entire area + if (top != null && top.isVisible()) { + Point topSize = top.computeSize( + caRect.width - (Util.isMac() ? 12 : 0), SWT.DEFAULT, true); /// -12 for mac margin + caRect.y += topSize.y; + caRect.height -= topSize.y; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(ca.x, ca.y, caRect.width, + topSize.y); + if (!newBounds.equals(top.getBounds())) { + top.setBounds(newBounds); + } + } + + // 'Header Separator' spans the entire area + if (headerSeparator != null && headerSeparator.isVisible()) { + Point underTopSize = headerSeparator.computeSize(caRect.width, + SWT.DEFAULT, true); + caRect.y += underTopSize.y; + caRect.height -= underTopSize.y; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(caRect.x, + caRect.y - underTopSize.y, caRect.width, underTopSize.y); + if (!newBounds.equals(headerSeparator.getBounds())) { + headerSeparator.setBounds(newBounds); + } + } + + // Include the gutter whether there is a top area or not. + caRect.y += gutterTop; + caRect.height -= gutterTop; + + // 'Bottom' spans the entire area + if (bottom != null && bottom.isVisible()) { + Point bottomSize = bottom.computeSize(caRect.width, SWT.DEFAULT, + true); + caRect.height -= bottomSize.y; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(caRect.x, + caRect.y + caRect.height, caRect.width, bottomSize.y); + if (!newBounds.equals(bottom.getBounds())) { + bottom.setBounds(newBounds); + } + } + + // 'Footer Separator' spans the entire area + if (footerSeparator != null && footerSeparator.isVisible()) { + Point aboveBottomSize = footerSeparator.computeSize(caRect.width, + SWT.DEFAULT, true); + caRect.height -= aboveBottomSize.y; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(caRect.x, + caRect.y + caRect.height, caRect.width, aboveBottomSize.y); + if (!newBounds.equals(footerSeparator.getBounds())) { + footerSeparator.setBounds(newBounds); + } + } + + caRect.height -= gutterBottom; + + // 'Left' spans between 'top' and 'bottom' + if (left != null && left.isVisible()) { + Point leftSize = left.computeSize(SWT.DEFAULT, caRect.height, true); + caRect.x += leftSize.x; + caRect.width -= leftSize.x; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(caRect.x - leftSize.x, caRect.y, + leftSize.x, caRect.height); + if (!newBounds.equals(left.getBounds())) { + left.setBounds(newBounds); + } + } + caRect.x += gutterLeft; + caRect.width -= gutterLeft; + + // 'Right' spans between 'top' and 'bottom' + if (right != null && right.isVisible()) { + Point rightSize = right.computeSize(SWT.DEFAULT, caRect.height, + true); + caRect.width -= rightSize.x; + + // Don't layout unless we've changed + Rectangle newBounds = new Rectangle(caRect.x + caRect.width, + caRect.y, rightSize.x, caRect.height); + if (!newBounds.equals(right.getBounds())) { + right.setBounds(newBounds); + } + } + caRect.width -= gutterRight; + + // Don't layout unless we've changed + if (clientArea.isVisible()) { + if (!caRect.equals(clientArea.getBounds())) { + clientArea.setBounds(caRect); + } + } + + for (Composite container : containers.values()) { + if (container != null && !container.isDisposed() + && container.isVisible()) { + if (!ca.equals(container.getBounds())) { + container.setBounds(ca); + } + } + } + + } + + public Composite getContainer(Composite parent, final Object child) { + Composite container = containers.get(child); + if (container == null || container.isDisposed()) { + container = new Composite(parent, SWT.NONE); + container.setLayout(new FillLayout()); + container.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + Composite c = containers.get(child); + if (c != e.widget) { + containers.remove(child); + } + } + }); + containers.put(child, container); + } + return container; + } + + public void removeContainer(Object child) { + Composite container = containers.remove(child); + if (container != null) { + container.dispose(); + } + } + + @Override + public Composite getTrimComposite(Composite parent, int side) { + if (side == SWT.RIGHT) { + if (right == null) { + right = new Composite(parent, SWT.NONE); + right.setLayout(new XRightTrimBarLayout()); + right.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + right = null; + } + }); + } + return right; + } + Composite trim = super.getTrimComposite(parent, side); + if (trim != null && clientArea != null && !clientArea.isDisposed()) { + trim.setVisible(clientArea.isVisible()); + } + return trim; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWBWRenderer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWBWRenderer.java index ea8dbec0b..26b2ae5c5 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWBWRenderer.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWBWRenderer.java @@ -1,223 +1,223 @@ -package org.xmind.cathy.internal.renderer; - -import java.util.List; - -import javax.inject.Inject; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.di.extensions.EventTopic; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.renderers.swt.CSSEngineHelper; -import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; -import org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Shell; -import org.osgi.service.event.Event; - -public class XWBWRenderer extends WBWRenderer { - - @Inject - private Display display; - - @Inject - private MApplication application; - - @Inject - private EModelService modelService; - - /** - * Hides all contents on startup, and will be set to true once the - * application fully starts up. - */ - private boolean showingContents = false; - - @Override - public Object createWidget(MUIElement element, Object parent) { - Object widget = super.createWidget(element, parent); - if (widget != null && widget instanceof Shell) { - recreateLayout(element, (Shell) widget); - } - - return widget; - } - - protected void recreateLayout(MUIElement element, Shell shell) { - Layout oldLayout = shell.getLayout(); - if (oldLayout != null && oldLayout instanceof TrimmedPartLayout) { - TrimmedPartLayout trimmedLayout = (TrimmedPartLayout) oldLayout; - if (trimmedLayout.clientArea != null) - trimmedLayout.clientArea.dispose(); - if (trimmedLayout.top != null) - trimmedLayout.top.dispose(); - if (trimmedLayout.bottom != null) - trimmedLayout.bottom.dispose(); - if (trimmedLayout.left != null) - trimmedLayout.left.dispose(); - if (trimmedLayout.right != null) - trimmedLayout.right.dispose(); - } - - XTrimmedPartLayout layout = new XTrimmedPartLayout(shell); - - IEclipseContext localContext = getContext(element); - // We need to retrieve specific CSS properties for our layout. - CSSEngineHelper helper = new CSSEngineHelper(localContext, shell); - layout.gutterTop = helper.getMarginTop(0); - layout.gutterBottom = helper.getMarginBottom(0); - layout.gutterLeft = helper.getMarginLeft(0); - layout.gutterRight = helper.getMarginRight(0); - - shell.setLayout(layout); - } - - @Override - public Object getUIContainer(MUIElement element) { - if (element instanceof MPart) { - MUIElement parent = element.getParent(); - if (parent != null) { - Object parentWidget = parent.getWidget(); - if (parentWidget instanceof Composite) { - Layout layout = ((Composite) parentWidget).getLayout(); - if (layout instanceof XTrimmedPartLayout) { - return ((XTrimmedPartLayout) layout).getContainer( - (Composite) parentWidget, element); - } - } - } - } - return super.getUIContainer(element); - } - - @Override - public void postProcess(MUIElement shellME) { - super.postProcess(shellME); - - MWindow window = (MWindow) shellME; - MWindowElement selectedElement = window.getSelectedElement(); - if (selectedElement != null) { - showChild(window, selectedElement); - } else if (!window.getChildren().isEmpty()) { - for (MWindowElement child : window.getChildren()) { - if (child.isToBeRendered() && child.isVisible()) { - window.setSelectedElement(child); - break; - } - } - } - } - - private void showChild(MWindow window, MWindowElement selectedChild) { - Shell shell = (Shell) window.getWidget(); - if (shell == null || shell.isDisposed()) - return; - - if (window.getChildren().isEmpty()) - return; - - for (MWindowElement child : window.getChildren()) { - Object container = getUIContainer(child); - if (container instanceof Control) { - ((Control) container) - .setVisible(showingContents && child == selectedChild); - } - } - - Layout layout = shell.getLayout(); - if (layout instanceof TrimmedPartLayout) { - TrimmedPartLayout tpl = (TrimmedPartLayout) layout; - boolean primaryClientAreaVisible = tpl.clientArea != null - && tpl.clientArea.isVisible(); - if (tpl.top != null) - tpl.top.setVisible(primaryClientAreaVisible); - if (tpl.bottom != null) - tpl.bottom.setVisible(primaryClientAreaVisible); - if (tpl.left != null) - tpl.left.setVisible(primaryClientAreaVisible); - if (tpl.right != null) - tpl.right.setVisible(primaryClientAreaVisible); - } - - shell.layout(true); - } - - @Inject - @Optional - public void subscribeTopicPartActivate( - @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (element == null || !(element instanceof MWindow)) - return; - - MWindow window = (MWindow) element; - if (window.getRenderer() != XWBWRenderer.this) - return; - - showChild(window, window.getSelectedElement()); - } - - @Inject - @Optional - public void subscribeTopicChildrenRemoved( - @EventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { - if (!UIEvents.isREMOVE(event)) - return; - - Object element = event.getProperty(UIEvents.EventTags.ELEMENT); - if (element == null || !(element instanceof MWindow)) - return; - - MWindow window = (MWindow) element; - if (window.getRenderer() != XWBWRenderer.this - || !(window.getWidget() instanceof Shell) - || !(((Shell) window.getWidget()) - .getLayout() instanceof XTrimmedPartLayout)) - return; - - XTrimmedPartLayout layout = (XTrimmedPartLayout) ((Shell) window - .getWidget()).getLayout(); - for (Object removed : UIEvents.asIterable(event, - UIEvents.EventTags.OLD_VALUE)) { - layout.removeContainer(removed); - } - } - - /** - * Once the application fully starts up, set the 'showingContents' flag to - * true and show all window contents. - * - * @param event - * the UI event of the topic - * {@link UIEvents.UILifeCycle#APP_STARTUP_COMPLETE} - */ - @Inject - @Optional - public void applicationStarted( - @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) { - showingContents = true; - - if (display == null) - return; - - display.syncExec(new Runnable() { - public void run() { - List windows = modelService.findElements(application, - null, MWindow.class, null); - for (MWindow window : windows) { - if (window.getRenderer() == XWBWRenderer.this) { - showChild(window, window.getSelectedElement()); - } - } - } - }); - } -} +package org.xmind.cathy.internal.renderer; + +import java.util.List; + +import javax.inject.Inject; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.di.extensions.EventTopic; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.renderers.swt.CSSEngineHelper; +import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; +import org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.osgi.service.event.Event; + +public class XWBWRenderer extends WBWRenderer { + + @Inject + private Display display; + + @Inject + private MApplication application; + + @Inject + private EModelService modelService; + + /** + * Hides all contents on startup, and will be set to true once the + * application fully starts up. + */ + private boolean showingContents = false; + + @Override + public Object createWidget(MUIElement element, Object parent) { + Object widget = super.createWidget(element, parent); + if (widget != null && widget instanceof Shell) { + recreateLayout(element, (Shell) widget); + } + + return widget; + } + + protected void recreateLayout(MUIElement element, Shell shell) { + Layout oldLayout = shell.getLayout(); + if (oldLayout != null && oldLayout instanceof TrimmedPartLayout) { + TrimmedPartLayout trimmedLayout = (TrimmedPartLayout) oldLayout; + if (trimmedLayout.clientArea != null) + trimmedLayout.clientArea.dispose(); + if (trimmedLayout.top != null) + trimmedLayout.top.dispose(); + if (trimmedLayout.bottom != null) + trimmedLayout.bottom.dispose(); + if (trimmedLayout.left != null) + trimmedLayout.left.dispose(); + if (trimmedLayout.right != null) + trimmedLayout.right.dispose(); + } + + XTrimmedPartLayout layout = new XTrimmedPartLayout(shell); + + IEclipseContext localContext = getContext(element); + // We need to retrieve specific CSS properties for our layout. + CSSEngineHelper helper = new CSSEngineHelper(localContext, shell); + layout.gutterTop = helper.getMarginTop(0); + layout.gutterBottom = helper.getMarginBottom(0); + layout.gutterLeft = helper.getMarginLeft(0); + layout.gutterRight = helper.getMarginRight(0); + + shell.setLayout(layout); + } + + @Override + public Object getUIContainer(MUIElement element) { + if (element instanceof MPart) { + MUIElement parent = element.getParent(); + if (parent != null) { + Object parentWidget = parent.getWidget(); + if (parentWidget instanceof Composite) { + Layout layout = ((Composite) parentWidget).getLayout(); + if (layout instanceof XTrimmedPartLayout) { + return ((XTrimmedPartLayout) layout).getContainer( + (Composite) parentWidget, element); + } + } + } + } + return super.getUIContainer(element); + } + + @Override + public void postProcess(MUIElement shellME) { + super.postProcess(shellME); + + MWindow window = (MWindow) shellME; + MWindowElement selectedElement = window.getSelectedElement(); + if (selectedElement != null) { + showChild(window, selectedElement); + } else if (!window.getChildren().isEmpty()) { + for (MWindowElement child : window.getChildren()) { + if (child.isToBeRendered() && child.isVisible()) { + window.setSelectedElement(child); + break; + } + } + } + } + + private void showChild(MWindow window, MWindowElement selectedChild) { + Shell shell = (Shell) window.getWidget(); + if (shell == null || shell.isDisposed()) + return; + + if (window.getChildren().isEmpty()) + return; + + for (MWindowElement child : window.getChildren()) { + Object container = getUIContainer(child); + if (container instanceof Control) { + ((Control) container) + .setVisible(showingContents && child == selectedChild); + } + } + + Layout layout = shell.getLayout(); + if (layout instanceof TrimmedPartLayout) { + TrimmedPartLayout tpl = (TrimmedPartLayout) layout; + boolean primaryClientAreaVisible = tpl.clientArea != null + && tpl.clientArea.isVisible(); + if (tpl.top != null) + tpl.top.setVisible(primaryClientAreaVisible); + if (tpl.bottom != null) + tpl.bottom.setVisible(primaryClientAreaVisible); + if (tpl.left != null) + tpl.left.setVisible(primaryClientAreaVisible); + if (tpl.right != null) + tpl.right.setVisible(primaryClientAreaVisible); + } + + shell.layout(true); + } + + @Inject + @Optional + public void subscribeTopicPartActivate( + @EventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) { + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (element == null || !(element instanceof MWindow)) + return; + + MWindow window = (MWindow) element; + if (window.getRenderer() != XWBWRenderer.this) + return; + + showChild(window, window.getSelectedElement()); + } + + @Inject + @Optional + public void subscribeTopicChildrenRemoved( + @EventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { + if (!UIEvents.isREMOVE(event)) + return; + + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (element == null || !(element instanceof MWindow)) + return; + + MWindow window = (MWindow) element; + if (window.getRenderer() != XWBWRenderer.this + || !(window.getWidget() instanceof Shell) + || !(((Shell) window.getWidget()) + .getLayout() instanceof XTrimmedPartLayout)) + return; + + XTrimmedPartLayout layout = (XTrimmedPartLayout) ((Shell) window + .getWidget()).getLayout(); + for (Object removed : UIEvents.asIterable(event, + UIEvents.EventTags.OLD_VALUE)) { + layout.removeContainer(removed); + } + } + + /** + * Once the application fully starts up, set the 'showingContents' flag to + * true and show all window contents. + * + * @param event + * the UI event of the topic + * {@link UIEvents.UILifeCycle#APP_STARTUP_COMPLETE} + */ + @Inject + @Optional + public void applicationStarted( + @EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) { + showingContents = true; + + if (display == null) + return; + + display.syncExec(new Runnable() { + public void run() { + List windows = modelService.findElements(application, + null, MWindow.class, null); + for (MWindow window : windows) { + if (window.getRenderer() == XWBWRenderer.this) { + showChild(window, window.getSelectedElement()); + } + } + } + }); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWorkbenchRendererFactory.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWorkbenchRendererFactory.java index 639087a88..c214ce09f 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWorkbenchRendererFactory.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XWorkbenchRendererFactory.java @@ -1,77 +1,78 @@ -package org.xmind.cathy.internal.renderer; - -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MDialog; -import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MMenu; -import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; -import org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer; -import org.eclipse.e4.ui.workbench.renderers.swt.WorkbenchRendererFactory; - -public class XWorkbenchRendererFactory extends WorkbenchRendererFactory { - - private XWBWRenderer xwbwRenderer; - private XToolBarManagerRenderer xtoolbarRenderer; - private XDialogRenderer xdialogRenderer; - private XRightStackRenderer xviewStackRenderer; - private XSashRenderer xsashRenderer; - private XMenuManagerRenderer xMenuManagerRenderer; - private LazyStackRenderer stackRenderer; - - public AbstractPartRenderer getRenderer(MUIElement uiElement, - Object parent) { - boolean viewPartStack = (uiElement instanceof MPartStack) - && (uiElement.getTags().contains("RightStack")) //$NON-NLS-1$ - && (uiElement.getElementId() != null); - boolean editorPartStack = (uiElement instanceof MPartStack) - && (uiElement.getTags().contains("EditorStack")) //$NON-NLS-1$ - && (uiElement.getElementId() != null); - if (viewPartStack) { - if (xviewStackRenderer == null) { - xviewStackRenderer = new XRightStackRenderer(); - initRenderer(xviewStackRenderer); - } - return xviewStackRenderer; - } else if (uiElement instanceof MPartSashContainer) { - if (xsashRenderer == null) { - xsashRenderer = new XSashRenderer(); - initRenderer(xsashRenderer); - } - return xsashRenderer; - } else if (uiElement instanceof MToolBar) { - if (xtoolbarRenderer == null) { - xtoolbarRenderer = new XToolBarManagerRenderer(); - initRenderer(xtoolbarRenderer); - } - return xtoolbarRenderer; - } else if (uiElement instanceof MMenu) { - if (xMenuManagerRenderer == null) { - xMenuManagerRenderer = new XMenuManagerRenderer(); - initRenderer(xMenuManagerRenderer); - } - return xMenuManagerRenderer; - - } else if (uiElement instanceof MTrimmedWindow) { - if (xwbwRenderer == null) { - xwbwRenderer = new XWBWRenderer(); - initRenderer(xwbwRenderer); - } - return xwbwRenderer; - } else if (uiElement instanceof MDialog) { - if (xdialogRenderer == null) - xdialogRenderer = new XDialogRenderer(); - initRenderer(xdialogRenderer); - return xdialogRenderer; - } else if (uiElement instanceof MPartStack && editorPartStack) { - if (stackRenderer == null) { - stackRenderer = new XStackRenderer(); - initRenderer(stackRenderer); - } - return stackRenderer; - } - return super.getRenderer(uiElement, parent); - } -} +package org.xmind.cathy.internal.renderer; + +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MDialog; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MMenu; +import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; +import org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer; +import org.eclipse.e4.ui.workbench.renderers.swt.WorkbenchRendererFactory; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class XWorkbenchRendererFactory extends WorkbenchRendererFactory { + + private XWBWRenderer xwbwRenderer; + private XToolBarManagerRenderer xtoolbarRenderer; + private XDialogRenderer xdialogRenderer; + private XStackRenderer xviewStackRenderer; + private XSashRenderer xsashRenderer; + private XMenuManagerRenderer xMenuManagerRenderer; + private LazyStackRenderer stackRenderer; + + public AbstractPartRenderer getRenderer(MUIElement uiElement, + Object parent) { + boolean viewPartStack = (uiElement instanceof MPartStack) + && (uiElement.getTags().contains(IModelConstants.TAG_X_STACK)) + && (uiElement.getElementId() != null); + boolean editorPartStack = (uiElement instanceof MPartStack) + && (uiElement.getTags().contains("EditorStack")) //$NON-NLS-1$ + && (uiElement.getElementId() != null); + if (viewPartStack) { + if (xviewStackRenderer == null) { + xviewStackRenderer = new XStackRenderer(); + initRenderer(xviewStackRenderer); + } + return xviewStackRenderer; + } else if (uiElement instanceof MPartSashContainer) { + if (xsashRenderer == null) { + xsashRenderer = new XSashRenderer(); + initRenderer(xsashRenderer); + } + return xsashRenderer; + } else if (uiElement instanceof MToolBar) { + if (xtoolbarRenderer == null) { + xtoolbarRenderer = new XToolBarManagerRenderer(); + initRenderer(xtoolbarRenderer); + } + return xtoolbarRenderer; + } else if (uiElement instanceof MMenu) { + if (xMenuManagerRenderer == null) { + xMenuManagerRenderer = new XMenuManagerRenderer(); + initRenderer(xMenuManagerRenderer); + } + return xMenuManagerRenderer; + + } else if (uiElement instanceof MTrimmedWindow) { + if (xwbwRenderer == null) { + xwbwRenderer = new XWBWRenderer(); + initRenderer(xwbwRenderer); + } + return xwbwRenderer; + } else if (uiElement instanceof MDialog) { + if (xdialogRenderer == null) + xdialogRenderer = new XDialogRenderer(); + initRenderer(xdialogRenderer); + return xdialogRenderer; + } else if (uiElement instanceof MPartStack && editorPartStack) { + if (stackRenderer == null) { + stackRenderer = new XEditorStackRenderer(); + initRenderer(stackRenderer); + } + return stackRenderer; + } + return super.getRenderer(uiElement, parent); + } +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/MinMaxAddon.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/MinMaxAddon.java index eb388eb41..de6845524 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/MinMaxAddon.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/MinMaxAddon.java @@ -1,800 +1,800 @@ -package org.xmind.cathy.internal.ui.workbench.addons.minmax; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.services.events.IEventBroker; -import org.eclipse.e4.ui.di.UIEventTopic; -import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.MAddon; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.ui.MGenericStack; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.SideValue; -import org.eclipse.e4.ui.model.application.ui.advanced.MArea; -import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; -import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimElement; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem; -import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; -import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement; -import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.UIEvents.EventTags; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolder2Adapter; -import org.eclipse.swt.custom.CTabFolderEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.ToolItem; -import org.eclipse.swt.widgets.Widget; -import org.osgi.service.event.Event; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.ui.internal.e4models.IModelConstants; - -/** - * Workbench addon that provides methods to hide, show parts in the window - */ -public class MinMaxAddon { - - static final String ID_SUFFIX = "(minimized)"; //$NON-NLS-1$ - static final String STACK_VISIBLE = "StackVisible"; //$NON-NLS-1$ - static final String STACK_HIDDEN = "StackHidden"; //$NON-NLS-1$ - /* - * TrimStack exist for PartStack - */ - static final String TRIM_STACK_EXIST = "TrimStackExist"; //$NON-NLS-1$ - - @Inject - IEventBroker eventBroker; - - @Inject - EModelService modelService; - - @Inject - EPartService partService; - - @Inject - private IEclipseContext context; - - @Inject - MAddon minMaxAddon; - - @Inject - MApplication application; - - private SelectionListener toolItemSelectionListener = new SelectionListener() { - - public void widgetSelected(SelectionEvent e) { - widgetDefaultSelected(e); - } - - public void widgetDefaultSelected(SelectionEvent e) { - ToolItem selectedToolItem = (ToolItem) e.widget; - MUIElement uiElement = (MUIElement) selectedToolItem - .getData(AbstractPartRenderer.OWNING_ME); - - if (uiElement.getTags() != null && uiElement.getTags() - .contains(IModelConstants.DIRECT_COMMAD_TAG)) - return; - - MUIElement rightTrimBar = modelService - .find(ICathyConstants.ID_TRIMBAR_RIGHT, application); - if (rightTrimBar instanceof MTrimBar) { - List children = ((MTrimBar) rightTrimBar) - .getChildren(); - for (MTrimElement trimElement : children) { - if (trimElement instanceof MToolBar) { - List toolItems = ((MToolBar) trimElement) - .getChildren(); - for (MToolBarElement toolBarElement : toolItems) { - if (toolBarElement instanceof MHandledToolItem - && toolBarElement != uiElement) { - MHandledToolItem handledToolItem = (MHandledToolItem) toolBarElement; - handledToolItem.setSelected(false); - - Map parameters = handledToolItem.getWbCommand() - .getParameterMap(); - String partId = (String) parameters.get( - IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID); - if (partId != null) { - MPart p = partService.findPart(partId); - if (p != null) { - p.setVisible(false); - partService.hidePart(p); - } - } - } - } - } - } - } - - } - }; - - private CTabFolder2Adapter CTFButtonListener = new CTabFolder2Adapter() { - private MUIElement getElementToChange(CTabFolderEvent event) { - CTabFolder ctf = (CTabFolder) event.widget; - MUIElement element = (MUIElement) ctf - .getData(AbstractPartRenderer.OWNING_ME); - if (element instanceof MArea) - return element.getCurSharedRef(); - - MUIElement parentElement = element.getParent(); - while (parentElement != null && !(parentElement instanceof MArea)) - parentElement = parentElement.getParent(); - - return parentElement != null ? parentElement.getCurSharedRef() - : element; - } - - @Override - public void maximize(CTabFolderEvent event) { - setState(getElementToChange(event), STACK_VISIBLE); - } - - @Override - public void minimize(CTabFolderEvent event) { - setState(getElementToChange(event), TRIM_STACK_EXIST); - setState(getElementToChange(event), STACK_HIDDEN); - } - - @Override - public void restore(CTabFolderEvent event) { - setState(getElementToChange(event), STACK_VISIBLE); - } - }; - - private MouseListener doubleClickListener = new MouseAdapter() { - - private MUIElement getElementToChange(MouseEvent event) { - Widget widget = (Widget) event.widget; - MUIElement element = (MUIElement) widget - .getData(AbstractPartRenderer.OWNING_ME); - if (element instanceof MArea) { - // set the state on the placeholder - return element.getCurSharedRef(); - } - - MUIElement parentElement = element.getParent(); - while (parentElement != null && !(parentElement instanceof MArea)) - parentElement = parentElement.getParent(); - - return parentElement != null ? parentElement.getCurSharedRef() - : element; - } - - public void mouseDoubleClick(MouseEvent e) { - if (e.button == 1) { - MUIElement elementToChange = getElementToChange(e); - if (!elementToChange.getTags().contains(STACK_VISIBLE)) { - setState(elementToChange, STACK_VISIBLE); - } - } - } - }; - - private void setState(MUIElement element, String state) { - if (STACK_VISIBLE.equals(state)) { - element.getTags().remove(STACK_HIDDEN); - element.getTags().remove(STACK_VISIBLE); - element.getTags().add(STACK_VISIBLE); - } else if (STACK_HIDDEN.equals(state)) { - element.getTags().remove(STACK_HIDDEN); - element.getTags().remove(STACK_VISIBLE); - element.getTags().add(STACK_HIDDEN); - } else if (TRIM_STACK_EXIST.equals(state)) { - element.getTags().remove(TRIM_STACK_EXIST); - element.getTags().add(TRIM_STACK_EXIST); - } - } - - @Inject - @Optional - private void subscribeAppStartUpCompleted( - @UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event, - @Optional MApplication application) { - fixToolItemOfRightTrimBarStatus(application); - } - - private void fixToolItemOfRightTrimBarStatus(MApplication application) { - if (application == null) - return; - - MTrimmedWindow tw = null; - List windows = application.getChildren(); - for (MWindow win : windows) { - if (win instanceof MTrimmedWindow) { - tw = (MTrimmedWindow) win; - break; - } - } - if (tw == null) - return; - - MUIElement rightPartStack = modelService - .find(ICathyConstants.ID_PARTSTACK_RIGHT, tw); - MStackElement selectedPartStackElement = null; - if (rightPartStack instanceof MPartStack) { - selectedPartStackElement = ((MPartStack) rightPartStack) - .getSelectedElement(); - } - - MTrimBar rightTrimBar = modelService.getTrim((MTrimmedWindow) tw, - SideValue.RIGHT); - if (rightTrimBar != null) { - List children = ((MTrimBar) rightTrimBar) - .getChildren(); - for (MTrimElement trimElement : children) { - if (trimElement instanceof MToolBar) { - List toolBarElements = ((MToolBar) trimElement) - .getChildren(); - for (MToolBarElement te : toolBarElements) { - if (te instanceof MHandledToolItem) { - MHandledToolItem handledToolItem = (MHandledToolItem) te; - - Object widget = te.getWidget(); - if (widget instanceof ToolItem) { - ((ToolItem) widget).removeSelectionListener( - toolItemSelectionListener); - ((ToolItem) widget).addSelectionListener( - toolItemSelectionListener); - } - - ParameterizedCommand pc = handledToolItem - .getWbCommand(); - if (pc != null) { - Map parameterMap = pc.getParameterMap(); - String partId = (String) parameterMap.get( - IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID); - boolean selected = selectedPartStackElement != null - && selectedPartStackElement - .getElementId().equals(partId); - handledToolItem.setSelected(selected); - Map persistedState = handledToolItem - .getPersistedState(); - String iconURI = persistedState.get(selected - ? IModelConstants.PERSISTED_STATE_KEY_SELECTED_ICONURI - : IModelConstants.PERSISTED_STATE_KEY_UNSELECTED_ICONURI); - if (iconURI != null) - handledToolItem.setIconURI(iconURI); - } - } - } - } - } - } - } - - @Inject - @Optional - private void subscribeTopicWidget( - @UIEventTopic(UIEvents.UIElement.TOPIC_WIDGET) Event event) { - final MUIElement changedElement = (MUIElement) event - .getProperty(EventTags.ELEMENT); - if (!(changedElement instanceof MPartStack) - && !(changedElement instanceof MArea)) - return; - - Control control = (Control) changedElement.getWidget(); - if (control == null || control.isDisposed()) - return; - - control.removeMouseListener(doubleClickListener);// Prevent multiple instances - control.addMouseListener(doubleClickListener); - - if (control instanceof CTabFolder) { - ((CTabFolder) control).removeCTabFolder2Listener(CTFButtonListener); // Prevent multiple instances - ((CTabFolder) control).addCTabFolder2Listener(CTFButtonListener); - } - } - - /** - * Handles removals from the perspective - * - * @param event - */ - - @Inject - @Optional - private void subscribeTopicChildren( - @UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { - final MUIElement changedElement = (MUIElement) event - .getProperty(EventTags.ELEMENT); - MWindow window = modelService.getTopLevelWindowFor(changedElement); - - // this method is intended to update the minimized stacks in a trim - // if the removed element is no perspective and the top level window - // is not a trimmed window, we don't need to do anything here - if (!(changedElement instanceof MPerspectiveStack) || window == null - || !(window instanceof MTrimmedWindow)) { - return; - } - - if (UIEvents.isREMOVE(event)) { - for (Object removedElement : UIEvents.asIterable(event, - UIEvents.EventTags.OLD_VALUE)) { - MUIElement removed = (MUIElement) removedElement; - String perspectiveId = removed.getElementId(); - - MTrimBar bar = modelService.getTrim((MTrimmedWindow) window, - SideValue.TOP); - - // gather up any minimized stacks for this perspective... - List toRemove = new ArrayList(); - for (MUIElement child : bar.getChildren()) { - String trimElementId = child.getElementId(); - if (child instanceof MToolControl - && trimElementId.contains(perspectiveId)) { - toRemove.add((MToolControl) child); - } - } - - // ...and remove them - for (MToolControl minStack : toRemove) { - minStack.setToBeRendered(false); - bar.getChildren().remove(minStack); - } - } - } - } - - /** - * Handles changes of the perspective - * - * @param event - */ - - @Inject - @Optional - private void subscribeTopicSelectedElement( - @UIEventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event, - @Optional MApplication application) { - final MUIElement changedElement = (MUIElement) event - .getProperty(EventTags.ELEMENT); - - if (changedElement instanceof MPartStack - && ICathyConstants.ID_PARTSTACK_RIGHT - .equals(changedElement.getElementId())) { - fixToolItemOfRightTrimBarStatus(application); - return; - } - - if (!(changedElement instanceof MPerspectiveStack)) - return; - - MPerspectiveStack ps = (MPerspectiveStack) changedElement; - MWindow window = modelService.getTopLevelWindowFor(ps); - - List tcList = modelService.findElements(window, null, - MToolControl.class, null); - - final MPerspective curPersp = ps.getSelectedElement(); - if (curPersp != null) { - List tags = new ArrayList(); - tags.add(TRIM_STACK_EXIST); - List minimizedElements = modelService - .findElements(curPersp, null, MUIElement.class, tags); - // Show any minimized stack from the current perspective - String perspId = '(' + curPersp.getElementId() + ')'; - for (MUIElement ele : minimizedElements) { - String fullId = ele.getElementId() + perspId; - - for (MToolControl tc : tcList) { - if (fullId.equals(tc.getElementId())) { - tc.setToBeRendered(true); - } - } - } - } - - // Hide any minimized stacks from the old perspective - if (event.getProperty(EventTags.OLD_VALUE) instanceof MPerspective) { - MPerspective oldPersp = (MPerspective) event - .getProperty(EventTags.OLD_VALUE); - String perspId = '(' + oldPersp.getElementId() + ')'; - for (MToolControl tc : tcList) { - if (tc.getObject() instanceof XTrimStack - && tc.getElementId().contains(perspId)) { - XTrimStack ts = (XTrimStack) tc.getObject(); - ts.setStateForShowStack(false); - tc.setToBeRendered(false); - } - } - } - - final Shell winShell = (Shell) window.getWidget(); - winShell.getDisplay().asyncExec(new Runnable() { - public void run() { - if (!winShell.isDisposed()) { - winShell.layout(true, true); - } - } - }); - } - - /** - * Handles changes in tags - * - * @param event - */ - - @Inject - @Optional - private void subscribeTopicTagsChanged( - @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) Event event) { - Object changedObj = event.getProperty(EventTags.ELEMENT); - - if (!(changedObj instanceof MUIElement)) - return; - - final MUIElement changedElement = (MUIElement) changedObj; - - if (UIEvents.isADD(event)) { - if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, - STACK_HIDDEN)) { - hideStack(changedElement); - } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, - STACK_VISIBLE)) { - showStack(changedElement); - } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, - TRIM_STACK_EXIST)) { - createTrim(changedElement); - changedElement.setVisible(false); - } - } - } - - /** - * Handles changes in the id of the element If a perspective ID changes fix - * any TrimStacks that reference the old id to point at the new id. This - * keeps trim stacks attached to the correct perspective when a perspective - * is saved with a new name. - * - * @param event - */ - - @Inject - @Optional - private void subscribeTopicElementId( - @UIEventTopic(UIEvents.ApplicationElement.TOPIC_ELEMENTID) Event event) { - Object changedObject = event.getProperty(EventTags.ELEMENT); - - // Only care about MPerspective id changes - if (!(changedObject instanceof MPerspective)) - return; - - MPerspective perspective = (MPerspective) changedObject; - - String newID = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE); - String oldID = (String) event.getProperty(UIEvents.EventTags.OLD_VALUE); - - // pattern is trimStackID(perspectiveID) - newID = '(' + newID + ')'; - oldID = '(' + oldID + ')'; - - // Search the trim for the window containing the perspective - MWindow perspWin = modelService.getTopLevelWindowFor(perspective); - if (perspWin == null) - return; - - List trimStacks = modelService.findElements(perspWin, - null, MToolControl.class, null); - for (MToolControl trimStack : trimStacks) { - // Only care about MToolControls that are TrimStacks - if (XTrimStack.CONTRIBUTION_URI_XTRIMSTACK - .equals(trimStack.getContributionURI())) - trimStack.setElementId( - trimStack.getElementId().replace(oldID, newID)); - } - } - - /** - * Handles the event that the perspective is saved - * - * @param event - */ - - @Inject - @Optional - private void subscribeTopicPerspSaved( - @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_SAVED) Event event) { - final MPerspective savedPersp = (MPerspective) event - .getProperty(EventTags.ELEMENT); - String cache = getTrimCache(savedPersp); - minMaxAddon.getPersistedState().put(savedPersp.getElementId(), cache); - } - - private String getTrimCache(MPerspective savedPersp) { - MWindow topWin = modelService.getTopLevelWindowFor(savedPersp); - String perspIdStr = '(' + savedPersp.getElementId() + ')'; - - String cache = getWinCache(topWin, perspIdStr); - for (MWindow dw : savedPersp.getWindows()) { - cache += getWinCache(dw, perspIdStr); - } - - return cache; - } - - private String getWinCache(MWindow win, String perspIdStr) { - String winStr = ""; //$NON-NLS-1$ - - List stackList = modelService.findElements(win, null, - MPartStack.class, null); - for (MPartStack stack : stackList) { - winStr += getStackTrimLoc(stack, perspIdStr); - } - return winStr; - } - - private String getStackTrimLoc(MPartStack stack, String perspIdStr) { - MWindow stackWin = modelService.getTopLevelWindowFor(stack);// getContainingWindow(stack); - MUIElement tcElement = modelService - .find(stack.getElementId() + perspIdStr, stackWin); - if (tcElement == null) - return ""; //$NON-NLS-1$ - - MTrimBar bar = (MTrimBar) ((MUIElement) tcElement.getParent()); - int sideVal = bar.getSide().getValue(); - int index = bar.getChildren().indexOf(tcElement); - return stack.getElementId() + ' ' + sideVal + ' ' + index + "#"; //$NON-NLS-1$ - } - - /** - * Handles the event that the perspective is reset - * - * @param event - */ - @Inject - @Optional - private void subscribeTopicPerspReset( - @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_RESET) Event event, - @Optional MApplication application) { - final MPerspective resetPersp = (MPerspective) event - .getProperty(EventTags.ELEMENT); - - //Any stack which has TrimStackExist tag should have a created trim - List minimizedElements = modelService.findElements( - resetPersp, null, MUIElement.class, - Arrays.asList(TRIM_STACK_EXIST)); - for (MUIElement element : minimizedElements) { - createTrim(element); - } - - fixToolItemOfRightTrimBarStatus(application); - - } - - /** - * Handles the event that the perspective is opened - * - * @param event - */ - @Inject - @Optional - private void subscribeTopicPerspOpened( - @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_OPENED) Event event) { - final MPerspective openedPersp = (MPerspective) event - .getProperty(EventTags.ELEMENT); - - //Any stack which has TrimStackExist tag should have a created trim - List allStacks = modelService.findElements(openedPersp, - null, MGenericStack.class, Arrays.asList(TRIM_STACK_EXIST)); - for (MGenericStack stack : allStacks) { - createTrim(stack); - } - } - - boolean isEmptyPerspectiveStack(MUIElement element) { - if (!(element instanceof MPerspectiveStack)) - return false; - MPerspectiveStack ps = (MPerspectiveStack) element; - return ps.getChildren().size() == 0; - } - - void hideStack(MUIElement element) { - // Can't create trim for a non-rendered element - if (!element.isToBeRendered()) - return; - - if (isEmptyPerspectiveStack(element)) { - element.setVisible(false); - return; - } - - createTrim(element); - element.setVisible(false); - } - - void showStack(final MUIElement element) { - if (!element.isToBeRendered()) - return; - - List elementsToHide = getElementsToHide(element); - for (MUIElement toMinimize : elementsToHide) { - setState(toMinimize, STACK_HIDDEN); - } - element.setVisible(true); - } - - private List getElementsToHide(MUIElement element) { - MWindow win = getWindowFor(element); - MPerspective persp = modelService.getActivePerspective(win); - - List elementsToHide = new ArrayList(); - int loc = modelService.getElementLocation(element); - if ((loc & EModelService.OUTSIDE_PERSPECTIVE) != 0) { - // Hide all other global stacks - List globalStacks = modelService.findElements(win, null, - MPartStack.class, null, EModelService.OUTSIDE_PERSPECTIVE); - for (MPartStack gStack : globalStacks) { - if (gStack == element || !gStack.isToBeRendered()) - continue; - - if (gStack.getWidget() != null - && !gStack.getTags().contains(STACK_HIDDEN)) { - elementsToHide.add(gStack); - } - } - - // Hide the Perspective Stack - MUIElement perspStack = null; - if (persp == null) { - // special case for windows with no perspectives (eg bug 372614: - // intro part with no perspectives). We know we're outside - // of the perspective stack, so find it top-down - List pStacks = modelService.findElements(win, - null, MPerspectiveStack.class, null); - perspStack = (pStacks.size() > 0) ? pStacks.get(0) : null; - } else { - perspStack = persp.getParent(); - } - if (perspStack != null) { - if (perspStack.getElementId() == null - || perspStack.getElementId().length() == 0) - perspStack.setElementId("PerspectiveStack"); //$NON-NLS-1$ - - elementsToHide.add(perspStack); - } - } else { - List stacks = modelService.findElements( - persp == null ? win : persp, null, MPartStack.class, null, - EModelService.PRESENTATION); - for (MPartStack theStack : stacks) { - if (theStack == element || !theStack.isToBeRendered()) - continue; - - // Exclude stacks in DW's - if (getWindowFor(theStack) != win) - continue; - - loc = modelService.getElementLocation(theStack); - if (loc != EModelService.IN_SHARED_AREA - && theStack.getWidget() != null && theStack.isVisible() - && !theStack.getTags().contains(STACK_HIDDEN)) { - elementsToHide.add(theStack); - } - } - - // Find any 'standalone' views *not* in a stack - List standaloneTag = new ArrayList(); - standaloneTag.add(IPresentationEngine.STANDALONE); - List standaloneViews = modelService.findElements( - persp == null ? win : persp, null, MPlaceholder.class, - standaloneTag, EModelService.PRESENTATION); - for (MPlaceholder part : standaloneViews) { - if (!part.isToBeRendered()) - continue; - elementsToHide.add(part); - } - } - - return elementsToHide; - } - - /** - * Return the MWindow containing this element (if any). This may either be a - * 'top level' window -or- a detached window. This allows the min.max code - * to only affect elements in the window containing the element. - * - * @param element - * The element to check - * @return the window containing the element. - */ - private MWindow getWindowFor(MUIElement element) { - MUIElement parent = element.getParent(); - - // We rely here on the fact that a DW's 'getParent' will return - // null since it's not in the 'children' hierarchy - while (parent != null && !(parent instanceof MWindow)) - parent = parent.getParent(); - - // A detached window will end up with getParent() == null - return (MWindow) parent; - } - - private void createTrim(MUIElement element) { - MWindow win = getWindowFor(element); - if (!(win instanceof MTrimmedWindow)) { - return; - } - - MTrimmedWindow window = (MTrimmedWindow) win; - Shell winShell = (Shell) window.getWidget(); - - // Is there already a TrimControl there ? - String trimId = element.getElementId() - + getMinimizedElementSuffix(element); - MToolControl trimStack = (MToolControl) modelService.find(trimId, - window); - - if (trimStack == null) { - trimStack = modelService.createModelElement(MToolControl.class); - trimStack.setElementId(trimId); - trimStack - .setContributionURI(XTrimStack.CONTRIBUTION_URI_XTRIMSTACK); - trimStack.getTags().add("XTrimStack"); //$NON-NLS-1$ - trimStack.getTags().add(ICathyConstants.TAG_TRIMBAR_LAYOUT_CENTER); - - MTrimBar bar = modelService.getTrim(window, SideValue.RIGHT); - bar.getChildren().add(trimStack); - bar.setVisible(true); - - // get the parent trim bar, see bug 320756 - if (bar.getWidget() == null) { - // ask it to be rendered - bar.setToBeRendered(true); - - // create the widget - context.get(IPresentationEngine.class).createGui(bar, winShell, - window.getContext()); - } - } else { - // get the parent trim bar, see bug 320756 - MUIElement parent = trimStack.getParent(); - parent.setVisible(true); - if (parent.getWidget() == null) { - // ask it to be rendered - parent.setToBeRendered(true); - // create the widget - context.get(IPresentationEngine.class).createGui(parent, - winShell, window.getContext()); - } - } - trimStack.setToBeRendered(true); - } - - private String getMinimizedElementSuffix(MUIElement element) { - String id = ID_SUFFIX; - MPerspective persp = modelService.getPerspectiveFor(element); - if (persp != null) { - id = '(' + persp.getElementId() + ')'; - } - return id; - } - -} +package org.xmind.cathy.internal.ui.workbench.addons.minmax; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; +import org.eclipse.e4.ui.model.application.MAddon; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MGenericStack; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.SideValue; +import org.eclipse.e4.ui.model.application.ui.advanced.MArea; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimElement; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem; +import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; +import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement; +import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.UIEvents.EventTags; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolder2Adapter; +import org.eclipse.swt.custom.CTabFolderEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.Widget; +import org.osgi.service.event.Event; +import org.xmind.cathy.internal.ICathyConstants; +import org.xmind.ui.internal.e4models.IModelConstants; + +/** + * Workbench addon that provides methods to hide, show parts in the window + */ +public class MinMaxAddon { + + static final String ID_SUFFIX = "(minimized)"; //$NON-NLS-1$ + static final String STACK_VISIBLE = "StackVisible"; //$NON-NLS-1$ + static final String STACK_HIDDEN = "StackHidden"; //$NON-NLS-1$ + /* + * TrimStack exist for PartStack + */ + static final String TRIM_STACK_EXIST = "TrimStackExist"; //$NON-NLS-1$ + + @Inject + IEventBroker eventBroker; + + @Inject + EModelService modelService; + + @Inject + EPartService partService; + + @Inject + private IEclipseContext context; + + @Inject + MAddon minMaxAddon; + + @Inject + MApplication application; + + private SelectionListener toolItemSelectionListener = new SelectionListener() { + + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + public void widgetDefaultSelected(SelectionEvent e) { + ToolItem selectedToolItem = (ToolItem) e.widget; + MUIElement uiElement = (MUIElement) selectedToolItem + .getData(AbstractPartRenderer.OWNING_ME); + + if (uiElement.getTags() != null && uiElement.getTags() + .contains(IModelConstants.DIRECT_COMMAD_TAG)) + return; + + MUIElement rightTrimBar = modelService + .find(ICathyConstants.ID_TRIMBAR_RIGHT, application); + if (rightTrimBar instanceof MTrimBar) { + List children = ((MTrimBar) rightTrimBar) + .getChildren(); + for (MTrimElement trimElement : children) { + if (trimElement instanceof MToolBar) { + List toolItems = ((MToolBar) trimElement) + .getChildren(); + for (MToolBarElement toolBarElement : toolItems) { + if (toolBarElement instanceof MHandledToolItem + && toolBarElement != uiElement) { + MHandledToolItem handledToolItem = (MHandledToolItem) toolBarElement; + handledToolItem.setSelected(false); + + Map parameters = handledToolItem.getWbCommand() + .getParameterMap(); + String partId = (String) parameters.get( + IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID); + if (partId != null) { + MPart p = partService.findPart(partId); + if (p != null) { + p.setVisible(false); + partService.hidePart(p); + } + } + } + } + } + } + } + + } + }; + + private CTabFolder2Adapter CTFButtonListener = new CTabFolder2Adapter() { + private MUIElement getElementToChange(CTabFolderEvent event) { + CTabFolder ctf = (CTabFolder) event.widget; + MUIElement element = (MUIElement) ctf + .getData(AbstractPartRenderer.OWNING_ME); + if (element instanceof MArea) + return element.getCurSharedRef(); + + MUIElement parentElement = element.getParent(); + while (parentElement != null && !(parentElement instanceof MArea)) + parentElement = parentElement.getParent(); + + return parentElement != null ? parentElement.getCurSharedRef() + : element; + } + + @Override + public void maximize(CTabFolderEvent event) { + setState(getElementToChange(event), STACK_VISIBLE); + } + + @Override + public void minimize(CTabFolderEvent event) { + setState(getElementToChange(event), TRIM_STACK_EXIST); + setState(getElementToChange(event), STACK_HIDDEN); + } + + @Override + public void restore(CTabFolderEvent event) { + setState(getElementToChange(event), STACK_VISIBLE); + } + }; + + private MouseListener doubleClickListener = new MouseAdapter() { + + private MUIElement getElementToChange(MouseEvent event) { + Widget widget = (Widget) event.widget; + MUIElement element = (MUIElement) widget + .getData(AbstractPartRenderer.OWNING_ME); + if (element instanceof MArea) { + // set the state on the placeholder + return element.getCurSharedRef(); + } + + MUIElement parentElement = element.getParent(); + while (parentElement != null && !(parentElement instanceof MArea)) + parentElement = parentElement.getParent(); + + return parentElement != null ? parentElement.getCurSharedRef() + : element; + } + + public void mouseDoubleClick(MouseEvent e) { + if (e.button == 1) { + MUIElement elementToChange = getElementToChange(e); + if (!elementToChange.getTags().contains(STACK_VISIBLE)) { + setState(elementToChange, STACK_VISIBLE); + } + } + } + }; + + private void setState(MUIElement element, String state) { + if (STACK_VISIBLE.equals(state)) { + element.getTags().remove(STACK_HIDDEN); + element.getTags().remove(STACK_VISIBLE); + element.getTags().add(STACK_VISIBLE); + } else if (STACK_HIDDEN.equals(state)) { + element.getTags().remove(STACK_HIDDEN); + element.getTags().remove(STACK_VISIBLE); + element.getTags().add(STACK_HIDDEN); + } else if (TRIM_STACK_EXIST.equals(state)) { + element.getTags().remove(TRIM_STACK_EXIST); + element.getTags().add(TRIM_STACK_EXIST); + } + } + + @Inject + @Optional + private void subscribeAppStartUpCompleted( + @UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event, + @Optional MApplication application) { + fixToolItemOfRightTrimBarStatus(application); + } + + private void fixToolItemOfRightTrimBarStatus(MApplication application) { + if (application == null) + return; + + MTrimmedWindow tw = null; + List windows = application.getChildren(); + for (MWindow win : windows) { + if (win instanceof MTrimmedWindow) { + tw = (MTrimmedWindow) win; + break; + } + } + if (tw == null) + return; + + MUIElement rightPartStack = modelService + .find(ICathyConstants.ID_PARTSTACK_RIGHT, tw); + MStackElement selectedPartStackElement = null; + if (rightPartStack instanceof MPartStack) { + selectedPartStackElement = ((MPartStack) rightPartStack) + .getSelectedElement(); + } + + MTrimBar rightTrimBar = modelService.getTrim((MTrimmedWindow) tw, + SideValue.RIGHT); + if (rightTrimBar != null) { + List children = ((MTrimBar) rightTrimBar) + .getChildren(); + for (MTrimElement trimElement : children) { + if (trimElement instanceof MToolBar) { + List toolBarElements = ((MToolBar) trimElement) + .getChildren(); + for (MToolBarElement te : toolBarElements) { + if (te instanceof MHandledToolItem) { + MHandledToolItem handledToolItem = (MHandledToolItem) te; + + Object widget = te.getWidget(); + if (widget instanceof ToolItem) { + ((ToolItem) widget).removeSelectionListener( + toolItemSelectionListener); + ((ToolItem) widget).addSelectionListener( + toolItemSelectionListener); + } + + ParameterizedCommand pc = handledToolItem + .getWbCommand(); + if (pc != null) { + Map parameterMap = pc.getParameterMap(); + String partId = (String) parameterMap.get( + IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID); + boolean selected = selectedPartStackElement != null + && selectedPartStackElement + .getElementId().equals(partId); + handledToolItem.setSelected(selected); + Map persistedState = handledToolItem + .getPersistedState(); + String iconURI = persistedState.get(selected + ? IModelConstants.PERSISTED_STATE_KEY_SELECTED_ICONURI + : IModelConstants.PERSISTED_STATE_KEY_UNSELECTED_ICONURI); + if (iconURI != null) + handledToolItem.setIconURI(iconURI); + } + } + } + } + } + } + } + + @Inject + @Optional + private void subscribeTopicWidget( + @UIEventTopic(UIEvents.UIElement.TOPIC_WIDGET) Event event) { + final MUIElement changedElement = (MUIElement) event + .getProperty(EventTags.ELEMENT); + if (!(changedElement instanceof MPartStack) + && !(changedElement instanceof MArea)) + return; + + Control control = (Control) changedElement.getWidget(); + if (control == null || control.isDisposed()) + return; + + control.removeMouseListener(doubleClickListener);// Prevent multiple instances + control.addMouseListener(doubleClickListener); + + if (control instanceof CTabFolder) { + ((CTabFolder) control).removeCTabFolder2Listener(CTFButtonListener); // Prevent multiple instances + ((CTabFolder) control).addCTabFolder2Listener(CTFButtonListener); + } + } + + /** + * Handles removals from the perspective + * + * @param event + */ + + @Inject + @Optional + private void subscribeTopicChildren( + @UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) { + final MUIElement changedElement = (MUIElement) event + .getProperty(EventTags.ELEMENT); + MWindow window = modelService.getTopLevelWindowFor(changedElement); + + // this method is intended to update the minimized stacks in a trim + // if the removed element is no perspective and the top level window + // is not a trimmed window, we don't need to do anything here + if (!(changedElement instanceof MPerspectiveStack) || window == null + || !(window instanceof MTrimmedWindow)) { + return; + } + + if (UIEvents.isREMOVE(event)) { + for (Object removedElement : UIEvents.asIterable(event, + UIEvents.EventTags.OLD_VALUE)) { + MUIElement removed = (MUIElement) removedElement; + String perspectiveId = removed.getElementId(); + + MTrimBar bar = modelService.getTrim((MTrimmedWindow) window, + SideValue.TOP); + + // gather up any minimized stacks for this perspective... + List toRemove = new ArrayList(); + for (MUIElement child : bar.getChildren()) { + String trimElementId = child.getElementId(); + if (child instanceof MToolControl + && trimElementId.contains(perspectiveId)) { + toRemove.add((MToolControl) child); + } + } + + // ...and remove them + for (MToolControl minStack : toRemove) { + minStack.setToBeRendered(false); + bar.getChildren().remove(minStack); + } + } + } + } + + /** + * Handles changes of the perspective + * + * @param event + */ + + @Inject + @Optional + private void subscribeTopicSelectedElement( + @UIEventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event, + @Optional MApplication application) { + final MUIElement changedElement = (MUIElement) event + .getProperty(EventTags.ELEMENT); + + if (changedElement instanceof MPartStack + && ICathyConstants.ID_PARTSTACK_RIGHT + .equals(changedElement.getElementId())) { + fixToolItemOfRightTrimBarStatus(application); + return; + } + + if (!(changedElement instanceof MPerspectiveStack)) + return; + + MPerspectiveStack ps = (MPerspectiveStack) changedElement; + MWindow window = modelService.getTopLevelWindowFor(ps); + + List tcList = modelService.findElements(window, null, + MToolControl.class, null); + + final MPerspective curPersp = ps.getSelectedElement(); + if (curPersp != null) { + List tags = new ArrayList(); + tags.add(TRIM_STACK_EXIST); + List minimizedElements = modelService + .findElements(curPersp, null, MUIElement.class, tags); + // Show any minimized stack from the current perspective + String perspId = '(' + curPersp.getElementId() + ')'; + for (MUIElement ele : minimizedElements) { + String fullId = ele.getElementId() + perspId; + + for (MToolControl tc : tcList) { + if (fullId.equals(tc.getElementId())) { + tc.setToBeRendered(true); + } + } + } + } + + // Hide any minimized stacks from the old perspective + if (event.getProperty(EventTags.OLD_VALUE) instanceof MPerspective) { + MPerspective oldPersp = (MPerspective) event + .getProperty(EventTags.OLD_VALUE); + String perspId = '(' + oldPersp.getElementId() + ')'; + for (MToolControl tc : tcList) { + if (tc.getObject() instanceof XTrimStack + && tc.getElementId().contains(perspId)) { + XTrimStack ts = (XTrimStack) tc.getObject(); + ts.setStateForShowStack(false); + tc.setToBeRendered(false); + } + } + } + + final Shell winShell = (Shell) window.getWidget(); + winShell.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!winShell.isDisposed()) { + winShell.layout(true, true); + } + } + }); + } + + /** + * Handles changes in tags + * + * @param event + */ + + @Inject + @Optional + private void subscribeTopicTagsChanged( + @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) Event event) { + Object changedObj = event.getProperty(EventTags.ELEMENT); + + if (!(changedObj instanceof MUIElement)) + return; + + final MUIElement changedElement = (MUIElement) changedObj; + + if (UIEvents.isADD(event)) { + if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, + STACK_HIDDEN)) { + hideStack(changedElement); + } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, + STACK_VISIBLE)) { + showStack(changedElement); + } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, + TRIM_STACK_EXIST)) { + createTrim(changedElement); + changedElement.setVisible(false); + } + } + } + + /** + * Handles changes in the id of the element If a perspective ID changes fix + * any TrimStacks that reference the old id to point at the new id. This + * keeps trim stacks attached to the correct perspective when a perspective + * is saved with a new name. + * + * @param event + */ + + @Inject + @Optional + private void subscribeTopicElementId( + @UIEventTopic(UIEvents.ApplicationElement.TOPIC_ELEMENTID) Event event) { + Object changedObject = event.getProperty(EventTags.ELEMENT); + + // Only care about MPerspective id changes + if (!(changedObject instanceof MPerspective)) + return; + + MPerspective perspective = (MPerspective) changedObject; + + String newID = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE); + String oldID = (String) event.getProperty(UIEvents.EventTags.OLD_VALUE); + + // pattern is trimStackID(perspectiveID) + newID = '(' + newID + ')'; + oldID = '(' + oldID + ')'; + + // Search the trim for the window containing the perspective + MWindow perspWin = modelService.getTopLevelWindowFor(perspective); + if (perspWin == null) + return; + + List trimStacks = modelService.findElements(perspWin, + null, MToolControl.class, null); + for (MToolControl trimStack : trimStacks) { + // Only care about MToolControls that are TrimStacks + if (XTrimStack.CONTRIBUTION_URI_XTRIMSTACK + .equals(trimStack.getContributionURI())) + trimStack.setElementId( + trimStack.getElementId().replace(oldID, newID)); + } + } + + /** + * Handles the event that the perspective is saved + * + * @param event + */ + + @Inject + @Optional + private void subscribeTopicPerspSaved( + @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_SAVED) Event event) { + final MPerspective savedPersp = (MPerspective) event + .getProperty(EventTags.ELEMENT); + String cache = getTrimCache(savedPersp); + minMaxAddon.getPersistedState().put(savedPersp.getElementId(), cache); + } + + private String getTrimCache(MPerspective savedPersp) { + MWindow topWin = modelService.getTopLevelWindowFor(savedPersp); + String perspIdStr = '(' + savedPersp.getElementId() + ')'; + + String cache = getWinCache(topWin, perspIdStr); + for (MWindow dw : savedPersp.getWindows()) { + cache += getWinCache(dw, perspIdStr); + } + + return cache; + } + + private String getWinCache(MWindow win, String perspIdStr) { + String winStr = ""; //$NON-NLS-1$ + + List stackList = modelService.findElements(win, null, + MPartStack.class, null); + for (MPartStack stack : stackList) { + winStr += getStackTrimLoc(stack, perspIdStr); + } + return winStr; + } + + private String getStackTrimLoc(MPartStack stack, String perspIdStr) { + MWindow stackWin = modelService.getTopLevelWindowFor(stack);// getContainingWindow(stack); + MUIElement tcElement = modelService + .find(stack.getElementId() + perspIdStr, stackWin); + if (tcElement == null) + return ""; //$NON-NLS-1$ + + MTrimBar bar = (MTrimBar) ((MUIElement) tcElement.getParent()); + int sideVal = bar.getSide().getValue(); + int index = bar.getChildren().indexOf(tcElement); + return stack.getElementId() + ' ' + sideVal + ' ' + index + "#"; //$NON-NLS-1$ + } + + /** + * Handles the event that the perspective is reset + * + * @param event + */ + @Inject + @Optional + private void subscribeTopicPerspReset( + @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_RESET) Event event, + @Optional MApplication application) { + final MPerspective resetPersp = (MPerspective) event + .getProperty(EventTags.ELEMENT); + + //Any stack which has TrimStackExist tag should have a created trim + List minimizedElements = modelService.findElements( + resetPersp, null, MUIElement.class, + Arrays.asList(TRIM_STACK_EXIST)); + for (MUIElement element : minimizedElements) { + createTrim(element); + } + + fixToolItemOfRightTrimBarStatus(application); + + } + + /** + * Handles the event that the perspective is opened + * + * @param event + */ + @Inject + @Optional + private void subscribeTopicPerspOpened( + @UIEventTopic(UIEvents.UILifeCycle.PERSPECTIVE_OPENED) Event event) { + final MPerspective openedPersp = (MPerspective) event + .getProperty(EventTags.ELEMENT); + + //Any stack which has TrimStackExist tag should have a created trim + List allStacks = modelService.findElements(openedPersp, + null, MGenericStack.class, Arrays.asList(TRIM_STACK_EXIST)); + for (MGenericStack stack : allStacks) { + createTrim(stack); + } + } + + boolean isEmptyPerspectiveStack(MUIElement element) { + if (!(element instanceof MPerspectiveStack)) + return false; + MPerspectiveStack ps = (MPerspectiveStack) element; + return ps.getChildren().size() == 0; + } + + void hideStack(MUIElement element) { + // Can't create trim for a non-rendered element + if (!element.isToBeRendered()) + return; + + if (isEmptyPerspectiveStack(element)) { + element.setVisible(false); + return; + } + + createTrim(element); + element.setVisible(false); + } + + void showStack(final MUIElement element) { + if (!element.isToBeRendered()) + return; + + List elementsToHide = getElementsToHide(element); + for (MUIElement toMinimize : elementsToHide) { + setState(toMinimize, STACK_HIDDEN); + } + element.setVisible(true); + } + + private List getElementsToHide(MUIElement element) { + MWindow win = getWindowFor(element); + MPerspective persp = modelService.getActivePerspective(win); + + List elementsToHide = new ArrayList(); + int loc = modelService.getElementLocation(element); + if ((loc & EModelService.OUTSIDE_PERSPECTIVE) != 0) { + // Hide all other global stacks + List globalStacks = modelService.findElements(win, null, + MPartStack.class, null, EModelService.OUTSIDE_PERSPECTIVE); + for (MPartStack gStack : globalStacks) { + if (gStack == element || !gStack.isToBeRendered()) + continue; + + if (gStack.getWidget() != null + && !gStack.getTags().contains(STACK_HIDDEN)) { + elementsToHide.add(gStack); + } + } + + // Hide the Perspective Stack + MUIElement perspStack = null; + if (persp == null) { + // special case for windows with no perspectives (eg bug 372614: + // intro part with no perspectives). We know we're outside + // of the perspective stack, so find it top-down + List pStacks = modelService.findElements(win, + null, MPerspectiveStack.class, null); + perspStack = (pStacks.size() > 0) ? pStacks.get(0) : null; + } else { + perspStack = persp.getParent(); + } + if (perspStack != null) { + if (perspStack.getElementId() == null + || perspStack.getElementId().length() == 0) + perspStack.setElementId("PerspectiveStack"); //$NON-NLS-1$ + + elementsToHide.add(perspStack); + } + } else { + List stacks = modelService.findElements( + persp == null ? win : persp, null, MPartStack.class, null, + EModelService.PRESENTATION); + for (MPartStack theStack : stacks) { + if (theStack == element || !theStack.isToBeRendered()) + continue; + + // Exclude stacks in DW's + if (getWindowFor(theStack) != win) + continue; + + loc = modelService.getElementLocation(theStack); + if (loc != EModelService.IN_SHARED_AREA + && theStack.getWidget() != null && theStack.isVisible() + && !theStack.getTags().contains(STACK_HIDDEN)) { + elementsToHide.add(theStack); + } + } + + // Find any 'standalone' views *not* in a stack + List standaloneTag = new ArrayList(); + standaloneTag.add(IPresentationEngine.STANDALONE); + List standaloneViews = modelService.findElements( + persp == null ? win : persp, null, MPlaceholder.class, + standaloneTag, EModelService.PRESENTATION); + for (MPlaceholder part : standaloneViews) { + if (!part.isToBeRendered()) + continue; + elementsToHide.add(part); + } + } + + return elementsToHide; + } + + /** + * Return the MWindow containing this element (if any). This may either be a + * 'top level' window -or- a detached window. This allows the min.max code + * to only affect elements in the window containing the element. + * + * @param element + * The element to check + * @return the window containing the element. + */ + private MWindow getWindowFor(MUIElement element) { + MUIElement parent = element.getParent(); + + // We rely here on the fact that a DW's 'getParent' will return + // null since it's not in the 'children' hierarchy + while (parent != null && !(parent instanceof MWindow)) + parent = parent.getParent(); + + // A detached window will end up with getParent() == null + return (MWindow) parent; + } + + private void createTrim(MUIElement element) { + MWindow win = getWindowFor(element); + if (!(win instanceof MTrimmedWindow)) { + return; + } + + MTrimmedWindow window = (MTrimmedWindow) win; + Shell winShell = (Shell) window.getWidget(); + + // Is there already a TrimControl there ? + String trimId = element.getElementId() + + getMinimizedElementSuffix(element); + MToolControl trimStack = (MToolControl) modelService.find(trimId, + window); + + if (trimStack == null) { + trimStack = modelService.createModelElement(MToolControl.class); + trimStack.setElementId(trimId); + trimStack + .setContributionURI(XTrimStack.CONTRIBUTION_URI_XTRIMSTACK); + trimStack.getTags().add("XTrimStack"); //$NON-NLS-1$ + trimStack.getTags().add(ICathyConstants.TAG_TRIMBAR_LAYOUT_CENTER); + + MTrimBar bar = modelService.getTrim(window, SideValue.RIGHT); + bar.getChildren().add(trimStack); + bar.setVisible(true); + + // get the parent trim bar, see bug 320756 + if (bar.getWidget() == null) { + // ask it to be rendered + bar.setToBeRendered(true); + + // create the widget + context.get(IPresentationEngine.class).createGui(bar, winShell, + window.getContext()); + } + } else { + // get the parent trim bar, see bug 320756 + MUIElement parent = trimStack.getParent(); + parent.setVisible(true); + if (parent.getWidget() == null) { + // ask it to be rendered + parent.setToBeRendered(true); + // create the widget + context.get(IPresentationEngine.class).createGui(parent, + winShell, window.getContext()); + } + } + trimStack.setToBeRendered(true); + } + + private String getMinimizedElementSuffix(MUIElement element) { + String id = ID_SUFFIX; + MPerspective persp = modelService.getPerspectiveFor(element); + if (persp != null) { + id = '(' + persp.getElementId() + ')'; + } + return id; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/XTrimStack.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/XTrimStack.java index 6e2e4b1d4..4d452469b 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/XTrimStack.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/XTrimStack.java @@ -1,608 +1,608 @@ -package org.xmind.cathy.internal.ui.workbench.addons.minmax; - -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.services.events.IEventBroker; -import org.eclipse.e4.ui.di.UIEventTopic; -import org.eclipse.e4.ui.internal.workbench.swt.CSSRenderingUtils; -import org.eclipse.e4.ui.model.application.ui.MElementContainer; -import org.eclipse.e4.ui.model.application.ui.MGenericStack; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.MUILabel; -import org.eclipse.e4.ui.model.application.ui.SideValue; -import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; -import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack; -import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.UIEvents; -import org.eclipse.e4.ui.workbench.UIEvents.EventTags; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** - * Class for representing window trim containing minimized views and shared - * areas - */ -public class XTrimStack { - - /** - * Contribution URI for this class - */ - public static String CONTRIBUTION_URI_XTRIMSTACK = "bundleclass://org.xmind.cathy/org.xmind.cathy.internal.ui.workbench.addons.minmax.XTrimStack"; //$NON-NLS-1$ - - private ToolBar trimStackTB; - - private MUIElement mGenericStack; - - /** - * A map of created images from a part's icon URI path. - */ - private Map imageMap = new HashMap(); - - // Listens to ESC and closes the active fast view - private Listener escapeListener = new Listener() { - public void handleEvent(Event event) { - if (event.character == SWT.ESC) { - setStateForShowStack(false); - partService.requestActivation(); - } - } - }; - - @Inject - EModelService modelService; - - @Inject - EPartService partService; - - @Inject - MWindow window; - - @Inject - MToolControl toolControl; - - @Inject - protected IEventBroker eventBroker; - - @SuppressWarnings("unchecked") - @Inject - @Optional - private void handleTransientDataEvents( - @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TRANSIENTDATA) org.osgi.service.event.Event event) { - // Prevent exceptions on shutdown - if (trimStackTB == null || trimStackTB.isDisposed()) - return; - - Object changedElement = event.getProperty(UIEvents.EventTags.ELEMENT); - if (!(changedElement instanceof MUIElement)) { - return; - } - - String key; - if (UIEvents.isREMOVE(event)) { - key = ((Entry) event - .getProperty(UIEvents.EventTags.OLD_VALUE)).getKey(); - } else { - key = ((Entry) event - .getProperty(UIEvents.EventTags.NEW_VALUE)).getKey(); - } - - if (key.equals(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY)) { - ToolItem toolItem = getChangedToolItem((MUIElement) changedElement); - if (toolItem != null) - toolItem.setImage(getImage((MUILabel) toolItem.getData())); - } else if (key - .equals(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY)) { - ToolItem toolItem = getChangedToolItem((MUIElement) changedElement); - if (toolItem != null) - toolItem.setToolTipText( - getLabelText((MUILabel) toolItem.getData())); - } - } - - private ToolItem getChangedToolItem(MUIElement changedElement) { - ToolItem[] toolItems = trimStackTB.getItems(); - for (ToolItem toolItem : toolItems) { - if (changedElement.equals(toolItem.getData())) { - return toolItem; - } - } - return null; - } - - // Listener attached to every ToolItem in a TrimStack. Responsible for activating the - // appropriate part. - private SelectionListener toolItemSelectionListener = new SelectionListener() { - public void widgetSelected(SelectionEvent e) { - ToolItem toolItem = (ToolItem) e.widget; - MUIElement uiElement = (MUIElement) toolItem.getData(); - - // Clicking on the already showing item ? NOTE: the selection will already have been - // turned off by the time the event arrives - if (!toolItem.getSelection()) { - partService.requestActivation(); - setStateForShowStack(false); - return; - } - - if (uiElement instanceof MPart) { - partService.activate((MPart) uiElement); - } else if (uiElement instanceof MPerspective) { - uiElement.getParent().setSelectedElement(uiElement); - } - setStateForShowStack(true); - } - - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }; - - /** - * Add or remove someone of MGenericStack's children - * - * @param event - */ - @Inject - @Optional - private void handleChildrenEvents( - @UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) org.osgi.service.event.Event event) { - - if (mGenericStack == null || trimStackTB == null) - return; - - Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT); - - if (changedObj == mGenericStack) { - trimStackTB.getDisplay().asyncExec(new Runnable() { - public void run() { - updateTrimStackItems(); - } - }); - } - } - - /** - * Someone of MGenericStack's children changes state - * - * @param event - */ - @Inject - @Optional - private void handleToBeRenderedEvents( - @UIEventTopic(UIEvents.UIElement.TOPIC_TOBERENDERED) org.osgi.service.event.Event event) { - - if (mGenericStack == null || trimStackTB == null) - return; - - MUIElement changedElement = (MUIElement) event - .getProperty(UIEvents.EventTags.ELEMENT); - - MUIElement parentElement = changedElement.getParent(); - if (parentElement == mGenericStack) { - trimStackTB.getDisplay().asyncExec(new Runnable() { - public void run() { - updateTrimStackItems(); - } - }); - } - } - - /** - * Handle changes in tags of stack - * - * @param event - */ - @Inject - @Optional - private void subscribeTopicTagsChanged( - @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) org.osgi.service.event.Event event) { - Object changedObj = event.getProperty(EventTags.ELEMENT); - if (changedObj != mGenericStack) - return; - - if (UIEvents.isADD(event)) { - if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, - MinMaxAddon.STACK_HIDDEN)) { - fixToolItemSelection(); - } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, - MinMaxAddon.STACK_VISIBLE)) { - fixToolItemSelection(); - } - } - } - - @Inject - @Optional - private void handleWidgeEvents( - @UIEventTopic(UIEvents.UIElement.TOPIC_WIDGET) org.osgi.service.event.Event event) { - Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT); - if (changedObj != mGenericStack) - return; - - if (mGenericStack.getWidget() != null) { - trimStackTB.getDisplay().asyncExec(new Runnable() { - public void run() { - updateTrimStackItems(); - } - }); - } - } - - /** - * Someone of MGenericStack's children was selected - * - * @param event - */ - @Inject - @Optional - private void handleBringToTopEvents( - @UIEventTopic(UIEvents.UILifeCycle.BRINGTOTOP) org.osgi.service.event.Event event) { - MUIElement changedElement = (MUIElement) event - .getProperty(UIEvents.EventTags.ELEMENT); - - // Open if shared area - if (getLeafPart(mGenericStack) == changedElement - && !(mGenericStack instanceof MPerspectiveStack)) { - setStateForShowStack(true); - return; - } - - MUIElement selectedElement = null; - - if (mGenericStack instanceof MPlaceholder) { - selectedElement = ((MPlaceholder) mGenericStack).getRef(); - } else if (mGenericStack instanceof MPartStack) { - selectedElement = ((MPartStack) mGenericStack).getSelectedElement(); - } - - if (selectedElement == null) - return; - - if (selectedElement instanceof MPlaceholder) - selectedElement = ((MPlaceholder) selectedElement).getRef(); - - if (changedElement != selectedElement) - return; - - setStateForShowStack(true); - } - - @Inject - @Optional - private void handleAppShutDownAndStartedEvents( - @UIEventTopic(UIEvents.UILifeCycle.APP_SHUTDOWN_STARTED) org.osgi.service.event.Event event) { - setStateForShowStack(false); - } - - @PostConstruct - void createWidget(Composite parent, MToolControl me, - CSSRenderingUtils cssUtils) { - if (mGenericStack == null) { - mGenericStack = findElement(); - } - - MUIElement meParent = me.getParent(); - int orientation = SWT.HORIZONTAL; - if (meParent instanceof MTrimBar) { - MTrimBar bar = (MTrimBar) meParent; - if (bar.getSide() == SideValue.RIGHT - || bar.getSide() == SideValue.LEFT) - orientation = SWT.VERTICAL; - } - trimStackTB = new ToolBar(parent, orientation | SWT.FLAT | SWT.WRAP); - trimStackTB.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - setStateForShowStack(false); - - trimStackTB = null; - } - }); - - updateTrimStackItems(); - } - - @PreDestroy - void destroy() { - for (Image image : imageMap.values()) { - image.dispose(); - } - } - - public MUIElement getMinimizedElement() { - return mGenericStack; - } - - //Find stack - private MUIElement findElement() { - MUIElement result; - List ps = modelService.findElements(window, null, - MPerspectiveStack.class, null); - if (ps.size() == 0) { - String toolControlId = toolControl.getElementId(); - int index = toolControlId.indexOf('('); - String stackId = toolControlId.substring(0, index); - result = modelService.find(stackId, window); - } else { - String toolControlId = toolControl.getElementId(); - int index = toolControlId.indexOf('('); - String stackId = toolControlId.substring(0, index); - String perspId = toolControlId.substring(index + 1, - toolControlId.length() - 1); - - MPerspective persp = null; - List perspectives = modelService - .findElements(ps.get(0), perspId, MPerspective.class, null); - if (perspectives != null && !perspectives.isEmpty()) { - persp = perspectives.get(0); - } - - if (persp != null) { - result = modelService.find(stackId, persp); - } else { - result = modelService.find(stackId, window); - } - } - - return result; - } - - private String getLabelText(MUILabel label) { - // Use override text if available - if (label instanceof MUIElement) { - String text = getOverrideTitleToolTip((MUIElement) label); - if (text != null && text.length() > 0) - return text; - } - - String string = label.getLocalizedLabel(); - return string == null ? "" : string; //$NON-NLS-1$ - } - - private Image getImage(MUILabel element) { - // Use override image if available - if (element instanceof MUIElement) { - Image image = getOverrideImage((MUIElement) element); - if (image != null) - return image; - } - - String iconURI = element.getIconURI(); - if (iconURI != null && iconURI.length() > 0) { - Image image = imageMap.get(iconURI); - if (image == null) { - image = imageDescriptorFromURI(iconURI).createImage(); - imageMap.put(iconURI, image); - } - return image; - } - - return null; - } - - public ImageDescriptor imageDescriptorFromURI(String iconPath) { - try { - URI uri = new URI(iconPath); - return ImageDescriptor.createFromURL(new URL(uri.toString())); - } catch (MalformedURLException e) { - } catch (URISyntaxException e) { - } - return null; - } - - private MUILabel getLabelElement(MUIElement element) { - if (element instanceof MPlaceholder) - element = ((MPlaceholder) element).getRef(); - - return (MUILabel) (element instanceof MUILabel ? element : null); - } - - private void updateTrimStackItems() { - // Prevent exceptions on shutdown - if (trimStackTB == null || trimStackTB.isDisposed()) - return; - - while (trimStackTB.getItemCount() > 0) { - trimStackTB.getItem(trimStackTB.getItemCount() - 1).dispose(); - } - - if (mGenericStack instanceof MPlaceholder) { - MPlaceholder ph = (MPlaceholder) mGenericStack; - if (ph.getRef() instanceof MPart) { - MPart part = (MPart) ph.getRef(); - ToolItem ti = new ToolItem(trimStackTB, SWT.CHECK); - ti.setData(part); - ti.setImage(getImage(part)); - ti.setToolTipText(getLabelText(part)); - ti.addSelectionListener(toolItemSelectionListener); - } - } else if (mGenericStack instanceof MGenericStack) { - // Handle *both* PartStacks and PerspectiveStacks here... - MGenericStack theStack = (MGenericStack) mGenericStack; - - for (MUIElement stackElement : theStack.getChildren()) { - boolean trimStackExists = stackElement.getTags() - .contains(MinMaxAddon.TRIM_STACK_EXIST); - if (stackElement instanceof MPlaceholder) { - MUIElement part = ((MPlaceholder) stackElement).getRef(); - trimStackExists = part.getTags() - .contains(MinMaxAddon.TRIM_STACK_EXIST); - } - if (/* stackElement.isToBeRendered() || FIXME */ trimStackExists) { - MUILabel labelElement = getLabelElement(stackElement); - ToolItem newItem = new ToolItem(trimStackTB, SWT.CHECK); - newItem.setData(labelElement); - newItem.setImage(getImage(labelElement)); - newItem.setToolTipText(getLabelText(labelElement)); - newItem.addSelectionListener(toolItemSelectionListener); - } - } - } - - trimStackTB.pack(); - trimStackTB.getShell().layout(new Control[] { trimStackTB }, SWT.DEFER); - fixToolItemSelection(); - } - - /** - * Sets whether this stack should be visible or hidden - * - * @param show - * whether the stack should be visible - */ - public void setStateForShowStack(boolean show) { - Control ctrl = (Control) mGenericStack.getWidget(); - - Composite clientAreaComposite = getCAComposite(); - if (clientAreaComposite == null || clientAreaComposite.isDisposed()) - return; - - if (show) { - mGenericStack.getTags().remove(MinMaxAddon.STACK_HIDDEN); - mGenericStack.getTags().remove(MinMaxAddon.STACK_VISIBLE); - mGenericStack.getTags().add(MinMaxAddon.STACK_VISIBLE); - - ctrl.removeListener(SWT.Traverse, escapeListener); - ctrl.addListener(SWT.Traverse, escapeListener); - } else { - if (ctrl != null && !ctrl.isDisposed()) - ctrl.removeListener(SWT.Traverse, escapeListener); - mGenericStack.getTags().remove(MinMaxAddon.STACK_HIDDEN); - mGenericStack.getTags().remove(MinMaxAddon.STACK_VISIBLE); - mGenericStack.getTags().add(MinMaxAddon.STACK_HIDDEN); - } - } - - private void fixToolItemSelection() { - if (trimStackTB == null || trimStackTB.isDisposed()) - return; - - boolean toHide = mGenericStack.getTags() - .contains(MinMaxAddon.STACK_HIDDEN); - boolean toShow = mGenericStack.getTags() - .contains(MinMaxAddon.STACK_VISIBLE); - if (toHide) { - // Not open...no selection - for (ToolItem item : trimStackTB.getItems()) { - item.setSelection(false); - } - } else if (toShow) { - if (mGenericStack instanceof MPlaceholder) { - trimStackTB.getItem(1).setSelection(true); - } else if (isPerspectiveStack()) { - MPerspectiveStack pStack = (MPerspectiveStack) mGenericStack; - MUIElement selElement = pStack.getSelectedElement(); - for (ToolItem item : trimStackTB.getItems()) { - item.setSelection(item.getData() == selElement); - } - } else { - MPartStack partStack = (MPartStack) mGenericStack; - MUIElement selElement = partStack.getSelectedElement(); - if (selElement instanceof MPlaceholder) - selElement = ((MPlaceholder) selElement).getRef(); - - for (ToolItem item : trimStackTB.getItems()) { - boolean isSel = item.getData() == selElement; - item.setSelection(isSel); - } - } - } - } - - private boolean isPerspectiveStack() { - return mGenericStack instanceof MPerspectiveStack; - } - - private MPart getLeafPart(MUIElement element) { - if (element instanceof MPlaceholder) - return getLeafPart(((MPlaceholder) element).getRef()); - - if (element instanceof MElementContainer) - return getLeafPart( - ((MElementContainer) element).getSelectedElement()); - - if (element instanceof MPart) - return (MPart) element; - - return null; - } - - private Composite getCAComposite() { - if (trimStackTB == null) - return null; - - // Get the shell's client area composite - Shell theShell = trimStackTB.getShell(); - if (theShell.getLayout() instanceof TrimmedPartLayout) { - TrimmedPartLayout tpl = (TrimmedPartLayout) theShell.getLayout(); - if (!tpl.clientArea.isDisposed()) - return tpl.clientArea; - } - return null; - } - - private Image getOverrideImage(MUIElement element) { - Image result = null; - - Object imageObject = element.getTransientData() - .get(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY); - if (imageObject != null && imageObject instanceof Image - && !((Image) imageObject).isDisposed()) - result = (Image) imageObject; - return result; - } - - private String getOverrideTitleToolTip(MUIElement element) { - String result = null; - - Object stringObject = element.getTransientData() - .get(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY); - if (stringObject != null && stringObject instanceof String) - result = (String) stringObject; - - if (result == null || result.length() == 0) - return null; - - if (element instanceof MUILabel) { - String label = ((MUILabel) element).getLocalizedLabel(); - if (label != null && label.length() > 0) { - result = label + ' ' + '(' + result + ')'; - } - } - - return result; - } - -} +package org.xmind.cathy.internal.ui.workbench.addons.minmax; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.UIEventTopic; +import org.eclipse.e4.ui.internal.workbench.swt.CSSRenderingUtils; +import org.eclipse.e4.ui.model.application.ui.MElementContainer; +import org.eclipse.e4.ui.model.application.ui.MGenericStack; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.MUILabel; +import org.eclipse.e4.ui.model.application.ui.SideValue; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack; +import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.e4.ui.workbench.UIEvents.EventTags; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** + * Class for representing window trim containing minimized views and shared + * areas + */ +public class XTrimStack { + + /** + * Contribution URI for this class + */ + public static String CONTRIBUTION_URI_XTRIMSTACK = "bundleclass://org.xmind.cathy/org.xmind.cathy.internal.ui.workbench.addons.minmax.XTrimStack"; //$NON-NLS-1$ + + private ToolBar trimStackTB; + + private MUIElement mGenericStack; + + /** + * A map of created images from a part's icon URI path. + */ + private Map imageMap = new HashMap(); + + // Listens to ESC and closes the active fast view + private Listener escapeListener = new Listener() { + public void handleEvent(Event event) { + if (event.character == SWT.ESC) { + setStateForShowStack(false); + partService.requestActivation(); + } + } + }; + + @Inject + EModelService modelService; + + @Inject + EPartService partService; + + @Inject + MWindow window; + + @Inject + MToolControl toolControl; + + @Inject + protected IEventBroker eventBroker; + + @SuppressWarnings("unchecked") + @Inject + @Optional + private void handleTransientDataEvents( + @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TRANSIENTDATA) org.osgi.service.event.Event event) { + // Prevent exceptions on shutdown + if (trimStackTB == null || trimStackTB.isDisposed()) + return; + + Object changedElement = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(changedElement instanceof MUIElement)) { + return; + } + + String key; + if (UIEvents.isREMOVE(event)) { + key = ((Entry) event + .getProperty(UIEvents.EventTags.OLD_VALUE)).getKey(); + } else { + key = ((Entry) event + .getProperty(UIEvents.EventTags.NEW_VALUE)).getKey(); + } + + if (key.equals(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY)) { + ToolItem toolItem = getChangedToolItem((MUIElement) changedElement); + if (toolItem != null) + toolItem.setImage(getImage((MUILabel) toolItem.getData())); + } else if (key + .equals(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY)) { + ToolItem toolItem = getChangedToolItem((MUIElement) changedElement); + if (toolItem != null) + toolItem.setToolTipText( + getLabelText((MUILabel) toolItem.getData())); + } + } + + private ToolItem getChangedToolItem(MUIElement changedElement) { + ToolItem[] toolItems = trimStackTB.getItems(); + for (ToolItem toolItem : toolItems) { + if (changedElement.equals(toolItem.getData())) { + return toolItem; + } + } + return null; + } + + // Listener attached to every ToolItem in a TrimStack. Responsible for activating the + // appropriate part. + private SelectionListener toolItemSelectionListener = new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + ToolItem toolItem = (ToolItem) e.widget; + MUIElement uiElement = (MUIElement) toolItem.getData(); + + // Clicking on the already showing item ? NOTE: the selection will already have been + // turned off by the time the event arrives + if (!toolItem.getSelection()) { + partService.requestActivation(); + setStateForShowStack(false); + return; + } + + if (uiElement instanceof MPart) { + partService.activate((MPart) uiElement); + } else if (uiElement instanceof MPerspective) { + uiElement.getParent().setSelectedElement(uiElement); + } + setStateForShowStack(true); + } + + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }; + + /** + * Add or remove someone of MGenericStack's children + * + * @param event + */ + @Inject + @Optional + private void handleChildrenEvents( + @UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) org.osgi.service.event.Event event) { + + if (mGenericStack == null || trimStackTB == null) + return; + + Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT); + + if (changedObj == mGenericStack) { + trimStackTB.getDisplay().asyncExec(new Runnable() { + public void run() { + updateTrimStackItems(); + } + }); + } + } + + /** + * Someone of MGenericStack's children changes state + * + * @param event + */ + @Inject + @Optional + private void handleToBeRenderedEvents( + @UIEventTopic(UIEvents.UIElement.TOPIC_TOBERENDERED) org.osgi.service.event.Event event) { + + if (mGenericStack == null || trimStackTB == null) + return; + + MUIElement changedElement = (MUIElement) event + .getProperty(UIEvents.EventTags.ELEMENT); + + MUIElement parentElement = changedElement.getParent(); + if (parentElement == mGenericStack) { + trimStackTB.getDisplay().asyncExec(new Runnable() { + public void run() { + updateTrimStackItems(); + } + }); + } + } + + /** + * Handle changes in tags of stack + * + * @param event + */ + @Inject + @Optional + private void subscribeTopicTagsChanged( + @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) org.osgi.service.event.Event event) { + Object changedObj = event.getProperty(EventTags.ELEMENT); + if (changedObj != mGenericStack) + return; + + if (UIEvents.isADD(event)) { + if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, + MinMaxAddon.STACK_HIDDEN)) { + fixToolItemSelection(); + } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE, + MinMaxAddon.STACK_VISIBLE)) { + fixToolItemSelection(); + } + } + } + + @Inject + @Optional + private void handleWidgeEvents( + @UIEventTopic(UIEvents.UIElement.TOPIC_WIDGET) org.osgi.service.event.Event event) { + Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT); + if (changedObj != mGenericStack) + return; + + if (mGenericStack.getWidget() != null) { + trimStackTB.getDisplay().asyncExec(new Runnable() { + public void run() { + updateTrimStackItems(); + } + }); + } + } + + /** + * Someone of MGenericStack's children was selected + * + * @param event + */ + @Inject + @Optional + private void handleBringToTopEvents( + @UIEventTopic(UIEvents.UILifeCycle.BRINGTOTOP) org.osgi.service.event.Event event) { + MUIElement changedElement = (MUIElement) event + .getProperty(UIEvents.EventTags.ELEMENT); + + // Open if shared area + if (getLeafPart(mGenericStack) == changedElement + && !(mGenericStack instanceof MPerspectiveStack)) { + setStateForShowStack(true); + return; + } + + MUIElement selectedElement = null; + + if (mGenericStack instanceof MPlaceholder) { + selectedElement = ((MPlaceholder) mGenericStack).getRef(); + } else if (mGenericStack instanceof MPartStack) { + selectedElement = ((MPartStack) mGenericStack).getSelectedElement(); + } + + if (selectedElement == null) + return; + + if (selectedElement instanceof MPlaceholder) + selectedElement = ((MPlaceholder) selectedElement).getRef(); + + if (changedElement != selectedElement) + return; + + setStateForShowStack(true); + } + + @Inject + @Optional + private void handleAppShutDownAndStartedEvents( + @UIEventTopic(UIEvents.UILifeCycle.APP_SHUTDOWN_STARTED) org.osgi.service.event.Event event) { + setStateForShowStack(false); + } + + @PostConstruct + void createWidget(Composite parent, MToolControl me, + CSSRenderingUtils cssUtils) { + if (mGenericStack == null) { + mGenericStack = findElement(); + } + + MUIElement meParent = me.getParent(); + int orientation = SWT.HORIZONTAL; + if (meParent instanceof MTrimBar) { + MTrimBar bar = (MTrimBar) meParent; + if (bar.getSide() == SideValue.RIGHT + || bar.getSide() == SideValue.LEFT) + orientation = SWT.VERTICAL; + } + trimStackTB = new ToolBar(parent, orientation | SWT.FLAT | SWT.WRAP); + trimStackTB.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + setStateForShowStack(false); + + trimStackTB = null; + } + }); + + updateTrimStackItems(); + } + + @PreDestroy + void destroy() { + for (Image image : imageMap.values()) { + image.dispose(); + } + } + + public MUIElement getMinimizedElement() { + return mGenericStack; + } + + //Find stack + private MUIElement findElement() { + MUIElement result; + List ps = modelService.findElements(window, null, + MPerspectiveStack.class, null); + if (ps.size() == 0) { + String toolControlId = toolControl.getElementId(); + int index = toolControlId.indexOf('('); + String stackId = toolControlId.substring(0, index); + result = modelService.find(stackId, window); + } else { + String toolControlId = toolControl.getElementId(); + int index = toolControlId.indexOf('('); + String stackId = toolControlId.substring(0, index); + String perspId = toolControlId.substring(index + 1, + toolControlId.length() - 1); + + MPerspective persp = null; + List perspectives = modelService + .findElements(ps.get(0), perspId, MPerspective.class, null); + if (perspectives != null && !perspectives.isEmpty()) { + persp = perspectives.get(0); + } + + if (persp != null) { + result = modelService.find(stackId, persp); + } else { + result = modelService.find(stackId, window); + } + } + + return result; + } + + private String getLabelText(MUILabel label) { + // Use override text if available + if (label instanceof MUIElement) { + String text = getOverrideTitleToolTip((MUIElement) label); + if (text != null && text.length() > 0) + return text; + } + + String string = label.getLocalizedLabel(); + return string == null ? "" : string; //$NON-NLS-1$ + } + + private Image getImage(MUILabel element) { + // Use override image if available + if (element instanceof MUIElement) { + Image image = getOverrideImage((MUIElement) element); + if (image != null) + return image; + } + + String iconURI = element.getIconURI(); + if (iconURI != null && iconURI.length() > 0) { + Image image = imageMap.get(iconURI); + if (image == null) { + image = imageDescriptorFromURI(iconURI).createImage(); + imageMap.put(iconURI, image); + } + return image; + } + + return null; + } + + public ImageDescriptor imageDescriptorFromURI(String iconPath) { + try { + URI uri = new URI(iconPath); + return ImageDescriptor.createFromURL(new URL(uri.toString())); + } catch (MalformedURLException e) { + } catch (URISyntaxException e) { + } + return null; + } + + private MUILabel getLabelElement(MUIElement element) { + if (element instanceof MPlaceholder) + element = ((MPlaceholder) element).getRef(); + + return (MUILabel) (element instanceof MUILabel ? element : null); + } + + private void updateTrimStackItems() { + // Prevent exceptions on shutdown + if (trimStackTB == null || trimStackTB.isDisposed()) + return; + + while (trimStackTB.getItemCount() > 0) { + trimStackTB.getItem(trimStackTB.getItemCount() - 1).dispose(); + } + + if (mGenericStack instanceof MPlaceholder) { + MPlaceholder ph = (MPlaceholder) mGenericStack; + if (ph.getRef() instanceof MPart) { + MPart part = (MPart) ph.getRef(); + ToolItem ti = new ToolItem(trimStackTB, SWT.CHECK); + ti.setData(part); + ti.setImage(getImage(part)); + ti.setToolTipText(getLabelText(part)); + ti.addSelectionListener(toolItemSelectionListener); + } + } else if (mGenericStack instanceof MGenericStack) { + // Handle *both* PartStacks and PerspectiveStacks here... + MGenericStack theStack = (MGenericStack) mGenericStack; + + for (MUIElement stackElement : theStack.getChildren()) { + boolean trimStackExists = stackElement.getTags() + .contains(MinMaxAddon.TRIM_STACK_EXIST); + if (stackElement instanceof MPlaceholder) { + MUIElement part = ((MPlaceholder) stackElement).getRef(); + trimStackExists = part.getTags() + .contains(MinMaxAddon.TRIM_STACK_EXIST); + } + if (/* stackElement.isToBeRendered() || FIXME */ trimStackExists) { + MUILabel labelElement = getLabelElement(stackElement); + ToolItem newItem = new ToolItem(trimStackTB, SWT.CHECK); + newItem.setData(labelElement); + newItem.setImage(getImage(labelElement)); + newItem.setToolTipText(getLabelText(labelElement)); + newItem.addSelectionListener(toolItemSelectionListener); + } + } + } + + trimStackTB.pack(); + trimStackTB.getShell().layout(new Control[] { trimStackTB }, SWT.DEFER); + fixToolItemSelection(); + } + + /** + * Sets whether this stack should be visible or hidden + * + * @param show + * whether the stack should be visible + */ + public void setStateForShowStack(boolean show) { + Control ctrl = (Control) mGenericStack.getWidget(); + + Composite clientAreaComposite = getCAComposite(); + if (clientAreaComposite == null || clientAreaComposite.isDisposed()) + return; + + if (show) { + mGenericStack.getTags().remove(MinMaxAddon.STACK_HIDDEN); + mGenericStack.getTags().remove(MinMaxAddon.STACK_VISIBLE); + mGenericStack.getTags().add(MinMaxAddon.STACK_VISIBLE); + + ctrl.removeListener(SWT.Traverse, escapeListener); + ctrl.addListener(SWT.Traverse, escapeListener); + } else { + if (ctrl != null && !ctrl.isDisposed()) + ctrl.removeListener(SWT.Traverse, escapeListener); + mGenericStack.getTags().remove(MinMaxAddon.STACK_HIDDEN); + mGenericStack.getTags().remove(MinMaxAddon.STACK_VISIBLE); + mGenericStack.getTags().add(MinMaxAddon.STACK_HIDDEN); + } + } + + private void fixToolItemSelection() { + if (trimStackTB == null || trimStackTB.isDisposed()) + return; + + boolean toHide = mGenericStack.getTags() + .contains(MinMaxAddon.STACK_HIDDEN); + boolean toShow = mGenericStack.getTags() + .contains(MinMaxAddon.STACK_VISIBLE); + if (toHide) { + // Not open...no selection + for (ToolItem item : trimStackTB.getItems()) { + item.setSelection(false); + } + } else if (toShow) { + if (mGenericStack instanceof MPlaceholder) { + trimStackTB.getItem(1).setSelection(true); + } else if (isPerspectiveStack()) { + MPerspectiveStack pStack = (MPerspectiveStack) mGenericStack; + MUIElement selElement = pStack.getSelectedElement(); + for (ToolItem item : trimStackTB.getItems()) { + item.setSelection(item.getData() == selElement); + } + } else { + MPartStack partStack = (MPartStack) mGenericStack; + MUIElement selElement = partStack.getSelectedElement(); + if (selElement instanceof MPlaceholder) + selElement = ((MPlaceholder) selElement).getRef(); + + for (ToolItem item : trimStackTB.getItems()) { + boolean isSel = item.getData() == selElement; + item.setSelection(isSel); + } + } + } + } + + private boolean isPerspectiveStack() { + return mGenericStack instanceof MPerspectiveStack; + } + + private MPart getLeafPart(MUIElement element) { + if (element instanceof MPlaceholder) + return getLeafPart(((MPlaceholder) element).getRef()); + + if (element instanceof MElementContainer) + return getLeafPart( + ((MElementContainer) element).getSelectedElement()); + + if (element instanceof MPart) + return (MPart) element; + + return null; + } + + private Composite getCAComposite() { + if (trimStackTB == null) + return null; + + // Get the shell's client area composite + Shell theShell = trimStackTB.getShell(); + if (theShell.getLayout() instanceof TrimmedPartLayout) { + TrimmedPartLayout tpl = (TrimmedPartLayout) theShell.getLayout(); + if (!tpl.clientArea.isDisposed()) + return tpl.clientArea; + } + return null; + } + + private Image getOverrideImage(MUIElement element) { + Image result = null; + + Object imageObject = element.getTransientData() + .get(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY); + if (imageObject != null && imageObject instanceof Image + && !((Image) imageObject).isDisposed()) + result = (Image) imageObject; + return result; + } + + private String getOverrideTitleToolTip(MUIElement element) { + String result = null; + + Object stringObject = element.getTransientData() + .get(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY); + if (stringObject != null && stringObject instanceof String) + result = (String) stringObject; + + if (result == null || result.length() == 0) + return null; + + if (element instanceof MUILabel) { + String label = ((MUILabel) element).getLocalizedLabel(); + if (label != null && label.length() > 0) { + result = label + ' ' + '(' + result + ')'; + } + } + + return result; + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/DisabledHandler.java b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/DisabledHandler.java index a0ab37f92..79eaaef26 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/DisabledHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/DisabledHandler.java @@ -1,67 +1,67 @@ -package org.xmind.ui.internal.e4handlers; - -import java.util.Map; - -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.ui.commands.IElementUpdater; -import org.eclipse.ui.menus.UIElement; - -/** - * A special handler that can never be executed, typically used as a 'disabler' - * for a command. - * - * @author Frank Shaka - * @since 3.6.0 - */ -public class DisabledHandler implements IElementUpdater { - - /** - * An element updater delegate that performs the real updating job. - */ - private IElementUpdater updater; - - /** - * A boolean indicating that the handler is currently updating an UIElement. - */ - private boolean updating = false; - - /** - * Constructs a new instance of this class. - * - * @param updater - * an element updater to perform the real updating job, typically - * the real handler for this command - */ - public DisabledHandler(IElementUpdater updater) { - this.updater = updater; - } - - public void updateElement(UIElement element, Map parameters) { - // check if we're currently updating to break infinite recursion - if (updating) - return; - - if (updater != null) { - updating = true; - updater.updateElement(element, parameters); - updating = false; - } - } - - /** - * Will always return false. - * - * @return - */ - @CanExecute - public boolean canExecute() { - return false; - } - - @Execute - public void execute() { - // do nothing - } - +package org.xmind.ui.internal.e4handlers; + +import java.util.Map; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; + +/** + * A special handler that can never be executed, typically used as a 'disabler' + * for a command. + * + * @author Frank Shaka + * @since 3.6.0 + */ +public class DisabledHandler implements IElementUpdater { + + /** + * An element updater delegate that performs the real updating job. + */ + private IElementUpdater updater; + + /** + * A boolean indicating that the handler is currently updating an UIElement. + */ + private boolean updating = false; + + /** + * Constructs a new instance of this class. + * + * @param updater + * an element updater to perform the real updating job, typically + * the real handler for this command + */ + public DisabledHandler(IElementUpdater updater) { + this.updater = updater; + } + + public void updateElement(UIElement element, Map parameters) { + // check if we're currently updating to break infinite recursion + if (updating) + return; + + if (updater != null) { + updating = true; + updater.updateElement(element, parameters); + updating = false; + } + } + + /** + * Will always return false. + * + * @return + */ + @CanExecute + public boolean canExecute() { + return false; + } + + @Execute + public void execute() { + // do nothing + } + } \ No newline at end of file diff --git a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/HideDashboardHandler.java b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/HideDashboardHandler.java index 96a8a8910..c7b552fcd 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/HideDashboardHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/HideDashboardHandler.java @@ -1,21 +1,21 @@ -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.xmind.cathy.internal.ICathyConstants; - -public class HideDashboardHandler { - - @Execute - public void execute(@Optional MWindow window) { - if (window == null) - return; - - if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); - } - - } - -} +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.xmind.cathy.internal.ICathyConstants; + +public class HideDashboardHandler { + + @Execute + public void execute(@Optional MWindow window) { + if (window == null) + return; + + if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); + } + + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ShowDashboardPageHandler.java b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ShowDashboardPageHandler.java index f772adae0..475934245 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ShowDashboardPageHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ShowDashboardPageHandler.java @@ -1,72 +1,72 @@ -package org.xmind.ui.internal.e4handlers; - -import java.util.List; - -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.ICathyConstants; - -public class ShowDashboardPageHandler { - - @Execute - public void execute(@Optional MWindow window, - @Optional ParameterizedCommand command) { - Object pageId = command == null ? null - : command.getParameterMap() - .get(ICathyConstants.PARAMETER_DASHBOARD_PAGE_ID); - showDashboardPage(window, - pageId instanceof String ? (String) pageId : null); - } - - public static void showDashboardPage(MWindow window, String pageId) { - if (window == null) { - CathyPlugin.log( - "Failed to find active window in ShowDashboardPageHandler."); //$NON-NLS-1$ - return; - } - - List tags = window.getTags(); - if (!tags.contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - tags.add(ICathyConstants.TAG_SHOW_DASHBOARD); - } - - if (pageId == null) - return; - - EModelService modelService = window.getContext() - .get(EModelService.class); - if (modelService == null) { - CathyPlugin.log( - "Failed to find EModelService in ShowDashboardPageHandler."); //$NON-NLS-1$ - return; - } - - List dashboardParts = modelService.findElements(window, - ICathyConstants.ID_DASHBOARD_PART, MPart.class, null); - if (dashboardParts.isEmpty()) { - CathyPlugin.log( - "Failed to find Dashboard part in ShowDashboardPageHandler."); //$NON-NLS-1$ - return; - } - - MPart dashboardPart = dashboardParts.get(0); - - String oldPageId = (String) dashboardPart.getTransientData() - .get(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); - if (pageId.equals(oldPageId)) { - ////todo - return; - } - - dashboardPart.getTransientData() - .remove(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); - dashboardPart.getTransientData() - .put(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID, pageId); - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.util.List; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.ICathyConstants; + +public class ShowDashboardPageHandler { + + @Execute + public void execute(@Optional MWindow window, + @Optional ParameterizedCommand command) { + Object pageId = command == null ? null + : command.getParameterMap() + .get(ICathyConstants.PARAMETER_DASHBOARD_PAGE_ID); + showDashboardPage(window, + pageId instanceof String ? (String) pageId : null); + } + + public static void showDashboardPage(MWindow window, String pageId) { + if (window == null) { + CathyPlugin.log( + "Failed to find active window in ShowDashboardPageHandler."); //$NON-NLS-1$ + return; + } + + List tags = window.getTags(); + if (!tags.contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + tags.add(ICathyConstants.TAG_SHOW_DASHBOARD); + } + + if (pageId == null) + return; + + EModelService modelService = window.getContext() + .get(EModelService.class); + if (modelService == null) { + CathyPlugin.log( + "Failed to find EModelService in ShowDashboardPageHandler."); //$NON-NLS-1$ + return; + } + + List dashboardParts = modelService.findElements(window, + ICathyConstants.ID_DASHBOARD_PART, MPart.class, null); + if (dashboardParts.isEmpty()) { + CathyPlugin.log( + "Failed to find Dashboard part in ShowDashboardPageHandler."); //$NON-NLS-1$ + return; + } + + MPart dashboardPart = dashboardParts.get(0); + + String oldPageId = (String) dashboardPart.getTransientData() + .get(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); + if (pageId.equals(oldPageId)) { + ////todo + return; + } + + dashboardPart.getTransientData() + .remove(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID); + dashboardPart.getTransientData() + .put(ICathyConstants.DATA_DASHBOARD_SELECTED_PAGE_ID, pageId); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ToggleDashboardHandler.java b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ToggleDashboardHandler.java index 73c0d26fd..0b89faf33 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ToggleDashboardHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/ToggleDashboardHandler.java @@ -1,27 +1,27 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.ui.basic.MWindow; -import org.xmind.cathy.internal.CathyPlugin; -import org.xmind.cathy.internal.ICathyConstants; - -public class ToggleDashboardHandler { - - @Execute - public void execute(@Optional MWindow window) { - if (window == null) { - CathyPlugin.log( - "Failed to locate active window when toggling the Dashboard."); //$NON-NLS-1$ - return; - } - - if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { - window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); - } else { - window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); - } - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.xmind.cathy.internal.CathyPlugin; +import org.xmind.cathy.internal.ICathyConstants; + +public class ToggleDashboardHandler { + + @Execute + public void execute(@Optional MWindow window) { + if (window == null) { + CathyPlugin.log( + "Failed to locate active window when toggling the Dashboard."); //$NON-NLS-1$ + return; + } + + if (window.getTags().contains(ICathyConstants.TAG_SHOW_DASHBOARD)) { + window.getTags().remove(ICathyConstants.TAG_SHOW_DASHBOARD); + } else { + window.getTags().add(ICathyConstants.TAG_SHOW_DASHBOARD); + } + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/XResourceHandler.java b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/XResourceHandler.java index b8298e33e..9d866ab03 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/XResourceHandler.java +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/XResourceHandler.java @@ -1,355 +1,355 @@ -package org.xmind.ui.internal.e4handlers; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Collections; -import java.util.Map; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.inject.Named; - -import org.eclipse.core.internal.runtime.PlatformURLPluginConnection; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.e4.core.contexts.ContextInjectionFactory; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.core.services.log.Logger; -import org.eclipse.e4.ui.internal.workbench.CommandLineOptionModelProcessor; -import org.eclipse.e4.ui.internal.workbench.E4Workbench; -import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory; -import org.eclipse.e4.ui.internal.workbench.ModelAssembler; -import org.eclipse.e4.ui.internal.workbench.URIHelper; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.MApplicationElement; -import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl; -import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl; -import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl; -import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicPackageImpl; -import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl; -import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuPackageImpl; -import org.eclipse.e4.ui.workbench.IModelResourceHandler; -import org.eclipse.e4.ui.workbench.IWorkbench; -import org.eclipse.emf.common.util.TreeIterator; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.URIConverter; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.osgi.service.datalocation.Location; -import org.osgi.framework.Bundle; -import org.xmind.cathy.internal.CathyPlugin; - -/** - * This class is responsible to load and save the model - */ -@SuppressWarnings("restriction") -public class XResourceHandler implements IModelResourceHandler { - - private static final String WORKBENCH_XMI = "workbench.xmi"; //$NON-NLS-1$ - private ResourceSetImpl resourceSetImpl; - private Resource resource; - - @Inject - private Logger logger; - - @Inject - private IEclipseContext context; - - @Inject - @Named(E4Workbench.INITIAL_WORKBENCH_MODEL_URI) - private URI applicationDefinitionInstance; - - @Inject - @Optional - @Named(E4Workbench.INSTANCE_LOCATION) - private Location instanceLocation; - - /** - * Dictates whether the model should be stored using EMF or with the merging - * algorithm. https://bugs.eclipse.org/bugs/show_bug.cgi?id=295524 - */ - final private boolean saveAndRestore; - final private boolean clearPersistedState; - - /** - * Constructor. - * - * @param saveAndRestore - * @param clearPersistedState - */ - @Inject - public XResourceHandler( - @Named(IWorkbench.PERSIST_STATE) boolean saveAndRestore, - @Named(IWorkbench.CLEAR_PERSISTED_STATE) boolean clearPersistedState) { - this.saveAndRestore = saveAndRestore; - this.clearPersistedState = clearPersistedState; - } - - @PostConstruct - void init() { - resourceSetImpl = new ResourceSetImpl(); - resourceSetImpl.getResourceFactoryRegistry().getExtensionToFactoryMap() - .put(Resource.Factory.Registry.DEFAULT_EXTENSION, - new E4XMIResourceFactory()); - - resourceSetImpl.getPackageRegistry().put(ApplicationPackageImpl.eNS_URI, - ApplicationPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put(CommandsPackageImpl.eNS_URI, - CommandsPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put(UiPackageImpl.eNS_URI, - UiPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put(MenuPackageImpl.eNS_URI, - MenuPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put(BasicPackageImpl.eNS_URI, - BasicPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put(AdvancedPackageImpl.eNS_URI, - AdvancedPackageImpl.eINSTANCE); - resourceSetImpl.getPackageRegistry().put( - org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eNS_URI, - org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eINSTANCE); - - } - - /** - * @return {@code true} if the current application model has top-level - * windows. - */ - public boolean hasTopLevelWindows() { - return hasTopLevelWindows(resource); - } - - /** - * @return {@code true} if the specified application model has top-level - * windows. - */ - private boolean hasTopLevelWindows(Resource applicationResource) { - if (applicationResource == null - || applicationResource.getContents() == null) { - // If the application resource doesn't exist or has no contents, then it has no - // top-level windows (and we are in an error state). - return false; - } - MApplication application = (MApplication) applicationResource - .getContents().get(0); - return !application.getChildren().isEmpty(); - } - - @Override - public Resource loadMostRecentModel() { - File workbenchData = null; - URI restoreLocation = null; - - if (saveAndRestore) { - workbenchData = getWorkbenchSaveLocation(); - restoreLocation = URI - .createFileURI(workbenchData.getAbsolutePath()); - } - - if (clearPersistedState && workbenchData != null - && workbenchData.exists()) { - workbenchData.delete(); - } - - // last stored time-stamp - long restoreLastModified = restoreLocation == null ? 0L - : new File(restoreLocation.toFileString()).lastModified(); - - // See bug 380663, bug 381219 - // long lastApplicationModification = getLastApplicationModification(); - // boolean restore = restoreLastModified > lastApplicationModification; - boolean restore = restoreLastModified > 0; - boolean initialModel; - - resource = null; - if (restore && saveAndRestore) { - resource = loadResource(restoreLocation); - // If the saved model does not have any top-level windows, Eclipse will exit - // immediately, so throw out the persisted state and reinitialize with the defaults. - if (!hasTopLevelWindows(resource)) { - if (logger != null) { - logger.error(new Exception(), // log a stack trace to help debug the corruption - "The persisted workbench has no top-level windows, so reinitializing with defaults."); //$NON-NLS-1$ - } - resource = null; - } - } - if (resource == null) { - Resource applicationResource = loadResource( - applicationDefinitionInstance); - MApplication theApp = (MApplication) applicationResource - .getContents().get(0); - resource = createResourceWithApp(theApp); - //Prevent 3.x workbench from using WorkbenchMigrationProcessor to migrate org.eclipse.ui.workbench/workbench.xml -// context.set(E4Workbench.NO_SAVED_MODEL_FOUND, Boolean.TRUE); - initialModel = true; - } else { - initialModel = false; - } - - // Add model items described in the model extension point - // This has to be done before commands are put into the context - MApplication appElement = (MApplication) resource.getContents().get(0); - - this.context.set(MApplication.class, appElement); - ModelAssembler contribProcessor = ContextInjectionFactory - .make(ModelAssembler.class, context); - contribProcessor.processModel(initialModel); - - if (!hasTopLevelWindows(resource) && logger != null) { - logger.error(new Exception(), // log a stack trace to help debug the - // corruption - "Initializing from the application definition instance yields no top-level windows! " //$NON-NLS-1$ - + "Continuing execution, but the missing windows may cause other initialization failures."); //$NON-NLS-1$ - } - - if (!clearPersistedState) { - CommandLineOptionModelProcessor processor = ContextInjectionFactory - .make(CommandLineOptionModelProcessor.class, context); - processor.process(); - } - - return resource; - } - - @Override - public void save() throws IOException { - if (saveAndRestore) - resource.save(null); - } - - /** - * Creates a resource with an app Model, used for saving copies of the main - * app model. - * - * @param theApp - * the application model to add to the resource - * @return a resource with a proper save path with the model as contents - */ - @Override - public Resource createResourceWithApp(MApplication theApp) { - Resource res = createResource(); - res.getContents().add((EObject) theApp); - return res; - } - - private Resource createResource() { - if (saveAndRestore) { - URI saveLocation = URI.createFileURI( - getWorkbenchSaveLocation().getAbsolutePath()); - return resourceSetImpl.createResource(saveLocation); - } - return resourceSetImpl.createResource(URI.createURI(WORKBENCH_XMI)); - } - - private File getWorkbenchSaveLocation() { - File workbenchData = new File(getBaseLocation(), WORKBENCH_XMI); - return workbenchData; - } - - private File getBaseLocation() { - File baseLocation; - try { - baseLocation = new File(URIUtil.toURI(instanceLocation.getURL())); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - baseLocation = new File(baseLocation, ".metadata"); //$NON-NLS-1$ - baseLocation = new File(baseLocation, ".plugins"); //$NON-NLS-1$ - baseLocation = new File(baseLocation, "org.xmind.cathy"); //$NON-NLS-1$ - baseLocation = new File(baseLocation, "e4Model"); //$NON-NLS-1$ - baseLocation = new File(baseLocation, - CathyPlugin.getDefault().getBundle().getVersion().toString()); - return baseLocation; - } - - // Ensures that even models with error are loaded! - private Resource loadResource(URI uri) { - Resource resource; - try { - resource = getResource(uri); - } catch (Exception e) { - // TODO We could use diagnostics for better analyzing the error - logger.error(e, "Unable to load resource " + uri.toString()); //$NON-NLS-1$ - return null; - } - - // TODO once we switch from deltas, we only need this once on the default model? - String contributorURI = URIHelper.EMFtoPlatform(uri); - if (contributorURI != null) { - TreeIterator it = EcoreUtil - .getAllContents(resource.getContents()); - while (it.hasNext()) { - EObject o = it.next(); - if (o instanceof MApplicationElement) { - ((MApplicationElement) o).setContributorURI(contributorURI); - } - } - } - return resource; - } - - private Resource getResource(URI uri) throws Exception { - Resource resource; - if (saveAndRestore) { - resource = resourceSetImpl.getResource(uri, true); - } else { - // Workaround for java.lang.IllegalStateException: No instance data can be specified - // thrown by org.eclipse.core.internal.runtime.DataArea.assertLocationInitialized - // The DataArea.assertLocationInitialized is called by ResourceSetImpl.getResource(URI, - // boolean) - resource = resourceSetImpl.createResource(uri); - resource.load(new URL(uri.toString()).openStream(), - resourceSetImpl.getLoadOptions()); - } - - return resource; - } - - protected long getLastApplicationModification() { - long appLastModified = 0L; - ResourceSetImpl resourceSetImpl = new ResourceSetImpl(); - - Map attributes = resourceSetImpl.getURIConverter() - .getAttributes(applicationDefinitionInstance, - Collections.singletonMap( - URIConverter.OPTION_REQUESTED_ATTRIBUTES, - Collections.singleton( - URIConverter.ATTRIBUTE_TIME_STAMP))); - - Object timestamp = attributes.get(URIConverter.ATTRIBUTE_TIME_STAMP); - if (timestamp instanceof Long) { - appLastModified = ((Long) timestamp).longValue(); - } else if (applicationDefinitionInstance.isPlatformPlugin()) { - try { - java.net.URL url = new java.net.URL( - applicationDefinitionInstance.toString()); - // can't just use 'url.openConnection()' as it usually returns a - // PlatformURLPluginConnection which doesn't expose the - // last-modification time. So we try to resolve the file through - // the bundle to obtain a BundleURLConnection instead. - Object[] obj = PlatformURLPluginConnection - .parse(url.getFile().trim(), url); - Bundle b = (Bundle) obj[0]; - // first try to resolve as an bundle file entry, then as a resource using - // the bundle's classpath - java.net.URL resolved = b.getEntry((String) obj[1]); - if (resolved == null) { - resolved = b.getResource((String) obj[1]); - } - if (resolved != null) { - URLConnection openConnection = resolved.openConnection(); - appLastModified = openConnection.getLastModified(); - } - } catch (Exception e) { - // ignore - } - } - - return appLastModified; - } -} +package org.xmind.ui.internal.e4handlers; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Collections; +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.core.internal.runtime.PlatformURLPluginConnection; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.log.Logger; +import org.eclipse.e4.ui.internal.workbench.CommandLineOptionModelProcessor; +import org.eclipse.e4.ui.internal.workbench.E4Workbench; +import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory; +import org.eclipse.e4.ui.internal.workbench.ModelAssembler; +import org.eclipse.e4.ui.internal.workbench.URIHelper; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.MApplicationElement; +import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl; +import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl; +import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl; +import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicPackageImpl; +import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl; +import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuPackageImpl; +import org.eclipse.e4.ui.workbench.IModelResourceHandler; +import org.eclipse.e4.ui.workbench.IWorkbench; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.osgi.service.datalocation.Location; +import org.osgi.framework.Bundle; +import org.xmind.cathy.internal.CathyPlugin; + +/** + * This class is responsible to load and save the model + */ +@SuppressWarnings("restriction") +public class XResourceHandler implements IModelResourceHandler { + + private static final String WORKBENCH_XMI = "workbench.xmi"; //$NON-NLS-1$ + private ResourceSetImpl resourceSetImpl; + private Resource resource; + + @Inject + private Logger logger; + + @Inject + private IEclipseContext context; + + @Inject + @Named(E4Workbench.INITIAL_WORKBENCH_MODEL_URI) + private URI applicationDefinitionInstance; + + @Inject + @Optional + @Named(E4Workbench.INSTANCE_LOCATION) + private Location instanceLocation; + + /** + * Dictates whether the model should be stored using EMF or with the merging + * algorithm. https://bugs.eclipse.org/bugs/show_bug.cgi?id=295524 + */ + final private boolean saveAndRestore; + final private boolean clearPersistedState; + + /** + * Constructor. + * + * @param saveAndRestore + * @param clearPersistedState + */ + @Inject + public XResourceHandler( + @Named(IWorkbench.PERSIST_STATE) boolean saveAndRestore, + @Named(IWorkbench.CLEAR_PERSISTED_STATE) boolean clearPersistedState) { + this.saveAndRestore = saveAndRestore; + this.clearPersistedState = clearPersistedState; + } + + @PostConstruct + void init() { + resourceSetImpl = new ResourceSetImpl(); + resourceSetImpl.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put(Resource.Factory.Registry.DEFAULT_EXTENSION, + new E4XMIResourceFactory()); + + resourceSetImpl.getPackageRegistry().put(ApplicationPackageImpl.eNS_URI, + ApplicationPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put(CommandsPackageImpl.eNS_URI, + CommandsPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put(UiPackageImpl.eNS_URI, + UiPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put(MenuPackageImpl.eNS_URI, + MenuPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put(BasicPackageImpl.eNS_URI, + BasicPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put(AdvancedPackageImpl.eNS_URI, + AdvancedPackageImpl.eINSTANCE); + resourceSetImpl.getPackageRegistry().put( + org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eNS_URI, + org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eINSTANCE); + + } + + /** + * @return {@code true} if the current application model has top-level + * windows. + */ + public boolean hasTopLevelWindows() { + return hasTopLevelWindows(resource); + } + + /** + * @return {@code true} if the specified application model has top-level + * windows. + */ + private boolean hasTopLevelWindows(Resource applicationResource) { + if (applicationResource == null + || applicationResource.getContents() == null) { + // If the application resource doesn't exist or has no contents, then it has no + // top-level windows (and we are in an error state). + return false; + } + MApplication application = (MApplication) applicationResource + .getContents().get(0); + return !application.getChildren().isEmpty(); + } + + @Override + public Resource loadMostRecentModel() { + File workbenchData = null; + URI restoreLocation = null; + + if (saveAndRestore) { + workbenchData = getWorkbenchSaveLocation(); + restoreLocation = URI + .createFileURI(workbenchData.getAbsolutePath()); + } + + if (clearPersistedState && workbenchData != null + && workbenchData.exists()) { + workbenchData.delete(); + } + + // last stored time-stamp + long restoreLastModified = restoreLocation == null ? 0L + : new File(restoreLocation.toFileString()).lastModified(); + + // See bug 380663, bug 381219 + // long lastApplicationModification = getLastApplicationModification(); + // boolean restore = restoreLastModified > lastApplicationModification; + boolean restore = restoreLastModified > 0; + boolean initialModel; + + resource = null; + if (restore && saveAndRestore) { + resource = loadResource(restoreLocation); + // If the saved model does not have any top-level windows, Eclipse will exit + // immediately, so throw out the persisted state and reinitialize with the defaults. + if (!hasTopLevelWindows(resource)) { + if (logger != null) { + logger.error(new Exception(), // log a stack trace to help debug the corruption + "The persisted workbench has no top-level windows, so reinitializing with defaults."); //$NON-NLS-1$ + } + resource = null; + } + } + if (resource == null) { + Resource applicationResource = loadResource( + applicationDefinitionInstance); + MApplication theApp = (MApplication) applicationResource + .getContents().get(0); + resource = createResourceWithApp(theApp); + //Prevent 3.x workbench from using WorkbenchMigrationProcessor to migrate org.eclipse.ui.workbench/workbench.xml +// context.set(E4Workbench.NO_SAVED_MODEL_FOUND, Boolean.TRUE); + initialModel = true; + } else { + initialModel = false; + } + + // Add model items described in the model extension point + // This has to be done before commands are put into the context + MApplication appElement = (MApplication) resource.getContents().get(0); + + this.context.set(MApplication.class, appElement); + ModelAssembler contribProcessor = ContextInjectionFactory + .make(ModelAssembler.class, context); + contribProcessor.processModel(initialModel); + + if (!hasTopLevelWindows(resource) && logger != null) { + logger.error(new Exception(), // log a stack trace to help debug the + // corruption + "Initializing from the application definition instance yields no top-level windows! " //$NON-NLS-1$ + + "Continuing execution, but the missing windows may cause other initialization failures."); //$NON-NLS-1$ + } + + if (!clearPersistedState) { + CommandLineOptionModelProcessor processor = ContextInjectionFactory + .make(CommandLineOptionModelProcessor.class, context); + processor.process(); + } + + return resource; + } + + @Override + public void save() throws IOException { + if (saveAndRestore) + resource.save(null); + } + + /** + * Creates a resource with an app Model, used for saving copies of the main + * app model. + * + * @param theApp + * the application model to add to the resource + * @return a resource with a proper save path with the model as contents + */ + @Override + public Resource createResourceWithApp(MApplication theApp) { + Resource res = createResource(); + res.getContents().add((EObject) theApp); + return res; + } + + private Resource createResource() { + if (saveAndRestore) { + URI saveLocation = URI.createFileURI( + getWorkbenchSaveLocation().getAbsolutePath()); + return resourceSetImpl.createResource(saveLocation); + } + return resourceSetImpl.createResource(URI.createURI(WORKBENCH_XMI)); + } + + private File getWorkbenchSaveLocation() { + File workbenchData = new File(getBaseLocation(), WORKBENCH_XMI); + return workbenchData; + } + + private File getBaseLocation() { + File baseLocation; + try { + baseLocation = new File(URIUtil.toURI(instanceLocation.getURL())); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + baseLocation = new File(baseLocation, ".metadata"); //$NON-NLS-1$ + baseLocation = new File(baseLocation, ".plugins"); //$NON-NLS-1$ + baseLocation = new File(baseLocation, "org.xmind.cathy"); //$NON-NLS-1$ + baseLocation = new File(baseLocation, "e4Model"); //$NON-NLS-1$ + baseLocation = new File(baseLocation, + CathyPlugin.getDefault().getBundle().getVersion().toString()); + return baseLocation; + } + + // Ensures that even models with error are loaded! + private Resource loadResource(URI uri) { + Resource resource; + try { + resource = getResource(uri); + } catch (Exception e) { + // TODO We could use diagnostics for better analyzing the error + logger.error(e, "Unable to load resource " + uri.toString()); //$NON-NLS-1$ + return null; + } + + // TODO once we switch from deltas, we only need this once on the default model? + String contributorURI = URIHelper.EMFtoPlatform(uri); + if (contributorURI != null) { + TreeIterator it = EcoreUtil + .getAllContents(resource.getContents()); + while (it.hasNext()) { + EObject o = it.next(); + if (o instanceof MApplicationElement) { + ((MApplicationElement) o).setContributorURI(contributorURI); + } + } + } + return resource; + } + + private Resource getResource(URI uri) throws Exception { + Resource resource; + if (saveAndRestore) { + resource = resourceSetImpl.getResource(uri, true); + } else { + // Workaround for java.lang.IllegalStateException: No instance data can be specified + // thrown by org.eclipse.core.internal.runtime.DataArea.assertLocationInitialized + // The DataArea.assertLocationInitialized is called by ResourceSetImpl.getResource(URI, + // boolean) + resource = resourceSetImpl.createResource(uri); + resource.load(new URL(uri.toString()).openStream(), + resourceSetImpl.getLoadOptions()); + } + + return resource; + } + + protected long getLastApplicationModification() { + long appLastModified = 0L; + ResourceSetImpl resourceSetImpl = new ResourceSetImpl(); + + Map attributes = resourceSetImpl.getURIConverter() + .getAttributes(applicationDefinitionInstance, + Collections.singletonMap( + URIConverter.OPTION_REQUESTED_ATTRIBUTES, + Collections.singleton( + URIConverter.ATTRIBUTE_TIME_STAMP))); + + Object timestamp = attributes.get(URIConverter.ATTRIBUTE_TIME_STAMP); + if (timestamp instanceof Long) { + appLastModified = ((Long) timestamp).longValue(); + } else if (applicationDefinitionInstance.isPlatformPlugin()) { + try { + java.net.URL url = new java.net.URL( + applicationDefinitionInstance.toString()); + // can't just use 'url.openConnection()' as it usually returns a + // PlatformURLPluginConnection which doesn't expose the + // last-modification time. So we try to resolve the file through + // the bundle to obtain a BundleURLConnection instead. + Object[] obj = PlatformURLPluginConnection + .parse(url.getFile().trim(), url); + Bundle b = (Bundle) obj[0]; + // first try to resolve as an bundle file entry, then as a resource using + // the bundle's classpath + java.net.URL resolved = b.getEntry((String) obj[1]); + if (resolved == null) { + resolved = b.getResource((String) obj[1]); + } + if (resolved != null) { + URLConnection openConnection = resolved.openConnection(); + appLastModified = openConnection.getLastModified(); + } + } catch (Exception e) { + // ignore + } + } + + return appLastModified; + } +} diff --git a/bundles/org.xmind.cathy/thirdPartySoftwareProviders.txt b/bundles/org.xmind.cathy/thirdPartySoftwareProviders.txt index 28bd2644e..3ce2e7559 100644 --- a/bundles/org.xmind.cathy/thirdPartySoftwareProviders.txt +++ b/bundles/org.xmind.cathy/thirdPartySoftwareProviders.txt @@ -1,14 +1,14 @@ -Apache Software Foundation http://www.apache.org/ -Apple Inc. http://www.apple.com/ -Aspose Corporate http://www.aspose.com/ -Coobird.net http://http://www.coobird.net/ -Douglas Crockford https://github.com/douglascrockford/JSON-java -Eclipse Foundation http://www.eclipse.org/ -Erich Seifert http://trac.erichseifert.de/vectorgraphics2d/ -Evernote https://evernote.com/ -FreeHEP http://www.freehep.org/ -JavaZOOM http://www.javazoom.net/ -Legion of the Bouncy Castle http://www.bouncycastle.org/ -Mindaugas Idzelis and others http://jazzy.sourceforge.net/ -Pablo Fernandez http://fernandezpablo85.github.io/about.html +Apache Software Foundation http://www.apache.org/ +Apple Inc. http://www.apple.com/ +Aspose Corporate http://www.aspose.com/ +Coobird.net http://http://www.coobird.net/ +Douglas Crockford https://github.com/douglascrockford/JSON-java +Eclipse Foundation http://www.eclipse.org/ +Erich Seifert http://trac.erichseifert.de/vectorgraphics2d/ +Evernote https://evernote.com/ +FreeHEP http://www.freehep.org/ +JavaZOOM http://www.javazoom.net/ +Legion of the Bouncy Castle http://www.bouncycastle.org/ +Mindaugas Idzelis and others http://jazzy.sourceforge.net/ +Pablo Fernandez http://fernandezpablo85.github.io/about.html Robert Hegemann and other LAME Developers http://lame.sourceforge.net/ \ No newline at end of file diff --git a/bundles/org.xmind.core.command.remote/.classpath b/bundles/org.xmind.core.command.remote/.classpath index 49885ec45..0846204f9 100644 --- a/bundles/org.xmind.core.command.remote/.classpath +++ b/bundles/org.xmind.core.command.remote/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/bundles/org.xmind.core.command.remote/.gitignore b/bundles/org.xmind.core.command.remote/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.command.remote/.gitignore +++ b/bundles/org.xmind.core.command.remote/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.command.remote/.options b/bundles/org.xmind.core.command.remote/.options index fdff784e9..84d898aec 100644 --- a/bundles/org.xmind.core.command.remote/.options +++ b/bundles/org.xmind.core.command.remote/.options @@ -1,5 +1,5 @@ -# Turn on debugging for remote command service plugin: -org.xmind.core.command.remote/debug=false -org.xmind.core.command.remote/debug/incomingCommandHandler=false -org.xmind.core.command.remote/debug/outgoingCommandHandler=false -org.xmind.core.command.remote/debug/outgoingSocketCommandHandler=false +# Turn on debugging for remote command service plugin: +org.xmind.core.command.remote/debug=false +org.xmind.core.command.remote/debug/incomingCommandHandler=false +org.xmind.core.command.remote/debug/outgoingCommandHandler=false +org.xmind.core.command.remote/debug/outgoingSocketCommandHandler=false diff --git a/bundles/org.xmind.core.command.remote/.project b/bundles/org.xmind.core.command.remote/.project index 9f6b0c7d1..1942a7534 100644 --- a/bundles/org.xmind.core.command.remote/.project +++ b/bundles/org.xmind.core.command.remote/.project @@ -1,28 +1,28 @@ - - - org.xmind.core.command.remote - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.core.command.remote + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.core.prefs index 9e961115c..23514476a 100644 --- a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.core.prefs @@ -1,322 +1,322 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.command.remote/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF b/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF index e8a80c475..23777734f 100644 --- a/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF @@ -1,16 +1,16 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name -Bundle-SymbolicName: org.xmind.core.command.remote;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.core.internal.command.remote.RemoteCommandPlugin -Bundle-Vendor: %Bundle-Vendor -Require-Bundle: org.eclipse.core.runtime, - org.xmind.core.command;bundle-version="[3.7.0,3.8.0)";visibility:=reexport -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.core.command.remote, - org.xmind.core.command.remote.socket, - org.xmind.core.command.transfer, - org.xmind.core.internal.command.remote;x-internal:=true -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.xmind.core.command.remote;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.core.internal.command.remote.RemoteCommandPlugin +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.core.runtime, + org.xmind.core.command;bundle-version="[3.7.0,3.8.0)";visibility:=reexport +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.core.command.remote, + org.xmind.core.command.remote.socket, + org.xmind.core.command.transfer, + org.xmind.core.internal.command.remote;x-internal:=true +Bundle-Localization: plugin diff --git a/bundles/org.xmind.core.command.remote/about.html b/bundles/org.xmind.core.command.remote/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.command.remote/about.html +++ b/bundles/org.xmind.core.command.remote/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.command.remote/build.properties b/bundles/org.xmind.core.command.remote/build.properties index cf5b8f707..0ec3c0bd2 100644 --- a/bundles/org.xmind.core.command.remote/build.properties +++ b/bundles/org.xmind.core.command.remote/build.properties @@ -1,9 +1,9 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - plugin.properties,\ - about.html -src.includes = about.html,\ - schema/ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + plugin.properties,\ + about.html +src.includes = about.html,\ + schema/ diff --git a/bundles/org.xmind.core.command.remote/plugin.properties b/bundles/org.xmind.core.command.remote/plugin.properties index b51fffcde..1c496e634 100644 --- a/bundles/org.xmind.core.command.remote/plugin.properties +++ b/bundles/org.xmind.core.command.remote/plugin.properties @@ -1,5 +1,5 @@ -#Properties file for org.xmind.core.command.remote -remote.command.name=Remote Command Service Domains - -Bundle-Vendor = XMind Ltd. +#Properties file for org.xmind.core.command.remote +remote.command.name=Remote Command Service Domains + +Bundle-Vendor = XMind Ltd. Bundle-Name = XMind Remote Command Service Core \ No newline at end of file diff --git a/bundles/org.xmind.core.command.remote/plugin.xml b/bundles/org.xmind.core.command.remote/plugin.xml index 142de24d3..05a7918bb 100644 --- a/bundles/org.xmind.core.command.remote/plugin.xml +++ b/bundles/org.xmind.core.command.remote/plugin.xml @@ -1,6 +1,6 @@ - - - - - - + + + + + + diff --git a/bundles/org.xmind.core.command.remote/pom.xml b/bundles/org.xmind.core.command.remote/pom.xml index 45792043d..8d04b567f 100644 --- a/bundles/org.xmind.core.command.remote/pom.xml +++ b/bundles/org.xmind.core.command.remote/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.command.remote - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.command.remote + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.command.remote/schema/domains.exsd b/bundles/org.xmind.core.command.remote/schema/domains.exsd index 9ab2ea954..44a503f3d 100644 --- a/bundles/org.xmind.core.command.remote/schema/domains.exsd +++ b/bundles/org.xmind.core.command.remote/schema/domains.exsd @@ -1,184 +1,184 @@ - - - - - - - - - [Enter description of this extension point.] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [Enter the first release in which this extension point appears.] - - - - - - - - - [Enter extension point usage example here.] - - - - - - - - - [Enter API information here.] - - - - - - - - - [Enter information about supplied implementation of this extension point.] - - - - - + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractCommandServerAdvertiser.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractCommandServerAdvertiser.java index 78dd9b2e5..0966bda0a 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractCommandServerAdvertiser.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractCommandServerAdvertiser.java @@ -1,66 +1,66 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * A base implementation of command server advertiser. - * - * @author Frank Shaka - */ -public abstract class AbstractCommandServerAdvertiser implements - ICommandServerAdvertiser { - - private ICommandServiceDomain domain; - - private ICommandServiceInfo registeringInfo = null; - - private ICommandServiceInfo registeredInfo = null; - - /** - * - */ - public AbstractCommandServerAdvertiser() { - } - - public void init(ICommandServiceDomain domain) { - this.domain = domain; - } - - /** - * @return the domain - */ - public ICommandServiceDomain getDomain() { - return domain; - } - - public ICommandServiceInfo getRegisteredInfo() { - return registeredInfo; - } - - public void setRegisteringInfo(ICommandServiceInfo info) { - this.registeringInfo = info; - } - - protected void setRegisteredInfo(ICommandServiceInfo info) { - this.registeredInfo = info; - } - - protected ICommandServiceInfo getRegisteringInfo() { - return this.registeringInfo; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * A base implementation of command server advertiser. + * + * @author Frank Shaka + */ +public abstract class AbstractCommandServerAdvertiser implements + ICommandServerAdvertiser { + + private ICommandServiceDomain domain; + + private ICommandServiceInfo registeringInfo = null; + + private ICommandServiceInfo registeredInfo = null; + + /** + * + */ + public AbstractCommandServerAdvertiser() { + } + + public void init(ICommandServiceDomain domain) { + this.domain = domain; + } + + /** + * @return the domain + */ + public ICommandServiceDomain getDomain() { + return domain; + } + + public ICommandServiceInfo getRegisteredInfo() { + return registeredInfo; + } + + public void setRegisteringInfo(ICommandServiceInfo info) { + this.registeringInfo = info; + } + + protected void setRegisteredInfo(ICommandServiceInfo info) { + this.registeredInfo = info; + } + + protected ICommandServiceInfo getRegisteringInfo() { + return this.registeringInfo; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractRemoteCommandServiceDiscoverer.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractRemoteCommandServiceDiscoverer.java index 09978b102..b725ec8e0 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractRemoteCommandServiceDiscoverer.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/AbstractRemoteCommandServiceDiscoverer.java @@ -1,154 +1,154 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.SafeRunner; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * A base implementation of remote command service discoverer. - * - * @author Frank Shaka - */ -public abstract class AbstractRemoteCommandServiceDiscoverer implements - IRemoteCommandServiceDiscoverer { - - private ICommandServiceDomain domain; - - private Map cache = new HashMap(); - - private Object cacheLock = new Object(); - - private ListenerList listeners = new ListenerList(); - - /** - * - */ - public AbstractRemoteCommandServiceDiscoverer() { - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.command.remote.IDomainService#init(org.xmind.core.command - * .remote.ICommandServiceDomain) - */ - public void init(ICommandServiceDomain domain) { - this.domain = domain; - } - - /** - * @return the domain - */ - public ICommandServiceDomain getDomain() { - return domain; - } - - public IRemoteCommandService[] getRemoteCommandServices() { - synchronized (cacheLock) { - return cache.values().toArray( - new IRemoteCommandService[cache.size()]); - } - } - - public IRemoteCommandService findRemoteCommandService(String serviceName) { - synchronized (cacheLock) { - return cache.get(serviceName); - } - } - - public void addRemoteCommandServiceListener( - IRemoteCommandServiceListener listener) { - listeners.add(listener); - } - - public void removeRemoteCommandServiceListener( - IRemoteCommandServiceListener listener) { - listeners.remove(listener); - } - - protected void remoteCommandServiceDiscovered(IRemoteCommandService service) { - IRemoteCommandService serviceRemovedById = null; - synchronized (cacheLock) { - ICommandServiceInfo info = service.getInfo(); - String serviceName = info.getId().getName(); - serviceRemovedById = cache.remove(serviceName); - cache.put(serviceName, service); - } - synchronized (listeners) { - if (serviceRemovedById != null) { - fireRemoteCommandServiceDropped(serviceRemovedById); - } - fireRemoteCommandServiceDiscovered(service); - } - } - - protected void remoteCommandServiceDropped(IRemoteCommandService service) { - IRemoteCommandService serviceRemovedById = null; - synchronized (cacheLock) { - ICommandServiceInfo info = service.getInfo(); - String serviceName = info.getId().getName(); - serviceRemovedById = cache.remove(serviceName); - } - synchronized (listeners) { - if (serviceRemovedById != null) { - fireRemoteCommandServiceDropped(serviceRemovedById); - } - } - } - - protected void fireRemoteCommandServiceDiscovered( - final IRemoteCommandService service) { - Object[] theListeners = listeners.getListeners(); - for (int i = 0; i < theListeners.length; i++) { - final IRemoteCommandServiceListener listener = (IRemoteCommandServiceListener) theListeners[i]; - SafeRunner.run(new ISafeRunnable() { - public void run() throws Exception { - listener.remoteCommandServiceDiscovered(service); - } - - public void handleException(Throwable exception) { - RemoteCommandPlugin.log(null, exception); - } - }); - } - } - - protected void fireRemoteCommandServiceDropped( - final IRemoteCommandService service) { - Object[] theListeners = listeners.getListeners(); - for (int i = 0; i < theListeners.length; i++) { - final IRemoteCommandServiceListener listener = (IRemoteCommandServiceListener) theListeners[i]; - SafeRunner.run(new ISafeRunnable() { - public void run() throws Exception { - listener.remoteCommandServiceDropped(service); - } - - public void handleException(Throwable exception) { - RemoteCommandPlugin.log(null, exception); - } - }); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.SafeRunner; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * A base implementation of remote command service discoverer. + * + * @author Frank Shaka + */ +public abstract class AbstractRemoteCommandServiceDiscoverer implements + IRemoteCommandServiceDiscoverer { + + private ICommandServiceDomain domain; + + private Map cache = new HashMap(); + + private Object cacheLock = new Object(); + + private ListenerList listeners = new ListenerList(); + + /** + * + */ + public AbstractRemoteCommandServiceDiscoverer() { + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.command.remote.IDomainService#init(org.xmind.core.command + * .remote.ICommandServiceDomain) + */ + public void init(ICommandServiceDomain domain) { + this.domain = domain; + } + + /** + * @return the domain + */ + public ICommandServiceDomain getDomain() { + return domain; + } + + public IRemoteCommandService[] getRemoteCommandServices() { + synchronized (cacheLock) { + return cache.values().toArray( + new IRemoteCommandService[cache.size()]); + } + } + + public IRemoteCommandService findRemoteCommandService(String serviceName) { + synchronized (cacheLock) { + return cache.get(serviceName); + } + } + + public void addRemoteCommandServiceListener( + IRemoteCommandServiceListener listener) { + listeners.add(listener); + } + + public void removeRemoteCommandServiceListener( + IRemoteCommandServiceListener listener) { + listeners.remove(listener); + } + + protected void remoteCommandServiceDiscovered(IRemoteCommandService service) { + IRemoteCommandService serviceRemovedById = null; + synchronized (cacheLock) { + ICommandServiceInfo info = service.getInfo(); + String serviceName = info.getId().getName(); + serviceRemovedById = cache.remove(serviceName); + cache.put(serviceName, service); + } + synchronized (listeners) { + if (serviceRemovedById != null) { + fireRemoteCommandServiceDropped(serviceRemovedById); + } + fireRemoteCommandServiceDiscovered(service); + } + } + + protected void remoteCommandServiceDropped(IRemoteCommandService service) { + IRemoteCommandService serviceRemovedById = null; + synchronized (cacheLock) { + ICommandServiceInfo info = service.getInfo(); + String serviceName = info.getId().getName(); + serviceRemovedById = cache.remove(serviceName); + } + synchronized (listeners) { + if (serviceRemovedById != null) { + fireRemoteCommandServiceDropped(serviceRemovedById); + } + } + } + + protected void fireRemoteCommandServiceDiscovered( + final IRemoteCommandService service) { + Object[] theListeners = listeners.getListeners(); + for (int i = 0; i < theListeners.length; i++) { + final IRemoteCommandServiceListener listener = (IRemoteCommandServiceListener) theListeners[i]; + SafeRunner.run(new ISafeRunnable() { + public void run() throws Exception { + listener.remoteCommandServiceDiscovered(service); + } + + public void handleException(Throwable exception) { + RemoteCommandPlugin.log(null, exception); + } + }); + } + } + + protected void fireRemoteCommandServiceDropped( + final IRemoteCommandService service) { + Object[] theListeners = listeners.getListeners(); + for (int i = 0; i < theListeners.length; i++) { + final IRemoteCommandServiceListener listener = (IRemoteCommandServiceListener) theListeners[i]; + SafeRunner.run(new ISafeRunnable() { + public void run() throws Exception { + listener.remoteCommandServiceDropped(service); + } + + public void handleException(Throwable exception) { + RemoteCommandPlugin.log(null, exception); + } + }); + } + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/CommandServiceInfo.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/CommandServiceInfo.java index e386aff08..7cce1bcb0 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/CommandServiceInfo.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/CommandServiceInfo.java @@ -1,143 +1,143 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.runtime.IProduct; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Bundle; -import org.osgi.framework.Version; - -/** - * An implementation of {@link ICommandServiceInfo} with abilities to set - * information and metadata. Note that all set- methods are for - * internal use only and are not recommended for direct invocation by clients. - * - * @noextend This class is not intended to be subclassed by clients. - * @author Frank Shaka - */ -public class CommandServiceInfo implements ICommandServiceInfo { - - private IIdentifier id = null; - - private String name = ""; //$NON-NLS-1$ - - private Map metadata = new HashMap(); - - /** - * Construct a new command service information object. - */ - public CommandServiceInfo() { - metadata.put(VERSION, CURRENT_VERSION); - IProduct product = Platform.getProduct(); - if (product != null) { - metadata.put(CLIENT_NAME, product.getName()); - metadata.put(CLIENT_SYMBOLIC_NAME, product.getId()); - Bundle bundle = product.getDefiningBundle(); - if (bundle != null) { - Version version = bundle.getVersion(); - metadata.put( - CLIENT_VERSION, - String.format( - "%s.%s.%s", //$NON-NLS-1$ - version.getMajor(), version.getMinor(), - version.getMicro())); - metadata.put(CLIENT_BUILD_ID, version.toString()); - } - } - } - - /** - * Constructs a new command service information object and copy all - * attributes from the given source. - * - * @param copy - */ - public CommandServiceInfo(ICommandServiceInfo source) { - this.id = source.getId(); - this.name = source.getName(); - Iterator keys = source.metadataKeys(); - while (keys.hasNext()) { - String key = keys.next(); - metadata.put(key, source.getMetadata(key)); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { - return Platform.getAdapterManager().getAdapter(this, adapter); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IRemoteCommandServiceInfo#getId() - */ - public IIdentifier getId() { - return id; - } - - public String getName() { - return name; - } - - public synchronized String getMetadata(String key) { - return metadata.get(key); - } - - public synchronized Iterator metadataKeys() { - return new ArrayList(metadata.keySet()).iterator(); - } - - public void setId(IIdentifier id) { - this.id = id; - } - - public void setName(String name) { - if (name == null) - name = ""; //$NON-NLS-1$ - this.name = name; - } - - public void setMetadata(String key, String value) { - if (value == null) { - metadata.remove(key); - } else { - metadata.put(key, value); - } - } - - protected Map getMetadataImpl() { - return metadata; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("CommandServiceInfo{id="); //$NON-NLS-1$ - sb.append(id); - sb.append(",name="); //$NON-NLS-1$ - sb.append(name); - sb.append(",metadata="); //$NON-NLS-1$ - sb.append(metadata); - sb.append('}'); - return sb.toString(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.runtime.IProduct; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.osgi.framework.Version; + +/** + * An implementation of {@link ICommandServiceInfo} with abilities to set + * information and metadata. Note that all set- methods are for + * internal use only and are not recommended for direct invocation by clients. + * + * @noextend This class is not intended to be subclassed by clients. + * @author Frank Shaka + */ +public class CommandServiceInfo implements ICommandServiceInfo { + + private IIdentifier id = null; + + private String name = ""; //$NON-NLS-1$ + + private Map metadata = new HashMap(); + + /** + * Construct a new command service information object. + */ + public CommandServiceInfo() { + metadata.put(VERSION, CURRENT_VERSION); + IProduct product = Platform.getProduct(); + if (product != null) { + metadata.put(CLIENT_NAME, product.getName()); + metadata.put(CLIENT_SYMBOLIC_NAME, product.getId()); + Bundle bundle = product.getDefiningBundle(); + if (bundle != null) { + Version version = bundle.getVersion(); + metadata.put( + CLIENT_VERSION, + String.format( + "%s.%s.%s", //$NON-NLS-1$ + version.getMajor(), version.getMinor(), + version.getMicro())); + metadata.put(CLIENT_BUILD_ID, version.toString()); + } + } + } + + /** + * Constructs a new command service information object and copy all + * attributes from the given source. + * + * @param copy + */ + public CommandServiceInfo(ICommandServiceInfo source) { + this.id = source.getId(); + this.name = source.getName(); + Iterator keys = source.metadataKeys(); + while (keys.hasNext()) { + String key = keys.next(); + metadata.put(key, source.getMetadata(key)); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IRemoteCommandServiceInfo#getId() + */ + public IIdentifier getId() { + return id; + } + + public String getName() { + return name; + } + + public synchronized String getMetadata(String key) { + return metadata.get(key); + } + + public synchronized Iterator metadataKeys() { + return new ArrayList(metadata.keySet()).iterator(); + } + + public void setId(IIdentifier id) { + this.id = id; + } + + public void setName(String name) { + if (name == null) + name = ""; //$NON-NLS-1$ + this.name = name; + } + + public void setMetadata(String key, String value) { + if (value == null) { + metadata.remove(key); + } else { + metadata.put(key, value); + } + } + + protected Map getMetadataImpl() { + return metadata; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("CommandServiceInfo{id="); //$NON-NLS-1$ + sb.append(id); + sb.append(",name="); //$NON-NLS-1$ + sb.append(name); + sb.append(",metadata="); //$NON-NLS-1$ + sb.append(metadata); + sb.append('}'); + return sb.toString(); + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServer.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServer.java index 6f030bb38..912a3b8d2 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServer.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServer.java @@ -1,78 +1,78 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A local command server listens for incoming command-handling requests, - * executes commands using {@link org.xmind.core.command.ICommandService} and - * sends return value back to the client. - * - * @author Frank Shaka - */ -public interface ICommandServer extends IDomainService { - - /** - * Deploys this command server. - * - *

- * This method is not intended to be called by clients directly because it - * will be called automatically by the {@link ICommandServiceDomain} on - * activation. - *

- * - *

- * This method may take a long time and block the current thread. - *

- * - * @param monitor - * the progress monitor - * @return the status of the deployment - */ - IStatus deploy(IProgressMonitor monitor); - - /** - * Undeploys this command server. - * - *

- * This method is not intended to be called by clients directly because it - * will be called automatically by the {@link ICommandServiceDomain} on - * deactivation. - *

- * - *

- * This method may take a long time and block the current thread. - *

- * - * @param monitor - * the progress monitor - * @return the status of the undeployment - */ - IStatus undeploy(IProgressMonitor monitor); - - /** - * Returns the information that will be used when registering this command - * server in the command service domain. - * - * @return the information used for registration, or null if - * the server is not deployed yet or has been undeployed - */ - ICommandServiceInfo getRegisteringInfo(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A local command server listens for incoming command-handling requests, + * executes commands using {@link org.xmind.core.command.ICommandService} and + * sends return value back to the client. + * + * @author Frank Shaka + */ +public interface ICommandServer extends IDomainService { + + /** + * Deploys this command server. + * + *

+ * This method is not intended to be called by clients directly because it + * will be called automatically by the {@link ICommandServiceDomain} on + * activation. + *

+ * + *

+ * This method may take a long time and block the current thread. + *

+ * + * @param monitor + * the progress monitor + * @return the status of the deployment + */ + IStatus deploy(IProgressMonitor monitor); + + /** + * Undeploys this command server. + * + *

+ * This method is not intended to be called by clients directly because it + * will be called automatically by the {@link ICommandServiceDomain} on + * deactivation. + *

+ * + *

+ * This method may take a long time and block the current thread. + *

+ * + * @param monitor + * the progress monitor + * @return the status of the undeployment + */ + IStatus undeploy(IProgressMonitor monitor); + + /** + * Returns the information that will be used when registering this command + * server in the command service domain. + * + * @return the information used for registration, or null if + * the server is not deployed yet or has been undeployed + */ + ICommandServiceInfo getRegisteringInfo(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServerAdvertiser.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServerAdvertiser.java index 4060a7a75..2f04d4151 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServerAdvertiser.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServerAdvertiser.java @@ -1,77 +1,77 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A command server advertiser. - * - * @author Frank Shaka - */ -public interface ICommandServerAdvertiser extends IDomainService { - - /** - * Sets the information of a local command server that will be registered. - * This method will be called by the command service domain after the - * command server has been deployed and before the registration is started. - * - * @param info - * the information to be registered, never null - */ - void setRegisteringInfo(ICommandServiceInfo info); - - /** - * Gets the information of the local command server that has been - * registered. This method will be called by the command service domain. - * - *

- * Note that all information returned by this method represents only the - * current state of the advertised command server. It may change due to - * various events. Client code should never cache this value. - * Instead, call this method each time you need info about the advertised - * command server. - *

- * - * @return the registration information of the local command server, or - * null if registration is not finished - */ - ICommandServiceInfo getRegisteredInfo(); - - /** - * Registers the local command server. The - * {@link #setRegisteringInfo(Object)} method should have been called in - * prior, otherwise an error status will be returned. - * - * @param monitor - * the progress monitor - * @return the status of the registration - */ - IStatus register(IProgressMonitor monitor); - - /** - * Unregisters the local command server. This method intends to undo any - * operations that {@link #register(IProgressMonitor)} has performed. - * - * @param monitor - * the progress monitor - * @return the status of the unregistration - */ - IStatus unregister(IProgressMonitor monitor); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A command server advertiser. + * + * @author Frank Shaka + */ +public interface ICommandServerAdvertiser extends IDomainService { + + /** + * Sets the information of a local command server that will be registered. + * This method will be called by the command service domain after the + * command server has been deployed and before the registration is started. + * + * @param info + * the information to be registered, never null + */ + void setRegisteringInfo(ICommandServiceInfo info); + + /** + * Gets the information of the local command server that has been + * registered. This method will be called by the command service domain. + * + *

+ * Note that all information returned by this method represents only the + * current state of the advertised command server. It may change due to + * various events. Client code should never cache this value. + * Instead, call this method each time you need info about the advertised + * command server. + *

+ * + * @return the registration information of the local command server, or + * null if registration is not finished + */ + ICommandServiceInfo getRegisteredInfo(); + + /** + * Registers the local command server. The + * {@link #setRegisteringInfo(Object)} method should have been called in + * prior, otherwise an error status will be returned. + * + * @param monitor + * the progress monitor + * @return the status of the registration + */ + IStatus register(IProgressMonitor monitor); + + /** + * Unregisters the local command server. This method intends to undo any + * operations that {@link #register(IProgressMonitor)} has performed. + * + * @param monitor + * the progress monitor + * @return the status of the unregistration + */ + IStatus unregister(IProgressMonitor monitor); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomain.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomain.java index 239889024..65b974fd5 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomain.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomain.java @@ -1,90 +1,90 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * A command service domain represents a specific range of access to command - * services, and provides a local command server and a remote command service - * discoverer for building/registering a command server and searching for remote - * command servers within this range. For example, a LAN command service domain - * may provide a command server that binds itself on a local server socket and - * use Zeroconf's DNS Service Discovery as the implementor of the remote command - * service discoverer for searching for remote command services within the local - * area network. - * - *

- * Connections to this domain should be made before the local command server and - * remote command service discoverer can return accurate results. - *

- * - * @author Frank Shaka - */ -public interface ICommandServiceDomain { - - /** - * Returns the unique identifier of this domain. - * - * @return the unqieu identifier of this domain - */ - String getId(); - - /** - * Returns the display name of this domain. - * - * @return the display name of this domain - */ - String getName(); - - /** - * Returns the director of this command service domain. The director is - * responsible for controlling the lifecycle of this domain. - * - * @return the director of this command service domain, never - * null - */ - ICommandServiceDomainDirector getDirector(); - - /** - * Returns the command server that will be deployed on the local machine. - * The command server is responsible for handling command requests sent from - * remote clients. The information of this command server will be advertised - * across this domain by an advertiser. - * - * @return the command server, never null - */ - ICommandServer getCommandServer(); - - /** - * Returns the advertiser for this domain's local command server. The - * advertiser is responsible for broadcasting the information of the local - * command server across the domain and registering it as a remote command - * service within this domain. - * - * @return the command server advertiser, never null - */ - ICommandServerAdvertiser getCommandServerAdvertiser(); - - /** - * Returns the remote command service discoverer for this domain. The - * discoverer is responsible for searching for available remote command - * services and provide clients methods to access them. - * - * @return the remote command service discoverer, never null - */ - IRemoteCommandServiceDiscoverer getRemoteCommandServiceDiscoverer(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * A command service domain represents a specific range of access to command + * services, and provides a local command server and a remote command service + * discoverer for building/registering a command server and searching for remote + * command servers within this range. For example, a LAN command service domain + * may provide a command server that binds itself on a local server socket and + * use Zeroconf's DNS Service Discovery as the implementor of the remote command + * service discoverer for searching for remote command services within the local + * area network. + * + *

+ * Connections to this domain should be made before the local command server and + * remote command service discoverer can return accurate results. + *

+ * + * @author Frank Shaka + */ +public interface ICommandServiceDomain { + + /** + * Returns the unique identifier of this domain. + * + * @return the unqieu identifier of this domain + */ + String getId(); + + /** + * Returns the display name of this domain. + * + * @return the display name of this domain + */ + String getName(); + + /** + * Returns the director of this command service domain. The director is + * responsible for controlling the lifecycle of this domain. + * + * @return the director of this command service domain, never + * null + */ + ICommandServiceDomainDirector getDirector(); + + /** + * Returns the command server that will be deployed on the local machine. + * The command server is responsible for handling command requests sent from + * remote clients. The information of this command server will be advertised + * across this domain by an advertiser. + * + * @return the command server, never null + */ + ICommandServer getCommandServer(); + + /** + * Returns the advertiser for this domain's local command server. The + * advertiser is responsible for broadcasting the information of the local + * command server across the domain and registering it as a remote command + * service within this domain. + * + * @return the command server advertiser, never null + */ + ICommandServerAdvertiser getCommandServerAdvertiser(); + + /** + * Returns the remote command service discoverer for this domain. The + * discoverer is responsible for searching for available remote command + * services and provide clients methods to access them. + * + * @return the remote command service discoverer, never null + */ + IRemoteCommandServiceDiscoverer getRemoteCommandServiceDiscoverer(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainDirector.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainDirector.java index 5f3d7d571..683b26768 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainDirector.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainDirector.java @@ -1,78 +1,78 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A command service domain director. - * - * @author Frank Shaka - */ -public interface ICommandServiceDomainDirector extends IDomainService { - - int INACTIVE = 1; - - int ACTIVATING = 2; - - int ACTIVE = 3; - - int DEACTIVATING = 4; - - /** - * Opens a connection to the command service domain this director is - * responsible for. All services provided by this domain, e.g. the remote - * command service discoverer, will be activated on the first connection - * being opened. Subsequent connections will wait for the activation or, if - * the activation has finished, return immediately. - * - *

- * This method may take a long time and block the current thread. - *

- * - * @param monitor - * the progress monitor - * @return the connection token - */ - IStatus connect(IProgressMonitor monitor); - - /** - * Closes a connection to the command service domain this director is - * responsible for. All services provided by this domain, e.g. the remote - * command service discoverer, will be deactivated on the last connection - * being closed. Disconnections prior to the last one will return - * immediately. - * - *

- * This method may take a long time and block the current thread. - *

- * - * @param monitor - * the progress monitor - * @return the status of the disconnection - */ - IStatus disconnect(IProgressMonitor monitor); - - /** - * Returns the status code of this director. - * - * @return the status code of this director - */ - int getStatus(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A command service domain director. + * + * @author Frank Shaka + */ +public interface ICommandServiceDomainDirector extends IDomainService { + + int INACTIVE = 1; + + int ACTIVATING = 2; + + int ACTIVE = 3; + + int DEACTIVATING = 4; + + /** + * Opens a connection to the command service domain this director is + * responsible for. All services provided by this domain, e.g. the remote + * command service discoverer, will be activated on the first connection + * being opened. Subsequent connections will wait for the activation or, if + * the activation has finished, return immediately. + * + *

+ * This method may take a long time and block the current thread. + *

+ * + * @param monitor + * the progress monitor + * @return the connection token + */ + IStatus connect(IProgressMonitor monitor); + + /** + * Closes a connection to the command service domain this director is + * responsible for. All services provided by this domain, e.g. the remote + * command service discoverer, will be deactivated on the last connection + * being closed. Disconnections prior to the last one will return + * immediately. + * + *

+ * This method may take a long time and block the current thread. + *

+ * + * @param monitor + * the progress monitor + * @return the status of the disconnection + */ + IStatus disconnect(IProgressMonitor monitor); + + /** + * Returns the status code of this director. + * + * @return the status code of this director + */ + int getStatus(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainManager.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainManager.java index f96abd212..838963f38 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainManager.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceDomainManager.java @@ -1,47 +1,47 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * A command service domain manager provides access to command service domains. - * - *

- * This class can be retrieved as an OSGi service. - *

- * - * @author Frank Shaka - */ -public interface ICommandServiceDomainManager { - - /** - * Returns all available command service domains. - * - * @return an array of command service domains, never null - */ - ICommandServiceDomain[] getCommandServiceDomains(); - - /** - * Finds a command service domain by the specific domain id. - * - * @param domainId - * the identifier of a specified domain - * @return the command service corresponding to the given domain id, or - * null if the domain can not be found - */ - ICommandServiceDomain getCommandServiceDomain(String domainId); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * A command service domain manager provides access to command service domains. + * + *

+ * This class can be retrieved as an OSGi service. + *

+ * + * @author Frank Shaka + */ +public interface ICommandServiceDomainManager { + + /** + * Returns all available command service domains. + * + * @return an array of command service domains, never null + */ + ICommandServiceDomain[] getCommandServiceDomains(); + + /** + * Finds a command service domain by the specific domain id. + * + * @param domainId + * the identifier of a specified domain + * @return the command service corresponding to the given domain id, or + * null if the domain can not be found + */ + ICommandServiceDomain getCommandServiceDomain(String domainId); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceInfo.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceInfo.java index 7889ddaa9..9cc673872 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceInfo.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/ICommandServiceInfo.java @@ -1,108 +1,108 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import java.util.Iterator; - -import org.eclipse.core.runtime.IAdaptable; - -/** - * This class provides information and metadata of a remote/local command - * service. - * - * - * @noimplement This interface is not intended to be implemented by clients. - * @author Frank Shaka - */ -public interface ICommandServiceInfo extends IAdaptable { - - /** - * A metadata key for the version of this command service (value is - * "ver"). - */ - String VERSION = "ver"; //$NON-NLS-1$ - - /** - * A metadata key for the name of the command service provider (value is - * "cli"). - */ - String CLIENT_NAME = "cli"; //$NON-NLS-1$ - - /** - * A metadata key for the version of the command service provider (value is - * "cliver"). - */ - String CLIENT_VERSION = "cliver"; //$NON-NLS-1$ - - /** - * A metadata key for the symbolic name of the command service provider - * (value is "cliid"). - */ - String CLIENT_SYMBOLIC_NAME = "cliid"; //$NON-NLS-1$ - - /** - * A metadata key for the build id of the command service provider (value is - * "clibid"). - */ - String CLIENT_BUILD_ID = "clibid"; //$NON-NLS-1$ - - /** - * The metadata value for the current local service version (value is - * "1"). - */ - String CURRENT_VERSION = "1"; //$NON-NLS-1$ - - /** - * Gets the identifier of this command service. An identifier should be - * unique within a specific domain (e.g. a local area network). To obtain a - * human-readable name, use {@link #getName()}. - * - * @return the identifier of this service, or null if the - * command service is not identified (e.g. an unreigstered local - * command server) - */ - IIdentifier getId(); - - /** - * Gets the name of this command service. This name is suitable to display - * to end users, but it's not guaranteed to be unique. To obtain a unique - * identifier, use {@link #getId()}. - * - * @return the name of this service, possibly an empty string, but never - * null - */ - String getName(); - - /** - * Retrieves the metadata value of this command service corresponding to the - * given key. - * - * @param key - * the key of the metadata - * @return the value of the metadata, or null if the specified - * metadata is not found - */ - String getMetadata(String key); - - /** - * Returns an iterator that iterates over all existing metadata keys. - * - * @return an iterator that iterates over all existing metadata keys - */ - Iterator metadataKeys(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import java.util.Iterator; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * This class provides information and metadata of a remote/local command + * service. + * + * + * @noimplement This interface is not intended to be implemented by clients. + * @author Frank Shaka + */ +public interface ICommandServiceInfo extends IAdaptable { + + /** + * A metadata key for the version of this command service (value is + * "ver"). + */ + String VERSION = "ver"; //$NON-NLS-1$ + + /** + * A metadata key for the name of the command service provider (value is + * "cli"). + */ + String CLIENT_NAME = "cli"; //$NON-NLS-1$ + + /** + * A metadata key for the version of the command service provider (value is + * "cliver"). + */ + String CLIENT_VERSION = "cliver"; //$NON-NLS-1$ + + /** + * A metadata key for the symbolic name of the command service provider + * (value is "cliid"). + */ + String CLIENT_SYMBOLIC_NAME = "cliid"; //$NON-NLS-1$ + + /** + * A metadata key for the build id of the command service provider (value is + * "clibid"). + */ + String CLIENT_BUILD_ID = "clibid"; //$NON-NLS-1$ + + /** + * The metadata value for the current local service version (value is + * "1"). + */ + String CURRENT_VERSION = "1"; //$NON-NLS-1$ + + /** + * Gets the identifier of this command service. An identifier should be + * unique within a specific domain (e.g. a local area network). To obtain a + * human-readable name, use {@link #getName()}. + * + * @return the identifier of this service, or null if the + * command service is not identified (e.g. an unreigstered local + * command server) + */ + IIdentifier getId(); + + /** + * Gets the name of this command service. This name is suitable to display + * to end users, but it's not guaranteed to be unique. To obtain a unique + * identifier, use {@link #getId()}. + * + * @return the name of this service, possibly an empty string, but never + * null + */ + String getName(); + + /** + * Retrieves the metadata value of this command service corresponding to the + * given key. + * + * @param key + * the key of the metadata + * @return the value of the metadata, or null if the specified + * metadata is not found + */ + String getMetadata(String key); + + /** + * Returns an iterator that iterates over all existing metadata keys. + * + * @return an iterator that iterates over all existing metadata keys + */ + Iterator metadataKeys(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainService.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainService.java index 9637509fe..2b9ef3bdb 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainService.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainService.java @@ -1,37 +1,37 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IAdaptable; - -/** - * The base interface for all services within a command service domain. - * - * @author Frank Shaka - */ -public interface IDomainService extends IAdaptable { - - /** - * Initializes this service. - * - * @param domain - * the command service domain within which this service is - * available - */ - void init(ICommandServiceDomain domain); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * The base interface for all services within a command service domain. + * + * @author Frank Shaka + */ +public interface IDomainService extends IAdaptable { + + /** + * Initializes this service. + * + * @param domain + * the command service domain within which this service is + * available + */ + void init(ICommandServiceDomain domain); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainServiceFactory.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainServiceFactory.java index 8f03297b0..dab46786b 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainServiceFactory.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IDomainServiceFactory.java @@ -1,29 +1,29 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * A factory that creates a specific type of service within a command service - * domain. - * - * @author Frank Shaka - */ -public interface IDomainServiceFactory { - - Object createDomainService(ICommandServiceDomain domain); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * A factory that creates a specific type of service within a command service + * domain. + * + * @author Frank Shaka + */ +public interface IDomainServiceFactory { + + Object createDomainService(ICommandServiceDomain domain); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IIdentifier.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IIdentifier.java index 3a247846d..bfa04faa8 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IIdentifier.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IIdentifier.java @@ -1,59 +1,59 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * This class identifies a command service. - * - * @author Frank Shaka - */ -public interface IIdentifier { - - /** - * Returns the domain id of this identifier. - * - * @return the domain id of this identifier - */ - String getDomain(); - - /** - * Returns the unique name of this identifier. This name should be unique - * within the specific domain returned by {@link #getDomain()}. - * - * @return the unique name of this identifier, never null - */ - String getName(); - - /** - * Returns a string representing this identifier. Different identifiers - * should return different strings. - * - * @return a string representing this identifier - */ - String toString(); - - /** - * Tests whether this identifier equals another object. - * - * @param obj - * the object to test against - * @return true is the specified object is equal to this - * identifier, or false otherwise - */ - boolean equals(Object obj); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * This class identifies a command service. + * + * @author Frank Shaka + */ +public interface IIdentifier { + + /** + * Returns the domain id of this identifier. + * + * @return the domain id of this identifier + */ + String getDomain(); + + /** + * Returns the unique name of this identifier. This name should be unique + * within the specific domain returned by {@link #getDomain()}. + * + * @return the unique name of this identifier, never null + */ + String getName(); + + /** + * Returns a string representing this identifier. Different identifiers + * should return different strings. + * + * @return a string representing this identifier + */ + String toString(); + + /** + * Tests whether this identifier equals another object. + * + * @param obj + * the object to test against + * @return true is the specified object is equal to this + * identifier, or false otherwise + */ + boolean equals(Object obj); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandService.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandService.java index 5121f0bd9..0f3bd1d27 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandService.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandService.java @@ -1,70 +1,70 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.IReturnValueConsumer; - -/** - * A command handling service delegating the command execution by a remote - * command service provider. - * - * @author Frank Shaka - */ -public interface IRemoteCommandService { - - /** - * Executes a command synchronously. This method may take a long time to - * finish and will block the current thread, so it is recommended to run it - * in a separate thread or an {@link org.eclipse.core.runtime.jobs.Job}. - * - *

- * The return value may contain cached resources which is cleaned right - * before this method returns, so the client may want to pass in an - * IReturnValueConsumer to consume the cached resources before - * they are cleaned. - *

- * - * @param monitor - * the progress monitor, or null if progress - * monitoring is not required - * @param command - * the command to handle, should never be null - * @param returnValueConsumer - * the return value consumer, or null if return - * value consumption is not needed - * @param options - * options to control the execution process, or null - * to use default options - * @return the return value, never null - * @throws org.eclipse.core.runtime.AssertionFailedException - * if any argument is invalid, e.g. the command is - * null - */ - IStatus execute(IProgressMonitor monitor, ICommand command, - IReturnValueConsumer returnValueConsumer, Options options); - - /** - * Returns the information and metadata of this remote command service. - * - * @return the information and metadata of this remote command service - */ - ICommandServiceInfo getInfo(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.IReturnValueConsumer; + +/** + * A command handling service delegating the command execution by a remote + * command service provider. + * + * @author Frank Shaka + */ +public interface IRemoteCommandService { + + /** + * Executes a command synchronously. This method may take a long time to + * finish and will block the current thread, so it is recommended to run it + * in a separate thread or an {@link org.eclipse.core.runtime.jobs.Job}. + * + *

+ * The return value may contain cached resources which is cleaned right + * before this method returns, so the client may want to pass in an + * IReturnValueConsumer to consume the cached resources before + * they are cleaned. + *

+ * + * @param monitor + * the progress monitor, or null if progress + * monitoring is not required + * @param command + * the command to handle, should never be null + * @param returnValueConsumer + * the return value consumer, or null if return + * value consumption is not needed + * @param options + * options to control the execution process, or null + * to use default options + * @return the return value, never null + * @throws org.eclipse.core.runtime.AssertionFailedException + * if any argument is invalid, e.g. the command is + * null + */ + IStatus execute(IProgressMonitor monitor, ICommand command, + IReturnValueConsumer returnValueConsumer, Options options); + + /** + * Returns the information and metadata of this remote command service. + * + * @return the information and metadata of this remote command service + */ + ICommandServiceInfo getInfo(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceDiscoverer.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceDiscoverer.java index 2f7ef971e..dc40c7525 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceDiscoverer.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceDiscoverer.java @@ -1,105 +1,105 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A remote command service discoverer. - * - * @author Frank Shaka - */ -public interface IRemoteCommandServiceDiscoverer extends IDomainService { - - /** - * Activates this remote command service discoverer. - * - * @param monitor - * the progress monitor - * @return the status of the activation - */ - IStatus activate(IProgressMonitor monitor); - - /** - * Deactivates this remote command service discoverer. This method intends - * to undo any operation that {@link #activate(IProgressMonitor)} has - * performed. - * - * @param monitor - * the progress monitor - * @return the status of the deactivation - */ - IStatus deactivate(IProgressMonitor monitor); - - /** - * Returns discovered remote command services. May not return an accurate - * result if {@link #activate(IProgressMonitor, ICommandServiceInfo)} has - * not been called and finished. - * - * @return an array of discovered remote command services, possibly an empty - * array, but never null - */ - IRemoteCommandService[] getRemoteCommandServices(); - - /** - * Finds the remote command service identified by the specified service - * name. May not return an accurate result if - * {@link #activate(IProgressMonitor, ICommandServiceInfo)} has not been - * called and finished. - * - * @param serviceName - * the unique name of the remote command service to find - * @return a remote command service identified by the speicified service - * name, or null if not found - * @see IIdentifier#getName() - */ - IRemoteCommandService findRemoteCommandService(String serviceName); - - /** - * Installs a remote command service listener to this discoverer. - * - * @param listener - * the listener to add - */ - void addRemoteCommandServiceListener(IRemoteCommandServiceListener listener); - - /** - * Uninstalls a remote command service listener from this discoverer. - * - * @param listener - * the listener to remove - */ - void removeRemoteCommandServiceListener( - IRemoteCommandServiceListener listener); - - /** - * Drops all previously discovered remote command services and search again - * for all existing remote command services. Dropped and discovered services - * will all be notified to installed remote command service listeners. - * - *

- * This method may take a long time and block the current thread. - *

- * - * @param monitor - * the progress monitor - * @return the status of the refresh operation - */ - IStatus refresh(IProgressMonitor monitor); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A remote command service discoverer. + * + * @author Frank Shaka + */ +public interface IRemoteCommandServiceDiscoverer extends IDomainService { + + /** + * Activates this remote command service discoverer. + * + * @param monitor + * the progress monitor + * @return the status of the activation + */ + IStatus activate(IProgressMonitor monitor); + + /** + * Deactivates this remote command service discoverer. This method intends + * to undo any operation that {@link #activate(IProgressMonitor)} has + * performed. + * + * @param monitor + * the progress monitor + * @return the status of the deactivation + */ + IStatus deactivate(IProgressMonitor monitor); + + /** + * Returns discovered remote command services. May not return an accurate + * result if {@link #activate(IProgressMonitor, ICommandServiceInfo)} has + * not been called and finished. + * + * @return an array of discovered remote command services, possibly an empty + * array, but never null + */ + IRemoteCommandService[] getRemoteCommandServices(); + + /** + * Finds the remote command service identified by the specified service + * name. May not return an accurate result if + * {@link #activate(IProgressMonitor, ICommandServiceInfo)} has not been + * called and finished. + * + * @param serviceName + * the unique name of the remote command service to find + * @return a remote command service identified by the speicified service + * name, or null if not found + * @see IIdentifier#getName() + */ + IRemoteCommandService findRemoteCommandService(String serviceName); + + /** + * Installs a remote command service listener to this discoverer. + * + * @param listener + * the listener to add + */ + void addRemoteCommandServiceListener(IRemoteCommandServiceListener listener); + + /** + * Uninstalls a remote command service listener from this discoverer. + * + * @param listener + * the listener to remove + */ + void removeRemoteCommandServiceListener( + IRemoteCommandServiceListener listener); + + /** + * Drops all previously discovered remote command services and search again + * for all existing remote command services. Dropped and discovered services + * will all be notified to installed remote command service listeners. + * + *

+ * This method may take a long time and block the current thread. + *

+ * + * @param monitor + * the progress monitor + * @return the status of the refresh operation + */ + IStatus refresh(IProgressMonitor monitor); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceListener.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceListener.java index a36c39a66..9cf426ef6 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceListener.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/IRemoteCommandServiceListener.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * A listener notified when remote command service is discovered or dropped. - * Clients may implement this interface. - * - * @author Frank Shaka - */ -public interface IRemoteCommandServiceListener { - - /** - * Called when a remote command service has been discovered. Note that this - * method may not be called in the UI thread. - * - * @param service - * the discovered remote command service - */ - void remoteCommandServiceDiscovered(IRemoteCommandService service); - - /** - * Called when a remote command service has been dropped. Note that this - * method may not be called in the UI thread. - * - * @param service - * the dropped remote command service - */ - void remoteCommandServiceDropped(IRemoteCommandService service); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * A listener notified when remote command service is discovered or dropped. + * Clients may implement this interface. + * + * @author Frank Shaka + */ +public interface IRemoteCommandServiceListener { + + /** + * Called when a remote command service has been discovered. Note that this + * method may not be called in the UI thread. + * + * @param service + * the discovered remote command service + */ + void remoteCommandServiceDiscovered(IRemoteCommandService service); + + /** + * Called when a remote command service has been dropped. Note that this + * method may not be called in the UI thread. + * + * @param service + * the dropped remote command service + */ + void remoteCommandServiceDropped(IRemoteCommandService service); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Identifier.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Identifier.java index fc49d131a..f1c8c0c67 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Identifier.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Identifier.java @@ -1,88 +1,88 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.Assert; - -/** - * An identifying object implementing {@link IIdentifier} interface. - * - * @author Frank Shaka - */ -public class Identifier implements IIdentifier { - - private final String domain; - - private final String name; - - private final String fullName; - - /** - * - */ - public Identifier(String domain, String name) { - Assert.isNotNull(domain); - Assert.isNotNull(name); - this.domain = domain; - this.name = name; - this.fullName = domain + "/" + name; //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IIdentifier#getDomain() - */ - public String getDomain() { - return domain; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IIdentifier#getName() - */ - public String getName() { - return name; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof Identifier)) - return false; - Identifier that = (Identifier) obj; - return this.domain.equals(that.domain) && this.name.equals(that.name); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return fullName; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.Assert; + +/** + * An identifying object implementing {@link IIdentifier} interface. + * + * @author Frank Shaka + */ +public class Identifier implements IIdentifier { + + private final String domain; + + private final String name; + + private final String fullName; + + /** + * + */ + public Identifier(String domain, String name) { + Assert.isNotNull(domain); + Assert.isNotNull(name); + this.domain = domain; + this.name = name; + this.fullName = domain + "/" + name; //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IIdentifier#getDomain() + */ + public String getDomain() { + return domain; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IIdentifier#getName() + */ + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof Identifier)) + return false; + Identifier that = (Identifier) obj; + return this.domain.equals(that.domain) && this.name.equals(that.name); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return fullName; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Options.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Options.java index fe49c6204..7792ba1ae 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Options.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/Options.java @@ -1,81 +1,81 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -/** - * Options and configurations for controlling the remote command execution - * process. For example, a timeout option specifies how long the client should - * wait before the remote command service completes the command execution. - * - * @author Frank Shaka - * @see IRemoteCommandService - */ -public class Options { - - /** - * The default timeout option value (value is 6000, i.e. 6 - * seconds); - */ - public static final int DEFAULT_TIMEOUT = 6000; - - /** - * The timeout option. - */ - private int timeout = DEFAULT_TIMEOUT; - - /** - * Construct a new {@link Options} instance with default values. - */ - public Options() { - } - - /** - * Sets the timeout option, in milliseconds. The service will wait for the - * remote handler for the specified timeout before cutting down the - * connection to the remote location and canceling the command execution. - * - *

- * Note that the timeout option should be a positive integer. Otherwise the - * default value {@link #DEFAULT_TIMEOUT} will be used. - *

- * - * @param timeout - * the specified timeout, in milliseconds - * @return this {@lin Options} instance - */ - public Options timeout(int timeout) { - if (timeout <= 0) - timeout = DEFAULT_TIMEOUT; - this.timeout = timeout; - return this; - } - - /** - * Gets the timeout option. - * - * @return the timeout option - */ - public int timeout() { - return this.timeout; - } - - /** - * A {@link Options} instance with default values. - */ - public static final Options DEFAULT = new Options(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +/** + * Options and configurations for controlling the remote command execution + * process. For example, a timeout option specifies how long the client should + * wait before the remote command service completes the command execution. + * + * @author Frank Shaka + * @see IRemoteCommandService + */ +public class Options { + + /** + * The default timeout option value (value is 6000, i.e. 6 + * seconds); + */ + public static final int DEFAULT_TIMEOUT = 6000; + + /** + * The timeout option. + */ + private int timeout = DEFAULT_TIMEOUT; + + /** + * Construct a new {@link Options} instance with default values. + */ + public Options() { + } + + /** + * Sets the timeout option, in milliseconds. The service will wait for the + * remote handler for the specified timeout before cutting down the + * connection to the remote location and canceling the command execution. + * + *

+ * Note that the timeout option should be a positive integer. Otherwise the + * default value {@link #DEFAULT_TIMEOUT} will be used. + *

+ * + * @param timeout + * the specified timeout, in milliseconds + * @return this {@lin Options} instance + */ + public Options timeout(int timeout) { + if (timeout <= 0) + timeout = DEFAULT_TIMEOUT; + this.timeout = timeout; + return this; + } + + /** + * Gets the timeout option. + * + * @return the timeout option + */ + public int timeout() { + return this.timeout; + } + + /** + * A {@link Options} instance with default values. + */ + public static final Options DEFAULT = new Options(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/RemoteCommandJob.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/RemoteCommandJob.java index 76b0ec508..19021d41a 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/RemoteCommandJob.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/RemoteCommandJob.java @@ -1,119 +1,119 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.IReturnValueConsumer; -import org.xmind.core.internal.command.remote.Messages; - -/** - * A job handling simple remote command execution. - * - * @author Frank Shaka - */ -public abstract class RemoteCommandJob extends Job implements - IReturnValueConsumer { - - private String pluginId; - - private IRemoteCommandService remoteCommandService; - - /** - * - */ - public RemoteCommandJob(String jobName, String pluginId, - IRemoteCommandService remoteCommandService) { - super(jobName); - this.pluginId = pluginId; - this.remoteCommandService = remoteCommandService; - } - - /** - * @return the pluginId - */ - public String getPluginId() { - return pluginId; - } - - /** - * @return the remoteCommandService - */ - public IRemoteCommandService getRemoteCommandService() { - return remoteCommandService; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { - if (adapter == IRemoteCommandService.class) - return getRemoteCommandService(); - return super.getAdapter(adapter); - } - - protected IStatus run(IProgressMonitor monitor) { - monitor.beginTask(null, 100); - - /* - * Create command. - */ - ICommand command; - SubProgressMonitor createCommandMonitor = new SubProgressMonitor( - monitor, 10); - try { - command = createCommand(createCommandMonitor); - } catch (CoreException e) { - return e.getStatus(); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - if (command == null) - return new Status(IStatus.CANCEL, pluginId, - Messages.RemoteCommandJob_CommandSendError_Message); - createCommandMonitor.done(); - - /* - * Send command. - */ - SubProgressMonitor sendCommandMonitor = new SubProgressMonitor(monitor, - 90); - IStatus executed = executeCommand(sendCommandMonitor, command); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - sendCommandMonitor.done(); - monitor.done(); - return executed; - } - - protected IStatus executeCommand(IProgressMonitor sendCommandMonitor, - ICommand command) { - return getRemoteCommandService().execute(sendCommandMonitor, command, - this, getOptions()); - } - - protected abstract ICommand createCommand(IProgressMonitor monitor) - throws CoreException; - - protected Options getOptions() { - return Options.DEFAULT; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.IReturnValueConsumer; +import org.xmind.core.internal.command.remote.Messages; + +/** + * A job handling simple remote command execution. + * + * @author Frank Shaka + */ +public abstract class RemoteCommandJob extends Job implements + IReturnValueConsumer { + + private String pluginId; + + private IRemoteCommandService remoteCommandService; + + /** + * + */ + public RemoteCommandJob(String jobName, String pluginId, + IRemoteCommandService remoteCommandService) { + super(jobName); + this.pluginId = pluginId; + this.remoteCommandService = remoteCommandService; + } + + /** + * @return the pluginId + */ + public String getPluginId() { + return pluginId; + } + + /** + * @return the remoteCommandService + */ + public IRemoteCommandService getRemoteCommandService() { + return remoteCommandService; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { + if (adapter == IRemoteCommandService.class) + return getRemoteCommandService(); + return super.getAdapter(adapter); + } + + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(null, 100); + + /* + * Create command. + */ + ICommand command; + SubProgressMonitor createCommandMonitor = new SubProgressMonitor( + monitor, 10); + try { + command = createCommand(createCommandMonitor); + } catch (CoreException e) { + return e.getStatus(); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + if (command == null) + return new Status(IStatus.CANCEL, pluginId, + Messages.RemoteCommandJob_CommandSendError_Message); + createCommandMonitor.done(); + + /* + * Send command. + */ + SubProgressMonitor sendCommandMonitor = new SubProgressMonitor(monitor, + 90); + IStatus executed = executeCommand(sendCommandMonitor, command); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + sendCommandMonitor.done(); + monitor.done(); + return executed; + } + + protected IStatus executeCommand(IProgressMonitor sendCommandMonitor, + ICommand command) { + return getRemoteCommandService().execute(sendCommandMonitor, command, + this, getOptions()); + } + + protected abstract ICommand createCommand(IProgressMonitor monitor) + throws CoreException; + + protected Options getOptions() { + return Options.DEFAULT; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/ISocketAddress.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/ISocketAddress.java index 125acf048..6f093c131 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/ISocketAddress.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/ISocketAddress.java @@ -1,38 +1,38 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.remote.socket; - -/** - * A lightweight representation of a socket address. - * - * @author Frank Shaka - * - */ -public interface ISocketAddress { - - /** - * Returns the host name of this socket address. - * - * @return the host name of this socket address - */ - String getHostName(); - - /** - * Returns the port number of this socket address. - * - * @return the port number of this socket address - */ - int getPort(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.remote.socket; + +/** + * A lightweight representation of a socket address. + * + * @author Frank Shaka + * + */ +public interface ISocketAddress { + + /** + * Returns the host name of this socket address. + * + * @return the host name of this socket address + */ + String getHostName(); + + /** + * Returns the port number of this socket address. + * + * @return the port number of this socket address + */ + int getPort(); + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/IncomingSocketCommandHandler.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/IncomingSocketCommandHandler.java index 4c9fa4dfc..d4dcb123c 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/IncomingSocketCommandHandler.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/IncomingSocketCommandHandler.java @@ -1,154 +1,154 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote.socket; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.net.SocketException; -import java.net.SocketTimeoutException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.transfer.IncomingCommandHandler; -import org.xmind.core.internal.command.remote.Messages; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * A job that handles incoming commands sent through sockets. - * - * @author Frank Shaka - */ -public class IncomingSocketCommandHandler extends Job { - - private class InternalIncomingSocketCommandHandler extends - IncomingCommandHandler { - - public InternalIncomingSocketCommandHandler() { - super(); - } - - protected IStatus createReadingErrorStatus(Throwable e) { - IStatus status = IncomingSocketCommandHandler.this - .createReadingErrorStatus(this, e); - if (status != null) - return status; - return super.createReadingErrorStatus(e); - } - - protected IStatus createWritingErrorStatus(Throwable e) { - IStatus status = IncomingSocketCommandHandler.this - .createWritingErrorStatus(this, e); - if (status != null) - return status; - return super.createWritingErrorStatus(e); - } - } - - private final Socket socket; - - private SocketPool socketPool = null; - - private String pluginId = RemoteCommandPlugin.PLUGIN_ID; - - /** - * - */ - public IncomingSocketCommandHandler(Socket socket) { - super("Handle Command Request Coming From Socket Connection"); //$NON-NLS-1$ - this.socket = socket; - setUser(false); - setSystem(true); - } - - public void setSocketPool(SocketPool socketPool) { - this.socketPool = socketPool; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. - * IProgressMonitor) - */ - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - InputStream input = socket.getInputStream(); - try { - OutputStream output = socket.getOutputStream(); - try { - IncomingCommandHandler handler = new InternalIncomingSocketCommandHandler(); - handler.setPluginId(getPluginId()); - handler.setRemoteLocation(socket.getRemoteSocketAddress()); - return handler - .handleIncomingCommand(monitor, input, output); - } finally { - output.close(); - } - } finally { - input.close(); - } - } catch (IOException e) { - return new Status(IStatus.ERROR, RemoteCommandPlugin.PLUGIN_ID, - null, e); - } finally { - if (socketPool != null) - socketPool.removeSocket(socket); - } - } - - public String getPluginId() { - return pluginId; - } - - public void setPluginId(String pluginId) { - if (pluginId == null) - pluginId = RemoteCommandPlugin.PLUGIN_ID; - this.pluginId = pluginId; - } - - protected IStatus createReadingErrorStatus(IncomingCommandHandler handler, - Throwable e) { - if (e instanceof SocketException || e instanceof SocketTimeoutException) { - return new Status( - IStatus.WARNING, - getPluginId(), - NLS.bind( - Messages.IncomingSocketCommandHandler_ConnectionFailed_Message, - handler.getRemoteLocation()), e); - } - return null; - } - - protected IStatus createWritingErrorStatus(IncomingCommandHandler handler, - Throwable e) { - if (e instanceof SocketException || e instanceof SocketTimeoutException) { - return new Status( - IStatus.WARNING, - getPluginId(), - NLS.bind( - Messages.IncomingSocketCommandHandler_ConnectionFailed_Message, - handler.getRemoteLocation()), e); - } - return null; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote.socket; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.net.SocketException; +import java.net.SocketTimeoutException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.transfer.IncomingCommandHandler; +import org.xmind.core.internal.command.remote.Messages; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * A job that handles incoming commands sent through sockets. + * + * @author Frank Shaka + */ +public class IncomingSocketCommandHandler extends Job { + + private class InternalIncomingSocketCommandHandler extends + IncomingCommandHandler { + + public InternalIncomingSocketCommandHandler() { + super(); + } + + protected IStatus createReadingErrorStatus(Throwable e) { + IStatus status = IncomingSocketCommandHandler.this + .createReadingErrorStatus(this, e); + if (status != null) + return status; + return super.createReadingErrorStatus(e); + } + + protected IStatus createWritingErrorStatus(Throwable e) { + IStatus status = IncomingSocketCommandHandler.this + .createWritingErrorStatus(this, e); + if (status != null) + return status; + return super.createWritingErrorStatus(e); + } + } + + private final Socket socket; + + private SocketPool socketPool = null; + + private String pluginId = RemoteCommandPlugin.PLUGIN_ID; + + /** + * + */ + public IncomingSocketCommandHandler(Socket socket) { + super("Handle Command Request Coming From Socket Connection"); //$NON-NLS-1$ + this.socket = socket; + setUser(false); + setSystem(true); + } + + public void setSocketPool(SocketPool socketPool) { + this.socketPool = socketPool; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. + * IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + InputStream input = socket.getInputStream(); + try { + OutputStream output = socket.getOutputStream(); + try { + IncomingCommandHandler handler = new InternalIncomingSocketCommandHandler(); + handler.setPluginId(getPluginId()); + handler.setRemoteLocation(socket.getRemoteSocketAddress()); + return handler + .handleIncomingCommand(monitor, input, output); + } finally { + output.close(); + } + } finally { + input.close(); + } + } catch (IOException e) { + return new Status(IStatus.ERROR, RemoteCommandPlugin.PLUGIN_ID, + null, e); + } finally { + if (socketPool != null) + socketPool.removeSocket(socket); + } + } + + public String getPluginId() { + return pluginId; + } + + public void setPluginId(String pluginId) { + if (pluginId == null) + pluginId = RemoteCommandPlugin.PLUGIN_ID; + this.pluginId = pluginId; + } + + protected IStatus createReadingErrorStatus(IncomingCommandHandler handler, + Throwable e) { + if (e instanceof SocketException || e instanceof SocketTimeoutException) { + return new Status( + IStatus.WARNING, + getPluginId(), + NLS.bind( + Messages.IncomingSocketCommandHandler_ConnectionFailed_Message, + handler.getRemoteLocation()), e); + } + return null; + } + + protected IStatus createWritingErrorStatus(IncomingCommandHandler handler, + Throwable e) { + if (e instanceof SocketException || e instanceof SocketTimeoutException) { + return new Status( + IStatus.WARNING, + getPluginId(), + NLS.bind( + Messages.IncomingSocketCommandHandler_ConnectionFailed_Message, + handler.getRemoteLocation()), e); + } + return null; + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/OutgoingSocketCommandHandler.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/OutgoingSocketCommandHandler.java index 6f17bcbb9..66baf0418 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/OutgoingSocketCommandHandler.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/OutgoingSocketCommandHandler.java @@ -1,189 +1,189 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote.socket; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketTimeoutException; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.IReturnValueConsumer; -import org.xmind.core.command.transfer.OutgoingCommandHandler; -import org.xmind.core.internal.command.remote.Messages; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * A client that handles outgoing commands sent to remote sockets. - * - * @author Frank Shaka - */ -public class OutgoingSocketCommandHandler extends OutgoingCommandHandler { - - private static final String DEBUG_OPTION = "/debug/outgoingSocketCommandHandler"; //$NON-NLS-1$ - - private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() - .isDebugging(DEBUG_OPTION); - - private ISocketAddress remoteAddress; - - private SocketPool socketPool = null; - - /** - * - */ - public OutgoingSocketCommandHandler(ISocketAddress remoteAddress) { - Assert.isNotNull(remoteAddress); - this.remoteAddress = remoteAddress; - setRemoteLocation(remoteAddress); - } - - public void setSocketPool(SocketPool socketPool) { - this.socketPool = socketPool; - } - - public IStatus handleOutgoingCommand(IProgressMonitor monitor, - ICommand command, IReturnValueConsumer returnValueConsumer, - int timeout) { - monitor.beginTask(null, 100); - - monitor.subTask(NLS.bind( - Messages.OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message, - remoteAddress)); - Socket socket = new Socket(); - try { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - try { - InetSocketAddress address = new InetSocketAddress( - remoteAddress.getHostName(), remoteAddress.getPort()); - socket.connect(address, timeout); - socket.setSoTimeout(timeout); - if (socketPool != null) - socketPool.addSocket(socket); - } catch (IOException e) { - if (DEBUGGING) - return new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, - NLS.bind( - Messages.OutgoingSocketCommandHandler_ConnectionFailed_Message, - remoteAddress), - e); - return new Status(IStatus.CANCEL, RemoteCommandPlugin.PLUGIN_ID, - NLS.bind( - Messages.OutgoingSocketCommandHandler_ConnectionFailed_Message, - remoteAddress), - e); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - InputStream input; - try { - input = socket.getInputStream(); - } catch (IOException e) { - return new Status(IStatus.ERROR, RemoteCommandPlugin.PLUGIN_ID, - NLS.bind( - Messages.OutgoingSocketCommandHandler_FailedOpenInputStream, - remoteAddress), - e); - } - try { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - OutputStream output; - try { - output = socket.getOutputStream(); - } catch (IOException e) { - return new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, - NLS.bind( - Messages.OutgoingSocketCommandHandler_FailedOpenOutputStream, - remoteAddress), - e); - } - try { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - monitor.worked(10); - - IProgressMonitor handleMonitor = new SubProgressMonitor( - monitor, 90); - IStatus handled = super.handleOutgoingCommand(handleMonitor, - command, returnValueConsumer, input, output); - if (!handleMonitor.isCanceled()) - handleMonitor.done(); - if (!monitor.isCanceled()) - monitor.done(); - return handled; - } finally { - try { - output.close(); - } catch (IOException e) { - } - } - } finally { - try { - input.close(); - } catch (IOException e) { - } - } - - } finally { - try { - socket.close(); - } catch (IOException e) { - } - if (socketPool != null) - socketPool.removeSocket(socket); - } - } - - protected IStatus createSendingErrorStatus(IOException e) { - if (e instanceof SocketTimeoutException) { - return new Status(IStatus.WARNING, getPluginId(), - NLS.bind( - Messages.OutgoingSocketCommandHandler_ConnectionTimeOut, - remoteAddress), - e); - } - return super.createSendingErrorStatus(e); - } - - protected IStatus createReceivingErrorStatus(IOException e) { - if (e instanceof SocketTimeoutException) { - return new Status(IStatus.WARNING, getPluginId(), - NLS.bind( - Messages.OutgoingSocketCommandHandler_ConnectionTimeOut, - remoteAddress), - e); - } - return super.createReceivingErrorStatus(e); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote.socket; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.IReturnValueConsumer; +import org.xmind.core.command.transfer.OutgoingCommandHandler; +import org.xmind.core.internal.command.remote.Messages; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * A client that handles outgoing commands sent to remote sockets. + * + * @author Frank Shaka + */ +public class OutgoingSocketCommandHandler extends OutgoingCommandHandler { + + private static final String DEBUG_OPTION = "/debug/outgoingSocketCommandHandler"; //$NON-NLS-1$ + + private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() + .isDebugging(DEBUG_OPTION); + + private ISocketAddress remoteAddress; + + private SocketPool socketPool = null; + + /** + * + */ + public OutgoingSocketCommandHandler(ISocketAddress remoteAddress) { + Assert.isNotNull(remoteAddress); + this.remoteAddress = remoteAddress; + setRemoteLocation(remoteAddress); + } + + public void setSocketPool(SocketPool socketPool) { + this.socketPool = socketPool; + } + + public IStatus handleOutgoingCommand(IProgressMonitor monitor, + ICommand command, IReturnValueConsumer returnValueConsumer, + int timeout) { + monitor.beginTask(null, 100); + + monitor.subTask(NLS.bind( + Messages.OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message, + remoteAddress)); + Socket socket = new Socket(); + try { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + try { + InetSocketAddress address = new InetSocketAddress( + remoteAddress.getHostName(), remoteAddress.getPort()); + socket.connect(address, timeout); + socket.setSoTimeout(timeout); + if (socketPool != null) + socketPool.addSocket(socket); + } catch (IOException e) { + if (DEBUGGING) + return new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, + NLS.bind( + Messages.OutgoingSocketCommandHandler_ConnectionFailed_Message, + remoteAddress), + e); + return new Status(IStatus.CANCEL, RemoteCommandPlugin.PLUGIN_ID, + NLS.bind( + Messages.OutgoingSocketCommandHandler_ConnectionFailed_Message, + remoteAddress), + e); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + InputStream input; + try { + input = socket.getInputStream(); + } catch (IOException e) { + return new Status(IStatus.ERROR, RemoteCommandPlugin.PLUGIN_ID, + NLS.bind( + Messages.OutgoingSocketCommandHandler_FailedOpenInputStream, + remoteAddress), + e); + } + try { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + OutputStream output; + try { + output = socket.getOutputStream(); + } catch (IOException e) { + return new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, + NLS.bind( + Messages.OutgoingSocketCommandHandler_FailedOpenOutputStream, + remoteAddress), + e); + } + try { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + monitor.worked(10); + + IProgressMonitor handleMonitor = new SubProgressMonitor( + monitor, 90); + IStatus handled = super.handleOutgoingCommand(handleMonitor, + command, returnValueConsumer, input, output); + if (!handleMonitor.isCanceled()) + handleMonitor.done(); + if (!monitor.isCanceled()) + monitor.done(); + return handled; + } finally { + try { + output.close(); + } catch (IOException e) { + } + } + } finally { + try { + input.close(); + } catch (IOException e) { + } + } + + } finally { + try { + socket.close(); + } catch (IOException e) { + } + if (socketPool != null) + socketPool.removeSocket(socket); + } + } + + protected IStatus createSendingErrorStatus(IOException e) { + if (e instanceof SocketTimeoutException) { + return new Status(IStatus.WARNING, getPluginId(), + NLS.bind( + Messages.OutgoingSocketCommandHandler_ConnectionTimeOut, + remoteAddress), + e); + } + return super.createSendingErrorStatus(e); + } + + protected IStatus createReceivingErrorStatus(IOException e) { + if (e instanceof SocketTimeoutException) { + return new Status(IStatus.WARNING, getPluginId(), + NLS.bind( + Messages.OutgoingSocketCommandHandler_ConnectionTimeOut, + remoteAddress), + e); + } + return super.createReceivingErrorStatus(e); + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketAddress.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketAddress.java index 7b468d746..8f831f093 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketAddress.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketAddress.java @@ -1,81 +1,81 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.remote.socket; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.AssertionFailedException; - -/** - * A simple implementation of {@link ISocketAddress}. - * - * @author Frank Shaka - * - */ -public class SocketAddress implements ISocketAddress { - - /** - * The host name. - */ - private String hostName; - - /** - * The port number. - */ - private int port; - - /** - * Constructs a new socket address object. - * - * @param hostName - * the host name - * @param port - * the port number - * @throws AssertionFailedException - * if hostName is null - */ - public SocketAddress(String hostName, int port) { - Assert.isNotNull(hostName); - this.hostName = hostName; - this.port = port; - } - - public String getHostName() { - return hostName; - } - - public int getPort() { - return port; - } - - @Override - public String toString() { - return String.format("%s:%s", hostName, port); //$NON-NLS-1$ - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SocketAddress)) - return false; - SocketAddress that = (SocketAddress) obj; - return this.hostName.equals(that.hostName) && this.port == that.port; - } - - @Override - public int hashCode() { - return hostName.hashCode() ^ port; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.remote.socket; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.AssertionFailedException; + +/** + * A simple implementation of {@link ISocketAddress}. + * + * @author Frank Shaka + * + */ +public class SocketAddress implements ISocketAddress { + + /** + * The host name. + */ + private String hostName; + + /** + * The port number. + */ + private int port; + + /** + * Constructs a new socket address object. + * + * @param hostName + * the host name + * @param port + * the port number + * @throws AssertionFailedException + * if hostName is null + */ + public SocketAddress(String hostName, int port) { + Assert.isNotNull(hostName); + this.hostName = hostName; + this.port = port; + } + + public String getHostName() { + return hostName; + } + + public int getPort() { + return port; + } + + @Override + public String toString() { + return String.format("%s:%s", hostName, port); //$NON-NLS-1$ + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SocketAddress)) + return false; + SocketAddress that = (SocketAddress) obj; + return this.hostName.equals(that.hostName) && this.port == that.port; + } + + @Override + public int hashCode() { + return hostName.hashCode() ^ port; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServer.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServer.java index 39d5de5e5..f269be658 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServer.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServer.java @@ -1,367 +1,367 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.remote.socket; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.xmind.core.command.remote.ICommandServer; -import org.xmind.core.command.remote.ICommandServiceDomain; -import org.xmind.core.command.remote.ICommandServiceInfo; -import org.xmind.core.internal.command.remote.Messages; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * This class provides basic implementations of a command server that relies on - * a server socket. - * - * @author Frank Shaka - */ -public class SocketCommandServer implements ICommandServer { - - private ICommandServiceDomain domain; - - private int defaultPort; - - private int defaultBacklog; - - private boolean triesEphemeralPort; - - private ServerSocket server = null; - - private Thread thread = null; - - private SocketCommandServiceInfo info = null; - - private Object lock = new Object(); - - private Runnable serverRunner = new Runnable() { - - /** - * Runs the server handling loop. Accepts all socket connections and - * fork them into separate handling job. - */ - public void run() { - ServerSocket theServer = server; - if (theServer == null) - return; - - try { - while (true) { - Socket socket = theServer.accept(); - socketPool.addSocket(socket); - runIncomingCommandHandler(socket); - } - } catch (IOException e) { - if (thread != null || server != null) { - RemoteCommandPlugin - .log("Error occurred while handling local command server.", //$NON-NLS-1$ - e); - } - } finally { - try { - theServer.close(); - } catch (IOException e) { - } - } - } - - }; - - private SocketPool socketPool = new SocketPool(); - - /** - * Constructs a new instance using default configurations, i.e. an ephemeral - * port as the default port, a backlog valued 50. - */ - public SocketCommandServer() { - this(0, 50, false); - } - - /** - * Constructs a new instance with specified configurations. - * - * @param defaultPort - * the default port number - * @param defaultBacklog - * the default connection waiting queue size - * @param triesEphemeralPort - * true to indicate that an ephemeral port will be - * tried if the default port fails to be bound to, which makes - * the best effort to ensure the command server started up, or - * false if no other port number than the default - * one should be tried to make the command server either fix on - * the given port number or just fail - */ - public SocketCommandServer(int defaultPort, int defaultBacklog, - boolean triesEphemeralPort) { - if (defaultPort < 0) - defaultPort = 0; - this.defaultPort = defaultPort; - this.defaultBacklog = defaultBacklog; - this.triesEphemeralPort = triesEphemeralPort; - } - - public void init(ICommandServiceDomain domain) { - this.domain = domain; - } - - /** - * @return the domain - */ - public ICommandServiceDomain getDomain() { - return domain; - } - - /** - * @return the defaultBacklog - */ - public int getDefaultBacklog() { - return defaultBacklog; - } - - /** - * @return the defaultPort - */ - public int getDefaultPort() { - return defaultPort; - } - - /** - * @return the server - */ - public ServerSocket getServer() { - return server; - } - - /** - * Returns the thread that handles the server socket's events. It is - * referred to as 'the loop thread' in this class. - * - * @return the loop thread, or null if the command server is - * not deployed or has been undeployed - */ - public Thread getThread() { - return thread; - } - - /** - * Deploys this command server using a server socket. - * - *

- * This method will first try to bind the server socket to the default port. - * If that fails, it will use an ephemeral port provided by the system. - *

- * - *

- * A daemon thread will be started once the server socket is ready. The - * thread will start a loop of accepting new socket connections on the - * server socket and starting an {@link org.eclipse.core.runtime.jobs.Job} - * to handle the command coming in through the accepted socket connection. - *

- * - * @param monitor - * the progress monitor - * @return the status of the deployment - */ - public IStatus deploy(IProgressMonitor monitor) { - monitor.beginTask(null, 100); - monitor.subTask(Messages.SocketCommandServer_OperationLock); - - synchronized (lock) { - monitor.subTask(Messages.SocketCommandServer_OpenCommandServerSocket); - - if (server == null || server.isClosed()) { - try { - server = new ServerSocket(); - } catch (IOException e) { - return new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, null, e); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(20); - - InetAddress localAddress = null; - int port = defaultPort; - try { - server.bind(new InetSocketAddress(localAddress, port), - defaultBacklog); - } catch (IOException e) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - if (port != 0 && triesEphemeralPort) { - try { - server.bind(new InetSocketAddress(localAddress, 0), - defaultBacklog); - } catch (IOException e1) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - return new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, null, e); - } - } else { - return new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, null, e); - } - } - - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(60); - - } else { - monitor.worked(70); - } - - if (info == null) { - info = new SocketCommandServiceInfo(); - info.setAddress(new SocketAddress(server.getInetAddress() - .getHostName(), server.getLocalPort())); - info.setName(System.getProperty("user.name")); //$NON-NLS-1$ - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(10); - - if (thread == null) { - thread = new Thread(serverRunner, getLoopThreadName()); - thread.setDaemon(true); - thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(10); - - monitor.done(); - return Status.OK_STATUS; - } - } - - /** - * Undeploys this command server. First, the daemon looping thread will be - * interrupted. Then the server socket opened by - * {@link #deploy(IProgressMonitor)} will be closed. - * - * @param monitor - * the progress monitor - * @return the status of the undeployment - */ - public IStatus undeploy(IProgressMonitor monitor) { - monitor.beginTask(null, 100); - monitor.subTask(Messages.SocketCommandServer_OperationLock); - - synchronized (lock) { - monitor.subTask(Messages.SocketCommandServer_CloseCommandServerSocket); - - Thread oldThread = thread; - ServerSocket oldServer = server; - thread = null; - server = null; - info = null; - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(10); - - if (oldThread != null) { - oldThread.interrupt(); - } - if (oldServer != null) { - try { - oldServer.close(); - } catch (IOException e) { - RemoteCommandPlugin.log( - "Could not stop local command server socket.", e); //$NON-NLS-1$ - } - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(90); - - socketPool.clear(); - - monitor.done(); - return Status.OK_STATUS; - } - } - - public ICommandServiceInfo getRegisteringInfo() { - return info; - } - - /** - * Returns the socket pool owned by this command server. A socket pool - * maintains a list of all active sockets and provides a method to close all - * active sockets. - * - * @return the socket pool - */ - public SocketPool getSocketPool() { - return socketPool; - } - - /** - * Handles the incoming accepted socket. The default implementation simply - * delegates the handling process to an {@link IncomingSocketCommandHandler} - * . Subclasses may extend this method to provide their own implementation. - * - * @param socket - * the accepted socket to handle, never null - */ - protected void runIncomingCommandHandler(Socket socket) { - createIncomingCommandHandler(socket).schedule(); - } - - /** - * Creates a socket command handler for the given accepted socket. The - * default implementation returns an {@link IncomingSocketCommandHandler}. - * Subclasses may extend this method to provide their own implementation. - * - * @param socket - * the accepted socket to handle, never null - * @return a socket command handler, never null - */ - protected Job createIncomingCommandHandler(Socket socket) { - IncomingSocketCommandHandler handler = new IncomingSocketCommandHandler( - socket); - handler.setSocketPool(getSocketPool()); - return handler; - } - - /** - * Returns the name of the command server loop thread. Subclasses may extend - * this method to provide their own name for the loop thread. - * - * @return a name, never null - */ - protected String getLoopThreadName() { - return "SocketCommandServerLoop"; //$NON-NLS-1$ - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { - if (adapter == SocketPool.class) - return getSocketPool(); - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.remote.socket; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.xmind.core.command.remote.ICommandServer; +import org.xmind.core.command.remote.ICommandServiceDomain; +import org.xmind.core.command.remote.ICommandServiceInfo; +import org.xmind.core.internal.command.remote.Messages; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * This class provides basic implementations of a command server that relies on + * a server socket. + * + * @author Frank Shaka + */ +public class SocketCommandServer implements ICommandServer { + + private ICommandServiceDomain domain; + + private int defaultPort; + + private int defaultBacklog; + + private boolean triesEphemeralPort; + + private ServerSocket server = null; + + private Thread thread = null; + + private SocketCommandServiceInfo info = null; + + private Object lock = new Object(); + + private Runnable serverRunner = new Runnable() { + + /** + * Runs the server handling loop. Accepts all socket connections and + * fork them into separate handling job. + */ + public void run() { + ServerSocket theServer = server; + if (theServer == null) + return; + + try { + while (true) { + Socket socket = theServer.accept(); + socketPool.addSocket(socket); + runIncomingCommandHandler(socket); + } + } catch (IOException e) { + if (thread != null || server != null) { + RemoteCommandPlugin + .log("Error occurred while handling local command server.", //$NON-NLS-1$ + e); + } + } finally { + try { + theServer.close(); + } catch (IOException e) { + } + } + } + + }; + + private SocketPool socketPool = new SocketPool(); + + /** + * Constructs a new instance using default configurations, i.e. an ephemeral + * port as the default port, a backlog valued 50. + */ + public SocketCommandServer() { + this(0, 50, false); + } + + /** + * Constructs a new instance with specified configurations. + * + * @param defaultPort + * the default port number + * @param defaultBacklog + * the default connection waiting queue size + * @param triesEphemeralPort + * true to indicate that an ephemeral port will be + * tried if the default port fails to be bound to, which makes + * the best effort to ensure the command server started up, or + * false if no other port number than the default + * one should be tried to make the command server either fix on + * the given port number or just fail + */ + public SocketCommandServer(int defaultPort, int defaultBacklog, + boolean triesEphemeralPort) { + if (defaultPort < 0) + defaultPort = 0; + this.defaultPort = defaultPort; + this.defaultBacklog = defaultBacklog; + this.triesEphemeralPort = triesEphemeralPort; + } + + public void init(ICommandServiceDomain domain) { + this.domain = domain; + } + + /** + * @return the domain + */ + public ICommandServiceDomain getDomain() { + return domain; + } + + /** + * @return the defaultBacklog + */ + public int getDefaultBacklog() { + return defaultBacklog; + } + + /** + * @return the defaultPort + */ + public int getDefaultPort() { + return defaultPort; + } + + /** + * @return the server + */ + public ServerSocket getServer() { + return server; + } + + /** + * Returns the thread that handles the server socket's events. It is + * referred to as 'the loop thread' in this class. + * + * @return the loop thread, or null if the command server is + * not deployed or has been undeployed + */ + public Thread getThread() { + return thread; + } + + /** + * Deploys this command server using a server socket. + * + *

+ * This method will first try to bind the server socket to the default port. + * If that fails, it will use an ephemeral port provided by the system. + *

+ * + *

+ * A daemon thread will be started once the server socket is ready. The + * thread will start a loop of accepting new socket connections on the + * server socket and starting an {@link org.eclipse.core.runtime.jobs.Job} + * to handle the command coming in through the accepted socket connection. + *

+ * + * @param monitor + * the progress monitor + * @return the status of the deployment + */ + public IStatus deploy(IProgressMonitor monitor) { + monitor.beginTask(null, 100); + monitor.subTask(Messages.SocketCommandServer_OperationLock); + + synchronized (lock) { + monitor.subTask(Messages.SocketCommandServer_OpenCommandServerSocket); + + if (server == null || server.isClosed()) { + try { + server = new ServerSocket(); + } catch (IOException e) { + return new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, null, e); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(20); + + InetAddress localAddress = null; + int port = defaultPort; + try { + server.bind(new InetSocketAddress(localAddress, port), + defaultBacklog); + } catch (IOException e) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + if (port != 0 && triesEphemeralPort) { + try { + server.bind(new InetSocketAddress(localAddress, 0), + defaultBacklog); + } catch (IOException e1) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + return new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, null, e); + } + } else { + return new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, null, e); + } + } + + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(60); + + } else { + monitor.worked(70); + } + + if (info == null) { + info = new SocketCommandServiceInfo(); + info.setAddress(new SocketAddress(server.getInetAddress() + .getHostName(), server.getLocalPort())); + info.setName(System.getProperty("user.name")); //$NON-NLS-1$ + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(10); + + if (thread == null) { + thread = new Thread(serverRunner, getLoopThreadName()); + thread.setDaemon(true); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(10); + + monitor.done(); + return Status.OK_STATUS; + } + } + + /** + * Undeploys this command server. First, the daemon looping thread will be + * interrupted. Then the server socket opened by + * {@link #deploy(IProgressMonitor)} will be closed. + * + * @param monitor + * the progress monitor + * @return the status of the undeployment + */ + public IStatus undeploy(IProgressMonitor monitor) { + monitor.beginTask(null, 100); + monitor.subTask(Messages.SocketCommandServer_OperationLock); + + synchronized (lock) { + monitor.subTask(Messages.SocketCommandServer_CloseCommandServerSocket); + + Thread oldThread = thread; + ServerSocket oldServer = server; + thread = null; + server = null; + info = null; + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(10); + + if (oldThread != null) { + oldThread.interrupt(); + } + if (oldServer != null) { + try { + oldServer.close(); + } catch (IOException e) { + RemoteCommandPlugin.log( + "Could not stop local command server socket.", e); //$NON-NLS-1$ + } + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(90); + + socketPool.clear(); + + monitor.done(); + return Status.OK_STATUS; + } + } + + public ICommandServiceInfo getRegisteringInfo() { + return info; + } + + /** + * Returns the socket pool owned by this command server. A socket pool + * maintains a list of all active sockets and provides a method to close all + * active sockets. + * + * @return the socket pool + */ + public SocketPool getSocketPool() { + return socketPool; + } + + /** + * Handles the incoming accepted socket. The default implementation simply + * delegates the handling process to an {@link IncomingSocketCommandHandler} + * . Subclasses may extend this method to provide their own implementation. + * + * @param socket + * the accepted socket to handle, never null + */ + protected void runIncomingCommandHandler(Socket socket) { + createIncomingCommandHandler(socket).schedule(); + } + + /** + * Creates a socket command handler for the given accepted socket. The + * default implementation returns an {@link IncomingSocketCommandHandler}. + * Subclasses may extend this method to provide their own implementation. + * + * @param socket + * the accepted socket to handle, never null + * @return a socket command handler, never null + */ + protected Job createIncomingCommandHandler(Socket socket) { + IncomingSocketCommandHandler handler = new IncomingSocketCommandHandler( + socket); + handler.setSocketPool(getSocketPool()); + return handler; + } + + /** + * Returns the name of the command server loop thread. Subclasses may extend + * this method to provide their own name for the loop thread. + * + * @return a name, never null + */ + protected String getLoopThreadName() { + return "SocketCommandServerLoop"; //$NON-NLS-1$ + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { + if (adapter == SocketPool.class) + return getSocketPool(); + return null; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServiceInfo.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServiceInfo.java index ac2f3f474..0fbda3192 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServiceInfo.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketCommandServiceInfo.java @@ -1,77 +1,77 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.remote.socket; - -import org.xmind.core.command.remote.CommandServiceInfo; -import org.xmind.core.command.remote.ICommandServiceInfo; - -/** - * Command service info used by a socket command server. - * - * @author Frank Shaka - */ -public class SocketCommandServiceInfo extends CommandServiceInfo { - - private ISocketAddress address; - - /** - * - */ - public SocketCommandServiceInfo() { - super(); - } - - /** - * @param source - */ - public SocketCommandServiceInfo(ICommandServiceInfo source) { - super(source); - if (source instanceof SocketCommandServiceInfo) { - this.address = ((SocketCommandServiceInfo) source).address; - } - } - - @SuppressWarnings("rawtypes") - public Object getAdapter(Class adapter) { - if (adapter == ISocketAddress.class) - return address; - return super.getAdapter(adapter); - } - - public ISocketAddress getAddress() { - return address; - } - - public void setAddress(ISocketAddress address) { - this.address = address; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("SocketCommandServiceInfo{id="); //$NON-NLS-1$ - sb.append(getId()); - sb.append(",name="); //$NON-NLS-1$ - sb.append(getName()); - sb.append(",address="); //$NON-NLS-1$ - sb.append(address); - sb.append(",metadata="); //$NON-NLS-1$ - sb.append(getMetadataImpl()); - sb.append('}'); - return sb.toString(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.remote.socket; + +import org.xmind.core.command.remote.CommandServiceInfo; +import org.xmind.core.command.remote.ICommandServiceInfo; + +/** + * Command service info used by a socket command server. + * + * @author Frank Shaka + */ +public class SocketCommandServiceInfo extends CommandServiceInfo { + + private ISocketAddress address; + + /** + * + */ + public SocketCommandServiceInfo() { + super(); + } + + /** + * @param source + */ + public SocketCommandServiceInfo(ICommandServiceInfo source) { + super(source); + if (source instanceof SocketCommandServiceInfo) { + this.address = ((SocketCommandServiceInfo) source).address; + } + } + + @SuppressWarnings("rawtypes") + public Object getAdapter(Class adapter) { + if (adapter == ISocketAddress.class) + return address; + return super.getAdapter(adapter); + } + + public ISocketAddress getAddress() { + return address; + } + + public void setAddress(ISocketAddress address) { + this.address = address; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SocketCommandServiceInfo{id="); //$NON-NLS-1$ + sb.append(getId()); + sb.append(",name="); //$NON-NLS-1$ + sb.append(getName()); + sb.append(",address="); //$NON-NLS-1$ + sb.append(address); + sb.append(",metadata="); //$NON-NLS-1$ + sb.append(getMetadataImpl()); + sb.append('}'); + return sb.toString(); + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketPool.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketPool.java index 20624dc48..13e45a629 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketPool.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/remote/socket/SocketPool.java @@ -1,70 +1,70 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.remote.socket; - -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; - -/** - * A socket pool maintains a list of socket objects and provides a method to - * clear/close all maintained sockets. - * - * @author Frank Shaka - */ -public class SocketPool { - - private List sockets = new ArrayList(); - - public SocketPool() { - } - - /** - * Registers a socket. - * - * @param socket - */ - public synchronized void addSocket(Socket socket) { - sockets.add(socket); - } - - /** - * Unregisters a socket. - * - * @param socket - */ - public synchronized void removeSocket(Socket socket) { - sockets.remove(socket); - } - - /** - * Clears and closes all registered sockets. - */ - public synchronized void clear() { - Object[] theSockets = sockets.toArray(); - sockets.clear(); - for (int i = 0; i < theSockets.length; i++) { - Socket socket = ((Socket) theSockets[i]); - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - // ignore close exceptions - } - } - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.remote.socket; + +import java.io.IOException; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +/** + * A socket pool maintains a list of socket objects and provides a method to + * clear/close all maintained sockets. + * + * @author Frank Shaka + */ +public class SocketPool { + + private List sockets = new ArrayList(); + + public SocketPool() { + } + + /** + * Registers a socket. + * + * @param socket + */ + public synchronized void addSocket(Socket socket) { + sockets.add(socket); + } + + /** + * Unregisters a socket. + * + * @param socket + */ + public synchronized void removeSocket(Socket socket) { + sockets.remove(socket); + } + + /** + * Clears and closes all registered sockets. + */ + public synchronized void clear() { + Object[] theSockets = sockets.toArray(); + sockets.clear(); + for (int i = 0; i < theSockets.length; i++) { + Socket socket = ((Socket) theSockets[i]); + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + // ignore close exceptions + } + } + } + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkReader.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkReader.java index ce649a3fa..64e125f41 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkReader.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkReader.java @@ -1,373 +1,373 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.transfer; - -import java.io.Closeable; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.UnmappableCharacterException; -import java.util.Arrays; - -/** - * A helper class that reads data from an input stream in chunks. - * - * @author Frank Shaka - * @see ChunkWriter - */ -public class ChunkReader implements Closeable { - - private class ChunkInputStream extends FilterInputStream { - - private boolean closed = false; - - public ChunkInputStream(InputStream in) { - super(in); - chunkEnded = false; - } - - @Override - public int read() throws IOException { - if (closed) - throw new IOException("Stream already closed."); //$NON-NLS-1$ - if (chunkEnded && binaryBuffered <= 0) - return -1; - if (binaryBuffered <= 0) { - refillBinary(); - } - if (chunkEnded && binaryBuffered <= 0) - return -1; - byte b = binaryBuffer[0]; - useBinary(1); - return b; - } - - @Override - public int read(byte[] b) throws IOException { - if (closed) - throw new IOException("Stream already closed."); //$NON-NLS-1$ - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (closed) - throw new IOException("Stream already closed."); //$NON-NLS-1$ - if (off < 0 || off + len > b.length) - throw new IndexOutOfBoundsException( - "Offset or length out of bounds."); //$NON-NLS-1$ - int read = 0; - while (len > 0) { - if (chunkEnded && binaryBuffered <= 0) - break; - if (binaryBuffered <= 0) { - refillBinary(); - } - if (chunkEnded && binaryBuffered <= 0) - break; - int size = Math.min(len, binaryBuffered); - System.arraycopy(binaryBuffer, 0, b, off, size); - read += size; - off += size; - len -= size; - useBinary(size); - } - if (read == 0) - read = -1; - return read; - } - - @Override - public void close() throws IOException { - closed = true; - binaryBuffered = 0; - } - - } - - private static final byte DEFAULT_CHUNK_SEPARATOR = (byte) '\n'; - - private static final String DEFAULT_TEXT_ENCODING = "UTF-8"; //$NON-NLS-1$ - - private static final int DEFAULT_BUFFER_SIZE = 4096; - - private static final int DEFAULT_TEXT_BUFFER_SIZE = 1024; - - private static final int DEFAULT_BINARY_BUFFER_SIZE = DEFAULT_BUFFER_SIZE / 4 * 3; - - private static final String EMPTY_TEXT = ""; //$NON-NLS-1$ - - /** - * This array is a lookup table that translates unicode characters drawn - * from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into - * their 6-bit positive integer equivalents. Characters that are not in the - * Base64 alphabet but fall within the bounds of the array are translated to - * -1. - */ - private static final byte base64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, - -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; - - private InputStream in; - - private String textEncoding; - - private byte separator; - - private boolean eof = false; - - private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - - private int buffered = 0; - - private byte[] textBuffer = new byte[DEFAULT_TEXT_BUFFER_SIZE]; - - private ChunkInputStream binaryStream = null; - - private byte[] binaryBuffer = new byte[DEFAULT_BINARY_BUFFER_SIZE]; - - private int binaryBuffered = 0; - - private boolean chunkEnded = false; - - public ChunkReader(InputStream in) { - this(in, DEFAULT_CHUNK_SEPARATOR, DEFAULT_TEXT_ENCODING); - } - - public ChunkReader(InputStream in, byte chunkSeparator, String textEncoding) { - this.in = in; - this.separator = chunkSeparator; - this.textEncoding = textEncoding; - } - - private boolean isStreamEnded() { - return eof && buffered <= 0; - } - - private boolean isBinaryChunkEnded() { - return chunkEnded && binaryBuffered <= 0; - } - - /** - * Read a line of text and return it. - * - * @return a line of text, or null if the main stream has - * reached the end - * @throws IOException - */ - public String readText() throws IOException { - closeBinaryStream(true); - - // The number of bytes to return as text. - int size = 0; - - // The index of the separator char in the byte buffer. - int sep; - - // A new number of bytes that we need to enlarge the text buffer. - int newSize; - - // The number of bytes in buffer. - int numBuffered; - - // The total number of bytes that we consumed from the stream. - // This number may be one more than 'size' as we consume the separator - // char as well. - int consumed = 0; - - // Run until the end of stream is reached. - while (!isStreamEnded()) { - - // Find the next separator char in the byte buffer, - // or the end of the byte buffer. - sep = findSep(0); - - // Calculate new text buffer size. - newSize = size + sep; - - // Enlarge the text buffer to receive new bytes. - if (newSize > textBuffer.length) { - textBuffer = Arrays.copyOf(textBuffer, - Math.max(textBuffer.length << 1, newSize)); - } - - // Copy required bytes from byte buffer to text buffer. - if (sep > 0) { - System.arraycopy(buffer, 0, textBuffer, size, sep); - } - - // Now we have 'size' bytes in the text buffer. - size = newSize; - - // Consume bytes from the byte buffer. - numBuffered = buffered; - if (sep == numBuffered) { - use(numBuffered); - consumed += numBuffered; - } else { - use(sep + 1); - consumed += sep + 1; - break; - } - - // Reload byte buffer from the stream. - reload(); - } - - // No bytes consumed from stream, this must be caused by the end of stream, - // otherwise there must have been at least one separator char. - if (consumed == 0) - return null; - - // Return the cached empty string to prevent creating a new String instance. - if (size == 0) - return EMPTY_TEXT; - - // Construct a new String instance from the text buffer. - return new String(textBuffer, 0, size, textEncoding); - } - - /** - * Create a stream for reading the next chunk of data. - * - * @return an input stream for reading the next chunk of data, or - * null if the main stream has reached the end - * @throws IOException - */ - public InputStream openNextChunkAsStream() throws IOException { - closeBinaryStream(true); - if (isStreamEnded()) - return null; - return binaryStream = new ChunkInputStream(in); - } - - private void closeBinaryStream(boolean drain) throws IOException { - if (binaryStream != null && !binaryStream.closed - && !isBinaryChunkEnded()) { - if (drain) { - byte[] buf = new byte[4096]; - while (binaryStream.read(buf) > 0) { - } - } - binaryStream.close(); - binaryStream = null; - } - } - - public void close() throws IOException { - closeBinaryStream(false); - in.close(); - } - - private void reload() throws IOException { - if (eof) - return; - if (!eof && buffered < buffer.length) { - int len = buffer.length - buffered; - int read = in.read(buffer, buffered, len); - if (read < 0) { - eof = true; - read = 0; - } - buffered += read; - } - } - - private static int base64toInt(byte c) throws IOException { - int b = base64ToInt[c]; - if (b < 0) - throw new UnmappableCharacterException(1); - return b; - } - - private int findSep(int off) { - for (int i = off; i < buffered; i++) { - if (buffer[i] == separator) - return i; - } - return buffered; - } - - private void use(int used) { - if (used >= buffered) { - buffered = 0; - } else { - int newCount = buffered - used; - System.arraycopy(buffer, used, buffer, 0, newCount); - buffered = newCount; - } - } - - private void refillBinary() throws IOException { - reload(); - if (eof) { - chunkEnded = true; - } - int used = 0; - int max = buffered - 3; - int bmax = binaryBuffer.length - 2; - while (used < max && binaryBuffered < bmax) { - byte b0 = buffer[used++]; - if (b0 == separator) { - chunkEnded = true; - break; - } - byte b1 = buffer[used++]; - if (b1 == separator) { - chunkEnded = true; - break; - } - byte b2 = buffer[used++]; - if (b2 == separator) { - chunkEnded = true; - break; - } - byte b3 = buffer[used++]; - if (b3 == separator) { - chunkEnded = true; - break; - } - - int c0 = base64toInt(b0); - int c1 = base64toInt(b1); - binaryBuffer[binaryBuffered++] = (byte) ((c0 << 2) | (c1 >> 4)); - - if (b2 != '=') { - int c2 = base64toInt(b2); - binaryBuffer[binaryBuffered++] = (byte) ((c1 << 4) | (c2 >> 2)); - if (b3 != '=') { - int c3 = base64toInt(b3); - binaryBuffer[binaryBuffered++] = (byte) ((c2 << 6) | c3); - } - } - } - use(used); - } - - private void useBinary(int used) { - if (used >= binaryBuffered) { - binaryBuffered = 0; - } else { - int newCount = binaryBuffered - used; - System.arraycopy(binaryBuffer, used, binaryBuffer, 0, newCount); - binaryBuffered = newCount; - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.transfer; + +import java.io.Closeable; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.UnmappableCharacterException; +import java.util.Arrays; + +/** + * A helper class that reads data from an input stream in chunks. + * + * @author Frank Shaka + * @see ChunkWriter + */ +public class ChunkReader implements Closeable { + + private class ChunkInputStream extends FilterInputStream { + + private boolean closed = false; + + public ChunkInputStream(InputStream in) { + super(in); + chunkEnded = false; + } + + @Override + public int read() throws IOException { + if (closed) + throw new IOException("Stream already closed."); //$NON-NLS-1$ + if (chunkEnded && binaryBuffered <= 0) + return -1; + if (binaryBuffered <= 0) { + refillBinary(); + } + if (chunkEnded && binaryBuffered <= 0) + return -1; + byte b = binaryBuffer[0]; + useBinary(1); + return b; + } + + @Override + public int read(byte[] b) throws IOException { + if (closed) + throw new IOException("Stream already closed."); //$NON-NLS-1$ + return read(b, 0, b.length); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (closed) + throw new IOException("Stream already closed."); //$NON-NLS-1$ + if (off < 0 || off + len > b.length) + throw new IndexOutOfBoundsException( + "Offset or length out of bounds."); //$NON-NLS-1$ + int read = 0; + while (len > 0) { + if (chunkEnded && binaryBuffered <= 0) + break; + if (binaryBuffered <= 0) { + refillBinary(); + } + if (chunkEnded && binaryBuffered <= 0) + break; + int size = Math.min(len, binaryBuffered); + System.arraycopy(binaryBuffer, 0, b, off, size); + read += size; + off += size; + len -= size; + useBinary(size); + } + if (read == 0) + read = -1; + return read; + } + + @Override + public void close() throws IOException { + closed = true; + binaryBuffered = 0; + } + + } + + private static final byte DEFAULT_CHUNK_SEPARATOR = (byte) '\n'; + + private static final String DEFAULT_TEXT_ENCODING = "UTF-8"; //$NON-NLS-1$ + + private static final int DEFAULT_BUFFER_SIZE = 4096; + + private static final int DEFAULT_TEXT_BUFFER_SIZE = 1024; + + private static final int DEFAULT_BINARY_BUFFER_SIZE = DEFAULT_BUFFER_SIZE / 4 * 3; + + private static final String EMPTY_TEXT = ""; //$NON-NLS-1$ + + /** + * This array is a lookup table that translates unicode characters drawn + * from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into + * their 6-bit positive integer equivalents. Characters that are not in the + * Base64 alphabet but fall within the bounds of the array are translated to + * -1. + */ + private static final byte base64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, + -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, + -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; + + private InputStream in; + + private String textEncoding; + + private byte separator; + + private boolean eof = false; + + private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + + private int buffered = 0; + + private byte[] textBuffer = new byte[DEFAULT_TEXT_BUFFER_SIZE]; + + private ChunkInputStream binaryStream = null; + + private byte[] binaryBuffer = new byte[DEFAULT_BINARY_BUFFER_SIZE]; + + private int binaryBuffered = 0; + + private boolean chunkEnded = false; + + public ChunkReader(InputStream in) { + this(in, DEFAULT_CHUNK_SEPARATOR, DEFAULT_TEXT_ENCODING); + } + + public ChunkReader(InputStream in, byte chunkSeparator, String textEncoding) { + this.in = in; + this.separator = chunkSeparator; + this.textEncoding = textEncoding; + } + + private boolean isStreamEnded() { + return eof && buffered <= 0; + } + + private boolean isBinaryChunkEnded() { + return chunkEnded && binaryBuffered <= 0; + } + + /** + * Read a line of text and return it. + * + * @return a line of text, or null if the main stream has + * reached the end + * @throws IOException + */ + public String readText() throws IOException { + closeBinaryStream(true); + + // The number of bytes to return as text. + int size = 0; + + // The index of the separator char in the byte buffer. + int sep; + + // A new number of bytes that we need to enlarge the text buffer. + int newSize; + + // The number of bytes in buffer. + int numBuffered; + + // The total number of bytes that we consumed from the stream. + // This number may be one more than 'size' as we consume the separator + // char as well. + int consumed = 0; + + // Run until the end of stream is reached. + while (!isStreamEnded()) { + + // Find the next separator char in the byte buffer, + // or the end of the byte buffer. + sep = findSep(0); + + // Calculate new text buffer size. + newSize = size + sep; + + // Enlarge the text buffer to receive new bytes. + if (newSize > textBuffer.length) { + textBuffer = Arrays.copyOf(textBuffer, + Math.max(textBuffer.length << 1, newSize)); + } + + // Copy required bytes from byte buffer to text buffer. + if (sep > 0) { + System.arraycopy(buffer, 0, textBuffer, size, sep); + } + + // Now we have 'size' bytes in the text buffer. + size = newSize; + + // Consume bytes from the byte buffer. + numBuffered = buffered; + if (sep == numBuffered) { + use(numBuffered); + consumed += numBuffered; + } else { + use(sep + 1); + consumed += sep + 1; + break; + } + + // Reload byte buffer from the stream. + reload(); + } + + // No bytes consumed from stream, this must be caused by the end of stream, + // otherwise there must have been at least one separator char. + if (consumed == 0) + return null; + + // Return the cached empty string to prevent creating a new String instance. + if (size == 0) + return EMPTY_TEXT; + + // Construct a new String instance from the text buffer. + return new String(textBuffer, 0, size, textEncoding); + } + + /** + * Create a stream for reading the next chunk of data. + * + * @return an input stream for reading the next chunk of data, or + * null if the main stream has reached the end + * @throws IOException + */ + public InputStream openNextChunkAsStream() throws IOException { + closeBinaryStream(true); + if (isStreamEnded()) + return null; + return binaryStream = new ChunkInputStream(in); + } + + private void closeBinaryStream(boolean drain) throws IOException { + if (binaryStream != null && !binaryStream.closed + && !isBinaryChunkEnded()) { + if (drain) { + byte[] buf = new byte[4096]; + while (binaryStream.read(buf) > 0) { + } + } + binaryStream.close(); + binaryStream = null; + } + } + + public void close() throws IOException { + closeBinaryStream(false); + in.close(); + } + + private void reload() throws IOException { + if (eof) + return; + if (!eof && buffered < buffer.length) { + int len = buffer.length - buffered; + int read = in.read(buffer, buffered, len); + if (read < 0) { + eof = true; + read = 0; + } + buffered += read; + } + } + + private static int base64toInt(byte c) throws IOException { + int b = base64ToInt[c]; + if (b < 0) + throw new UnmappableCharacterException(1); + return b; + } + + private int findSep(int off) { + for (int i = off; i < buffered; i++) { + if (buffer[i] == separator) + return i; + } + return buffered; + } + + private void use(int used) { + if (used >= buffered) { + buffered = 0; + } else { + int newCount = buffered - used; + System.arraycopy(buffer, used, buffer, 0, newCount); + buffered = newCount; + } + } + + private void refillBinary() throws IOException { + reload(); + if (eof) { + chunkEnded = true; + } + int used = 0; + int max = buffered - 3; + int bmax = binaryBuffer.length - 2; + while (used < max && binaryBuffered < bmax) { + byte b0 = buffer[used++]; + if (b0 == separator) { + chunkEnded = true; + break; + } + byte b1 = buffer[used++]; + if (b1 == separator) { + chunkEnded = true; + break; + } + byte b2 = buffer[used++]; + if (b2 == separator) { + chunkEnded = true; + break; + } + byte b3 = buffer[used++]; + if (b3 == separator) { + chunkEnded = true; + break; + } + + int c0 = base64toInt(b0); + int c1 = base64toInt(b1); + binaryBuffer[binaryBuffered++] = (byte) ((c0 << 2) | (c1 >> 4)); + + if (b2 != '=') { + int c2 = base64toInt(b2); + binaryBuffer[binaryBuffered++] = (byte) ((c1 << 4) | (c2 >> 2)); + if (b3 != '=') { + int c3 = base64toInt(b3); + binaryBuffer[binaryBuffered++] = (byte) ((c2 << 6) | c3); + } + } + } + use(used); + } + + private void useBinary(int used) { + if (used >= binaryBuffered) { + binaryBuffered = 0; + } else { + int newCount = binaryBuffered - used; + System.arraycopy(binaryBuffer, used, binaryBuffer, 0, newCount); + binaryBuffered = newCount; + } + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkWriter.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkWriter.java index 0abcacbc4..2067b82f1 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkWriter.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/ChunkWriter.java @@ -1,235 +1,235 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.transfer; - -import java.io.Closeable; -import java.io.FilterOutputStream; -import java.io.Flushable; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A helper class that writes data to an output stream in chunks. - * - * @author Frank Shaka - * @see ChunkReader - */ -public class ChunkWriter implements Closeable, Flushable { - - private class ChunkOutputStream extends FilterOutputStream { - - private boolean closed = false; - - public ChunkOutputStream(OutputStream out) { - super(out); - } - - @Override - public void close() throws IOException { - flushBinaryBuffer(true); - flushBuffer(); - if (!closed) { - out.write(separator); - out.flush(); - } - closed = true; - } - - @Override - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (closed) - throw new IOException("Stream already closed."); //$NON-NLS-1$ - for (int i = 0; i < len; i++) { - appendToBuffer(b[off + i]); - } - } - - @Override - public void write(int b) throws IOException { - if (closed) - throw new IOException("Stream already closed."); //$NON-NLS-1$ - appendToBuffer((byte) (b & 0xff)); - } - - @Override - public void flush() throws IOException { - flushBinaryBuffer(false); - flushBuffer(); - out.flush(); - } - - } - - private static final byte DEFAULT_CHUNK_SEPARATOR = (byte) '\n'; - - private static final String DEFAULT_TEXT_ENCODING = "UTF-8"; //$NON-NLS-1$ - - private static final int DEFAULT_BUFFER_SIZE = 16; - - private static final int DEFAULT_BINARY_BUFFER_SIZE = DEFAULT_BUFFER_SIZE / 4 * 3; - - /** - * This array is a lookup table that translates 6-bit positive integer index - * values into their "Base64 Alphabet" equivalents as specified in Table 1 - * of RFC 2045. - */ - private static final byte intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', - 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' }; - - private OutputStream out; - - private String textEncoding; - - private byte separator; - - private ChunkOutputStream binaryStream = null; - - private byte[] binaryBuffer = new byte[DEFAULT_BINARY_BUFFER_SIZE]; - - private int binaryBuffered = 0; - - private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - - private int buffered = 0; - - public ChunkWriter(OutputStream out) { - this(out, DEFAULT_CHUNK_SEPARATOR, DEFAULT_TEXT_ENCODING); - } - - public ChunkWriter(OutputStream out, byte chunkSeparator, - String textEncoding) { - this.out = out; - this.separator = chunkSeparator; - this.textEncoding = textEncoding; - } - - public synchronized void writeText(String text) throws IOException { - closeBinaryStream(); - if (text == null) - text = ""; //$NON-NLS-1$ - byte[] bytes = text.getBytes(textEncoding); - out.write(bytes); - out.write(separator); - out.flush(); - } - - public synchronized OutputStream openNextChunkAsStream() throws IOException { - closeBinaryStream(); - return binaryStream = new ChunkOutputStream(out); - } - - public synchronized void close() throws IOException { - closeBinaryStream(); - try { - out.flush(); - } finally { - out.close(); - } - } - - public synchronized void flush() throws IOException { - flushBinaryBuffer(false); - flushBuffer(); - out.flush(); - } - - private synchronized void closeBinaryStream() throws IOException { - if (binaryStream != null && !binaryStream.closed) { - binaryStream.close(); - binaryStream = null; - } - } - - private synchronized void appendToBuffer(byte b) throws IOException { - binaryBuffer[binaryBuffered++] = b; - if (binaryBuffered >= binaryBuffer.length) { - int off = 0; - while (off < binaryBuffered) { - int b0 = binaryBuffer[off++] & 0xff; - int b1 = off >= binaryBuffered ? -1 - : binaryBuffer[off++] & 0xff; - int b2 = off >= binaryBuffered ? -1 - : binaryBuffer[off++] & 0xff; - writeBinary(b0, b1, b2); - } - binaryBuffered = 0; - } - } - - private synchronized void writeBinary(int b0, int b1, int b2) - throws IOException { - buffer[buffered++] = intToBase64[b0 >> 2]; - if (b1 < 0) { - buffer[buffered++] = intToBase64[(b0 << 4) & 0x3f]; - buffer[buffered++] = '='; - buffer[buffered++] = '='; - } else { - buffer[buffered++] = intToBase64[(b0 << 4) & 0x3f | (b1 >> 4)]; - if (b2 < 0) { - buffer[buffered++] = intToBase64[(b1 << 2) & 0x3f]; - buffer[buffered++] = '='; - } else { - buffer[buffered++] = intToBase64[(b1 << 2) & 0x3f | (b2 >> 6)]; - buffer[buffered++] = intToBase64[b2 & 0x3f]; - } - } - if (buffered >= buffer.length || b2 < 0) { - try { - out.write(buffer, 0, buffered); - } finally { - buffered = 0; - } - } - } - - private synchronized void flushBinaryBuffer(boolean all) throws IOException { - if (binaryBuffered > 0) { - int off = 0; - int max = all ? binaryBuffered : binaryBuffered - 2; - while (off < max) { - int b0 = binaryBuffer[off++] & 0xff; - int b1 = off >= binaryBuffered ? -1 - : binaryBuffer[off++] & 0xff; - int b2 = off >= binaryBuffered ? -1 - : binaryBuffer[off++] & 0xff; - writeBinary(b0, b1, b2); - } - int newCount = binaryBuffered - off; - if (newCount > 0) { - System.arraycopy(binaryBuffer, off, binaryBuffer, 0, newCount); - } - binaryBuffered = newCount; - } - } - - private synchronized void flushBuffer() throws IOException { - if (buffered > 0) { - try { - out.write(buffer, 0, buffered); - } finally { - buffered = 0; - } - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.transfer; + +import java.io.Closeable; +import java.io.FilterOutputStream; +import java.io.Flushable; +import java.io.IOException; +import java.io.OutputStream; + +/** + * A helper class that writes data to an output stream in chunks. + * + * @author Frank Shaka + * @see ChunkReader + */ +public class ChunkWriter implements Closeable, Flushable { + + private class ChunkOutputStream extends FilterOutputStream { + + private boolean closed = false; + + public ChunkOutputStream(OutputStream out) { + super(out); + } + + @Override + public void close() throws IOException { + flushBinaryBuffer(true); + flushBuffer(); + if (!closed) { + out.write(separator); + out.flush(); + } + closed = true; + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (closed) + throw new IOException("Stream already closed."); //$NON-NLS-1$ + for (int i = 0; i < len; i++) { + appendToBuffer(b[off + i]); + } + } + + @Override + public void write(int b) throws IOException { + if (closed) + throw new IOException("Stream already closed."); //$NON-NLS-1$ + appendToBuffer((byte) (b & 0xff)); + } + + @Override + public void flush() throws IOException { + flushBinaryBuffer(false); + flushBuffer(); + out.flush(); + } + + } + + private static final byte DEFAULT_CHUNK_SEPARATOR = (byte) '\n'; + + private static final String DEFAULT_TEXT_ENCODING = "UTF-8"; //$NON-NLS-1$ + + private static final int DEFAULT_BUFFER_SIZE = 16; + + private static final int DEFAULT_BINARY_BUFFER_SIZE = DEFAULT_BUFFER_SIZE / 4 * 3; + + /** + * This array is a lookup table that translates 6-bit positive integer index + * values into their "Base64 Alphabet" equivalents as specified in Table 1 + * of RFC 2045. + */ + private static final byte intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' }; + + private OutputStream out; + + private String textEncoding; + + private byte separator; + + private ChunkOutputStream binaryStream = null; + + private byte[] binaryBuffer = new byte[DEFAULT_BINARY_BUFFER_SIZE]; + + private int binaryBuffered = 0; + + private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + + private int buffered = 0; + + public ChunkWriter(OutputStream out) { + this(out, DEFAULT_CHUNK_SEPARATOR, DEFAULT_TEXT_ENCODING); + } + + public ChunkWriter(OutputStream out, byte chunkSeparator, + String textEncoding) { + this.out = out; + this.separator = chunkSeparator; + this.textEncoding = textEncoding; + } + + public synchronized void writeText(String text) throws IOException { + closeBinaryStream(); + if (text == null) + text = ""; //$NON-NLS-1$ + byte[] bytes = text.getBytes(textEncoding); + out.write(bytes); + out.write(separator); + out.flush(); + } + + public synchronized OutputStream openNextChunkAsStream() throws IOException { + closeBinaryStream(); + return binaryStream = new ChunkOutputStream(out); + } + + public synchronized void close() throws IOException { + closeBinaryStream(); + try { + out.flush(); + } finally { + out.close(); + } + } + + public synchronized void flush() throws IOException { + flushBinaryBuffer(false); + flushBuffer(); + out.flush(); + } + + private synchronized void closeBinaryStream() throws IOException { + if (binaryStream != null && !binaryStream.closed) { + binaryStream.close(); + binaryStream = null; + } + } + + private synchronized void appendToBuffer(byte b) throws IOException { + binaryBuffer[binaryBuffered++] = b; + if (binaryBuffered >= binaryBuffer.length) { + int off = 0; + while (off < binaryBuffered) { + int b0 = binaryBuffer[off++] & 0xff; + int b1 = off >= binaryBuffered ? -1 + : binaryBuffer[off++] & 0xff; + int b2 = off >= binaryBuffered ? -1 + : binaryBuffer[off++] & 0xff; + writeBinary(b0, b1, b2); + } + binaryBuffered = 0; + } + } + + private synchronized void writeBinary(int b0, int b1, int b2) + throws IOException { + buffer[buffered++] = intToBase64[b0 >> 2]; + if (b1 < 0) { + buffer[buffered++] = intToBase64[(b0 << 4) & 0x3f]; + buffer[buffered++] = '='; + buffer[buffered++] = '='; + } else { + buffer[buffered++] = intToBase64[(b0 << 4) & 0x3f | (b1 >> 4)]; + if (b2 < 0) { + buffer[buffered++] = intToBase64[(b1 << 2) & 0x3f]; + buffer[buffered++] = '='; + } else { + buffer[buffered++] = intToBase64[(b1 << 2) & 0x3f | (b2 >> 6)]; + buffer[buffered++] = intToBase64[b2 & 0x3f]; + } + } + if (buffered >= buffer.length || b2 < 0) { + try { + out.write(buffer, 0, buffered); + } finally { + buffered = 0; + } + } + } + + private synchronized void flushBinaryBuffer(boolean all) throws IOException { + if (binaryBuffered > 0) { + int off = 0; + int max = all ? binaryBuffered : binaryBuffered - 2; + while (off < max) { + int b0 = binaryBuffer[off++] & 0xff; + int b1 = off >= binaryBuffered ? -1 + : binaryBuffer[off++] & 0xff; + int b2 = off >= binaryBuffered ? -1 + : binaryBuffer[off++] & 0xff; + writeBinary(b0, b1, b2); + } + int newCount = binaryBuffered - off; + if (newCount > 0) { + System.arraycopy(binaryBuffer, off, binaryBuffer, 0, newCount); + } + binaryBuffered = newCount; + } + } + + private synchronized void flushBuffer() throws IOException { + if (buffered > 0) { + try { + out.write(buffer, 0, buffered); + } finally { + buffered = 0; + } + } + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/CommandTransferUtil.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/CommandTransferUtil.java index 9634ea886..c4e106a35 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/CommandTransferUtil.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/CommandTransferUtil.java @@ -1,149 +1,149 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.transfer; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Iterator; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.xmind.core.command.binary.BinaryStore; -import org.xmind.core.command.binary.IBinaryEntry; -import org.xmind.core.command.binary.IBinaryStore; - -/** - * This utility class provides constants and convenient methods to - * encode/decode/read/write data from/to input/output streams. - * - * @author Frank Shaka - */ -public class CommandTransferUtil { - - public static final String ENCODING = "UTF-8"; //$NON-NLS-1$ - - public static final String MARKER_PROPERTIES = "[PROPERTIES]"; //$NON-NLS-1$ - - public static final String MARKER_VALUES = "[VALUES]"; //$NON-NLS-1$ - - public static final String MARKER_FILES = "[FILES]"; //$NON-NLS-1$ - - private CommandTransferUtil() { - } - - public static String encode(String str) { - try { - return URLEncoder.encode(str, ENCODING); - } catch (UnsupportedEncodingException e) { - return str; - } - } - - public static String decode(String str) { - try { - return URLDecoder.decode(str, ENCODING); - } catch (UnsupportedEncodingException e) { - return str; - } - } - - public static IBinaryStore readFiles(IProgressMonitor monitor, - ChunkReader reader) throws IOException { - String numFilesStr = reader.readText(); - if (numFilesStr == null) - // Empty files - return null; - - int numFiles; - try { - numFiles = Integer.parseInt(numFilesStr, 10); - } catch (NumberFormatException e) { - throw new IOException( - "Invalid format of files number: " + numFilesStr); //$NON-NLS-1$ - } - monitor.beginTask(null, numFiles); - - IBinaryStore store = null; - String entryName; - try { - while ((entryName = reader.readText()) != null) { - if ("".equals(entryName) || monitor.isCanceled()) //$NON-NLS-1$ - break; - - InputStream chunkStream = reader.openNextChunkAsStream(); - if (chunkStream != null) { - IProgressMonitor fileMonitor = new SubProgressMonitor( - monitor, 1); - if (store == null) { - store = new BinaryStore(); - } - store.addEntry(fileMonitor, entryName, chunkStream); - if (monitor.isCanceled()) - return null; - fileMonitor.done(); - } - } - } catch (InterruptedException e) { - return null; - } - return store; - } - - public static void writeFiles(IProgressMonitor monitor, IBinaryStore files, - ChunkWriter writer) throws IOException { - monitor.beginTask(null, files.size()); - writer.writeText(String.valueOf(files.size())); - Iterator entryNames = files.entryNames(); - while (entryNames.hasNext()) { - String entryName = entryNames.next(); - IBinaryEntry entry = files.getEntry(entryName); - writer.writeText(entryName); - if (monitor.isCanceled()) - return; - if (entry != null && !entryName.endsWith("/")) { //$NON-NLS-1$ - InputStream in = entry.openInputStream(); - if (monitor.isCanceled()) - return; - try { - OutputStream out = writer.openNextChunkAsStream(); - if (monitor.isCanceled()) - return; - try { - byte[] buffer = new byte[4096]; - int read; - while ((read = in.read(buffer)) > 0) { - if (monitor.isCanceled()) - return; - out.write(buffer, 0, read); - } - } finally { - out.close(); - } - } finally { - in.close(); - } - } - if (monitor.isCanceled()) - return; - monitor.worked(1); - } - if (monitor.isCanceled()) - return; - monitor.done(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.transfer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Iterator; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.xmind.core.command.binary.BinaryStore; +import org.xmind.core.command.binary.IBinaryEntry; +import org.xmind.core.command.binary.IBinaryStore; + +/** + * This utility class provides constants and convenient methods to + * encode/decode/read/write data from/to input/output streams. + * + * @author Frank Shaka + */ +public class CommandTransferUtil { + + public static final String ENCODING = "UTF-8"; //$NON-NLS-1$ + + public static final String MARKER_PROPERTIES = "[PROPERTIES]"; //$NON-NLS-1$ + + public static final String MARKER_VALUES = "[VALUES]"; //$NON-NLS-1$ + + public static final String MARKER_FILES = "[FILES]"; //$NON-NLS-1$ + + private CommandTransferUtil() { + } + + public static String encode(String str) { + try { + return URLEncoder.encode(str, ENCODING); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + public static String decode(String str) { + try { + return URLDecoder.decode(str, ENCODING); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + public static IBinaryStore readFiles(IProgressMonitor monitor, + ChunkReader reader) throws IOException { + String numFilesStr = reader.readText(); + if (numFilesStr == null) + // Empty files + return null; + + int numFiles; + try { + numFiles = Integer.parseInt(numFilesStr, 10); + } catch (NumberFormatException e) { + throw new IOException( + "Invalid format of files number: " + numFilesStr); //$NON-NLS-1$ + } + monitor.beginTask(null, numFiles); + + IBinaryStore store = null; + String entryName; + try { + while ((entryName = reader.readText()) != null) { + if ("".equals(entryName) || monitor.isCanceled()) //$NON-NLS-1$ + break; + + InputStream chunkStream = reader.openNextChunkAsStream(); + if (chunkStream != null) { + IProgressMonitor fileMonitor = new SubProgressMonitor( + monitor, 1); + if (store == null) { + store = new BinaryStore(); + } + store.addEntry(fileMonitor, entryName, chunkStream); + if (monitor.isCanceled()) + return null; + fileMonitor.done(); + } + } + } catch (InterruptedException e) { + return null; + } + return store; + } + + public static void writeFiles(IProgressMonitor monitor, IBinaryStore files, + ChunkWriter writer) throws IOException { + monitor.beginTask(null, files.size()); + writer.writeText(String.valueOf(files.size())); + Iterator entryNames = files.entryNames(); + while (entryNames.hasNext()) { + String entryName = entryNames.next(); + IBinaryEntry entry = files.getEntry(entryName); + writer.writeText(entryName); + if (monitor.isCanceled()) + return; + if (entry != null && !entryName.endsWith("/")) { //$NON-NLS-1$ + InputStream in = entry.openInputStream(); + if (monitor.isCanceled()) + return; + try { + OutputStream out = writer.openNextChunkAsStream(); + if (monitor.isCanceled()) + return; + try { + byte[] buffer = new byte[4096]; + int read; + while ((read = in.read(buffer)) > 0) { + if (monitor.isCanceled()) + return; + out.write(buffer, 0, read); + } + } finally { + out.close(); + } + } finally { + in.close(); + } + } + if (monitor.isCanceled()) + return; + monitor.worked(1); + } + if (monitor.isCanceled()) + return; + monitor.done(); + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/IncomingCommandHandler.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/IncomingCommandHandler.java index 7199a826e..9fbd894cb 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/IncomingCommandHandler.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/IncomingCommandHandler.java @@ -1,338 +1,338 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.transfer; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.Command; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.ICommandService; -import org.xmind.core.command.IReturnValueConsumer; -import org.xmind.core.command.ReturnValue; -import org.xmind.core.command.arguments.Attributes; -import org.xmind.core.command.binary.IBinaryStore; -import org.xmind.core.internal.command.remote.Messages; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * A basic handler that handles incoming command requests from an input stream - * and writes the return value to an output stream. - * - * @author Frank Shaka - */ -public class IncomingCommandHandler { - - private static final String DEBUG_OPTION = "/debug/incomingCommandHandler"; //$NON-NLS-1$ - - private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() - .isDebugging(DEBUG_OPTION); - - private Object remoteLocation = "(unknown location)"; //$NON-NLS-1$ - - private String pluginId = RemoteCommandPlugin.PLUGIN_ID; - - /** - * - */ - public IncomingCommandHandler() { - } - - /** - * For debugging purpose only. - * - * @param location - * the remote location representation - */ - public void setRemoteLocation(Object location) { - if (location == null) { - location = "(unknown location)"; //$NON-NLS-1$ - } - this.remoteLocation = location; - } - - public Object getRemoteLocation() { - return remoteLocation; - } - - public void setPluginId(String pluginId) { - if (pluginId == null) - pluginId = RemoteCommandPlugin.PLUGIN_ID; - this.pluginId = pluginId; - } - - public String getPluginId() { - return pluginId; - } - - public IStatus handleIncomingCommand(IProgressMonitor monitor, - InputStream input, OutputStream output) { - ChunkReader reader = new ChunkReader(input); - try { - ChunkWriter writer = new ChunkWriter(output); - try { - return handleIncomingCommand(monitor, reader, writer); - } finally { - try { - writer.close(); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - } - } finally { - try { - reader.close(); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - } - } - - public IStatus handleIncomingCommand(IProgressMonitor monitor, - ChunkReader reader, ChunkWriter writer) { - monitor.beginTask(null, 100); - - // Read command: - monitor.subTask(Messages.IncomingCommandHandler_ReadCommand); - IProgressMonitor readMonitor = new SubProgressMonitor(monitor, 10); - ICommand command; - try { - command = readCommand(readMonitor, reader); - } catch (Throwable e) { - return createReadingErrorStatus(e); - } - if (command == null || monitor.isCanceled()) - return Status.CANCEL_STATUS; - readMonitor.done(); - - try { - // Execute command: - monitor.subTask(NLS.bind( - Messages.IncomingCommandHandler_ExcuteCommand, command)); - IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, - 90); - IStatus returnValue = executeCommand(executeMonitor, command, - writer); - if (returnValue != null && !returnValue.isOK()) - return returnValue; - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - executeMonitor.done(); - - monitor.done(); - return returnValue; - } finally { - IBinaryStore binaryStore = command.getBinaryStore(); - if (binaryStore != null) - binaryStore.clear(); - } - } - - private ICommand readCommand(IProgressMonitor monitor, ChunkReader reader) - throws IOException { - monitor.beginTask(null, 100); - - if (DEBUGGING) - System.out.println("Start reading command from " //$NON-NLS-1$ - + remoteLocation); - // Read command: - String uri = reader.readText(); - if (uri == null) - // No command available - return null; - - if (DEBUGGING) - System.out.println("Request received: " + uri); //$NON-NLS-1$ - if (monitor.isCanceled()) - return null; - monitor.worked(50); - - // Read file arguments: - String argumentType = reader.readText(); - if (monitor.isCanceled()) - return null; - IBinaryStore files = null; - IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 40); - if (CommandTransferUtil.MARKER_FILES.equals(argumentType)) { - files = CommandTransferUtil.readFiles(filesMonitor, reader); - if (DEBUGGING) - System.out.println("Files received: " + files); //$NON-NLS-1$ - } - if (monitor.isCanceled()) - return null; - filesMonitor.done(); - - // Build command: - ICommand command = Command.parseURI(uri, files); - if (monitor.isCanceled()) - return null; - monitor.done(); - return command; - } - - private IStatus executeCommand(IProgressMonitor monitor, ICommand command, - final ChunkWriter writer) { - // Retrieve command handling service: - ICommandService commandService = RemoteCommandPlugin.getDefault() - .getCommandService(); - if (commandService == null) { - try { - writeReturnValue(monitor, - new Status(IStatus.ERROR, getPluginId(), - "No command handling service available."), //$NON-NLS-1$ - writer); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - return new Status(IStatus.WARNING, getPluginId(), - "No command handling service available."); //$NON-NLS-1$ - } - if (monitor.isCanceled()) { - try { - writeReturnValue(monitor, Status.CANCEL_STATUS, writer); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - return Status.CANCEL_STATUS; - } - - // Execute command locally: - IStatus returnValue = commandService.execute(monitor, command, - new IReturnValueConsumer() { - public IStatus consumeReturnValue(IProgressMonitor monitor, - IStatus returnValue) { - try { - writeReturnValue(monitor, returnValue, writer); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - return Status.OK_STATUS; - } catch (Throwable e) { - return createWritingErrorStatus(e); - } - } - }); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.done(); - return returnValue; - } - - /** - * @param monitor - * @param returnValue - * @param writer - * @return - */ - private void writeReturnValue(IProgressMonitor monitor, - IStatus returnValue, ChunkWriter writer) throws IOException { - if (DEBUGGING) - System.out.println("Command executed: " + returnValue); //$NON-NLS-1$ - - monitor.beginTask(null, 100); - - monitor.subTask(Messages.IncomingCommandHandler_WriteReponseBack); - - // Write status: - writer.writeText(String.valueOf(returnValue.getSeverity())); - monitor.worked(10); - - // Write plugin ID: - writer.writeText(returnValue.getPlugin() == null ? "" : returnValue.getPlugin()); //$NON-NLS-1$ - monitor.worked(10); - - // Write plugin-specific code: - writer.writeText(String.valueOf(returnValue.getCode())); - monitor.worked(10); - - // Write message: - writer.writeText(returnValue.getMessage()); - monitor.worked(10); - - // Write return value: - SubProgressMonitor writeValueMonitor = new SubProgressMonitor(monitor, - 40); - writeValue(writeValueMonitor, writer, returnValue); - if (writeValueMonitor.isCanceled()) - return; - writeValueMonitor.done(); - - writer.writeText(""); //$NON-NLS-1$ - monitor.worked(10); - - writer.flush(); - monitor.worked(10); - - monitor.done(); - } - - private void writeValue(IProgressMonitor monitor, ChunkWriter writer, - IStatus returnValue) throws IOException { - if (returnValue.isOK()) { - if (returnValue instanceof ReturnValue) { - Object value = ((ReturnValue) returnValue).getValue(); - if (value instanceof Attributes) { - Attributes attrs = (Attributes) value; - monitor.beginTask(null, attrs.size()); - writer.writeText(CommandTransferUtil.MARKER_PROPERTIES); - Iterator names = attrs.keys(); - while (names.hasNext()) { - String name = names.next(); - writer.writeText(CommandTransferUtil.encode(name)); - writer.writeText(CommandTransferUtil.encode(attrs - .getString(name, ""))); //$NON-NLS-1$ - monitor.worked(1); - } - } else if (value instanceof String[]) { - String[] strings = (String[]) value; - monitor.beginTask(null, strings.length); - writer.writeText(CommandTransferUtil.MARKER_VALUES); - for (int i = 0; i < strings.length; i++) { - writer.writeText(CommandTransferUtil.encode(strings[i])); - monitor.worked(1); - } - } else if (value instanceof IBinaryStore) { - IBinaryStore files = (IBinaryStore) value; - writer.writeText(CommandTransferUtil.MARKER_FILES); - CommandTransferUtil.writeFiles(monitor, files, writer); - } - } - } - } - - protected IStatus createReadingErrorStatus(Throwable e) { -// if (e instanceof EOFException) { -// return new Status( -// IStatus.WARNING, -// getPluginId(), -// Messages.IncomingCommandHandler_ConnectionClose, -// e); -// } - return new Status(IStatus.ERROR, getPluginId(), null, e); - } - - protected IStatus createWritingErrorStatus(Throwable e) { - return new Status(IStatus.ERROR, getPluginId(), null, e); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.transfer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.Command; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.ICommandService; +import org.xmind.core.command.IReturnValueConsumer; +import org.xmind.core.command.ReturnValue; +import org.xmind.core.command.arguments.Attributes; +import org.xmind.core.command.binary.IBinaryStore; +import org.xmind.core.internal.command.remote.Messages; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * A basic handler that handles incoming command requests from an input stream + * and writes the return value to an output stream. + * + * @author Frank Shaka + */ +public class IncomingCommandHandler { + + private static final String DEBUG_OPTION = "/debug/incomingCommandHandler"; //$NON-NLS-1$ + + private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() + .isDebugging(DEBUG_OPTION); + + private Object remoteLocation = "(unknown location)"; //$NON-NLS-1$ + + private String pluginId = RemoteCommandPlugin.PLUGIN_ID; + + /** + * + */ + public IncomingCommandHandler() { + } + + /** + * For debugging purpose only. + * + * @param location + * the remote location representation + */ + public void setRemoteLocation(Object location) { + if (location == null) { + location = "(unknown location)"; //$NON-NLS-1$ + } + this.remoteLocation = location; + } + + public Object getRemoteLocation() { + return remoteLocation; + } + + public void setPluginId(String pluginId) { + if (pluginId == null) + pluginId = RemoteCommandPlugin.PLUGIN_ID; + this.pluginId = pluginId; + } + + public String getPluginId() { + return pluginId; + } + + public IStatus handleIncomingCommand(IProgressMonitor monitor, + InputStream input, OutputStream output) { + ChunkReader reader = new ChunkReader(input); + try { + ChunkWriter writer = new ChunkWriter(output); + try { + return handleIncomingCommand(monitor, reader, writer); + } finally { + try { + writer.close(); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + } + } finally { + try { + reader.close(); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + } + } + + public IStatus handleIncomingCommand(IProgressMonitor monitor, + ChunkReader reader, ChunkWriter writer) { + monitor.beginTask(null, 100); + + // Read command: + monitor.subTask(Messages.IncomingCommandHandler_ReadCommand); + IProgressMonitor readMonitor = new SubProgressMonitor(monitor, 10); + ICommand command; + try { + command = readCommand(readMonitor, reader); + } catch (Throwable e) { + return createReadingErrorStatus(e); + } + if (command == null || monitor.isCanceled()) + return Status.CANCEL_STATUS; + readMonitor.done(); + + try { + // Execute command: + monitor.subTask(NLS.bind( + Messages.IncomingCommandHandler_ExcuteCommand, command)); + IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, + 90); + IStatus returnValue = executeCommand(executeMonitor, command, + writer); + if (returnValue != null && !returnValue.isOK()) + return returnValue; + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + executeMonitor.done(); + + monitor.done(); + return returnValue; + } finally { + IBinaryStore binaryStore = command.getBinaryStore(); + if (binaryStore != null) + binaryStore.clear(); + } + } + + private ICommand readCommand(IProgressMonitor monitor, ChunkReader reader) + throws IOException { + monitor.beginTask(null, 100); + + if (DEBUGGING) + System.out.println("Start reading command from " //$NON-NLS-1$ + + remoteLocation); + // Read command: + String uri = reader.readText(); + if (uri == null) + // No command available + return null; + + if (DEBUGGING) + System.out.println("Request received: " + uri); //$NON-NLS-1$ + if (monitor.isCanceled()) + return null; + monitor.worked(50); + + // Read file arguments: + String argumentType = reader.readText(); + if (monitor.isCanceled()) + return null; + IBinaryStore files = null; + IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 40); + if (CommandTransferUtil.MARKER_FILES.equals(argumentType)) { + files = CommandTransferUtil.readFiles(filesMonitor, reader); + if (DEBUGGING) + System.out.println("Files received: " + files); //$NON-NLS-1$ + } + if (monitor.isCanceled()) + return null; + filesMonitor.done(); + + // Build command: + ICommand command = Command.parseURI(uri, files); + if (monitor.isCanceled()) + return null; + monitor.done(); + return command; + } + + private IStatus executeCommand(IProgressMonitor monitor, ICommand command, + final ChunkWriter writer) { + // Retrieve command handling service: + ICommandService commandService = RemoteCommandPlugin.getDefault() + .getCommandService(); + if (commandService == null) { + try { + writeReturnValue(monitor, + new Status(IStatus.ERROR, getPluginId(), + "No command handling service available."), //$NON-NLS-1$ + writer); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + return new Status(IStatus.WARNING, getPluginId(), + "No command handling service available."); //$NON-NLS-1$ + } + if (monitor.isCanceled()) { + try { + writeReturnValue(monitor, Status.CANCEL_STATUS, writer); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + return Status.CANCEL_STATUS; + } + + // Execute command locally: + IStatus returnValue = commandService.execute(monitor, command, + new IReturnValueConsumer() { + public IStatus consumeReturnValue(IProgressMonitor monitor, + IStatus returnValue) { + try { + writeReturnValue(monitor, returnValue, writer); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + return Status.OK_STATUS; + } catch (Throwable e) { + return createWritingErrorStatus(e); + } + } + }); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.done(); + return returnValue; + } + + /** + * @param monitor + * @param returnValue + * @param writer + * @return + */ + private void writeReturnValue(IProgressMonitor monitor, + IStatus returnValue, ChunkWriter writer) throws IOException { + if (DEBUGGING) + System.out.println("Command executed: " + returnValue); //$NON-NLS-1$ + + monitor.beginTask(null, 100); + + monitor.subTask(Messages.IncomingCommandHandler_WriteReponseBack); + + // Write status: + writer.writeText(String.valueOf(returnValue.getSeverity())); + monitor.worked(10); + + // Write plugin ID: + writer.writeText(returnValue.getPlugin() == null ? "" : returnValue.getPlugin()); //$NON-NLS-1$ + monitor.worked(10); + + // Write plugin-specific code: + writer.writeText(String.valueOf(returnValue.getCode())); + monitor.worked(10); + + // Write message: + writer.writeText(returnValue.getMessage()); + monitor.worked(10); + + // Write return value: + SubProgressMonitor writeValueMonitor = new SubProgressMonitor(monitor, + 40); + writeValue(writeValueMonitor, writer, returnValue); + if (writeValueMonitor.isCanceled()) + return; + writeValueMonitor.done(); + + writer.writeText(""); //$NON-NLS-1$ + monitor.worked(10); + + writer.flush(); + monitor.worked(10); + + monitor.done(); + } + + private void writeValue(IProgressMonitor monitor, ChunkWriter writer, + IStatus returnValue) throws IOException { + if (returnValue.isOK()) { + if (returnValue instanceof ReturnValue) { + Object value = ((ReturnValue) returnValue).getValue(); + if (value instanceof Attributes) { + Attributes attrs = (Attributes) value; + monitor.beginTask(null, attrs.size()); + writer.writeText(CommandTransferUtil.MARKER_PROPERTIES); + Iterator names = attrs.keys(); + while (names.hasNext()) { + String name = names.next(); + writer.writeText(CommandTransferUtil.encode(name)); + writer.writeText(CommandTransferUtil.encode(attrs + .getString(name, ""))); //$NON-NLS-1$ + monitor.worked(1); + } + } else if (value instanceof String[]) { + String[] strings = (String[]) value; + monitor.beginTask(null, strings.length); + writer.writeText(CommandTransferUtil.MARKER_VALUES); + for (int i = 0; i < strings.length; i++) { + writer.writeText(CommandTransferUtil.encode(strings[i])); + monitor.worked(1); + } + } else if (value instanceof IBinaryStore) { + IBinaryStore files = (IBinaryStore) value; + writer.writeText(CommandTransferUtil.MARKER_FILES); + CommandTransferUtil.writeFiles(monitor, files, writer); + } + } + } + } + + protected IStatus createReadingErrorStatus(Throwable e) { +// if (e instanceof EOFException) { +// return new Status( +// IStatus.WARNING, +// getPluginId(), +// Messages.IncomingCommandHandler_ConnectionClose, +// e); +// } + return new Status(IStatus.ERROR, getPluginId(), null, e); + } + + protected IStatus createWritingErrorStatus(Throwable e) { + return new Status(IStatus.ERROR, getPluginId(), null, e); + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/OutgoingCommandHandler.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/OutgoingCommandHandler.java index fbbe1295b..320514336 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/OutgoingCommandHandler.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/command/transfer/OutgoingCommandHandler.java @@ -1,370 +1,370 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.command.transfer; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.Command; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.IReturnValueConsumer; -import org.xmind.core.command.ReturnValue; -import org.xmind.core.command.arguments.Attributes; -import org.xmind.core.command.binary.IBinaryStore; -import org.xmind.core.internal.command.remote.Messages; -import org.xmind.core.internal.command.remote.RemoteCommandPlugin; - -/** - * A basic handler that sends a command to a remote command service via an - * output stream and wait for responded return value from an input stream. - * - * @author Frank Shaka - */ -public class OutgoingCommandHandler { - - private static final String DEBUG_OPTION = "/debug/outgoingCommandHandler"; //$NON-NLS-1$ - - private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() - .isDebugging(DEBUG_OPTION); - - private Object remoteLocation = "(unknown location)"; //$NON-NLS-1$ - - private String pluginId = RemoteCommandPlugin.PLUGIN_ID; - - /** - * - */ - public OutgoingCommandHandler() { - } - - /** - * For debugging purpose only. - * - * @param location - * the remote location representation - */ - public void setRemoteLocation(Object location) { - if (location == null) - location = "(unknown location)"; //$NON-NLS-1$ - this.remoteLocation = location; - } - - public Object getRemoteLocation() { - return remoteLocation; - } - - public void setPluginId(String pluginId) { - if (pluginId == null) - pluginId = RemoteCommandPlugin.PLUGIN_ID; - this.pluginId = pluginId; - } - - public String getPluginId() { - return pluginId; - } - - public IStatus handleOutgoingCommand(IProgressMonitor monitor, - ICommand command, IReturnValueConsumer returnValueConsumer, - InputStream input, OutputStream output) { - ChunkReader reader = new ChunkReader(input); - try { - ChunkWriter writer = new ChunkWriter(output); - try { - return handleOutgoingCommand(monitor, command, - returnValueConsumer, reader, writer); - } finally { - try { - writer.close(); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - } - } finally { - try { - reader.close(); - } catch (IOException e) { - RemoteCommandPlugin.log(null, e); - } - } - } - - public IStatus handleOutgoingCommand(IProgressMonitor monitor, - ICommand command, IReturnValueConsumer returnValueConsumer, - ChunkReader reader, ChunkWriter writer) { - monitor.beginTask(null, 100); - - monitor.subTask(Messages.OutgoingCommandHandler_ExcuteCommand); - IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, 90); - IStatus returnValue = executeCommandRemotely(executeMonitor, command, - reader, writer); - if (!executeMonitor.isCanceled()) - executeMonitor.done(); - - try { - monitor.subTask(Messages.OutgoingCommandHandler_ConsumeReturnValue); - IProgressMonitor consumeMonitor = new SubProgressMonitor(monitor, - 10); - consumeCommand(consumeMonitor, command, returnValue, - returnValueConsumer); - if (!consumeMonitor.isCanceled()) - consumeMonitor.done(); - - if (!monitor.isCanceled()) - monitor.done(); - return returnValue; - } finally { - if (returnValue != null && returnValue instanceof ReturnValue) { - Object value = ((ReturnValue) returnValue).getValue(); - if (value instanceof IBinaryStore) { - ((IBinaryStore) value).clear(); - } - } - } - } - - private IStatus executeCommandRemotely(IProgressMonitor monitor, - ICommand command, ChunkReader reader, ChunkWriter writer) { - monitor.beginTask(null, 100); - - monitor.subTask(Messages.OutgoingCommandHandler_SendCommand); - IProgressMonitor sendMonitor = new SubProgressMonitor(monitor, 30); - try { - sendCommand(sendMonitor, command, writer); - } catch (Throwable e) { - return createSendingErrorStatus(e); - } - if (sendMonitor.isCanceled()) - return Status.CANCEL_STATUS; - sendMonitor.done(); - - monitor.subTask(Messages.OutgoingCommandHandler_ReceiveReturnValue); - IProgressMonitor receiveMonitor = new SubProgressMonitor(monitor, 70); - IStatus returnValue; - try { - returnValue = receive(receiveMonitor, reader); - } catch (Throwable e) { - returnValue = createReceivingErrorStatus(e); - } - if (!receiveMonitor.isCanceled()) - receiveMonitor.done(); - if (!monitor.isCanceled()) - monitor.done(); - return returnValue; - } - - private void sendCommand(IProgressMonitor monitor, ICommand command, - ChunkWriter writer) throws IOException { - monitor.beginTask(null, 100); - - if (DEBUGGING) - System.out.println("Sending command to " //$NON-NLS-1$ - + remoteLocation + ": " + command); //$NON-NLS-1$ - long start = System.currentTimeMillis(); - String uri = Command.toURI(command); - writer.writeText(uri); - if (monitor.isCanceled()) - return; - monitor.worked(40); - - IBinaryStore files = command.getBinaryStore(); - if (files != null && !files.isEmpty()) { - writer.writeText(CommandTransferUtil.MARKER_FILES); - if (monitor.isCanceled()) - return; - monitor.worked(10); - - IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 40); - CommandTransferUtil.writeFiles(filesMonitor, files, writer); - if (monitor.isCanceled()) - return; - filesMonitor.done(); - } else { - monitor.worked(50); - } - writer.writeText(""); //$NON-NLS-1$ - if (monitor.isCanceled()) - return; - monitor.worked(10); - - writer.flush(); - if (monitor.isCanceled()) - return; - monitor.done(); - - long end = System.currentTimeMillis(); - if (DEBUGGING) - System.out.println("Command sent to " //$NON-NLS-1$ - + remoteLocation + " (" //$NON-NLS-1$ - + (end - start) + " ms): " + command); //$NON-NLS-1$ - } - - private IStatus receive(IProgressMonitor monitor, ChunkReader reader) - throws IOException { - monitor.beginTask(null, 100); - - if (DEBUGGING) - System.out.println("Receiving return value from " //$NON-NLS-1$ - + remoteLocation); - long start = System.currentTimeMillis(); - - String status = reader.readText(); - if (status == null) - return null; - - int severity; - try { - severity = Integer.parseInt(status, 10); - } catch (NumberFormatException e) { - return new Status(IStatus.ERROR, getPluginId(), NLS.bind( - Messages.OutgoingCommandHandler_InvalidReturnValueStatus, - status)); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(15); - - String pluginId = reader.readText(); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(15); - - String codeStr = reader.readText(); - int code; - if (codeStr != null && !"".equals(codeStr)) { //$NON-NLS-1$ - try { - code = Integer.parseInt(codeStr, 10); - } catch (NumberFormatException e) { - return new Status(IStatus.ERROR, getPluginId(), NLS.bind( - Messages.OutgoingCommandHandler_InvalidReturnValueCode, - codeStr)); - } - } else { - code = 0; - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(15); - - String message = reader.readText(); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(15); - - String responseType = reader.readText(); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(15); - - IStatus returnValue; - if (CommandTransferUtil.MARKER_PROPERTIES.equals(responseType)) { - Attributes attrs = new Attributes(); - String name; - String value; - while ((name = reader.readText()) != null - && (value = reader.readText()) != null) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - - if ("".equals(name) || "".equals(value)) //$NON-NLS-1$ //$NON-NLS-2$ - break; - - attrs.with(CommandTransferUtil.decode(name), - CommandTransferUtil.decode(value)); - } - returnValue = new ReturnValue(severity, pluginId, code, message, - attrs); - } else if (CommandTransferUtil.MARKER_VALUES.equals(responseType)) { - List values = new ArrayList(); - String value; - while ((value = reader.readText()) != null) { - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - if ("".equals(value)) //$NON-NLS-1$ - break; - values.add(CommandTransferUtil.decode(value)); - } - returnValue = new ReturnValue(severity, pluginId, code, message, - values.toArray(new String[values.size()])); - } else if (CommandTransferUtil.MARKER_FILES.equals(responseType)) { - IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 20); - IBinaryStore files = CommandTransferUtil.readFiles(filesMonitor, - reader); - if (filesMonitor.isCanceled()) { - if (files != null) - files.clear(); - return Status.CANCEL_STATUS; - } - filesMonitor.done(); - returnValue = new ReturnValue(severity, pluginId, code, message, - files); - } else { - returnValue = new Status(severity, pluginId, code, message, null); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.done(); - - long end = System.currentTimeMillis(); - if (DEBUGGING) { - System.out.println("Return value received from " //$NON-NLS-1$ - + remoteLocation + " (" //$NON-NLS-1$ - + (end - start) + " ms): " + returnValue); //$NON-NLS-1$ - } - return returnValue; - } - - private void consumeCommand(IProgressMonitor monitor, ICommand command, - IStatus returnValue, IReturnValueConsumer returnValueConsumer) { - if (returnValueConsumer != null) { - try { - IStatus consumed = returnValueConsumer.consumeReturnValue( - monitor, returnValue); - if (!monitor.isCanceled() && consumed != null - && !consumed.isOK() - && consumed.getSeverity() != IStatus.CANCEL) { - RemoteCommandPlugin.log(consumed); - } - } catch (Throwable e) { - RemoteCommandPlugin.log( - "Error occurred while consuming return value.", //$NON-NLS-1$ - e); - } - } - } - - protected IStatus createSendingErrorStatus(Throwable e) { - return new Status(IStatus.ERROR, getPluginId(), null, e); - } - - protected IStatus createReceivingErrorStatus(Throwable e) { - if (e instanceof EOFException) { - return new Status(IStatus.WARNING, getPluginId(), - Messages.OutgoingCommandHandler_ConnectionClose, e); - } - return new Status(IStatus.ERROR, getPluginId(), null, e); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.command.transfer; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.Command; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.IReturnValueConsumer; +import org.xmind.core.command.ReturnValue; +import org.xmind.core.command.arguments.Attributes; +import org.xmind.core.command.binary.IBinaryStore; +import org.xmind.core.internal.command.remote.Messages; +import org.xmind.core.internal.command.remote.RemoteCommandPlugin; + +/** + * A basic handler that sends a command to a remote command service via an + * output stream and wait for responded return value from an input stream. + * + * @author Frank Shaka + */ +public class OutgoingCommandHandler { + + private static final String DEBUG_OPTION = "/debug/outgoingCommandHandler"; //$NON-NLS-1$ + + private static boolean DEBUGGING = RemoteCommandPlugin.getDefault() + .isDebugging(DEBUG_OPTION); + + private Object remoteLocation = "(unknown location)"; //$NON-NLS-1$ + + private String pluginId = RemoteCommandPlugin.PLUGIN_ID; + + /** + * + */ + public OutgoingCommandHandler() { + } + + /** + * For debugging purpose only. + * + * @param location + * the remote location representation + */ + public void setRemoteLocation(Object location) { + if (location == null) + location = "(unknown location)"; //$NON-NLS-1$ + this.remoteLocation = location; + } + + public Object getRemoteLocation() { + return remoteLocation; + } + + public void setPluginId(String pluginId) { + if (pluginId == null) + pluginId = RemoteCommandPlugin.PLUGIN_ID; + this.pluginId = pluginId; + } + + public String getPluginId() { + return pluginId; + } + + public IStatus handleOutgoingCommand(IProgressMonitor monitor, + ICommand command, IReturnValueConsumer returnValueConsumer, + InputStream input, OutputStream output) { + ChunkReader reader = new ChunkReader(input); + try { + ChunkWriter writer = new ChunkWriter(output); + try { + return handleOutgoingCommand(monitor, command, + returnValueConsumer, reader, writer); + } finally { + try { + writer.close(); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + } + } finally { + try { + reader.close(); + } catch (IOException e) { + RemoteCommandPlugin.log(null, e); + } + } + } + + public IStatus handleOutgoingCommand(IProgressMonitor monitor, + ICommand command, IReturnValueConsumer returnValueConsumer, + ChunkReader reader, ChunkWriter writer) { + monitor.beginTask(null, 100); + + monitor.subTask(Messages.OutgoingCommandHandler_ExcuteCommand); + IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, 90); + IStatus returnValue = executeCommandRemotely(executeMonitor, command, + reader, writer); + if (!executeMonitor.isCanceled()) + executeMonitor.done(); + + try { + monitor.subTask(Messages.OutgoingCommandHandler_ConsumeReturnValue); + IProgressMonitor consumeMonitor = new SubProgressMonitor(monitor, + 10); + consumeCommand(consumeMonitor, command, returnValue, + returnValueConsumer); + if (!consumeMonitor.isCanceled()) + consumeMonitor.done(); + + if (!monitor.isCanceled()) + monitor.done(); + return returnValue; + } finally { + if (returnValue != null && returnValue instanceof ReturnValue) { + Object value = ((ReturnValue) returnValue).getValue(); + if (value instanceof IBinaryStore) { + ((IBinaryStore) value).clear(); + } + } + } + } + + private IStatus executeCommandRemotely(IProgressMonitor monitor, + ICommand command, ChunkReader reader, ChunkWriter writer) { + monitor.beginTask(null, 100); + + monitor.subTask(Messages.OutgoingCommandHandler_SendCommand); + IProgressMonitor sendMonitor = new SubProgressMonitor(monitor, 30); + try { + sendCommand(sendMonitor, command, writer); + } catch (Throwable e) { + return createSendingErrorStatus(e); + } + if (sendMonitor.isCanceled()) + return Status.CANCEL_STATUS; + sendMonitor.done(); + + monitor.subTask(Messages.OutgoingCommandHandler_ReceiveReturnValue); + IProgressMonitor receiveMonitor = new SubProgressMonitor(monitor, 70); + IStatus returnValue; + try { + returnValue = receive(receiveMonitor, reader); + } catch (Throwable e) { + returnValue = createReceivingErrorStatus(e); + } + if (!receiveMonitor.isCanceled()) + receiveMonitor.done(); + if (!monitor.isCanceled()) + monitor.done(); + return returnValue; + } + + private void sendCommand(IProgressMonitor monitor, ICommand command, + ChunkWriter writer) throws IOException { + monitor.beginTask(null, 100); + + if (DEBUGGING) + System.out.println("Sending command to " //$NON-NLS-1$ + + remoteLocation + ": " + command); //$NON-NLS-1$ + long start = System.currentTimeMillis(); + String uri = Command.toURI(command); + writer.writeText(uri); + if (monitor.isCanceled()) + return; + monitor.worked(40); + + IBinaryStore files = command.getBinaryStore(); + if (files != null && !files.isEmpty()) { + writer.writeText(CommandTransferUtil.MARKER_FILES); + if (monitor.isCanceled()) + return; + monitor.worked(10); + + IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 40); + CommandTransferUtil.writeFiles(filesMonitor, files, writer); + if (monitor.isCanceled()) + return; + filesMonitor.done(); + } else { + monitor.worked(50); + } + writer.writeText(""); //$NON-NLS-1$ + if (monitor.isCanceled()) + return; + monitor.worked(10); + + writer.flush(); + if (monitor.isCanceled()) + return; + monitor.done(); + + long end = System.currentTimeMillis(); + if (DEBUGGING) + System.out.println("Command sent to " //$NON-NLS-1$ + + remoteLocation + " (" //$NON-NLS-1$ + + (end - start) + " ms): " + command); //$NON-NLS-1$ + } + + private IStatus receive(IProgressMonitor monitor, ChunkReader reader) + throws IOException { + monitor.beginTask(null, 100); + + if (DEBUGGING) + System.out.println("Receiving return value from " //$NON-NLS-1$ + + remoteLocation); + long start = System.currentTimeMillis(); + + String status = reader.readText(); + if (status == null) + return null; + + int severity; + try { + severity = Integer.parseInt(status, 10); + } catch (NumberFormatException e) { + return new Status(IStatus.ERROR, getPluginId(), NLS.bind( + Messages.OutgoingCommandHandler_InvalidReturnValueStatus, + status)); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(15); + + String pluginId = reader.readText(); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(15); + + String codeStr = reader.readText(); + int code; + if (codeStr != null && !"".equals(codeStr)) { //$NON-NLS-1$ + try { + code = Integer.parseInt(codeStr, 10); + } catch (NumberFormatException e) { + return new Status(IStatus.ERROR, getPluginId(), NLS.bind( + Messages.OutgoingCommandHandler_InvalidReturnValueCode, + codeStr)); + } + } else { + code = 0; + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(15); + + String message = reader.readText(); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(15); + + String responseType = reader.readText(); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(15); + + IStatus returnValue; + if (CommandTransferUtil.MARKER_PROPERTIES.equals(responseType)) { + Attributes attrs = new Attributes(); + String name; + String value; + while ((name = reader.readText()) != null + && (value = reader.readText()) != null) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + + if ("".equals(name) || "".equals(value)) //$NON-NLS-1$ //$NON-NLS-2$ + break; + + attrs.with(CommandTransferUtil.decode(name), + CommandTransferUtil.decode(value)); + } + returnValue = new ReturnValue(severity, pluginId, code, message, + attrs); + } else if (CommandTransferUtil.MARKER_VALUES.equals(responseType)) { + List values = new ArrayList(); + String value; + while ((value = reader.readText()) != null) { + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + if ("".equals(value)) //$NON-NLS-1$ + break; + values.add(CommandTransferUtil.decode(value)); + } + returnValue = new ReturnValue(severity, pluginId, code, message, + values.toArray(new String[values.size()])); + } else if (CommandTransferUtil.MARKER_FILES.equals(responseType)) { + IProgressMonitor filesMonitor = new SubProgressMonitor(monitor, 20); + IBinaryStore files = CommandTransferUtil.readFiles(filesMonitor, + reader); + if (filesMonitor.isCanceled()) { + if (files != null) + files.clear(); + return Status.CANCEL_STATUS; + } + filesMonitor.done(); + returnValue = new ReturnValue(severity, pluginId, code, message, + files); + } else { + returnValue = new Status(severity, pluginId, code, message, null); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.done(); + + long end = System.currentTimeMillis(); + if (DEBUGGING) { + System.out.println("Return value received from " //$NON-NLS-1$ + + remoteLocation + " (" //$NON-NLS-1$ + + (end - start) + " ms): " + returnValue); //$NON-NLS-1$ + } + return returnValue; + } + + private void consumeCommand(IProgressMonitor monitor, ICommand command, + IStatus returnValue, IReturnValueConsumer returnValueConsumer) { + if (returnValueConsumer != null) { + try { + IStatus consumed = returnValueConsumer.consumeReturnValue( + monitor, returnValue); + if (!monitor.isCanceled() && consumed != null + && !consumed.isOK() + && consumed.getSeverity() != IStatus.CANCEL) { + RemoteCommandPlugin.log(consumed); + } + } catch (Throwable e) { + RemoteCommandPlugin.log( + "Error occurred while consuming return value.", //$NON-NLS-1$ + e); + } + } + } + + protected IStatus createSendingErrorStatus(Throwable e) { + return new Status(IStatus.ERROR, getPluginId(), null, e); + } + + protected IStatus createReceivingErrorStatus(Throwable e) { + if (e instanceof EOFException) { + return new Status(IStatus.WARNING, getPluginId(), + Messages.OutgoingCommandHandler_ConnectionClose, e); + } + return new Status(IStatus.ERROR, getPluginId(), null, e); + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainImpl.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainImpl.java index 5e23d3973..fd9c03a33 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainImpl.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainImpl.java @@ -1,166 +1,166 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.command.remote; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.xmind.core.command.remote.ICommandServer; -import org.xmind.core.command.remote.ICommandServerAdvertiser; -import org.xmind.core.command.remote.ICommandServiceDomain; -import org.xmind.core.command.remote.ICommandServiceDomainDirector; -import org.xmind.core.command.remote.IDomainServiceFactory; -import org.xmind.core.command.remote.IRemoteCommandServiceDiscoverer; - -/** - * @author Frank Shaka - */ -public class CommandServiceDomainImpl implements ICommandServiceDomain, - IDomainsExtensionConstants { - - private final CommandServiceDomainManagerImpl manager; - - private final String id; - - private final IConfigurationElement element; - - private ICommandServiceDomainDirector director = null; - - private ICommandServer server = null; - - private ICommandServerAdvertiser advertiser = null; - - private IRemoteCommandServiceDiscoverer discoverer = null; - - /** - * - */ - public CommandServiceDomainImpl(CommandServiceDomainManagerImpl manager, - String id, IConfigurationElement element) { - this.manager = manager; - this.id = id; - this.element = element; - } - - public String getId() { - return id; - } - - public String getName() { - return element.getAttribute(ATT_NAME); - } - - private T createDomainService(String attrName, Class serviceClass) { - String factoryId = element.getAttribute(attrName); - if (factoryId != null) { - IDomainServiceFactory factory = manager - .getServiceFactory(factoryId); - if (factory != null) { - Object service = factory.createDomainService(this); - if (service != null - && serviceClass.isAssignableFrom(service.getClass())) { - return serviceClass.cast(service); - } - } - } - if (serviceClass == ICommandServiceDomainDirector.class) { - return serviceClass.cast(new DefaultCommandServiceDomainDirector()); - } - return serviceClass.cast(NullDomainService.getDefault()); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.ICommandServiceDomain#getDirector() - */ - public synchronized ICommandServiceDomainDirector getDirector() { - if (director == null) { - director = createDomainService(ATT_DIRECTOR, - ICommandServiceDomainDirector.class); - director.init(this); - } - return director; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IRemoteCommandServiceDomain# - * getLocalCommandServerDeployer() - */ - public synchronized ICommandServer getCommandServer() { - if (server == null) { - server = createDomainService(ATT_SERVER, ICommandServer.class); - server.init(this); - } - return server; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.ICommandServiceDomain# - * getLocalCommandServerAdvertiser() - */ - public synchronized ICommandServerAdvertiser getCommandServerAdvertiser() { - if (advertiser == null) { - advertiser = createDomainService(ATT_ADVERTISER, - ICommandServerAdvertiser.class); - advertiser.init(this); - } - return advertiser; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IRemoteCommandServiceDomain# - * getRemoteCommandServiceDiscoverer() - */ - public synchronized IRemoteCommandServiceDiscoverer getRemoteCommandServiceDiscoverer() { - if (discoverer == null) { - discoverer = createDomainService(ATT_DISCOVERER, - IRemoteCommandServiceDiscoverer.class); - discoverer.init(this); - } - return discoverer; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof CommandServiceDomainImpl)) - return false; - CommandServiceDomainImpl that = (CommandServiceDomainImpl) obj; - return this.id.equals(that.id); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CommandServiceDomain#" + this.id; //$NON-NLS-1$ - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.command.remote; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.xmind.core.command.remote.ICommandServer; +import org.xmind.core.command.remote.ICommandServerAdvertiser; +import org.xmind.core.command.remote.ICommandServiceDomain; +import org.xmind.core.command.remote.ICommandServiceDomainDirector; +import org.xmind.core.command.remote.IDomainServiceFactory; +import org.xmind.core.command.remote.IRemoteCommandServiceDiscoverer; + +/** + * @author Frank Shaka + */ +public class CommandServiceDomainImpl implements ICommandServiceDomain, + IDomainsExtensionConstants { + + private final CommandServiceDomainManagerImpl manager; + + private final String id; + + private final IConfigurationElement element; + + private ICommandServiceDomainDirector director = null; + + private ICommandServer server = null; + + private ICommandServerAdvertiser advertiser = null; + + private IRemoteCommandServiceDiscoverer discoverer = null; + + /** + * + */ + public CommandServiceDomainImpl(CommandServiceDomainManagerImpl manager, + String id, IConfigurationElement element) { + this.manager = manager; + this.id = id; + this.element = element; + } + + public String getId() { + return id; + } + + public String getName() { + return element.getAttribute(ATT_NAME); + } + + private T createDomainService(String attrName, Class serviceClass) { + String factoryId = element.getAttribute(attrName); + if (factoryId != null) { + IDomainServiceFactory factory = manager + .getServiceFactory(factoryId); + if (factory != null) { + Object service = factory.createDomainService(this); + if (service != null + && serviceClass.isAssignableFrom(service.getClass())) { + return serviceClass.cast(service); + } + } + } + if (serviceClass == ICommandServiceDomainDirector.class) { + return serviceClass.cast(new DefaultCommandServiceDomainDirector()); + } + return serviceClass.cast(NullDomainService.getDefault()); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.ICommandServiceDomain#getDirector() + */ + public synchronized ICommandServiceDomainDirector getDirector() { + if (director == null) { + director = createDomainService(ATT_DIRECTOR, + ICommandServiceDomainDirector.class); + director.init(this); + } + return director; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IRemoteCommandServiceDomain# + * getLocalCommandServerDeployer() + */ + public synchronized ICommandServer getCommandServer() { + if (server == null) { + server = createDomainService(ATT_SERVER, ICommandServer.class); + server.init(this); + } + return server; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.ICommandServiceDomain# + * getLocalCommandServerAdvertiser() + */ + public synchronized ICommandServerAdvertiser getCommandServerAdvertiser() { + if (advertiser == null) { + advertiser = createDomainService(ATT_ADVERTISER, + ICommandServerAdvertiser.class); + advertiser.init(this); + } + return advertiser; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IRemoteCommandServiceDomain# + * getRemoteCommandServiceDiscoverer() + */ + public synchronized IRemoteCommandServiceDiscoverer getRemoteCommandServiceDiscoverer() { + if (discoverer == null) { + discoverer = createDomainService(ATT_DISCOVERER, + IRemoteCommandServiceDiscoverer.class); + discoverer.init(this); + } + return discoverer; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof CommandServiceDomainImpl)) + return false; + CommandServiceDomainImpl that = (CommandServiceDomainImpl) obj; + return this.id.equals(that.id); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CommandServiceDomain#" + this.id; //$NON-NLS-1$ + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainManagerImpl.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainManagerImpl.java index 627c8e870..45cd9a4d1 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainManagerImpl.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/CommandServiceDomainManagerImpl.java @@ -1,200 +1,200 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.command.remote; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.xmind.core.command.remote.ICommandServiceDomain; -import org.xmind.core.command.remote.ICommandServiceDomainManager; -import org.xmind.core.command.remote.IDomainServiceFactory; - -/** - * @author Frank Shaka - */ -public class CommandServiceDomainManagerImpl implements - ICommandServiceDomainManager, IDomainsExtensionConstants { - - private static final CommandServiceDomainManagerImpl singleton = new CommandServiceDomainManagerImpl(); - - private static class DomainServiceFactoryDescriptor { - - private IConfigurationElement element; - - private IDomainServiceFactory factory = null; - - public DomainServiceFactoryDescriptor(IConfigurationElement element) { - this.element = element; - } - - public IDomainServiceFactory getFactory() { - if (factory == null) { - try { - factory = (IDomainServiceFactory) element - .createExecutableExtension(ATT_CLASS); - } catch (CoreException e) { - RemoteCommandPlugin.log(null, e); - factory = NullDomainService.getDefault(); - } - } - return factory == NullDomainService.getDefault() ? null : factory; - } - } - - private Map domains = null; - - private Map factories = null; - - /** - * - */ - private CommandServiceDomainManagerImpl() { - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IRemoteCommandServiceFramework# - * getRemoteCommandServiceDomains() - */ - public synchronized ICommandServiceDomain[] getCommandServiceDomains() { - ensureLoaded(); - return domains.values().toArray( - new ICommandServiceDomain[domains.size()]); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.command.remote.IRemoteCommandServiceFramework# - * getRemoteCommandServiceDomain(java.lang.String) - */ - public synchronized ICommandServiceDomain getCommandServiceDomain( - String domainId) { - ensureLoaded(); - return domains.get(domainId); - } - - public IDomainServiceFactory getServiceFactory(String factoryId) { - DomainServiceFactoryDescriptor factory = factories.get(factoryId); - return factory == null ? null : factory.getFactory(); - } - - private void ensureLoaded() { - if (domains == null) { - IExtensionPoint extensionPoint = Platform.getExtensionRegistry() - .getExtensionPoint(EXT_POINT); - if (extensionPoint != null) { - loadFromExtensions(extensionPoint.getExtensions()); - } - if (domains == null) - domains = new HashMap(1); - } - } - - private void loadFromExtensions(IExtension[] extensions) { - for (int i = 0; i < extensions.length; i++) { - loadFromExtensionElements(extensions[i].getConfigurationElements()); - } - } - - private void loadFromExtensionElements(IConfigurationElement[] elements) { - for (int i = 0; i < elements.length; i++) { - loadFromExtensionElement(elements[i]); - } - } - - private void loadFromExtensionElement(IConfigurationElement element) { - if (TAG_DOMAIN.equals(element.getName())) { - loadRemoteCommandServiceDomain(element); - } else if (TAG_SERVICE_FACTORY.equals(element.getName())) { - loadServiceFactory(element); - } - loadFromExtensionElements(element.getChildren()); - } - - private void loadRemoteCommandServiceDomain(IConfigurationElement element) { - String id = element.getAttribute(ATT_ID); - if (id == null || "".equals(id)) {//$NON-NLS-1$ - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid domain extension: (missing id)")); //$NON-NLS-1$ - return; - } - if (element.getAttribute(ATT_SERVER) == null) { - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid domain extension: (missing server) " + id)); //$NON-NLS-1$ - return; - } - if (element.getAttribute(ATT_ADVERTISER) == null) { - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid domain extension: (missing advertiser) " + id)); //$NON-NLS-1$ - return; - } - if (element.getAttribute(ATT_DISCOVERER) == null) { - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid domain extension: (missing discoverer) " + id)); //$NON-NLS-1$ - return; - } - - CommandServiceDomainImpl domain = new CommandServiceDomainImpl(this, - id, element); - if (domains == null) { - domains = new HashMap(3); - } - domains.put(id, domain); - } - - private void loadServiceFactory(IConfigurationElement element) { - String id = element.getAttribute(ATT_ID); - if (id == null || "".equals(id)) { //$NON-NLS-1$ - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid serviceFactory extension: (missing id)")); //$NON-NLS-1$ - return; - } - - if (element.getAttribute(ATT_CLASS) == null) { - RemoteCommandPlugin.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid serviceFactory extension: (missing class) " + id)); //$NON-NLS-1$ - return; - } - - DomainServiceFactoryDescriptor factory = new DomainServiceFactoryDescriptor( - element); - if (factories == null) { - factories = new HashMap(3); - } - factories.put(id, factory); - } - - public static CommandServiceDomainManagerImpl getDefault() { - return CommandServiceDomainManagerImpl.singleton; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.command.remote; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.xmind.core.command.remote.ICommandServiceDomain; +import org.xmind.core.command.remote.ICommandServiceDomainManager; +import org.xmind.core.command.remote.IDomainServiceFactory; + +/** + * @author Frank Shaka + */ +public class CommandServiceDomainManagerImpl implements + ICommandServiceDomainManager, IDomainsExtensionConstants { + + private static final CommandServiceDomainManagerImpl singleton = new CommandServiceDomainManagerImpl(); + + private static class DomainServiceFactoryDescriptor { + + private IConfigurationElement element; + + private IDomainServiceFactory factory = null; + + public DomainServiceFactoryDescriptor(IConfigurationElement element) { + this.element = element; + } + + public IDomainServiceFactory getFactory() { + if (factory == null) { + try { + factory = (IDomainServiceFactory) element + .createExecutableExtension(ATT_CLASS); + } catch (CoreException e) { + RemoteCommandPlugin.log(null, e); + factory = NullDomainService.getDefault(); + } + } + return factory == NullDomainService.getDefault() ? null : factory; + } + } + + private Map domains = null; + + private Map factories = null; + + /** + * + */ + private CommandServiceDomainManagerImpl() { + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IRemoteCommandServiceFramework# + * getRemoteCommandServiceDomains() + */ + public synchronized ICommandServiceDomain[] getCommandServiceDomains() { + ensureLoaded(); + return domains.values().toArray( + new ICommandServiceDomain[domains.size()]); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.command.remote.IRemoteCommandServiceFramework# + * getRemoteCommandServiceDomain(java.lang.String) + */ + public synchronized ICommandServiceDomain getCommandServiceDomain( + String domainId) { + ensureLoaded(); + return domains.get(domainId); + } + + public IDomainServiceFactory getServiceFactory(String factoryId) { + DomainServiceFactoryDescriptor factory = factories.get(factoryId); + return factory == null ? null : factory.getFactory(); + } + + private void ensureLoaded() { + if (domains == null) { + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(EXT_POINT); + if (extensionPoint != null) { + loadFromExtensions(extensionPoint.getExtensions()); + } + if (domains == null) + domains = new HashMap(1); + } + } + + private void loadFromExtensions(IExtension[] extensions) { + for (int i = 0; i < extensions.length; i++) { + loadFromExtensionElements(extensions[i].getConfigurationElements()); + } + } + + private void loadFromExtensionElements(IConfigurationElement[] elements) { + for (int i = 0; i < elements.length; i++) { + loadFromExtensionElement(elements[i]); + } + } + + private void loadFromExtensionElement(IConfigurationElement element) { + if (TAG_DOMAIN.equals(element.getName())) { + loadRemoteCommandServiceDomain(element); + } else if (TAG_SERVICE_FACTORY.equals(element.getName())) { + loadServiceFactory(element); + } + loadFromExtensionElements(element.getChildren()); + } + + private void loadRemoteCommandServiceDomain(IConfigurationElement element) { + String id = element.getAttribute(ATT_ID); + if (id == null || "".equals(id)) {//$NON-NLS-1$ + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid domain extension: (missing id)")); //$NON-NLS-1$ + return; + } + if (element.getAttribute(ATT_SERVER) == null) { + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid domain extension: (missing server) " + id)); //$NON-NLS-1$ + return; + } + if (element.getAttribute(ATT_ADVERTISER) == null) { + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid domain extension: (missing advertiser) " + id)); //$NON-NLS-1$ + return; + } + if (element.getAttribute(ATT_DISCOVERER) == null) { + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid domain extension: (missing discoverer) " + id)); //$NON-NLS-1$ + return; + } + + CommandServiceDomainImpl domain = new CommandServiceDomainImpl(this, + id, element); + if (domains == null) { + domains = new HashMap(3); + } + domains.put(id, domain); + } + + private void loadServiceFactory(IConfigurationElement element) { + String id = element.getAttribute(ATT_ID); + if (id == null || "".equals(id)) { //$NON-NLS-1$ + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid serviceFactory extension: (missing id)")); //$NON-NLS-1$ + return; + } + + if (element.getAttribute(ATT_CLASS) == null) { + RemoteCommandPlugin.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid serviceFactory extension: (missing class) " + id)); //$NON-NLS-1$ + return; + } + + DomainServiceFactoryDescriptor factory = new DomainServiceFactoryDescriptor( + element); + if (factories == null) { + factories = new HashMap(3); + } + factories.put(id, factory); + } + + public static CommandServiceDomainManagerImpl getDefault() { + return CommandServiceDomainManagerImpl.singleton; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/DefaultCommandServiceDomainDirector.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/DefaultCommandServiceDomainDirector.java index a9a96df3a..3fe3fcf3a 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/DefaultCommandServiceDomainDirector.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/DefaultCommandServiceDomainDirector.java @@ -1,266 +1,266 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.remote.ICommandServiceDomain; -import org.xmind.core.command.remote.ICommandServiceDomainDirector; - -/** - * @author Frank Shaka - */ -public class DefaultCommandServiceDomainDirector implements - ICommandServiceDomainDirector { - - private ICommandServiceDomain domain; - - private int connectionCount = 0; - - private int status = INACTIVE; - - private Object statusLock = new Object(); - - public DefaultCommandServiceDomainDirector() { - } - - public void init(ICommandServiceDomain domain) { - this.domain = domain; - } - - /** - * @return the domain - */ - public ICommandServiceDomain getDomain() { - return domain; - } - - public IStatus connect(IProgressMonitor monitor) { - boolean shouldWait = false; - synchronized (statusLock) { - if (status == ACTIVE) { - connectionCount++; - monitor.done(); - return Status.OK_STATUS; - } else if (status == INACTIVE) { - status = ACTIVATING; - } else if (status == ACTIVATING) { - shouldWait = true; - } else { - return Status.CANCEL_STATUS; - } - } - - monitor.beginTask(NLS.bind( - Messages.DefaultCommandServiceDomainDirector_ConnectionRemoteCommand, - getDomain().getName()), 1); - - if (shouldWait) { - try { - while (true) { - synchronized (statusLock) { - if (status == ACTIVE) { - connectionCount++; - monitor.done(); - return Status.OK_STATUS; - } else if (status == INACTIVE || status == DEACTIVATING) { - return Status.CANCEL_STATUS; - } - } - Thread.sleep(5); - } - } catch (InterruptedException e) { - return Status.CANCEL_STATUS; - } - } else { - IStatus activated; - try { - activated = activate(new SubProgressMonitor(monitor, 1)); - } catch (Throwable e) { - activated = new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, null, e); - } - if (activated != null && !activated.isOK()) { - synchronized (statusLock) { - status = DEACTIVATING; - } - try { - deactivate(new NullProgressMonitor()); - } catch (Throwable e) { - RemoteCommandPlugin.log( - "Failed to deactivate command service domain.", e); //$NON-NLS-1$ - } - synchronized (statusLock) { - status = INACTIVE; - return activated; - } - } else { - synchronized (statusLock) { - status = ACTIVE; - connectionCount++; - monitor.done(); - return Status.OK_STATUS; - } - } - } - } - - public IStatus disconnect(IProgressMonitor monitor) { - synchronized (statusLock) { - if (status == INACTIVE || status == DEACTIVATING) { - monitor.done(); - return Status.OK_STATUS; - } else if (status == ACTIVATING) { - return Status.CANCEL_STATUS; - } else { - connectionCount--; - if (connectionCount > 0) - return Status.OK_STATUS; - status = DEACTIVATING; - } - } - - monitor.beginTask(NLS.bind( - Messages.DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand, - getDomain().getName()), 1); - - IStatus deactivated; - try { - deactivated = deactivate(new SubProgressMonitor(monitor, 1)); - } catch (Throwable e) { - deactivated = new Status(IStatus.ERROR, - RemoteCommandPlugin.PLUGIN_ID, null, e); - } - synchronized (statusLock) { - status = INACTIVE; - } - return deactivated; - } - - /** - * @param monitor - * @return - */ - private IStatus activate(IProgressMonitor monitor) { - monitor.beginTask(null, 100); - - IProgressMonitor subMonitor; - - // Activate remote command service discoverer: - subMonitor = new SubProgressMonitor(monitor, 40); - IStatus activated = getDomain().getRemoteCommandServiceDiscoverer() - .activate(subMonitor); - if (activated != null && !activated.isOK()) - return activated; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - // Deploy local command server: - subMonitor = new SubProgressMonitor(monitor, 30); - IStatus deployed = getDomain().getCommandServer().deploy(subMonitor); - if (deployed != null && !deployed.isOK()) - return deployed; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - // Register local command server as a command service: - getDomain().getCommandServerAdvertiser().setRegisteringInfo( - getDomain().getCommandServer().getRegisteringInfo()); - subMonitor = new SubProgressMonitor(monitor, 30); - IStatus registered = getDomain().getCommandServerAdvertiser().register( - subMonitor); - if (registered != null && !registered.isOK()) - return registered; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.done(); - return Status.OK_STATUS; - } - - /** - * @param nullProgressMonitor - * @return - */ - private IStatus deactivate(IProgressMonitor monitor) { - monitor.beginTask(null, 100); - - IProgressMonitor subMonitor; - - // Unregister local command server as a command service: - subMonitor = new SubProgressMonitor(monitor, 30); - IStatus unregistered = getDomain().getCommandServerAdvertiser() - .unregister(subMonitor); - if (unregistered != null && !unregistered.isOK()) - return unregistered; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - // Undeploy local command server: - subMonitor = new SubProgressMonitor(monitor, 30); - IStatus undeployed = getDomain().getCommandServer() - .undeploy(subMonitor); - if (undeployed != null && !undeployed.isOK()) - return undeployed; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - // Deactivate remote command service discoverer: - subMonitor = new SubProgressMonitor(monitor, 40); - IStatus deactivated = getDomain().getRemoteCommandServiceDiscoverer() - .deactivate(subMonitor); - if (deactivated != null && !deactivated.isOK()) - return deactivated; - if (subMonitor.isCanceled()) - return Status.CANCEL_STATUS; - subMonitor.done(); - - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.done(); - return Status.OK_STATUS; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.command.remote.ICommandServiceDomainDirector#getStatus() - */ - public int getStatus() { - synchronized (statusLock) { - return status; - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.remote.ICommandServiceDomain; +import org.xmind.core.command.remote.ICommandServiceDomainDirector; + +/** + * @author Frank Shaka + */ +public class DefaultCommandServiceDomainDirector implements + ICommandServiceDomainDirector { + + private ICommandServiceDomain domain; + + private int connectionCount = 0; + + private int status = INACTIVE; + + private Object statusLock = new Object(); + + public DefaultCommandServiceDomainDirector() { + } + + public void init(ICommandServiceDomain domain) { + this.domain = domain; + } + + /** + * @return the domain + */ + public ICommandServiceDomain getDomain() { + return domain; + } + + public IStatus connect(IProgressMonitor monitor) { + boolean shouldWait = false; + synchronized (statusLock) { + if (status == ACTIVE) { + connectionCount++; + monitor.done(); + return Status.OK_STATUS; + } else if (status == INACTIVE) { + status = ACTIVATING; + } else if (status == ACTIVATING) { + shouldWait = true; + } else { + return Status.CANCEL_STATUS; + } + } + + monitor.beginTask(NLS.bind( + Messages.DefaultCommandServiceDomainDirector_ConnectionRemoteCommand, + getDomain().getName()), 1); + + if (shouldWait) { + try { + while (true) { + synchronized (statusLock) { + if (status == ACTIVE) { + connectionCount++; + monitor.done(); + return Status.OK_STATUS; + } else if (status == INACTIVE || status == DEACTIVATING) { + return Status.CANCEL_STATUS; + } + } + Thread.sleep(5); + } + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } + } else { + IStatus activated; + try { + activated = activate(new SubProgressMonitor(monitor, 1)); + } catch (Throwable e) { + activated = new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, null, e); + } + if (activated != null && !activated.isOK()) { + synchronized (statusLock) { + status = DEACTIVATING; + } + try { + deactivate(new NullProgressMonitor()); + } catch (Throwable e) { + RemoteCommandPlugin.log( + "Failed to deactivate command service domain.", e); //$NON-NLS-1$ + } + synchronized (statusLock) { + status = INACTIVE; + return activated; + } + } else { + synchronized (statusLock) { + status = ACTIVE; + connectionCount++; + monitor.done(); + return Status.OK_STATUS; + } + } + } + } + + public IStatus disconnect(IProgressMonitor monitor) { + synchronized (statusLock) { + if (status == INACTIVE || status == DEACTIVATING) { + monitor.done(); + return Status.OK_STATUS; + } else if (status == ACTIVATING) { + return Status.CANCEL_STATUS; + } else { + connectionCount--; + if (connectionCount > 0) + return Status.OK_STATUS; + status = DEACTIVATING; + } + } + + monitor.beginTask(NLS.bind( + Messages.DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand, + getDomain().getName()), 1); + + IStatus deactivated; + try { + deactivated = deactivate(new SubProgressMonitor(monitor, 1)); + } catch (Throwable e) { + deactivated = new Status(IStatus.ERROR, + RemoteCommandPlugin.PLUGIN_ID, null, e); + } + synchronized (statusLock) { + status = INACTIVE; + } + return deactivated; + } + + /** + * @param monitor + * @return + */ + private IStatus activate(IProgressMonitor monitor) { + monitor.beginTask(null, 100); + + IProgressMonitor subMonitor; + + // Activate remote command service discoverer: + subMonitor = new SubProgressMonitor(monitor, 40); + IStatus activated = getDomain().getRemoteCommandServiceDiscoverer() + .activate(subMonitor); + if (activated != null && !activated.isOK()) + return activated; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + // Deploy local command server: + subMonitor = new SubProgressMonitor(monitor, 30); + IStatus deployed = getDomain().getCommandServer().deploy(subMonitor); + if (deployed != null && !deployed.isOK()) + return deployed; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + // Register local command server as a command service: + getDomain().getCommandServerAdvertiser().setRegisteringInfo( + getDomain().getCommandServer().getRegisteringInfo()); + subMonitor = new SubProgressMonitor(monitor, 30); + IStatus registered = getDomain().getCommandServerAdvertiser().register( + subMonitor); + if (registered != null && !registered.isOK()) + return registered; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.done(); + return Status.OK_STATUS; + } + + /** + * @param nullProgressMonitor + * @return + */ + private IStatus deactivate(IProgressMonitor monitor) { + monitor.beginTask(null, 100); + + IProgressMonitor subMonitor; + + // Unregister local command server as a command service: + subMonitor = new SubProgressMonitor(monitor, 30); + IStatus unregistered = getDomain().getCommandServerAdvertiser() + .unregister(subMonitor); + if (unregistered != null && !unregistered.isOK()) + return unregistered; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + // Undeploy local command server: + subMonitor = new SubProgressMonitor(monitor, 30); + IStatus undeployed = getDomain().getCommandServer() + .undeploy(subMonitor); + if (undeployed != null && !undeployed.isOK()) + return undeployed; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + // Deactivate remote command service discoverer: + subMonitor = new SubProgressMonitor(monitor, 40); + IStatus deactivated = getDomain().getRemoteCommandServiceDiscoverer() + .deactivate(subMonitor); + if (deactivated != null && !deactivated.isOK()) + return deactivated; + if (subMonitor.isCanceled()) + return Status.CANCEL_STATUS; + subMonitor.done(); + + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.done(); + return Status.OK_STATUS; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.command.remote.ICommandServiceDomainDirector#getStatus() + */ + public int getStatus() { + synchronized (statusLock) { + return status; + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { + return null; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/IDomainsExtensionConstants.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/IDomainsExtensionConstants.java index 007cbb1ca..d5f6595c2 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/IDomainsExtensionConstants.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/IDomainsExtensionConstants.java @@ -1,44 +1,44 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.command.remote; - -/** - * @author Frank Shaka - */ -public interface IDomainsExtensionConstants { - - String EXT_POINT = "org.xmind.core.command.remote.domains"; //$NON-NLS-1$ - - String TAG_DOMAIN = "domain"; //$NON-NLS-1$ - - String TAG_SERVICE_FACTORY = "serviceFactory"; //$NON-NLS-1$ - - String ATT_ID = "id"; //$NON-NLS-1$ - - String ATT_NAME = "name"; //$NON-NLS-1$ - - String ATT_DIRECTOR = "director"; //$NON-NLS-1$ - - String ATT_SERVER = "server"; //$NON-NLS-1$ - - String ATT_ADVERTISER = "advertiser"; //$NON-NLS-1$ - - String ATT_DISCOVERER = "discoverer"; //$NON-NLS-1$ - - String ATT_CLASS = "class"; //$NON-NLS-1$ - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.command.remote; + +/** + * @author Frank Shaka + */ +public interface IDomainsExtensionConstants { + + String EXT_POINT = "org.xmind.core.command.remote.domains"; //$NON-NLS-1$ + + String TAG_DOMAIN = "domain"; //$NON-NLS-1$ + + String TAG_SERVICE_FACTORY = "serviceFactory"; //$NON-NLS-1$ + + String ATT_ID = "id"; //$NON-NLS-1$ + + String ATT_NAME = "name"; //$NON-NLS-1$ + + String ATT_DIRECTOR = "director"; //$NON-NLS-1$ + + String ATT_SERVER = "server"; //$NON-NLS-1$ + + String ATT_ADVERTISER = "advertiser"; //$NON-NLS-1$ + + String ATT_DISCOVERER = "discoverer"; //$NON-NLS-1$ + + String ATT_CLASS = "class"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/Messages.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/Messages.java index 1cb529634..44f3fa2a5 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/Messages.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/Messages.java @@ -1,41 +1,41 @@ -package org.xmind.core.internal.command.remote; - -import org.eclipse.osgi.util.NLS; - -/** - * @auther Jason Wong - */ - -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.xmind.core.internal.command.remote.messages"; //$NON-NLS-1$ - public static String DefaultCommandServiceDomainDirector_ConnectionRemoteCommand; - public static String DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand; - public static String IncomingCommandHandler_ConnectionClose; - public static String IncomingCommandHandler_ExcuteCommand; - public static String IncomingCommandHandler_ReadCommand; - public static String IncomingCommandHandler_WriteReponseBack; - public static String IncomingSocketCommandHandler_ConnectionFailed_Message; - public static String OutgoingCommandHandler_ConnectionClose; - public static String OutgoingCommandHandler_ConsumeReturnValue; - public static String OutgoingCommandHandler_ExcuteCommand; - public static String OutgoingCommandHandler_InvalidReturnValueCode; - public static String OutgoingCommandHandler_InvalidReturnValueStatus; - public static String OutgoingCommandHandler_ReceiveReturnValue; - public static String OutgoingCommandHandler_SendCommand; - public static String OutgoingSocketCommandHandler_ConnectionFailed_Message; - public static String OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message; - public static String OutgoingSocketCommandHandler_ConnectionTimeOut; - public static String OutgoingSocketCommandHandler_FailedOpenInputStream; - public static String OutgoingSocketCommandHandler_FailedOpenOutputStream; - public static String RemoteCommandJob_CommandSendError_Message; - public static String SocketCommandServer_CloseCommandServerSocket; - public static String SocketCommandServer_OpenCommandServerSocket; - public static String SocketCommandServer_OperationLock; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} +package org.xmind.core.internal.command.remote; + +import org.eclipse.osgi.util.NLS; + +/** + * @auther Jason Wong + */ + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.xmind.core.internal.command.remote.messages"; //$NON-NLS-1$ + public static String DefaultCommandServiceDomainDirector_ConnectionRemoteCommand; + public static String DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand; + public static String IncomingCommandHandler_ConnectionClose; + public static String IncomingCommandHandler_ExcuteCommand; + public static String IncomingCommandHandler_ReadCommand; + public static String IncomingCommandHandler_WriteReponseBack; + public static String IncomingSocketCommandHandler_ConnectionFailed_Message; + public static String OutgoingCommandHandler_ConnectionClose; + public static String OutgoingCommandHandler_ConsumeReturnValue; + public static String OutgoingCommandHandler_ExcuteCommand; + public static String OutgoingCommandHandler_InvalidReturnValueCode; + public static String OutgoingCommandHandler_InvalidReturnValueStatus; + public static String OutgoingCommandHandler_ReceiveReturnValue; + public static String OutgoingCommandHandler_SendCommand; + public static String OutgoingSocketCommandHandler_ConnectionFailed_Message; + public static String OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message; + public static String OutgoingSocketCommandHandler_ConnectionTimeOut; + public static String OutgoingSocketCommandHandler_FailedOpenInputStream; + public static String OutgoingSocketCommandHandler_FailedOpenOutputStream; + public static String RemoteCommandJob_CommandSendError_Message; + public static String SocketCommandServer_CloseCommandServerSocket; + public static String SocketCommandServer_OpenCommandServerSocket; + public static String SocketCommandServer_OperationLock; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/NullDomainService.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/NullDomainService.java index d9ee9622e..356f2816c 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/NullDomainService.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/NullDomainService.java @@ -1,144 +1,144 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command.remote; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.xmind.core.command.remote.CommandServiceInfo; -import org.xmind.core.command.remote.ICommandServer; -import org.xmind.core.command.remote.ICommandServerAdvertiser; -import org.xmind.core.command.remote.ICommandServiceDomain; -import org.xmind.core.command.remote.ICommandServiceDomainDirector; -import org.xmind.core.command.remote.ICommandServiceInfo; -import org.xmind.core.command.remote.IDomainServiceFactory; -import org.xmind.core.command.remote.IRemoteCommandService; -import org.xmind.core.command.remote.IRemoteCommandServiceDiscoverer; -import org.xmind.core.command.remote.IRemoteCommandServiceListener; - -/** - * @author Frank Shaka - */ -public class NullDomainService implements IDomainServiceFactory, - ICommandServiceDomainDirector, ICommandServer, - ICommandServerAdvertiser, IRemoteCommandServiceDiscoverer { - - private static final IRemoteCommandService[] NO_SERVICES = new IRemoteCommandService[0]; - - private static NullDomainService singleton = null; - - private ICommandServiceInfo info = new CommandServiceInfo(); - - /** - * - */ - private NullDomainService() { - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.command.remote.IDomainService#init(org.xmind.core.command - * .remote.ICommandServiceDomain) - */ - public void init(ICommandServiceDomain domain) { - } - - public IStatus activate(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IStatus deactivate(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IRemoteCommandService[] getRemoteCommandServices() { - return NO_SERVICES; - } - - public IRemoteCommandService findRemoteCommandService(String serviceName) { - return null; - } - - public void addRemoteCommandServiceListener( - IRemoteCommandServiceListener listener) { - } - - public void removeRemoteCommandServiceListener( - IRemoteCommandServiceListener listener) { - } - - public IStatus refresh(IProgressMonitor monitor) { - monitor.done(); - return Status.OK_STATUS; - } - - public void setRegisteringInfo(ICommandServiceInfo info) { - this.info = info; - } - - public IStatus register(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IStatus unregister(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IStatus deploy(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IStatus undeploy(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public ICommandServiceInfo getRegisteringInfo() { - return info; - } - - public ICommandServiceInfo getRegisteredInfo() { - return info; - } - - public IStatus connect(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public IStatus disconnect(IProgressMonitor monitor) { - return Status.CANCEL_STATUS; - } - - public int getStatus() { - return INACTIVE; - } - - public Object createDomainService(ICommandServiceDomain domain) { - return this; - } - - public static synchronized NullDomainService getDefault() { - if (singleton == null) { - singleton = new NullDomainService(); - } - return singleton; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command.remote; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.xmind.core.command.remote.CommandServiceInfo; +import org.xmind.core.command.remote.ICommandServer; +import org.xmind.core.command.remote.ICommandServerAdvertiser; +import org.xmind.core.command.remote.ICommandServiceDomain; +import org.xmind.core.command.remote.ICommandServiceDomainDirector; +import org.xmind.core.command.remote.ICommandServiceInfo; +import org.xmind.core.command.remote.IDomainServiceFactory; +import org.xmind.core.command.remote.IRemoteCommandService; +import org.xmind.core.command.remote.IRemoteCommandServiceDiscoverer; +import org.xmind.core.command.remote.IRemoteCommandServiceListener; + +/** + * @author Frank Shaka + */ +public class NullDomainService implements IDomainServiceFactory, + ICommandServiceDomainDirector, ICommandServer, + ICommandServerAdvertiser, IRemoteCommandServiceDiscoverer { + + private static final IRemoteCommandService[] NO_SERVICES = new IRemoteCommandService[0]; + + private static NullDomainService singleton = null; + + private ICommandServiceInfo info = new CommandServiceInfo(); + + /** + * + */ + private NullDomainService() { + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.command.remote.IDomainService#init(org.xmind.core.command + * .remote.ICommandServiceDomain) + */ + public void init(ICommandServiceDomain domain) { + } + + public IStatus activate(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IStatus deactivate(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IRemoteCommandService[] getRemoteCommandServices() { + return NO_SERVICES; + } + + public IRemoteCommandService findRemoteCommandService(String serviceName) { + return null; + } + + public void addRemoteCommandServiceListener( + IRemoteCommandServiceListener listener) { + } + + public void removeRemoteCommandServiceListener( + IRemoteCommandServiceListener listener) { + } + + public IStatus refresh(IProgressMonitor monitor) { + monitor.done(); + return Status.OK_STATUS; + } + + public void setRegisteringInfo(ICommandServiceInfo info) { + this.info = info; + } + + public IStatus register(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IStatus unregister(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IStatus deploy(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IStatus undeploy(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public ICommandServiceInfo getRegisteringInfo() { + return info; + } + + public ICommandServiceInfo getRegisteredInfo() { + return info; + } + + public IStatus connect(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public IStatus disconnect(IProgressMonitor monitor) { + return Status.CANCEL_STATUS; + } + + public int getStatus() { + return INACTIVE; + } + + public Object createDomainService(ICommandServiceDomain domain) { + return this; + } + + public static synchronized NullDomainService getDefault() { + if (singleton == null) { + singleton = new NullDomainService(); + } + return singleton; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { + return null; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/RemoteCommandPlugin.java b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/RemoteCommandPlugin.java index eb8ecd40b..7833efaeb 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/RemoteCommandPlugin.java +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/RemoteCommandPlugin.java @@ -1,104 +1,104 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command.remote; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.xmind.core.command.ICommandService; -import org.xmind.core.command.remote.ICommandServiceDomainManager; -import org.xmind.core.internal.command.XMindCommandPlugin; - -/** - * - * @author Frank Shaka - * - */ -public class RemoteCommandPlugin implements BundleActivator { - - public static final String PLUGIN_ID = "org.xmind.core.command.remote"; //$NON-NLS-1$ - - private static BundleContext context; - - private static RemoteCommandPlugin singleton; - - private ServiceRegistration frameworkRegistration = null; - - private ServiceTracker debugTracker = null; - - static BundleContext getContext() { - return context; - } - - public void start(BundleContext bundleContext) throws Exception { - RemoteCommandPlugin.singleton = this; - RemoteCommandPlugin.context = bundleContext; - - frameworkRegistration = bundleContext.registerService( - ICommandServiceDomainManager.class, - CommandServiceDomainManagerImpl.getDefault(), null); - - } - - public void stop(BundleContext bundleContext) throws Exception { - if (debugTracker != null) { - debugTracker.close(); - debugTracker = null; - } - if (frameworkRegistration != null) { - frameworkRegistration.unregister(); - frameworkRegistration = null; - } - RemoteCommandPlugin.context = null; - RemoteCommandPlugin.singleton = null; - } - - public static void log(String message, Throwable e) { - log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } - - public static void log(IStatus status) { - Platform.getLog(context.getBundle()).log(status); - } - - public DebugOptions getDebugOptions() { - if (debugTracker == null) { - debugTracker = new ServiceTracker( - context, DebugOptions.class.getName(), null); - debugTracker.open(); - } - return debugTracker.getService(); - } - - public boolean isDebugging(String option) { - DebugOptions debugOptions = getDebugOptions(); - return debugOptions!=null&&debugOptions.isDebugEnabled() - && debugOptions - .getBooleanOption(PLUGIN_ID + option, false); - } - - public ICommandService getCommandService() { - return XMindCommandPlugin.getDefault().getCommandService(); - } - - public static RemoteCommandPlugin getDefault() { - return RemoteCommandPlugin.singleton; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command.remote; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.ServiceTracker; +import org.xmind.core.command.ICommandService; +import org.xmind.core.command.remote.ICommandServiceDomainManager; +import org.xmind.core.internal.command.XMindCommandPlugin; + +/** + * + * @author Frank Shaka + * + */ +public class RemoteCommandPlugin implements BundleActivator { + + public static final String PLUGIN_ID = "org.xmind.core.command.remote"; //$NON-NLS-1$ + + private static BundleContext context; + + private static RemoteCommandPlugin singleton; + + private ServiceRegistration frameworkRegistration = null; + + private ServiceTracker debugTracker = null; + + static BundleContext getContext() { + return context; + } + + public void start(BundleContext bundleContext) throws Exception { + RemoteCommandPlugin.singleton = this; + RemoteCommandPlugin.context = bundleContext; + + frameworkRegistration = bundleContext.registerService( + ICommandServiceDomainManager.class, + CommandServiceDomainManagerImpl.getDefault(), null); + + } + + public void stop(BundleContext bundleContext) throws Exception { + if (debugTracker != null) { + debugTracker.close(); + debugTracker = null; + } + if (frameworkRegistration != null) { + frameworkRegistration.unregister(); + frameworkRegistration = null; + } + RemoteCommandPlugin.context = null; + RemoteCommandPlugin.singleton = null; + } + + public static void log(String message, Throwable e) { + log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + + public static void log(IStatus status) { + Platform.getLog(context.getBundle()).log(status); + } + + public DebugOptions getDebugOptions() { + if (debugTracker == null) { + debugTracker = new ServiceTracker( + context, DebugOptions.class.getName(), null); + debugTracker.open(); + } + return debugTracker.getService(); + } + + public boolean isDebugging(String option) { + DebugOptions debugOptions = getDebugOptions(); + return debugOptions!=null&&debugOptions.isDebugEnabled() + && debugOptions + .getBooleanOption(PLUGIN_ID + option, false); + } + + public ICommandService getCommandService() { + return XMindCommandPlugin.getDefault().getCommandService(); + } + + public static RemoteCommandPlugin getDefault() { + return RemoteCommandPlugin.singleton; + } + +} diff --git a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/messages.properties b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/messages.properties index c575a815c..44765b97c 100644 --- a/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/messages.properties +++ b/bundles/org.xmind.core.command.remote/src/org/xmind/core/internal/command/remote/messages.properties @@ -1,23 +1,23 @@ -DefaultCommandServiceDomainDirector_ConnectionRemoteCommand=Connecting to remote command service domain ''{0}'' -DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand=Disconnecting from remote command service domain ''{0}'' -IncomingCommandHandler_ConnectionClose=Connection closed unexpectedly. Remote client may have been offline. -IncomingCommandHandler_ExcuteCommand=Executing command {0} -IncomingCommandHandler_ReadCommand=Reading command from request -IncomingCommandHandler_WriteReponseBack=Writing response back -IncomingSocketCommandHandler_ConnectionFailed_Message=Connection failed. Remote client may have been offline: {0} -OutgoingCommandHandler_ConnectionClose=Connection closed unexpectedly. Remote client may have been offline. -OutgoingCommandHandler_ConsumeReturnValue=Consuming return value -OutgoingCommandHandler_ExcuteCommand=Executing command remotely -OutgoingCommandHandler_InvalidReturnValueCode=Invalid return value code: {0} -OutgoingCommandHandler_InvalidReturnValueStatus=Invalid return value status: {0} -OutgoingCommandHandler_ReceiveReturnValue=Receiving return value from remote command service -OutgoingCommandHandler_SendCommand=Sending command to remote command service -OutgoingSocketCommandHandler_ConnectionFailed_Message=Connection failed. Remote client may be offline: {0} -OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message=Connecting to remote command service at {0} -OutgoingSocketCommandHandler_ConnectionTimeOut=Connection timed out. Remote client may have been offline: {0} -OutgoingSocketCommandHandler_FailedOpenInputStream=Failed to open input stream on {0} -OutgoingSocketCommandHandler_FailedOpenOutputStream=Failed to open output stream on {0} -RemoteCommandJob_CommandSendError_Message=No command to send. -SocketCommandServer_CloseCommandServerSocket=Closing local command server socket -SocketCommandServer_OpenCommandServerSocket=Opening local command server socket -SocketCommandServer_OperationLock=Acquiring operation lock +DefaultCommandServiceDomainDirector_ConnectionRemoteCommand=Connecting to remote command service domain ''{0}'' +DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand=Disconnecting from remote command service domain ''{0}'' +IncomingCommandHandler_ConnectionClose=Connection closed unexpectedly. Remote client may have been offline. +IncomingCommandHandler_ExcuteCommand=Executing command {0} +IncomingCommandHandler_ReadCommand=Reading command from request +IncomingCommandHandler_WriteReponseBack=Writing response back +IncomingSocketCommandHandler_ConnectionFailed_Message=Connection failed. Remote client may have been offline: {0} +OutgoingCommandHandler_ConnectionClose=Connection closed unexpectedly. Remote client may have been offline. +OutgoingCommandHandler_ConsumeReturnValue=Consuming return value +OutgoingCommandHandler_ExcuteCommand=Executing command remotely +OutgoingCommandHandler_InvalidReturnValueCode=Invalid return value code: {0} +OutgoingCommandHandler_InvalidReturnValueStatus=Invalid return value status: {0} +OutgoingCommandHandler_ReceiveReturnValue=Receiving return value from remote command service +OutgoingCommandHandler_SendCommand=Sending command to remote command service +OutgoingSocketCommandHandler_ConnectionFailed_Message=Connection failed. Remote client may be offline: {0} +OutgoingSocketCommandHandler_ConnectionRemoteCommand_Message=Connecting to remote command service at {0} +OutgoingSocketCommandHandler_ConnectionTimeOut=Connection timed out. Remote client may have been offline: {0} +OutgoingSocketCommandHandler_FailedOpenInputStream=Failed to open input stream on {0} +OutgoingSocketCommandHandler_FailedOpenOutputStream=Failed to open output stream on {0} +RemoteCommandJob_CommandSendError_Message=No command to send. +SocketCommandServer_CloseCommandServerSocket=Closing local command server socket +SocketCommandServer_OpenCommandServerSocket=Opening local command server socket +SocketCommandServer_OperationLock=Acquiring operation lock diff --git a/bundles/org.xmind.core.command/.classpath b/bundles/org.xmind.core.command/.classpath index 2d1a4302f..64c5e31b7 100644 --- a/bundles/org.xmind.core.command/.classpath +++ b/bundles/org.xmind.core.command/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.core.command/.gitignore b/bundles/org.xmind.core.command/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.command/.gitignore +++ b/bundles/org.xmind.core.command/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.command/.options b/bundles/org.xmind.core.command/.options index 7c1807823..8806e5ec6 100644 --- a/bundles/org.xmind.core.command/.options +++ b/bundles/org.xmind.core.command/.options @@ -1 +1 @@ -org.xmind.core.command/debug=false +org.xmind.core.command/debug=false diff --git a/bundles/org.xmind.core.command/.project b/bundles/org.xmind.core.command/.project index 7dfb843ca..14a8d8974 100644 --- a/bundles/org.xmind.core.command/.project +++ b/bundles/org.xmind.core.command/.project @@ -1,28 +1,28 @@ - - - org.xmind.core.command - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.core.command + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.core.prefs index 5d49216ca..99e8a2a52 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.core.prefs @@ -1,410 +1,410 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.ui.prefs index 5ff980f2f..6a418ff47 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.jdt.ui.prefs @@ -1,3 +1,3 @@ -eclipse.preferences.version=1 -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 +eclipse.preferences.version=1 +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 diff --git a/bundles/org.xmind.core.command/.settings/org.eclipse.ltk.core.refactoring.prefs b/bundles/org.xmind.core.command/.settings/org.eclipse.ltk.core.refactoring.prefs index cfcd1d3c2..b196c64a3 100644 --- a/bundles/org.xmind.core.command/.settings/org.eclipse.ltk.core.refactoring.prefs +++ b/bundles/org.xmind.core.command/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/bundles/org.xmind.core.command/META-INF/MANIFEST.MF b/bundles/org.xmind.core.command/META-INF/MANIFEST.MF index 88a8e346c..1d8691464 100644 --- a/bundles/org.xmind.core.command/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.command/META-INF/MANIFEST.MF @@ -1,15 +1,15 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name -Bundle-SymbolicName: org.xmind.core.command;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.core.internal.command.XMindCommandPlugin -Bundle-Vendor: %Bundle-Vendor -Require-Bundle: org.eclipse.core.runtime -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.core.command, - org.xmind.core.command.arguments, - org.xmind.core.command.binary, - org.xmind.core.internal.command;x-internal:=true -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.xmind.core.command;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.core.internal.command.XMindCommandPlugin +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.core.runtime +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.core.command, + org.xmind.core.command.arguments, + org.xmind.core.command.binary, + org.xmind.core.internal.command;x-internal:=true +Bundle-Localization: plugin diff --git a/bundles/org.xmind.core.command/about.html b/bundles/org.xmind.core.command/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.command/about.html +++ b/bundles/org.xmind.core.command/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.command/build.properties b/bundles/org.xmind.core.command/build.properties index 172b18cc4..7488572a3 100644 --- a/bundles/org.xmind.core.command/build.properties +++ b/bundles/org.xmind.core.command/build.properties @@ -1,10 +1,10 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - plugin.xml,\ - .,\ - .options,\ - plugin.properties,\ - about.html -src.includes = about.html,\ - schema/ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + plugin.xml,\ + .,\ + .options,\ + plugin.properties,\ + about.html +src.includes = about.html,\ + schema/ diff --git a/bundles/org.xmind.core.command/plugin.properties b/bundles/org.xmind.core.command/plugin.properties index ca6f83c1c..141f819e7 100644 --- a/bundles/org.xmind.core.command/plugin.properties +++ b/bundles/org.xmind.core.command/plugin.properties @@ -1,4 +1,4 @@ -#Properties file for org.xmind.core.command -command.handlers.name=XMind Command Handlers -Bundle-Vendor = XMind Ltd. +#Properties file for org.xmind.core.command +command.handlers.name=XMind Command Handlers +Bundle-Vendor = XMind Ltd. Bundle-Name = XMind Command Service Core \ No newline at end of file diff --git a/bundles/org.xmind.core.command/plugin.xml b/bundles/org.xmind.core.command/plugin.xml index 76ff3f0d1..6ba9d6ad3 100644 --- a/bundles/org.xmind.core.command/plugin.xml +++ b/bundles/org.xmind.core.command/plugin.xml @@ -1,5 +1,5 @@ - - - - - + + + + + diff --git a/bundles/org.xmind.core.command/pom.xml b/bundles/org.xmind.core.command/pom.xml index ed154836d..3fae40a32 100644 --- a/bundles/org.xmind.core.command/pom.xml +++ b/bundles/org.xmind.core.command/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.command - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.command + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.command/schema/handlers.exsd b/bundles/org.xmind.core.command/schema/handlers.exsd index c149275f5..15a681ae5 100644 --- a/bundles/org.xmind.core.command/schema/handlers.exsd +++ b/bundles/org.xmind.core.command/schema/handlers.exsd @@ -1,115 +1,115 @@ - - - - - - - - - [Enter description of this extension point.] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [Enter the first release in which this extension point appears.] - - - - - - - - - [Enter extension point usage example here.] - - - - - - - - - [Enter API information here.] - - - - - - - - - [Enter information about supplied implementation of this extension point.] - - - - - + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/Command.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/Command.java index 6c2de240e..b94ed38d0 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/Command.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/Command.java @@ -1,223 +1,223 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Iterator; - -import org.xmind.core.command.arguments.Attributes; -import org.xmind.core.command.binary.IBinaryEntry; -import org.xmind.core.command.binary.IBinaryStore; -import org.xmind.core.internal.command.Logger; -import org.xmind.core.internal.command.XMindCommandPlugin; - -public class Command implements ICommand { - - private static boolean DEBUGGING = XMindCommandPlugin.isDebugging("/debug"); //$NON-NLS-1$ - - public static final String XMIND_SCHEME = "xmind"; //$NON-NLS-1$ - - public static final String XMIND_PROTOCOL = XMIND_SCHEME + ":"; //$NON-NLS-1$ - - private String source; - - private String commandName; - - private Attributes arguments; - - private String target; - - private IBinaryStore files; - - public Command(String source, String commandName) { - this(source, commandName, null, null, null); - } - - public Command(String source, String commandName, Attributes arguments, - String target, IBinaryStore files) { - this.source = source; - this.commandName = commandName; - if (arguments == null) { - this.arguments = new Attributes(); - } else { - this.arguments = arguments; - } - this.target = target; - this.files = files; - } - - public String getCommandName() { - return commandName; - } - - public Attributes getArguments() { - return arguments; - } - - public String getArgument(String key) { - return arguments.get(key); - } - - public String getSource() { - return source; - } - - public String getTarget() { - return target; - } - - public IBinaryStore getBinaryStore() { - return files; - } - - public IBinaryEntry getBinaryEntry(String entryName) { - return files == null ? null : files.getEntry(entryName); - } - - public static Command parseURI(String uriString, IBinaryStore files) { - URI uri; - try { - uri = new URI(uriString); - } catch (URISyntaxException e) { - Logger.log("Malformed URI: " + uriString, null); //$NON-NLS-1$ - return null; - } - - if (!XMIND_SCHEME.equals(uri.getScheme())) { - if (DEBUGGING) - System.out - .println("Not a valid XMind command URI: " + uriString); //$NON-NLS-1$ - return null; - } - - return new Command(uri.getHost(), trimPath(uri.getPath()), - parseArguments(uri.getRawQuery()), uri.getFragment(), files); - } - - public static Command parseURI(String uriString) { - return parseURI(uriString, null); - } - - private static String trimPath(String path) { - if (path == null) - return path; - if (path.startsWith("/")) //$NON-NLS-1$ - path = path.substring(1); - if (path.endsWith("/")) //$NON-NLS-1$ - path = path.substring(0, path.length() - 1); - return path; - } - - private static Attributes parseArguments(String query) { - if (query == null || "".equals(query)) //$NON-NLS-1$ - return new Attributes(); - Attributes args = new Attributes(); - for (String kv : query.split("&")) { //$NON-NLS-1$ - int sep = kv.indexOf('='); - if (sep < 0) { - args.with(urlDecode(kv), ""); //$NON-NLS-1$ - } else { - args.with(urlDecode(kv.substring(0, sep)), - urlDecode(kv.substring(sep + 1))); - } - } - return args; - } - - private static String urlDecode(String text) { - try { - return URLDecoder.decode(text, "UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - if (DEBUGGING) { - System.err.println("Failed to decode XMind command argument: " //$NON-NLS-1$ - + text); - e.printStackTrace(); - } - return text; - } - } - - private static String urlEncode(String text) { - try { - return URLEncoder.encode(text, "UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - if (DEBUGGING) { - System.err.println("Failed to encode XMind command argument: " //$NON-NLS-1$ - + text); - e.printStackTrace(); - } - return text; - } - } - - public String toURI() { - return toURI(this); - } - - @Override - public String toString() { - return toURI(); - } - - public static String toURI(ICommand command) { - StringBuffer buf = new StringBuffer(32); - buf.append(XMIND_PROTOCOL); - buf.append('/'); - buf.append('/'); - buf.append(command.getSource()); - - String commandName = command.getCommandName(); - if (commandName != null) { - if (!commandName.startsWith("/")) { //$NON-NLS-1$ - buf.append('/'); - } - buf.append(commandName); - } else { - buf.append('/'); - } - - Attributes arguments = command.getArguments(); - if (arguments != null && !arguments.isEmpty()) { - buf.append('?'); - Iterator keys = arguments.keys(); - boolean firstArgument = true; - while (keys.hasNext()) { - String key = keys.next(); - String value = arguments.get(key); - if (value != null) { - if (!firstArgument) { - buf.append('&'); - } else { - firstArgument = false; - } - buf.append(urlEncode(key)); - buf.append('='); - buf.append(urlEncode(value)); - } - } - } - - String target = command.getTarget(); - if (target != null) { - buf.append('#'); - buf.append(target); - } - return buf.toString(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Iterator; + +import org.xmind.core.command.arguments.Attributes; +import org.xmind.core.command.binary.IBinaryEntry; +import org.xmind.core.command.binary.IBinaryStore; +import org.xmind.core.internal.command.Logger; +import org.xmind.core.internal.command.XMindCommandPlugin; + +public class Command implements ICommand { + + private static boolean DEBUGGING = XMindCommandPlugin.isDebugging("/debug"); //$NON-NLS-1$ + + public static final String XMIND_SCHEME = "xmind"; //$NON-NLS-1$ + + public static final String XMIND_PROTOCOL = XMIND_SCHEME + ":"; //$NON-NLS-1$ + + private String source; + + private String commandName; + + private Attributes arguments; + + private String target; + + private IBinaryStore files; + + public Command(String source, String commandName) { + this(source, commandName, null, null, null); + } + + public Command(String source, String commandName, Attributes arguments, + String target, IBinaryStore files) { + this.source = source; + this.commandName = commandName; + if (arguments == null) { + this.arguments = new Attributes(); + } else { + this.arguments = arguments; + } + this.target = target; + this.files = files; + } + + public String getCommandName() { + return commandName; + } + + public Attributes getArguments() { + return arguments; + } + + public String getArgument(String key) { + return arguments.get(key); + } + + public String getSource() { + return source; + } + + public String getTarget() { + return target; + } + + public IBinaryStore getBinaryStore() { + return files; + } + + public IBinaryEntry getBinaryEntry(String entryName) { + return files == null ? null : files.getEntry(entryName); + } + + public static Command parseURI(String uriString, IBinaryStore files) { + URI uri; + try { + uri = new URI(uriString); + } catch (URISyntaxException e) { + Logger.log("Malformed URI: " + uriString, null); //$NON-NLS-1$ + return null; + } + + if (!XMIND_SCHEME.equals(uri.getScheme())) { + if (DEBUGGING) + System.out + .println("Not a valid XMind command URI: " + uriString); //$NON-NLS-1$ + return null; + } + + return new Command(uri.getHost(), trimPath(uri.getPath()), + parseArguments(uri.getRawQuery()), uri.getFragment(), files); + } + + public static Command parseURI(String uriString) { + return parseURI(uriString, null); + } + + private static String trimPath(String path) { + if (path == null) + return path; + if (path.startsWith("/")) //$NON-NLS-1$ + path = path.substring(1); + if (path.endsWith("/")) //$NON-NLS-1$ + path = path.substring(0, path.length() - 1); + return path; + } + + private static Attributes parseArguments(String query) { + if (query == null || "".equals(query)) //$NON-NLS-1$ + return new Attributes(); + Attributes args = new Attributes(); + for (String kv : query.split("&")) { //$NON-NLS-1$ + int sep = kv.indexOf('='); + if (sep < 0) { + args.with(urlDecode(kv), ""); //$NON-NLS-1$ + } else { + args.with(urlDecode(kv.substring(0, sep)), + urlDecode(kv.substring(sep + 1))); + } + } + return args; + } + + private static String urlDecode(String text) { + try { + return URLDecoder.decode(text, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + if (DEBUGGING) { + System.err.println("Failed to decode XMind command argument: " //$NON-NLS-1$ + + text); + e.printStackTrace(); + } + return text; + } + } + + private static String urlEncode(String text) { + try { + return URLEncoder.encode(text, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + if (DEBUGGING) { + System.err.println("Failed to encode XMind command argument: " //$NON-NLS-1$ + + text); + e.printStackTrace(); + } + return text; + } + } + + public String toURI() { + return toURI(this); + } + + @Override + public String toString() { + return toURI(); + } + + public static String toURI(ICommand command) { + StringBuffer buf = new StringBuffer(32); + buf.append(XMIND_PROTOCOL); + buf.append('/'); + buf.append('/'); + buf.append(command.getSource()); + + String commandName = command.getCommandName(); + if (commandName != null) { + if (!commandName.startsWith("/")) { //$NON-NLS-1$ + buf.append('/'); + } + buf.append(commandName); + } else { + buf.append('/'); + } + + Attributes arguments = command.getArguments(); + if (arguments != null && !arguments.isEmpty()) { + buf.append('?'); + Iterator keys = arguments.keys(); + boolean firstArgument = true; + while (keys.hasNext()) { + String key = keys.next(); + String value = arguments.get(key); + if (value != null) { + if (!firstArgument) { + buf.append('&'); + } else { + firstArgument = false; + } + buf.append(urlEncode(key)); + buf.append('='); + buf.append(urlEncode(value)); + } + } + } + + String target = command.getTarget(); + if (target != null) { + buf.append('#'); + buf.append(target); + } + return buf.toString(); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/CommandJob.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/CommandJob.java index 5736ab3cc..34fb82a8b 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/CommandJob.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/CommandJob.java @@ -1,46 +1,46 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.jobs.Job; -import org.xmind.core.internal.command.Messages; -import org.xmind.core.internal.command.XMindCommandPlugin; - -public class CommandJob extends Job { - - private ICommand command; - - private IReturnValueConsumer returnValueConsumer; - - public CommandJob(ICommand command, IReturnValueConsumer returnValueConsumer) { - this(Messages.CommandJob_Name, command, returnValueConsumer); - } - - public CommandJob(String name, ICommand command, - IReturnValueConsumer returnValueConsumer) { - super(name); - Assert.isNotNull(command); - this.command = command; - this.returnValueConsumer = returnValueConsumer; - } - - protected IStatus run(IProgressMonitor monitor) { - return XMindCommandPlugin.getDefault().getCommandService() - .execute(monitor, command, returnValueConsumer); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; +import org.xmind.core.internal.command.Messages; +import org.xmind.core.internal.command.XMindCommandPlugin; + +public class CommandJob extends Job { + + private ICommand command; + + private IReturnValueConsumer returnValueConsumer; + + public CommandJob(ICommand command, IReturnValueConsumer returnValueConsumer) { + this(Messages.CommandJob_Name, command, returnValueConsumer); + } + + public CommandJob(String name, ICommand command, + IReturnValueConsumer returnValueConsumer) { + super(name); + Assert.isNotNull(command); + this.command = command; + this.returnValueConsumer = returnValueConsumer; + } + + protected IStatus run(IProgressMonitor monitor) { + return XMindCommandPlugin.getDefault().getCommandService() + .execute(monitor, command, returnValueConsumer); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommand.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommand.java index 7a094adde..84141fd64 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommand.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommand.java @@ -1,97 +1,97 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import org.xmind.core.command.arguments.Attributes; -import org.xmind.core.command.binary.IBinaryEntry; -import org.xmind.core.command.binary.IBinaryStore; - -/** - * - * @author Frank Shaka <frank@xmind.net> - */ -public interface ICommand { - - /** - * Gets the command name. May be emtpy string. Never be null. - *

- * For example, if the command was requested from a URI, the command name is - * the path portion of the URI, with heading/trailing slashes trimmed. - *

- * - * @return the name of the command - */ - String getCommandName(); - - /** - * Gets all arguments of this command. - *

- * For example, if the command was requested from a URI, the arguments are - * decoded and parsed from the query portion of the URI by - * 'x-www-form-urlencoded' encoding. If there're duplicated keys, only the - * last value will be kept. - *

- * - * @return all arguments of this command as key-value pairs - */ - Attributes getArguments(); - - /** - * Gets an argument value by a specified key. - * - * @param key - * the key of the value - * @return the value related to the specified key - */ - String getArgument(String key); - - /** - * Gets the name of the authority who issued this request. - *

- * For example, if the command was requested from a URI, the source name is - * the host name portion of the URI. - *

- * - * @return the source name of this command - */ - String getSource(); - - /** - * Gets the target of this command. - *

- * For example, if the command was requested from a URI, the target name is - * the fragment portion of the URI. - *

- * - * @return the target of this command - */ - String getTarget(); - - /** - * Gets all the associated files in 'entryName - absolutePath' pairs. - * - * @return all the associated files - */ - IBinaryStore getBinaryStore(); - - /** - * Gets a specified file path using its entry name. - * - * @param entryName - * the name of required file entry - * @return the path of the file specified by the entry name - */ - IBinaryEntry getBinaryEntry(String entryName); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import org.xmind.core.command.arguments.Attributes; +import org.xmind.core.command.binary.IBinaryEntry; +import org.xmind.core.command.binary.IBinaryStore; + +/** + * + * @author Frank Shaka <frank@xmind.net> + */ +public interface ICommand { + + /** + * Gets the command name. May be emtpy string. Never be null. + *

+ * For example, if the command was requested from a URI, the command name is + * the path portion of the URI, with heading/trailing slashes trimmed. + *

+ * + * @return the name of the command + */ + String getCommandName(); + + /** + * Gets all arguments of this command. + *

+ * For example, if the command was requested from a URI, the arguments are + * decoded and parsed from the query portion of the URI by + * 'x-www-form-urlencoded' encoding. If there're duplicated keys, only the + * last value will be kept. + *

+ * + * @return all arguments of this command as key-value pairs + */ + Attributes getArguments(); + + /** + * Gets an argument value by a specified key. + * + * @param key + * the key of the value + * @return the value related to the specified key + */ + String getArgument(String key); + + /** + * Gets the name of the authority who issued this request. + *

+ * For example, if the command was requested from a URI, the source name is + * the host name portion of the URI. + *

+ * + * @return the source name of this command + */ + String getSource(); + + /** + * Gets the target of this command. + *

+ * For example, if the command was requested from a URI, the target name is + * the fragment portion of the URI. + *

+ * + * @return the target of this command + */ + String getTarget(); + + /** + * Gets all the associated files in 'entryName - absolutePath' pairs. + * + * @return all the associated files + */ + IBinaryStore getBinaryStore(); + + /** + * Gets a specified file path using its entry name. + * + * @param entryName + * the name of required file entry + * @return the path of the file specified by the entry name + */ + IBinaryEntry getBinaryEntry(String entryName); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandHandler.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandHandler.java index 5c45a4f17..7b0db9635 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandHandler.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandHandler.java @@ -1,49 +1,49 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A command handler executes a command. - * - * @author Frank Shaka - */ -public interface ICommandHandler { - - /** - * Executes the given command. This method will be called by - * {@link ICommandService}. - * - *

- * Note that null should only be returned if the command is not - * recognized. A non-null value is required if the execution - * has been finished. - *

- * - * @param monitor - * the progress monitor - * @param command - * the command to handle - * @param matches - * the matching groups matched against the command name pattern - * @return the return value, e.g. a normal - * {@link org.eclipse.core.runtime.Status}, a {@link ReturnValue} - * with additional information, or null indicating that - * the command is not recognized - */ - IStatus execute(IProgressMonitor monitor, ICommand command, String[] matches); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A command handler executes a command. + * + * @author Frank Shaka + */ +public interface ICommandHandler { + + /** + * Executes the given command. This method will be called by + * {@link ICommandService}. + * + *

+ * Note that null should only be returned if the command is not + * recognized. A non-null value is required if the execution + * has been finished. + *

+ * + * @param monitor + * the progress monitor + * @param command + * the command to handle + * @param matches + * the matching groups matched against the command name pattern + * @return the return value, e.g. a normal + * {@link org.eclipse.core.runtime.Status}, a {@link ReturnValue} + * with additional information, or null indicating that + * the command is not recognized + */ + IStatus execute(IProgressMonitor monitor, ICommand command, String[] matches); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandService.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandService.java index b29347f6a..a7c3d8718 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandService.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/ICommandService.java @@ -1,110 +1,110 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.osgi.util.tracker.ServiceTracker; - -/** - * The command handling service. The service will look up registered command - * handlers and delegate the execution of the command to the best matched - * command handler. - * - *

- * Note that ICommandHandler and IReturnValueConsumer - * must take the responsibility to stop execution when the cancellation of the - * given progress monitor is detected. - *

- * - *

- * To register a command handler, extend the - * org.xmind.core.command.handlers extension point. - *

- * - *

- * This service is registered as an OSGi service, so it can be retrieved via - * {@link ServiceTracker}. Example: - * - *

- * ServiceTracker commandServiceTracker;
- * 
- * public void start(BundleContext bundleContext) throws Exception {
- *     commandServiceTracker = new ServiceTracker(bundleContext,
- *             ICommandService.class.getName(), null);
- *     commandServiceTracker.open();
- * }
- * 
- * public void stop(BundleContext bundleContext) throws Exception {
- *     if (commandServiceTracker != null) {
- *         commandServiceTracker.close();
- *         commandServiceTracker = null;
- *     }
- * }
- * 
- * public ICommandService getCommandService() {
- *     if (commandServiceTracker != null) {
- *         return (ICommandService) commandServiceTracker.getService();
- *     }
- *     return null;
- * }
- * 
- * - *

- * - * @author Frank Shaka - * @since 3.4.0 - * @see ICommandHandler - */ -public interface ICommandService { - - /** - * Integer constant indicating that no handlers are available for executing - * a command. Value is 10001. Used as the 'code' of a return - * value with {@link IStatus#WARNING} severity. - */ - int CODE_NO_HANDLERS = 10001; - - /** - * Integer constant indicating that a command is not handled by any of the - * handlers. Value is 10002. Used as the 'code' of a return - * value with {@link IStatus#WARNING} severity. - */ - int CODE_NOT_HANDLED = 10002; - - /** - * Executes a command synchronously. This method may take a long time to - * finish and will block the current thread, so it is recommended to run it - * in a separate thread of an {@link org.eclipse.core.runtime.jobs.Job}. - * - *

- * The return value may contain cached resources which is cleaned right - * before the method execute() returns, so the client may want - * to pass in an IReturnValueConsumer to consume the cached - * resources before they are cleaned. - *

- * - * @param monitor - * the progress monitor, or null if the progress - * monitoring is not required - * @param command - * the command to handle - * @param returnValueConsumer - * the return value consumer - * @return the return value, never null - */ - IStatus execute(IProgressMonitor monitor, ICommand command, - IReturnValueConsumer returnValueConsumer); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.osgi.util.tracker.ServiceTracker; + +/** + * The command handling service. The service will look up registered command + * handlers and delegate the execution of the command to the best matched + * command handler. + * + *

+ * Note that ICommandHandler and IReturnValueConsumer + * must take the responsibility to stop execution when the cancellation of the + * given progress monitor is detected. + *

+ * + *

+ * To register a command handler, extend the + * org.xmind.core.command.handlers extension point. + *

+ * + *

+ * This service is registered as an OSGi service, so it can be retrieved via + * {@link ServiceTracker}. Example: + * + *

+ * ServiceTracker commandServiceTracker;
+ * 
+ * public void start(BundleContext bundleContext) throws Exception {
+ *     commandServiceTracker = new ServiceTracker(bundleContext,
+ *             ICommandService.class.getName(), null);
+ *     commandServiceTracker.open();
+ * }
+ * 
+ * public void stop(BundleContext bundleContext) throws Exception {
+ *     if (commandServiceTracker != null) {
+ *         commandServiceTracker.close();
+ *         commandServiceTracker = null;
+ *     }
+ * }
+ * 
+ * public ICommandService getCommandService() {
+ *     if (commandServiceTracker != null) {
+ *         return (ICommandService) commandServiceTracker.getService();
+ *     }
+ *     return null;
+ * }
+ * 
+ * + *

+ * + * @author Frank Shaka + * @since 3.4.0 + * @see ICommandHandler + */ +public interface ICommandService { + + /** + * Integer constant indicating that no handlers are available for executing + * a command. Value is 10001. Used as the 'code' of a return + * value with {@link IStatus#WARNING} severity. + */ + int CODE_NO_HANDLERS = 10001; + + /** + * Integer constant indicating that a command is not handled by any of the + * handlers. Value is 10002. Used as the 'code' of a return + * value with {@link IStatus#WARNING} severity. + */ + int CODE_NOT_HANDLED = 10002; + + /** + * Executes a command synchronously. This method may take a long time to + * finish and will block the current thread, so it is recommended to run it + * in a separate thread of an {@link org.eclipse.core.runtime.jobs.Job}. + * + *

+ * The return value may contain cached resources which is cleaned right + * before the method execute() returns, so the client may want + * to pass in an IReturnValueConsumer to consume the cached + * resources before they are cleaned. + *

+ * + * @param monitor + * the progress monitor, or null if the progress + * monitoring is not required + * @param command + * the command to handle + * @param returnValueConsumer + * the return value consumer + * @return the return value, never null + */ + IStatus execute(IProgressMonitor monitor, ICommand command, + IReturnValueConsumer returnValueConsumer); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/IReturnValueConsumer.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/IReturnValueConsumer.java index 8c06a2769..40b63d572 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/IReturnValueConsumer.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/IReturnValueConsumer.java @@ -1,40 +1,40 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -/** - * A return value consumer. - * - * @author Frank Shaka - */ -public interface IReturnValueConsumer { - - /** - * Consumes the value returned from execution of a command. The return value - * may be a normal {@link org.eclipse.core.runtime.Status} or a - * {@link ReturnValue} instance containing additional information and/or - * cached resources. - * - * @param monitor - * the progress monitor, never null - * @param returnValue - * the return value, never null - * @return a status indicating the consumption of the return value - */ - IStatus consumeReturnValue(IProgressMonitor monitor, IStatus returnValue); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +/** + * A return value consumer. + * + * @author Frank Shaka + */ +public interface IReturnValueConsumer { + + /** + * Consumes the value returned from execution of a command. The return value + * may be a normal {@link org.eclipse.core.runtime.Status} or a + * {@link ReturnValue} instance containing additional information and/or + * cached resources. + * + * @param monitor + * the progress monitor, never null + * @param returnValue + * the return value, never null + * @return a status indicating the consumption of the return value + */ + IStatus consumeReturnValue(IProgressMonitor monitor, IStatus returnValue); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/ReturnValue.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/ReturnValue.java index 7e016e961..1c482ec00 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/ReturnValue.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/ReturnValue.java @@ -1,122 +1,122 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - -import java.util.Arrays; - -import org.eclipse.core.runtime.Status; -import org.xmind.core.command.arguments.Attributes; -import org.xmind.core.command.binary.IBinaryStore; - -public class ReturnValue extends Status { - - private Object value; - - public ReturnValue(String pluginId, Attributes values) { - super(OK, pluginId, null); - this.value = values; - } - - public ReturnValue(String pluginId, String[] values) { - super(OK, pluginId, null); - this.value = values; - } - - public ReturnValue(String pluginId, IBinaryStore files) { - super(OK, pluginId, null); - this.value = files; - } - - public ReturnValue(int severity, String pluginId, int code, String message, - Attributes values) { - super(severity, pluginId, code, message, null); - this.value = values; - } - - public ReturnValue(int severity, String pluginId, int code, String message, - String[] values) { - super(severity, pluginId, code, message, null); - this.value = values; - } - - public ReturnValue(int severity, String pluginId, int code, String message, - IBinaryStore values) { - super(severity, pluginId, code, message, null); - this.value = values; - } - - public Object getValue() { - return value; - } - - public Attributes getAttributes() { - return (Attributes) value; - } - - public String[] getStrings() { - return (String[]) value; - } - - public IBinaryStore getBinaryEntries() { - return (IBinaryStore) value; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("ReturnValue["); //$NON-NLS-1$ - int severity = getSeverity(); - if (severity == OK) { - buf.append("OK"); //$NON-NLS-1$ - } else if (severity == ERROR) { - buf.append("ERROR"); //$NON-NLS-1$ - } else if (severity == WARNING) { - buf.append("WARNING"); //$NON-NLS-1$ - } else if (severity == INFO) { - buf.append("INFO"); //$NON-NLS-1$ - } else if (severity == CANCEL) { - buf.append("CANCEL"); //$NON-NLS-1$ - } else { - buf.append("severity="); //$NON-NLS-1$ - buf.append(severity); - } - buf.append(';'); - buf.append(getCode()); - buf.append(';'); - buf.append(getPlugin()); - String message = getMessage(); - if (message != null && !"".equals(message)) { //$NON-NLS-1$ - buf.append(';'); - buf.append('\''); - buf.append(message); - buf.append('\''); - } - Throwable exception = getException(); - if (exception != null) { - buf.append(";exception="); //$NON-NLS-1$ - buf.append(exception); - } - if (value != null) { - buf.append(";value="); //$NON-NLS-1$ - if (value instanceof String[]) { - buf.append(Arrays.toString((String[]) value)); - } else { - buf.append(value); - } - } - buf.append(']'); - return buf.toString(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + +import java.util.Arrays; + +import org.eclipse.core.runtime.Status; +import org.xmind.core.command.arguments.Attributes; +import org.xmind.core.command.binary.IBinaryStore; + +public class ReturnValue extends Status { + + private Object value; + + public ReturnValue(String pluginId, Attributes values) { + super(OK, pluginId, null); + this.value = values; + } + + public ReturnValue(String pluginId, String[] values) { + super(OK, pluginId, null); + this.value = values; + } + + public ReturnValue(String pluginId, IBinaryStore files) { + super(OK, pluginId, null); + this.value = files; + } + + public ReturnValue(int severity, String pluginId, int code, String message, + Attributes values) { + super(severity, pluginId, code, message, null); + this.value = values; + } + + public ReturnValue(int severity, String pluginId, int code, String message, + String[] values) { + super(severity, pluginId, code, message, null); + this.value = values; + } + + public ReturnValue(int severity, String pluginId, int code, String message, + IBinaryStore values) { + super(severity, pluginId, code, message, null); + this.value = values; + } + + public Object getValue() { + return value; + } + + public Attributes getAttributes() { + return (Attributes) value; + } + + public String[] getStrings() { + return (String[]) value; + } + + public IBinaryStore getBinaryEntries() { + return (IBinaryStore) value; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("ReturnValue["); //$NON-NLS-1$ + int severity = getSeverity(); + if (severity == OK) { + buf.append("OK"); //$NON-NLS-1$ + } else if (severity == ERROR) { + buf.append("ERROR"); //$NON-NLS-1$ + } else if (severity == WARNING) { + buf.append("WARNING"); //$NON-NLS-1$ + } else if (severity == INFO) { + buf.append("INFO"); //$NON-NLS-1$ + } else if (severity == CANCEL) { + buf.append("CANCEL"); //$NON-NLS-1$ + } else { + buf.append("severity="); //$NON-NLS-1$ + buf.append(severity); + } + buf.append(';'); + buf.append(getCode()); + buf.append(';'); + buf.append(getPlugin()); + String message = getMessage(); + if (message != null && !"".equals(message)) { //$NON-NLS-1$ + buf.append(';'); + buf.append('\''); + buf.append(message); + buf.append('\''); + } + Throwable exception = getException(); + if (exception != null) { + buf.append(";exception="); //$NON-NLS-1$ + buf.append(exception); + } + if (value != null) { + buf.append(";value="); //$NON-NLS-1$ + if (value instanceof String[]) { + buf.append(Arrays.toString((String[]) value)); + } else { + buf.append(value); + } + } + buf.append(']'); + return buf.toString(); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/XMindCommandCenter.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/XMindCommandCenter.java index f59a02d1f..764286076 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/XMindCommandCenter.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/XMindCommandCenter.java @@ -1,49 +1,49 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command; - - -/** - * - * @author frankshaka - * @deprecated Use {@link ICommandService} instead. - */ -public class XMindCommandCenter { - -// private XMindCommandCenter() { -// } -// -// public static IStatus execute(ICommand command) { -// return XMindCommandSupport.getInstance().executeCommand(command); -// } -// -// public static IStatus execute(String uri) { -// Command command = Command.parseURI(uri); -// if (command == null) -// return null; -// return XMindCommandSupport.getInstance().executeCommand(command); -// } -// -// public static IStatus execute(String uri, IBinaryStore files) { -// Command command = Command.parseURI(uri, files); -// if (command == null) -// return null; -// return XMindCommandSupport.getInstance().executeCommand(command); -// } -// -// public static boolean canExecute(String uri) { -// return uri != null && uri.startsWith(Command.XMIND_PROTOCOL); -// } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command; + + +/** + * + * @author frankshaka + * @deprecated Use {@link ICommandService} instead. + */ +public class XMindCommandCenter { + +// private XMindCommandCenter() { +// } +// +// public static IStatus execute(ICommand command) { +// return XMindCommandSupport.getInstance().executeCommand(command); +// } +// +// public static IStatus execute(String uri) { +// Command command = Command.parseURI(uri); +// if (command == null) +// return null; +// return XMindCommandSupport.getInstance().executeCommand(command); +// } +// +// public static IStatus execute(String uri, IBinaryStore files) { +// Command command = Command.parseURI(uri, files); +// if (command == null) +// return null; +// return XMindCommandSupport.getInstance().executeCommand(command); +// } +// +// public static boolean canExecute(String uri) { +// return uri != null && uri.startsWith(Command.XMIND_PROTOCOL); +// } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/ArrayMapper.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/ArrayMapper.java index 01a0b291a..02ea5a41f 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/ArrayMapper.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/ArrayMapper.java @@ -1,283 +1,283 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.arguments; - -import java.util.Map; - -import org.eclipse.core.runtime.Assert; - -/** - * This class provides a mechanism to normalize indexed objects and their - * properties into key-value pairs. - * - *

- * The keys look like "prefix-index" or - * "prefix-index-subkey", where prefix is an - * identifier to protect all objects under a same group, index is - * the index of the object, subkey is for storing properties of the - * object. - *

- * - *

- * The "prefix-index" key is used to map an object alone, while the - * "prefix-index-subkey" key is used to map a property of an - * object. - *

- * - *

- * To write objects into a map, iterate over the collection of objects and set - * each object/property into the ArrayMapper. To read objects from - * a map, iterate over the ArrayMapper and get each object/property - * from it. - *

- * - *

- * Note that the method next() should be called at the - * beginning of each iteration step to make the index cursor point to the next - * object. - *

- * - *

- * Also note that the method setSize() should be called - * after writing objects into the map is finished, otherwise the map will be - * unable to read objects from. - *

- * - *

- * Samples: - * - *

- * Map writeElementsIntoMap(Collection elements) {
- *     Map data = new HashMap();
- *     ArrayMapper writer = new ArrayMapper(data, "elements");
- *     Iterator it = elements.iterator();
- *     while (it.hasNext()) {
- *         Element element = (Element) it.next();
- *         writer.next();
- *         writer.set("content", element.getContent());
- *         writer.set("time", element.getTime());
- *     }
- *     writer.setSize(); //DO NOT FORGET THIS LINE!
- *     return data;
- * }
- * 
- * Collection readElementsFromMap(Map data) {
- *     Collection elements = new ArrayList();
- *     ArrayMapper reader = new ArrayMapper(data, "elements");
- *     while (reader.hasNext()) {
- *         reader.next();
- *         Element element = new Element();
- *         element.setContent(reader.get("content"));
- *         element.setTime(reader.get("time"));
- *         elements.add(element);
- *     }
- *     return elements;
- * }
- * 
- * - *

- * - * @author Frank Shaka - * - */ -public class ArrayMapper { - - @SuppressWarnings("rawtypes") - private Map map; - - private String prefix; - - private int index = -1; - - /** - * Constructs an ArrayMapper instance using the map and prefix. - * - * @param map - * the map to store/load objects - * @param prefix - * the key prefix of all objects to map, while null - * or an empty string indicates no prefix - */ - @SuppressWarnings("rawtypes") - public ArrayMapper(Map map, String prefix) { - Assert.isNotNull(map); - this.map = map; - this.prefix = prefix; - } - - /** - * Checks if there are more objects to read. - * - * @return true if there are more objects to read, or - * false otherwise - */ - public boolean hasNext() { - return index + 1 < getSize(); - } - - /** - * Moves the index cursor forward to next object. - *

- * NOTE: This method should be called at the beginning of each - * iteration step. - *

- */ - public void next() { - index++; - } - - /** - * Manually sets the index cursor to a specific position. This method is not - * recommended unless you really want to roll back or skip forward. To move - * the index cursor one step forward, use next() instead. - * - *

- * Note that no IndexOutOfBoundsException will be raised if the - * index is set to an illegal value, so it's the client's responsibility to - * set a proper value to prevent reading/writing failure. - *

- * - * @param index - * the new position of the index cursor - */ - public void setIndex(int index) { - this.index = index; - } - - /** - * Puts the object at the current index into the map with the - * "prefix-index" key. - * - * @param value - * the object to put - */ - @SuppressWarnings("unchecked") - public void set(Object value) { - map.put(getKey(null), value); - } - - /** - * Puts the property of the object at the current index into the map with - * the "prefix-index-subkey" key. - * - * @param subkey - * the sub-key of this property - * @param value - * the property to put - */ - @SuppressWarnings("unchecked") - public void set(String subkey, Object value) { - map.put(getKey(subkey), value); - } - - /** - * Retrieves the object at the current index from the map specified by the - * "prefix-index" key. - * - * @return the object at the current index - */ - public Object get() { - return map.get(getKey(null)); - } - - /** - * Retrieves the property of the object at the current index from map - * specified by the "prefix-index-subkey" key. - * - * @param subkey - * the sub-key of this property - * @return the disired property of the object at the current index - */ - public Object get(String subkey) { - return map.get(getKey(subkey)); - } - - /** - * Generates a key using the prefix, the current index and the sub-key. - * - * @param subkey - * the sub-key to use, or null to indicate no - * sub-key - * @return "prefix-index-subkey" if prefix and subkey are - * non-empty, "prefix-index" if prefix is non-empty and - * subkey is empty, "index-subkey" if prefix is empty - * and subkey is non-empty, or "index" is prefix and - * subkey are empty - */ - private String getKey(String subkey) { - if (prefix == null || "".equals(prefix)) //$NON-NLS-1$ - return subkey == null || "".equals(subkey) //$NON-NLS-1$ - ? String.valueOf(index) : String.valueOf(index) + "-" + subkey; //$NON-NLS-1$ - return subkey == null || "".equals(subkey) //$NON-NLS-1$ - ? prefix + "-" + index //$NON-NLS-1$ - : prefix + "-" + index + "-" + subkey; //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Generates the key for the size value. - * - * @return "prefix-size" if prefix is non-empty, or - * "size" otherwise - */ - private String getSizeKey() { - if (prefix == null || "".equals(prefix)) { //$NON-NLS-1$ - return "size"; //$NON-NLS-1$ - } else { - return prefix + "-size"; //$NON-NLS-1$ - } - } - - /** - * Stores the current size into the map. - *

- * NOTE: This method should be called after all objects are written - * into the map. Failing to do so will lead to unability to read objects - * from the map. - *

- */ - public void setSize() { - setSize(index + 1); - } - - /** - * Manually stores the size to a specific value. This method is not - * recommended unless you have manually changed the index cursor using - * setIndex(int), otherwise use setSize() instead. - * - * @param size - * the new size value - */ - @SuppressWarnings("unchecked") - public void setSize(int size) { - map.put(getSizeKey(), String.valueOf(size)); - } - - /** - * Gets the number of the objects stored in the map. - * - * @return the number of all objects, or 0 if retrieving is - * failed. - */ - public int getSize() { - Object size = map.get(getSizeKey()); - if (size == null || !(size instanceof String)) - return 0; - try { - return Integer.parseInt((String) size, 10); - } catch (NumberFormatException e) { - return 0; - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.arguments; + +import java.util.Map; + +import org.eclipse.core.runtime.Assert; + +/** + * This class provides a mechanism to normalize indexed objects and their + * properties into key-value pairs. + * + *

+ * The keys look like "prefix-index" or + * "prefix-index-subkey", where prefix is an + * identifier to protect all objects under a same group, index is + * the index of the object, subkey is for storing properties of the + * object. + *

+ * + *

+ * The "prefix-index" key is used to map an object alone, while the + * "prefix-index-subkey" key is used to map a property of an + * object. + *

+ * + *

+ * To write objects into a map, iterate over the collection of objects and set + * each object/property into the ArrayMapper. To read objects from + * a map, iterate over the ArrayMapper and get each object/property + * from it. + *

+ * + *

+ * Note that the method next() should be called at the + * beginning of each iteration step to make the index cursor point to the next + * object. + *

+ * + *

+ * Also note that the method setSize() should be called + * after writing objects into the map is finished, otherwise the map will be + * unable to read objects from. + *

+ * + *

+ * Samples: + * + *

+ * Map writeElementsIntoMap(Collection elements) {
+ *     Map data = new HashMap();
+ *     ArrayMapper writer = new ArrayMapper(data, "elements");
+ *     Iterator it = elements.iterator();
+ *     while (it.hasNext()) {
+ *         Element element = (Element) it.next();
+ *         writer.next();
+ *         writer.set("content", element.getContent());
+ *         writer.set("time", element.getTime());
+ *     }
+ *     writer.setSize(); //DO NOT FORGET THIS LINE!
+ *     return data;
+ * }
+ * 
+ * Collection readElementsFromMap(Map data) {
+ *     Collection elements = new ArrayList();
+ *     ArrayMapper reader = new ArrayMapper(data, "elements");
+ *     while (reader.hasNext()) {
+ *         reader.next();
+ *         Element element = new Element();
+ *         element.setContent(reader.get("content"));
+ *         element.setTime(reader.get("time"));
+ *         elements.add(element);
+ *     }
+ *     return elements;
+ * }
+ * 
+ * + *

+ * + * @author Frank Shaka + * + */ +public class ArrayMapper { + + @SuppressWarnings("rawtypes") + private Map map; + + private String prefix; + + private int index = -1; + + /** + * Constructs an ArrayMapper instance using the map and prefix. + * + * @param map + * the map to store/load objects + * @param prefix + * the key prefix of all objects to map, while null + * or an empty string indicates no prefix + */ + @SuppressWarnings("rawtypes") + public ArrayMapper(Map map, String prefix) { + Assert.isNotNull(map); + this.map = map; + this.prefix = prefix; + } + + /** + * Checks if there are more objects to read. + * + * @return true if there are more objects to read, or + * false otherwise + */ + public boolean hasNext() { + return index + 1 < getSize(); + } + + /** + * Moves the index cursor forward to next object. + *

+ * NOTE: This method should be called at the beginning of each + * iteration step. + *

+ */ + public void next() { + index++; + } + + /** + * Manually sets the index cursor to a specific position. This method is not + * recommended unless you really want to roll back or skip forward. To move + * the index cursor one step forward, use next() instead. + * + *

+ * Note that no IndexOutOfBoundsException will be raised if the + * index is set to an illegal value, so it's the client's responsibility to + * set a proper value to prevent reading/writing failure. + *

+ * + * @param index + * the new position of the index cursor + */ + public void setIndex(int index) { + this.index = index; + } + + /** + * Puts the object at the current index into the map with the + * "prefix-index" key. + * + * @param value + * the object to put + */ + @SuppressWarnings("unchecked") + public void set(Object value) { + map.put(getKey(null), value); + } + + /** + * Puts the property of the object at the current index into the map with + * the "prefix-index-subkey" key. + * + * @param subkey + * the sub-key of this property + * @param value + * the property to put + */ + @SuppressWarnings("unchecked") + public void set(String subkey, Object value) { + map.put(getKey(subkey), value); + } + + /** + * Retrieves the object at the current index from the map specified by the + * "prefix-index" key. + * + * @return the object at the current index + */ + public Object get() { + return map.get(getKey(null)); + } + + /** + * Retrieves the property of the object at the current index from map + * specified by the "prefix-index-subkey" key. + * + * @param subkey + * the sub-key of this property + * @return the disired property of the object at the current index + */ + public Object get(String subkey) { + return map.get(getKey(subkey)); + } + + /** + * Generates a key using the prefix, the current index and the sub-key. + * + * @param subkey + * the sub-key to use, or null to indicate no + * sub-key + * @return "prefix-index-subkey" if prefix and subkey are + * non-empty, "prefix-index" if prefix is non-empty and + * subkey is empty, "index-subkey" if prefix is empty + * and subkey is non-empty, or "index" is prefix and + * subkey are empty + */ + private String getKey(String subkey) { + if (prefix == null || "".equals(prefix)) //$NON-NLS-1$ + return subkey == null || "".equals(subkey) //$NON-NLS-1$ + ? String.valueOf(index) : String.valueOf(index) + "-" + subkey; //$NON-NLS-1$ + return subkey == null || "".equals(subkey) //$NON-NLS-1$ + ? prefix + "-" + index //$NON-NLS-1$ + : prefix + "-" + index + "-" + subkey; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Generates the key for the size value. + * + * @return "prefix-size" if prefix is non-empty, or + * "size" otherwise + */ + private String getSizeKey() { + if (prefix == null || "".equals(prefix)) { //$NON-NLS-1$ + return "size"; //$NON-NLS-1$ + } else { + return prefix + "-size"; //$NON-NLS-1$ + } + } + + /** + * Stores the current size into the map. + *

+ * NOTE: This method should be called after all objects are written + * into the map. Failing to do so will lead to unability to read objects + * from the map. + *

+ */ + public void setSize() { + setSize(index + 1); + } + + /** + * Manually stores the size to a specific value. This method is not + * recommended unless you have manually changed the index cursor using + * setIndex(int), otherwise use setSize() instead. + * + * @param size + * the new size value + */ + @SuppressWarnings("unchecked") + public void setSize(int size) { + map.put(getSizeKey(), String.valueOf(size)); + } + + /** + * Gets the number of the objects stored in the map. + * + * @return the number of all objects, or 0 if retrieving is + * failed. + */ + public int getSize() { + Object size = map.get(getSizeKey()); + if (size == null || !(size instanceof String)) + return 0; + try { + return Integer.parseInt((String) size, 10); + } catch (NumberFormatException e) { + return 0; + } + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/Attributes.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/Attributes.java index b389e1a77..57f8eb73e 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/Attributes.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/arguments/Attributes.java @@ -1,163 +1,163 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.arguments; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -public class Attributes { - - private Map map = new HashMap(); - - public Attributes() { - } - - public Attributes(Map initials) { - for (Object key : initials.keySet()) { - this.map.put((String) key, (String) initials.get(key)); - } - } - - public Attributes with(String key, String value) { - map.put(key, value); - return this; - } - - public Attributes with(String key, int value) { - map.put(key, String.valueOf(value)); - return this; - } - - public Attributes with(String key, long value) { - map.put(key, String.valueOf(value)); - return this; - } - - public Attributes with(String key, boolean value) { - map.put(key, String.valueOf(value)); - return this; - } - - public Attributes with(String key, float value) { - map.put(key, String.valueOf(value)); - return this; - } - - public Attributes with(String key, double value) { - map.put(key, String.valueOf(value)); - return this; - } - - public String get(String key) { - return map.get(key); - } - - public String getString(String key, String defaultValue) { - String value = map.get(key); - return value == null ? defaultValue : value; - } - - public int getInt(String key, int defaultValue) { - String value = map.get(key); - if (value == null || "".equals(value)) //$NON-NLS-1$ - return defaultValue; - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public long getLong(String key, long defaultValue) { - String value = map.get(key); - if (value == null || "".equals(value)) //$NON-NLS-1$ - return defaultValue; - try { - return Long.parseLong(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public boolean getBoolean(String key, boolean defaultValue) { - String value = map.get(key); - if (value == null || "".equals(value)) //$NON-NLS-1$ - return defaultValue; - if ("true".equalsIgnoreCase(value)) //$NON-NLS-1$ - return true; - if ("false".equalsIgnoreCase(value)) //$NON-NLS-1$ - return false; - return defaultValue; - } - - public float getFloat(String key, float defaultValue) { - String value = map.get(key); - if (value == null || "".equals(value)) //$NON-NLS-1$ - return defaultValue; - try { - return Float.parseFloat(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public double getDouble(String key, double defaultValue) { - String value = map.get(key); - if (value == null || "".equals(value)) //$NON-NLS-1$ - return defaultValue; - try { - return Double.parseDouble(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public Iterator keys() { - return map.keySet().iterator(); - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - public int size() { - return map.size(); - } - - public Map getRawMap() { - return map; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof Attributes)) - return false; - Attributes that = (Attributes) obj; - return this.map.equals(that.map); - } - - @Override - public int hashCode() { - return map.hashCode(); - } - - @Override - public String toString() { - return "Attributes" + map.toString(); //$NON-NLS-1$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.arguments; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class Attributes { + + private Map map = new HashMap(); + + public Attributes() { + } + + public Attributes(Map initials) { + for (Object key : initials.keySet()) { + this.map.put((String) key, (String) initials.get(key)); + } + } + + public Attributes with(String key, String value) { + map.put(key, value); + return this; + } + + public Attributes with(String key, int value) { + map.put(key, String.valueOf(value)); + return this; + } + + public Attributes with(String key, long value) { + map.put(key, String.valueOf(value)); + return this; + } + + public Attributes with(String key, boolean value) { + map.put(key, String.valueOf(value)); + return this; + } + + public Attributes with(String key, float value) { + map.put(key, String.valueOf(value)); + return this; + } + + public Attributes with(String key, double value) { + map.put(key, String.valueOf(value)); + return this; + } + + public String get(String key) { + return map.get(key); + } + + public String getString(String key, String defaultValue) { + String value = map.get(key); + return value == null ? defaultValue : value; + } + + public int getInt(String key, int defaultValue) { + String value = map.get(key); + if (value == null || "".equals(value)) //$NON-NLS-1$ + return defaultValue; + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public long getLong(String key, long defaultValue) { + String value = map.get(key); + if (value == null || "".equals(value)) //$NON-NLS-1$ + return defaultValue; + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public boolean getBoolean(String key, boolean defaultValue) { + String value = map.get(key); + if (value == null || "".equals(value)) //$NON-NLS-1$ + return defaultValue; + if ("true".equalsIgnoreCase(value)) //$NON-NLS-1$ + return true; + if ("false".equalsIgnoreCase(value)) //$NON-NLS-1$ + return false; + return defaultValue; + } + + public float getFloat(String key, float defaultValue) { + String value = map.get(key); + if (value == null || "".equals(value)) //$NON-NLS-1$ + return defaultValue; + try { + return Float.parseFloat(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public double getDouble(String key, double defaultValue) { + String value = map.get(key); + if (value == null || "".equals(value)) //$NON-NLS-1$ + return defaultValue; + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public Iterator keys() { + return map.keySet().iterator(); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public int size() { + return map.size(); + } + + public Map getRawMap() { + return map; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof Attributes)) + return false; + Attributes that = (Attributes) obj; + return this.map.equals(that.map); + } + + @Override + public int hashCode() { + return map.hashCode(); + } + + @Override + public String toString() { + return "Attributes" + map.toString(); //$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/BinaryStore.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/BinaryStore.java index d9277b78e..28c847d26 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/BinaryStore.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/BinaryStore.java @@ -1,216 +1,216 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.xmind.core.internal.command.BinaryUtil; -import org.xmind.core.internal.command.XMindCommandPlugin; - -public class BinaryStore implements IBinaryStore { - - private Map entries = new HashMap(); - - private List entryNames = new ArrayList(); - - private File root; - - private byte[] buffer = new byte[4096]; - - private int randomIndex = 1; - - public BinaryStore(File root) { - this.root = root; - } - - public BinaryStore(boolean useLocalFileCache) { - if (useLocalFileCache) { - File cacheDir = XMindCommandPlugin.getDefault() - .getBinaryCacheLocation(); - String rootName = String.format("%s-%s", //$NON-NLS-1$ - String.valueOf(System.currentTimeMillis()), String - .valueOf(new Random(System.currentTimeMillis()) - .nextInt())); - this.root = new File(cacheDir, rootName); - } else { - this.root = null; - } - } - - public BinaryStore() { - this(true); - } - - public synchronized Iterator entryNames() { - return this.entryNames.iterator(); - } - - public synchronized boolean isEmpty() { - return this.entries.isEmpty(); - } - - public synchronized int size() { - return this.entries.size(); - } - - public synchronized IBinaryEntry getEntry(String entryName) { - return this.entries.get(entryName); - } - - public synchronized boolean hasEntry(String entryName) { - return this.entries.containsKey(entryName); - } - - public synchronized void clear() { - Object[] oldEntries = this.entries.values().toArray(); - this.entries.clear(); - this.entryNames.clear(); - for (int i = 0; i < oldEntries.length; i++) { - ((IBinaryEntry) oldEntries[i]).dispose(); - } - if (this.root != null) { - BinaryUtil.delete(this.root); - } - } - - public synchronized boolean removeEntry(String entryName) { - IBinaryEntry entry = this.entries.remove(entryName); - if (entry != null) { - this.entryNames.remove(entryName); - entry.dispose(); - } - return entry != null; - } - - public synchronized INamedEntry addEntry(IProgressMonitor monitor, - InputStream source) throws IOException, InterruptedException { - String entryName = generateRandomEntryName(); - IBinaryEntry realEntry = createEntry(monitor, entryName, source); - NamedEntry entry = new NamedEntry(entryName, realEntry); - addEntry(entryName, entry); - return entry; - } - - protected String generateRandomEntryName() { - String entryName = Long.toHexString(System.currentTimeMillis()) + "-" //$NON-NLS-1$ - + (randomIndex++) + "-" //$NON-NLS-1$ - + Integer.toHexString(new Random().nextInt()) + ".tmp"; //$NON-NLS-1$ - return entryName; - } - - public synchronized IBinaryEntry addEntry(IProgressMonitor monitor, - String entryName, InputStream source) throws IOException, - InterruptedException { - IBinaryEntry entry = createEntry(monitor, entryName, source); - addEntry(entryName, entry); - return entry; - } - - public synchronized void addEntry(String entryName, IBinaryEntry entry) { - removeEntry(entryName); - this.entries.put(entryName, entry); - this.entryNames.add(entryName); - } - - protected IBinaryEntry createEntry(IProgressMonitor monitor, - String entryName, InputStream source) throws IOException, - InterruptedException { - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - if (this.root != null) { - this.root.mkdirs(); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - - if (this.root != null && this.root.isDirectory()) { - if (entryName.endsWith("/")) { //$NON-NLS-1$ - File file = new File(this.root, entryName.substring(0, - entryName.length() - 1)); - if (monitor.isCanceled()) - throw new InterruptedException(); - file.mkdirs(); - return IBinaryEntry.NULL; - } else { - File file = new File(this.root, entryName); - file.getParentFile().mkdirs(); - if (monitor.isCanceled()) - throw new InterruptedException(); - try { - OutputStream fout = new FileOutputStream(file); - try { - int read; - while ((read = source.read(buffer)) > 0) { - if (monitor.isCanceled()) - throw new InterruptedException(); - fout.write(buffer, 0, read); - } - } finally { - fout.close(); - } - } finally { - source.close(); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - return new FileEntry(file); - } - } else { - if (entryName.endsWith("/")) { //$NON-NLS-1$ - return IBinaryEntry.NULL; - } else { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(4096); - try { - int read; - while ((read = source.read(buffer)) > 0) { - if (monitor.isCanceled()) - throw new InterruptedException(); - out.write(buffer, 0, read); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - return new ByteArrayEntry(out.toByteArray()); - } finally { - out.close(); - } - } finally { - source.close(); - } - } - } - } - - @Override - public String toString() { - return entries.toString(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.xmind.core.internal.command.BinaryUtil; +import org.xmind.core.internal.command.XMindCommandPlugin; + +public class BinaryStore implements IBinaryStore { + + private Map entries = new HashMap(); + + private List entryNames = new ArrayList(); + + private File root; + + private byte[] buffer = new byte[4096]; + + private int randomIndex = 1; + + public BinaryStore(File root) { + this.root = root; + } + + public BinaryStore(boolean useLocalFileCache) { + if (useLocalFileCache) { + File cacheDir = XMindCommandPlugin.getDefault() + .getBinaryCacheLocation(); + String rootName = String.format("%s-%s", //$NON-NLS-1$ + String.valueOf(System.currentTimeMillis()), String + .valueOf(new Random(System.currentTimeMillis()) + .nextInt())); + this.root = new File(cacheDir, rootName); + } else { + this.root = null; + } + } + + public BinaryStore() { + this(true); + } + + public synchronized Iterator entryNames() { + return this.entryNames.iterator(); + } + + public synchronized boolean isEmpty() { + return this.entries.isEmpty(); + } + + public synchronized int size() { + return this.entries.size(); + } + + public synchronized IBinaryEntry getEntry(String entryName) { + return this.entries.get(entryName); + } + + public synchronized boolean hasEntry(String entryName) { + return this.entries.containsKey(entryName); + } + + public synchronized void clear() { + Object[] oldEntries = this.entries.values().toArray(); + this.entries.clear(); + this.entryNames.clear(); + for (int i = 0; i < oldEntries.length; i++) { + ((IBinaryEntry) oldEntries[i]).dispose(); + } + if (this.root != null) { + BinaryUtil.delete(this.root); + } + } + + public synchronized boolean removeEntry(String entryName) { + IBinaryEntry entry = this.entries.remove(entryName); + if (entry != null) { + this.entryNames.remove(entryName); + entry.dispose(); + } + return entry != null; + } + + public synchronized INamedEntry addEntry(IProgressMonitor monitor, + InputStream source) throws IOException, InterruptedException { + String entryName = generateRandomEntryName(); + IBinaryEntry realEntry = createEntry(monitor, entryName, source); + NamedEntry entry = new NamedEntry(entryName, realEntry); + addEntry(entryName, entry); + return entry; + } + + protected String generateRandomEntryName() { + String entryName = Long.toHexString(System.currentTimeMillis()) + "-" //$NON-NLS-1$ + + (randomIndex++) + "-" //$NON-NLS-1$ + + Integer.toHexString(new Random().nextInt()) + ".tmp"; //$NON-NLS-1$ + return entryName; + } + + public synchronized IBinaryEntry addEntry(IProgressMonitor monitor, + String entryName, InputStream source) throws IOException, + InterruptedException { + IBinaryEntry entry = createEntry(monitor, entryName, source); + addEntry(entryName, entry); + return entry; + } + + public synchronized void addEntry(String entryName, IBinaryEntry entry) { + removeEntry(entryName); + this.entries.put(entryName, entry); + this.entryNames.add(entryName); + } + + protected IBinaryEntry createEntry(IProgressMonitor monitor, + String entryName, InputStream source) throws IOException, + InterruptedException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + if (this.root != null) { + this.root.mkdirs(); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + + if (this.root != null && this.root.isDirectory()) { + if (entryName.endsWith("/")) { //$NON-NLS-1$ + File file = new File(this.root, entryName.substring(0, + entryName.length() - 1)); + if (monitor.isCanceled()) + throw new InterruptedException(); + file.mkdirs(); + return IBinaryEntry.NULL; + } else { + File file = new File(this.root, entryName); + file.getParentFile().mkdirs(); + if (monitor.isCanceled()) + throw new InterruptedException(); + try { + OutputStream fout = new FileOutputStream(file); + try { + int read; + while ((read = source.read(buffer)) > 0) { + if (monitor.isCanceled()) + throw new InterruptedException(); + fout.write(buffer, 0, read); + } + } finally { + fout.close(); + } + } finally { + source.close(); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + return new FileEntry(file); + } + } else { + if (entryName.endsWith("/")) { //$NON-NLS-1$ + return IBinaryEntry.NULL; + } else { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + try { + int read; + while ((read = source.read(buffer)) > 0) { + if (monitor.isCanceled()) + throw new InterruptedException(); + out.write(buffer, 0, read); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + return new ByteArrayEntry(out.toByteArray()); + } finally { + out.close(); + } + } finally { + source.close(); + } + } + } + } + + @Override + public String toString() { + return entries.toString(); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/ByteArrayEntry.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/ByteArrayEntry.java index 342dbaf12..cb2f956c6 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/ByteArrayEntry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/ByteArrayEntry.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -public class ByteArrayEntry implements IBinaryEntry { - - private byte[] bytes; - - public ByteArrayEntry(byte[] bytes) { - this.bytes = bytes; - } - - public byte[] getBytes() { - return bytes; - } - - public InputStream openInputStream() throws IOException { - if (this.bytes == null) - throw new IOException("Byte array entry already disposed."); //$NON-NLS-1$ - return new ByteArrayInputStream(bytes); - } - - /** - * Release byte array. - */ - public void dispose() { - this.bytes = null; - } - - @Override - public String toString() { - return "[" + bytes.length + " bytes]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ByteArrayEntry implements IBinaryEntry { + + private byte[] bytes; + + public ByteArrayEntry(byte[] bytes) { + this.bytes = bytes; + } + + public byte[] getBytes() { + return bytes; + } + + public InputStream openInputStream() throws IOException { + if (this.bytes == null) + throw new IOException("Byte array entry already disposed."); //$NON-NLS-1$ + return new ByteArrayInputStream(bytes); + } + + /** + * Release byte array. + */ + public void dispose() { + this.bytes = null; + } + + @Override + public String toString() { + return "[" + bytes.length + " bytes]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/FileEntry.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/FileEntry.java index 23c1bc82e..4ca7209b8 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/FileEntry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/FileEntry.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.internal.command.BinaryUtil; - -public class FileEntry implements IBinaryEntry { - - private File file; - - public FileEntry(File file) { - this.file = file; - } - - public File getFile() { - return this.file; - } - - public InputStream openInputStream() throws IOException { - return new FileInputStream(this.file); - } - - public void dispose() { - BinaryUtil.delete(this.file); - } - - @Override - public String toString() { - return file.getAbsolutePath() + " (" + file.length() + " bytes)"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.internal.command.BinaryUtil; + +public class FileEntry implements IBinaryEntry { + + private File file; + + public FileEntry(File file) { + this.file = file; + } + + public File getFile() { + return this.file; + } + + public InputStream openInputStream() throws IOException { + return new FileInputStream(this.file); + } + + public void dispose() { + BinaryUtil.delete(this.file); + } + + @Override + public String toString() { + return file.getAbsolutePath() + " (" + file.length() + " bytes)"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntry.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntry.java index 030e832bb..3aedd9b28 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntry.java @@ -1,78 +1,78 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A binary entry holds a sort of binary contents and provides methods to access - * these contents and flush caches. - * - * @author Frank Shaka - */ -public interface IBinaryEntry { - - /** - * A binary entry providing no contents. Clients may use - * obj == IBinaryEntry.NULL to determine whether the given - * object equals this binary entry. - */ - IBinaryEntry NULL = new IBinaryEntry() { - - /** - * This method is not intended to be called as no contents are available - * for this binary entry. - * - * @return never returns - * @throws IOException - * whenever this method is invoked - */ - public InputStream openInputStream() throws IOException { - throw new IOException( - "No input stream available for NULL binary entry."); //$NON-NLS-1$ - } - - /** - * Do nothing as there is nothing to dispose for this binary entry. - */ - public void dispose() { - } - - /** - * Returns "NULL" for this binary entry. - */ - public String toString() { - return "NULL"; //$NON-NLS-1$ - } - }; - - /** - * Opens an input stream for underlying contents. The returned input stream - * should be consumed before this binary entry is disposed. - * - * @return an input stream, never null - * @throws IOException - * if this binary entry has been disposed, the underlying - * contents can not be found, or any other IO error occurs - */ - InputStream openInputStream() throws IOException; - - /** - * Disposes this binary entry. This may flush all caches in this binary - * entry. - */ - void dispose(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A binary entry holds a sort of binary contents and provides methods to access + * these contents and flush caches. + * + * @author Frank Shaka + */ +public interface IBinaryEntry { + + /** + * A binary entry providing no contents. Clients may use + * obj == IBinaryEntry.NULL to determine whether the given + * object equals this binary entry. + */ + IBinaryEntry NULL = new IBinaryEntry() { + + /** + * This method is not intended to be called as no contents are available + * for this binary entry. + * + * @return never returns + * @throws IOException + * whenever this method is invoked + */ + public InputStream openInputStream() throws IOException { + throw new IOException( + "No input stream available for NULL binary entry."); //$NON-NLS-1$ + } + + /** + * Do nothing as there is nothing to dispose for this binary entry. + */ + public void dispose() { + } + + /** + * Returns "NULL" for this binary entry. + */ + public String toString() { + return "NULL"; //$NON-NLS-1$ + } + }; + + /** + * Opens an input stream for underlying contents. The returned input stream + * should be consumed before this binary entry is disposed. + * + * @return an input stream, never null + * @throws IOException + * if this binary entry has been disposed, the underlying + * contents can not be found, or any other IO error occurs + */ + InputStream openInputStream() throws IOException; + + /** + * Disposes this binary entry. This may flush all caches in this binary + * entry. + */ + void dispose(); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntryDelegate.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntryDelegate.java index 968d87d55..a88d8d2a9 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntryDelegate.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryEntryDelegate.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -public interface IBinaryEntryDelegate { - - IBinaryEntry getRealEntry(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +public interface IBinaryEntryDelegate { + + IBinaryEntry getRealEntry(); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryStore.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryStore.java index 4ceac3f29..684b51d46 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryStore.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/IBinaryStore.java @@ -1,150 +1,150 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * A binary store stores binary entries with unique names. It may use local - * memory as the cache pool, but local files are more recommended. - * - * @author Frank Shaka - * - */ -public interface IBinaryStore { - - /** - * Returns a binary entry associated with the given name. - * - * @param entryName - * the name of a binary entry - * @return a binary entry associated with the given name, or - * null if the entry is not found - */ - IBinaryEntry getEntry(String entryName); - - /** - * Determines whether a binary entry associated with the given name exists - * in this binary store. - * - * @param entryName - * the name of a binary entry - * @return true if the name if found, or false - * otherwise - */ - boolean hasEntry(String entryName); - - /** - * Clears this binary store and disposes all binary entries. All caches will - * be flushed. - */ - void clear(); - - /** - * Determines whether this binary store contains any binary entry or not. - * - * @return true if this binary store has no entries, or - * false otherwise - */ - boolean isEmpty(); - - /** - * Returns the number of binary entries exists in this binary store. - * - * @return the integer number of binary entries - */ - int size(); - - /** - * Returns an iterator that iterates over all existing entry names. - * - * @return an iterator instance, never null - */ - Iterator entryNames(); - - /** - * Removes and disposes a binary entry associated with the given name from - * this binary store. - * - * @param entryName - * the name of a binary entry - * @return true if the binary entry existed in this binary - * store and has been removed successfully, or false - * otherwise - */ - boolean removeEntry(String entryName); - - /** - * Adds a binary entry into this binary store and associate it with the - * given name. Note that any existing binary entry associated with the given - * will be removed and disposed in prior. - * - * @param entryName - * the name to be associated with the binary entry - * @param entry - * the binary entry to be added into this binary store - */ - void addEntry(String entryName, IBinaryEntry entry); - - /** - * Caches the contents of the given input stream in this binary store as a - * new binary entry. A unique name will be generated for the new binary - * entry. - * - * @param monitor - * the progress monitor, or null if progress - * monitoring is not required - * @param source - * the input stream providing binary contents - * @return a new binary entry with name associated, whose name can be - * retrieved via {@link INamedEntry#getName()} - * @throws IOException - * if any IO error occurs - * @throws InterruptedException - * if the process is canceled by detecting that - * {@link IProgressMonitor#isCanceled()} returns - * true - */ - INamedEntry addEntry(IProgressMonitor monitor, InputStream source) - throws IOException, InterruptedException; - - /** - * Caches the contents of the given input stream in this binary store as a - * new binary entry and associate it with the given name. Note that any - * existing binary entry associated with the given name will be removed and - * disposed in prior. - * - * @param monitor - * the progress monitor, or null if progress - * monitoring is not required - * @param entryName - * the name to be associated with the new binary entry - * @param source - * the input stream providing binary contents - * @return a new binary entry - * @throws IOException - * if any IO error occurs - * @throws InterruptedException - * if the process is canceled by detecting that - * {@link IProgressMonitor#isCanceled()} returns - * true - */ - IBinaryEntry addEntry(IProgressMonitor monitor, String entryName, - InputStream source) throws IOException, InterruptedException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * A binary store stores binary entries with unique names. It may use local + * memory as the cache pool, but local files are more recommended. + * + * @author Frank Shaka + * + */ +public interface IBinaryStore { + + /** + * Returns a binary entry associated with the given name. + * + * @param entryName + * the name of a binary entry + * @return a binary entry associated with the given name, or + * null if the entry is not found + */ + IBinaryEntry getEntry(String entryName); + + /** + * Determines whether a binary entry associated with the given name exists + * in this binary store. + * + * @param entryName + * the name of a binary entry + * @return true if the name if found, or false + * otherwise + */ + boolean hasEntry(String entryName); + + /** + * Clears this binary store and disposes all binary entries. All caches will + * be flushed. + */ + void clear(); + + /** + * Determines whether this binary store contains any binary entry or not. + * + * @return true if this binary store has no entries, or + * false otherwise + */ + boolean isEmpty(); + + /** + * Returns the number of binary entries exists in this binary store. + * + * @return the integer number of binary entries + */ + int size(); + + /** + * Returns an iterator that iterates over all existing entry names. + * + * @return an iterator instance, never null + */ + Iterator entryNames(); + + /** + * Removes and disposes a binary entry associated with the given name from + * this binary store. + * + * @param entryName + * the name of a binary entry + * @return true if the binary entry existed in this binary + * store and has been removed successfully, or false + * otherwise + */ + boolean removeEntry(String entryName); + + /** + * Adds a binary entry into this binary store and associate it with the + * given name. Note that any existing binary entry associated with the given + * will be removed and disposed in prior. + * + * @param entryName + * the name to be associated with the binary entry + * @param entry + * the binary entry to be added into this binary store + */ + void addEntry(String entryName, IBinaryEntry entry); + + /** + * Caches the contents of the given input stream in this binary store as a + * new binary entry. A unique name will be generated for the new binary + * entry. + * + * @param monitor + * the progress monitor, or null if progress + * monitoring is not required + * @param source + * the input stream providing binary contents + * @return a new binary entry with name associated, whose name can be + * retrieved via {@link INamedEntry#getName()} + * @throws IOException + * if any IO error occurs + * @throws InterruptedException + * if the process is canceled by detecting that + * {@link IProgressMonitor#isCanceled()} returns + * true + */ + INamedEntry addEntry(IProgressMonitor monitor, InputStream source) + throws IOException, InterruptedException; + + /** + * Caches the contents of the given input stream in this binary store as a + * new binary entry and associate it with the given name. Note that any + * existing binary entry associated with the given name will be removed and + * disposed in prior. + * + * @param monitor + * the progress monitor, or null if progress + * monitoring is not required + * @param entryName + * the name to be associated with the new binary entry + * @param source + * the input stream providing binary contents + * @return a new binary entry + * @throws IOException + * if any IO error occurs + * @throws InterruptedException + * if the process is canceled by detecting that + * {@link IProgressMonitor#isCanceled()} returns + * true + */ + IBinaryEntry addEntry(IProgressMonitor monitor, String entryName, + InputStream source) throws IOException, InterruptedException; + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/INamedEntry.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/INamedEntry.java index 4c3d1f640..79120f75f 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/INamedEntry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/INamedEntry.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -public interface INamedEntry extends IBinaryEntry { - - String getName(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +public interface INamedEntry extends IBinaryEntry { + + String getName(); + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/NamedEntry.java b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/NamedEntry.java index 3040c056d..af2e59105 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/NamedEntry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/command/binary/NamedEntry.java @@ -1,51 +1,51 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.command.binary; - -import java.io.IOException; -import java.io.InputStream; - -public class NamedEntry implements INamedEntry, IBinaryEntryDelegate { - - private final String name; - - private final IBinaryEntry entry; - - public NamedEntry(String name, IBinaryEntry entry) { - this.name = name; - this.entry = entry; - } - - public String getName() { - return name; - } - - public IBinaryEntry getRealEntry() { - return entry; - } - - public InputStream openInputStream() throws IOException { - return this.entry.openInputStream(); - } - - public void dispose() { - this.entry.dispose(); - } - - @Override - public String toString() { - return name + "[" + entry.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.command.binary; + +import java.io.IOException; +import java.io.InputStream; + +public class NamedEntry implements INamedEntry, IBinaryEntryDelegate { + + private final String name; + + private final IBinaryEntry entry; + + public NamedEntry(String name, IBinaryEntry entry) { + this.name = name; + this.entry = entry; + } + + public String getName() { + return name; + } + + public IBinaryEntry getRealEntry() { + return entry; + } + + public InputStream openInputStream() throws IOException { + return this.entry.openInputStream(); + } + + public void dispose() { + this.entry.dispose(); + } + + @Override + public String toString() { + return name + "[" + entry.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/BinaryUtil.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/BinaryUtil.java index 355994cac..ebb34246d 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/BinaryUtil.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/BinaryUtil.java @@ -1,34 +1,34 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command; - -import java.io.File; - -public class BinaryUtil { - - private BinaryUtil() { - throw new AssertionError(); - } - - public static boolean delete(File f) { - if (f.isDirectory()) { - String[] names = f.list(); - for (int i = 0; i < names.length; i++) { - delete(new File(f, names[i])); - } - } - return f.delete(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command; + +import java.io.File; + +public class BinaryUtil { + + private BinaryUtil() { + throw new AssertionError(); + } + + public static boolean delete(File f) { + if (f.isDirectory()) { + String[] names = f.list(); + for (int i = 0; i < names.length; i++) { + delete(new File(f, names[i])); + } + } + return f.delete(); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Logger.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Logger.java index 4972d3907..3bc1e9814 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Logger.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Logger.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command; - -import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; - -public class Logger { - - private Logger() { - throw new AssertionError(); - } - - public static void log(String message, Throwable error) { - ILog log = getLog(); - if (log != null) { - log.log(new Status(error == null ? IStatus.INFO : IStatus.ERROR, - XMindCommandPlugin.PLUGIN_ID, message, error)); - } - } - - public static void log(IStatus status) { - ILog log = getLog(); - if (log != null) { - log.log(status); - } - } - - private static ILog getLog() { - return XMindCommandPlugin.getLog(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class Logger { + + private Logger() { + throw new AssertionError(); + } + + public static void log(String message, Throwable error) { + ILog log = getLog(); + if (log != null) { + log.log(new Status(error == null ? IStatus.INFO : IStatus.ERROR, + XMindCommandPlugin.PLUGIN_ID, message, error)); + } + } + + public static void log(IStatus status) { + ILog log = getLog(); + if (log != null) { + log.log(status); + } + } + + private static ILog getLog() { + return XMindCommandPlugin.getLog(); + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Messages.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Messages.java index e95f1d6fd..c3f3c502a 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Messages.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/Messages.java @@ -1,29 +1,29 @@ -package org.xmind.core.internal.command; - -import org.eclipse.osgi.util.NLS; - -/** - * @auther Jason Wong - */ - -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.xmind.core.internal.command.messages"; //$NON-NLS-1$ - - public static String CommandJob_Name; - - public static String XMindCommandService_CommandHandledError_Message; - public static String XMindCommandService_ConsumingValue; - public static String XMindCommandService_ExcutingCommand; - public static String XMindCommandService_HandingCommand_Message; - public static String XMindCommandService_InvokingCommandError_Message; - public static String XMindCommandService_SearchHandler_Message; - public static String XMindCommandService_SearchHandlersError_Message; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} +package org.xmind.core.internal.command; + +import org.eclipse.osgi.util.NLS; + +/** + * @auther Jason Wong + */ + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.xmind.core.internal.command.messages"; //$NON-NLS-1$ + + public static String CommandJob_Name; + + public static String XMindCommandService_CommandHandledError_Message; + public static String XMindCommandService_ConsumingValue; + public static String XMindCommandService_ExcutingCommand; + public static String XMindCommandService_HandingCommand_Message; + public static String XMindCommandService_InvokingCommandError_Message; + public static String XMindCommandService_SearchHandler_Message; + public static String XMindCommandService_SearchHandlersError_Message; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandHandlerRegistry.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandHandlerRegistry.java index 73ebc8c83..a2dfa8826 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandHandlerRegistry.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandHandlerRegistry.java @@ -1,232 +1,232 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.IRegistryEventListener; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.ICommandHandler; - -public class XMindCommandHandlerRegistry implements IRegistryEventListener { - - private static final String EXT_POINT_ID = "handlers"; //$NON-NLS-1$ - - private static final String ATT_COMMAND = "command"; //$NON-NLS-1$ - - private static final String ATT_CLASS = "class"; //$NON-NLS-1$ - - private static final String ATT_ID = "id"; //$NON-NLS-1$ - - public static class CommandHandlerDescriptor { - - private String id; - - private Pattern pattern; - - private IConfigurationElement element; - - private ICommandHandler handler; - - public CommandHandlerDescriptor(String id, IConfigurationElement element) { - String namePattern = element.getAttribute(ATT_COMMAND); - if (namePattern == null) - namePattern = ""; //$NON-NLS-1$ - this.id = id; - this.pattern = Pattern.compile(namePattern); - this.element = element; - this.handler = null; - } - - public String getId() { - return id; - } - - public Matcher match(String commandName) { - return pattern.matcher(commandName); - } - - public ICommandHandler getHandler() { - if (handler == null) { - try { - handler = (ICommandHandler) element - .createExecutableExtension(ATT_CLASS); - } catch (CoreException e) { - Logger.log(null, e); - } - } - return handler; - } - - @Override - public String toString() { - return "CommandHandler{" + getId() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - } - - private static final XMindCommandHandlerRegistry instance = new XMindCommandHandlerRegistry(); - - private List descriptors = null; - - private Map> cache = null; - - private XMindCommandHandlerRegistry() { - } - - private synchronized List getHandlers() { - ensureLoaded(); - return descriptors; - } - - private void ensureLoaded() { - if (descriptors != null) - return; - loadFromExtensions(); - if (descriptors == null) - descriptors = Collections.emptyList(); - } - - private void loadFromExtensions() { - IExtensionPoint point = Platform.getExtensionRegistry() - .getExtensionPoint(XMindCommandPlugin.PLUGIN_ID, EXT_POINT_ID); - if (point == null) - return; - IExtension[] extensions = point.getExtensions(); - loadFromExtensions(extensions); - } - - private void loadFromExtensions(IExtension[] extensions) { - for (int i = 0; i < extensions.length; i++) { - loadFromConfigurationElements(extensions[i] - .getConfigurationElements()); - } - } - - private void loadFromConfigurationElements(IConfigurationElement[] elements) { - for (int i = 0; i < elements.length; i++) { - loadFromConfigurationElement(elements[i]); - } - } - - private void loadFromConfigurationElement(IConfigurationElement element) { - String name = element.getName(); - if ("handler".equals(name)) { //$NON-NLS-1$ - loadFromHandlerConfigurationElement(element); - loadFromConfigurationElements(element.getChildren()); - } - } - - private void loadFromHandlerConfigurationElement( - IConfigurationElement element) { - String id = element.getAttribute(ATT_ID); - if (id == null) { - Logger.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid extension: (id missing)")); //$NON-NLS-1$ - return; - } - if (element.getAttribute(ATT_CLASS) == null) { - Logger.log(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid extension: (class missing)")); //$NON-NLS-1$ - return; - } - - registerContribution(new CommandHandlerDescriptor(id, element)); - } - - private void registerContribution(CommandHandlerDescriptor contribution) { - if (descriptors == null) - descriptors = new ArrayList(); - descriptors.add(contribution); - } - - synchronized List findMatchedHandlerDescriptors( - ICommand command) { - if (cache == null) { - cache = new HashMap>(); - } - List list = cache.get(command - .getCommandName()); - if (list == null) { - list = collectHandlers(command.getCommandName()); - cache.put(command.getCommandName(), list); - } - return list; - } - - private List collectHandlers(String commandName) { - List list = new ArrayList(); - for (CommandHandlerDescriptor desc : getHandlers()) { - if (desc.match(commandName).matches()) { - list.add((CommandHandlerDescriptor) desc); - } - } - return list; - } - - private void invalidate() { - descriptors = null; - cache = null; - } - - public void added(IExtension[] extensions) { - invalidate(); - } - - public void removed(IExtension[] extensions) { - invalidate(); - } - - public void added(IExtensionPoint[] extensionPoints) { - // do nothing - } - - public void removed(IExtensionPoint[] extensionPoints) { - // do nothing - } - - public void installRegistryEventListener(IExtensionRegistry registry) { - if (registry == null) - return; - registry.addListener(this, XMindCommandPlugin.PLUGIN_ID + "." //$NON-NLS-1$ - + EXT_POINT_ID); - } - - public void uninstallRegistryEventListener(IExtensionRegistry registry) { - if (registry == null) - return; - registry.removeListener(this); - } - - public static XMindCommandHandlerRegistry getInstance() { - return instance; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IRegistryEventListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.ICommandHandler; + +public class XMindCommandHandlerRegistry implements IRegistryEventListener { + + private static final String EXT_POINT_ID = "handlers"; //$NON-NLS-1$ + + private static final String ATT_COMMAND = "command"; //$NON-NLS-1$ + + private static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + private static final String ATT_ID = "id"; //$NON-NLS-1$ + + public static class CommandHandlerDescriptor { + + private String id; + + private Pattern pattern; + + private IConfigurationElement element; + + private ICommandHandler handler; + + public CommandHandlerDescriptor(String id, IConfigurationElement element) { + String namePattern = element.getAttribute(ATT_COMMAND); + if (namePattern == null) + namePattern = ""; //$NON-NLS-1$ + this.id = id; + this.pattern = Pattern.compile(namePattern); + this.element = element; + this.handler = null; + } + + public String getId() { + return id; + } + + public Matcher match(String commandName) { + return pattern.matcher(commandName); + } + + public ICommandHandler getHandler() { + if (handler == null) { + try { + handler = (ICommandHandler) element + .createExecutableExtension(ATT_CLASS); + } catch (CoreException e) { + Logger.log(null, e); + } + } + return handler; + } + + @Override + public String toString() { + return "CommandHandler{" + getId() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + } + + private static final XMindCommandHandlerRegistry instance = new XMindCommandHandlerRegistry(); + + private List descriptors = null; + + private Map> cache = null; + + private XMindCommandHandlerRegistry() { + } + + private synchronized List getHandlers() { + ensureLoaded(); + return descriptors; + } + + private void ensureLoaded() { + if (descriptors != null) + return; + loadFromExtensions(); + if (descriptors == null) + descriptors = Collections.emptyList(); + } + + private void loadFromExtensions() { + IExtensionPoint point = Platform.getExtensionRegistry() + .getExtensionPoint(XMindCommandPlugin.PLUGIN_ID, EXT_POINT_ID); + if (point == null) + return; + IExtension[] extensions = point.getExtensions(); + loadFromExtensions(extensions); + } + + private void loadFromExtensions(IExtension[] extensions) { + for (int i = 0; i < extensions.length; i++) { + loadFromConfigurationElements(extensions[i] + .getConfigurationElements()); + } + } + + private void loadFromConfigurationElements(IConfigurationElement[] elements) { + for (int i = 0; i < elements.length; i++) { + loadFromConfigurationElement(elements[i]); + } + } + + private void loadFromConfigurationElement(IConfigurationElement element) { + String name = element.getName(); + if ("handler".equals(name)) { //$NON-NLS-1$ + loadFromHandlerConfigurationElement(element); + loadFromConfigurationElements(element.getChildren()); + } + } + + private void loadFromHandlerConfigurationElement( + IConfigurationElement element) { + String id = element.getAttribute(ATT_ID); + if (id == null) { + Logger.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid extension: (id missing)")); //$NON-NLS-1$ + return; + } + if (element.getAttribute(ATT_CLASS) == null) { + Logger.log(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid extension: (class missing)")); //$NON-NLS-1$ + return; + } + + registerContribution(new CommandHandlerDescriptor(id, element)); + } + + private void registerContribution(CommandHandlerDescriptor contribution) { + if (descriptors == null) + descriptors = new ArrayList(); + descriptors.add(contribution); + } + + synchronized List findMatchedHandlerDescriptors( + ICommand command) { + if (cache == null) { + cache = new HashMap>(); + } + List list = cache.get(command + .getCommandName()); + if (list == null) { + list = collectHandlers(command.getCommandName()); + cache.put(command.getCommandName(), list); + } + return list; + } + + private List collectHandlers(String commandName) { + List list = new ArrayList(); + for (CommandHandlerDescriptor desc : getHandlers()) { + if (desc.match(commandName).matches()) { + list.add((CommandHandlerDescriptor) desc); + } + } + return list; + } + + private void invalidate() { + descriptors = null; + cache = null; + } + + public void added(IExtension[] extensions) { + invalidate(); + } + + public void removed(IExtension[] extensions) { + invalidate(); + } + + public void added(IExtensionPoint[] extensionPoints) { + // do nothing + } + + public void removed(IExtensionPoint[] extensionPoints) { + // do nothing + } + + public void installRegistryEventListener(IExtensionRegistry registry) { + if (registry == null) + return; + registry.addListener(this, XMindCommandPlugin.PLUGIN_ID + "." //$NON-NLS-1$ + + EXT_POINT_ID); + } + + public void uninstallRegistryEventListener(IExtensionRegistry registry) { + if (registry == null) + return; + registry.removeListener(this); + } + + public static XMindCommandHandlerRegistry getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandPlugin.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandPlugin.java index 8ef1959a2..e0cf4ece1 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandPlugin.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandPlugin.java @@ -1,145 +1,145 @@ -package org.xmind.core.internal.command; - -import java.io.File; - -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.Platform; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; -import org.xmind.core.command.ICommandService; - -public class XMindCommandPlugin implements BundleActivator, - ServiceTrackerCustomizer { - - public static final String PLUGIN_ID = "org.xmind.core.command"; //$NON-NLS-1$ - - private static BundleContext bundleContext; - - private static XMindCommandPlugin singleton; - - private ICommandService commandService = null; - - private ServiceRegistration commandServiceRegistration = null; - - private ServiceTracker registryTracker = null; - - private File cacheLocation = null; - - private ServiceTracker debugTracker = null; - - public XMindCommandPlugin() { - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext - * ) - */ - public void start(final BundleContext bundleContext) throws Exception { - XMindCommandPlugin.bundleContext = bundleContext; - XMindCommandPlugin.singleton = this; - - commandService = new XMindCommandService(); - commandServiceRegistration = bundleContext.registerService( - ICommandService.class, commandService, null); - - registryTracker = new ServiceTracker( - bundleContext, IExtensionRegistry.class, this); - registryTracker.open(); - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext bundleContext) throws Exception { - if (debugTracker != null) { - debugTracker.close(); - debugTracker = null; - } - if (registryTracker != null) { - registryTracker.close(); - registryTracker = null; - } - - if (commandServiceRegistration != null) { - commandServiceRegistration.unregister(); - commandServiceRegistration = null; - } - commandService = null; - - if (cacheLocation != null) { - BinaryUtil.delete(cacheLocation); - cacheLocation = null; - } - - XMindCommandPlugin.bundleContext = null; - XMindCommandPlugin.singleton = null; - } - - public File getBinaryCacheLocation() { - if (cacheLocation == null) { - cacheLocation = new File(Platform.getStateLocation( - bundleContext.getBundle()).toFile(), ".binarycaches"); //$NON-NLS-1$ - } - return cacheLocation; - } - - public ICommandService getCommandService() { - return commandService; - } - - public IExtensionRegistry addingService( - ServiceReference reference) { - IExtensionRegistry registry = bundleContext.getService(reference); - XMindCommandHandlerRegistry.getInstance().installRegistryEventListener( - registry); - return registry; - } - - public void modifiedService(ServiceReference reference, - IExtensionRegistry service) { - // do nothing - } - - public void removedService(ServiceReference reference, - IExtensionRegistry registry) { - XMindCommandHandlerRegistry.getInstance() - .uninstallRegistryEventListener(registry); - bundleContext.ungetService(reference); - } - - private DebugOptions getDebugOptions() { - if (debugTracker == null) { - debugTracker = new ServiceTracker( - bundleContext, DebugOptions.class, null); - debugTracker.open(); - } - return debugTracker.getService(); - } - - public static boolean isDebugging(String option) { - DebugOptions options = getDefault().getDebugOptions(); - return options != null - && options.getBooleanOption(PLUGIN_ID + option, false); - } - - public static ILog getLog() { - return Platform.getLog(bundleContext.getBundle()); - } - - public static XMindCommandPlugin getDefault() { - return singleton; - } - -} +package org.xmind.core.internal.command; + +import java.io.File; + +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; +import org.xmind.core.command.ICommandService; + +public class XMindCommandPlugin implements BundleActivator, + ServiceTrackerCustomizer { + + public static final String PLUGIN_ID = "org.xmind.core.command"; //$NON-NLS-1$ + + private static BundleContext bundleContext; + + private static XMindCommandPlugin singleton; + + private ICommandService commandService = null; + + private ServiceRegistration commandServiceRegistration = null; + + private ServiceTracker registryTracker = null; + + private File cacheLocation = null; + + private ServiceTracker debugTracker = null; + + public XMindCommandPlugin() { + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext + * ) + */ + public void start(final BundleContext bundleContext) throws Exception { + XMindCommandPlugin.bundleContext = bundleContext; + XMindCommandPlugin.singleton = this; + + commandService = new XMindCommandService(); + commandServiceRegistration = bundleContext.registerService( + ICommandService.class, commandService, null); + + registryTracker = new ServiceTracker( + bundleContext, IExtensionRegistry.class, this); + registryTracker.open(); + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + if (debugTracker != null) { + debugTracker.close(); + debugTracker = null; + } + if (registryTracker != null) { + registryTracker.close(); + registryTracker = null; + } + + if (commandServiceRegistration != null) { + commandServiceRegistration.unregister(); + commandServiceRegistration = null; + } + commandService = null; + + if (cacheLocation != null) { + BinaryUtil.delete(cacheLocation); + cacheLocation = null; + } + + XMindCommandPlugin.bundleContext = null; + XMindCommandPlugin.singleton = null; + } + + public File getBinaryCacheLocation() { + if (cacheLocation == null) { + cacheLocation = new File(Platform.getStateLocation( + bundleContext.getBundle()).toFile(), ".binarycaches"); //$NON-NLS-1$ + } + return cacheLocation; + } + + public ICommandService getCommandService() { + return commandService; + } + + public IExtensionRegistry addingService( + ServiceReference reference) { + IExtensionRegistry registry = bundleContext.getService(reference); + XMindCommandHandlerRegistry.getInstance().installRegistryEventListener( + registry); + return registry; + } + + public void modifiedService(ServiceReference reference, + IExtensionRegistry service) { + // do nothing + } + + public void removedService(ServiceReference reference, + IExtensionRegistry registry) { + XMindCommandHandlerRegistry.getInstance() + .uninstallRegistryEventListener(registry); + bundleContext.ungetService(reference); + } + + private DebugOptions getDebugOptions() { + if (debugTracker == null) { + debugTracker = new ServiceTracker( + bundleContext, DebugOptions.class, null); + debugTracker.open(); + } + return debugTracker.getService(); + } + + public static boolean isDebugging(String option) { + DebugOptions options = getDefault().getDebugOptions(); + return options != null + && options.getBooleanOption(PLUGIN_ID + option, false); + } + + public static ILog getLog() { + return Platform.getLog(bundleContext.getBundle()); + } + + public static XMindCommandPlugin getDefault() { + return singleton; + } + +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandService.java b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandService.java index 321265dd1..5c868b443 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandService.java +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/XMindCommandService.java @@ -1,192 +1,192 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.command; - -import java.util.List; -import java.util.regex.Matcher; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.command.ICommand; -import org.xmind.core.command.ICommandHandler; -import org.xmind.core.command.ICommandService; -import org.xmind.core.command.IReturnValueConsumer; -import org.xmind.core.command.ReturnValue; -import org.xmind.core.command.binary.IBinaryStore; -import org.xmind.core.internal.command.XMindCommandHandlerRegistry.CommandHandlerDescriptor; - -/** - * This implementation of command service delegates command execution to - * specific command handlers. - * - * @author Frank Shaka - */ -public class XMindCommandService implements ICommandService { - - private static final String[] NO_MATCH_GROUPS = new String[0]; - - XMindCommandService() { - } - - public IStatus execute(IProgressMonitor monitor, ICommand command, - IReturnValueConsumer returnValueConsumer) { - if (monitor == null) - monitor = new NullProgressMonitor(); - monitor.beginTask(null, 100); - - monitor.subTask(NLS.bind(Messages.XMindCommandService_ExcutingCommand, - command)); - IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, 90); - IStatus returnValue = executeCommand(executeMonitor, command); - if (!executeMonitor.isCanceled()) - executeMonitor.done(); - - try { - monitor.subTask(Messages.XMindCommandService_ConsumingValue); - IProgressMonitor consumeMonitor = new SubProgressMonitor(monitor, - 10); - consumeCommand(consumeMonitor, command, returnValue, - returnValueConsumer); - if (!consumeMonitor.isCanceled()) - consumeMonitor.done(); - - if (!monitor.isCanceled()) - monitor.done(); - return returnValue; - } finally { - if (returnValue != null && returnValue instanceof ReturnValue) { - Object value = ((ReturnValue) returnValue).getValue(); - if (value instanceof IBinaryStore) { - ((IBinaryStore) value).clear(); - } - } - } - } - - private IStatus executeCommand(IProgressMonitor monitor, ICommand command) { - monitor.beginTask(null, 100); - - monitor.subTask(Messages.XMindCommandService_SearchHandler_Message); - - List handlerDescriptors = XMindCommandHandlerRegistry - .getInstance().findMatchedHandlerDescriptors(command); - if (handlerDescriptors.isEmpty()) { - monitor.done(); - return new Status( - IStatus.WARNING, - XMindCommandPlugin.PLUGIN_ID, - CODE_NO_HANDLERS, - NLS.bind( - Messages.XMindCommandService_SearchHandlersError_Message, - command), null); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.worked(10); - - monitor.subTask(NLS.bind( - Messages.XMindCommandService_HandingCommand_Message, command)); - SubProgressMonitor handlersMonitor = new SubProgressMonitor(monitor, 80); - IStatus returnValue = handleCommand(handlersMonitor, command, - handlerDescriptors); - if (returnValue != null && !returnValue.isOK() - && returnValue.getSeverity() != IStatus.CANCEL) { - Logger.log(returnValue); - } else if (returnValue == null) { - Logger.log("Command not handled: " + command, null); //$NON-NLS-1$ - returnValue = new Status( - IStatus.WARNING, - XMindCommandPlugin.PLUGIN_ID, - CODE_NOT_HANDLED, - NLS.bind( - Messages.XMindCommandService_CommandHandledError_Message, - command), null); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - handlersMonitor.done(); - monitor.done(); - return returnValue; - } - - protected IStatus handleCommand(SubProgressMonitor monitor, - ICommand command, List handlerDescriptors) { - IStatus returnValue = null; - try { - monitor.beginTask(null, handlerDescriptors.size()); - for (CommandHandlerDescriptor handlerDescriptor : handlerDescriptors) { - ICommandHandler handler = handlerDescriptor.getHandler(); - if (handler != null) { - SubProgressMonitor handlerMonitor = new SubProgressMonitor( - monitor, 1); - returnValue = handler.execute(handlerMonitor, command, - getMatchGroups(handlerDescriptor, command)); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - handlerMonitor.done(); - if (returnValue != null) - break; - } - } - } catch (Throwable e) { - return new Status( - IStatus.ERROR, - XMindCommandPlugin.PLUGIN_ID, - NLS.bind( - Messages.XMindCommandService_InvokingCommandError_Message, - e.toString()), e); - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - monitor.done(); - return returnValue; - } - - private String[] getMatchGroups(CommandHandlerDescriptor handlerDescriptor, - ICommand command) { - Matcher matcher = handlerDescriptor.match(command.getCommandName()); - if (!matcher.find()) - return NO_MATCH_GROUPS; - int total = matcher.groupCount(); - if (total <= 0) - return NO_MATCH_GROUPS; - String[] groups = new String[total]; - for (int i = 0; i < total; i++) { - groups[i] = matcher.group(i + 1); - } - return groups; - } - - private void consumeCommand(IProgressMonitor monitor, ICommand command, - IStatus returnValue, IReturnValueConsumer returnValueConsumer) { - if (returnValueConsumer != null) { - try { - IStatus consumed = returnValueConsumer.consumeReturnValue( - monitor, returnValue); - if (!monitor.isCanceled() && consumed != null - && !consumed.isOK() - && consumed.getSeverity() != IStatus.CANCEL) { - Logger.log(consumed); - } - } catch (Throwable e) { - Logger.log("Error occurred while consuming return value.", //$NON-NLS-1$ - e); - } - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.command; + +import java.util.List; +import java.util.regex.Matcher; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.command.ICommand; +import org.xmind.core.command.ICommandHandler; +import org.xmind.core.command.ICommandService; +import org.xmind.core.command.IReturnValueConsumer; +import org.xmind.core.command.ReturnValue; +import org.xmind.core.command.binary.IBinaryStore; +import org.xmind.core.internal.command.XMindCommandHandlerRegistry.CommandHandlerDescriptor; + +/** + * This implementation of command service delegates command execution to + * specific command handlers. + * + * @author Frank Shaka + */ +public class XMindCommandService implements ICommandService { + + private static final String[] NO_MATCH_GROUPS = new String[0]; + + XMindCommandService() { + } + + public IStatus execute(IProgressMonitor monitor, ICommand command, + IReturnValueConsumer returnValueConsumer) { + if (monitor == null) + monitor = new NullProgressMonitor(); + monitor.beginTask(null, 100); + + monitor.subTask(NLS.bind(Messages.XMindCommandService_ExcutingCommand, + command)); + IProgressMonitor executeMonitor = new SubProgressMonitor(monitor, 90); + IStatus returnValue = executeCommand(executeMonitor, command); + if (!executeMonitor.isCanceled()) + executeMonitor.done(); + + try { + monitor.subTask(Messages.XMindCommandService_ConsumingValue); + IProgressMonitor consumeMonitor = new SubProgressMonitor(monitor, + 10); + consumeCommand(consumeMonitor, command, returnValue, + returnValueConsumer); + if (!consumeMonitor.isCanceled()) + consumeMonitor.done(); + + if (!monitor.isCanceled()) + monitor.done(); + return returnValue; + } finally { + if (returnValue != null && returnValue instanceof ReturnValue) { + Object value = ((ReturnValue) returnValue).getValue(); + if (value instanceof IBinaryStore) { + ((IBinaryStore) value).clear(); + } + } + } + } + + private IStatus executeCommand(IProgressMonitor monitor, ICommand command) { + monitor.beginTask(null, 100); + + monitor.subTask(Messages.XMindCommandService_SearchHandler_Message); + + List handlerDescriptors = XMindCommandHandlerRegistry + .getInstance().findMatchedHandlerDescriptors(command); + if (handlerDescriptors.isEmpty()) { + monitor.done(); + return new Status( + IStatus.WARNING, + XMindCommandPlugin.PLUGIN_ID, + CODE_NO_HANDLERS, + NLS.bind( + Messages.XMindCommandService_SearchHandlersError_Message, + command), null); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.worked(10); + + monitor.subTask(NLS.bind( + Messages.XMindCommandService_HandingCommand_Message, command)); + SubProgressMonitor handlersMonitor = new SubProgressMonitor(monitor, 80); + IStatus returnValue = handleCommand(handlersMonitor, command, + handlerDescriptors); + if (returnValue != null && !returnValue.isOK() + && returnValue.getSeverity() != IStatus.CANCEL) { + Logger.log(returnValue); + } else if (returnValue == null) { + Logger.log("Command not handled: " + command, null); //$NON-NLS-1$ + returnValue = new Status( + IStatus.WARNING, + XMindCommandPlugin.PLUGIN_ID, + CODE_NOT_HANDLED, + NLS.bind( + Messages.XMindCommandService_CommandHandledError_Message, + command), null); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + handlersMonitor.done(); + monitor.done(); + return returnValue; + } + + protected IStatus handleCommand(SubProgressMonitor monitor, + ICommand command, List handlerDescriptors) { + IStatus returnValue = null; + try { + monitor.beginTask(null, handlerDescriptors.size()); + for (CommandHandlerDescriptor handlerDescriptor : handlerDescriptors) { + ICommandHandler handler = handlerDescriptor.getHandler(); + if (handler != null) { + SubProgressMonitor handlerMonitor = new SubProgressMonitor( + monitor, 1); + returnValue = handler.execute(handlerMonitor, command, + getMatchGroups(handlerDescriptor, command)); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + handlerMonitor.done(); + if (returnValue != null) + break; + } + } + } catch (Throwable e) { + return new Status( + IStatus.ERROR, + XMindCommandPlugin.PLUGIN_ID, + NLS.bind( + Messages.XMindCommandService_InvokingCommandError_Message, + e.toString()), e); + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + monitor.done(); + return returnValue; + } + + private String[] getMatchGroups(CommandHandlerDescriptor handlerDescriptor, + ICommand command) { + Matcher matcher = handlerDescriptor.match(command.getCommandName()); + if (!matcher.find()) + return NO_MATCH_GROUPS; + int total = matcher.groupCount(); + if (total <= 0) + return NO_MATCH_GROUPS; + String[] groups = new String[total]; + for (int i = 0; i < total; i++) { + groups[i] = matcher.group(i + 1); + } + return groups; + } + + private void consumeCommand(IProgressMonitor monitor, ICommand command, + IStatus returnValue, IReturnValueConsumer returnValueConsumer) { + if (returnValueConsumer != null) { + try { + IStatus consumed = returnValueConsumer.consumeReturnValue( + monitor, returnValue); + if (!monitor.isCanceled() && consumed != null + && !consumed.isOK() + && consumed.getSeverity() != IStatus.CANCEL) { + Logger.log(consumed); + } + } catch (Throwable e) { + Logger.log("Error occurred while consuming return value.", //$NON-NLS-1$ + e); + } + } + } +} diff --git a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/messages.properties b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/messages.properties index 8375ba153..1da0dc220 100644 --- a/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/messages.properties +++ b/bundles/org.xmind.core.command/src/org/xmind/core/internal/command/messages.properties @@ -1,9 +1,9 @@ -CommandJob_Name=Handle Command - -XMindCommandService_CommandHandledError_Message=Command is not handled: {0} -XMindCommandService_ConsumingValue=Consuming return value -XMindCommandService_ExcutingCommand=Executing command {0} -XMindCommandService_HandingCommand_Message=Handling command: {0} -XMindCommandService_InvokingCommandError_Message=Error occurred while invoking command handler: {0} -XMindCommandService_SearchHandler_Message=Searching for command handlers +CommandJob_Name=Handle Command + +XMindCommandService_CommandHandledError_Message=Command is not handled: {0} +XMindCommandService_ConsumingValue=Consuming return value +XMindCommandService_ExcutingCommand=Executing command {0} +XMindCommandService_HandingCommand_Message=Handling command: {0} +XMindCommandService_InvokingCommandError_Message=Error occurred while invoking command handler: {0} +XMindCommandService_SearchHandler_Message=Searching for command handlers XMindCommandService_SearchHandlersError_Message=No handlers available for this command: {0} \ No newline at end of file diff --git a/bundles/org.xmind.core.io/.gitignore b/bundles/org.xmind.core.io/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.io/.gitignore +++ b/bundles/org.xmind.core.io/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.io/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.io/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.io/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.io/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.io/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.io/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.io/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.io/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core.io/META-INF/MANIFEST.MF b/bundles/org.xmind.core.io/META-INF/MANIFEST.MF index 402906a08..734d69f8b 100644 --- a/bundles/org.xmind.core.io/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.io/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.core.io;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %providerName -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.core.io, - org.xmind.core.io.freemind, - org.xmind.core.io.mindmanager, - org.xmind.core.io.workbook -Bundle-Localization: plugin -Require-Bundle: org.xmind.core +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.core.io;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.core.io, + org.xmind.core.io.freemind, + org.xmind.core.io.mindmanager, + org.xmind.core.io.workbook +Bundle-Localization: plugin +Require-Bundle: org.xmind.core diff --git a/bundles/org.xmind.core.io/about.html b/bundles/org.xmind.core.io/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.io/about.html +++ b/bundles/org.xmind.core.io/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.io/plugin.properties b/bundles/org.xmind.core.io/plugin.properties index b015f1d9c..79e81d1b4 100644 --- a/bundles/org.xmind.core.io/plugin.properties +++ b/bundles/org.xmind.core.io/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.core.io -providerName = XMind Ltd. +#Properties file for org.xmind.core.io +providerName = XMind Ltd. pluginName = XMind Core IO \ No newline at end of file diff --git a/bundles/org.xmind.core.io/pom.xml b/bundles/org.xmind.core.io/pom.xml index 8610d3993..8a1d826ba 100644 --- a/bundles/org.xmind.core.io/pom.xml +++ b/bundles/org.xmind.core.io/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.io - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.io + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingConstants.java b/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingConstants.java index 7335572ce..bbf5767c1 100644 --- a/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingConstants.java +++ b/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingConstants.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -public class ResourceMappingConstants { - - static final String TAG_RESOURCE_GROUP = "resource-group"; //$NON-NLS-1$ - static final String TAG_TRANSFER_MAPPING = "resource-mapping"; //$NON-NLS-1$ - static final String ATT_APPLICATION_ID = "application-id"; //$NON-NLS-1$ - static final String ATT_TYPE = "type"; //$NON-NLS-1$ - static final String ATT_SRC = "src"; //$NON-NLS-1$ - static final String ATT_DEST = "dest"; //$NON-NLS-1$ - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +public class ResourceMappingConstants { + + static final String TAG_RESOURCE_GROUP = "resource-group"; //$NON-NLS-1$ + static final String TAG_TRANSFER_MAPPING = "resource-mapping"; //$NON-NLS-1$ + static final String ATT_APPLICATION_ID = "application-id"; //$NON-NLS-1$ + static final String ATT_TYPE = "type"; //$NON-NLS-1$ + static final String ATT_SRC = "src"; //$NON-NLS-1$ + static final String ATT_DEST = "dest"; //$NON-NLS-1$ + } \ No newline at end of file diff --git a/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingManager.java b/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingManager.java index 55383a1a5..18378dbf5 100644 --- a/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingManager.java +++ b/bundles/org.xmind.core.io/src/org/xmind/core/io/ResourceMappingManager.java @@ -1,153 +1,153 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.util.DOMUtils; -import org.xml.sax.SAXException; - -public class ResourceMappingManager { - - private String applicationId; - - private Document implementation; - - private List groups; - - private Map map; - - private ResourceMappingManager(Document implementation) { - this.implementation = implementation; - this.applicationId = DOMUtils.getAttribute( - implementation.getDocumentElement(), - ResourceMappingConstants.ATT_APPLICATION_ID); - } - - private ResourceMappingManager(String applicationId) { - this.implementation = null; - this.applicationId = applicationId; - } - - public String getApplicationId() { - return applicationId; - } - - public List getGroups() { - ensureLoaded(); - return groups; - } - - public ResourceGroup getGroup(String groupName) { - ensureLoaded(); - return map.get(groupName); - } - - public String getDestination(String groupName, String source) { - ResourceGroup list = getGroup(groupName); - if (list != null) - return list.getDestination(source); - return null; - } - - public String getSource(String groupName, String destination) { - ResourceGroup list = getGroup(groupName); - if (list != null) - return list.getSource(destination); - return null; - } - - private void ensureLoaded() { - if (groups != null && map != null) - return; - lazyLoad(); - if (groups == null) - groups = Collections.emptyList(); - if (map == null) - map = Collections.emptyMap(); - } - - private void lazyLoad() { - if (implementation == null) - return; - - Iterator it = DOMUtils.childElementIterByTag( - implementation.getDocumentElement(), - ResourceMappingConstants.TAG_RESOURCE_GROUP); - while (it.hasNext()) { - createResourceGorup(it.next()); - } - } - - private void createResourceGorup(Element element) { - ResourceGroup list = new ResourceGroup(element, this); - if (groups == null) - groups = new ArrayList(); - groups.add(list); - String type = list.getType(); - if (type != null) { - if (map == null) - map = new HashMap(); - map.put(type, list); - } - } - - public static ResourceMappingManager createEmptyInstance( - String applicationId) { - return new ResourceMappingManager(applicationId); - } - - public static ResourceMappingManager createInstance(InputStream stream) - throws ParserConfigurationException, SAXException, IOException { - DocumentBuilder builder = DOMUtils.getDefaultDocumentBuilder(); - try { - Document document = builder.parse(stream); - return new ResourceMappingManager(document); - } finally { - try { - stream.close(); - } catch (IOException ignore) { - } - } - } - - public static ResourceMappingManager createInstance(URL url) - throws ParserConfigurationException, SAXException, IOException { - InputStream stream = url.openStream(); - return createInstance(stream); - } - - public static ResourceMappingManager createInstance(Class clazz, - String name) throws ParserConfigurationException, SAXException, - IOException { - InputStream stream = clazz.getResourceAsStream(name); - if (stream == null) - throw new FileNotFoundException(); - return createInstance(stream); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.util.DOMUtils; +import org.xml.sax.SAXException; + +public class ResourceMappingManager { + + private String applicationId; + + private Document implementation; + + private List groups; + + private Map map; + + private ResourceMappingManager(Document implementation) { + this.implementation = implementation; + this.applicationId = DOMUtils.getAttribute( + implementation.getDocumentElement(), + ResourceMappingConstants.ATT_APPLICATION_ID); + } + + private ResourceMappingManager(String applicationId) { + this.implementation = null; + this.applicationId = applicationId; + } + + public String getApplicationId() { + return applicationId; + } + + public List getGroups() { + ensureLoaded(); + return groups; + } + + public ResourceGroup getGroup(String groupName) { + ensureLoaded(); + return map.get(groupName); + } + + public String getDestination(String groupName, String source) { + ResourceGroup list = getGroup(groupName); + if (list != null) + return list.getDestination(source); + return null; + } + + public String getSource(String groupName, String destination) { + ResourceGroup list = getGroup(groupName); + if (list != null) + return list.getSource(destination); + return null; + } + + private void ensureLoaded() { + if (groups != null && map != null) + return; + lazyLoad(); + if (groups == null) + groups = Collections.emptyList(); + if (map == null) + map = Collections.emptyMap(); + } + + private void lazyLoad() { + if (implementation == null) + return; + + Iterator it = DOMUtils.childElementIterByTag( + implementation.getDocumentElement(), + ResourceMappingConstants.TAG_RESOURCE_GROUP); + while (it.hasNext()) { + createResourceGorup(it.next()); + } + } + + private void createResourceGorup(Element element) { + ResourceGroup list = new ResourceGroup(element, this); + if (groups == null) + groups = new ArrayList(); + groups.add(list); + String type = list.getType(); + if (type != null) { + if (map == null) + map = new HashMap(); + map.put(type, list); + } + } + + public static ResourceMappingManager createEmptyInstance( + String applicationId) { + return new ResourceMappingManager(applicationId); + } + + public static ResourceMappingManager createInstance(InputStream stream) + throws ParserConfigurationException, SAXException, IOException { + DocumentBuilder builder = DOMUtils.getDefaultDocumentBuilder(); + try { + Document document = builder.parse(stream); + return new ResourceMappingManager(document); + } finally { + try { + stream.close(); + } catch (IOException ignore) { + } + } + } + + public static ResourceMappingManager createInstance(URL url) + throws ParserConfigurationException, SAXException, IOException { + InputStream stream = url.openStream(); + return createInstance(stream); + } + + public static ResourceMappingManager createInstance(Class clazz, + String name) throws ParserConfigurationException, SAXException, + IOException { + InputStream stream = clazz.getResourceAsStream(name); + if (stream == null) + throw new FileNotFoundException(); + return createInstance(stream); + } } \ No newline at end of file diff --git a/bundles/org.xmind.core.io/src/org/xmind/core/io/freemind/FreeMindConstants.java b/bundles/org.xmind.core.io/src/org/xmind/core/io/freemind/FreeMindConstants.java index 79aa829be..7c7196a6a 100644 --- a/bundles/org.xmind.core.io/src/org/xmind/core/io/freemind/FreeMindConstants.java +++ b/bundles/org.xmind.core.io/src/org/xmind/core/io/freemind/FreeMindConstants.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io.freemind; - -public interface FreeMindConstants { - - String FILE_EXTENSION = ".mm"; //$NON-NLS-1$ - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io.freemind; + +public interface FreeMindConstants { + + String FILE_EXTENSION = ".mm"; //$NON-NLS-1$ + } \ No newline at end of file diff --git a/bundles/org.xmind.core.licensing/.classpath b/bundles/org.xmind.core.licensing/.classpath index 8a8f1668c..ad32c83a7 100644 --- a/bundles/org.xmind.core.licensing/.classpath +++ b/bundles/org.xmind.core.licensing/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.core.licensing/.gitignore b/bundles/org.xmind.core.licensing/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.licensing/.gitignore +++ b/bundles/org.xmind.core.licensing/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.licensing/.project b/bundles/org.xmind.core.licensing/.project index 8269a578c..833c52558 100644 --- a/bundles/org.xmind.core.licensing/.project +++ b/bundles/org.xmind.core.licensing/.project @@ -1,28 +1,28 @@ - - - org.xmind.core.licensing - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.core.licensing + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.core.prefs index 082f08668..4d7b8a249 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.core.prefs @@ -1,416 +1,416 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.launching.prefs index 940d7b066..d211d3263 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.ltk.core.refactoring.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.ltk.core.refactoring.prefs index cfcd1d3c2..b196c64a3 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.ltk.core.refactoring.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/bundles/org.xmind.core.licensing/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.core.licensing/.settings/org.eclipse.pde.prefs index 9be2bbfea..62cfa90de 100644 --- a/bundles/org.xmind.core.licensing/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.core.licensing/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=1 -compilers.p.discouraged-class=1 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF b/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF index 783a145d0..022ca8243 100644 --- a/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF @@ -1,8 +1,8 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Licensing API -Bundle-SymbolicName: org.xmind.core.licensing -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: XMind Ltd. -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Export-Package: org.xmind.core.licensing +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Licensing API +Bundle-SymbolicName: org.xmind.core.licensing +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: XMind Ltd. +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.xmind.core.licensing diff --git a/bundles/org.xmind.core.licensing/about.html b/bundles/org.xmind.core.licensing/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.licensing/about.html +++ b/bundles/org.xmind.core.licensing/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.licensing/build.properties b/bundles/org.xmind.core.licensing/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/bundles/org.xmind.core.licensing/build.properties +++ b/bundles/org.xmind.core.licensing/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/bundles/org.xmind.core.licensing/pom.xml b/bundles/org.xmind.core.licensing/pom.xml index cb5f07535..d42660a16 100644 --- a/bundles/org.xmind.core.licensing/pom.xml +++ b/bundles/org.xmind.core.licensing/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.licensing - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.licensing + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseAgent.java b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseAgent.java index 317b7c9d5..7119f7bff 100644 --- a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseAgent.java +++ b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseAgent.java @@ -1,73 +1,73 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.licensing; - -/** - * @author Frank Shaka - * @since 3.6.51 - */ -public interface ILicenseAgent { - - int NOT_LICENSED = 1 << 0; - - int PRO_SUBSCRIPTION = 1 << 1; - int PRO_LICENSE_KEY = 1 << 2; - int PLUS_LICENSE_KEY = 1 << 3; - - /** - * Returns the type code of the license verification result. This code may - * consists of multiple bit flags defined as static members of this - * interface. - * - * @return the type code - */ - int getLicenseType(); - - /** - * Returns the representative name of the entity to whom the current XMind - * Pro/Plus is licensed. - * - * @return the name of the licensee entity, or null if not - * licensed - */ - String getLicenseeName(); - - /** - * Returns a 12-character string representing the verified license key. - * - * @return the license key header, or null if no license key is - * verified - */ - ILicenseKeyHeader getLicenseKeyHeader(); - - /** - * Adds a listener for license changed events. - * - * @param listener - * the listener to add - */ - void addLicenseChangedListener(ILicenseChangedListener listener); - - /** - * Removes a listener for license changed events. - * - * @param listener - * the listener to remove - */ - void removeLicenseChangedListener(ILicenseChangedListener listener); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.licensing; + +/** + * @author Frank Shaka + * @since 3.6.51 + */ +public interface ILicenseAgent { + + int NOT_LICENSED = 1 << 0; + + int PRO_SUBSCRIPTION = 1 << 1; + int PRO_LICENSE_KEY = 1 << 2; + int PLUS_LICENSE_KEY = 1 << 3; + + /** + * Returns the type code of the license verification result. This code may + * consists of multiple bit flags defined as static members of this + * interface. + * + * @return the type code + */ + int getLicenseType(); + + /** + * Returns the representative name of the entity to whom the current XMind + * Pro/Plus is licensed. + * + * @return the name of the licensee entity, or null if not + * licensed + */ + String getLicenseeName(); + + /** + * Returns a 12-character string representing the verified license key. + * + * @return the license key header, or null if no license key is + * verified + */ + ILicenseKeyHeader getLicenseKeyHeader(); + + /** + * Adds a listener for license changed events. + * + * @param listener + * the listener to add + */ + void addLicenseChangedListener(ILicenseChangedListener listener); + + /** + * Removes a listener for license changed events. + * + * @param listener + * the listener to remove + */ + void removeLicenseChangedListener(ILicenseChangedListener listener); + +} diff --git a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseChangedListener.java b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseChangedListener.java index 8f3573820..4b735816f 100644 --- a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseChangedListener.java +++ b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseChangedListener.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.licensing; - -/** - * @author Frank Shaka - * - */ -public interface ILicenseChangedListener { - - void licenseChanged(ILicenseAgent licenseAgent); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.licensing; + +/** + * @author Frank Shaka + * + */ +public interface ILicenseChangedListener { + + void licenseChanged(ILicenseAgent licenseAgent); + +} diff --git a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseKeyHeader.java b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseKeyHeader.java index a8d3512c8..4a69ae42e 100644 --- a/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseKeyHeader.java +++ b/bundles/org.xmind.core.licensing/src/org/xmind/core/licensing/ILicenseKeyHeader.java @@ -1,226 +1,226 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.licensing; - -/** - * The header info of a license key. - * - * @author Frank Shaka - * @since 3.6.51 - */ -public interface ILicenseKeyHeader { - - /** - * The identifying marker of a XMind product license key (value is - * "X" ). - */ - String IDENTIFYING_MARKER = "X"; //$NON-NLS-1$ - - /** - * The type of a XMind Pro license key (value is "A"). - * - * @see #getLicenseType() - */ - String TYPE_PRO = "A"; //$NON-NLS-1$ - - /** - * The type of a XMind Plus license key (value is "B"). - * - * @see #getLicenseType() - */ - String TYPE_PLUS = "B"; //$NON-NLS-1$ - - /** - * The type of a XMind Pro VLE license key (value is "C"). - * - * @see #getLicenseType() - */ - String TYPE_VINDY = "C"; //$NON-NLS-1$ - - /** - * The type of individual customers (value is "I"). - * - * @see #getLicenseeType() - */ - String LICENSEE_INDIVIDUAL = "I"; //$NON-NLS-1$ - - /** - * The type of educational/non-profit organizations (value is - * "E"). - * - * @see #getLicenseeType() - */ - String LICENSEE_EDU = "E"; //$NON-NLS-1$ - - /** - * The type of govenment organizations (value is "G"). - * - * @see #getLicenseeType() - */ - String LICENSEE_GOV = "G"; //$NON-NLS-1$ - - /** - * The type of families (value is "F"). - * - * @see #getLicenseeType() - */ - String LICENSEE_FAMILY = "F"; //$NON-NLS-1$ - - /** - * The type of small teams with 5 members (value is "T"). - * - * @see #getLicenseeType() - */ - String LICENSEE_TEAM_5U = "T"; //$NON-NLS-1$ - - /** - * The type of small teams with 10 members (value is "1"). - * - * @see #getLicenseeType() - */ - String LICENSEE_TEAM_10U = "1"; //$NON-NLS-1$ - - /** - * The type of small teams with 20 members (value is "2"). - * - * @see #getLicenseeType() - */ - String LICENSEE_TEAM_20U = "2"; //$NON-NLS-1$ - - /** - * The type of VLE customers (value is "V"). - * - * @see #getLicenseeType() - */ - String LICENSEE_VLE = "V"; //$NON-NLS-1$ - - /** - * Returns the type of this license key. - * - * @return the identifier of license key type - * @see #TYPE_PRO - * @see #TYPE_PLUS - * @see #TYPE_VINDY - */ - String getLicenseType(); - - /** - * Returns the code name of the XMind product vendor that this license key - * was generated for. - * - * @return the code name of XMind product vendor - */ - String getVendorName(); - - /** - * Returns the major part of the XMind product version number bound to this - * license key. - * - * @return the major version number - */ - int getMajorVersionNumber(); - - /** - * Returns the minor part of the XMind product version number bound to this - * license key. - * - * @return the minor version number - */ - int getMinorVersionNumber(); - - /** - * Returns the type of the entity that is licensed to. - * - * @return the type of the licensee - * - * @see #LICENSEE_INDIVIDUAL - * @see #LICENSEE_EDU - * @see #LICENSEE_GOV - * @see #LICENSEE_FAMILY - * @see #LICENSEE_TEAM_5U - * @see #LICENSEE_TEAM_10U - * @see #LICENSEE_TEAM_20U - * @see #LICENSEE_VLE - */ - String getLicenseeType(); - - /** - * Returns the number of years within which this license key can be upgraded - * to the latest version. - * - * @return a positive number of years of free version upgrade, or - * 0 to indicate no free version upgrade is available - * for this license key - */ - int getYearsOfUpgrade(); - - /** - * Returns the 12-character string representing this license key header. See - * {@link ILicenseKeyHeader} for detailed description of how all information - * is encoded. - * - *

- * A license key header contains 12 characters which have the following - * meanings: - *

- * - *
    - *
  1. Characters 1 is an identifying marker, "X", - * indicating that following characters describe a license key used to - * activate an XMind product
  2. - *
  3. Character 2 is the type of the license key
  4. - *
  5. Characters 3-6 specifies the XMind product this license key is - * generated against: - *
      - *
    • Characters 3 & 4 = the code name of the XMind product vendor
    • - *
    • Characters 5 = the major version number of XMind product - * (Base36 encoded)
    • - *
    • Characters 6 = the minor version number of XMind product - * (Base36 encoded)
    • - *
    - *
  6. - *
  7. Character 7 is the type of the licensee
  8. - *
  9. Character 8 & 9 = the years of free version upgrade - * applied to this license key (Base36 encoded, left padded with 0)
  10. - *
  11. Character 10 is the free months number of the license
  12. - *
  13. Character 11 & 12 = (reserved for future use, currently randomly - * generated and Base36 encoded)
  14. - *
- * - *

- * Each type of a license key is bound to a unique method (i.e. - * secure key pair) to verify the license key body. - *

- * - *

- * Product info may not be checked restrictly but may be prompted if - * verification fails. - *

- * - *

- * It's gauranteed that same license key headers are encoded as the same - * string and different headers as different strings. That is to say, if two - * license key headers are same (or different) as determined by - * {@link #equals(Object)}, they are encoded as the same (or different) - * strings, and vice versa. - *

- * - * @return the encoded 12-character string of the license key - */ - String toEncoded(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.licensing; + +/** + * The header info of a license key. + * + * @author Frank Shaka + * @since 3.6.51 + */ +public interface ILicenseKeyHeader { + + /** + * The identifying marker of a XMind product license key (value is + * "X" ). + */ + String IDENTIFYING_MARKER = "X"; //$NON-NLS-1$ + + /** + * The type of a XMind Pro license key (value is "A"). + * + * @see #getLicenseType() + */ + String TYPE_PRO = "A"; //$NON-NLS-1$ + + /** + * The type of a XMind Plus license key (value is "B"). + * + * @see #getLicenseType() + */ + String TYPE_PLUS = "B"; //$NON-NLS-1$ + + /** + * The type of a XMind Pro VLE license key (value is "C"). + * + * @see #getLicenseType() + */ + String TYPE_VINDY = "C"; //$NON-NLS-1$ + + /** + * The type of individual customers (value is "I"). + * + * @see #getLicenseeType() + */ + String LICENSEE_INDIVIDUAL = "I"; //$NON-NLS-1$ + + /** + * The type of educational/non-profit organizations (value is + * "E"). + * + * @see #getLicenseeType() + */ + String LICENSEE_EDU = "E"; //$NON-NLS-1$ + + /** + * The type of govenment organizations (value is "G"). + * + * @see #getLicenseeType() + */ + String LICENSEE_GOV = "G"; //$NON-NLS-1$ + + /** + * The type of families (value is "F"). + * + * @see #getLicenseeType() + */ + String LICENSEE_FAMILY = "F"; //$NON-NLS-1$ + + /** + * The type of small teams with 5 members (value is "T"). + * + * @see #getLicenseeType() + */ + String LICENSEE_TEAM_5U = "T"; //$NON-NLS-1$ + + /** + * The type of small teams with 10 members (value is "1"). + * + * @see #getLicenseeType() + */ + String LICENSEE_TEAM_10U = "1"; //$NON-NLS-1$ + + /** + * The type of small teams with 20 members (value is "2"). + * + * @see #getLicenseeType() + */ + String LICENSEE_TEAM_20U = "2"; //$NON-NLS-1$ + + /** + * The type of VLE customers (value is "V"). + * + * @see #getLicenseeType() + */ + String LICENSEE_VLE = "V"; //$NON-NLS-1$ + + /** + * Returns the type of this license key. + * + * @return the identifier of license key type + * @see #TYPE_PRO + * @see #TYPE_PLUS + * @see #TYPE_VINDY + */ + String getLicenseType(); + + /** + * Returns the code name of the XMind product vendor that this license key + * was generated for. + * + * @return the code name of XMind product vendor + */ + String getVendorName(); + + /** + * Returns the major part of the XMind product version number bound to this + * license key. + * + * @return the major version number + */ + int getMajorVersionNumber(); + + /** + * Returns the minor part of the XMind product version number bound to this + * license key. + * + * @return the minor version number + */ + int getMinorVersionNumber(); + + /** + * Returns the type of the entity that is licensed to. + * + * @return the type of the licensee + * + * @see #LICENSEE_INDIVIDUAL + * @see #LICENSEE_EDU + * @see #LICENSEE_GOV + * @see #LICENSEE_FAMILY + * @see #LICENSEE_TEAM_5U + * @see #LICENSEE_TEAM_10U + * @see #LICENSEE_TEAM_20U + * @see #LICENSEE_VLE + */ + String getLicenseeType(); + + /** + * Returns the number of years within which this license key can be upgraded + * to the latest version. + * + * @return a positive number of years of free version upgrade, or + * 0 to indicate no free version upgrade is available + * for this license key + */ + int getYearsOfUpgrade(); + + /** + * Returns the 12-character string representing this license key header. See + * {@link ILicenseKeyHeader} for detailed description of how all information + * is encoded. + * + *

+ * A license key header contains 12 characters which have the following + * meanings: + *

+ * + *
    + *
  1. Characters 1 is an identifying marker, "X", + * indicating that following characters describe a license key used to + * activate an XMind product
  2. + *
  3. Character 2 is the type of the license key
  4. + *
  5. Characters 3-6 specifies the XMind product this license key is + * generated against: + *
      + *
    • Characters 3 & 4 = the code name of the XMind product vendor
    • + *
    • Characters 5 = the major version number of XMind product + * (Base36 encoded)
    • + *
    • Characters 6 = the minor version number of XMind product + * (Base36 encoded)
    • + *
    + *
  6. + *
  7. Character 7 is the type of the licensee
  8. + *
  9. Character 8 & 9 = the years of free version upgrade + * applied to this license key (Base36 encoded, left padded with 0)
  10. + *
  11. Character 10 is the free months number of the license
  12. + *
  13. Character 11 & 12 = (reserved for future use, currently randomly + * generated and Base36 encoded)
  14. + *
+ * + *

+ * Each type of a license key is bound to a unique method (i.e. + * secure key pair) to verify the license key body. + *

+ * + *

+ * Product info may not be checked restrictly but may be prompted if + * verification fails. + *

+ * + *

+ * It's gauranteed that same license key headers are encoded as the same + * string and different headers as different strings. That is to say, if two + * license key headers are same (or different) as determined by + * {@link #equals(Object)}, they are encoded as the same (or different) + * strings, and vice versa. + *

+ * + * @return the encoded 12-character string of the license key + */ + String toEncoded(); + +} diff --git a/bundles/org.xmind.core.net/.classpath b/bundles/org.xmind.core.net/.classpath index b1dabee38..098194ca4 100644 --- a/bundles/org.xmind.core.net/.classpath +++ b/bundles/org.xmind.core.net/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.core.net/.gitignore b/bundles/org.xmind.core.net/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.net/.gitignore +++ b/bundles/org.xmind.core.net/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.net/.options b/bundles/org.xmind.core.net/.options index a3adec843..9d20f4789 100644 --- a/bundles/org.xmind.core.net/.options +++ b/bundles/org.xmind.core.net/.options @@ -1,3 +1,3 @@ -org.xmind.core.net/debug=false -org.xmind.core.net/debug/http/requests=false -org.xmind.core.net/debug/http/assc=false +org.xmind.core.net/debug=false +org.xmind.core.net/debug/http/requests=false +org.xmind.core.net/debug/http/assc=false diff --git a/bundles/org.xmind.core.net/.project b/bundles/org.xmind.core.net/.project index 68f893f21..bada5e770 100644 --- a/bundles/org.xmind.core.net/.project +++ b/bundles/org.xmind.core.net/.project @@ -1,28 +1,28 @@ - - - org.xmind.core.net - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.core.net + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.core.prefs index d3a3f618c..aa3092cb4 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.core.prefs @@ -1,411 +1,411 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.7 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.core.net/.settings/org.eclipse.ltk.core.refactoring.prefs b/bundles/org.xmind.core.net/.settings/org.eclipse.ltk.core.refactoring.prefs index cfcd1d3c2..b196c64a3 100644 --- a/bundles/org.xmind.core.net/.settings/org.eclipse.ltk.core.refactoring.prefs +++ b/bundles/org.xmind.core.net/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/bundles/org.xmind.core.net/META-INF/MANIFEST.MF b/bundles/org.xmind.core.net/META-INF/MANIFEST.MF index c32371100..28b3e78be 100644 --- a/bundles/org.xmind.core.net/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.net/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.core.net;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.core.net.internal.Activator -Require-Bundle: org.eclipse.core.runtime, - org.json;bundle-version="1.0.0" -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.core.net, - org.xmind.core.net.http, - org.xmind.core.net.internal;x-internal:=true -Bundle-Vendor: %providerName +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.core.net;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.core.net.internal.Activator +Require-Bundle: org.eclipse.core.runtime, + org.json;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.core.net, + org.xmind.core.net.http, + org.xmind.core.net.internal;x-internal:=true +Bundle-Vendor: %providerName diff --git a/bundles/org.xmind.core.net/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.core.net/OSGI-INF/l10n/bundle.properties index 723fbaf01..f6645647d 100644 --- a/bundles/org.xmind.core.net/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.core.net/OSGI-INF/l10n/bundle.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.core.net -providerName = XMind Ltd. +#Properties file for org.xmind.core.net +providerName = XMind Ltd. pluginName = XMind Core Net Plug-in \ No newline at end of file diff --git a/bundles/org.xmind.core.net/build.properties b/bundles/org.xmind.core.net/build.properties index a65755cb2..c58ea2178 100644 --- a/bundles/org.xmind.core.net/build.properties +++ b/bundles/org.xmind.core.net/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ diff --git a/bundles/org.xmind.core.net/pom.xml b/bundles/org.xmind.core.net/pom.xml index 9e92b86ac..bd4a3cb52 100644 --- a/bundles/org.xmind.core.net/pom.xml +++ b/bundles/org.xmind.core.net/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.net - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.net + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/Entity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/Entity.java index 6164c51bd..5d70cc740 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/Entity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/Entity.java @@ -1,30 +1,30 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public interface Entity { - - void writeTo(OutputStream output) throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public interface Entity { + + void writeTo(OutputStream output) throws IOException; + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/Field.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/Field.java index e12aaa1e2..2965ad445 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/Field.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/Field.java @@ -1,69 +1,69 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net; - -import static org.xmind.core.net.internal.EncodingUtils.urlEncode; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class Field { - - public final String name; - - public final Object value; - - private String encodedName = null; - - private String encodedValue = null; - - public Field(String name, Object value) { - this.name = name; - this.value = value; - } - - public String getValue() { - return value == null ? "" : value.toString(); //$NON-NLS-1$ - } - - public String getEncodedName() { - if (encodedName == null) { - encodedName = urlEncode(name); - } - return encodedName; - } - - public String getEncodedValue() { - if (encodedValue == null) { - encodedValue = urlEncode(value); - } - return encodedValue; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return String.format("%s: %s", name, value); //$NON-NLS-1$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net; + +import static org.xmind.core.net.internal.EncodingUtils.urlEncode; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class Field { + + public final String name; + + public final Object value; + + private String encodedName = null; + + private String encodedValue = null; + + public Field(String name, Object value) { + this.name = name; + this.value = value; + } + + public String getValue() { + return value == null ? "" : value.toString(); //$NON-NLS-1$ + } + + public String getEncodedName() { + if (encodedName == null) { + encodedName = urlEncode(name); + } + return encodedName; + } + + public String getEncodedValue() { + if (encodedValue == null) { + encodedValue = urlEncode(value); + } + return encodedValue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String.format("%s: %s", name, value); //$NON-NLS-1$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/FieldSet.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/FieldSet.java index 993728749..984fb88b8 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/FieldSet.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/FieldSet.java @@ -1,299 +1,299 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.runtime.Assert; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class FieldSet implements Iterable { - - private final List fields; - - /** - * - */ - public FieldSet() { - this.fields = new ArrayList(); - } - - /** - * - */ - public FieldSet(Collection fields) { - this.fields = new ArrayList(fields); - } - - public FieldSet(FieldSet source) { - this.fields = (source == null) ? new ArrayList() - : new ArrayList(source.fields); - } - - public boolean has(String name) { - if (name == null) - return false; - for (Field field : fields) { - if (name.equalsIgnoreCase(field.name)) - return true; - } - return false; - } - - public FieldSet put(String name, Object value) { - Assert.isLegal(name != null); - remove(name); - add(name, value); - return this; - } - - public FieldSet add(String name, Object value) { - Assert.isLegal(name != null); - if (value != null) - fields.add(new Field(name, value)); - return this; - } - - public FieldSet putAll(FieldSet source) { - if (source != null) { - for (Field field : source.fields) { - remove(field.name); - fields.add(field); - } - } - return this; - } - - public FieldSet addAll(FieldSet source) { - if (source != null) { - fields.addAll(source.fields); - } - return this; - } - - public FieldSet remove(String name) { - Assert.isLegal(name != null); - Iterator it = fields.iterator(); - while (it.hasNext()) { - Field field = it.next(); - if (name.equalsIgnoreCase(field.name)) { - it.remove(); - } - } - return this; - } - - public Object get(String name) { - if (name != null) { - for (Field field : fields) { - if (name.equalsIgnoreCase(field.name)) - return field.value; - } - } - return null; - } - - public Field get(int index) { - if (index < 0 || index >= fields.size()) - return null; - return fields.get(index); - } - - public String getString(String name) { - Object value = get(name); - return value != null && value instanceof String ? (String) value : null; - } - - public int getInt(String name, int defaultValue) { - Object value = get(name); - return value != null && value instanceof Integer - ? ((Integer) value).intValue() : defaultValue; - } - - /** - * @return the headers - */ - public Collection toList() { - return Collections.unmodifiableCollection(fields); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Iterable#iterator() - */ - public Iterator iterator() { - final Iterator it = fields.iterator(); - return new Iterator() { - - public void remove() { - throw new UnsupportedOperationException(); - } - - public Field next() { - return it.next(); - } - - public boolean hasNext() { - return it.hasNext(); - } - }; - } - - public boolean isEmpty() { - return fields.isEmpty(); - } - - public int size() { - return fields.size(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - for (Field field : fields) { - buffer.append(field.name); - buffer.append(':'); - buffer.append(' '); - buffer.append(field.value); - buffer.append('\r'); - buffer.append('\n'); - } - return buffer.toString(); - } - - public String toSemicolonSeparatedString(boolean quoteValues) { - StringBuilder buffer = new StringBuilder(); - for (Field field : fields) { - if (buffer.length() > 0) { - buffer.append(';'); - buffer.append(' '); - } - buffer.append(field.name); - buffer.append('='); - if (quoteValues) { - buffer.append('"'); - } - buffer.append(field.value); - if (quoteValues) { - buffer.append('"'); - } - } - return buffer.toString(); - } - - public static FieldSet fromSemicolonSeparatedString(String str) { - FieldSet set = new FieldSet(); - String name = null; - String value = null; - StringBuilder buffer = null; - boolean inQuote = false; - - int size = str.length(); - for (int i = 0; i < size; i++) { - char c = str.charAt(i); - if (c == ' ') { - if (inQuote) { - // add it to buffer - } else { - if (buffer == null) { - // skip white spaces - } else if (name == null) { - // name ends, value starts - name = buffer.toString(); - buffer = null; - value = null; - } else { - // value ends - value = (buffer == null) ? "" : buffer.toString(); //$NON-NLS-1$ - set.add(name, value); - name = null; - value = null; - buffer = null; - } - continue; - } - } else if (c == '"') { - inQuote = !inQuote; - continue; - } else if (c == '=') { - if (inQuote) { - // add it to buffer - } else { - // name ends, value starts - name = (buffer == null) ? "" : buffer.toString(); //$NON-NLS-1$ - buffer = null; - value = null; - continue; - } - } else if (c == ';') { - if (inQuote) { - // add it to buffer - } else { - // value ends, name starts - if (buffer != null) { - if (name == null) { - name = buffer.toString(); - value = ""; //$NON-NLS-1$ - } else { - value = buffer.toString(); - } - } - if (name != null) { - set.add(name, value == null ? "" : value); //$NON-NLS-1$ - } - name = null; - value = null; - buffer = null; - continue; - } - } - - if (buffer == null) { - buffer = new StringBuilder(); - } - buffer.append(c); - } - - if (buffer != null) { - if (name == null) { - name = buffer.toString(); - set.add(name, ""); //$NON-NLS-1$ - } else { - value = buffer.toString(); - set.add(name, value); - } - } else if (name != null) { - set.add(name, ""); //$NON-NLS-1$ - } - - return set; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.Assert; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class FieldSet implements Iterable { + + private final List fields; + + /** + * + */ + public FieldSet() { + this.fields = new ArrayList(); + } + + /** + * + */ + public FieldSet(Collection fields) { + this.fields = new ArrayList(fields); + } + + public FieldSet(FieldSet source) { + this.fields = (source == null) ? new ArrayList() + : new ArrayList(source.fields); + } + + public boolean has(String name) { + if (name == null) + return false; + for (Field field : fields) { + if (name.equalsIgnoreCase(field.name)) + return true; + } + return false; + } + + public FieldSet put(String name, Object value) { + Assert.isLegal(name != null); + remove(name); + add(name, value); + return this; + } + + public FieldSet add(String name, Object value) { + Assert.isLegal(name != null); + if (value != null) + fields.add(new Field(name, value)); + return this; + } + + public FieldSet putAll(FieldSet source) { + if (source != null) { + for (Field field : source.fields) { + remove(field.name); + fields.add(field); + } + } + return this; + } + + public FieldSet addAll(FieldSet source) { + if (source != null) { + fields.addAll(source.fields); + } + return this; + } + + public FieldSet remove(String name) { + Assert.isLegal(name != null); + Iterator it = fields.iterator(); + while (it.hasNext()) { + Field field = it.next(); + if (name.equalsIgnoreCase(field.name)) { + it.remove(); + } + } + return this; + } + + public Object get(String name) { + if (name != null) { + for (Field field : fields) { + if (name.equalsIgnoreCase(field.name)) + return field.value; + } + } + return null; + } + + public Field get(int index) { + if (index < 0 || index >= fields.size()) + return null; + return fields.get(index); + } + + public String getString(String name) { + Object value = get(name); + return value != null && value instanceof String ? (String) value : null; + } + + public int getInt(String name, int defaultValue) { + Object value = get(name); + return value != null && value instanceof Integer + ? ((Integer) value).intValue() : defaultValue; + } + + /** + * @return the headers + */ + public Collection toList() { + return Collections.unmodifiableCollection(fields); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Iterable#iterator() + */ + public Iterator iterator() { + final Iterator it = fields.iterator(); + return new Iterator() { + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Field next() { + return it.next(); + } + + public boolean hasNext() { + return it.hasNext(); + } + }; + } + + public boolean isEmpty() { + return fields.isEmpty(); + } + + public int size() { + return fields.size(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + for (Field field : fields) { + buffer.append(field.name); + buffer.append(':'); + buffer.append(' '); + buffer.append(field.value); + buffer.append('\r'); + buffer.append('\n'); + } + return buffer.toString(); + } + + public String toSemicolonSeparatedString(boolean quoteValues) { + StringBuilder buffer = new StringBuilder(); + for (Field field : fields) { + if (buffer.length() > 0) { + buffer.append(';'); + buffer.append(' '); + } + buffer.append(field.name); + buffer.append('='); + if (quoteValues) { + buffer.append('"'); + } + buffer.append(field.value); + if (quoteValues) { + buffer.append('"'); + } + } + return buffer.toString(); + } + + public static FieldSet fromSemicolonSeparatedString(String str) { + FieldSet set = new FieldSet(); + String name = null; + String value = null; + StringBuilder buffer = null; + boolean inQuote = false; + + int size = str.length(); + for (int i = 0; i < size; i++) { + char c = str.charAt(i); + if (c == ' ') { + if (inQuote) { + // add it to buffer + } else { + if (buffer == null) { + // skip white spaces + } else if (name == null) { + // name ends, value starts + name = buffer.toString(); + buffer = null; + value = null; + } else { + // value ends + value = (buffer == null) ? "" : buffer.toString(); //$NON-NLS-1$ + set.add(name, value); + name = null; + value = null; + buffer = null; + } + continue; + } + } else if (c == '"') { + inQuote = !inQuote; + continue; + } else if (c == '=') { + if (inQuote) { + // add it to buffer + } else { + // name ends, value starts + name = (buffer == null) ? "" : buffer.toString(); //$NON-NLS-1$ + buffer = null; + value = null; + continue; + } + } else if (c == ';') { + if (inQuote) { + // add it to buffer + } else { + // value ends, name starts + if (buffer != null) { + if (name == null) { + name = buffer.toString(); + value = ""; //$NON-NLS-1$ + } else { + value = buffer.toString(); + } + } + if (name != null) { + set.add(name, value == null ? "" : value); //$NON-NLS-1$ + } + name = null; + value = null; + buffer = null; + continue; + } + } + + if (buffer == null) { + buffer = new StringBuilder(); + } + buffer.append(c); + } + + if (buffer != null) { + if (name == null) { + name = buffer.toString(); + set.add(name, ""); //$NON-NLS-1$ + } else { + value = buffer.toString(); + set.add(name, value); + } + } else if (name != null) { + set.add(name, ""); //$NON-NLS-1$ + } + + return set; + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/IDataStore.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/IDataStore.java index 7941358ff..80521f3df 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/IDataStore.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/IDataStore.java @@ -1,68 +1,68 @@ -/** - * - */ -package org.xmind.core.net; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public interface IDataStore { - - public static final IDataStore EMPTY = new IDataStore() { - - private final Map noMap = Collections.emptyMap(); - - private final List noChildren = Collections.emptyList(); - - public Map toMap() { - return noMap; - } - - public boolean has(String key) { - return false; - } - - public String getString(String key) { - return null; - } - - public long getLong(String key) { - return 0; - } - - public int getInt(String key) { - return 0; - } - - public double getDouble(String key) { - return 0; - } - - public boolean getBoolean(String key) { - return false; - } - - public List getChildren(String key) { - return noChildren; - } - - }; - - boolean has(String key); - - String getString(String key); - - int getInt(String key); - - boolean getBoolean(String key); - - long getLong(String key); - - double getDouble(String key); - - List getChildren(String key); - - Map toMap(); - +/** + * + */ +package org.xmind.core.net; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public interface IDataStore { + + public static final IDataStore EMPTY = new IDataStore() { + + private final Map noMap = Collections.emptyMap(); + + private final List noChildren = Collections.emptyList(); + + public Map toMap() { + return noMap; + } + + public boolean has(String key) { + return false; + } + + public String getString(String key) { + return null; + } + + public long getLong(String key) { + return 0; + } + + public int getInt(String key) { + return 0; + } + + public double getDouble(String key) { + return 0; + } + + public boolean getBoolean(String key) { + return false; + } + + public List getChildren(String key) { + return noChildren; + } + + }; + + boolean has(String key); + + String getString(String key); + + int getInt(String key); + + boolean getBoolean(String key); + + long getLong(String key); + + double getDouble(String key); + + List getChildren(String key); + + Map toMap(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/JSONStore.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/JSONStore.java index a6f2087fc..e938feb94 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/JSONStore.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/JSONStore.java @@ -1,116 +1,116 @@ -/** - * - */ -package org.xmind.core.net; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.json.JSONArray; -import org.json.JSONObject; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class JSONStore implements IDataStore { - - private JSONObject json; - - public JSONStore(JSONObject json) { - this.json = json; - } - - public JSONObject getJson() { - return json; - } - - public boolean has(String key) { - return json.has(key); - } - - public long getLong(String key) { - return json.optLong(key, 0); - } - - public boolean getBoolean(String key) { - return json.optBoolean(key, false); - } - - public int getInt(String key) { - return json.optInt(key, 0); - } - - public double getDouble(String key) { - return json.optDouble(key, 0); - } - - public String getString(String key) { - Object o = json.opt(key); - return o == null || JSONObject.NULL.equals(o) ? null : o.toString(); - } - - public Map toMap() { - HashMap map = new HashMap(); - Iterator keys = json.keys(); - while (keys.hasNext()) { - Object key = keys.next(); - map.put(key, json.opt((String) key)); - } - return map; - } - - public List getChildren(String key) { - JSONArray array = json.optJSONArray(key); - if (array != null) { - List children = new ArrayList( - array.length()); - for (int i = 0; i < array.length(); i++) { - JSONObject child = array.optJSONObject(i); - children.add(new JSONStore(child)); - } - return children; - } - return EMPTY.getChildren(key); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof JSONStore)) - return false; - JSONStore that = (JSONStore) obj; - return this.json.equals(that.json); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return json.hashCode(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return json.toString(); - } - +/** + * + */ +package org.xmind.core.net; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.json.JSONArray; +import org.json.JSONObject; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class JSONStore implements IDataStore { + + private JSONObject json; + + public JSONStore(JSONObject json) { + this.json = json; + } + + public JSONObject getJson() { + return json; + } + + public boolean has(String key) { + return json.has(key); + } + + public long getLong(String key) { + return json.optLong(key, 0); + } + + public boolean getBoolean(String key) { + return json.optBoolean(key, false); + } + + public int getInt(String key) { + return json.optInt(key, 0); + } + + public double getDouble(String key) { + return json.optDouble(key, 0); + } + + public String getString(String key) { + Object o = json.opt(key); + return o == null || JSONObject.NULL.equals(o) ? null : o.toString(); + } + + public Map toMap() { + HashMap map = new HashMap(); + Iterator keys = json.keys(); + while (keys.hasNext()) { + Object key = keys.next(); + map.put(key, json.opt((String) key)); + } + return map; + } + + public List getChildren(String key) { + JSONArray array = json.optJSONArray(key); + if (array != null) { + List children = new ArrayList( + array.length()); + for (int i = 0; i < array.length(); i++) { + JSONObject child = array.optJSONObject(i); + children.add(new JSONStore(child)); + } + return children; + } + return EMPTY.getChildren(key); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof JSONStore)) + return false; + JSONStore that = (JSONStore) obj; + return this.json.equals(that.json); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return json.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return json.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FileEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FileEntity.java index db4e4b652..1ee7c53f6 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FileEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FileEntity.java @@ -1,62 +1,62 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class FileEntity extends HttpEntity { - - private File file; - - /** - * - */ - public FileEntity(File file) { - this.file = file; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentLength() - */ - @Override - public long getContentLength() { - return file.length(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) - */ - @Override - public void writeTo(OutputStream output) throws IOException { - InputStream input = new FileInputStream(file); - StreamedEntity.transfer(input, output, - StreamedEntity.DEFAULT_BUFFER_SIZE); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class FileEntity extends HttpEntity { + + private File file; + + /** + * + */ + public FileEntity(File file) { + this.file = file; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentLength() + */ + @Override + public long getContentLength() { + return file.length(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) + */ + @Override + public void writeTo(OutputStream output) throws IOException { + InputStream input = new FileInputStream(file); + StreamedEntity.transfer(input, output, + StreamedEntity.DEFAULT_BUFFER_SIZE); + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FormEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FormEntity.java index c5d416c5a..41d09363d 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FormEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/FormEntity.java @@ -1,117 +1,117 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Collection; - -import org.xmind.core.net.Field; -import org.xmind.core.net.FieldSet; -import org.xmind.core.net.internal.EncodingUtils; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class FormEntity extends HttpEntity { - - private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8"; //$NON-NLS-1$ - - private FieldSet parameters; - - /** - * - */ - public FormEntity(FieldSet parameters) { - this.parameters = parameters; - } - - /** - * @return the fields - */ - public FieldSet getParameters() { - return parameters; - } - - private byte[] formData = null; - - private byte[] getFormData() { - if (formData != null) - return formData; - formData = toAsciiBytes(toQueryString(parameters.toList())); - return formData; - } - - public String getContentType() { - return FORM_CONTENT_TYPE; - } - - public long getContentLength() { - return getFormData().length; - } - - public void writeTo(OutputStream stream) throws IOException { - stream.write(getFormData()); - } - - private static String toQueryString(Collection parameters) { - StringBuffer buffer = new StringBuffer(parameters.size() * 15); - for (Field param : parameters) { - if (buffer.length() > 0) { - buffer.append('&'); - } - buffer.append(param.getEncodedName()); - buffer.append('='); - buffer.append(param.getEncodedValue()); - } - return buffer.toString(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try { - writeTo(bytes); - } catch (IOException e) { - throw new AssertionError( - "Failed to dump form data using byte array stream", e); //$NON-NLS-1$ - } finally { - try { - bytes.close(); - } catch (IOException e) { - } - } - try { - return bytes.toString(EncodingUtils.DEFAULT_ENCODING); - } catch (UnsupportedEncodingException e) { - throw EncodingUtils.wrapEncodingException(e, - EncodingUtils.DEFAULT_ENCODING); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; + +import org.xmind.core.net.Field; +import org.xmind.core.net.FieldSet; +import org.xmind.core.net.internal.EncodingUtils; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class FormEntity extends HttpEntity { + + private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8"; //$NON-NLS-1$ + + private FieldSet parameters; + + /** + * + */ + public FormEntity(FieldSet parameters) { + this.parameters = parameters; + } + + /** + * @return the fields + */ + public FieldSet getParameters() { + return parameters; + } + + private byte[] formData = null; + + private byte[] getFormData() { + if (formData != null) + return formData; + formData = toAsciiBytes(toQueryString(parameters.toList())); + return formData; + } + + public String getContentType() { + return FORM_CONTENT_TYPE; + } + + public long getContentLength() { + return getFormData().length; + } + + public void writeTo(OutputStream stream) throws IOException { + stream.write(getFormData()); + } + + private static String toQueryString(Collection parameters) { + StringBuffer buffer = new StringBuffer(parameters.size() * 15); + for (Field param : parameters) { + if (buffer.length() > 0) { + buffer.append('&'); + } + buffer.append(param.getEncodedName()); + buffer.append('='); + buffer.append(param.getEncodedValue()); + } + return buffer.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try { + writeTo(bytes); + } catch (IOException e) { + throw new AssertionError( + "Failed to dump form data using byte array stream", e); //$NON-NLS-1$ + } finally { + try { + bytes.close(); + } catch (IOException e) { + } + } + try { + return bytes.toString(EncodingUtils.DEFAULT_ENCODING); + } catch (UnsupportedEncodingException e) { + throw EncodingUtils.wrapEncodingException(e, + EncodingUtils.DEFAULT_ENCODING); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntity.java index 384b32563..a6d19c10f 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntity.java @@ -1,77 +1,77 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.core.net.Entity; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public abstract class HttpEntity implements Entity { - - private String fileName = null; - - protected HttpEntity() { - super(); - } - - /** - * Returns the content type string. - * - * @return the content type string - */ - public String getContentType() { - return "application/octet-stream"; //$NON-NLS-1$ - } - - /** - * Returns the suggested name for this entity as a file part when used in a - * {@link MultipartEntity}. - * - * @return the suggested file name for this entity - */ - public String getFileName() { - return this.fileName; - } - - /** - * Sets the suggested file name for this entity. - * - * @param fileName - * the name to set - */ - public void setFileName(String fileName) { - this.fileName = fileName; - } - - /** - * Returns the total length (in bytes) of this entity. - * - * @return the total length of this entity - */ - public abstract long getContentLength(); - - /** - * Writes the content of this entity into the output stream. - */ - public abstract void writeTo(OutputStream output) throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.core.net.Entity; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public abstract class HttpEntity implements Entity { + + private String fileName = null; + + protected HttpEntity() { + super(); + } + + /** + * Returns the content type string. + * + * @return the content type string + */ + public String getContentType() { + return "application/octet-stream"; //$NON-NLS-1$ + } + + /** + * Returns the suggested name for this entity as a file part when used in a + * {@link MultipartEntity}. + * + * @return the suggested file name for this entity + */ + public String getFileName() { + return this.fileName; + } + + /** + * Sets the suggested file name for this entity. + * + * @param fileName + * the name to set + */ + public void setFileName(String fileName) { + this.fileName = fileName; + } + + /** + * Returns the total length (in bytes) of this entity. + * + * @return the total length of this entity + */ + public abstract long getContentLength(); + + /** + * Writes the content of this entity into the output stream. + */ + public abstract void writeTo(OutputStream output) throws IOException; + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntityProxy.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntityProxy.java index f7b6b456d..4c7f9aea0 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntityProxy.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpEntityProxy.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class HttpEntityProxy extends HttpEntity { - - private HttpEntity entity; - - private String customContentType; - - /** - * - */ - public HttpEntityProxy(HttpEntity entity, String customContentType) { - this.entity = entity; - this.customContentType = customContentType; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentLength() - */ - @Override - public long getContentLength() { - return entity.getContentLength(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) - */ - @Override - public void writeTo(OutputStream output) throws IOException { - entity.writeTo(output); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentType() - */ - @Override - public String getContentType() { - if (customContentType != null) - return customContentType; - return entity.getContentType(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class HttpEntityProxy extends HttpEntity { + + private HttpEntity entity; + + private String customContentType; + + /** + * + */ + public HttpEntityProxy(HttpEntity entity, String customContentType) { + this.entity = entity; + this.customContentType = customContentType; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentLength() + */ + @Override + public long getContentLength() { + return entity.getContentLength(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) + */ + @Override + public void writeTo(OutputStream output) throws IOException { + entity.writeTo(output); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentType() + */ + @Override + public String getContentType() { + if (customContentType != null) + return customContentType; + return entity.getContentType(); + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpException.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpException.java index 36466c3ea..96eaa7db4 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpException.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpException.java @@ -1,78 +1,78 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class HttpException extends IOException { - - /** - * - */ - private static final long serialVersionUID = -7867134378055860110L; - - private int code; - - private String status; - - private HttpRequest request; - - /** - * - */ - public HttpException(HttpRequest request, Throwable cause) { - this(request, request.getStatusCode(), request.getStatusMessage(), - cause); - } - - /** - * - */ - public HttpException(HttpRequest request, int code, String status, - Throwable cause) { - super(String.format("%s %s", code, status), cause); //$NON-NLS-1$ - this.request = request; - this.code = code; - this.status = status; - } - - /** - * @return the code - */ - public int getCode() { - return code; - } - - /** - * @return the status - */ - public String getStatus() { - return status; - } - - /** - * @return the request - */ - public HttpRequest getRequest() { - return request; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class HttpException extends IOException { + + /** + * + */ + private static final long serialVersionUID = -7867134378055860110L; + + private int code; + + private String status; + + private HttpRequest request; + + /** + * + */ + public HttpException(HttpRequest request, Throwable cause) { + this(request, request.getStatusCode(), request.getStatusMessage(), + cause); + } + + /** + * + */ + public HttpException(HttpRequest request, int code, String status, + Throwable cause) { + super(String.format("%s %s", code, status), cause); //$NON-NLS-1$ + this.request = request; + this.code = code; + this.status = status; + } + + /** + * @return the code + */ + public int getCode() { + return code; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @return the request + */ + public HttpRequest getRequest() { + return request; + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpRequest.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpRequest.java index f56afa234..a7dcb1e94 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpRequest.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpRequest.java @@ -1,899 +1,898 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubMonitor; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.xmind.core.net.Field; -import org.xmind.core.net.FieldSet; -import org.xmind.core.net.internal.Activator; -import org.xmind.core.net.internal.EncodingUtils; -import org.xmind.core.net.internal.FixedLengthInputStream; -import org.xmind.core.net.internal.LoggingOutputStream; -import org.xmind.core.net.internal.MonitoredInputStream; -import org.xmind.core.net.internal.MonitoredOutputStream; -import org.xmind.core.net.internal.TeeInputStream; -import org.xmind.core.net.internal.TeeOutputStream; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class HttpRequest { - - public static final int DEFAULT_PORT = -1; - - public static final String GET = "GET"; //$NON-NLS-1$ - - public static final String POST = "POST"; //$NON-NLS-1$ - - public static final String PUT = "PUT"; //$NON-NLS-1$ - - public static final String DELETE = "DELETE"; //$NON-NLS-1$ - - public static final int HTTP_PREPARING = 0; - - public static final int HTTP_CONNECTING = 1; - - public static final int HTTP_SENDING = 2; - - public static final int HTTP_WAITING = 3; - - public static final int HTTP_RECEIVING = 4; - - public static final int HTTP_ERROR = 999; - - /* 2XX: generally "OK" */ - - /** - * HTTP Status-Code 200: OK. - */ - public static final int HTTP_OK = HttpURLConnection.HTTP_OK; - - /** - * HTTP Status-Code 201: Created. - */ - public static final int HTTP_CREATED = HttpURLConnection.HTTP_CREATED; - - /** - * HTTP Status-Code 202: Accepted. - */ - public static final int HTTP_ACCEPTED = HttpURLConnection.HTTP_ACCEPTED; - - /** - * HTTP Status-Code 203: Non-Authoritative Information. - */ - public static final int HTTP_NOT_AUTHORITATIVE = HttpURLConnection.HTTP_NOT_AUTHORITATIVE; - - /** - * HTTP Status-Code 204: No Content. - */ - public static final int HTTP_NO_CONTENT = HttpURLConnection.HTTP_NO_CONTENT; - - /** - * HTTP Status-Code 205: Reset Content. - */ - public static final int HTTP_RESET = HttpURLConnection.HTTP_RESET; - - /** - * HTTP Status-Code 206: Partial Content. - */ - public static final int HTTP_PARTIAL = HttpURLConnection.HTTP_PARTIAL; - - /* 3XX: relocation/redirect */ - - /** - * HTTP Status-Code 300: Multiple Choices. - */ - public static final int HTTP_MULT_CHOICE = HttpURLConnection.HTTP_MULT_CHOICE; - - /** - * HTTP Status-Code 301: Moved Permanently. - */ - public static final int HTTP_MOVED_PERM = HttpURLConnection.HTTP_MOVED_PERM; - - /** - * HTTP Status-Code 302: Temporary Redirect. - */ - public static final int HTTP_MOVED_TEMP = HttpURLConnection.HTTP_MOVED_TEMP; - - /** - * HTTP Status-Code 303: See Other. - */ - public static final int HTTP_SEE_OTHER = HttpURLConnection.HTTP_SEE_OTHER; - - /** - * HTTP Status-Code 304: Not Modified. - */ - public static final int HTTP_NOT_MODIFIED = HttpURLConnection.HTTP_NOT_MODIFIED; - - /** - * HTTP Status-Code 305: Use Proxy. - */ - public static final int HTTP_USE_PROXY = HttpURLConnection.HTTP_USE_PROXY; - - /* 4XX: client error */ - - /** - * HTTP Status-Code 400: Bad Request. - */ - public static final int HTTP_BAD_REQUEST = HttpURLConnection.HTTP_BAD_REQUEST; - - /** - * HTTP Status-Code 401: Unauthorized. - */ - public static final int HTTP_UNAUTHORIZED = HttpURLConnection.HTTP_UNAUTHORIZED; - - /** - * HTTP Status-Code 402: Payment Required. - */ - public static final int HTTP_PAYMENT_REQUIRED = HttpURLConnection.HTTP_PAYMENT_REQUIRED; - - /** - * HTTP Status-Code 403: Forbidden. - */ - public static final int HTTP_FORBIDDEN = HttpURLConnection.HTTP_FORBIDDEN; - - /** - * HTTP Status-Code 404: Not Found. - */ - public static final int HTTP_NOT_FOUND = HttpURLConnection.HTTP_NOT_FOUND; - - /** - * HTTP Status-Code 405: Method Not Allowed. - */ - public static final int HTTP_BAD_METHOD = HttpURLConnection.HTTP_BAD_METHOD; - - /** - * HTTP Status-Code 406: Not Acceptable. - */ - public static final int HTTP_NOT_ACCEPTABLE = HttpURLConnection.HTTP_NOT_ACCEPTABLE; - - /** - * HTTP Status-Code 407: Proxy Authentication Required. - */ - public static final int HTTP_PROXY_AUTH = HttpURLConnection.HTTP_PROXY_AUTH; - - /** - * HTTP Status-Code 408: Request Time-Out. - */ - public static final int HTTP_CLIENT_TIMEOUT = HttpURLConnection.HTTP_CLIENT_TIMEOUT; - - /** - * HTTP Status-Code 409: Conflict. - */ - public static final int HTTP_CONFLICT = HttpURLConnection.HTTP_CONFLICT; - - /** - * HTTP Status-Code 410: Gone. - */ - public static final int HTTP_GONE = HttpURLConnection.HTTP_GONE; - - /** - * HTTP Status-Code 411: Length Required. - */ - public static final int HTTP_LENGTH_REQUIRED = HttpURLConnection.HTTP_LENGTH_REQUIRED; - - /** - * HTTP Status-Code 412: Precondition Failed. - */ - public static final int HTTP_PRECON_FAILED = HttpURLConnection.HTTP_PRECON_FAILED; - - /** - * HTTP Status-Code 413: Request HttpEntity Too Large. - */ - public static final int HTTP_ENTITY_TOO_LARGE = HttpURLConnection.HTTP_ENTITY_TOO_LARGE; - - /** - * HTTP Status-Code 414: Request-URI Too Large. - */ - public static final int HTTP_REQ_TOO_LONG = HttpURLConnection.HTTP_REQ_TOO_LONG; - - /** - * HTTP Status-Code 415: Unsupported Media Type. - */ - public static final int HTTP_UNSUPPORTED_TYPE = HttpURLConnection.HTTP_UNSUPPORTED_TYPE; - - /* 5XX: server error */ - - /** - * HTTP Status-Code 500: Internal Server Error. - */ - public static final int HTTP_INTERNAL_ERROR = HttpURLConnection.HTTP_INTERNAL_ERROR; - - /** - * HTTP Status-Code 501: Not Implemented. - */ - public static final int HTTP_NOT_IMPLEMENTED = HttpURLConnection.HTTP_NOT_IMPLEMENTED; - - /** - * HTTP Status-Code 502: Bad Gateway. - */ - public static final int HTTP_BAD_GATEWAY = HttpURLConnection.HTTP_BAD_GATEWAY; - - /** - * HTTP Status-Code 503: Service Unavailable. - */ - public static final int HTTP_UNAVAILABLE = HttpURLConnection.HTTP_UNAVAILABLE; - - /** - * HTTP Status-Code 504: Gateway Timeout. - */ - public static final int HTTP_GATEWAY_TIMEOUT = HttpURLConnection.HTTP_GATEWAY_TIMEOUT; - - /** - * HTTP Status-Code 505: HTTP Version Not Supported. - */ - public static final int HTTP_VERSION = HttpURLConnection.HTTP_VERSION; - - /** - * Property name for connect timeout. Value should be a positive integer. - */ - public static final String SETTING_CONNECT_TIMEOUT = "connectTimeout"; //$NON-NLS-1$ - - /** - * Property name for read timeout. Value should be a positive integer. - */ - public static final String SETTING_READ_TIMEOUT = "readTimeout"; //$NON-NLS-1$ - - private static Set VALID_METHODS = new HashSet( - Arrays.asList(GET, PUT, POST, DELETE)); - - private URL url; - - private String method; - - private FieldSet requestHeaders; - - private HttpEntity requestEntity; - - private FieldSet settings; - - private IResponseHandler responseHandler; - - private int statusCode; - - private String statusMessage; - - private FieldSet responseHeaders; - - private boolean debugging; - - private PrintStream logStream; - - private byte[] responseBuffer; - - public HttpRequest(URL url, String method, FieldSet headers, - HttpEntity entity, FieldSet settings, - IResponseHandler responseHandler) { - Assert.isLegal(url != null); - Assert.isLegal(method != null && VALID_METHODS.contains(method)); - this.url = url; - this.method = method; - this.requestHeaders = new FieldSet(headers); - this.requestEntity = entity; - this.settings = new FieldSet(settings); - this.responseHandler = responseHandler; - this.statusCode = HTTP_PREPARING; - this.statusMessage = null; - this.responseHeaders = new FieldSet(); - - boolean forceDebugging = Activator - .isDebugging(Activator.OPTION_HTTP_REQEUSTS); - this.debugging = forceDebugging - || System.getProperty(Activator.CONFIG_DEBUG_HTTP_REQUESTS, - null) != null; - this.logStream = forceDebugging ? System.out : null; - this.responseBuffer = null; - } - - public HttpRequest(boolean https, String host, int port, String path, - FieldSet queries, String ref, String method, FieldSet headers, - HttpEntity entity, FieldSet settings, - IResponseHandler responseHandler) { - this(makeURL(https, host, port, path, queries, ref), method, headers, - entity, settings, responseHandler); - } - - /** - * @return the url - */ - public URL getURL() { - return url; - } - - public String getMethod() { - return method; - } - - /** - * @return the requestEntity - */ - public HttpEntity getRequestEntity() { - return requestEntity; - } - - /** - * @return the requestHeaders - */ - public FieldSet getRequestHeaders() { - return new FieldSet(requestHeaders); - } - - public int getStatusCode() { - return statusCode; - } - - public String getStatusMessage() { - return statusMessage; - } - - /** - * @return the responseHandler - */ - public IResponseHandler getResponseHandler() { - return responseHandler; - } - - public String getResponseAsString() { - if (responseBuffer == null) - return null; - return EncodingUtils.toDefaultString(responseBuffer); - } - - public JSONObject getResponseAsJSON() { - if (responseBuffer == null) - return null; - ByteArrayInputStream input = new ByteArrayInputStream(responseBuffer); - try { - return new JSONObject(new JSONTokener(input)); - } catch (JSONException e) { - // not a valid JSON object - return null; - } finally { - try { - input.close(); - } catch (IOException e) { - } - } - } - - /** - * @return the responseHeaders - */ - public FieldSet getResponseHeaders() { - return new FieldSet(responseHeaders); - } - - public String getResponseHeader(String name) { - return responseHeaders.getString(name); - } - - public void execute(IProgressMonitor monitor) - throws HttpException, InterruptedException { - final SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - if (subMonitor.isCanceled()) - return; - - final boolean[] finished = new boolean[1]; - final Throwable[] exception = new Throwable[1]; - final HttpURLConnection[] connection = new HttpURLConnection[1]; - - log("Preparing...."); //$NON-NLS-1$ - - finished[0] = false; - Thread thread = new Thread(new Runnable() { - - public void run() { - try { - doExecute(subMonitor, connection); - } catch (InterruptedException e) { - subMonitor.setCanceled(true); - } catch (Throwable e) { - exception[0] = e; - } finally { - finished[0] = true; - } - } - }, "HttpRequestSession-" + method + "-" + url.toExternalForm()); //$NON-NLS-1$ //$NON-NLS-2$ - thread.setDaemon(true); - thread.setPriority((Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2); - thread.start(); - - try { - while (!finished[0] && !subMonitor.isCanceled()) { - Thread.sleep(1); - } - } finally { - if (thread != null) { - thread.interrupt(); - } - if (connection[0] != null) { - connection[0].disconnect(); - } - } - - if (subMonitor.isCanceled()) { - log("Canceled."); //$NON-NLS-1$ - throw new InterruptedException(); - } - - if (exception[0] != null) { - Throwable e = exception[0]; - log("Error: {0}", e); //$NON-NLS-1$ - if (e instanceof HttpException) - throw (HttpException) e; - throw new HttpException(this, e); - } - - if (getStatusCode() >= 400) - throw new HttpException(this, null); - } - - private void doExecute(IProgressMonitor monitor, - HttpURLConnection[] _connection) - throws InterruptedException, IOException { - if (monitor.isCanceled()) - return; - - log("Connecting to {0}....", url.getAuthority()); //$NON-NLS-1$ - setStatusCode(HTTP_CONNECTING, "Connecting"); //$NON-NLS-1$ - if (monitor.isCanceled()) - throw new OperationCanceledException(); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - _connection[0] = connection; - - if (monitor.isCanceled()) - throw new InterruptedException(); - - assc(connection); - if (monitor.isCanceled()) - throw new InterruptedException(); - - int connectTimeout = settings.getInt(SETTING_CONNECT_TIMEOUT, -1); - if (connectTimeout >= 0) { - connection.setConnectTimeout(connectTimeout); - } - int readTimeout = settings.getInt(SETTING_READ_TIMEOUT, -1); - if (readTimeout >= 0) { - connection.setReadTimeout(readTimeout); - } - - log("Sending...."); //$NON-NLS-1$ - setStatusCode(HTTP_SENDING, "Sending"); //$NON-NLS-1$ - if (monitor.isCanceled()) - throw new InterruptedException(); - - try { - connection.setDoOutput(requestEntity != null); - if (monitor.isCanceled()) - throw new InterruptedException(); - - connection.setRequestMethod(method); - if (monitor.isCanceled()) - throw new InterruptedException(); - - writeHeaders(connection); - if (monitor.isCanceled()) - throw new InterruptedException(); - - writeBody(monitor, connection); - if (monitor.isCanceled()) - throw new InterruptedException(); - - log("Waiting..."); //$NON-NLS-1$ - setStatusCode(HTTP_WAITING, "Waiting"); //$NON-NLS-1$ - if (monitor.isCanceled()) - throw new InterruptedException(); - - readResponse(monitor, connection, connection.getInputStream(), - connection.getResponseCode(), - connection.getResponseMessage()); - if (monitor.isCanceled()) - throw new InterruptedException(); - } catch (IOException e) { - InputStream errorStream = connection.getErrorStream(); - if (errorStream == null) { - e.printStackTrace(); - log("Error stream is NULL, response state: {0} {1}", //$NON-NLS-1$ - connection.getResponseCode(), - connection.getResponseMessage()); - throw new InterruptedException(); - } else { - readResponse(monitor, connection, errorStream, - connection.getResponseCode(), - connection.getResponseMessage()); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - - private void setStatusCode(int newStatus, String statusMessage) { - this.statusCode = newStatus; - this.statusMessage = statusMessage; - } - - private void writeHeaders(URLConnection connection) { - List writtenHeaders = new ArrayList(); - Object userAgent = null; - for (Field header : requestHeaders) { - writeHeader(connection, header.name, header.getValue(), - writtenHeaders); - if ("User-Agent".equalsIgnoreCase(header.name)) { //$NON-NLS-1$ - userAgent = header.value; - } - } - - if (userAgent == null || "".equals(userAgent)) { //$NON-NLS-1$ - writeHeader(connection, "User-Agent", getDefaultUserAgent(), //$NON-NLS-1$ - writtenHeaders); - } - if (requestEntity != null) { - writeHeader(connection, "Content-Type", //$NON-NLS-1$ - requestEntity.getContentType(), writtenHeaders); - writeHeader(connection, "Content-Length", //$NON-NLS-1$ - String.valueOf(requestEntity.getContentLength()), - writtenHeaders); - } - - log("> {0} {1} HTTP/1.1", method, url.getPath()); //$NON-NLS-1$ - if (debugging) { - for (Field header : writtenHeaders) { - log("> {0}: {1}", header.name, //$NON-NLS-1$ - header.value); - } - } - } - - private void writeHeader(URLConnection connection, String key, String value, - List headers) { - connection.setRequestProperty(key, value); - headers.add(new Field(key, value)); - } - - private static String getDefaultUserAgent() { - String buildId = System.getProperty("org.xmind.product.buildid", //$NON-NLS-1$ - null); - if (buildId == null || "".equals(buildId)) { //$NON-NLS-1$ - Activator p = Activator.getDefault(); - if (p != null) { - buildId = p.getBundle().getVersion().toString(); - } else { - buildId = "unknown"; //$NON-NLS-1$ - } - } - String os = System.getProperty("osgi.os", "OS"); //$NON-NLS-1$ //$NON-NLS-2$ - String arch = System.getProperty("osgi.arch", "ARCH"); //$NON-NLS-1$ //$NON-NLS-2$ - String ws = System.getProperty("osgi.ws", "WS"); //$NON-NLS-1$ //$NON-NLS-2$ - String nl = System.getProperty("osgi.nl", "NL"); //$NON-NLS-1$ //$NON-NLS-2$ - String osName = System.getProperty("os.name", "OS_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ - String osArch = System.getProperty("os.arch", "OS_ARCH"); //$NON-NLS-1$ //$NON-NLS-2$ - String osVersion = System.getProperty("os.version", "OS_VERSION"); //$NON-NLS-1$ //$NON-NLS-2$ - String javaVersion = System.getProperty("java.version", "JAVA_VERSION"); //$NON-NLS-1$ //$NON-NLS-2$ - return String.format( - "XMind/%s (%s.%s.%s; %s Arch/%s Version/%s; %s) Java/%s", //$NON-NLS-1$ - buildId, ws, os, arch, osName, osArch, osVersion, nl, - javaVersion); - } - - private void writeBody(IProgressMonitor monitor, URLConnection connection) - throws InterruptedException, IOException { - if (requestEntity == null) - return; - - OutputStream output = new MonitoredOutputStream( - connection.getOutputStream(), monitor); - if (debugging && logStream != null) { - output = new TeeOutputStream(output, - new LoggingOutputStream(logStream)); - } - try { - requestEntity.writeTo(output); - } catch (OperationCanceledException e) { - throw new InterruptedIOException(); - } - if (debugging && logStream != null) { - logStream.println(); - } - if (monitor.isCanceled()) - throw new InterruptedException(); - - output.flush(); - } - - private void readResponse(IProgressMonitor monitor, - URLConnection connection, InputStream readStream, int responseCode, - String responseMessage) throws InterruptedException, IOException { - if (responseCode < 0) { - responseCode = HTTP_ERROR; - log("Unknown error, maybe not a valid HTTP response."); //$NON-NLS-1$ - setStatusCode(responseCode, responseMessage); - return; - } - - log("< HTTP/1.1 {0} {1}", responseCode, responseMessage); //$NON-NLS-1$ - setStatusCode(responseCode, responseMessage); - if (monitor.isCanceled()) - throw new InterruptedException(); - - readResponseHeaders(connection); - if (monitor.isCanceled()) - throw new InterruptedException(); - - final long totalBytes = getResponseLength(readStream); - if (monitor.isCanceled()) - throw new InterruptedException(); - - log("Receiving {0} bytes...", totalBytes); //$NON-NLS-1$ - - if (totalBytes > 0) { - if (readStream == null) - throw new IOException( - "No input stream available to read response from"); //$NON-NLS-1$ - readStream = new FixedLengthInputStream(readStream, this, - totalBytes); - } - - if (readStream != null) { - if (debugging && logStream != null) { - readStream = new TeeInputStream(readStream, - new LoggingOutputStream(logStream)); - } - ByteArrayOutputStream bufferStream = new ByteArrayOutputStream( - (int) totalBytes); - readStream = new TeeInputStream(readStream, bufferStream); - readStream = new MonitoredInputStream(readStream, monitor); - - if (responseHandler != null) { - final HttpEntity responseEntity = new StreamedEntity(readStream, - totalBytes); - try { - responseHandler.handleResponseEntity(monitor, this, - responseEntity); - } catch (OperationCanceledException e) { - throw new InterruptedException(); - } - } - - /// read until the end of stream to receive all response content - /// TODO potential dead lock? - byte[] temp = new byte[1024]; - while (readStream.read(temp) != -1) { - /// do nothing and wait until the stream is consumed - } - - responseBuffer = bufferStream.toByteArray(); - } - - if (debugging && logStream != null) { - logStream.println(); - } - - log("Handled."); //$NON-NLS-1$ - } - - private long getResponseLength(InputStream readStream) throws IOException { - long totalBytes = -1; - String length = getResponseHeader("Content-Length"); //$NON-NLS-1$ - if (length != null) { - try { - totalBytes = Long.parseLong(length, 10); - } catch (NumberFormatException e) { - } - } - if (totalBytes < 0 && readStream != null) { - totalBytes = readStream.available(); - } - return totalBytes; - } - - /** - * @param connection - */ - private void readResponseHeaders(URLConnection connection) { - // Skip status line: - connection.getHeaderField(0); - // Start from 2nd header line: - int i = 1; - String key, value; - while ((key = connection.getHeaderFieldKey(i)) != null) { - value = connection.getHeaderField(i); - responseHeaders.add(key, value); - log("< {0}: {1}", key, value); //$NON-NLS-1$ - i++; - } - } - - public HttpRequest debug(PrintStream logStream) { - this.debugging = true; - this.logStream = logStream; - return this; - } - - private void log(String format, Object... values) { - if (!debugging) - return; - - String prefix; - if (format.startsWith(">") || format.startsWith("<")) { //$NON-NLS-1$ //$NON-NLS-2$ - prefix = ""; //$NON-NLS-1$ - } else { - prefix = "* "; //$NON-NLS-1$ - } - String message = prefix + MessageFormat.format(format, values); - if (logStream != null) { - logStream.println(message); - } else { - Activator.log(message); - } - } - - private void assc(HttpURLConnection connection) { - if (!Activator.isDebugging(Activator.OPTION_HTTP_ASSC)) - return; - - try { - TrustModifier.relaxHostChecking(connection); - } catch (Exception e) { - if (logStream != null) { - e.printStackTrace(logStream); - } else { - Activator.log(e); - } - } - } - - /** - * A solution to accept self-signed SSL certificates. - *

- * Source came from Craig Flichel's post Ignoring Self-Signed Certificates in Java on Dec 1, 2011. - *

- * - * @author Craig Flichel - */ - private static class TrustModifier { - - private static final TrustingHostnameVerifier TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier(); - private static SSLSocketFactory factory; - - /** - * Call this with any HttpURLConnection, and it will modify the trust - * settings if it is an HTTPS connection. - */ - public static void relaxHostChecking(HttpURLConnection conn) - throws KeyManagementException, NoSuchAlgorithmException, - KeyStoreException { - - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection httpsConnection = (HttpsURLConnection) conn; - SSLSocketFactory factory = prepFactory(httpsConnection); - httpsConnection.setSSLSocketFactory(factory); - httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER); - } - } - - static synchronized SSLSocketFactory prepFactory( - HttpsURLConnection httpsConnection) - throws NoSuchAlgorithmException, KeyStoreException, - KeyManagementException { - - if (factory == null) { - SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ - ctx.init(null, new TrustManager[] { new AlwaysTrustManager() }, - null); - factory = ctx.getSocketFactory(); - } - return factory; - } - - private static final class TrustingHostnameVerifier - implements HostnameVerifier { - - public boolean verify(String hostname, SSLSession session) { - return true; - } - } - - private static class AlwaysTrustManager implements X509TrustManager { - - public void checkClientTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - } - - public void checkServerTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - } - - } - - private static final String PROTOCOL_HTTP = "http"; //$NON-NLS-1$ - private static final String PROTOCOL_HTTPS = "https"; //$NON-NLS-1$ - - private static URL makeURL(boolean https, String host, int port, - String path, FieldSet queries, String ref) { - String protocol = https ? PROTOCOL_HTTPS : PROTOCOL_HTTP; - - String file = (path == null) ? "/" : path; //$NON-NLS-1$ - - if (queries != null) { - file = file + "?" + new FormEntity(queries).toString(); //$NON-NLS-1$ - } - - if (ref != null) { - file = file + "#" + ref; //$NON-NLS-1$ - } - - URL url; - try { - url = new URL(protocol, host, port, file); - } catch (MalformedURLException e) { - throw new AssertionError("Failed creating HTTP URL from components", //$NON-NLS-1$ - e); - } - return url; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.xmind.core.net.Field; +import org.xmind.core.net.FieldSet; +import org.xmind.core.net.internal.Activator; +import org.xmind.core.net.internal.EncodingUtils; +import org.xmind.core.net.internal.FixedLengthInputStream; +import org.xmind.core.net.internal.LoggingOutputStream; +import org.xmind.core.net.internal.MonitoredInputStream; +import org.xmind.core.net.internal.MonitoredOutputStream; +import org.xmind.core.net.internal.TeeInputStream; +import org.xmind.core.net.internal.TeeOutputStream; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class HttpRequest { + + public static final int DEFAULT_PORT = -1; + + public static final String GET = "GET"; //$NON-NLS-1$ + + public static final String POST = "POST"; //$NON-NLS-1$ + + public static final String PUT = "PUT"; //$NON-NLS-1$ + + public static final String DELETE = "DELETE"; //$NON-NLS-1$ + + public static final int HTTP_PREPARING = 0; + + public static final int HTTP_CONNECTING = 1; + + public static final int HTTP_SENDING = 2; + + public static final int HTTP_WAITING = 3; + + public static final int HTTP_RECEIVING = 4; + + public static final int HTTP_ERROR = 999; + + /* 2XX: generally "OK" */ + + /** + * HTTP Status-Code 200: OK. + */ + public static final int HTTP_OK = HttpURLConnection.HTTP_OK; + + /** + * HTTP Status-Code 201: Created. + */ + public static final int HTTP_CREATED = HttpURLConnection.HTTP_CREATED; + + /** + * HTTP Status-Code 202: Accepted. + */ + public static final int HTTP_ACCEPTED = HttpURLConnection.HTTP_ACCEPTED; + + /** + * HTTP Status-Code 203: Non-Authoritative Information. + */ + public static final int HTTP_NOT_AUTHORITATIVE = HttpURLConnection.HTTP_NOT_AUTHORITATIVE; + + /** + * HTTP Status-Code 204: No Content. + */ + public static final int HTTP_NO_CONTENT = HttpURLConnection.HTTP_NO_CONTENT; + + /** + * HTTP Status-Code 205: Reset Content. + */ + public static final int HTTP_RESET = HttpURLConnection.HTTP_RESET; + + /** + * HTTP Status-Code 206: Partial Content. + */ + public static final int HTTP_PARTIAL = HttpURLConnection.HTTP_PARTIAL; + + /* 3XX: relocation/redirect */ + + /** + * HTTP Status-Code 300: Multiple Choices. + */ + public static final int HTTP_MULT_CHOICE = HttpURLConnection.HTTP_MULT_CHOICE; + + /** + * HTTP Status-Code 301: Moved Permanently. + */ + public static final int HTTP_MOVED_PERM = HttpURLConnection.HTTP_MOVED_PERM; + + /** + * HTTP Status-Code 302: Temporary Redirect. + */ + public static final int HTTP_MOVED_TEMP = HttpURLConnection.HTTP_MOVED_TEMP; + + /** + * HTTP Status-Code 303: See Other. + */ + public static final int HTTP_SEE_OTHER = HttpURLConnection.HTTP_SEE_OTHER; + + /** + * HTTP Status-Code 304: Not Modified. + */ + public static final int HTTP_NOT_MODIFIED = HttpURLConnection.HTTP_NOT_MODIFIED; + + /** + * HTTP Status-Code 305: Use Proxy. + */ + public static final int HTTP_USE_PROXY = HttpURLConnection.HTTP_USE_PROXY; + + /* 4XX: client error */ + + /** + * HTTP Status-Code 400: Bad Request. + */ + public static final int HTTP_BAD_REQUEST = HttpURLConnection.HTTP_BAD_REQUEST; + + /** + * HTTP Status-Code 401: Unauthorized. + */ + public static final int HTTP_UNAUTHORIZED = HttpURLConnection.HTTP_UNAUTHORIZED; + + /** + * HTTP Status-Code 402: Payment Required. + */ + public static final int HTTP_PAYMENT_REQUIRED = HttpURLConnection.HTTP_PAYMENT_REQUIRED; + + /** + * HTTP Status-Code 403: Forbidden. + */ + public static final int HTTP_FORBIDDEN = HttpURLConnection.HTTP_FORBIDDEN; + + /** + * HTTP Status-Code 404: Not Found. + */ + public static final int HTTP_NOT_FOUND = HttpURLConnection.HTTP_NOT_FOUND; + + /** + * HTTP Status-Code 405: Method Not Allowed. + */ + public static final int HTTP_BAD_METHOD = HttpURLConnection.HTTP_BAD_METHOD; + + /** + * HTTP Status-Code 406: Not Acceptable. + */ + public static final int HTTP_NOT_ACCEPTABLE = HttpURLConnection.HTTP_NOT_ACCEPTABLE; + + /** + * HTTP Status-Code 407: Proxy Authentication Required. + */ + public static final int HTTP_PROXY_AUTH = HttpURLConnection.HTTP_PROXY_AUTH; + + /** + * HTTP Status-Code 408: Request Time-Out. + */ + public static final int HTTP_CLIENT_TIMEOUT = HttpURLConnection.HTTP_CLIENT_TIMEOUT; + + /** + * HTTP Status-Code 409: Conflict. + */ + public static final int HTTP_CONFLICT = HttpURLConnection.HTTP_CONFLICT; + + /** + * HTTP Status-Code 410: Gone. + */ + public static final int HTTP_GONE = HttpURLConnection.HTTP_GONE; + + /** + * HTTP Status-Code 411: Length Required. + */ + public static final int HTTP_LENGTH_REQUIRED = HttpURLConnection.HTTP_LENGTH_REQUIRED; + + /** + * HTTP Status-Code 412: Precondition Failed. + */ + public static final int HTTP_PRECON_FAILED = HttpURLConnection.HTTP_PRECON_FAILED; + + /** + * HTTP Status-Code 413: Request HttpEntity Too Large. + */ + public static final int HTTP_ENTITY_TOO_LARGE = HttpURLConnection.HTTP_ENTITY_TOO_LARGE; + + /** + * HTTP Status-Code 414: Request-URI Too Large. + */ + public static final int HTTP_REQ_TOO_LONG = HttpURLConnection.HTTP_REQ_TOO_LONG; + + /** + * HTTP Status-Code 415: Unsupported Media Type. + */ + public static final int HTTP_UNSUPPORTED_TYPE = HttpURLConnection.HTTP_UNSUPPORTED_TYPE; + + /* 5XX: server error */ + + /** + * HTTP Status-Code 500: Internal Server Error. + */ + public static final int HTTP_INTERNAL_ERROR = HttpURLConnection.HTTP_INTERNAL_ERROR; + + /** + * HTTP Status-Code 501: Not Implemented. + */ + public static final int HTTP_NOT_IMPLEMENTED = HttpURLConnection.HTTP_NOT_IMPLEMENTED; + + /** + * HTTP Status-Code 502: Bad Gateway. + */ + public static final int HTTP_BAD_GATEWAY = HttpURLConnection.HTTP_BAD_GATEWAY; + + /** + * HTTP Status-Code 503: Service Unavailable. + */ + public static final int HTTP_UNAVAILABLE = HttpURLConnection.HTTP_UNAVAILABLE; + + /** + * HTTP Status-Code 504: Gateway Timeout. + */ + public static final int HTTP_GATEWAY_TIMEOUT = HttpURLConnection.HTTP_GATEWAY_TIMEOUT; + + /** + * HTTP Status-Code 505: HTTP Version Not Supported. + */ + public static final int HTTP_VERSION = HttpURLConnection.HTTP_VERSION; + + /** + * Property name for connect timeout. Value should be a positive integer. + */ + public static final String SETTING_CONNECT_TIMEOUT = "connectTimeout"; //$NON-NLS-1$ + + /** + * Property name for read timeout. Value should be a positive integer. + */ + public static final String SETTING_READ_TIMEOUT = "readTimeout"; //$NON-NLS-1$ + + private static Set VALID_METHODS = new HashSet( + Arrays.asList(GET, PUT, POST, DELETE)); + + private URL url; + + private String method; + + private FieldSet requestHeaders; + + private HttpEntity requestEntity; + + private FieldSet settings; + + private IResponseHandler responseHandler; + + private int statusCode; + + private String statusMessage; + + private FieldSet responseHeaders; + + private boolean debugging; + + private PrintStream logStream; + + private byte[] responseBuffer; + + public HttpRequest(URL url, String method, FieldSet headers, + HttpEntity entity, FieldSet settings, + IResponseHandler responseHandler) { + Assert.isLegal(url != null); + Assert.isLegal(method != null && VALID_METHODS.contains(method)); + this.url = url; + this.method = method; + this.requestHeaders = new FieldSet(headers); + this.requestEntity = entity; + this.settings = new FieldSet(settings); + this.responseHandler = responseHandler; + this.statusCode = HTTP_PREPARING; + this.statusMessage = null; + this.responseHeaders = new FieldSet(); + + boolean forceDebugging = Activator + .isDebugging(Activator.OPTION_HTTP_REQEUSTS); + this.debugging = forceDebugging + || System.getProperty(Activator.CONFIG_DEBUG_HTTP_REQUESTS, + null) != null; + this.logStream = forceDebugging ? System.out : null; + this.responseBuffer = null; + } + + public HttpRequest(boolean https, String host, int port, String path, + FieldSet queries, String ref, String method, FieldSet headers, + HttpEntity entity, FieldSet settings, + IResponseHandler responseHandler) { + this(makeURL(https, host, port, path, queries, ref), method, headers, + entity, settings, responseHandler); + } + + /** + * @return the url + */ + public URL getURL() { + return url; + } + + public String getMethod() { + return method; + } + + /** + * @return the requestEntity + */ + public HttpEntity getRequestEntity() { + return requestEntity; + } + + /** + * @return the requestHeaders + */ + public FieldSet getRequestHeaders() { + return new FieldSet(requestHeaders); + } + + public int getStatusCode() { + return statusCode; + } + + public String getStatusMessage() { + return statusMessage; + } + + /** + * @return the responseHandler + */ + public IResponseHandler getResponseHandler() { + return responseHandler; + } + + public String getResponseAsString() { + if (responseBuffer == null) + return null; + return EncodingUtils.toDefaultString(responseBuffer); + } + + public JSONObject getResponseAsJSON() { + if (responseBuffer == null) + return null; + ByteArrayInputStream input = new ByteArrayInputStream(responseBuffer); + try { + return new JSONObject(new JSONTokener(input)); + } catch (JSONException e) { + // not a valid JSON object + return null; + } finally { + try { + input.close(); + } catch (IOException e) { + } + } + } + + /** + * @return the responseHeaders + */ + public FieldSet getResponseHeaders() { + return new FieldSet(responseHeaders); + } + + public String getResponseHeader(String name) { + return responseHeaders.getString(name); + } + + public void execute(IProgressMonitor monitor) + throws HttpException, InterruptedException { + final SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + if (subMonitor.isCanceled()) + return; + + final boolean[] finished = new boolean[1]; + final Throwable[] exception = new Throwable[1]; + final HttpURLConnection[] connection = new HttpURLConnection[1]; + + log("Preparing...."); //$NON-NLS-1$ + + finished[0] = false; + Thread thread = new Thread(new Runnable() { + + public void run() { + try { + doExecute(subMonitor, connection); + } catch (InterruptedException e) { + subMonitor.setCanceled(true); + } catch (Throwable e) { + exception[0] = e; + } finally { + finished[0] = true; + } + } + }, "HttpRequestSession-" + method + "-" + url.toExternalForm()); //$NON-NLS-1$ //$NON-NLS-2$ + thread.setDaemon(true); + thread.setPriority((Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2); + thread.start(); + + try { + while (!finished[0] && !subMonitor.isCanceled()) { + Thread.sleep(1); + } + } finally { + if (thread != null) { + thread.interrupt(); + } + if (connection[0] != null) { + connection[0].disconnect(); + } + } + + if (subMonitor.isCanceled()) { + log("Canceled."); //$NON-NLS-1$ + throw new InterruptedException(); + } + + if (exception[0] != null) { + Throwable e = exception[0]; + log("Error: {0}", e); //$NON-NLS-1$ + if (e instanceof HttpException) + throw (HttpException) e; + throw new HttpException(this, e); + } + + if (getStatusCode() >= 400) + throw new HttpException(this, null); + } + + private void doExecute(IProgressMonitor monitor, + HttpURLConnection[] _connection) + throws InterruptedException, IOException { + if (monitor.isCanceled()) + return; + + log("Connecting to {0}....", url.getAuthority()); //$NON-NLS-1$ + setStatusCode(HTTP_CONNECTING, "Connecting"); //$NON-NLS-1$ + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + _connection[0] = connection; + + if (monitor.isCanceled()) + throw new InterruptedException(); + + assc(connection); + if (monitor.isCanceled()) + throw new InterruptedException(); + + int connectTimeout = settings.getInt(SETTING_CONNECT_TIMEOUT, -1); + if (connectTimeout >= 0) { + connection.setConnectTimeout(connectTimeout); + } + int readTimeout = settings.getInt(SETTING_READ_TIMEOUT, -1); + if (readTimeout >= 0) { + connection.setReadTimeout(readTimeout); + } + + log("Sending...."); //$NON-NLS-1$ + setStatusCode(HTTP_SENDING, "Sending"); //$NON-NLS-1$ + if (monitor.isCanceled()) + throw new InterruptedException(); + + try { + connection.setDoOutput(requestEntity != null); + if (monitor.isCanceled()) + throw new InterruptedException(); + + connection.setRequestMethod(method); + if (monitor.isCanceled()) + throw new InterruptedException(); + + writeHeaders(connection); + if (monitor.isCanceled()) + throw new InterruptedException(); + + writeBody(monitor, connection); + if (monitor.isCanceled()) + throw new InterruptedException(); + + log("Waiting..."); //$NON-NLS-1$ + setStatusCode(HTTP_WAITING, "Waiting"); //$NON-NLS-1$ + if (monitor.isCanceled()) + throw new InterruptedException(); + + readResponse(monitor, connection, connection.getInputStream(), + connection.getResponseCode(), + connection.getResponseMessage()); + if (monitor.isCanceled()) + throw new InterruptedException(); + } catch (IOException e) { + InputStream errorStream = connection.getErrorStream(); + if (errorStream == null) { + e.printStackTrace(); + log("Error stream is NULL, response state: {0} {1}", //$NON-NLS-1$ + connection.getResponseCode(), + connection.getResponseMessage()); + } else { + readResponse(monitor, connection, errorStream, + connection.getResponseCode(), + connection.getResponseMessage()); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + private void setStatusCode(int newStatus, String statusMessage) { + this.statusCode = newStatus; + this.statusMessage = statusMessage; + } + + private void writeHeaders(URLConnection connection) { + List writtenHeaders = new ArrayList(); + Object userAgent = null; + for (Field header : requestHeaders) { + writeHeader(connection, header.name, header.getValue(), + writtenHeaders); + if ("User-Agent".equalsIgnoreCase(header.name)) { //$NON-NLS-1$ + userAgent = header.value; + } + } + + if (userAgent == null || "".equals(userAgent)) { //$NON-NLS-1$ + writeHeader(connection, "User-Agent", getDefaultUserAgent(), //$NON-NLS-1$ + writtenHeaders); + } + if (requestEntity != null) { + writeHeader(connection, "Content-Type", //$NON-NLS-1$ + requestEntity.getContentType(), writtenHeaders); + writeHeader(connection, "Content-Length", //$NON-NLS-1$ + String.valueOf(requestEntity.getContentLength()), + writtenHeaders); + } + + log("> {0} {1} HTTP/1.1", method, url.getPath()); //$NON-NLS-1$ + if (debugging) { + for (Field header : writtenHeaders) { + log("> {0}: {1}", header.name, //$NON-NLS-1$ + header.value); + } + } + } + + private void writeHeader(URLConnection connection, String key, String value, + List headers) { + connection.setRequestProperty(key, value); + headers.add(new Field(key, value)); + } + + private static String getDefaultUserAgent() { + String buildId = System.getProperty("org.xmind.product.buildid", //$NON-NLS-1$ + null); + if (buildId == null || "".equals(buildId)) { //$NON-NLS-1$ + Activator p = Activator.getDefault(); + if (p != null) { + buildId = p.getBundle().getVersion().toString(); + } else { + buildId = "unknown"; //$NON-NLS-1$ + } + } + String os = System.getProperty("osgi.os", "OS"); //$NON-NLS-1$ //$NON-NLS-2$ + String arch = System.getProperty("osgi.arch", "ARCH"); //$NON-NLS-1$ //$NON-NLS-2$ + String ws = System.getProperty("osgi.ws", "WS"); //$NON-NLS-1$ //$NON-NLS-2$ + String nl = System.getProperty("osgi.nl", "NL"); //$NON-NLS-1$ //$NON-NLS-2$ + String osName = System.getProperty("os.name", "OS_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ + String osArch = System.getProperty("os.arch", "OS_ARCH"); //$NON-NLS-1$ //$NON-NLS-2$ + String osVersion = System.getProperty("os.version", "OS_VERSION"); //$NON-NLS-1$ //$NON-NLS-2$ + String javaVersion = System.getProperty("java.version", "JAVA_VERSION"); //$NON-NLS-1$ //$NON-NLS-2$ + return String.format( + "XMind/%s (%s.%s.%s; %s Arch/%s Version/%s; %s) Java/%s", //$NON-NLS-1$ + buildId, ws, os, arch, osName, osArch, osVersion, nl, + javaVersion); + } + + private void writeBody(IProgressMonitor monitor, URLConnection connection) + throws InterruptedException, IOException { + if (requestEntity == null) + return; + + OutputStream output = new MonitoredOutputStream( + connection.getOutputStream(), monitor); + if (debugging && logStream != null) { + output = new TeeOutputStream(output, + new LoggingOutputStream(logStream)); + } + try { + requestEntity.writeTo(output); + } catch (OperationCanceledException e) { + throw new InterruptedIOException(); + } + if (debugging && logStream != null) { + logStream.println(); + } + if (monitor.isCanceled()) + throw new InterruptedException(); + + output.flush(); + } + + private void readResponse(IProgressMonitor monitor, + URLConnection connection, InputStream readStream, int responseCode, + String responseMessage) throws InterruptedException, IOException { + if (responseCode < 0) { + responseCode = HTTP_ERROR; + log("Unknown error, maybe not a valid HTTP response."); //$NON-NLS-1$ + setStatusCode(responseCode, responseMessage); + return; + } + + log("< HTTP/1.1 {0} {1}", responseCode, responseMessage); //$NON-NLS-1$ + setStatusCode(responseCode, responseMessage); + if (monitor.isCanceled()) + throw new InterruptedException(); + + readResponseHeaders(connection); + if (monitor.isCanceled()) + throw new InterruptedException(); + + final long totalBytes = getResponseLength(readStream); + if (monitor.isCanceled()) + throw new InterruptedException(); + + log("Receiving {0} bytes...", totalBytes); //$NON-NLS-1$ + + if (totalBytes > 0) { + if (readStream == null) + throw new IOException( + "No input stream available to read response from"); //$NON-NLS-1$ + readStream = new FixedLengthInputStream(readStream, this, + totalBytes); + } + + if (readStream != null) { + if (debugging && logStream != null) { + readStream = new TeeInputStream(readStream, + new LoggingOutputStream(logStream)); + } + ByteArrayOutputStream bufferStream = new ByteArrayOutputStream( + (int) totalBytes); + readStream = new TeeInputStream(readStream, bufferStream); + readStream = new MonitoredInputStream(readStream, monitor); + + if (responseHandler != null) { + final HttpEntity responseEntity = new StreamedEntity(readStream, + totalBytes); + try { + responseHandler.handleResponseEntity(monitor, this, + responseEntity); + } catch (OperationCanceledException e) { + throw new InterruptedException(); + } + } + + /// read until the end of stream to receive all response content + /// TODO potential dead lock? + byte[] temp = new byte[1024]; + while (readStream.read(temp) != -1) { + /// do nothing and wait until the stream is consumed + } + + responseBuffer = bufferStream.toByteArray(); + } + + if (debugging && logStream != null) { + logStream.println(); + } + + log("Handled."); //$NON-NLS-1$ + } + + private long getResponseLength(InputStream readStream) throws IOException { + long totalBytes = -1; + String length = getResponseHeader("Content-Length"); //$NON-NLS-1$ + if (length != null) { + try { + totalBytes = Long.parseLong(length, 10); + } catch (NumberFormatException e) { + } + } + if (totalBytes < 0 && readStream != null) { + totalBytes = readStream.available(); + } + return totalBytes; + } + + /** + * @param connection + */ + private void readResponseHeaders(URLConnection connection) { + // Skip status line: + connection.getHeaderField(0); + // Start from 2nd header line: + int i = 1; + String key, value; + while ((key = connection.getHeaderFieldKey(i)) != null) { + value = connection.getHeaderField(i); + responseHeaders.add(key, value); + log("< {0}: {1}", key, value); //$NON-NLS-1$ + i++; + } + } + + public HttpRequest debug(PrintStream logStream) { + this.debugging = true; + this.logStream = logStream; + return this; + } + + private void log(String format, Object... values) { + if (!debugging) + return; + + String prefix; + if (format.startsWith(">") || format.startsWith("<")) { //$NON-NLS-1$ //$NON-NLS-2$ + prefix = ""; //$NON-NLS-1$ + } else { + prefix = "* "; //$NON-NLS-1$ + } + String message = prefix + MessageFormat.format(format, values); + if (logStream != null) { + logStream.println(message); + } else { + Activator.log(message); + } + } + + private void assc(HttpURLConnection connection) { + if (!Activator.isDebugging(Activator.OPTION_HTTP_ASSC)) + return; + + try { + TrustModifier.relaxHostChecking(connection); + } catch (Exception e) { + if (logStream != null) { + e.printStackTrace(logStream); + } else { + Activator.log(e); + } + } + } + + /** + * A solution to accept self-signed SSL certificates. + *

+ * Source came from Craig Flichel's post Ignoring Self-Signed Certificates in Java on Dec 1, 2011. + *

+ * + * @author Craig Flichel + */ + private static class TrustModifier { + + private static final TrustingHostnameVerifier TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier(); + private static SSLSocketFactory factory; + + /** + * Call this with any HttpURLConnection, and it will modify the trust + * settings if it is an HTTPS connection. + */ + public static void relaxHostChecking(HttpURLConnection conn) + throws KeyManagementException, NoSuchAlgorithmException, + KeyStoreException { + + if (conn instanceof HttpsURLConnection) { + HttpsURLConnection httpsConnection = (HttpsURLConnection) conn; + SSLSocketFactory factory = prepFactory(httpsConnection); + httpsConnection.setSSLSocketFactory(factory); + httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER); + } + } + + static synchronized SSLSocketFactory prepFactory( + HttpsURLConnection httpsConnection) + throws NoSuchAlgorithmException, KeyStoreException, + KeyManagementException { + + if (factory == null) { + SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ + ctx.init(null, new TrustManager[] { new AlwaysTrustManager() }, + null); + factory = ctx.getSocketFactory(); + } + return factory; + } + + private static final class TrustingHostnameVerifier + implements HostnameVerifier { + + public boolean verify(String hostname, SSLSession session) { + return true; + } + } + + private static class AlwaysTrustManager implements X509TrustManager { + + public void checkClientTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + } + + } + + private static final String PROTOCOL_HTTP = "http"; //$NON-NLS-1$ + private static final String PROTOCOL_HTTPS = "https"; //$NON-NLS-1$ + + private static URL makeURL(boolean https, String host, int port, + String path, FieldSet queries, String ref) { + String protocol = https ? PROTOCOL_HTTPS : PROTOCOL_HTTP; + + String file = (path == null) ? "/" : path; //$NON-NLS-1$ + + if (queries != null) { + file = file + "?" + new FormEntity(queries).toString(); //$NON-NLS-1$ + } + + if (ref != null) { + file = file + "#" + ref; //$NON-NLS-1$ + } + + URL url; + try { + url = new URL(protocol, host, port, file); + } catch (MalformedURLException e) { + throw new AssertionError("Failed creating HTTP URL from components", //$NON-NLS-1$ + e); + } + return url; + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/IResponseHandler.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/IResponseHandler.java index 6f6323cab..742c8c86b 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/IResponseHandler.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/IResponseHandler.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IResponseHandler { - - void handleResponseEntity(IProgressMonitor monitor, HttpRequest request, - HttpEntity entity) throws InterruptedException, IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IResponseHandler { + + void handleResponseEntity(IProgressMonitor monitor, HttpRequest request, + HttpEntity entity) throws InterruptedException, IOException; + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/JSONEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/JSONEntity.java index 5d5357595..7fdcd0ab7 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/JSONEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/JSONEntity.java @@ -1,99 +1,99 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; -import java.io.OutputStream; - -import org.json.JSONObject; -import org.xmind.core.net.internal.EncodingUtils; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class JSONEntity extends HttpEntity { - - public static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8"; //$NON-NLS-1$ - - private JSONObject object; - - private boolean pretty; - - private String json; - - /** - * - */ - public JSONEntity(JSONObject object) { - this(object, false); - } - - /** - * - */ - public JSONEntity(JSONObject object, boolean pretty) { - this.object = object; - this.pretty = pretty; - this.json = null; - } - - /** - * @return the json - */ - public String getJSON() { - if (json == null) { - if (pretty) { - json = object.toString(4); - } else { - json = object.toString(); - } - } - return json; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentType() - */ - @Override - public String getContentType() { - return CONTENT_TYPE_JSON; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentLength() - */ - @Override - public long getContentLength() { - return EncodingUtils.toDefaultBytes(getJSON()).length; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) - */ - @Override - public void writeTo(OutputStream output) throws IOException { - output.write(EncodingUtils.toDefaultBytes(getJSON())); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; +import java.io.OutputStream; + +import org.json.JSONObject; +import org.xmind.core.net.internal.EncodingUtils; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class JSONEntity extends HttpEntity { + + public static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8"; //$NON-NLS-1$ + + private JSONObject object; + + private boolean pretty; + + private String json; + + /** + * + */ + public JSONEntity(JSONObject object) { + this(object, false); + } + + /** + * + */ + public JSONEntity(JSONObject object, boolean pretty) { + this.object = object; + this.pretty = pretty; + this.json = null; + } + + /** + * @return the json + */ + public String getJSON() { + if (json == null) { + if (pretty) { + json = object.toString(4); + } else { + json = object.toString(); + } + } + return json; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentType() + */ + @Override + public String getContentType() { + return CONTENT_TYPE_JSON; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentLength() + */ + @Override + public long getContentLength() { + return EncodingUtils.toDefaultBytes(getJSON()).length; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#writeTo(java.io.OutputStream) + */ + @Override + public void writeTo(OutputStream output) throws IOException { + output.write(EncodingUtils.toDefaultBytes(getJSON())); + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/MultipartEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/MultipartEntity.java index d3c9eb74e..1e65c9841 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/MultipartEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/MultipartEntity.java @@ -1,240 +1,240 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Random; - -import org.xmind.core.net.Field; -import org.xmind.core.net.FieldSet; -import org.xmind.core.net.internal.EncodingUtils; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class MultipartEntity extends HttpEntity { - - private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data; boundary="; //$NON-NLS-1$ - - /** - * The pool of ASCII chars to be used for generating a multipart boundary. - */ - private static final byte[] BOUNDARY_CHARS = toAsciiBytes( - "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); //$NON-NLS-1$ - - /** Carriage return/linefeed as a byte array */ - private static final byte[] CRLF = toAsciiBytes("\r\n"); //$NON-NLS-1$ - - /** Content dispostion as a byte array */ - private static final byte[] QUOTE = toAsciiBytes("\""); //$NON-NLS-1$ - - /** Extra characters as a byte array */ - private static final byte[] EXTRA = toAsciiBytes("--"); //$NON-NLS-1$ - - /** Content dispostion as a byte array */ - private static final byte[] CONTENT_DISPOSITION = toAsciiBytes( - "Content-Disposition: form-data; name="); //$NON-NLS-1$ - - /** Content type header as a byte array */ - private static final byte[] CONTENT_TYPE = toAsciiBytes("Content-Type: "); //$NON-NLS-1$ - - /** Content type header as a byte array */ - private static final byte[] CONTENT_TRANSFER_ENCODING = toAsciiBytes( - "Content-Transfer-Encoding: "); //$NON-NLS-1$ - - /** Attachment's file name as a byte array */ - private static final byte[] FILE_NAME = toAsciiBytes("; filename="); //$NON-NLS-1$ - - private static final byte[] TEXT_CONTENT_TYPE = toAsciiBytes( - "text/plain; charset=utf-8"); //$NON-NLS-1$ - - private static final byte[] FILE_TRANSFER_ENCODING = toAsciiBytes("binary"); //$NON-NLS-1$ - - private static final byte[] TEXT_TRANSFER_ENCODING = toAsciiBytes("8bit"); //$NON-NLS-1$ - - private FieldSet parts; - - private byte[] boundary = null; - - /** - * - */ - public MultipartEntity(FieldSet parts) { - this.parts = parts; - } - - /** - * @return the parts - */ - public FieldSet getParts() { - return parts; - } - - private byte[] getBoundary() { - if (boundary != null) - return boundary; - Random rand = new Random(); - byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size - // from 30 to 40 - for (int i = 0; i < bytes.length; i++) { - bytes[i] = BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]; - } - boundary = bytes; - return boundary; - } - - public String getContentType() { - StringBuffer typeBuffer = new StringBuffer(MULTIPART_CONTENT_TYPE); - typeBuffer.append(EncodingUtils.toAsciiString(getBoundary())); - return typeBuffer.toString(); - } - - private static String toSafeName(String name) { - return name.replaceAll("\"", "%22"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public long getContentLength() { - if (parts.isEmpty()) - return 0; - long length = 0; - for (Field part : parts) { - length += EXTRA.length; - length += getBoundary().length; - length += CRLF.length; - - length += CONTENT_DISPOSITION.length; - length += QUOTE.length; - length += toAsciiBytes(toSafeName(part.name)).length; - length += QUOTE.length; - length += CRLF.length; - - if (part.value instanceof HttpEntity) { - String fileName = ((HttpEntity) part.value).getFileName(); - if (fileName == null) - fileName = part.name; - length += FILE_NAME.length; - length += QUOTE.length; - length += toAsciiBytes(toSafeName(fileName)).length; - length += QUOTE.length; - } - - length += CONTENT_TYPE.length; - length += getContentType(part.value).length; - length += CRLF.length; - - length += CONTENT_TRANSFER_ENCODING.length; - length += getTransferEncoding(part.value).length; - length += CRLF.length; - length += CRLF.length; - - length += getPartDataLength(part); - - length += CRLF.length; - - } - - length += EXTRA.length; - length += getBoundary().length; - length += EXTRA.length; - length += CRLF.length; - return length; - } - - public void writeTo(OutputStream stream) throws IOException { - if (parts.isEmpty()) - return; - - for (Field part : parts) { - stream.write(EXTRA); - stream.write(getBoundary()); - stream.write(CRLF); - - stream.write(CONTENT_DISPOSITION); - stream.write(QUOTE); - stream.write(toAsciiBytes(toSafeName(part.name))); - stream.write(QUOTE); - if (part.value instanceof HttpEntity) { - String fileName = ((HttpEntity) part.value).getFileName(); - if (fileName == null) - fileName = part.name; - stream.write(FILE_NAME); - stream.write(QUOTE); - stream.write(toAsciiBytes(toSafeName(fileName))); - stream.write(QUOTE); - } - stream.write(CRLF); - - stream.write(CONTENT_TYPE); - stream.write(getContentType(part.value)); - stream.write(CRLF); - - stream.write(CONTENT_TRANSFER_ENCODING); - stream.write(getTransferEncoding(part.value)); - stream.write(CRLF); - stream.write(CRLF); - - writePartData(stream, part); - - stream.write(CRLF); - } - - stream.write(EXTRA); - stream.write(getBoundary()); - stream.write(EXTRA); - stream.write(CRLF); - } - - private static byte[] getContentType(Object value) { - if (value instanceof HttpEntity) - return EncodingUtils - .toAsciiBytes(((HttpEntity) value).getContentType()); - return TEXT_CONTENT_TYPE; - } - - private static byte[] getTransferEncoding(Object value) { - if (value instanceof HttpEntity) - return FILE_TRANSFER_ENCODING; - return TEXT_TRANSFER_ENCODING; - } - - private static long getPartDataLength(Field part) { - if (part.value instanceof HttpEntity) { - return ((HttpEntity) part.value).getContentLength(); - } - return toAsciiBytes(part.getValue()).length; - } - - private static void writePartData(OutputStream stream, Field part) - throws IOException { - if (part.value instanceof HttpEntity) { - ((HttpEntity) part.value).writeTo(stream); - } else { - writeFromText(stream, part.getValue()); - } - } - - private static void writeFromText(OutputStream writeStream, - String encodedText) throws IOException { - writeStream.write(encodedText.getBytes("UTF-8")); //$NON-NLS-1$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Random; + +import org.xmind.core.net.Field; +import org.xmind.core.net.FieldSet; +import org.xmind.core.net.internal.EncodingUtils; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class MultipartEntity extends HttpEntity { + + private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data; boundary="; //$NON-NLS-1$ + + /** + * The pool of ASCII chars to be used for generating a multipart boundary. + */ + private static final byte[] BOUNDARY_CHARS = toAsciiBytes( + "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); //$NON-NLS-1$ + + /** Carriage return/linefeed as a byte array */ + private static final byte[] CRLF = toAsciiBytes("\r\n"); //$NON-NLS-1$ + + /** Content dispostion as a byte array */ + private static final byte[] QUOTE = toAsciiBytes("\""); //$NON-NLS-1$ + + /** Extra characters as a byte array */ + private static final byte[] EXTRA = toAsciiBytes("--"); //$NON-NLS-1$ + + /** Content dispostion as a byte array */ + private static final byte[] CONTENT_DISPOSITION = toAsciiBytes( + "Content-Disposition: form-data; name="); //$NON-NLS-1$ + + /** Content type header as a byte array */ + private static final byte[] CONTENT_TYPE = toAsciiBytes("Content-Type: "); //$NON-NLS-1$ + + /** Content type header as a byte array */ + private static final byte[] CONTENT_TRANSFER_ENCODING = toAsciiBytes( + "Content-Transfer-Encoding: "); //$NON-NLS-1$ + + /** Attachment's file name as a byte array */ + private static final byte[] FILE_NAME = toAsciiBytes("; filename="); //$NON-NLS-1$ + + private static final byte[] TEXT_CONTENT_TYPE = toAsciiBytes( + "text/plain; charset=utf-8"); //$NON-NLS-1$ + + private static final byte[] FILE_TRANSFER_ENCODING = toAsciiBytes("binary"); //$NON-NLS-1$ + + private static final byte[] TEXT_TRANSFER_ENCODING = toAsciiBytes("8bit"); //$NON-NLS-1$ + + private FieldSet parts; + + private byte[] boundary = null; + + /** + * + */ + public MultipartEntity(FieldSet parts) { + this.parts = parts; + } + + /** + * @return the parts + */ + public FieldSet getParts() { + return parts; + } + + private byte[] getBoundary() { + if (boundary != null) + return boundary; + Random rand = new Random(); + byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size + // from 30 to 40 + for (int i = 0; i < bytes.length; i++) { + bytes[i] = BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]; + } + boundary = bytes; + return boundary; + } + + public String getContentType() { + StringBuffer typeBuffer = new StringBuffer(MULTIPART_CONTENT_TYPE); + typeBuffer.append(EncodingUtils.toAsciiString(getBoundary())); + return typeBuffer.toString(); + } + + private static String toSafeName(String name) { + return name.replaceAll("\"", "%22"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public long getContentLength() { + if (parts.isEmpty()) + return 0; + long length = 0; + for (Field part : parts) { + length += EXTRA.length; + length += getBoundary().length; + length += CRLF.length; + + length += CONTENT_DISPOSITION.length; + length += QUOTE.length; + length += toAsciiBytes(toSafeName(part.name)).length; + length += QUOTE.length; + length += CRLF.length; + + if (part.value instanceof HttpEntity) { + String fileName = ((HttpEntity) part.value).getFileName(); + if (fileName == null) + fileName = part.name; + length += FILE_NAME.length; + length += QUOTE.length; + length += toAsciiBytes(toSafeName(fileName)).length; + length += QUOTE.length; + } + + length += CONTENT_TYPE.length; + length += getContentType(part.value).length; + length += CRLF.length; + + length += CONTENT_TRANSFER_ENCODING.length; + length += getTransferEncoding(part.value).length; + length += CRLF.length; + length += CRLF.length; + + length += getPartDataLength(part); + + length += CRLF.length; + + } + + length += EXTRA.length; + length += getBoundary().length; + length += EXTRA.length; + length += CRLF.length; + return length; + } + + public void writeTo(OutputStream stream) throws IOException { + if (parts.isEmpty()) + return; + + for (Field part : parts) { + stream.write(EXTRA); + stream.write(getBoundary()); + stream.write(CRLF); + + stream.write(CONTENT_DISPOSITION); + stream.write(QUOTE); + stream.write(toAsciiBytes(toSafeName(part.name))); + stream.write(QUOTE); + if (part.value instanceof HttpEntity) { + String fileName = ((HttpEntity) part.value).getFileName(); + if (fileName == null) + fileName = part.name; + stream.write(FILE_NAME); + stream.write(QUOTE); + stream.write(toAsciiBytes(toSafeName(fileName))); + stream.write(QUOTE); + } + stream.write(CRLF); + + stream.write(CONTENT_TYPE); + stream.write(getContentType(part.value)); + stream.write(CRLF); + + stream.write(CONTENT_TRANSFER_ENCODING); + stream.write(getTransferEncoding(part.value)); + stream.write(CRLF); + stream.write(CRLF); + + writePartData(stream, part); + + stream.write(CRLF); + } + + stream.write(EXTRA); + stream.write(getBoundary()); + stream.write(EXTRA); + stream.write(CRLF); + } + + private static byte[] getContentType(Object value) { + if (value instanceof HttpEntity) + return EncodingUtils + .toAsciiBytes(((HttpEntity) value).getContentType()); + return TEXT_CONTENT_TYPE; + } + + private static byte[] getTransferEncoding(Object value) { + if (value instanceof HttpEntity) + return FILE_TRANSFER_ENCODING; + return TEXT_TRANSFER_ENCODING; + } + + private static long getPartDataLength(Field part) { + if (part.value instanceof HttpEntity) { + return ((HttpEntity) part.value).getContentLength(); + } + return toAsciiBytes(part.getValue()).length; + } + + private static void writePartData(OutputStream stream, Field part) + throws IOException { + if (part.value instanceof HttpEntity) { + ((HttpEntity) part.value).writeTo(stream); + } else { + writeFromText(stream, part.getValue()); + } + } + + private static void writeFromText(OutputStream writeStream, + String encodedText) throws IOException { + writeStream.write(encodedText.getBytes("UTF-8")); //$NON-NLS-1$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedEntity.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedEntity.java index 0095e2004..96479f778 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedEntity.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedEntity.java @@ -1,87 +1,87 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.eclipse.core.runtime.Assert; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class StreamedEntity extends HttpEntity { - - public static final int DEFAULT_BUFFER_SIZE = 4096; - - private InputStream input; - - private long length; - - private int bufferSize; - - /** - * - */ - public StreamedEntity(InputStream input, long length, int bufferSize) { - super(); - Assert.isLegal(input != null); - Assert.isLegal(bufferSize > 0); - this.input = input; - this.length = length; - this.bufferSize = bufferSize; - } - - /** - * - */ - public StreamedEntity(InputStream input, long length) { - this(input, length, DEFAULT_BUFFER_SIZE); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.internal.Entity#writeTo(java.io.OutputStream) - */ - @Override - public void writeTo(OutputStream output) throws IOException { - transfer(input, output, bufferSize); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.net.http.HttpEntity#getContentLength() - */ - @Override - public long getContentLength() { - return length; - } - - public static void transfer(InputStream input, OutputStream output, - int bufferSize) throws IOException { - byte[] buffer = new byte[bufferSize]; - int numRead; - while ((numRead = input.read(buffer)) != -1) { - output.write(buffer, 0, numRead); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.eclipse.core.runtime.Assert; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class StreamedEntity extends HttpEntity { + + public static final int DEFAULT_BUFFER_SIZE = 4096; + + private InputStream input; + + private long length; + + private int bufferSize; + + /** + * + */ + public StreamedEntity(InputStream input, long length, int bufferSize) { + super(); + Assert.isLegal(input != null); + Assert.isLegal(bufferSize > 0); + this.input = input; + this.length = length; + this.bufferSize = bufferSize; + } + + /** + * + */ + public StreamedEntity(InputStream input, long length) { + this(input, length, DEFAULT_BUFFER_SIZE); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.internal.Entity#writeTo(java.io.OutputStream) + */ + @Override + public void writeTo(OutputStream output) throws IOException { + transfer(input, output, bufferSize); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.net.http.HttpEntity#getContentLength() + */ + @Override + public long getContentLength() { + return length; + } + + public static void transfer(InputStream input, OutputStream output, + int bufferSize) throws IOException { + byte[] buffer = new byte[bufferSize]; + int numRead; + while ((numRead = input.read(buffer)) != -1) { + output.write(buffer, 0, numRead); + } + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedResponseHandler.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedResponseHandler.java index 9890c797f..22a5eb824 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedResponseHandler.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/StreamedResponseHandler.java @@ -1,52 +1,52 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.http; - -import java.io.IOException; -import java.io.OutputStream; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public abstract class StreamedResponseHandler implements IResponseHandler { - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.net.http.IResponseHandler#handleResponseEntity(org.eclipse - * .core.runtime.IProgressMonitor, org.xmind.core.net.http.HttpRequest, - * org.xmind.core.net.http.HttpEntity) - */ - public void handleResponseEntity(IProgressMonitor monitor, - HttpRequest request, HttpEntity entity) - throws InterruptedException, IOException { - OutputStream output = openOutputStream(monitor, request); - try { - entity.writeTo(output); - } finally { - output.close(); - } - } - - protected abstract OutputStream openOutputStream(IProgressMonitor monitor, - HttpRequest request) throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.http; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public abstract class StreamedResponseHandler implements IResponseHandler { + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.net.http.IResponseHandler#handleResponseEntity(org.eclipse + * .core.runtime.IProgressMonitor, org.xmind.core.net.http.HttpRequest, + * org.xmind.core.net.http.HttpEntity) + */ + public void handleResponseEntity(IProgressMonitor monitor, + HttpRequest request, HttpEntity entity) + throws InterruptedException, IOException { + OutputStream output = openOutputStream(monitor, request); + try { + entity.writeTo(output); + } finally { + output.close(); + } + } + + protected abstract OutputStream openOutputStream(IProgressMonitor monitor, + HttpRequest request) throws IOException; + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/Activator.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/Activator.java index 4c081cefa..ab974e6a1 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/Activator.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/Activator.java @@ -1,129 +1,129 @@ -package org.xmind.core.net.internal; - -import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; - -/** - * The activator class controls the plug-in life cycle - */ -public class Activator implements BundleActivator { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.core.net"; //$NON-NLS-1$ - - public static final String OPTION_HTTP_ASSC = "/debug/http/assc"; //$NON-NLS-1$ - - public static final String OPTION_HTTP_REQEUSTS = "/debug/http/requests"; //$NON-NLS-1$ - - public static final String CONFIG_DEBUG_HTTP_REQUESTS = "org.xmind.debug.httprequests"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - private BundleContext bundleContext; - - private ServiceTracker debugTracker = null; - - /** - * The constructor - */ - public Activator() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. - * BundleContext) - */ - public void start(BundleContext context) throws Exception { - plugin = this; - this.bundleContext = context; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. - * BundleContext) - */ - public void stop(BundleContext context) throws Exception { - ServiceTracker theDebugTracker = this.debugTracker; - if (theDebugTracker != null) { - theDebugTracker.close(); - } - this.debugTracker = null; - - this.bundleContext = null; - plugin = null; - } - - public Bundle getBundle() { - return bundleContext.getBundle(); - } - - public ILog getLog() { - return Platform.getLog(getBundle()); - } - - private synchronized DebugOptions getDebugOptions() { - if (debugTracker == null) { - debugTracker = new ServiceTracker( - getDefault().getBundle().getBundleContext(), - DebugOptions.class, null); - debugTracker.open(); - } - return debugTracker.getService(); - } - - public static boolean isDebugging(String option) { - Activator defaultInstance = getDefault(); - if (defaultInstance == null) - return false; - DebugOptions options = defaultInstance.getDebugOptions(); - return options != null - && options.getBooleanOption(PLUGIN_ID + option, false); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } - - public static void log(String message) { - Activator p = getDefault(); - if (p == null) { - System.out.println(message); - } else { - p.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); - } - } - - public static void log(Throwable e) { - log(e, null); - } - - public static void log(Throwable e, String message) { - Activator p = getDefault(); - if (p == null) { - if (message != null) { - System.err.println(message); - } - e.printStackTrace(); - } else { - p.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } - } - -} +package org.xmind.core.net.internal; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator implements BundleActivator { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.core.net"; //$NON-NLS-1$ + + public static final String OPTION_HTTP_ASSC = "/debug/http/assc"; //$NON-NLS-1$ + + public static final String OPTION_HTTP_REQEUSTS = "/debug/http/requests"; //$NON-NLS-1$ + + public static final String CONFIG_DEBUG_HTTP_REQUESTS = "org.xmind.debug.httprequests"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + private BundleContext bundleContext; + + private ServiceTracker debugTracker = null; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. + * BundleContext) + */ + public void start(BundleContext context) throws Exception { + plugin = this; + this.bundleContext = context; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. + * BundleContext) + */ + public void stop(BundleContext context) throws Exception { + ServiceTracker theDebugTracker = this.debugTracker; + if (theDebugTracker != null) { + theDebugTracker.close(); + } + this.debugTracker = null; + + this.bundleContext = null; + plugin = null; + } + + public Bundle getBundle() { + return bundleContext.getBundle(); + } + + public ILog getLog() { + return Platform.getLog(getBundle()); + } + + private synchronized DebugOptions getDebugOptions() { + if (debugTracker == null) { + debugTracker = new ServiceTracker( + getDefault().getBundle().getBundleContext(), + DebugOptions.class, null); + debugTracker.open(); + } + return debugTracker.getService(); + } + + public static boolean isDebugging(String option) { + Activator defaultInstance = getDefault(); + if (defaultInstance == null) + return false; + DebugOptions options = defaultInstance.getDebugOptions(); + return options != null + && options.getBooleanOption(PLUGIN_ID + option, false); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + public static void log(String message) { + Activator p = getDefault(); + if (p == null) { + System.out.println(message); + } else { + p.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message)); + } + } + + public static void log(Throwable e) { + log(e, null); + } + + public static void log(Throwable e, String message) { + Activator p = getDefault(); + if (p == null) { + if (message != null) { + System.err.println(message); + } + e.printStackTrace(); + } else { + p.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/EncodingUtils.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/EncodingUtils.java index 70c97cc3d..c297829eb 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/EncodingUtils.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/EncodingUtils.java @@ -1,168 +1,168 @@ -package org.xmind.core.net.internal; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; - -public class EncodingUtils { - - public static final String DEFAULT_ENCODING = "UTF-8"; //$NON-NLS-1$ - - public static final String LATIN1 = "ISO-8859-1"; //$NON-NLS-1$ - - private EncodingUtils() { - } - - public static String urlEncode(Object object) { - String text = object == null ? "" : String.valueOf(object); //$NON-NLS-1$ - try { - return URLEncoder.encode(text, DEFAULT_ENCODING); - } catch (UnsupportedEncodingException e) { - throw wrapEncodingException(e, DEFAULT_ENCODING); - } - } - - public static String urlDecode(String text) { - if (text == null) - return ""; //$NON-NLS-1$ - try { - return URLDecoder.decode(text, DEFAULT_ENCODING); - } catch (UnsupportedEncodingException e) { - throw wrapEncodingException(e, DEFAULT_ENCODING); - } - } - - public static String format(String pattern, Object... values) { - Object[] encodedValues = new Object[values.length]; - for (int i = 0; i < values.length; i++) { - encodedValues[i] = EncodingUtils.urlEncode(values[i]); - } - return String.format(pattern, encodedValues); - } - - /** - * - * @param str - * @return - * @throws AssertionError - * if the default encoding (UTF-8) is not supported - */ - public static byte[] toDefaultBytes(String str) { - return toBytes(str, DEFAULT_ENCODING); - } - - /** - * - * @param bytes - * @return - * @throws AssertionError - * if the default encoding (UTF-8) is not supported - */ - public static String toDefaultString(byte[] bytes) { - return toString(bytes, DEFAULT_ENCODING); - } - - /** - * - * @param str - * @return - * @throws AssertionError - * if the ASCII encoding (ISO-8859-1) is not supported - */ - public static byte[] toAsciiBytes(String str) { - return toBytes(str, LATIN1); - } - - /** - * - * @param bytes - * @return - * @throws AssertionError - * if the ASCII encoding (ISO-8859-1) is not supported - */ - public static String toAsciiString(byte[] bytes) { - return toString(bytes, LATIN1); - } - - private static byte[] toBytes(String str, String charsetName) { - try { - return str.getBytes(charsetName); - } catch (UnsupportedEncodingException e) { - throw wrapEncodingException(e, charsetName); - } - } - - private static String toString(byte[] bytes, String charsetName) { - try { - return new String(bytes, charsetName); - } catch (UnsupportedEncodingException e) { - throw wrapEncodingException(e, charsetName); - } - } - - public static AssertionError wrapEncodingException( - UnsupportedEncodingException e, String charsetName) { - return new AssertionError( - String.format("Encoding not supported: %s", charsetName), e); //$NON-NLS-1$ - } - - /** - * This array is a lookup table that translates 6-bit positive integer index - * values into their "Base64 Alphabet" equivalents as specified in Table 1 - * of RFC 2045. - */ - private static final char[] intToBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', - 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' }; - - /** - * Translates the specified byte array into a Base64 string as per - * Preferences.put(byte[]). - */ - public static char[] base64Encode(byte[] a) { - int aLen = a.length; - int numFullGroups = aLen / 3; - int numBytesInPartialGroup = aLen - 3 * numFullGroups; - int resultLen = 4 * ((aLen + 2) / 3); - char[] result = new char[resultLen]; - char[] intToAlpha = intToBase64; - - // Translate all full groups from byte array elements to Base64 - int inCursor = 0; - int outCursor = 0; - for (int i = 0; i < numFullGroups; i++) { - int byte0 = a[inCursor++] & 0xff; - int byte1 = a[inCursor++] & 0xff; - int byte2 = a[inCursor++] & 0xff; - result[outCursor++] = intToAlpha[byte0 >> 2]; - result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f - | (byte1 >> 4)]; - result[outCursor++] = intToAlpha[(byte1 << 2) & 0x3f - | (byte2 >> 6)]; - result[outCursor++] = intToAlpha[byte2 & 0x3f]; - } - - // Translate partial group if present - if (numBytesInPartialGroup != 0) { - int byte0 = a[inCursor++] & 0xff; - result[outCursor++] = intToAlpha[byte0 >> 2]; - if (numBytesInPartialGroup == 1) { - result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f]; - result[outCursor++] = '='; - result[outCursor++] = '='; - } else { - // assert numBytesInPartialGroup == 2; - int byte1 = a[inCursor++] & 0xff; - result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f - | (byte1 >> 4)]; - result[outCursor++] = intToAlpha[(byte1 << 2) & 0x3f]; - result[outCursor++] = '='; - } - } - return result; - } - -} +package org.xmind.core.net.internal; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; + +public class EncodingUtils { + + public static final String DEFAULT_ENCODING = "UTF-8"; //$NON-NLS-1$ + + public static final String LATIN1 = "ISO-8859-1"; //$NON-NLS-1$ + + private EncodingUtils() { + } + + public static String urlEncode(Object object) { + String text = object == null ? "" : String.valueOf(object); //$NON-NLS-1$ + try { + return URLEncoder.encode(text, DEFAULT_ENCODING); + } catch (UnsupportedEncodingException e) { + throw wrapEncodingException(e, DEFAULT_ENCODING); + } + } + + public static String urlDecode(String text) { + if (text == null) + return ""; //$NON-NLS-1$ + try { + return URLDecoder.decode(text, DEFAULT_ENCODING); + } catch (UnsupportedEncodingException e) { + throw wrapEncodingException(e, DEFAULT_ENCODING); + } + } + + public static String format(String pattern, Object... values) { + Object[] encodedValues = new Object[values.length]; + for (int i = 0; i < values.length; i++) { + encodedValues[i] = EncodingUtils.urlEncode(values[i]); + } + return String.format(pattern, encodedValues); + } + + /** + * + * @param str + * @return + * @throws AssertionError + * if the default encoding (UTF-8) is not supported + */ + public static byte[] toDefaultBytes(String str) { + return toBytes(str, DEFAULT_ENCODING); + } + + /** + * + * @param bytes + * @return + * @throws AssertionError + * if the default encoding (UTF-8) is not supported + */ + public static String toDefaultString(byte[] bytes) { + return toString(bytes, DEFAULT_ENCODING); + } + + /** + * + * @param str + * @return + * @throws AssertionError + * if the ASCII encoding (ISO-8859-1) is not supported + */ + public static byte[] toAsciiBytes(String str) { + return toBytes(str, LATIN1); + } + + /** + * + * @param bytes + * @return + * @throws AssertionError + * if the ASCII encoding (ISO-8859-1) is not supported + */ + public static String toAsciiString(byte[] bytes) { + return toString(bytes, LATIN1); + } + + private static byte[] toBytes(String str, String charsetName) { + try { + return str.getBytes(charsetName); + } catch (UnsupportedEncodingException e) { + throw wrapEncodingException(e, charsetName); + } + } + + private static String toString(byte[] bytes, String charsetName) { + try { + return new String(bytes, charsetName); + } catch (UnsupportedEncodingException e) { + throw wrapEncodingException(e, charsetName); + } + } + + public static AssertionError wrapEncodingException( + UnsupportedEncodingException e, String charsetName) { + return new AssertionError( + String.format("Encoding not supported: %s", charsetName), e); //$NON-NLS-1$ + } + + /** + * This array is a lookup table that translates 6-bit positive integer index + * values into their "Base64 Alphabet" equivalents as specified in Table 1 + * of RFC 2045. + */ + private static final char[] intToBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' }; + + /** + * Translates the specified byte array into a Base64 string as per + * Preferences.put(byte[]). + */ + public static char[] base64Encode(byte[] a) { + int aLen = a.length; + int numFullGroups = aLen / 3; + int numBytesInPartialGroup = aLen - 3 * numFullGroups; + int resultLen = 4 * ((aLen + 2) / 3); + char[] result = new char[resultLen]; + char[] intToAlpha = intToBase64; + + // Translate all full groups from byte array elements to Base64 + int inCursor = 0; + int outCursor = 0; + for (int i = 0; i < numFullGroups; i++) { + int byte0 = a[inCursor++] & 0xff; + int byte1 = a[inCursor++] & 0xff; + int byte2 = a[inCursor++] & 0xff; + result[outCursor++] = intToAlpha[byte0 >> 2]; + result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f + | (byte1 >> 4)]; + result[outCursor++] = intToAlpha[(byte1 << 2) & 0x3f + | (byte2 >> 6)]; + result[outCursor++] = intToAlpha[byte2 & 0x3f]; + } + + // Translate partial group if present + if (numBytesInPartialGroup != 0) { + int byte0 = a[inCursor++] & 0xff; + result[outCursor++] = intToAlpha[byte0 >> 2]; + if (numBytesInPartialGroup == 1) { + result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f]; + result[outCursor++] = '='; + result[outCursor++] = '='; + } else { + // assert numBytesInPartialGroup == 2; + int byte1 = a[inCursor++] & 0xff; + result[outCursor++] = intToAlpha[(byte0 << 4) & 0x3f + | (byte1 >> 4)]; + result[outCursor++] = intToAlpha[(byte1 << 2) & 0x3f]; + result[outCursor++] = '='; + } + } + return result; + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/FixedLengthInputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/FixedLengthInputStream.java index d7673cb81..0461935e4 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/FixedLengthInputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/FixedLengthInputStream.java @@ -1,130 +1,130 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.internal; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.net.http.HttpException; -import org.xmind.core.net.http.HttpRequest; - -/** - * @author Frank Shaka - * - */ -public class FixedLengthInputStream extends FilterInputStream { - - private final HttpRequest request; - - private final long expectedCount; - - private long actualCount - - ; - - /** - * @param in - */ - public FixedLengthInputStream(InputStream in, HttpRequest request, - long expectedCount) { - super(in); - this.request = request; - this.expectedCount = expectedCount; - this.actualCount = 0; - } - - @Override - public int read() throws IOException { - if (actualCount >= expectedCount) - return -1; - - int b = in.read(); - if (b < 0) { - if (actualCount < expectedCount) { - throw new HttpException(request, HttpRequest.HTTP_RECEIVING, - "Insufficient data received", null); //$NON-NLS-1$ - } - return b; - } - actualCount += 1; - return b; - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterInputStream#read(byte[]) - */ - @Override - public int read(byte[] b) throws IOException { - if (actualCount >= expectedCount) - return -1; - - int num = in.read(b); - if (num < 0) { - if (actualCount < expectedCount) { - throw new HttpException(request, HttpRequest.HTTP_RECEIVING, - "Insufficient data received", null); //$NON-NLS-1$ - } - return num; - } - - long oldCount = actualCount; - actualCount = Math.min(actualCount + num, expectedCount); - return (int) (actualCount - oldCount); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterInputStream#read(byte[], int, int) - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (actualCount >= expectedCount) - return -1; - - int num = in.read(b, off, len); - if (num < 0) { - if (actualCount < expectedCount) { - throw new HttpException(request, HttpRequest.HTTP_RECEIVING, - "Insufficient data received", null); //$NON-NLS-1$ - } - return num; - } - - long oldCount = actualCount; - actualCount = Math.min(actualCount + num, expectedCount); - return (int) (actualCount - oldCount); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterInputStream#available() - */ - @Override - public int available() throws IOException { - int num = super.available(); - if (num < 0) { - return num; - } - return Math.min(num, (int) (expectedCount - actualCount)); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.internal; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.net.http.HttpException; +import org.xmind.core.net.http.HttpRequest; + +/** + * @author Frank Shaka + * + */ +public class FixedLengthInputStream extends FilterInputStream { + + private final HttpRequest request; + + private final long expectedCount; + + private long actualCount + + ; + + /** + * @param in + */ + public FixedLengthInputStream(InputStream in, HttpRequest request, + long expectedCount) { + super(in); + this.request = request; + this.expectedCount = expectedCount; + this.actualCount = 0; + } + + @Override + public int read() throws IOException { + if (actualCount >= expectedCount) + return -1; + + int b = in.read(); + if (b < 0) { + if (actualCount < expectedCount) { + throw new HttpException(request, HttpRequest.HTTP_RECEIVING, + "Insufficient data received", null); //$NON-NLS-1$ + } + return b; + } + actualCount += 1; + return b; + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterInputStream#read(byte[]) + */ + @Override + public int read(byte[] b) throws IOException { + if (actualCount >= expectedCount) + return -1; + + int num = in.read(b); + if (num < 0) { + if (actualCount < expectedCount) { + throw new HttpException(request, HttpRequest.HTTP_RECEIVING, + "Insufficient data received", null); //$NON-NLS-1$ + } + return num; + } + + long oldCount = actualCount; + actualCount = Math.min(actualCount + num, expectedCount); + return (int) (actualCount - oldCount); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterInputStream#read(byte[], int, int) + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (actualCount >= expectedCount) + return -1; + + int num = in.read(b, off, len); + if (num < 0) { + if (actualCount < expectedCount) { + throw new HttpException(request, HttpRequest.HTTP_RECEIVING, + "Insufficient data received", null); //$NON-NLS-1$ + } + return num; + } + + long oldCount = actualCount; + actualCount = Math.min(actualCount + num, expectedCount); + return (int) (actualCount - oldCount); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterInputStream#available() + */ + @Override + public int available() throws IOException { + int num = super.available(); + if (num < 0) { + return num; + } + return Math.min(num, (int) (expectedCount - actualCount)); + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/IRequestStatusChangeListener.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/IRequestStatusChangeListener.java index 5a5097fbe..d948eb7a5 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/IRequestStatusChangeListener.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/IRequestStatusChangeListener.java @@ -1,22 +1,22 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2016 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.core.net.internal; - -/** - * @author Frank Shaka - */ -@Deprecated -public interface IRequestStatusChangeListener { - - public void requestStatusChanged(XMindNetRequest request, int oldStatus, - int newStatus); - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2016 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.core.net.internal; + +/** + * @author Frank Shaka + */ +@Deprecated +public interface IRequestStatusChangeListener { + + public void requestStatusChanged(XMindNetRequest request, int oldStatus, + int newStatus); + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggingOutputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggingOutputStream.java index 608fcd2ce..f7f7bdd85 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggingOutputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggingOutputStream.java @@ -1,137 +1,137 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.internal; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Invisible characters are encoded using - * Quoted-Printable - * codec. - * - * @author Frank Shaka - * @since 3.6.51 - */ -public class LoggingOutputStream extends FilterOutputStream { - - private static final byte MIN_VISIBLE_CHAR = (byte) 32; - private static final byte MAX_VISIBLE_CHAR = (byte) 126; - - private static final byte PREFIX = (byte) '='; - private static final byte LF = (byte) '\n'; - private static final byte CR = (byte) '\r'; - private static final byte START1 = (byte) '0'; - private static final byte START2 = (byte) ('A' - 10); - - private byte[] buffer; - - /** - * @param out - */ - public LoggingOutputStream(OutputStream out) { - super(out); - this.buffer = new byte[1024]; - } - - private int quote(byte[] b, int off, int len) { - int buffered = 0; - int n; - for (int i = 0; i < len; i++) { - n = quote(b[i], buffered); - buffered += n; - } - return buffered; - } - - private int quote(byte b, int bufferOffset) { - if (b != LF && b != CR && (b == PREFIX || b < MIN_VISIBLE_CHAR - || b > MAX_VISIBLE_CHAR)) { - ensureBufferSize(bufferOffset + 2); - buffer[bufferOffset] = PREFIX; - buffer[bufferOffset + 1] = toHex((b & 0xF0) >> 4); - buffer[bufferOffset + 2] = toHex(b & 0x0F); - return 3; - } else { - ensureBufferSize(bufferOffset); - buffer[bufferOffset] = b; - return 1; - } - } - - private static final byte toHex(int x) { - if (x < 10) { - return (byte) (START1 + x); - } - return (byte) (START2 + x); - } - - /** - * @param expectedSize - */ - private void ensureBufferSize(int expectedSize) { - if (expectedSize >= buffer.length) { - byte[] newBuffer = new byte[(int) (buffer.length * 1.4)]; - System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); - buffer = newBuffer; - } - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(byte[]) - */ - @Override - public void write(byte[] b) throws IOException { - int n = quote(b, 0, b.length); - try { - out.write(buffer, 0, n); - out.flush(); - } catch (IOException e) { - } - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(byte[], int, int) - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - int n = quote(b, off, len); - try { - out.write(buffer, 0, n); - out.flush(); - } catch (IOException e) { - } - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(int) - */ - @Override - public void write(int b) throws IOException { - int n = quote((byte) b, 0); - try { - out.write(buffer, 0, n); - out.flush(); - } catch (IOException e) { - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.internal; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Invisible characters are encoded using + * Quoted-Printable + * codec. + * + * @author Frank Shaka + * @since 3.6.51 + */ +public class LoggingOutputStream extends FilterOutputStream { + + private static final byte MIN_VISIBLE_CHAR = (byte) 32; + private static final byte MAX_VISIBLE_CHAR = (byte) 126; + + private static final byte PREFIX = (byte) '='; + private static final byte LF = (byte) '\n'; + private static final byte CR = (byte) '\r'; + private static final byte START1 = (byte) '0'; + private static final byte START2 = (byte) ('A' - 10); + + private byte[] buffer; + + /** + * @param out + */ + public LoggingOutputStream(OutputStream out) { + super(out); + this.buffer = new byte[1024]; + } + + private int quote(byte[] b, int off, int len) { + int buffered = 0; + int n; + for (int i = 0; i < len; i++) { + n = quote(b[i], buffered); + buffered += n; + } + return buffered; + } + + private int quote(byte b, int bufferOffset) { + if (b != LF && b != CR && (b == PREFIX || b < MIN_VISIBLE_CHAR + || b > MAX_VISIBLE_CHAR)) { + ensureBufferSize(bufferOffset + 2); + buffer[bufferOffset] = PREFIX; + buffer[bufferOffset + 1] = toHex((b & 0xF0) >> 4); + buffer[bufferOffset + 2] = toHex(b & 0x0F); + return 3; + } else { + ensureBufferSize(bufferOffset); + buffer[bufferOffset] = b; + return 1; + } + } + + private static final byte toHex(int x) { + if (x < 10) { + return (byte) (START1 + x); + } + return (byte) (START2 + x); + } + + /** + * @param expectedSize + */ + private void ensureBufferSize(int expectedSize) { + if (expectedSize >= buffer.length) { + byte[] newBuffer = new byte[(int) (buffer.length * 1.4)]; + System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); + buffer = newBuffer; + } + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(byte[]) + */ + @Override + public void write(byte[] b) throws IOException { + int n = quote(b, 0, b.length); + try { + out.write(buffer, 0, n); + out.flush(); + } catch (IOException e) { + } + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(byte[], int, int) + */ + @Override + public void write(byte[] b, int off, int len) throws IOException { + int n = quote(b, off, len); + try { + out.write(buffer, 0, n); + out.flush(); + } catch (IOException e) { + } + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(int) + */ + @Override + public void write(int b) throws IOException { + int n = quote((byte) b, 0); + try { + out.write(buffer, 0, n); + out.flush(); + } catch (IOException e) { + } + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredInputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredInputStream.java index b91dff688..c367ac910 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredInputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredInputStream.java @@ -1,102 +1,102 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.net.internal; - -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class MonitoredInputStream extends InputStream { - - private InputStream realStream; - - private IProgressMonitor monitor; - - public MonitoredInputStream(InputStream realStream, - IProgressMonitor monitor) { - this.realStream = realStream; - this.monitor = monitor; - } - - private void closeRealStream() { - try { - realStream.close(); - } catch (IOException ignore) { - } - } - - public int read() throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - return realStream.read(); - } - - public int available() throws IOException { - return realStream.available(); - } - - public void close() throws IOException { - realStream.close(); - } - - public void mark(int readlimit) { - realStream.mark(readlimit); - } - - public boolean markSupported() { - return realStream.markSupported(); - } - - public int read(byte[] b, int off, int len) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - return realStream.read(b, off, len); - } - - public int read(byte[] b) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - return realStream.read(b); - } - - public void reset() throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - realStream.reset(); - } - - public long skip(long n) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - return realStream.skip(n); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.net.internal; + +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class MonitoredInputStream extends InputStream { + + private InputStream realStream; + + private IProgressMonitor monitor; + + public MonitoredInputStream(InputStream realStream, + IProgressMonitor monitor) { + this.realStream = realStream; + this.monitor = monitor; + } + + private void closeRealStream() { + try { + realStream.close(); + } catch (IOException ignore) { + } + } + + public int read() throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + return realStream.read(); + } + + public int available() throws IOException { + return realStream.available(); + } + + public void close() throws IOException { + realStream.close(); + } + + public void mark(int readlimit) { + realStream.mark(readlimit); + } + + public boolean markSupported() { + return realStream.markSupported(); + } + + public int read(byte[] b, int off, int len) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + return realStream.read(b, off, len); + } + + public int read(byte[] b) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + return realStream.read(b); + } + + public void reset() throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + realStream.reset(); + } + + public long skip(long n) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + return realStream.skip(n); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredOutputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredOutputStream.java index e533354a5..1ab6c2623 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredOutputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/MonitoredOutputStream.java @@ -1,83 +1,83 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.net.internal; - -import java.io.IOException; -import java.io.OutputStream; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class MonitoredOutputStream extends OutputStream { - - private OutputStream realStream; - - private IProgressMonitor monitor; - - public MonitoredOutputStream(OutputStream realStream, - IProgressMonitor monitor) { - super(); - this.realStream = realStream; - this.monitor = monitor; - } - - private void closeRealStream() { - try { - realStream.close(); - } catch (IOException ignore) { - } - } - - public void close() throws IOException { - realStream.close(); - } - - public void flush() throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - realStream.flush(); - } - - public void write(byte[] b, int off, int len) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - realStream.write(b, off, len); - } - - public void write(byte[] b) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - realStream.write(b); - } - - public void write(int b) throws IOException { - if (monitor.isCanceled()) { - closeRealStream(); - throw new OperationCanceledException(); - } - realStream.write(b); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.net.internal; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class MonitoredOutputStream extends OutputStream { + + private OutputStream realStream; + + private IProgressMonitor monitor; + + public MonitoredOutputStream(OutputStream realStream, + IProgressMonitor monitor) { + super(); + this.realStream = realStream; + this.monitor = monitor; + } + + private void closeRealStream() { + try { + realStream.close(); + } catch (IOException ignore) { + } + } + + public void close() throws IOException { + realStream.close(); + } + + public void flush() throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + realStream.flush(); + } + + public void write(byte[] b, int off, int len) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + realStream.write(b, off, len); + } + + public void write(byte[] b) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + realStream.write(b); + } + + public void write(int b) throws IOException { + if (monitor.isCanceled()) { + closeRealStream(); + throw new OperationCanceledException(); + } + realStream.write(b); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java index 0911831d4..705d6840c 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java @@ -1,79 +1,79 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.internal; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * @author Frank Shaka - * @since 3.6.51 - */ -public class TeeInputStream extends FilterInputStream { - - private OutputStream out; - - /** - * @param in - */ - public TeeInputStream(InputStream in, OutputStream out) { - super(in); - this.out = out; - } - - /* - * (non-Javadoc) - * @see java.io.FilterInputStream#read() - */ - @Override - public int read() throws IOException { - int b = in.read(); - if (b != -1) { - out.write(b); - } - return b; - } - - /* - * (non-Javadoc) - * @see java.io.FilterInputStream#read(byte[]) - */ - @Override - public int read(byte[] b) throws IOException { - int n = in.read(b); - if (n != -1) { - out.write(b, 0, n); - } - return n; - } - - /* - * (non-Javadoc) - * @see java.io.FilterInputStream#read(byte[], int, int) - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - int n = in.read(b, off, len); - if (n != -1) { - out.write(b, off, n); - } - return n; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.internal; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * @author Frank Shaka + * @since 3.6.51 + */ +public class TeeInputStream extends FilterInputStream { + + private OutputStream out; + + /** + * @param in + */ + public TeeInputStream(InputStream in, OutputStream out) { + super(in); + this.out = out; + } + + /* + * (non-Javadoc) + * @see java.io.FilterInputStream#read() + */ + @Override + public int read() throws IOException { + int b = in.read(); + if (b != -1) { + out.write(b); + } + return b; + } + + /* + * (non-Javadoc) + * @see java.io.FilterInputStream#read(byte[]) + */ + @Override + public int read(byte[] b) throws IOException { + int n = in.read(b); + if (n != -1) { + out.write(b, 0, n); + } + return n; + } + + /* + * (non-Javadoc) + * @see java.io.FilterInputStream#read(byte[], int, int) + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + int n = in.read(b, off, len); + if (n != -1) { + out.write(b, off, n); + } + return n; + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java index e72636408..1158d7fe0 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java @@ -1,79 +1,79 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.net.internal; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * @author Frank Shaka - * @since 3.6.51 - */ -public class TeeOutputStream extends FilterOutputStream { - - private OutputStream out2; - - /** - * @param out - */ - public TeeOutputStream(OutputStream out, OutputStream out2) { - super(out); - this.out2 = out2; - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(byte[]) - */ - @Override - public void write(byte[] b) throws IOException { - out.write(b); - out2.write(b); - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(byte[], int, int) - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - out2.write(b, off, len); - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#write(int) - */ - @Override - public void write(int b) throws IOException { - out.write(b); - out2.write(b); - } - - /* - * (non-Javadoc) - * @see java.io.FilterOutputStream#flush() - */ - @Override - public void flush() throws IOException { - super.flush(); - out2.flush(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.net.internal; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Frank Shaka + * @since 3.6.51 + */ +public class TeeOutputStream extends FilterOutputStream { + + private OutputStream out2; + + /** + * @param out + */ + public TeeOutputStream(OutputStream out, OutputStream out2) { + super(out); + this.out2 = out2; + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(byte[]) + */ + @Override + public void write(byte[] b) throws IOException { + out.write(b); + out2.write(b); + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(byte[], int, int) + */ + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + out2.write(b, off, len); + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#write(int) + */ + @Override + public void write(int b) throws IOException { + out.write(b); + out2.write(b); + } + + /* + * (non-Javadoc) + * @see java.io.FilterOutputStream#flush() + */ + @Override + public void flush() throws IOException { + super.flush(); + out2.flush(); + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/XMindNetRequest.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/XMindNetRequest.java index e906eec16..9cd019f93 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/XMindNetRequest.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/XMindNetRequest.java @@ -1,1366 +1,1366 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.net.internal; - -import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; -import static org.xmind.core.net.internal.EncodingUtils.urlEncode; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import java.util.Set; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.json.JSONException; -import org.json.JSONObject; -import org.xmind.core.net.IDataStore; -import org.xmind.core.net.JSONStore; -import org.xmind.core.net.http.HttpRequest; - -/** - * @deprecated Use {@link HttpRequest} instead - * @author Frank Shaka - */ -public class XMindNetRequest { - - public static final int HTTP_PREPARING = 0; - - public static final int HTTP_CONNECTING = 1; - - public static final int HTTP_SENDING = 2; - - public static final int HTTP_WAITING = 3; - - public static final int HTTP_RECEIVING = 4; - - public static final int HTTP_ERROR = 999; - - /* 2XX: generally "OK" */ - - /** - * HTTP Status-Code 200: OK. - */ - public static final int HTTP_OK = HttpURLConnection.HTTP_OK; - - /** - * HTTP Status-Code 201: Created. - */ - public static final int HTTP_CREATED = HttpURLConnection.HTTP_CREATED; - - /** - * HTTP Status-Code 202: Accepted. - */ - public static final int HTTP_ACCEPTED = HttpURLConnection.HTTP_ACCEPTED; - - /** - * HTTP Status-Code 203: Non-Authoritative Information. - */ - public static final int HTTP_NOT_AUTHORITATIVE = HttpURLConnection.HTTP_NOT_AUTHORITATIVE; - - /** - * HTTP Status-Code 204: No Content. - */ - public static final int HTTP_NO_CONTENT = HttpURLConnection.HTTP_NO_CONTENT; - - /** - * HTTP Status-Code 205: Reset Content. - */ - public static final int HTTP_RESET = HttpURLConnection.HTTP_RESET; - - /** - * HTTP Status-Code 206: Partial Content. - */ - public static final int HTTP_PARTIAL = HttpURLConnection.HTTP_PARTIAL; - - /* 3XX: relocation/redirect */ - - /** - * HTTP Status-Code 300: Multiple Choices. - */ - public static final int HTTP_MULT_CHOICE = HttpURLConnection.HTTP_MULT_CHOICE; - - /** - * HTTP Status-Code 301: Moved Permanently. - */ - public static final int HTTP_MOVED_PERM = HttpURLConnection.HTTP_MOVED_PERM; - - /** - * HTTP Status-Code 302: Temporary Redirect. - */ - public static final int HTTP_MOVED_TEMP = HttpURLConnection.HTTP_MOVED_TEMP; - - /** - * HTTP Status-Code 303: See Other. - */ - public static final int HTTP_SEE_OTHER = HttpURLConnection.HTTP_SEE_OTHER; - - /** - * HTTP Status-Code 304: Not Modified. - */ - public static final int HTTP_NOT_MODIFIED = HttpURLConnection.HTTP_NOT_MODIFIED; - - /** - * HTTP Status-Code 305: Use Proxy. - */ - public static final int HTTP_USE_PROXY = HttpURLConnection.HTTP_USE_PROXY; - - /* 4XX: client error */ - - /** - * HTTP Status-Code 400: Bad Request. - */ - public static final int HTTP_BAD_REQUEST = HttpURLConnection.HTTP_BAD_REQUEST; - - /** - * HTTP Status-Code 401: Unauthorized. - */ - public static final int HTTP_UNAUTHORIZED = HttpURLConnection.HTTP_UNAUTHORIZED; - - /** - * HTTP Status-Code 402: Payment Required. - */ - public static final int HTTP_PAYMENT_REQUIRED = HttpURLConnection.HTTP_PAYMENT_REQUIRED; - - /** - * HTTP Status-Code 403: Forbidden. - */ - public static final int HTTP_FORBIDDEN = HttpURLConnection.HTTP_FORBIDDEN; - - /** - * HTTP Status-Code 404: Not Found. - */ - public static final int HTTP_NOT_FOUND = HttpURLConnection.HTTP_NOT_FOUND; - - /** - * HTTP Status-Code 405: Method Not Allowed. - */ - public static final int HTTP_BAD_METHOD = HttpURLConnection.HTTP_BAD_METHOD; - - /** - * HTTP Status-Code 406: Not Acceptable. - */ - public static final int HTTP_NOT_ACCEPTABLE = HttpURLConnection.HTTP_NOT_ACCEPTABLE; - - /** - * HTTP Status-Code 407: Proxy Authentication Required. - */ - public static final int HTTP_PROXY_AUTH = HttpURLConnection.HTTP_PROXY_AUTH; - - /** - * HTTP Status-Code 408: Request Time-Out. - */ - public static final int HTTP_CLIENT_TIMEOUT = HttpURLConnection.HTTP_CLIENT_TIMEOUT; - - /** - * HTTP Status-Code 409: Conflict. - */ - public static final int HTTP_CONFLICT = HttpURLConnection.HTTP_CONFLICT; - - /** - * HTTP Status-Code 410: Gone. - */ - public static final int HTTP_GONE = HttpURLConnection.HTTP_GONE; - - /** - * HTTP Status-Code 411: Length Required. - */ - public static final int HTTP_LENGTH_REQUIRED = HttpURLConnection.HTTP_LENGTH_REQUIRED; - - /** - * HTTP Status-Code 412: Precondition Failed. - */ - public static final int HTTP_PRECON_FAILED = HttpURLConnection.HTTP_PRECON_FAILED; - - /** - * HTTP Status-Code 413: Request HttpEntity Too Large. - */ - public static final int HTTP_ENTITY_TOO_LARGE = HttpURLConnection.HTTP_ENTITY_TOO_LARGE; - - /** - * HTTP Status-Code 414: Request-URI Too Large. - */ - public static final int HTTP_REQ_TOO_LONG = HttpURLConnection.HTTP_REQ_TOO_LONG; - - /** - * HTTP Status-Code 415: Unsupported Media Type. - */ - public static final int HTTP_UNSUPPORTED_TYPE = HttpURLConnection.HTTP_UNSUPPORTED_TYPE; - - /* 5XX: server error */ - - /** - * HTTP Status-Code 500: Internal Server Error. - */ - public static final int HTTP_INTERNAL_ERROR = HttpURLConnection.HTTP_INTERNAL_ERROR; - - /** - * HTTP Status-Code 501: Not Implemented. - */ - public static final int HTTP_NOT_IMPLEMENTED = HttpURLConnection.HTTP_NOT_IMPLEMENTED; - - /** - * HTTP Status-Code 502: Bad Gateway. - */ - public static final int HTTP_BAD_GATEWAY = HttpURLConnection.HTTP_BAD_GATEWAY; - - /** - * HTTP Status-Code 503: Service Unavailable. - */ - public static final int HTTP_UNAVAILABLE = HttpURLConnection.HTTP_UNAVAILABLE; - - /** - * HTTP Status-Code 504: Gateway Timeout. - */ - public static final int HTTP_GATEWAY_TIMEOUT = HttpURLConnection.HTTP_GATEWAY_TIMEOUT; - - /** - * HTTP Status-Code 505: HTTP Version Not Supported. - */ - public static final int HTTP_VERSION = HttpURLConnection.HTTP_VERSION; - - private static final boolean DEBUG_ALL = Activator - .isDebugging("/debug/http/requests"); //$NON-NLS-1$ - - private static final boolean DEBUG_TO_STDOUT = DEBUG_ALL - || Activator.isDebugging("/debug/requests/stdout"); //$NON-NLS-1$ - - private static final boolean DEBUG_ASSC = Activator - .isDebugging("/debug/requests/assc"); //$NON-NLS-1$ - - private static final String DEFAULT_DOMAIN = "www.xmind.net"; //$NON-NLS-1$ - - private static final String HEAD = "HEAD"; //$NON-NLS-1$ - - private static final String GET = "GET"; //$NON-NLS-1$ - - private static final String POST = "POST"; //$NON-NLS-1$ - - private static final String PUT = "PUT"; //$NON-NLS-1$ - - private static final String DELETE = "DELETE"; //$NON-NLS-1$ - - private static Set WRITABLE_METHODS = new HashSet( - Arrays.asList(POST, PUT)); - - protected static class NamedValue { - - public String name; - - public Object value; - - private String encodedName = null; - - private String encodedValue = null; - - public NamedValue(String name, Object value) { - this.name = name; - this.value = value; - } - - public String getValue() { - return value == null ? "" : value.toString(); //$NON-NLS-1$ - } - - public String getEncodedName() { - if (encodedName == null) { - encodedName = urlEncode(name); - } - return encodedName; - } - - public String getEncodedValue() { - if (encodedValue == null) { - encodedValue = urlEncode(value); - } - return encodedValue; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return String.format("%s: %s", name, value); //$NON-NLS-1$ - } - - } - - protected static abstract class RequestWriter { - - private List parameters; - - public void init(List parameters) { - this.parameters = parameters; - } - - /** - * @return the parameters - */ - protected List getParameters() { - return parameters; - } - - public abstract String getContentType(); - - public abstract long getContentLength(); - - public abstract void write(OutputStream stream) throws IOException; - - } - - protected static class FormSubmitter extends RequestWriter { - - private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8"; //$NON-NLS-1$ - - private byte[] formData = null; - - private byte[] getFormData() { - if (formData != null) - return formData; - formData = toAsciiBytes(toQueryString(getParameters())); - return formData; - } - - public String getContentType() { - return FORM_CONTENT_TYPE; - } - - public long getContentLength() { - return getFormData().length; - } - - public void write(OutputStream stream) throws IOException { - stream.write(getFormData()); - } - - } - - protected static class MultipartWriter extends RequestWriter { - - private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data; boundary="; //$NON-NLS-1$ - - /** - * The pool of ASCII chars to be used for generating a multipart - * boundary. - */ - private static final byte[] BOUNDARY_CHARS = toAsciiBytes( - "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); //$NON-NLS-1$ - - /** Carriage return/linefeed as a byte array */ - private static final byte[] CRLF = toAsciiBytes("\r\n"); //$NON-NLS-1$ - - /** Content dispostion as a byte array */ - private static final byte[] QUOTE = toAsciiBytes("\""); //$NON-NLS-1$ - - /** Extra characters as a byte array */ - private static final byte[] EXTRA = toAsciiBytes("--"); //$NON-NLS-1$ - - /** Content dispostion as a byte array */ - private static final byte[] CONTENT_DISPOSITION = toAsciiBytes( - "Content-Disposition: form-data; name="); //$NON-NLS-1$ - - /** Content type header as a byte array */ - private static final byte[] CONTENT_TYPE = toAsciiBytes( - "Content-Type: "); //$NON-NLS-1$ - - /** Content charset as a byte array */ - private static final byte[] CHARSET = toAsciiBytes("; charset=utf-8"); //$NON-NLS-1$ - - /** Content type header as a byte array */ - private static final byte[] CONTENT_TRANSFER_ENCODING = toAsciiBytes( - "Content-Transfer-Encoding: "); //$NON-NLS-1$ - - /** Attachment's file name as a byte array */ - private static final byte[] FILE_NAME = toAsciiBytes("; filename="); //$NON-NLS-1$ - - private static final byte[] FILE_CONTENT_TYPE = toAsciiBytes( - "application/octet-stream"); //$NON-NLS-1$ - - private static final byte[] TEXT_CONTENT_TYPE = toAsciiBytes( - "text/plain"); //$NON-NLS-1$ - - private static final byte[] FILE_TRANSFER_ENCODING = toAsciiBytes( - "binary"); //$NON-NLS-1$ - - private static final byte[] TEXT_TRANSFER_ENCODING = toAsciiBytes( - "8bit"); //$NON-NLS-1$ - - private byte[] boundary = null; - - private byte[] getBoundary() { - if (boundary != null) - return boundary; - Random rand = new Random(); - byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size - // from 30 to 40 - for (int i = 0; i < bytes.length; i++) { - bytes[i] = BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]; - } - boundary = bytes; - return boundary; - } - - public String getContentType() { - StringBuffer typeBuffer = new StringBuffer(MULTIPART_CONTENT_TYPE); - typeBuffer.append(EncodingUtils.toAsciiString(getBoundary())); - return typeBuffer.toString(); - } - - public long getContentLength() { - if (getParameters().isEmpty()) - return 0; - long length = 0; - for (NamedValue part : getParameters()) { - length += EXTRA.length; - length += getBoundary().length; - length += CRLF.length; - - length += CONTENT_DISPOSITION.length; - length += QUOTE.length; - length += toAsciiBytes(part.getEncodedName()).length; - length += QUOTE.length; - length += CRLF.length; - - if (part.value instanceof File) { - length += FILE_NAME.length; - length += QUOTE.length; - length += toAsciiBytes(part.getEncodedName()).length; - length += QUOTE.length; - } - - length += CONTENT_TYPE.length; - length += getContentType(part.value).length; - length += CHARSET.length; - length += CRLF.length; - - length += CONTENT_TRANSFER_ENCODING.length; - length += getTransferEncoding(part.value).length; - length += CRLF.length; - length += CRLF.length; - - length += getPartDataLength(part); - - length += CRLF.length; - - } - - length += EXTRA.length; - length += getBoundary().length; - length += EXTRA.length; - length += CRLF.length; - return length; - } - - public void write(OutputStream stream) throws IOException { - if (getParameters().isEmpty()) - return; - - for (NamedValue part : getParameters()) { - stream.write(EXTRA); - stream.write(getBoundary()); - stream.write(CRLF); - - stream.write(CONTENT_DISPOSITION); - stream.write(QUOTE); - stream.write(toAsciiBytes(part.getEncodedName())); - stream.write(QUOTE); - if (part.value instanceof File) { - stream.write(FILE_NAME); - stream.write(QUOTE); - stream.write(toAsciiBytes(((File) part.value).getName())); - stream.write(QUOTE); - } - stream.write(CRLF); - - stream.write(CONTENT_TYPE); - stream.write(getContentType(part.value)); - stream.write(CHARSET); - stream.write(CRLF); - - stream.write(CONTENT_TRANSFER_ENCODING); - stream.write(getTransferEncoding(part.value)); - stream.write(CRLF); - stream.write(CRLF); - - writePartData(stream, part); - - stream.write(CRLF); - - try { - Thread.sleep(0); - } catch (InterruptedException e) { - throw new OperationCanceledException(); - } - } - - stream.write(EXTRA); - stream.write(getBoundary()); - stream.write(EXTRA); - stream.write(CRLF); - } - - private static byte[] getContentType(Object value) { - if (value instanceof File) - return FILE_CONTENT_TYPE; - return TEXT_CONTENT_TYPE; - } - - private static byte[] getTransferEncoding(Object value) { - if (value instanceof File) - return FILE_TRANSFER_ENCODING; - return TEXT_TRANSFER_ENCODING; - } - - private static long getPartDataLength(NamedValue part) { - if (part.value instanceof File) { - return (int) ((File) part.value).length(); - } - return toAsciiBytes(part.getValue()).length; - } - - private static void writePartData(OutputStream stream, NamedValue part) - throws IOException { - if (part.value instanceof File) { - writeFromFile(stream, (File) part.value); - } else { - writeFromText(stream, part.getValue()); - } - } - - private static void writeFromFile(OutputStream writeStream, File file) - throws IOException { - FileInputStream readStream = new FileInputStream(file); - try { - byte[] buffer = new byte[4096]; - int bytes; - while ((bytes = readStream.read(buffer)) >= 0) { - writeStream.write(buffer, 0, bytes); - try { - Thread.sleep(0); - } catch (InterruptedException e) { - throw new OperationCanceledException(); - } - } - } finally { - readStream.close(); - } - } - - private static void writeFromText(OutputStream writeStream, - String encodedText) throws IOException { - // writeStream.write(toAsciiBytes(encodedText)); - writeStream.write(encodedText.getBytes("UTF-8")); //$NON-NLS-1$ - } - - } - - private boolean https; - - private String method = null; - - private String uri = null; - - private String domain = DEFAULT_DOMAIN; - - private String path = null; - - private List requestHeaders = new ArrayList(); - - private List params = new ArrayList(); - - private boolean multipart = false; - - private File targetFile = null; - - private int statusCode = HTTP_PREPARING; - - private String responseText = null; - - private IDataStore data = null; - - private List responseHeaders = new ArrayList(); - - private boolean aborted = false; - - private Throwable error = null; - - private List statusChangeListeners = new ArrayList(); - - private boolean debugging = DEBUG_ALL - || System.getProperty("org.xmind.debug.httprequests") != null; //$NON-NLS-1$ - - private long totalBytes = 0; - - private long transferedBytes = 0; - - private Thread runningThread = null; - - public XMindNetRequest() { - this(false); - } - - public XMindNetRequest(boolean useHTTPS) { - this.https = useHTTPS; - } - - /** - * Sets the URI of this request. - *

- * Note that setting this value will override all https / - * domain / path settings. - * - * @param uri - * @return - */ - public XMindNetRequest uri(String uri) { - this.uri = uri; - return this; - } - - /** - * Sets the absolute path of this request's URI. - *

- * The path should start with a "/", and may contain formatting - * tags supported by java.util.Formatter. The URI will be - * formatted as "[scheme]://[domain][path]". - * - * @param path - * the path of this request's URI - * @param values - * objects to be formatted into path - * @return - */ - public XMindNetRequest path(String path, Object... values) { - this.path = EncodingUtils.format(path, values); - return this; - } - - protected XMindNetRequest domain(String domain) { - this.domain = domain; - return this; - } - - public XMindNetRequest useHTTPS() { - this.https = true; - return this; - } - - public XMindNetRequest multipart() { - this.multipart = true; - return this; - } - - public XMindNetRequest setAuthToken(String authToken) { - return this.addHeader("AuthToken", authToken); //$NON-NLS-1$ - } - - public XMindNetRequest addHeader(String name, String value) { - requestHeaders.add(new NamedValue(name, value)); - return this; - } - - public XMindNetRequest addParameter(String name, Object value) { - params.add(new NamedValue(name, value)); - return this; - } - - public String getMethod() { - return method; - } - - public String getURI() { - StringBuffer uriBuilder = new StringBuffer(50); - if (uri != null) { - uriBuilder.append(uri); - } else if (path != null) { - String domain = this.domain == null ? DEFAULT_DOMAIN : this.domain; - if (https) { - uriBuilder.append("https://"); //$NON-NLS-1$ - } else { - uriBuilder.append("http://"); //$NON-NLS-1$ - } - uriBuilder.append(domain); - uriBuilder.append(path); - } else { - return null; - } - if (!WRITABLE_METHODS.contains(method) && !params.isEmpty()) { - int i = uriBuilder.indexOf("?"); //$NON-NLS-1$ - if (i >= 0) { - if (i < uriBuilder.length() - 1) { - uriBuilder.append('&'); - } else { - // append nothing if '?' is the last character. - } - } else { - uriBuilder.append('?'); - } - uriBuilder.append(toQueryString(params)); - } - return uriBuilder.toString(); - } - - /** - * @return the totalBytes - */ - public long getTotalBytes() { - return totalBytes; - } - - /** - * @return the transferedBytes - */ - public long getTransferedBytes() { - return transferedBytes; - } - - /** - * Set the target file where the response body will be stored. - *

- * Note that setting the target file to non-null will cause both - * getResponseText() and getData() return null should the request succeed. - * - * @param file - * the target file - * @return this request - */ - public XMindNetRequest setTargetFile(File file) { - this.targetFile = file; - return this; - } - - public File getTargetFile() { - return targetFile; - } - - public void abort() { - this.aborted = true; - Thread theThread = this.runningThread; - if (theThread != null) { - theThread.interrupt(); - } - } - - public boolean isAborted() { - return aborted; - } - - public XMindNetRequest head() { - this.method = HEAD; - return execute(); - } - - public XMindNetRequest get() { - this.method = GET; - return execute(); - } - - public XMindNetRequest put() { - this.method = PUT; - return execute(); - } - - public XMindNetRequest delete() { - this.method = DELETE; - return execute(); - } - - public XMindNetRequest post() { - this.method = POST; - return execute(); - } - - public int getStatusCode() { - return statusCode; - } - - public IDataStore getData() { - return data; - } - - public String getResponseText() { - return responseText; - } - - public List getAllResponseHeaders() { - List keys = new ArrayList(responseHeaders.size()); - for (NamedValue header : responseHeaders) { - keys.add(header.name); - } - return keys; - } - - public String getResponseHeader(String name) { - if (name != null) { - for (NamedValue header : responseHeaders) { - if (name.equalsIgnoreCase(header.name)) - return header.getValue(); - } - } - return null; - } - - public boolean isRunning() { - return runningThread != null; - } - - protected synchronized XMindNetRequest execute() { - runningThread = Thread.currentThread(); - try { - if (isAborted()) - return this; - - if (method == null) - throw new IllegalStateException( - "Invalid HTTP Request: no method specified"); //$NON-NLS-1$ - - final String uri = getURI(); - if (uri == null) - throw new IllegalStateException( - "Invalid HTTP Request: no URI/path specified"); //$NON-NLS-1$ - - final RequestWriter writer = createRequestWriter(); - if (isAborted()) - return this; - - Thread thread = new Thread(new Runnable() { - public void run() { - executeInDaemonThread(uri, writer); - } - }, "XMindNetRequestConnection:" + uri); //$NON-NLS-1$ - thread.setDaemon(true); - thread.setPriority( - (Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2); - thread.start(); - try { - thread.join(); - } catch (InterruptedException e) { - // probably aborted by user - } - - return this; - } finally { - runningThread = null; - } - } - - private void executeInDaemonThread(String uri, RequestWriter writer) { - error = null; - try { - if (isAborted()) - return; - debug("HTTP Request: (Prepared) %s %s\r\n%s", method, uri, //$NON-NLS-1$ - requestHeaders); - send(uri, writer); - if (isAborted()) - return; - } catch (OperationCanceledException e) { - debug("HTTP Request: (Aborted) %s %s", method, uri); //$NON-NLS-1$ - if (!isAborted()) { - abort(); - } - } catch (Throwable e) { - if (!isAborted()) { - error = e; - debug("HTTP Request: (Error: %s) %s %s", e, method, uri); //$NON-NLS-1$ - } - } - } - - protected void send(String uri, RequestWriter writer) throws IOException { - this.data = null; - this.responseText = null; - this.responseHeaders.clear(); - - setStatusCode(HTTP_CONNECTING); - debug("HTTP Request: (Connecting...) %s %s", method, uri); //$NON-NLS-1$ - if (isAborted()) - throw new OperationCanceledException(); - - URL url = new URL(uri); - if (isAborted()) - throw new OperationCanceledException(); - - HttpURLConnection connection; - Proxy proxy = getProxy(uri); - if (proxy != null) { - debug("HTTP Request: (Applying proxy %s) %s %s", proxy, method, //$NON-NLS-1$ - uri); - connection = (HttpURLConnection) url.openConnection(proxy); - } else { - connection = (HttpURLConnection) url.openConnection(); - } - if (isAborted()) - throw new OperationCanceledException(); - if (DEBUG_ASSC) { - assc(connection); - if (isAborted()) - throw new OperationCanceledException(); - } - - setStatusCode(HTTP_SENDING); - debug("HTTP Request: (Sending data...) %s %s", method, uri); //$NON-NLS-1$ - if (isAborted()) - throw new OperationCanceledException(); - - try { - connection.setDoOutput(writer != null); - if (isAborted()) - throw new OperationCanceledException(); - connection.setRequestMethod(method); - if (isAborted()) - throw new OperationCanceledException(); - - if (writer != null) { - writer.init(params); - } - if (isAborted()) - throw new OperationCanceledException(); - - writeHeaders(uri, connection, writer); - if (isAborted()) - throw new OperationCanceledException(); - - if (writer != null) { - writeBody(uri, connection, writer); - } - if (isAborted()) - throw new OperationCanceledException(); - - setStatusCode(HTTP_WAITING); - debug("HTTP Request: (Waiting...) %s %s", method, uri); //$NON-NLS-1$ - if (isAborted()) - throw new OperationCanceledException(); - - readResponse(uri, connection, connection.getInputStream(), - connection.getResponseCode()); - if (isAborted()) - throw new OperationCanceledException(); - } catch (IOException e) { - if (isAborted()) - throw new OperationCanceledException(); - readResponse(uri, connection, connection.getErrorStream(), - connection.getResponseCode()); - if (isAborted()) - throw new OperationCanceledException(); - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - - protected Proxy getProxy(String uri) { - /* - * Return null and let HttpURLConnection read proxy settings from system - * properties. Note that plugin 'org.eclipse.core.net' writes its proxy - * settings to system properties when it's activated, so if you relies - * on this plugin to provide proxy settings please make sure to activate - * it before making any http request. - */ - return null; - } - - public Throwable getError() { - return error; - } - - private RequestWriter createRequestWriter() { - if (WRITABLE_METHODS.contains(method)) { - if (multipart) - return new MultipartWriter(); - return new FormSubmitter(); - } - return null; - } - - protected void writeHeaders(String uri, URLConnection connection, - RequestWriter writer) { - List writtenHeaders = new ArrayList(); - Object accept = null; - for (NamedValue header : requestHeaders) { - writeHeader(connection, header.name, header.getValue(), - writtenHeaders); - if ("Accept".equalsIgnoreCase(header.name)) //$NON-NLS-1$ - accept = header.value; - } - - if (accept == null || "".equals(accept)) { //$NON-NLS-1$ - writeHeader(connection, "Accept", "application/json", //$NON-NLS-1$//$NON-NLS-2$ - writtenHeaders); - } - writeHeader(connection, "X-Client-ID", getClientId(), writtenHeaders); //$NON-NLS-1$ - if (writer != null) { - writeHeader(connection, "Content-Type", //$NON-NLS-1$ - writer.getContentType(), writtenHeaders); - writeHeader(connection, "Content-Length", //$NON-NLS-1$ - String.valueOf(writer.getContentLength()), writtenHeaders); - } - debug("HTTP Request: (Headers written) %s %s\r\n%s", method, uri, //$NON-NLS-1$ - writtenHeaders); - } - - private String getClientId() { - return "xmind_v3.4.1"; //$NON-NLS-1$ - } - - protected void writeHeader(URLConnection connection, String key, - String value, List headers) { - connection.setRequestProperty(key, value); - headers.add(new NamedValue(key, value)); - } - - private void writeBody(String uri, URLConnection connection, - RequestWriter writer) throws IOException { - OutputStream writeStream = connection.getOutputStream(); - if (isAborted()) - throw new OperationCanceledException(); - BufferedOutputStream bufferedWriteStream = new BufferedOutputStream( - writeStream); - if (isAborted()) - throw new OperationCanceledException(); - writer.write(bufferedWriteStream); - if (isAborted()) - throw new OperationCanceledException(); - bufferedWriteStream.flush(); - writeStream.flush(); - } - - protected static String toQueryString(List parameters) { - StringBuffer buffer = new StringBuffer(parameters.size() * 15); - for (int i = 0; i < parameters.size(); i++) { - NamedValue param = parameters.get(i); - if (i > 0) { - buffer.append('&'); - } - buffer.append(param.getEncodedName()); - buffer.append('='); - buffer.append(param.getEncodedValue()); - } - return buffer.toString(); - } - - protected void readResponse(String uri, URLConnection connection, - InputStream readStream, int responseCode) throws IOException { - this.responseText = null; - this.data = null; - this.responseHeaders.clear(); - if (responseCode < 0) { - responseCode = HTTP_ERROR; - } - try { - readResponseHeaders(connection); - if (isAborted()) - throw new OperationCanceledException(); - if (responseCode == HTTP_ERROR) { - setStatusCode(responseCode); - debug("HTTP Response: (Unknown error) %s %s", method, uri); //$NON-NLS-1$ - } else { - this.totalBytes = 0; - this.transferedBytes = 0; - String length = getResponseHeader("Content-Length"); //$NON-NLS-1$ - if (length != null) { - try { - this.totalBytes = Long.parseLong(length, 10); - } catch (NumberFormatException e) { - } - } - if (isAborted()) - throw new OperationCanceledException(); - if (this.totalBytes == 0) { - this.totalBytes = readStream.available(); - } - if (isAborted()) - throw new OperationCanceledException(); - setStatusCode(HTTP_RECEIVING); - debug("HTTP Request: (Receiving data, total %s bytes...) [%s] %s %s", //$NON-NLS-1$ - totalBytes, responseCode, method, uri); - if (isAborted()) - throw new OperationCanceledException(); - if (targetFile != null && responseCode >= 200 - && responseCode < 300) { - saveTargetFile(readStream); - setStatusCode(responseCode); - debug("HTTP Request: (Response) [%s] %s %s\r\n%s\r\nSaved to '%s' (%s bytes).", //$NON-NLS-1$ - getStatusCode(), method, uri, responseHeaders, - targetFile.getAbsolutePath(), targetFile.length()); - } else { - int wrappedResponseCode = readResponseData(readStream); - if (wrappedResponseCode >= 100) { - setStatusCode(wrappedResponseCode); - } else { - setStatusCode(responseCode); - } - debug("HTTP Request: (Response) [%s] %s %s\r\n%s\r\n%s", //$NON-NLS-1$ - responseCode, method, uri, responseHeaders, - responseText); - } - } - } finally { - if (statusCode < 100 && responseCode >= 100) { - setStatusCode(responseCode); - } - } - } - - /** - * @param connection - */ - private int readResponseData(InputStream readStream) throws IOException { - this.responseText = readResponseText(readStream); - if (!"".equals(this.responseText)) { //$NON-NLS-1$ - String respType = getResponseHeader("Content-Type"); //$NON-NLS-1$ - if (respType != null && respType.indexOf("application/json") >= 0) { //$NON-NLS-1$ - try { - this.data = new JSONStore( - new JSONObject(this.responseText)); - if (this.data.has("_code")) { //$NON-NLS-1$ - return this.data.getInt("_code"); //$NON-NLS-1$ - } - } catch (JSONException e) { - this.error = e; - } - } - } - return 0; - } - - private String readResponseText(InputStream readStream) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream( - Math.max((int) totalBytes, 1024)); - transfer(readStream, bytes); - return bytes.toString("utf-8"); //$NON-NLS-1$ - } - - /** - * @param connection - */ - private void saveTargetFile(InputStream readStream) throws IOException { - File file = this.targetFile; - File dir = file.getParentFile(); - if (!dir.exists()) { - dir.mkdirs(); - } - OutputStream fileWriteStream = new FileOutputStream(file); - try { - transfer(readStream, fileWriteStream); - } finally { - fileWriteStream.close(); - } - } - - protected void transfer(InputStream readStream, OutputStream writeStream) - throws IOException { - transfer(readStream, writeStream, 1024); - } - - protected void transfer(InputStream readStream, OutputStream writeStream, - int bufSize) throws IOException { - if (bufSize <= 0) - bufSize = 1024; - byte[] buffer = new byte[bufSize]; - int bytes; - while ((bytes = readStream.read(buffer)) >= 0) { - writeStream.write(buffer, 0, bytes); - this.transferedBytes += bytes; - if (isAborted()) - throw new OperationCanceledException(); - try { - Thread.sleep(0); - } catch (InterruptedException e) { - throw new OperationCanceledException(); - } - } - } - - /** - * @param connection - */ - private void readResponseHeaders(URLConnection connection) { - // Skip status line: - connection.getHeaderField(0); - // Start from 2nd header line: - int i = 1; - String key, value; - while ((key = connection.getHeaderFieldKey(i)) != null) { - value = connection.getHeaderField(i); - responseHeaders.add(new NamedValue(key, value)); - i++; - } - } - - public XMindNetRequest debug() { - this.debugging = true; - return this; - } - - public void addStatusChangeListener(IRequestStatusChangeListener listener) { - statusChangeListeners.add(listener); - } - - public void removeStatusChangeListener( - IRequestStatusChangeListener listener) { - statusChangeListeners.remove(listener); - } - - protected void setStatusCode(int newStatus) { - if (newStatus == this.statusCode) - return; - int oldStatus = this.statusCode; - this.statusCode = newStatus; - fireStatusChanged(oldStatus); - } - - protected void fireStatusChanged(final int oldStatus) { - final int newStatus = this.statusCode; - IRequestStatusChangeListener[] listeners = statusChangeListeners - .toArray(new IRequestStatusChangeListener[statusChangeListeners - .size()]); - for (int i = 0; i < listeners.length; i++) { - try { - listeners[i].requestStatusChanged(this, oldStatus, newStatus); - } catch (Throwable e) { - Activator.getDefault().getLog().log(new Status(IStatus.WARNING, - Activator.PLUGIN_ID, - "Error occurred when notifying request status change.", //$NON-NLS-1$ - e)); - } - } - } - - protected void debug(String format, Object... values) { - if (!debugging) - return; - if (DEBUG_TO_STDOUT) { - System.out.println(String.format(format, values)); - } else { - Activator.log(String.format(format, values)); - } - } - - private static void assc(HttpURLConnection connection) { - try { - TrustModifier.relaxHostChecking(connection); - } catch (Exception e) { - if (DEBUG_TO_STDOUT) { - e.printStackTrace(); - System.err.println("Failed to relax host checking."); //$NON-NLS-1$ - } else { - Activator.getDefault().getLog() - .log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, - "Failed to relax host checking.", e)); //$NON-NLS-1$ - } - } - } - - /** - * A solution to accept self-signed SSL certificates. - * - *

- * Source came from Craig Flichel's post Ignoring Self-Signed Certificates in Java on Dec 1, 2011. - *

- * - * @author Craig Flichel - */ - private static class TrustModifier { - private static final TrustingHostnameVerifier TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier(); - private static SSLSocketFactory factory; - - /** - * Call this with any HttpURLConnection, and it will modify the trust - * settings if it is an HTTPS connection. - */ - public static void relaxHostChecking(HttpURLConnection conn) - throws KeyManagementException, NoSuchAlgorithmException, - KeyStoreException { - - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection httpsConnection = (HttpsURLConnection) conn; - SSLSocketFactory factory = prepFactory(httpsConnection); - httpsConnection.setSSLSocketFactory(factory); - httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER); - } - } - - static synchronized SSLSocketFactory prepFactory( - HttpsURLConnection httpsConnection) - throws NoSuchAlgorithmException, KeyStoreException, - KeyManagementException { - - if (factory == null) { - SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ - ctx.init(null, new TrustManager[] { new AlwaysTrustManager() }, - null); - factory = ctx.getSocketFactory(); - } - return factory; - } - - private static final class TrustingHostnameVerifier - implements HostnameVerifier { - public boolean verify(String hostname, SSLSession session) { - return true; - } - } - - private static class AlwaysTrustManager implements X509TrustManager { - public void checkClientTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - } - - public void checkServerTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - } - - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.net.internal; + +import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; +import static org.xmind.core.net.internal.EncodingUtils.urlEncode; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.json.JSONException; +import org.json.JSONObject; +import org.xmind.core.net.IDataStore; +import org.xmind.core.net.JSONStore; +import org.xmind.core.net.http.HttpRequest; + +/** + * @deprecated Use {@link HttpRequest} instead + * @author Frank Shaka + */ +public class XMindNetRequest { + + public static final int HTTP_PREPARING = 0; + + public static final int HTTP_CONNECTING = 1; + + public static final int HTTP_SENDING = 2; + + public static final int HTTP_WAITING = 3; + + public static final int HTTP_RECEIVING = 4; + + public static final int HTTP_ERROR = 999; + + /* 2XX: generally "OK" */ + + /** + * HTTP Status-Code 200: OK. + */ + public static final int HTTP_OK = HttpURLConnection.HTTP_OK; + + /** + * HTTP Status-Code 201: Created. + */ + public static final int HTTP_CREATED = HttpURLConnection.HTTP_CREATED; + + /** + * HTTP Status-Code 202: Accepted. + */ + public static final int HTTP_ACCEPTED = HttpURLConnection.HTTP_ACCEPTED; + + /** + * HTTP Status-Code 203: Non-Authoritative Information. + */ + public static final int HTTP_NOT_AUTHORITATIVE = HttpURLConnection.HTTP_NOT_AUTHORITATIVE; + + /** + * HTTP Status-Code 204: No Content. + */ + public static final int HTTP_NO_CONTENT = HttpURLConnection.HTTP_NO_CONTENT; + + /** + * HTTP Status-Code 205: Reset Content. + */ + public static final int HTTP_RESET = HttpURLConnection.HTTP_RESET; + + /** + * HTTP Status-Code 206: Partial Content. + */ + public static final int HTTP_PARTIAL = HttpURLConnection.HTTP_PARTIAL; + + /* 3XX: relocation/redirect */ + + /** + * HTTP Status-Code 300: Multiple Choices. + */ + public static final int HTTP_MULT_CHOICE = HttpURLConnection.HTTP_MULT_CHOICE; + + /** + * HTTP Status-Code 301: Moved Permanently. + */ + public static final int HTTP_MOVED_PERM = HttpURLConnection.HTTP_MOVED_PERM; + + /** + * HTTP Status-Code 302: Temporary Redirect. + */ + public static final int HTTP_MOVED_TEMP = HttpURLConnection.HTTP_MOVED_TEMP; + + /** + * HTTP Status-Code 303: See Other. + */ + public static final int HTTP_SEE_OTHER = HttpURLConnection.HTTP_SEE_OTHER; + + /** + * HTTP Status-Code 304: Not Modified. + */ + public static final int HTTP_NOT_MODIFIED = HttpURLConnection.HTTP_NOT_MODIFIED; + + /** + * HTTP Status-Code 305: Use Proxy. + */ + public static final int HTTP_USE_PROXY = HttpURLConnection.HTTP_USE_PROXY; + + /* 4XX: client error */ + + /** + * HTTP Status-Code 400: Bad Request. + */ + public static final int HTTP_BAD_REQUEST = HttpURLConnection.HTTP_BAD_REQUEST; + + /** + * HTTP Status-Code 401: Unauthorized. + */ + public static final int HTTP_UNAUTHORIZED = HttpURLConnection.HTTP_UNAUTHORIZED; + + /** + * HTTP Status-Code 402: Payment Required. + */ + public static final int HTTP_PAYMENT_REQUIRED = HttpURLConnection.HTTP_PAYMENT_REQUIRED; + + /** + * HTTP Status-Code 403: Forbidden. + */ + public static final int HTTP_FORBIDDEN = HttpURLConnection.HTTP_FORBIDDEN; + + /** + * HTTP Status-Code 404: Not Found. + */ + public static final int HTTP_NOT_FOUND = HttpURLConnection.HTTP_NOT_FOUND; + + /** + * HTTP Status-Code 405: Method Not Allowed. + */ + public static final int HTTP_BAD_METHOD = HttpURLConnection.HTTP_BAD_METHOD; + + /** + * HTTP Status-Code 406: Not Acceptable. + */ + public static final int HTTP_NOT_ACCEPTABLE = HttpURLConnection.HTTP_NOT_ACCEPTABLE; + + /** + * HTTP Status-Code 407: Proxy Authentication Required. + */ + public static final int HTTP_PROXY_AUTH = HttpURLConnection.HTTP_PROXY_AUTH; + + /** + * HTTP Status-Code 408: Request Time-Out. + */ + public static final int HTTP_CLIENT_TIMEOUT = HttpURLConnection.HTTP_CLIENT_TIMEOUT; + + /** + * HTTP Status-Code 409: Conflict. + */ + public static final int HTTP_CONFLICT = HttpURLConnection.HTTP_CONFLICT; + + /** + * HTTP Status-Code 410: Gone. + */ + public static final int HTTP_GONE = HttpURLConnection.HTTP_GONE; + + /** + * HTTP Status-Code 411: Length Required. + */ + public static final int HTTP_LENGTH_REQUIRED = HttpURLConnection.HTTP_LENGTH_REQUIRED; + + /** + * HTTP Status-Code 412: Precondition Failed. + */ + public static final int HTTP_PRECON_FAILED = HttpURLConnection.HTTP_PRECON_FAILED; + + /** + * HTTP Status-Code 413: Request HttpEntity Too Large. + */ + public static final int HTTP_ENTITY_TOO_LARGE = HttpURLConnection.HTTP_ENTITY_TOO_LARGE; + + /** + * HTTP Status-Code 414: Request-URI Too Large. + */ + public static final int HTTP_REQ_TOO_LONG = HttpURLConnection.HTTP_REQ_TOO_LONG; + + /** + * HTTP Status-Code 415: Unsupported Media Type. + */ + public static final int HTTP_UNSUPPORTED_TYPE = HttpURLConnection.HTTP_UNSUPPORTED_TYPE; + + /* 5XX: server error */ + + /** + * HTTP Status-Code 500: Internal Server Error. + */ + public static final int HTTP_INTERNAL_ERROR = HttpURLConnection.HTTP_INTERNAL_ERROR; + + /** + * HTTP Status-Code 501: Not Implemented. + */ + public static final int HTTP_NOT_IMPLEMENTED = HttpURLConnection.HTTP_NOT_IMPLEMENTED; + + /** + * HTTP Status-Code 502: Bad Gateway. + */ + public static final int HTTP_BAD_GATEWAY = HttpURLConnection.HTTP_BAD_GATEWAY; + + /** + * HTTP Status-Code 503: Service Unavailable. + */ + public static final int HTTP_UNAVAILABLE = HttpURLConnection.HTTP_UNAVAILABLE; + + /** + * HTTP Status-Code 504: Gateway Timeout. + */ + public static final int HTTP_GATEWAY_TIMEOUT = HttpURLConnection.HTTP_GATEWAY_TIMEOUT; + + /** + * HTTP Status-Code 505: HTTP Version Not Supported. + */ + public static final int HTTP_VERSION = HttpURLConnection.HTTP_VERSION; + + private static final boolean DEBUG_ALL = Activator + .isDebugging("/debug/http/requests"); //$NON-NLS-1$ + + private static final boolean DEBUG_TO_STDOUT = DEBUG_ALL + || Activator.isDebugging("/debug/requests/stdout"); //$NON-NLS-1$ + + private static final boolean DEBUG_ASSC = Activator + .isDebugging("/debug/requests/assc"); //$NON-NLS-1$ + + private static final String DEFAULT_DOMAIN = "www.xmind.net"; //$NON-NLS-1$ + + private static final String HEAD = "HEAD"; //$NON-NLS-1$ + + private static final String GET = "GET"; //$NON-NLS-1$ + + private static final String POST = "POST"; //$NON-NLS-1$ + + private static final String PUT = "PUT"; //$NON-NLS-1$ + + private static final String DELETE = "DELETE"; //$NON-NLS-1$ + + private static Set WRITABLE_METHODS = new HashSet( + Arrays.asList(POST, PUT)); + + protected static class NamedValue { + + public String name; + + public Object value; + + private String encodedName = null; + + private String encodedValue = null; + + public NamedValue(String name, Object value) { + this.name = name; + this.value = value; + } + + public String getValue() { + return value == null ? "" : value.toString(); //$NON-NLS-1$ + } + + public String getEncodedName() { + if (encodedName == null) { + encodedName = urlEncode(name); + } + return encodedName; + } + + public String getEncodedValue() { + if (encodedValue == null) { + encodedValue = urlEncode(value); + } + return encodedValue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String.format("%s: %s", name, value); //$NON-NLS-1$ + } + + } + + protected static abstract class RequestWriter { + + private List parameters; + + public void init(List parameters) { + this.parameters = parameters; + } + + /** + * @return the parameters + */ + protected List getParameters() { + return parameters; + } + + public abstract String getContentType(); + + public abstract long getContentLength(); + + public abstract void write(OutputStream stream) throws IOException; + + } + + protected static class FormSubmitter extends RequestWriter { + + private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8"; //$NON-NLS-1$ + + private byte[] formData = null; + + private byte[] getFormData() { + if (formData != null) + return formData; + formData = toAsciiBytes(toQueryString(getParameters())); + return formData; + } + + public String getContentType() { + return FORM_CONTENT_TYPE; + } + + public long getContentLength() { + return getFormData().length; + } + + public void write(OutputStream stream) throws IOException { + stream.write(getFormData()); + } + + } + + protected static class MultipartWriter extends RequestWriter { + + private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data; boundary="; //$NON-NLS-1$ + + /** + * The pool of ASCII chars to be used for generating a multipart + * boundary. + */ + private static final byte[] BOUNDARY_CHARS = toAsciiBytes( + "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); //$NON-NLS-1$ + + /** Carriage return/linefeed as a byte array */ + private static final byte[] CRLF = toAsciiBytes("\r\n"); //$NON-NLS-1$ + + /** Content dispostion as a byte array */ + private static final byte[] QUOTE = toAsciiBytes("\""); //$NON-NLS-1$ + + /** Extra characters as a byte array */ + private static final byte[] EXTRA = toAsciiBytes("--"); //$NON-NLS-1$ + + /** Content dispostion as a byte array */ + private static final byte[] CONTENT_DISPOSITION = toAsciiBytes( + "Content-Disposition: form-data; name="); //$NON-NLS-1$ + + /** Content type header as a byte array */ + private static final byte[] CONTENT_TYPE = toAsciiBytes( + "Content-Type: "); //$NON-NLS-1$ + + /** Content charset as a byte array */ + private static final byte[] CHARSET = toAsciiBytes("; charset=utf-8"); //$NON-NLS-1$ + + /** Content type header as a byte array */ + private static final byte[] CONTENT_TRANSFER_ENCODING = toAsciiBytes( + "Content-Transfer-Encoding: "); //$NON-NLS-1$ + + /** Attachment's file name as a byte array */ + private static final byte[] FILE_NAME = toAsciiBytes("; filename="); //$NON-NLS-1$ + + private static final byte[] FILE_CONTENT_TYPE = toAsciiBytes( + "application/octet-stream"); //$NON-NLS-1$ + + private static final byte[] TEXT_CONTENT_TYPE = toAsciiBytes( + "text/plain"); //$NON-NLS-1$ + + private static final byte[] FILE_TRANSFER_ENCODING = toAsciiBytes( + "binary"); //$NON-NLS-1$ + + private static final byte[] TEXT_TRANSFER_ENCODING = toAsciiBytes( + "8bit"); //$NON-NLS-1$ + + private byte[] boundary = null; + + private byte[] getBoundary() { + if (boundary != null) + return boundary; + Random rand = new Random(); + byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size + // from 30 to 40 + for (int i = 0; i < bytes.length; i++) { + bytes[i] = BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]; + } + boundary = bytes; + return boundary; + } + + public String getContentType() { + StringBuffer typeBuffer = new StringBuffer(MULTIPART_CONTENT_TYPE); + typeBuffer.append(EncodingUtils.toAsciiString(getBoundary())); + return typeBuffer.toString(); + } + + public long getContentLength() { + if (getParameters().isEmpty()) + return 0; + long length = 0; + for (NamedValue part : getParameters()) { + length += EXTRA.length; + length += getBoundary().length; + length += CRLF.length; + + length += CONTENT_DISPOSITION.length; + length += QUOTE.length; + length += toAsciiBytes(part.getEncodedName()).length; + length += QUOTE.length; + length += CRLF.length; + + if (part.value instanceof File) { + length += FILE_NAME.length; + length += QUOTE.length; + length += toAsciiBytes(part.getEncodedName()).length; + length += QUOTE.length; + } + + length += CONTENT_TYPE.length; + length += getContentType(part.value).length; + length += CHARSET.length; + length += CRLF.length; + + length += CONTENT_TRANSFER_ENCODING.length; + length += getTransferEncoding(part.value).length; + length += CRLF.length; + length += CRLF.length; + + length += getPartDataLength(part); + + length += CRLF.length; + + } + + length += EXTRA.length; + length += getBoundary().length; + length += EXTRA.length; + length += CRLF.length; + return length; + } + + public void write(OutputStream stream) throws IOException { + if (getParameters().isEmpty()) + return; + + for (NamedValue part : getParameters()) { + stream.write(EXTRA); + stream.write(getBoundary()); + stream.write(CRLF); + + stream.write(CONTENT_DISPOSITION); + stream.write(QUOTE); + stream.write(toAsciiBytes(part.getEncodedName())); + stream.write(QUOTE); + if (part.value instanceof File) { + stream.write(FILE_NAME); + stream.write(QUOTE); + stream.write(toAsciiBytes(((File) part.value).getName())); + stream.write(QUOTE); + } + stream.write(CRLF); + + stream.write(CONTENT_TYPE); + stream.write(getContentType(part.value)); + stream.write(CHARSET); + stream.write(CRLF); + + stream.write(CONTENT_TRANSFER_ENCODING); + stream.write(getTransferEncoding(part.value)); + stream.write(CRLF); + stream.write(CRLF); + + writePartData(stream, part); + + stream.write(CRLF); + + try { + Thread.sleep(0); + } catch (InterruptedException e) { + throw new OperationCanceledException(); + } + } + + stream.write(EXTRA); + stream.write(getBoundary()); + stream.write(EXTRA); + stream.write(CRLF); + } + + private static byte[] getContentType(Object value) { + if (value instanceof File) + return FILE_CONTENT_TYPE; + return TEXT_CONTENT_TYPE; + } + + private static byte[] getTransferEncoding(Object value) { + if (value instanceof File) + return FILE_TRANSFER_ENCODING; + return TEXT_TRANSFER_ENCODING; + } + + private static long getPartDataLength(NamedValue part) { + if (part.value instanceof File) { + return (int) ((File) part.value).length(); + } + return toAsciiBytes(part.getValue()).length; + } + + private static void writePartData(OutputStream stream, NamedValue part) + throws IOException { + if (part.value instanceof File) { + writeFromFile(stream, (File) part.value); + } else { + writeFromText(stream, part.getValue()); + } + } + + private static void writeFromFile(OutputStream writeStream, File file) + throws IOException { + FileInputStream readStream = new FileInputStream(file); + try { + byte[] buffer = new byte[4096]; + int bytes; + while ((bytes = readStream.read(buffer)) >= 0) { + writeStream.write(buffer, 0, bytes); + try { + Thread.sleep(0); + } catch (InterruptedException e) { + throw new OperationCanceledException(); + } + } + } finally { + readStream.close(); + } + } + + private static void writeFromText(OutputStream writeStream, + String encodedText) throws IOException { + // writeStream.write(toAsciiBytes(encodedText)); + writeStream.write(encodedText.getBytes("UTF-8")); //$NON-NLS-1$ + } + + } + + private boolean https; + + private String method = null; + + private String uri = null; + + private String domain = DEFAULT_DOMAIN; + + private String path = null; + + private List requestHeaders = new ArrayList(); + + private List params = new ArrayList(); + + private boolean multipart = false; + + private File targetFile = null; + + private int statusCode = HTTP_PREPARING; + + private String responseText = null; + + private IDataStore data = null; + + private List responseHeaders = new ArrayList(); + + private boolean aborted = false; + + private Throwable error = null; + + private List statusChangeListeners = new ArrayList(); + + private boolean debugging = DEBUG_ALL + || System.getProperty("org.xmind.debug.httprequests") != null; //$NON-NLS-1$ + + private long totalBytes = 0; + + private long transferedBytes = 0; + + private Thread runningThread = null; + + public XMindNetRequest() { + this(false); + } + + public XMindNetRequest(boolean useHTTPS) { + this.https = useHTTPS; + } + + /** + * Sets the URI of this request. + *

+ * Note that setting this value will override all https / + * domain / path settings. + * + * @param uri + * @return + */ + public XMindNetRequest uri(String uri) { + this.uri = uri; + return this; + } + + /** + * Sets the absolute path of this request's URI. + *

+ * The path should start with a "/", and may contain formatting + * tags supported by java.util.Formatter. The URI will be + * formatted as "[scheme]://[domain][path]". + * + * @param path + * the path of this request's URI + * @param values + * objects to be formatted into path + * @return + */ + public XMindNetRequest path(String path, Object... values) { + this.path = EncodingUtils.format(path, values); + return this; + } + + protected XMindNetRequest domain(String domain) { + this.domain = domain; + return this; + } + + public XMindNetRequest useHTTPS() { + this.https = true; + return this; + } + + public XMindNetRequest multipart() { + this.multipart = true; + return this; + } + + public XMindNetRequest setAuthToken(String authToken) { + return this.addHeader("AuthToken", authToken); //$NON-NLS-1$ + } + + public XMindNetRequest addHeader(String name, String value) { + requestHeaders.add(new NamedValue(name, value)); + return this; + } + + public XMindNetRequest addParameter(String name, Object value) { + params.add(new NamedValue(name, value)); + return this; + } + + public String getMethod() { + return method; + } + + public String getURI() { + StringBuffer uriBuilder = new StringBuffer(50); + if (uri != null) { + uriBuilder.append(uri); + } else if (path != null) { + String domain = this.domain == null ? DEFAULT_DOMAIN : this.domain; + if (https) { + uriBuilder.append("https://"); //$NON-NLS-1$ + } else { + uriBuilder.append("http://"); //$NON-NLS-1$ + } + uriBuilder.append(domain); + uriBuilder.append(path); + } else { + return null; + } + if (!WRITABLE_METHODS.contains(method) && !params.isEmpty()) { + int i = uriBuilder.indexOf("?"); //$NON-NLS-1$ + if (i >= 0) { + if (i < uriBuilder.length() - 1) { + uriBuilder.append('&'); + } else { + // append nothing if '?' is the last character. + } + } else { + uriBuilder.append('?'); + } + uriBuilder.append(toQueryString(params)); + } + return uriBuilder.toString(); + } + + /** + * @return the totalBytes + */ + public long getTotalBytes() { + return totalBytes; + } + + /** + * @return the transferedBytes + */ + public long getTransferedBytes() { + return transferedBytes; + } + + /** + * Set the target file where the response body will be stored. + *

+ * Note that setting the target file to non-null will cause both + * getResponseText() and getData() return null should the request succeed. + * + * @param file + * the target file + * @return this request + */ + public XMindNetRequest setTargetFile(File file) { + this.targetFile = file; + return this; + } + + public File getTargetFile() { + return targetFile; + } + + public void abort() { + this.aborted = true; + Thread theThread = this.runningThread; + if (theThread != null) { + theThread.interrupt(); + } + } + + public boolean isAborted() { + return aborted; + } + + public XMindNetRequest head() { + this.method = HEAD; + return execute(); + } + + public XMindNetRequest get() { + this.method = GET; + return execute(); + } + + public XMindNetRequest put() { + this.method = PUT; + return execute(); + } + + public XMindNetRequest delete() { + this.method = DELETE; + return execute(); + } + + public XMindNetRequest post() { + this.method = POST; + return execute(); + } + + public int getStatusCode() { + return statusCode; + } + + public IDataStore getData() { + return data; + } + + public String getResponseText() { + return responseText; + } + + public List getAllResponseHeaders() { + List keys = new ArrayList(responseHeaders.size()); + for (NamedValue header : responseHeaders) { + keys.add(header.name); + } + return keys; + } + + public String getResponseHeader(String name) { + if (name != null) { + for (NamedValue header : responseHeaders) { + if (name.equalsIgnoreCase(header.name)) + return header.getValue(); + } + } + return null; + } + + public boolean isRunning() { + return runningThread != null; + } + + protected synchronized XMindNetRequest execute() { + runningThread = Thread.currentThread(); + try { + if (isAborted()) + return this; + + if (method == null) + throw new IllegalStateException( + "Invalid HTTP Request: no method specified"); //$NON-NLS-1$ + + final String uri = getURI(); + if (uri == null) + throw new IllegalStateException( + "Invalid HTTP Request: no URI/path specified"); //$NON-NLS-1$ + + final RequestWriter writer = createRequestWriter(); + if (isAborted()) + return this; + + Thread thread = new Thread(new Runnable() { + public void run() { + executeInDaemonThread(uri, writer); + } + }, "XMindNetRequestConnection:" + uri); //$NON-NLS-1$ + thread.setDaemon(true); + thread.setPriority( + (Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2); + thread.start(); + try { + thread.join(); + } catch (InterruptedException e) { + // probably aborted by user + } + + return this; + } finally { + runningThread = null; + } + } + + private void executeInDaemonThread(String uri, RequestWriter writer) { + error = null; + try { + if (isAborted()) + return; + debug("HTTP Request: (Prepared) %s %s\r\n%s", method, uri, //$NON-NLS-1$ + requestHeaders); + send(uri, writer); + if (isAborted()) + return; + } catch (OperationCanceledException e) { + debug("HTTP Request: (Aborted) %s %s", method, uri); //$NON-NLS-1$ + if (!isAborted()) { + abort(); + } + } catch (Throwable e) { + if (!isAborted()) { + error = e; + debug("HTTP Request: (Error: %s) %s %s", e, method, uri); //$NON-NLS-1$ + } + } + } + + protected void send(String uri, RequestWriter writer) throws IOException { + this.data = null; + this.responseText = null; + this.responseHeaders.clear(); + + setStatusCode(HTTP_CONNECTING); + debug("HTTP Request: (Connecting...) %s %s", method, uri); //$NON-NLS-1$ + if (isAborted()) + throw new OperationCanceledException(); + + URL url = new URL(uri); + if (isAborted()) + throw new OperationCanceledException(); + + HttpURLConnection connection; + Proxy proxy = getProxy(uri); + if (proxy != null) { + debug("HTTP Request: (Applying proxy %s) %s %s", proxy, method, //$NON-NLS-1$ + uri); + connection = (HttpURLConnection) url.openConnection(proxy); + } else { + connection = (HttpURLConnection) url.openConnection(); + } + if (isAborted()) + throw new OperationCanceledException(); + if (DEBUG_ASSC) { + assc(connection); + if (isAborted()) + throw new OperationCanceledException(); + } + + setStatusCode(HTTP_SENDING); + debug("HTTP Request: (Sending data...) %s %s", method, uri); //$NON-NLS-1$ + if (isAborted()) + throw new OperationCanceledException(); + + try { + connection.setDoOutput(writer != null); + if (isAborted()) + throw new OperationCanceledException(); + connection.setRequestMethod(method); + if (isAborted()) + throw new OperationCanceledException(); + + if (writer != null) { + writer.init(params); + } + if (isAborted()) + throw new OperationCanceledException(); + + writeHeaders(uri, connection, writer); + if (isAborted()) + throw new OperationCanceledException(); + + if (writer != null) { + writeBody(uri, connection, writer); + } + if (isAborted()) + throw new OperationCanceledException(); + + setStatusCode(HTTP_WAITING); + debug("HTTP Request: (Waiting...) %s %s", method, uri); //$NON-NLS-1$ + if (isAborted()) + throw new OperationCanceledException(); + + readResponse(uri, connection, connection.getInputStream(), + connection.getResponseCode()); + if (isAborted()) + throw new OperationCanceledException(); + } catch (IOException e) { + if (isAborted()) + throw new OperationCanceledException(); + readResponse(uri, connection, connection.getErrorStream(), + connection.getResponseCode()); + if (isAborted()) + throw new OperationCanceledException(); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + protected Proxy getProxy(String uri) { + /* + * Return null and let HttpURLConnection read proxy settings from system + * properties. Note that plugin 'org.eclipse.core.net' writes its proxy + * settings to system properties when it's activated, so if you relies + * on this plugin to provide proxy settings please make sure to activate + * it before making any http request. + */ + return null; + } + + public Throwable getError() { + return error; + } + + private RequestWriter createRequestWriter() { + if (WRITABLE_METHODS.contains(method)) { + if (multipart) + return new MultipartWriter(); + return new FormSubmitter(); + } + return null; + } + + protected void writeHeaders(String uri, URLConnection connection, + RequestWriter writer) { + List writtenHeaders = new ArrayList(); + Object accept = null; + for (NamedValue header : requestHeaders) { + writeHeader(connection, header.name, header.getValue(), + writtenHeaders); + if ("Accept".equalsIgnoreCase(header.name)) //$NON-NLS-1$ + accept = header.value; + } + + if (accept == null || "".equals(accept)) { //$NON-NLS-1$ + writeHeader(connection, "Accept", "application/json", //$NON-NLS-1$//$NON-NLS-2$ + writtenHeaders); + } + writeHeader(connection, "X-Client-ID", getClientId(), writtenHeaders); //$NON-NLS-1$ + if (writer != null) { + writeHeader(connection, "Content-Type", //$NON-NLS-1$ + writer.getContentType(), writtenHeaders); + writeHeader(connection, "Content-Length", //$NON-NLS-1$ + String.valueOf(writer.getContentLength()), writtenHeaders); + } + debug("HTTP Request: (Headers written) %s %s\r\n%s", method, uri, //$NON-NLS-1$ + writtenHeaders); + } + + private String getClientId() { + return "xmind_v3.4.1"; //$NON-NLS-1$ + } + + protected void writeHeader(URLConnection connection, String key, + String value, List headers) { + connection.setRequestProperty(key, value); + headers.add(new NamedValue(key, value)); + } + + private void writeBody(String uri, URLConnection connection, + RequestWriter writer) throws IOException { + OutputStream writeStream = connection.getOutputStream(); + if (isAborted()) + throw new OperationCanceledException(); + BufferedOutputStream bufferedWriteStream = new BufferedOutputStream( + writeStream); + if (isAborted()) + throw new OperationCanceledException(); + writer.write(bufferedWriteStream); + if (isAborted()) + throw new OperationCanceledException(); + bufferedWriteStream.flush(); + writeStream.flush(); + } + + protected static String toQueryString(List parameters) { + StringBuffer buffer = new StringBuffer(parameters.size() * 15); + for (int i = 0; i < parameters.size(); i++) { + NamedValue param = parameters.get(i); + if (i > 0) { + buffer.append('&'); + } + buffer.append(param.getEncodedName()); + buffer.append('='); + buffer.append(param.getEncodedValue()); + } + return buffer.toString(); + } + + protected void readResponse(String uri, URLConnection connection, + InputStream readStream, int responseCode) throws IOException { + this.responseText = null; + this.data = null; + this.responseHeaders.clear(); + if (responseCode < 0) { + responseCode = HTTP_ERROR; + } + try { + readResponseHeaders(connection); + if (isAborted()) + throw new OperationCanceledException(); + if (responseCode == HTTP_ERROR) { + setStatusCode(responseCode); + debug("HTTP Response: (Unknown error) %s %s", method, uri); //$NON-NLS-1$ + } else { + this.totalBytes = 0; + this.transferedBytes = 0; + String length = getResponseHeader("Content-Length"); //$NON-NLS-1$ + if (length != null) { + try { + this.totalBytes = Long.parseLong(length, 10); + } catch (NumberFormatException e) { + } + } + if (isAborted()) + throw new OperationCanceledException(); + if (this.totalBytes == 0) { + this.totalBytes = readStream.available(); + } + if (isAborted()) + throw new OperationCanceledException(); + setStatusCode(HTTP_RECEIVING); + debug("HTTP Request: (Receiving data, total %s bytes...) [%s] %s %s", //$NON-NLS-1$ + totalBytes, responseCode, method, uri); + if (isAborted()) + throw new OperationCanceledException(); + if (targetFile != null && responseCode >= 200 + && responseCode < 300) { + saveTargetFile(readStream); + setStatusCode(responseCode); + debug("HTTP Request: (Response) [%s] %s %s\r\n%s\r\nSaved to '%s' (%s bytes).", //$NON-NLS-1$ + getStatusCode(), method, uri, responseHeaders, + targetFile.getAbsolutePath(), targetFile.length()); + } else { + int wrappedResponseCode = readResponseData(readStream); + if (wrappedResponseCode >= 100) { + setStatusCode(wrappedResponseCode); + } else { + setStatusCode(responseCode); + } + debug("HTTP Request: (Response) [%s] %s %s\r\n%s\r\n%s", //$NON-NLS-1$ + responseCode, method, uri, responseHeaders, + responseText); + } + } + } finally { + if (statusCode < 100 && responseCode >= 100) { + setStatusCode(responseCode); + } + } + } + + /** + * @param connection + */ + private int readResponseData(InputStream readStream) throws IOException { + this.responseText = readResponseText(readStream); + if (!"".equals(this.responseText)) { //$NON-NLS-1$ + String respType = getResponseHeader("Content-Type"); //$NON-NLS-1$ + if (respType != null && respType.indexOf("application/json") >= 0) { //$NON-NLS-1$ + try { + this.data = new JSONStore( + new JSONObject(this.responseText)); + if (this.data.has("_code")) { //$NON-NLS-1$ + return this.data.getInt("_code"); //$NON-NLS-1$ + } + } catch (JSONException e) { + this.error = e; + } + } + } + return 0; + } + + private String readResponseText(InputStream readStream) throws IOException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream( + Math.max((int) totalBytes, 1024)); + transfer(readStream, bytes); + return bytes.toString("utf-8"); //$NON-NLS-1$ + } + + /** + * @param connection + */ + private void saveTargetFile(InputStream readStream) throws IOException { + File file = this.targetFile; + File dir = file.getParentFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + OutputStream fileWriteStream = new FileOutputStream(file); + try { + transfer(readStream, fileWriteStream); + } finally { + fileWriteStream.close(); + } + } + + protected void transfer(InputStream readStream, OutputStream writeStream) + throws IOException { + transfer(readStream, writeStream, 1024); + } + + protected void transfer(InputStream readStream, OutputStream writeStream, + int bufSize) throws IOException { + if (bufSize <= 0) + bufSize = 1024; + byte[] buffer = new byte[bufSize]; + int bytes; + while ((bytes = readStream.read(buffer)) >= 0) { + writeStream.write(buffer, 0, bytes); + this.transferedBytes += bytes; + if (isAborted()) + throw new OperationCanceledException(); + try { + Thread.sleep(0); + } catch (InterruptedException e) { + throw new OperationCanceledException(); + } + } + } + + /** + * @param connection + */ + private void readResponseHeaders(URLConnection connection) { + // Skip status line: + connection.getHeaderField(0); + // Start from 2nd header line: + int i = 1; + String key, value; + while ((key = connection.getHeaderFieldKey(i)) != null) { + value = connection.getHeaderField(i); + responseHeaders.add(new NamedValue(key, value)); + i++; + } + } + + public XMindNetRequest debug() { + this.debugging = true; + return this; + } + + public void addStatusChangeListener(IRequestStatusChangeListener listener) { + statusChangeListeners.add(listener); + } + + public void removeStatusChangeListener( + IRequestStatusChangeListener listener) { + statusChangeListeners.remove(listener); + } + + protected void setStatusCode(int newStatus) { + if (newStatus == this.statusCode) + return; + int oldStatus = this.statusCode; + this.statusCode = newStatus; + fireStatusChanged(oldStatus); + } + + protected void fireStatusChanged(final int oldStatus) { + final int newStatus = this.statusCode; + IRequestStatusChangeListener[] listeners = statusChangeListeners + .toArray(new IRequestStatusChangeListener[statusChangeListeners + .size()]); + for (int i = 0; i < listeners.length; i++) { + try { + listeners[i].requestStatusChanged(this, oldStatus, newStatus); + } catch (Throwable e) { + Activator.getDefault().getLog().log(new Status(IStatus.WARNING, + Activator.PLUGIN_ID, + "Error occurred when notifying request status change.", //$NON-NLS-1$ + e)); + } + } + } + + protected void debug(String format, Object... values) { + if (!debugging) + return; + if (DEBUG_TO_STDOUT) { + System.out.println(String.format(format, values)); + } else { + Activator.log(String.format(format, values)); + } + } + + private static void assc(HttpURLConnection connection) { + try { + TrustModifier.relaxHostChecking(connection); + } catch (Exception e) { + if (DEBUG_TO_STDOUT) { + e.printStackTrace(); + System.err.println("Failed to relax host checking."); //$NON-NLS-1$ + } else { + Activator.getDefault().getLog() + .log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, + "Failed to relax host checking.", e)); //$NON-NLS-1$ + } + } + } + + /** + * A solution to accept self-signed SSL certificates. + * + *

+ * Source came from Craig Flichel's post Ignoring Self-Signed Certificates in Java on Dec 1, 2011. + *

+ * + * @author Craig Flichel + */ + private static class TrustModifier { + private static final TrustingHostnameVerifier TRUSTING_HOSTNAME_VERIFIER = new TrustingHostnameVerifier(); + private static SSLSocketFactory factory; + + /** + * Call this with any HttpURLConnection, and it will modify the trust + * settings if it is an HTTPS connection. + */ + public static void relaxHostChecking(HttpURLConnection conn) + throws KeyManagementException, NoSuchAlgorithmException, + KeyStoreException { + + if (conn instanceof HttpsURLConnection) { + HttpsURLConnection httpsConnection = (HttpsURLConnection) conn; + SSLSocketFactory factory = prepFactory(httpsConnection); + httpsConnection.setSSLSocketFactory(factory); + httpsConnection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER); + } + } + + static synchronized SSLSocketFactory prepFactory( + HttpsURLConnection httpsConnection) + throws NoSuchAlgorithmException, KeyStoreException, + KeyManagementException { + + if (factory == null) { + SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ + ctx.init(null, new TrustManager[] { new AlwaysTrustManager() }, + null); + factory = ctx.getSocketFactory(); + } + return factory; + } + + private static final class TrustingHostnameVerifier + implements HostnameVerifier { + public boolean verify(String hostname, SSLSession session) { + return true; + } + } + + private static class AlwaysTrustManager implements X509TrustManager { + public void checkClientTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + } + + } + +} diff --git a/bundles/org.xmind.core.runtime/.gitignore b/bundles/org.xmind.core.runtime/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.runtime/.gitignore +++ b/bundles/org.xmind.core.runtime/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.runtime/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF b/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF index d6e05f23e..1be6d8c08 100644 --- a/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF @@ -1,23 +1,23 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.core.runtime;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.core.internal.XmindCore -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.core.expressions, - org.bouncycastle, - org.xmind.core;bundle-version="[3.7.0,3.8.0)";visibility:=reexport -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.xmind.core.internal;x-internal:=true, - org.xmind.core.internal.factory;x-internal:=true, - org.xmind.core.internal.runtime;x-internal:=true, - org.xmind.core.internal.security;x-internal:=true, - org.xmind.core.internal.xpath;x-internal:=true, - org.xmind.core.io, - org.xmind.core.util -Bundle-ClassPath: src/org/xmind/core/internal/, - . -Bundle-Localization: plugin -Bundle-ActivationPolicy: lazy +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.core.runtime;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.core.internal.XmindCore +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.core.expressions, + org.bouncycastle, + org.xmind.core;bundle-version="[3.7.0,3.8.0)";visibility:=reexport +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.xmind.core.internal;x-internal:=true, + org.xmind.core.internal.factory;x-internal:=true, + org.xmind.core.internal.runtime;x-internal:=true, + org.xmind.core.internal.security;x-internal:=true, + org.xmind.core.internal.xpath;x-internal:=true, + org.xmind.core.io, + org.xmind.core.util +Bundle-ClassPath: src/org/xmind/core/internal/, + . +Bundle-Localization: plugin +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.xmind.core.runtime/about.html b/bundles/org.xmind.core.runtime/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.runtime/about.html +++ b/bundles/org.xmind.core.runtime/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.runtime/plugin.properties b/bundles/org.xmind.core.runtime/plugin.properties index 815709105..4801a4dee 100644 --- a/bundles/org.xmind.core.runtime/plugin.properties +++ b/bundles/org.xmind.core.runtime/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.core.runtime -providerName = XMind Ltd. +#Properties file for org.xmind.core.runtime +providerName = XMind Ltd. pluginName = XMind Core Runtime \ No newline at end of file diff --git a/bundles/org.xmind.core.runtime/plugin.xml b/bundles/org.xmind.core.runtime/plugin.xml index 05316d253..6fc95f4f9 100644 --- a/bundles/org.xmind.core.runtime/plugin.xml +++ b/bundles/org.xmind.core.runtime/plugin.xml @@ -1,38 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.core.runtime/pom.xml b/bundles/org.xmind.core.runtime/pom.xml index 45d0c57e8..e004014fe 100644 --- a/bundles/org.xmind.core.runtime/pom.xml +++ b/bundles/org.xmind.core.runtime/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.runtime - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.runtime + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/CoreAxisProvider.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/CoreAxisProvider.java index 11d2d17fd..0f089623c 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/CoreAxisProvider.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/CoreAxisProvider.java @@ -1,140 +1,140 @@ -package org.xmind.core.internal; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.xmind.core.IIdentifiable; -import org.xmind.core.IImage; -import org.xmind.core.IResourceRef; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.internal.xpath.IAxisProvider; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerRef; - -public class CoreAxisProvider implements IAxisProvider { - - private static final String TAG_TOPIC = "topic"; //$NON-NLS-1$ - private static final String TAG_MARKER = "marker"; //$NON-NLS-1$ - private static final String TAG_LABEL = "label"; //$NON-NLS-1$ - private static final String TAG_IMAGE = "image"; //$NON-NLS-1$ - private static final String TAG_EXTENSION = "extension"; //$NON-NLS-1$ - private static final String TAG_CONTENT = "content"; //$NON-NLS-1$ - private static final String TAG_RESOURCE = "resource"; //$NON-NLS-1$ - - private static final String ATTR_ID = "id"; //$NON-NLS-1$ - private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - private static final String ATTR_TITLE = "title"; //$NON-NLS-1$ - private static final String ATTR_FOLDED = "folded"; //$NON-NLS-1$ - private static final String ATTR_HYPERLINK = "hyperlink"; //$NON-NLS-1$ - private static final String ATTR_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ - private static final String ATTR_SOURCE = "source"; //$NON-NLS-1$ - private static final String ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String ATTR_GROUP_ID = "groupId"; //$NON-NLS-1$ - private static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$ - - public List getChildNodes(Object node, String name) { - if (TAG_MARKER.equals(name)) { - if (node instanceof ITopic) - return new ArrayList(((ITopic) node).getMarkerRefs()); - } else if (TAG_LABEL.equals(name)) { - if (node instanceof ITopic) - return new ArrayList(((ITopic) node).getLabels()); - } else if (TAG_IMAGE.equals(name)) { - if (node instanceof ITopic) - return Arrays.asList(((ITopic) node).getImage()); - } else if (TAG_TOPIC.equals(name)) { - if (node instanceof ITopic) - return ((ITopic) node).getAllChildren(); - } else if (TAG_EXTENSION.equals(name)) { - if (node instanceof ITopic) - return ((ITopic) node).getExtensions(); - } else if (TAG_CONTENT.equals(name)) { - if (node instanceof ITopicExtension) - return Arrays.asList(((ITopicExtension) node).getContent()); - } else if (TAG_RESOURCE.equals(name)) { - if (node instanceof ITopicExtension) - return ((ITopicExtension) node).getResourceRefs(); - } else { - if (node instanceof ITopicExtensionElement) - return ((ITopicExtensionElement) node).getChildren(name); - } - return Collections.emptyList(); - } - - public Object getParentNode(Object node) { - if (node instanceof ITopic) { - ITopic parent = ((ITopic) node).getParent(); - return parent != null ? parent : ((ITopic) node).getOwnedSheet(); - } - return null; - } - - public Object getAttribute(Object node, String name) { - if (ATTR_TYPE.equals(name)) { - if (node instanceof ITopic) - return ((ITopic) node).getType(); - if (node instanceof IResourceRef) - return ((IResourceRef) node).getType(); - } else if (ATTR_ID.equals(name)) { - if (node instanceof IIdentifiable) - return ((IIdentifiable) node).getId(); - if (node instanceof IMarkerRef) - return ((IMarkerRef) node).getMarkerId(); - if (node instanceof IResourceRef) - return ((IResourceRef) node).getResourceId(); - } else if (ATTR_TITLE.equals(name)) { - if (node instanceof ITitled) - return ((ITitled) node).getTitleText(); - } else if (ATTR_FOLDED.equals(name)) { - if (node instanceof ITopic) - return Boolean.valueOf(((ITopic) node).isFolded()); - } else if (ATTR_HYPERLINK.equals(name)) { - if (node instanceof ITopic) - return ((ITopic) node).getHyperlink(); - } else if (ATTR_STRUCTURE_CLASS.equals(name)) { - if (node instanceof ITopic) - return ((ITopic) node).getStructureClass(); - } else if (ATTR_SOURCE.equals(name)) { - if (node instanceof IImage) - return ((IImage) node).getSource(); - } else if (ATTR_GROUP_ID.equals(name)) { - if (node instanceof IMarkerRef) - return getMarkerGroupId((IMarkerRef) node); - } else if (ATTR_NAME.equals(name)) { - if (node instanceof IMarkerRef) - return ((IMarkerRef) node).getDescription(); - } else if (ATTR_PROVIDER.equals(name)) { - if (node instanceof ITopicExtension) - return ((ITopicExtension) node).getProviderName(); - } else { - if (node instanceof ITopicExtensionElement) - return ((ITopicExtensionElement) node).getAttribute(name); - } - return null; - } - - public String getTextContent(Object node) { - if (node instanceof ITopicExtensionElement) - return ((ITopicExtensionElement) node).getTextContent(); - if (node instanceof String) - return (String) node; - return null; - } - - private String getMarkerGroupId(IMarkerRef mr) { - IMarker m = mr.getMarker(); - if (m == null) - return null; - IMarkerGroup g = m.getParent(); - if (g == null) - return null; - return g.getId(); - } - -} +package org.xmind.core.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.xmind.core.IIdentifiable; +import org.xmind.core.IImage; +import org.xmind.core.IResourceRef; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.internal.xpath.IAxisProvider; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerRef; + +public class CoreAxisProvider implements IAxisProvider { + + private static final String TAG_TOPIC = "topic"; //$NON-NLS-1$ + private static final String TAG_MARKER = "marker"; //$NON-NLS-1$ + private static final String TAG_LABEL = "label"; //$NON-NLS-1$ + private static final String TAG_IMAGE = "image"; //$NON-NLS-1$ + private static final String TAG_EXTENSION = "extension"; //$NON-NLS-1$ + private static final String TAG_CONTENT = "content"; //$NON-NLS-1$ + private static final String TAG_RESOURCE = "resource"; //$NON-NLS-1$ + + private static final String ATTR_ID = "id"; //$NON-NLS-1$ + private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ + private static final String ATTR_TITLE = "title"; //$NON-NLS-1$ + private static final String ATTR_FOLDED = "folded"; //$NON-NLS-1$ + private static final String ATTR_HYPERLINK = "hyperlink"; //$NON-NLS-1$ + private static final String ATTR_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ + private static final String ATTR_SOURCE = "source"; //$NON-NLS-1$ + private static final String ATTR_NAME = "name"; //$NON-NLS-1$ + private static final String ATTR_GROUP_ID = "groupId"; //$NON-NLS-1$ + private static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$ + + public List getChildNodes(Object node, String name) { + if (TAG_MARKER.equals(name)) { + if (node instanceof ITopic) + return new ArrayList(((ITopic) node).getMarkerRefs()); + } else if (TAG_LABEL.equals(name)) { + if (node instanceof ITopic) + return new ArrayList(((ITopic) node).getLabels()); + } else if (TAG_IMAGE.equals(name)) { + if (node instanceof ITopic) + return Arrays.asList(((ITopic) node).getImage()); + } else if (TAG_TOPIC.equals(name)) { + if (node instanceof ITopic) + return ((ITopic) node).getAllChildren(); + } else if (TAG_EXTENSION.equals(name)) { + if (node instanceof ITopic) + return ((ITopic) node).getExtensions(); + } else if (TAG_CONTENT.equals(name)) { + if (node instanceof ITopicExtension) + return Arrays.asList(((ITopicExtension) node).getContent()); + } else if (TAG_RESOURCE.equals(name)) { + if (node instanceof ITopicExtension) + return ((ITopicExtension) node).getResourceRefs(); + } else { + if (node instanceof ITopicExtensionElement) + return ((ITopicExtensionElement) node).getChildren(name); + } + return Collections.emptyList(); + } + + public Object getParentNode(Object node) { + if (node instanceof ITopic) { + ITopic parent = ((ITopic) node).getParent(); + return parent != null ? parent : ((ITopic) node).getOwnedSheet(); + } + return null; + } + + public Object getAttribute(Object node, String name) { + if (ATTR_TYPE.equals(name)) { + if (node instanceof ITopic) + return ((ITopic) node).getType(); + if (node instanceof IResourceRef) + return ((IResourceRef) node).getType(); + } else if (ATTR_ID.equals(name)) { + if (node instanceof IIdentifiable) + return ((IIdentifiable) node).getId(); + if (node instanceof IMarkerRef) + return ((IMarkerRef) node).getMarkerId(); + if (node instanceof IResourceRef) + return ((IResourceRef) node).getResourceId(); + } else if (ATTR_TITLE.equals(name)) { + if (node instanceof ITitled) + return ((ITitled) node).getTitleText(); + } else if (ATTR_FOLDED.equals(name)) { + if (node instanceof ITopic) + return Boolean.valueOf(((ITopic) node).isFolded()); + } else if (ATTR_HYPERLINK.equals(name)) { + if (node instanceof ITopic) + return ((ITopic) node).getHyperlink(); + } else if (ATTR_STRUCTURE_CLASS.equals(name)) { + if (node instanceof ITopic) + return ((ITopic) node).getStructureClass(); + } else if (ATTR_SOURCE.equals(name)) { + if (node instanceof IImage) + return ((IImage) node).getSource(); + } else if (ATTR_GROUP_ID.equals(name)) { + if (node instanceof IMarkerRef) + return getMarkerGroupId((IMarkerRef) node); + } else if (ATTR_NAME.equals(name)) { + if (node instanceof IMarkerRef) + return ((IMarkerRef) node).getDescription(); + } else if (ATTR_PROVIDER.equals(name)) { + if (node instanceof ITopicExtension) + return ((ITopicExtension) node).getProviderName(); + } else { + if (node instanceof ITopicExtensionElement) + return ((ITopicExtensionElement) node).getAttribute(name); + } + return null; + } + + public String getTextContent(Object node) { + if (node instanceof ITopicExtensionElement) + return ((ITopicExtensionElement) node).getTextContent(); + if (node instanceof String) + return (String) node; + return null; + } + + private String getMarkerGroupId(IMarkerRef mr) { + IMarker m = mr.getMarker(); + if (m == null) + return null; + IMarkerGroup g = m.getParent(); + if (g == null) + return null; + return g.getId(); + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/StylePropertyTester.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/StylePropertyTester.java index 499fbafb5..832f008f0 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/StylePropertyTester.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/StylePropertyTester.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.core.style.IStyle; - -public class StylePropertyTester extends PropertyTester { - - private static final String P_ID = "id"; //$NON-NLS-1$ - - private static final String P_TYPE = "type"; //$NON-NLS-1$ - - private static final String P_GROUP = "group"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - if (receiver instanceof IStyle) { - IStyle style = (IStyle) receiver; - if (P_ID.equals(property)) { - return expectedValue != null - && expectedValue.equals(style.getId()); - } else if (P_TYPE.equals(property)) { - return expectedValue != null - && expectedValue.equals(style.getType()); - } else if (P_GROUP.equals(property)) { - return expectedValue != null - && expectedValue.equals(style.getOwnedStyleSheet() - .findOwnedGroup(style)); - } - } - Assert.isTrue(false); - return false; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.core.style.IStyle; + +public class StylePropertyTester extends PropertyTester { + + private static final String P_ID = "id"; //$NON-NLS-1$ + + private static final String P_TYPE = "type"; //$NON-NLS-1$ + + private static final String P_GROUP = "group"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + if (receiver instanceof IStyle) { + IStyle style = (IStyle) receiver; + if (P_ID.equals(property)) { + return expectedValue != null + && expectedValue.equals(style.getId()); + } else if (P_TYPE.equals(property)) { + return expectedValue != null + && expectedValue.equals(style.getType()); + } else if (P_GROUP.equals(property)) { + return expectedValue != null + && expectedValue.equals(style.getOwnedStyleSheet() + .findOwnedGroup(style)); + } + } + Assert.isTrue(false); + return false; + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/TopicPropertyTester.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/TopicPropertyTester.java index fc1ba94bc..7e54ca2ae 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/TopicPropertyTester.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/TopicPropertyTester.java @@ -1,349 +1,349 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.List; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.core.IImage; -import org.xmind.core.ITopic; -import org.xmind.core.internal.xpath.Evaluator; - -/** - * A property tester used to test whether a topic contains expected properties. - * - *

- * The receiver to test against MUST be an {@link ITopic} instance. - * Otherwise, {@link IllegalArgumentException} will be thrown. - *

- * - *

Supported property Values

- * - *
- * - *
eval
- *
Evaluates the topic property evaluation expression (specified by the - * expected value) against the receiver topic. See 'Topic Property Evaluation' - * for details of syntax. The evaluation result MUST be a boolean value.
- * - *
type
- *
Compares the expected value against the type of the receiver topic - * retrieved via {@link ITopic#getType()}. This property is a shortcut of - * testing the eval property with 'args' specified as - * matches(@type,'EXPECTED_VALUE') if the expected value starts - * with "^" or @type='EXPECTED_VALUE' otherwise.
- * - *
title
- *
Compares the expected value against the topic title text retrieved via - * {@link ITopic#getTitleText()}. This property is a shortcut of testing the - * eval property with 'args' specified as - * matches(@title,'EXPECTED_VALUE') if the expected value starts - * with "^" or @title='EXPECTED_VALUE' otherwise.
- * - *
structureClass
- *
Compares the expected value against the structure class retrieved via - * {@link ITopic#getStructureClass()}. This property is a shortcut of testing - * the eval property with 'args' specified as - * matches(@structureClass,'EXPECTED_VALUE') if the expected value - * starts with "^" or @structureClass='EXPECTED_VALUE' - * otherwise.
- * - *
folded
- *
Compares the expected value against the folded state retrieved via - * {@link ITopic#isFolded()}. This property is a shortcut of testing the - * eval property with 'args' specified as @folded. - *
- * - *
hyperlink
- *
Compares the expected value against the hyperlink value retrieved via - * {@link ITopic#getHyperlink()}. This property is a shortcut of testing the - * eval property with 'args' specified as - * matches(@hyperlink,'EXPECTED_VALUE') if the expected value - * starts with "^" or @hyperlink='EXPECTED_VALUE' - * otherwise.
- * - *
imageSource
- *
Compares the expected value against the image source retrieved via - * {@link ITopic#getImage()} and {@link IImage#getSource()}. This property is a - * shortcut of testing the eval property with 'args' specified as - * matches(image/@source,'EXPECTED_VALUE') if the expected value - * starts with "^" or image/@source='EXPECTED_VALUE' - * otherwise.
- * - *
- * - *

Topic Property Evaluation

- * - *

- * A topic property evaluation expression is a function call (e.g. - * matches(@type,'(de|at)tached')), a comparison (e.g. - * @type!='attached') or an evaluation of a boolean value (e.g. - * @folded). Variables may be an XPath-like query (e.g. - * topic[@type='attached']/label/text()), a string value (e.g. - * 'xxx'), a number value (e.g. 23) or a boolean value - * (e.g. true() or false()). - *

- * - *

- * An XPath-like query is evaluated against the receiver topic, so it starts - * without a leading slash (/) to indicate that this is a - * relative path. See the following Topic Model Hierarchy for what elements and - * attributes can be selected. - *

- * - *

- * This class only supports a small set of XPath 2 specifications. - *

- * - *
- *
label
- *
(Collection) Returns the child element labeled by the specified label - *
- *
@attr
- *
(String, Boolean, Number) Returns the specified attribute value of the - * context object (or the first object of the context collection)
- *
x=y, x!=y, x>y, - * x<y, x>=y, x<= - * y
- *
(Boolean) Compares x and y using the literal operator - *
- *
count(Collection node-set)
- *
(Number) Returns the count of the nodes in the specified node set
- *
matches(String str, String pattern)
- *
(Boolean) Returns whether the string matches the specified regular - * expression pattern
- *
true()
- *
(Boolean) Returns true
- *
false()
- *
(Boolean) Returns false
- *
- * - *

Topic Model Hierarchy

- * - *
- * - *
topic
- *
- *
- *
Type
- *
{@link org.xmind.core.ITopic}
- *
Attributes
- *
- *
- *
type
- *
(String) {@link org.xmind.core.ITopic#getType()}
- *
title
- *
(String) {@link org.xmind.core.ITopic#getTitleText()}
- *
structureClass
- *
(String) {@link org.xmind.core.ITopic#getStructureClass()}
- *
folded
- *
(boolean) {@link org.xmind.core.ITopic#isFolded()}
- *
hyperlink
- *
(String) {@link org.xmind.core.ITopic#getHyperlink()}
- *
- *
- *
Elements
- *
- *
- *
image
- *
A singleton list of {@link org.xmind.core.ITopic#getImage()}
- *
marker
- *
(Set) {@link org.xmind.core.ITopic#getMarkerRefs()}
- *
label
- *
(Set) {@link org.xmind.core.ITopic#getLabels()}
- *
extension
- *
(List) {@link org.xmind.core.ITopic#getExtension(String)}
- *
topic
- *
(List) {@link org.xmind.core.ITopic#getAllChildren()}
- *
- *
- *
- *
- * - *
image
- *
- *
- *
Type
- *
{@link org.xmind.core.IImage}
- *
Attributes
- *
- *
- *
source
- *
(String) {@link org.xmind.core.IImage#getSource()}
- *
- *
- *
- *
- * - *
marker
- *
- *
- *
Type
- *
{@link org.xmind.core.marker.IMarkerRef}
- *
Attributes
- *
- *
- *
id
- *
(String) {@link org.xmind.core.marker.IMarkerRef#getMarkerId()}
- *
name
- *
(String) {@link org.xmind.core.marker.IMarkerRef#getDescription()}
- *
groupId
- *
(String) The marker group id retrieved by - * element.getMarker().getParent().getId()
- *
- *
- *
- *
- * - *
label
- *
- *
- *
Type
- *
String
- *
Text Content (text())
- *
The string value of this label
- *
- *
- * - *
extension
- *
- *
- *
Type
- *
{@link org.xmind.core.ITopicExtension}
- *
Attributes
- *
- *
- *
provider
- *
(String) {@link org.xmind.core.ITopicExtension#getProviderName()}
- *
- *
- *
Elements
- *
- *
- *
content
- *
A singleton collection of - * {@link org.xmind.core.ITopicExtension#getContent()}
- *
resource
- *
(List) {@link org.xmind.core.ITopicExtension#getResourceRefs()}
- *
- *
- *
- *
- * - *
resource
- *
- *
- *
Type
- *
{@link org.xmind.core.IResourceRef}
- *
Attributes
- *
- *
- *
type
- *
(String) {@link org.xmind.core.IResourceRef#getType()}
- *
id
- *
(String) {@link org.xmind.core.IResourceRef#getResourceId()}
- *
- *
- *
- *
- * - *
content
- *
- *
- *
Type
- *
{@link org.xmind.core.ITopicExtensionElement}
- *
Attributes
- *
(String) - * {@link org.xmind.core.ITopicExtensionElement#getAttribute(String)}
- *
Elements
- *
(List) {@link org.xmind.core.ITopicExtensionElement#getChildren(String)} - *
- *
Text Content
- *
(String) {@link org.xmind.core.ITopicExtensionElement#getTextContent()} - *
- *
- *
- *
- * - * @author Frank Shaka - * - */ -public class TopicPropertyTester extends PropertyTester { - - private static final String P_EVAL = "eval"; //$NON-NLS-1$ - - private static final String P_TYPE = "type"; //$NON-NLS-1$ - - private static final String P_TITLE = "title"; //$NON-NLS-1$ - - private static final String P_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ - - private static final String P_FOLDED = "folded"; //$NON-NLS-1$ - - private static final String P_HYPERLINK = "hyperlink"; //$NON-NLS-1$ - - private static final String P_IMAGE_SOURCE = "imageSource"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof ITopic, - "Receiver is not an ITopic object: " + receiver); //$NON-NLS-1$ - - ITopic topic = (ITopic) receiver; - - if (P_TYPE.equals(property)) { - return evaluates(topic, propEvalExp("@type", expectedValue)); //$NON-NLS-1$ - } else if (P_HYPERLINK.equals(property)) { - return evaluates(topic, propEvalExp("@hyperlink", expectedValue)); //$NON-NLS-1$ - } else if (P_TITLE.equals(property)) { - return evaluates(topic, propEvalExp("@title", expectedValue)); //$NON-NLS-1$ - } else if (P_STRUCTURE_CLASS.equals(property)) { - return evaluates(topic, - propEvalExp("@structureClass", expectedValue)); //$NON-NLS-1$ - } else if (P_FOLDED.equals(property)) { - return evaluates(topic, "@folded"); //$NON-NLS-1$ - } else if (P_IMAGE_SOURCE.equals(property)) { - return evaluates(topic, - propEvalExp("image/@source", expectedValue)); //$NON-NLS-1$ - } else if (P_EVAL.equals(property)) { - if (!(expectedValue instanceof String)) - return false; - return evaluates(topic, (String) expectedValue); - } - - throw new IllegalArgumentException( - "Unrecognized property: " + property); //$NON-NLS-1$ - } - - private static String propEvalExp(String propertyPath, - Object expectedValue) { - String value = expectedValue == null ? "" : expectedValue.toString(); //$NON-NLS-1$ - if (value.startsWith("^")) //$NON-NLS-1$ - return String.format("matches(%s,'%s')", propertyPath, value); //$NON-NLS-1$ - return String.format("%s='%s'", propertyPath, value); //$NON-NLS-1$ - } - - private static boolean evaluates(ITopic topic, String expression) { - Evaluator evaluator = new Evaluator(expression, new CoreAxisProvider()); - List sequence = evaluator.evaluate(topic); - if (sequence.isEmpty()) - return false; - Object result = sequence.get(0); - if (result instanceof Boolean) - return ((Boolean) result).booleanValue(); - return result != null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.List; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.core.IImage; +import org.xmind.core.ITopic; +import org.xmind.core.internal.xpath.Evaluator; + +/** + * A property tester used to test whether a topic contains expected properties. + * + *

+ * The receiver to test against MUST be an {@link ITopic} instance. + * Otherwise, {@link IllegalArgumentException} will be thrown. + *

+ * + *

Supported property Values

+ * + *
+ * + *
eval
+ *
Evaluates the topic property evaluation expression (specified by the + * expected value) against the receiver topic. See 'Topic Property Evaluation' + * for details of syntax. The evaluation result MUST be a boolean value.
+ * + *
type
+ *
Compares the expected value against the type of the receiver topic + * retrieved via {@link ITopic#getType()}. This property is a shortcut of + * testing the eval property with 'args' specified as + * matches(@type,'EXPECTED_VALUE') if the expected value starts + * with "^" or @type='EXPECTED_VALUE' otherwise.
+ * + *
title
+ *
Compares the expected value against the topic title text retrieved via + * {@link ITopic#getTitleText()}. This property is a shortcut of testing the + * eval property with 'args' specified as + * matches(@title,'EXPECTED_VALUE') if the expected value starts + * with "^" or @title='EXPECTED_VALUE' otherwise.
+ * + *
structureClass
+ *
Compares the expected value against the structure class retrieved via + * {@link ITopic#getStructureClass()}. This property is a shortcut of testing + * the eval property with 'args' specified as + * matches(@structureClass,'EXPECTED_VALUE') if the expected value + * starts with "^" or @structureClass='EXPECTED_VALUE' + * otherwise.
+ * + *
folded
+ *
Compares the expected value against the folded state retrieved via + * {@link ITopic#isFolded()}. This property is a shortcut of testing the + * eval property with 'args' specified as @folded. + *
+ * + *
hyperlink
+ *
Compares the expected value against the hyperlink value retrieved via + * {@link ITopic#getHyperlink()}. This property is a shortcut of testing the + * eval property with 'args' specified as + * matches(@hyperlink,'EXPECTED_VALUE') if the expected value + * starts with "^" or @hyperlink='EXPECTED_VALUE' + * otherwise.
+ * + *
imageSource
+ *
Compares the expected value against the image source retrieved via + * {@link ITopic#getImage()} and {@link IImage#getSource()}. This property is a + * shortcut of testing the eval property with 'args' specified as + * matches(image/@source,'EXPECTED_VALUE') if the expected value + * starts with "^" or image/@source='EXPECTED_VALUE' + * otherwise.
+ * + *
+ * + *

Topic Property Evaluation

+ * + *

+ * A topic property evaluation expression is a function call (e.g. + * matches(@type,'(de|at)tached')), a comparison (e.g. + * @type!='attached') or an evaluation of a boolean value (e.g. + * @folded). Variables may be an XPath-like query (e.g. + * topic[@type='attached']/label/text()), a string value (e.g. + * 'xxx'), a number value (e.g. 23) or a boolean value + * (e.g. true() or false()). + *

+ * + *

+ * An XPath-like query is evaluated against the receiver topic, so it starts + * without a leading slash (/) to indicate that this is a + * relative path. See the following Topic Model Hierarchy for what elements and + * attributes can be selected. + *

+ * + *

+ * This class only supports a small set of XPath 2 specifications. + *

+ * + *
+ *
label
+ *
(Collection) Returns the child element labeled by the specified label + *
+ *
@attr
+ *
(String, Boolean, Number) Returns the specified attribute value of the + * context object (or the first object of the context collection)
+ *
x=y, x!=y, x>y, + * x<y, x>=y, x<= + * y
+ *
(Boolean) Compares x and y using the literal operator + *
+ *
count(Collection node-set)
+ *
(Number) Returns the count of the nodes in the specified node set
+ *
matches(String str, String pattern)
+ *
(Boolean) Returns whether the string matches the specified regular + * expression pattern
+ *
true()
+ *
(Boolean) Returns true
+ *
false()
+ *
(Boolean) Returns false
+ *
+ * + *

Topic Model Hierarchy

+ * + *
+ * + *
topic
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.ITopic}
+ *
Attributes
+ *
+ *
+ *
type
+ *
(String) {@link org.xmind.core.ITopic#getType()}
+ *
title
+ *
(String) {@link org.xmind.core.ITopic#getTitleText()}
+ *
structureClass
+ *
(String) {@link org.xmind.core.ITopic#getStructureClass()}
+ *
folded
+ *
(boolean) {@link org.xmind.core.ITopic#isFolded()}
+ *
hyperlink
+ *
(String) {@link org.xmind.core.ITopic#getHyperlink()}
+ *
+ *
+ *
Elements
+ *
+ *
+ *
image
+ *
A singleton list of {@link org.xmind.core.ITopic#getImage()}
+ *
marker
+ *
(Set) {@link org.xmind.core.ITopic#getMarkerRefs()}
+ *
label
+ *
(Set) {@link org.xmind.core.ITopic#getLabels()}
+ *
extension
+ *
(List) {@link org.xmind.core.ITopic#getExtension(String)}
+ *
topic
+ *
(List) {@link org.xmind.core.ITopic#getAllChildren()}
+ *
+ *
+ *
+ *
+ * + *
image
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.IImage}
+ *
Attributes
+ *
+ *
+ *
source
+ *
(String) {@link org.xmind.core.IImage#getSource()}
+ *
+ *
+ *
+ *
+ * + *
marker
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.marker.IMarkerRef}
+ *
Attributes
+ *
+ *
+ *
id
+ *
(String) {@link org.xmind.core.marker.IMarkerRef#getMarkerId()}
+ *
name
+ *
(String) {@link org.xmind.core.marker.IMarkerRef#getDescription()}
+ *
groupId
+ *
(String) The marker group id retrieved by + * element.getMarker().getParent().getId()
+ *
+ *
+ *
+ *
+ * + *
label
+ *
+ *
+ *
Type
+ *
String
+ *
Text Content (text())
+ *
The string value of this label
+ *
+ *
+ * + *
extension
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.ITopicExtension}
+ *
Attributes
+ *
+ *
+ *
provider
+ *
(String) {@link org.xmind.core.ITopicExtension#getProviderName()}
+ *
+ *
+ *
Elements
+ *
+ *
+ *
content
+ *
A singleton collection of + * {@link org.xmind.core.ITopicExtension#getContent()}
+ *
resource
+ *
(List) {@link org.xmind.core.ITopicExtension#getResourceRefs()}
+ *
+ *
+ *
+ *
+ * + *
resource
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.IResourceRef}
+ *
Attributes
+ *
+ *
+ *
type
+ *
(String) {@link org.xmind.core.IResourceRef#getType()}
+ *
id
+ *
(String) {@link org.xmind.core.IResourceRef#getResourceId()}
+ *
+ *
+ *
+ *
+ * + *
content
+ *
+ *
+ *
Type
+ *
{@link org.xmind.core.ITopicExtensionElement}
+ *
Attributes
+ *
(String) + * {@link org.xmind.core.ITopicExtensionElement#getAttribute(String)}
+ *
Elements
+ *
(List) {@link org.xmind.core.ITopicExtensionElement#getChildren(String)} + *
+ *
Text Content
+ *
(String) {@link org.xmind.core.ITopicExtensionElement#getTextContent()} + *
+ *
+ *
+ *
+ * + * @author Frank Shaka + * + */ +public class TopicPropertyTester extends PropertyTester { + + private static final String P_EVAL = "eval"; //$NON-NLS-1$ + + private static final String P_TYPE = "type"; //$NON-NLS-1$ + + private static final String P_TITLE = "title"; //$NON-NLS-1$ + + private static final String P_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ + + private static final String P_FOLDED = "folded"; //$NON-NLS-1$ + + private static final String P_HYPERLINK = "hyperlink"; //$NON-NLS-1$ + + private static final String P_IMAGE_SOURCE = "imageSource"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof ITopic, + "Receiver is not an ITopic object: " + receiver); //$NON-NLS-1$ + + ITopic topic = (ITopic) receiver; + + if (P_TYPE.equals(property)) { + return evaluates(topic, propEvalExp("@type", expectedValue)); //$NON-NLS-1$ + } else if (P_HYPERLINK.equals(property)) { + return evaluates(topic, propEvalExp("@hyperlink", expectedValue)); //$NON-NLS-1$ + } else if (P_TITLE.equals(property)) { + return evaluates(topic, propEvalExp("@title", expectedValue)); //$NON-NLS-1$ + } else if (P_STRUCTURE_CLASS.equals(property)) { + return evaluates(topic, + propEvalExp("@structureClass", expectedValue)); //$NON-NLS-1$ + } else if (P_FOLDED.equals(property)) { + return evaluates(topic, "@folded"); //$NON-NLS-1$ + } else if (P_IMAGE_SOURCE.equals(property)) { + return evaluates(topic, + propEvalExp("image/@source", expectedValue)); //$NON-NLS-1$ + } else if (P_EVAL.equals(property)) { + if (!(expectedValue instanceof String)) + return false; + return evaluates(topic, (String) expectedValue); + } + + throw new IllegalArgumentException( + "Unrecognized property: " + property); //$NON-NLS-1$ + } + + private static String propEvalExp(String propertyPath, + Object expectedValue) { + String value = expectedValue == null ? "" : expectedValue.toString(); //$NON-NLS-1$ + if (value.startsWith("^")) //$NON-NLS-1$ + return String.format("matches(%s,'%s')", propertyPath, value); //$NON-NLS-1$ + return String.format("%s='%s'", propertyPath, value); //$NON-NLS-1$ + } + + private static boolean evaluates(ITopic topic, String expression) { + Evaluator evaluator = new Evaluator(expression, new CoreAxisProvider()); + List sequence = evaluator.evaluate(topic); + if (sequence.isEmpty()) + return false; + Object result = sequence.get(0); + if (result instanceof Boolean) + return ((Boolean) result).booleanValue(); + return result != null; + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/XmindCore.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/XmindCore.java index 1d7608dd2..f50da06be 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/XmindCore.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/XmindCore.java @@ -1,73 +1,73 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.core.internal; - -import org.eclipse.core.runtime.Plugin; -import org.osgi.framework.BundleContext; -import org.xmind.core.internal.runtime.RuntimeLogger; -import org.xmind.core.internal.security.BouncyCastleSecurityProvider; -import org.xmind.core.internal.security.Crypto; - -/** - * The activator class controls the plug-in life cycle - */ -@SuppressWarnings("deprecation") -public class XmindCore extends Plugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.core.runtime"; //$NON-NLS-1$ - - // The shared instance - private static XmindCore plugin; - - /** - * The constructor - */ - public XmindCore() { - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - - InternalCore.getInstance().setLogger(new RuntimeLogger()); - - Crypto.setProvider(new BouncyCastleSecurityProvider()); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static XmindCore getDefault() { - return plugin; - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.core.internal; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; +import org.xmind.core.internal.runtime.RuntimeLogger; +import org.xmind.core.internal.security.BouncyCastleSecurityProvider; +import org.xmind.core.internal.security.Crypto; + +/** + * The activator class controls the plug-in life cycle + */ +@SuppressWarnings("deprecation") +public class XmindCore extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.core.runtime"; //$NON-NLS-1$ + + // The shared instance + private static XmindCore plugin; + + /** + * The constructor + */ + public XmindCore() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + InternalCore.getInstance().setLogger(new RuntimeLogger()); + + Crypto.setProvider(new BouncyCastleSecurityProvider()); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static XmindCore getDefault() { + return plugin; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/BundleResourceFinder.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/BundleResourceFinder.java index 5713e023d..93a142aa6 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/BundleResourceFinder.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/BundleResourceFinder.java @@ -1,91 +1,91 @@ -package org.xmind.core.internal.runtime; - -import java.net.URL; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Bundle; -import org.xmind.core.io.BundleResource; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class BundleResourceFinder { - - public static BundleResource resolve(BundleResource res) { - IPath path = res.getPath(); - if (path.isEmpty() || path.isRoot()) { - path = Path.EMPTY; - } - - BundleResource result; - String first = path.segment(0); - if (first == null || !first.startsWith("$")) { //$NON-NLS-1$ - result = find(res.getBundle(), path); - } else { - path = path.removeFirstSegments(1); - if ("$nl$".equalsIgnoreCase(first)) { //$NON-NLS-1$ - result = resolveByNL(res.getBundle(), path); - } else if ("$os$".equalsIgnoreCase(first)) { //$NON-NLS-1$ - result = resolveByOS(res.getBundle(), path); - } else if ("$ws$".equalsIgnoreCase(first)) { //$NON-NLS-1$ - result = resolveByWS(res.getBundle(), path); - } else { - result = find(res.getBundle(), path); - } - } - return result; - } - - private static BundleResource find(Bundle bundle, IPath path) { - URL entry = bundle.getEntry(path.toString()); - if (entry != null) { - return new BundleResource(bundle, new Path(entry.getPath())); - } - - Bundle[] fragments = Platform.getFragments(bundle); - if (fragments == null) - return null; - - for (int i = 0; i < fragments.length; i++) { - BundleResource result = find(fragments[i], path); - if (result != null) - return result; - } - - return null; - } - - private static BundleResource resolveByNL(Bundle bundle, IPath path) { - String nl = Platform.getNL(); - String[] nlParts = nl.split("_"); //$NON-NLS-1$ - - for (int i = 0; i < nlParts.length; i++) { - int count = nlParts.length - i; - IPath p = Path.ROOT.append("nl"); //$NON-NLS-1$ - for (int j = 0; j < count; j++) { - p = p.append(nlParts[j]); - } - p = p.append(path); - BundleResource result = find(bundle, p); - if (result != null) - return result; - } - - return find(bundle, path); - } - - private static BundleResource resolveByOS(Bundle bundle, IPath path) { - // TODO - return null; - } - - private static BundleResource resolveByWS(Bundle bundle, IPath path) { - // TODO - return null; - } - -} +package org.xmind.core.internal.runtime; + +import java.net.URL; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.xmind.core.io.BundleResource; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class BundleResourceFinder { + + public static BundleResource resolve(BundleResource res) { + IPath path = res.getPath(); + if (path.isEmpty() || path.isRoot()) { + path = Path.EMPTY; + } + + BundleResource result; + String first = path.segment(0); + if (first == null || !first.startsWith("$")) { //$NON-NLS-1$ + result = find(res.getBundle(), path); + } else { + path = path.removeFirstSegments(1); + if ("$nl$".equalsIgnoreCase(first)) { //$NON-NLS-1$ + result = resolveByNL(res.getBundle(), path); + } else if ("$os$".equalsIgnoreCase(first)) { //$NON-NLS-1$ + result = resolveByOS(res.getBundle(), path); + } else if ("$ws$".equalsIgnoreCase(first)) { //$NON-NLS-1$ + result = resolveByWS(res.getBundle(), path); + } else { + result = find(res.getBundle(), path); + } + } + return result; + } + + private static BundleResource find(Bundle bundle, IPath path) { + URL entry = bundle.getEntry(path.toString()); + if (entry != null) { + return new BundleResource(bundle, new Path(entry.getPath())); + } + + Bundle[] fragments = Platform.getFragments(bundle); + if (fragments == null) + return null; + + for (int i = 0; i < fragments.length; i++) { + BundleResource result = find(fragments[i], path); + if (result != null) + return result; + } + + return null; + } + + private static BundleResource resolveByNL(Bundle bundle, IPath path) { + String nl = Platform.getNL(); + String[] nlParts = nl.split("_"); //$NON-NLS-1$ + + for (int i = 0; i < nlParts.length; i++) { + int count = nlParts.length - i; + IPath p = Path.ROOT.append("nl"); //$NON-NLS-1$ + for (int j = 0; j < count; j++) { + p = p.append(nlParts[j]); + } + p = p.append(path); + BundleResource result = find(bundle, p); + if (result != null) + return result; + } + + return find(bundle, path); + } + + private static BundleResource resolveByOS(Bundle bundle, IPath path) { + // TODO + return null; + } + + private static BundleResource resolveByWS(Bundle bundle, IPath path) { + // TODO + return null; + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/RuntimeLogger.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/RuntimeLogger.java index dbb1de3b9..9357436cb 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/RuntimeLogger.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/RuntimeLogger.java @@ -1,60 +1,60 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal.runtime; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.xmind.core.internal.XmindCore; -import org.xmind.core.util.ILogger; - -/** - * @author Frank Shaka - * - */ -public class RuntimeLogger implements ILogger { - - /* - * (non-Javadoc) - * - * @see org.xmind.core.util.ILogger#log(java.lang.String) - */ - public void log(String message) { - XmindCore.getDefault().getLog().log( - new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, message)); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.util.ILogger#log(java.lang.Throwable, - * java.lang.String) - */ - public void log(Throwable e, String message) { - XmindCore.getDefault().getLog().log( - new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, message, e)); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.util.ILogger#log(java.lang.Throwable) - */ - public void log(Throwable e) { - XmindCore.getDefault().getLog().log( - new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, - "(Untitled error)", e)); //$NON-NLS-1$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal.runtime; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.xmind.core.internal.XmindCore; +import org.xmind.core.util.ILogger; + +/** + * @author Frank Shaka + * + */ +public class RuntimeLogger implements ILogger { + + /* + * (non-Javadoc) + * + * @see org.xmind.core.util.ILogger#log(java.lang.String) + */ + public void log(String message) { + XmindCore.getDefault().getLog().log( + new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, message)); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.util.ILogger#log(java.lang.Throwable, + * java.lang.String) + */ + public void log(Throwable e, String message) { + XmindCore.getDefault().getLog().log( + new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, message, e)); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.util.ILogger#log(java.lang.Throwable) + */ + public void log(Throwable e) { + XmindCore.getDefault().getLog().log( + new Status(IStatus.ERROR, XmindCore.PLUGIN_ID, + "(Untitled error)", e)); //$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceConfigurer.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceConfigurer.java index 55cb0dd62..0d3c1c5db 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceConfigurer.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceConfigurer.java @@ -1,120 +1,120 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.runtime; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.osgi.service.datalocation.Location; -import org.xmind.core.Core; -import org.xmind.core.internal.Workspace; - -public class WorkspaceConfigurer { - - public static final String INSTANCE_LOCATION = "${osgi.instance.area}"; //$NON-NLS-1$ - - public static final String USER_HOME = "${user.home}"; //$NON-NLS-1$ - - private static final Pattern EXPANSION = Pattern - .compile("\\$\\{([^\\}]+)\\}"); //$NON-NLS-1$ - - private WorkspaceConfigurer() { - throw new AssertionError(); - } - - public static void setDefaultWorkspaceLocation(String path) { - String location = expandWorkspaceLocation(path); - File dir = new File(location); - if (!dir.isDirectory()) { - dir.mkdirs(); - } - ((Workspace) Core.getWorkspace()).setDefaultWorkingDirectory(location); - } - - private static String expandWorkspaceLocation(String path) { - if (INSTANCE_LOCATION.equals(path)) { - String oldWorkspaceLocation = expandWorkspaceLocation(path - + "/.xmind"); //$NON-NLS-1$ - if (new File(oldWorkspaceLocation).isDirectory()) - return oldWorkspaceLocation; - } - - File instanceLocation = calculateInstanceDir(); - - Properties p = new Properties(); - p.putAll(System.getProperties()); - p.put(INSTANCE_LOCATION.substring(2, INSTANCE_LOCATION.length() - 1), - instanceLocation.getAbsolutePath()); - - StringBuffer buffer = new StringBuffer(path.length() * 2); - Matcher m = EXPANSION.matcher(path); - while (m.find()) { - String value = p.getProperty(m.group(1)); - if (value == null) - value = m.group(); - // Replace '\' and '$' to literal '\\' and '\$'. - value = value.replaceAll("([\\\\\\$])", "\\\\$1"); //$NON-NLS-1$ //$NON-NLS-2$ - m.appendReplacement(buffer, value); - } - m.appendTail(buffer); - return buffer.toString(); - } - - private static File calculateInstanceDir() { - Location loc = Platform.getInstanceLocation(); - if (loc == null) { - // Instance location not specified. - return calculateDefaultInstanceDir(); - } - URL url = loc.getURL(); - try { - url = FileLocator.toFileURL(url); - } catch (IOException e) { - // Invalid URL. - return calculateDefaultInstanceDir(); - } - - String file = url.getFile(); - if (file == null || "".equals(file)) {//$NON-NLS-1$ - // Invalid URL path. - return calculateDefaultInstanceDir(); - } - - return new File(file); - } - - private static File calculateDefaultInstanceDir() { - String homeDir = System.getProperty("user.home"); //$NON-NLS-1$ - String os = Platform.getOS(); - if (Platform.OS_WIN32.equals(os)) { - return new File(new File(new File(homeDir, "Application Data"), //$NON-NLS-1$ - "XMind"), //$NON-NLS-1$ - "workspace-cathy"); //$NON-NLS-1$ - } else if (Platform.OS_MACOSX.equals(os)) { - return new File(new File(new File(homeDir, "Library"), //$NON-NLS-1$ - "XMind"), //$NON-NLS-1$ - "workspace-cathy"); //$NON-NLS-1$ - } else { - return new File(new File(homeDir, ".xmind"), //$NON-NLS-1$ - "workspace-cathy"); //$NON-NLS-1$ - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.runtime; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.service.datalocation.Location; +import org.xmind.core.Core; +import org.xmind.core.internal.Workspace; + +public class WorkspaceConfigurer { + + public static final String INSTANCE_LOCATION = "${osgi.instance.area}"; //$NON-NLS-1$ + + public static final String USER_HOME = "${user.home}"; //$NON-NLS-1$ + + private static final Pattern EXPANSION = Pattern + .compile("\\$\\{([^\\}]+)\\}"); //$NON-NLS-1$ + + private WorkspaceConfigurer() { + throw new AssertionError(); + } + + public static void setDefaultWorkspaceLocation(String path) { + String location = expandWorkspaceLocation(path); + File dir = new File(location); + if (!dir.isDirectory()) { + dir.mkdirs(); + } + ((Workspace) Core.getWorkspace()).setDefaultWorkingDirectory(location); + } + + private static String expandWorkspaceLocation(String path) { + if (INSTANCE_LOCATION.equals(path)) { + String oldWorkspaceLocation = expandWorkspaceLocation(path + + "/.xmind"); //$NON-NLS-1$ + if (new File(oldWorkspaceLocation).isDirectory()) + return oldWorkspaceLocation; + } + + File instanceLocation = calculateInstanceDir(); + + Properties p = new Properties(); + p.putAll(System.getProperties()); + p.put(INSTANCE_LOCATION.substring(2, INSTANCE_LOCATION.length() - 1), + instanceLocation.getAbsolutePath()); + + StringBuffer buffer = new StringBuffer(path.length() * 2); + Matcher m = EXPANSION.matcher(path); + while (m.find()) { + String value = p.getProperty(m.group(1)); + if (value == null) + value = m.group(); + // Replace '\' and '$' to literal '\\' and '\$'. + value = value.replaceAll("([\\\\\\$])", "\\\\$1"); //$NON-NLS-1$ //$NON-NLS-2$ + m.appendReplacement(buffer, value); + } + m.appendTail(buffer); + return buffer.toString(); + } + + private static File calculateInstanceDir() { + Location loc = Platform.getInstanceLocation(); + if (loc == null) { + // Instance location not specified. + return calculateDefaultInstanceDir(); + } + URL url = loc.getURL(); + try { + url = FileLocator.toFileURL(url); + } catch (IOException e) { + // Invalid URL. + return calculateDefaultInstanceDir(); + } + + String file = url.getFile(); + if (file == null || "".equals(file)) {//$NON-NLS-1$ + // Invalid URL path. + return calculateDefaultInstanceDir(); + } + + return new File(file); + } + + private static File calculateDefaultInstanceDir() { + String homeDir = System.getProperty("user.home"); //$NON-NLS-1$ + String os = Platform.getOS(); + if (Platform.OS_WIN32.equals(os)) { + return new File(new File(new File(homeDir, "Application Data"), //$NON-NLS-1$ + "XMind"), //$NON-NLS-1$ + "workspace-cathy"); //$NON-NLS-1$ + } else if (Platform.OS_MACOSX.equals(os)) { + return new File(new File(new File(homeDir, "Library"), //$NON-NLS-1$ + "XMind"), //$NON-NLS-1$ + "workspace-cathy"); //$NON-NLS-1$ + } else { + return new File(new File(homeDir, ".xmind"), //$NON-NLS-1$ + "workspace-cathy"); //$NON-NLS-1$ + } + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceSession.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceSession.java index e0bb638ef..099f97115 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceSession.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/runtime/WorkspaceSession.java @@ -1,194 +1,194 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.runtime; - -import static org.xmind.core.internal.XmindCore.PLUGIN_ID; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.channels.FileLock; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.xmind.core.util.FileUtils; - -public class WorkspaceSession { - - private File tempRoot; - - private File stampFile; - - private RandomAccessFile stampFileWrapper; - - private FileLock stampFileLock; - - public WorkspaceSession(File tempRoot, File stampFile, - RandomAccessFile stampFileWrapper, FileLock stampFileLock) { - this.tempRoot = tempRoot; - this.stampFile = stampFile; - this.stampFileWrapper = stampFileWrapper; - this.stampFileLock = stampFileLock; - } - - /** - * Create a 'Workspace Stamp File' in the temp dir and lock it. - * - * @throws CoreException - * when we fail to the create or lock of the 'Workspace Stamp - * File' - */ - public static WorkspaceSession openSessionIn(File tempRoot) - throws CoreException { - if (!tempRoot.isDirectory()) { - if (!tempRoot.mkdirs()) { - throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, - "Failed to create temporary directory at " //$NON-NLS-1$ - + tempRoot.getAbsolutePath())); - } - } - - File stampFile; - try { - stampFile = File.createTempFile("xmind", ".core", tempRoot); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, - "Failed to create workspace stamp file in " //$NON-NLS-1$ - + tempRoot.getAbsolutePath(), e)); - } - - RandomAccessFile stampFileWrapper; - try { - stampFileWrapper = new RandomAccessFile(stampFile, "rw"); //$NON-NLS-1$ - } catch (FileNotFoundException e) { - stampFile.delete(); - throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, - "Failed to find created workspace stamp file at " //$NON-NLS-1$ - + stampFile.getAbsolutePath(), e)); - } - - FileLock stampFileLock = null; - - try { - for (int err = 0; err < 10; err++) { - try { - stampFileLock = stampFileWrapper.getChannel().tryLock(); - } catch (IOException e) { - } - if (stampFileLock != null) - break; - Thread.sleep(1); - } - } catch (InterruptedException e) { - } - - if (stampFileLock == null) { - try { - stampFileWrapper.close(); - } catch (IOException e) { - } - stampFile.delete(); - throw new CoreException( - new Status( - IStatus.ERROR, - PLUGIN_ID, - "Failed to lock workspace stamp file. Please make sure you have r/w permission at " //$NON-NLS-1$ - + tempRoot.getAbsolutePath())); - } - - return new WorkspaceSession(tempRoot, stampFile, stampFileWrapper, - stampFileLock); - } - - public void close() { - // Release stamp file lock and delete stamp file. - deleteStampFile(); - - // The last session in a temp dir is responsible for clearing the temp dir. - if (!hasOtherSession()) { - clearTempRoot(); - } - } - - private void deleteStampFile() { - if (stampFileLock != null) { - try { - stampFileLock.release(); - } catch (IOException e) { - } - stampFileLock = null; - } - if (stampFileWrapper != null) { - try { - stampFileWrapper.close(); - } catch (IOException e) { - } - stampFileWrapper = null; - } - if (stampFile != null) { - stampFile.delete(); - stampFile = null; - } - } - - private boolean hasOtherSession() { - if (!tempRoot.exists()) - return false; - - String[] stampFileNames = tempRoot.list(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.endsWith(".core"); //$NON-NLS-1$ - } - }); - - if (stampFileNames != null && stampFileNames.length > 0) { - for (int i = 0; i < stampFileNames.length; i++) { - File otherStampFile = new File(tempRoot, stampFileNames[i]); - if (isLocked(otherStampFile)) - return true; - } - } - - return false; - } - - private boolean isLocked(File file) { - try { - RandomAccessFile s = new RandomAccessFile(file, "rw"); //$NON-NLS-1$ - try { - FileLock l = s.getChannel().tryLock(); - if (l == null) - return true; - - try { - l.release(); - } catch (IOException e2) { - } - return false; - } finally { - s.close(); - } - } catch (IOException e) { - return false; - } - } - - private void clearTempRoot() { - FileUtils.delete(tempRoot); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.runtime; + +import static org.xmind.core.internal.XmindCore.PLUGIN_ID; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileLock; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.xmind.core.util.FileUtils; + +public class WorkspaceSession { + + private File tempRoot; + + private File stampFile; + + private RandomAccessFile stampFileWrapper; + + private FileLock stampFileLock; + + public WorkspaceSession(File tempRoot, File stampFile, + RandomAccessFile stampFileWrapper, FileLock stampFileLock) { + this.tempRoot = tempRoot; + this.stampFile = stampFile; + this.stampFileWrapper = stampFileWrapper; + this.stampFileLock = stampFileLock; + } + + /** + * Create a 'Workspace Stamp File' in the temp dir and lock it. + * + * @throws CoreException + * when we fail to the create or lock of the 'Workspace Stamp + * File' + */ + public static WorkspaceSession openSessionIn(File tempRoot) + throws CoreException { + if (!tempRoot.isDirectory()) { + if (!tempRoot.mkdirs()) { + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, + "Failed to create temporary directory at " //$NON-NLS-1$ + + tempRoot.getAbsolutePath())); + } + } + + File stampFile; + try { + stampFile = File.createTempFile("xmind", ".core", tempRoot); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, + "Failed to create workspace stamp file in " //$NON-NLS-1$ + + tempRoot.getAbsolutePath(), e)); + } + + RandomAccessFile stampFileWrapper; + try { + stampFileWrapper = new RandomAccessFile(stampFile, "rw"); //$NON-NLS-1$ + } catch (FileNotFoundException e) { + stampFile.delete(); + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, + "Failed to find created workspace stamp file at " //$NON-NLS-1$ + + stampFile.getAbsolutePath(), e)); + } + + FileLock stampFileLock = null; + + try { + for (int err = 0; err < 10; err++) { + try { + stampFileLock = stampFileWrapper.getChannel().tryLock(); + } catch (IOException e) { + } + if (stampFileLock != null) + break; + Thread.sleep(1); + } + } catch (InterruptedException e) { + } + + if (stampFileLock == null) { + try { + stampFileWrapper.close(); + } catch (IOException e) { + } + stampFile.delete(); + throw new CoreException( + new Status( + IStatus.ERROR, + PLUGIN_ID, + "Failed to lock workspace stamp file. Please make sure you have r/w permission at " //$NON-NLS-1$ + + tempRoot.getAbsolutePath())); + } + + return new WorkspaceSession(tempRoot, stampFile, stampFileWrapper, + stampFileLock); + } + + public void close() { + // Release stamp file lock and delete stamp file. + deleteStampFile(); + + // The last session in a temp dir is responsible for clearing the temp dir. + if (!hasOtherSession()) { + clearTempRoot(); + } + } + + private void deleteStampFile() { + if (stampFileLock != null) { + try { + stampFileLock.release(); + } catch (IOException e) { + } + stampFileLock = null; + } + if (stampFileWrapper != null) { + try { + stampFileWrapper.close(); + } catch (IOException e) { + } + stampFileWrapper = null; + } + if (stampFile != null) { + stampFile.delete(); + stampFile = null; + } + } + + private boolean hasOtherSession() { + if (!tempRoot.exists()) + return false; + + String[] stampFileNames = tempRoot.list(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".core"); //$NON-NLS-1$ + } + }); + + if (stampFileNames != null && stampFileNames.length > 0) { + for (int i = 0; i < stampFileNames.length; i++) { + File otherStampFile = new File(tempRoot, stampFileNames[i]); + if (isLocked(otherStampFile)) + return true; + } + } + + return false; + } + + private boolean isLocked(File file) { + try { + RandomAccessFile s = new RandomAccessFile(file, "rw"); //$NON-NLS-1$ + try { + FileLock l = s.getChannel().tryLock(); + if (l == null) + return true; + + try { + l.release(); + } catch (IOException e2) { + } + return false; + } finally { + s.close(); + } + } catch (IOException e) { + return false; + } + } + + private void clearTempRoot() { + FileUtils.delete(tempRoot); + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/Base64.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/Base64.java index d70cc4a0f..9b0cdd1d4 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/Base64.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/Base64.java @@ -1,238 +1,238 @@ -/* - * %W% %E% - * - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -package org.xmind.core.internal.security; - -/** - * Static methods for translating Base64 encoded strings to byte arrays and - * vice-versa. - * - * @author Josh Bloch - * @version %I%, %G% - * @see java.util.prefs.Preferences - * @since 1.4 - */ -class Base64 { - /** - * Translates the specified byte array into a Base64 string as per - * Preferences.put(byte[]). - */ - static String byteArrayToBase64(byte[] a) { - return byteArrayToBase64(a, false); - } - - /** - * Translates the specified byte array into an "alternate representation" - * Base64 string. This non-standard variant uses an alphabet that does not - * contain the uppercase alphabetic characters, which makes it suitable for - * use in situations where case-folding occurs. - */ - static String byteArrayToAltBase64(byte[] a) { - return byteArrayToBase64(a, true); - } - - private static String byteArrayToBase64(byte[] a, boolean alternate) { - int aLen = a.length; - int numFullGroups = aLen / 3; - int numBytesInPartialGroup = aLen - 3 * numFullGroups; - int resultLen = 4 * ((aLen + 2) / 3); - StringBuffer result = new StringBuffer(resultLen); - char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); - - // Translate all full groups from byte array elements to Base64 - int inCursor = 0; - for (int i = 0; i < numFullGroups; i++) { - int byte0 = a[inCursor++] & 0xff; - int byte1 = a[inCursor++] & 0xff; - int byte2 = a[inCursor++] & 0xff; - result.append(intToAlpha[byte0 >> 2]); - result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2) & 0x3f | (byte2 >> 6)]); - result.append(intToAlpha[byte2 & 0x3f]); - } - - // Translate partial group if present - if (numBytesInPartialGroup != 0) { - int byte0 = a[inCursor++] & 0xff; - result.append(intToAlpha[byte0 >> 2]); - if (numBytesInPartialGroup == 1) { - result.append(intToAlpha[(byte0 << 4) & 0x3f]); - result.append("=="); //$NON-NLS-1$ - } else { - // assert numBytesInPartialGroup == 2; - int byte1 = a[inCursor++] & 0xff; - result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2) & 0x3f]); - result.append('='); - } - } - // assert inCursor == a.length; - // assert result.length() == resultLen; - return result.toString(); - } - - /** - * This array is a lookup table that translates 6-bit positive integer index - * values into their "Base64 Alphabet" equivalents as specified in Table 1 - * of RFC 2045. - */ - private static final char intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', - 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' }; - - /** - * This array is a lookup table that translates 6-bit positive integer index - * values into their "Alternate Base64 Alphabet" equivalents. This is NOT - * the real Base64 Alphabet as per in Table 1 of RFC 2045. This alternate - * alphabet does not use the capital letters. It is designed for use in - * environments where "case folding" occurs. - */ - private static final char intToAltBase64[] = { '!', '"', '#', '$', '%', - '&', '\'', '(', ')', ',', '-', '.', ':', ';', '<', '>', '@', '[', - ']', '^', '`', '_', '{', '|', '}', '~', 'a', 'b', 'c', 'd', 'e', - 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', - 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', '+', '?' }; - - /** - * Translates the specified Base64 string (as per Preferences.get(byte[])) - * into a byte array. - * - * @throw IllegalArgumentException if s is not a valid Base64 - * string. - */ - static byte[] base64ToByteArray(String s) { - return base64ToByteArray(s, false); - } - - /** - * Translates the specified "alternate representation" Base64 string into a - * byte array. - * - * @throw IllegalArgumentException or ArrayOutOfBoundsException if - * s is not a valid alternate representation Base64 string. - */ - static byte[] altBase64ToByteArray(String s) { - return base64ToByteArray(s, true); - } - - private static byte[] base64ToByteArray(String s, boolean alternate) { - byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); - int sLen = s.length(); - int numGroups = sLen / 4; - if (4 * numGroups != sLen) - throw new IllegalArgumentException( - "String length must be a multiple of four."); //$NON-NLS-1$ - int missingBytesInLastGroup = 0; - int numFullGroups = numGroups; - if (sLen != 0) { - if (s.charAt(sLen - 1) == '=') { - missingBytesInLastGroup++; - numFullGroups--; - } - if (s.charAt(sLen - 2) == '=') - missingBytesInLastGroup++; - } - byte[] result = new byte[3 * numGroups - missingBytesInLastGroup]; - - // Translate all full groups from base64 to byte array elements - int inCursor = 0, outCursor = 0; - for (int i = 0; i < numFullGroups; i++) { - int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - result[outCursor++] = (byte) ((ch2 << 6) | ch3); - } - - // Translate partial group, if present - if (missingBytesInLastGroup != 0) { - int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); - - if (missingBytesInLastGroup == 1) { - int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - } - } - // assert inCursor == s.length()-missingBytesInLastGroup; - // assert outCursor == result.length; - return result; - } - - /** - * Translates the specified character, which is assumed to be in the - * "Base 64 Alphabet" into its equivalent 6-bit positive integer. - * - * @throw IllegalArgumentException or ArrayOutOfBoundsException if c is not - * in the Base64 Alphabet. - */ - private static int base64toInt(char c, byte[] alphaToInt) { - int result = alphaToInt[c]; - if (result < 0) - throw new IllegalArgumentException("Illegal character " + c); //$NON-NLS-1$ - return result; - } - - /** - * This array is a lookup table that translates unicode characters drawn - * from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into - * their 6-bit positive integer equivalents. Characters that are not in the - * Base64 alphabet but fall within the bounds of the array are translated to - * -1. - */ - private static final byte base64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, - -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; - - /** - * This array is the analogue of base64ToInt, but for the nonstandard - * variant that avoids the use of uppercase alphabetic characters. - */ - private static final byte altBase64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, - 62, 9, 10, 11, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 12, 13, - 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, 18, - 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 22, 23, 24, 25 }; - - public static void main(String args[]) { - int numRuns = Integer.parseInt(args[0]); - int numBytes = Integer.parseInt(args[1]); - java.util.Random rnd = new java.util.Random(); - for (int i = 0; i < numRuns; i++) { - for (int j = 0; j < numBytes; j++) { - byte[] arr = new byte[j]; - for (int k = 0; k < j; k++) - arr[k] = (byte) rnd.nextInt(); - - String s = byteArrayToBase64(arr); - byte[] b = base64ToByteArray(s); - if (!java.util.Arrays.equals(arr, b)) - System.out.println("Dismal failure!"); //$NON-NLS-1$ - - s = byteArrayToAltBase64(arr); - b = altBase64ToByteArray(s); - if (!java.util.Arrays.equals(arr, b)) - System.out.println("Alternate dismal failure!"); //$NON-NLS-1$ - } - } - } -} +/* + * %W% %E% + * + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package org.xmind.core.internal.security; + +/** + * Static methods for translating Base64 encoded strings to byte arrays and + * vice-versa. + * + * @author Josh Bloch + * @version %I%, %G% + * @see java.util.prefs.Preferences + * @since 1.4 + */ +class Base64 { + /** + * Translates the specified byte array into a Base64 string as per + * Preferences.put(byte[]). + */ + static String byteArrayToBase64(byte[] a) { + return byteArrayToBase64(a, false); + } + + /** + * Translates the specified byte array into an "alternate representation" + * Base64 string. This non-standard variant uses an alphabet that does not + * contain the uppercase alphabetic characters, which makes it suitable for + * use in situations where case-folding occurs. + */ + static String byteArrayToAltBase64(byte[] a) { + return byteArrayToBase64(a, true); + } + + private static String byteArrayToBase64(byte[] a, boolean alternate) { + int aLen = a.length; + int numFullGroups = aLen / 3; + int numBytesInPartialGroup = aLen - 3 * numFullGroups; + int resultLen = 4 * ((aLen + 2) / 3); + StringBuffer result = new StringBuffer(resultLen); + char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); + + // Translate all full groups from byte array elements to Base64 + int inCursor = 0; + for (int i = 0; i < numFullGroups; i++) { + int byte0 = a[inCursor++] & 0xff; + int byte1 = a[inCursor++] & 0xff; + int byte2 = a[inCursor++] & 0xff; + result.append(intToAlpha[byte0 >> 2]); + result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); + result.append(intToAlpha[(byte1 << 2) & 0x3f | (byte2 >> 6)]); + result.append(intToAlpha[byte2 & 0x3f]); + } + + // Translate partial group if present + if (numBytesInPartialGroup != 0) { + int byte0 = a[inCursor++] & 0xff; + result.append(intToAlpha[byte0 >> 2]); + if (numBytesInPartialGroup == 1) { + result.append(intToAlpha[(byte0 << 4) & 0x3f]); + result.append("=="); //$NON-NLS-1$ + } else { + // assert numBytesInPartialGroup == 2; + int byte1 = a[inCursor++] & 0xff; + result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); + result.append(intToAlpha[(byte1 << 2) & 0x3f]); + result.append('='); + } + } + // assert inCursor == a.length; + // assert result.length() == resultLen; + return result.toString(); + } + + /** + * This array is a lookup table that translates 6-bit positive integer index + * values into their "Base64 Alphabet" equivalents as specified in Table 1 + * of RFC 2045. + */ + private static final char intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' }; + + /** + * This array is a lookup table that translates 6-bit positive integer index + * values into their "Alternate Base64 Alphabet" equivalents. This is NOT + * the real Base64 Alphabet as per in Table 1 of RFC 2045. This alternate + * alphabet does not use the capital letters. It is designed for use in + * environments where "case folding" occurs. + */ + private static final char intToAltBase64[] = { '!', '"', '#', '$', '%', + '&', '\'', '(', ')', ',', '-', '.', ':', ';', '<', '>', '@', '[', + ']', '^', '`', '_', '{', '|', '}', '~', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '+', '?' }; + + /** + * Translates the specified Base64 string (as per Preferences.get(byte[])) + * into a byte array. + * + * @throw IllegalArgumentException if s is not a valid Base64 + * string. + */ + static byte[] base64ToByteArray(String s) { + return base64ToByteArray(s, false); + } + + /** + * Translates the specified "alternate representation" Base64 string into a + * byte array. + * + * @throw IllegalArgumentException or ArrayOutOfBoundsException if + * s is not a valid alternate representation Base64 string. + */ + static byte[] altBase64ToByteArray(String s) { + return base64ToByteArray(s, true); + } + + private static byte[] base64ToByteArray(String s, boolean alternate) { + byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); + int sLen = s.length(); + int numGroups = sLen / 4; + if (4 * numGroups != sLen) + throw new IllegalArgumentException( + "String length must be a multiple of four."); //$NON-NLS-1$ + int missingBytesInLastGroup = 0; + int numFullGroups = numGroups; + if (sLen != 0) { + if (s.charAt(sLen - 1) == '=') { + missingBytesInLastGroup++; + numFullGroups--; + } + if (s.charAt(sLen - 2) == '=') + missingBytesInLastGroup++; + } + byte[] result = new byte[3 * numGroups - missingBytesInLastGroup]; + + // Translate all full groups from base64 to byte array elements + int inCursor = 0, outCursor = 0; + for (int i = 0; i < numFullGroups; i++) { + int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); + int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); + int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); + int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt); + result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); + result[outCursor++] = (byte) ((ch2 << 6) | ch3); + } + + // Translate partial group, if present + if (missingBytesInLastGroup != 0) { + int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); + int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); + result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); + + if (missingBytesInLastGroup == 1) { + int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); + } + } + // assert inCursor == s.length()-missingBytesInLastGroup; + // assert outCursor == result.length; + return result; + } + + /** + * Translates the specified character, which is assumed to be in the + * "Base 64 Alphabet" into its equivalent 6-bit positive integer. + * + * @throw IllegalArgumentException or ArrayOutOfBoundsException if c is not + * in the Base64 Alphabet. + */ + private static int base64toInt(char c, byte[] alphaToInt) { + int result = alphaToInt[c]; + if (result < 0) + throw new IllegalArgumentException("Illegal character " + c); //$NON-NLS-1$ + return result; + } + + /** + * This array is a lookup table that translates unicode characters drawn + * from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into + * their 6-bit positive integer equivalents. Characters that are not in the + * Base64 alphabet but fall within the bounds of the array are translated to + * -1. + */ + private static final byte base64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, + -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, + -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; + + /** + * This array is the analogue of base64ToInt, but for the nonstandard + * variant that avoids the use of uppercase alphabetic characters. + */ + private static final byte altBase64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, + 62, 9, 10, 11, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 12, 13, + 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, 18, + 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 22, 23, 24, 25 }; + + public static void main(String args[]) { + int numRuns = Integer.parseInt(args[0]); + int numBytes = Integer.parseInt(args[1]); + java.util.Random rnd = new java.util.Random(); + for (int i = 0; i < numRuns; i++) { + for (int j = 0; j < numBytes; j++) { + byte[] arr = new byte[j]; + for (int k = 0; k < j; k++) + arr[k] = (byte) rnd.nextInt(); + + String s = byteArrayToBase64(arr); + byte[] b = base64ToByteArray(s); + if (!java.util.Arrays.equals(arr, b)) + System.out.println("Dismal failure!"); //$NON-NLS-1$ + + s = byteArrayToAltBase64(arr); + b = altBase64ToByteArray(s); + if (!java.util.Arrays.equals(arr, b)) + System.out.println("Alternate dismal failure!"); //$NON-NLS-1$ + } + } + } +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PKCS12KeyGenerator.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PKCS12KeyGenerator.java index 1c77cfcfe..d57d86719 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PKCS12KeyGenerator.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PKCS12KeyGenerator.java @@ -1,238 +1,238 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.security; - -import java.security.MessageDigest; - -/** - * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0. - *

- * The document this implementation is based on can be found at RSA's PKCS12 - * Page - *

- * NOTE: This algorithm in this class is copied from Bouncycastle's - * PKCS12ParametersGenerator in order to decrypt legacy xmind files. - * - * @author Frank Shaka - */ -public class PKCS12KeyGenerator { - - public static final int KEY_MATERIAL = 1; - public static final int IV_MATERIAL = 2; - public static final int MAC_MATERIAL = 3; - - protected byte[] password; - protected byte[] salt; - protected int iterationCount; - - private MessageDigest digest; - - private int u; - private int v; - - /** - * Construct a PKCS 12 Parameters generator. This constructor will accept - * any digest which also implements ExtendedDigest. - * - * @param digest - * the digest to be used as the source of derived keys. - * @exception IllegalArgumentException - * if an unknown digest is passed in. - */ - public PKCS12KeyGenerator(MessageDigest digest) { - this.digest = digest; - u = digest.getDigestLength(); - v = 64; //((ExtendedDigest)digest).getByteLength(); - } - - /** - * initialise the PBE generator. - * - * @param password - * the password converted into bytes (see below). - * @param salt - * the salt to be mixed with the password. - * @param iterationCount - * the number of iterations the "mixing" function is to be - * applied for. - */ - public void init(byte[] password, byte[] salt, int iterationCount) { - this.password = password; - this.salt = salt; - this.iterationCount = iterationCount; - } - - /** - * return the password byte array. - * - * @return the password byte array. - */ - public byte[] getPassword() { - return password; - } - - /** - * return the salt byte array. - * - * @return the salt byte array. - */ - public byte[] getSalt() { - return salt; - } - - /** - * return the iteration count. - * - * @return the iteration count. - */ - public int getIterationCount() { - return iterationCount; - } - - /** - * converts a password to a byte array according to the scheme in PKCS12 - * (unicode, big endian, 2 zero pad bytes at the end). - * - * @param password - * a character array representing the password. - * @return a byte array representing the password. - */ - public static byte[] PKCS12PasswordToBytes(char[] password) { - if (password != null && password.length > 0) { - // +1 for extra 2 pad bytes. - byte[] bytes = new byte[(password.length + 1) * 2]; - - for (int i = 0; i != password.length; i++) { - bytes[i * 2] = (byte) (password[i] >>> 8); - bytes[i * 2 + 1] = (byte) password[i]; - } - - return bytes; - } else { - return new byte[0]; - } - } - - /** - * add a + b + 1, returning the result in a. The a value is treated as a - * BigInteger of length (b.length * 8) bits. The result is modulo 2^b.length - * in case of overflow. - */ - private void adjust(byte[] a, int aOff, byte[] b) { - int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1; - - a[aOff + b.length - 1] = (byte) x; - x >>>= 8; - - for (int i = b.length - 2; i >= 0; i--) { - x += (b[i] & 0xff) + (a[aOff + i] & 0xff); - a[aOff + i] = (byte) x; - x >>>= 8; - } - } - - /** - * generation of a derived key ala PKCS12 V1.0. - */ - private byte[] generateDerivedKey(int idByte, int n) { - byte[] D = new byte[v]; - byte[] dKey = new byte[n]; - - for (int i = 0; i != D.length; i++) { - D[i] = (byte) idByte; - } - - byte[] S; - - if ((salt != null) && (salt.length != 0)) { - S = new byte[v * ((salt.length + v - 1) / v)]; - - for (int i = 0; i != S.length; i++) { - S[i] = salt[i % salt.length]; - } - } else { - S = new byte[0]; - } - - byte[] P; - - if ((password != null) && (password.length != 0)) { - P = new byte[v * ((password.length + v - 1) / v)]; - - for (int i = 0; i != P.length; i++) { - P[i] = password[i % password.length]; - } - } else { - P = new byte[0]; - } - - byte[] I = new byte[S.length + P.length]; - - System.arraycopy(S, 0, I, 0, S.length); - System.arraycopy(P, 0, I, S.length, P.length); - - byte[] B = new byte[v]; - int c = (n + u - 1) / u; - byte[] A; - - for (int i = 1; i <= c; i++) { - digest.update(D, 0, D.length); - digest.update(I, 0, I.length); - A = digest.digest(); - for (int j = 1; j < iterationCount; j++) { - digest.update(A, 0, A.length); - A = digest.digest(); - } - - for (int j = 0; j != B.length; j++) { - B[j] = A[j % A.length]; - } - - for (int j = 0; j != I.length / v; j++) { - adjust(I, j * v, B); - } - - if (i == c) { - System.arraycopy(A, 0, dKey, (i - 1) * u, - dKey.length - ((i - 1) * u)); - } else { - System.arraycopy(A, 0, dKey, (i - 1) * u, A.length); - } - } - - return dKey; - } - - /** - * Generate a key parameter derived from the password, salt, and iteration - * count we are currently initialised with. - * - * @param keySize - * the size of the key we want (in bits) - * @return a KeyParameter object. - */ - public byte[] generateDerivedKey(int keySize) { - keySize = keySize / 8; - - byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); - byte[] key = new byte[keySize]; - System.arraycopy(dKey, 0, key, 0, keySize); - return key; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.security; + +import java.security.MessageDigest; + +/** + * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0. + *

+ * The document this implementation is based on can be found at RSA's PKCS12 + * Page + *

+ * NOTE: This algorithm in this class is copied from Bouncycastle's + * PKCS12ParametersGenerator in order to decrypt legacy xmind files. + * + * @author Frank Shaka + */ +public class PKCS12KeyGenerator { + + public static final int KEY_MATERIAL = 1; + public static final int IV_MATERIAL = 2; + public static final int MAC_MATERIAL = 3; + + protected byte[] password; + protected byte[] salt; + protected int iterationCount; + + private MessageDigest digest; + + private int u; + private int v; + + /** + * Construct a PKCS 12 Parameters generator. This constructor will accept + * any digest which also implements ExtendedDigest. + * + * @param digest + * the digest to be used as the source of derived keys. + * @exception IllegalArgumentException + * if an unknown digest is passed in. + */ + public PKCS12KeyGenerator(MessageDigest digest) { + this.digest = digest; + u = digest.getDigestLength(); + v = 64; //((ExtendedDigest)digest).getByteLength(); + } + + /** + * initialise the PBE generator. + * + * @param password + * the password converted into bytes (see below). + * @param salt + * the salt to be mixed with the password. + * @param iterationCount + * the number of iterations the "mixing" function is to be + * applied for. + */ + public void init(byte[] password, byte[] salt, int iterationCount) { + this.password = password; + this.salt = salt; + this.iterationCount = iterationCount; + } + + /** + * return the password byte array. + * + * @return the password byte array. + */ + public byte[] getPassword() { + return password; + } + + /** + * return the salt byte array. + * + * @return the salt byte array. + */ + public byte[] getSalt() { + return salt; + } + + /** + * return the iteration count. + * + * @return the iteration count. + */ + public int getIterationCount() { + return iterationCount; + } + + /** + * converts a password to a byte array according to the scheme in PKCS12 + * (unicode, big endian, 2 zero pad bytes at the end). + * + * @param password + * a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] PKCS12PasswordToBytes(char[] password) { + if (password != null && password.length > 0) { + // +1 for extra 2 pad bytes. + byte[] bytes = new byte[(password.length + 1) * 2]; + + for (int i = 0; i != password.length; i++) { + bytes[i * 2] = (byte) (password[i] >>> 8); + bytes[i * 2 + 1] = (byte) password[i]; + } + + return bytes; + } else { + return new byte[0]; + } + } + + /** + * add a + b + 1, returning the result in a. The a value is treated as a + * BigInteger of length (b.length * 8) bits. The result is modulo 2^b.length + * in case of overflow. + */ + private void adjust(byte[] a, int aOff, byte[] b) { + int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1; + + a[aOff + b.length - 1] = (byte) x; + x >>>= 8; + + for (int i = b.length - 2; i >= 0; i--) { + x += (b[i] & 0xff) + (a[aOff + i] & 0xff); + a[aOff + i] = (byte) x; + x >>>= 8; + } + } + + /** + * generation of a derived key ala PKCS12 V1.0. + */ + private byte[] generateDerivedKey(int idByte, int n) { + byte[] D = new byte[v]; + byte[] dKey = new byte[n]; + + for (int i = 0; i != D.length; i++) { + D[i] = (byte) idByte; + } + + byte[] S; + + if ((salt != null) && (salt.length != 0)) { + S = new byte[v * ((salt.length + v - 1) / v)]; + + for (int i = 0; i != S.length; i++) { + S[i] = salt[i % salt.length]; + } + } else { + S = new byte[0]; + } + + byte[] P; + + if ((password != null) && (password.length != 0)) { + P = new byte[v * ((password.length + v - 1) / v)]; + + for (int i = 0; i != P.length; i++) { + P[i] = password[i % password.length]; + } + } else { + P = new byte[0]; + } + + byte[] I = new byte[S.length + P.length]; + + System.arraycopy(S, 0, I, 0, S.length); + System.arraycopy(P, 0, I, S.length, P.length); + + byte[] B = new byte[v]; + int c = (n + u - 1) / u; + byte[] A; + + for (int i = 1; i <= c; i++) { + digest.update(D, 0, D.length); + digest.update(I, 0, I.length); + A = digest.digest(); + for (int j = 1; j < iterationCount; j++) { + digest.update(A, 0, A.length); + A = digest.digest(); + } + + for (int j = 0; j != B.length; j++) { + B[j] = A[j % A.length]; + } + + for (int j = 0; j != I.length / v; j++) { + adjust(I, j * v, B); + } + + if (i == c) { + System.arraycopy(A, 0, dKey, (i - 1) * u, + dKey.length - ((i - 1) * u)); + } else { + System.arraycopy(A, 0, dKey, (i - 1) * u, A.length); + } + } + + return dKey; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize + * the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public byte[] generateDerivedKey(int keySize) { + keySize = keySize / 8; + + byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); + byte[] key = new byte[keySize]; + System.arraycopy(dKey, 0, key, 0, keySize); + return key; + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PasswordProtectedNormalizer.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PasswordProtectedNormalizer.java index 27d9e2f24..dd3dd2923 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PasswordProtectedNormalizer.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PasswordProtectedNormalizer.java @@ -1,313 +1,313 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.security; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALGORITHM_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ITERATION_COUNT; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_DERIVATION_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_IV; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_SIZE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SALT; -import static org.xmind.core.internal.dom.DOMConstants.TAG_ALGORITHM; -import static org.xmind.core.internal.dom.DOMConstants.TAG_KEY_DERIVATION; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.util.Random; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; - -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IEncryptionData; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.io.ChecksumTrackingOutputStream; -import org.xmind.core.io.ChecksumVerifiedInputStream; - -/** - * This class provides file entry encryption/decryption based on a password. - * Instances of this class that have the same password are considered equal to - * each other. - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class PasswordProtectedNormalizer implements IEntryStreamNormalizer { - - private static final String ALGORITHM_NAME = "AES/CBC/PKCS5Padding"; //$NON-NLS-1$ - private static final String OLD37_KEY_DERIVATION_ALGORITHM_NAME = "PKCS12"; //$NON-NLS-1$ - private static final String KEY_DERIVATION_ALGORITHM_NAME = "PBKDF2WithHmacSHA512"; //$NON-NLS-1$ - private static final String KEY_DERIVATION_ITERATION_COUNT = "1024"; //$NON-NLS-1$ - private static final String CHECKSUM_TYPE = "MD5"; //$NON-NLS-1$ - private static final String KEY_DERIVATION_SIZE = "128"; //$NON-NLS-1$ - - /** - * The randomizer - */ - private static Random random = null; - - /** - * The password - */ - private final String password; - - /** - * - */ - public PasswordProtectedNormalizer(String password) { - if (password == null) - throw new IllegalArgumentException("password is null"); //$NON-NLS-1$ - this.password = password; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. - * OutputStream, org.xmind.core.IFileEntry) - */ - public OutputStream normalizeOutputStream(OutputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - fileEntry.deleteEncryptionData(); - - IEncryptionData encData = fileEntry.createEncryptionData(); - encData.setAttribute(ALGORITHM_NAME, TAG_ALGORITHM, - ATTR_ALGORITHM_NAME); - encData.setAttribute(KEY_DERIVATION_ALGORITHM_NAME, TAG_KEY_DERIVATION, - ATTR_KEY_DERIVATION_NAME); - encData.setAttribute(generateSalt(), TAG_KEY_DERIVATION, ATTR_SALT); - encData.setAttribute(KEY_DERIVATION_ITERATION_COUNT, TAG_KEY_DERIVATION, - ATTR_ITERATION_COUNT); - encData.setAttribute(KEY_DERIVATION_SIZE, TAG_KEY_DERIVATION, - ATTR_KEY_SIZE); - encData.setAttribute(generateIV(), TAG_KEY_DERIVATION, ATTR_KEY_IV); - encData.setChecksumType(CHECKSUM_TYPE); - - boolean oldEncrptWay = beforeEncrpt37(encData); - Cipher cipher = createCipher(true, oldEncrptWay, encData, password); - OutputStream out = new CipherOutputStream(stream, cipher); - if (encData.getChecksumType() != null) { - out = new ChecksumTrackingOutputStream(encData, - new ChecksumOutputStream(out)); - } - return out; - } - - private boolean beforeEncrpt37(IEncryptionData encData) { - String keyAlgoName = encData.getAttribute(TAG_KEY_DERIVATION, - ATTR_KEY_DERIVATION_NAME); - return OLD37_KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. - * InputStream, org.xmind.core.IFileEntry) - */ - public InputStream normalizeInputStream(InputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - IEncryptionData encData = fileEntry.getEncryptionData(); - if (encData == null) - return stream; - - boolean oldEncrptWay = beforeEncrpt37(encData); - Cipher oldCipher = createCipher(false, oldEncrptWay, encData, password); - InputStream in = new CipherInputStream(stream, oldCipher); - if (encData.getChecksumType() != null) { - in = new ChecksumVerifiedInputStream(new ChecksumInputStream(in), - encData.getChecksum()); - } - return in; - } - - private Cipher createCipher(boolean encrypt, boolean oldWay, - IEncryptionData encData, String password) throws CoreException { - checkEncryptionData(encData); - Key aesKey = createKey(oldWay, encData, password); - byte[] iv = getIV(encData); - IvParameterSpec ivParameter = new IvParameterSpec(iv); - Cipher cipher = null; - try { - cipher = Cipher.getInstance(ALGORITHM_NAME); - } catch (NoSuchAlgorithmException e) { - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); - } catch (NoSuchPaddingException e) { - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); - } - try { - cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, - aesKey, ivParameter); - } catch (InvalidKeyException e) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } catch (InvalidAlgorithmParameterException e) { - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); - } - return cipher; - } - - private Key createKey(boolean old, IEncryptionData encData, String password) - throws CoreException { - byte[] key = old ? getOldKeyByte(encData, password) - : getKeyByte(encData, password); - return new SecretKeySpec(key, "AES"); //$NON-NLS-1$ - } - - private byte[] getKeyByte(IEncryptionData encData, String password) - throws CoreException { - SecretKeyFactory keyFactory = null; - try { - keyFactory = SecretKeyFactory - .getInstance(KEY_DERIVATION_ALGORITHM_NAME); - } catch (NoSuchAlgorithmException e) { - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); - } - - KeySpec keySpec = new PBEKeySpec(password.toCharArray(), - getSalt(encData), getIterationCount(encData), - getKeySize(encData)); - try { - return keyFactory.generateSecret(keySpec).getEncoded(); - } catch (InvalidKeySpecException e) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } - } - - private byte[] getOldKeyByte(IEncryptionData encData, String password) - throws CoreException { - PKCS12KeyGenerator keyGen = null; - try { - keyGen = new PKCS12KeyGenerator(MessageDigest.getInstance("MD5")); //$NON-NLS-1$ - } catch (NoSuchAlgorithmException e) { - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); - } - byte[] pwBytes = password == null ? new byte[0] - : PKCS12KeyGenerator - .PKCS12PasswordToBytes(password.toCharArray()); - keyGen.init(pwBytes, getSalt(encData), getIterationCount(encData)); - byte[] key = keyGen.generateDerivedKey(getKeySize(encData)); - return key; - } - - private void checkEncryptionData(IEncryptionData encData) - throws CoreException { - String algoName = encData.getAttribute(TAG_ALGORITHM, - ATTR_ALGORITHM_NAME); - if (algoName == null || !ALGORITHM_NAME.equals(algoName)) - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); - - String keyAlgoName = encData.getAttribute(TAG_KEY_DERIVATION, - ATTR_KEY_DERIVATION_NAME); - if (keyAlgoName == null || !(KEY_DERIVATION_ALGORITHM_NAME - .equals(keyAlgoName) - || OLD37_KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName))) - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); - } - - private int getIterationCount(IEncryptionData encData) { - return encData.getIntAttribute(1024, TAG_KEY_DERIVATION, - ATTR_ITERATION_COUNT); - } - - private byte[] getSalt(IEncryptionData encData) throws CoreException { - String saltString = encData.getAttribute(TAG_KEY_DERIVATION, ATTR_SALT); - if (saltString == null) - throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); - return Base64.base64ToByteArray(saltString); - } - - private byte[] getIV(IEncryptionData encData) throws CoreException { - String ivString = encData.getAttribute(TAG_KEY_DERIVATION, ATTR_KEY_IV); - if (ivString == null) { - return new byte[16]; - } - return Base64.base64ToByteArray(ivString); - } - - private int getKeySize(IEncryptionData encData) throws CoreException { - String keySizeString = encData.getAttribute(TAG_KEY_DERIVATION, - ATTR_KEY_SIZE); - if (keySizeString == null) { - return Integer.parseInt(KEY_DERIVATION_SIZE); - } - return Integer.parseInt(keySizeString); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof PasswordProtectedNormalizer)) - return false; - PasswordProtectedNormalizer that = (PasswordProtectedNormalizer) obj; - return this.password.equals(that.password); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return 37 ^ password.hashCode(); - } - - private static Random getRandom() { - if (random == null) - random = new Random(); - return random; - } - - private static String generateSalt() { - return Base64.byteArrayToBase64(generateSaltBytes()); - } - - private static String generateIV() { - return Base64.byteArrayToBase64(generateIVBytes()); - } - - private static byte[] generateSaltBytes() { - byte[] bytes = new byte[8]; - getRandom().nextBytes(bytes); - return bytes; - } - - private static byte[] generateIVBytes() { - byte[] bytes = new byte[16]; - getRandom().nextBytes(bytes); - return bytes; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.security; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALGORITHM_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ITERATION_COUNT; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_DERIVATION_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_IV; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_KEY_SIZE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SALT; +import static org.xmind.core.internal.dom.DOMConstants.TAG_ALGORITHM; +import static org.xmind.core.internal.dom.DOMConstants.TAG_KEY_DERIVATION; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Random; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IEncryptionData; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.io.ChecksumTrackingOutputStream; +import org.xmind.core.io.ChecksumVerifiedInputStream; + +/** + * This class provides file entry encryption/decryption based on a password. + * Instances of this class that have the same password are considered equal to + * each other. + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class PasswordProtectedNormalizer implements IEntryStreamNormalizer { + + private static final String ALGORITHM_NAME = "AES/CBC/PKCS5Padding"; //$NON-NLS-1$ + private static final String OLD37_KEY_DERIVATION_ALGORITHM_NAME = "PKCS12"; //$NON-NLS-1$ + private static final String KEY_DERIVATION_ALGORITHM_NAME = "PBKDF2WithHmacSHA512"; //$NON-NLS-1$ + private static final String KEY_DERIVATION_ITERATION_COUNT = "1024"; //$NON-NLS-1$ + private static final String CHECKSUM_TYPE = "MD5"; //$NON-NLS-1$ + private static final String KEY_DERIVATION_SIZE = "128"; //$NON-NLS-1$ + + /** + * The randomizer + */ + private static Random random = null; + + /** + * The password + */ + private final String password; + + /** + * + */ + public PasswordProtectedNormalizer(String password) { + if (password == null) + throw new IllegalArgumentException("password is null"); //$NON-NLS-1$ + this.password = password; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. + * OutputStream, org.xmind.core.IFileEntry) + */ + public OutputStream normalizeOutputStream(OutputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + fileEntry.deleteEncryptionData(); + + IEncryptionData encData = fileEntry.createEncryptionData(); + encData.setAttribute(ALGORITHM_NAME, TAG_ALGORITHM, + ATTR_ALGORITHM_NAME); + encData.setAttribute(KEY_DERIVATION_ALGORITHM_NAME, TAG_KEY_DERIVATION, + ATTR_KEY_DERIVATION_NAME); + encData.setAttribute(generateSalt(), TAG_KEY_DERIVATION, ATTR_SALT); + encData.setAttribute(KEY_DERIVATION_ITERATION_COUNT, TAG_KEY_DERIVATION, + ATTR_ITERATION_COUNT); + encData.setAttribute(KEY_DERIVATION_SIZE, TAG_KEY_DERIVATION, + ATTR_KEY_SIZE); + encData.setAttribute(generateIV(), TAG_KEY_DERIVATION, ATTR_KEY_IV); + encData.setChecksumType(CHECKSUM_TYPE); + + boolean oldEncrptWay = beforeEncrpt37(encData); + Cipher cipher = createCipher(true, oldEncrptWay, encData, password); + OutputStream out = new CipherOutputStream(stream, cipher); + if (encData.getChecksumType() != null) { + out = new ChecksumTrackingOutputStream(encData, + new ChecksumOutputStream(out)); + } + return out; + } + + private boolean beforeEncrpt37(IEncryptionData encData) { + String keyAlgoName = encData.getAttribute(TAG_KEY_DERIVATION, + ATTR_KEY_DERIVATION_NAME); + return OLD37_KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. + * InputStream, org.xmind.core.IFileEntry) + */ + public InputStream normalizeInputStream(InputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + IEncryptionData encData = fileEntry.getEncryptionData(); + if (encData == null) + return stream; + + boolean oldEncrptWay = beforeEncrpt37(encData); + Cipher oldCipher = createCipher(false, oldEncrptWay, encData, password); + InputStream in = new CipherInputStream(stream, oldCipher); + if (encData.getChecksumType() != null) { + in = new ChecksumVerifiedInputStream(new ChecksumInputStream(in), + encData.getChecksum()); + } + return in; + } + + private Cipher createCipher(boolean encrypt, boolean oldWay, + IEncryptionData encData, String password) throws CoreException { + checkEncryptionData(encData); + Key aesKey = createKey(oldWay, encData, password); + byte[] iv = getIV(encData); + IvParameterSpec ivParameter = new IvParameterSpec(iv); + Cipher cipher = null; + try { + cipher = Cipher.getInstance(ALGORITHM_NAME); + } catch (NoSuchAlgorithmException e) { + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); + } catch (NoSuchPaddingException e) { + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); + } + try { + cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, + aesKey, ivParameter); + } catch (InvalidKeyException e) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } catch (InvalidAlgorithmParameterException e) { + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); + } + return cipher; + } + + private Key createKey(boolean old, IEncryptionData encData, String password) + throws CoreException { + byte[] key = old ? getOldKeyByte(encData, password) + : getKeyByte(encData, password); + return new SecretKeySpec(key, "AES"); //$NON-NLS-1$ + } + + private byte[] getKeyByte(IEncryptionData encData, String password) + throws CoreException { + SecretKeyFactory keyFactory = null; + try { + keyFactory = SecretKeyFactory + .getInstance(KEY_DERIVATION_ALGORITHM_NAME); + } catch (NoSuchAlgorithmException e) { + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); + } + + KeySpec keySpec = new PBEKeySpec(password.toCharArray(), + getSalt(encData), getIterationCount(encData), + getKeySize(encData)); + try { + return keyFactory.generateSecret(keySpec).getEncoded(); + } catch (InvalidKeySpecException e) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } + } + + private byte[] getOldKeyByte(IEncryptionData encData, String password) + throws CoreException { + PKCS12KeyGenerator keyGen = null; + try { + keyGen = new PKCS12KeyGenerator(MessageDigest.getInstance("MD5")); //$NON-NLS-1$ + } catch (NoSuchAlgorithmException e) { + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM, e); + } + byte[] pwBytes = password == null ? new byte[0] + : PKCS12KeyGenerator + .PKCS12PasswordToBytes(password.toCharArray()); + keyGen.init(pwBytes, getSalt(encData), getIterationCount(encData)); + byte[] key = keyGen.generateDerivedKey(getKeySize(encData)); + return key; + } + + private void checkEncryptionData(IEncryptionData encData) + throws CoreException { + String algoName = encData.getAttribute(TAG_ALGORITHM, + ATTR_ALGORITHM_NAME); + if (algoName == null || !ALGORITHM_NAME.equals(algoName)) + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); + + String keyAlgoName = encData.getAttribute(TAG_KEY_DERIVATION, + ATTR_KEY_DERIVATION_NAME); + if (keyAlgoName == null || !(KEY_DERIVATION_ALGORITHM_NAME + .equals(keyAlgoName) + || OLD37_KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName))) + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); + } + + private int getIterationCount(IEncryptionData encData) { + return encData.getIntAttribute(1024, TAG_KEY_DERIVATION, + ATTR_ITERATION_COUNT); + } + + private byte[] getSalt(IEncryptionData encData) throws CoreException { + String saltString = encData.getAttribute(TAG_KEY_DERIVATION, ATTR_SALT); + if (saltString == null) + throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); + return Base64.base64ToByteArray(saltString); + } + + private byte[] getIV(IEncryptionData encData) throws CoreException { + String ivString = encData.getAttribute(TAG_KEY_DERIVATION, ATTR_KEY_IV); + if (ivString == null) { + return new byte[16]; + } + return Base64.base64ToByteArray(ivString); + } + + private int getKeySize(IEncryptionData encData) throws CoreException { + String keySizeString = encData.getAttribute(TAG_KEY_DERIVATION, + ATTR_KEY_SIZE); + if (keySizeString == null) { + return Integer.parseInt(KEY_DERIVATION_SIZE); + } + return Integer.parseInt(keySizeString); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof PasswordProtectedNormalizer)) + return false; + PasswordProtectedNormalizer that = (PasswordProtectedNormalizer) obj; + return this.password.equals(that.password); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return 37 ^ password.hashCode(); + } + + private static Random getRandom() { + if (random == null) + random = new Random(); + return random; + } + + private static String generateSalt() { + return Base64.byteArrayToBase64(generateSaltBytes()); + } + + private static String generateIV() { + return Base64.byteArrayToBase64(generateIVBytes()); + } + + private static byte[] generateSaltBytes() { + byte[] bytes = new byte[8]; + getRandom().nextBytes(bytes); + return bytes; + } + + private static byte[] generateIVBytes() { + byte[] bytes = new byte[16]; + getRandom().nextBytes(bytes); + return bytes; + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/Evaluator.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/Evaluator.java index e1129b749..c57e2c04a 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/Evaluator.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/Evaluator.java @@ -1,903 +1,903 @@ -package org.xmind.core.internal.xpath; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Evaluator { - - private static final List EMPTY_SEQUENCE = Collections.emptyList(); - - private static final String AXIS_ATTRIBUTE = "attribute"; //$NON-NLS-1$ - private static final String AXIS_CHILD = "child"; //$NON-NLS-1$ - private static final String AXIS_SELF = "self"; //$NON-NLS-1$ - private static final String AXIS_PARENT = "parent"; //$NON-NLS-1$ - - private static final String KIND_TEXT = "text"; //$NON-NLS-1$ - private static final String KIND_NODE = "node"; //$NON-NLS-1$ - private static final Set KINDS = new HashSet( - Arrays.asList(KIND_TEXT, KIND_NODE)); - - private static final String TOKEN_SINGLE_SLASH = "/"; //$NON-NLS-1$ - private static final String TOKEN_PREDICATE_START = "["; //$NON-NLS-1$ - private static final String TOKEN_PREDICATE_END = "]"; //$NON-NLS-1$ - private static final String TOKEN_SELF = "."; //$NON-NLS-1$ - private static final String TOKEN_PARENT = ".."; //$NON-NLS-1$ - private static final String TOKEN_PAREN_START = "("; //$NON-NLS-1$ - private static final String TOKEN_PAREN_END = ")"; //$NON-NLS-1$ - private static final String TOKEN_ARGUMENT_SEPARATOR = ","; //$NON-NLS-1$ - private static final String TOKEN_AXIS_SEPARATOR = "::"; //$NON-NLS-1$ - private static final String TOKEN_AXIS_ATTRIBUTE = "@"; //$NON-NLS-1$ - - private static final Pattern RE_LEXER = Pattern.compile( - "\\$?(?:(?![0-9-])(?:[\\w-]+|\\*):)?(?![0-9-])(?:[\\w-]+|\\*)|\\(:|:\\)|\\/\\/|\\.\\.|::|\\d+(?:\\.\\d*)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?|\"[^\"]*(?:\"\"[^\"]*)*\"|'[^']*(?:''[^']*)*'|<<|>>|[!<>]=|(?![0-9-])[\\w-]+:\\*|\\s+|."); //$NON-NLS-1$ - private static final Pattern RE_SPACE = Pattern.compile("^\\s+$"); //$NON-NLS-1$ - private static final Pattern RE_NAME = Pattern.compile( - "^(?:(?![0-9-])([\\w-]+|\\*)\\:)?(?![0-9-])([\\w-]+|\\*)$"); //$NON-NLS-1$ - private static final Pattern RE_INTEGER = Pattern.compile("^\\d+$"); //$NON-NLS-1$ - private static final Pattern RE_DOUBLE = Pattern.compile("^\\d*\\.\\d+$"); //$NON-NLS-1$ - private static final Pattern RE_STRING = Pattern - .compile("^'([^']*(?:''[^']*)*)'|\"([^\"]*(?:\"\"[^\"]*)*)\"$"); //$NON-NLS-1$ - - private static class EvaluationContext { - - public Evaluator staticContext; - - public Object item; - - public int position; - - public int size; - - public EvaluationContext(Evaluator staticContext, Object item) { - this.staticContext = staticContext; - this.item = item; - this.position = 0; - this.size = 0; - } - - } - - private static abstract class Expression { - - private List arguments = new ArrayList(); - - protected Expression() { - } - - protected void addArgument(Expression argument) { - this.arguments.add(argument); - } - - protected Expression getArgument(int index, Expression defaultArg) { - return index < arguments.size() ? arguments.get(index) : defaultArg; - } - - protected List getArguments() { - return this.arguments; - } - - public abstract List evaluate(EvaluationContext context); - - } - - private static final Expression NULL = new Expression() { - - @Override - public List evaluate(EvaluationContext context) { - return EMPTY_SEQUENCE; - } - - @Override - public String toString() { - return "null"; //$NON-NLS-1$ - } - - }; - - private static class Literal extends Expression { - - private Object value; - - public Literal(Object value) { - this.value = value; - } - - public Object getValue() { - return value; - } - - @Override - public List evaluate(EvaluationContext context) { - return Arrays.asList(value); - } - - @Override - public String toString() { - return value == null ? "null" : value.toString(); //$NON-NLS-1$ - } - - } - - private static class PathExpression extends Expression { - - @Override - public List evaluate(EvaluationContext context) { - Object oldItem = context.item; - - List sequence = Arrays.asList(oldItem); - List inputSequence, results; - - for (Expression arg : getArguments()) { - inputSequence = sequence; - sequence = new ArrayList(); - for (Object item : inputSequence) { - context.item = item; - results = arg.evaluate(context); - for (Object obj : results) { - if (!sequence.contains(obj)) { - sequence.add(obj); - } - } - } - } - - context.item = oldItem; - - return sequence; - } - - } - - private static class AxisExpression extends Expression { - - public String axis; - - public String nameToTest; - - public String kindToTest; - - public AxisExpression(String axis, String nameToTest, - String kindToTest) { - this.axis = axis; - this.nameToTest = nameToTest; - this.kindToTest = kindToTest; - } - - @Override - public List evaluate(EvaluationContext context) { - List sequence = new ArrayList(); - - IAxisProvider axisProvider = context.staticContext - .getAxisProvider(); - if (axisProvider == null) - return sequence; - - Object item = context.item; - if (AXIS_ATTRIBUTE.equals(axis)) { - if (nameToTest != null) - sequence.add(axisProvider.getAttribute(item, nameToTest)); - } else if (AXIS_CHILD.equals(axis)) { - if (nameToTest != null) - sequence.addAll( - axisProvider.getChildNodes(item, nameToTest)); - } else if (AXIS_PARENT.equals(axis)) { - if (KIND_NODE.equals(kindToTest)) { - sequence.add(axisProvider.getParentNode(item)); - } - } else if (AXIS_SELF.equals(axis)) { - if (KIND_TEXT.equals(kindToTest)) { - sequence.add(axisProvider.getTextContent(item)); - } else if (KIND_NODE.equals(kindToTest)) { - sequence.add(item); - } - } - - return sequence; - } - - @Override - public String toString() { - return String.format("%s::%s", axis, //$NON-NLS-1$ - nameToTest != null ? nameToTest : kindToTest + "()"); //$NON-NLS-1$ - } - - } - - private static class FilterExpression extends Expression { - - private Expression primary; - - public FilterExpression(Expression primary) { - this.primary = primary; - } - - @Override - public List evaluate(EvaluationContext context) { - List sequence = primary.evaluate(context); - sequence = applyPredicates(context, sequence); - return sequence; - } - - private List applyPredicates(EvaluationContext context, - List sequence) { - if (sequence.isEmpty() || getArguments().isEmpty()) - return sequence; - - Object oldItem = context.item; - int oldPosition = context.position; - int oldSize = context.size; - - List inputSequence, results; - int sequenceSize; - - for (Expression predicate : getArguments()) { - inputSequence = sequence; - sequenceSize = inputSequence.size(); - sequence = new ArrayList(); - - if (predicate instanceof Literal && ((Literal) predicate) - .getValue() instanceof Integer) { - int targetIndex = ((Integer) ((Literal) predicate) - .getValue()).intValue() - 1; - if (targetIndex >= 0 && targetIndex < sequenceSize) { - sequence.add(inputSequence.get(targetIndex)); - } - } else { - for (int index = 0; index < sequenceSize; index++) { - Object item = inputSequence.get(index); - context.item = item; - context.position = index + 1; - context.size = sequenceSize; - results = predicate.evaluate(context); - if (test(results, context, index + 1, predicate)) { - sequence.add(item); - } - } - } - } - - context.item = oldItem; - context.position = oldPosition; - context.size = oldSize; - - return sequence; - } - - private boolean test(List conditions, EvaluationContext context, - int position, Expression predicate) { - if (conditions.size() != 1) - return false; - - Object condition = conditions.get(0); - if (condition instanceof Boolean) - return ((Boolean) condition).booleanValue(); - if (condition instanceof String) - return !"".equals(condition); //$NON-NLS-1$ - if (condition instanceof Integer) - return ((Integer) condition).intValue() != 0; - if (condition instanceof Double) - return ((Double) condition).doubleValue() != 0; - - return condition != null; - } - - } - - private static class FunctionArgument { - private List sequence; - - public FunctionArgument(List sequence) { - this.sequence = sequence; - } - - public Object anyItem() { - return anyItem(null); - } - - public Object anyItem(Object defaultItem) { - return sequence.isEmpty() ? defaultItem : sequence.get(0); - } - - public List sequence() { - return sequence; - } - - } - - private static final FunctionArgument NULL_ARGUMENT = new FunctionArgument( - EMPTY_SEQUENCE); - - private static class FunctionArgumentList { - private List arguments; - - public FunctionArgumentList() { - this.arguments = new ArrayList(); - } - - public void add(FunctionArgument arg) { - arguments.add(arg); - } - - public FunctionArgument argumentAt(int index) { - return index >= 0 && index < arguments.size() ? arguments.get(index) - : NULL_ARGUMENT; - } - - public List sequenceAt(int index) { - return argumentAt(index).sequence(); - } - - public Object itemAt(int index) { - return argumentAt(index).anyItem(); - } - - } - - private static interface Function { - - Object call(EvaluationContext context, FunctionArgumentList args); - - } - - private static Map FUNCTIONS = new HashMap(); - - static { - FUNCTIONS.put("true", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - return Boolean.TRUE; - } - }); - - FUNCTIONS.put("false", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - return Boolean.FALSE; - } - }); - - FUNCTIONS.put("position", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - return Integer.valueOf(context.position); - } - }); - - FUNCTIONS.put("count", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - return Integer.valueOf(args.sequenceAt(0).size()); - } - }); - - FUNCTIONS.put("matches", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object text = args.itemAt(0); - Object regex = args.itemAt(1); - if (text == null || !(text instanceof String) || regex == null - || !(regex instanceof String)) - return Boolean.FALSE; - return Boolean.valueOf( - Pattern.matches((String) regex, (String) text)); - } - }); - - FUNCTIONS.put("eq", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - return op1 == op2 || (op1 != null && op1.equals(op2)); - } - }); - - FUNCTIONS.put("ne", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - return op1 != op2 && (op1 == null || !op1.equals(op2)); - } - }); - - FUNCTIONS.put("lt", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) - || (!(op2 instanceof Integer) - && !(op2 instanceof Double))) - return false; - Number n1 = (Number) op1; - Number n2 = (Number) op2; - if (op1 instanceof Double || op2 instanceof Double) { - return n1.doubleValue() < n2.doubleValue(); - } - return n1.intValue() < n2.intValue(); - } - }); - - FUNCTIONS.put("gt", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) - || (!(op2 instanceof Integer) - && !(op2 instanceof Double))) - return false; - Number n1 = (Number) op1; - Number n2 = (Number) op2; - if (op1 instanceof Double || op2 instanceof Double) { - return n1.doubleValue() > n2.doubleValue(); - } - return n1.intValue() > n2.intValue(); - } - }); - - FUNCTIONS.put("lte", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) - || (!(op2 instanceof Integer) - && !(op2 instanceof Double))) - return false; - Number n1 = (Number) op1; - Number n2 = (Number) op2; - if (op1 instanceof Double || op2 instanceof Double) { - return n1.doubleValue() <= n2.doubleValue(); - } - return n1.intValue() <= n2.intValue(); - } - }); - - FUNCTIONS.put("gte", new Function() { //$NON-NLS-1$ - public Object call(EvaluationContext context, - FunctionArgumentList args) { - Object op1 = args.itemAt(0); - Object op2 = args.itemAt(1); - if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) - || (!(op2 instanceof Integer) - && !(op2 instanceof Double))) - return false; - Number n1 = (Number) op1; - Number n2 = (Number) op2; - if (op1 instanceof Double || op2 instanceof Double) { - return n1.doubleValue() >= n2.doubleValue(); - } - return n1.intValue() >= n2.intValue(); - } - }); - - } - - private static final Map OPERATORS = new HashMap(); - - static { - OPERATORS.put("=", "eq"); //$NON-NLS-1$ //$NON-NLS-2$ - OPERATORS.put("!=", "ne"); //$NON-NLS-1$ //$NON-NLS-2$ - OPERATORS.put("<", "lt"); //$NON-NLS-1$ //$NON-NLS-2$ - OPERATORS.put(">", "gt"); //$NON-NLS-1$ //$NON-NLS-2$ - OPERATORS.put("<=", "lte"); //$NON-NLS-1$ //$NON-NLS-2$ - OPERATORS.put(">=", "gte"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - private static class FunctionCall extends Expression { - - private String name; - - public FunctionCall(String name) { - this.name = name; - } - - @SuppressWarnings("unchecked") - @Override - public List evaluate(EvaluationContext context) { - Function f = FUNCTIONS.get(name); - if (f == null) - return EMPTY_SEQUENCE; - - FunctionArgumentList args = new FunctionArgumentList(); - for (Expression arg : getArguments()) { - List sequence = arg.evaluate(context); - args.add(new FunctionArgument(sequence)); - } - - Object result = f.call(context, args); - if (result instanceof List) - return (List) result; - return Arrays.asList(result); - } - - } - - private String expressionText; - - private Expression expression; - - private IAxisProvider axisProvider; - - public Evaluator(String expression) { - this(expression, null); - } - - public Evaluator(String expression, IAxisProvider axisProvider) { - this.expressionText = expression; - this.axisProvider = axisProvider; - this.expression = null; - } - - public IAxisProvider getAxisProvider() { - return axisProvider; - } - - public void setAxisProvider(IAxisProvider axisProvider) { - this.axisProvider = axisProvider; - } - - @Override - public String toString() { - return expression.toString(); - } - - public List evaluate(Object context) { - if (expression == null) - expression = new ExpressionParser(expressionText).parse(); - - EvaluationContext ctx = new EvaluationContext(this, context); - return expression.evaluate(ctx); - } - - private static class ExpressionParser { - - private String[] tokens; - - private int tokenIndex; - - public ExpressionParser(String expression) { - List tokens = new ArrayList(); - Matcher matcher = RE_LEXER.matcher(expression); - while (matcher.find()) { - String token = matcher.group(); - if (!RE_SPACE.matcher(token).matches()) { - tokens.add(token); - } - } - this.tokens = tokens.toArray(new String[tokens.size()]); - this.tokenIndex = 0; - } - - public Expression parse() { - return parseExpression(); - } - - private String token() { - return token(0); - } - - private String token(int offset) { - int index = tokenIndex + offset; - return index < tokens.length ? tokens[index] : null; - } - - private boolean nextToken() { - return nextToken(1); - } - - private boolean nextToken(int offset) { - tokenIndex += Math.max(offset, 1); - return tokenIndex < tokens.length; - } - - private boolean hasToken() { - return tokenIndex < tokens.length; - } - - private Expression parseExpression() { - return parseSingleExpression(); - } - - private Expression parseSingleExpression() { - return parseOrExpression(); - } - - private Expression parseOrExpression() { - return parseAndExpression(); - } - - private Expression parseAndExpression() { - return parseComparisonExpression(); - } - - private Expression parseComparisonExpression() { - if (!hasToken()) - return NULL; - - Expression arg1 = null; - if (hasToken()) { - arg1 = parseRangeExpression(); - } - if (!hasToken()) - return arg1; - - String funcName = OPERATORS.get(token()); - if (funcName == null) - return arg1; - - nextToken(); - - Expression arg2 = parseRangeExpression(); - - Expression func = new FunctionCall(funcName); - func.addArgument(arg1); - func.addArgument(arg2); - return func; - } - - private Expression parseRangeExpression() { - return parseAdditiveExpression(); - } - - private Expression parseAdditiveExpression() { - return parseMultiplicativeExpression(); - } - - private Expression parseMultiplicativeExpression() { - return parseUnionExpression(); - } - - private Expression parseUnionExpression() { - return parseIntersectExceptExpression(); - } - - private Expression parseIntersectExceptExpression() { - return parseInstanceofExpression(); - } - - private Expression parseInstanceofExpression() { - return parseTreatExpression(); - } - - private Expression parseTreatExpression() { - return parseCastableExpression(); - } - - private Expression parseCastableExpression() { - return parseCastExpression(); - } - - private Expression parseCastExpression() { - return parseUnaryExpression(); - } - - private Expression parseUnaryExpression() { - return parseValueExpression(); - } - - private Expression parseValueExpression() { - return parsePathExpression(); - } - - private Expression parsePathExpression() { - if (!hasToken()) - return NULL; - - PathExpression path = new PathExpression(); - - if (TOKEN_SINGLE_SLASH.equals(token())) - nextToken(); - - while (true) { - Expression step = parseStepExpression(); - if (step == NULL) - break; - path.addArgument(step); - if (TOKEN_SINGLE_SLASH.equals(token())) - nextToken(); - else - break; - } - - if (path.getArguments().size() == 1) - return path.getArgument(0, NULL); - - return path; - } - - private Expression parseStepExpression() { - return parseFilterExpression(); - } - - private Expression parseFilterExpression() { - if (!hasToken()) - return NULL; - - Expression exp = parsePrimaryExpression(); - if (exp == NULL) - return NULL; - - Expression filter = new FilterExpression(exp); - while (TOKEN_PREDICATE_START.equals(token())) { - nextToken(); - Expression predicate = parseExpression(); - if (predicate != NULL) { - filter.addArgument(predicate); - } - if (TOKEN_PREDICATE_END.equals(token())) { - nextToken(); - } - } - if (filter.getArguments().isEmpty()) - return exp; - return filter; - } - - private Expression parsePrimaryExpression() { - if (!hasToken()) - return NULL; - - String token = token(); - if (TOKEN_PARENT.equals(token)) { - nextToken(); - return new AxisExpression(AXIS_PARENT, null, KIND_NODE); - } - if (TOKEN_SELF.equals(token)) { - nextToken(); - return new AxisExpression(AXIS_SELF, null, KIND_NODE); - } - Expression exp; - - exp = parseParenthesizedExpression(); - if (exp != NULL) - return exp; - - exp = parseFunctionCall(); - if (exp != NULL) - return exp; - - exp = parseVarRef(); - if (exp != NULL) - return exp; - - exp = parseLiteral(); - if (exp != NULL) - return exp; - - exp = parseAxisExpression(); - if (exp != NULL) - return exp; - - return NULL; - } - - private Expression parseParenthesizedExpression() { - Expression exp = NULL; - if (TOKEN_PAREN_START.equals(token())) { - nextToken(); - if (!TOKEN_PAREN_END.equals(token())) { - exp = parseExpression(); - } - if (TOKEN_PAREN_END.equals(token())) - nextToken(); - } - return exp; - } - - private Expression parseFunctionCall() { - if (!hasToken()) - return NULL; - - Matcher nameMatch = RE_NAME.matcher(token()); - if (nameMatch.matches() && TOKEN_PAREN_START.equals(token(1))) { - String namespace = nameMatch.group(1); - String funcName = nameMatch.group(2); - - if (namespace == null && KINDS.contains(funcName)) - return parseAxisExpression(); - - FunctionCall functionCall = new FunctionCall(funcName); - nextToken(2); - - if (!TOKEN_PAREN_END.equals(token())) { - do { - Expression exp = parseSingleExpression(); - functionCall.addArgument(exp); - } while (TOKEN_ARGUMENT_SEPARATOR.equals(token()) - && nextToken()); - } - - if (TOKEN_PAREN_END.equals(token())) { - nextToken(); - } - return functionCall; - } - return NULL; - } - - private Expression parseVarRef() { - return NULL; - } - - private Expression parseLiteral() { - if (!hasToken()) - return NULL; - - String token = token(); - if (RE_INTEGER.matcher(token).matches()) { - nextToken(); - return new Literal( - Integer.valueOf(Integer.parseInt(token, 10))); - } else if (RE_DOUBLE.matcher(token).matches()) { - nextToken(); - return new Literal(Double.valueOf(Double.parseDouble(token))); - } else { - Matcher m = RE_STRING.matcher(token); - if (m.matches()) { - nextToken(); - String string; - if (m.group(1) != null) { - string = m.group(1).replace("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$ - } else if (m.group(2) != null) { - string = m.group(2).replace("\"\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - string = ""; //$NON-NLS-1$ - } - return new Literal(string); - } - - } - return NULL; - } - - private Expression parseAxisExpression() { - if (!hasToken()) - return NULL; - - String axis = token(); - if (TOKEN_AXIS_SEPARATOR.equals(token(1))) { - nextToken(2); - String toTest = token(); - if (toTest != null && RE_NAME.matcher(toTest).matches()) { - nextToken(); - if (TOKEN_PAREN_START.equals(token(1)) - && TOKEN_PAREN_END.equals(token(2))) { - nextToken(2); - return new AxisExpression(axis, null, toTest); - } else { - return new AxisExpression(axis, toTest, null); - } - } else { - return new AxisExpression(axis, null, KIND_NODE); - } - } else if (TOKEN_AXIS_ATTRIBUTE.equals(axis)) { - nextToken(); - String name = token(); - if (RE_NAME.matcher(name).matches()) { - nextToken(); - return new AxisExpression(AXIS_ATTRIBUTE, name, null); - } - } else { - String name = token(); - if (RE_NAME.matcher(name).matches()) { - nextToken(); - return new AxisExpression(AXIS_CHILD, name, null); - } - } - return NULL; - } - - } - -} +package org.xmind.core.internal.xpath; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Evaluator { + + private static final List EMPTY_SEQUENCE = Collections.emptyList(); + + private static final String AXIS_ATTRIBUTE = "attribute"; //$NON-NLS-1$ + private static final String AXIS_CHILD = "child"; //$NON-NLS-1$ + private static final String AXIS_SELF = "self"; //$NON-NLS-1$ + private static final String AXIS_PARENT = "parent"; //$NON-NLS-1$ + + private static final String KIND_TEXT = "text"; //$NON-NLS-1$ + private static final String KIND_NODE = "node"; //$NON-NLS-1$ + private static final Set KINDS = new HashSet( + Arrays.asList(KIND_TEXT, KIND_NODE)); + + private static final String TOKEN_SINGLE_SLASH = "/"; //$NON-NLS-1$ + private static final String TOKEN_PREDICATE_START = "["; //$NON-NLS-1$ + private static final String TOKEN_PREDICATE_END = "]"; //$NON-NLS-1$ + private static final String TOKEN_SELF = "."; //$NON-NLS-1$ + private static final String TOKEN_PARENT = ".."; //$NON-NLS-1$ + private static final String TOKEN_PAREN_START = "("; //$NON-NLS-1$ + private static final String TOKEN_PAREN_END = ")"; //$NON-NLS-1$ + private static final String TOKEN_ARGUMENT_SEPARATOR = ","; //$NON-NLS-1$ + private static final String TOKEN_AXIS_SEPARATOR = "::"; //$NON-NLS-1$ + private static final String TOKEN_AXIS_ATTRIBUTE = "@"; //$NON-NLS-1$ + + private static final Pattern RE_LEXER = Pattern.compile( + "\\$?(?:(?![0-9-])(?:[\\w-]+|\\*):)?(?![0-9-])(?:[\\w-]+|\\*)|\\(:|:\\)|\\/\\/|\\.\\.|::|\\d+(?:\\.\\d*)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?|\"[^\"]*(?:\"\"[^\"]*)*\"|'[^']*(?:''[^']*)*'|<<|>>|[!<>]=|(?![0-9-])[\\w-]+:\\*|\\s+|."); //$NON-NLS-1$ + private static final Pattern RE_SPACE = Pattern.compile("^\\s+$"); //$NON-NLS-1$ + private static final Pattern RE_NAME = Pattern.compile( + "^(?:(?![0-9-])([\\w-]+|\\*)\\:)?(?![0-9-])([\\w-]+|\\*)$"); //$NON-NLS-1$ + private static final Pattern RE_INTEGER = Pattern.compile("^\\d+$"); //$NON-NLS-1$ + private static final Pattern RE_DOUBLE = Pattern.compile("^\\d*\\.\\d+$"); //$NON-NLS-1$ + private static final Pattern RE_STRING = Pattern + .compile("^'([^']*(?:''[^']*)*)'|\"([^\"]*(?:\"\"[^\"]*)*)\"$"); //$NON-NLS-1$ + + private static class EvaluationContext { + + public Evaluator staticContext; + + public Object item; + + public int position; + + public int size; + + public EvaluationContext(Evaluator staticContext, Object item) { + this.staticContext = staticContext; + this.item = item; + this.position = 0; + this.size = 0; + } + + } + + private static abstract class Expression { + + private List arguments = new ArrayList(); + + protected Expression() { + } + + protected void addArgument(Expression argument) { + this.arguments.add(argument); + } + + protected Expression getArgument(int index, Expression defaultArg) { + return index < arguments.size() ? arguments.get(index) : defaultArg; + } + + protected List getArguments() { + return this.arguments; + } + + public abstract List evaluate(EvaluationContext context); + + } + + private static final Expression NULL = new Expression() { + + @Override + public List evaluate(EvaluationContext context) { + return EMPTY_SEQUENCE; + } + + @Override + public String toString() { + return "null"; //$NON-NLS-1$ + } + + }; + + private static class Literal extends Expression { + + private Object value; + + public Literal(Object value) { + this.value = value; + } + + public Object getValue() { + return value; + } + + @Override + public List evaluate(EvaluationContext context) { + return Arrays.asList(value); + } + + @Override + public String toString() { + return value == null ? "null" : value.toString(); //$NON-NLS-1$ + } + + } + + private static class PathExpression extends Expression { + + @Override + public List evaluate(EvaluationContext context) { + Object oldItem = context.item; + + List sequence = Arrays.asList(oldItem); + List inputSequence, results; + + for (Expression arg : getArguments()) { + inputSequence = sequence; + sequence = new ArrayList(); + for (Object item : inputSequence) { + context.item = item; + results = arg.evaluate(context); + for (Object obj : results) { + if (!sequence.contains(obj)) { + sequence.add(obj); + } + } + } + } + + context.item = oldItem; + + return sequence; + } + + } + + private static class AxisExpression extends Expression { + + public String axis; + + public String nameToTest; + + public String kindToTest; + + public AxisExpression(String axis, String nameToTest, + String kindToTest) { + this.axis = axis; + this.nameToTest = nameToTest; + this.kindToTest = kindToTest; + } + + @Override + public List evaluate(EvaluationContext context) { + List sequence = new ArrayList(); + + IAxisProvider axisProvider = context.staticContext + .getAxisProvider(); + if (axisProvider == null) + return sequence; + + Object item = context.item; + if (AXIS_ATTRIBUTE.equals(axis)) { + if (nameToTest != null) + sequence.add(axisProvider.getAttribute(item, nameToTest)); + } else if (AXIS_CHILD.equals(axis)) { + if (nameToTest != null) + sequence.addAll( + axisProvider.getChildNodes(item, nameToTest)); + } else if (AXIS_PARENT.equals(axis)) { + if (KIND_NODE.equals(kindToTest)) { + sequence.add(axisProvider.getParentNode(item)); + } + } else if (AXIS_SELF.equals(axis)) { + if (KIND_TEXT.equals(kindToTest)) { + sequence.add(axisProvider.getTextContent(item)); + } else if (KIND_NODE.equals(kindToTest)) { + sequence.add(item); + } + } + + return sequence; + } + + @Override + public String toString() { + return String.format("%s::%s", axis, //$NON-NLS-1$ + nameToTest != null ? nameToTest : kindToTest + "()"); //$NON-NLS-1$ + } + + } + + private static class FilterExpression extends Expression { + + private Expression primary; + + public FilterExpression(Expression primary) { + this.primary = primary; + } + + @Override + public List evaluate(EvaluationContext context) { + List sequence = primary.evaluate(context); + sequence = applyPredicates(context, sequence); + return sequence; + } + + private List applyPredicates(EvaluationContext context, + List sequence) { + if (sequence.isEmpty() || getArguments().isEmpty()) + return sequence; + + Object oldItem = context.item; + int oldPosition = context.position; + int oldSize = context.size; + + List inputSequence, results; + int sequenceSize; + + for (Expression predicate : getArguments()) { + inputSequence = sequence; + sequenceSize = inputSequence.size(); + sequence = new ArrayList(); + + if (predicate instanceof Literal && ((Literal) predicate) + .getValue() instanceof Integer) { + int targetIndex = ((Integer) ((Literal) predicate) + .getValue()).intValue() - 1; + if (targetIndex >= 0 && targetIndex < sequenceSize) { + sequence.add(inputSequence.get(targetIndex)); + } + } else { + for (int index = 0; index < sequenceSize; index++) { + Object item = inputSequence.get(index); + context.item = item; + context.position = index + 1; + context.size = sequenceSize; + results = predicate.evaluate(context); + if (test(results, context, index + 1, predicate)) { + sequence.add(item); + } + } + } + } + + context.item = oldItem; + context.position = oldPosition; + context.size = oldSize; + + return sequence; + } + + private boolean test(List conditions, EvaluationContext context, + int position, Expression predicate) { + if (conditions.size() != 1) + return false; + + Object condition = conditions.get(0); + if (condition instanceof Boolean) + return ((Boolean) condition).booleanValue(); + if (condition instanceof String) + return !"".equals(condition); //$NON-NLS-1$ + if (condition instanceof Integer) + return ((Integer) condition).intValue() != 0; + if (condition instanceof Double) + return ((Double) condition).doubleValue() != 0; + + return condition != null; + } + + } + + private static class FunctionArgument { + private List sequence; + + public FunctionArgument(List sequence) { + this.sequence = sequence; + } + + public Object anyItem() { + return anyItem(null); + } + + public Object anyItem(Object defaultItem) { + return sequence.isEmpty() ? defaultItem : sequence.get(0); + } + + public List sequence() { + return sequence; + } + + } + + private static final FunctionArgument NULL_ARGUMENT = new FunctionArgument( + EMPTY_SEQUENCE); + + private static class FunctionArgumentList { + private List arguments; + + public FunctionArgumentList() { + this.arguments = new ArrayList(); + } + + public void add(FunctionArgument arg) { + arguments.add(arg); + } + + public FunctionArgument argumentAt(int index) { + return index >= 0 && index < arguments.size() ? arguments.get(index) + : NULL_ARGUMENT; + } + + public List sequenceAt(int index) { + return argumentAt(index).sequence(); + } + + public Object itemAt(int index) { + return argumentAt(index).anyItem(); + } + + } + + private static interface Function { + + Object call(EvaluationContext context, FunctionArgumentList args); + + } + + private static Map FUNCTIONS = new HashMap(); + + static { + FUNCTIONS.put("true", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + return Boolean.TRUE; + } + }); + + FUNCTIONS.put("false", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + return Boolean.FALSE; + } + }); + + FUNCTIONS.put("position", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + return Integer.valueOf(context.position); + } + }); + + FUNCTIONS.put("count", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + return Integer.valueOf(args.sequenceAt(0).size()); + } + }); + + FUNCTIONS.put("matches", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object text = args.itemAt(0); + Object regex = args.itemAt(1); + if (text == null || !(text instanceof String) || regex == null + || !(regex instanceof String)) + return Boolean.FALSE; + return Boolean.valueOf( + Pattern.matches((String) regex, (String) text)); + } + }); + + FUNCTIONS.put("eq", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + return op1 == op2 || (op1 != null && op1.equals(op2)); + } + }); + + FUNCTIONS.put("ne", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + return op1 != op2 && (op1 == null || !op1.equals(op2)); + } + }); + + FUNCTIONS.put("lt", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) + || (!(op2 instanceof Integer) + && !(op2 instanceof Double))) + return false; + Number n1 = (Number) op1; + Number n2 = (Number) op2; + if (op1 instanceof Double || op2 instanceof Double) { + return n1.doubleValue() < n2.doubleValue(); + } + return n1.intValue() < n2.intValue(); + } + }); + + FUNCTIONS.put("gt", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) + || (!(op2 instanceof Integer) + && !(op2 instanceof Double))) + return false; + Number n1 = (Number) op1; + Number n2 = (Number) op2; + if (op1 instanceof Double || op2 instanceof Double) { + return n1.doubleValue() > n2.doubleValue(); + } + return n1.intValue() > n2.intValue(); + } + }); + + FUNCTIONS.put("lte", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) + || (!(op2 instanceof Integer) + && !(op2 instanceof Double))) + return false; + Number n1 = (Number) op1; + Number n2 = (Number) op2; + if (op1 instanceof Double || op2 instanceof Double) { + return n1.doubleValue() <= n2.doubleValue(); + } + return n1.intValue() <= n2.intValue(); + } + }); + + FUNCTIONS.put("gte", new Function() { //$NON-NLS-1$ + public Object call(EvaluationContext context, + FunctionArgumentList args) { + Object op1 = args.itemAt(0); + Object op2 = args.itemAt(1); + if ((!(op1 instanceof Integer) && !(op1 instanceof Double)) + || (!(op2 instanceof Integer) + && !(op2 instanceof Double))) + return false; + Number n1 = (Number) op1; + Number n2 = (Number) op2; + if (op1 instanceof Double || op2 instanceof Double) { + return n1.doubleValue() >= n2.doubleValue(); + } + return n1.intValue() >= n2.intValue(); + } + }); + + } + + private static final Map OPERATORS = new HashMap(); + + static { + OPERATORS.put("=", "eq"); //$NON-NLS-1$ //$NON-NLS-2$ + OPERATORS.put("!=", "ne"); //$NON-NLS-1$ //$NON-NLS-2$ + OPERATORS.put("<", "lt"); //$NON-NLS-1$ //$NON-NLS-2$ + OPERATORS.put(">", "gt"); //$NON-NLS-1$ //$NON-NLS-2$ + OPERATORS.put("<=", "lte"); //$NON-NLS-1$ //$NON-NLS-2$ + OPERATORS.put(">=", "gte"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private static class FunctionCall extends Expression { + + private String name; + + public FunctionCall(String name) { + this.name = name; + } + + @SuppressWarnings("unchecked") + @Override + public List evaluate(EvaluationContext context) { + Function f = FUNCTIONS.get(name); + if (f == null) + return EMPTY_SEQUENCE; + + FunctionArgumentList args = new FunctionArgumentList(); + for (Expression arg : getArguments()) { + List sequence = arg.evaluate(context); + args.add(new FunctionArgument(sequence)); + } + + Object result = f.call(context, args); + if (result instanceof List) + return (List) result; + return Arrays.asList(result); + } + + } + + private String expressionText; + + private Expression expression; + + private IAxisProvider axisProvider; + + public Evaluator(String expression) { + this(expression, null); + } + + public Evaluator(String expression, IAxisProvider axisProvider) { + this.expressionText = expression; + this.axisProvider = axisProvider; + this.expression = null; + } + + public IAxisProvider getAxisProvider() { + return axisProvider; + } + + public void setAxisProvider(IAxisProvider axisProvider) { + this.axisProvider = axisProvider; + } + + @Override + public String toString() { + return expression.toString(); + } + + public List evaluate(Object context) { + if (expression == null) + expression = new ExpressionParser(expressionText).parse(); + + EvaluationContext ctx = new EvaluationContext(this, context); + return expression.evaluate(ctx); + } + + private static class ExpressionParser { + + private String[] tokens; + + private int tokenIndex; + + public ExpressionParser(String expression) { + List tokens = new ArrayList(); + Matcher matcher = RE_LEXER.matcher(expression); + while (matcher.find()) { + String token = matcher.group(); + if (!RE_SPACE.matcher(token).matches()) { + tokens.add(token); + } + } + this.tokens = tokens.toArray(new String[tokens.size()]); + this.tokenIndex = 0; + } + + public Expression parse() { + return parseExpression(); + } + + private String token() { + return token(0); + } + + private String token(int offset) { + int index = tokenIndex + offset; + return index < tokens.length ? tokens[index] : null; + } + + private boolean nextToken() { + return nextToken(1); + } + + private boolean nextToken(int offset) { + tokenIndex += Math.max(offset, 1); + return tokenIndex < tokens.length; + } + + private boolean hasToken() { + return tokenIndex < tokens.length; + } + + private Expression parseExpression() { + return parseSingleExpression(); + } + + private Expression parseSingleExpression() { + return parseOrExpression(); + } + + private Expression parseOrExpression() { + return parseAndExpression(); + } + + private Expression parseAndExpression() { + return parseComparisonExpression(); + } + + private Expression parseComparisonExpression() { + if (!hasToken()) + return NULL; + + Expression arg1 = null; + if (hasToken()) { + arg1 = parseRangeExpression(); + } + if (!hasToken()) + return arg1; + + String funcName = OPERATORS.get(token()); + if (funcName == null) + return arg1; + + nextToken(); + + Expression arg2 = parseRangeExpression(); + + Expression func = new FunctionCall(funcName); + func.addArgument(arg1); + func.addArgument(arg2); + return func; + } + + private Expression parseRangeExpression() { + return parseAdditiveExpression(); + } + + private Expression parseAdditiveExpression() { + return parseMultiplicativeExpression(); + } + + private Expression parseMultiplicativeExpression() { + return parseUnionExpression(); + } + + private Expression parseUnionExpression() { + return parseIntersectExceptExpression(); + } + + private Expression parseIntersectExceptExpression() { + return parseInstanceofExpression(); + } + + private Expression parseInstanceofExpression() { + return parseTreatExpression(); + } + + private Expression parseTreatExpression() { + return parseCastableExpression(); + } + + private Expression parseCastableExpression() { + return parseCastExpression(); + } + + private Expression parseCastExpression() { + return parseUnaryExpression(); + } + + private Expression parseUnaryExpression() { + return parseValueExpression(); + } + + private Expression parseValueExpression() { + return parsePathExpression(); + } + + private Expression parsePathExpression() { + if (!hasToken()) + return NULL; + + PathExpression path = new PathExpression(); + + if (TOKEN_SINGLE_SLASH.equals(token())) + nextToken(); + + while (true) { + Expression step = parseStepExpression(); + if (step == NULL) + break; + path.addArgument(step); + if (TOKEN_SINGLE_SLASH.equals(token())) + nextToken(); + else + break; + } + + if (path.getArguments().size() == 1) + return path.getArgument(0, NULL); + + return path; + } + + private Expression parseStepExpression() { + return parseFilterExpression(); + } + + private Expression parseFilterExpression() { + if (!hasToken()) + return NULL; + + Expression exp = parsePrimaryExpression(); + if (exp == NULL) + return NULL; + + Expression filter = new FilterExpression(exp); + while (TOKEN_PREDICATE_START.equals(token())) { + nextToken(); + Expression predicate = parseExpression(); + if (predicate != NULL) { + filter.addArgument(predicate); + } + if (TOKEN_PREDICATE_END.equals(token())) { + nextToken(); + } + } + if (filter.getArguments().isEmpty()) + return exp; + return filter; + } + + private Expression parsePrimaryExpression() { + if (!hasToken()) + return NULL; + + String token = token(); + if (TOKEN_PARENT.equals(token)) { + nextToken(); + return new AxisExpression(AXIS_PARENT, null, KIND_NODE); + } + if (TOKEN_SELF.equals(token)) { + nextToken(); + return new AxisExpression(AXIS_SELF, null, KIND_NODE); + } + Expression exp; + + exp = parseParenthesizedExpression(); + if (exp != NULL) + return exp; + + exp = parseFunctionCall(); + if (exp != NULL) + return exp; + + exp = parseVarRef(); + if (exp != NULL) + return exp; + + exp = parseLiteral(); + if (exp != NULL) + return exp; + + exp = parseAxisExpression(); + if (exp != NULL) + return exp; + + return NULL; + } + + private Expression parseParenthesizedExpression() { + Expression exp = NULL; + if (TOKEN_PAREN_START.equals(token())) { + nextToken(); + if (!TOKEN_PAREN_END.equals(token())) { + exp = parseExpression(); + } + if (TOKEN_PAREN_END.equals(token())) + nextToken(); + } + return exp; + } + + private Expression parseFunctionCall() { + if (!hasToken()) + return NULL; + + Matcher nameMatch = RE_NAME.matcher(token()); + if (nameMatch.matches() && TOKEN_PAREN_START.equals(token(1))) { + String namespace = nameMatch.group(1); + String funcName = nameMatch.group(2); + + if (namespace == null && KINDS.contains(funcName)) + return parseAxisExpression(); + + FunctionCall functionCall = new FunctionCall(funcName); + nextToken(2); + + if (!TOKEN_PAREN_END.equals(token())) { + do { + Expression exp = parseSingleExpression(); + functionCall.addArgument(exp); + } while (TOKEN_ARGUMENT_SEPARATOR.equals(token()) + && nextToken()); + } + + if (TOKEN_PAREN_END.equals(token())) { + nextToken(); + } + return functionCall; + } + return NULL; + } + + private Expression parseVarRef() { + return NULL; + } + + private Expression parseLiteral() { + if (!hasToken()) + return NULL; + + String token = token(); + if (RE_INTEGER.matcher(token).matches()) { + nextToken(); + return new Literal( + Integer.valueOf(Integer.parseInt(token, 10))); + } else if (RE_DOUBLE.matcher(token).matches()) { + nextToken(); + return new Literal(Double.valueOf(Double.parseDouble(token))); + } else { + Matcher m = RE_STRING.matcher(token); + if (m.matches()) { + nextToken(); + String string; + if (m.group(1) != null) { + string = m.group(1).replace("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } else if (m.group(2) != null) { + string = m.group(2).replace("\"\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + string = ""; //$NON-NLS-1$ + } + return new Literal(string); + } + + } + return NULL; + } + + private Expression parseAxisExpression() { + if (!hasToken()) + return NULL; + + String axis = token(); + if (TOKEN_AXIS_SEPARATOR.equals(token(1))) { + nextToken(2); + String toTest = token(); + if (toTest != null && RE_NAME.matcher(toTest).matches()) { + nextToken(); + if (TOKEN_PAREN_START.equals(token(1)) + && TOKEN_PAREN_END.equals(token(2))) { + nextToken(2); + return new AxisExpression(axis, null, toTest); + } else { + return new AxisExpression(axis, toTest, null); + } + } else { + return new AxisExpression(axis, null, KIND_NODE); + } + } else if (TOKEN_AXIS_ATTRIBUTE.equals(axis)) { + nextToken(); + String name = token(); + if (RE_NAME.matcher(name).matches()) { + nextToken(); + return new AxisExpression(AXIS_ATTRIBUTE, name, null); + } + } else { + String name = token(); + if (RE_NAME.matcher(name).matches()) { + nextToken(); + return new AxisExpression(AXIS_CHILD, name, null); + } + } + return NULL; + } + + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/IAxisProvider.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/IAxisProvider.java index 43b01876b..67f8f2ed4 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/IAxisProvider.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/xpath/IAxisProvider.java @@ -1,15 +1,15 @@ -package org.xmind.core.internal.xpath; - -import java.util.List; - -public interface IAxisProvider { - - Object getAttribute(Object node, String name); - - List getChildNodes(Object node, String name); - - Object getParentNode(Object node); - - String getTextContent(Object node); - -} +package org.xmind.core.internal.xpath; + +import java.util.List; + +public interface IAxisProvider { + + Object getAttribute(Object node, String name); + + List getChildNodes(Object node, String name); + + Object getParentNode(Object node); + + String getTextContent(Object node); + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResource.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResource.java index 8941bd945..3bb10665e 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResource.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResource.java @@ -1,105 +1,105 @@ -package org.xmind.core.io; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Bundle; -import org.xmind.core.internal.runtime.BundleResourceFinder; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public final class BundleResource { - - private static final String SCHEME_PLATFORM = "platform"; //$NON-NLS-1$ - private static final String TYPE_PLUGIN = "plugin"; //$NON-NLS-1$ - - private final Bundle bundle; - - private final IPath path; - - public BundleResource(Bundle bundle, IPath path) { - Assert.isNotNull(bundle); - this.bundle = bundle; - this.path = path == null ? Path.EMPTY : path; - } - - public BundleResource(URL platformURL) { - Assert.isNotNull(platformURL); - Assert.isLegal(SCHEME_PLATFORM.equals(platformURL.getProtocol())); - - String fullPathString = platformURL.getPath(); - Assert.isLegal(fullPathString != null && !"".equals(fullPathString)); //$NON-NLS-1$ - - IPath fullPath = new Path(fullPathString); - String type = fullPath.segment(0); - Assert.isLegal(TYPE_PLUGIN.equals(type)); - - fullPath = fullPath.removeFirstSegments(1); - String bundleId = fullPath.segment(0); - Assert.isLegal(bundleId != null && !"".equals(bundleId)); //$NON-NLS-1$ - - Bundle bundle = Platform.getBundle(bundleId); - Assert.isLegal(bundle != null); - - this.bundle = bundle; - this.path = fullPath.removeFirstSegments(1); - } - - public Bundle getBundle() { - return bundle; - } - - public IPath getPath() { - return path; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof BundleResource)) - return false; - BundleResource that = (BundleResource) obj; - return this.bundle.equals(that.bundle) && this.path.equals(that.path); - } - - @Override - public int hashCode() { - return 37 ^ bundle.hashCode() ^ path.hashCode(); - } - - @Override - public String toString() { - return toPlatformURL().toExternalForm(); - } - - public URL toPlatformURL() { - IPath urlPath = Path.ROOT.append(TYPE_PLUGIN).addTrailingSeparator() - .append(bundle.getSymbolicName()).addTrailingSeparator() - .append(path); - try { - return new URL(SCHEME_PLATFORM, null, urlPath.toString()); - } catch (MalformedURLException e) { - throw new IllegalStateException(String.format( - "Failed to construct platform URL: bundle=%s, path=%s", //$NON-NLS-1$ - bundle.getSymbolicName(), path), e); - } - } - - /** - * Replace variables like '$nl$', '$os$', '$ws$'. - * - * @return resolved bundle resource, or null if not resolved - */ - public BundleResource resolve() { - return BundleResourceFinder.resolve(this); - } - -} +package org.xmind.core.io; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.xmind.core.internal.runtime.BundleResourceFinder; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public final class BundleResource { + + private static final String SCHEME_PLATFORM = "platform"; //$NON-NLS-1$ + private static final String TYPE_PLUGIN = "plugin"; //$NON-NLS-1$ + + private final Bundle bundle; + + private final IPath path; + + public BundleResource(Bundle bundle, IPath path) { + Assert.isNotNull(bundle); + this.bundle = bundle; + this.path = path == null ? Path.EMPTY : path; + } + + public BundleResource(URL platformURL) { + Assert.isNotNull(platformURL); + Assert.isLegal(SCHEME_PLATFORM.equals(platformURL.getProtocol())); + + String fullPathString = platformURL.getPath(); + Assert.isLegal(fullPathString != null && !"".equals(fullPathString)); //$NON-NLS-1$ + + IPath fullPath = new Path(fullPathString); + String type = fullPath.segment(0); + Assert.isLegal(TYPE_PLUGIN.equals(type)); + + fullPath = fullPath.removeFirstSegments(1); + String bundleId = fullPath.segment(0); + Assert.isLegal(bundleId != null && !"".equals(bundleId)); //$NON-NLS-1$ + + Bundle bundle = Platform.getBundle(bundleId); + Assert.isLegal(bundle != null); + + this.bundle = bundle; + this.path = fullPath.removeFirstSegments(1); + } + + public Bundle getBundle() { + return bundle; + } + + public IPath getPath() { + return path; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof BundleResource)) + return false; + BundleResource that = (BundleResource) obj; + return this.bundle.equals(that.bundle) && this.path.equals(that.path); + } + + @Override + public int hashCode() { + return 37 ^ bundle.hashCode() ^ path.hashCode(); + } + + @Override + public String toString() { + return toPlatformURL().toExternalForm(); + } + + public URL toPlatformURL() { + IPath urlPath = Path.ROOT.append(TYPE_PLUGIN).addTrailingSeparator() + .append(bundle.getSymbolicName()).addTrailingSeparator() + .append(path); + try { + return new URL(SCHEME_PLATFORM, null, urlPath.toString()); + } catch (MalformedURLException e) { + throw new IllegalStateException(String.format( + "Failed to construct platform URL: bundle=%s, path=%s", //$NON-NLS-1$ + bundle.getSymbolicName(), path), e); + } + } + + /** + * Replace variables like '$nl$', '$os$', '$ws$'. + * + * @return resolved bundle resource, or null if not resolved + */ + public BundleResource resolve() { + return BundleResourceFinder.resolve(this); + } + +} diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResourceInputSource.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResourceInputSource.java index 8042f2cad..4338fc52c 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResourceInputSource.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/io/BundleResourceInputSource.java @@ -1,145 +1,145 @@ -package org.xmind.core.io; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Stack; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Bundle; - -public class BundleResourceInputSource implements IInputSource { - - private BundleResource base; - - public BundleResourceInputSource(BundleResource baseResource) { - Assert.isNotNull(baseResource); - BundleResource resolved = baseResource.resolve(); - this.base = resolved == null ? baseResource : resolved; - } - - public BundleResourceInputSource(String pluginId, String basePath) { - this(new BundleResource(Platform.getBundle(pluginId), - new Path(basePath))); - } - - public BundleResourceInputSource(Bundle bundle, String basePath) { - this(new BundleResource(bundle, new Path(basePath))); - } - - private URL getEntry(String entryName) { - BundleResource entryResource = new BundleResource(base.getBundle(), - base.getPath().append(entryName)).resolve(); - if (entryResource == null) - return null; - return entryResource.toPlatformURL(); - } - - public boolean hasEntry(String entryName) { - return getEntry(entryName) != null; - } - - public Iterator getEntries() { - String basePath = base.getPath().toString(); - final String prefix = basePath.startsWith("/") ? basePath.substring(1) //$NON-NLS-1$ - : basePath; - final Stack> pathStack = new Stack>(); - pathStack.push(base.getBundle().getEntryPaths(basePath)); - return new Iterator() { - - private String nextPath = findNextPath(); - - private String findNextPath() { - if (pathStack.isEmpty()) - return null; - - Enumeration paths = pathStack.peek(); - - if (!paths.hasMoreElements()) { - // reached end of current path list - pathStack.pop(); - return findNextPath(); - } - - String path = paths.nextElement(); - - if (path.endsWith("/")) { //$NON-NLS-1$ - // directory path - // add sub path list - pathStack.push(base.getBundle().getEntryPaths(path)); - return findNextPath(); - } - - if (path.startsWith(prefix)) - return path.substring(prefix.length()); - - return findNextPath(); - } - - public void remove() { - } - - public String next() { - String p = nextPath; - nextPath = findNextPath(); - return p; - } - - public boolean hasNext() { - return nextPath != null; - } - }; - } - - public boolean isEntryAvailable(String entryName) { - return getEntry(entryName) != null; - } - - public InputStream getEntryStream(String entryName) { - try { - return openEntryStream(entryName); - } catch (IOException e) { - return null; - } - } - - public InputStream openEntryStream(String entryName) throws IOException { - URL entry = getEntry(entryName); - if (entry == null) - throw new FileNotFoundException(); - return entry.openStream(); - } - - public long getEntrySize(String entryName) { - URL entry = getEntry(entryName); - if (entry == null) - return 0; - URLConnection conn; - try { - conn = entry.openConnection(); - } catch (IOException e) { - return 0; - } - return conn.getContentLength(); - } - - public long getEntryTime(String entryName) { - URL entry = getEntry(entryName); - if (entry == null) - return 0; - URLConnection conn; - try { - conn = entry.openConnection(); - } catch (IOException e) { - return 0; - } - return conn.getLastModified(); - } - +package org.xmind.core.io; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Stack; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + +public class BundleResourceInputSource implements IInputSource { + + private BundleResource base; + + public BundleResourceInputSource(BundleResource baseResource) { + Assert.isNotNull(baseResource); + BundleResource resolved = baseResource.resolve(); + this.base = resolved == null ? baseResource : resolved; + } + + public BundleResourceInputSource(String pluginId, String basePath) { + this(new BundleResource(Platform.getBundle(pluginId), + new Path(basePath))); + } + + public BundleResourceInputSource(Bundle bundle, String basePath) { + this(new BundleResource(bundle, new Path(basePath))); + } + + private URL getEntry(String entryName) { + BundleResource entryResource = new BundleResource(base.getBundle(), + base.getPath().append(entryName)).resolve(); + if (entryResource == null) + return null; + return entryResource.toPlatformURL(); + } + + public boolean hasEntry(String entryName) { + return getEntry(entryName) != null; + } + + public Iterator getEntries() { + String basePath = base.getPath().toString(); + final String prefix = basePath.startsWith("/") ? basePath.substring(1) //$NON-NLS-1$ + : basePath; + final Stack> pathStack = new Stack>(); + pathStack.push(base.getBundle().getEntryPaths(basePath)); + return new Iterator() { + + private String nextPath = findNextPath(); + + private String findNextPath() { + if (pathStack.isEmpty()) + return null; + + Enumeration paths = pathStack.peek(); + + if (!paths.hasMoreElements()) { + // reached end of current path list + pathStack.pop(); + return findNextPath(); + } + + String path = paths.nextElement(); + + if (path.endsWith("/")) { //$NON-NLS-1$ + // directory path + // add sub path list + pathStack.push(base.getBundle().getEntryPaths(path)); + return findNextPath(); + } + + if (path.startsWith(prefix)) + return path.substring(prefix.length()); + + return findNextPath(); + } + + public void remove() { + } + + public String next() { + String p = nextPath; + nextPath = findNextPath(); + return p; + } + + public boolean hasNext() { + return nextPath != null; + } + }; + } + + public boolean isEntryAvailable(String entryName) { + return getEntry(entryName) != null; + } + + public InputStream getEntryStream(String entryName) { + try { + return openEntryStream(entryName); + } catch (IOException e) { + return null; + } + } + + public InputStream openEntryStream(String entryName) throws IOException { + URL entry = getEntry(entryName); + if (entry == null) + throw new FileNotFoundException(); + return entry.openStream(); + } + + public long getEntrySize(String entryName) { + URL entry = getEntry(entryName); + if (entry == null) + return 0; + URLConnection conn; + try { + conn = entry.openConnection(); + } catch (IOException e) { + return 0; + } + return conn.getContentLength(); + } + + public long getEntryTime(String entryName) { + URL entry = getEntry(entryName); + if (entry == null) + return 0; + URLConnection conn; + try { + conn = entry.openConnection(); + } catch (IOException e) { + return 0; + } + return conn.getLastModified(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core.runtime/src/org/xmind/core/util/ProgressReporter.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/util/ProgressReporter.java index 8d576615a..70c86cedc 100644 --- a/bundles/org.xmind.core.runtime/src/org/xmind/core/util/ProgressReporter.java +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/util/ProgressReporter.java @@ -1,63 +1,63 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.util; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.xmind.core.util.IProgressReporter; - -/** - * @author Frank Shaka - * - */ -public class ProgressReporter implements IProgressReporter { - - private static final int DEFAULT_TOTAL = 10000; - - private SubMonitor monitor; - - private int worked; - - /** - * - */ - public ProgressReporter(IProgressMonitor monitor) { - this.monitor = SubMonitor.convert(monitor, DEFAULT_TOTAL); - this.worked = 0; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.util.IProgressReporter#progressChanged(int, int) - */ - public void progressChanged(int current, int total) { - int target = current * DEFAULT_TOTAL / total; - monitor.worked(target - worked); - this.worked = target; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.util.IProgressReporter#isCanceled() - */ - public boolean isCanceled() { - return monitor.isCanceled(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.util; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.xmind.core.util.IProgressReporter; + +/** + * @author Frank Shaka + * + */ +public class ProgressReporter implements IProgressReporter { + + private static final int DEFAULT_TOTAL = 10000; + + private SubMonitor monitor; + + private int worked; + + /** + * + */ + public ProgressReporter(IProgressMonitor monitor) { + this.monitor = SubMonitor.convert(monitor, DEFAULT_TOTAL); + this.worked = 0; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.util.IProgressReporter#progressChanged(int, int) + */ + public void progressChanged(int current, int total) { + int target = current * DEFAULT_TOTAL / total; + monitor.worked(target - worked); + this.worked = target; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.util.IProgressReporter#isCanceled() + */ + public boolean isCanceled() { + return monitor.isCanceled(); + } + +} diff --git a/bundles/org.xmind.core.usagedata/.classpath b/bundles/org.xmind.core.usagedata/.classpath index 8a8f1668c..ad32c83a7 100644 --- a/bundles/org.xmind.core.usagedata/.classpath +++ b/bundles/org.xmind.core.usagedata/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.core.usagedata/.gitignore b/bundles/org.xmind.core.usagedata/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core.usagedata/.gitignore +++ b/bundles/org.xmind.core.usagedata/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core.usagedata/.project b/bundles/org.xmind.core.usagedata/.project index 1107b880d..dec6dd5a6 100644 --- a/bundles/org.xmind.core.usagedata/.project +++ b/bundles/org.xmind.core.usagedata/.project @@ -1,28 +1,28 @@ - - - org.xmind.core.usagedata - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.core.usagedata + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.core.prefs index 10cd93bd3..ed4985d46 100644 --- a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.core.prefs @@ -1,404 +1,404 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.pde.prefs index 9be2bbfea..62cfa90de 100644 --- a/bundles/org.xmind.core.usagedata/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.core.usagedata/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=1 -compilers.p.discouraged-class=1 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF b/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF index 00336c978..27838d0ef 100644 --- a/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF @@ -1,9 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Usage Data API -Bundle-SymbolicName: org.xmind.core.usagedata -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %Bundle-Vendor -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.core.usagedata +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Usage Data API +Bundle-SymbolicName: org.xmind.core.usagedata +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.core.internal;x-internal:=true, + org.xmind.core.usagedata diff --git a/bundles/org.xmind.core.usagedata/about.html b/bundles/org.xmind.core.usagedata/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core.usagedata/about.html +++ b/bundles/org.xmind.core.usagedata/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core.usagedata/build.properties b/bundles/org.xmind.core.usagedata/build.properties index a657887e9..17daa5b49 100644 --- a/bundles/org.xmind.core.usagedata/build.properties +++ b/bundles/org.xmind.core.usagedata/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html diff --git a/bundles/org.xmind.core.usagedata/pom.xml b/bundles/org.xmind.core.usagedata/pom.xml index 7945a9b90..2db051b1c 100644 --- a/bundles/org.xmind.core.usagedata/pom.xml +++ b/bundles/org.xmind.core.usagedata/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core.usagedata - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core.usagedata + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core.usagedata/src/org/xmind/core/internal/UserDataConstants.java b/bundles/org.xmind.core.usagedata/src/org/xmind/core/internal/UserDataConstants.java new file mode 100644 index 000000000..7f34dbc89 --- /dev/null +++ b/bundles/org.xmind.core.usagedata/src/org/xmind/core/internal/UserDataConstants.java @@ -0,0 +1,246 @@ +package org.xmind.core.internal; + +public class UserDataConstants { + + /** StartUp */ + public static final String SCREEN_RESOLUTION = "ScreenResolution"; //$NON-NLS-1$ + public static final String SCREEN_WIDTH = "ScreenWidth"; //$NON-NLS-1$ + public static final String SCREEN_HEIGHT = "ScreenHeight";//$NON-NLS-1$ + public static final String JAVA_VENDOR = "JavaVendor";//$NON-NLS-1$ + public static final String JAVA_VERSION = "JavaVersion";//$NON-NLS-1$ + public static final String COUNTRY = "Country";//$NON-NLS-1$ + public static final String OS_VERSION = "OSVersion";//$NON-NLS-1$ + public static final String OS_NAME = "OSName";//$NON-NLS-1$ + public static final String BUILD_ID = "BuildId";//$NON-NLS-1$ + public static final String ARCH = "Arch";//$NON-NLS-1$ + public static final String OS = "OS";//$NON-NLS-1$ + public static final String DISTRIBUTION_ID = "DistributionId";//$NON-NLS-1$ + public static final String SHUT_DOWN_TIME = "ShutDownTime"; //$NON-NLS-1$ + public static final String START_UP_TIME = "StartUpTime";//$NON-NLS-1$ + public static final String NL = "NL";//$NON-NLS-1$ + public static final String APP_ID = "AppId"; //$NON-NLS-1$ + + public static final String BUY_COUNT = "BuyCount"; //$NON-NLS-1$ + public static final String BUY_FOR_S_COUNT = "BuyFor%sCount"; //$NON-NLS-1$ + public static final String SUBSCRIBE_COUNT = "SubscribeCount"; //$NON-NLS-1$ + + public static final String KEY_AUTH_SESSION_ID = "sessionId"; //$NON-NLS-1$ + public static final String KEY_AUTH_ACCOUNT_ID = "user"; //$NON-NLS-1$ + public static final String KEY_AUTH_SIGN_IN_TIME_WITH_SESSION_ID = "XMindIdAuthorizations/%s/SignInTime"; //$NON-NLS-1$ + public static final String KEY_AUTH_SIGN_OUT_TIME_WITH_SESSION_ID = "XMindIdAuthorizations/%s/SignOutTime"; //$NON-NLS-1$ + public static final String KEY_AUTH_ACCOUNT_TYPE_WITH_SESSION_ID = "XMindIdAuthorizations/%s/AccountType"; //$NON-NLS-1$ + + public static final String KEY_SHOW_TIME = "Notifications/%s/%s/ShowTime"; //$NON-NLS-1$ + public static final String KEY_DISMISS_TIME = "Notifications/%s/%s/DismissTime"; //$NON-NLS-1$ + public static final String KEY_CLICK_TIME = "Notifications/%s/%s/ClickTime"; //$NON-NLS-1$ + + /** Workbook */ + public static final String CREATE_WORKBOOK_COUNT = "CreateWorkbookCount"; //$NON-NLS-1$ + public static final String SET_PASSWORD_COUNT = "SetPasswordCount"; //$NON-NLS-1$ + public static final String SET_PASSWORD_HINT_COUNT = "SetPasswordHintCount"; //$NON-NLS-1$ + public static final String OPEN_LOCAL_WORKBOOK_COUNT = "OpenLocalWorkbookCount"; //$NON-NLS-1$ + public static final String OPEN_CLOUD_WORKBOOK_COUNT = "OpenCloudWorkbookCount"; //$NON-NLS-1$ + public static final String FILE_ENCRYPTION_COUNT = "FileEncryptionCount"; //$NON-NLS-1$ + + /** FormatPart */ + public static final String SHOW_FORMAT_PART_COUNT = "ShowFormatPartCount"; //$NON-NLS-1$ + public static final String CHANGE_WALLPAPER_COUNT = "ChangeWallpaperCount"; //$NON-NLS-1$ + public static final String TOGGLE_GRADIENT_COLOR_COUNT = "ToggleGradientColorCount"; //$NON-NLS-1$ + public static final String TOGGLE_TAPEREDLINE_COUNT = "ToggleTaperedlineCount"; //$NON-NLS-1$ + public static final String TOGGLE_MULTI_COLOR_COUNT = "ToggleMultiColorCount"; //$NON-NLS-1$ + public static final String CHANGE_LEGEND_BACKGROUD_COUNT = "ChangeLegendBackgroudCount"; //$NON-NLS-1$ + public static final String SHOW_LEGEND_COUNT = "ShowLegendCount"; //$NON-NLS-1$ + public static final String NUMBERING_TYPE_COUNT = "NumberingTypeCount:"; //$NON-NLS-1$ + public static final String NUMBER_DEPTH_COUNT = "NumberDepthCount"; //$NON-NLS-1$ + public static final String FILTER_OPERATION_COUNT = "FilterOperationCount"; //$NON-NLS-1$ + + public static final String WELCOME_TO_XMIND_COUNT = "WelcomeToXmindCount"; //$NON-NLS-1$ + public static final String SHOW_PRO_COUNT = "ShowProCount"; //$NON-NLS-1$ + public static final String SHOW_PRO_FOR_S_COUNT = "ShowProFor%sCount"; //$NON-NLS-1$ + + /** Modify */ + public static final String DRILL_DOWN_COUNT = "DrillDownCount"; //$NON-NLS-1$ + public static final String RESET_POSITION_COUNT = "ResetPositionCount"; //$NON-NLS-1$ + public static final String TILE_COUNT = "TileCount"; //$NON-NLS-1$ + public static final String ALLOW_OVERLAP_COUNT = "AllowOverlapCount"; //$NON-NLS-1$ + public static final String ALLOW_FREE_POSITION_COUNT = "AllowFreePositionCount"; //$NON-NLS-1$ + public static final String REDUCE_FILE_SIZE_COUNT = "ReduceFileSizeCount"; //$NON-NLS-1$ + + /** Sheet */ + public static final String CREATE_SHEET_COUNT = "CreateSheetCount"; //$NON-NLS-1$ + public static final String SPREAD_SHEET_COUNT = "SpreadSheetCount"; //$NON-NLS-1$ + + /** Structure */ + public static final String STRUCTURE_TYPE_COUNT = "StructureTypeCount:";//$NON-NLS-1$ + public static final String MODIFY_STRUCTURE_COUNT = "ModifyStructureCount"; //$NON-NLS-1$ + + /** MarkerPart */ + public static final String SHOW_MARKER_COUNT = "ShowMarkerCount"; //$NON-NLS-1$ // its in popover ,and unused. + public static final String SHOW_MARKER_PART_COUNT = "ShowMarkerPartCount"; //$NON-NLS-1$ + public static final String USE_MARKERS_COUNT = "UseMarkersCount"; //$NON-NLS-1$ + public static final String USER_MARKER_COUNT = "UserMarkerCount"; //$NON-NLS-1$ + public static final String USER_ADD_GROUP_COUNT = "UserAddGroupCount"; //$NON-NLS-1$ + + /** NotesPart */ + public static final String USE_NOTES_COUNT = "UseNotesCount"; //$NON-NLS-1$ + public static final String NOTES_FONT_CHANGE_COUNT = "NotesFontChangeCount"; //$NON-NLS-1$ + public static final String NOTES_INSERT_IMAGE_COUNT = "NotesInsertImageCount"; //$NON-NLS-1$ + public static final String NOTES_INSERT_HYPERLINK_COUNT = "NotesInsertHyperlinkCount"; //$NON-NLS-1$ + + /** Comment */ + public static final String ADD_COMMENT_COUNT = "AddCommentCount"; //$NON-NLS-1$ + + /** Presentation */ + public static final String START_PRESENTATION_COUNT = "StartPresentationCount"; //$NON-NLS-1$ + public static final String SHOW_OR_HIDE_SIDE_BAR_COUNT = "ShowOrHideSideBarCount"; //$NON-NLS-1$ + public static final String CREATE_STORY_COUNT = "CreateStoryCount"; //$NON-NLS-1$ + public static final String ADD_SLIDE_COUNT = "AddSlideCount"; //$NON-NLS-1$ + public static final String START_PRESENTATION_STORY_COUNT = "StartPresentationStoryCount"; //$NON-NLS-1$ + public static final String SHOW_SIDE_STORY_WARNING_TIP_COUNT = "ShowSideStoryWarningTipCount";//$NON-NLS-1$ + + /** Template */ + public static final String SHOW_TEMPLATES_COUNT = "ShowTemplatesCount"; //$NON-NLS-1$ + public static final String USE_TEMPLATES_COUNT = "UseTemplatesCount"; //$NON-NLS-1$ + public static final String USE_S_TEMPLATE_COUNT = "Use_%s_TemplateCount";//$NON-NLS-1$ + + /** Theme */ + public static final String SHOW_THEME_COUNT = "ShowThemeCount"; //$NON-NLS-1$ + public static final String CHANGE_THEME_COUNT = "ChangeThemeCount"; //$NON-NLS-1$ + public static final String EDIT_THEME_COUNT = "EditThemeCount"; //$NON-NLS-1$ + public static final String EXTRACT_THEME_COUNT = "ExtractThemeCount"; //$NON-NLS-1$ + public static final String CREATE_THEME_COUNT = "CreateThemeCount"; //$NON-NLS-1$ + public static final String USE_S_THEME_COUNT = "Use_%s_ThemeCount";//$NON-NLS-1$ + + /** Style */ + public static final String CREATE_STYLE_COUNT = "CreateStyleCount"; //$NON-NLS-1$ + public static final String FONT_CHANGE_ALL_COUNT = "FontChangeAllCount"; //$NON-NLS-1$ + public static final String EDIT_STYLE_COUNT = "EditStyleCount"; //$NON-NLS-1$ + public static final String EXTRACT_STYLE_COUNT = "ExtractStyleCount"; //$NON-NLS-1$ + + public static final String INSERT_RELATIONSHIP_COUNT = "InsertRelationshipCount"; //$NON-NLS-1$ + public static final String INSERT_CALLOUT_COUNT = "InsertCalloutCount"; //$NON-NLS-1$ + public static final String INSERT_BOUNDARY_COUNT = "InsertBoundaryCount"; //$NON-NLS-1$ + public static final String INSERT_SUMMARY_COUNT = "InsertSummaryCount"; //$NON-NLS-1$ + public static final String INSERT_LABEL_COUNT = "InsertLabelCount"; //$NON-NLS-1$ + + public static final String ADD_ATTACHMENT_COUNT = "AddAttachmentCount"; //$NON-NLS-1$ + public static final String ATTACHMENT_FORMAT_COUNT_BLANK_FORMAT = "AttachmentFormatCount:BlankFormat"; //$NON-NLS-1$ + public static final String ATTACHMENT_FORMAT_COUNT_S = "AttachmentFormatCount:%s"; //$NON-NLS-1$ + + /** Import */ + public static final String IMPORT_FROM_WORD_COUNT = "ImportFromWordCount"; //$NON-NLS-1$ + public static final String IMPORT_FROM_OPML_COUNT = "ImportFromOpmlCount"; //$NON-NLS-1$ + public static final String IMPORT_FROM_X_MIND2008_COUNT = "ImportFromXMind2008Count"; //$NON-NLS-1$ + public static final String IMPORT_FROM_FREE_MIND_COUNT = "ImportFromFreeMindCount"; //$NON-NLS-1$ + public static final String IMPORT_FROM_MIND_MANAGER_COUNT = "ImportFromMindManagerCount"; //$NON-NLS-1$ + public static final String IMPORT_FROM_LIGHTEN_COUNT = "ImportFromLightenCount"; //$NON-NLS-1$ + public static final String IMPORT_FROM_NOVA_COUNT = "ImportFromNovaCount"; //$NON-NLS-1$ + public static final String IMPORT_BUNDLE_COUNT = "ImportResourcesCount";//$NON-NLS-1$ + + /** Export */ + public static final String EXPORT_TO_WORD_COUNT = "ExportToWordCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_PDF_MAP_COUNT = "ExportToPDFMapCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_MIND_MANAGER_COUNT = "ExportToMindManagerCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_OPML_COUNT = "ExportToOPMLCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_TXT_COUNT = "ExportToTxtCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_ODP_COUNT = "ExportToODPCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_LIGHTEN_COUNT = "ExportToLightenCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_FREE_MIND_COUNT = "ExportToFreeMindCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_HTML_COUNT = "ExportToHtmlCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_IMAGE_COUNT = "ExportToImageCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_X_MIND2008_COUNT = "ExportToXMind2008Count"; //$NON-NLS-1$ + public static final String EXPORT_TO_CSV_COUNT = "ExportToCSVCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_EXCEL2007_COUNT = "ExportToExcel2007Count"; //$NON-NLS-1$ + public static final String EXPORT_TO_EXCEL_COUNT = "ExportToExcelCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_ODS_COUNT = "ExportToODSCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_RTF_COUNT = "ExportToRTFCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_WORD2007_COUNT = "ExportToWord2007Count"; //$NON-NLS-1$ + public static final String EXPORT_TO_PROJECT_COUNT = "ExportToProjectCount"; //$NON-NLS-1$ + public static final String EXPORT_TO_PDF2007_COUNT = "ExportToPDF2007Count"; //$NON-NLS-1$ + public static final String EXPORT_TO_PPT_COUNT = "ExportToPPTCount"; //$NON-NLS-1$ + public static final String EXPORT_GANTT_TO_PROJECT_COUNT = "ExportGanttToImageCount";//$NON-NLS-1$ + public static final String EXPORT_GANTT_TO_IMAGE_COUNT = "ExportGanttToImageCount"; //$NON-NLS-1$ + public static final String EXPORT_GANTT_TO_PDF_COUNT = "ExportGanttToPDFCount";//$NON-NLS-1$ + public static final String EXPORT_OUTLINE_TO_WORD_COUNT = "ExportOutlineToWordCount"; //$NON-NLS-1$ + public static final String EXPORT_OUTLINE_TO_PDF_COUNT = "ExportOutlineToPDFCount"; //$NON-NLS-1$ + public static final String EXPORT_OUTLINE_TO_TEXT_COUNT = "ExportOutlineToTextCount"; //$NON-NLS-1$ + + public static final String EXPORT_BUNDLE_COUNT = "ExportBundleCount"; //$NON-NLS-1$ + public static final String EXPORT_CLIP_ART_COUNT = "ExportClipArtCount"; //$NON-NLS-1$ + public static final String EXPORT_MARKER_COUNT = "ExportMarkerCount"; //$NON-NLS-1$ + public static final String EXPORT_THEME_COUNT = "ExportThemeCount"; //$NON-NLS-1$ + public static final String EXPORT_TEMPLATE_COUNT = "ExportTemplateCount"; //$NON-NLS-1$ + + /** ClipArts */ + public static final String DRAG_CLIP_ARTS_COUNT = "DragClipArtsCount"; //$NON-NLS-1$ + public static final String ADD_CLIP_ART_GROUP_COUNT = "AddClipArtGroupCount"; //$NON-NLS-1$ + public static final String ADD_CLIP_ARTS_TO_MAP_COUNT = "AddClipArtsToMapCount"; //$NON-NLS-1$ + public static final String ADD_CLIP_ARTS_TO_GROUP_COUNT = "AddClipArtsToGroupCount"; //$NON-NLS-1$ + public static final String SHOW_CLIP_ART_COUNT = "ShowClipArtCount"; //$NON-NLS-1$ + + /** Iconfinder */ + public static final String SHOW_ICONFINDER_COUNT = "ShowIconfinderCount"; //$NON-NLS-1$ + public static final String DOWNLOAD_ICON_COUNT = "DownloadIconCount"; //$NON-NLS-1$ + public static final String ICONFINDER_SHOW_SIZE_DIALOG_COUNT = "IconfinderShowSizeDialogCount"; //$NON-NLS-1$ + public static final String ICONFINDER_ICON_USE_COUNT = "Iconfinder/Icon/UseCount"; //$NON-NLS-1$ + public static final String ICONFINDER_S_SEARCH_COUNT = "Iconfinder/%s/SearchCount"; //$NON-NLS-1$ + + /** AudioNotes */ + public static final String INSERT_AUDIO_NOTES_COUNT = "InsertAudioNotesCount"; //$NON-NLS-1$ + public static final String AUDIO_NOTES_RECORD_COUNT = "AudioNotesRecordCount"; //$NON-NLS-1$ //unused + + /** TaskInfoPart */ + public static final String SHOW_TASK_INFO_PART_COUNT = "ShowTaskInfoPartCount"; //$NON-NLS-1$ + public static final String TASK_END_TIME = "TaskEndTime_"; //$NON-NLS-1$ + public static final String TASK_START_TIME = "TaskStartTime_"; //$NON-NLS-1$ + public static final String TASK_INFO_CLICK_CHECK_POINT_COUNT = "TaskInfoClickCheckPointCount"; //$NON-NLS-1$ + public static final String CHANGE_PREDECESSOR_COUNT = "ChangePredecessorCount"; //$NON-NLS-1$ + public static final String REMOVE_PREDECESSOR_COUNT = "RemovePredecessorCount"; //$NON-NLS-1$ + public static final String ADD_PREDECESSOR_COUNT = "AddPredecessorCount"; //$NON-NLS-1$ + public static final String ADD_ASSIGNEE_COUNT = "AddAssigneeCount"; //$NON-NLS-1$ + + //unused + public static final String SHOW_TASK_INFO_COUNT = "ShowTaskInfoCount"; //$NON-NLS-1$ + + /** MapShot */ + public static final String COPY_MAP_SHOT_COUNT = "CopyMapShotCount"; //$NON-NLS-1$ + public static final String SAVE_MAPSHOT_COUNT = "SaveMapshotCount"; //$NON-NLS-1$ + public static final String MAP_SHOT_COUNT = "MapShotCount"; //$NON-NLS-1$ + + /** Search */ + public static final String SEARCH_IN_WORKBOOKS_COUNT = "SearchInWorkbooksCount"; //$NON-NLS-1$ + public static final String SEARCH_IN_WEB_COUNT = "SearchInWebCount"; //$NON-NLS-1$ + + /** AdvancedFilter */ + public static final String SHOW_ADVANCED_FILTER_DIALOG_COUNT = "ShowAdvancedFilterDialogCount"; //$NON-NLS-1$ + public static final String FILTER_SHOW_ALL_COUNT = "FilterShowAllCount"; //$NON-NLS-1$ + public static final String FILTER_DARKER_COUNT = "FilterDarkerCount"; //$NON-NLS-1$ + + /** Gantt */ + public static final String SHOW_GANTT_DIALOG_COUNT = "ShowGanttDialogCount"; //$NON-NLS-1$ + public static final String GANTT_TIME_LINE_CHANGE_COUNT = "GanttTimeLineChangeCount"; //$NON-NLS-1$ + public static final String PRINT_GANTT_CHART_COUNT = "PrintGanttChartCount"; //$NON-NLS-1$ + + @Deprecated + public static final String SHOW_GANTT_CHART_COUNT = "ShowGanttChartCount"; //$NON-NLS-1$ + public static final String SHOW_INDEX_VIEW_COUNT = "ShowIndexViewCount"; //$NON-NLS-1$ + + /** Share */ + public static final String SHARE_TO_BLOG_COUNT = "ShareToBlogCount"; //$NON-NLS-1$ + public static final String SHARE_PRIVATE_LINK_COUNT = "SharePrivateLinkCount"; //$NON-NLS-1$ + public static final String SHARE_PUBLIC_LINK_COUNT = "SharePublicLinkCount"; //$NON-NLS-1$ + public static final String SHARE_TO_LINKED_IN_COUNT = "ShareToLinkedInCount"; //$NON-NLS-1$ + public static final String SHARE_TO_TWITTER_COUNT = "ShareToTwitterCount"; //$NON-NLS-1$ + public static final String SHARE_TO_FACEBOOK_COUNT = "ShareToFacebookCount"; //$NON-NLS-1$ + public static final String SHARE_TO_EMAIL_COUNT = "ShareToEmailCount"; //$NON-NLS-1$ + public static final String SHARE_TO_BIGGERPLATE_COUNT = "ShareToBiggerplateCount";//$NON-NLS-1$ + public static final String SHARE_TO_LOCAL_NETWORK_COUNT = "ShareToLocalNetworkCount";//$NON-NLS-1$ + public static final String SHARE_TO_EVERNOTE_COUNT = "ShareToEvernoteCount";//$NON-NLS-1$ + + /** BrainStorm */ + public static final String START_BRAINSTORM_COUNT = "StartBrainstormCount"; //$NON-NLS-1$ + + public static final String MERGE_MAPS_COUNT = "MergeMapsCount";//$NON-NLS-1$ + + public static final String SPELLING_CHECK_COUNT = "SpellingCheckCount"; //$NON-NLS-1$ +} diff --git a/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataSampler.java b/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataSampler.java index 582352ed2..666a7e8f2 100644 --- a/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataSampler.java +++ b/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataSampler.java @@ -1,119 +1,119 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.usagedata; - -/** - * This interface provides abilities to record usage data. - * - *

- * Usage data are recorded in the form of a collection of key-value pairs, where - * the key is a unique string defined by the feature being used. Keys may - * consist of sub-keys separated by slashes('/'). - *

- * - *

- * Features that wish to provide usage data should obtain a dedicated instance - * of this interface via OSGi's service tracker. See below for example. If no - * such instance is available, the default instance {@link #NULL} should be used - * instead to prevent {@link NullPointerException}. - * - *

- * public class MyBundleActivator implements BundleActivator {
- * 
- *     private ServiceTracker<IUsageDataSampler, IUsageDataSampler> usageDataService;
- * 
- *     public void start(BundleContext context) throws Exception {
- *         usageDataService = new ServiceTracker<IUsageDataSampler, IUsageDataSampler>(
- *                 context, IUsageDataSampler.class.getName(), null);
- *         usageDataService.open();
- *     }
- * 
- *     public void stop(BundleContext context) throws Exception {
- *         usageDataService.close();
- *         usageDataService = null;
- *     }
- * 
- *     public IUsageDataSampler getUsageDataSampler() {
- *         IUsageDataSampler sampler = usageDataService.get();
- *         return sampler == null ? IUsageDataSampler.NULL : sampler;
- *     }
- * }
- * 
- *

- * - * @author Frank Shaka - */ -public interface IUsageDataSampler { - - /** - * A singleton instance to do nothing on sampling. This helps ensure that - * sampling operations are always error-free no matter a dedicated sampling - * service exists or not. - */ - IUsageDataSampler NULL = new IUsageDataSampler() { - @Override - public void increase(String key) { - // do nothing - } - - @Override - public void put(String key, String value) { - // do nothing - } - - @Override - public void put(String key, long value) { - // do nothing - } - }; - - /** - * Increases the numeric value of a specified item by one. This method is - * useful when counting how many times a feature is triggered. - * - * @param key - * the key of the item, must NOT be null - * @throws IllegalArgumentException - * if the key is null - */ - void increase(String key); - - /** - * Put an item with the specified key and value directly into the item set. - * - * @param key - * the key of the item, must NOT be null - * @param value - * the value of the item, or null to delete the item - * @throws IllegalArgumentException - * if the key is null - */ - void put(String key, String value); - - /** - * Put an item with the specified key and value directly into the item set. - * - * @param key - * the key of the item, must NOT be null - * @param value - * the value of the item - * @throws IllegalArgumentException - * if the key is null - */ - void put(String key, long value); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.usagedata; + +/** + * This interface provides abilities to record usage data. + * + *

+ * Usage data are recorded in the form of a collection of key-value pairs, where + * the key is a unique string defined by the feature being used. Keys may + * consist of sub-keys separated by slashes('/'). + *

+ * + *

+ * Features that wish to provide usage data should obtain a dedicated instance + * of this interface via OSGi's service tracker. See below for example. If no + * such instance is available, the default instance {@link #NULL} should be used + * instead to prevent {@link NullPointerException}. + * + *

+ * public class MyBundleActivator implements BundleActivator {
+ * 
+ *     private ServiceTracker<IUsageDataSampler, IUsageDataSampler> usageDataService;
+ * 
+ *     public void start(BundleContext context) throws Exception {
+ *         usageDataService = new ServiceTracker<IUsageDataSampler, IUsageDataSampler>(
+ *                 context, IUsageDataSampler.class.getName(), null);
+ *         usageDataService.open();
+ *     }
+ * 
+ *     public void stop(BundleContext context) throws Exception {
+ *         usageDataService.close();
+ *         usageDataService = null;
+ *     }
+ * 
+ *     public IUsageDataSampler getUsageDataSampler() {
+ *         IUsageDataSampler sampler = usageDataService.get();
+ *         return sampler == null ? IUsageDataSampler.NULL : sampler;
+ *     }
+ * }
+ * 
+ *

+ * + * @author Frank Shaka + */ +public interface IUsageDataSampler { + + /** + * A singleton instance to do nothing on sampling. This helps ensure that + * sampling operations are always error-free no matter a dedicated sampling + * service exists or not. + */ + IUsageDataSampler NULL = new IUsageDataSampler() { + @Override + public void increase(String key) { + // do nothing + } + + @Override + public void put(String key, String value) { + // do nothing + } + + @Override + public void put(String key, long value) { + // do nothing + } + }; + + /** + * Increases the numeric value of a specified item by one. This method is + * useful when counting how many times a feature is triggered. + * + * @param key + * the key of the item, must NOT be null + * @throws IllegalArgumentException + * if the key is null + */ + void increase(String key); + + /** + * Put an item with the specified key and value directly into the item set. + * + * @param key + * the key of the item, must NOT be null + * @param value + * the value of the item, or null to delete the item + * @throws IllegalArgumentException + * if the key is null + */ + void put(String key, String value); + + /** + * Put an item with the specified key and value directly into the item set. + * + * @param key + * the key of the item, must NOT be null + * @param value + * the value of the item + * @throws IllegalArgumentException + * if the key is null + */ + void put(String key, long value); + +} diff --git a/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataUploader.java b/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataUploader.java index 5b685c674..67075f838 100644 --- a/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataUploader.java +++ b/bundles/org.xmind.core.usagedata/src/org/xmind/core/usagedata/IUsageDataUploader.java @@ -1,30 +1,30 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.usagedata; - -/** - * @author Frank Shaka - * @since 3.6.51 - */ -public interface IUsageDataUploader { - - /** - * - */ - void forceUpload(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.usagedata; + +/** + * @author Frank Shaka + * @since 3.6.51 + */ +public interface IUsageDataUploader { + + /** + * + */ + void forceUpload(); + +} diff --git a/bundles/org.xmind.core/.classpath b/bundles/org.xmind.core/.classpath index 9f1e795e8..b79a2e1ed 100644 --- a/bundles/org.xmind.core/.classpath +++ b/bundles/org.xmind.core/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.core/.gitignore b/bundles/org.xmind.core/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.core/.gitignore +++ b/bundles/org.xmind.core/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.core/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.core/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.core/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.core/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs index 49bffb015..f0f17d752 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs @@ -1,415 +1,415 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled -org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,NORMAL,HIGH -org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,ATTN,Release -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled +org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,NORMAL,HIGH +org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,ATTN,Release +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.core/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.core/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.core/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core/.settings/org.eclipse.jdt.ui.prefs index c1373536c..cf7cf1b4c 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.jdt.ui.prefs @@ -1,56 +1,56 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=false -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=false +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=true +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/bundles/org.xmind.core/META-INF/MANIFEST.MF b/bundles/org.xmind.core/META-INF/MANIFEST.MF index 9229606e4..c1450e37a 100644 --- a/bundles/org.xmind.core/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core/META-INF/MANIFEST.MF @@ -1,20 +1,20 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.core -Bundle-Version: 3.7.0.qualifier -Export-Package: org.xmind.core, - org.xmind.core.event, - org.xmind.core.internal;x-internal:=true, - org.xmind.core.internal.compatibility;x-internal:=true, - org.xmind.core.internal.dom;x-internal:=true, - org.xmind.core.internal.event;x-internal:=true, - org.xmind.core.internal.security;x-internal:=true, - org.xmind.core.internal.zip;x-internal:=true, - org.xmind.core.io, - org.xmind.core.marker, - org.xmind.core.style, - org.xmind.core.util -Bundle-Vendor: %providerName -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.core +Bundle-Version: 3.7.0.qualifier +Export-Package: org.xmind.core, + org.xmind.core.event, + org.xmind.core.internal;x-internal:=true, + org.xmind.core.internal.compatibility;x-internal:=true, + org.xmind.core.internal.dom;x-internal:=true, + org.xmind.core.internal.event;x-internal:=true, + org.xmind.core.internal.security;x-internal:=true, + org.xmind.core.internal.zip;x-internal:=true, + org.xmind.core.io, + org.xmind.core.marker, + org.xmind.core.style, + org.xmind.core.util +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-Localization: plugin diff --git a/bundles/org.xmind.core/about.html b/bundles/org.xmind.core/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.core/about.html +++ b/bundles/org.xmind.core/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.core/plugin.properties b/bundles/org.xmind.core/plugin.properties index b5c88e419..ae85b0ba3 100644 --- a/bundles/org.xmind.core/plugin.properties +++ b/bundles/org.xmind.core/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.core -providerName = XMind Ltd. +#Properties file for org.xmind.core +providerName = XMind Ltd. pluginName = XMind Core \ No newline at end of file diff --git a/bundles/org.xmind.core/pom.xml b/bundles/org.xmind.core/pom.xml index ba6fd0c6a..c71bee8e0 100644 --- a/bundles/org.xmind.core/pom.xml +++ b/bundles/org.xmind.core/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.core - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.core + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.core/src/org/xmind/core/Core.java b/bundles/org.xmind.core/src/org/xmind/core/Core.java index 7795b9f6d..0f661148a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/Core.java +++ b/bundles/org.xmind.core/src/org/xmind/core/Core.java @@ -1,1189 +1,1189 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.util.Comparator; -import java.util.UUID; - -import org.xmind.core.internal.InternalCore; -import org.xmind.core.marker.IMarkerSheetBuilder; -import org.xmind.core.style.IStyleSheetBuilder; -import org.xmind.core.util.ILogger; - -/** - * - * @author Frank Shaka - */ -@SuppressWarnings("deprecation") -public class Core { - - /** - * Core event type for modifying the title text (value is 'titleText'). - *
- *
Source:
- *
{@link org.xmind.core.ITitled}
- *
OldValue:
- *
the old title ({@link String}), or null indicating that - * the title was unspecified
- *
NewValue:
- *
the new title ({@link String}), or null indicating that - * the title is unspecified
- *
- * - * @see org.xmind.core.ITitled#getTitleText() - * @see org.xmind.core.ITitled#setTitleText(String) - */ - public static final String TitleText = "titleText"; //$NON-NLS-1$ - - /** - * Core event type for modifying a topic's title width (value is - * 'titleWidth'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
OldValue:
- *
the old width ({@link Integer}), or null indicating that - * the width was unspecified
- *
NewValue:
- *
the new width ({@link Integer}), or null indicating that - * the with is unspecified
- *
- * - * @see org.xmind.core.ITopic#getTitleWidth() - * @see org.xmind.core.ITopic#setTitleWidth(int) - */ - public static final String TitleWidth = "titleWidth"; //$NON-NLS-1$ - - /** - * Core event type for modifying the style id (value is 'style'). - *
- *
Source:
- *
{@link org.xmind.core.style.IStyled}
- *
OldValue:
- *
the old style's id ({@link String}), or null indicating - * that the style was unspecified
- *
NewValue:
- *
the new style's id ({@link String}), or null indicating - * that the style is unspecified
- *
- * - * @see org.xmind.core.style.IStyled#getStyleId() - * @see org.xmind.core.style.IStyled#setStyleId(String) - */ - public static final String Style = "style"; //$NON-NLS-1$ - - /** - * Core event type for folding/unfolding a topic (value is 'topicFolded'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
OldValue:
- *
the old folding state ({@link java.lang.Boolean})
- *
NewValue:
- *
the new folding state ({@link java.lang.Boolean})
- *
- * - * @see org.xmind.core.ITopic#isFolded() - * @see org.xmind.core.ITopic#setFolded(boolean) - */ - public static final String TopicFolded = "topicFolded"; //$NON-NLS-1$ - - /** - * Core event type for modifying an object's position (value is 'position'). - *
- *
Source:
- *
{@link org.xmind.core.IPositioned}
- *
OldValue:
- *
the old position ({@link org.xmind.core.util.Point}), or - * null indicating that the position was unspecified
- *
NewValue:
- *
the new position ({@link org.xmind.core.util.Point}), or - * null indicating that the position is unspecified
- *
- * - * @see org.xmind.core.IPositioned#getPosition() - * @see org.xmind.core.IPositioned#setPosition(org.xmind.core.util.Point) - * @see org.xmind.core.IPositioned#setPosition(int, int) - */ - public static final String Position = "position"; //$NON-NLS-1$ - - /** - * Core event type for modifying a topic's hyperlink reference (value is - * 'topicHyperlink'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
OldValue:
- *
the old hyperlink reference ({@link String}), or null - * indicating that the hyperlink was unspecified
- *
NewValue:
- *
the new hyperlink reference ({@link String}), or null - * indicating that the hyperlink is unspecified
- *
- * - * @see org.xmind.core.ITopic#getHyperlink() - * @see org.xmind.core.ITopic#setHyperlink(String) - */ - public static final String TopicHyperlink = "topicHyperlink"; //$NON-NLS-1$ - - /** - * Core event type for adding a subtopic to a topic (value is 'topicAdd'). - *
- *
Source:
- *
the parent {@link org.xmind.core.ITopic}
- *
Target:
- *
the child {@link org.xmind.core.ITopic}
- *
Index:
- *
the index of the added subtopic
- *
Data:
- *
the child topic's type ({@link String})
- *
- * - * @see org.xmind.core.ITopic#getType() - * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic) - * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic, String) - * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic, int, String) - */ - public static final String TopicAdd = "topicAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a subtopic from a topic (value is - * 'topicRemove'). - *
- *
Source:
- *
the parent {@link org.xmind.core.ITopic}
- *
Target:
- *
the child {@link org.xmind.core.ITopic}
- *
Index:
- *
the index of the removed subtopic
- *
Data:
- *
the child topic's type ({@link String})
- *
- * - * @see org.xmind.core.ITopic#remove(org.xmind.core.ITopic) - */ - public static final String TopicRemove = "topicRemove"; //$NON-NLS-1$ - - /** - * Core event type for adding a sheet to a workbook (value is 'sheetAdd'). - *
- *
Source:
- *
{@link org.xmind.core.IWorkbook}
- *
Target:
- *
the added {@link org.xmind.core.ISheet}
- *
Index:
- *
the index of the added sheet
- *
- * - * @see org.xmind.core.IWorkbook#addSheet(org.xmind.core.ISheet) - * @see org.xmind.core.IWorkbook#addSheet(org.xmind.core.ISheet, int) - */ - public static final String SheetAdd = "sheetAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a sheet from a workbook (value is - * 'sheetRemove'). - *
- *
Source:
- *
{@link org.xmind.core.IWorkbook}
- *
Target:
- *
the removed {@link org.xmind.core.ISheet}
- *
Index:
- *
the index of the removed sheet
- *
- * - * @see org.xmind.core.IWorkbook#removeSheet(org.xmind.core.ISheet) - */ - public static final String SheetRemove = "sheetRemove"; //$NON-NLS-1$ - - /** - * Core event type for moving a sheet to a different index within the owned - * workbook (value is 'sheetMove'). - *
- *
Source:
- *
{@link org.xmind.core.IWorkbook}
- *
Target:
- *
the moved {@link org.xmind.core.ISheet}
- *
Index:
- *
the old index of the moved sheet
- *
- * - * @see org.xmind.core.IWorkbook#moveSheet(int, int) - */ - public static final String SheetMove = "sheetMove"; //$NON-NLS-1$ - - /** - * Core event type for modifying one attribute of a sheet's settings (value - * is 'sheetSettings'). - *
- *
Source:
- *
{@link org.xmind.core.ISheet}
- *
Target:
- *
the attribute key ({@link String})
- *
Data:
- *
the entry path ({@link String})
- *
OldValue:
- *
the old attribute value ({@link String})
- *
NewValue:
- *
the new attribute value ({@link String})
- *
- * - * @see org.xmind.core.ISheetSettings - * @see org.xmind.core.ISheet#getSettings() - */ - public static final String SheetSettings = "sheetSettings"; //$NON-NLS-1$ - - /** - * Core event type for adding a relationship to a sheet (value is - * 'relationshipAdd'). - *
- *
Source:
- *
{@link org.xmind.core.ISheet}
- *
Target:
- *
the added {@link org.xmind.core.IRelationship}
- *
- * - * @see org.xmind.core.ISheet#addRelationship(org.xmind.core.IRelationship) - */ - public static final String RelationshipAdd = "relationshipAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a relationship from a sheet (value is - * 'relationshipRemove'). - *
- *
Source:
- *
{@link org.xmind.core.ISheet}
- *
Target:
- *
the removed {@link org.xmind.core.IRelationship}
- *
- * - * @see org.xmind.core.ISheet#removeRelationship(org.xmind.core.IRelationship) - */ - public static final String RelationshipRemove = "relationshipRemove"; //$NON-NLS-1$ - - /** - * Core event type for replacing the root topic of a sheet (value is - * 'rootTopic'). - *
- *
Source:
- *
{@link org.xmind.core.ISheet}
- *
OldValue:
- *
the old root {@link org.xmind.core.ITopic}
- *
NewValue:
- *
the new root {@link org.xmind.core.ITopic}
- *
- * - * @see org.xmind.core.ISheet#getRootTopic() - * @see org.xmind.core.ISheet#replaceRootTopic(ITopic) - */ - public static final String RootTopic = "rootTopic"; //$NON-NLS-1$ - -// /** -// * Core event type for modifying one control point on a relationship (value -// * is 'relationshipControlPoint'). -// *
-// *
Source:
-// *
{@link org.xmind.core.IRelationship}
-// *
Target:
-// *
the modified {@link org.xmind.core.IControlPoint}, or -// * null indicating that the control point is unspecified
-// *
Index:
-// *
the index of the modified control point
-// *
-// * -// * @see org.xmind.core.IRelationship#getControlPoint(int); -// * @see org.xmind.core.IRelationship#setControlPoint(int, double, double); -// * @see org.xmind.core.IRelationship#resetControlPoint(int); -// */ -// public static final String RelationshipControlPoint = "relationshipControlPoint"; //$NON-NLS-1$ - - /** - * Core event type for modifying the first end of a relationship (value is - * 'relationshipEnd1'). - *
- *
Source:
- *
{@link org.xmind.core.IRelationship}
- *
OldValue:
- *
the old first end's id ({@link String}), or null - * indicating that the first end was unspecified
- *
NewValue:
- *
the new first end's id ({@link String}), or null - * indicating that the first end is unspecified
- *
- * - * @see org.xmind.core.IRelationship#getEnd1() - * @see org.xmind.core.IRelationship#getEnd1Id() - * @see org.xmind.core.IRelationship#setEnd1Id(String) - */ - public static final String RelationshipEnd1 = "relationshipEnd1"; //$NON-NLS-1$ - - /** - * Core event type for modifying the second end of a relationship (value is - * 'relationshipEnd2'). - *
- *
Source:
- *
{@link org.xmind.core.IRelationship}
- *
OldValue:
- *
the old second end's id ({@link String}), or null - * indicating that the second end was unspecified
- *
NewValue:
- *
the new second end's id ({@link String}), or null - * indicating that the second end is unspecified
- *
- * - * @see org.xmind.core.IRelationship#getEnd2() - * @see org.xmind.core.IRelationship#getEnd2Id() - * @see org.xmind.core.IRelationship#setEnd2Id(String) - */ - public static final String RelationshipEnd2 = "relationshipEnd2"; //$NON-NLS-1$ - - /** - * Core event type for adding a marker to a marker group (value is - * 'markerAdd'). - *
- *
Source:
- *
{@link org.xmind.core.marker.IMarkerGroup}
- *
Target:
- *
the added {@link org.xmind.core.marker.IMarker}
- *
Index:
- *
the index of the added marker
- *
- * - * @see org.xmind.core.marker.IMarkerGroup#addMarker(org.xmind.core.marker.IMarker) - */ - public static final String MarkerAdd = "markerAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a marker from a marker group (value is - * 'markerRemove'). - *
- *
Source:
- *
{@link org.xmind.core.marker.IMarkerGroup}
- *
Target:
- *
the removed {@link org.xmind.core.marker.IMarker}
- *
Index:
- *
the index of the removed marker
- *
- * - * @see org.xmind.core.marker.IMarkerGroup#removeMarker(org.xmind.core.marker.IMarker) - */ - public static final String MarkerRemove = "markerRemove"; //$NON-NLS-1$ - - /** - * Core event type for adding a marker group to a marker sheet (value is - * 'markerGroupAdd'). - *
- *
Source:
- *
{@link org.xmind.core.marker.IMarkerSheet}
- *
Target:
- *
the added {@link org.xmind.core.marker.IMarkerGroup}
- *
Index:
- *
the index of the added marker group
- *
- * - * @see org.xmind.core.marker.IMarkerSheet#addMarkerGroup(org.xmind.core.marker.IMarkerGroup) - */ - public static final String MarkerGroupAdd = "markerGroupAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a marker group from a marker sheet (value is - * 'markerGroupRemove'). - *
- *
Source:
- *
{@link org.xmind.core.marker.IMarkerSheet}
- *
Target:
- *
the removed {@link org.xmind.core.marker.IMarkerGroup}
- *
Index:
- *
the index of the removed marker group
- *
- * - * @see org.xmind.core.marker.IMarkerSheet#removeMarkerGroup(org.xmind.core.marker.IMarkerGroup) - */ - public static final String MarkerGroupRemove = "markerGroupRemove"; //$NON-NLS-1$ - - /** - * Core event type for adding a marker to a topic (value is 'markerRefAdd'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the added marker's id ({@link String})
- *
- * - * @see org.xmind.core.ITopic#addMarker(String) - */ - public static final String MarkerRefAdd = "markerRefAdd"; //$NON-NLS-1$ - - /** - * Core event type for removong a marker from a topic (value is - * 'markerRefRemove'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the removed marker's id ({@link String})
- *
- * - * @see org.xmind.core.ITopic#removeMarker(String) - */ - public static final String MarkerRefRemove = "markerRefRemove"; //$NON-NLS-1$ - - /** - * Core event type for modifying the range of a Range object (value is - * 'range'). - *

- * An event of this type usually follows a 'startIndex' or 'endIndex' event. - *

- *
- *
Source:
- *
{@link org.xmind.core.IRange}
- *
OldValue:
- *
unspecified
- *
NewValue:
- *
unspecified
- *
- */ - public static final String Range = "range"; //$NON-NLS-1$; - - /** - * Core event type for modifying the starting index of a Range object (value - * is 'startIndex'). - *

- * NOTE: This event is always followed by a 'range' event as the - * range is modified. - *

- * - *
- *
Source:
- *
{@link org.xmind.core.IRange}
- *
OldValue:
- *
the old starting index ({@link Integer}) of the range, or - * null indicating that the index was unspecified
- *
NewValue:
- *
the new starting index ({@link Integer}) of the range, or - * null indicating that the index is unspecified
- *
- */ - public static final String StartIndex = "startIndex"; //$NON-NLS-1$ - - /** - * Core event type for modifying the ending index of a Range object (value - * is 'endIndex'). - *

- * NOTE: This event is always followed by a 'range' event as the - * range is modified. - *

- * - *
- *
Source:
- *
{@link org.xmind.core.IRange}
- *
OldValue:
- *
the old ending index ({@link Integer}) of the range, or - * null indicating that the index was unspecified
- *
NewValue:
- *
the new ending index ({@link Integer}) of the range, or - * null indicating that the index is unspecified
- *
- */ - public static final String EndIndex = "endIndex"; //$NON-NLS-1$ - - /** - * Core event type for adding a boundary to a topic (value is - * 'boundaryAdd'). - * - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the added {@link org.xmind.core.IBoundary}
- *
- */ - public static final String BoundaryAdd = "boundaryAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a boundary to a topic (value is - * 'boundaryRemove'). - * - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the removed {@link org.xmind.core.IBoundary}
- *
- */ - public static final String BoundaryRemove = "boundaryRemove"; //$NON-NLS-1$ - - /** - * Core event type for modifying the attached topic of a summary (value is - * 'topicRefId'). - *
- *
Source:
- *
{@link org.xmind.core.ISummary}
- *
OldValue:
- *
the old topic's id ({@link String})
- *
NewValue:
- *
the new topic's id ({@link String})
- *
- */ - public static final String TopicRefId = "topicRefId"; //$NON-NLS-1$ - - /** - * Core event type for adding a summary to a topic (value is 'summaryAdd'). - * - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the added {@link org.xmind.core.IBoundary}
- *
- */ - public static final String SummaryAdd = "summaryAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a summary to a topic (value is - * 'summaryRemove'). - * - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the removed {@link org.xmind.core.IBoundary}
- *
- */ - public static final String SummaryRemove = "summaryRemove"; //$NON-NLS-1$ - - /** - * Core event type for adding a style to a style sheet (value is - * 'styleAdd'). - * - *
- *
Source:
- *
{@link org.xmind.core.style.IStyleSheet}
- *
Target:
- *
the added {@link org.xmind.core.style.IStyle}
- *
- */ - public static final String StyleAdd = "styleAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a style from a style sheet (value is - * 'styleRemove'). - * - *
- *
Source:
- *
{@link org.xmind.core.style.IStyleSheet}
- *
Target:
- *
the removed {@link org.xmind.core.style.IStyle}
- *
- */ - public static final String StyleRemove = "styleRemove"; //$NON-NLS-1$ - - /** - * Core event type for modifying a the name (value is 'name). - *
- *
Source:
- *
{@link org.xmind.core.INamed}
- *
OldValue:
- *
the old name ({@link String}), or null indicating that - * the name was unspecified
- *
NewValue:
- *
the new name ({@link String}), or null indicating that - * the name is unspecified
- *
- */ - public static final String Name = "name"; //$NON-NLS-1$ - - /** - * Core event type for modifying a property (value is 'property'). - *
- *
Source:
- *
{@link org.xmind.core.IProperties}
- *
Target:
- *
the property name ({@link String})
- *
OldValue:
- *
the old property value ({@link String}), or null - * indicating that the property was unspecified
- *
NewValue:
- *
the new property value ({@link String}), or null - * indicating that the property is unspecified
- *
- */ - public static final String Property = "property"; //$NON-NLS-1$ - - /** - * Core event type for modifying a sheet's theme id (value is 'themeId'). - *
- *
Source:
- *
{@link org.xmind.core.ISheet}
- *
OldValue:
- *
the old theme id ({@link String}), or null indicating - * that the theme id was unspecified
- *
NewValue:
- *
the new theme id ({@link String}), or null indicating - * that the theme id is unspecified
- *
- */ - public static final String ThemeId = "themeId"; //$NON-NLS-1$ - - /** - * Core event type for modifying the structure class of a topic (value is - * 'structureClass'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
OldValue:
- *
the old structure class ({@link String}), or null - * indicating that the structure class was unspecified
- *
NewValue:
- *
the new structure class ({@link String}), or null - * indicating that the structure class is unspecified
- *
- */ - public static final String StructureClass = "structureClass"; //$NON-NLS-1$ - - /** - * Core event type for modifying the note content of a topic (value is - * 'topicNotes'). - *
- *
Source:
- *
{@link org.xmind.core.ITopic}
- *
Target:
- *
the note format (either {@link org.xmind.core.INotes#PLAIN} or - * {@link org.xmind.core.INotes#HTML})
- *
OldValue:
- *
the old notes content ({@link org.xmind.core.INotesContent}), or - * null indicating that the note content was unspecified
- *
NewValue:
- *
the new notes content ({@link org.xmind.core.INotesContent}), or - * null indicating that the note content is unspecified
- *
- * - * @see org.xmind.core.INotes#PLAIN - * @see org.xmind.core.INotes#HTML - * @see org.xmind.core.INotes#getContent(String) - * @see org.xmind.core.INotes#setContent(String, INotesContent) - */ - public static final String TopicNotes = "topicNotes"; //$NON-NLS-1$ - - /** - * Core event type for modifying the labels (value is 'labels'). - *
- *
Source:
- *
{@link org.xmind.core.ILabeled}
- *
OldValue:
- *
a {@link java.util.Set} of String containing all the old - * labels (may be empty, but is never null)
- *
NewValue:
- *
a {@link java.util.Set} of String containing all the new - * labels (may be empty, but is never null)
- *
- */ - public static final String Labels = "labels"; //$NON-NLS-1$ - - /** - * Core event type for changes of the resource references (value is - * 'resourceRefs'). - *
- *
Source:
- *
{@link org.xmind.core.util.IRefCounter}
- *
OldValue:
- *
a {@link java.util.Collection} of String containing all - * the old resource references (may be empty, but is never null)
- *
NewValue:
- *
a {@link java.util.Collection} of String containing all - * the new resource references (may be empty, but is never null)
- *
- */ - public static final String ResourceRefs = "resourceRefs"; //$NON-NLS-1$ - - /** - * Core event type for modifying the source url of an image (value is - * 'imageSource'). - *
- *
Source:
- *
{@link org.xmind.core.IImage}
- *
OldValue:
- *
the old source url of the image ({@link String}), or - * null indicating that the source url was unspecified
- *
NewValue:
- *
the new source url of the image ({@link String}), or - * null indicating that the source url is unspecified
- *
- */ - public static final String ImageSource = "imageSource"; //$NON-NLS-1$ - - /** - * Core event type for modifying the width of an image (value is - * 'imageWidth'). - *
- *
Source:
- *
{@link org.xmind.core.IImage}
- *
OldValue:
- *
the old width of the image ({@link Integer}), or null - * indicating that the width was unspecified
- *
NewValue:
- *
the new width of the image ({@link String}), or null - * indicating that the width is unspecified
- *
- */ - public static final String ImageWidth = "imageWidth"; //$NON-NLS-1$ - - /** - * Core event type for modifying the height of an image (value is - * 'imageHeight'). - *
- *
Source:
- *
{@link org.xmind.core.IImage}
- *
OldValue:
- *
the old height of the image ({@link Integer}), or null - * indicating that the height was unspecified
- *
NewValue:
- *
the new height of the image ({@link String}), or null - * indicating that the height is unspecified
- *
- */ - public static final String ImageHeight = "imageHeight"; //$NON-NLS-1$ - - /** - * Core event type for modifying the alignment of an image (value is - * 'imageAlignment'). - *
- *
Source:
- *
{@link org.xmind.core.IImage}
- *
OldValue:
- *
the old alignment of the image ({@link Integer}), or - * null indicating that the alignment was unspecified
- *
NewValue:
- *
the new alignment of the image ({@link String}), or null - * indicating that the alignment is unspecified
- *
- */ - public static final String ImageAlignment = "imageAlignment"; //$NON-NLS-1$ - - /** - * Core event type for modifying the visiblity of a legend (value is - * 'visibility'). - *
- *
Source:
- *
{@link org.xmind.core.ILegend}
- *
OldValue:
- *
the old visibility ({@link Boolean})
- *
NewValue:
- *
the new visibility ({@link Boolean})
- *
- */ - public static final String Visibility = "visibility"; //$NON-NLS-1$ - - /** - * Core event type for modifying the description of a marker on a sheet - * (value is 'markerDescription'). - *
- *
Source:
- *
{@link org.xmind.core.ILegend}
- *
Target:
- *
the marker's id ({@link String})
- *
OldValue:
- *
the old description ({@link String}) of the target marker, or - * null indicating that the description was unspecified
- *
NewValue:
- *
the new description ({@link String}) of the target marker, or - * null indicating that the description is unspecified
- *
- */ - public static final String MarkerDescription = "markerDescription"; //$NON-NLS-1$ - - public static final String NumberFormat = "numberingFormat"; //$NON-NLS-1$ - - public static final String NumberingPrefix = "numberingPrefix"; //$NON-NLS-1$ - - public static final String NumberingSuffix = "numberingSuffix"; //$NON-NLS-1$ - - public static final String NumberPrepending = "parentNumberingPrepending"; //$NON-NLS-1$ - - public static final String NumberingSeparator = "numberingSeparator"; //$NON-NLS-1$ - - public static final String NumberingDepth = "numberingDepth"; //$NON-NLS-1$ - - /** - * Core event type for changing the password of a workbook (value is - * 'passwordChange'). - *
- *
Source:
- *
{@link org.xmind.core.IWorkboook}
- *
- */ - public static final String PasswordChange = "passwordChange"; //$NON-NLS-1$ - - /** - * Core event type for going to save a workbook (value is - * 'workbookPreSave'). This type of events is dispatched before a workbook - * is saved. Listening to this type of events allows modification to the - * workbook content before saving it to the destination. The most common - * usage is to save preview pictures by the UI, for we can't generate a - * preview picture without a graphical environment. - * - *
- *
Source:
- *
{@link org.xmind.core.IWorkboook}
- *
- * - * @see org.xmind.core.IWorkbook#save() - * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) - * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) - * @see org.xmind.core.IWorkbook#save(String) - */ - public static final String WorkbookPreSave = "workbookPreSave"; //$NON-NLS-1$ - - /** - * Core event type for going to save a workbook (value is - * 'workbookPreSaveOnce'). Similar to {@link #WorkbookPreSave}, but - * listeners to this type events are notified only once and removed from the - * event list thereafter. This type of events are commonly used when some - * pending work that may modify the content of a workbook should be counted - * before saving the workbook. - * - *
- *
Source:
- *
{@link org.xmind.core.IWorkboook}
- *
- * - * @see org.xmind.core.IWorkbook#save() - * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) - * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) - * @see org.xmind.core.IWorkbook#save(String) - */ - public static final String WorkbookPreSaveOnce = "workbookPreSaveOnce"; //$NON-NLS-1$ - - /** - * Core event type for having saved a workbook (value is 'workbookSave'). - * This type of events is dispatched after a workbook is saved. - * - *
- *
Source:
- *
{@link org.xmind.core.IWorkboook}
- *
- *
- * - * @see org.xmind.core.IWorkbook#save() - * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) - * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) - * @see org.xmind.core.IWorkbook#save(String) - */ - public static final String WorkbookSave = "workbookSave"; //$NON-NLS-1$ - - /** - * Core event for updating the modified time of an element (value is - * 'modifyTime'). When this event is dispatched, all other modification info - * has been updated such as - * {@link org.xmind.core.IModifiable#getModifiedBy()}. - * - *
- *
Source:
- *
a {@link org.xmind.core.IModifiable} object
- *
OldValue:
- *
the old modified time (long)
- *
NewValue:
- *
the new modified time (long)
- *
- * - * @see org.xmind.core.IModifiable - */ - public static final String ModifyTime = "modifyTime"; //$NON-NLS-1$ - - /** - * Core event type for adding a revision to the revision manager (value is - * 'revisionAdd'). - * - *
- *
Source:
- *
the parent {@link org.xmind.core.IRevisionManager}
- *
Target:
- *
the child {@link org.xmind.core.IRevision}
- *
Data:
- *
Corresponding resource ID (String)
- *
- * - * @see org.xmind.core.IRevisionManager#addRevision(IAdaptable) - */ - public static final String RevisionAdd = "revisionAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a revision from the revision manager (value - * is 'revisionRemove'). - * - *
- *
Source:
- *
the parent {@link org.xmind.core.IRevisionManager}
- *
Target:
- *
the child {@link org.xmind.core.IRevision}
- *
Data:
- *
Corresponding resource ID (String)
- *
- * - * @see org.xmind.core.IRevisionManager#removeRevision(IRevision) - */ - public static final String RevisionRemove = "revisionRemove"; //$NON-NLS-1$ - - /** - * Core event type for value change in {@link org.xmind.core.IMeta} (value - * is 'metadata'). - * - *
- *
Source:
- *
{@link org.xmind.core.IMeta}
- *
Target:
- *
a {@link String} representing the key path of the modified metadata - *
- *
OldValue:
- *
the old {@link String} value of the metadata, or null to - * indicate this metadata was created
- *
NewValue:
- *
the new {@link String} value of the metadata, or null to - * indicate this metadata was deleted
- *
- * - * @see org.xmind.core.IMeta#setValue(String, String) - * @see org.xmind.core.IMetaData#setValue(String) - */ - public static final String Metadata = "metadata"; //$NON-NLS-1$ - - /** - * Core event type for attribute change in {@link org.xmind.core.IMetaData} - * (value is 'metadataAttribute'). - * - *
- *
Source:
- *
{@link org.xmind.core.IMeta}
- *
Target:
- *
a {@link String} representing the key of the modified metadata
- *
Data:
- *
a {@link String} representing the name of the modified attribute
- *
OldValue:
- *
the old {@link String} value of the attribute, or null - * to indicate this attribute was added
- *
NewValue:
- *
the new {@link String} value of the attribute, or null - * to indicate this attribute was removed
- * - * @deprecated Not used any more. {@link #Metadata} is enough. - * - * @see org.xmind.core.IMetaData#setAttribute(String, String) - */ - public static final String MetadataAttribute = "metadataAttribute"; //$NON-NLS-1$ - - /** - * Core event type for adding a file entry to the owned manifest (value is - * 'fileEntryAdd'). A file entry is automatically added to the owned - * manifest once its reference count is increased from 0 to 1. - *
- *
Source:
- *
the {@link org.xmind.core.IManifest}
- *
Target:
- *
the {@link org.xmind.core.IFileEntry}
- *
- * - * @see org.xmind.core.IFileEntry#increaseReference() - */ - public static final String FileEntryAdd = "fileEntryAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a file entry from the owned manifest (value - * is 'fileEntryRemove'). A file entry is automatically removed from the - * owned manifest once its reference count is decreased from 1 to 0. - *
- *
Source:
- *
the {@link org.xmind.core.IManifest}
- *
Target:
- *
the {@link org.xmind.core.IFileEntry}
- *
- * - * @see org.xmind.core.IFileEntry#decreaseReference() - */ - public static final String FileEntryRemove = "fileEntryRemove"; //$NON-NLS-1$ - - /** - * Core event type for adding a comment to its associated object (value is - * 'commentAdd'). - * - *
- *
Source:
- *
the associated object that implements {@link org.xmind.core.ITitled}, - * e.g. {@link org.xmind.core.ITopic} or {@link org.xmind.core.ISheet}
- *
Target:
- *
the {@link org.xmind.core.IComment}
- *
- * - * @see org.xmind.core.ICommentManager#addComment(IComment) - */ - public static final String CommentAdd = "commentAdd"; //$NON-NLS-1$ - - /** - * Core event type for removing a comment from its associated object (value - * is 'commentRemove'). - * - *
- *
Source:
- *
the associated object that implements {@link org.xmind.core.ITitled}, - * e.g. {@link org.xmind.core.ITopic} or {@link org.xmind.core.ISheet}
- *
Target:
- *
the {@link org.xmind.core.IComment}
- *
- * - * @see org.xmind.core.ICommentManager#removeComment(IComment) - */ - public static final String CommentRemove = "commentRemove"; //$NON-NLS-1$ - - /** - * Core event type for modifying the content of a comment (value is - * 'commentContent'). - * - *
- *
Source:
- *
the {@link org.xmind.core.IComment}
- *
OldValue:
- *
the old text content ({@link String}), or null if there - * was no content before modifying
- *
NewValue:
- *
the new text content ({@link String}), or null if there - * is no content after modifying
- *
- */ - public static final String CommentContent = "commentContent"; //$NON-NLS-1$ - - /** - * Error constants indicating that an unknown error occurs (value=1). - */ - public static final int ERROR_UNKNOWN = 1; - - /** - * Error constants indicating that a null argument is passed in (value=2). - */ - public static final int ERROR_NULL_ARGUMENT = 2; - - /** - * Error constants indicating that an invalid argument is passed in - * (value=3). - */ - public static final int ERROR_INVALID_ARGUMENT = 3; - - public static final int ERROR_INVALID_FILE = 10; - - public static final int ERROR_NO_SUCH_ENTRY = 11; - - public static final int ERROR_FAIL_ACCESS_XML_PARSER = 12; - - public static final int ERROR_SYNTAX = 13; - public static final int ERROR_FAIL_PARSING_XML = ERROR_SYNTAX; - - public static final int ERROR_NO_WORKBOOK_CONTENT = 14; - - public static final int ERROR_FAIL_ACCESS_XML_TRANSFORMER = 15; - - public static final int ERROR_FAIL_INIT_CRYPTOGRAM = 16; - - public static final int ERROR_WRONG_PASSWORD = 17; - - public static final int ERROR_FAIL_SERIALIZING_XML = 18; - - public static final int ERROR_CANCELLATION = 100; - - /** - * Media type for a textual file (value='text/xml'). - * - * @see org.xmind.core.IFileEntry#getMediaType() - */ - public static final String MEDIA_TYPE_TEXT_XML = "text/xml"; //$NON-NLS-1$ - - /** - * Media type for an image file (value='image/png'). - * - * @see org.xmind.core.IFileEntry#getMediaType() - */ - public static final String MEDIA_TYPE_IMAGE_PNG = "image/png"; //$NON-NLS-1$ - - @Deprecated - public static final String TopicComments = "topicComments"; //$NON-NLS-1$ - - private Core() { - throw new AssertionError("Instantiation of this class is not allowed!"); //$NON-NLS-1$ - } - - /** - * - *

- * WARNING: This is a legacy mechanism to generate unique - * identifiers. Clients should use {@link UUID} instead for higher - * uniqueness. - *

- * - * @return an {@link IIdFactory} that generates unique identifiers - */ - public static IIdFactory getIdFactory() { - return getInternal().getIdFactory(); - } - - /** - * - *

- * WARNING: The workbook builder no longer supports loading - * workbooks. Use - * Core.getSerializationProvider().newDeserializer() for this - * kind of tasks. - *

- * - * @return an {@link IWorkbookBuilder} that is capable for creating workbook - * instances - */ - public static IWorkbookBuilder getWorkbookBuilder() { - return getInternal().getWorkbookBuilder(); - } - - public static IWorkspace getWorkspace() { - return getInternal().getWorkspace(); - } - - public static Comparator getTopicComparator() { - return getInternal().getTopicComparator(); - } - - public static IMarkerSheetBuilder getMarkerSheetBuilder() { - return getInternal().getMarkerSheetBuilder(); - } - - public static IStyleSheetBuilder getStyleSheetBuilder() { - return getInternal().getStyleSheetBuilder(); - } - - public static final String getCurrentVersion() { - return getInternal().getCurrentVersion(); - } - - public static final boolean isPartiallyCompatible(String version) { - return getInternal().isPartiallyCompatible(version); - } - - /** - * NOTE: For internal use only. Not a public API. - * - * @return the default error logger - */ - public static final ILogger getLogger() { - return getInternal().getLogger(); - } - - private static InternalCore getInternal() { - return InternalCore.getInstance(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.util.Comparator; +import java.util.UUID; + +import org.xmind.core.internal.InternalCore; +import org.xmind.core.marker.IMarkerSheetBuilder; +import org.xmind.core.style.IStyleSheetBuilder; +import org.xmind.core.util.ILogger; + +/** + * + * @author Frank Shaka + */ +@SuppressWarnings("deprecation") +public class Core { + + /** + * Core event type for modifying the title text (value is 'titleText'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITitled}
+ *
OldValue:
+ *
the old title ({@link String}), or null indicating that + * the title was unspecified
+ *
NewValue:
+ *
the new title ({@link String}), or null indicating that + * the title is unspecified
+ *
+ * + * @see org.xmind.core.ITitled#getTitleText() + * @see org.xmind.core.ITitled#setTitleText(String) + */ + public static final String TitleText = "titleText"; //$NON-NLS-1$ + + /** + * Core event type for modifying a topic's title width (value is + * 'titleWidth'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
OldValue:
+ *
the old width ({@link Integer}), or null indicating that + * the width was unspecified
+ *
NewValue:
+ *
the new width ({@link Integer}), or null indicating that + * the with is unspecified
+ *
+ * + * @see org.xmind.core.ITopic#getTitleWidth() + * @see org.xmind.core.ITopic#setTitleWidth(int) + */ + public static final String TitleWidth = "titleWidth"; //$NON-NLS-1$ + + /** + * Core event type for modifying the style id (value is 'style'). + *
+ *
Source:
+ *
{@link org.xmind.core.style.IStyled}
+ *
OldValue:
+ *
the old style's id ({@link String}), or null indicating + * that the style was unspecified
+ *
NewValue:
+ *
the new style's id ({@link String}), or null indicating + * that the style is unspecified
+ *
+ * + * @see org.xmind.core.style.IStyled#getStyleId() + * @see org.xmind.core.style.IStyled#setStyleId(String) + */ + public static final String Style = "style"; //$NON-NLS-1$ + + /** + * Core event type for folding/unfolding a topic (value is 'topicFolded'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
OldValue:
+ *
the old folding state ({@link java.lang.Boolean})
+ *
NewValue:
+ *
the new folding state ({@link java.lang.Boolean})
+ *
+ * + * @see org.xmind.core.ITopic#isFolded() + * @see org.xmind.core.ITopic#setFolded(boolean) + */ + public static final String TopicFolded = "topicFolded"; //$NON-NLS-1$ + + /** + * Core event type for modifying an object's position (value is 'position'). + *
+ *
Source:
+ *
{@link org.xmind.core.IPositioned}
+ *
OldValue:
+ *
the old position ({@link org.xmind.core.util.Point}), or + * null indicating that the position was unspecified
+ *
NewValue:
+ *
the new position ({@link org.xmind.core.util.Point}), or + * null indicating that the position is unspecified
+ *
+ * + * @see org.xmind.core.IPositioned#getPosition() + * @see org.xmind.core.IPositioned#setPosition(org.xmind.core.util.Point) + * @see org.xmind.core.IPositioned#setPosition(int, int) + */ + public static final String Position = "position"; //$NON-NLS-1$ + + /** + * Core event type for modifying a topic's hyperlink reference (value is + * 'topicHyperlink'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
OldValue:
+ *
the old hyperlink reference ({@link String}), or null + * indicating that the hyperlink was unspecified
+ *
NewValue:
+ *
the new hyperlink reference ({@link String}), or null + * indicating that the hyperlink is unspecified
+ *
+ * + * @see org.xmind.core.ITopic#getHyperlink() + * @see org.xmind.core.ITopic#setHyperlink(String) + */ + public static final String TopicHyperlink = "topicHyperlink"; //$NON-NLS-1$ + + /** + * Core event type for adding a subtopic to a topic (value is 'topicAdd'). + *
+ *
Source:
+ *
the parent {@link org.xmind.core.ITopic}
+ *
Target:
+ *
the child {@link org.xmind.core.ITopic}
+ *
Index:
+ *
the index of the added subtopic
+ *
Data:
+ *
the child topic's type ({@link String})
+ *
+ * + * @see org.xmind.core.ITopic#getType() + * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic) + * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic, String) + * @see org.xmind.core.ITopic#add(org.xmind.core.ITopic, int, String) + */ + public static final String TopicAdd = "topicAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a subtopic from a topic (value is + * 'topicRemove'). + *
+ *
Source:
+ *
the parent {@link org.xmind.core.ITopic}
+ *
Target:
+ *
the child {@link org.xmind.core.ITopic}
+ *
Index:
+ *
the index of the removed subtopic
+ *
Data:
+ *
the child topic's type ({@link String})
+ *
+ * + * @see org.xmind.core.ITopic#remove(org.xmind.core.ITopic) + */ + public static final String TopicRemove = "topicRemove"; //$NON-NLS-1$ + + /** + * Core event type for adding a sheet to a workbook (value is 'sheetAdd'). + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkbook}
+ *
Target:
+ *
the added {@link org.xmind.core.ISheet}
+ *
Index:
+ *
the index of the added sheet
+ *
+ * + * @see org.xmind.core.IWorkbook#addSheet(org.xmind.core.ISheet) + * @see org.xmind.core.IWorkbook#addSheet(org.xmind.core.ISheet, int) + */ + public static final String SheetAdd = "sheetAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a sheet from a workbook (value is + * 'sheetRemove'). + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkbook}
+ *
Target:
+ *
the removed {@link org.xmind.core.ISheet}
+ *
Index:
+ *
the index of the removed sheet
+ *
+ * + * @see org.xmind.core.IWorkbook#removeSheet(org.xmind.core.ISheet) + */ + public static final String SheetRemove = "sheetRemove"; //$NON-NLS-1$ + + /** + * Core event type for moving a sheet to a different index within the owned + * workbook (value is 'sheetMove'). + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkbook}
+ *
Target:
+ *
the moved {@link org.xmind.core.ISheet}
+ *
Index:
+ *
the old index of the moved sheet
+ *
+ * + * @see org.xmind.core.IWorkbook#moveSheet(int, int) + */ + public static final String SheetMove = "sheetMove"; //$NON-NLS-1$ + + /** + * Core event type for modifying one attribute of a sheet's settings (value + * is 'sheetSettings'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISheet}
+ *
Target:
+ *
the attribute key ({@link String})
+ *
Data:
+ *
the entry path ({@link String})
+ *
OldValue:
+ *
the old attribute value ({@link String})
+ *
NewValue:
+ *
the new attribute value ({@link String})
+ *
+ * + * @see org.xmind.core.ISheetSettings + * @see org.xmind.core.ISheet#getSettings() + */ + public static final String SheetSettings = "sheetSettings"; //$NON-NLS-1$ + + /** + * Core event type for adding a relationship to a sheet (value is + * 'relationshipAdd'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISheet}
+ *
Target:
+ *
the added {@link org.xmind.core.IRelationship}
+ *
+ * + * @see org.xmind.core.ISheet#addRelationship(org.xmind.core.IRelationship) + */ + public static final String RelationshipAdd = "relationshipAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a relationship from a sheet (value is + * 'relationshipRemove'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISheet}
+ *
Target:
+ *
the removed {@link org.xmind.core.IRelationship}
+ *
+ * + * @see org.xmind.core.ISheet#removeRelationship(org.xmind.core.IRelationship) + */ + public static final String RelationshipRemove = "relationshipRemove"; //$NON-NLS-1$ + + /** + * Core event type for replacing the root topic of a sheet (value is + * 'rootTopic'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISheet}
+ *
OldValue:
+ *
the old root {@link org.xmind.core.ITopic}
+ *
NewValue:
+ *
the new root {@link org.xmind.core.ITopic}
+ *
+ * + * @see org.xmind.core.ISheet#getRootTopic() + * @see org.xmind.core.ISheet#replaceRootTopic(ITopic) + */ + public static final String RootTopic = "rootTopic"; //$NON-NLS-1$ + +// /** +// * Core event type for modifying one control point on a relationship (value +// * is 'relationshipControlPoint'). +// *
+// *
Source:
+// *
{@link org.xmind.core.IRelationship}
+// *
Target:
+// *
the modified {@link org.xmind.core.IControlPoint}, or +// * null indicating that the control point is unspecified
+// *
Index:
+// *
the index of the modified control point
+// *
+// * +// * @see org.xmind.core.IRelationship#getControlPoint(int); +// * @see org.xmind.core.IRelationship#setControlPoint(int, double, double); +// * @see org.xmind.core.IRelationship#resetControlPoint(int); +// */ +// public static final String RelationshipControlPoint = "relationshipControlPoint"; //$NON-NLS-1$ + + /** + * Core event type for modifying the first end of a relationship (value is + * 'relationshipEnd1'). + *
+ *
Source:
+ *
{@link org.xmind.core.IRelationship}
+ *
OldValue:
+ *
the old first end's id ({@link String}), or null + * indicating that the first end was unspecified
+ *
NewValue:
+ *
the new first end's id ({@link String}), or null + * indicating that the first end is unspecified
+ *
+ * + * @see org.xmind.core.IRelationship#getEnd1() + * @see org.xmind.core.IRelationship#getEnd1Id() + * @see org.xmind.core.IRelationship#setEnd1Id(String) + */ + public static final String RelationshipEnd1 = "relationshipEnd1"; //$NON-NLS-1$ + + /** + * Core event type for modifying the second end of a relationship (value is + * 'relationshipEnd2'). + *
+ *
Source:
+ *
{@link org.xmind.core.IRelationship}
+ *
OldValue:
+ *
the old second end's id ({@link String}), or null + * indicating that the second end was unspecified
+ *
NewValue:
+ *
the new second end's id ({@link String}), or null + * indicating that the second end is unspecified
+ *
+ * + * @see org.xmind.core.IRelationship#getEnd2() + * @see org.xmind.core.IRelationship#getEnd2Id() + * @see org.xmind.core.IRelationship#setEnd2Id(String) + */ + public static final String RelationshipEnd2 = "relationshipEnd2"; //$NON-NLS-1$ + + /** + * Core event type for adding a marker to a marker group (value is + * 'markerAdd'). + *
+ *
Source:
+ *
{@link org.xmind.core.marker.IMarkerGroup}
+ *
Target:
+ *
the added {@link org.xmind.core.marker.IMarker}
+ *
Index:
+ *
the index of the added marker
+ *
+ * + * @see org.xmind.core.marker.IMarkerGroup#addMarker(org.xmind.core.marker.IMarker) + */ + public static final String MarkerAdd = "markerAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a marker from a marker group (value is + * 'markerRemove'). + *
+ *
Source:
+ *
{@link org.xmind.core.marker.IMarkerGroup}
+ *
Target:
+ *
the removed {@link org.xmind.core.marker.IMarker}
+ *
Index:
+ *
the index of the removed marker
+ *
+ * + * @see org.xmind.core.marker.IMarkerGroup#removeMarker(org.xmind.core.marker.IMarker) + */ + public static final String MarkerRemove = "markerRemove"; //$NON-NLS-1$ + + /** + * Core event type for adding a marker group to a marker sheet (value is + * 'markerGroupAdd'). + *
+ *
Source:
+ *
{@link org.xmind.core.marker.IMarkerSheet}
+ *
Target:
+ *
the added {@link org.xmind.core.marker.IMarkerGroup}
+ *
Index:
+ *
the index of the added marker group
+ *
+ * + * @see org.xmind.core.marker.IMarkerSheet#addMarkerGroup(org.xmind.core.marker.IMarkerGroup) + */ + public static final String MarkerGroupAdd = "markerGroupAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a marker group from a marker sheet (value is + * 'markerGroupRemove'). + *
+ *
Source:
+ *
{@link org.xmind.core.marker.IMarkerSheet}
+ *
Target:
+ *
the removed {@link org.xmind.core.marker.IMarkerGroup}
+ *
Index:
+ *
the index of the removed marker group
+ *
+ * + * @see org.xmind.core.marker.IMarkerSheet#removeMarkerGroup(org.xmind.core.marker.IMarkerGroup) + */ + public static final String MarkerGroupRemove = "markerGroupRemove"; //$NON-NLS-1$ + + /** + * Core event type for adding a marker to a topic (value is 'markerRefAdd'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the added marker's id ({@link String})
+ *
+ * + * @see org.xmind.core.ITopic#addMarker(String) + */ + public static final String MarkerRefAdd = "markerRefAdd"; //$NON-NLS-1$ + + /** + * Core event type for removong a marker from a topic (value is + * 'markerRefRemove'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the removed marker's id ({@link String})
+ *
+ * + * @see org.xmind.core.ITopic#removeMarker(String) + */ + public static final String MarkerRefRemove = "markerRefRemove"; //$NON-NLS-1$ + + /** + * Core event type for modifying the range of a Range object (value is + * 'range'). + *

+ * An event of this type usually follows a 'startIndex' or 'endIndex' event. + *

+ *
+ *
Source:
+ *
{@link org.xmind.core.IRange}
+ *
OldValue:
+ *
unspecified
+ *
NewValue:
+ *
unspecified
+ *
+ */ + public static final String Range = "range"; //$NON-NLS-1$; + + /** + * Core event type for modifying the starting index of a Range object (value + * is 'startIndex'). + *

+ * NOTE: This event is always followed by a 'range' event as the + * range is modified. + *

+ * + *
+ *
Source:
+ *
{@link org.xmind.core.IRange}
+ *
OldValue:
+ *
the old starting index ({@link Integer}) of the range, or + * null indicating that the index was unspecified
+ *
NewValue:
+ *
the new starting index ({@link Integer}) of the range, or + * null indicating that the index is unspecified
+ *
+ */ + public static final String StartIndex = "startIndex"; //$NON-NLS-1$ + + /** + * Core event type for modifying the ending index of a Range object (value + * is 'endIndex'). + *

+ * NOTE: This event is always followed by a 'range' event as the + * range is modified. + *

+ * + *
+ *
Source:
+ *
{@link org.xmind.core.IRange}
+ *
OldValue:
+ *
the old ending index ({@link Integer}) of the range, or + * null indicating that the index was unspecified
+ *
NewValue:
+ *
the new ending index ({@link Integer}) of the range, or + * null indicating that the index is unspecified
+ *
+ */ + public static final String EndIndex = "endIndex"; //$NON-NLS-1$ + + /** + * Core event type for adding a boundary to a topic (value is + * 'boundaryAdd'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the added {@link org.xmind.core.IBoundary}
+ *
+ */ + public static final String BoundaryAdd = "boundaryAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a boundary to a topic (value is + * 'boundaryRemove'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the removed {@link org.xmind.core.IBoundary}
+ *
+ */ + public static final String BoundaryRemove = "boundaryRemove"; //$NON-NLS-1$ + + /** + * Core event type for modifying the attached topic of a summary (value is + * 'topicRefId'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISummary}
+ *
OldValue:
+ *
the old topic's id ({@link String})
+ *
NewValue:
+ *
the new topic's id ({@link String})
+ *
+ */ + public static final String TopicRefId = "topicRefId"; //$NON-NLS-1$ + + /** + * Core event type for adding a summary to a topic (value is 'summaryAdd'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the added {@link org.xmind.core.IBoundary}
+ *
+ */ + public static final String SummaryAdd = "summaryAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a summary to a topic (value is + * 'summaryRemove'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the removed {@link org.xmind.core.IBoundary}
+ *
+ */ + public static final String SummaryRemove = "summaryRemove"; //$NON-NLS-1$ + + /** + * Core event type for adding a style to a style sheet (value is + * 'styleAdd'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.style.IStyleSheet}
+ *
Target:
+ *
the added {@link org.xmind.core.style.IStyle}
+ *
+ */ + public static final String StyleAdd = "styleAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a style from a style sheet (value is + * 'styleRemove'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.style.IStyleSheet}
+ *
Target:
+ *
the removed {@link org.xmind.core.style.IStyle}
+ *
+ */ + public static final String StyleRemove = "styleRemove"; //$NON-NLS-1$ + + /** + * Core event type for modifying a the name (value is 'name). + *
+ *
Source:
+ *
{@link org.xmind.core.INamed}
+ *
OldValue:
+ *
the old name ({@link String}), or null indicating that + * the name was unspecified
+ *
NewValue:
+ *
the new name ({@link String}), or null indicating that + * the name is unspecified
+ *
+ */ + public static final String Name = "name"; //$NON-NLS-1$ + + /** + * Core event type for modifying a property (value is 'property'). + *
+ *
Source:
+ *
{@link org.xmind.core.IProperties}
+ *
Target:
+ *
the property name ({@link String})
+ *
OldValue:
+ *
the old property value ({@link String}), or null + * indicating that the property was unspecified
+ *
NewValue:
+ *
the new property value ({@link String}), or null + * indicating that the property is unspecified
+ *
+ */ + public static final String Property = "property"; //$NON-NLS-1$ + + /** + * Core event type for modifying a sheet's theme id (value is 'themeId'). + *
+ *
Source:
+ *
{@link org.xmind.core.ISheet}
+ *
OldValue:
+ *
the old theme id ({@link String}), or null indicating + * that the theme id was unspecified
+ *
NewValue:
+ *
the new theme id ({@link String}), or null indicating + * that the theme id is unspecified
+ *
+ */ + public static final String ThemeId = "themeId"; //$NON-NLS-1$ + + /** + * Core event type for modifying the structure class of a topic (value is + * 'structureClass'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
OldValue:
+ *
the old structure class ({@link String}), or null + * indicating that the structure class was unspecified
+ *
NewValue:
+ *
the new structure class ({@link String}), or null + * indicating that the structure class is unspecified
+ *
+ */ + public static final String StructureClass = "structureClass"; //$NON-NLS-1$ + + /** + * Core event type for modifying the note content of a topic (value is + * 'topicNotes'). + *
+ *
Source:
+ *
{@link org.xmind.core.ITopic}
+ *
Target:
+ *
the note format (either {@link org.xmind.core.INotes#PLAIN} or + * {@link org.xmind.core.INotes#HTML})
+ *
OldValue:
+ *
the old notes content ({@link org.xmind.core.INotesContent}), or + * null indicating that the note content was unspecified
+ *
NewValue:
+ *
the new notes content ({@link org.xmind.core.INotesContent}), or + * null indicating that the note content is unspecified
+ *
+ * + * @see org.xmind.core.INotes#PLAIN + * @see org.xmind.core.INotes#HTML + * @see org.xmind.core.INotes#getContent(String) + * @see org.xmind.core.INotes#setContent(String, INotesContent) + */ + public static final String TopicNotes = "topicNotes"; //$NON-NLS-1$ + + /** + * Core event type for modifying the labels (value is 'labels'). + *
+ *
Source:
+ *
{@link org.xmind.core.ILabeled}
+ *
OldValue:
+ *
a {@link java.util.Set} of String containing all the old + * labels (may be empty, but is never null)
+ *
NewValue:
+ *
a {@link java.util.Set} of String containing all the new + * labels (may be empty, but is never null)
+ *
+ */ + public static final String Labels = "labels"; //$NON-NLS-1$ + + /** + * Core event type for changes of the resource references (value is + * 'resourceRefs'). + *
+ *
Source:
+ *
{@link org.xmind.core.util.IRefCounter}
+ *
OldValue:
+ *
a {@link java.util.Collection} of String containing all + * the old resource references (may be empty, but is never null)
+ *
NewValue:
+ *
a {@link java.util.Collection} of String containing all + * the new resource references (may be empty, but is never null)
+ *
+ */ + public static final String ResourceRefs = "resourceRefs"; //$NON-NLS-1$ + + /** + * Core event type for modifying the source url of an image (value is + * 'imageSource'). + *
+ *
Source:
+ *
{@link org.xmind.core.IImage}
+ *
OldValue:
+ *
the old source url of the image ({@link String}), or + * null indicating that the source url was unspecified
+ *
NewValue:
+ *
the new source url of the image ({@link String}), or + * null indicating that the source url is unspecified
+ *
+ */ + public static final String ImageSource = "imageSource"; //$NON-NLS-1$ + + /** + * Core event type for modifying the width of an image (value is + * 'imageWidth'). + *
+ *
Source:
+ *
{@link org.xmind.core.IImage}
+ *
OldValue:
+ *
the old width of the image ({@link Integer}), or null + * indicating that the width was unspecified
+ *
NewValue:
+ *
the new width of the image ({@link String}), or null + * indicating that the width is unspecified
+ *
+ */ + public static final String ImageWidth = "imageWidth"; //$NON-NLS-1$ + + /** + * Core event type for modifying the height of an image (value is + * 'imageHeight'). + *
+ *
Source:
+ *
{@link org.xmind.core.IImage}
+ *
OldValue:
+ *
the old height of the image ({@link Integer}), or null + * indicating that the height was unspecified
+ *
NewValue:
+ *
the new height of the image ({@link String}), or null + * indicating that the height is unspecified
+ *
+ */ + public static final String ImageHeight = "imageHeight"; //$NON-NLS-1$ + + /** + * Core event type for modifying the alignment of an image (value is + * 'imageAlignment'). + *
+ *
Source:
+ *
{@link org.xmind.core.IImage}
+ *
OldValue:
+ *
the old alignment of the image ({@link Integer}), or + * null indicating that the alignment was unspecified
+ *
NewValue:
+ *
the new alignment of the image ({@link String}), or null + * indicating that the alignment is unspecified
+ *
+ */ + public static final String ImageAlignment = "imageAlignment"; //$NON-NLS-1$ + + /** + * Core event type for modifying the visiblity of a legend (value is + * 'visibility'). + *
+ *
Source:
+ *
{@link org.xmind.core.ILegend}
+ *
OldValue:
+ *
the old visibility ({@link Boolean})
+ *
NewValue:
+ *
the new visibility ({@link Boolean})
+ *
+ */ + public static final String Visibility = "visibility"; //$NON-NLS-1$ + + /** + * Core event type for modifying the description of a marker on a sheet + * (value is 'markerDescription'). + *
+ *
Source:
+ *
{@link org.xmind.core.ILegend}
+ *
Target:
+ *
the marker's id ({@link String})
+ *
OldValue:
+ *
the old description ({@link String}) of the target marker, or + * null indicating that the description was unspecified
+ *
NewValue:
+ *
the new description ({@link String}) of the target marker, or + * null indicating that the description is unspecified
+ *
+ */ + public static final String MarkerDescription = "markerDescription"; //$NON-NLS-1$ + + public static final String NumberFormat = "numberingFormat"; //$NON-NLS-1$ + + public static final String NumberingPrefix = "numberingPrefix"; //$NON-NLS-1$ + + public static final String NumberingSuffix = "numberingSuffix"; //$NON-NLS-1$ + + public static final String NumberPrepending = "parentNumberingPrepending"; //$NON-NLS-1$ + + public static final String NumberingSeparator = "numberingSeparator"; //$NON-NLS-1$ + + public static final String NumberingDepth = "numberingDepth"; //$NON-NLS-1$ + + /** + * Core event type for changing the password of a workbook (value is + * 'passwordChange'). + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkboook}
+ *
+ */ + public static final String PasswordChange = "passwordChange"; //$NON-NLS-1$ + + /** + * Core event type for going to save a workbook (value is + * 'workbookPreSave'). This type of events is dispatched before a workbook + * is saved. Listening to this type of events allows modification to the + * workbook content before saving it to the destination. The most common + * usage is to save preview pictures by the UI, for we can't generate a + * preview picture without a graphical environment. + * + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkboook}
+ *
+ * + * @see org.xmind.core.IWorkbook#save() + * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) + * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) + * @see org.xmind.core.IWorkbook#save(String) + */ + public static final String WorkbookPreSave = "workbookPreSave"; //$NON-NLS-1$ + + /** + * Core event type for going to save a workbook (value is + * 'workbookPreSaveOnce'). Similar to {@link #WorkbookPreSave}, but + * listeners to this type events are notified only once and removed from the + * event list thereafter. This type of events are commonly used when some + * pending work that may modify the content of a workbook should be counted + * before saving the workbook. + * + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkboook}
+ *
+ * + * @see org.xmind.core.IWorkbook#save() + * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) + * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) + * @see org.xmind.core.IWorkbook#save(String) + */ + public static final String WorkbookPreSaveOnce = "workbookPreSaveOnce"; //$NON-NLS-1$ + + /** + * Core event type for having saved a workbook (value is 'workbookSave'). + * This type of events is dispatched after a workbook is saved. + * + *
+ *
Source:
+ *
{@link org.xmind.core.IWorkboook}
+ *
+ *
+ * + * @see org.xmind.core.IWorkbook#save() + * @see org.xmind.core.IWorkbook#save(org.xmind.core.io.IOutputTarget) + * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) + * @see org.xmind.core.IWorkbook#save(String) + */ + public static final String WorkbookSave = "workbookSave"; //$NON-NLS-1$ + + /** + * Core event for updating the modified time of an element (value is + * 'modifyTime'). When this event is dispatched, all other modification info + * has been updated such as + * {@link org.xmind.core.IModifiable#getModifiedBy()}. + * + *
+ *
Source:
+ *
a {@link org.xmind.core.IModifiable} object
+ *
OldValue:
+ *
the old modified time (long)
+ *
NewValue:
+ *
the new modified time (long)
+ *
+ * + * @see org.xmind.core.IModifiable + */ + public static final String ModifyTime = "modifyTime"; //$NON-NLS-1$ + + /** + * Core event type for adding a revision to the revision manager (value is + * 'revisionAdd'). + * + *
+ *
Source:
+ *
the parent {@link org.xmind.core.IRevisionManager}
+ *
Target:
+ *
the child {@link org.xmind.core.IRevision}
+ *
Data:
+ *
Corresponding resource ID (String)
+ *
+ * + * @see org.xmind.core.IRevisionManager#addRevision(IAdaptable) + */ + public static final String RevisionAdd = "revisionAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a revision from the revision manager (value + * is 'revisionRemove'). + * + *
+ *
Source:
+ *
the parent {@link org.xmind.core.IRevisionManager}
+ *
Target:
+ *
the child {@link org.xmind.core.IRevision}
+ *
Data:
+ *
Corresponding resource ID (String)
+ *
+ * + * @see org.xmind.core.IRevisionManager#removeRevision(IRevision) + */ + public static final String RevisionRemove = "revisionRemove"; //$NON-NLS-1$ + + /** + * Core event type for value change in {@link org.xmind.core.IMeta} (value + * is 'metadata'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.IMeta}
+ *
Target:
+ *
a {@link String} representing the key path of the modified metadata + *
+ *
OldValue:
+ *
the old {@link String} value of the metadata, or null to + * indicate this metadata was created
+ *
NewValue:
+ *
the new {@link String} value of the metadata, or null to + * indicate this metadata was deleted
+ *
+ * + * @see org.xmind.core.IMeta#setValue(String, String) + * @see org.xmind.core.IMetaData#setValue(String) + */ + public static final String Metadata = "metadata"; //$NON-NLS-1$ + + /** + * Core event type for attribute change in {@link org.xmind.core.IMetaData} + * (value is 'metadataAttribute'). + * + *
+ *
Source:
+ *
{@link org.xmind.core.IMeta}
+ *
Target:
+ *
a {@link String} representing the key of the modified metadata
+ *
Data:
+ *
a {@link String} representing the name of the modified attribute
+ *
OldValue:
+ *
the old {@link String} value of the attribute, or null + * to indicate this attribute was added
+ *
NewValue:
+ *
the new {@link String} value of the attribute, or null + * to indicate this attribute was removed
+ * + * @deprecated Not used any more. {@link #Metadata} is enough. + * + * @see org.xmind.core.IMetaData#setAttribute(String, String) + */ + public static final String MetadataAttribute = "metadataAttribute"; //$NON-NLS-1$ + + /** + * Core event type for adding a file entry to the owned manifest (value is + * 'fileEntryAdd'). A file entry is automatically added to the owned + * manifest once its reference count is increased from 0 to 1. + *
+ *
Source:
+ *
the {@link org.xmind.core.IManifest}
+ *
Target:
+ *
the {@link org.xmind.core.IFileEntry}
+ *
+ * + * @see org.xmind.core.IFileEntry#increaseReference() + */ + public static final String FileEntryAdd = "fileEntryAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a file entry from the owned manifest (value + * is 'fileEntryRemove'). A file entry is automatically removed from the + * owned manifest once its reference count is decreased from 1 to 0. + *
+ *
Source:
+ *
the {@link org.xmind.core.IManifest}
+ *
Target:
+ *
the {@link org.xmind.core.IFileEntry}
+ *
+ * + * @see org.xmind.core.IFileEntry#decreaseReference() + */ + public static final String FileEntryRemove = "fileEntryRemove"; //$NON-NLS-1$ + + /** + * Core event type for adding a comment to its associated object (value is + * 'commentAdd'). + * + *
+ *
Source:
+ *
the associated object that implements {@link org.xmind.core.ITitled}, + * e.g. {@link org.xmind.core.ITopic} or {@link org.xmind.core.ISheet}
+ *
Target:
+ *
the {@link org.xmind.core.IComment}
+ *
+ * + * @see org.xmind.core.ICommentManager#addComment(IComment) + */ + public static final String CommentAdd = "commentAdd"; //$NON-NLS-1$ + + /** + * Core event type for removing a comment from its associated object (value + * is 'commentRemove'). + * + *
+ *
Source:
+ *
the associated object that implements {@link org.xmind.core.ITitled}, + * e.g. {@link org.xmind.core.ITopic} or {@link org.xmind.core.ISheet}
+ *
Target:
+ *
the {@link org.xmind.core.IComment}
+ *
+ * + * @see org.xmind.core.ICommentManager#removeComment(IComment) + */ + public static final String CommentRemove = "commentRemove"; //$NON-NLS-1$ + + /** + * Core event type for modifying the content of a comment (value is + * 'commentContent'). + * + *
+ *
Source:
+ *
the {@link org.xmind.core.IComment}
+ *
OldValue:
+ *
the old text content ({@link String}), or null if there + * was no content before modifying
+ *
NewValue:
+ *
the new text content ({@link String}), or null if there + * is no content after modifying
+ *
+ */ + public static final String CommentContent = "commentContent"; //$NON-NLS-1$ + + /** + * Error constants indicating that an unknown error occurs (value=1). + */ + public static final int ERROR_UNKNOWN = 1; + + /** + * Error constants indicating that a null argument is passed in (value=2). + */ + public static final int ERROR_NULL_ARGUMENT = 2; + + /** + * Error constants indicating that an invalid argument is passed in + * (value=3). + */ + public static final int ERROR_INVALID_ARGUMENT = 3; + + public static final int ERROR_INVALID_FILE = 10; + + public static final int ERROR_NO_SUCH_ENTRY = 11; + + public static final int ERROR_FAIL_ACCESS_XML_PARSER = 12; + + public static final int ERROR_SYNTAX = 13; + public static final int ERROR_FAIL_PARSING_XML = ERROR_SYNTAX; + + public static final int ERROR_NO_WORKBOOK_CONTENT = 14; + + public static final int ERROR_FAIL_ACCESS_XML_TRANSFORMER = 15; + + public static final int ERROR_FAIL_INIT_CRYPTOGRAM = 16; + + public static final int ERROR_WRONG_PASSWORD = 17; + + public static final int ERROR_FAIL_SERIALIZING_XML = 18; + + public static final int ERROR_CANCELLATION = 100; + + /** + * Media type for a textual file (value='text/xml'). + * + * @see org.xmind.core.IFileEntry#getMediaType() + */ + public static final String MEDIA_TYPE_TEXT_XML = "text/xml"; //$NON-NLS-1$ + + /** + * Media type for an image file (value='image/png'). + * + * @see org.xmind.core.IFileEntry#getMediaType() + */ + public static final String MEDIA_TYPE_IMAGE_PNG = "image/png"; //$NON-NLS-1$ + + @Deprecated + public static final String TopicComments = "topicComments"; //$NON-NLS-1$ + + private Core() { + throw new AssertionError("Instantiation of this class is not allowed!"); //$NON-NLS-1$ + } + + /** + * + *

+ * WARNING: This is a legacy mechanism to generate unique + * identifiers. Clients should use {@link UUID} instead for higher + * uniqueness. + *

+ * + * @return an {@link IIdFactory} that generates unique identifiers + */ + public static IIdFactory getIdFactory() { + return getInternal().getIdFactory(); + } + + /** + * + *

+ * WARNING: The workbook builder no longer supports loading + * workbooks. Use + * Core.getSerializationProvider().newDeserializer() for this + * kind of tasks. + *

+ * + * @return an {@link IWorkbookBuilder} that is capable for creating workbook + * instances + */ + public static IWorkbookBuilder getWorkbookBuilder() { + return getInternal().getWorkbookBuilder(); + } + + public static IWorkspace getWorkspace() { + return getInternal().getWorkspace(); + } + + public static Comparator getTopicComparator() { + return getInternal().getTopicComparator(); + } + + public static IMarkerSheetBuilder getMarkerSheetBuilder() { + return getInternal().getMarkerSheetBuilder(); + } + + public static IStyleSheetBuilder getStyleSheetBuilder() { + return getInternal().getStyleSheetBuilder(); + } + + public static final String getCurrentVersion() { + return getInternal().getCurrentVersion(); + } + + public static final boolean isPartiallyCompatible(String version) { + return getInternal().isPartiallyCompatible(version); + } + + /** + * NOTE: For internal use only. Not a public API. + * + * @return the default error logger + */ + public static final ILogger getLogger() { + return getInternal().getLogger(); + } + + private static InternalCore getInternal() { + return InternalCore.getInstance(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IAdaptable.java b/bundles/org.xmind.core/src/org/xmind/core/IAdaptable.java index aa9e616d9..5145c9ef7 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IAdaptable.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IAdaptable.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -/** - * An interface for an adaptable object. - *

- * Adaptable objects can be dynamically extended to provide different interfaces - * (or "adapters"). Workbooks and workbook components implement this interface - * to provide additional functionalities specific to their implementations. - *

- * For example, - * - *
- *     IAdaptable a = [some adaptable];
- *     IFoo x = a.getAdapter(IFoo.class);
- *     if (x != null)
- *         [do IFoo things with x]
- * 
- */ -public interface IAdaptable { - - /** - * Returns an object which is an instance of the given class associated with - * this object. Returns null if no such object can be found. - * - * @param adapter - * the adapter class to look up - * @return a object of the given class, or null if this object - * does not have an adapter for the given class - */ - T getAdapter(Class adapter); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +/** + * An interface for an adaptable object. + *

+ * Adaptable objects can be dynamically extended to provide different interfaces + * (or "adapters"). Workbooks and workbook components implement this interface + * to provide additional functionalities specific to their implementations. + *

+ * For example, + * + *
+ *     IAdaptable a = [some adaptable];
+ *     IFoo x = a.getAdapter(IFoo.class);
+ *     if (x != null)
+ *         [do IFoo things with x]
+ * 
+ */ +public interface IAdaptable { + + /** + * Returns an object which is an instance of the given class associated with + * this object. Returns null if no such object can be found. + * + * @param adapter + * the adapter class to look up + * @return a object of the given class, or null if this object + * does not have an adapter for the given class + */ + T getAdapter(Class adapter); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IBoundary.java b/bundles/org.xmind.core/src/org/xmind/core/IBoundary.java index 000f07104..12cefd3cd 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IBoundary.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IBoundary.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import org.xmind.core.style.IStyled; - -public interface IBoundary extends IAdaptable, IIdentifiable, ITopicComponent, - ITopicRange, ITitled, IStyled, IRelationshipEnd, IModifiable { - - boolean isMasterBoundary(); - - void setMasterBoundary(boolean master); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import org.xmind.core.style.IStyled; + +public interface IBoundary extends IAdaptable, IIdentifiable, ITopicComponent, + ITopicRange, ITitled, IStyled, IRelationshipEnd, IModifiable { + + boolean isMasterBoundary(); + + void setMasterBoundary(boolean master); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IComment.java b/bundles/org.xmind.core/src/org/xmind/core/IComment.java index dcdf9bd23..33c1487e5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IComment.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IComment.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core; - -/** - * This interface represents a piece of text a user writes to comment on an - * object. The target object MUST be available via - * getOwnedWorkbook().getElementById(getObjectId()), otherwise the - * comment will not be included in the workbook. The user who wrote a comment is - * called the author, whose name will be associated with this comment. - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IComment - extends IAdaptable, IWorkbookComponent, Comparable { - - /** - * Returns the id of the object to which this comment is associated. This - * attribute can not be modified once this comment is created. - * - * @return the object id, never null - */ - String getObjectId(); - - /** - * Returns the name of the author of this comment. - * - * @return the author name, never null - */ - String getAuthor(); - - /** - * Returns the time (in milliseconds since Jan 1, 1970) when this comment is - * created. - * - * @return the creation time - */ - long getTime(); - - /** - * Returns the text content of this comment. This method may return - * null if the content is not set yet or be cleared out. - * - * @return the text content, or null - */ - String getContent(); - - /** - * Sets the text content of this comment to the specified string. If the - * string is null, the original content will be cleared out. - * - * @param content - * a {@link String} of the new content - */ - void setContent(String content); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core; + +/** + * This interface represents a piece of text a user writes to comment on an + * object. The target object MUST be available via + * getOwnedWorkbook().getElementById(getObjectId()), otherwise the + * comment will not be included in the workbook. The user who wrote a comment is + * called the author, whose name will be associated with this comment. + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IComment + extends IAdaptable, IWorkbookComponent, Comparable { + + /** + * Returns the id of the object to which this comment is associated. This + * attribute can not be modified once this comment is created. + * + * @return the object id, never null + */ + String getObjectId(); + + /** + * Returns the name of the author of this comment. + * + * @return the author name, never null + */ + String getAuthor(); + + /** + * Returns the time (in milliseconds since Jan 1, 1970) when this comment is + * created. + * + * @return the creation time + */ + long getTime(); + + /** + * Returns the text content of this comment. This method may return + * null if the content is not set yet or be cleared out. + * + * @return the text content, or null + */ + String getContent(); + + /** + * Sets the text content of this comment to the specified string. If the + * string is null, the original content will be cleared out. + * + * @param content + * a {@link String} of the new content + */ + void setContent(String content); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ICommentManager.java b/bundles/org.xmind.core/src/org/xmind/core/ICommentManager.java index 6b285f634..6c994f035 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ICommentManager.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ICommentManager.java @@ -1,136 +1,136 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core; - -import java.util.Set; - -/** - * This interface provides abilities to manage comments within a workbook. - * Instances of this interface should also provide a functionality that - * automatically adds (or removes) comments whose associated object is added to - * (or removed from) the owner workbook, so that no redundant comments exist. - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface ICommentManager extends IAdaptable, IWorkbookComponent { - - /** - * Creates a new comment with basic attributes. The created comment instance - * is stored in memory only and has not been added to workbook yet (i.e. - * comment.isOrphan() returns true). This method - * associates the created comment with the specified object id regardless of - * its existence or orphanhood. - * - * @param author - * the author name - * @param time - * the creation time (may be - * System.currentTimeMillis()) - * @param objectId - * the id of the object to be associated with - * @return a new comment - * @throws IllegalArgumentException - * if the author is null, time is less than or - * equals to 0, or the object id is null - */ - IComment createComment(String author, long time, String objectId); - - /** - * Adds a comment into the owner workbook. Has no effect if the comment is - * already added. - * - *

- * Note that, if the comment's associated object is an orphan or does not - * exist, this operation will be remembered and suppressed, and the comment - * will not be included in the results of {@link #getComments(String)} or - * {@link #getAllComments()}, until the associated object becomes part of - * the workbook. Pending comments will not be saved with workbook. - *

- * - * @param comment - * the comment to be added - * @throws IllegalArgumentException - * if the comment is not owned by the same workbook - */ - void addComment(IComment comment); - - /** - * Removes a comment from the owner workbook. Has no effect if the comment - * is already removed. - * - *

- * Note that, if the comment's associated object is an orphan or does not - * exist, this operation is still remembered and the comment will not be - * included in results of {@link #getComments(String)} or - * {@link #getAllComments()} even though the associated object becomes part - * of the workbook again. - *

- * - * @param comment - * the comment to be removed - * @throws IllegalArgumentException - * if the comment is not owned by the same workbook - */ - void removeComment(IComment comment); - - /** - * Returns a set of comments that are associated with the same object id. An - * empty set will be returned if the associated object is an orphan or does - * not exist. - * - * @param objectId - * the id of the associated object - * @return a set of comments (never null) - * @throws IllegalArgumentException - * if the object id is null - */ - Set getComments(String objectId); - - /** - * Tests whether this workbook contains any comment that is associated with - * a specific object. The result should be the same with - * !getComments(objectId).isEmpty(). - * - * @param objectId - * @return true if such comments exist, or false - * otherwise - * @see #getComments(String) - * @throws IllegalArgumentException - * if the object id is null - */ - boolean hasComments(String objectId); - - /** - * Returns a set of all comments in this workbook. Note that comments whose - * associated objects are orphans will be excluded. - * - * @return a set of all comments (never null) - */ - Set getAllComments(); - - /** - * Tests whether this workbook contains no comment. The result should be - * same with getAllComments().isEmpty(). - * - * @return true if no comments exist, or false - * otherwise - * @see #getAllComments() - */ - boolean isEmpty(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core; + +import java.util.Set; + +/** + * This interface provides abilities to manage comments within a workbook. + * Instances of this interface should also provide a functionality that + * automatically adds (or removes) comments whose associated object is added to + * (or removed from) the owner workbook, so that no redundant comments exist. + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface ICommentManager extends IAdaptable, IWorkbookComponent { + + /** + * Creates a new comment with basic attributes. The created comment instance + * is stored in memory only and has not been added to workbook yet (i.e. + * comment.isOrphan() returns true). This method + * associates the created comment with the specified object id regardless of + * its existence or orphanhood. + * + * @param author + * the author name + * @param time + * the creation time (may be + * System.currentTimeMillis()) + * @param objectId + * the id of the object to be associated with + * @return a new comment + * @throws IllegalArgumentException + * if the author is null, time is less than or + * equals to 0, or the object id is null + */ + IComment createComment(String author, long time, String objectId); + + /** + * Adds a comment into the owner workbook. Has no effect if the comment is + * already added. + * + *

+ * Note that, if the comment's associated object is an orphan or does not + * exist, this operation will be remembered and suppressed, and the comment + * will not be included in the results of {@link #getComments(String)} or + * {@link #getAllComments()}, until the associated object becomes part of + * the workbook. Pending comments will not be saved with workbook. + *

+ * + * @param comment + * the comment to be added + * @throws IllegalArgumentException + * if the comment is not owned by the same workbook + */ + void addComment(IComment comment); + + /** + * Removes a comment from the owner workbook. Has no effect if the comment + * is already removed. + * + *

+ * Note that, if the comment's associated object is an orphan or does not + * exist, this operation is still remembered and the comment will not be + * included in results of {@link #getComments(String)} or + * {@link #getAllComments()} even though the associated object becomes part + * of the workbook again. + *

+ * + * @param comment + * the comment to be removed + * @throws IllegalArgumentException + * if the comment is not owned by the same workbook + */ + void removeComment(IComment comment); + + /** + * Returns a set of comments that are associated with the same object id. An + * empty set will be returned if the associated object is an orphan or does + * not exist. + * + * @param objectId + * the id of the associated object + * @return a set of comments (never null) + * @throws IllegalArgumentException + * if the object id is null + */ + Set getComments(String objectId); + + /** + * Tests whether this workbook contains any comment that is associated with + * a specific object. The result should be the same with + * !getComments(objectId).isEmpty(). + * + * @param objectId + * @return true if such comments exist, or false + * otherwise + * @see #getComments(String) + * @throws IllegalArgumentException + * if the object id is null + */ + boolean hasComments(String objectId); + + /** + * Returns a set of all comments in this workbook. Note that comments whose + * associated objects are orphans will be excluded. + * + * @return a set of all comments (never null) + */ + Set getAllComments(); + + /** + * Tests whether this workbook contains no comment. The result should be + * same with getAllComments().isEmpty(). + * + * @return true if no comments exist, or false + * otherwise + * @see #getAllComments() + */ + boolean isEmpty(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java b/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java index 7c46120df..1ed8b49ec 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java @@ -1,165 +1,165 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core; - -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.IProgressReporter; - -/** - * A deserializer is responsible for parsing binary data into a workbook. - * Workbooks loaded by this deserializer can be later saved via - * {@link ISerializer} objects of the same format version. - * - *

- * Instances of this interface can be retrieved via - * Core.getSerializationProvider().newDeserializer(). NOTE - * that clients are allowed to use one deserializer instance to load - * one workbook from one location for only once, and - * repeated usage of a single deserializer instance may result in unexpected - * behaviors. Also note that all methods of this interface may NOT be - * thread-safe. - *

- * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IDeserializer extends ISerializingBase { - - IManifest getManifest(); - - void deserializeManifest(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException; - - /** - * Returns the deserialized workbook. - * - * @return the deserialized workbook, or null if no workbook is - * successfully deserialized - */ - IWorkbook getWorkbook(); - - /** - * Deserializes binary data from the given input source (set via - * {@link #setInputSource(IInputSource)}, - * {@link #setInputStream(InputStream)}, or - * {@link #setWorkbookStorageAsInputSource()}) into a workbook, storing its - * file entries in the specified storage (set via - * {@link #setWorkbookStorage(IStorage)} or, if not set, a new - * {@link ByteArrayStorage} created automatically). The deserialized - * workbook can be retrieved via {@link #getWorkbook()} after the - * deserialization is done. The progress during the deserialization is - * reported via the given progress reporter. - * - * @param reporter - * an {@link IProgressReporter} object to receive progress - * information and indicate user cancellation requests, or - * null if the progress is not significant and - * cancellation is not required - * @throws IOException - * if any I/O error occurs - * @throws CoreException - *
    - *
  • Core.ERROR_CANCELLATION - if the operation - * is canceled
  • - *
  • Core.ERROR_WRONG_PASSWORD - if the workbook - * is encrypted and the decryption operation failed
  • - *
  • (TODO add more error codes)
  • - *
- * @throws IllegalStateException - * if either input source or workbook storage is not set - * properly - */ - void deserialize(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException; - - /** - * Sets the storage with read-write random-access abilities to store - * contents of file entries for the deserialized workbook. This storage will - * be kept and held by the deserialized workbook after deserialization is - * over. If no storage is set, a new empty in-memory - * {@link ByteArrayStorage} will be automatically created and used. - * - * @param storage - * the {@link IStorage} to use - * @throws IllegalArgumentException - * if the storage is null - */ - void setWorkbookStorage(IStorage storage); - - /** - * Returns the storage set via {@link #setWorkbookStorage(IStorage)}. - * - * @return the storage set previously, or null if not set yet - */ - IStorage getWorkbookStorage(); - - /** - * Sets the input source from which the content of the deserialized workbook - * will be loaded. - * - * @param source - * the {@link IInputSource} - * @throws IllegalArgumentException - * if the source is null - */ - void setInputSource(IInputSource source); - - /** - * Sets the input stream as the input source from which the content of the - * deserialized workbook will be loaded. - * - *

- * NOTE: The deserializer may not close the given stream after usage. The - * client should close it on its own. - *

- * - * @param stream - * the source {@link InputStream} - * @throws IllegalArgumentException - * if the stream is null - */ - void setInputStream(InputStream stream); - - /** - * Sets the output target to be the input source of the storage set via - * {@link #setWorkbookStorage(IStorage)}. Calling this method will remove - * any input source set previously. - * - *

- * This special setting indicates some special behaviors, e.g. no file - * entries will be copied to save time. - *

- */ - void setWorkbookStorageAsInputSource(); - - /** - * Tests whether an input source is properly set via - * {@link #setInputSource(IInputSource)}, - * {@link #setInputStream(InputStream)} or - * {@link #setWorkbookStorageAsInputSource()}. - * - * @return true if the input source is set, or - * false otherwise - */ - boolean hasInputSource(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core; + +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.IProgressReporter; + +/** + * A deserializer is responsible for parsing binary data into a workbook. + * Workbooks loaded by this deserializer can be later saved via + * {@link ISerializer} objects of the same format version. + * + *

+ * Instances of this interface can be retrieved via + * Core.getSerializationProvider().newDeserializer(). NOTE + * that clients are allowed to use one deserializer instance to load + * one workbook from one location for only once, and + * repeated usage of a single deserializer instance may result in unexpected + * behaviors. Also note that all methods of this interface may NOT be + * thread-safe. + *

+ * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IDeserializer extends ISerializingBase { + + IManifest getManifest(); + + void deserializeManifest(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException; + + /** + * Returns the deserialized workbook. + * + * @return the deserialized workbook, or null if no workbook is + * successfully deserialized + */ + IWorkbook getWorkbook(); + + /** + * Deserializes binary data from the given input source (set via + * {@link #setInputSource(IInputSource)}, + * {@link #setInputStream(InputStream)}, or + * {@link #setWorkbookStorageAsInputSource()}) into a workbook, storing its + * file entries in the specified storage (set via + * {@link #setWorkbookStorage(IStorage)} or, if not set, a new + * {@link ByteArrayStorage} created automatically). The deserialized + * workbook can be retrieved via {@link #getWorkbook()} after the + * deserialization is done. The progress during the deserialization is + * reported via the given progress reporter. + * + * @param reporter + * an {@link IProgressReporter} object to receive progress + * information and indicate user cancellation requests, or + * null if the progress is not significant and + * cancellation is not required + * @throws IOException + * if any I/O error occurs + * @throws CoreException + *
    + *
  • Core.ERROR_CANCELLATION - if the operation + * is canceled
  • + *
  • Core.ERROR_WRONG_PASSWORD - if the workbook + * is encrypted and the decryption operation failed
  • + *
  • (TODO add more error codes)
  • + *
+ * @throws IllegalStateException + * if either input source or workbook storage is not set + * properly + */ + void deserialize(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException; + + /** + * Sets the storage with read-write random-access abilities to store + * contents of file entries for the deserialized workbook. This storage will + * be kept and held by the deserialized workbook after deserialization is + * over. If no storage is set, a new empty in-memory + * {@link ByteArrayStorage} will be automatically created and used. + * + * @param storage + * the {@link IStorage} to use + * @throws IllegalArgumentException + * if the storage is null + */ + void setWorkbookStorage(IStorage storage); + + /** + * Returns the storage set via {@link #setWorkbookStorage(IStorage)}. + * + * @return the storage set previously, or null if not set yet + */ + IStorage getWorkbookStorage(); + + /** + * Sets the input source from which the content of the deserialized workbook + * will be loaded. + * + * @param source + * the {@link IInputSource} + * @throws IllegalArgumentException + * if the source is null + */ + void setInputSource(IInputSource source); + + /** + * Sets the input stream as the input source from which the content of the + * deserialized workbook will be loaded. + * + *

+ * NOTE: The deserializer may not close the given stream after usage. The + * client should close it on its own. + *

+ * + * @param stream + * the source {@link InputStream} + * @throws IllegalArgumentException + * if the stream is null + */ + void setInputStream(InputStream stream); + + /** + * Sets the output target to be the input source of the storage set via + * {@link #setWorkbookStorage(IStorage)}. Calling this method will remove + * any input source set previously. + * + *

+ * This special setting indicates some special behaviors, e.g. no file + * entries will be copied to save time. + *

+ */ + void setWorkbookStorageAsInputSource(); + + /** + * Tests whether an input source is properly set via + * {@link #setInputSource(IInputSource)}, + * {@link #setInputStream(InputStream)} or + * {@link #setWorkbookStorageAsInputSource()}. + * + * @return true if the input source is set, or + * false otherwise + */ + boolean hasInputSource(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java b/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java index 3910cc33b..4a40b587b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java @@ -1,93 +1,93 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -/** - * @author frankshaka - * - */ -public interface IEncryptionData extends IAdaptable { - - /** - * Use SEP to separate multiple keys. - *

- * Example: - * - *

-     * encryption data: checksum="acbdefghij==" checksum-type="MD5"
-     *     +-- algorithm: algorithm-name="PBEWithMD5AndDES/CBC/Padded"  
-     *     +-- key-derivation: key-derivation-name="PKCS12" salt="12345678==" iteration-count="1024"
-     * 
- * - * encryptionData.getAttribute("checksum") = "acbdefghij=="
- * encryptionData.getAttribute("checksum-type") = "MD5"
- * encryptionData.getAttribute("algorithm", "algorithm-name") = - * "PBEWithMD5AndDES/CBC/Padded"
- * encryptionData.getAttribute("key-derivation", "key-derivation-name") = - * "PKCS12"
- * encryptionData.getAttribute("key-derivation", "salt") = "12345678=="
- * encryptionData.getAttribute("key-derivation", "iteration-count") = "1024" - *

- * - * @param keyPath - * @return - */ - String getAttribute(String... keyPath); - - /** - * - * @param defaultValue - * @param keyPath - * @return - */ - int getIntAttribute(int defaultValue, String... keyPath); - - /** - * - * @param value - * @param keyPath - */ - void setAttribute(String value, String... keyPath); - - /** - * - * @return - */ - String getChecksum(); - - /** - * - * @param checksum - */ - void setChecksum(String checksum); - - /** - * - * @return - */ - String getChecksumType(); - - /** - * - * @param checksumType - */ - void setChecksumType(String checksumType); - - /** - * - * @return - */ - IFileEntry getFileEntry(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +/** + * @author frankshaka + * + */ +public interface IEncryptionData extends IAdaptable { + + /** + * Use SEP to separate multiple keys. + *

+ * Example: + * + *

+     * encryption data: checksum="acbdefghij==" checksum-type="MD5"
+     *     +-- algorithm: algorithm-name="PBEWithMD5AndDES/CBC/Padded"  
+     *     +-- key-derivation: key-derivation-name="PKCS12" salt="12345678==" iteration-count="1024"
+     * 
+ * + * encryptionData.getAttribute("checksum") = "acbdefghij=="
+ * encryptionData.getAttribute("checksum-type") = "MD5"
+ * encryptionData.getAttribute("algorithm", "algorithm-name") = + * "PBEWithMD5AndDES/CBC/Padded"
+ * encryptionData.getAttribute("key-derivation", "key-derivation-name") = + * "PKCS12"
+ * encryptionData.getAttribute("key-derivation", "salt") = "12345678=="
+ * encryptionData.getAttribute("key-derivation", "iteration-count") = "1024" + *

+ * + * @param keyPath + * @return + */ + String getAttribute(String... keyPath); + + /** + * + * @param defaultValue + * @param keyPath + * @return + */ + int getIntAttribute(int defaultValue, String... keyPath); + + /** + * + * @param value + * @param keyPath + */ + void setAttribute(String value, String... keyPath); + + /** + * + * @return + */ + String getChecksum(); + + /** + * + * @param checksum + */ + void setChecksum(String checksum); + + /** + * + * @return + */ + String getChecksumType(); + + /** + * + * @param checksumType + */ + void setChecksumType(String checksumType); + + /** + * + * @return + */ + IFileEntry getFileEntry(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IEntryStreamNormalizer.java b/bundles/org.xmind.core/src/org/xmind/core/IEntryStreamNormalizer.java index 9a9295e3b..6905a85b2 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IEntryStreamNormalizer.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IEntryStreamNormalizer.java @@ -1,87 +1,87 @@ -package org.xmind.core; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * This interface converts input/output streams that may be encoded/encrypted - * into normalized ones that are decoded/decrypted and suitable for - * reading/writing actual entry content directly. A file entry provides - * encoding/encryption information when decoding/decrypting and receives - * encoding/encryption information when encoding/encrypting. - * - * @author Ren Siu - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IEntryStreamNormalizer { - - IEntryStreamNormalizer NULL = new IEntryStreamNormalizer() { - - public OutputStream normalizeOutputStream(OutputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - fileEntry.deleteEncryptionData(); - return stream; - } - - public InputStream normalizeInputStream(InputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - return stream; - } - - }; - - /** - * Converts the specified output stream into an encoded/encrypted one that - * can be used for writing normal entry content. The specified file entry's - * original encoding/encryption data will be cleared and new ones will be - * created on it to store encoding/encryption information used for writing - * operations. - * - * @param stream - * the {@link OutputStream} that writes data to the target - * storage - * @param fileEntry - * the {@link IFileEntry} that receives encoding/encryption data - * @return a new {@link OutputStream} that receives content data and writes - * them to the given stream - * @throws IOException - * if any I/O error occurs - * @throws CoreException - *
    - *
  • Core.ERROR_WRONG_PASSWORD - if - * encoding/encryption fails;
  • - *
  • Core.ERROR_CANCELLATION - if the operation - * is cancelled
  • - *
- * @throws IllegalArgumentException - * if the stream or file entry is null - */ - OutputStream normalizeOutputStream(OutputStream stream, - IFileEntry fileEntry) throws IOException, CoreException; - - /** - * Converts the specified input stream into an decoded/decrypted one that - * can be used for reading normal entry content. The specified file entry's - * encoding/encryption data will be used during converting and reading - * operations. - * - * @param stream - * the {@link InputStream} that reads data from the target - * storage - * @param fileEntry - * the {@link IFileEntry} that provides encoding/encryption data - * @return a new {@link InputStream} that reads encoded/encrypted data from - * the given stream and decodes/decrypts them - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if decoding/decryption fails - * @throws IllegalArgumentException - * if the stream or file entry is null - */ - InputStream normalizeInputStream(InputStream stream, IFileEntry fileEntry) - throws IOException, CoreException; - -} +package org.xmind.core; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * This interface converts input/output streams that may be encoded/encrypted + * into normalized ones that are decoded/decrypted and suitable for + * reading/writing actual entry content directly. A file entry provides + * encoding/encryption information when decoding/decrypting and receives + * encoding/encryption information when encoding/encrypting. + * + * @author Ren Siu + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IEntryStreamNormalizer { + + IEntryStreamNormalizer NULL = new IEntryStreamNormalizer() { + + public OutputStream normalizeOutputStream(OutputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + fileEntry.deleteEncryptionData(); + return stream; + } + + public InputStream normalizeInputStream(InputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + return stream; + } + + }; + + /** + * Converts the specified output stream into an encoded/encrypted one that + * can be used for writing normal entry content. The specified file entry's + * original encoding/encryption data will be cleared and new ones will be + * created on it to store encoding/encryption information used for writing + * operations. + * + * @param stream + * the {@link OutputStream} that writes data to the target + * storage + * @param fileEntry + * the {@link IFileEntry} that receives encoding/encryption data + * @return a new {@link OutputStream} that receives content data and writes + * them to the given stream + * @throws IOException + * if any I/O error occurs + * @throws CoreException + *
    + *
  • Core.ERROR_WRONG_PASSWORD - if + * encoding/encryption fails;
  • + *
  • Core.ERROR_CANCELLATION - if the operation + * is cancelled
  • + *
+ * @throws IllegalArgumentException + * if the stream or file entry is null + */ + OutputStream normalizeOutputStream(OutputStream stream, + IFileEntry fileEntry) throws IOException, CoreException; + + /** + * Converts the specified input stream into an decoded/decrypted one that + * can be used for reading normal entry content. The specified file entry's + * encoding/encryption data will be used during converting and reading + * operations. + * + * @param stream + * the {@link InputStream} that reads data from the target + * storage + * @param fileEntry + * the {@link IFileEntry} that provides encoding/encryption data + * @return a new {@link InputStream} that reads encoded/encrypted data from + * the given stream and decodes/decrypts them + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if decoding/decryption fails + * @throws IllegalArgumentException + * if the stream or file entry is null + */ + InputStream normalizeInputStream(InputStream stream, IFileEntry fileEntry) + throws IOException, CoreException; + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java index c38edb8ab..197189647 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java @@ -1,43 +1,43 @@ -package org.xmind.core; - -import java.util.List; -import java.util.Set; - -/** - * @author Jason Wong - */ -public interface IExtensionElement { - - List getChildren(); - - List getChildren(String elementName); - - T createChild(String elementName); - - T getCreatedChild(String elementName); - - T getFirstChild(String elementName); - - T getParent(); - - void addChild(T child, int index); - - void deleteChild(T child); - - void deleteChildren(String elementName); - - void deleteChildren(); - - String getName(); - - Set getAttributeKeys(); - - String getAttribute(String attrName); - - void setAttribute(String attrName, String attrValue); - - String getTextContent(); - - void setTextContent(String text); - -} +package org.xmind.core; + +import java.util.List; +import java.util.Set; + +/** + * @author Jason Wong + */ +public interface IExtensionElement { + + List getChildren(); + + List getChildren(String elementName); + + T createChild(String elementName); + + T getCreatedChild(String elementName); + + T getFirstChild(String elementName); + + T getParent(); + + void addChild(T child, int index); + + void deleteChild(T child); + + void deleteChildren(String elementName); + + void deleteChildren(); + + String getName(); + + Set getAttributeKeys(); + + String getAttribute(String attrName); + + void setAttribute(String attrName, String attrValue); + + String getTextContent(); + + void setTextContent(String text); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IFileEntry.java b/bundles/org.xmind.core/src/org/xmind/core/IFileEntry.java index 685dcb638..843eff3e5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IFileEntry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IFileEntry.java @@ -1,221 +1,221 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; - -/** - * A file entry represents a file-like data block included in a workbook. A file - * entry is identified by a relative path string, i.e. not starting - * with a slash('/'). A file entry should be referenced to keep its - * existence in the workbook, and non-referenced file entries will be excluded - * when the workbook is serialized. However, clients typically need not - * to explicitly call increaseReference() if they use - * xap: links as topic hyperlinks, notes hyperinks, etc. - * - * @author Frank Shaka - */ -public interface IFileEntry extends IAdaptable, IWorkbookComponent { - - /** - * Returns the path of this file entry. This path can be used to find this - * file entry in the owner workbook's {@link IManifest#getFileEntry(String) - * manifest}. File entries that have the same paths should be regarded as - * equal instances. - * - * @return the path - */ - String getPath(); - - /** - * Returns the media type of this file entry. This attribute helps identify - * what type this file entry's content should be. For entries that is a - * directory or does not have a obvious media type, an empty string is - * returned. - * - * @return the media type, or an empty string, never null - */ - String getMediaType(); - - /** - * TODO java doc - * - * @return - */ - boolean hasBeenReferred(); - - /** - * TODO java doc - * - * @return - */ - int getReferenceCount(); - - /** - * TODO java doc - * - */ - void increaseReference(); - - /** - * TODO java doc - * - */ - void decreaseReference(); - - /** - * Checks whether this file entry is available for reading. Calls to - * {@link #openInputStream()} will fail if this file entry is not available - * for reading. - * - * @return true if this file entry is available for reading, or - * false otherwise - */ - boolean canRead(); - - /** - * Checks whether this file entry is available for writing. Calls to - * {@link #openOutputStream()} will fail if this file entry is not available - * for writing. - * - * @return true if this file entry is available for writing, or - * false otherwise - */ - boolean canWrite(); - - /** - * Opens a new input stream for reading data from this file entry. - * - * @return an input stream for this file entry - * @throws IOException - * if I/O error occurs, this entry is not found in storage, or - * this entry is a directory - */ - InputStream openInputStream() throws IOException; - - /** - * Opens a new output stream for writing data to this file entry. - * - * @return an output stream for this file entry - * @throws IOException - * if I/O error occurs, or this entry is not available for - * writing - */ - OutputStream openOutputStream() throws IOException; - - /** - * Checks whether this file entry represents a directory. An entry is a - * directory if its path has a trailing slash('/'). A directory entry is - * neither readable nor writable, but has sub-entries. - * - * @return true if this entry is a directory entry, or - * false otherwise - * @see #getSubEntries() - * @see #iterSubEntries() - */ - boolean isDirectory(); - - /** - * TODO java doc - * - * @return - */ - List getSubEntries(); - - /** - * TODO java doc - * - * @return - */ - Iterator iterSubEntries(); - - /** - * Returns the time (in milliseconds since midnight, January 1, 1970 UTC) - * this entry last modified. - * - * @return the time this entry last modified, or -1 if this - * entry is not accessible or some error occurred while getting the - * time - */ - long getTime(); - - /** - * TODO java doc - * - * @param time - */ - void setTime(long time); - - /** - * Returns the size (in bytes) of this entry's content. - * - * @return the size of this entry's content, or -1 if this - * entry is not accessible or some error occurred while getting the - * size - */ - long getSize(); - - /** - * TODO java doc - * - * @return - */ - IEncryptionData getEncryptionData(); - - /** - * TODO java doc - * - * @return - */ - IEncryptionData createEncryptionData(); - - /** - * TODO java doc - * - */ - void deleteEncryptionData(); - - /** - * Opens a new input stream for reading data from this file entry. - * - * @deprecated For diagnostic purpose, this method is not - * recommended any more. Use {@link #canRead()} to test - * readability and {@link #openInputStream()} to create a byte - * stream for reading. - * - * @return an input stream for this file entry, or null if the - * input stream is not available - */ - @Deprecated - InputStream getInputStream(); - - /** - * Opens a new output stream for writing data to this file entry. - * - * @deprecated For diagnostic purpose, this method is not - * recommended any more. Use {@link #canWrite()} to test - * writability and {@link #openOutputStream()} to create a byte - * stream for writing. - * - * @return an output stream for this file entry, or null if the - * output stream is not available - */ - @Deprecated - OutputStream getOutputStream(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +/** + * A file entry represents a file-like data block included in a workbook. A file + * entry is identified by a relative path string, i.e. not starting + * with a slash('/'). A file entry should be referenced to keep its + * existence in the workbook, and non-referenced file entries will be excluded + * when the workbook is serialized. However, clients typically need not + * to explicitly call increaseReference() if they use + * xap: links as topic hyperlinks, notes hyperinks, etc. + * + * @author Frank Shaka + */ +public interface IFileEntry extends IAdaptable, IWorkbookComponent { + + /** + * Returns the path of this file entry. This path can be used to find this + * file entry in the owner workbook's {@link IManifest#getFileEntry(String) + * manifest}. File entries that have the same paths should be regarded as + * equal instances. + * + * @return the path + */ + String getPath(); + + /** + * Returns the media type of this file entry. This attribute helps identify + * what type this file entry's content should be. For entries that is a + * directory or does not have a obvious media type, an empty string is + * returned. + * + * @return the media type, or an empty string, never null + */ + String getMediaType(); + + /** + * TODO java doc + * + * @return + */ + boolean hasBeenReferred(); + + /** + * TODO java doc + * + * @return + */ + int getReferenceCount(); + + /** + * TODO java doc + * + */ + void increaseReference(); + + /** + * TODO java doc + * + */ + void decreaseReference(); + + /** + * Checks whether this file entry is available for reading. Calls to + * {@link #openInputStream()} will fail if this file entry is not available + * for reading. + * + * @return true if this file entry is available for reading, or + * false otherwise + */ + boolean canRead(); + + /** + * Checks whether this file entry is available for writing. Calls to + * {@link #openOutputStream()} will fail if this file entry is not available + * for writing. + * + * @return true if this file entry is available for writing, or + * false otherwise + */ + boolean canWrite(); + + /** + * Opens a new input stream for reading data from this file entry. + * + * @return an input stream for this file entry + * @throws IOException + * if I/O error occurs, this entry is not found in storage, or + * this entry is a directory + */ + InputStream openInputStream() throws IOException; + + /** + * Opens a new output stream for writing data to this file entry. + * + * @return an output stream for this file entry + * @throws IOException + * if I/O error occurs, or this entry is not available for + * writing + */ + OutputStream openOutputStream() throws IOException; + + /** + * Checks whether this file entry represents a directory. An entry is a + * directory if its path has a trailing slash('/'). A directory entry is + * neither readable nor writable, but has sub-entries. + * + * @return true if this entry is a directory entry, or + * false otherwise + * @see #getSubEntries() + * @see #iterSubEntries() + */ + boolean isDirectory(); + + /** + * TODO java doc + * + * @return + */ + List getSubEntries(); + + /** + * TODO java doc + * + * @return + */ + Iterator iterSubEntries(); + + /** + * Returns the time (in milliseconds since midnight, January 1, 1970 UTC) + * this entry last modified. + * + * @return the time this entry last modified, or -1 if this + * entry is not accessible or some error occurred while getting the + * time + */ + long getTime(); + + /** + * TODO java doc + * + * @param time + */ + void setTime(long time); + + /** + * Returns the size (in bytes) of this entry's content. + * + * @return the size of this entry's content, or -1 if this + * entry is not accessible or some error occurred while getting the + * size + */ + long getSize(); + + /** + * TODO java doc + * + * @return + */ + IEncryptionData getEncryptionData(); + + /** + * TODO java doc + * + * @return + */ + IEncryptionData createEncryptionData(); + + /** + * TODO java doc + * + */ + void deleteEncryptionData(); + + /** + * Opens a new input stream for reading data from this file entry. + * + * @deprecated For diagnostic purpose, this method is not + * recommended any more. Use {@link #canRead()} to test + * readability and {@link #openInputStream()} to create a byte + * stream for reading. + * + * @return an input stream for this file entry, or null if the + * input stream is not available + */ + @Deprecated + InputStream getInputStream(); + + /** + * Opens a new output stream for writing data to this file entry. + * + * @deprecated For diagnostic purpose, this method is not + * recommended any more. Use {@link #canWrite()} to test + * writability and {@link #openOutputStream()} to create a byte + * stream for writing. + * + * @return an output stream for this file entry, or null if the + * output stream is not available + */ + @Deprecated + OutputStream getOutputStream(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IFileEntryFilter.java b/bundles/org.xmind.core/src/org/xmind/core/IFileEntryFilter.java index 87e741078..fb90e3f8e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IFileEntryFilter.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IFileEntryFilter.java @@ -1,15 +1,15 @@ -package org.xmind.core; - -public interface IFileEntryFilter { - - /** - * Returns true to indicate the path passes the filter. - * - * @param path - * @param mediaType - * @param isDirectory - * @return - */ - boolean select(String path, String mediaType, boolean isDirectory); - +package org.xmind.core; + +public interface IFileEntryFilter { + + /** + * Returns true to indicate the path passes the filter. + * + * @param path + * @param mediaType + * @param isDirectory + * @return + */ + boolean select(String path, String mediaType, boolean isDirectory); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IHtmlNotesContent.java b/bundles/org.xmind.core/src/org/xmind/core/IHtmlNotesContent.java index cd6211579..811a6ebba 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IHtmlNotesContent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IHtmlNotesContent.java @@ -1,34 +1,34 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.util.List; - -public interface IHtmlNotesContent extends INotesContent { - - List getParagraphs(); - - void addParagraph(IParagraph paragraph); - - void removeParagraph(IParagraph paragraph); - - IParagraph createParagraph(); - - ITextSpan createTextSpan(String textContent); - - IImageSpan createImageSpan(String source); - - IHyperlinkSpan createHyperlinkSpan(String href); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.util.List; + +public interface IHtmlNotesContent extends INotesContent { + + List getParagraphs(); + + void addParagraph(IParagraph paragraph); + + void removeParagraph(IParagraph paragraph); + + IParagraph createParagraph(); + + ITextSpan createTextSpan(String textContent); + + IImageSpan createImageSpan(String source); + + IHyperlinkSpan createHyperlinkSpan(String href); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IIdFactory.java b/bundles/org.xmind.core/src/org/xmind/core/IIdFactory.java index e3696cbcb..180970094 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IIdFactory.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IIdFactory.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IIdFactory { - - String createId(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IIdFactory { + + String createId(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IIdentifiable.java b/bundles/org.xmind.core/src/org/xmind/core/IIdentifiable.java index 66fcdef38..b21a7b6b6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IIdentifiable.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IIdentifiable.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IIdentifiable { - - String getId(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IIdentifiable { + + String getId(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IImageSpan.java b/bundles/org.xmind.core/src/org/xmind/core/IImageSpan.java index e285a2acb..8bbb4a9d9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IImageSpan.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IImageSpan.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IImageSpan extends ISpan { - - String getSource(); - - void setSource(String source); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IImageSpan extends ISpan { + + String getSource(); + + void setSource(String source); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IManifest.java b/bundles/org.xmind.core/src/org/xmind/core/IManifest.java index b731683fe..16e06296e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IManifest.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IManifest.java @@ -1,260 +1,260 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.List; - -/** - * A manifest manages file-like data blocks, identified as file entries - * , included in the owner workbook. It provides methods to import external - * files/streams into the workbook storage, and manages a list of file entries - * that have at least one reference count, in a way that, when a file - * entry's reference count is reduced to zero, it is automatically removed from - * this list, and, when its reference count is increased from zero, it is - * automatically added to this list. - * - * @author Frank Shaka - * - */ -public interface IManifest extends IWorkbookComponent, IAdaptable { - - String getPasswordHint(); - - void setPasswordHint(String hint); - - /** - * Lists all existing file entries that has at least one reference. - * - * @return referenced file entries - */ - List getFileEntries(); - - /** - * Returns an iterator to iterate over all existing file entries that has at - * least one reference. - * - * @return an iterator for referenced file entries - */ - Iterator iterFileEntries(); - - /** - * Returns an iterator to iterate over all existing file entries that has at - * least one reference and passes the given filter. - * - * @param filter - * an object to determine whether a file entry should be included - * in the results, or null to accept all - * @return an iterator for filtered and referenced file entries - */ - Iterator iterFileEntries(IFileEntryFilter filter); - - /** - * Finds and returns a file entry that has the desired path, no matter it's - * referenced or not. - * - * @param path - * the path of the desired file entry - * @return a file entry that has the desired path - */ - IFileEntry getFileEntry(String path); - - /** - * Creates a new file entry and copies the content of the given stream to - * that entry. If the source file name is not null, its - * extension part will be appended to the created entry's file name and used - * to guess the media type of that entry. The entry's time will be set the - * time when it's created. - * - * @param stream - * the source stream containing entry data - * @param sourceName - * a suggested name, typically the source file's name or path, or - * null to indicate no extension part - * @return a new file entry - * @throws IOException - * if any I/O error occurs - * @throws IllegalArgumentException - * if the source stream is null - */ - IFileEntry createAttachmentFromStream(InputStream stream, String sourceName) - throws IOException; - - /** - * Creates a new file entry and copies the content of the given stream to - * that entry. If the source file name is not null, its - * extension part will be appended to the created entry's file name. The - * entry's media type will be set the given one, and it time will be set the - * time when it's created. - * - * @param stream - * the source stream containing entry data - * @param sourceName - * a suggested name, typically the source file's name or path, or - * null to indicate no extension part - * @param mediaType - * a suggested media type of the entry, or null to - * let the manifest guess a media type - * @return a new file entry - * @throws IOException - * if any I/O error occurs - * @throws IllegalArgumentException - * if the source stream is null - */ - IFileEntry createAttachmentFromStream(InputStream stream, String sourceName, - String mediaType) throws IOException; - - /** - * Creates a new file entry and copies the content of the given file to that - * entry. The source file's extension name will be appended to the created - * entry's file name and used to guess the media type of that entry. The - * entry's time will be set to the time when it's created. - * - *

- * This method is simply a convenient way of 1) opening a file input stream - * using the given file path, 2) calling - * {@link #createAttachmentFromStream(InputStream, String)} and 3) closing - * the file input stream. - *

- * - * @param sourcePath - * the path of a local file - * @return a new file entry - * @throws IOException - * if any I/O error occurs - * @throws IllegalArgumentException - * if the source path is null - */ - IFileEntry createAttachmentFromFilePath(String sourcePath) - throws IOException; - - /** - * Creates a new file entry and copies the content of the given file to that - * entry. The source file's extension name will be appended to the created - * entry's file name. The entry's media type will be set the given one, and - * it time will be set to the time when it's created. - * - *

- * This method is simply a convenient way of 1) opening a file input stream - * using the given file path, 2) calling - * {@link #createAttachmentFromStream(InputStream, String, String)} and 3) - * closing the file input stream. - *

- * - * @param sourcePath - * the path of a local file - * @param mediaType - * a suggested media type of the entry, or null to - * let the manifest guess a media type - * @return a new file entry - * @throws IOException - * if any I/O error occurs - * @throws IllegalArgumentException - * if the source path is null - */ - IFileEntry createAttachmentFromFilePath(String sourcePath, String mediaType) - throws IOException; - - /** - * Creates a new file entry using the given path as its path. - * - *

- * NOTE: Use this method with CAUTION, as the way of storing internal - * resources by a workbook may change over time or across implementations. - *

- * - * @param path - * an internal path to the desired file entry - * @return a new file entry, or an existing one if the path already exists - * @throws IllegalArgumentException - * if the path is null - */ - IFileEntry createFileEntry(String path); - - /** - * Creates a new file entry using the given path as its path and the given - * media type as its media type. - * - *

- * NOTE: Use this method with CAUTION, as the way of storing internal - * resources by a workbook may change over time or across implementations. - *

- * - * @param path - * an internal path to the desired file entry - * @param mediaType - * the media type of the new file entry, or null to - * indicate no media type - * @return a new file entry, or an existing one if the path already exists - * @throws IllegalArgumentException - * if the path is null - */ - IFileEntry createFileEntry(String path, String mediaType); - - /** - * TODO add java docs - * - * @param sourceEntry - * @param targetPath - * @return - * @throws IOException - */ - IFileEntry cloneEntry(IFileEntry sourceEntry, String targetPath) - throws IOException; - - /** - * TODO add java docs - * - * @param sourceEntry - * @return - * @throws IOException - */ - IFileEntry cloneEntryAsAttachment(IFileEntry sourceEntry) - throws IOException; - - /** - * - * @param entryPath - * @return - */ - IEncryptionData getEncryptionData(String entryPath); - - /** - * @deprecated No need to delete file entries. - * @param path - * @return - */ - @Deprecated - boolean deleteFileEntry(String path); - - /** - * @deprecated Use one of createAttachmentFromXXXX methods. - * @param sourcePath - * @return - */ - @Deprecated - String makeAttachmentPath(String sourcePath); - - /** - * @deprecated Use one of createAttachmentFromXXX methods. - * @param source - * @param directory - * @return - */ - @Deprecated - String makeAttachmentPath(String source, boolean directory); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.List; + +/** + * A manifest manages file-like data blocks, identified as file entries + * , included in the owner workbook. It provides methods to import external + * files/streams into the workbook storage, and manages a list of file entries + * that have at least one reference count, in a way that, when a file + * entry's reference count is reduced to zero, it is automatically removed from + * this list, and, when its reference count is increased from zero, it is + * automatically added to this list. + * + * @author Frank Shaka + * + */ +public interface IManifest extends IWorkbookComponent, IAdaptable { + + String getPasswordHint(); + + void setPasswordHint(String hint); + + /** + * Lists all existing file entries that has at least one reference. + * + * @return referenced file entries + */ + List getFileEntries(); + + /** + * Returns an iterator to iterate over all existing file entries that has at + * least one reference. + * + * @return an iterator for referenced file entries + */ + Iterator iterFileEntries(); + + /** + * Returns an iterator to iterate over all existing file entries that has at + * least one reference and passes the given filter. + * + * @param filter + * an object to determine whether a file entry should be included + * in the results, or null to accept all + * @return an iterator for filtered and referenced file entries + */ + Iterator iterFileEntries(IFileEntryFilter filter); + + /** + * Finds and returns a file entry that has the desired path, no matter it's + * referenced or not. + * + * @param path + * the path of the desired file entry + * @return a file entry that has the desired path + */ + IFileEntry getFileEntry(String path); + + /** + * Creates a new file entry and copies the content of the given stream to + * that entry. If the source file name is not null, its + * extension part will be appended to the created entry's file name and used + * to guess the media type of that entry. The entry's time will be set the + * time when it's created. + * + * @param stream + * the source stream containing entry data + * @param sourceName + * a suggested name, typically the source file's name or path, or + * null to indicate no extension part + * @return a new file entry + * @throws IOException + * if any I/O error occurs + * @throws IllegalArgumentException + * if the source stream is null + */ + IFileEntry createAttachmentFromStream(InputStream stream, String sourceName) + throws IOException; + + /** + * Creates a new file entry and copies the content of the given stream to + * that entry. If the source file name is not null, its + * extension part will be appended to the created entry's file name. The + * entry's media type will be set the given one, and it time will be set the + * time when it's created. + * + * @param stream + * the source stream containing entry data + * @param sourceName + * a suggested name, typically the source file's name or path, or + * null to indicate no extension part + * @param mediaType + * a suggested media type of the entry, or null to + * let the manifest guess a media type + * @return a new file entry + * @throws IOException + * if any I/O error occurs + * @throws IllegalArgumentException + * if the source stream is null + */ + IFileEntry createAttachmentFromStream(InputStream stream, String sourceName, + String mediaType) throws IOException; + + /** + * Creates a new file entry and copies the content of the given file to that + * entry. The source file's extension name will be appended to the created + * entry's file name and used to guess the media type of that entry. The + * entry's time will be set to the time when it's created. + * + *

+ * This method is simply a convenient way of 1) opening a file input stream + * using the given file path, 2) calling + * {@link #createAttachmentFromStream(InputStream, String)} and 3) closing + * the file input stream. + *

+ * + * @param sourcePath + * the path of a local file + * @return a new file entry + * @throws IOException + * if any I/O error occurs + * @throws IllegalArgumentException + * if the source path is null + */ + IFileEntry createAttachmentFromFilePath(String sourcePath) + throws IOException; + + /** + * Creates a new file entry and copies the content of the given file to that + * entry. The source file's extension name will be appended to the created + * entry's file name. The entry's media type will be set the given one, and + * it time will be set to the time when it's created. + * + *

+ * This method is simply a convenient way of 1) opening a file input stream + * using the given file path, 2) calling + * {@link #createAttachmentFromStream(InputStream, String, String)} and 3) + * closing the file input stream. + *

+ * + * @param sourcePath + * the path of a local file + * @param mediaType + * a suggested media type of the entry, or null to + * let the manifest guess a media type + * @return a new file entry + * @throws IOException + * if any I/O error occurs + * @throws IllegalArgumentException + * if the source path is null + */ + IFileEntry createAttachmentFromFilePath(String sourcePath, String mediaType) + throws IOException; + + /** + * Creates a new file entry using the given path as its path. + * + *

+ * NOTE: Use this method with CAUTION, as the way of storing internal + * resources by a workbook may change over time or across implementations. + *

+ * + * @param path + * an internal path to the desired file entry + * @return a new file entry, or an existing one if the path already exists + * @throws IllegalArgumentException + * if the path is null + */ + IFileEntry createFileEntry(String path); + + /** + * Creates a new file entry using the given path as its path and the given + * media type as its media type. + * + *

+ * NOTE: Use this method with CAUTION, as the way of storing internal + * resources by a workbook may change over time or across implementations. + *

+ * + * @param path + * an internal path to the desired file entry + * @param mediaType + * the media type of the new file entry, or null to + * indicate no media type + * @return a new file entry, or an existing one if the path already exists + * @throws IllegalArgumentException + * if the path is null + */ + IFileEntry createFileEntry(String path, String mediaType); + + /** + * TODO add java docs + * + * @param sourceEntry + * @param targetPath + * @return + * @throws IOException + */ + IFileEntry cloneEntry(IFileEntry sourceEntry, String targetPath) + throws IOException; + + /** + * TODO add java docs + * + * @param sourceEntry + * @return + * @throws IOException + */ + IFileEntry cloneEntryAsAttachment(IFileEntry sourceEntry) + throws IOException; + + /** + * + * @param entryPath + * @return + */ + IEncryptionData getEncryptionData(String entryPath); + + /** + * @deprecated No need to delete file entries. + * @param path + * @return + */ + @Deprecated + boolean deleteFileEntry(String path); + + /** + * @deprecated Use one of createAttachmentFromXXXX methods. + * @param sourcePath + * @return + */ + @Deprecated + String makeAttachmentPath(String sourcePath); + + /** + * @deprecated Use one of createAttachmentFromXXX methods. + * @param source + * @param directory + * @return + */ + @Deprecated + String makeAttachmentPath(String source, boolean directory); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IMeta.java b/bundles/org.xmind.core/src/org/xmind/core/IMeta.java index bd562e567..b6c71f70d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IMeta.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IMeta.java @@ -1,116 +1,116 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.util.Set; - -public interface IMeta extends IAdaptable, IWorkbookComponent { - - String SEP = "/"; //$NON-NLS-1$ - - String AUTHOR = "Author"; //$NON-NLS-1$ - - String DESCRIPTION = "Description"; //$NON-NLS-1$ - - String THUMBNAIL = "Thumbnail"; //$NON-NLS-1$ - - String ORIGIN_X = THUMBNAIL + SEP + "Origin" + SEP + "X"; //$NON-NLS-1$ //$NON-NLS-2$ - - String ORIGIN_Y = THUMBNAIL + SEP + "Origin" + SEP + "Y"; //$NON-NLS-1$ //$NON-NLS-2$ - - String BACKGROUND_COLOR = THUMBNAIL + SEP + "BackgroundColor"; //$NON-NLS-1$ - - String CREATOR = "Creator"; //$NON-NLS-1$ - - String CREATOR_NAME = CREATOR + SEP + "Name"; //$NON-NLS-1$ - - String CREATOR_VERSION = CREATOR + SEP + "Version"; //$NON-NLS-1$ - - String CREATE = "Create"; //$NON-NLS-1$ - - String CREATED_TIME = CREATE + SEP + "Time"; //$NON-NLS-1$ - - String AUTHOR_NAME = AUTHOR + SEP + "Name"; //$NON-NLS-1$ - - String AUTHOR_EMAIL = AUTHOR + SEP + "Email"; //$NON-NLS-1$ - - String AUTHOR_ORG = AUTHOR + SEP + "Org"; //$NON-NLS-1$ - - /** - * Key path prefix for all configuration keys. - */ - String CONFIGURATIONS = "Configurations"; //$NON-NLS-1$ - - /** - *

- * Key path for configuration of whether to save revisions automatically. - *

- * Values: "Yes", "No" - */ - String CONFIG_AUTO_REVISION_GENERATION = CONFIGURATIONS + SEP - + "AutoRevisionGeneration"; //$NON-NLS-1$ - - String V_YES = "Yes"; //$NON-NLS-1$ - String V_NO = "No"; //$NON-NLS-1$ - - /** - * - * @param keyPath - * @return - */ - String getValue(String keyPath); - - /** - * - * @param key - * @param value - */ - void setValue(String keyPath, String value); - - /** - * - * @return - */ - Set getKeyPaths(); - - /** - * @deprecated - * @param key - * @return - */ - IMetaData[] getMetaData(String key); - - /** - * @deprecated - * - * @param key - * @return - */ - IMetaData createMetaData(String key); - - /** - * @deprecated - * - * @param data - */ - void addMetaData(IMetaData data); - - /** - * @deprecated - * - * @param data - */ - void removeMetaData(IMetaData data); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.util.Set; + +public interface IMeta extends IAdaptable, IWorkbookComponent { + + String SEP = "/"; //$NON-NLS-1$ + + String AUTHOR = "Author"; //$NON-NLS-1$ + + String DESCRIPTION = "Description"; //$NON-NLS-1$ + + String THUMBNAIL = "Thumbnail"; //$NON-NLS-1$ + + String ORIGIN_X = THUMBNAIL + SEP + "Origin" + SEP + "X"; //$NON-NLS-1$ //$NON-NLS-2$ + + String ORIGIN_Y = THUMBNAIL + SEP + "Origin" + SEP + "Y"; //$NON-NLS-1$ //$NON-NLS-2$ + + String BACKGROUND_COLOR = THUMBNAIL + SEP + "BackgroundColor"; //$NON-NLS-1$ + + String CREATOR = "Creator"; //$NON-NLS-1$ + + String CREATOR_NAME = CREATOR + SEP + "Name"; //$NON-NLS-1$ + + String CREATOR_VERSION = CREATOR + SEP + "Version"; //$NON-NLS-1$ + + String CREATE = "Create"; //$NON-NLS-1$ + + String CREATED_TIME = CREATE + SEP + "Time"; //$NON-NLS-1$ + + String AUTHOR_NAME = AUTHOR + SEP + "Name"; //$NON-NLS-1$ + + String AUTHOR_EMAIL = AUTHOR + SEP + "Email"; //$NON-NLS-1$ + + String AUTHOR_ORG = AUTHOR + SEP + "Org"; //$NON-NLS-1$ + + /** + * Key path prefix for all configuration keys. + */ + String CONFIGURATIONS = "Configurations"; //$NON-NLS-1$ + + /** + *

+ * Key path for configuration of whether to save revisions automatically. + *

+ * Values: "Yes", "No" + */ + String CONFIG_AUTO_REVISION_GENERATION = CONFIGURATIONS + SEP + + "AutoRevisionGeneration"; //$NON-NLS-1$ + + String V_YES = "Yes"; //$NON-NLS-1$ + String V_NO = "No"; //$NON-NLS-1$ + + /** + * + * @param keyPath + * @return + */ + String getValue(String keyPath); + + /** + * + * @param key + * @param value + */ + void setValue(String keyPath, String value); + + /** + * + * @return + */ + Set getKeyPaths(); + + /** + * @deprecated + * @param key + * @return + */ + IMetaData[] getMetaData(String key); + + /** + * @deprecated + * + * @param key + * @return + */ + IMetaData createMetaData(String key); + + /** + * @deprecated + * + * @param data + */ + void addMetaData(IMetaData data); + + /** + * @deprecated + * + * @param data + */ + void removeMetaData(IMetaData data); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IModifiable.java b/bundles/org.xmind.core/src/org/xmind/core/IModifiable.java index 9a4b0d624..715a42a08 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IModifiable.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IModifiable.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core; - -/** - * @author Frank Shaka - * - */ -public interface IModifiable { - - long getModifiedTime(); - - String getModifiedBy(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core; + +/** + * @author Frank Shaka + * + */ +public interface IModifiable { + + long getModifiedTime(); + + String getModifiedBy(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/INamed.java b/bundles/org.xmind.core/src/org/xmind/core/INamed.java index 3a15b427c..cd1114449 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/INamed.java +++ b/bundles/org.xmind.core/src/org/xmind/core/INamed.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface INamed { - - String getName(); - - void setName(String name); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface INamed { + + String getName(); + + void setName(String name); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IParagraph.java b/bundles/org.xmind.core/src/org/xmind/core/IParagraph.java index 63287850c..9d9343754 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IParagraph.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IParagraph.java @@ -1,21 +1,21 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import org.xmind.core.style.IStyled; - -public interface IParagraph extends IAdaptable, IStyled, IWorkbookComponent, - ISpanList { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import org.xmind.core.style.IStyled; + +public interface IParagraph extends IAdaptable, IStyled, IWorkbookComponent, + ISpanList { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IPlainNotesContent.java b/bundles/org.xmind.core/src/org/xmind/core/IPlainNotesContent.java index 68abee20a..a3d918491 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IPlainNotesContent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IPlainNotesContent.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IPlainNotesContent extends INotesContent { - - String getTextContent(); - - void setTextContent(String textContent); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IPlainNotesContent extends INotesContent { + + String getTextContent(); + + void setTextContent(String textContent); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IPositioned.java b/bundles/org.xmind.core/src/org/xmind/core/IPositioned.java index 785b762e8..dc96cb62b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IPositioned.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IPositioned.java @@ -1,42 +1,42 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import org.xmind.core.util.Point; - -public interface IPositioned { - - /** - * @param x - * @param y - */ - void setPosition(int x, int y); - - /** - * @return The position of this object; or null to indicate no - * position has been set. - */ - Point getPosition(); - - /** - * @param position - */ - void setPosition(Point position); - - /** - * @return - */ - boolean hasPosition(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import org.xmind.core.util.Point; + +public interface IPositioned { + + /** + * @param x + * @param y + */ + void setPosition(int x, int y); + + /** + * @return The position of this object; or null to indicate no + * position has been set. + */ + Point getPosition(); + + /** + * @param position + */ + void setPosition(Point position); + + /** + * @return + */ + boolean hasPosition(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IRelationship.java b/bundles/org.xmind.core/src/org/xmind/core/IRelationship.java index 06b7ae0fe..5383c46a8 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IRelationship.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IRelationship.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import org.xmind.core.style.IStyled; - -/** - * @author briansun - * - */ -public interface IRelationship extends IAdaptable, IIdentifiable, ITitled, - ISheetComponent, IStyled, IModifiable { - - /** - * @return - */ - IRelationshipEnd getEnd1(); - - /** - * @return - */ - String getEnd1Id(); - - /** - * @return - */ - IRelationshipEnd getEnd2(); - - /** - * @return - */ - String getEnd2Id(); - - /** - * @return - */ - ISheet getParent(); - - /** - * @param id - */ - void setEnd1Id(String id); - - /** - * @param id - */ - void setEnd2Id(String id); - - /** - * @return - */ - boolean checkAvailable(); - - /** - * - * @param index - * @return - */ - IControlPoint getControlPoint(int index); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import org.xmind.core.style.IStyled; + +/** + * @author briansun + * + */ +public interface IRelationship extends IAdaptable, IIdentifiable, ITitled, + ISheetComponent, IStyled, IModifiable { + + /** + * @return + */ + IRelationshipEnd getEnd1(); + + /** + * @return + */ + String getEnd1Id(); + + /** + * @return + */ + IRelationshipEnd getEnd2(); + + /** + * @return + */ + String getEnd2Id(); + + /** + * @return + */ + ISheet getParent(); + + /** + * @param id + */ + void setEnd1Id(String id); + + /** + * @param id + */ + void setEnd2Id(String id); + + /** + * @return + */ + boolean checkAvailable(); + + /** + * + * @param index + * @return + */ + IControlPoint getControlPoint(int index); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IRelationshipEnd.java b/bundles/org.xmind.core/src/org/xmind/core/IRelationshipEnd.java index b95eae7aa..d68a3b527 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IRelationshipEnd.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IRelationshipEnd.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -/** - * @author briansun - * - */ -public interface IRelationshipEnd extends IIdentifiable, ISheetComponent { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +/** + * @author briansun + * + */ +public interface IRelationshipEnd extends IIdentifiable, ISheetComponent { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IResourceRef.java b/bundles/org.xmind.core/src/org/xmind/core/IResourceRef.java index 5bdabb874..11cca8f21 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IResourceRef.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IResourceRef.java @@ -1,41 +1,41 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IResourceRef extends IAdaptable, IWorkbookComponent { - - /** - * Resource type for file entries in a workbook. - */ - String FILE_ENTRY = "file-entry"; //$NON-NLS-1$ - - /** - * - * @return - */ - String getType(); - - /** - * - * @return - */ - String getResourceId(); - - /** - * - * @return - */ - Object getResource(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IResourceRef extends IAdaptable, IWorkbookComponent { + + /** + * Resource type for file entries in a workbook. + */ + String FILE_ENTRY = "file-entry"; //$NON-NLS-1$ + + /** + * + * @return + */ + String getType(); + + /** + * + * @return + */ + String getResourceId(); + + /** + * + * @return + */ + Object getResource(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IRevision.java b/bundles/org.xmind.core/src/org/xmind/core/IRevision.java index ac7d6e3bd..136ddf501 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IRevision.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IRevision.java @@ -1,97 +1,97 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core; - -/** - * A revision of the resource. - * - *

- * Currently only sheet resource with content type IRevision.SHEET - * is supported. - *

- * - * @author Frank Shaka <frank@xmind.net> - */ -public interface IRevision extends IAdaptable, IWorkbookComponent, - Comparable { - - /** - * Resource type for a sheet resource. Value is "sheet". - *

- * Content with this type is safe to be casted into {@link ISheet} objects. - *

- */ - String SHEET = "application/vnd.xmind.sheet"; //$NON-NLS-1$ - - /** - * Gets the type of the content. - * - * @return the revision content type - * @see IRevision#SHEET - */ - String getContentType(); - - /** - * Get the ID of the corresponding resource. - * - * @return - */ - String getResourceId(); - - /** - * Gets the number of this revision. - * - * @return the revision number - */ - int getRevisionNumber(); - - /** - * Gets the timestamp of this revision. The timestamp is represented in UNIX - * epoch milliseconds, which marks the time when this revision is added to - * the workbook. - * - * @return the revision timestamp - */ - long getTimestamp(); - - /** - * Gets the content of this revision. If content is not available, returns - * null. - * - *

- * Note that the object returned by this method is a snapshot of the - * original resource. - *

- * - *

- * The returned object's class is determined by the resource's content type. - * For example, an object with {@link IRevision#SHEET} as its content type - * is safe to be casted into an {@link ISheet} object. - *

- * - * @return the revision content, or null if no content is - * available - * @see IRevision#getContentType() - */ - IAdaptable getContent(); - - /** - * Gets the manager that manages this revision. - * - * @return the manager of this revision - */ - IRevisionManager getOwnedManager(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core; + +/** + * A revision of the resource. + * + *

+ * Currently only sheet resource with content type IRevision.SHEET + * is supported. + *

+ * + * @author Frank Shaka <frank@xmind.net> + */ +public interface IRevision extends IAdaptable, IWorkbookComponent, + Comparable { + + /** + * Resource type for a sheet resource. Value is "sheet". + *

+ * Content with this type is safe to be casted into {@link ISheet} objects. + *

+ */ + String SHEET = "application/vnd.xmind.sheet"; //$NON-NLS-1$ + + /** + * Gets the type of the content. + * + * @return the revision content type + * @see IRevision#SHEET + */ + String getContentType(); + + /** + * Get the ID of the corresponding resource. + * + * @return + */ + String getResourceId(); + + /** + * Gets the number of this revision. + * + * @return the revision number + */ + int getRevisionNumber(); + + /** + * Gets the timestamp of this revision. The timestamp is represented in UNIX + * epoch milliseconds, which marks the time when this revision is added to + * the workbook. + * + * @return the revision timestamp + */ + long getTimestamp(); + + /** + * Gets the content of this revision. If content is not available, returns + * null. + * + *

+ * Note that the object returned by this method is a snapshot of the + * original resource. + *

+ * + *

+ * The returned object's class is determined by the resource's content type. + * For example, an object with {@link IRevision#SHEET} as its content type + * is safe to be casted into an {@link ISheet} object. + *

+ * + * @return the revision content, or null if no content is + * available + * @see IRevision#getContentType() + */ + IAdaptable getContent(); + + /** + * Gets the manager that manages this revision. + * + * @return the manager of this revision + */ + IRevisionManager getOwnedManager(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IRevisionManager.java b/bundles/org.xmind.core/src/org/xmind/core/IRevisionManager.java index 807fea0c3..673e36649 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IRevisionManager.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IRevisionManager.java @@ -1,164 +1,164 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core; - -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -/** - * The manager of all revisions related to a resource. - * - * @author Frank Shaka <frank@xmind.net> - * - */ -public interface IRevisionManager extends IWorkbookComponent, IAdaptable { - - /** - * Gets corresponding resource ID. - * - * @return the ID of the corresponding resource - */ - String getResourceId(); - - /** - * Gets the content type of the corresponding resource. See - * {@link IRevision} for all available content types. - * - * @return the content type of the corresponding resource - * @see IRevision - */ - String getContentType(); - - /** - * Gets a list of all revisions. The list is sorted by revision's number so - * that the revision with the smallest number is in the front and the one - * with the largest number in the end. - * - * @return a list of revisions - */ - List getRevisions(); - - /** - * Gets a list of all revisions. The list is sorted by revision's number in - * reversed order so that the revision with the largest number is in the - * front and the one with the smallest number in the end. - * - * @return a list of revision in reversed order - */ - List getRevisionsReversed(); - - /** - * Gets an iterator of all revisions. The revisions in the iterator is - * returned in the order of revision numbers, so that the revision with the - * smallest number is returned first and the one with the largest number is - * returned last. - * - * @return an iterator of revisions - */ - Iterator iterRevisions(); - - /** - * Gets an iterator of all revisions. The revisions in the iterator is - * returned in the reversed order of revision numbers, so that the revision - * with the largest number is returned first and the one with the smallest - * number is returned last. - * - * @return an iterator of revisions in reversed order - */ - Iterator iterRevisionsReversed(); - - /** - * Gets the revision by the specified revision number. - * - * @param number - * the number of the returned revision - * @return the revision with the specified revision number, or - * null if not found - */ - IRevision getRevision(int number); - - /** - * Gets the revision with the largest revision number. - * - * @return the latest revision - */ - IRevision getLatestRevision(); - - /** - * Gets the next revision number to be assigned. - * - *

- * Note that this number may be different from the size of the list returned - * by {@link IRevisionManager#getRevisions()}. Removed revisions will not be - * present in the list, but its revision number is taken and will not be - * assigned to another revision. For example, assume that there have been 6 - * revisions in this manager, the next revision number will be 7 even if the - * 6th revision is removed. - *

- * - * @return - */ - int getNextRevisionNumber(); - - /** - * Creates a snapshot derived from the specified content and add it as a new - * revision into this manager. If the content is regarded the same as the - * content of the latest revision, it will not create any new revision and - * simply return null. - * - * @param content - * the content to make snapshot - * @return the newly added revision, or null if the content - * equals the latest revision - */ - IRevision addRevision(IAdaptable content) throws IOException, CoreException; - - /** - * Removes the specified revision from this manager. - * - * @param revision - * the revision to remove - * @return an object used to restore this revision into this workbook, or - * null if the revision has already been deleted or not - * found. - * @throws IllegalArgumentException - * if the revision is null or not owned by the same - * workbook - */ - Object removeRevision(IRevision revision); - - /** - * Restores a previously removed revision into this manager. - * - * @param revision - * the revision to restore - * @param removal - * an object returned by remove() method - * @throws IllegalArgumentException - * if the revision is null, or the removal - * object is invalid - */ - void restoreRevision(IRevision revision, Object removal); - - /** - * Determines if this manager has any revisions. - * - * @return true if the this manager has at least one revision, - * false otherwise - */ - boolean hasRevisions(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + * The manager of all revisions related to a resource. + * + * @author Frank Shaka <frank@xmind.net> + * + */ +public interface IRevisionManager extends IWorkbookComponent, IAdaptable { + + /** + * Gets corresponding resource ID. + * + * @return the ID of the corresponding resource + */ + String getResourceId(); + + /** + * Gets the content type of the corresponding resource. See + * {@link IRevision} for all available content types. + * + * @return the content type of the corresponding resource + * @see IRevision + */ + String getContentType(); + + /** + * Gets a list of all revisions. The list is sorted by revision's number so + * that the revision with the smallest number is in the front and the one + * with the largest number in the end. + * + * @return a list of revisions + */ + List getRevisions(); + + /** + * Gets a list of all revisions. The list is sorted by revision's number in + * reversed order so that the revision with the largest number is in the + * front and the one with the smallest number in the end. + * + * @return a list of revision in reversed order + */ + List getRevisionsReversed(); + + /** + * Gets an iterator of all revisions. The revisions in the iterator is + * returned in the order of revision numbers, so that the revision with the + * smallest number is returned first and the one with the largest number is + * returned last. + * + * @return an iterator of revisions + */ + Iterator iterRevisions(); + + /** + * Gets an iterator of all revisions. The revisions in the iterator is + * returned in the reversed order of revision numbers, so that the revision + * with the largest number is returned first and the one with the smallest + * number is returned last. + * + * @return an iterator of revisions in reversed order + */ + Iterator iterRevisionsReversed(); + + /** + * Gets the revision by the specified revision number. + * + * @param number + * the number of the returned revision + * @return the revision with the specified revision number, or + * null if not found + */ + IRevision getRevision(int number); + + /** + * Gets the revision with the largest revision number. + * + * @return the latest revision + */ + IRevision getLatestRevision(); + + /** + * Gets the next revision number to be assigned. + * + *

+ * Note that this number may be different from the size of the list returned + * by {@link IRevisionManager#getRevisions()}. Removed revisions will not be + * present in the list, but its revision number is taken and will not be + * assigned to another revision. For example, assume that there have been 6 + * revisions in this manager, the next revision number will be 7 even if the + * 6th revision is removed. + *

+ * + * @return + */ + int getNextRevisionNumber(); + + /** + * Creates a snapshot derived from the specified content and add it as a new + * revision into this manager. If the content is regarded the same as the + * content of the latest revision, it will not create any new revision and + * simply return null. + * + * @param content + * the content to make snapshot + * @return the newly added revision, or null if the content + * equals the latest revision + */ + IRevision addRevision(IAdaptable content) throws IOException, CoreException; + + /** + * Removes the specified revision from this manager. + * + * @param revision + * the revision to remove + * @return an object used to restore this revision into this workbook, or + * null if the revision has already been deleted or not + * found. + * @throws IllegalArgumentException + * if the revision is null or not owned by the same + * workbook + */ + Object removeRevision(IRevision revision); + + /** + * Restores a previously removed revision into this manager. + * + * @param revision + * the revision to restore + * @param removal + * an object returned by remove() method + * @throws IllegalArgumentException + * if the revision is null, or the removal + * object is invalid + */ + void restoreRevision(IRevision revision, Object removal); + + /** + * Determines if this manager has any revisions. + * + * @return true if the this manager has at least one revision, + * false otherwise + */ + boolean hasRevisions(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISerializer.java b/bundles/org.xmind.core/src/org/xmind/core/ISerializer.java index 8babd020b..e74069698 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISerializer.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISerializer.java @@ -1,161 +1,161 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.util.IProgressReporter; - -/** - * A serializer is responsible for storing the content of a workbook as binary - * data to external resources. Workbooks saved by this serializer can be later - * loaded via {@link IDeserializer} objects of the same format version. - * - *

- * Instances of this interface can be retrieved via - * Core.getSerializationProvider().newSerializer(). NOTE - * that clients are allowed to use one serializer instance to save one - * workbook to one location for only once, and repeated usage - * of a single serializer instance may result in unexpected behaviors. Also note - * that all methods of this interface may NOT be thread-safe. - *

- * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface ISerializer extends ISerializingBase { - - /** - * Serializes the workbook (set via {@link #setWorkbook(IWorkbook)}), - * storing the serialized binary data into the output target (set via - * {@link #setOutputTarget(IOutputTarget)}, - * {@link #setOutputStream(OutputStream)} or - * {@link #setWorkbookStorageAsOutputTarget()}). The progress during the - * serialization is reported via the given progress reporter. - * - * @param reporter - * an {@link IProgressReporter} object to receive progress - * information and indicate user cancellation requests, or - * null if the progress is not significant and - * cancellation is not required - * @throws IOException - * if any I/O error occurs - * @throws CoreException - *
    - *
  • Core.ERROR_CANCELLATION - if the operation - * is canceled
  • - *
  • Core.ERROR_WRONG_PASSWORD - if the workbook - * is encrypted and the decryption operation failed
  • - *
  • (TODO add more error codes)
  • - *
- * @throws IllegalStateException - * if either workbook or output target is not set properly - */ - void serialize(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException; - - /** - * Sets the workbook to be serialized. - * - * @param workbook - * the {@link IWorkbook} to be serialized - * @throws IllegalArgumentException - * if the workbook is null or can not be serialized - * by this serializer - */ - void setWorkbook(IWorkbook workbook); - - /** - * Returns the workbook set via {@link #setWorkbook(IWorkbook)}. - * - * @return the {@link IWorkbook} to be serialized, or null if - * not set yet - */ - IWorkbook getWorkbook(); - - /** - * Sets the output target to which the content of the serialized workbook - * will be stored. - * - * @param target - * the {@link IOutputTarget} - * @throws IllegalArgumentException - * if the target is null - */ - void setOutputTarget(IOutputTarget target); - - /** - * Sets the output stream as the output target to which the content of the - * serialized workbook will be stored. - * - *

- * NOTE: The serializer may not close the given stream after usage. The - * client should close it on its own. - *

- * - * @param stream - * the target {@link OutputStream} - * @throws IllegalArgumentException - * if the stream is null - */ - void setOutputStream(OutputStream stream); - - /** - * Sets the output target to be the current file entry storage of the - * workbook to be serialized. Calling this method will remove any output - * target set previously. - * - *

- * This special setting indicates some special behaviors, e.g. skipping some - * kinds of file entries to save time if the normalizer is not going to - * change, or, if it will change, re-encoding/re-encrypting all - * existing file entries using the new normalizer, who will then be kept and - * held by the serialized workbook to perform normalizing tasks afterwards. - *

- */ - void setWorkbookStorageAsOutputTarget(); - - /** - * Tests whether an output target is properly set via - * {@link #setOutputTarget(IOutputTarget)}, - * {@link #setOutputStream(OutputStream)} or - * {@link #setWorkbookStorageAsOutputTarget()}. - * - * @return true if the output target is set, or - * false otherwise - */ - boolean hasOutputTarget(); - - /** - * Sets the set of entry paths whose encryption should be ignored during the - * serializing process. - * - * @param entryPaths - * a set of entry paths, or null to use default - * settings - */ - void setEncryptionIgnoredEntries(String[] entryPaths); - - /** - * Returns a set of entry paths whose encryption will be ignored during the - * serializing process. - * - * @return a set of entry paths, or null if not set or set to - * null - */ - String[] getEncryptionIgnoredEntries(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.util.IProgressReporter; + +/** + * A serializer is responsible for storing the content of a workbook as binary + * data to external resources. Workbooks saved by this serializer can be later + * loaded via {@link IDeserializer} objects of the same format version. + * + *

+ * Instances of this interface can be retrieved via + * Core.getSerializationProvider().newSerializer(). NOTE + * that clients are allowed to use one serializer instance to save one + * workbook to one location for only once, and repeated usage + * of a single serializer instance may result in unexpected behaviors. Also note + * that all methods of this interface may NOT be thread-safe. + *

+ * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface ISerializer extends ISerializingBase { + + /** + * Serializes the workbook (set via {@link #setWorkbook(IWorkbook)}), + * storing the serialized binary data into the output target (set via + * {@link #setOutputTarget(IOutputTarget)}, + * {@link #setOutputStream(OutputStream)} or + * {@link #setWorkbookStorageAsOutputTarget()}). The progress during the + * serialization is reported via the given progress reporter. + * + * @param reporter + * an {@link IProgressReporter} object to receive progress + * information and indicate user cancellation requests, or + * null if the progress is not significant and + * cancellation is not required + * @throws IOException + * if any I/O error occurs + * @throws CoreException + *
    + *
  • Core.ERROR_CANCELLATION - if the operation + * is canceled
  • + *
  • Core.ERROR_WRONG_PASSWORD - if the workbook + * is encrypted and the decryption operation failed
  • + *
  • (TODO add more error codes)
  • + *
+ * @throws IllegalStateException + * if either workbook or output target is not set properly + */ + void serialize(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException; + + /** + * Sets the workbook to be serialized. + * + * @param workbook + * the {@link IWorkbook} to be serialized + * @throws IllegalArgumentException + * if the workbook is null or can not be serialized + * by this serializer + */ + void setWorkbook(IWorkbook workbook); + + /** + * Returns the workbook set via {@link #setWorkbook(IWorkbook)}. + * + * @return the {@link IWorkbook} to be serialized, or null if + * not set yet + */ + IWorkbook getWorkbook(); + + /** + * Sets the output target to which the content of the serialized workbook + * will be stored. + * + * @param target + * the {@link IOutputTarget} + * @throws IllegalArgumentException + * if the target is null + */ + void setOutputTarget(IOutputTarget target); + + /** + * Sets the output stream as the output target to which the content of the + * serialized workbook will be stored. + * + *

+ * NOTE: The serializer may not close the given stream after usage. The + * client should close it on its own. + *

+ * + * @param stream + * the target {@link OutputStream} + * @throws IllegalArgumentException + * if the stream is null + */ + void setOutputStream(OutputStream stream); + + /** + * Sets the output target to be the current file entry storage of the + * workbook to be serialized. Calling this method will remove any output + * target set previously. + * + *

+ * This special setting indicates some special behaviors, e.g. skipping some + * kinds of file entries to save time if the normalizer is not going to + * change, or, if it will change, re-encoding/re-encrypting all + * existing file entries using the new normalizer, who will then be kept and + * held by the serialized workbook to perform normalizing tasks afterwards. + *

+ */ + void setWorkbookStorageAsOutputTarget(); + + /** + * Tests whether an output target is properly set via + * {@link #setOutputTarget(IOutputTarget)}, + * {@link #setOutputStream(OutputStream)} or + * {@link #setWorkbookStorageAsOutputTarget()}. + * + * @return true if the output target is set, or + * false otherwise + */ + boolean hasOutputTarget(); + + /** + * Sets the set of entry paths whose encryption should be ignored during the + * serializing process. + * + * @param entryPaths + * a set of entry paths, or null to use default + * settings + */ + void setEncryptionIgnoredEntries(String[] entryPaths); + + /** + * Returns a set of entry paths whose encryption will be ignored during the + * serializing process. + * + * @return a set of entry paths, or null if not set or set to + * null + */ + String[] getEncryptionIgnoredEntries(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java b/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java index 259ddc906..ac9345dff 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java @@ -1,31 +1,31 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -/** - * This class is used to create new serializer instances. - * - * @author Frank Shaka - * @since 3.6.2 - */ -public interface ISerializerFactory { - - /** - * Creates a new serializer instance. - * - * @return a new serializer instance (never null) - */ - ISerializer newSerializer(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +/** + * This class is used to create new serializer instances. + * + * @author Frank Shaka + * @since 3.6.2 + */ +public interface ISerializerFactory { + + /** + * Creates a new serializer instance. + * + * @return a new serializer instance (never null) + */ + ISerializer newSerializer(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISerializingBase.java b/bundles/org.xmind.core/src/org/xmind/core/ISerializingBase.java index 884425bad..f3c303f3f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISerializingBase.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISerializingBase.java @@ -1,92 +1,92 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core; - -/** - * The base interface for {@link ISerializer} and {@link IDeserializer} that - * provides some common facilities useful both for serialization and - * deserialization. - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface ISerializingBase { - - /** - * Sets the name of the client program whom the end user asks to perform the - * serializing/deserializing task. - * - * @param name - * the name to set - */ - void setCreatorName(String name); - - /** - * Returns the name of the client program whom the end user asks to perform - * the serializing/deserializing task. - * - * @return the creator name - */ - String getCreatorName(); - - /** - * Sets the version of the Creator representing the client program whom the - * end user asks to perform the serializing/deserializing task. - * - * @param version - * the version to set - */ - void setCreatorVersion(String version); - - /** - * Returns the version of the client program whom the end user asks to - * perform the serializing/deserializing task. - * - * @return the creator version - */ - String getCreatorVersion(); - - /** - * Sets the file entry stream normalizer to perform encoding/encryption or - * decoding/decryption operations during the serializing/deserializing - * process. - * - *

- * Note that the given normalizer should honor the equals() - * method to determine whether two normalizers provides the same abilities. - * A workbook tends to keep and hold the new normalizer that is different - * than its old one. - *

- * - * @param normalizer - * the {@link IEntryStreamNormalizer} to use, or - * null to indicate that (for serialization) the one - * already held by the workbook should be used or (for - * deserialization) no decoding/decryption should be performed - */ - void setEntryStreamNormalizer(IEntryStreamNormalizer normalizer); - - /** - * Returns the entry stream normalizer to perform encryption/decryption - * operations. - * - * @return the {@link IEntryStreamNormalizer} to use, or null - * if not set - */ - IEntryStreamNormalizer getEntryStreamNormalizer(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core; + +/** + * The base interface for {@link ISerializer} and {@link IDeserializer} that + * provides some common facilities useful both for serialization and + * deserialization. + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface ISerializingBase { + + /** + * Sets the name of the client program whom the end user asks to perform the + * serializing/deserializing task. + * + * @param name + * the name to set + */ + void setCreatorName(String name); + + /** + * Returns the name of the client program whom the end user asks to perform + * the serializing/deserializing task. + * + * @return the creator name + */ + String getCreatorName(); + + /** + * Sets the version of the Creator representing the client program whom the + * end user asks to perform the serializing/deserializing task. + * + * @param version + * the version to set + */ + void setCreatorVersion(String version); + + /** + * Returns the version of the client program whom the end user asks to + * perform the serializing/deserializing task. + * + * @return the creator version + */ + String getCreatorVersion(); + + /** + * Sets the file entry stream normalizer to perform encoding/encryption or + * decoding/decryption operations during the serializing/deserializing + * process. + * + *

+ * Note that the given normalizer should honor the equals() + * method to determine whether two normalizers provides the same abilities. + * A workbook tends to keep and hold the new normalizer that is different + * than its old one. + *

+ * + * @param normalizer + * the {@link IEntryStreamNormalizer} to use, or + * null to indicate that (for serialization) the one + * already held by the workbook should be used or (for + * deserialization) no decoding/decryption should be performed + */ + void setEntryStreamNormalizer(IEntryStreamNormalizer normalizer); + + /** + * Returns the entry stream normalizer to perform encryption/decryption + * operations. + * + * @return the {@link IEntryStreamNormalizer} to use, or null + * if not set + */ + IEntryStreamNormalizer getEntryStreamNormalizer(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java b/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java index a40f2df72..c772e6f8b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java @@ -1,20 +1,20 @@ -package org.xmind.core; - -import java.util.Set; - -public interface ISettingEntry extends IAdaptable, ISheetComponent { - - String getPath(); - - /** - * - * @param key - * @return - */ - String getAttribute(String key); - - void setAttribute(String key, String value); - - Set getAttributeKeys(); - -} +package org.xmind.core; + +import java.util.Set; + +public interface ISettingEntry extends IAdaptable, ISheetComponent { + + String getPath(); + + /** + * + * @param key + * @return + */ + String getAttribute(String key); + + void setAttribute(String key, String value); + + Set getAttributeKeys(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISheet.java b/bundles/org.xmind.core/src/org/xmind/core/ISheet.java index 112c2016a..78e4bc347 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISheet.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISheet.java @@ -1,97 +1,97 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.util.Set; - -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyled; - -/** - * @author briansun - * - */ -public interface ISheet extends IIdentifiable, ITitled, IWorkbookComponent, - IAdaptable, IStyled, IModifiable { - - /** - * @return - */ - ITopic getRootTopic(); - - /** - * - * @param newRootTopic - */ - void replaceRootTopic(ITopic newRootTopic); - - /** - * @return - */ - int getIndex(); - - /** - * - * @return - */ - IWorkbook getParent(); - - /** - * @return - */ - Set getRelationships(); - - /** - * @param rel - */ - void addRelationship(IRelationship relationship); - - /** - * @param rel - */ - void removeRelationship(IRelationship relationship); - - /** - * - * @return - */ - IStyle getTheme(); - - /** - * - * @return - */ - String getThemeId(); - - /** - * - */ - void setThemeId(String themeId); - - /** - * - * @return - */ - ILegend getLegend(); - - /** - * @deprecated - * @return - */ - @Deprecated - ISheetSetting getSetting(); - - ISheetSettings getSettings(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.util.Set; + +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyled; + +/** + * @author briansun + * + */ +public interface ISheet extends IIdentifiable, ITitled, IWorkbookComponent, + IAdaptable, IStyled, IModifiable { + + /** + * @return + */ + ITopic getRootTopic(); + + /** + * + * @param newRootTopic + */ + void replaceRootTopic(ITopic newRootTopic); + + /** + * @return + */ + int getIndex(); + + /** + * + * @return + */ + IWorkbook getParent(); + + /** + * @return + */ + Set getRelationships(); + + /** + * @param rel + */ + void addRelationship(IRelationship relationship); + + /** + * @param rel + */ + void removeRelationship(IRelationship relationship); + + /** + * + * @return + */ + IStyle getTheme(); + + /** + * + * @return + */ + String getThemeId(); + + /** + * + */ + void setThemeId(String themeId); + + /** + * + * @return + */ + ILegend getLegend(); + + /** + * @deprecated + * @return + */ + @Deprecated + ISheetSetting getSetting(); + + ISheetSettings getSettings(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISheetComponent.java b/bundles/org.xmind.core/src/org/xmind/core/ISheetComponent.java index 16537e9f7..6f857e80d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISheetComponent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISheetComponent.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface ISheetComponent extends IWorkbookComponent { - - ISheet getOwnedSheet(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface ISheetComponent extends IWorkbookComponent { + + ISheet getOwnedSheet(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISheetSetting.java b/bundles/org.xmind.core/src/org/xmind/core/ISheetSetting.java index 211b5aa6b..d2ecba865 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISheetSetting.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISheetSetting.java @@ -1,14 +1,14 @@ -package org.xmind.core; - -public interface ISheetSetting { - - boolean isInfoItemVisible(String type, String key, String defaultMode); - - void setInfoItemVisible(String type, String key, String defaultMode, - boolean visible); - - String getInfoItemMode(String type, String key); - - void setInfoItemMode(String type, String key, String value); - -} +package org.xmind.core; + +public interface ISheetSetting { + + boolean isInfoItemVisible(String type, String key, String defaultMode); + + void setInfoItemVisible(String type, String key, String defaultMode, + boolean visible); + + String getInfoItemMode(String type, String key); + + void setInfoItemMode(String type, String key, String value); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java b/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java index 441ddc947..838792a40 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java @@ -1,38 +1,38 @@ -package org.xmind.core; - -import java.util.List; -import java.util.Set; - -/** - * @author Jason Wong - */ -public interface ISheetSettings extends IAdaptable, ISheetComponent { - - String SEP = "/"; //$NON-NLS-1$ - - String INFO_ITEM = "info-items/info-item"; //$NON-NLS-1$ - String ATTR_TYPE = "type"; //$NON-NLS-1$ - String ATTR_MODE = "mode"; //$NON-NLS-1$ - String MODE_CARD = "card"; //$NON-NLS-1$ - String MODE_ICON = "icon"; //$NON-NLS-1$ - - String TAB_COLOR = "tab-color"; //$NON-NLS-1$ - String ATTR_RGB = "rgb"; //$NON-NLS-1$ - - /** - * - * @param path - * "info-items/info-item" - * @return - */ - List getEntries(String path); - - ISettingEntry createEntry(String path); - - void addEntry(ISettingEntry entry); - - void removeEntry(ISettingEntry entry); - - Set getPaths(); - -} +package org.xmind.core; + +import java.util.List; +import java.util.Set; + +/** + * @author Jason Wong + */ +public interface ISheetSettings extends IAdaptable, ISheetComponent { + + String SEP = "/"; //$NON-NLS-1$ + + String INFO_ITEM = "info-items/info-item"; //$NON-NLS-1$ + String ATTR_TYPE = "type"; //$NON-NLS-1$ + String ATTR_MODE = "mode"; //$NON-NLS-1$ + String MODE_CARD = "card"; //$NON-NLS-1$ + String MODE_ICON = "icon"; //$NON-NLS-1$ + + String TAB_COLOR = "tab-color"; //$NON-NLS-1$ + String ATTR_RGB = "rgb"; //$NON-NLS-1$ + + /** + * + * @param path + * "info-items/info-item" + * @return + */ + List getEntries(String path); + + ISettingEntry createEntry(String path); + + void addEntry(ISettingEntry entry); + + void removeEntry(ISettingEntry entry); + + Set getPaths(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISpan.java b/bundles/org.xmind.core/src/org/xmind/core/ISpan.java index eed34f274..ccd1f2056 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISpan.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISpan.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import org.xmind.core.style.IStyled; - -public interface ISpan extends IAdaptable, IStyled, IWorkbookComponent { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import org.xmind.core.style.IStyled; + +public interface ISpan extends IAdaptable, IStyled, IWorkbookComponent { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISpanList.java b/bundles/org.xmind.core/src/org/xmind/core/ISpanList.java index 0062f9c43..df2a1f129 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISpanList.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISpanList.java @@ -1,13 +1,13 @@ -package org.xmind.core; - -import java.util.List; - -public interface ISpanList { - - List getSpans(); - - void addSpan(ISpan span); - - void removeSpan(ISpan span); - -} +package org.xmind.core; + +import java.util.List; + +public interface ISpanList { + + List getSpans(); + + void addSpan(ISpan span); + + void removeSpan(ISpan span); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/ITextSpan.java b/bundles/org.xmind.core/src/org/xmind/core/ITextSpan.java index d2fb66c0e..cf7daac6c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITextSpan.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITextSpan.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface ITextSpan extends ISpan { - - String getTextContent(); - - void setTextContent(String textContent); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface ITextSpan extends ISpan { + + String getTextContent(); + + void setTextContent(String textContent); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ITopic.java b/bundles/org.xmind.core/src/org/xmind/core/ITopic.java index ada996234..f38c6c91c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITopic.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITopic.java @@ -1,293 +1,293 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.style.IStyled; - -/** - * @author briansun - * - */ -public interface ITopic extends ITitled, IStyled, IRelationshipEnd, IAdaptable, - ILabeled, ITopicComponent, IPositioned, IModifiable { - - /** - * Type for the root topic (value='root'). - * - * @see org.xmind.core.ITopic#getType() - */ - public static final String ROOT = "root"; //$NON-NLS-1$ - - /** - * Type for topics directly attached to their parent topics - * (value='attached'). - * - * @see org.xmind.core.ITopic#getType() - */ - public static final String ATTACHED = "attached"; //$NON-NLS-1$ - - /** - * - */ - public static final String CALLOUT = "callout"; //$NON-NLS-1$ - - /** - * Type for topics detached from their parent topics (value='detached'). - * - * @see org.xmind.core.ITopic#getType() - */ - public static final String DETACHED = "detached"; //$NON-NLS-1$ - - /** - * Type for topics attached on their parent topics' summaries - * (value='summary'). - * - * @see org.xmind.core.ITopic#getType() - */ - public static final String SUMMARY = "summary"; //$NON-NLS-1$ - - public static final int UNSPECIFIED = -1; - - /** - * @return - */ - boolean isFolded(); - - /** - * @param folded - */ - void setFolded(boolean folded); - - /** - * Gets the type of this topic. - *

- * A topic's Type is a {@link String} used to define how this topic - * is connected to its parent topic, such as 'attached' - * (directly connected), 'detached' (totally separated), or ' - * summary' (attached on a summary), etc. This attribute - * matters when it is required how a topic and its parent topic are painted - * on graphics. - *

- *

- * A root topic always returns a special type 'root' since it has NO parent - * topic. - *

- *

- * If this topic has not been added to any parent topic, or its type is not - * specified, null is returned. - *

- * - * @return The type of this topic, or null indicating that the - * type is unspecified - * - * @see org.xmind.core.ITopic#ATTACHED - * @see org.xmind.core.ITopic#DETACHED - * @see org.xmind.core.ITopic#SUMMARY - * @see org.xmind.core.ITopic#ROOT - */ - String getType(); - - /** - * @return Whether this topic is directly connected to its parent topic - * - * @see #getType(); - */ - boolean isAttached(); - - /** - * Gets all children topics of this topic. - *

- * NOTE: This list is not supposed to be modifiable. Use - * {@link #add(ITopic)}, {@link #add(ITopic, String)}, - * {@link #add(ITopic, int, String)} or {@link #remove(ITopic)} to - * add/remove child topic to this topic. - *

- * - * @return A list containing all children topics of this topic - */ - List getAllChildren(); - - /** - * Returns an iterator over all children topics of this topic. - *

- * NOTE: This iterator is not supposed to be modifiable and calling - * {@link Iterator#remove()} method on the returned iterator will cause an - * {@link java.lang.UnsupportedOperationException} to be thrown. Use - * {@link #remove(ITopic)} to remove child topic. - *

- * - * @return An iterator over all children topics of this topic. - */ - Iterator getAllChildrenIterator(); - - /** - * Gets this topic's children topics that are of the specified type. - *

- * If this topic has NO children topics that are of this type, or the type - * is null, an empty list will be returned. - *

- *

- * NOTE: This list is not supposed to be modifiable. Use - * {@link #add(ITopic)}, {@link #add(ITopic, String)}, - * {@link #add(ITopic, int, String)} or {@link #remove(ITopic)} to - * add/remove child topic to this topic. - *

- * - * @param type - * The children's type - * @return A list containing this topic's children topics that are of the - * specified type - * - * @see #getType() - */ - List getChildren(String type); - - /** - * Returns an iterator over this topic's children topics that are of the - * specified type. - * - *

- * NOTE: This iterator is not supposed to be modifiable and calling - * {@link Iterator#remove()} method on the returned iterator will cause an - * {@link java.lang.UnsupportedOperationException} to be thrown. Use - * {@link #remove(ITopic)} to remove child topic. - *

- * - * @param type - * the children topics' type - * @return An iterator over this topic's children topics that are of the - * specified type (never be null) - */ - Iterator getChildrenIterator(String type); - - /** - * - * @param type - * @return - */ - boolean hasChildren(String type); - - /** - * - * @return - */ - Set getChildrenTypes(); - - /** - * @param child - */ - void add(ITopic child); - - /** - * @param child - * @param type - * The child's type. - */ - void add(ITopic child, String type); - - /** - * @param child - * @param index - * @param type - * The child's type. - */ - void add(ITopic child, int index, String type); - - /** - * @param child - */ - void remove(ITopic child); - - /** - * @return - */ - ITopicPath getPath(); - - /** - * @return - */ - int getIndex(); - - /** - * @param string - */ - void setHyperlink(String hyperlink); - - /** - * @return - */ - String getHyperlink(); - - /** - * @return - */ - INotes getNotes(); - - /** - * - * @return - */ - INumbering getNumbering(); - - /** - * @return - */ - boolean isRoot(); - - void addMarker(String markerId); - - void removeMarker(String markerId); - - boolean hasMarker(String markerId); - - Set getMarkerRefs(); - - void addBoundary(IBoundary boundary); - - void removeBoundary(IBoundary boundary); - - Set getBoundaries(); - - void addSummary(ISummary summary); - - void removeSummary(ISummary summary); - - Set getSummaries(); - - String getStructureClass(); - - void setStructureClass(String structureClass); - - IImage getImage(); - - int getTitleWidth(); - - void setTitleWidth(int width); - - List getExtensions(); - - ITopicExtension getExtension(String providerName); - - ITopicExtension createExtension(String providerName); - - void deleteExtension(String providerName); - - long getModifiedTime(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.style.IStyled; + +/** + * @author briansun + * + */ +public interface ITopic extends ITitled, IStyled, IRelationshipEnd, IAdaptable, + ILabeled, ITopicComponent, IPositioned, IModifiable { + + /** + * Type for the root topic (value='root'). + * + * @see org.xmind.core.ITopic#getType() + */ + public static final String ROOT = "root"; //$NON-NLS-1$ + + /** + * Type for topics directly attached to their parent topics + * (value='attached'). + * + * @see org.xmind.core.ITopic#getType() + */ + public static final String ATTACHED = "attached"; //$NON-NLS-1$ + + /** + * + */ + public static final String CALLOUT = "callout"; //$NON-NLS-1$ + + /** + * Type for topics detached from their parent topics (value='detached'). + * + * @see org.xmind.core.ITopic#getType() + */ + public static final String DETACHED = "detached"; //$NON-NLS-1$ + + /** + * Type for topics attached on their parent topics' summaries + * (value='summary'). + * + * @see org.xmind.core.ITopic#getType() + */ + public static final String SUMMARY = "summary"; //$NON-NLS-1$ + + public static final int UNSPECIFIED = -1; + + /** + * @return + */ + boolean isFolded(); + + /** + * @param folded + */ + void setFolded(boolean folded); + + /** + * Gets the type of this topic. + *

+ * A topic's Type is a {@link String} used to define how this topic + * is connected to its parent topic, such as 'attached' + * (directly connected), 'detached' (totally separated), or ' + * summary' (attached on a summary), etc. This attribute + * matters when it is required how a topic and its parent topic are painted + * on graphics. + *

+ *

+ * A root topic always returns a special type 'root' since it has NO parent + * topic. + *

+ *

+ * If this topic has not been added to any parent topic, or its type is not + * specified, null is returned. + *

+ * + * @return The type of this topic, or null indicating that the + * type is unspecified + * + * @see org.xmind.core.ITopic#ATTACHED + * @see org.xmind.core.ITopic#DETACHED + * @see org.xmind.core.ITopic#SUMMARY + * @see org.xmind.core.ITopic#ROOT + */ + String getType(); + + /** + * @return Whether this topic is directly connected to its parent topic + * + * @see #getType(); + */ + boolean isAttached(); + + /** + * Gets all children topics of this topic. + *

+ * NOTE: This list is not supposed to be modifiable. Use + * {@link #add(ITopic)}, {@link #add(ITopic, String)}, + * {@link #add(ITopic, int, String)} or {@link #remove(ITopic)} to + * add/remove child topic to this topic. + *

+ * + * @return A list containing all children topics of this topic + */ + List getAllChildren(); + + /** + * Returns an iterator over all children topics of this topic. + *

+ * NOTE: This iterator is not supposed to be modifiable and calling + * {@link Iterator#remove()} method on the returned iterator will cause an + * {@link java.lang.UnsupportedOperationException} to be thrown. Use + * {@link #remove(ITopic)} to remove child topic. + *

+ * + * @return An iterator over all children topics of this topic. + */ + Iterator getAllChildrenIterator(); + + /** + * Gets this topic's children topics that are of the specified type. + *

+ * If this topic has NO children topics that are of this type, or the type + * is null, an empty list will be returned. + *

+ *

+ * NOTE: This list is not supposed to be modifiable. Use + * {@link #add(ITopic)}, {@link #add(ITopic, String)}, + * {@link #add(ITopic, int, String)} or {@link #remove(ITopic)} to + * add/remove child topic to this topic. + *

+ * + * @param type + * The children's type + * @return A list containing this topic's children topics that are of the + * specified type + * + * @see #getType() + */ + List getChildren(String type); + + /** + * Returns an iterator over this topic's children topics that are of the + * specified type. + * + *

+ * NOTE: This iterator is not supposed to be modifiable and calling + * {@link Iterator#remove()} method on the returned iterator will cause an + * {@link java.lang.UnsupportedOperationException} to be thrown. Use + * {@link #remove(ITopic)} to remove child topic. + *

+ * + * @param type + * the children topics' type + * @return An iterator over this topic's children topics that are of the + * specified type (never be null) + */ + Iterator getChildrenIterator(String type); + + /** + * + * @param type + * @return + */ + boolean hasChildren(String type); + + /** + * + * @return + */ + Set getChildrenTypes(); + + /** + * @param child + */ + void add(ITopic child); + + /** + * @param child + * @param type + * The child's type. + */ + void add(ITopic child, String type); + + /** + * @param child + * @param index + * @param type + * The child's type. + */ + void add(ITopic child, int index, String type); + + /** + * @param child + */ + void remove(ITopic child); + + /** + * @return + */ + ITopicPath getPath(); + + /** + * @return + */ + int getIndex(); + + /** + * @param string + */ + void setHyperlink(String hyperlink); + + /** + * @return + */ + String getHyperlink(); + + /** + * @return + */ + INotes getNotes(); + + /** + * + * @return + */ + INumbering getNumbering(); + + /** + * @return + */ + boolean isRoot(); + + void addMarker(String markerId); + + void removeMarker(String markerId); + + boolean hasMarker(String markerId); + + Set getMarkerRefs(); + + void addBoundary(IBoundary boundary); + + void removeBoundary(IBoundary boundary); + + Set getBoundaries(); + + void addSummary(ISummary summary); + + void removeSummary(ISummary summary); + + Set getSummaries(); + + String getStructureClass(); + + void setStructureClass(String structureClass); + + IImage getImage(); + + int getTitleWidth(); + + void setTitleWidth(int width); + + List getExtensions(); + + ITopicExtension getExtension(String providerName); + + ITopicExtension createExtension(String providerName); + + void deleteExtension(String providerName); + + long getModifiedTime(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ITopicComponent.java b/bundles/org.xmind.core/src/org/xmind/core/ITopicComponent.java index fa82ae09e..0817577df 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITopicComponent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITopicComponent.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface ITopicComponent extends ISheetComponent { - - ITopic getParent(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface ITopicComponent extends ISheetComponent { + + ITopic getParent(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java index cf052cf99..b3ffab456 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface ITopicExtensionElement extends IAdaptable, IWorkbookComponent, - IExtensionElement { - - ITopicExtension getExtension(); - - ITopic getTopic(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface ITopicExtensionElement extends IAdaptable, IWorkbookComponent, + IExtensionElement { + + ITopicExtension getExtension(); + + ITopic getTopic(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ITopicRange.java b/bundles/org.xmind.core/src/org/xmind/core/ITopicRange.java index 8fd9133d8..340f541cf 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITopicRange.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITopicRange.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface ITopicRange extends IRange { - - ITopic getParent(); - - java.util.List getEnclosingTopics(); - - boolean encloses(ITopic subtopic); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface ITopicRange extends IRange { + + ITopic getParent(); + + java.util.List getEnclosingTopics(); + + boolean encloses(ITopic subtopic); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbook.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbook.java index 143b34c55..14619b394 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbook.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbook.java @@ -1,457 +1,457 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collection; -import java.util.List; - -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyleSheet; - -/** - * @author briansun - * - */ -public interface IWorkbook extends IAdaptable, IModifiable { - - /** - * @return - */ - ITopic createTopic(); - - /** - * @return - */ - - ISheet createSheet(); - - /** - * @param end1 - * @param end2 - * @return - */ - IRelationship createRelationship(IRelationshipEnd end1, - IRelationshipEnd end2); - - /** - * @return - */ - IRelationship createRelationship(); - - /** - * - * @return - */ - IBoundary createBoundary(); - - /** - * - * @return - */ - ISummary createSummary(); - - /** - * - */ - List getSheets(); - - /** - * - * @return - */ - ISheet getPrimarySheet(); - - /** - * - * @param sheet - */ - void addSheet(ISheet sheet); - - /** - * - * @param sheet - * @param index - */ - void addSheet(ISheet sheet, int index); - - /** - * - * @param sheet - */ - void removeSheet(ISheet sheet); - - /** - * - * @param sourceIndex - * @param targetIndex - */ - void moveSheet(int sourceIndex, int targetIndex); - - /** - * Gets an element with the given identifier string. - * - * @param id - * The identifier string of the desired element - * @return The element with the given identifier string. - */ - Object getElementById(String id); - - /** - * Finds an element with the given identifier string requested starting from - * the source object. - * - * @param id - * @param source - * @return - */ - Object findElement(String id, IAdaptable source); - - /** - * Gets a Topic element with the given id. The topic returned is the same - * as: - * - *
-     * Object element = getElementById(id);
-     * return element instanceof ITopic ? (ITopic) element : null;
-     * 
- * - * @see #getElementById(String) - * @param id - * @return - */ - ITopic findTopic(String id); - - /** - * Finds the topic element with the given ID starting from the source - * object. - * - * @param id - * @param source - * @return - */ - ITopic findTopic(String id, IAdaptable source); - - /** - * - * @return - */ - IStyleSheet getStyleSheet(); - - /** - * - * @return - */ - IManifest getManifest(); - - /** - * - * @return - */ - IMeta getMeta(); - - /** - * - * @return - */ - IMarkerSheet getMarkerSheet(); - - /** - * - * @return - */ - IRevisionRepository getRevisionRepository(); - - /** - * - * @return - */ - ICommentManager getCommentManager(); - - /** - * @see org.xmind.core.INotes#PLAIN - * @see org.xmind.core.INotes#HTML - * @see org.xmind.core.IPlainNotesContent - * @see org.xmind.core.IHtmlNotesContent - * @param format - * @return - */ - INotesContent createNotesContent(String format); - - /** - * - * @return - */ - String getVersion(); - - /** - * Imports the specified element into this workbook. The imported element - * will have the same identifying attributes with the source element, so - * this method is primarily used to replace existing elements that have the - * same identifying attributes. - * - *

- * Note that adding imported elements into this workbook without first - * removing the source element may cause unknown behavior when invoking - * getElementById() or findElement(). - *

- * - * @param source - * the element to import - * @return the imported element - */ - IAdaptable importElement(IAdaptable source); - - /** - * - * @param resourceType - * @param resourceId - * @return - */ - IResourceRef createResourceRef(String resourceType, String resourceId); - - /** - * Clones the specified elements into this workbook and returns a session - * object mapping source resources to their clones. - * - *

- * Note that the elements cloned will have newly assigned identifying - * attributes, so that it's safe to keep the cloned elements together with - * their sources within one workbook. - *

- * - * @param sources - * @return - * @deprecated Use {@link org.xmind.core.util.CloneHandler} - */ - @Deprecated - ICloneData clone(Collection sources); - - /** - * A convenient method for clone(Arrays.asList(topic)). - * - * @param topic - * @return - * @deprecated Use {@link org.xmind.core.util.CloneHandler} - */ - @Deprecated - ITopic cloneTopic(ITopic topic); - - /** - * Saves this workbook to the last saved location. - * - * @throws IOException - * @throws CoreException - * @deprecated Workbook instances should NOT cache output target any more, - * as the output target may not be ready if called multiple - * times. Use other save(xxx) methods instead and prepare a - * proper output target in prior. - */ - void save() throws IOException, CoreException; - - /** - * Saves all contents of this workbook to a target local file. The default - * implementation uses the ZIP file format to store multiple entries into - * one file. - * - *

- * As a legacy behaviour, the file path passed to this method is remembered - * and reused for the {@link #save()} method. However, this behaviour is not - * recommended any more and may be removed in future. So clients should not - * rely on the deprecated save() method any more. - *

- * - *

- * Another legacy behaviour is that the file path passed to this method will - * override the file path set by setFile(). So curently clients - * need to call setFile() after calling this method if they - * want the workbook refers to a different file path. However, this - * behaviour may be removed in future to reduce the reliability on local - * files. - *

- * - * @deprecated Use - * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) - * - * @param file - * the absolute path of the target file in the local file system - * @throws IOException - * if I/O error occurs - * @throws CoreException - * if some logic or execution error occurs, e.g. missing some - * required components, or operation canceled by user, etc. - */ - void save(String file) throws IOException, CoreException; - - /** - * Saves all contents of this workbook to a target output stream. The - * default implementation uses the ZIP file format to store multiple entries - * into one output stream. - * - *

- * Note that it's not gauranteed that the output stream will be closed when - * the process finishes, so clients should explictly call - * close() on the output stream in a finally - * block. - *

- * - * @deprecated Use - * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) - * - * @param output - * the output stream to write workbook contents to - * @throws IOException - * if I/O error occurs - * @throws CoreException - * if some logic or execution error occurs, e.g. missing some - * required components, or operation canceled by user, etc. - */ - void save(OutputStream output) throws IOException, CoreException; - - /** - * Saves all contents of this workbook to a multi-entry output target. - * - *

- * Note that clients should make sure the output target is ready before - * calling this method. - *

- * - *

- * As a legacy behaviour, the output target passed in this method is - * remembered and reused for the {@link #save()} method. However, this - * behaviour is not recommended any more and may be removed in future. So - * clients should not rely on the deprecated save() method any - * more. - *

- * - * @deprecated Use - * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) - * - * @param target - * the output target to write all entries of this workbook to - * @throws IOException - * if I/O error occurs - * @throws CoreException - * if some logic or execution error occurs, e.g. missing some - * required components, or operation canceled by user, etc. - */ - void save(IOutputTarget target) throws IOException, CoreException; - - /** - * Returns the path of the local file that this workbook refers to. - * - *

- * The path is typically set by {@link #setFile(String)} or - * {@link #save(String)}. - *

- * - *

- * Developer Guide: As a legacy concept, the reliability on local files will - * be gradually reduced in future so that a workbook performs as a pure - * in-memory model and support more kinds of output targets to save to. So - * this method may one day be deprecated, and thus it's recommended that - * clients use external mechanisms to remember which output target a - * workbook refers to and is referred to. - *

- * - * @return the file path that this workbook refers to - * @see #setFile(String) - * @see #save(String) - * @deprecated - */ - @Deprecated - String getFile(); - - /** - * Sets the path of a local file that this workbook will refer to. - * - *

- * Developer Guide: As a legacy concept, the reliability on local files will - * be gradually reduced in future so that a workbook performs as a pure - * in-memory model and support more kinds of output targets to save to. So - * this method may one day be deprecated, and thus it's recommended that - * clients use external mechanisms to remember which output target a - * workbook refers to and is referred to. - *

- * - * @param file - * the path of a new local file that this workbook will refer to - * @see #getFile() - * @deprecated - */ - @Deprecated - void setFile(String file); - - /** - * - * @param storage - * @deprecated - */ - @Deprecated - void setTempStorage(IStorage storage); - - /** - * - * @return - * @deprecated - */ - @Deprecated - IStorage getTempStorage(); - - /** - * - * @param tempLocation - * @deprecated - */ - @Deprecated - void setTempLocation(String tempLocation); - - /** - * - * @return - * @deprecated - */ - @Deprecated - String getTempLocation(); - - /** - * Saves temporary data to somewhere, or does nothing if not supported. The - * implementation decides how and where to save these data. - * - * @throws IOException - * @throws CoreException - * @deprecated Use - * Core.getSerializationProvider().newSerializer() - */ - @Deprecated - void saveTemp() throws IOException, CoreException; - - /** - * @deprecated - * @param password - */ - @Deprecated - void setPassword(String password); - - /** - * @return - * @deprecated - */ - @Deprecated - String getPassword(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; +import java.util.List; + +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyleSheet; + +/** + * @author briansun + * + */ +public interface IWorkbook extends IAdaptable, IModifiable { + + /** + * @return + */ + ITopic createTopic(); + + /** + * @return + */ + + ISheet createSheet(); + + /** + * @param end1 + * @param end2 + * @return + */ + IRelationship createRelationship(IRelationshipEnd end1, + IRelationshipEnd end2); + + /** + * @return + */ + IRelationship createRelationship(); + + /** + * + * @return + */ + IBoundary createBoundary(); + + /** + * + * @return + */ + ISummary createSummary(); + + /** + * + */ + List getSheets(); + + /** + * + * @return + */ + ISheet getPrimarySheet(); + + /** + * + * @param sheet + */ + void addSheet(ISheet sheet); + + /** + * + * @param sheet + * @param index + */ + void addSheet(ISheet sheet, int index); + + /** + * + * @param sheet + */ + void removeSheet(ISheet sheet); + + /** + * + * @param sourceIndex + * @param targetIndex + */ + void moveSheet(int sourceIndex, int targetIndex); + + /** + * Gets an element with the given identifier string. + * + * @param id + * The identifier string of the desired element + * @return The element with the given identifier string. + */ + Object getElementById(String id); + + /** + * Finds an element with the given identifier string requested starting from + * the source object. + * + * @param id + * @param source + * @return + */ + Object findElement(String id, IAdaptable source); + + /** + * Gets a Topic element with the given id. The topic returned is the same + * as: + * + *

+     * Object element = getElementById(id);
+     * return element instanceof ITopic ? (ITopic) element : null;
+     * 
+ * + * @see #getElementById(String) + * @param id + * @return + */ + ITopic findTopic(String id); + + /** + * Finds the topic element with the given ID starting from the source + * object. + * + * @param id + * @param source + * @return + */ + ITopic findTopic(String id, IAdaptable source); + + /** + * + * @return + */ + IStyleSheet getStyleSheet(); + + /** + * + * @return + */ + IManifest getManifest(); + + /** + * + * @return + */ + IMeta getMeta(); + + /** + * + * @return + */ + IMarkerSheet getMarkerSheet(); + + /** + * + * @return + */ + IRevisionRepository getRevisionRepository(); + + /** + * + * @return + */ + ICommentManager getCommentManager(); + + /** + * @see org.xmind.core.INotes#PLAIN + * @see org.xmind.core.INotes#HTML + * @see org.xmind.core.IPlainNotesContent + * @see org.xmind.core.IHtmlNotesContent + * @param format + * @return + */ + INotesContent createNotesContent(String format); + + /** + * + * @return + */ + String getVersion(); + + /** + * Imports the specified element into this workbook. The imported element + * will have the same identifying attributes with the source element, so + * this method is primarily used to replace existing elements that have the + * same identifying attributes. + * + *

+ * Note that adding imported elements into this workbook without first + * removing the source element may cause unknown behavior when invoking + * getElementById() or findElement(). + *

+ * + * @param source + * the element to import + * @return the imported element + */ + IAdaptable importElement(IAdaptable source); + + /** + * + * @param resourceType + * @param resourceId + * @return + */ + IResourceRef createResourceRef(String resourceType, String resourceId); + + /** + * Clones the specified elements into this workbook and returns a session + * object mapping source resources to their clones. + * + *

+ * Note that the elements cloned will have newly assigned identifying + * attributes, so that it's safe to keep the cloned elements together with + * their sources within one workbook. + *

+ * + * @param sources + * @return + * @deprecated Use {@link org.xmind.core.util.CloneHandler} + */ + @Deprecated + ICloneData clone(Collection sources); + + /** + * A convenient method for clone(Arrays.asList(topic)). + * + * @param topic + * @return + * @deprecated Use {@link org.xmind.core.util.CloneHandler} + */ + @Deprecated + ITopic cloneTopic(ITopic topic); + + /** + * Saves this workbook to the last saved location. + * + * @throws IOException + * @throws CoreException + * @deprecated Workbook instances should NOT cache output target any more, + * as the output target may not be ready if called multiple + * times. Use other save(xxx) methods instead and prepare a + * proper output target in prior. + */ + void save() throws IOException, CoreException; + + /** + * Saves all contents of this workbook to a target local file. The default + * implementation uses the ZIP file format to store multiple entries into + * one file. + * + *

+ * As a legacy behaviour, the file path passed to this method is remembered + * and reused for the {@link #save()} method. However, this behaviour is not + * recommended any more and may be removed in future. So clients should not + * rely on the deprecated save() method any more. + *

+ * + *

+ * Another legacy behaviour is that the file path passed to this method will + * override the file path set by setFile(). So curently clients + * need to call setFile() after calling this method if they + * want the workbook refers to a different file path. However, this + * behaviour may be removed in future to reduce the reliability on local + * files. + *

+ * + * @deprecated Use + * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) + * + * @param file + * the absolute path of the target file in the local file system + * @throws IOException + * if I/O error occurs + * @throws CoreException + * if some logic or execution error occurs, e.g. missing some + * required components, or operation canceled by user, etc. + */ + void save(String file) throws IOException, CoreException; + + /** + * Saves all contents of this workbook to a target output stream. The + * default implementation uses the ZIP file format to store multiple entries + * into one output stream. + * + *

+ * Note that it's not gauranteed that the output stream will be closed when + * the process finishes, so clients should explictly call + * close() on the output stream in a finally + * block. + *

+ * + * @deprecated Use + * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) + * + * @param output + * the output stream to write workbook contents to + * @throws IOException + * if I/O error occurs + * @throws CoreException + * if some logic or execution error occurs, e.g. missing some + * required components, or operation canceled by user, etc. + */ + void save(OutputStream output) throws IOException, CoreException; + + /** + * Saves all contents of this workbook to a multi-entry output target. + * + *

+ * Note that clients should make sure the output target is ready before + * calling this method. + *

+ * + *

+ * As a legacy behaviour, the output target passed in this method is + * remembered and reused for the {@link #save()} method. However, this + * behaviour is not recommended any more and may be removed in future. So + * clients should not rely on the deprecated save() method any + * more. + *

+ * + * @deprecated Use + * Core.getSerializerFactory().newSerializer().saveToXXX(workbook, target) + * + * @param target + * the output target to write all entries of this workbook to + * @throws IOException + * if I/O error occurs + * @throws CoreException + * if some logic or execution error occurs, e.g. missing some + * required components, or operation canceled by user, etc. + */ + void save(IOutputTarget target) throws IOException, CoreException; + + /** + * Returns the path of the local file that this workbook refers to. + * + *

+ * The path is typically set by {@link #setFile(String)} or + * {@link #save(String)}. + *

+ * + *

+ * Developer Guide: As a legacy concept, the reliability on local files will + * be gradually reduced in future so that a workbook performs as a pure + * in-memory model and support more kinds of output targets to save to. So + * this method may one day be deprecated, and thus it's recommended that + * clients use external mechanisms to remember which output target a + * workbook refers to and is referred to. + *

+ * + * @return the file path that this workbook refers to + * @see #setFile(String) + * @see #save(String) + * @deprecated + */ + @Deprecated + String getFile(); + + /** + * Sets the path of a local file that this workbook will refer to. + * + *

+ * Developer Guide: As a legacy concept, the reliability on local files will + * be gradually reduced in future so that a workbook performs as a pure + * in-memory model and support more kinds of output targets to save to. So + * this method may one day be deprecated, and thus it's recommended that + * clients use external mechanisms to remember which output target a + * workbook refers to and is referred to. + *

+ * + * @param file + * the path of a new local file that this workbook will refer to + * @see #getFile() + * @deprecated + */ + @Deprecated + void setFile(String file); + + /** + * + * @param storage + * @deprecated + */ + @Deprecated + void setTempStorage(IStorage storage); + + /** + * + * @return + * @deprecated + */ + @Deprecated + IStorage getTempStorage(); + + /** + * + * @param tempLocation + * @deprecated + */ + @Deprecated + void setTempLocation(String tempLocation); + + /** + * + * @return + * @deprecated + */ + @Deprecated + String getTempLocation(); + + /** + * Saves temporary data to somewhere, or does nothing if not supported. The + * implementation decides how and where to save these data. + * + * @throws IOException + * @throws CoreException + * @deprecated Use + * Core.getSerializationProvider().newSerializer() + */ + @Deprecated + void saveTemp() throws IOException, CoreException; + + /** + * @deprecated + * @param password + */ + @Deprecated + void setPassword(String password); + + /** + * @return + * @deprecated + */ + @Deprecated + String getPassword(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java index 51cfe5375..b2520ffb6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java @@ -1,518 +1,518 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; - -/** - * A workbook builder is responsible for creating/loading/saving workbook - * instances. - * - *

- * Every workbook instance created by this workbook builder holds an - * {@link IStorage} object to store temporary data during creation/loading and - * afterwards. This storage object can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @author Frank Shaka - * @since 3.0 - */ -public interface IWorkbookBuilder { - - /** - * Creates a new empty workbook instance with a new in-memory - * storage. Equivalent to - * createWorkbook(new ByteArrayStorage()). - * - * @return a new empty workbook instance - */ - IWorkbook createWorkbook(); - - /** - * Creates a new empty workbook instance with the specified - * storage. The storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param storage - * used by the created workbook to store temporary data after - * creation - * @return a new empty workbook instance - */ - IWorkbook createWorkbook(IStorage storage); - - /** - * Creates a new instance of {@link ISerializer} used for saving a workbook - * to a location. - * - * @return a new serializer instance (never null) - */ - ISerializer newSerializer(); - - /** - * Creates a new instance of {@link IDeserializer} used for loading a - * workbook from a location. - * - * @return a new deserializer instance (never null) - */ - IDeserializer newDeserializer(); - - /** - * Sets the default name and version of all workbooks loaded/saved by this - * workbook builder, to be stored in their meta info. - * - * @param name - * the name of this builder - * @param version - * the version of this builder - */ - void setCreator(String name, String version); - - ///////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////// - //// - //// DEPRECATED METHODS - //// - ///////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////// - - /** - * Creates a new workbook instance and loads its content from the specified - * local file path, into a new in-memory storage. The default encryption - * handler of this workbook builder is used to decrypt any - * password-protected content during the process. - * - * @param path - * the absolute path of the local file from which the created - * workbook's content is loaded - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromPath(String path) throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * local file path, into a new in-memory storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. - * - * @param file - * the absolute path of the local file from which the created - * workbook's content is loaded - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromPath(String path, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * local file path, into the specified storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. The storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param file - * the absolute path of the local file from which the created - * workbok's content is loaded - * @param storage - * used by the created workbook to store temporary data after - * loading - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromPath(String path, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * local file, into a new in-memory storage. The default encryption handler - * of this workbook builder is used to decrypt any password-protected - * content during the process. - * - * @param file - * the local file from which the created workbook's content is - * loaded - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromFile(File file) throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * local file, into a new in-memory storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. - * - * @param file - * the local file from which the created workbook's content is - * loaded - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromFile(File file, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * local file, into the specified storage. The specified encryption handler - * is used to decrypt any password-protected content during the process. The - * storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param file - * the local file from which the created workbok's content is - * loaded - * @param storage - * used by the created workbook to store temporary data after - * loading - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromFile(File file, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input stream, into a new in-memory storage. The default encryption - * handler of this workbook builder is used to decrypt any - * password-protected content during the process. - * - *

- * NOTE that the specified input stream will be closed after this - * method returns. - *

- * - * @param in - * the input stream from which the created workbok's content is - * loaded - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStream(InputStream in) throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input stream, into the specified storage. The default encryption handler - * of this workbook builder is used to decrypt any password-protected - * content during the process. The storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - *

- * NOTE that the specified input stream will be closed after this - * method returns. - *

- * - * @param in - * the input stream from which the created workbok's content is - * loaded - * @param storage - * used by the created workbook to store temporary data after - * loading - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStream(InputStream in, IStorage storage) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input stream, into the specified storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. The storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - *

- * NOTE that the specified input stream will be closed after this - * method returns. - *

- * - * @param in - * the input stream from which the created workbok's content is - * loaded - * @param storage - * used by the created workbook to store temporary data after - * loading - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStream(InputStream in, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input source, into a new in-memory storage. The default encryption - * handler of this workbook builder is used to decrypt any - * password-protected content during the process. - * - * @param source - * the input source from which the created workbok's content is - * loaded - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromInputSource(IInputSource source) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input source, into a new in-memory storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. - * - * @param source - * the input source from which the created workbok's content is - * loaded - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromInputSource(IInputSource source, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a workbook instance and loads its content from the specified - * input source, into the specified storage. The specified encryption - * handler is used to decrypt any password-protected content during the - * process. The storage will be cleared. - * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param source - * the input source from which the created workbok's content is - * loaded - * @param storage - * used by the created workbook to store temporary data after - * loading - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs, or the operation is canceled - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromInputSource(IInputSource source, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Creates a new workbook instance and loads its content directly - * from the specified storage. The default encryption handler of this - * workbook builder is used to decrypt any password-protected content during - * the process. - * - *

- * The storage will NOT be cleared so that all existing data in it - * will be preserved. If the storage is empty or corrupted, loading errors - * may occur. - *

- * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param storage - * used by the worbook to load initial content and store - * temporary data after loading - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStorage(IStorage storage) - throws IOException, CoreException; - - /** - * Creates a new workbook instance and loads its content directly - * from the specified storage. The specified encryption handler is used to - * decrypt any password-protected content during the process. - * - *

- * The storage will NOT be cleared so that all existing data in it - * will be preserved. If the storage is empty or corrupted, loading errors - * may occur. - *

- * - *

- * The storage can be retrieved using - * workbook.getAdapter(IStorage.class). - *

- * - * @param storage - * used by the worbook to load initial content and store - * temporary data after loading - * @param encryptionHandler - * providing decryption information - * @return a new workbook instance with content - * @throws IOException - * if any I/O error occurs - * @throws CoreException - * if any syntax error occurs - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStorage(IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * Sets the default encryption handler to use for loadFromXXX methods. - * - * @param encryptionHandler - * the new encryption handler to use - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - void setDefaultEncryptionHandler(IEncryptionHandler encryptionHandler); - - /** - * @deprecated Do NOT let workbook know about its file path. - */ - @Deprecated - IWorkbook createWorkbook(String targetPath); - - /** - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook createWorkbookOnTemp(String tempLocation); - - /** - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStream(InputStream in, String tempLocation) - throws IOException, CoreException; - - /** - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromStream(InputStream in, String tempLocation, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - /** - * @deprecated See {@link org.xmind.core.IDeserializer} - */ - @Deprecated - IWorkbook loadFromTempLocation(String tempLocation) - throws IOException, CoreException; - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; + +/** + * A workbook builder is responsible for creating/loading/saving workbook + * instances. + * + *

+ * Every workbook instance created by this workbook builder holds an + * {@link IStorage} object to store temporary data during creation/loading and + * afterwards. This storage object can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @author Frank Shaka + * @since 3.0 + */ +public interface IWorkbookBuilder { + + /** + * Creates a new empty workbook instance with a new in-memory + * storage. Equivalent to + * createWorkbook(new ByteArrayStorage()). + * + * @return a new empty workbook instance + */ + IWorkbook createWorkbook(); + + /** + * Creates a new empty workbook instance with the specified + * storage. The storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param storage + * used by the created workbook to store temporary data after + * creation + * @return a new empty workbook instance + */ + IWorkbook createWorkbook(IStorage storage); + + /** + * Creates a new instance of {@link ISerializer} used for saving a workbook + * to a location. + * + * @return a new serializer instance (never null) + */ + ISerializer newSerializer(); + + /** + * Creates a new instance of {@link IDeserializer} used for loading a + * workbook from a location. + * + * @return a new deserializer instance (never null) + */ + IDeserializer newDeserializer(); + + /** + * Sets the default name and version of all workbooks loaded/saved by this + * workbook builder, to be stored in their meta info. + * + * @param name + * the name of this builder + * @param version + * the version of this builder + */ + void setCreator(String name, String version); + + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + //// + //// DEPRECATED METHODS + //// + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + + /** + * Creates a new workbook instance and loads its content from the specified + * local file path, into a new in-memory storage. The default encryption + * handler of this workbook builder is used to decrypt any + * password-protected content during the process. + * + * @param path + * the absolute path of the local file from which the created + * workbook's content is loaded + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromPath(String path) throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * local file path, into a new in-memory storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. + * + * @param file + * the absolute path of the local file from which the created + * workbook's content is loaded + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromPath(String path, IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * local file path, into the specified storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. The storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param file + * the absolute path of the local file from which the created + * workbok's content is loaded + * @param storage + * used by the created workbook to store temporary data after + * loading + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromPath(String path, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * local file, into a new in-memory storage. The default encryption handler + * of this workbook builder is used to decrypt any password-protected + * content during the process. + * + * @param file + * the local file from which the created workbook's content is + * loaded + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromFile(File file) throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * local file, into a new in-memory storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. + * + * @param file + * the local file from which the created workbook's content is + * loaded + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromFile(File file, IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * local file, into the specified storage. The specified encryption handler + * is used to decrypt any password-protected content during the process. The + * storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param file + * the local file from which the created workbok's content is + * loaded + * @param storage + * used by the created workbook to store temporary data after + * loading + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromFile(File file, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input stream, into a new in-memory storage. The default encryption + * handler of this workbook builder is used to decrypt any + * password-protected content during the process. + * + *

+ * NOTE that the specified input stream will be closed after this + * method returns. + *

+ * + * @param in + * the input stream from which the created workbok's content is + * loaded + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStream(InputStream in) throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input stream, into the specified storage. The default encryption handler + * of this workbook builder is used to decrypt any password-protected + * content during the process. The storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + *

+ * NOTE that the specified input stream will be closed after this + * method returns. + *

+ * + * @param in + * the input stream from which the created workbok's content is + * loaded + * @param storage + * used by the created workbook to store temporary data after + * loading + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStream(InputStream in, IStorage storage) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input stream, into the specified storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. The storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + *

+ * NOTE that the specified input stream will be closed after this + * method returns. + *

+ * + * @param in + * the input stream from which the created workbok's content is + * loaded + * @param storage + * used by the created workbook to store temporary data after + * loading + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStream(InputStream in, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input source, into a new in-memory storage. The default encryption + * handler of this workbook builder is used to decrypt any + * password-protected content during the process. + * + * @param source + * the input source from which the created workbok's content is + * loaded + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromInputSource(IInputSource source) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input source, into a new in-memory storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. + * + * @param source + * the input source from which the created workbok's content is + * loaded + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromInputSource(IInputSource source, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a workbook instance and loads its content from the specified + * input source, into the specified storage. The specified encryption + * handler is used to decrypt any password-protected content during the + * process. The storage will be cleared. + * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param source + * the input source from which the created workbok's content is + * loaded + * @param storage + * used by the created workbook to store temporary data after + * loading + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs, or the operation is canceled + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromInputSource(IInputSource source, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Creates a new workbook instance and loads its content directly + * from the specified storage. The default encryption handler of this + * workbook builder is used to decrypt any password-protected content during + * the process. + * + *

+ * The storage will NOT be cleared so that all existing data in it + * will be preserved. If the storage is empty or corrupted, loading errors + * may occur. + *

+ * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param storage + * used by the worbook to load initial content and store + * temporary data after loading + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStorage(IStorage storage) + throws IOException, CoreException; + + /** + * Creates a new workbook instance and loads its content directly + * from the specified storage. The specified encryption handler is used to + * decrypt any password-protected content during the process. + * + *

+ * The storage will NOT be cleared so that all existing data in it + * will be preserved. If the storage is empty or corrupted, loading errors + * may occur. + *

+ * + *

+ * The storage can be retrieved using + * workbook.getAdapter(IStorage.class). + *

+ * + * @param storage + * used by the worbook to load initial content and store + * temporary data after loading + * @param encryptionHandler + * providing decryption information + * @return a new workbook instance with content + * @throws IOException + * if any I/O error occurs + * @throws CoreException + * if any syntax error occurs + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStorage(IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * Sets the default encryption handler to use for loadFromXXX methods. + * + * @param encryptionHandler + * the new encryption handler to use + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + void setDefaultEncryptionHandler(IEncryptionHandler encryptionHandler); + + /** + * @deprecated Do NOT let workbook know about its file path. + */ + @Deprecated + IWorkbook createWorkbook(String targetPath); + + /** + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook createWorkbookOnTemp(String tempLocation); + + /** + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStream(InputStream in, String tempLocation) + throws IOException, CoreException; + + /** + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromStream(InputStream in, String tempLocation, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + /** + * @deprecated See {@link org.xmind.core.IDeserializer} + */ + @Deprecated + IWorkbook loadFromTempLocation(String tempLocation) + throws IOException, CoreException; + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookComponent.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookComponent.java index b43a3d499..14c2ceb2b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookComponent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookComponent.java @@ -1,43 +1,43 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -public interface IWorkbookComponent { - - /** - * Gets the workbook who owns this component. - * - * @return the owned workbook - */ - IWorkbook getOwnedWorkbook(); - - /** - * Determines whether this component is isolated from the owned workbook. - * - *

- * Isolated objects are objects that is owned by this workbook but will not - * be saved with this workbook. - *

- *

- * To isolate an object, generally call removeXXX() from its - * parent. To attach an isolated object, generally call corresponding - * addXXX() from a parental object. - *

- * - * @return true if this component is isolated from its owned - * workbook, false otherwise - */ - boolean isOrphan(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +public interface IWorkbookComponent { + + /** + * Gets the workbook who owns this component. + * + * @return the owned workbook + */ + IWorkbook getOwnedWorkbook(); + + /** + * Determines whether this component is isolated from the owned workbook. + * + *

+ * Isolated objects are objects that is owned by this workbook but will not + * be saved with this workbook. + *

+ *

+ * To isolate an object, generally call removeXXX() from its + * parent. To attach an isolated object, generally call corresponding + * addXXX() from a parental object. + *

+ * + * @return true if this component is isolated from its owned + * workbook, false otherwise + */ + boolean isOrphan(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java index 837c20cc4..d3d6ef266 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java @@ -1,22 +1,22 @@ -package org.xmind.core; - -import java.util.List; - -/** - * @author Jason Wong - */ -public interface IWorkbookExtension extends IAdaptable, IWorkbookComponent { - - String getProviderName(); - - IWorkbookExtensionElement getContent(); - - List getResourceRefs(); - - void addResourceRef(IResourceRef ref); - - void removeResourceRef(IResourceRef ref); - - IResourceRef getResourceRef(String resourceId); - -} +package org.xmind.core; + +import java.util.List; + +/** + * @author Jason Wong + */ +public interface IWorkbookExtension extends IAdaptable, IWorkbookComponent { + + String getProviderName(); + + IWorkbookExtensionElement getContent(); + + List getResourceRefs(); + + void addResourceRef(IResourceRef ref); + + void removeResourceRef(IResourceRef ref); + + IResourceRef getResourceRef(String resourceId); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java index 7832cdb8d..25ac7d4aa 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java @@ -1,19 +1,19 @@ -package org.xmind.core; - -/** - * @author Jason Wong - */ -public interface IWorkbookExtensionElement extends IAdaptable, - IWorkbookComponent, IExtensionElement { - - IWorkbookExtension getExtension(); - - void setResourcePath(String resourcePath); - - String getResourcePath(); - - void setObjectId(String objectId); - - String getObjectId(); - -} +package org.xmind.core; + +/** + * @author Jason Wong + */ +public interface IWorkbookExtensionElement extends IAdaptable, + IWorkbookComponent, IExtensionElement { + + IWorkbookExtension getExtension(); + + void setResourcePath(String resourcePath); + + String getResourcePath(); + + void setObjectId(String objectId); + + String getObjectId(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java index 020d795ae..5e5d4dc85 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java @@ -1,20 +1,20 @@ -package org.xmind.core; - -import java.util.List; - -/** - * @author Jason Wong - */ -public interface IWorkbookExtensionManager extends IWorkbookComponent { - - List getExtensions(); - - IWorkbookExtension getExtension(String providerName); - - IWorkbookExtension createExtension(String providerName); - - void deleteExtension(String providerName); - - List getProviders(); - -} +package org.xmind.core; + +import java.util.List; + +/** + * @author Jason Wong + */ +public interface IWorkbookExtensionManager extends IWorkbookComponent { + + List getExtensions(); + + IWorkbookExtension getExtension(String providerName); + + IWorkbookExtension createExtension(String providerName); + + void deleteExtension(String providerName); + + List getProviders(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java index c38c22510..5e0c70fd9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java @@ -1,148 +1,148 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core; - -import java.io.File; - -/** - * A workspace is a location in local file system where XMind Core stores - * temporary and preference data. - * - *

- * NOTE: This interface is not intended to be implemented by client. - * Use the facade method Core.getWorkspace() to get a singleton - * instance. - *

- * - * @author Frank Shaka (frank@xmind.net) - * @since 1.0 - */ -public interface IWorkspace { - - /** - * A relative path representing the temporary sub-directory inside a - * workspace. - * - * @see #getTempDir() - */ - String DIR_TEMP = "temp"; //$NON-NLS-1$ - - /** - * Returns the root directory of this workspace. XMind Core must be given - * read-and-write access to this directory and all contents inside it. - * - *

- * The result will be searched for in the following order: - * - *

    - *
  1. the path set by invoking setWorkingDirectory(String); - *
  2. - *
  3. "${org.xmind.core.workspace}" if - * org.xmind.core.workspace system property exists;
  4. - *
  5. ".xmind" under the program's current working directory. - *
  6. - *
- *

- * - * @return the root directory of this workspace (never null) - */ - String getWorkingDirectory(); - - /** - * Sets the root directory of this workspace. The current program must be - * given read-and-write access to this directory and all contents inside it. - * If the directory does not exist, it will be automatically created on - * demand. - * - * @param path - * an absolute path to set, or null to indicate - * system defaults should be used - */ - void setWorkingDirectory(String path); - - /** - * Calculates and returns an absolute file path representing a sub-directory - * inside this workspace specified by the relative subPath - * based on the root of this workspace. - * - * @param subPath - * a relative path inside this workspace - * @return an absolute path representing the desired file inside this - * workspace - */ - String getAbsolutePath(String subPath); - - /** - * Returns an absolute path representing the sub-directory inside this - * workspace for storing temporary data. - * - *

- * This method behaves equivalent to getAbsolutePath(DIR_TEMP). - *

- * - * @return an absolute path of the temporary data sub-directory - */ - String getTempDir(); - - /** - * Calculates and returns an absolute path representing a sub-directory - * inside this workspace specified by the relative subDir based - * on the temporary data sub-directory in this workspace. If the - * sub-directory does not exist, it will be created before returned. - * - * @param subDir - * a relative path based on the temporary data sub-directory - * @return an absolute path representing the desired directory inside this - * workspace - */ - String getTempDir(String subDir); - - /** - * Calculates and returns an absolute path representing a file inside this - * workspace specified by the relative fileName based on the - * temporary data sub-directory in this workspace. - * - * @param fileName - * a relative path based on the temporary data sub-directory - * @return an absolute path representing the desired file inside this - * workspace - */ - String getTempFile(String fileName); - - /** - * Creates a new empty file in the directory specified by the relative - * subDir based on the temporary data sub-directory inside this - * workspace, using the given prefix and suffix to - * generate its name. It is guaranteed that the file denoted by the returned - * abstract pathname did not exist before this method was invoked. - * - *

- * This method simply ensures that the subDir sub-directory - * exists and calls File.createTempFile(String, String, File) - * to create the empty file. - *

- * - * @param subDir - * a relative path based on the temporary data sub-directory - * @param prefix - * The prefix string to be used in generating the file's name; - * must be at least three characters long - * @param suffix - * The suffix string to be used in generating the file's name; - * may be null, in which case the suffix ".tmp" will be used - * @return a new empty file - */ - File createTempFile(String subDir, String prefix, String suffix); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core; + +import java.io.File; + +/** + * A workspace is a location in local file system where XMind Core stores + * temporary and preference data. + * + *

+ * NOTE: This interface is not intended to be implemented by client. + * Use the facade method Core.getWorkspace() to get a singleton + * instance. + *

+ * + * @author Frank Shaka (frank@xmind.net) + * @since 1.0 + */ +public interface IWorkspace { + + /** + * A relative path representing the temporary sub-directory inside a + * workspace. + * + * @see #getTempDir() + */ + String DIR_TEMP = "temp"; //$NON-NLS-1$ + + /** + * Returns the root directory of this workspace. XMind Core must be given + * read-and-write access to this directory and all contents inside it. + * + *

+ * The result will be searched for in the following order: + * + *

    + *
  1. the path set by invoking setWorkingDirectory(String); + *
  2. + *
  3. "${org.xmind.core.workspace}" if + * org.xmind.core.workspace system property exists;
  4. + *
  5. ".xmind" under the program's current working directory. + *
  6. + *
+ *

+ * + * @return the root directory of this workspace (never null) + */ + String getWorkingDirectory(); + + /** + * Sets the root directory of this workspace. The current program must be + * given read-and-write access to this directory and all contents inside it. + * If the directory does not exist, it will be automatically created on + * demand. + * + * @param path + * an absolute path to set, or null to indicate + * system defaults should be used + */ + void setWorkingDirectory(String path); + + /** + * Calculates and returns an absolute file path representing a sub-directory + * inside this workspace specified by the relative subPath + * based on the root of this workspace. + * + * @param subPath + * a relative path inside this workspace + * @return an absolute path representing the desired file inside this + * workspace + */ + String getAbsolutePath(String subPath); + + /** + * Returns an absolute path representing the sub-directory inside this + * workspace for storing temporary data. + * + *

+ * This method behaves equivalent to getAbsolutePath(DIR_TEMP). + *

+ * + * @return an absolute path of the temporary data sub-directory + */ + String getTempDir(); + + /** + * Calculates and returns an absolute path representing a sub-directory + * inside this workspace specified by the relative subDir based + * on the temporary data sub-directory in this workspace. If the + * sub-directory does not exist, it will be created before returned. + * + * @param subDir + * a relative path based on the temporary data sub-directory + * @return an absolute path representing the desired directory inside this + * workspace + */ + String getTempDir(String subDir); + + /** + * Calculates and returns an absolute path representing a file inside this + * workspace specified by the relative fileName based on the + * temporary data sub-directory in this workspace. + * + * @param fileName + * a relative path based on the temporary data sub-directory + * @return an absolute path representing the desired file inside this + * workspace + */ + String getTempFile(String fileName); + + /** + * Creates a new empty file in the directory specified by the relative + * subDir based on the temporary data sub-directory inside this + * workspace, using the given prefix and suffix to + * generate its name. It is guaranteed that the file denoted by the returned + * abstract pathname did not exist before this method was invoked. + * + *

+ * This method simply ensures that the subDir sub-directory + * exists and calls File.createTempFile(String, String, File) + * to create the empty file. + *

+ * + * @param subDir + * a relative path based on the temporary data sub-directory + * @param prefix + * The prefix string to be used in generating the file's name; + * must be at least three characters long + * @param suffix + * The suffix string to be used in generating the file's name; + * may be null, in which case the suffix ".tmp" will be used + * @return a new empty file + */ + File createTempFile(String subDir, String prefix, String suffix); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/CoreEvent.java b/bundles/org.xmind.core/src/org/xmind/core/event/CoreEvent.java index 25b790351..909d3a81b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/CoreEvent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/CoreEvent.java @@ -1,173 +1,173 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -import java.util.EventObject; - -/** - * @author MANGOSOFT - * - */ -public class CoreEvent extends EventObject { - - /** - * - */ - private static final long serialVersionUID = -5729530103366986314L; - - private String type; - - private Object oldValue; - - private Object newValue; - - private int index; - - private Object target; - - private Object data; - - public CoreEvent(ICoreEventSource source, String type, Object target) { - this(source, type, target, null, null, -1); - } - - public CoreEvent(ICoreEventSource source, String type, Object target, - int index) { - this(source, type, target, null, null, index); - } - - public CoreEvent(ICoreEventSource source, String type, Object target, - Object oldValue, Object newValue) { - this(source, type, target, oldValue, newValue, -1); - } - - public CoreEvent(ICoreEventSource source, String type, Object oldValue, - Object newValue) { - this(source, type, null, oldValue, newValue, -1); - } - - public CoreEvent(ICoreEventSource source, String type, Object oldValue, - Object newValue, int index) { - this(source, type, null, oldValue, newValue, index); - } - - public CoreEvent(ICoreEventSource source, String type, Object target, - Object oldValue, Object newValue, int index) { - super(source); - this.type = type; - this.oldValue = oldValue; - this.newValue = newValue; - this.target = target; - this.index = index; - } - - /** - * @return - */ - public ICoreEventSource getEventSource() { - return (ICoreEventSource) getSource(); - } - - /** - * - * @return - */ - public String getType() { - return type; - } - - /** - * @return - */ - public Object getOldValue() { - return oldValue; - } - - /** - * @return - */ - public Object getNewValue() { - return newValue; - } - - public void setNewValue(Object newValue) { - this.newValue = newValue; - } - - public void setOldValue(Object oldValue) { - this.oldValue = oldValue; - } - - /** - * - * @return - */ - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - /** - * - * @return - */ - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - - public Object getTarget() { - return target; - } - - public void setTarget(Object target) { - this.target = target; - } - - public String toString() { - StringBuilder sb = new StringBuilder(30); - sb.append("{type="); //$NON-NLS-1$ - sb.append(type); - sb.append(",source="); //$NON-NLS-1$ - sb.append(source); - if (target != null) { - sb.append(",target="); //$NON-NLS-1$ - sb.append(target); - } - if (oldValue != null) { - sb.append(",oldValue="); //$NON-NLS-1$ - sb.append(oldValue); - } - if (newValue != null) { - sb.append(",newValue="); //$NON-NLS-1$ - sb.append(newValue); - } - if (index >= 0) { - sb.append(",index="); //$NON-NLS-1$ - sb.append(index); - } - if (data != null) { - sb.append(",data="); //$NON-NLS-1$ - sb.append(data); - } - sb.append("}"); //$NON-NLS-1$ - return sb.toString(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +import java.util.EventObject; + +/** + * @author MANGOSOFT + * + */ +public class CoreEvent extends EventObject { + + /** + * + */ + private static final long serialVersionUID = -5729530103366986314L; + + private String type; + + private Object oldValue; + + private Object newValue; + + private int index; + + private Object target; + + private Object data; + + public CoreEvent(ICoreEventSource source, String type, Object target) { + this(source, type, target, null, null, -1); + } + + public CoreEvent(ICoreEventSource source, String type, Object target, + int index) { + this(source, type, target, null, null, index); + } + + public CoreEvent(ICoreEventSource source, String type, Object target, + Object oldValue, Object newValue) { + this(source, type, target, oldValue, newValue, -1); + } + + public CoreEvent(ICoreEventSource source, String type, Object oldValue, + Object newValue) { + this(source, type, null, oldValue, newValue, -1); + } + + public CoreEvent(ICoreEventSource source, String type, Object oldValue, + Object newValue, int index) { + this(source, type, null, oldValue, newValue, index); + } + + public CoreEvent(ICoreEventSource source, String type, Object target, + Object oldValue, Object newValue, int index) { + super(source); + this.type = type; + this.oldValue = oldValue; + this.newValue = newValue; + this.target = target; + this.index = index; + } + + /** + * @return + */ + public ICoreEventSource getEventSource() { + return (ICoreEventSource) getSource(); + } + + /** + * + * @return + */ + public String getType() { + return type; + } + + /** + * @return + */ + public Object getOldValue() { + return oldValue; + } + + /** + * @return + */ + public Object getNewValue() { + return newValue; + } + + public void setNewValue(Object newValue) { + this.newValue = newValue; + } + + public void setOldValue(Object oldValue) { + this.oldValue = oldValue; + } + + /** + * + * @return + */ + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + /** + * + * @return + */ + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public Object getTarget() { + return target; + } + + public void setTarget(Object target) { + this.target = target; + } + + public String toString() { + StringBuilder sb = new StringBuilder(30); + sb.append("{type="); //$NON-NLS-1$ + sb.append(type); + sb.append(",source="); //$NON-NLS-1$ + sb.append(source); + if (target != null) { + sb.append(",target="); //$NON-NLS-1$ + sb.append(target); + } + if (oldValue != null) { + sb.append(",oldValue="); //$NON-NLS-1$ + sb.append(oldValue); + } + if (newValue != null) { + sb.append(",newValue="); //$NON-NLS-1$ + sb.append(newValue); + } + if (index >= 0) { + sb.append(",index="); //$NON-NLS-1$ + sb.append(index); + } + if (data != null) { + sb.append(",data="); //$NON-NLS-1$ + sb.append(data); + } + sb.append("}"); //$NON-NLS-1$ + return sb.toString(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventListener.java b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventListener.java index 185ffa5ca..473e61a4c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventListener.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventListener.java @@ -1,37 +1,37 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -/** - * @author MANGOSOFT - * - */ -public interface ICoreEventListener { - - static class NullCoreEventListener implements ICoreEventListener { - - public void handleCoreEvent(CoreEvent event) { - // do nothing - } - - } - - public static final ICoreEventListener NULL = new NullCoreEventListener(); - - /** - * @param event - */ - void handleCoreEvent(CoreEvent event); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +/** + * @author MANGOSOFT + * + */ +public interface ICoreEventListener { + + static class NullCoreEventListener implements ICoreEventListener { + + public void handleCoreEvent(CoreEvent event) { + // do nothing + } + + } + + public static final ICoreEventListener NULL = new NullCoreEventListener(); + + /** + * @param event + */ + void handleCoreEvent(CoreEvent event); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventRegistration.java b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventRegistration.java index 910505770..ef07cb4a3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventRegistration.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventRegistration.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -/** - * @author MANGOSOFT - * - */ -public interface ICoreEventRegistration { - - void unregister(); - - /** - * Returns false after unregister, otherwise returns - * true. - * - * @return - */ - boolean isValid(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +/** + * @author MANGOSOFT + * + */ +public interface ICoreEventRegistration { + + void unregister(); + + /** + * Returns false after unregister, otherwise returns + * true. + * + * @return + */ + boolean isValid(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource.java b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource.java index 0e5dca73b..33ed31371 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource.java @@ -1,36 +1,36 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -/** - * @author Frank Shaka - * - */ -public interface ICoreEventSource { - - /** - * @param type - * @param listener - * @return - */ - ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener); - - /** - * - * @return - */ - ICoreEventSupport getCoreEventSupport(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +/** + * @author Frank Shaka + * + */ +public interface ICoreEventSource { + + /** + * @param type + * @param listener + * @return + */ + ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener); + + /** + * + * @return + */ + ICoreEventSupport getCoreEventSupport(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource2.java b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource2.java index 4c1e54a16..1c9fb08dd 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource2.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSource2.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -/** - * @author Frank Shaka - * - */ -public interface ICoreEventSource2 { - - ICoreEventRegistration registerOnceCoreEventListener(String eventType, - ICoreEventListener listener); - - boolean hasOnceListeners(String eventType); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +/** + * @author Frank Shaka + * + */ +public interface ICoreEventSource2 { + + ICoreEventRegistration registerOnceCoreEventListener(String eventType, + ICoreEventListener listener); + + boolean hasOnceListeners(String eventType); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSupport.java b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSupport.java index 05b832fd3..b8a2e7caa 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSupport.java +++ b/bundles/org.xmind.core/src/org/xmind/core/event/ICoreEventSupport.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.event; - -public interface ICoreEventSupport { - - ICoreEventRegistration registerCoreEventListener(ICoreEventSource source, - String eventType, ICoreEventListener listener); - - ICoreEventRegistration registerGlobalListener(String eventType, - ICoreEventListener listener); - - ICoreEventRegistration registerOnceCoreEventListener( - ICoreEventSource source, String eventType, - ICoreEventListener listener); - - ICoreEventRegistration registerOnceGlobalListener(String eventType, - ICoreEventListener listener); - - void dispatchValueChange(ICoreEventSource source, String eventType, - Object oldValue, Object newValue); - - void dispatchIndexedValueChange(ICoreEventSource source, String eventType, - Object oldValue, Object newValue, int index); - - void dispatchTargetChange(ICoreEventSource source, String eventType, - Object target); - - void dispatchIndexedTargetChange(ICoreEventSource source, String eventType, - Object target, int index); - - void dispatchTargetValueChange(ICoreEventSource source, String eventType, - Object target, Object oldValue, Object newValue); - - void dispatch(ICoreEventSource source, CoreEvent event); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.event; + +public interface ICoreEventSupport { + + ICoreEventRegistration registerCoreEventListener(ICoreEventSource source, + String eventType, ICoreEventListener listener); + + ICoreEventRegistration registerGlobalListener(String eventType, + ICoreEventListener listener); + + ICoreEventRegistration registerOnceCoreEventListener( + ICoreEventSource source, String eventType, + ICoreEventListener listener); + + ICoreEventRegistration registerOnceGlobalListener(String eventType, + ICoreEventListener listener); + + void dispatchValueChange(ICoreEventSource source, String eventType, + Object oldValue, Object newValue); + + void dispatchIndexedValueChange(ICoreEventSource source, String eventType, + Object oldValue, Object newValue, int index); + + void dispatchTargetChange(ICoreEventSource source, String eventType, + Object target); + + void dispatchIndexedTargetChange(ICoreEventSource source, String eventType, + Object target, int index); + + void dispatchTargetValueChange(ICoreEventSource source, String eventType, + Object target, Object oldValue, Object newValue); + + void dispatch(ICoreEventSource source, CoreEvent event); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractSerializingBase.java b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractSerializingBase.java index 7adf716e4..95884b057 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractSerializingBase.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractSerializingBase.java @@ -1,66 +1,66 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal; - -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.ISerializingBase; - -/** - * @author Frank Shaka - * - */ -public abstract class AbstractSerializingBase implements ISerializingBase { - - private String creatorName; - private String creatorVersion; - private IEntryStreamNormalizer encryptionHandler; - - /** - * - */ - protected AbstractSerializingBase() { - this.creatorName = null; - this.creatorVersion = null; - this.encryptionHandler = null; - } - - public String getCreatorName() { - return creatorName; - } - - public String getCreatorVersion() { - return creatorVersion; - } - - public void setCreatorName(String name) { - this.creatorName = name; - } - - public void setCreatorVersion(String version) { - this.creatorVersion = version; - } - - public IEntryStreamNormalizer getEntryStreamNormalizer() { - return encryptionHandler; - } - - public void setEntryStreamNormalizer( - IEntryStreamNormalizer encryptionHandler) { - this.encryptionHandler = encryptionHandler; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal; + +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.ISerializingBase; + +/** + * @author Frank Shaka + * + */ +public abstract class AbstractSerializingBase implements ISerializingBase { + + private String creatorName; + private String creatorVersion; + private IEntryStreamNormalizer encryptionHandler; + + /** + * + */ + protected AbstractSerializingBase() { + this.creatorName = null; + this.creatorVersion = null; + this.encryptionHandler = null; + } + + public String getCreatorName() { + return creatorName; + } + + public String getCreatorVersion() { + return creatorVersion; + } + + public void setCreatorName(String name) { + this.creatorName = name; + } + + public void setCreatorVersion(String version) { + this.creatorVersion = version; + } + + public IEntryStreamNormalizer getEntryStreamNormalizer() { + return encryptionHandler; + } + + public void setEntryStreamNormalizer( + IEntryStreamNormalizer encryptionHandler) { + this.encryptionHandler = encryptionHandler; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookBuilder.java b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookBuilder.java index 12e49c5f2..37910d1f8 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookBuilder.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookBuilder.java @@ -1,321 +1,321 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.CoreException; -import org.xmind.core.IEncryptionHandler; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookBuilder; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.FileUtils; - -@SuppressWarnings("deprecation") -public abstract class AbstractWorkbookBuilder implements IWorkbookBuilder { - - private IEncryptionHandler defaultEncryptionHandler = null; - - public String creatorName; - - public String creatorVersion; - - public synchronized void setDefaultEncryptionHandler( - IEncryptionHandler encryptionHandler) { - if (this.defaultEncryptionHandler != null) - return; - - this.defaultEncryptionHandler = encryptionHandler; - } - - public synchronized void setCreator(String name, String version) { - this.creatorName = name; - this.creatorVersion = version; - } - - protected IEncryptionHandler getDefaultEncryptionHandler() { - return this.defaultEncryptionHandler; - } - - public String getCreatorName() { - return this.creatorName; - } - - public String getCreatorVersion() { - return this.creatorVersion; - } - - public IWorkbook createWorkbook() { - return createWorkbook(new ByteArrayStorage()); - } - - public IWorkbook createWorkbook(IStorage storage) { - return doCreateWorkbook(storage); - } - - public IWorkbook loadFromPath(String path) - throws IOException, CoreException { - return loadFromPath(path, new ByteArrayStorage(), - getDefaultEncryptionHandler()); - } - - public IWorkbook loadFromPath(String path, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - return loadFromPath(path, new ByteArrayStorage(), encryptionHandler); - } - - public IWorkbook loadFromPath(String path, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (path == null) - throw new IllegalArgumentException("Path is null"); //$NON-NLS-1$ - return doLoadFromPath(path, storage, encryptionHandler); - } - - public IWorkbook loadFromFile(File file) throws IOException, CoreException { - return loadFromFile(file, new ByteArrayStorage(), - getDefaultEncryptionHandler()); - } - - public IWorkbook loadFromFile(File file, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - return loadFromFile(file, new ByteArrayStorage(), encryptionHandler); - } - - public IWorkbook loadFromFile(File file, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (file == null) - throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ - if (!file.exists()) - throw new FileNotFoundException("File not exists: " + file); //$NON-NLS-1$ - - if (file.isDirectory()) { - return doLoadFromDirectory(file, storage, encryptionHandler); - } - - if (!file.canRead()) - throw new IOException("File can't be read: " + file); //$NON-NLS-1$ - - return doLoadFromFile(file, storage, encryptionHandler); - } - - public IWorkbook loadFromStream(InputStream in) - throws IOException, CoreException { - return loadFromStream(in, new ByteArrayStorage(), - getDefaultEncryptionHandler()); - } - - public IWorkbook loadFromStream(InputStream in, IStorage storage) - throws IOException, CoreException { - return loadFromStream(in, storage, getDefaultEncryptionHandler()); - } - - public IWorkbook loadFromStream(InputStream in, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (in == null) - throw new IllegalArgumentException("Input stream is null"); //$NON-NLS-1$ - return doLoadFromStream(in, storage, encryptionHandler); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.IWorkbookBuilder#loadFromInputSource(org.xmind.core.io - * .IInputSource) - */ - public IWorkbook loadFromInputSource(IInputSource source) - throws IOException, CoreException { - return loadFromInputSource(source, new ByteArrayStorage(), - getDefaultEncryptionHandler()); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.IWorkbookBuilder#loadFromInputSource(org.xmind.core.io - * .IInputSource, org.xmind.core.IEncryptionHandler) - */ - public IWorkbook loadFromInputSource(IInputSource source, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - return loadFromInputSource(source, new ByteArrayStorage(), - encryptionHandler); - } - - /** - * - * @param source - * @param storage - * @param encryptionHandler - * @return - * @throws IOException - * @throws CoreException - */ - public IWorkbook loadFromInputSource(IInputSource source, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (source == null) - throw new IllegalArgumentException("Input source is null"); //$NON-NLS-1$ - return doLoadFromInputSource(source, storage, encryptionHandler); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IWorkbookBuilder#loadFromStorage(org.xmind.core.io. - * IStorage ) - */ - public IWorkbook loadFromStorage(IStorage storage) - throws IOException, CoreException { - if (storage == null) - throw new IllegalArgumentException("Storage is null"); //$NON-NLS-1$ - return loadFromStorage(storage, null); - } - - public IWorkbook loadFromStorage(IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (storage == null) - throw new IllegalArgumentException("Storage is null"); //$NON-NLS-1$ - return doLoadFromStorage(storage, encryptionHandler); - } - - @Deprecated - public IWorkbook loadFromTempLocation(String tempLocation) - throws IOException, CoreException { - if (tempLocation == null) - throw new IllegalArgumentException("Temp location is null"); //$NON-NLS-1$ - File dir = new File(tempLocation); - if (!dir.exists()) - throw new FileNotFoundException( - "Temp location not found: " + tempLocation); //$NON-NLS-1$ - if (!dir.isDirectory()) - throw new FileNotFoundException( - "Temp location is not directory: " + tempLocation); //$NON-NLS-1$ - DirectoryStorage storage = new DirectoryStorage(dir); -// return loadFromInputSource(storage.getInputSource(), storage, null); - return doLoadFromStorage(storage, null); - } - - //////////////////////////////////////////////////////////////// - // - // Methods That Subclasses Can Override - // - //////////////////////////////////////////////////////////////// - - protected abstract IWorkbook doCreateWorkbook(IStorage storage); - - protected IWorkbook doLoadFromPath(String path, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - return loadFromFile(new File(path), storage, encryptionHandler); - } - - protected IWorkbook doLoadFromDirectory(File dir, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - return loadFromInputSource(new DirectoryInputSource(dir), storage, - encryptionHandler); - } - - protected IWorkbook doLoadFromFile(File file, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException, FileNotFoundException { - return loadFromStream(new FileInputStream(file), storage, - encryptionHandler); - } - - protected IWorkbook doLoadFromStream(InputStream in, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (storage == null) - storage = new ByteArrayStorage(); - try { - extractFromStream(in, storage.getOutputTarget()); - } finally { - in.close(); - } - return doLoadFromStorage(storage, encryptionHandler); - } - - protected IWorkbook doLoadFromInputSource(IInputSource source, - IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (storage == null) - storage = new ByteArrayStorage(); - FileUtils.transfer(source, storage.getOutputTarget()); - return doLoadFromStorage(storage, encryptionHandler); - } - - protected abstract void extractFromStream(InputStream input, - IOutputTarget target) throws IOException, CoreException; - - protected abstract IWorkbook doLoadFromStorage(IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException; - - //////////////////////////////////////////////////////////////// - // - // Deprecated Methods - // - //////////////////////////////////////////////////////////////// - - @Deprecated - public IWorkbook createWorkbook(String targetPath) { - return createWorkbook(new ByteArrayStorage()); - } - - @Deprecated - public IWorkbook createWorkbookOnTemp(String tempLocation) { - return createWorkbook(new DirectoryStorage(new File(tempLocation))); - } - - @Deprecated - public IWorkbook loadFromStream(InputStream in, String tempLocation) - throws IOException, CoreException { - return loadFromStream(in, tempLocation, null); - } - - @Deprecated - public IWorkbook loadFromStream(InputStream in, String tempLocation, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - if (tempLocation == null) - throw new IllegalArgumentException("Temp location is null"); //$NON-NLS-1$ - File dir = new File(tempLocation); - if (!dir.exists()) - throw new FileNotFoundException( - "Temp location not found: " + tempLocation); //$NON-NLS-1$ - if (!dir.isDirectory()) - throw new FileNotFoundException( - "Temp location is not directory: " + tempLocation); //$NON-NLS-1$ - return loadFromStream(in, new DirectoryStorage(dir), encryptionHandler); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.CoreException; +import org.xmind.core.IEncryptionHandler; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookBuilder; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.FileUtils; + +@SuppressWarnings("deprecation") +public abstract class AbstractWorkbookBuilder implements IWorkbookBuilder { + + private IEncryptionHandler defaultEncryptionHandler = null; + + public String creatorName; + + public String creatorVersion; + + public synchronized void setDefaultEncryptionHandler( + IEncryptionHandler encryptionHandler) { + if (this.defaultEncryptionHandler != null) + return; + + this.defaultEncryptionHandler = encryptionHandler; + } + + public synchronized void setCreator(String name, String version) { + this.creatorName = name; + this.creatorVersion = version; + } + + protected IEncryptionHandler getDefaultEncryptionHandler() { + return this.defaultEncryptionHandler; + } + + public String getCreatorName() { + return this.creatorName; + } + + public String getCreatorVersion() { + return this.creatorVersion; + } + + public IWorkbook createWorkbook() { + return createWorkbook(new ByteArrayStorage()); + } + + public IWorkbook createWorkbook(IStorage storage) { + return doCreateWorkbook(storage); + } + + public IWorkbook loadFromPath(String path) + throws IOException, CoreException { + return loadFromPath(path, new ByteArrayStorage(), + getDefaultEncryptionHandler()); + } + + public IWorkbook loadFromPath(String path, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + return loadFromPath(path, new ByteArrayStorage(), encryptionHandler); + } + + public IWorkbook loadFromPath(String path, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (path == null) + throw new IllegalArgumentException("Path is null"); //$NON-NLS-1$ + return doLoadFromPath(path, storage, encryptionHandler); + } + + public IWorkbook loadFromFile(File file) throws IOException, CoreException { + return loadFromFile(file, new ByteArrayStorage(), + getDefaultEncryptionHandler()); + } + + public IWorkbook loadFromFile(File file, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + return loadFromFile(file, new ByteArrayStorage(), encryptionHandler); + } + + public IWorkbook loadFromFile(File file, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (file == null) + throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ + if (!file.exists()) + throw new FileNotFoundException("File not exists: " + file); //$NON-NLS-1$ + + if (file.isDirectory()) { + return doLoadFromDirectory(file, storage, encryptionHandler); + } + + if (!file.canRead()) + throw new IOException("File can't be read: " + file); //$NON-NLS-1$ + + return doLoadFromFile(file, storage, encryptionHandler); + } + + public IWorkbook loadFromStream(InputStream in) + throws IOException, CoreException { + return loadFromStream(in, new ByteArrayStorage(), + getDefaultEncryptionHandler()); + } + + public IWorkbook loadFromStream(InputStream in, IStorage storage) + throws IOException, CoreException { + return loadFromStream(in, storage, getDefaultEncryptionHandler()); + } + + public IWorkbook loadFromStream(InputStream in, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (in == null) + throw new IllegalArgumentException("Input stream is null"); //$NON-NLS-1$ + return doLoadFromStream(in, storage, encryptionHandler); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.IWorkbookBuilder#loadFromInputSource(org.xmind.core.io + * .IInputSource) + */ + public IWorkbook loadFromInputSource(IInputSource source) + throws IOException, CoreException { + return loadFromInputSource(source, new ByteArrayStorage(), + getDefaultEncryptionHandler()); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.IWorkbookBuilder#loadFromInputSource(org.xmind.core.io + * .IInputSource, org.xmind.core.IEncryptionHandler) + */ + public IWorkbook loadFromInputSource(IInputSource source, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + return loadFromInputSource(source, new ByteArrayStorage(), + encryptionHandler); + } + + /** + * + * @param source + * @param storage + * @param encryptionHandler + * @return + * @throws IOException + * @throws CoreException + */ + public IWorkbook loadFromInputSource(IInputSource source, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (source == null) + throw new IllegalArgumentException("Input source is null"); //$NON-NLS-1$ + return doLoadFromInputSource(source, storage, encryptionHandler); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IWorkbookBuilder#loadFromStorage(org.xmind.core.io. + * IStorage ) + */ + public IWorkbook loadFromStorage(IStorage storage) + throws IOException, CoreException { + if (storage == null) + throw new IllegalArgumentException("Storage is null"); //$NON-NLS-1$ + return loadFromStorage(storage, null); + } + + public IWorkbook loadFromStorage(IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (storage == null) + throw new IllegalArgumentException("Storage is null"); //$NON-NLS-1$ + return doLoadFromStorage(storage, encryptionHandler); + } + + @Deprecated + public IWorkbook loadFromTempLocation(String tempLocation) + throws IOException, CoreException { + if (tempLocation == null) + throw new IllegalArgumentException("Temp location is null"); //$NON-NLS-1$ + File dir = new File(tempLocation); + if (!dir.exists()) + throw new FileNotFoundException( + "Temp location not found: " + tempLocation); //$NON-NLS-1$ + if (!dir.isDirectory()) + throw new FileNotFoundException( + "Temp location is not directory: " + tempLocation); //$NON-NLS-1$ + DirectoryStorage storage = new DirectoryStorage(dir); +// return loadFromInputSource(storage.getInputSource(), storage, null); + return doLoadFromStorage(storage, null); + } + + //////////////////////////////////////////////////////////////// + // + // Methods That Subclasses Can Override + // + //////////////////////////////////////////////////////////////// + + protected abstract IWorkbook doCreateWorkbook(IStorage storage); + + protected IWorkbook doLoadFromPath(String path, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + return loadFromFile(new File(path), storage, encryptionHandler); + } + + protected IWorkbook doLoadFromDirectory(File dir, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + return loadFromInputSource(new DirectoryInputSource(dir), storage, + encryptionHandler); + } + + protected IWorkbook doLoadFromFile(File file, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException, FileNotFoundException { + return loadFromStream(new FileInputStream(file), storage, + encryptionHandler); + } + + protected IWorkbook doLoadFromStream(InputStream in, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (storage == null) + storage = new ByteArrayStorage(); + try { + extractFromStream(in, storage.getOutputTarget()); + } finally { + in.close(); + } + return doLoadFromStorage(storage, encryptionHandler); + } + + protected IWorkbook doLoadFromInputSource(IInputSource source, + IStorage storage, IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (storage == null) + storage = new ByteArrayStorage(); + FileUtils.transfer(source, storage.getOutputTarget()); + return doLoadFromStorage(storage, encryptionHandler); + } + + protected abstract void extractFromStream(InputStream input, + IOutputTarget target) throws IOException, CoreException; + + protected abstract IWorkbook doLoadFromStorage(IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException; + + //////////////////////////////////////////////////////////////// + // + // Deprecated Methods + // + //////////////////////////////////////////////////////////////// + + @Deprecated + public IWorkbook createWorkbook(String targetPath) { + return createWorkbook(new ByteArrayStorage()); + } + + @Deprecated + public IWorkbook createWorkbookOnTemp(String tempLocation) { + return createWorkbook(new DirectoryStorage(new File(tempLocation))); + } + + @Deprecated + public IWorkbook loadFromStream(InputStream in, String tempLocation) + throws IOException, CoreException { + return loadFromStream(in, tempLocation, null); + } + + @Deprecated + public IWorkbook loadFromStream(InputStream in, String tempLocation, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + if (tempLocation == null) + throw new IllegalArgumentException("Temp location is null"); //$NON-NLS-1$ + File dir = new File(tempLocation); + if (!dir.exists()) + throw new FileNotFoundException( + "Temp location not found: " + tempLocation); //$NON-NLS-1$ + if (!dir.isDirectory()) + throw new FileNotFoundException( + "Temp location is not directory: " + tempLocation); //$NON-NLS-1$ + return loadFromStream(in, new DirectoryStorage(dir), encryptionHandler); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookComponent.java b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookComponent.java index e2753a996..f45d0d1d6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookComponent.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/AbstractWorkbookComponent.java @@ -1,17 +1,17 @@ -package org.xmind.core.internal; - -import org.xmind.core.IAdaptable; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookComponent; - -public abstract class AbstractWorkbookComponent - implements IAdaptable, IWorkbookComponent { - - public T getAdapter(Class adapter) { - if (adapter == IWorkbook.class) - return adapter.cast(getOwnedWorkbook()); - - return null; - } - -} +package org.xmind.core.internal; + +import org.xmind.core.IAdaptable; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookComponent; + +public abstract class AbstractWorkbookComponent + implements IAdaptable, IWorkbookComponent { + + public T getAdapter(Class adapter) { + if (adapter == IWorkbook.class) + return adapter.cast(getOwnedWorkbook()); + + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Boundary.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Boundary.java index 692c58cc2..1f38a2490 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Boundary.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Boundary.java @@ -1,117 +1,117 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.Collections; -import java.util.List; - -import org.xmind.core.IBoundary; -import org.xmind.core.ITopic; -import org.xmind.core.style.IStyle; - -public abstract class Boundary extends AbstractWorkbookComponent - implements IBoundary { - - protected static final List NO_ENCLOSING_TOPICS = Collections - .emptyList(); - - public String getStyleType() { - return IStyle.BOUNDARY; - } - - /** - * Clients may override this method. - * - * @see org.xmind.core.ITitled#getTitleText() - */ - public String getTitleText() { - String t = getLocalTitleText(); - return t == null ? "" : t; //$NON-NLS-1$ - } - - /** - * @see org.xmind.core.ITitled#hasTitle() - */ - public boolean hasTitle() { - return getLocalTitleText() != null; - } - - /** - * @return - */ - protected abstract String getLocalTitleText(); - - public List getEnclosingTopics() { - int startIndex = getStartIndex(); - int endIndex = getEndIndex(); - if (startIndex >= 0 && endIndex >= 0 && endIndex >= startIndex) { - ITopic parent = getParent(); - if (parent != null) { - List children = parent.getChildren(ITopic.ATTACHED); - if (!children.isEmpty()) { - return getSubtopics(startIndex, endIndex, children); - } - } - } - return NO_ENCLOSING_TOPICS; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ITopicRange#encloses(org.xmind.core.ITopic) - */ - public boolean encloses(ITopic subtopic) { - if (subtopic == null) - return false; - ITopic parent = subtopic.getParent(); - if (parent == null || !parent.equals(getParent())) - return false; - int startIndex = getStartIndex(); - int endIndex = getEndIndex(); - int subIndex = subtopic.getIndex(); - return subIndex >= startIndex && subIndex <= endIndex; - } - - private List getSubtopics(int startIndex, int endIndex, - List children) { - startIndex = Math.min(startIndex, children.size() - 1); - endIndex = Math.min(endIndex, children.size() - 1); - return children.subList(startIndex, endIndex + 1); - } - - public ITopic getStartTopic() { - return getTopic(getStartIndex()); - } - - public ITopic getEndTopic() { - return getTopic(getEndIndex()); - } - - protected ITopic getTopic(int index) { - if (index >= 0) { - ITopic parent = getParent(); - if (parent != null) { - List children = parent.getChildren(ITopic.ATTACHED); - if (index < children.size()) - return children.get(index); - } - } - return null; - } - - public String toString() { - return "BOUNDARY (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.Collections; +import java.util.List; + +import org.xmind.core.IBoundary; +import org.xmind.core.ITopic; +import org.xmind.core.style.IStyle; + +public abstract class Boundary extends AbstractWorkbookComponent + implements IBoundary { + + protected static final List NO_ENCLOSING_TOPICS = Collections + .emptyList(); + + public String getStyleType() { + return IStyle.BOUNDARY; + } + + /** + * Clients may override this method. + * + * @see org.xmind.core.ITitled#getTitleText() + */ + public String getTitleText() { + String t = getLocalTitleText(); + return t == null ? "" : t; //$NON-NLS-1$ + } + + /** + * @see org.xmind.core.ITitled#hasTitle() + */ + public boolean hasTitle() { + return getLocalTitleText() != null; + } + + /** + * @return + */ + protected abstract String getLocalTitleText(); + + public List getEnclosingTopics() { + int startIndex = getStartIndex(); + int endIndex = getEndIndex(); + if (startIndex >= 0 && endIndex >= 0 && endIndex >= startIndex) { + ITopic parent = getParent(); + if (parent != null) { + List children = parent.getChildren(ITopic.ATTACHED); + if (!children.isEmpty()) { + return getSubtopics(startIndex, endIndex, children); + } + } + } + return NO_ENCLOSING_TOPICS; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ITopicRange#encloses(org.xmind.core.ITopic) + */ + public boolean encloses(ITopic subtopic) { + if (subtopic == null) + return false; + ITopic parent = subtopic.getParent(); + if (parent == null || !parent.equals(getParent())) + return false; + int startIndex = getStartIndex(); + int endIndex = getEndIndex(); + int subIndex = subtopic.getIndex(); + return subIndex >= startIndex && subIndex <= endIndex; + } + + private List getSubtopics(int startIndex, int endIndex, + List children) { + startIndex = Math.min(startIndex, children.size() - 1); + endIndex = Math.min(endIndex, children.size() - 1); + return children.subList(startIndex, endIndex + 1); + } + + public ITopic getStartTopic() { + return getTopic(getStartIndex()); + } + + public ITopic getEndTopic() { + return getTopic(getEndIndex()); + } + + protected ITopic getTopic(int index) { + if (index >= 0) { + ITopic parent = getParent(); + if (parent != null) { + List children = parent.getChildren(ITopic.ATTACHED); + if (index < children.size()) + return children.get(index); + } + } + return null; + } + + public String toString() { + return "BOUNDARY (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/ControlPoint.java b/bundles/org.xmind.core/src/org/xmind/core/internal/ControlPoint.java index 25e013db8..25b3d3382 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/ControlPoint.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/ControlPoint.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IControlPoint; - -public abstract class ControlPoint extends AbstractWorkbookComponent - implements IControlPoint { +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IControlPoint; + +public abstract class ControlPoint extends AbstractWorkbookComponent + implements IControlPoint { } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/EncryptionData.java b/bundles/org.xmind.core/src/org/xmind/core/internal/EncryptionData.java index 17fe5ece9..5cca7f64e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/EncryptionData.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/EncryptionData.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IEncryptionData; - -/** - * @author frankshaka - * - */ -public abstract class EncryptionData implements IEncryptionData { - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) - */ - public T getAdapter(Class adapter) { - return null; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IEncryptionData; + +/** + * @author frankshaka + * + */ +public abstract class EncryptionData implements IEncryptionData { + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) + */ + public T getAdapter(Class adapter) { + return null; + } +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/FileEntry.java b/bundles/org.xmind.core/src/org/xmind/core/internal/FileEntry.java index 5ce023827..082f022e3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/FileEntry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/FileEntry.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.xmind.core.IFileEntry; - -public abstract class FileEntry extends AbstractWorkbookComponent - implements IFileEntry { - - protected static final List NO_SUB_FILE_ENTRIES = Collections - .emptyList(); - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IFileEntry#getSubEntries() - */ - public List getSubEntries() { - if (!isDirectory()) - return NO_SUB_FILE_ENTRIES; - List list = new ArrayList(); - Iterator it = iterSubEntries(); - while (it.hasNext()) { - list.add(it.next()); - } - return list; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.xmind.core.IFileEntry; + +public abstract class FileEntry extends AbstractWorkbookComponent + implements IFileEntry { + + protected static final List NO_SUB_FILE_ENTRIES = Collections + .emptyList(); + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IFileEntry#getSubEntries() + */ + public List getSubEntries() { + if (!isDirectory()) + return NO_SUB_FILE_ENTRIES; + List list = new ArrayList(); + Iterator it = iterSubEntries(); + while (it.hasNext()) { + list.add(it.next()); + } + return list; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/ICloneDataListener.java b/bundles/org.xmind.core/src/org/xmind/core/internal/ICloneDataListener.java index 0c46a5042..0bf22ed24 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/ICloneDataListener.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/ICloneDataListener.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -public interface ICloneDataListener { - - void objectCloned(Object source, Object cloned); - - void stringCloned(String category, String source, String cloned); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +public interface ICloneDataListener { + + void objectCloned(Object source, Object cloned); + + void stringCloned(String category, String source, String cloned); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/IDFactory.java b/bundles/org.xmind.core/src/org/xmind/core/internal/IDFactory.java index 00804c7b1..fba1c054c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/IDFactory.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/IDFactory.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.math.BigInteger; -import java.util.Random; - -import org.xmind.core.IIdFactory; - -/** - * @author briansun - * - */ -public class IDFactory implements IIdFactory { - - private static final int ID_LENGTH = 26; - - private static final char PADDING_CHAR = '0'; - - private static final Random random = new Random(System.currentTimeMillis()); - - /** - * @return - */ - public String createId() { - BigInteger bi = new BigInteger(128, random); - String id = bi.toString(32); - int paddingLength = ID_LENGTH - id.length(); - if (paddingLength > 0) { - StringBuffer buf = new StringBuffer(ID_LENGTH); - for (int i = 0; i < paddingLength; i++) { - buf.append(PADDING_CHAR); - } - buf.append(id); - return buf.toString(); - } - return id; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.math.BigInteger; +import java.util.Random; + +import org.xmind.core.IIdFactory; + +/** + * @author briansun + * + */ +public class IDFactory implements IIdFactory { + + private static final int ID_LENGTH = 26; + + private static final char PADDING_CHAR = '0'; + + private static final Random random = new Random(System.currentTimeMillis()); + + /** + * @return + */ + public String createId() { + BigInteger bi = new BigInteger(128, random); + String id = bi.toString(32); + int paddingLength = ID_LENGTH - id.length(); + if (paddingLength > 0) { + StringBuffer buf = new StringBuffer(ID_LENGTH); + for (int i = 0; i < paddingLength; i++) { + buf.append(PADDING_CHAR); + } + buf.append(id); + return buf.toString(); + } + return id; + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Image.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Image.java index f6c71bb78..0407c10e7 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Image.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Image.java @@ -1,31 +1,31 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IImage; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; - -public abstract class Image extends AbstractWorkbookComponent - implements IImage { - - public T getAdapter(Class adapter) { - if (adapter == ITitled.class || adapter == ITopic.class) { - return adapter.cast(getParent()); - } - - return super.getAdapter(adapter); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IImage; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; + +public abstract class Image extends AbstractWorkbookComponent + implements IImage { + + public T getAdapter(Class adapter) { + if (adapter == ITitled.class || adapter == ITopic.class) { + return adapter.cast(getParent()); + } + + return super.getAdapter(adapter); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/InternalCore.java b/bundles/org.xmind.core/src/org/xmind/core/internal/InternalCore.java index a532cdae6..0bb805a9d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/InternalCore.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/InternalCore.java @@ -1,148 +1,148 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.Comparator; -import java.util.regex.Pattern; - -import org.xmind.core.IIdFactory; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbookBuilder; -import org.xmind.core.IWorkspace; -import org.xmind.core.internal.dom.MarkerSheetBuilderImpl; -import org.xmind.core.internal.dom.StyleSheetBuilderImpl; -import org.xmind.core.internal.dom.WorkbookBuilderImpl; -import org.xmind.core.marker.IMarkerSheetBuilder; -import org.xmind.core.style.IStyleSheetBuilder; -import org.xmind.core.util.ILogger; - -public class InternalCore { - - public static final boolean DEBUG_WORKBOOK_SAVE = Boolean - .getBoolean("org.xmind.debug.core.workbookSave"); //$NON-NLS-1$ - - /** - * @author Frank Shaka - * - */ - private final class ConsoleLogger implements ILogger { - public void log(Throwable e) { - e.printStackTrace(); - } - - public void log(Throwable e, String message) { - System.err.println(message); - e.printStackTrace(); - } - - public void log(String message) { - System.err.println(message); - } - } - - private static InternalCore instance = null; - - private IWorkbookBuilder workbookBuilder = null; - - private IWorkspace workspace = null; - - private IMarkerSheetBuilder markerSheetBuilder = null; - - private Comparator topicComparator; - - private IIdFactory idFactory; - - private IStyleSheetBuilder styleSheetBuilder; - - private ILogger logger; - - private Pattern partiallyCompatibleVersionPattern = Pattern - .compile("[012]\\.\\d+"); //$NON-NLS-1$ - - private InternalCore() { - } - - public String getCurrentVersion() { - return "2.0"; //$NON-NLS-1$ - } - - public boolean isPartiallyCompatible(String version) { - if (version == null) - return false; - - if (getCurrentVersion().equals(version)) - return true; - - return partiallyCompatibleVersionPattern.matcher(version).matches(); - } - - public synchronized IWorkbookBuilder getWorkbookBuilder() { - if (workbookBuilder == null) - workbookBuilder = new WorkbookBuilderImpl(); - return workbookBuilder; - } - - public synchronized IWorkspace getWorkspace() { - if (workspace == null) { - workspace = new Workspace(); - } - return workspace; - } - - public synchronized IMarkerSheetBuilder getMarkerSheetBuilder() { - if (markerSheetBuilder == null) { - markerSheetBuilder = new MarkerSheetBuilderImpl(); - } - return markerSheetBuilder; - } - - public synchronized Comparator getTopicComparator() { - if (topicComparator == null) { - topicComparator = new TopicCompartor(); - } - return topicComparator; - } - - public synchronized IIdFactory getIdFactory() { - if (idFactory == null) { - idFactory = new IDFactory(); - } - return idFactory; - } - - public synchronized IStyleSheetBuilder getStyleSheetBuilder() { - if (styleSheetBuilder == null) { - styleSheetBuilder = new StyleSheetBuilderImpl(); - } - return styleSheetBuilder; - } - - public synchronized ILogger getLogger() { - if (logger == null) { - logger = new ConsoleLogger(); - } - return logger; - } - - public synchronized void setLogger(ILogger logger) { - this.logger = logger; - } - - public static InternalCore getInstance() { - if (instance == null) - instance = new InternalCore(); - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.Comparator; +import java.util.regex.Pattern; + +import org.xmind.core.IIdFactory; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbookBuilder; +import org.xmind.core.IWorkspace; +import org.xmind.core.internal.dom.MarkerSheetBuilderImpl; +import org.xmind.core.internal.dom.StyleSheetBuilderImpl; +import org.xmind.core.internal.dom.WorkbookBuilderImpl; +import org.xmind.core.marker.IMarkerSheetBuilder; +import org.xmind.core.style.IStyleSheetBuilder; +import org.xmind.core.util.ILogger; + +public class InternalCore { + + public static final boolean DEBUG_WORKBOOK_SAVE = Boolean + .getBoolean("org.xmind.debug.core.workbookSave"); //$NON-NLS-1$ + + /** + * @author Frank Shaka + * + */ + private final class ConsoleLogger implements ILogger { + public void log(Throwable e) { + e.printStackTrace(); + } + + public void log(Throwable e, String message) { + System.err.println(message); + e.printStackTrace(); + } + + public void log(String message) { + System.err.println(message); + } + } + + private static InternalCore instance = null; + + private IWorkbookBuilder workbookBuilder = null; + + private IWorkspace workspace = null; + + private IMarkerSheetBuilder markerSheetBuilder = null; + + private Comparator topicComparator; + + private IIdFactory idFactory; + + private IStyleSheetBuilder styleSheetBuilder; + + private ILogger logger; + + private Pattern partiallyCompatibleVersionPattern = Pattern + .compile("[012]\\.\\d+"); //$NON-NLS-1$ + + private InternalCore() { + } + + public String getCurrentVersion() { + return "2.0"; //$NON-NLS-1$ + } + + public boolean isPartiallyCompatible(String version) { + if (version == null) + return false; + + if (getCurrentVersion().equals(version)) + return true; + + return partiallyCompatibleVersionPattern.matcher(version).matches(); + } + + public synchronized IWorkbookBuilder getWorkbookBuilder() { + if (workbookBuilder == null) + workbookBuilder = new WorkbookBuilderImpl(); + return workbookBuilder; + } + + public synchronized IWorkspace getWorkspace() { + if (workspace == null) { + workspace = new Workspace(); + } + return workspace; + } + + public synchronized IMarkerSheetBuilder getMarkerSheetBuilder() { + if (markerSheetBuilder == null) { + markerSheetBuilder = new MarkerSheetBuilderImpl(); + } + return markerSheetBuilder; + } + + public synchronized Comparator getTopicComparator() { + if (topicComparator == null) { + topicComparator = new TopicCompartor(); + } + return topicComparator; + } + + public synchronized IIdFactory getIdFactory() { + if (idFactory == null) { + idFactory = new IDFactory(); + } + return idFactory; + } + + public synchronized IStyleSheetBuilder getStyleSheetBuilder() { + if (styleSheetBuilder == null) { + styleSheetBuilder = new StyleSheetBuilderImpl(); + } + return styleSheetBuilder; + } + + public synchronized ILogger getLogger() { + if (logger == null) { + logger = new ConsoleLogger(); + } + return logger; + } + + public synchronized void setLogger(ILogger logger) { + this.logger = logger; + } + + public static InternalCore getInstance() { + if (instance == null) + instance = new InternalCore(); + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/MarkerVariation.java b/bundles/org.xmind.core/src/org/xmind/core/internal/MarkerVariation.java index fd96a3b44..bdee0118b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/MarkerVariation.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/MarkerVariation.java @@ -1,39 +1,39 @@ -package org.xmind.core.internal; - -import org.xmind.core.marker.IMarkerVariation; - -public class MarkerVariation implements IMarkerVariation { - - private String suffix; - - private int applicableWidth; - - private int applicableHeight; - - public MarkerVariation(String suffix, int applicableWidth, - int applicableHeight) { - super(); - this.suffix = suffix; - this.applicableWidth = applicableWidth; - this.applicableHeight = applicableHeight; - } - - public String getVariedPath(String path) { - int extLength = 0; - if (path.endsWith(".png") || path.endsWith(".jpg") //$NON-NLS-1$ //$NON-NLS-2$ - || path.endsWith(".gif") || path.endsWith("bmp")) { //$NON-NLS-1$//$NON-NLS-2$ - extLength = 4; - } else if (path.endsWith(".jpeg")) { //$NON-NLS-1$ - extLength = 5; - } - if (extLength > 0) - return path.substring(0, path.length() - extLength) + suffix - + path.substring(path.length() - extLength); - return path + suffix + path.substring(path.length() - extLength); - } - - public boolean isApplicable(int widthHint, int heightHint) { - return widthHint <= applicableWidth && heightHint <= applicableHeight; - } - -} +package org.xmind.core.internal; + +import org.xmind.core.marker.IMarkerVariation; + +public class MarkerVariation implements IMarkerVariation { + + private String suffix; + + private int applicableWidth; + + private int applicableHeight; + + public MarkerVariation(String suffix, int applicableWidth, + int applicableHeight) { + super(); + this.suffix = suffix; + this.applicableWidth = applicableWidth; + this.applicableHeight = applicableHeight; + } + + public String getVariedPath(String path) { + int extLength = 0; + if (path.endsWith(".png") || path.endsWith(".jpg") //$NON-NLS-1$ //$NON-NLS-2$ + || path.endsWith(".gif") || path.endsWith("bmp")) { //$NON-NLS-1$//$NON-NLS-2$ + extLength = 4; + } else if (path.endsWith(".jpeg")) { //$NON-NLS-1$ + extLength = 5; + } + if (extLength > 0) + return path.substring(0, path.length() - extLength) + suffix + + path.substring(path.length() - extLength); + return path + suffix + path.substring(path.length() - extLength); + } + + public boolean isApplicable(int widthHint, int heightHint) { + return widthHint <= applicableWidth && heightHint <= applicableHeight; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Meta.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Meta.java index 7cea21c36..ae66cdfd9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Meta.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Meta.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IMeta; - -public abstract class Meta extends AbstractWorkbookComponent implements IMeta { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IMeta; + +public abstract class Meta extends AbstractWorkbookComponent implements IMeta { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/MetaData.java b/bundles/org.xmind.core/src/org/xmind/core/internal/MetaData.java index 3a6759dd5..da17e1647 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/MetaData.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/MetaData.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IMetaData; - -@Deprecated -public abstract class MetaData implements IMetaData { - - public T getAdapter(Class adapter) { - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IMetaData; + +@Deprecated +public abstract class MetaData implements IMetaData { + + public T getAdapter(Class adapter) { + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Relationship.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Relationship.java index 27cf4f4aa..b14ce1043 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Relationship.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Relationship.java @@ -1,107 +1,107 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.style.IStyle; - -/** - * @author briansun - * - */ -public abstract class Relationship extends AbstractWorkbookComponent - implements IRelationship { - - public String getStyleType() { - return IStyle.RELATIONSHIP; - } - - /** - * @see org.xmind.core.IRelationship#getEnd1() - */ - public IRelationshipEnd getEnd1() { - String end1Id = getEnd1Id(); - if (end1Id == null) - return null; - IWorkbook workbook = getOwnedWorkbook(); - if (workbook == null) - return null; - Object element = workbook.getElementById(end1Id); - if (element instanceof IRelationshipEnd) - return (IRelationshipEnd) element; - return null; - } - - /** - * @see org.xmind.core.IRelationship#getEnd2() - */ - public IRelationshipEnd getEnd2() { - String end2Id = getEnd2Id(); - if (end2Id == null) - return null; - IWorkbook workbook = getOwnedWorkbook(); - if (workbook == null) - return null; - Object element = workbook.getElementById(end2Id); - if (element instanceof IRelationshipEnd) - return (IRelationshipEnd) element; - return null; - } - - /** - * Clients may override this method. - * - * @see org.xmind.core.ITitled#getTitleText() - */ - public String getTitleText() { - String t = getLocalTitleText(); - return t == null ? "" : t; //$NON-NLS-1$ - } - - /** - * @see org.xmind.core.ITitled#hasTitle() - */ - public boolean hasTitle() { - return getLocalTitleText() != null; - } - - public ISheet getOwnedSheet() { - return getParent(); - } - - /** - * @return - */ - protected abstract String getLocalTitleText(); - - public T getAdapter(Class adapter) { - if (adapter == ISheet.class) - return adapter.cast(getOwnedSheet()); - - return super.getAdapter(adapter); - } - -// /** -// * @return -// */ -// protected abstract IWorkbook getOwnedWorkbook(); - - public String toString() { - return "RELATIONSHIP (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.style.IStyle; + +/** + * @author briansun + * + */ +public abstract class Relationship extends AbstractWorkbookComponent + implements IRelationship { + + public String getStyleType() { + return IStyle.RELATIONSHIP; + } + + /** + * @see org.xmind.core.IRelationship#getEnd1() + */ + public IRelationshipEnd getEnd1() { + String end1Id = getEnd1Id(); + if (end1Id == null) + return null; + IWorkbook workbook = getOwnedWorkbook(); + if (workbook == null) + return null; + Object element = workbook.getElementById(end1Id); + if (element instanceof IRelationshipEnd) + return (IRelationshipEnd) element; + return null; + } + + /** + * @see org.xmind.core.IRelationship#getEnd2() + */ + public IRelationshipEnd getEnd2() { + String end2Id = getEnd2Id(); + if (end2Id == null) + return null; + IWorkbook workbook = getOwnedWorkbook(); + if (workbook == null) + return null; + Object element = workbook.getElementById(end2Id); + if (element instanceof IRelationshipEnd) + return (IRelationshipEnd) element; + return null; + } + + /** + * Clients may override this method. + * + * @see org.xmind.core.ITitled#getTitleText() + */ + public String getTitleText() { + String t = getLocalTitleText(); + return t == null ? "" : t; //$NON-NLS-1$ + } + + /** + * @see org.xmind.core.ITitled#hasTitle() + */ + public boolean hasTitle() { + return getLocalTitleText() != null; + } + + public ISheet getOwnedSheet() { + return getParent(); + } + + /** + * @return + */ + protected abstract String getLocalTitleText(); + + public T getAdapter(Class adapter) { + if (adapter == ISheet.class) + return adapter.cast(getOwnedSheet()); + + return super.getAdapter(adapter); + } + +// /** +// * @return +// */ +// protected abstract IWorkbook getOwnedWorkbook(); + + public String toString() { + return "RELATIONSHIP (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Revision.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Revision.java index f8b8dbe17..e40b542c0 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Revision.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Revision.java @@ -1,39 +1,39 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal; - -import org.xmind.core.IRevision; - -/** - * @author Frank Shaka - * - */ -public abstract class Revision extends AbstractWorkbookComponent - implements IRevision { - - /* - * (non-Javadoc) - * - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(IRevision r) { - int c = this.getRevisionNumber() - r.getRevisionNumber(); - if (c == 0) { - c = (int) (this.getTimestamp() - r.getTimestamp()); - } - return c; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal; + +import org.xmind.core.IRevision; + +/** + * @author Frank Shaka + * + */ +public abstract class Revision extends AbstractWorkbookComponent + implements IRevision { + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(IRevision r) { + int c = this.getRevisionNumber() - r.getRevisionNumber(); + if (c == 0) { + c = (int) (this.getTimestamp() - r.getTimestamp()); + } + return c; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/RevisionManager.java b/bundles/org.xmind.core/src/org/xmind/core/internal/RevisionManager.java index c6fedbb24..ccfd4086e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/RevisionManager.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/RevisionManager.java @@ -1,68 +1,68 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.xmind.core.IRevision; -import org.xmind.core.IRevisionManager; - -/** - * @author Frank Shaka - * - */ -public abstract class RevisionManager extends AbstractWorkbookComponent - implements IRevisionManager { - - public List getRevisions() { - ArrayList list = new ArrayList(); - Iterator it = iterRevisions(); - while (it.hasNext()) { - list.add(it.next()); - } - return list; - } - - public List getRevisionsReversed() { - ArrayList list = new ArrayList(); - Iterator it = iterRevisionsReversed(); - while (it.hasNext()) { - list.add(it.next()); - } - return list; - } - - public boolean hasRevisions() { - return iterRevisions().hasNext(); - } - - public IRevision getLatestRevision() { - Iterator it = iterRevisionsReversed(); - return it.hasNext() ? it.next() : null; - } - - public IRevision getRevision(int number) { - Iterator it = iterRevisionsReversed(); - while (it.hasNext()) { - IRevision revision = it.next(); - if (revision.getRevisionNumber() == number) - return revision; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.xmind.core.IRevision; +import org.xmind.core.IRevisionManager; + +/** + * @author Frank Shaka + * + */ +public abstract class RevisionManager extends AbstractWorkbookComponent + implements IRevisionManager { + + public List getRevisions() { + ArrayList list = new ArrayList(); + Iterator it = iterRevisions(); + while (it.hasNext()) { + list.add(it.next()); + } + return list; + } + + public List getRevisionsReversed() { + ArrayList list = new ArrayList(); + Iterator it = iterRevisionsReversed(); + while (it.hasNext()) { + list.add(it.next()); + } + return list; + } + + public boolean hasRevisions() { + return iterRevisions().hasNext(); + } + + public IRevision getLatestRevision() { + Iterator it = iterRevisionsReversed(); + return it.hasNext() ? it.next() : null; + } + + public IRevision getRevision(int number) { + Iterator it = iterRevisionsReversed(); + while (it.hasNext()) { + IRevision revision = it.next(); + if (revision.getRevisionNumber() == number) + return revision; + } + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/SettingEntry.java b/bundles/org.xmind.core/src/org/xmind/core/internal/SettingEntry.java index 5cffee2a5..159ca943a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/SettingEntry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/SettingEntry.java @@ -1,15 +1,15 @@ -package org.xmind.core.internal; - -import org.xmind.core.ISettingEntry; - -/** - * @author Jason Wong - * @since 3.6.50 - */ -public abstract class SettingEntry implements ISettingEntry { - - public T getAdapter(Class adapter) { - return null; - } - -} +package org.xmind.core.internal; + +import org.xmind.core.ISettingEntry; + +/** + * @author Jason Wong + * @since 3.6.50 + */ +public abstract class SettingEntry implements ISettingEntry { + + public T getAdapter(Class adapter) { + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Sheet.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Sheet.java index 4df01fff9..0010e5c8d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Sheet.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Sheet.java @@ -1,86 +1,86 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; - -/** - * @author briansun - * - */ -public abstract class Sheet extends AbstractWorkbookComponent - implements ISheet { - - public String getStyleType() { - return IStyle.MAP; - } - - /** - * Clients may override this method. - * - * @see org.xmind.core.ITitled#getTitleText() - */ - public String getTitleText() { - String t = getLocalTitleText(); - return t == null ? "" : t; //$NON-NLS-1$ - } - - /** - * @see org.xmind.core.ITitled#hasTitle() - */ - public boolean hasTitle() { - return getLocalTitleText() != null; - } - - /** - * @return - */ - protected abstract String getLocalTitleText(); - - public int getIndex() { - IWorkbook w = getParent(); - if (w != null) { - return w.getSheets().indexOf(this); - } - return -1; - } - - public T getAdapter(Class adapter) { - if (adapter == ITopic.class) - return adapter.cast(getRootTopic()); - - return super.getAdapter(adapter); - } - - public IStyle getTheme() { - String themeId = getThemeId(); - if (themeId == null) - return null; - - IStyleSheet styleSheet = getOwnedWorkbook().getStyleSheet(); - if (styleSheet == null) - return null; - - return styleSheet.findStyle(themeId); - } - - public String toString() { - return "SHEET (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; + +/** + * @author briansun + * + */ +public abstract class Sheet extends AbstractWorkbookComponent + implements ISheet { + + public String getStyleType() { + return IStyle.MAP; + } + + /** + * Clients may override this method. + * + * @see org.xmind.core.ITitled#getTitleText() + */ + public String getTitleText() { + String t = getLocalTitleText(); + return t == null ? "" : t; //$NON-NLS-1$ + } + + /** + * @see org.xmind.core.ITitled#hasTitle() + */ + public boolean hasTitle() { + return getLocalTitleText() != null; + } + + /** + * @return + */ + protected abstract String getLocalTitleText(); + + public int getIndex() { + IWorkbook w = getParent(); + if (w != null) { + return w.getSheets().indexOf(this); + } + return -1; + } + + public T getAdapter(Class adapter) { + if (adapter == ITopic.class) + return adapter.cast(getRootTopic()); + + return super.getAdapter(adapter); + } + + public IStyle getTheme() { + String themeId = getThemeId(); + if (themeId == null) + return null; + + IStyleSheet styleSheet = getOwnedWorkbook().getStyleSheet(); + if (styleSheet == null) + return null; + + return styleSheet.findStyle(themeId); + } + + public String toString() { + return "SHEET (" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/SheetSettings.java b/bundles/org.xmind.core/src/org/xmind/core/internal/SheetSettings.java index 37452d756..d7d1c44c7 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/SheetSettings.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/SheetSettings.java @@ -1,12 +1,12 @@ -package org.xmind.core.internal; - -import org.xmind.core.ISheetSettings; - -/** - * @author Jason Wong - * @since 3.6.50 - */ -public abstract class SheetSettings extends AbstractWorkbookComponent - implements ISheetSettings { - -} +package org.xmind.core.internal; + +import org.xmind.core.ISheetSettings; + +/** + * @author Jason Wong + * @since 3.6.50 + */ +public abstract class SheetSettings extends AbstractWorkbookComponent + implements ISheetSettings { + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Summary.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Summary.java index 563e0ae3d..4a190cc62 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Summary.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Summary.java @@ -1,96 +1,96 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.Collections; -import java.util.List; - -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.style.IStyle; - -public abstract class Summary extends AbstractWorkbookComponent - implements ISummary { - - protected static final List NO_ENCLOSING_TOPICS = Collections - .emptyList(); - - public String getStyleType() { - return IStyle.SUMMARY; - } - - public List getEnclosingTopics() { - int startIndex = getStartIndex(); - int endIndex = getEndIndex(); - if (startIndex >= 0 && endIndex >= 0 && endIndex >= startIndex) { - ITopic parent = getParent(); - if (parent != null) { - List children = parent.getChildren(ITopic.ATTACHED); - if (!children.isEmpty()) { - return getSubtopics(startIndex, endIndex, children); - } - } - } - return NO_ENCLOSING_TOPICS; - } - - private List getSubtopics(int startIndex, int endIndex, - List children) { - startIndex = Math.min(startIndex, children.size() - 1); - endIndex = Math.min(endIndex, children.size() - 1); - return children.subList(startIndex, endIndex + 1); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ITopicRange#encloses(org.xmind.core.ITopic) - */ - public boolean encloses(ITopic subtopic) { - if (subtopic == null) - return false; - ITopic parent = subtopic.getParent(); - if (parent == null || !parent.equals(getParent())) - return false; - int startIndex = getStartIndex(); - int endIndex = getEndIndex(); - int subIndex = subtopic.getIndex(); - return subIndex >= startIndex && subIndex <= endIndex; - } - - public ITopic getStartTopic() { - return getTopic(getStartIndex()); - } - - public ITopic getEndTopic() { - return getTopic(getEndIndex()); - } - - protected ITopic getTopic(int index) { - if (index >= 0) { - ITopic parent = getParent(); - if (parent != null) { - List children = parent.getChildren(ITopic.ATTACHED); - if (index < children.size()) - return children.get(index); - } - } - return null; - } - - public String toString() { - return "SUMMARY (" + getTopicId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.Collections; +import java.util.List; + +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.style.IStyle; + +public abstract class Summary extends AbstractWorkbookComponent + implements ISummary { + + protected static final List NO_ENCLOSING_TOPICS = Collections + .emptyList(); + + public String getStyleType() { + return IStyle.SUMMARY; + } + + public List getEnclosingTopics() { + int startIndex = getStartIndex(); + int endIndex = getEndIndex(); + if (startIndex >= 0 && endIndex >= 0 && endIndex >= startIndex) { + ITopic parent = getParent(); + if (parent != null) { + List children = parent.getChildren(ITopic.ATTACHED); + if (!children.isEmpty()) { + return getSubtopics(startIndex, endIndex, children); + } + } + } + return NO_ENCLOSING_TOPICS; + } + + private List getSubtopics(int startIndex, int endIndex, + List children) { + startIndex = Math.min(startIndex, children.size() - 1); + endIndex = Math.min(endIndex, children.size() - 1); + return children.subList(startIndex, endIndex + 1); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ITopicRange#encloses(org.xmind.core.ITopic) + */ + public boolean encloses(ITopic subtopic) { + if (subtopic == null) + return false; + ITopic parent = subtopic.getParent(); + if (parent == null || !parent.equals(getParent())) + return false; + int startIndex = getStartIndex(); + int endIndex = getEndIndex(); + int subIndex = subtopic.getIndex(); + return subIndex >= startIndex && subIndex <= endIndex; + } + + public ITopic getStartTopic() { + return getTopic(getStartIndex()); + } + + public ITopic getEndTopic() { + return getTopic(getEndIndex()); + } + + protected ITopic getTopic(int index) { + if (index >= 0) { + ITopic parent = getParent(); + if (parent != null) { + List children = parent.getChildren(ITopic.ATTACHED); + if (index < children.size()) + return children.get(index); + } + } + return null; + } + + public String toString() { + return "SUMMARY (" + getTopicId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/TopicExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/internal/TopicExtensionElement.java index eacfb4f3b..d84c6c13d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/TopicExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/TopicExtensionElement.java @@ -1,30 +1,30 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.util.List; - -import org.xmind.core.ITopicExtensionElement; - -public abstract class TopicExtensionElement extends AbstractWorkbookComponent - implements ITopicExtensionElement { - - public ITopicExtensionElement getCreatedChild(String elementName) { - List children = getChildren(elementName); - if (!children.isEmpty()) - return children.get(0); - return createChild(elementName); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.util.List; + +import org.xmind.core.ITopicExtensionElement; + +public abstract class TopicExtensionElement extends AbstractWorkbookComponent + implements ITopicExtensionElement { + + public ITopicExtensionElement getCreatedChild(String elementName) { + List children = getChildren(elementName); + if (!children.isEmpty()) + return children.get(0); + return createChild(elementName); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtension.java b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtension.java index 65cedfe11..244a5d86e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtension.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtension.java @@ -1,24 +1,24 @@ -package org.xmind.core.internal; - -import java.util.Collections; -import java.util.List; - -import org.xmind.core.IResourceRef; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtension; - -/** - * @author Jason Wong - */ -public abstract class WorkbookExtension implements IWorkbookExtension { - - public T getAdapter(Class adapter) { - if (IWorkbook.class.equals(adapter)) - return adapter.cast(getOwnedWorkbook()); - return null; - } - - protected static final List EMPTY_REFS = Collections - .emptyList(); - -} +package org.xmind.core.internal; + +import java.util.Collections; +import java.util.List; + +import org.xmind.core.IResourceRef; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtension; + +/** + * @author Jason Wong + */ +public abstract class WorkbookExtension implements IWorkbookExtension { + + public T getAdapter(Class adapter) { + if (IWorkbook.class.equals(adapter)) + return adapter.cast(getOwnedWorkbook()); + return null; + } + + protected static final List EMPTY_REFS = Collections + .emptyList(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionElement.java index beb602e0d..fb07204fe 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionElement.java @@ -1,20 +1,20 @@ -package org.xmind.core.internal; - -import java.util.List; - -import org.xmind.core.IWorkbookExtensionElement; - -/** - * @author Jason Wong - */ -public abstract class WorkbookExtensionElement extends AbstractWorkbookComponent - implements IWorkbookExtensionElement { - - public IWorkbookExtensionElement getCreatedChild(String elementName) { - List children = getChildren(elementName); - if (!children.isEmpty()) - return children.get(0); - return createChild(elementName); - } - -} +package org.xmind.core.internal; + +import java.util.List; + +import org.xmind.core.IWorkbookExtensionElement; + +/** + * @author Jason Wong + */ +public abstract class WorkbookExtensionElement extends AbstractWorkbookComponent + implements IWorkbookExtensionElement { + + public IWorkbookExtensionElement getCreatedChild(String elementName) { + List children = getChildren(elementName); + if (!children.isEmpty()) + return children.get(0); + return createChild(elementName); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionManager.java b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionManager.java index 2cce88fac..b69e7a55d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionManager.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionManager.java @@ -1,11 +1,11 @@ -package org.xmind.core.internal; - -import org.xmind.core.IWorkbookExtensionManager; - -/** - * @author Jason Wong - */ -public abstract class WorkbookExtensionManager - implements IWorkbookExtensionManager { - -} +package org.xmind.core.internal; + +import org.xmind.core.IWorkbookExtensionManager; + +/** + * @author Jason Wong + */ +public abstract class WorkbookExtensionManager + implements IWorkbookExtensionManager { + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Workspace.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Workspace.java index 1b944397a..37a9ad0af 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Workspace.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Workspace.java @@ -1,142 +1,142 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal; - -import java.io.File; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.xmind.core.Core; -import org.xmind.core.IWorkspace; -import org.xmind.core.util.FileUtils; - -/** - * - * @author Frank Shaka - */ -public class Workspace implements IWorkspace { - - private static final String P_WORKSPACE = "org.xmind.core.workspace"; //$NON-NLS-1$ - - private static final String P_APPLIED_WORKSPACE = "org.xmind.core.workspace.applied"; //$NON-NLS-1$ - - private static final Pattern EXPANSION_PATTERN = Pattern - .compile("\\$\\{([^\\}]+)\\}"); //$NON-NLS-1$ - - private String workingDirectory = null; - - private String defaultWorkingDirectory = null; - - public String getWorkingDirectory() { - if (workingDirectory != null) - return workingDirectory; - - String wd = System.getProperty(P_WORKSPACE); - if (wd != null && !"".equals(wd)) { //$NON-NLS-1$ - workingDirectory = expandProperties(wd, System.getProperties()); - System.setProperty(P_APPLIED_WORKSPACE, workingDirectory); - return workingDirectory; - } - - return getDefaultWorkingDirectory(); - } - - public void setDefaultWorkingDirectory(String path) { - this.defaultWorkingDirectory = path; - if (workingDirectory == null && System.getProperty(P_WORKSPACE) == null) { - System.setProperty(P_APPLIED_WORKSPACE, path); - } - } - - private String getDefaultWorkingDirectory() { - if (defaultWorkingDirectory == null) { - defaultWorkingDirectory = calculateDefaultWorkingDirectory(); - System.setProperty(P_APPLIED_WORKSPACE, defaultWorkingDirectory); - } - return defaultWorkingDirectory; - } - - public void setWorkingDirectory(String path) { - workingDirectory = path; - System.setProperty(P_APPLIED_WORKSPACE, path); - } - - public String getAbsolutePath(String subPath) { - if (subPath == null) - return null; - String wd = getWorkingDirectory(); - File f = new File(wd, subPath); - return f.getAbsolutePath(); - } - - public String getTempDir() { - return getAbsolutePath(DIR_TEMP); - } - - public String getTempDir(String subPath) { - return FileUtils.ensureDirectory(new File(getTempDir(), subPath)) - .getAbsolutePath(); - } - - public String getTempFile(String fileName) { - return FileUtils.ensureFileParent(new File(getTempDir(), fileName)) - .getAbsolutePath(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IWorkspace#createTempFile(java.lang.String, - * java.lang.String, java.lang.String) - */ - public synchronized File createTempFile(String subPath, String prefix, - String suffix) { - String subDir = getTempDir(subPath); - File file; - while (true) { - file = new File(subDir, prefix + Core.getIdFactory().createId() - + suffix); - if (!file.exists()) - break; - } - return file; - } - - private static String calculateDefaultWorkingDirectory() { - String userHome = System.getProperty("user.home"); //$NON-NLS-1$ - if (userHome == null) { - return ".xmind"; //$NON-NLS-1$ - } - return new File(userHome, ".xmind").getAbsolutePath(); //$NON-NLS-1$ - } - - private static String expandProperties(String input, Properties props) { - StringBuffer buffer = new StringBuffer(input.length()); - Matcher m = EXPANSION_PATTERN.matcher(input); - while (m.find()) { - String name = m.group(1); - String value = props.getProperty(name); - if (value == null) { - value = m.group(); - } - // Replace '\' and '$' to literal '\\' and '\$'. - value = value.replaceAll("([\\\\\\$])", "\\\\$1"); //$NON-NLS-1$ //$NON-NLS-2$ - m.appendReplacement(buffer, value); - } - m.appendTail(buffer); - return buffer.toString(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal; + +import java.io.File; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.xmind.core.Core; +import org.xmind.core.IWorkspace; +import org.xmind.core.util.FileUtils; + +/** + * + * @author Frank Shaka + */ +public class Workspace implements IWorkspace { + + private static final String P_WORKSPACE = "org.xmind.core.workspace"; //$NON-NLS-1$ + + private static final String P_APPLIED_WORKSPACE = "org.xmind.core.workspace.applied"; //$NON-NLS-1$ + + private static final Pattern EXPANSION_PATTERN = Pattern + .compile("\\$\\{([^\\}]+)\\}"); //$NON-NLS-1$ + + private String workingDirectory = null; + + private String defaultWorkingDirectory = null; + + public String getWorkingDirectory() { + if (workingDirectory != null) + return workingDirectory; + + String wd = System.getProperty(P_WORKSPACE); + if (wd != null && !"".equals(wd)) { //$NON-NLS-1$ + workingDirectory = expandProperties(wd, System.getProperties()); + System.setProperty(P_APPLIED_WORKSPACE, workingDirectory); + return workingDirectory; + } + + return getDefaultWorkingDirectory(); + } + + public void setDefaultWorkingDirectory(String path) { + this.defaultWorkingDirectory = path; + if (workingDirectory == null && System.getProperty(P_WORKSPACE) == null) { + System.setProperty(P_APPLIED_WORKSPACE, path); + } + } + + private String getDefaultWorkingDirectory() { + if (defaultWorkingDirectory == null) { + defaultWorkingDirectory = calculateDefaultWorkingDirectory(); + System.setProperty(P_APPLIED_WORKSPACE, defaultWorkingDirectory); + } + return defaultWorkingDirectory; + } + + public void setWorkingDirectory(String path) { + workingDirectory = path; + System.setProperty(P_APPLIED_WORKSPACE, path); + } + + public String getAbsolutePath(String subPath) { + if (subPath == null) + return null; + String wd = getWorkingDirectory(); + File f = new File(wd, subPath); + return f.getAbsolutePath(); + } + + public String getTempDir() { + return getAbsolutePath(DIR_TEMP); + } + + public String getTempDir(String subPath) { + return FileUtils.ensureDirectory(new File(getTempDir(), subPath)) + .getAbsolutePath(); + } + + public String getTempFile(String fileName) { + return FileUtils.ensureFileParent(new File(getTempDir(), fileName)) + .getAbsolutePath(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IWorkspace#createTempFile(java.lang.String, + * java.lang.String, java.lang.String) + */ + public synchronized File createTempFile(String subPath, String prefix, + String suffix) { + String subDir = getTempDir(subPath); + File file; + while (true) { + file = new File(subDir, prefix + Core.getIdFactory().createId() + + suffix); + if (!file.exists()) + break; + } + return file; + } + + private static String calculateDefaultWorkingDirectory() { + String userHome = System.getProperty("user.home"); //$NON-NLS-1$ + if (userHome == null) { + return ".xmind"; //$NON-NLS-1$ + } + return new File(userHome, ".xmind").getAbsolutePath(); //$NON-NLS-1$ + } + + private static String expandProperties(String input, Properties props) { + StringBuffer buffer = new StringBuffer(input.length()); + Matcher m = EXPANSION_PATTERN.matcher(input); + while (m.find()) { + String name = m.group(1); + String value = props.getProperty(name); + if (value == null) { + value = m.group(); + } + // Replace '\' and '$' to literal '\\' and '\$'. + value = value.replaceAll("([\\\\\\$])", "\\\\$1"); //$NON-NLS-1$ //$NON-NLS-2$ + m.appendReplacement(buffer, value); + } + m.appendTail(buffer); + return buffer.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/Compatibility.java b/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/Compatibility.java index a4c83aa3f..407a31ac1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/Compatibility.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/Compatibility.java @@ -1,67 +1,67 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.compatibility; - -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.internal.dom.DeserializerImpl; -import org.xmind.core.internal.dom.FileFormat_0_1; -import org.xmind.core.internal.dom.FileFormat_1; -import org.xmind.core.internal.dom.WorkbookImpl; -import org.xmind.core.io.CoreIOException; - -public class Compatibility { - - public static WorkbookImpl loadCompatibleWorkbook( - DeserializerImpl deserializer) throws CoreException { - WorkbookImpl workbook = null; - - if (workbook == null) { - workbook = loadForFormat(new FileFormat_0_1(deserializer)); - } - - if (workbook == null) { - workbook = loadForFormat(new FileFormat_1(deserializer)); - } - - return workbook; - } - - private static WorkbookImpl loadForFormat(FileFormat format) - throws CoreException { - try { - if (!format.identifies()) - return null; - return format.load(); - } catch (CoreIOException e) { - CoreException ce = e.getCoreException(); - if (ce.getType() == Core.ERROR_WRONG_PASSWORD - || ce.getType() == Core.ERROR_CANCELLATION) { - throw new CoreException(ce.getType(), ce.getCodeInfo(), e); - } - } catch (CoreException e) { - if (e.getType() == Core.ERROR_WRONG_PASSWORD - || e.getType() == Core.ERROR_CANCELLATION) { - // if we encountered wrong password or cancellation, - // interrupt the loading process - throw e; - } - // otherwise, just continue to the next available format - } catch (Throwable e) { - // just continue to the next available format - } - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.compatibility; + +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.internal.dom.DeserializerImpl; +import org.xmind.core.internal.dom.FileFormat_0_1; +import org.xmind.core.internal.dom.FileFormat_1; +import org.xmind.core.internal.dom.WorkbookImpl; +import org.xmind.core.io.CoreIOException; + +public class Compatibility { + + public static WorkbookImpl loadCompatibleWorkbook( + DeserializerImpl deserializer) throws CoreException { + WorkbookImpl workbook = null; + + if (workbook == null) { + workbook = loadForFormat(new FileFormat_0_1(deserializer)); + } + + if (workbook == null) { + workbook = loadForFormat(new FileFormat_1(deserializer)); + } + + return workbook; + } + + private static WorkbookImpl loadForFormat(FileFormat format) + throws CoreException { + try { + if (!format.identifies()) + return null; + return format.load(); + } catch (CoreIOException e) { + CoreException ce = e.getCoreException(); + if (ce.getType() == Core.ERROR_WRONG_PASSWORD + || ce.getType() == Core.ERROR_CANCELLATION) { + throw new CoreException(ce.getType(), ce.getCodeInfo(), e); + } + } catch (CoreException e) { + if (e.getType() == Core.ERROR_WRONG_PASSWORD + || e.getType() == Core.ERROR_CANCELLATION) { + // if we encountered wrong password or cancellation, + // interrupt the loading process + throw e; + } + // otherwise, just continue to the next available format + } catch (Throwable e) { + // just continue to the next available format + } + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/FileFormat.java b/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/FileFormat.java index 25b35ddd8..cce94b1a8 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/FileFormat.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/compatibility/FileFormat.java @@ -1,35 +1,35 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.compatibility; - -import java.io.IOException; - -import org.xmind.core.CoreException; -import org.xmind.core.internal.dom.DeserializerImpl; -import org.xmind.core.internal.dom.WorkbookImpl; - -public abstract class FileFormat { - - protected DeserializerImpl deserializer; - - public FileFormat(DeserializerImpl deserializer) { - super(); - this.deserializer = deserializer; - } - - public abstract boolean identifies() throws CoreException, IOException; - - public abstract WorkbookImpl load() throws CoreException, IOException; - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.compatibility; + +import java.io.IOException; + +import org.xmind.core.CoreException; +import org.xmind.core.internal.dom.DeserializerImpl; +import org.xmind.core.internal.dom.WorkbookImpl; + +public abstract class FileFormat { + + protected DeserializerImpl deserializer; + + public FileFormat(DeserializerImpl deserializer) { + super(); + this.deserializer = deserializer; + } + + public abstract boolean identifies() throws CoreException, IOException; + + public abstract WorkbookImpl load() throws CoreException, IOException; + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BoundaryImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BoundaryImpl.java index 09ebc1410..38cf116f3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BoundaryImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BoundaryImpl.java @@ -1,291 +1,291 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RANGE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; - -import java.util.Iterator; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Boundary; -import org.xmind.core.util.DOMUtils; - -public class BoundaryImpl extends Boundary implements ICoreEventSource { - - private WorkbookImpl ownedWorkbook; - - private Element implementation; - - public BoundaryImpl(Element implementation, WorkbookImpl ownedWorkbook) { - super(); - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedWorkbook = ownedWorkbook; - } - - public Element getImplementation() { - return implementation; - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof BoundaryImpl)) - return false; - BoundaryImpl that = (BoundaryImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "BND#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - protected String getLocalTitleText() { - return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); - } - - public void setTitleText(String titleText) { - String oldText = getLocalTitleText(); - DOMUtils.setText(implementation, TAG_TITLE, titleText); - String newText = getLocalTitleText(); - fireValueChange(Core.TitleText, oldText, newText); - updateModificationInfo(); - } - - public String getStyleId() { - return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); - } - - public void setStyleId(String styleId) { - String oldValue = getStyleId(); - WorkbookImpl workbook = getRealizedWorkbook(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - String newValue = getStyleId(); - fireValueChange(Core.Style, oldValue, newValue); - updateModificationInfo(); - } - - public ISheet getOwnedSheet() { - ITopic parent = getParent(); - return parent == null ? null : parent.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - public ITopic getParent() { - Element t = getParentTopicElement(); - if (t != null) - return (ITopic) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(t); - return null; - } - - private Element getParentTopicElement() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_BOUNDARIES)) { - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPIC)) - return (Element) p; - } - return null; - } - - protected ITopic getTopic(int index) { - if (index < 0) - return null; - - Element p = getParentTopicElement(); - if (p == null) - return null; - - Element ts = TopicImpl.findSubtopicsElement(p, ITopic.ATTACHED); - if (ts == null) - return null; - - Iterator it = DOMUtils.childElementIterByTag(ts, TAG_TOPIC); - int i = 0; - while (it.hasNext()) { - Element t = it.next(); - if (i == index) { - return (ITopic) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(t); - } - i++; - } - return null; - } - - public int getEndIndex() { - return InternalDOMUtils - .getEndIndex(DOMUtils.getAttribute(implementation, ATTR_RANGE)); -// return safeParseInt(getAttribute(implementation, ATTR_END_INDEX), -1); - } - - public int getStartIndex() { - return InternalDOMUtils.getStartIndex( - DOMUtils.getAttribute(implementation, ATTR_RANGE)); -// return safeParseInt(getAttribute(implementation, ATTR_START_INDEX), -1); - } - -// private Integer getIndex(String attrName) { -// if (implementation.hasAttribute(attrName)) { -// try { -// return Integer.valueOf(implementation.getAttribute(attrName)); -// } catch (NumberFormatException e) { -// return null; -// } -// } -// return null; -// } - - private Integer toIndexValue(int index) { - return index < 0 ? null : Integer.valueOf(index); - } - - public void setEndIndex(int index) { - String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - Integer oldIndexValue = toIndexValue(getEndIndex()); - DOMUtils.setAttribute(implementation, ATTR_RANGE, - InternalDOMUtils.toRangeValue(getStartIndex(), index)); - Integer newIndexValue = toIndexValue(getEndIndex()); - String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - fireValueChange(Core.EndIndex, oldIndexValue, newIndexValue); - fireValueChange(Core.Range, oldValue, newValue); - updateModificationInfo(); - } - - public void setStartIndex(int index) { - String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - Integer oldIndexValue = toIndexValue(getStartIndex()); - DOMUtils.setAttribute(implementation, ATTR_RANGE, - InternalDOMUtils.toRangeValue(index, getEndIndex())); - Integer newIndexValue = toIndexValue(getStartIndex()); - String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - fireValueChange(Core.StartIndex, oldIndexValue, newIndexValue); - fireValueChange(Core.Range, oldValue, newValue); - updateModificationInfo(); - } - - public boolean isMasterBoundary() { - return DOMConstants.VAL_MASTER - .equals(DOMUtils.getAttribute(implementation, ATTR_RANGE)); - } - - public void setMasterBoundary(boolean overall) { - String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - String value = overall ? DOMConstants.VAL_MASTER : null; - DOMUtils.setAttribute(implementation, ATTR_RANGE, value); - String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - fireValueChange(Core.Range, oldValue, newValue); - updateModificationInfo(); - } - - protected WorkbookImpl getRealizedWorkbook() { - ITopic parent = getParent(); - if (parent instanceof TopicImpl) { - return ((TopicImpl) parent).getRealizedWorkbook(); - } - return null; - } - - protected void addNotify(WorkbookImpl workbook, TopicImpl parent) { - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); - workbook.getAdaptableRegistry().registerById(this, getId(), - getImplementation().getOwnerDocument()); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - } - - protected void removeNotify(WorkbookImpl workbook, TopicImpl parent) { - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - workbook.getAdaptableRegistry().unregisterById(this, getId(), - getImplementation().getOwnerDocument()); - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public ICoreEventSupport getCoreEventSupport() { - // Use workbook's core event support directly, so that - // orphan components can have events broadcasted, which - // will enable transient actions (such as dragging topics - // or adjusting relationship control points, etc.) to - // perform correctly. - return ownedWorkbook.getCoreEventSupport(); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, type, oldValue, - newValue); - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, implementation); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, implementation); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - - ITopic parent = getParent(); - if (parent != null) { - ((TopicImpl) parent).updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RANGE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; + +import java.util.Iterator; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Boundary; +import org.xmind.core.util.DOMUtils; + +public class BoundaryImpl extends Boundary implements ICoreEventSource { + + private WorkbookImpl ownedWorkbook; + + private Element implementation; + + public BoundaryImpl(Element implementation, WorkbookImpl ownedWorkbook) { + super(); + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedWorkbook = ownedWorkbook; + } + + public Element getImplementation() { + return implementation; + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof BoundaryImpl)) + return false; + BoundaryImpl that = (BoundaryImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "BND#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + protected String getLocalTitleText() { + return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); + } + + public void setTitleText(String titleText) { + String oldText = getLocalTitleText(); + DOMUtils.setText(implementation, TAG_TITLE, titleText); + String newText = getLocalTitleText(); + fireValueChange(Core.TitleText, oldText, newText); + updateModificationInfo(); + } + + public String getStyleId() { + return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); + } + + public void setStyleId(String styleId) { + String oldValue = getStyleId(); + WorkbookImpl workbook = getRealizedWorkbook(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + String newValue = getStyleId(); + fireValueChange(Core.Style, oldValue, newValue); + updateModificationInfo(); + } + + public ISheet getOwnedSheet() { + ITopic parent = getParent(); + return parent == null ? null : parent.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + public ITopic getParent() { + Element t = getParentTopicElement(); + if (t != null) + return (ITopic) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(t); + return null; + } + + private Element getParentTopicElement() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_BOUNDARIES)) { + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPIC)) + return (Element) p; + } + return null; + } + + protected ITopic getTopic(int index) { + if (index < 0) + return null; + + Element p = getParentTopicElement(); + if (p == null) + return null; + + Element ts = TopicImpl.findSubtopicsElement(p, ITopic.ATTACHED); + if (ts == null) + return null; + + Iterator it = DOMUtils.childElementIterByTag(ts, TAG_TOPIC); + int i = 0; + while (it.hasNext()) { + Element t = it.next(); + if (i == index) { + return (ITopic) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(t); + } + i++; + } + return null; + } + + public int getEndIndex() { + return InternalDOMUtils + .getEndIndex(DOMUtils.getAttribute(implementation, ATTR_RANGE)); +// return safeParseInt(getAttribute(implementation, ATTR_END_INDEX), -1); + } + + public int getStartIndex() { + return InternalDOMUtils.getStartIndex( + DOMUtils.getAttribute(implementation, ATTR_RANGE)); +// return safeParseInt(getAttribute(implementation, ATTR_START_INDEX), -1); + } + +// private Integer getIndex(String attrName) { +// if (implementation.hasAttribute(attrName)) { +// try { +// return Integer.valueOf(implementation.getAttribute(attrName)); +// } catch (NumberFormatException e) { +// return null; +// } +// } +// return null; +// } + + private Integer toIndexValue(int index) { + return index < 0 ? null : Integer.valueOf(index); + } + + public void setEndIndex(int index) { + String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + Integer oldIndexValue = toIndexValue(getEndIndex()); + DOMUtils.setAttribute(implementation, ATTR_RANGE, + InternalDOMUtils.toRangeValue(getStartIndex(), index)); + Integer newIndexValue = toIndexValue(getEndIndex()); + String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + fireValueChange(Core.EndIndex, oldIndexValue, newIndexValue); + fireValueChange(Core.Range, oldValue, newValue); + updateModificationInfo(); + } + + public void setStartIndex(int index) { + String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + Integer oldIndexValue = toIndexValue(getStartIndex()); + DOMUtils.setAttribute(implementation, ATTR_RANGE, + InternalDOMUtils.toRangeValue(index, getEndIndex())); + Integer newIndexValue = toIndexValue(getStartIndex()); + String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + fireValueChange(Core.StartIndex, oldIndexValue, newIndexValue); + fireValueChange(Core.Range, oldValue, newValue); + updateModificationInfo(); + } + + public boolean isMasterBoundary() { + return DOMConstants.VAL_MASTER + .equals(DOMUtils.getAttribute(implementation, ATTR_RANGE)); + } + + public void setMasterBoundary(boolean overall) { + String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + String value = overall ? DOMConstants.VAL_MASTER : null; + DOMUtils.setAttribute(implementation, ATTR_RANGE, value); + String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + fireValueChange(Core.Range, oldValue, newValue); + updateModificationInfo(); + } + + protected WorkbookImpl getRealizedWorkbook() { + ITopic parent = getParent(); + if (parent instanceof TopicImpl) { + return ((TopicImpl) parent).getRealizedWorkbook(); + } + return null; + } + + protected void addNotify(WorkbookImpl workbook, TopicImpl parent) { + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); + workbook.getAdaptableRegistry().registerById(this, getId(), + getImplementation().getOwnerDocument()); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + } + + protected void removeNotify(WorkbookImpl workbook, TopicImpl parent) { + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + workbook.getAdaptableRegistry().unregisterById(this, getId(), + getImplementation().getOwnerDocument()); + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public ICoreEventSupport getCoreEventSupport() { + // Use workbook's core event support directly, so that + // orphan components can have events broadcasted, which + // will enable transient actions (such as dragging topics + // or adjusting relationship control points, etc.) to + // perform correctly. + return ownedWorkbook.getCoreEventSupport(); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, type, oldValue, + newValue); + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, implementation); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, implementation); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + + ITopic parent = getParent(); + if (parent != null) { + ((TopicImpl) parent).updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentImpl.java index 8aa06f145..e1edb2dff 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentImpl.java @@ -1,175 +1,175 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_AUTHOR; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.util.DOMUtils; - -/** - * @author Frank Shaka - */ -public class CommentImpl implements IComment, ICoreEventSource { - - private final WorkbookImpl ownerWorkbook; - - private final Element implementation; - - private CommentManagerImpl ownedCommentManager; - - /** - * - */ - public CommentImpl(WorkbookImpl ownerWorkbook, - CommentManagerImpl ownedCommentManager, Element implementation) { - this.ownerWorkbook = ownerWorkbook; - this.ownedCommentManager = ownedCommentManager; - this.implementation = implementation; - } - - /** - * @return the implementation - */ - public Element getImplementation() { - return implementation; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) - */ - public T getAdapter(Class adapter) { - if (IWorkbook.class.equals(adapter)) - return adapter.cast(getOwnedWorkbook()); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - if (ICoreEventSupport.class.equals(adapter)) - return adapter.cast(getCoreEventSupport()); - return null; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() - */ - public IWorkbook getOwnedWorkbook() { - return ownerWorkbook; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - /* - * (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(IComment that) { - return (int) (that.getTime() - this.getTime()); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IComment#getObjectId() - */ - public String getObjectId() { - return DOMUtils.getAttribute(implementation, ATTR_OBJECT_ID); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IComment#getAuthor() - */ - public String getAuthor() { - return DOMUtils.getAttribute(implementation, ATTR_AUTHOR); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IComment#getTime() - */ - public long getTime() { - return NumberUtils.safeParseLong( - DOMUtils.getAttribute(implementation, DOMConstants.ATTR_TIME), - 0); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IComment#getContent() - */ - public String getContent() { - return DOMUtils.getTextContentByTag(implementation, TAG_CONTENT); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IComment#setContent(java.lang.String) - */ - public void setContent(String content) { - String oldContent = getContent(); - if (content == oldContent - || (content != null && content.equals(oldContent))) - return; - - DOMUtils.setText(implementation, TAG_CONTENT, content); - getCoreEventSupport().dispatchValueChange(this, Core.CommentContent, - oldContent, content); - updateModificationInfo(); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java.lang - * .String, org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() - */ - public ICoreEventSupport getCoreEventSupport() { - return ownerWorkbook.getCoreEventSupport(); - } - - protected void updateModificationInfo() { - if (ownedCommentManager != null) { - ownedCommentManager.updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_AUTHOR; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.util.DOMUtils; + +/** + * @author Frank Shaka + */ +public class CommentImpl implements IComment, ICoreEventSource { + + private final WorkbookImpl ownerWorkbook; + + private final Element implementation; + + private CommentManagerImpl ownedCommentManager; + + /** + * + */ + public CommentImpl(WorkbookImpl ownerWorkbook, + CommentManagerImpl ownedCommentManager, Element implementation) { + this.ownerWorkbook = ownerWorkbook; + this.ownedCommentManager = ownedCommentManager; + this.implementation = implementation; + } + + /** + * @return the implementation + */ + public Element getImplementation() { + return implementation; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) + */ + public T getAdapter(Class adapter) { + if (IWorkbook.class.equals(adapter)) + return adapter.cast(getOwnedWorkbook()); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + if (ICoreEventSupport.class.equals(adapter)) + return adapter.cast(getCoreEventSupport()); + return null; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() + */ + public IWorkbook getOwnedWorkbook() { + return ownerWorkbook; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + /* + * (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(IComment that) { + return (int) (that.getTime() - this.getTime()); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IComment#getObjectId() + */ + public String getObjectId() { + return DOMUtils.getAttribute(implementation, ATTR_OBJECT_ID); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IComment#getAuthor() + */ + public String getAuthor() { + return DOMUtils.getAttribute(implementation, ATTR_AUTHOR); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IComment#getTime() + */ + public long getTime() { + return NumberUtils.safeParseLong( + DOMUtils.getAttribute(implementation, DOMConstants.ATTR_TIME), + 0); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IComment#getContent() + */ + public String getContent() { + return DOMUtils.getTextContentByTag(implementation, TAG_CONTENT); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IComment#setContent(java.lang.String) + */ + public void setContent(String content) { + String oldContent = getContent(); + if (content == oldContent + || (content != null && content.equals(oldContent))) + return; + + DOMUtils.setText(implementation, TAG_CONTENT, content); + getCoreEventSupport().dispatchValueChange(this, Core.CommentContent, + oldContent, content); + updateModificationInfo(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java.lang + * .String, org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() + */ + public ICoreEventSupport getCoreEventSupport() { + return ownerWorkbook.getCoreEventSupport(); + } + + protected void updateModificationInfo() { + if (ownedCommentManager != null) { + ownedCommentManager.updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentManagerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentManagerImpl.java index 95b684aeb..7cede45a7 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentManagerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/CommentManagerImpl.java @@ -1,365 +1,365 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_AUTHOR; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIME; -import static org.xmind.core.internal.dom.DOMConstants.TAG_COMMENT; -import static org.xmind.core.internal.dom.DOMConstants.TAG_COMMENTS; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.IAdaptable; -import org.xmind.core.IComment; -import org.xmind.core.ICommentManager; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookComponent; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.util.DOMUtils; - -/** - * @author Frank Shaka - */ -public class CommentManagerImpl - implements ICommentManager, INodeAdaptableFactory { - - private final WorkbookImpl ownedWorkbook; - - private final Document implementation; - - private final NodeAdaptableRegistry registry; - - private final Set pendingComments; - - /** - * - */ - public CommentManagerImpl(WorkbookImpl ownerWorkbook, - Document implementation) { - this.ownedWorkbook = ownerWorkbook; - this.implementation = implementation; - this.registry = new NodeAdaptableRegistry(implementation, this); - this.pendingComments = new HashSet(); - init(); - } - - private void init() { - Element m = DOMUtils.ensureChildElement(implementation, TAG_COMMENTS); - NS.setNS(NS.Comments, m); - InternalDOMUtils.addVersion(implementation); - } - - private Element getCommentsElement() { - return implementation.getDocumentElement(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) - */ - public T getAdapter(Class adapter) { - if (IWorkbook.class.equals(adapter)) - return adapter.cast(getOwnedWorkbook()); - if (Node.class.equals(adapter) || Document.class.equals(adapter)) - return adapter.cast(implementation); - return null; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() - */ - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return false; - } - - protected void objectAddNotify(String objectId, Object obj) { - Element p = getCommentsElement(); - Iterator it = pendingComments.iterator(); - while (it.hasNext()) { - CommentImpl c = it.next(); - if (objectId.equals(c.getObjectId())) { - it.remove(); - Element ele = c.getImplementation(); - if (ele.getParentNode() != p) { - p.appendChild(ele); - if (obj instanceof ICoreEventSource) { - ownedWorkbook.getCoreEventSupport() - .dispatchTargetChange((ICoreEventSource) obj, - Core.CommentAdd, c); - } - } - } - } - } - - protected void objectRemoveNotify(String objectId, Object obj) { - Element p = getCommentsElement(); - int i = 0; - while (i < p.getChildNodes().getLength()) { - Node n = p.getChildNodes().item(i); - if (n instanceof Element - && TAG_COMMENT.equals(((Element) n).getTagName())) { - Element ele = (Element) n; - if (objectId - .equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { - p.removeChild(ele); - IAdaptable a = registry.getAdaptable(ele); - if (a instanceof CommentImpl) { - CommentImpl c = (CommentImpl) a; - pendingComments.add(c); - if (obj instanceof ICoreEventSource) { - ownedWorkbook.getCoreEventSupport() - .dispatchTargetChange( - (ICoreEventSource) obj, - Core.CommentRemove, c); - } - } - continue; - } - } - i++; - } - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#createComment(java.lang.String, long, - * java.lang.String) - */ - public IComment createComment(String author, long time, String objectId) { - if (author == null) - throw new IllegalArgumentException(); - if (time <= 0) - throw new IllegalArgumentException(); - if (objectId == null) - throw new IllegalArgumentException(); - - Element ele = implementation.createElement(TAG_COMMENT); - DOMUtils.setAttribute(ele, ATTR_AUTHOR, author); - DOMUtils.setAttribute(ele, ATTR_TIME, Long.toString(time)); - DOMUtils.setAttribute(ele, ATTR_OBJECT_ID, objectId); - - CommentImpl c = new CommentImpl(ownedWorkbook, this, ele); - registry.register(c, ele); - return c; - } - - private static boolean isObjectOrphan(Object obj) { - return !(obj instanceof IWorkbookComponent) - || ((IWorkbookComponent) obj).isOrphan(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#addCommand(org.xmind.core.IComment) - */ - public void addComment(IComment comment) { - if (!(comment instanceof CommentImpl) - || comment.getOwnedWorkbook() != getOwnedWorkbook()) - throw new IllegalArgumentException(); - - CommentImpl c = (CommentImpl) comment; - Element ele = c.getImplementation(); - Element p = getCommentsElement(); - if (ele.getParentNode() == p) - return; - - Object obj = ownedWorkbook.getElementById(c.getObjectId()); - if (obj == null || isObjectOrphan(obj)) { - /// associated object not exist, - /// add comment to pending set - pendingComments.add(c); - return; - } - - p.appendChild(ele); - if (obj instanceof ICoreEventSource) { - ownedWorkbook.getCoreEventSupport().dispatchTargetChange( - (ICoreEventSource) obj, Core.CommentAdd, c); - } - updateModificationInfo(); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.ICommentManager#removeComment(org.xmind.core.IComment) - */ - public void removeComment(IComment comment) { - if (!(comment instanceof CommentImpl) - || comment.getOwnedWorkbook() != getOwnedWorkbook()) - throw new IllegalArgumentException(); - - CommentImpl c = (CommentImpl) comment; - Element ele = c.getImplementation(); - Element p = getCommentsElement(); - - pendingComments.remove(c); - - if (ele.getParentNode() != p) - return; - - p.removeChild(ele); - - Object obj = ownedWorkbook.getElementById(c.getObjectId()); - if (obj instanceof ICoreEventSource) { - ownedWorkbook.getCoreEventSupport().dispatchTargetChange( - (ICoreEventSource) obj, Core.CommentRemove, c); - } - updateModificationInfo(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#getComments(java.lang.String) - */ - public Set getComments(String objectId) { - if (objectId == null) - throw new IllegalArgumentException(); - - Object o = getOwnedWorkbook().getElementById(objectId); - if (o == null || isObjectOrphan(o)) { - return Collections.emptySet(); - } - - Set set = new HashSet(); - Iterator it = DOMUtils - .childElementIterByTag(getCommentsElement(), TAG_COMMENT); - while (it.hasNext()) { - Element ele = it.next(); - if (objectId.equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { - IAdaptable a = registry.getAdaptable(ele); - if (a instanceof CommentImpl) { - set.add((CommentImpl) a); - } - } - } - return set; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#hasComments(java.lang.String) - */ - public boolean hasComments(String objectId) { - if (objectId == null) - throw new IllegalArgumentException(); - - Object o = getOwnedWorkbook().getElementById(objectId); - if (o == null || isObjectOrphan(o)) { - return false; - } - - Iterator it = DOMUtils - .childElementIterByTag(getCommentsElement(), TAG_COMMENT); - while (it.hasNext()) { - Element ele = it.next(); - if (objectId.equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { - IAdaptable a = registry.getAdaptable(ele); - if (a instanceof CommentImpl) { - return true; - } - } - } - - return false; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#getAllComments() - */ - public Set getAllComments() { - Set set = new HashSet(); - Iterator it = DOMUtils - .childElementIterByTag(getCommentsElement(), TAG_COMMENT); - while (it.hasNext()) { - Element ele = it.next(); - IAdaptable a = registry.getAdaptable(ele); - if (a instanceof CommentImpl) { - CommentImpl c = (CommentImpl) a; - Object o = getOwnedWorkbook().getElementById(c.getObjectId()); - if (o != null && !isObjectOrphan(o)) { - set.add(c); - } - } - } - return set; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.ICommentManager#isEmpty() - */ - public boolean isEmpty() { - Iterator it = DOMUtils - .childElementIterByTag(getCommentsElement(), TAG_COMMENT); - while (it.hasNext()) { - Element ele = it.next(); - IAdaptable a = registry.getAdaptable(ele); - if (a instanceof CommentImpl) { - CommentImpl c = (CommentImpl) a; - Object o = getOwnedWorkbook().getElementById(c.getObjectId()); - if (o != null && !isObjectOrphan(o)) { - return false; - } - } - } - return true; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.internal.dom.INodeAdaptableFactory#createAdaptable(org.w3c - * .dom.Node) - */ - public IAdaptable createAdaptable(Node node) { - if (node instanceof Element) { - Element ele = (Element) node; - String tag = ele.getTagName(); - if (TAG_COMMENT.equals(tag)) { - return new CommentImpl(ownedWorkbook, this, ele); - } - } - return null; - } - - protected void updateModificationInfo() { - if (ownedWorkbook != null) { - ownedWorkbook.updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_AUTHOR; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIME; +import static org.xmind.core.internal.dom.DOMConstants.TAG_COMMENT; +import static org.xmind.core.internal.dom.DOMConstants.TAG_COMMENTS; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.IComment; +import org.xmind.core.ICommentManager; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookComponent; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.util.DOMUtils; + +/** + * @author Frank Shaka + */ +public class CommentManagerImpl + implements ICommentManager, INodeAdaptableFactory { + + private final WorkbookImpl ownedWorkbook; + + private final Document implementation; + + private final NodeAdaptableRegistry registry; + + private final Set pendingComments; + + /** + * + */ + public CommentManagerImpl(WorkbookImpl ownerWorkbook, + Document implementation) { + this.ownedWorkbook = ownerWorkbook; + this.implementation = implementation; + this.registry = new NodeAdaptableRegistry(implementation, this); + this.pendingComments = new HashSet(); + init(); + } + + private void init() { + Element m = DOMUtils.ensureChildElement(implementation, TAG_COMMENTS); + NS.setNS(NS.Comments, m); + InternalDOMUtils.addVersion(implementation); + } + + private Element getCommentsElement() { + return implementation.getDocumentElement(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) + */ + public T getAdapter(Class adapter) { + if (IWorkbook.class.equals(adapter)) + return adapter.cast(getOwnedWorkbook()); + if (Node.class.equals(adapter) || Document.class.equals(adapter)) + return adapter.cast(implementation); + return null; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() + */ + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return false; + } + + protected void objectAddNotify(String objectId, Object obj) { + Element p = getCommentsElement(); + Iterator it = pendingComments.iterator(); + while (it.hasNext()) { + CommentImpl c = it.next(); + if (objectId.equals(c.getObjectId())) { + it.remove(); + Element ele = c.getImplementation(); + if (ele.getParentNode() != p) { + p.appendChild(ele); + if (obj instanceof ICoreEventSource) { + ownedWorkbook.getCoreEventSupport() + .dispatchTargetChange((ICoreEventSource) obj, + Core.CommentAdd, c); + } + } + } + } + } + + protected void objectRemoveNotify(String objectId, Object obj) { + Element p = getCommentsElement(); + int i = 0; + while (i < p.getChildNodes().getLength()) { + Node n = p.getChildNodes().item(i); + if (n instanceof Element + && TAG_COMMENT.equals(((Element) n).getTagName())) { + Element ele = (Element) n; + if (objectId + .equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { + p.removeChild(ele); + IAdaptable a = registry.getAdaptable(ele); + if (a instanceof CommentImpl) { + CommentImpl c = (CommentImpl) a; + pendingComments.add(c); + if (obj instanceof ICoreEventSource) { + ownedWorkbook.getCoreEventSupport() + .dispatchTargetChange( + (ICoreEventSource) obj, + Core.CommentRemove, c); + } + } + continue; + } + } + i++; + } + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#createComment(java.lang.String, long, + * java.lang.String) + */ + public IComment createComment(String author, long time, String objectId) { + if (author == null) + throw new IllegalArgumentException(); + if (time <= 0) + throw new IllegalArgumentException(); + if (objectId == null) + throw new IllegalArgumentException(); + + Element ele = implementation.createElement(TAG_COMMENT); + DOMUtils.setAttribute(ele, ATTR_AUTHOR, author); + DOMUtils.setAttribute(ele, ATTR_TIME, Long.toString(time)); + DOMUtils.setAttribute(ele, ATTR_OBJECT_ID, objectId); + + CommentImpl c = new CommentImpl(ownedWorkbook, this, ele); + registry.register(c, ele); + return c; + } + + private static boolean isObjectOrphan(Object obj) { + return !(obj instanceof IWorkbookComponent) + || ((IWorkbookComponent) obj).isOrphan(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#addCommand(org.xmind.core.IComment) + */ + public void addComment(IComment comment) { + if (!(comment instanceof CommentImpl) + || comment.getOwnedWorkbook() != getOwnedWorkbook()) + throw new IllegalArgumentException(); + + CommentImpl c = (CommentImpl) comment; + Element ele = c.getImplementation(); + Element p = getCommentsElement(); + if (ele.getParentNode() == p) + return; + + Object obj = ownedWorkbook.getElementById(c.getObjectId()); + if (obj == null || isObjectOrphan(obj)) { + /// associated object not exist, + /// add comment to pending set + pendingComments.add(c); + return; + } + + p.appendChild(ele); + if (obj instanceof ICoreEventSource) { + ownedWorkbook.getCoreEventSupport().dispatchTargetChange( + (ICoreEventSource) obj, Core.CommentAdd, c); + } + updateModificationInfo(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.ICommentManager#removeComment(org.xmind.core.IComment) + */ + public void removeComment(IComment comment) { + if (!(comment instanceof CommentImpl) + || comment.getOwnedWorkbook() != getOwnedWorkbook()) + throw new IllegalArgumentException(); + + CommentImpl c = (CommentImpl) comment; + Element ele = c.getImplementation(); + Element p = getCommentsElement(); + + pendingComments.remove(c); + + if (ele.getParentNode() != p) + return; + + p.removeChild(ele); + + Object obj = ownedWorkbook.getElementById(c.getObjectId()); + if (obj instanceof ICoreEventSource) { + ownedWorkbook.getCoreEventSupport().dispatchTargetChange( + (ICoreEventSource) obj, Core.CommentRemove, c); + } + updateModificationInfo(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#getComments(java.lang.String) + */ + public Set getComments(String objectId) { + if (objectId == null) + throw new IllegalArgumentException(); + + Object o = getOwnedWorkbook().getElementById(objectId); + if (o == null || isObjectOrphan(o)) { + return Collections.emptySet(); + } + + Set set = new HashSet(); + Iterator it = DOMUtils + .childElementIterByTag(getCommentsElement(), TAG_COMMENT); + while (it.hasNext()) { + Element ele = it.next(); + if (objectId.equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { + IAdaptable a = registry.getAdaptable(ele); + if (a instanceof CommentImpl) { + set.add((CommentImpl) a); + } + } + } + return set; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#hasComments(java.lang.String) + */ + public boolean hasComments(String objectId) { + if (objectId == null) + throw new IllegalArgumentException(); + + Object o = getOwnedWorkbook().getElementById(objectId); + if (o == null || isObjectOrphan(o)) { + return false; + } + + Iterator it = DOMUtils + .childElementIterByTag(getCommentsElement(), TAG_COMMENT); + while (it.hasNext()) { + Element ele = it.next(); + if (objectId.equals(DOMUtils.getAttribute(ele, ATTR_OBJECT_ID))) { + IAdaptable a = registry.getAdaptable(ele); + if (a instanceof CommentImpl) { + return true; + } + } + } + + return false; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#getAllComments() + */ + public Set getAllComments() { + Set set = new HashSet(); + Iterator it = DOMUtils + .childElementIterByTag(getCommentsElement(), TAG_COMMENT); + while (it.hasNext()) { + Element ele = it.next(); + IAdaptable a = registry.getAdaptable(ele); + if (a instanceof CommentImpl) { + CommentImpl c = (CommentImpl) a; + Object o = getOwnedWorkbook().getElementById(c.getObjectId()); + if (o != null && !isObjectOrphan(o)) { + set.add(c); + } + } + } + return set; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.ICommentManager#isEmpty() + */ + public boolean isEmpty() { + Iterator it = DOMUtils + .childElementIterByTag(getCommentsElement(), TAG_COMMENT); + while (it.hasNext()) { + Element ele = it.next(); + IAdaptable a = registry.getAdaptable(ele); + if (a instanceof CommentImpl) { + CommentImpl c = (CommentImpl) a; + Object o = getOwnedWorkbook().getElementById(c.getObjectId()); + if (o != null && !isObjectOrphan(o)) { + return false; + } + } + } + return true; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.internal.dom.INodeAdaptableFactory#createAdaptable(org.w3c + * .dom.Node) + */ + public IAdaptable createAdaptable(Node node) { + if (node instanceof Element) { + Element ele = (Element) node; + String tag = ele.getTagName(); + if (TAG_COMMENT.equals(tag)) { + return new CommentImpl(ownedWorkbook, this, ele); + } + } + return null; + } + + protected void updateModificationInfo() { + if (ownedWorkbook != null) { + ownedWorkbook.updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DOMConstants.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DOMConstants.java index b6faa1b12..5dde44f6f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DOMConstants.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DOMConstants.java @@ -1,238 +1,238 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -/** - * @author briansun - */ -public class DOMConstants { - - // ========================= - // ATTRIBUTES - // ------------------------- - public static final String ATTR_ALGORITHM_NAME = "algorithm-name"; //$NON-NLS-1$ - public static final String ATTR_ALIGN = "align"; //$NON-NLS-1$ - public static final String ATTR_AMOUNT = "amount"; //$NON-NLS-1$ - public static final String ATTR_ANGLE = "angle"; //$NON-NLS-1$ - public static final String ATTR_ARROW_BEGIN_CLASS = "arrow-begin-class"; //$NON-NLS-1$ - public static final String ATTR_ARROW_END_CLASS = "arrow-end-class"; //$NON-NLS-1$ - public static final String ATTR_AUTHOR = "author"; //$NON-NLS-1$ - public static final String ATTR_BACKGROUND = "background"; //$NON-NLS-1$ - public static final String ATTR_BACKGROUND_COLOR = "fo:background-color"; //$NON-NLS-1$ - public static final String ATTR_BORDER_LINE_COLOR = "border-line-color"; //$NON-NLS-1$ - public static final String ATTR_BORDER_LINE_WIDTH = "border-line-width"; //$NON-NLS-1$ - public static final String ATTR_BRANCH = "branch"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_FILL_COLOR = "callout-fill-color"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_LINE_CLASS = "callout-line-class"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_LINE_COLOR = "callout-line-color"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_LINE_CORNER = "callout-line-corner"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_LINE_PATTERN = "callout-line-pattern"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_LINE_WIDTH = "callout-line-width"; //$NON-NLS-1$ - public static final String ATTR_CALLOUT_SHAPE_CLASS = "callout-shape-class"; //$NON-NLS-1$ - public static final String ATTR_CHECKSUM = "checksum";//$NON-NLS-1$ - public static final String ATTR_CHECKSUM_TYPE = "checksum-type";//$NON-NLS-1$ - public static final String ATTR_COLOR = "fo:color"; //$NON-NLS-1$ - public static final String ATTR_CREATOR_NAME = "creator-name"; //$NON-NLS-1$ - public static final String ATTR_CREATOR_VERSION = "creator-version"; //$NON-NLS-1$ - public static final String ATTR_DESCRIPTION = "description"; //$NON-NLS-1$ - public static final String ATTR_END1 = "end1"; //$NON-NLS-1$ - public static final String ATTR_END2 = "end2"; //$NON-NLS-1$ - public static final String ATTR_FILL = "svg:fill"; //$NON-NLS-1$ - public static final String ATTR_FONT_DECORATION = "fo:text-decoration"; //$NON-NLS-1$ - public static final String ATTR_FONT_FAMILY = "fo:font-family"; //$NON-NLS-1$ - public static final String ATTR_FONT_SIZE = "fo:font-size"; //$NON-NLS-1$ - public static final String ATTR_FONT_STYLE = "fo:font-style"; //$NON-NLS-1$ - public static final String ATTR_FONT_WEIGHT = "fo:font-weight"; //$NON-NLS-1$ - public static final String ATTR_FULL_PATH = "full-path"; //$NON-NLS-1$ - public static final String ATTR_GRADIENT_COLOR = "color-gradient";//$NON-NLS-1$ - public static final String ATTR_HEIGHT = "svg:height"; //$NON-NLS-1$ - public static final String ATTR_HIDDEN = "hidden"; //$NON-NLS-1$ - public static final String ATTR_HREF = "xlink:href"; //$NON-NLS-1$ - public static final String ATTR_ID = "id"; //$NON-NLS-1$ - public static final String ATTR_INDEX = "index"; //$NON-NLS-1$ - public static final String ATTR_ITERATION_COUNT = "iteration-count"; //$NON-NLS-1$ - public static final String ATTR_KEY_DERIVATION_NAME = "key-derivation-name"; //$NON-NLS-1$ - public static final String ATTR_LINE_CLASS = "line-class"; //$NON-NLS-1$ - public static final String ATTR_LINE_COLOR = "line-color"; //$NON-NLS-1$ - public static final String ATTR_LINE_CORNER = "line-corner"; //$NON-NLS-1$ - public static final String ATTR_LINE_PATTERN = "line-pattern"; //$NON-NLS-1$ - public static final String ATTR_LINE_TAPERED = "line-tapered"; //$NON-NLS-1$ - public static final String ATTR_LINE_WIDTH = "line-width"; //$NON-NLS-1$ - public static final String ATTR_MARGIN_BOTTOM = "fo:margin-bottom"; //$NON-NLS-1$ - public static final String ATTR_MARGIN_LEFT = "fo:margin-left"; //$NON-NLS-1$ - public static final String ATTR_MARGIN_RIGHT = "fo:margin-right"; //$NON-NLS-1$ - public static final String ATTR_MARGIN_TOP = "fo:margin-top"; //$NON-NLS-1$ - public static final String ATTR_MARKER_ID = "marker-id"; //$NON-NLS-1$ - public static final String ATTR_MEDIA_TYPE = "media-type"; //$NON-NLS-1$ - public static final String ATTR_MODE = "mode"; //$NON-NLS-1$ - public static final String ATTR_MODIFIED_BY = "modified-by"; //$NON-NLS-1$ - public static final String ATTR_MODIFYBY = "modifyby"; //$NON-NLS-1$ - public static final String ATTR_MULTI_LINE_COLORS = "multi-line-colors"; //$NON-NLS-1$ - public static final String ATTR_NAME = "name"; //$NON-NLS-1$ - public static final String ATTR_NEXT_REVISION_NUMBER = "next-rev-num"; //$NON-NLS-1$ - public static final String ATTR_NUMBER_FORMAT = "number-format"; //$NON-NLS-1$ - public static final String ATTR_NUMBER_SEPARATOR = "number-separator"; //$NON-NLS-1$ - public static final String ATTR_NUMBER_DEPTH = "number-depth"; //$NON-NLS-1$ - public static final String ATTR_OBJECT_ID = "object-id"; //$NON-NLS-1$ - public static final String ATTR_OPACITY = "svg:opacity"; //$NON-NLS-1$ - public static final String ATTR_PREPENDING_NUMBERS = "prepending-numbers"; //$NON-NLS-1$ - public static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$ - public static final String ATTR_RANGE = "range"; //$NON-NLS-1$ - public static final String ATTR_RESOURCE = "resource"; //$NON-NLS-1$ - public static final String ATTR_RESOURCE_PATH = "resource-path"; //$NON-NLS-1$ - public static final String ATTR_SVG = "svg"; //$NON-NLS-1$ - public static final String ATTR_RESOURCE_ID = "resource-id"; //$NON-NLS-1$ - public static final String ATTR_RESOURCE_TYPE = "resource-type"; //$NON-NLS-1$ - public static final String ATTR_REVISION_NUMBER = "rev-num"; //$NON-NLS-1$ - public static final String ATTR_SALT = "salt"; //$NON-NLS-1$ - public static final String ATTR_KEY_IV = "iv"; //$NON-NLS-1$ - public static final String ATTR_KEY_SIZE = "size"; //$NON-NLS-1$ - public static final String ATTR_SHAPE_CLASS = "shape-class"; //$NON-NLS-1$ - public static final String ATTR_SHAPE_CORNER = "shape-corner"; //$NON-NLS-1$ - public static final String ATTR_SINGLETON = "singleton"; //$NON-NLS-1$ - public static final String ATTR_SPACING_MAJOR = "spacing-major"; //$NON-NLS-1$ - public static final String ATTR_SPACING_MINOR = "spacing-minor"; //$NON-NLS-1$ - public static final String ATTR_SRC = "xhtml:src"; //$NON-NLS-1$ - public static final String ATTR_STRUCTURE_CLASS = "structure-class"; //$NON-NLS-1$ - public static final String ATTR_STYLE_FAMILY = "style-family"; //$NON-NLS-1$ - public static final String ATTR_STYLE_ID = "style-id"; //$NON-NLS-1$ - public static final String ATTR_TEXT_ALIGN = "fo:text-align"; //$NON-NLS-1$ - public static final String ATTR_TEXT_BULLET = "fo:text-bullet"; //$NON-NLS-1$ - public static final String ATTR_TEXT_TRANSFORM = "fo:text-transform"; //$NON-NLS-1$ - public static final String ATTR_THEME = "theme"; //$NON-NLS-1$ - public static final String ATTR_TIME = "time"; //$NON-NLS-1$ - public static final String ATTR_TIMESTAMP = "timestamp"; //$NON-NLS-1$ - public static final String ATTR_TOPIC_ID = "topic-id"; //$NON-NLS-1$ - public static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - public static final String ATTR_VERSION = "version"; //$NON-NLS-1$ - public static final String ATTR_VISIBILITY = "visibility"; //$NON-NLS-1$ - public static final String ATTR_WIDTH = "svg:width"; //$NON-NLS-1$ - public static final String ATTR_X = "svg:x"; //$NON-NLS-1$ - public static final String ATTR_Y = "svg:y"; //$NON-NLS-1$ - public static final String PASSWORD_HINT = "password-hint"; //$NON-NLS-1$ - - /* - * - */ - public static final String AUTHOR_EMAIL = "org.xmind.author.email"; //$NON-NLS-1$ - public static final String AUTHOR_NAME = "org.xmind.author.name"; //$NON-NLS-1$ - public static final String AUTHOR_ORG = "org.xmind.author.org"; //$NON-NLS-1$ - - @Deprecated - protected static final String EVENT_SUBTREE_MODIFIED = "DOMSubtreeModified"; //$NON-NLS-1$ - - // ========================= - // TAGS - // ------------------------- - public static final String TAG_A = "xhtml:a"; //$NON-NLS-1$ - public static final String TAG_ALGORITHM = "algorithm"; //$NON-NLS-1$ - public static final String TAG_ASSIGNEE = "assignee"; //$NON-NLS-1$ - public static final String TAG_ASSIGNEE_SHEET = "assignee-sheet"; //$NON-NLS-1$ - public static final String TAG_AUTOMATIC_STYLES = "automatic-styles"; //$NON-NLS-1$ - public static final String TAG_BOUNDARIES = "boundaries"; //$NON-NLS-1$ - public static final String TAG_BOUNDARY = "boundary"; //$NON-NLS-1$ - public static final String TAG_CHILDREN = "children"; //$NON-NLS-1$ - public static final String TAG_COMMENT = "comment"; //$NON-NLS-1$ - public static final String TAG_COMMENTS = "comments"; //$NON-NLS-1$ - public static final String TAG_CONTENT = "content"; //$NON-NLS-1$ - public static final String TAG_CONTROL_POINT = "control-point"; //$NON-NLS-1$ - public static final String TAG_CONTROL_POINTS = "control-points"; //$NON-NLS-1$ - public static final String TAG_DEFAULT_STYLE = "default-style"; //$NON-NLS-1$ - public static final String TAG_ENCRYPTION_DATA = "encryption-data"; //$NON-NLS-1$ - public static final String TAG_EXTENSION = "extension"; //$NON-NLS-1$ - public static final String TAG_EXTENSIONS = "extensions"; //$NON-NLS-1$ - public static final String TAG_FILE_ENTRY = "file-entry"; //$NON-NLS-1$ - public static final String TAG_IMG = "xhtml:img"; //$NON-NLS-1$ - public static final String TAG_INFO_ITEM = "info-item"; //$NON-NLS-1$ - public static final String TAG_INFO_ITEMS = "info-items"; //$NON-NLS-1$ - public static final String TAG_KEY_DERIVATION = "key-derivation"; //$NON-NLS-1$ - public static final String TAG_LABEL = "label"; //$NON-NLS-1$ - public static final String TAG_LABELS = "labels"; //$NON-NLS-1$ - public static final String TAG_LEGEND = "legend"; //$NON-NLS-1$ - public static final String TAG_MANIFEST = "manifest"; //$NON-NLS-1$ - public static final String TAG_MARKER = "marker"; //$NON-NLS-1$ - public static final String TAG_MARKER_DESCRIPTION = "marker-description"; //$NON-NLS-1$ - public static final String TAG_MARKER_DESCRIPTIONS = "marker-descriptions"; //$NON-NLS-1$ - public static final String TAG_MARKER_GROUP = "marker-group"; //$NON-NLS-1$ - public static final String TAG_MARKER_REF = "marker-ref"; //$NON-NLS-1$ - public static final String TAG_MARKER_REFS = "marker-refs"; //$NON-NLS-1$ - public static final String TAG_MARKER_SHEET = "marker-sheet"; //$NON-NLS-1$ - public static final String TAG_MASTER_STYLES = "master-styles"; //$NON-NLS-1$ - public static final String TAG_META = "meta"; //$NON-NLS-1$ - public static final String TAG_NOTES = "notes"; //$NON-NLS-1$ - public static final String TAG_NUMBERING = "numbering"; //$NON-NLS-1$ - public static final String TAG_P = "xhtml:p"; //$NON-NLS-1$ - public static final String TAG_POSITION = "position"; //$NON-NLS-1$ - public static final String TAG_PREFIX = "prefix"; //$NON-NLS-1$ - public static final String TAG_PROPERTIES = "properties"; //$NON-NLS-1$ - public static final String TAG_RELATIONSHIP = "relationship"; //$NON-NLS-1$ - public static final String TAG_RELATIONSHIPS = "relationships"; //$NON-NLS-1$ - public static final String TAG_RESOURCE_REF = "resource-ref"; //$NON-NLS-1$ - public static final String TAG_RESOURCE_REFS = "resource-refs"; //$NON-NLS-1$ - public static final String TAG_REVISION = "revision"; //$NON-NLS-1$ - public static final String TAG_REVISION_CONTENT = "xmap-revision-content"; //$NON-NLS-1$ - public static final String TAG_REVISIONS = "xmap-revisions"; //$NON-NLS-1$ - public static final String TAG_SEPARATOR = "separator"; //$NON-NLS-1$ - public static final String TAG_SHEET = "sheet"; //$NON-NLS-1$ - public static final String TAG_SHEET_SETTINGS = "sheet-settings"; //$NON-NLS-1$ - public static final String TAG_SPAN = "xhtml:span"; //$NON-NLS-1$ - public static final String TAG_STYLE = "style"; //$NON-NLS-1$ - public static final String TAG_STYLE_SHEET = "xmap-styles"; //$NON-NLS-1$ - public static final String TAG_STYLES = "styles"; //$NON-NLS-1$ - public static final String TAG_SUFFIX = "suffix"; //$NON-NLS-1$ - public static final String TAG_SUMMARIES = "summaries"; //$NON-NLS-1$ - public static final String TAG_SUMMARY = "summary"; //$NON-NLS-1$ - public static final String TAG_TITLE = "title"; //$NON-NLS-1$ - public static final String TAG_TOPIC = "topic"; //$NON-NLS-1$ - public static final String TAG_TOPICS = "topics"; //$NON-NLS-1$ - public static final String TAG_WORKBOOK = "xmap-content"; //$NON-NLS-1$ - public static final String TAG_STORIES = "stories"; //$NON-NLS-1$ - - // ================== - // VALUES - // ------------------ - public static final String VAL_BOLD = "bold"; //$NON-NLS-1$ - public static final String VAL_BOTTOM = "bottom"; //$NON-NLS-1$ - public static final String VAL_BULLET = "bullet"; //$NON-NLS-1$ - public static final String VAL_CAPITALIZE = "capitalize"; //$NON-NLS-1$ - public static final String VAL_CARDMODE = "card"; //$NON-NLS-1$ - public static final String VAL_CENTER = "center"; //$NON-NLS-1$ - public static final String VAL_DEFAULT = "default"; //$NON-NLS-1$ - public static final String VAL_FOLDED = "folded"; //$NON-NLS-1$ - public static final String VAL_GRADIENT = "gradient"; //$NON-NLS-1$ - public static final String VAL_HIDDEN = "hidden"; //$NON-NLS-1$ - public static final String VAL_ICONMODE = "icon"; //$NON-NLS-1$ - public static final String VAL_ITALIC = "italic"; //$NON-NLS-1$ - public static final String VAL_LEFT = "left"; //$NON-NLS-1$ - public static final String VAL_LINE_DASH = "dash"; //$NON-NLS-1$ - public static final String VAL_LINE_DASH_DOT = "dash-dot"; //$NON-NLS-1$ - public static final String VAL_LINE_DASH_DOT_DOT = "dash-dot-dot"; //$NON-NLS-1$ - public static final String VAL_LINE_DOT = "dot"; //$NON-NLS-1$ - public static final String VAL_LINE_SOLID = "solid"; //$NON-NLS-1$ - public static final String VAL_LINE_THROUGH = "line-through"; //$NON-NLS-1$ - public static final String VAL_LOWERCASE = "lowercase"; //$NON-NLS-1$ - public static final String VAL_MANUAL = "manual"; //$NON-NLS-1$ - public static final String VAL_MASTER = "master"; //$NON-NLS-1$ - public static final String VAL_NONE = "none"; //$NON-NLS-1$ - public static final String VAL_NORMAL = "normal"; //$NON-NLS-1$ - public static final String VAL_NUMBER = "number"; //$NON-NLS-1$ - public static final String VAL_RIGHT = "right"; //$NON-NLS-1$ - public static final String VAL_SYSTEM = "$system$"; //$NON-NLS-1$ - public static final String VAL_TAPERED = "tapered"; //$NON-NLS-1$ - public static final String VAL_TOP = "top"; //$NON-NLS-1$ - public static final String VAL_UNDERLINE = "underline"; //$NON-NLS-1$ - public static final String VAL_UPPERCASE = "uppercase"; //$NON-NLS-1$ - public static final String VAL_VISIBLE = "visible"; //$NON-NLS-1$ - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +/** + * @author briansun + */ +public class DOMConstants { + + // ========================= + // ATTRIBUTES + // ------------------------- + public static final String ATTR_ALGORITHM_NAME = "algorithm-name"; //$NON-NLS-1$ + public static final String ATTR_ALIGN = "align"; //$NON-NLS-1$ + public static final String ATTR_AMOUNT = "amount"; //$NON-NLS-1$ + public static final String ATTR_ANGLE = "angle"; //$NON-NLS-1$ + public static final String ATTR_ARROW_BEGIN_CLASS = "arrow-begin-class"; //$NON-NLS-1$ + public static final String ATTR_ARROW_END_CLASS = "arrow-end-class"; //$NON-NLS-1$ + public static final String ATTR_AUTHOR = "author"; //$NON-NLS-1$ + public static final String ATTR_BACKGROUND = "background"; //$NON-NLS-1$ + public static final String ATTR_BACKGROUND_COLOR = "fo:background-color"; //$NON-NLS-1$ + public static final String ATTR_BORDER_LINE_COLOR = "border-line-color"; //$NON-NLS-1$ + public static final String ATTR_BORDER_LINE_WIDTH = "border-line-width"; //$NON-NLS-1$ + public static final String ATTR_BRANCH = "branch"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_FILL_COLOR = "callout-fill-color"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_LINE_CLASS = "callout-line-class"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_LINE_COLOR = "callout-line-color"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_LINE_CORNER = "callout-line-corner"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_LINE_PATTERN = "callout-line-pattern"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_LINE_WIDTH = "callout-line-width"; //$NON-NLS-1$ + public static final String ATTR_CALLOUT_SHAPE_CLASS = "callout-shape-class"; //$NON-NLS-1$ + public static final String ATTR_CHECKSUM = "checksum";//$NON-NLS-1$ + public static final String ATTR_CHECKSUM_TYPE = "checksum-type";//$NON-NLS-1$ + public static final String ATTR_COLOR = "fo:color"; //$NON-NLS-1$ + public static final String ATTR_CREATOR_NAME = "creator-name"; //$NON-NLS-1$ + public static final String ATTR_CREATOR_VERSION = "creator-version"; //$NON-NLS-1$ + public static final String ATTR_DESCRIPTION = "description"; //$NON-NLS-1$ + public static final String ATTR_END1 = "end1"; //$NON-NLS-1$ + public static final String ATTR_END2 = "end2"; //$NON-NLS-1$ + public static final String ATTR_FILL = "svg:fill"; //$NON-NLS-1$ + public static final String ATTR_FONT_DECORATION = "fo:text-decoration"; //$NON-NLS-1$ + public static final String ATTR_FONT_FAMILY = "fo:font-family"; //$NON-NLS-1$ + public static final String ATTR_FONT_SIZE = "fo:font-size"; //$NON-NLS-1$ + public static final String ATTR_FONT_STYLE = "fo:font-style"; //$NON-NLS-1$ + public static final String ATTR_FONT_WEIGHT = "fo:font-weight"; //$NON-NLS-1$ + public static final String ATTR_FULL_PATH = "full-path"; //$NON-NLS-1$ + public static final String ATTR_GRADIENT_COLOR = "color-gradient";//$NON-NLS-1$ + public static final String ATTR_HEIGHT = "svg:height"; //$NON-NLS-1$ + public static final String ATTR_HIDDEN = "hidden"; //$NON-NLS-1$ + public static final String ATTR_HREF = "xlink:href"; //$NON-NLS-1$ + public static final String ATTR_ID = "id"; //$NON-NLS-1$ + public static final String ATTR_INDEX = "index"; //$NON-NLS-1$ + public static final String ATTR_ITERATION_COUNT = "iteration-count"; //$NON-NLS-1$ + public static final String ATTR_KEY_DERIVATION_NAME = "key-derivation-name"; //$NON-NLS-1$ + public static final String ATTR_LINE_CLASS = "line-class"; //$NON-NLS-1$ + public static final String ATTR_LINE_COLOR = "line-color"; //$NON-NLS-1$ + public static final String ATTR_LINE_CORNER = "line-corner"; //$NON-NLS-1$ + public static final String ATTR_LINE_PATTERN = "line-pattern"; //$NON-NLS-1$ + public static final String ATTR_LINE_TAPERED = "line-tapered"; //$NON-NLS-1$ + public static final String ATTR_LINE_WIDTH = "line-width"; //$NON-NLS-1$ + public static final String ATTR_MARGIN_BOTTOM = "fo:margin-bottom"; //$NON-NLS-1$ + public static final String ATTR_MARGIN_LEFT = "fo:margin-left"; //$NON-NLS-1$ + public static final String ATTR_MARGIN_RIGHT = "fo:margin-right"; //$NON-NLS-1$ + public static final String ATTR_MARGIN_TOP = "fo:margin-top"; //$NON-NLS-1$ + public static final String ATTR_MARKER_ID = "marker-id"; //$NON-NLS-1$ + public static final String ATTR_MEDIA_TYPE = "media-type"; //$NON-NLS-1$ + public static final String ATTR_MODE = "mode"; //$NON-NLS-1$ + public static final String ATTR_MODIFIED_BY = "modified-by"; //$NON-NLS-1$ + public static final String ATTR_MODIFYBY = "modifyby"; //$NON-NLS-1$ + public static final String ATTR_MULTI_LINE_COLORS = "multi-line-colors"; //$NON-NLS-1$ + public static final String ATTR_NAME = "name"; //$NON-NLS-1$ + public static final String ATTR_NEXT_REVISION_NUMBER = "next-rev-num"; //$NON-NLS-1$ + public static final String ATTR_NUMBER_FORMAT = "number-format"; //$NON-NLS-1$ + public static final String ATTR_NUMBER_SEPARATOR = "number-separator"; //$NON-NLS-1$ + public static final String ATTR_NUMBER_DEPTH = "number-depth"; //$NON-NLS-1$ + public static final String ATTR_OBJECT_ID = "object-id"; //$NON-NLS-1$ + public static final String ATTR_OPACITY = "svg:opacity"; //$NON-NLS-1$ + public static final String ATTR_PREPENDING_NUMBERS = "prepending-numbers"; //$NON-NLS-1$ + public static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$ + public static final String ATTR_RANGE = "range"; //$NON-NLS-1$ + public static final String ATTR_RESOURCE = "resource"; //$NON-NLS-1$ + public static final String ATTR_RESOURCE_PATH = "resource-path"; //$NON-NLS-1$ + public static final String ATTR_SVG = "svg"; //$NON-NLS-1$ + public static final String ATTR_RESOURCE_ID = "resource-id"; //$NON-NLS-1$ + public static final String ATTR_RESOURCE_TYPE = "resource-type"; //$NON-NLS-1$ + public static final String ATTR_REVISION_NUMBER = "rev-num"; //$NON-NLS-1$ + public static final String ATTR_SALT = "salt"; //$NON-NLS-1$ + public static final String ATTR_KEY_IV = "iv"; //$NON-NLS-1$ + public static final String ATTR_KEY_SIZE = "size"; //$NON-NLS-1$ + public static final String ATTR_SHAPE_CLASS = "shape-class"; //$NON-NLS-1$ + public static final String ATTR_SHAPE_CORNER = "shape-corner"; //$NON-NLS-1$ + public static final String ATTR_SINGLETON = "singleton"; //$NON-NLS-1$ + public static final String ATTR_SPACING_MAJOR = "spacing-major"; //$NON-NLS-1$ + public static final String ATTR_SPACING_MINOR = "spacing-minor"; //$NON-NLS-1$ + public static final String ATTR_SRC = "xhtml:src"; //$NON-NLS-1$ + public static final String ATTR_STRUCTURE_CLASS = "structure-class"; //$NON-NLS-1$ + public static final String ATTR_STYLE_FAMILY = "style-family"; //$NON-NLS-1$ + public static final String ATTR_STYLE_ID = "style-id"; //$NON-NLS-1$ + public static final String ATTR_TEXT_ALIGN = "fo:text-align"; //$NON-NLS-1$ + public static final String ATTR_TEXT_BULLET = "fo:text-bullet"; //$NON-NLS-1$ + public static final String ATTR_TEXT_TRANSFORM = "fo:text-transform"; //$NON-NLS-1$ + public static final String ATTR_THEME = "theme"; //$NON-NLS-1$ + public static final String ATTR_TIME = "time"; //$NON-NLS-1$ + public static final String ATTR_TIMESTAMP = "timestamp"; //$NON-NLS-1$ + public static final String ATTR_TOPIC_ID = "topic-id"; //$NON-NLS-1$ + public static final String ATTR_TYPE = "type"; //$NON-NLS-1$ + public static final String ATTR_VERSION = "version"; //$NON-NLS-1$ + public static final String ATTR_VISIBILITY = "visibility"; //$NON-NLS-1$ + public static final String ATTR_WIDTH = "svg:width"; //$NON-NLS-1$ + public static final String ATTR_X = "svg:x"; //$NON-NLS-1$ + public static final String ATTR_Y = "svg:y"; //$NON-NLS-1$ + public static final String PASSWORD_HINT = "password-hint"; //$NON-NLS-1$ + + /* + * + */ + public static final String AUTHOR_EMAIL = "org.xmind.author.email"; //$NON-NLS-1$ + public static final String AUTHOR_NAME = "org.xmind.author.name"; //$NON-NLS-1$ + public static final String AUTHOR_ORG = "org.xmind.author.org"; //$NON-NLS-1$ + + @Deprecated + protected static final String EVENT_SUBTREE_MODIFIED = "DOMSubtreeModified"; //$NON-NLS-1$ + + // ========================= + // TAGS + // ------------------------- + public static final String TAG_A = "xhtml:a"; //$NON-NLS-1$ + public static final String TAG_ALGORITHM = "algorithm"; //$NON-NLS-1$ + public static final String TAG_ASSIGNEE = "assignee"; //$NON-NLS-1$ + public static final String TAG_ASSIGNEE_SHEET = "assignee-sheet"; //$NON-NLS-1$ + public static final String TAG_AUTOMATIC_STYLES = "automatic-styles"; //$NON-NLS-1$ + public static final String TAG_BOUNDARIES = "boundaries"; //$NON-NLS-1$ + public static final String TAG_BOUNDARY = "boundary"; //$NON-NLS-1$ + public static final String TAG_CHILDREN = "children"; //$NON-NLS-1$ + public static final String TAG_COMMENT = "comment"; //$NON-NLS-1$ + public static final String TAG_COMMENTS = "comments"; //$NON-NLS-1$ + public static final String TAG_CONTENT = "content"; //$NON-NLS-1$ + public static final String TAG_CONTROL_POINT = "control-point"; //$NON-NLS-1$ + public static final String TAG_CONTROL_POINTS = "control-points"; //$NON-NLS-1$ + public static final String TAG_DEFAULT_STYLE = "default-style"; //$NON-NLS-1$ + public static final String TAG_ENCRYPTION_DATA = "encryption-data"; //$NON-NLS-1$ + public static final String TAG_EXTENSION = "extension"; //$NON-NLS-1$ + public static final String TAG_EXTENSIONS = "extensions"; //$NON-NLS-1$ + public static final String TAG_FILE_ENTRY = "file-entry"; //$NON-NLS-1$ + public static final String TAG_IMG = "xhtml:img"; //$NON-NLS-1$ + public static final String TAG_INFO_ITEM = "info-item"; //$NON-NLS-1$ + public static final String TAG_INFO_ITEMS = "info-items"; //$NON-NLS-1$ + public static final String TAG_KEY_DERIVATION = "key-derivation"; //$NON-NLS-1$ + public static final String TAG_LABEL = "label"; //$NON-NLS-1$ + public static final String TAG_LABELS = "labels"; //$NON-NLS-1$ + public static final String TAG_LEGEND = "legend"; //$NON-NLS-1$ + public static final String TAG_MANIFEST = "manifest"; //$NON-NLS-1$ + public static final String TAG_MARKER = "marker"; //$NON-NLS-1$ + public static final String TAG_MARKER_DESCRIPTION = "marker-description"; //$NON-NLS-1$ + public static final String TAG_MARKER_DESCRIPTIONS = "marker-descriptions"; //$NON-NLS-1$ + public static final String TAG_MARKER_GROUP = "marker-group"; //$NON-NLS-1$ + public static final String TAG_MARKER_REF = "marker-ref"; //$NON-NLS-1$ + public static final String TAG_MARKER_REFS = "marker-refs"; //$NON-NLS-1$ + public static final String TAG_MARKER_SHEET = "marker-sheet"; //$NON-NLS-1$ + public static final String TAG_MASTER_STYLES = "master-styles"; //$NON-NLS-1$ + public static final String TAG_META = "meta"; //$NON-NLS-1$ + public static final String TAG_NOTES = "notes"; //$NON-NLS-1$ + public static final String TAG_NUMBERING = "numbering"; //$NON-NLS-1$ + public static final String TAG_P = "xhtml:p"; //$NON-NLS-1$ + public static final String TAG_POSITION = "position"; //$NON-NLS-1$ + public static final String TAG_PREFIX = "prefix"; //$NON-NLS-1$ + public static final String TAG_PROPERTIES = "properties"; //$NON-NLS-1$ + public static final String TAG_RELATIONSHIP = "relationship"; //$NON-NLS-1$ + public static final String TAG_RELATIONSHIPS = "relationships"; //$NON-NLS-1$ + public static final String TAG_RESOURCE_REF = "resource-ref"; //$NON-NLS-1$ + public static final String TAG_RESOURCE_REFS = "resource-refs"; //$NON-NLS-1$ + public static final String TAG_REVISION = "revision"; //$NON-NLS-1$ + public static final String TAG_REVISION_CONTENT = "xmap-revision-content"; //$NON-NLS-1$ + public static final String TAG_REVISIONS = "xmap-revisions"; //$NON-NLS-1$ + public static final String TAG_SEPARATOR = "separator"; //$NON-NLS-1$ + public static final String TAG_SHEET = "sheet"; //$NON-NLS-1$ + public static final String TAG_SHEET_SETTINGS = "sheet-settings"; //$NON-NLS-1$ + public static final String TAG_SPAN = "xhtml:span"; //$NON-NLS-1$ + public static final String TAG_STYLE = "style"; //$NON-NLS-1$ + public static final String TAG_STYLE_SHEET = "xmap-styles"; //$NON-NLS-1$ + public static final String TAG_STYLES = "styles"; //$NON-NLS-1$ + public static final String TAG_SUFFIX = "suffix"; //$NON-NLS-1$ + public static final String TAG_SUMMARIES = "summaries"; //$NON-NLS-1$ + public static final String TAG_SUMMARY = "summary"; //$NON-NLS-1$ + public static final String TAG_TITLE = "title"; //$NON-NLS-1$ + public static final String TAG_TOPIC = "topic"; //$NON-NLS-1$ + public static final String TAG_TOPICS = "topics"; //$NON-NLS-1$ + public static final String TAG_WORKBOOK = "xmap-content"; //$NON-NLS-1$ + public static final String TAG_STORIES = "stories"; //$NON-NLS-1$ + + // ================== + // VALUES + // ------------------ + public static final String VAL_BOLD = "bold"; //$NON-NLS-1$ + public static final String VAL_BOTTOM = "bottom"; //$NON-NLS-1$ + public static final String VAL_BULLET = "bullet"; //$NON-NLS-1$ + public static final String VAL_CAPITALIZE = "capitalize"; //$NON-NLS-1$ + public static final String VAL_CARDMODE = "card"; //$NON-NLS-1$ + public static final String VAL_CENTER = "center"; //$NON-NLS-1$ + public static final String VAL_DEFAULT = "default"; //$NON-NLS-1$ + public static final String VAL_FOLDED = "folded"; //$NON-NLS-1$ + public static final String VAL_GRADIENT = "gradient"; //$NON-NLS-1$ + public static final String VAL_HIDDEN = "hidden"; //$NON-NLS-1$ + public static final String VAL_ICONMODE = "icon"; //$NON-NLS-1$ + public static final String VAL_ITALIC = "italic"; //$NON-NLS-1$ + public static final String VAL_LEFT = "left"; //$NON-NLS-1$ + public static final String VAL_LINE_DASH = "dash"; //$NON-NLS-1$ + public static final String VAL_LINE_DASH_DOT = "dash-dot"; //$NON-NLS-1$ + public static final String VAL_LINE_DASH_DOT_DOT = "dash-dot-dot"; //$NON-NLS-1$ + public static final String VAL_LINE_DOT = "dot"; //$NON-NLS-1$ + public static final String VAL_LINE_SOLID = "solid"; //$NON-NLS-1$ + public static final String VAL_LINE_THROUGH = "line-through"; //$NON-NLS-1$ + public static final String VAL_LOWERCASE = "lowercase"; //$NON-NLS-1$ + public static final String VAL_MANUAL = "manual"; //$NON-NLS-1$ + public static final String VAL_MASTER = "master"; //$NON-NLS-1$ + public static final String VAL_NONE = "none"; //$NON-NLS-1$ + public static final String VAL_NORMAL = "normal"; //$NON-NLS-1$ + public static final String VAL_NUMBER = "number"; //$NON-NLS-1$ + public static final String VAL_RIGHT = "right"; //$NON-NLS-1$ + public static final String VAL_SYSTEM = "$system$"; //$NON-NLS-1$ + public static final String VAL_TAPERED = "tapered"; //$NON-NLS-1$ + public static final String VAL_TOP = "top"; //$NON-NLS-1$ + public static final String VAL_UNDERLINE = "underline"; //$NON-NLS-1$ + public static final String VAL_UPPERCASE = "uppercase"; //$NON-NLS-1$ + public static final String VAL_VISIBLE = "visible"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DeserializerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DeserializerImpl.java index 68ebbf1a6..2c9acbbdd 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DeserializerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/DeserializerImpl.java @@ -1,446 +1,446 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.zip.ArchiveConstants.COMMENTS_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IDeserializer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IMeta; -import org.xmind.core.IRevisionRepository; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtensionManager; -import org.xmind.core.internal.AbstractSerializingBase; -import org.xmind.core.internal.compatibility.Compatibility; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.CoreIOException; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; -import org.xmind.core.io.InvalidChecksumException; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.IProgressReporter; -import org.xml.sax.SAXException; - -/** - * @author Frank Shaka - * - */ -public class DeserializerImpl extends AbstractSerializingBase - implements IDeserializer { - - private WorkbookImpl workbook; - - private IStorage storage; - - private IInputSource inputSource; - - private InputStream inputStream; - - private boolean usesWorkbookStorageAsInputSource; - - private ManifestImpl manifest; - - private final Map loadedDocuments; - - /** - * - */ - public DeserializerImpl() { - super(); - this.workbook = null; - this.storage = new ByteArrayStorage(); - this.inputSource = null; - this.inputStream = null; - this.usesWorkbookStorageAsInputSource = false; - this.manifest = null; - this.loadedDocuments = new HashMap(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#getWorkbook() - */ - public IWorkbook getWorkbook() { - return workbook; - } - - protected void setWorkbook(WorkbookImpl workbook) { - this.workbook = workbook; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#setWorkbookStorage(org.xmind.core.io. - * IStorage) - */ - public void setWorkbookStorage(IStorage storage) { - if (storage == null) - throw new IllegalArgumentException("storage is null"); //$NON-NLS-1$ - this.storage = storage; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#getWorkbookStorage() - */ - public IStorage getWorkbookStorage() { - return this.storage; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#setInputSource(org.xmind.core.io. - * IInputSource) - */ - public void setInputSource(IInputSource source) { - if (source == null) - throw new IllegalArgumentException("input source is null"); //$NON-NLS-1$ - this.inputSource = source; - this.inputStream = null; - this.usesWorkbookStorageAsInputSource = false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#setInputStream(java.io.InputStream) - */ - public void setInputStream(InputStream stream) { - if (stream == null) - throw new IllegalArgumentException("input stream is null"); //$NON-NLS-1$ - this.inputStream = stream; - this.inputSource = null; - this.usesWorkbookStorageAsInputSource = false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#setWorkbookStorageAsInputSource() - */ - public void setWorkbookStorageAsInputSource() { - this.usesWorkbookStorageAsInputSource = true; - this.inputSource = null; - this.inputStream = null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#hasInputSource() - */ - public boolean hasInputSource() { - return inputSource != null || inputStream != null - || usesWorkbookStorageAsInputSource; - } - - public void deserializeManifest(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException { - if (inputStream != null) { - ZipInputStream zin = new ZipInputStream(inputStream); - try { - FileUtils.extractZipFile(zin, storage.getOutputTarget()); - } finally { - zin.close(); - } - } else if (inputSource != null) { - FileUtils.transfer(inputSource, storage.getOutputTarget()); - } else if (!usesWorkbookStorageAsInputSource) { - throw new IllegalStateException("no input source available"); //$NON-NLS-1$ - } - - /// load manifest.xml first to provide file entry info - Document manifestDoc = forceLoadDocumentFromEntry( - ArchiveConstants.MANIFEST_XML); - manifest = new ManifestImpl(manifestDoc, storage); - manifest.setStreamNormalizer(getEntryStreamNormalizer()); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#deserialize(org.xmind.core.util. - * IProgressReporter) - */ - public void deserialize(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException { - if (manifest == null) - deserializeManifest(reporter); - - /// Check if it's in old format - WorkbookImpl compatibleWorkbook = Compatibility - .loadCompatibleWorkbook(this); - if (compatibleWorkbook != null) { - setWorkbook(compatibleWorkbook); - return; - } - - try { - setWorkbook(loadWorkbook()); - } catch (InvalidChecksumException e) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } catch (CoreIOException e) { - CoreException ce = e.getCoreException(); - throw new CoreException(ce.getType(), ce.getCodeInfo(), e); - } - - } - - private WorkbookImpl loadWorkbook() throws IOException, CoreException { - /// load content.xml - Document workbookDoc = forceLoadDocumentFromEntry( - ArchiveConstants.CONTENT_XML); - WorkbookImpl workbook = new WorkbookImpl(workbookDoc, manifest); - - Document metaDoc = forceLoadDocumentFromEntry(META_XML); - MetaImpl meta = new MetaImpl(metaDoc); - workbook.setMeta(meta); - if (meta.getValue(IMeta.CREATED_TIME) == null) { - meta.setValue(IMeta.CREATED_TIME, - NumberUtils.formatDate(System.currentTimeMillis())); - } - meta.setValue(IMeta.CREATOR_NAME, getCreatorName()); - meta.setValue(IMeta.CREATOR_VERSION, getCreatorVersion()); - - /// load styles.xml - Document styleSheetDoc = loadDocumentFromEntry(STYLES_XML); - if (styleSheetDoc != null) { - StyleSheetImpl styleSheet = ((StyleSheetBuilderImpl) Core - .getStyleSheetBuilder()).createStyleSheet(styleSheetDoc); - styleSheet.setManifest(manifest); - workbook.setStyleSheet(styleSheet); - } - - /// load markers/markerSheet.xml - Document markerSheetDoc = loadDocumentFromEntry(PATH_MARKER_SHEET); - if (markerSheetDoc != null) { - MarkerSheetImpl markerSheet = ((MarkerSheetBuilderImpl) Core - .getMarkerSheetBuilder()).createMarkerSheet(markerSheetDoc, - new WorkbookMarkerResourceProvider(workbook)); - markerSheet.setManifest(manifest); - workbook.setMarkerSheet(markerSheet); - } - - /// load extensions - IWorkbookExtensionManager m = ((IWorkbook) workbook) - .getAdapter(IWorkbookExtensionManager.class); - if (m instanceof WorkbookExtensionManagerImpl) { - WorkbookExtensionManagerImpl extManager = (WorkbookExtensionManagerImpl) m; - for (String provider : extManager.getProviders()) { - Document extDoc = loadDocumentFromEntry(PATH_EXTENSIONS + // - provider + ".xml"); //$NON-NLS-1$ - if (extDoc != null) { - extManager.createExtension(provider, extDoc); - } - } - } - - /// load comments.xml - Document commentManagerDoc = loadDocumentFromEntry(COMMENTS_XML); - if (commentManagerDoc != null) { - CommentManagerImpl commentManager = new CommentManagerImpl(workbook, - commentManagerDoc); - workbook.setCommentManager(commentManager); - } - - /// initialize workbook content - for (ISheet sheet : workbook.getSheets()) { - ((SheetImpl) sheet).addNotify(workbook); - } - - IRevisionRepository revisionRepository = workbook - .getRevisionRepository(); - for (String resourceId : revisionRepository - .getRegisteredResourceIds()) { - revisionRepository.getRegisteredRevisionManager(resourceId); - } - - /// check all file entries for integrity - /// TODO FIXME do we really need this? - Iterator it = manifest.iterFileEntries(); - while (it.hasNext()) { - IFileEntry e = it.next(); - if (e.isDirectory() || !e.canRead()) - continue; - InputStream in = e.openInputStream(); - byte[] b = new byte[1024]; - while (in.read(b) != -1) { - /// do nothing - } - } - - return workbook; - } - - protected InputStream openEntryInputStream(String entryPath) - throws IOException, CoreException { - if (manifest == null && storage == null) - throw new IllegalStateException( - "No manifest or input source available"); //$NON-NLS-1$ - - if (manifest != null) { - IFileEntry entry = manifest.getFileEntry(entryPath); - if (entry != null) { - if (!entry.canRead()) - return null; - return entry.openInputStream(); - } - } - - if (storage != null) { - IInputSource source = storage.getInputSource(); - if (source != null && source.hasEntry(entryPath) - && source.isEntryAvailable(entryPath)) { - return source.openEntryStream(entryPath); - } - } - - return null; - } - - protected Document loadDocumentFromEntry(String entryPath) - throws IOException, CoreException { - Document cache = loadedDocuments.get(entryPath); - if (cache != null) - return cache; - - InputStream stream = openEntryInputStream(entryPath); - if (stream == null) - return null; - - Document document; - try { - document = loadDocumentFromStream(stream); - } catch (CoreIOException e) { - CoreException ce = e.getCoreException(); - throw new CoreException(ce.getType(), ce.getCodeInfo(), e); - } catch (IOException e) { - if (hasEncryptionData(entryPath)) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } - throw e; - } catch (CoreException e) { - if (e.getType() == Core.ERROR_CANCELLATION) - throw e; - if (hasEncryptionData(entryPath)) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } - throw e; - } catch (RuntimeException e) { - /// catching any runtime exception during xml parsing - if (hasEncryptionData(entryPath)) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } - throw e; - } catch (Error e) { - /// catching any error during xml parsing - if (hasEncryptionData(entryPath)) { - throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); - } - throw e; - } finally { - if (stream != null) - stream.close(); - } - - if (document != null) { - loadedDocuments.put(entryPath, document); - } - return document; - } - - protected Document loadDocumentFromStream(InputStream stream) - throws IOException, CoreException { - try { - DocumentBuilder builder; - try { - builder = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); - } - return builder.parse(stream); - } catch (SAXException e) { - throw new CoreException(Core.ERROR_FAIL_PARSING_XML, e); - } finally { - stream.close(); - } - } - - protected Document createDocument() throws CoreException { - DocumentBuilder builder; - try { - builder = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); - } - - return builder.newDocument(); - } - - protected Document forceLoadDocumentFromEntry(String entryPath) - throws CoreException { - Document document; - try { - document = loadDocumentFromEntry(entryPath); - } catch (IOException e) { - document = null; - } - - if (document == null) { - document = createDocument(); - loadedDocuments.put(entryPath, document); - } - return document; - } - - public ManifestImpl getManifest() { - return manifest; - } - - private boolean hasEncryptionData(String entryPath) { - if (manifest != null) { - IFileEntry entry = manifest.getFileEntry(entryPath); - return entry != null && entry.getEncryptionData() != null; - } - return false; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.zip.ArchiveConstants.COMMENTS_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IDeserializer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IMeta; +import org.xmind.core.IRevisionRepository; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtensionManager; +import org.xmind.core.internal.AbstractSerializingBase; +import org.xmind.core.internal.compatibility.Compatibility; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.CoreIOException; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; +import org.xmind.core.io.InvalidChecksumException; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.IProgressReporter; +import org.xml.sax.SAXException; + +/** + * @author Frank Shaka + * + */ +public class DeserializerImpl extends AbstractSerializingBase + implements IDeserializer { + + private WorkbookImpl workbook; + + private IStorage storage; + + private IInputSource inputSource; + + private InputStream inputStream; + + private boolean usesWorkbookStorageAsInputSource; + + private ManifestImpl manifest; + + private final Map loadedDocuments; + + /** + * + */ + public DeserializerImpl() { + super(); + this.workbook = null; + this.storage = new ByteArrayStorage(); + this.inputSource = null; + this.inputStream = null; + this.usesWorkbookStorageAsInputSource = false; + this.manifest = null; + this.loadedDocuments = new HashMap(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#getWorkbook() + */ + public IWorkbook getWorkbook() { + return workbook; + } + + protected void setWorkbook(WorkbookImpl workbook) { + this.workbook = workbook; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#setWorkbookStorage(org.xmind.core.io. + * IStorage) + */ + public void setWorkbookStorage(IStorage storage) { + if (storage == null) + throw new IllegalArgumentException("storage is null"); //$NON-NLS-1$ + this.storage = storage; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#getWorkbookStorage() + */ + public IStorage getWorkbookStorage() { + return this.storage; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#setInputSource(org.xmind.core.io. + * IInputSource) + */ + public void setInputSource(IInputSource source) { + if (source == null) + throw new IllegalArgumentException("input source is null"); //$NON-NLS-1$ + this.inputSource = source; + this.inputStream = null; + this.usesWorkbookStorageAsInputSource = false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#setInputStream(java.io.InputStream) + */ + public void setInputStream(InputStream stream) { + if (stream == null) + throw new IllegalArgumentException("input stream is null"); //$NON-NLS-1$ + this.inputStream = stream; + this.inputSource = null; + this.usesWorkbookStorageAsInputSource = false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#setWorkbookStorageAsInputSource() + */ + public void setWorkbookStorageAsInputSource() { + this.usesWorkbookStorageAsInputSource = true; + this.inputSource = null; + this.inputStream = null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#hasInputSource() + */ + public boolean hasInputSource() { + return inputSource != null || inputStream != null + || usesWorkbookStorageAsInputSource; + } + + public void deserializeManifest(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException { + if (inputStream != null) { + ZipInputStream zin = new ZipInputStream(inputStream); + try { + FileUtils.extractZipFile(zin, storage.getOutputTarget()); + } finally { + zin.close(); + } + } else if (inputSource != null) { + FileUtils.transfer(inputSource, storage.getOutputTarget()); + } else if (!usesWorkbookStorageAsInputSource) { + throw new IllegalStateException("no input source available"); //$NON-NLS-1$ + } + + /// load manifest.xml first to provide file entry info + Document manifestDoc = forceLoadDocumentFromEntry( + ArchiveConstants.MANIFEST_XML); + manifest = new ManifestImpl(manifestDoc, storage); + manifest.setStreamNormalizer(getEntryStreamNormalizer()); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IDeserializer#deserialize(org.xmind.core.util. + * IProgressReporter) + */ + public void deserialize(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException { + if (manifest == null) + deserializeManifest(reporter); + + /// Check if it's in old format + WorkbookImpl compatibleWorkbook = Compatibility + .loadCompatibleWorkbook(this); + if (compatibleWorkbook != null) { + setWorkbook(compatibleWorkbook); + return; + } + + try { + setWorkbook(loadWorkbook()); + } catch (InvalidChecksumException e) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } catch (CoreIOException e) { + CoreException ce = e.getCoreException(); + throw new CoreException(ce.getType(), ce.getCodeInfo(), e); + } + + } + + private WorkbookImpl loadWorkbook() throws IOException, CoreException { + /// load content.xml + Document workbookDoc = forceLoadDocumentFromEntry( + ArchiveConstants.CONTENT_XML); + WorkbookImpl workbook = new WorkbookImpl(workbookDoc, manifest); + + Document metaDoc = forceLoadDocumentFromEntry(META_XML); + MetaImpl meta = new MetaImpl(metaDoc); + workbook.setMeta(meta); + if (meta.getValue(IMeta.CREATED_TIME) == null) { + meta.setValue(IMeta.CREATED_TIME, + NumberUtils.formatDate(System.currentTimeMillis())); + } + meta.setValue(IMeta.CREATOR_NAME, getCreatorName()); + meta.setValue(IMeta.CREATOR_VERSION, getCreatorVersion()); + + /// load styles.xml + Document styleSheetDoc = loadDocumentFromEntry(STYLES_XML); + if (styleSheetDoc != null) { + StyleSheetImpl styleSheet = ((StyleSheetBuilderImpl) Core + .getStyleSheetBuilder()).createStyleSheet(styleSheetDoc); + styleSheet.setManifest(manifest); + workbook.setStyleSheet(styleSheet); + } + + /// load markers/markerSheet.xml + Document markerSheetDoc = loadDocumentFromEntry(PATH_MARKER_SHEET); + if (markerSheetDoc != null) { + MarkerSheetImpl markerSheet = ((MarkerSheetBuilderImpl) Core + .getMarkerSheetBuilder()).createMarkerSheet(markerSheetDoc, + new WorkbookMarkerResourceProvider(workbook)); + markerSheet.setManifest(manifest); + workbook.setMarkerSheet(markerSheet); + } + + /// load extensions + IWorkbookExtensionManager m = ((IWorkbook) workbook) + .getAdapter(IWorkbookExtensionManager.class); + if (m instanceof WorkbookExtensionManagerImpl) { + WorkbookExtensionManagerImpl extManager = (WorkbookExtensionManagerImpl) m; + for (String provider : extManager.getProviders()) { + Document extDoc = loadDocumentFromEntry(PATH_EXTENSIONS + // + provider + ".xml"); //$NON-NLS-1$ + if (extDoc != null) { + extManager.createExtension(provider, extDoc); + } + } + } + + /// load comments.xml + Document commentManagerDoc = loadDocumentFromEntry(COMMENTS_XML); + if (commentManagerDoc != null) { + CommentManagerImpl commentManager = new CommentManagerImpl(workbook, + commentManagerDoc); + workbook.setCommentManager(commentManager); + } + + /// initialize workbook content + for (ISheet sheet : workbook.getSheets()) { + ((SheetImpl) sheet).addNotify(workbook); + } + + IRevisionRepository revisionRepository = workbook + .getRevisionRepository(); + for (String resourceId : revisionRepository + .getRegisteredResourceIds()) { + revisionRepository.getRegisteredRevisionManager(resourceId); + } + + /// check all file entries for integrity + /// TODO FIXME do we really need this? + Iterator it = manifest.iterFileEntries(); + while (it.hasNext()) { + IFileEntry e = it.next(); + if (e.isDirectory() || !e.canRead()) + continue; + InputStream in = e.openInputStream(); + byte[] b = new byte[1024]; + while (in.read(b) != -1) { + /// do nothing + } + } + + return workbook; + } + + protected InputStream openEntryInputStream(String entryPath) + throws IOException, CoreException { + if (manifest == null && storage == null) + throw new IllegalStateException( + "No manifest or input source available"); //$NON-NLS-1$ + + if (manifest != null) { + IFileEntry entry = manifest.getFileEntry(entryPath); + if (entry != null) { + if (!entry.canRead()) + return null; + return entry.openInputStream(); + } + } + + if (storage != null) { + IInputSource source = storage.getInputSource(); + if (source != null && source.hasEntry(entryPath) + && source.isEntryAvailable(entryPath)) { + return source.openEntryStream(entryPath); + } + } + + return null; + } + + protected Document loadDocumentFromEntry(String entryPath) + throws IOException, CoreException { + Document cache = loadedDocuments.get(entryPath); + if (cache != null) + return cache; + + InputStream stream = openEntryInputStream(entryPath); + if (stream == null) + return null; + + Document document; + try { + document = loadDocumentFromStream(stream); + } catch (CoreIOException e) { + CoreException ce = e.getCoreException(); + throw new CoreException(ce.getType(), ce.getCodeInfo(), e); + } catch (IOException e) { + if (hasEncryptionData(entryPath)) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } + throw e; + } catch (CoreException e) { + if (e.getType() == Core.ERROR_CANCELLATION) + throw e; + if (hasEncryptionData(entryPath)) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } + throw e; + } catch (RuntimeException e) { + /// catching any runtime exception during xml parsing + if (hasEncryptionData(entryPath)) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } + throw e; + } catch (Error e) { + /// catching any error during xml parsing + if (hasEncryptionData(entryPath)) { + throw new CoreException(Core.ERROR_WRONG_PASSWORD, e); + } + throw e; + } finally { + if (stream != null) + stream.close(); + } + + if (document != null) { + loadedDocuments.put(entryPath, document); + } + return document; + } + + protected Document loadDocumentFromStream(InputStream stream) + throws IOException, CoreException { + try { + DocumentBuilder builder; + try { + builder = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); + } + return builder.parse(stream); + } catch (SAXException e) { + throw new CoreException(Core.ERROR_FAIL_PARSING_XML, e); + } finally { + stream.close(); + } + } + + protected Document createDocument() throws CoreException { + DocumentBuilder builder; + try { + builder = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); + } + + return builder.newDocument(); + } + + protected Document forceLoadDocumentFromEntry(String entryPath) + throws CoreException { + Document document; + try { + document = loadDocumentFromEntry(entryPath); + } catch (IOException e) { + document = null; + } + + if (document == null) { + document = createDocument(); + loadedDocuments.put(entryPath, document); + } + return document; + } + + public ManifestImpl getManifest() { + return manifest; + } + + private boolean hasEncryptionData(String entryPath) { + if (manifest != null) { + IFileEntry entry = manifest.getFileEntry(entryPath); + return entry != null && entry.getEncryptionData() != null; + } + return false; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/EncryptionDataImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/EncryptionDataImpl.java index 45d3acfff..01ec2ab49 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/EncryptionDataImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/EncryptionDataImpl.java @@ -1,158 +1,158 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_CHECKSUM; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_CHECKSUM_TYPE; - -import org.w3c.dom.Element; -import org.xmind.core.IFileEntry; -import org.xmind.core.internal.EncryptionData; -import org.xmind.core.util.DOMUtils; - -/** - * @author frankshaka - */ -public class EncryptionDataImpl extends EncryptionData { - - private Element implementation; - - private FileEntryImpl entry; - - /** - * @param implementation - * @param manifest - */ - public EncryptionDataImpl(Element implementation, FileEntryImpl entry) { - super(); - this.implementation = implementation; - this.entry = entry; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.internal.EncryptionData#getAdapter(java.lang.Class) - */ - @Override - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getImplementation()); - return super.getAdapter(adapter); - } - - /** - * @return the implementation - */ - public Element getImplementation() { - return implementation; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#getIntAttribute(int, - * java.lang.String[]) - */ - public int getIntAttribute(int defaultValue, String... keyPath) { - String value = getAttribute(keyPath); - if (value != null) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException ignore) { - } - } - return defaultValue; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#getAttribute(java.lang.String) - */ - public String getAttribute(String... keys) { - if (keys.length > 0) { - Element ele = implementation; - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - if (i == keys.length - 1) { - return DOMUtils.getAttribute(ele, key); - } - ele = DOMUtils.getFirstChildElementByTag(ele, key); - } - } - return null; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#setAttribute(java.lang.String, - * java.lang.String) - */ - public void setAttribute(String value, String... keys) { - if (keys.length > 0) { - Element ele = implementation; - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - if (i == keys.length - 1) { - DOMUtils.setAttribute(ele, key, value); - } - Element ele2 = DOMUtils.getFirstChildElementByTag(ele, key); - if (ele2 == null) { - ele = DOMUtils.createElement(ele, key); - } else { - ele = ele2; - } - } - } - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#getChecksum() - */ - public String getChecksum() { - return getAttribute(ATTR_CHECKSUM); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#getChecksumType() - */ - public String getChecksumType() { - return getAttribute(ATTR_CHECKSUM_TYPE); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#setChecksum(java.lang.String) - */ - public void setChecksum(String checksum) { - setAttribute(checksum, ATTR_CHECKSUM); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#setChecksumType(java.lang.String) - */ - public void setChecksumType(String checksumType) { - setAttribute(checksumType, ATTR_CHECKSUM_TYPE); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IEncryptionData#getFileEntry() - */ - public IFileEntry getFileEntry() { - return entry; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_CHECKSUM; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_CHECKSUM_TYPE; + +import org.w3c.dom.Element; +import org.xmind.core.IFileEntry; +import org.xmind.core.internal.EncryptionData; +import org.xmind.core.util.DOMUtils; + +/** + * @author frankshaka + */ +public class EncryptionDataImpl extends EncryptionData { + + private Element implementation; + + private FileEntryImpl entry; + + /** + * @param implementation + * @param manifest + */ + public EncryptionDataImpl(Element implementation, FileEntryImpl entry) { + super(); + this.implementation = implementation; + this.entry = entry; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.internal.EncryptionData#getAdapter(java.lang.Class) + */ + @Override + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); + return super.getAdapter(adapter); + } + + /** + * @return the implementation + */ + public Element getImplementation() { + return implementation; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#getIntAttribute(int, + * java.lang.String[]) + */ + public int getIntAttribute(int defaultValue, String... keyPath) { + String value = getAttribute(keyPath); + if (value != null) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException ignore) { + } + } + return defaultValue; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#getAttribute(java.lang.String) + */ + public String getAttribute(String... keys) { + if (keys.length > 0) { + Element ele = implementation; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (i == keys.length - 1) { + return DOMUtils.getAttribute(ele, key); + } + ele = DOMUtils.getFirstChildElementByTag(ele, key); + } + } + return null; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#setAttribute(java.lang.String, + * java.lang.String) + */ + public void setAttribute(String value, String... keys) { + if (keys.length > 0) { + Element ele = implementation; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (i == keys.length - 1) { + DOMUtils.setAttribute(ele, key, value); + } + Element ele2 = DOMUtils.getFirstChildElementByTag(ele, key); + if (ele2 == null) { + ele = DOMUtils.createElement(ele, key); + } else { + ele = ele2; + } + } + } + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#getChecksum() + */ + public String getChecksum() { + return getAttribute(ATTR_CHECKSUM); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#getChecksumType() + */ + public String getChecksumType() { + return getAttribute(ATTR_CHECKSUM_TYPE); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#setChecksum(java.lang.String) + */ + public void setChecksum(String checksum) { + setAttribute(checksum, ATTR_CHECKSUM); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#setChecksumType(java.lang.String) + */ + public void setChecksumType(String checksumType) { + setAttribute(checksumType, ATTR_CHECKSUM_TYPE); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IEncryptionData#getFileEntry() + */ + public IFileEntry getFileEntry() { + return entry; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileEntryImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileEntryImpl.java index 096da07f0..e468b91c9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileEntryImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileEntryImpl.java @@ -1,340 +1,340 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_FULL_PATH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_ENCRYPTION_DATA; -import static org.xmind.core.internal.dom.InternalDOMUtils.getParentPath; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; - -import org.w3c.dom.Element; -import org.xmind.core.CoreException; -import org.xmind.core.IEncryptionData; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IFileEntryFilter; -import org.xmind.core.IManifest; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.FileEntry; -import org.xmind.core.io.CoreIOException; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.DOMUtils; - -public class FileEntryImpl extends FileEntry { - - private Element implementation; - - private ManifestImpl ownedManifest; - - private Integer refCount = null; - - private EncryptionDataImpl encData; - - private boolean ignoreEncryption = false; - - public FileEntryImpl(Element implementation, ManifestImpl ownedManifest) { - this.implementation = implementation; - this.ownedManifest = ownedManifest; - } - - public Element getImplementation() { - return implementation; - } - - public String getMediaType() { - return implementation.getAttribute(ATTR_MEDIA_TYPE); - } - - public IManifest getOwnedManifest() { - return ownedManifest; - } - - public String getPath() { - return implementation.getAttribute(ATTR_FULL_PATH); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof FileEntryImpl)) - return false; - FileEntryImpl that = (FileEntryImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return DOMUtils.toString(implementation); - } - - public int getReferenceCount() { - return refCount == null ? 0 : refCount.intValue(); - } - - public boolean hasBeenReferred() { - return refCount != null; - } - - public void increaseReference() { - int c = getReferenceCount(); - refCount = Integer.valueOf(c + 1); - if (c <= 0) { - ownedManifest.insertFileEntry(this); - } - String parent = getParentPath(getPath()); - if (parent != null) { - IFileEntry parentEntry = ownedManifest.getFileEntry(parent); - if (parentEntry != null) - parentEntry.increaseReference(); - } - } - - public void decreaseReference() { - if (refCount == null) - return; - int c = refCount.intValue(); - c--; - refCount = Integer.valueOf(c); - if (c <= 0) { - ownedManifest.removeFileEntry(this); - } - String parent = getParentPath(getPath()); - if (parent != null) { - IFileEntry parentEntry = ownedManifest.getFileEntry(parent); - if (parentEntry != null) - parentEntry.decreaseReference(); - } - } - - private IStorage getStorage() { - return ownedManifest.getStorage(); - } - - @Deprecated - public InputStream getInputStream() { - if (isDirectory()) - return null; - IStorage storage = getStorage(); - if (storage != null) { - String path = getPath(); - return storage.getInputSource().getEntryStream(path); - } - return null; - } - - @Deprecated - public OutputStream getOutputStream() { - if (isDirectory()) - return null; - IStorage storage = getStorage(); - if (storage != null) { - return storage.getOutputTarget().getEntryStream(getPath()); - } - return null; - } - - public boolean canRead() { - IStorage storage = getStorage(); - if (storage != null) { - IInputSource source = storage.getInputSource(); - return source.hasEntry(getPath()) - && source.isEntryAvailable(getPath()); - } - return false; - } - - public boolean canWrite() { - IStorage storage = getStorage(); - if (storage != null) { - return storage.getOutputTarget().isEntryAvaialble(getPath()); - } - return false; - } - - public InputStream openInputStream() throws IOException { - if (isDirectory()) - throw new FileNotFoundException(getPath()); - IStorage storage = getStorage(); - if (storage == null) - throw new FileNotFoundException(getPath()); - - IInputSource inputSource = storage.getInputSource(); - if (!inputSource.hasEntry(getPath())) - throw new FileNotFoundException(getPath()); - - InputStream stream = inputSource.openEntryStream(getPath()); - IEntryStreamNormalizer encryptionHandler = ownedManifest - .getStreamNormalizer(); - if (!isIgnoreEncryption() && encryptionHandler != null) { - try { - stream = encryptionHandler.normalizeInputStream(stream, this); - } catch (CoreException e) { - throw new CoreIOException(e); - } - } - return stream; - } - - public OutputStream openOutputStream() throws IOException { - if (isDirectory()) - throw new FileNotFoundException(getPath()); - IStorage storage = getStorage(); - if (storage == null) - throw new FileNotFoundException(getPath()); - OutputStream stream = storage.getOutputTarget() - .openEntryStream(getPath()); - IEntryStreamNormalizer encryptionHandler = ownedManifest - .getStreamNormalizer(); - if (!isIgnoreEncryption() && encryptionHandler != null) { - try { - stream = encryptionHandler.normalizeOutputStream(stream, this); - } catch (CoreException e) { - throw new CoreIOException(e); - } - } - return stream; - } - - public long getTime() { - IStorage storage = getStorage(); - if (storage != null) - return storage.getInputSource().getEntryTime(getPath()); - return -1; - } - - public void setTime(long time) { - IStorage storage = getStorage(); - if (storage != null) { - storage.getOutputTarget().setEntryTime(getPath(), time); - } - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IFileEntry#iterSubEntries() - */ - public Iterator iterSubEntries() { - final String parentPath = getPath(); - return ownedManifest.iterFileEntries(new IFileEntryFilter() { - public boolean select(String path, String mediaType, - boolean isDirectory) { - return path.length() > parentPath.length() - && path.startsWith(parentPath); - } - }); - } - - public boolean isDirectory() { - return getPath().endsWith("/"); //$NON-NLS-1$ - } - - public long getSize() { - IStorage storage = getStorage(); - if (storage != null) { - return storage.getInputSource().getEntrySize(getPath()); - } - return -1; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IFileEntry#getEncryptionData() - */ - public IEncryptionData getEncryptionData() { - Element encEle = DOMUtils.getFirstChildElementByTag(implementation, - TAG_ENCRYPTION_DATA); - if (encEle == null) { - if (encData != null) { - encData = null; - } - } else { - if (encData == null) { - encData = new EncryptionDataImpl(encEle, this); - } - } - return encData; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IFileEntry#createEncryptionData() - */ - public IEncryptionData createEncryptionData() { - IEncryptionData ed = getEncryptionData(); - if (ed != null) - return ed; - - Element encEle = DOMUtils.createElement(implementation, - TAG_ENCRYPTION_DATA); - encData = new EncryptionDataImpl(encEle, this); - return encData; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IFileEntry#deleteEncryptionData() - */ - public void deleteEncryptionData() { - getEncryptionData(); - if (encData != null) { - Element encEle = encData.getImplementation(); - if (encEle != null && encEle.getParentNode() == implementation) { - implementation.removeChild(encEle); - } - encData = null; - } - } - - /** - * @param ignoreEncryption - * the ignoreEncryption to set - * @deprecated - */ - public void setIgnoreEncryption(boolean ignoreEncryption) { - this.ignoreEncryption = ignoreEncryption; - } - - /** - * @return the ignoreEncryption - * @deprecated - */ - public boolean isIgnoreEncryption() { - return ignoreEncryption; - } - - public IWorkbook getOwnedWorkbook() { - return ownedManifest.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(getImplementation()); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_FULL_PATH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_ENCRYPTION_DATA; +import static org.xmind.core.internal.dom.InternalDOMUtils.getParentPath; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; + +import org.w3c.dom.Element; +import org.xmind.core.CoreException; +import org.xmind.core.IEncryptionData; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IFileEntryFilter; +import org.xmind.core.IManifest; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.FileEntry; +import org.xmind.core.io.CoreIOException; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.DOMUtils; + +public class FileEntryImpl extends FileEntry { + + private Element implementation; + + private ManifestImpl ownedManifest; + + private Integer refCount = null; + + private EncryptionDataImpl encData; + + private boolean ignoreEncryption = false; + + public FileEntryImpl(Element implementation, ManifestImpl ownedManifest) { + this.implementation = implementation; + this.ownedManifest = ownedManifest; + } + + public Element getImplementation() { + return implementation; + } + + public String getMediaType() { + return implementation.getAttribute(ATTR_MEDIA_TYPE); + } + + public IManifest getOwnedManifest() { + return ownedManifest; + } + + public String getPath() { + return implementation.getAttribute(ATTR_FULL_PATH); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof FileEntryImpl)) + return false; + FileEntryImpl that = (FileEntryImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return DOMUtils.toString(implementation); + } + + public int getReferenceCount() { + return refCount == null ? 0 : refCount.intValue(); + } + + public boolean hasBeenReferred() { + return refCount != null; + } + + public void increaseReference() { + int c = getReferenceCount(); + refCount = Integer.valueOf(c + 1); + if (c <= 0) { + ownedManifest.insertFileEntry(this); + } + String parent = getParentPath(getPath()); + if (parent != null) { + IFileEntry parentEntry = ownedManifest.getFileEntry(parent); + if (parentEntry != null) + parentEntry.increaseReference(); + } + } + + public void decreaseReference() { + if (refCount == null) + return; + int c = refCount.intValue(); + c--; + refCount = Integer.valueOf(c); + if (c <= 0) { + ownedManifest.removeFileEntry(this); + } + String parent = getParentPath(getPath()); + if (parent != null) { + IFileEntry parentEntry = ownedManifest.getFileEntry(parent); + if (parentEntry != null) + parentEntry.decreaseReference(); + } + } + + private IStorage getStorage() { + return ownedManifest.getStorage(); + } + + @Deprecated + public InputStream getInputStream() { + if (isDirectory()) + return null; + IStorage storage = getStorage(); + if (storage != null) { + String path = getPath(); + return storage.getInputSource().getEntryStream(path); + } + return null; + } + + @Deprecated + public OutputStream getOutputStream() { + if (isDirectory()) + return null; + IStorage storage = getStorage(); + if (storage != null) { + return storage.getOutputTarget().getEntryStream(getPath()); + } + return null; + } + + public boolean canRead() { + IStorage storage = getStorage(); + if (storage != null) { + IInputSource source = storage.getInputSource(); + return source.hasEntry(getPath()) + && source.isEntryAvailable(getPath()); + } + return false; + } + + public boolean canWrite() { + IStorage storage = getStorage(); + if (storage != null) { + return storage.getOutputTarget().isEntryAvaialble(getPath()); + } + return false; + } + + public InputStream openInputStream() throws IOException { + if (isDirectory()) + throw new FileNotFoundException(getPath()); + IStorage storage = getStorage(); + if (storage == null) + throw new FileNotFoundException(getPath()); + + IInputSource inputSource = storage.getInputSource(); + if (!inputSource.hasEntry(getPath())) + throw new FileNotFoundException(getPath()); + + InputStream stream = inputSource.openEntryStream(getPath()); + IEntryStreamNormalizer encryptionHandler = ownedManifest + .getStreamNormalizer(); + if (!isIgnoreEncryption() && encryptionHandler != null) { + try { + stream = encryptionHandler.normalizeInputStream(stream, this); + } catch (CoreException e) { + throw new CoreIOException(e); + } + } + return stream; + } + + public OutputStream openOutputStream() throws IOException { + if (isDirectory()) + throw new FileNotFoundException(getPath()); + IStorage storage = getStorage(); + if (storage == null) + throw new FileNotFoundException(getPath()); + OutputStream stream = storage.getOutputTarget() + .openEntryStream(getPath()); + IEntryStreamNormalizer encryptionHandler = ownedManifest + .getStreamNormalizer(); + if (!isIgnoreEncryption() && encryptionHandler != null) { + try { + stream = encryptionHandler.normalizeOutputStream(stream, this); + } catch (CoreException e) { + throw new CoreIOException(e); + } + } + return stream; + } + + public long getTime() { + IStorage storage = getStorage(); + if (storage != null) + return storage.getInputSource().getEntryTime(getPath()); + return -1; + } + + public void setTime(long time) { + IStorage storage = getStorage(); + if (storage != null) { + storage.getOutputTarget().setEntryTime(getPath(), time); + } + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IFileEntry#iterSubEntries() + */ + public Iterator iterSubEntries() { + final String parentPath = getPath(); + return ownedManifest.iterFileEntries(new IFileEntryFilter() { + public boolean select(String path, String mediaType, + boolean isDirectory) { + return path.length() > parentPath.length() + && path.startsWith(parentPath); + } + }); + } + + public boolean isDirectory() { + return getPath().endsWith("/"); //$NON-NLS-1$ + } + + public long getSize() { + IStorage storage = getStorage(); + if (storage != null) { + return storage.getInputSource().getEntrySize(getPath()); + } + return -1; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IFileEntry#getEncryptionData() + */ + public IEncryptionData getEncryptionData() { + Element encEle = DOMUtils.getFirstChildElementByTag(implementation, + TAG_ENCRYPTION_DATA); + if (encEle == null) { + if (encData != null) { + encData = null; + } + } else { + if (encData == null) { + encData = new EncryptionDataImpl(encEle, this); + } + } + return encData; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IFileEntry#createEncryptionData() + */ + public IEncryptionData createEncryptionData() { + IEncryptionData ed = getEncryptionData(); + if (ed != null) + return ed; + + Element encEle = DOMUtils.createElement(implementation, + TAG_ENCRYPTION_DATA); + encData = new EncryptionDataImpl(encEle, this); + return encData; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IFileEntry#deleteEncryptionData() + */ + public void deleteEncryptionData() { + getEncryptionData(); + if (encData != null) { + Element encEle = encData.getImplementation(); + if (encEle != null && encEle.getParentNode() == implementation) { + implementation.removeChild(encEle); + } + encData = null; + } + } + + /** + * @param ignoreEncryption + * the ignoreEncryption to set + * @deprecated + */ + public void setIgnoreEncryption(boolean ignoreEncryption) { + this.ignoreEncryption = ignoreEncryption; + } + + /** + * @return the ignoreEncryption + * @deprecated + */ + public boolean isIgnoreEncryption() { + return ignoreEncryption; + } + + public IWorkbook getOwnedWorkbook() { + return ownedManifest.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(getImplementation()); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_0_1.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_0_1.java index 0119d7e75..996aeb2ee 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_0_1.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_0_1.java @@ -1,54 +1,54 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; - -import java.io.IOException; - -import org.xmind.core.CoreException; -import org.xmind.core.internal.compatibility.FileFormat; -import org.xmind.core.io.IInputSource; -import org.xmind.core.util.DOMUtils; - -public class FileFormat_0_1 extends FileFormat { - - private static final String VERSION = "0.1"; //$NON-NLS-1$ - - private static final String CONTENTS_XML = "contents.xml"; //$NON-NLS-1$ - -// private static final String PATH_PICTURES = "Pictures"; //$NON-NLS-1$ - - public FileFormat_0_1(DeserializerImpl deserializer) { - super(deserializer); - } - - public boolean identifies() throws CoreException, IOException { - IInputSource inputSource = deserializer.getWorkbookStorage() - .getInputSource(); - return inputSource.hasEntry(CONTENTS_XML) - && inputSource.isEntryAvailable(CONTENTS_XML); - } - - public WorkbookImpl load() throws CoreException, IOException { - WorkbookImpl wb = new WorkbookImpl(deserializer.createDocument(), - deserializer.getManifest()); - DOMUtils.setAttribute(wb.getWorkbookElement(), ATTR_VERSION, VERSION); - - //TODO load workbook content from old-formatted file - - return wb; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; + +import java.io.IOException; + +import org.xmind.core.CoreException; +import org.xmind.core.internal.compatibility.FileFormat; +import org.xmind.core.io.IInputSource; +import org.xmind.core.util.DOMUtils; + +public class FileFormat_0_1 extends FileFormat { + + private static final String VERSION = "0.1"; //$NON-NLS-1$ + + private static final String CONTENTS_XML = "contents.xml"; //$NON-NLS-1$ + +// private static final String PATH_PICTURES = "Pictures"; //$NON-NLS-1$ + + public FileFormat_0_1(DeserializerImpl deserializer) { + super(deserializer); + } + + public boolean identifies() throws CoreException, IOException { + IInputSource inputSource = deserializer.getWorkbookStorage() + .getInputSource(); + return inputSource.hasEntry(CONTENTS_XML) + && inputSource.isEntryAvailable(CONTENTS_XML); + } + + public WorkbookImpl load() throws CoreException, IOException { + WorkbookImpl wb = new WorkbookImpl(deserializer.createDocument(), + deserializer.getManifest()); + DOMUtils.setAttribute(wb.getWorkbookElement(), ATTR_VERSION, VERSION); + + //TODO load workbook content from old-formatted file + + return wb; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_1.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_1.java index 3a288f96d..72b7ffa54 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_1.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/FileFormat_1.java @@ -1,831 +1,831 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALIGN; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HEIGHT; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HREF; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_LINE_TAPERED; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_MULTI_LINE_COLORS; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_FORMAT; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_SEPARATOR; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STRUCTURE_CLASS; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_FAMILY; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_THEME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_X; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_Y; -import static org.xmind.core.internal.dom.DOMConstants.TAG_A; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; -import static org.xmind.core.internal.dom.DOMConstants.TAG_LABEL; -import static org.xmind.core.internal.dom.DOMConstants.TAG_LABELS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; -import static org.xmind.core.internal.dom.DOMConstants.TAG_NOTES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_NUMBERING; -import static org.xmind.core.internal.dom.DOMConstants.TAG_POSITION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_PREFIX; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUFFIX; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; -import static org.xmind.core.internal.dom.DOMConstants.VAL_NONE; -import static org.xmind.core.internal.dom.DOMConstants.VAL_TAPERED; -import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IBoundary; -import org.xmind.core.IFileEntry; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IHyperlinkSpan; -import org.xmind.core.IImage; -import org.xmind.core.IImageSpan; -import org.xmind.core.IManifest; -import org.xmind.core.INotes; -import org.xmind.core.INumbering; -import org.xmind.core.IParagraph; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISpanList; -import org.xmind.core.ITextSpan; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.compatibility.FileFormat; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.HyperlinkUtils; - -public class FileFormat_1 extends FileFormat { - - private static final String VERSION = "1.0"; //$NON-NLS-1$ - - private static final String TAG_MAP = "map"; //$NON-NLS-1$ - private static final String TAG_ROOT_TOPIC = "root-topic"; //$NON-NLS-1$ - private static final String TAG_MARKERS = "markers"; //$NON-NLS-1$ - private static final String TAG_ATTACHED_TOPICS = "attached-topics"; //$NON-NLS-1$ - private static final String TAG_DETACHED_TOPICS = "detached-topics"; //$NON-NLS-1$ - private static final String TAG_PLAIN = "plain"; //$NON-NLS-1$ - private static final String TAG_RICH = "rich"; //$NON-NLS-1$ - - private static final String ATTR_FOLDED = "folded"; //$NON-NLS-1$ - private static final String ATTR_FLOATING_TYPE = "floating-type"; //$NON-NLS-1$ - private static final String ATTR_INHERITED = "inherited"; //$NON-NLS-1$ - private static final String ATTR_FROM = "from-id"; //$NON-NLS-1$ - private static final String ATTR_TO = "to-id"; //$NON-NLS-1$ - private static final String ATTR_END_INDEX = "end-index"; //$NON-NLS-1$ - private static final String ATTR_START_INDEX = "start-index"; //$NON-NLS-1$ - - private static final String ATTR_RAINBOWCOLOR = "rainbowcolor"; //$NON-NLS-1$ - private static final String ATTR_SPINYLINES = "spinylines"; //$NON-NLS-1$ - - private static final String ATTR_FROM_POINT = "control-point1"; //$NON-NLS-1$ - private static final String ATTR_TO_POINT = "control-point2"; //$NON-NLS-1$ - - private static final String VAL_CENTRAL = "central"; //$NON-NLS-1$ - private static final String VAL_MULTI_LINE_COLORS = "#017c98 #00b2a1 #ffdd00 #fc8f00 #ff1500 #00b04c"; //$NON-NLS-1$ - - private static final String VAL_USER = "User"; //$NON-NLS-1$ - private static final String VAL_ATTACHMENT = "Attachment"; //$NON-NLS-1$ - - private MarkerSheetImpl markerSheet; - - private String defaultMarkerGroupId; - - public FileFormat_1(DeserializerImpl deserializer) { - super(deserializer); - } - - public boolean identifies() throws CoreException, IOException { - Document document = deserializer.loadDocumentFromEntry(CONTENT_XML); - if (document == null) - return false; - - Element ele = document.getDocumentElement(); - String version = DOMUtils.getAttribute(ele, ATTR_VERSION); - return version == null || VERSION.equals(version); - } - - public WorkbookImpl load() throws CoreException, IOException { - WorkbookImpl workbook = new WorkbookImpl(deserializer.createDocument(), - deserializer.getManifest()); - - DOMUtils.setAttribute(workbook.getWorkbookElement(), ATTR_VERSION, - VERSION); - - Document metaDocument = deserializer.loadDocumentFromEntry(META_XML); - if (metaDocument != null) { - MetaImpl meta = new MetaImpl(metaDocument); - workbook.setMeta(meta); - } - - Document ssDocument = deserializer.loadDocumentFromEntry(STYLES_XML); - if (ssDocument != null) { - upgradeStyleSheet(ssDocument); - StyleSheetImpl ss = new StyleSheetImpl(ssDocument); - workbook.setStyleSheet(ss); - ss.getAllStyles(); - } - - Document contentDocument = deserializer - .loadDocumentFromEntry(CONTENT_XML); - assert contentDocument != null; - loadWorkbookContent(workbook, contentDocument); - return workbook; - } - -// private void copyEntry(IInputSource source, IOutputTarget target, -// String entryPath) throws CoreException { -// try { -// InputStream in = getInputStream(source, entryPath); -// if (in != null) { -// long time = source.getEntryTime(entryPath); -// if (time >= 0) { -// target.setEntryTime(entryPath, time); -// } -// OutputStream out = getOutputStream(target, entryPath); -// if (out != null) { -// FileUtils.transfer(in, out, true); -// } -// } -// } catch (IOException e) { -// Core.getLogger().log(e); -// } catch (CoreException e) { -// if (e.getType() == Core.ERROR_WRONG_PASSWORD -// || e.getType() == Core.ERROR_CANCELLATION) -// throw e; -// Core.getLogger().log(e); -// } -// } - -// private InputStream getInputStream(IInputSource source, String entryPath) -// throws IOException, CoreException { -// if (!source.hasEntry(entryPath)) -// return null; -// -// return source.openEntryStream(entryPath); -// } -// -// private OutputStream getOutputStream(IOutputTarget target, String entryPath) -// throws IOException { -// if (!target.isEntryAvaialble(entryPath)) -// return null; -// -// return target.openEntryStream(entryPath); -// } - - private void upgradeStyleSheet(Document ssDocument) { - Element element = ssDocument.getDocumentElement(); - if (element != null) - upgradeStyles(element); - } - - private void upgradeStyles(Element element) { - upgradeStyle(element); - Iterator it = DOMUtils.childElementIter(element); - while (it.hasNext()) { - Element subElement = it.next(); - upgradeStyles(subElement); - } - } - - private void upgradeStyle(Element element) { - NamedNodeMap attributes = element.getAttributes(); - Map added = null; - for (int i = 0; i < attributes.getLength(); i++) { - Attr attr = (Attr) attributes.item(i); - String name = attr.getName(); - String value = attr.getValue(); - if (ATTR_TYPE.equals(name)) { - attr.setValue(value.toLowerCase()); - } else if (ATTR_STYLE_FAMILY.equals(name)) { - attr.setValue(value.toLowerCase()); - } else if (ATTR_RAINBOWCOLOR.equals(name)) { - if (Boolean.TRUE.toString().equalsIgnoreCase(value)) { - added = add(added, ATTR_MULTI_LINE_COLORS, - VAL_MULTI_LINE_COLORS); - } - } else if (ATTR_SPINYLINES.equals(name)) { - if (Boolean.TRUE.toString().equalsIgnoreCase(value)) { - added = add(added, ATTR_LINE_TAPERED, VAL_TAPERED); - } - } - if ("floatingMainTopic".equals(value)) { //$NON-NLS-1$ - attr.setValue("floatingTopic"); //$NON-NLS-1$ - } else if ("$none$".equals(value)) { //$NON-NLS-1$ - attr.setValue(VAL_NONE); - } - } - if (added != null) { - for (Entry e : added.entrySet()) { - element.setAttribute(e.getKey(), e.getValue()); - } - } - } - - private Map add(Map map, String key, - String value) { - if (map == null) - map = new HashMap(); - map.put(key, value); - return map; - } - - private void loadWorkbookContent(WorkbookImpl workbook, Document wbDocument) - throws CoreException { - Element wbEle = wbDocument.getDocumentElement(); - Iterator sheetIter = DOMUtils.childElementIterByTag(wbEle, - TAG_MAP); - boolean primary = true; - while (sheetIter.hasNext()) { - Element sheetEle = sheetIter.next(); - ISheet sheet; - if (primary) { - sheet = workbook.getPrimarySheet(); - primary = false; - } else { - sheet = workbook.createSheet(); - workbook.addSheet(sheet); - } - loadSheet(sheet, sheetEle, workbook); - } - } - - private void loadId(IAdaptable elementAdaptable, Element oldElement, - WorkbookImpl workbook) { - Element newElement = getElement(elementAdaptable); - if (newElement != null) { - String id = DOMUtils.getAttribute(oldElement, ATTR_ID); - if (id != null) { -// workbook.getElementRegistry().unregisterByKey(id); - Document doc = newElement.getOwnerDocument(); - workbook.getAdaptableRegistry().unregisterById(elementAdaptable, - newElement.getAttribute(ATTR_ID), doc); - DOMUtils.replaceId(newElement, id); -// workbook.getElementRegistry().registerByKey(id, -// elementAdaptable); - workbook.getAdaptableRegistry().registerById(elementAdaptable, - id, doc); - } - } - } - - private Element getElement(IAdaptable elementAdaptable) { - return (Element) elementAdaptable.getAdapter(Element.class); - } - - private void loadTitle(ITitled titled, Element oldElement) { - String title = DOMUtils.getTextContentByTag(oldElement, TAG_TITLE); - titled.setTitleText(title); - } - - private void loadStyle(IStyled styled, Element oldElement) { - String styleId = DOMUtils.getAttribute(oldElement, ATTR_STYLE_ID); - styled.setStyleId(styleId); - } - - private void loadSheet(ISheet sheet, Element sheetEle, - WorkbookImpl workbook) { - loadId(sheet, sheetEle, workbook); - loadTitle(sheet, sheetEle); - loadSheetStyle(sheet, sheetEle, workbook); - String themeId = DOMUtils.getAttribute(sheetEle, ATTR_THEME); - sheet.setThemeId(themeId); - - Element topicEle = DOMUtils.getFirstChildElementByTag(sheetEle, - TAG_ROOT_TOPIC); - if (topicEle != null) { - loadTopic(sheet.getRootTopic(), topicEle, workbook); - } - - Element relsEle = DOMUtils.getFirstChildElementByTag(sheetEle, - TAG_RELATIONSHIPS); - if (relsEle != null) { - Iterator relIter = DOMUtils.childElementIterByTag(relsEle, - TAG_RELATIONSHIP); - while (relIter.hasNext()) { - Element relEle = relIter.next(); - IRelationship rel = workbook.createRelationship(); - sheet.addRelationship(rel); - loadRelationship(rel, relEle, workbook); - } - } - } - - private void loadSheetStyle(ISheet sheet, Element sheetEle, - IWorkbook workbook) { - String styleId = DOMUtils.getAttribute(sheetEle, ATTR_STYLE_ID); - IStyleSheet styleSheet = workbook.getStyleSheet(); - IStyle style = styleSheet.findStyle(styleId); - if (style != null) { - String type = style.getType(); - if ("map".equals(type)) { //$NON-NLS-1$ - String p = style.getProperty("background"); //$NON-NLS-1$ - String url = findAttachmentUrl(p, workbook); - style.setProperty("background", url); //$NON-NLS-1$ - } - } - sheet.setStyleId(styleId); - } - - private String findAttachmentUrl(String url, IWorkbook workbook) { - if (HyperlinkUtils.isAttachmentURL(url)) { - String attId = HyperlinkUtils.toAttachmentPath(url); - if (attId.startsWith("#")) { //$NON-NLS-1$ - attId = attId.substring(1, attId.length()); - } - IFileEntry entry = findAttachmentEntry(attId, - workbook.getManifest()); - if (entry != null) { - try { - InputStream is = entry.openInputStream(); - try { - String path = entry.getPath(); - IFileEntry fileEntry = workbook.getManifest() - .createAttachmentFromStream(is, path); - return HyperlinkUtils - .toAttachmentURL(fileEntry.getPath()); - } finally { - is.close(); - } - } catch (IOException e) { - } - } - } - return url; - } - - private void loadTopic(ITopic topic, Element topicEle, - WorkbookImpl workbook) { - loadId(topic, topicEle, workbook); - loadTitle(topic, topicEle); - loadStyle(topic, topicEle); - loadFolded(topic, topicEle); - loadPosition(topic, topicEle); - loadHyperlink(topic, topicEle); - loadStructureClass(topic, topicEle); - loadLabels(topic, topicEle); - loadImage(topic, topicEle, workbook); - loadMarkers(topic, topicEle, workbook); - loadNotes(topic, topicEle, workbook); - loadNumbering(topic, topicEle); - loadSubTopics(topic, topicEle, TAG_ATTACHED_TOPICS, ITopic.ATTACHED, - workbook); - loadSubTopics(topic, topicEle, TAG_DETACHED_TOPICS, ITopic.DETACHED, - workbook); - loadBoundaries(topic, topicEle, workbook); - } - - private void loadHyperlink(ITopic topic, Element topicEle) { - String url = DOMUtils.getAttribute(topicEle, ATTR_HREF); - if (url != null) { - url = readAttachment(topic, url); - } - topic.setHyperlink(url); - } - - /** - * Read attachment content. - * - * @param topic - * @param url - * @return - */ - private String readAttachment(ITopic topic, String url) { - String path = HyperlinkUtils.toAttachmentPath(url); - if (path.startsWith("#")) //$NON-NLS-1$ - path = path.substring(1); - IFileEntry entry = findAttachmentEntry(path, - topic.getOwnedWorkbook().getManifest()); - if (entry != null) { - url = HyperlinkUtils.toAttachmentURL(entry.getPath()); - } - return url; - } - - private void loadFolded(ITopic topic, Element topicEle) { - String folded = DOMUtils.getAttribute(topicEle, ATTR_FOLDED); - topic.setFolded(Boolean.TRUE.toString().equalsIgnoreCase(folded)); - } - - private void loadPosition(ITopic topic, Element topicEle) { - Element positionEle = DOMUtils.getFirstChildElementByTag(topicEle, - TAG_POSITION); - if (positionEle != null) { - String x = DOMUtils.getAttribute(positionEle, ATTR_X); - String y = DOMUtils.getAttribute(positionEle, ATTR_Y); - if (x != null && y != null) { - try { - int xValue = Integer.parseInt(x); - int yValue = Integer.parseInt(y); - topic.setPosition(xValue, yValue); - } catch (NumberFormatException e) { - } - } - if (x != null || y != null) { - Element newPositionEle = DOMUtils - .ensureChildElement(getElement(topic), TAG_POSITION); - DOMUtils.setAttribute(newPositionEle, ATTR_X, x); - DOMUtils.setAttribute(newPositionEle, ATTR_Y, y); - } - } - } - - private void loadBoundaries(ITopic topic, Element topicEle, - WorkbookImpl workbook) { - Element boundariesEle = DOMUtils.getFirstChildElementByTag(topicEle, - TAG_BOUNDARIES); - if (boundariesEle == null) - return; - Iterator boundaryIter = DOMUtils - .childElementIterByTag(boundariesEle, TAG_BOUNDARY); - while (boundaryIter.hasNext()) { - Element boundaryEle = boundaryIter.next(); - IBoundary boundary = workbook.createBoundary(); - topic.addBoundary(boundary); - loadBoundary(boundary, boundaryEle, workbook); - } - } - - private void loadBoundary(IBoundary boundary, Element boundaryEle, - WorkbookImpl workbook) { - String startIndex = DOMUtils.getAttribute(boundaryEle, - ATTR_START_INDEX); - String endIndex = DOMUtils.getAttribute(boundaryEle, ATTR_END_INDEX); - Element newBoundaryEle = getElement(boundary); - DOMUtils.setAttribute(newBoundaryEle, ATTR_START_INDEX, startIndex); - DOMUtils.setAttribute(newBoundaryEle, ATTR_END_INDEX, endIndex); - loadStyle(boundary, boundaryEle); - } - - private void loadSubTopics(ITopic topic, Element topicEle, String topicsTag, - String topicType, WorkbookImpl workbook) { - Element subTopicsEle = DOMUtils.getFirstChildElementByTag(topicEle, - topicsTag); - if (subTopicsEle == null) - return; - Iterator subTopicIter = DOMUtils - .childElementIterByTag(subTopicsEle, TAG_TOPIC); - while (subTopicIter.hasNext()) { - Element subTopicEle = subTopicIter.next(); - ITopic subTopic = workbook.createTopic(); - topic.add(subTopic, topicType); - loadTopic(subTopic, subTopicEle, workbook); - } - } - - private void loadNumbering(ITopic topic, Element topicEle) { - Element numberingEle = DOMUtils.getFirstChildElementByTag(topicEle, - TAG_NUMBERING); - if (numberingEle == null) - return; - - INumbering numbering = topic.getNumbering(); - String format = DOMUtils.getAttribute(numberingEle, ATTR_NUMBER_FORMAT); - String separator = DOMUtils.getAttribute(numberingEle, - ATTR_NUMBER_SEPARATOR); - String prefix = DOMUtils.getAttribute(numberingEle, TAG_PREFIX); - String suffix = DOMUtils.getAttribute(numberingEle, TAG_SUFFIX); - String inherited = DOMUtils.getAttribute(numberingEle, ATTR_INHERITED); - numbering.setFormat(format); - numbering.setSeparator(separator); - numbering.setPrefix(prefix); - numbering.setSuffix(suffix); - - boolean prependParentNumbering = inherited == null - || Boolean.parseBoolean(inherited); - numbering.setPrependsParentNumbers(prependParentNumbering); - } - - private void loadNotes(ITopic topic, Element topicEle, - WorkbookImpl workbook) { - Element notesEle = DOMUtils.getFirstChildElementByTag(topicEle, - TAG_NOTES); - if (notesEle == null) - return; - - INotes notes = topic.getNotes(); - Element plainEle = DOMUtils.getFirstChildElementByTag(notesEle, - TAG_PLAIN); - if (plainEle != null) { - IPlainNotesContent content = (IPlainNotesContent) workbook - .createNotesContent(INotes.PLAIN); - content.setTextContent(plainEle.getTextContent()); - notes.setContent(INotes.PLAIN, content); - } - - Element richEle = DOMUtils.getFirstChildElementByTag(notesEle, - TAG_RICH); - if (richEle != null) { - IHtmlNotesContent content = (IHtmlNotesContent) workbook - .createNotesContent(INotes.HTML); - loadRichNotes(topic, topicEle, richEle, content, workbook); - notes.setContent(INotes.HTML, content); - } - } - - private void loadRichNotes(ITopic topic, Element topicEle, Element richEle, - IHtmlNotesContent content, WorkbookImpl workbook) { - Iterator it = DOMUtils.childElementIterByTag(richEle, - DOMConstants.TAG_P); - while (it.hasNext()) { - Element pEle = it.next(); - IParagraph p = content.createParagraph(); - loadSpanList(topic, topicEle, pEle, p, content, workbook); - content.addParagraph(p); - } - } - - private void loadSpanList(ITopic topic, Element topicEle, Element listEle, - ISpanList list, IHtmlNotesContent content, WorkbookImpl workbook) { - NodeList ns = listEle.getChildNodes(); - for (int i = 0; i < ns.getLength(); i++) { - Node n = ns.item(i); - if (n instanceof Text) { - ITextSpan span = content.createTextSpan(n.getTextContent()); - list.addSpan(span); - } else if (n instanceof Element) { - Element e = (Element) n; - String tag = e.getTagName(); - if (TAG_IMG.equals(tag)) { - String url = findImageUrl(e, workbook); - if (url != null) { - IImageSpan span = content.createImageSpan(url); - list.addSpan(span); - } - } else if (TAG_A.equals(tag)) { - String href = e.getAttribute(ATTR_HREF); - if (href != null) { - IHyperlinkSpan hyperlinkSpan = content - .createHyperlinkSpan(href); - list.addSpan(hyperlinkSpan); - loadSpanList(topic, topicEle, e, hyperlinkSpan, content, - workbook); - } - } else { - ITextSpan span = content.createTextSpan(e.getTextContent()); - span.setStyleId(DOMUtils.getAttribute(e, ATTR_STYLE_ID)); - list.addSpan(span); - } - } - } - } - - private void loadMarkers(ITopic topic, Element topicEle, - WorkbookImpl workbook) { - Element markersEle = DOMUtils.getFirstChildElementByTag(topicEle, - TAG_MARKERS); - if (markersEle == null) - return; - Iterator markerIter = DOMUtils - .childElementIterByTag(markersEle, TAG_MARKER); - while (markerIter.hasNext()) { - Element markerEle = markerIter.next(); - loadMarker(topic, markerEle, workbook); - } - } - - private void loadMarker(ITopic topic, Element markerEle, - WorkbookImpl workbook) { - String id = DOMUtils.getAttribute(markerEle, ATTR_ID); - if (id == null) - return; - - String type = DOMUtils.getAttribute(markerEle, ATTR_TYPE); - int sepIndex = id.indexOf('/'); - String markerId; - String markerGroupId; - if (sepIndex >= 0) { - markerId = id.substring(sepIndex + 1); - if (VAL_USER.equals(type)) { - if (id.startsWith("#")) { //$NON-NLS-1$ - markerGroupId = id.substring(1, sepIndex); - } else { - markerGroupId = id.substring(0, sepIndex); - } - } else { - markerGroupId = null; - } - } else { - markerId = id; - if (VAL_USER.equals(type) || VAL_ATTACHMENT.equals(type)) { - markerGroupId = getDefaultMarkerGroupId(); - } else { - markerGroupId = null; - } - } - - if (markerGroupId != null) { - if (markerSheet == null) { - markerSheet = (MarkerSheetImpl) workbook.getMarkerSheet(); - } - IMarkerGroup group = markerSheet.findMarkerGroup(markerGroupId); - if (group == null) { - group = markerSheet.createMarkerGroup(false); - markerSheet.getElementRegistry().unregister(group); - DOMUtils.replaceId( - ((MarkerGroupImpl) group).getImplementation(), - markerGroupId); - markerSheet.getElementRegistry().register(group); - markerSheet.addMarkerGroup(group); - } - IMarker marker = group.getMarker(markerId); - if (marker == null) { - IFileEntry markerEntry = findAttachmentEntry(markerId, - workbook.getManifest()); - if (markerEntry != null) { - String path = markerEntry.getPath(); - if (!path.startsWith("/")) //$NON-NLS-1$ - path = "/" + path; //$NON-NLS-1$ - marker = markerSheet.createMarker(path); - markerSheet.getElementRegistry().unregister(marker); - DOMUtils.replaceId( - ((MarkerImpl) marker).getImplementation(), - markerId); - markerSheet.getElementRegistry().register(marker); - } - } - } - - topic.addMarker(markerId); - } - - private IFileEntry findAttachmentEntry(String attId, IManifest manifest) { - List fileEntries = manifest.getFileEntries(); - for (IFileEntry entry : fileEntries) { - if (entry.getPath().contains(attId)) - return entry; - } - return null; - } - - private String getDefaultMarkerGroupId() { - if (defaultMarkerGroupId == null) { - defaultMarkerGroupId = Core.getIdFactory().createId(); - } - return defaultMarkerGroupId; - } - - private void loadImage(ITopic topic, Element topicEle, - WorkbookImpl workbook) { - Element imgEle = DOMUtils.getFirstChildElementByTag(topicEle, TAG_IMG); - if (imgEle == null) - return; - - IImage image = topic.getImage(); - String url = findImageUrl(imgEle, workbook); - image.setSource(url); - - String width = DOMUtils.getAttribute(imgEle, ATTR_WIDTH); - if (width != null) { - int w = NumberUtils.safeParseInt(width, -1); - if (w >= 0) { - image.setWidth(w); - } - } - String height = DOMUtils.getAttribute(imgEle, ATTR_HEIGHT); - if (height != null) { - int h = NumberUtils.safeParseInt(height, -1); - if (h >= 0) { - image.setHeight(h); - } - } - - String alignment = DOMUtils.getAttribute(imgEle, ATTR_ALIGN); - image.setAlignment(alignment); - } - - private String findImageUrl(Element imgEle, WorkbookImpl workbook) { - String url = DOMUtils.getAttribute(imgEle, ATTR_SRC); - if (HyperlinkUtils.isAttachmentURL(url)) { - String attId = HyperlinkUtils.toAttachmentPath(url); - if (attId.startsWith("#")) { //$NON-NLS-1$ - attId = attId.substring(1, attId.length()); - } - IFileEntry entry = findAttachmentEntry(attId, - workbook.getManifest()); - if (entry != null) { - url = HyperlinkUtils.toAttachmentURL(entry.getPath()); - } - } - return url; - } - - private void loadLabels(ITopic topic, Element topicEle) { - Iterator labelsIter = DOMUtils.childElementIterByTag(topicEle, - TAG_LABELS); - while (labelsIter.hasNext()) { - Element labelsEle = labelsIter.next(); - Iterator labelIter = DOMUtils - .childElementIterByTag(labelsEle, TAG_LABEL); - while (labelIter.hasNext()) { - Element labelEle = labelIter.next(); - String label = labelEle.getTextContent(); - topic.addLabel(label); - } - } - } - - private void loadStructureClass(ITopic topic, Element topicEle) { - String floatingType = DOMUtils.getAttribute(topicEle, - ATTR_FLOATING_TYPE); - String structureClass; - if (VAL_CENTRAL.equals(floatingType)) { - structureClass = "org.xmind.branchPolicy.map.floating"; //$NON-NLS-1$ - } else { - structureClass = upgradeStructureClass( - DOMUtils.getAttribute(topicEle, ATTR_STRUCTURE_CLASS)); - } - topic.setStructureClass(structureClass); - } - - private String upgradeStructureClass(String structureClass) { - if (structureClass == null) - return null; - if ("org.xmind.branchPolicy.org-chart.left".equals(structureClass)) { //$NON-NLS-1$ - structureClass = "org.xmind.ui.logic.left"; //$NON-NLS-1$ - } else if ("org.xmind.branchPolicy.org-chart.right" //$NON-NLS-1$ - .equals(structureClass)) { - structureClass = "org.xmind.ui.logic.right"; //$NON-NLS-1$ - } else if ("org.xmind.branchPolicy.chart2d".equals(structureClass)) { //$NON-NLS-1$ - structureClass = "org.xmind.ui.spreadsheet"; //$NON-NLS-1$ - } else if (structureClass.startsWith("org.xmind.branchPolicy.")) { //$NON-NLS-1$ - structureClass = "org.xmind.ui." + structureClass.substring(23); //$NON-NLS-1$ - } - return structureClass; - } - - private void loadRelationship(IRelationship rel, Element relEle, - WorkbookImpl workbook) { - loadId(rel, relEle, workbook); - loadStyle(rel, relEle); - loadTitle(rel, relEle); - - rel.setEnd1Id(DOMUtils.getAttribute(relEle, ATTR_FROM)); - rel.setEnd2Id(DOMUtils.getAttribute(relEle, ATTR_TO)); - - loadControlPoint(rel, 0, relEle, ATTR_FROM_POINT); - loadControlPoint(rel, 1, relEle, ATTR_TO_POINT); - } - - private void loadControlPoint(IRelationship rel, int index, Element relEle, - String pointAttr) { - String p = DOMUtils.getAttribute(relEle, pointAttr); - if (p != null) { - String[] xy = p.split(", "); //$NON-NLS-1$ - if (xy.length == 2) { - int x; - int y; - try { - x = Integer.parseInt(xy[0]); - y = Integer.parseInt(xy[1]); - } catch (Throwable e) { - return; - } - rel.getControlPoint(index).setPosition(x, y); - } - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALIGN; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HEIGHT; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HREF; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_LINE_TAPERED; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_MULTI_LINE_COLORS; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_FORMAT; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_SEPARATOR; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STRUCTURE_CLASS; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_FAMILY; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_THEME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_X; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_Y; +import static org.xmind.core.internal.dom.DOMConstants.TAG_A; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; +import static org.xmind.core.internal.dom.DOMConstants.TAG_LABEL; +import static org.xmind.core.internal.dom.DOMConstants.TAG_LABELS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; +import static org.xmind.core.internal.dom.DOMConstants.TAG_NOTES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_NUMBERING; +import static org.xmind.core.internal.dom.DOMConstants.TAG_POSITION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_PREFIX; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUFFIX; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; +import static org.xmind.core.internal.dom.DOMConstants.VAL_NONE; +import static org.xmind.core.internal.dom.DOMConstants.VAL_TAPERED; +import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IBoundary; +import org.xmind.core.IFileEntry; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IHyperlinkSpan; +import org.xmind.core.IImage; +import org.xmind.core.IImageSpan; +import org.xmind.core.IManifest; +import org.xmind.core.INotes; +import org.xmind.core.INumbering; +import org.xmind.core.IParagraph; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISpanList; +import org.xmind.core.ITextSpan; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.compatibility.FileFormat; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.HyperlinkUtils; + +public class FileFormat_1 extends FileFormat { + + private static final String VERSION = "1.0"; //$NON-NLS-1$ + + private static final String TAG_MAP = "map"; //$NON-NLS-1$ + private static final String TAG_ROOT_TOPIC = "root-topic"; //$NON-NLS-1$ + private static final String TAG_MARKERS = "markers"; //$NON-NLS-1$ + private static final String TAG_ATTACHED_TOPICS = "attached-topics"; //$NON-NLS-1$ + private static final String TAG_DETACHED_TOPICS = "detached-topics"; //$NON-NLS-1$ + private static final String TAG_PLAIN = "plain"; //$NON-NLS-1$ + private static final String TAG_RICH = "rich"; //$NON-NLS-1$ + + private static final String ATTR_FOLDED = "folded"; //$NON-NLS-1$ + private static final String ATTR_FLOATING_TYPE = "floating-type"; //$NON-NLS-1$ + private static final String ATTR_INHERITED = "inherited"; //$NON-NLS-1$ + private static final String ATTR_FROM = "from-id"; //$NON-NLS-1$ + private static final String ATTR_TO = "to-id"; //$NON-NLS-1$ + private static final String ATTR_END_INDEX = "end-index"; //$NON-NLS-1$ + private static final String ATTR_START_INDEX = "start-index"; //$NON-NLS-1$ + + private static final String ATTR_RAINBOWCOLOR = "rainbowcolor"; //$NON-NLS-1$ + private static final String ATTR_SPINYLINES = "spinylines"; //$NON-NLS-1$ + + private static final String ATTR_FROM_POINT = "control-point1"; //$NON-NLS-1$ + private static final String ATTR_TO_POINT = "control-point2"; //$NON-NLS-1$ + + private static final String VAL_CENTRAL = "central"; //$NON-NLS-1$ + private static final String VAL_MULTI_LINE_COLORS = "#017c98 #00b2a1 #ffdd00 #fc8f00 #ff1500 #00b04c"; //$NON-NLS-1$ + + private static final String VAL_USER = "User"; //$NON-NLS-1$ + private static final String VAL_ATTACHMENT = "Attachment"; //$NON-NLS-1$ + + private MarkerSheetImpl markerSheet; + + private String defaultMarkerGroupId; + + public FileFormat_1(DeserializerImpl deserializer) { + super(deserializer); + } + + public boolean identifies() throws CoreException, IOException { + Document document = deserializer.loadDocumentFromEntry(CONTENT_XML); + if (document == null) + return false; + + Element ele = document.getDocumentElement(); + String version = DOMUtils.getAttribute(ele, ATTR_VERSION); + return version == null || VERSION.equals(version); + } + + public WorkbookImpl load() throws CoreException, IOException { + WorkbookImpl workbook = new WorkbookImpl(deserializer.createDocument(), + deserializer.getManifest()); + + DOMUtils.setAttribute(workbook.getWorkbookElement(), ATTR_VERSION, + VERSION); + + Document metaDocument = deserializer.loadDocumentFromEntry(META_XML); + if (metaDocument != null) { + MetaImpl meta = new MetaImpl(metaDocument); + workbook.setMeta(meta); + } + + Document ssDocument = deserializer.loadDocumentFromEntry(STYLES_XML); + if (ssDocument != null) { + upgradeStyleSheet(ssDocument); + StyleSheetImpl ss = new StyleSheetImpl(ssDocument); + workbook.setStyleSheet(ss); + ss.getAllStyles(); + } + + Document contentDocument = deserializer + .loadDocumentFromEntry(CONTENT_XML); + assert contentDocument != null; + loadWorkbookContent(workbook, contentDocument); + return workbook; + } + +// private void copyEntry(IInputSource source, IOutputTarget target, +// String entryPath) throws CoreException { +// try { +// InputStream in = getInputStream(source, entryPath); +// if (in != null) { +// long time = source.getEntryTime(entryPath); +// if (time >= 0) { +// target.setEntryTime(entryPath, time); +// } +// OutputStream out = getOutputStream(target, entryPath); +// if (out != null) { +// FileUtils.transfer(in, out, true); +// } +// } +// } catch (IOException e) { +// Core.getLogger().log(e); +// } catch (CoreException e) { +// if (e.getType() == Core.ERROR_WRONG_PASSWORD +// || e.getType() == Core.ERROR_CANCELLATION) +// throw e; +// Core.getLogger().log(e); +// } +// } + +// private InputStream getInputStream(IInputSource source, String entryPath) +// throws IOException, CoreException { +// if (!source.hasEntry(entryPath)) +// return null; +// +// return source.openEntryStream(entryPath); +// } +// +// private OutputStream getOutputStream(IOutputTarget target, String entryPath) +// throws IOException { +// if (!target.isEntryAvaialble(entryPath)) +// return null; +// +// return target.openEntryStream(entryPath); +// } + + private void upgradeStyleSheet(Document ssDocument) { + Element element = ssDocument.getDocumentElement(); + if (element != null) + upgradeStyles(element); + } + + private void upgradeStyles(Element element) { + upgradeStyle(element); + Iterator it = DOMUtils.childElementIter(element); + while (it.hasNext()) { + Element subElement = it.next(); + upgradeStyles(subElement); + } + } + + private void upgradeStyle(Element element) { + NamedNodeMap attributes = element.getAttributes(); + Map added = null; + for (int i = 0; i < attributes.getLength(); i++) { + Attr attr = (Attr) attributes.item(i); + String name = attr.getName(); + String value = attr.getValue(); + if (ATTR_TYPE.equals(name)) { + attr.setValue(value.toLowerCase()); + } else if (ATTR_STYLE_FAMILY.equals(name)) { + attr.setValue(value.toLowerCase()); + } else if (ATTR_RAINBOWCOLOR.equals(name)) { + if (Boolean.TRUE.toString().equalsIgnoreCase(value)) { + added = add(added, ATTR_MULTI_LINE_COLORS, + VAL_MULTI_LINE_COLORS); + } + } else if (ATTR_SPINYLINES.equals(name)) { + if (Boolean.TRUE.toString().equalsIgnoreCase(value)) { + added = add(added, ATTR_LINE_TAPERED, VAL_TAPERED); + } + } + if ("floatingMainTopic".equals(value)) { //$NON-NLS-1$ + attr.setValue("floatingTopic"); //$NON-NLS-1$ + } else if ("$none$".equals(value)) { //$NON-NLS-1$ + attr.setValue(VAL_NONE); + } + } + if (added != null) { + for (Entry e : added.entrySet()) { + element.setAttribute(e.getKey(), e.getValue()); + } + } + } + + private Map add(Map map, String key, + String value) { + if (map == null) + map = new HashMap(); + map.put(key, value); + return map; + } + + private void loadWorkbookContent(WorkbookImpl workbook, Document wbDocument) + throws CoreException { + Element wbEle = wbDocument.getDocumentElement(); + Iterator sheetIter = DOMUtils.childElementIterByTag(wbEle, + TAG_MAP); + boolean primary = true; + while (sheetIter.hasNext()) { + Element sheetEle = sheetIter.next(); + ISheet sheet; + if (primary) { + sheet = workbook.getPrimarySheet(); + primary = false; + } else { + sheet = workbook.createSheet(); + workbook.addSheet(sheet); + } + loadSheet(sheet, sheetEle, workbook); + } + } + + private void loadId(IAdaptable elementAdaptable, Element oldElement, + WorkbookImpl workbook) { + Element newElement = getElement(elementAdaptable); + if (newElement != null) { + String id = DOMUtils.getAttribute(oldElement, ATTR_ID); + if (id != null) { +// workbook.getElementRegistry().unregisterByKey(id); + Document doc = newElement.getOwnerDocument(); + workbook.getAdaptableRegistry().unregisterById(elementAdaptable, + newElement.getAttribute(ATTR_ID), doc); + DOMUtils.replaceId(newElement, id); +// workbook.getElementRegistry().registerByKey(id, +// elementAdaptable); + workbook.getAdaptableRegistry().registerById(elementAdaptable, + id, doc); + } + } + } + + private Element getElement(IAdaptable elementAdaptable) { + return (Element) elementAdaptable.getAdapter(Element.class); + } + + private void loadTitle(ITitled titled, Element oldElement) { + String title = DOMUtils.getTextContentByTag(oldElement, TAG_TITLE); + titled.setTitleText(title); + } + + private void loadStyle(IStyled styled, Element oldElement) { + String styleId = DOMUtils.getAttribute(oldElement, ATTR_STYLE_ID); + styled.setStyleId(styleId); + } + + private void loadSheet(ISheet sheet, Element sheetEle, + WorkbookImpl workbook) { + loadId(sheet, sheetEle, workbook); + loadTitle(sheet, sheetEle); + loadSheetStyle(sheet, sheetEle, workbook); + String themeId = DOMUtils.getAttribute(sheetEle, ATTR_THEME); + sheet.setThemeId(themeId); + + Element topicEle = DOMUtils.getFirstChildElementByTag(sheetEle, + TAG_ROOT_TOPIC); + if (topicEle != null) { + loadTopic(sheet.getRootTopic(), topicEle, workbook); + } + + Element relsEle = DOMUtils.getFirstChildElementByTag(sheetEle, + TAG_RELATIONSHIPS); + if (relsEle != null) { + Iterator relIter = DOMUtils.childElementIterByTag(relsEle, + TAG_RELATIONSHIP); + while (relIter.hasNext()) { + Element relEle = relIter.next(); + IRelationship rel = workbook.createRelationship(); + sheet.addRelationship(rel); + loadRelationship(rel, relEle, workbook); + } + } + } + + private void loadSheetStyle(ISheet sheet, Element sheetEle, + IWorkbook workbook) { + String styleId = DOMUtils.getAttribute(sheetEle, ATTR_STYLE_ID); + IStyleSheet styleSheet = workbook.getStyleSheet(); + IStyle style = styleSheet.findStyle(styleId); + if (style != null) { + String type = style.getType(); + if ("map".equals(type)) { //$NON-NLS-1$ + String p = style.getProperty("background"); //$NON-NLS-1$ + String url = findAttachmentUrl(p, workbook); + style.setProperty("background", url); //$NON-NLS-1$ + } + } + sheet.setStyleId(styleId); + } + + private String findAttachmentUrl(String url, IWorkbook workbook) { + if (HyperlinkUtils.isAttachmentURL(url)) { + String attId = HyperlinkUtils.toAttachmentPath(url); + if (attId.startsWith("#")) { //$NON-NLS-1$ + attId = attId.substring(1, attId.length()); + } + IFileEntry entry = findAttachmentEntry(attId, + workbook.getManifest()); + if (entry != null) { + try { + InputStream is = entry.openInputStream(); + try { + String path = entry.getPath(); + IFileEntry fileEntry = workbook.getManifest() + .createAttachmentFromStream(is, path); + return HyperlinkUtils + .toAttachmentURL(fileEntry.getPath()); + } finally { + is.close(); + } + } catch (IOException e) { + } + } + } + return url; + } + + private void loadTopic(ITopic topic, Element topicEle, + WorkbookImpl workbook) { + loadId(topic, topicEle, workbook); + loadTitle(topic, topicEle); + loadStyle(topic, topicEle); + loadFolded(topic, topicEle); + loadPosition(topic, topicEle); + loadHyperlink(topic, topicEle); + loadStructureClass(topic, topicEle); + loadLabels(topic, topicEle); + loadImage(topic, topicEle, workbook); + loadMarkers(topic, topicEle, workbook); + loadNotes(topic, topicEle, workbook); + loadNumbering(topic, topicEle); + loadSubTopics(topic, topicEle, TAG_ATTACHED_TOPICS, ITopic.ATTACHED, + workbook); + loadSubTopics(topic, topicEle, TAG_DETACHED_TOPICS, ITopic.DETACHED, + workbook); + loadBoundaries(topic, topicEle, workbook); + } + + private void loadHyperlink(ITopic topic, Element topicEle) { + String url = DOMUtils.getAttribute(topicEle, ATTR_HREF); + if (url != null) { + url = readAttachment(topic, url); + } + topic.setHyperlink(url); + } + + /** + * Read attachment content. + * + * @param topic + * @param url + * @return + */ + private String readAttachment(ITopic topic, String url) { + String path = HyperlinkUtils.toAttachmentPath(url); + if (path.startsWith("#")) //$NON-NLS-1$ + path = path.substring(1); + IFileEntry entry = findAttachmentEntry(path, + topic.getOwnedWorkbook().getManifest()); + if (entry != null) { + url = HyperlinkUtils.toAttachmentURL(entry.getPath()); + } + return url; + } + + private void loadFolded(ITopic topic, Element topicEle) { + String folded = DOMUtils.getAttribute(topicEle, ATTR_FOLDED); + topic.setFolded(Boolean.TRUE.toString().equalsIgnoreCase(folded)); + } + + private void loadPosition(ITopic topic, Element topicEle) { + Element positionEle = DOMUtils.getFirstChildElementByTag(topicEle, + TAG_POSITION); + if (positionEle != null) { + String x = DOMUtils.getAttribute(positionEle, ATTR_X); + String y = DOMUtils.getAttribute(positionEle, ATTR_Y); + if (x != null && y != null) { + try { + int xValue = Integer.parseInt(x); + int yValue = Integer.parseInt(y); + topic.setPosition(xValue, yValue); + } catch (NumberFormatException e) { + } + } + if (x != null || y != null) { + Element newPositionEle = DOMUtils + .ensureChildElement(getElement(topic), TAG_POSITION); + DOMUtils.setAttribute(newPositionEle, ATTR_X, x); + DOMUtils.setAttribute(newPositionEle, ATTR_Y, y); + } + } + } + + private void loadBoundaries(ITopic topic, Element topicEle, + WorkbookImpl workbook) { + Element boundariesEle = DOMUtils.getFirstChildElementByTag(topicEle, + TAG_BOUNDARIES); + if (boundariesEle == null) + return; + Iterator boundaryIter = DOMUtils + .childElementIterByTag(boundariesEle, TAG_BOUNDARY); + while (boundaryIter.hasNext()) { + Element boundaryEle = boundaryIter.next(); + IBoundary boundary = workbook.createBoundary(); + topic.addBoundary(boundary); + loadBoundary(boundary, boundaryEle, workbook); + } + } + + private void loadBoundary(IBoundary boundary, Element boundaryEle, + WorkbookImpl workbook) { + String startIndex = DOMUtils.getAttribute(boundaryEle, + ATTR_START_INDEX); + String endIndex = DOMUtils.getAttribute(boundaryEle, ATTR_END_INDEX); + Element newBoundaryEle = getElement(boundary); + DOMUtils.setAttribute(newBoundaryEle, ATTR_START_INDEX, startIndex); + DOMUtils.setAttribute(newBoundaryEle, ATTR_END_INDEX, endIndex); + loadStyle(boundary, boundaryEle); + } + + private void loadSubTopics(ITopic topic, Element topicEle, String topicsTag, + String topicType, WorkbookImpl workbook) { + Element subTopicsEle = DOMUtils.getFirstChildElementByTag(topicEle, + topicsTag); + if (subTopicsEle == null) + return; + Iterator subTopicIter = DOMUtils + .childElementIterByTag(subTopicsEle, TAG_TOPIC); + while (subTopicIter.hasNext()) { + Element subTopicEle = subTopicIter.next(); + ITopic subTopic = workbook.createTopic(); + topic.add(subTopic, topicType); + loadTopic(subTopic, subTopicEle, workbook); + } + } + + private void loadNumbering(ITopic topic, Element topicEle) { + Element numberingEle = DOMUtils.getFirstChildElementByTag(topicEle, + TAG_NUMBERING); + if (numberingEle == null) + return; + + INumbering numbering = topic.getNumbering(); + String format = DOMUtils.getAttribute(numberingEle, ATTR_NUMBER_FORMAT); + String separator = DOMUtils.getAttribute(numberingEle, + ATTR_NUMBER_SEPARATOR); + String prefix = DOMUtils.getAttribute(numberingEle, TAG_PREFIX); + String suffix = DOMUtils.getAttribute(numberingEle, TAG_SUFFIX); + String inherited = DOMUtils.getAttribute(numberingEle, ATTR_INHERITED); + numbering.setFormat(format); + numbering.setSeparator(separator); + numbering.setPrefix(prefix); + numbering.setSuffix(suffix); + + boolean prependParentNumbering = inherited == null + || Boolean.parseBoolean(inherited); + numbering.setPrependsParentNumbers(prependParentNumbering); + } + + private void loadNotes(ITopic topic, Element topicEle, + WorkbookImpl workbook) { + Element notesEle = DOMUtils.getFirstChildElementByTag(topicEle, + TAG_NOTES); + if (notesEle == null) + return; + + INotes notes = topic.getNotes(); + Element plainEle = DOMUtils.getFirstChildElementByTag(notesEle, + TAG_PLAIN); + if (plainEle != null) { + IPlainNotesContent content = (IPlainNotesContent) workbook + .createNotesContent(INotes.PLAIN); + content.setTextContent(plainEle.getTextContent()); + notes.setContent(INotes.PLAIN, content); + } + + Element richEle = DOMUtils.getFirstChildElementByTag(notesEle, + TAG_RICH); + if (richEle != null) { + IHtmlNotesContent content = (IHtmlNotesContent) workbook + .createNotesContent(INotes.HTML); + loadRichNotes(topic, topicEle, richEle, content, workbook); + notes.setContent(INotes.HTML, content); + } + } + + private void loadRichNotes(ITopic topic, Element topicEle, Element richEle, + IHtmlNotesContent content, WorkbookImpl workbook) { + Iterator it = DOMUtils.childElementIterByTag(richEle, + DOMConstants.TAG_P); + while (it.hasNext()) { + Element pEle = it.next(); + IParagraph p = content.createParagraph(); + loadSpanList(topic, topicEle, pEle, p, content, workbook); + content.addParagraph(p); + } + } + + private void loadSpanList(ITopic topic, Element topicEle, Element listEle, + ISpanList list, IHtmlNotesContent content, WorkbookImpl workbook) { + NodeList ns = listEle.getChildNodes(); + for (int i = 0; i < ns.getLength(); i++) { + Node n = ns.item(i); + if (n instanceof Text) { + ITextSpan span = content.createTextSpan(n.getTextContent()); + list.addSpan(span); + } else if (n instanceof Element) { + Element e = (Element) n; + String tag = e.getTagName(); + if (TAG_IMG.equals(tag)) { + String url = findImageUrl(e, workbook); + if (url != null) { + IImageSpan span = content.createImageSpan(url); + list.addSpan(span); + } + } else if (TAG_A.equals(tag)) { + String href = e.getAttribute(ATTR_HREF); + if (href != null) { + IHyperlinkSpan hyperlinkSpan = content + .createHyperlinkSpan(href); + list.addSpan(hyperlinkSpan); + loadSpanList(topic, topicEle, e, hyperlinkSpan, content, + workbook); + } + } else { + ITextSpan span = content.createTextSpan(e.getTextContent()); + span.setStyleId(DOMUtils.getAttribute(e, ATTR_STYLE_ID)); + list.addSpan(span); + } + } + } + } + + private void loadMarkers(ITopic topic, Element topicEle, + WorkbookImpl workbook) { + Element markersEle = DOMUtils.getFirstChildElementByTag(topicEle, + TAG_MARKERS); + if (markersEle == null) + return; + Iterator markerIter = DOMUtils + .childElementIterByTag(markersEle, TAG_MARKER); + while (markerIter.hasNext()) { + Element markerEle = markerIter.next(); + loadMarker(topic, markerEle, workbook); + } + } + + private void loadMarker(ITopic topic, Element markerEle, + WorkbookImpl workbook) { + String id = DOMUtils.getAttribute(markerEle, ATTR_ID); + if (id == null) + return; + + String type = DOMUtils.getAttribute(markerEle, ATTR_TYPE); + int sepIndex = id.indexOf('/'); + String markerId; + String markerGroupId; + if (sepIndex >= 0) { + markerId = id.substring(sepIndex + 1); + if (VAL_USER.equals(type)) { + if (id.startsWith("#")) { //$NON-NLS-1$ + markerGroupId = id.substring(1, sepIndex); + } else { + markerGroupId = id.substring(0, sepIndex); + } + } else { + markerGroupId = null; + } + } else { + markerId = id; + if (VAL_USER.equals(type) || VAL_ATTACHMENT.equals(type)) { + markerGroupId = getDefaultMarkerGroupId(); + } else { + markerGroupId = null; + } + } + + if (markerGroupId != null) { + if (markerSheet == null) { + markerSheet = (MarkerSheetImpl) workbook.getMarkerSheet(); + } + IMarkerGroup group = markerSheet.findMarkerGroup(markerGroupId); + if (group == null) { + group = markerSheet.createMarkerGroup(false); + markerSheet.getElementRegistry().unregister(group); + DOMUtils.replaceId( + ((MarkerGroupImpl) group).getImplementation(), + markerGroupId); + markerSheet.getElementRegistry().register(group); + markerSheet.addMarkerGroup(group); + } + IMarker marker = group.getMarker(markerId); + if (marker == null) { + IFileEntry markerEntry = findAttachmentEntry(markerId, + workbook.getManifest()); + if (markerEntry != null) { + String path = markerEntry.getPath(); + if (!path.startsWith("/")) //$NON-NLS-1$ + path = "/" + path; //$NON-NLS-1$ + marker = markerSheet.createMarker(path); + markerSheet.getElementRegistry().unregister(marker); + DOMUtils.replaceId( + ((MarkerImpl) marker).getImplementation(), + markerId); + markerSheet.getElementRegistry().register(marker); + } + } + } + + topic.addMarker(markerId); + } + + private IFileEntry findAttachmentEntry(String attId, IManifest manifest) { + List fileEntries = manifest.getFileEntries(); + for (IFileEntry entry : fileEntries) { + if (entry.getPath().contains(attId)) + return entry; + } + return null; + } + + private String getDefaultMarkerGroupId() { + if (defaultMarkerGroupId == null) { + defaultMarkerGroupId = Core.getIdFactory().createId(); + } + return defaultMarkerGroupId; + } + + private void loadImage(ITopic topic, Element topicEle, + WorkbookImpl workbook) { + Element imgEle = DOMUtils.getFirstChildElementByTag(topicEle, TAG_IMG); + if (imgEle == null) + return; + + IImage image = topic.getImage(); + String url = findImageUrl(imgEle, workbook); + image.setSource(url); + + String width = DOMUtils.getAttribute(imgEle, ATTR_WIDTH); + if (width != null) { + int w = NumberUtils.safeParseInt(width, -1); + if (w >= 0) { + image.setWidth(w); + } + } + String height = DOMUtils.getAttribute(imgEle, ATTR_HEIGHT); + if (height != null) { + int h = NumberUtils.safeParseInt(height, -1); + if (h >= 0) { + image.setHeight(h); + } + } + + String alignment = DOMUtils.getAttribute(imgEle, ATTR_ALIGN); + image.setAlignment(alignment); + } + + private String findImageUrl(Element imgEle, WorkbookImpl workbook) { + String url = DOMUtils.getAttribute(imgEle, ATTR_SRC); + if (HyperlinkUtils.isAttachmentURL(url)) { + String attId = HyperlinkUtils.toAttachmentPath(url); + if (attId.startsWith("#")) { //$NON-NLS-1$ + attId = attId.substring(1, attId.length()); + } + IFileEntry entry = findAttachmentEntry(attId, + workbook.getManifest()); + if (entry != null) { + url = HyperlinkUtils.toAttachmentURL(entry.getPath()); + } + } + return url; + } + + private void loadLabels(ITopic topic, Element topicEle) { + Iterator labelsIter = DOMUtils.childElementIterByTag(topicEle, + TAG_LABELS); + while (labelsIter.hasNext()) { + Element labelsEle = labelsIter.next(); + Iterator labelIter = DOMUtils + .childElementIterByTag(labelsEle, TAG_LABEL); + while (labelIter.hasNext()) { + Element labelEle = labelIter.next(); + String label = labelEle.getTextContent(); + topic.addLabel(label); + } + } + } + + private void loadStructureClass(ITopic topic, Element topicEle) { + String floatingType = DOMUtils.getAttribute(topicEle, + ATTR_FLOATING_TYPE); + String structureClass; + if (VAL_CENTRAL.equals(floatingType)) { + structureClass = "org.xmind.branchPolicy.map.floating"; //$NON-NLS-1$ + } else { + structureClass = upgradeStructureClass( + DOMUtils.getAttribute(topicEle, ATTR_STRUCTURE_CLASS)); + } + topic.setStructureClass(structureClass); + } + + private String upgradeStructureClass(String structureClass) { + if (structureClass == null) + return null; + if ("org.xmind.branchPolicy.org-chart.left".equals(structureClass)) { //$NON-NLS-1$ + structureClass = "org.xmind.ui.logic.left"; //$NON-NLS-1$ + } else if ("org.xmind.branchPolicy.org-chart.right" //$NON-NLS-1$ + .equals(structureClass)) { + structureClass = "org.xmind.ui.logic.right"; //$NON-NLS-1$ + } else if ("org.xmind.branchPolicy.chart2d".equals(structureClass)) { //$NON-NLS-1$ + structureClass = "org.xmind.ui.spreadsheet"; //$NON-NLS-1$ + } else if (structureClass.startsWith("org.xmind.branchPolicy.")) { //$NON-NLS-1$ + structureClass = "org.xmind.ui." + structureClass.substring(23); //$NON-NLS-1$ + } + return structureClass; + } + + private void loadRelationship(IRelationship rel, Element relEle, + WorkbookImpl workbook) { + loadId(rel, relEle, workbook); + loadStyle(rel, relEle); + loadTitle(rel, relEle); + + rel.setEnd1Id(DOMUtils.getAttribute(relEle, ATTR_FROM)); + rel.setEnd2Id(DOMUtils.getAttribute(relEle, ATTR_TO)); + + loadControlPoint(rel, 0, relEle, ATTR_FROM_POINT); + loadControlPoint(rel, 1, relEle, ATTR_TO_POINT); + } + + private void loadControlPoint(IRelationship rel, int index, Element relEle, + String pointAttr) { + String p = DOMUtils.getAttribute(relEle, pointAttr); + if (p != null) { + String[] xy = p.split(", "); //$NON-NLS-1$ + if (xy.length == 2) { + int x; + int y; + try { + x = Integer.parseInt(xy[0]); + y = Integer.parseInt(xy[1]); + } catch (Throwable e) { + return; + } + rel.getControlPoint(index).setPosition(x, y); + } + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/HtmlNotesContentImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/HtmlNotesContentImpl.java index 9810891d9..68348d55c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/HtmlNotesContentImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/HtmlNotesContentImpl.java @@ -1,160 +1,160 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_A; -import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; -import static org.xmind.core.internal.dom.DOMConstants.TAG_P; - -import java.util.List; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.Text; -import org.xmind.core.IAdaptable; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IHyperlinkSpan; -import org.xmind.core.IImageSpan; -import org.xmind.core.INotes; -import org.xmind.core.IParagraph; -import org.xmind.core.ITextSpan; -import org.xmind.core.util.DOMUtils; - -public class HtmlNotesContentImpl extends BaseNotesContentImpl implements - IHtmlNotesContent, INodeAdaptableProvider { - - public HtmlNotesContentImpl(Element implementation, - WorkbookImpl ownedWorkbook) { - super(implementation, ownedWorkbook); - } - - public void addParagraph(IParagraph paragraph) { - ParagraphImpl p = (ParagraphImpl) paragraph; - getImplementation().appendChild(p.getImplementation()); - if (!isOrphan()) { - p.addNotify((WorkbookImpl) getOwnedWorkbook()); - } - updateModifiedTime(); - } - - public IImageSpan createImageSpan(String source) { - Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() - .createElement(TAG_IMG); - ImageSpanImpl image = new ImageSpanImpl(e, this); - image.setSource(source); - getAdaptableRegistry().register(image, e); - return image; - } - - public IHyperlinkSpan createHyperlinkSpan(String sourceHyper) { - Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() - .createElement(TAG_A); - HyperlinkSpanImpl hyperlink = new HyperlinkSpanImpl(e, this); - hyperlink.setHref(sourceHyper); - getAdaptableRegistry().register(hyperlink, e); - return hyperlink; - } - - public IParagraph createParagraph() { - Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() - .createElement(DOMConstants.TAG_P); - ParagraphImpl paragraph = new ParagraphImpl(e, this); - getAdaptableRegistry().register(paragraph, e); - return paragraph; - } - - public ITextSpan createTextSpan(String textContent) { - Text t = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() - .createTextNode(textContent); - TextSpanImpl text = new TextSpanImpl(t, this); - getAdaptableRegistry().register(text, t); - return text; - } - - public List getParagraphs() { - return DOMUtils.getChildList(getImplementation(), TAG_P, this); - } - - public void removeParagraph(IParagraph paragraph) { - ParagraphImpl p = (ParagraphImpl) paragraph; - if (p.getImplementation().getParentNode() == getImplementation()) { - if (!isOrphan()) { - p.removeNotify((WorkbookImpl) getOwnedWorkbook()); - } - getImplementation().removeChild(p.getImplementation()); - updateModifiedTime(); - } - } - -// protected ElementRegistry getElementRegistry() { -// return ((WorkbookImpl) getOwnedWorkbook()).getElementRegistry(); -// } - - protected NodeAdaptableRegistry getAdaptableRegistry() { - return ((WorkbookImpl) getOwnedWorkbook()).getAdaptableRegistry(); - } - - public IAdaptable getAdaptable(Node node) { - if (node == null) - return null; - - IAdaptable element = getAdaptableRegistry().getAdaptable(node); - if (element == null) { - if (node instanceof Element) { - Element e = (Element) node; - String tagName = e.getTagName(); - if (TAG_P.equals(tagName)) { - element = new ParagraphImpl(e, this); - } else if (DOMConstants.TAG_SPAN.equals(tagName)) { - element = new TextSpanImpl(e, this); - } else if (DOMConstants.TAG_IMG.equals(tagName)) { - element = new ImageSpanImpl(e, this); - } else if (DOMConstants.TAG_A.equals(tagName)) { - element = new HyperlinkSpanImpl(e, this); - } - } else { - Node p = node.getParentNode(); - if (p instanceof Element) { - if (TAG_P.equals(p.getNodeName()) - || TAG_A.equals(p.getNodeName())) - element = new TextSpanImpl(node, this); - } - } - if (element != null) { - getAdaptableRegistry().register(element, node); - } - } - return element; - } - - protected void addNotify(WorkbookImpl workbook) { - for (IParagraph p : getParagraphs()) { - ((ParagraphImpl) p).addNotify(workbook); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - for (IParagraph p : getParagraphs()) { - ((ParagraphImpl) p).removeNotify(workbook); - } - } - - protected WorkbookImpl getRealizedWorkbook() { - INotes parent = getParent(); - if (parent instanceof NotesImpl) - return ((NotesImpl) parent).getRealizedWorkbook(); - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_A; +import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; +import static org.xmind.core.internal.dom.DOMConstants.TAG_P; + +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.Text; +import org.xmind.core.IAdaptable; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IHyperlinkSpan; +import org.xmind.core.IImageSpan; +import org.xmind.core.INotes; +import org.xmind.core.IParagraph; +import org.xmind.core.ITextSpan; +import org.xmind.core.util.DOMUtils; + +public class HtmlNotesContentImpl extends BaseNotesContentImpl implements + IHtmlNotesContent, INodeAdaptableProvider { + + public HtmlNotesContentImpl(Element implementation, + WorkbookImpl ownedWorkbook) { + super(implementation, ownedWorkbook); + } + + public void addParagraph(IParagraph paragraph) { + ParagraphImpl p = (ParagraphImpl) paragraph; + getImplementation().appendChild(p.getImplementation()); + if (!isOrphan()) { + p.addNotify((WorkbookImpl) getOwnedWorkbook()); + } + updateModifiedTime(); + } + + public IImageSpan createImageSpan(String source) { + Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() + .createElement(TAG_IMG); + ImageSpanImpl image = new ImageSpanImpl(e, this); + image.setSource(source); + getAdaptableRegistry().register(image, e); + return image; + } + + public IHyperlinkSpan createHyperlinkSpan(String sourceHyper) { + Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() + .createElement(TAG_A); + HyperlinkSpanImpl hyperlink = new HyperlinkSpanImpl(e, this); + hyperlink.setHref(sourceHyper); + getAdaptableRegistry().register(hyperlink, e); + return hyperlink; + } + + public IParagraph createParagraph() { + Element e = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() + .createElement(DOMConstants.TAG_P); + ParagraphImpl paragraph = new ParagraphImpl(e, this); + getAdaptableRegistry().register(paragraph, e); + return paragraph; + } + + public ITextSpan createTextSpan(String textContent) { + Text t = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() + .createTextNode(textContent); + TextSpanImpl text = new TextSpanImpl(t, this); + getAdaptableRegistry().register(text, t); + return text; + } + + public List getParagraphs() { + return DOMUtils.getChildList(getImplementation(), TAG_P, this); + } + + public void removeParagraph(IParagraph paragraph) { + ParagraphImpl p = (ParagraphImpl) paragraph; + if (p.getImplementation().getParentNode() == getImplementation()) { + if (!isOrphan()) { + p.removeNotify((WorkbookImpl) getOwnedWorkbook()); + } + getImplementation().removeChild(p.getImplementation()); + updateModifiedTime(); + } + } + +// protected ElementRegistry getElementRegistry() { +// return ((WorkbookImpl) getOwnedWorkbook()).getElementRegistry(); +// } + + protected NodeAdaptableRegistry getAdaptableRegistry() { + return ((WorkbookImpl) getOwnedWorkbook()).getAdaptableRegistry(); + } + + public IAdaptable getAdaptable(Node node) { + if (node == null) + return null; + + IAdaptable element = getAdaptableRegistry().getAdaptable(node); + if (element == null) { + if (node instanceof Element) { + Element e = (Element) node; + String tagName = e.getTagName(); + if (TAG_P.equals(tagName)) { + element = new ParagraphImpl(e, this); + } else if (DOMConstants.TAG_SPAN.equals(tagName)) { + element = new TextSpanImpl(e, this); + } else if (DOMConstants.TAG_IMG.equals(tagName)) { + element = new ImageSpanImpl(e, this); + } else if (DOMConstants.TAG_A.equals(tagName)) { + element = new HyperlinkSpanImpl(e, this); + } + } else { + Node p = node.getParentNode(); + if (p instanceof Element) { + if (TAG_P.equals(p.getNodeName()) + || TAG_A.equals(p.getNodeName())) + element = new TextSpanImpl(node, this); + } + } + if (element != null) { + getAdaptableRegistry().register(element, node); + } + } + return element; + } + + protected void addNotify(WorkbookImpl workbook) { + for (IParagraph p : getParagraphs()) { + ((ParagraphImpl) p).addNotify(workbook); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + for (IParagraph p : getParagraphs()) { + ((ParagraphImpl) p).removeNotify(workbook); + } + } + + protected WorkbookImpl getRealizedWorkbook() { + INotes parent = getParent(); + if (parent instanceof NotesImpl) + return ((NotesImpl) parent).getRealizedWorkbook(); + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/IDKey.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/IDKey.java index d3c132bd1..505863a2d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/IDKey.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/IDKey.java @@ -1,60 +1,60 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal.dom; - -import org.w3c.dom.Document; - -/** - * Bind element ID with its owner document, so that same IDs in different - * documents will be corresponded to different objects. - * - * @author Frank Shaka - */ -public class IDKey { - public Document document; - public String id; - - public IDKey(Document document, String id) { - super(); - this.document = document; - this.id = id; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return document.hashCode() ^ id.hashCode(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof IDKey)) - return false; - IDKey that = (IDKey) obj; - return this.document.equals(that.document) - && this.id.equals(that.id); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal.dom; + +import org.w3c.dom.Document; + +/** + * Bind element ID with its owner document, so that same IDs in different + * documents will be corresponded to different objects. + * + * @author Frank Shaka + */ +public class IDKey { + public Document document; + public String id; + + public IDKey(Document document, String id) { + super(); + this.document = document; + this.id = id; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return document.hashCode() ^ id.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof IDKey)) + return false; + IDKey that = (IDKey) obj; + return this.document.equals(that.document) + && this.id.equals(that.id); + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableFactory.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableFactory.java index 652718c76..3562e106f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableFactory.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableFactory.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; - -public interface INodeAdaptableFactory { - - IAdaptable createAdaptable(Node node); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; + +public interface INodeAdaptableFactory { + + IAdaptable createAdaptable(Node node); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableProvider.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableProvider.java index 253b51a4c..a55110488 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableProvider.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/INodeAdaptableProvider.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; - -public interface INodeAdaptableProvider { - - IAdaptable getAdaptable(Node node); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; + +public interface INodeAdaptableProvider { + + IAdaptable getAdaptable(Node node); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageImpl.java index 0a79e815a..8f8f58d78 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageImpl.java @@ -1,227 +1,227 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALIGN; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HEIGHT; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; -import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; -import static org.xmind.core.internal.dom.NumberUtils.safeParseInt; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Image; -import org.xmind.core.util.DOMUtils; - -public class ImageImpl extends Image implements ICoreEventSource { - - private Element topicElement; - - private TopicImpl ownedTopic; - - public ImageImpl(Element topicElement, TopicImpl ownedTopic) { - this.topicElement = topicElement; - this.ownedTopic = ownedTopic; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof ImageImpl)) - return false; - ImageImpl that = (ImageImpl) obj; - return this.topicElement == that.topicElement; - } - - public int hashCode() { - return topicElement.hashCode(); - } - - public String toString() { - return DOMUtils.toString(getImageElement()); - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getImageElement()); - return super.getAdapter(adapter); - } - - private Element getImageElement() { - return DOMUtils.getFirstChildElementByTag(topicElement, TAG_IMG); - } - - public String getAlignment() { - Element img = getImageElement(); - return img == null ? null : DOMUtils.getAttribute(img, ATTR_ALIGN); - } - - public int getHeight() { - Element img = getImageElement(); - if (img == null) - return UNSPECIFIED; - return safeParseInt(DOMUtils.getAttribute(img, ATTR_HEIGHT), - UNSPECIFIED); - } - - private Integer getHeightInt() { - int h = getHeight(); - return h < 0 ? null : Integer.valueOf(h); - } - - private Integer getWidthInt() { - int w = getWidth(); - return w < 0 ? null : Integer.valueOf(w); - } - - public ITopic getParent() { - return ownedTopic; - } - - public String getSource() { - Element img = getImageElement(); - return img == null ? null : DOMUtils.getAttribute(img, ATTR_SRC); - } - - public int getWidth() { - Element img = getImageElement(); - if (img == null) - return UNSPECIFIED; - return safeParseInt(DOMUtils.getAttribute(img, ATTR_WIDTH), - UNSPECIFIED); - } - - private Element ensureImageElement() { - return DOMUtils.ensureChildElement(topicElement, TAG_IMG); - } - - public void setAlignment(String alignment) { - String oldValue = getAlignment(); - Element img = ensureImageElement(); - DOMUtils.setAttribute(img, ATTR_ALIGN, alignment); - checkImageElement(); - String newValue = getAlignment(); - fireValueChange(Core.ImageAlignment, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setHeight(int height) { - Integer oldValue = getHeightInt(); - Element img = ensureImageElement(); - String h = height < 0 ? null : Integer.toString(height); - DOMUtils.setAttribute(img, ATTR_HEIGHT, h); - checkImageElement(); - Integer newValue = getHeightInt(); - fireValueChange(Core.ImageHeight, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setSize(int width, int height) { - Integer oldWidth = getWidthInt(); - Integer oldHeight = getHeightInt(); - Element img = ensureImageElement(); - String h = height < 0 ? null : Integer.toString(height); - String w = width < 0 ? null : Integer.toString(width); - DOMUtils.setAttribute(img, ATTR_HEIGHT, h); - DOMUtils.setAttribute(img, ATTR_WIDTH, w); - checkImageElement(); - Integer newWidth = getWidthInt(); - Integer newHeight = getHeightInt(); - fireValueChange(Core.ImageWidth, oldWidth, newWidth); - fireValueChange(Core.ImageHeight, oldHeight, newHeight); - ownedTopic.updateModificationInfo(); - } - - public void setSource(String source) { - String oldValue = getSource(); - Element img = ensureImageElement(); - IWorkbook workbook = ownedTopic.getPath().getWorkbook(); - deactivateHyperlink(workbook); - DOMUtils.setAttribute(img, ATTR_SRC, source); - activateHyperlink(workbook); - checkImageElement(); - String newValue = getSource(); - fireValueChange(Core.ImageSource, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setWidth(int width) { - Integer oldValue = getWidthInt(); - Element img = ensureImageElement(); - String w = width < 0 ? null : Integer.toString(width); - DOMUtils.setAttribute(img, ATTR_WIDTH, w); - checkImageElement(); - Integer newValue = getWidthInt(); - fireValueChange(Core.ImageWidth, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - private void checkImageElement() { - Element img = getImageElement(); - if (!img.hasChildNodes() && !img.hasAttributes()) { - topicElement.removeChild(img); - } - } - - public ISheet getOwnedSheet() { - return ownedTopic.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedTopic.getOwnedWorkbook(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return ownedTopic.isOrphan() || getImageElement() == null; - } - - private void fireValueChange(String eventType, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, - newValue); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedTopic.getCoreEventSupport(); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - protected void activateHyperlink(IWorkbook workbook) { - InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); - } - - protected void deactivateHyperlink(IWorkbook workbook) { - InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ALIGN; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HEIGHT; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; +import static org.xmind.core.internal.dom.DOMConstants.TAG_IMG; +import static org.xmind.core.internal.dom.NumberUtils.safeParseInt; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Image; +import org.xmind.core.util.DOMUtils; + +public class ImageImpl extends Image implements ICoreEventSource { + + private Element topicElement; + + private TopicImpl ownedTopic; + + public ImageImpl(Element topicElement, TopicImpl ownedTopic) { + this.topicElement = topicElement; + this.ownedTopic = ownedTopic; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof ImageImpl)) + return false; + ImageImpl that = (ImageImpl) obj; + return this.topicElement == that.topicElement; + } + + public int hashCode() { + return topicElement.hashCode(); + } + + public String toString() { + return DOMUtils.toString(getImageElement()); + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImageElement()); + return super.getAdapter(adapter); + } + + private Element getImageElement() { + return DOMUtils.getFirstChildElementByTag(topicElement, TAG_IMG); + } + + public String getAlignment() { + Element img = getImageElement(); + return img == null ? null : DOMUtils.getAttribute(img, ATTR_ALIGN); + } + + public int getHeight() { + Element img = getImageElement(); + if (img == null) + return UNSPECIFIED; + return safeParseInt(DOMUtils.getAttribute(img, ATTR_HEIGHT), + UNSPECIFIED); + } + + private Integer getHeightInt() { + int h = getHeight(); + return h < 0 ? null : Integer.valueOf(h); + } + + private Integer getWidthInt() { + int w = getWidth(); + return w < 0 ? null : Integer.valueOf(w); + } + + public ITopic getParent() { + return ownedTopic; + } + + public String getSource() { + Element img = getImageElement(); + return img == null ? null : DOMUtils.getAttribute(img, ATTR_SRC); + } + + public int getWidth() { + Element img = getImageElement(); + if (img == null) + return UNSPECIFIED; + return safeParseInt(DOMUtils.getAttribute(img, ATTR_WIDTH), + UNSPECIFIED); + } + + private Element ensureImageElement() { + return DOMUtils.ensureChildElement(topicElement, TAG_IMG); + } + + public void setAlignment(String alignment) { + String oldValue = getAlignment(); + Element img = ensureImageElement(); + DOMUtils.setAttribute(img, ATTR_ALIGN, alignment); + checkImageElement(); + String newValue = getAlignment(); + fireValueChange(Core.ImageAlignment, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setHeight(int height) { + Integer oldValue = getHeightInt(); + Element img = ensureImageElement(); + String h = height < 0 ? null : Integer.toString(height); + DOMUtils.setAttribute(img, ATTR_HEIGHT, h); + checkImageElement(); + Integer newValue = getHeightInt(); + fireValueChange(Core.ImageHeight, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setSize(int width, int height) { + Integer oldWidth = getWidthInt(); + Integer oldHeight = getHeightInt(); + Element img = ensureImageElement(); + String h = height < 0 ? null : Integer.toString(height); + String w = width < 0 ? null : Integer.toString(width); + DOMUtils.setAttribute(img, ATTR_HEIGHT, h); + DOMUtils.setAttribute(img, ATTR_WIDTH, w); + checkImageElement(); + Integer newWidth = getWidthInt(); + Integer newHeight = getHeightInt(); + fireValueChange(Core.ImageWidth, oldWidth, newWidth); + fireValueChange(Core.ImageHeight, oldHeight, newHeight); + ownedTopic.updateModificationInfo(); + } + + public void setSource(String source) { + String oldValue = getSource(); + Element img = ensureImageElement(); + IWorkbook workbook = ownedTopic.getPath().getWorkbook(); + deactivateHyperlink(workbook); + DOMUtils.setAttribute(img, ATTR_SRC, source); + activateHyperlink(workbook); + checkImageElement(); + String newValue = getSource(); + fireValueChange(Core.ImageSource, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setWidth(int width) { + Integer oldValue = getWidthInt(); + Element img = ensureImageElement(); + String w = width < 0 ? null : Integer.toString(width); + DOMUtils.setAttribute(img, ATTR_WIDTH, w); + checkImageElement(); + Integer newValue = getWidthInt(); + fireValueChange(Core.ImageWidth, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + private void checkImageElement() { + Element img = getImageElement(); + if (!img.hasChildNodes() && !img.hasAttributes()) { + topicElement.removeChild(img); + } + } + + public ISheet getOwnedSheet() { + return ownedTopic.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedTopic.getOwnedWorkbook(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return ownedTopic.isOrphan() || getImageElement() == null; + } + + private void fireValueChange(String eventType, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, + newValue); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedTopic.getCoreEventSupport(); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + protected void activateHyperlink(IWorkbook workbook) { + InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); + } + + protected void deactivateHyperlink(IWorkbook workbook) { + InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageSpanImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageSpanImpl.java index a5b91f64a..f2119b7a1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageSpanImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ImageSpanImpl.java @@ -1,49 +1,49 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; - -import org.w3c.dom.Element; -import org.xmind.core.IImageSpan; -import org.xmind.core.util.DOMUtils; - -public class ImageSpanImpl extends SpanImplBase implements IImageSpan { - - public ImageSpanImpl(Element implementation, HtmlNotesContentImpl owner) { - super(implementation, owner); - } - - public String getSource() { - return DOMUtils.getAttribute((Element) getImplementation(), ATTR_SRC); - } - - public void setSource(String source) { - WorkbookImpl workbook = getOwner().getRealizedWorkbook(); - InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); - DOMUtils.setAttribute((Element) getImplementation(), ATTR_SRC, source); - InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); - getOwner().updateModifiedTime(); - } - - protected void addNotify(WorkbookImpl workbook) { - super.addNotify(workbook); - InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); - } - - protected void removeNotify(WorkbookImpl workbook) { - InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); - super.removeNotify(workbook); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SRC; + +import org.w3c.dom.Element; +import org.xmind.core.IImageSpan; +import org.xmind.core.util.DOMUtils; + +public class ImageSpanImpl extends SpanImplBase implements IImageSpan { + + public ImageSpanImpl(Element implementation, HtmlNotesContentImpl owner) { + super(implementation, owner); + } + + public String getSource() { + return DOMUtils.getAttribute((Element) getImplementation(), ATTR_SRC); + } + + public void setSource(String source) { + WorkbookImpl workbook = getOwner().getRealizedWorkbook(); + InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); + DOMUtils.setAttribute((Element) getImplementation(), ATTR_SRC, source); + InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); + getOwner().updateModifiedTime(); + } + + protected void addNotify(WorkbookImpl workbook) { + super.addNotify(workbook); + InternalHyperlinkUtils.activateHyperlink(workbook, getSource(), this); + } + + protected void removeNotify(WorkbookImpl workbook) { + InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); + super.removeNotify(workbook); + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalDOMUtils.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalDOMUtils.java index 17b30f48a..628c78903 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalDOMUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalDOMUtils.java @@ -1,218 +1,218 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.IAdaptable; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.util.DOMUtils; - -/** - * @author briansun - * - */ -public class InternalDOMUtils { - - public static void addVersion(Document document) { - Element element = document.getDocumentElement(); - if (element != null && !element.hasAttribute(ATTR_VERSION)) { - DOMUtils.setAttribute(element, ATTR_VERSION, - Core.getCurrentVersion()); - } - } - - public static void replaceVersion(Document document) { - Element element = document.getDocumentElement(); - if (element != null) { - DOMUtils.setAttribute(element, ATTR_VERSION, - Core.getCurrentVersion()); - } - } - - public static String getParentPath(String path) { - int i; - if (path.endsWith("/")) { //$NON-NLS-1$ - i = path.lastIndexOf('/', path.length() - 2); - } else { - i = path.lastIndexOf('/'); - } - if (i < 0) - return null; - return path.substring(0, i + 1); - } - - public static String getLastName(String path) { - String parent = getParentPath(path); - if (parent != null) { - return path.substring(parent.length()); - } - return path; - } - - public static boolean isParentPath(String path, String parentPath) { - return path.startsWith(parentPath); - } - - public static String trim(String text) { - return text == null ? null : text.trim(); - } - - public static String trimElementContent(String text, String tagName) { - int start = text.indexOf("<" + tagName + " "); //$NON-NLS-1$ //$NON-NLS-2$ - if (start < 0) { - start = text.indexOf("<" + tagName + ">"); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (start >= 0) { - start = text.indexOf('>', start + 1); - if (start > 0) { - int i = start - 1; - // prevent element like '' - while (text.charAt(i) != '<') { - if (text.charAt(i) == '/') - return null; - i--; - } - } - start++; - } - int end = text.lastIndexOf(""); //$NON-NLS-1$ //$NON-NLS-2$ - if (start > 0 || (end >= 0 && end < text.length())) - return text.substring(start, end); - return text; - } - - public static String makeElementText(String text, NS defaultNS, - String tagName, NS... nss) { - if (tagName != null) { - if (text.indexOf("<" + tagName) < 0) { //$NON-NLS-1$ - StringBuffer sb = new StringBuffer( - tagName.length() - + (defaultNS != null - ? defaultNS.getURI().length() : 0) - + nss.length * 20 + 2); - sb.append('<'); - sb.append(tagName); - if (defaultNS != null) { - sb.append(" xmlns=\""); //$NON-NLS-1$ - sb.append(defaultNS.getURI()); - sb.append('\"'); - } - for (NS ns : nss) { - sb.append(" xmlns:"); //$NON-NLS-1$ - sb.append(ns.getPrefix()); - sb.append('='); - sb.append('\"'); - sb.append(ns.getURI()); - sb.append('\"'); - } - sb.append('>'); - sb.append(text); - sb.append('<'); - sb.append('/'); - sb.append(tagName); - sb.append('>'); - return sb.toString(); - } - } - return text; - } - - public static String toRangeValue(int startIndex, int endIndex) { - if (startIndex >= 0 || endIndex >= 0) { - StringBuilder sb = new StringBuilder(); - sb.append('('); - if (startIndex >= 0) - sb.append(startIndex); - sb.append(','); - if (endIndex >= 0) - sb.append(endIndex); - sb.append(')'); - return sb.toString(); - } - return null; - } - - public static int getStartIndex(String rangeValue) { - if (rangeValue != null && rangeValue.startsWith("(") //$NON-NLS-1$ - && rangeValue.endsWith(")")) { //$NON-NLS-1$ - int sep = rangeValue.indexOf(','); - if (sep > 0) { - String startIndexValue = rangeValue.substring(1, sep).trim(); - int index = NumberUtils.safeParseInt(startIndexValue, -1); - return index < 0 ? -1 : index; - } - } - return -1; - } - - public static int getEndIndex(String rangeValue) { - if (rangeValue != null && rangeValue.startsWith("(") //$NON-NLS-1$ - && rangeValue.endsWith(")")) { //$NON-NLS-1$ - int sep = rangeValue.lastIndexOf(','); - if (sep > 0) { - String endIndexValue = rangeValue - .substring(sep + 1, rangeValue.length() - 1).trim(); - int index = NumberUtils.safeParseInt(endIndexValue, -1); - return index < 0 ? -1 : index; - } - } - return -1; - } - - public static void updateModificationInfo(IAdaptable obj) { - Element ele = (Element) obj.getAdapter(Element.class); - if (ele == null) - return; - - long oldTime = getModifiedTime(obj, ele); - long newTime = System.currentTimeMillis(); - DOMUtils.setAttribute(ele, DOMConstants.ATTR_TIMESTAMP, - Long.toString(newTime)); - - DOMUtils.setAttribute(ele, DOMConstants.ATTR_MODIFYBY, null); - DOMUtils.setAttribute(ele, DOMConstants.ATTR_MODIFIED_BY, - getDefaultModifierName()); - - ICoreEventSupport eventSupport = (ICoreEventSupport) obj - .getAdapter(ICoreEventSupport.class); - if (eventSupport != null && obj instanceof ICoreEventSource) { - eventSupport.dispatchValueChange((ICoreEventSource) obj, - Core.ModifyTime, Long.valueOf(oldTime), - Long.valueOf(newTime)); - } - } - - public static long getModifiedTime(IAdaptable obj, Element ele) { - String time = DOMUtils.getAttribute(ele, DOMConstants.ATTR_TIMESTAMP); - return NumberUtils.safeParseLong(time, 0); - } - - public static String getModifiedBy(IAdaptable obj, Element ele) { - String name = DOMUtils.getAttribute(ele, DOMConstants.ATTR_MODIFIED_BY); - if (name != null) - return name; - return DOMUtils.getAttribute(ele, DOMConstants.ATTR_MODIFYBY); - } - - public static String getDefaultModifierName() { - String name = System.getProperty(DOMConstants.AUTHOR_NAME); - return name != null ? name : System.getProperty("user.name"); //$NON-NLS-1$ - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.util.DOMUtils; + +/** + * @author briansun + * + */ +public class InternalDOMUtils { + + public static void addVersion(Document document) { + Element element = document.getDocumentElement(); + if (element != null && !element.hasAttribute(ATTR_VERSION)) { + DOMUtils.setAttribute(element, ATTR_VERSION, + Core.getCurrentVersion()); + } + } + + public static void replaceVersion(Document document) { + Element element = document.getDocumentElement(); + if (element != null) { + DOMUtils.setAttribute(element, ATTR_VERSION, + Core.getCurrentVersion()); + } + } + + public static String getParentPath(String path) { + int i; + if (path.endsWith("/")) { //$NON-NLS-1$ + i = path.lastIndexOf('/', path.length() - 2); + } else { + i = path.lastIndexOf('/'); + } + if (i < 0) + return null; + return path.substring(0, i + 1); + } + + public static String getLastName(String path) { + String parent = getParentPath(path); + if (parent != null) { + return path.substring(parent.length()); + } + return path; + } + + public static boolean isParentPath(String path, String parentPath) { + return path.startsWith(parentPath); + } + + public static String trim(String text) { + return text == null ? null : text.trim(); + } + + public static String trimElementContent(String text, String tagName) { + int start = text.indexOf("<" + tagName + " "); //$NON-NLS-1$ //$NON-NLS-2$ + if (start < 0) { + start = text.indexOf("<" + tagName + ">"); //$NON-NLS-1$ //$NON-NLS-2$ + } + if (start >= 0) { + start = text.indexOf('>', start + 1); + if (start > 0) { + int i = start - 1; + // prevent element like '' + while (text.charAt(i) != '<') { + if (text.charAt(i) == '/') + return null; + i--; + } + } + start++; + } + int end = text.lastIndexOf(""); //$NON-NLS-1$ //$NON-NLS-2$ + if (start > 0 || (end >= 0 && end < text.length())) + return text.substring(start, end); + return text; + } + + public static String makeElementText(String text, NS defaultNS, + String tagName, NS... nss) { + if (tagName != null) { + if (text.indexOf("<" + tagName) < 0) { //$NON-NLS-1$ + StringBuffer sb = new StringBuffer( + tagName.length() + + (defaultNS != null + ? defaultNS.getURI().length() : 0) + + nss.length * 20 + 2); + sb.append('<'); + sb.append(tagName); + if (defaultNS != null) { + sb.append(" xmlns=\""); //$NON-NLS-1$ + sb.append(defaultNS.getURI()); + sb.append('\"'); + } + for (NS ns : nss) { + sb.append(" xmlns:"); //$NON-NLS-1$ + sb.append(ns.getPrefix()); + sb.append('='); + sb.append('\"'); + sb.append(ns.getURI()); + sb.append('\"'); + } + sb.append('>'); + sb.append(text); + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + return sb.toString(); + } + } + return text; + } + + public static String toRangeValue(int startIndex, int endIndex) { + if (startIndex >= 0 || endIndex >= 0) { + StringBuilder sb = new StringBuilder(); + sb.append('('); + if (startIndex >= 0) + sb.append(startIndex); + sb.append(','); + if (endIndex >= 0) + sb.append(endIndex); + sb.append(')'); + return sb.toString(); + } + return null; + } + + public static int getStartIndex(String rangeValue) { + if (rangeValue != null && rangeValue.startsWith("(") //$NON-NLS-1$ + && rangeValue.endsWith(")")) { //$NON-NLS-1$ + int sep = rangeValue.indexOf(','); + if (sep > 0) { + String startIndexValue = rangeValue.substring(1, sep).trim(); + int index = NumberUtils.safeParseInt(startIndexValue, -1); + return index < 0 ? -1 : index; + } + } + return -1; + } + + public static int getEndIndex(String rangeValue) { + if (rangeValue != null && rangeValue.startsWith("(") //$NON-NLS-1$ + && rangeValue.endsWith(")")) { //$NON-NLS-1$ + int sep = rangeValue.lastIndexOf(','); + if (sep > 0) { + String endIndexValue = rangeValue + .substring(sep + 1, rangeValue.length() - 1).trim(); + int index = NumberUtils.safeParseInt(endIndexValue, -1); + return index < 0 ? -1 : index; + } + } + return -1; + } + + public static void updateModificationInfo(IAdaptable obj) { + Element ele = (Element) obj.getAdapter(Element.class); + if (ele == null) + return; + + long oldTime = getModifiedTime(obj, ele); + long newTime = System.currentTimeMillis(); + DOMUtils.setAttribute(ele, DOMConstants.ATTR_TIMESTAMP, + Long.toString(newTime)); + + DOMUtils.setAttribute(ele, DOMConstants.ATTR_MODIFYBY, null); + DOMUtils.setAttribute(ele, DOMConstants.ATTR_MODIFIED_BY, + getDefaultModifierName()); + + ICoreEventSupport eventSupport = (ICoreEventSupport) obj + .getAdapter(ICoreEventSupport.class); + if (eventSupport != null && obj instanceof ICoreEventSource) { + eventSupport.dispatchValueChange((ICoreEventSource) obj, + Core.ModifyTime, Long.valueOf(oldTime), + Long.valueOf(newTime)); + } + } + + public static long getModifiedTime(IAdaptable obj, Element ele) { + String time = DOMUtils.getAttribute(ele, DOMConstants.ATTR_TIMESTAMP); + return NumberUtils.safeParseLong(time, 0); + } + + public static String getModifiedBy(IAdaptable obj, Element ele) { + String name = DOMUtils.getAttribute(ele, DOMConstants.ATTR_MODIFIED_BY); + if (name != null) + return name; + return DOMUtils.getAttribute(ele, DOMConstants.ATTR_MODIFYBY); + } + + public static String getDefaultModifierName() { + String name = System.getProperty(DOMConstants.AUTHOR_NAME); + return name != null ? name : System.getProperty("user.name"); //$NON-NLS-1$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalHyperlinkUtils.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalHyperlinkUtils.java index 926f32818..e71e02522 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalHyperlinkUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/InternalHyperlinkUtils.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.IOException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; -import org.xmind.core.IFileEntry; -import org.xmind.core.IIdentifiable; -import org.xmind.core.IManifest; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookComponentRefManager; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.HyperlinkUtils; - -public class InternalHyperlinkUtils { - - private static boolean isInWorkingRevision(IAdaptable object) { - Node node = (Node) object.getAdapter(Node.class); - if (node != null) { - Document doc = DOMUtils.getOwnerDocument(node); - if (doc != null) { - Element docEle = doc.getDocumentElement(); - if (docEle != null) { - return !DOMConstants.TAG_REVISION_CONTENT.equals(docEle - .getNodeName()); - } - } - } - return true; - } - - public static void activateHyperlink(IWorkbook workbook, String url, - IAdaptable source) { - if (workbook != null) { - if (HyperlinkUtils.isAttachmentURL(url)) { - if (isInWorkingRevision(source)) { - String attPath = HyperlinkUtils.toAttachmentPath(url); - increaseFileEntryRef(workbook, attPath); - } - } else if (HyperlinkUtils.isInternalURL(url)) { - if (source instanceof IIdentifiable) { - String sourceId = ((IIdentifiable) source).getId(); - String id = HyperlinkUtils.toElementID(url); - increateElementRef(workbook, id, sourceId); - } - } - } - } - - public static void increaseFileEntryRef(IWorkbook workbook, String entryPath) { - if (workbook != null && entryPath != null) { - IFileEntry e = workbook.getManifest().getFileEntry(entryPath); - if (e != null) { - e.increaseReference(); - if (e.isDirectory()) { - for (IFileEntry sub : e.getSubEntries()) { - sub.increaseReference(); - } - } - } - } - } - - public static void increateElementRef(IWorkbook workbook, String elementId, - String sourceId) { - if (workbook != null && elementId != null) { - IWorkbookComponentRefManager counter = (IWorkbookComponentRefManager) workbook - .getAdapter(IWorkbookComponentRefManager.class); - if (counter != null) { - counter.increaseRef(sourceId, elementId); - } - } - } - - public static void deactivateHyperlink(IWorkbook workbook, String url, - IAdaptable source) { - if (workbook != null) { - if (HyperlinkUtils.isAttachmentURL(url)) { - if (isInWorkingRevision(source)) { - String attPath = HyperlinkUtils.toAttachmentPath(url); - decreaseFileEntryRef(workbook, attPath); - } - } else if (HyperlinkUtils.isInternalURL(url)) { - if (source instanceof IIdentifiable) { - String sourceId = ((IIdentifiable) source).getId(); - String elementId = HyperlinkUtils.toElementID(url); - decreaseElementRef(workbook, elementId, sourceId); - } - } - } - } - - public static void decreaseFileEntryRef(IWorkbook workbook, String entryPath) { - if (workbook != null && entryPath != null) { - IFileEntry e = workbook.getManifest().getFileEntry(entryPath); - if (e != null) { - e.decreaseReference(); - if (e.isDirectory()) { - for (IFileEntry sub : e.getSubEntries()) { - sub.decreaseReference(); - } - } - } - } - } - - public static void decreaseElementRef(IWorkbook workbook, String elementId, - String sourceId) { - if (workbook != null && elementId != null) { - IWorkbookComponentRefManager counter = (IWorkbookComponentRefManager) workbook - .getAdapter(IWorkbookComponentRefManager.class); - if (counter != null) { - counter.decreaseRef(sourceId, elementId); - } - } - } - - public static String importAttachmentURL(String sourceHyperlink, - IWorkbook sourceWorkbook, IWorkbook targetWorkbook) - throws IOException { - String sourcePath = HyperlinkUtils.toAttachmentPath(sourceHyperlink); - String targetPath = importAttachment(sourcePath, sourceWorkbook, - targetWorkbook); - return HyperlinkUtils.toAttachmentURL(targetPath); - } - - public static String importAttachment(String sourcePath, - IWorkbook sourceWorkbook, IWorkbook targetWorkbook) - throws IOException { - IFileEntry sourceEntry = sourceWorkbook.getManifest().getFileEntry( - sourcePath); - if (sourceEntry != null) { - IManifest manifest = targetWorkbook.getManifest(); - IFileEntry targetEntry = manifest - .cloneEntryAsAttachment(sourceEntry); - if (targetEntry != null) { - return targetEntry.getPath(); - } - } - return sourcePath; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.IOException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; +import org.xmind.core.IFileEntry; +import org.xmind.core.IIdentifiable; +import org.xmind.core.IManifest; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookComponentRefManager; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.HyperlinkUtils; + +public class InternalHyperlinkUtils { + + private static boolean isInWorkingRevision(IAdaptable object) { + Node node = (Node) object.getAdapter(Node.class); + if (node != null) { + Document doc = DOMUtils.getOwnerDocument(node); + if (doc != null) { + Element docEle = doc.getDocumentElement(); + if (docEle != null) { + return !DOMConstants.TAG_REVISION_CONTENT.equals(docEle + .getNodeName()); + } + } + } + return true; + } + + public static void activateHyperlink(IWorkbook workbook, String url, + IAdaptable source) { + if (workbook != null) { + if (HyperlinkUtils.isAttachmentURL(url)) { + if (isInWorkingRevision(source)) { + String attPath = HyperlinkUtils.toAttachmentPath(url); + increaseFileEntryRef(workbook, attPath); + } + } else if (HyperlinkUtils.isInternalURL(url)) { + if (source instanceof IIdentifiable) { + String sourceId = ((IIdentifiable) source).getId(); + String id = HyperlinkUtils.toElementID(url); + increateElementRef(workbook, id, sourceId); + } + } + } + } + + public static void increaseFileEntryRef(IWorkbook workbook, String entryPath) { + if (workbook != null && entryPath != null) { + IFileEntry e = workbook.getManifest().getFileEntry(entryPath); + if (e != null) { + e.increaseReference(); + if (e.isDirectory()) { + for (IFileEntry sub : e.getSubEntries()) { + sub.increaseReference(); + } + } + } + } + } + + public static void increateElementRef(IWorkbook workbook, String elementId, + String sourceId) { + if (workbook != null && elementId != null) { + IWorkbookComponentRefManager counter = (IWorkbookComponentRefManager) workbook + .getAdapter(IWorkbookComponentRefManager.class); + if (counter != null) { + counter.increaseRef(sourceId, elementId); + } + } + } + + public static void deactivateHyperlink(IWorkbook workbook, String url, + IAdaptable source) { + if (workbook != null) { + if (HyperlinkUtils.isAttachmentURL(url)) { + if (isInWorkingRevision(source)) { + String attPath = HyperlinkUtils.toAttachmentPath(url); + decreaseFileEntryRef(workbook, attPath); + } + } else if (HyperlinkUtils.isInternalURL(url)) { + if (source instanceof IIdentifiable) { + String sourceId = ((IIdentifiable) source).getId(); + String elementId = HyperlinkUtils.toElementID(url); + decreaseElementRef(workbook, elementId, sourceId); + } + } + } + } + + public static void decreaseFileEntryRef(IWorkbook workbook, String entryPath) { + if (workbook != null && entryPath != null) { + IFileEntry e = workbook.getManifest().getFileEntry(entryPath); + if (e != null) { + e.decreaseReference(); + if (e.isDirectory()) { + for (IFileEntry sub : e.getSubEntries()) { + sub.decreaseReference(); + } + } + } + } + } + + public static void decreaseElementRef(IWorkbook workbook, String elementId, + String sourceId) { + if (workbook != null && elementId != null) { + IWorkbookComponentRefManager counter = (IWorkbookComponentRefManager) workbook + .getAdapter(IWorkbookComponentRefManager.class); + if (counter != null) { + counter.decreaseRef(sourceId, elementId); + } + } + } + + public static String importAttachmentURL(String sourceHyperlink, + IWorkbook sourceWorkbook, IWorkbook targetWorkbook) + throws IOException { + String sourcePath = HyperlinkUtils.toAttachmentPath(sourceHyperlink); + String targetPath = importAttachment(sourcePath, sourceWorkbook, + targetWorkbook); + return HyperlinkUtils.toAttachmentURL(targetPath); + } + + public static String importAttachment(String sourcePath, + IWorkbook sourceWorkbook, IWorkbook targetWorkbook) + throws IOException { + IFileEntry sourceEntry = sourceWorkbook.getManifest().getFileEntry( + sourcePath); + if (sourceEntry != null) { + IManifest manifest = targetWorkbook.getManifest(); + IFileEntry targetEntry = manifest + .cloneEntryAsAttachment(sourceEntry); + if (targetEntry != null) { + return targetEntry.getPath(); + } + } + return sourcePath; + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ManifestImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ManifestImpl.java index 921eb63cd..9c10d9ce3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ManifestImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ManifestImpl.java @@ -1,571 +1,571 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_FULL_PATH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.PASSWORD_HINT; -import static org.xmind.core.internal.dom.DOMConstants.TAG_FILE_ENTRY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MANIFEST; -import static org.xmind.core.internal.dom.InternalDOMUtils.getParentPath; -import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.IEncryptionData; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IFileEntryFilter; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.internal.Manifest; -import org.xmind.core.internal.event.CoreEventSupport; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; - -public class ManifestImpl extends Manifest implements ICoreEventSource { - - private Document implementation; - - private IStorage storage; - - private WorkbookImpl ownedWorkbook; - - private final Map entries; - - private IEntryStreamNormalizer normalizer; - - private CoreEventSupport coreEventSupport; - - public ManifestImpl(Document implementation, IStorage storage) { - this.implementation = implementation; - this.storage = storage == null ? new ByteArrayStorage() : storage; - this.normalizer = IEntryStreamNormalizer.NULL; - this.ownedWorkbook = null; - this.entries = new HashMap(); - init(); - } - - private void init() { - Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); - NS.setNS(NS.Manifest, m); - - // Prefetch all file entries, which makes getAllRegisteredEntries() - // always returns correct value. - for (Iterator it = iterFileEntries(); it.hasNext();) { - it.next(); - } - - IFileEntry metaEntry = createFileEntry(MANIFEST_XML, - Core.MEDIA_TYPE_TEXT_XML); - insertFileEntryImpl(metaEntry.getAdapter(Element.class)); - } - - public Document getImplementation() { - return implementation; - } - - public Element getManifestElement() { - return implementation.getDocumentElement(); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(implementation); - if (IWorkbook.class.equals(adapter)) - return adapter.cast(ownedWorkbook); - return super.getAdapter(adapter); - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return ownedWorkbook == null; - } - - /** - * @param workbook - */ - protected void setWorkbook(WorkbookImpl workbook) { - this.ownedWorkbook = workbook; - if (workbook != null) { - getCoreEventSupport().setParent(workbook.getCoreEventSupport()); - } - } - - protected void setStorage(IStorage storage) { - this.storage = storage == null ? new ByteArrayStorage() : storage; - } - - protected IStorage getStorage() { - return storage; - } - - protected void setStreamNormalizer(IEntryStreamNormalizer normalizer) { - this.normalizer = normalizer == null ? IEntryStreamNormalizer.NULL - : normalizer; - } - - protected IEntryStreamNormalizer getStreamNormalizer() { - return this.normalizer; - } - - protected Collection getAllRegisteredEntries() { - return entries.values(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IManifest#iterFileEntries() - */ - public Iterator iterFileEntries() { - return iterFileEntries(null); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IManifest#iterFileEntries(org.xmind.core.IManifest. - * IFileEntryFilter) - */ - public Iterator iterFileEntries(final IFileEntryFilter filter) { - final Iterator it = DOMUtils - .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); - return new Iterator() { - - IFileEntry next = findNext(); - - private IFileEntry findNext() { - while (it.hasNext()) { - Element e = it.next(); - if (e.hasAttribute(ATTR_FULL_PATH) && select(e)) { - return getFileEntry(e); - } - } - return null; - } - - private boolean select(Element e) { - if (filter == null) - return true; - - String path = e.getAttribute(ATTR_FULL_PATH); - String mediaType = e.getAttribute(ATTR_MEDIA_TYPE); - boolean isDirectory = path.endsWith("/"); //$NON-NLS-1$ - return filter.select(path, mediaType, isDirectory); - } - - public void remove() { - } - - public IFileEntry next() { - IFileEntry n = next; - next = findNext(); - return n; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - public IFileEntry getFileEntry(String path) { - if (path == null) - return null; - IFileEntry entry = findEntry(path); - if (entry == null) { - while (path.startsWith("/")) { //$NON-NLS-1$ - path = path.substring(1, path.length()); - entry = findEntry(path); - if (entry != null) - break; - } - } - if (entry == null) { - entry = findEntry("/" + path); //$NON-NLS-1$ - } - return entry; - } - - private IFileEntry findEntry(String path) { - IFileEntry entry = entries.get(path); - if (entry == null) { - Element e = findEntryElementByPath(path); - if (e != null) - entry = createFileEntry(path, e); - } - return entry; - } - - private Element findEntryElementByPath(String path) { - Iterator it = DOMUtils - .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); - while (it.hasNext()) { - Element e = it.next(); - if (path.equals(e.getAttribute(ATTR_FULL_PATH))) - return e; - } - return null; - } - - public IFileEntry createFileEntry(String path) { - return createFileEntry(path, ""); //$NON-NLS-1$ - } - - public IFileEntry createFileEntry(String path, String mediaType) { - IFileEntry entry = getFileEntry(path); - if (entry != null) - return entry; - - String parent = InternalDOMUtils.getParentPath(path); - if (parent != null) { - IFileEntry parentFileEntry = createFileEntry(parent); - insertFileEntryImpl(parentFileEntry.getAdapter(Element.class)); - } - Element e = implementation.createElement(TAG_FILE_ENTRY); - e.setAttribute(ATTR_FULL_PATH, path); - e.setAttribute(ATTR_MEDIA_TYPE, mediaType); - - return createFileEntry(path, e); - } - - private IFileEntry createFileEntry(String path, Element entryElement) { - IFileEntry entry = new FileEntryImpl(entryElement, this); - entries.put(path, entry); - return entry; - } - - private IFileEntry getFileEntry(Element element) { - String path = element.getAttribute(ATTR_FULL_PATH); - IFileEntry entry = entries.get(path); - if (entry != null) - return entry; - return createFileEntry(path, element); - } - - protected void insertFileEntry(IFileEntry entry) { - Element e = (Element) entry.getAdapter(Element.class); - if (e != null) { - insertFileEntryImpl(e); - } - getCoreEventSupport().dispatchTargetChange(this, Core.FileEntryAdd, - entry); - } - - protected void removeFileEntry(IFileEntry entry) { - Element e = (Element) entry.getAdapter(Element.class); - if (e != null) { - Element m = getManifestElement(); - if (m == e.getParentNode()) - m.removeChild(e); - } - getCoreEventSupport().dispatchTargetChange(this, Core.FileEntryRemove, - entry); - } - - private void insertFileEntryImpl(Element entryElement) { - Element e = findInsertLocation(entryElement); - if (e != null) { - getManifestElement().insertBefore(entryElement, e); - } else { - getManifestElement().appendChild(entryElement); - } - } - - private Element findInsertLocation(Element entryElement) { - if (entryElement.hasAttribute(ATTR_FULL_PATH)) - return findInsertLocation(entryElement, - entryElement.getAttribute(ATTR_FULL_PATH)); - return null; - } - - private Element findInsertLocation(Element entryElement, String path) { - Iterator it = DOMUtils - .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); - while (it.hasNext()) { - Element e = it.next(); - if (e != entryElement && e.hasAttribute(ATTR_FULL_PATH)) { - String p = e.getAttribute(ATTR_FULL_PATH); - if (p != null && path.compareToIgnoreCase(p) < 0) { - return e; - } - } - } - return null; - } - - public IFileEntry createAttachmentFromFilePath(String sourcePath) - throws IOException { - return createAttachmentFromFilePath(sourcePath, null); - } - - public IFileEntry createAttachmentFromFilePath(String sourcePath, - String mediaType) throws IOException { - if (sourcePath == null) - throw new IllegalArgumentException("Path is null!"); //$NON-NLS-1$ - File file = new File(sourcePath); - if (!file.exists()) - throw new FileNotFoundException("Source path does not exists."); //$NON-NLS-1$ - - if (file.isFile()) { - IFileEntry entry = createAttachmentFromStream( - new FileInputStream(sourcePath), sourcePath, mediaType); - if (entry != null) { - entry.setTime(file.lastModified()); - } - return entry; - } - - if (file.isDirectory()) { - String fileName = file.getName(); - String path = makeAttachmentPath(fileName, true); - if (mediaType == null) - mediaType = FileUtils.getMediaType(fileName); - IFileEntry root = createFileEntry(path, mediaType); - if (root != null) { - importDirectory(path, file); - } - return root; - } - - throw new IllegalArgumentException( - "Unknown file type (neither a file nor a directory)"); //$NON-NLS-1$ - } - - protected void importDirectory(String parentPath, File dir) - throws IOException { - for (String sub : dir.list()) { - File f = new File(dir, sub); - if (f.isFile()) { - String path = parentPath == null ? sub : parentPath + sub; - String mediaType = FileUtils.getMediaType(sub); - IFileEntry e = createFileEntry(path, mediaType); - if (e != null) { - e.setTime(f.lastModified()); - OutputStream os = e.openOutputStream(); - try { - FileInputStream is = new FileInputStream(f); - try { - FileUtils.transfer(is, os); - } finally { - is.close(); - } - } finally { - os.close(); - } - } - } else if (f.isDirectory()) { - String path = parentPath == null ? sub + "/" //$NON-NLS-1$ - : parentPath + sub + "/"; //$NON-NLS-1$ - importDirectory(path, f); - } - } - } - - public IFileEntry createAttachmentFromStream(InputStream stream, - String sourceName) throws IOException { - return createAttachmentFromStream(stream, sourceName, null); - } - - public IFileEntry createAttachmentFromStream(InputStream stream, - String sourceName, String mediaType) throws IOException { - if (sourceName == null || stream == null) - return null; - - String path = makeAttachmentPath(sourceName, false); - if (mediaType == null) - mediaType = FileUtils.getMediaType(sourceName); - IFileEntry entry = createFileEntry(path, mediaType); - if (entry != null) { - OutputStream os = entry.openOutputStream(); - try { - FileUtils.transfer(stream, os); - } finally { - os.close(); - } - } - return entry; - } - - public IFileEntry cloneEntry(IFileEntry sourceEntry, String targetPath) - throws IOException { - if (sourceEntry == null || targetPath == null) - return null; - - IFileEntry existingEntry = getFileEntry(targetPath); - if (existingEntry != null) { - return null; - } - - if (sourceEntry.isDirectory()) { - if (!targetPath.endsWith("/")) //$NON-NLS-1$ - targetPath = targetPath + "/"; //$NON-NLS-1$ - importDirectoryEntry(targetPath, sourceEntry); - } else { - importFileEntry(targetPath, sourceEntry); - } - return getFileEntry(targetPath); - } - - private void importFileEntry(String path, IFileEntry sourceEntry) - throws IOException { - InputStream is = sourceEntry.openInputStream(); - try { - IFileEntry entry = createFileEntry(path, - sourceEntry.getMediaType()); - entry.setTime(sourceEntry.getTime()); - OutputStream os = entry.openOutputStream(); - try { - FileUtils.transfer(is, os); - } finally { - os.close(); - } - } finally { - is.close(); - } - } - - private void importDirectoryEntry(String parentPath, IFileEntry sourceEntry) - throws IOException { - String sourceParentPath = getParentPath(sourceEntry.getPath()); - for (IFileEntry sourceSubEntry : sourceEntry.getSubEntries()) { - String sourceSubPath = sourceSubEntry.getPath(); - if (sourceSubPath != null) { - String subPath = sourceSubPath - .substring(sourceParentPath.length()); - if (parentPath != null) { - subPath = parentPath + subPath; - } - if (!sourceSubEntry.isDirectory()) { - importFileEntry(subPath, sourceSubEntry); - } - } - } - if (getFileEntry(parentPath) == null) { - createFileEntry(parentPath, sourceEntry.getMediaType()); - } - } - - public IFileEntry cloneEntryAsAttachment(IFileEntry sourceEntry) - throws IOException { - String sourcePath = sourceEntry.getPath(); - String path = makeAttachmentPath(sourcePath, sourceEntry.isDirectory()); - IFileEntry cloneEntry = cloneEntry(sourceEntry, path); - return cloneEntry; - } - - public String makeAttachmentPath(String source) { - return makeAttachmentPath(source, false); - } - - public String makeAttachmentPath(String source, boolean directory) { - String path = "attachments/" + Core.getIdFactory().createId() //$NON-NLS-1$ - + FileUtils.getExtension(source); - if (directory) - path += "/"; //$NON-NLS-1$ - return path; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IManifest#getEncryptionData(java.lang.String) - */ - public IEncryptionData getEncryptionData(String entryPath) { - IFileEntry entry = getFileEntry(entryPath); - if (entry != null) - return entry.getEncryptionData(); - return null; - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return ownedWorkbook.getCoreEventSupport() - .registerCoreEventListener(this, type, listener); - } - - public CoreEventSupport getCoreEventSupport() { - if (coreEventSupport != null) - return coreEventSupport; - - coreEventSupport = new CoreEventSupport(); - return coreEventSupport; - } - - public String getPasswordHint() { - Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); - return m.getAttribute(PASSWORD_HINT); - } - - public void setPasswordHint(String hint) { - Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); - m.setAttribute(PASSWORD_HINT, hint); - } - -// protected void saveTemp(String newPassword) -// throws IOException, CoreException { -// String oldPassword = getPassword(); -// SerializerImpl serializer = (SerializerImpl) Core.getSerializerFactory() -// .newSerializer(); -// if (oldPassword == newPassword -// || (oldPassword != null && oldPassword.equals(newPassword))) { -// serializer.serializeAll(ownedWorkbook, this, this, -// FileEntrySelection.None, true); -// } else { -// Transformer transformer = DOMUtils.getDefaultTransformer(); -// DOMResult newDocResult = new DOMResult(); -// try { -// transformer.transform(new DOMSource(implementation), -// newDocResult); -// } catch (TransformerException e) { -// throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, -// MANIFEST_XML, e); -// } -// -// ManifestImpl tempManifest = new ManifestImpl( -// (Document) newDocResult.getNode(), storage); -// this.password = newPassword; -// for (IFileEntry entry : getAllRegisteredEntries()) { -// if (entry.getEncryptionData() != null) { -// entry.deleteEncryptionData(); -// entry.createEncryptionData(); -// } -// } -// serializer.serializeAll(ownedWorkbook, tempManifest, this, -// FileEntrySelection.All, true); -// } -// } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_FULL_PATH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.PASSWORD_HINT; +import static org.xmind.core.internal.dom.DOMConstants.TAG_FILE_ENTRY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MANIFEST; +import static org.xmind.core.internal.dom.InternalDOMUtils.getParentPath; +import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.IEncryptionData; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IFileEntryFilter; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.internal.Manifest; +import org.xmind.core.internal.event.CoreEventSupport; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; + +public class ManifestImpl extends Manifest implements ICoreEventSource { + + private Document implementation; + + private IStorage storage; + + private WorkbookImpl ownedWorkbook; + + private final Map entries; + + private IEntryStreamNormalizer normalizer; + + private CoreEventSupport coreEventSupport; + + public ManifestImpl(Document implementation, IStorage storage) { + this.implementation = implementation; + this.storage = storage == null ? new ByteArrayStorage() : storage; + this.normalizer = IEntryStreamNormalizer.NULL; + this.ownedWorkbook = null; + this.entries = new HashMap(); + init(); + } + + private void init() { + Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); + NS.setNS(NS.Manifest, m); + + // Prefetch all file entries, which makes getAllRegisteredEntries() + // always returns correct value. + for (Iterator it = iterFileEntries(); it.hasNext();) { + it.next(); + } + + IFileEntry metaEntry = createFileEntry(MANIFEST_XML, + Core.MEDIA_TYPE_TEXT_XML); + insertFileEntryImpl(metaEntry.getAdapter(Element.class)); + } + + public Document getImplementation() { + return implementation; + } + + public Element getManifestElement() { + return implementation.getDocumentElement(); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(implementation); + if (IWorkbook.class.equals(adapter)) + return adapter.cast(ownedWorkbook); + return super.getAdapter(adapter); + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return ownedWorkbook == null; + } + + /** + * @param workbook + */ + protected void setWorkbook(WorkbookImpl workbook) { + this.ownedWorkbook = workbook; + if (workbook != null) { + getCoreEventSupport().setParent(workbook.getCoreEventSupport()); + } + } + + protected void setStorage(IStorage storage) { + this.storage = storage == null ? new ByteArrayStorage() : storage; + } + + protected IStorage getStorage() { + return storage; + } + + protected void setStreamNormalizer(IEntryStreamNormalizer normalizer) { + this.normalizer = normalizer == null ? IEntryStreamNormalizer.NULL + : normalizer; + } + + protected IEntryStreamNormalizer getStreamNormalizer() { + return this.normalizer; + } + + protected Collection getAllRegisteredEntries() { + return entries.values(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IManifest#iterFileEntries() + */ + public Iterator iterFileEntries() { + return iterFileEntries(null); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IManifest#iterFileEntries(org.xmind.core.IManifest. + * IFileEntryFilter) + */ + public Iterator iterFileEntries(final IFileEntryFilter filter) { + final Iterator it = DOMUtils + .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); + return new Iterator() { + + IFileEntry next = findNext(); + + private IFileEntry findNext() { + while (it.hasNext()) { + Element e = it.next(); + if (e.hasAttribute(ATTR_FULL_PATH) && select(e)) { + return getFileEntry(e); + } + } + return null; + } + + private boolean select(Element e) { + if (filter == null) + return true; + + String path = e.getAttribute(ATTR_FULL_PATH); + String mediaType = e.getAttribute(ATTR_MEDIA_TYPE); + boolean isDirectory = path.endsWith("/"); //$NON-NLS-1$ + return filter.select(path, mediaType, isDirectory); + } + + public void remove() { + } + + public IFileEntry next() { + IFileEntry n = next; + next = findNext(); + return n; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + public IFileEntry getFileEntry(String path) { + if (path == null) + return null; + IFileEntry entry = findEntry(path); + if (entry == null) { + while (path.startsWith("/")) { //$NON-NLS-1$ + path = path.substring(1, path.length()); + entry = findEntry(path); + if (entry != null) + break; + } + } + if (entry == null) { + entry = findEntry("/" + path); //$NON-NLS-1$ + } + return entry; + } + + private IFileEntry findEntry(String path) { + IFileEntry entry = entries.get(path); + if (entry == null) { + Element e = findEntryElementByPath(path); + if (e != null) + entry = createFileEntry(path, e); + } + return entry; + } + + private Element findEntryElementByPath(String path) { + Iterator it = DOMUtils + .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); + while (it.hasNext()) { + Element e = it.next(); + if (path.equals(e.getAttribute(ATTR_FULL_PATH))) + return e; + } + return null; + } + + public IFileEntry createFileEntry(String path) { + return createFileEntry(path, ""); //$NON-NLS-1$ + } + + public IFileEntry createFileEntry(String path, String mediaType) { + IFileEntry entry = getFileEntry(path); + if (entry != null) + return entry; + + String parent = InternalDOMUtils.getParentPath(path); + if (parent != null) { + IFileEntry parentFileEntry = createFileEntry(parent); + insertFileEntryImpl(parentFileEntry.getAdapter(Element.class)); + } + Element e = implementation.createElement(TAG_FILE_ENTRY); + e.setAttribute(ATTR_FULL_PATH, path); + e.setAttribute(ATTR_MEDIA_TYPE, mediaType); + + return createFileEntry(path, e); + } + + private IFileEntry createFileEntry(String path, Element entryElement) { + IFileEntry entry = new FileEntryImpl(entryElement, this); + entries.put(path, entry); + return entry; + } + + private IFileEntry getFileEntry(Element element) { + String path = element.getAttribute(ATTR_FULL_PATH); + IFileEntry entry = entries.get(path); + if (entry != null) + return entry; + return createFileEntry(path, element); + } + + protected void insertFileEntry(IFileEntry entry) { + Element e = (Element) entry.getAdapter(Element.class); + if (e != null) { + insertFileEntryImpl(e); + } + getCoreEventSupport().dispatchTargetChange(this, Core.FileEntryAdd, + entry); + } + + protected void removeFileEntry(IFileEntry entry) { + Element e = (Element) entry.getAdapter(Element.class); + if (e != null) { + Element m = getManifestElement(); + if (m == e.getParentNode()) + m.removeChild(e); + } + getCoreEventSupport().dispatchTargetChange(this, Core.FileEntryRemove, + entry); + } + + private void insertFileEntryImpl(Element entryElement) { + Element e = findInsertLocation(entryElement); + if (e != null) { + getManifestElement().insertBefore(entryElement, e); + } else { + getManifestElement().appendChild(entryElement); + } + } + + private Element findInsertLocation(Element entryElement) { + if (entryElement.hasAttribute(ATTR_FULL_PATH)) + return findInsertLocation(entryElement, + entryElement.getAttribute(ATTR_FULL_PATH)); + return null; + } + + private Element findInsertLocation(Element entryElement, String path) { + Iterator it = DOMUtils + .childElementIterByTag(getManifestElement(), TAG_FILE_ENTRY); + while (it.hasNext()) { + Element e = it.next(); + if (e != entryElement && e.hasAttribute(ATTR_FULL_PATH)) { + String p = e.getAttribute(ATTR_FULL_PATH); + if (p != null && path.compareToIgnoreCase(p) < 0) { + return e; + } + } + } + return null; + } + + public IFileEntry createAttachmentFromFilePath(String sourcePath) + throws IOException { + return createAttachmentFromFilePath(sourcePath, null); + } + + public IFileEntry createAttachmentFromFilePath(String sourcePath, + String mediaType) throws IOException { + if (sourcePath == null) + throw new IllegalArgumentException("Path is null!"); //$NON-NLS-1$ + File file = new File(sourcePath); + if (!file.exists()) + throw new FileNotFoundException("Source path does not exists."); //$NON-NLS-1$ + + if (file.isFile()) { + IFileEntry entry = createAttachmentFromStream( + new FileInputStream(sourcePath), sourcePath, mediaType); + if (entry != null) { + entry.setTime(file.lastModified()); + } + return entry; + } + + if (file.isDirectory()) { + String fileName = file.getName(); + String path = makeAttachmentPath(fileName, true); + if (mediaType == null) + mediaType = FileUtils.getMediaType(fileName); + IFileEntry root = createFileEntry(path, mediaType); + if (root != null) { + importDirectory(path, file); + } + return root; + } + + throw new IllegalArgumentException( + "Unknown file type (neither a file nor a directory)"); //$NON-NLS-1$ + } + + protected void importDirectory(String parentPath, File dir) + throws IOException { + for (String sub : dir.list()) { + File f = new File(dir, sub); + if (f.isFile()) { + String path = parentPath == null ? sub : parentPath + sub; + String mediaType = FileUtils.getMediaType(sub); + IFileEntry e = createFileEntry(path, mediaType); + if (e != null) { + e.setTime(f.lastModified()); + OutputStream os = e.openOutputStream(); + try { + FileInputStream is = new FileInputStream(f); + try { + FileUtils.transfer(is, os); + } finally { + is.close(); + } + } finally { + os.close(); + } + } + } else if (f.isDirectory()) { + String path = parentPath == null ? sub + "/" //$NON-NLS-1$ + : parentPath + sub + "/"; //$NON-NLS-1$ + importDirectory(path, f); + } + } + } + + public IFileEntry createAttachmentFromStream(InputStream stream, + String sourceName) throws IOException { + return createAttachmentFromStream(stream, sourceName, null); + } + + public IFileEntry createAttachmentFromStream(InputStream stream, + String sourceName, String mediaType) throws IOException { + if (sourceName == null || stream == null) + return null; + + String path = makeAttachmentPath(sourceName, false); + if (mediaType == null) + mediaType = FileUtils.getMediaType(sourceName); + IFileEntry entry = createFileEntry(path, mediaType); + if (entry != null) { + OutputStream os = entry.openOutputStream(); + try { + FileUtils.transfer(stream, os); + } finally { + os.close(); + } + } + return entry; + } + + public IFileEntry cloneEntry(IFileEntry sourceEntry, String targetPath) + throws IOException { + if (sourceEntry == null || targetPath == null) + return null; + + IFileEntry existingEntry = getFileEntry(targetPath); + if (existingEntry != null) { + return null; + } + + if (sourceEntry.isDirectory()) { + if (!targetPath.endsWith("/")) //$NON-NLS-1$ + targetPath = targetPath + "/"; //$NON-NLS-1$ + importDirectoryEntry(targetPath, sourceEntry); + } else { + importFileEntry(targetPath, sourceEntry); + } + return getFileEntry(targetPath); + } + + private void importFileEntry(String path, IFileEntry sourceEntry) + throws IOException { + InputStream is = sourceEntry.openInputStream(); + try { + IFileEntry entry = createFileEntry(path, + sourceEntry.getMediaType()); + entry.setTime(sourceEntry.getTime()); + OutputStream os = entry.openOutputStream(); + try { + FileUtils.transfer(is, os); + } finally { + os.close(); + } + } finally { + is.close(); + } + } + + private void importDirectoryEntry(String parentPath, IFileEntry sourceEntry) + throws IOException { + String sourceParentPath = getParentPath(sourceEntry.getPath()); + for (IFileEntry sourceSubEntry : sourceEntry.getSubEntries()) { + String sourceSubPath = sourceSubEntry.getPath(); + if (sourceSubPath != null) { + String subPath = sourceSubPath + .substring(sourceParentPath.length()); + if (parentPath != null) { + subPath = parentPath + subPath; + } + if (!sourceSubEntry.isDirectory()) { + importFileEntry(subPath, sourceSubEntry); + } + } + } + if (getFileEntry(parentPath) == null) { + createFileEntry(parentPath, sourceEntry.getMediaType()); + } + } + + public IFileEntry cloneEntryAsAttachment(IFileEntry sourceEntry) + throws IOException { + String sourcePath = sourceEntry.getPath(); + String path = makeAttachmentPath(sourcePath, sourceEntry.isDirectory()); + IFileEntry cloneEntry = cloneEntry(sourceEntry, path); + return cloneEntry; + } + + public String makeAttachmentPath(String source) { + return makeAttachmentPath(source, false); + } + + public String makeAttachmentPath(String source, boolean directory) { + String path = "attachments/" + Core.getIdFactory().createId() //$NON-NLS-1$ + + FileUtils.getExtension(source); + if (directory) + path += "/"; //$NON-NLS-1$ + return path; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IManifest#getEncryptionData(java.lang.String) + */ + public IEncryptionData getEncryptionData(String entryPath) { + IFileEntry entry = getFileEntry(entryPath); + if (entry != null) + return entry.getEncryptionData(); + return null; + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return ownedWorkbook.getCoreEventSupport() + .registerCoreEventListener(this, type, listener); + } + + public CoreEventSupport getCoreEventSupport() { + if (coreEventSupport != null) + return coreEventSupport; + + coreEventSupport = new CoreEventSupport(); + return coreEventSupport; + } + + public String getPasswordHint() { + Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); + return m.getAttribute(PASSWORD_HINT); + } + + public void setPasswordHint(String hint) { + Element m = DOMUtils.ensureChildElement(implementation, TAG_MANIFEST); + m.setAttribute(PASSWORD_HINT, hint); + } + +// protected void saveTemp(String newPassword) +// throws IOException, CoreException { +// String oldPassword = getPassword(); +// SerializerImpl serializer = (SerializerImpl) Core.getSerializerFactory() +// .newSerializer(); +// if (oldPassword == newPassword +// || (oldPassword != null && oldPassword.equals(newPassword))) { +// serializer.serializeAll(ownedWorkbook, this, this, +// FileEntrySelection.None, true); +// } else { +// Transformer transformer = DOMUtils.getDefaultTransformer(); +// DOMResult newDocResult = new DOMResult(); +// try { +// transformer.transform(new DOMSource(implementation), +// newDocResult); +// } catch (TransformerException e) { +// throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, +// MANIFEST_XML, e); +// } +// +// ManifestImpl tempManifest = new ManifestImpl( +// (Document) newDocResult.getNode(), storage); +// this.password = newPassword; +// for (IFileEntry entry : getAllRegisteredEntries()) { +// if (entry.getEncryptionData() != null) { +// entry.deleteEncryptionData(); +// entry.createEncryptionData(); +// } +// } +// serializer.serializeAll(ownedWorkbook, tempManifest, this, +// FileEntrySelection.All, true); +// } +// } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerGroupImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerGroupImpl.java index 1808dfc71..ecb4ed645 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerGroupImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerGroupImpl.java @@ -1,194 +1,194 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HIDDEN; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SINGLETON; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; - -import java.util.List; -import java.util.Properties; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.MarkerGroup; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.DOMUtils; - -public class MarkerGroupImpl extends MarkerGroup implements ICoreEventSource { - - private Element implementation; - - private MarkerSheetImpl ownedSheet; - - public MarkerGroupImpl(Element implementation, MarkerSheetImpl ownedSheet) { - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedSheet = ownedSheet; - } - - public Element getImplementation() { - return implementation; - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof MarkerGroupImpl)) - return false; - MarkerGroupImpl that = (MarkerGroupImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return DOMUtils.toString(implementation); - } - - public String getName() { - String name = implementation.getAttribute(ATTR_NAME); - if (name.startsWith("%")) { //$NON-NLS-1$ - Properties properties = ownedSheet.getProperties(); - if (properties != null) { - String key = name.substring(1); - name = properties.getProperty(key, name); - } - } - return name; - } - - public IMarkerSheet getOwnedSheet() { - return ownedSheet; - } - - public IMarkerSheet getParent() { - Node p = implementation.getParentNode(); - if (p == ownedSheet.getSheetElement()) { - return ownedSheet; - } - return null; - } - - public boolean isSingleton() { - return Boolean - .parseBoolean(implementation.getAttribute(ATTR_SINGLETON)); - } - - public boolean isHidden() { - return Boolean.parseBoolean(implementation.getAttribute(ATTR_HIDDEN)); - } - - public void setName(String name) { - String oldName = implementation.hasAttribute(ATTR_NAME) ? getName() - : null; - DOMUtils.setAttribute(implementation, ATTR_NAME, name); - String newName = implementation.hasAttribute(ATTR_NAME) ? getName() - : null; - fireValueChange(Core.Name, oldName, newName); - } - - public void setSingleton(boolean singleton) { - DOMUtils.setAttribute(implementation, ATTR_SINGLETON, - Boolean.toString(singleton)); - } - - public void setHidden(boolean hidden) { - DOMUtils.setAttribute(implementation, ATTR_HIDDEN, - Boolean.toString(hidden)); - } - - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - public List getMarkers() { - return DOMUtils.getChildList(implementation, TAG_MARKER, - ownedSheet.getElementAdapterProvider()); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerGroup#isEmpty() - */ - public boolean isEmpty() { - return !implementation.hasChildNodes(); - } - - public void addMarker(IMarker marker) { - Element m = ((MarkerImpl) marker).getImplementation(); - Node n = implementation.appendChild(m); - if (n != null) { - int index = DOMUtils.getElementIndex(implementation, TAG_MARKER, m); - if (index >= 0) { - if (getParent() != null) - fireIndexedTargetChange(Core.MarkerAdd, marker, index); - } - } - } - - public void removeMarker(IMarker marker) { - Element m = ((MarkerImpl) marker).getImplementation(); - if (m != null && m.getParentNode() == implementation) { - int index = DOMUtils.getElementIndex(implementation, TAG_MARKER, m); - if (index >= 0) { - Node n = implementation.removeChild(m); - if (n != null) { - if (getParent() != null) - fireIndexedTargetChange(Core.MarkerRemove, marker, - index); - } - } - } - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, type, oldValue, - newValue); - } - - private void fireIndexedTargetChange(String type, Object target, - int index) { - getCoreEventSupport().dispatchIndexedTargetChange(this, type, target, - index); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedSheet.getCoreEventSupport(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HIDDEN; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SINGLETON; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; + +import java.util.List; +import java.util.Properties; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.MarkerGroup; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.DOMUtils; + +public class MarkerGroupImpl extends MarkerGroup implements ICoreEventSource { + + private Element implementation; + + private MarkerSheetImpl ownedSheet; + + public MarkerGroupImpl(Element implementation, MarkerSheetImpl ownedSheet) { + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedSheet = ownedSheet; + } + + public Element getImplementation() { + return implementation; + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof MarkerGroupImpl)) + return false; + MarkerGroupImpl that = (MarkerGroupImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return DOMUtils.toString(implementation); + } + + public String getName() { + String name = implementation.getAttribute(ATTR_NAME); + if (name.startsWith("%")) { //$NON-NLS-1$ + Properties properties = ownedSheet.getProperties(); + if (properties != null) { + String key = name.substring(1); + name = properties.getProperty(key, name); + } + } + return name; + } + + public IMarkerSheet getOwnedSheet() { + return ownedSheet; + } + + public IMarkerSheet getParent() { + Node p = implementation.getParentNode(); + if (p == ownedSheet.getSheetElement()) { + return ownedSheet; + } + return null; + } + + public boolean isSingleton() { + return Boolean + .parseBoolean(implementation.getAttribute(ATTR_SINGLETON)); + } + + public boolean isHidden() { + return Boolean.parseBoolean(implementation.getAttribute(ATTR_HIDDEN)); + } + + public void setName(String name) { + String oldName = implementation.hasAttribute(ATTR_NAME) ? getName() + : null; + DOMUtils.setAttribute(implementation, ATTR_NAME, name); + String newName = implementation.hasAttribute(ATTR_NAME) ? getName() + : null; + fireValueChange(Core.Name, oldName, newName); + } + + public void setSingleton(boolean singleton) { + DOMUtils.setAttribute(implementation, ATTR_SINGLETON, + Boolean.toString(singleton)); + } + + public void setHidden(boolean hidden) { + DOMUtils.setAttribute(implementation, ATTR_HIDDEN, + Boolean.toString(hidden)); + } + + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + public List getMarkers() { + return DOMUtils.getChildList(implementation, TAG_MARKER, + ownedSheet.getElementAdapterProvider()); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerGroup#isEmpty() + */ + public boolean isEmpty() { + return !implementation.hasChildNodes(); + } + + public void addMarker(IMarker marker) { + Element m = ((MarkerImpl) marker).getImplementation(); + Node n = implementation.appendChild(m); + if (n != null) { + int index = DOMUtils.getElementIndex(implementation, TAG_MARKER, m); + if (index >= 0) { + if (getParent() != null) + fireIndexedTargetChange(Core.MarkerAdd, marker, index); + } + } + } + + public void removeMarker(IMarker marker) { + Element m = ((MarkerImpl) marker).getImplementation(); + if (m != null && m.getParentNode() == implementation) { + int index = DOMUtils.getElementIndex(implementation, TAG_MARKER, m); + if (index >= 0) { + Node n = implementation.removeChild(m); + if (n != null) { + if (getParent() != null) + fireIndexedTargetChange(Core.MarkerRemove, marker, + index); + } + } + } + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, type, oldValue, + newValue); + } + + private void fireIndexedTargetChange(String type, Object target, + int index) { + getCoreEventSupport().dispatchIndexedTargetChange(this, type, target, + index); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedSheet.getCoreEventSupport(); + } +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerImpl.java index cd9aa2cd4..f43f9967f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerImpl.java @@ -1,153 +1,153 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HIDDEN; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SVG; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_GROUP; - -import java.util.Properties; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Marker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerResource; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.DOMUtils; - -public class MarkerImpl extends Marker implements ICoreEventSource { - - private Element implementation; - - private MarkerSheetImpl ownedSheet; - - public MarkerImpl(Element implementation, MarkerSheetImpl ownedSheet) { - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedSheet = ownedSheet; - } - - public IMarkerSheet getOwnedSheet() { - return ownedSheet; - } - - public Element getImplementation() { - return implementation; - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof MarkerImpl)) - return false; - MarkerImpl that = (MarkerImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "MKR#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public String getName() { - String name = implementation.getAttribute(ATTR_NAME); - if (name.startsWith("%")) { //$NON-NLS-1$ - Properties properties = ownedSheet.getProperties(); - if (properties != null) { - String key = name.substring(1); - name = properties.getProperty(key, name); - } - } - return name; - } - - public IMarkerGroup getParent() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_MARKER_GROUP)) { - return (IMarkerGroup) ownedSheet.getElementAdapter((Element) p); - } - return null; - } - - public IMarkerResource getResource() { - return ownedSheet.getMarkerResource(this); - } - - public String getResourcePath() { - return implementation.getAttribute(ATTR_RESOURCE); - } - - public void setResourcePath(String resourcePath) { - DOMUtils.setAttribute(implementation, ATTR_RESOURCE, resourcePath); - } - - public String getSVGPath() { - return DOMUtils.getAttribute(implementation, ATTR_SVG); - } - - public void setName(String name) { - String oldName = DOMUtils.getAttribute(implementation, ATTR_NAME); - DOMUtils.setAttribute(implementation, ATTR_NAME, name); - String newName = DOMUtils.getAttribute(implementation, ATTR_NAME); - fireValueChange(Core.Name, oldName, newName); - } - - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - public boolean isHidden() { - return Boolean.parseBoolean(implementation.getAttribute(ATTR_HIDDEN)); - } - - public void setHidden(boolean hidden) { - DOMUtils.setAttribute(implementation, ATTR_HIDDEN, - Boolean.toString(hidden)); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, type, oldValue, - newValue); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedSheet.getCoreEventSupport(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HIDDEN; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SVG; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_GROUP; + +import java.util.Properties; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Marker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerResource; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.DOMUtils; + +public class MarkerImpl extends Marker implements ICoreEventSource { + + private Element implementation; + + private MarkerSheetImpl ownedSheet; + + public MarkerImpl(Element implementation, MarkerSheetImpl ownedSheet) { + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedSheet = ownedSheet; + } + + public IMarkerSheet getOwnedSheet() { + return ownedSheet; + } + + public Element getImplementation() { + return implementation; + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof MarkerImpl)) + return false; + MarkerImpl that = (MarkerImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "MKR#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public String getName() { + String name = implementation.getAttribute(ATTR_NAME); + if (name.startsWith("%")) { //$NON-NLS-1$ + Properties properties = ownedSheet.getProperties(); + if (properties != null) { + String key = name.substring(1); + name = properties.getProperty(key, name); + } + } + return name; + } + + public IMarkerGroup getParent() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_MARKER_GROUP)) { + return (IMarkerGroup) ownedSheet.getElementAdapter((Element) p); + } + return null; + } + + public IMarkerResource getResource() { + return ownedSheet.getMarkerResource(this); + } + + public String getResourcePath() { + return implementation.getAttribute(ATTR_RESOURCE); + } + + public void setResourcePath(String resourcePath) { + DOMUtils.setAttribute(implementation, ATTR_RESOURCE, resourcePath); + } + + public String getSVGPath() { + return DOMUtils.getAttribute(implementation, ATTR_SVG); + } + + public void setName(String name) { + String oldName = DOMUtils.getAttribute(implementation, ATTR_NAME); + DOMUtils.setAttribute(implementation, ATTR_NAME, name); + String newName = DOMUtils.getAttribute(implementation, ATTR_NAME); + fireValueChange(Core.Name, oldName, newName); + } + + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + public boolean isHidden() { + return Boolean.parseBoolean(implementation.getAttribute(ATTR_HIDDEN)); + } + + public void setHidden(boolean hidden) { + DOMUtils.setAttribute(implementation, ATTR_HIDDEN, + Boolean.toString(hidden)); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, type, oldValue, + newValue); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedSheet.getCoreEventSupport(); + } +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerResource.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerResource.java index 6def7406e..06f7d35e9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerResource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerResource.java @@ -1,51 +1,51 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.marker.AbstractMarkerResource; -import org.xmind.core.marker.IMarker; - -public class MarkerResource extends AbstractMarkerResource { - - private IInputSource source; - - private IOutputTarget target; - - public MarkerResource(IMarker marker, IInputSource source, - IOutputTarget target) { - super(marker); - this.source = source; - this.target = target; - } - - public InputStream openInputStream() throws IOException { - if (source == null) - throw new FileNotFoundException(getFullPath()); - return source.openEntryStream(getFullPath()); - } - - public OutputStream openOutputStream() throws IOException { - if (target == null) - throw new FileNotFoundException(getFullPath()); - return target.openEntryStream(getFullPath()); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.marker.AbstractMarkerResource; +import org.xmind.core.marker.IMarker; + +public class MarkerResource extends AbstractMarkerResource { + + private IInputSource source; + + private IOutputTarget target; + + public MarkerResource(IMarker marker, IInputSource source, + IOutputTarget target) { + super(marker); + this.source = source; + this.target = target; + } + + public InputStream openInputStream() throws IOException { + if (source == null) + throw new FileNotFoundException(getFullPath()); + return source.openEntryStream(getFullPath()); + } + + public OutputStream openOutputStream() throws IOException { + if (target == null) + throw new FileNotFoundException(getFullPath()); + return target.openEntryStream(getFullPath()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetBuilderImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetBuilderImpl.java index 4a89fa4c7..39a765b97 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetBuilderImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetBuilderImpl.java @@ -1,146 +1,146 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_SHEET; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.internal.MarkerSheetBuilder; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerResourceProvider; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.DOMUtils; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class MarkerSheetBuilderImpl extends MarkerSheetBuilder - implements ErrorHandler { - - private DocumentBuilder getDocumentCreator() { - DocumentBuilder documentCreator = null; - try { - documentCreator = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new IllegalStateException(e); - } - return documentCreator; - } - - private DocumentBuilder getDocumentLoader() throws CoreException { - DocumentBuilder documentLoader = null; - try { - documentLoader = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); - } - documentLoader.setErrorHandler(this); - return documentLoader; - } - - public IMarkerSheet createMarkerSheet( - IMarkerResourceProvider resourceProvider) { - Document impl = createDocument(); - DOMUtils.createElement(impl, TAG_MARKER_SHEET); - MarkerSheetImpl sheet = new MarkerSheetImpl(impl, resourceProvider); - return sheet; - } - - private Document createDocument() { - return getDocumentCreator().newDocument(); - } - - public IMarkerSheet loadFromStream(InputStream stream, - IMarkerResourceProvider resourceProvider) - throws IOException, CoreException { - DocumentBuilder loader = getDocumentLoader(); - Document doc = parse(loader, stream); - return createMarkerSheet(doc, resourceProvider); - } - - protected MarkerSheetImpl createMarkerSheet(Document doc, - IMarkerResourceProvider resourceProvider) { - MarkerSheetImpl sheet = new MarkerSheetImpl(doc, resourceProvider); - init(sheet); - return sheet; - } - -// public IMarkerSheet loadFromInputSource(IInputSource source, -// IXMLLoader xmlLoader, IMarkerResourceProvider resourceProvider) -// throws IOException, CoreException { -// Document doc = xmlLoader.loadXMLFile(source, PATH_MARKER_SHEET); -// return createMarkerSheet(doc, resourceProvider); -// } - - private void init(MarkerSheetImpl sheet) { - for (IMarkerGroup group : sheet.getMarkerGroups()) { - initGroup(group); - } - } - - private void initGroup(IMarkerGroup group) { - for (IMarker marker : group.getMarkers()) { - initMarker(marker); - } - } - - private void initMarker(IMarker marker) { - } - - private Document parse(DocumentBuilder loader, InputStream stream) - throws IOException, CoreException { - try { - return loader.parse(stream); - } catch (SAXException e) { - throw new CoreException(Core.ERROR_FAIL_PARSING_XML, e); - } catch (IOException e) { - throw e; - } finally { - try { - stream.close(); - } catch (IOException ignore) { - } - } - } - - public void error(SAXParseException exception) throws SAXException { - Core.getLogger().log(exception); - } - - public void fatalError(SAXParseException exception) throws SAXException { - Core.getLogger().log(exception); - } - - public void warning(SAXParseException exception) throws SAXException { - Core.getLogger().log(exception); - } - - public void loadProperties(InputStream stream, IMarkerSheet sheet) - throws IOException, CoreException { - Properties p = new Properties(); - p.load(stream); - ((MarkerSheetImpl) sheet).setProperties(p); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_SHEET; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.internal.MarkerSheetBuilder; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerResourceProvider; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.DOMUtils; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class MarkerSheetBuilderImpl extends MarkerSheetBuilder + implements ErrorHandler { + + private DocumentBuilder getDocumentCreator() { + DocumentBuilder documentCreator = null; + try { + documentCreator = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } + return documentCreator; + } + + private DocumentBuilder getDocumentLoader() throws CoreException { + DocumentBuilder documentLoader = null; + try { + documentLoader = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); + } + documentLoader.setErrorHandler(this); + return documentLoader; + } + + public IMarkerSheet createMarkerSheet( + IMarkerResourceProvider resourceProvider) { + Document impl = createDocument(); + DOMUtils.createElement(impl, TAG_MARKER_SHEET); + MarkerSheetImpl sheet = new MarkerSheetImpl(impl, resourceProvider); + return sheet; + } + + private Document createDocument() { + return getDocumentCreator().newDocument(); + } + + public IMarkerSheet loadFromStream(InputStream stream, + IMarkerResourceProvider resourceProvider) + throws IOException, CoreException { + DocumentBuilder loader = getDocumentLoader(); + Document doc = parse(loader, stream); + return createMarkerSheet(doc, resourceProvider); + } + + protected MarkerSheetImpl createMarkerSheet(Document doc, + IMarkerResourceProvider resourceProvider) { + MarkerSheetImpl sheet = new MarkerSheetImpl(doc, resourceProvider); + init(sheet); + return sheet; + } + +// public IMarkerSheet loadFromInputSource(IInputSource source, +// IXMLLoader xmlLoader, IMarkerResourceProvider resourceProvider) +// throws IOException, CoreException { +// Document doc = xmlLoader.loadXMLFile(source, PATH_MARKER_SHEET); +// return createMarkerSheet(doc, resourceProvider); +// } + + private void init(MarkerSheetImpl sheet) { + for (IMarkerGroup group : sheet.getMarkerGroups()) { + initGroup(group); + } + } + + private void initGroup(IMarkerGroup group) { + for (IMarker marker : group.getMarkers()) { + initMarker(marker); + } + } + + private void initMarker(IMarker marker) { + } + + private Document parse(DocumentBuilder loader, InputStream stream) + throws IOException, CoreException { + try { + return loader.parse(stream); + } catch (SAXException e) { + throw new CoreException(Core.ERROR_FAIL_PARSING_XML, e); + } catch (IOException e) { + throw e; + } finally { + try { + stream.close(); + } catch (IOException ignore) { + } + } + } + + public void error(SAXParseException exception) throws SAXException { + Core.getLogger().log(exception); + } + + public void fatalError(SAXParseException exception) throws SAXException { + Core.getLogger().log(exception); + } + + public void warning(SAXParseException exception) throws SAXException { + Core.getLogger().log(exception); + } + + public void loadProperties(InputStream stream, IMarkerSheet sheet) + throws IOException, CoreException { + Properties p = new Properties(); + p.load(stream); + ((MarkerSheetImpl) sheet).setProperties(p); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetImpl.java index 269c6a497..4c6b29e9c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerSheetImpl.java @@ -1,570 +1,570 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_SINGLETON; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_GROUP; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_SHEET; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.zip.ZipFile; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IManifest; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.ElementRegistry; -import org.xmind.core.internal.MarkerSheet; -import org.xmind.core.internal.event.CoreEventSupport; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.internal.zip.ZipFileInputSource; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.io.IInputSource; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerResource; -import org.xmind.core.marker.IMarkerResourceAllocator; -import org.xmind.core.marker.IMarkerResourceProvider; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.IPropertiesProvider; - -public class MarkerSheetImpl extends MarkerSheet implements - INodeAdaptableFactory, ICoreEventSource, IPropertiesProvider { - - private Document implementation; - - private IMarkerResourceProvider realResourceProvider; - - private ElementRegistry elementRegistry = null; - - private NodeAdaptableProvider elementAdaptableProvider = null; - - private CoreEventSupport coreEventSupport = null; - - private Properties properties = null; - - private ManifestImpl manifest = null; - - public MarkerSheetImpl(Document implementation, - IMarkerResourceProvider resourceProvider) { - this.implementation = implementation; - this.realResourceProvider = resourceProvider; - init(); - } - - private void init() { - Element m = DOMUtils.ensureChildElement(implementation, - TAG_MARKER_SHEET); - NS.setNS(NS.Marker, m); - InternalDOMUtils.addVersion(implementation); - } - - public Document getImplementation() { - return implementation; - } - - public Element getSheetElement() { - return implementation.getDocumentElement(); - } - - /** - * @param manifest - * the manifest to set - */ - public void setManifest(ManifestImpl manifest) { - this.manifest = manifest; - } - - public T getAdapter(Class adapter) { - if (IManifest.class.equals(adapter)) - return adapter.cast(manifest); - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (IMarkerResourceProvider.class.equals(adapter)) - return adapter.cast(realResourceProvider); - if (ICoreEventSupport.class.equals(adapter)) - return adapter.cast(getCoreEventSupport()); - if (IPropertiesProvider.class.equals(adapter)) - return adapter.cast(this); - if (Properties.class.equals(adapter)) - return adapter.cast(getProperties()); - if (ElementRegistry.class.equals(adapter)) - return adapter.cast(getElementRegistry()); - if (INodeAdaptableFactory.class.equals(adapter)) - return adapter.cast(this); - if (INodeAdaptableProvider.class.equals(adapter)) - return adapter.cast(getElementAdapterProvider()); - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - protected IMarkerResource getMarkerResource(IMarker marker) { - if (realResourceProvider != null) - return realResourceProvider.getMarkerResource(marker); - return null; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof MarkerSheetImpl)) - return false; - MarkerSheetImpl that = (MarkerSheetImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return DOMUtils.toString(implementation); - } - - public boolean isPermanent() { - return realResourceProvider == null - || realResourceProvider.isPermanent(); - } - - public IMarker createMarker(String resourcePath) { - Element markerImpl = implementation.createElement(TAG_MARKER); - DOMUtils.setAttribute(markerImpl, ATTR_RESOURCE, resourcePath); - MarkerImpl marker = new MarkerImpl(markerImpl, this); - getElementRegistry().register(marker); - return marker; - } - - public IMarker createMarkerById(String markerId, String resourcePath) { - Element markerImpl = implementation.createElement(TAG_MARKER); - DOMUtils.setAttribute(markerImpl, ATTR_RESOURCE, resourcePath); - MarkerImpl marker = new MarkerImpl(markerImpl, this); - replaceId(marker, markerId); - getElementRegistry().register(marker); - return marker; - } - - public IMarkerGroup createMarkerGroupById(String groupId) { - Element groupImpl = implementation.createElement(TAG_MARKER_GROUP); - MarkerGroupImpl group = new MarkerGroupImpl(groupImpl, this); - replaceId(group, groupId); - getElementRegistry().register(group); - return group; - } - - public IMarkerGroup createMarkerGroup(boolean singleton) { - Element groupImpl = implementation.createElement(TAG_MARKER_GROUP); - if (singleton) - groupImpl.setAttribute(ATTR_SINGLETON, Boolean.toString(singleton)); - MarkerGroupImpl group = new MarkerGroupImpl(groupImpl, this); - getElementRegistry().register(group); - return group; - } - - protected IMarker getLocalMarker(String markerId) { - Object element = getElementById(markerId); - if (element != null && element instanceof IMarker) - return (IMarker) element; - return null; - } - - protected IMarkerGroup getLocalMarkerGroup(String groupId) { - Object element = getElementById(groupId); - if (element != null && element instanceof IMarkerGroup) - return (IMarkerGroup) element; - return null; - } - - public List getMarkerGroups() { - return DOMUtils.getChildList(getSheetElement(), TAG_MARKER_GROUP, - getElementAdapterProvider()); - } - - public void addMarkerGroup(IMarkerGroup group) { - Element g = ((MarkerGroupImpl) group).getImplementation(); - Element s = getSheetElement(); - Node n = s.appendChild(g); - if (n != null) { - int index = DOMUtils.getElementIndex(s, TAG_MARKER_GROUP, g); - if (index >= 0) { - fireIndexedTargetChange(Core.MarkerGroupAdd, group, index); - } - } - } - - public void removeMarkerGroup(IMarkerGroup group) { - Element g = ((MarkerGroupImpl) group).getImplementation(); - Element s = getSheetElement(); - if (g.getParentNode() == s) { - int index = DOMUtils.getElementIndex(s, TAG_MARKER_GROUP, g); - if (index >= 0) { - Node n = s.removeChild(g); - if (n != null) { - fireIndexedTargetChange(Core.MarkerGroupRemove, group, - index); - } - } - } - } - - @Override - public boolean isEmpty() { - return !getSheetElement().hasChildNodes(); - } - - protected Object getElementById(String id) { - Object element = getElementRegistry().getElement(id); - if (element == null) { - Element domElement = implementation.getElementById(id); - if (domElement != null) { - element = getElementAdapter(domElement); - } - } - return element; - } - - public ElementRegistry getElementRegistry() { - if (elementRegistry == null) - elementRegistry = new ElementRegistry(); - return elementRegistry; - } - - protected NodeAdaptableProvider getElementAdapterProvider() { - if (elementAdaptableProvider == null) - elementAdaptableProvider = new NodeAdaptableProvider( - getElementRegistry(), this, implementation); - return elementAdaptableProvider; - } - - protected IAdaptable getElementAdapter(Node node) { - return getElementAdapterProvider().getAdaptable(node); - } - - public IAdaptable createAdaptable(Node node) { - if (node instanceof Element) { - Element e = (Element) node; - String tagName = e.getTagName(); - if (TAG_MARKER_GROUP.equals(tagName)) { - return new MarkerGroupImpl(e, this); - } else if (TAG_MARKER.equals(tagName)) { - return new MarkerImpl(e, this); - } - } - return null; - } - - @Deprecated - public void save(OutputStream out) throws IOException, CoreException { - DOMUtils.save(implementation, out, false); - } - - private static final String OLD_MARKERLISTS_XML = "markerlists.xml"; //$NON-NLS-1$ - @SuppressWarnings("unused") - private static final String OLD_TAG_MARKER_LISTS = "markerLists"; //$NON-NLS-1$ - private static final String OLD_TAG_MARKER_LIST = "markerList"; //$NON-NLS-1$ - private static final String OLD_TAG_MARKER = "marker"; //$NON-NLS-1$ - private static final String OLD_ATT_NAME = "name"; //$NON-NLS-1$ - private static final String OLD_ATT_ID = "id"; //$NON-NLS-1$ - private static final String OLD_ATT_FILE = "file"; //$NON-NLS-1$ - - @Deprecated - public void importFrom(String sourcePath) - throws IOException, CoreException { - File sourceFile = new File(sourcePath); - IInputSource source; - if (sourceFile.isDirectory()) { - source = new DirectoryInputSource(sourceFile); - } else { - source = new ZipFileInputSource(new ZipFile(sourceFile)); - } - try { - importFrom(source, new File(sourcePath).getName()); - } finally { - if (source instanceof ZipFileInputSource) { - ((ZipFileInputSource) source).closeZipFile(); - } - } - } - - @Deprecated - public void importFrom(IInputSource source) - throws IOException, CoreException { - importFrom(source, null); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerSheet#importFrom(org.xmind.core.io. - * IInputSource , java.lang.String) - */ - @Deprecated - public void importFrom(IInputSource source, String groupName) - throws IOException, CoreException { - if (source.hasEntry(ArchiveConstants.MARKER_SHEET_XML)) { - InputStream is = source - .openEntryStream(ArchiveConstants.MARKER_SHEET_XML); - IMarkerSheet sourceMarkerSheet = Core.getMarkerSheetBuilder() - .loadFromStream(is, - new MarkerResourceProvider(source, null)); - importFrom(sourceMarkerSheet); - } else if (source.hasEntry(OLD_MARKERLISTS_XML)) { - importFromOldMarkerSheet(source); - } else { - importAllAsNewGroup(source, groupName); - } - } - - @Deprecated - private void importAllAsNewGroup(IInputSource source, String groupName) - throws IOException { - IMarkerGroup group = createMarkerGroup(false); - if (groupName == null) { - groupName = createGroupName(); - } - group.setName(groupName); - Iterator entries = source.getEntries(); - while (entries.hasNext()) { - String entry = entries.next(); - InputStream is = source.openEntryStream(entry); - if (is != null) { - IMarker marker = createMarker(entry); - marker.setName(FileUtils.getFileName(entry)); - group.addMarker(marker); - IMarkerResource resource = marker.getResource(); - if (resource != null) { - OutputStream os = resource.openOutputStream(); - if (os != null) { - try { - FileUtils.transfer(is, os, true); - } catch (IOException ignore) { - } - } - } - } - } - addMarkerGroup(group); - } - - private String createGroupName() { - return "Group " + (getMarkerGroups().size() + 1); //$NON-NLS-1$ - //return Core.getIdFactory().createId(); - } - - @Deprecated - private void importFromOldMarkerSheet(IInputSource source) - throws IOException { - InputStream is = source.openEntryStream(OLD_MARKERLISTS_XML); - if (is == null) - throw new FileNotFoundException(); - Document document = DOMUtils.loadDocument(is); - Iterator listIt = DOMUtils.childElementIterByTag( - document.getDocumentElement(), OLD_TAG_MARKER_LIST); - while (listIt.hasNext()) { - Element listEle = listIt.next(); - String listId = listEle.getAttribute(OLD_ATT_ID); - IMarkerGroup existingGroup = findMarkerGroup(listId); - if (existingGroup != null) { - importGroupFromOld(source, listEle, existingGroup); - } else { - IMarkerGroup newGroup = createMarkerGroup(false); - replaceId(newGroup, listId); - addMarkerGroup(newGroup); - importGroupFromOld(source, listEle, newGroup); - } - } - - } - - private void replaceId(IAdaptable adaptable, String newId) { - Element ele = (Element) adaptable.getAdapter(Element.class); - if (ele == null) - return; - String oldId = ele.getAttribute(DOMConstants.ATTR_ID); - getElementRegistry().unregisterByKey(oldId); - ele.setAttribute(DOMConstants.ATTR_ID, newId); - getElementRegistry().registerByKey(newId, adaptable); - } - - @Deprecated - private void importGroupFromOld(IInputSource source, Element listEle, - IMarkerGroup targetGroup) throws IOException { - targetGroup.setName(listEle.getAttribute(OLD_ATT_NAME)); - Iterator markerIt = DOMUtils.childElementIterByTag(listEle, - OLD_TAG_MARKER); - while (markerIt.hasNext()) { - Element markerEle = markerIt.next(); - String file = DOMUtils.getAttribute(markerEle, OLD_ATT_FILE); - if (file != null) { - String markerId = markerEle.getAttribute(OLD_ATT_ID); - IMarker targetMarker = findMarker(markerId); - if (targetMarker == null) { - targetMarker = targetGroup.getOwnedSheet().createMarker( - createGroupName() + FileUtils.getExtension(file)); - replaceId(targetMarker, markerId); - targetGroup.addMarker(targetMarker); - } - targetMarker.setName(markerEle.getAttribute(OLD_ATT_NAME)); - String oldEntryName = listEle.getAttribute(OLD_ATT_ID) + "/" //$NON-NLS-1$ - + file; - IMarkerResource newRes = targetMarker.getResource(); - if (newRes != null) { - OutputStream os = newRes.openOutputStream(); - if (os != null) { - if (source.hasEntry(oldEntryName)) { - InputStream mis = source - .openEntryStream(oldEntryName); - FileUtils.transfer(mis, os, true); - } - } - } - } - } - } - - @Deprecated - public void importFrom(IMarkerSheet sheet) { - try { - importFromChecked(sheet); - } catch (Exception e) { - Core.getLogger().log(e); - } - } - - @Deprecated - public void importFromChecked(IMarkerSheet sheet) - throws IOException, CoreException { - for (IMarkerGroup group : sheet.getMarkerGroups()) { - importGroupChecked(group); - } - } - - @Deprecated - public IMarkerGroup importGroup(IMarkerGroup group) { - try { - return importGroupChecked(group); - } catch (Exception e) { - Core.getLogger().log(e); - return null; - } - } - - @Deprecated - public IMarkerGroup importGroupChecked(IMarkerGroup group) - throws IOException, CoreException { - String id = group.getId(); - IMarkerGroup existingGroup = findMarkerGroup(id); - if (existingGroup != null) { - existingGroup.setName(group.getName()); - importGroup(group, existingGroup); - if (existingGroup.getParent() == null) - addMarkerGroup(existingGroup); - return existingGroup; - } - - IMarkerGroup targetGroup = createMarkerGroup(group.isSingleton()); - replaceId(targetGroup, group.getId()); - targetGroup.setName(group.getName()); - importGroup(group, targetGroup); - addMarkerGroup(targetGroup); - return targetGroup; - } - - @Deprecated - private void importGroup(IMarkerGroup sourceGroup, IMarkerGroup targetGroup) - throws IOException { - for (IMarker sourceMarker : sourceGroup.getMarkers()) { - String id = sourceMarker.getId(); - IMarker targetMarker = getLocalMarker(id); - if (targetMarker == null - || !targetGroup.equals(targetMarker.getParent())) { - targetMarker = targetGroup.getOwnedSheet() - .createMarker(sourceMarker.getResourcePath()); - replaceId(targetMarker, sourceMarker.getId()); - targetGroup.addMarker(targetMarker); - } - targetMarker.setName(sourceMarker.getName()); - IMarkerResource sourceRes = sourceMarker.getResource(); - if (sourceRes != null) { - InputStream is = sourceRes.openInputStream(); - IMarkerResource targetRes = targetMarker.getResource(); - if (targetRes != null) { - OutputStream os = targetRes.openOutputStream(); - FileUtils.transfer(is, os, true); - } - } - } - } - - public Properties getProperties() { - return properties; - } - - public void setProperties(Properties properties) { - this.properties = properties; - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public CoreEventSupport getCoreEventSupport() { - if (coreEventSupport != null) - return coreEventSupport; - - coreEventSupport = new CoreEventSupport(); - return coreEventSupport; - } - - private void fireIndexedTargetChange(String type, Object target, - int index) { - getCoreEventSupport().dispatchIndexedTargetChange(this, type, target, - index); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerSheet#createMarkerResourcePath(java.io. - * InputStream, java.lang.String) - */ - public String allocateMarkerResource(InputStream source, - String suggestedPath) throws IOException { - if (realResourceProvider != null - && realResourceProvider instanceof IMarkerResourceAllocator) { - return ((IMarkerResourceAllocator) realResourceProvider) - .allocateMarkerResource(source, suggestedPath); - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_SINGLETON; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_GROUP; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_SHEET; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.zip.ZipFile; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IManifest; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.ElementRegistry; +import org.xmind.core.internal.MarkerSheet; +import org.xmind.core.internal.event.CoreEventSupport; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.internal.zip.ZipFileInputSource; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.io.IInputSource; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerResource; +import org.xmind.core.marker.IMarkerResourceAllocator; +import org.xmind.core.marker.IMarkerResourceProvider; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.IPropertiesProvider; + +public class MarkerSheetImpl extends MarkerSheet implements + INodeAdaptableFactory, ICoreEventSource, IPropertiesProvider { + + private Document implementation; + + private IMarkerResourceProvider realResourceProvider; + + private ElementRegistry elementRegistry = null; + + private NodeAdaptableProvider elementAdaptableProvider = null; + + private CoreEventSupport coreEventSupport = null; + + private Properties properties = null; + + private ManifestImpl manifest = null; + + public MarkerSheetImpl(Document implementation, + IMarkerResourceProvider resourceProvider) { + this.implementation = implementation; + this.realResourceProvider = resourceProvider; + init(); + } + + private void init() { + Element m = DOMUtils.ensureChildElement(implementation, + TAG_MARKER_SHEET); + NS.setNS(NS.Marker, m); + InternalDOMUtils.addVersion(implementation); + } + + public Document getImplementation() { + return implementation; + } + + public Element getSheetElement() { + return implementation.getDocumentElement(); + } + + /** + * @param manifest + * the manifest to set + */ + public void setManifest(ManifestImpl manifest) { + this.manifest = manifest; + } + + public T getAdapter(Class adapter) { + if (IManifest.class.equals(adapter)) + return adapter.cast(manifest); + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (IMarkerResourceProvider.class.equals(adapter)) + return adapter.cast(realResourceProvider); + if (ICoreEventSupport.class.equals(adapter)) + return adapter.cast(getCoreEventSupport()); + if (IPropertiesProvider.class.equals(adapter)) + return adapter.cast(this); + if (Properties.class.equals(adapter)) + return adapter.cast(getProperties()); + if (ElementRegistry.class.equals(adapter)) + return adapter.cast(getElementRegistry()); + if (INodeAdaptableFactory.class.equals(adapter)) + return adapter.cast(this); + if (INodeAdaptableProvider.class.equals(adapter)) + return adapter.cast(getElementAdapterProvider()); + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + protected IMarkerResource getMarkerResource(IMarker marker) { + if (realResourceProvider != null) + return realResourceProvider.getMarkerResource(marker); + return null; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof MarkerSheetImpl)) + return false; + MarkerSheetImpl that = (MarkerSheetImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return DOMUtils.toString(implementation); + } + + public boolean isPermanent() { + return realResourceProvider == null + || realResourceProvider.isPermanent(); + } + + public IMarker createMarker(String resourcePath) { + Element markerImpl = implementation.createElement(TAG_MARKER); + DOMUtils.setAttribute(markerImpl, ATTR_RESOURCE, resourcePath); + MarkerImpl marker = new MarkerImpl(markerImpl, this); + getElementRegistry().register(marker); + return marker; + } + + public IMarker createMarkerById(String markerId, String resourcePath) { + Element markerImpl = implementation.createElement(TAG_MARKER); + DOMUtils.setAttribute(markerImpl, ATTR_RESOURCE, resourcePath); + MarkerImpl marker = new MarkerImpl(markerImpl, this); + replaceId(marker, markerId); + getElementRegistry().register(marker); + return marker; + } + + public IMarkerGroup createMarkerGroupById(String groupId) { + Element groupImpl = implementation.createElement(TAG_MARKER_GROUP); + MarkerGroupImpl group = new MarkerGroupImpl(groupImpl, this); + replaceId(group, groupId); + getElementRegistry().register(group); + return group; + } + + public IMarkerGroup createMarkerGroup(boolean singleton) { + Element groupImpl = implementation.createElement(TAG_MARKER_GROUP); + if (singleton) + groupImpl.setAttribute(ATTR_SINGLETON, Boolean.toString(singleton)); + MarkerGroupImpl group = new MarkerGroupImpl(groupImpl, this); + getElementRegistry().register(group); + return group; + } + + protected IMarker getLocalMarker(String markerId) { + Object element = getElementById(markerId); + if (element != null && element instanceof IMarker) + return (IMarker) element; + return null; + } + + protected IMarkerGroup getLocalMarkerGroup(String groupId) { + Object element = getElementById(groupId); + if (element != null && element instanceof IMarkerGroup) + return (IMarkerGroup) element; + return null; + } + + public List getMarkerGroups() { + return DOMUtils.getChildList(getSheetElement(), TAG_MARKER_GROUP, + getElementAdapterProvider()); + } + + public void addMarkerGroup(IMarkerGroup group) { + Element g = ((MarkerGroupImpl) group).getImplementation(); + Element s = getSheetElement(); + Node n = s.appendChild(g); + if (n != null) { + int index = DOMUtils.getElementIndex(s, TAG_MARKER_GROUP, g); + if (index >= 0) { + fireIndexedTargetChange(Core.MarkerGroupAdd, group, index); + } + } + } + + public void removeMarkerGroup(IMarkerGroup group) { + Element g = ((MarkerGroupImpl) group).getImplementation(); + Element s = getSheetElement(); + if (g.getParentNode() == s) { + int index = DOMUtils.getElementIndex(s, TAG_MARKER_GROUP, g); + if (index >= 0) { + Node n = s.removeChild(g); + if (n != null) { + fireIndexedTargetChange(Core.MarkerGroupRemove, group, + index); + } + } + } + } + + @Override + public boolean isEmpty() { + return !getSheetElement().hasChildNodes(); + } + + protected Object getElementById(String id) { + Object element = getElementRegistry().getElement(id); + if (element == null) { + Element domElement = implementation.getElementById(id); + if (domElement != null) { + element = getElementAdapter(domElement); + } + } + return element; + } + + public ElementRegistry getElementRegistry() { + if (elementRegistry == null) + elementRegistry = new ElementRegistry(); + return elementRegistry; + } + + protected NodeAdaptableProvider getElementAdapterProvider() { + if (elementAdaptableProvider == null) + elementAdaptableProvider = new NodeAdaptableProvider( + getElementRegistry(), this, implementation); + return elementAdaptableProvider; + } + + protected IAdaptable getElementAdapter(Node node) { + return getElementAdapterProvider().getAdaptable(node); + } + + public IAdaptable createAdaptable(Node node) { + if (node instanceof Element) { + Element e = (Element) node; + String tagName = e.getTagName(); + if (TAG_MARKER_GROUP.equals(tagName)) { + return new MarkerGroupImpl(e, this); + } else if (TAG_MARKER.equals(tagName)) { + return new MarkerImpl(e, this); + } + } + return null; + } + + @Deprecated + public void save(OutputStream out) throws IOException, CoreException { + DOMUtils.save(implementation, out, false); + } + + private static final String OLD_MARKERLISTS_XML = "markerlists.xml"; //$NON-NLS-1$ + @SuppressWarnings("unused") + private static final String OLD_TAG_MARKER_LISTS = "markerLists"; //$NON-NLS-1$ + private static final String OLD_TAG_MARKER_LIST = "markerList"; //$NON-NLS-1$ + private static final String OLD_TAG_MARKER = "marker"; //$NON-NLS-1$ + private static final String OLD_ATT_NAME = "name"; //$NON-NLS-1$ + private static final String OLD_ATT_ID = "id"; //$NON-NLS-1$ + private static final String OLD_ATT_FILE = "file"; //$NON-NLS-1$ + + @Deprecated + public void importFrom(String sourcePath) + throws IOException, CoreException { + File sourceFile = new File(sourcePath); + IInputSource source; + if (sourceFile.isDirectory()) { + source = new DirectoryInputSource(sourceFile); + } else { + source = new ZipFileInputSource(new ZipFile(sourceFile)); + } + try { + importFrom(source, new File(sourcePath).getName()); + } finally { + if (source instanceof ZipFileInputSource) { + ((ZipFileInputSource) source).closeZipFile(); + } + } + } + + @Deprecated + public void importFrom(IInputSource source) + throws IOException, CoreException { + importFrom(source, null); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerSheet#importFrom(org.xmind.core.io. + * IInputSource , java.lang.String) + */ + @Deprecated + public void importFrom(IInputSource source, String groupName) + throws IOException, CoreException { + if (source.hasEntry(ArchiveConstants.MARKER_SHEET_XML)) { + InputStream is = source + .openEntryStream(ArchiveConstants.MARKER_SHEET_XML); + IMarkerSheet sourceMarkerSheet = Core.getMarkerSheetBuilder() + .loadFromStream(is, + new MarkerResourceProvider(source, null)); + importFrom(sourceMarkerSheet); + } else if (source.hasEntry(OLD_MARKERLISTS_XML)) { + importFromOldMarkerSheet(source); + } else { + importAllAsNewGroup(source, groupName); + } + } + + @Deprecated + private void importAllAsNewGroup(IInputSource source, String groupName) + throws IOException { + IMarkerGroup group = createMarkerGroup(false); + if (groupName == null) { + groupName = createGroupName(); + } + group.setName(groupName); + Iterator entries = source.getEntries(); + while (entries.hasNext()) { + String entry = entries.next(); + InputStream is = source.openEntryStream(entry); + if (is != null) { + IMarker marker = createMarker(entry); + marker.setName(FileUtils.getFileName(entry)); + group.addMarker(marker); + IMarkerResource resource = marker.getResource(); + if (resource != null) { + OutputStream os = resource.openOutputStream(); + if (os != null) { + try { + FileUtils.transfer(is, os, true); + } catch (IOException ignore) { + } + } + } + } + } + addMarkerGroup(group); + } + + private String createGroupName() { + return "Group " + (getMarkerGroups().size() + 1); //$NON-NLS-1$ + //return Core.getIdFactory().createId(); + } + + @Deprecated + private void importFromOldMarkerSheet(IInputSource source) + throws IOException { + InputStream is = source.openEntryStream(OLD_MARKERLISTS_XML); + if (is == null) + throw new FileNotFoundException(); + Document document = DOMUtils.loadDocument(is); + Iterator listIt = DOMUtils.childElementIterByTag( + document.getDocumentElement(), OLD_TAG_MARKER_LIST); + while (listIt.hasNext()) { + Element listEle = listIt.next(); + String listId = listEle.getAttribute(OLD_ATT_ID); + IMarkerGroup existingGroup = findMarkerGroup(listId); + if (existingGroup != null) { + importGroupFromOld(source, listEle, existingGroup); + } else { + IMarkerGroup newGroup = createMarkerGroup(false); + replaceId(newGroup, listId); + addMarkerGroup(newGroup); + importGroupFromOld(source, listEle, newGroup); + } + } + + } + + private void replaceId(IAdaptable adaptable, String newId) { + Element ele = (Element) adaptable.getAdapter(Element.class); + if (ele == null) + return; + String oldId = ele.getAttribute(DOMConstants.ATTR_ID); + getElementRegistry().unregisterByKey(oldId); + ele.setAttribute(DOMConstants.ATTR_ID, newId); + getElementRegistry().registerByKey(newId, adaptable); + } + + @Deprecated + private void importGroupFromOld(IInputSource source, Element listEle, + IMarkerGroup targetGroup) throws IOException { + targetGroup.setName(listEle.getAttribute(OLD_ATT_NAME)); + Iterator markerIt = DOMUtils.childElementIterByTag(listEle, + OLD_TAG_MARKER); + while (markerIt.hasNext()) { + Element markerEle = markerIt.next(); + String file = DOMUtils.getAttribute(markerEle, OLD_ATT_FILE); + if (file != null) { + String markerId = markerEle.getAttribute(OLD_ATT_ID); + IMarker targetMarker = findMarker(markerId); + if (targetMarker == null) { + targetMarker = targetGroup.getOwnedSheet().createMarker( + createGroupName() + FileUtils.getExtension(file)); + replaceId(targetMarker, markerId); + targetGroup.addMarker(targetMarker); + } + targetMarker.setName(markerEle.getAttribute(OLD_ATT_NAME)); + String oldEntryName = listEle.getAttribute(OLD_ATT_ID) + "/" //$NON-NLS-1$ + + file; + IMarkerResource newRes = targetMarker.getResource(); + if (newRes != null) { + OutputStream os = newRes.openOutputStream(); + if (os != null) { + if (source.hasEntry(oldEntryName)) { + InputStream mis = source + .openEntryStream(oldEntryName); + FileUtils.transfer(mis, os, true); + } + } + } + } + } + } + + @Deprecated + public void importFrom(IMarkerSheet sheet) { + try { + importFromChecked(sheet); + } catch (Exception e) { + Core.getLogger().log(e); + } + } + + @Deprecated + public void importFromChecked(IMarkerSheet sheet) + throws IOException, CoreException { + for (IMarkerGroup group : sheet.getMarkerGroups()) { + importGroupChecked(group); + } + } + + @Deprecated + public IMarkerGroup importGroup(IMarkerGroup group) { + try { + return importGroupChecked(group); + } catch (Exception e) { + Core.getLogger().log(e); + return null; + } + } + + @Deprecated + public IMarkerGroup importGroupChecked(IMarkerGroup group) + throws IOException, CoreException { + String id = group.getId(); + IMarkerGroup existingGroup = findMarkerGroup(id); + if (existingGroup != null) { + existingGroup.setName(group.getName()); + importGroup(group, existingGroup); + if (existingGroup.getParent() == null) + addMarkerGroup(existingGroup); + return existingGroup; + } + + IMarkerGroup targetGroup = createMarkerGroup(group.isSingleton()); + replaceId(targetGroup, group.getId()); + targetGroup.setName(group.getName()); + importGroup(group, targetGroup); + addMarkerGroup(targetGroup); + return targetGroup; + } + + @Deprecated + private void importGroup(IMarkerGroup sourceGroup, IMarkerGroup targetGroup) + throws IOException { + for (IMarker sourceMarker : sourceGroup.getMarkers()) { + String id = sourceMarker.getId(); + IMarker targetMarker = getLocalMarker(id); + if (targetMarker == null + || !targetGroup.equals(targetMarker.getParent())) { + targetMarker = targetGroup.getOwnedSheet() + .createMarker(sourceMarker.getResourcePath()); + replaceId(targetMarker, sourceMarker.getId()); + targetGroup.addMarker(targetMarker); + } + targetMarker.setName(sourceMarker.getName()); + IMarkerResource sourceRes = sourceMarker.getResource(); + if (sourceRes != null) { + InputStream is = sourceRes.openInputStream(); + IMarkerResource targetRes = targetMarker.getResource(); + if (targetRes != null) { + OutputStream os = targetRes.openOutputStream(); + FileUtils.transfer(is, os, true); + } + } + } + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public CoreEventSupport getCoreEventSupport() { + if (coreEventSupport != null) + return coreEventSupport; + + coreEventSupport = new CoreEventSupport(); + return coreEventSupport; + } + + private void fireIndexedTargetChange(String type, Object target, + int index) { + getCoreEventSupport().dispatchIndexedTargetChange(this, type, target, + index); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerSheet#createMarkerResourcePath(java.io. + * InputStream, java.lang.String) + */ + public String allocateMarkerResource(InputStream source, + String suggestedPath) throws IOException { + if (realResourceProvider != null + && realResourceProvider instanceof IMarkerResourceAllocator) { + return ((IMarkerResourceAllocator) realResourceProvider) + .allocateMarkerResource(source, suggestedPath); + } + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaImpl.java index 29dedd2a1..f67b89991 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaImpl.java @@ -1,279 +1,279 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_META; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.IMetaData; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.ElementRegistry; -import org.xmind.core.internal.Meta; -import org.xmind.core.util.DOMUtils; - -@SuppressWarnings("deprecation") -public class MetaImpl extends Meta implements ICoreEventSource { - - private Document implementation; - - private WorkbookImpl ownedWorkbook; - - private ElementRegistry elementRegistry; - - public MetaImpl(Document implementation) { - super(); - this.implementation = implementation; - init(); - } - - /** - * @param ownedWorkbook - * the ownedWorkbook to set - */ - protected void setOwnedWorkbook(WorkbookImpl ownedWorkbook) { - this.ownedWorkbook = ownedWorkbook; - } - - private void init() { - Element m = DOMUtils.ensureChildElement(implementation, TAG_META); - NS.setNS(NS.Meta, m); - InternalDOMUtils.addVersion(implementation); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof MetaImpl)) - return false; - MetaImpl that = (MetaImpl) obj; - return that.implementation == this.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return DOMUtils.toString(implementation); - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(implementation); - if (ElementRegistry.class.equals(adapter)) - return adapter.cast(getElementRegistry()); - return super.getAdapter(adapter); - } - - public Document getImplementation() { - return implementation; - } - - protected Element getMetaElement() { - return implementation.getDocumentElement(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return ownedWorkbook == null; - } - - private String[] getKeys(String keyPath) { - return keyPath.split(SEP); - } - - private Element findElementByPath(String keyPath, boolean ensure) { - String[] keys = getKeys(keyPath); - if (keys.length == 0) - return null; - Element e = getMetaElement(); - Element c = null; - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - if (!"".equals(key)) { //$NON-NLS-1$ - if (ensure) { - c = DOMUtils.ensureChildElement(e, key); - } else { - c = DOMUtils.getFirstChildElementByTag(e, key); - } - if (c == null) - return null; - e = c; - } - } - return c; - } - - public String getValue(String keyPath) { - Element d = findElementByPath(keyPath, false); - return d == null ? null : d.getTextContent(); - } - - public void setValue(String keyPath, String value) { - String oldValue = null; - Element d; - if (value == null) { - d = findElementByPath(keyPath, false); - if (d != null && d.getParentNode() != null) { - oldValue = d.getTextContent(); - d.getParentNode().removeChild(d); - } - } else { - d = findElementByPath(keyPath, true); - if (d != null) { - oldValue = d.getTextContent(); - d.setTextContent(value); - } - } - getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, - keyPath, oldValue, value); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IMeta#getKeyPaths() - */ - public Set getKeyPaths() { - Set keyPaths = new HashSet(); - collectKeyPaths(getMetaElement(), null, keyPaths); - return keyPaths; - } - - private void collectKeyPaths(Element parentEle, String parentKeyPath, - Set keyPaths) { - Iterator it = DOMUtils.childElementIter(parentEle); - while (it.hasNext()) { - Element childEle = it.next(); - String childKey = childEle.getTagName(); - String childKeyPath = parentKeyPath == null ? childKey - : parentKeyPath + SEP + childKey; - if (childEle.hasChildNodes()) { - collectKeyPaths(childEle, childKeyPath, keyPaths); - } else { - keyPaths.add(childKeyPath); - } - } - } - - /** - * @deprecated - */ - public void addMetaData(IMetaData data) { - Element mdEle = ((MetaDataImpl) data).getImplementation(); - getMetaElement().appendChild(mdEle); - String keyPath = ((MetaDataImpl) data).getKeyPath(); - String newValue = data.getValue(); - getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, - keyPath, null, newValue); - } - - /** - * @deprecated - */ - public void removeMetaData(IMetaData data) { - String keyPath = ((MetaDataImpl) data).getKeyPath(); - String oldValue = data.getValue(); - Element mdEle = ((MetaDataImpl) data).getImplementation(); - getMetaElement().removeChild(mdEle); - getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, - keyPath, oldValue, null); - } - - /** - * @deprecated - */ - public IMetaData createMetaData(String key) { - Element mdEle = implementation.createElement(key); - MetaDataImpl md = new MetaDataImpl(mdEle, this); - getElementRegistry().registerByKey(mdEle, md); - return md; - } - - /** - * @deprecated - */ - public IMetaData[] getMetaData(String key) { - List list = new ArrayList(); - Iterator it = DOMUtils.childElementIterByTag(getMetaElement(), - key); - while (it.hasNext()) { - Element mdEle = it.next(); - list.add(getMetaData(mdEle)); - } - return list.toArray(new IMetaData[list.size()]); - } - - /** - * @deprecated - */ - protected MetaDataImpl getMetaData(Element mdEle) { - if (elementRegistry != null) { - Object md = elementRegistry.getElement(mdEle); - if (md != null && md instanceof IMetaData) - return (MetaDataImpl) md; - } - MetaDataImpl md = new MetaDataImpl(mdEle, this); - getElementRegistry().registerByKey(mdEle, md); - return md; - } - - public ElementRegistry getElementRegistry() { - if (elementRegistry == null) { - elementRegistry = new ElementRegistry(); - } - return elementRegistry; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() - */ - public ICoreEventSupport getCoreEventSupport() { - return ownedWorkbook.getCoreEventSupport(); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. - * lang.String, org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_META; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.IMetaData; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.ElementRegistry; +import org.xmind.core.internal.Meta; +import org.xmind.core.util.DOMUtils; + +@SuppressWarnings("deprecation") +public class MetaImpl extends Meta implements ICoreEventSource { + + private Document implementation; + + private WorkbookImpl ownedWorkbook; + + private ElementRegistry elementRegistry; + + public MetaImpl(Document implementation) { + super(); + this.implementation = implementation; + init(); + } + + /** + * @param ownedWorkbook + * the ownedWorkbook to set + */ + protected void setOwnedWorkbook(WorkbookImpl ownedWorkbook) { + this.ownedWorkbook = ownedWorkbook; + } + + private void init() { + Element m = DOMUtils.ensureChildElement(implementation, TAG_META); + NS.setNS(NS.Meta, m); + InternalDOMUtils.addVersion(implementation); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof MetaImpl)) + return false; + MetaImpl that = (MetaImpl) obj; + return that.implementation == this.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return DOMUtils.toString(implementation); + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(implementation); + if (ElementRegistry.class.equals(adapter)) + return adapter.cast(getElementRegistry()); + return super.getAdapter(adapter); + } + + public Document getImplementation() { + return implementation; + } + + protected Element getMetaElement() { + return implementation.getDocumentElement(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return ownedWorkbook == null; + } + + private String[] getKeys(String keyPath) { + return keyPath.split(SEP); + } + + private Element findElementByPath(String keyPath, boolean ensure) { + String[] keys = getKeys(keyPath); + if (keys.length == 0) + return null; + Element e = getMetaElement(); + Element c = null; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (!"".equals(key)) { //$NON-NLS-1$ + if (ensure) { + c = DOMUtils.ensureChildElement(e, key); + } else { + c = DOMUtils.getFirstChildElementByTag(e, key); + } + if (c == null) + return null; + e = c; + } + } + return c; + } + + public String getValue(String keyPath) { + Element d = findElementByPath(keyPath, false); + return d == null ? null : d.getTextContent(); + } + + public void setValue(String keyPath, String value) { + String oldValue = null; + Element d; + if (value == null) { + d = findElementByPath(keyPath, false); + if (d != null && d.getParentNode() != null) { + oldValue = d.getTextContent(); + d.getParentNode().removeChild(d); + } + } else { + d = findElementByPath(keyPath, true); + if (d != null) { + oldValue = d.getTextContent(); + d.setTextContent(value); + } + } + getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, + keyPath, oldValue, value); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IMeta#getKeyPaths() + */ + public Set getKeyPaths() { + Set keyPaths = new HashSet(); + collectKeyPaths(getMetaElement(), null, keyPaths); + return keyPaths; + } + + private void collectKeyPaths(Element parentEle, String parentKeyPath, + Set keyPaths) { + Iterator it = DOMUtils.childElementIter(parentEle); + while (it.hasNext()) { + Element childEle = it.next(); + String childKey = childEle.getTagName(); + String childKeyPath = parentKeyPath == null ? childKey + : parentKeyPath + SEP + childKey; + if (childEle.hasChildNodes()) { + collectKeyPaths(childEle, childKeyPath, keyPaths); + } else { + keyPaths.add(childKeyPath); + } + } + } + + /** + * @deprecated + */ + public void addMetaData(IMetaData data) { + Element mdEle = ((MetaDataImpl) data).getImplementation(); + getMetaElement().appendChild(mdEle); + String keyPath = ((MetaDataImpl) data).getKeyPath(); + String newValue = data.getValue(); + getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, + keyPath, null, newValue); + } + + /** + * @deprecated + */ + public void removeMetaData(IMetaData data) { + String keyPath = ((MetaDataImpl) data).getKeyPath(); + String oldValue = data.getValue(); + Element mdEle = ((MetaDataImpl) data).getImplementation(); + getMetaElement().removeChild(mdEle); + getCoreEventSupport().dispatchTargetValueChange(this, Core.Metadata, + keyPath, oldValue, null); + } + + /** + * @deprecated + */ + public IMetaData createMetaData(String key) { + Element mdEle = implementation.createElement(key); + MetaDataImpl md = new MetaDataImpl(mdEle, this); + getElementRegistry().registerByKey(mdEle, md); + return md; + } + + /** + * @deprecated + */ + public IMetaData[] getMetaData(String key) { + List list = new ArrayList(); + Iterator it = DOMUtils.childElementIterByTag(getMetaElement(), + key); + while (it.hasNext()) { + Element mdEle = it.next(); + list.add(getMetaData(mdEle)); + } + return list.toArray(new IMetaData[list.size()]); + } + + /** + * @deprecated + */ + protected MetaDataImpl getMetaData(Element mdEle) { + if (elementRegistry != null) { + Object md = elementRegistry.getElement(mdEle); + if (md != null && md instanceof IMetaData) + return (MetaDataImpl) md; + } + MetaDataImpl md = new MetaDataImpl(mdEle, this); + getElementRegistry().registerByKey(mdEle, md); + return md; + } + + public ElementRegistry getElementRegistry() { + if (elementRegistry == null) { + elementRegistry = new ElementRegistry(); + } + return elementRegistry; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() + */ + public ICoreEventSupport getCoreEventSupport() { + return ownedWorkbook.getCoreEventSupport(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. + * lang.String, org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NS.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NS.java index e6f26f055..b166babf1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NS.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NS.java @@ -1,81 +1,81 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import org.w3c.dom.Element; - -public enum NS { - - /* Internal Namespaces */ - XMAP("xmap", "urn:xmind:xmap:xmlns:content:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Style("style", "urn:xmind:xmap:xmlns:style:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Marker("marker", "urn:xmind:xmap:xmlns:marker:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Meta("meta", "urn:xmind:xmap:xmlns:meta:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Comments("comments", "urn:xmind:xmap:xmlns:comments:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Manifest("manifest", "urn:xmind:xmap:xmlns:manifest:1.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Revision("revision", "urn:xmind:xmap:xmlns:revision:1.0"), //$NON-NLS-1$ //$NON-NLS-2$ - Assignee("assignee", "urn:xmind:xmap:xmlns:assignee:1.0"), //$NON-NLS-1$//$NON-NLS-2$ - Stories("stories", "urn:xmind:xmap:xmlns:stories:1.0"), //$NON-NLS-1$//$NON-NLS-2$ - - /* External Namespaces */ - Xhtml("xhtml", "http://www.w3.org/1999/xhtml"), //$NON-NLS-1$ //$NON-NLS-2$ - Xlink("xlink", "http://www.w3.org/1999/xlink"), //$NON-NLS-1$ //$NON-NLS-2$ - Fo("fo", "http://www.w3.org/1999/XSL/Format"), //$NON-NLS-1$ //$NON-NLS-2$ - SVG("svg", "http://www.w3.org/2000/svg"); //$NON-NLS-1$ //$NON-NLS-2$ - - private String prefix; - - private String uri; - - private NS(String prefix, String uri) { - this.prefix = prefix; - this.uri = uri; - } - - public String getPrefix() { - return prefix; - } - - public String getURI() { - return uri; - } - - public String getQualifiedName(String localName) { - return prefix + ":" + localName; //$NON-NLS-1$ - } - - public static String getPrefix(String qualifiedName) { - int index = qualifiedName.indexOf(':'); - if (index >= 0) { - return qualifiedName.substring(0, index); - } - return null; - } - - public static String getLocalName(String qualifiedName) { - int index = qualifiedName.indexOf(':'); - if (index >= 0) - return qualifiedName.substring(index + 1); - return qualifiedName; - } - - public static void setNS(NS defaultNS, Element element, NS... nss) { - if (defaultNS != null) - element.setAttribute("xmlns", defaultNS.getURI()); //$NON-NLS-1$ - for (NS ns : nss) { - element.setAttribute("xmlns:" + ns.getPrefix(), ns.getURI()); //$NON-NLS-1$ - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import org.w3c.dom.Element; + +public enum NS { + + /* Internal Namespaces */ + XMAP("xmap", "urn:xmind:xmap:xmlns:content:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Style("style", "urn:xmind:xmap:xmlns:style:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Marker("marker", "urn:xmind:xmap:xmlns:marker:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Meta("meta", "urn:xmind:xmap:xmlns:meta:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Comments("comments", "urn:xmind:xmap:xmlns:comments:2.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Manifest("manifest", "urn:xmind:xmap:xmlns:manifest:1.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Revision("revision", "urn:xmind:xmap:xmlns:revision:1.0"), //$NON-NLS-1$ //$NON-NLS-2$ + Assignee("assignee", "urn:xmind:xmap:xmlns:assignee:1.0"), //$NON-NLS-1$//$NON-NLS-2$ + Stories("stories", "urn:xmind:xmap:xmlns:stories:1.0"), //$NON-NLS-1$//$NON-NLS-2$ + + /* External Namespaces */ + Xhtml("xhtml", "http://www.w3.org/1999/xhtml"), //$NON-NLS-1$ //$NON-NLS-2$ + Xlink("xlink", "http://www.w3.org/1999/xlink"), //$NON-NLS-1$ //$NON-NLS-2$ + Fo("fo", "http://www.w3.org/1999/XSL/Format"), //$NON-NLS-1$ //$NON-NLS-2$ + SVG("svg", "http://www.w3.org/2000/svg"); //$NON-NLS-1$ //$NON-NLS-2$ + + private String prefix; + + private String uri; + + private NS(String prefix, String uri) { + this.prefix = prefix; + this.uri = uri; + } + + public String getPrefix() { + return prefix; + } + + public String getURI() { + return uri; + } + + public String getQualifiedName(String localName) { + return prefix + ":" + localName; //$NON-NLS-1$ + } + + public static String getPrefix(String qualifiedName) { + int index = qualifiedName.indexOf(':'); + if (index >= 0) { + return qualifiedName.substring(0, index); + } + return null; + } + + public static String getLocalName(String qualifiedName) { + int index = qualifiedName.indexOf(':'); + if (index >= 0) + return qualifiedName.substring(index + 1); + return qualifiedName; + } + + public static void setNS(NS defaultNS, Element element, NS... nss) { + if (defaultNS != null) + element.setAttribute("xmlns", defaultNS.getURI()); //$NON-NLS-1$ + for (NS ns : nss) { + element.setAttribute("xmlns:" + ns.getPrefix(), ns.getURI()); //$NON-NLS-1$ + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NodeAdaptableRegistry.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NodeAdaptableRegistry.java index 403fffd99..a71038d81 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NodeAdaptableRegistry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NodeAdaptableRegistry.java @@ -1,203 +1,203 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal.dom; - -import java.util.HashMap; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; - -/** - * @author Frank Shaka - * - */ -public class NodeAdaptableRegistry implements INodeAdaptableProvider { - - private Document defaultDocument; - - private INodeAdaptableFactory factory; - - private Map idMap = new HashMap(); - - private Map nodeMap = new HashMap(); - - /** - * Used to retrieve adaptable object by ID. - */ - private IDKey key = new IDKey(null, null); - - /** - * - */ - public NodeAdaptableRegistry(Document defaultDocument, - INodeAdaptableFactory factory) { - this.defaultDocument = defaultDocument; - this.factory = factory; - } - - public IAdaptable getAdaptable(String id) { - return getAdaptable(id, defaultDocument); - } - - public IAdaptable getAdaptable(String id, Document document) { - IAdaptable a = getAdaptableById(id, document); - if (a == null) { - Element element = document.getElementById(id); - if (element != null) { - a = getAdaptableByNode(element); - if (a == null) { - a = createAdaptable(element); - } - if (a != null) { - registerByNode(a, element); - registerById(a, id, document); - } - } - } - return a; - } - - public IAdaptable getAdaptable(Node node) { - IAdaptable a = nodeMap.get(node); - if (a == null) { - a = createAdaptable(node); - if (a != null) { - registerByNode(a, node); - String id = getId(node); - if (id != null) { - registerById(a, id, node.getOwnerDocument()); - } - } - } - return a; - } - - public void register(IAdaptable adaptable, String id) { - register(adaptable, id, defaultDocument); - } - - public void register(IAdaptable adaptable, String id, Document document) { - registerById(adaptable, id, document); - Element element = document.getElementById(id); - if (element != null) { - registerByNode(adaptable, element); - } - } - - public void register(IAdaptable adaptable, Node node) { - registerByNode(adaptable, node); - String id = getId(node); - if (id != null) { - registerById(adaptable, id, node.getOwnerDocument()); - } - } - - public void unregister(IAdaptable adaptable, String id) { - unregister(adaptable, id, defaultDocument); - } - - public void unregister(IAdaptable adaptable, String id, Document document) { - unregisterById(adaptable, id, document); - Element element = document.getElementById(id); - if (element != null) { - unregisterByNode(adaptable, element); - } - } - - public void unregister(IAdaptable adaptable, Node node) { - unregisterByNode(adaptable, node); - String id = getId(node); - if (id != null) { - unregisterById(adaptable, id, node.getOwnerDocument()); - } - } - - private String getId(Node node) { - if (node.getNodeType() == Node.ELEMENT_NODE) { - Node v = node.getAttributes().getNamedItem(DOMConstants.ATTR_ID); - if (v != null) { - String id = v.getNodeValue(); - if (id != null && !"".equals(id)) { //$NON-NLS-1$ - return id; - } - } - } - return null; - } - - /** - * @param id - * @param document - * @return - */ - private IDKey getIDKey(String id, Document document) { - key.id = id; - key.document = document; - return key; - } - - /** - * @param id - * @param document - * @return - */ - private IDKey createIDKey(String id, Document document) { - return new IDKey(document, id); - } - - public IAdaptable getAdaptableById(String id, Document document) { - return idMap.get(getIDKey(id, document)); - } - - public IAdaptable getAdaptableByNode(Node node) { - return nodeMap.get(node); - } - - public void registerById(IAdaptable adaptable, String id, Document document) { - idMap.put(createIDKey(id, document), adaptable); - } - - public void registerByNode(IAdaptable adaptable, Node node) { - nodeMap.put(node, adaptable); - } - - public void unregisterById(IAdaptable adaptable, String id, - Document document) { - IDKey key = getIDKey(id, document); - IAdaptable a = idMap.get(key); - if (a == adaptable || (a != null && a.equals(adaptable))) { - idMap.remove(key); - } - } - - public void unregisterByNode(IAdaptable adaptable, Node node) { - IAdaptable a = nodeMap.get(node); - if (a == adaptable || (a != null && a.equals(adaptable))) { - nodeMap.remove(node); - } - } - - /** - * @param element - * @return - */ - private IAdaptable createAdaptable(Node element) { - return factory == null ? null : factory.createAdaptable(element); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal.dom; + +import java.util.HashMap; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; + +/** + * @author Frank Shaka + * + */ +public class NodeAdaptableRegistry implements INodeAdaptableProvider { + + private Document defaultDocument; + + private INodeAdaptableFactory factory; + + private Map idMap = new HashMap(); + + private Map nodeMap = new HashMap(); + + /** + * Used to retrieve adaptable object by ID. + */ + private IDKey key = new IDKey(null, null); + + /** + * + */ + public NodeAdaptableRegistry(Document defaultDocument, + INodeAdaptableFactory factory) { + this.defaultDocument = defaultDocument; + this.factory = factory; + } + + public IAdaptable getAdaptable(String id) { + return getAdaptable(id, defaultDocument); + } + + public IAdaptable getAdaptable(String id, Document document) { + IAdaptable a = getAdaptableById(id, document); + if (a == null) { + Element element = document.getElementById(id); + if (element != null) { + a = getAdaptableByNode(element); + if (a == null) { + a = createAdaptable(element); + } + if (a != null) { + registerByNode(a, element); + registerById(a, id, document); + } + } + } + return a; + } + + public IAdaptable getAdaptable(Node node) { + IAdaptable a = nodeMap.get(node); + if (a == null) { + a = createAdaptable(node); + if (a != null) { + registerByNode(a, node); + String id = getId(node); + if (id != null) { + registerById(a, id, node.getOwnerDocument()); + } + } + } + return a; + } + + public void register(IAdaptable adaptable, String id) { + register(adaptable, id, defaultDocument); + } + + public void register(IAdaptable adaptable, String id, Document document) { + registerById(adaptable, id, document); + Element element = document.getElementById(id); + if (element != null) { + registerByNode(adaptable, element); + } + } + + public void register(IAdaptable adaptable, Node node) { + registerByNode(adaptable, node); + String id = getId(node); + if (id != null) { + registerById(adaptable, id, node.getOwnerDocument()); + } + } + + public void unregister(IAdaptable adaptable, String id) { + unregister(adaptable, id, defaultDocument); + } + + public void unregister(IAdaptable adaptable, String id, Document document) { + unregisterById(adaptable, id, document); + Element element = document.getElementById(id); + if (element != null) { + unregisterByNode(adaptable, element); + } + } + + public void unregister(IAdaptable adaptable, Node node) { + unregisterByNode(adaptable, node); + String id = getId(node); + if (id != null) { + unregisterById(adaptable, id, node.getOwnerDocument()); + } + } + + private String getId(Node node) { + if (node.getNodeType() == Node.ELEMENT_NODE) { + Node v = node.getAttributes().getNamedItem(DOMConstants.ATTR_ID); + if (v != null) { + String id = v.getNodeValue(); + if (id != null && !"".equals(id)) { //$NON-NLS-1$ + return id; + } + } + } + return null; + } + + /** + * @param id + * @param document + * @return + */ + private IDKey getIDKey(String id, Document document) { + key.id = id; + key.document = document; + return key; + } + + /** + * @param id + * @param document + * @return + */ + private IDKey createIDKey(String id, Document document) { + return new IDKey(document, id); + } + + public IAdaptable getAdaptableById(String id, Document document) { + return idMap.get(getIDKey(id, document)); + } + + public IAdaptable getAdaptableByNode(Node node) { + return nodeMap.get(node); + } + + public void registerById(IAdaptable adaptable, String id, Document document) { + idMap.put(createIDKey(id, document), adaptable); + } + + public void registerByNode(IAdaptable adaptable, Node node) { + nodeMap.put(node, adaptable); + } + + public void unregisterById(IAdaptable adaptable, String id, + Document document) { + IDKey key = getIDKey(id, document); + IAdaptable a = idMap.get(key); + if (a == adaptable || (a != null && a.equals(adaptable))) { + idMap.remove(key); + } + } + + public void unregisterByNode(IAdaptable adaptable, Node node) { + IAdaptable a = nodeMap.get(node); + if (a == adaptable || (a != null && a.equals(adaptable))) { + nodeMap.remove(node); + } + } + + /** + * @param element + * @return + */ + private IAdaptable createAdaptable(Node element) { + return factory == null ? null : factory.createAdaptable(element); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NotesImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NotesImpl.java index 2ff0278b9..876176bd4 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NotesImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NotesImpl.java @@ -1,207 +1,207 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_NOTES; - -import java.util.Iterator; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.INotesContent; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.Notes; -import org.xmind.core.util.DOMUtils; - -/** - * @author briansun - */ -public class NotesImpl extends Notes { - - private Element topicElement; - - private TopicImpl ownedTopic; - - /** - * @param implementation - */ - public NotesImpl(Element topicElement, TopicImpl ownedTopic) { - super(); - this.topicElement = topicElement; - this.ownedTopic = ownedTopic; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof NotesImpl)) - return false; - NotesImpl that = (NotesImpl) obj; - return this.topicElement == that.topicElement; - } - - public int hashCode() { - return topicElement.hashCode(); - } - - public String toString() { - return DOMUtils.toString(getNotesElement()); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getNotesElement()); - return super.getAdapter(adapter); - } - - /** - * @see org.xmind.core.INotes#getParent() - */ - public ITopic getParent() { - return ownedTopic; - } - - private Element getNotesElement() { - return DOMUtils.getFirstChildElementByTag(topicElement, TAG_NOTES); - } - - public INotesContent getContent(String format) { - Element n = getNotesElement(); - if (n != null) { - Element c = DOMUtils.getFirstChildElementByTag(n, format); - if (c != null) { - return getNotesContent(c); - } - } - return null; - } - - public boolean isEmpty() { - Element n = getNotesElement(); - if (n != null) { - return !n.hasChildNodes(); - } - return true; - } - - public void setContent(String format, INotesContent content) { - if (format == null) - return; - - Element notesEle = getNotesElement(); - Element oldContentEle = notesEle == null ? null - : DOMUtils.getFirstChildElementByTag(notesEle, format); - INotesContent oldContent = oldContentEle == null ? null - : getNotesContent(oldContentEle); - - WorkbookImpl workbook = null; - if (oldContent instanceof BaseNotesContentImpl) { - if (workbook == null) - workbook = getRealizedWorkbook(); - ((BaseNotesContentImpl) oldContent).removeNotify(workbook); - } - - if (oldContentEle != null && notesEle != null) { - notesEle.removeChild(oldContentEle); - } - - if (content != null) { - Element newContentEle = (Element) content.getAdapter(Element.class); - if (newContentEle != null) { - if (notesEle == null) - notesEle = DOMUtils.ensureChildElement(topicElement, - TAG_NOTES); - notesEle.appendChild(newContentEle); - } - } - - if (notesEle != null && !notesEle.hasChildNodes()) { - topicElement.removeChild(notesEle); - } - - if (content instanceof BaseNotesContentImpl) { - if (workbook == null) - workbook = getRealizedWorkbook(); - ((BaseNotesContentImpl) content).addNotify(workbook); - } - - fireTargetValueChange(format, oldContent, content); - ownedTopic.updateModificationInfo(); - } - - private INotesContent getNotesContent(Element oldContentEle) { - return (INotesContent) ((WorkbookImpl) getOwnedWorkbook()) - .getAdaptableRegistry().getAdaptable(oldContentEle); - } - - protected WorkbookImpl getRealizedWorkbook() { - ITopic parent = getParent(); - if (parent instanceof TopicImpl) - return ((TopicImpl) parent).getRealizedWorkbook(); - return null; - } - - protected void addNotify(WorkbookImpl workbook) { - Element n = getNotesElement(); - if (n != null) { - Iterator it = DOMUtils.childElementIter(n); - while (it.hasNext()) { - Element c = it.next(); - INotesContent content = getNotesContent(c); - if (content instanceof BaseNotesContentImpl) { - ((BaseNotesContentImpl) content).addNotify(workbook); - } - } - } - } - - protected void removeNotify(WorkbookImpl workbook) { - Element n = getNotesElement(); - if (n != null) { - Iterator it = DOMUtils.childElementIter(n); - while (it.hasNext()) { - Element c = it.next(); - INotesContent content = getNotesContent(c); - if (content instanceof BaseNotesContentImpl) { - ((BaseNotesContentImpl) content).removeNotify(workbook); - } - } - } - } - - private void fireTargetValueChange(Object target, Object oldValue, - Object newValue) { - ownedTopic.getCoreEventSupport().dispatchTargetValueChange(ownedTopic, - Core.TopicNotes, target, oldValue, newValue); - } - - public ISheet getOwnedSheet() { - return ownedTopic.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedTopic.getOwnedWorkbook(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return ownedTopic.isOrphan(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_NOTES; + +import java.util.Iterator; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.INotesContent; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.Notes; +import org.xmind.core.util.DOMUtils; + +/** + * @author briansun + */ +public class NotesImpl extends Notes { + + private Element topicElement; + + private TopicImpl ownedTopic; + + /** + * @param implementation + */ + public NotesImpl(Element topicElement, TopicImpl ownedTopic) { + super(); + this.topicElement = topicElement; + this.ownedTopic = ownedTopic; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof NotesImpl)) + return false; + NotesImpl that = (NotesImpl) obj; + return this.topicElement == that.topicElement; + } + + public int hashCode() { + return topicElement.hashCode(); + } + + public String toString() { + return DOMUtils.toString(getNotesElement()); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getNotesElement()); + return super.getAdapter(adapter); + } + + /** + * @see org.xmind.core.INotes#getParent() + */ + public ITopic getParent() { + return ownedTopic; + } + + private Element getNotesElement() { + return DOMUtils.getFirstChildElementByTag(topicElement, TAG_NOTES); + } + + public INotesContent getContent(String format) { + Element n = getNotesElement(); + if (n != null) { + Element c = DOMUtils.getFirstChildElementByTag(n, format); + if (c != null) { + return getNotesContent(c); + } + } + return null; + } + + public boolean isEmpty() { + Element n = getNotesElement(); + if (n != null) { + return !n.hasChildNodes(); + } + return true; + } + + public void setContent(String format, INotesContent content) { + if (format == null) + return; + + Element notesEle = getNotesElement(); + Element oldContentEle = notesEle == null ? null + : DOMUtils.getFirstChildElementByTag(notesEle, format); + INotesContent oldContent = oldContentEle == null ? null + : getNotesContent(oldContentEle); + + WorkbookImpl workbook = null; + if (oldContent instanceof BaseNotesContentImpl) { + if (workbook == null) + workbook = getRealizedWorkbook(); + ((BaseNotesContentImpl) oldContent).removeNotify(workbook); + } + + if (oldContentEle != null && notesEle != null) { + notesEle.removeChild(oldContentEle); + } + + if (content != null) { + Element newContentEle = (Element) content.getAdapter(Element.class); + if (newContentEle != null) { + if (notesEle == null) + notesEle = DOMUtils.ensureChildElement(topicElement, + TAG_NOTES); + notesEle.appendChild(newContentEle); + } + } + + if (notesEle != null && !notesEle.hasChildNodes()) { + topicElement.removeChild(notesEle); + } + + if (content instanceof BaseNotesContentImpl) { + if (workbook == null) + workbook = getRealizedWorkbook(); + ((BaseNotesContentImpl) content).addNotify(workbook); + } + + fireTargetValueChange(format, oldContent, content); + ownedTopic.updateModificationInfo(); + } + + private INotesContent getNotesContent(Element oldContentEle) { + return (INotesContent) ((WorkbookImpl) getOwnedWorkbook()) + .getAdaptableRegistry().getAdaptable(oldContentEle); + } + + protected WorkbookImpl getRealizedWorkbook() { + ITopic parent = getParent(); + if (parent instanceof TopicImpl) + return ((TopicImpl) parent).getRealizedWorkbook(); + return null; + } + + protected void addNotify(WorkbookImpl workbook) { + Element n = getNotesElement(); + if (n != null) { + Iterator it = DOMUtils.childElementIter(n); + while (it.hasNext()) { + Element c = it.next(); + INotesContent content = getNotesContent(c); + if (content instanceof BaseNotesContentImpl) { + ((BaseNotesContentImpl) content).addNotify(workbook); + } + } + } + } + + protected void removeNotify(WorkbookImpl workbook) { + Element n = getNotesElement(); + if (n != null) { + Iterator it = DOMUtils.childElementIter(n); + while (it.hasNext()) { + Element c = it.next(); + INotesContent content = getNotesContent(c); + if (content instanceof BaseNotesContentImpl) { + ((BaseNotesContentImpl) content).removeNotify(workbook); + } + } + } + } + + private void fireTargetValueChange(Object target, Object oldValue, + Object newValue) { + ownedTopic.getCoreEventSupport().dispatchTargetValueChange(ownedTopic, + Core.TopicNotes, target, oldValue, newValue); + } + + public ISheet getOwnedSheet() { + return ownedTopic.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedTopic.getOwnedWorkbook(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return ownedTopic.isOrphan(); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberUtils.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberUtils.java index 563572708..70434194e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberUtils.java @@ -1,105 +1,105 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.text.DateFormat; -import java.text.ParseException; -import java.util.Date; - -/** - * @author briansun - * - */ -public class NumberUtils { - - private static DateFormat dateFormat = null; - - /** - * @param string - * @param defaultReturn - * @return - */ - public static int safeParseInt(String string, int defaultReturn) { - if (string != null) { - try { - return Integer.parseInt(string); - } catch (Throwable e) { - } - } - return defaultReturn; - } - - /** - * @param s - * @param defaultFloat - * @return - */ - public static float safeParseFloat(String s, float defaultFloat) { - if (s != null) { - try { - return Float.parseFloat(s); - } catch (Throwable e) { - } - } - return defaultFloat; - } - - public static double safeParseDouble(String s, double defaultValue) { - if (s != null) { - try { - return Double.parseDouble(s); - } catch (Throwable e) { - } - } - return defaultValue; - } - - /** - * @param s - * @param defaultLong - * @return - */ - public static long safeParseLong(String s, long defaultLong) { - if (s != null) { - try { - return Long.parseLong(s); - } catch (Throwable e) { - } - } - return defaultLong; - } - - private static DateFormat getDateFormat() { - if (dateFormat == null) - dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, - DateFormat.MEDIUM); - return dateFormat; - } - - public static String formatDate(long time) { - Date date = new Date(time); - return getDateFormat().format(date); - } - - public static long parseDate(String time) { - if (time == null) - return System.currentTimeMillis(); - try { - Date date = getDateFormat().parse(time); - return date.getTime(); - } catch (ParseException e) { - return System.currentTimeMillis(); - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Date; + +/** + * @author briansun + * + */ +public class NumberUtils { + + private static DateFormat dateFormat = null; + + /** + * @param string + * @param defaultReturn + * @return + */ + public static int safeParseInt(String string, int defaultReturn) { + if (string != null) { + try { + return Integer.parseInt(string); + } catch (Throwable e) { + } + } + return defaultReturn; + } + + /** + * @param s + * @param defaultFloat + * @return + */ + public static float safeParseFloat(String s, float defaultFloat) { + if (s != null) { + try { + return Float.parseFloat(s); + } catch (Throwable e) { + } + } + return defaultFloat; + } + + public static double safeParseDouble(String s, double defaultValue) { + if (s != null) { + try { + return Double.parseDouble(s); + } catch (Throwable e) { + } + } + return defaultValue; + } + + /** + * @param s + * @param defaultLong + * @return + */ + public static long safeParseLong(String s, long defaultLong) { + if (s != null) { + try { + return Long.parseLong(s); + } catch (Throwable e) { + } + } + return defaultLong; + } + + private static DateFormat getDateFormat() { + if (dateFormat == null) + dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, + DateFormat.MEDIUM); + return dateFormat; + } + + public static String formatDate(long time) { + Date date = new Date(time); + return getDateFormat().format(date); + } + + public static long parseDate(String time) { + if (time == null) + return System.currentTimeMillis(); + try { + Date date = getDateFormat().parse(time); + return date.getTime(); + } catch (ParseException e) { + return System.currentTimeMillis(); + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberingImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberingImpl.java index ad7e17829..634f9c84a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberingImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/NumberingImpl.java @@ -1,242 +1,242 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_DEPTH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_FORMAT; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_SEPARATOR; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_PREPENDING_NUMBERS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_NUMBERING; -import static org.xmind.core.internal.dom.DOMConstants.TAG_PREFIX; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUFFIX; -import static org.xmind.core.internal.dom.DOMConstants.VAL_NONE; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Numbering; -import org.xmind.core.util.DOMUtils; - -public class NumberingImpl extends Numbering implements ICoreEventSource { - - private Element topicElement; - - private TopicImpl ownedTopic; - - public NumberingImpl(Element topicElement, TopicImpl ownedTopic) { - this.topicElement = topicElement; - this.ownedTopic = ownedTopic; - } - - public Element getNumberingElement() { - return DOMUtils.getFirstChildElementByTag(topicElement, TAG_NUMBERING); - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getNumberingElement()); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof NumberingImpl)) - return false; - NumberingImpl that = (NumberingImpl) obj; - return this.topicElement == that.topicElement; - } - - public int hashCode() { - return topicElement.hashCode(); - } - - public String toString() { - return "Numbering of " + ownedTopic; //$NON-NLS-1$ - } - - public String getNumberFormat() { - Element e = getNumberingElement(); - if (e == null) - return null; - return DOMUtils.getAttribute(e, ATTR_NUMBER_FORMAT); - } - - public String getSeparator() { - Element e = getNumberingElement(); - if (e == null) - return null; - return DOMUtils.getAttribute(e, ATTR_NUMBER_SEPARATOR); - } - - public String getPrefix() { - return getText(TAG_PREFIX); - } - - public String getSuffix() { - return getText(TAG_SUFFIX); - } - - public String getDepth() { - Element e = getNumberingElement(); - if (e == null) - return null; - return DOMUtils.getAttribute(e, ATTR_NUMBER_DEPTH); - } - - public boolean prependsParentNumbers() { - Element e = getNumberingElement(); - if (e == null) - return true; - String value = DOMUtils.getAttribute(e, ATTR_PREPENDING_NUMBERS); - return !VAL_NONE.equals(value); - } - - public ITopic getParent() { - return ownedTopic; - } - - public ISheet getOwnedSheet() { - return ownedTopic.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedTopic.getOwnedWorkbook(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return ownedTopic.isOrphan(); - } - - private void setAttribute(String key, String value) { - if (value == null) { - Element e = getNumberingElement(); - if (e != null) { - e.removeAttribute(key); - if (!e.hasAttributes() && !e.hasChildNodes()) { - topicElement.removeChild(e); - } - } - } else { - Element e = DOMUtils.ensureChildElement(topicElement, - TAG_NUMBERING); - e.setAttribute(key, value); - } - } - - private String getText(String key) { - Element e = getNumberingElement(); - if (e != null) { - return DOMUtils.getTextContentByTag(e, key); - } - return null; - } - - private void setText(String key, String value) { - if (value == null) { - Element e = getNumberingElement(); - if (e != null) { - Element t = DOMUtils.getFirstChildElementByTag(e, key); - if (t != null) { - e.removeChild(t); - if (!e.hasAttributes() && !e.hasChildNodes()) { - topicElement.removeChild(e); - } - } - } - } else { - Element e = DOMUtils.ensureChildElement(topicElement, - TAG_NUMBERING); - Element t = DOMUtils.ensureChildElement(e, key); - t.setTextContent(value); - } - } - - public void setFormat(String format) { - String oldValue = getNumberFormat(); - setAttribute(ATTR_NUMBER_FORMAT, format); - String newValue = getNumberFormat(); - fireValueChange(Core.NumberFormat, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setPrefix(String prefix) { - String oldValue = getPrefix(); - setText(TAG_PREFIX, prefix); - String newValue = getPrefix(); - fireValueChange(Core.NumberingPrefix, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setPrependsParentNumbers(boolean prepend) { - Boolean oldValue = Boolean.valueOf(prependsParentNumbers()); - setAttribute(ATTR_PREPENDING_NUMBERS, prepend ? null : VAL_NONE); - Boolean newValue = Boolean.valueOf(prependsParentNumbers()); - fireValueChange(Core.NumberPrepending, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setSuffix(String suffix) { - String oldValue = getSuffix(); - setText(TAG_SUFFIX, suffix); - String newValue = getSuffix(); - fireValueChange(Core.NumberingSuffix, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setSeparator(String separator) { - String oldValue = getSeparator(); - setAttribute(ATTR_NUMBER_SEPARATOR, separator); - String newValue = getSeparator(); - fireValueChange(Core.NumberingSeparator, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - public void setDepth(String depth) { - String oldValue = String.valueOf(getComputedDepth()); - setAttribute(ATTR_NUMBER_DEPTH, depth); - String newValue = String.valueOf(getComputedDepth()); - fireValueChange(Core.NumberingDepth, oldValue, newValue); - ownedTopic.updateModificationInfo(); - } - - private void fireValueChange(String eventType, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, - newValue); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedTopic.getCoreEventSupport(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_DEPTH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_FORMAT; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NUMBER_SEPARATOR; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_PREPENDING_NUMBERS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_NUMBERING; +import static org.xmind.core.internal.dom.DOMConstants.TAG_PREFIX; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUFFIX; +import static org.xmind.core.internal.dom.DOMConstants.VAL_NONE; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Numbering; +import org.xmind.core.util.DOMUtils; + +public class NumberingImpl extends Numbering implements ICoreEventSource { + + private Element topicElement; + + private TopicImpl ownedTopic; + + public NumberingImpl(Element topicElement, TopicImpl ownedTopic) { + this.topicElement = topicElement; + this.ownedTopic = ownedTopic; + } + + public Element getNumberingElement() { + return DOMUtils.getFirstChildElementByTag(topicElement, TAG_NUMBERING); + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getNumberingElement()); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof NumberingImpl)) + return false; + NumberingImpl that = (NumberingImpl) obj; + return this.topicElement == that.topicElement; + } + + public int hashCode() { + return topicElement.hashCode(); + } + + public String toString() { + return "Numbering of " + ownedTopic; //$NON-NLS-1$ + } + + public String getNumberFormat() { + Element e = getNumberingElement(); + if (e == null) + return null; + return DOMUtils.getAttribute(e, ATTR_NUMBER_FORMAT); + } + + public String getSeparator() { + Element e = getNumberingElement(); + if (e == null) + return null; + return DOMUtils.getAttribute(e, ATTR_NUMBER_SEPARATOR); + } + + public String getPrefix() { + return getText(TAG_PREFIX); + } + + public String getSuffix() { + return getText(TAG_SUFFIX); + } + + public String getDepth() { + Element e = getNumberingElement(); + if (e == null) + return null; + return DOMUtils.getAttribute(e, ATTR_NUMBER_DEPTH); + } + + public boolean prependsParentNumbers() { + Element e = getNumberingElement(); + if (e == null) + return true; + String value = DOMUtils.getAttribute(e, ATTR_PREPENDING_NUMBERS); + return !VAL_NONE.equals(value); + } + + public ITopic getParent() { + return ownedTopic; + } + + public ISheet getOwnedSheet() { + return ownedTopic.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedTopic.getOwnedWorkbook(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return ownedTopic.isOrphan(); + } + + private void setAttribute(String key, String value) { + if (value == null) { + Element e = getNumberingElement(); + if (e != null) { + e.removeAttribute(key); + if (!e.hasAttributes() && !e.hasChildNodes()) { + topicElement.removeChild(e); + } + } + } else { + Element e = DOMUtils.ensureChildElement(topicElement, + TAG_NUMBERING); + e.setAttribute(key, value); + } + } + + private String getText(String key) { + Element e = getNumberingElement(); + if (e != null) { + return DOMUtils.getTextContentByTag(e, key); + } + return null; + } + + private void setText(String key, String value) { + if (value == null) { + Element e = getNumberingElement(); + if (e != null) { + Element t = DOMUtils.getFirstChildElementByTag(e, key); + if (t != null) { + e.removeChild(t); + if (!e.hasAttributes() && !e.hasChildNodes()) { + topicElement.removeChild(e); + } + } + } + } else { + Element e = DOMUtils.ensureChildElement(topicElement, + TAG_NUMBERING); + Element t = DOMUtils.ensureChildElement(e, key); + t.setTextContent(value); + } + } + + public void setFormat(String format) { + String oldValue = getNumberFormat(); + setAttribute(ATTR_NUMBER_FORMAT, format); + String newValue = getNumberFormat(); + fireValueChange(Core.NumberFormat, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setPrefix(String prefix) { + String oldValue = getPrefix(); + setText(TAG_PREFIX, prefix); + String newValue = getPrefix(); + fireValueChange(Core.NumberingPrefix, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setPrependsParentNumbers(boolean prepend) { + Boolean oldValue = Boolean.valueOf(prependsParentNumbers()); + setAttribute(ATTR_PREPENDING_NUMBERS, prepend ? null : VAL_NONE); + Boolean newValue = Boolean.valueOf(prependsParentNumbers()); + fireValueChange(Core.NumberPrepending, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setSuffix(String suffix) { + String oldValue = getSuffix(); + setText(TAG_SUFFIX, suffix); + String newValue = getSuffix(); + fireValueChange(Core.NumberingSuffix, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setSeparator(String separator) { + String oldValue = getSeparator(); + setAttribute(ATTR_NUMBER_SEPARATOR, separator); + String newValue = getSeparator(); + fireValueChange(Core.NumberingSeparator, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + public void setDepth(String depth) { + String oldValue = String.valueOf(getComputedDepth()); + setAttribute(ATTR_NUMBER_DEPTH, depth); + String newValue = String.valueOf(getComputedDepth()); + fireValueChange(Core.NumberingDepth, oldValue, newValue); + ownedTopic.updateModificationInfo(); + } + + private void fireValueChange(String eventType, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, + newValue); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedTopic.getCoreEventSupport(); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ParagraphImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ParagraphImpl.java index 3ad2d9b1b..e88675682 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ParagraphImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ParagraphImpl.java @@ -1,131 +1,131 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.util.List; - -import org.w3c.dom.Element; -import org.xmind.core.IParagraph; -import org.xmind.core.ISpan; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.AbstractWorkbookComponent; -import org.xmind.core.style.IStyle; -import org.xmind.core.util.DOMUtils; - -public class ParagraphImpl extends AbstractWorkbookComponent - implements IParagraph { - - private Element implementation; - - private HtmlNotesContentImpl owner; - - public ParagraphImpl(Element implementation, HtmlNotesContentImpl owner) { - this.implementation = implementation; - this.owner = owner; - } - - public String getStyleType() { - return IStyle.PARAGRAPH; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof ParagraphImpl)) - return false; - ParagraphImpl that = (ParagraphImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return implementation.toString(); - } - - public Element getImplementation() { - return implementation; - } - - public HtmlNotesContentImpl getOwner() { - return owner; - } - - public void addSpan(ISpan span) { - SpanImplBase s = (SpanImplBase) span; - implementation.appendChild(s.getImplementation()); - s.addNotify(owner.getRealizedWorkbook()); - getOwner().updateModifiedTime(); - } - - public List getSpans() { - return DOMUtils.getChildren(implementation, owner); - } - - public void removeSpan(ISpan span) { - SpanImplBase s = (SpanImplBase) span; - s.removeNotify(owner.getRealizedWorkbook()); - implementation.removeChild(s.getImplementation()); - getOwner().updateModifiedTime(); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public String getStyleId() { - return DOMUtils.getAttribute(implementation, - DOMConstants.ATTR_STYLE_ID); - } - - public void setStyleId(String styleId) { - WorkbookImpl workbook = owner.getRealizedWorkbook(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute(implementation, DOMConstants.ATTR_STYLE_ID, - styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - getOwner().updateModifiedTime(); - } - - public IWorkbook getOwnedWorkbook() { - return owner.getOwnedWorkbook(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - protected void addNotify(WorkbookImpl workbook) { - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - for (ISpan span : getSpans()) { - ((SpanImplBase) span).addNotify(workbook); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - for (ISpan span : getSpans()) { - ((SpanImplBase) span).removeNotify(workbook); - } - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.util.List; + +import org.w3c.dom.Element; +import org.xmind.core.IParagraph; +import org.xmind.core.ISpan; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.AbstractWorkbookComponent; +import org.xmind.core.style.IStyle; +import org.xmind.core.util.DOMUtils; + +public class ParagraphImpl extends AbstractWorkbookComponent + implements IParagraph { + + private Element implementation; + + private HtmlNotesContentImpl owner; + + public ParagraphImpl(Element implementation, HtmlNotesContentImpl owner) { + this.implementation = implementation; + this.owner = owner; + } + + public String getStyleType() { + return IStyle.PARAGRAPH; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof ParagraphImpl)) + return false; + ParagraphImpl that = (ParagraphImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return implementation.toString(); + } + + public Element getImplementation() { + return implementation; + } + + public HtmlNotesContentImpl getOwner() { + return owner; + } + + public void addSpan(ISpan span) { + SpanImplBase s = (SpanImplBase) span; + implementation.appendChild(s.getImplementation()); + s.addNotify(owner.getRealizedWorkbook()); + getOwner().updateModifiedTime(); + } + + public List getSpans() { + return DOMUtils.getChildren(implementation, owner); + } + + public void removeSpan(ISpan span) { + SpanImplBase s = (SpanImplBase) span; + s.removeNotify(owner.getRealizedWorkbook()); + implementation.removeChild(s.getImplementation()); + getOwner().updateModifiedTime(); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public String getStyleId() { + return DOMUtils.getAttribute(implementation, + DOMConstants.ATTR_STYLE_ID); + } + + public void setStyleId(String styleId) { + WorkbookImpl workbook = owner.getRealizedWorkbook(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute(implementation, DOMConstants.ATTR_STYLE_ID, + styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + getOwner().updateModifiedTime(); + } + + public IWorkbook getOwnedWorkbook() { + return owner.getOwnedWorkbook(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + protected void addNotify(WorkbookImpl workbook) { + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + for (ISpan span : getSpans()) { + ((SpanImplBase) span).addNotify(workbook); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + for (ISpan span : getSpans()) { + ((SpanImplBase) span).removeNotify(workbook); + } + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/PlainNotesContentImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/PlainNotesContentImpl.java index 4c5a6e728..45c5651db 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/PlainNotesContentImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/PlainNotesContentImpl.java @@ -1,42 +1,42 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import org.w3c.dom.Element; -import org.xmind.core.IPlainNotesContent; - -public class PlainNotesContentImpl extends BaseNotesContentImpl implements - IPlainNotesContent { - - public PlainNotesContentImpl(Element implementation, - WorkbookImpl ownedWorkbook) { - super(implementation, ownedWorkbook); - } - - public String getTextContent() { - return getImplementation().getTextContent(); - } - - public void setTextContent(String textContent) { - getImplementation().setTextContent(textContent); - updateModifiedTime(); - } - - protected void addNotify(WorkbookImpl workbook) { - } - - protected void removeNotify(WorkbookImpl workbook) { - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import org.w3c.dom.Element; +import org.xmind.core.IPlainNotesContent; + +public class PlainNotesContentImpl extends BaseNotesContentImpl implements + IPlainNotesContent { + + public PlainNotesContentImpl(Element implementation, + WorkbookImpl ownedWorkbook) { + super(implementation, ownedWorkbook); + } + + public String getTextContent() { + return getImplementation().getTextContent(); + } + + public void setTextContent(String textContent) { + getImplementation().setTextContent(textContent); + updateModifiedTime(); + } + + protected void addNotify(WorkbookImpl workbook) { + } + + protected void removeNotify(WorkbookImpl workbook) { + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RelationshipImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RelationshipImpl.java index 905acb277..f9a87db9b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RelationshipImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RelationshipImpl.java @@ -1,371 +1,371 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_END1; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_END2; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; - -import java.util.HashMap; -import java.util.Map; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.IAdaptable; -import org.xmind.core.IControlPoint; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Relationship; -import org.xmind.core.util.DOMUtils; - -/** - * @author briansun - */ -public class RelationshipImpl extends Relationship implements ICoreEventSource { - - private Element implementation; - - private WorkbookImpl ownedWorkbook; - - private Map controlPoints = null; - - /** - * @param implementation - */ - public RelationshipImpl(Element implementation, - WorkbookImpl ownedWorkbook) { - super(); - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedWorkbook = ownedWorkbook; - } - - /** - * @return the implementation - */ - public Element getImplementation() { - return implementation; - } - - /** - * @see org.xmind.core.IRelationship#getId() - */ - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof RelationshipImpl)) - return false; - RelationshipImpl r = (RelationshipImpl) obj; - return implementation == r.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "REL#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - /** - * @see org.xmind.core.IRelationship#getEnd1Id() - */ - public String getEnd1Id() { - return DOMUtils.getAttribute(implementation, ATTR_END1); - } - - /** - * @see org.xmind.core.IRelationship#setEnd1Id(java.lang.String) - */ - public void setEnd1Id(String id) { - String oldId = getEnd1Id(); - DOMUtils.setAttribute(implementation, ATTR_END1, id); - String newId = getEnd1Id(); - fireValueChange(Core.RelationshipEnd1, oldId, newId); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.IRelationship#getEnd2Id() - */ - public String getEnd2Id() { - return DOMUtils.getAttribute(implementation, ATTR_END2); - } - - /** - * @see org.xmind.core.IRelationship#setEnd2Id(java.lang.String) - */ - public void setEnd2Id(String id) { - String oldId = getEnd2Id(); - DOMUtils.setAttribute(implementation, ATTR_END2, id); - String newId = getEnd2Id(); - fireValueChange(Core.RelationshipEnd2, oldId, newId); - updateModificationInfo(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.internal.Relationship#getEnd1() - */ - @Override - public IRelationshipEnd getEnd1() { - return findEnd(getEnd1Id()); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.internal.Relationship#getEnd2() - */ - @Override - public IRelationshipEnd getEnd2() { - return findEnd(getEnd2Id()); - } - - private IRelationshipEnd findEnd(String endId) { - if (endId == null) - return null; - - IAdaptable obj = ownedWorkbook.getAdaptableRegistry() - .getAdaptable(endId, implementation.getOwnerDocument()); - if (obj instanceof IRelationshipEnd) { - return (IRelationshipEnd) obj; - } - return null; - } - - /** - * @see org.xmind.core.IRelationship#getParent() - */ - public ISheet getParent() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_RELATIONSHIPS)) { - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_SHEET)) { - return (ISheet) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(p); - } - } - return null; - } - - /** - * @see org.xmind.core.ITitled#setTitleText(java.lang.String) - */ - public void setTitleText(String titleText) { - String oldText = getLocalTitleText(); - DOMUtils.setText(implementation, TAG_TITLE, titleText); - String newText = getLocalTitleText(); - fireValueChange(Core.TitleText, oldText, newText); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.internal.Relationship#getLocalTitleText() - */ - @Override - protected String getLocalTitleText() { - return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); - } - - /** - * @see org.xmind.core.internal.Relationship#getOwnedWorkbook() - */ - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - /** - * @see org.xmind.core.IRelationship#checkAvailable() - */ - public boolean checkAvailable() { - IRelationshipEnd end1 = getEnd1(); - IRelationshipEnd end2 = getEnd2(); - if (end1 != null && end2 != null) { - ISheet sheet1 = end1.getOwnedSheet(); - if (sheet1 != null && sheet1.equals(end2.getOwnedSheet())) - return true; - } - return false; - } - - public String getStyleId() { - return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); - } - - public void setStyleId(String styleId) { - String oldValue = getStyleId(); - WorkbookImpl workbook = getRealizedWorkbook(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - String newValue = getStyleId(); - fireValueChange(Core.Style, oldValue, newValue); - updateModificationInfo(); - } - - public IControlPoint getControlPoint(int index) { - if (controlPoints == null) - controlPoints = new HashMap(); - ControlPointImpl controlPoint = controlPoints - .get(Integer.valueOf(index)); - if (controlPoint == null) { - controlPoint = new ControlPointImpl(this, index); - controlPoints.put(Integer.valueOf(index), controlPoint); - } - return controlPoint; -// Element cp = getControlPointElement(index); -// if (cp != null) { -// return new ControlPointImpl(cp); -// } -// return null; - } - -// private Element getControlPointElement(int index) { -// Element cps = getFirstChildElementByTag(implementation, -// TAG_CONTROL_POINTS); -// return cps == null ? null : getControlPointElement(index, cps); -// } -// -// private Element getControlPointElement(int index, Element cps) { -// Iterator it = childElementIterByTag(cps, TAG_CONTROL_POINT); -// while (it.hasNext()) { -// Element cp = it.next(); -// String i = cp.getAttribute(ATTR_INDEX); -// if (i != null && NumberUtils.safeParseInt(i, -1) == index) -// return cp; -// } -// return null; -// } -// -// public void setControlPoint(int index, double angle, double amount) { -// Element cps = ensureChildElement(implementation, TAG_CONTROL_POINTS); -// Element cp = getControlPointElement(index, cps); -// if (cp == null) { -// cp = createElement(cps, TAG_CONTROL_POINT); -// cp.setAttribute(ATTR_INDEX, Integer.toString(index)); -// } -// cp.setAttribute(ATTR_ANGLE, Double.toString(angle)); -// cp.setAttribute(ATTR_AMOUNT, Double.toString(amount)); -// fireIndexedTargetChange(Core.RelationshipControlPoint, -// getControlPoint(index), index); -// } -// -// public void resetControlPoint(int index) { -// Element cps = getFirstChildElementByTag(implementation, -// TAG_CONTROL_POINTS); -// if (cps == null) -// return; -// Element cp = getControlPointElement(index, cps); -// if (cp == null) -// return; -// cp.removeAttribute(ATTR_ANGLE); -// cp.removeAttribute(ATTR_AMOUNT); -// if (!cp.hasChildNodes()) { -// cps.removeChild(cp); -// } -// fireIndexedTargetChange(Core.RelationshipControlPoint, -// getControlPoint(index), index); -// } - - protected WorkbookImpl getRealizedWorkbook() { - ISheet sheet = getParent(); - if (sheet != null) { - if (ownedWorkbook == sheet.getParent()) - return ownedWorkbook; - } - return null; - } - - protected void addNotify(WorkbookImpl workbook, SheetImpl parent) { - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); - workbook.getAdaptableRegistry().registerById(this, getId(), - getImplementation().getOwnerDocument()); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - } - - protected void removeNotify(WorkbookImpl workbook, SheetImpl parent) { - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - workbook.getAdaptableRegistry().unregisterById(this, getId(), - getImplementation().getOwnerDocument()); - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public ICoreEventSupport getCoreEventSupport() { - // Use workbook's core event support directly, so that - // orphan components can have events broadcasted, which - // will enable transient actions (such as dragging topics - // or adjusting relationship control points, etc.) to - // perform correctly. - return ownedWorkbook.getCoreEventSupport(); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, type, oldValue, - newValue); - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, implementation); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, implementation); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - - ISheet sheet = getParent(); - if (sheet != null) { - ((SheetImpl) sheet).updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_END1; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_END2; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; + +import java.util.HashMap; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.IControlPoint; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Relationship; +import org.xmind.core.util.DOMUtils; + +/** + * @author briansun + */ +public class RelationshipImpl extends Relationship implements ICoreEventSource { + + private Element implementation; + + private WorkbookImpl ownedWorkbook; + + private Map controlPoints = null; + + /** + * @param implementation + */ + public RelationshipImpl(Element implementation, + WorkbookImpl ownedWorkbook) { + super(); + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedWorkbook = ownedWorkbook; + } + + /** + * @return the implementation + */ + public Element getImplementation() { + return implementation; + } + + /** + * @see org.xmind.core.IRelationship#getId() + */ + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof RelationshipImpl)) + return false; + RelationshipImpl r = (RelationshipImpl) obj; + return implementation == r.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "REL#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * @see org.xmind.core.IRelationship#getEnd1Id() + */ + public String getEnd1Id() { + return DOMUtils.getAttribute(implementation, ATTR_END1); + } + + /** + * @see org.xmind.core.IRelationship#setEnd1Id(java.lang.String) + */ + public void setEnd1Id(String id) { + String oldId = getEnd1Id(); + DOMUtils.setAttribute(implementation, ATTR_END1, id); + String newId = getEnd1Id(); + fireValueChange(Core.RelationshipEnd1, oldId, newId); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.IRelationship#getEnd2Id() + */ + public String getEnd2Id() { + return DOMUtils.getAttribute(implementation, ATTR_END2); + } + + /** + * @see org.xmind.core.IRelationship#setEnd2Id(java.lang.String) + */ + public void setEnd2Id(String id) { + String oldId = getEnd2Id(); + DOMUtils.setAttribute(implementation, ATTR_END2, id); + String newId = getEnd2Id(); + fireValueChange(Core.RelationshipEnd2, oldId, newId); + updateModificationInfo(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.internal.Relationship#getEnd1() + */ + @Override + public IRelationshipEnd getEnd1() { + return findEnd(getEnd1Id()); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.internal.Relationship#getEnd2() + */ + @Override + public IRelationshipEnd getEnd2() { + return findEnd(getEnd2Id()); + } + + private IRelationshipEnd findEnd(String endId) { + if (endId == null) + return null; + + IAdaptable obj = ownedWorkbook.getAdaptableRegistry() + .getAdaptable(endId, implementation.getOwnerDocument()); + if (obj instanceof IRelationshipEnd) { + return (IRelationshipEnd) obj; + } + return null; + } + + /** + * @see org.xmind.core.IRelationship#getParent() + */ + public ISheet getParent() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_RELATIONSHIPS)) { + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_SHEET)) { + return (ISheet) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(p); + } + } + return null; + } + + /** + * @see org.xmind.core.ITitled#setTitleText(java.lang.String) + */ + public void setTitleText(String titleText) { + String oldText = getLocalTitleText(); + DOMUtils.setText(implementation, TAG_TITLE, titleText); + String newText = getLocalTitleText(); + fireValueChange(Core.TitleText, oldText, newText); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.internal.Relationship#getLocalTitleText() + */ + @Override + protected String getLocalTitleText() { + return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); + } + + /** + * @see org.xmind.core.internal.Relationship#getOwnedWorkbook() + */ + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + /** + * @see org.xmind.core.IRelationship#checkAvailable() + */ + public boolean checkAvailable() { + IRelationshipEnd end1 = getEnd1(); + IRelationshipEnd end2 = getEnd2(); + if (end1 != null && end2 != null) { + ISheet sheet1 = end1.getOwnedSheet(); + if (sheet1 != null && sheet1.equals(end2.getOwnedSheet())) + return true; + } + return false; + } + + public String getStyleId() { + return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); + } + + public void setStyleId(String styleId) { + String oldValue = getStyleId(); + WorkbookImpl workbook = getRealizedWorkbook(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + String newValue = getStyleId(); + fireValueChange(Core.Style, oldValue, newValue); + updateModificationInfo(); + } + + public IControlPoint getControlPoint(int index) { + if (controlPoints == null) + controlPoints = new HashMap(); + ControlPointImpl controlPoint = controlPoints + .get(Integer.valueOf(index)); + if (controlPoint == null) { + controlPoint = new ControlPointImpl(this, index); + controlPoints.put(Integer.valueOf(index), controlPoint); + } + return controlPoint; +// Element cp = getControlPointElement(index); +// if (cp != null) { +// return new ControlPointImpl(cp); +// } +// return null; + } + +// private Element getControlPointElement(int index) { +// Element cps = getFirstChildElementByTag(implementation, +// TAG_CONTROL_POINTS); +// return cps == null ? null : getControlPointElement(index, cps); +// } +// +// private Element getControlPointElement(int index, Element cps) { +// Iterator it = childElementIterByTag(cps, TAG_CONTROL_POINT); +// while (it.hasNext()) { +// Element cp = it.next(); +// String i = cp.getAttribute(ATTR_INDEX); +// if (i != null && NumberUtils.safeParseInt(i, -1) == index) +// return cp; +// } +// return null; +// } +// +// public void setControlPoint(int index, double angle, double amount) { +// Element cps = ensureChildElement(implementation, TAG_CONTROL_POINTS); +// Element cp = getControlPointElement(index, cps); +// if (cp == null) { +// cp = createElement(cps, TAG_CONTROL_POINT); +// cp.setAttribute(ATTR_INDEX, Integer.toString(index)); +// } +// cp.setAttribute(ATTR_ANGLE, Double.toString(angle)); +// cp.setAttribute(ATTR_AMOUNT, Double.toString(amount)); +// fireIndexedTargetChange(Core.RelationshipControlPoint, +// getControlPoint(index), index); +// } +// +// public void resetControlPoint(int index) { +// Element cps = getFirstChildElementByTag(implementation, +// TAG_CONTROL_POINTS); +// if (cps == null) +// return; +// Element cp = getControlPointElement(index, cps); +// if (cp == null) +// return; +// cp.removeAttribute(ATTR_ANGLE); +// cp.removeAttribute(ATTR_AMOUNT); +// if (!cp.hasChildNodes()) { +// cps.removeChild(cp); +// } +// fireIndexedTargetChange(Core.RelationshipControlPoint, +// getControlPoint(index), index); +// } + + protected WorkbookImpl getRealizedWorkbook() { + ISheet sheet = getParent(); + if (sheet != null) { + if (ownedWorkbook == sheet.getParent()) + return ownedWorkbook; + } + return null; + } + + protected void addNotify(WorkbookImpl workbook, SheetImpl parent) { + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); + workbook.getAdaptableRegistry().registerById(this, getId(), + getImplementation().getOwnerDocument()); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + } + + protected void removeNotify(WorkbookImpl workbook, SheetImpl parent) { + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + workbook.getAdaptableRegistry().unregisterById(this, getId(), + getImplementation().getOwnerDocument()); + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public ICoreEventSupport getCoreEventSupport() { + // Use workbook's core event support directly, so that + // orphan components can have events broadcasted, which + // will enable transient actions (such as dragging topics + // or adjusting relationship control points, etc.) to + // perform correctly. + return ownedWorkbook.getCoreEventSupport(); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, type, oldValue, + newValue); + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, implementation); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, implementation); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + + ISheet sheet = getParent(); + if (sheet != null) { + ((SheetImpl) sheet).updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionImpl.java index af2e9738e..8d0420c4b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionImpl.java @@ -1,196 +1,196 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_REVISION_NUMBER; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIMESTAMP; - -import java.io.InputStream; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.IAdaptable; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.IRevisionManager; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.Revision; -import org.xmind.core.util.DOMUtils; - -/** - * @author Frank Shaka - */ -public class RevisionImpl extends Revision { - - private Element implementation; - - private RevisionManagerImpl parent; - - private IAdaptable content = null; - - public RevisionImpl(Element implementation, RevisionManagerImpl parent) { - this.implementation = implementation; - this.parent = parent; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof RevisionImpl)) - return false; - RevisionImpl that = (RevisionImpl) obj; - return implementation.equals(that.implementation); - } - - @Override - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getImplementation()); - return super.getAdapter(adapter); - } - - public Element getImplementation() { - return implementation; - } - - public IRevisionManager getOwnedManager() { - return parent; - } - - public String getContentType() { - return parent.getContentType(); - } - - public String getResourceId() { - return parent.getResourceId(); - } - - public int getRevisionNumber() { - String num = getImplementation().getAttribute(ATTR_REVISION_NUMBER); - return NumberUtils.safeParseInt(num, 0); - } - - public long getTimestamp() { - String num = getImplementation().getAttribute(ATTR_TIMESTAMP); - return NumberUtils.safeParseLong(num, 0); - } - - public IAdaptable getContent() { - if (content == null) { - content = loadContent(); - } - return content; - } - - public String getResourcePath() { - return getImplementation().getAttribute(ATTR_RESOURCE); - } - - private IAdaptable loadContent() { - String path = getResourcePath(); - Document doc = loadDocument(path); - if (doc != null) { - Element docEle = doc.getDocumentElement(); - if (docEle != null) { - Node ele = docEle.getFirstChild(); - if (ele != null) { - return parent.getAdaptableFactory().createAdaptable(ele); - } - } - } - return null; - } - - private Document loadDocument(String path) { - IFileEntry entry = getOwnedWorkbook().getManifest().getFileEntry(path); - if (entry != null) { - try { - InputStream stream = entry.openInputStream(); - try { - return DOMUtils.loadDocument(stream); - } finally { - stream.close(); - } - } catch (Throwable e) { - Core.getLogger().log(e, "Failed to load content from " + path); //$NON-NLS-1$ - } - } - return null; - } - - public IWorkbook getOwnedWorkbook() { - return parent.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(getImplementation()); - } - - protected void addNotify(WorkbookImpl workbook) { - increaseFileEntryReference(); - if (SHEET.equals(getContentType()) - && getContent() instanceof SheetImpl) { - ((SheetImpl) getContent()).addNotify(workbook); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - if (SHEET.equals(getContentType()) - && getContent() instanceof SheetImpl) { - ((SheetImpl) getContent()).removeNotify(workbook); - } - decreaseFileEntryReference(); - } - - /** - * - */ - private void increaseFileEntryReference() { - String path = getResourcePath(); - if (path == null || "".equals(path)) //$NON-NLS-1$ - return; - - IManifest manifest = parent.getOwnedWorkbook().getManifest(); - IFileEntry entry = manifest.getFileEntry(path); - if (entry != null) { - entry.increaseReference(); - } - } - - /** - * - */ - private void decreaseFileEntryReference() { - String path = getResourcePath(); - if (path == null || "".equals(path)) //$NON-NLS-1$ - return; - - IManifest manifest = parent.getOwnedWorkbook().getManifest(); - IFileEntry entry = manifest.getFileEntry(path); - if (entry != null) { - entry.decreaseReference(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_REVISION_NUMBER; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIMESTAMP; + +import java.io.InputStream; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.IRevisionManager; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.Revision; +import org.xmind.core.util.DOMUtils; + +/** + * @author Frank Shaka + */ +public class RevisionImpl extends Revision { + + private Element implementation; + + private RevisionManagerImpl parent; + + private IAdaptable content = null; + + public RevisionImpl(Element implementation, RevisionManagerImpl parent) { + this.implementation = implementation; + this.parent = parent; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof RevisionImpl)) + return false; + RevisionImpl that = (RevisionImpl) obj; + return implementation.equals(that.implementation); + } + + @Override + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); + return super.getAdapter(adapter); + } + + public Element getImplementation() { + return implementation; + } + + public IRevisionManager getOwnedManager() { + return parent; + } + + public String getContentType() { + return parent.getContentType(); + } + + public String getResourceId() { + return parent.getResourceId(); + } + + public int getRevisionNumber() { + String num = getImplementation().getAttribute(ATTR_REVISION_NUMBER); + return NumberUtils.safeParseInt(num, 0); + } + + public long getTimestamp() { + String num = getImplementation().getAttribute(ATTR_TIMESTAMP); + return NumberUtils.safeParseLong(num, 0); + } + + public IAdaptable getContent() { + if (content == null) { + content = loadContent(); + } + return content; + } + + public String getResourcePath() { + return getImplementation().getAttribute(ATTR_RESOURCE); + } + + private IAdaptable loadContent() { + String path = getResourcePath(); + Document doc = loadDocument(path); + if (doc != null) { + Element docEle = doc.getDocumentElement(); + if (docEle != null) { + Node ele = docEle.getFirstChild(); + if (ele != null) { + return parent.getAdaptableFactory().createAdaptable(ele); + } + } + } + return null; + } + + private Document loadDocument(String path) { + IFileEntry entry = getOwnedWorkbook().getManifest().getFileEntry(path); + if (entry != null) { + try { + InputStream stream = entry.openInputStream(); + try { + return DOMUtils.loadDocument(stream); + } finally { + stream.close(); + } + } catch (Throwable e) { + Core.getLogger().log(e, "Failed to load content from " + path); //$NON-NLS-1$ + } + } + return null; + } + + public IWorkbook getOwnedWorkbook() { + return parent.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(getImplementation()); + } + + protected void addNotify(WorkbookImpl workbook) { + increaseFileEntryReference(); + if (SHEET.equals(getContentType()) + && getContent() instanceof SheetImpl) { + ((SheetImpl) getContent()).addNotify(workbook); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + if (SHEET.equals(getContentType()) + && getContent() instanceof SheetImpl) { + ((SheetImpl) getContent()).removeNotify(workbook); + } + decreaseFileEntryReference(); + } + + /** + * + */ + private void increaseFileEntryReference() { + String path = getResourcePath(); + if (path == null || "".equals(path)) //$NON-NLS-1$ + return; + + IManifest manifest = parent.getOwnedWorkbook().getManifest(); + IFileEntry entry = manifest.getFileEntry(path); + if (entry != null) { + entry.increaseReference(); + } + } + + /** + * + */ + private void decreaseFileEntryReference() { + String path = getResourcePath(); + if (path == null || "".equals(path)) //$NON-NLS-1$ + return; + + IManifest manifest = parent.getOwnedWorkbook().getManifest(); + IFileEntry entry = manifest.getFileEntry(path); + if (entry != null) { + entry.decreaseReference(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionManagerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionManagerImpl.java index 18d699939..7f19fb706 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionManagerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/RevisionManagerImpl.java @@ -1,338 +1,338 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_CREATOR_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_CREATOR_VERSION; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NEXT_REVISION_NUMBER; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_REVISION_NUMBER; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIMESTAMP; -import static org.xmind.core.internal.dom.DOMConstants.TAG_REVISION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_REVISION_CONTENT; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IFileEntry; -import org.xmind.core.IMeta; -import org.xmind.core.IRevision; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.RevisionManager; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.util.DOMUtils; - -/** - * @author Frank Shaka - */ -public class RevisionManagerImpl extends RevisionManager - implements ICoreEventSource, INodeAdaptableFactory { - - private Document implementation; - - private WorkbookImpl ownedWorkbook; - - private NodeAdaptableRegistry registry; - - private ICoreEventSupport coreEventSupport; - - private String dirPath; - - private boolean registered = false; - - /** - * - */ - public RevisionManagerImpl(Document implementation, - WorkbookImpl ownedWorkbook, String dirPath) { - this.implementation = implementation; - this.ownedWorkbook = ownedWorkbook; - this.dirPath = dirPath; - this.registry = new NodeAdaptableRegistry(implementation, this); - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof RevisionManagerImpl)) - return false; - RevisionManagerImpl that = (RevisionManagerImpl) obj; - return implementation.equals(that.implementation); - } - - @Override - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(getImplementation()); - return super.getAdapter(adapter); - } - - public Document getImplementation() { - return implementation; - } - - protected Element getRevisionsElement() { - return implementation.getDocumentElement(); - } - - protected INodeAdaptableFactory getAdaptableFactory() { - return ownedWorkbook; - } - - public IAdaptable createAdaptable(Node node) { - return new RevisionImpl((Element) node, this); - } - - protected String getDirPath() { - return dirPath; - } - - public String getResourceId() { - return getRevisionsElement().getAttribute(ATTR_RESOURCE_ID); - } - - public String getContentType() { - return getRevisionsElement().getAttribute(ATTR_MEDIA_TYPE); - } - - public Iterator iterRevisions() { - return new DOMUtils.AdaptableIterator(getRevisionsElement(), - TAG_REVISION, registry, false); - } - - public Iterator iterRevisionsReversed() { - return new DOMUtils.AdaptableIterator(getRevisionsElement(), - TAG_REVISION, registry, true); - } - - public IRevision getLatestRevision() { - Node node = getLastRevisionNode(); - return node == null ? null : (IRevision) registry.getAdaptable(node); - } - - protected Node getLastRevisionNode() { - Node node = getRevisionsElement().getLastChild(); - while (node != null && !DOMUtils.isElementByTag(node, TAG_REVISION)) { - node = node.getPreviousSibling(); - } - return node; - } - - public int getNextRevisionNumber() { - String num = getRevisionsElement() - .getAttribute(ATTR_NEXT_REVISION_NUMBER); - return NumberUtils.safeParseInt(num, 1); - } - - public IRevision addRevision(IAdaptable content) - throws IOException, CoreException { - Node node = (Node) content.getAdapter(Node.class); - if (node == null) - throw new CoreException(Core.ERROR_INVALID_ARGUMENT, - "Invalid content for content type: " + getContentType()); //$NON-NLS-1$ - - IRevision latest = getLatestRevision(); - if (latest != null) { - IAdaptable latestContent = latest.getContent(); - if (latestContent != null) { - Object latestNode = latestContent.getAdapter(Node.class); - if (latestNode != null && latestNode.equals(node)) - return null; - } - } - - int revNum = getNextRevisionNumber(); - long timestamp = System.currentTimeMillis(); - String path = takeSnapshot(node, revNum, timestamp); - RevisionImpl revision = createRevision(revNum, timestamp, path); - setNextRevisionNumber(revNum + 1); - if (!isOrphan()) { - revision.addNotify(ownedWorkbook); - fireTargetEvent(Core.RevisionAdd, revision); - } - return revision; - } - - private void setNextRevisionNumber(int nextRevNum) { - getRevisionsElement().setAttribute(ATTR_NEXT_REVISION_NUMBER, - String.valueOf(nextRevNum)); - } - - private RevisionImpl createRevision(int revNum, long timestamp, - String path) { - Element ele = implementation.createElement(TAG_REVISION); - ele.setAttribute(ATTR_REVISION_NUMBER, String.valueOf(revNum)); - ele.setAttribute(ATTR_TIMESTAMP, String.valueOf(timestamp)); - ele.setAttribute(ATTR_RESOURCE, path); - - ele.setAttribute(ATTR_CREATOR_NAME, - getOwnedWorkbook().getMeta().getValue(IMeta.CREATOR_NAME)); - ele.setAttribute(ATTR_CREATOR_VERSION, - getOwnedWorkbook().getMeta().getValue(IMeta.CREATOR_VERSION)); - getRevisionsElement().appendChild(ele); - return new RevisionImpl(ele, this); - } - - private String takeSnapshot(Node source, int revNum, long timestamp) - throws IOException, CoreException { - Document doc = DOMUtils.createDocument(TAG_REVISION_CONTENT); - Element docEle = doc.getDocumentElement(); - NS.setNS(NS.Revision, docEle, NS.Xhtml, NS.Xlink, NS.SVG, NS.Fo); - Node snapshot = doc.importNode(source, true); - docEle.appendChild(snapshot); - - String path = getDirPath() + getFileName(revNum, timestamp, "xml"); //$NON-NLS-1$ - IFileEntry entry = ownedWorkbook.getManifest().createFileEntry(path); - OutputStream stream = entry.openOutputStream(); - DOMUtils.save(doc, stream, true); - return path; - } - - private String getFileName(int revNum, long timestamp, String extName) { - return String.format("rev-%s-%s.%s", revNum, timestamp, extName); //$NON-NLS-1$ - } - - public Object removeRevision(IRevision revision) { - RevisionImpl rev = (RevisionImpl) revision; - Element ele = rev.getImplementation(); - Element parentEle = getRevisionsElement(); - int index = DOMUtils.getNodeIndex(parentEle, ele); - if (index < 0) - return null; - if (!isOrphan()) - rev.removeNotify(ownedWorkbook); - parentEle.removeChild(ele); - if (!isOrphan()) - fireTargetEvent(Core.RevisionRemove, revision); - return Integer.valueOf(index); - } - - public void restoreRevision(IRevision revision, Object removal) { - if (!(removal instanceof Integer)) - throw new IllegalArgumentException("Invalid removal object"); //$NON-NLS-1$ - int index = ((Integer) removal).intValue(); - RevisionImpl rev = (RevisionImpl) revision; - Element ele = rev.getImplementation(); - Element parentEle = getRevisionsElement(); - NodeList childNodes = parentEle.getChildNodes(); - if (index < childNodes.getLength()) { - parentEle.insertBefore(ele, childNodes.item(index)); - } else { - parentEle.appendChild(ele); - } - if (!isOrphan()) { - ((RevisionImpl) revision).addNotify(ownedWorkbook); - fireTargetEvent(Core.RevisionAdd, revision); - } - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public boolean isOrphan() { - return !registered; - } - - protected void addNotify(WorkbookImpl workbook) { - registered = true; - increaseFileEntryReference(); - Iterator it = iterRevisions(); - while (it.hasNext()) { - RevisionImpl rev = (RevisionImpl) it.next(); - rev.addNotify(workbook); - fireTargetEvent(Core.RevisionAdd, rev); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - Iterator it = iterRevisionsReversed(); - while (it.hasNext()) { - RevisionImpl rev = (RevisionImpl) it.next(); - rev.removeNotify(workbook); - fireTargetEvent(Core.RevisionRemove, rev); - } - decreaseFileEntryReference(); - registered = false; - } - - private void increaseFileEntryReference() { - IFileEntry entry = getMetaFileEntry(); - if (entry != null) { - entry.increaseReference(); - } - } - - private void decreaseFileEntryReference() { - IFileEntry entry = getMetaFileEntry(); - if (entry != null) { - entry.decreaseReference(); - } - } - - private IFileEntry getMetaFileEntry() { - String path = dirPath + ArchiveConstants.REVISIONS_XML; - return ownedWorkbook.getManifest().getFileEntry(path); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() - */ - public ICoreEventSupport getCoreEventSupport() { - if (coreEventSupport == null) { - coreEventSupport = ownedWorkbook.getCoreEventSupport(); - } - return coreEventSupport; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. - * lang.String, org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerGlobalListener(type, listener); - } - - private void fireTargetEvent(String eventType, IRevision revision) { - getCoreEventSupport().dispatchTargetChange(this, eventType, revision); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_CREATOR_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_CREATOR_VERSION; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_MEDIA_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NEXT_REVISION_NUMBER; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_REVISION_NUMBER; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TIMESTAMP; +import static org.xmind.core.internal.dom.DOMConstants.TAG_REVISION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_REVISION_CONTENT; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IFileEntry; +import org.xmind.core.IMeta; +import org.xmind.core.IRevision; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.RevisionManager; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.util.DOMUtils; + +/** + * @author Frank Shaka + */ +public class RevisionManagerImpl extends RevisionManager + implements ICoreEventSource, INodeAdaptableFactory { + + private Document implementation; + + private WorkbookImpl ownedWorkbook; + + private NodeAdaptableRegistry registry; + + private ICoreEventSupport coreEventSupport; + + private String dirPath; + + private boolean registered = false; + + /** + * + */ + public RevisionManagerImpl(Document implementation, + WorkbookImpl ownedWorkbook, String dirPath) { + this.implementation = implementation; + this.ownedWorkbook = ownedWorkbook; + this.dirPath = dirPath; + this.registry = new NodeAdaptableRegistry(implementation, this); + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof RevisionManagerImpl)) + return false; + RevisionManagerImpl that = (RevisionManagerImpl) obj; + return implementation.equals(that.implementation); + } + + @Override + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(getImplementation()); + return super.getAdapter(adapter); + } + + public Document getImplementation() { + return implementation; + } + + protected Element getRevisionsElement() { + return implementation.getDocumentElement(); + } + + protected INodeAdaptableFactory getAdaptableFactory() { + return ownedWorkbook; + } + + public IAdaptable createAdaptable(Node node) { + return new RevisionImpl((Element) node, this); + } + + protected String getDirPath() { + return dirPath; + } + + public String getResourceId() { + return getRevisionsElement().getAttribute(ATTR_RESOURCE_ID); + } + + public String getContentType() { + return getRevisionsElement().getAttribute(ATTR_MEDIA_TYPE); + } + + public Iterator iterRevisions() { + return new DOMUtils.AdaptableIterator(getRevisionsElement(), + TAG_REVISION, registry, false); + } + + public Iterator iterRevisionsReversed() { + return new DOMUtils.AdaptableIterator(getRevisionsElement(), + TAG_REVISION, registry, true); + } + + public IRevision getLatestRevision() { + Node node = getLastRevisionNode(); + return node == null ? null : (IRevision) registry.getAdaptable(node); + } + + protected Node getLastRevisionNode() { + Node node = getRevisionsElement().getLastChild(); + while (node != null && !DOMUtils.isElementByTag(node, TAG_REVISION)) { + node = node.getPreviousSibling(); + } + return node; + } + + public int getNextRevisionNumber() { + String num = getRevisionsElement() + .getAttribute(ATTR_NEXT_REVISION_NUMBER); + return NumberUtils.safeParseInt(num, 1); + } + + public IRevision addRevision(IAdaptable content) + throws IOException, CoreException { + Node node = (Node) content.getAdapter(Node.class); + if (node == null) + throw new CoreException(Core.ERROR_INVALID_ARGUMENT, + "Invalid content for content type: " + getContentType()); //$NON-NLS-1$ + + IRevision latest = getLatestRevision(); + if (latest != null) { + IAdaptable latestContent = latest.getContent(); + if (latestContent != null) { + Object latestNode = latestContent.getAdapter(Node.class); + if (latestNode != null && latestNode.equals(node)) + return null; + } + } + + int revNum = getNextRevisionNumber(); + long timestamp = System.currentTimeMillis(); + String path = takeSnapshot(node, revNum, timestamp); + RevisionImpl revision = createRevision(revNum, timestamp, path); + setNextRevisionNumber(revNum + 1); + if (!isOrphan()) { + revision.addNotify(ownedWorkbook); + fireTargetEvent(Core.RevisionAdd, revision); + } + return revision; + } + + private void setNextRevisionNumber(int nextRevNum) { + getRevisionsElement().setAttribute(ATTR_NEXT_REVISION_NUMBER, + String.valueOf(nextRevNum)); + } + + private RevisionImpl createRevision(int revNum, long timestamp, + String path) { + Element ele = implementation.createElement(TAG_REVISION); + ele.setAttribute(ATTR_REVISION_NUMBER, String.valueOf(revNum)); + ele.setAttribute(ATTR_TIMESTAMP, String.valueOf(timestamp)); + ele.setAttribute(ATTR_RESOURCE, path); + + ele.setAttribute(ATTR_CREATOR_NAME, + getOwnedWorkbook().getMeta().getValue(IMeta.CREATOR_NAME)); + ele.setAttribute(ATTR_CREATOR_VERSION, + getOwnedWorkbook().getMeta().getValue(IMeta.CREATOR_VERSION)); + getRevisionsElement().appendChild(ele); + return new RevisionImpl(ele, this); + } + + private String takeSnapshot(Node source, int revNum, long timestamp) + throws IOException, CoreException { + Document doc = DOMUtils.createDocument(TAG_REVISION_CONTENT); + Element docEle = doc.getDocumentElement(); + NS.setNS(NS.Revision, docEle, NS.Xhtml, NS.Xlink, NS.SVG, NS.Fo); + Node snapshot = doc.importNode(source, true); + docEle.appendChild(snapshot); + + String path = getDirPath() + getFileName(revNum, timestamp, "xml"); //$NON-NLS-1$ + IFileEntry entry = ownedWorkbook.getManifest().createFileEntry(path); + OutputStream stream = entry.openOutputStream(); + DOMUtils.save(doc, stream, true); + return path; + } + + private String getFileName(int revNum, long timestamp, String extName) { + return String.format("rev-%s-%s.%s", revNum, timestamp, extName); //$NON-NLS-1$ + } + + public Object removeRevision(IRevision revision) { + RevisionImpl rev = (RevisionImpl) revision; + Element ele = rev.getImplementation(); + Element parentEle = getRevisionsElement(); + int index = DOMUtils.getNodeIndex(parentEle, ele); + if (index < 0) + return null; + if (!isOrphan()) + rev.removeNotify(ownedWorkbook); + parentEle.removeChild(ele); + if (!isOrphan()) + fireTargetEvent(Core.RevisionRemove, revision); + return Integer.valueOf(index); + } + + public void restoreRevision(IRevision revision, Object removal) { + if (!(removal instanceof Integer)) + throw new IllegalArgumentException("Invalid removal object"); //$NON-NLS-1$ + int index = ((Integer) removal).intValue(); + RevisionImpl rev = (RevisionImpl) revision; + Element ele = rev.getImplementation(); + Element parentEle = getRevisionsElement(); + NodeList childNodes = parentEle.getChildNodes(); + if (index < childNodes.getLength()) { + parentEle.insertBefore(ele, childNodes.item(index)); + } else { + parentEle.appendChild(ele); + } + if (!isOrphan()) { + ((RevisionImpl) revision).addNotify(ownedWorkbook); + fireTargetEvent(Core.RevisionAdd, revision); + } + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public boolean isOrphan() { + return !registered; + } + + protected void addNotify(WorkbookImpl workbook) { + registered = true; + increaseFileEntryReference(); + Iterator it = iterRevisions(); + while (it.hasNext()) { + RevisionImpl rev = (RevisionImpl) it.next(); + rev.addNotify(workbook); + fireTargetEvent(Core.RevisionAdd, rev); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + Iterator it = iterRevisionsReversed(); + while (it.hasNext()) { + RevisionImpl rev = (RevisionImpl) it.next(); + rev.removeNotify(workbook); + fireTargetEvent(Core.RevisionRemove, rev); + } + decreaseFileEntryReference(); + registered = false; + } + + private void increaseFileEntryReference() { + IFileEntry entry = getMetaFileEntry(); + if (entry != null) { + entry.increaseReference(); + } + } + + private void decreaseFileEntryReference() { + IFileEntry entry = getMetaFileEntry(); + if (entry != null) { + entry.decreaseReference(); + } + } + + private IFileEntry getMetaFileEntry() { + String path = dirPath + ArchiveConstants.REVISIONS_XML; + return ownedWorkbook.getManifest().getFileEntry(path); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() + */ + public ICoreEventSupport getCoreEventSupport() { + if (coreEventSupport == null) { + coreEventSupport = ownedWorkbook.getCoreEventSupport(); + } + return coreEventSupport; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. + * lang.String, org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerGlobalListener(type, listener); + } + + private void fireTargetEvent(String eventType, IRevision revision) { + getCoreEventSupport().dispatchTargetChange(this, eventType, revision); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SerializerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SerializerImpl.java index 376baabc0..346fb339c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SerializerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SerializerImpl.java @@ -1,583 +1,583 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.zip.ArchiveConstants.COMMENTS_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_REVISIONS; -import static org.xmind.core.internal.zip.ArchiveConstants.REVISIONS_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.zip.ZipOutputStream; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.ICommentManager; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IMeta; -import org.xmind.core.IRevisionManager; -import org.xmind.core.IRevisionRepository; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtension; -import org.xmind.core.IWorkbookExtensionManager; -import org.xmind.core.internal.AbstractSerializingBase; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.internal.zip.ZipStreamOutputTarget; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.IProgressReporter; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class SerializerImpl extends AbstractSerializingBase - implements ISerializer { - - private IWorkbook workbook; - private IOutputTarget outputTarget; - - private final Set encryptionIgnoredEntries; - private String[] preferredEncryptionIgnoredEntries; - - private ZipOutputStream intermediateOutputStream; - - private boolean compressed; - - private boolean usesWorkbookStorageAsOutputTarget; - - private ManifestImpl manifest; - - private ManifestImpl tempManifest; - - private final Set serializedEntryPaths; - - public SerializerImpl() { - super(); - this.workbook = null; - this.outputTarget = null; - this.encryptionIgnoredEntries = new HashSet(); - this.preferredEncryptionIgnoredEntries = null; - this.intermediateOutputStream = null; - this.compressed = false; - this.usesWorkbookStorageAsOutputTarget = false; - this.manifest = null; - this.tempManifest = null; - this.serializedEntryPaths = new HashSet(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#getWorkbook() - */ - public IWorkbook getWorkbook() { - return workbook; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#setWorkbook(org.xmind.core.IWorkbook) - */ - public void setWorkbook(IWorkbook workbook) { - if (workbook == null) - throw new IllegalArgumentException("Workbook is null"); //$NON-NLS-1$ - if (!(workbook instanceof WorkbookImpl)) - throw new IllegalArgumentException("Can't serialize this workbook"); //$NON-NLS-1$ - IStorage storage = null; - if (usesWorkbookStorageAsOutputTarget) { - storage = workbook.getAdapter(IStorage.class); - if (storage == null) - throw new IllegalArgumentException( - "No workbook storage available"); //$NON-NLS-1$ - } - this.workbook = workbook; - if (storage != null) { - doSetOutputTarget(storage.getOutputTarget()); - } - } - - protected IOutputTarget getOutputTarget() { - return this.outputTarget; - } - - protected void doSetOutputTarget(IOutputTarget target) { - this.outputTarget = target; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#hasOutputTarget() - */ - public boolean hasOutputTarget() { - return outputTarget != null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#setOutputTarget(org.xmind.core.io. - * IOutputTarget) - */ - public void setOutputTarget(IOutputTarget target) { - if (target == null) - throw new IllegalArgumentException("output target is null"); //$NON-NLS-1$ - doSetOutputTarget(target); - this.intermediateOutputStream = null; - this.usesWorkbookStorageAsOutputTarget = false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#setOutputStream(java.io.OutputStream) - */ - public void setOutputStream(OutputStream stream) { - if (stream == null) - throw new IllegalArgumentException("stream is null"); //$NON-NLS-1$ - this.intermediateOutputStream = new ZipOutputStream(stream); - doSetOutputTarget(new ZipStreamOutputTarget(intermediateOutputStream, - compressed)); - this.usesWorkbookStorageAsOutputTarget = false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#setWorkbookStorageAsOutputTarget() - */ - public void setWorkbookStorageAsOutputTarget() { - if (getWorkbook() != null) { - IStorage storage = getWorkbook().getAdapter(IStorage.class); - if (storage == null) - throw new IllegalArgumentException( - "no workbook storage available"); //$NON-NLS-1$ - doSetOutputTarget(storage.getOutputTarget()); - } else { - /// sets a fake output target that will be substituted when - /// workbook is set - doSetOutputTarget(new ByteArrayStorage().getOutputTarget()); - } - this.usesWorkbookStorageAsOutputTarget = true; - this.intermediateOutputStream = null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#getEncryptionIgnoredEntries() - */ - public String[] getEncryptionIgnoredEntries() { - return preferredEncryptionIgnoredEntries; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.ISerializer#setEncryptionIgnoredEntries(java.lang.String[] - * ) - */ - public void setEncryptionIgnoredEntries(String[] entryPaths) { - this.preferredEncryptionIgnoredEntries = entryPaths; - encryptionIgnoredEntries.clear(); - collectDefaultEncryptionIgnoredEntries(encryptionIgnoredEntries); - if (entryPaths != null) { - encryptionIgnoredEntries.addAll(Arrays.asList(entryPaths)); - } - } - - protected boolean isEntryEncryptionIgnored(String entryPath) { - return encryptionIgnoredEntries.contains(entryPath); - } - - protected void collectDefaultEncryptionIgnoredEntries( - Set entryPaths) { - entryPaths.add(ArchiveConstants.MANIFEST_XML); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISerializer#serialize(org.xmind.core.util. - * IProgressReporter) - */ - public void serialize(IProgressReporter reporter) - throws IOException, CoreException, IllegalStateException { - WorkbookImpl workbook = (WorkbookImpl) getWorkbook(); - if (workbook == null) - throw new IllegalStateException("no workbook to serialize"); //$NON-NLS-1$ - - if (!hasOutputTarget()) - throw new IllegalStateException("no output target specified"); //$NON-NLS-1$ - - manifest = workbook.getManifest(); - - IEntryStreamNormalizer oldNormalizer = manifest.getStreamNormalizer(); - IEntryStreamNormalizer newNormalizer = getEntryStreamNormalizer(); - boolean normalizerChanged = newNormalizer != null - && !newNormalizer.equals(oldNormalizer); - - if (usesWorkbookStorageAsOutputTarget) { - tempManifest = manifest; - if (normalizerChanged) { - /// use new normalizer to save XML files - tempManifest.setStreamNormalizer(newNormalizer); - } - } else { - Document tempImplementation = cloneDocument( - manifest.getImplementation(), - ArchiveConstants.MANIFEST_XML); - tempManifest = new ManifestImpl(tempImplementation, - new WriteOnlyStorage(getOutputTarget())); - if (newNormalizer != null) { - tempManifest.setStreamNormalizer(newNormalizer); - } else { - tempManifest.setStreamNormalizer(oldNormalizer); - } - - /// Give this manifest a temp owner workbook to prevent null - /// pointer exception when file entry events are triggered. - new WorkbookImpl(DOMUtils.createDocument(), tempManifest); - } - - /// save meta.xml - IMeta meta = workbook.getMeta(); - String creatorName = getCreatorName(); - if (creatorName != null) - meta.setValue(IMeta.CREATOR_NAME, creatorName); - String creatorVersion = getCreatorVersion(); - if (creatorVersion != null) - meta.setValue(IMeta.CREATOR_VERSION, creatorVersion); - serializeXML(meta, META_XML); - - /// save content.xml - serializeXML(workbook, CONTENT_XML); - - /// NOTE: XML files should always serialized when saving to the - /// workbook's temp storage, otherwise recovered workbooks may contain - /// invalid data. - - /// save markers/markerSheet.xml - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (usesWorkbookStorageAsOutputTarget || !markerSheet.isEmpty()) { - serializeXML(markerSheet, PATH_MARKER_SHEET); - } else { - tempManifest.deleteFileEntry(PATH_MARKER_SHEET); - serializedEntryPaths.add(PATH_MARKER_SHEET); - } - - /// save styles.xml - IStyleSheet styleSheet = workbook.getStyleSheet(); - if (usesWorkbookStorageAsOutputTarget || !styleSheet.isEmpty()) { - serializeXML(styleSheet, STYLES_XML); - } else { - tempManifest.deleteFileEntry(STYLES_XML); - serializedEntryPaths.add(STYLES_XML); - } - - /// save comments.xml - ICommentManager commentManager = workbook.getCommentManager(); - if (usesWorkbookStorageAsOutputTarget || !commentManager.isEmpty()) { - serializeXML(commentManager, COMMENTS_XML); - } else { - tempManifest.deleteFileEntry(COMMENTS_XML); - serializedEntryPaths.add(COMMENTS_XML); - } - - /// save extensions - IWorkbookExtensionManager extensionManager = ((IWorkbook) workbook) - .getAdapter(IWorkbookExtensionManager.class); - List exts = extensionManager.getExtensions(); - for (IWorkbookExtension ext : exts) { - String providerName = ext.getProviderName(); - String path = PATH_EXTENSIONS + providerName + ".xml"; //$NON-NLS-1$ - serializeXML(ext, path); - } - - /// save revisions - IRevisionRepository revisionRepository = workbook - .getRevisionRepository(); - for (String resourceId : revisionRepository - .getRegisteredResourceIds()) { - IRevisionManager manager = revisionRepository - .getRegisteredRevisionManager(resourceId); - if (manager != null) { - String path = PATH_REVISIONS + resourceId + "/" //$NON-NLS-1$ - + REVISIONS_XML; - serializeXML(manager, path); - } - } - - /// copy remaining file entries, e.g. attachments, etc. - Iterator sourceEntryIter; - if (!usesWorkbookStorageAsOutputTarget) { - /// saving to external location, - /// write only referenced file entries - sourceEntryIter = manifest.iterFileEntries(); - } else if (normalizerChanged) { - /// saving to internal storage when encryption is changed, - /// re-encrypt all file entries - sourceEntryIter = manifest.getAllRegisteredEntries().iterator(); - } else { - /// saving to internal storage when encryption is not changed, - /// touch no file entries - sourceEntryIter = null; - } - - while (sourceEntryIter != null && sourceEntryIter.hasNext()) { - IFileEntry sourceEntry = sourceEntryIter.next(); - if (sourceEntry.isDirectory() || !sourceEntry.canRead()) - continue; - - String entryPath = sourceEntry.getPath(); - if (MANIFEST_XML.equals(entryPath) - || serializedEntryPaths.contains(entryPath)) - continue; - - IFileEntry targetEntry = tempManifest.getFileEntry(entryPath); - if (targetEntry == null) - // TODO missing entry, need log? - continue; - - if (usesWorkbookStorageAsOutputTarget) { - /// saving to internal storage, - /// write to a temporary entry first to protect original entry - String tempEntryPath = makeTempPath(entryPath); - - /// make sure we use the old normalizer to decrypt the file entry - manifest.setStreamNormalizer(oldNormalizer); - InputStream entryInput = sourceEntry.openInputStream(); - try { - OutputStream tempOutput = tempManifest.getStorage() - .getOutputTarget().openEntryStream(tempEntryPath); - try { - FileUtils.transfer(entryInput, tempOutput, false); - } finally { - tempOutput.close(); - } - } finally { - entryInput.close(); - } - - /// make sure we use the new normalizer to encrypt the file entry - tempManifest.setStreamNormalizer(newNormalizer); - InputStream tempInput = tempManifest.getStorage() - .getInputSource().openEntryStream(tempEntryPath); - try { - OutputStream entryOutput = openEntryOutputStream(entryPath); - try { - FileUtils.transfer(tempInput, entryOutput, false); - } finally { - entryOutput.close(); - } - } finally { - tempInput.close(); - } - - } else { - /// saving to external location, - /// just copy the entry directly - InputStream entryInput = sourceEntry.openInputStream(); - try { - OutputStream entryOutput = openEntryOutputStream(entryPath); - try { - FileUtils.transfer(entryInput, entryOutput, false); - } finally { - entryOutput.close(); - } - } finally { - entryInput.close(); - } - } - } - - if (usesWorkbookStorageAsOutputTarget && normalizerChanged) { - /// keep the new normalizer in the original manifest - /// to decrypt data in the internal storage afterwards - manifest.setStreamNormalizer(newNormalizer); - } - - /// save manifest.xml - serializeXML(tempManifest, MANIFEST_XML); - - /// only upon success should we close zip stream - if (intermediateOutputStream != null) { - intermediateOutputStream.finish(); - intermediateOutputStream.flush(); - intermediateOutputStream.close(); - } - - } - - private static Document cloneDocument(Document document, String xmlName) - throws CoreException { - try { - Transformer transformer = createXMLSerializer(); - DOMResult result = new DOMResult(); - transformer.transform(new DOMSource(document), result); - return (Document) result.getNode(); - } catch (TransformerException e) { - throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, xmlName, - e); - } - } - - private static Transformer createXMLSerializer() throws CoreException { - /// create a new transformer instance each time - return DOMUtils.getDefaultTransformer(); - } - - private String makeTempPath(String path) { - int sepIndex = path.lastIndexOf('/'); - if (sepIndex >= 0) { - return path.substring(0, sepIndex + 1) + "._." //$NON-NLS-1$ - + path.substring(sepIndex + 1); - } - // no separator - return "._." + path; //$NON-NLS-1$ - } - - private void serializeXML(IAdaptable domAdaptable, String entryPath) - throws IOException, CoreException { - Node node = (Node) domAdaptable.getAdapter(Node.class); - if (node == null) - throw new CoreException(Core.ERROR_INVALID_ARGUMENT, - "Object has no DOM node"); //$NON-NLS-1$ - - Transformer transformer = createXMLSerializer(); - OutputStream out = openEntryOutputStream(entryPath); - try { - transformer.transform(new DOMSource(node), new StreamResult(out)); - } catch (TransformerException e) { - if (e.getCause() != null && e.getCause() instanceof IOException) { - throw (IOException) e.getCause(); - } - throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, entryPath, - e); - } finally { - out.close(); - } - - serializedEntryPaths.add(entryPath); - } - - private OutputStream openEntryOutputStream(String entryPath) - throws IOException, CoreException { - IFileEntry entry = tempManifest.getFileEntry(entryPath); - - if (isEntryEncryptionIgnored(entryPath)) { - entry.deleteEncryptionData(); - return tempManifest.getStorage().getOutputTarget() - .openEntryStream(entryPath); - } - - if (entry == null) { - entry = tempManifest.createFileEntry(entryPath); - entry.increaseReference(); - } - return entry.openOutputStream(); - } - -// String calcChecksum(Object checksumProvider) { -// if (checksumProvider instanceof IChecksumStream) { -// return ((IChecksumStream) checksumProvider).getChecksum(); -// } -// return null; -// } - -// void recordChecksum(String entryPath, Object checksumProvider) { -// String checksum = calcChecksum(checksumProvider); -// if (checksum == null) -// return; -// -// IFileEntry entry = tempManifest.getFileEntry(entryPath); -// if (entry == null) -// return; -// -// IEncryptionData encData = entry.getEncryptionData(); -// if (encData == null || encData.getChecksumType() == null) -// return; -// -// encData.setAttribute(checksum, DOMConstants.ATTR_CHECKSUM); -// } - - private static class WriteOnlyStorage implements IStorage { - - private IOutputTarget target; - - public WriteOnlyStorage(IOutputTarget target) { - this.target = target; - } - - public IInputSource getInputSource() { - throw new UnsupportedOperationException(); - } - - public IOutputTarget getOutputTarget() { - return target; - } - - public String getName() { - return toString(); - } - - public String getFullPath() { - return getName(); - } - - public void clear() { - } - - public void deleteEntry(String entryName) { - } - - public void renameEntry(String entryName, String newName) { - } - - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.zip.ArchiveConstants.COMMENTS_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_REVISIONS; +import static org.xmind.core.internal.zip.ArchiveConstants.REVISIONS_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipOutputStream; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.ICommentManager; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IMeta; +import org.xmind.core.IRevisionManager; +import org.xmind.core.IRevisionRepository; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtension; +import org.xmind.core.IWorkbookExtensionManager; +import org.xmind.core.internal.AbstractSerializingBase; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.internal.zip.ZipStreamOutputTarget; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.IProgressReporter; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class SerializerImpl extends AbstractSerializingBase + implements ISerializer { + + private IWorkbook workbook; + private IOutputTarget outputTarget; + + private final Set encryptionIgnoredEntries; + private String[] preferredEncryptionIgnoredEntries; + + private ZipOutputStream intermediateOutputStream; + + private boolean compressed; + + private boolean usesWorkbookStorageAsOutputTarget; + + private ManifestImpl manifest; + + private ManifestImpl tempManifest; + + private final Set serializedEntryPaths; + + public SerializerImpl() { + super(); + this.workbook = null; + this.outputTarget = null; + this.encryptionIgnoredEntries = new HashSet(); + this.preferredEncryptionIgnoredEntries = null; + this.intermediateOutputStream = null; + this.compressed = false; + this.usesWorkbookStorageAsOutputTarget = false; + this.manifest = null; + this.tempManifest = null; + this.serializedEntryPaths = new HashSet(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#getWorkbook() + */ + public IWorkbook getWorkbook() { + return workbook; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#setWorkbook(org.xmind.core.IWorkbook) + */ + public void setWorkbook(IWorkbook workbook) { + if (workbook == null) + throw new IllegalArgumentException("Workbook is null"); //$NON-NLS-1$ + if (!(workbook instanceof WorkbookImpl)) + throw new IllegalArgumentException("Can't serialize this workbook"); //$NON-NLS-1$ + IStorage storage = null; + if (usesWorkbookStorageAsOutputTarget) { + storage = workbook.getAdapter(IStorage.class); + if (storage == null) + throw new IllegalArgumentException( + "No workbook storage available"); //$NON-NLS-1$ + } + this.workbook = workbook; + if (storage != null) { + doSetOutputTarget(storage.getOutputTarget()); + } + } + + protected IOutputTarget getOutputTarget() { + return this.outputTarget; + } + + protected void doSetOutputTarget(IOutputTarget target) { + this.outputTarget = target; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#hasOutputTarget() + */ + public boolean hasOutputTarget() { + return outputTarget != null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#setOutputTarget(org.xmind.core.io. + * IOutputTarget) + */ + public void setOutputTarget(IOutputTarget target) { + if (target == null) + throw new IllegalArgumentException("output target is null"); //$NON-NLS-1$ + doSetOutputTarget(target); + this.intermediateOutputStream = null; + this.usesWorkbookStorageAsOutputTarget = false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#setOutputStream(java.io.OutputStream) + */ + public void setOutputStream(OutputStream stream) { + if (stream == null) + throw new IllegalArgumentException("stream is null"); //$NON-NLS-1$ + this.intermediateOutputStream = new ZipOutputStream(stream); + doSetOutputTarget(new ZipStreamOutputTarget(intermediateOutputStream, + compressed)); + this.usesWorkbookStorageAsOutputTarget = false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#setWorkbookStorageAsOutputTarget() + */ + public void setWorkbookStorageAsOutputTarget() { + if (getWorkbook() != null) { + IStorage storage = getWorkbook().getAdapter(IStorage.class); + if (storage == null) + throw new IllegalArgumentException( + "no workbook storage available"); //$NON-NLS-1$ + doSetOutputTarget(storage.getOutputTarget()); + } else { + /// sets a fake output target that will be substituted when + /// workbook is set + doSetOutputTarget(new ByteArrayStorage().getOutputTarget()); + } + this.usesWorkbookStorageAsOutputTarget = true; + this.intermediateOutputStream = null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#getEncryptionIgnoredEntries() + */ + public String[] getEncryptionIgnoredEntries() { + return preferredEncryptionIgnoredEntries; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.ISerializer#setEncryptionIgnoredEntries(java.lang.String[] + * ) + */ + public void setEncryptionIgnoredEntries(String[] entryPaths) { + this.preferredEncryptionIgnoredEntries = entryPaths; + encryptionIgnoredEntries.clear(); + collectDefaultEncryptionIgnoredEntries(encryptionIgnoredEntries); + if (entryPaths != null) { + encryptionIgnoredEntries.addAll(Arrays.asList(entryPaths)); + } + } + + protected boolean isEntryEncryptionIgnored(String entryPath) { + return encryptionIgnoredEntries.contains(entryPath); + } + + protected void collectDefaultEncryptionIgnoredEntries( + Set entryPaths) { + entryPaths.add(ArchiveConstants.MANIFEST_XML); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISerializer#serialize(org.xmind.core.util. + * IProgressReporter) + */ + public void serialize(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException { + WorkbookImpl workbook = (WorkbookImpl) getWorkbook(); + if (workbook == null) + throw new IllegalStateException("no workbook to serialize"); //$NON-NLS-1$ + + if (!hasOutputTarget()) + throw new IllegalStateException("no output target specified"); //$NON-NLS-1$ + + manifest = workbook.getManifest(); + + IEntryStreamNormalizer oldNormalizer = manifest.getStreamNormalizer(); + IEntryStreamNormalizer newNormalizer = getEntryStreamNormalizer(); + boolean normalizerChanged = newNormalizer != null + && !newNormalizer.equals(oldNormalizer); + + if (usesWorkbookStorageAsOutputTarget) { + tempManifest = manifest; + if (normalizerChanged) { + /// use new normalizer to save XML files + tempManifest.setStreamNormalizer(newNormalizer); + } + } else { + Document tempImplementation = cloneDocument( + manifest.getImplementation(), + ArchiveConstants.MANIFEST_XML); + tempManifest = new ManifestImpl(tempImplementation, + new WriteOnlyStorage(getOutputTarget())); + if (newNormalizer != null) { + tempManifest.setStreamNormalizer(newNormalizer); + } else { + tempManifest.setStreamNormalizer(oldNormalizer); + } + + /// Give this manifest a temp owner workbook to prevent null + /// pointer exception when file entry events are triggered. + new WorkbookImpl(DOMUtils.createDocument(), tempManifest); + } + + /// save meta.xml + IMeta meta = workbook.getMeta(); + String creatorName = getCreatorName(); + if (creatorName != null) + meta.setValue(IMeta.CREATOR_NAME, creatorName); + String creatorVersion = getCreatorVersion(); + if (creatorVersion != null) + meta.setValue(IMeta.CREATOR_VERSION, creatorVersion); + serializeXML(meta, META_XML); + + /// save content.xml + serializeXML(workbook, CONTENT_XML); + + /// NOTE: XML files should always serialized when saving to the + /// workbook's temp storage, otherwise recovered workbooks may contain + /// invalid data. + + /// save markers/markerSheet.xml + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (usesWorkbookStorageAsOutputTarget || !markerSheet.isEmpty()) { + serializeXML(markerSheet, PATH_MARKER_SHEET); + } else { + tempManifest.deleteFileEntry(PATH_MARKER_SHEET); + serializedEntryPaths.add(PATH_MARKER_SHEET); + } + + /// save styles.xml + IStyleSheet styleSheet = workbook.getStyleSheet(); + if (usesWorkbookStorageAsOutputTarget || !styleSheet.isEmpty()) { + serializeXML(styleSheet, STYLES_XML); + } else { + tempManifest.deleteFileEntry(STYLES_XML); + serializedEntryPaths.add(STYLES_XML); + } + + /// save comments.xml + ICommentManager commentManager = workbook.getCommentManager(); + if (usesWorkbookStorageAsOutputTarget || !commentManager.isEmpty()) { + serializeXML(commentManager, COMMENTS_XML); + } else { + tempManifest.deleteFileEntry(COMMENTS_XML); + serializedEntryPaths.add(COMMENTS_XML); + } + + /// save extensions + IWorkbookExtensionManager extensionManager = ((IWorkbook) workbook) + .getAdapter(IWorkbookExtensionManager.class); + List exts = extensionManager.getExtensions(); + for (IWorkbookExtension ext : exts) { + String providerName = ext.getProviderName(); + String path = PATH_EXTENSIONS + providerName + ".xml"; //$NON-NLS-1$ + serializeXML(ext, path); + } + + /// save revisions + IRevisionRepository revisionRepository = workbook + .getRevisionRepository(); + for (String resourceId : revisionRepository + .getRegisteredResourceIds()) { + IRevisionManager manager = revisionRepository + .getRegisteredRevisionManager(resourceId); + if (manager != null) { + String path = PATH_REVISIONS + resourceId + "/" //$NON-NLS-1$ + + REVISIONS_XML; + serializeXML(manager, path); + } + } + + /// copy remaining file entries, e.g. attachments, etc. + Iterator sourceEntryIter; + if (!usesWorkbookStorageAsOutputTarget) { + /// saving to external location, + /// write only referenced file entries + sourceEntryIter = manifest.iterFileEntries(); + } else if (normalizerChanged) { + /// saving to internal storage when encryption is changed, + /// re-encrypt all file entries + sourceEntryIter = manifest.getAllRegisteredEntries().iterator(); + } else { + /// saving to internal storage when encryption is not changed, + /// touch no file entries + sourceEntryIter = null; + } + + while (sourceEntryIter != null && sourceEntryIter.hasNext()) { + IFileEntry sourceEntry = sourceEntryIter.next(); + if (sourceEntry.isDirectory() || !sourceEntry.canRead()) + continue; + + String entryPath = sourceEntry.getPath(); + if (MANIFEST_XML.equals(entryPath) + || serializedEntryPaths.contains(entryPath)) + continue; + + IFileEntry targetEntry = tempManifest.getFileEntry(entryPath); + if (targetEntry == null) + // TODO missing entry, need log? + continue; + + if (usesWorkbookStorageAsOutputTarget) { + /// saving to internal storage, + /// write to a temporary entry first to protect original entry + String tempEntryPath = makeTempPath(entryPath); + + /// make sure we use the old normalizer to decrypt the file entry + manifest.setStreamNormalizer(oldNormalizer); + InputStream entryInput = sourceEntry.openInputStream(); + try { + OutputStream tempOutput = tempManifest.getStorage() + .getOutputTarget().openEntryStream(tempEntryPath); + try { + FileUtils.transfer(entryInput, tempOutput, false); + } finally { + tempOutput.close(); + } + } finally { + entryInput.close(); + } + + /// make sure we use the new normalizer to encrypt the file entry + tempManifest.setStreamNormalizer(newNormalizer); + InputStream tempInput = tempManifest.getStorage() + .getInputSource().openEntryStream(tempEntryPath); + try { + OutputStream entryOutput = openEntryOutputStream(entryPath); + try { + FileUtils.transfer(tempInput, entryOutput, false); + } finally { + entryOutput.close(); + } + } finally { + tempInput.close(); + } + + } else { + /// saving to external location, + /// just copy the entry directly + InputStream entryInput = sourceEntry.openInputStream(); + try { + OutputStream entryOutput = openEntryOutputStream(entryPath); + try { + FileUtils.transfer(entryInput, entryOutput, false); + } finally { + entryOutput.close(); + } + } finally { + entryInput.close(); + } + } + } + + if (usesWorkbookStorageAsOutputTarget && normalizerChanged) { + /// keep the new normalizer in the original manifest + /// to decrypt data in the internal storage afterwards + manifest.setStreamNormalizer(newNormalizer); + } + + /// save manifest.xml + serializeXML(tempManifest, MANIFEST_XML); + + /// only upon success should we close zip stream + if (intermediateOutputStream != null) { + intermediateOutputStream.finish(); + intermediateOutputStream.flush(); + intermediateOutputStream.close(); + } + + } + + private static Document cloneDocument(Document document, String xmlName) + throws CoreException { + try { + Transformer transformer = createXMLSerializer(); + DOMResult result = new DOMResult(); + transformer.transform(new DOMSource(document), result); + return (Document) result.getNode(); + } catch (TransformerException e) { + throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, xmlName, + e); + } + } + + private static Transformer createXMLSerializer() throws CoreException { + /// create a new transformer instance each time + return DOMUtils.getDefaultTransformer(); + } + + private String makeTempPath(String path) { + int sepIndex = path.lastIndexOf('/'); + if (sepIndex >= 0) { + return path.substring(0, sepIndex + 1) + "._." //$NON-NLS-1$ + + path.substring(sepIndex + 1); + } + // no separator + return "._." + path; //$NON-NLS-1$ + } + + private void serializeXML(IAdaptable domAdaptable, String entryPath) + throws IOException, CoreException { + Node node = (Node) domAdaptable.getAdapter(Node.class); + if (node == null) + throw new CoreException(Core.ERROR_INVALID_ARGUMENT, + "Object has no DOM node"); //$NON-NLS-1$ + + Transformer transformer = createXMLSerializer(); + OutputStream out = openEntryOutputStream(entryPath); + try { + transformer.transform(new DOMSource(node), new StreamResult(out)); + } catch (TransformerException e) { + if (e.getCause() != null && e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } + throw new CoreException(Core.ERROR_FAIL_SERIALIZING_XML, entryPath, + e); + } finally { + out.close(); + } + + serializedEntryPaths.add(entryPath); + } + + private OutputStream openEntryOutputStream(String entryPath) + throws IOException, CoreException { + IFileEntry entry = tempManifest.getFileEntry(entryPath); + + if (isEntryEncryptionIgnored(entryPath)) { + entry.deleteEncryptionData(); + return tempManifest.getStorage().getOutputTarget() + .openEntryStream(entryPath); + } + + if (entry == null) { + entry = tempManifest.createFileEntry(entryPath); + entry.increaseReference(); + } + return entry.openOutputStream(); + } + +// String calcChecksum(Object checksumProvider) { +// if (checksumProvider instanceof IChecksumStream) { +// return ((IChecksumStream) checksumProvider).getChecksum(); +// } +// return null; +// } + +// void recordChecksum(String entryPath, Object checksumProvider) { +// String checksum = calcChecksum(checksumProvider); +// if (checksum == null) +// return; +// +// IFileEntry entry = tempManifest.getFileEntry(entryPath); +// if (entry == null) +// return; +// +// IEncryptionData encData = entry.getEncryptionData(); +// if (encData == null || encData.getChecksumType() == null) +// return; +// +// encData.setAttribute(checksum, DOMConstants.ATTR_CHECKSUM); +// } + + private static class WriteOnlyStorage implements IStorage { + + private IOutputTarget target; + + public WriteOnlyStorage(IOutputTarget target) { + this.target = target; + } + + public IInputSource getInputSource() { + throw new UnsupportedOperationException(); + } + + public IOutputTarget getOutputTarget() { + return target; + } + + public String getName() { + return toString(); + } + + public String getFullPath() { + return getName(); + } + + public void clear() { + } + + public void deleteEntry(String entryName) { + } + + public void renameEntry(String entryName, String newName) { + } + + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SettingEntryImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SettingEntryImpl.java index 38ef2efb9..c0ab6bff1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SettingEntryImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SettingEntryImpl.java @@ -1,108 +1,108 @@ -package org.xmind.core.internal.dom; - -import java.util.HashSet; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.internal.SettingEntry; -import org.xmind.core.util.DOMUtils; - -/** - * @author Jason Wong - * @since 3.6.50 - */ -public class SettingEntryImpl extends SettingEntry { - - private Element implementation; - - private SheetImpl ownedSheet; - - private String path; - - public SettingEntryImpl(Element implementation, String path, - SheetImpl ownedSheet) { - this.implementation = implementation; - this.path = path; - this.ownedSheet = ownedSheet; - } - - protected Element getImplementation() { - return implementation; - } - - public String getPath() { - return path; - } - - public String getAttribute(String key) { - return DOMUtils.getAttribute(implementation, key); - } - - public void setAttribute(String key, String value) { - String oldValue = DOMUtils.getAttribute(implementation, key); - DOMUtils.setAttribute(implementation, key, value); - String newValue = DOMUtils.getAttribute(implementation, key); - if (oldValue != newValue - && (oldValue == null || !oldValue.equals(newValue))) { - ISheet sheet = getOwnedSheet(); - if (sheet != null) { - CoreEvent event = new CoreEvent(ownedSheet, Core.SheetSettings, - key, oldValue, newValue); - event.setData(getPath()); - ownedSheet.getCoreEventSupport().dispatch(ownedSheet, event); - } - } - } - - public Set getAttributeKeys() { - Set keys = new HashSet(); - NamedNodeMap atts = implementation.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) - keys.add(atts.item(i).getNodeName()); - return keys; - } - - public ISheet getOwnedSheet() { - return ownedSheet; - } - - public IWorkbook getOwnedWorkbook() { - return getOwnedSheet().getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getImplementation()); - return super.getAdapter(adapter); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SettingEntryImpl)) - return false; - SettingEntryImpl that = (SettingEntryImpl) obj; - return that.implementation == this.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public String toString() { - return DOMUtils.toString(implementation); - } - -} +package org.xmind.core.internal.dom; + +import java.util.HashSet; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.internal.SettingEntry; +import org.xmind.core.util.DOMUtils; + +/** + * @author Jason Wong + * @since 3.6.50 + */ +public class SettingEntryImpl extends SettingEntry { + + private Element implementation; + + private SheetImpl ownedSheet; + + private String path; + + public SettingEntryImpl(Element implementation, String path, + SheetImpl ownedSheet) { + this.implementation = implementation; + this.path = path; + this.ownedSheet = ownedSheet; + } + + protected Element getImplementation() { + return implementation; + } + + public String getPath() { + return path; + } + + public String getAttribute(String key) { + return DOMUtils.getAttribute(implementation, key); + } + + public void setAttribute(String key, String value) { + String oldValue = DOMUtils.getAttribute(implementation, key); + DOMUtils.setAttribute(implementation, key, value); + String newValue = DOMUtils.getAttribute(implementation, key); + if (oldValue != newValue + && (oldValue == null || !oldValue.equals(newValue))) { + ISheet sheet = getOwnedSheet(); + if (sheet != null) { + CoreEvent event = new CoreEvent(ownedSheet, Core.SheetSettings, + key, oldValue, newValue); + event.setData(getPath()); + ownedSheet.getCoreEventSupport().dispatch(ownedSheet, event); + } + } + } + + public Set getAttributeKeys() { + Set keys = new HashSet(); + NamedNodeMap atts = implementation.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) + keys.add(atts.item(i).getNodeName()); + return keys; + } + + public ISheet getOwnedSheet() { + return ownedSheet; + } + + public IWorkbook getOwnedWorkbook() { + return getOwnedSheet().getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); + return super.getAdapter(adapter); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SettingEntryImpl)) + return false; + SettingEntryImpl that = (SettingEntryImpl) obj; + return that.implementation == this.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public String toString() { + return DOMUtils.toString(implementation); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetImpl.java index a2d572e8e..41d4be451 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetImpl.java @@ -1,401 +1,401 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_THEME; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; - -import java.util.Collections; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.ILegend; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheetSetting; -import org.xmind.core.ISheetSettings; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Sheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.ILabelRefCounter; -import org.xmind.core.util.IMarkerRefCounter; - -/** - * @author Brian Sun - * @author Frank Shaka - */ -public class SheetImpl extends Sheet implements ICoreEventSource { - - private static final Set NO_RELATIONSHIPS = Collections - .emptySet(); - - private Element implementation; - - private WorkbookImpl ownedWorkbook; - - private SheetMarkerRefCounter markerRefCounter = null; - - private SheetLabelRefCounter labelRefCounter = null; - - private LegendImpl legend = null; - - private ISheetSetting setting; - - private ISheetSettings settings; - - /** - * @param implementation - */ - public SheetImpl(Element implementation, WorkbookImpl ownedWorkbook) { - super(); - this.ownedWorkbook = ownedWorkbook; - this.implementation = DOMUtils.addIdAttribute(implementation); - DOMUtils.ensureChildElement(implementation, TAG_TOPIC); - //((TopicImpl) getRootTopic()).addNotify(ownedWorkbook, this, null); - } - - /** - * @return the implementation - */ - public Element getImplementation() { - return implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SheetImpl)) - return false; - SheetImpl t = (SheetImpl) obj; - return implementation == t.implementation; - } - - public String toString() { - return "SHT#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) { - return adapter.cast(implementation); - } else if (IMarkerRefCounter.class.equals(adapter)) { - return adapter.cast(getMarkerRefCounter()); - } else if (ILabelRefCounter.class.equals(adapter)) { - return adapter.cast(getLabelRefCounter()); - } else if (ICoreEventSupport.class.equals(adapter)) { - return adapter.cast(getCoreEventSupport()); - } - return super.getAdapter(adapter); - } - - /** - * @see org.xmind.core.internal.Sheet#getLocalTitleText() - */ - @Override - protected String getLocalTitleText() { - return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); - } - - /** - * @see org.xmind.core.ITitled#setTitleText(java.lang.String) - */ - public void setTitleText(String titleText) { - String oldValue = getLocalTitleText(); - DOMUtils.setText(implementation, TAG_TITLE, titleText); - String newValue = getLocalTitleText(); - fireValueChange(Core.TitleText, oldValue, newValue); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.ISheet#getRootTopic() - */ - public ITopic getRootTopic() { - Element t = DOMUtils.getFirstChildElementByTag(implementation, - TAG_TOPIC); - return (ITopic) ownedWorkbook.getAdaptableRegistry().getAdaptable(t); - } - - /** - * @see org.xmind.core.ISheet#getId() - */ - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbookComponent#isOrphan() - */ - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - /** - * @see org.xmind.core.ISheet#getParent() - */ - public IWorkbook getParent() { - Node p = implementation.getParentNode(); - if (p == ownedWorkbook.getWorkbookElement()) - return ownedWorkbook; - return null; - } - - /** - * @see org.xmind.core.ISheet#getIndex() - */ - public int getIndex() { - Node p = implementation.getParentNode(); - if (p == ownedWorkbook.getWorkbookElement()) { - return DOMUtils.getElementIndex(p, DOMConstants.TAG_SHEET, - implementation); - } - return -1; - } - - /** - * @see org.xmind.core.ISheet#getRelationships() - */ - public Set getRelationships() { - Element rs = DOMUtils.getFirstChildElementByTag(implementation, - TAG_RELATIONSHIPS); - if (rs != null) - return DOMUtils.getChildSet(rs, TAG_RELATIONSHIP, - ownedWorkbook.getAdaptableRegistry()); - return NO_RELATIONSHIPS; - } - - /** - * @see org.xmind.core.ISheet#addRelationship(org.xmind.core.IRelationship) - */ - public void addRelationship(IRelationship rel) { - Element rs = DOMUtils.ensureChildElement(implementation, - TAG_RELATIONSHIPS); - Element r = ((RelationshipImpl) rel).getImplementation(); - Node n = rs.appendChild(r); - if (n != null) { - if (!isOrphan()) { - ((RelationshipImpl) rel).addNotify(ownedWorkbook, this); - } - fireTargetChange(Core.RelationshipAdd, rel); - } - } - - /** - * @see org.xmind.core.ISheet#removeRelationship(org.xmind.core.IRelationship) - */ - public void removeRelationship(IRelationship rel) { - Element rs = DOMUtils.getFirstChildElementByTag(implementation, - TAG_RELATIONSHIPS); - if (rs != null) { - if (!isOrphan()) { - ((RelationshipImpl) rel).removeNotify(ownedWorkbook, this); - } - Element r = ((RelationshipImpl) rel).getImplementation(); - Node n = rs.removeChild(r); - if (!rs.hasChildNodes()) - implementation.removeChild(rs); - if (n != null) { - fireTargetChange(Core.RelationshipRemove, rel); - updateModificationInfo(); - } - } - } - - public String getThemeId() { - return DOMUtils.getAttribute(implementation, ATTR_THEME); - } - - public void setThemeId(String themeId) { - String oldValue = getThemeId(); - WorkbookImpl workbook = (WorkbookImpl) getParent(); - decreaseThemeRef(workbook); - DOMUtils.setAttribute(implementation, ATTR_THEME, themeId); - increaseThemeRef(workbook); - String newValue = getThemeId(); - fireValueChange(Core.ThemeId, oldValue, newValue); - updateModificationInfo(); - } - - public String getStyleId() { - return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); - } - - public void setStyleId(String styleId) { - String oldValue = getStyleId(); - WorkbookImpl workbook = (WorkbookImpl) getParent(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - String newValue = getStyleId(); - fireValueChange(Core.Style, oldValue, newValue); - updateModificationInfo(); - } - - public void replaceRootTopic(ITopic newRootTopic) { - TopicImpl r1 = (TopicImpl) getRootTopic(); - TopicImpl r2 = (TopicImpl) newRootTopic; - if (!isOrphan()) { - r1.removeNotify((WorkbookImpl) getParent(), this, null); - } - implementation.removeChild(r1.getImplementation()); - implementation.appendChild(r2.getImplementation()); - if (!isOrphan()) { - r2.addNotify((WorkbookImpl) getParent(), this, null); - } - fireValueChange(Core.RootTopic, r1, r2); - updateModificationInfo(); - } - - public ILegend getLegend() { - if (legend == null) { - legend = new LegendImpl(implementation, this); - } - return legend; - } - - public ILabelRefCounter getLabelRefCounter() { - if (labelRefCounter == null) - labelRefCounter = new SheetLabelRefCounter(this); - return labelRefCounter; - } - - public IMarkerRefCounter getMarkerRefCounter() { - if (markerRefCounter == null) - markerRefCounter = new SheetMarkerRefCounter(this); - return markerRefCounter; - } - - protected void addNotify(WorkbookImpl workbook) { - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); - workbook.getAdaptableRegistry().registerById(this, getId(), - getImplementation().getOwnerDocument()); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - increaseThemeRef(workbook); - ((TopicImpl) getRootTopic()).addNotify(workbook, this, null); - for (IRelationship rel : getRelationships()) { - ((RelationshipImpl) rel).addNotify(workbook, this); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - for (IRelationship rel : getRelationships()) { - ((RelationshipImpl) rel).removeNotify(workbook, this); - } - ((TopicImpl) getRootTopic()).removeNotify(workbook, this, null); - decreaseThemeRef(workbook); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - workbook.getAdaptableRegistry().unregisterById(this, getId(), - getImplementation().getOwnerDocument()); - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); - } - - private void decreaseThemeRef(WorkbookImpl workbook) { - if (workbook == null) - return; - - String themeId = getThemeId(); - if (themeId != null) - workbook.getStyleRefCounter().decreaseRef(themeId); - } - - private void increaseThemeRef(WorkbookImpl workbook) { - if (workbook == null) - return; - - String themeId = getThemeId(); - if (themeId != null) - workbook.getStyleRefCounter().increaseRef(themeId); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedWorkbook.getCoreEventSupport(); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - ICoreEventSupport coreEventSupport = getCoreEventSupport(); - if (coreEventSupport != null) { - coreEventSupport.dispatchValueChange(this, type, oldValue, - newValue); - } - } - - private void fireTargetChange(String type, Object target) { - ICoreEventSupport coreEventSupport = getCoreEventSupport(); - if (coreEventSupport != null) { - coreEventSupport.dispatchTargetChange(this, type, target); - } - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, implementation); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, implementation); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - - IWorkbook parent = getParent(); - if (parent != null) { - ((WorkbookImpl) parent).updateModificationInfo(); - } - } - - public ISheetSetting getSetting() { - if (setting == null) - setting = new SheetSetting(implementation, this); - return setting; - } - - public ISheetSettings getSettings() { - if (settings == null) - settings = new SheetSettingsImpl(implementation, this); - return settings; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_THEME; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; + +import java.util.Collections; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.ILegend; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheetSetting; +import org.xmind.core.ISheetSettings; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Sheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.ILabelRefCounter; +import org.xmind.core.util.IMarkerRefCounter; + +/** + * @author Brian Sun + * @author Frank Shaka + */ +public class SheetImpl extends Sheet implements ICoreEventSource { + + private static final Set NO_RELATIONSHIPS = Collections + .emptySet(); + + private Element implementation; + + private WorkbookImpl ownedWorkbook; + + private SheetMarkerRefCounter markerRefCounter = null; + + private SheetLabelRefCounter labelRefCounter = null; + + private LegendImpl legend = null; + + private ISheetSetting setting; + + private ISheetSettings settings; + + /** + * @param implementation + */ + public SheetImpl(Element implementation, WorkbookImpl ownedWorkbook) { + super(); + this.ownedWorkbook = ownedWorkbook; + this.implementation = DOMUtils.addIdAttribute(implementation); + DOMUtils.ensureChildElement(implementation, TAG_TOPIC); + //((TopicImpl) getRootTopic()).addNotify(ownedWorkbook, this, null); + } + + /** + * @return the implementation + */ + public Element getImplementation() { + return implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SheetImpl)) + return false; + SheetImpl t = (SheetImpl) obj; + return implementation == t.implementation; + } + + public String toString() { + return "SHT#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) { + return adapter.cast(implementation); + } else if (IMarkerRefCounter.class.equals(adapter)) { + return adapter.cast(getMarkerRefCounter()); + } else if (ILabelRefCounter.class.equals(adapter)) { + return adapter.cast(getLabelRefCounter()); + } else if (ICoreEventSupport.class.equals(adapter)) { + return adapter.cast(getCoreEventSupport()); + } + return super.getAdapter(adapter); + } + + /** + * @see org.xmind.core.internal.Sheet#getLocalTitleText() + */ + @Override + protected String getLocalTitleText() { + return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); + } + + /** + * @see org.xmind.core.ITitled#setTitleText(java.lang.String) + */ + public void setTitleText(String titleText) { + String oldValue = getLocalTitleText(); + DOMUtils.setText(implementation, TAG_TITLE, titleText); + String newValue = getLocalTitleText(); + fireValueChange(Core.TitleText, oldValue, newValue); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.ISheet#getRootTopic() + */ + public ITopic getRootTopic() { + Element t = DOMUtils.getFirstChildElementByTag(implementation, + TAG_TOPIC); + return (ITopic) ownedWorkbook.getAdaptableRegistry().getAdaptable(t); + } + + /** + * @see org.xmind.core.ISheet#getId() + */ + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbookComponent#isOrphan() + */ + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + /** + * @see org.xmind.core.ISheet#getParent() + */ + public IWorkbook getParent() { + Node p = implementation.getParentNode(); + if (p == ownedWorkbook.getWorkbookElement()) + return ownedWorkbook; + return null; + } + + /** + * @see org.xmind.core.ISheet#getIndex() + */ + public int getIndex() { + Node p = implementation.getParentNode(); + if (p == ownedWorkbook.getWorkbookElement()) { + return DOMUtils.getElementIndex(p, DOMConstants.TAG_SHEET, + implementation); + } + return -1; + } + + /** + * @see org.xmind.core.ISheet#getRelationships() + */ + public Set getRelationships() { + Element rs = DOMUtils.getFirstChildElementByTag(implementation, + TAG_RELATIONSHIPS); + if (rs != null) + return DOMUtils.getChildSet(rs, TAG_RELATIONSHIP, + ownedWorkbook.getAdaptableRegistry()); + return NO_RELATIONSHIPS; + } + + /** + * @see org.xmind.core.ISheet#addRelationship(org.xmind.core.IRelationship) + */ + public void addRelationship(IRelationship rel) { + Element rs = DOMUtils.ensureChildElement(implementation, + TAG_RELATIONSHIPS); + Element r = ((RelationshipImpl) rel).getImplementation(); + Node n = rs.appendChild(r); + if (n != null) { + if (!isOrphan()) { + ((RelationshipImpl) rel).addNotify(ownedWorkbook, this); + } + fireTargetChange(Core.RelationshipAdd, rel); + } + } + + /** + * @see org.xmind.core.ISheet#removeRelationship(org.xmind.core.IRelationship) + */ + public void removeRelationship(IRelationship rel) { + Element rs = DOMUtils.getFirstChildElementByTag(implementation, + TAG_RELATIONSHIPS); + if (rs != null) { + if (!isOrphan()) { + ((RelationshipImpl) rel).removeNotify(ownedWorkbook, this); + } + Element r = ((RelationshipImpl) rel).getImplementation(); + Node n = rs.removeChild(r); + if (!rs.hasChildNodes()) + implementation.removeChild(rs); + if (n != null) { + fireTargetChange(Core.RelationshipRemove, rel); + updateModificationInfo(); + } + } + } + + public String getThemeId() { + return DOMUtils.getAttribute(implementation, ATTR_THEME); + } + + public void setThemeId(String themeId) { + String oldValue = getThemeId(); + WorkbookImpl workbook = (WorkbookImpl) getParent(); + decreaseThemeRef(workbook); + DOMUtils.setAttribute(implementation, ATTR_THEME, themeId); + increaseThemeRef(workbook); + String newValue = getThemeId(); + fireValueChange(Core.ThemeId, oldValue, newValue); + updateModificationInfo(); + } + + public String getStyleId() { + return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); + } + + public void setStyleId(String styleId) { + String oldValue = getStyleId(); + WorkbookImpl workbook = (WorkbookImpl) getParent(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + String newValue = getStyleId(); + fireValueChange(Core.Style, oldValue, newValue); + updateModificationInfo(); + } + + public void replaceRootTopic(ITopic newRootTopic) { + TopicImpl r1 = (TopicImpl) getRootTopic(); + TopicImpl r2 = (TopicImpl) newRootTopic; + if (!isOrphan()) { + r1.removeNotify((WorkbookImpl) getParent(), this, null); + } + implementation.removeChild(r1.getImplementation()); + implementation.appendChild(r2.getImplementation()); + if (!isOrphan()) { + r2.addNotify((WorkbookImpl) getParent(), this, null); + } + fireValueChange(Core.RootTopic, r1, r2); + updateModificationInfo(); + } + + public ILegend getLegend() { + if (legend == null) { + legend = new LegendImpl(implementation, this); + } + return legend; + } + + public ILabelRefCounter getLabelRefCounter() { + if (labelRefCounter == null) + labelRefCounter = new SheetLabelRefCounter(this); + return labelRefCounter; + } + + public IMarkerRefCounter getMarkerRefCounter() { + if (markerRefCounter == null) + markerRefCounter = new SheetMarkerRefCounter(this); + return markerRefCounter; + } + + protected void addNotify(WorkbookImpl workbook) { + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); + workbook.getAdaptableRegistry().registerById(this, getId(), + getImplementation().getOwnerDocument()); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + increaseThemeRef(workbook); + ((TopicImpl) getRootTopic()).addNotify(workbook, this, null); + for (IRelationship rel : getRelationships()) { + ((RelationshipImpl) rel).addNotify(workbook, this); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + for (IRelationship rel : getRelationships()) { + ((RelationshipImpl) rel).removeNotify(workbook, this); + } + ((TopicImpl) getRootTopic()).removeNotify(workbook, this, null); + decreaseThemeRef(workbook); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + workbook.getAdaptableRegistry().unregisterById(this, getId(), + getImplementation().getOwnerDocument()); + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); + } + + private void decreaseThemeRef(WorkbookImpl workbook) { + if (workbook == null) + return; + + String themeId = getThemeId(); + if (themeId != null) + workbook.getStyleRefCounter().decreaseRef(themeId); + } + + private void increaseThemeRef(WorkbookImpl workbook) { + if (workbook == null) + return; + + String themeId = getThemeId(); + if (themeId != null) + workbook.getStyleRefCounter().increaseRef(themeId); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedWorkbook.getCoreEventSupport(); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + ICoreEventSupport coreEventSupport = getCoreEventSupport(); + if (coreEventSupport != null) { + coreEventSupport.dispatchValueChange(this, type, oldValue, + newValue); + } + } + + private void fireTargetChange(String type, Object target) { + ICoreEventSupport coreEventSupport = getCoreEventSupport(); + if (coreEventSupport != null) { + coreEventSupport.dispatchTargetChange(this, type, target); + } + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, implementation); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, implementation); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + + IWorkbook parent = getParent(); + if (parent != null) { + ((WorkbookImpl) parent).updateModificationInfo(); + } + } + + public ISheetSetting getSetting() { + if (setting == null) + setting = new SheetSetting(implementation, this); + return setting; + } + + public ISheetSettings getSettings() { + if (settings == null) + settings = new SheetSettingsImpl(implementation, this); + return settings; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSetting.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSetting.java index f2f3775e2..d4736bd37 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSetting.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSetting.java @@ -1,119 +1,119 @@ -package org.xmind.core.internal.dom; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ISheetSetting; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.util.DOMUtils; - -public class SheetSetting implements ISheetSetting { - - private Element sheetEle; - - private SheetImpl ownedSheet; - - public SheetSetting(Element sheetEle, SheetImpl ownedSheet) { - this.sheetEle = sheetEle; - this.ownedSheet = ownedSheet; - } - - public boolean isInfoItemVisible(String type, String key, String defaultMode) { - String mode = getInfoItemMode(type, DOMConstants.ATTR_MODE); - - if (mode == null) - mode = defaultMode; - - return mode != null && mode.equals(DOMConstants.VAL_CARDMODE); - } - - public void setInfoItemVisible(String type, String key, String defaultMode, - boolean visible) { - if (visible) { - if (!isInfoItemVisible(type, key, defaultMode)) { - setInfoItemMode(type, key, DOMConstants.VAL_CARDMODE); - fireValueChange(ownedSheet, Core.Visibility, Boolean.FALSE, - Boolean.TRUE); - } - } else { - if (isInfoItemVisible(type, key, defaultMode)) { - setInfoItemMode(type, key, DOMConstants.VAL_ICONMODE); - fireValueChange(ownedSheet, Core.Visibility, Boolean.TRUE, - Boolean.FALSE); - } - } - } - - public String getInfoItemMode(String type, String key) { - Element infoItemEle = getInfoItemEle(type); - if (infoItemEle == null) - return null; - return DOMUtils.getAttribute(infoItemEle, DOMConstants.ATTR_MODE); - } - - public void setInfoItemMode(String type, String key, String value) { - Element infoItemEle = ensureInfoItemEle(type); - DOMUtils.setAttribute(infoItemEle, key, value); - } - - public Element getSheetEle() { - return sheetEle; - } - - public SheetImpl getOwnedSheet() { - return ownedSheet; - } - - private Element getInfoItemEle(String type) { - if (sheetEle != null) { - Element settingsEle = DOMUtils.getFirstChildElementByTag(sheetEle, - DOMConstants.TAG_SHEET_SETTINGS); - if (settingsEle == null) - return null; - Element infoItemsEle = DOMUtils.getFirstChildElementByTag( - settingsEle, DOMConstants.TAG_INFO_ITEMS); - if (infoItemsEle == null) - return null; - Element[] infoItemEles = DOMUtils.getChildElementsByTag( - infoItemsEle, DOMConstants.TAG_INFO_ITEM); - if (infoItemEles == null || infoItemEles.length == 0) - return null; - - for (Element infoItemEle : infoItemEles) { - String eleType = DOMUtils.getAttribute(infoItemEle, - DOMConstants.ATTR_TYPE); - if (type.equals(eleType)) - return infoItemEle; - } - } - return null; - } - - private Element ensureInfoItemEle(String type) { - Element sheetSettingsEle = DOMUtils.ensureChildElement(sheetEle, - DOMConstants.TAG_SHEET_SETTINGS); - Element infoItemsEle = DOMUtils.ensureChildElement(sheetSettingsEle, - DOMConstants.TAG_INFO_ITEMS); - Element infoItemEle = getInfoItemEle(type); - if (infoItemEle == null) { - infoItemEle = DOMUtils.createElement(infoItemsEle, - DOMConstants.TAG_INFO_ITEM); - DOMUtils.setAttribute(infoItemEle, DOMConstants.ATTR_TYPE, type); - } - - return infoItemEle; - } - - private void fireValueChange(ISheet sheet, String visibility, - Boolean oldValue, Boolean newValue) { - if (sheet instanceof ICoreEventSource) - getCoreEventSupport(sheet).dispatchValueChange( - (ICoreEventSource) sheet, visibility, oldValue, newValue); - } - - private ICoreEventSupport getCoreEventSupport(ISheet sheet) { - return (ICoreEventSupport) sheet.getAdapter(ICoreEventSupport.class); - } - -} +package org.xmind.core.internal.dom; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ISheetSetting; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.util.DOMUtils; + +public class SheetSetting implements ISheetSetting { + + private Element sheetEle; + + private SheetImpl ownedSheet; + + public SheetSetting(Element sheetEle, SheetImpl ownedSheet) { + this.sheetEle = sheetEle; + this.ownedSheet = ownedSheet; + } + + public boolean isInfoItemVisible(String type, String key, String defaultMode) { + String mode = getInfoItemMode(type, DOMConstants.ATTR_MODE); + + if (mode == null) + mode = defaultMode; + + return mode != null && mode.equals(DOMConstants.VAL_CARDMODE); + } + + public void setInfoItemVisible(String type, String key, String defaultMode, + boolean visible) { + if (visible) { + if (!isInfoItemVisible(type, key, defaultMode)) { + setInfoItemMode(type, key, DOMConstants.VAL_CARDMODE); + fireValueChange(ownedSheet, Core.Visibility, Boolean.FALSE, + Boolean.TRUE); + } + } else { + if (isInfoItemVisible(type, key, defaultMode)) { + setInfoItemMode(type, key, DOMConstants.VAL_ICONMODE); + fireValueChange(ownedSheet, Core.Visibility, Boolean.TRUE, + Boolean.FALSE); + } + } + } + + public String getInfoItemMode(String type, String key) { + Element infoItemEle = getInfoItemEle(type); + if (infoItemEle == null) + return null; + return DOMUtils.getAttribute(infoItemEle, DOMConstants.ATTR_MODE); + } + + public void setInfoItemMode(String type, String key, String value) { + Element infoItemEle = ensureInfoItemEle(type); + DOMUtils.setAttribute(infoItemEle, key, value); + } + + public Element getSheetEle() { + return sheetEle; + } + + public SheetImpl getOwnedSheet() { + return ownedSheet; + } + + private Element getInfoItemEle(String type) { + if (sheetEle != null) { + Element settingsEle = DOMUtils.getFirstChildElementByTag(sheetEle, + DOMConstants.TAG_SHEET_SETTINGS); + if (settingsEle == null) + return null; + Element infoItemsEle = DOMUtils.getFirstChildElementByTag( + settingsEle, DOMConstants.TAG_INFO_ITEMS); + if (infoItemsEle == null) + return null; + Element[] infoItemEles = DOMUtils.getChildElementsByTag( + infoItemsEle, DOMConstants.TAG_INFO_ITEM); + if (infoItemEles == null || infoItemEles.length == 0) + return null; + + for (Element infoItemEle : infoItemEles) { + String eleType = DOMUtils.getAttribute(infoItemEle, + DOMConstants.ATTR_TYPE); + if (type.equals(eleType)) + return infoItemEle; + } + } + return null; + } + + private Element ensureInfoItemEle(String type) { + Element sheetSettingsEle = DOMUtils.ensureChildElement(sheetEle, + DOMConstants.TAG_SHEET_SETTINGS); + Element infoItemsEle = DOMUtils.ensureChildElement(sheetSettingsEle, + DOMConstants.TAG_INFO_ITEMS); + Element infoItemEle = getInfoItemEle(type); + if (infoItemEle == null) { + infoItemEle = DOMUtils.createElement(infoItemsEle, + DOMConstants.TAG_INFO_ITEM); + DOMUtils.setAttribute(infoItemEle, DOMConstants.ATTR_TYPE, type); + } + + return infoItemEle; + } + + private void fireValueChange(ISheet sheet, String visibility, + Boolean oldValue, Boolean newValue) { + if (sheet instanceof ICoreEventSource) + getCoreEventSupport(sheet).dispatchValueChange( + (ICoreEventSource) sheet, visibility, oldValue, newValue); + } + + private ICoreEventSupport getCoreEventSupport(ISheet sheet) { + return (ICoreEventSupport) sheet.getAdapter(ICoreEventSupport.class); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSettingsImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSettingsImpl.java index 7eb8d386f..4878f1bd9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSettingsImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SheetSettingsImpl.java @@ -1,220 +1,220 @@ -package org.xmind.core.internal.dom; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.ISettingEntry; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.internal.ElementRegistry; -import org.xmind.core.internal.SheetSettings; -import org.xmind.core.util.DOMUtils; - -/** - * @author Jason Wong - * @since 3.6.50 - */ -public class SheetSettingsImpl extends SheetSettings { - - private Element implementation; - - private SheetImpl ownedSheet; - - private ElementRegistry elementRegistry; - - public SheetSettingsImpl(Element implementation, SheetImpl ownedSheet) { - super(); - this.implementation = implementation; - this.ownedSheet = ownedSheet; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.ISheetSettings#getPaths() - */ - public Set getPaths() { - HashSet paths = new HashSet(); - Element e = DOMUtils.getFirstChildElementByTag(implementation, - DOMConstants.TAG_SHEET_SETTINGS); - if (e == null) - return paths; - - collectPaths(paths, e, null); - return paths; - } - - private void collectPaths(Set paths, Element p, String path) { - Iterator childIt = DOMUtils.childElementIter(p); - if (childIt.hasNext()) { - while (childIt.hasNext()) { - Element c = childIt.next(); - String subTag = c.getTagName(); - String subPath = path == null ? subTag : path + SEP + subTag; - collectPaths(paths, c, subPath); - } - } else { - if (path != null) { - paths.add(path); - } - } - } - - public List getEntries(String path) { - if (path == null || "".equals(path)) //$NON-NLS-1$ - return Collections.emptyList(); - - Element e = DOMUtils.getFirstChildElementByTag(implementation, - DOMConstants.TAG_SHEET_SETTINGS); - if (e == null) - return Collections.emptyList(); - - String[] keys = path.split(SEP); - if (keys.length > 0) { - String endKey = keys[keys.length - 1]; - Element c = null; - for (String key : keys) { - if (key != endKey) { - c = DOMUtils.getFirstChildElementByTag(e, key); - if (c == null) - break; - e = c; - } else { - List entries = new ArrayList(); - Iterator es = DOMUtils.childElementIterByTag(e, - key); - while (es.hasNext()) { - Element entryEle = es.next(); - ISettingEntry entry = getEntry(entryEle, path); - if (entry != null) - entries.add(entry); - } - return entries; - } - } - } - return Collections.emptyList(); - } - - protected SettingEntryImpl getEntry(Element entryEle, String path) { - if (elementRegistry != null) { - Object entry = elementRegistry.getElement(entryEle); - if (entry != null && entry instanceof ISettingEntry) - return (SettingEntryImpl) entry; - } - - SettingEntryImpl entry = new SettingEntryImpl(entryEle, path, - ownedSheet); - getElementRegistry().registerByKey(entryEle, entry); - return entry; - } - - public ISettingEntry createEntry(String path) { - if (path != null) { - String[] keys = path.split(SEP); - if (keys.length > 0) { - String tag = keys[keys.length - 1]; - Element entryEle = implementation.getOwnerDocument() - .createElement(tag); - SettingEntryImpl entry = new SettingEntryImpl(entryEle, path, - ownedSheet); - getElementRegistry().registerByKey(entryEle, entry); - return entry; - } - } - return null; - } - - public void addEntry(ISettingEntry entry) { - SettingEntryImpl entryImpl = (SettingEntryImpl) entry; - String path = entryImpl.getPath(); - String[] keys = path.split(SEP); - - String lastKey = keys[keys.length - 1]; - Element p = DOMUtils.ensureChildElement(implementation, - DOMConstants.TAG_SHEET_SETTINGS); - for (String key : keys) { - if (key != lastKey) { - p = DOMUtils.ensureChildElement(p, key); - } else { - p.appendChild(entryImpl.getImplementation()); - for (String attrKey : entry.getAttributeKeys()) { - CoreEvent event = new CoreEvent(ownedSheet, - Core.SheetSettings, attrKey, null, - entry.getAttribute(attrKey)); - event.setData(path); - ownedSheet.getCoreEventSupport().dispatch(ownedSheet, - event); - } - } - } - } - - public void removeEntry(ISettingEntry entry) { - Element settingsEle = DOMUtils.getFirstChildElementByTag(implementation, - DOMConstants.TAG_SHEET_SETTINGS); - if (settingsEle == null) - return; - - String path = entry.getPath(); - Element entryEle = ((SettingEntryImpl) entry).getImplementation(); - settingsEle.removeChild(entryEle); - for (String attrKey : entry.getAttributeKeys()) { - CoreEvent event = new CoreEvent(ownedSheet, Core.SheetSettings, - attrKey, entry.getAttribute(attrKey), null); - event.setData(path); - ownedSheet.getCoreEventSupport().dispatch(ownedSheet, event); - } - } - - protected Element getImplementation() { - return implementation; - } - - public ElementRegistry getElementRegistry() { - if (elementRegistry == null) { - elementRegistry = new ElementRegistry(); - } - return elementRegistry; - } - - public ISheet getOwnedSheet() { - return ownedSheet; - } - - public IWorkbook getOwnedWorkbook() { - return ownedSheet.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SheetSettingsImpl)) - return false; - SheetSettingsImpl that = (SheetSettingsImpl) obj; - return that.implementation == this.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public String toString() { - return DOMUtils.toString(implementation); - } - -} +package org.xmind.core.internal.dom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.ISettingEntry; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.internal.ElementRegistry; +import org.xmind.core.internal.SheetSettings; +import org.xmind.core.util.DOMUtils; + +/** + * @author Jason Wong + * @since 3.6.50 + */ +public class SheetSettingsImpl extends SheetSettings { + + private Element implementation; + + private SheetImpl ownedSheet; + + private ElementRegistry elementRegistry; + + public SheetSettingsImpl(Element implementation, SheetImpl ownedSheet) { + super(); + this.implementation = implementation; + this.ownedSheet = ownedSheet; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.ISheetSettings#getPaths() + */ + public Set getPaths() { + HashSet paths = new HashSet(); + Element e = DOMUtils.getFirstChildElementByTag(implementation, + DOMConstants.TAG_SHEET_SETTINGS); + if (e == null) + return paths; + + collectPaths(paths, e, null); + return paths; + } + + private void collectPaths(Set paths, Element p, String path) { + Iterator childIt = DOMUtils.childElementIter(p); + if (childIt.hasNext()) { + while (childIt.hasNext()) { + Element c = childIt.next(); + String subTag = c.getTagName(); + String subPath = path == null ? subTag : path + SEP + subTag; + collectPaths(paths, c, subPath); + } + } else { + if (path != null) { + paths.add(path); + } + } + } + + public List getEntries(String path) { + if (path == null || "".equals(path)) //$NON-NLS-1$ + return Collections.emptyList(); + + Element e = DOMUtils.getFirstChildElementByTag(implementation, + DOMConstants.TAG_SHEET_SETTINGS); + if (e == null) + return Collections.emptyList(); + + String[] keys = path.split(SEP); + if (keys.length > 0) { + String endKey = keys[keys.length - 1]; + Element c = null; + for (String key : keys) { + if (key != endKey) { + c = DOMUtils.getFirstChildElementByTag(e, key); + if (c == null) + break; + e = c; + } else { + List entries = new ArrayList(); + Iterator es = DOMUtils.childElementIterByTag(e, + key); + while (es.hasNext()) { + Element entryEle = es.next(); + ISettingEntry entry = getEntry(entryEle, path); + if (entry != null) + entries.add(entry); + } + return entries; + } + } + } + return Collections.emptyList(); + } + + protected SettingEntryImpl getEntry(Element entryEle, String path) { + if (elementRegistry != null) { + Object entry = elementRegistry.getElement(entryEle); + if (entry != null && entry instanceof ISettingEntry) + return (SettingEntryImpl) entry; + } + + SettingEntryImpl entry = new SettingEntryImpl(entryEle, path, + ownedSheet); + getElementRegistry().registerByKey(entryEle, entry); + return entry; + } + + public ISettingEntry createEntry(String path) { + if (path != null) { + String[] keys = path.split(SEP); + if (keys.length > 0) { + String tag = keys[keys.length - 1]; + Element entryEle = implementation.getOwnerDocument() + .createElement(tag); + SettingEntryImpl entry = new SettingEntryImpl(entryEle, path, + ownedSheet); + getElementRegistry().registerByKey(entryEle, entry); + return entry; + } + } + return null; + } + + public void addEntry(ISettingEntry entry) { + SettingEntryImpl entryImpl = (SettingEntryImpl) entry; + String path = entryImpl.getPath(); + String[] keys = path.split(SEP); + + String lastKey = keys[keys.length - 1]; + Element p = DOMUtils.ensureChildElement(implementation, + DOMConstants.TAG_SHEET_SETTINGS); + for (String key : keys) { + if (key != lastKey) { + p = DOMUtils.ensureChildElement(p, key); + } else { + p.appendChild(entryImpl.getImplementation()); + for (String attrKey : entry.getAttributeKeys()) { + CoreEvent event = new CoreEvent(ownedSheet, + Core.SheetSettings, attrKey, null, + entry.getAttribute(attrKey)); + event.setData(path); + ownedSheet.getCoreEventSupport().dispatch(ownedSheet, + event); + } + } + } + } + + public void removeEntry(ISettingEntry entry) { + Element settingsEle = DOMUtils.getFirstChildElementByTag(implementation, + DOMConstants.TAG_SHEET_SETTINGS); + if (settingsEle == null) + return; + + String path = entry.getPath(); + Element entryEle = ((SettingEntryImpl) entry).getImplementation(); + settingsEle.removeChild(entryEle); + for (String attrKey : entry.getAttributeKeys()) { + CoreEvent event = new CoreEvent(ownedSheet, Core.SheetSettings, + attrKey, entry.getAttribute(attrKey), null); + event.setData(path); + ownedSheet.getCoreEventSupport().dispatch(ownedSheet, event); + } + } + + protected Element getImplementation() { + return implementation; + } + + public ElementRegistry getElementRegistry() { + if (elementRegistry == null) { + elementRegistry = new ElementRegistry(); + } + return elementRegistry; + } + + public ISheet getOwnedSheet() { + return ownedSheet; + } + + public IWorkbook getOwnedWorkbook() { + return ownedSheet.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SheetSettingsImpl)) + return false; + SheetSettingsImpl that = (SheetSettingsImpl) obj; + return that.implementation == this.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public String toString() { + return DOMUtils.toString(implementation); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SpanImplBase.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SpanImplBase.java index 9dbd8be0e..85d42ac64 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SpanImplBase.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SpanImplBase.java @@ -1,119 +1,119 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.ISpan; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.AbstractWorkbookComponent; -import org.xmind.core.style.IStyle; -import org.xmind.core.util.DOMUtils; - -public abstract class SpanImplBase extends AbstractWorkbookComponent - implements ISpan { - - private Node implementation; - - private HtmlNotesContentImpl owner; - - public SpanImplBase(Node implementation, HtmlNotesContentImpl owner) { - this.implementation = implementation; - this.owner = owner; - } - - public String getStyleType() { - return IStyle.TEXT; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SpanImplBase)) - return false; - SpanImplBase that = (SpanImplBase) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return implementation.toString(); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class) - && implementation instanceof Element) - return adapter.cast(implementation); - if (adapter.isAssignableFrom(Node.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public Node getImplementation() { - return implementation; - } - - protected void setImplementation(Node implementation) { -// owner.unregister(this.implementation); - owner.getAdaptableRegistry().unregister(this, this.implementation); - this.implementation = implementation; -// owner.register(this.implementation, this); - owner.getAdaptableRegistry().register(this, this.implementation); - } - - public HtmlNotesContentImpl getOwner() { - return owner; - } - - public String getStyleId() { - if (implementation instanceof Element) { - return DOMUtils.getAttribute((Element) implementation, - ATTR_STYLE_ID); - } - return null; - } - - public void setStyleId(String styleId) { - if (implementation instanceof Element) { - WorkbookImpl workbook = owner.getRealizedWorkbook(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute((Element) implementation, ATTR_STYLE_ID, - styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - getOwner().updateModifiedTime(); - } - } - - public IWorkbook getOwnedWorkbook() { - return owner.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - protected void addNotify(WorkbookImpl workbook) { - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - } - - protected void removeNotify(WorkbookImpl workbook) { - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.ISpan; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.AbstractWorkbookComponent; +import org.xmind.core.style.IStyle; +import org.xmind.core.util.DOMUtils; + +public abstract class SpanImplBase extends AbstractWorkbookComponent + implements ISpan { + + private Node implementation; + + private HtmlNotesContentImpl owner; + + public SpanImplBase(Node implementation, HtmlNotesContentImpl owner) { + this.implementation = implementation; + this.owner = owner; + } + + public String getStyleType() { + return IStyle.TEXT; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SpanImplBase)) + return false; + SpanImplBase that = (SpanImplBase) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return implementation.toString(); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class) + && implementation instanceof Element) + return adapter.cast(implementation); + if (adapter.isAssignableFrom(Node.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public Node getImplementation() { + return implementation; + } + + protected void setImplementation(Node implementation) { +// owner.unregister(this.implementation); + owner.getAdaptableRegistry().unregister(this, this.implementation); + this.implementation = implementation; +// owner.register(this.implementation, this); + owner.getAdaptableRegistry().register(this, this.implementation); + } + + public HtmlNotesContentImpl getOwner() { + return owner; + } + + public String getStyleId() { + if (implementation instanceof Element) { + return DOMUtils.getAttribute((Element) implementation, + ATTR_STYLE_ID); + } + return null; + } + + public void setStyleId(String styleId) { + if (implementation instanceof Element) { + WorkbookImpl workbook = owner.getRealizedWorkbook(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute((Element) implementation, ATTR_STYLE_ID, + styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + getOwner().updateModifiedTime(); + } + } + + public IWorkbook getOwnedWorkbook() { + return owner.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + protected void addNotify(WorkbookImpl workbook) { + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + } + + protected void removeNotify(WorkbookImpl workbook) { + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleImpl.java index ced196465..fc151373f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleImpl.java @@ -1,407 +1,407 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_FAMILY; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_DEFAULT_STYLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_PROPERTIES; - -import java.util.Iterator; -import java.util.Properties; - -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Style; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.Property; - -public class StyleImpl extends Style implements ICoreEventSource { - - private final class PropertyIter implements Iterator { - - Iterator it = propertiesElementIter(); - - Element propEle = it.next(); - - NamedNodeMap map = propEle == null ? null : propEle.getAttributes(); - - int index = 0; - - Property next = findNextProperty(); - - private Property findNextProperty() { - if (map != null) { - if (index < map.getLength()) { - Attr attr = (Attr) map.item(index); - index++; - return new Property(attr.getName(), attr.getValue()); - } - if (it.hasNext()) { - propEle = it.next(); - map = propEle == null ? null : propEle.getAttributes(); - index = 0; - if (map != null) { - return findNextProperty(); - } - } - } - return null; - } - - public void remove() { - } - - public Property next() { - if (next == null) - return next; - - Property result = next; - next = findNextProperty(); - return result; - } - - public boolean hasNext() { - return next != null; - } - } - - private final class DefaultStyleIter implements Iterator { - - Iterator propEleIt = propertiesElementIter(); - - Element propEle = null; - - Iterator defaultStyleEleIt = null; - - Property next = findNextDefaultStyle(); - - private Property findNextDefaultStyle() { - if (defaultStyleEleIt != null) { - while (defaultStyleEleIt.hasNext()) { - Element defaultStyleEle = defaultStyleEleIt.next(); - String family = DOMUtils.getAttribute(defaultStyleEle, - ATTR_STYLE_FAMILY); - if (family != null) { - String styleId = DOMUtils.getAttribute(defaultStyleEle, - ATTR_STYLE_ID); - return new Property(family, styleId); - } - } - } - if (propEleIt.hasNext()) { - propEle = propEleIt.next(); - defaultStyleEleIt = DOMUtils.childElementIterByTag(propEle, - TAG_DEFAULT_STYLE); - return findNextDefaultStyle(); - } - return null; - } - - public boolean hasNext() { - return next != null; - } - - public Property next() { - if (next == null) - return next; - - Property result = next; - next = findNextDefaultStyle(); - return result; - } - - public void remove() { - } - - } - - private Element implementation; - - private StyleSheetImpl ownedSheet; - - public StyleImpl(Element implementation, StyleSheetImpl ownedSheet) { - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedSheet = ownedSheet; - } - - public String getId() { - return implementation.getAttribute(DOMConstants.ATTR_ID); - } - - public String getType() { - return implementation.getAttribute(ATTR_TYPE); - } - - public Element getImplementation() { - return implementation; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof StyleImpl)) - return false; - StyleImpl that = (StyleImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "STY#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public IStyleSheet getOwnedStyleSheet() { - return ownedSheet; - } - - public String getName() { - String name = implementation.getAttribute(ATTR_NAME); - if (name.startsWith("%")) { //$NON-NLS-1$ - Properties properties = ownedSheet.getProperties(); - if (properties != null) { - String key = name.substring(1); - name = properties.getProperty(key, name); - } - } - return name; - } - -// public Properties getProperties() { -// Properties prop = new Properties(); -// Iterator it = propertiesElementsIter(); -// while (it.hasNext()) { -// Element propEle = it.next(); -// NamedNodeMap attrs = propEle.getAttributes(); -// for (int i = 0; i < attrs.getLength(); i++) { -// Attr attr = (Attr) attrs.item(i); -// prop.setProperty(attr.getName(), attr.getValue()); -// } -// } -// return prop; -// } - - public String getProperty(String key) { - Iterator it = propertiesElementIter(); - while (it.hasNext()) { - String value = DOMUtils.getAttribute(it.next(), key); - if (value != null) - return value; - } - return null; - } - - private Iterator propertiesElementIter() { - return DOMUtils.childElementIterByTag(implementation, - getPropertiesElementName()); - } - - public void setProperty(String key, String value) { - String oldValue = getProperty(key); - String propEleName = getPropertiesElementName(); - Element p = DOMUtils.ensureChildElement(implementation, propEleName); - DOMUtils.setAttribute(p, key, value); - String newValue = getProperty(key); - firePropertyChange(key, oldValue, newValue); - } - - private String getPropertiesElementName() { - return getType().toLowerCase() + "-" + TAG_PROPERTIES; //$NON-NLS-1$ - } - - public int size() { - Iterator it = propertiesElementIter(); - int size = 0; - while (it.hasNext()) { - size += it.next().getAttributes().getLength(); - } - return size; - } - - public boolean isEmpty() { - Iterator it = propertiesElementIter(); - while (it.hasNext()) { - Element propEle = it.next(); - if (propEle.hasAttributes() || propEle.hasChildNodes()) - return false; - } - return true; - } - - public Iterator properties() { - return new PropertyIter(); - } - - public void setName(String name) { - String oldValue = implementation.hasAttribute(ATTR_NAME) ? getName() - : null; - DOMUtils.setAttribute(implementation, ATTR_NAME, name); - String newValue = implementation.hasAttribute(ATTR_NAME) ? getName() - : null; - fireValueChange(Core.Name, oldValue, newValue); - } - - public Iterator defaultStyles() { - return new DefaultStyleIter(); - } - - public String getDefaultStyleId(String styleFamily) { - if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$ - return null; - Iterator it = propertiesElementIter(); - while (it.hasNext()) { - Iterator it2 = DOMUtils.childElementIterByTag(it.next(), - TAG_DEFAULT_STYLE); - while (it2.hasNext()) { - Element ds = it2.next(); - if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) { - return DOMUtils.getAttribute(ds, ATTR_STYLE_ID); - } - } - } - return null; - } - - public void setDefaultStyleId(String styleFamily, String styleId) { - if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$ - return; - - String propEleName = getPropertiesElementName(); - if (styleId != null) { - Element p = DOMUtils.ensureChildElement(implementation, - propEleName); - Element ds = findDefaultStyleElement(p, styleFamily); - if (ds == null) { - ds = DOMUtils.createElement(p, TAG_DEFAULT_STYLE); - DOMUtils.setAttribute(ds, ATTR_STYLE_FAMILY, styleFamily); - } - DOMUtils.setAttribute(ds, ATTR_STYLE_ID, styleId); - } else { - Element p = DOMUtils.getFirstChildElementByTag(implementation, - propEleName); - if (p != null) { - Element ds = findDefaultStyleElement(p, styleFamily); - if (ds != null) { - Node n = p.removeChild(ds); - if (n != null) { - if (!p.hasChildNodes()) { - implementation.removeChild(p); - } - } - } - } - } - } - - private Element findDefaultStyleElement(Element propEle, - String styleFamily) { - Iterator it = DOMUtils.childElementIterByTag(propEle, - TAG_DEFAULT_STYLE); - while (it.hasNext()) { - Element ds = it.next(); - if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) { - return ds; - } - } - return null; - } - -// public boolean contentEquals(IStyle style) { -// StyleImpl s = (StyleImpl) style; -// if (!getType().equals(s.getType())) -// return false; -// -// int propSize = 0; -// int dsSize = 0; -// -// Iterator it = propertiesElementIter(); -// while (it.hasNext()) { -// Element propEle = it.next(); -// NamedNodeMap attrs = propEle.getAttributes(); -// for (int i = 0; i < attrs.getLength(); i++) { -// Node attr = attrs.item(i); -// String key = attr.getNodeName(); -// String value = attr.getNodeValue(); -// if (!value.equals(s.getProperty(key))) -// return false; -// } -// Iterator dsIt = DOMUtils.childElementIterByTag(propEle, -// TAG_DEFAULT_STYLE); -// while (dsIt.hasNext()) { -// -// } -// } -// -// return true; -// } -// -// public int getParentGroupId() { -// Node p = implementation.getParentNode(); -// if (p != null && p instanceof Element) { -// Element g = (Element) p; -// String name = g.getTagName(); -// if (DOMConstants.TAG_STYLES.equals(name)) -// return IStyleSheet.GROUP_NORMAL; -// if (DOMConstants.TAG_MASTER_STYLES.equals(name)) -// return IStyleSheet.GROUP_MASTER; -// if (DOMConstants.TAG_AUTOMATIC_STYLES.equals(name)) -// return IStyleSheet.GROUP_AUTOMATIC; -// } -// return IStyleSheet.GROUP_NONE; -// } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - private void fireValueChange(String eventType, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, - newValue); - } - - private void firePropertyChange(String key, String oldValue, - String newValue) { - getCoreEventSupport().dispatchTargetValueChange(this, Core.Property, - key, oldValue, newValue); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedSheet.getCoreEventSupport(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_NAME; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_FAMILY; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_DEFAULT_STYLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_PROPERTIES; + +import java.util.Iterator; +import java.util.Properties; + +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Style; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.Property; + +public class StyleImpl extends Style implements ICoreEventSource { + + private final class PropertyIter implements Iterator { + + Iterator it = propertiesElementIter(); + + Element propEle = it.next(); + + NamedNodeMap map = propEle == null ? null : propEle.getAttributes(); + + int index = 0; + + Property next = findNextProperty(); + + private Property findNextProperty() { + if (map != null) { + if (index < map.getLength()) { + Attr attr = (Attr) map.item(index); + index++; + return new Property(attr.getName(), attr.getValue()); + } + if (it.hasNext()) { + propEle = it.next(); + map = propEle == null ? null : propEle.getAttributes(); + index = 0; + if (map != null) { + return findNextProperty(); + } + } + } + return null; + } + + public void remove() { + } + + public Property next() { + if (next == null) + return next; + + Property result = next; + next = findNextProperty(); + return result; + } + + public boolean hasNext() { + return next != null; + } + } + + private final class DefaultStyleIter implements Iterator { + + Iterator propEleIt = propertiesElementIter(); + + Element propEle = null; + + Iterator defaultStyleEleIt = null; + + Property next = findNextDefaultStyle(); + + private Property findNextDefaultStyle() { + if (defaultStyleEleIt != null) { + while (defaultStyleEleIt.hasNext()) { + Element defaultStyleEle = defaultStyleEleIt.next(); + String family = DOMUtils.getAttribute(defaultStyleEle, + ATTR_STYLE_FAMILY); + if (family != null) { + String styleId = DOMUtils.getAttribute(defaultStyleEle, + ATTR_STYLE_ID); + return new Property(family, styleId); + } + } + } + if (propEleIt.hasNext()) { + propEle = propEleIt.next(); + defaultStyleEleIt = DOMUtils.childElementIterByTag(propEle, + TAG_DEFAULT_STYLE); + return findNextDefaultStyle(); + } + return null; + } + + public boolean hasNext() { + return next != null; + } + + public Property next() { + if (next == null) + return next; + + Property result = next; + next = findNextDefaultStyle(); + return result; + } + + public void remove() { + } + + } + + private Element implementation; + + private StyleSheetImpl ownedSheet; + + public StyleImpl(Element implementation, StyleSheetImpl ownedSheet) { + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedSheet = ownedSheet; + } + + public String getId() { + return implementation.getAttribute(DOMConstants.ATTR_ID); + } + + public String getType() { + return implementation.getAttribute(ATTR_TYPE); + } + + public Element getImplementation() { + return implementation; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof StyleImpl)) + return false; + StyleImpl that = (StyleImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "STY#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public IStyleSheet getOwnedStyleSheet() { + return ownedSheet; + } + + public String getName() { + String name = implementation.getAttribute(ATTR_NAME); + if (name.startsWith("%")) { //$NON-NLS-1$ + Properties properties = ownedSheet.getProperties(); + if (properties != null) { + String key = name.substring(1); + name = properties.getProperty(key, name); + } + } + return name; + } + +// public Properties getProperties() { +// Properties prop = new Properties(); +// Iterator it = propertiesElementsIter(); +// while (it.hasNext()) { +// Element propEle = it.next(); +// NamedNodeMap attrs = propEle.getAttributes(); +// for (int i = 0; i < attrs.getLength(); i++) { +// Attr attr = (Attr) attrs.item(i); +// prop.setProperty(attr.getName(), attr.getValue()); +// } +// } +// return prop; +// } + + public String getProperty(String key) { + Iterator it = propertiesElementIter(); + while (it.hasNext()) { + String value = DOMUtils.getAttribute(it.next(), key); + if (value != null) + return value; + } + return null; + } + + private Iterator propertiesElementIter() { + return DOMUtils.childElementIterByTag(implementation, + getPropertiesElementName()); + } + + public void setProperty(String key, String value) { + String oldValue = getProperty(key); + String propEleName = getPropertiesElementName(); + Element p = DOMUtils.ensureChildElement(implementation, propEleName); + DOMUtils.setAttribute(p, key, value); + String newValue = getProperty(key); + firePropertyChange(key, oldValue, newValue); + } + + private String getPropertiesElementName() { + return getType().toLowerCase() + "-" + TAG_PROPERTIES; //$NON-NLS-1$ + } + + public int size() { + Iterator it = propertiesElementIter(); + int size = 0; + while (it.hasNext()) { + size += it.next().getAttributes().getLength(); + } + return size; + } + + public boolean isEmpty() { + Iterator it = propertiesElementIter(); + while (it.hasNext()) { + Element propEle = it.next(); + if (propEle.hasAttributes() || propEle.hasChildNodes()) + return false; + } + return true; + } + + public Iterator properties() { + return new PropertyIter(); + } + + public void setName(String name) { + String oldValue = implementation.hasAttribute(ATTR_NAME) ? getName() + : null; + DOMUtils.setAttribute(implementation, ATTR_NAME, name); + String newValue = implementation.hasAttribute(ATTR_NAME) ? getName() + : null; + fireValueChange(Core.Name, oldValue, newValue); + } + + public Iterator defaultStyles() { + return new DefaultStyleIter(); + } + + public String getDefaultStyleId(String styleFamily) { + if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$ + return null; + Iterator it = propertiesElementIter(); + while (it.hasNext()) { + Iterator it2 = DOMUtils.childElementIterByTag(it.next(), + TAG_DEFAULT_STYLE); + while (it2.hasNext()) { + Element ds = it2.next(); + if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) { + return DOMUtils.getAttribute(ds, ATTR_STYLE_ID); + } + } + } + return null; + } + + public void setDefaultStyleId(String styleFamily, String styleId) { + if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$ + return; + + String propEleName = getPropertiesElementName(); + if (styleId != null) { + Element p = DOMUtils.ensureChildElement(implementation, + propEleName); + Element ds = findDefaultStyleElement(p, styleFamily); + if (ds == null) { + ds = DOMUtils.createElement(p, TAG_DEFAULT_STYLE); + DOMUtils.setAttribute(ds, ATTR_STYLE_FAMILY, styleFamily); + } + DOMUtils.setAttribute(ds, ATTR_STYLE_ID, styleId); + } else { + Element p = DOMUtils.getFirstChildElementByTag(implementation, + propEleName); + if (p != null) { + Element ds = findDefaultStyleElement(p, styleFamily); + if (ds != null) { + Node n = p.removeChild(ds); + if (n != null) { + if (!p.hasChildNodes()) { + implementation.removeChild(p); + } + } + } + } + } + } + + private Element findDefaultStyleElement(Element propEle, + String styleFamily) { + Iterator it = DOMUtils.childElementIterByTag(propEle, + TAG_DEFAULT_STYLE); + while (it.hasNext()) { + Element ds = it.next(); + if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) { + return ds; + } + } + return null; + } + +// public boolean contentEquals(IStyle style) { +// StyleImpl s = (StyleImpl) style; +// if (!getType().equals(s.getType())) +// return false; +// +// int propSize = 0; +// int dsSize = 0; +// +// Iterator it = propertiesElementIter(); +// while (it.hasNext()) { +// Element propEle = it.next(); +// NamedNodeMap attrs = propEle.getAttributes(); +// for (int i = 0; i < attrs.getLength(); i++) { +// Node attr = attrs.item(i); +// String key = attr.getNodeName(); +// String value = attr.getNodeValue(); +// if (!value.equals(s.getProperty(key))) +// return false; +// } +// Iterator dsIt = DOMUtils.childElementIterByTag(propEle, +// TAG_DEFAULT_STYLE); +// while (dsIt.hasNext()) { +// +// } +// } +// +// return true; +// } +// +// public int getParentGroupId() { +// Node p = implementation.getParentNode(); +// if (p != null && p instanceof Element) { +// Element g = (Element) p; +// String name = g.getTagName(); +// if (DOMConstants.TAG_STYLES.equals(name)) +// return IStyleSheet.GROUP_NORMAL; +// if (DOMConstants.TAG_MASTER_STYLES.equals(name)) +// return IStyleSheet.GROUP_MASTER; +// if (DOMConstants.TAG_AUTOMATIC_STYLES.equals(name)) +// return IStyleSheet.GROUP_AUTOMATIC; +// } +// return IStyleSheet.GROUP_NONE; +// } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + private void fireValueChange(String eventType, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, eventType, oldValue, + newValue); + } + + private void firePropertyChange(String key, String oldValue, + String newValue) { + getCoreEventSupport().dispatchTargetValueChange(this, Core.Property, + key, oldValue, newValue); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedSheet.getCoreEventSupport(); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetBuilderImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetBuilderImpl.java index c73e594b4..1d2261be3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetBuilderImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetBuilderImpl.java @@ -1,165 +1,165 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE_SHEET; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.internal.StyleSheetBuilder; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class StyleSheetBuilderImpl extends StyleSheetBuilder - implements ErrorHandler { - - private DocumentBuilder getDocumentCreator() { - DocumentBuilder documentCreator = null; - try { - documentCreator = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new IllegalStateException(e); - } - return documentCreator; - } - - private DocumentBuilder getDocumentLoader() throws CoreException { - DocumentBuilder documentLoader = null; - try { - documentLoader = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); - } - documentLoader.setErrorHandler(this); - return documentLoader; - } - - private Document createDocument() { - return getDocumentCreator().newDocument(); - } - - public IStyleSheet createStyleSheet() { - Document impl = createDocument(); - DOMUtils.createElement(impl, TAG_STYLE_SHEET); - StyleSheetImpl sheet = new StyleSheetImpl(impl); - return sheet; - } - - public IStyleSheet loadFromStream(InputStream stream) - throws IOException, CoreException { - DocumentBuilder loader = getDocumentLoader(); - Document doc = parse(loader, stream); - return createStyleSheet(doc); - } - -// public IStyleSheet loadFromInputSource(IInputSource source, -// IXMLLoader xmlLoader) throws IOException, CoreException { -// Document doc = xmlLoader.loadXMLFile(source, -// ArchiveConstants.STYLES_XML); -// return createStyleSheet(doc); -// } - - protected StyleSheetImpl createStyleSheet(Document doc) { - fixbug(doc); - StyleSheetImpl sheet = new StyleSheetImpl(doc); - init(sheet); - return sheet; - } - - private void init(StyleSheetImpl sheet) { - for (IStyle style : sheet.getAllStyles()) { - init(style); - } -// for (IStyle style : sheet.getMasterStyles()) { -// init(style); -// } -// for (IStyle style : sheet.getNormalStyles()) { -// init(style); -// } - } - - private void init(IStyle style) { - } - - private Document parse(DocumentBuilder loader, InputStream stream) - throws IOException, CoreException { - try { - return loader.parse(stream); - } catch (SAXException e) { - throw new CoreException(Core.ERROR_FAIL_PARSING_XML); - } catch (IOException e) { - throw e; - } - } - - public void loadProperties(InputStream stream, IStyleSheet styleSheet) - throws IOException, CoreException { - Properties p = new Properties(); - p.load(stream); - ((StyleSheetImpl) styleSheet).setProperties(p); - } - - public void error(SAXParseException exception) throws SAXException { - } - - public void fatalError(SAXParseException exception) throws SAXException { - } - - public void warning(SAXParseException exception) throws SAXException { - } - - /** - * This is to fix a bug generated by version 3.0.0. - * - * @param doc - */ - private void fixbug(Document doc) { - Element element = doc.getDocumentElement(); - if (element != null) { - fixbug(element); - } - } - - /** - * This is to fix a bug generated by version 3.0.0. - * - * @param element - */ - private void fixbug(Element element) { - String value = element.getAttribute(DOMConstants.ATTR_SHAPE_CLASS); - if ("org.xmind.topicShape.rectangle".equals(value)) { //$NON-NLS-1$ - element.setAttribute(DOMConstants.ATTR_SHAPE_CLASS, - "org.xmind.topicShape.rect"); //$NON-NLS-1$ - } - Iterator it = DOMUtils.childElementIter(element); - while (it.hasNext()) { - fixbug(it.next()); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE_SHEET; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.internal.StyleSheetBuilder; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class StyleSheetBuilderImpl extends StyleSheetBuilder + implements ErrorHandler { + + private DocumentBuilder getDocumentCreator() { + DocumentBuilder documentCreator = null; + try { + documentCreator = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } + return documentCreator; + } + + private DocumentBuilder getDocumentLoader() throws CoreException { + DocumentBuilder documentLoader = null; + try { + documentLoader = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); + } + documentLoader.setErrorHandler(this); + return documentLoader; + } + + private Document createDocument() { + return getDocumentCreator().newDocument(); + } + + public IStyleSheet createStyleSheet() { + Document impl = createDocument(); + DOMUtils.createElement(impl, TAG_STYLE_SHEET); + StyleSheetImpl sheet = new StyleSheetImpl(impl); + return sheet; + } + + public IStyleSheet loadFromStream(InputStream stream) + throws IOException, CoreException { + DocumentBuilder loader = getDocumentLoader(); + Document doc = parse(loader, stream); + return createStyleSheet(doc); + } + +// public IStyleSheet loadFromInputSource(IInputSource source, +// IXMLLoader xmlLoader) throws IOException, CoreException { +// Document doc = xmlLoader.loadXMLFile(source, +// ArchiveConstants.STYLES_XML); +// return createStyleSheet(doc); +// } + + protected StyleSheetImpl createStyleSheet(Document doc) { + fixbug(doc); + StyleSheetImpl sheet = new StyleSheetImpl(doc); + init(sheet); + return sheet; + } + + private void init(StyleSheetImpl sheet) { + for (IStyle style : sheet.getAllStyles()) { + init(style); + } +// for (IStyle style : sheet.getMasterStyles()) { +// init(style); +// } +// for (IStyle style : sheet.getNormalStyles()) { +// init(style); +// } + } + + private void init(IStyle style) { + } + + private Document parse(DocumentBuilder loader, InputStream stream) + throws IOException, CoreException { + try { + return loader.parse(stream); + } catch (SAXException e) { + throw new CoreException(Core.ERROR_FAIL_PARSING_XML); + } catch (IOException e) { + throw e; + } + } + + public void loadProperties(InputStream stream, IStyleSheet styleSheet) + throws IOException, CoreException { + Properties p = new Properties(); + p.load(stream); + ((StyleSheetImpl) styleSheet).setProperties(p); + } + + public void error(SAXParseException exception) throws SAXException { + } + + public void fatalError(SAXParseException exception) throws SAXException { + } + + public void warning(SAXParseException exception) throws SAXException { + } + + /** + * This is to fix a bug generated by version 3.0.0. + * + * @param doc + */ + private void fixbug(Document doc) { + Element element = doc.getDocumentElement(); + if (element != null) { + fixbug(element); + } + } + + /** + * This is to fix a bug generated by version 3.0.0. + * + * @param element + */ + private void fixbug(Element element) { + String value = element.getAttribute(DOMConstants.ATTR_SHAPE_CLASS); + if ("org.xmind.topicShape.rectangle".equals(value)) { //$NON-NLS-1$ + element.setAttribute(DOMConstants.ATTR_SHAPE_CLASS, + "org.xmind.topicShape.rect"); //$NON-NLS-1$ + } + Iterator it = DOMUtils.childElementIter(element); + while (it.hasNext()) { + fixbug(it.next()); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetImpl.java index b619b3a30..4364300c1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/StyleSheetImpl.java @@ -1,304 +1,304 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_AUTOMATIC_STYLES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MASTER_STYLES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE_SHEET; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Properties; -import java.util.Set; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IManifest; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.ElementRegistry; -import org.xmind.core.internal.StyleSheet; -import org.xmind.core.internal.event.CoreEventSupport; -import org.xmind.core.style.IStyle; -import org.xmind.core.util.CloneHandler; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.IPropertiesProvider; - -public class StyleSheetImpl extends StyleSheet implements INodeAdaptableFactory, - ICoreEventSource, IPropertiesProvider { - - private Document implementation; - - private ElementRegistry elementRegistry = null; - - private NodeAdaptableProvider nodeAdaptableProvider = null; - - private CoreEventSupport coreEventSupport = null; - - private Properties properties = null; - - private IManifest manifest = null; - - public StyleSheetImpl(Document implementation) { - this.implementation = implementation; - init(); - } - - private void init() { - Element s = DOMUtils.ensureChildElement(implementation, - TAG_STYLE_SHEET); - NS.setNS(NS.Style, s, NS.SVG, NS.Fo); - InternalDOMUtils.addVersion(implementation); - } - - public Document getImplementation() { - return implementation; - } - - public T getAdapter(Class adapter) { - if (IManifest.class.equals(adapter)) - return adapter.cast(manifest); - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (ElementRegistry.class.equals(adapter)) - return adapter.cast(getElementRegistry()); - if (ICoreEventSupport.class.equals(adapter)) - return adapter.cast(getCoreEventSupport()); - if (IPropertiesProvider.class.equals(adapter)) - return adapter.cast(this); - if (Properties.class.equals(adapter)) - return adapter.cast(getProperties()); - if (INodeAdaptableFactory.class.equals(adapter)) - return adapter.cast(this); - if (INodeAdaptableProvider.class.equals(adapter)) - return adapter.cast(getNodeAdaptableProvider()); - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - protected Element getSheetElement() { - return implementation.getDocumentElement(); - } - - public boolean isEmpty() { - return !getSheetElement().hasChildNodes(); - } - - @Override - protected IStyle getLocalStyle(String styleId) { - Object element = getElementById(styleId); - return element instanceof IStyle ? (IStyle) element : null; - } - - public IStyle createStyle(String type) { - Element s = implementation.createElement(TAG_STYLE); - s.setAttribute(ATTR_TYPE, type); - StyleImpl style = new StyleImpl(s, this); - getElementRegistry().register(style); - return style; - } - - public Set getStyles(String groupName) { - String groupTag = getGroupTag(groupName); - if (groupTag != null) { - Element ss = DOMUtils.getFirstChildElementByTag(getSheetElement(), - groupTag); - if (ss != null) { - return DOMUtils.getChildSet(ss, TAG_STYLE, - getNodeAdaptableProvider()); - } - } - return NO_STYLES; - } - - public void addStyle(IStyle style, String groupName) { - String groupTag = getGroupTag(groupName); - if (groupTag == null) - return; - - Element s = ((StyleImpl) style).getImplementation(); - Element as = DOMUtils.ensureChildElement(getSheetElement(), groupTag); - Node n = as.appendChild(s); - if (n != null) { - fireTargetChange(Core.StyleAdd, style); - } - } - - public String findOwnedGroup(IStyle style) { - StyleImpl s = (StyleImpl) style; - Node p = s.getImplementation().getParentNode(); - if (p instanceof Element) { - String groupTag = ((Element) p).getTagName(); - return getGroupName(groupTag); - } - return null; - } - - private String getGroupTag(String groupName) { - if (NORMAL_STYLES.equals(groupName)) - return TAG_STYLES; - if (MASTER_STYLES.equals(groupName)) - return TAG_MASTER_STYLES; - if (AUTOMATIC_STYLES.equals(groupName)) - return TAG_AUTOMATIC_STYLES; - return null; - } - - private String getGroupName(String groupTag) { - if (TAG_STYLES.equals(groupTag)) - return NORMAL_STYLES; - if (TAG_MASTER_STYLES.equals(groupTag)) - return MASTER_STYLES; - if (TAG_AUTOMATIC_STYLES.equals(groupTag)) - return AUTOMATIC_STYLES; - return null; - } - - public void removeStyle(IStyle style) { - Element s = ((StyleImpl) style).getImplementation(); - Node p = s.getParentNode(); - if (p instanceof Element) { - Element ss = (Element) p; - Element sheet = getSheetElement(); - if (ss.getParentNode() == sheet) { - Node n = ss.removeChild(s); - if (n != null) { - if (!ss.hasChildNodes()) { - sheet.removeChild(ss); - } - fireTargetChange(Core.StyleRemove, style); - } - } - } - } - - protected Object getElementById(String id) { - Object element = getElementRegistry().getElement(id); - if (element == null) { - Element domElement = implementation.getElementById(id); - if (domElement != null) { - element = getNodeAdaptable(domElement); - } - } - return element; - } - - public ElementRegistry getElementRegistry() { - if (elementRegistry == null) - elementRegistry = new ElementRegistry(); - return elementRegistry; - } - - protected NodeAdaptableProvider getNodeAdaptableProvider() { - if (nodeAdaptableProvider == null) - nodeAdaptableProvider = new NodeAdaptableProvider( - getElementRegistry(), this, implementation); - return nodeAdaptableProvider; - } - - protected IAdaptable getNodeAdaptable(Node node) { - return getNodeAdaptableProvider().getAdaptable(node); - } - - public IAdaptable createAdaptable(Node node) { - if (node instanceof Element) { - Element e = (Element) node; - String tagName = e.getTagName(); - if (TAG_STYLE.equals(tagName)) { - return new StyleImpl(e, this); - } - } - return null; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof StyleSheetImpl)) - return false; - StyleSheetImpl that = (StyleSheetImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return DOMUtils.toString(implementation); - } - - public Properties getProperties() { - return properties; - } - - public void setProperties(Properties properties) { - this.properties = properties; - } - - public IManifest getManifest() { - return manifest; - } - - public void setManifest(IManifest manifest) { - this.manifest = manifest; - } - - public void save(OutputStream out) throws IOException, CoreException { - DOMUtils.save(implementation, out, false); - } - - public IStyle importStyle(IStyle style) { - if (style == null) - return null; - - try { - return (IStyle) new CloneHandler() - .withStyleSheets(style.getOwnedStyleSheet(), this) - .cloneObject(style); - } catch (IOException e) { - Core.getLogger().log(e); - } - return null; - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public CoreEventSupport getCoreEventSupport() { - if (coreEventSupport != null) - return coreEventSupport; - - coreEventSupport = new CoreEventSupport(); - return coreEventSupport; - } - - private void fireTargetChange(String type, Object target) { - getCoreEventSupport().dispatchTargetChange(this, type, target); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_AUTOMATIC_STYLES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MASTER_STYLES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_STYLE_SHEET; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Properties; +import java.util.Set; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IManifest; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.ElementRegistry; +import org.xmind.core.internal.StyleSheet; +import org.xmind.core.internal.event.CoreEventSupport; +import org.xmind.core.style.IStyle; +import org.xmind.core.util.CloneHandler; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.IPropertiesProvider; + +public class StyleSheetImpl extends StyleSheet implements INodeAdaptableFactory, + ICoreEventSource, IPropertiesProvider { + + private Document implementation; + + private ElementRegistry elementRegistry = null; + + private NodeAdaptableProvider nodeAdaptableProvider = null; + + private CoreEventSupport coreEventSupport = null; + + private Properties properties = null; + + private IManifest manifest = null; + + public StyleSheetImpl(Document implementation) { + this.implementation = implementation; + init(); + } + + private void init() { + Element s = DOMUtils.ensureChildElement(implementation, + TAG_STYLE_SHEET); + NS.setNS(NS.Style, s, NS.SVG, NS.Fo); + InternalDOMUtils.addVersion(implementation); + } + + public Document getImplementation() { + return implementation; + } + + public T getAdapter(Class adapter) { + if (IManifest.class.equals(adapter)) + return adapter.cast(manifest); + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (ElementRegistry.class.equals(adapter)) + return adapter.cast(getElementRegistry()); + if (ICoreEventSupport.class.equals(adapter)) + return adapter.cast(getCoreEventSupport()); + if (IPropertiesProvider.class.equals(adapter)) + return adapter.cast(this); + if (Properties.class.equals(adapter)) + return adapter.cast(getProperties()); + if (INodeAdaptableFactory.class.equals(adapter)) + return adapter.cast(this); + if (INodeAdaptableProvider.class.equals(adapter)) + return adapter.cast(getNodeAdaptableProvider()); + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + protected Element getSheetElement() { + return implementation.getDocumentElement(); + } + + public boolean isEmpty() { + return !getSheetElement().hasChildNodes(); + } + + @Override + protected IStyle getLocalStyle(String styleId) { + Object element = getElementById(styleId); + return element instanceof IStyle ? (IStyle) element : null; + } + + public IStyle createStyle(String type) { + Element s = implementation.createElement(TAG_STYLE); + s.setAttribute(ATTR_TYPE, type); + StyleImpl style = new StyleImpl(s, this); + getElementRegistry().register(style); + return style; + } + + public Set getStyles(String groupName) { + String groupTag = getGroupTag(groupName); + if (groupTag != null) { + Element ss = DOMUtils.getFirstChildElementByTag(getSheetElement(), + groupTag); + if (ss != null) { + return DOMUtils.getChildSet(ss, TAG_STYLE, + getNodeAdaptableProvider()); + } + } + return NO_STYLES; + } + + public void addStyle(IStyle style, String groupName) { + String groupTag = getGroupTag(groupName); + if (groupTag == null) + return; + + Element s = ((StyleImpl) style).getImplementation(); + Element as = DOMUtils.ensureChildElement(getSheetElement(), groupTag); + Node n = as.appendChild(s); + if (n != null) { + fireTargetChange(Core.StyleAdd, style); + } + } + + public String findOwnedGroup(IStyle style) { + StyleImpl s = (StyleImpl) style; + Node p = s.getImplementation().getParentNode(); + if (p instanceof Element) { + String groupTag = ((Element) p).getTagName(); + return getGroupName(groupTag); + } + return null; + } + + private String getGroupTag(String groupName) { + if (NORMAL_STYLES.equals(groupName)) + return TAG_STYLES; + if (MASTER_STYLES.equals(groupName)) + return TAG_MASTER_STYLES; + if (AUTOMATIC_STYLES.equals(groupName)) + return TAG_AUTOMATIC_STYLES; + return null; + } + + private String getGroupName(String groupTag) { + if (TAG_STYLES.equals(groupTag)) + return NORMAL_STYLES; + if (TAG_MASTER_STYLES.equals(groupTag)) + return MASTER_STYLES; + if (TAG_AUTOMATIC_STYLES.equals(groupTag)) + return AUTOMATIC_STYLES; + return null; + } + + public void removeStyle(IStyle style) { + Element s = ((StyleImpl) style).getImplementation(); + Node p = s.getParentNode(); + if (p instanceof Element) { + Element ss = (Element) p; + Element sheet = getSheetElement(); + if (ss.getParentNode() == sheet) { + Node n = ss.removeChild(s); + if (n != null) { + if (!ss.hasChildNodes()) { + sheet.removeChild(ss); + } + fireTargetChange(Core.StyleRemove, style); + } + } + } + } + + protected Object getElementById(String id) { + Object element = getElementRegistry().getElement(id); + if (element == null) { + Element domElement = implementation.getElementById(id); + if (domElement != null) { + element = getNodeAdaptable(domElement); + } + } + return element; + } + + public ElementRegistry getElementRegistry() { + if (elementRegistry == null) + elementRegistry = new ElementRegistry(); + return elementRegistry; + } + + protected NodeAdaptableProvider getNodeAdaptableProvider() { + if (nodeAdaptableProvider == null) + nodeAdaptableProvider = new NodeAdaptableProvider( + getElementRegistry(), this, implementation); + return nodeAdaptableProvider; + } + + protected IAdaptable getNodeAdaptable(Node node) { + return getNodeAdaptableProvider().getAdaptable(node); + } + + public IAdaptable createAdaptable(Node node) { + if (node instanceof Element) { + Element e = (Element) node; + String tagName = e.getTagName(); + if (TAG_STYLE.equals(tagName)) { + return new StyleImpl(e, this); + } + } + return null; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof StyleSheetImpl)) + return false; + StyleSheetImpl that = (StyleSheetImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return DOMUtils.toString(implementation); + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public IManifest getManifest() { + return manifest; + } + + public void setManifest(IManifest manifest) { + this.manifest = manifest; + } + + public void save(OutputStream out) throws IOException, CoreException { + DOMUtils.save(implementation, out, false); + } + + public IStyle importStyle(IStyle style) { + if (style == null) + return null; + + try { + return (IStyle) new CloneHandler() + .withStyleSheets(style.getOwnedStyleSheet(), this) + .cloneObject(style); + } catch (IOException e) { + Core.getLogger().log(e); + } + return null; + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public CoreEventSupport getCoreEventSupport() { + if (coreEventSupport != null) + return coreEventSupport; + + coreEventSupport = new CoreEventSupport(); + return coreEventSupport; + } + + private void fireTargetChange(String type, Object target) { + getCoreEventSupport().dispatchTargetChange(this, type, target); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SummaryImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SummaryImpl.java index c96b09ba7..2eca2a939 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SummaryImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/SummaryImpl.java @@ -1,263 +1,263 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RANGE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TOPIC_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARIES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; - -import java.util.Iterator; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Summary; -import org.xmind.core.util.DOMUtils; - -public class SummaryImpl extends Summary implements ICoreEventSource { - - private WorkbookImpl ownedWorkbook; - - private Element implementation; - - public SummaryImpl(Element implementation, WorkbookImpl ownedWorkbook) { - super(); - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedWorkbook = ownedWorkbook; - } - - public Element getImplementation() { - return implementation; - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SummaryImpl)) - return false; - SummaryImpl that = (SummaryImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "SUM#" + getId() + "{" + getTopicId() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - public String getStyleId() { - return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); - } - - public void setStyleId(String styleId) { - String oldValue = getStyleId(); - WorkbookImpl workbook = getRealizedWorkbook(); - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - String newValue = getStyleId(); - fireValueChange(Core.Style, oldValue, newValue); - updateModificationInfo(); - } - - public ISheet getOwnedSheet() { - ITopic parent = getParent(); - return parent == null ? null : parent.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - public ITopic getParent() { - Element t = getParentTopicElement(); - if (t != null) - return (ITopic) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(t); - return null; - } - - private Element getParentTopicElement() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_SUMMARIES)) { - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPIC)) - return (Element) p; - } - return null; - } - - protected ITopic getTopic(int index) { - if (index < 0) - return null; - - Element p = getParentTopicElement(); - if (p == null) - return null; - - Element ts = TopicImpl.findSubtopicsElement(p, ITopic.ATTACHED); - if (ts == null) - return null; - - Iterator it = DOMUtils.childElementIterByTag(ts, TAG_TOPIC); - int i = 0; - while (it.hasNext()) { - Element t = it.next(); - if (i == index) { - return (ITopic) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(t); - } - i++; - } - return null; - } - - public int getEndIndex() { - return InternalDOMUtils - .getEndIndex(DOMUtils.getAttribute(implementation, ATTR_RANGE)); - } - - public int getStartIndex() { - return InternalDOMUtils.getStartIndex( - DOMUtils.getAttribute(implementation, ATTR_RANGE)); - } - - private Integer toIndexValue(int index) { - return index < 0 ? null : Integer.valueOf(index); - } - - public void setEndIndex(int index) { - String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - Integer oldIndexValue = toIndexValue(getEndIndex()); - DOMUtils.setAttribute(implementation, ATTR_RANGE, - InternalDOMUtils.toRangeValue(getStartIndex(), index)); - Integer newIndexValue = toIndexValue(getEndIndex()); - String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - fireValueChange(Core.EndIndex, oldIndexValue, newIndexValue); - fireValueChange(Core.Range, oldValue, newValue); - updateModificationInfo(); - } - - public void setStartIndex(int index) { - String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - Integer oldIndexValue = toIndexValue(getStartIndex()); - DOMUtils.setAttribute(implementation, ATTR_RANGE, - InternalDOMUtils.toRangeValue(index, getEndIndex())); - Integer newIndexValue = toIndexValue(getStartIndex()); - String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); - fireValueChange(Core.StartIndex, oldIndexValue, newIndexValue); - fireValueChange(Core.Range, oldValue, newValue); - updateModificationInfo(); - } - - public ITopic getTopic() { - String topicId = getTopicId(); - return topicId == null ? null : ownedWorkbook.findTopic(topicId); - } - - public String getTopicId() { - return DOMUtils.getAttribute(implementation, ATTR_TOPIC_ID); - } - - public void setTopicId(String topicId) { - String oldValue = getTopicId(); - DOMUtils.setAttribute(implementation, ATTR_TOPIC_ID, topicId); - String newValue = getTopicId(); - fireValueChange(Core.TopicRefId, oldValue, newValue); - updateModificationInfo(); - } - - protected WorkbookImpl getRealizedWorkbook() { - ITopic parent = getParent(); - if (parent instanceof TopicImpl) - return ((TopicImpl) parent).getRealizedWorkbook(); - return null; - } - - protected void addNotify(WorkbookImpl workbook, TopicImpl parent) { - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); - workbook.getAdaptableRegistry().registerById(this, getId(), - getImplementation().getOwnerDocument()); - WorkbookUtilsImpl.increaseStyleRef(workbook, this); - } - - protected void removeNotify(WorkbookImpl workbook, TopicImpl parent) { - WorkbookUtilsImpl.decreaseStyleRef(workbook, this); - workbook.getAdaptableRegistry().unregisterById(this, getId(), - getImplementation().getOwnerDocument()); - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public ICoreEventSupport getCoreEventSupport() { - return ownedWorkbook.getCoreEventSupport(); - } - - private void fireValueChange(String type, Object oldValue, - Object newValue) { - getCoreEventSupport().dispatchValueChange(this, type, oldValue, - newValue); - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, implementation); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, implementation); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - - ITopic parent = getParent(); - if (parent != null) { - ((TopicImpl) parent).updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RANGE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TOPIC_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARIES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; + +import java.util.Iterator; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Summary; +import org.xmind.core.util.DOMUtils; + +public class SummaryImpl extends Summary implements ICoreEventSource { + + private WorkbookImpl ownedWorkbook; + + private Element implementation; + + public SummaryImpl(Element implementation, WorkbookImpl ownedWorkbook) { + super(); + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedWorkbook = ownedWorkbook; + } + + public Element getImplementation() { + return implementation; + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SummaryImpl)) + return false; + SummaryImpl that = (SummaryImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "SUM#" + getId() + "{" + getTopicId() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + public String getStyleId() { + return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); + } + + public void setStyleId(String styleId) { + String oldValue = getStyleId(); + WorkbookImpl workbook = getRealizedWorkbook(); + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + String newValue = getStyleId(); + fireValueChange(Core.Style, oldValue, newValue); + updateModificationInfo(); + } + + public ISheet getOwnedSheet() { + ITopic parent = getParent(); + return parent == null ? null : parent.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + public ITopic getParent() { + Element t = getParentTopicElement(); + if (t != null) + return (ITopic) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(t); + return null; + } + + private Element getParentTopicElement() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_SUMMARIES)) { + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPIC)) + return (Element) p; + } + return null; + } + + protected ITopic getTopic(int index) { + if (index < 0) + return null; + + Element p = getParentTopicElement(); + if (p == null) + return null; + + Element ts = TopicImpl.findSubtopicsElement(p, ITopic.ATTACHED); + if (ts == null) + return null; + + Iterator it = DOMUtils.childElementIterByTag(ts, TAG_TOPIC); + int i = 0; + while (it.hasNext()) { + Element t = it.next(); + if (i == index) { + return (ITopic) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(t); + } + i++; + } + return null; + } + + public int getEndIndex() { + return InternalDOMUtils + .getEndIndex(DOMUtils.getAttribute(implementation, ATTR_RANGE)); + } + + public int getStartIndex() { + return InternalDOMUtils.getStartIndex( + DOMUtils.getAttribute(implementation, ATTR_RANGE)); + } + + private Integer toIndexValue(int index) { + return index < 0 ? null : Integer.valueOf(index); + } + + public void setEndIndex(int index) { + String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + Integer oldIndexValue = toIndexValue(getEndIndex()); + DOMUtils.setAttribute(implementation, ATTR_RANGE, + InternalDOMUtils.toRangeValue(getStartIndex(), index)); + Integer newIndexValue = toIndexValue(getEndIndex()); + String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + fireValueChange(Core.EndIndex, oldIndexValue, newIndexValue); + fireValueChange(Core.Range, oldValue, newValue); + updateModificationInfo(); + } + + public void setStartIndex(int index) { + String oldValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + Integer oldIndexValue = toIndexValue(getStartIndex()); + DOMUtils.setAttribute(implementation, ATTR_RANGE, + InternalDOMUtils.toRangeValue(index, getEndIndex())); + Integer newIndexValue = toIndexValue(getStartIndex()); + String newValue = DOMUtils.getAttribute(implementation, ATTR_RANGE); + fireValueChange(Core.StartIndex, oldIndexValue, newIndexValue); + fireValueChange(Core.Range, oldValue, newValue); + updateModificationInfo(); + } + + public ITopic getTopic() { + String topicId = getTopicId(); + return topicId == null ? null : ownedWorkbook.findTopic(topicId); + } + + public String getTopicId() { + return DOMUtils.getAttribute(implementation, ATTR_TOPIC_ID); + } + + public void setTopicId(String topicId) { + String oldValue = getTopicId(); + DOMUtils.setAttribute(implementation, ATTR_TOPIC_ID, topicId); + String newValue = getTopicId(); + fireValueChange(Core.TopicRefId, oldValue, newValue); + updateModificationInfo(); + } + + protected WorkbookImpl getRealizedWorkbook() { + ITopic parent = getParent(); + if (parent instanceof TopicImpl) + return ((TopicImpl) parent).getRealizedWorkbook(); + return null; + } + + protected void addNotify(WorkbookImpl workbook, TopicImpl parent) { + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); + workbook.getAdaptableRegistry().registerById(this, getId(), + getImplementation().getOwnerDocument()); + WorkbookUtilsImpl.increaseStyleRef(workbook, this); + } + + protected void removeNotify(WorkbookImpl workbook, TopicImpl parent) { + WorkbookUtilsImpl.decreaseStyleRef(workbook, this); + workbook.getAdaptableRegistry().unregisterById(this, getId(), + getImplementation().getOwnerDocument()); + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public ICoreEventSupport getCoreEventSupport() { + return ownedWorkbook.getCoreEventSupport(); + } + + private void fireValueChange(String type, Object oldValue, + Object newValue) { + getCoreEventSupport().dispatchValueChange(this, type, oldValue, + newValue); + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, implementation); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, implementation); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + + ITopic parent = getParent(); + if (parent != null) { + ((TopicImpl) parent).updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TempSaver.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TempSaver.java index a10151d6d..b504a33d6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TempSaver.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TempSaver.java @@ -1,226 +1,226 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -/** - * @author Frank Shaka - */ -public class TempSaver { - -// private class Session { -// IOutputTarget target; -// Set savedEntryPaths = new HashSet(); -// -// void serialize(IAdaptable domAdaptable, String entryPath) { -// -// } -// } -// -// private WorkbookImpl workbook; -// -// private ManifestImpl manifest; -// -// /** -// * @param workbook -// */ -// public TempSaver(WorkbookImpl workbook, ManifestImpl manifest) { -// super(); -// this.workbook = workbook; -// this.manifest = manifest; -// } -// -// /** -// * @return the storage -// */ -// public IStorage getStorage() { -// return manifest.getStorage(); -// } -// -// public IStorage getPrexiedStorage() { -// return manifest.getPrefixedStorage(); -// } -// -// public void save(String oldPassword, String newPassword) -// throws IOException, CoreException { -// String oldPrefix = prefixedStorage.getPrefix(); -// String newPrefix = newPassword == null ? "" //$NON-NLS-1$ -// : ".encrypted/" + digest(newPassword) + "/"; //$NON-NLS-1$ //$NON-NLS-2$ -// -// IOutputTarget target = storage.getOutputTarget(); -// -// IMeta meta = workbook.getMeta(); -// meta.setValue(IMeta.CREATOR_NAME, -// Core.getWorkbookBuilder().getCreatorName()); -// meta.setValue(IMeta.CREATOR_VERSION, -// Core.getWorkbookBuilder().getCreatorVersion()); -// serialize(target, meta, META_XML); -// -// serialize(target, workbook, CONTENT_XML); -// -// IMarkerSheet markerSheet = workbook.getMarkerSheet(); -// if (!markerSheet.isEmpty()) { -// serialize(target, markerSheet, PATH_MARKER_SHEET); -// } -// -// IStyleSheet styleSheet = workbook.getStyleSheet(); -// if (!styleSheet.isEmpty()) { -// serialize(target, styleSheet, STYLES_XML); -// } -// -// ICommentManager commentManager = workbook.getCommentManager(); -// if (!commentManager.isEmpty()) { -// serialize(target, commentManager, COMMENTS_XML); -// } -// -// IRevisionRepository revisionRepository = workbook -// .getRevisionRepository(); -// for (String resourceId : revisionRepository -// .getRegisteredResourceIds()) { -// IRevisionManager manager = revisionRepository -// .getRegisteredRevisionManager(resourceId); -// String path = PATH_REVISIONS + resourceId + "/" //$NON-NLS-1$ -// + REVISIONS_XML; -// serialize(target, manager, path); -// } -// -// IManifest manifest = workbook.getManifest(); -// serialize(target, manifest, MANIFEST_XML); -// -// } -// -//// private void saveStorage(IStorage sourceStorage, IOutputTarget target) -//// throws CoreException, IOException { -//// IInputSource source = storage.getInputSource(); -//// Iterator entries = source.getEntries(); -//// while (entries.hasNext()) { -//// String entryPath = entries.next(); -//// if (entryPath != null && !"".equals(entryPath) //$NON-NLS-1$ -//// && !hasBeenSaved(entryPath)) { -//// saveStorageEntry(source, target, entryPath); -//// markSaved(entryPath); -//// } -//// } -//// } -//// -//// private void clearEncryptionData() { -//// for (IFileEntry entry : workbook.getManifest().getFileEntries()) { -//// entry.deleteEncryptionData(); -//// } -//// } -//// -//// /** -//// * @param source -//// * @param target -//// * @param entryPath -//// */ -//// private void saveStorageEntry(IInputSource source, IOutputTarget target, -//// String entryPath) { -//// try { -//// InputStream in = getInputStream(source, entryPath); -//// if (in != null) { -//// try { -//// long time = source.getEntryTime(entryPath); -//// if (time >= 0) { -//// target.setEntryTime(entryPath, time); -//// } -//// OutputStream out = getOutputStream(target, entryPath); -//// if (out != null) { -//// try { -//// byte[] byteBuffer = new byte[1024]; -//// int numBytes; -//// while ((numBytes = in.read(byteBuffer)) > 0) { -//// out.write(byteBuffer, 0, numBytes); -//// } -//// } finally { -//// out.close(); -//// } -//// } -//// } finally { -//// in.close(); -//// } -//// } -//// } catch (IOException e) { -//// Core.getLogger().log(e); -//// } catch (CoreException e) { -//// Core.getLogger().log(e); -//// } -//// } -//// -//// private InputStream getInputStream(IInputSource source, String entryPath) -//// throws IOException, CoreException { -//// if (source.hasEntry(entryPath)) { -//// return source.getEntryStream(entryPath); -//// } -//// return null; -//// } -// -// private void serialize(IOutputTarget target, IAdaptable domAdapter, -// String entryPath) throws IOException, CoreException { -// OutputStream out = getOutputStream(target, entryPath); -// if (out != null) { -//// try { -// DOMUtils.save(domAdapter, out, true); -//// } finally { -//// markSaved(entryPath); -//// } -// } -// } -// -// private OutputStream getOutputStream(IOutputTarget target, String entryPath) -// throws IOException, CoreException { -//// if (!target.isEntryAvaialble(entryPath)) -//// return null; -//// -//// return target.openEntryStream(entryPath); -// -// OutputStream out = target.openEntryStream(entryPath); -// -// String password = workbook.getPassword(); -// if (password == null) -// return out; -// -// IFileEntry entry = workbook.getManifest().getFileEntry(entryPath); -// if (entry == null) -// return out; -// -// if (ignoresEncryption(entry, entryPath)) -// return out; -// -// IEncryptionData encData = entry.createEncryptionData(); -// return Crypto.creatOutputStream(out, true, encData, password); -// } -// -// private boolean ignoresEncryption(IFileEntry entry, String entryPath) { -// return MANIFEST_XML.equals(entryPath) -// || ((FileEntryImpl) entry).isIgnoreEncryption(); -// } -// -//// private boolean hasBeenSaved(String entryPath) { -//// return savedEntries != null && savedEntries.contains(entryPath); -//// } -//// -//// /** -//// * @param entryPath -//// */ -//// private void markSaved(String entryPath) { -//// if (savedEntries == null) -//// savedEntries = new HashSet(); -//// savedEntries.add(entryPath); -//// } -// -// private static String digest(String str) { -// return UUID.randomUUID().toString(); -// } -// -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +/** + * @author Frank Shaka + */ +public class TempSaver { + +// private class Session { +// IOutputTarget target; +// Set savedEntryPaths = new HashSet(); +// +// void serialize(IAdaptable domAdaptable, String entryPath) { +// +// } +// } +// +// private WorkbookImpl workbook; +// +// private ManifestImpl manifest; +// +// /** +// * @param workbook +// */ +// public TempSaver(WorkbookImpl workbook, ManifestImpl manifest) { +// super(); +// this.workbook = workbook; +// this.manifest = manifest; +// } +// +// /** +// * @return the storage +// */ +// public IStorage getStorage() { +// return manifest.getStorage(); +// } +// +// public IStorage getPrexiedStorage() { +// return manifest.getPrefixedStorage(); +// } +// +// public void save(String oldPassword, String newPassword) +// throws IOException, CoreException { +// String oldPrefix = prefixedStorage.getPrefix(); +// String newPrefix = newPassword == null ? "" //$NON-NLS-1$ +// : ".encrypted/" + digest(newPassword) + "/"; //$NON-NLS-1$ //$NON-NLS-2$ +// +// IOutputTarget target = storage.getOutputTarget(); +// +// IMeta meta = workbook.getMeta(); +// meta.setValue(IMeta.CREATOR_NAME, +// Core.getWorkbookBuilder().getCreatorName()); +// meta.setValue(IMeta.CREATOR_VERSION, +// Core.getWorkbookBuilder().getCreatorVersion()); +// serialize(target, meta, META_XML); +// +// serialize(target, workbook, CONTENT_XML); +// +// IMarkerSheet markerSheet = workbook.getMarkerSheet(); +// if (!markerSheet.isEmpty()) { +// serialize(target, markerSheet, PATH_MARKER_SHEET); +// } +// +// IStyleSheet styleSheet = workbook.getStyleSheet(); +// if (!styleSheet.isEmpty()) { +// serialize(target, styleSheet, STYLES_XML); +// } +// +// ICommentManager commentManager = workbook.getCommentManager(); +// if (!commentManager.isEmpty()) { +// serialize(target, commentManager, COMMENTS_XML); +// } +// +// IRevisionRepository revisionRepository = workbook +// .getRevisionRepository(); +// for (String resourceId : revisionRepository +// .getRegisteredResourceIds()) { +// IRevisionManager manager = revisionRepository +// .getRegisteredRevisionManager(resourceId); +// String path = PATH_REVISIONS + resourceId + "/" //$NON-NLS-1$ +// + REVISIONS_XML; +// serialize(target, manager, path); +// } +// +// IManifest manifest = workbook.getManifest(); +// serialize(target, manifest, MANIFEST_XML); +// +// } +// +//// private void saveStorage(IStorage sourceStorage, IOutputTarget target) +//// throws CoreException, IOException { +//// IInputSource source = storage.getInputSource(); +//// Iterator entries = source.getEntries(); +//// while (entries.hasNext()) { +//// String entryPath = entries.next(); +//// if (entryPath != null && !"".equals(entryPath) //$NON-NLS-1$ +//// && !hasBeenSaved(entryPath)) { +//// saveStorageEntry(source, target, entryPath); +//// markSaved(entryPath); +//// } +//// } +//// } +//// +//// private void clearEncryptionData() { +//// for (IFileEntry entry : workbook.getManifest().getFileEntries()) { +//// entry.deleteEncryptionData(); +//// } +//// } +//// +//// /** +//// * @param source +//// * @param target +//// * @param entryPath +//// */ +//// private void saveStorageEntry(IInputSource source, IOutputTarget target, +//// String entryPath) { +//// try { +//// InputStream in = getInputStream(source, entryPath); +//// if (in != null) { +//// try { +//// long time = source.getEntryTime(entryPath); +//// if (time >= 0) { +//// target.setEntryTime(entryPath, time); +//// } +//// OutputStream out = getOutputStream(target, entryPath); +//// if (out != null) { +//// try { +//// byte[] byteBuffer = new byte[1024]; +//// int numBytes; +//// while ((numBytes = in.read(byteBuffer)) > 0) { +//// out.write(byteBuffer, 0, numBytes); +//// } +//// } finally { +//// out.close(); +//// } +//// } +//// } finally { +//// in.close(); +//// } +//// } +//// } catch (IOException e) { +//// Core.getLogger().log(e); +//// } catch (CoreException e) { +//// Core.getLogger().log(e); +//// } +//// } +//// +//// private InputStream getInputStream(IInputSource source, String entryPath) +//// throws IOException, CoreException { +//// if (source.hasEntry(entryPath)) { +//// return source.getEntryStream(entryPath); +//// } +//// return null; +//// } +// +// private void serialize(IOutputTarget target, IAdaptable domAdapter, +// String entryPath) throws IOException, CoreException { +// OutputStream out = getOutputStream(target, entryPath); +// if (out != null) { +//// try { +// DOMUtils.save(domAdapter, out, true); +//// } finally { +//// markSaved(entryPath); +//// } +// } +// } +// +// private OutputStream getOutputStream(IOutputTarget target, String entryPath) +// throws IOException, CoreException { +//// if (!target.isEntryAvaialble(entryPath)) +//// return null; +//// +//// return target.openEntryStream(entryPath); +// +// OutputStream out = target.openEntryStream(entryPath); +// +// String password = workbook.getPassword(); +// if (password == null) +// return out; +// +// IFileEntry entry = workbook.getManifest().getFileEntry(entryPath); +// if (entry == null) +// return out; +// +// if (ignoresEncryption(entry, entryPath)) +// return out; +// +// IEncryptionData encData = entry.createEncryptionData(); +// return Crypto.creatOutputStream(out, true, encData, password); +// } +// +// private boolean ignoresEncryption(IFileEntry entry, String entryPath) { +// return MANIFEST_XML.equals(entryPath) +// || ((FileEntryImpl) entry).isIgnoreEncryption(); +// } +// +//// private boolean hasBeenSaved(String entryPath) { +//// return savedEntries != null && savedEntries.contains(entryPath); +//// } +//// +//// /** +//// * @param entryPath +//// */ +//// private void markSaved(String entryPath) { +//// if (savedEntries == null) +//// savedEntries = new HashSet(); +//// savedEntries.add(entryPath); +//// } +// +// private static String digest(String str) { +// return UUID.randomUUID().toString(); +// } +// +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TextSpanImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TextSpanImpl.java index 44759f2b4..651cf95d2 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TextSpanImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TextSpanImpl.java @@ -1,92 +1,92 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.Text; -import org.xmind.core.ITextSpan; -import org.xmind.core.util.DOMUtils; - -public class TextSpanImpl extends SpanImplBase implements ITextSpan { - - private Text text; - - private Element ele; - - public TextSpanImpl(Node implementation, HtmlNotesContentImpl owner) { - super(implementation, owner); - if (implementation instanceof Text) { - this.text = (Text) implementation; - this.ele = null; - } else if (implementation instanceof Element) { - this.text = null; - this.ele = (Element) implementation; - } - } - - public void setStyleId(String styleId) { - if (styleId == null) { - if (getImplementation() == text) - return; - - if (text == null) { - text = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() - .createTextNode(getTextContent()); - } - WorkbookUtilsImpl.decreaseStyleRef( - getOwner().getRealizedWorkbook(), this); - Node oldImpl = getImplementation(); - Node p = oldImpl.getParentNode(); - if (p != null) { - p.replaceChild(oldImpl, text); - } - setImplementation(text); - getOwner().updateModifiedTime(); - } else { - if (getImplementation() == ele) { - super.setStyleId(styleId); - } else { - if (ele == null) { - ele = ((WorkbookImpl) getOwnedWorkbook()) - .getImplementation().createElement( - DOMConstants.TAG_SPAN); - ele.setTextContent(getTextContent()); - } - Node oldImpl = getImplementation(); - Node p = oldImpl.getParentNode(); - if (p != null) { - p.replaceChild(ele, oldImpl); - } - setImplementation(ele); - DOMUtils.setAttribute(ele, ATTR_STYLE_ID, styleId); - WorkbookUtilsImpl.increaseStyleRef(getOwner() - .getRealizedWorkbook(), this); - getOwner().updateModifiedTime(); - } - } - } - - public String getTextContent() { - return getImplementation().getTextContent(); - } - - public void setTextContent(String textContent) { - getImplementation().setTextContent(textContent); - getOwner().updateModifiedTime(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.Text; +import org.xmind.core.ITextSpan; +import org.xmind.core.util.DOMUtils; + +public class TextSpanImpl extends SpanImplBase implements ITextSpan { + + private Text text; + + private Element ele; + + public TextSpanImpl(Node implementation, HtmlNotesContentImpl owner) { + super(implementation, owner); + if (implementation instanceof Text) { + this.text = (Text) implementation; + this.ele = null; + } else if (implementation instanceof Element) { + this.text = null; + this.ele = (Element) implementation; + } + } + + public void setStyleId(String styleId) { + if (styleId == null) { + if (getImplementation() == text) + return; + + if (text == null) { + text = ((WorkbookImpl) getOwnedWorkbook()).getImplementation() + .createTextNode(getTextContent()); + } + WorkbookUtilsImpl.decreaseStyleRef( + getOwner().getRealizedWorkbook(), this); + Node oldImpl = getImplementation(); + Node p = oldImpl.getParentNode(); + if (p != null) { + p.replaceChild(oldImpl, text); + } + setImplementation(text); + getOwner().updateModifiedTime(); + } else { + if (getImplementation() == ele) { + super.setStyleId(styleId); + } else { + if (ele == null) { + ele = ((WorkbookImpl) getOwnedWorkbook()) + .getImplementation().createElement( + DOMConstants.TAG_SPAN); + ele.setTextContent(getTextContent()); + } + Node oldImpl = getImplementation(); + Node p = oldImpl.getParentNode(); + if (p != null) { + p.replaceChild(ele, oldImpl); + } + setImplementation(ele); + DOMUtils.setAttribute(ele, ATTR_STYLE_ID, styleId); + WorkbookUtilsImpl.increaseStyleRef(getOwner() + .getRealizedWorkbook(), this); + getOwner().updateModifiedTime(); + } + } + } + + public String getTextContent() { + return getImplementation().getTextContent(); + } + + public void setTextContent(String textContent) { + getImplementation().setTextContent(textContent); + getOwner().updateModifiedTime(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionElementImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionElementImpl.java index 28a14c3f4..488eee01f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionElementImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionElementImpl.java @@ -1,226 +1,226 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.TopicExtensionElement; -import org.xmind.core.util.DOMUtils; - -public class TopicExtensionElementImpl extends TopicExtensionElement { - - private Element implementation; - - private TopicImpl topic; - - private TopicExtensionImpl extension; - - public TopicExtensionElementImpl(Element implementation, TopicImpl topic, - TopicExtensionImpl extension) { - super(); - this.implementation = implementation; - this.topic = topic; - this.extension = extension; - } - - public Element getImplementation() { - return implementation; - } - - public IWorkbook getOwnedWorkbook() { - return topic.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(getImplementation()); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof TopicExtensionElementImpl)) - return false; - TopicExtensionElementImpl that = (TopicExtensionElementImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "{element:" + getName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public String getName() { - return implementation.getTagName(); - } - - public ITopicExtensionElement createChild(String elementName) { - Element childImpl = DOMUtils.createElement(implementation, elementName); - TopicExtensionElementImpl child = new TopicExtensionElementImpl( - childImpl, topic, extension); - registerChild(child); - topic.updateModificationInfo(); - return child; - } - - private void registerChild(TopicExtensionElementImpl child) { - extension.registerElement(child); - } - - private void unregisterChild(TopicExtensionElementImpl child) { - extension.unregisterElement(child); - } - - public void addChild(ITopicExtensionElement child, int index) { - TopicExtensionElementImpl c = (TopicExtensionElementImpl) child; - if (c.getExtension() != this.getExtension() - || c.getTopic() != this.getTopic()) - return; - - ITopicExtensionElement oldParent = c.getParent(); - if (oldParent != null) { - oldParent.deleteChild(child); - } - Element childImpl = c.getImplementation(); - Element[] es = DOMUtils.getChildElements(implementation); - if (index >= 0 && index < es.length) { - implementation.insertBefore(childImpl, es[index]); - } else { - implementation.appendChild(childImpl); - } - registerChild(c); - topic.updateModificationInfo(); - } - - public void deleteChild(ITopicExtensionElement child) { - TopicExtensionElementImpl c = (TopicExtensionElementImpl) child; - Element childImpl = c.getImplementation(); - if (childImpl.getParentNode() == implementation) { - unregisterChild(c); - implementation.removeChild(childImpl); - topic.updateModificationInfo(); - } - } - - public void deleteChildren(String elementName) { - Element[] children; - if (elementName == null) - children = DOMUtils.getChildElements(implementation); - else - children = DOMUtils.getChildElementsByTag(implementation, - elementName); - for (int i = 0; i < children.length; i++) { - implementation.removeChild(children[i]); - } - if (children.length > 0) - topic.updateModificationInfo(); - } - - public void deleteChildren() { - deleteChildren(null); - } - - public Set getAttributeKeys() { - Set keys = new HashSet(); - NamedNodeMap atts = implementation.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) { - Node att = atts.item(i); - String key = att.getNodeName(); - if (key != null && !"".equals(key)) //$NON-NLS-1$ - keys.add(key); - } - return keys; - } - - public String getAttribute(String attrName) { - return DOMUtils.getAttribute(implementation, attrName); - } - - public List getChildren() { - return DOMUtils.getChildList(implementation, null, extension); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.ITopicExtensionElement#getFirstChild(java.lang.String) - */ - public ITopicExtensionElement getFirstChild(String elementName) { - Element childImpl = DOMUtils.getFirstChildElementByTag(implementation, - elementName); - return childImpl == null ? null : extension.getElement(childImpl); - } - - public List getChildren(String elementName) { - return DOMUtils.getChildList(implementation, elementName, extension); - } - - public ITopicExtension getExtension() { - return extension; - } - - public ITopicExtensionElement getParent() { - Node p = implementation.getParentNode(); - if (p == null || !(p instanceof Element)) - return null; - return extension.getElement((Element) p); - } - - public String getTextContent() { - Node c = implementation.getFirstChild(); - if (c != null && c.getNodeType() == Node.TEXT_NODE) - return c.getTextContent(); - return null; - } - - public ITopic getTopic() { - return topic; - } - - public void setAttribute(String attrName, String attrValue) { - DOMUtils.setAttribute(implementation, attrName, attrValue); - topic.updateModificationInfo(); - } - - public void setTextContent(String text) { - Node c = implementation.getFirstChild(); - if (text == null) { - if (c != null) { - implementation.removeChild(c); - topic.updateModificationInfo(); - } - } else { - if (c != null && c.getNodeType() == Node.TEXT_NODE) { - c.setTextContent(text); - } else { - Node t = implementation.getOwnerDocument().createTextNode(text); - implementation.insertBefore(t, c); - } - topic.updateModificationInfo(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.TopicExtensionElement; +import org.xmind.core.util.DOMUtils; + +public class TopicExtensionElementImpl extends TopicExtensionElement { + + private Element implementation; + + private TopicImpl topic; + + private TopicExtensionImpl extension; + + public TopicExtensionElementImpl(Element implementation, TopicImpl topic, + TopicExtensionImpl extension) { + super(); + this.implementation = implementation; + this.topic = topic; + this.extension = extension; + } + + public Element getImplementation() { + return implementation; + } + + public IWorkbook getOwnedWorkbook() { + return topic.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(getImplementation()); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof TopicExtensionElementImpl)) + return false; + TopicExtensionElementImpl that = (TopicExtensionElementImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "{element:" + getName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String getName() { + return implementation.getTagName(); + } + + public ITopicExtensionElement createChild(String elementName) { + Element childImpl = DOMUtils.createElement(implementation, elementName); + TopicExtensionElementImpl child = new TopicExtensionElementImpl( + childImpl, topic, extension); + registerChild(child); + topic.updateModificationInfo(); + return child; + } + + private void registerChild(TopicExtensionElementImpl child) { + extension.registerElement(child); + } + + private void unregisterChild(TopicExtensionElementImpl child) { + extension.unregisterElement(child); + } + + public void addChild(ITopicExtensionElement child, int index) { + TopicExtensionElementImpl c = (TopicExtensionElementImpl) child; + if (c.getExtension() != this.getExtension() + || c.getTopic() != this.getTopic()) + return; + + ITopicExtensionElement oldParent = c.getParent(); + if (oldParent != null) { + oldParent.deleteChild(child); + } + Element childImpl = c.getImplementation(); + Element[] es = DOMUtils.getChildElements(implementation); + if (index >= 0 && index < es.length) { + implementation.insertBefore(childImpl, es[index]); + } else { + implementation.appendChild(childImpl); + } + registerChild(c); + topic.updateModificationInfo(); + } + + public void deleteChild(ITopicExtensionElement child) { + TopicExtensionElementImpl c = (TopicExtensionElementImpl) child; + Element childImpl = c.getImplementation(); + if (childImpl.getParentNode() == implementation) { + unregisterChild(c); + implementation.removeChild(childImpl); + topic.updateModificationInfo(); + } + } + + public void deleteChildren(String elementName) { + Element[] children; + if (elementName == null) + children = DOMUtils.getChildElements(implementation); + else + children = DOMUtils.getChildElementsByTag(implementation, + elementName); + for (int i = 0; i < children.length; i++) { + implementation.removeChild(children[i]); + } + if (children.length > 0) + topic.updateModificationInfo(); + } + + public void deleteChildren() { + deleteChildren(null); + } + + public Set getAttributeKeys() { + Set keys = new HashSet(); + NamedNodeMap atts = implementation.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node att = atts.item(i); + String key = att.getNodeName(); + if (key != null && !"".equals(key)) //$NON-NLS-1$ + keys.add(key); + } + return keys; + } + + public String getAttribute(String attrName) { + return DOMUtils.getAttribute(implementation, attrName); + } + + public List getChildren() { + return DOMUtils.getChildList(implementation, null, extension); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.ITopicExtensionElement#getFirstChild(java.lang.String) + */ + public ITopicExtensionElement getFirstChild(String elementName) { + Element childImpl = DOMUtils.getFirstChildElementByTag(implementation, + elementName); + return childImpl == null ? null : extension.getElement(childImpl); + } + + public List getChildren(String elementName) { + return DOMUtils.getChildList(implementation, elementName, extension); + } + + public ITopicExtension getExtension() { + return extension; + } + + public ITopicExtensionElement getParent() { + Node p = implementation.getParentNode(); + if (p == null || !(p instanceof Element)) + return null; + return extension.getElement((Element) p); + } + + public String getTextContent() { + Node c = implementation.getFirstChild(); + if (c != null && c.getNodeType() == Node.TEXT_NODE) + return c.getTextContent(); + return null; + } + + public ITopic getTopic() { + return topic; + } + + public void setAttribute(String attrName, String attrValue) { + DOMUtils.setAttribute(implementation, attrName, attrValue); + topic.updateModificationInfo(); + } + + public void setTextContent(String text) { + Node c = implementation.getFirstChild(); + if (text == null) { + if (c != null) { + implementation.removeChild(c); + topic.updateModificationInfo(); + } + } else { + if (c != null && c.getNodeType() == Node.TEXT_NODE) { + c.setTextContent(text); + } else { + Node t = implementation.getOwnerDocument().createTextNode(text); + implementation.insertBefore(t, c); + } + topic.updateModificationInfo(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionImpl.java index e9020f44e..1078bb947 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicExtensionImpl.java @@ -1,192 +1,192 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REFS; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; -import org.xmind.core.IResourceRef; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.TopicExtension; -import org.xmind.core.util.DOMUtils; - -public class TopicExtensionImpl extends TopicExtension - implements INodeAdaptableProvider { - - private Element implementation; - - private TopicImpl topic; - - private TopicExtensionElementImpl content; - - private Map eleMap = new HashMap(); - - public TopicExtensionImpl(Element implementation, TopicImpl topic) { - this.implementation = implementation; - this.topic = topic; - } - - public Element getImplementation() { - return implementation; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof TopicExtensionImpl)) - return false; - TopicExtensionImpl that = (TopicExtensionImpl) obj; - return this.implementation == that.implementation; - } - - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "{topic-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - private Element getContentElement() { - return DOMUtils.ensureChildElement(implementation, - DOMConstants.TAG_CONTENT); - } - - public ITopicExtensionElement getContent() { - if (content == null) { - content = new TopicExtensionElementImpl(getContentElement(), topic, - this); - registerElement(content); - } - return content; - } - - public String getProviderName() { - return implementation.getAttribute(DOMConstants.ATTR_PROVIDER); - } - - public ITopic getParent() { - return topic; - } - - public ISheet getOwnedSheet() { - return topic.getOwnedSheet(); - } - - public IWorkbook getOwnedWorkbook() { - return topic.getOwnedWorkbook(); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - private Element getRefsElement() { - return DOMUtils.getFirstChildElementByTag(implementation, - TAG_RESOURCE_REFS); - } - - public void addResourceRef(IResourceRef ref) { - Element refEle = ((ResourceRefImpl) ref).getImplementation(); - Element refsEle = DOMUtils.ensureChildElement(implementation, - TAG_RESOURCE_REFS); - Node n = refsEle.appendChild(refEle); - if (n != null) { - if (!isOrphan()) { - ((ResourceRefImpl) ref).addNotify(topic.getRealizedWorkbook()); - } - //TODO fire resource ref added - topic.updateModificationInfo(); - } - } - - public List getResourceRefs() { - Element refsEle = getRefsElement(); - if (refsEle != null) - return DOMUtils.getChildList(refsEle, DOMConstants.TAG_RESOURCE_REF, - ((WorkbookImpl) topic.getOwnedWorkbook()) - .getAdaptableRegistry()); - return EMPTY_REFS; - } - - public void removeResourceRef(IResourceRef ref) { - Element refsEle = getRefsElement(); - if (refsEle == null) - return; - Element refEle = ((ResourceRefImpl) ref).getImplementation(); - if (refEle.getParentNode() == refsEle) { - ((ResourceRefImpl) ref).removeNotify(topic.getRealizedWorkbook()); - Node n = refsEle.removeChild(refEle); - if (!refsEle.hasChildNodes()) - implementation.removeChild(refsEle); - if (n != null) { - //TODO fire resource ref removed - topic.updateModificationInfo(); - } - } - } - - protected void addNotify(WorkbookImpl workbook) { - for (IResourceRef ref : getResourceRefs()) { - ((ResourceRefImpl) ref).addNotify(workbook); - } - } - - protected void removeNotify(WorkbookImpl workbook) { - for (IResourceRef ref : getResourceRefs()) { - ((ResourceRefImpl) ref).removeNotify(workbook); - } - } - - protected void registerElement(TopicExtensionElementImpl element) { - eleMap.put(element.getImplementation(), element); - } - - protected void unregisterElement(TopicExtensionElementImpl element) { - eleMap.remove(element.getImplementation()); - } - - protected TopicExtensionElementImpl getElement(Element impl) { - if (impl == implementation) - return null; - TopicExtensionElementImpl ele = eleMap.get(impl); - if (ele == null) { - ele = new TopicExtensionElementImpl(impl, topic, this); - registerElement(ele); - } - return ele; - } - - public IAdaptable getAdaptable(Node node) { - if (node instanceof Element) - return getElement((Element) node); - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REFS; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; +import org.xmind.core.IResourceRef; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.TopicExtension; +import org.xmind.core.util.DOMUtils; + +public class TopicExtensionImpl extends TopicExtension + implements INodeAdaptableProvider { + + private Element implementation; + + private TopicImpl topic; + + private TopicExtensionElementImpl content; + + private Map eleMap = new HashMap(); + + public TopicExtensionImpl(Element implementation, TopicImpl topic) { + this.implementation = implementation; + this.topic = topic; + } + + public Element getImplementation() { + return implementation; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof TopicExtensionImpl)) + return false; + TopicExtensionImpl that = (TopicExtensionImpl) obj; + return this.implementation == that.implementation; + } + + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "{topic-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + private Element getContentElement() { + return DOMUtils.ensureChildElement(implementation, + DOMConstants.TAG_CONTENT); + } + + public ITopicExtensionElement getContent() { + if (content == null) { + content = new TopicExtensionElementImpl(getContentElement(), topic, + this); + registerElement(content); + } + return content; + } + + public String getProviderName() { + return implementation.getAttribute(DOMConstants.ATTR_PROVIDER); + } + + public ITopic getParent() { + return topic; + } + + public ISheet getOwnedSheet() { + return topic.getOwnedSheet(); + } + + public IWorkbook getOwnedWorkbook() { + return topic.getOwnedWorkbook(); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + private Element getRefsElement() { + return DOMUtils.getFirstChildElementByTag(implementation, + TAG_RESOURCE_REFS); + } + + public void addResourceRef(IResourceRef ref) { + Element refEle = ((ResourceRefImpl) ref).getImplementation(); + Element refsEle = DOMUtils.ensureChildElement(implementation, + TAG_RESOURCE_REFS); + Node n = refsEle.appendChild(refEle); + if (n != null) { + if (!isOrphan()) { + ((ResourceRefImpl) ref).addNotify(topic.getRealizedWorkbook()); + } + //TODO fire resource ref added + topic.updateModificationInfo(); + } + } + + public List getResourceRefs() { + Element refsEle = getRefsElement(); + if (refsEle != null) + return DOMUtils.getChildList(refsEle, DOMConstants.TAG_RESOURCE_REF, + ((WorkbookImpl) topic.getOwnedWorkbook()) + .getAdaptableRegistry()); + return EMPTY_REFS; + } + + public void removeResourceRef(IResourceRef ref) { + Element refsEle = getRefsElement(); + if (refsEle == null) + return; + Element refEle = ((ResourceRefImpl) ref).getImplementation(); + if (refEle.getParentNode() == refsEle) { + ((ResourceRefImpl) ref).removeNotify(topic.getRealizedWorkbook()); + Node n = refsEle.removeChild(refEle); + if (!refsEle.hasChildNodes()) + implementation.removeChild(refsEle); + if (n != null) { + //TODO fire resource ref removed + topic.updateModificationInfo(); + } + } + } + + protected void addNotify(WorkbookImpl workbook) { + for (IResourceRef ref : getResourceRefs()) { + ((ResourceRefImpl) ref).addNotify(workbook); + } + } + + protected void removeNotify(WorkbookImpl workbook) { + for (IResourceRef ref : getResourceRefs()) { + ((ResourceRefImpl) ref).removeNotify(workbook); + } + } + + protected void registerElement(TopicExtensionElementImpl element) { + eleMap.put(element.getImplementation(), element); + } + + protected void unregisterElement(TopicExtensionElementImpl element) { + eleMap.remove(element.getImplementation()); + } + + protected TopicExtensionElementImpl getElement(Element impl) { + if (impl == implementation) + return null; + TopicExtensionElementImpl ele = eleMap.get(impl); + if (ele == null) { + ele = new TopicExtensionElementImpl(impl, topic, this); + registerElement(ele); + } + return ele; + } + + public IAdaptable getAdaptable(Node node) { + if (node instanceof Element) + return getElement((Element) node); + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicImpl.java index c5e6ae0cd..1100a71c6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicImpl.java @@ -1,1364 +1,1364 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_BRANCH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_HREF; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_MARKER_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STRUCTURE_CLASS; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_X; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_Y; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_CHILDREN; -import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSIONS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_LABEL; -import static org.xmind.core.internal.dom.DOMConstants.TAG_LABELS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REF; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REFS; -import static org.xmind.core.internal.dom.DOMConstants.TAG_POSITION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARIES; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPICS; -import static org.xmind.core.internal.dom.DOMConstants.VAL_FOLDED; -import static org.xmind.core.internal.dom.NumberUtils.safeParseInt; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.IImage; -import org.xmind.core.INotes; -import org.xmind.core.INumbering; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicPath; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Topic; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.ILabelRefCounter; -import org.xmind.core.util.IMarkerRefCounter; -import org.xmind.core.util.Point; - -/** - * @author briansun - */ -public class TopicImpl extends Topic implements ICoreEventSource { - - private Element implementation; - - private WorkbookImpl ownedWorkbook; - - private NotesImpl notes; - - private ImageImpl image; - - private NumberingImpl numbering; - - private Map extensions = new HashMap(); - -// private boolean updatingTimestamp = false; - - /** - * @param implementation - */ - public TopicImpl(Element implementation, WorkbookImpl ownedWorkbook) { - super(); - this.implementation = DOMUtils.addIdAttribute(implementation); - this.ownedWorkbook = ownedWorkbook; -// installTimestampUpdater(implementation); - } - - /** - * @return the implementation - */ - public Element getImplementation() { - return implementation; - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof TopicImpl)) - return false; - TopicImpl that = (TopicImpl) obj; - return this.implementation == that.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - return "TPC#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - public T getAdapter(Class adapter) { - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(implementation); - return super.getAdapter(adapter); - } - - /** - * @see org.xmind.core.ITopic#getId() - */ - public String getId() { - return implementation.getAttribute(ATTR_ID); - } - - /** - * @see org.xmind.core.internal.Topic#getLocalTitleText() - */ - @Override - protected String getLocalTitleText() { - return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); - } - - /** - * @see org.xmind.core.ITitled#setTitleText(java.lang.String) - */ - public void setTitleText(String titleText) { - String oldValue = getLocalTitleText(); - DOMUtils.setText(implementation, TAG_TITLE, titleText); - String newValue = getLocalTitleText(); - fireValueChange(Core.TitleText, oldValue, newValue); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.ITopic#isFolded() - */ - public boolean isFolded() { - String value = DOMUtils.getAttribute(implementation, ATTR_BRANCH); - return value != null && value.contains(VAL_FOLDED); - } - - /** - * @see org.xmind.core.ITopic#setFolded(boolean) - */ - public void setFolded(boolean folded) { - Boolean oldValue = isFolded(); - String value = folded ? VAL_FOLDED : null; - DOMUtils.setAttribute(implementation, ATTR_BRANCH, value); - Boolean newValue = isFolded(); - fireValueChange(Core.TopicFolded, oldValue, newValue); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.style.IStyled#getStyleId() - */ - public String getStyleId() { - return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); - } - - /** - * @see org.xmind.core.style.IStyled#setStyleId(java.lang.String) - */ - public void setStyleId(String styleId) { - String oldValue = getStyleId(); - WorkbookImpl workbook = getRealizedWorkbook(); - decreaseStyleRef(workbook); - DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); - increaseStyleRef(workbook); - String newValue = getStyleId(); - fireValueChange(Core.Style, oldValue, newValue); - updateModificationInfo(); - } - - public boolean hasPosition() { - Element e = DOMUtils.getFirstChildElementByTag(implementation, - TAG_POSITION); - if (e == null) - return false; - return e.hasAttribute(ATTR_X) && e.hasAttribute(ATTR_Y); - } - - /** - * @see org.xmind.core.ITopic#getPosition() - */ - public Point getPosition() { - Element e = DOMUtils.getFirstChildElementByTag(implementation, - TAG_POSITION); - if (e == null) - return null; - String x = DOMUtils.getAttribute(e, ATTR_X); - String y = DOMUtils.getAttribute(e, ATTR_Y); - if (x == null && y == null) - return null; - return new Point(safeParseInt(x, 0), safeParseInt(y, 0)); - } - - /** - * @see org.xmind.core.ITopic#setPosition(int, int) - */ - public void setPosition(int x, int y) { - Point oldValue = getPosition(); - Element e = DOMUtils.ensureChildElement(implementation, TAG_POSITION); - DOMUtils.setAttribute(e, ATTR_X, Integer.toString(x)); - DOMUtils.setAttribute(e, ATTR_Y, Integer.toString(y)); - Point newValue = getPosition(); - fireValueChange(Core.Position, oldValue, newValue); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.internal.Topic#removePosition() - */ - @Override - protected void removePosition() { - Point oldValue = getPosition(); - Element e = DOMUtils.getFirstChildElementByTag(implementation, - TAG_POSITION); - if (e != null) - implementation.removeChild(e); - Point newValue = getPosition(); - fireValueChange(Core.Position, oldValue, newValue); - updateModificationInfo(); - } - - public String getType() { - if (isRoot()) - return ITopic.ROOT; - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { - return getType((Element) p); - } - return null; - } - - public List getChildren(String type) { - if (type == null) - return NO_CHILDREN; - Element ts = findSubtopicsElement(implementation, type); - if (ts != null) - return getChildren(ts); - return NO_CHILDREN; - } - - public boolean hasChildren(String type) { - if (type == null) - return false; - Element ts = findSubtopicsElement(implementation, type); - if (ts != null) - return DOMUtils.hasChildElementByTag(ts, TAG_TOPIC); - return false; - } - - public Iterator getChildrenIterator(String type) { - if (type == null) - return NO_CHILDREN.iterator(); - Element ts = findSubtopicsElement(implementation, type); - if (ts != null) { - return DOMUtils.getChildIterator(ts, TAG_TOPIC, - ownedWorkbook.getAdaptableRegistry(), ITopic.class); - } - return NO_CHILDREN.iterator(); - } - - public Iterator getAllChildrenIterator() { - Element c = DOMUtils.getFirstChildElementByTag(implementation, - TAG_CHILDREN); - if (c == null) - return NO_CHILDREN.iterator(); - - final Iterator tsIter = DOMUtils.childElementIterByTag(c, - TAG_TOPICS); - return new Iterator() { - - Iterator childTopicIter = null; - - ITopic next = findNextChildTopic(); - - private ITopic findNextChildTopic() { - if (childTopicIter == null || !childTopicIter.hasNext()) { - childTopicIter = nextChildTopicIter(); - } - if (childTopicIter == null) - return null; - - return childTopicIter.next(); - } - - private Iterator nextChildTopicIter() { - while (tsIter.hasNext()) { - Element ts = tsIter.next(); - if (ts != null) { - return DOMUtils.getChildIterator(ts, TAG_TOPIC, - ownedWorkbook.getAdaptableRegistry(), - ITopic.class); - } - } - return null; - - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public ITopic next() { - ITopic n = next; - next = findNextChildTopic(); - return n; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - protected static Element findSubtopicsElement(Element topicElement, - String type) { - Element c = DOMUtils.getFirstChildElementByTag(topicElement, - TAG_CHILDREN); - if (c != null) { - return findSubtopicsElementFromChildren(c, type); - } - return null; - } - - private static Element findSubtopicsElementFromChildren(Element c, - String type) { - Iterator it = DOMUtils.childElementIterByTag(c, TAG_TOPICS); - while (it.hasNext()) { - Element ts = it.next(); - if (type.equals(getType(ts))) - return ts; - } - return null; - } - - protected static String getType(Element topicsImpl) { - return DOMUtils.getAttribute(topicsImpl, ATTR_TYPE); - } - - private List getChildren(Element ts) { - return DOMUtils.getChildList(ts, TAG_TOPIC, - ownedWorkbook.getAdaptableRegistry()); - } - - public Set getChildrenTypes() { - Element c = DOMUtils.getFirstChildElementByTag(implementation, - TAG_CHILDREN); - if (c == null) - return NO_TYPES; - - List list = new ArrayList( - c.getChildNodes().getLength()); - Iterator it = DOMUtils.childElementIterByTag(c, TAG_TOPICS); - while (it.hasNext()) { - Element ts = it.next(); - String type = getType(ts); - if (type != null && !list.contains(type)) { - list.add(type); - } - } - return DOMUtils.unmodifiableSet(list); - } - - public void add(ITopic child, int index, String type) { - Element t = ((TopicImpl) child).getImplementation(); - Element c = DOMUtils.ensureChildElement(implementation, TAG_CHILDREN); - Element ts = findSubtopicsElementFromChildren(c, type); - if (ts == null) { - ts = DOMUtils.createElement(c, TAG_TOPICS); - DOMUtils.setAttribute(ts, ATTR_TYPE, type); - } - Node n = null; - Element[] es = DOMUtils.getChildElementsByTag(ts, TAG_TOPIC); - if (index >= 0 && index < es.length) { - n = ts.insertBefore(t, es[index]); - } else { - n = ts.appendChild(t); - } - if (n != null) { - if (!isOrphan()) { - ((TopicImpl) child).addNotify(getRealizedWorkbook(), - getRealizedSheet(), this); - } - fireIndexedTargetChange(Core.TopicAdd, child, child.getIndex(), - type); - updateModificationInfo(); - } - } - - public void add(ITopic child, String type) { - add(child, -1, type); - } - - public void add(ITopic child) { - add(child, -1, ITopic.ATTACHED); - } - - public void remove(ITopic child) { - Element t = ((TopicImpl) child).getImplementation(); - Node p = t.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { - Element ts = (Element) p; - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_CHILDREN)) { - Element c = (Element) p; - p = p.getParentNode(); - if (p == implementation) { - int index = child.getIndex(); - String type = DOMUtils.getAttribute(ts, ATTR_TYPE); - if (!isOrphan()) { - ((TopicImpl) child).removeNotify(getRealizedWorkbook(), - getRealizedSheet(), null); - } - Node n = ts.removeChild(t); - if (!ts.hasChildNodes()) { - c.removeChild(ts); - if (!c.hasChildNodes()) { - implementation.removeChild(c); - } - } - if (n != null) { - fireIndexedTargetChange(Core.TopicRemove, child, index, - type); - updateModificationInfo(); - } - } - } - } - } - - /** - * @see org.xmind.core.ITopic#getParent() - */ - public ITopic getParent() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_CHILDREN)) { - p = p.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPIC)) { - return (ITopic) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(p); - } - } - } - return null; - } - - /** - * @see org.xmind.core.ITopic#isRoot() - */ - public boolean isRoot() { - Node p = implementation.getParentNode(); - return DOMUtils.isElementByTag(p, TAG_SHEET); - } - - /** - * @see org.xmind.core.internal.Topic#getOwnedSheet() - */ - @Override - public ISheet getOwnedSheet() { - Node s = implementation.getParentNode(); - if (DOMUtils.isElementByTag(s, TAG_SHEET)) { - return (ISheet) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(s); - } - return super.getOwnedSheet(); - } - - /** - * @see org.xmind.core.internal.Topic#getOwnedWorkbook() - */ - @Override - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - /** - * @see org.xmind.core.ITopic#getPath() - */ - public ITopicPath getPath() { - return new TopicPathImpl(this); - } - - /** - * @see org.xmind.core.ITopic#getIndex() - */ - public int getIndex() { - Node p = implementation.getParentNode(); - if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { - return DOMUtils.getElementIndex(p, TAG_TOPIC, implementation); - } - return -1; - } - - /** - * @see org.xmind.core.ITopic#getHyperlink() - */ - public String getHyperlink() { - return DOMUtils.getAttribute(implementation, ATTR_HREF); - } - - /** - * @see org.xmind.core.ITopic#setHyperlink(java.lang.String) - */ - public void setHyperlink(String hyperlink) { - String oldValue = getHyperlink(); - WorkbookImpl workbook = getRealizedWorkbook(); - InternalHyperlinkUtils.deactivateHyperlink(workbook, oldValue, this); - DOMUtils.setAttribute(implementation, ATTR_HREF, hyperlink); - InternalHyperlinkUtils.activateHyperlink(workbook, getHyperlink(), - this); - String newValue = getHyperlink(); - fireValueChange(Core.TopicHyperlink, oldValue, newValue); - updateModificationInfo(); - } - - /** - * @see org.xmind.core.ITopic#getNotes() - */ - public INotes getNotes() { - if (notes == null) { - notes = new NotesImpl(implementation, this); - } - return notes; - } - - public INumbering getNumbering() { - if (numbering == null) { - numbering = new NumberingImpl(implementation, this); - } - return numbering; - } - - public void addMarker(String markerId) { - if (markerId == null) - return; - - Element ms = DOMUtils.ensureChildElement(implementation, - TAG_MARKER_REFS); - Element m = getMarkerRefElement(markerId, ms); - if (m != null) - return; - - m = DOMUtils.createElement(ms, TAG_MARKER_REF); - m.setAttribute(ATTR_MARKER_ID, markerId); - WorkbookImpl workbook = getRealizedWorkbook(); - if (workbook != null) { - workbook.getMarkerRefCounter().increaseRef(markerId); - } - fireTargetChange(Core.MarkerRefAdd, markerId); - SheetImpl sheet = getRealizedSheet(); - if (sheet != null) { - sheet.getMarkerRefCounter().increaseRef(markerId); - } - updateModificationInfo(); - } - - public void removeMarker(String markerId) { - if (markerId == null) - return; - - Element ms = getMarkerRefsElement(); - if (ms == null) - return; - - Element m = getMarkerRefElement(markerId, ms); - if (m == null) - return; - - Node n = ms.removeChild(m); - if (!ms.hasChildNodes()) { - implementation.removeChild(ms); - } - if (n != null) { - WorkbookImpl workbook = getRealizedWorkbook(); - if (workbook != null) { - workbook.getMarkerRefCounter().decreaseRef(markerId); - } - fireTargetChange(Core.MarkerRefRemove, markerId); - SheetImpl sheet = getRealizedSheet(); - if (sheet != null) { - sheet.getMarkerRefCounter().decreaseRef(markerId); - } - updateModificationInfo(); - } - } - - public boolean hasMarker(String markerId) { - if (markerId == null) - return false; - - return getMarkerRefElement(markerId) != null; - } - - public IMarkerRef getMarkerRef(String markerId) { - if (markerId == null) - return null; - - Element m = getMarkerRefElement(markerId); - if (m != null) - return (IMarkerRef) ownedWorkbook.getAdaptableRegistry() - .getAdaptable(m); - return null; - } - - public Set getMarkerRefs() { - Element ms = getMarkerRefsElement(); - if (ms == null) - return NO_MARKER_REFS; - return DOMUtils.getChildSet(ms, TAG_MARKER_REF, - ownedWorkbook.getAdaptableRegistry()); - } - - private Element getMarkerRefsElement() { - return DOMUtils.getFirstChildElementByTag(implementation, - TAG_MARKER_REFS); - } - - private Element getMarkerRefElement(String markerId) { - Element ms = getMarkerRefsElement(); - if (ms == null) - return null; - return getMarkerRefElement(markerId, ms); - } - - private Element getMarkerRefElement(String markerId, Element ms) { - Iterator it = DOMUtils.childElementIterByTag(ms, - TAG_MARKER_REF); - while (it.hasNext()) { - Element m = it.next(); - if (markerId.equals(m.getAttribute(ATTR_MARKER_ID))) - return m; - } - return null; - } - - public void addBoundary(IBoundary boundary) { - Element b = ((BoundaryImpl) boundary).getImplementation(); - Element bs = DOMUtils.ensureChildElement(implementation, - TAG_BOUNDARIES); - Node n = bs.appendChild(b); - if (n != null) { - if (!isOrphan()) { - ((BoundaryImpl) boundary).addNotify(getRealizedWorkbook(), - this); - } - fireTargetChange(Core.BoundaryAdd, boundary); - updateModificationInfo(); - } - } - - public void removeBoundary(IBoundary boundary) { - Element bs = DOMUtils.getFirstChildElementByTag(implementation, - TAG_BOUNDARIES); - if (bs == null) - return; - - Element b = ((BoundaryImpl) boundary).getImplementation(); - if (b.getParentNode() == bs) { - ((BoundaryImpl) boundary).removeNotify(getRealizedWorkbook(), this); - Node n = bs.removeChild(b); - if (!bs.hasChildNodes()) - implementation.removeChild(bs); - if (n != null) { - fireTargetChange(Core.BoundaryRemove, boundary); - updateModificationInfo(); - } - } - } - - public Set getBoundaries() { - Element bs = DOMUtils.getFirstChildElementByTag(implementation, - TAG_BOUNDARIES); - if (bs == null) - return NO_BOUNDARIES; - return DOMUtils.getChildSet(bs, TAG_BOUNDARY, - ownedWorkbook.getAdaptableRegistry()); - } - - public void addSummary(ISummary summary) { - Element s = ((SummaryImpl) summary).getImplementation(); - Element ss = DOMUtils.ensureChildElement(implementation, TAG_SUMMARIES); - Node n = ss.appendChild(s); - if (n != null) { - if (!isOrphan()) { - ((SummaryImpl) summary).addNotify(getRealizedWorkbook(), this); - } - fireTargetChange(Core.SummaryAdd, summary); - updateModificationInfo(); - } - } - - public void removeSummary(ISummary summary) { - Element ss = DOMUtils.getFirstChildElementByTag(implementation, - TAG_SUMMARIES); - if (ss == null) - return; - - Element s = ((SummaryImpl) summary).getImplementation(); - if (s.getParentNode() == ss) { - ((SummaryImpl) summary).removeNotify(getRealizedWorkbook(), this); - Node n = ss.removeChild(s); - if (!ss.hasChildNodes()) - implementation.removeChild(ss); - if (n != null) { - fireTargetChange(Core.SummaryRemove, summary); - updateModificationInfo(); - } - } - } - - public Set getSummaries() { - Element ss = DOMUtils.getFirstChildElementByTag(implementation, - TAG_SUMMARIES); - if (ss == null) - return NO_SUMMARIES; - return DOMUtils.getChildSet(ss, TAG_SUMMARY, - ownedWorkbook.getAdaptableRegistry()); - } - - public String getStructureClass() { - return DOMUtils.getAttribute(implementation, ATTR_STRUCTURE_CLASS); - } - - public void setStructureClass(String structureClass) { - String oldValue = getStructureClass(); - DOMUtils.setAttribute(implementation, ATTR_STRUCTURE_CLASS, - structureClass); - String newValue = getStructureClass(); - fireValueChange(Core.StructureClass, oldValue, newValue); - updateModificationInfo(); - } - - public Set getLabels() { - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls != null) { - NodeList c = ls.getChildNodes(); - int num = c.getLength(); - if (num > 0) { - List set = new ArrayList(num); - for (int i = 0; i < num; i++) { - Node n = c.item(i); - if (DOMUtils.isElementByTag(n, TAG_LABEL)) { - set.add(n.getTextContent()); - } - } - return DOMUtils.unmodifiableSet(set); - } - } - return NO_LABELS; - } - - private Element findLabelElement(String label, Element ls) { - NodeList c = ls.getChildNodes(); - for (int i = 0; i < c.getLength(); i++) { - Node n = c.item(i); - if (DOMUtils.isElementByTag(n, TAG_LABEL)) { - String text = n.getTextContent(); - if (label.equals(text)) - return (Element) n; - } - } - return null; - } - - public void addLabel(String label) { - if (label == null) - return; - - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls != null) { - Element existing = findLabelElement(label, ls); - if (existing != null) - return; - } - - Set oldValue = getLabels(); - addLabelElement(ls, label); - Set newValue = getLabels(); - fireValueChange(Core.Labels, oldValue, newValue); - SheetImpl sheet = getRealizedSheet(); - if (sheet != null) { - sheet.getLabelRefCounter().increaseRef(label); - } - updateModificationInfo(); - } - - public void removeLabel(String label) { - if (label == null) - return; - - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls == null) - return; - - Element l = findLabelElement(label, ls); - if (l == null) - return; - - Set oldValue = getLabels(); - Node n = ls.removeChild(l); - if (n != null) { - if (!ls.hasChildNodes()) { - implementation.removeChild(ls); - } - Set newValue = getLabels(); - fireValueChange(Core.Labels, oldValue, newValue); - SheetImpl sheet = getRealizedSheet(); - if (sheet != null) { - sheet.getLabelRefCounter().decreaseRef(label); - } - updateModificationInfo(); - } - } - - public void setLabels(Collection labels) { - Set oldValue = getLabels(); - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls != null) { - implementation.removeChild(ls); - ls = null; - } - if (labels != null && !labels.isEmpty()) { - for (String label : labels) { - if (label != null) { - ls = addLabelElement(ls, label); - } - } - } - Set newValue = getLabels(); - fireValueChange(Core.Labels, oldValue, newValue); - SheetImpl sheet = getRealizedSheet(); - if (sheet != null) { - ILabelRefCounter counter = sheet.getLabelRefCounter(); - List added = new ArrayList(newValue); - added.removeAll(oldValue); - List removed = new ArrayList(oldValue); - removed.removeAll(newValue); - for (String increased : added) { - counter.increaseRef(increased); - } - for (String decreased : removed) { - counter.decreaseRef(decreased); - } - } - updateModificationInfo(); - } - - public void removeAllLabels() { - setLabels(NO_LABELS); - } - - private Element addLabelElement(Element ls, String label) { - if (ls == null) - ls = DOMUtils.createElement(implementation, TAG_LABELS); - Element l = DOMUtils.createElement(ls, TAG_LABEL); - l.setTextContent(label); - return ls; - } - - public IImage getImage() { - if (image == null) { - image = new ImageImpl(implementation, this); - } - return image; - } - - public int getTitleWidth() { - Element t = DOMUtils.getFirstChildElementByTag(implementation, - TAG_TITLE); - return t == null ? UNSPECIFIED - : NumberUtils.safeParseInt(DOMUtils.getAttribute(t, ATTR_WIDTH), - UNSPECIFIED); - } - - public void setTitleWidth(int width) { - Integer oldValue = getTitleWidthValue(); - if (width == UNSPECIFIED) { - Element t = DOMUtils.getFirstChildElementByTag(implementation, - TAG_TITLE); - if (t != null) { - t.removeAttribute(ATTR_WIDTH); - if (!t.hasChildNodes() && !t.hasAttributes()) { - implementation.removeChild(t); - } - } - } else { - Element t = DOMUtils.ensureChildElement(implementation, TAG_TITLE); - t.setAttribute(ATTR_WIDTH, String.valueOf(width)); - } - Integer newValue = getTitleWidthValue(); - fireValueChange(Core.TitleWidth, oldValue, newValue); - updateModificationInfo(); - } - - private Integer getTitleWidthValue() { - int width = getTitleWidth(); - if (width != UNSPECIFIED) - return Integer.valueOf(width); - return null; - } - - private Iterator iterExtensions() { - return iterExtensions(!isOrphan()); - } - - private Iterator iterExtensions( - final boolean realized) { - Element es = DOMUtils.getFirstChildElementByTag(implementation, - TAG_EXTENSIONS); - final Iterator it = es == null ? null - : DOMUtils.childElementIterByTag(es, TAG_EXTENSION); - return new Iterator() { - - TopicExtensionImpl next = findNext(); - - public void remove() { - } - - private TopicExtensionImpl findNext() { - if (it == null) - return null; - while (it.hasNext()) { - Element ele = it.next(); - String providerName = ele.getAttribute(ATTR_PROVIDER); - if (providerName != null && !"".equals(providerName)) { //$NON-NLS-1$ - TopicExtensionImpl ext = extensions.get(providerName); - if (ext == null) { - ext = new TopicExtensionImpl(ele, TopicImpl.this); - extensions.put(providerName, ext); - if (realized) { - ext.addNotify(ownedWorkbook); - } - } - return ext; - } - } - return null; - } - - public TopicExtensionImpl next() { - TopicExtensionImpl n = next; - next = findNext(); - return n; - } - - public boolean hasNext() { - return next != null; - } - }; - } - -// private TopicExtensionImpl getExtension(String providerName, Element extImpl) { -// TopicExtensionImpl ext = extensions.get(providerName); -// if (ext == null) { -// ext = new TopicExtensionImpl(extImpl, this); -// extensions.put(providerName, ext); -// ext.addNotify(getRealizedWorkbook()); -// } -// return ext; -// } - - public List getExtensions() { - List extensions = new ArrayList(); - Iterator it = iterExtensions(); - while (it.hasNext()) { - extensions.add(it.next()); - } - return extensions; - } - - public ITopicExtension getExtension(String providerName) { - Iterator it = iterExtensions(); - while (it.hasNext()) { - TopicExtensionImpl ext = it.next(); - if (providerName.equals(ext.getProviderName())) { - return ext; - } - } - return null; - } - - public ITopicExtension createExtension(String providerName) { - ITopicExtension ext = getExtension(providerName); - if (ext == null) { - Element es = DOMUtils.ensureChildElement(implementation, - TAG_EXTENSIONS); - Element e = DOMUtils.createElement(es, TAG_EXTENSION); - e.setAttribute(ATTR_PROVIDER, providerName); - ext = new TopicExtensionImpl(e, this); - extensions.put(providerName, (TopicExtensionImpl) ext); - if (!isOrphan()) { - ((TopicExtensionImpl) ext).addNotify(ownedWorkbook); - } - updateModificationInfo(); - } - return ext; -// Element e = findExtensionElement(es, providerName); -// if (e == null) { -// } -// return getExtension(providerName, e); - } - - private Element findExtensionElement(Element es, String providerName) { - Iterator it = DOMUtils.childElementIterByTag(es, - TAG_EXTENSION); - while (it.hasNext()) { - Element e = it.next(); - if (providerName.equals(e.getAttribute(ATTR_PROVIDER))) { - return e; - } - } - return null; - } - - public void deleteExtension(String providerName) { - Element es = DOMUtils.getFirstChildElementByTag(implementation, - TAG_EXTENSIONS); - if (es != null) { - Element e = findExtensionElement(es, providerName); - if (e != null) { - es.removeChild(e); - if (!es.hasChildNodes()) - implementation.removeChild(es); - updateModificationInfo(); - } - } - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - protected void fireValueChange(String type, Object oldValue, - Object newValue) { - ICoreEventSupport coreEventSupport = getCoreEventSupport(); - if (coreEventSupport != null) { - coreEventSupport.dispatchValueChange(this, type, oldValue, - newValue); - } - } - - protected void fireIndexedTargetChange(String type, Object target, - int index, Object data) { - ICoreEventSupport coreEventSupport = getCoreEventSupport(); - if (coreEventSupport != null) { - CoreEvent event = new CoreEvent(this, type, target, index); - event.setData(data); - coreEventSupport.dispatch(this, event); - } - } - - protected void fireTargetChange(String type, Object target) { - ICoreEventSupport coreEventSupport = getCoreEventSupport(); - if (coreEventSupport != null) { - coreEventSupport.dispatchTargetChange(this, type, target); - } - } - - public ICoreEventSupport getCoreEventSupport() { - // Use workbook's core event support directly, so that - // orphan components can have events broadcasted, which - // will enable transient actions (such as dragging topics - // or adjusting relationship control points, etc.) to - // perform correctly. - return ownedWorkbook.getCoreEventSupport(); - } - - protected WorkbookImpl getRealizedWorkbook() { - if (getPath().getWorkbook() == ownedWorkbook) - return ownedWorkbook; - return null; - } - - protected SheetImpl getRealizedSheet() { - ISheet sheet = getOwnedSheet(); - if (sheet != null && sheet instanceof SheetImpl) - return (SheetImpl) sheet; - return null; - } - - protected void addNotify(WorkbookImpl workbook, SheetImpl sheet, - TopicImpl parent) { - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); - workbook.getAdaptableRegistry().registerById(this, getId(), - getImplementation().getOwnerDocument()); - increaseLabelRefs(sheet); - increaseMarkerRefs(workbook, sheet); - increaseStyleRef(workbook); - activateHyperlinks(workbook); - ((NotesImpl) getNotes()).addNotify(workbook); - for (ITopic t : getAllChildren()) { - ((TopicImpl) t).addNotify(workbook, sheet, this); - } - for (IBoundary b : getBoundaries()) { - ((BoundaryImpl) b).addNotify(workbook, this); - } - for (ISummary s : getSummaries()) { - ((SummaryImpl) s).addNotify(workbook, this); - } - extensionsAddNotify(workbook); - - boolean isRevising = (workbook.getAdaptableRegistry() - .getAdaptableByNode(sheet.getImplementation()) != sheet); - if (!isRevising) { - ((CommentManagerImpl) workbook.getCommentManager()) - .objectAddNotify(getId(), this); - } - } - - protected void removeNotify(WorkbookImpl workbook, SheetImpl sheet, - TopicImpl parent) { - boolean isRevising = (workbook.getAdaptableRegistry() - .getAdaptableByNode(sheet.getImplementation()) != sheet); - if (!isRevising) { - ((CommentManagerImpl) workbook.getCommentManager()) - .objectRemoveNotify(getId(), this); - } - - extensionsRemoveNotify(workbook); - for (ISummary s : getSummaries()) { - ((SummaryImpl) s).removeNotify(workbook, this); - } - for (IBoundary b : getBoundaries()) { - ((BoundaryImpl) b).removeNotify(workbook, this); - } - for (ITopic t : getAllChildren()) { - ((TopicImpl) t).removeNotify(workbook, sheet, this); - } - ((NotesImpl) getNotes()).removeNotify(workbook); - deactivateHyperlinks(workbook); - decreaseStyleRef(workbook); - decreaseMarkerRefs(workbook, sheet); - decreaseLabelRefs(sheet); - workbook.getAdaptableRegistry().unregisterById(this, getId(), - getImplementation().getOwnerDocument()); - getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); - } - - private void extensionsAddNotify(WorkbookImpl workbook) { - Iterator it = iterExtensions(false); - while (it.hasNext()) { - it.next().addNotify(workbook); - } -// Element es = getFirstChildElementByTag(implementation, TAG_EXTENSIONS); -// if (es != null) { -// Iterator it = childElementIterByTag(es, TAG_EXTENSION); -// while (it.hasNext()) { -// Element e = it.next(); -// String providerName = getAttribute(e, ATTR_PROVIDER); -// if (providerName != null) { -// TopicExtensionImpl ext = extensions.get(providerName); -// if (ext == null) { -// ext = new TopicExtensionImpl(e, this); -// extensions.put(providerName, ext); -// } -// ext.addNotify(workbook); -// } -// } -// } - } - - private void extensionsRemoveNotify(WorkbookImpl workbook) { - Iterator it = iterExtensions(true); - while (it.hasNext()) { - it.next().removeNotify(workbook); - } -// Element es = DOMUtils.getFirstChildElementByTag(implementation, -// TAG_EXTENSIONS); -// if (es != null) { -// Iterator it = DOMUtils.childElementIterByTag(es, -// TAG_EXTENSION); -// while (it.hasNext()) { -// Element e = it.next(); -// String providerName = DOMUtils.getAttribute(e, ATTR_PROVIDER); -// if (providerName != null) { -// TopicExtensionImpl ext = getExtension(providerName, e); -// ext.removeNotify(workbook); -// } -// } -// } - } - - protected void increaseStyleRef(WorkbookImpl workbook) { - if (workbook == null) - return; - String styleId = getStyleId(); - if (styleId != null) { - workbook.getStyleRefCounter().increaseRef(styleId); - } - } - - protected void decreaseStyleRef(WorkbookImpl workbook) { - if (workbook == null) - return; - String styleId = getStyleId(); - if (styleId != null) { - workbook.getStyleRefCounter().decreaseRef(styleId); - } - } - - protected void increaseMarkerRefs(WorkbookImpl workbook, SheetImpl sheet) { - IMarkerRefCounter counter = sheet == null ? null - : sheet.getMarkerRefCounter(); - if (workbook == null && counter == null) - return; - - Element mrs = getMarkerRefsElement(); - if (mrs == null) - return; - - Iterator it = DOMUtils.childElementIterByTag(mrs, - TAG_MARKER_REF); - while (it.hasNext()) { - String markerId = DOMUtils.getAttribute(it.next(), ATTR_MARKER_ID); - if (markerId != null) { - if (workbook != null) - workbook.getMarkerRefCounter().increaseRef(markerId); - if (counter != null) - counter.increaseRef(markerId); - } - } - } - - protected void decreaseMarkerRefs(WorkbookImpl workbook, SheetImpl sheet) { - IMarkerRefCounter counter = sheet == null ? null - : sheet.getMarkerRefCounter(); - if (workbook == null && counter == null) - return; - - Element mrs = getMarkerRefsElement(); - if (mrs == null) - return; - - Iterator it = DOMUtils.childElementIterByTag(mrs, - TAG_MARKER_REF); - while (it.hasNext()) { - String markerId = DOMUtils.getAttribute(it.next(), ATTR_MARKER_ID); - if (markerId != null) { - if (workbook != null) - workbook.getMarkerRefCounter().decreaseRef(markerId); - if (counter != null) { - counter.decreaseRef(markerId); - } - } - } - } - - private void increaseLabelRefs(SheetImpl sheet) { - if (sheet == null) - return; - - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls == null) - return; - - ILabelRefCounter counter = sheet.getLabelRefCounter(); - Iterator it = DOMUtils.childElementIterByTag(ls, TAG_LABEL); - while (it.hasNext()) { - String label = it.next().getTextContent(); - counter.increaseRef(label); - } - } - - private void decreaseLabelRefs(SheetImpl sheet) { - if (sheet == null) - return; - - Element ls = DOMUtils.getFirstChildElementByTag(implementation, - TAG_LABELS); - if (ls == null) - return; - - ILabelRefCounter counter = sheet.getLabelRefCounter(); - Iterator it = DOMUtils.childElementIterByTag(ls, TAG_LABEL); - while (it.hasNext()) { - String label = it.next().getTextContent(); - counter.decreaseRef(label); - } - } - - protected void activateHyperlinks(WorkbookImpl workbook) { - InternalHyperlinkUtils.activateHyperlink(workbook, getHyperlink(), - this); - ((ImageImpl) getImage()).activateHyperlink(workbook); - } - - protected void deactivateHyperlinks(WorkbookImpl workbook) { - ((ImageImpl) getImage()).deactivateHyperlink(workbook); - InternalHyperlinkUtils.deactivateHyperlink(workbook, getHyperlink(), - this); - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, implementation); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, implementation); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - - ISheet sheet = getOwnedSheet(); - if (sheet != null) { - ((SheetImpl) sheet).updateModificationInfo(); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_BRANCH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_HREF; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_MARKER_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STRUCTURE_CLASS; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_WIDTH; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_X; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_Y; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARIES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_CHILDREN; +import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSIONS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_LABEL; +import static org.xmind.core.internal.dom.DOMConstants.TAG_LABELS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REF; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REFS; +import static org.xmind.core.internal.dom.DOMConstants.TAG_POSITION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARIES; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPICS; +import static org.xmind.core.internal.dom.DOMConstants.VAL_FOLDED; +import static org.xmind.core.internal.dom.NumberUtils.safeParseInt; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.IImage; +import org.xmind.core.INotes; +import org.xmind.core.INumbering; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicPath; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Topic; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.ILabelRefCounter; +import org.xmind.core.util.IMarkerRefCounter; +import org.xmind.core.util.Point; + +/** + * @author briansun + */ +public class TopicImpl extends Topic implements ICoreEventSource { + + private Element implementation; + + private WorkbookImpl ownedWorkbook; + + private NotesImpl notes; + + private ImageImpl image; + + private NumberingImpl numbering; + + private Map extensions = new HashMap(); + +// private boolean updatingTimestamp = false; + + /** + * @param implementation + */ + public TopicImpl(Element implementation, WorkbookImpl ownedWorkbook) { + super(); + this.implementation = DOMUtils.addIdAttribute(implementation); + this.ownedWorkbook = ownedWorkbook; +// installTimestampUpdater(implementation); + } + + /** + * @return the implementation + */ + public Element getImplementation() { + return implementation; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof TopicImpl)) + return false; + TopicImpl that = (TopicImpl) obj; + return this.implementation == that.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + return "TPC#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); + return super.getAdapter(adapter); + } + + /** + * @see org.xmind.core.ITopic#getId() + */ + public String getId() { + return implementation.getAttribute(ATTR_ID); + } + + /** + * @see org.xmind.core.internal.Topic#getLocalTitleText() + */ + @Override + protected String getLocalTitleText() { + return DOMUtils.getTextContentByTag(implementation, TAG_TITLE); + } + + /** + * @see org.xmind.core.ITitled#setTitleText(java.lang.String) + */ + public void setTitleText(String titleText) { + String oldValue = getLocalTitleText(); + DOMUtils.setText(implementation, TAG_TITLE, titleText); + String newValue = getLocalTitleText(); + fireValueChange(Core.TitleText, oldValue, newValue); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.ITopic#isFolded() + */ + public boolean isFolded() { + String value = DOMUtils.getAttribute(implementation, ATTR_BRANCH); + return value != null && value.contains(VAL_FOLDED); + } + + /** + * @see org.xmind.core.ITopic#setFolded(boolean) + */ + public void setFolded(boolean folded) { + Boolean oldValue = isFolded(); + String value = folded ? VAL_FOLDED : null; + DOMUtils.setAttribute(implementation, ATTR_BRANCH, value); + Boolean newValue = isFolded(); + fireValueChange(Core.TopicFolded, oldValue, newValue); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.style.IStyled#getStyleId() + */ + public String getStyleId() { + return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID); + } + + /** + * @see org.xmind.core.style.IStyled#setStyleId(java.lang.String) + */ + public void setStyleId(String styleId) { + String oldValue = getStyleId(); + WorkbookImpl workbook = getRealizedWorkbook(); + decreaseStyleRef(workbook); + DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId); + increaseStyleRef(workbook); + String newValue = getStyleId(); + fireValueChange(Core.Style, oldValue, newValue); + updateModificationInfo(); + } + + public boolean hasPosition() { + Element e = DOMUtils.getFirstChildElementByTag(implementation, + TAG_POSITION); + if (e == null) + return false; + return e.hasAttribute(ATTR_X) && e.hasAttribute(ATTR_Y); + } + + /** + * @see org.xmind.core.ITopic#getPosition() + */ + public Point getPosition() { + Element e = DOMUtils.getFirstChildElementByTag(implementation, + TAG_POSITION); + if (e == null) + return null; + String x = DOMUtils.getAttribute(e, ATTR_X); + String y = DOMUtils.getAttribute(e, ATTR_Y); + if (x == null && y == null) + return null; + return new Point(safeParseInt(x, 0), safeParseInt(y, 0)); + } + + /** + * @see org.xmind.core.ITopic#setPosition(int, int) + */ + public void setPosition(int x, int y) { + Point oldValue = getPosition(); + Element e = DOMUtils.ensureChildElement(implementation, TAG_POSITION); + DOMUtils.setAttribute(e, ATTR_X, Integer.toString(x)); + DOMUtils.setAttribute(e, ATTR_Y, Integer.toString(y)); + Point newValue = getPosition(); + fireValueChange(Core.Position, oldValue, newValue); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.internal.Topic#removePosition() + */ + @Override + protected void removePosition() { + Point oldValue = getPosition(); + Element e = DOMUtils.getFirstChildElementByTag(implementation, + TAG_POSITION); + if (e != null) + implementation.removeChild(e); + Point newValue = getPosition(); + fireValueChange(Core.Position, oldValue, newValue); + updateModificationInfo(); + } + + public String getType() { + if (isRoot()) + return ITopic.ROOT; + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { + return getType((Element) p); + } + return null; + } + + public List getChildren(String type) { + if (type == null) + return NO_CHILDREN; + Element ts = findSubtopicsElement(implementation, type); + if (ts != null) + return getChildren(ts); + return NO_CHILDREN; + } + + public boolean hasChildren(String type) { + if (type == null) + return false; + Element ts = findSubtopicsElement(implementation, type); + if (ts != null) + return DOMUtils.hasChildElementByTag(ts, TAG_TOPIC); + return false; + } + + public Iterator getChildrenIterator(String type) { + if (type == null) + return NO_CHILDREN.iterator(); + Element ts = findSubtopicsElement(implementation, type); + if (ts != null) { + return DOMUtils.getChildIterator(ts, TAG_TOPIC, + ownedWorkbook.getAdaptableRegistry(), ITopic.class); + } + return NO_CHILDREN.iterator(); + } + + public Iterator getAllChildrenIterator() { + Element c = DOMUtils.getFirstChildElementByTag(implementation, + TAG_CHILDREN); + if (c == null) + return NO_CHILDREN.iterator(); + + final Iterator tsIter = DOMUtils.childElementIterByTag(c, + TAG_TOPICS); + return new Iterator() { + + Iterator childTopicIter = null; + + ITopic next = findNextChildTopic(); + + private ITopic findNextChildTopic() { + if (childTopicIter == null || !childTopicIter.hasNext()) { + childTopicIter = nextChildTopicIter(); + } + if (childTopicIter == null) + return null; + + return childTopicIter.next(); + } + + private Iterator nextChildTopicIter() { + while (tsIter.hasNext()) { + Element ts = tsIter.next(); + if (ts != null) { + return DOMUtils.getChildIterator(ts, TAG_TOPIC, + ownedWorkbook.getAdaptableRegistry(), + ITopic.class); + } + } + return null; + + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public ITopic next() { + ITopic n = next; + next = findNextChildTopic(); + return n; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + protected static Element findSubtopicsElement(Element topicElement, + String type) { + Element c = DOMUtils.getFirstChildElementByTag(topicElement, + TAG_CHILDREN); + if (c != null) { + return findSubtopicsElementFromChildren(c, type); + } + return null; + } + + private static Element findSubtopicsElementFromChildren(Element c, + String type) { + Iterator it = DOMUtils.childElementIterByTag(c, TAG_TOPICS); + while (it.hasNext()) { + Element ts = it.next(); + if (type.equals(getType(ts))) + return ts; + } + return null; + } + + protected static String getType(Element topicsImpl) { + return DOMUtils.getAttribute(topicsImpl, ATTR_TYPE); + } + + private List getChildren(Element ts) { + return DOMUtils.getChildList(ts, TAG_TOPIC, + ownedWorkbook.getAdaptableRegistry()); + } + + public Set getChildrenTypes() { + Element c = DOMUtils.getFirstChildElementByTag(implementation, + TAG_CHILDREN); + if (c == null) + return NO_TYPES; + + List list = new ArrayList( + c.getChildNodes().getLength()); + Iterator it = DOMUtils.childElementIterByTag(c, TAG_TOPICS); + while (it.hasNext()) { + Element ts = it.next(); + String type = getType(ts); + if (type != null && !list.contains(type)) { + list.add(type); + } + } + return DOMUtils.unmodifiableSet(list); + } + + public void add(ITopic child, int index, String type) { + Element t = ((TopicImpl) child).getImplementation(); + Element c = DOMUtils.ensureChildElement(implementation, TAG_CHILDREN); + Element ts = findSubtopicsElementFromChildren(c, type); + if (ts == null) { + ts = DOMUtils.createElement(c, TAG_TOPICS); + DOMUtils.setAttribute(ts, ATTR_TYPE, type); + } + Node n = null; + Element[] es = DOMUtils.getChildElementsByTag(ts, TAG_TOPIC); + if (index >= 0 && index < es.length) { + n = ts.insertBefore(t, es[index]); + } else { + n = ts.appendChild(t); + } + if (n != null) { + if (!isOrphan()) { + ((TopicImpl) child).addNotify(getRealizedWorkbook(), + getRealizedSheet(), this); + } + fireIndexedTargetChange(Core.TopicAdd, child, child.getIndex(), + type); + updateModificationInfo(); + } + } + + public void add(ITopic child, String type) { + add(child, -1, type); + } + + public void add(ITopic child) { + add(child, -1, ITopic.ATTACHED); + } + + public void remove(ITopic child) { + Element t = ((TopicImpl) child).getImplementation(); + Node p = t.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { + Element ts = (Element) p; + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_CHILDREN)) { + Element c = (Element) p; + p = p.getParentNode(); + if (p == implementation) { + int index = child.getIndex(); + String type = DOMUtils.getAttribute(ts, ATTR_TYPE); + if (!isOrphan()) { + ((TopicImpl) child).removeNotify(getRealizedWorkbook(), + getRealizedSheet(), null); + } + Node n = ts.removeChild(t); + if (!ts.hasChildNodes()) { + c.removeChild(ts); + if (!c.hasChildNodes()) { + implementation.removeChild(c); + } + } + if (n != null) { + fireIndexedTargetChange(Core.TopicRemove, child, index, + type); + updateModificationInfo(); + } + } + } + } + } + + /** + * @see org.xmind.core.ITopic#getParent() + */ + public ITopic getParent() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_CHILDREN)) { + p = p.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPIC)) { + return (ITopic) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(p); + } + } + } + return null; + } + + /** + * @see org.xmind.core.ITopic#isRoot() + */ + public boolean isRoot() { + Node p = implementation.getParentNode(); + return DOMUtils.isElementByTag(p, TAG_SHEET); + } + + /** + * @see org.xmind.core.internal.Topic#getOwnedSheet() + */ + @Override + public ISheet getOwnedSheet() { + Node s = implementation.getParentNode(); + if (DOMUtils.isElementByTag(s, TAG_SHEET)) { + return (ISheet) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(s); + } + return super.getOwnedSheet(); + } + + /** + * @see org.xmind.core.internal.Topic#getOwnedWorkbook() + */ + @Override + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + /** + * @see org.xmind.core.ITopic#getPath() + */ + public ITopicPath getPath() { + return new TopicPathImpl(this); + } + + /** + * @see org.xmind.core.ITopic#getIndex() + */ + public int getIndex() { + Node p = implementation.getParentNode(); + if (DOMUtils.isElementByTag(p, TAG_TOPICS)) { + return DOMUtils.getElementIndex(p, TAG_TOPIC, implementation); + } + return -1; + } + + /** + * @see org.xmind.core.ITopic#getHyperlink() + */ + public String getHyperlink() { + return DOMUtils.getAttribute(implementation, ATTR_HREF); + } + + /** + * @see org.xmind.core.ITopic#setHyperlink(java.lang.String) + */ + public void setHyperlink(String hyperlink) { + String oldValue = getHyperlink(); + WorkbookImpl workbook = getRealizedWorkbook(); + InternalHyperlinkUtils.deactivateHyperlink(workbook, oldValue, this); + DOMUtils.setAttribute(implementation, ATTR_HREF, hyperlink); + InternalHyperlinkUtils.activateHyperlink(workbook, getHyperlink(), + this); + String newValue = getHyperlink(); + fireValueChange(Core.TopicHyperlink, oldValue, newValue); + updateModificationInfo(); + } + + /** + * @see org.xmind.core.ITopic#getNotes() + */ + public INotes getNotes() { + if (notes == null) { + notes = new NotesImpl(implementation, this); + } + return notes; + } + + public INumbering getNumbering() { + if (numbering == null) { + numbering = new NumberingImpl(implementation, this); + } + return numbering; + } + + public void addMarker(String markerId) { + if (markerId == null) + return; + + Element ms = DOMUtils.ensureChildElement(implementation, + TAG_MARKER_REFS); + Element m = getMarkerRefElement(markerId, ms); + if (m != null) + return; + + m = DOMUtils.createElement(ms, TAG_MARKER_REF); + m.setAttribute(ATTR_MARKER_ID, markerId); + WorkbookImpl workbook = getRealizedWorkbook(); + if (workbook != null) { + workbook.getMarkerRefCounter().increaseRef(markerId); + } + fireTargetChange(Core.MarkerRefAdd, markerId); + SheetImpl sheet = getRealizedSheet(); + if (sheet != null) { + sheet.getMarkerRefCounter().increaseRef(markerId); + } + updateModificationInfo(); + } + + public void removeMarker(String markerId) { + if (markerId == null) + return; + + Element ms = getMarkerRefsElement(); + if (ms == null) + return; + + Element m = getMarkerRefElement(markerId, ms); + if (m == null) + return; + + Node n = ms.removeChild(m); + if (!ms.hasChildNodes()) { + implementation.removeChild(ms); + } + if (n != null) { + WorkbookImpl workbook = getRealizedWorkbook(); + if (workbook != null) { + workbook.getMarkerRefCounter().decreaseRef(markerId); + } + fireTargetChange(Core.MarkerRefRemove, markerId); + SheetImpl sheet = getRealizedSheet(); + if (sheet != null) { + sheet.getMarkerRefCounter().decreaseRef(markerId); + } + updateModificationInfo(); + } + } + + public boolean hasMarker(String markerId) { + if (markerId == null) + return false; + + return getMarkerRefElement(markerId) != null; + } + + public IMarkerRef getMarkerRef(String markerId) { + if (markerId == null) + return null; + + Element m = getMarkerRefElement(markerId); + if (m != null) + return (IMarkerRef) ownedWorkbook.getAdaptableRegistry() + .getAdaptable(m); + return null; + } + + public Set getMarkerRefs() { + Element ms = getMarkerRefsElement(); + if (ms == null) + return NO_MARKER_REFS; + return DOMUtils.getChildSet(ms, TAG_MARKER_REF, + ownedWorkbook.getAdaptableRegistry()); + } + + private Element getMarkerRefsElement() { + return DOMUtils.getFirstChildElementByTag(implementation, + TAG_MARKER_REFS); + } + + private Element getMarkerRefElement(String markerId) { + Element ms = getMarkerRefsElement(); + if (ms == null) + return null; + return getMarkerRefElement(markerId, ms); + } + + private Element getMarkerRefElement(String markerId, Element ms) { + Iterator it = DOMUtils.childElementIterByTag(ms, + TAG_MARKER_REF); + while (it.hasNext()) { + Element m = it.next(); + if (markerId.equals(m.getAttribute(ATTR_MARKER_ID))) + return m; + } + return null; + } + + public void addBoundary(IBoundary boundary) { + Element b = ((BoundaryImpl) boundary).getImplementation(); + Element bs = DOMUtils.ensureChildElement(implementation, + TAG_BOUNDARIES); + Node n = bs.appendChild(b); + if (n != null) { + if (!isOrphan()) { + ((BoundaryImpl) boundary).addNotify(getRealizedWorkbook(), + this); + } + fireTargetChange(Core.BoundaryAdd, boundary); + updateModificationInfo(); + } + } + + public void removeBoundary(IBoundary boundary) { + Element bs = DOMUtils.getFirstChildElementByTag(implementation, + TAG_BOUNDARIES); + if (bs == null) + return; + + Element b = ((BoundaryImpl) boundary).getImplementation(); + if (b.getParentNode() == bs) { + ((BoundaryImpl) boundary).removeNotify(getRealizedWorkbook(), this); + Node n = bs.removeChild(b); + if (!bs.hasChildNodes()) + implementation.removeChild(bs); + if (n != null) { + fireTargetChange(Core.BoundaryRemove, boundary); + updateModificationInfo(); + } + } + } + + public Set getBoundaries() { + Element bs = DOMUtils.getFirstChildElementByTag(implementation, + TAG_BOUNDARIES); + if (bs == null) + return NO_BOUNDARIES; + return DOMUtils.getChildSet(bs, TAG_BOUNDARY, + ownedWorkbook.getAdaptableRegistry()); + } + + public void addSummary(ISummary summary) { + Element s = ((SummaryImpl) summary).getImplementation(); + Element ss = DOMUtils.ensureChildElement(implementation, TAG_SUMMARIES); + Node n = ss.appendChild(s); + if (n != null) { + if (!isOrphan()) { + ((SummaryImpl) summary).addNotify(getRealizedWorkbook(), this); + } + fireTargetChange(Core.SummaryAdd, summary); + updateModificationInfo(); + } + } + + public void removeSummary(ISummary summary) { + Element ss = DOMUtils.getFirstChildElementByTag(implementation, + TAG_SUMMARIES); + if (ss == null) + return; + + Element s = ((SummaryImpl) summary).getImplementation(); + if (s.getParentNode() == ss) { + ((SummaryImpl) summary).removeNotify(getRealizedWorkbook(), this); + Node n = ss.removeChild(s); + if (!ss.hasChildNodes()) + implementation.removeChild(ss); + if (n != null) { + fireTargetChange(Core.SummaryRemove, summary); + updateModificationInfo(); + } + } + } + + public Set getSummaries() { + Element ss = DOMUtils.getFirstChildElementByTag(implementation, + TAG_SUMMARIES); + if (ss == null) + return NO_SUMMARIES; + return DOMUtils.getChildSet(ss, TAG_SUMMARY, + ownedWorkbook.getAdaptableRegistry()); + } + + public String getStructureClass() { + return DOMUtils.getAttribute(implementation, ATTR_STRUCTURE_CLASS); + } + + public void setStructureClass(String structureClass) { + String oldValue = getStructureClass(); + DOMUtils.setAttribute(implementation, ATTR_STRUCTURE_CLASS, + structureClass); + String newValue = getStructureClass(); + fireValueChange(Core.StructureClass, oldValue, newValue); + updateModificationInfo(); + } + + public Set getLabels() { + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls != null) { + NodeList c = ls.getChildNodes(); + int num = c.getLength(); + if (num > 0) { + List set = new ArrayList(num); + for (int i = 0; i < num; i++) { + Node n = c.item(i); + if (DOMUtils.isElementByTag(n, TAG_LABEL)) { + set.add(n.getTextContent()); + } + } + return DOMUtils.unmodifiableSet(set); + } + } + return NO_LABELS; + } + + private Element findLabelElement(String label, Element ls) { + NodeList c = ls.getChildNodes(); + for (int i = 0; i < c.getLength(); i++) { + Node n = c.item(i); + if (DOMUtils.isElementByTag(n, TAG_LABEL)) { + String text = n.getTextContent(); + if (label.equals(text)) + return (Element) n; + } + } + return null; + } + + public void addLabel(String label) { + if (label == null) + return; + + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls != null) { + Element existing = findLabelElement(label, ls); + if (existing != null) + return; + } + + Set oldValue = getLabels(); + addLabelElement(ls, label); + Set newValue = getLabels(); + fireValueChange(Core.Labels, oldValue, newValue); + SheetImpl sheet = getRealizedSheet(); + if (sheet != null) { + sheet.getLabelRefCounter().increaseRef(label); + } + updateModificationInfo(); + } + + public void removeLabel(String label) { + if (label == null) + return; + + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls == null) + return; + + Element l = findLabelElement(label, ls); + if (l == null) + return; + + Set oldValue = getLabels(); + Node n = ls.removeChild(l); + if (n != null) { + if (!ls.hasChildNodes()) { + implementation.removeChild(ls); + } + Set newValue = getLabels(); + fireValueChange(Core.Labels, oldValue, newValue); + SheetImpl sheet = getRealizedSheet(); + if (sheet != null) { + sheet.getLabelRefCounter().decreaseRef(label); + } + updateModificationInfo(); + } + } + + public void setLabels(Collection labels) { + Set oldValue = getLabels(); + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls != null) { + implementation.removeChild(ls); + ls = null; + } + if (labels != null && !labels.isEmpty()) { + for (String label : labels) { + if (label != null) { + ls = addLabelElement(ls, label); + } + } + } + Set newValue = getLabels(); + fireValueChange(Core.Labels, oldValue, newValue); + SheetImpl sheet = getRealizedSheet(); + if (sheet != null) { + ILabelRefCounter counter = sheet.getLabelRefCounter(); + List added = new ArrayList(newValue); + added.removeAll(oldValue); + List removed = new ArrayList(oldValue); + removed.removeAll(newValue); + for (String increased : added) { + counter.increaseRef(increased); + } + for (String decreased : removed) { + counter.decreaseRef(decreased); + } + } + updateModificationInfo(); + } + + public void removeAllLabels() { + setLabels(NO_LABELS); + } + + private Element addLabelElement(Element ls, String label) { + if (ls == null) + ls = DOMUtils.createElement(implementation, TAG_LABELS); + Element l = DOMUtils.createElement(ls, TAG_LABEL); + l.setTextContent(label); + return ls; + } + + public IImage getImage() { + if (image == null) { + image = new ImageImpl(implementation, this); + } + return image; + } + + public int getTitleWidth() { + Element t = DOMUtils.getFirstChildElementByTag(implementation, + TAG_TITLE); + return t == null ? UNSPECIFIED + : NumberUtils.safeParseInt(DOMUtils.getAttribute(t, ATTR_WIDTH), + UNSPECIFIED); + } + + public void setTitleWidth(int width) { + Integer oldValue = getTitleWidthValue(); + if (width == UNSPECIFIED) { + Element t = DOMUtils.getFirstChildElementByTag(implementation, + TAG_TITLE); + if (t != null) { + t.removeAttribute(ATTR_WIDTH); + if (!t.hasChildNodes() && !t.hasAttributes()) { + implementation.removeChild(t); + } + } + } else { + Element t = DOMUtils.ensureChildElement(implementation, TAG_TITLE); + t.setAttribute(ATTR_WIDTH, String.valueOf(width)); + } + Integer newValue = getTitleWidthValue(); + fireValueChange(Core.TitleWidth, oldValue, newValue); + updateModificationInfo(); + } + + private Integer getTitleWidthValue() { + int width = getTitleWidth(); + if (width != UNSPECIFIED) + return Integer.valueOf(width); + return null; + } + + private Iterator iterExtensions() { + return iterExtensions(!isOrphan()); + } + + private Iterator iterExtensions( + final boolean realized) { + Element es = DOMUtils.getFirstChildElementByTag(implementation, + TAG_EXTENSIONS); + final Iterator it = es == null ? null + : DOMUtils.childElementIterByTag(es, TAG_EXTENSION); + return new Iterator() { + + TopicExtensionImpl next = findNext(); + + public void remove() { + } + + private TopicExtensionImpl findNext() { + if (it == null) + return null; + while (it.hasNext()) { + Element ele = it.next(); + String providerName = ele.getAttribute(ATTR_PROVIDER); + if (providerName != null && !"".equals(providerName)) { //$NON-NLS-1$ + TopicExtensionImpl ext = extensions.get(providerName); + if (ext == null) { + ext = new TopicExtensionImpl(ele, TopicImpl.this); + extensions.put(providerName, ext); + if (realized) { + ext.addNotify(ownedWorkbook); + } + } + return ext; + } + } + return null; + } + + public TopicExtensionImpl next() { + TopicExtensionImpl n = next; + next = findNext(); + return n; + } + + public boolean hasNext() { + return next != null; + } + }; + } + +// private TopicExtensionImpl getExtension(String providerName, Element extImpl) { +// TopicExtensionImpl ext = extensions.get(providerName); +// if (ext == null) { +// ext = new TopicExtensionImpl(extImpl, this); +// extensions.put(providerName, ext); +// ext.addNotify(getRealizedWorkbook()); +// } +// return ext; +// } + + public List getExtensions() { + List extensions = new ArrayList(); + Iterator it = iterExtensions(); + while (it.hasNext()) { + extensions.add(it.next()); + } + return extensions; + } + + public ITopicExtension getExtension(String providerName) { + Iterator it = iterExtensions(); + while (it.hasNext()) { + TopicExtensionImpl ext = it.next(); + if (providerName.equals(ext.getProviderName())) { + return ext; + } + } + return null; + } + + public ITopicExtension createExtension(String providerName) { + ITopicExtension ext = getExtension(providerName); + if (ext == null) { + Element es = DOMUtils.ensureChildElement(implementation, + TAG_EXTENSIONS); + Element e = DOMUtils.createElement(es, TAG_EXTENSION); + e.setAttribute(ATTR_PROVIDER, providerName); + ext = new TopicExtensionImpl(e, this); + extensions.put(providerName, (TopicExtensionImpl) ext); + if (!isOrphan()) { + ((TopicExtensionImpl) ext).addNotify(ownedWorkbook); + } + updateModificationInfo(); + } + return ext; +// Element e = findExtensionElement(es, providerName); +// if (e == null) { +// } +// return getExtension(providerName, e); + } + + private Element findExtensionElement(Element es, String providerName) { + Iterator it = DOMUtils.childElementIterByTag(es, + TAG_EXTENSION); + while (it.hasNext()) { + Element e = it.next(); + if (providerName.equals(e.getAttribute(ATTR_PROVIDER))) { + return e; + } + } + return null; + } + + public void deleteExtension(String providerName) { + Element es = DOMUtils.getFirstChildElementByTag(implementation, + TAG_EXTENSIONS); + if (es != null) { + Element e = findExtensionElement(es, providerName); + if (e != null) { + es.removeChild(e); + if (!es.hasChildNodes()) + implementation.removeChild(es); + updateModificationInfo(); + } + } + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + protected void fireValueChange(String type, Object oldValue, + Object newValue) { + ICoreEventSupport coreEventSupport = getCoreEventSupport(); + if (coreEventSupport != null) { + coreEventSupport.dispatchValueChange(this, type, oldValue, + newValue); + } + } + + protected void fireIndexedTargetChange(String type, Object target, + int index, Object data) { + ICoreEventSupport coreEventSupport = getCoreEventSupport(); + if (coreEventSupport != null) { + CoreEvent event = new CoreEvent(this, type, target, index); + event.setData(data); + coreEventSupport.dispatch(this, event); + } + } + + protected void fireTargetChange(String type, Object target) { + ICoreEventSupport coreEventSupport = getCoreEventSupport(); + if (coreEventSupport != null) { + coreEventSupport.dispatchTargetChange(this, type, target); + } + } + + public ICoreEventSupport getCoreEventSupport() { + // Use workbook's core event support directly, so that + // orphan components can have events broadcasted, which + // will enable transient actions (such as dragging topics + // or adjusting relationship control points, etc.) to + // perform correctly. + return ownedWorkbook.getCoreEventSupport(); + } + + protected WorkbookImpl getRealizedWorkbook() { + if (getPath().getWorkbook() == ownedWorkbook) + return ownedWorkbook; + return null; + } + + protected SheetImpl getRealizedSheet() { + ISheet sheet = getOwnedSheet(); + if (sheet != null && sheet instanceof SheetImpl) + return (SheetImpl) sheet; + return null; + } + + protected void addNotify(WorkbookImpl workbook, SheetImpl sheet, + TopicImpl parent) { + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true); + workbook.getAdaptableRegistry().registerById(this, getId(), + getImplementation().getOwnerDocument()); + increaseLabelRefs(sheet); + increaseMarkerRefs(workbook, sheet); + increaseStyleRef(workbook); + activateHyperlinks(workbook); + ((NotesImpl) getNotes()).addNotify(workbook); + for (ITopic t : getAllChildren()) { + ((TopicImpl) t).addNotify(workbook, sheet, this); + } + for (IBoundary b : getBoundaries()) { + ((BoundaryImpl) b).addNotify(workbook, this); + } + for (ISummary s : getSummaries()) { + ((SummaryImpl) s).addNotify(workbook, this); + } + extensionsAddNotify(workbook); + + boolean isRevising = (workbook.getAdaptableRegistry() + .getAdaptableByNode(sheet.getImplementation()) != sheet); + if (!isRevising) { + ((CommentManagerImpl) workbook.getCommentManager()) + .objectAddNotify(getId(), this); + } + } + + protected void removeNotify(WorkbookImpl workbook, SheetImpl sheet, + TopicImpl parent) { + boolean isRevising = (workbook.getAdaptableRegistry() + .getAdaptableByNode(sheet.getImplementation()) != sheet); + if (!isRevising) { + ((CommentManagerImpl) workbook.getCommentManager()) + .objectRemoveNotify(getId(), this); + } + + extensionsRemoveNotify(workbook); + for (ISummary s : getSummaries()) { + ((SummaryImpl) s).removeNotify(workbook, this); + } + for (IBoundary b : getBoundaries()) { + ((BoundaryImpl) b).removeNotify(workbook, this); + } + for (ITopic t : getAllChildren()) { + ((TopicImpl) t).removeNotify(workbook, sheet, this); + } + ((NotesImpl) getNotes()).removeNotify(workbook); + deactivateHyperlinks(workbook); + decreaseStyleRef(workbook); + decreaseMarkerRefs(workbook, sheet); + decreaseLabelRefs(sheet); + workbook.getAdaptableRegistry().unregisterById(this, getId(), + getImplementation().getOwnerDocument()); + getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false); + } + + private void extensionsAddNotify(WorkbookImpl workbook) { + Iterator it = iterExtensions(false); + while (it.hasNext()) { + it.next().addNotify(workbook); + } +// Element es = getFirstChildElementByTag(implementation, TAG_EXTENSIONS); +// if (es != null) { +// Iterator it = childElementIterByTag(es, TAG_EXTENSION); +// while (it.hasNext()) { +// Element e = it.next(); +// String providerName = getAttribute(e, ATTR_PROVIDER); +// if (providerName != null) { +// TopicExtensionImpl ext = extensions.get(providerName); +// if (ext == null) { +// ext = new TopicExtensionImpl(e, this); +// extensions.put(providerName, ext); +// } +// ext.addNotify(workbook); +// } +// } +// } + } + + private void extensionsRemoveNotify(WorkbookImpl workbook) { + Iterator it = iterExtensions(true); + while (it.hasNext()) { + it.next().removeNotify(workbook); + } +// Element es = DOMUtils.getFirstChildElementByTag(implementation, +// TAG_EXTENSIONS); +// if (es != null) { +// Iterator it = DOMUtils.childElementIterByTag(es, +// TAG_EXTENSION); +// while (it.hasNext()) { +// Element e = it.next(); +// String providerName = DOMUtils.getAttribute(e, ATTR_PROVIDER); +// if (providerName != null) { +// TopicExtensionImpl ext = getExtension(providerName, e); +// ext.removeNotify(workbook); +// } +// } +// } + } + + protected void increaseStyleRef(WorkbookImpl workbook) { + if (workbook == null) + return; + String styleId = getStyleId(); + if (styleId != null) { + workbook.getStyleRefCounter().increaseRef(styleId); + } + } + + protected void decreaseStyleRef(WorkbookImpl workbook) { + if (workbook == null) + return; + String styleId = getStyleId(); + if (styleId != null) { + workbook.getStyleRefCounter().decreaseRef(styleId); + } + } + + protected void increaseMarkerRefs(WorkbookImpl workbook, SheetImpl sheet) { + IMarkerRefCounter counter = sheet == null ? null + : sheet.getMarkerRefCounter(); + if (workbook == null && counter == null) + return; + + Element mrs = getMarkerRefsElement(); + if (mrs == null) + return; + + Iterator it = DOMUtils.childElementIterByTag(mrs, + TAG_MARKER_REF); + while (it.hasNext()) { + String markerId = DOMUtils.getAttribute(it.next(), ATTR_MARKER_ID); + if (markerId != null) { + if (workbook != null) + workbook.getMarkerRefCounter().increaseRef(markerId); + if (counter != null) + counter.increaseRef(markerId); + } + } + } + + protected void decreaseMarkerRefs(WorkbookImpl workbook, SheetImpl sheet) { + IMarkerRefCounter counter = sheet == null ? null + : sheet.getMarkerRefCounter(); + if (workbook == null && counter == null) + return; + + Element mrs = getMarkerRefsElement(); + if (mrs == null) + return; + + Iterator it = DOMUtils.childElementIterByTag(mrs, + TAG_MARKER_REF); + while (it.hasNext()) { + String markerId = DOMUtils.getAttribute(it.next(), ATTR_MARKER_ID); + if (markerId != null) { + if (workbook != null) + workbook.getMarkerRefCounter().decreaseRef(markerId); + if (counter != null) { + counter.decreaseRef(markerId); + } + } + } + } + + private void increaseLabelRefs(SheetImpl sheet) { + if (sheet == null) + return; + + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls == null) + return; + + ILabelRefCounter counter = sheet.getLabelRefCounter(); + Iterator it = DOMUtils.childElementIterByTag(ls, TAG_LABEL); + while (it.hasNext()) { + String label = it.next().getTextContent(); + counter.increaseRef(label); + } + } + + private void decreaseLabelRefs(SheetImpl sheet) { + if (sheet == null) + return; + + Element ls = DOMUtils.getFirstChildElementByTag(implementation, + TAG_LABELS); + if (ls == null) + return; + + ILabelRefCounter counter = sheet.getLabelRefCounter(); + Iterator it = DOMUtils.childElementIterByTag(ls, TAG_LABEL); + while (it.hasNext()) { + String label = it.next().getTextContent(); + counter.decreaseRef(label); + } + } + + protected void activateHyperlinks(WorkbookImpl workbook) { + InternalHyperlinkUtils.activateHyperlink(workbook, getHyperlink(), + this); + ((ImageImpl) getImage()).activateHyperlink(workbook); + } + + protected void deactivateHyperlinks(WorkbookImpl workbook) { + ((ImageImpl) getImage()).deactivateHyperlink(workbook); + InternalHyperlinkUtils.deactivateHyperlink(workbook, getHyperlink(), + this); + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, implementation); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, implementation); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + + ISheet sheet = getOwnedSheet(); + if (sheet != null) { + ((SheetImpl) sheet).updateModificationInfo(); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicPathImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicPathImpl.java index 07405b0be..1f2b99b5e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicPathImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/TopicPathImpl.java @@ -1,63 +1,63 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.TopicPath; - -/** - * @author briansun - * - */ -public class TopicPathImpl extends TopicPath { - - private ITopic topic; - - /** - * - */ - public TopicPathImpl(ITopic topic) { - this.topic = topic; - toList(); - } - - protected List createPathEntries() { - List entries = new ArrayList(); - ITopic t = topic; - ITopic parent = t.getParent(); - while (parent != null) { - entries.add(0, t); - t = parent; - parent = t.getParent(); - } - entries.add(0, t); - if (t != null && t.isRoot()) { - ISheet sheet = t.getOwnedSheet(); - if (sheet != null) { - entries.add(0, sheet); - IWorkbook workbook = sheet.getParent(); - if (workbook != null) { - entries.add(0, workbook); - } - } - } - return entries; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.TopicPath; + +/** + * @author briansun + * + */ +public class TopicPathImpl extends TopicPath { + + private ITopic topic; + + /** + * + */ + public TopicPathImpl(ITopic topic) { + this.topic = topic; + toList(); + } + + protected List createPathEntries() { + List entries = new ArrayList(); + ITopic t = topic; + ITopic parent = t.getParent(); + while (parent != null) { + entries.add(0, t); + t = parent; + parent = t.getParent(); + } + entries.add(0, t); + if (t != null && t.isRoot()) { + ISheet sheet = t.getOwnedSheet(); + if (sheet != null) { + entries.add(0, sheet); + IWorkbook workbook = sheet.getParent(); + if (workbook != null) { + entries.add(0, workbook); + } + } + } + return entries; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookBuilderImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookBuilderImpl.java index 491650884..758636dc8 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookBuilderImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookBuilderImpl.java @@ -1,284 +1,284 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IDeserializer; -import org.xmind.core.IEncryptionData; -import org.xmind.core.IEncryptionHandler; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IMeta; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.AbstractWorkbookBuilder; -import org.xmind.core.internal.security.Crypto; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.ChecksumTrackingOutputStream; -import org.xmind.core.io.ChecksumVerifiedInputStream; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; - -@SuppressWarnings("deprecation") -public class WorkbookBuilderImpl extends AbstractWorkbookBuilder { - - protected synchronized Document createDocument() { - DocumentBuilder docBuilder; - try { - docBuilder = DOMUtils.getDefaultDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new IllegalStateException(e); - } - return docBuilder.newDocument(); - } - - protected synchronized DocumentBuilder getDocumentLoader() - throws CoreException { - try { - DocumentBuilder loader = DOMUtils.getDefaultDocumentBuilder(); - return loader; - } catch (ParserConfigurationException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); - } - } - - @Override - protected IWorkbook doCreateWorkbook(IStorage storage) { - if (storage == null) - storage = new ByteArrayStorage(); - storage.clear(); - - Document contentDoc = createDocument(); - WorkbookImpl workbook = new WorkbookImpl(contentDoc, storage); - - /* - * ------------------------------------------------------ - * - * NEED REFACTOR: - */ - IMeta meta = workbook.getMeta(); - String name = System.getProperty(DOMConstants.AUTHOR_NAME); - if (name == null) - name = System.getProperty("user.name"); //$NON-NLS-1$ - if (name != null) - meta.setValue(IMeta.AUTHOR_NAME, name); - - String email = System.getProperty(DOMConstants.AUTHOR_EMAIL); - if (email != null) - meta.setValue(IMeta.AUTHOR_EMAIL, email); - - String org = System.getProperty(DOMConstants.AUTHOR_ORG); - if (org != null) - meta.setValue(IMeta.AUTHOR_ORG, org); - - if (meta.getValue(IMeta.CREATED_TIME) == null) - meta.setValue(IMeta.CREATED_TIME, - NumberUtils.formatDate(System.currentTimeMillis())); - - meta.setValue(IMeta.CREATOR_NAME, getCreatorName()); - meta.setValue(IMeta.CREATOR_VERSION, getCreatorVersion()); - - return workbook; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IWorkbookBuilder#newDeserializer() - */ - public IDeserializer newDeserializer() { - DeserializerImpl deserializer = new DeserializerImpl(); - deserializer.setCreatorName(getCreatorName()); - deserializer.setCreatorVersion(getCreatorVersion()); - return deserializer; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.IWorkbookBuilder#newSerializer() - */ - public ISerializer newSerializer() { - SerializerImpl serializer = new SerializerImpl(); - serializer.setCreatorName(getCreatorName()); - serializer.setCreatorVersion(getCreatorVersion()); - return serializer; - } - - private static class LegacyEncryptionNormalizerAdapter - implements IEntryStreamNormalizer { - - private final IEncryptionHandler encryptionHandler; - - /** - * - */ - public LegacyEncryptionNormalizerAdapter( - IEncryptionHandler encryptionHandler) { - super(); - this.encryptionHandler = encryptionHandler; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. - * OutputStream, org.xmind.core.IFileEntry) - */ - public OutputStream normalizeOutputStream(OutputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - fileEntry.deleteEncryptionData(); - IEncryptionData encData = fileEntry.createEncryptionData(); - Crypto.initEncryptionData(encData); - OutputStream out = Crypto.creatOutputStream(stream, true, encData, - encryptionHandler.retrievePassword()); - if (encData.getChecksumType() != null) { - return new ChecksumTrackingOutputStream(encData, out); - } - return out; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. - * InputStream, org.xmind.core.IFileEntry) - */ - public InputStream normalizeInputStream(InputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - IEncryptionData encData = fileEntry.getEncryptionData(); - if (encData == null) - return stream; - InputStream in = Crypto.createInputStream(stream, false, encData, - encryptionHandler.retrievePassword()); - if (encData.getChecksumType() != null) { - return new ChecksumVerifiedInputStream(in, - encData.getChecksum()); - } - return in; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null - || !(obj instanceof LegacyEncryptionNormalizerAdapter)) - return false; - LegacyEncryptionNormalizerAdapter that = (LegacyEncryptionNormalizerAdapter) obj; - return this.encryptionHandler.equals(that.encryptionHandler); - } - - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.internal.AbstractWorkbookBuilder#doLoadFromInputSource(org - * .xmind.core.io.IInputSource, org.xmind.core.io.IStorage, - * org.xmind.core.IEncryptionHandler) - */ - @Override - protected IWorkbook doLoadFromInputSource(IInputSource source, - IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setCreatorName(getCreatorName()); - deserializer.setCreatorVersion(getCreatorVersion()); - deserializer.setWorkbookStorage(storage); - deserializer.setEntryStreamNormalizer( - new LegacyEncryptionNormalizerAdapter(encryptionHandler)); - deserializer.setInputSource(source); - deserializer.deserialize(null); - return deserializer.getWorkbook(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.internal.AbstractWorkbookBuilder#doLoadFromStream(java.io. - * InputStream, org.xmind.core.io.IStorage, - * org.xmind.core.IEncryptionHandler) - */ - @Override - protected IWorkbook doLoadFromStream(InputStream in, IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setCreatorName(getCreatorName()); - deserializer.setCreatorVersion(getCreatorVersion()); - deserializer.setWorkbookStorage(storage); - deserializer.setEntryStreamNormalizer( - new LegacyEncryptionNormalizerAdapter(encryptionHandler)); - deserializer.setInputStream(in); - deserializer.deserialize(null); - return deserializer.getWorkbook(); - } - - @Override - protected IWorkbook doLoadFromStorage(IStorage storage, - IEncryptionHandler encryptionHandler) - throws IOException, CoreException { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setCreatorName(getCreatorName()); - deserializer.setCreatorVersion(getCreatorVersion()); - deserializer.setWorkbookStorage(storage); - deserializer.setEntryStreamNormalizer( - new LegacyEncryptionNormalizerAdapter(encryptionHandler)); - deserializer.setWorkbookStorageAsInputSource(); - deserializer.deserialize(null); - return deserializer.getWorkbook(); - } - - /** - * @deprecated This method should NOT be called any more. - */ - @Override - @Deprecated - protected void extractFromStream(InputStream input, IOutputTarget target) - throws IOException, CoreException { - ZipInputStream zip = new ZipInputStream(input); - try { - FileUtils.extractZipFile(zip, target); - } finally { - zip.close(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IDeserializer; +import org.xmind.core.IEncryptionData; +import org.xmind.core.IEncryptionHandler; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IMeta; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.AbstractWorkbookBuilder; +import org.xmind.core.internal.security.Crypto; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.ChecksumTrackingOutputStream; +import org.xmind.core.io.ChecksumVerifiedInputStream; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; + +@SuppressWarnings("deprecation") +public class WorkbookBuilderImpl extends AbstractWorkbookBuilder { + + protected synchronized Document createDocument() { + DocumentBuilder docBuilder; + try { + docBuilder = DOMUtils.getDefaultDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } + return docBuilder.newDocument(); + } + + protected synchronized DocumentBuilder getDocumentLoader() + throws CoreException { + try { + DocumentBuilder loader = DOMUtils.getDefaultDocumentBuilder(); + return loader; + } catch (ParserConfigurationException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_PARSER, e); + } + } + + @Override + protected IWorkbook doCreateWorkbook(IStorage storage) { + if (storage == null) + storage = new ByteArrayStorage(); + storage.clear(); + + Document contentDoc = createDocument(); + WorkbookImpl workbook = new WorkbookImpl(contentDoc, storage); + + /* + * ------------------------------------------------------ + * + * NEED REFACTOR: + */ + IMeta meta = workbook.getMeta(); + String name = System.getProperty(DOMConstants.AUTHOR_NAME); + if (name == null) + name = System.getProperty("user.name"); //$NON-NLS-1$ + if (name != null) + meta.setValue(IMeta.AUTHOR_NAME, name); + + String email = System.getProperty(DOMConstants.AUTHOR_EMAIL); + if (email != null) + meta.setValue(IMeta.AUTHOR_EMAIL, email); + + String org = System.getProperty(DOMConstants.AUTHOR_ORG); + if (org != null) + meta.setValue(IMeta.AUTHOR_ORG, org); + + if (meta.getValue(IMeta.CREATED_TIME) == null) + meta.setValue(IMeta.CREATED_TIME, + NumberUtils.formatDate(System.currentTimeMillis())); + + meta.setValue(IMeta.CREATOR_NAME, getCreatorName()); + meta.setValue(IMeta.CREATOR_VERSION, getCreatorVersion()); + + return workbook; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IWorkbookBuilder#newDeserializer() + */ + public IDeserializer newDeserializer() { + DeserializerImpl deserializer = new DeserializerImpl(); + deserializer.setCreatorName(getCreatorName()); + deserializer.setCreatorVersion(getCreatorVersion()); + return deserializer; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.IWorkbookBuilder#newSerializer() + */ + public ISerializer newSerializer() { + SerializerImpl serializer = new SerializerImpl(); + serializer.setCreatorName(getCreatorName()); + serializer.setCreatorVersion(getCreatorVersion()); + return serializer; + } + + private static class LegacyEncryptionNormalizerAdapter + implements IEntryStreamNormalizer { + + private final IEncryptionHandler encryptionHandler; + + /** + * + */ + public LegacyEncryptionNormalizerAdapter( + IEncryptionHandler encryptionHandler) { + super(); + this.encryptionHandler = encryptionHandler; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. + * OutputStream, org.xmind.core.IFileEntry) + */ + public OutputStream normalizeOutputStream(OutputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + fileEntry.deleteEncryptionData(); + IEncryptionData encData = fileEntry.createEncryptionData(); + Crypto.initEncryptionData(encData); + OutputStream out = Crypto.creatOutputStream(stream, true, encData, + encryptionHandler.retrievePassword()); + if (encData.getChecksumType() != null) { + return new ChecksumTrackingOutputStream(encData, out); + } + return out; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. + * InputStream, org.xmind.core.IFileEntry) + */ + public InputStream normalizeInputStream(InputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + IEncryptionData encData = fileEntry.getEncryptionData(); + if (encData == null) + return stream; + InputStream in = Crypto.createInputStream(stream, false, encData, + encryptionHandler.retrievePassword()); + if (encData.getChecksumType() != null) { + return new ChecksumVerifiedInputStream(in, + encData.getChecksum()); + } + return in; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null + || !(obj instanceof LegacyEncryptionNormalizerAdapter)) + return false; + LegacyEncryptionNormalizerAdapter that = (LegacyEncryptionNormalizerAdapter) obj; + return this.encryptionHandler.equals(that.encryptionHandler); + } + + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.internal.AbstractWorkbookBuilder#doLoadFromInputSource(org + * .xmind.core.io.IInputSource, org.xmind.core.io.IStorage, + * org.xmind.core.IEncryptionHandler) + */ + @Override + protected IWorkbook doLoadFromInputSource(IInputSource source, + IStorage storage, IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setCreatorName(getCreatorName()); + deserializer.setCreatorVersion(getCreatorVersion()); + deserializer.setWorkbookStorage(storage); + deserializer.setEntryStreamNormalizer( + new LegacyEncryptionNormalizerAdapter(encryptionHandler)); + deserializer.setInputSource(source); + deserializer.deserialize(null); + return deserializer.getWorkbook(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.internal.AbstractWorkbookBuilder#doLoadFromStream(java.io. + * InputStream, org.xmind.core.io.IStorage, + * org.xmind.core.IEncryptionHandler) + */ + @Override + protected IWorkbook doLoadFromStream(InputStream in, IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setCreatorName(getCreatorName()); + deserializer.setCreatorVersion(getCreatorVersion()); + deserializer.setWorkbookStorage(storage); + deserializer.setEntryStreamNormalizer( + new LegacyEncryptionNormalizerAdapter(encryptionHandler)); + deserializer.setInputStream(in); + deserializer.deserialize(null); + return deserializer.getWorkbook(); + } + + @Override + protected IWorkbook doLoadFromStorage(IStorage storage, + IEncryptionHandler encryptionHandler) + throws IOException, CoreException { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setCreatorName(getCreatorName()); + deserializer.setCreatorVersion(getCreatorVersion()); + deserializer.setWorkbookStorage(storage); + deserializer.setEntryStreamNormalizer( + new LegacyEncryptionNormalizerAdapter(encryptionHandler)); + deserializer.setWorkbookStorageAsInputSource(); + deserializer.deserialize(null); + return deserializer.getWorkbook(); + } + + /** + * @deprecated This method should NOT be called any more. + */ + @Override + @Deprecated + protected void extractFromStream(InputStream input, IOutputTarget target) + throws IOException, CoreException { + ZipInputStream zip = new ZipInputStream(input); + try { + FileUtils.extractZipFile(zip, target); + } finally { + zip.close(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionElementImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionElementImpl.java index c9515a37f..3081c67a5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionElementImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionElementImpl.java @@ -1,226 +1,226 @@ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_PATH; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtension; -import org.xmind.core.IWorkbookExtensionElement; -import org.xmind.core.internal.WorkbookExtensionElement; -import org.xmind.core.util.DOMUtils; - -/** - * @author Jason Wong - */ -public class WorkbookExtensionElementImpl extends WorkbookExtensionElement { - - private Element implementation; - - private WorkbookImpl workbook; - - private WorkbookExtensionImpl extension; - - public WorkbookExtensionElementImpl(Element implementation, - WorkbookImpl workbook, WorkbookExtensionImpl extension) { - this.implementation = implementation; - this.workbook = workbook; - this.extension = extension; - } - - public Element getImplementation() { - return implementation; - } - - public IWorkbook getOwnedWorkbook() { - return workbook; - } - - public IWorkbookExtension getExtension() { - return extension; - } - - public String getName() { - return implementation.getTagName(); - } - - public List getChildren() { - return getChildren(null); - } - - public List getChildren(String elementName) { - return DOMUtils.getChildList(implementation, elementName, extension); - } - - public IWorkbookExtensionElement getParent() { - Node p = implementation.getParentNode(); - if (p == null || !(p instanceof Element)) - return null; - return extension.getElement((Element) p); - } - - public IWorkbookExtensionElement createChild(String elementName) { - Element childImpl = DOMUtils.createElement(implementation, elementName); - WorkbookExtensionElementImpl child = new WorkbookExtensionElementImpl( - childImpl, workbook, extension); - registerChild(child); - workbook.updateModificationInfo(); - return child; - } - - public IWorkbookExtensionElement getFirstChild(String elementName) { - Element childImpl = DOMUtils.getFirstChildElementByTag(implementation, - elementName); - return childImpl == null ? null : extension.getElement(childImpl); - } - - public void addChild(IWorkbookExtensionElement child, int index) { - WorkbookExtensionElementImpl c = (WorkbookExtensionElementImpl) child; - if (c.getExtension() != this.getExtension() - || c.getOwnedWorkbook() != this.getOwnedWorkbook()) - return; - - IWorkbookExtensionElement oldParent = c.getParent(); - if (oldParent != null) - oldParent.deleteChild(child); - - Element childImpl = c.getImplementation(); - Element[] es = DOMUtils.getChildElements(implementation); - if (index >= 0 && index < es.length) - implementation.insertBefore(childImpl, es[index]); - else - implementation.appendChild(childImpl); - registerChild(c); - workbook.updateModificationInfo(); - } - - public void deleteChild(IWorkbookExtensionElement child) { - WorkbookExtensionElementImpl c = (WorkbookExtensionElementImpl) child; - Element childImpl = c.getImplementation(); - if (childImpl.getParentNode() == implementation) { - unregisterChild(c); - implementation.removeChild(childImpl); - workbook.updateModificationInfo(); - } - } - - public void deleteChildren() { - deleteChildren(null); - } - - public void deleteChildren(String elementName) { - Element[] children; - if (elementName == null) - children = DOMUtils.getChildElements(implementation); - else - children = DOMUtils.getChildElementsByTag(implementation, - elementName); - - for (int i = 0; i < children.length; i++) - implementation.removeChild(children[i]); - - if (children.length > 0) - workbook.updateModificationInfo(); - } - - public Set getAttributeKeys() { - Set keys = new HashSet(); - NamedNodeMap atts = implementation.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) { - Node att = atts.item(i); - String key = att.getNodeName(); - if (key != null && !"".equals(key)) //$NON-NLS-1$ - keys.add(key); - } - return keys; - } - - public String getAttribute(String attrName) { - return DOMUtils.getAttribute(implementation, attrName); - } - - public void setAttribute(String attrName, String attrValue) { - DOMUtils.setAttribute(implementation, attrName, attrValue); - workbook.updateModificationInfo(); - } - - public String getTextContent() { - Node c = implementation.getFirstChild(); - if (c != null && c.getNodeType() == Node.TEXT_NODE) - return c.getTextContent(); - return null; - } - - public void setTextContent(String text) { - Node c = implementation.getFirstChild(); - if (text == null) { - if (c != null) { - implementation.removeChild(c); - workbook.updateModificationInfo(); - } - } else { - if (c != null && c.getNodeType() == Node.TEXT_NODE) { - c.setTextContent(text); - } else { - Node t = implementation.getOwnerDocument().createTextNode(text); - implementation.insertBefore(t, c); - } - workbook.updateModificationInfo(); - } - } - - public void setResourcePath(String resourcePath) { - setAttribute(ATTR_RESOURCE_PATH, resourcePath); - } - - public String getResourcePath() { - return getAttribute(ATTR_RESOURCE_PATH); - } - - public void setObjectId(String objectId) { - setAttribute(ATTR_OBJECT_ID, objectId); - } - - public String getObjectId() { - return getAttribute(ATTR_OBJECT_ID); - } - - private void registerChild(WorkbookExtensionElementImpl child) { - extension.registerElement(child); - } - - private void unregisterChild(WorkbookExtensionElementImpl child) { - extension.unregisterElement(child); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookExtensionElementImpl)) - return false; - WorkbookExtensionElementImpl that = (WorkbookExtensionElementImpl) obj; - return this.implementation == that.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public String toString() { - return "{element:}" + getName() + "}"; //$NON-NLS-1$//$NON-NLS-2$ - } - -} +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_PATH; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtension; +import org.xmind.core.IWorkbookExtensionElement; +import org.xmind.core.internal.WorkbookExtensionElement; +import org.xmind.core.util.DOMUtils; + +/** + * @author Jason Wong + */ +public class WorkbookExtensionElementImpl extends WorkbookExtensionElement { + + private Element implementation; + + private WorkbookImpl workbook; + + private WorkbookExtensionImpl extension; + + public WorkbookExtensionElementImpl(Element implementation, + WorkbookImpl workbook, WorkbookExtensionImpl extension) { + this.implementation = implementation; + this.workbook = workbook; + this.extension = extension; + } + + public Element getImplementation() { + return implementation; + } + + public IWorkbook getOwnedWorkbook() { + return workbook; + } + + public IWorkbookExtension getExtension() { + return extension; + } + + public String getName() { + return implementation.getTagName(); + } + + public List getChildren() { + return getChildren(null); + } + + public List getChildren(String elementName) { + return DOMUtils.getChildList(implementation, elementName, extension); + } + + public IWorkbookExtensionElement getParent() { + Node p = implementation.getParentNode(); + if (p == null || !(p instanceof Element)) + return null; + return extension.getElement((Element) p); + } + + public IWorkbookExtensionElement createChild(String elementName) { + Element childImpl = DOMUtils.createElement(implementation, elementName); + WorkbookExtensionElementImpl child = new WorkbookExtensionElementImpl( + childImpl, workbook, extension); + registerChild(child); + workbook.updateModificationInfo(); + return child; + } + + public IWorkbookExtensionElement getFirstChild(String elementName) { + Element childImpl = DOMUtils.getFirstChildElementByTag(implementation, + elementName); + return childImpl == null ? null : extension.getElement(childImpl); + } + + public void addChild(IWorkbookExtensionElement child, int index) { + WorkbookExtensionElementImpl c = (WorkbookExtensionElementImpl) child; + if (c.getExtension() != this.getExtension() + || c.getOwnedWorkbook() != this.getOwnedWorkbook()) + return; + + IWorkbookExtensionElement oldParent = c.getParent(); + if (oldParent != null) + oldParent.deleteChild(child); + + Element childImpl = c.getImplementation(); + Element[] es = DOMUtils.getChildElements(implementation); + if (index >= 0 && index < es.length) + implementation.insertBefore(childImpl, es[index]); + else + implementation.appendChild(childImpl); + registerChild(c); + workbook.updateModificationInfo(); + } + + public void deleteChild(IWorkbookExtensionElement child) { + WorkbookExtensionElementImpl c = (WorkbookExtensionElementImpl) child; + Element childImpl = c.getImplementation(); + if (childImpl.getParentNode() == implementation) { + unregisterChild(c); + implementation.removeChild(childImpl); + workbook.updateModificationInfo(); + } + } + + public void deleteChildren() { + deleteChildren(null); + } + + public void deleteChildren(String elementName) { + Element[] children; + if (elementName == null) + children = DOMUtils.getChildElements(implementation); + else + children = DOMUtils.getChildElementsByTag(implementation, + elementName); + + for (int i = 0; i < children.length; i++) + implementation.removeChild(children[i]); + + if (children.length > 0) + workbook.updateModificationInfo(); + } + + public Set getAttributeKeys() { + Set keys = new HashSet(); + NamedNodeMap atts = implementation.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node att = atts.item(i); + String key = att.getNodeName(); + if (key != null && !"".equals(key)) //$NON-NLS-1$ + keys.add(key); + } + return keys; + } + + public String getAttribute(String attrName) { + return DOMUtils.getAttribute(implementation, attrName); + } + + public void setAttribute(String attrName, String attrValue) { + DOMUtils.setAttribute(implementation, attrName, attrValue); + workbook.updateModificationInfo(); + } + + public String getTextContent() { + Node c = implementation.getFirstChild(); + if (c != null && c.getNodeType() == Node.TEXT_NODE) + return c.getTextContent(); + return null; + } + + public void setTextContent(String text) { + Node c = implementation.getFirstChild(); + if (text == null) { + if (c != null) { + implementation.removeChild(c); + workbook.updateModificationInfo(); + } + } else { + if (c != null && c.getNodeType() == Node.TEXT_NODE) { + c.setTextContent(text); + } else { + Node t = implementation.getOwnerDocument().createTextNode(text); + implementation.insertBefore(t, c); + } + workbook.updateModificationInfo(); + } + } + + public void setResourcePath(String resourcePath) { + setAttribute(ATTR_RESOURCE_PATH, resourcePath); + } + + public String getResourcePath() { + return getAttribute(ATTR_RESOURCE_PATH); + } + + public void setObjectId(String objectId) { + setAttribute(ATTR_OBJECT_ID, objectId); + } + + public String getObjectId() { + return getAttribute(ATTR_OBJECT_ID); + } + + private void registerChild(WorkbookExtensionElementImpl child) { + extension.registerElement(child); + } + + private void unregisterChild(WorkbookExtensionElementImpl child) { + extension.unregisterElement(child); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookExtensionElementImpl)) + return false; + WorkbookExtensionElementImpl that = (WorkbookExtensionElementImpl) obj; + return this.implementation == that.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public String toString() { + return "{element:}" + getName() + "}"; //$NON-NLS-1$//$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionImpl.java index f3a0c9153..fa559931a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionImpl.java @@ -1,210 +1,210 @@ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; -import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REF; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REFS; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.IAdaptable; -import org.xmind.core.IResourceRef; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtensionElement; -import org.xmind.core.internal.WorkbookExtension; -import org.xmind.core.util.DOMUtils; - -/** - * @author Jason Wong - */ -public class WorkbookExtensionImpl extends WorkbookExtension - implements INodeAdaptableProvider { - - private Map eleMap = new HashMap(); - - private Document implementation; - - private WorkbookImpl workbook; - - private WorkbookExtensionElementImpl content; - - public WorkbookExtensionImpl(Document implementation, - WorkbookImpl workbook) { - this.implementation = implementation; - this.workbook = workbook; - init(); - } - - private void init() { - Element e = getExtensionElement(); - for (NS ns : NS.values()) { - if (ns.getPrefix().equals(e.getTagName())) - NS.setNS(ns, e); - } - } - - private Element getExtensionElement() { - return implementation.getDocumentElement(); - } - - protected void addNotify(WorkbookImpl workbook) { - for (IResourceRef ref : getResourceRefs()) - ((ResourceRefImpl) ref).addNotify(workbook); - } - - protected void removeNotify(WorkbookImpl workbook) { - for (IResourceRef ref : getResourceRefs()) - ((ResourceRefImpl) ref).removeNotify(workbook); - } - - public Document getImplementation() { - return implementation; - } - - public String getProviderName() { - return getExtensionElement().getAttribute(ATTR_PROVIDER); - } - - public IWorkbookExtensionElement getContent() { - if (content == null) { - content = new WorkbookExtensionElementImpl(getContentElement(), - workbook, this); - registerElement(content); - } - return content; - } - - private Element getContentElement() { - return DOMUtils.ensureChildElement(getExtensionElement(), TAG_CONTENT); - } - - public List getResourceRefs() { - Element refsEle = getRefsElement(); - if (refsEle != null) - return DOMUtils.getChildList(refsEle, TAG_RESOURCE_REF, - workbook.getAdaptableRegistry()); - return EMPTY_REFS; - } - - public IResourceRef getResourceRef(String resourceId) { - if (resourceId != null && !"".equals(resourceId)) { //$NON-NLS-1$ - for (IResourceRef ref : getResourceRefs()) { - if (resourceId.equals(ref.getResourceId())) - return ref; - } - } - return null; - } - - public void addResourceRef(IResourceRef ref) { - importResourceRef(ref); - - Element refEle = ((ResourceRefImpl) ref).getImplementation(); - Element refsEle = DOMUtils.ensureChildElement(getExtensionElement(), - TAG_RESOURCE_REFS); - Node n = refsEle.appendChild(refEle); - if (n != null) { - if (!isOrphan()) - ((ResourceRefImpl) ref).addNotify(workbook); - } - workbook.updateModificationInfo(); - } - - private void importResourceRef(IResourceRef ref) { - Element oldValue = ((ResourceRefImpl) ref).getImplementation(); - - Element newValue = implementation.createElement(oldValue.getTagName()); - newValue.setAttribute(DOMConstants.ATTR_RESOURCE_ID, - ref.getResourceId()); - newValue.setAttribute(DOMConstants.ATTR_TYPE, ref.getType()); - - ((ResourceRefImpl) ref).setImplementation(newValue); - } - - public void removeResourceRef(IResourceRef ref) { - Element refsEle = getRefsElement(); - if (refsEle == null) - return; - - Element refEle = ((ResourceRefImpl) ref).getImplementation(); - if (refEle.getParentNode() == refsEle) { - ((ResourceRefImpl) ref).removeNotify(workbook); - Node n = refsEle.removeChild(refEle); - if (!refsEle.hasChildNodes()) - getExtensionElement().removeChild(refsEle); - if (n != null) - workbook.updateModificationInfo(); - } - } - - private Element getRefsElement() { - return DOMUtils.getFirstChildElementByTag(getExtensionElement(), - TAG_RESOURCE_REFS); - } - - public IWorkbook getOwnedWorkbook() { - return workbook; - } - - public IAdaptable getAdaptable(Node node) { - if (node instanceof Element) - return getElement((Element) node); - return null; - } - - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getImplementation()); - return super.getAdapter(adapter); - } - - protected WorkbookExtensionElementImpl getElement(Element impl) { - if (impl == getExtensionElement()) - return null; - - WorkbookExtensionElementImpl ele = eleMap.get(impl); - if (ele == null) { - ele = new WorkbookExtensionElementImpl(impl, workbook, this); - registerElement(ele); - } - return ele; - } - - protected void registerElement(WorkbookExtensionElementImpl element) { - eleMap.put(element.getImplementation(), element); - } - - protected void unregisterElement(WorkbookExtensionElementImpl element) { - eleMap.remove(element.getImplementation()); - } - - public boolean isOrphan() { - return DOMUtils.isOrphanNode(implementation); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookExtensionImpl)) - return false; - WorkbookExtensionImpl that = (WorkbookExtensionImpl) obj; - return this.implementation == that.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - @Override - public String toString() { - return "{workbook-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; +import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REF; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REFS; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.IAdaptable; +import org.xmind.core.IResourceRef; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtensionElement; +import org.xmind.core.internal.WorkbookExtension; +import org.xmind.core.util.DOMUtils; + +/** + * @author Jason Wong + */ +public class WorkbookExtensionImpl extends WorkbookExtension + implements INodeAdaptableProvider { + + private Map eleMap = new HashMap(); + + private Document implementation; + + private WorkbookImpl workbook; + + private WorkbookExtensionElementImpl content; + + public WorkbookExtensionImpl(Document implementation, + WorkbookImpl workbook) { + this.implementation = implementation; + this.workbook = workbook; + init(); + } + + private void init() { + Element e = getExtensionElement(); + for (NS ns : NS.values()) { + if (ns.getPrefix().equals(e.getTagName())) + NS.setNS(ns, e); + } + } + + private Element getExtensionElement() { + return implementation.getDocumentElement(); + } + + protected void addNotify(WorkbookImpl workbook) { + for (IResourceRef ref : getResourceRefs()) + ((ResourceRefImpl) ref).addNotify(workbook); + } + + protected void removeNotify(WorkbookImpl workbook) { + for (IResourceRef ref : getResourceRefs()) + ((ResourceRefImpl) ref).removeNotify(workbook); + } + + public Document getImplementation() { + return implementation; + } + + public String getProviderName() { + return getExtensionElement().getAttribute(ATTR_PROVIDER); + } + + public IWorkbookExtensionElement getContent() { + if (content == null) { + content = new WorkbookExtensionElementImpl(getContentElement(), + workbook, this); + registerElement(content); + } + return content; + } + + private Element getContentElement() { + return DOMUtils.ensureChildElement(getExtensionElement(), TAG_CONTENT); + } + + public List getResourceRefs() { + Element refsEle = getRefsElement(); + if (refsEle != null) + return DOMUtils.getChildList(refsEle, TAG_RESOURCE_REF, + workbook.getAdaptableRegistry()); + return EMPTY_REFS; + } + + public IResourceRef getResourceRef(String resourceId) { + if (resourceId != null && !"".equals(resourceId)) { //$NON-NLS-1$ + for (IResourceRef ref : getResourceRefs()) { + if (resourceId.equals(ref.getResourceId())) + return ref; + } + } + return null; + } + + public void addResourceRef(IResourceRef ref) { + importResourceRef(ref); + + Element refEle = ((ResourceRefImpl) ref).getImplementation(); + Element refsEle = DOMUtils.ensureChildElement(getExtensionElement(), + TAG_RESOURCE_REFS); + Node n = refsEle.appendChild(refEle); + if (n != null) { + if (!isOrphan()) + ((ResourceRefImpl) ref).addNotify(workbook); + } + workbook.updateModificationInfo(); + } + + private void importResourceRef(IResourceRef ref) { + Element oldValue = ((ResourceRefImpl) ref).getImplementation(); + + Element newValue = implementation.createElement(oldValue.getTagName()); + newValue.setAttribute(DOMConstants.ATTR_RESOURCE_ID, + ref.getResourceId()); + newValue.setAttribute(DOMConstants.ATTR_TYPE, ref.getType()); + + ((ResourceRefImpl) ref).setImplementation(newValue); + } + + public void removeResourceRef(IResourceRef ref) { + Element refsEle = getRefsElement(); + if (refsEle == null) + return; + + Element refEle = ((ResourceRefImpl) ref).getImplementation(); + if (refEle.getParentNode() == refsEle) { + ((ResourceRefImpl) ref).removeNotify(workbook); + Node n = refsEle.removeChild(refEle); + if (!refsEle.hasChildNodes()) + getExtensionElement().removeChild(refsEle); + if (n != null) + workbook.updateModificationInfo(); + } + } + + private Element getRefsElement() { + return DOMUtils.getFirstChildElementByTag(getExtensionElement(), + TAG_RESOURCE_REFS); + } + + public IWorkbook getOwnedWorkbook() { + return workbook; + } + + public IAdaptable getAdaptable(Node node) { + if (node instanceof Element) + return getElement((Element) node); + return null; + } + + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); + return super.getAdapter(adapter); + } + + protected WorkbookExtensionElementImpl getElement(Element impl) { + if (impl == getExtensionElement()) + return null; + + WorkbookExtensionElementImpl ele = eleMap.get(impl); + if (ele == null) { + ele = new WorkbookExtensionElementImpl(impl, workbook, this); + registerElement(ele); + } + return ele; + } + + protected void registerElement(WorkbookExtensionElementImpl element) { + eleMap.put(element.getImplementation(), element); + } + + protected void unregisterElement(WorkbookExtensionElementImpl element) { + eleMap.remove(element.getImplementation()); + } + + public boolean isOrphan() { + return DOMUtils.isOrphanNode(implementation); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookExtensionImpl)) + return false; + WorkbookExtensionImpl that = (WorkbookExtensionImpl) obj; + return this.implementation == that.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + @Override + public String toString() { + return "{workbook-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionManagerImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionManagerImpl.java index 3b4dea6db..8fddcfce5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionManagerImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionManagerImpl.java @@ -1,148 +1,148 @@ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; -import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSIONS; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtension; -import org.xmind.core.internal.WorkbookExtensionManager; -import org.xmind.core.util.DOMUtils; - -/** - * @author Jason Wong - */ -public class WorkbookExtensionManagerImpl extends WorkbookExtensionManager { - - private WorkbookImpl ownedWorkbook; - - private Map extensions = new HashMap(); - - public WorkbookExtensionManagerImpl() { - } - - protected void setOwnedWorkbook(WorkbookImpl ownedWorkbook) { - this.ownedWorkbook = ownedWorkbook; - } - - public IWorkbook getOwnedWorkbook() { - return ownedWorkbook; - } - - public IWorkbookExtension createExtension(String providerName) { - return createExtension(providerName, null); - } - - protected IWorkbookExtension createExtension(String providerName, - Document doc) { - if (providerName == null || "".equals(providerName)) //$NON-NLS-1$ - return null; - - IWorkbookExtension ext = extensions.get(providerName); - if (ext == null) { - if (doc == null) - doc = createExtensionDocument(providerName); - ensureExtensionElement(providerName); - ensureFileEntry(providerName); - - ext = new WorkbookExtensionImpl(doc, ownedWorkbook); - extensions.put(providerName, (WorkbookExtensionImpl) ext); - ((WorkbookExtensionImpl) ext).addNotify(ownedWorkbook); - ownedWorkbook.updateModificationInfo(); - } - return ext; - } - - private void ensureExtensionElement(String provider) { - Element extsEle = DOMUtils.ensureChildElement(getWorkbookElement(), - TAG_EXTENSIONS); - Element[] es = DOMUtils.getChildElementsByTag(extsEle, TAG_EXTENSION); - for (Element e : es) { - if (provider.equals(e.getAttribute(// - ATTR_PROVIDER))) - return; - } - - Element e = DOMUtils.createElement(extsEle, TAG_EXTENSION); - e.setAttribute(ATTR_PROVIDER, provider); - } - - private Document createExtensionDocument(String provider) { - Document doc = DOMUtils.createDocument(getExtensionTag(provider)); - doc.getDocumentElement().setAttribute(ATTR_PROVIDER, provider); - return doc; - } - - private void ensureFileEntry(String provider) { - IManifest m = ownedWorkbook.getManifest(); - String path = PATH_EXTENSIONS + provider + ".xml";//$NON-NLS-1$ - IFileEntry entry = m.getFileEntry(path); - if (entry == null) { - m.createFileEntry(path).increaseReference(); - } - } - - private Element getWorkbookElement() { - return ownedWorkbook.getWorkbookElement(); - } - - private String getExtensionTag(String providerName) { - if (providerName.contains(".")) { //$NON-NLS-1$ - int index = providerName.lastIndexOf("."); //$NON-NLS-1$ - if (index > 0 && index < providerName.length()) - return providerName.substring(index + 1); - } - return providerName; - } - - public List getExtensions() { - return new ArrayList(extensions.values()); - } - - public IWorkbookExtension getExtension(String provider) { - if (provider != null && !"".equals(provider)) { //$NON-NLS-1$ - for (IWorkbookExtension e : getExtensions()) { - if (provider.equals(e.getProviderName())) - return e; - } - } - return null; - } - - public void deleteExtension(String providerName) { - // TODO Auto-generated method stub - } - - public List getProviders() { - Element es = DOMUtils.getFirstChildElementByTag(getWorkbookElement(), - TAG_EXTENSIONS); - if (es != null) { - Element[] eles = DOMUtils.getChildElementsByTag(es, TAG_EXTENSION); - List providers = new ArrayList(); - for (Element ele : eles) { - String provider = ele.getAttribute(ATTR_PROVIDER); - if (provider != null && !"".equals(provider)) { //$NON-NLS-1$ - providers.add(provider); - } - } - return providers; - } - return Collections.emptyList(); - } - - public boolean isOrphan() { - return false; - } - -} +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; +import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_EXTENSIONS; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_EXTENSIONS; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtension; +import org.xmind.core.internal.WorkbookExtensionManager; +import org.xmind.core.util.DOMUtils; + +/** + * @author Jason Wong + */ +public class WorkbookExtensionManagerImpl extends WorkbookExtensionManager { + + private WorkbookImpl ownedWorkbook; + + private Map extensions = new HashMap(); + + public WorkbookExtensionManagerImpl() { + } + + protected void setOwnedWorkbook(WorkbookImpl ownedWorkbook) { + this.ownedWorkbook = ownedWorkbook; + } + + public IWorkbook getOwnedWorkbook() { + return ownedWorkbook; + } + + public IWorkbookExtension createExtension(String providerName) { + return createExtension(providerName, null); + } + + protected IWorkbookExtension createExtension(String providerName, + Document doc) { + if (providerName == null || "".equals(providerName)) //$NON-NLS-1$ + return null; + + IWorkbookExtension ext = extensions.get(providerName); + if (ext == null) { + if (doc == null) + doc = createExtensionDocument(providerName); + ensureExtensionElement(providerName); + ensureFileEntry(providerName); + + ext = new WorkbookExtensionImpl(doc, ownedWorkbook); + extensions.put(providerName, (WorkbookExtensionImpl) ext); + ((WorkbookExtensionImpl) ext).addNotify(ownedWorkbook); + ownedWorkbook.updateModificationInfo(); + } + return ext; + } + + private void ensureExtensionElement(String provider) { + Element extsEle = DOMUtils.ensureChildElement(getWorkbookElement(), + TAG_EXTENSIONS); + Element[] es = DOMUtils.getChildElementsByTag(extsEle, TAG_EXTENSION); + for (Element e : es) { + if (provider.equals(e.getAttribute(// + ATTR_PROVIDER))) + return; + } + + Element e = DOMUtils.createElement(extsEle, TAG_EXTENSION); + e.setAttribute(ATTR_PROVIDER, provider); + } + + private Document createExtensionDocument(String provider) { + Document doc = DOMUtils.createDocument(getExtensionTag(provider)); + doc.getDocumentElement().setAttribute(ATTR_PROVIDER, provider); + return doc; + } + + private void ensureFileEntry(String provider) { + IManifest m = ownedWorkbook.getManifest(); + String path = PATH_EXTENSIONS + provider + ".xml";//$NON-NLS-1$ + IFileEntry entry = m.getFileEntry(path); + if (entry == null) { + m.createFileEntry(path).increaseReference(); + } + } + + private Element getWorkbookElement() { + return ownedWorkbook.getWorkbookElement(); + } + + private String getExtensionTag(String providerName) { + if (providerName.contains(".")) { //$NON-NLS-1$ + int index = providerName.lastIndexOf("."); //$NON-NLS-1$ + if (index > 0 && index < providerName.length()) + return providerName.substring(index + 1); + } + return providerName; + } + + public List getExtensions() { + return new ArrayList(extensions.values()); + } + + public IWorkbookExtension getExtension(String provider) { + if (provider != null && !"".equals(provider)) { //$NON-NLS-1$ + for (IWorkbookExtension e : getExtensions()) { + if (provider.equals(e.getProviderName())) + return e; + } + } + return null; + } + + public void deleteExtension(String providerName) { + // TODO Auto-generated method stub + } + + public List getProviders() { + Element es = DOMUtils.getFirstChildElementByTag(getWorkbookElement(), + TAG_EXTENSIONS); + if (es != null) { + Element[] eles = DOMUtils.getChildElementsByTag(es, TAG_EXTENSION); + List providers = new ArrayList(); + for (Element ele : eles) { + String provider = ele.getAttribute(ATTR_PROVIDER); + if (provider != null && !"".equals(provider)) { //$NON-NLS-1$ + providers.add(provider); + } + } + return providers; + } + return Collections.emptyList(); + } + + public boolean isOrphan() { + return false; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookImpl.java index b0db14360..5010095b6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookImpl.java @@ -1,843 +1,843 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; -import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REF; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; -import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REF; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARY; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; -import static org.xmind.core.internal.dom.DOMConstants.TAG_WORKBOOK; -import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collection; -import java.util.List; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IBoundary; -import org.xmind.core.ICloneData; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.INotes; -import org.xmind.core.INotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.IResourceRef; -import org.xmind.core.IRevisionRepository; -import org.xmind.core.ISerializer; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbookComponentRefManager; -import org.xmind.core.IWorkbookExtensionManager; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.Workbook; -import org.xmind.core.internal.event.CoreEventSupport; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.IMarkerRefCounter; -import org.xmind.core.util.IStyleRefCounter; - -/** - * @author briansun - */ -public class WorkbookImpl extends Workbook - implements ICoreEventSource, ICoreEventSource2, INodeAdaptableFactory { - - private Document implementation; - - private ManifestImpl manifest; - - private NodeAdaptableRegistry adaptableRegistry; - - private CoreEventSupport coreEventSupport = null; - - private StyleSheetImpl styleSheet = null; - - private MarkerSheetImpl markerSheet = null; - - private MetaImpl meta = null; - - private CommentManagerImpl commentManager = null; - - private WorkbookMarkerRefCounter markerRefCounter = null; - - private WorkbookStyleRefCounter styleRefCounter = null; - - private WorkbookComponentRefCounter elementRefCounter = null; - - private RevisionRepositoryImpl revisionRepository = null; - - private WorkbookExtensionManagerImpl extensionManager; - - /** - * @param implementation - */ - public WorkbookImpl(Document implementation, IStorage storage) { - this(implementation, - new ManifestImpl(DOMUtils.createDocument(), storage)); - } - - /** - * @param implementation - * @param manifest - */ - public WorkbookImpl(Document implementation, ManifestImpl manifest) { - this.implementation = implementation; - this.manifest = manifest; - this.adaptableRegistry = new NodeAdaptableRegistry(implementation, - this); - init(); - } - - private void init() { - manifest.setWorkbook(this); - manifest.createFileEntry(CONTENT_XML, Core.MEDIA_TYPE_TEXT_XML) - .increaseReference(); - manifest.createFileEntry(META_XML, Core.MEDIA_TYPE_TEXT_XML) - .increaseReference(); - - Element w = DOMUtils.ensureChildElement(implementation, TAG_WORKBOOK); - NS.setNS(NS.XMAP, w, NS.Xhtml, NS.Xlink, NS.SVG, NS.Fo); - if (!DOMUtils.childElementIterByTag(w, TAG_SHEET).hasNext()) - addSheet(createSheet()); - InternalDOMUtils.addVersion(implementation); - - ICoreEventListener eventHook = new ICoreEventListener() { - public void handleCoreEvent(CoreEvent event) { - handleMarkerSheetEvent(event); - } - }; - ICoreEventSupport eventSupport = getCoreEventSupport(); - eventSupport.registerGlobalListener(Core.MarkerAdd, eventHook); - eventSupport.registerGlobalListener(Core.MarkerRemove, eventHook); - eventSupport.registerGlobalListener(Core.MarkerGroupAdd, eventHook); - eventSupport.registerGlobalListener(Core.MarkerGroupRemove, eventHook); - } - - /** - * NOTE: This is not a public API. - * - * @return the implementation - */ - public Document getImplementation() { - return implementation; - } - - /** - * NOTE: This is not a public API. - * - * @return the storage - */ - public IStorage getStorage() { - return manifest.getStorage(); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookImpl)) - return false; - WorkbookImpl that = (WorkbookImpl) obj; - return implementation == that.implementation; - } - - @Override - public int hashCode() { - return implementation.hashCode(); - } - - public String toString() { - if (getStorage() != null) { - return "Workbook{" + hashCode() + ";path:" //$NON-NLS-1$//$NON-NLS-2$ - + getStorage().getFullPath() + "}"; //$NON-NLS-1$ - } - return "Workbook{" + hashCode() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public T getAdapter(Class adapter) { - if (IStorage.class.equals(adapter)) - return adapter.cast(getStorage()); - if (IEntryStreamNormalizer.class.equals(adapter)) - return adapter.cast(manifest.getStreamNormalizer()); - if (ICoreEventSource.class.equals(adapter)) - return adapter.cast(this); - if (adapter.isAssignableFrom(Document.class)) - return adapter.cast(implementation); - if (adapter.isAssignableFrom(Element.class)) - return adapter.cast(getWorkbookElement()); - if (IMarkerSheet.class.equals(adapter)) - return adapter.cast(getMarkerSheet()); - if (IManifest.class.equals(adapter)) - return adapter.cast(getManifest()); - if (ICoreEventSupport.class.equals(adapter)) - return adapter.cast(getCoreEventSupport()); - if (INodeAdaptableFactory.class.equals(adapter)) - return adapter.cast(this); - if (INodeAdaptableProvider.class.equals(adapter)) - return adapter.cast(getAdaptableRegistry()); - if (IMarkerRefCounter.class.equals(adapter)) - return adapter.cast(getMarkerRefCounter()); - if (IStyleRefCounter.class.equals(adapter)) - return adapter.cast(getStyleRefCounter()); - if (IWorkbookComponentRefManager.class.equals(adapter)) - return adapter.cast(getElementRefCounter()); - if (IRevisionRepository.class.equals(adapter)) - return adapter.cast(getRevisionRepository()); - if (IWorkbookExtensionManager.class.equals(adapter)) - return adapter.cast(getWorkbookExtensionManager()); - return super.getAdapter(adapter); - } - - /** - * @return - */ - protected Element getWorkbookElement() { - return implementation.getDocumentElement(); - } - - /** - * @return the adaptableRegistry - */ - public NodeAdaptableRegistry getAdaptableRegistry() { - return adaptableRegistry; - } - - /** - * @see org.xmind.core.IWorkbook#createTopic() - */ - public ITopic createTopic() { - TopicImpl topic = new TopicImpl(implementation.createElement(TAG_TOPIC), - this); - getAdaptableRegistry().registerByNode(topic, topic.getImplementation()); - return topic; - } - - /** - * @see org.xmind.core.IWorkbook#createSheet() - */ - public ISheet createSheet() { - SheetImpl sheet = new SheetImpl(implementation.createElement(TAG_SHEET), - this); - getAdaptableRegistry().registerByNode(sheet, sheet.getImplementation()); - return sheet; - } - - /** - * @see org.xmind.core.IWorkbook#createRelationship() - */ - public IRelationship createRelationship() { - RelationshipImpl relationship = new RelationshipImpl( - implementation.createElement(TAG_RELATIONSHIP), this); - getAdaptableRegistry().registerByNode(relationship, - relationship.getImplementation()); - return relationship; - } - - /** - * @see org.xmind.core.IWorkbook#createRelationship(org.xmind.core.ITopic, - * org.xmind.core.ITopic) - */ - public IRelationship createRelationship(IRelationshipEnd end1, - IRelationshipEnd end2) { - ISheet sheet = end1.getOwnedSheet(); - IRelationship rel = createRelationship(); - rel.setEnd1Id(end1.getId()); - rel.setEnd2Id(end2.getId()); - sheet.addRelationship(rel); - return rel; - } - - public IBoundary createBoundary() { - BoundaryImpl boundary = new BoundaryImpl( - implementation.createElement(TAG_BOUNDARY), this); - getAdaptableRegistry().registerByNode(boundary, - boundary.getImplementation()); - return boundary; - } - - public ISummary createSummary() { - SummaryImpl summary = new SummaryImpl( - implementation.createElement(TAG_SUMMARY), this); - getAdaptableRegistry().registerByNode(summary, - summary.getImplementation()); - return summary; - } - - public INotesContent createNotesContent(String format) { - Element e = implementation.createElement(format); - INotesContent content; - if (INotes.HTML.equals(format)) { - content = new HtmlNotesContentImpl(e, this); - } else { - content = new PlainNotesContentImpl(e, this); - } - getAdaptableRegistry().registerByNode(content, e); - return content; - } - - public String getVersion() { - return DOMUtils.getAttribute(getWorkbookElement(), ATTR_VERSION); - } - - /** - * @see org.xmind.core.IWorkbook#getSheets() - */ - public List getSheets() { - return DOMUtils.getChildList(getWorkbookElement(), TAG_SHEET, - getAdaptableRegistry()); - } - - public SheetImpl getPrimarySheet() { - Element e = DOMUtils.getFirstChildElementByTag(getWorkbookElement(), - TAG_SHEET); - if (e != null) - return (SheetImpl) getAdaptableRegistry().getAdaptable(e); - return null; - } - - public void addSheet(ISheet sheet, int index) { - Element s = ((SheetImpl) sheet).getImplementation(); - if (s != null && s.getOwnerDocument() == implementation) { - Element w = getWorkbookElement(); - Node n = null; - Element[] es = DOMUtils.getChildElementsByTag(w, TAG_SHEET); - if (index >= 0 && index < es.length) { - n = w.insertBefore(s, es[index]); - } else { - n = w.appendChild(s); - } - if (n != null) { - ((SheetImpl) sheet).addNotify(this); - fireIndexedTargetChange(Core.SheetAdd, sheet, sheet.getIndex()); - updateModificationInfo(); - } - } - } - - public void removeSheet(ISheet sheet) { - Element s = ((SheetImpl) sheet).getImplementation(); - Element w = getWorkbookElement(); - if (s != null && s.getParentNode() == w) { - int oldIndex = sheet.getIndex(); - ((SheetImpl) sheet).removeNotify(this); - Node n = w.removeChild(s); - if (n != null) { - fireIndexedTargetChange(Core.SheetRemove, sheet, oldIndex); - updateModificationInfo(); - } - } - } - - public void moveSheet(int sourceIndex, int targetIndex) { - if (sourceIndex < 0 || sourceIndex == targetIndex) - return; - Element w = getWorkbookElement(); - Element[] ss = DOMUtils.getChildElementsByTag(w, TAG_SHEET); - if (sourceIndex >= ss.length) - return; - Element s = ss[sourceIndex]; - if (targetIndex >= 0 && targetIndex < ss.length - 1) { - int realTargetIndex = sourceIndex < targetIndex ? targetIndex + 1 - : targetIndex; - Element target = ss[realTargetIndex]; - if (s != target) { - w.removeChild(s); - w.insertBefore(s, target); - } - } else { - w.removeChild(s); - w.appendChild(s); - targetIndex = ss.length - 1; - } - if (sourceIndex != targetIndex) { - fireIndexedTargetChange(Core.SheetMove, - getAdaptableRegistry().getAdaptable(s), sourceIndex); - updateModificationInfo(); - } - } - - public StyleSheetImpl getStyleSheet() { - if (styleSheet == null) - setStyleSheet(createStyleSheet()); - return styleSheet; - } - - public void setStyleSheet(StyleSheetImpl styleSheet) { - StyleSheetImpl oldStyleSheet = this.styleSheet; - if (styleSheet == oldStyleSheet) - return; - - if (oldStyleSheet != null) { - oldStyleSheet.getCoreEventSupport().setParent(null); - } - this.styleSheet = styleSheet; - if (styleSheet != null) { - styleSheet.getCoreEventSupport().setParent(getCoreEventSupport()); - } - } - - protected StyleSheetImpl createStyleSheet() { - StyleSheetImpl ss = (StyleSheetImpl) Core.getStyleSheetBuilder() - .createStyleSheet(); - getManifest().createFileEntry(STYLES_XML, Core.MEDIA_TYPE_TEXT_XML) - .increaseReference(); - ss.setManifest(getManifest()); - return ss; - } - - public ManifestImpl getManifest() { - return manifest; - } - - public MarkerSheetImpl getMarkerSheet() { - if (markerSheet == null) - setMarkerSheet(createMarkerSheet()); - return markerSheet; - } - - protected MarkerSheetImpl createMarkerSheet() { - MarkerSheetImpl ms = (MarkerSheetImpl) Core.getMarkerSheetBuilder() - .createMarkerSheet(new WorkbookMarkerResourceProvider(this)); - ms.setManifest(getManifest()); - return ms; - } - - public void setMarkerSheet(MarkerSheetImpl markerSheet) { - MarkerSheetImpl oldMarkerSheet = this.markerSheet; - if (markerSheet == oldMarkerSheet) - return; - - if (oldMarkerSheet != null) { - oldMarkerSheet.getCoreEventSupport().setParent(null); - for (IMarkerGroup oldMarkerGroup : oldMarkerSheet - .getMarkerGroups()) { - handleMarkerGroupManagement(oldMarkerGroup, false); - } - } - this.markerSheet = markerSheet; - if (markerSheet != null) { - for (IMarkerGroup newMarkerGroup : markerSheet.getMarkerGroups()) { - handleMarkerGroupManagement(newMarkerGroup, true); - } - markerSheet.getCoreEventSupport().setParent(getCoreEventSupport()); - } - } - - public MetaImpl getMeta() { - if (meta == null) { - meta = createMeta(); - } - return meta; - } - - private MetaImpl createMeta() { - Document metaImpl = DOMUtils.createDocument(); - MetaImpl meta = new MetaImpl(metaImpl); - meta.setOwnedWorkbook(this); - return meta; - } - - public void setMeta(MetaImpl meta) { - if (meta == null) - throw new IllegalArgumentException("Meta is null"); //$NON-NLS-1$ - MetaImpl oldMeta = this.meta; - this.meta = meta; - if (oldMeta != null) { - oldMeta.setOwnedWorkbook(null); - } - meta.setOwnedWorkbook(this); - } - - protected WorkbookMarkerRefCounter getMarkerRefCounter() { - if (markerRefCounter == null) - markerRefCounter = new WorkbookMarkerRefCounter(this); - return markerRefCounter; - } - - protected WorkbookStyleRefCounter getStyleRefCounter() { - if (styleRefCounter == null) { - styleRefCounter = new WorkbookStyleRefCounter( - (StyleSheetImpl) getStyleSheet(), manifest); - } - return styleRefCounter; - } - - protected WorkbookComponentRefCounter getElementRefCounter() { - if (elementRefCounter == null) { - elementRefCounter = new WorkbookComponentRefCounter(this); - } - return elementRefCounter; - } - - public IRevisionRepository getRevisionRepository() { - if (revisionRepository == null) { - revisionRepository = new RevisionRepositoryImpl(this); - } - return revisionRepository; - } - - public ICloneData clone(Collection sources) { - return WorkbookUtilsImpl.clone(this, sources, null); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbook#importElement(org.xmind.core.IAdaptable) - */ - public IAdaptable importElement(IAdaptable source) { - Node node = (Node) source.getAdapter(Node.class); - if (node == null) - return null; - Node ele = getImplementation().importNode(node, true); - return getAdaptableRegistry().getAdaptable(ele); - } - - public IResourceRef createResourceRef(String resourceType, - String resourceId) { - Element ele = implementation.createElement(TAG_RESOURCE_REF); - ele.setAttribute(ATTR_TYPE, resourceType); - ele.setAttribute(ATTR_RESOURCE_ID, resourceId); - ResourceRefImpl ref = new ResourceRefImpl(ele, this); - getAdaptableRegistry().registerByNode(ref, ele); - return ref; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbook#findElementById(java.lang.String, - * org.xmind.core.IAdaptable) - */ - public Object findElement(String id, IAdaptable source) { - Node node = source == null ? null - : (Node) source.getAdapter(Node.class); - if (node == null) - node = getImplementation(); - return getAdaptableRegistry().getAdaptable(id, - DOMUtils.getOwnerDocument(node)); - } - - public IAdaptable createAdaptable(Node node) { - if (node instanceof Element) { - Element e = (Element) node; - String tagName = e.getNodeName(); - if (TAG_SHEET.equals(tagName)) { - return new SheetImpl(e, this); - } else if (TAG_TOPIC.equals(tagName)) { - return new TopicImpl(e, this); - } else if (TAG_RELATIONSHIP.equals(tagName)) { - return new RelationshipImpl(e, this); - } else if (TAG_MARKER_REF.equals(tagName)) { - return new MarkerRefImpl(e, this); - } else if (TAG_BOUNDARY.equals(tagName)) { - return new BoundaryImpl(e, this); - } else if (TAG_SUMMARY.equals(tagName)) { - return new SummaryImpl(e, this); - } else if (TAG_RESOURCE_REF.equals(tagName)) { - return new ResourceRefImpl(e, this); - } - Node p = node.getParentNode(); - if (p != null && p instanceof Element) { - String parentName = p.getNodeName(); - if (DOMConstants.TAG_NOTES.equals(parentName)) { - String format = tagName; - if (INotes.HTML.equals(format)) { - return new HtmlNotesContentImpl(e, this); - } else if (INotes.PLAIN.equals(format)) { - return new PlainNotesContentImpl(e, this); - } - } - } - } - return null; - } - - public ICoreEventSupport getCoreEventSupport() { - if (coreEventSupport == null) - coreEventSupport = new CoreEventSupport(); - return coreEventSupport; - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerCoreEventListener(this, type, - listener); - } - - public ICoreEventRegistration registerOnceCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerOnceCoreEventListener(this, type, - listener); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.event.ICoreEventSource2#hasOnceListeners(java.lang.String) - */ - public boolean hasOnceListeners(String type) { - return coreEventSupport != null - && coreEventSupport.hasOnceListeners(this, type); - } - - private void fireIndexedTargetChange(String type, Object target, - int index) { - if (coreEventSupport != null) { - coreEventSupport.dispatchIndexedTargetChange(this, type, target, - index); - } - } - - /** - * @deprecated - */ - @Deprecated - public synchronized void save() throws IOException, CoreException { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public synchronized void save(final String file) - throws IOException, CoreException { - FileOutputStream stream = new FileOutputStream(file); - try { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(this); - serializer.setOutputStream(stream); - serializer.serialize(null); - } finally { - stream.close(); - } - } - - /** - * @deprecated - */ - @Deprecated - public synchronized void save(final IOutputTarget target) - throws IOException, CoreException { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(this); - serializer.setOutputTarget(target); - serializer.serialize(null); - } - - /** - * @deprecated - */ - @Deprecated - public synchronized void save(final OutputStream output) - throws IOException, CoreException { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(this); - serializer.setOutputStream(output); - serializer.serialize(null); - } - - /** - * @deprecated - */ - @Deprecated - public void setTempStorage(IStorage storage) { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public IStorage getTempStorage() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public String getFile() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public void setFile(String file) { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public boolean isSkipRevisionsWhenSaving() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public String getTempLocation() { - throw new UnsupportedOperationException(); - } - - /** - * @deprecated - */ - @Deprecated - public void setTempLocation(String tempLocation) { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbook#setPassword(java.lang.String) - */ - @Deprecated - public void setPassword(String password) { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbook#getPassword() - */ - @Deprecated - public String getPassword() { - throw new UnsupportedOperationException(); - } - - @Deprecated - public void saveTemp() throws IOException, CoreException { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(this); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.serialize(null); - } - - public long getModifiedTime() { - return InternalDOMUtils.getModifiedTime(this, getWorkbookElement()); - } - - public String getModifiedBy() { - return InternalDOMUtils.getModifiedBy(this, getWorkbookElement()); - } - - protected void updateModificationInfo() { - InternalDOMUtils.updateModificationInfo(this); - } - - /* - * (non-Javadoc) - * @see org.xmind.core.IWorkbook#getCommentManager() - */ - public org.xmind.core.ICommentManager getCommentManager() { - if (commentManager == null) { - commentManager = createCommentManager(); - } - return commentManager; - } - - /** - * @return - */ - private CommentManagerImpl createCommentManager() { - return new CommentManagerImpl(this, DOMUtils.createDocument()); - } - - public void setCommentManager(CommentManagerImpl commentManager) { - this.commentManager = commentManager; - } - - private void handleMarkerSheetEvent(CoreEvent event) { - String type = event.getType(); - if (Core.MarkerAdd.equals(type)) { - handleMarkerManagement((IMarker) event.getTarget(), true); - } else if (Core.MarkerRemove.equals(type)) { - handleMarkerManagement((IMarker) event.getTarget(), false); - } else if (Core.MarkerGroupAdd.equals(type)) { - handleMarkerGroupManagement((IMarkerGroup) event.getTarget(), true); - } else if (Core.MarkerGroupRemove.equals(type)) { - handleMarkerGroupManagement((IMarkerGroup) event.getTarget(), - false); - } - } - - /** - * @param marker - */ - private void handleMarkerManagement(IMarker marker, boolean added) { - String path = marker.getResourcePath(); - if (path == null || "".equals(path)) //$NON-NLS-1$ - return; - - IFileEntry entry = getManifest() - .getFileEntry(ArchiveConstants.PATH_MARKERS + path); - if (entry == null) - return; - - if (added) { - entry.increaseReference(); - } else { - entry.decreaseReference(); - } - } - - private void handleMarkerGroupManagement(IMarkerGroup group, - boolean added) { - for (IMarker marker : group.getMarkers()) { - handleMarkerManagement(marker, added); - } - } - - private IWorkbookExtensionManager getWorkbookExtensionManager() { - if (extensionManager == null) { - extensionManager = new WorkbookExtensionManagerImpl(); - extensionManager.setOwnedWorkbook(this); - } - return extensionManager; - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_VERSION; +import static org.xmind.core.internal.dom.DOMConstants.TAG_BOUNDARY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_MARKER_REF; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP; +import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REF; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SUMMARY; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; +import static org.xmind.core.internal.dom.DOMConstants.TAG_WORKBOOK; +import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; +import java.util.List; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IBoundary; +import org.xmind.core.ICloneData; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.INotes; +import org.xmind.core.INotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.IResourceRef; +import org.xmind.core.IRevisionRepository; +import org.xmind.core.ISerializer; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbookComponentRefManager; +import org.xmind.core.IWorkbookExtensionManager; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.Workbook; +import org.xmind.core.internal.event.CoreEventSupport; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.IMarkerRefCounter; +import org.xmind.core.util.IStyleRefCounter; + +/** + * @author briansun + */ +public class WorkbookImpl extends Workbook + implements ICoreEventSource, ICoreEventSource2, INodeAdaptableFactory { + + private Document implementation; + + private ManifestImpl manifest; + + private NodeAdaptableRegistry adaptableRegistry; + + private CoreEventSupport coreEventSupport = null; + + private StyleSheetImpl styleSheet = null; + + private MarkerSheetImpl markerSheet = null; + + private MetaImpl meta = null; + + private CommentManagerImpl commentManager = null; + + private WorkbookMarkerRefCounter markerRefCounter = null; + + private WorkbookStyleRefCounter styleRefCounter = null; + + private WorkbookComponentRefCounter elementRefCounter = null; + + private RevisionRepositoryImpl revisionRepository = null; + + private WorkbookExtensionManagerImpl extensionManager; + + /** + * @param implementation + */ + public WorkbookImpl(Document implementation, IStorage storage) { + this(implementation, + new ManifestImpl(DOMUtils.createDocument(), storage)); + } + + /** + * @param implementation + * @param manifest + */ + public WorkbookImpl(Document implementation, ManifestImpl manifest) { + this.implementation = implementation; + this.manifest = manifest; + this.adaptableRegistry = new NodeAdaptableRegistry(implementation, + this); + init(); + } + + private void init() { + manifest.setWorkbook(this); + manifest.createFileEntry(CONTENT_XML, Core.MEDIA_TYPE_TEXT_XML) + .increaseReference(); + manifest.createFileEntry(META_XML, Core.MEDIA_TYPE_TEXT_XML) + .increaseReference(); + + Element w = DOMUtils.ensureChildElement(implementation, TAG_WORKBOOK); + NS.setNS(NS.XMAP, w, NS.Xhtml, NS.Xlink, NS.SVG, NS.Fo); + if (!DOMUtils.childElementIterByTag(w, TAG_SHEET).hasNext()) + addSheet(createSheet()); + InternalDOMUtils.addVersion(implementation); + + ICoreEventListener eventHook = new ICoreEventListener() { + public void handleCoreEvent(CoreEvent event) { + handleMarkerSheetEvent(event); + } + }; + ICoreEventSupport eventSupport = getCoreEventSupport(); + eventSupport.registerGlobalListener(Core.MarkerAdd, eventHook); + eventSupport.registerGlobalListener(Core.MarkerRemove, eventHook); + eventSupport.registerGlobalListener(Core.MarkerGroupAdd, eventHook); + eventSupport.registerGlobalListener(Core.MarkerGroupRemove, eventHook); + } + + /** + * NOTE: This is not a public API. + * + * @return the implementation + */ + public Document getImplementation() { + return implementation; + } + + /** + * NOTE: This is not a public API. + * + * @return the storage + */ + public IStorage getStorage() { + return manifest.getStorage(); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookImpl)) + return false; + WorkbookImpl that = (WorkbookImpl) obj; + return implementation == that.implementation; + } + + @Override + public int hashCode() { + return implementation.hashCode(); + } + + public String toString() { + if (getStorage() != null) { + return "Workbook{" + hashCode() + ";path:" //$NON-NLS-1$//$NON-NLS-2$ + + getStorage().getFullPath() + "}"; //$NON-NLS-1$ + } + return "Workbook{" + hashCode() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public T getAdapter(Class adapter) { + if (IStorage.class.equals(adapter)) + return adapter.cast(getStorage()); + if (IEntryStreamNormalizer.class.equals(adapter)) + return adapter.cast(manifest.getStreamNormalizer()); + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Document.class)) + return adapter.cast(implementation); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getWorkbookElement()); + if (IMarkerSheet.class.equals(adapter)) + return adapter.cast(getMarkerSheet()); + if (IManifest.class.equals(adapter)) + return adapter.cast(getManifest()); + if (ICoreEventSupport.class.equals(adapter)) + return adapter.cast(getCoreEventSupport()); + if (INodeAdaptableFactory.class.equals(adapter)) + return adapter.cast(this); + if (INodeAdaptableProvider.class.equals(adapter)) + return adapter.cast(getAdaptableRegistry()); + if (IMarkerRefCounter.class.equals(adapter)) + return adapter.cast(getMarkerRefCounter()); + if (IStyleRefCounter.class.equals(adapter)) + return adapter.cast(getStyleRefCounter()); + if (IWorkbookComponentRefManager.class.equals(adapter)) + return adapter.cast(getElementRefCounter()); + if (IRevisionRepository.class.equals(adapter)) + return adapter.cast(getRevisionRepository()); + if (IWorkbookExtensionManager.class.equals(adapter)) + return adapter.cast(getWorkbookExtensionManager()); + return super.getAdapter(adapter); + } + + /** + * @return + */ + protected Element getWorkbookElement() { + return implementation.getDocumentElement(); + } + + /** + * @return the adaptableRegistry + */ + public NodeAdaptableRegistry getAdaptableRegistry() { + return adaptableRegistry; + } + + /** + * @see org.xmind.core.IWorkbook#createTopic() + */ + public ITopic createTopic() { + TopicImpl topic = new TopicImpl(implementation.createElement(TAG_TOPIC), + this); + getAdaptableRegistry().registerByNode(topic, topic.getImplementation()); + return topic; + } + + /** + * @see org.xmind.core.IWorkbook#createSheet() + */ + public ISheet createSheet() { + SheetImpl sheet = new SheetImpl(implementation.createElement(TAG_SHEET), + this); + getAdaptableRegistry().registerByNode(sheet, sheet.getImplementation()); + return sheet; + } + + /** + * @see org.xmind.core.IWorkbook#createRelationship() + */ + public IRelationship createRelationship() { + RelationshipImpl relationship = new RelationshipImpl( + implementation.createElement(TAG_RELATIONSHIP), this); + getAdaptableRegistry().registerByNode(relationship, + relationship.getImplementation()); + return relationship; + } + + /** + * @see org.xmind.core.IWorkbook#createRelationship(org.xmind.core.ITopic, + * org.xmind.core.ITopic) + */ + public IRelationship createRelationship(IRelationshipEnd end1, + IRelationshipEnd end2) { + ISheet sheet = end1.getOwnedSheet(); + IRelationship rel = createRelationship(); + rel.setEnd1Id(end1.getId()); + rel.setEnd2Id(end2.getId()); + sheet.addRelationship(rel); + return rel; + } + + public IBoundary createBoundary() { + BoundaryImpl boundary = new BoundaryImpl( + implementation.createElement(TAG_BOUNDARY), this); + getAdaptableRegistry().registerByNode(boundary, + boundary.getImplementation()); + return boundary; + } + + public ISummary createSummary() { + SummaryImpl summary = new SummaryImpl( + implementation.createElement(TAG_SUMMARY), this); + getAdaptableRegistry().registerByNode(summary, + summary.getImplementation()); + return summary; + } + + public INotesContent createNotesContent(String format) { + Element e = implementation.createElement(format); + INotesContent content; + if (INotes.HTML.equals(format)) { + content = new HtmlNotesContentImpl(e, this); + } else { + content = new PlainNotesContentImpl(e, this); + } + getAdaptableRegistry().registerByNode(content, e); + return content; + } + + public String getVersion() { + return DOMUtils.getAttribute(getWorkbookElement(), ATTR_VERSION); + } + + /** + * @see org.xmind.core.IWorkbook#getSheets() + */ + public List getSheets() { + return DOMUtils.getChildList(getWorkbookElement(), TAG_SHEET, + getAdaptableRegistry()); + } + + public SheetImpl getPrimarySheet() { + Element e = DOMUtils.getFirstChildElementByTag(getWorkbookElement(), + TAG_SHEET); + if (e != null) + return (SheetImpl) getAdaptableRegistry().getAdaptable(e); + return null; + } + + public void addSheet(ISheet sheet, int index) { + Element s = ((SheetImpl) sheet).getImplementation(); + if (s != null && s.getOwnerDocument() == implementation) { + Element w = getWorkbookElement(); + Node n = null; + Element[] es = DOMUtils.getChildElementsByTag(w, TAG_SHEET); + if (index >= 0 && index < es.length) { + n = w.insertBefore(s, es[index]); + } else { + n = w.appendChild(s); + } + if (n != null) { + ((SheetImpl) sheet).addNotify(this); + fireIndexedTargetChange(Core.SheetAdd, sheet, sheet.getIndex()); + updateModificationInfo(); + } + } + } + + public void removeSheet(ISheet sheet) { + Element s = ((SheetImpl) sheet).getImplementation(); + Element w = getWorkbookElement(); + if (s != null && s.getParentNode() == w) { + int oldIndex = sheet.getIndex(); + ((SheetImpl) sheet).removeNotify(this); + Node n = w.removeChild(s); + if (n != null) { + fireIndexedTargetChange(Core.SheetRemove, sheet, oldIndex); + updateModificationInfo(); + } + } + } + + public void moveSheet(int sourceIndex, int targetIndex) { + if (sourceIndex < 0 || sourceIndex == targetIndex) + return; + Element w = getWorkbookElement(); + Element[] ss = DOMUtils.getChildElementsByTag(w, TAG_SHEET); + if (sourceIndex >= ss.length) + return; + Element s = ss[sourceIndex]; + if (targetIndex >= 0 && targetIndex < ss.length - 1) { + int realTargetIndex = sourceIndex < targetIndex ? targetIndex + 1 + : targetIndex; + Element target = ss[realTargetIndex]; + if (s != target) { + w.removeChild(s); + w.insertBefore(s, target); + } + } else { + w.removeChild(s); + w.appendChild(s); + targetIndex = ss.length - 1; + } + if (sourceIndex != targetIndex) { + fireIndexedTargetChange(Core.SheetMove, + getAdaptableRegistry().getAdaptable(s), sourceIndex); + updateModificationInfo(); + } + } + + public StyleSheetImpl getStyleSheet() { + if (styleSheet == null) + setStyleSheet(createStyleSheet()); + return styleSheet; + } + + public void setStyleSheet(StyleSheetImpl styleSheet) { + StyleSheetImpl oldStyleSheet = this.styleSheet; + if (styleSheet == oldStyleSheet) + return; + + if (oldStyleSheet != null) { + oldStyleSheet.getCoreEventSupport().setParent(null); + } + this.styleSheet = styleSheet; + if (styleSheet != null) { + styleSheet.getCoreEventSupport().setParent(getCoreEventSupport()); + } + } + + protected StyleSheetImpl createStyleSheet() { + StyleSheetImpl ss = (StyleSheetImpl) Core.getStyleSheetBuilder() + .createStyleSheet(); + getManifest().createFileEntry(STYLES_XML, Core.MEDIA_TYPE_TEXT_XML) + .increaseReference(); + ss.setManifest(getManifest()); + return ss; + } + + public ManifestImpl getManifest() { + return manifest; + } + + public MarkerSheetImpl getMarkerSheet() { + if (markerSheet == null) + setMarkerSheet(createMarkerSheet()); + return markerSheet; + } + + protected MarkerSheetImpl createMarkerSheet() { + MarkerSheetImpl ms = (MarkerSheetImpl) Core.getMarkerSheetBuilder() + .createMarkerSheet(new WorkbookMarkerResourceProvider(this)); + ms.setManifest(getManifest()); + return ms; + } + + public void setMarkerSheet(MarkerSheetImpl markerSheet) { + MarkerSheetImpl oldMarkerSheet = this.markerSheet; + if (markerSheet == oldMarkerSheet) + return; + + if (oldMarkerSheet != null) { + oldMarkerSheet.getCoreEventSupport().setParent(null); + for (IMarkerGroup oldMarkerGroup : oldMarkerSheet + .getMarkerGroups()) { + handleMarkerGroupManagement(oldMarkerGroup, false); + } + } + this.markerSheet = markerSheet; + if (markerSheet != null) { + for (IMarkerGroup newMarkerGroup : markerSheet.getMarkerGroups()) { + handleMarkerGroupManagement(newMarkerGroup, true); + } + markerSheet.getCoreEventSupport().setParent(getCoreEventSupport()); + } + } + + public MetaImpl getMeta() { + if (meta == null) { + meta = createMeta(); + } + return meta; + } + + private MetaImpl createMeta() { + Document metaImpl = DOMUtils.createDocument(); + MetaImpl meta = new MetaImpl(metaImpl); + meta.setOwnedWorkbook(this); + return meta; + } + + public void setMeta(MetaImpl meta) { + if (meta == null) + throw new IllegalArgumentException("Meta is null"); //$NON-NLS-1$ + MetaImpl oldMeta = this.meta; + this.meta = meta; + if (oldMeta != null) { + oldMeta.setOwnedWorkbook(null); + } + meta.setOwnedWorkbook(this); + } + + protected WorkbookMarkerRefCounter getMarkerRefCounter() { + if (markerRefCounter == null) + markerRefCounter = new WorkbookMarkerRefCounter(this); + return markerRefCounter; + } + + protected WorkbookStyleRefCounter getStyleRefCounter() { + if (styleRefCounter == null) { + styleRefCounter = new WorkbookStyleRefCounter( + (StyleSheetImpl) getStyleSheet(), manifest); + } + return styleRefCounter; + } + + protected WorkbookComponentRefCounter getElementRefCounter() { + if (elementRefCounter == null) { + elementRefCounter = new WorkbookComponentRefCounter(this); + } + return elementRefCounter; + } + + public IRevisionRepository getRevisionRepository() { + if (revisionRepository == null) { + revisionRepository = new RevisionRepositoryImpl(this); + } + return revisionRepository; + } + + public ICloneData clone(Collection sources) { + return WorkbookUtilsImpl.clone(this, sources, null); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbook#importElement(org.xmind.core.IAdaptable) + */ + public IAdaptable importElement(IAdaptable source) { + Node node = (Node) source.getAdapter(Node.class); + if (node == null) + return null; + Node ele = getImplementation().importNode(node, true); + return getAdaptableRegistry().getAdaptable(ele); + } + + public IResourceRef createResourceRef(String resourceType, + String resourceId) { + Element ele = implementation.createElement(TAG_RESOURCE_REF); + ele.setAttribute(ATTR_TYPE, resourceType); + ele.setAttribute(ATTR_RESOURCE_ID, resourceId); + ResourceRefImpl ref = new ResourceRefImpl(ele, this); + getAdaptableRegistry().registerByNode(ref, ele); + return ref; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbook#findElementById(java.lang.String, + * org.xmind.core.IAdaptable) + */ + public Object findElement(String id, IAdaptable source) { + Node node = source == null ? null + : (Node) source.getAdapter(Node.class); + if (node == null) + node = getImplementation(); + return getAdaptableRegistry().getAdaptable(id, + DOMUtils.getOwnerDocument(node)); + } + + public IAdaptable createAdaptable(Node node) { + if (node instanceof Element) { + Element e = (Element) node; + String tagName = e.getNodeName(); + if (TAG_SHEET.equals(tagName)) { + return new SheetImpl(e, this); + } else if (TAG_TOPIC.equals(tagName)) { + return new TopicImpl(e, this); + } else if (TAG_RELATIONSHIP.equals(tagName)) { + return new RelationshipImpl(e, this); + } else if (TAG_MARKER_REF.equals(tagName)) { + return new MarkerRefImpl(e, this); + } else if (TAG_BOUNDARY.equals(tagName)) { + return new BoundaryImpl(e, this); + } else if (TAG_SUMMARY.equals(tagName)) { + return new SummaryImpl(e, this); + } else if (TAG_RESOURCE_REF.equals(tagName)) { + return new ResourceRefImpl(e, this); + } + Node p = node.getParentNode(); + if (p != null && p instanceof Element) { + String parentName = p.getNodeName(); + if (DOMConstants.TAG_NOTES.equals(parentName)) { + String format = tagName; + if (INotes.HTML.equals(format)) { + return new HtmlNotesContentImpl(e, this); + } else if (INotes.PLAIN.equals(format)) { + return new PlainNotesContentImpl(e, this); + } + } + } + } + return null; + } + + public ICoreEventSupport getCoreEventSupport() { + if (coreEventSupport == null) + coreEventSupport = new CoreEventSupport(); + return coreEventSupport; + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerCoreEventListener(this, type, + listener); + } + + public ICoreEventRegistration registerOnceCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerOnceCoreEventListener(this, type, + listener); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.event.ICoreEventSource2#hasOnceListeners(java.lang.String) + */ + public boolean hasOnceListeners(String type) { + return coreEventSupport != null + && coreEventSupport.hasOnceListeners(this, type); + } + + private void fireIndexedTargetChange(String type, Object target, + int index) { + if (coreEventSupport != null) { + coreEventSupport.dispatchIndexedTargetChange(this, type, target, + index); + } + } + + /** + * @deprecated + */ + @Deprecated + public synchronized void save() throws IOException, CoreException { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public synchronized void save(final String file) + throws IOException, CoreException { + FileOutputStream stream = new FileOutputStream(file); + try { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(this); + serializer.setOutputStream(stream); + serializer.serialize(null); + } finally { + stream.close(); + } + } + + /** + * @deprecated + */ + @Deprecated + public synchronized void save(final IOutputTarget target) + throws IOException, CoreException { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(this); + serializer.setOutputTarget(target); + serializer.serialize(null); + } + + /** + * @deprecated + */ + @Deprecated + public synchronized void save(final OutputStream output) + throws IOException, CoreException { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(this); + serializer.setOutputStream(output); + serializer.serialize(null); + } + + /** + * @deprecated + */ + @Deprecated + public void setTempStorage(IStorage storage) { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public IStorage getTempStorage() { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public String getFile() { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public void setFile(String file) { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public boolean isSkipRevisionsWhenSaving() { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public String getTempLocation() { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated + */ + @Deprecated + public void setTempLocation(String tempLocation) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbook#setPassword(java.lang.String) + */ + @Deprecated + public void setPassword(String password) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbook#getPassword() + */ + @Deprecated + public String getPassword() { + throw new UnsupportedOperationException(); + } + + @Deprecated + public void saveTemp() throws IOException, CoreException { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(this); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.serialize(null); + } + + public long getModifiedTime() { + return InternalDOMUtils.getModifiedTime(this, getWorkbookElement()); + } + + public String getModifiedBy() { + return InternalDOMUtils.getModifiedBy(this, getWorkbookElement()); + } + + protected void updateModificationInfo() { + InternalDOMUtils.updateModificationInfo(this); + } + + /* + * (non-Javadoc) + * @see org.xmind.core.IWorkbook#getCommentManager() + */ + public org.xmind.core.ICommentManager getCommentManager() { + if (commentManager == null) { + commentManager = createCommentManager(); + } + return commentManager; + } + + /** + * @return + */ + private CommentManagerImpl createCommentManager() { + return new CommentManagerImpl(this, DOMUtils.createDocument()); + } + + public void setCommentManager(CommentManagerImpl commentManager) { + this.commentManager = commentManager; + } + + private void handleMarkerSheetEvent(CoreEvent event) { + String type = event.getType(); + if (Core.MarkerAdd.equals(type)) { + handleMarkerManagement((IMarker) event.getTarget(), true); + } else if (Core.MarkerRemove.equals(type)) { + handleMarkerManagement((IMarker) event.getTarget(), false); + } else if (Core.MarkerGroupAdd.equals(type)) { + handleMarkerGroupManagement((IMarkerGroup) event.getTarget(), true); + } else if (Core.MarkerGroupRemove.equals(type)) { + handleMarkerGroupManagement((IMarkerGroup) event.getTarget(), + false); + } + } + + /** + * @param marker + */ + private void handleMarkerManagement(IMarker marker, boolean added) { + String path = marker.getResourcePath(); + if (path == null || "".equals(path)) //$NON-NLS-1$ + return; + + IFileEntry entry = getManifest() + .getFileEntry(ArchiveConstants.PATH_MARKERS + path); + if (entry == null) + return; + + if (added) { + entry.increaseReference(); + } else { + entry.decreaseReference(); + } + } + + private void handleMarkerGroupManagement(IMarkerGroup group, + boolean added) { + for (IMarker marker : group.getMarkers()) { + handleMarkerManagement(marker, added); + } + } + + private IWorkbookExtensionManager getWorkbookExtensionManager() { + if (extensionManager == null) { + extensionManager = new WorkbookExtensionManagerImpl(); + extensionManager.setOwnedWorkbook(this); + } + return extensionManager; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookLoader.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookLoader.java index 141bbb74a..e1716fd03 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookLoader.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookLoader.java @@ -1,294 +1,294 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -/** - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public class WorkbookLoader { - -// private WorkbookBuilderImpl builder; -// private IStorage storage; -// private IEncryptionHandler encryptionHandler; -// -// private IInputSource source = null; -// private WorkbookImpl workbook = null; -// -// private ManifestImpl manifest = null; -// private String password = null; -// -// /** -// * -// * @param builder -// * @param source -// * @param storage -// * @param encryptionHandler -// */ -// public WorkbookLoader(WorkbookBuilderImpl builder, IStorage storage, -// IEncryptionHandler encryptionHandler) throws CoreException { -// super(); -// this.builder = builder; -// this.storage = storage; -// this.encryptionHandler = encryptionHandler; -// } -// -// public IWorkbook load() throws IOException, CoreException { -// source = storage.getInputSource(); -// password = null; -// manifest = null; -// try { -// doLoad(); -// } finally { -// manifest = null; -// password = null; -// source = null; -// } -// return workbook; -// } -// -// /** -// * The main loading process. -// * -// * @throws IOException -// * @throws CoreException -// */ -// private void doLoad() throws IOException, CoreException { -// loadManifest(); -// -// if (loadOldFormat()) -// return; -// -// loadContents(); -// loadMeta(); -// loadStyleSheet(); -// loadMarkerSheet(); -// loadComments(); -// -// initWorkbook(); -// } -// -// private void loadManifest() throws IOException, CoreException { -// Document doc = forceLoadXML(MANIFEST_XML); -// ManifestImpl manifest = new ManifestImpl(doc, null, storage); -// manifest.setEncryptionDelegate(encryptionHandler); -// this.manifest = manifest; -// } -// -// private boolean loadOldFormat() throws IOException, CoreException { -// IWorkbook compatible = Compatibility.loadCompatibleWorkbook(source, -// this, storage); -// if (compatible != null) { -// workbook = (WorkbookImpl) compatible; -// return true; -// } -// return false; -// } -// -// private void loadContents() throws IOException, CoreException { -// Document doc = loadXMLFile(source, ArchiveConstants.CONTENT_XML); -// workbook = new WorkbookImpl(doc, manifest); -// workbook.setInitialPassword(password); -// } -// -// private void loadMeta() throws IOException, CoreException { -// Document doc = forceLoadXML(ArchiveConstants.META_XML); -// MetaImpl meta = new MetaImpl(doc); -// workbook.setMeta(meta); -// if (meta.getValue(IMeta.CREATED_TIME) == null) -// meta.setValue(IMeta.CREATED_TIME, -// NumberUtils.formatDate(System.currentTimeMillis())); -// } -// -// private void loadStyleSheet() throws IOException, CoreException { -// try { -// IStyleSheet styleSheet = ((StyleSheetBuilderImpl) Core -// .getStyleSheetBuilder()).loadFromInputSource(source, this); -// ((StyleSheetImpl) styleSheet).setManifest(manifest); -// workbook.setStyleSheet((StyleSheetImpl) styleSheet); -// } catch (IOException e) { -// throw e; -// } catch (CoreException e) { -// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) -// throw e; -// } -// } -// -// private void loadMarkerSheet() throws IOException, CoreException { -// try { -// IMarkerSheet markerSheet = ((MarkerSheetBuilderImpl) Core -// .getMarkerSheetBuilder()).loadFromInputSource(source, this, -// new WorkbookMarkerResourceProvider(workbook)); -// workbook.setMarkerSheet((MarkerSheetImpl) markerSheet); -// } catch (IOException e) { -// throw e; -// } catch (CoreException e) { -// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) -// throw e; -// } -// } -// -// private void loadComments() throws IOException, CoreException { -// try { -// ICommentManager commentManager = ((CommentManagerBuilderImpl) Core -// .getCommentManagerBuilder()).loadFromInputSource(source, -// this); -// workbook.setCommentManager((CommentManagerImpl) commentManager); -// } catch (IOException e) { -// throw e; -// } catch (CoreException e) { -// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) -// throw e; -// } -// } -// -// private void initWorkbook() throws IOException, CoreException { -// // Prefetch all file entries: -// workbook.getManifest().getFileEntries(); -// initWorkbookContents(workbook); -// workbook.setInitialPassword(password); -// } -// -// private void initWorkbookContents(WorkbookImpl workbook) { -// for (ISheet s : workbook.getSheets()) { -// initSheet(s, workbook); -// } -// } -// -// private void initSheet(ISheet sheet, WorkbookImpl wb) { -// ((SheetImpl) sheet).addNotify(wb); -// -// // Prefetch all revisions of this sheet. -// workbook.getRevisionRepository().getRevisionManager(sheet.getId(), -// IRevision.SHEET); -// } -// -// private Document forceLoadXML(String entryPath) -// throws IOException, CoreException { -// try { -// return loadXMLFile(source, entryPath); -// } catch (Throwable e) { -// if (e instanceof CoreException) { -// CoreException coreEx = (CoreException) e; -// if (coreEx.getType() == Core.ERROR_WRONG_PASSWORD -// || coreEx.getType() == Core.ERROR_CANCELLATION) { -// throw coreEx; -// } -// } -// //in case the file is damaged, -// //try continue loading -// Core.getLogger().log(e, "Faild to load " + entryPath); //$NON-NLS-1$ -// return createDocument(); -// } -// } -// -// private InputStream getInputStream(IInputSource source, String entryPath) -// throws IOException, CoreException { -// if (manifest != null) { -// IFileEntry entry = manifest.getFileEntry(entryPath); -// if (entry != null) { -// return entry.openInputStream(); -// } -// } -// if (!source.hasEntry(entryPath)) -// return null; -// -// InputStream in = source.openEntryStream(entryPath); -// IEncryptionData encData = manifest.getEncryptionData(entryPath); -// if (encData != null) { -// in = createDecryptedStream(in, encData); -// } -// return in; -// } -// -// private InputStream createDecryptedStream(InputStream in, -// IEncryptionData encData) throws CoreException { -// String password = getPassword(); -// if (password == null) -// throw new CoreException(Core.ERROR_CANCELLATION); -// return Crypto.createInputStream(in, false, encData, password); -// } -// -// private String getPassword() throws CoreException { -// if (password == null) { -// if (encryptionHandler != null) { -// password = encryptionHandler.retrievePassword(); -// } -// } -// return password; -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.xmind.core.internal.dom.XMLLoader#doLoadXMLFile(org.xmind.core.io -// * .IInputSource, java.lang.String) -// */ -// protected Document doLoadXMLFile(IInputSource source, String entryPath) -// throws IOException, CoreException { -// InputStream stream = getInputStream(source, entryPath); -// if (stream == null) -// throw new CoreException(Core.ERROR_NO_SUCH_ENTRY, entryPath); -// -// Document doc; -// try { -// doc = builder.getDocumentLoader().parse(stream); -// } catch (Throwable error) { -// if (!verifyChecksum(source, entryPath, stream)) -// throw new CoreException(Core.ERROR_WRONG_PASSWORD, error); -// if (error instanceof IOException) -// throw (IOException) error; -// if (error instanceof CoreException) -// throw (CoreException) error; -// throw new CoreException(Core.ERROR_FAIL_PARSING_XML, error); -// } finally { -// stream.close(); -// } -// -// if (!verifyChecksum(source, entryPath, stream)) -// throw new CoreException(Core.ERROR_WRONG_PASSWORD); -// -// return doc; -// } -// -// private boolean verifyChecksum(IInputSource source, String entryName, -// InputStream stream) throws IOException, CoreException { -// if (stream instanceof IChecksumStream) { -// if (manifest == null) { -// throw new IllegalStateException( -// "Manifest should not be encrypted"); //$NON-NLS-1$ -// } -// IEncryptionData encData = manifest.getEncryptionData(entryName); -// if (encData != null) { -// String expectedChecksum = encData.getChecksum(); -// if (expectedChecksum != null) { -// String actualChecksum; -// actualChecksum = ((IChecksumStream) stream).getChecksum(); -// if (actualChecksum == null -// || !expectedChecksum.equals(actualChecksum)) { -// return false; -// } -// } -// } -// } -// return true; -// } -// -// public Document createDocument() { -// return builder.createDocument(); -// } -// -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +/** + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public class WorkbookLoader { + +// private WorkbookBuilderImpl builder; +// private IStorage storage; +// private IEncryptionHandler encryptionHandler; +// +// private IInputSource source = null; +// private WorkbookImpl workbook = null; +// +// private ManifestImpl manifest = null; +// private String password = null; +// +// /** +// * +// * @param builder +// * @param source +// * @param storage +// * @param encryptionHandler +// */ +// public WorkbookLoader(WorkbookBuilderImpl builder, IStorage storage, +// IEncryptionHandler encryptionHandler) throws CoreException { +// super(); +// this.builder = builder; +// this.storage = storage; +// this.encryptionHandler = encryptionHandler; +// } +// +// public IWorkbook load() throws IOException, CoreException { +// source = storage.getInputSource(); +// password = null; +// manifest = null; +// try { +// doLoad(); +// } finally { +// manifest = null; +// password = null; +// source = null; +// } +// return workbook; +// } +// +// /** +// * The main loading process. +// * +// * @throws IOException +// * @throws CoreException +// */ +// private void doLoad() throws IOException, CoreException { +// loadManifest(); +// +// if (loadOldFormat()) +// return; +// +// loadContents(); +// loadMeta(); +// loadStyleSheet(); +// loadMarkerSheet(); +// loadComments(); +// +// initWorkbook(); +// } +// +// private void loadManifest() throws IOException, CoreException { +// Document doc = forceLoadXML(MANIFEST_XML); +// ManifestImpl manifest = new ManifestImpl(doc, null, storage); +// manifest.setEncryptionDelegate(encryptionHandler); +// this.manifest = manifest; +// } +// +// private boolean loadOldFormat() throws IOException, CoreException { +// IWorkbook compatible = Compatibility.loadCompatibleWorkbook(source, +// this, storage); +// if (compatible != null) { +// workbook = (WorkbookImpl) compatible; +// return true; +// } +// return false; +// } +// +// private void loadContents() throws IOException, CoreException { +// Document doc = loadXMLFile(source, ArchiveConstants.CONTENT_XML); +// workbook = new WorkbookImpl(doc, manifest); +// workbook.setInitialPassword(password); +// } +// +// private void loadMeta() throws IOException, CoreException { +// Document doc = forceLoadXML(ArchiveConstants.META_XML); +// MetaImpl meta = new MetaImpl(doc); +// workbook.setMeta(meta); +// if (meta.getValue(IMeta.CREATED_TIME) == null) +// meta.setValue(IMeta.CREATED_TIME, +// NumberUtils.formatDate(System.currentTimeMillis())); +// } +// +// private void loadStyleSheet() throws IOException, CoreException { +// try { +// IStyleSheet styleSheet = ((StyleSheetBuilderImpl) Core +// .getStyleSheetBuilder()).loadFromInputSource(source, this); +// ((StyleSheetImpl) styleSheet).setManifest(manifest); +// workbook.setStyleSheet((StyleSheetImpl) styleSheet); +// } catch (IOException e) { +// throw e; +// } catch (CoreException e) { +// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) +// throw e; +// } +// } +// +// private void loadMarkerSheet() throws IOException, CoreException { +// try { +// IMarkerSheet markerSheet = ((MarkerSheetBuilderImpl) Core +// .getMarkerSheetBuilder()).loadFromInputSource(source, this, +// new WorkbookMarkerResourceProvider(workbook)); +// workbook.setMarkerSheet((MarkerSheetImpl) markerSheet); +// } catch (IOException e) { +// throw e; +// } catch (CoreException e) { +// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) +// throw e; +// } +// } +// +// private void loadComments() throws IOException, CoreException { +// try { +// ICommentManager commentManager = ((CommentManagerBuilderImpl) Core +// .getCommentManagerBuilder()).loadFromInputSource(source, +// this); +// workbook.setCommentManager((CommentManagerImpl) commentManager); +// } catch (IOException e) { +// throw e; +// } catch (CoreException e) { +// if (e.getType() != Core.ERROR_NO_SUCH_ENTRY) +// throw e; +// } +// } +// +// private void initWorkbook() throws IOException, CoreException { +// // Prefetch all file entries: +// workbook.getManifest().getFileEntries(); +// initWorkbookContents(workbook); +// workbook.setInitialPassword(password); +// } +// +// private void initWorkbookContents(WorkbookImpl workbook) { +// for (ISheet s : workbook.getSheets()) { +// initSheet(s, workbook); +// } +// } +// +// private void initSheet(ISheet sheet, WorkbookImpl wb) { +// ((SheetImpl) sheet).addNotify(wb); +// +// // Prefetch all revisions of this sheet. +// workbook.getRevisionRepository().getRevisionManager(sheet.getId(), +// IRevision.SHEET); +// } +// +// private Document forceLoadXML(String entryPath) +// throws IOException, CoreException { +// try { +// return loadXMLFile(source, entryPath); +// } catch (Throwable e) { +// if (e instanceof CoreException) { +// CoreException coreEx = (CoreException) e; +// if (coreEx.getType() == Core.ERROR_WRONG_PASSWORD +// || coreEx.getType() == Core.ERROR_CANCELLATION) { +// throw coreEx; +// } +// } +// //in case the file is damaged, +// //try continue loading +// Core.getLogger().log(e, "Faild to load " + entryPath); //$NON-NLS-1$ +// return createDocument(); +// } +// } +// +// private InputStream getInputStream(IInputSource source, String entryPath) +// throws IOException, CoreException { +// if (manifest != null) { +// IFileEntry entry = manifest.getFileEntry(entryPath); +// if (entry != null) { +// return entry.openInputStream(); +// } +// } +// if (!source.hasEntry(entryPath)) +// return null; +// +// InputStream in = source.openEntryStream(entryPath); +// IEncryptionData encData = manifest.getEncryptionData(entryPath); +// if (encData != null) { +// in = createDecryptedStream(in, encData); +// } +// return in; +// } +// +// private InputStream createDecryptedStream(InputStream in, +// IEncryptionData encData) throws CoreException { +// String password = getPassword(); +// if (password == null) +// throw new CoreException(Core.ERROR_CANCELLATION); +// return Crypto.createInputStream(in, false, encData, password); +// } +// +// private String getPassword() throws CoreException { +// if (password == null) { +// if (encryptionHandler != null) { +// password = encryptionHandler.retrievePassword(); +// } +// } +// return password; +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.xmind.core.internal.dom.XMLLoader#doLoadXMLFile(org.xmind.core.io +// * .IInputSource, java.lang.String) +// */ +// protected Document doLoadXMLFile(IInputSource source, String entryPath) +// throws IOException, CoreException { +// InputStream stream = getInputStream(source, entryPath); +// if (stream == null) +// throw new CoreException(Core.ERROR_NO_SUCH_ENTRY, entryPath); +// +// Document doc; +// try { +// doc = builder.getDocumentLoader().parse(stream); +// } catch (Throwable error) { +// if (!verifyChecksum(source, entryPath, stream)) +// throw new CoreException(Core.ERROR_WRONG_PASSWORD, error); +// if (error instanceof IOException) +// throw (IOException) error; +// if (error instanceof CoreException) +// throw (CoreException) error; +// throw new CoreException(Core.ERROR_FAIL_PARSING_XML, error); +// } finally { +// stream.close(); +// } +// +// if (!verifyChecksum(source, entryPath, stream)) +// throw new CoreException(Core.ERROR_WRONG_PASSWORD); +// +// return doc; +// } +// +// private boolean verifyChecksum(IInputSource source, String entryName, +// InputStream stream) throws IOException, CoreException { +// if (stream instanceof IChecksumStream) { +// if (manifest == null) { +// throw new IllegalStateException( +// "Manifest should not be encrypted"); //$NON-NLS-1$ +// } +// IEncryptionData encData = manifest.getEncryptionData(entryName); +// if (encData != null) { +// String expectedChecksum = encData.getChecksum(); +// if (expectedChecksum != null) { +// String actualChecksum; +// actualChecksum = ((IChecksumStream) stream).getChecksum(); +// if (actualChecksum == null +// || !expectedChecksum.equals(actualChecksum)) { +// return false; +// } +// } +// } +// } +// return true; +// } +// +// public Document createDocument() { +// return builder.createDocument(); +// } +// +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookMarkerResource.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookMarkerResource.java index fcc9a61f0..f8da0b800 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookMarkerResource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookMarkerResource.java @@ -1,76 +1,76 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.xmind.core.IFileEntry; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.marker.AbstractMarkerResource; -import org.xmind.core.marker.IMarker; - -public class WorkbookMarkerResource extends AbstractMarkerResource { - - private WorkbookImpl workbook; - - public WorkbookMarkerResource(WorkbookImpl workbook, IMarker marker) { - super(marker, ArchiveConstants.PATH_MARKERS); - this.workbook = workbook; - } - - /** - * @deprecated - */ - @Deprecated - public InputStream getInputStream() { - IFileEntry entry = workbook.getManifest().getFileEntry(getFullPath()); - return entry == null ? null : entry.getInputStream(); - } - - /** - * @deprecated - */ - @Deprecated - public OutputStream getOutputStream() { - IFileEntry entry = workbook.getManifest() - .createFileEntry(getFullPath()); - return entry.getOutputStream(); - } - - public InputStream openInputStream() throws IOException { - IFileEntry entry = workbook.getManifest().getFileEntry(getFullPath()); - if (entry == null) - throw new FileNotFoundException(); - return entry.openInputStream(); - } - - public OutputStream openOutputStream() throws IOException { - IFileEntry entry = workbook.getManifest() - .createFileEntry(getFullPath()); - return entry.openOutputStream(); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookMarkerResource)) - return false; - WorkbookMarkerResource that = (WorkbookMarkerResource) obj; - return this.workbook.equals(that.workbook) && super.equals(obj); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.xmind.core.IFileEntry; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.marker.AbstractMarkerResource; +import org.xmind.core.marker.IMarker; + +public class WorkbookMarkerResource extends AbstractMarkerResource { + + private WorkbookImpl workbook; + + public WorkbookMarkerResource(WorkbookImpl workbook, IMarker marker) { + super(marker, ArchiveConstants.PATH_MARKERS); + this.workbook = workbook; + } + + /** + * @deprecated + */ + @Deprecated + public InputStream getInputStream() { + IFileEntry entry = workbook.getManifest().getFileEntry(getFullPath()); + return entry == null ? null : entry.getInputStream(); + } + + /** + * @deprecated + */ + @Deprecated + public OutputStream getOutputStream() { + IFileEntry entry = workbook.getManifest() + .createFileEntry(getFullPath()); + return entry.getOutputStream(); + } + + public InputStream openInputStream() throws IOException { + IFileEntry entry = workbook.getManifest().getFileEntry(getFullPath()); + if (entry == null) + throw new FileNotFoundException(); + return entry.openInputStream(); + } + + public OutputStream openOutputStream() throws IOException { + IFileEntry entry = workbook.getManifest() + .createFileEntry(getFullPath()); + return entry.openOutputStream(); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookMarkerResource)) + return false; + WorkbookMarkerResource that = (WorkbookMarkerResource) obj; + return this.workbook.equals(that.workbook) && super.equals(obj); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookSaver.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookSaver.java index a2dc7d97e..8cb611b87 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookSaver.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookSaver.java @@ -1,489 +1,489 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; -import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_REVISIONS; -import static org.xmind.core.internal.zip.ArchiveConstants.REVISIONS_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.zip.ZipOutputStream; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.IChecksumStream; -import org.xmind.core.IEncryptionData; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.IMeta; -import org.xmind.core.IRevision; -import org.xmind.core.IRevisionManager; -import org.xmind.core.internal.InternalCore; -import org.xmind.core.internal.security.Crypto; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.internal.zip.ZipStreamOutputTarget; -import org.xmind.core.io.DirectoryOutputTarget; -import org.xmind.core.io.ICloseableOutputTarget; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; - -/** - * @author Frank Shaka - * @deprecated Use Core.getSerializerFactory().newSerializer() - */ -@Deprecated -public class WorkbookSaver { - - private static class WorkbookSaveSession { - - /** - * The workbook to save. - */ - private final WorkbookImpl workbook; - - /** - * The multi-entry output target to save to. - */ - private final IOutputTarget target; - - /** - * Entry paths that have been saved. - */ - private Set savedEntries = new HashSet(); - - /** - * DOM transformer factory, lazy created. - */ - private TransformerFactory transformerFactory = null; - - /** - * Constructs a new WorkbookSaveSession. - * - * @param workbook - * @param target - */ - public WorkbookSaveSession(WorkbookImpl workbook, - IOutputTarget target) { - this.workbook = workbook; - this.target = target; - } - - /** - * The main saving process. - * - * @throws IOException - * @throws CoreException - */ - public synchronized void save() throws IOException, CoreException { - try { - try { - try { - saveMeta(); - } finally { - try { - saveContent(); - } finally { - try { - saveMarkerSheet(); - } finally { - try { - saveStyleSheet(); - } finally { - try { - saveComments(); - } finally { - try { - if (!workbook - .isSkipRevisionsWhenSaving()) { - saveRevisions(); - } - } finally { - try { - copyOtherStaff(); - } finally { - saveManifest(); - } - } - } - } - } - - } - } - } finally { - clearEncryptionData(); - } - } finally { - if (target instanceof ICloseableOutputTarget) { - ((ICloseableOutputTarget) target).close(); - } - } - } - - private void saveManifest() throws IOException, CoreException { - saveDOM(workbook.getManifest(), target, MANIFEST_XML); - } - - private void saveStyleSheet() throws IOException, CoreException { - IStyleSheet styleSheet = workbook.getStyleSheet(); - if (!styleSheet.isEmpty()) { - saveDOM(styleSheet, target, STYLES_XML); - } - } - - private void saveMarkerSheet() throws IOException, CoreException { - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (!markerSheet.isEmpty()) { - saveDOM(markerSheet, target, PATH_MARKER_SHEET); - } - } - - private void saveComments() throws IOException, CoreException { - } - - private void saveRevisions() throws IOException, CoreException { - Iterator sheets = DOMUtils.childElementIterByTag( - workbook.getWorkbookElement(), TAG_SHEET); - while (sheets.hasNext()) { - Element sheetEle = sheets.next(); - String sheetId = sheetEle.getAttribute(ATTR_ID); - IRevisionManager manager = workbook.getRevisionRepository() - .getRevisionManager(sheetId, IRevision.SHEET); - String path = PATH_REVISIONS + sheetId + "/" + REVISIONS_XML; //$NON-NLS-1$ - saveDOM(manager, target, path); - } - } - - private void saveContent() throws IOException, CoreException { - saveDOM(workbook, target, CONTENT_XML); - } - - private void saveMeta() throws IOException, CoreException { - IMeta meta = workbook.getMeta(); -// meta.setValue(IMeta.CREATOR_NAME, workbook.getCurrentCreatorName()); -// meta.setValue(IMeta.CREATOR_VERSION, workbook.getCurrentCreatorVersion()); - saveDOM(meta, target, META_XML); - } - - private void copyOtherStaff() throws IOException, CoreException { - IInputSource source = workbook.getTempStorage().getInputSource(); - IManifest manifest = workbook.getManifest(); - for (IFileEntry entry : manifest.getFileEntries()) { - if (!entry.isDirectory()) { - String entryPath = entry.getPath(); - if (shouldSaveEntry(entryPath)) { - copyEntry(source, target, entryPath); - markSaved(entryPath); - } - } - } - } - - private synchronized void copyEntry(IInputSource source, - IOutputTarget target, String entryPath) - throws IOException, CoreException { - InputStream in = getInputStream(source, entryPath); - if (in == null) { - Core.getLogger().log( - "Save workbook: failed to copy entry, input stream not avaiable: " //$NON-NLS-1$ - + entryPath); - return; // Entry source not found. - } - - try { - long time = source.getEntryTime(entryPath); - if (time >= 0) { - target.setEntryTime(entryPath, time); - } - OutputStream out = getOutputStream(target, entryPath); - try { - int numBytes; - byte[] byteBuffer = new byte[4096]; - while ((numBytes = in.read(byteBuffer)) > 0) { - out.write(byteBuffer, 0, numBytes); - } - recordChecksum(entryPath, out); - } finally { - out.close(); - } - } finally { - in.close(); - } - } - - private boolean shouldSaveEntry(String entryPath) { - return entryPath != null && !"".equals(entryPath) //$NON-NLS-1$ - && !MANIFEST_XML.equals(entryPath) - && !hasBeenSaved(entryPath) - && !(workbook.isSkipRevisionsWhenSaving() && entryPath - .startsWith(ArchiveConstants.PATH_REVISIONS)); - } - - private void clearEncryptionData() { - for (IFileEntry entry : workbook.getManifest().getFileEntries()) { - entry.deleteEncryptionData(); - } - } - - private void saveDOM(IAdaptable domAdapter, IOutputTarget target, - String entryPath) throws IOException, CoreException { - Node node = (Node) domAdapter.getAdapter(Node.class); - if (node == null) { - Core.getLogger() - .log("SaveWorkbook: No DOM node available for entry: " //$NON-NLS-1$ - + entryPath); - return; - } - - if (transformerFactory == null) { - try { - transformerFactory = TransformerFactory.newInstance(); - } catch (TransformerFactoryConfigurationError error) { - throw new CoreException( - Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, - "Failed to obtain XML transformer factory.", error); //$NON-NLS-1$ - } - } - - Transformer transformer; - try { - transformer = transformerFactory.newTransformer(); - } catch (TransformerConfigurationException error) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, - "Failed to create XML transformer for DOM entry '" //$NON-NLS-1$ - + entryPath + "'.", //$NON-NLS-1$ - error); - } - - OutputStream out = getOutputStream(target, entryPath); - try { - transformer.transform(new DOMSource(node), - new StreamResult(out)); - } catch (TransformerException e) { - throw new IOException(e.getLocalizedMessage(), e); - } finally { - out.close(); - } - recordChecksum(entryPath, out); - markSaved(entryPath); - } - - private void recordChecksum(String entryPath, Object checksumProvider) - throws IOException { - if (checksumProvider instanceof IChecksumStream) { - IEncryptionData encData = workbook.getManifest() - .getEncryptionData(entryPath); - if (encData != null && encData.getChecksumType() != null) { - String checksum = ((IChecksumStream) checksumProvider) - .getChecksum(); - if (checksum != null) { - encData.setAttribute(checksum, - DOMConstants.ATTR_CHECKSUM); - } - } - } - } - - private InputStream getInputStream(IInputSource source, - String entryPath) { - if (source.hasEntry(entryPath)) { - return source.getEntryStream(entryPath); - } - return null; - } - - private OutputStream getOutputStream(IOutputTarget target, - String entryPath) throws IOException, CoreException { - OutputStream out = target.openEntryStream(entryPath); - - String password = workbook.getPassword(); - if (password == null) - return out; - - IFileEntry entry = workbook.getManifest().getFileEntry(entryPath); - if (entry == null) - return out; - - if (ignoresEncryption(entry, entryPath)) - return out; - - IEncryptionData encData = entry.createEncryptionData(); - return Crypto.creatOutputStream(out, true, encData, password); - } - - private boolean ignoresEncryption(IFileEntry entry, String entryPath) { - return MANIFEST_XML.equals(entryPath) - || ((FileEntryImpl) entry).isIgnoreEncryption(); - } - - private boolean hasBeenSaved(String entryPath) { - return savedEntries.contains(entryPath); - } - - private void markSaved(String entryPath) { - savedEntries.add(entryPath); - } - - } - - /** - * The workbook to save. - */ - private final WorkbookImpl workbook; - - /** - * The last target saved to. - */ - private IOutputTarget lastTarget; - - /** - * (Optional) The absolute path representing a ZIP file target - */ - private String file; - - /** - * Whether to skip revisions when saving. - */ - private boolean skipRevisions = false; - - /** - * @param workbook - * @param file - */ - public WorkbookSaver(WorkbookImpl workbook, String file) { - super(); - this.workbook = workbook; - this.file = file; - } - - /** - * @return the file path - */ - public String getFile() { - return file; - } - - public void setFile(String file) { - this.file = file; - } - - /** - * @param skipRevisions - * the skipRevisions to set - */ - public void setSkipRevisions(boolean skipRevisions) { - this.skipRevisions = skipRevisions; - } - - public boolean isSkipRevisions() { - return skipRevisions; - } - - /** - * - * @throws IOException - * @throws CoreException - */ - public synchronized void save() throws IOException, CoreException { - doSave(this.lastTarget); - } - - /** - * - * @param output - * @throws IOException - * @throws CoreException - */ - public synchronized void save(OutputStream output) - throws IOException, CoreException { - doSave(new ZipStreamOutputTarget(new ZipOutputStream(output))); - } - - public synchronized void save(String file) - throws IOException, CoreException { - if (new File(file).isDirectory()) { - doSave(new DirectoryOutputTarget(file)); - } else { - FileOutputStream fout = new FileOutputStream(file); - try { - ZipOutputStream stream = new ZipOutputStream(fout); - try { - doSave(new ZipStreamOutputTarget(stream)); - } finally { - stream.close(); - } - } finally { - fout.close(); - } - } - this.file = file; - } - - public synchronized void save(IOutputTarget target) - throws IOException, CoreException { - doSave(target); - this.lastTarget = target; - } - - /** - * - * @param target - * @throws IOException - * @throws CoreException - */ - private synchronized void doSave(IOutputTarget target) - throws IOException, CoreException { - if (target == null) - throw new FileNotFoundException("No target to save."); //$NON-NLS-1$ - - if (InternalCore.DEBUG_WORKBOOK_SAVE) - Core.getLogger().log( - "WorkbookSaver: About to save workbook to output target " //$NON-NLS-1$ - + target.toString()); - new WorkbookSaveSession(workbook, target).save(); - if (InternalCore.DEBUG_WORKBOOK_SAVE) - Core.getLogger().log( - "WorkbookSaver: Finished saving workbook to output target " //$NON-NLS-1$ - + target.toString()); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_SHEET; +import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_REVISIONS; +import static org.xmind.core.internal.zip.ArchiveConstants.REVISIONS_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.zip.ZipOutputStream; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.IChecksumStream; +import org.xmind.core.IEncryptionData; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.IMeta; +import org.xmind.core.IRevision; +import org.xmind.core.IRevisionManager; +import org.xmind.core.internal.InternalCore; +import org.xmind.core.internal.security.Crypto; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.internal.zip.ZipStreamOutputTarget; +import org.xmind.core.io.DirectoryOutputTarget; +import org.xmind.core.io.ICloseableOutputTarget; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; + +/** + * @author Frank Shaka + * @deprecated Use Core.getSerializerFactory().newSerializer() + */ +@Deprecated +public class WorkbookSaver { + + private static class WorkbookSaveSession { + + /** + * The workbook to save. + */ + private final WorkbookImpl workbook; + + /** + * The multi-entry output target to save to. + */ + private final IOutputTarget target; + + /** + * Entry paths that have been saved. + */ + private Set savedEntries = new HashSet(); + + /** + * DOM transformer factory, lazy created. + */ + private TransformerFactory transformerFactory = null; + + /** + * Constructs a new WorkbookSaveSession. + * + * @param workbook + * @param target + */ + public WorkbookSaveSession(WorkbookImpl workbook, + IOutputTarget target) { + this.workbook = workbook; + this.target = target; + } + + /** + * The main saving process. + * + * @throws IOException + * @throws CoreException + */ + public synchronized void save() throws IOException, CoreException { + try { + try { + try { + saveMeta(); + } finally { + try { + saveContent(); + } finally { + try { + saveMarkerSheet(); + } finally { + try { + saveStyleSheet(); + } finally { + try { + saveComments(); + } finally { + try { + if (!workbook + .isSkipRevisionsWhenSaving()) { + saveRevisions(); + } + } finally { + try { + copyOtherStaff(); + } finally { + saveManifest(); + } + } + } + } + } + + } + } + } finally { + clearEncryptionData(); + } + } finally { + if (target instanceof ICloseableOutputTarget) { + ((ICloseableOutputTarget) target).close(); + } + } + } + + private void saveManifest() throws IOException, CoreException { + saveDOM(workbook.getManifest(), target, MANIFEST_XML); + } + + private void saveStyleSheet() throws IOException, CoreException { + IStyleSheet styleSheet = workbook.getStyleSheet(); + if (!styleSheet.isEmpty()) { + saveDOM(styleSheet, target, STYLES_XML); + } + } + + private void saveMarkerSheet() throws IOException, CoreException { + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (!markerSheet.isEmpty()) { + saveDOM(markerSheet, target, PATH_MARKER_SHEET); + } + } + + private void saveComments() throws IOException, CoreException { + } + + private void saveRevisions() throws IOException, CoreException { + Iterator sheets = DOMUtils.childElementIterByTag( + workbook.getWorkbookElement(), TAG_SHEET); + while (sheets.hasNext()) { + Element sheetEle = sheets.next(); + String sheetId = sheetEle.getAttribute(ATTR_ID); + IRevisionManager manager = workbook.getRevisionRepository() + .getRevisionManager(sheetId, IRevision.SHEET); + String path = PATH_REVISIONS + sheetId + "/" + REVISIONS_XML; //$NON-NLS-1$ + saveDOM(manager, target, path); + } + } + + private void saveContent() throws IOException, CoreException { + saveDOM(workbook, target, CONTENT_XML); + } + + private void saveMeta() throws IOException, CoreException { + IMeta meta = workbook.getMeta(); +// meta.setValue(IMeta.CREATOR_NAME, workbook.getCurrentCreatorName()); +// meta.setValue(IMeta.CREATOR_VERSION, workbook.getCurrentCreatorVersion()); + saveDOM(meta, target, META_XML); + } + + private void copyOtherStaff() throws IOException, CoreException { + IInputSource source = workbook.getTempStorage().getInputSource(); + IManifest manifest = workbook.getManifest(); + for (IFileEntry entry : manifest.getFileEntries()) { + if (!entry.isDirectory()) { + String entryPath = entry.getPath(); + if (shouldSaveEntry(entryPath)) { + copyEntry(source, target, entryPath); + markSaved(entryPath); + } + } + } + } + + private synchronized void copyEntry(IInputSource source, + IOutputTarget target, String entryPath) + throws IOException, CoreException { + InputStream in = getInputStream(source, entryPath); + if (in == null) { + Core.getLogger().log( + "Save workbook: failed to copy entry, input stream not avaiable: " //$NON-NLS-1$ + + entryPath); + return; // Entry source not found. + } + + try { + long time = source.getEntryTime(entryPath); + if (time >= 0) { + target.setEntryTime(entryPath, time); + } + OutputStream out = getOutputStream(target, entryPath); + try { + int numBytes; + byte[] byteBuffer = new byte[4096]; + while ((numBytes = in.read(byteBuffer)) > 0) { + out.write(byteBuffer, 0, numBytes); + } + recordChecksum(entryPath, out); + } finally { + out.close(); + } + } finally { + in.close(); + } + } + + private boolean shouldSaveEntry(String entryPath) { + return entryPath != null && !"".equals(entryPath) //$NON-NLS-1$ + && !MANIFEST_XML.equals(entryPath) + && !hasBeenSaved(entryPath) + && !(workbook.isSkipRevisionsWhenSaving() && entryPath + .startsWith(ArchiveConstants.PATH_REVISIONS)); + } + + private void clearEncryptionData() { + for (IFileEntry entry : workbook.getManifest().getFileEntries()) { + entry.deleteEncryptionData(); + } + } + + private void saveDOM(IAdaptable domAdapter, IOutputTarget target, + String entryPath) throws IOException, CoreException { + Node node = (Node) domAdapter.getAdapter(Node.class); + if (node == null) { + Core.getLogger() + .log("SaveWorkbook: No DOM node available for entry: " //$NON-NLS-1$ + + entryPath); + return; + } + + if (transformerFactory == null) { + try { + transformerFactory = TransformerFactory.newInstance(); + } catch (TransformerFactoryConfigurationError error) { + throw new CoreException( + Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, + "Failed to obtain XML transformer factory.", error); //$NON-NLS-1$ + } + } + + Transformer transformer; + try { + transformer = transformerFactory.newTransformer(); + } catch (TransformerConfigurationException error) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, + "Failed to create XML transformer for DOM entry '" //$NON-NLS-1$ + + entryPath + "'.", //$NON-NLS-1$ + error); + } + + OutputStream out = getOutputStream(target, entryPath); + try { + transformer.transform(new DOMSource(node), + new StreamResult(out)); + } catch (TransformerException e) { + throw new IOException(e.getLocalizedMessage(), e); + } finally { + out.close(); + } + recordChecksum(entryPath, out); + markSaved(entryPath); + } + + private void recordChecksum(String entryPath, Object checksumProvider) + throws IOException { + if (checksumProvider instanceof IChecksumStream) { + IEncryptionData encData = workbook.getManifest() + .getEncryptionData(entryPath); + if (encData != null && encData.getChecksumType() != null) { + String checksum = ((IChecksumStream) checksumProvider) + .getChecksum(); + if (checksum != null) { + encData.setAttribute(checksum, + DOMConstants.ATTR_CHECKSUM); + } + } + } + } + + private InputStream getInputStream(IInputSource source, + String entryPath) { + if (source.hasEntry(entryPath)) { + return source.getEntryStream(entryPath); + } + return null; + } + + private OutputStream getOutputStream(IOutputTarget target, + String entryPath) throws IOException, CoreException { + OutputStream out = target.openEntryStream(entryPath); + + String password = workbook.getPassword(); + if (password == null) + return out; + + IFileEntry entry = workbook.getManifest().getFileEntry(entryPath); + if (entry == null) + return out; + + if (ignoresEncryption(entry, entryPath)) + return out; + + IEncryptionData encData = entry.createEncryptionData(); + return Crypto.creatOutputStream(out, true, encData, password); + } + + private boolean ignoresEncryption(IFileEntry entry, String entryPath) { + return MANIFEST_XML.equals(entryPath) + || ((FileEntryImpl) entry).isIgnoreEncryption(); + } + + private boolean hasBeenSaved(String entryPath) { + return savedEntries.contains(entryPath); + } + + private void markSaved(String entryPath) { + savedEntries.add(entryPath); + } + + } + + /** + * The workbook to save. + */ + private final WorkbookImpl workbook; + + /** + * The last target saved to. + */ + private IOutputTarget lastTarget; + + /** + * (Optional) The absolute path representing a ZIP file target + */ + private String file; + + /** + * Whether to skip revisions when saving. + */ + private boolean skipRevisions = false; + + /** + * @param workbook + * @param file + */ + public WorkbookSaver(WorkbookImpl workbook, String file) { + super(); + this.workbook = workbook; + this.file = file; + } + + /** + * @return the file path + */ + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + /** + * @param skipRevisions + * the skipRevisions to set + */ + public void setSkipRevisions(boolean skipRevisions) { + this.skipRevisions = skipRevisions; + } + + public boolean isSkipRevisions() { + return skipRevisions; + } + + /** + * + * @throws IOException + * @throws CoreException + */ + public synchronized void save() throws IOException, CoreException { + doSave(this.lastTarget); + } + + /** + * + * @param output + * @throws IOException + * @throws CoreException + */ + public synchronized void save(OutputStream output) + throws IOException, CoreException { + doSave(new ZipStreamOutputTarget(new ZipOutputStream(output))); + } + + public synchronized void save(String file) + throws IOException, CoreException { + if (new File(file).isDirectory()) { + doSave(new DirectoryOutputTarget(file)); + } else { + FileOutputStream fout = new FileOutputStream(file); + try { + ZipOutputStream stream = new ZipOutputStream(fout); + try { + doSave(new ZipStreamOutputTarget(stream)); + } finally { + stream.close(); + } + } finally { + fout.close(); + } + } + this.file = file; + } + + public synchronized void save(IOutputTarget target) + throws IOException, CoreException { + doSave(target); + this.lastTarget = target; + } + + /** + * + * @param target + * @throws IOException + * @throws CoreException + */ + private synchronized void doSave(IOutputTarget target) + throws IOException, CoreException { + if (target == null) + throw new FileNotFoundException("No target to save."); //$NON-NLS-1$ + + if (InternalCore.DEBUG_WORKBOOK_SAVE) + Core.getLogger().log( + "WorkbookSaver: About to save workbook to output target " //$NON-NLS-1$ + + target.toString()); + new WorkbookSaveSession(workbook, target).save(); + if (InternalCore.DEBUG_WORKBOOK_SAVE) + Core.getLogger().log( + "WorkbookSaver: Finished saving workbook to output target " //$NON-NLS-1$ + + target.toString()); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookUtilsImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookUtilsImpl.java index 185e2b93d..fbd04b76a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookUtilsImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookUtilsImpl.java @@ -1,83 +1,83 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.IOException; -import java.util.Collection; - -import org.xmind.core.Core; -import org.xmind.core.ICloneData; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookComponent; -import org.xmind.core.internal.CloneData; -import org.xmind.core.marker.IMarker; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.CloneHandler; - -public class WorkbookUtilsImpl { - - private WorkbookUtilsImpl() { - } - - public static ICloneData clone(IWorkbook targetWorkbook, - Collection sources, ICloneData prevResult) { - CloneData result = new CloneData(sources, prevResult); - for (Object source : sources) { - if (result.get(source) == null) { - CloneHandler handler = new CloneHandler(result); - if (source instanceof IWorkbookComponent) { - IWorkbook sourceWorkbook = ((IWorkbookComponent) source) - .getOwnedWorkbook(); - handler.withWorkbooks(sourceWorkbook, targetWorkbook); - } else if (source instanceof IMarker) { - handler.withMarkerSheets(((IMarker) source).getOwnedSheet(), - targetWorkbook.getMarkerSheet()); - } else { - /// unrecognized object, skip it - continue; - } - - try { - handler.cloneObject(source); - } catch (IOException e) { - Core.getLogger().log(e); - } - } - } - return result; - } - - public static void increaseStyleRef(WorkbookImpl workbook, IStyled styled) { - if (workbook == null || styled == null) - return; - - String styleId = styled.getStyleId(); - if (styleId == null) - return; - - workbook.getStyleRefCounter().increaseRef(styleId); - } - - public static void decreaseStyleRef(WorkbookImpl workbook, IStyled styled) { - if (workbook == null || styled == null) - return; - - String styleId = styled.getStyleId(); - if (styleId == null) - return; - - workbook.getStyleRefCounter().decreaseRef(styleId); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.IOException; +import java.util.Collection; + +import org.xmind.core.Core; +import org.xmind.core.ICloneData; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookComponent; +import org.xmind.core.internal.CloneData; +import org.xmind.core.marker.IMarker; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.CloneHandler; + +public class WorkbookUtilsImpl { + + private WorkbookUtilsImpl() { + } + + public static ICloneData clone(IWorkbook targetWorkbook, + Collection sources, ICloneData prevResult) { + CloneData result = new CloneData(sources, prevResult); + for (Object source : sources) { + if (result.get(source) == null) { + CloneHandler handler = new CloneHandler(result); + if (source instanceof IWorkbookComponent) { + IWorkbook sourceWorkbook = ((IWorkbookComponent) source) + .getOwnedWorkbook(); + handler.withWorkbooks(sourceWorkbook, targetWorkbook); + } else if (source instanceof IMarker) { + handler.withMarkerSheets(((IMarker) source).getOwnedSheet(), + targetWorkbook.getMarkerSheet()); + } else { + /// unrecognized object, skip it + continue; + } + + try { + handler.cloneObject(source); + } catch (IOException e) { + Core.getLogger().log(e); + } + } + } + return result; + } + + public static void increaseStyleRef(WorkbookImpl workbook, IStyled styled) { + if (workbook == null || styled == null) + return; + + String styleId = styled.getStyleId(); + if (styleId == null) + return; + + workbook.getStyleRefCounter().increaseRef(styleId); + } + + public static void decreaseStyleRef(WorkbookImpl workbook, IStyled styled) { + if (workbook == null || styled == null) + return; + + String styleId = styled.getStyleId(); + if (styleId == null) + return; + + workbook.getStyleRefCounter().decreaseRef(styleId); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/XMLLoader.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/XMLLoader.java index f33ca295f..98810a569 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/XMLLoader.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/XMLLoader.java @@ -1,62 +1,62 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.dom; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.w3c.dom.Document; -import org.xmind.core.CoreException; -import org.xmind.core.io.IInputSource; -import org.xmind.core.util.IXMLLoader; - -/** - * @deprecated - * @author Frank Shaka - */ -@Deprecated -public abstract class XMLLoader implements IXMLLoader { - - private Map loadedDocuments = null; - - /** - * @deprecated - */ - @Deprecated - public Document loadXMLFile(IInputSource source, String entryName) - throws IOException, CoreException { - if (loadedDocuments != null) { - Document document = loadedDocuments.get(entryName); - if (document != null) { - return document; - } - } - - Document document = doLoadXMLFile(source, entryName); - - if (loadedDocuments == null) - loadedDocuments = new HashMap(); - loadedDocuments.put(entryName, document); - return document; - } - - /** - * @deprecated - */ - @Deprecated - protected abstract Document doLoadXMLFile(IInputSource source, - String entryName) throws IOException, CoreException; - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.dom; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.w3c.dom.Document; +import org.xmind.core.CoreException; +import org.xmind.core.io.IInputSource; +import org.xmind.core.util.IXMLLoader; + +/** + * @deprecated + * @author Frank Shaka + */ +@Deprecated +public abstract class XMLLoader implements IXMLLoader { + + private Map loadedDocuments = null; + + /** + * @deprecated + */ + @Deprecated + public Document loadXMLFile(IInputSource source, String entryName) + throws IOException, CoreException { + if (loadedDocuments != null) { + Document document = loadedDocuments.get(entryName); + if (document != null) { + return document; + } + } + + Document document = doLoadXMLFile(source, entryName); + + if (loadedDocuments == null) + loadedDocuments = new HashMap(); + loadedDocuments.put(entryName, document); + return document; + } + + /** + * @deprecated + */ + @Deprecated + protected abstract Document doLoadXMLFile(IInputSource source, + String entryName) throws IOException, CoreException; + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventListenerList.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventListenerList.java index e89ace869..94f564aa1 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventListenerList.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventListenerList.java @@ -1,77 +1,77 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; - -/** - * - * @author frankshaka - * @deprecated Use CoreEventRegistrationList - */ -public class CoreEventListenerList { - - private List listeners; - - public CoreEventListenerList(ICoreEventListener listener) { - this.listeners = new ArrayList(4); - this.listeners.add(listener); - } - - public CoreEventListenerList(ICoreEventListener[] listeners) { - this.listeners = new ArrayList(listeners.length); - this.listeners.addAll(Arrays.asList(listeners)); - } - - public void add(ICoreEventListener listener) { - if (listener == null) - return; - - if (listeners == null) { - listeners = new ArrayList(4); - } - listeners.add(listener); - } - - public void remove(ICoreEventListener listener) { - if (listener == null || this.listeners == null) - return; - - listeners.remove(listener); - } - - public boolean isEmpty() { - return listeners == null || listeners.isEmpty(); - } - - public void fireCoreEvent(CoreEvent e) { - if (listeners == null) - return; - - Object[] list = listeners.toArray(); - for (Object listener : list) { - ((ICoreEventListener) listener).handleCoreEvent(e); - } - } - - public boolean hasListener(ICoreEventListener listener) { - return listeners != null && listeners.contains(listener); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; + +/** + * + * @author frankshaka + * @deprecated Use CoreEventRegistrationList + */ +public class CoreEventListenerList { + + private List listeners; + + public CoreEventListenerList(ICoreEventListener listener) { + this.listeners = new ArrayList(4); + this.listeners.add(listener); + } + + public CoreEventListenerList(ICoreEventListener[] listeners) { + this.listeners = new ArrayList(listeners.length); + this.listeners.addAll(Arrays.asList(listeners)); + } + + public void add(ICoreEventListener listener) { + if (listener == null) + return; + + if (listeners == null) { + listeners = new ArrayList(4); + } + listeners.add(listener); + } + + public void remove(ICoreEventListener listener) { + if (listener == null || this.listeners == null) + return; + + listeners.remove(listener); + } + + public boolean isEmpty() { + return listeners == null || listeners.isEmpty(); + } + + public void fireCoreEvent(CoreEvent e) { + if (listeners == null) + return; + + Object[] list = listeners.toArray(); + for (Object listener : list) { + ((ICoreEventListener) listener).handleCoreEvent(e); + } + } + + public boolean hasListener(ICoreEventListener listener) { + return listeners != null && listeners.contains(listener); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistration.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistration.java index 1e93f3315..03c0874e5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistration.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistration.java @@ -1,83 +1,83 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; - -public class CoreEventRegistration implements ICoreEventRegistration { - - private CoreEventSupport dispatcher; - - private ICoreEventSource source; - - private String eventType; - - private ICoreEventListener listener; - - private boolean once; - - private boolean valid = true; - - public CoreEventRegistration(CoreEventSupport dispatcher, - ICoreEventSource source, String eventType, - ICoreEventListener listener) { - this(dispatcher, source, eventType, listener, false); - } - - public CoreEventRegistration(CoreEventSupport dispatcher, - ICoreEventSource source, String eventType, - ICoreEventListener listener, boolean once) { - this.dispatcher = dispatcher; - this.source = source; - this.eventType = eventType; - this.listener = listener; - this.once = once; - } - - public ICoreEventSource getSource() { - return source; - } - - public String getEventType() { - return eventType; - } - - public ICoreEventListener getListener() { - return listener; - } - - /** - * @return the once - */ - public boolean isOnce() { - return once; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.event.ICoreEventRegistration#isValid() - */ - public boolean isValid() { - return valid; - } - - public void unregister() { - dispatcher.unregister(this); - valid = false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; + +public class CoreEventRegistration implements ICoreEventRegistration { + + private CoreEventSupport dispatcher; + + private ICoreEventSource source; + + private String eventType; + + private ICoreEventListener listener; + + private boolean once; + + private boolean valid = true; + + public CoreEventRegistration(CoreEventSupport dispatcher, + ICoreEventSource source, String eventType, + ICoreEventListener listener) { + this(dispatcher, source, eventType, listener, false); + } + + public CoreEventRegistration(CoreEventSupport dispatcher, + ICoreEventSource source, String eventType, + ICoreEventListener listener, boolean once) { + this.dispatcher = dispatcher; + this.source = source; + this.eventType = eventType; + this.listener = listener; + this.once = once; + } + + public ICoreEventSource getSource() { + return source; + } + + public String getEventType() { + return eventType; + } + + public ICoreEventListener getListener() { + return listener; + } + + /** + * @return the once + */ + public boolean isOnce() { + return once; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.event.ICoreEventRegistration#isValid() + */ + public boolean isValid() { + return valid; + } + + public void unregister() { + dispatcher.unregister(this); + valid = false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistrationList.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistrationList.java index 539b0fd72..39fe0671c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistrationList.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventRegistrationList.java @@ -1,97 +1,97 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventRegistration; - -/** - * @author frankshaka - * - */ -public class CoreEventRegistrationList { - - public static final int ONLY_ONCE = 1; - - public static final int ONLY_NORMAL = 1 << 1; - - public static final int ALL = ONLY_NORMAL | ONLY_ONCE; - - private List regs; - - private int numOnceRegs = 0; - - public CoreEventRegistrationList() { - } - - public void add(CoreEventRegistration reg) { - if (reg == null) - return; - - if (regs == null) { - regs = new ArrayList(4); - } - regs.add(reg); - if (reg.isOnce()) { - numOnceRegs++; - } - } - - public void remove(CoreEventRegistration reg) { - if (reg == null || this.regs == null) - return; - - boolean isRemoved = regs.remove(reg); - if (reg.isOnce() && isRemoved) { - numOnceRegs--; - } - if (regs.isEmpty()) { - regs = null; - } - } - - public boolean isEmpty() { - return regs == null || regs.isEmpty(); - } - - public void fireCoreEvent(CoreEvent e, int group) { - if (regs == null) - return; - - Object[] array = regs.toArray(); - for (Object obj : array) { - CoreEventRegistration reg = (CoreEventRegistration) obj; - if (group == ALL - || ((group == ONLY_ONCE && reg.isOnce()) || (group == ONLY_NORMAL && !reg - .isOnce()))) { - reg.getListener().handleCoreEvent(e); - if (reg.isOnce()) { - reg.unregister(); - } - } - } - } - - public boolean hasRegistration(ICoreEventRegistration reg) { - return regs != null && regs.contains(reg); - } - - public boolean hasOnceRegistration() { - return numOnceRegs > 0; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventRegistration; + +/** + * @author frankshaka + * + */ +public class CoreEventRegistrationList { + + public static final int ONLY_ONCE = 1; + + public static final int ONLY_NORMAL = 1 << 1; + + public static final int ALL = ONLY_NORMAL | ONLY_ONCE; + + private List regs; + + private int numOnceRegs = 0; + + public CoreEventRegistrationList() { + } + + public void add(CoreEventRegistration reg) { + if (reg == null) + return; + + if (regs == null) { + regs = new ArrayList(4); + } + regs.add(reg); + if (reg.isOnce()) { + numOnceRegs++; + } + } + + public void remove(CoreEventRegistration reg) { + if (reg == null || this.regs == null) + return; + + boolean isRemoved = regs.remove(reg); + if (reg.isOnce() && isRemoved) { + numOnceRegs--; + } + if (regs.isEmpty()) { + regs = null; + } + } + + public boolean isEmpty() { + return regs == null || regs.isEmpty(); + } + + public void fireCoreEvent(CoreEvent e, int group) { + if (regs == null) + return; + + Object[] array = regs.toArray(); + for (Object obj : array) { + CoreEventRegistration reg = (CoreEventRegistration) obj; + if (group == ALL + || ((group == ONLY_ONCE && reg.isOnce()) || (group == ONLY_NORMAL && !reg + .isOnce()))) { + reg.getListener().handleCoreEvent(e); + if (reg.isOnce()) { + reg.unregister(); + } + } + } + } + + public boolean hasRegistration(ICoreEventRegistration reg) { + return regs != null && regs.contains(reg); + } + + public boolean hasOnceRegistration() { + return numOnceRegs > 0; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventSupport.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventSupport.java index 0c3931ec5..6d8b1c81b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventSupport.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/CoreEventSupport.java @@ -1,362 +1,362 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; - -public class CoreEventSupport implements ICoreEventSupport { - - private static class CoreEventManager { - - private Map regs; - - public void add(CoreEventRegistration reg) { - regs = addListener(reg.getEventType(), reg, regs); - } - - private Map addListener(String type, - CoreEventRegistration reg, - Map map) { - if (map == null) - map = new HashMap(); - CoreEventRegistrationList list = map.get(type); - if (list == null) { - list = new CoreEventRegistrationList(); - map.put(type, list); - } - list.add(reg); - return map; - } - - public void remove(CoreEventRegistration reg) { - regs = removeListener(reg.getEventType(), reg, regs); - } - - private Map removeListener( - String type, CoreEventRegistration reg, - Map map) { - if (map != null) { - CoreEventRegistrationList list = map.get(type); - if (list != null) { - list.remove(reg); - if (list.isEmpty()) { - map.remove(type); - } - } - if (map.isEmpty()) { - map = null; - } - } - return map; - } - - public boolean isEmpty() { - return regs == null || regs.isEmpty(); - } - - public void dispatchCoreEvent(String type, CoreEvent event) { - if (regs != null) { - CoreEventRegistrationList list = regs.get(type); - if (list != null) { - if (list.hasOnceRegistration()) { - list.fireCoreEvent(event, - CoreEventRegistrationList.ONLY_ONCE); - } else { - list - .fireCoreEvent(event, - CoreEventRegistrationList.ALL); - } - } - } - } - - public void dispatchCoreEvent(String type, CoreEvent event, - int eventGroup) { - dispatchCoreEvent(type, event, eventGroup, regs); - } - - private Map dispatchCoreEvent( - String type, CoreEvent event, int eventGroup, - Map map) { - if (map != null) { - CoreEventRegistrationList list = map.get(type); - if (list != null) { - list.fireCoreEvent(event, eventGroup); - } - } - return map; - } - - public boolean hasListeners(String type) { - return regs != null && regs.containsKey(type); - } - - public boolean hasOnceListeners(String type) { - if (regs == null) - return false; - CoreEventRegistrationList list = regs.get(type); - return list != null && list.hasOnceRegistration(); - } - - } - - private ICoreEventSupport parent; - - private Map managers; - - private CoreEventManager globalManager; - - public ICoreEventSupport getParent() { - return parent; - } - - public void setParent(ICoreEventSupport parent) { - this.parent = parent; - } - - public ICoreEventRegistration registerCoreEventListener( - ICoreEventSource source, String eventType, - ICoreEventListener listener) { - return registerListener(source, eventType, listener, false); - } - - private ICoreEventRegistration registerListener(ICoreEventSource source, - String eventType, ICoreEventListener listener, boolean once) { - CoreEventRegistration reg = new CoreEventRegistration(this, source, - eventType, listener, once); - if (managers == null) - managers = new HashMap(); - CoreEventManager manager = managers.get(source); - if (manager == null) { - manager = new CoreEventManager(); - managers.put(source, manager); - } - manager.add(reg); - return reg; - } - - public ICoreEventRegistration registerGlobalListener(String eventType, - ICoreEventListener listener) { - return registerGlobalListener(eventType, listener, false); - } - - private ICoreEventRegistration registerGlobalListener(String eventType, - ICoreEventListener listener, boolean once) { - CoreEventRegistration reg = new CoreEventRegistration(this, null, - eventType, listener, once); - if (globalManager == null) - globalManager = new CoreEventManager(); - globalManager.add(reg); - return reg; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#registerOnceCoreEventListener( - * org.xmind.core.event.ICoreEventSource, java.lang.String, - * org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerOnceCoreEventListener( - ICoreEventSource source, String eventType, - ICoreEventListener listener) { - ICoreEventRegistration reg = registerListener(source, eventType, - listener, true); - dispatch(source, eventType, new CoreEvent(source, eventType, null, - listener), false); - return reg; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#registerOnceGlobalListener(java - * .lang.String, org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerOnceGlobalListener(String eventType, - ICoreEventListener listener) { - ICoreEventRegistration reg = registerGlobalListener(eventType, - listener, true); - if (managers != null) { - for (Entry entry : managers - .entrySet()) { - if (entry.getValue().hasListeners(eventType)) { - ICoreEventSource source = entry.getKey(); - dispatch(source, eventType, new CoreEvent(source, - eventType, listener), false); - } - } - } - return reg; - } - - protected void unregister(CoreEventRegistration reg) { - ICoreEventSource source = reg.getSource(); - if (source == null) { - unregisterGlobalRegistration(reg); - return; - } - - if (managers == null || managers.isEmpty()) - return; - - CoreEventManager manager = managers.get(source); - if (manager == null) - return; - - manager.remove(reg); - if (manager.isEmpty()) { - managers.remove(source); - } - if (managers.isEmpty()) { - managers = null; - } - - if (reg.isOnce()) { - String eventType = reg.getEventType(); - ICoreEventListener listener = reg.getListener(); - dispatch(source, eventType, new CoreEvent(source, eventType, - listener, null), false); - } - } - - private void unregisterGlobalRegistration(CoreEventRegistration reg) { - if (globalManager != null) { - globalManager.remove(reg); - } - if (globalManager.isEmpty()) { - globalManager = null; - } - } - - public void dispatchValueChange(ICoreEventSource source, String eventType, - Object oldValue, Object newValue) { - if (oldValue == newValue - || (oldValue != null && oldValue.equals(newValue))) - return; - - dispatch(source, eventType, new CoreEvent(source, eventType, oldValue, - newValue), true); - } - - public void dispatchIndexedValueChange(ICoreEventSource source, - String eventType, Object oldValue, Object newValue, int index) { - if (oldValue == newValue - || (oldValue != null && oldValue.equals(newValue))) - return; - - dispatch(source, eventType, new CoreEvent(source, eventType, oldValue, - newValue, index), true); - } - - public void dispatchIndexedTargetChange(ICoreEventSource source, - String eventType, Object target, int index) { - dispatch(source, eventType, new CoreEvent(source, eventType, target, - index), true); - } - - public void dispatchTargetChange(ICoreEventSource source, String eventType, - Object target) { - dispatch(source, eventType, new CoreEvent(source, eventType, target), - true); - } - - public void dispatchTargetValueChange(ICoreEventSource source, - String eventType, Object target, Object oldValue, Object newValue) { - dispatch(source, eventType, new CoreEvent(source, eventType, target, - oldValue, newValue), true); - } - - public void dispatch(ICoreEventSource source, CoreEvent event) { - String eventType = event.getType(); - dispatch(source, eventType, event, true); - } - - private void dispatch(ICoreEventSource source, String eventType, - CoreEvent event, boolean notifyOnceListeners) { - dispatchBySource(source, eventType, event, notifyOnceListeners); - dispatchGlobal(eventType, event, notifyOnceListeners); - } - - private void dispatchBySource(ICoreEventSource source, String eventType, - CoreEvent event, boolean notifyOnceListeners) { - if (managers == null || managers.isEmpty()) - return; - - CoreEventManager manager = managers.get(source); - if (manager == null || manager.isEmpty()) - return; - - if (notifyOnceListeners) { - manager.dispatchCoreEvent(eventType, event); - } else { - manager.dispatchCoreEvent(eventType, event, - CoreEventRegistrationList.ONLY_NORMAL); - } - } - - private void dispatchGlobal(String eventType, CoreEvent event, - boolean notifyOnceListeners) { - if (globalManager != null) { - if (notifyOnceListeners) { - globalManager.dispatchCoreEvent(eventType, event); - } else { - globalManager.dispatchCoreEvent(eventType, event, - CoreEventRegistrationList.ONLY_NORMAL); - } - } - if (getParent() != null && getParent() instanceof CoreEventSupport) { - ((CoreEventSupport) getParent()).dispatchGlobal(eventType, event, - notifyOnceListeners); - } - } - - public void dispose() { - if (managers != null) { - managers.clear(); - managers = null; - } - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#hasListeners(java.lang.String) - */ - public boolean hasListeners(ICoreEventSource source, String eventType) { - if (managers == null) - return false; - CoreEventManager manager = managers.get(source); - return manager != null && manager.hasListeners(eventType); - } - - public boolean hasOnceListeners(ICoreEventSource source, String eventType) { - if (managers == null) - return false; - CoreEventManager manager = managers.get(source); - return manager != null && manager.hasOnceListeners(eventType); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; + +public class CoreEventSupport implements ICoreEventSupport { + + private static class CoreEventManager { + + private Map regs; + + public void add(CoreEventRegistration reg) { + regs = addListener(reg.getEventType(), reg, regs); + } + + private Map addListener(String type, + CoreEventRegistration reg, + Map map) { + if (map == null) + map = new HashMap(); + CoreEventRegistrationList list = map.get(type); + if (list == null) { + list = new CoreEventRegistrationList(); + map.put(type, list); + } + list.add(reg); + return map; + } + + public void remove(CoreEventRegistration reg) { + regs = removeListener(reg.getEventType(), reg, regs); + } + + private Map removeListener( + String type, CoreEventRegistration reg, + Map map) { + if (map != null) { + CoreEventRegistrationList list = map.get(type); + if (list != null) { + list.remove(reg); + if (list.isEmpty()) { + map.remove(type); + } + } + if (map.isEmpty()) { + map = null; + } + } + return map; + } + + public boolean isEmpty() { + return regs == null || regs.isEmpty(); + } + + public void dispatchCoreEvent(String type, CoreEvent event) { + if (regs != null) { + CoreEventRegistrationList list = regs.get(type); + if (list != null) { + if (list.hasOnceRegistration()) { + list.fireCoreEvent(event, + CoreEventRegistrationList.ONLY_ONCE); + } else { + list + .fireCoreEvent(event, + CoreEventRegistrationList.ALL); + } + } + } + } + + public void dispatchCoreEvent(String type, CoreEvent event, + int eventGroup) { + dispatchCoreEvent(type, event, eventGroup, regs); + } + + private Map dispatchCoreEvent( + String type, CoreEvent event, int eventGroup, + Map map) { + if (map != null) { + CoreEventRegistrationList list = map.get(type); + if (list != null) { + list.fireCoreEvent(event, eventGroup); + } + } + return map; + } + + public boolean hasListeners(String type) { + return regs != null && regs.containsKey(type); + } + + public boolean hasOnceListeners(String type) { + if (regs == null) + return false; + CoreEventRegistrationList list = regs.get(type); + return list != null && list.hasOnceRegistration(); + } + + } + + private ICoreEventSupport parent; + + private Map managers; + + private CoreEventManager globalManager; + + public ICoreEventSupport getParent() { + return parent; + } + + public void setParent(ICoreEventSupport parent) { + this.parent = parent; + } + + public ICoreEventRegistration registerCoreEventListener( + ICoreEventSource source, String eventType, + ICoreEventListener listener) { + return registerListener(source, eventType, listener, false); + } + + private ICoreEventRegistration registerListener(ICoreEventSource source, + String eventType, ICoreEventListener listener, boolean once) { + CoreEventRegistration reg = new CoreEventRegistration(this, source, + eventType, listener, once); + if (managers == null) + managers = new HashMap(); + CoreEventManager manager = managers.get(source); + if (manager == null) { + manager = new CoreEventManager(); + managers.put(source, manager); + } + manager.add(reg); + return reg; + } + + public ICoreEventRegistration registerGlobalListener(String eventType, + ICoreEventListener listener) { + return registerGlobalListener(eventType, listener, false); + } + + private ICoreEventRegistration registerGlobalListener(String eventType, + ICoreEventListener listener, boolean once) { + CoreEventRegistration reg = new CoreEventRegistration(this, null, + eventType, listener, once); + if (globalManager == null) + globalManager = new CoreEventManager(); + globalManager.add(reg); + return reg; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#registerOnceCoreEventListener( + * org.xmind.core.event.ICoreEventSource, java.lang.String, + * org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerOnceCoreEventListener( + ICoreEventSource source, String eventType, + ICoreEventListener listener) { + ICoreEventRegistration reg = registerListener(source, eventType, + listener, true); + dispatch(source, eventType, new CoreEvent(source, eventType, null, + listener), false); + return reg; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#registerOnceGlobalListener(java + * .lang.String, org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerOnceGlobalListener(String eventType, + ICoreEventListener listener) { + ICoreEventRegistration reg = registerGlobalListener(eventType, + listener, true); + if (managers != null) { + for (Entry entry : managers + .entrySet()) { + if (entry.getValue().hasListeners(eventType)) { + ICoreEventSource source = entry.getKey(); + dispatch(source, eventType, new CoreEvent(source, + eventType, listener), false); + } + } + } + return reg; + } + + protected void unregister(CoreEventRegistration reg) { + ICoreEventSource source = reg.getSource(); + if (source == null) { + unregisterGlobalRegistration(reg); + return; + } + + if (managers == null || managers.isEmpty()) + return; + + CoreEventManager manager = managers.get(source); + if (manager == null) + return; + + manager.remove(reg); + if (manager.isEmpty()) { + managers.remove(source); + } + if (managers.isEmpty()) { + managers = null; + } + + if (reg.isOnce()) { + String eventType = reg.getEventType(); + ICoreEventListener listener = reg.getListener(); + dispatch(source, eventType, new CoreEvent(source, eventType, + listener, null), false); + } + } + + private void unregisterGlobalRegistration(CoreEventRegistration reg) { + if (globalManager != null) { + globalManager.remove(reg); + } + if (globalManager.isEmpty()) { + globalManager = null; + } + } + + public void dispatchValueChange(ICoreEventSource source, String eventType, + Object oldValue, Object newValue) { + if (oldValue == newValue + || (oldValue != null && oldValue.equals(newValue))) + return; + + dispatch(source, eventType, new CoreEvent(source, eventType, oldValue, + newValue), true); + } + + public void dispatchIndexedValueChange(ICoreEventSource source, + String eventType, Object oldValue, Object newValue, int index) { + if (oldValue == newValue + || (oldValue != null && oldValue.equals(newValue))) + return; + + dispatch(source, eventType, new CoreEvent(source, eventType, oldValue, + newValue, index), true); + } + + public void dispatchIndexedTargetChange(ICoreEventSource source, + String eventType, Object target, int index) { + dispatch(source, eventType, new CoreEvent(source, eventType, target, + index), true); + } + + public void dispatchTargetChange(ICoreEventSource source, String eventType, + Object target) { + dispatch(source, eventType, new CoreEvent(source, eventType, target), + true); + } + + public void dispatchTargetValueChange(ICoreEventSource source, + String eventType, Object target, Object oldValue, Object newValue) { + dispatch(source, eventType, new CoreEvent(source, eventType, target, + oldValue, newValue), true); + } + + public void dispatch(ICoreEventSource source, CoreEvent event) { + String eventType = event.getType(); + dispatch(source, eventType, event, true); + } + + private void dispatch(ICoreEventSource source, String eventType, + CoreEvent event, boolean notifyOnceListeners) { + dispatchBySource(source, eventType, event, notifyOnceListeners); + dispatchGlobal(eventType, event, notifyOnceListeners); + } + + private void dispatchBySource(ICoreEventSource source, String eventType, + CoreEvent event, boolean notifyOnceListeners) { + if (managers == null || managers.isEmpty()) + return; + + CoreEventManager manager = managers.get(source); + if (manager == null || manager.isEmpty()) + return; + + if (notifyOnceListeners) { + manager.dispatchCoreEvent(eventType, event); + } else { + manager.dispatchCoreEvent(eventType, event, + CoreEventRegistrationList.ONLY_NORMAL); + } + } + + private void dispatchGlobal(String eventType, CoreEvent event, + boolean notifyOnceListeners) { + if (globalManager != null) { + if (notifyOnceListeners) { + globalManager.dispatchCoreEvent(eventType, event); + } else { + globalManager.dispatchCoreEvent(eventType, event, + CoreEventRegistrationList.ONLY_NORMAL); + } + } + if (getParent() != null && getParent() instanceof CoreEventSupport) { + ((CoreEventSupport) getParent()).dispatchGlobal(eventType, event, + notifyOnceListeners); + } + } + + public void dispose() { + if (managers != null) { + managers.clear(); + managers = null; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#hasListeners(java.lang.String) + */ + public boolean hasListeners(ICoreEventSource source, String eventType) { + if (managers == null) + return false; + CoreEventManager manager = managers.get(source); + return manager != null && manager.hasListeners(eventType); + } + + public boolean hasOnceListeners(ICoreEventSource source, String eventType) { + if (managers == null) + return false; + CoreEventManager manager = managers.get(source); + return manager != null && manager.hasOnceListeners(eventType); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventRegistration.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventRegistration.java index 59ec6e075..6af7b294c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventRegistration.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventRegistration.java @@ -1,38 +1,38 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import org.xmind.core.event.ICoreEventRegistration; - -public class NullCoreEventRegistration implements ICoreEventRegistration { - - private static final NullCoreEventRegistration instance = new NullCoreEventRegistration(); - - private boolean valid = true; - - private NullCoreEventRegistration() { - } - - public void unregister() { - valid = false; - } - - public boolean isValid() { - return valid; - } - - public static NullCoreEventRegistration getInstance() { - return instance; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import org.xmind.core.event.ICoreEventRegistration; + +public class NullCoreEventRegistration implements ICoreEventRegistration { + + private static final NullCoreEventRegistration instance = new NullCoreEventRegistration(); + + private boolean valid = true; + + private NullCoreEventRegistration() { + } + + public void unregister() { + valid = false; + } + + public boolean isValid() { + return valid; + } + + public static NullCoreEventRegistration getInstance() { + return instance; + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventSupport.java b/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventSupport.java index d2783e14f..96fb4e311 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventSupport.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/event/NullCoreEventSupport.java @@ -1,115 +1,115 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.event; - -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; - -public class NullCoreEventSupport implements ICoreEventSupport { - - private static final NullCoreEventSupport instance = new NullCoreEventSupport(); - - private NullCoreEventSupport() { - } - - public void dispatch(ICoreEventSource source, CoreEvent event) { - } - - public void dispatchIndexedTargetChange(ICoreEventSource source, - String eventType, Object target, int index) { - } - - public void dispatchIndexedValueChange(ICoreEventSource source, - String eventType, Object oldValue, Object newValue, int index) { - } - - public void dispatchTargetChange(ICoreEventSource source, String eventType, - Object target) { - } - - public void dispatchTargetValueChange(ICoreEventSource source, - String eventType, Object target, Object oldValue, Object newValue) { - } - - public void dispatchValueChange(ICoreEventSource source, String eventType, - Object oldValue, Object newValue) { - } - - public ICoreEventRegistration registerCoreEventListener( - ICoreEventSource source, String eventType, - ICoreEventListener listener) { - return NullCoreEventRegistration.getInstance(); - } - - public ICoreEventRegistration registerGlobalListener(String eventType, - ICoreEventListener listener) { - return NullCoreEventRegistration.getInstance(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#registerOnceCoreEventListener( - * org.xmind.core.event.ICoreEventSource, java.lang.String, - * org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerOnceCoreEventListener( - ICoreEventSource source, String eventType, - ICoreEventListener listener) { - return NullCoreEventRegistration.getInstance(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#registerOnceGlobalListener(java - * .lang.String, org.xmind.core.event.ICoreEventListener) - */ - public ICoreEventRegistration registerOnceGlobalListener(String eventType, - ICoreEventListener listener) { - return NullCoreEventRegistration.getInstance(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#hasListeners(org.xmind.core.event - * .ICoreEventSource, java.lang.String) - */ - public boolean hasListeners(ICoreEventSource source, String eventType) { - return false; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.event.ICoreEventSupport#hasOnceListeners(org.xmind.core - * .event.ICoreEventSource, java.lang.String) - */ - public boolean hasOnceListeners(ICoreEventSource source, String eventType) { - return false; - } - - public static NullCoreEventSupport getInstance() { - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.event; + +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; + +public class NullCoreEventSupport implements ICoreEventSupport { + + private static final NullCoreEventSupport instance = new NullCoreEventSupport(); + + private NullCoreEventSupport() { + } + + public void dispatch(ICoreEventSource source, CoreEvent event) { + } + + public void dispatchIndexedTargetChange(ICoreEventSource source, + String eventType, Object target, int index) { + } + + public void dispatchIndexedValueChange(ICoreEventSource source, + String eventType, Object oldValue, Object newValue, int index) { + } + + public void dispatchTargetChange(ICoreEventSource source, String eventType, + Object target) { + } + + public void dispatchTargetValueChange(ICoreEventSource source, + String eventType, Object target, Object oldValue, Object newValue) { + } + + public void dispatchValueChange(ICoreEventSource source, String eventType, + Object oldValue, Object newValue) { + } + + public ICoreEventRegistration registerCoreEventListener( + ICoreEventSource source, String eventType, + ICoreEventListener listener) { + return NullCoreEventRegistration.getInstance(); + } + + public ICoreEventRegistration registerGlobalListener(String eventType, + ICoreEventListener listener) { + return NullCoreEventRegistration.getInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#registerOnceCoreEventListener( + * org.xmind.core.event.ICoreEventSource, java.lang.String, + * org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerOnceCoreEventListener( + ICoreEventSource source, String eventType, + ICoreEventListener listener) { + return NullCoreEventRegistration.getInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#registerOnceGlobalListener(java + * .lang.String, org.xmind.core.event.ICoreEventListener) + */ + public ICoreEventRegistration registerOnceGlobalListener(String eventType, + ICoreEventListener listener) { + return NullCoreEventRegistration.getInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#hasListeners(org.xmind.core.event + * .ICoreEventSource, java.lang.String) + */ + public boolean hasListeners(ICoreEventSource source, String eventType) { + return false; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.event.ICoreEventSupport#hasOnceListeners(org.xmind.core + * .event.ICoreEventSource, java.lang.String) + */ + public boolean hasOnceListeners(ICoreEventSource source, String eventType) { + return false; + } + + public static NullCoreEventSupport getInstance() { + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/AbstractArchivedWorkbook.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/AbstractArchivedWorkbook.java index 82256dab3..682d8255d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/AbstractArchivedWorkbook.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/AbstractArchivedWorkbook.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -import java.io.IOException; - -import org.xmind.core.CoreException; -import org.xmind.core.IWorkbook; - -/** - * - * @author frankshaka - * @deprecated - */ -public abstract class AbstractArchivedWorkbook implements IArchivedWorkbook { - - private final String file; - - protected final IWorkbook workbook; - - public AbstractArchivedWorkbook(IWorkbook workbook, String file) { - this.workbook = workbook; - this.file = file; - } - - public String getFile() { - return file; - } - - /** - * - */ - public void save() throws IOException, CoreException { - save(null); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +import java.io.IOException; + +import org.xmind.core.CoreException; +import org.xmind.core.IWorkbook; + +/** + * + * @author frankshaka + * @deprecated + */ +public abstract class AbstractArchivedWorkbook implements IArchivedWorkbook { + + private final String file; + + protected final IWorkbook workbook; + + public AbstractArchivedWorkbook(IWorkbook workbook, String file) { + this.workbook = workbook; + this.file = file; + } + + public String getFile() { + return file; + } + + /** + * + */ + public void save() throws IOException, CoreException { + save(null); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchiveConstants.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchiveConstants.java index 8cc7180c0..d5800fe8c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchiveConstants.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchiveConstants.java @@ -1,87 +1,87 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -/** - * @author briansun - * - */ -public class ArchiveConstants { - - /** - * - */ - public static final String CONTENT_XML = "content.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String STYLES_XML = "styles.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String META_XML = "meta.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String MANIFEST_XML = "META-INF/manifest.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_META_INF = "META-INF/"; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_ATTACHMENTS = "attachments/"; //$NON-NLS-1$ - - /** - * - */ - public static final String MARKER_SHEET_XML = "markerSheet.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_MARKER_SHEET = "markers/" + MARKER_SHEET_XML; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_MARKERS = "markers/"; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_REVISIONS = "Revisions/"; //$NON-NLS-1$ - - /** - * - */ - public static final String REVISIONS_XML = "revisions.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String COMMENTS_XML = "comments.xml"; //$NON-NLS-1$ - - /** - * - */ - public static final String PATH_EXTENSIONS = "extensions/"; //$NON-NLS-1$ - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +/** + * @author briansun + * + */ +public class ArchiveConstants { + + /** + * + */ + public static final String CONTENT_XML = "content.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String STYLES_XML = "styles.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String META_XML = "meta.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String MANIFEST_XML = "META-INF/manifest.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_META_INF = "META-INF/"; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_ATTACHMENTS = "attachments/"; //$NON-NLS-1$ + + /** + * + */ + public static final String MARKER_SHEET_XML = "markerSheet.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_MARKER_SHEET = "markers/" + MARKER_SHEET_XML; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_MARKERS = "markers/"; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_REVISIONS = "Revisions/"; //$NON-NLS-1$ + + /** + * + */ + public static final String REVISIONS_XML = "revisions.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String COMMENTS_XML = "comments.xml"; //$NON-NLS-1$ + + /** + * + */ + public static final String PATH_EXTENSIONS = "extensions/"; //$NON-NLS-1$ + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchivedWorkbook.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchivedWorkbook.java index 3ab4204fd..70768ab6a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchivedWorkbook.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ArchivedWorkbook.java @@ -1,517 +1,517 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - - -/** - * @author briansun - * @deprecated - */ -public class ArchivedWorkbook { -//extends AbstractArchivedWorkbook { -// -// private static class ZipEntryInputStream extends InputStream { -// -// private ZipFile zipFile; -// -// private InputStream delegate; -// -// public ZipEntryInputStream(ZipFile zipFile, InputStream delegate) { -// this.zipFile = zipFile; -// this.delegate = delegate; -// } -// -// public int available() throws IOException { -// return delegate.available(); -// } -// -// public void close() throws IOException { -// try { -// delegate.close(); -// } finally { -// zipFile.close(); -// } -// } -// -// public int hashCode() { -// return delegate.hashCode(); -// } -// -// public synchronized void mark(int readlimit) { -// delegate.mark(readlimit); -// } -// -// public boolean markSupported() { -// return delegate.markSupported(); -// } -// -// public int read() throws IOException { -// return delegate.read(); -// } -// -// public int read(byte[] b) throws IOException { -// return delegate.read(b); -// } -// -// public int read(byte[] b, int off, int len) throws IOException { -// return delegate.read(b, off, len); -// } -// -// public synchronized void reset() throws IOException { -// delegate.reset(); -// } -// -// public long skip(long n) throws IOException { -// return delegate.skip(n); -// } -// -// public String toString() { -// return delegate.toString(); -// } -// -// } -// -// private static final List XML_PATHS = Arrays.asList(CONTENT_XML, -// PATH_MARKER_SHEET, STYLES_XML, MANIFEST_XML, META_XML); -// -// /** -// * @param file -// */ -// public ArchivedWorkbook(IWorkbook workbook, String file) { -// super(workbook, file); -// } -// -// public OutputStream getEntryOutputStream(String entryPath) { -// //ZipOutputStream os = new ZipOutputStream( -// // new FileOutputStream(getFile())); -// //os.putNextEntry(new ZipEntry(entryPath)); -// //return os; -// -// /* -// * We can't provide an output stream for those who wants to insert, -// * replace or delete some entry within a ZIP archive, for the -// * ZipOutputStream will ignore all other existing contents in the -// * archive and leave only the given entry. -// */ -// return null; -// } -// -// public InputStream getEntryInputStream(String entryPath) { -// InputStream stream = getZippedStream(entryPath); -// if (stream != null) { -// String password = workbook.getPassword(); -// if (password != null) { -// if (map != null) { -// EncryptionData encData = map.get(entryPath); -// if (encData != null) { -// try { -//// BufferedBlockCipher cipher = Crypto -//// .createBlockCipher(false, password, encData); -//// stream = new BlockCipherInputStream(stream, cipher); -// stream = Crypto.createInputStream(stream, -// false, encData, password); -// } catch (CoreException e) { -// Core.getLogger().log(e); -// return null; -// } -// } -// } -// } -// } -// return stream; -// } -// -// /** -// * @param entryPath -// * @return -// */ -// private InputStream getZippedStream(String entryPath) { -// try { -// ZipFile zipFile = new ZipFile(getFile()); -// try { -// ZipEntry entry = zipFile.getEntry(entryPath); -// if (entry != null) { -// InputStream realInputStream = zipFile.getInputStream(entry); -// if (realInputStream != null) -// return new ZipEntryInputStream(zipFile, realInputStream); -// } -// } catch (Exception e) { -// } -// zipFile.close(); -// } catch (Exception e) { -// } -// return null; -// } -// -// public long getTime(String entryPath) { -// try { -// ZipFile zipFile = new ZipFile(getFile()); -// try { -// ZipEntry e = zipFile.getEntry(entryPath); -// if (e != null) { -// return e.getTime(); -// } -// } finally { -// zipFile.close(); -// } -// } catch (Exception e) { -// } -// return -1; -// } -// -// public void setTime(String entryPath, long time) { -// } -// -// public long getSize(String entryPath) { -// try { -// ZipFile zipFile = new ZipFile(getFile()); -// try { -// ZipEntry e = zipFile.getEntry(entryPath); -// if (e != null) { -// return e.getSize(); -// } -// } finally { -// zipFile.close(); -// } -// } catch (Exception e) { -// } -// return -1; -// } -// -// public void save(IArchivedWorkbook source) throws IOException, -// CoreException { -// File tempSource = null; -// if (!isValidSource(source)) { -// String tempDir = Core.getWorkspace().getAbsolutePath( -// IWorkspace.DIR_TEMP); -// tempSource = new File(tempDir, Core.getIdFactory().createId()); -// extractTo(tempSource); -// } -// -// FileUtils.ensureFileParent(new File(getFile())); -// -// ZipOutputStream zos = new ZipOutputStream(new FileOutputStream( -// getFile())); -// -// try { -// IManifest manifest = workbook.getManifest(); -// -// if (map != null) { -// map.clear(); -// } -// -// OutputStream out_CONTENT = getOutputStream(zos, CONTENT_XML, -// manifest); -// DOMUtils.save(workbook, out_CONTENT, true); -// if (out_CONTENT instanceof IChecksumStream) -// saveChecksum(CONTENT_XML, ((IChecksumStream) out_CONTENT) -// .getChecksum()); -// -// IMarkerSheet markerSheet = workbook.getMarkerSheet(); -// if (!markerSheet.isEmpty()) { -// DOMUtils.save(markerSheet, getOutputStream(zos, -// PATH_MARKER_SHEET, manifest), true); -// } -// -// IStyleSheet styleSheet = workbook.getStyleSheet(); -// if (!styleSheet.isEmpty()) { -// OutputStream out_STYLES = getOutputStream(zos, STYLES_XML, -// manifest); -// DOMUtils.save(styleSheet, out_STYLES, true); -// if (out_STYLES instanceof IChecksumStream) -// saveChecksum(STYLES_XML, ((IChecksumStream) out_STYLES) -// .getChecksum()); -// } -// -// IMeta meta = workbook.getMeta(); -// OutputStream out_META = getOutputStream(zos, META_XML, manifest); -// DOMUtils.save(meta, out_META, true); -// if (out_META instanceof IChecksumStream) -// saveChecksum(META_XML, ((IChecksumStream) out_META) -// .getChecksum()); -// -// encapsulate(manifest, source, tempSource, zos); -// -// //zos.putNextEntry(new ZipEntry(MANIFEST_XML)); -// OutputStream manifestOutput = getOutputStream(zos, MANIFEST_XML, -// manifest); -// DOMUtils.save(manifest, manifestOutput, true); -// -// clearEncryptionData(manifest); -// -// } finally { -// zos.close(); -// if (tempSource != null) { -// FileUtils.delete(tempSource); -// tempSource = null; -// } -// } -// } -// -// /** -// * @param entryPath -// * @param checksum -// */ -// private void saveChecksum(String entryPath, String checksum) { -// if (map != null) { -// EncryptionData encData = map.get(entryPath); -// if (encData != null) { -// encData.setChecksum(checksum); -// } -// } -// } -// -// /** -// * @param zippedOutput -// * @param entryName -// * @param manifest -// * @return -// * @throws IOException -// */ -// private OutputStream getOutputStream(ZipOutputStream zippedOutput, -// String entryName, IManifest manifest) throws CoreException, -// IOException { -// -// zippedOutput.putNextEntry(new ZipEntry(entryName)); -// OutputStream out = new NonCloseOutputStream(zippedOutput); -// -// if (ignoresEncryption(entryName)) -// return out; -// -// String password = workbook.getPassword(); -// -// if (password == null) { -// return out; -// } -// Document mfDoc = (Document) manifest.getAdapter(Document.class); -// if (mfDoc == null) -// return out; -// -// EncryptionData encData = Crypto.generateEncryptionData(mfDoc); -// if (encData == null) -// return out; -// -// if (map == null) -// map = new HashMap(); -// map.put(entryName, encData); -// -// return Crypto.creatOutputStream(out, true, encData, password); -// -//// BufferedBlockCipher cipher = Crypto.createBlockCipher(true, password, -//// encData); -//// return new ChecksumOutputStream( -//// new BlockCipherOutputStream(out, cipher)); -// } -// -// private static class NonCloseOutputStream extends FilterOutputStream { -// -// public NonCloseOutputStream(OutputStream out) { -// super(out); -// } -// -// @Override -// public void close() throws IOException { -// // don't close the underlying stream -// } -// -// } -// -// /** -// * @param entryName -// * @return -// */ -// private boolean ignoresEncryption(String entryName) { -// return ArchiveConstants.MANIFEST_XML.equals(entryName); -// } -// -// private Map map = null; -// -// /** -// * @param map -// * the map to set -// */ -// public void setEncryptionDataMap(Map map) { -// this.map = map; -// } -// -// /** -// * Encapsulate all preserved files from the directory back to the archive. -// * -// * @param manifest -// * @param source -// * @param sourcePath -// * @param target -// */ -// private void encapsulate(IManifest manifest, IArchivedWorkbook source, -// File sourcePath, ZipOutputStream target) { -// -// for (IFileEntry entry : manifest.getFileEntries()) { -// if (entry.isDirectory()) -// continue; -// -// String path = entry.getPath(); -// -// if (!isXmlFile(path)) { -// InputStream is = getInputStream(path, source, sourcePath); -// if (is != null) { -//// ZipEntry ze = new ZipEntry(path); -//// ze.setTime(getTime(path, source, sourcePath)); -// try { -// //target.putNextEntry(ze); -// FileUtils.transfer(is, getOutputStream(target, path, -// manifest), true); -// } catch (IOException e) { -// } catch (CoreException e) { -// } finally { -// try { -// is.close(); -// } catch (IOException e) { -// } -// } -// } -// } -// insertEncryptionData(entry, path); -// } -// } -// -// /** -// * @param manifest -// */ -// private void clearEncryptionData(IManifest manifest) { -// if (map != null) { -// for (EncryptionData encData : map.values()) { -// deleteEncryptionData(encData, manifest); -// } -// } -// } -// -// /** -// * @param encData -// * @param manifest -// */ -// private void deleteEncryptionData(EncryptionData encData, IManifest manifest) { -// Element encDataEle = (Element) encData.getAdapter(Element.class); -// if (encDataEle != null) { -// Node p = encDataEle.getParentNode(); -// if (p != null) { -// p.removeChild(encDataEle); -// } -// } -// } -// -// /** -// * @param entry -// * @param path -// */ -// private void insertEncryptionData(IFileEntry entry, String path) { -// if (map == null || map.isEmpty()) -// return; -// -// EncryptionData encData = map.get(path); -// if (encData != null) { -// Element entryEle = (Element) entry.getAdapter(Element.class); -// Element encDataEle = (Element) encData.getAdapter(Element.class); -// if (entryEle != null && encDataEle != null) { -// entryEle.appendChild(encDataEle); -// } -// } -// } -// -// /** -// * Extract all preserved files to directory. -// * -// * @param destPath -// */ -// private void extractTo(File destPath) { -// try { -// ZipFile zipFile = new ZipFile(getFile()); -// try { -// extract(zipFile, destPath); -// } finally { -// zipFile.close(); -// } -// } catch (IOException e) { -// } -// } -// -// private void extract(ZipFile zipFile, File destPath) { -// Enumeration entries = zipFile.entries(); -// while (entries.hasMoreElements()) { -// ZipEntry entry = entries.nextElement(); -// String path = entry.getName(); -// if (!isXmlFile(path)) { -// try { -// InputStream is = zipFile.getInputStream(entry); -// if (is != null) { -// File f = FileUtils.ensureFileParent(new File(destPath, -// path)); -// OutputStream os = new FileOutputStream(f); -// FileUtils.transfer(is, os); -// f.setLastModified(entry.getTime()); -// } -// } catch (IOException e) { -// } -// } -// } -// } -// -// /** -// * Checks whether a directory is needed for a re-encapsulation action. -// * -// * @param source -// * @return Whether to create a temporary directory. -// */ -// private boolean isValidSource(IArchivedWorkbook source) { -// return source != null && !equals(source); -// } -// -// private InputStream getInputStream(String entryPath, -// IArchivedWorkbook source, File tempSource) { -// -// if (isValidSource(source)) { -// return source.getEntryInputStream(entryPath); -// } else if (tempSource != null) { -// try { -// return new FileInputStream(new File(tempSource, entryPath)); -// } catch (FileNotFoundException e) { -// } -// } -// return null; -// } -// -//// private long getTime(String entryPath, IArchivedWorkbook source, -//// File tempSource) { -//// if (isValidSource(source)) { -//// return source.getTime(entryPath); -//// } else if (tempSource != null) { -//// File f = new File(tempSource, entryPath); -//// if (f.exists()) -//// return f.lastModified(); -//// } -//// return System.currentTimeMillis(); -//// } -// -// private static boolean isXmlFile(String path) { -// return XML_PATHS.contains(path); -// } -// -// public boolean equals(Object obj) { -// if (obj == this) -// return true; -// if (obj == null || !(obj instanceof ArchivedWorkbook)) -// return false; -// ArchivedWorkbook that = (ArchivedWorkbook) obj; -// return new File(getFile()).equals(new File(that.getFile())); -// } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + + +/** + * @author briansun + * @deprecated + */ +public class ArchivedWorkbook { +//extends AbstractArchivedWorkbook { +// +// private static class ZipEntryInputStream extends InputStream { +// +// private ZipFile zipFile; +// +// private InputStream delegate; +// +// public ZipEntryInputStream(ZipFile zipFile, InputStream delegate) { +// this.zipFile = zipFile; +// this.delegate = delegate; +// } +// +// public int available() throws IOException { +// return delegate.available(); +// } +// +// public void close() throws IOException { +// try { +// delegate.close(); +// } finally { +// zipFile.close(); +// } +// } +// +// public int hashCode() { +// return delegate.hashCode(); +// } +// +// public synchronized void mark(int readlimit) { +// delegate.mark(readlimit); +// } +// +// public boolean markSupported() { +// return delegate.markSupported(); +// } +// +// public int read() throws IOException { +// return delegate.read(); +// } +// +// public int read(byte[] b) throws IOException { +// return delegate.read(b); +// } +// +// public int read(byte[] b, int off, int len) throws IOException { +// return delegate.read(b, off, len); +// } +// +// public synchronized void reset() throws IOException { +// delegate.reset(); +// } +// +// public long skip(long n) throws IOException { +// return delegate.skip(n); +// } +// +// public String toString() { +// return delegate.toString(); +// } +// +// } +// +// private static final List XML_PATHS = Arrays.asList(CONTENT_XML, +// PATH_MARKER_SHEET, STYLES_XML, MANIFEST_XML, META_XML); +// +// /** +// * @param file +// */ +// public ArchivedWorkbook(IWorkbook workbook, String file) { +// super(workbook, file); +// } +// +// public OutputStream getEntryOutputStream(String entryPath) { +// //ZipOutputStream os = new ZipOutputStream( +// // new FileOutputStream(getFile())); +// //os.putNextEntry(new ZipEntry(entryPath)); +// //return os; +// +// /* +// * We can't provide an output stream for those who wants to insert, +// * replace or delete some entry within a ZIP archive, for the +// * ZipOutputStream will ignore all other existing contents in the +// * archive and leave only the given entry. +// */ +// return null; +// } +// +// public InputStream getEntryInputStream(String entryPath) { +// InputStream stream = getZippedStream(entryPath); +// if (stream != null) { +// String password = workbook.getPassword(); +// if (password != null) { +// if (map != null) { +// EncryptionData encData = map.get(entryPath); +// if (encData != null) { +// try { +//// BufferedBlockCipher cipher = Crypto +//// .createBlockCipher(false, password, encData); +//// stream = new BlockCipherInputStream(stream, cipher); +// stream = Crypto.createInputStream(stream, +// false, encData, password); +// } catch (CoreException e) { +// Core.getLogger().log(e); +// return null; +// } +// } +// } +// } +// } +// return stream; +// } +// +// /** +// * @param entryPath +// * @return +// */ +// private InputStream getZippedStream(String entryPath) { +// try { +// ZipFile zipFile = new ZipFile(getFile()); +// try { +// ZipEntry entry = zipFile.getEntry(entryPath); +// if (entry != null) { +// InputStream realInputStream = zipFile.getInputStream(entry); +// if (realInputStream != null) +// return new ZipEntryInputStream(zipFile, realInputStream); +// } +// } catch (Exception e) { +// } +// zipFile.close(); +// } catch (Exception e) { +// } +// return null; +// } +// +// public long getTime(String entryPath) { +// try { +// ZipFile zipFile = new ZipFile(getFile()); +// try { +// ZipEntry e = zipFile.getEntry(entryPath); +// if (e != null) { +// return e.getTime(); +// } +// } finally { +// zipFile.close(); +// } +// } catch (Exception e) { +// } +// return -1; +// } +// +// public void setTime(String entryPath, long time) { +// } +// +// public long getSize(String entryPath) { +// try { +// ZipFile zipFile = new ZipFile(getFile()); +// try { +// ZipEntry e = zipFile.getEntry(entryPath); +// if (e != null) { +// return e.getSize(); +// } +// } finally { +// zipFile.close(); +// } +// } catch (Exception e) { +// } +// return -1; +// } +// +// public void save(IArchivedWorkbook source) throws IOException, +// CoreException { +// File tempSource = null; +// if (!isValidSource(source)) { +// String tempDir = Core.getWorkspace().getAbsolutePath( +// IWorkspace.DIR_TEMP); +// tempSource = new File(tempDir, Core.getIdFactory().createId()); +// extractTo(tempSource); +// } +// +// FileUtils.ensureFileParent(new File(getFile())); +// +// ZipOutputStream zos = new ZipOutputStream(new FileOutputStream( +// getFile())); +// +// try { +// IManifest manifest = workbook.getManifest(); +// +// if (map != null) { +// map.clear(); +// } +// +// OutputStream out_CONTENT = getOutputStream(zos, CONTENT_XML, +// manifest); +// DOMUtils.save(workbook, out_CONTENT, true); +// if (out_CONTENT instanceof IChecksumStream) +// saveChecksum(CONTENT_XML, ((IChecksumStream) out_CONTENT) +// .getChecksum()); +// +// IMarkerSheet markerSheet = workbook.getMarkerSheet(); +// if (!markerSheet.isEmpty()) { +// DOMUtils.save(markerSheet, getOutputStream(zos, +// PATH_MARKER_SHEET, manifest), true); +// } +// +// IStyleSheet styleSheet = workbook.getStyleSheet(); +// if (!styleSheet.isEmpty()) { +// OutputStream out_STYLES = getOutputStream(zos, STYLES_XML, +// manifest); +// DOMUtils.save(styleSheet, out_STYLES, true); +// if (out_STYLES instanceof IChecksumStream) +// saveChecksum(STYLES_XML, ((IChecksumStream) out_STYLES) +// .getChecksum()); +// } +// +// IMeta meta = workbook.getMeta(); +// OutputStream out_META = getOutputStream(zos, META_XML, manifest); +// DOMUtils.save(meta, out_META, true); +// if (out_META instanceof IChecksumStream) +// saveChecksum(META_XML, ((IChecksumStream) out_META) +// .getChecksum()); +// +// encapsulate(manifest, source, tempSource, zos); +// +// //zos.putNextEntry(new ZipEntry(MANIFEST_XML)); +// OutputStream manifestOutput = getOutputStream(zos, MANIFEST_XML, +// manifest); +// DOMUtils.save(manifest, manifestOutput, true); +// +// clearEncryptionData(manifest); +// +// } finally { +// zos.close(); +// if (tempSource != null) { +// FileUtils.delete(tempSource); +// tempSource = null; +// } +// } +// } +// +// /** +// * @param entryPath +// * @param checksum +// */ +// private void saveChecksum(String entryPath, String checksum) { +// if (map != null) { +// EncryptionData encData = map.get(entryPath); +// if (encData != null) { +// encData.setChecksum(checksum); +// } +// } +// } +// +// /** +// * @param zippedOutput +// * @param entryName +// * @param manifest +// * @return +// * @throws IOException +// */ +// private OutputStream getOutputStream(ZipOutputStream zippedOutput, +// String entryName, IManifest manifest) throws CoreException, +// IOException { +// +// zippedOutput.putNextEntry(new ZipEntry(entryName)); +// OutputStream out = new NonCloseOutputStream(zippedOutput); +// +// if (ignoresEncryption(entryName)) +// return out; +// +// String password = workbook.getPassword(); +// +// if (password == null) { +// return out; +// } +// Document mfDoc = (Document) manifest.getAdapter(Document.class); +// if (mfDoc == null) +// return out; +// +// EncryptionData encData = Crypto.generateEncryptionData(mfDoc); +// if (encData == null) +// return out; +// +// if (map == null) +// map = new HashMap(); +// map.put(entryName, encData); +// +// return Crypto.creatOutputStream(out, true, encData, password); +// +//// BufferedBlockCipher cipher = Crypto.createBlockCipher(true, password, +//// encData); +//// return new ChecksumOutputStream( +//// new BlockCipherOutputStream(out, cipher)); +// } +// +// private static class NonCloseOutputStream extends FilterOutputStream { +// +// public NonCloseOutputStream(OutputStream out) { +// super(out); +// } +// +// @Override +// public void close() throws IOException { +// // don't close the underlying stream +// } +// +// } +// +// /** +// * @param entryName +// * @return +// */ +// private boolean ignoresEncryption(String entryName) { +// return ArchiveConstants.MANIFEST_XML.equals(entryName); +// } +// +// private Map map = null; +// +// /** +// * @param map +// * the map to set +// */ +// public void setEncryptionDataMap(Map map) { +// this.map = map; +// } +// +// /** +// * Encapsulate all preserved files from the directory back to the archive. +// * +// * @param manifest +// * @param source +// * @param sourcePath +// * @param target +// */ +// private void encapsulate(IManifest manifest, IArchivedWorkbook source, +// File sourcePath, ZipOutputStream target) { +// +// for (IFileEntry entry : manifest.getFileEntries()) { +// if (entry.isDirectory()) +// continue; +// +// String path = entry.getPath(); +// +// if (!isXmlFile(path)) { +// InputStream is = getInputStream(path, source, sourcePath); +// if (is != null) { +//// ZipEntry ze = new ZipEntry(path); +//// ze.setTime(getTime(path, source, sourcePath)); +// try { +// //target.putNextEntry(ze); +// FileUtils.transfer(is, getOutputStream(target, path, +// manifest), true); +// } catch (IOException e) { +// } catch (CoreException e) { +// } finally { +// try { +// is.close(); +// } catch (IOException e) { +// } +// } +// } +// } +// insertEncryptionData(entry, path); +// } +// } +// +// /** +// * @param manifest +// */ +// private void clearEncryptionData(IManifest manifest) { +// if (map != null) { +// for (EncryptionData encData : map.values()) { +// deleteEncryptionData(encData, manifest); +// } +// } +// } +// +// /** +// * @param encData +// * @param manifest +// */ +// private void deleteEncryptionData(EncryptionData encData, IManifest manifest) { +// Element encDataEle = (Element) encData.getAdapter(Element.class); +// if (encDataEle != null) { +// Node p = encDataEle.getParentNode(); +// if (p != null) { +// p.removeChild(encDataEle); +// } +// } +// } +// +// /** +// * @param entry +// * @param path +// */ +// private void insertEncryptionData(IFileEntry entry, String path) { +// if (map == null || map.isEmpty()) +// return; +// +// EncryptionData encData = map.get(path); +// if (encData != null) { +// Element entryEle = (Element) entry.getAdapter(Element.class); +// Element encDataEle = (Element) encData.getAdapter(Element.class); +// if (entryEle != null && encDataEle != null) { +// entryEle.appendChild(encDataEle); +// } +// } +// } +// +// /** +// * Extract all preserved files to directory. +// * +// * @param destPath +// */ +// private void extractTo(File destPath) { +// try { +// ZipFile zipFile = new ZipFile(getFile()); +// try { +// extract(zipFile, destPath); +// } finally { +// zipFile.close(); +// } +// } catch (IOException e) { +// } +// } +// +// private void extract(ZipFile zipFile, File destPath) { +// Enumeration entries = zipFile.entries(); +// while (entries.hasMoreElements()) { +// ZipEntry entry = entries.nextElement(); +// String path = entry.getName(); +// if (!isXmlFile(path)) { +// try { +// InputStream is = zipFile.getInputStream(entry); +// if (is != null) { +// File f = FileUtils.ensureFileParent(new File(destPath, +// path)); +// OutputStream os = new FileOutputStream(f); +// FileUtils.transfer(is, os); +// f.setLastModified(entry.getTime()); +// } +// } catch (IOException e) { +// } +// } +// } +// } +// +// /** +// * Checks whether a directory is needed for a re-encapsulation action. +// * +// * @param source +// * @return Whether to create a temporary directory. +// */ +// private boolean isValidSource(IArchivedWorkbook source) { +// return source != null && !equals(source); +// } +// +// private InputStream getInputStream(String entryPath, +// IArchivedWorkbook source, File tempSource) { +// +// if (isValidSource(source)) { +// return source.getEntryInputStream(entryPath); +// } else if (tempSource != null) { +// try { +// return new FileInputStream(new File(tempSource, entryPath)); +// } catch (FileNotFoundException e) { +// } +// } +// return null; +// } +// +//// private long getTime(String entryPath, IArchivedWorkbook source, +//// File tempSource) { +//// if (isValidSource(source)) { +//// return source.getTime(entryPath); +//// } else if (tempSource != null) { +//// File f = new File(tempSource, entryPath); +//// if (f.exists()) +//// return f.lastModified(); +//// } +//// return System.currentTimeMillis(); +//// } +// +// private static boolean isXmlFile(String path) { +// return XML_PATHS.contains(path); +// } +// +// public boolean equals(Object obj) { +// if (obj == this) +// return true; +// if (obj == null || !(obj instanceof ArchivedWorkbook)) +// return false; +// ArchivedWorkbook that = (ArchivedWorkbook) obj; +// return new File(getFile()).equals(new File(that.getFile())); +// } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/IArchivedWorkbook.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/IArchivedWorkbook.java index 190edb090..db9e7985b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/IArchivedWorkbook.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/IArchivedWorkbook.java @@ -1,79 +1,79 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.xmind.core.CoreException; - -/** - * - * @author frankshaka - * @deprecated - */ -public interface IArchivedWorkbook { - - /** - * @return the file - */ - String getFile(); - - /** - * - * @throws IOException - * @throws CoreException - */ - void save() throws IOException, CoreException; - - /** - * - * @param source - * @throws IOException - * @throws CoreException - */ - void save(IArchivedWorkbook source) throws IOException, CoreException; - - /** - * - * @param entryPath - * @return - */ - OutputStream getEntryOutputStream(String entryPath); - - /** - * - * @param entryPath - * @return - */ - InputStream getEntryInputStream(String entryPath); - - /** - * - * @param entryPath - * @return - */ - long getTime(String entryPath); - - /** - * - * @param entryPath - * @param time - */ - void setTime(String entryPath, long time); - - long getSize(String entryPath); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.xmind.core.CoreException; + +/** + * + * @author frankshaka + * @deprecated + */ +public interface IArchivedWorkbook { + + /** + * @return the file + */ + String getFile(); + + /** + * + * @throws IOException + * @throws CoreException + */ + void save() throws IOException, CoreException; + + /** + * + * @param source + * @throws IOException + * @throws CoreException + */ + void save(IArchivedWorkbook source) throws IOException, CoreException; + + /** + * + * @param entryPath + * @return + */ + OutputStream getEntryOutputStream(String entryPath); + + /** + * + * @param entryPath + * @return + */ + InputStream getEntryInputStream(String entryPath); + + /** + * + * @param entryPath + * @return + */ + long getTime(String entryPath); + + /** + * + * @param entryPath + * @param time + */ + void setTime(String entryPath, long time); + + long getSize(String entryPath); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/TempArchivedWorkbook.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/TempArchivedWorkbook.java index 7f9ebf592..b18ef7838 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/TempArchivedWorkbook.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/TempArchivedWorkbook.java @@ -1,150 +1,150 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; -import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; -import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.List; - -import org.xmind.core.CoreException; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.IMeta; -import org.xmind.core.IWorkbook; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; - -/** - * - * @author frankshaka - * @deprecated - */ -public class TempArchivedWorkbook extends AbstractArchivedWorkbook { - - private static final List IGNORE_LIST = Arrays.asList(CONTENT_XML, - PATH_MARKER_SHEET, STYLES_XML, MANIFEST_XML, META_XML); - - public TempArchivedWorkbook(IWorkbook workbook, String file) { - super(workbook, file); - } - - public InputStream getEntryInputStream(String entryPath) { - File entryFile = new File(getFile(), entryPath); - try { - return new FileInputStream(entryFile); - } catch (FileNotFoundException e) { - } - return null; - } - - public OutputStream getEntryOutputStream(String entryPath) { - File entryFile = FileUtils.ensureFileParent(new File(getFile(), - entryPath)); - try { - return new FileOutputStream(entryFile); - } catch (FileNotFoundException e) { - } - return null; - } - - public long getTime(String entryPath) { - File entryFile = new File(getFile(), entryPath); - if (entryFile.exists()) - return entryFile.lastModified(); - return -1; - } - - public void setTime(String entryPath, long time) { - if (time < 0) - return; - File entryFile = new File(getFile(), entryPath); - if (entryFile.exists()) - entryFile.setLastModified(time); - } - - public long getSize(String entryPath) { - File entryFile = new File(getFile(), entryPath); - if (entryFile.exists()) { - long length = entryFile.length(); - if (length > 0) - return length; - } - return -1; - } - - public void save(IArchivedWorkbook source) throws IOException, - CoreException { - DOMUtils.save(workbook, getEntryOutputStream(CONTENT_XML), true); - - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (!markerSheet.isEmpty()) { - DOMUtils.save(markerSheet, getEntryOutputStream(PATH_MARKER_SHEET), - true); - } - - IStyleSheet styleSheet = workbook.getStyleSheet(); - if (!styleSheet.isEmpty()) { - DOMUtils.save(styleSheet, getEntryOutputStream(STYLES_XML), true); - } - - IMeta meta = workbook.getMeta(); - DOMUtils.save(meta, getEntryOutputStream(META_XML), true); - - IManifest manifest = workbook.getManifest(); - DOMUtils.save(manifest, getEntryOutputStream(MANIFEST_XML), true); - - if (source != null && !equals(source)) { - for (IFileEntry entry : manifest.getFileEntries()) { - String path = entry.getPath(); - if (!IGNORE_LIST.contains(path) && !entry.isDirectory()) { - InputStream is = source.getEntryInputStream(path); - if (is != null) { - OutputStream os = getEntryOutputStream(path); - if (os != null) { - try { - FileUtils.transfer(is, os); - } catch (IOException e) { - } - setTime(path, source.getTime(path)); - } - } - } - } - } - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof TempArchivedWorkbook)) - return false; - TempArchivedWorkbook that = (TempArchivedWorkbook) obj; - return new File(this.getFile()).equals(new File(that.getFile())); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +import static org.xmind.core.internal.zip.ArchiveConstants.CONTENT_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.MANIFEST_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.META_XML; +import static org.xmind.core.internal.zip.ArchiveConstants.PATH_MARKER_SHEET; +import static org.xmind.core.internal.zip.ArchiveConstants.STYLES_XML; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; + +import org.xmind.core.CoreException; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.IMeta; +import org.xmind.core.IWorkbook; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; + +/** + * + * @author frankshaka + * @deprecated + */ +public class TempArchivedWorkbook extends AbstractArchivedWorkbook { + + private static final List IGNORE_LIST = Arrays.asList(CONTENT_XML, + PATH_MARKER_SHEET, STYLES_XML, MANIFEST_XML, META_XML); + + public TempArchivedWorkbook(IWorkbook workbook, String file) { + super(workbook, file); + } + + public InputStream getEntryInputStream(String entryPath) { + File entryFile = new File(getFile(), entryPath); + try { + return new FileInputStream(entryFile); + } catch (FileNotFoundException e) { + } + return null; + } + + public OutputStream getEntryOutputStream(String entryPath) { + File entryFile = FileUtils.ensureFileParent(new File(getFile(), + entryPath)); + try { + return new FileOutputStream(entryFile); + } catch (FileNotFoundException e) { + } + return null; + } + + public long getTime(String entryPath) { + File entryFile = new File(getFile(), entryPath); + if (entryFile.exists()) + return entryFile.lastModified(); + return -1; + } + + public void setTime(String entryPath, long time) { + if (time < 0) + return; + File entryFile = new File(getFile(), entryPath); + if (entryFile.exists()) + entryFile.setLastModified(time); + } + + public long getSize(String entryPath) { + File entryFile = new File(getFile(), entryPath); + if (entryFile.exists()) { + long length = entryFile.length(); + if (length > 0) + return length; + } + return -1; + } + + public void save(IArchivedWorkbook source) throws IOException, + CoreException { + DOMUtils.save(workbook, getEntryOutputStream(CONTENT_XML), true); + + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (!markerSheet.isEmpty()) { + DOMUtils.save(markerSheet, getEntryOutputStream(PATH_MARKER_SHEET), + true); + } + + IStyleSheet styleSheet = workbook.getStyleSheet(); + if (!styleSheet.isEmpty()) { + DOMUtils.save(styleSheet, getEntryOutputStream(STYLES_XML), true); + } + + IMeta meta = workbook.getMeta(); + DOMUtils.save(meta, getEntryOutputStream(META_XML), true); + + IManifest manifest = workbook.getManifest(); + DOMUtils.save(manifest, getEntryOutputStream(MANIFEST_XML), true); + + if (source != null && !equals(source)) { + for (IFileEntry entry : manifest.getFileEntries()) { + String path = entry.getPath(); + if (!IGNORE_LIST.contains(path) && !entry.isDirectory()) { + InputStream is = source.getEntryInputStream(path); + if (is != null) { + OutputStream os = getEntryOutputStream(path); + if (os != null) { + try { + FileUtils.transfer(is, os); + } catch (IOException e) { + } + setTime(path, source.getTime(path)); + } + } + } + } + } + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof TempArchivedWorkbook)) + return false; + TempArchivedWorkbook that = (TempArchivedWorkbook) obj; + return new File(this.getFile()).equals(new File(that.getFile())); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipFileInputSource.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipFileInputSource.java index 79456b68f..ee58cef0d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipFileInputSource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipFileInputSource.java @@ -1,170 +1,170 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.xmind.core.Core; -import org.xmind.core.io.IInputSource; - -public class ZipFileInputSource implements IInputSource { - - private static class EntryIterAdapter implements Iterator { - - private Enumeration entries; - - /** - * @param entries - */ - public EntryIterAdapter(Enumeration entries) { - super(); - this.entries = entries; - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#hasNext() - */ - public boolean hasNext() { - return entries.hasMoreElements(); - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#next() - */ - public String next() { - ZipEntry entry = entries.nextElement(); - if (entry == null) - return null; - return entry.getName(); - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#remove() - */ - public void remove() { - throw new UnsupportedOperationException(); - } - - } - - private ZipFile zipFile; - - public ZipFileInputSource(ZipFile zipFile) { - this.zipFile = zipFile; - } - - public Iterator getEntries() { - return new EntryIterAdapter(zipFile.entries()); - } - - public boolean hasEntry(String entryName) { - return zipFile.getEntry(entryName) != null; - } - - public InputStream getEntryStream(String entryName) { - ZipEntry entry = zipFile.getEntry(entryName); - if (entry == null) - return null; - try { - return zipFile.getInputStream(entry); - } catch (IOException e) { - Core.getLogger().log(e); - } - return null; - } - - public InputStream openEntryStream(String entryName) throws IOException { - ZipEntry entry = zipFile.getEntry(entryName); - if (entry == null) - throw new FileNotFoundException(entryName); - return zipFile.getInputStream(entry); - } - - public boolean isEntryAvailable(String entryName) { - ZipEntry entry = zipFile.getEntry(entryName); - return entry != null && !entry.isDirectory(); - } - - public void closeZipFile() { - try { - zipFile.close(); - } catch (IOException e) { - Core.getLogger().log(e); - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) - */ - public long getEntrySize(String entryName) { - ZipEntry entry = zipFile.getEntry(entryName); - if (entry != null) { - return entry.getSize(); - } - return -1; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) - */ - public long getEntryTime(String entryName) { - ZipEntry entry = zipFile.getEntry(entryName); - if (entry != null) { - return entry.getTime(); - } - return -1; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof ZipFileInputSource)) - return false; - ZipFileInputSource that = (ZipFileInputSource) obj; - return this.zipFile.equals(that.zipFile); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return this.zipFile.hashCode(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.xmind.core.Core; +import org.xmind.core.io.IInputSource; + +public class ZipFileInputSource implements IInputSource { + + private static class EntryIterAdapter implements Iterator { + + private Enumeration entries; + + /** + * @param entries + */ + public EntryIterAdapter(Enumeration entries) { + super(); + this.entries = entries; + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return entries.hasMoreElements(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#next() + */ + public String next() { + ZipEntry entry = entries.nextElement(); + if (entry == null) + return null; + return entry.getName(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + private ZipFile zipFile; + + public ZipFileInputSource(ZipFile zipFile) { + this.zipFile = zipFile; + } + + public Iterator getEntries() { + return new EntryIterAdapter(zipFile.entries()); + } + + public boolean hasEntry(String entryName) { + return zipFile.getEntry(entryName) != null; + } + + public InputStream getEntryStream(String entryName) { + ZipEntry entry = zipFile.getEntry(entryName); + if (entry == null) + return null; + try { + return zipFile.getInputStream(entry); + } catch (IOException e) { + Core.getLogger().log(e); + } + return null; + } + + public InputStream openEntryStream(String entryName) throws IOException { + ZipEntry entry = zipFile.getEntry(entryName); + if (entry == null) + throw new FileNotFoundException(entryName); + return zipFile.getInputStream(entry); + } + + public boolean isEntryAvailable(String entryName) { + ZipEntry entry = zipFile.getEntry(entryName); + return entry != null && !entry.isDirectory(); + } + + public void closeZipFile() { + try { + zipFile.close(); + } catch (IOException e) { + Core.getLogger().log(e); + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) + */ + public long getEntrySize(String entryName) { + ZipEntry entry = zipFile.getEntry(entryName); + if (entry != null) { + return entry.getSize(); + } + return -1; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) + */ + public long getEntryTime(String entryName) { + ZipEntry entry = zipFile.getEntry(entryName); + if (entry != null) { + return entry.getTime(); + } + return -1; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof ZipFileInputSource)) + return false; + ZipFileInputSource that = (ZipFileInputSource) obj; + return this.zipFile.equals(that.zipFile); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.zipFile.hashCode(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipStreamOutputTarget.java b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipStreamOutputTarget.java index 7bbb22845..af31e30fa 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipStreamOutputTarget.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/zip/ZipStreamOutputTarget.java @@ -1,131 +1,131 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.internal.zip; - -import java.io.Closeable; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.Deflater; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.xmind.core.Core; -import org.xmind.core.io.IOutputTarget; - -/** - * @author frankshaka - * - */ -public class ZipStreamOutputTarget implements IOutputTarget, Closeable { - - private static final boolean DEFAULT_COMPRESSED = Boolean - .getBoolean("org.xmind.core.workbook.compressed"); //$NON-NLS-1$ - - private static class ZipEntryOutputStream extends FilterOutputStream { - - /** - * @param out - */ - public ZipEntryOutputStream(ZipOutputStream out) { - super(out); - } - - @Override - public void write(byte[] b) throws IOException { - out.write(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - } - - @Override - public void write(int b) throws IOException { - out.write(b); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterOutputStream#close() - */ - @Override - public void close() throws IOException { - out.flush(); - ((ZipOutputStream) out).closeEntry(); - // Don't call out.close() to close the ZIP output stream. - } - - } - - private ZipOutputStream zip; - - private Map timeTable = new HashMap(); - - /** - * - */ - public ZipStreamOutputTarget(ZipOutputStream zip) { - this(zip, DEFAULT_COMPRESSED); - } - - public ZipStreamOutputTarget(ZipOutputStream zip, boolean compressed) { - this.zip = zip; - if (compressed) { - zip.setLevel(Deflater.DEFAULT_COMPRESSION); - } else { - zip.setLevel(Deflater.NO_COMPRESSION); - } - } - - public void setEntryTime(String entryName, long time) { - timeTable.put(entryName, Long.valueOf(time)); - } - - public OutputStream getEntryStream(String entryName) { - try { - return openEntryStream(entryName); - } catch (IOException e) { - Core.getLogger().log(e); - return null; - } - } - - public OutputStream openEntryStream(String entryName) throws IOException { - ZipEntry entry = new ZipEntry(entryName); - - Long time = timeTable.remove(entryName); - if (time != null) { - entry.setTime(time.longValue()); - } - - zip.putNextEntry(entry); - return new ZipEntryOutputStream(zip); - } - - public boolean isEntryAvaialble(String entryName) { - return zip != null; - } - - public void close() throws IOException { - zip.finish(); - zip.flush(); - zip.close(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.internal.zip; + +import java.io.Closeable; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.xmind.core.Core; +import org.xmind.core.io.IOutputTarget; + +/** + * @author frankshaka + * + */ +public class ZipStreamOutputTarget implements IOutputTarget, Closeable { + + private static final boolean DEFAULT_COMPRESSED = Boolean + .getBoolean("org.xmind.core.workbook.compressed"); //$NON-NLS-1$ + + private static class ZipEntryOutputStream extends FilterOutputStream { + + /** + * @param out + */ + public ZipEntryOutputStream(ZipOutputStream out) { + super(out); + } + + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + @Override + public void write(int b) throws IOException { + out.write(b); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterOutputStream#close() + */ + @Override + public void close() throws IOException { + out.flush(); + ((ZipOutputStream) out).closeEntry(); + // Don't call out.close() to close the ZIP output stream. + } + + } + + private ZipOutputStream zip; + + private Map timeTable = new HashMap(); + + /** + * + */ + public ZipStreamOutputTarget(ZipOutputStream zip) { + this(zip, DEFAULT_COMPRESSED); + } + + public ZipStreamOutputTarget(ZipOutputStream zip, boolean compressed) { + this.zip = zip; + if (compressed) { + zip.setLevel(Deflater.DEFAULT_COMPRESSION); + } else { + zip.setLevel(Deflater.NO_COMPRESSION); + } + } + + public void setEntryTime(String entryName, long time) { + timeTable.put(entryName, Long.valueOf(time)); + } + + public OutputStream getEntryStream(String entryName) { + try { + return openEntryStream(entryName); + } catch (IOException e) { + Core.getLogger().log(e); + return null; + } + } + + public OutputStream openEntryStream(String entryName) throws IOException { + ZipEntry entry = new ZipEntry(entryName); + + Long time = timeTable.remove(entryName); + if (time != null) { + entry.setTime(time.longValue()); + } + + zip.putNextEntry(entry); + return new ZipEntryOutputStream(zip); + } + + public boolean isEntryAvaialble(String entryName) { + return zip != null; + } + + public void close() throws IOException { + zip.finish(); + zip.flush(); + zip.close(); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/ByteArrayStorage.java b/bundles/org.xmind.core/src/org/xmind/core/io/ByteArrayStorage.java index 953e9debb..c2419b065 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/ByteArrayStorage.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/ByteArrayStorage.java @@ -1,294 +1,294 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * @author frankshaka - * - */ -public class ByteArrayStorage implements IStorage { - - private static Collection NO_ENTRIES = Collections.emptyList(); - - protected class ByteArrayInputSource implements IInputSource { - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntries() - */ - public Iterator getEntries() { - return dataTable == null ? NO_ENTRIES.iterator() - : dataTable.keySet().iterator(); - } - - public boolean isEntryAvailable(String entryName) { - return dataTable != null && dataTable.get(entryName) != null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntryStream(java.lang.String) - */ - public InputStream getEntryStream(String entryName) { - if (dataTable != null && entryName != null) { - byte[] bs = dataTable.get(entryName); - if (bs != null) { - return new ByteArrayInputStream(bs); - } - } - return null; - } - - public InputStream openEntryStream(String entryName) - throws IOException { - InputStream stream = getEntryStream(entryName); - if (stream == null) - throw new FileNotFoundException(entryName); - return stream; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) - */ - public long getEntrySize(String entryName) { - if (dataTable != null && entryName != null) { - byte[] bs = dataTable.get(entryName); - if (bs != null) { - return bs.length; - } - } - return -1; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) - */ - public long getEntryTime(String entryName) { - if (timeTable != null && entryName != null) { - Long time = timeTable.get(entryName); - if (time != null) - return time.longValue(); - } - return 0; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#hasEntry(java.lang.String) - */ - public boolean hasEntry(String entryName) { - return dataTable != null && dataTable.containsKey(entryName); - } - - } - - protected class ByteArrayOutputTarget implements IOutputTarget { - - private class EntryByteArrayOutputStream extends ByteArrayOutputStream { - - private String entryName; - - /** - * - */ - public EntryByteArrayOutputStream(String entryName) { - this.entryName = entryName; - } - - /* - * (non-Javadoc) - * - * @see java.io.OutputStream#flush() - */ - @Override - public void flush() throws IOException { - super.flush(); - pushBytes(); - } - - /* - * (non-Javadoc) - * - * @see java.io.ByteArrayOutputStream#close() - */ - @Override - public void close() throws IOException { - super.close(); - pushBytes(); - synchronized (ByteArrayOutputTarget.this) { - if (timeTable == null - || !timeTable.containsKey(entryName)) { - setEntryTime(entryName, System.currentTimeMillis()); - } - } - } - - /** - * - */ - private void pushBytes() { - putEntryData(entryName, toByteArray()); - } - - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IOutputTarget#getEntryStream(java.lang.String) - */ - public OutputStream getEntryStream(String entryName) { - return new EntryByteArrayOutputStream(entryName); - } - - public OutputStream openEntryStream(String entryName) - throws IOException { - return new EntryByteArrayOutputStream(entryName); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.core.io.IOutputTarget#isEntryAvaialble(java.lang.String) - */ - public boolean isEntryAvaialble(String entryName) { - return entryName != null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IOutputTarget#setEntryTime(long) - */ - public void setEntryTime(String entryName, long time) { - synchronized (this) { - if (timeTable == null) { - timeTable = new HashMap(); - } - timeTable.put(entryName, time); - } - } - - } - - private Map dataTable; - - private Map timeTable; - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IArchive#getFullPath() - */ - public String getFullPath() { - return getName(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IArchive#getInputSource() - */ - public IInputSource getInputSource() { - return new ByteArrayInputSource(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IArchive#getName() - */ - public String getName() { - return toString(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IArchive#getOutputTarget() - */ - public IOutputTarget getOutputTarget() { - return new ByteArrayOutputTarget(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IStorage#clear() - */ - public void clear() { - dataTable = null; - timeTable = null; - } - - public void deleteEntry(String entryName) { - if (dataTable != null) { - dataTable.remove(entryName); - } - if (timeTable != null) { - timeTable.remove(entryName); - } - } - - public void renameEntry(String entryName, String newName) { - if (dataTable != null) { - byte[] data = dataTable.remove(entryName); - if (data != null) { - dataTable.put(newName, data); - } else { - dataTable.remove(newName); - } - } - if (timeTable != null) { - Long time = timeTable.remove(entryName); - if (time != null) { - timeTable.put(newName, time); - } else { - timeTable.remove(newName); - } - } - } - - public byte[] getEntryData(String entryPath) { - return dataTable == null ? null : dataTable.get(entryPath); - } - - public void putEntryData(String entryPath, byte[] data) { - if (dataTable == null) { - dataTable = new HashMap(); - } - dataTable.put(entryPath, data); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author frankshaka + * + */ +public class ByteArrayStorage implements IStorage { + + private static Collection NO_ENTRIES = Collections.emptyList(); + + protected class ByteArrayInputSource implements IInputSource { + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntries() + */ + public Iterator getEntries() { + return dataTable == null ? NO_ENTRIES.iterator() + : dataTable.keySet().iterator(); + } + + public boolean isEntryAvailable(String entryName) { + return dataTable != null && dataTable.get(entryName) != null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntryStream(java.lang.String) + */ + public InputStream getEntryStream(String entryName) { + if (dataTable != null && entryName != null) { + byte[] bs = dataTable.get(entryName); + if (bs != null) { + return new ByteArrayInputStream(bs); + } + } + return null; + } + + public InputStream openEntryStream(String entryName) + throws IOException { + InputStream stream = getEntryStream(entryName); + if (stream == null) + throw new FileNotFoundException(entryName); + return stream; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) + */ + public long getEntrySize(String entryName) { + if (dataTable != null && entryName != null) { + byte[] bs = dataTable.get(entryName); + if (bs != null) { + return bs.length; + } + } + return -1; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) + */ + public long getEntryTime(String entryName) { + if (timeTable != null && entryName != null) { + Long time = timeTable.get(entryName); + if (time != null) + return time.longValue(); + } + return 0; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#hasEntry(java.lang.String) + */ + public boolean hasEntry(String entryName) { + return dataTable != null && dataTable.containsKey(entryName); + } + + } + + protected class ByteArrayOutputTarget implements IOutputTarget { + + private class EntryByteArrayOutputStream extends ByteArrayOutputStream { + + private String entryName; + + /** + * + */ + public EntryByteArrayOutputStream(String entryName) { + this.entryName = entryName; + } + + /* + * (non-Javadoc) + * + * @see java.io.OutputStream#flush() + */ + @Override + public void flush() throws IOException { + super.flush(); + pushBytes(); + } + + /* + * (non-Javadoc) + * + * @see java.io.ByteArrayOutputStream#close() + */ + @Override + public void close() throws IOException { + super.close(); + pushBytes(); + synchronized (ByteArrayOutputTarget.this) { + if (timeTable == null + || !timeTable.containsKey(entryName)) { + setEntryTime(entryName, System.currentTimeMillis()); + } + } + } + + /** + * + */ + private void pushBytes() { + putEntryData(entryName, toByteArray()); + } + + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IOutputTarget#getEntryStream(java.lang.String) + */ + public OutputStream getEntryStream(String entryName) { + return new EntryByteArrayOutputStream(entryName); + } + + public OutputStream openEntryStream(String entryName) + throws IOException { + return new EntryByteArrayOutputStream(entryName); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.core.io.IOutputTarget#isEntryAvaialble(java.lang.String) + */ + public boolean isEntryAvaialble(String entryName) { + return entryName != null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IOutputTarget#setEntryTime(long) + */ + public void setEntryTime(String entryName, long time) { + synchronized (this) { + if (timeTable == null) { + timeTable = new HashMap(); + } + timeTable.put(entryName, time); + } + } + + } + + private Map dataTable; + + private Map timeTable; + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IArchive#getFullPath() + */ + public String getFullPath() { + return getName(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IArchive#getInputSource() + */ + public IInputSource getInputSource() { + return new ByteArrayInputSource(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IArchive#getName() + */ + public String getName() { + return toString(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IArchive#getOutputTarget() + */ + public IOutputTarget getOutputTarget() { + return new ByteArrayOutputTarget(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IStorage#clear() + */ + public void clear() { + dataTable = null; + timeTable = null; + } + + public void deleteEntry(String entryName) { + if (dataTable != null) { + dataTable.remove(entryName); + } + if (timeTable != null) { + timeTable.remove(entryName); + } + } + + public void renameEntry(String entryName, String newName) { + if (dataTable != null) { + byte[] data = dataTable.remove(entryName); + if (data != null) { + dataTable.put(newName, data); + } else { + dataTable.remove(newName); + } + } + if (timeTable != null) { + Long time = timeTable.remove(entryName); + if (time != null) { + timeTable.put(newName, time); + } else { + timeTable.remove(newName); + } + } + } + + public byte[] getEntryData(String entryPath) { + return dataTable == null ? null : dataTable.get(entryPath); + } + + public void putEntryData(String entryPath, byte[] data) { + if (dataTable == null) { + dataTable = new HashMap(); + } + dataTable.put(entryPath, data); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumTrackingOutputStream.java b/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumTrackingOutputStream.java index 43cf5e17c..b848bf6f8 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumTrackingOutputStream.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumTrackingOutputStream.java @@ -1,88 +1,88 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.core.IChecksumStream; -import org.xmind.core.IEncryptionData; - -/** - * @author Frank Shaka - * - */ -public class ChecksumTrackingOutputStream extends FilterOutputStream { - - private final IEncryptionData encData; - - /** - * @param out - */ - public ChecksumTrackingOutputStream(IEncryptionData encData, - OutputStream out) { - super(out); - this.encData = encData; - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterOutputStream#write(byte[]) - */ - @Override - public void write(byte[] b) throws IOException { - out.write(b); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterOutputStream#write(byte[], int, int) - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterOutputStream#write(int) - */ - @Override - public void write(int b) throws IOException { - out.write(b); - } - - /* - * (non-Javadoc) - * - * @see java.io.FilterOutputStream#close() - */ - @Override - public void close() throws IOException { - super.close(); - - if (out instanceof IChecksumStream) { - String checksum = ((IChecksumStream) out).getChecksum(); - encData.setChecksum(checksum); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.io; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.core.IChecksumStream; +import org.xmind.core.IEncryptionData; + +/** + * @author Frank Shaka + * + */ +public class ChecksumTrackingOutputStream extends FilterOutputStream { + + private final IEncryptionData encData; + + /** + * @param out + */ + public ChecksumTrackingOutputStream(IEncryptionData encData, + OutputStream out) { + super(out); + this.encData = encData; + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterOutputStream#write(byte[]) + */ + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterOutputStream#write(byte[], int, int) + */ + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterOutputStream#write(int) + */ + @Override + public void write(int b) throws IOException { + out.write(b); + } + + /* + * (non-Javadoc) + * + * @see java.io.FilterOutputStream#close() + */ + @Override + public void close() throws IOException { + super.close(); + + if (out instanceof IChecksumStream) { + String checksum = ((IChecksumStream) out).getChecksum(); + encData.setChecksum(checksum); + } + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumVerifiedInputStream.java b/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumVerifiedInputStream.java index 6c09246e2..959f75070 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumVerifiedInputStream.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/ChecksumVerifiedInputStream.java @@ -1,79 +1,79 @@ -package org.xmind.core.io; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.xmind.core.IChecksumStream; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class ChecksumVerifiedInputStream extends FilterInputStream - implements IChecksumStream { - - private String expectedChecksum; - - public ChecksumVerifiedInputStream(InputStream in, - String expectedChecksum) { - super(in); - this.expectedChecksum = expectedChecksum; - } - - @Override - public int read() throws IOException { - int n = super.read(); - if (n < 0) { - verifyChecksum(); - } - return n; - } - - @Override - public int read(byte[] b) throws IOException { - int n = super.read(b); - if (n < 0) { - verifyChecksum(); - } - return n; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int n = super.read(b, off, len); - if (n < 0) { - verifyChecksum(); - } - return n; - } - - @Override - public void close() throws IOException { - try { - super.close(); - } finally { - verifyChecksum(); - } - } - - private void verifyChecksum() throws InvalidChecksumException { - if (!(in instanceof IChecksumStream)) - return; - - String checksum = ((IChecksumStream) in).getChecksum(); - if (checksum == expectedChecksum - || (checksum != null && checksum.equals(expectedChecksum))) - return; - - throw new InvalidChecksumException(expectedChecksum, checksum); - } - - public String getChecksum() { - if (in instanceof IChecksumStream) - return ((IChecksumStream) in).getChecksum(); - return null; - } - -} +package org.xmind.core.io; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.xmind.core.IChecksumStream; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class ChecksumVerifiedInputStream extends FilterInputStream + implements IChecksumStream { + + private String expectedChecksum; + + public ChecksumVerifiedInputStream(InputStream in, + String expectedChecksum) { + super(in); + this.expectedChecksum = expectedChecksum; + } + + @Override + public int read() throws IOException { + int n = super.read(); + if (n < 0) { + verifyChecksum(); + } + return n; + } + + @Override + public int read(byte[] b) throws IOException { + int n = super.read(b); + if (n < 0) { + verifyChecksum(); + } + return n; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int n = super.read(b, off, len); + if (n < 0) { + verifyChecksum(); + } + return n; + } + + @Override + public void close() throws IOException { + try { + super.close(); + } finally { + verifyChecksum(); + } + } + + private void verifyChecksum() throws InvalidChecksumException { + if (!(in instanceof IChecksumStream)) + return; + + String checksum = ((IChecksumStream) in).getChecksum(); + if (checksum == expectedChecksum + || (checksum != null && checksum.equals(expectedChecksum))) + return; + + throw new InvalidChecksumException(expectedChecksum, checksum); + } + + public String getChecksum() { + if (in instanceof IChecksumStream) + return ((IChecksumStream) in).getChecksum(); + return null; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/CoreIOException.java b/bundles/org.xmind.core/src/org/xmind/core/io/CoreIOException.java index a6c09ffb2..6c668df8d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/CoreIOException.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/CoreIOException.java @@ -1,38 +1,38 @@ -package org.xmind.core.io; - -import java.io.IOException; - -import org.xmind.core.CoreException; - -/** - * This class simply wraps a {@link CoreException} into an {@link IOException} - * so that, when performing I/O operations, core exceptions can be successfully - * thrown and caught. - * - * @author Frank Shaka - * @since 3.6.2 - */ -public class CoreIOException extends IOException { - - /** - * - */ - private static final long serialVersionUID = -5617725226498169561L; - - private CoreException coreException; - - public CoreIOException(CoreException coreException) { - super(coreException.getMessage(), coreException); - this.coreException = coreException; - } - - public CoreException getCoreException() { - return this.coreException; - } - - @Override - public synchronized Throwable getCause() { - return this.coreException; - } - -} +package org.xmind.core.io; + +import java.io.IOException; + +import org.xmind.core.CoreException; + +/** + * This class simply wraps a {@link CoreException} into an {@link IOException} + * so that, when performing I/O operations, core exceptions can be successfully + * thrown and caught. + * + * @author Frank Shaka + * @since 3.6.2 + */ +public class CoreIOException extends IOException { + + /** + * + */ + private static final long serialVersionUID = -5617725226498169561L; + + private CoreException coreException; + + public CoreIOException(CoreException coreException) { + super(coreException.getMessage(), coreException); + this.coreException = coreException; + } + + public CoreException getCoreException() { + return this.coreException; + } + + @Override + public synchronized Throwable getCause() { + return this.coreException; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryInputSource.java b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryInputSource.java index 8ff3cc55e..d71be6a97 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryInputSource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryInputSource.java @@ -1,195 +1,195 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.xmind.core.Core; - -public class DirectoryInputSource implements IInputSource { - - private File dir; - - private FileFilter filter; - - public DirectoryInputSource(File file) { - this(file, null); - } - - public DirectoryInputSource(String path) { - this(new File(path), null); - } - - /** - * - */ - public DirectoryInputSource(File file, FileFilter filter) { - this.dir = file; - this.filter = filter; - } - - /** - * @return the file - */ - public File getFile() { - return dir; - } - - public FileFilter getFilter() { - return filter; - } - - public void setFilter(FileFilter filter) { - this.filter = filter; - } - - public String getName() { - return dir.getName(); - } - - public Iterator getEntries() { - List list = new ArrayList(); - getSubFiles("", dir, list); //$NON-NLS-1$ - return list.iterator(); - } - - private void getSubFiles(String parentEntry, File parentFile, - List list) { - if (!parentFile.isDirectory()) - return; - - for (File file : parentFile.listFiles()) { - if (filter == null || filter.accept(file)) { - String entryName; - if ("".equals(parentEntry)) { //$NON-NLS-1$ - entryName = file.getName(); - } else { - entryName = parentEntry + "/" + file.getName(); //$NON-NLS-1$ - } - if (!file.isDirectory()) { - list.add(entryName); - } - getSubFiles(entryName, file, list); - } - } - } - - public boolean isEntryAvailable(String entryName) { - return isAvailable() && !new File(dir, entryName).isDirectory(); - } - - protected boolean isAvailable() { - return dir.exists() && dir.isDirectory(); - } - - public boolean hasEntry(String entryName) { - File f = new File(dir, entryName); - return f.exists() && f.canRead() - && (filter == null || filter.accept(f)); - } - - public InputStream getEntryStream(String entryName) { - if (!isAvailable()) - return null; - - File file = new File(dir, entryName); - if (file.isFile() && file.canRead()) { - try { - return new FileInputStream(file); - } catch (FileNotFoundException e) { - Core.getLogger().log(e, - "Failed to get entry input stream: " + entryName); //$NON-NLS-1$ - } - } - return null; - } - - public InputStream openEntryStream(String entryName) throws IOException { - File file = new File(dir, entryName); - if (!file.exists()) - throw new FileNotFoundException(file.toString()); - return new FileInputStream(file); - } - - public boolean closeEntryStream(String entryPath, InputStream stream) { - try { - stream.close(); - return true; - } catch (IOException e) { - Core.getLogger().log(e, - "Failed to close entry input stream: " + entryPath); //$NON-NLS-1$ - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) - */ - public long getEntrySize(String entryName) { - File f = new File(dir, entryName); - if (f.exists()) - return f.length(); - return -1; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) - */ - public long getEntryTime(String entryName) { - File f = new File(dir, entryName); - if (f.exists()) - return f.lastModified(); - return -1; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof DirectoryInputSource)) - return false; - DirectoryInputSource that = (DirectoryInputSource) obj; - return this.dir.equals(that.dir) && (this.filter == that.filter - || (this.filter != null && this.filter.equals(that.filter))); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return this.dir.hashCode() - ^ (this.filter == null ? 1 : this.filter.hashCode()); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.xmind.core.Core; + +public class DirectoryInputSource implements IInputSource { + + private File dir; + + private FileFilter filter; + + public DirectoryInputSource(File file) { + this(file, null); + } + + public DirectoryInputSource(String path) { + this(new File(path), null); + } + + /** + * + */ + public DirectoryInputSource(File file, FileFilter filter) { + this.dir = file; + this.filter = filter; + } + + /** + * @return the file + */ + public File getFile() { + return dir; + } + + public FileFilter getFilter() { + return filter; + } + + public void setFilter(FileFilter filter) { + this.filter = filter; + } + + public String getName() { + return dir.getName(); + } + + public Iterator getEntries() { + List list = new ArrayList(); + getSubFiles("", dir, list); //$NON-NLS-1$ + return list.iterator(); + } + + private void getSubFiles(String parentEntry, File parentFile, + List list) { + if (!parentFile.isDirectory()) + return; + + for (File file : parentFile.listFiles()) { + if (filter == null || filter.accept(file)) { + String entryName; + if ("".equals(parentEntry)) { //$NON-NLS-1$ + entryName = file.getName(); + } else { + entryName = parentEntry + "/" + file.getName(); //$NON-NLS-1$ + } + if (!file.isDirectory()) { + list.add(entryName); + } + getSubFiles(entryName, file, list); + } + } + } + + public boolean isEntryAvailable(String entryName) { + return isAvailable() && !new File(dir, entryName).isDirectory(); + } + + protected boolean isAvailable() { + return dir.exists() && dir.isDirectory(); + } + + public boolean hasEntry(String entryName) { + File f = new File(dir, entryName); + return f.exists() && f.canRead() + && (filter == null || filter.accept(f)); + } + + public InputStream getEntryStream(String entryName) { + if (!isAvailable()) + return null; + + File file = new File(dir, entryName); + if (file.isFile() && file.canRead()) { + try { + return new FileInputStream(file); + } catch (FileNotFoundException e) { + Core.getLogger().log(e, + "Failed to get entry input stream: " + entryName); //$NON-NLS-1$ + } + } + return null; + } + + public InputStream openEntryStream(String entryName) throws IOException { + File file = new File(dir, entryName); + if (!file.exists()) + throw new FileNotFoundException(file.toString()); + return new FileInputStream(file); + } + + public boolean closeEntryStream(String entryPath, InputStream stream) { + try { + stream.close(); + return true; + } catch (IOException e) { + Core.getLogger().log(e, + "Failed to close entry input stream: " + entryPath); //$NON-NLS-1$ + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String) + */ + public long getEntrySize(String entryName) { + File f = new File(dir, entryName); + if (f.exists()) + return f.length(); + return -1; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String) + */ + public long getEntryTime(String entryName) { + File f = new File(dir, entryName); + if (f.exists()) + return f.lastModified(); + return -1; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof DirectoryInputSource)) + return false; + DirectoryInputSource that = (DirectoryInputSource) obj; + return this.dir.equals(that.dir) && (this.filter == that.filter + || (this.filter != null && this.filter.equals(that.filter))); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.dir.hashCode() + ^ (this.filter == null ? 1 : this.filter.hashCode()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryOutputTarget.java b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryOutputTarget.java index 9e7f02e09..b0b95ef77 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryOutputTarget.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryOutputTarget.java @@ -1,110 +1,110 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import org.xmind.core.Core; - -public class DirectoryOutputTarget implements IOutputTarget { - - private class TimedFileOutputStream extends FileOutputStream { - - private String entryName; - - private File file; - - public TimedFileOutputStream(String entryName, File file) - throws FileNotFoundException { - super(file); - this.entryName = entryName; - this.file = file; - } - - public void close() throws IOException { - super.close(); - Long time = timeTable.remove(entryName); - if (time != null) { - file.setLastModified(time.longValue()); - } - } - - } - - private File dir; - - private Map timeTable = new HashMap(); - - public DirectoryOutputTarget(String path) { - this.dir = new File(path); - } - - public DirectoryOutputTarget(File file) { - this.dir = file; - } - - public OutputStream getEntryStream(String entryName) { - if (!isAvailable()) - return null; - - try { - return openEntryStream(entryName); - } catch (IOException e) { - Core.getLogger().log(e, - "Failed to get entry output stream for file: " //$NON-NLS-1$ - + new File(dir, entryName).getPath()); - return null; - } - } - - public OutputStream openEntryStream(String entryName) throws IOException { - File file = new File(dir, entryName); - File parent = file.getParentFile(); - if (!parent.exists()) { - parent.mkdirs(); - } - return new TimedFileOutputStream(entryName, file); - } - - public boolean isEntryAvaialble(String entryName) { - return isAvailable() && !new File(dir, entryName).isDirectory(); - } - - public boolean isAvailable() { - if (!dir.exists()) { - dir.mkdirs(); - } - return dir.exists() && dir.isDirectory(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IOutputTarget#setEntryTime(java.lang.String, long) - */ - public void setEntryTime(String entryName, long time) { - timeTable.put(entryName, Long.valueOf(time)); - File f = new File(dir, entryName); - if (f.exists()) { - f.setLastModified(time); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +import org.xmind.core.Core; + +public class DirectoryOutputTarget implements IOutputTarget { + + private class TimedFileOutputStream extends FileOutputStream { + + private String entryName; + + private File file; + + public TimedFileOutputStream(String entryName, File file) + throws FileNotFoundException { + super(file); + this.entryName = entryName; + this.file = file; + } + + public void close() throws IOException { + super.close(); + Long time = timeTable.remove(entryName); + if (time != null) { + file.setLastModified(time.longValue()); + } + } + + } + + private File dir; + + private Map timeTable = new HashMap(); + + public DirectoryOutputTarget(String path) { + this.dir = new File(path); + } + + public DirectoryOutputTarget(File file) { + this.dir = file; + } + + public OutputStream getEntryStream(String entryName) { + if (!isAvailable()) + return null; + + try { + return openEntryStream(entryName); + } catch (IOException e) { + Core.getLogger().log(e, + "Failed to get entry output stream for file: " //$NON-NLS-1$ + + new File(dir, entryName).getPath()); + return null; + } + } + + public OutputStream openEntryStream(String entryName) throws IOException { + File file = new File(dir, entryName); + File parent = file.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } + return new TimedFileOutputStream(entryName, file); + } + + public boolean isEntryAvaialble(String entryName) { + return isAvailable() && !new File(dir, entryName).isDirectory(); + } + + public boolean isAvailable() { + if (!dir.exists()) { + dir.mkdirs(); + } + return dir.exists() && dir.isDirectory(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IOutputTarget#setEntryTime(java.lang.String, long) + */ + public void setEntryTime(String entryName, long time) { + timeTable.put(entryName, Long.valueOf(time)); + File f = new File(dir, entryName); + if (f.exists()) { + f.setLastModified(time); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryStorage.java b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryStorage.java index de7ed90b0..db775192f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryStorage.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/DirectoryStorage.java @@ -1,143 +1,143 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.File; -import java.io.FileFilter; - -import org.xmind.core.util.FileUtils; - -/** - * @author frankshaka - * - */ -public class DirectoryStorage implements IStorage { - - private File dir; - - private FileFilter filter; - - /** - * - */ - public DirectoryStorage(File dir) { - this(dir, null); - } - - /** - * - */ - public DirectoryStorage(File dir, FileFilter filter) { - this.dir = dir; - this.filter = filter; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IRandomAccessArchive#getFullPath() - */ - public String getFullPath() { - return dir.getAbsolutePath(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IRandomAccessArchive#getInputSource() - */ - public IInputSource getInputSource() { - return new DirectoryInputSource(dir, filter); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IRandomAccessArchive#getName() - */ - public String getName() { - return dir.getName(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IRandomAccessArchive#getOutputTarget() - */ - public IOutputTarget getOutputTarget() { - return new DirectoryOutputTarget(dir); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.core.io.IStorage#clear() - */ - public void clear() { - FileUtils.delete(dir); - } - - public void deleteEntry(String entryName) { - File f = new File(dir, entryName); - while (f != null && !f.equals(dir)) { - if (f.isFile() || (f.isDirectory() && f.list().length == 0)) { - f.delete(); - } - f = f.getParentFile(); - } - dir.delete(); - } - - public void renameEntry(String entryName, String newName) { - File targetFile = new File(dir, newName); - File targetParent = targetFile.getParentFile(); - if (targetParent != null) { - targetParent.mkdirs(); - } - new File(dir, entryName).renameTo(targetFile); - deleteEntry(entryName); - } - - @Override - public String toString() { - return dir.toString(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return dir.hashCode() ^ (filter == null ? 37 : filter.hashCode()); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof DirectoryStorage)) - return false; - DirectoryStorage that = (DirectoryStorage) obj; - return this.dir.equals(that.dir) && (this.filter == that.filter - || (this.filter != null && this.filter.equals(that.filter))); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.File; +import java.io.FileFilter; + +import org.xmind.core.util.FileUtils; + +/** + * @author frankshaka + * + */ +public class DirectoryStorage implements IStorage { + + private File dir; + + private FileFilter filter; + + /** + * + */ + public DirectoryStorage(File dir) { + this(dir, null); + } + + /** + * + */ + public DirectoryStorage(File dir, FileFilter filter) { + this.dir = dir; + this.filter = filter; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IRandomAccessArchive#getFullPath() + */ + public String getFullPath() { + return dir.getAbsolutePath(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IRandomAccessArchive#getInputSource() + */ + public IInputSource getInputSource() { + return new DirectoryInputSource(dir, filter); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IRandomAccessArchive#getName() + */ + public String getName() { + return dir.getName(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IRandomAccessArchive#getOutputTarget() + */ + public IOutputTarget getOutputTarget() { + return new DirectoryOutputTarget(dir); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.core.io.IStorage#clear() + */ + public void clear() { + FileUtils.delete(dir); + } + + public void deleteEntry(String entryName) { + File f = new File(dir, entryName); + while (f != null && !f.equals(dir)) { + if (f.isFile() || (f.isDirectory() && f.list().length == 0)) { + f.delete(); + } + f = f.getParentFile(); + } + dir.delete(); + } + + public void renameEntry(String entryName, String newName) { + File targetFile = new File(dir, newName); + File targetParent = targetFile.getParentFile(); + if (targetParent != null) { + targetParent.mkdirs(); + } + new File(dir, entryName).renameTo(targetFile); + deleteEntry(entryName); + } + + @Override + public String toString() { + return dir.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return dir.hashCode() ^ (filter == null ? 37 : filter.hashCode()); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof DirectoryStorage)) + return false; + DirectoryStorage that = (DirectoryStorage) obj; + return this.dir.equals(that.dir) && (this.filter == that.filter + || (this.filter != null && this.filter.equals(that.filter))); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/ICloseableOutputTarget.java b/bundles/org.xmind.core/src/org/xmind/core/io/ICloseableOutputTarget.java index 04ac29e79..5c7a22aa3 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/ICloseableOutputTarget.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/ICloseableOutputTarget.java @@ -1,21 +1,21 @@ -package org.xmind.core.io; - -import java.io.IOException; - -/** - * @deprecated Use {@link java.io.Closeable} instead. - * - * @author Frank Shaka - */ -@Deprecated -public interface ICloseableOutputTarget extends IOutputTarget { - - /** - * Close this output target and flush all contents to the target. - * - * @deprecated - */ - @Deprecated - void close() throws IOException; - -} +package org.xmind.core.io; + +import java.io.IOException; + +/** + * @deprecated Use {@link java.io.Closeable} instead. + * + * @author Frank Shaka + */ +@Deprecated +public interface ICloseableOutputTarget extends IOutputTarget { + + /** + * Close this output target and flush all contents to the target. + * + * @deprecated + */ + @Deprecated + void close() throws IOException; + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/IInputSource.java b/bundles/org.xmind.core/src/org/xmind/core/io/IInputSource.java index 46b041216..e125d852b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/IInputSource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/IInputSource.java @@ -1,90 +1,90 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -public interface IInputSource { - - /** - * - * @param entryName - * @return - */ - boolean hasEntry(String entryName); - - /** - * - * @return - */ - Iterator getEntries(); - - /** - * Determines whether a specified entry is a available. - * - * @param entryName - * the name of the entry - * @return true if the specified entry is available, or - * false otherwise - */ - boolean isEntryAvailable(String entryName); - - /** - * Opens a new input stream to read data from for specified entry. - * - * @deprecated For diagnostic purpose, this method is not - * recommended any more. Use {@link #openEntryStream(String)} - * instead to let potential I/O errors be thrown. - * - * @param entryName - * the name of the entry - * @return an input stream for the specified entry, or null if - * the specified entry is not available - */ - InputStream getEntryStream(String entryName); - - /** - * Opens a new input stream to read data from for the specified entry. - * - * @param entryName - * @return an output stream for the specified entry (never null - * ) - * @throws IOException - * if I/O error occurs or entry is not found - */ - InputStream openEntryStream(String entryName) throws IOException; - - /** - * Returns the file size of the specific entry. - * - * @param entryName - * The name of the entry - * @return The file size of the specific entry; or -1 if the - * entry does not exist - */ - long getEntrySize(String entryName); - - /** - * Returns the last modification time of the specific entry. - * - * @param entryName - * The name of the entry - * @return The last modification time of the specific entry; or - * -1 if the entry does not exist - */ - long getEntryTime(String entryName); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +public interface IInputSource { + + /** + * + * @param entryName + * @return + */ + boolean hasEntry(String entryName); + + /** + * + * @return + */ + Iterator getEntries(); + + /** + * Determines whether a specified entry is a available. + * + * @param entryName + * the name of the entry + * @return true if the specified entry is available, or + * false otherwise + */ + boolean isEntryAvailable(String entryName); + + /** + * Opens a new input stream to read data from for specified entry. + * + * @deprecated For diagnostic purpose, this method is not + * recommended any more. Use {@link #openEntryStream(String)} + * instead to let potential I/O errors be thrown. + * + * @param entryName + * the name of the entry + * @return an input stream for the specified entry, or null if + * the specified entry is not available + */ + InputStream getEntryStream(String entryName); + + /** + * Opens a new input stream to read data from for the specified entry. + * + * @param entryName + * @return an output stream for the specified entry (never null + * ) + * @throws IOException + * if I/O error occurs or entry is not found + */ + InputStream openEntryStream(String entryName) throws IOException; + + /** + * Returns the file size of the specific entry. + * + * @param entryName + * The name of the entry + * @return The file size of the specific entry; or -1 if the + * entry does not exist + */ + long getEntrySize(String entryName); + + /** + * Returns the last modification time of the specific entry. + * + * @param entryName + * The name of the entry + * @return The last modification time of the specific entry; or + * -1 if the entry does not exist + */ + long getEntryTime(String entryName); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/IOutputTarget.java b/bundles/org.xmind.core/src/org/xmind/core/io/IOutputTarget.java index f788bacb6..3d477c97c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/IOutputTarget.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/IOutputTarget.java @@ -1,79 +1,79 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An output target provides abilities to write multi-entry data into specific - * resources. - * - * @author Frank Shaka - */ -public interface IOutputTarget { - - /** - * Determines whether an entry with the specified name is available or not. - * - * @param entryName - * the name of the desired entry - * @return true if the entry is available, or - * false otherwise - */ - boolean isEntryAvaialble(String entryName); - - /** - * Opens a new output stream to receive data for the specified entry. The - * stream should be closed by clients when data writing finishes. - * - * @deprecated For diagnostic purpose, this method is not - * recommended any more. Use {@link #openEntryStream(String)} - * instead to let potential I/O errors be thrown. - * - * @param entryName - * the name of the entry - * @return an output stream for the specified entry, or null if - * the specified entry is not available - */ - @Deprecated - OutputStream getEntryStream(String entryName); - - /** - * Opens a new output stream to receive data for the specified entry. The - * stream should be closed by clients when data writing finishes. - * - * @param entryName - * the name of the entry - * @return an output stream for the specified entry (never null - * ) - * @throws IOException - * if I/O error occurs - */ - OutputStream openEntryStream(String entryName) throws IOException; - - /** - * Sets the modification time of the specific entry. - * - *

- * Note that this method should be called before - * getEntryStream(), otherwise it may have no effect. - *

- * - * @param time - * the new modification time to set - */ - void setEntryTime(String entryName, long time); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An output target provides abilities to write multi-entry data into specific + * resources. + * + * @author Frank Shaka + */ +public interface IOutputTarget { + + /** + * Determines whether an entry with the specified name is available or not. + * + * @param entryName + * the name of the desired entry + * @return true if the entry is available, or + * false otherwise + */ + boolean isEntryAvaialble(String entryName); + + /** + * Opens a new output stream to receive data for the specified entry. The + * stream should be closed by clients when data writing finishes. + * + * @deprecated For diagnostic purpose, this method is not + * recommended any more. Use {@link #openEntryStream(String)} + * instead to let potential I/O errors be thrown. + * + * @param entryName + * the name of the entry + * @return an output stream for the specified entry, or null if + * the specified entry is not available + */ + @Deprecated + OutputStream getEntryStream(String entryName); + + /** + * Opens a new output stream to receive data for the specified entry. The + * stream should be closed by clients when data writing finishes. + * + * @param entryName + * the name of the entry + * @return an output stream for the specified entry (never null + * ) + * @throws IOException + * if I/O error occurs + */ + OutputStream openEntryStream(String entryName) throws IOException; + + /** + * Sets the modification time of the specific entry. + * + *

+ * Note that this method should be called before + * getEntryStream(), otherwise it may have no effect. + *

+ * + * @param time + * the new modification time to set + */ + void setEntryTime(String entryName, long time); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/IStorage.java b/bundles/org.xmind.core/src/org/xmind/core/io/IStorage.java index 7cf4aac59..ca4b6143d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/IStorage.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/IStorage.java @@ -1,63 +1,63 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.io; - -/** - * @author Frank Shaka - * - */ -public interface IStorage { - - /** - * - * @return - */ - IInputSource getInputSource(); - - /** - * - * @return - */ - IOutputTarget getOutputTarget(); - - /** - * - * @return The name of this archive - */ - String getName(); - - /** - * @return - */ - String getFullPath(); - - /** - * - */ - void clear(); - - /** - * - * @param entryName - */ - void deleteEntry(String entryName); - - /** - * - * @param entryName - * @param newName - */ - void renameEntry(String entryName, String newName); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.io; + +/** + * @author Frank Shaka + * + */ +public interface IStorage { + + /** + * + * @return + */ + IInputSource getInputSource(); + + /** + * + * @return + */ + IOutputTarget getOutputTarget(); + + /** + * + * @return The name of this archive + */ + String getName(); + + /** + * @return + */ + String getFullPath(); + + /** + * + */ + void clear(); + + /** + * + * @param entryName + */ + void deleteEntry(String entryName); + + /** + * + * @param entryName + * @param newName + */ + void renameEntry(String entryName, String newName); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/InvalidChecksumException.java b/bundles/org.xmind.core/src/org/xmind/core/io/InvalidChecksumException.java index fe7ed62e8..fe6d7e204 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/InvalidChecksumException.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/InvalidChecksumException.java @@ -1,36 +1,36 @@ -package org.xmind.core.io; - -import java.io.IOException; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class InvalidChecksumException extends IOException { - - /** - * - */ - private static final long serialVersionUID = -7976264532100430240L; - - private String expectedValue; - - private String actualValue; - - public InvalidChecksumException(String expectedValue, String actualValue) { - super("Invalid checksum, expected value is '" + expectedValue //$NON-NLS-1$ - + "', actual value is '" + actualValue + "'"); //$NON-NLS-1$ //$NON-NLS-2$ - this.expectedValue = expectedValue; - this.actualValue = actualValue; - } - - public String getExpectedValue() { - return expectedValue; - } - - public String getActualValue() { - return actualValue; - } - -} +package org.xmind.core.io; + +import java.io.IOException; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class InvalidChecksumException extends IOException { + + /** + * + */ + private static final long serialVersionUID = -7976264532100430240L; + + private String expectedValue; + + private String actualValue; + + public InvalidChecksumException(String expectedValue, String actualValue) { + super("Invalid checksum, expected value is '" + expectedValue //$NON-NLS-1$ + + "', actual value is '" + actualValue + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + this.expectedValue = expectedValue; + this.actualValue = actualValue; + } + + public String getExpectedValue() { + return expectedValue; + } + + public String getActualValue() { + return actualValue; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/io/PrefixedStorage.java b/bundles/org.xmind.core/src/org/xmind/core/io/PrefixedStorage.java index ee536753f..76c7473d6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/io/PrefixedStorage.java +++ b/bundles/org.xmind.core/src/org/xmind/core/io/PrefixedStorage.java @@ -1,214 +1,214 @@ -package org.xmind.core.io; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class PrefixedStorage implements IStorage { - - private class PrefixedInputSource implements IInputSource, Closeable { - - private IInputSource source; - - public PrefixedInputSource(IInputSource source) { - this.source = source; - } - - public boolean hasEntry(String entryName) { - return source.hasEntry(prefix + entryName); - } - - public Iterator getEntries() { - return new Iterator() { - Iterator it = source.getEntries(); - String next = findNext(); - - private String findNext() { - while (it.hasNext()) { - String n = it.next(); - if (n != null && n.startsWith(prefix)) { - return n.substring(prefix.length()); - } - } - return null; - } - - public void remove() { - } - - public String next() { - String n = next; - next = findNext(); - return n; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - public boolean isEntryAvailable(String entryName) { - return source.isEntryAvailable(prefix + entryName); - } - - @Deprecated - public InputStream getEntryStream(String entryName) { - return source.getEntryStream(prefix + entryName); - } - - public InputStream openEntryStream(String entryName) - throws IOException { - return source.openEntryStream(prefix + entryName); - } - - public long getEntrySize(String entryName) { - return source.getEntrySize(prefix + entryName); - } - - public long getEntryTime(String entryName) { - return source.getEntryTime(prefix + entryName); - } - - public void close() throws IOException { - if (source instanceof Closeable) { - ((Closeable) source).close(); - } - } - - } - - private class PrefixedOutputTarget implements IOutputTarget, Closeable { - - private IOutputTarget target; - - public PrefixedOutputTarget(IOutputTarget target) { - this.target = target; - } - - public boolean isEntryAvaialble(String entryName) { - return target.isEntryAvaialble(prefix + entryName); - } - - @Deprecated - public OutputStream getEntryStream(String entryName) { - return target.getEntryStream(prefix + entryName); - } - - public OutputStream openEntryStream(String entryName) - throws IOException { - return target.openEntryStream(prefix + entryName); - } - - public void setEntryTime(String entryName, long time) { - target.setEntryTime(prefix + entryName, time); - } - - public void close() throws IOException { - if (target instanceof Closeable) { - ((Closeable) target).close(); - } - } - - } - - private IStorage storage; - - private String prefix; - - public PrefixedStorage(IStorage storage, String prefix) { - this.storage = storage; - this.prefix = prefix; - } - - public String getPrefix() { - return prefix; - } - - public IStorage getStorage() { - return storage; - } - - public IInputSource getInputSource() { - return new PrefixedInputSource(storage.getInputSource()); - } - - public IOutputTarget getOutputTarget() { - return new PrefixedOutputTarget(storage.getOutputTarget()); - } - - public String getName() { - return storage.getName(); - } - - public String getFullPath() { - return storage.getFullPath(); - } - - public void clear() { - Set entriesToDelete = new HashSet(); - Iterator it = storage.getInputSource().getEntries(); - while (it.hasNext()) { - String entry = it.next(); - while (entry.startsWith(prefix)) { - entriesToDelete.add(entry); - int slashIndex = entry.lastIndexOf('/'); - if (slashIndex <= 0) - break; - entry = entry.substring(0, slashIndex); - } - } - List entryList = new ArrayList(entriesToDelete); - Collections.sort(entryList, Collections.reverseOrder()); - for (String entry : entryList) { - storage.deleteEntry(entry); - } - storage.deleteEntry(prefix); - } - - public void deleteEntry(String entryName) { - storage.deleteEntry(prefix + entryName); - } - - public void renameEntry(String entryName, String newName) { - storage.renameEntry(prefix + entryName, prefix + newName); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return storage.hashCode() ^ prefix.hashCode(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof PrefixedStorage)) - return false; - PrefixedStorage that = (PrefixedStorage) obj; - return this.storage.equals(that.storage) - && this.prefix.equals(that.prefix); - } -} +package org.xmind.core.io; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class PrefixedStorage implements IStorage { + + private class PrefixedInputSource implements IInputSource, Closeable { + + private IInputSource source; + + public PrefixedInputSource(IInputSource source) { + this.source = source; + } + + public boolean hasEntry(String entryName) { + return source.hasEntry(prefix + entryName); + } + + public Iterator getEntries() { + return new Iterator() { + Iterator it = source.getEntries(); + String next = findNext(); + + private String findNext() { + while (it.hasNext()) { + String n = it.next(); + if (n != null && n.startsWith(prefix)) { + return n.substring(prefix.length()); + } + } + return null; + } + + public void remove() { + } + + public String next() { + String n = next; + next = findNext(); + return n; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + public boolean isEntryAvailable(String entryName) { + return source.isEntryAvailable(prefix + entryName); + } + + @Deprecated + public InputStream getEntryStream(String entryName) { + return source.getEntryStream(prefix + entryName); + } + + public InputStream openEntryStream(String entryName) + throws IOException { + return source.openEntryStream(prefix + entryName); + } + + public long getEntrySize(String entryName) { + return source.getEntrySize(prefix + entryName); + } + + public long getEntryTime(String entryName) { + return source.getEntryTime(prefix + entryName); + } + + public void close() throws IOException { + if (source instanceof Closeable) { + ((Closeable) source).close(); + } + } + + } + + private class PrefixedOutputTarget implements IOutputTarget, Closeable { + + private IOutputTarget target; + + public PrefixedOutputTarget(IOutputTarget target) { + this.target = target; + } + + public boolean isEntryAvaialble(String entryName) { + return target.isEntryAvaialble(prefix + entryName); + } + + @Deprecated + public OutputStream getEntryStream(String entryName) { + return target.getEntryStream(prefix + entryName); + } + + public OutputStream openEntryStream(String entryName) + throws IOException { + return target.openEntryStream(prefix + entryName); + } + + public void setEntryTime(String entryName, long time) { + target.setEntryTime(prefix + entryName, time); + } + + public void close() throws IOException { + if (target instanceof Closeable) { + ((Closeable) target).close(); + } + } + + } + + private IStorage storage; + + private String prefix; + + public PrefixedStorage(IStorage storage, String prefix) { + this.storage = storage; + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + + public IStorage getStorage() { + return storage; + } + + public IInputSource getInputSource() { + return new PrefixedInputSource(storage.getInputSource()); + } + + public IOutputTarget getOutputTarget() { + return new PrefixedOutputTarget(storage.getOutputTarget()); + } + + public String getName() { + return storage.getName(); + } + + public String getFullPath() { + return storage.getFullPath(); + } + + public void clear() { + Set entriesToDelete = new HashSet(); + Iterator it = storage.getInputSource().getEntries(); + while (it.hasNext()) { + String entry = it.next(); + while (entry.startsWith(prefix)) { + entriesToDelete.add(entry); + int slashIndex = entry.lastIndexOf('/'); + if (slashIndex <= 0) + break; + entry = entry.substring(0, slashIndex); + } + } + List entryList = new ArrayList(entriesToDelete); + Collections.sort(entryList, Collections.reverseOrder()); + for (String entry : entryList) { + storage.deleteEntry(entry); + } + storage.deleteEntry(prefix); + } + + public void deleteEntry(String entryName) { + storage.deleteEntry(prefix + entryName); + } + + public void renameEntry(String entryName, String newName) { + storage.renameEntry(prefix + entryName, prefix + newName); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return storage.hashCode() ^ prefix.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof PrefixedStorage)) + return false; + PrefixedStorage that = (PrefixedStorage) obj; + return this.storage.equals(that.storage) + && this.prefix.equals(that.prefix); + } +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/AbstractMarkerResource.java b/bundles/org.xmind.core/src/org/xmind/core/marker/AbstractMarkerResource.java index fe043c530..8352e5b09 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/AbstractMarkerResource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/AbstractMarkerResource.java @@ -1,141 +1,141 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.marker; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -public abstract class AbstractMarkerResource implements IMarkerResource { - - private String mainPath; - - private IMarker marker; - - private List variations = null; - - public AbstractMarkerResource(IMarker marker) { - this(marker, null); - } - - public AbstractMarkerResource(IMarker marker, String mainPath) { - if (marker == null) - throw new IllegalArgumentException(); - this.marker = marker; - this.mainPath = mainPath == null ? "" : mainPath; //$NON-NLS-1$ - } - - protected IMarker getMarker() { - return marker; - } - - public String getPath() { - return marker.getResourcePath(); - } - - public String getFullPath() { - String path = getPath(); - if (!path.startsWith("/")) { //$NON-NLS-1$ - path = getMainPath() + path; - } - return path; - } - - protected String getMainPath() { - return mainPath; - } - - public synchronized List getVariations() { - if (variations == null) { - variations = new ArrayList(); - loadVariations(variations); - } - return variations; - } - - protected void loadVariations(List variations) { - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerResource#getInputStream() - */ - public InputStream getInputStream() { - try { - return openInputStream(); - } catch (IOException e) { - return null; - } - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerResource#getOutputStream() - */ - @Deprecated - public OutputStream getOutputStream() { - try { - return openOutputStream(); - } catch (IOException e) { - return null; - } - } - - /** - * @deprecated - */ - @Deprecated - public InputStream getInputStream(IMarkerVariation variation) { - return getInputStream(); - } - - /** - * @deprecated - */ - @Deprecated - public OutputStream getOutputStream(IMarkerVariation variation) { - return getOutputStream(); - } - - public InputStream openInputStream(IMarkerVariation variation) - throws IOException { - return openInputStream(); - } - - public InputStream openInputStream(int zoom) throws IOException { - return openInputStream(); - } - - public InputStream openInputStream(IMarkerVariation variation, int zoom) - throws IOException { - return openInputStream(); - } - - @Deprecated - public OutputStream openOutputStream(IMarkerVariation variation) - throws IOException { - return openOutputStream(); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof AbstractMarkerResource)) - return false; - AbstractMarkerResource that = (AbstractMarkerResource) obj; - return this.marker.equals(that.marker); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.marker; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +public abstract class AbstractMarkerResource implements IMarkerResource { + + private String mainPath; + + private IMarker marker; + + private List variations = null; + + public AbstractMarkerResource(IMarker marker) { + this(marker, null); + } + + public AbstractMarkerResource(IMarker marker, String mainPath) { + if (marker == null) + throw new IllegalArgumentException(); + this.marker = marker; + this.mainPath = mainPath == null ? "" : mainPath; //$NON-NLS-1$ + } + + protected IMarker getMarker() { + return marker; + } + + public String getPath() { + return marker.getResourcePath(); + } + + public String getFullPath() { + String path = getPath(); + if (!path.startsWith("/")) { //$NON-NLS-1$ + path = getMainPath() + path; + } + return path; + } + + protected String getMainPath() { + return mainPath; + } + + public synchronized List getVariations() { + if (variations == null) { + variations = new ArrayList(); + loadVariations(variations); + } + return variations; + } + + protected void loadVariations(List variations) { + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerResource#getInputStream() + */ + public InputStream getInputStream() { + try { + return openInputStream(); + } catch (IOException e) { + return null; + } + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerResource#getOutputStream() + */ + @Deprecated + public OutputStream getOutputStream() { + try { + return openOutputStream(); + } catch (IOException e) { + return null; + } + } + + /** + * @deprecated + */ + @Deprecated + public InputStream getInputStream(IMarkerVariation variation) { + return getInputStream(); + } + + /** + * @deprecated + */ + @Deprecated + public OutputStream getOutputStream(IMarkerVariation variation) { + return getOutputStream(); + } + + public InputStream openInputStream(IMarkerVariation variation) + throws IOException { + return openInputStream(); + } + + public InputStream openInputStream(int zoom) throws IOException { + return openInputStream(); + } + + public InputStream openInputStream(IMarkerVariation variation, int zoom) + throws IOException { + return openInputStream(); + } + + @Deprecated + public OutputStream openOutputStream(IMarkerVariation variation) + throws IOException { + return openOutputStream(); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof AbstractMarkerResource)) + return false; + AbstractMarkerResource that = (AbstractMarkerResource) obj; + return this.marker.equals(that.marker); + } +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceAllocator.java b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceAllocator.java index 3af690799..bc25d8dd6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceAllocator.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceAllocator.java @@ -1,40 +1,40 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.marker; - -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IMarkerResourceAllocator { - - /** - * Allocates a new marker resource path storing the given data. - * - * @param source - * @param suggestedPath - * @return - * @throws IOException - * @throws UnsupportedOperationException - */ - String allocateMarkerResource(InputStream source, String suggestedPath) - throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.marker; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IMarkerResourceAllocator { + + /** + * Allocates a new marker resource path storing the given data. + * + * @param source + * @param suggestedPath + * @return + * @throws IOException + * @throws UnsupportedOperationException + */ + String allocateMarkerResource(InputStream source, String suggestedPath) + throws IOException; + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceProvider.java b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceProvider.java index 28f60dee7..ec856e763 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceProvider.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResourceProvider.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.marker; - -public interface IMarkerResourceProvider { - - IMarkerResource getMarkerResource(IMarker marker); - - boolean isPermanent(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.marker; + +public interface IMarkerResourceProvider { + + IMarkerResource getMarkerResource(IMarker marker); + + boolean isPermanent(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerSheet.java b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerSheet.java index b8f420489..ef942517c 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerSheet.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerSheet.java @@ -1,190 +1,190 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.marker; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.io.IInputSource; - -public interface IMarkerSheet extends IAdaptable { - - List getMarkerGroups(); - - IMarkerGroup createMarkerGroup(boolean singleton); - - IMarker createMarker(String resourcePath); - - IMarkerGroup createMarkerGroupById(String groupId); - - IMarker createMarkerById(String markerId, String resourcePath); - - void addMarkerGroup(IMarkerGroup group); - - void removeMarkerGroup(IMarkerGroup group); - - void setParentSheet(IMarkerSheet parent); - - IMarkerSheet getParentSheet(); - - /** - * Gets the marker group with the given group ID within this marker sheet. - * - * @param groupId - * the group ID - * @return the marker group with the given group ID, or null if - * no such marker group is found in this marker sheet - */ - IMarkerGroup getMarkerGroup(String groupId); - - /** - * Gets the marker with the given marker ID within this marker sheet. - * - * @param markerId - * the marker ID - * @return the marker with the given marker ID, or null if no - * such marker is found in this marker sheet - */ - IMarker getMarker(String markerId); - - /** - * Finds the marker group with the given group ID in this marker sheet and - * all its parents. - * - * @param groupId - * the group ID - * @return the marker group with the given group ID, or null if - * no such marker group is found in this marker sheet and all its - * parents. - */ - IMarkerGroup findMarkerGroup(String groupId); - - /** - * Finds the marker with the given marker ID in this marker sheet and all - * its parents. - * - * @param markerId - * the marker ID - * @return the marker with the given marker ID, or null if no - * such marker is found in this marker sheet and all its parents. - */ - IMarker findMarker(String markerId); - - /** - * Returns whether this marker sheet contains at least one marker group. - * - * @return true if no marker groups exist, or - * false otherwise - */ - boolean isEmpty(); - - /** - * Returns whether this marker sheet's content is permanent that will not - * change over time. A permanent sheet's markers can always be referenced - * and need not to be copied to another marker sheet. - * - * @return true if this marker sheet is permanent, or - * false otherwise - */ - boolean isPermanent(); - - /** - *

- * WARNING: This method is for internal use only! Clients should use - * serialization methods to save a marker sheet. - *

- * - * @param out - * @throws IOException - * @throws CoreException - */ - @Deprecated - void save(OutputStream out) throws IOException, CoreException; - - /** - *

- * WARNING: This method is for internal use only! Don't call it! - *

- * - * @param source - * @throws IOException - * @throws CoreException - */ - @Deprecated - void importFrom(IInputSource source) throws IOException, CoreException; - - /** - *

- * WARNING: This method is for internal use only! Don't call it! - *

- * - * @param source - * @param groupName - * @throws IOException - * @throws CoreException - */ - @Deprecated - void importFrom(IInputSource source, String groupName) - throws IOException, CoreException; - - /** - *

- * WARNING: This method is for internal use only! Don't call it! - *

- * - * @param sourcePath - * @throws IOException - * @throws CoreException - */ - @Deprecated - void importFrom(String sourcePath) throws IOException, CoreException; - - /** - *

- * WARNING: This method is for internal use only! Don't call it! - *

- * - * @param sheet - */ - @Deprecated - void importFrom(IMarkerSheet sheet); - - /** - *

- * WARNING: This method is for internal use only! Don't call it! - *

- * - * @param group - * @return - */ - @Deprecated - IMarkerGroup importGroup(IMarkerGroup group); - - /** - * Allocates a new marker resource path storing the given data. - * - * @param source - * @param suggestedPath - * @return - * @throws IOException - * @throws UnsupportedOperationException - */ - String allocateMarkerResource(InputStream source, String suggestedPath) - throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.marker; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.io.IInputSource; + +public interface IMarkerSheet extends IAdaptable { + + List getMarkerGroups(); + + IMarkerGroup createMarkerGroup(boolean singleton); + + IMarker createMarker(String resourcePath); + + IMarkerGroup createMarkerGroupById(String groupId); + + IMarker createMarkerById(String markerId, String resourcePath); + + void addMarkerGroup(IMarkerGroup group); + + void removeMarkerGroup(IMarkerGroup group); + + void setParentSheet(IMarkerSheet parent); + + IMarkerSheet getParentSheet(); + + /** + * Gets the marker group with the given group ID within this marker sheet. + * + * @param groupId + * the group ID + * @return the marker group with the given group ID, or null if + * no such marker group is found in this marker sheet + */ + IMarkerGroup getMarkerGroup(String groupId); + + /** + * Gets the marker with the given marker ID within this marker sheet. + * + * @param markerId + * the marker ID + * @return the marker with the given marker ID, or null if no + * such marker is found in this marker sheet + */ + IMarker getMarker(String markerId); + + /** + * Finds the marker group with the given group ID in this marker sheet and + * all its parents. + * + * @param groupId + * the group ID + * @return the marker group with the given group ID, or null if + * no such marker group is found in this marker sheet and all its + * parents. + */ + IMarkerGroup findMarkerGroup(String groupId); + + /** + * Finds the marker with the given marker ID in this marker sheet and all + * its parents. + * + * @param markerId + * the marker ID + * @return the marker with the given marker ID, or null if no + * such marker is found in this marker sheet and all its parents. + */ + IMarker findMarker(String markerId); + + /** + * Returns whether this marker sheet contains at least one marker group. + * + * @return true if no marker groups exist, or + * false otherwise + */ + boolean isEmpty(); + + /** + * Returns whether this marker sheet's content is permanent that will not + * change over time. A permanent sheet's markers can always be referenced + * and need not to be copied to another marker sheet. + * + * @return true if this marker sheet is permanent, or + * false otherwise + */ + boolean isPermanent(); + + /** + *

+ * WARNING: This method is for internal use only! Clients should use + * serialization methods to save a marker sheet. + *

+ * + * @param out + * @throws IOException + * @throws CoreException + */ + @Deprecated + void save(OutputStream out) throws IOException, CoreException; + + /** + *

+ * WARNING: This method is for internal use only! Don't call it! + *

+ * + * @param source + * @throws IOException + * @throws CoreException + */ + @Deprecated + void importFrom(IInputSource source) throws IOException, CoreException; + + /** + *

+ * WARNING: This method is for internal use only! Don't call it! + *

+ * + * @param source + * @param groupName + * @throws IOException + * @throws CoreException + */ + @Deprecated + void importFrom(IInputSource source, String groupName) + throws IOException, CoreException; + + /** + *

+ * WARNING: This method is for internal use only! Don't call it! + *

+ * + * @param sourcePath + * @throws IOException + * @throws CoreException + */ + @Deprecated + void importFrom(String sourcePath) throws IOException, CoreException; + + /** + *

+ * WARNING: This method is for internal use only! Don't call it! + *

+ * + * @param sheet + */ + @Deprecated + void importFrom(IMarkerSheet sheet); + + /** + *

+ * WARNING: This method is for internal use only! Don't call it! + *

+ * + * @param group + * @return + */ + @Deprecated + IMarkerGroup importGroup(IMarkerGroup group); + + /** + * Allocates a new marker resource path storing the given data. + * + * @param source + * @param suggestedPath + * @return + * @throws IOException + * @throws UnsupportedOperationException + */ + String allocateMarkerResource(InputStream source, String suggestedPath) + throws IOException; + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerVariation.java b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerVariation.java index d8bfc8560..d5488f612 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerVariation.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerVariation.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.marker; - -public interface IMarkerVariation { - - String getVariedPath(String path); - - boolean isApplicable(int widthHint, int heightHint); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.marker; + +public interface IMarkerVariation { + + String getVariedPath(String path); + + boolean isApplicable(int widthHint, int heightHint); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/style/IStyle.java b/bundles/org.xmind.core/src/org/xmind/core/style/IStyle.java index ffe55c13a..f0e4be536 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/style/IStyle.java +++ b/bundles/org.xmind.core/src/org/xmind/core/style/IStyle.java @@ -1,127 +1,127 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.style; - -import java.util.Iterator; - -import org.xmind.core.IAdaptable; -import org.xmind.core.IIdentifiable; -import org.xmind.core.INamed; -import org.xmind.core.IProperties; -import org.xmind.core.ITopic; -import org.xmind.core.util.Property; - -public interface IStyle extends IAdaptable, IIdentifiable, IProperties, INamed { - - /** - * Style type for theme properties. - */ - String THEME = "theme"; //$NON-NLS-1$ - - /** - * Style type for paragraph properties. - */ - String PARAGRAPH = "paragraph"; //$NON-NLS-1$ - /** - * Style type for bullet paragraph properties. - */ -// String BULLETPARAGRAPH = "bulletParagraph"; - /** - * Style type for text properties. - */ - String TEXT = "text"; //$NON-NLS-1$ - - /** - * Style type for summary properties. - */ - String SUMMARY = "summary"; //$NON-NLS-1$ - - /** - * Style type for boundary properties. - */ - String BOUNDARY = "boundary"; //$NON-NLS-1$ - - /** - * Style type for relationship properties. - */ - String RELATIONSHIP = "relationship"; //$NON-NLS-1$ - - /** - * Style type for topic properties. - */ - String TOPIC = "topic"; //$NON-NLS-1$ - - /** - * Style type for map properties. - */ - String MAP = "map"; //$NON-NLS-1$ - - /** - * Gets the style sheet who owns this style. - *

- * A style can not be added to a style sheet that does not own it. - * - * @return the owned style sheet - */ - IStyleSheet getOwnedStyleSheet(); - - /** - * Gets the string identifitying the type of this style. A style with a - * specific type can only be applied to a specific type of object, i.e. a - * style with {@link #TOPIC} type can only be applied to {@link ITopic} - * objects. Trying to apply a style to a object of different type may result - * in no effects. - * - * @see #TOPIC - * @see #MAP - * @see #BOUNDARY - * @see #RELATIONSHIP - * @see #SUMMARY - * @see #PARAGRAPH - * @see #TEXT - * @see #THEME - * @return the type of this style - */ - String getType(); - - /** - * @return - */ - Iterator defaultStyles(); - - /** - * @param styleFamily - * @return - */ - String getDefaultStyleId(String styleFamily); - - /** - * @param styleFamily - * @return - */ - IStyle getDefaultStyle(String styleFamily); - - /** - * @param styleId - * @return - */ - IStyle getDefaultStyleById(String styleId); - - /** - * @param styleFamily - * @param styleId - */ - void setDefaultStyleId(String styleFamily, String styleId); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.style; + +import java.util.Iterator; + +import org.xmind.core.IAdaptable; +import org.xmind.core.IIdentifiable; +import org.xmind.core.INamed; +import org.xmind.core.IProperties; +import org.xmind.core.ITopic; +import org.xmind.core.util.Property; + +public interface IStyle extends IAdaptable, IIdentifiable, IProperties, INamed { + + /** + * Style type for theme properties. + */ + String THEME = "theme"; //$NON-NLS-1$ + + /** + * Style type for paragraph properties. + */ + String PARAGRAPH = "paragraph"; //$NON-NLS-1$ + /** + * Style type for bullet paragraph properties. + */ +// String BULLETPARAGRAPH = "bulletParagraph"; + /** + * Style type for text properties. + */ + String TEXT = "text"; //$NON-NLS-1$ + + /** + * Style type for summary properties. + */ + String SUMMARY = "summary"; //$NON-NLS-1$ + + /** + * Style type for boundary properties. + */ + String BOUNDARY = "boundary"; //$NON-NLS-1$ + + /** + * Style type for relationship properties. + */ + String RELATIONSHIP = "relationship"; //$NON-NLS-1$ + + /** + * Style type for topic properties. + */ + String TOPIC = "topic"; //$NON-NLS-1$ + + /** + * Style type for map properties. + */ + String MAP = "map"; //$NON-NLS-1$ + + /** + * Gets the style sheet who owns this style. + *

+ * A style can not be added to a style sheet that does not own it. + * + * @return the owned style sheet + */ + IStyleSheet getOwnedStyleSheet(); + + /** + * Gets the string identifitying the type of this style. A style with a + * specific type can only be applied to a specific type of object, i.e. a + * style with {@link #TOPIC} type can only be applied to {@link ITopic} + * objects. Trying to apply a style to a object of different type may result + * in no effects. + * + * @see #TOPIC + * @see #MAP + * @see #BOUNDARY + * @see #RELATIONSHIP + * @see #SUMMARY + * @see #PARAGRAPH + * @see #TEXT + * @see #THEME + * @return the type of this style + */ + String getType(); + + /** + * @return + */ + Iterator defaultStyles(); + + /** + * @param styleFamily + * @return + */ + String getDefaultStyleId(String styleFamily); + + /** + * @param styleFamily + * @return + */ + IStyle getDefaultStyle(String styleFamily); + + /** + * @param styleId + * @return + */ + IStyle getDefaultStyleById(String styleId); + + /** + * @param styleFamily + * @param styleId + */ + void setDefaultStyleId(String styleFamily, String styleId); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/style/IStyleRef.java b/bundles/org.xmind.core/src/org/xmind/core/style/IStyleRef.java index ea637c11a..3652a6ca6 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/style/IStyleRef.java +++ b/bundles/org.xmind.core/src/org/xmind/core/style/IStyleRef.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.style; - -public interface IStyleRef extends IStyled { - - IStyle getStyle(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.style; + +public interface IStyleRef extends IStyled { + + IStyle getStyle(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/CloneHandler.java b/bundles/org.xmind.core/src/org/xmind/core/util/CloneHandler.java index 61ba56b71..87ac1103b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/CloneHandler.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/CloneHandler.java @@ -1,1007 +1,1018 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.util; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_PATH; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.xmind.core.CoreException; -import org.xmind.core.IBoundary; -import org.xmind.core.ICloneData; -import org.xmind.core.IComment; -import org.xmind.core.ICommentManager; -import org.xmind.core.IControlPoint; -import org.xmind.core.IFileEntry; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IHyperlinkSpan; -import org.xmind.core.IImage; -import org.xmind.core.IImageSpan; -import org.xmind.core.IManifest; -import org.xmind.core.IMeta; -import org.xmind.core.INotes; -import org.xmind.core.INotesContent; -import org.xmind.core.IParagraph; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.IResourceRef; -import org.xmind.core.ISettingEntry; -import org.xmind.core.ISheet; -import org.xmind.core.ISpan; -import org.xmind.core.ISpanList; -import org.xmind.core.ISummary; -import org.xmind.core.ITextSpan; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookExtension; -import org.xmind.core.IWorkbookExtensionElement; -import org.xmind.core.IWorkbookExtensionManager; -import org.xmind.core.internal.CloneData; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.marker.IMarkerResource; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class CloneHandler { - - private ICloneData mapper; - - private IWorkbook sourceWorkbook; - private IWorkbook targetWorkbook; - - private IManifest sourceManifest; - private IManifest targetManifest; - - private IStyleSheet sourceStyleSheet; - private IStyleSheet targetStyleSheet; - - private IMarkerSheet sourceMarkerSheet; - private IMarkerSheet targetMarkerSheet; - - /** - * - */ - public CloneHandler() { - this(null); - } - - /** - * - */ - public CloneHandler(ICloneData mapper) { - this.mapper = mapper == null - ? new CloneData(Collections.emptyList(), null) : mapper; - this.sourceWorkbook = null; - this.targetWorkbook = null; - this.sourceManifest = null; - this.targetManifest = null; - this.sourceStyleSheet = null; - this.targetStyleSheet = null; - this.sourceMarkerSheet = null; - this.targetMarkerSheet = null; - } - - public CloneHandler withWorkbooks(IWorkbook sourceWorkbook, - IWorkbook targetWorkbook) { - if (sourceWorkbook == null) - throw new IllegalArgumentException(); - if (targetWorkbook == null) - throw new IllegalArgumentException(); - - this.sourceWorkbook = sourceWorkbook; - this.targetWorkbook = targetWorkbook; - this.sourceManifest = sourceWorkbook.getManifest(); - this.targetManifest = targetWorkbook.getManifest(); - this.sourceStyleSheet = sourceWorkbook.getStyleSheet(); - this.targetStyleSheet = targetWorkbook.getStyleSheet(); - this.sourceMarkerSheet = sourceWorkbook.getMarkerSheet(); - this.targetMarkerSheet = targetWorkbook.getMarkerSheet(); - - return this; - } - - public CloneHandler withManifests(IManifest sourceManifest, - IManifest targetManifest) { - if (sourceManifest == null) - throw new IllegalArgumentException(); - if (targetManifest == null) - throw new IllegalArgumentException(); - - this.sourceManifest = sourceManifest; - this.targetManifest = targetManifest; - return this; - } - - public CloneHandler withStyleSheets(IStyleSheet sourceStyleSheet, - IStyleSheet targetStyleSheet) { - if (sourceStyleSheet == null) - throw new IllegalArgumentException(); - if (targetStyleSheet == null) - throw new IllegalArgumentException(); - - this.sourceStyleSheet = sourceStyleSheet; - this.targetStyleSheet = targetStyleSheet; - this.sourceManifest = sourceStyleSheet.getAdapter(IManifest.class); - this.targetManifest = targetStyleSheet.getAdapter(IManifest.class); - return this; - } - - public CloneHandler withMarkerSheets(IMarkerSheet sourceMarkerSheet, - IMarkerSheet targetMarkerSheet) { - if (sourceMarkerSheet == null) - throw new IllegalArgumentException(); - if (targetMarkerSheet == null) - throw new IllegalArgumentException(); - - this.sourceMarkerSheet = sourceMarkerSheet; - this.targetMarkerSheet = targetMarkerSheet; - this.sourceManifest = sourceMarkerSheet.getAdapter(IManifest.class); - this.targetManifest = targetMarkerSheet.getAdapter(IManifest.class); - return this; - } - - /** - * @return the mapper - */ - public ICloneData getMapper() { - return mapper; - } - - public void copyWorkbookContents() throws IOException { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - - List oldSheets = new ArrayList( - targetWorkbook.getSheets()); - for (ISheet sourceSheet : sourceWorkbook.getSheets()) { - targetWorkbook.addSheet(cloneSheet(sourceSheet)); - } - if (targetWorkbook.getSheets().isEmpty()) { - targetWorkbook.addSheet(targetWorkbook.createSheet()); - } - for (ISheet oldSheet : oldSheets) { - targetWorkbook.removeSheet(oldSheet); - } - - IMeta sourceMeta = sourceWorkbook.getMeta(); - IMeta targetMeta = targetWorkbook.getMeta(); - for (String keyPath : sourceMeta.getKeyPaths()) { - targetMeta.setValue(keyPath, sourceMeta.getValue(keyPath)); - } - - List sheets = targetWorkbook.getSheets(); - ArrayList targetAllTopics = new ArrayList(); - for (ISheet sheet : sheets) { - targetAllTopics.add(sheet.getRootTopic()); - targetAllTopics.addAll(sheet.getRootTopic().getAllChildren()); - } - - IWorkbookExtensionManager sourceExtensionManager = sourceWorkbook - .getAdapter(IWorkbookExtensionManager.class); - IWorkbookExtensionManager targetExtensionManager = targetWorkbook - .getAdapter(IWorkbookExtensionManager.class); - if (sourceExtensionManager != null && targetExtensionManager != null) { - for (IWorkbookExtension sourceExtension : sourceExtensionManager - .getExtensions()) { - IWorkbookExtension targetExtension = targetExtensionManager - .createExtension(sourceExtension.getProviderName()); - copyWorkbookExtension(sourceExtension, targetExtension); - } - } - - fixInternalHyperlinkFor(targetAllTopics); - } - - /** - * Clones a source object into the target container (e.g. workbook or style - * sheet, etc.). Currently only these kinds of objects can be cloned: - *

    - *
  • {@link org.xmind.core.ISheet} (require sourceWorkbook/targetWorkbook) - *
  • - *
  • {@link org.xmind.core.ITopic} (require sourceWorkbook/targetWorkobok) - *
  • - *
  • {@link org.xmind.core.IBoundary} (require - * sourceWorkbook/targetWorkbook)
  • - *
  • {@link org.xmind.core.ISummary} (require - * sourceWorkbook/targetWorkbook)
  • - *
  • {@link org.xmind.core.IRelationship} (require - * sourceWorkbook/targetWorkbook)
  • - *
  • {@link org.xmind.core.IImage} (require sourceWorkbook/targetWorkbook) - *
  • - *
  • {@link org.xmind.core.style.IStyle} (require - * sourceStyleSheet/targetStyleSheet)
  • - *
- * - * @param source - * the source object to clone - * @return a cloned object, or null if the object is - * unrecognized - * @throws IOException - * if any I/O error occurred during the clone process (e.g. when - * importing attachments along with its referrence topic) - * @throws AssertionError - * if required target contexts are missing - */ - public Object cloneObject(Object source) throws IOException { - Object target = mapper.get(source); - if (target != null) - return target; - - if (source instanceof ISheet) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - return cloneSheet((ISheet) source); - } else if (source instanceof ITopic) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - ITopic sourceTopic = (ITopic) source; - ITopic targetTopic = targetWorkbook.createTopic(); - copyTopicContents(sourceTopic, targetTopic); - return targetTopic; - } else if (source instanceof IBoundary) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - IBoundary sourceBoundary = (IBoundary) source; - IBoundary targetBoundary = targetWorkbook.createBoundary(); - copyBoundaryContents(sourceBoundary, targetBoundary); - return targetBoundary; - } else if (source instanceof ISummary) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - ISummary sourceSummary = (ISummary) source; - ISummary targetSummary = targetWorkbook.createSummary(); - copySummaryContents(sourceSummary, targetSummary); - return targetSummary; - } else if (source instanceof IRelationship) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - IRelationship sourceRel = (IRelationship) source; - IRelationship targetRel = targetWorkbook.createRelationship(); - copyRelationshipContents(sourceRel, targetRel); - return targetRel; - } else if (source instanceof IStyle) { - if (sourceStyleSheet == null) - throw new AssertionError("sourceStyleSheet is null"); //$NON-NLS-1$ - if (targetStyleSheet == null) - throw new AssertionError("targetStyleSheet is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - return findOrCloneStyle((IStyle) source); - } else if (source instanceof IImage) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - if (sourceManifest == null) - throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ - if (targetManifest == null) - throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ - IImage sourceImage = (IImage) source; - ITopic sourceTopic = sourceImage.getParent(); - ITopic targetTopic = targetWorkbook.createTopic(); - copyTopicContents(sourceTopic, targetTopic); - IImage targetImage = targetTopic.getImage(); - mapper.put(sourceImage, targetImage); - return targetImage; - } else if (source instanceof IMarker) { - if (sourceMarkerSheet == null) - throw new AssertionError("sourceMarkerSheet is null"); //$NON-NLS-1$ - if (targetMarkerSheet == null) - throw new AssertionError("targetMarkerSheet is null"); //$NON-NLS-1$ - /// marker sheets require not manifests, but resource providers, - /// so sourceManifest and targetManifest are not checked here - IMarker marker = findOrCloneMarker((IMarker) source); - mapper.put(source, marker); - return marker; - } else if (source instanceof IMarkerRef) { - if (sourceWorkbook == null) - throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ - if (targetWorkbook == null) - throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ - IMarkerRef sourceMarkerRef = (IMarkerRef) source; - IMarkerRef targetMarkerRef = cloneMarkerRef(sourceMarkerRef); - mapper.put(sourceMarkerRef, targetMarkerRef); - return targetMarkerRef; - } - - return null; - } - - /** - * @param sourceMarkerRef - * @return - * @throws IOException - */ - private IMarkerRef cloneMarkerRef(IMarkerRef sourceMarkerRef) - throws IOException { - IMarkerRef targetMarkerRef; - IMarker sourceMarker = sourceMarkerRef.getMarker(); - if (sourceMarker == null) { - targetMarkerRef = sourceMarkerRef; - } else { - IMarker targetMarker = findOrCloneMarker(sourceMarker); - if (targetMarker == null) { - targetMarkerRef = null; - } else { - mapper.put(sourceMarker, targetMarker); - mapper.putString(ICloneData.MARKERSHEET_COMPONENTS, - sourceMarker.getId(), targetMarker.getId()); - ITopic tempTopic = targetWorkbook.createTopic(); - tempTopic.addMarker(targetMarker.getId()); - targetMarkerRef = tempTopic.getMarkerRefs().iterator().next(); - } - } - return targetMarkerRef; - } - - private IMarker findOrCloneMarker(IMarker sourceMarker) throws IOException { - if (sourceMarker == null) - return null; - - IMarker targetMarker = (IMarker) mapper.get(sourceMarker); - if (targetMarker != null) - return targetMarker; - - String markerId = sourceMarker.getId(); - targetMarker = targetMarkerSheet.findMarker(markerId); - if (targetMarker != null) { - mapper.put(sourceMarker, targetMarker); - return targetMarker; - } - - /// markers do not change across permanent marker sheets - if (sourceMarker.getOwnedSheet().isPermanent()) - return sourceMarker; - - IMarkerGroup sourceGroup = sourceMarker.getParent(); - IMarkerGroup targetGroup = findOrCloneMarkerGroup(sourceGroup); - - String sourceResourcePath = sourceMarker.getResourcePath(); - String targetResourcePath = null; - - /// copy marker resource content - IMarkerResource sourceResource = sourceMarker.getResource(); - if (sourceResource != null) { - InputStream input = sourceResource.openInputStream(); - try { - targetResourcePath = targetMarkerSheet - .allocateMarkerResource(input, sourceResourcePath); - } finally { - input.close(); - } - } - - /// create target marker with the same marker id - targetMarker = targetMarkerSheet.createMarkerById(markerId, - targetResourcePath); - - targetMarker.setName(sourceMarker.getName()); - - if (targetGroup != null) - targetGroup.addMarker(targetMarker); - - mapper.put(sourceMarker, targetMarker); - - return targetMarker; - } - - private IMarkerGroup findOrCloneMarkerGroup( - IMarkerGroup sourceMarkerGroup) { - if (sourceMarkerGroup == null) - return null; - - IMarkerGroup targetMarkerGroup = (IMarkerGroup) mapper - .get(sourceMarkerGroup); - if (targetMarkerGroup != null) - return targetMarkerGroup; - - String groupId = sourceMarkerGroup.getId(); - targetMarkerGroup = targetMarkerSheet.findMarkerGroup(groupId); - if (targetMarkerGroup == null - || targetMarkerGroup.getOwnedSheet() != targetMarkerSheet) { - /// make sure the new group is owned by the target marker sheet - targetMarkerGroup = targetMarkerSheet - .createMarkerGroupById(groupId); - targetMarkerGroup.setSingleton(sourceMarkerGroup.isSingleton()); - targetMarkerGroup.setName(sourceMarkerGroup.getName()); - } - if (targetMarkerGroup.getParent() == null) { - targetMarkerSheet.addMarkerGroup(targetMarkerGroup); - } - return targetMarkerGroup; - } - - private ISheet cloneSheet(ISheet sourceSheet) throws IOException { - ISheet targetSheet = targetWorkbook.createSheet(); - copySheetContents(sourceSheet, targetSheet); - - ArrayList targetAllTopics = new ArrayList(); - targetAllTopics.add(targetSheet.getRootTopic()); - targetAllTopics.addAll(targetSheet.getRootTopic().getAllChildren()); - - fixInternalHyperlinkFor(targetAllTopics); - return targetSheet; - } - - /** - * @param sourceSheet - * @param targetSheet - * @throws IOException - * @throws CoreException - */ - private void copySheetContents(ISheet sourceSheet, ISheet targetSheet) - throws IOException { - mapper.put(sourceSheet, targetSheet); - mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceSheet.getId(), - targetSheet.getId()); - - targetSheet.setTitleText(sourceSheet.getTitleText()); - targetSheet.setStyleId(convertStyleId(sourceSheet.getStyleId())); - targetSheet.setThemeId(convertStyleId(sourceSheet.getThemeId())); - - ITopic sourceRootTopic = sourceSheet.getRootTopic(); - if (sourceRootTopic != null) { - ITopic targetRootTopic = targetSheet.getRootTopic(); - copyTopicContents(sourceRootTopic, targetRootTopic); - } - - for (IRelationship sourceRel : sourceSheet.getRelationships()) { - IRelationship targetRel = targetWorkbook.createRelationship(); - copyRelationshipContents(sourceRel, targetRel); - targetSheet.addRelationship(targetRel); - } - - targetSheet.getLegend().setVisible(sourceSheet.getLegend().isVisible()); - targetSheet.getLegend() - .setPosition(sourceSheet.getLegend().getPosition()); - for (String markerId : sourceSheet.getLegend().getMarkerIds()) { - targetSheet.getLegend().setMarkerDescription(markerId, - sourceSheet.getLegend().getMarkerDescription(markerId)); - } - - for (String settingPath : sourceSheet.getSettings().getPaths()) { - for (ISettingEntry sourceSettingEntry : sourceSheet.getSettings() - .getEntries(settingPath)) { - ISettingEntry targetSettingEntry = targetSheet.getSettings() - .createEntry(settingPath); - for (String key : sourceSettingEntry.getAttributeKeys()) { - targetSettingEntry.setAttribute(key, - sourceSettingEntry.getAttribute(key)); - } - targetSheet.getSettings().addEntry(targetSettingEntry); - } - } - - copyComments(sourceSheet.getId(), targetSheet.getId()); - } - - private void copyTopicContents(ITopic sourceTopic, ITopic targetTopic) - throws IOException { - mapper.put(sourceTopic, targetTopic); - mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceTopic.getId(), - targetTopic.getId()); - targetTopic.setTitleText( - sourceTopic.hasTitle() ? sourceTopic.getTitleText() : null); - targetTopic.setTitleWidth(sourceTopic.getTitleWidth()); - targetTopic.setFolded(sourceTopic.isFolded()); - targetTopic.setStructureClass(sourceTopic.getStructureClass()); - targetTopic.setPosition(sourceTopic.getPosition()); - - targetTopic.setHyperlink(convertHyperlink(sourceTopic.getHyperlink())); - - for (String label : sourceTopic.getLabels()) { - targetTopic.addLabel(label); - } - - for (IMarkerRef markerRef : sourceTopic.getMarkerRefs()) { - IMarkerRef mr = (IMarkerRef) cloneObject(markerRef); - if (mr != null) { - targetTopic.addMarker(mr.getMarkerId()); - } - } - - targetTopic.setStyleId(convertStyleId(sourceTopic.getStyleId())); - - targetTopic.getImage().setSource( - convertHyperlink(sourceTopic.getImage().getSource())); - targetTopic.getImage().setWidth(sourceTopic.getImage().getWidth()); - targetTopic.getImage().setHeight(sourceTopic.getImage().getHeight()); - targetTopic.getImage() - .setAlignment(sourceTopic.getImage().getAlignment()); - - for (String type : sourceTopic.getChildrenTypes()) { - for (ITopic sourceChild : sourceTopic.getChildren(type)) { - ITopic targetChild = targetTopic.getOwnedWorkbook() - .createTopic(); - copyTopicContents(sourceChild, targetChild); - targetTopic.add(targetChild, type); - } - } - - for (IBoundary sourceBoundary : sourceTopic.getBoundaries()) { - IBoundary targetBoundary = targetTopic.getOwnedWorkbook() - .createBoundary(); - copyBoundaryContents(sourceBoundary, targetBoundary); - targetTopic.addBoundary(targetBoundary); - } - - for (ISummary sourceSummary : sourceTopic.getSummaries()) { - ISummary targetSummary = targetTopic.getOwnedWorkbook() - .createSummary(); - copySummaryContents(sourceSummary, targetSummary); - targetTopic.addSummary(targetSummary); - } - - for (ITopicExtension sourceExt : sourceTopic.getExtensions()) { - ITopicExtension targetExt = targetTopic - .createExtension(sourceExt.getProviderName()); - copyTopicExtension(sourceExt, targetExt); - } - - targetTopic.getNumbering() - .setFormat(sourceTopic.getNumbering().getNumberFormat()); - targetTopic.getNumbering() - .setPrefix(sourceTopic.getNumbering().getPrefix()); - targetTopic.getNumbering() - .setSuffix(sourceTopic.getNumbering().getSuffix()); - targetTopic.getNumbering() - .setSeparator(sourceTopic.getNumbering().getSeparator()); - targetTopic.getNumbering().setPrependsParentNumbers( - sourceTopic.getNumbering().prependsParentNumbers()); - targetTopic.getNumbering() - .setDepth(sourceTopic.getNumbering().getDepth()); - - INotesContent sourcePlainContent = sourceTopic.getNotes() - .getContent(INotes.PLAIN); - if (sourcePlainContent != null - && sourcePlainContent instanceof IPlainNotesContent) { - INotesContent targetPlainContent = targetWorkbook - .createNotesContent(INotes.PLAIN); - if (targetPlainContent instanceof IPlainNotesContent) { - ((IPlainNotesContent) targetPlainContent).setTextContent( - ((IPlainNotesContent) sourcePlainContent) - .getTextContent()); - targetTopic.getNotes().setContent(INotes.PLAIN, - targetPlainContent); - } - } - - INotesContent sourceHtmlContent = sourceTopic.getNotes() - .getContent(INotes.HTML); - if (sourceHtmlContent != null - && sourceHtmlContent instanceof IHtmlNotesContent) { - INotesContent targetHtmlContent = targetWorkbook - .createNotesContent(INotes.HTML); - if (targetHtmlContent instanceof IHtmlNotesContent) { - copyHtmlNotesContent((IHtmlNotesContent) sourceHtmlContent, - (IHtmlNotesContent) targetHtmlContent); - targetTopic.getNotes().setContent(INotes.HTML, - targetHtmlContent); - } - } - - List targetAllTopics = new ArrayList(); - targetAllTopics.add(targetTopic); - targetAllTopics.addAll(targetTopic.getAllChildren()); - - fixInternalHyperlinkFor(targetAllTopics); - - copyComments(sourceTopic.getId(), targetTopic.getId()); - } - - /** - * @param source - * @param target - */ - private void copyComments(String sourceObjectId, String targetObjectId) { - Set sourceComments = sourceWorkbook.getCommentManager() - .getComments(sourceObjectId); - if (!sourceComments.isEmpty()) { - ICommentManager targetCommentManager = targetWorkbook - .getCommentManager(); - for (IComment sourceComment : sourceComments) { - IComment targetComment = targetCommentManager.createComment( - sourceComment.getAuthor(), sourceComment.getTime(), - targetObjectId); - targetComment.setContent(sourceComment.getContent()); - targetCommentManager.addComment(targetComment); - } - } - } - - private void fixInternalHyperlinkFor(List allTargetTopics) { - for (ITopic targetTopic : allTargetTopics) { - String hyperlink = targetTopic.getHyperlink(); - if (HyperlinkUtils.isInternalURL(hyperlink)) { - Object sourceElement = HyperlinkUtils.findElement(hyperlink, - sourceWorkbook); - Object result = mapper.get(sourceElement); - if (result != null) { - targetTopic - .setHyperlink(HyperlinkUtils.toInternalURL(result)); - } - } - } - } - - private void copyHtmlNotesContent(IHtmlNotesContent sourceNotesContent, - IHtmlNotesContent targetNotesContent) throws IOException { - for (IParagraph sourceParagraph : sourceNotesContent.getParagraphs()) { - IParagraph targetParagraph = targetNotesContent.createParagraph(); - targetParagraph - .setStyleId(convertStyleId(sourceParagraph.getStyleId())); - targetNotesContent.addParagraph(targetParagraph); - copySpanList(sourceParagraph, targetParagraph, targetNotesContent); - } - } - - private void copySpanList(ISpanList sourceSpanList, - ISpanList targetSpanList, IHtmlNotesContent spanFactory) - throws IOException { - for (ISpan sourceSpan : sourceSpanList.getSpans()) { - ISpan targetSpan; - if (sourceSpan instanceof ITextSpan) { - targetSpan = spanFactory.createTextSpan( - ((ITextSpan) sourceSpan).getTextContent()); - } else if (sourceSpan instanceof IImageSpan) { - String source = ((IImageSpan) sourceSpan).getSource(); - String newImageSource = convertHyperlink(source); - targetSpan = spanFactory.createImageSpan(newImageSource); - } else if (sourceSpan instanceof IHyperlinkSpan) { - targetSpan = spanFactory.createHyperlinkSpan( - ((IHyperlinkSpan) sourceSpan).getHref()); - copySpanList((IHyperlinkSpan) sourceSpan, - (IHyperlinkSpan) targetSpan, spanFactory); - } else { - continue; - } - targetSpan.setStyleId(convertStyleId(sourceSpan.getStyleId())); - targetSpanList.addSpan(targetSpan); - } - } - - private void copyBoundaryContents(IBoundary sourceBoundary, - IBoundary targetBoundary) throws IOException { - mapper.put(sourceBoundary, targetBoundary); - mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceBoundary.getId(), - targetBoundary.getId()); - targetBoundary.setTitleText(sourceBoundary.getTitleText()); - targetBoundary.setStyleId(convertStyleId(sourceBoundary.getStyleId())); - if (sourceBoundary.isMasterBoundary()) { - targetBoundary.setMasterBoundary(sourceBoundary.isMasterBoundary()); - } else { - targetBoundary.setStartIndex(sourceBoundary.getStartIndex()); - targetBoundary.setEndIndex(sourceBoundary.getEndIndex()); - } - } - - private void copySummaryContents(ISummary sourceSummary, - ISummary targetSummary) throws IOException { - mapper.put(sourceSummary, targetSummary); - mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceSummary.getId(), - targetSummary.getId()); - targetSummary.setStyleId(convertStyleId(sourceSummary.getStyleId())); - targetSummary.setTopicId(mapper.getString( - ICloneData.WORKBOOK_COMPONENTS, sourceSummary.getTopicId())); - targetSummary.setStartIndex(sourceSummary.getStartIndex()); - targetSummary.setEndIndex(sourceSummary.getEndIndex()); - } - - private void copyTopicExtension(ITopicExtension sourceExt, - ITopicExtension targetExt) throws IOException { - for (IResourceRef ref : sourceExt.getResourceRefs()) { - if (IResourceRef.FILE_ENTRY.equals(ref.getType())) { - String targetEntryPath = convertEntryPath(ref.getResourceId()); - if (targetEntryPath != null) { - targetExt.addResourceRef( - targetExt.getOwnedWorkbook().createResourceRef( - IResourceRef.FILE_ENTRY, targetEntryPath)); - } - } - } - - copyTopicExtensionElement(sourceExt.getContent(), - targetExt.getContent()); - } - - private void copyTopicExtensionElement(ITopicExtensionElement sourceEle, - ITopicExtensionElement targetEle) { - for (String key : sourceEle.getAttributeKeys()) { - targetEle.setAttribute(key, sourceEle.getAttribute(key)); - } - - targetEle.setTextContent(sourceEle.getTextContent()); - - for (ITopicExtensionElement sourceChild : sourceEle.getChildren()) { - ITopicExtensionElement targetChild = targetEle - .createChild(sourceChild.getName()); - copyTopicExtensionElement(sourceChild, targetChild); - } - } - - private void copyRelationshipContents(IRelationship sourceRel, - IRelationship targetRel) throws IOException { - mapper.put(sourceRel, targetRel); - mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceRel.getId(), - targetRel.getId()); - targetRel.setTitleText(sourceRel.getTitleText()); - - String end1Id = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, - sourceRel.getEnd1Id()); - targetRel.setEnd1Id(end1Id == null ? sourceRel.getEnd1Id() : end1Id); - - String end2Id = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, - sourceRel.getEnd2Id()); - targetRel.setEnd2Id(end2Id == null ? sourceRel.getEnd2Id() : end2Id); - - targetRel.setStyleId(convertStyleId(sourceRel.getStyleId())); - - copyControlPointContents(sourceRel, targetRel, 0); - copyControlPointContents(sourceRel, targetRel, 1); - } - - private void copyControlPointContents(IRelationship sourceRel, - IRelationship targetRel, int index) { - IControlPoint sourceControlPoint = sourceRel.getControlPoint(index); - if (!sourceControlPoint.hasPosition() - && !sourceControlPoint.hasPolarAngle() - && !sourceControlPoint.hasPolarAmount()) - return; - - IControlPoint targetControlPoint = targetRel.getControlPoint(index); - if (sourceControlPoint.hasPosition()) { - Point position = sourceControlPoint.getPosition(); - targetControlPoint.setPosition(new Point(position.x, position.y)); - } - if (sourceControlPoint.hasPolarAngle()) { - targetControlPoint - .setPolarAngle(sourceControlPoint.getPolarAngle()); - } - if (sourceControlPoint.hasPolarAmount()) { - targetControlPoint - .setPolarAmount(sourceControlPoint.getPolarAmount()); - } - } - - private void copyWorkbookExtension(IWorkbookExtension sourceExt, - IWorkbookExtension targetExt) throws IOException { - for (IResourceRef ref : sourceExt.getResourceRefs()) { - if (IResourceRef.FILE_ENTRY.equals(ref.getType())) { - String targetEntryPath = convertEntryPath(ref.getResourceId()); - if (targetEntryPath != null) { - targetExt.addResourceRef( - targetExt.getOwnedWorkbook().createResourceRef( - IResourceRef.FILE_ENTRY, targetEntryPath)); - } - } - } - - copyWorkbookExtensionElement(sourceExt.getContent(), - targetExt.getContent()); - } - - private void copyWorkbookExtensionElement( - IWorkbookExtensionElement sourceEle, - IWorkbookExtensionElement targetEle) throws IOException { - targetEle.setTextContent(sourceEle.getTextContent()); - for (String key : sourceEle.getAttributeKeys()) { - String value = sourceEle.getAttribute(key); - if (ATTR_RESOURCE_PATH.equals(key)) { - value = convertEntryPath(value); - } else if (ATTR_OBJECT_ID.equals(key)) { - value = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, value); - } - targetEle.setAttribute(key, value); - } - - for (IWorkbookExtensionElement sourceE : sourceEle.getChildren()) { - IWorkbookExtensionElement targetE = targetEle - .createChild(sourceE.getName()); - copyWorkbookExtensionElement(sourceE, targetE); - } - } - - private String convertHyperlink(String sourceHyperlink) throws IOException { - if (sourceHyperlink == null) - return null; - - if (HyperlinkUtils.isAttachmentURL(sourceHyperlink)) { - String sourceEntryPath = HyperlinkUtils - .toAttachmentPath(sourceHyperlink); - - String targetEntryPath = convertEntryPath(sourceEntryPath); - return targetEntryPath == null ? null - : HyperlinkUtils.toAttachmentURL(targetEntryPath); - } else if (HyperlinkUtils.isInternalURL(sourceHyperlink)) { - ///TODO handle 'xmind:xxxxx' - } - - return sourceHyperlink; - } - - /** - * @param sourceEntryPath - * @return - * @throws IOException - */ - private String convertEntryPath(String sourceEntryPath) throws IOException { - IFileEntry sourceEntry = sourceManifest.getFileEntry(sourceEntryPath); - if (sourceEntry == null || !sourceEntry.canRead()) - // TODO log missing attachment? - return null; - - String targetEntryPath; - if (sourceEntryPath.startsWith(ArchiveConstants.PATH_ATTACHMENTS)) { - // convert attachments to resources (using hash as file name) - targetEntryPath = mapper.getString(ICloneData.FILE_ENTRIES, - sourceEntryPath); - if (targetEntryPath == null) { - IFileEntry targetEntry; - InputStream sourceStream = sourceEntry.openInputStream(); - try { - targetEntry = targetManifest.createAttachmentFromStream( - sourceStream, sourceEntryPath, - sourceEntry.getMediaType()); - } finally { - sourceStream.close(); - } - targetEntryPath = targetEntry.getPath(); - mapper.putString(ICloneData.FILE_ENTRIES, sourceEntryPath, - targetEntryPath); - } - } else { - targetEntryPath = sourceEntryPath; - IFileEntry targetEntry = targetManifest - .getFileEntry(targetEntryPath); - if (targetEntry == null) { - targetEntry = targetManifest.createFileEntry(targetEntryPath, - sourceEntry.getMediaType()); - InputStream sourceStream = sourceEntry.openInputStream(); - try { - OutputStream targetStream = targetEntry.openOutputStream(); - try { - FileUtils.transfer(sourceStream, targetStream, false); - } finally { - targetStream.close(); - } - } finally { - sourceStream.close(); - } - } - } - - return targetEntryPath; - } - - private IStyle findOrCloneStyle(IStyle sourceStyle) throws IOException { - if (sourceStyle == null) - return null; - - String sourceStyleId = sourceStyle.getId(); - String targetStyleId = mapper - .getString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId); - if (targetStyleId != null) { - return targetStyleSheet.findStyle(targetStyleId); - } - - /// TODO: find similar style to reduce redundant styles - - String groupName = sourceStyleSheet.findOwnedGroup(sourceStyle); - if (groupName == null) - return null; - - IStyle targetStyle = targetStyleSheet - .createStyle(sourceStyle.getType()); - - targetStyle.setName(sourceStyle.getName()); - - Iterator properties = sourceStyle.properties(); - while (properties.hasNext()) { - Property p = properties.next(); - - String value = p.value; - if (HyperlinkUtils.isAttachmentURL(value)) { - value = convertHyperlink(value); - } - - targetStyle.setProperty(p.key, value); - } - - Iterator defaultStyleIds = sourceStyle.defaultStyles(); - while (defaultStyleIds.hasNext()) { - Property p = defaultStyleIds.next(); - targetStyle.setDefaultStyleId(p.key, convertStyleId(p.value)); - } - - targetStyleSheet.addStyle(targetStyle, groupName); - mapper.put(sourceStyle, targetStyle); - mapper.putString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId, - targetStyle.getId()); - - return targetStyle; - } - - private String convertStyleId(String sourceStyleId) throws IOException { - if (sourceStyleId == null) - return null; - - String targetStyleId = mapper - .getString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId); - if (targetStyleId != null) - return targetStyleId; - - IStyle sourceStyle = sourceStyleSheet.findStyle(sourceStyleId); - if (sourceStyle == null) - return null; - - IStyle targetStyle = findOrCloneStyle(sourceStyle); - return targetStyle == null ? null : targetStyle.getId(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.util; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_OBJECT_ID; +import static org.xmind.core.internal.dom.DOMConstants.ATTR_RESOURCE_PATH; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.xmind.core.CoreException; +import org.xmind.core.IBoundary; +import org.xmind.core.ICloneData; +import org.xmind.core.IComment; +import org.xmind.core.ICommentManager; +import org.xmind.core.IControlPoint; +import org.xmind.core.IFileEntry; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IHyperlinkSpan; +import org.xmind.core.IImage; +import org.xmind.core.IImageSpan; +import org.xmind.core.IManifest; +import org.xmind.core.IMeta; +import org.xmind.core.INotes; +import org.xmind.core.INotesContent; +import org.xmind.core.IParagraph; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.IResourceRef; +import org.xmind.core.ISettingEntry; +import org.xmind.core.ISheet; +import org.xmind.core.ISpan; +import org.xmind.core.ISpanList; +import org.xmind.core.ISummary; +import org.xmind.core.ITextSpan; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookExtension; +import org.xmind.core.IWorkbookExtensionElement; +import org.xmind.core.IWorkbookExtensionManager; +import org.xmind.core.internal.CloneData; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.marker.IMarkerResource; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class CloneHandler { + + private ICloneData mapper; + + private IWorkbook sourceWorkbook; + private IWorkbook targetWorkbook; + + private IManifest sourceManifest; + private IManifest targetManifest; + + private IStyleSheet sourceStyleSheet; + private IStyleSheet targetStyleSheet; + + private IMarkerSheet sourceMarkerSheet; + private IMarkerSheet targetMarkerSheet; + + /** + * + */ + public CloneHandler() { + this(null); + } + + /** + * + */ + public CloneHandler(ICloneData mapper) { + this.mapper = mapper == null + ? new CloneData(Collections.emptyList(), null) : mapper; + this.sourceWorkbook = null; + this.targetWorkbook = null; + this.sourceManifest = null; + this.targetManifest = null; + this.sourceStyleSheet = null; + this.targetStyleSheet = null; + this.sourceMarkerSheet = null; + this.targetMarkerSheet = null; + } + + public CloneHandler withWorkbooks(IWorkbook sourceWorkbook, + IWorkbook targetWorkbook) { + if (sourceWorkbook == null) + throw new IllegalArgumentException(); + if (targetWorkbook == null) + throw new IllegalArgumentException(); + + this.sourceWorkbook = sourceWorkbook; + this.targetWorkbook = targetWorkbook; + this.sourceManifest = sourceWorkbook.getManifest(); + this.targetManifest = targetWorkbook.getManifest(); + this.sourceStyleSheet = sourceWorkbook.getStyleSheet(); + this.targetStyleSheet = targetWorkbook.getStyleSheet(); + this.sourceMarkerSheet = sourceWorkbook.getMarkerSheet(); + this.targetMarkerSheet = targetWorkbook.getMarkerSheet(); + + return this; + } + + public CloneHandler withManifests(IManifest sourceManifest, + IManifest targetManifest) { + if (sourceManifest == null) + throw new IllegalArgumentException(); + if (targetManifest == null) + throw new IllegalArgumentException(); + + this.sourceManifest = sourceManifest; + this.targetManifest = targetManifest; + return this; + } + + public CloneHandler withStyleSheets(IStyleSheet sourceStyleSheet, + IStyleSheet targetStyleSheet) { + if (sourceStyleSheet == null) + throw new IllegalArgumentException(); + if (targetStyleSheet == null) + throw new IllegalArgumentException(); + + this.sourceStyleSheet = sourceStyleSheet; + this.targetStyleSheet = targetStyleSheet; + this.sourceManifest = sourceStyleSheet.getAdapter(IManifest.class); + this.targetManifest = targetStyleSheet.getAdapter(IManifest.class); + return this; + } + + public CloneHandler withMarkerSheets(IMarkerSheet sourceMarkerSheet, + IMarkerSheet targetMarkerSheet) { + if (sourceMarkerSheet == null) + throw new IllegalArgumentException(); + if (targetMarkerSheet == null) + throw new IllegalArgumentException(); + + this.sourceMarkerSheet = sourceMarkerSheet; + this.targetMarkerSheet = targetMarkerSheet; + this.sourceManifest = sourceMarkerSheet.getAdapter(IManifest.class); + this.targetManifest = targetMarkerSheet.getAdapter(IManifest.class); + return this; + } + + /** + * @return the mapper + */ + public ICloneData getMapper() { + return mapper; + } + + public void copyWorkbookContents() throws IOException { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + + List oldSheets = new ArrayList( + targetWorkbook.getSheets()); + for (ISheet sourceSheet : sourceWorkbook.getSheets()) { + targetWorkbook.addSheet(cloneSheet(sourceSheet)); + } + if (targetWorkbook.getSheets().isEmpty()) { + targetWorkbook.addSheet(targetWorkbook.createSheet()); + } + for (ISheet oldSheet : oldSheets) { + targetWorkbook.removeSheet(oldSheet); + } + + IMeta sourceMeta = sourceWorkbook.getMeta(); + IMeta targetMeta = targetWorkbook.getMeta(); + for (String keyPath : sourceMeta.getKeyPaths()) { + targetMeta.setValue(keyPath, sourceMeta.getValue(keyPath)); + } + + List sheets = targetWorkbook.getSheets(); + ArrayList targetAllTopics = new ArrayList(); + for (ISheet sheet : sheets) { + getAllChildrenTopic(targetAllTopics, sheet.getRootTopic()); + } + + IWorkbookExtensionManager sourceExtensionManager = sourceWorkbook + .getAdapter(IWorkbookExtensionManager.class); + IWorkbookExtensionManager targetExtensionManager = targetWorkbook + .getAdapter(IWorkbookExtensionManager.class); + if (sourceExtensionManager != null && targetExtensionManager != null) { + for (IWorkbookExtension sourceExtension : sourceExtensionManager + .getExtensions()) { + IWorkbookExtension targetExtension = targetExtensionManager + .createExtension(sourceExtension.getProviderName()); + copyWorkbookExtension(sourceExtension, targetExtension); + } + } + + fixInternalHyperlinkFor(targetAllTopics); + } + + private List getAllChildrenTopic(List topics, ITopic root) { + topics.add(root); + for (ITopic topic : root.getAllChildren()) { + getAllChildrenTopic(topics, topic); + } + return topics; + } + + /** + * Clones a source object into the target container (e.g. workbook or style + * sheet, etc.). Currently only these kinds of objects can be cloned: + *
    + *
  • {@link org.xmind.core.ISheet} (require sourceWorkbook/targetWorkbook) + *
  • + *
  • {@link org.xmind.core.ITopic} (require sourceWorkbook/targetWorkobok) + *
  • + *
  • {@link org.xmind.core.IBoundary} (require + * sourceWorkbook/targetWorkbook)
  • + *
  • {@link org.xmind.core.ISummary} (require + * sourceWorkbook/targetWorkbook)
  • + *
  • {@link org.xmind.core.IRelationship} (require + * sourceWorkbook/targetWorkbook)
  • + *
  • {@link org.xmind.core.IImage} (require sourceWorkbook/targetWorkbook) + *
  • + *
  • {@link org.xmind.core.style.IStyle} (require + * sourceStyleSheet/targetStyleSheet)
  • + *
+ * + * @param source + * the source object to clone + * @return a cloned object, or null if the object is + * unrecognized + * @throws IOException + * if any I/O error occurred during the clone process (e.g. when + * importing attachments along with its referrence topic) + * @throws AssertionError + * if required target contexts are missing + */ + public Object cloneObject(Object source) throws IOException { + Object target = mapper.get(source); + if (target != null) + return target; + + if (source instanceof ISheet) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + return cloneSheet((ISheet) source); + } else if (source instanceof ITopic) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + ITopic sourceTopic = (ITopic) source; + ITopic targetTopic = targetWorkbook.createTopic(); + copyTopicContents(sourceTopic, targetTopic); + return targetTopic; + } else if (source instanceof IBoundary) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + IBoundary sourceBoundary = (IBoundary) source; + IBoundary targetBoundary = targetWorkbook.createBoundary(); + copyBoundaryContents(sourceBoundary, targetBoundary); + return targetBoundary; + } else if (source instanceof ISummary) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + ISummary sourceSummary = (ISummary) source; + ISummary targetSummary = targetWorkbook.createSummary(); + copySummaryContents(sourceSummary, targetSummary); + return targetSummary; + } else if (source instanceof IRelationship) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + IRelationship sourceRel = (IRelationship) source; + IRelationship targetRel = targetWorkbook.createRelationship(); + copyRelationshipContents(sourceRel, targetRel); + return targetRel; + } else if (source instanceof IStyle) { + if (sourceStyleSheet == null) + throw new AssertionError("sourceStyleSheet is null"); //$NON-NLS-1$ + if (targetStyleSheet == null) + throw new AssertionError("targetStyleSheet is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + return findOrCloneStyle((IStyle) source); + } else if (source instanceof IImage) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + if (sourceManifest == null) + throw new AssertionError("sourceManifest is null"); //$NON-NLS-1$ + if (targetManifest == null) + throw new AssertionError("targetManifest is null"); //$NON-NLS-1$ + IImage sourceImage = (IImage) source; + ITopic sourceTopic = sourceImage.getParent(); + ITopic targetTopic = targetWorkbook.createTopic(); + copyTopicContents(sourceTopic, targetTopic); + IImage targetImage = targetTopic.getImage(); + mapper.put(sourceImage, targetImage); + return targetImage; + } else if (source instanceof IMarker) { + if (sourceMarkerSheet == null) + throw new AssertionError("sourceMarkerSheet is null"); //$NON-NLS-1$ + if (targetMarkerSheet == null) + throw new AssertionError("targetMarkerSheet is null"); //$NON-NLS-1$ + /// marker sheets require not manifests, but resource providers, + /// so sourceManifest and targetManifest are not checked here + IMarker marker = findOrCloneMarker((IMarker) source); + mapper.put(source, marker); + return marker; + } else if (source instanceof IMarkerRef) { + if (sourceWorkbook == null) + throw new AssertionError("sourceWorkbook is null"); //$NON-NLS-1$ + if (targetWorkbook == null) + throw new AssertionError("targetWorkbook is null"); //$NON-NLS-1$ + IMarkerRef sourceMarkerRef = (IMarkerRef) source; + IMarkerRef targetMarkerRef = cloneMarkerRef(sourceMarkerRef); + mapper.put(sourceMarkerRef, targetMarkerRef); + return targetMarkerRef; + } + + return null; + } + + /** + * @param sourceMarkerRef + * @return + * @throws IOException + */ + private IMarkerRef cloneMarkerRef(IMarkerRef sourceMarkerRef) + throws IOException { + IMarkerRef targetMarkerRef; + IMarker sourceMarker = sourceMarkerRef.getMarker(); + if (sourceMarker == null) { + targetMarkerRef = sourceMarkerRef; + } else { + IMarker targetMarker = findOrCloneMarker(sourceMarker); + if (targetMarker == null) { + targetMarkerRef = null; + } else { + mapper.put(sourceMarker, targetMarker); + mapper.putString(ICloneData.MARKERSHEET_COMPONENTS, + sourceMarker.getId(), targetMarker.getId()); + ITopic tempTopic = targetWorkbook.createTopic(); + tempTopic.addMarker(targetMarker.getId()); + targetMarkerRef = tempTopic.getMarkerRefs().iterator().next(); + } + } + return targetMarkerRef; + } + + private IMarker findOrCloneMarker(IMarker sourceMarker) throws IOException { + if (sourceMarker == null) + return null; + + IMarker targetMarker = (IMarker) mapper.get(sourceMarker); + if (targetMarker != null) + return targetMarker; + + String markerId = sourceMarker.getId(); + targetMarker = targetMarkerSheet.findMarker(markerId); + if (targetMarker != null) { + mapper.put(sourceMarker, targetMarker); + return targetMarker; + } + + /// markers do not change across permanent marker sheets + if (sourceMarker.getOwnedSheet().isPermanent()) + return sourceMarker; + + IMarkerGroup sourceGroup = sourceMarker.getParent(); + IMarkerGroup targetGroup = findOrCloneMarkerGroup(sourceGroup); + + String sourceResourcePath = sourceMarker.getResourcePath(); + String targetResourcePath = null; + + /// copy marker resource content + IMarkerResource sourceResource = sourceMarker.getResource(); + if (sourceResource != null) { + InputStream input = null; + try { + input = sourceResource.openInputStream(); + targetResourcePath = targetMarkerSheet + .allocateMarkerResource(input, sourceResourcePath); + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (input != null) { + input.close(); + } + } + } + + /// create target marker with the same marker id + targetMarker = targetMarkerSheet.createMarkerById(markerId, + targetResourcePath); + + targetMarker.setName(sourceMarker.getName()); + + if (targetGroup != null) + targetGroup.addMarker(targetMarker); + + mapper.put(sourceMarker, targetMarker); + + return targetMarker; + } + + private IMarkerGroup findOrCloneMarkerGroup( + IMarkerGroup sourceMarkerGroup) { + if (sourceMarkerGroup == null) + return null; + + IMarkerGroup targetMarkerGroup = (IMarkerGroup) mapper + .get(sourceMarkerGroup); + if (targetMarkerGroup != null) + return targetMarkerGroup; + + String groupId = sourceMarkerGroup.getId(); + targetMarkerGroup = targetMarkerSheet.findMarkerGroup(groupId); + if (targetMarkerGroup == null + || targetMarkerGroup.getOwnedSheet() != targetMarkerSheet) { + /// make sure the new group is owned by the target marker sheet + targetMarkerGroup = targetMarkerSheet + .createMarkerGroupById(groupId); + targetMarkerGroup.setSingleton(sourceMarkerGroup.isSingleton()); + targetMarkerGroup.setName(sourceMarkerGroup.getName()); + } + if (targetMarkerGroup.getParent() == null) { + targetMarkerSheet.addMarkerGroup(targetMarkerGroup); + } + return targetMarkerGroup; + } + + private ISheet cloneSheet(ISheet sourceSheet) throws IOException { + ISheet targetSheet = targetWorkbook.createSheet(); + copySheetContents(sourceSheet, targetSheet); + + ArrayList targetAllTopics = new ArrayList(); + getAllChildrenTopic(targetAllTopics, targetSheet.getRootTopic()); + + fixInternalHyperlinkFor(targetAllTopics); + return targetSheet; + } + + /** + * @param sourceSheet + * @param targetSheet + * @throws IOException + * @throws CoreException + */ + private void copySheetContents(ISheet sourceSheet, ISheet targetSheet) + throws IOException { + mapper.put(sourceSheet, targetSheet); + mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceSheet.getId(), + targetSheet.getId()); + + targetSheet.setTitleText(sourceSheet.getTitleText()); + targetSheet.setStyleId(convertStyleId(sourceSheet.getStyleId())); + targetSheet.setThemeId(convertStyleId(sourceSheet.getThemeId())); + + ITopic sourceRootTopic = sourceSheet.getRootTopic(); + if (sourceRootTopic != null) { + ITopic targetRootTopic = targetSheet.getRootTopic(); + copyTopicContents(sourceRootTopic, targetRootTopic); + } + + for (IRelationship sourceRel : sourceSheet.getRelationships()) { + IRelationship targetRel = targetWorkbook.createRelationship(); + copyRelationshipContents(sourceRel, targetRel); + targetSheet.addRelationship(targetRel); + } + + targetSheet.getLegend().setVisible(sourceSheet.getLegend().isVisible()); + targetSheet.getLegend() + .setPosition(sourceSheet.getLegend().getPosition()); + for (String markerId : sourceSheet.getLegend().getMarkerIds()) { + targetSheet.getLegend().setMarkerDescription(markerId, + sourceSheet.getLegend().getMarkerDescription(markerId)); + } + + for (String settingPath : sourceSheet.getSettings().getPaths()) { + for (ISettingEntry sourceSettingEntry : sourceSheet.getSettings() + .getEntries(settingPath)) { + ISettingEntry targetSettingEntry = targetSheet.getSettings() + .createEntry(settingPath); + for (String key : sourceSettingEntry.getAttributeKeys()) { + targetSettingEntry.setAttribute(key, + sourceSettingEntry.getAttribute(key)); + } + targetSheet.getSettings().addEntry(targetSettingEntry); + } + } + + copyComments(sourceSheet.getId(), targetSheet.getId()); + } + + private void copyTopicContents(ITopic sourceTopic, ITopic targetTopic) + throws IOException { + mapper.put(sourceTopic, targetTopic); + mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceTopic.getId(), + targetTopic.getId()); + targetTopic.setTitleText( + sourceTopic.hasTitle() ? sourceTopic.getTitleText() : null); + targetTopic.setTitleWidth(sourceTopic.getTitleWidth()); + targetTopic.setFolded(sourceTopic.isFolded()); + targetTopic.setStructureClass(sourceTopic.getStructureClass()); + targetTopic.setPosition(sourceTopic.getPosition()); + + targetTopic.setHyperlink(convertHyperlink(sourceTopic.getHyperlink())); + + for (String label : sourceTopic.getLabels()) { + targetTopic.addLabel(label); + } + + for (IMarkerRef markerRef : sourceTopic.getMarkerRefs()) { + IMarkerRef mr = (IMarkerRef) cloneObject(markerRef); + if (mr != null) { + targetTopic.addMarker(mr.getMarkerId()); + } + } + + targetTopic.setStyleId(convertStyleId(sourceTopic.getStyleId())); + + targetTopic.getImage().setSource( + convertHyperlink(sourceTopic.getImage().getSource())); + targetTopic.getImage().setWidth(sourceTopic.getImage().getWidth()); + targetTopic.getImage().setHeight(sourceTopic.getImage().getHeight()); + targetTopic.getImage() + .setAlignment(sourceTopic.getImage().getAlignment()); + + for (String type : sourceTopic.getChildrenTypes()) { + for (ITopic sourceChild : sourceTopic.getChildren(type)) { + ITopic targetChild = targetTopic.getOwnedWorkbook() + .createTopic(); + copyTopicContents(sourceChild, targetChild); + targetTopic.add(targetChild, type); + } + } + + for (IBoundary sourceBoundary : sourceTopic.getBoundaries()) { + IBoundary targetBoundary = targetTopic.getOwnedWorkbook() + .createBoundary(); + copyBoundaryContents(sourceBoundary, targetBoundary); + targetTopic.addBoundary(targetBoundary); + } + + for (ISummary sourceSummary : sourceTopic.getSummaries()) { + ISummary targetSummary = targetTopic.getOwnedWorkbook() + .createSummary(); + copySummaryContents(sourceSummary, targetSummary); + targetTopic.addSummary(targetSummary); + } + + for (ITopicExtension sourceExt : sourceTopic.getExtensions()) { + ITopicExtension targetExt = targetTopic + .createExtension(sourceExt.getProviderName()); + copyTopicExtension(sourceExt, targetExt); + } + + targetTopic.getNumbering() + .setFormat(sourceTopic.getNumbering().getNumberFormat()); + targetTopic.getNumbering() + .setPrefix(sourceTopic.getNumbering().getPrefix()); + targetTopic.getNumbering() + .setSuffix(sourceTopic.getNumbering().getSuffix()); + targetTopic.getNumbering() + .setSeparator(sourceTopic.getNumbering().getSeparator()); + targetTopic.getNumbering().setPrependsParentNumbers( + sourceTopic.getNumbering().prependsParentNumbers()); + targetTopic.getNumbering() + .setDepth(sourceTopic.getNumbering().getDepth()); + + INotesContent sourcePlainContent = sourceTopic.getNotes() + .getContent(INotes.PLAIN); + if (sourcePlainContent != null + && sourcePlainContent instanceof IPlainNotesContent) { + INotesContent targetPlainContent = targetWorkbook + .createNotesContent(INotes.PLAIN); + if (targetPlainContent instanceof IPlainNotesContent) { + ((IPlainNotesContent) targetPlainContent).setTextContent( + ((IPlainNotesContent) sourcePlainContent) + .getTextContent()); + targetTopic.getNotes().setContent(INotes.PLAIN, + targetPlainContent); + } + } + + INotesContent sourceHtmlContent = sourceTopic.getNotes() + .getContent(INotes.HTML); + if (sourceHtmlContent != null + && sourceHtmlContent instanceof IHtmlNotesContent) { + INotesContent targetHtmlContent = targetWorkbook + .createNotesContent(INotes.HTML); + if (targetHtmlContent instanceof IHtmlNotesContent) { + copyHtmlNotesContent((IHtmlNotesContent) sourceHtmlContent, + (IHtmlNotesContent) targetHtmlContent); + targetTopic.getNotes().setContent(INotes.HTML, + targetHtmlContent); + } + } + + List targetAllTopics = new ArrayList(); + getAllChildrenTopic(targetAllTopics, targetTopic); + + fixInternalHyperlinkFor(targetAllTopics); + + copyComments(sourceTopic.getId(), targetTopic.getId()); + } + + /** + * @param source + * @param target + */ + private void copyComments(String sourceObjectId, String targetObjectId) { + Set sourceComments = sourceWorkbook.getCommentManager() + .getComments(sourceObjectId); + if (!sourceComments.isEmpty()) { + ICommentManager targetCommentManager = targetWorkbook + .getCommentManager(); + for (IComment sourceComment : sourceComments) { + IComment targetComment = targetCommentManager.createComment( + sourceComment.getAuthor(), sourceComment.getTime(), + targetObjectId); + targetComment.setContent(sourceComment.getContent()); + targetCommentManager.addComment(targetComment); + } + } + } + + private void fixInternalHyperlinkFor(List allTargetTopics) { + for (ITopic targetTopic : allTargetTopics) { + String hyperlink = targetTopic.getHyperlink(); + if (HyperlinkUtils.isInternalURL(hyperlink)) { + Object sourceElement = HyperlinkUtils.findElement(hyperlink, + sourceWorkbook); + Object result = mapper.get(sourceElement); + if (result != null) { + targetTopic + .setHyperlink(HyperlinkUtils.toInternalURL(result)); + } + } + } + } + + private void copyHtmlNotesContent(IHtmlNotesContent sourceNotesContent, + IHtmlNotesContent targetNotesContent) throws IOException { + for (IParagraph sourceParagraph : sourceNotesContent.getParagraphs()) { + IParagraph targetParagraph = targetNotesContent.createParagraph(); + targetParagraph + .setStyleId(convertStyleId(sourceParagraph.getStyleId())); + targetNotesContent.addParagraph(targetParagraph); + copySpanList(sourceParagraph, targetParagraph, targetNotesContent); + } + } + + private void copySpanList(ISpanList sourceSpanList, + ISpanList targetSpanList, IHtmlNotesContent spanFactory) + throws IOException { + for (ISpan sourceSpan : sourceSpanList.getSpans()) { + ISpan targetSpan; + if (sourceSpan instanceof ITextSpan) { + targetSpan = spanFactory.createTextSpan( + ((ITextSpan) sourceSpan).getTextContent()); + } else if (sourceSpan instanceof IImageSpan) { + String source = ((IImageSpan) sourceSpan).getSource(); + String newImageSource = convertHyperlink(source); + targetSpan = spanFactory.createImageSpan(newImageSource); + } else if (sourceSpan instanceof IHyperlinkSpan) { + targetSpan = spanFactory.createHyperlinkSpan( + ((IHyperlinkSpan) sourceSpan).getHref()); + copySpanList((IHyperlinkSpan) sourceSpan, + (IHyperlinkSpan) targetSpan, spanFactory); + } else { + continue; + } + targetSpan.setStyleId(convertStyleId(sourceSpan.getStyleId())); + targetSpanList.addSpan(targetSpan); + } + } + + private void copyBoundaryContents(IBoundary sourceBoundary, + IBoundary targetBoundary) throws IOException { + mapper.put(sourceBoundary, targetBoundary); + mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceBoundary.getId(), + targetBoundary.getId()); + targetBoundary.setTitleText(sourceBoundary.getTitleText()); + targetBoundary.setStyleId(convertStyleId(sourceBoundary.getStyleId())); + if (sourceBoundary.isMasterBoundary()) { + targetBoundary.setMasterBoundary(sourceBoundary.isMasterBoundary()); + } else { + targetBoundary.setStartIndex(sourceBoundary.getStartIndex()); + targetBoundary.setEndIndex(sourceBoundary.getEndIndex()); + } + } + + private void copySummaryContents(ISummary sourceSummary, + ISummary targetSummary) throws IOException { + mapper.put(sourceSummary, targetSummary); + mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceSummary.getId(), + targetSummary.getId()); + targetSummary.setStyleId(convertStyleId(sourceSummary.getStyleId())); + targetSummary.setTopicId(mapper.getString( + ICloneData.WORKBOOK_COMPONENTS, sourceSummary.getTopicId())); + targetSummary.setStartIndex(sourceSummary.getStartIndex()); + targetSummary.setEndIndex(sourceSummary.getEndIndex()); + } + + private void copyTopicExtension(ITopicExtension sourceExt, + ITopicExtension targetExt) throws IOException { + for (IResourceRef ref : sourceExt.getResourceRefs()) { + if (IResourceRef.FILE_ENTRY.equals(ref.getType())) { + String targetEntryPath = convertEntryPath(ref.getResourceId()); + if (targetEntryPath != null) { + targetExt.addResourceRef( + targetExt.getOwnedWorkbook().createResourceRef( + IResourceRef.FILE_ENTRY, targetEntryPath)); + } + } + } + + copyTopicExtensionElement(sourceExt.getContent(), + targetExt.getContent()); + } + + private void copyTopicExtensionElement(ITopicExtensionElement sourceEle, + ITopicExtensionElement targetEle) { + for (String key : sourceEle.getAttributeKeys()) { + targetEle.setAttribute(key, sourceEle.getAttribute(key)); + } + + targetEle.setTextContent(sourceEle.getTextContent()); + + for (ITopicExtensionElement sourceChild : sourceEle.getChildren()) { + ITopicExtensionElement targetChild = targetEle + .createChild(sourceChild.getName()); + copyTopicExtensionElement(sourceChild, targetChild); + } + } + + private void copyRelationshipContents(IRelationship sourceRel, + IRelationship targetRel) throws IOException { + mapper.put(sourceRel, targetRel); + mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceRel.getId(), + targetRel.getId()); + targetRel.setTitleText(sourceRel.getTitleText()); + + String end1Id = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, + sourceRel.getEnd1Id()); + targetRel.setEnd1Id(end1Id == null ? sourceRel.getEnd1Id() : end1Id); + + String end2Id = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, + sourceRel.getEnd2Id()); + targetRel.setEnd2Id(end2Id == null ? sourceRel.getEnd2Id() : end2Id); + + targetRel.setStyleId(convertStyleId(sourceRel.getStyleId())); + + copyControlPointContents(sourceRel, targetRel, 0); + copyControlPointContents(sourceRel, targetRel, 1); + } + + private void copyControlPointContents(IRelationship sourceRel, + IRelationship targetRel, int index) { + IControlPoint sourceControlPoint = sourceRel.getControlPoint(index); + if (!sourceControlPoint.hasPosition() + && !sourceControlPoint.hasPolarAngle() + && !sourceControlPoint.hasPolarAmount()) + return; + + IControlPoint targetControlPoint = targetRel.getControlPoint(index); + if (sourceControlPoint.hasPosition()) { + Point position = sourceControlPoint.getPosition(); + targetControlPoint.setPosition(new Point(position.x, position.y)); + } + if (sourceControlPoint.hasPolarAngle()) { + targetControlPoint + .setPolarAngle(sourceControlPoint.getPolarAngle()); + } + if (sourceControlPoint.hasPolarAmount()) { + targetControlPoint + .setPolarAmount(sourceControlPoint.getPolarAmount()); + } + } + + private void copyWorkbookExtension(IWorkbookExtension sourceExt, + IWorkbookExtension targetExt) throws IOException { + for (IResourceRef ref : sourceExt.getResourceRefs()) { + if (IResourceRef.FILE_ENTRY.equals(ref.getType())) { + String targetEntryPath = convertEntryPath(ref.getResourceId()); + if (targetEntryPath != null) { + targetExt.addResourceRef( + targetExt.getOwnedWorkbook().createResourceRef( + IResourceRef.FILE_ENTRY, targetEntryPath)); + } + } + } + + copyWorkbookExtensionElement(sourceExt.getContent(), + targetExt.getContent()); + } + + private void copyWorkbookExtensionElement( + IWorkbookExtensionElement sourceEle, + IWorkbookExtensionElement targetEle) throws IOException { + targetEle.setTextContent(sourceEle.getTextContent()); + for (String key : sourceEle.getAttributeKeys()) { + String value = sourceEle.getAttribute(key); + if (ATTR_RESOURCE_PATH.equals(key)) { + value = convertEntryPath(value); + } else if (ATTR_OBJECT_ID.equals(key)) { + value = mapper.getString(ICloneData.WORKBOOK_COMPONENTS, value); + } + targetEle.setAttribute(key, value); + } + + for (IWorkbookExtensionElement sourceE : sourceEle.getChildren()) { + IWorkbookExtensionElement targetE = targetEle + .createChild(sourceE.getName()); + copyWorkbookExtensionElement(sourceE, targetE); + } + } + + private String convertHyperlink(String sourceHyperlink) throws IOException { + if (sourceHyperlink == null) + return null; + + if (HyperlinkUtils.isAttachmentURL(sourceHyperlink)) { + String sourceEntryPath = HyperlinkUtils + .toAttachmentPath(sourceHyperlink); + + String targetEntryPath = convertEntryPath(sourceEntryPath); + return targetEntryPath == null ? null + : HyperlinkUtils.toAttachmentURL(targetEntryPath); + } else if (HyperlinkUtils.isInternalURL(sourceHyperlink)) { + ///TODO handle 'xmind:xxxxx' + } + + return sourceHyperlink; + } + + /** + * @param sourceEntryPath + * @return + * @throws IOException + */ + private String convertEntryPath(String sourceEntryPath) throws IOException { + IFileEntry sourceEntry = sourceManifest.getFileEntry(sourceEntryPath); + if (sourceEntry == null || !sourceEntry.canRead()) + // TODO log missing attachment? + return null; + + String targetEntryPath; + if (sourceEntryPath.startsWith(ArchiveConstants.PATH_ATTACHMENTS)) { + // convert attachments to resources (using hash as file name) + targetEntryPath = mapper.getString(ICloneData.FILE_ENTRIES, + sourceEntryPath); + if (targetEntryPath == null) { + IFileEntry targetEntry; + InputStream sourceStream = sourceEntry.openInputStream(); + try { + targetEntry = targetManifest.createAttachmentFromStream( + sourceStream, sourceEntryPath, + sourceEntry.getMediaType()); + } finally { + sourceStream.close(); + } + targetEntryPath = targetEntry.getPath(); + mapper.putString(ICloneData.FILE_ENTRIES, sourceEntryPath, + targetEntryPath); + } + } else { + targetEntryPath = sourceEntryPath; + IFileEntry targetEntry = targetManifest + .getFileEntry(targetEntryPath); + if (targetEntry == null) { + targetEntry = targetManifest.createFileEntry(targetEntryPath, + sourceEntry.getMediaType()); + InputStream sourceStream = sourceEntry.openInputStream(); + try { + OutputStream targetStream = targetEntry.openOutputStream(); + try { + FileUtils.transfer(sourceStream, targetStream, false); + } finally { + targetStream.close(); + } + } finally { + sourceStream.close(); + } + } + } + + return targetEntryPath; + } + + private IStyle findOrCloneStyle(IStyle sourceStyle) throws IOException { + if (sourceStyle == null) + return null; + + String sourceStyleId = sourceStyle.getId(); + String targetStyleId = mapper + .getString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId); + if (targetStyleId != null) { + return targetStyleSheet.findStyle(targetStyleId); + } + + /// TODO: find similar style to reduce redundant styles + + String groupName = sourceStyleSheet.findOwnedGroup(sourceStyle); + if (groupName == null) + return null; + + IStyle targetStyle = targetStyleSheet + .createStyle(sourceStyle.getType()); + + targetStyle.setName(sourceStyle.getName()); + + Iterator properties = sourceStyle.properties(); + while (properties.hasNext()) { + Property p = properties.next(); + + String value = p.value; + if (HyperlinkUtils.isAttachmentURL(value)) { + value = convertHyperlink(value); + } + + targetStyle.setProperty(p.key, value); + } + + Iterator defaultStyleIds = sourceStyle.defaultStyles(); + while (defaultStyleIds.hasNext()) { + Property p = defaultStyleIds.next(); + targetStyle.setDefaultStyleId(p.key, convertStyleId(p.value)); + } + + targetStyleSheet.addStyle(targetStyle, groupName); + mapper.put(sourceStyle, targetStyle); + mapper.putString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId, + targetStyle.getId()); + + return targetStyle; + } + + private String convertStyleId(String sourceStyleId) throws IOException { + if (sourceStyleId == null) + return null; + + String targetStyleId = mapper + .getString(ICloneData.STYLESHEET_COMPONENTS, sourceStyleId); + if (targetStyleId != null) + return targetStyleId; + + IStyle sourceStyle = sourceStyleSheet.findStyle(sourceStyleId); + if (sourceStyle == null) + return null; + + IStyle targetStyle = findOrCloneStyle(sourceStyle); + return targetStyle == null ? null : targetStyle.getId(); + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/Codec.java b/bundles/org.xmind.core/src/org/xmind/core/util/Codec.java index 83efff5e6..cdb333a57 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/Codec.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/Codec.java @@ -1,83 +1,83 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.util; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class Codec { - - public static final String HASH_ALGORITHM = "SHA-256"; //$NON-NLS-1$ - - private Codec() { - } - - public static char[] hexEncode(byte[] bytes, boolean upperCase) { - int bytesLength = bytes.length; - char[] chars = new char[bytesLength << 1]; - int byteIndex = 0; - int charIndex = 0; - int value; - char c; - while (byteIndex < bytesLength) { - value = bytes[byteIndex++] & 0xFF; - - c = Character.forDigit(value >> 4, 16); - if (upperCase) - c = Character.toUpperCase(c); - chars[charIndex++] = c; - - c = Character.forDigit(value & 0x0F, 16); - if (upperCase) - c = Character.toUpperCase(c); - chars[charIndex++] = c; - } - - return chars; - } - - public static byte[] hexDecode(char[] chars) { - int charsLength = chars.length; - if ((charsLength & 0x01) != 0) - throw new IllegalArgumentException( - "Invalid hex length: " + charsLength); //$NON-NLS-1$ - - byte[] bytes = new byte[charsLength >> 1]; - - int charIndex = 0; - int byteIndex = 0; - int value1; - int value2; - while (charIndex < charsLength) { - value1 = Character.digit(chars[charIndex], 16); - if (value1 < 0) - throw new IllegalArgumentException("Invalid character '" //$NON-NLS-1$ - + chars[charIndex] + "' at index " + charIndex); //$NON-NLS-1$ - charIndex++; - value2 = Character.digit(chars[charIndex], 16); - if (value2 < 0) - throw new IllegalArgumentException("Invalid character '" //$NON-NLS-1$ - + chars[charIndex] + "' at index " + charIndex); //$NON-NLS-1$ - charIndex++; - bytes[byteIndex++] = (byte) (((value1 << 4) | value2) & 0xFF); - } - - return bytes; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.util; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class Codec { + + public static final String HASH_ALGORITHM = "SHA-256"; //$NON-NLS-1$ + + private Codec() { + } + + public static char[] hexEncode(byte[] bytes, boolean upperCase) { + int bytesLength = bytes.length; + char[] chars = new char[bytesLength << 1]; + int byteIndex = 0; + int charIndex = 0; + int value; + char c; + while (byteIndex < bytesLength) { + value = bytes[byteIndex++] & 0xFF; + + c = Character.forDigit(value >> 4, 16); + if (upperCase) + c = Character.toUpperCase(c); + chars[charIndex++] = c; + + c = Character.forDigit(value & 0x0F, 16); + if (upperCase) + c = Character.toUpperCase(c); + chars[charIndex++] = c; + } + + return chars; + } + + public static byte[] hexDecode(char[] chars) { + int charsLength = chars.length; + if ((charsLength & 0x01) != 0) + throw new IllegalArgumentException( + "Invalid hex length: " + charsLength); //$NON-NLS-1$ + + byte[] bytes = new byte[charsLength >> 1]; + + int charIndex = 0; + int byteIndex = 0; + int value1; + int value2; + while (charIndex < charsLength) { + value1 = Character.digit(chars[charIndex], 16); + if (value1 < 0) + throw new IllegalArgumentException("Invalid character '" //$NON-NLS-1$ + + chars[charIndex] + "' at index " + charIndex); //$NON-NLS-1$ + charIndex++; + value2 = Character.digit(chars[charIndex], 16); + if (value2 < 0) + throw new IllegalArgumentException("Invalid character '" //$NON-NLS-1$ + + chars[charIndex] + "' at index " + charIndex); //$NON-NLS-1$ + charIndex++; + bytes[byteIndex++] = (byte) (((value1 << 4) | value2) & 0xFF); + } + + return bytes; + } + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/DOMUtils.java b/bundles/org.xmind.core/src/org/xmind/core/util/DOMUtils.java index ac6fbfb92..6cd8a0913 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/DOMUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/DOMUtils.java @@ -1,763 +1,763 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IAdaptable; -import org.xmind.core.ITopic; -import org.xmind.core.internal.dom.INodeAdaptableProvider; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class DOMUtils { - - private static class ElementIterator implements Iterator { - - private String tagName; - - private Node child; -// private NodeList children; -// -// private int index; - - private Element next; - - public ElementIterator(Node parent) { - this(parent, null); - } - - public ElementIterator(Node parent, String tagName) { - this.tagName = tagName; - this.child = parent.getFirstChild(); -// this.children = parent.getChildNodes(); -// this.index = 0; - this.next = findNextElement(); - } - - private Element findNextElement() { - if (child == null) { - next = null; - } else { - while (child != null && !isElementByTag(child, tagName)) { - child = child.getNextSibling(); - } - if (child != null) { - next = (Element) child; - child = child.getNextSibling(); - } else { - next = null; - } - } -// for (int i = index; i < children.getLength(); i++) { -// Node n = children.item(i); -// if (isElementByTag(n, tagName)) { -// next = (Element) n; -// index = i + 1; -// return next; -// } -// } - return next; - } - - public boolean hasNext() { - return next != null; - } - - public Element next() { - Element result = next; - next = findNextElement(); - return result; - } - - public void remove() { - } - - } - - public static class AdaptableIterator - implements Iterator { - - private Node node; - - private String tagName; - - private INodeAdaptableProvider provider; - - private boolean reversed; - - private T next; - - public AdaptableIterator(Node parent, String tagName, - INodeAdaptableProvider provider, boolean reversed) { - this.tagName = tagName; - this.provider = provider; - this.reversed = reversed; - this.node = reversed ? parent.getLastChild() - : parent.getFirstChild(); - this.next = findNext(); - } - - @SuppressWarnings("unchecked") - private T findNext() { - while (node != null) { - IAdaptable obj; - if (isElementByTag(node, tagName)) { - obj = provider.getAdaptable(node); - } else { - obj = null; - } - node = reversed ? node.getPreviousSibling() - : node.getNextSibling(); - if (obj != null) - return (T) obj; - } - return null; - } - - public boolean hasNext() { - return next != null; - } - - public T next() { - T n = next; - next = findNext(); - return n; - } - - public void remove() { - } - - } - - private static class DelegateSet extends AbstractSet { - - private Collection c; - - public DelegateSet(Collection c) { - this.c = c; - } - - public Iterator iterator() { - return c.iterator(); - } - - public int size() { - return c.size(); - } - - } - - private static final ErrorHandler NULL_ERROR_HANDLER = new ErrorHandler() { - - public void warning(SAXParseException exception) throws SAXException { - } - - public void fatalError(SAXParseException exception) - throws SAXException { - } - - public void error(SAXParseException exception) throws SAXException { - } - - }; - -// private static Transformer transformer = null; -// private static DocumentBuilder documentBuilder = null; - - private DOMUtils() { - } - - public static Transformer getDefaultTransformer() throws CoreException { - try { - return TransformerFactory.newInstance().newTransformer(); - } catch (TransformerException e) { - throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, e); - } - } - - public static DocumentBuilder getDefaultDocumentBuilder() - throws ParserConfigurationException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - try { - factory.setAttribute( - "http://apache.org/xml/features/continue-after-fatal-error", //$NON-NLS-1$ - true); - } catch (Exception e) { - // ignore - } - try { - factory.setFeature( - "http://apache.org/xml/features/disallow-doctype-decl", //$NON-NLS-1$ - true); - } catch (Exception e) { - // ignore - } - try { - factory.setFeature( - "http://xml.org/sax/features/external-parameter-entities", //$NON-NLS-1$ - false); - } catch (Exception e) { - // ignore - } - try { - factory.setFeature( - "http://xml.org/sax/features/external-general-entities", //$NON-NLS-1$ - false); - } catch (Exception e) { - // ignore - } - factory.setXIncludeAware(false); - factory.setExpandEntityReferences(false); - factory.setNamespaceAware(true); - factory.setIgnoringElementContentWhitespace(true); - DocumentBuilder documentBuilder = factory.newDocumentBuilder(); - documentBuilder.setErrorHandler(NULL_ERROR_HANDLER); - return documentBuilder; - } - - public static String toString(Node node) { - if (node == null) - return "null"; //$NON-NLS-1$ - StringBuilder sb = new StringBuilder(); - sb.append('['); - sb.append(node.getNodeName()); - NamedNodeMap attributes = node.getAttributes(); - if (attributes != null && attributes.getLength() > 0) { - for (int i = 0; i < attributes.getLength(); i++) { - sb.append(' '); - Node item = attributes.item(i); - sb.append(item.getNodeName()); - sb.append('='); - sb.append('"'); - sb.append(item.getNodeValue()); - sb.append('"'); - } - } - sb.append(']'); - return sb.toString(); - } - - public static Document doCreateDocument() - throws ParserConfigurationException { - return getDefaultDocumentBuilder().newDocument(); - } - - /** - * @return - */ - public static Document createDocument() { - try { - return getDefaultDocumentBuilder().newDocument(); - } catch (ParserConfigurationException e) { - return null; - } - } - - /** - * @param docTag - * =manifest - * @return - */ - public static Document createDocument(String docTag) { - Document ret = createDocument(); - createElement(ret, docTag); - return ret; - } - - /** - * @param is - * @return - * @throws IOException - */ - public static Document loadDocument(InputStream is) throws IOException { - if (is == null) - throw new IllegalArgumentException(); - try { - return getDefaultDocumentBuilder().parse(is); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e.getMessage()); - } - } - - public static Document loadDocument(byte[] bytes) throws IOException { - if (bytes == null) - throw new IllegalArgumentException(); - ByteArrayInputStream in = new ByteArrayInputStream(bytes); - try { - return loadDocument(in); - } finally { - in.close(); - } - } - - public static void save(Node dom, OutputStream out, boolean closeOnFinish) - throws IOException, CoreException { - save(getDefaultTransformer(), dom, out, closeOnFinish); - } - - //manifest, zob, false - public static void save(IAdaptable adaptable, OutputStream out, - boolean closeOnFinish) throws IOException, CoreException { - save(getDefaultTransformer(), adaptable, out, closeOnFinish); - } - - public static void save(Transformer t, IAdaptable adaptable, - OutputStream out, boolean closeOnFinish) throws IOException { - Node dom = (Node) adaptable.getAdapter(Node.class); - - if (dom != null) { - save(t, dom, out, closeOnFinish); - } - } - - public static void save(Transformer t, Node dom, OutputStream out, - boolean closeOnFinish) throws IOException { - try { - t.transform(new DOMSource(dom), new StreamResult(out)); - } catch (TransformerException e) { - throw new IOException(e.getMessage()); - } finally { - if (closeOnFinish) { - out.close(); - } - } - } - - /** - * @param parent - * @param tag - * =manifest - * @return - */ - public static Element createElement(Node parent, String tag) { - Document doc = parent.getNodeType() == Node.DOCUMENT_NODE - ? (Document) parent : parent.getOwnerDocument(); - Element e = doc.createElement(tag); - parent.appendChild(e); - return e; - } - - public static String getPrefix(String qualifiedName) { - int index = qualifiedName.indexOf(':'); - if (index >= 0) - return qualifiedName.substring(0, index); - return null; - } - - public static String getLocalName(String qualifiedName) { - int index = qualifiedName.indexOf(':'); - if (index >= 0) - return qualifiedName.substring(index + 1); - return qualifiedName; - } - - public static String getQualifiedName(String prefix, String localName) { - return prefix + ":" + localName; //$NON-NLS-1$ - } - - /** - * @param parent - * @param tag - * @param text - * @return - */ - public static Element createText(Node parent, String tag, String text) { - Element e = createElement(parent, tag); - Node t = parent.getOwnerDocument().createTextNode(text); - e.appendChild(t); - return e; - } - - /** - * @param parent - * @param name - * @param value - * @return - */ - public static Attr createAttr(Element parent, String name, Object value) { - if (value == null) - return null; - Attr a = parent.getOwnerDocument().createAttribute(name); - a.setNodeValue(value.toString()); - parent.getAttributes().setNamedItem(a); - return a; - } - - /** - * @param element - * @param attrName - * @param value - */ - public static void setAttribute(Element element, String attrName, - Object value) { - if (value != null) { - element.setAttribute(attrName, value.toString()); - } else if (element.hasAttribute(attrName)) { - element.removeAttribute(attrName); - } - } - - public static String getAttribute(Element element, String attrName) { - if (!element.hasAttribute(attrName)) { - String localName = getLocalName(attrName); - if (!attrName.equals(localName)) - return getAttribute(element, localName); - return null; - } - return element.getAttribute(attrName); - } - - public static boolean isElementByTag(Node node, String tagName) { - if (!(node instanceof Element)) - return false; - if (tagName == null) - return true; - Element element = (Element) node; - String tag = element.getTagName(); - return tag.equals(tagName) - || getLocalName(tag).equals(getLocalName(tagName)); - } - - public static Iterator childElementIter(Node parent) { - return new ElementIterator(parent); - } - - public static Iterator childElementIterByTag(Node parent, - String tagName) { - return new ElementIterator(parent, tagName); - } - - public static boolean hasChildElement(Node parent) { - return childElementIter(parent).hasNext(); - } - - public static boolean hasChildElementByTag(Node parent, String tagName) { - return childElementIterByTag(parent, tagName).hasNext(); - } - - public static int getElementIndex(Node parent, String tagName, - Element child) { - Iterator it = childElementIterByTag(parent, tagName); - for (int i = 0; it.hasNext(); i++) { - if (it.next() == child) - return i; - } - return -1; - } - - public static int getNodeIndex(Node parent, Node child) { - NodeList children = parent.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (child == children.item(i)) - return i; - } - return -1; - } - - public static Element getFirstChildElement(Node parent) { - return childElementIter(parent).next(); - } - - public static Element getFirstChildElementByTag(Node parent, String tag) { - return childElementIterByTag(parent, tag).next(); - } - - public static int getNumChildElementsByTag(Node parent, String tag) { - int num = 0; - Iterator it = childElementIterByTag(parent, tag); - while (it.hasNext()) { - it.next(); - num++; - } - return num; - } - - /** - * @param parent - * @param tag - * @return - */ - public static Element[] getChildElementsByTag(Node parent, String tag) { - List list = new ArrayList( - parent.getChildNodes().getLength()); - Iterator it = childElementIterByTag(parent, tag); - while (it.hasNext()) { - list.add(it.next()); - } - return list.toArray(new Element[list.size()]); - } - - public static Element[] getChildElements(Node parent) { - List list = new ArrayList( - parent.getChildNodes().getLength()); - Iterator it = childElementIter(parent); - while (it.hasNext()) { - list.add(it.next()); - } - return list.toArray(new Element[list.size()]); - } - - public static Element ensureChildElement(Node parent, String tagName) { - Element ele; - - if (parent.getNodeType() == Node.DOCUMENT_NODE) { - ele = ((Document) parent).getDocumentElement(); - } else { - ele = getFirstChildElementByTag(parent, tagName); - } - if (ele == null) { - ele = createElement(parent, tagName); - } - return ele; - } - - public static void createCentalTopicElement(Node parent, ITopic topic) { - if (topic == null) - createElement(parent, TAG_TOPIC); - else - createElement(parent, topic.getTitleText()); - } - - public static List getChildList(Element element, - String childTag, INodeAdaptableProvider finder) { - List list = getChildren(element, childTag, finder); - return list; - } - - public static Set getChildSet(Element element, - String childTag, INodeAdaptableProvider finder) { - List list = getChildren(element, childTag, finder); - return unmodifiableSet(list); - } - - public static Iterator getChildIterator( - Element element, String childTag, - final INodeAdaptableProvider finder, final Class childClass) { - final Iterator it = childElementIterByTag(element, childTag); - return new Iterator() { - - T next = findNext(); - - private T findNext() { - while (it.hasNext()) { - Element e = it.next(); - IAdaptable a = finder.getAdaptable(e); - if (a != null && childClass.isInstance(a)) { - return childClass.cast(a); - } - } - return null; - } - - public boolean hasNext() { - return next != null; - } - - public T next() { - T n = next; - next = findNext(); - return n; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - public static Iterator emptyIter() { - return new Iterator() { - - public boolean hasNext() { - return false; - } - - public T next() { - return null; - } - - public void remove() { - } - - }; - } - - @SuppressWarnings("unchecked") - public static List getChildren(Element element, - String childTag, INodeAdaptableProvider finder) { - ArrayList list = new ArrayList( - element.getChildNodes().getLength()); - Iterator it = childElementIterByTag(element, childTag); - while (it.hasNext()) { - Element child = it.next(); - IAdaptable a = finder.getAdaptable(child); - if (a != null) { - list.add((T) a); - } - } - return list; - } - - @SuppressWarnings("unchecked") - public static List getChildren(Node parent, - INodeAdaptableProvider finder) { - - NodeList childNodes = parent.getChildNodes(); - int num = childNodes.getLength(); - ArrayList list = new ArrayList(num); - for (int i = 0; i < num; i++) { - Node n = childNodes.item(i); - IAdaptable a = finder.getAdaptable(n); - if (a != null) { - list.add((T) a); - } - } - return list; - } - - public static Set unmodifiableSet(Collection c) { - return new DelegateSet(c); - } - - /** - * @param parent - * @param tag - * @return - */ - public static String getTextContentByTag(Node parent, String tag) { - Element ele = getFirstChildElementByTag(parent, tag); - if (ele == null) - return null; - Node firstChild = ele.getFirstChild(); - return firstChild == null ? null : firstChild.getTextContent(); - } - - /** - * @param titleNode - * @param textContent - */ - public static void setText(Node titleNode, String textContent) { - Node textNode = findTextNode(titleNode); - if (textNode != null) { - if (textContent == null) { - titleNode.removeChild(textNode); - } else { - textNode.setTextContent(textContent); - } - } else { - titleNode.setTextContent(textContent); - } - } - - public static Node findTextNode(Node node) { - NodeList children = node.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node c = children.item(i); - if (c.getNodeType() == Node.TEXT_NODE) - return c; - } - return null; - } - - /** - * @param parent - * @param tag - * @param text - */ - public static void setText(Node parent, String tag, String text) { - Element titleElement = getFirstChildElementByTag(parent, tag); - if (titleElement == null) { - if (text != null) - createText(parent, tag, text); - } else { - setText(titleElement, text); - if (!titleElement.hasChildNodes() - && !titleElement.hasAttributes()) { - parent.removeChild(titleElement); - } - } - } - - /** - * @param element - * @return - */ - public static Element addIdAttribute(Element element) { - if (!element.hasAttribute(ATTR_ID)) { - element.setAttribute(ATTR_ID, Core.getIdFactory().createId()); - element.setIdAttribute(ATTR_ID, true); - } - return element; - } - - public static String replaceId(Element element) { - String newId = Core.getIdFactory().createId(); - replaceId(element, newId); - return newId; - } - - public static Element replaceId(Element element, String newId) { - if (newId == null) - return element; - element.setAttribute(ATTR_ID, newId); - element.setIdAttribute(ATTR_ID, true); - return element; - } - - public static boolean isOrphanNode(Node node) { - if (node == null) - return true; - if (node.getNodeType() == Node.DOCUMENT_NODE) - return false; - return isOrphanNode(node.getParentNode()); - } - - public static Document getOwnerDocument(Node node) { - return node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node - : node.getOwnerDocument(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID; +import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IAdaptable; +import org.xmind.core.ITopic; +import org.xmind.core.internal.dom.INodeAdaptableProvider; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class DOMUtils { + + private static class ElementIterator implements Iterator { + + private String tagName; + + private Node child; +// private NodeList children; +// +// private int index; + + private Element next; + + public ElementIterator(Node parent) { + this(parent, null); + } + + public ElementIterator(Node parent, String tagName) { + this.tagName = tagName; + this.child = parent.getFirstChild(); +// this.children = parent.getChildNodes(); +// this.index = 0; + this.next = findNextElement(); + } + + private Element findNextElement() { + if (child == null) { + next = null; + } else { + while (child != null && !isElementByTag(child, tagName)) { + child = child.getNextSibling(); + } + if (child != null) { + next = (Element) child; + child = child.getNextSibling(); + } else { + next = null; + } + } +// for (int i = index; i < children.getLength(); i++) { +// Node n = children.item(i); +// if (isElementByTag(n, tagName)) { +// next = (Element) n; +// index = i + 1; +// return next; +// } +// } + return next; + } + + public boolean hasNext() { + return next != null; + } + + public Element next() { + Element result = next; + next = findNextElement(); + return result; + } + + public void remove() { + } + + } + + public static class AdaptableIterator + implements Iterator { + + private Node node; + + private String tagName; + + private INodeAdaptableProvider provider; + + private boolean reversed; + + private T next; + + public AdaptableIterator(Node parent, String tagName, + INodeAdaptableProvider provider, boolean reversed) { + this.tagName = tagName; + this.provider = provider; + this.reversed = reversed; + this.node = reversed ? parent.getLastChild() + : parent.getFirstChild(); + this.next = findNext(); + } + + @SuppressWarnings("unchecked") + private T findNext() { + while (node != null) { + IAdaptable obj; + if (isElementByTag(node, tagName)) { + obj = provider.getAdaptable(node); + } else { + obj = null; + } + node = reversed ? node.getPreviousSibling() + : node.getNextSibling(); + if (obj != null) + return (T) obj; + } + return null; + } + + public boolean hasNext() { + return next != null; + } + + public T next() { + T n = next; + next = findNext(); + return n; + } + + public void remove() { + } + + } + + private static class DelegateSet extends AbstractSet { + + private Collection c; + + public DelegateSet(Collection c) { + this.c = c; + } + + public Iterator iterator() { + return c.iterator(); + } + + public int size() { + return c.size(); + } + + } + + private static final ErrorHandler NULL_ERROR_HANDLER = new ErrorHandler() { + + public void warning(SAXParseException exception) throws SAXException { + } + + public void fatalError(SAXParseException exception) + throws SAXException { + } + + public void error(SAXParseException exception) throws SAXException { + } + + }; + +// private static Transformer transformer = null; +// private static DocumentBuilder documentBuilder = null; + + private DOMUtils() { + } + + public static Transformer getDefaultTransformer() throws CoreException { + try { + return TransformerFactory.newInstance().newTransformer(); + } catch (TransformerException e) { + throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, e); + } + } + + public static DocumentBuilder getDefaultDocumentBuilder() + throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + factory.setAttribute( + "http://apache.org/xml/features/continue-after-fatal-error", //$NON-NLS-1$ + true); + } catch (Exception e) { + // ignore + } + try { + factory.setFeature( + "http://apache.org/xml/features/disallow-doctype-decl", //$NON-NLS-1$ + true); + } catch (Exception e) { + // ignore + } + try { + factory.setFeature( + "http://xml.org/sax/features/external-parameter-entities", //$NON-NLS-1$ + false); + } catch (Exception e) { + // ignore + } + try { + factory.setFeature( + "http://xml.org/sax/features/external-general-entities", //$NON-NLS-1$ + false); + } catch (Exception e) { + // ignore + } + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + factory.setNamespaceAware(true); + factory.setIgnoringElementContentWhitespace(true); + DocumentBuilder documentBuilder = factory.newDocumentBuilder(); + documentBuilder.setErrorHandler(NULL_ERROR_HANDLER); + return documentBuilder; + } + + public static String toString(Node node) { + if (node == null) + return "null"; //$NON-NLS-1$ + StringBuilder sb = new StringBuilder(); + sb.append('['); + sb.append(node.getNodeName()); + NamedNodeMap attributes = node.getAttributes(); + if (attributes != null && attributes.getLength() > 0) { + for (int i = 0; i < attributes.getLength(); i++) { + sb.append(' '); + Node item = attributes.item(i); + sb.append(item.getNodeName()); + sb.append('='); + sb.append('"'); + sb.append(item.getNodeValue()); + sb.append('"'); + } + } + sb.append(']'); + return sb.toString(); + } + + public static Document doCreateDocument() + throws ParserConfigurationException { + return getDefaultDocumentBuilder().newDocument(); + } + + /** + * @return + */ + public static Document createDocument() { + try { + return getDefaultDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + return null; + } + } + + /** + * @param docTag + * =manifest + * @return + */ + public static Document createDocument(String docTag) { + Document ret = createDocument(); + createElement(ret, docTag); + return ret; + } + + /** + * @param is + * @return + * @throws IOException + */ + public static Document loadDocument(InputStream is) throws IOException { + if (is == null) + throw new IllegalArgumentException(); + try { + return getDefaultDocumentBuilder().parse(is); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + } + + public static Document loadDocument(byte[] bytes) throws IOException { + if (bytes == null) + throw new IllegalArgumentException(); + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + try { + return loadDocument(in); + } finally { + in.close(); + } + } + + public static void save(Node dom, OutputStream out, boolean closeOnFinish) + throws IOException, CoreException { + save(getDefaultTransformer(), dom, out, closeOnFinish); + } + + //manifest, zob, false + public static void save(IAdaptable adaptable, OutputStream out, + boolean closeOnFinish) throws IOException, CoreException { + save(getDefaultTransformer(), adaptable, out, closeOnFinish); + } + + public static void save(Transformer t, IAdaptable adaptable, + OutputStream out, boolean closeOnFinish) throws IOException { + Node dom = (Node) adaptable.getAdapter(Node.class); + + if (dom != null) { + save(t, dom, out, closeOnFinish); + } + } + + public static void save(Transformer t, Node dom, OutputStream out, + boolean closeOnFinish) throws IOException { + try { + t.transform(new DOMSource(dom), new StreamResult(out)); + } catch (TransformerException e) { + throw new IOException(e.getMessage()); + } finally { + if (closeOnFinish) { + out.close(); + } + } + } + + /** + * @param parent + * @param tag + * =manifest + * @return + */ + public static Element createElement(Node parent, String tag) { + Document doc = parent.getNodeType() == Node.DOCUMENT_NODE + ? (Document) parent : parent.getOwnerDocument(); + Element e = doc.createElement(tag); + parent.appendChild(e); + return e; + } + + public static String getPrefix(String qualifiedName) { + int index = qualifiedName.indexOf(':'); + if (index >= 0) + return qualifiedName.substring(0, index); + return null; + } + + public static String getLocalName(String qualifiedName) { + int index = qualifiedName.indexOf(':'); + if (index >= 0) + return qualifiedName.substring(index + 1); + return qualifiedName; + } + + public static String getQualifiedName(String prefix, String localName) { + return prefix + ":" + localName; //$NON-NLS-1$ + } + + /** + * @param parent + * @param tag + * @param text + * @return + */ + public static Element createText(Node parent, String tag, String text) { + Element e = createElement(parent, tag); + Node t = parent.getOwnerDocument().createTextNode(text); + e.appendChild(t); + return e; + } + + /** + * @param parent + * @param name + * @param value + * @return + */ + public static Attr createAttr(Element parent, String name, Object value) { + if (value == null) + return null; + Attr a = parent.getOwnerDocument().createAttribute(name); + a.setNodeValue(value.toString()); + parent.getAttributes().setNamedItem(a); + return a; + } + + /** + * @param element + * @param attrName + * @param value + */ + public static void setAttribute(Element element, String attrName, + Object value) { + if (value != null) { + element.setAttribute(attrName, value.toString()); + } else if (element.hasAttribute(attrName)) { + element.removeAttribute(attrName); + } + } + + public static String getAttribute(Element element, String attrName) { + if (!element.hasAttribute(attrName)) { + String localName = getLocalName(attrName); + if (!attrName.equals(localName)) + return getAttribute(element, localName); + return null; + } + return element.getAttribute(attrName); + } + + public static boolean isElementByTag(Node node, String tagName) { + if (!(node instanceof Element)) + return false; + if (tagName == null) + return true; + Element element = (Element) node; + String tag = element.getTagName(); + return tag.equals(tagName) + || getLocalName(tag).equals(getLocalName(tagName)); + } + + public static Iterator childElementIter(Node parent) { + return new ElementIterator(parent); + } + + public static Iterator childElementIterByTag(Node parent, + String tagName) { + return new ElementIterator(parent, tagName); + } + + public static boolean hasChildElement(Node parent) { + return childElementIter(parent).hasNext(); + } + + public static boolean hasChildElementByTag(Node parent, String tagName) { + return childElementIterByTag(parent, tagName).hasNext(); + } + + public static int getElementIndex(Node parent, String tagName, + Element child) { + Iterator it = childElementIterByTag(parent, tagName); + for (int i = 0; it.hasNext(); i++) { + if (it.next() == child) + return i; + } + return -1; + } + + public static int getNodeIndex(Node parent, Node child) { + NodeList children = parent.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (child == children.item(i)) + return i; + } + return -1; + } + + public static Element getFirstChildElement(Node parent) { + return childElementIter(parent).next(); + } + + public static Element getFirstChildElementByTag(Node parent, String tag) { + return childElementIterByTag(parent, tag).next(); + } + + public static int getNumChildElementsByTag(Node parent, String tag) { + int num = 0; + Iterator it = childElementIterByTag(parent, tag); + while (it.hasNext()) { + it.next(); + num++; + } + return num; + } + + /** + * @param parent + * @param tag + * @return + */ + public static Element[] getChildElementsByTag(Node parent, String tag) { + List list = new ArrayList( + parent.getChildNodes().getLength()); + Iterator it = childElementIterByTag(parent, tag); + while (it.hasNext()) { + list.add(it.next()); + } + return list.toArray(new Element[list.size()]); + } + + public static Element[] getChildElements(Node parent) { + List list = new ArrayList( + parent.getChildNodes().getLength()); + Iterator it = childElementIter(parent); + while (it.hasNext()) { + list.add(it.next()); + } + return list.toArray(new Element[list.size()]); + } + + public static Element ensureChildElement(Node parent, String tagName) { + Element ele; + + if (parent.getNodeType() == Node.DOCUMENT_NODE) { + ele = ((Document) parent).getDocumentElement(); + } else { + ele = getFirstChildElementByTag(parent, tagName); + } + if (ele == null) { + ele = createElement(parent, tagName); + } + return ele; + } + + public static void createCentalTopicElement(Node parent, ITopic topic) { + if (topic == null) + createElement(parent, TAG_TOPIC); + else + createElement(parent, topic.getTitleText()); + } + + public static List getChildList(Element element, + String childTag, INodeAdaptableProvider finder) { + List list = getChildren(element, childTag, finder); + return list; + } + + public static Set getChildSet(Element element, + String childTag, INodeAdaptableProvider finder) { + List list = getChildren(element, childTag, finder); + return unmodifiableSet(list); + } + + public static Iterator getChildIterator( + Element element, String childTag, + final INodeAdaptableProvider finder, final Class childClass) { + final Iterator it = childElementIterByTag(element, childTag); + return new Iterator() { + + T next = findNext(); + + private T findNext() { + while (it.hasNext()) { + Element e = it.next(); + IAdaptable a = finder.getAdaptable(e); + if (a != null && childClass.isInstance(a)) { + return childClass.cast(a); + } + } + return null; + } + + public boolean hasNext() { + return next != null; + } + + public T next() { + T n = next; + next = findNext(); + return n; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public static Iterator emptyIter() { + return new Iterator() { + + public boolean hasNext() { + return false; + } + + public T next() { + return null; + } + + public void remove() { + } + + }; + } + + @SuppressWarnings("unchecked") + public static List getChildren(Element element, + String childTag, INodeAdaptableProvider finder) { + ArrayList list = new ArrayList( + element.getChildNodes().getLength()); + Iterator it = childElementIterByTag(element, childTag); + while (it.hasNext()) { + Element child = it.next(); + IAdaptable a = finder.getAdaptable(child); + if (a != null) { + list.add((T) a); + } + } + return list; + } + + @SuppressWarnings("unchecked") + public static List getChildren(Node parent, + INodeAdaptableProvider finder) { + + NodeList childNodes = parent.getChildNodes(); + int num = childNodes.getLength(); + ArrayList list = new ArrayList(num); + for (int i = 0; i < num; i++) { + Node n = childNodes.item(i); + IAdaptable a = finder.getAdaptable(n); + if (a != null) { + list.add((T) a); + } + } + return list; + } + + public static Set unmodifiableSet(Collection c) { + return new DelegateSet(c); + } + + /** + * @param parent + * @param tag + * @return + */ + public static String getTextContentByTag(Node parent, String tag) { + Element ele = getFirstChildElementByTag(parent, tag); + if (ele == null) + return null; + Node firstChild = ele.getFirstChild(); + return firstChild == null ? null : firstChild.getTextContent(); + } + + /** + * @param titleNode + * @param textContent + */ + public static void setText(Node titleNode, String textContent) { + Node textNode = findTextNode(titleNode); + if (textNode != null) { + if (textContent == null) { + titleNode.removeChild(textNode); + } else { + textNode.setTextContent(textContent); + } + } else { + titleNode.setTextContent(textContent); + } + } + + public static Node findTextNode(Node node) { + NodeList children = node.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node c = children.item(i); + if (c.getNodeType() == Node.TEXT_NODE) + return c; + } + return null; + } + + /** + * @param parent + * @param tag + * @param text + */ + public static void setText(Node parent, String tag, String text) { + Element titleElement = getFirstChildElementByTag(parent, tag); + if (titleElement == null) { + if (text != null) + createText(parent, tag, text); + } else { + setText(titleElement, text); + if (!titleElement.hasChildNodes() + && !titleElement.hasAttributes()) { + parent.removeChild(titleElement); + } + } + } + + /** + * @param element + * @return + */ + public static Element addIdAttribute(Element element) { + if (!element.hasAttribute(ATTR_ID)) { + element.setAttribute(ATTR_ID, Core.getIdFactory().createId()); + element.setIdAttribute(ATTR_ID, true); + } + return element; + } + + public static String replaceId(Element element) { + String newId = Core.getIdFactory().createId(); + replaceId(element, newId); + return newId; + } + + public static Element replaceId(Element element, String newId) { + if (newId == null) + return element; + element.setAttribute(ATTR_ID, newId); + element.setIdAttribute(ATTR_ID, true); + return element; + } + + public static boolean isOrphanNode(Node node) { + if (node == null) + return true; + if (node.getNodeType() == Node.DOCUMENT_NODE) + return false; + return isOrphanNode(node.getParentNode()); + } + + public static Document getOwnerDocument(Node node) { + return node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node + : node.getOwnerDocument(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/FileUtils.java b/bundles/org.xmind.core/src/org/xmind/core/util/FileUtils.java index 54bd5f7ad..f9bd7f0dd 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/FileUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/FileUtils.java @@ -1,348 +1,348 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.xmind.core.CoreException; -import org.xmind.core.IFileEntryFilter; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.io.IStorage; - -/** - * @author briansun - * - */ -public class FileUtils { - - /** - * @param f - * @return - */ - public static File ensureFileParent(File f) { - ensureDirectory(f.getParentFile()); - return f; - } - - /** - * @param dir - * @return - */ - public static File ensureDirectory(File dir) { - if (!dir.exists()) - dir.mkdirs(); - return dir; - } - - public static void copy(String src, String dest) throws IOException { - FileInputStream is = new FileInputStream(src); - FileOutputStream os = new FileOutputStream(dest); - transfer(is, os, true); - } - - public static void copy(File src, File dest) throws IOException { - FileInputStream is = new FileInputStream(src); - FileOutputStream os = new FileOutputStream(dest); - transfer(is, os, true); - } - - public static void transfer(IStorage oldStorage, IStorage newStorage) - throws IOException, CoreException { - transfer(oldStorage, newStorage, null); - } - - public static void transfer(IStorage oldStorage, IStorage newStorage, - IFileEntryFilter filter) throws IOException, CoreException { - IInputSource inSource = oldStorage.getInputSource(); - IOutputTarget outTarget = newStorage.getOutputTarget(); - transfer(inSource, outTarget, filter); - } - - public static void transfer(IInputSource inputSource, - IOutputTarget outputTarget) throws IOException { - transfer(inputSource, outputTarget, null); - } - - public static void transfer(IInputSource inputSource, - IOutputTarget outputTarget, IFileEntryFilter filter) - throws IOException { - Iterator entries = inputSource.getEntries(); - while (entries.hasNext()) { - String entryPath = entries.next(); - if ((filter == null || filter.select(entryPath, null, false))) { - if (inputSource.hasEntry(entryPath) - && inputSource.isEntryAvailable(entryPath)) { - InputStream is = inputSource.openEntryStream(entryPath); - try { - OutputStream os = outputTarget - .openEntryStream(entryPath); - try { - transfer(is, os); - } finally { - os.close(); - } - } finally { - is.close(); - } - } - } - } - } - - public static void transfer(IInputSource source, String sourcePath, - IOutputTarget target, String targetPath) throws IOException { - InputStream input = source.openEntryStream(sourcePath); - try { - OutputStream output = target.openEntryStream(targetPath); - try { - transfer(input, output, false); - } finally { - output.close(); - } - } finally { - input.close(); - } - } - - public static void transfer(InputStream is, OutputStream os) - throws IOException { - transfer(is, os, true, null); - } - - public static void transfer(InputStream is, OutputStream os, - boolean closeOnFinish) throws IOException { - transfer(is, os, closeOnFinish, null); - } - - public static void transfer(InputStream is, OutputStream os, - boolean closeOnFinish, String taskName) throws IOException { - try { - byte[] buffer = new byte[4096]; - int numRead; - while ((numRead = is.read(buffer)) != -1) { - os.write(buffer, 0, numRead); - } - } finally { - if (closeOnFinish) { - try { - is.close(); - } finally { - os.close(); - } - } - } - } - - public static void transfer(File source, File target) throws IOException { - ensureFileParent(target); - InputStream in = new FileInputStream(source); - try { - OutputStream out = new FileOutputStream(target); - try { - transfer(in, out, false); - } finally { - out.close(); - } - } finally { - in.close(); - } - } - - /** - * Deletes the given file and, if it is a directory, delete all its - * sub-directories and sub-files. - * - * @param f - * The file or directory to delete - * @return Whether the given file or directory is successfully deleted. - */ - public static boolean delete(File f) { - if (f.isFile()) - return f.delete(); - else if (f.isDirectory()) { - boolean b = clearDir(f); - b &= f.delete(); - return b; - } else - return false; - } - - /** - * Deletes all sub-files and sub-directories in the given directory. - * - * @param dir - * The directory to clear - * @return Whether the given directory is successfully cleared. - */ - public static boolean clearDir(File dir) { - if (!dir.isDirectory()) - return false; - File[] files = dir.listFiles(); - if (files == null || files.length == 0) - return true; - boolean cleared = true; - for (File sub : files) { - cleared &= delete(sub); - } - return cleared; - } - - /** - * Determines corresponding media type of the given path. - * - * @param path - * @return - */ - public static String getMediaType(String path) { - if (path != null) { - String ext = getExtension(path); - if (".jpg".equals(ext) || ".jpeg".equals(ext)) //$NON-NLS-1$ //$NON-NLS-2$ - return "image/jpeg"; //$NON-NLS-1$ - if (".png".equals(ext)) //$NON-NLS-1$ - return "image/png"; //$NON-NLS-1$ - if (".bmp".equals(ext)) //$NON-NLS-1$ - return "image/bmp"; //$NON-NLS-1$ - if (".gif".equals(ext)) //$NON-NLS-1$ - return "image/gif"; //$NON-NLS-1$ - } - return ""; //$NON-NLS-1$ - } - - private static Pattern FileNamePattern = null; - - public static String getFileName(String fullPath) { - if (FileNamePattern == null) - FileNamePattern = Pattern.compile("([^/\\\\]*)[/|\\\\]?$"); //$NON-NLS-1$ - Matcher m = FileNamePattern.matcher(fullPath); - if (m.find()) - return m.group(1); - return fullPath; - } - - /** - * Returns the extension part of a file path, e.g., .jpg, - * .html. If the file does not have an extension, an empty - * string is returned. - * - * @param fullPath - * @return - */ - public static String getExtension(String fullPath) { - String fileName = getFileName(fullPath); - int i = fileName.lastIndexOf('.'); - if (i >= 0) - return fileName.substring(i); - return ""; //$NON-NLS-1$ - } - - public static String getNoExtensionFileName(String fullPath) { - String fileName = getFileName(fullPath); - int i = fileName.lastIndexOf('.'); - if (i >= 0) - return fileName.substring(0, i); - return fileName; - } - - public static void extractZipFile(String filename, IOutputTarget target) - throws IOException { - extractZipFile(filename, target, null); - } - - public static void extractZipFile(String filename, IOutputTarget target, - IFileEntryFilter filter) throws IOException { - FileInputStream fin = new FileInputStream(filename); - try { - ZipInputStream zin = new ZipInputStream( - new BufferedInputStream(fin)); - try { - extractZipFile(zin, target, filter); - } finally { - zin.close(); - } - } finally { - fin.close(); - } - } - - public static void extractZipFile(File file, IOutputTarget target) - throws IOException { - extractZipFile(file, target, null); - } - - public static void extractZipFile(File file, IOutputTarget target, - IFileEntryFilter filter) throws IOException { - FileInputStream fin = new FileInputStream(file); - try { - ZipInputStream zin = new ZipInputStream( - new BufferedInputStream(fin)); - try { - extractZipFile(zin, target, filter); - } finally { - zin.close(); - } - } finally { - fin.close(); - } - } - - public static void extractZipFile(ZipInputStream zin, IOutputTarget target) - throws IOException { - extractZipFile(zin, target, null); - } - - public static void extractZipFile(ZipInputStream zin, IOutputTarget target, - IFileEntryFilter filter) throws IOException { - ZipEntry entry; - while ((entry = zin.getNextEntry()) != null) { - String entryPath = entry.getName(); - if (!entry.isDirectory() && (filter == null - || filter.select(entryPath, null, false))) { - if (target.isEntryAvaialble(entryPath)) { - OutputStream out = target.openEntryStream(entryPath); - try { - FileUtils.transfer(zin, out, false); - } finally { - try { - out.close(); - } catch (IOException ignore) { - } - } - } - } - } - } - - public static void extractZipStream(InputStream stream, - IOutputTarget target) throws IOException { - extractZipStream(stream, target, null); - } - - public static void extractZipStream(InputStream stream, - IOutputTarget target, IFileEntryFilter filter) throws IOException { - extractZipFile(new ZipInputStream(stream), target, filter); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.xmind.core.CoreException; +import org.xmind.core.IFileEntryFilter; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.io.IStorage; + +/** + * @author briansun + * + */ +public class FileUtils { + + /** + * @param f + * @return + */ + public static File ensureFileParent(File f) { + ensureDirectory(f.getParentFile()); + return f; + } + + /** + * @param dir + * @return + */ + public static File ensureDirectory(File dir) { + if (!dir.exists()) + dir.mkdirs(); + return dir; + } + + public static void copy(String src, String dest) throws IOException { + FileInputStream is = new FileInputStream(src); + FileOutputStream os = new FileOutputStream(dest); + transfer(is, os, true); + } + + public static void copy(File src, File dest) throws IOException { + FileInputStream is = new FileInputStream(src); + FileOutputStream os = new FileOutputStream(dest); + transfer(is, os, true); + } + + public static void transfer(IStorage oldStorage, IStorage newStorage) + throws IOException, CoreException { + transfer(oldStorage, newStorage, null); + } + + public static void transfer(IStorage oldStorage, IStorage newStorage, + IFileEntryFilter filter) throws IOException, CoreException { + IInputSource inSource = oldStorage.getInputSource(); + IOutputTarget outTarget = newStorage.getOutputTarget(); + transfer(inSource, outTarget, filter); + } + + public static void transfer(IInputSource inputSource, + IOutputTarget outputTarget) throws IOException { + transfer(inputSource, outputTarget, null); + } + + public static void transfer(IInputSource inputSource, + IOutputTarget outputTarget, IFileEntryFilter filter) + throws IOException { + Iterator entries = inputSource.getEntries(); + while (entries.hasNext()) { + String entryPath = entries.next(); + if ((filter == null || filter.select(entryPath, null, false))) { + if (inputSource.hasEntry(entryPath) + && inputSource.isEntryAvailable(entryPath)) { + InputStream is = inputSource.openEntryStream(entryPath); + try { + OutputStream os = outputTarget + .openEntryStream(entryPath); + try { + transfer(is, os); + } finally { + os.close(); + } + } finally { + is.close(); + } + } + } + } + } + + public static void transfer(IInputSource source, String sourcePath, + IOutputTarget target, String targetPath) throws IOException { + InputStream input = source.openEntryStream(sourcePath); + try { + OutputStream output = target.openEntryStream(targetPath); + try { + transfer(input, output, false); + } finally { + output.close(); + } + } finally { + input.close(); + } + } + + public static void transfer(InputStream is, OutputStream os) + throws IOException { + transfer(is, os, true, null); + } + + public static void transfer(InputStream is, OutputStream os, + boolean closeOnFinish) throws IOException { + transfer(is, os, closeOnFinish, null); + } + + public static void transfer(InputStream is, OutputStream os, + boolean closeOnFinish, String taskName) throws IOException { + try { + byte[] buffer = new byte[4096]; + int numRead; + while ((numRead = is.read(buffer)) != -1) { + os.write(buffer, 0, numRead); + } + } finally { + if (closeOnFinish) { + try { + is.close(); + } finally { + os.close(); + } + } + } + } + + public static void transfer(File source, File target) throws IOException { + ensureFileParent(target); + InputStream in = new FileInputStream(source); + try { + OutputStream out = new FileOutputStream(target); + try { + transfer(in, out, false); + } finally { + out.close(); + } + } finally { + in.close(); + } + } + + /** + * Deletes the given file and, if it is a directory, delete all its + * sub-directories and sub-files. + * + * @param f + * The file or directory to delete + * @return Whether the given file or directory is successfully deleted. + */ + public static boolean delete(File f) { + if (f.isFile()) + return f.delete(); + else if (f.isDirectory()) { + boolean b = clearDir(f); + b &= f.delete(); + return b; + } else + return false; + } + + /** + * Deletes all sub-files and sub-directories in the given directory. + * + * @param dir + * The directory to clear + * @return Whether the given directory is successfully cleared. + */ + public static boolean clearDir(File dir) { + if (!dir.isDirectory()) + return false; + File[] files = dir.listFiles(); + if (files == null || files.length == 0) + return true; + boolean cleared = true; + for (File sub : files) { + cleared &= delete(sub); + } + return cleared; + } + + /** + * Determines corresponding media type of the given path. + * + * @param path + * @return + */ + public static String getMediaType(String path) { + if (path != null) { + String ext = getExtension(path); + if (".jpg".equals(ext) || ".jpeg".equals(ext)) //$NON-NLS-1$ //$NON-NLS-2$ + return "image/jpeg"; //$NON-NLS-1$ + if (".png".equals(ext)) //$NON-NLS-1$ + return "image/png"; //$NON-NLS-1$ + if (".bmp".equals(ext)) //$NON-NLS-1$ + return "image/bmp"; //$NON-NLS-1$ + if (".gif".equals(ext)) //$NON-NLS-1$ + return "image/gif"; //$NON-NLS-1$ + } + return ""; //$NON-NLS-1$ + } + + private static Pattern FileNamePattern = null; + + public static String getFileName(String fullPath) { + if (FileNamePattern == null) + FileNamePattern = Pattern.compile("([^/\\\\]*)[/|\\\\]?$"); //$NON-NLS-1$ + Matcher m = FileNamePattern.matcher(fullPath); + if (m.find()) + return m.group(1); + return fullPath; + } + + /** + * Returns the extension part of a file path, e.g., .jpg, + * .html. If the file does not have an extension, an empty + * string is returned. + * + * @param fullPath + * @return + */ + public static String getExtension(String fullPath) { + String fileName = getFileName(fullPath); + int i = fileName.lastIndexOf('.'); + if (i >= 0) + return fileName.substring(i); + return ""; //$NON-NLS-1$ + } + + public static String getNoExtensionFileName(String fullPath) { + String fileName = getFileName(fullPath); + int i = fileName.lastIndexOf('.'); + if (i >= 0) + return fileName.substring(0, i); + return fileName; + } + + public static void extractZipFile(String filename, IOutputTarget target) + throws IOException { + extractZipFile(filename, target, null); + } + + public static void extractZipFile(String filename, IOutputTarget target, + IFileEntryFilter filter) throws IOException { + FileInputStream fin = new FileInputStream(filename); + try { + ZipInputStream zin = new ZipInputStream( + new BufferedInputStream(fin)); + try { + extractZipFile(zin, target, filter); + } finally { + zin.close(); + } + } finally { + fin.close(); + } + } + + public static void extractZipFile(File file, IOutputTarget target) + throws IOException { + extractZipFile(file, target, null); + } + + public static void extractZipFile(File file, IOutputTarget target, + IFileEntryFilter filter) throws IOException { + FileInputStream fin = new FileInputStream(file); + try { + ZipInputStream zin = new ZipInputStream( + new BufferedInputStream(fin)); + try { + extractZipFile(zin, target, filter); + } finally { + zin.close(); + } + } finally { + fin.close(); + } + } + + public static void extractZipFile(ZipInputStream zin, IOutputTarget target) + throws IOException { + extractZipFile(zin, target, null); + } + + public static void extractZipFile(ZipInputStream zin, IOutputTarget target, + IFileEntryFilter filter) throws IOException { + ZipEntry entry; + while ((entry = zin.getNextEntry()) != null) { + String entryPath = entry.getName(); + if (!entry.isDirectory() && (filter == null + || filter.select(entryPath, null, false))) { + if (target.isEntryAvaialble(entryPath)) { + OutputStream out = target.openEntryStream(entryPath); + try { + FileUtils.transfer(zin, out, false); + } finally { + try { + out.close(); + } catch (IOException ignore) { + } + } + } + } + } + } + + public static void extractZipStream(InputStream stream, + IOutputTarget target) throws IOException { + extractZipStream(stream, target, null); + } + + public static void extractZipStream(InputStream stream, + IOutputTarget target, IFileEntryFilter filter) throws IOException { + extractZipFile(new ZipInputStream(stream), target, filter); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/HyperlinkUtils.java b/bundles/org.xmind.core/src/org/xmind/core/util/HyperlinkUtils.java index 336d91c06..098c843f9 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/HyperlinkUtils.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/HyperlinkUtils.java @@ -1,188 +1,188 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.xmind.core.IIdentifiable; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; - -public class HyperlinkUtils { - - private HyperlinkUtils() { - } - - public static String getProtocolName(String uri) { - int i = uri.indexOf(':'); - return i < 0 ? null : uri.substring(0, i); - } - - public static String trimURLContent(String uri) { - int i = uri.indexOf(':'); - if (i >= 0) { - uri = uri.substring(i + 1); - while (uri.startsWith("/")) { //$NON-NLS-1$ - uri = uri.substring(1); - } - } - return uri; - } - - public static String trimFileUrlContent(String uri) { - if (uri.startsWith("file://")) //$NON-NLS-1$ - return uri.substring("file://".length()); //$NON-NLS-1$ - return uri; - } - - public static String getAttachmentProtocolName() { - return "xap"; //$NON-NLS-1$ - } - - public static String getFileProtocolName() { - return "file"; //$NON-NLS-1$ - } - - public static boolean isFileUrl(String url) { - if (url == null || "".equals(url)) //$NON-NLS-1$ - return false; - return getFileProtocolName().equals(getProtocolName(url)); - } - - public static boolean isAttachmentURL(String url) { - if (url == null || "".equals(url)) //$NON-NLS-1$ - return false; - String protocol = getProtocolName(url); - return getAttachmentProtocolName().equals(protocol); - } - - public static String toAttachmentURL(String path) { - return getAttachmentProtocolName() + ":" + path; //$NON-NLS-1$ - } - - public static String toAttachmentPath(String url) { - return trimURLContent(url); - } - - public static boolean isInternalAttachmentURL(String url) { - if (url == null || "".equals(url)) //$NON-NLS-1$ - return false; - return url.startsWith("platform:/plugin"); //$NON-NLS-1$ - } - - public static String getInternalProtocolName() { - return "xmind"; //$NON-NLS-1$ - } - - public static boolean isInternalURL(String url) { - if (url == null || "".equals(url)) //$NON-NLS-1$ - return false; - return getInternalProtocolName().equals(getProtocolName(url)); - } - - public static String toInternalURL(String elementId) { - return getInternalProtocolName() + ":#" + elementId; //$NON-NLS-1$ - } - - public static String toInternalURL(Object element) { - return toInternalURL(element, null); - } - - public static String toInternalURL(Object element, IWorkbook workbook) { - if (element instanceof IIdentifiable) { - String id = ((IIdentifiable) element).getId(); - //String mainPath = getMainPath(element, workbook); - return getInternalProtocolName() + ":#" + id; //$NON-NLS-1$ - } - return null; - } - - public static String toElementID(String uri) { - if (isInternalURL(uri)) { - int index = uri.indexOf("#"); //$NON-NLS-1$ - if (index >= 0) { - return uri.substring(index + 1); - } - } - return null; - } - -// /** -// * @param element -// * @param workbook -// * @return -// */ -// private static String getMainPath(Object element, IWorkbook workbook) { -// if (workbook != null) { -// String file = workbook.getFile(); -// if (file != null) { -// return file; -// } -// } -// return ""; //$NON-NLS-1$ -// } - - public static Object findElement(String uri, IWorkbook workbook) { - String id = toElementID(uri); - if (id != null) { - Object element = workbook.getElementById(id); - if (element instanceof ITopic) { - if (!isAttach((ITopic) element)) { - element = null; - } - } - return element; - } - return null; - } - - private static boolean isAttach(ITopic topic) { - return topic.getPath().getWorkbook() == topic.getOwnedWorkbook(); - } - - @SuppressWarnings("nls") - public static boolean isLinkToWeb(String urlOrBookmark) { - if (urlOrBookmark.contains("www.") || urlOrBookmark.contains(".com") - || urlOrBookmark.contains(".cn") - || urlOrBookmark.contains(".org") - || urlOrBookmark.contains(".cc") - || urlOrBookmark.contains(".net")) { - return true; - } - return false; - } - - @SuppressWarnings("nls") - public static boolean isUrlAddress(String text) { - final String URL_REGEX = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; - Pattern pattern = Pattern.compile(URL_REGEX); - Matcher matcher; - if (!text.contains("http://") && !text.contains("https://") - && !text.contains("file://")) { - matcher = pattern.matcher("http://" + text); - } else { - matcher = pattern.matcher(text); - } - return matcher.matches() && isLinkToWeb(text); - } - - public static boolean isEmailAddress(String text) { - final String EMAIL_REGEX = "^([\\w_\\-\\.]+)@((\\[[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.)|(([\\w\\-]+\\.)+))([a-zA-Z]{2,4}|[\\d]{1,3})(\\]?)$"; //$NON-NLS-1$ - Pattern pattern = Pattern.compile(EMAIL_REGEX); - Matcher matcher = pattern.matcher(text); - return matcher.matches(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.xmind.core.IIdentifiable; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; + +public class HyperlinkUtils { + + private HyperlinkUtils() { + } + + public static String getProtocolName(String uri) { + int i = uri.indexOf(':'); + return i < 0 ? null : uri.substring(0, i); + } + + public static String trimURLContent(String uri) { + int i = uri.indexOf(':'); + if (i >= 0) { + uri = uri.substring(i + 1); + while (uri.startsWith("/")) { //$NON-NLS-1$ + uri = uri.substring(1); + } + } + return uri; + } + + public static String trimFileUrlContent(String uri) { + if (uri.startsWith("file://")) //$NON-NLS-1$ + return uri.substring("file://".length()); //$NON-NLS-1$ + return uri; + } + + public static String getAttachmentProtocolName() { + return "xap"; //$NON-NLS-1$ + } + + public static String getFileProtocolName() { + return "file"; //$NON-NLS-1$ + } + + public static boolean isFileUrl(String url) { + if (url == null || "".equals(url)) //$NON-NLS-1$ + return false; + return getFileProtocolName().equals(getProtocolName(url)); + } + + public static boolean isAttachmentURL(String url) { + if (url == null || "".equals(url)) //$NON-NLS-1$ + return false; + String protocol = getProtocolName(url); + return getAttachmentProtocolName().equals(protocol); + } + + public static String toAttachmentURL(String path) { + return getAttachmentProtocolName() + ":" + path; //$NON-NLS-1$ + } + + public static String toAttachmentPath(String url) { + return trimURLContent(url); + } + + public static boolean isInternalAttachmentURL(String url) { + if (url == null || "".equals(url)) //$NON-NLS-1$ + return false; + return url.startsWith("platform:/plugin"); //$NON-NLS-1$ + } + + public static String getInternalProtocolName() { + return "xmind"; //$NON-NLS-1$ + } + + public static boolean isInternalURL(String url) { + if (url == null || "".equals(url)) //$NON-NLS-1$ + return false; + return getInternalProtocolName().equals(getProtocolName(url)); + } + + public static String toInternalURL(String elementId) { + return getInternalProtocolName() + ":#" + elementId; //$NON-NLS-1$ + } + + public static String toInternalURL(Object element) { + return toInternalURL(element, null); + } + + public static String toInternalURL(Object element, IWorkbook workbook) { + if (element instanceof IIdentifiable) { + String id = ((IIdentifiable) element).getId(); + //String mainPath = getMainPath(element, workbook); + return getInternalProtocolName() + ":#" + id; //$NON-NLS-1$ + } + return null; + } + + public static String toElementID(String uri) { + if (isInternalURL(uri)) { + int index = uri.indexOf("#"); //$NON-NLS-1$ + if (index >= 0) { + return uri.substring(index + 1); + } + } + return null; + } + +// /** +// * @param element +// * @param workbook +// * @return +// */ +// private static String getMainPath(Object element, IWorkbook workbook) { +// if (workbook != null) { +// String file = workbook.getFile(); +// if (file != null) { +// return file; +// } +// } +// return ""; //$NON-NLS-1$ +// } + + public static Object findElement(String uri, IWorkbook workbook) { + String id = toElementID(uri); + if (id != null) { + Object element = workbook.getElementById(id); + if (element instanceof ITopic) { + if (!isAttach((ITopic) element)) { + element = null; + } + } + return element; + } + return null; + } + + private static boolean isAttach(ITopic topic) { + return topic.getPath().getWorkbook() == topic.getOwnedWorkbook(); + } + + @SuppressWarnings("nls") + public static boolean isLinkToWeb(String urlOrBookmark) { + if (urlOrBookmark.contains("www.") || urlOrBookmark.contains(".com") + || urlOrBookmark.contains(".cn") + || urlOrBookmark.contains(".org") + || urlOrBookmark.contains(".cc") + || urlOrBookmark.contains(".net")) { + return true; + } + return false; + } + + @SuppressWarnings("nls") + public static boolean isUrlAddress(String text) { + final String URL_REGEX = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; + Pattern pattern = Pattern.compile(URL_REGEX); + Matcher matcher; + if (!text.contains("http://") && !text.contains("https://") + && !text.contains("file://")) { + matcher = pattern.matcher("http://" + text); + } else { + matcher = pattern.matcher(text); + } + return matcher.matches() && isLinkToWeb(text); + } + + public static boolean isEmailAddress(String text) { + final String EMAIL_REGEX = "^([\\w_\\-\\.]+)@((\\[[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.)|(([\\w\\-]+\\.)+))([a-zA-Z]{2,4}|[\\d]{1,3})(\\]?)$"; //$NON-NLS-1$ + Pattern pattern = Pattern.compile(EMAIL_REGEX); + Matcher matcher = pattern.matcher(text); + return matcher.matches(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/ILabelRefCounter.java b/bundles/org.xmind.core/src/org/xmind/core/util/ILabelRefCounter.java index 38c7c5a6d..6c00ff2f4 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/ILabelRefCounter.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/ILabelRefCounter.java @@ -1,18 +1,18 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -public interface ILabelRefCounter extends IRefCounter { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +public interface ILabelRefCounter extends IRefCounter { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/IProgressReporter.java b/bundles/org.xmind.core/src/org/xmind/core/util/IProgressReporter.java index 61b48e5c1..ffda0b590 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/IProgressReporter.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/IProgressReporter.java @@ -1,29 +1,29 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.util; - -/** - * @author Frank Shaka - * - */ -public interface IProgressReporter { - - void progressChanged(int current, int total); - - boolean isCanceled(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.util; + +/** + * @author Frank Shaka + * + */ +public interface IProgressReporter { + + void progressChanged(int current, int total); + + boolean isCanceled(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/IPropertiesProvider.java b/bundles/org.xmind.core/src/org/xmind/core/util/IPropertiesProvider.java index cfcb99ab3..9dcf3202e 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/IPropertiesProvider.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/IPropertiesProvider.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -import java.util.Properties; - -public interface IPropertiesProvider { - - Properties getProperties(); - - void setProperties(Properties properties); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +import java.util.Properties; + +public interface IPropertiesProvider { + + Properties getProperties(); + + void setProperties(Properties properties); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/IRefCounter.java b/bundles/org.xmind.core/src/org/xmind/core/util/IRefCounter.java index c1c97ccc3..86a67f7c7 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/IRefCounter.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/IRefCounter.java @@ -1,54 +1,54 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -import java.util.Collection; - -public interface IRefCounter { - - /** - * - * @param resourceId - */ - void increaseRef(String resourceId); - - /** - * - * @param resourceId - */ - void decreaseRef(String resourceId); - - /** - * - * @param resourceId - * @return - */ - int getRefCount(String resourceId); - - /** - * Returns all references ever increased by this counter (some of which may - * possibly have no counts). - * - * @return - */ - Collection getRefs(); - - /** - * Returns all references each of which has at least one count. - * - * @return - */ - Collection getCountedRefs(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +import java.util.Collection; + +public interface IRefCounter { + + /** + * + * @param resourceId + */ + void increaseRef(String resourceId); + + /** + * + * @param resourceId + */ + void decreaseRef(String resourceId); + + /** + * + * @param resourceId + * @return + */ + int getRefCount(String resourceId); + + /** + * Returns all references ever increased by this counter (some of which may + * possibly have no counts). + * + * @return + */ + Collection getRefs(); + + /** + * Returns all references each of which has at least one count. + * + * @return + */ + Collection getCountedRefs(); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/IStyleRefCounter.java b/bundles/org.xmind.core/src/org/xmind/core/util/IStyleRefCounter.java index eab55aad8..c85133de0 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/IStyleRefCounter.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/IStyleRefCounter.java @@ -1,18 +1,18 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.core.util; - -public interface IStyleRefCounter extends IRefCounter { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.core.util; + +public interface IStyleRefCounter extends IRefCounter { + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/util/TopicIterator.java b/bundles/org.xmind.core/src/org/xmind/core/util/TopicIterator.java index 402371ebf..ae6970d37 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/util/TopicIterator.java +++ b/bundles/org.xmind.core/src/org/xmind/core/util/TopicIterator.java @@ -1,136 +1,136 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.core.util; - -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.Stack; - -import org.xmind.core.ITopic; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class TopicIterator implements Iterator { - - private static class TopicWrapper { - - public final ITopic topic; - - /** - * - */ - public TopicWrapper(ITopic topic) { - this.topic = topic; - } - } - - public static final int NONE = 0; - public static final int REVERSED = 1 << 0; - - private int options; - - private ITopic next; - - private Stack stack; - - public TopicIterator(ITopic root) { - this(root, NONE); - } - - /** - * - */ - public TopicIterator(ITopic root, int options) { - this.options = options; - this.stack = new Stack(); - this.stack.push(root); - this.next = findNext(); - } - - private static void pushFIFO(Stack stack, List topics) { - ListIterator it = topics.listIterator(topics.size()); - while (it.hasPrevious()) { - stack.push(it.previous()); - } - } - - private static void pushLIFOStack(Stack stack, - List topics) { - for (ITopic topic : topics) { - stack.push(topic); - } - } - - private ITopic findNext() { - if (stack.isEmpty()) - return null; - - Object o = stack.pop(); - if (hasOption(REVERSED)) { - if (o instanceof TopicWrapper) - return ((TopicWrapper) o).topic; - ITopic t = (ITopic) o; - stack.push(new TopicWrapper(t)); - pushLIFOStack(stack, t.getAllChildren()); - return findNext(); - } else { - ITopic t = (ITopic) o; - pushFIFO(stack, t.getAllChildren()); - return t; - } - } - - private boolean hasOption(int option) { - return (options & option) != 0; - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#hasNext() - */ - public boolean hasNext() { - return next != null; - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#next() - */ - public ITopic next() { - ITopic t = next; - if (t == null) - throw new NoSuchElementException(); - next = findNext(); - return t; - } - - /* - * (non-Javadoc) - * - * @see java.util.Iterator#remove() - */ - public void remove() { - /// ignore remove operations - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.core.util; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.Stack; + +import org.xmind.core.ITopic; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class TopicIterator implements Iterator { + + private static class TopicWrapper { + + public final ITopic topic; + + /** + * + */ + public TopicWrapper(ITopic topic) { + this.topic = topic; + } + } + + public static final int NONE = 0; + public static final int REVERSED = 1 << 0; + + private int options; + + private ITopic next; + + private Stack stack; + + public TopicIterator(ITopic root) { + this(root, NONE); + } + + /** + * + */ + public TopicIterator(ITopic root, int options) { + this.options = options; + this.stack = new Stack(); + this.stack.push(root); + this.next = findNext(); + } + + private static void pushFIFO(Stack stack, List topics) { + ListIterator it = topics.listIterator(topics.size()); + while (it.hasPrevious()) { + stack.push(it.previous()); + } + } + + private static void pushLIFOStack(Stack stack, + List topics) { + for (ITopic topic : topics) { + stack.push(topic); + } + } + + private ITopic findNext() { + if (stack.isEmpty()) + return null; + + Object o = stack.pop(); + if (hasOption(REVERSED)) { + if (o instanceof TopicWrapper) + return ((TopicWrapper) o).topic; + ITopic t = (ITopic) o; + stack.push(new TopicWrapper(t)); + pushLIFOStack(stack, t.getAllChildren()); + return findNext(); + } else { + ITopic t = (ITopic) o; + pushFIFO(stack, t.getAllChildren()); + return t; + } + } + + private boolean hasOption(int option) { + return (options & option) != 0; + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return next != null; + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#next() + */ + public ITopic next() { + ITopic t = next; + if (t == null) + throw new NoSuchElementException(); + next = findNext(); + return t; + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#remove() + */ + public void remove() { + /// ignore remove operations + } + +} diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.classpath b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.classpath index 8a8f1668c..ad32c83a7 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.classpath +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.gitignore b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.gitignore +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.project b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.project index a88a6c472..831ed6b60 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.project +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.project @@ -1,28 +1,28 @@ - - - org.xmind.de.erichseifert.vectorgraphics2d - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.de.erichseifert.vectorgraphics2d + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.core.prefs index d1e7a3352..a5181ab09 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.core.prefs @@ -1,108 +1,108 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=ignore -org.eclipse.jdt.core.compiler.problem.deadCode=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=ignore -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=ignore -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=ignore -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=ignore +org.eclipse.jdt.core.compiler.problem.deadCode=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=ignore +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=ignore +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=ignore +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.pde.prefs index 7a0277731..0387c6e30 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=2 -compilers.p.discouraged-class=2 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=2 +compilers.p.discouraged-class=2 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF index 97084e0bf..a64c1dd8c 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.de.erichseifert.vectorgraphics2d;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-Vendor: %providerName -Export-Package: org.xmind.de.erichseifert.vectorgraphics2d, - org.xmind.de.erichseifert.vectorgraphics2d.util -Bundle-ActivationPolicy: lazy +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.de.erichseifert.vectorgraphics2d;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Vendor: %providerName +Export-Package: org.xmind.de.erichseifert.vectorgraphics2d, + org.xmind.de.erichseifert.vectorgraphics2d.util +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/OSGI-INF/l10n/bundle.properties index 1bb837939..2a683fddf 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/OSGI-INF/l10n/bundle.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.de.erichseifert.vectorgraphics2d -providerName = XMind Ltd. -pluginName = Vector Graphics 2D +#Properties file for org.xmind.de.erichseifert.vectorgraphics2d +providerName = XMind Ltd. +pluginName = Vector Graphics 2D diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/about.html b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/about.html +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/build.properties b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/build.properties index 8b7b2f0fc..0565497ea 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/build.properties +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/build.properties @@ -1,7 +1,7 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html,\ - OSGI-INF/ -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + OSGI-INF/ +src.includes = about.html diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml index 46d455785..88bd7cd80 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.orbit - org.xmind.de.erichseifert.vectorgraphics2d - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.orbit + org.xmind.de.erichseifert.vectorgraphics2d + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/PDFGraphics2D.java b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/PDFGraphics2D.java index 446921858..dd05d9cfd 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/PDFGraphics2D.java +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/PDFGraphics2D.java @@ -1,718 +1,718 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.de.erichseifert.vectorgraphics2d; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; -import java.awt.Image; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.TreeMap; - -import org.xmind.de.erichseifert.vectorgraphics2d.util.DataUtils; -import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; - -/** - * {@code Graphics2D} implementation that saves all operations to a string in - * the Portable Document Format (PDF). - * - * @author Jason Wong - */ -public class PDFGraphics2D extends VectorGraphics2D { - /** Prefix string for PDF font resource ids. */ - protected static final String FONT_RESOURCE_PREFIX = "F"; //$NON-NLS-1$ - /** Prefix string for PDF image resource ids. */ - protected static final String IMAGE_RESOURCE_PREFIX = "Im"; //$NON-NLS-1$ - /** Prefix string for PDF transparency resource ids. */ - protected static final String TRANSPARENCY_RESOURCE_PREFIX = "T"; //$NON-NLS-1$ - - /** - * Constant to convert values from millimeters to PostScript®/PDF units - * (1/72th inch). - */ - protected static final double MM_IN_UNITS = 72.0 / 25.4; - - /** Mapping of stroke endcap values from Java to PDF. */ - private static final Map STROKE_ENDCAPS = DataUtils.map( - new Integer[] { BasicStroke.CAP_BUTT, BasicStroke.CAP_ROUND, - BasicStroke.CAP_SQUARE }, new Integer[] { 0, 1, 2 }); - - /** Mapping of line join values for path drawing from Java to PDF. */ - private static final Map STROKE_LINEJOIN = DataUtils.map( - new Integer[] { BasicStroke.JOIN_MITER, BasicStroke.JOIN_ROUND, - BasicStroke.JOIN_BEVEL }, new Integer[] { 0, 1, 2 }); - - /** Id of the current PDF object. */ - private int curObjId; - /** Mapping from objects to file positions. */ - private final Map objPositions; - /** Mapping from transparency levels to transparency resource ids. */ - private final Map transpResources; - /** Mapping from image data to image resource ids. */ - private final Map imageResources; - /** Mapping from font objects to font resource ids. */ - private final Map fontResources; - /** File position of the actual content. */ - private int contentStart; - - private double scale; - private double scaledOffsetX; - private double scaledOffsetY; - - /** - * Constructor that initializes a new {@code PDFGraphics2D} instance. The - * document dimension must be specified as parameters. - */ - public PDFGraphics2D(double x, double y, double width, double height, - double scale, double scaledOffsetX, double scaledOffsetY) { - super(x, y, width, height); - this.scale = scale; - this.scaledOffsetX = Math.round(scaledOffsetX * 100) / 100.0; - this.scaledOffsetY = Math.round(scaledOffsetY * 100) / 100.0; - curObjId = 1; - objPositions = new TreeMap(); - transpResources = new TreeMap(); - imageResources = new LinkedHashMap(); - fontResources = new LinkedHashMap(); - writeHeader(); - } - - @SuppressWarnings("nls") - @Override - protected void writeString(String str, double x, double y) { - // Escape string - str = str.replaceAll("\\\\", "\\\\\\\\").replaceAll("\t", "\\\\t") - .replaceAll("\b", "\\\\b").replaceAll("\f", "\\\\f") - .replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)"); - - float fontSize = getFont().getSize2D(); - float leading = getFont().getLineMetrics("", getFontRenderContext()) - .getLeading(); - - // Start text and save current graphics state - writeln("q BT"); - - String fontResourceId = getFontResource(getFont()); - writeln("/", fontResourceId, " ", fontSize, " Tf"); - // Set leading - writeln(fontSize + leading, " TL"); - - // Undo swapping of y axis for text - writeln("1 0 0 -1 ", x, " ", y, " cm"); - - /* - * // Extract lines String[] lines = str.replaceAll("\r\n", - * "\n").replaceAll("\r", "\n").split("\n"); // Paint lines for (int i = - * 0; i < lines.length; i++) { writeln("(", lines[i], ") ", (i == 0) ? - * "Tj" : "'"); } - */ - - str = str.replaceAll("[\r\n]", ""); - writeln("(", str, ") Tj"); - - // End text and restore previous graphics state - writeln("ET Q"); - } - - @SuppressWarnings("nls") - @Override - public void setStroke(Stroke s) { - super.setStroke(s); - if (s instanceof BasicStroke) { - BasicStroke bs = (BasicStroke) s; - writeln(bs.getLineWidth(), " w"); - writeln(STROKE_LINEJOIN.get(bs.getLineJoin()), " j"); - writeln(STROKE_ENDCAPS.get(bs.getEndCap()), " J"); - writeln("[", DataUtils.join(" ", bs.getDashArray()), "] ", - bs.getDashPhase(), " d"); - } - } - - @SuppressWarnings("nls") - @Override - protected void writeImage(Image img, int imgWidth, int imgHeight, double x, - double y, double width, double height) { - BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); - String imageResourceId = getImageResource(bufferedImg); - // Save graphics state - write("q "); - // Take current transformations into account - AffineTransform txCurrent = getTransform(); - if (!txCurrent.isIdentity()) { - double[] matrix = new double[6]; - txCurrent.getMatrix(matrix); - write(DataUtils.join(" ", matrix), " cm "); - } - // Move image to correct position and scale it to (width, height) - write(width, " 0 0 ", height, " ", x - 2, " ", y - 2, " cm "); - - // Swap y axis - write("1 0 0 -1 0 1 cm "); - // Draw image - write("/", imageResourceId, " Do "); - // Restore old graphics state - writeln("Q"); - } - - @SuppressWarnings("nls") - @Override - public void setColor(Color c) { - if (c != null) { - super.setColor(c); - // Add a new graphics state to resources - double a = c.getAlpha() / 255.0; - String transpResourceId = getTransparencyResource(a); - writeln("/", transpResourceId, " gs"); - double r = c.getRed() / 255.0; - double g = c.getGreen() / 255.0; - double b = c.getBlue() / 255.0; - write(r, " ", g, " ", b, " rg "); - writeln(r, " ", g, " ", b, " RG"); - } - } - - @Override - public void setClip(Shape clip) { - if (getClip() != null) { - writeln("Q");//$NON-NLS-1$ - } - super.setClip(clip); - if (getClip() != null) { - writeln("q");//$NON-NLS-1$ - writeShape(getClip()); - writeln(" W n");//$NON-NLS-1$ - } - } - - // TODO Correct transformations - /* - * @Override protected void setAffineTransform(AffineTransform tx) { if - * (getTransform().equals(tx)) { return; } // Undo previous transforms if - * (isTransformed()) { writeln("Q"); } // Set new transform - * super.setAffineTransform(tx); // Write transform to document if - * (isTransformed()) { writeln("q"); double[] matrix = new double[6]; - * getTransform().getMatrix(matrix); writeln(DataUtils.join(" ", matrix), - * " cm"); } } // - */ - - @SuppressWarnings("nls") - @Override - protected void writeHeader() { - Rectangle2D bounds = getBounds(); - int x = (int) Math.floor(bounds.getX());// * MM_IN_UNITS); - int y = (int) Math.floor(bounds.getY());// * MM_IN_UNITS); - int w = (int) Math.ceil(bounds.getWidth());// * MM_IN_UNITS); - int h = (int) Math.ceil(bounds.getHeight());// * MM_IN_UNITS); - - writeln("%PDF-1.4"); - // Object 1 - writeObj("Type", "/Catalog", "Pages", "2 0 R"); - // Object 2 - writeObj("Type", "/Pages", "Kids", "[3 0 R]", "Count", "1"); - // Object 3 - writeObj("Type", "/Page", "Parent", "2 0 R", "MediaBox", - String.format("[%d %d %d %d]", x, y, w, h), "Contents", - "4 0 R", "Resources", "6 0 R"); - // Object 5 - writeln(nextObjId(size()), " 0 obj"); - writeDict("Length", "5 0 R"); - writeln("stream"); - contentStart = size(); - writeln("q"); - // Adjust page size and page origin - writeln(scale, " 0 0 ", -scale, " " + scaledOffsetX + " ", h - - scaledOffsetY, " cm"); - } - - /** - * Write a PDF dictionary from the specified collection of objects. The - * passed objects are converted to strings. Every object with odd position - * is used as key, every object with even position is used as value. - * - * @param strs - * Objects to be written to dictionary - */ - @SuppressWarnings("nls") - protected void writeDict(Object... strs) { - writeln("<<"); - for (int i = 0; i < strs.length; i += 2) { - writeln("/", strs[i], " ", strs[i + 1]); - } - writeln(">>"); - } - - /** - * Write a collection of elements to the document stream as PDF object. The - * passed objects are converted to strings. - * - * @param strs - * Objects to be written to the document stream. - * @return Id of the PDF object that was written. - */ - protected int writeObj(Object... strs) { - int objId = nextObjId(size()); - writeln(objId, " 0 obj"); //$NON-NLS-1$ - writeDict(strs); - writeln("endobj"); //$NON-NLS-1$ - return objId; - } - - /** - * Returns the next PDF object id without incrementing. - * - * @return Next PDF object id. - */ - protected int peekObjId() { - return curObjId + 1; - } - - /** - * Returns a new PDF object id with every call. - * - * @param position - * File position of the object. - * @return A new PDF object id. - */ - private int nextObjId(int position) { - objPositions.put(curObjId, position); - return curObjId++; - } - - /** - * Returns the resource for the specified transparency level. - * - * @param a - * Transparency level. - * @return A new PDF object id. - */ - protected String getTransparencyResource(double a) { - String name = transpResources.get(a); - if (name == null) { - name = String.format("%s%d", TRANSPARENCY_RESOURCE_PREFIX, //$NON-NLS-1$ - transpResources.size() + 1); - transpResources.put(a, name); - } - return name; - } - - /** - * Returns the resource for the specified image data. - * - * @param bufferedImg - * Image object with data. - * @return A new PDF object id. - */ - protected String getImageResource(BufferedImage bufferedImg) { - String name = imageResources.get(bufferedImg); - if (name == null) { - name = String.format("%s%d", IMAGE_RESOURCE_PREFIX, //$NON-NLS-1$ - imageResources.size() + 1); - imageResources.put(bufferedImg, name); - } - return name; - } - - /** - * Returns the resource describing the specified font. - * - * @param font - * Font to be described. - * @return A new PDF object id. - */ - protected String getFontResource(Font font) { - String name = fontResources.get(font); - if (name == null) { - name = String.format("%s%d", FONT_RESOURCE_PREFIX, //$NON-NLS-1$ - fontResources.size() + 1); - fontResources.put(font, name); - } - return name; - } - - /** - * Utility method for writing a tag closing fragment for drawing operations. - */ - @Override - protected void writeClosingDraw(Shape s) { - writeln(" S"); //$NON-NLS-1$ - } - - /** - * Utility method for writing a tag closing fragment for filling operations. - */ - @Override - protected void writeClosingFill(Shape s) { - writeln(" f"); //$NON-NLS-1$ - if (!(getPaint() instanceof Color)) { - super.writeClosingFill(s); - } - } - - /** - * Utility method for writing an arbitrary shape to. It tries to translate - * Java2D shapes to the corresponding PDF shape commands. - */ - @SuppressWarnings("nls") - @Override - protected void writeShape(Shape s) { - // TODO Correct transformations - /* - * if (s instanceof Line2D) { Line2D l = (Line2D) s; double x1 = - * l.getX1(); double y1 = l.getY1(); double x2 = l.getX2(); double y2 = - * l.getY2(); write(x1, " ", y1, " m ", x2, " ", y2, " l"); } else if (s - * instanceof Rectangle2D) { Rectangle2D r = (Rectangle2D) s; double x = - * r.getX(); double y = r.getY(); double width = r.getWidth(); double - * height = r.getHeight(); write(x, " ", y, " ", width, " ", height, - * " re"); } else // - */ - { - s = getTransform().createTransformedShape(s); - PathIterator segments = s.getPathIterator(null); - double[] coordsCur = new double[6]; - double[] pointPrev = new double[2]; - for (int i = 0; !segments.isDone(); i++, segments.next()) { - if (i > 0) { - write(" "); - } - int segmentType = segments.currentSegment(coordsCur); - switch (segmentType) { - case PathIterator.SEG_MOVETO: - write(coordsCur[0], " ", coordsCur[1], " m"); - pointPrev[0] = coordsCur[0]; - pointPrev[1] = coordsCur[1]; - break; - case PathIterator.SEG_LINETO: - write(coordsCur[0], " ", coordsCur[1], " l"); - pointPrev[0] = coordsCur[0]; - pointPrev[1] = coordsCur[1]; - break; - case PathIterator.SEG_CUBICTO: - write(coordsCur[0], " ", coordsCur[1], " ", coordsCur[2], - " ", coordsCur[3], " ", coordsCur[4], " ", - coordsCur[5], " c"); - pointPrev[0] = coordsCur[4]; - pointPrev[1] = coordsCur[5]; - break; - case PathIterator.SEG_QUADTO: - double x1 = pointPrev[0] + 2.0 / 3.0 - * (coordsCur[0] - pointPrev[0]); - double y1 = pointPrev[1] + 2.0 / 3.0 - * (coordsCur[1] - pointPrev[1]); - double x2 = coordsCur[0] + 1.0 / 3.0 - * (coordsCur[2] - coordsCur[0]); - double y2 = coordsCur[1] + 1.0 / 3.0 - * (coordsCur[3] - coordsCur[1]); - double x3 = coordsCur[2]; - double y3 = coordsCur[3]; - write(x1, " ", y1, " ", x2, " ", y2, " ", x3, " ", y3, " c"); - pointPrev[0] = x3; - pointPrev[1] = y3; - break; - case PathIterator.SEG_CLOSE: - write("h"); - break; - default: - throw new IllegalStateException("Unknown path operation."); - } - } - } - } - - /** - * Returns a string which represents the data of the specified image. - * - * @param bufferedImg - * Image to convert. - * @return String representation of image in PDF hexadecimal format. - */ - private String getPdf(BufferedImage bufferedImg) { - int width = bufferedImg.getWidth(); - int height = bufferedImg.getHeight(); - int bands = bufferedImg.getSampleModel().getNumBands(); - StringBuffer str = new StringBuffer(width * height * bands * 2); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - int pixel = bufferedImg.getRGB(x, y) & 0xffffff; - if (bands >= 3) { - String hex = String.format("%06x", pixel); //$NON-NLS-1$ - str.append(hex); - } else if (bands == 1) { - str.append(String.format("%02x", pixel)); //$NON-NLS-1$ - } - } - str.append('\n'); - } - return str.append('>').toString(); - } - - @SuppressWarnings("nls") - @Override - protected String getFooter() { - StringBuffer footer = new StringBuffer(); - // TODO Correct transformations - /* - * if (isTransformed()) { footer.append("Q\n"); } - */ - if (getClip() != null) { - footer.append("Q\n"); //$NON-NLS-1$ - } - footer.append("Q"); //$NON-NLS-1$ - int contentEnd = size() + footer.length(); - footer.append('\n'); - footer.append("endstream\n"); //$NON-NLS-1$ - footer.append("endobj\n"); - - int lenObjId = nextObjId(size() + footer.length()); - footer.append(lenObjId).append(" 0 obj\n"); - footer.append(contentEnd - contentStart).append('\n'); - footer.append("endobj\n"); - - int resourcesObjId = nextObjId(size() + footer.length()); - footer.append(resourcesObjId).append(" 0 obj\n"); - footer.append("<<\n"); - footer.append(" /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n"); - - // Add resources for fonts - if (!fontResources.isEmpty()) { - footer.append(" /Font <<\n"); - for (Map.Entry entry : fontResources.entrySet()) { - Font font = entry.getKey(); - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId) - .append(" << /Type /Font").append(" /Subtype /") - .append("TrueType").append(" /BaseFont /") - .append(font.getPSName()).append(" >>\n"); - } - footer.append(" >>\n"); - } - - // Add resources for images - if (!imageResources.isEmpty()) { - footer.append(" /XObject <<\n"); - - int objIdOffset = 0; - for (Map.Entry entry : imageResources - .entrySet()) { - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId).append(' ') - .append(curObjId + objIdOffset).append(" 0 R\n"); - objIdOffset++; - } - footer.append(" >>\n"); - } - - // Add resources for transparency levels - if (!transpResources.isEmpty()) { - footer.append(" /ExtGState <<\n"); - for (Map.Entry entry : transpResources.entrySet()) { - Double alpha = entry.getKey(); - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId) - .append(" << /Type /ExtGState").append(" /ca ") - .append(alpha).append(" /CA ").append(alpha) - .append(" >>\n"); - } - footer.append(" >>\n"); - } - - footer.append(">>\n"); - footer.append("endobj\n"); - - // Add data of images - for (BufferedImage image : imageResources.keySet()) { - int imageObjId = nextObjId(size() + footer.length()); - footer.append(imageObjId).append(" 0 obj\n"); - footer.append("<<\n"); - String imageData = getPdf(image); - footer.append("/Type /XObject\n").append("/Subtype /Image\n") - .append("/Width ").append(image.getWidth()).append('\n') - .append("/Height ").append(image.getHeight()).append('\n') - .append("/ColorSpace /DeviceRGB\n") - .append("/BitsPerComponent 8\n").append("/Length ") - .append(imageData.length()).append('\n') - .append("/Filter /ASCIIHexDecode\n").append(">>\n") - .append("stream\n").append(imageData) - .append("\nendstream\n").append("endobj\n"); - } - - int objs = objPositions.size() + 1; - - int xrefPos = size() + footer.length(); - footer.append("xref\n"); - footer.append("0 ").append(objs).append('\n'); - // lines of xref entries must must be exactly 20 bytes long - // (including line break) and thus end with - footer.append(String.format("%010d %05d", 0, 65535)).append(" f \n"); - for (int pos : objPositions.values()) { - footer.append(String.format("%010d %05d", pos, 0)).append(" n \n"); - } - - footer.append("trailer\n"); - footer.append("<<\n"); - footer.append("/Size ").append(objs).append('\n'); - footer.append("/Root 1 0 R\n"); - footer.append(">>\n"); - footer.append("startxref\n"); - footer.append(xrefPos).append('\n'); - - footer.append("%%EOF\n"); - return footer.toString(); - } - - @SuppressWarnings("nls") - public void writeFooter(Writer out) throws IOException { - StringBuffer footer = new StringBuffer(); - - if (getClip() != null) { - footer.append("Q\n"); - } - footer.append("Q"); - int contentEnd = size() + footer.length(); - footer.append('\n'); - footer.append("endstream\n"); - footer.append("endobj\n"); - - int lenObjId = nextObjId(size() + footer.length()); - footer.append(lenObjId).append(" 0 obj\n"); - footer.append(contentEnd - contentStart).append('\n'); - footer.append("endobj\n"); - - int resourcesObjId = nextObjId(size() + footer.length()); - footer.append(resourcesObjId).append(" 0 obj\n"); - footer.append("<<\n"); - footer.append(" /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n"); - out.write(footer.toString()); - footer = new StringBuffer(); - - // Add resources for fonts - if (!fontResources.isEmpty()) { - footer.append(" /Font <<\n"); - for (Map.Entry entry : fontResources.entrySet()) { - Font font = entry.getKey(); - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId) - .append(" << /Type /Font").append(" /Subtype /") - .append("TrueType").append(" /BaseFont /") - .append(font.getPSName()).append(" >>\n"); - } - footer.append(" >>\n"); - } - - // Add resources for images - if (!imageResources.isEmpty()) { - footer.append(" /XObject <<\n"); - int objIdOffset = 0; - for (Map.Entry entry : imageResources - .entrySet()) { - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId).append(' ') - .append(curObjId + objIdOffset).append(" 0 R\n"); - objIdOffset++; - } - footer.append(" >>\n"); - } - - // Add resources for transparency levels - if (!transpResources.isEmpty()) { - footer.append(" /ExtGState <<\n"); - for (Map.Entry entry : transpResources.entrySet()) { - Double alpha = entry.getKey(); - String resourceId = entry.getValue(); - footer.append(" /").append(resourceId) - .append(" << /Type /ExtGState").append(" /ca ") - .append(alpha).append(" /CA ").append(alpha) - .append(" >>\n"); - } - footer.append(" >>\n"); - } - - footer.append(">>\n"); - footer.append("endobj\n"); - out.write(footer.toString()); - footer = new StringBuffer(); - - // Add data of images - for (BufferedImage image : imageResources.keySet()) { - int imageObjId = nextObjId(size() + footer.length()); - footer.append(imageObjId).append(" 0 obj\n"); - footer.append("<<\n"); - String imageData = getPdf(image); - footer.append("/Type /XObject\n").append("/Subtype /Image\n") - .append("/Width ").append(image.getWidth()).append('\n') - .append("/Height ").append(image.getHeight()).append('\n') - .append("/ColorSpace /DeviceRGB\n") - .append("/BitsPerComponent 8\n").append("/Length ") - .append(imageData.length()).append('\n') - .append("/Filter /ASCIIHexDecode\n").append(">>\n") - .append("stream\n"); - out.write(footer.toString()); - out.write(imageData); - out.write("\nendstream\n"); - out.write("endobj\n"); - footer = new StringBuffer(); - } - - int objs = objPositions.size() + 1; - - int xrefPos = size() + footer.length(); - footer.append("xref\n"); - footer.append("0 ").append(objs).append('\n'); - // lines of xref entries must must be exactly 20 bytes long - // (including line break) and thus end with - footer.append(String.format("%010d %05d", 0, 65535)).append(" f \n"); - for (int pos : objPositions.values()) { - footer.append(String.format("%010d %05d", pos, 0)).append(" n \n"); - } - - footer.append("trailer\n"); - footer.append("<<\n"); - footer.append("/Size ").append(objs).append('\n'); - footer.append("/Root 1 0 R\n"); - footer.append(">>\n"); - footer.append("startxref\n"); - footer.append(xrefPos).append('\n'); - - footer.append("%%EOF\n"); - out.write(footer.toString()); - } - - @Override - public String toString() { - // String doc = super.toString(); - String doc = super.getDocument().toString(); - // doc = - // doc.replaceAll("q\n[0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* cm\nQ\n", - // ""); - return doc; - } - - @Override - public byte[] getBytes() { - try { - return toString().getBytes("UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - return super.getBytes(); - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.de.erichseifert.vectorgraphics2d; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Image; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.xmind.de.erichseifert.vectorgraphics2d.util.DataUtils; +import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; + +/** + * {@code Graphics2D} implementation that saves all operations to a string in + * the Portable Document Format (PDF). + * + * @author Jason Wong + */ +public class PDFGraphics2D extends VectorGraphics2D { + /** Prefix string for PDF font resource ids. */ + protected static final String FONT_RESOURCE_PREFIX = "F"; //$NON-NLS-1$ + /** Prefix string for PDF image resource ids. */ + protected static final String IMAGE_RESOURCE_PREFIX = "Im"; //$NON-NLS-1$ + /** Prefix string for PDF transparency resource ids. */ + protected static final String TRANSPARENCY_RESOURCE_PREFIX = "T"; //$NON-NLS-1$ + + /** + * Constant to convert values from millimeters to PostScript®/PDF units + * (1/72th inch). + */ + protected static final double MM_IN_UNITS = 72.0 / 25.4; + + /** Mapping of stroke endcap values from Java to PDF. */ + private static final Map STROKE_ENDCAPS = DataUtils.map( + new Integer[] { BasicStroke.CAP_BUTT, BasicStroke.CAP_ROUND, + BasicStroke.CAP_SQUARE }, new Integer[] { 0, 1, 2 }); + + /** Mapping of line join values for path drawing from Java to PDF. */ + private static final Map STROKE_LINEJOIN = DataUtils.map( + new Integer[] { BasicStroke.JOIN_MITER, BasicStroke.JOIN_ROUND, + BasicStroke.JOIN_BEVEL }, new Integer[] { 0, 1, 2 }); + + /** Id of the current PDF object. */ + private int curObjId; + /** Mapping from objects to file positions. */ + private final Map objPositions; + /** Mapping from transparency levels to transparency resource ids. */ + private final Map transpResources; + /** Mapping from image data to image resource ids. */ + private final Map imageResources; + /** Mapping from font objects to font resource ids. */ + private final Map fontResources; + /** File position of the actual content. */ + private int contentStart; + + private double scale; + private double scaledOffsetX; + private double scaledOffsetY; + + /** + * Constructor that initializes a new {@code PDFGraphics2D} instance. The + * document dimension must be specified as parameters. + */ + public PDFGraphics2D(double x, double y, double width, double height, + double scale, double scaledOffsetX, double scaledOffsetY) { + super(x, y, width, height); + this.scale = scale; + this.scaledOffsetX = Math.round(scaledOffsetX * 100) / 100.0; + this.scaledOffsetY = Math.round(scaledOffsetY * 100) / 100.0; + curObjId = 1; + objPositions = new TreeMap(); + transpResources = new TreeMap(); + imageResources = new LinkedHashMap(); + fontResources = new LinkedHashMap(); + writeHeader(); + } + + @SuppressWarnings("nls") + @Override + protected void writeString(String str, double x, double y) { + // Escape string + str = str.replaceAll("\\\\", "\\\\\\\\").replaceAll("\t", "\\\\t") + .replaceAll("\b", "\\\\b").replaceAll("\f", "\\\\f") + .replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)"); + + float fontSize = getFont().getSize2D(); + float leading = getFont().getLineMetrics("", getFontRenderContext()) + .getLeading(); + + // Start text and save current graphics state + writeln("q BT"); + + String fontResourceId = getFontResource(getFont()); + writeln("/", fontResourceId, " ", fontSize, " Tf"); + // Set leading + writeln(fontSize + leading, " TL"); + + // Undo swapping of y axis for text + writeln("1 0 0 -1 ", x, " ", y, " cm"); + + /* + * // Extract lines String[] lines = str.replaceAll("\r\n", + * "\n").replaceAll("\r", "\n").split("\n"); // Paint lines for (int i = + * 0; i < lines.length; i++) { writeln("(", lines[i], ") ", (i == 0) ? + * "Tj" : "'"); } + */ + + str = str.replaceAll("[\r\n]", ""); + writeln("(", str, ") Tj"); + + // End text and restore previous graphics state + writeln("ET Q"); + } + + @SuppressWarnings("nls") + @Override + public void setStroke(Stroke s) { + super.setStroke(s); + if (s instanceof BasicStroke) { + BasicStroke bs = (BasicStroke) s; + writeln(bs.getLineWidth(), " w"); + writeln(STROKE_LINEJOIN.get(bs.getLineJoin()), " j"); + writeln(STROKE_ENDCAPS.get(bs.getEndCap()), " J"); + writeln("[", DataUtils.join(" ", bs.getDashArray()), "] ", + bs.getDashPhase(), " d"); + } + } + + @SuppressWarnings("nls") + @Override + protected void writeImage(Image img, int imgWidth, int imgHeight, double x, + double y, double width, double height) { + BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); + String imageResourceId = getImageResource(bufferedImg); + // Save graphics state + write("q "); + // Take current transformations into account + AffineTransform txCurrent = getTransform(); + if (!txCurrent.isIdentity()) { + double[] matrix = new double[6]; + txCurrent.getMatrix(matrix); + write(DataUtils.join(" ", matrix), " cm "); + } + // Move image to correct position and scale it to (width, height) + write(width, " 0 0 ", height, " ", x - 2, " ", y - 2, " cm "); + + // Swap y axis + write("1 0 0 -1 0 1 cm "); + // Draw image + write("/", imageResourceId, " Do "); + // Restore old graphics state + writeln("Q"); + } + + @SuppressWarnings("nls") + @Override + public void setColor(Color c) { + if (c != null) { + super.setColor(c); + // Add a new graphics state to resources + double a = c.getAlpha() / 255.0; + String transpResourceId = getTransparencyResource(a); + writeln("/", transpResourceId, " gs"); + double r = c.getRed() / 255.0; + double g = c.getGreen() / 255.0; + double b = c.getBlue() / 255.0; + write(r, " ", g, " ", b, " rg "); + writeln(r, " ", g, " ", b, " RG"); + } + } + + @Override + public void setClip(Shape clip) { + if (getClip() != null) { + writeln("Q");//$NON-NLS-1$ + } + super.setClip(clip); + if (getClip() != null) { + writeln("q");//$NON-NLS-1$ + writeShape(getClip()); + writeln(" W n");//$NON-NLS-1$ + } + } + + // TODO Correct transformations + /* + * @Override protected void setAffineTransform(AffineTransform tx) { if + * (getTransform().equals(tx)) { return; } // Undo previous transforms if + * (isTransformed()) { writeln("Q"); } // Set new transform + * super.setAffineTransform(tx); // Write transform to document if + * (isTransformed()) { writeln("q"); double[] matrix = new double[6]; + * getTransform().getMatrix(matrix); writeln(DataUtils.join(" ", matrix), + * " cm"); } } // + */ + + @SuppressWarnings("nls") + @Override + protected void writeHeader() { + Rectangle2D bounds = getBounds(); + int x = (int) Math.floor(bounds.getX());// * MM_IN_UNITS); + int y = (int) Math.floor(bounds.getY());// * MM_IN_UNITS); + int w = (int) Math.ceil(bounds.getWidth());// * MM_IN_UNITS); + int h = (int) Math.ceil(bounds.getHeight());// * MM_IN_UNITS); + + writeln("%PDF-1.4"); + // Object 1 + writeObj("Type", "/Catalog", "Pages", "2 0 R"); + // Object 2 + writeObj("Type", "/Pages", "Kids", "[3 0 R]", "Count", "1"); + // Object 3 + writeObj("Type", "/Page", "Parent", "2 0 R", "MediaBox", + String.format("[%d %d %d %d]", x, y, w, h), "Contents", + "4 0 R", "Resources", "6 0 R"); + // Object 5 + writeln(nextObjId(size()), " 0 obj"); + writeDict("Length", "5 0 R"); + writeln("stream"); + contentStart = size(); + writeln("q"); + // Adjust page size and page origin + writeln(scale, " 0 0 ", -scale, " " + scaledOffsetX + " ", h + - scaledOffsetY, " cm"); + } + + /** + * Write a PDF dictionary from the specified collection of objects. The + * passed objects are converted to strings. Every object with odd position + * is used as key, every object with even position is used as value. + * + * @param strs + * Objects to be written to dictionary + */ + @SuppressWarnings("nls") + protected void writeDict(Object... strs) { + writeln("<<"); + for (int i = 0; i < strs.length; i += 2) { + writeln("/", strs[i], " ", strs[i + 1]); + } + writeln(">>"); + } + + /** + * Write a collection of elements to the document stream as PDF object. The + * passed objects are converted to strings. + * + * @param strs + * Objects to be written to the document stream. + * @return Id of the PDF object that was written. + */ + protected int writeObj(Object... strs) { + int objId = nextObjId(size()); + writeln(objId, " 0 obj"); //$NON-NLS-1$ + writeDict(strs); + writeln("endobj"); //$NON-NLS-1$ + return objId; + } + + /** + * Returns the next PDF object id without incrementing. + * + * @return Next PDF object id. + */ + protected int peekObjId() { + return curObjId + 1; + } + + /** + * Returns a new PDF object id with every call. + * + * @param position + * File position of the object. + * @return A new PDF object id. + */ + private int nextObjId(int position) { + objPositions.put(curObjId, position); + return curObjId++; + } + + /** + * Returns the resource for the specified transparency level. + * + * @param a + * Transparency level. + * @return A new PDF object id. + */ + protected String getTransparencyResource(double a) { + String name = transpResources.get(a); + if (name == null) { + name = String.format("%s%d", TRANSPARENCY_RESOURCE_PREFIX, //$NON-NLS-1$ + transpResources.size() + 1); + transpResources.put(a, name); + } + return name; + } + + /** + * Returns the resource for the specified image data. + * + * @param bufferedImg + * Image object with data. + * @return A new PDF object id. + */ + protected String getImageResource(BufferedImage bufferedImg) { + String name = imageResources.get(bufferedImg); + if (name == null) { + name = String.format("%s%d", IMAGE_RESOURCE_PREFIX, //$NON-NLS-1$ + imageResources.size() + 1); + imageResources.put(bufferedImg, name); + } + return name; + } + + /** + * Returns the resource describing the specified font. + * + * @param font + * Font to be described. + * @return A new PDF object id. + */ + protected String getFontResource(Font font) { + String name = fontResources.get(font); + if (name == null) { + name = String.format("%s%d", FONT_RESOURCE_PREFIX, //$NON-NLS-1$ + fontResources.size() + 1); + fontResources.put(font, name); + } + return name; + } + + /** + * Utility method for writing a tag closing fragment for drawing operations. + */ + @Override + protected void writeClosingDraw(Shape s) { + writeln(" S"); //$NON-NLS-1$ + } + + /** + * Utility method for writing a tag closing fragment for filling operations. + */ + @Override + protected void writeClosingFill(Shape s) { + writeln(" f"); //$NON-NLS-1$ + if (!(getPaint() instanceof Color)) { + super.writeClosingFill(s); + } + } + + /** + * Utility method for writing an arbitrary shape to. It tries to translate + * Java2D shapes to the corresponding PDF shape commands. + */ + @SuppressWarnings("nls") + @Override + protected void writeShape(Shape s) { + // TODO Correct transformations + /* + * if (s instanceof Line2D) { Line2D l = (Line2D) s; double x1 = + * l.getX1(); double y1 = l.getY1(); double x2 = l.getX2(); double y2 = + * l.getY2(); write(x1, " ", y1, " m ", x2, " ", y2, " l"); } else if (s + * instanceof Rectangle2D) { Rectangle2D r = (Rectangle2D) s; double x = + * r.getX(); double y = r.getY(); double width = r.getWidth(); double + * height = r.getHeight(); write(x, " ", y, " ", width, " ", height, + * " re"); } else // + */ + { + s = getTransform().createTransformedShape(s); + PathIterator segments = s.getPathIterator(null); + double[] coordsCur = new double[6]; + double[] pointPrev = new double[2]; + for (int i = 0; !segments.isDone(); i++, segments.next()) { + if (i > 0) { + write(" "); + } + int segmentType = segments.currentSegment(coordsCur); + switch (segmentType) { + case PathIterator.SEG_MOVETO: + write(coordsCur[0], " ", coordsCur[1], " m"); + pointPrev[0] = coordsCur[0]; + pointPrev[1] = coordsCur[1]; + break; + case PathIterator.SEG_LINETO: + write(coordsCur[0], " ", coordsCur[1], " l"); + pointPrev[0] = coordsCur[0]; + pointPrev[1] = coordsCur[1]; + break; + case PathIterator.SEG_CUBICTO: + write(coordsCur[0], " ", coordsCur[1], " ", coordsCur[2], + " ", coordsCur[3], " ", coordsCur[4], " ", + coordsCur[5], " c"); + pointPrev[0] = coordsCur[4]; + pointPrev[1] = coordsCur[5]; + break; + case PathIterator.SEG_QUADTO: + double x1 = pointPrev[0] + 2.0 / 3.0 + * (coordsCur[0] - pointPrev[0]); + double y1 = pointPrev[1] + 2.0 / 3.0 + * (coordsCur[1] - pointPrev[1]); + double x2 = coordsCur[0] + 1.0 / 3.0 + * (coordsCur[2] - coordsCur[0]); + double y2 = coordsCur[1] + 1.0 / 3.0 + * (coordsCur[3] - coordsCur[1]); + double x3 = coordsCur[2]; + double y3 = coordsCur[3]; + write(x1, " ", y1, " ", x2, " ", y2, " ", x3, " ", y3, " c"); + pointPrev[0] = x3; + pointPrev[1] = y3; + break; + case PathIterator.SEG_CLOSE: + write("h"); + break; + default: + throw new IllegalStateException("Unknown path operation."); + } + } + } + } + + /** + * Returns a string which represents the data of the specified image. + * + * @param bufferedImg + * Image to convert. + * @return String representation of image in PDF hexadecimal format. + */ + private String getPdf(BufferedImage bufferedImg) { + int width = bufferedImg.getWidth(); + int height = bufferedImg.getHeight(); + int bands = bufferedImg.getSampleModel().getNumBands(); + StringBuffer str = new StringBuffer(width * height * bands * 2); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int pixel = bufferedImg.getRGB(x, y) & 0xffffff; + if (bands >= 3) { + String hex = String.format("%06x", pixel); //$NON-NLS-1$ + str.append(hex); + } else if (bands == 1) { + str.append(String.format("%02x", pixel)); //$NON-NLS-1$ + } + } + str.append('\n'); + } + return str.append('>').toString(); + } + + @SuppressWarnings("nls") + @Override + protected String getFooter() { + StringBuffer footer = new StringBuffer(); + // TODO Correct transformations + /* + * if (isTransformed()) { footer.append("Q\n"); } + */ + if (getClip() != null) { + footer.append("Q\n"); //$NON-NLS-1$ + } + footer.append("Q"); //$NON-NLS-1$ + int contentEnd = size() + footer.length(); + footer.append('\n'); + footer.append("endstream\n"); //$NON-NLS-1$ + footer.append("endobj\n"); + + int lenObjId = nextObjId(size() + footer.length()); + footer.append(lenObjId).append(" 0 obj\n"); + footer.append(contentEnd - contentStart).append('\n'); + footer.append("endobj\n"); + + int resourcesObjId = nextObjId(size() + footer.length()); + footer.append(resourcesObjId).append(" 0 obj\n"); + footer.append("<<\n"); + footer.append(" /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n"); + + // Add resources for fonts + if (!fontResources.isEmpty()) { + footer.append(" /Font <<\n"); + for (Map.Entry entry : fontResources.entrySet()) { + Font font = entry.getKey(); + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId) + .append(" << /Type /Font").append(" /Subtype /") + .append("TrueType").append(" /BaseFont /") + .append(font.getPSName()).append(" >>\n"); + } + footer.append(" >>\n"); + } + + // Add resources for images + if (!imageResources.isEmpty()) { + footer.append(" /XObject <<\n"); + + int objIdOffset = 0; + for (Map.Entry entry : imageResources + .entrySet()) { + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId).append(' ') + .append(curObjId + objIdOffset).append(" 0 R\n"); + objIdOffset++; + } + footer.append(" >>\n"); + } + + // Add resources for transparency levels + if (!transpResources.isEmpty()) { + footer.append(" /ExtGState <<\n"); + for (Map.Entry entry : transpResources.entrySet()) { + Double alpha = entry.getKey(); + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId) + .append(" << /Type /ExtGState").append(" /ca ") + .append(alpha).append(" /CA ").append(alpha) + .append(" >>\n"); + } + footer.append(" >>\n"); + } + + footer.append(">>\n"); + footer.append("endobj\n"); + + // Add data of images + for (BufferedImage image : imageResources.keySet()) { + int imageObjId = nextObjId(size() + footer.length()); + footer.append(imageObjId).append(" 0 obj\n"); + footer.append("<<\n"); + String imageData = getPdf(image); + footer.append("/Type /XObject\n").append("/Subtype /Image\n") + .append("/Width ").append(image.getWidth()).append('\n') + .append("/Height ").append(image.getHeight()).append('\n') + .append("/ColorSpace /DeviceRGB\n") + .append("/BitsPerComponent 8\n").append("/Length ") + .append(imageData.length()).append('\n') + .append("/Filter /ASCIIHexDecode\n").append(">>\n") + .append("stream\n").append(imageData) + .append("\nendstream\n").append("endobj\n"); + } + + int objs = objPositions.size() + 1; + + int xrefPos = size() + footer.length(); + footer.append("xref\n"); + footer.append("0 ").append(objs).append('\n'); + // lines of xref entries must must be exactly 20 bytes long + // (including line break) and thus end with + footer.append(String.format("%010d %05d", 0, 65535)).append(" f \n"); + for (int pos : objPositions.values()) { + footer.append(String.format("%010d %05d", pos, 0)).append(" n \n"); + } + + footer.append("trailer\n"); + footer.append("<<\n"); + footer.append("/Size ").append(objs).append('\n'); + footer.append("/Root 1 0 R\n"); + footer.append(">>\n"); + footer.append("startxref\n"); + footer.append(xrefPos).append('\n'); + + footer.append("%%EOF\n"); + return footer.toString(); + } + + @SuppressWarnings("nls") + public void writeFooter(Writer out) throws IOException { + StringBuffer footer = new StringBuffer(); + + if (getClip() != null) { + footer.append("Q\n"); + } + footer.append("Q"); + int contentEnd = size() + footer.length(); + footer.append('\n'); + footer.append("endstream\n"); + footer.append("endobj\n"); + + int lenObjId = nextObjId(size() + footer.length()); + footer.append(lenObjId).append(" 0 obj\n"); + footer.append(contentEnd - contentStart).append('\n'); + footer.append("endobj\n"); + + int resourcesObjId = nextObjId(size() + footer.length()); + footer.append(resourcesObjId).append(" 0 obj\n"); + footer.append("<<\n"); + footer.append(" /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n"); + out.write(footer.toString()); + footer = new StringBuffer(); + + // Add resources for fonts + if (!fontResources.isEmpty()) { + footer.append(" /Font <<\n"); + for (Map.Entry entry : fontResources.entrySet()) { + Font font = entry.getKey(); + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId) + .append(" << /Type /Font").append(" /Subtype /") + .append("TrueType").append(" /BaseFont /") + .append(font.getPSName()).append(" >>\n"); + } + footer.append(" >>\n"); + } + + // Add resources for images + if (!imageResources.isEmpty()) { + footer.append(" /XObject <<\n"); + int objIdOffset = 0; + for (Map.Entry entry : imageResources + .entrySet()) { + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId).append(' ') + .append(curObjId + objIdOffset).append(" 0 R\n"); + objIdOffset++; + } + footer.append(" >>\n"); + } + + // Add resources for transparency levels + if (!transpResources.isEmpty()) { + footer.append(" /ExtGState <<\n"); + for (Map.Entry entry : transpResources.entrySet()) { + Double alpha = entry.getKey(); + String resourceId = entry.getValue(); + footer.append(" /").append(resourceId) + .append(" << /Type /ExtGState").append(" /ca ") + .append(alpha).append(" /CA ").append(alpha) + .append(" >>\n"); + } + footer.append(" >>\n"); + } + + footer.append(">>\n"); + footer.append("endobj\n"); + out.write(footer.toString()); + footer = new StringBuffer(); + + // Add data of images + for (BufferedImage image : imageResources.keySet()) { + int imageObjId = nextObjId(size() + footer.length()); + footer.append(imageObjId).append(" 0 obj\n"); + footer.append("<<\n"); + String imageData = getPdf(image); + footer.append("/Type /XObject\n").append("/Subtype /Image\n") + .append("/Width ").append(image.getWidth()).append('\n') + .append("/Height ").append(image.getHeight()).append('\n') + .append("/ColorSpace /DeviceRGB\n") + .append("/BitsPerComponent 8\n").append("/Length ") + .append(imageData.length()).append('\n') + .append("/Filter /ASCIIHexDecode\n").append(">>\n") + .append("stream\n"); + out.write(footer.toString()); + out.write(imageData); + out.write("\nendstream\n"); + out.write("endobj\n"); + footer = new StringBuffer(); + } + + int objs = objPositions.size() + 1; + + int xrefPos = size() + footer.length(); + footer.append("xref\n"); + footer.append("0 ").append(objs).append('\n'); + // lines of xref entries must must be exactly 20 bytes long + // (including line break) and thus end with + footer.append(String.format("%010d %05d", 0, 65535)).append(" f \n"); + for (int pos : objPositions.values()) { + footer.append(String.format("%010d %05d", pos, 0)).append(" n \n"); + } + + footer.append("trailer\n"); + footer.append("<<\n"); + footer.append("/Size ").append(objs).append('\n'); + footer.append("/Root 1 0 R\n"); + footer.append(">>\n"); + footer.append("startxref\n"); + footer.append(xrefPos).append('\n'); + + footer.append("%%EOF\n"); + out.write(footer.toString()); + } + + @Override + public String toString() { + // String doc = super.toString(); + String doc = super.getDocument().toString(); + // doc = + // doc.replaceAll("q\n[0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* [0-9]+\\.?[0-9]* cm\nQ\n", + // ""); + return doc; + } + + @Override + public byte[] getBytes() { + try { + return toString().getBytes("UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + return super.getBytes(); + } + } +} diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/SVGGraphics2D.java b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/SVGGraphics2D.java index e8c84624d..44885d96d 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/SVGGraphics2D.java +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/SVGGraphics2D.java @@ -1,438 +1,438 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.de.erichseifert.vectorgraphics2d; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Image; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Map; - -import javax.imageio.ImageIO; -import javax.xml.bind.DatatypeConverter; - -import org.xmind.de.erichseifert.vectorgraphics2d.util.DataUtils; -import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; - -/** - * {@code Graphics2D} implementation that saves all operations to a string in - * the Scaled Vector Graphics (SVG) format. - * - * @author Jason Wong - */ -public class SVGGraphics2D extends VectorGraphics2D { - /** Mapping of stroke endcap values from Java to SVG. */ - private static final Map STROKE_ENDCAPS = DataUtils.map( - new Integer[] { BasicStroke.CAP_BUTT, BasicStroke.CAP_ROUND, - BasicStroke.CAP_SQUARE }, new String[] { "butt", "round", //$NON-NLS-1$ //$NON-NLS-2$ - "square" }); //$NON-NLS-1$ - - /** Mapping of line join values for path drawing from Java to SVG. */ - private static final Map STROKE_LINEJOIN = DataUtils.map( - new Integer[] { BasicStroke.JOIN_MITER, BasicStroke.JOIN_ROUND, - BasicStroke.JOIN_BEVEL }, new String[] { "miter", "round",//$NON-NLS-1$ //$NON-NLS-2$ - "bevel" });//$NON-NLS-1$ - - /** Prefix string for ids of clipping paths. */ - private static final String CLIP_PATH_ID = "clip"; //$NON-NLS-1$ - /** Number of the current clipping path. */ - private long clipCounter; - - /** - * Constructor that initializes a new {@code SVGGraphics2D} instance. The - * document dimension must be specified as parameters. - * - * @param x - * Left offset of document. - * @param y - * Top offset of document. - * @param width - * Width of document. - * @param height - * Height of document. - */ - public SVGGraphics2D(double x, double y, double width, double height) { - super(x, y, width, height); - writeHeader(); - } - - @SuppressWarnings("nls") - @Override - protected void writeString(String str, double x, double y) { - // Escape string - str = str.replaceAll("&", "&").replaceAll("<", "<") - .replaceAll(">", ">"); - - float fontSize = getFont().getSize2D(); - // float leading = getFont().getLineMetrics("", - // getFontRenderContext()).getLeading(); - - /* - * // Extract lines String[] lines = str.replaceAll("\r\n", - * "\n").replaceAll("\r", "\n").split("\n"); - * - * // Output lines writeln(""); for (int i = 0; i < lines.length; i++) - * { String line = lines[i]; writeln(" 0) ? leading : 0f), "\">", line, ""); } - * writeln(""); - */ - - str = str.replaceAll("[\r\n]", ""); - writeln("", str, ""); - } - - @SuppressWarnings("nls") - @Override - protected void writeImage(Image img, int imgWidth, int imgHeight, double x, - double y, double width, double height) { - BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); - String imgData = getSvg(bufferedImg); - write(""); //$NON-NLS-1$ - } - - @Override - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { - Path2D s = new Path2D.Double(Path2D.WIND_NON_ZERO, xPoints.length); - write(""); //$NON-NLS-1$ - } - // Set transformation matrix - super.setAffineTransform(tx); - // Begin new transformation group - if (isTransformed()) { - double[] matrix = new double[6]; - getTransform().getMatrix(matrix); - writeln(""); //$NON-NLS-1$ - } - } - - @SuppressWarnings("nls") - @Override - protected void writeHeader() { - Rectangle2D bounds = getBounds(); - double x = bounds.getX(); - double y = bounds.getY(); - double w = bounds.getWidth(); - double h = bounds.getHeight(); - writeln(""); - writeln(""); - writeln(""); - writeln(""); - } - - @Override - protected void writeClosingDraw(Shape s) { - write("style=\"fill:none;stroke:", getSvg(getColor())); //$NON-NLS-1$ - if (getStroke() instanceof BasicStroke) { - BasicStroke stroke = (BasicStroke) getStroke(); - if (stroke.getLineWidth() != 1f) { - write(";stroke-width:", stroke.getLineWidth()); //$NON-NLS-1$ - } - if (stroke.getEndCap() != BasicStroke.CAP_BUTT) { - write(";stroke-linecap:", //$NON-NLS-1$ - STROKE_ENDCAPS.get(stroke.getEndCap())); - } - if (stroke.getLineJoin() != BasicStroke.JOIN_MITER) { - write(";stroke-linejoin:", //$NON-NLS-1$ - STROKE_LINEJOIN.get(stroke.getLineJoin())); - } - // write(";stroke-miterlimit:", s.getMiterLimit()); - if (stroke.getDashArray() != null - && stroke.getDashArray().length > 0) { - write(";stroke-dasharray:", //$NON-NLS-1$ - DataUtils.join(",", stroke.getDashArray())); //$NON-NLS-1$ - write(";stroke-dashoffset:", stroke.getDashPhase()); //$NON-NLS-1$ - } - } - if (getClip() != null) { - write("\" clip-path=\"url(#", getClipId(), ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } - writeln("\" />"); //$NON-NLS-1$ - } - - @Override - protected void writeClosingFill(Shape s) { - if (getPaint() instanceof Color) { - write("style=\"fill:", getSvg(getColor()), ";stroke:none"); //$NON-NLS-1$ //$NON-NLS-2$ - if (getClip() != null) { - write("\" clip-path=\"url(#", getClipId(), ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } - writeln("\" />"); //$NON-NLS-1$ - } else { - write("style=\"stroke:none\" />"); //$NON-NLS-1$ - super.writeClosingFill(s); - } - } - - @Override - protected void writeShape(Shape s) { - writeClip(); - writeUnclippedShape(s); - } - - /** - * Returns the id of the current clipping path. - * - * @return id string of the current clipping path. - */ - private String getClipId() { - return CLIP_PATH_ID + clipCounter; - } - - /** - * Generates a new id for a clipping path. - * - * @return id string of the next clipping path. - */ - private String nextClipId() { - clipCounter++; - return getClipId(); - } - - /** - * Writes the current clipping path. - */ - private void writeClip() { - Shape clip = getClip(); - if (clip == null) { - return; - } - write(""); //$NON-NLS-1$ //$NON-NLS-2$ - writeUnclippedShape(clip); - write("/>"); //$NON-NLS-1$ - writeln(""); //$NON-NLS-1$ - } - - /** - * Writes the specified shape without clipping path information. - * - * @param s - * Shape to be written. - */ - @SuppressWarnings("nls") - private void writeUnclippedShape(Shape s) { - if (s instanceof Line2D) { - Line2D l = (Line2D) s; - double x1 = l.getX1(); - double y1 = l.getY1(); - double x2 = l.getX2(); - double y2 = l.getY2(); - write(" 0) { - write(" "); - } - int segmentType = segments.currentSegment(coords); - switch (segmentType) { - case PathIterator.SEG_MOVETO: - write("M", coords[0], ",", coords[1]); - break; - case PathIterator.SEG_LINETO: - write("L", coords[0], ",", coords[1]); - break; - case PathIterator.SEG_CUBICTO: - write("C", coords[0], ",", coords[1], " ", coords[2], ",", - coords[3], " ", coords[4], ",", coords[5]); - break; - case PathIterator.SEG_QUADTO: - write("Q", coords[0], ",", coords[1], " ", coords[2], ",", - coords[3]); - break; - case PathIterator.SEG_CLOSE: - write("Z"); - break; - default: - throw new IllegalStateException("Unknown path operation."); - } - } - } - - /** - * Converts a {@code Color} object to an SVG color statement. - * - * @param c - * Color object. - * @return String representation in SVG compatible format. - */ - private static String getSvg(Color c) { - String color = "rgb(" + c.getRed() + "," + c.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - + c.getBlue() + ")"; //$NON-NLS-1$ - if (c.getAlpha() < 255) { - double opacity = c.getAlpha() / 255.0; - color += ";opacity:" + opacity; //$NON-NLS-1$ - } - return color; - } - - /** - * Converts a {@code BufferedImage} object to an SVG base64 encoded string. - * - * @param bufferedImg - * Image object. - * @return String representation in SVG base64 format. - */ - private static String getSvg(BufferedImage bufferedImg) { - ByteArrayOutputStream data = new ByteArrayOutputStream(); - try { - ImageIO.write(bufferedImg, "png", data); //$NON-NLS-1$ - } catch (IOException e) { - return ""; //$NON-NLS-1$ - } - String dataBase64 = DatatypeConverter.printBase64Binary(data - .toByteArray()); - return "data:image/png;base64," + dataBase64; //$NON-NLS-1$ - } - - @Override - protected String getFooter() { - String footer = ""; //$NON-NLS-1$ - // Close any previous transformation groups - if (isTransformed()) { - footer += "\n"; //$NON-NLS-1$ - } - footer += "\n"; //$NON-NLS-1$ - return footer; - } - - @Override - public String toString() { - String doc = super.toString(); - doc = doc.replaceAll("\n*\n", ""); //$NON-NLS-1$ //$NON-NLS-2$ - return doc; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.de.erichseifert.vectorgraphics2d; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Image; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Map; + +import javax.imageio.ImageIO; +import javax.xml.bind.DatatypeConverter; + +import org.xmind.de.erichseifert.vectorgraphics2d.util.DataUtils; +import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; + +/** + * {@code Graphics2D} implementation that saves all operations to a string in + * the Scaled Vector Graphics (SVG) format. + * + * @author Jason Wong + */ +public class SVGGraphics2D extends VectorGraphics2D { + /** Mapping of stroke endcap values from Java to SVG. */ + private static final Map STROKE_ENDCAPS = DataUtils.map( + new Integer[] { BasicStroke.CAP_BUTT, BasicStroke.CAP_ROUND, + BasicStroke.CAP_SQUARE }, new String[] { "butt", "round", //$NON-NLS-1$ //$NON-NLS-2$ + "square" }); //$NON-NLS-1$ + + /** Mapping of line join values for path drawing from Java to SVG. */ + private static final Map STROKE_LINEJOIN = DataUtils.map( + new Integer[] { BasicStroke.JOIN_MITER, BasicStroke.JOIN_ROUND, + BasicStroke.JOIN_BEVEL }, new String[] { "miter", "round",//$NON-NLS-1$ //$NON-NLS-2$ + "bevel" });//$NON-NLS-1$ + + /** Prefix string for ids of clipping paths. */ + private static final String CLIP_PATH_ID = "clip"; //$NON-NLS-1$ + /** Number of the current clipping path. */ + private long clipCounter; + + /** + * Constructor that initializes a new {@code SVGGraphics2D} instance. The + * document dimension must be specified as parameters. + * + * @param x + * Left offset of document. + * @param y + * Top offset of document. + * @param width + * Width of document. + * @param height + * Height of document. + */ + public SVGGraphics2D(double x, double y, double width, double height) { + super(x, y, width, height); + writeHeader(); + } + + @SuppressWarnings("nls") + @Override + protected void writeString(String str, double x, double y) { + // Escape string + str = str.replaceAll("&", "&").replaceAll("<", "<") + .replaceAll(">", ">"); + + float fontSize = getFont().getSize2D(); + // float leading = getFont().getLineMetrics("", + // getFontRenderContext()).getLeading(); + + /* + * // Extract lines String[] lines = str.replaceAll("\r\n", + * "\n").replaceAll("\r", "\n").split("\n"); + * + * // Output lines writeln(""); for (int i = 0; i < lines.length; i++) + * { String line = lines[i]; writeln(" 0) ? leading : 0f), "\">", line, ""); } + * writeln(""); + */ + + str = str.replaceAll("[\r\n]", ""); + writeln("", str, ""); + } + + @SuppressWarnings("nls") + @Override + protected void writeImage(Image img, int imgWidth, int imgHeight, double x, + double y, double width, double height) { + BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); + String imgData = getSvg(bufferedImg); + write(""); //$NON-NLS-1$ + } + + @Override + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + Path2D s = new Path2D.Double(Path2D.WIND_NON_ZERO, xPoints.length); + write(""); //$NON-NLS-1$ + } + // Set transformation matrix + super.setAffineTransform(tx); + // Begin new transformation group + if (isTransformed()) { + double[] matrix = new double[6]; + getTransform().getMatrix(matrix); + writeln(""); //$NON-NLS-1$ + } + } + + @SuppressWarnings("nls") + @Override + protected void writeHeader() { + Rectangle2D bounds = getBounds(); + double x = bounds.getX(); + double y = bounds.getY(); + double w = bounds.getWidth(); + double h = bounds.getHeight(); + writeln(""); + writeln(""); + writeln(""); + writeln(""); + } + + @Override + protected void writeClosingDraw(Shape s) { + write("style=\"fill:none;stroke:", getSvg(getColor())); //$NON-NLS-1$ + if (getStroke() instanceof BasicStroke) { + BasicStroke stroke = (BasicStroke) getStroke(); + if (stroke.getLineWidth() != 1f) { + write(";stroke-width:", stroke.getLineWidth()); //$NON-NLS-1$ + } + if (stroke.getEndCap() != BasicStroke.CAP_BUTT) { + write(";stroke-linecap:", //$NON-NLS-1$ + STROKE_ENDCAPS.get(stroke.getEndCap())); + } + if (stroke.getLineJoin() != BasicStroke.JOIN_MITER) { + write(";stroke-linejoin:", //$NON-NLS-1$ + STROKE_LINEJOIN.get(stroke.getLineJoin())); + } + // write(";stroke-miterlimit:", s.getMiterLimit()); + if (stroke.getDashArray() != null + && stroke.getDashArray().length > 0) { + write(";stroke-dasharray:", //$NON-NLS-1$ + DataUtils.join(",", stroke.getDashArray())); //$NON-NLS-1$ + write(";stroke-dashoffset:", stroke.getDashPhase()); //$NON-NLS-1$ + } + } + if (getClip() != null) { + write("\" clip-path=\"url(#", getClipId(), ")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + writeln("\" />"); //$NON-NLS-1$ + } + + @Override + protected void writeClosingFill(Shape s) { + if (getPaint() instanceof Color) { + write("style=\"fill:", getSvg(getColor()), ";stroke:none"); //$NON-NLS-1$ //$NON-NLS-2$ + if (getClip() != null) { + write("\" clip-path=\"url(#", getClipId(), ")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + writeln("\" />"); //$NON-NLS-1$ + } else { + write("style=\"stroke:none\" />"); //$NON-NLS-1$ + super.writeClosingFill(s); + } + } + + @Override + protected void writeShape(Shape s) { + writeClip(); + writeUnclippedShape(s); + } + + /** + * Returns the id of the current clipping path. + * + * @return id string of the current clipping path. + */ + private String getClipId() { + return CLIP_PATH_ID + clipCounter; + } + + /** + * Generates a new id for a clipping path. + * + * @return id string of the next clipping path. + */ + private String nextClipId() { + clipCounter++; + return getClipId(); + } + + /** + * Writes the current clipping path. + */ + private void writeClip() { + Shape clip = getClip(); + if (clip == null) { + return; + } + write(""); //$NON-NLS-1$ //$NON-NLS-2$ + writeUnclippedShape(clip); + write("/>"); //$NON-NLS-1$ + writeln(""); //$NON-NLS-1$ + } + + /** + * Writes the specified shape without clipping path information. + * + * @param s + * Shape to be written. + */ + @SuppressWarnings("nls") + private void writeUnclippedShape(Shape s) { + if (s instanceof Line2D) { + Line2D l = (Line2D) s; + double x1 = l.getX1(); + double y1 = l.getY1(); + double x2 = l.getX2(); + double y2 = l.getY2(); + write(" 0) { + write(" "); + } + int segmentType = segments.currentSegment(coords); + switch (segmentType) { + case PathIterator.SEG_MOVETO: + write("M", coords[0], ",", coords[1]); + break; + case PathIterator.SEG_LINETO: + write("L", coords[0], ",", coords[1]); + break; + case PathIterator.SEG_CUBICTO: + write("C", coords[0], ",", coords[1], " ", coords[2], ",", + coords[3], " ", coords[4], ",", coords[5]); + break; + case PathIterator.SEG_QUADTO: + write("Q", coords[0], ",", coords[1], " ", coords[2], ",", + coords[3]); + break; + case PathIterator.SEG_CLOSE: + write("Z"); + break; + default: + throw new IllegalStateException("Unknown path operation."); + } + } + } + + /** + * Converts a {@code Color} object to an SVG color statement. + * + * @param c + * Color object. + * @return String representation in SVG compatible format. + */ + private static String getSvg(Color c) { + String color = "rgb(" + c.getRed() + "," + c.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + c.getBlue() + ")"; //$NON-NLS-1$ + if (c.getAlpha() < 255) { + double opacity = c.getAlpha() / 255.0; + color += ";opacity:" + opacity; //$NON-NLS-1$ + } + return color; + } + + /** + * Converts a {@code BufferedImage} object to an SVG base64 encoded string. + * + * @param bufferedImg + * Image object. + * @return String representation in SVG base64 format. + */ + private static String getSvg(BufferedImage bufferedImg) { + ByteArrayOutputStream data = new ByteArrayOutputStream(); + try { + ImageIO.write(bufferedImg, "png", data); //$NON-NLS-1$ + } catch (IOException e) { + return ""; //$NON-NLS-1$ + } + String dataBase64 = DatatypeConverter.printBase64Binary(data + .toByteArray()); + return "data:image/png;base64," + dataBase64; //$NON-NLS-1$ + } + + @Override + protected String getFooter() { + String footer = ""; //$NON-NLS-1$ + // Close any previous transformation groups + if (isTransformed()) { + footer += "\n"; //$NON-NLS-1$ + } + footer += "\n"; //$NON-NLS-1$ + return footer; + } + + @Override + public String toString() { + String doc = super.toString(); + doc = doc.replaceAll("\n*\n", ""); //$NON-NLS-1$ //$NON-NLS-2$ + return doc; + } + +} diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/VectorGraphics2D.java b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/VectorGraphics2D.java index f9d0edf3d..0b7b6995b 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/VectorGraphics2D.java +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/VectorGraphics2D.java @@ -1,1016 +1,1016 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.de.erichseifert.vectorgraphics2d; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.MultipleGradientPaint; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Area; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.io.UnsupportedEncodingException; -import java.text.AttributedCharacterIterator; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; - -/** - * Base for classed that want to implement vector export. - * - * @author Jason Wong - */ -public abstract class VectorGraphics2D extends Graphics2D { - /** Constants to define how fonts are rendered. */ - public static enum FontRendering { - /** - * Constant indicating that fonts should be rendered as text objects. - */ - TEXT, - /** Constant indicating that fonts should be converted to vectors. */ - VECTORS - } - - /** Maximal resolution for image rastering. */ - private static final int DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM = 128; - - /** Document contents. */ - private final StringBuffer document; - /** Rectangular bounds of the documents. */ - private final Rectangle2D bounds; - /** Resolution in dots per inch that is used to raster paints. */ - private double resolution; - /** Maximal size of images that are used to raster paints. */ - private int rasteredImageSizeMaximum; - /** Font rendering mode. */ - private FontRendering fontRendering; - /** Flag that stores whether affine transformations have been applied. */ - private boolean transformed; - - /** Rendering hints. */ - private final RenderingHints hints; - /** Current background color. */ - private Color background; - /** Current foreground color. */ - private Color color; - /** Shape used for clipping paint operations. */ - private Shape clip; - /** Method used for compositing. */ - private Composite composite; - /** Device configuration settings. */ - private final GraphicsConfiguration deviceConfig; - /** Current font. */ - private Font font; - /** Context settings used to render fonts. */ - private final FontRenderContext fontRenderContext; - /** Paint used to fill shapes. */ - private Paint paint; - /** Stroke used for drawing shapes. */ - private Stroke stroke; - /** Current transformation matrix. */ - private final AffineTransform transform; - /** XOR mode used for rendering. */ - private Color xorMode; - - /** - * Constructor to initialize a new {@code VectorGraphics2D} document. The - * dimensions of the document must be passed. - * - * @param x - * Horizontal position of document origin. - * @param y - * Vertical position of document origin. - * @param width - * Width of document. - * @param height - * Height of document. - */ - public VectorGraphics2D(double x, double y, double width, double height) { - hints = new RenderingHints(new HashMap()); - document = new StringBuffer(); - bounds = new Rectangle2D.Double(x, y, width, height); - fontRendering = FontRendering.TEXT; - resolution = 72.0; - rasteredImageSizeMaximum = DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM; - - background = Color.WHITE; - color = Color.BLACK; - composite = AlphaComposite.getInstance(AlphaComposite.CLEAR); - deviceConfig = null; - font = Font.decode(null); - fontRenderContext = new FontRenderContext(null, false, true); - paint = color; - stroke = new BasicStroke(1f); - transform = new AffineTransform(); - transformed = false; - xorMode = Color.BLACK; - } - - @Override - public void addRenderingHints(Map hints) { - this.hints.putAll(hints); - } - - @Override - public void clip(Shape s) { - if ((getClip() != null) && (s != null)) { - Area clipAreaOld = new Area(getClip()); - Area clipAreaNew = new Area(s); - clipAreaNew.intersect(clipAreaOld); - s = clipAreaNew; - } - setClip(s); - } - - @Override - public void draw(Shape s) { - writeShape(s); - writeClosingDraw(s); - } - - @Override - public void drawGlyphVector(GlyphVector g, float x, float y) { - draw(g.getOutline(x, y)); - } - - @Override - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - BufferedImage bimg = getTransformedImage(img, xform); - drawImage(bimg, null, bimg.getMinX(), bimg.getMinY()); - return true; - } - - /** - * Returns a transformed version of an image. - * - * @param image - * Image to be transformed - * @param xform - * Affine transform to be applied - * @return Image with transformed content - */ - private BufferedImage getTransformedImage(Image image, AffineTransform xform) { - Integer interpolationType = (Integer) hints - .get(RenderingHints.KEY_INTERPOLATION); - if (RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR - .equals(interpolationType)) { - interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; - } else if (RenderingHints.VALUE_INTERPOLATION_BILINEAR - .equals(interpolationType)) { - interpolationType = AffineTransformOp.TYPE_BILINEAR; - } else { - interpolationType = AffineTransformOp.TYPE_BICUBIC; - } - AffineTransformOp op = new AffineTransformOp(xform, interpolationType); - BufferedImage bufferedImage = GraphicsUtils.toBufferedImage(image); - return op.filter(bufferedImage, null); - } - - @Override - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { - if (op != null) { - img = op.filter(img, null); - } - drawImage(img, x, y, img.getWidth(), img.getHeight(), null); - } - - @Override - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - drawRenderedImage(img.createDefaultRendering(), xform); - } - - @Override - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - BufferedImage bimg = GraphicsUtils.toBufferedImage(img); - drawImage(bimg, xform, null); - } - - @Override - public void drawString(String str, int x, int y) { - drawString(str, (float) x, (float) y); - } - - @Override - public void drawString(String str, float x, float y) { - if (str != null && str.trim().isEmpty()) { - return; - } - switch (getFontRendering()) { - case VECTORS: - TextLayout layout = new TextLayout(str, getFont(), - getFontRenderContext()); - Shape s = layout.getOutline(AffineTransform.getTranslateInstance(x, - y)); - fill(s); - break; - case TEXT: - writeString(str, x, y); - break; - default: - throw new IllegalStateException("Unknown font rendering mode."); //$NON-NLS-1$ - } - } - - @Override - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - drawString(iterator, (float) x, (float) y); - } - - @Override - public void drawString(AttributedCharacterIterator iterator, float x, - float y) { - // TODO Take text formatting into account - StringBuffer buf = new StringBuffer(); - for (char c = iterator.first(); c != AttributedCharacterIterator.DONE; c = iterator - .next()) { - buf.append(c); - } - drawString(buf.toString(), x, y); - } - - @Override - public void fill(Shape s) { - writeShape(s); - writeClosingFill(s); - } - - @Override - public Color getBackground() { - return background; - } - - @Override - public Composite getComposite() { - return composite; - } - - @Override - public GraphicsConfiguration getDeviceConfiguration() { - return deviceConfig; - } - - @Override - public FontRenderContext getFontRenderContext() { - return fontRenderContext; - } - - @Override - public Paint getPaint() { - return paint; - } - - @Override - public Object getRenderingHint(RenderingHints.Key hintKey) { - if (RenderingHints.KEY_ANTIALIASING.equals(hintKey)) { - return RenderingHints.VALUE_ANTIALIAS_OFF; - } else if (RenderingHints.KEY_TEXT_ANTIALIASING.equals(hintKey)) { - return RenderingHints.VALUE_TEXT_ANTIALIAS_OFF; - } else if (RenderingHints.KEY_FRACTIONALMETRICS.equals(hintKey)) { - return RenderingHints.VALUE_FRACTIONALMETRICS_ON; - } - return hints.get(hintKey); - } - - @Override - public RenderingHints getRenderingHints() { - return hints; - } - - @Override - public Stroke getStroke() { - return stroke; - } - - @Override - public boolean hit(Rectangle rect, Shape s, boolean onStroke) { - if (onStroke) { - Shape sStroke = getStroke().createStrokedShape(s); - return sStroke.intersects(rect); - } else { - return s.intersects(rect); - } - } - - @Override - public void setBackground(Color color) { - background = color; - } - - @Override - public void setComposite(Composite comp) { - composite = comp; - } - - @Override - public void setPaint(Paint paint) { - if (paint != null) { - this.paint = paint; - if (paint instanceof Color) { - setColor((Color) paint); - } else if (paint instanceof MultipleGradientPaint) { - // Set brightest or least opaque color for gradients - Color[] colors = ((MultipleGradientPaint) paint).getColors(); - if (colors.length == 1) { - setColor(colors[0]); - } else if (colors.length > 1) { - Color colLight = colors[0]; - float brightness = getBrightness(colLight); - int alpha = colLight.getAlpha(); - - for (int i = 1; i < colors.length; i++) { - Color c = colors[i]; - float b = getBrightness(c); - int a = c.getAlpha(); - if (b < brightness || a < alpha) { - colLight = c; - brightness = b; - } - } - setColor(colLight); - } - } - } - } - - /** - * Utility method to get the brightness of a specified color. - * - * @param c - * Color. - * @return Brightness value between 0f (black) and 1f (white). - */ - private static float getBrightness(Color c) { - return Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null)[2]; - } - - @Override - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { - hints.put(hintKey, hintValue); - } - - @Override - public void setRenderingHints(Map hints) { - this.hints.putAll(hints); - } - - @Override - public void setStroke(Stroke s) { - stroke = s; - } - - @Override - public AffineTransform getTransform() { - return new AffineTransform(transform); - } - - @Override - public void setTransform(AffineTransform tx) { - setAffineTransform(tx); - } - - /** - * Sets the current transformation. - * - * @param tx - * Current transformation - */ - protected void setAffineTransform(AffineTransform tx) { - if (!transform.equals(tx)) { - transform.setTransform(tx); - transformed = true; - } - } - - @Override - public void shear(double shx, double shy) { - AffineTransform transform = getTransform(); - transform.shear(shx, shy); - setAffineTransform(transform); - } - - @Override - public void transform(AffineTransform tx) { - AffineTransform transform = getTransform(); - transform.concatenate(tx); - setAffineTransform(transform); - } - - @Override - public void translate(int x, int y) { - translate((double) x, (double) y); - } - - @Override - public void translate(double tx, double ty) { - AffineTransform transform = getTransform(); - transform.translate(tx, ty); - setAffineTransform(transform); - } - - @Override - public void rotate(double theta) { - AffineTransform transform = getTransform(); - transform.rotate(theta); - setAffineTransform(transform); - } - - @Override - public void rotate(double theta, double x, double y) { - AffineTransform transform = getTransform(); - transform.rotate(theta, x, y); - setAffineTransform(transform); - } - - @Override - public void scale(double sx, double sy) { - AffineTransform transform = getTransform(); - transform.scale(sx, sy); - setAffineTransform(transform); - } - - @Override - public void clearRect(int x, int y, int width, int height) { - // TODO Implement - // throw new - // UnsupportedOperationException("clearRect() isn't supported by VectorGraphics2D."); - } - - @Override - public void clipRect(int x, int y, int width, int height) { - clip(new Rectangle(x, y, width, height)); - } - - @Override - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - // TODO Implement - // throw new - // UnsupportedOperationException("copyArea() isn't supported by VectorGraphics2D."); - } - - @Override - public Graphics create() { - // TODO Implement - return this; - } - - @Override - public void dispose() { - // TODO Implement - } - - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, - Arc2D.OPEN)); - } - - @Override - public boolean drawImage(Image img, int x, int y, ImageObserver observer) { - return drawImage(img, x, y, img.getWidth(observer), - img.getHeight(observer), observer); - } - - @Override - public boolean drawImage(Image img, int x, int y, Color bgcolor, - ImageObserver observer) { - return drawImage(img, x, y, img.getWidth(observer), - img.getHeight(observer), observer); - } - - @Override - public boolean drawImage(Image img, int x, int y, int width, int height, - ImageObserver observer) { - int imgWidth = img.getWidth(observer); - int imgHeight = img.getHeight(observer); - writeImage(img, imgWidth, imgHeight, x, y, width, height); - return true; // TODO Return only true if image data was complete - } - - @Override - public boolean drawImage(Image img, int x, int y, int width, int height, - Color bgcolor, ImageObserver observer) { - return drawImage(img, x, y, width, height, observer); - } - - @Override - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - if (img == null) { - return true; - } - - int sx = Math.min(sx1, sx2); - int sy = Math.min(sy1, sy2); - int sw = Math.abs(sx2 - sx1); - int sh = Math.abs(sy2 - sy1); - int dx = Math.min(dx1, dx2); - int dy = Math.min(dy1, dy2); - int dw = Math.abs(dx2 - dx1); - int dh = Math.abs(dy2 - dy1); - - // Draw image - BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); - Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh); - return drawImage(cropped, dx, dy, dw, dh, observer); - } - - @Override - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, Color bgcolor, - ImageObserver observer) { - if (img == null) { - return true; - } - - int sx = Math.min(sx1, sx2); - int sy = Math.min(sy1, sy2); - int sw = Math.abs(sx2 - sx1); - int sh = Math.abs(sy2 - sy1); - int dx = Math.min(dx1, dx2); - int dy = Math.min(dy1, dy2); - int dw = Math.abs(dx2 - dx1); - int dh = Math.abs(dy2 - dy1); - - // Fill Rectangle with bgcolor - Color bgcolorOld = getColor(); - setColor(bgcolor); - fill(new Rectangle(dx, dy, dw, dh)); - setColor(bgcolorOld); - - // Draw image on rectangle - BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); - Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh); - return drawImage(cropped, dx, dy, dw, dh, observer); - } - - @Override - public void drawLine(int x1, int y1, int x2, int y2) { - draw(new Line2D.Double(x1, y1, x2, y2)); - } - - @Override - public void drawOval(int x, int y, int width, int height) { - draw(new Ellipse2D.Double(x, y, width, height)); - } - - @Override - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { - Path2D p = new Path2D.Float(); - for (int i = 0; i < nPoints; i++) { - if (i > 0) { - p.lineTo(xPoints[i], yPoints[i]); - } else { - p.moveTo(xPoints[i], yPoints[i]); - } - } - p.closePath(); - draw(p); - } - - @Override - public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { - Path2D p = new Path2D.Float(); - for (int i = 0; i < nPoints; i++) { - if (i > 0) { - p.lineTo(xPoints[i], yPoints[i]); - } else { - p.moveTo(xPoints[i], yPoints[i]); - } - } - draw(p); - } - - @Override - public void drawRect(int x, int y, int width, int height) { - draw(new Rectangle2D.Double(x, y, width, height)); - } - - @Override - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth, - arcHeight)); - } - - @Override - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, - Arc2D.PIE)); - } - - @Override - public void fillOval(int x, int y, int width, int height) { - fill(new Ellipse2D.Double(x, y, width, height)); - } - - @Override - public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { - Path2D p = new Path2D.Float(); - for (int i = 0; i < nPoints; i++) { - if (i > 0) { - p.lineTo(xPoints[i], yPoints[i]); - } else { - p.moveTo(xPoints[i], yPoints[i]); - } - } - p.closePath(); - - fill(p); - } - - @Override - public void fillRect(int x, int y, int width, int height) { - fill(new Rectangle2D.Double(x, y, width, height)); - } - - @Override - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth, - arcHeight)); - } - - @Override - public Shape getClip() { - Shape clip = this.clip; - if (clip != null) { - try { - clip = transform.createInverse().createTransformedShape( - this.clip); - } catch (NoninvertibleTransformException e) { - clip = null; - } - } - return clip; - } - - @Override - public Rectangle getClipBounds() { - if (getClip() == null) { - return null; - } - return getClip().getBounds(); - } - - @Override - public Color getColor() { - return color; - } - - @Override - public Font getFont() { - return font; - } - - @Override - public FontMetrics getFontMetrics(Font f) { - // TODO Find a better way for creating a new FontMetrics instance - BufferedImage bi = new BufferedImage(1, 1, - BufferedImage.TYPE_INT_ARGB_PRE); - Graphics g = bi.getGraphics(); - FontMetrics fontMetrics = g.getFontMetrics(getFont()); - g.dispose(); - bi = null; - return fontMetrics; - } - - @Override - public void setClip(Shape clip) { - if (clip != null) { - this.clip = transform.createTransformedShape(clip); - } else { - this.clip = null; - } - } - - @Override - public void setClip(int x, int y, int width, int height) { - setClip(new Rectangle(x, y, width, height)); - } - - @Override - public void setColor(Color c) { - color = c; - } - - @Override - public void setFont(Font font) { - if (!this.font.equals(font)) { - this.font = font; - } - } - - @Override - public void setPaintMode() { - // TODO Implement - // throw new - // UnsupportedOperationException("setPaintMode() isn't supported."); - } - - @Override - public void setXORMode(Color c1) { - xorMode = c1; - } - - /** - * Utility method for writing multiple objects to the SVG document. - * - * @param strs - * Objects to be written - */ - protected void write(Object... strs) { - for (Object o : strs) { - String str = o.toString(); - if ((o instanceof Double) || (o instanceof Float)) { - str = String.format(Locale.ENGLISH, "%.7f", o).replaceAll( //$NON-NLS-1$ - "\\.?0+$", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - document.append(str); - } - } - - /** - * Utility method for writing a line of multiple objects to the SVG - * document. - * - * @param strs - * Objects to be written - */ - protected void writeln(Object... strs) { - write(strs); - write("\n"); //$NON-NLS-1$ - } - - /** - * Write the specified shape to the document. This does not necessarily - * contain the actual command to paint the shape. - * - * @param s - * Shape to be written. - */ - protected abstract void writeShape(Shape s); - - /** - * Write the specified image to the document. A number of dimensions will - * specify how the image will be placed in the document. - * - * @param img - * Image to be rendered. - * @param imgWidth - * Number of pixels in horizontal direction. - * @param imgHeight - * Number of pixels in vertical direction - * @param x - * Horizontal position in document units where the upper left - * corner of the image should be placed. - * @param y - * Vertical position in document units where the upper left - * corner of the image should be placed. - * @param width - * Width of the image in document units. - * @param height - * Height of the image in document units. - */ - protected abstract void writeImage(Image img, int imgWidth, int imgHeight, - double x, double y, double width, double height); - - /** - * Write a text string to the document at a specified position. - * - * @param str - * Text to be rendered. - * @param x - * Horizontal position in document units. - * @param y - * Vertical position in document units. - */ - protected abstract void writeString(String str, double x, double y); - - /** - * Write a command to draw the outline of a previously inserted shape. - * - * @param s - * Shape that should be drawn. - */ - protected abstract void writeClosingDraw(Shape s); - - /** - * Write a command to fill the outline of a previously inserted shape. - * - * @param s - * Shape that should be filled. - */ - protected void writeClosingFill(Shape s) { - Rectangle2D shapeBounds = s.getBounds2D(); - - // Calculate dimensions of shape with current transformations - int wImage = (int) Math.ceil(shapeBounds.getWidth() * getResolution()); - int hImage = (int) Math.ceil(shapeBounds.getHeight() * getResolution()); - // Limit the size of images - wImage = Math.min(wImage, rasteredImageSizeMaximum); - hImage = Math.min(hImage, rasteredImageSizeMaximum); - - // Create image to paint draw gradient with current transformations - BufferedImage paintImage = new BufferedImage(wImage, hImage, - BufferedImage.TYPE_INT_ARGB); - // Paint shape - Graphics2D g = (Graphics2D) paintImage.getGraphics(); - g.scale(wImage / shapeBounds.getWidth(), - hImage / shapeBounds.getHeight()); - g.translate(-shapeBounds.getX(), -shapeBounds.getY()); - g.setPaint(getPaint()); - g.fill(s); - // Free resources - g.dispose(); - - // Output image of gradient - writeImage(paintImage, wImage, hImage, shapeBounds.getX(), - shapeBounds.getY(), shapeBounds.getWidth(), - shapeBounds.getHeight()); - } - - /** - * Write the header to start a new document. - */ - protected abstract void writeHeader(); - - /** - * Returns a string of the footer to end a document. - */ - protected abstract String getFooter(); - - /** - * Returns whether a distorting transformation has been applied to the - * document. - * - * @return {@code true} if the document is distorted, otherwise - * {@code false}. - */ - protected boolean isDistorted() { - if (!isTransformed()) { - return false; - } - int type = transform.getType(); - int otherButTranslatedOrScaled = ~(AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_MASK_SCALE); - return (type & otherButTranslatedOrScaled) != 0; - } - - @Override - public String toString() { - return document.toString() + getFooter(); - } - - protected StringBuffer getDocument() { - return document; - } - - /** - * Encodes the painted data into a sequence of bytes. - * - * @return A byte array containing the data in the current file format. - */ - public byte[] getBytes() { - try { - return toString().getBytes("UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - return toString().getBytes(); - } - } - - /** - * Returns the dimensions of the document. - * - * @return dimensions of the document. - */ - public Rectangle2D getBounds() { - Rectangle2D b = new Rectangle2D.Double(); - b.setFrame(bounds); - return b; - } - - /** - * Returns the number of bytes of the document. - * - * @return size of the document in bytes. - */ - protected int size() { - return document.length(); - } - - /** - * Returns how fonts should be rendered. - * - * @return Font rendering mode. - */ - public FontRendering getFontRendering() { - return fontRendering; - } - - /** - * Sets how fonts should be rendered. For example, they can be converted to - * vector shapes. - * - * @param mode - * New font rendering mode. - */ - public void setFontRendering(FontRendering mode) { - fontRendering = mode; - } - - /** - * Returns whether an affine transformation like translation, scaling, - * rotation or shearing has been applied to this graphics instance. - * - * @return {@code true} if the instance has been transformed, {@code false} - * otherwise - */ - protected boolean isTransformed() { - return transformed; - } - - /** - * Returns the resolution in pixels per inch. - * - * @return Resolution in pixels per inch. - */ - public double getResolution() { - return resolution; - } - - /** - * Sets the resolution in pixels per inch. - * - * @param resolution - * New resolution in pixels per inch. - */ - public void setResolution(double resolution) { - if (resolution <= 0.0) { - throw new IllegalArgumentException( - "Only positive non-zero values allowed"); //$NON-NLS-1$ - } - this.resolution = resolution; - } - - /** - * Returns the maximal size of images which are used to raster paints like - * e.g. gradients, or patterns. The default value is 128. - * - * @return Current maximal image size in pixels. - */ - public int getRasteredImageSizeMaximum() { - return rasteredImageSizeMaximum; - } - - /** - * Sets the maximal size of images which are used to raster paints like e.g. - * gradients, or patterns. - * - * @param paintImageSizeMaximum - * New maximal image size in pixels. - */ - public void setRasteredImageSizeMaximum(int paintImageSizeMaximum) { - this.rasteredImageSizeMaximum = paintImageSizeMaximum; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.de.erichseifert.vectorgraphics2d; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.MultipleGradientPaint; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.io.UnsupportedEncodingException; +import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.xmind.de.erichseifert.vectorgraphics2d.util.GraphicsUtils; + +/** + * Base for classed that want to implement vector export. + * + * @author Jason Wong + */ +public abstract class VectorGraphics2D extends Graphics2D { + /** Constants to define how fonts are rendered. */ + public static enum FontRendering { + /** + * Constant indicating that fonts should be rendered as text objects. + */ + TEXT, + /** Constant indicating that fonts should be converted to vectors. */ + VECTORS + } + + /** Maximal resolution for image rastering. */ + private static final int DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM = 128; + + /** Document contents. */ + private final StringBuffer document; + /** Rectangular bounds of the documents. */ + private final Rectangle2D bounds; + /** Resolution in dots per inch that is used to raster paints. */ + private double resolution; + /** Maximal size of images that are used to raster paints. */ + private int rasteredImageSizeMaximum; + /** Font rendering mode. */ + private FontRendering fontRendering; + /** Flag that stores whether affine transformations have been applied. */ + private boolean transformed; + + /** Rendering hints. */ + private final RenderingHints hints; + /** Current background color. */ + private Color background; + /** Current foreground color. */ + private Color color; + /** Shape used for clipping paint operations. */ + private Shape clip; + /** Method used for compositing. */ + private Composite composite; + /** Device configuration settings. */ + private final GraphicsConfiguration deviceConfig; + /** Current font. */ + private Font font; + /** Context settings used to render fonts. */ + private final FontRenderContext fontRenderContext; + /** Paint used to fill shapes. */ + private Paint paint; + /** Stroke used for drawing shapes. */ + private Stroke stroke; + /** Current transformation matrix. */ + private final AffineTransform transform; + /** XOR mode used for rendering. */ + private Color xorMode; + + /** + * Constructor to initialize a new {@code VectorGraphics2D} document. The + * dimensions of the document must be passed. + * + * @param x + * Horizontal position of document origin. + * @param y + * Vertical position of document origin. + * @param width + * Width of document. + * @param height + * Height of document. + */ + public VectorGraphics2D(double x, double y, double width, double height) { + hints = new RenderingHints(new HashMap()); + document = new StringBuffer(); + bounds = new Rectangle2D.Double(x, y, width, height); + fontRendering = FontRendering.TEXT; + resolution = 72.0; + rasteredImageSizeMaximum = DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM; + + background = Color.WHITE; + color = Color.BLACK; + composite = AlphaComposite.getInstance(AlphaComposite.CLEAR); + deviceConfig = null; + font = Font.decode(null); + fontRenderContext = new FontRenderContext(null, false, true); + paint = color; + stroke = new BasicStroke(1f); + transform = new AffineTransform(); + transformed = false; + xorMode = Color.BLACK; + } + + @Override + public void addRenderingHints(Map hints) { + this.hints.putAll(hints); + } + + @Override + public void clip(Shape s) { + if ((getClip() != null) && (s != null)) { + Area clipAreaOld = new Area(getClip()); + Area clipAreaNew = new Area(s); + clipAreaNew.intersect(clipAreaOld); + s = clipAreaNew; + } + setClip(s); + } + + @Override + public void draw(Shape s) { + writeShape(s); + writeClosingDraw(s); + } + + @Override + public void drawGlyphVector(GlyphVector g, float x, float y) { + draw(g.getOutline(x, y)); + } + + @Override + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { + BufferedImage bimg = getTransformedImage(img, xform); + drawImage(bimg, null, bimg.getMinX(), bimg.getMinY()); + return true; + } + + /** + * Returns a transformed version of an image. + * + * @param image + * Image to be transformed + * @param xform + * Affine transform to be applied + * @return Image with transformed content + */ + private BufferedImage getTransformedImage(Image image, AffineTransform xform) { + Integer interpolationType = (Integer) hints + .get(RenderingHints.KEY_INTERPOLATION); + if (RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR + .equals(interpolationType)) { + interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; + } else if (RenderingHints.VALUE_INTERPOLATION_BILINEAR + .equals(interpolationType)) { + interpolationType = AffineTransformOp.TYPE_BILINEAR; + } else { + interpolationType = AffineTransformOp.TYPE_BICUBIC; + } + AffineTransformOp op = new AffineTransformOp(xform, interpolationType); + BufferedImage bufferedImage = GraphicsUtils.toBufferedImage(image); + return op.filter(bufferedImage, null); + } + + @Override + public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { + if (op != null) { + img = op.filter(img, null); + } + drawImage(img, x, y, img.getWidth(), img.getHeight(), null); + } + + @Override + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + drawRenderedImage(img.createDefaultRendering(), xform); + } + + @Override + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + BufferedImage bimg = GraphicsUtils.toBufferedImage(img); + drawImage(bimg, xform, null); + } + + @Override + public void drawString(String str, int x, int y) { + drawString(str, (float) x, (float) y); + } + + @Override + public void drawString(String str, float x, float y) { + if (str != null && str.trim().isEmpty()) { + return; + } + switch (getFontRendering()) { + case VECTORS: + TextLayout layout = new TextLayout(str, getFont(), + getFontRenderContext()); + Shape s = layout.getOutline(AffineTransform.getTranslateInstance(x, + y)); + fill(s); + break; + case TEXT: + writeString(str, x, y); + break; + default: + throw new IllegalStateException("Unknown font rendering mode."); //$NON-NLS-1$ + } + } + + @Override + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + drawString(iterator, (float) x, (float) y); + } + + @Override + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + // TODO Take text formatting into account + StringBuffer buf = new StringBuffer(); + for (char c = iterator.first(); c != AttributedCharacterIterator.DONE; c = iterator + .next()) { + buf.append(c); + } + drawString(buf.toString(), x, y); + } + + @Override + public void fill(Shape s) { + writeShape(s); + writeClosingFill(s); + } + + @Override + public Color getBackground() { + return background; + } + + @Override + public Composite getComposite() { + return composite; + } + + @Override + public GraphicsConfiguration getDeviceConfiguration() { + return deviceConfig; + } + + @Override + public FontRenderContext getFontRenderContext() { + return fontRenderContext; + } + + @Override + public Paint getPaint() { + return paint; + } + + @Override + public Object getRenderingHint(RenderingHints.Key hintKey) { + if (RenderingHints.KEY_ANTIALIASING.equals(hintKey)) { + return RenderingHints.VALUE_ANTIALIAS_OFF; + } else if (RenderingHints.KEY_TEXT_ANTIALIASING.equals(hintKey)) { + return RenderingHints.VALUE_TEXT_ANTIALIAS_OFF; + } else if (RenderingHints.KEY_FRACTIONALMETRICS.equals(hintKey)) { + return RenderingHints.VALUE_FRACTIONALMETRICS_ON; + } + return hints.get(hintKey); + } + + @Override + public RenderingHints getRenderingHints() { + return hints; + } + + @Override + public Stroke getStroke() { + return stroke; + } + + @Override + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + if (onStroke) { + Shape sStroke = getStroke().createStrokedShape(s); + return sStroke.intersects(rect); + } else { + return s.intersects(rect); + } + } + + @Override + public void setBackground(Color color) { + background = color; + } + + @Override + public void setComposite(Composite comp) { + composite = comp; + } + + @Override + public void setPaint(Paint paint) { + if (paint != null) { + this.paint = paint; + if (paint instanceof Color) { + setColor((Color) paint); + } else if (paint instanceof MultipleGradientPaint) { + // Set brightest or least opaque color for gradients + Color[] colors = ((MultipleGradientPaint) paint).getColors(); + if (colors.length == 1) { + setColor(colors[0]); + } else if (colors.length > 1) { + Color colLight = colors[0]; + float brightness = getBrightness(colLight); + int alpha = colLight.getAlpha(); + + for (int i = 1; i < colors.length; i++) { + Color c = colors[i]; + float b = getBrightness(c); + int a = c.getAlpha(); + if (b < brightness || a < alpha) { + colLight = c; + brightness = b; + } + } + setColor(colLight); + } + } + } + } + + /** + * Utility method to get the brightness of a specified color. + * + * @param c + * Color. + * @return Brightness value between 0f (black) and 1f (white). + */ + private static float getBrightness(Color c) { + return Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null)[2]; + } + + @Override + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { + hints.put(hintKey, hintValue); + } + + @Override + public void setRenderingHints(Map hints) { + this.hints.putAll(hints); + } + + @Override + public void setStroke(Stroke s) { + stroke = s; + } + + @Override + public AffineTransform getTransform() { + return new AffineTransform(transform); + } + + @Override + public void setTransform(AffineTransform tx) { + setAffineTransform(tx); + } + + /** + * Sets the current transformation. + * + * @param tx + * Current transformation + */ + protected void setAffineTransform(AffineTransform tx) { + if (!transform.equals(tx)) { + transform.setTransform(tx); + transformed = true; + } + } + + @Override + public void shear(double shx, double shy) { + AffineTransform transform = getTransform(); + transform.shear(shx, shy); + setAffineTransform(transform); + } + + @Override + public void transform(AffineTransform tx) { + AffineTransform transform = getTransform(); + transform.concatenate(tx); + setAffineTransform(transform); + } + + @Override + public void translate(int x, int y) { + translate((double) x, (double) y); + } + + @Override + public void translate(double tx, double ty) { + AffineTransform transform = getTransform(); + transform.translate(tx, ty); + setAffineTransform(transform); + } + + @Override + public void rotate(double theta) { + AffineTransform transform = getTransform(); + transform.rotate(theta); + setAffineTransform(transform); + } + + @Override + public void rotate(double theta, double x, double y) { + AffineTransform transform = getTransform(); + transform.rotate(theta, x, y); + setAffineTransform(transform); + } + + @Override + public void scale(double sx, double sy) { + AffineTransform transform = getTransform(); + transform.scale(sx, sy); + setAffineTransform(transform); + } + + @Override + public void clearRect(int x, int y, int width, int height) { + // TODO Implement + // throw new + // UnsupportedOperationException("clearRect() isn't supported by VectorGraphics2D."); + } + + @Override + public void clipRect(int x, int y, int width, int height) { + clip(new Rectangle(x, y, width, height)); + } + + @Override + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + // TODO Implement + // throw new + // UnsupportedOperationException("copyArea() isn't supported by VectorGraphics2D."); + } + + @Override + public Graphics create() { + // TODO Implement + return this; + } + + @Override + public void dispose() { + // TODO Implement + } + + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, + Arc2D.OPEN)); + } + + @Override + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + return drawImage(img, x, y, img.getWidth(observer), + img.getHeight(observer), observer); + } + + @Override + public boolean drawImage(Image img, int x, int y, Color bgcolor, + ImageObserver observer) { + return drawImage(img, x, y, img.getWidth(observer), + img.getHeight(observer), observer); + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { + int imgWidth = img.getWidth(observer); + int imgHeight = img.getHeight(observer); + writeImage(img, imgWidth, imgHeight, x, y, width, height); + return true; // TODO Return only true if image data was complete + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { + return drawImage(img, x, y, width, height, observer); + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + if (img == null) { + return true; + } + + int sx = Math.min(sx1, sx2); + int sy = Math.min(sy1, sy2); + int sw = Math.abs(sx2 - sx1); + int sh = Math.abs(sy2 - sy1); + int dx = Math.min(dx1, dx2); + int dy = Math.min(dy1, dy2); + int dw = Math.abs(dx2 - dx1); + int dh = Math.abs(dy2 - dy1); + + // Draw image + BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); + Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh); + return drawImage(cropped, dx, dy, dw, dh, observer); + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) { + if (img == null) { + return true; + } + + int sx = Math.min(sx1, sx2); + int sy = Math.min(sy1, sy2); + int sw = Math.abs(sx2 - sx1); + int sh = Math.abs(sy2 - sy1); + int dx = Math.min(dx1, dx2); + int dy = Math.min(dy1, dy2); + int dw = Math.abs(dx2 - dx1); + int dh = Math.abs(dy2 - dy1); + + // Fill Rectangle with bgcolor + Color bgcolorOld = getColor(); + setColor(bgcolor); + fill(new Rectangle(dx, dy, dw, dh)); + setColor(bgcolorOld); + + // Draw image on rectangle + BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img); + Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh); + return drawImage(cropped, dx, dy, dw, dh, observer); + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + draw(new Line2D.Double(x1, y1, x2, y2)); + } + + @Override + public void drawOval(int x, int y, int width, int height) { + draw(new Ellipse2D.Double(x, y, width, height)); + } + + @Override + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + Path2D p = new Path2D.Float(); + for (int i = 0; i < nPoints; i++) { + if (i > 0) { + p.lineTo(xPoints[i], yPoints[i]); + } else { + p.moveTo(xPoints[i], yPoints[i]); + } + } + p.closePath(); + draw(p); + } + + @Override + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + Path2D p = new Path2D.Float(); + for (int i = 0; i < nPoints; i++) { + if (i > 0) { + p.lineTo(xPoints[i], yPoints[i]); + } else { + p.moveTo(xPoints[i], yPoints[i]); + } + } + draw(p); + } + + @Override + public void drawRect(int x, int y, int width, int height) { + draw(new Rectangle2D.Double(x, y, width, height)); + } + + @Override + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth, + arcHeight)); + } + + @Override + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, + Arc2D.PIE)); + } + + @Override + public void fillOval(int x, int y, int width, int height) { + fill(new Ellipse2D.Double(x, y, width, height)); + } + + @Override + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + Path2D p = new Path2D.Float(); + for (int i = 0; i < nPoints; i++) { + if (i > 0) { + p.lineTo(xPoints[i], yPoints[i]); + } else { + p.moveTo(xPoints[i], yPoints[i]); + } + } + p.closePath(); + + fill(p); + } + + @Override + public void fillRect(int x, int y, int width, int height) { + fill(new Rectangle2D.Double(x, y, width, height)); + } + + @Override + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth, + arcHeight)); + } + + @Override + public Shape getClip() { + Shape clip = this.clip; + if (clip != null) { + try { + clip = transform.createInverse().createTransformedShape( + this.clip); + } catch (NoninvertibleTransformException e) { + clip = null; + } + } + return clip; + } + + @Override + public Rectangle getClipBounds() { + if (getClip() == null) { + return null; + } + return getClip().getBounds(); + } + + @Override + public Color getColor() { + return color; + } + + @Override + public Font getFont() { + return font; + } + + @Override + public FontMetrics getFontMetrics(Font f) { + // TODO Find a better way for creating a new FontMetrics instance + BufferedImage bi = new BufferedImage(1, 1, + BufferedImage.TYPE_INT_ARGB_PRE); + Graphics g = bi.getGraphics(); + FontMetrics fontMetrics = g.getFontMetrics(getFont()); + g.dispose(); + bi = null; + return fontMetrics; + } + + @Override + public void setClip(Shape clip) { + if (clip != null) { + this.clip = transform.createTransformedShape(clip); + } else { + this.clip = null; + } + } + + @Override + public void setClip(int x, int y, int width, int height) { + setClip(new Rectangle(x, y, width, height)); + } + + @Override + public void setColor(Color c) { + color = c; + } + + @Override + public void setFont(Font font) { + if (!this.font.equals(font)) { + this.font = font; + } + } + + @Override + public void setPaintMode() { + // TODO Implement + // throw new + // UnsupportedOperationException("setPaintMode() isn't supported."); + } + + @Override + public void setXORMode(Color c1) { + xorMode = c1; + } + + /** + * Utility method for writing multiple objects to the SVG document. + * + * @param strs + * Objects to be written + */ + protected void write(Object... strs) { + for (Object o : strs) { + String str = o.toString(); + if ((o instanceof Double) || (o instanceof Float)) { + str = String.format(Locale.ENGLISH, "%.7f", o).replaceAll( //$NON-NLS-1$ + "\\.?0+$", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + document.append(str); + } + } + + /** + * Utility method for writing a line of multiple objects to the SVG + * document. + * + * @param strs + * Objects to be written + */ + protected void writeln(Object... strs) { + write(strs); + write("\n"); //$NON-NLS-1$ + } + + /** + * Write the specified shape to the document. This does not necessarily + * contain the actual command to paint the shape. + * + * @param s + * Shape to be written. + */ + protected abstract void writeShape(Shape s); + + /** + * Write the specified image to the document. A number of dimensions will + * specify how the image will be placed in the document. + * + * @param img + * Image to be rendered. + * @param imgWidth + * Number of pixels in horizontal direction. + * @param imgHeight + * Number of pixels in vertical direction + * @param x + * Horizontal position in document units where the upper left + * corner of the image should be placed. + * @param y + * Vertical position in document units where the upper left + * corner of the image should be placed. + * @param width + * Width of the image in document units. + * @param height + * Height of the image in document units. + */ + protected abstract void writeImage(Image img, int imgWidth, int imgHeight, + double x, double y, double width, double height); + + /** + * Write a text string to the document at a specified position. + * + * @param str + * Text to be rendered. + * @param x + * Horizontal position in document units. + * @param y + * Vertical position in document units. + */ + protected abstract void writeString(String str, double x, double y); + + /** + * Write a command to draw the outline of a previously inserted shape. + * + * @param s + * Shape that should be drawn. + */ + protected abstract void writeClosingDraw(Shape s); + + /** + * Write a command to fill the outline of a previously inserted shape. + * + * @param s + * Shape that should be filled. + */ + protected void writeClosingFill(Shape s) { + Rectangle2D shapeBounds = s.getBounds2D(); + + // Calculate dimensions of shape with current transformations + int wImage = (int) Math.ceil(shapeBounds.getWidth() * getResolution()); + int hImage = (int) Math.ceil(shapeBounds.getHeight() * getResolution()); + // Limit the size of images + wImage = Math.min(wImage, rasteredImageSizeMaximum); + hImage = Math.min(hImage, rasteredImageSizeMaximum); + + // Create image to paint draw gradient with current transformations + BufferedImage paintImage = new BufferedImage(wImage, hImage, + BufferedImage.TYPE_INT_ARGB); + // Paint shape + Graphics2D g = (Graphics2D) paintImage.getGraphics(); + g.scale(wImage / shapeBounds.getWidth(), + hImage / shapeBounds.getHeight()); + g.translate(-shapeBounds.getX(), -shapeBounds.getY()); + g.setPaint(getPaint()); + g.fill(s); + // Free resources + g.dispose(); + + // Output image of gradient + writeImage(paintImage, wImage, hImage, shapeBounds.getX(), + shapeBounds.getY(), shapeBounds.getWidth(), + shapeBounds.getHeight()); + } + + /** + * Write the header to start a new document. + */ + protected abstract void writeHeader(); + + /** + * Returns a string of the footer to end a document. + */ + protected abstract String getFooter(); + + /** + * Returns whether a distorting transformation has been applied to the + * document. + * + * @return {@code true} if the document is distorted, otherwise + * {@code false}. + */ + protected boolean isDistorted() { + if (!isTransformed()) { + return false; + } + int type = transform.getType(); + int otherButTranslatedOrScaled = ~(AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_MASK_SCALE); + return (type & otherButTranslatedOrScaled) != 0; + } + + @Override + public String toString() { + return document.toString() + getFooter(); + } + + protected StringBuffer getDocument() { + return document; + } + + /** + * Encodes the painted data into a sequence of bytes. + * + * @return A byte array containing the data in the current file format. + */ + public byte[] getBytes() { + try { + return toString().getBytes("UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + return toString().getBytes(); + } + } + + /** + * Returns the dimensions of the document. + * + * @return dimensions of the document. + */ + public Rectangle2D getBounds() { + Rectangle2D b = new Rectangle2D.Double(); + b.setFrame(bounds); + return b; + } + + /** + * Returns the number of bytes of the document. + * + * @return size of the document in bytes. + */ + protected int size() { + return document.length(); + } + + /** + * Returns how fonts should be rendered. + * + * @return Font rendering mode. + */ + public FontRendering getFontRendering() { + return fontRendering; + } + + /** + * Sets how fonts should be rendered. For example, they can be converted to + * vector shapes. + * + * @param mode + * New font rendering mode. + */ + public void setFontRendering(FontRendering mode) { + fontRendering = mode; + } + + /** + * Returns whether an affine transformation like translation, scaling, + * rotation or shearing has been applied to this graphics instance. + * + * @return {@code true} if the instance has been transformed, {@code false} + * otherwise + */ + protected boolean isTransformed() { + return transformed; + } + + /** + * Returns the resolution in pixels per inch. + * + * @return Resolution in pixels per inch. + */ + public double getResolution() { + return resolution; + } + + /** + * Sets the resolution in pixels per inch. + * + * @param resolution + * New resolution in pixels per inch. + */ + public void setResolution(double resolution) { + if (resolution <= 0.0) { + throw new IllegalArgumentException( + "Only positive non-zero values allowed"); //$NON-NLS-1$ + } + this.resolution = resolution; + } + + /** + * Returns the maximal size of images which are used to raster paints like + * e.g. gradients, or patterns. The default value is 128. + * + * @return Current maximal image size in pixels. + */ + public int getRasteredImageSizeMaximum() { + return rasteredImageSizeMaximum; + } + + /** + * Sets the maximal size of images which are used to raster paints like e.g. + * gradients, or patterns. + * + * @param paintImageSizeMaximum + * New maximal image size in pixels. + */ + public void setRasteredImageSizeMaximum(int paintImageSizeMaximum) { + this.rasteredImageSizeMaximum = paintImageSizeMaximum; + } +} diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/DataUtils.java b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/DataUtils.java index 5315acb32..3c2516095 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/DataUtils.java +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/DataUtils.java @@ -1,220 +1,220 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.de.erichseifert.vectorgraphics2d.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Abstract class that contains utility functions for working with data - * collections like maps or lists. - * - * @author Jason Wong - */ -public abstract class DataUtils { - /** - * Default constructor that prevents creation of class. - */ - protected DataUtils() { - throw new UnsupportedOperationException(); - } - - /** - * Creates a mapping from two arrays, one with keys, one with values. - * - * @param - * Data type of the keys. - * @param - * Data type of the values. - * @param keys - * Array containing the keys. - * @param values - * Array containing the values. - * @return Map with keys and values from the specified arrays. - */ - public static Map map(K[] keys, V[] values) { - // Check for valid parameters - if (keys.length != values.length) { - throw new IllegalArgumentException("Cannot create a Map: " //$NON-NLS-1$ - + "The number of keys and values differs."); //$NON-NLS-1$ - } - // Fill map with keys and values - Map map = new LinkedHashMap(); - for (int i = 0; i < keys.length; i++) { - K key = keys[i]; - V value = values[i]; - map.put(key, value); - } - return map; - } - - /** - * Returns a string containing all elements concatenated by a specified - * separator. - * - * @param separator - * Separator string. - * @param elements - * List of elements that should be concatenated. - * @return a concatenated string. - */ - public static String join(String separator, List elements) { - if (elements == null || elements.size() == 0) { - return ""; //$NON-NLS-1$ - } - StringBuffer sb = new StringBuffer(elements.size() * 3); - int i = 0; - for (Object elem : elements) { - if (i++ > 0) { - sb.append(separator); - } - sb.append(format(elem)); - } - return sb.toString(); - } - - /** - * Returns a string containing all elements concatenated by a specified - * separator. - * - * @param separator - * Separator string. - * @param elements - * List of elements that should be concatenated. - * @return a concatenated string. - */ - public static String join(String separator, Object... elements) { - if (elements == null || elements.length == 0) { - return ""; //$NON-NLS-1$ - } - return join(separator, Arrays.asList(elements)); - } - - /** - * Returns a string with all float values concatenated by a specified - * separator. - * - * @param separator - * Separator string. - * @param elements - * Float array. - * @return a concatenated string. - */ - public static String join(String separator, float... elements) { - if (elements == null || elements.length == 0) { - return ""; //$NON-NLS-1$ - } - List list = new ArrayList(elements.length); - for (Float elem : elements) { - list.add(elem); - } - return join(separator, list); - } - - /** - * Returns a string with all double values concatenated by a specified - * separator. - * - * @param separator - * Separator string. - * @param elements - * Double array. - * @return a concatenated string. - */ - public static String join(String separator, double... elements) { - if (elements == null || elements.length == 0) { - return ""; //$NON-NLS-1$ - } - List list = new ArrayList(elements.length); - for (Double elem : elements) { - list.add(elem); - } - return join(separator, list); - } - - /** - * Returns the largest of all specified values. - * - * @param values - * Several integer values. - * @return largest value. - */ - public static int max(int... values) { - int max = values[0]; - for (int i = 1; i < values.length; i++) { - if (values[i] > max) { - max = values[i]; - } - } - return max; - } - - /** - * Copies data from an input stream to an output stream using a buffer of - * specified size. - * - * @param in - * Input stream. - * @param out - * Output stream. - * @param bufferSize - * Size of the copy buffer. - * @throws IOException - * when an error occurs while copying. - */ - public static void transfer(InputStream in, OutputStream out, int bufferSize) - throws IOException { - byte[] buffer = new byte[bufferSize]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - } - - /** - * Returns a formatted string of the specified number. All trailing zeroes - * or decimal points will be stripped. - * - * @param number - * Number to convert to a string. - * @return A formatted string. - */ - public static String format(Number number) { - String formatted = Double.toString(number.doubleValue()) - .replaceAll("\\.0+$", "") //$NON-NLS-1$ //$NON-NLS-2$ - .replaceAll("(\\.[0-9]*[1-9])0+$", "$1"); //$NON-NLS-1$ //$NON-NLS-2$ - return formatted; - } - - /** - * Returns a formatted string of the specified object. - * - * @param number - * Object to convert to a string. - * @return A formatted string. - */ - public static String format(Object obj) { - if (obj instanceof Number) { - return format((Number) obj); - } else { - return obj.toString(); - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.de.erichseifert.vectorgraphics2d.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Abstract class that contains utility functions for working with data + * collections like maps or lists. + * + * @author Jason Wong + */ +public abstract class DataUtils { + /** + * Default constructor that prevents creation of class. + */ + protected DataUtils() { + throw new UnsupportedOperationException(); + } + + /** + * Creates a mapping from two arrays, one with keys, one with values. + * + * @param + * Data type of the keys. + * @param + * Data type of the values. + * @param keys + * Array containing the keys. + * @param values + * Array containing the values. + * @return Map with keys and values from the specified arrays. + */ + public static Map map(K[] keys, V[] values) { + // Check for valid parameters + if (keys.length != values.length) { + throw new IllegalArgumentException("Cannot create a Map: " //$NON-NLS-1$ + + "The number of keys and values differs."); //$NON-NLS-1$ + } + // Fill map with keys and values + Map map = new LinkedHashMap(); + for (int i = 0; i < keys.length; i++) { + K key = keys[i]; + V value = values[i]; + map.put(key, value); + } + return map; + } + + /** + * Returns a string containing all elements concatenated by a specified + * separator. + * + * @param separator + * Separator string. + * @param elements + * List of elements that should be concatenated. + * @return a concatenated string. + */ + public static String join(String separator, List elements) { + if (elements == null || elements.size() == 0) { + return ""; //$NON-NLS-1$ + } + StringBuffer sb = new StringBuffer(elements.size() * 3); + int i = 0; + for (Object elem : elements) { + if (i++ > 0) { + sb.append(separator); + } + sb.append(format(elem)); + } + return sb.toString(); + } + + /** + * Returns a string containing all elements concatenated by a specified + * separator. + * + * @param separator + * Separator string. + * @param elements + * List of elements that should be concatenated. + * @return a concatenated string. + */ + public static String join(String separator, Object... elements) { + if (elements == null || elements.length == 0) { + return ""; //$NON-NLS-1$ + } + return join(separator, Arrays.asList(elements)); + } + + /** + * Returns a string with all float values concatenated by a specified + * separator. + * + * @param separator + * Separator string. + * @param elements + * Float array. + * @return a concatenated string. + */ + public static String join(String separator, float... elements) { + if (elements == null || elements.length == 0) { + return ""; //$NON-NLS-1$ + } + List list = new ArrayList(elements.length); + for (Float elem : elements) { + list.add(elem); + } + return join(separator, list); + } + + /** + * Returns a string with all double values concatenated by a specified + * separator. + * + * @param separator + * Separator string. + * @param elements + * Double array. + * @return a concatenated string. + */ + public static String join(String separator, double... elements) { + if (elements == null || elements.length == 0) { + return ""; //$NON-NLS-1$ + } + List list = new ArrayList(elements.length); + for (Double elem : elements) { + list.add(elem); + } + return join(separator, list); + } + + /** + * Returns the largest of all specified values. + * + * @param values + * Several integer values. + * @return largest value. + */ + public static int max(int... values) { + int max = values[0]; + for (int i = 1; i < values.length; i++) { + if (values[i] > max) { + max = values[i]; + } + } + return max; + } + + /** + * Copies data from an input stream to an output stream using a buffer of + * specified size. + * + * @param in + * Input stream. + * @param out + * Output stream. + * @param bufferSize + * Size of the copy buffer. + * @throws IOException + * when an error occurs while copying. + */ + public static void transfer(InputStream in, OutputStream out, int bufferSize) + throws IOException { + byte[] buffer = new byte[bufferSize]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + + /** + * Returns a formatted string of the specified number. All trailing zeroes + * or decimal points will be stripped. + * + * @param number + * Number to convert to a string. + * @return A formatted string. + */ + public static String format(Number number) { + String formatted = Double.toString(number.doubleValue()) + .replaceAll("\\.0+$", "") //$NON-NLS-1$ //$NON-NLS-2$ + .replaceAll("(\\.[0-9]*[1-9])0+$", "$1"); //$NON-NLS-1$ //$NON-NLS-2$ + return formatted; + } + + /** + * Returns a formatted string of the specified object. + * + * @param number + * Object to convert to a string. + * @return A formatted string. + */ + public static String format(Object obj) { + if (obj instanceof Number) { + return format((Number) obj); + } else { + return obj.toString(); + } + } +} diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/GraphicsUtils.java b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/GraphicsUtils.java index f6cd12530..f29a50829 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/GraphicsUtils.java +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/src/org/xmind/de/erichseifert/vectorgraphics2d/util/GraphicsUtils.java @@ -1,191 +1,191 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.de.erichseifert.vectorgraphics2d.util; - -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; -import java.awt.Image; -import java.awt.Transparency; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.PixelGrabber; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; -import java.awt.image.WritableRaster; -import java.util.Hashtable; - -import javax.swing.ImageIcon; - -/** - * Abstract class that contains utility functions for working with graphics. For - * example, this includes font handling. - * - * @author Jason Wong - */ -public abstract class GraphicsUtils { - /** - * Default constructor that prevents creation of class. - */ - protected GraphicsUtils() { - throw new UnsupportedOperationException(); - } - - /** - * This method returns {@code true} if the specified image has the - * possibility to store transparent pixels. Inspired by - * http://www.exampledepot.com/egs/java.awt.image/HasAlpha.html - * - * @param image - * Image that should be checked for alpha channel. - * @return {@code true} if the specified image can have transparent pixels, - * {@code false} otherwise - */ - public static boolean hasAlpha(Image image) { - ColorModel cm; - // If buffered image, the color model is readily available - if (image instanceof BufferedImage) { - BufferedImage bimage = (BufferedImage) image; - cm = bimage.getColorModel(); - } else { - // Use a pixel grabber to retrieve the image's color model; - // grabbing a single pixel is usually sufficient - PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); - try { - pg.grabPixels(); - } catch (InterruptedException e) { - return false; - } - // Get the image's color model - cm = pg.getColorModel(); - } - return cm.hasAlpha(); - } - - /** - * This method returns {@code true} if the specified image has at least one - * pixel that is not fully opaque. - * - * @param image - * Image that should be checked for non-opaque pixels. - * @return {@code true} if the specified image has transparent pixels, - * {@code false} otherwise - */ - public static boolean usesAlpha(Image image) { - if (image == null) { - return false; - } - BufferedImage bimage = toBufferedImage(image); - Raster alphaRaster = bimage.getAlphaRaster(); - if (alphaRaster == null) { - return false; - } - DataBuffer dataBuffer = alphaRaster.getDataBuffer(); - for (int i = 0; i < dataBuffer.getSize(); i++) { - int alpha = dataBuffer.getElem(i); - if (alpha < 255) { - return true; - } - } - return false; - } - - /** - * Converts an arbitrary image to a {@code BufferedImage}. - * - * @param image - * Image that should be converted. - * @return a buffered image containing the image pixels, or the original - * instance if the image already was of type {@code BufferedImage}. - */ - public static BufferedImage toBufferedImage(RenderedImage image) { - if (image instanceof BufferedImage) { - return (BufferedImage) image; - } - - ColorModel cm = image.getColorModel(); - WritableRaster raster = cm.createCompatibleWritableRaster( - image.getWidth(), image.getHeight()); - boolean isRasterPremultiplied = cm.isAlphaPremultiplied(); - Hashtable properties = null; - if (image.getPropertyNames() != null) { - properties = new Hashtable(); - for (String key : image.getPropertyNames()) { - properties.put(key, image.getProperty(key)); - } - } - - BufferedImage bimage = new BufferedImage(cm, raster, - isRasterPremultiplied, properties); - image.copyData(raster); - return bimage; - } - - /** - * This method returns a buffered image with the contents of an image. Taken - * from http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html - * - * @param image - * Image to be converted - * @return a buffered image with the contents of the specified image - */ - public static BufferedImage toBufferedImage(Image image) { - if (image instanceof BufferedImage) { - return (BufferedImage) image; - } - // This code ensures that all the pixels in the image are loaded - image = new ImageIcon(image).getImage(); - // Determine if the image has transparent pixels - boolean hasAlpha = hasAlpha(image); - - // Create a buffered image with a format that's compatible with the - // screen - BufferedImage bimage = null; - GraphicsEnvironment ge = GraphicsEnvironment - .getLocalGraphicsEnvironment(); - try { - // Determine the type of transparency of the new buffered image - int transparency = Transparency.OPAQUE; - if (hasAlpha) { - transparency = Transparency.TRANSLUCENT; - } - // Create the buffered image - GraphicsDevice gs = ge.getDefaultScreenDevice(); - GraphicsConfiguration gc = gs.getDefaultConfiguration(); - bimage = gc.createCompatibleImage(image.getWidth(null), - image.getHeight(null), transparency); - } catch (HeadlessException e) { - // The system does not have a screen - bimage = null; - } - if (bimage == null) { - // Create a buffered image using the default color model - int type = BufferedImage.TYPE_INT_RGB; - if (hasAlpha) { - type = BufferedImage.TYPE_INT_ARGB; - } - bimage = new BufferedImage(image.getWidth(null), - image.getHeight(null), type); - } - // Copy image to buffered image - Graphics g = bimage.createGraphics(); - // Paint the image onto the buffered image - g.drawImage(image, 0, 0, null); - g.dispose(); - return bimage; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.de.erichseifert.vectorgraphics2d.util; + +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.PixelGrabber; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.WritableRaster; +import java.util.Hashtable; + +import javax.swing.ImageIcon; + +/** + * Abstract class that contains utility functions for working with graphics. For + * example, this includes font handling. + * + * @author Jason Wong + */ +public abstract class GraphicsUtils { + /** + * Default constructor that prevents creation of class. + */ + protected GraphicsUtils() { + throw new UnsupportedOperationException(); + } + + /** + * This method returns {@code true} if the specified image has the + * possibility to store transparent pixels. Inspired by + * http://www.exampledepot.com/egs/java.awt.image/HasAlpha.html + * + * @param image + * Image that should be checked for alpha channel. + * @return {@code true} if the specified image can have transparent pixels, + * {@code false} otherwise + */ + public static boolean hasAlpha(Image image) { + ColorModel cm; + // If buffered image, the color model is readily available + if (image instanceof BufferedImage) { + BufferedImage bimage = (BufferedImage) image; + cm = bimage.getColorModel(); + } else { + // Use a pixel grabber to retrieve the image's color model; + // grabbing a single pixel is usually sufficient + PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); + try { + pg.grabPixels(); + } catch (InterruptedException e) { + return false; + } + // Get the image's color model + cm = pg.getColorModel(); + } + return cm.hasAlpha(); + } + + /** + * This method returns {@code true} if the specified image has at least one + * pixel that is not fully opaque. + * + * @param image + * Image that should be checked for non-opaque pixels. + * @return {@code true} if the specified image has transparent pixels, + * {@code false} otherwise + */ + public static boolean usesAlpha(Image image) { + if (image == null) { + return false; + } + BufferedImage bimage = toBufferedImage(image); + Raster alphaRaster = bimage.getAlphaRaster(); + if (alphaRaster == null) { + return false; + } + DataBuffer dataBuffer = alphaRaster.getDataBuffer(); + for (int i = 0; i < dataBuffer.getSize(); i++) { + int alpha = dataBuffer.getElem(i); + if (alpha < 255) { + return true; + } + } + return false; + } + + /** + * Converts an arbitrary image to a {@code BufferedImage}. + * + * @param image + * Image that should be converted. + * @return a buffered image containing the image pixels, or the original + * instance if the image already was of type {@code BufferedImage}. + */ + public static BufferedImage toBufferedImage(RenderedImage image) { + if (image instanceof BufferedImage) { + return (BufferedImage) image; + } + + ColorModel cm = image.getColorModel(); + WritableRaster raster = cm.createCompatibleWritableRaster( + image.getWidth(), image.getHeight()); + boolean isRasterPremultiplied = cm.isAlphaPremultiplied(); + Hashtable properties = null; + if (image.getPropertyNames() != null) { + properties = new Hashtable(); + for (String key : image.getPropertyNames()) { + properties.put(key, image.getProperty(key)); + } + } + + BufferedImage bimage = new BufferedImage(cm, raster, + isRasterPremultiplied, properties); + image.copyData(raster); + return bimage; + } + + /** + * This method returns a buffered image with the contents of an image. Taken + * from http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html + * + * @param image + * Image to be converted + * @return a buffered image with the contents of the specified image + */ + public static BufferedImage toBufferedImage(Image image) { + if (image instanceof BufferedImage) { + return (BufferedImage) image; + } + // This code ensures that all the pixels in the image are loaded + image = new ImageIcon(image).getImage(); + // Determine if the image has transparent pixels + boolean hasAlpha = hasAlpha(image); + + // Create a buffered image with a format that's compatible with the + // screen + BufferedImage bimage = null; + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + try { + // Determine the type of transparency of the new buffered image + int transparency = Transparency.OPAQUE; + if (hasAlpha) { + transparency = Transparency.TRANSLUCENT; + } + // Create the buffered image + GraphicsDevice gs = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gs.getDefaultConfiguration(); + bimage = gc.createCompatibleImage(image.getWidth(null), + image.getHeight(null), transparency); + } catch (HeadlessException e) { + // The system does not have a screen + bimage = null; + } + if (bimage == null) { + // Create a buffered image using the default color model + int type = BufferedImage.TYPE_INT_RGB; + if (hasAlpha) { + type = BufferedImage.TYPE_INT_ARGB; + } + bimage = new BufferedImage(image.getWidth(null), + image.getHeight(null), type); + } + // Copy image to buffered image + Graphics g = bimage.createGraphics(); + // Paint the image onto the buffered image + g.drawImage(image, 0, 0, null); + g.dispose(); + return bimage; + } +} diff --git a/bundles/org.xmind.gef.ui/.classpath b/bundles/org.xmind.gef.ui/.classpath index 1e7b269e5..757662350 100644 --- a/bundles/org.xmind.gef.ui/.classpath +++ b/bundles/org.xmind.gef.ui/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.gef.ui/.gitignore b/bundles/org.xmind.gef.ui/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.gef.ui/.gitignore +++ b/bundles/org.xmind.gef.ui/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.gef.ui/.project b/bundles/org.xmind.gef.ui/.project index bf5200d1f..0f6ab0228 100644 --- a/bundles/org.xmind.gef.ui/.project +++ b/bundles/org.xmind.gef.ui/.project @@ -1,28 +1,28 @@ - - - org.xmind.gef.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.gef.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.gef.ui/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF b/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF index 48bb24832..2ea9bc3f5 100644 --- a/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF @@ -1,25 +1,25 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.gef.ui;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.gef.ui.internal.GEFPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.core.expressions, - org.xmind.gef;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)" -Eclipse-LazyStart: true -Export-Package: org.xmind.gef.ui.actions, - org.xmind.gef.ui.editor, - org.xmind.gef.ui.internal;x-internal:=true, - org.xmind.gef.ui.outline, - org.xmind.gef.ui.properties, - org.xmind.ui.animation, - org.xmind.ui.datepicker, - org.xmind.ui.gallery, - org.xmind.ui.texteditor -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-ActivationPolicy: lazy -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.gef.ui;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.gef.ui.internal.GEFPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.expressions, + org.xmind.gef;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)" +Eclipse-LazyStart: true +Export-Package: org.xmind.gef.ui.actions, + org.xmind.gef.ui.editor, + org.xmind.gef.ui.internal;x-internal:=true, + org.xmind.gef.ui.outline, + org.xmind.gef.ui.properties, + org.xmind.ui.animation, + org.xmind.ui.datepicker, + org.xmind.ui.gallery, + org.xmind.ui.texteditor +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin diff --git a/bundles/org.xmind.gef.ui/about.html b/bundles/org.xmind.gef.ui/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.gef.ui/about.html +++ b/bundles/org.xmind.gef.ui/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.gef.ui/build.properties b/bundles/org.xmind.gef.ui/build.properties index baa36b183..f70828ba5 100644 --- a/bundles/org.xmind.gef.ui/build.properties +++ b/bundles/org.xmind.gef.ui/build.properties @@ -1,8 +1,8 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html,\ - plugin.properties,\ - plugin.xml -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + plugin.properties,\ + plugin.xml +src.includes = about.html diff --git a/bundles/org.xmind.gef.ui/plugin.properties b/bundles/org.xmind.gef.ui/plugin.properties index a9c58284e..46daca8c5 100644 --- a/bundles/org.xmind.gef.ui/plugin.properties +++ b/bundles/org.xmind.gef.ui/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.gef.ui -providerName = XMind Ltd. +#Properties file for org.xmind.gef.ui +providerName = XMind Ltd. pluginName = XMind GEF UI \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/plugin.xml b/bundles/org.xmind.gef.ui/plugin.xml index 0489ae3b6..a3614740c 100644 --- a/bundles/org.xmind.gef.ui/plugin.xml +++ b/bundles/org.xmind.gef.ui/plugin.xml @@ -1,57 +1,57 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.gef.ui/pom.xml b/bundles/org.xmind.gef.ui/pom.xml index bae503458..d63def1b1 100644 --- a/bundles/org.xmind.gef.ui/pom.xml +++ b/bundles/org.xmind.gef.ui/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.gef.ui - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.gef.ui + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ActionRegistry.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ActionRegistry.java index 6028466ff..3d5e0335b 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ActionRegistry.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ActionRegistry.java @@ -43,6 +43,11 @@ public void dispose() { ((IWorkbenchAction) action).dispose(); } } + if (actions != null) { + actions.clear(); + actions = null; + } + parent = null; } public IAction getAction(String id) { @@ -88,4 +93,4 @@ public void setParent(IActionRegistry parent) { this.parent = parent; } -} +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ICommandStackAction.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ICommandStackAction.java index 423a38472..9334bf6c9 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ICommandStackAction.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ICommandStackAction.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.actions; - -import org.xmind.gef.command.ICommandStack; - -public interface ICommandStackAction { - - void setCommandStack(ICommandStack commandStack); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.actions; + +import org.xmind.gef.command.ICommandStack; + +public interface ICommandStackAction { + + void setCommandStack(ICommandStack commandStack); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ISelectionAction.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ISelectionAction.java index 41b305d4e..2207b1c51 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ISelectionAction.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/ISelectionAction.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.actions; - -import org.eclipse.jface.viewers.ISelection; - -public interface ISelectionAction { - - void setSelection(ISelection selection); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.actions; + +import org.eclipse.jface.viewers.ISelection; + +public interface ISelectionAction { + + void setSelection(ISelection selection); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/PageAction.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/PageAction.java index 865c84dfe..0cfabcd39 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/PageAction.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/PageAction.java @@ -1,96 +1,96 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.actions; - -import org.eclipse.jface.action.Action; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IDisposable2; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; - -public abstract class PageAction extends Action implements IDisposable2 { - - private IGraphicalEditorPage page; - - protected PageAction(IGraphicalEditorPage page) { - this.page = page; - } - - protected PageAction(String id, IGraphicalEditorPage page) { - this(page); - setId(id); - } - - protected IGraphicalEditorPage getPage() { - return page; - } - - protected IGraphicalViewer getViewer() { - return page == null ? null : page.getViewer(); - } - - protected EditDomain getEditDomain() { - return page == null ? null : page.getEditDomain(); - } - - protected ITool getActiveTool() { - EditDomain domain = getEditDomain(); - return domain == null ? null : domain.getActiveTool(); - } - - protected void sendRequest(String request) { - EditDomain domain = getEditDomain(); - if (domain != null) { - domain.handleRequest(request, getViewer()); - } - } - - protected void sendRequest(Request request) { - request.setViewer(getViewer()); - EditDomain domain = getEditDomain(); - if (domain != null) { - domain.handleRequest(request); - } - } - - protected IGraphicalEditor getEditor() { - return page == null ? null : page.getParentEditor(); - } - - protected ICommandStack getCommandStack() { - IGraphicalEditor editor = getEditor(); - return editor == null ? null : editor.getCommandStack(); - } - - protected void saveAndRun(Command command) { - ICommandStack cs = getCommandStack(); - if (cs != null) { - cs.execute(command); - } - } - - public void dispose() { - page = null; - } - - public boolean isDisposed() { - return page == null || page.isDisposed(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.actions; + +import org.eclipse.jface.action.Action; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IDisposable2; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; + +public abstract class PageAction extends Action implements IDisposable2 { + + private IGraphicalEditorPage page; + + protected PageAction(IGraphicalEditorPage page) { + this.page = page; + } + + protected PageAction(String id, IGraphicalEditorPage page) { + this(page); + setId(id); + } + + protected IGraphicalEditorPage getPage() { + return page; + } + + protected IGraphicalViewer getViewer() { + return page == null ? null : page.getViewer(); + } + + protected EditDomain getEditDomain() { + return page == null ? null : page.getEditDomain(); + } + + protected ITool getActiveTool() { + EditDomain domain = getEditDomain(); + return domain == null ? null : domain.getActiveTool(); + } + + protected void sendRequest(String request) { + EditDomain domain = getEditDomain(); + if (domain != null) { + domain.handleRequest(request, getViewer()); + } + } + + protected void sendRequest(Request request) { + request.setViewer(getViewer()); + EditDomain domain = getEditDomain(); + if (domain != null) { + domain.handleRequest(request); + } + } + + protected IGraphicalEditor getEditor() { + return page == null ? null : page.getParentEditor(); + } + + protected ICommandStack getCommandStack() { + IGraphicalEditor editor = getEditor(); + return editor == null ? null : editor.getCommandStack(); + } + + protected void saveAndRun(Command command) { + ICommandStack cs = getCommandStack(); + if (cs != null) { + cs.execute(command); + } + } + + public void dispose() { + page = null; + } + + public boolean isDisposed() { + return page == null || page.isDisposed(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/RedoAction.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/RedoAction.java index 64c10959e..57ff3564b 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/RedoAction.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/RedoAction.java @@ -1,56 +1,56 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.actions; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.actions.ActionFactory; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.internal.ActionMessages; - -public class RedoAction extends CommandStackAction { - - public RedoAction(IGraphicalEditor editor) { - super(editor); - setId(ActionFactory.REDO.getId()); - setActionDefinitionId(ActionFactory.REDO.getCommandId()); - } - - public void run() { - if (getCommandStack() == null || isDisposed()) - return; - - getCommandStack().redo(); - } - - protected void update() { - ICommandStack cs = getCommandStack(); - boolean canRedo = cs != null && cs.canRedo(); - - setEnabled(canRedo); - - String label = null; - if (canRedo && cs != null) { - label = cs.getRedoLabel(); - } - - if (label == null) { - setText(ActionMessages.RedoText); - setToolTipText(ActionMessages.RedoTooltip); - } else { - setText(NLS.bind(ActionMessages.RedoTextFormat, label)); - setToolTipText(NLS.bind(ActionMessages.RedoTooltipFormat, label)); - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.actions; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.actions.ActionFactory; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.internal.ActionMessages; + +public class RedoAction extends CommandStackAction { + + public RedoAction(IGraphicalEditor editor) { + super(editor); + setId(ActionFactory.REDO.getId()); + setActionDefinitionId(ActionFactory.REDO.getCommandId()); + } + + public void run() { + if (getCommandStack() == null || isDisposed()) + return; + + getCommandStack().redo(); + } + + protected void update() { + ICommandStack cs = getCommandStack(); + boolean canRedo = cs != null && cs.canRedo(); + + setEnabled(canRedo); + + String label = null; + if (canRedo && cs != null) { + label = cs.getRedoLabel(); + } + + if (label == null) { + setText(ActionMessages.RedoText); + setToolTipText(ActionMessages.RedoTooltip); + } else { + setText(NLS.bind(ActionMessages.RedoTextFormat, label)); + setToolTipText(NLS.bind(ActionMessages.RedoTooltipFormat, label)); + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/UndoAction.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/UndoAction.java index 73f040b9b..2cf0f9eb1 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/UndoAction.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/actions/UndoAction.java @@ -1,57 +1,57 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.actions; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.actions.ActionFactory; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.internal.ActionMessages; - -public class UndoAction extends CommandStackAction { - - public UndoAction(IGraphicalEditor editor) { - super(editor); - setId(ActionFactory.UNDO.getId()); - setActionDefinitionId(ActionFactory.UNDO.getCommandId()); - } - - public void run() { - if (getCommandStack() == null || isDisposed()) - return; - - getCommandStack().undo(); - } - - protected void update() { - ICommandStack cs = getCommandStack(); - boolean canUndo = cs != null && cs.canUndo(); - - setEnabled(canUndo); - - String label = null; - if (canUndo && cs != null) { - label = cs.getUndoLabel(); - } - - if (label == null) { - setText(ActionMessages.UndoText); - setToolTipText(ActionMessages.UndoTooltip); - } else { - setText(NLS.bind(ActionMessages.UndoTextFormat, label)); - setToolTipText(NLS.bind(ActionMessages.UndoTooltipFormat, label)); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.actions; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.actions.ActionFactory; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.internal.ActionMessages; + +public class UndoAction extends CommandStackAction { + + public UndoAction(IGraphicalEditor editor) { + super(editor); + setId(ActionFactory.UNDO.getId()); + setActionDefinitionId(ActionFactory.UNDO.getCommandId()); + } + + public void run() { + if (getCommandStack() == null || isDisposed()) + return; + + getCommandStack().undo(); + } + + protected void update() { + ICommandStack cs = getCommandStack(); + boolean canUndo = cs != null && cs.canUndo(); + + setEnabled(canUndo); + + String label = null; + if (canUndo && cs != null) { + label = cs.getUndoLabel(); + } + + if (label == null) { + setText(ActionMessages.UndoText); + setToolTipText(ActionMessages.UndoTooltip); + } else { + setText(NLS.bind(ActionMessages.UndoTextFormat, label)); + setToolTipText(NLS.bind(ActionMessages.UndoTooltipFormat, label)); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Editable.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Editable.java index 741849383..925333339 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Editable.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Editable.java @@ -1,679 +1,680 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.xmind.gef.GEF; -import org.xmind.gef.command.CommandStack; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.command.ICommandStackListener; - -/** - *

- * This class implements basic behaviors of {@link IEditable}. A document-based - * application should create its own subclass of Editable and - * provide abilities to access actual content. - *

- *

Subclassing Notes

- *
    - *
  • Each subclass MUST override {@link #doOpen(IProgressMonitor) - * doOpen()} and MUST NOT call super.doOpen(), unless it - * overrides {@link #open(IProgressMonitor) open()} to change the default - * behavior.
  • - *
  • Each subclass MUST override {@link #doSave(IProgressMonitor) - * doSave()} and MUST NOT call super.doSave() if it may - * return true by overriding {@link #canSave()}, unless it - * overrides {@link #save(IProgressMonitor)} to change the default behavior. - *
  • - *
  • Each subclass may override {@link #doClose(IProgressMonitor) doClose()} - * to perform additional actions while closing the document.
  • - *
- * - * @author Frank Shaka - * @since 3.6.50 - */ -public abstract class Editable implements IEditable { - - private URI uri; - - private int state; - - private long modificationTime = 0; - - private int progress = 0; - - private ICommandStack commandStack = null; - - private IEditingContext activeContext = null; - - private final List cleaners = new ArrayList(); - - private final ListenerList listenerManager = new ListenerList(); - - private int contentRefCount = 0; - - private ICommandStackListener commandStackHook = new ICommandStackListener() { - - @Override - public void handleCommandStackEvent(CommandStackEvent event) { - if ((event.getStatus() & GEF.CS_UPDATED) != 0) { - boolean isDirty = isDirty(); - firePropertyChanged(PROP_DIRTY, false, isDirty); - } - - doHandleCommandStackChange(event); - } - }; - - private final List messages = new ArrayList(); - - protected Editable(URI uri) { - this.uri = uri; - this.state = CLOSED; - } - - @Override - public T getAdapter(Class adapter) { - if (URI.class.equals(adapter)) - return adapter.cast(getURI()); - if (ICommandStack.class.equals(adapter)) - return adapter.cast(getCommandStack()); - return Platform.getAdapterManager().getAdapter(this, adapter); - } - - @Override - public URI getURI() { - return this.uri; - } - - @Override - public String getName() { - if (this.uri != null) { - String path = this.uri.getPath(); - if (path != null && path.length() > 0) { - if (path.charAt(path.length() - 1) == '/') { - path = path.substring(0, path.length() - 1); - } - int sep = path.lastIndexOf('/'); - if (sep >= 0) { - return path.substring(sep + 1); - } - } - } - return null; - } - - @Override - public String getDescription() { - return getName(); - } - - @Override - public long getModificationTime() { - return this.modificationTime; - } - - protected void setModificationTime(long modificationTime) { - long oldModificationTime = this.modificationTime; - if (modificationTime == oldModificationTime) - return; - - this.modificationTime = modificationTime; - firePropertyChanged(PROP_MODIFICATION_TIME, oldModificationTime, - modificationTime); - } - - @Override - public synchronized int getState() { - return this.state; - } - - @Override - public boolean isInState(int state) { - return (getState() & state) != 0; - } - - protected void setState(int newState) { - int oldState; - synchronized (this) { - oldState = this.state; - if (newState == oldState) - return; - this.state = newState; - } - firePropertyChanged(PROP_STATE, oldState, newState); - } - - protected void modifyState(int stateToAdd, int stateToRemove) { - int newState = getState(); - if (stateToAdd != 0) { - newState |= stateToAdd; - } - if (stateToRemove != 0) { - newState &= ~stateToRemove; - } - setState(newState); - } - - protected void addState(int state) { - setState(getState() | state); - } - - protected void removeState(int state) { - setState(getState() & (~state)); - } - - @Override - public synchronized int getProgress() { - return this.progress; - } - - protected void setProgress(int newProgress) { - int oldProgress; - synchronized (this) { - oldProgress = this.progress; - if (newProgress == oldProgress) - return; - this.progress = newProgress; - } - firePropertyChanged(PROP_PROGRESS, oldProgress, newProgress); - } - - protected void addProgress(int delta) { - setProgress(getProgress() + delta); - } - - protected void removeProgress(int delta) { - setProgress(getProgress() - delta); - } - - @Override - public ICommandStack getCommandStack() { - if (this.commandStack == null) { - setCommandStack(createDefaultCommandStack()); - } - return this.commandStack; - } - - protected ICommandStack createDefaultCommandStack() { - return new CommandStack(); - } - - protected void setCommandStack(ICommandStack commandStack) { - ICommandStack oldCommandStack = this.commandStack; - if (oldCommandStack == commandStack) - return; - - if (oldCommandStack != null) { - oldCommandStack.removeCSListener(commandStackHook); - } - this.commandStack = commandStack; - if (commandStack != null) { - commandStack.addCSListener(commandStackHook); - } - firePropertyChanged(PROP_COMMAND_STACK, oldCommandStack, commandStack); - } - - @Override - public IEditingContext getActiveContext() { - IEditingContext context = this.activeContext; - return context == null ? IEditingContext.NULL : context; - } - - protected T getService(Class serviceType) { - return getActiveContext().getAdapter(serviceType); - } - - @Override - public void setActiveContext(IEditingContext context) { - IEditingContext oldContext = this.activeContext; - if (oldContext == context) - return; - this.activeContext = context; - firePropertyChanged(PROP_ACTIVE_CONTEXT, oldContext, context); - } - - @Override - public boolean exists() { - return false; - } - - @Override - public boolean isDirty() { - return (commandStack != null && commandStack.isDirty()) - || !cleaners.isEmpty(); - } - - @Override - public void markDirtyWith(IEditableCleaner cleaner) { - boolean wasDirty = isDirty(); - synchronized (this.cleaners) { - this.cleaners.add(cleaner); - } - boolean isDirty = isDirty(); - if (wasDirty != isDirty) { - firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); - } - } - - @Override - public void unmarkDirtyWith(IEditableCleaner cleaner) { - boolean wasDirty = isDirty(); - synchronized (this.cleaners) { - this.cleaners.remove(cleaner); - } - boolean isDirty = isDirty(); - if (wasDirty != isDirty) { - firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); - } - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.ui.editor.IEditable#discardChanges() - */ - @Override - public void discardChanges() { - boolean wasDirty = isDirty(); - doDiscardChanges(); - boolean isDirty = isDirty(); - if (wasDirty != isDirty) { - firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); - } - } - - protected void doDiscardChanges() { - if (commandStack != null) { - while (commandStack.isDirty() && commandStack.canUndo()) { - commandStack.markSaved(); - } - } - synchronized (this.cleaners) { - this.cleaners.clear(); - } - } - - protected void clean(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - IEditableCleaner[] theCleaners = new IEditableCleaner[0]; - synchronized (this.cleaners) { - theCleaners = this.cleaners.toArray(theCleaners); - this.cleaners.clear(); - } - - SubMonitor subMonitor = SubMonitor.convert(monitor, theCleaners.length); - for (int i = 0; i < theCleaners.length; i++) { - IEditableCleaner cleaner = theCleaners[i]; - doClean(subMonitor.newChild(1), cleaner); - } - } - - protected void doClean(IProgressMonitor monitor, IEditableCleaner cleaner) - throws InterruptedException, InvocationTargetException { - cleaner.cleanEditable(monitor, this); - } - - @Override - public void addPropertyChangeListener(IPropertyChangeListener listener) { - listenerManager.add(listener); - } - - @Override - public void removePropertyChangeListener(IPropertyChangeListener listener) { - listenerManager.remove(listener); - } - - protected void firePropertyChanged(String property, Object oldValue, - Object newValue) { - final PropertyChangeEvent event = new PropertyChangeEvent(this, - property, oldValue, newValue); - for (final Object o : listenerManager.getListeners()) { - if (o instanceof IPropertyChangeListener) { - try { - ((IPropertyChangeListener) o).propertyChange(event); - } catch (Exception e) { - handlePropertyChangeNotificationError(e); - } - } - } - } - - private void handlePropertyChangeNotificationError(Exception e) { - // TODO handle errors during editable state change notification - } - - @Override - public void open(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - if (!isInState(CLOSED)) { - // already opened - contentRefCount += 1; - return; - } - - if (isInState(OPENING | CLOSING | SAVING)) - // already being opened - throw new IllegalStateException( - "Concurrent open/close/save operations are not allowed"); //$NON-NLS-1$ - - try { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - subMonitor.newChild(10); - addState(OPENING); - try { - if (subMonitor.isCanceled()) - throw new InterruptedException(); - doOpen(subMonitor.newChild(80)); - - subMonitor.newChild(5); - contentRefCount += 1; - if (isInState(CLOSED)) { - removeState(CLOSED); - } - } finally { - subMonitor.setWorkRemaining(5); - subMonitor.newChild(5); - removeState(OPENING); - } - } catch (OperationCanceledException e) { - // interpret cancellation - throw new InterruptedException(); - } - } - - /** - * Perform actual open operations. - *

- * This method is, by default, called by {@link #open(IProgressMonitor)} and - * its default implementation from {@link Editable} does nothing but throws - * {@link UnsupportedOperationException}, so subclasses MUST override - * this method and MUST NOT call super.doOpen(), unless - * they override {@link #open(IProgressMonitor)} to change the default - * behavior. - *

- * - * @see #open(IProgressMonitor) - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - protected void doOpen(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - throw new UnsupportedOperationException(); - } - - @Override - public boolean canSave() { - return false; - } - - @Override - public void save(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - if (!canSave()) - throw new IllegalStateException("Save operation is not allowed"); //$NON-NLS-1$ - - if (isInState(CLOSED)) - // already closed - throw new IllegalStateException( - "Can't perform save operation while editable is closed"); //$NON-NLS-1$ - - if (isInState(OPENING | CLOSING | SAVING)) - // already being opened/closing/saving - throw new IllegalStateException( - "Concurrent open/close/save operations are not allowed in SynchronizedEditable"); //$NON-NLS-1$ - - try { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - subMonitor.newChild(5); - addState(SAVING); - try { - boolean wasDirty = isDirty(); - if (subMonitor.isCanceled()) - throw new InterruptedException(); - clean(subMonitor.newChild(5)); - - if (subMonitor.isCanceled()) - throw new OperationCanceledException(); - doSave(subMonitor.newChild(80)); - markSaved(subMonitor.newChild(5)); - - subMonitor.newChild(4); - boolean isDirty = isDirty(); - if (wasDirty != isDirty) { - firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); - } - } finally { - subMonitor.setWorkRemaining(1); - subMonitor.newChild(1); - removeState(SAVING); - } - } catch (OperationCanceledException e) { - // interpret cancellation - throw new InterruptedException(); - } - } - - /** - * Perform actual save operations. - *

- * This method is, by default, called by {@link #save(IProgressMonitor)} and - * its default implementation from {@link Editable} does nothing but throws - * {@link UnsupportedOperationException}, so subclasses MUST override - * this method and MUST NOT call super.doSave() if they - * return true by overriding {@link #canSave()}, unless they - * override {@link #save(IProgressMonitor)} to change the default behavior. - *

- * - * @see #save(IProgressMonitor) - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - protected void doSave(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - throw new UnsupportedOperationException(); - } - - /** - * Called after the save operation has successfully completed. Typically - * used to send notifications. - *

- * Subclasses may override and call super.markSaved(). - *

- * - * @param monitor - * @throws InterruptedException - * @throws InvocationTargetException - */ - protected void markSaved(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - ICommandStack commandStack = getCommandStack(); - if (commandStack != null) { - commandStack.markSaved(); - } - } - - @Override - public void close(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - if (isInState(CLOSED)) - // already closed - return; - - if (isInState(OPENING | CLOSING | SAVING)) - // already being opened - throw new IllegalStateException( - "Concurrent open/close/save operations are not allowed in SynchronizedEditable"); //$NON-NLS-1$ - - if (contentRefCount > 1) { - // some other clients requiring content - // should do nothing - contentRefCount -= 1; - return; - } - - try { - // no other clients requiring content - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - if (isDirty() && canSave()) { - // should save first - doSave(subMonitor.newChild(70)); - } - if (subMonitor.isCanceled()) - throw new InterruptedException(); - subMonitor.setWorkRemaining(30); - - if (commandStack != null) { - commandStack.clear(); - } - - subMonitor.newChild(5); - contentRefCount -= 1; - addState(CLOSED); - try { - if (subMonitor.isCanceled()) - throw new InterruptedException(); - doClose(subMonitor.newChild(20)); - if (!isInState(CLOSED)) { - addState(CLOSED); - } - } finally { - subMonitor.setWorkRemaining(5); - subMonitor.newChild(5); - removeState(CLOSING); - } - } catch (OperationCanceledException e) { - // interpret cancellation - throw new InterruptedException(); - } - } - - /** - * Perform actual close operations. - *

- * This method is, by default, called from {@link #close(IProgressMonitor)} - * and its default implementation from {@link Editable} does nothing, so - * subclasses may or may not override this method and need not to - * call super.doClose(). - *

- * - * @see #close(IProgressMonitor) - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - protected void doClose(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - // do nothing, subclasses may override - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.ui.editor.IEditable#getMessages() - */ - @Override - public List getMessages() { - return Collections.unmodifiableList(messages); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.ui.editor.IEditable#addMessage(org.eclipse.jface.dialogs. - * IMessageProvider) - */ - @Override - public void addMessage(IInteractiveMessage message) { - List oldMessages = new ArrayList( - messages); - if (messages.add(message)) { - firePropertyChanged(PROP_MESSAGES, oldMessages, - new ArrayList(messages)); - } - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.ui.editor.IEditable#removeMessage(org.eclipse.jface.dialogs - * .IMessageProvider) - */ - @Override - public void removeMessage(IInteractiveMessage message) { - List oldMessages = new ArrayList( - messages); - if (messages.remove(message)) { - firePropertyChanged(PROP_MESSAGES, oldMessages, - new ArrayList(messages)); - } - } - - protected void doHandleCommandStackChange(CommandStackEvent event) { - /// do nothing, subclasses may override - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.xmind.gef.GEF; +import org.xmind.gef.command.CommandStack; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.command.ICommandStackListener; + +/** + *

+ * This class implements basic behaviors of {@link IEditable}. A document-based + * application should create its own subclass of Editable and + * provide abilities to access actual content. + *

+ *

Subclassing Notes

+ *
    + *
  • Each subclass MUST override {@link #doOpen(IProgressMonitor) + * doOpen()} and MUST NOT call super.doOpen(), unless it + * overrides {@link #open(IProgressMonitor) open()} to change the default + * behavior.
  • + *
  • Each subclass MUST override {@link #doSave(IProgressMonitor) + * doSave()} and MUST NOT call super.doSave() if it may + * return true by overriding {@link #canSave()}, unless it + * overrides {@link #save(IProgressMonitor)} to change the default behavior. + *
  • + *
  • Each subclass may override {@link #doClose(IProgressMonitor) doClose()} + * to perform additional actions while closing the document.
  • + *
+ * + * @author Frank Shaka + * @since 3.6.50 + */ +public abstract class Editable implements IEditable { + + private URI uri; + + private int state; + + private long modificationTime = 0; + + private int progress = 0; + + private ICommandStack commandStack = null; + + private IEditingContext activeContext = null; + + private final List cleaners = new ArrayList(); + + private final ListenerList listenerManager = new ListenerList(); + + private int contentRefCount = 0; + + private ICommandStackListener commandStackHook = new ICommandStackListener() { + + @Override + public void handleCommandStackEvent(CommandStackEvent event) { + if ((event.getStatus() & GEF.CS_UPDATED) != 0) { + boolean isDirty = isDirty(); + firePropertyChanged(PROP_DIRTY, false, isDirty); + } + + doHandleCommandStackChange(event); + } + }; + + private final List messages = new ArrayList(); + + protected Editable(URI uri) { + this.uri = uri; + this.state = CLOSED; + } + + @Override + public T getAdapter(Class adapter) { + if (URI.class.equals(adapter)) + return adapter.cast(getURI()); + if (ICommandStack.class.equals(adapter)) + return adapter.cast(getCommandStack()); + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + @Override + public URI getURI() { + return this.uri; + } + + @Override + public String getName() { + if (this.uri != null) { + String path = this.uri.getPath(); + if (path != null && path.length() > 0) { + if (path.charAt(path.length() - 1) == '/') { + path = path.substring(0, path.length() - 1); + } + int sep = path.lastIndexOf('/'); + if (sep >= 0) { + return path.substring(sep + 1); + } + } + } + return null; + } + + @Override + public String getDescription() { + return getName(); + } + + @Override + public long getModificationTime() { + return this.modificationTime; + } + + protected void setModificationTime(long modificationTime) { + long oldModificationTime = this.modificationTime; + if (modificationTime == oldModificationTime) + return; + + this.modificationTime = modificationTime; + firePropertyChanged(PROP_MODIFICATION_TIME, oldModificationTime, + modificationTime); + } + + @Override + public synchronized int getState() { + return this.state; + } + + @Override + public boolean isInState(int state) { + return (getState() & state) != 0; + } + + protected void setState(int newState) { + int oldState; + synchronized (this) { + oldState = this.state; + if (newState == oldState) + return; + this.state = newState; + } + firePropertyChanged(PROP_STATE, oldState, newState); + } + + protected void modifyState(int stateToAdd, int stateToRemove) { + int newState = getState(); + if (stateToAdd != 0) { + newState |= stateToAdd; + } + if (stateToRemove != 0) { + newState &= ~stateToRemove; + } + setState(newState); + } + + protected void addState(int state) { + setState(getState() | state); + } + + protected void removeState(int state) { + setState(getState() & (~state)); + } + + @Override + public synchronized int getProgress() { + return this.progress; + } + + protected void setProgress(int newProgress) { + int oldProgress; + synchronized (this) { + oldProgress = this.progress; + if (newProgress == oldProgress) + return; + this.progress = newProgress; + } + firePropertyChanged(PROP_PROGRESS, oldProgress, newProgress); + } + + protected void addProgress(int delta) { + setProgress(getProgress() + delta); + } + + protected void removeProgress(int delta) { + setProgress(getProgress() - delta); + } + + @Override + public ICommandStack getCommandStack() { + if (this.commandStack == null) { + setCommandStack(createDefaultCommandStack()); + } + return this.commandStack; + } + + protected ICommandStack createDefaultCommandStack() { + return new CommandStack(); + } + + protected void setCommandStack(ICommandStack commandStack) { + ICommandStack oldCommandStack = this.commandStack; + if (oldCommandStack == commandStack) + return; + + if (oldCommandStack != null) { + oldCommandStack.removeCSListener(commandStackHook); + oldCommandStack.dispose(); + } + this.commandStack = commandStack; + if (commandStack != null) { + commandStack.addCSListener(commandStackHook); + } + firePropertyChanged(PROP_COMMAND_STACK, oldCommandStack, commandStack); + } + + @Override + public IEditingContext getActiveContext() { + IEditingContext context = this.activeContext; + return context == null ? IEditingContext.NULL : context; + } + + protected T getService(Class serviceType) { + return getActiveContext().getAdapter(serviceType); + } + + @Override + public void setActiveContext(IEditingContext context) { + IEditingContext oldContext = this.activeContext; + if (oldContext == context) + return; + this.activeContext = context; + firePropertyChanged(PROP_ACTIVE_CONTEXT, oldContext, context); + } + + @Override + public boolean exists() { + return false; + } + + @Override + public boolean isDirty() { + return (commandStack != null && commandStack.isDirty()) + || !cleaners.isEmpty(); + } + + @Override + public void markDirtyWith(IEditableCleaner cleaner) { + boolean wasDirty = isDirty(); + synchronized (this.cleaners) { + this.cleaners.add(cleaner); + } + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } + } + + @Override + public void unmarkDirtyWith(IEditableCleaner cleaner) { + boolean wasDirty = isDirty(); + synchronized (this.cleaners) { + this.cleaners.remove(cleaner); + } + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.ui.editor.IEditable#discardChanges() + */ + @Override + public void discardChanges() { + boolean wasDirty = isDirty(); + doDiscardChanges(); + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } + } + + protected void doDiscardChanges() { + if (commandStack != null) { + while (commandStack.isDirty() && commandStack.canUndo()) { + commandStack.markSaved(); + } + } + synchronized (this.cleaners) { + this.cleaners.clear(); + } + } + + protected void clean(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + IEditableCleaner[] theCleaners = new IEditableCleaner[0]; + synchronized (this.cleaners) { + theCleaners = this.cleaners.toArray(theCleaners); + this.cleaners.clear(); + } + + SubMonitor subMonitor = SubMonitor.convert(monitor, theCleaners.length); + for (int i = 0; i < theCleaners.length; i++) { + IEditableCleaner cleaner = theCleaners[i]; + doClean(subMonitor.newChild(1), cleaner); + } + } + + protected void doClean(IProgressMonitor monitor, IEditableCleaner cleaner) + throws InterruptedException, InvocationTargetException { + cleaner.cleanEditable(monitor, this); + } + + @Override + public void addPropertyChangeListener(IPropertyChangeListener listener) { + listenerManager.add(listener); + } + + @Override + public void removePropertyChangeListener(IPropertyChangeListener listener) { + listenerManager.remove(listener); + } + + protected void firePropertyChanged(String property, Object oldValue, + Object newValue) { + final PropertyChangeEvent event = new PropertyChangeEvent(this, + property, oldValue, newValue); + for (final Object o : listenerManager.getListeners()) { + if (o instanceof IPropertyChangeListener) { + try { + ((IPropertyChangeListener) o).propertyChange(event); + } catch (Exception e) { + handlePropertyChangeNotificationError(e); + } + } + } + } + + private void handlePropertyChangeNotificationError(Exception e) { + // TODO handle errors during editable state change notification + } + + @Override + public void open(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + if (!isInState(CLOSED)) { + // already opened + contentRefCount += 1; + return; + } + + if (isInState(OPENING | CLOSING | SAVING)) + // already being opened + throw new IllegalStateException( + "Concurrent open/close/save operations are not allowed"); //$NON-NLS-1$ + + try { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + subMonitor.newChild(10); + addState(OPENING); + try { + if (subMonitor.isCanceled()) + throw new InterruptedException(); + doOpen(subMonitor.newChild(80)); + + subMonitor.newChild(5); + contentRefCount += 1; + if (isInState(CLOSED)) { + removeState(CLOSED); + } + } finally { + subMonitor.setWorkRemaining(5); + subMonitor.newChild(5); + removeState(OPENING); + } + } catch (OperationCanceledException e) { + // interpret cancellation + throw new InterruptedException(); + } + } + + /** + * Perform actual open operations. + *

+ * This method is, by default, called by {@link #open(IProgressMonitor)} and + * its default implementation from {@link Editable} does nothing but throws + * {@link UnsupportedOperationException}, so subclasses MUST override + * this method and MUST NOT call super.doOpen(), unless + * they override {@link #open(IProgressMonitor)} to change the default + * behavior. + *

+ * + * @see #open(IProgressMonitor) + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + protected void doOpen(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean canSave() { + return false; + } + + @Override + public void save(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + if (!canSave()) + throw new IllegalStateException("Save operation is not allowed"); //$NON-NLS-1$ + + if (isInState(CLOSED)) + // already closed + throw new IllegalStateException( + "Can't perform save operation while editable is closed"); //$NON-NLS-1$ + + if (isInState(OPENING | CLOSING | SAVING)) + // already being opened/closing/saving + throw new IllegalStateException( + "Concurrent open/close/save operations are not allowed in SynchronizedEditable"); //$NON-NLS-1$ + + try { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + subMonitor.newChild(5); + addState(SAVING); + try { + boolean wasDirty = isDirty(); + if (subMonitor.isCanceled()) + throw new InterruptedException(); + clean(subMonitor.newChild(5)); + + if (subMonitor.isCanceled()) + throw new OperationCanceledException(); + doSave(subMonitor.newChild(80)); + markSaved(subMonitor.newChild(5)); + + subMonitor.newChild(4); + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } + } finally { + subMonitor.setWorkRemaining(1); + subMonitor.newChild(1); + removeState(SAVING); + } + } catch (OperationCanceledException e) { + // interpret cancellation + throw new InterruptedException(); + } + } + + /** + * Perform actual save operations. + *

+ * This method is, by default, called by {@link #save(IProgressMonitor)} and + * its default implementation from {@link Editable} does nothing but throws + * {@link UnsupportedOperationException}, so subclasses MUST override + * this method and MUST NOT call super.doSave() if they + * return true by overriding {@link #canSave()}, unless they + * override {@link #save(IProgressMonitor)} to change the default behavior. + *

+ * + * @see #save(IProgressMonitor) + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + protected void doSave(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + throw new UnsupportedOperationException(); + } + + /** + * Called after the save operation has successfully completed. Typically + * used to send notifications. + *

+ * Subclasses may override and call super.markSaved(). + *

+ * + * @param monitor + * @throws InterruptedException + * @throws InvocationTargetException + */ + protected void markSaved(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + ICommandStack commandStack = getCommandStack(); + if (commandStack != null) { + commandStack.markSaved(); + } + } + + @Override + public void close(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + if (isInState(CLOSED)) + // already closed + return; + + if (isInState(OPENING | CLOSING | SAVING)) + // already being opened + throw new IllegalStateException( + "Concurrent open/close/save operations are not allowed in SynchronizedEditable"); //$NON-NLS-1$ + + if (contentRefCount > 1) { + // some other clients requiring content + // should do nothing + contentRefCount -= 1; + return; + } + + try { + // no other clients requiring content + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + if (isDirty() && canSave()) { + // should save first + doSave(subMonitor.newChild(70)); + } + if (subMonitor.isCanceled()) + throw new InterruptedException(); + subMonitor.setWorkRemaining(30); + + if (commandStack != null) { + commandStack.clear(); + } + + subMonitor.newChild(5); + contentRefCount -= 1; + addState(CLOSED); + try { + if (subMonitor.isCanceled()) + throw new InterruptedException(); + doClose(subMonitor.newChild(20)); + if (!isInState(CLOSED)) { + addState(CLOSED); + } + } finally { + subMonitor.setWorkRemaining(5); + subMonitor.newChild(5); + removeState(CLOSING); + } + } catch (OperationCanceledException e) { + // interpret cancellation + throw new InterruptedException(); + } + } + + /** + * Perform actual close operations. + *

+ * This method is, by default, called from {@link #close(IProgressMonitor)} + * and its default implementation from {@link Editable} does nothing, so + * subclasses may or may not override this method and need not to + * call super.doClose(). + *

+ * + * @see #close(IProgressMonitor) + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + protected void doClose(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + // do nothing, subclasses may override + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.ui.editor.IEditable#getMessages() + */ + @Override + public List getMessages() { + return Collections.unmodifiableList(messages); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.ui.editor.IEditable#addMessage(org.eclipse.jface.dialogs. + * IMessageProvider) + */ + @Override + public void addMessage(IInteractiveMessage message) { + List oldMessages = new ArrayList( + messages); + if (messages.add(message)) { + firePropertyChanged(PROP_MESSAGES, oldMessages, + new ArrayList(messages)); + } + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.ui.editor.IEditable#removeMessage(org.eclipse.jface.dialogs + * .IMessageProvider) + */ + @Override + public void removeMessage(IInteractiveMessage message) { + List oldMessages = new ArrayList( + messages); + if (messages.remove(message)) { + firePropertyChanged(PROP_MESSAGES, oldMessages, + new ArrayList(messages)); + } + } + + protected void doHandleCommandStackChange(CommandStackEvent event) { + /// do nothing, subclasses may override + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GlobalActionHandlerService.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GlobalActionHandlerService.java index 4e2ee5db3..c6e7b5093 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GlobalActionHandlerService.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GlobalActionHandlerService.java @@ -1,101 +1,101 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.ui.IActionBars; - -/** - * @author Frank Shaka - * - */ -public class GlobalActionHandlerService implements IGlobalActionHandlerService, - IPageChangedListener { - - private IGraphicalEditor editor; - - private List actionBarsList = null; - - /** - * - */ - public GlobalActionHandlerService(IGraphicalEditor editor) { - this.editor = editor; - editor.addPageChangedListener(this); - } - - public void addActionBars(IActionBars actionBars) { - if (actionBarsList != null && actionBarsList.contains(actionBars)) - return; - - if (actionBarsList == null) - actionBarsList = new ArrayList(); - actionBarsList.add(actionBars); - update(actionBars, getUpdater()); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.ui.editor.IGlobalActionHandlerService#removeActionBars( - * org.eclipse.ui.IActionBars) - */ - public void removeActionBars(IActionBars actionBars) { - if (actionBarsList != null) { - actionBarsList.remove(actionBars); - } - if (actionBars != null) { - actionBars.clearGlobalActionHandlers(); - actionBars.updateActionBars(); - } - } - - private IGlobalActionHandlerUpdater getUpdater() { - return (IGlobalActionHandlerUpdater) editor - .getAdapter(IGlobalActionHandlerUpdater.class); - } - - private void update(IActionBars actionBars, - IGlobalActionHandlerUpdater updater) { - if (updater == null) - return; - - updater.updateGlobalActionHandlers(actionBars); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.dialogs.IPageChangedListener#pageChanged(org.eclipse - * .jface.dialogs.PageChangedEvent) - */ - public void pageChanged(PageChangedEvent event) { - if (actionBarsList != null) { - IGlobalActionHandlerUpdater updater = getUpdater(); - if (updater != null) { - for (IActionBars actionBars : actionBarsList) { - update(actionBars, updater); - } - } - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.ui.IActionBars; + +/** + * @author Frank Shaka + * + */ +public class GlobalActionHandlerService implements IGlobalActionHandlerService, + IPageChangedListener { + + private IGraphicalEditor editor; + + private List actionBarsList = null; + + /** + * + */ + public GlobalActionHandlerService(IGraphicalEditor editor) { + this.editor = editor; + editor.addPageChangedListener(this); + } + + public void addActionBars(IActionBars actionBars) { + if (actionBarsList != null && actionBarsList.contains(actionBars)) + return; + + if (actionBarsList == null) + actionBarsList = new ArrayList(); + actionBarsList.add(actionBars); + update(actionBars, getUpdater()); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.ui.editor.IGlobalActionHandlerService#removeActionBars( + * org.eclipse.ui.IActionBars) + */ + public void removeActionBars(IActionBars actionBars) { + if (actionBarsList != null) { + actionBarsList.remove(actionBars); + } + if (actionBars != null) { + actionBars.clearGlobalActionHandlers(); + actionBars.updateActionBars(); + } + } + + private IGlobalActionHandlerUpdater getUpdater() { + return (IGlobalActionHandlerUpdater) editor + .getAdapter(IGlobalActionHandlerUpdater.class); + } + + private void update(IActionBars actionBars, + IGlobalActionHandlerUpdater updater) { + if (updater == null) + return; + + updater.updateGlobalActionHandlers(actionBars); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.IPageChangedListener#pageChanged(org.eclipse + * .jface.dialogs.PageChangedEvent) + */ + public void pageChanged(PageChangedEvent event) { + if (actionBarsList != null) { + IGlobalActionHandlerUpdater updater = getUpdater(); + if (updater != null) { + for (IActionBars actionBars : actionBarsList) { + update(actionBars, updater); + } + } + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditor.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditor.java index 04cb480b1..9c12e0b46 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditor.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditor.java @@ -1,844 +1,864 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.events.MenuDetectEvent; -import org.eclipse.swt.events.MenuDetectListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.ui.IEditorActionBarContributor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.part.EditorPart; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.command.CommandStack; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.command.ICommandStackListener; -import org.xmind.gef.ui.actions.ActionRegistry; -import org.xmind.gef.ui.actions.IActionRegistry; -import org.xmind.gef.ui.actions.ICommandStackAction; -import org.xmind.gef.ui.internal.GEFPlugin; -import org.xmind.gef.util.EventListenerSupport; -import org.xmind.gef.util.IEventDispatcher; -import org.xmind.ui.tabfolder.DelegatedSelectionProvider; -import org.xmind.ui.tabfolder.IDelegatedSelectionProvider; -import org.xmind.ui.tabfolder.IPageClosedListener; - -/** - * @author Brian Sun - */ -public abstract class GraphicalEditor extends EditorPart - implements IGraphicalEditor, ICommandStackListener { - - protected class PageInputSelectionProvider implements ISelectionProvider { - - private EventListenerSupport listeners = new EventListenerSupport(); - - public void addSelectionChangedListener( - ISelectionChangedListener listener) { - listeners.addListener(ISelectionChangedListener.class, listener); - } - - public ISelection getSelection() { - IGraphicalEditorPage page = getActivePageInstance(); - if (page != null) { - Object pageInput = page.getInput(); - if (pageInput != null) { - return new StructuredSelection(pageInput); - } - } - return StructuredSelection.EMPTY; - } - - public void removeSelectionChangedListener( - ISelectionChangedListener listener) { - listeners.removeListener(ISelectionChangedListener.class, listener); - } - - public void setSelection(ISelection selection) { - if (selection instanceof IStructuredSelection) { - Object pageInput = ((IStructuredSelection) selection) - .getFirstElement(); - if (pageInput != null) { - ensurePageVisible(pageInput); - } - } - } - - protected void firePageChanged() { - fireSelectionChanged( - new SelectionChangedEvent(this, getSelection())); - } - - private void fireSelectionChanged(final SelectionChangedEvent event) { - listeners.fireEvent(ISelectionChangedListener.class, - new IEventDispatcher() { - - public void dispatch(Object listener) { - ((ISelectionChangedListener) listener) - .selectionChanged(event); - } - }); - } - - } - - protected class MultiPageSelectionProvider - extends DelegatedSelectionProvider { - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.tabfolder.DelegatedSelectionProvider#setSelection(org - * .eclipse.jface.viewers.ISelection) - */ - @Override - public void setSelection(ISelection selection) { - Object input = findOwnedInput(selection); - if (input != null) { - ensurePageVisible(input); - } - super.setSelection(selection); - } - } - - private Composite container = null; - - private IPageContainerPresentation containerPresentation = null; - - private IPageChangedListener presentationHooker = new IPageChangedListener() { - - public void pageChanged(PageChangedEvent event) { - handlePageChange(getActivePage()); - } - }; - - private List pages = new ArrayList(); - - private EventListenerSupport listeners = new EventListenerSupport(); - - private ICommandStack commandStack = null; - - private IMiniBar miniBar = null; - - private IMiniBarContributor miniBarContributor = null; - - private IActionRegistry actionRegistry = null; - - private List csActions = null; - - private int activePageIndex = -1; - - private PageInputSelectionProvider pageInputSelectionProvider = null; - - private MenuManager pagePopupMenu = null; - - private IGlobalActionHandlerService globalActionHandlerService = null; - - /* - * (non-Javadoc) - * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, - * org.eclipse.ui.IEditorInput) - */ - @Override - public void init(IEditorSite site, IEditorInput input) - throws PartInitException { - setSite(site); - setInput(input); - site.setSelectionProvider(createSelectionProvider()); - setCommandStack(createCommandStack()); - } - - protected ISelectionProvider createSelectionProvider() { - return new MultiPageSelectionProvider(); - } - - protected Object findOwnedInput(ISelection selection) { - return null; - } - - protected Composite getContainer() { - return container; - } - - protected IPageContainerPresentation getContainerPresentation() { - return containerPresentation; - } - - protected void hookContainerPresentation() { - getContainerPresentation().addPageChangedListener(presentationHooker); - } - - public void createPartControl(Composite parent) { - if (containerPresentation == null) { - containerPresentation = createContainerPresentation(); - hookContainerPresentation(); - } - Composite containerParent = createContainerParent(parent); - this.container = containerPresentation.createContainer(containerParent); - createEditorContents(); - } - - protected void createEditorContents() { - if (getContainer() instanceof CTabFolder) { - createMiniBarComposite((CTabFolder) getContainer()); - createPageContextMenu((CTabFolder) getContainer()); - } - } - - private void createMiniBarComposite(CTabFolder tabFolder) { - final Composite composite = new Composite(getContainer(), SWT.None); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - createMiniBar(composite); - final ToolBar control = ((ToolBarManager) miniBar.getToolBarManager()) - .getControl(); - GridData controlData = new GridData(SWT.RIGHT, SWT.FILL, true, true); - control.setLayoutData(controlData); - - tabFolder.setTopRight(composite, SWT.RIGHT); - } - - protected IPageContainerPresentation createContainerPresentation() { - return new TabFolderContainerPresentation(); - } - - /** - * Creates the parent control for the container returned by - * {@link #getContainer() }. - *

- * Subclasses may extend and must call super implementation first. - *

- * - * @param parent - * the parent for all of the editors contents. - * @return the parent for this editor's container. Must not be - * null. - */ - protected Composite createContainerParent(Composite parent) { - parent.setLayout(new FillLayout()); - return parent; - } - - public void addPage(IGraphicalEditorPage page) { - page.setEditDomain(createEditDomain(page)); - createPageControl(page); - pages.add(page); - } - - private void createPageControl(IGraphicalEditorPage page) { - page.createPageControl(getContainer()); - Assert.isNotNull(page.getControl()); - Assert.isNotNull(page.getViewer()); - Assert.isNotNull(page.getViewer().getControl()); - addPageControl(page.getControl()); - } - - private void addPageControl(Control pageControl) { - int index = containerPresentation.getPageCount(getContainer()); - containerPresentation.addPage(getContainer(), index, pageControl); - } - - protected EditDomain createEditDomain(IGraphicalEditorPage page) { - return new EditDomain(); - } - - protected void disposeEditDomain(IGraphicalEditorPage page, - EditDomain editDomain) { - editDomain.dispose(); - } - - protected void createPageContextMenu(Composite container) { - if (pagePopupMenu == null) { - pagePopupMenu = createPagePopupMenu(); - String menuId = getSite().getId() + ".page"; //$NON-NLS-1$ - if (isPagePopupMenuDynamic()) { - setupDynamicPopupMenu(container, pagePopupMenu); - } else { - contributeToPagePopupMenu(pagePopupMenu); - } - registerPagePopupMenu(menuId, pagePopupMenu); - } - container.setMenu(pagePopupMenu.createContextMenu(container)); - - } - - private void setupDynamicPopupMenu(final Composite container, - MenuManager popupMenu) { - final boolean[] showsItems = new boolean[1]; - showsItems[0] = false; - popupMenu.setRemoveAllWhenShown(true); - popupMenu.addMenuListener(new IMenuListener() { - - public void menuAboutToShow(IMenuManager manager) { - if (showsItems[0]) { - contributeToPagePopupMenu(manager); - } - } - }); - container.addMenuDetectListener(new MenuDetectListener() { - - public void menuDetected(MenuDetectEvent e) { - CTabFolder folder = (CTabFolder) container; - Point p = folder.toControl(e.x, e.y); - showsItems[0] = !(folder.getClientArea().contains(p) - || folder.getTopRight().getBounds().contains(p)); - } - }); - } - - protected void registerPagePopupMenu(String menuId, MenuManager menu) { - getSite().registerContextMenu(menuId, menu, - getPageInputSelectionProvider()); - } - - protected void contributeToPagePopupMenu(IMenuManager menu) { - IEditorActionBarContributor contributor = getEditorSite() - .getActionBarContributor(); - if (contributor instanceof GraphicalEditorActionBarContributor) { - ((GraphicalEditorActionBarContributor) contributor) - .contributeToPagePopupMenu(menu); - } - } - - protected boolean isPagePopupMenuDynamic() { - return true; - } - - protected MenuManager createPagePopupMenu() { - return new MenuManager(); - } - - public void removePage(IGraphicalEditorPage page) { - removePage(findPage(page)); - } - - protected void removePage(int pageIndex) { - Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount()); - boolean wasActivePage = pageIndex == getActivePage(); - IGraphicalEditorPage page = getPage(pageIndex); - containerPresentation.disposePage(getContainer(), pageIndex); - if (page != null) { - page.dispose(); - } - pages.remove(page); - if (wasActivePage) { - if (pageIndex == getPageCount()) - pageIndex--; - setActivePage(pageIndex); - } - firePageClosed(page); - } - - public IGraphicalEditorPage getPage(int pageIndex) { - if (pageIndex < 0 || pageIndex >= getPageCount()) - return null; - return pages.get(pageIndex); - } - - public int findPage(IGraphicalEditorPage page) { - return pages.indexOf(page); - } - - protected void postSave() { - if (getCommandStack() != null) { - getCommandStack().markSaved(); - } - firePropertyChange(PROP_DIRTY); - } - - public int getPageCount() { - return pages.size(); - } - - public boolean isDirty() { - return getCommandStack() != null && getCommandStack().isDirty(); - } - - /** - * Creates the mini bar on the part control. - *

- * IMPORTANT: This mini bar contribution relies on the fact that the - * page container is a CTabFolder, so it may do nothing if the - * implementation changes. - *

- * - * @see #getContainer() - */ - protected final void createMiniBar(Composite parent) { - if (!(getContainer() instanceof CTabFolder)) - return; - - miniBar = new MiniBar(); - initializeMiniBar(miniBar); - if (!((MiniBar) miniBar).isEmpty()) { - createMiniBarControl(miniBar, (CTabFolder) getContainer(), parent); - } - } - - /** - * @param miniBar - */ - private void initializeMiniBar(IMiniBar miniBar) { - if (getMiniBarContributor() != null) { - getMiniBarContributor().init(miniBar, this); - } - } - - /** - * Creates the mini bar's control on the specified tab folder. - * - * @param miniBar - * @param tabFolder - */ - private void createMiniBarControl(IMiniBar miniBar, CTabFolder tabFolder, - Composite parent) { - ((ToolBarManager) miniBar.getToolBarManager()).createControl(parent); - } - - public IMiniBarContributor getMiniBarContributor() { - return miniBarContributor; - } - - public void setMiniBarContributor(IMiniBarContributor miniBarContributor) { - this.miniBarContributor = miniBarContributor; - } - - /** - * @return commandStack - */ - public ICommandStack getCommandStack() { - return commandStack; - } - - protected ICommandStack createCommandStack() { - return new CommandStack(); - } - - public void handleCommandStackEvent(CommandStackEvent event) { - if ((event.getStatus() & GEF.CS_POST_MASK) != 0 - || event.getStatus() == GEF.CS_UPDATED) { - getSite().getShell().getDisplay().asyncExec(new Runnable() { - - public void run() { - firePropertyChange(PROP_DIRTY); - } - }); - } - } - - @Deprecated - protected void fireDirty() { - firePropertyChange(PROP_DIRTY); - } - - /** - * @param commandStack - * the commandStack to set - */ - public void setCommandStack(ICommandStack commandStack) { - ICommandStack oldCS = this.commandStack; - if (commandStack == oldCS) - return; - - this.commandStack = commandStack; - commandStackChanged(oldCS, commandStack); - } - - protected void commandStackChanged(ICommandStack oldCS, - ICommandStack newCS) { - if (oldCS != null) { - unhookCommandStack(oldCS); - } - if (newCS != null) { - hookCommandStack(newCS); - } - for (IGraphicalEditorPage page : getPages()) { - EditDomain domain = page.getEditDomain(); - if (domain != null) { - domain.setCommandStack(newCS); - } - } - if (csActions != null) { - for (ICommandStackAction action : csActions) { - action.setCommandStack(newCS); - } - } - firePropertyChange(PROP_DIRTY); - } - - protected void hookCommandStack(ICommandStack cs) { - cs.addCSListener(this); - } - - protected void unhookCommandStack(ICommandStack cs) { - cs.removeCSListener(this); - } - - @SuppressWarnings("unchecked") - public T getAdapter(Class adapter) { - Object activePage = getSelectedPage(); - if (activePage != null) { - T result = GEFPlugin.getAdapter(activePage, adapter); - if (result != null) - return result; - } - - T result = getEditorAdapter(adapter); - if (result != null) - return result; - - return super.getAdapter(adapter); - } - - protected T getEditorAdapter(Class adapter) { - if (adapter.isInstance(this)) - return adapter.cast(this); - if (adapter == ICommandStack.class) - return adapter.cast(getCommandStack()); - if (adapter == IActionRegistry.class) - return adapter.cast(getActionRegistry()); - if (adapter == IMiniBar.class) - return adapter.cast(miniBar); - if (adapter == IMiniBarContributor.class) - return adapter.cast(getMiniBarContributor()); - if (adapter == IGlobalActionHandlerService.class) { - if (globalActionHandlerService == null) { - globalActionHandlerService = new GlobalActionHandlerService( - this); - } - return adapter.cast(globalActionHandlerService); - } - if (adapter == IGlobalActionHandlerUpdater.class) { - IEditorActionBarContributor contributor = getEditorSite() - .getActionBarContributor(); - if (contributor instanceof IGlobalActionHandlerUpdater) { - return adapter.cast(contributor); - } - return null; - } - return null; - } - - public Object getSelectedPage() { - return getActivePageInstance(); - } - - public IGraphicalEditorPage getActivePageInstance() { - return getPage(getActivePage()); - } - - public void addPageChangedListener(IPageChangedListener listener) { - listeners.addListener(IPageChangedListener.class, listener); - } - - public void removePageChangedListener(IPageChangedListener listener) { - listeners.removeListener(IPageChangedListener.class, listener); - } - - protected void firePageChanged(Object page) { - final PageChangedEvent event = new PageChangedEvent(this, page); - listeners.fireEvent(IPageChangedListener.class, new IEventDispatcher() { - - public void dispatch(Object listener) { - ((IPageChangedListener) listener).pageChanged(event); - } - }); - } - - protected void firePageClosed(final Object page) { - listeners.fireEvent(IPageChangedListener.class, new IEventDispatcher() { - - public void dispatch(Object listener) { - if (listener instanceof IPageClosedListener) { - ((IPageClosedListener) listener).pageClosed(page); - } - } - }); - } - - @SuppressWarnings("deprecation") - protected void handlePageChange(int newPageIndex) { - boolean wasFocused = false; - IGraphicalEditorPage oldActivePage = getPage(activePageIndex); - if (oldActivePage != null && oldActivePage.isActive()) { - wasFocused = oldActivePage.isFocused(); -// EditDomain editDomain = oldActivePage.getEditDomain(); -// if (editDomain != null) { -// editDomain.setActiveTool(GEF.TOOL_DEFAULT); -// } - oldActivePage.setActive(false); - } - - this.activePageIndex = newPageIndex; - IGraphicalEditorPage activePage = getPage(newPageIndex); - if (activePage != null && !activePage.isActive()) { - activePage.setActive(true); - } - if (wasFocused) { - activePage.setFocus(); - } - - IWorkbenchPage page = getSite().getPage(); - if (page != null) { - //Only when this part is current active part, configure editor by use of active editor page. - IWorkbenchPart currentActivePart = page.getActivePart(); - if (currentActivePart == this) { - IEditorActionBarContributor contributor = getEditorSite() - .getActionBarContributor(); - if (contributor != null - && contributor instanceof GraphicalEditorActionBarContributor) { - ((GraphicalEditorActionBarContributor) contributor) - .setActivePage(activePage); - } - } - } - - ISelectionProvider selectionProvider = getSite().getSelectionProvider(); - if (selectionProvider instanceof IDelegatedSelectionProvider) { - ((IDelegatedSelectionProvider) selectionProvider) - .setDelegate(activePage == null ? null - : activePage.getSelectionProvider()); - } - if (getMiniBarContributor() != null) { - getMiniBarContributor().setActivePage(activePage); - } - if (pageInputSelectionProvider != null) { - Object pageInput = activePage == null ? null - : activePage.getInput(); - pageInputSelectionProvider - .setSelection(pageInput == null ? StructuredSelection.EMPTY - : new StructuredSelection(pageInput)); - } - firePageChanged(activePage); - } - - public void setFocus() { - setFocus(getActivePage()); - } - - protected void setFocus(int pageIndex) { - if (pageIndex < 0 || pageIndex >= getPageCount()) { - container.setFocus(); - } else { - IGraphicalEditorPage page = getPage(pageIndex); - if (page != null) { - page.setFocus(); - } else { - Control control = containerPresentation - .getPageControl(getContainer(), pageIndex); - if (control != null && !control.isDisposed()) { - control.setFocus(); - } - } - } - } - - public void movePageTo(int oldIndex, int newIndex) { - IGraphicalEditorPage activePage = getActivePageInstance(); - boolean wasActive = oldIndex == getActivePage(); - pages.add(newIndex, pages.remove(oldIndex)); - for (int i = 0; i < pages.size(); i++) { - IGraphicalEditorPage page = pages.get(i); - boolean wasFocused = page.isFocused(); - containerPresentation.setPageControl(getContainer(), i, - page.getControl()); - if (wasFocused) - page.setFocus(); - page.updatePageTitle(); - } - if (wasActive) { - pages.get(newIndex).getControl().setVisible(true); - setActivePage(newIndex); - } - if (activePage != null) { - containerPresentation.setActivePage(getContainer(), - pages.indexOf(activePage)); - } - } - - public String getPageText(int pageIndex) { - return containerPresentation.getPageText(getContainer(), pageIndex); - } - - public void setPageText(int pageIndex, String text) { - if (text == null) - text = ""; //$NON-NLS-1$ - containerPresentation.setPageText(getContainer(), pageIndex, text); - } - - public int getActivePage() { - return containerPresentation.getActivePage(getContainer()); - } - - public void setActivePage(int pageIndex) { -// Assert.isTrue(pageIndex < getPageCount()); - if (pageIndex < 0 || pageIndex >= getPageCount()) - return; - - if (pageIndex >= 0) { - containerPresentation.setActivePage(getContainer(), pageIndex); - } else { - containerPresentation.setActivePage(getContainer(), - containerPresentation.getPageCount(getContainer()) - 1); - } - handlePageChange(pageIndex); - } - - public IGraphicalEditorPage[] getPages() { - return pages.toArray(new IGraphicalEditorPage[pages.size()]); - } - - protected ISelectionProvider getPageInputSelectionProvider() { - if (pageInputSelectionProvider == null) { - pageInputSelectionProvider = new PageInputSelectionProvider(); - } - return pageInputSelectionProvider; - } - - protected IActionRegistry getActionRegistry() { - if (actionRegistry == null) - actionRegistry = new ActionRegistry(); - return actionRegistry; - } - - @Override - public void dispose() { - if (csActions != null) { - for (ICommandStackAction action : csActions) { - action.setCommandStack(null); - } - csActions = null; - } - if (actionRegistry != null) { - actionRegistry.dispose(); - actionRegistry = null; - } - if (pagePopupMenu != null) { - pagePopupMenu.dispose(); - pagePopupMenu = null; - } - - if (commandStack != null && !commandStack.isDisposed()) { - disposeCommandStack(commandStack); - commandStack = null; - } - disposePages(); - super.dispose(); - } - - protected void disposeCommandStack(ICommandStack commandStack) { - commandStack.dispose(); - } - - private void disposePages() { - if (pages.isEmpty()) - return; - - for (final Object o : pages.toArray()) { - SafeRunner.run(new SafeRunnable() { - - public void run() throws Exception { - IGraphicalEditorPage page = (IGraphicalEditorPage) o; - page.dispose(); - EditDomain editDomain = page.getEditDomain(); - if (editDomain != null) { - disposeEditDomain(page, editDomain); - } - } - }); - } - pages.clear(); - } - - /** - * @param sourceEvent - * @return - */ - public IGraphicalEditorPage findPage(Object input) { - for (IGraphicalEditorPage page : getPages()) { - Object pageInput = page.getInput(); - if (pageInput == input - || (input != null && input.equals(pageInput))) - return page; - } - return null; - } - - public IGraphicalEditorPage ensurePageVisible(Object input) { - IGraphicalEditorPage page = findPage(input); - if (page != null) { - if (page != getActivePageInstance()) { - setActivePage(page.getIndex()); - page = getActivePageInstance(); - } - } - return page; - } - - public boolean navigateTo(Object input, Object... elements) { - IGraphicalEditorPage page = ensurePageVisible(input); - if (page != null) { - if (elements == null) - return true; - ISelectionProvider viewer = page.getSelectionProvider(); - if (viewer != null) { - viewer.setSelection(new StructuredSelection(elements)); - return true; - } - } - return false; - } - - protected void addCommandStackAction(ICommandStackAction action) { - if (csActions == null) - csActions = new ArrayList(); - csActions.add(action); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.events.MenuDetectEvent; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.ui.IEditorActionBarContributor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.command.CommandStack; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.command.ICommandStackListener; +import org.xmind.gef.ui.actions.ActionRegistry; +import org.xmind.gef.ui.actions.IActionRegistry; +import org.xmind.gef.ui.actions.ICommandStackAction; +import org.xmind.gef.ui.internal.GEFPlugin; +import org.xmind.gef.util.EventListenerSupport; +import org.xmind.gef.util.IEventDispatcher; +import org.xmind.ui.tabfolder.DelegatedSelectionProvider; +import org.xmind.ui.tabfolder.IDelegatedSelectionProvider; +import org.xmind.ui.tabfolder.IPageClosedListener; + +/** + * @author Brian Sun + */ +public abstract class GraphicalEditor extends EditorPart + implements IGraphicalEditor, ICommandStackListener { + + protected class PageInputSelectionProvider implements ISelectionProvider { + + private EventListenerSupport listeners = new EventListenerSupport(); + + public void addSelectionChangedListener( + ISelectionChangedListener listener) { + listeners.addListener(ISelectionChangedListener.class, listener); + } + + public ISelection getSelection() { + IGraphicalEditorPage page = getActivePageInstance(); + if (page != null) { + Object pageInput = page.getInput(); + if (pageInput != null) { + return new StructuredSelection(pageInput); + } + } + return StructuredSelection.EMPTY; + } + + public void removeSelectionChangedListener( + ISelectionChangedListener listener) { + listeners.removeListener(ISelectionChangedListener.class, listener); + } + + public void setSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + Object pageInput = ((IStructuredSelection) selection) + .getFirstElement(); + if (pageInput != null) { + ensurePageVisible(pageInput); + } + } + } + + protected void firePageChanged() { + fireSelectionChanged( + new SelectionChangedEvent(this, getSelection())); + } + + private void fireSelectionChanged(final SelectionChangedEvent event) { + listeners.fireEvent(ISelectionChangedListener.class, + new IEventDispatcher() { + + public void dispatch(Object listener) { + ((ISelectionChangedListener) listener) + .selectionChanged(event); + } + }); + } + + } + + protected class MultiPageSelectionProvider + extends DelegatedSelectionProvider { + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.tabfolder.DelegatedSelectionProvider#setSelection(org + * .eclipse.jface.viewers.ISelection) + */ + @Override + public void setSelection(ISelection selection) { + Object input = findOwnedInput(selection); + if (input != null) { + ensurePageVisible(input); + } + super.setSelection(selection); + } + } + + private Composite container = null; + + private IPageContainerPresentation containerPresentation = null; + + private IPageChangedListener presentationHooker = new IPageChangedListener() { + + public void pageChanged(PageChangedEvent event) { + handlePageChange(getActivePage()); + } + }; + + private List pages = new ArrayList(); + + private EventListenerSupport listeners = new EventListenerSupport(); + + private ICommandStack commandStack = null; + + private IMiniBar miniBar = null; + + private IMiniBarContributor miniBarContributor = null; + + private IActionRegistry actionRegistry = null; + + private List csActions = null; + + private int activePageIndex = -1; + + private PageInputSelectionProvider pageInputSelectionProvider = null; + + private MenuManager pagePopupMenu = null; + + private IGlobalActionHandlerService globalActionHandlerService = null; + + /* + * (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, + * org.eclipse.ui.IEditorInput) + */ + @Override + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + setSite(site); + setInput(input); + site.setSelectionProvider(createSelectionProvider()); + setCommandStack(createCommandStack()); + } + + protected ISelectionProvider createSelectionProvider() { + return new MultiPageSelectionProvider(); + } + + protected Object findOwnedInput(ISelection selection) { + return null; + } + + protected Composite getContainer() { + return container; + } + + protected IPageContainerPresentation getContainerPresentation() { + return containerPresentation; + } + + protected void hookContainerPresentation() { + getContainerPresentation().addPageChangedListener(presentationHooker); + } + + public void createPartControl(Composite parent) { + if (containerPresentation == null) { + containerPresentation = createContainerPresentation(); + hookContainerPresentation(); + } + Composite containerParent = createContainerParent(parent); + this.container = containerPresentation.createContainer(containerParent); + createEditorContents(); + } + + protected void createEditorContents() { + if (getContainer() instanceof CTabFolder) { + createMiniBarComposite((CTabFolder) getContainer()); + createPageContextMenu((CTabFolder) getContainer()); + } + } + + private void createMiniBarComposite(CTabFolder tabFolder) { + final Composite composite = new Composite(getContainer(), SWT.None); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + createMiniBar(composite); + final ToolBar control = ((ToolBarManager) miniBar.getToolBarManager()) + .getControl(); + GridData controlData = new GridData(SWT.RIGHT, SWT.FILL, true, true); + control.setLayoutData(controlData); + + tabFolder.setTopRight(composite, SWT.RIGHT); + } + + protected IPageContainerPresentation createContainerPresentation() { + return new TabFolderContainerPresentation(); + } + + /** + * Creates the parent control for the container returned by + * {@link #getContainer() }. + *

+ * Subclasses may extend and must call super implementation first. + *

+ * + * @param parent + * the parent for all of the editors contents. + * @return the parent for this editor's container. Must not be + * null. + */ + protected Composite createContainerParent(Composite parent) { + parent.setLayout(new FillLayout()); + return parent; + } + + public void addPage(IGraphicalEditorPage page) { + page.setEditDomain(createEditDomain(page)); + createPageControl(page); + pages.add(page); + } + + private void createPageControl(IGraphicalEditorPage page) { + page.createPageControl(getContainer()); + Assert.isNotNull(page.getControl()); + Assert.isNotNull(page.getViewer()); + Assert.isNotNull(page.getViewer().getControl()); + addPageControl(page.getControl()); + } + + private void addPageControl(Control pageControl) { + int index = containerPresentation.getPageCount(getContainer()); + containerPresentation.addPage(getContainer(), index, pageControl); + } + + protected EditDomain createEditDomain(IGraphicalEditorPage page) { + return new EditDomain(); + } + + protected void disposeEditDomain(IGraphicalEditorPage page, + EditDomain editDomain) { + editDomain.dispose(); + } + + protected void createPageContextMenu(Composite container) { + if (pagePopupMenu == null) { + pagePopupMenu = createPagePopupMenu(); + String menuId = getSite().getId() + ".page"; //$NON-NLS-1$ + if (isPagePopupMenuDynamic()) { + setupDynamicPopupMenu(container, pagePopupMenu); + } else { + contributeToPagePopupMenu(pagePopupMenu); + } + registerPagePopupMenu(menuId, pagePopupMenu); + } + container.setMenu(pagePopupMenu.createContextMenu(container)); + + } + + private void setupDynamicPopupMenu(final Composite container, + MenuManager popupMenu) { + final boolean[] showsItems = new boolean[1]; + showsItems[0] = false; + popupMenu.setRemoveAllWhenShown(true); + popupMenu.addMenuListener(new IMenuListener() { + + public void menuAboutToShow(IMenuManager manager) { + if (showsItems[0]) { + contributeToPagePopupMenu(manager); + } + } + }); + container.addMenuDetectListener(new MenuDetectListener() { + + public void menuDetected(MenuDetectEvent e) { + CTabFolder folder = (CTabFolder) container; + Point p = folder.toControl(e.x, e.y); + showsItems[0] = !(folder.getClientArea().contains(p) + || folder.getTopRight().getBounds().contains(p)); + } + }); + } + + protected void registerPagePopupMenu(String menuId, MenuManager menu) { + getSite().registerContextMenu(menuId, menu, + getPageInputSelectionProvider()); + } + + protected void contributeToPagePopupMenu(IMenuManager menu) { + IEditorActionBarContributor contributor = getEditorSite() + .getActionBarContributor(); + if (contributor instanceof GraphicalEditorActionBarContributor) { + ((GraphicalEditorActionBarContributor) contributor) + .contributeToPagePopupMenu(menu); + } + } + + protected boolean isPagePopupMenuDynamic() { + return true; + } + + protected MenuManager createPagePopupMenu() { + return new MenuManager(); + } + + public void removePage(IGraphicalEditorPage page) { + removePage(findPage(page)); + } + + protected void removePage(int pageIndex) { + Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount()); + boolean wasActivePage = pageIndex == getActivePage(); + IGraphicalEditorPage page = getPage(pageIndex); + containerPresentation.disposePage(getContainer(), pageIndex); + if (page != null) { + page.dispose(); + } + pages.remove(page); + if (wasActivePage) { + if (pageIndex == getPageCount()) + pageIndex--; + setActivePage(pageIndex); + } + firePageClosed(page); + } + + public IGraphicalEditorPage getPage(int pageIndex) { + if (pageIndex < 0 || pageIndex >= getPageCount()) + return null; + return pages.get(pageIndex); + } + + public int findPage(IGraphicalEditorPage page) { + return pages.indexOf(page); + } + + protected void postSave() { + if (getCommandStack() != null) { + getCommandStack().markSaved(); + } + firePropertyChange(PROP_DIRTY); + } + + public int getPageCount() { + return pages.size(); + } + + public boolean isDirty() { + return getCommandStack() != null && getCommandStack().isDirty(); + } + + /** + * Creates the mini bar on the part control. + *

+ * IMPORTANT: This mini bar contribution relies on the fact that the + * page container is a CTabFolder, so it may do nothing if the + * implementation changes. + *

+ * + * @see #getContainer() + */ + protected final void createMiniBar(Composite parent) { + if (!(getContainer() instanceof CTabFolder)) + return; + + miniBar = new MiniBar(); + initializeMiniBar(miniBar); + if (!((MiniBar) miniBar).isEmpty()) { + createMiniBarControl(miniBar, (CTabFolder) getContainer(), parent); + } + } + + /** + * @param miniBar + */ + private void initializeMiniBar(IMiniBar miniBar) { + if (getMiniBarContributor() != null) { + getMiniBarContributor().init(miniBar, this); + } + } + + /** + * Creates the mini bar's control on the specified tab folder. + * + * @param miniBar + * @param tabFolder + */ + private void createMiniBarControl(IMiniBar miniBar, CTabFolder tabFolder, + Composite parent) { + ((ToolBarManager) miniBar.getToolBarManager()).createControl(parent); + } + + public IMiniBarContributor getMiniBarContributor() { + return miniBarContributor; + } + + public void setMiniBarContributor(IMiniBarContributor miniBarContributor) { + this.miniBarContributor = miniBarContributor; + } + + /** + * @return commandStack + */ + public ICommandStack getCommandStack() { + return commandStack; + } + + protected ICommandStack createCommandStack() { + return new CommandStack(); + } + + public void handleCommandStackEvent(CommandStackEvent event) { + if ((event.getStatus() & GEF.CS_POST_MASK) != 0 + || event.getStatus() == GEF.CS_UPDATED) { + getSite().getShell().getDisplay().asyncExec(new Runnable() { + + public void run() { + firePropertyChange(PROP_DIRTY); + } + }); + } + } + + @Deprecated + protected void fireDirty() { + firePropertyChange(PROP_DIRTY); + } + + /** + * @param commandStack + * the commandStack to set + */ + public void setCommandStack(ICommandStack commandStack) { + ICommandStack oldCS = this.commandStack; + if (commandStack == oldCS) + return; + + this.commandStack = commandStack; + commandStackChanged(oldCS, commandStack); + } + + protected void commandStackChanged(ICommandStack oldCS, + ICommandStack newCS) { + if (oldCS != null) { + unhookCommandStack(oldCS); + } + if (newCS != null) { + hookCommandStack(newCS); + } + for (IGraphicalEditorPage page : getPages()) { + EditDomain domain = page.getEditDomain(); + if (domain != null) { + domain.setCommandStack(newCS); + } + } + if (csActions != null) { + for (ICommandStackAction action : csActions) { + action.setCommandStack(newCS); + } + } + firePropertyChange(PROP_DIRTY); + } + + protected void hookCommandStack(ICommandStack cs) { + cs.addCSListener(this); + } + + protected void unhookCommandStack(ICommandStack cs) { + cs.removeCSListener(this); + } + + @SuppressWarnings("unchecked") + public T getAdapter(Class adapter) { + Object activePage = getSelectedPage(); + if (activePage != null) { + T result = GEFPlugin.getAdapter(activePage, adapter); + if (result != null) + return result; + } + + T result = getEditorAdapter(adapter); + if (result != null) + return result; + + return super.getAdapter(adapter); + } + + protected T getEditorAdapter(Class adapter) { + if (adapter.isInstance(this)) + return adapter.cast(this); + if (adapter == ICommandStack.class) + return adapter.cast(getCommandStack()); + if (adapter == IActionRegistry.class) + return adapter.cast(getActionRegistry()); + if (adapter == IMiniBar.class) + return adapter.cast(miniBar); + if (adapter == IMiniBarContributor.class) + return adapter.cast(getMiniBarContributor()); + if (adapter == IGlobalActionHandlerService.class) { + if (globalActionHandlerService == null) { + globalActionHandlerService = new GlobalActionHandlerService( + this); + } + return adapter.cast(globalActionHandlerService); + } + if (adapter == IGlobalActionHandlerUpdater.class) { + IEditorActionBarContributor contributor = getEditorSite() + .getActionBarContributor(); + if (contributor instanceof IGlobalActionHandlerUpdater) { + return adapter.cast(contributor); + } + return null; + } + return null; + } + + public Object getSelectedPage() { + return getActivePageInstance(); + } + + public IGraphicalEditorPage getActivePageInstance() { + return getPage(getActivePage()); + } + + public void addPageChangedListener(IPageChangedListener listener) { + listeners.addListener(IPageChangedListener.class, listener); + } + + public void removePageChangedListener(IPageChangedListener listener) { + listeners.removeListener(IPageChangedListener.class, listener); + } + + protected void firePageChanged(Object page) { + final PageChangedEvent event = new PageChangedEvent(this, page); + listeners.fireEvent(IPageChangedListener.class, new IEventDispatcher() { + + public void dispatch(Object listener) { + ((IPageChangedListener) listener).pageChanged(event); + } + }); + } + + protected void firePageClosed(final Object page) { + listeners.fireEvent(IPageChangedListener.class, new IEventDispatcher() { + + public void dispatch(Object listener) { + if (listener instanceof IPageClosedListener) { + ((IPageClosedListener) listener).pageClosed(page); + } + } + }); + } + + @SuppressWarnings("deprecation") + protected void handlePageChange(int newPageIndex) { + boolean wasFocused = false; + IGraphicalEditorPage oldActivePage = getPage(activePageIndex); + if (oldActivePage != null && oldActivePage.isActive()) { + wasFocused = oldActivePage.isFocused(); +// EditDomain editDomain = oldActivePage.getEditDomain(); +// if (editDomain != null) { +// editDomain.setActiveTool(GEF.TOOL_DEFAULT); +// } + oldActivePage.setActive(false); + } + + this.activePageIndex = newPageIndex; + IGraphicalEditorPage activePage = getPage(newPageIndex); + if (activePage != null && !activePage.isActive()) { + activePage.setActive(true); + } + if (wasFocused) { + activePage.setFocus(); + } + + IWorkbenchPage page = getSite().getPage(); + if (page != null) { + //Only when this part is current active part, configure editor by use of active editor page. + IWorkbenchPart currentActivePart = page.getActivePart(); + if (currentActivePart == this) { + IEditorActionBarContributor contributor = getEditorSite() + .getActionBarContributor(); + if (contributor != null + && contributor instanceof GraphicalEditorActionBarContributor) { + ((GraphicalEditorActionBarContributor) contributor) + .setActivePage(activePage); + } + } + } + + ISelectionProvider selectionProvider = getSite().getSelectionProvider(); + if (selectionProvider instanceof IDelegatedSelectionProvider) { + ((IDelegatedSelectionProvider) selectionProvider) + .setDelegate(activePage == null ? null + : activePage.getSelectionProvider()); + } + if (getMiniBarContributor() != null) { + getMiniBarContributor().setActivePage(activePage); + } + if (pageInputSelectionProvider != null) { + Object pageInput = activePage == null ? null + : activePage.getInput(); + pageInputSelectionProvider + .setSelection(pageInput == null ? StructuredSelection.EMPTY + : new StructuredSelection(pageInput)); + } + firePageChanged(activePage); + } + + public void setFocus() { + setFocus(getActivePage()); + } + + protected void setFocus(int pageIndex) { + if (pageIndex < 0 || pageIndex >= getPageCount()) { + container.setFocus(); + } else { + IGraphicalEditorPage page = getPage(pageIndex); + if (page != null) { + page.setFocus(); + } else { + Control control = containerPresentation + .getPageControl(getContainer(), pageIndex); + if (control != null && !control.isDisposed()) { + control.setFocus(); + } + } + } + } + + public void movePageTo(int oldIndex, int newIndex) { + IGraphicalEditorPage activePage = getActivePageInstance(); + boolean wasActive = oldIndex == getActivePage(); + pages.add(newIndex, pages.remove(oldIndex)); + for (int i = 0; i < pages.size(); i++) { + IGraphicalEditorPage page = pages.get(i); + boolean wasFocused = page.isFocused(); + containerPresentation.setPageControl(getContainer(), i, + page.getControl()); + if (wasFocused) + page.setFocus(); + page.updatePageTitle(); + } + if (wasActive) { + pages.get(newIndex).getControl().setVisible(true); + setActivePage(newIndex); + } + if (activePage != null) { + containerPresentation.setActivePage(getContainer(), + pages.indexOf(activePage)); + } + } + + public String getPageText(int pageIndex) { + return containerPresentation.getPageText(getContainer(), pageIndex); + } + + public void setPageText(int pageIndex, String text) { + if (text == null) + text = ""; //$NON-NLS-1$ + containerPresentation.setPageText(getContainer(), pageIndex, text); + } + + public int getActivePage() { + return containerPresentation.getActivePage(getContainer()); + } + + public void setActivePage(int pageIndex) { +// Assert.isTrue(pageIndex < getPageCount()); + if (pageIndex < 0 || pageIndex >= getPageCount()) + return; + + if (pageIndex >= 0) { + containerPresentation.setActivePage(getContainer(), pageIndex); + } else { + containerPresentation.setActivePage(getContainer(), + containerPresentation.getPageCount(getContainer()) - 1); + } + handlePageChange(pageIndex); + } + + public IGraphicalEditorPage[] getPages() { + return pages.toArray(new IGraphicalEditorPage[pages.size()]); + } + + protected ISelectionProvider getPageInputSelectionProvider() { + if (pageInputSelectionProvider == null) { + pageInputSelectionProvider = new PageInputSelectionProvider(); + } + return pageInputSelectionProvider; + } + + protected IActionRegistry getActionRegistry() { + if (actionRegistry == null) + actionRegistry = new ActionRegistry(); + return actionRegistry; + } + + @Override + public void dispose() { + if (csActions != null) { + for (ICommandStackAction action : csActions) { + action.setCommandStack(null); + } + csActions = null; + } + if (actionRegistry != null) { + actionRegistry.dispose(); + actionRegistry = null; + } + if (pagePopupMenu != null) { + pagePopupMenu.dispose(); + pagePopupMenu = null; + } + + if (miniBar != null) { + IToolBarManager toolBarManager = miniBar.getToolBarManager(); + if (toolBarManager instanceof ToolBarManager) { + ((ToolBarManager) toolBarManager).dispose(); + } + miniBar = null; + } + + if (miniBarContributor != null) { + miniBarContributor.dispose(); + miniBarContributor = null; + } + + if (commandStack != null) { + if (!commandStack.isDisposed()) + disposeCommandStack(commandStack); + commandStack = null; + } + IWorkbenchPartSite site = getSite(); + if (site != null) { + site.setSelectionProvider(null); + } + disposePages(); + super.dispose(); + } + + protected void disposeCommandStack(ICommandStack commandStack) { + commandStack.dispose(); + } + + private void disposePages() { + if (pages.isEmpty()) + return; + + for (final Object o : pages.toArray()) { + SafeRunner.run(new SafeRunnable() { + + public void run() throws Exception { + IGraphicalEditorPage page = (IGraphicalEditorPage) o; + page.dispose(); + EditDomain editDomain = page.getEditDomain(); + if (editDomain != null) { + disposeEditDomain(page, editDomain); + } + } + }); + } + pages.clear(); + } + + /** + * @param sourceEvent + * @return + */ + public IGraphicalEditorPage findPage(Object input) { + for (IGraphicalEditorPage page : getPages()) { + Object pageInput = page.getInput(); + if (pageInput == input + || (input != null && input.equals(pageInput))) + return page; + } + return null; + } + + public IGraphicalEditorPage ensurePageVisible(Object input) { + IGraphicalEditorPage page = findPage(input); + if (page != null) { + if (page != getActivePageInstance()) { + setActivePage(page.getIndex()); + page = getActivePageInstance(); + } + } + return page; + } + + public boolean navigateTo(Object input, Object... elements) { + IGraphicalEditorPage page = ensurePageVisible(input); + if (page != null) { + if (elements == null) + return true; + ISelectionProvider viewer = page.getSelectionProvider(); + if (viewer != null) { + viewer.setSelection(new StructuredSelection(elements)); + return true; + } + } + return false; + } + + protected void addCommandStackAction(ICommandStackAction action) { + if (csActions == null) + csActions = new ArrayList(); + csActions.add(action); + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorActionBarContributor.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorActionBarContributor.java index a1deb74db..b841c05c0 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorActionBarContributor.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorActionBarContributor.java @@ -81,8 +81,8 @@ public void setActiveEditor(IEditorPart targetEditor) { updateGlobalActions(getActionBars(), targetEditor, activePage); } - private void updateGlobalActions(IActionBars actionBars, - IEditorPart editor, IGraphicalEditorPage page) { + private void updateGlobalActions(IActionBars actionBars, IEditorPart editor, + IGraphicalEditorPage page) { IActionRegistry editorActions = getActionRegistry(editor); IActionRegistry pageActions = getActionRegistry(page); @@ -167,12 +167,12 @@ public void dispose() { actionRegistry.dispose(); actionRegistry = null; } + activeEditor = null; super.dispose(); } /* * (non-Javadoc) - * * @see * org.xmind.gef.ui.editor.IActionBarsUpdater#updateActionBars(org.eclipse * .ui.IActionBars) @@ -184,4 +184,4 @@ public void updateGlobalActionHandlers(IActionBars actionBars) { updateGlobalActions(actionBars, activeEditor, page); } } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPage.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPage.java index 463b06a4e..50a1d015e 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPage.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPage.java @@ -1,411 +1,411 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IEditorActionBarContributor; -import org.xmind.gef.Disposable; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.ui.actions.ActionRegistry; -import org.xmind.gef.ui.actions.IActionRegistry; -import org.xmind.gef.ui.actions.ISelectionAction; - -/** - * @author Brian Sun - */ -public abstract class GraphicalEditorPage extends Disposable - implements IGraphicalEditorPage, ISelectionChangedListener { - - private IGraphicalEditor parent = null; - - private Object input = null; - - private Control control = null; - - private EditDomain domain = null; - - private IGraphicalViewer viewer = null; - - private MenuManager contentPopupMenu = null; - - private boolean active = false; - - private IActionRegistry actionRegistry = null; - - private List selectionActions = null; - - private IPanelContributor panelContributor = null; - - protected void setPanelContributor(IPanelContributor contributor) { - this.panelContributor = contributor; - } - - public IPanelContributor getPanelContributor() { - return panelContributor; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getIndex() - */ - public int getIndex() { - return parent.findPage(this); - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getPageTitle() - */ - public String getPageTitle() { - return parent.getPageText(getIndex()); - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getParentEditor() - */ - public IGraphicalEditor getParentEditor() { - return parent; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getSelectionProvider() - */ - public ISelectionProvider getSelectionProvider() { - return viewer; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#init(org.xmind.gef.ui.editor.GraphicalEditor, - * java.lang.Object) - */ - public void init(IGraphicalEditor parent, Object input) { - this.parent = parent; - this.input = input; - if (input != null) { - installModelListeners(input); - } - - IActionRegistry parentActionRegistry = (IActionRegistry) parent - .getAdapter(IActionRegistry.class); - if (parentActionRegistry != null) { - this.actionRegistry = new ActionRegistry(parentActionRegistry); - } else { - this.actionRegistry = new ActionRegistry(); - } - initPageActions(getActionRegistry()); - } - - protected void installModelListeners(Object input) { - } - - protected void uninstallModelListeners(Object input) { - } - - public Object getInput() { - return input; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#isActive() - */ - public boolean isActive() { - return active; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setActive(boolean) - */ - public void setActive(boolean active) { - this.active = active; - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setIndex(int) - */ - public void setIndex(int index) { - parent.movePageTo(getIndex(), index); - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setPageTitle(java.lang.String) - */ - public void setPageTitle(String title) { - parent.setPageText(getIndex(), title); - } - - public EditDomain getEditDomain() { - return domain; - } - - public void setEditDomain(EditDomain domain) { -// if (this.domain != null && getViewer() != null) { -// this.domain.setViewer(null); -// } - this.domain = domain; - if (getViewer() != null) { - getViewer().setEditDomain(getEditDomain()); - } -// if (domain != null && getViewer() != null) { -// domain.setViewer(getViewer()); -// } - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#createPageControl(org.eclipse.swt.widgets.Composite) - */ - public void createPageControl(Composite parent) { - Panel panel = null; - if (panelContributor != null) { - panel = new Panel(); - panelContributor.init(panel, this); - if (panel.isEmpty()) { - panel = null; - } - } - - Composite container; - if (panel == null) { - container = parent; - } else { - panel.createControls(parent); - container = panel.getContainer(); - } - viewer = createViewer(); - initViewer(viewer); - createViewerControl(viewer, container); - createContentPopupMenu(viewer.getControl()); - - if (panel != null) { - panel.setContent(viewer.getControl()); - panel.update(); - } - - hookViewer(viewer); - configureViewer(viewer); - updateSelectionActions(viewer.getSelection()); - if (panelContributor != null) { - panelContributor.setViewer(viewer); - } - - if (panel != null) { - control = panel.getContainer(); - } else { - control = viewer.getControl(); - } - } - - /** - * @param parent - * @return - */ - protected abstract IGraphicalViewer createViewer(); - - protected abstract void createViewerControl(IGraphicalViewer viewer, - Composite parent); - - public Control getControl() { - return control; - } - - protected void createContentPopupMenu(Control control) { - if (contentPopupMenu == null) { - contentPopupMenu = createContentPopupMenu(); - String menuId = getParentEditor().getSite().getId() + ".content"; //$NON-NLS-1$ - initContentPopupMenu(contentPopupMenu); - registerContentPopupMenu(menuId, contentPopupMenu); - } - control.setMenu(contentPopupMenu.createContextMenu(control)); - } - - protected void registerContentPopupMenu(String menuId, MenuManager menu) { - getParentEditor().getSite().registerContextMenu(menuId, menu, - getSelectionProvider()); - } - - protected MenuManager createContentPopupMenu() { - return new MenuManager(); - } - - protected void initContentPopupMenu(MenuManager menu) { - if (isContentPopupMenuDynamic()) { - menu.setRemoveAllWhenShown(true); - menu.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - contributeToContentPopupMenu(manager); - } - }); - } else { - contributeToContentPopupMenu(menu); - } - } - - protected boolean isContentPopupMenuDynamic() { - return true; - } - - protected void contributeToContentPopupMenu(IMenuManager menu) { - IEditorActionBarContributor contributor = getParentEditor() - .getEditorSite().getActionBarContributor(); - if (contributor instanceof GraphicalEditorActionBarContributor) { - ((GraphicalEditorActionBarContributor) contributor) - .contributeToContentPopupMenu(menu); - } - } - - protected void initPageActions(IActionRegistry actionRegistry) { - } - - protected void initViewer(IGraphicalViewer viewer) { - if (getEditDomain() != null) { - viewer.setEditDomain(getEditDomain()); - } - viewer.getProperties().set(VIEWER_EDITOR_PAGE, this); - } - - protected void configureViewer(IGraphicalViewer viewer) { - viewer.setInput(createViewerInput()); - } - - protected Object createViewerInput() { - return getInput(); - } - - protected void hookViewer(IGraphicalViewer viewer) { - viewer.addSelectionChangedListener(this); - } - - protected void unhookViewer(IGraphicalViewer viewer) { - viewer.removeSelectionChangedListener(this); - } - - /** - * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setFocus() - */ - public void setFocus() { - if (viewer == null) - return; - Control focusControl = viewer.getControl(); - if (focusControl != null && !focusControl.isDisposed()) { - focusControl.setFocus(); - } - } - - public boolean isFocused() { - return hasFocusControl(getControl()); - } - - private boolean hasFocusControl(Control c) { - if (c == null || c.isDisposed()) - return false; - if (c.isFocusControl()) - return true; - if (c instanceof Composite) { - for (Control child : ((Composite) c).getChildren()) { - if (hasFocusControl(child)) - return true; - } - } - return true; - } - - public IGraphicalViewer getViewer() { - return viewer; - } - - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter == IActionRegistry.class) - return getActionRegistry(); - if (adapter == IGraphicalViewer.class || adapter == IViewer.class) - return getViewer(); - if (adapter == EditDomain.class) - return getEditDomain(); - return null; - } - - protected IActionRegistry getActionRegistry() { - if (actionRegistry == null) - actionRegistry = new ActionRegistry(); - return actionRegistry; - } - - protected void addSelectionAction(ISelectionAction action) { - if (selectionActions == null) - selectionActions = new ArrayList(); - selectionActions.add(action); - } - - public void selectionChanged(SelectionChangedEvent event) { - updateSelectionActions(event.getSelection()); - } - - protected void updateSelectionActions(ISelection selection) { - if (selectionActions != null) { - for (ISelectionAction action : selectionActions) { - action.setSelection(selection); - } - } - } - - /** - * @see org.xmind.util.Disposable#clear() - */ - @Override - public void dispose() { - if (panelContributor != null) { - panelContributor.dispose(); - } - if (selectionActions != null) { - for (ISelectionAction action : selectionActions) { - action.setSelection(null); - } - selectionActions = null; - } - if (actionRegistry != null) { - actionRegistry.dispose(); - actionRegistry = null; - } - if (getInput() != null) { - uninstallModelListeners(getInput()); - } - if (contentPopupMenu != null) { - contentPopupMenu.dispose(); - contentPopupMenu = null; - } - if (viewer != null) { - unhookViewer(viewer); -// if (domain != null) { -// domain.setViewer(null); -// domain.dispose(); -// } - if (viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.getControl().dispose(); - } -// viewer = null; - } - super.dispose(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorActionBarContributor; +import org.xmind.gef.Disposable; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.ui.actions.ActionRegistry; +import org.xmind.gef.ui.actions.IActionRegistry; +import org.xmind.gef.ui.actions.ISelectionAction; + +/** + * @author Brian Sun + */ +public abstract class GraphicalEditorPage extends Disposable + implements IGraphicalEditorPage, ISelectionChangedListener { + + private IGraphicalEditor parent = null; + + private Object input = null; + + private Control control = null; + + private EditDomain domain = null; + + private IGraphicalViewer viewer = null; + + private MenuManager contentPopupMenu = null; + + private boolean active = false; + + private IActionRegistry actionRegistry = null; + + private List selectionActions = null; + + private IPanelContributor panelContributor = null; + + protected void setPanelContributor(IPanelContributor contributor) { + this.panelContributor = contributor; + } + + public IPanelContributor getPanelContributor() { + return panelContributor; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getIndex() + */ + public int getIndex() { + return parent.findPage(this); + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getPageTitle() + */ + public String getPageTitle() { + return parent.getPageText(getIndex()); + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getParentEditor() + */ + public IGraphicalEditor getParentEditor() { + return parent; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getSelectionProvider() + */ + public ISelectionProvider getSelectionProvider() { + return viewer; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#init(org.xmind.gef.ui.editor.GraphicalEditor, + * java.lang.Object) + */ + public void init(IGraphicalEditor parent, Object input) { + this.parent = parent; + this.input = input; + if (input != null) { + installModelListeners(input); + } + + IActionRegistry parentActionRegistry = (IActionRegistry) parent + .getAdapter(IActionRegistry.class); + if (parentActionRegistry != null) { + this.actionRegistry = new ActionRegistry(parentActionRegistry); + } else { + this.actionRegistry = new ActionRegistry(); + } + initPageActions(getActionRegistry()); + } + + protected void installModelListeners(Object input) { + } + + protected void uninstallModelListeners(Object input) { + } + + public Object getInput() { + return input; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#isActive() + */ + public boolean isActive() { + return active; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setActive(boolean) + */ + public void setActive(boolean active) { + this.active = active; + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setIndex(int) + */ + public void setIndex(int index) { + parent.movePageTo(getIndex(), index); + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setPageTitle(java.lang.String) + */ + public void setPageTitle(String title) { + parent.setPageText(getIndex(), title); + } + + public EditDomain getEditDomain() { + return domain; + } + + public void setEditDomain(EditDomain domain) { +// if (this.domain != null && getViewer() != null) { +// this.domain.setViewer(null); +// } + this.domain = domain; + if (getViewer() != null) { + getViewer().setEditDomain(getEditDomain()); + } +// if (domain != null && getViewer() != null) { +// domain.setViewer(getViewer()); +// } + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#createPageControl(org.eclipse.swt.widgets.Composite) + */ + public void createPageControl(Composite parent) { + Panel panel = null; + if (panelContributor != null) { + panel = new Panel(); + panelContributor.init(panel, this); + if (panel.isEmpty()) { + panel = null; + } + } + + Composite container; + if (panel == null) { + container = parent; + } else { + panel.createControls(parent); + container = panel.getContainer(); + } + viewer = createViewer(); + initViewer(viewer); + createViewerControl(viewer, container); + createContentPopupMenu(viewer.getControl()); + + if (panel != null) { + panel.setContent(viewer.getControl()); + panel.update(); + } + + hookViewer(viewer); + configureViewer(viewer); + updateSelectionActions(viewer.getSelection()); + if (panelContributor != null) { + panelContributor.setViewer(viewer); + } + + if (panel != null) { + control = panel.getContainer(); + } else { + control = viewer.getControl(); + } + } + + /** + * @param parent + * @return + */ + protected abstract IGraphicalViewer createViewer(); + + protected abstract void createViewerControl(IGraphicalViewer viewer, + Composite parent); + + public Control getControl() { + return control; + } + + protected void createContentPopupMenu(Control control) { + if (contentPopupMenu == null) { + contentPopupMenu = createContentPopupMenu(); + String menuId = getParentEditor().getSite().getId() + ".content"; //$NON-NLS-1$ + initContentPopupMenu(contentPopupMenu); + registerContentPopupMenu(menuId, contentPopupMenu); + } + control.setMenu(contentPopupMenu.createContextMenu(control)); + } + + protected void registerContentPopupMenu(String menuId, MenuManager menu) { + getParentEditor().getSite().registerContextMenu(menuId, menu, + getSelectionProvider()); + } + + protected MenuManager createContentPopupMenu() { + return new MenuManager(); + } + + protected void initContentPopupMenu(MenuManager menu) { + if (isContentPopupMenuDynamic()) { + menu.setRemoveAllWhenShown(true); + menu.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + contributeToContentPopupMenu(manager); + } + }); + } else { + contributeToContentPopupMenu(menu); + } + } + + protected boolean isContentPopupMenuDynamic() { + return true; + } + + protected void contributeToContentPopupMenu(IMenuManager menu) { + IEditorActionBarContributor contributor = getParentEditor() + .getEditorSite().getActionBarContributor(); + if (contributor instanceof GraphicalEditorActionBarContributor) { + ((GraphicalEditorActionBarContributor) contributor) + .contributeToContentPopupMenu(menu); + } + } + + protected void initPageActions(IActionRegistry actionRegistry) { + } + + protected void initViewer(IGraphicalViewer viewer) { + if (getEditDomain() != null) { + viewer.setEditDomain(getEditDomain()); + } + viewer.getProperties().set(VIEWER_EDITOR_PAGE, this); + } + + protected void configureViewer(IGraphicalViewer viewer) { + viewer.setInput(createViewerInput()); + } + + protected Object createViewerInput() { + return getInput(); + } + + protected void hookViewer(IGraphicalViewer viewer) { + viewer.addSelectionChangedListener(this); + } + + protected void unhookViewer(IGraphicalViewer viewer) { + viewer.removeSelectionChangedListener(this); + } + + /** + * @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setFocus() + */ + public void setFocus() { + if (viewer == null) + return; + Control focusControl = viewer.getControl(); + if (focusControl != null && !focusControl.isDisposed()) { + focusControl.setFocus(); + } + } + + public boolean isFocused() { + return hasFocusControl(getControl()); + } + + private boolean hasFocusControl(Control c) { + if (c == null || c.isDisposed()) + return false; + if (c.isFocusControl()) + return true; + if (c instanceof Composite) { + for (Control child : ((Composite) c).getChildren()) { + if (hasFocusControl(child)) + return true; + } + } + return true; + } + + public IGraphicalViewer getViewer() { + return viewer; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter == IActionRegistry.class) + return getActionRegistry(); + if (adapter == IGraphicalViewer.class || adapter == IViewer.class) + return getViewer(); + if (adapter == EditDomain.class) + return getEditDomain(); + return null; + } + + protected IActionRegistry getActionRegistry() { + if (actionRegistry == null) + actionRegistry = new ActionRegistry(); + return actionRegistry; + } + + protected void addSelectionAction(ISelectionAction action) { + if (selectionActions == null) + selectionActions = new ArrayList(); + selectionActions.add(action); + } + + public void selectionChanged(SelectionChangedEvent event) { + updateSelectionActions(event.getSelection()); + } + + protected void updateSelectionActions(ISelection selection) { + if (selectionActions != null) { + for (ISelectionAction action : selectionActions) { + action.setSelection(selection); + } + } + } + + /** + * @see org.xmind.util.Disposable#clear() + */ + @Override + public void dispose() { + if (panelContributor != null) { + panelContributor.dispose(); + } + if (selectionActions != null) { + for (ISelectionAction action : selectionActions) { + action.setSelection(null); + } + selectionActions = null; + } + if (actionRegistry != null) { + actionRegistry.dispose(); + actionRegistry = null; + } + if (getInput() != null) { + uninstallModelListeners(getInput()); + } + if (contentPopupMenu != null) { + contentPopupMenu.dispose(); + contentPopupMenu = null; + } + if (viewer != null) { + unhookViewer(viewer); +// if (domain != null) { +// domain.setViewer(null); +// domain.dispose(); +// } + if (viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.getControl().dispose(); + } +// viewer = null; + } + super.dispose(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPagePopupPreviewHelper.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPagePopupPreviewHelper.java index b53192f70..855665fd7 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPagePopupPreviewHelper.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/GraphicalEditorPagePopupPreviewHelper.java @@ -23,6 +23,8 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; @@ -86,7 +88,7 @@ protected int getAppliedBorderWidth() { } private void hookTabFolder() { - Listener listener = new Listener() { + final Listener listener = new Listener() { public void handleEvent(Event event) { switch (event.type) { case SWT.MouseHover: @@ -120,6 +122,16 @@ public void handleEvent(Event event) { tabFolder.addListener(SWT.Dispose, listener); tabFolder.addListener(SWT.FocusOut, listener); tabFolder.getShell().addListener(SWT.Deactivate, listener); + tabFolder.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + if (tabFolder != null && !tabFolder.isDisposed()) { + tabFolder.getShell().removeListener(SWT.Deactivate, + listener); + } + + } + }); } private void showPopup(Event e) { @@ -402,4 +414,4 @@ private void checkPopup(Event e) { } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditable.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditable.java index e9b6eed4b..0615be8a3 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditable.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditable.java @@ -1,304 +1,304 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.List; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.xmind.gef.command.ICommandStack; - -/** - * This interface is a base interface that manages data of an editable document. - * - *

- * The primary attribute of an editable object is its URI which locates the - * content. In a typical scenario, a client opens an editable document by - * calling {@link #open(IProgressMonitor)}, makes changes to its content, which - * can be saved to the URI by calling {@link #save(IProgressMonitor)}, and - * finally closes the document by calling {@link #close(IProgressMonitor)}. - *

- * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IEditable extends IAdaptable { - - /** - * State bit: The editable is open and has no errors or conflicts. - */ - int NORMAL = 0; - - /** - * State bit: The editable has either not been successfully opened, or has - * been since closed. Its properties might not be valid. - */ - int CLOSED = 1 << 0; - - /** - * State bit: Asynchronous jobs are being performed. See - * {@link #getProgress()} for detailed progress info. - */ - int IN_PROGRESS = 1 << 1; - - /** - * State bit: Current version is in conflict with another version. - */ - int IN_CONFLICT = 1 << 2; - - /** - * State bit: The editable is being opened. - */ - int OPENING = 1 << 3; - - /** - * State bit: The editable is being saved. - */ - int SAVING = 1 << 4; - - /** - * State bit: The editable is being closed. - */ - int CLOSING = 1 << 5; - - /** - * The maximum progress number. - */ - int MAX_PROGRESS = 10000; - - /** - * - */ - String PROP_NAME = "name"; //$NON-NLS-1$ - String PROP_DESCRIPTION = "description"; //$NON-NLS-1$ - String PROP_MODIFICATION_TIME = "modificationTime"; //$NON-NLS-1$ - String PROP_STATE = "state"; //$NON-NLS-1$ - String PROP_PROGRESS = "progress"; //$NON-NLS-1$ - String PROP_COMMAND_STACK = "commandStack"; //$NON-NLS-1$ - String PROP_ACTIVE_CONTEXT = "activeContext"; //$NON-NLS-1$ - String PROP_EXISTS = "exists"; //$NON-NLS-1$ - String PROP_CAN_SAVE = "canSave"; //$NON-NLS-1$ - String PROP_DIRTY = "dirty"; //$NON-NLS-1$ - String PROP_MESSAGES = "messages"; //$NON-NLS-1$ - - /** - * @return - */ - URI getURI(); - - /** - * Returns the name of this editable, or null if the name is - * undetermined. - * - * @return name of this editable, or null if the name is - * undetermined - */ - String getName(); - - /** - * Returns a short text describing this editable, or null if - * the description is undetermined. May be same with name or not. - * - * @return a short text describing this editable, or null if - * the description is undetermined - */ - String getDescription(); - - /** - * - * @return - */ - long getModificationTime(); - - /** - * - * @return - */ - int getState(); - - /** - * Tests whether this editable is in the given state. - * - * @param state - * @return - */ - boolean isInState(int state); - - /** - * [0, MAX_PROGRESS] - * - * @return - */ - int getProgress(); - - /** - * - * @return - */ - ICommandStack getCommandStack(); - - /** - * - * @return - */ - IEditingContext getActiveContext(); - - /** - * - * @param context - */ - void setActiveContext(IEditingContext context); - - /** - * - * @return - */ - boolean exists(); - - /** - * Opens this editable and loads its content from the URI, or does nothing - * if the editable is already open or is being opened. - * - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - void open(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException; - - /** - * Closes this editable and unload its content, after saving any unsaved - * changes, or does nothing if the editable is already closed or never - * opened. - * - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - void close(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException; - - /** - * Checks whether this editable can be saved. - * - * @return - */ - boolean canSave(); - - /** - * Saves this editable to the URI. - * - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - void save(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException; - - /** - * - * @return - */ - boolean isDirty(); - - /** - * - */ - void discardChanges(); - - /** - * - * @param cleaner - */ - void markDirtyWith(IEditableCleaner cleaner); - - /** - * - * @param cleaner - */ - void unmarkDirtyWith(IEditableCleaner cleaner); - - /** - * - * @return - */ - List getMessages(); - - /** - * - * @param message - */ - void addMessage(IInteractiveMessage message); - - /** - * - * @param message - */ - void removeMessage(IInteractiveMessage message); - - /** - * - * @param listener - */ - void addPropertyChangeListener(IPropertyChangeListener listener); - - /** - * - * @param listener - */ - void removePropertyChangeListener(IPropertyChangeListener listener); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.xmind.gef.command.ICommandStack; + +/** + * This interface is a base interface that manages data of an editable document. + * + *

+ * The primary attribute of an editable object is its URI which locates the + * content. In a typical scenario, a client opens an editable document by + * calling {@link #open(IProgressMonitor)}, makes changes to its content, which + * can be saved to the URI by calling {@link #save(IProgressMonitor)}, and + * finally closes the document by calling {@link #close(IProgressMonitor)}. + *

+ * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IEditable extends IAdaptable { + + /** + * State bit: The editable is open and has no errors or conflicts. + */ + int NORMAL = 0; + + /** + * State bit: The editable has either not been successfully opened, or has + * been since closed. Its properties might not be valid. + */ + int CLOSED = 1 << 0; + + /** + * State bit: Asynchronous jobs are being performed. See + * {@link #getProgress()} for detailed progress info. + */ + int IN_PROGRESS = 1 << 1; + + /** + * State bit: Current version is in conflict with another version. + */ + int IN_CONFLICT = 1 << 2; + + /** + * State bit: The editable is being opened. + */ + int OPENING = 1 << 3; + + /** + * State bit: The editable is being saved. + */ + int SAVING = 1 << 4; + + /** + * State bit: The editable is being closed. + */ + int CLOSING = 1 << 5; + + /** + * The maximum progress number. + */ + int MAX_PROGRESS = 10000; + + /** + * + */ + String PROP_NAME = "name"; //$NON-NLS-1$ + String PROP_DESCRIPTION = "description"; //$NON-NLS-1$ + String PROP_MODIFICATION_TIME = "modificationTime"; //$NON-NLS-1$ + String PROP_STATE = "state"; //$NON-NLS-1$ + String PROP_PROGRESS = "progress"; //$NON-NLS-1$ + String PROP_COMMAND_STACK = "commandStack"; //$NON-NLS-1$ + String PROP_ACTIVE_CONTEXT = "activeContext"; //$NON-NLS-1$ + String PROP_EXISTS = "exists"; //$NON-NLS-1$ + String PROP_CAN_SAVE = "canSave"; //$NON-NLS-1$ + String PROP_DIRTY = "dirty"; //$NON-NLS-1$ + String PROP_MESSAGES = "messages"; //$NON-NLS-1$ + + /** + * @return + */ + URI getURI(); + + /** + * Returns the name of this editable, or null if the name is + * undetermined. + * + * @return name of this editable, or null if the name is + * undetermined + */ + String getName(); + + /** + * Returns a short text describing this editable, or null if + * the description is undetermined. May be same with name or not. + * + * @return a short text describing this editable, or null if + * the description is undetermined + */ + String getDescription(); + + /** + * + * @return + */ + long getModificationTime(); + + /** + * + * @return + */ + int getState(); + + /** + * Tests whether this editable is in the given state. + * + * @param state + * @return + */ + boolean isInState(int state); + + /** + * [0, MAX_PROGRESS] + * + * @return + */ + int getProgress(); + + /** + * + * @return + */ + ICommandStack getCommandStack(); + + /** + * + * @return + */ + IEditingContext getActiveContext(); + + /** + * + * @param context + */ + void setActiveContext(IEditingContext context); + + /** + * + * @return + */ + boolean exists(); + + /** + * Opens this editable and loads its content from the URI, or does nothing + * if the editable is already open or is being opened. + * + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + void open(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException; + + /** + * Closes this editable and unload its content, after saving any unsaved + * changes, or does nothing if the editable is already closed or never + * opened. + * + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + void close(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException; + + /** + * Checks whether this editable can be saved. + * + * @return + */ + boolean canSave(); + + /** + * Saves this editable to the URI. + * + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + void save(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException; + + /** + * + * @return + */ + boolean isDirty(); + + /** + * + */ + void discardChanges(); + + /** + * + * @param cleaner + */ + void markDirtyWith(IEditableCleaner cleaner); + + /** + * + * @param cleaner + */ + void unmarkDirtyWith(IEditableCleaner cleaner); + + /** + * + * @return + */ + List getMessages(); + + /** + * + * @param message + */ + void addMessage(IInteractiveMessage message); + + /** + * + * @param message + */ + void removeMessage(IInteractiveMessage message); + + /** + * + * @param listener + */ + void addPropertyChangeListener(IPropertyChangeListener listener); + + /** + * + * @param listener + */ + void removePropertyChangeListener(IPropertyChangeListener listener); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditableCleaner.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditableCleaner.java index 19a56099d..f5c173941 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditableCleaner.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditableCleaner.java @@ -1,30 +1,30 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IEditableCleaner { - - void cleanEditable(IProgressMonitor monitor, IEditable editable) - throws InterruptedException, InvocationTargetException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IEditableCleaner { + + void cleanEditable(IProgressMonitor monitor, IEditable editable) + throws InterruptedException, InvocationTargetException; + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditingContext.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditingContext.java index ae580c6a8..1abd4ec82 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditingContext.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IEditingContext.java @@ -1,31 +1,31 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import org.eclipse.core.runtime.IAdaptable; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IEditingContext extends IAdaptable { - - IEditingContext NULL = new IEditingContext() { - public T getAdapter(Class adapter) { - return null; - } - }; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IEditingContext extends IAdaptable { + + IEditingContext NULL = new IEditingContext() { + public T getAdapter(Class adapter) { + return null; + } + }; + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerService.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerService.java index 30bf1aa19..7f7df948c 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerService.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerService.java @@ -1,29 +1,29 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.ui.editor; - -import org.eclipse.ui.IActionBars; - -/** - * @author Frank Shaka - * - */ -public interface IGlobalActionHandlerService { - - void addActionBars(IActionBars actionBars); - - void removeActionBars(IActionBars actionBars); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.ui.editor; + +import org.eclipse.ui.IActionBars; + +/** + * @author Frank Shaka + * + */ +public interface IGlobalActionHandlerService { + + void addActionBars(IActionBars actionBars); + + void removeActionBars(IActionBars actionBars); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerUpdater.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerUpdater.java index 11bf68aac..28cc38269 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerUpdater.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IGlobalActionHandlerUpdater.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.ui.editor; - -import org.eclipse.ui.IActionBars; - -/** - * @author Frank Shaka - * - */ -public interface IGlobalActionHandlerUpdater { - - void updateGlobalActionHandlers(IActionBars actionBars); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.ui.editor; + +import org.eclipse.ui.IActionBars; + +/** + * @author Frank Shaka + * + */ +public interface IGlobalActionHandlerUpdater { + + void updateGlobalActionHandlers(IActionBars actionBars); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IInteractiveMessage.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IInteractiveMessage.java index 5a04727bd..7a752d64c 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IInteractiveMessage.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IInteractiveMessage.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.gef.ui.editor; - -import java.util.List; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.IMessageProvider; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IInteractiveMessage extends IMessageProvider { - - List getActions(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.gef.ui.editor; + +import java.util.List; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IMessageProvider; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IInteractiveMessage extends IMessageProvider { + + List getActions(); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBar.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBar.java index cc4fb000e..f24b4db50 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBar.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBar.java @@ -1,28 +1,28 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import org.eclipse.jface.action.IToolBarManager; - -public interface IMiniBar { - - IToolBarManager getToolBarManager(); - - /** - * @deprecated Use {{@link #getToolBarManager()}'s - * update(boolean) method to update the mini bar. - */ - void updateBar(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import org.eclipse.jface.action.IToolBarManager; + +public interface IMiniBar { + + IToolBarManager getToolBarManager(); + + /** + * @deprecated Use {{@link #getToolBarManager()}'s + * update(boolean) method to update the mini bar. + */ + void updateBar(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBarContributor.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBarContributor.java index 9fc7f75cd..416162e56 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBarContributor.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/IMiniBarContributor.java @@ -1,33 +1,33 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import org.eclipse.core.runtime.IAdaptable; - -public interface IMiniBarContributor extends IAdaptable { - - void init(IMiniBar bar, IGraphicalEditor editor); - - void dispose(); - - /** - * - * @param page - * @deprecated Use - * {@link IGraphicalEditor#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)} - * to listen to active page change events. - */ - void setActivePage(IGraphicalEditorPage page); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import org.eclipse.core.runtime.IAdaptable; + +public interface IMiniBarContributor extends IAdaptable { + + void init(IMiniBar bar, IGraphicalEditor editor); + + void dispose(); + + /** + * + * @param page + * @deprecated Use + * {@link IGraphicalEditor#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)} + * to listen to active page change events. + */ + void setActivePage(IGraphicalEditorPage page); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/InteractiveMessage.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/InteractiveMessage.java index 586657eb1..d0e2d5a87 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/InteractiveMessage.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/InteractiveMessage.java @@ -1,86 +1,86 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.action.IAction; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class InteractiveMessage implements IInteractiveMessage { - - private final int type; - - private final String content; - - private final List actions; - - /** - * - */ - public InteractiveMessage(int type, String content) { - this(type, content, Collections. emptyList()); - } - - /** - * - */ - public InteractiveMessage(int type, String content, List actions) { - Assert.isLegal(content != null); - this.type = type; - this.content = content; - this.actions = actions == null ? Collections. emptyList() - : new ArrayList(actions); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() - */ - @Override - public String getMessage() { - return content; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() - */ - @Override - public int getMessageType() { - return type; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.ui.editor.IInteractiveMessage#getActions() - */ - @Override - public List getActions() { - return Collections.unmodifiableList(actions); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.action.IAction; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class InteractiveMessage implements IInteractiveMessage { + + private final int type; + + private final String content; + + private final List actions; + + /** + * + */ + public InteractiveMessage(int type, String content) { + this(type, content, Collections. emptyList()); + } + + /** + * + */ + public InteractiveMessage(int type, String content, List actions) { + Assert.isLegal(content != null); + this.type = type; + this.content = content; + this.actions = actions == null ? Collections. emptyList() + : new ArrayList(actions); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + @Override + public String getMessage() { + return content; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + @Override + public int getMessageType() { + return type; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.ui.editor.IInteractiveMessage#getActions() + */ + @Override + public List getActions() { + return Collections.unmodifiableList(actions); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/MultiGraphicalPageSelectionProvider.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/MultiGraphicalPageSelectionProvider.java index 5f5c954a7..5694ed8cd 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/MultiGraphicalPageSelectionProvider.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/MultiGraphicalPageSelectionProvider.java @@ -1,165 +1,165 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.IPostSelectionProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Display; -import org.xmind.ui.tabfolder.DelegatedSelectionProvider; - -/** - * - * @author Frank Shaka - * @deprecated Use {@link DelegatedSelectionProvider} instead. - */ -public class MultiGraphicalPageSelectionProvider implements - IPostSelectionProvider, ISelectionChangedListener { - - private List listeners = new ArrayList(); - - private List postListeners = new ArrayList(); - - private IGraphicalEditorPage activePage = null; - - private class PostSelectionDispatcher implements Runnable { - - private ISelection selection; - - /** - * - */ - public PostSelectionDispatcher(ISelection selection) { - this.selection = selection; - } - - public void schedule() { - postSelectionDispatcher = this; - Display.getCurrent().asyncExec(this); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - public void run() { - if (postSelectionDispatcher != this) - return; - try { - firePostSelectionChangedEvent(new SelectionChangedEvent( - MultiGraphicalPageSelectionProvider.this, selection)); - } finally { - postSelectionDispatcher = null; - } - } - } - - private PostSelectionDispatcher postSelectionDispatcher = null; - - public void addPostSelectionChangedListener( - ISelectionChangedListener listener) { - postListeners.add(listener); - } - - public void addSelectionChangedListener(ISelectionChangedListener listener) { - listeners.add(listener); - } - - public void removePostSelectionChangedListener( - ISelectionChangedListener listener) { - postListeners.remove(listener); - } - - public void removeSelectionChangedListener( - ISelectionChangedListener listener) { - listeners.remove(listener); - } - - public void setActivePage(IGraphicalEditorPage page) { - if (page == this.activePage) - return; - if (this.activePage != null) { - ISelectionProvider selectionProvider = this.activePage - .getSelectionProvider(); - if (selectionProvider != null) - selectionProvider.removeSelectionChangedListener(this); - } - this.activePage = page; - if (page != null) { - ISelectionProvider selectionProvider = page.getSelectionProvider(); - if (selectionProvider != null) - selectionProvider.addSelectionChangedListener(this); - } - handlePageSelectionChanged(getSelection()); - } - - private void handlePageSelectionChanged(ISelection selection) { - fireSelectionChangedEvent(new SelectionChangedEvent(this, selection)); - new PostSelectionDispatcher(selection).schedule(); - } - - protected void fireSelectionChangedEvent(SelectionChangedEvent event) { - fireSelectionChangedEvent( - new SelectionChangedEvent(this, event.getSelection()), - listeners); - } - - protected void firePostSelectionChangedEvent(SelectionChangedEvent event) { - fireSelectionChangedEvent( - new SelectionChangedEvent(this, event.getSelection()), - postListeners); - } - - private void fireSelectionChangedEvent(SelectionChangedEvent event, - List listeners) { - for (Object listener : listeners.toArray()) { - ((ISelectionChangedListener) listener).selectionChanged(event); - } - } - - public ISelection getSelection() { - if (activePage != null) { - ISelectionProvider selectionProvider = activePage - .getSelectionProvider(); - if (selectionProvider != null) - return selectionProvider.getSelection(); - } - return StructuredSelection.EMPTY; - } - - public void setSelection(ISelection selection) { - if (activePage != null) { - ISelectionProvider selectionProvider = activePage - .getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.setSelection(selection); - } - } - } - - /** - * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) - */ - public void selectionChanged(SelectionChangedEvent event) { - handlePageSelectionChanged(event.getSelection()); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.xmind.ui.tabfolder.DelegatedSelectionProvider; + +/** + * + * @author Frank Shaka + * @deprecated Use {@link DelegatedSelectionProvider} instead. + */ +public class MultiGraphicalPageSelectionProvider implements + IPostSelectionProvider, ISelectionChangedListener { + + private List listeners = new ArrayList(); + + private List postListeners = new ArrayList(); + + private IGraphicalEditorPage activePage = null; + + private class PostSelectionDispatcher implements Runnable { + + private ISelection selection; + + /** + * + */ + public PostSelectionDispatcher(ISelection selection) { + this.selection = selection; + } + + public void schedule() { + postSelectionDispatcher = this; + Display.getCurrent().asyncExec(this); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + public void run() { + if (postSelectionDispatcher != this) + return; + try { + firePostSelectionChangedEvent(new SelectionChangedEvent( + MultiGraphicalPageSelectionProvider.this, selection)); + } finally { + postSelectionDispatcher = null; + } + } + } + + private PostSelectionDispatcher postSelectionDispatcher = null; + + public void addPostSelectionChangedListener( + ISelectionChangedListener listener) { + postListeners.add(listener); + } + + public void addSelectionChangedListener(ISelectionChangedListener listener) { + listeners.add(listener); + } + + public void removePostSelectionChangedListener( + ISelectionChangedListener listener) { + postListeners.remove(listener); + } + + public void removeSelectionChangedListener( + ISelectionChangedListener listener) { + listeners.remove(listener); + } + + public void setActivePage(IGraphicalEditorPage page) { + if (page == this.activePage) + return; + if (this.activePage != null) { + ISelectionProvider selectionProvider = this.activePage + .getSelectionProvider(); + if (selectionProvider != null) + selectionProvider.removeSelectionChangedListener(this); + } + this.activePage = page; + if (page != null) { + ISelectionProvider selectionProvider = page.getSelectionProvider(); + if (selectionProvider != null) + selectionProvider.addSelectionChangedListener(this); + } + handlePageSelectionChanged(getSelection()); + } + + private void handlePageSelectionChanged(ISelection selection) { + fireSelectionChangedEvent(new SelectionChangedEvent(this, selection)); + new PostSelectionDispatcher(selection).schedule(); + } + + protected void fireSelectionChangedEvent(SelectionChangedEvent event) { + fireSelectionChangedEvent( + new SelectionChangedEvent(this, event.getSelection()), + listeners); + } + + protected void firePostSelectionChangedEvent(SelectionChangedEvent event) { + fireSelectionChangedEvent( + new SelectionChangedEvent(this, event.getSelection()), + postListeners); + } + + private void fireSelectionChangedEvent(SelectionChangedEvent event, + List listeners) { + for (Object listener : listeners.toArray()) { + ((ISelectionChangedListener) listener).selectionChanged(event); + } + } + + public ISelection getSelection() { + if (activePage != null) { + ISelectionProvider selectionProvider = activePage + .getSelectionProvider(); + if (selectionProvider != null) + return selectionProvider.getSelection(); + } + return StructuredSelection.EMPTY; + } + + public void setSelection(ISelection selection) { + if (activePage != null) { + ISelectionProvider selectionProvider = activePage + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.setSelection(selection); + } + } + } + + /** + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + handlePageSelectionChanged(event.getSelection()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Panel.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Panel.java index dcd657abb..f9885eeed 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Panel.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/Panel.java @@ -1,272 +1,272 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.editor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; - -public class Panel implements IPanel { - - private static final List NO_CONTRIBUTIONS = Collections - .emptyList(); - - private Composite container; - - private Control content; - - private Map> contributions = null; - - public void addContribution(int orientation, IPanelContribution contribution) { - if (contribution == null || orientation < TOP || orientation > RIGHT) - return; - - removeContribution(contribution); - if (contributions == null) - contributions = new HashMap>(); - List list = contributions.get(orientation); - if (list == null) { - list = new ArrayList(); - contributions.put(orientation, list); - } - list.add(contribution); - contributionAdded(contribution); - } - - public List getContributions(int orientation) { - if (contributions != null) { - List list = contributions.get(orientation); - if (list != null) - return list; - } - return NO_CONTRIBUTIONS; - } - - public void removeContribution(IPanelContribution contribution) { - if (contribution == null || contributions == null) - return; - for (Integer orientation : contributions.keySet()) { - List list = contributions.get(orientation); - if (list.contains(contribution)) { - list.remove(contribution); - if (list.isEmpty()) { - contributions.remove(orientation); - } - contributionRemoved(contribution); - return; - } - } - } - - private void contributionAdded(IPanelContribution contribution) { - contribution.setPanel(this); - createContributionControl(contribution); - } - - private void createContributionControl(IPanelContribution contribution) { - if (containerExists()) { - contribution.createControl(container); - } - } - - private void contributionRemoved(IPanelContribution contribution) { - disposeContributionControl(contribution); - contribution.setPanel(null); - } - - private void disposeContributionControl(IPanelContribution contribution) { - Control c = contribution.getControl(); - if (c != null) { - c.dispose(); - } - } - - protected boolean isEmpty() { - return contributions == null || contributions.isEmpty(); - } - - public void update() { - if (containerExists()) { - GridLayout layout = getContainerLayout(); - int numColumns = calcNumColumns(); - layout.numColumns = numColumns; - - Control last = null; - last = adaptContributions(TOP, numColumns, last); - last = adaptContributions(LEFT, numColumns, last); - - if (content != null) { -// moveAfter(content, last); - last = content; - GridData data = getControlLayoutData(content); - defaultLayoutData(data); - data.exclude = false; - data.grabExcessHorizontalSpace = true; - data.grabExcessVerticalSpace = true; - data.horizontalAlignment = SWT.FILL; - data.verticalAlignment = SWT.FILL; - data.horizontalSpan = 1; - data.verticalSpan = 1; - last = content; - } - - last = adaptContributions(RIGHT, numColumns, last); - last = adaptContributions(BOTTOM, numColumns, last); - - container.layout(); - } - } - - private Control adaptContributions(int orientation, int numColumns, - Control last) { - if (contributions == null) - return last; - - List list = contributions.get(orientation); - if (list != null) { - for (IPanelContribution contribution : list) { - Control c = contribution.getControl(); - if (c != null && !c.isDisposed()) { - moveAfter(c, last); - last = c; - boolean visible = contribution.isVisible(); - c.setVisible(visible); - GridData data = getControlLayoutData(c); - contributionLayoutData(data, orientation == LEFT - || orientation == RIGHT, orientation == TOP - || orientation == LEFT, visible, numColumns); - } - } - } - return last; - } - - private void contributionLayoutData(GridData data, boolean horizontal, - boolean beginning, boolean visible, int numColumns) { - defaultLayoutData(data); - data.exclude = !visible; - data.grabExcessHorizontalSpace = !horizontal; - data.grabExcessVerticalSpace = horizontal; - data.horizontalAlignment = horizontal ? (beginning ? SWT.LEFT - : SWT.RIGHT) : SWT.FILL; - data.horizontalSpan = horizontal ? 1 : numColumns; - data.verticalAlignment = horizontal ? SWT.FILL : (beginning ? SWT.TOP - : SWT.BOTTOM); - data.verticalSpan = horizontal ? numColumns : 1; - } - - private static void defaultLayoutData(GridData data) { - data.heightHint = SWT.DEFAULT; - data.horizontalIndent = 0; - data.minimumHeight = 0; - data.minimumWidth = 0; - data.verticalIndent = 0; - data.widthHint = SWT.DEFAULT; - } - - private GridData getControlLayoutData(Control c) { - Object data = c.getLayoutData(); - if (data == null || !(data instanceof GridData)) { - data = new GridData(); - c.setLayoutData(data); - } - return (GridData) data; - } - - private static void moveAfter(Control current, Control last) { - if (last == null) - current.moveAbove(null); - else - current.moveBelow(last); - } - - private int calcNumColumns() { - int num = 0; - if (contributions != null) { - List left = contributions.get(LEFT); - if (left != null) { - for (IPanelContribution contribution : left) { - Control c = contribution.getControl(); - if (c != null && !c.isDisposed()) { - num++; - } - } - } - List right = contributions.get(RIGHT); - if (right != null) { - for (IPanelContribution contribution : right) { - Control c = contribution.getControl(); - if (c != null && !c.isDisposed()) { - num++; - } - } - } - } - if (content != null) { - num++; - } - return num; - } - - private GridLayout getContainerLayout() { - Layout layout = container.getLayout(); - if (layout == null || !(layout instanceof GridLayout)) { - GridLayout gridLayout = new GridLayout(); - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginHeight = 0; - gridLayout.marginWidth = 0; - gridLayout.makeColumnsEqualWidth = false; - container.setLayout(gridLayout); - layout = gridLayout; - } - return (GridLayout) layout; - } - - protected void createControls(Composite parent) { - if (container == null || !containerExists()) { - container = new Composite(parent, SWT.NONE); - - if (contributions != null) { - for (List list : contributions.values()) { - for (IPanelContribution contribution : list) { - createContributionControl(contribution); - } - } - } - } - } - - protected Composite getContainer() { - return container; - } - - protected void setContent(Control content) { - this.content = content; - } - - protected boolean containerExists() { - return container != null && !container.isDisposed(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.editor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; + +public class Panel implements IPanel { + + private static final List NO_CONTRIBUTIONS = Collections + .emptyList(); + + private Composite container; + + private Control content; + + private Map> contributions = null; + + public void addContribution(int orientation, IPanelContribution contribution) { + if (contribution == null || orientation < TOP || orientation > RIGHT) + return; + + removeContribution(contribution); + if (contributions == null) + contributions = new HashMap>(); + List list = contributions.get(orientation); + if (list == null) { + list = new ArrayList(); + contributions.put(orientation, list); + } + list.add(contribution); + contributionAdded(contribution); + } + + public List getContributions(int orientation) { + if (contributions != null) { + List list = contributions.get(orientation); + if (list != null) + return list; + } + return NO_CONTRIBUTIONS; + } + + public void removeContribution(IPanelContribution contribution) { + if (contribution == null || contributions == null) + return; + for (Integer orientation : contributions.keySet()) { + List list = contributions.get(orientation); + if (list.contains(contribution)) { + list.remove(contribution); + if (list.isEmpty()) { + contributions.remove(orientation); + } + contributionRemoved(contribution); + return; + } + } + } + + private void contributionAdded(IPanelContribution contribution) { + contribution.setPanel(this); + createContributionControl(contribution); + } + + private void createContributionControl(IPanelContribution contribution) { + if (containerExists()) { + contribution.createControl(container); + } + } + + private void contributionRemoved(IPanelContribution contribution) { + disposeContributionControl(contribution); + contribution.setPanel(null); + } + + private void disposeContributionControl(IPanelContribution contribution) { + Control c = contribution.getControl(); + if (c != null) { + c.dispose(); + } + } + + protected boolean isEmpty() { + return contributions == null || contributions.isEmpty(); + } + + public void update() { + if (containerExists()) { + GridLayout layout = getContainerLayout(); + int numColumns = calcNumColumns(); + layout.numColumns = numColumns; + + Control last = null; + last = adaptContributions(TOP, numColumns, last); + last = adaptContributions(LEFT, numColumns, last); + + if (content != null) { +// moveAfter(content, last); + last = content; + GridData data = getControlLayoutData(content); + defaultLayoutData(data); + data.exclude = false; + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + data.horizontalAlignment = SWT.FILL; + data.verticalAlignment = SWT.FILL; + data.horizontalSpan = 1; + data.verticalSpan = 1; + last = content; + } + + last = adaptContributions(RIGHT, numColumns, last); + last = adaptContributions(BOTTOM, numColumns, last); + + container.layout(); + } + } + + private Control adaptContributions(int orientation, int numColumns, + Control last) { + if (contributions == null) + return last; + + List list = contributions.get(orientation); + if (list != null) { + for (IPanelContribution contribution : list) { + Control c = contribution.getControl(); + if (c != null && !c.isDisposed()) { + moveAfter(c, last); + last = c; + boolean visible = contribution.isVisible(); + c.setVisible(visible); + GridData data = getControlLayoutData(c); + contributionLayoutData(data, orientation == LEFT + || orientation == RIGHT, orientation == TOP + || orientation == LEFT, visible, numColumns); + } + } + } + return last; + } + + private void contributionLayoutData(GridData data, boolean horizontal, + boolean beginning, boolean visible, int numColumns) { + defaultLayoutData(data); + data.exclude = !visible; + data.grabExcessHorizontalSpace = !horizontal; + data.grabExcessVerticalSpace = horizontal; + data.horizontalAlignment = horizontal ? (beginning ? SWT.LEFT + : SWT.RIGHT) : SWT.FILL; + data.horizontalSpan = horizontal ? 1 : numColumns; + data.verticalAlignment = horizontal ? SWT.FILL : (beginning ? SWT.TOP + : SWT.BOTTOM); + data.verticalSpan = horizontal ? numColumns : 1; + } + + private static void defaultLayoutData(GridData data) { + data.heightHint = SWT.DEFAULT; + data.horizontalIndent = 0; + data.minimumHeight = 0; + data.minimumWidth = 0; + data.verticalIndent = 0; + data.widthHint = SWT.DEFAULT; + } + + private GridData getControlLayoutData(Control c) { + Object data = c.getLayoutData(); + if (data == null || !(data instanceof GridData)) { + data = new GridData(); + c.setLayoutData(data); + } + return (GridData) data; + } + + private static void moveAfter(Control current, Control last) { + if (last == null) + current.moveAbove(null); + else + current.moveBelow(last); + } + + private int calcNumColumns() { + int num = 0; + if (contributions != null) { + List left = contributions.get(LEFT); + if (left != null) { + for (IPanelContribution contribution : left) { + Control c = contribution.getControl(); + if (c != null && !c.isDisposed()) { + num++; + } + } + } + List right = contributions.get(RIGHT); + if (right != null) { + for (IPanelContribution contribution : right) { + Control c = contribution.getControl(); + if (c != null && !c.isDisposed()) { + num++; + } + } + } + } + if (content != null) { + num++; + } + return num; + } + + private GridLayout getContainerLayout() { + Layout layout = container.getLayout(); + if (layout == null || !(layout instanceof GridLayout)) { + GridLayout gridLayout = new GridLayout(); + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + gridLayout.makeColumnsEqualWidth = false; + container.setLayout(gridLayout); + layout = gridLayout; + } + return (GridLayout) layout; + } + + protected void createControls(Composite parent) { + if (container == null || !containerExists()) { + container = new Composite(parent, SWT.NONE); + + if (contributions != null) { + for (List list : contributions.values()) { + for (IPanelContribution contribution : list) { + createContributionControl(contribution); + } + } + } + } + } + + protected Composite getContainer() { + return container; + } + + protected void setContent(Control content) { + this.content = content; + } + + protected boolean containerExists() { + return container != null && !container.isDisposed(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/CommandStackPropertyTester.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/CommandStackPropertyTester.java index b2c36e196..81c4e3eb9 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/CommandStackPropertyTester.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/CommandStackPropertyTester.java @@ -1,47 +1,47 @@ -package org.xmind.gef.ui.internal; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.gef.command.ICommandStack; - -public class CommandStackPropertyTester extends PropertyTester { - - private static final String P_CAN_UNDO = "canUndo"; //$NON-NLS-1$ - - private static final String P_CAN_REDO = "canRedo"; //$NON-NLS-1$ - - private static final String P_IS_DIRTY = "isDirty"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof ICommandStack); - - ICommandStack stack = (ICommandStack) receiver; - if (P_CAN_UNDO.equals(property)) { - return testBooleanValue(stack.canUndo(), expectedValue); - } else if (P_CAN_REDO.equals(property)) { - return testBooleanValue(stack.canRedo(), expectedValue); - } else if (P_IS_DIRTY.equals(property)) { - return testBooleanValue(stack.isDirty(), expectedValue); - } - - Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ - - return false; - } - - private static boolean testBooleanValue(boolean actualValue, - Object expectedValue) { - if (expectedValue == null || "".equals(expectedValue)) //$NON-NLS-1$ - return actualValue; - if (expectedValue instanceof String) - return Boolean.parseBoolean((String) expectedValue) == actualValue; - if (expectedValue instanceof Boolean) - return ((Boolean) expectedValue).booleanValue() == actualValue; - - Assert.isLegal(false, "Unrecognized expected value: " + expectedValue); //$NON-NLS-1$ - - return false; - } - -} +package org.xmind.gef.ui.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.gef.command.ICommandStack; + +public class CommandStackPropertyTester extends PropertyTester { + + private static final String P_CAN_UNDO = "canUndo"; //$NON-NLS-1$ + + private static final String P_CAN_REDO = "canRedo"; //$NON-NLS-1$ + + private static final String P_IS_DIRTY = "isDirty"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof ICommandStack); + + ICommandStack stack = (ICommandStack) receiver; + if (P_CAN_UNDO.equals(property)) { + return testBooleanValue(stack.canUndo(), expectedValue); + } else if (P_CAN_REDO.equals(property)) { + return testBooleanValue(stack.canRedo(), expectedValue); + } else if (P_IS_DIRTY.equals(property)) { + return testBooleanValue(stack.isDirty(), expectedValue); + } + + Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ + + return false; + } + + private static boolean testBooleanValue(boolean actualValue, + Object expectedValue) { + if (expectedValue == null || "".equals(expectedValue)) //$NON-NLS-1$ + return actualValue; + if (expectedValue instanceof String) + return Boolean.parseBoolean((String) expectedValue) == actualValue; + if (expectedValue instanceof Boolean) + return ((Boolean) expectedValue).booleanValue() == actualValue; + + Assert.isLegal(false, "Unrecognized expected value: " + expectedValue); //$NON-NLS-1$ + + return false; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/ModelToPartAdapterFactory.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/ModelToPartAdapterFactory.java index 7c1525188..ce3dacdb7 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/ModelToPartAdapterFactory.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/ModelToPartAdapterFactory.java @@ -1,62 +1,62 @@ -package org.xmind.gef.ui.internal; - -import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.gef.IViewer; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; - -public class ModelToPartAdapterFactory implements IAdapterFactory { - - public Class[] getAdapterList() { - return new Class[] { IPart.class, IGraphicalPart.class }; - } - - public T getAdapter(Object adaptableObject, Class adapterType) { - if (isSubclass(adapterType, IPart.class)) { - IViewer viewer = findViewer(); - if (viewer != null) { - IPart part = viewer.getPartRegistry() - .getPartByModel(adaptableObject); - if (adapterType.isInstance(part)) - return adapterType.cast(part); - } - } - return null; - } - - private static IViewer findViewer() { - if (PlatformUI.isWorkbenchRunning()) { - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - IWorkbenchPart part = window.getPartService().getActivePart(); - if (part != null) { - return GEFPlugin.getAdapter(part, IViewer.class); - } - } - } - return null; - } - - private static boolean isSubclass(Class cls, Class superCls) { - if (cls == null) - return false; - - if (cls.equals(superCls)) - return true; - - if (superCls.isInterface()) { - Class[] interfaces = cls.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - if (isSubclass(interfaces[i], superCls)) - return true; - } - } - - return isSubclass(cls.getSuperclass(), superCls); - } - -} +package org.xmind.gef.ui.internal; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.gef.IViewer; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; + +public class ModelToPartAdapterFactory implements IAdapterFactory { + + public Class[] getAdapterList() { + return new Class[] { IPart.class, IGraphicalPart.class }; + } + + public T getAdapter(Object adaptableObject, Class adapterType) { + if (isSubclass(adapterType, IPart.class)) { + IViewer viewer = findViewer(); + if (viewer != null) { + IPart part = viewer.getPartRegistry() + .getPartByModel(adaptableObject); + if (adapterType.isInstance(part)) + return adapterType.cast(part); + } + } + return null; + } + + private static IViewer findViewer() { + if (PlatformUI.isWorkbenchRunning()) { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPart part = window.getPartService().getActivePart(); + if (part != null) { + return GEFPlugin.getAdapter(part, IViewer.class); + } + } + } + return null; + } + + private static boolean isSubclass(Class cls, Class superCls) { + if (cls == null) + return false; + + if (cls.equals(superCls)) + return true; + + if (superCls.isInterface()) { + Class[] interfaces = cls.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (isSubclass(interfaces[i], superCls)) + return true; + } + } + + return isSubclass(cls.getSuperclass(), superCls); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/SpaceCollaborativeEngine.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/SpaceCollaborativeEngine.java index 9b7fc3506..fcaf0e7af 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/SpaceCollaborativeEngine.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/SpaceCollaborativeEngine.java @@ -1,58 +1,58 @@ -package org.xmind.gef.ui.internal; - -import java.util.List; -import java.util.Set; -import java.util.WeakHashMap; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.ui.gallery.ContentPane; - -public class SpaceCollaborativeEngine { - - private WeakHashMap managedContentPanes = new WeakHashMap(); - - public void register(Object key, ContentPane contentPane) { - managedContentPanes.put(key, contentPane); - } - - public void refreshMinorSpace() { - int maxCount = 0; - ContentPane contentPane = null; - Set keys = managedContentPanes.keySet(); - for (Object key : keys) { - ContentPane cp = managedContentPanes.get(key); - int size = cp.getChildren().size(); - if (size >= maxCount) { - contentPane = cp; - maxCount = size; - } - } - List elements = contentPane.getChildren(); - if (contentPane == null || elements.isEmpty()) - return; - - Rectangle clientArea = contentPane.getClientArea(); - int totalSize = clientArea.width; - int elementSize = ((IFigure) elements.get(0)).getPreferredSize(-1, - -1).width; - - int calculatedCount = totalSize / elementSize; - int calculatedTotalSpace = totalSize - calculatedCount * elementSize; - - int calculatedEachSpace = 0; - if (calculatedCount > 1) { - calculatedEachSpace = calculatedTotalSpace / (calculatedCount - 1); - } - - Set managedKeys = managedContentPanes.keySet(); - for (Object key : managedKeys) { - ContentPane cp = managedContentPanes.get(key); - int oldSpace = cp.getMinorSpacing(); - if (oldSpace != calculatedEachSpace) { - cp.setMinorSpacing(calculatedEachSpace); - } - } - } - -} +package org.xmind.gef.ui.internal; + +import java.util.List; +import java.util.Set; +import java.util.WeakHashMap; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.ui.gallery.ContentPane; + +public class SpaceCollaborativeEngine { + + private WeakHashMap managedContentPanes = new WeakHashMap(); + + public void register(Object key, ContentPane contentPane) { + managedContentPanes.put(key, contentPane); + } + + public void refreshMinorSpace() { + int maxCount = 0; + ContentPane contentPane = null; + Set keys = managedContentPanes.keySet(); + for (Object key : keys) { + ContentPane cp = managedContentPanes.get(key); + int size = cp.getChildren().size(); + if (size >= maxCount) { + contentPane = cp; + maxCount = size; + } + } + List elements = contentPane.getChildren(); + if (contentPane == null || elements.isEmpty()) + return; + + Rectangle clientArea = contentPane.getClientArea(); + int totalSize = clientArea.width; + int elementSize = ((IFigure) elements.get(0)).getPreferredSize(-1, + -1).width; + + int calculatedCount = totalSize / elementSize; + int calculatedTotalSpace = totalSize - calculatedCount * elementSize; + + int calculatedEachSpace = 0; + if (calculatedCount > 1) { + calculatedEachSpace = calculatedTotalSpace / (calculatedCount - 1); + } + + Set managedKeys = managedContentPanes.keySet(); + for (Object key : managedKeys) { + ContentPane cp = managedContentPanes.get(key); + int oldSpace = cp.getMinorSpacing(); + if (oldSpace != calculatedEachSpace) { + cp.setMinorSpacing(calculatedEachSpace); + } + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/outline/GraphicalOutlinePage.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/outline/GraphicalOutlinePage.java index 3f5a8e77a..9a46820a1 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/outline/GraphicalOutlinePage.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/outline/GraphicalOutlinePage.java @@ -1,292 +1,292 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.outline; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.part.IPageSite; -import org.eclipse.ui.part.Page; -import org.eclipse.ui.part.PageBook; -import org.xmind.gef.tree.ITreeViewer; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; - -/** - * @author Brian Sun - */ -public abstract class GraphicalOutlinePage extends Page - implements ISelectionProvider, ISelectionChangedListener, - IPageChangedListener, IPropertyListener { - - private List selectionChangedListeners = null; - - private IGraphicalEditor editor; - - private PageBook pageBook; - - private ITreeViewer editorTreeViewer; - - private Map pageViewers = new HashMap(); - - private boolean showCurrentPageViewer = false; - - public GraphicalOutlinePage(IGraphicalEditor editor) { - this.editor = editor; - hookEditor(editor); - } - - protected void hookEditor(IGraphicalEditor editor) { - editor.addPageChangedListener(this); - editor.addPropertyListener(this); - } - - protected void unhookEditor(IGraphicalEditor editor) { - editor.removePropertyListener(this); - editor.removePageChangedListener(this); - } - - public void pageChanged(PageChangedEvent event) { - if (pageBook == null || pageBook.isDisposed() || !showCurrentPageViewer) - return; - updatePageBook(); - } - - protected IGraphicalEditor getParentEditor() { - return editor; - } - - public void init(IPageSite pageSite) { - super.init(pageSite); - pageSite.setSelectionProvider(this); - } - - public void createControl(Composite parent) { - pageBook = new PageBook(parent, SWT.NONE); - updatePageBook(); - } - - public boolean isShowCurrentPageViewer() { - return showCurrentPageViewer; - } - - public void setShowCurrentPageViewer(boolean showCurrentPageViewer) { - if (showCurrentPageViewer == this.showCurrentPageViewer) - return; - - this.showCurrentPageViewer = showCurrentPageViewer; - updatePageBook(); - } - - protected void updatePageBook() { - if (isShowCurrentPageViewer()) { - showCurrentPageViewer(false); - } else { - showEditorTreeViewer(false); - } - } - - protected void refresh() { - if (isShowCurrentPageViewer()) { - showCurrentPageViewer(true); - } else { - showEditorTreeViewer(true); - } - } - - protected void showEditorTreeViewer(boolean refresh) { - if (editorTreeViewer == null || editorTreeViewer.getControl() == null - || editorTreeViewer.getControl().isDisposed()) { - editorTreeViewer = createEditorTreeViewer(); - if (editorTreeViewer != null) { - configureEditorTreeViewer(editorTreeViewer); - createEditorTreeViewerControl(editorTreeViewer, pageBook); - if (!refresh) { - editorTreeViewer - .setInput(createEditorTreeViewerInput(editor)); - } - } - } - if (editorTreeViewer != null) { - if (refresh) { - Object newInput = createEditorTreeViewerInput(editor); - if (newInput != editorTreeViewer.getInput()) { - editorTreeViewer.setInput(newInput); - } - } - pageBook.showPage(editorTreeViewer.getControl()); - } - } - - protected void showCurrentPageViewer(boolean refresh) { - IGraphicalEditorPage page = editor.getActivePageInstance(); - if (page == null) - return; - Object pageInput = page.getInput(); - ITreeViewer pageTreeViewer = pageViewers.get(pageInput); - if (pageTreeViewer == null || pageTreeViewer.getControl() == null - || pageTreeViewer.getControl().isDisposed()) { - pageTreeViewer = createPageTreeViewer(); - if (pageTreeViewer != null) { - configurePageTreeViewer(pageTreeViewer); - createPageTreeViewerControl(pageTreeViewer, pageBook); - if (!refresh) { - pageTreeViewer - .setInput(createPageTreeViewerInput(pageInput)); - } - } - } - if (pageTreeViewer != null) { - if (refresh) { - Object newInput = createPageTreeViewerInput(pageInput); - if (newInput != pageTreeViewer.getInput()) { - pageTreeViewer.setInput(newInput); - } - } - pageBook.showPage(pageTreeViewer.getControl()); - } - } - - protected abstract ITreeViewer createEditorTreeViewer(); - - protected abstract ITreeViewer createPageTreeViewer(); - - protected abstract Control createEditorTreeViewerControl(ITreeViewer viewer, - Composite parent); - - protected abstract Control createPageTreeViewerControl(ITreeViewer viewer, - Composite parent); - - protected abstract Object createEditorTreeViewerInput( - IGraphicalEditor parentEditor); - - protected abstract Object createPageTreeViewerInput(Object pageInput); - - protected void configureEditorTreeViewer(ITreeViewer viewer) { - configureTreeViewer(viewer); - } - - protected void configurePageTreeViewer(ITreeViewer viewer) { - configureTreeViewer(viewer); - } - - protected void configureTreeViewer(ITreeViewer viewer) { - viewer.addSelectionChangedListener(this); - } - - public Control getControl() { - return pageBook; - } - - public void setFocus() { - pageBook.setFocus(); - } - - public void addSelectionChangedListener( - ISelectionChangedListener listener) { - if (selectionChangedListeners == null) - selectionChangedListeners = new ArrayList(); - selectionChangedListeners.add(listener); - } - - public ISelection getSelection() { - if (editorTreeViewer == null) - return StructuredSelection.EMPTY; - return editorTreeViewer.getSelection(); - } - - public void removeSelectionChangedListener( - ISelectionChangedListener listener) { - if (selectionChangedListeners == null) - return; - selectionChangedListeners.remove(listener); - } - - public void setSelection(ISelection selection) { - if (editorTreeViewer != null) { - editorTreeViewer.setSelection(selection); - } - } - - public void selectionChanged(SelectionChangedEvent event) { - fireSelectionChanged(event.getSelection()); - } - - /** - * Fires a selection changed event. - * - * @param selection - * the new selection - */ - protected void fireSelectionChanged(ISelection selection) { - if (selectionChangedListeners == null) - return; - - // create an event - final SelectionChangedEvent event = new SelectionChangedEvent(this, - selection); - - // fire the event - Object[] listeners = selectionChangedListeners.toArray(); - for (int i = 0; i < listeners.length; ++i) { - final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; - SafeRunner.run(new SafeRunnable() { - public void run() { - l.selectionChanged(event); - } - }); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, - * int) - */ - public void propertyChanged(Object source, int propId) { - if (propId == IEditorPart.PROP_INPUT) { - editorInputChanged(); - } - } - - /** - * - */ - protected void editorInputChanged() { - refresh(); - } - - public void dispose() { - unhookEditor(editor); - super.dispose(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.outline; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.part.Page; +import org.eclipse.ui.part.PageBook; +import org.xmind.gef.tree.ITreeViewer; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; + +/** + * @author Brian Sun + */ +public abstract class GraphicalOutlinePage extends Page + implements ISelectionProvider, ISelectionChangedListener, + IPageChangedListener, IPropertyListener { + + private List selectionChangedListeners = null; + + private IGraphicalEditor editor; + + private PageBook pageBook; + + private ITreeViewer editorTreeViewer; + + private Map pageViewers = new HashMap(); + + private boolean showCurrentPageViewer = false; + + public GraphicalOutlinePage(IGraphicalEditor editor) { + this.editor = editor; + hookEditor(editor); + } + + protected void hookEditor(IGraphicalEditor editor) { + editor.addPageChangedListener(this); + editor.addPropertyListener(this); + } + + protected void unhookEditor(IGraphicalEditor editor) { + editor.removePropertyListener(this); + editor.removePageChangedListener(this); + } + + public void pageChanged(PageChangedEvent event) { + if (pageBook == null || pageBook.isDisposed() || !showCurrentPageViewer) + return; + updatePageBook(); + } + + protected IGraphicalEditor getParentEditor() { + return editor; + } + + public void init(IPageSite pageSite) { + super.init(pageSite); + pageSite.setSelectionProvider(this); + } + + public void createControl(Composite parent) { + pageBook = new PageBook(parent, SWT.NONE); + updatePageBook(); + } + + public boolean isShowCurrentPageViewer() { + return showCurrentPageViewer; + } + + public void setShowCurrentPageViewer(boolean showCurrentPageViewer) { + if (showCurrentPageViewer == this.showCurrentPageViewer) + return; + + this.showCurrentPageViewer = showCurrentPageViewer; + updatePageBook(); + } + + protected void updatePageBook() { + if (isShowCurrentPageViewer()) { + showCurrentPageViewer(false); + } else { + showEditorTreeViewer(false); + } + } + + protected void refresh() { + if (isShowCurrentPageViewer()) { + showCurrentPageViewer(true); + } else { + showEditorTreeViewer(true); + } + } + + protected void showEditorTreeViewer(boolean refresh) { + if (editorTreeViewer == null || editorTreeViewer.getControl() == null + || editorTreeViewer.getControl().isDisposed()) { + editorTreeViewer = createEditorTreeViewer(); + if (editorTreeViewer != null) { + configureEditorTreeViewer(editorTreeViewer); + createEditorTreeViewerControl(editorTreeViewer, pageBook); + if (!refresh) { + editorTreeViewer + .setInput(createEditorTreeViewerInput(editor)); + } + } + } + if (editorTreeViewer != null) { + if (refresh) { + Object newInput = createEditorTreeViewerInput(editor); + if (newInput != editorTreeViewer.getInput()) { + editorTreeViewer.setInput(newInput); + } + } + pageBook.showPage(editorTreeViewer.getControl()); + } + } + + protected void showCurrentPageViewer(boolean refresh) { + IGraphicalEditorPage page = editor.getActivePageInstance(); + if (page == null) + return; + Object pageInput = page.getInput(); + ITreeViewer pageTreeViewer = pageViewers.get(pageInput); + if (pageTreeViewer == null || pageTreeViewer.getControl() == null + || pageTreeViewer.getControl().isDisposed()) { + pageTreeViewer = createPageTreeViewer(); + if (pageTreeViewer != null) { + configurePageTreeViewer(pageTreeViewer); + createPageTreeViewerControl(pageTreeViewer, pageBook); + if (!refresh) { + pageTreeViewer + .setInput(createPageTreeViewerInput(pageInput)); + } + } + } + if (pageTreeViewer != null) { + if (refresh) { + Object newInput = createPageTreeViewerInput(pageInput); + if (newInput != pageTreeViewer.getInput()) { + pageTreeViewer.setInput(newInput); + } + } + pageBook.showPage(pageTreeViewer.getControl()); + } + } + + protected abstract ITreeViewer createEditorTreeViewer(); + + protected abstract ITreeViewer createPageTreeViewer(); + + protected abstract Control createEditorTreeViewerControl(ITreeViewer viewer, + Composite parent); + + protected abstract Control createPageTreeViewerControl(ITreeViewer viewer, + Composite parent); + + protected abstract Object createEditorTreeViewerInput( + IGraphicalEditor parentEditor); + + protected abstract Object createPageTreeViewerInput(Object pageInput); + + protected void configureEditorTreeViewer(ITreeViewer viewer) { + configureTreeViewer(viewer); + } + + protected void configurePageTreeViewer(ITreeViewer viewer) { + configureTreeViewer(viewer); + } + + protected void configureTreeViewer(ITreeViewer viewer) { + viewer.addSelectionChangedListener(this); + } + + public Control getControl() { + return pageBook; + } + + public void setFocus() { + pageBook.setFocus(); + } + + public void addSelectionChangedListener( + ISelectionChangedListener listener) { + if (selectionChangedListeners == null) + selectionChangedListeners = new ArrayList(); + selectionChangedListeners.add(listener); + } + + public ISelection getSelection() { + if (editorTreeViewer == null) + return StructuredSelection.EMPTY; + return editorTreeViewer.getSelection(); + } + + public void removeSelectionChangedListener( + ISelectionChangedListener listener) { + if (selectionChangedListeners == null) + return; + selectionChangedListeners.remove(listener); + } + + public void setSelection(ISelection selection) { + if (editorTreeViewer != null) { + editorTreeViewer.setSelection(selection); + } + } + + public void selectionChanged(SelectionChangedEvent event) { + fireSelectionChanged(event.getSelection()); + } + + /** + * Fires a selection changed event. + * + * @param selection + * the new selection + */ + protected void fireSelectionChanged(ISelection selection) { + if (selectionChangedListeners == null) + return; + + // create an event + final SelectionChangedEvent event = new SelectionChangedEvent(this, + selection); + + // fire the event + Object[] listeners = selectionChangedListeners.toArray(); + for (int i = 0; i < listeners.length; ++i) { + final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; + SafeRunner.run(new SafeRunnable() { + public void run() { + l.selectionChanged(event); + } + }); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, + * int) + */ + public void propertyChanged(Object source, int propId) { + if (propId == IEditorPart.PROP_INPUT) { + editorInputChanged(); + } + } + + /** + * + */ + protected void editorInputChanged() { + refresh(); + } + + public void dispose() { + unhookEditor(editor); + super.dispose(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/GraphicalPropertySheetPage.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/GraphicalPropertySheetPage.java index 68efdec7f..04e3c3694 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/GraphicalPropertySheetPage.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/GraphicalPropertySheetPage.java @@ -1,453 +1,453 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.properties; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.part.IPageSite; -import org.eclipse.ui.part.Page; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.forms.WidgetFactory; - -public abstract class GraphicalPropertySheetPage extends Page - implements ISelectionChangedListener, IPropertyPartContainer { - - protected static class SectionRec { - - String id; - - IPropertySectionPart section; - - Section control; - - boolean visible; - - public SectionRec(String id, IPropertySectionPart section) { - this.id = id; - this.section = section; - } - - } - - private static final int DEFAULT_SECTION_WIDTH = 200; - - private final IGraphicalEditor editor; - - private List sections = new ArrayList(); - - private Composite composite; - - private WidgetFactory widgetFactory; - - private ScrolledForm form; - - private Label titleBar; - - private Control titleSeparator; - - private String title; - - public GraphicalPropertySheetPage(IGraphicalEditor editor) { - this.editor = editor; - } - - public void init(IPageSite pageSite) { - super.init(pageSite); - for (SectionRec rec : sections) { - rec.section.init(this, getContributedEditor()); - } - if (editor != null) { - editor.getSite().getSelectionProvider() - .addSelectionChangedListener(this); - - final ISelection selection = editor.getSite().getSelectionProvider() - .getSelection(); - if (selection != null && !selection.isEmpty()) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - selectionChanged(new SelectionChangedEvent( - editor.getSite().getSelectionProvider(), - selection)); - } - }); - } - } - } - - public IGraphicalEditor getContributedEditor() { - return editor; - } - - protected void addSection(String id, IPropertySectionPart section) { - Assert.isNotNull(id); - Assert.isNotNull(section); - removeSection(id); - SectionRec rec = new SectionRec(id, section); - sections.add(rec); - section.init(this, editor); - if (form != null && !form.isDisposed()) { - createSectionControl(form.getBody(), rec); - } - } - - protected void removeSection(String id) { - SectionRec rec = getRec(id); - if (rec == null) - return; - - if (sections.remove(rec)) { - rec.section.dispose(); - if (rec.control != null && !rec.control.isDisposed()) { - rec.control.dispose(); - } - } - } - - protected boolean hasSection(String id) { - return getRec(id) != null; - } - - protected IPropertySectionPart getSection(String id) { - SectionRec rec = getRec(id); - return rec == null ? null : rec.section; - } - - protected List getSectionIds() { - ArrayList list = new ArrayList(sections.size()); - for (SectionRec rec : sections) { - list.add(rec.id); - } - return list; - } - - protected List getVisibleSectionIds() { - ArrayList list = new ArrayList(sections.size()); - for (SectionRec rec : sections) { - if (rec.visible) - list.add(rec.id); - } - return list; - } - - protected boolean isSectionVisible(String id) { - SectionRec rec = getRec(id); - return rec != null && rec.visible; - } - - protected void setSectionVisible(String id, boolean visible) { - SectionRec rec = getRec(id); - if (rec == null || rec.visible == visible) - return; - - rec.visible = visible; - if (rec.control != null && !rec.control.isDisposed()) { - GridData gd = (GridData) rec.control.getLayoutData(); - gd.exclude = !visible; - rec.control.setVisible(visible); - } - } - - protected void reflow() { - if (form != null && !form.isDisposed()) { - form.reflow(true); - form.getParent().layout(); - } - } - - protected void moveSectionFirst(String id) { - SectionRec rec = getRec(id); - if (rec == null) - return; - - moveSectionFirst(rec); - } - - private void moveSectionFirst(SectionRec rec) { - if (rec.control != null && !rec.control.isDisposed()) { - rec.control.moveAbove(null); - rec.control.getParent().layout(); - } - } - - protected void moveSectionAfter(String id, String lastId) { - SectionRec rec = getRec(id); - if (rec == null) - return; - SectionRec lastRec = getRec(lastId); - if (lastRec == null) { - moveSectionFirst(rec); - } else { - if (rec.control != null && !rec.control.isDisposed() - && lastRec.control != null - && !lastRec.control.isDisposed()) { - rec.control.moveBelow(lastRec.control); - rec.control.getParent().layout(); - } - } - } - - private SectionRec getRec(String id) { - if (id == null) - return null; - - for (SectionRec rec : sections) { - if (id.equals(rec.id)) - return rec; - } - return null; - } - - public void createControl(Composite parent) { - composite = new Composite(parent, SWT.NO_FOCUS); - GridLayout layout = new GridLayout(1, true); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - titleBar = new Label(composite, SWT.NONE); - titleBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - titleBar.setBackground( - composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - titleSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); - titleSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - this.widgetFactory = new WidgetFactory(composite.getDisplay()); - - form = widgetFactory.createScrolledForm(composite); - form.setLayoutData(new GridData(GridData.FILL_BOTH)); - form.setMinWidth(DEFAULT_SECTION_WIDTH); // TODO this not working??? - form.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (widgetFactory != null) { - widgetFactory.dispose(); - widgetFactory = null; - } - } - }); - - createSectionControls(form, form.getBody()); - - Composite internalComposite = new Composite(form.getBody(), SWT.NONE); - internalComposite.setBackground(form.getBody().getBackground()); - internalComposite.setLayout(new GridLayout(1, false)); - internalComposite - .setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); - createExtendSectionControls(widgetFactory, internalComposite); - form.reflow(true); - } - - protected void createExtendSectionControls(WidgetFactory widgetFactory, - Composite parent) { - } - - protected void createSectionControls(final ScrolledForm form, - final Composite formBody) { - GridLayout layout = new GridLayout(1, true); - formBody.setLayout(layout); - for (SectionRec rec : sections) { - createSectionControl(formBody, rec); - } - form.addControlListener(new ControlListener() { - public void controlResized(ControlEvent e) { - relayout(form, formBody); - } - - public void controlMoved(ControlEvent e) { - } - }); - } - - private void relayout(ScrolledForm form, Composite formBody) { - Rectangle area = form.getClientArea(); - GridLayout layout = (GridLayout) formBody.getLayout(); - int newNumColumns = Math.max(1, area.width / DEFAULT_SECTION_WIDTH); - boolean change = newNumColumns != layout.numColumns - && newNumColumns >= 0 - && newNumColumns <= formBody.getChildren().length; - if (change) { - layout.numColumns = newNumColumns; - formBody.layout(); - } - } - - private void createSectionControl(Composite parent, SectionRec rec) { - rec.control = widgetFactory.createSection(parent, - Section.TITLE_BAR | SWT.BORDER); - Composite client = widgetFactory.createComposite(rec.control, - SWT.NO_FOCUS | SWT.WRAP); - rec.control.setClient(client); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.verticalAlignment = GridData.BEGINNING; - data.widthHint = DEFAULT_SECTION_WIDTH; - rec.control.setLayoutData(data); - rec.section.createControl(client); - rec.visible = true; - updateSectionTitle(rec); - } - - public void updateSectionTitle(IPropertySectionPart section) { - SectionRec rec = findRecord(section); - if (rec != null) { - updateSectionTitle(rec); - } - } - - private SectionRec findRecord(IPropertySectionPart section) { - for (SectionRec rec : sections) { - if (rec.section == section) - return rec; - } - return null; - } - - private void updateSectionTitle(SectionRec rec) { - if (rec.control == null || rec.control.isDisposed()) - return; - - String title = rec.section.getTitle(); - if (title == null) { - title = ""; //$NON-NLS-1$ - } - rec.control.setText(title); - } - - public Control getControl() { - return composite; - } - - public void setFocus() { - if (sections.isEmpty()) { - if (form != null && !form.isDisposed()) - form.setFocus(); - else if (composite != null && !composite.isDisposed()) - composite.setFocus(); - } else { - sections.get(0).section.setFocus(); - } - } - - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - - selectionChanged(selection); - - if (composite != null && !composite.isDisposed()) - composite.setRedraw(false); - setSelectionToSections(selection); - if (form != null && !form.isDisposed()) { - refresh(); - } - if (composite != null && !composite.isDisposed()) - composite.setRedraw(true); - } - - protected abstract void selectionChanged(ISelection selection); - - private void setSelectionToSections(ISelection selection) { - for (SectionRec rec : sections) { - if (rec.visible) { - rec.section.setSelection(selection); - updateSectionTitle(rec); - } - } - } - - private void updateTitleBar() { - if (titleBar == null || titleBar.isDisposed()) - return; - String title = getTitle(); - titleBar.setText(title == null ? "" : title); //$NON-NLS-1$ - setTitleVisible(title != null); - } - - private void setTitleVisible(boolean visible) { - if (titleBar == null || titleBar.isDisposed()) - return; - if (titleBar.getVisible() == visible) - return; - titleBar.setVisible(visible); - ((GridData) titleBar.getLayoutData()).exclude = !visible; - titleSeparator.setVisible(visible); - ((GridData) titleSeparator.getLayoutData()).exclude = !visible; - titleBar.getParent().layout(); - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - if (title == this.title || (title != null && title.equals(this.title))) - return; - this.title = title; - updateTitleBar(); - } - - public IPageSite getContainerSite() { - return getSite(); - } - - public void refresh() { - for (SectionRec rec : sections) { - if (rec.visible) { - rec.section.refresh(); - } - } - if (form != null && !form.isDisposed()) { - form.reflow(true); - } - } - - public void dispose() { - if (editor != null) { - editor.getSite().getSelectionProvider() - .removeSelectionChangedListener(this); - } - - for (SectionRec rec : sections) { - rec.section.dispose(); - rec.visible = false; - rec.control = null; - } - if (composite != null) { - composite.dispose(); - composite = null; - } - form = null; - title = null; - titleBar = null; - titleSeparator = null; - super.dispose(); - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.properties; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.part.Page; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.forms.WidgetFactory; + +public abstract class GraphicalPropertySheetPage extends Page + implements ISelectionChangedListener, IPropertyPartContainer { + + protected static class SectionRec { + + String id; + + IPropertySectionPart section; + + Section control; + + boolean visible; + + public SectionRec(String id, IPropertySectionPart section) { + this.id = id; + this.section = section; + } + + } + + private static final int DEFAULT_SECTION_WIDTH = 200; + + private final IGraphicalEditor editor; + + private List sections = new ArrayList(); + + private Composite composite; + + private WidgetFactory widgetFactory; + + private ScrolledForm form; + + private Label titleBar; + + private Control titleSeparator; + + private String title; + + public GraphicalPropertySheetPage(IGraphicalEditor editor) { + this.editor = editor; + } + + public void init(IPageSite pageSite) { + super.init(pageSite); + for (SectionRec rec : sections) { + rec.section.init(this, getContributedEditor()); + } + if (editor != null) { + editor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + + final ISelection selection = editor.getSite().getSelectionProvider() + .getSelection(); + if (selection != null && !selection.isEmpty()) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + selectionChanged(new SelectionChangedEvent( + editor.getSite().getSelectionProvider(), + selection)); + } + }); + } + } + } + + public IGraphicalEditor getContributedEditor() { + return editor; + } + + protected void addSection(String id, IPropertySectionPart section) { + Assert.isNotNull(id); + Assert.isNotNull(section); + removeSection(id); + SectionRec rec = new SectionRec(id, section); + sections.add(rec); + section.init(this, editor); + if (form != null && !form.isDisposed()) { + createSectionControl(form.getBody(), rec); + } + } + + protected void removeSection(String id) { + SectionRec rec = getRec(id); + if (rec == null) + return; + + if (sections.remove(rec)) { + rec.section.dispose(); + if (rec.control != null && !rec.control.isDisposed()) { + rec.control.dispose(); + } + } + } + + protected boolean hasSection(String id) { + return getRec(id) != null; + } + + protected IPropertySectionPart getSection(String id) { + SectionRec rec = getRec(id); + return rec == null ? null : rec.section; + } + + protected List getSectionIds() { + ArrayList list = new ArrayList(sections.size()); + for (SectionRec rec : sections) { + list.add(rec.id); + } + return list; + } + + protected List getVisibleSectionIds() { + ArrayList list = new ArrayList(sections.size()); + for (SectionRec rec : sections) { + if (rec.visible) + list.add(rec.id); + } + return list; + } + + protected boolean isSectionVisible(String id) { + SectionRec rec = getRec(id); + return rec != null && rec.visible; + } + + protected void setSectionVisible(String id, boolean visible) { + SectionRec rec = getRec(id); + if (rec == null || rec.visible == visible) + return; + + rec.visible = visible; + if (rec.control != null && !rec.control.isDisposed()) { + GridData gd = (GridData) rec.control.getLayoutData(); + gd.exclude = !visible; + rec.control.setVisible(visible); + } + } + + protected void reflow() { + if (form != null && !form.isDisposed()) { + form.reflow(true); + form.getParent().layout(); + } + } + + protected void moveSectionFirst(String id) { + SectionRec rec = getRec(id); + if (rec == null) + return; + + moveSectionFirst(rec); + } + + private void moveSectionFirst(SectionRec rec) { + if (rec.control != null && !rec.control.isDisposed()) { + rec.control.moveAbove(null); + rec.control.getParent().layout(); + } + } + + protected void moveSectionAfter(String id, String lastId) { + SectionRec rec = getRec(id); + if (rec == null) + return; + SectionRec lastRec = getRec(lastId); + if (lastRec == null) { + moveSectionFirst(rec); + } else { + if (rec.control != null && !rec.control.isDisposed() + && lastRec.control != null + && !lastRec.control.isDisposed()) { + rec.control.moveBelow(lastRec.control); + rec.control.getParent().layout(); + } + } + } + + private SectionRec getRec(String id) { + if (id == null) + return null; + + for (SectionRec rec : sections) { + if (id.equals(rec.id)) + return rec; + } + return null; + } + + public void createControl(Composite parent) { + composite = new Composite(parent, SWT.NO_FOCUS); + GridLayout layout = new GridLayout(1, true); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + titleBar = new Label(composite, SWT.NONE); + titleBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + titleBar.setBackground( + composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + titleSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + titleSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + this.widgetFactory = new WidgetFactory(composite.getDisplay()); + + form = widgetFactory.createScrolledForm(composite); + form.setLayoutData(new GridData(GridData.FILL_BOTH)); + form.setMinWidth(DEFAULT_SECTION_WIDTH); // TODO this not working??? + form.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (widgetFactory != null) { + widgetFactory.dispose(); + widgetFactory = null; + } + } + }); + + createSectionControls(form, form.getBody()); + + Composite internalComposite = new Composite(form.getBody(), SWT.NONE); + internalComposite.setBackground(form.getBody().getBackground()); + internalComposite.setLayout(new GridLayout(1, false)); + internalComposite + .setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); + createExtendSectionControls(widgetFactory, internalComposite); + form.reflow(true); + } + + protected void createExtendSectionControls(WidgetFactory widgetFactory, + Composite parent) { + } + + protected void createSectionControls(final ScrolledForm form, + final Composite formBody) { + GridLayout layout = new GridLayout(1, true); + formBody.setLayout(layout); + for (SectionRec rec : sections) { + createSectionControl(formBody, rec); + } + form.addControlListener(new ControlListener() { + public void controlResized(ControlEvent e) { + relayout(form, formBody); + } + + public void controlMoved(ControlEvent e) { + } + }); + } + + private void relayout(ScrolledForm form, Composite formBody) { + Rectangle area = form.getClientArea(); + GridLayout layout = (GridLayout) formBody.getLayout(); + int newNumColumns = Math.max(1, area.width / DEFAULT_SECTION_WIDTH); + boolean change = newNumColumns != layout.numColumns + && newNumColumns >= 0 + && newNumColumns <= formBody.getChildren().length; + if (change) { + layout.numColumns = newNumColumns; + formBody.layout(); + } + } + + private void createSectionControl(Composite parent, SectionRec rec) { + rec.control = widgetFactory.createSection(parent, + Section.TITLE_BAR | SWT.BORDER); + Composite client = widgetFactory.createComposite(rec.control, + SWT.NO_FOCUS | SWT.WRAP); + rec.control.setClient(client); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.verticalAlignment = GridData.BEGINNING; + data.widthHint = DEFAULT_SECTION_WIDTH; + rec.control.setLayoutData(data); + rec.section.createControl(client); + rec.visible = true; + updateSectionTitle(rec); + } + + public void updateSectionTitle(IPropertySectionPart section) { + SectionRec rec = findRecord(section); + if (rec != null) { + updateSectionTitle(rec); + } + } + + private SectionRec findRecord(IPropertySectionPart section) { + for (SectionRec rec : sections) { + if (rec.section == section) + return rec; + } + return null; + } + + private void updateSectionTitle(SectionRec rec) { + if (rec.control == null || rec.control.isDisposed()) + return; + + String title = rec.section.getTitle(); + if (title == null) { + title = ""; //$NON-NLS-1$ + } + rec.control.setText(title); + } + + public Control getControl() { + return composite; + } + + public void setFocus() { + if (sections.isEmpty()) { + if (form != null && !form.isDisposed()) + form.setFocus(); + else if (composite != null && !composite.isDisposed()) + composite.setFocus(); + } else { + sections.get(0).section.setFocus(); + } + } + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + + selectionChanged(selection); + + if (composite != null && !composite.isDisposed()) + composite.setRedraw(false); + setSelectionToSections(selection); + if (form != null && !form.isDisposed()) { + refresh(); + } + if (composite != null && !composite.isDisposed()) + composite.setRedraw(true); + } + + protected abstract void selectionChanged(ISelection selection); + + private void setSelectionToSections(ISelection selection) { + for (SectionRec rec : sections) { + if (rec.visible) { + rec.section.setSelection(selection); + updateSectionTitle(rec); + } + } + } + + private void updateTitleBar() { + if (titleBar == null || titleBar.isDisposed()) + return; + String title = getTitle(); + titleBar.setText(title == null ? "" : title); //$NON-NLS-1$ + setTitleVisible(title != null); + } + + private void setTitleVisible(boolean visible) { + if (titleBar == null || titleBar.isDisposed()) + return; + if (titleBar.getVisible() == visible) + return; + titleBar.setVisible(visible); + ((GridData) titleBar.getLayoutData()).exclude = !visible; + titleSeparator.setVisible(visible); + ((GridData) titleSeparator.getLayoutData()).exclude = !visible; + titleBar.getParent().layout(); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + if (title == this.title || (title != null && title.equals(this.title))) + return; + this.title = title; + updateTitleBar(); + } + + public IPageSite getContainerSite() { + return getSite(); + } + + public void refresh() { + for (SectionRec rec : sections) { + if (rec.visible) { + rec.section.refresh(); + } + } + if (form != null && !form.isDisposed()) { + form.reflow(true); + } + } + + public void dispose() { + if (editor != null) { + editor.getSite().getSelectionProvider() + .removeSelectionChangedListener(this); + } + + for (SectionRec rec : sections) { + rec.section.dispose(); + rec.visible = false; + rec.control = null; + } + if (composite != null) { + composite.dispose(); + composite = null; + } + form = null; + title = null; + titleBar = null; + titleSeparator = null; + super.dispose(); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/Messages.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/Messages.java index b4bea402c..d44ae8edf 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/Messages.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/Messages.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.ui.properties; - -import org.eclipse.osgi.util.NLS; - -/** - * @author frankshaka - * - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.xmind.gef.ui.properties.messages"; //$NON-NLS-1$ - public static String propertiesNotAvailable; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.ui.properties; + +import org.eclipse.osgi.util.NLS; + +/** + * @author frankshaka + * + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.xmind.gef.ui.properties.messages"; //$NON-NLS-1$ + public static String propertiesNotAvailable; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/messages.properties b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/messages.properties index ef951fec8..6f955a830 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/messages.properties +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/properties/messages.properties @@ -1 +1 @@ -propertiesNotAvailable=No property available. +propertiesNotAvailable=No property available. diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/animation/AnimationService.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/animation/AnimationService.java index dbd78426c..08b1ce920 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/animation/AnimationService.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/animation/AnimationService.java @@ -1,396 +1,396 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.animation; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutListener; -import org.eclipse.draw2d.UpdateManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.widgets.Control; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.service.GraphicalViewerService; -import org.xmind.gef.service.IAnimationService; -import org.xmind.gef.service.IPlaybackProvider; -import org.xmind.ui.util.UITimer; - -public class AnimationService extends GraphicalViewerService implements - IAnimationService { - - private static boolean DEBUG = false; - - private class LayoutCapturer implements LayoutListener { - - public void invalidate(IFigure container) { - if (isRecordingInitial()) { - hookPlayback(container); - } - } - - public boolean layout(IFigure container) { - if (isAnimating()) { - return playback(container); - } - return false; - } - - public void postLayout(IFigure container) { - if (isRecordingFinal()) { - hookCapture(container); - } - } - - public void remove(IFigure child) { - } - - public void setConstraint(IFigure child, Object constraint) { - } - - } - - private class PlaybackTask extends SafeRunnable { - - public void run() throws Exception { - if (getViewer().getControl().isDisposed()) - return; - - if (initialStates != null) { - for (IFigure figure : initialStates.keySet()) { - figure.revalidate(); - } - } - - if (timer == null || timer.isCanceled()) - return; - - progress = timer.getCurrentLoop() * 1.0f / (timer.getLoops() + 1); - } - - } - - private class PlaybackTimer extends UITimer { - - private Runnable afterEffect; - - public PlaybackTimer(Runnable after) { - super(0, DEBUG ? 300 : 10, DEBUG ? 10 : 3, task); - this.afterEffect = after; - } - - @Override - protected void onFinished() { - super.onFinished(); - timer = null; - stop(); - runAfterEffect(); - } - - private void runAfterEffect() { - if (afterEffect != null && !getViewer().getControl().isDisposed()) { - SafeRunner.run(new SafeRunnable( - "Error running effect after animation.") { //$NON-NLS-1$ - public void run() throws Exception { - afterEffect.run(); - } - }); - } - } - - @Override - protected void onCanceled() { - super.onCanceled(); - runAfterEffect(); - timer = null; - stop(); - } - - } - - private static final int IDLE = 0; - private static final int RECORDING_INITIAL = 1; - private static final int RECORDING_FINAL = 2; - private static final int PLAYBACK = 3; - - private static final IPlaybackProvider DEFAULT_PLAYBACK_PROVIDER = new LayoutPlaybackProvider(); - - private UpdateManager updateManager; - - private int state = IDLE; - - private final LayoutCapturer layoutCapturer = new LayoutCapturer(); - - private Map registry = null; - - private IPlaybackProvider playbackProvider = DEFAULT_PLAYBACK_PROVIDER; - - private Set keyFigures = null; - - private Map initialStates = null; - - private Map finalStates = null; - - private Set toCapture = null; - - private float progress = 0; - - private ISafeRunnable task = new PlaybackTask(); - - private UITimer timer = null; - - public AnimationService(IGraphicalViewer viewer) { - super(viewer); - } - - protected void hookControl(Control control) { - super.hookControl(control); - if (control instanceof FigureCanvas) { - updateManager = ((FigureCanvas) control).getLightweightSystem() - .getUpdateManager(); - } else { - updateManager = null; - } - } - - protected void activate() { - } - - protected void deactivate() { - stop(); - } - - public void registerFigure(IFigure figure, IGraphicalPart part) { - figure.addLayoutListener(layoutCapturer); - if (registry == null) - registry = new HashMap(); - registry.put(figure, part); - } - - public void unregisterFigure(IFigure figure) { - figure.removeLayoutListener(layoutCapturer); - if (registry != null) { - registry.remove(figure); - } - } - - public IGraphicalPart getRegisteredPart(IFigure figure) { - return registry == null ? null : registry.get(figure); - } - - public boolean isIdle() { - return state == IDLE; - } - - public boolean isAnimating() { - return state == PLAYBACK; - } - - protected boolean isRecordingInitial() { - return state == RECORDING_INITIAL; - } - - protected boolean isRecordingFinal() { - return state == RECORDING_FINAL; - } - - public IPlaybackProvider getPlaybackProvider() { - return playbackProvider; - } - - public void setPlaybackProvider(IPlaybackProvider playbackProvider) { - if (playbackProvider == null) - playbackProvider = DEFAULT_PLAYBACK_PROVIDER; - this.playbackProvider = playbackProvider; - } - - public void start(Runnable keyframeMaker, Runnable beforeEffect, - Runnable afterEffect) { - if (keyframeMaker == null || !isActive() || updateManager == null - || getViewer().getControl().isDisposed()) - return; - - stop(); - - if (!markBegin()) - return; - - try { - keyframeMaker.run(); - } catch (Exception e) { - stop(); - return; - } - - if (state == IDLE || keyFigures == null || keyFigures.isEmpty() - || getViewer().getControl().isDisposed()) { - stop(); - return; - } - - markEnd(); - - runPlayback(beforeEffect, afterEffect); - } - - public void stop() { - if (timer != null) { - timer.cancel(); - timer = null; - } - - state = IDLE; - - SafeRunner.run(task); - - initialStates = null; - finalStates = null; - keyFigures = null; - toCapture = null; - state = IDLE; - } - - protected boolean markBegin() { - if (state == IDLE) { - state = RECORDING_INITIAL; - initialStates = new HashMap(); - finalStates = new HashMap(); - keyFigures = new HashSet(); - toCapture = new HashSet(); - return true; - } - return false; - } - - protected void recordInitialState(IFigure figure) { - if (initialStates != null) { - initialStates.put(figure, getCurrentState(figure)); - } - } - - protected void markEnd() { - state = RECORDING_FINAL; - if (updateManager != null) { - updateManager.performValidation(); - } - recordFinalStates(); - } - - protected Object getCurrentState(IFigure figure) { - return playbackProvider.getState(figure, getRegisteredPart(figure)); - } - - private void recordFinalStates() { - Iterator figureIterator = keyFigures.iterator(); - while (figureIterator.hasNext()) { - IFigure fig = figureIterator.next(); - if (toCapture.contains(fig)) { - recordFinalState(fig); - } else { - figureIterator.remove(); - } - } - } - - protected void recordFinalState(IFigure figure) { - if (finalStates != null) { - finalStates.put(figure, getCurrentState(figure)); - } - } - - private void runPlayback(final Runnable beforeEffect, Runnable afterEffect) { - if (beforeEffect != null) { - SafeRunner.run(new SafeRunnable( - "Error running effect before animation.") { //$NON-NLS-1$ - public void run() throws Exception { - beforeEffect.run(); - } - }); - } - if (state == IDLE || getViewer().getControl().isDisposed()) - return; - - state = PLAYBACK; - progress = 0; - SafeRunner.run(task); - timer = new PlaybackTimer(afterEffect); - timer.run(); - } - - protected boolean playback(IFigure figure) { - if (toCapture != null && toCapture.contains(figure)) { - return doPlayback(figure); - } - return false; - } - - protected boolean doPlayback(IFigure figure) { - Map initial = (Map) getInitialState(figure); - Map ending = (Map) getFinalState(figure); - if (initial == null || ending == null) - return false; - return playbackProvider.doPlayback(figure, getRegisteredPart(figure), - initial, ending, progress); - } - - protected Object getInitialState(IFigure figure) { - return initialStates == null ? null : initialStates.get(figure); - } - - protected Object getFinalState(IFigure figure) { - return finalStates == null ? null : finalStates.get(figure); - } - - protected void hookPlayback(IFigure figure) { - if (keyFigures != null) { - if (keyFigures.add(figure)) { - recordInitialState(figure); - } - } - } - - protected void hookCapture(IFigure container) { - if (keyFigures != null && keyFigures.contains(container) - && toCapture != null) { - toCapture.add(container); - } - } - -// public void addFigureInitial(IFigure figure) { -// hookPlayback(figure); -// } -// -// public void addFigureFinal(IFigure figure) { -// hookCapture(figure); -// if (toCapture != null && toCapture.contains(figure)) -// recordFinalState(figure); -// } - - public boolean isAnimating(IFigure figure) { - if (isAnimating()) - return getInitialState(figure) != null - && getFinalState(figure) != null; - if (isRecordingFinal()) - return getInitialState(figure) != null; - return false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.animation; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutListener; +import org.eclipse.draw2d.UpdateManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.widgets.Control; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.service.GraphicalViewerService; +import org.xmind.gef.service.IAnimationService; +import org.xmind.gef.service.IPlaybackProvider; +import org.xmind.ui.util.UITimer; + +public class AnimationService extends GraphicalViewerService implements + IAnimationService { + + private static boolean DEBUG = false; + + private class LayoutCapturer implements LayoutListener { + + public void invalidate(IFigure container) { + if (isRecordingInitial()) { + hookPlayback(container); + } + } + + public boolean layout(IFigure container) { + if (isAnimating()) { + return playback(container); + } + return false; + } + + public void postLayout(IFigure container) { + if (isRecordingFinal()) { + hookCapture(container); + } + } + + public void remove(IFigure child) { + } + + public void setConstraint(IFigure child, Object constraint) { + } + + } + + private class PlaybackTask extends SafeRunnable { + + public void run() throws Exception { + if (getViewer().getControl().isDisposed()) + return; + + if (initialStates != null) { + for (IFigure figure : initialStates.keySet()) { + figure.revalidate(); + } + } + + if (timer == null || timer.isCanceled()) + return; + + progress = timer.getCurrentLoop() * 1.0f / (timer.getLoops() + 1); + } + + } + + private class PlaybackTimer extends UITimer { + + private Runnable afterEffect; + + public PlaybackTimer(Runnable after) { + super(0, DEBUG ? 300 : 10, DEBUG ? 10 : 3, task); + this.afterEffect = after; + } + + @Override + protected void onFinished() { + super.onFinished(); + timer = null; + stop(); + runAfterEffect(); + } + + private void runAfterEffect() { + if (afterEffect != null && !getViewer().getControl().isDisposed()) { + SafeRunner.run(new SafeRunnable( + "Error running effect after animation.") { //$NON-NLS-1$ + public void run() throws Exception { + afterEffect.run(); + } + }); + } + } + + @Override + protected void onCanceled() { + super.onCanceled(); + runAfterEffect(); + timer = null; + stop(); + } + + } + + private static final int IDLE = 0; + private static final int RECORDING_INITIAL = 1; + private static final int RECORDING_FINAL = 2; + private static final int PLAYBACK = 3; + + private static final IPlaybackProvider DEFAULT_PLAYBACK_PROVIDER = new LayoutPlaybackProvider(); + + private UpdateManager updateManager; + + private int state = IDLE; + + private final LayoutCapturer layoutCapturer = new LayoutCapturer(); + + private Map registry = null; + + private IPlaybackProvider playbackProvider = DEFAULT_PLAYBACK_PROVIDER; + + private Set keyFigures = null; + + private Map initialStates = null; + + private Map finalStates = null; + + private Set toCapture = null; + + private float progress = 0; + + private ISafeRunnable task = new PlaybackTask(); + + private UITimer timer = null; + + public AnimationService(IGraphicalViewer viewer) { + super(viewer); + } + + protected void hookControl(Control control) { + super.hookControl(control); + if (control instanceof FigureCanvas) { + updateManager = ((FigureCanvas) control).getLightweightSystem() + .getUpdateManager(); + } else { + updateManager = null; + } + } + + protected void activate() { + } + + protected void deactivate() { + stop(); + } + + public void registerFigure(IFigure figure, IGraphicalPart part) { + figure.addLayoutListener(layoutCapturer); + if (registry == null) + registry = new HashMap(); + registry.put(figure, part); + } + + public void unregisterFigure(IFigure figure) { + figure.removeLayoutListener(layoutCapturer); + if (registry != null) { + registry.remove(figure); + } + } + + public IGraphicalPart getRegisteredPart(IFigure figure) { + return registry == null ? null : registry.get(figure); + } + + public boolean isIdle() { + return state == IDLE; + } + + public boolean isAnimating() { + return state == PLAYBACK; + } + + protected boolean isRecordingInitial() { + return state == RECORDING_INITIAL; + } + + protected boolean isRecordingFinal() { + return state == RECORDING_FINAL; + } + + public IPlaybackProvider getPlaybackProvider() { + return playbackProvider; + } + + public void setPlaybackProvider(IPlaybackProvider playbackProvider) { + if (playbackProvider == null) + playbackProvider = DEFAULT_PLAYBACK_PROVIDER; + this.playbackProvider = playbackProvider; + } + + public void start(Runnable keyframeMaker, Runnable beforeEffect, + Runnable afterEffect) { + if (keyframeMaker == null || !isActive() || updateManager == null + || getViewer().getControl().isDisposed()) + return; + + stop(); + + if (!markBegin()) + return; + + try { + keyframeMaker.run(); + } catch (Exception e) { + stop(); + return; + } + + if (state == IDLE || keyFigures == null || keyFigures.isEmpty() + || getViewer().getControl().isDisposed()) { + stop(); + return; + } + + markEnd(); + + runPlayback(beforeEffect, afterEffect); + } + + public void stop() { + if (timer != null) { + timer.cancel(); + timer = null; + } + + state = IDLE; + + SafeRunner.run(task); + + initialStates = null; + finalStates = null; + keyFigures = null; + toCapture = null; + state = IDLE; + } + + protected boolean markBegin() { + if (state == IDLE) { + state = RECORDING_INITIAL; + initialStates = new HashMap(); + finalStates = new HashMap(); + keyFigures = new HashSet(); + toCapture = new HashSet(); + return true; + } + return false; + } + + protected void recordInitialState(IFigure figure) { + if (initialStates != null) { + initialStates.put(figure, getCurrentState(figure)); + } + } + + protected void markEnd() { + state = RECORDING_FINAL; + if (updateManager != null) { + updateManager.performValidation(); + } + recordFinalStates(); + } + + protected Object getCurrentState(IFigure figure) { + return playbackProvider.getState(figure, getRegisteredPart(figure)); + } + + private void recordFinalStates() { + Iterator figureIterator = keyFigures.iterator(); + while (figureIterator.hasNext()) { + IFigure fig = figureIterator.next(); + if (toCapture.contains(fig)) { + recordFinalState(fig); + } else { + figureIterator.remove(); + } + } + } + + protected void recordFinalState(IFigure figure) { + if (finalStates != null) { + finalStates.put(figure, getCurrentState(figure)); + } + } + + private void runPlayback(final Runnable beforeEffect, Runnable afterEffect) { + if (beforeEffect != null) { + SafeRunner.run(new SafeRunnable( + "Error running effect before animation.") { //$NON-NLS-1$ + public void run() throws Exception { + beforeEffect.run(); + } + }); + } + if (state == IDLE || getViewer().getControl().isDisposed()) + return; + + state = PLAYBACK; + progress = 0; + SafeRunner.run(task); + timer = new PlaybackTimer(afterEffect); + timer.run(); + } + + protected boolean playback(IFigure figure) { + if (toCapture != null && toCapture.contains(figure)) { + return doPlayback(figure); + } + return false; + } + + protected boolean doPlayback(IFigure figure) { + Map initial = (Map) getInitialState(figure); + Map ending = (Map) getFinalState(figure); + if (initial == null || ending == null) + return false; + return playbackProvider.doPlayback(figure, getRegisteredPart(figure), + initial, ending, progress); + } + + protected Object getInitialState(IFigure figure) { + return initialStates == null ? null : initialStates.get(figure); + } + + protected Object getFinalState(IFigure figure) { + return finalStates == null ? null : finalStates.get(figure); + } + + protected void hookPlayback(IFigure figure) { + if (keyFigures != null) { + if (keyFigures.add(figure)) { + recordInitialState(figure); + } + } + } + + protected void hookCapture(IFigure container) { + if (keyFigures != null && keyFigures.contains(container) + && toCapture != null) { + toCapture.add(container); + } + } + +// public void addFigureInitial(IFigure figure) { +// hookPlayback(figure); +// } +// +// public void addFigureFinal(IFigure figure) { +// hookCapture(figure); +// if (toCapture != null && toCapture.contains(figure)) +// recordFinalState(figure); +// } + + public boolean isAnimating(IFigure figure) { + if (isAnimating()) + return getInitialState(figure) != null + && getFinalState(figure) != null; + if (isRecordingFinal()) + return getInitialState(figure) != null; + return false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ArrowFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ArrowFigure.java index d8ad96a94..c9e8056d9 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ArrowFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ArrowFigure.java @@ -1,74 +1,74 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Rectangle; - -public class ArrowFigure extends BaseFigure { - - public static final int LEFT = PositionConstants.LEFT; - - public static final int RIGHT = PositionConstants.RIGHT; - - public static final int UP = PositionConstants.TOP; - - public static final int DOWN = PositionConstants.BOTTOM; - - private static final float len = 4.0f; - - private class Arrow extends Layer { - - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - - Rectangle b = getBounds(); - float cx = b.x + ((float) b.width) / 2; - float cy = b.y + ((float) b.height) / 2; - int[] points; - if (orientation == LEFT) { - points = new int[] { (int) (cx - len), (int) cy, // - (int) (cx + len), (int) (cy - len), // - (int) (cx + len), (int) (cy + len) }; - } else if (orientation == RIGHT) { - points = new int[] { (int) (cx + len), (int) cy, // - (int) (cx - len), (int) (cy - len), // - (int) (cx - len), (int) (cy + len) }; - } else if (orientation == UP) { - points = new int[] { (int) cx, (int) (cy - len), // - (int) (cx + len), (int) (cy + len), // - (int) (cx - len), (int) (cy + len) }; - } else { - points = new int[] { (int) cx, (int) (cy + len), // - (int) (cx + len), (int) (cy - len), // - (int) (cx - len), (int) (cy - len) }; - } - graphics.fillPolygon(points); - graphics.drawPolygon(points); - } - - } - - private int orientation = 0; - - @Override - protected void addFeedbackLayers() { - addPressFeedbackLayer(); - } - - @Override - protected void addContentLayer() { - setContentLayer(new Arrow()); - } - - public int getOrientation() { - return orientation; - } - - public void setOrientation(int direction) { - this.orientation = direction; - repaint(); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Rectangle; + +public class ArrowFigure extends BaseFigure { + + public static final int LEFT = PositionConstants.LEFT; + + public static final int RIGHT = PositionConstants.RIGHT; + + public static final int UP = PositionConstants.TOP; + + public static final int DOWN = PositionConstants.BOTTOM; + + private static final float len = 4.0f; + + private class Arrow extends Layer { + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + + Rectangle b = getBounds(); + float cx = b.x + ((float) b.width) / 2; + float cy = b.y + ((float) b.height) / 2; + int[] points; + if (orientation == LEFT) { + points = new int[] { (int) (cx - len), (int) cy, // + (int) (cx + len), (int) (cy - len), // + (int) (cx + len), (int) (cy + len) }; + } else if (orientation == RIGHT) { + points = new int[] { (int) (cx + len), (int) cy, // + (int) (cx - len), (int) (cy - len), // + (int) (cx - len), (int) (cy + len) }; + } else if (orientation == UP) { + points = new int[] { (int) cx, (int) (cy - len), // + (int) (cx + len), (int) (cy + len), // + (int) (cx - len), (int) (cy + len) }; + } else { + points = new int[] { (int) cx, (int) (cy + len), // + (int) (cx + len), (int) (cy - len), // + (int) (cx - len), (int) (cy - len) }; + } + graphics.fillPolygon(points); + graphics.drawPolygon(points); + } + + } + + private int orientation = 0; + + @Override + protected void addFeedbackLayers() { + addPressFeedbackLayer(); + } + + @Override + protected void addContentLayer() { + setContentLayer(new Arrow()); + } + + public int getOrientation() { + return orientation; + } + + public void setOrientation(int direction) { + this.orientation = direction; + repaint(); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/BaseFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/BaseFigure.java index af9d25496..9f5719794 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/BaseFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/BaseFigure.java @@ -1,198 +1,198 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.GridData; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.LayeredPane; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.StackLayout; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.graphics.AlphaGraphics; - -public class BaseFigure extends Figure { - - public static Object PRESELECTED = "PRESELECTED"; //$NON-NLS-1$ - - public static Object SELECTED = "SELECTED"; //$NON-NLS-1$ - - public static Object PRESSED = "PRESSED"; //$NON-NLS-1$ - - public static Object CONTENT = "CONTENT"; //$NON-NLS-1$ - - private double alpha = 255; - - private LayeredPane pane = new LayeredPane(); - - public BaseFigure() { - setLayoutManager(new StackLayout()); - setOpaque(false); - add(pane); - addLayers(); - setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND)); - } - - protected void addLayers() { - addFeedbackLayers(); - addContentLayer(); - } - - protected void addFeedbackLayers() { - addSelectFeedbackLayer(); - addPressFeedbackLayer(); - addPreselectFeedbackLayer(); - } - - protected void addPreselectFeedbackLayer() { - pane.add(new PreselectFeedbackLayer(), PRESELECTED, -1); - } - - protected void addPressFeedbackLayer() { - pane.add(new PressFeedbackLayer(), PRESSED, -1); - } - - protected void addSelectFeedbackLayer() { - pane.add(new SelectFeedbackLayer(), SELECTED, -1); - } - - protected void addContentLayer() { - pane.add(new TextLayer(), CONTENT, -1); - } - - public void setContentLayer(IFigure content) { - removeOldContent(); - pane.add(content, CONTENT, -1); - } - - private void removeOldContent() { - Layer content = pane.getLayer(CONTENT); - if (content != null) - pane.remove(content); - } - - public void setContentLayerAfter(Layer content, Object after) { - removeOldContent(); - pane.addLayerAfter(content, CONTENT, after); - } - - public void setContentLayerBefore(Layer content, Object before) { - removeOldContent(); - pane.addLayerBefore(content, CONTENT, before); - } - - public IFigure getContent() { - return pane.getLayer(CONTENT); - } - - public String getText() { - IFigure content = getContent(); - if (content instanceof TextLayer) - return ((TextLayer) content).getText(); - return null; - } - - public void setText(String text) { - IFigure content = getContent(); - if (content instanceof TextLayer) - ((TextLayer) content).setText(text); - } - - public void setTextCandidates(String[] candidates) { - IFigure content = getContent(); - if (content instanceof TextLayer) - ((TextLayer) content).setCandidates(candidates); - } - - public void setTextAlpha(int alpha) { - IFigure content = getContent(); - if (content instanceof TextLayer) - ((TextLayer) content).setAlpha(alpha); - } - - @Override - public void paint(Graphics graphics) { - AlphaGraphics g = new AlphaGraphics(graphics); - g.setMainAlpha((int) alpha); - g.setAntialias(SWT.ON); - super.paint(g); - g.dispose(); - } - - public void setAlpha(double alpha) { - this.alpha = alpha; - repaint(); - } - - public double getAlpha() { - return alpha; - } - - public boolean isPreselected() { - Layer layer = pane.getLayer(PRESELECTED); - return layer != null && layer.isVisible(); - } - - public void setPreselected(boolean value) { - Layer layer = pane.getLayer(PRESELECTED); - - if (layer != null) { - layer.setVisible(value); - } - } - - public boolean isSelected() { - Layer layer = pane.getLayer(SELECTED); - return layer != null && layer.isVisible(); - } - - public void setSelected(boolean value) { - Layer layer = pane.getLayer(SELECTED); - if (layer != null) { - layer.setVisible(value); - this.setForegroundColor( - value ? ColorConstants.white : ColorConstants.black); - } - } - - public boolean isPressed() { - Layer layer = pane.getLayer(PRESSED); - return layer != null && layer.isVisible(); - } - - public void setPressed(boolean value) { - Layer layer = pane.getLayer(PRESSED); - if (layer != null) { - layer.setVisible(value); - } - IFigure content = getContent(); - if (content instanceof TextLayer) - ((TextLayer) content).setOffset(value ? 1 : 0, value ? 1 : 0); - } - - @Override - public Dimension getPreferredSize(int wHint, int hHint) { - Dimension psize = super.getPreferredSize(wHint, hHint); - if (getParent() != null) { - LayoutManager layout = getParent().getLayoutManager(); - if (layout != null) { - Object constraint = layout.getConstraint(this); - if (constraint instanceof GridData) { - int h = ((GridData) constraint).horizontalSpan; - if (h > 1) { - psize = psize.getCopy(); - psize.width = psize.width / h; - } - } - } - } - return psize; - } - -} +/** + * + */ +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.GridData; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.LayeredPane; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.graphics.AlphaGraphics; + +public class BaseFigure extends Figure { + + public static Object PRESELECTED = "PRESELECTED"; //$NON-NLS-1$ + + public static Object SELECTED = "SELECTED"; //$NON-NLS-1$ + + public static Object PRESSED = "PRESSED"; //$NON-NLS-1$ + + public static Object CONTENT = "CONTENT"; //$NON-NLS-1$ + + private double alpha = 255; + + private LayeredPane pane = new LayeredPane(); + + public BaseFigure() { + setLayoutManager(new StackLayout()); + setOpaque(false); + add(pane); + addLayers(); + setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND)); + } + + protected void addLayers() { + addFeedbackLayers(); + addContentLayer(); + } + + protected void addFeedbackLayers() { + addSelectFeedbackLayer(); + addPressFeedbackLayer(); + addPreselectFeedbackLayer(); + } + + protected void addPreselectFeedbackLayer() { + pane.add(new PreselectFeedbackLayer(), PRESELECTED, -1); + } + + protected void addPressFeedbackLayer() { + pane.add(new PressFeedbackLayer(), PRESSED, -1); + } + + protected void addSelectFeedbackLayer() { + pane.add(new SelectFeedbackLayer(), SELECTED, -1); + } + + protected void addContentLayer() { + pane.add(new TextLayer(), CONTENT, -1); + } + + public void setContentLayer(IFigure content) { + removeOldContent(); + pane.add(content, CONTENT, -1); + } + + private void removeOldContent() { + Layer content = pane.getLayer(CONTENT); + if (content != null) + pane.remove(content); + } + + public void setContentLayerAfter(Layer content, Object after) { + removeOldContent(); + pane.addLayerAfter(content, CONTENT, after); + } + + public void setContentLayerBefore(Layer content, Object before) { + removeOldContent(); + pane.addLayerBefore(content, CONTENT, before); + } + + public IFigure getContent() { + return pane.getLayer(CONTENT); + } + + public String getText() { + IFigure content = getContent(); + if (content instanceof TextLayer) + return ((TextLayer) content).getText(); + return null; + } + + public void setText(String text) { + IFigure content = getContent(); + if (content instanceof TextLayer) + ((TextLayer) content).setText(text); + } + + public void setTextCandidates(String[] candidates) { + IFigure content = getContent(); + if (content instanceof TextLayer) + ((TextLayer) content).setCandidates(candidates); + } + + public void setTextAlpha(int alpha) { + IFigure content = getContent(); + if (content instanceof TextLayer) + ((TextLayer) content).setAlpha(alpha); + } + + @Override + public void paint(Graphics graphics) { + AlphaGraphics g = new AlphaGraphics(graphics); + g.setMainAlpha((int) alpha); + g.setAntialias(SWT.ON); + super.paint(g); + g.dispose(); + } + + public void setAlpha(double alpha) { + this.alpha = alpha; + repaint(); + } + + public double getAlpha() { + return alpha; + } + + public boolean isPreselected() { + Layer layer = pane.getLayer(PRESELECTED); + return layer != null && layer.isVisible(); + } + + public void setPreselected(boolean value) { + Layer layer = pane.getLayer(PRESELECTED); + + if (layer != null) { + layer.setVisible(value); + } + } + + public boolean isSelected() { + Layer layer = pane.getLayer(SELECTED); + return layer != null && layer.isVisible(); + } + + public void setSelected(boolean value) { + Layer layer = pane.getLayer(SELECTED); + if (layer != null) { + layer.setVisible(value); + this.setForegroundColor( + value ? ColorConstants.white : ColorConstants.black); + } + } + + public boolean isPressed() { + Layer layer = pane.getLayer(PRESSED); + return layer != null && layer.isVisible(); + } + + public void setPressed(boolean value) { + Layer layer = pane.getLayer(PRESSED); + if (layer != null) { + layer.setVisible(value); + } + IFigure content = getContent(); + if (content instanceof TextLayer) + ((TextLayer) content).setOffset(value ? 1 : 0, value ? 1 : 0); + } + + @Override + public Dimension getPreferredSize(int wHint, int hHint) { + Dimension psize = super.getPreferredSize(wHint, hHint); + if (getParent() != null) { + LayoutManager layout = getParent().getLayoutManager(); + if (layout != null) { + Object constraint = layout.getConstraint(this); + if (constraint instanceof GridData) { + int h = ((GridData) constraint).horizontalSpan; + if (h > 1) { + psize = psize.getCopy(); + psize.width = psize.width / h; + } + } + } + } + return psize; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/CalendarAnimation.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/CalendarAnimation.java index 96594e3fa..a1cc1708f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/CalendarAnimation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/CalendarAnimation.java @@ -1,190 +1,190 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.MONTH; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; - -public abstract class CalendarAnimation { - - protected final IAnimationAdvisor advisor; - - private Runnable callback; - - protected IFigure newPanel; - - protected Dimension oldSize; - - protected List oldDays = new ArrayList(31); - - protected List newDays = new ArrayList(31); - - protected boolean hasNewPanel; - - protected Rectangle oldInitConstraint; - - protected Rectangle oldFinalConstraint; - - protected Rectangle newInitConstraint; - - protected Rectangle newFinalConstraint; - - private Rectangle oldConstraint; - - private Rectangle newConstraint; - - private long start; - - public CalendarAnimation(IAnimationAdvisor advisor) { - this.advisor = advisor; - } - - public CalendarAnimation callback(Runnable callback) { - this.callback = callback; - return this; - } - - public IFigure getNewPanel() { - return newPanel; - } - - public void start() { - init(); - start = System.currentTimeMillis(); - Runnable step = new Runnable() { - public void run() { - int pass = (int) (System.currentTimeMillis() - start); - if (pass > advisor.getDuration()) { - end(); - } else { - playback(pass); - Display.getCurrent().asyncExec(this); - } - } - }; - Display.getCurrent().asyncExec(step); - } - - private void init() { - this.oldSize = advisor.getPanel().getSize(); - initOldDays(); - newPanel = createNewPanel(); - hasNewPanel = newPanel != advisor.getPanel(); - if (hasNewPanel) { - advisor.getLayer().add(newPanel); - } - createNewDays(); - initConstraint(); - } - - private void initOldDays() { - List dayFigures = advisor.getPanel().getChildren(); - for (int i = 0; i < dayFigures.size(); i++) { - DayFigure dayFigure = (DayFigure) dayFigures.get(i); - advisor.initOldDay(dayFigure); - Calendar date = dayFigure.getDate(); - int month = date.get(MONTH); - if (month == advisor.getOldMonth()) { - oldDays.add(dayFigure); - } else if (month == advisor.getNewMonth()) { - oldDayInNewMonth(dayFigure, date, month, i); - } - } - } - - protected IFigure createNewPanel() { - return advisor.getPanel(); - } - - protected abstract void createNewDays(); - - protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, - int month, int index) { - } - - protected abstract Rectangle createOldInitConstraint(); - - protected abstract Rectangle createOldFinalConstraint(); - - protected Rectangle createNewInitConstraint() { - return null; - } - - protected Rectangle createNewFinalConstraint() { - return null; - } - - private void initConstraint() { - hasNewPanel = newPanel != advisor.getPanel(); - oldInitConstraint = createOldInitConstraint(); - oldFinalConstraint = createOldFinalConstraint(); - newInitConstraint = hasNewPanel ? createNewInitConstraint() : null; - newFinalConstraint = hasNewPanel ? createNewFinalConstraint() : null; - - oldConstraint = oldInitConstraint.getCopy(); - newConstraint = hasNewPanel ? newInitConstraint.getCopy() : null; - advisor.getLayer().setConstraint(advisor.getPanel(), oldConstraint); - if (hasNewPanel) - advisor.getLayer().setConstraint(newPanel, newConstraint); - } - - private void playback(int elapsed) { - int duration = advisor.getDuration(); - IFigure layer = advisor.getLayer(); - oldConstraint.x = DatePicker.calc(oldInitConstraint.x, - oldFinalConstraint.x, elapsed, duration); - oldConstraint.y = DatePicker.calc(oldInitConstraint.y, - oldFinalConstraint.y, elapsed, duration); - layer.setConstraint(advisor.getPanel(), oldConstraint); - - if (hasNewPanel) { - newConstraint.x = DatePicker.calc(newInitConstraint.x, - newFinalConstraint.x, elapsed, duration); - newConstraint.y = DatePicker.calc(newInitConstraint.y, - newFinalConstraint.y, elapsed, duration); - layer.setConstraint(newPanel, newConstraint); - } - - for (DayFigure oldDay : oldDays) { - oldDay.setTextAlpha(DatePicker.calc(DatePicker.NORMAL_ALPHA, - DatePicker.SIBLING_MONTH_ALPHA, elapsed, duration)); - } - for (DayFigure newDay : newDays) { - newDay.setTextAlpha(DatePicker.calc(DatePicker.SIBLING_MONTH_ALPHA, - DatePicker.NORMAL_ALPHA, elapsed, duration)); - } - } - - protected void end() { - removeOldDays(); - updateNewPanel(); - updateJobs(); - if (callback != null) - callback.run(); - } - - protected void removeOldDays() { - } - - private void updateNewPanel() { - List dayFigures = newPanel.getChildren(); - for (int i = 0; i < dayFigures.size(); i++) { - DayFigure dayFigure = (DayFigure) dayFigures.get(i); - advisor.updateNewDay(dayFigure); - } - newPanel.invalidate(); - advisor.getLayer().setConstraint(newPanel, null); - } - - protected abstract void updateJobs(); - +/** + * + */ +package org.xmind.ui.datepicker; + +import static java.util.Calendar.MONTH; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; + +public abstract class CalendarAnimation { + + protected final IAnimationAdvisor advisor; + + private Runnable callback; + + protected IFigure newPanel; + + protected Dimension oldSize; + + protected List oldDays = new ArrayList(31); + + protected List newDays = new ArrayList(31); + + protected boolean hasNewPanel; + + protected Rectangle oldInitConstraint; + + protected Rectangle oldFinalConstraint; + + protected Rectangle newInitConstraint; + + protected Rectangle newFinalConstraint; + + private Rectangle oldConstraint; + + private Rectangle newConstraint; + + private long start; + + public CalendarAnimation(IAnimationAdvisor advisor) { + this.advisor = advisor; + } + + public CalendarAnimation callback(Runnable callback) { + this.callback = callback; + return this; + } + + public IFigure getNewPanel() { + return newPanel; + } + + public void start() { + init(); + start = System.currentTimeMillis(); + Runnable step = new Runnable() { + public void run() { + int pass = (int) (System.currentTimeMillis() - start); + if (pass > advisor.getDuration()) { + end(); + } else { + playback(pass); + Display.getCurrent().asyncExec(this); + } + } + }; + Display.getCurrent().asyncExec(step); + } + + private void init() { + this.oldSize = advisor.getPanel().getSize(); + initOldDays(); + newPanel = createNewPanel(); + hasNewPanel = newPanel != advisor.getPanel(); + if (hasNewPanel) { + advisor.getLayer().add(newPanel); + } + createNewDays(); + initConstraint(); + } + + private void initOldDays() { + List dayFigures = advisor.getPanel().getChildren(); + for (int i = 0; i < dayFigures.size(); i++) { + DayFigure dayFigure = (DayFigure) dayFigures.get(i); + advisor.initOldDay(dayFigure); + Calendar date = dayFigure.getDate(); + int month = date.get(MONTH); + if (month == advisor.getOldMonth()) { + oldDays.add(dayFigure); + } else if (month == advisor.getNewMonth()) { + oldDayInNewMonth(dayFigure, date, month, i); + } + } + } + + protected IFigure createNewPanel() { + return advisor.getPanel(); + } + + protected abstract void createNewDays(); + + protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, + int month, int index) { + } + + protected abstract Rectangle createOldInitConstraint(); + + protected abstract Rectangle createOldFinalConstraint(); + + protected Rectangle createNewInitConstraint() { + return null; + } + + protected Rectangle createNewFinalConstraint() { + return null; + } + + private void initConstraint() { + hasNewPanel = newPanel != advisor.getPanel(); + oldInitConstraint = createOldInitConstraint(); + oldFinalConstraint = createOldFinalConstraint(); + newInitConstraint = hasNewPanel ? createNewInitConstraint() : null; + newFinalConstraint = hasNewPanel ? createNewFinalConstraint() : null; + + oldConstraint = oldInitConstraint.getCopy(); + newConstraint = hasNewPanel ? newInitConstraint.getCopy() : null; + advisor.getLayer().setConstraint(advisor.getPanel(), oldConstraint); + if (hasNewPanel) + advisor.getLayer().setConstraint(newPanel, newConstraint); + } + + private void playback(int elapsed) { + int duration = advisor.getDuration(); + IFigure layer = advisor.getLayer(); + oldConstraint.x = DatePicker.calc(oldInitConstraint.x, + oldFinalConstraint.x, elapsed, duration); + oldConstraint.y = DatePicker.calc(oldInitConstraint.y, + oldFinalConstraint.y, elapsed, duration); + layer.setConstraint(advisor.getPanel(), oldConstraint); + + if (hasNewPanel) { + newConstraint.x = DatePicker.calc(newInitConstraint.x, + newFinalConstraint.x, elapsed, duration); + newConstraint.y = DatePicker.calc(newInitConstraint.y, + newFinalConstraint.y, elapsed, duration); + layer.setConstraint(newPanel, newConstraint); + } + + for (DayFigure oldDay : oldDays) { + oldDay.setTextAlpha(DatePicker.calc(DatePicker.NORMAL_ALPHA, + DatePicker.SIBLING_MONTH_ALPHA, elapsed, duration)); + } + for (DayFigure newDay : newDays) { + newDay.setTextAlpha(DatePicker.calc(DatePicker.SIBLING_MONTH_ALPHA, + DatePicker.NORMAL_ALPHA, elapsed, duration)); + } + } + + protected void end() { + removeOldDays(); + updateNewPanel(); + updateJobs(); + if (callback != null) + callback.run(); + } + + protected void removeOldDays() { + } + + private void updateNewPanel() { + List dayFigures = newPanel.getChildren(); + for (int i = 0; i < dayFigures.size(); i++) { + DayFigure dayFigure = (DayFigure) dayFigures.get(i); + advisor.updateNewDay(dayFigure); + } + newPanel.invalidate(); + advisor.getLayer().setConstraint(newPanel, null); + } + + protected abstract void updateJobs(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ConstraintStackLayout.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ConstraintStackLayout.java index 51fe7e6d2..ea5ba3c44 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ConstraintStackLayout.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/ConstraintStackLayout.java @@ -1,40 +1,40 @@ -package org.xmind.ui.datepicker; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.StackLayout; -import org.eclipse.draw2d.geometry.Rectangle; - -public class ConstraintStackLayout extends StackLayout { - - private Map constraints = new HashMap(); - - public void layout(IFigure container) { - Rectangle r = container.getClientArea(); - List children = container.getChildren(); - IFigure child; - Rectangle constraint; - for (int i = 0; i < children.size(); i++) { - child = (IFigure) children.get(i); - constraint = constraints.get(child); - if (constraint == null) { - child.setBounds(r); - } else { - child.setBounds(constraint.getTranslated(r.x, r.y)); - } - } - } - - public void setConstraint(IFigure child, Object constraint) { - super.setConstraint(child, constraint); - if (constraint == null || !(constraint instanceof Rectangle)) { - constraints.remove(child); - } else { - constraints.put(child, (Rectangle) constraint); - } - } - -} +package org.xmind.ui.datepicker; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Rectangle; + +public class ConstraintStackLayout extends StackLayout { + + private Map constraints = new HashMap(); + + public void layout(IFigure container) { + Rectangle r = container.getClientArea(); + List children = container.getChildren(); + IFigure child; + Rectangle constraint; + for (int i = 0; i < children.size(); i++) { + child = (IFigure) children.get(i); + constraint = constraints.get(child); + if (constraint == null) { + child.setBounds(r); + } else { + child.setBounds(constraint.getTranslated(r.x, r.y)); + } + } + } + + public void setConstraint(IFigure child, Object constraint) { + super.setConstraint(child, constraint); + if (constraint == null || !(constraint instanceof Rectangle)) { + constraints.remove(child); + } else { + constraints.put(child, (Rectangle) constraint); + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateLabelProvider.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateLabelProvider.java index 5570bdc64..c721a8f32 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateLabelProvider.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateLabelProvider.java @@ -1,27 +1,27 @@ -package org.xmind.ui.datepicker; - -import java.util.Calendar; - -import org.eclipse.jface.viewers.LabelProvider; - -public class DateLabelProvider extends LabelProvider { - - @Override - public String getText(Object element) { - if (element == null) - return Messages.None; - if (element instanceof Long) { - element = Calendar.getInstance(); - ((Calendar) element).setTimeInMillis(((Long) element).longValue()); - } - if (element instanceof Calendar) { - return getDateText((Calendar) element); - } - return Messages.Illegal; - } - - protected String getDateText(Calendar date) { -// return String.format("%1$tF %1$tT ", date); //$NON-NLS-1$ %1$tb %1$te, %1$tY" - return String.format("%1$tb %1$te, %1$tY", date); //$NON-NLS-1$ - } -} +package org.xmind.ui.datepicker; + +import java.util.Calendar; + +import org.eclipse.jface.viewers.LabelProvider; + +public class DateLabelProvider extends LabelProvider { + + @Override + public String getText(Object element) { + if (element == null) + return Messages.None; + if (element instanceof Long) { + element = Calendar.getInstance(); + ((Calendar) element).setTimeInMillis(((Long) element).longValue()); + } + if (element instanceof Calendar) { + return getDateText((Calendar) element); + } + return Messages.Illegal; + } + + protected String getDateText(Calendar date) { +// return String.format("%1$tF %1$tT ", date); //$NON-NLS-1$ %1$tb %1$te, %1$tY" + return String.format("%1$tb %1$te, %1$tY", date); //$NON-NLS-1$ + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePanelLayout.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePanelLayout.java index ba2f61801..e3609d9c4 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePanelLayout.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePanelLayout.java @@ -1,106 +1,106 @@ -package org.xmind.ui.datepicker; - -import java.util.List; - -import org.eclipse.draw2d.AbstractLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; - -public class DatePanelLayout extends AbstractLayout { - - @Override - protected Dimension calculatePreferredSize(IFigure container, int wHint, - int hHint) { - if (wHint >= 0 && hHint >= 0) { - return new Dimension(wHint, hHint); - } - - List children = container.getChildren(); - int cols = 7; - int rows = (children.size() + 6) / cols; - int[] widths = wHint >= 0 ? null : new int[cols]; - int[] heights = hHint >= 0 ? null : new int[rows]; - int m = 0, n = 0; - int wh = wHint >= 0 ? wHint / cols : -1; - int hh = hHint >= 0 ? hHint / rows : -1; - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - Dimension childSize = child.getPreferredSize(wh, hh); - if (wHint < 0) - widths[m] = Math.max(widths[m], childSize.width); - if (hHint < 0) - heights[n] = Math.max(heights[n], childSize.height); - m++; - if (m >= cols) { - n++; - m = 0; - } - } - - int width; - if (wHint >= 0) { - width = wHint; - } else { - width = 0; - for (int i = 0; i < widths.length; i++) { - width += widths[i]; - } - } - int height; - if (hHint >= 0) { - height = hHint; - } else { - height = 0; - for (int i = 0; i < heights.length; i++) { - height += heights[i]; - } - } - - return new Dimension(width, height); - } - - public void layout(IFigure container) { - Rectangle box = container.getClientArea(); - List children = container.getChildren(); - int cols = 7; - int rows = (children.size() + 6) / cols; - float fx = box.x, fy = box.y; - float fw = ((float) box.width + 0.99f) / cols; - float fh = ((float) box.height + 0.99f) / rows; - int x = box.x, y = box.y; - int w = ((int) (fx + fw)) - x; - int h = ((int) (fy + fh)) - y; - int m = 0, n = 0; - int[] lefts = new int[7]; - int[] widths = new int[7]; - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - Rectangle b; - if (n == 0) { - b = new Rectangle(x, y, w, h); - lefts[m] = x; - widths[m] = w; - x += w; - fx += fw; - w = ((int) (fx + fw)) - x; - } else { - x = lefts[m]; - w = widths[m]; - b = new Rectangle(x, y, w, h); - } - - child.setBounds(b); - - m++; - if (m >= cols) { - y += h; - fy += fh; - h = ((int) (fy + fh)) - y; - n++; - m = 0; - } - } - } - -} +package org.xmind.ui.datepicker; + +import java.util.List; + +import org.eclipse.draw2d.AbstractLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; + +public class DatePanelLayout extends AbstractLayout { + + @Override + protected Dimension calculatePreferredSize(IFigure container, int wHint, + int hHint) { + if (wHint >= 0 && hHint >= 0) { + return new Dimension(wHint, hHint); + } + + List children = container.getChildren(); + int cols = 7; + int rows = (children.size() + 6) / cols; + int[] widths = wHint >= 0 ? null : new int[cols]; + int[] heights = hHint >= 0 ? null : new int[rows]; + int m = 0, n = 0; + int wh = wHint >= 0 ? wHint / cols : -1; + int hh = hHint >= 0 ? hHint / rows : -1; + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + Dimension childSize = child.getPreferredSize(wh, hh); + if (wHint < 0) + widths[m] = Math.max(widths[m], childSize.width); + if (hHint < 0) + heights[n] = Math.max(heights[n], childSize.height); + m++; + if (m >= cols) { + n++; + m = 0; + } + } + + int width; + if (wHint >= 0) { + width = wHint; + } else { + width = 0; + for (int i = 0; i < widths.length; i++) { + width += widths[i]; + } + } + int height; + if (hHint >= 0) { + height = hHint; + } else { + height = 0; + for (int i = 0; i < heights.length; i++) { + height += heights[i]; + } + } + + return new Dimension(width, height); + } + + public void layout(IFigure container) { + Rectangle box = container.getClientArea(); + List children = container.getChildren(); + int cols = 7; + int rows = (children.size() + 6) / cols; + float fx = box.x, fy = box.y; + float fw = ((float) box.width + 0.99f) / cols; + float fh = ((float) box.height + 0.99f) / rows; + int x = box.x, y = box.y; + int w = ((int) (fx + fw)) - x; + int h = ((int) (fy + fh)) - y; + int m = 0, n = 0; + int[] lefts = new int[7]; + int[] widths = new int[7]; + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + Rectangle b; + if (n == 0) { + b = new Rectangle(x, y, w, h); + lefts[m] = x; + widths[m] = w; + x += w; + fx += fw; + w = ((int) (fx + fw)) - x; + } else { + x = lefts[m]; + w = widths[m]; + b = new Rectangle(x, y, w, h); + } + + child.setBounds(b); + + m++; + if (m >= cols) { + y += h; + fy += fh; + h = ((int) (fy + fh)) - y; + n++; + m = 0; + } + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker.java index 17d10a4e0..62fe19a8d 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker.java @@ -1,1695 +1,1695 @@ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.DAY_OF_WEEK; -import static java.util.Calendar.HOUR_OF_DAY; -import static java.util.Calendar.MINUTE; -import static java.util.Calendar.MONTH; -import static java.util.Calendar.SATURDAY; -import static java.util.Calendar.SUNDAY; -import static java.util.Calendar.YEAR; -import static org.eclipse.jface.resource.JFaceResources.DEFAULT_FONT; - -import java.util.Calendar; -import java.util.List; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Cursors; -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.GridData; -import org.eclipse.draw2d.GridLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.LineBorder; -import org.eclipse.draw2d.MouseEvent; -import org.eclipse.draw2d.MouseListener; -import org.eclipse.draw2d.MouseMotionListener; -import org.eclipse.draw2d.Viewport; -import org.eclipse.draw2d.XYLayout; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener2; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.dialogs.PopupDialog; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.viewers.MButton; -import org.xmind.ui.viewers.SWTUtils; - -/** - * A viewer to pick a date on the calendar. - * - * @author Frank Shaka - */ -public class DatePicker extends Viewer { - - public static final String[] MONTHS = new String[] { Messages.January, - Messages.Feburary, Messages.March, Messages.April, Messages.May, - Messages.June, Messages.July, Messages.August, Messages.September, - Messages.October, Messages.November, Messages.December }; - - public static final String[] WEEK_SYMBOLS = new String[] { Messages.Sunday, - Messages.Monday, Messages.Tuesday, Messages.Wednesday, - Messages.Thursday, Messages.Friday, Messages.Saturday }; - - public static final int TIME_12 = 12; - - public static final int TIME_24 = 24; - - public static final int CORNER = 8; - - public static final int LOAD_TIMEPICKER = 1 << 3; - - private static final int FUTURE_YEARS = 7; - - private static final int PASSED_YEARS = 3; - - private static final String TEXT = "#000000"; //$NON-NLS-1$ - - private static final String WEEKEND = "#EE0000"; //$NON-NLS-1$ - - private static final String SEPARATOR = "#C0C0C0"; //$NON-NLS-1$ - - private static final String TODAY = "#ff9900"; //$NON-NLS-1$ - - private static final String WEEK_SYMBOL = "#808080"; //$NON-NLS-1$ - - private static final String ARROW_BORDER = "#808080"; //$NON-NLS-1$ - - private static final String ARROW_FILL = "#C0C0C0"; //$NON-NLS-1$ - - private static final String CANCEL = "#D80000"; //$NON-NLS-1$ - - private static final String TIME = "#5D5D5D"; //$NON-NLS-1$ - - protected static final int NORMAL_ALPHA = 0xff; - - protected static final int SIBLING_MONTH_ALPHA = 0x20; - - private static final int DURATION = 200; - - protected static final int TOTAL_DAYS = 42; - - protected class EventHandler - implements MouseListener, MouseMotionListener, Listener { - - private boolean dayPressed = false; - - private BaseFigure pretarget = null; - - private FigureCanvas canvas; - - private BaseFigure target = null; - - public void attach(IFigure figure) { - figure.addMouseListener(this); - figure.addMouseMotionListener(this); - } - - public void detach(IFigure figure) { - figure.removeMouseListener(this); - figure.removeMouseMotionListener(this); - } - - public void install(Control control) { - control.addListener(SWT.MouseUp, this); - control.addListener(SWT.MouseWheel, this); - control.addListener(SWT.KeyDown, this); - } - - public void uninstall(Control control) { - control.removeListener(SWT.MouseUp, this); - control.removeListener(SWT.MouseWheel, this); - control.removeListener(SWT.KeyDown, this); - } - - public void handleEvent(Event event) { - if (event.type == SWT.MouseUp) { - dayPressed = false; - if (target != null) { - final BaseFigure eventTarget = target; - final BaseFigure eventPreTarget = pretarget; - target.setPressed(false); - target = null; - selected(eventTarget, eventPreTarget); - } - } else if (event.type == SWT.MouseWheel) { - if (event.count == 0) - return; - // wheel upwards, count > 0, month should decrease - // wheel downwards, count < 0, month should increase - rollMonth(event.count > 0 ? -1 : 1); - } else if (event.type == SWT.KeyDown) { - handleKeyPress(event.keyCode, event.stateMask); - } - } - - private void handleKeyPress(int key, int mask) { - if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_UP)) { - lastMonthSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_DOWN)) { - nextMonthSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_LEFT)) { - lastYearSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_RIGHT)) { - nextYearSelected(true); - } - } - - public void mouseDoubleClicked(MouseEvent me) { - // do nothing - BaseFigure source = (BaseFigure) me.getSource(); - if (source instanceof HourFigure - || source instanceof MinutesFigure) { - startEditing(source); - } - } - - private void startEditing(final BaseFigure source) { - canvas = getDatePicker(); - final Text editor = new Text(getDatePicker(), - SWT.SINGLE | SWT.BORDER); - editor.setFont(source.getFont()); - editor.setText(source.getText()); - //set location of editor - Rectangle bounds = source.getBounds(); - Viewport viewport = canvas.getViewport(); - int x = bounds.x - viewport.getClientArea().x; - int y = bounds.y - viewport.getClientArea().y; - - Point size = editor.computeSize(SWT.DEFAULT, SWT.DEFAULT); - editor.setBounds(x, y + (bounds.height - size.y) / 2, bounds.width, - size.y); - - canvas.layout(); - - editor.selectAll(); - editor.setFocus(); - //focus out - final Listener mouseDownFilter = new Listener() { - - public void handleEvent(Event event) { - if (event.widget != editor) { - finishEditingTime(editor, source); - } - } - }; - - editor.getDisplay().addFilter(SWT.MouseDown, mouseDownFilter); - editor.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - editor.getDisplay().removeFilter(SWT.MouseDown, - mouseDownFilter); - } - }); - - editor.addKeyListener(new KeyListener() { - - public void keyReleased(KeyEvent e) { - } - - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.CR) { - finishEditingTime(editor, source); - } - } - }); - - editor.addTraverseListener(new TraverseListener() { - - public void keyTraversed(TraverseEvent e) { - if (e.detail == SWT.TRAVERSE_ESCAPE) { - e.doit = false; - cancelEditingTime(editor); - } - } - }); - } - - private void cancelEditingTime(Text editor) { - editor.dispose(); - canvas.layout(); - } - - private void finishEditingTime(Text editor, BaseFigure source) { - String newValue = editor.getText().trim(); - String oldValue = source.getText().trim(); - if ("".equals(newValue) || null == newValue //$NON-NLS-1$ - || newValue.equals(oldValue)) { - disposeEditor(editor, source); - if (!"12".equals(newValue)) //$NON-NLS-1$ - return; - } - int value = -1; - try { - value = Integer.parseInt(newValue); - if (source instanceof HourFigure) - changeHourOrMinutes(false, value, currentMinutes); - if (source instanceof MinutesFigure) - changeHourOrMinutes(false, currentHour, value); - } catch (NumberFormatException e) { -// e.printStackTrace(); - } - disposeEditor(editor, source); - } - - private void disposeEditor(Text editor, BaseFigure source) { - updateSelection(); - source.setBorder(null); - editor.dispose(); - canvas.layout(); - } - - public void mouseDragged(MouseEvent me) { - // do nothing - } - - public void mouseEntered(MouseEvent me) { - if (target == null) { - BaseFigure source = (BaseFigure) me.getSource(); - if (source instanceof DayFigure && dayPressed) { - source.setPressed(true); - source.setPreselected(false); - } else { - if (source == monthFigure || source == lastMonth - || source == nextMonth) { - monthFigure.setPreselected(true); - lastMonth.getContent().setVisible(true); - nextMonth.getContent().setVisible(true); - } else if (source == yearFigure || source == lastYear - || source == nextYear) { - yearFigure.setPreselected(true); - lastYear.getContent().setVisible(true); - nextYear.getContent().setVisible(true); - } else if (source == todayFigure) { - todayFigure.setFont( - FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); - todayFigure.setForegroundColor( - ColorUtils.getColor(CANCEL)); - return; - } - source.setPreselected(true); - } - } - } - - public void mouseExited(MouseEvent me) { - if (target == null) { - BaseFigure source = (BaseFigure) me.getSource(); - if (source instanceof DayFigure) { - source.setPreselected(false); - if (dayPressed) { - source.setPressed(false); - } - } else { - if (source == monthFigure || source == lastMonth - || source == nextMonth) { - monthFigure.setPreselected(false); - lastMonth.getContent().setVisible(false); - nextMonth.getContent().setVisible(false); - } else if (source == yearFigure || source == lastYear - || source == nextYear) { - yearFigure.setPreselected(false); - lastYear.getContent().setVisible(false); - nextYear.getContent().setVisible(false); - } else if (source == todayFigure) { - todayFigure.setFont( - FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); - todayFigure - .setForegroundColor(ColorUtils.getColor(TEXT)); - return; - } - source.setPreselected(false); - } - } - } - - public void mouseHover(MouseEvent me) { - // do nothing - } - - public void mouseMoved(MouseEvent me) { - // do nothing - } - - public void mousePressed(MouseEvent me) { - BaseFigure source = (BaseFigure) me.getSource(); - if (source != todayFigure) { - source.setPressed(true); - source.setPreselected(false); - } - if (source instanceof DayFigure) { - dayPressed = true; - } else { - target = source; - } - if (source instanceof HourFigure - || source instanceof MinutesFigure) { - startEditing(source); - } - } - - public void mouseReleased(MouseEvent me) { - BaseFigure source = (BaseFigure) me.getSource(); - source.setPressed(false); - if (source instanceof DayFigure) { - if (dayPressed) { - daySelected((DayFigure) me.getSource()); - } - source.setPreselected(true); - } else if (source instanceof HourFigure - || source instanceof MinutesFigure) { - pretarget = source; - } else { - if (!source.isSelected()) { - if (source != todayFigure) - source.setPreselected(true); - } - } - } - } - - private class DropdownDatePicker extends PopupDialog { - public DropdownDatePicker(Shell parent) { - super(parent, SWT.NO_TRIM, true, false, false, false, false, null, - null); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - createDatePicker(composite); - datePicker.setLayoutData(new org.eclipse.swt.layout.GridData( - SWT.FILL, SWT.FILL, true, true)); - initDatePicker(); - update(); - return composite; - } - - @Override - public int open() { - isPopupEditing = true; - return super.open(); - } - - @Override - public boolean close() { - isPopupEditing = false; - boolean closed = super.close(); - if (closed) { - datePicker = null; - } - return closed; - } - - @Override - protected Point getInitialLocation(Point initialSize) { - Control c = DatePicker.this.getControl(); - org.eclipse.swt.graphics.Rectangle r = c.getBounds(); - return c.toDisplay(0, r.height + 1); - } - - } - - private class MonthAction extends Action { - - private int month; - - public MonthAction(int month) { - super(MONTHS[month]); - this.month = month; - } - - public void run() { - monthSelected(month); - } - } - - private class YearAction extends Action { - - private int year; - - public void setYear(int year) { - this.year = year; - setText("" + year); //$NON-NLS-1$ - } - - public int getYear() { - return year; - } - - public void run() { - yearSelected(year); - } - } - - private class AnimationAdvisor implements IAnimationAdvisor { - - private int monthsToRoll = 0; - - private int yearsToRoll = 0; - - private int duration = -1; - - private int oldYear; - - private int oldMonth; - - private int newYear; - - private int newMonth; - - public void addMonthsToRoll(int count) { - monthsToRoll += count; - duration = -1; - } - - public void addYearsToRoll(int count) { - yearsToRoll += count; - duration = -1; - } - - public int getDuration() { - if (duration < 0) { - int steps = Math.abs(monthsToRoll) + Math.abs(yearsToRoll); - duration = steps == 0 ? 0 : DURATION / steps; - } - return duration; - } - - public IFigure getLayer() { - return DatePicker.this.dateLayer; - } - - public int getMonthsToRoll() { - return monthsToRoll; - } - - public int getNewMonth() { - return newMonth; - } - - public int getNewYear() { - return newYear; - } - - public int getOldMonth() { - return oldMonth; - } - - public int getOldYear() { - return oldYear; - } - - public IFigure getPanel() { - return DatePicker.this.datePanel; - } - - public int getYearsToRoll() { - return yearsToRoll; - } - - public void initNewDay(DayFigure figure) { - updateDayFigure(figure, oldYear, oldMonth); - } - - public void initOldDay(DayFigure figure) { - figure.setPreselected(false); - figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); - eventHandler.detach(figure); - } - - public boolean isDone() { - return monthsToRoll == 0 && yearsToRoll == 0; - } - - public void setEndMonth(int newYear, int newMonth) { - this.newYear = newYear; - this.newMonth = newMonth; - } - - public void setStartMonth(int oldYear, int oldMonth) { - this.oldYear = oldYear; - this.oldMonth = oldMonth; - } - - public void updateNewDay(DayFigure figure) { - figure.setPreselected(false); - figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); - eventHandler.attach(figure); - updateDayFigure(figure, newYear, newMonth); - } - - } - - private int style; //mark the style of datepicker - - private int type = TIME_12; // TIME_12 or TIME_24 mark the type of time 12 Hour or 24 Hour. - - private Control control; - - private FigureCanvas datePicker; - - private BaseFigure timePicker; - - private HourFigure hourFigure; - - private MinutesFigure minutesFigure; - -// private BaseFigure okButton; -// -// private BaseFigure cancelButton; - -// private BaseFigure figure; - - private BaseFigure timeLabel; - - private ArrowFigure beforeTime; - - private ArrowFigure afterTime; - - private MButton placeholder; - - private ILabelProvider dateLabelProvider; - - private DropdownDatePicker dropdownDatePicker; - - private Calendar today; - - private int currentMonth; - - private int currentYear; - - private int currentHour; - - private int currentMinutes; - - private Calendar selection; - - private IFigure dateLayer; - - private IFigure datePanel; - - private MonthFigure monthFigure; - - private YearFigure yearFigure; - - private BaseFigure todayFigure; - - private BaseFigure cancelFigure; - - private EventHandler eventHandler; - - private MenuManager monthMenu; - - private MonthAction[] monthActions; - - private MenuManager yearMenu; - - private YearAction[] yearActions; - - private ArrowFigure lastYear; - - private ArrowFigure nextYear; - - private ArrowFigure lastMonth; - - private ArrowFigure nextMonth; - - private boolean firingSelectionChange = false; - - private boolean animating = false; - - private IAnimationAdvisor animationAdvisor = new AnimationAdvisor(); - - private boolean isPopupEditing = false; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a composite control which will be the parent of the new - * instance (cannot be null) - * @param style - * the style of control to construct - * @see SWT#SIMPLE - * @see SWT#DROP_DOWN - * @see SWT#CANCEL - */ - public DatePicker(Composite parent, int style) { - this(parent, style, Calendar.getInstance()); - } - - public DatePicker(Composite parent, int style, Calendar today) { - this.today = today; - this.currentMonth = today.get(MONTH); - this.currentYear = today.get(YEAR); - this.currentHour = today.get(HOUR_OF_DAY); - this.currentMinutes = today.get(MINUTE); - this.style = style; - if ((style & SWT.DROP_DOWN) != 0) { - createPlaceholder(parent); - this.control = placeholder.getControl(); - initPlaceholder(); - } else { - createDatePicker(parent); - this.control = datePicker; - initDatePicker(); - } - update(); - } - - private void createPlaceholder(Composite parent) { - this.placeholder = new MButton(parent, MButton.NORMAL); - } - - private void createDatePicker(Composite parent) { - this.datePicker = new FigureCanvas(parent); - } - - public void setLabelProvider(ILabelProvider labelProvider) { - this.dateLabelProvider = labelProvider; - update(); - } - - public ILabelProvider getLabelProvider() { - if (this.dateLabelProvider == null) { - this.dateLabelProvider = new DateLabelProvider(); - } - return this.dateLabelProvider; - } - - public Control getControl() { - return control; - } - - public FigureCanvas getDatePicker() { - return datePicker; - } - - public boolean isPopupEditing() { - return isPopupEditing; - } - - public void setBackground(Color color) { - if (control != null && !control.isDisposed()) { - control.setBackground(color); - } - } - - public void setEnabled(boolean enabled) { - if (placeholder != null) { - placeholder.setEnabled(enabled); - } - } - - public MButton getPlaceholder() { - return placeholder; - } - - public ISelection getSelection() { - return new DateSelection(selection); - } - - @Override - public void setSelection(ISelection selection) { - setSelection(selection, true); - } - - @Override - public void setSelection(ISelection selection, boolean reveal) { - if (selection instanceof DateSelection) { - setDateSelection(((DateSelection) selection).getDate(), reveal); - } else if (selection instanceof IStructuredSelection) { - Object sel = ((IStructuredSelection) selection).getFirstElement(); - if (sel instanceof Calendar) { - setDateSelection((Calendar) sel, reveal); - } - } - } - - public void setDateSelection(Calendar date, boolean reveal) { - changeDate(date); - if (reveal && date != null) { - changeCalendar(date.get(YEAR), date.get(MONTH), - date.get(HOUR_OF_DAY), date.get(MINUTE)); - } - update(); - } - - private void initPlaceholder() { - placeholder.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - if (dropdownDatePicker == null - || dropdownDatePicker.getShell() == null - || dropdownDatePicker.getShell().isDisposed() - || !dropdownDatePicker.isClosing()) - showDropdown(); - } - }); - } - - /** - * Shows the drop-down date picker ,and compute the size by the control. - */ - private void showDropdown() { - placeholder.setForceFocus(true); - createDropdownDatePicker(); - dropdownDatePicker.open(); - Shell shell = dropdownDatePicker.getShell(); - int x = placeholder.getControl().getBounds().width; - x = x < 230 ? 230 : x; //set the datepicker min width is 250px - x = x > 250 ? 250 : x; //set the datepicker max width is 280px - shell.setSize(x, x + 30); - if (shell != null && !shell.isDisposed()) { - shell.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - if (placeholder != null - && !placeholder.getControl().isDisposed()) { - placeholder.setForceFocus(false); - updateSelection(); - closeDatePicker(); - } - } - - }); - } else { - placeholder.setForceFocus(false); - } - } - - private void closeDatePicker() { - if (firingSelectionChange) - return; - firingSelectionChange = true; - if (dropdownDatePicker != null) { - control.getDisplay().asyncExec(new Runnable() { - public void run() { - dropdownDatePicker.close(); - } - }); - } - fireSelectionChanged( - new SelectionChangedEvent(DatePicker.this, getSelection())); - firingSelectionChange = false; - } - - /** - * Shows the drop-down menu if this date picker is created with - * SWT.DROP_DOWN style bit. - */ - public void open() { - showDropdown(); - } - - public void close() { - if (dropdownDatePicker != null) { - control.getDisplay().asyncExec(new Runnable() { - public void run() { - dropdownDatePicker.close(); - } - }); - } - } - - private void createDropdownDatePicker() { - if (dropdownDatePicker != null) - return; - dropdownDatePicker = new DropdownDatePicker(control.getShell()); - } - - private void initDatePicker() { - datePicker.setScrollBarVisibility(FigureCanvas.NEVER); -// if (Util.isWindows()) { - //datePicker.setBackground(datePicker.getParent().getBackground()); -// } else { -// datePicker.getLightweightSystem().getRootFigure().setOpaque(false); -// } - - eventHandler = new EventHandler(); - eventHandler.install(datePicker); - datePicker.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - eventHandler.uninstall(datePicker); - } - }); - - Viewport viewport = new Viewport(true); - viewport.setContentsTracksHeight(true); - viewport.setContentsTracksWidth(true); - datePicker.setViewport(viewport); - - IFigure container = new Layer(); - datePicker.setContents(container); - - GridLayout containerLayout = new GridLayout(1, true); - containerLayout.horizontalSpacing = 3; - containerLayout.verticalSpacing = 3; - containerLayout.marginHeight = 3; - containerLayout.marginWidth = 3; - container.setLayoutManager(containerLayout); - createTopPanel(container); - createSeparator(container); - createWeekPanel(container); - createDaysPanel(container); - createSeparator(container); - createBottomPanel(container); -// createSeparator(container); -// createOkAndCancel(container); - - } - - private void createTopPanel(IFigure parent) { - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - - GridLayout panelLayout = new GridLayout(12, true); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 0; - panelLayout.marginWidth = 0; - panel.setLayoutManager(panelLayout); - - lastMonth = createArrowFigure(panel, ArrowFigure.UP); - monthFigure = createMonthFigure(panel); - nextMonth = createArrowFigure(panel, ArrowFigure.DOWN); - lastYear = createArrowFigure(panel, ArrowFigure.LEFT); - yearFigure = createYearFigure(panel); - nextYear = createArrowFigure(panel, ArrowFigure.RIGHT); - } - - private MonthFigure createMonthFigure(IFigure parent) { - MonthFigure figure = new MonthFigure(); - figure.setTextCandidates(MONTHS); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - constraint.horizontalSpan = 5; - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - private YearFigure createYearFigure(IFigure parent) { - YearFigure figure = new YearFigure(); - figure.setTextCandidates(new String[] { "0000" }); //$NON-NLS-1$ - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - constraint.horizontalSpan = 3; - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - @SuppressWarnings("deprecation") - private ArrowFigure createArrowFigure(IFigure parent, int orientation) { - ArrowFigure arrow = new ArrowFigure(); - arrow.setOrientation(orientation); - arrow.setForegroundColor(ColorUtils.getColor(ARROW_BORDER)); - arrow.setBackgroundColor(ColorUtils.getColor(ARROW_FILL)); - arrow.getContent().setVisible(false); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.add(arrow, constraint); - eventHandler.attach(arrow); - return arrow; - } - - @SuppressWarnings("deprecation") - private void createSeparator(IFigure parent) { - HorizontalLine line = new HorizontalLine(); - line.setMargin(3); - line.setForegroundColor(ColorUtils.getColor(SEPARATOR)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); - constraint.heightHint = 3; - parent.add(line, constraint); - } - - @SuppressWarnings("deprecation") - private void createWeekPanel(IFigure parent) { - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - GridLayout panelLayout = new GridLayout(7, true); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 0; - panelLayout.marginWidth = 0; - panel.setLayoutManager(panelLayout); - @SuppressWarnings("deprecation") - Font symbolFont = FontUtils.getRelativeHeight(DEFAULT_FONT, -2); - for (int i = 0; i < 7; i++) { - TextLayer symbol = new TextLayer(); - symbol.setFont(symbolFont); - symbol.setText(WEEK_SYMBOLS[i]); - if (i == 0 || i == 6) { - symbol.setForegroundColor(ColorUtils.getColor(WEEKEND)); - } else { - symbol.setForegroundColor(ColorUtils.getColor(WEEK_SYMBOL)); - } - GridData symbolConstraint = new GridData(SWT.FILL, SWT.FILL, true, - true); - panel.add(symbol, symbolConstraint); - } - } - - private void createDaysPanel(IFigure parent) { - dateLayer = new Layer(); - GridData layerConstraint = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.add(dateLayer, layerConstraint); - dateLayer.setLayoutManager(new ConstraintStackLayout()); - - datePanel = new Layer(); - dateLayer.add(datePanel, null); - datePanel.setLayoutManager(new DatePanelLayout()); - for (int i = 0; i < TOTAL_DAYS; i++) { - DayFigure dayFigure = new DayFigure(); - eventHandler.attach(dayFigure); - datePanel.add(dayFigure); - } - } - - private void createBottomPanel(IFigure parent) { - boolean hasCancel = (style & SWT.CANCEL) != 0; - boolean hasTimePicker = (style & LOAD_TIMEPICKER) != 0; - - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - - int cols = 0; - cols = hasCancel ? 2 : 1; - cols = hasTimePicker ? cols + 2 : cols; - - GridLayout panelLayout = new GridLayout(cols, false); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 10; - panelLayout.marginWidth = 5; - - panel.setLayoutManager(panelLayout); - - todayFigure = createTodayFigure(panel); - - if (hasTimePicker) { - timePicker = createTimeFigure(panel); -// createUpAndDown(panel); - timeLabel = createLabelOfTime(panel); - } - if (hasCancel) { - cancelFigure = createCancelFigure(panel); - } - } - - @SuppressWarnings("deprecation") - private BaseFigure createTodayFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); - figure.setForegroundColor(ColorUtils.getColor(TEXT)); - GridData constraint = new GridData(SWT.CENTER, SWT.CENTER, true, true); - parent.add(figure, constraint); - - eventHandler.attach(figure); - return figure; - } - - @SuppressWarnings("deprecation") - private BaseFigure createCancelFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setText(" X "); //$NON-NLS-1$ - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); - figure.setForegroundColor(ColorUtils.getColor(CANCEL)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - @SuppressWarnings("deprecation") - private BaseFigure createTimeFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -1)); - figure.setForegroundColor(ColorConstants.white); - figure.setBackgroundColor(ColorConstants.white); - figure.setOpaque(true); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, false); - figure.setLayoutManager(new XYLayout()); - parent.add(figure, constraint); - - IFigure panel = new Layer(); - figure.add(panel, new Rectangle(0, 2, 60, 20)); - panel.setBorder(new LineBorder(ColorConstants.lightGray, 1)); - panel.setForegroundColor(ColorConstants.white); - XYLayout layout = new XYLayout(); - - panel.setLayoutManager(layout); - hourFigure = createHourFigure(panel); - BaseFigure point = createPointFigure(panel); - minutesFigure = createMinutesFigure(panel); - panel.add(hourFigure, new Rectangle(0, 0, 25, 18)); - panel.add(point, new Rectangle(26, 0, 3, 18)); - panel.add(minutesFigure, new Rectangle(31, 0, 25, 18)); - return figure; - } - - @SuppressWarnings("deprecation") - private BaseFigure createPointFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setSize(3, 18); - figure.setText(" : "); //$NON-NLS-1$ - figure.setForegroundColor(ColorUtils.getColor(TIME)); - parent.add(figure); - return figure; - } - -// private IFigure createHourAndMinutesPanel(IFigure parent) { -// IFigure panel = new Layer(); -// panel.setSize(32, 16); -// GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); -// constraint.horizontalSpan = 3; -// parent.add(panel, constraint); -// ToolbarLayout layout = new ToolbarLayout(); -// layout.setSpacing(0); -// panel.setLayoutManager(layout); -// return panel; -// } - - @SuppressWarnings("deprecation") - private HourFigure createHourFigure(IFigure parent) { - HourFigure figure = new HourFigure(); - figure.setHour(currentHour, type); - figure.setTextCandidates(new String[] { " 00 " }); //$NON-NLS-1$ - figure.setForegroundColor(ColorUtils.getColor(TIME)); - eventHandler.attach(figure); - return figure; - } - - @SuppressWarnings("deprecation") - private MinutesFigure createMinutesFigure(IFigure parent) { - MinutesFigure figure = new MinutesFigure(); - figure.setMinutes(currentMinutes); - figure.setTextCandidates(new String[] { " 00 " }); //$NON-NLS-1$ - figure.setForegroundColor(ColorUtils.getColor(TIME)); - eventHandler.attach(figure); - return figure; - } - - @SuppressWarnings("deprecation") - private BaseFigure createLabelOfTime(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setText(getTimeLabel()); - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -1)); - figure.setForegroundColor(ColorUtils.getColor(TEXT)); - figure.setCursor(Cursors.ARROW); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); - parent.add(figure, constraint); - return figure; - } - -// private void createOkAndCancel(IFigure parent) { -// IFigure panel = new Layer(); -// GridData panelConstraint = new GridData(SWT.CENTER, SWT.FILL, true, -// false); -// parent.add(panel, panelConstraint); -// GridLayout panelLayout = new GridLayout(4, true); -// panelLayout.horizontalSpacing = 10; -// panelLayout.verticalSpacing = 0; -// panelLayout.marginHeight = 5; -// panelLayout.marginWidth = 5; -// panelLayout.verticalSpacing = 5; -// panel.setLayoutManager(panelLayout); -// cancelButton = createCancel(panel); -// createLabel(panel); -// createLabel(panel); -// okButton = createOk(panel); -// } - -// private void createLabel(IFigure parent) { -// BaseFigure figure = new BaseFigure(); -// GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); -// parent.add(figure, data); -// } -// -// private BaseFigure createOk(IFigure parent) { -// BaseFigure figure = new BaseFigure(); -// figure.setText("OK"); -// figure.setOpaque(true); -// figure.setBackgroundColor(ColorConstants.white); -// figure.setBorder(new LineBorder(ColorConstants.lightGray)); -// figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); -// parent.add(figure, new GridData(SWT.FILL, SWT.FILL, false, false)); -// eventHandler.attach(figure); -// return figure; -// } - -// private BaseFigure createCancel(IFigure parent) { -// BaseFigure figure = new BaseFigure(); -// figure.setText("CANCEL"); -// figure.setBackgroundColor(ColorConstants.white); -// figure.setOpaque(true); -// figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); -// figure.setBorder(new LineBorder(ColorConstants.lightGray)); -// parent.add(figure, new GridData(SWT.FILL, SWT.FILL, false, false)); -// eventHandler.attach(figure); -// return figure; -// } - - private String getTimeLabel() { - if (currentHour >= 0 && currentHour < 12) - return Messages.DatePicker_Time_AM_text; - else if (currentHour >= 12 && currentHour < 24) - return Messages.DatePicker_Time_PM_text; - return ""; //$NON-NLS-1$ - } - - private Calendar getSelectedDate() { - return selection; - } - - private static boolean isSameDay(Calendar date1, Calendar date2) { - if (date1 == null) - return date2 == null; - if (date2 == null) - return false; - return date1.get(DATE) == date2.get(DATE) - && date1.get(MONTH) == date2.get(MONTH) - && date1.get(YEAR) == date2.get(YEAR); - } - - protected void changeCalendar(int newYear, int newMonth, int newHour, - int newMinutes) { - changeCalendar(newYear, newMonth, newHour, newMinutes, false); - } - - //change the ui of canlendar - protected void changeCalendar(int newYear, int newMonth, int hours, - int minutes, boolean smooth) { - boolean calendarChanged = newMonth != currentMonth - || newYear != currentYear || currentHour != hours - || currentMinutes != minutes; - if (!calendarChanged) - return; - if (smooth) { - if (datePicker != null) { - int months = (newYear - currentYear) * 12 + newMonth - - currentMonth; - animationAdvisor.addYearsToRoll(months / 12); - animationAdvisor.addMonthsToRoll(months % 12); - performRollCalendarAnimation(currentYear, currentMonth); - } - currentYear = newYear; - currentMonth = newMonth; - currentHour = hours; - currentMinutes = minutes; - } else { - currentYear = newYear; - currentMonth = newMonth; - currentHour = hours; - currentMinutes = minutes; - if (datePicker != null) { - updateCalendar(); - } - updateSelection(); - } - } - - private void updateCalendar() { - today = Calendar.getInstance(); - updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); - monthFigure.setMonth(currentMonth); - yearFigure.setYear(currentYear); - hourFigure.setHour(currentHour, type); - minutesFigure.setMinutes(currentMinutes); -// todayFigure.setText(NLS.bind(Messages.TodayPattern, -// String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ - todayFigure.setText(Messages.TodayPattern); - } - - private void updateDayFigures(List dayFigures, int year, int month) { - Calendar date = getCalendarStart(today, year, month); - for (int i = 0; i < dayFigures.size(); i++) { - DayFigure dayFigure = (DayFigure) dayFigures.get(i); - date = (Calendar) date.clone(); - if (i > 0) - date.add(DATE, 1); - dayFigure.setDate(date); - updateDayFigure(dayFigure, year, month); - } - - } - - @SuppressWarnings("deprecation") - void updateDayFigure(DayFigure figure, int year, int month) { - figure.setFont(FontUtils.getBold(DEFAULT_FONT)); - Calendar date = figure.getDate(); - if (isSameDay(date, today)) { - figure.setForegroundColor(ColorUtils.getColor(TODAY)); - } else if (isWeekend(date)) { - figure.setForegroundColor(ColorUtils.getColor(WEEKEND)); - } else { - figure.setForegroundColor(ColorUtils.getColor(TEXT)); - } - if (date.get(MONTH) == month && date.get(YEAR) == year) { - figure.setTextAlpha(NORMAL_ALPHA); - } else { - figure.setTextAlpha(SIBLING_MONTH_ALPHA); - } - } - - private void updateSelection() { - if (datePicker != null) { - for (Object figure : datePanel.getChildren()) { - DayFigure dayFigure = (DayFigure) figure; - dayFigure.setSelected( - isSameDay(dayFigure.getDate(), getSelectedDate())); - } - } -// if (null != hourFigure && null != selection) -// selection.set(HOUR_OF_DAY, hourFigure.getHour()); -// if (null != minutesFigure && null != selection) -// selection.set(MINUTE, minutesFigure.getMinutes()); - if (placeholder != null) { - String text = getLabelProvider().getText(selection); - placeholder.setText(text); - } - } - - protected void update() { - if (datePicker != null) { - updateCalendar(); - } - updateSelection(); - } - - private void performRollCalendarAnimation(int oldYear, int oldMonth) { - if (animating) - return; - - animating = true; - - final int newYear, newMonth; - final CalendarAnimation animation; - if (animationAdvisor.getYearsToRoll() != 0) { - if (animationAdvisor.getYearsToRoll() < 0) { - newYear = oldYear - 1; - newMonth = oldMonth; - animation = new LastYearAnimation(animationAdvisor); - } else { - newYear = oldYear + 1; - newMonth = oldMonth; - animation = new NextYearAnimation(animationAdvisor); - } - } else if (animationAdvisor.getMonthsToRoll() != 0) { - if (animationAdvisor.getMonthsToRoll() < 0) { - newYear = oldMonth <= 0 ? oldYear - 1 : oldYear; - newMonth = oldMonth <= 0 ? 11 : oldMonth - 1; - animation = new LastMonthAnimation(animationAdvisor); - } else { - newYear = oldMonth >= 11 ? oldYear + 1 : oldYear; - newMonth = oldMonth >= 11 ? 0 : oldMonth + 1; - animation = new NextMonthAnimation(animationAdvisor); - } - } else { - newYear = oldYear; - newMonth = oldMonth; - animation = null; - } - monthFigure.setMonth(newMonth); - yearFigure.setYear(newYear); - if (animation != null) { - animationAdvisor.setStartMonth(oldYear, oldMonth); - animationAdvisor.setEndMonth(newYear, newMonth); - animation.callback(new Runnable() { - public void run() { - datePanel = animation.getNewPanel(); - if (animationAdvisor.isDone()) { - animating = false; - } else { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - animating = false; - performRollCalendarAnimation(newYear, newMonth); - } - }); - } - - } - }).start(); - } - } - - static int calc(int start, int end, int current, int total) { - return start + (end - start) * current / total; - } - - protected void selected(final BaseFigure target, - final BaseFigure pretarget) { - if (target instanceof MonthFigure) { - target.setSelected(true); - showMonthPopup(); - } else if (target instanceof YearFigure) { - target.setSelected(true); - showYearPopup(); - } else if (target == todayFigure) { - todaySelected(); - } else if (target == lastMonth) { - lastMonthSelected(true); - } else if (target == nextMonth) { - nextMonthSelected(true); - } else if (target == lastYear) { - lastYearSelected(true); - } else if (target == nextYear) { - nextYearSelected(true); - } else if (target == cancelFigure) { - cancelSelected(); - } else if (target == beforeTime) { -// beforeTimeSelected(true, pretarget); - } else if (target == afterTime) { -// afterTimeSelected(true, pretarget); - } else if (target instanceof HourFigure) { - if (null != minutesFigure) - minutesFigure.setSelected(false); - hourSelected((HourFigure) target); - } else if (target instanceof MinutesFigure) { - if (null != hourFigure) - hourFigure.setSelected(false); - minuteSelected((MinutesFigure) target); - } - } - - protected void showMonthPopup() { - createMonthMenu(); - for (int month = 0; month < monthActions.length; month++) { - MonthAction action = monthActions[month]; - action.setChecked(month == currentMonth); - } - Rectangle b = monthFigure.getBounds(); - Point loc = control.toDisplay(b.x, b.y + b.height); - final Menu menu = monthMenu.createContextMenu(control); - menu.setLocation(loc.x + 10, loc.y + 1); - menu.setVisible(true); - } - - protected void createMonthMenu() { - if (monthMenu != null) - return; - monthMenu = new MenuManager(); - monthMenu.addMenuListener(new IMenuListener2() { - public void menuAboutToShow(IMenuManager manager) { - // do nothing - } - - public void menuAboutToHide(IMenuManager manager) { - monthFigure.setSelected(false); - } - }); - monthActions = new MonthAction[12]; - for (int month = 0; month < 12; month++) { - MonthAction action = new MonthAction(month); - monthMenu.add(action); - monthActions[month] = action; - } - } - - protected void showYearPopup() { - createYearMenu(); - int start = currentYear - PASSED_YEARS; - for (int year = 0; year < yearActions.length; year++) { - YearAction action = yearActions[year]; - action.setYear(start + year); - action.setChecked(action.getYear() == currentYear); - } - Rectangle b = yearFigure.getBounds(); - Point loc = control.toDisplay(b.x, b.y + b.height); - Menu menu = yearMenu.createContextMenu(control); - menu.setLocation(loc.x, loc.y + 1); - menu.setVisible(true); - } - - protected void createYearMenu() { - if (yearMenu != null) - return; - yearMenu = new MenuManager(); - yearMenu.addMenuListener(new IMenuListener2() { - public void menuAboutToShow(IMenuManager manager) { - // do nothing - } - - public void menuAboutToHide(IMenuManager manager) { - yearFigure.setSelected(false); - } - }); - yearActions = new YearAction[FUTURE_YEARS + PASSED_YEARS + 1]; - for (int year = 0; year < yearActions.length; year++) { - YearAction action = new YearAction(); - yearMenu.add(action); - yearActions[year] = action; - } - } - - protected void monthSelected(int month) { - changeCalendar(currentYear, month, currentHour, currentMinutes); - } - - protected void yearSelected(int year) { - changeCalendar(year, currentMonth, currentHour, currentMinutes); - } - - protected void daySelected(DayFigure day) { - Calendar date = day.getDate(); - if (date != null && date.get(MONTH) != currentMonth) { - changeCalendar(date.get(YEAR), date.get(MONTH), - date.get(HOUR_OF_DAY), date.get(MINUTE), true); - } - if (null != date && date.get(HOUR_OF_DAY) != currentHour) { - changeHourOrMinutes(true, date.get(HOUR_OF_DAY), date.get(MINUTE)); - } - selection = date; - changeDate(date); - } - - protected void hourSelected(HourFigure hour) { - hour.setSelected(true); - } - - protected void minuteSelected(MinutesFigure minute) { - minute.setSelected(true); - } - - protected void todaySelected() { - changeDate(today); - changeCalendar(today.get(YEAR), today.get(MONTH), - today.get(HOUR_OF_DAY), today.get(MINUTE)); - } - - protected void lastMonthSelected(boolean smooth) { - if (currentMonth <= 0) { - changeCalendar(currentYear - 1, 11, currentHour, currentMinutes, - smooth); - } else { - changeCalendar(currentYear, currentMonth - 1, currentHour, - currentMinutes, smooth); - } - } - - protected void nextMonthSelected(boolean smooth) { - if (currentMonth >= 11) { - changeCalendar(currentYear + 1, 0, currentHour, currentMinutes, - smooth); - } else { - changeCalendar(currentYear, currentMonth + 1, currentHour, - currentMinutes, smooth); - } - } - - protected void lastYearSelected(boolean smooth) { - changeCalendar(currentYear - 1, currentMonth, currentHour, - currentMinutes, smooth); - } - - protected void nextYearSelected(boolean smooth) { - changeCalendar(currentYear + 1, currentMonth, currentHour, - currentMinutes, smooth); - } - - protected void cancelSelected() { - changeDate(null); - } - -// protected void beforeTimeSelected(boolean smooth, BaseFigure target) { -// if (target instanceof HourFigure) { -// changeHourOrMinutes(smooth, currentHour - 1, currentMinutes); -// } else if (target instanceof MinutesFigure) -// changeHourOrMinutes(smooth, currentHour, currentMinutes - 1); -// } -// -// protected void afterTimeSelected(boolean smooth, BaseFigure target) { -// if (target instanceof HourFigure) -// changeHourOrMinutes(smooth, currentHour + 1, currentMinutes); -// else if (target instanceof MinutesFigure) -// changeHourOrMinutes(smooth, currentHour, currentMinutes + 1); -// } - - protected void changeHourOrMinutes(boolean smooth, int newHour, - int newMinutes) { - - freshTimePicker(newHour, newMinutes); - - if (selection != null) { - selection.set(HOUR_OF_DAY, newHour); - selection.set(MINUTE, newMinutes); - changeDate(selection); - } - - update(); - } - - private void freshTimePicker(int newHour, int newMinutes) { - boolean hourChanged = newHour != currentHour; - boolean minuteChanged = newMinutes != currentMinutes; - if (!hourChanged && !minuteChanged) - return; - - newHour = resetHour(newHour); - newMinutes = resetMinutes(newMinutes); - if (null != timePicker) { - if (null != hourFigure && hourChanged) { - if (!validateHour(newHour)) - return; - if (newHour >= 12) - timeLabel.setText(Messages.DatePicker_Time_AM_text); - else if (newHour < 12) - timeLabel.setText(Messages.DatePicker_Time_PM_text); - currentHour = newHour; - hourFigure.setHour(newHour, type); //default type = 12 hours every day. - } - if (null != minutesFigure && minuteChanged) { - if (!validateMinutes(newMinutes)) - return; - currentMinutes = newMinutes; - minutesFigure.setMinutes(newMinutes); - } - } - } - - private int resetHour(int hour) { - if (hour > 23) { - return 0; - } - if (hour < 0 && type == TIME_24) { - hour = 23; - } else if (hour < 0 && type == TIME_12) { - hour = 11; - } - return hour; - } - - private int resetMinutes(int minutes) { - if (minutes > 59) { - minutes = 0; - } else if (minutes < 0) { - minutes = 59; - } - return minutes; - } - - private boolean validateHour(int hour) { - if (hour >= 0 && hour <= 23) - return true; - return false; - } - - private boolean validateMinutes(int minutes) { - if (minutes >= 0 && minutes < 60) - return true; - return false; - } - - protected void rollMonth(int count) { - Calendar temp = (Calendar) today.clone(); - temp.set(YEAR, currentYear); - temp.set(MONTH, currentMonth); - temp.add(MONTH, count); - changeCalendar(temp.get(YEAR), temp.get(MONTH), temp.get(HOUR_OF_DAY), - temp.get(MINUTE), true); - } - - //send the selectionChanged event ,inform all listeners. - protected void changeDate(Calendar date) { - this.selection = date; - updateSelection(); - if (firingSelectionChange) - return; - - firingSelectionChange = true; - fireSelectionChanged( - new SelectionChangedEvent(DatePicker.this, getSelection())); - firingSelectionChange = false; - } - - @Override - public Object getInput() { - return today; - } - - @Override - public void refresh() { - update(); - } - - @Override - public void setInput(Object input) { - if (input instanceof Calendar) { - Calendar oldInput = this.today; - this.today = (Calendar) input; - inputChanged(input, oldInput); - } - } - - @Override - protected void inputChanged(Object input, Object oldInput) { - update(); - } - - private static boolean isWeekend(Calendar date) { - int dow = date.get(DAY_OF_WEEK); - return dow == SUNDAY || dow == SATURDAY; - } - - static Calendar getCalendarStart(Calendar date, int year, int month) { - date = (Calendar) date.clone(); - date.set(year, month, 1); - while (date.get(DAY_OF_WEEK) != SUNDAY) { - date.add(DATE, -1); - } - return date; - } -} +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.DAY_OF_WEEK; +import static java.util.Calendar.HOUR_OF_DAY; +import static java.util.Calendar.MINUTE; +import static java.util.Calendar.MONTH; +import static java.util.Calendar.SATURDAY; +import static java.util.Calendar.SUNDAY; +import static java.util.Calendar.YEAR; +import static org.eclipse.jface.resource.JFaceResources.DEFAULT_FONT; + +import java.util.Calendar; +import java.util.List; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Cursors; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.GridData; +import org.eclipse.draw2d.GridLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.LineBorder; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.MouseListener; +import org.eclipse.draw2d.MouseMotionListener; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.XYLayout; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener2; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.dialogs.PopupDialog; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.viewers.MButton; +import org.xmind.ui.viewers.SWTUtils; + +/** + * A viewer to pick a date on the calendar. + * + * @author Frank Shaka + */ +public class DatePicker extends Viewer { + + public static final String[] MONTHS = new String[] { Messages.January, + Messages.Feburary, Messages.March, Messages.April, Messages.May, + Messages.June, Messages.July, Messages.August, Messages.September, + Messages.October, Messages.November, Messages.December }; + + public static final String[] WEEK_SYMBOLS = new String[] { Messages.Sunday, + Messages.Monday, Messages.Tuesday, Messages.Wednesday, + Messages.Thursday, Messages.Friday, Messages.Saturday }; + + public static final int TIME_12 = 12; + + public static final int TIME_24 = 24; + + public static final int CORNER = 8; + + public static final int LOAD_TIMEPICKER = 1 << 3; + + private static final int FUTURE_YEARS = 7; + + private static final int PASSED_YEARS = 3; + + private static final String TEXT = "#000000"; //$NON-NLS-1$ + + private static final String WEEKEND = "#EE0000"; //$NON-NLS-1$ + + private static final String SEPARATOR = "#C0C0C0"; //$NON-NLS-1$ + + private static final String TODAY = "#ff9900"; //$NON-NLS-1$ + + private static final String WEEK_SYMBOL = "#808080"; //$NON-NLS-1$ + + private static final String ARROW_BORDER = "#808080"; //$NON-NLS-1$ + + private static final String ARROW_FILL = "#C0C0C0"; //$NON-NLS-1$ + + private static final String CANCEL = "#D80000"; //$NON-NLS-1$ + + private static final String TIME = "#5D5D5D"; //$NON-NLS-1$ + + protected static final int NORMAL_ALPHA = 0xff; + + protected static final int SIBLING_MONTH_ALPHA = 0x20; + + private static final int DURATION = 200; + + protected static final int TOTAL_DAYS = 42; + + protected class EventHandler + implements MouseListener, MouseMotionListener, Listener { + + private boolean dayPressed = false; + + private BaseFigure pretarget = null; + + private FigureCanvas canvas; + + private BaseFigure target = null; + + public void attach(IFigure figure) { + figure.addMouseListener(this); + figure.addMouseMotionListener(this); + } + + public void detach(IFigure figure) { + figure.removeMouseListener(this); + figure.removeMouseMotionListener(this); + } + + public void install(Control control) { + control.addListener(SWT.MouseUp, this); + control.addListener(SWT.MouseWheel, this); + control.addListener(SWT.KeyDown, this); + } + + public void uninstall(Control control) { + control.removeListener(SWT.MouseUp, this); + control.removeListener(SWT.MouseWheel, this); + control.removeListener(SWT.KeyDown, this); + } + + public void handleEvent(Event event) { + if (event.type == SWT.MouseUp) { + dayPressed = false; + if (target != null) { + final BaseFigure eventTarget = target; + final BaseFigure eventPreTarget = pretarget; + target.setPressed(false); + target = null; + selected(eventTarget, eventPreTarget); + } + } else if (event.type == SWT.MouseWheel) { + if (event.count == 0) + return; + // wheel upwards, count > 0, month should decrease + // wheel downwards, count < 0, month should increase + rollMonth(event.count > 0 ? -1 : 1); + } else if (event.type == SWT.KeyDown) { + handleKeyPress(event.keyCode, event.stateMask); + } + } + + private void handleKeyPress(int key, int mask) { + if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_UP)) { + lastMonthSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_DOWN)) { + nextMonthSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_LEFT)) { + lastYearSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_RIGHT)) { + nextYearSelected(true); + } + } + + public void mouseDoubleClicked(MouseEvent me) { + // do nothing + BaseFigure source = (BaseFigure) me.getSource(); + if (source instanceof HourFigure + || source instanceof MinutesFigure) { + startEditing(source); + } + } + + private void startEditing(final BaseFigure source) { + canvas = getDatePicker(); + final Text editor = new Text(getDatePicker(), + SWT.SINGLE | SWT.BORDER); + editor.setFont(source.getFont()); + editor.setText(source.getText()); + //set location of editor + Rectangle bounds = source.getBounds(); + Viewport viewport = canvas.getViewport(); + int x = bounds.x - viewport.getClientArea().x; + int y = bounds.y - viewport.getClientArea().y; + + Point size = editor.computeSize(SWT.DEFAULT, SWT.DEFAULT); + editor.setBounds(x, y + (bounds.height - size.y) / 2, bounds.width, + size.y); + + canvas.layout(); + + editor.selectAll(); + editor.setFocus(); + //focus out + final Listener mouseDownFilter = new Listener() { + + public void handleEvent(Event event) { + if (event.widget != editor) { + finishEditingTime(editor, source); + } + } + }; + + editor.getDisplay().addFilter(SWT.MouseDown, mouseDownFilter); + editor.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + editor.getDisplay().removeFilter(SWT.MouseDown, + mouseDownFilter); + } + }); + + editor.addKeyListener(new KeyListener() { + + public void keyReleased(KeyEvent e) { + } + + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.CR) { + finishEditingTime(editor, source); + } + } + }); + + editor.addTraverseListener(new TraverseListener() { + + public void keyTraversed(TraverseEvent e) { + if (e.detail == SWT.TRAVERSE_ESCAPE) { + e.doit = false; + cancelEditingTime(editor); + } + } + }); + } + + private void cancelEditingTime(Text editor) { + editor.dispose(); + canvas.layout(); + } + + private void finishEditingTime(Text editor, BaseFigure source) { + String newValue = editor.getText().trim(); + String oldValue = source.getText().trim(); + if ("".equals(newValue) || null == newValue //$NON-NLS-1$ + || newValue.equals(oldValue)) { + disposeEditor(editor, source); + if (!"12".equals(newValue)) //$NON-NLS-1$ + return; + } + int value = -1; + try { + value = Integer.parseInt(newValue); + if (source instanceof HourFigure) + changeHourOrMinutes(false, value, currentMinutes); + if (source instanceof MinutesFigure) + changeHourOrMinutes(false, currentHour, value); + } catch (NumberFormatException e) { +// e.printStackTrace(); + } + disposeEditor(editor, source); + } + + private void disposeEditor(Text editor, BaseFigure source) { + updateSelection(); + source.setBorder(null); + editor.dispose(); + canvas.layout(); + } + + public void mouseDragged(MouseEvent me) { + // do nothing + } + + public void mouseEntered(MouseEvent me) { + if (target == null) { + BaseFigure source = (BaseFigure) me.getSource(); + if (source instanceof DayFigure && dayPressed) { + source.setPressed(true); + source.setPreselected(false); + } else { + if (source == monthFigure || source == lastMonth + || source == nextMonth) { + monthFigure.setPreselected(true); + lastMonth.getContent().setVisible(true); + nextMonth.getContent().setVisible(true); + } else if (source == yearFigure || source == lastYear + || source == nextYear) { + yearFigure.setPreselected(true); + lastYear.getContent().setVisible(true); + nextYear.getContent().setVisible(true); + } else if (source == todayFigure) { + todayFigure.setFont( + FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); + todayFigure.setForegroundColor( + ColorUtils.getColor(CANCEL)); + return; + } + source.setPreselected(true); + } + } + } + + public void mouseExited(MouseEvent me) { + if (target == null) { + BaseFigure source = (BaseFigure) me.getSource(); + if (source instanceof DayFigure) { + source.setPreselected(false); + if (dayPressed) { + source.setPressed(false); + } + } else { + if (source == monthFigure || source == lastMonth + || source == nextMonth) { + monthFigure.setPreselected(false); + lastMonth.getContent().setVisible(false); + nextMonth.getContent().setVisible(false); + } else if (source == yearFigure || source == lastYear + || source == nextYear) { + yearFigure.setPreselected(false); + lastYear.getContent().setVisible(false); + nextYear.getContent().setVisible(false); + } else if (source == todayFigure) { + todayFigure.setFont( + FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); + todayFigure + .setForegroundColor(ColorUtils.getColor(TEXT)); + return; + } + source.setPreselected(false); + } + } + } + + public void mouseHover(MouseEvent me) { + // do nothing + } + + public void mouseMoved(MouseEvent me) { + // do nothing + } + + public void mousePressed(MouseEvent me) { + BaseFigure source = (BaseFigure) me.getSource(); + if (source != todayFigure) { + source.setPressed(true); + source.setPreselected(false); + } + if (source instanceof DayFigure) { + dayPressed = true; + } else { + target = source; + } + if (source instanceof HourFigure + || source instanceof MinutesFigure) { + startEditing(source); + } + } + + public void mouseReleased(MouseEvent me) { + BaseFigure source = (BaseFigure) me.getSource(); + source.setPressed(false); + if (source instanceof DayFigure) { + if (dayPressed) { + daySelected((DayFigure) me.getSource()); + } + source.setPreselected(true); + } else if (source instanceof HourFigure + || source instanceof MinutesFigure) { + pretarget = source; + } else { + if (!source.isSelected()) { + if (source != todayFigure) + source.setPreselected(true); + } + } + } + } + + private class DropdownDatePicker extends PopupDialog { + public DropdownDatePicker(Shell parent) { + super(parent, SWT.NO_TRIM, true, false, false, false, false, null, + null); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + createDatePicker(composite); + datePicker.setLayoutData(new org.eclipse.swt.layout.GridData( + SWT.FILL, SWT.FILL, true, true)); + initDatePicker(); + update(); + return composite; + } + + @Override + public int open() { + isPopupEditing = true; + return super.open(); + } + + @Override + public boolean close() { + isPopupEditing = false; + boolean closed = super.close(); + if (closed) { + datePicker = null; + } + return closed; + } + + @Override + protected Point getInitialLocation(Point initialSize) { + Control c = DatePicker.this.getControl(); + org.eclipse.swt.graphics.Rectangle r = c.getBounds(); + return c.toDisplay(0, r.height + 1); + } + + } + + private class MonthAction extends Action { + + private int month; + + public MonthAction(int month) { + super(MONTHS[month]); + this.month = month; + } + + public void run() { + monthSelected(month); + } + } + + private class YearAction extends Action { + + private int year; + + public void setYear(int year) { + this.year = year; + setText("" + year); //$NON-NLS-1$ + } + + public int getYear() { + return year; + } + + public void run() { + yearSelected(year); + } + } + + private class AnimationAdvisor implements IAnimationAdvisor { + + private int monthsToRoll = 0; + + private int yearsToRoll = 0; + + private int duration = -1; + + private int oldYear; + + private int oldMonth; + + private int newYear; + + private int newMonth; + + public void addMonthsToRoll(int count) { + monthsToRoll += count; + duration = -1; + } + + public void addYearsToRoll(int count) { + yearsToRoll += count; + duration = -1; + } + + public int getDuration() { + if (duration < 0) { + int steps = Math.abs(monthsToRoll) + Math.abs(yearsToRoll); + duration = steps == 0 ? 0 : DURATION / steps; + } + return duration; + } + + public IFigure getLayer() { + return DatePicker.this.dateLayer; + } + + public int getMonthsToRoll() { + return monthsToRoll; + } + + public int getNewMonth() { + return newMonth; + } + + public int getNewYear() { + return newYear; + } + + public int getOldMonth() { + return oldMonth; + } + + public int getOldYear() { + return oldYear; + } + + public IFigure getPanel() { + return DatePicker.this.datePanel; + } + + public int getYearsToRoll() { + return yearsToRoll; + } + + public void initNewDay(DayFigure figure) { + updateDayFigure(figure, oldYear, oldMonth); + } + + public void initOldDay(DayFigure figure) { + figure.setPreselected(false); + figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); + eventHandler.detach(figure); + } + + public boolean isDone() { + return monthsToRoll == 0 && yearsToRoll == 0; + } + + public void setEndMonth(int newYear, int newMonth) { + this.newYear = newYear; + this.newMonth = newMonth; + } + + public void setStartMonth(int oldYear, int oldMonth) { + this.oldYear = oldYear; + this.oldMonth = oldMonth; + } + + public void updateNewDay(DayFigure figure) { + figure.setPreselected(false); + figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); + eventHandler.attach(figure); + updateDayFigure(figure, newYear, newMonth); + } + + } + + private int style; //mark the style of datepicker + + private int type = TIME_12; // TIME_12 or TIME_24 mark the type of time 12 Hour or 24 Hour. + + private Control control; + + private FigureCanvas datePicker; + + private BaseFigure timePicker; + + private HourFigure hourFigure; + + private MinutesFigure minutesFigure; + +// private BaseFigure okButton; +// +// private BaseFigure cancelButton; + +// private BaseFigure figure; + + private BaseFigure timeLabel; + + private ArrowFigure beforeTime; + + private ArrowFigure afterTime; + + private MButton placeholder; + + private ILabelProvider dateLabelProvider; + + private DropdownDatePicker dropdownDatePicker; + + private Calendar today; + + private int currentMonth; + + private int currentYear; + + private int currentHour; + + private int currentMinutes; + + private Calendar selection; + + private IFigure dateLayer; + + private IFigure datePanel; + + private MonthFigure monthFigure; + + private YearFigure yearFigure; + + private BaseFigure todayFigure; + + private BaseFigure cancelFigure; + + private EventHandler eventHandler; + + private MenuManager monthMenu; + + private MonthAction[] monthActions; + + private MenuManager yearMenu; + + private YearAction[] yearActions; + + private ArrowFigure lastYear; + + private ArrowFigure nextYear; + + private ArrowFigure lastMonth; + + private ArrowFigure nextMonth; + + private boolean firingSelectionChange = false; + + private boolean animating = false; + + private IAnimationAdvisor animationAdvisor = new AnimationAdvisor(); + + private boolean isPopupEditing = false; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a composite control which will be the parent of the new + * instance (cannot be null) + * @param style + * the style of control to construct + * @see SWT#SIMPLE + * @see SWT#DROP_DOWN + * @see SWT#CANCEL + */ + public DatePicker(Composite parent, int style) { + this(parent, style, Calendar.getInstance()); + } + + public DatePicker(Composite parent, int style, Calendar today) { + this.today = today; + this.currentMonth = today.get(MONTH); + this.currentYear = today.get(YEAR); + this.currentHour = today.get(HOUR_OF_DAY); + this.currentMinutes = today.get(MINUTE); + this.style = style; + if ((style & SWT.DROP_DOWN) != 0) { + createPlaceholder(parent); + this.control = placeholder.getControl(); + initPlaceholder(); + } else { + createDatePicker(parent); + this.control = datePicker; + initDatePicker(); + } + update(); + } + + private void createPlaceholder(Composite parent) { + this.placeholder = new MButton(parent, MButton.NORMAL); + } + + private void createDatePicker(Composite parent) { + this.datePicker = new FigureCanvas(parent); + } + + public void setLabelProvider(ILabelProvider labelProvider) { + this.dateLabelProvider = labelProvider; + update(); + } + + public ILabelProvider getLabelProvider() { + if (this.dateLabelProvider == null) { + this.dateLabelProvider = new DateLabelProvider(); + } + return this.dateLabelProvider; + } + + public Control getControl() { + return control; + } + + public FigureCanvas getDatePicker() { + return datePicker; + } + + public boolean isPopupEditing() { + return isPopupEditing; + } + + public void setBackground(Color color) { + if (control != null && !control.isDisposed()) { + control.setBackground(color); + } + } + + public void setEnabled(boolean enabled) { + if (placeholder != null) { + placeholder.setEnabled(enabled); + } + } + + public MButton getPlaceholder() { + return placeholder; + } + + public ISelection getSelection() { + return new DateSelection(selection); + } + + @Override + public void setSelection(ISelection selection) { + setSelection(selection, true); + } + + @Override + public void setSelection(ISelection selection, boolean reveal) { + if (selection instanceof DateSelection) { + setDateSelection(((DateSelection) selection).getDate(), reveal); + } else if (selection instanceof IStructuredSelection) { + Object sel = ((IStructuredSelection) selection).getFirstElement(); + if (sel instanceof Calendar) { + setDateSelection((Calendar) sel, reveal); + } + } + } + + public void setDateSelection(Calendar date, boolean reveal) { + changeDate(date); + if (reveal && date != null) { + changeCalendar(date.get(YEAR), date.get(MONTH), + date.get(HOUR_OF_DAY), date.get(MINUTE)); + } + update(); + } + + private void initPlaceholder() { + placeholder.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + if (dropdownDatePicker == null + || dropdownDatePicker.getShell() == null + || dropdownDatePicker.getShell().isDisposed() + || !dropdownDatePicker.isClosing()) + showDropdown(); + } + }); + } + + /** + * Shows the drop-down date picker ,and compute the size by the control. + */ + private void showDropdown() { + placeholder.setForceFocus(true); + createDropdownDatePicker(); + dropdownDatePicker.open(); + Shell shell = dropdownDatePicker.getShell(); + int x = placeholder.getControl().getBounds().width; + x = x < 230 ? 230 : x; //set the datepicker min width is 250px + x = x > 250 ? 250 : x; //set the datepicker max width is 280px + shell.setSize(x, x + 30); + if (shell != null && !shell.isDisposed()) { + shell.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + if (placeholder != null + && !placeholder.getControl().isDisposed()) { + placeholder.setForceFocus(false); + updateSelection(); + closeDatePicker(); + } + } + + }); + } else { + placeholder.setForceFocus(false); + } + } + + private void closeDatePicker() { + if (firingSelectionChange) + return; + firingSelectionChange = true; + if (dropdownDatePicker != null) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + dropdownDatePicker.close(); + } + }); + } + fireSelectionChanged( + new SelectionChangedEvent(DatePicker.this, getSelection())); + firingSelectionChange = false; + } + + /** + * Shows the drop-down menu if this date picker is created with + * SWT.DROP_DOWN style bit. + */ + public void open() { + showDropdown(); + } + + public void close() { + if (dropdownDatePicker != null) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + dropdownDatePicker.close(); + } + }); + } + } + + private void createDropdownDatePicker() { + if (dropdownDatePicker != null) + return; + dropdownDatePicker = new DropdownDatePicker(control.getShell()); + } + + private void initDatePicker() { + datePicker.setScrollBarVisibility(FigureCanvas.NEVER); +// if (Util.isWindows()) { + //datePicker.setBackground(datePicker.getParent().getBackground()); +// } else { +// datePicker.getLightweightSystem().getRootFigure().setOpaque(false); +// } + + eventHandler = new EventHandler(); + eventHandler.install(datePicker); + datePicker.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + eventHandler.uninstall(datePicker); + } + }); + + Viewport viewport = new Viewport(true); + viewport.setContentsTracksHeight(true); + viewport.setContentsTracksWidth(true); + datePicker.setViewport(viewport); + + IFigure container = new Layer(); + datePicker.setContents(container); + + GridLayout containerLayout = new GridLayout(1, true); + containerLayout.horizontalSpacing = 3; + containerLayout.verticalSpacing = 3; + containerLayout.marginHeight = 3; + containerLayout.marginWidth = 3; + container.setLayoutManager(containerLayout); + createTopPanel(container); + createSeparator(container); + createWeekPanel(container); + createDaysPanel(container); + createSeparator(container); + createBottomPanel(container); +// createSeparator(container); +// createOkAndCancel(container); + + } + + private void createTopPanel(IFigure parent) { + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + + GridLayout panelLayout = new GridLayout(12, true); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 0; + panelLayout.marginWidth = 0; + panel.setLayoutManager(panelLayout); + + lastMonth = createArrowFigure(panel, ArrowFigure.UP); + monthFigure = createMonthFigure(panel); + nextMonth = createArrowFigure(panel, ArrowFigure.DOWN); + lastYear = createArrowFigure(panel, ArrowFigure.LEFT); + yearFigure = createYearFigure(panel); + nextYear = createArrowFigure(panel, ArrowFigure.RIGHT); + } + + private MonthFigure createMonthFigure(IFigure parent) { + MonthFigure figure = new MonthFigure(); + figure.setTextCandidates(MONTHS); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + constraint.horizontalSpan = 5; + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + private YearFigure createYearFigure(IFigure parent) { + YearFigure figure = new YearFigure(); + figure.setTextCandidates(new String[] { "0000" }); //$NON-NLS-1$ + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + constraint.horizontalSpan = 3; + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + @SuppressWarnings("deprecation") + private ArrowFigure createArrowFigure(IFigure parent, int orientation) { + ArrowFigure arrow = new ArrowFigure(); + arrow.setOrientation(orientation); + arrow.setForegroundColor(ColorUtils.getColor(ARROW_BORDER)); + arrow.setBackgroundColor(ColorUtils.getColor(ARROW_FILL)); + arrow.getContent().setVisible(false); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.add(arrow, constraint); + eventHandler.attach(arrow); + return arrow; + } + + @SuppressWarnings("deprecation") + private void createSeparator(IFigure parent) { + HorizontalLine line = new HorizontalLine(); + line.setMargin(3); + line.setForegroundColor(ColorUtils.getColor(SEPARATOR)); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); + constraint.heightHint = 3; + parent.add(line, constraint); + } + + @SuppressWarnings("deprecation") + private void createWeekPanel(IFigure parent) { + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + GridLayout panelLayout = new GridLayout(7, true); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 0; + panelLayout.marginWidth = 0; + panel.setLayoutManager(panelLayout); + @SuppressWarnings("deprecation") + Font symbolFont = FontUtils.getRelativeHeight(DEFAULT_FONT, -2); + for (int i = 0; i < 7; i++) { + TextLayer symbol = new TextLayer(); + symbol.setFont(symbolFont); + symbol.setText(WEEK_SYMBOLS[i]); + if (i == 0 || i == 6) { + symbol.setForegroundColor(ColorUtils.getColor(WEEKEND)); + } else { + symbol.setForegroundColor(ColorUtils.getColor(WEEK_SYMBOL)); + } + GridData symbolConstraint = new GridData(SWT.FILL, SWT.FILL, true, + true); + panel.add(symbol, symbolConstraint); + } + } + + private void createDaysPanel(IFigure parent) { + dateLayer = new Layer(); + GridData layerConstraint = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.add(dateLayer, layerConstraint); + dateLayer.setLayoutManager(new ConstraintStackLayout()); + + datePanel = new Layer(); + dateLayer.add(datePanel, null); + datePanel.setLayoutManager(new DatePanelLayout()); + for (int i = 0; i < TOTAL_DAYS; i++) { + DayFigure dayFigure = new DayFigure(); + eventHandler.attach(dayFigure); + datePanel.add(dayFigure); + } + } + + private void createBottomPanel(IFigure parent) { + boolean hasCancel = (style & SWT.CANCEL) != 0; + boolean hasTimePicker = (style & LOAD_TIMEPICKER) != 0; + + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + + int cols = 0; + cols = hasCancel ? 2 : 1; + cols = hasTimePicker ? cols + 2 : cols; + + GridLayout panelLayout = new GridLayout(cols, false); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 10; + panelLayout.marginWidth = 5; + + panel.setLayoutManager(panelLayout); + + todayFigure = createTodayFigure(panel); + + if (hasTimePicker) { + timePicker = createTimeFigure(panel); +// createUpAndDown(panel); + timeLabel = createLabelOfTime(panel); + } + if (hasCancel) { + cancelFigure = createCancelFigure(panel); + } + } + + @SuppressWarnings("deprecation") + private BaseFigure createTodayFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, 0)); + figure.setForegroundColor(ColorUtils.getColor(TEXT)); + GridData constraint = new GridData(SWT.CENTER, SWT.CENTER, true, true); + parent.add(figure, constraint); + + eventHandler.attach(figure); + return figure; + } + + @SuppressWarnings("deprecation") + private BaseFigure createCancelFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setText(" X "); //$NON-NLS-1$ + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); + figure.setForegroundColor(ColorUtils.getColor(CANCEL)); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + @SuppressWarnings("deprecation") + private BaseFigure createTimeFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -1)); + figure.setForegroundColor(ColorConstants.white); + figure.setBackgroundColor(ColorConstants.white); + figure.setOpaque(true); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, false); + figure.setLayoutManager(new XYLayout()); + parent.add(figure, constraint); + + IFigure panel = new Layer(); + figure.add(panel, new Rectangle(0, 2, 60, 20)); + panel.setBorder(new LineBorder(ColorConstants.lightGray, 1)); + panel.setForegroundColor(ColorConstants.white); + XYLayout layout = new XYLayout(); + + panel.setLayoutManager(layout); + hourFigure = createHourFigure(panel); + BaseFigure point = createPointFigure(panel); + minutesFigure = createMinutesFigure(panel); + panel.add(hourFigure, new Rectangle(0, 0, 25, 18)); + panel.add(point, new Rectangle(26, 0, 3, 18)); + panel.add(minutesFigure, new Rectangle(31, 0, 25, 18)); + return figure; + } + + @SuppressWarnings("deprecation") + private BaseFigure createPointFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setSize(3, 18); + figure.setText(" : "); //$NON-NLS-1$ + figure.setForegroundColor(ColorUtils.getColor(TIME)); + parent.add(figure); + return figure; + } + +// private IFigure createHourAndMinutesPanel(IFigure parent) { +// IFigure panel = new Layer(); +// panel.setSize(32, 16); +// GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); +// constraint.horizontalSpan = 3; +// parent.add(panel, constraint); +// ToolbarLayout layout = new ToolbarLayout(); +// layout.setSpacing(0); +// panel.setLayoutManager(layout); +// return panel; +// } + + @SuppressWarnings("deprecation") + private HourFigure createHourFigure(IFigure parent) { + HourFigure figure = new HourFigure(); + figure.setHour(currentHour, type); + figure.setTextCandidates(new String[] { " 00 " }); //$NON-NLS-1$ + figure.setForegroundColor(ColorUtils.getColor(TIME)); + eventHandler.attach(figure); + return figure; + } + + @SuppressWarnings("deprecation") + private MinutesFigure createMinutesFigure(IFigure parent) { + MinutesFigure figure = new MinutesFigure(); + figure.setMinutes(currentMinutes); + figure.setTextCandidates(new String[] { " 00 " }); //$NON-NLS-1$ + figure.setForegroundColor(ColorUtils.getColor(TIME)); + eventHandler.attach(figure); + return figure; + } + + @SuppressWarnings("deprecation") + private BaseFigure createLabelOfTime(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setText(getTimeLabel()); + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -1)); + figure.setForegroundColor(ColorUtils.getColor(TEXT)); + figure.setCursor(Cursors.ARROW); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); + parent.add(figure, constraint); + return figure; + } + +// private void createOkAndCancel(IFigure parent) { +// IFigure panel = new Layer(); +// GridData panelConstraint = new GridData(SWT.CENTER, SWT.FILL, true, +// false); +// parent.add(panel, panelConstraint); +// GridLayout panelLayout = new GridLayout(4, true); +// panelLayout.horizontalSpacing = 10; +// panelLayout.verticalSpacing = 0; +// panelLayout.marginHeight = 5; +// panelLayout.marginWidth = 5; +// panelLayout.verticalSpacing = 5; +// panel.setLayoutManager(panelLayout); +// cancelButton = createCancel(panel); +// createLabel(panel); +// createLabel(panel); +// okButton = createOk(panel); +// } + +// private void createLabel(IFigure parent) { +// BaseFigure figure = new BaseFigure(); +// GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); +// parent.add(figure, data); +// } +// +// private BaseFigure createOk(IFigure parent) { +// BaseFigure figure = new BaseFigure(); +// figure.setText("OK"); +// figure.setOpaque(true); +// figure.setBackgroundColor(ColorConstants.white); +// figure.setBorder(new LineBorder(ColorConstants.lightGray)); +// figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); +// parent.add(figure, new GridData(SWT.FILL, SWT.FILL, false, false)); +// eventHandler.attach(figure); +// return figure; +// } + +// private BaseFigure createCancel(IFigure parent) { +// BaseFigure figure = new BaseFigure(); +// figure.setText("CANCEL"); +// figure.setBackgroundColor(ColorConstants.white); +// figure.setOpaque(true); +// figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); +// figure.setBorder(new LineBorder(ColorConstants.lightGray)); +// parent.add(figure, new GridData(SWT.FILL, SWT.FILL, false, false)); +// eventHandler.attach(figure); +// return figure; +// } + + private String getTimeLabel() { + if (currentHour >= 0 && currentHour < 12) + return Messages.DatePicker_Time_AM_text; + else if (currentHour >= 12 && currentHour < 24) + return Messages.DatePicker_Time_PM_text; + return ""; //$NON-NLS-1$ + } + + private Calendar getSelectedDate() { + return selection; + } + + private static boolean isSameDay(Calendar date1, Calendar date2) { + if (date1 == null) + return date2 == null; + if (date2 == null) + return false; + return date1.get(DATE) == date2.get(DATE) + && date1.get(MONTH) == date2.get(MONTH) + && date1.get(YEAR) == date2.get(YEAR); + } + + protected void changeCalendar(int newYear, int newMonth, int newHour, + int newMinutes) { + changeCalendar(newYear, newMonth, newHour, newMinutes, false); + } + + //change the ui of canlendar + protected void changeCalendar(int newYear, int newMonth, int hours, + int minutes, boolean smooth) { + boolean calendarChanged = newMonth != currentMonth + || newYear != currentYear || currentHour != hours + || currentMinutes != minutes; + if (!calendarChanged) + return; + if (smooth) { + if (datePicker != null) { + int months = (newYear - currentYear) * 12 + newMonth + - currentMonth; + animationAdvisor.addYearsToRoll(months / 12); + animationAdvisor.addMonthsToRoll(months % 12); + performRollCalendarAnimation(currentYear, currentMonth); + } + currentYear = newYear; + currentMonth = newMonth; + currentHour = hours; + currentMinutes = minutes; + } else { + currentYear = newYear; + currentMonth = newMonth; + currentHour = hours; + currentMinutes = minutes; + if (datePicker != null) { + updateCalendar(); + } + updateSelection(); + } + } + + private void updateCalendar() { + today = Calendar.getInstance(); + updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); + monthFigure.setMonth(currentMonth); + yearFigure.setYear(currentYear); + hourFigure.setHour(currentHour, type); + minutesFigure.setMinutes(currentMinutes); +// todayFigure.setText(NLS.bind(Messages.TodayPattern, +// String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ + todayFigure.setText(Messages.TodayPattern); + } + + private void updateDayFigures(List dayFigures, int year, int month) { + Calendar date = getCalendarStart(today, year, month); + for (int i = 0; i < dayFigures.size(); i++) { + DayFigure dayFigure = (DayFigure) dayFigures.get(i); + date = (Calendar) date.clone(); + if (i > 0) + date.add(DATE, 1); + dayFigure.setDate(date); + updateDayFigure(dayFigure, year, month); + } + + } + + @SuppressWarnings("deprecation") + void updateDayFigure(DayFigure figure, int year, int month) { + figure.setFont(FontUtils.getBold(DEFAULT_FONT)); + Calendar date = figure.getDate(); + if (isSameDay(date, today)) { + figure.setForegroundColor(ColorUtils.getColor(TODAY)); + } else if (isWeekend(date)) { + figure.setForegroundColor(ColorUtils.getColor(WEEKEND)); + } else { + figure.setForegroundColor(ColorUtils.getColor(TEXT)); + } + if (date.get(MONTH) == month && date.get(YEAR) == year) { + figure.setTextAlpha(NORMAL_ALPHA); + } else { + figure.setTextAlpha(SIBLING_MONTH_ALPHA); + } + } + + private void updateSelection() { + if (datePicker != null) { + for (Object figure : datePanel.getChildren()) { + DayFigure dayFigure = (DayFigure) figure; + dayFigure.setSelected( + isSameDay(dayFigure.getDate(), getSelectedDate())); + } + } + + if (null != hourFigure && null != selection) + selection.set(HOUR_OF_DAY, hourFigure.getHour()); + if (null != minutesFigure && null != selection) + selection.set(MINUTE, minutesFigure.getMinutes()); + + if (placeholder != null) { + String text = getLabelProvider().getText(selection); + placeholder.setText(text); + } + } + + protected void update() { + if (datePicker != null) { + updateCalendar(); + } + updateSelection(); + } + + private void performRollCalendarAnimation(int oldYear, int oldMonth) { + if (animating) + return; + + animating = true; + + final int newYear, newMonth; + final CalendarAnimation animation; + if (animationAdvisor.getYearsToRoll() != 0) { + if (animationAdvisor.getYearsToRoll() < 0) { + newYear = oldYear - 1; + newMonth = oldMonth; + animation = new LastYearAnimation(animationAdvisor); + } else { + newYear = oldYear + 1; + newMonth = oldMonth; + animation = new NextYearAnimation(animationAdvisor); + } + } else if (animationAdvisor.getMonthsToRoll() != 0) { + if (animationAdvisor.getMonthsToRoll() < 0) { + newYear = oldMonth <= 0 ? oldYear - 1 : oldYear; + newMonth = oldMonth <= 0 ? 11 : oldMonth - 1; + animation = new LastMonthAnimation(animationAdvisor); + } else { + newYear = oldMonth >= 11 ? oldYear + 1 : oldYear; + newMonth = oldMonth >= 11 ? 0 : oldMonth + 1; + animation = new NextMonthAnimation(animationAdvisor); + } + } else { + newYear = oldYear; + newMonth = oldMonth; + animation = null; + } + monthFigure.setMonth(newMonth); + yearFigure.setYear(newYear); + if (animation != null) { + animationAdvisor.setStartMonth(oldYear, oldMonth); + animationAdvisor.setEndMonth(newYear, newMonth); + animation.callback(new Runnable() { + public void run() { + datePanel = animation.getNewPanel(); + if (animationAdvisor.isDone()) { + animating = false; + } else { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + animating = false; + performRollCalendarAnimation(newYear, newMonth); + } + }); + } + + } + }).start(); + } + } + + static int calc(int start, int end, int current, int total) { + return start + (end - start) * current / total; + } + + protected void selected(final BaseFigure target, + final BaseFigure pretarget) { + if (target instanceof MonthFigure) { + target.setSelected(true); + showMonthPopup(); + } else if (target instanceof YearFigure) { + target.setSelected(true); + showYearPopup(); + } else if (target == todayFigure) { + todaySelected(); + } else if (target == lastMonth) { + lastMonthSelected(true); + } else if (target == nextMonth) { + nextMonthSelected(true); + } else if (target == lastYear) { + lastYearSelected(true); + } else if (target == nextYear) { + nextYearSelected(true); + } else if (target == cancelFigure) { + cancelSelected(); + } else if (target == beforeTime) { +// beforeTimeSelected(true, pretarget); + } else if (target == afterTime) { +// afterTimeSelected(true, pretarget); + } else if (target instanceof HourFigure) { + if (null != minutesFigure) + minutesFigure.setSelected(false); + hourSelected((HourFigure) target); + } else if (target instanceof MinutesFigure) { + if (null != hourFigure) + hourFigure.setSelected(false); + minuteSelected((MinutesFigure) target); + } + } + + protected void showMonthPopup() { + createMonthMenu(); + for (int month = 0; month < monthActions.length; month++) { + MonthAction action = monthActions[month]; + action.setChecked(month == currentMonth); + } + Rectangle b = monthFigure.getBounds(); + Point loc = control.toDisplay(b.x, b.y + b.height); + final Menu menu = monthMenu.createContextMenu(control); + menu.setLocation(loc.x + 10, loc.y + 1); + menu.setVisible(true); + } + + protected void createMonthMenu() { + if (monthMenu != null) + return; + monthMenu = new MenuManager(); + monthMenu.addMenuListener(new IMenuListener2() { + public void menuAboutToShow(IMenuManager manager) { + // do nothing + } + + public void menuAboutToHide(IMenuManager manager) { + monthFigure.setSelected(false); + } + }); + monthActions = new MonthAction[12]; + for (int month = 0; month < 12; month++) { + MonthAction action = new MonthAction(month); + monthMenu.add(action); + monthActions[month] = action; + } + } + + protected void showYearPopup() { + createYearMenu(); + int start = currentYear - PASSED_YEARS; + for (int year = 0; year < yearActions.length; year++) { + YearAction action = yearActions[year]; + action.setYear(start + year); + action.setChecked(action.getYear() == currentYear); + } + Rectangle b = yearFigure.getBounds(); + Point loc = control.toDisplay(b.x, b.y + b.height); + Menu menu = yearMenu.createContextMenu(control); + menu.setLocation(loc.x, loc.y + 1); + menu.setVisible(true); + } + + protected void createYearMenu() { + if (yearMenu != null) + return; + yearMenu = new MenuManager(); + yearMenu.addMenuListener(new IMenuListener2() { + public void menuAboutToShow(IMenuManager manager) { + // do nothing + } + + public void menuAboutToHide(IMenuManager manager) { + yearFigure.setSelected(false); + } + }); + yearActions = new YearAction[FUTURE_YEARS + PASSED_YEARS + 1]; + for (int year = 0; year < yearActions.length; year++) { + YearAction action = new YearAction(); + yearMenu.add(action); + yearActions[year] = action; + } + } + + protected void monthSelected(int month) { + changeCalendar(currentYear, month, currentHour, currentMinutes); + } + + protected void yearSelected(int year) { + changeCalendar(year, currentMonth, currentHour, currentMinutes); + } + + protected void daySelected(DayFigure day) { + Calendar date = day.getDate(); + if (date != null && date.get(MONTH) != currentMonth) { + changeCalendar(date.get(YEAR), date.get(MONTH), + date.get(HOUR_OF_DAY), date.get(MINUTE), true); + } + if (null != date && date.get(HOUR_OF_DAY) != currentHour) { + changeHourOrMinutes(true, date.get(HOUR_OF_DAY), date.get(MINUTE)); + } + selection = date; + changeDate(date); + } + + protected void hourSelected(HourFigure hour) { + hour.setSelected(true); + } + + protected void minuteSelected(MinutesFigure minute) { + minute.setSelected(true); + } + + protected void todaySelected() { + changeDate(today); + changeCalendar(today.get(YEAR), today.get(MONTH), + today.get(HOUR_OF_DAY), today.get(MINUTE)); + freshTimePicker(today.get(HOUR_OF_DAY), currentMinutes); + } + + protected void lastMonthSelected(boolean smooth) { + if (currentMonth <= 0) { + changeCalendar(currentYear - 1, 11, currentHour, currentMinutes, + smooth); + } else { + changeCalendar(currentYear, currentMonth - 1, currentHour, + currentMinutes, smooth); + } + } + + protected void nextMonthSelected(boolean smooth) { + if (currentMonth >= 11) { + changeCalendar(currentYear + 1, 0, currentHour, currentMinutes, + smooth); + } else { + changeCalendar(currentYear, currentMonth + 1, currentHour, + currentMinutes, smooth); + } + } + + protected void lastYearSelected(boolean smooth) { + changeCalendar(currentYear - 1, currentMonth, currentHour, + currentMinutes, smooth); + } + + protected void nextYearSelected(boolean smooth) { + changeCalendar(currentYear + 1, currentMonth, currentHour, + currentMinutes, smooth); + } + + protected void cancelSelected() { + changeDate(null); + } + +// protected void beforeTimeSelected(boolean smooth, BaseFigure target) { +// if (target instanceof HourFigure) { +// changeHourOrMinutes(smooth, currentHour - 1, currentMinutes); +// } else if (target instanceof MinutesFigure) +// changeHourOrMinutes(smooth, currentHour, currentMinutes - 1); +// } +// +// protected void afterTimeSelected(boolean smooth, BaseFigure target) { +// if (target instanceof HourFigure) +// changeHourOrMinutes(smooth, currentHour + 1, currentMinutes); +// else if (target instanceof MinutesFigure) +// changeHourOrMinutes(smooth, currentHour, currentMinutes + 1); +// } + + protected void changeHourOrMinutes(boolean smooth, int newHour, + int newMinutes) { + + freshTimePicker(newHour, newMinutes); + + if (selection != null) { + selection.set(HOUR_OF_DAY, newHour); + selection.set(MINUTE, newMinutes); + changeDate(selection); + } + + update(); + } + + private void freshTimePicker(int newHour, int newMinutes) { + boolean minuteChanged = newMinutes != currentMinutes; + + newHour = resetHour(newHour); + newMinutes = resetMinutes(newMinutes); + if (null != timePicker) { + if (null != hourFigure) { + if (!validateHour(newHour)) + return; + if (newHour >= 12) + timeLabel.setText(Messages.DatePicker_Time_PM_text); + else if (newHour < 12) + timeLabel.setText(Messages.DatePicker_Time_AM_text); + currentHour = newHour; + hourFigure.setHour(newHour, type); //default type = 12 hours every day. + } + if (null != minutesFigure && minuteChanged) { + if (!validateMinutes(newMinutes)) + return; + currentMinutes = newMinutes; + minutesFigure.setMinutes(newMinutes); + } + } + } + + private int resetHour(int hour) { + if (hour > 23) { + return 0; + } + if (hour < 0 && type == TIME_24) { + hour = 23; + } else if (hour < 0 && type == TIME_12) { + hour = 11; + } + return hour; + } + + private int resetMinutes(int minutes) { + if (minutes > 59) { + minutes = 0; + } else if (minutes < 0) { + minutes = 59; + } + return minutes; + } + + private boolean validateHour(int hour) { + if (hour >= 0 && hour <= 23) + return true; + return false; + } + + private boolean validateMinutes(int minutes) { + if (minutes >= 0 && minutes < 60) + return true; + return false; + } + + protected void rollMonth(int count) { + Calendar temp = (Calendar) today.clone(); + temp.set(YEAR, currentYear); + temp.set(MONTH, currentMonth); + temp.add(MONTH, count); + changeCalendar(temp.get(YEAR), temp.get(MONTH), temp.get(HOUR_OF_DAY), + temp.get(MINUTE), true); + } + + //send the selectionChanged event ,inform all listeners. + protected void changeDate(Calendar date) { + this.selection = date; + updateSelection(); + if (firingSelectionChange) + return; + + firingSelectionChange = true; + fireSelectionChanged( + new SelectionChangedEvent(DatePicker.this, getSelection())); + firingSelectionChange = false; + } + + @Override + public Object getInput() { + return today; + } + + @Override + public void refresh() { + update(); + } + + @Override + public void setInput(Object input) { + if (input instanceof Calendar) { + Calendar oldInput = this.today; + this.today = (Calendar) input; + inputChanged(input, oldInput); + } + } + + @Override + protected void inputChanged(Object input, Object oldInput) { + update(); + } + + private static boolean isWeekend(Calendar date) { + int dow = date.get(DAY_OF_WEEK); + return dow == SUNDAY || dow == SATURDAY; + } + + static Calendar getCalendarStart(Calendar date, int year, int month) { + date = (Calendar) date.clone(); + date.set(year, month, 1); + while (date.get(DAY_OF_WEEK) != SUNDAY) { + date.add(DATE, -1); + } + return date; + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker2.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker2.java index c0d983cb5..024ebcd17 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker2.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker2.java @@ -1,1400 +1,1400 @@ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.DAY_OF_WEEK; -import static java.util.Calendar.MONTH; -import static java.util.Calendar.SATURDAY; -import static java.util.Calendar.SUNDAY; -import static java.util.Calendar.YEAR; -import static org.eclipse.jface.resource.JFaceResources.DEFAULT_FONT; - -import java.util.Calendar; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.GridData; -import org.eclipse.draw2d.GridLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.MouseEvent; -import org.eclipse.draw2d.MouseListener; -import org.eclipse.draw2d.MouseMotionListener; -import org.eclipse.draw2d.Viewport; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener2; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.dialogs.PopupDialog; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.viewers.SWTUtils; - -/** - * A viewer to pick a date on the calendar. - */ -public class DatePicker2 extends Viewer { - - private static final String[] MONTHS = new String[] { Messages.January, - Messages.Feburary, Messages.March, Messages.April, Messages.May, - Messages.June, Messages.July, Messages.August, Messages.September, - Messages.October, Messages.November, Messages.December }; - - private static final String[] WEEK_SYMBOLS = new String[] { Messages.Sunday, - Messages.Monday, Messages.Tuesday, Messages.Wednesday, - Messages.Thursday, Messages.Friday, Messages.Saturday }; - - private static final int FUTURE_YEARS = 7; - - private static final int PASSED_YEARS = 3; - - private static final String COLOR_TEXT = "#000000"; //$NON-NLS-1$ - - private static final String COLOR_WEEKEND = "#EE0000"; //$NON-NLS-1$ - - private static final String COLOR_SEPARATOR = "#C0C0C0"; //$NON-NLS-1$ - - private static final String COLOR_TODAY = "#ff9900"; //$NON-NLS-1$ - - private static final String COLOR_WEEK_SYMBOL = "#808080"; //$NON-NLS-1$ - - private static final String COLOR_ARROW_BORDER = "#808080"; //$NON-NLS-1$ - - private static final String COLOR_ARROW_FILL = "#C0C0C0"; //$NON-NLS-1$ - - private static final String COLOR_CANCEL = "#D80000"; //$NON-NLS-1$ - - private static final int NORMAL_ALPHA = 0xff; - - private static final int SIBLING_MONTH_ALPHA = 0x20; - - private static final int DURATION = 200; - - private static final int TOTAL_DAYS = 42; - - private static Color validColor = ColorUtils.getColor("#ffffff"); //$NON-NLS-1$ - - private static Color invalidColor = ColorUtils.getColor("#f0f0f0"); //$NON-NLS-1$ - - private class EventHandler - implements MouseListener, MouseMotionListener, Listener { - - private boolean dayPressed = false; - - private BaseFigure target = null; - - public void attach(IFigure figure) { - figure.addMouseListener(this); - figure.addMouseMotionListener(this); - } - - public void detach(IFigure figure) { - figure.removeMouseListener(this); - figure.removeMouseMotionListener(this); - } - - public void install(Control control) { - control.addListener(SWT.MouseUp, this); - control.addListener(SWT.MouseWheel, this); - control.addListener(SWT.KeyDown, this); - } - - public void uninstall(Control control) { - control.removeListener(SWT.MouseUp, this); - control.removeListener(SWT.MouseWheel, this); - control.removeListener(SWT.KeyDown, this); - } - - public void handleEvent(Event event) { - if (event.type == SWT.MouseUp) { - dayPressed = false; - if (target != null) { - final BaseFigure eventTarget = target; - target.setPressed(false); - target = null; - selected(eventTarget); - } - } else if (event.type == SWT.MouseWheel) { - if (event.count == 0) - return; - // wheel upwards, count > 0, month should decrease - // wheel downwards, count < 0, month should increase - rollMonth(event.count > 0 ? -1 : 1); - } else if (event.type == SWT.KeyDown) { - handleKeyPress(event.keyCode, event.stateMask); - } - } - - private void handleKeyPress(int key, int mask) { - if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_UP)) { - lastMonthSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_DOWN)) { - nextMonthSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_LEFT)) { - lastYearSelected(true); - } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_RIGHT)) { - nextYearSelected(true); - } - } - - public void mouseDoubleClicked(MouseEvent me) { - // do nothing - } - - public void mouseDragged(MouseEvent me) { - // do nothing - } - - public void mouseEntered(MouseEvent me) { - if (target == null) { - BaseFigure source = (BaseFigure) me.getSource(); - if (source instanceof DayFigure && dayPressed) { - source.setPressed(true); - source.setPreselected(false); - } else { - if (source == monthFigure || source == lastMonth - || source == nextMonth) { - monthFigure.setPreselected(true); - lastMonth.getContent().setVisible(true); - nextMonth.getContent().setVisible(true); - } else if (source == yearFigure || source == lastYear - || source == nextYear) { - yearFigure.setPreselected(true); - lastYear.getContent().setVisible(true); - nextYear.getContent().setVisible(true); - } - source.setPreselected(true); - } - } - } - - public void mouseExited(MouseEvent me) { - if (target == null) { - BaseFigure source = (BaseFigure) me.getSource(); - if (source instanceof DayFigure) { - source.setPreselected(false); - if (dayPressed) { - source.setPressed(false); - } - } else { - if (source == monthFigure || source == lastMonth - || source == nextMonth) { - monthFigure.setPreselected(false); - lastMonth.getContent().setVisible(false); - nextMonth.getContent().setVisible(false); - } else if (source == yearFigure || source == lastYear - || source == nextYear) { - yearFigure.setPreselected(false); - lastYear.getContent().setVisible(false); - nextYear.getContent().setVisible(false); - } - source.setPreselected(false); - } - } - } - - public void mouseHover(MouseEvent me) { - // do nothing - } - - public void mouseMoved(MouseEvent me) { - // do nothing - } - - public void mousePressed(MouseEvent me) { - BaseFigure source = (BaseFigure) me.getSource(); - source.setPressed(true); - source.setPreselected(false); - if (source instanceof DayFigure) { - dayPressed = true; - } else { - target = source; - } - } - - public void mouseReleased(MouseEvent me) { - BaseFigure source = (BaseFigure) me.getSource(); - source.setPressed(false); - if (source instanceof DayFigure) { - if (dayPressed) { - daySelected((DayFigure) me.getSource()); - } - source.setPreselected(true); - } else { - if (!source.isSelected()) { - source.setPreselected(true); - } - } - } - - } - - private class DropdownDatePicker extends PopupDialog { - - public DropdownDatePicker(Shell parent) { - super(parent, SWT.NO_TRIM, true, false, false, false, false, null, - null); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - createDatePicker(composite); - datePicker.setLayoutData(new org.eclipse.swt.layout.GridData( - SWT.FILL, SWT.FILL, true, true)); - initDatePicker(); - update(); - return composite; - } - - @Override - public boolean close() { - boolean closed = super.close(); - if (closed) { - datePicker = null; - } - return closed; - } - - @Override - protected Point getInitialLocation(Point initialSize) { - Control c = DatePicker2.this.getControl(); - org.eclipse.swt.graphics.Rectangle r = c.getBounds(); - return c.toDisplay(-2, r.height - 1); - } - - } - - private class MonthAction extends Action { - - private int month; - - public MonthAction(int month) { - super(MONTHS[month]); - this.month = month; - } - - public void run() { - monthSelected(month); - } - } - - private class YearAction extends Action { - - private int year; - - public void setYear(int year) { - this.year = year; - setText("" + year); //$NON-NLS-1$ - } - - public int getYear() { - return year; - } - - public void run() { - yearSelected(year); - } - } - - private class AnimationAdvisor implements IAnimationAdvisor { - - private int monthsToRoll = 0; - - private int yearsToRoll = 0; - - private int duration = -1; - - private int oldYear; - - private int oldMonth; - - private int newYear; - - private int newMonth; - - public void addMonthsToRoll(int count) { - monthsToRoll += count; - duration = -1; - } - - public void addYearsToRoll(int count) { - yearsToRoll += count; - duration = -1; - } - - public int getDuration() { - if (duration < 0) { - int steps = Math.abs(monthsToRoll) + Math.abs(yearsToRoll); - duration = steps == 0 ? 0 : DURATION / steps; - } - return duration; - } - - public IFigure getLayer() { - return DatePicker2.this.dateLayer; - } - - public int getMonthsToRoll() { - return monthsToRoll; - } - - public int getNewMonth() { - return newMonth; - } - - public int getNewYear() { - return newYear; - } - - public int getOldMonth() { - return oldMonth; - } - - public int getOldYear() { - return oldYear; - } - - public IFigure getPanel() { - return DatePicker2.this.datePanel; - } - - public int getYearsToRoll() { - return yearsToRoll; - } - - public void initNewDay(DayFigure figure) { - updateDayFigure(figure, oldYear, oldMonth); - } - - public void initOldDay(DayFigure figure) { - figure.setPreselected(false); - figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); - eventHandler.detach(figure); - } - - public boolean isDone() { - return monthsToRoll == 0 && yearsToRoll == 0; - } - - public void setEndMonth(int newYear, int newMonth) { - this.newYear = newYear; - this.newMonth = newMonth; - } - - public void setStartMonth(int oldYear, int oldMonth) { - this.oldYear = oldYear; - this.oldMonth = oldMonth; - } - - public void updateNewDay(DayFigure figure) { - figure.setPreselected(false); - figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); - eventHandler.attach(figure); - updateDayFigure(figure, newYear, newMonth); - } - - } - - private int style; - - private Control control; - - private FigureCanvas datePicker; - - private Composite placeholder; - - private Text yearText; - - private Text monthText; - - private Text dayText; - - private Button showDatePickerButton; - - private Label slash1; - - private Label slash2; - - private ILabelProvider dateLabelProvider; - - private DropdownDatePicker dropdownDatePicker; - - private Calendar today; - - private int currentMonth; - - private int currentYear; - - private Calendar selection; - - private IFigure dateLayer; - - private IFigure datePanel; - - private MonthFigure monthFigure; - - private YearFigure yearFigure; - - private BaseFigure todayFigure; - - private BaseFigure cancelFigure; - - private EventHandler eventHandler; - - private MenuManager monthMenu; - - private MonthAction[] monthActions; - - private MenuManager yearMenu; - - private YearAction[] yearActions; - - private ArrowFigure lastYear; - - private ArrowFigure nextYear; - - private ArrowFigure lastMonth; - - private ArrowFigure nextMonth; - - private boolean firingSelectionChange = false; - - private boolean animating = false; - - private IAnimationAdvisor animationAdvisor = new AnimationAdvisor(); - - private String oldValue = ""; //$NON-NLS-1$ - - private Calendar minTime; - - private Calendar maxTime; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a composite control which will be the parent of the new - * instance (cannot be null) - * @param style - * the style of control to construct - * @see SWT#SIMPLE - * @see SWT#DROP_DOWN - * @see SWT#CANCEL - */ - public DatePicker2(Composite parent, int style) { - this(parent, style, Calendar.getInstance()); - } - - public DatePicker2(Composite parent, int style, Calendar today) { - this.today = today; - this.currentMonth = today.get(MONTH); - this.currentYear = today.get(YEAR); - this.style = style; - if ((style & SWT.DROP_DOWN) != 0) { - createPlaceholder(parent); - this.control = placeholder; - initPlaceholder(); - } else { - createDatePicker(parent); - this.control = datePicker; - initDatePicker(); - } - update(); - } - - private void createPlaceholder(Composite parent) { - Composite composite = new Composite(parent, SWT.BORDER); - org.eclipse.swt.layout.GridLayout layout = new org.eclipse.swt.layout.GridLayout( - 6, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - composite.setBackground(validColor); - - dayText = new Text(composite, SWT.SINGLE | SWT.NONE); - org.eclipse.swt.layout.GridData dateData = new org.eclipse.swt.layout.GridData( - SWT.RIGHT, SWT.CENTER, false, false); -// dateData.widthHint = 14; - dayText.setLayoutData(dateData); - dayText.setTextLimit(2); - dayText.setBackground(dayText.getParent().getBackground()); - - slash1 = new Label(composite, SWT.NONE); - slash1.setLayoutData(new org.eclipse.swt.layout.GridData(SWT.CENTER, - SWT.CENTER, false, false)); - slash1.setBackground(slash1.getParent().getBackground()); - slash1.setText("/"); //$NON-NLS-1$ - - monthText = new Text(composite, SWT.SINGLE | SWT.NONE); - org.eclipse.swt.layout.GridData monthData = new org.eclipse.swt.layout.GridData( - SWT.CENTER, SWT.CENTER, false, false); -// monthData.widthHint = 14; - monthText.setLayoutData(monthData); - monthText.setTextLimit(2); - monthText.setBackground(monthText.getParent().getBackground()); - - slash2 = new Label(composite, SWT.NONE); - slash2.setLayoutData(new org.eclipse.swt.layout.GridData(SWT.CENTER, - SWT.CENTER, false, false)); - slash2.setBackground(slash2.getParent().getBackground()); - slash2.setText("/"); //$NON-NLS-1$ - - yearText = new Text(composite, SWT.SINGLE | SWT.NONE); - org.eclipse.swt.layout.GridData yearData = new org.eclipse.swt.layout.GridData( - SWT.LEFT, SWT.CENTER, false, false); -// yearData.widthHint = 28; - yearText.setLayoutData(yearData); - yearText.setTextLimit(4); - yearText.setBackground(yearText.getParent().getBackground()); - - showDatePickerButton = new Button(composite, SWT.ARROW | SWT.DOWN); - showDatePickerButton.setLayoutData(new org.eclipse.swt.layout.GridData( - SWT.LEFT, SWT.CENTER, false, false)); - - filterInput(); - - this.placeholder = composite; - } - - private void filterInput() { - checkInput(dayText); - checkInput(monthText); - checkInput(yearText); - } - - private void checkInput(final Text field) { - KeyListener keyListener = new KeyAdapter() { - - @Override - public void keyPressed(KeyEvent e) { - switch (e.character) { - case SWT.ESC: - field.setText(oldValue); - field.getParent().forceFocus(); - break; - - case SWT.CR: - field.getParent().forceFocus(); - break; - } - } - }; - - FocusListener focusListener = new FocusListener() { - - public void focusLost(FocusEvent e) { - editField(field, oldValue); - oldValue = ""; //$NON-NLS-1$ - } - - public void focusGained(FocusEvent e) { - oldValue = field.getText(); - field.selectAll(); - } - }; - - field.addKeyListener(keyListener); - field.addFocusListener(focusListener); - } - - private void editField(Text field, String oldValue) { - String text = field.getText(); - if (text.equals(oldValue)) { - return; - } - if ("".equals(text)) { //$NON-NLS-1$ - field.setText(oldValue); - return; - } - - int value = 0; - text = text.trim(); - Pattern re = Pattern.compile("^\\d+$"); //$NON-NLS-1$ - Matcher m = re.matcher(text); - if (!m.matches()) { - field.setText(oldValue); - return; - } - - value = parseInt(m.group()); - int calendarField = (field == yearText ? Calendar.YEAR - : (field == monthText ? Calendar.MONTH - : Calendar.DAY_OF_MONTH)); - if (calendarField == Calendar.MONTH) { - value -= 1; - } - - Calendar newTime = Calendar.getInstance(); - newTime.setTimeInMillis(getSelectedDate().getTimeInMillis()); - newTime.set(calendarField, value); - newTime = checkTime(newTime); - changeDate(newTime); - - refresh(); - } - - private int parseInt(String s) { - if (s != null && !"".equals(s)) {//$NON-NLS-1$ - try { - return Integer.parseInt(s, 10); - } catch (NumberFormatException e) { - } - } - return 0; - } - - private Calendar checkTime(Calendar newTime) { - final Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(newTime.getTimeInMillis()); - if (calendar.before(minTime)) { - MessageDialog.openInformation(Display.getDefault().getActiveShell(), - Messages.TimeCheckInvalid_label, - Messages.TimeCheckInvalidSmall_message); - calendar.setTimeInMillis(minTime.getTimeInMillis()); - } else if (calendar.after(maxTime)) { - MessageDialog.openConfirm(Display.getDefault().getActiveShell(), - Messages.TimeCheckInvalid_label, - Messages.TimeCheckInvalidBig_message); - calendar.setTimeInMillis(maxTime.getTimeInMillis()); - } - - return calendar; - } - - private void createDatePicker(Composite parent) { - this.datePicker = new FigureCanvas(parent); - } - - public void setLabelProvider(ILabelProvider labelProvider) { - this.dateLabelProvider = labelProvider; - update(); - } - - public ILabelProvider getLabelProvider() { - if (this.dateLabelProvider == null) { - this.dateLabelProvider = new DateLabelProvider(); - } - return this.dateLabelProvider; - } - - public Control getControl() { - return control; - } - - public FigureCanvas getDatePicker() { - return datePicker; - } - - public void setBackground(Color color) { - if (control != null && !control.isDisposed()) { - control.setBackground(color); - } - } - - public void setEnabled(boolean enabled) { - if (placeholder != null) { - placeholder.setEnabled(enabled); - placeholder.setBackground(enabled ? validColor : invalidColor); - yearText.setEnabled(enabled); - yearText.setBackground(enabled ? validColor : invalidColor); - monthText.setEnabled(enabled); - monthText.setBackground(enabled ? validColor : invalidColor); - dayText.setEnabled(enabled); - dayText.setBackground(enabled ? validColor : invalidColor); - slash1.setEnabled(enabled); - slash1.setBackground(enabled ? validColor : invalidColor); - slash2.setEnabled(enabled); - slash2.setBackground(enabled ? validColor : invalidColor); - showDatePickerButton.setEnabled(enabled); - } - } - - public Composite getPlaceholder() { - return placeholder; - } - - public ISelection getSelection() { - return new DateSelection(selection); - } - - @Override - public void setSelection(ISelection selection) { - setSelection(selection, true); - } - - @Override - public void setSelection(ISelection selection, boolean reveal) { - if (selection instanceof DateSelection) { - setDateSelection(((DateSelection) selection).getDate(), reveal); - } else if (selection instanceof IStructuredSelection) { - Object sel = ((IStructuredSelection) selection).getFirstElement(); - if (sel instanceof Calendar) { - setDateSelection((Calendar) sel, reveal); - } - } - } - - public void setDateSelection(Calendar date, boolean reveal) { - changeDate(date); - if (reveal && date != null) { - changeCalendar(date.get(YEAR), date.get(MONTH)); - } - update(); - } - - private void initPlaceholder() { - showDatePickerButton.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - if (dropdownDatePicker == null - || dropdownDatePicker.getShell() == null - || dropdownDatePicker.getShell().isDisposed() - || !dropdownDatePicker.isClosing()) - showDropdown(); - } - - }); - } - - private void showDropdown() { - placeholder.forceFocus(); - createDropdownDatePicker(); - dropdownDatePicker.open(); - Shell shell = dropdownDatePicker.getShell(); - if (shell != null && !shell.isDisposed()) { - shell.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - if (placeholder != null && !placeholder.isDisposed()) { - placeholder.forceFocus(); - } - } - }); - } - } - - /** - * Shows the drop-down menu if this date picker is created with - * SWT.DROP_DOWN style bit. - */ - public void open() { - showDropdown(); - } - - private void createDropdownDatePicker() { - if (dropdownDatePicker != null) - return; - dropdownDatePicker = new DropdownDatePicker(control.getShell()); - } - - private void initDatePicker() { - datePicker.setScrollBarVisibility(FigureCanvas.NEVER); - - eventHandler = new EventHandler(); - eventHandler.install(datePicker); - datePicker.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - eventHandler.uninstall(datePicker); - } - }); - - Viewport viewport = new Viewport(true); - viewport.setContentsTracksHeight(true); - viewport.setContentsTracksWidth(true); - datePicker.setViewport(viewport); - - IFigure container = new Layer(); - datePicker.setContents(container); - - GridLayout containerLayout = new GridLayout(1, true); - containerLayout.horizontalSpacing = 3; - containerLayout.verticalSpacing = 3; - containerLayout.marginHeight = 3; - containerLayout.marginWidth = 3; - container.setLayoutManager(containerLayout); - createTopPanel(container); - createSeparator(container); - createWeekPanel(container); - createDaysPanel(container); - createSeparator(container); - createBottomPanel(container); - } - - private void createTopPanel(IFigure parent) { - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - - GridLayout panelLayout = new GridLayout(12, true); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 0; - panelLayout.marginWidth = 0; - panel.setLayoutManager(panelLayout); - - lastMonth = createArrowFigure(panel, ArrowFigure.UP); - monthFigure = createMonthFigure(panel); - nextMonth = createArrowFigure(panel, ArrowFigure.DOWN); - lastYear = createArrowFigure(panel, ArrowFigure.LEFT); - yearFigure = createYearFigure(panel); - nextYear = createArrowFigure(panel, ArrowFigure.RIGHT); - } - - private MonthFigure createMonthFigure(IFigure parent) { - MonthFigure figure = new MonthFigure(); - figure.setTextCandidates(MONTHS); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - constraint.horizontalSpan = 5; - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - private YearFigure createYearFigure(IFigure parent) { - YearFigure figure = new YearFigure(); - figure.setTextCandidates(new String[] { "0000" }); //$NON-NLS-1$ - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - constraint.horizontalSpan = 3; - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - private ArrowFigure createArrowFigure(IFigure parent, int orientation) { - ArrowFigure arrow = new ArrowFigure(); - arrow.setOrientation(orientation); - arrow.setForegroundColor(ColorUtils.getColor(COLOR_ARROW_BORDER)); - arrow.setBackgroundColor(ColorUtils.getColor(COLOR_ARROW_FILL)); - arrow.getContent().setVisible(false); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.add(arrow, constraint); - eventHandler.attach(arrow); - return arrow; - } - - private void createSeparator(IFigure parent) { - HorizontalLine line = new HorizontalLine(); - line.setMargin(3); - line.setForegroundColor(ColorUtils.getColor(COLOR_SEPARATOR)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); - constraint.heightHint = 3; - parent.add(line, constraint); - } - - private void createWeekPanel(IFigure parent) { - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - GridLayout panelLayout = new GridLayout(7, true); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 0; - panelLayout.marginWidth = 0; - panel.setLayoutManager(panelLayout); - Font symbolFont = FontUtils.getRelativeHeight(DEFAULT_FONT, -2); - for (int i = 0; i < 7; i++) { - TextLayer symbol = new TextLayer(); - symbol.setFont(symbolFont); - symbol.setText(WEEK_SYMBOLS[i]); - if (i == 0 || i == 6) { - symbol.setForegroundColor(ColorUtils.getColor(COLOR_WEEKEND)); - } else { - symbol.setForegroundColor( - ColorUtils.getColor(COLOR_WEEK_SYMBOL)); - } - GridData symbolConstraint = new GridData(SWT.FILL, SWT.FILL, true, - true); - panel.add(symbol, symbolConstraint); - } - } - - private void createDaysPanel(IFigure parent) { - dateLayer = new Layer(); - GridData layerConstraint = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.add(dateLayer, layerConstraint); - dateLayer.setLayoutManager(new ConstraintStackLayout()); - - datePanel = new Layer(); - dateLayer.add(datePanel, null); - datePanel.setLayoutManager(new DatePanelLayout()); - for (int i = 0; i < TOTAL_DAYS; i++) { - DayFigure dayFigure = new DayFigure(); - eventHandler.attach(dayFigure); - datePanel.add(dayFigure); - } - } - - private void createBottomPanel(IFigure parent) { - boolean hasCancel = (style & SWT.CANCEL) != 0; - IFigure panel = new Layer(); - GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, - false); - parent.add(panel, panelConstraint); - GridLayout panelLayout = new GridLayout(hasCancel ? 2 : 1, false); - panelLayout.horizontalSpacing = 0; - panelLayout.verticalSpacing = 0; - panelLayout.marginHeight = 0; - panelLayout.marginWidth = 0; - panel.setLayoutManager(panelLayout); - - todayFigure = createTodayFigure(panel); - if (hasCancel) { - cancelFigure = createCancelFigure(panel); - } - } - - private BaseFigure createTodayFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); - figure.setForegroundColor(ColorUtils.getColor(COLOR_TODAY)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - private BaseFigure createCancelFigure(IFigure parent) { - BaseFigure figure = new BaseFigure(); - figure.setText(" X "); //$NON-NLS-1$ - figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); - figure.setForegroundColor(ColorUtils.getColor(COLOR_CANCEL)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); - parent.add(figure, constraint); - eventHandler.attach(figure); - return figure; - } - - private Calendar getSelectedDate() { - return selection; - } - - private void changeCalendar(int newYear, int newMonth) { - changeCalendar(newYear, newMonth, false); - } - - private void changeCalendar(int newYear, int newMonth, boolean smooth) { - boolean calendarChanged = newMonth != currentMonth - || newYear != currentYear; - if (!calendarChanged) - return; - if (smooth) { - if (datePicker != null) { - int months = (newYear - currentYear) * 12 + newMonth - - currentMonth; - animationAdvisor.addYearsToRoll(months / 12); - animationAdvisor.addMonthsToRoll(months % 12); - performRollCalendarAnimation(currentYear, currentMonth); - } - currentYear = newYear; - currentMonth = newMonth; - } else { - currentYear = newYear; - currentMonth = newMonth; - if (datePicker != null) { - updateCalendar(); - } - updateSelection(); - } - } - - private void updateCalendar() { - today = Calendar.getInstance(); - updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); - monthFigure.setMonth(currentMonth); - yearFigure.setYear(currentYear); - todayFigure.setText(Messages.TodayPattern); -// todayFigure.setText(NLS.bind(Messages.TodayPattern, -// String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ - } - - private void updateDayFigures(List dayFigures, int year, int month) { - Calendar date = getCalendarStart(today, year, month); - for (int i = 0; i < dayFigures.size(); i++) { - DayFigure dayFigure = (DayFigure) dayFigures.get(i); - date = (Calendar) date.clone(); - if (i > 0) - date.add(DATE, 1); - dayFigure.setDate(date); - updateDayFigure(dayFigure, year, month); - } - } - - private void updateDayFigure(DayFigure figure, int year, int month) { - figure.setFont(FontUtils.getBold(DEFAULT_FONT)); - Calendar date = figure.getDate(); - if (isSameDay(date, today)) { - figure.setForegroundColor(ColorUtils.getColor(COLOR_TODAY)); - } else if (isWeekend(date)) { - figure.setForegroundColor(ColorUtils.getColor(COLOR_WEEKEND)); - } else { - figure.setForegroundColor(ColorUtils.getColor(COLOR_TEXT)); - } - if (date.get(MONTH) == month && date.get(YEAR) == year) { - figure.setTextAlpha(NORMAL_ALPHA); - } else { - figure.setTextAlpha(SIBLING_MONTH_ALPHA); - } - } - - private void updateSelection() { - if (datePicker != null) { - for (Object figure : datePanel.getChildren()) { - DayFigure dayFigure = (DayFigure) figure; - dayFigure.setSelected( - isSameDay(dayFigure.getDate(), getSelectedDate())); - } - } - if (placeholder != null && selection != null) { - String day = String.format("%1$td", selection); //$NON-NLS-1$ - String month = String.format("%1$tm", selection); //$NON-NLS-1$ - String year = String.format("%1$tY", selection); //$NON-NLS-1$ - - dayText.setText(day); - monthText.setText(month); - yearText.setText(year); - } - - placeholder.layout(); - } - - private void update() { - if (datePicker != null) { - updateCalendar(); - } - updateSelection(); - } - - private void performRollCalendarAnimation(int oldYear, int oldMonth) { - if (animating) - return; - - animating = true; - - final int newYear, newMonth; - final CalendarAnimation animation; - if (animationAdvisor.getYearsToRoll() != 0) { - if (animationAdvisor.getYearsToRoll() < 0) { - newYear = oldYear - 1; - newMonth = oldMonth; - animation = new LastYearAnimation(animationAdvisor); - } else { - newYear = oldYear + 1; - newMonth = oldMonth; - animation = new NextYearAnimation(animationAdvisor); - } - } else if (animationAdvisor.getMonthsToRoll() != 0) { - if (animationAdvisor.getMonthsToRoll() < 0) { - newYear = oldMonth <= 0 ? oldYear - 1 : oldYear; - newMonth = oldMonth <= 0 ? 11 : oldMonth - 1; - animation = new LastMonthAnimation(animationAdvisor); - } else { - newYear = oldMonth >= 11 ? oldYear + 1 : oldYear; - newMonth = oldMonth >= 11 ? 0 : oldMonth + 1; - animation = new NextMonthAnimation(animationAdvisor); - } - } else { - newYear = oldYear; - newMonth = oldMonth; - animation = null; - } - monthFigure.setMonth(newMonth); - yearFigure.setYear(newYear); - if (animation != null) { - animationAdvisor.setStartMonth(oldYear, oldMonth); - animationAdvisor.setEndMonth(newYear, newMonth); - animation.callback(new Runnable() { - public void run() { - datePanel = animation.getNewPanel(); - if (animationAdvisor.isDone()) { - animating = false; - } else { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - animating = false; - performRollCalendarAnimation(newYear, newMonth); - } - }); - } - - } - }).start(); - } - } - - private void selected(final BaseFigure target) { - if (target instanceof MonthFigure) { - target.setSelected(true); - showMonthPopup(); - } else if (target instanceof YearFigure) { - target.setSelected(true); - showYearPopup(); - } else if (target == todayFigure) { - todaySelected(); - } else if (target == lastMonth) { - lastMonthSelected(true); - } else if (target == nextMonth) { - nextMonthSelected(true); - } else if (target == lastYear) { - lastYearSelected(true); - } else if (target == nextYear) { - nextYearSelected(true); - } else if (target == cancelFigure) { - cancelSelected(); - } - } - - private void showMonthPopup() { - createMonthMenu(); - for (int month = 0; month < monthActions.length; month++) { - MonthAction action = monthActions[month]; - action.setChecked(month == currentMonth); - } - Rectangle b = monthFigure.getBounds(); - Point loc = control.toDisplay(b.x, b.y + b.height); - final Menu menu = monthMenu.createContextMenu(control); - menu.setLocation(loc.x + 10, loc.y + 1); - menu.setVisible(true); - } - - private void createMonthMenu() { - if (monthMenu != null) - return; - monthMenu = new MenuManager(); - monthMenu.addMenuListener(new IMenuListener2() { - public void menuAboutToShow(IMenuManager manager) { - // do nothing - } - - public void menuAboutToHide(IMenuManager manager) { - monthFigure.setSelected(false); - } - }); - monthActions = new MonthAction[12]; - for (int month = 0; month < 12; month++) { - MonthAction action = new MonthAction(month); - monthMenu.add(action); - monthActions[month] = action; - } - } - - private void showYearPopup() { - createYearMenu(); - int start = currentYear - PASSED_YEARS; - for (int year = 0; year < yearActions.length; year++) { - YearAction action = yearActions[year]; - action.setYear(start + year); - action.setChecked(action.getYear() == currentYear); - } - Rectangle b = yearFigure.getBounds(); - Point loc = control.toDisplay(b.x, b.y + b.height); - Menu menu = yearMenu.createContextMenu(control); - menu.setLocation(loc.x, loc.y + 1); - menu.setVisible(true); - } - - private void createYearMenu() { - if (yearMenu != null) - return; - yearMenu = new MenuManager(); - yearMenu.addMenuListener(new IMenuListener2() { - public void menuAboutToShow(IMenuManager manager) { - // do nothing - } - - public void menuAboutToHide(IMenuManager manager) { - yearFigure.setSelected(false); - } - }); - yearActions = new YearAction[FUTURE_YEARS + PASSED_YEARS + 1]; - for (int year = 0; year < yearActions.length; year++) { - YearAction action = new YearAction(); - yearMenu.add(action); - yearActions[year] = action; - } - } - - private void monthSelected(int month) { - changeCalendar(currentYear, month); - } - - private void yearSelected(int year) { - changeCalendar(year, currentMonth); - } - - private void daySelected(DayFigure day) { - Calendar date = day.getDate(); - changeDate(date); - if (date != null && date.get(MONTH) != currentMonth) { - changeCalendar(date.get(YEAR), date.get(MONTH), true); - } - } - - private void todaySelected() { - changeDate(today); - changeCalendar(today.get(YEAR), today.get(MONTH)); - } - - private void lastMonthSelected(boolean smooth) { - if (currentMonth <= 0) { - changeCalendar(currentYear - 1, 11, smooth); - } else { - changeCalendar(currentYear, currentMonth - 1, smooth); - } - } - - private void nextMonthSelected(boolean smooth) { - if (currentMonth >= 11) { - changeCalendar(currentYear + 1, 0, smooth); - } else { - changeCalendar(currentYear, currentMonth + 1, smooth); - } - } - - private void lastYearSelected(boolean smooth) { - changeCalendar(currentYear - 1, currentMonth, smooth); - } - - private void nextYearSelected(boolean smooth) { - changeCalendar(currentYear + 1, currentMonth, smooth); - } - - private void cancelSelected() { - changeDate(null); - } - - private void rollMonth(int count) { - Calendar temp = (Calendar) today.clone(); - temp.set(YEAR, currentYear); - temp.set(MONTH, currentMonth); - temp.add(MONTH, count); - changeCalendar(temp.get(YEAR), temp.get(MONTH), true); - } - - private void changeDate(Calendar date) { - if (date != null) { - date.set(Calendar.MILLISECOND, 0); - } - this.selection = date; - updateSelection(); - - if (firingSelectionChange) - return; - firingSelectionChange = true; - if (dropdownDatePicker != null) { - control.getDisplay().asyncExec(new Runnable() { - public void run() { - dropdownDatePicker.close(); - } - }); - } - fireSelectionChanged( - new SelectionChangedEvent(DatePicker2.this, getSelection())); - firingSelectionChange = false; - } - - @Override - public Object getInput() { - return today; - } - - @Override - public void refresh() { - update(); - } - - @Override - public void setInput(Object input) { - if (input instanceof Calendar) { - Calendar oldInput = this.today; - this.today = (Calendar) input; - inputChanged(input, oldInput); - } - } - - @Override - protected void inputChanged(Object input, Object oldInput) { - update(); - } - - public void setMinTime(Calendar minTime) { - if (minTime != null) { - minTime.set(Calendar.MILLISECOND, 0); - this.minTime = minTime; - } - } - - public Calendar getMinTime() { - return minTime; - } - - public void setMaxTime(Calendar maxTime) { - if (maxTime != null) { - maxTime.set(Calendar.MILLISECOND, 0); - this.maxTime = maxTime; - } - } - - public Calendar getMaxTime() { - return maxTime; - } - - private static boolean isWeekend(Calendar date) { - int dow = date.get(DAY_OF_WEEK); - return dow == SUNDAY || dow == SATURDAY; - } - - private static Calendar getCalendarStart(Calendar date, int year, - int month) { - date = (Calendar) date.clone(); - date.set(year, month, 1); - while (date.get(DAY_OF_WEEK) != SUNDAY) { - date.add(DATE, -1); - } - return date; - } - - private static boolean isSameDay(Calendar date1, Calendar date2) { - if (date1 == null) - return date2 == null; - if (date2 == null) - return false; - return date1.get(DATE) == date2.get(DATE) - && date1.get(MONTH) == date2.get(MONTH) - && date1.get(YEAR) == date2.get(YEAR); - } - -} +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.DAY_OF_WEEK; +import static java.util.Calendar.MONTH; +import static java.util.Calendar.SATURDAY; +import static java.util.Calendar.SUNDAY; +import static java.util.Calendar.YEAR; +import static org.eclipse.jface.resource.JFaceResources.DEFAULT_FONT; + +import java.util.Calendar; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.GridData; +import org.eclipse.draw2d.GridLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.MouseListener; +import org.eclipse.draw2d.MouseMotionListener; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener2; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.dialogs.PopupDialog; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.viewers.SWTUtils; + +/** + * A viewer to pick a date on the calendar. + */ +public class DatePicker2 extends Viewer { + + private static final String[] MONTHS = new String[] { Messages.January, + Messages.Feburary, Messages.March, Messages.April, Messages.May, + Messages.June, Messages.July, Messages.August, Messages.September, + Messages.October, Messages.November, Messages.December }; + + private static final String[] WEEK_SYMBOLS = new String[] { Messages.Sunday, + Messages.Monday, Messages.Tuesday, Messages.Wednesday, + Messages.Thursday, Messages.Friday, Messages.Saturday }; + + private static final int FUTURE_YEARS = 7; + + private static final int PASSED_YEARS = 3; + + private static final String COLOR_TEXT = "#000000"; //$NON-NLS-1$ + + private static final String COLOR_WEEKEND = "#EE0000"; //$NON-NLS-1$ + + private static final String COLOR_SEPARATOR = "#C0C0C0"; //$NON-NLS-1$ + + private static final String COLOR_TODAY = "#ff9900"; //$NON-NLS-1$ + + private static final String COLOR_WEEK_SYMBOL = "#808080"; //$NON-NLS-1$ + + private static final String COLOR_ARROW_BORDER = "#808080"; //$NON-NLS-1$ + + private static final String COLOR_ARROW_FILL = "#C0C0C0"; //$NON-NLS-1$ + + private static final String COLOR_CANCEL = "#D80000"; //$NON-NLS-1$ + + private static final int NORMAL_ALPHA = 0xff; + + private static final int SIBLING_MONTH_ALPHA = 0x20; + + private static final int DURATION = 200; + + private static final int TOTAL_DAYS = 42; + + private static Color validColor = ColorUtils.getColor("#ffffff"); //$NON-NLS-1$ + + private static Color invalidColor = ColorUtils.getColor("#f0f0f0"); //$NON-NLS-1$ + + private class EventHandler + implements MouseListener, MouseMotionListener, Listener { + + private boolean dayPressed = false; + + private BaseFigure target = null; + + public void attach(IFigure figure) { + figure.addMouseListener(this); + figure.addMouseMotionListener(this); + } + + public void detach(IFigure figure) { + figure.removeMouseListener(this); + figure.removeMouseMotionListener(this); + } + + public void install(Control control) { + control.addListener(SWT.MouseUp, this); + control.addListener(SWT.MouseWheel, this); + control.addListener(SWT.KeyDown, this); + } + + public void uninstall(Control control) { + control.removeListener(SWT.MouseUp, this); + control.removeListener(SWT.MouseWheel, this); + control.removeListener(SWT.KeyDown, this); + } + + public void handleEvent(Event event) { + if (event.type == SWT.MouseUp) { + dayPressed = false; + if (target != null) { + final BaseFigure eventTarget = target; + target.setPressed(false); + target = null; + selected(eventTarget); + } + } else if (event.type == SWT.MouseWheel) { + if (event.count == 0) + return; + // wheel upwards, count > 0, month should decrease + // wheel downwards, count < 0, month should increase + rollMonth(event.count > 0 ? -1 : 1); + } else if (event.type == SWT.KeyDown) { + handleKeyPress(event.keyCode, event.stateMask); + } + } + + private void handleKeyPress(int key, int mask) { + if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_UP)) { + lastMonthSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_DOWN)) { + nextMonthSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_LEFT)) { + lastYearSelected(true); + } else if (SWTUtils.matchKey(mask, key, 0, SWT.ARROW_RIGHT)) { + nextYearSelected(true); + } + } + + public void mouseDoubleClicked(MouseEvent me) { + // do nothing + } + + public void mouseDragged(MouseEvent me) { + // do nothing + } + + public void mouseEntered(MouseEvent me) { + if (target == null) { + BaseFigure source = (BaseFigure) me.getSource(); + if (source instanceof DayFigure && dayPressed) { + source.setPressed(true); + source.setPreselected(false); + } else { + if (source == monthFigure || source == lastMonth + || source == nextMonth) { + monthFigure.setPreselected(true); + lastMonth.getContent().setVisible(true); + nextMonth.getContent().setVisible(true); + } else if (source == yearFigure || source == lastYear + || source == nextYear) { + yearFigure.setPreselected(true); + lastYear.getContent().setVisible(true); + nextYear.getContent().setVisible(true); + } + source.setPreselected(true); + } + } + } + + public void mouseExited(MouseEvent me) { + if (target == null) { + BaseFigure source = (BaseFigure) me.getSource(); + if (source instanceof DayFigure) { + source.setPreselected(false); + if (dayPressed) { + source.setPressed(false); + } + } else { + if (source == monthFigure || source == lastMonth + || source == nextMonth) { + monthFigure.setPreselected(false); + lastMonth.getContent().setVisible(false); + nextMonth.getContent().setVisible(false); + } else if (source == yearFigure || source == lastYear + || source == nextYear) { + yearFigure.setPreselected(false); + lastYear.getContent().setVisible(false); + nextYear.getContent().setVisible(false); + } + source.setPreselected(false); + } + } + } + + public void mouseHover(MouseEvent me) { + // do nothing + } + + public void mouseMoved(MouseEvent me) { + // do nothing + } + + public void mousePressed(MouseEvent me) { + BaseFigure source = (BaseFigure) me.getSource(); + source.setPressed(true); + source.setPreselected(false); + if (source instanceof DayFigure) { + dayPressed = true; + } else { + target = source; + } + } + + public void mouseReleased(MouseEvent me) { + BaseFigure source = (BaseFigure) me.getSource(); + source.setPressed(false); + if (source instanceof DayFigure) { + if (dayPressed) { + daySelected((DayFigure) me.getSource()); + } + source.setPreselected(true); + } else { + if (!source.isSelected()) { + source.setPreselected(true); + } + } + } + + } + + private class DropdownDatePicker extends PopupDialog { + + public DropdownDatePicker(Shell parent) { + super(parent, SWT.NO_TRIM, true, false, false, false, false, null, + null); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + createDatePicker(composite); + datePicker.setLayoutData(new org.eclipse.swt.layout.GridData( + SWT.FILL, SWT.FILL, true, true)); + initDatePicker(); + update(); + return composite; + } + + @Override + public boolean close() { + boolean closed = super.close(); + if (closed) { + datePicker = null; + } + return closed; + } + + @Override + protected Point getInitialLocation(Point initialSize) { + Control c = DatePicker2.this.getControl(); + org.eclipse.swt.graphics.Rectangle r = c.getBounds(); + return c.toDisplay(-2, r.height - 1); + } + + } + + private class MonthAction extends Action { + + private int month; + + public MonthAction(int month) { + super(MONTHS[month]); + this.month = month; + } + + public void run() { + monthSelected(month); + } + } + + private class YearAction extends Action { + + private int year; + + public void setYear(int year) { + this.year = year; + setText("" + year); //$NON-NLS-1$ + } + + public int getYear() { + return year; + } + + public void run() { + yearSelected(year); + } + } + + private class AnimationAdvisor implements IAnimationAdvisor { + + private int monthsToRoll = 0; + + private int yearsToRoll = 0; + + private int duration = -1; + + private int oldYear; + + private int oldMonth; + + private int newYear; + + private int newMonth; + + public void addMonthsToRoll(int count) { + monthsToRoll += count; + duration = -1; + } + + public void addYearsToRoll(int count) { + yearsToRoll += count; + duration = -1; + } + + public int getDuration() { + if (duration < 0) { + int steps = Math.abs(monthsToRoll) + Math.abs(yearsToRoll); + duration = steps == 0 ? 0 : DURATION / steps; + } + return duration; + } + + public IFigure getLayer() { + return DatePicker2.this.dateLayer; + } + + public int getMonthsToRoll() { + return monthsToRoll; + } + + public int getNewMonth() { + return newMonth; + } + + public int getNewYear() { + return newYear; + } + + public int getOldMonth() { + return oldMonth; + } + + public int getOldYear() { + return oldYear; + } + + public IFigure getPanel() { + return DatePicker2.this.datePanel; + } + + public int getYearsToRoll() { + return yearsToRoll; + } + + public void initNewDay(DayFigure figure) { + updateDayFigure(figure, oldYear, oldMonth); + } + + public void initOldDay(DayFigure figure) { + figure.setPreselected(false); + figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); + eventHandler.detach(figure); + } + + public boolean isDone() { + return monthsToRoll == 0 && yearsToRoll == 0; + } + + public void setEndMonth(int newYear, int newMonth) { + this.newYear = newYear; + this.newMonth = newMonth; + } + + public void setStartMonth(int oldYear, int oldMonth) { + this.oldYear = oldYear; + this.oldMonth = oldMonth; + } + + public void updateNewDay(DayFigure figure) { + figure.setPreselected(false); + figure.setSelected(isSameDay(figure.getDate(), getSelectedDate())); + eventHandler.attach(figure); + updateDayFigure(figure, newYear, newMonth); + } + + } + + private int style; + + private Control control; + + private FigureCanvas datePicker; + + private Composite placeholder; + + private Text yearText; + + private Text monthText; + + private Text dayText; + + private Button showDatePickerButton; + + private Label slash1; + + private Label slash2; + + private ILabelProvider dateLabelProvider; + + private DropdownDatePicker dropdownDatePicker; + + private Calendar today; + + private int currentMonth; + + private int currentYear; + + private Calendar selection; + + private IFigure dateLayer; + + private IFigure datePanel; + + private MonthFigure monthFigure; + + private YearFigure yearFigure; + + private BaseFigure todayFigure; + + private BaseFigure cancelFigure; + + private EventHandler eventHandler; + + private MenuManager monthMenu; + + private MonthAction[] monthActions; + + private MenuManager yearMenu; + + private YearAction[] yearActions; + + private ArrowFigure lastYear; + + private ArrowFigure nextYear; + + private ArrowFigure lastMonth; + + private ArrowFigure nextMonth; + + private boolean firingSelectionChange = false; + + private boolean animating = false; + + private IAnimationAdvisor animationAdvisor = new AnimationAdvisor(); + + private String oldValue = ""; //$NON-NLS-1$ + + private Calendar minTime; + + private Calendar maxTime; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a composite control which will be the parent of the new + * instance (cannot be null) + * @param style + * the style of control to construct + * @see SWT#SIMPLE + * @see SWT#DROP_DOWN + * @see SWT#CANCEL + */ + public DatePicker2(Composite parent, int style) { + this(parent, style, Calendar.getInstance()); + } + + public DatePicker2(Composite parent, int style, Calendar today) { + this.today = today; + this.currentMonth = today.get(MONTH); + this.currentYear = today.get(YEAR); + this.style = style; + if ((style & SWT.DROP_DOWN) != 0) { + createPlaceholder(parent); + this.control = placeholder; + initPlaceholder(); + } else { + createDatePicker(parent); + this.control = datePicker; + initDatePicker(); + } + update(); + } + + private void createPlaceholder(Composite parent) { + Composite composite = new Composite(parent, SWT.BORDER); + org.eclipse.swt.layout.GridLayout layout = new org.eclipse.swt.layout.GridLayout( + 6, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite.setBackground(validColor); + + dayText = new Text(composite, SWT.SINGLE | SWT.NONE); + org.eclipse.swt.layout.GridData dateData = new org.eclipse.swt.layout.GridData( + SWT.RIGHT, SWT.CENTER, false, false); +// dateData.widthHint = 14; + dayText.setLayoutData(dateData); + dayText.setTextLimit(2); + dayText.setBackground(dayText.getParent().getBackground()); + + slash1 = new Label(composite, SWT.NONE); + slash1.setLayoutData(new org.eclipse.swt.layout.GridData(SWT.CENTER, + SWT.CENTER, false, false)); + slash1.setBackground(slash1.getParent().getBackground()); + slash1.setText("/"); //$NON-NLS-1$ + + monthText = new Text(composite, SWT.SINGLE | SWT.NONE); + org.eclipse.swt.layout.GridData monthData = new org.eclipse.swt.layout.GridData( + SWT.CENTER, SWT.CENTER, false, false); +// monthData.widthHint = 14; + monthText.setLayoutData(monthData); + monthText.setTextLimit(2); + monthText.setBackground(monthText.getParent().getBackground()); + + slash2 = new Label(composite, SWT.NONE); + slash2.setLayoutData(new org.eclipse.swt.layout.GridData(SWT.CENTER, + SWT.CENTER, false, false)); + slash2.setBackground(slash2.getParent().getBackground()); + slash2.setText("/"); //$NON-NLS-1$ + + yearText = new Text(composite, SWT.SINGLE | SWT.NONE); + org.eclipse.swt.layout.GridData yearData = new org.eclipse.swt.layout.GridData( + SWT.LEFT, SWT.CENTER, false, false); +// yearData.widthHint = 28; + yearText.setLayoutData(yearData); + yearText.setTextLimit(4); + yearText.setBackground(yearText.getParent().getBackground()); + + showDatePickerButton = new Button(composite, SWT.ARROW | SWT.DOWN); + showDatePickerButton.setLayoutData(new org.eclipse.swt.layout.GridData( + SWT.LEFT, SWT.CENTER, false, false)); + + filterInput(); + + this.placeholder = composite; + } + + private void filterInput() { + checkInput(dayText); + checkInput(monthText); + checkInput(yearText); + } + + private void checkInput(final Text field) { + KeyListener keyListener = new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + switch (e.character) { + case SWT.ESC: + field.setText(oldValue); + field.getParent().forceFocus(); + break; + + case SWT.CR: + field.getParent().forceFocus(); + break; + } + } + }; + + FocusListener focusListener = new FocusListener() { + + public void focusLost(FocusEvent e) { + editField(field, oldValue); + oldValue = ""; //$NON-NLS-1$ + } + + public void focusGained(FocusEvent e) { + oldValue = field.getText(); + field.selectAll(); + } + }; + + field.addKeyListener(keyListener); + field.addFocusListener(focusListener); + } + + private void editField(Text field, String oldValue) { + String text = field.getText(); + if (text.equals(oldValue)) { + return; + } + if ("".equals(text)) { //$NON-NLS-1$ + field.setText(oldValue); + return; + } + + int value = 0; + text = text.trim(); + Pattern re = Pattern.compile("^\\d+$"); //$NON-NLS-1$ + Matcher m = re.matcher(text); + if (!m.matches()) { + field.setText(oldValue); + return; + } + + value = parseInt(m.group()); + int calendarField = (field == yearText ? Calendar.YEAR + : (field == monthText ? Calendar.MONTH + : Calendar.DAY_OF_MONTH)); + if (calendarField == Calendar.MONTH) { + value -= 1; + } + + Calendar newTime = Calendar.getInstance(); + newTime.setTimeInMillis(getSelectedDate().getTimeInMillis()); + newTime.set(calendarField, value); + newTime = checkTime(newTime); + changeDate(newTime); + + refresh(); + } + + private int parseInt(String s) { + if (s != null && !"".equals(s)) {//$NON-NLS-1$ + try { + return Integer.parseInt(s, 10); + } catch (NumberFormatException e) { + } + } + return 0; + } + + private Calendar checkTime(Calendar newTime) { + final Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(newTime.getTimeInMillis()); + if (calendar.before(minTime)) { + MessageDialog.openInformation(Display.getDefault().getActiveShell(), + Messages.TimeCheckInvalid_label, + Messages.TimeCheckInvalidSmall_message); + calendar.setTimeInMillis(minTime.getTimeInMillis()); + } else if (calendar.after(maxTime)) { + MessageDialog.openConfirm(Display.getDefault().getActiveShell(), + Messages.TimeCheckInvalid_label, + Messages.TimeCheckInvalidBig_message); + calendar.setTimeInMillis(maxTime.getTimeInMillis()); + } + + return calendar; + } + + private void createDatePicker(Composite parent) { + this.datePicker = new FigureCanvas(parent); + } + + public void setLabelProvider(ILabelProvider labelProvider) { + this.dateLabelProvider = labelProvider; + update(); + } + + public ILabelProvider getLabelProvider() { + if (this.dateLabelProvider == null) { + this.dateLabelProvider = new DateLabelProvider(); + } + return this.dateLabelProvider; + } + + public Control getControl() { + return control; + } + + public FigureCanvas getDatePicker() { + return datePicker; + } + + public void setBackground(Color color) { + if (control != null && !control.isDisposed()) { + control.setBackground(color); + } + } + + public void setEnabled(boolean enabled) { + if (placeholder != null) { + placeholder.setEnabled(enabled); + placeholder.setBackground(enabled ? validColor : invalidColor); + yearText.setEnabled(enabled); + yearText.setBackground(enabled ? validColor : invalidColor); + monthText.setEnabled(enabled); + monthText.setBackground(enabled ? validColor : invalidColor); + dayText.setEnabled(enabled); + dayText.setBackground(enabled ? validColor : invalidColor); + slash1.setEnabled(enabled); + slash1.setBackground(enabled ? validColor : invalidColor); + slash2.setEnabled(enabled); + slash2.setBackground(enabled ? validColor : invalidColor); + showDatePickerButton.setEnabled(enabled); + } + } + + public Composite getPlaceholder() { + return placeholder; + } + + public ISelection getSelection() { + return new DateSelection(selection); + } + + @Override + public void setSelection(ISelection selection) { + setSelection(selection, true); + } + + @Override + public void setSelection(ISelection selection, boolean reveal) { + if (selection instanceof DateSelection) { + setDateSelection(((DateSelection) selection).getDate(), reveal); + } else if (selection instanceof IStructuredSelection) { + Object sel = ((IStructuredSelection) selection).getFirstElement(); + if (sel instanceof Calendar) { + setDateSelection((Calendar) sel, reveal); + } + } + } + + public void setDateSelection(Calendar date, boolean reveal) { + changeDate(date); + if (reveal && date != null) { + changeCalendar(date.get(YEAR), date.get(MONTH)); + } + update(); + } + + private void initPlaceholder() { + showDatePickerButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (dropdownDatePicker == null + || dropdownDatePicker.getShell() == null + || dropdownDatePicker.getShell().isDisposed() + || !dropdownDatePicker.isClosing()) + showDropdown(); + } + + }); + } + + private void showDropdown() { + placeholder.forceFocus(); + createDropdownDatePicker(); + dropdownDatePicker.open(); + Shell shell = dropdownDatePicker.getShell(); + if (shell != null && !shell.isDisposed()) { + shell.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + if (placeholder != null && !placeholder.isDisposed()) { + placeholder.forceFocus(); + } + } + }); + } + } + + /** + * Shows the drop-down menu if this date picker is created with + * SWT.DROP_DOWN style bit. + */ + public void open() { + showDropdown(); + } + + private void createDropdownDatePicker() { + if (dropdownDatePicker != null) + return; + dropdownDatePicker = new DropdownDatePicker(control.getShell()); + } + + private void initDatePicker() { + datePicker.setScrollBarVisibility(FigureCanvas.NEVER); + + eventHandler = new EventHandler(); + eventHandler.install(datePicker); + datePicker.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + eventHandler.uninstall(datePicker); + } + }); + + Viewport viewport = new Viewport(true); + viewport.setContentsTracksHeight(true); + viewport.setContentsTracksWidth(true); + datePicker.setViewport(viewport); + + IFigure container = new Layer(); + datePicker.setContents(container); + + GridLayout containerLayout = new GridLayout(1, true); + containerLayout.horizontalSpacing = 3; + containerLayout.verticalSpacing = 3; + containerLayout.marginHeight = 3; + containerLayout.marginWidth = 3; + container.setLayoutManager(containerLayout); + createTopPanel(container); + createSeparator(container); + createWeekPanel(container); + createDaysPanel(container); + createSeparator(container); + createBottomPanel(container); + } + + private void createTopPanel(IFigure parent) { + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + + GridLayout panelLayout = new GridLayout(12, true); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 0; + panelLayout.marginWidth = 0; + panel.setLayoutManager(panelLayout); + + lastMonth = createArrowFigure(panel, ArrowFigure.UP); + monthFigure = createMonthFigure(panel); + nextMonth = createArrowFigure(panel, ArrowFigure.DOWN); + lastYear = createArrowFigure(panel, ArrowFigure.LEFT); + yearFigure = createYearFigure(panel); + nextYear = createArrowFigure(panel, ArrowFigure.RIGHT); + } + + private MonthFigure createMonthFigure(IFigure parent) { + MonthFigure figure = new MonthFigure(); + figure.setTextCandidates(MONTHS); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + constraint.horizontalSpan = 5; + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + private YearFigure createYearFigure(IFigure parent) { + YearFigure figure = new YearFigure(); + figure.setTextCandidates(new String[] { "0000" }); //$NON-NLS-1$ + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + constraint.horizontalSpan = 3; + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + private ArrowFigure createArrowFigure(IFigure parent, int orientation) { + ArrowFigure arrow = new ArrowFigure(); + arrow.setOrientation(orientation); + arrow.setForegroundColor(ColorUtils.getColor(COLOR_ARROW_BORDER)); + arrow.setBackgroundColor(ColorUtils.getColor(COLOR_ARROW_FILL)); + arrow.getContent().setVisible(false); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.add(arrow, constraint); + eventHandler.attach(arrow); + return arrow; + } + + private void createSeparator(IFigure parent) { + HorizontalLine line = new HorizontalLine(); + line.setMargin(3); + line.setForegroundColor(ColorUtils.getColor(COLOR_SEPARATOR)); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, false); + constraint.heightHint = 3; + parent.add(line, constraint); + } + + private void createWeekPanel(IFigure parent) { + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + GridLayout panelLayout = new GridLayout(7, true); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 0; + panelLayout.marginWidth = 0; + panel.setLayoutManager(panelLayout); + Font symbolFont = FontUtils.getRelativeHeight(DEFAULT_FONT, -2); + for (int i = 0; i < 7; i++) { + TextLayer symbol = new TextLayer(); + symbol.setFont(symbolFont); + symbol.setText(WEEK_SYMBOLS[i]); + if (i == 0 || i == 6) { + symbol.setForegroundColor(ColorUtils.getColor(COLOR_WEEKEND)); + } else { + symbol.setForegroundColor( + ColorUtils.getColor(COLOR_WEEK_SYMBOL)); + } + GridData symbolConstraint = new GridData(SWT.FILL, SWT.FILL, true, + true); + panel.add(symbol, symbolConstraint); + } + } + + private void createDaysPanel(IFigure parent) { + dateLayer = new Layer(); + GridData layerConstraint = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.add(dateLayer, layerConstraint); + dateLayer.setLayoutManager(new ConstraintStackLayout()); + + datePanel = new Layer(); + dateLayer.add(datePanel, null); + datePanel.setLayoutManager(new DatePanelLayout()); + for (int i = 0; i < TOTAL_DAYS; i++) { + DayFigure dayFigure = new DayFigure(); + eventHandler.attach(dayFigure); + datePanel.add(dayFigure); + } + } + + private void createBottomPanel(IFigure parent) { + boolean hasCancel = (style & SWT.CANCEL) != 0; + IFigure panel = new Layer(); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); + parent.add(panel, panelConstraint); + GridLayout panelLayout = new GridLayout(hasCancel ? 2 : 1, false); + panelLayout.horizontalSpacing = 0; + panelLayout.verticalSpacing = 0; + panelLayout.marginHeight = 0; + panelLayout.marginWidth = 0; + panel.setLayoutManager(panelLayout); + + todayFigure = createTodayFigure(panel); + if (hasCancel) { + cancelFigure = createCancelFigure(panel); + } + } + + private BaseFigure createTodayFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); + figure.setForegroundColor(ColorUtils.getColor(COLOR_TODAY)); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + private BaseFigure createCancelFigure(IFigure parent) { + BaseFigure figure = new BaseFigure(); + figure.setText(" X "); //$NON-NLS-1$ + figure.setFont(FontUtils.getRelativeHeight(DEFAULT_FONT, -2)); + figure.setForegroundColor(ColorUtils.getColor(COLOR_CANCEL)); + GridData constraint = new GridData(SWT.FILL, SWT.FILL, false, true); + parent.add(figure, constraint); + eventHandler.attach(figure); + return figure; + } + + private Calendar getSelectedDate() { + return selection; + } + + private void changeCalendar(int newYear, int newMonth) { + changeCalendar(newYear, newMonth, false); + } + + private void changeCalendar(int newYear, int newMonth, boolean smooth) { + boolean calendarChanged = newMonth != currentMonth + || newYear != currentYear; + if (!calendarChanged) + return; + if (smooth) { + if (datePicker != null) { + int months = (newYear - currentYear) * 12 + newMonth + - currentMonth; + animationAdvisor.addYearsToRoll(months / 12); + animationAdvisor.addMonthsToRoll(months % 12); + performRollCalendarAnimation(currentYear, currentMonth); + } + currentYear = newYear; + currentMonth = newMonth; + } else { + currentYear = newYear; + currentMonth = newMonth; + if (datePicker != null) { + updateCalendar(); + } + updateSelection(); + } + } + + private void updateCalendar() { + today = Calendar.getInstance(); + updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); + monthFigure.setMonth(currentMonth); + yearFigure.setYear(currentYear); + todayFigure.setText(Messages.TodayPattern); +// todayFigure.setText(NLS.bind(Messages.TodayPattern, +// String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ + } + + private void updateDayFigures(List dayFigures, int year, int month) { + Calendar date = getCalendarStart(today, year, month); + for (int i = 0; i < dayFigures.size(); i++) { + DayFigure dayFigure = (DayFigure) dayFigures.get(i); + date = (Calendar) date.clone(); + if (i > 0) + date.add(DATE, 1); + dayFigure.setDate(date); + updateDayFigure(dayFigure, year, month); + } + } + + private void updateDayFigure(DayFigure figure, int year, int month) { + figure.setFont(FontUtils.getBold(DEFAULT_FONT)); + Calendar date = figure.getDate(); + if (isSameDay(date, today)) { + figure.setForegroundColor(ColorUtils.getColor(COLOR_TODAY)); + } else if (isWeekend(date)) { + figure.setForegroundColor(ColorUtils.getColor(COLOR_WEEKEND)); + } else { + figure.setForegroundColor(ColorUtils.getColor(COLOR_TEXT)); + } + if (date.get(MONTH) == month && date.get(YEAR) == year) { + figure.setTextAlpha(NORMAL_ALPHA); + } else { + figure.setTextAlpha(SIBLING_MONTH_ALPHA); + } + } + + private void updateSelection() { + if (datePicker != null) { + for (Object figure : datePanel.getChildren()) { + DayFigure dayFigure = (DayFigure) figure; + dayFigure.setSelected( + isSameDay(dayFigure.getDate(), getSelectedDate())); + } + } + if (placeholder != null && selection != null) { + String day = String.format("%1$td", selection); //$NON-NLS-1$ + String month = String.format("%1$tm", selection); //$NON-NLS-1$ + String year = String.format("%1$tY", selection); //$NON-NLS-1$ + + dayText.setText(day); + monthText.setText(month); + yearText.setText(year); + } + + placeholder.layout(); + } + + private void update() { + if (datePicker != null) { + updateCalendar(); + } + updateSelection(); + } + + private void performRollCalendarAnimation(int oldYear, int oldMonth) { + if (animating) + return; + + animating = true; + + final int newYear, newMonth; + final CalendarAnimation animation; + if (animationAdvisor.getYearsToRoll() != 0) { + if (animationAdvisor.getYearsToRoll() < 0) { + newYear = oldYear - 1; + newMonth = oldMonth; + animation = new LastYearAnimation(animationAdvisor); + } else { + newYear = oldYear + 1; + newMonth = oldMonth; + animation = new NextYearAnimation(animationAdvisor); + } + } else if (animationAdvisor.getMonthsToRoll() != 0) { + if (animationAdvisor.getMonthsToRoll() < 0) { + newYear = oldMonth <= 0 ? oldYear - 1 : oldYear; + newMonth = oldMonth <= 0 ? 11 : oldMonth - 1; + animation = new LastMonthAnimation(animationAdvisor); + } else { + newYear = oldMonth >= 11 ? oldYear + 1 : oldYear; + newMonth = oldMonth >= 11 ? 0 : oldMonth + 1; + animation = new NextMonthAnimation(animationAdvisor); + } + } else { + newYear = oldYear; + newMonth = oldMonth; + animation = null; + } + monthFigure.setMonth(newMonth); + yearFigure.setYear(newYear); + if (animation != null) { + animationAdvisor.setStartMonth(oldYear, oldMonth); + animationAdvisor.setEndMonth(newYear, newMonth); + animation.callback(new Runnable() { + public void run() { + datePanel = animation.getNewPanel(); + if (animationAdvisor.isDone()) { + animating = false; + } else { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + animating = false; + performRollCalendarAnimation(newYear, newMonth); + } + }); + } + + } + }).start(); + } + } + + private void selected(final BaseFigure target) { + if (target instanceof MonthFigure) { + target.setSelected(true); + showMonthPopup(); + } else if (target instanceof YearFigure) { + target.setSelected(true); + showYearPopup(); + } else if (target == todayFigure) { + todaySelected(); + } else if (target == lastMonth) { + lastMonthSelected(true); + } else if (target == nextMonth) { + nextMonthSelected(true); + } else if (target == lastYear) { + lastYearSelected(true); + } else if (target == nextYear) { + nextYearSelected(true); + } else if (target == cancelFigure) { + cancelSelected(); + } + } + + private void showMonthPopup() { + createMonthMenu(); + for (int month = 0; month < monthActions.length; month++) { + MonthAction action = monthActions[month]; + action.setChecked(month == currentMonth); + } + Rectangle b = monthFigure.getBounds(); + Point loc = control.toDisplay(b.x, b.y + b.height); + final Menu menu = monthMenu.createContextMenu(control); + menu.setLocation(loc.x + 10, loc.y + 1); + menu.setVisible(true); + } + + private void createMonthMenu() { + if (monthMenu != null) + return; + monthMenu = new MenuManager(); + monthMenu.addMenuListener(new IMenuListener2() { + public void menuAboutToShow(IMenuManager manager) { + // do nothing + } + + public void menuAboutToHide(IMenuManager manager) { + monthFigure.setSelected(false); + } + }); + monthActions = new MonthAction[12]; + for (int month = 0; month < 12; month++) { + MonthAction action = new MonthAction(month); + monthMenu.add(action); + monthActions[month] = action; + } + } + + private void showYearPopup() { + createYearMenu(); + int start = currentYear - PASSED_YEARS; + for (int year = 0; year < yearActions.length; year++) { + YearAction action = yearActions[year]; + action.setYear(start + year); + action.setChecked(action.getYear() == currentYear); + } + Rectangle b = yearFigure.getBounds(); + Point loc = control.toDisplay(b.x, b.y + b.height); + Menu menu = yearMenu.createContextMenu(control); + menu.setLocation(loc.x, loc.y + 1); + menu.setVisible(true); + } + + private void createYearMenu() { + if (yearMenu != null) + return; + yearMenu = new MenuManager(); + yearMenu.addMenuListener(new IMenuListener2() { + public void menuAboutToShow(IMenuManager manager) { + // do nothing + } + + public void menuAboutToHide(IMenuManager manager) { + yearFigure.setSelected(false); + } + }); + yearActions = new YearAction[FUTURE_YEARS + PASSED_YEARS + 1]; + for (int year = 0; year < yearActions.length; year++) { + YearAction action = new YearAction(); + yearMenu.add(action); + yearActions[year] = action; + } + } + + private void monthSelected(int month) { + changeCalendar(currentYear, month); + } + + private void yearSelected(int year) { + changeCalendar(year, currentMonth); + } + + private void daySelected(DayFigure day) { + Calendar date = day.getDate(); + changeDate(date); + if (date != null && date.get(MONTH) != currentMonth) { + changeCalendar(date.get(YEAR), date.get(MONTH), true); + } + } + + private void todaySelected() { + changeDate(today); + changeCalendar(today.get(YEAR), today.get(MONTH)); + } + + private void lastMonthSelected(boolean smooth) { + if (currentMonth <= 0) { + changeCalendar(currentYear - 1, 11, smooth); + } else { + changeCalendar(currentYear, currentMonth - 1, smooth); + } + } + + private void nextMonthSelected(boolean smooth) { + if (currentMonth >= 11) { + changeCalendar(currentYear + 1, 0, smooth); + } else { + changeCalendar(currentYear, currentMonth + 1, smooth); + } + } + + private void lastYearSelected(boolean smooth) { + changeCalendar(currentYear - 1, currentMonth, smooth); + } + + private void nextYearSelected(boolean smooth) { + changeCalendar(currentYear + 1, currentMonth, smooth); + } + + private void cancelSelected() { + changeDate(null); + } + + private void rollMonth(int count) { + Calendar temp = (Calendar) today.clone(); + temp.set(YEAR, currentYear); + temp.set(MONTH, currentMonth); + temp.add(MONTH, count); + changeCalendar(temp.get(YEAR), temp.get(MONTH), true); + } + + private void changeDate(Calendar date) { + if (date != null) { + date.set(Calendar.MILLISECOND, 0); + } + this.selection = date; + updateSelection(); + + if (firingSelectionChange) + return; + firingSelectionChange = true; + if (dropdownDatePicker != null) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + dropdownDatePicker.close(); + } + }); + } + fireSelectionChanged( + new SelectionChangedEvent(DatePicker2.this, getSelection())); + firingSelectionChange = false; + } + + @Override + public Object getInput() { + return today; + } + + @Override + public void refresh() { + update(); + } + + @Override + public void setInput(Object input) { + if (input instanceof Calendar) { + Calendar oldInput = this.today; + this.today = (Calendar) input; + inputChanged(input, oldInput); + } + } + + @Override + protected void inputChanged(Object input, Object oldInput) { + update(); + } + + public void setMinTime(Calendar minTime) { + if (minTime != null) { + minTime.set(Calendar.MILLISECOND, 0); + this.minTime = minTime; + } + } + + public Calendar getMinTime() { + return minTime; + } + + public void setMaxTime(Calendar maxTime) { + if (maxTime != null) { + maxTime.set(Calendar.MILLISECOND, 0); + this.maxTime = maxTime; + } + } + + public Calendar getMaxTime() { + return maxTime; + } + + private static boolean isWeekend(Calendar date) { + int dow = date.get(DAY_OF_WEEK); + return dow == SUNDAY || dow == SATURDAY; + } + + private static Calendar getCalendarStart(Calendar date, int year, + int month) { + date = (Calendar) date.clone(); + date.set(year, month, 1); + while (date.get(DAY_OF_WEEK) != SUNDAY) { + date.add(DATE, -1); + } + return date; + } + + private static boolean isSameDay(Calendar date1, Calendar date2) { + if (date1 == null) + return date2 == null; + if (date2 == null) + return false; + return date1.get(DATE) == date2.get(DATE) + && date1.get(MONTH) == date2.get(MONTH) + && date1.get(YEAR) == date2.get(YEAR); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateSelection.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateSelection.java index 569d7a5f2..7211bfd67 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateSelection.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DateSelection.java @@ -1,35 +1,35 @@ -package org.xmind.ui.datepicker; - -import java.util.Calendar; - -import org.eclipse.jface.viewers.ISelection; - -public class DateSelection implements ISelection { - - private Calendar date; - - public DateSelection(Calendar date) { - this.date = date; - } - - public boolean isEmpty() { - return date != null; - } - - public Calendar getDate() { - return date; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (obj == this) - return true; - if (!(obj instanceof DateSelection)) - return false; - DateSelection that = (DateSelection) obj; - return this.date == that.date - || (this.date != null && this.date.equals(that.date)); - } -} +package org.xmind.ui.datepicker; + +import java.util.Calendar; + +import org.eclipse.jface.viewers.ISelection; + +public class DateSelection implements ISelection { + + private Calendar date; + + public DateSelection(Calendar date) { + this.date = date; + } + + public boolean isEmpty() { + return date != null; + } + + public Calendar getDate() { + return date; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (obj == this) + return true; + if (!(obj instanceof DateSelection)) + return false; + DateSelection that = (DateSelection) obj; + return this.date == that.date + || (this.date != null && this.date.equals(that.date)); + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DayFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DayFigure.java index fcd42d814..82dd37f57 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DayFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DayFigure.java @@ -1,26 +1,26 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import java.util.Calendar; - -public class DayFigure extends BaseFigure { - - private Calendar date = null; - - public DayFigure() { - super(); - } - - public Calendar getDate() { - return date; - } - - public void setDate(Calendar date) { - this.date = date; - setText("" + date.get(Calendar.DATE)); //$NON-NLS-1$ - repaint(); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +import java.util.Calendar; + +public class DayFigure extends BaseFigure { + + private Calendar date = null; + + public DayFigure() { + super(); + } + + public Calendar getDate() { + return date; + } + + public void setDate(Calendar date) { + this.date = date; + setText("" + date.get(Calendar.DATE)); //$NON-NLS-1$ + repaint(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HorizontalLine.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HorizontalLine.java index 789115d86..0fa5578f7 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HorizontalLine.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HorizontalLine.java @@ -1,31 +1,31 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Rectangle; - -public class HorizontalLine extends Figure { - - private int margin = 0; - - public int getMargin() { - return margin; - } - - public void setMargin(int margin) { - this.margin = margin; - repaint(); - } - - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - Rectangle b = getBounds(); - int left = b.x + margin; - int right = b.x + b.width - margin - 1; - if (left > right) - return; - graphics.drawLine(left, b.y + b.height / 2, right, b.y + b.height / 2); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Rectangle; + +public class HorizontalLine extends Figure { + + private int margin = 0; + + public int getMargin() { + return margin; + } + + public void setMargin(int margin) { + this.margin = margin; + repaint(); + } + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + Rectangle b = getBounds(); + int left = b.x + margin; + int right = b.x + b.width - margin - 1; + if (left > right) + return; + graphics.drawLine(left, b.y + b.height / 2, right, b.y + b.height / 2); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HourFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HourFigure.java index 2fa3eeecc..460ad1b5f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HourFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HourFigure.java @@ -1,37 +1,37 @@ -package org.xmind.ui.datepicker; - -public class HourFigure extends BaseFigure { - - private static final String[] HOURS_12 = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ - private static final String[] HOURS_24 = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ - "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ - - private int hour = -1; - - public HourFigure() { - super(); - } - - public int getHour() { - return hour; - } - - public void setHour(int hour, int type) { - this.hour = hour; - String hour_tx = HOURS_12[0]; - if (type == DatePicker.TIME_12) { - if (hour > 12) - hour = hour % 12; - hour_tx = (hour > 0 && hour < HOURS_12.length) ? HOURS_12[hour] - : HOURS_12[12]; - } else if (type == DatePicker.TIME_24) { - hour_tx = hour >= 0 && hour < HOURS_24.length ? HOURS_24[hour] - : HOURS_24[0]; - } - - setText(hour_tx); - repaint(); - } -} +package org.xmind.ui.datepicker; + +public class HourFigure extends BaseFigure { + + private static final String[] HOURS_12 = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ + private static final String[] HOURS_24 = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ + "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ + + private int hour = -1; + + public HourFigure() { + super(); + } + + public int getHour() { + return hour; + } + + public void setHour(int hour, int type) { + this.hour = hour; + String hour_tx = HOURS_12[0]; + if (type == DatePicker.TIME_12) { + if (hour > 12) + hour = hour % 12; + hour_tx = (hour > 0 && hour < HOURS_12.length) ? HOURS_12[hour] + : HOURS_12[12]; + } else if (type == DatePicker.TIME_24) { + hour_tx = hour >= 0 && hour < HOURS_24.length ? HOURS_24[hour] + : HOURS_24[0]; + } + + setText(hour_tx); + repaint(); + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/IAnimationAdvisor.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/IAnimationAdvisor.java index 850f68dcf..57411548f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/IAnimationAdvisor.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/IAnimationAdvisor.java @@ -1,41 +1,41 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.IFigure; - -public interface IAnimationAdvisor { - - boolean isDone(); - - int getMonthsToRoll(); - - int getYearsToRoll(); - - void addMonthsToRoll(int count); - - void addYearsToRoll(int count); - - void initOldDay(DayFigure figure); - - void initNewDay(DayFigure figure); - - void updateNewDay(DayFigure figure); - - void setStartMonth(int oldYear, int oldMonth); - - void setEndMonth(int newYear, int newMonth); - - int getOldYear(); - - int getOldMonth(); - - int getNewYear(); - - int getNewMonth(); - - IFigure getLayer(); - - IFigure getPanel(); - - int getDuration(); - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.IFigure; + +public interface IAnimationAdvisor { + + boolean isDone(); + + int getMonthsToRoll(); + + int getYearsToRoll(); + + void addMonthsToRoll(int count); + + void addYearsToRoll(int count); + + void initOldDay(DayFigure figure); + + void initNewDay(DayFigure figure); + + void updateNewDay(DayFigure figure); + + void setStartMonth(int oldYear, int oldMonth); + + void setEndMonth(int newYear, int newMonth); + + int getOldYear(); + + int getOldMonth(); + + int getNewYear(); + + int getNewMonth(); + + IFigure getLayer(); + + IFigure getPanel(); + + int getDuration(); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastMonthAnimation.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastMonthAnimation.java index 45c3d57e0..5c4f6d2c2 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastMonthAnimation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastMonthAnimation.java @@ -1,81 +1,81 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.MONTH; - -import java.util.Calendar; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; - -class LastMonthAnimation extends CalendarAnimation { - - private int newRows; - - public LastMonthAnimation(IAnimationAdvisor advisor) { - super(advisor); - } - - @Override - protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, - int month, int index) { - newDays.add(dayFigure); - } - - @Override - protected void createNewDays() { - newRows = 0; - Calendar date = ((DayFigure) advisor.getPanel().getChildren() - .get(0)).getDate(); - boolean head = false; - while (!head) { - for (int i = 0; i < 7; i++) { - date = (Calendar) date.clone(); - date.add(DATE, -1); - DayFigure dayFigure = new DayFigure(); - dayFigure.setDate(date); - advisor.initNewDay(dayFigure); - newPanel.add(dayFigure, 0); - if (date.get(MONTH) == advisor.getNewMonth()) - newDays.add(0, dayFigure); - if (date.get(DATE) == 1) { - head = true; - } - } - newRows++; - } - } - - @Override - protected Rectangle createOldInitConstraint() { - int oldRows = 6; - Rectangle constraint = new Rectangle(); - constraint.width = oldSize.width; - constraint.height = oldSize.height * (oldRows + newRows) / oldRows; - constraint.y = oldSize.height - constraint.height; - return constraint; - } - - @Override - protected Rectangle createOldFinalConstraint() { - return new Rectangle(0, 0, oldInitConstraint.width, - oldInitConstraint.height); - } - - @Override - protected void removeOldDays() { - IFigure oldPanel = advisor.getPanel(); - while (oldPanel.getChildren().size() > DatePicker.TOTAL_DAYS) { - oldPanel.remove((IFigure) oldPanel.getChildren().get( - oldPanel.getChildren().size() - 1)); - } - } - - @Override - protected void updateJobs() { - advisor.addMonthsToRoll(1); - } +/** + * + */ +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.MONTH; + +import java.util.Calendar; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; + +class LastMonthAnimation extends CalendarAnimation { + + private int newRows; + + public LastMonthAnimation(IAnimationAdvisor advisor) { + super(advisor); + } + + @Override + protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, + int month, int index) { + newDays.add(dayFigure); + } + + @Override + protected void createNewDays() { + newRows = 0; + Calendar date = ((DayFigure) advisor.getPanel().getChildren() + .get(0)).getDate(); + boolean head = false; + while (!head) { + for (int i = 0; i < 7; i++) { + date = (Calendar) date.clone(); + date.add(DATE, -1); + DayFigure dayFigure = new DayFigure(); + dayFigure.setDate(date); + advisor.initNewDay(dayFigure); + newPanel.add(dayFigure, 0); + if (date.get(MONTH) == advisor.getNewMonth()) + newDays.add(0, dayFigure); + if (date.get(DATE) == 1) { + head = true; + } + } + newRows++; + } + } + + @Override + protected Rectangle createOldInitConstraint() { + int oldRows = 6; + Rectangle constraint = new Rectangle(); + constraint.width = oldSize.width; + constraint.height = oldSize.height * (oldRows + newRows) / oldRows; + constraint.y = oldSize.height - constraint.height; + return constraint; + } + + @Override + protected Rectangle createOldFinalConstraint() { + return new Rectangle(0, 0, oldInitConstraint.width, + oldInitConstraint.height); + } + + @Override + protected void removeOldDays() { + IFigure oldPanel = advisor.getPanel(); + while (oldPanel.getChildren().size() > DatePicker.TOTAL_DAYS) { + oldPanel.remove((IFigure) oldPanel.getChildren().get( + oldPanel.getChildren().size() - 1)); + } + } + + @Override + protected void updateJobs() { + advisor.addMonthsToRoll(1); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastYearAnimation.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastYearAnimation.java index a18005178..2ecab5702 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastYearAnimation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/LastYearAnimation.java @@ -1,80 +1,80 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.MONTH; - -import java.util.Calendar; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Rectangle; - -class LastYearAnimation extends CalendarAnimation { - - private int distance; - - public LastYearAnimation(IAnimationAdvisor advisor) { - super(advisor); - } - - @Override - protected IFigure createNewPanel() { - IFigure newPanel = new Layer(); - newPanel.setLayoutManager(new DatePanelLayout()); - return newPanel; - } - - @Override - protected void createNewDays() { - Calendar date = DatePicker.getCalendarStart(oldDays.get(0).getDate(), advisor - .getNewYear(), advisor.getNewMonth()); - for (int i = 0; i < DatePicker.TOTAL_DAYS; i++) { - if (i > 0) { - date = (Calendar) date.clone(); - date.add(DATE, 1); - } - DayFigure dayFigure = new DayFigure(); - dayFigure.setDate(date); - advisor.initNewDay(dayFigure); - newPanel.add(dayFigure); - if (date.get(MONTH) == advisor.getNewMonth()) { - newDays.add(dayFigure); - } - } - } - - @Override - protected Rectangle createOldInitConstraint() { - distance = oldSize.width + 10; - return new Rectangle(0, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createOldFinalConstraint() { - return new Rectangle(distance, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createNewInitConstraint() { - return new Rectangle(-distance, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createNewFinalConstraint() { - return new Rectangle(0, 0, oldSize.width, oldSize.height); - } - - @Override - protected void removeOldDays() { - advisor.getLayer().remove(advisor.getPanel()); - } - - @Override - protected void updateJobs() { - advisor.addYearsToRoll(1); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.MONTH; + +import java.util.Calendar; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Rectangle; + +class LastYearAnimation extends CalendarAnimation { + + private int distance; + + public LastYearAnimation(IAnimationAdvisor advisor) { + super(advisor); + } + + @Override + protected IFigure createNewPanel() { + IFigure newPanel = new Layer(); + newPanel.setLayoutManager(new DatePanelLayout()); + return newPanel; + } + + @Override + protected void createNewDays() { + Calendar date = DatePicker.getCalendarStart(oldDays.get(0).getDate(), advisor + .getNewYear(), advisor.getNewMonth()); + for (int i = 0; i < DatePicker.TOTAL_DAYS; i++) { + if (i > 0) { + date = (Calendar) date.clone(); + date.add(DATE, 1); + } + DayFigure dayFigure = new DayFigure(); + dayFigure.setDate(date); + advisor.initNewDay(dayFigure); + newPanel.add(dayFigure); + if (date.get(MONTH) == advisor.getNewMonth()) { + newDays.add(dayFigure); + } + } + } + + @Override + protected Rectangle createOldInitConstraint() { + distance = oldSize.width + 10; + return new Rectangle(0, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createOldFinalConstraint() { + return new Rectangle(distance, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createNewInitConstraint() { + return new Rectangle(-distance, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createNewFinalConstraint() { + return new Rectangle(0, 0, oldSize.width, oldSize.height); + } + + @Override + protected void removeOldDays() { + advisor.getLayer().remove(advisor.getPanel()); + } + + @Override + protected void updateJobs() { + advisor.addYearsToRoll(1); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/Messages.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/Messages.java index d976d54ed..d5ac6801a 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/Messages.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/Messages.java @@ -1,63 +1,63 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.datepicker; - -import org.eclipse.osgi.util.NLS; - -public class Messages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.ui.datepicker.messages"; //$NON-NLS-1$ - - // Full name of each month - public static String January; - public static String Feburary; - public static String March; - public static String April; - public static String May; - public static String June; - public static String July; - public static String August; - public static String September; - public static String October; - public static String November; - public static String December; - - // Abbr name of each week day - public static String Monday; - public static String Tuesday; - public static String Wednesday; - public static String Thursday; - public static String Friday; - public static String Saturday; - public static String Sunday; - - public static String TodayPattern; - public static String None; - public static String Illegal; - - public static String TimeCheckInvalid_label; - public static String TimeCheckInvalidSmall_message; - public static String TimeCheckInvalidBig_message; - - public static String DatePicker_Time_AM_text; - public static String DatePicker_Time_PM_text; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.datepicker; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.ui.datepicker.messages"; //$NON-NLS-1$ + + // Full name of each month + public static String January; + public static String Feburary; + public static String March; + public static String April; + public static String May; + public static String June; + public static String July; + public static String August; + public static String September; + public static String October; + public static String November; + public static String December; + + // Abbr name of each week day + public static String Monday; + public static String Tuesday; + public static String Wednesday; + public static String Thursday; + public static String Friday; + public static String Saturday; + public static String Sunday; + + public static String TodayPattern; + public static String None; + public static String Illegal; + + public static String TimeCheckInvalid_label; + public static String TimeCheckInvalidSmall_message; + public static String TimeCheckInvalidBig_message; + + public static String DatePicker_Time_AM_text; + public static String DatePicker_Time_PM_text; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MinutesFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MinutesFigure.java index eb5e1d019..f75a6a999 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MinutesFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MinutesFigure.java @@ -1,26 +1,26 @@ -package org.xmind.ui.datepicker; - -public class MinutesFigure extends BaseFigure { - - private static final String[] MINUTES = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "03", "04", "05", "06", "07", "08", "09" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ - private int minute = -1; - - public MinutesFigure() { - super(); - } - - public int getMinutes() { - return minute; - } - - public void setMinutes(int minute) { - this.minute = minute; - String hour_tx = MINUTES[0]; - if (minute >= 0 && minute < 60) - hour_tx = (minute >= 0 && minute < MINUTES.length) ? MINUTES[minute] - : minute + ""; //$NON-NLS-1$ - setText(hour_tx); - repaint(); - } -} +package org.xmind.ui.datepicker; + +public class MinutesFigure extends BaseFigure { + + private static final String[] MINUTES = new String[] { "00", "01", "02", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "03", "04", "05", "06", "07", "08", "09" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ + private int minute = -1; + + public MinutesFigure() { + super(); + } + + public int getMinutes() { + return minute; + } + + public void setMinutes(int minute) { + this.minute = minute; + String hour_tx = MINUTES[0]; + if (minute >= 0 && minute < 60) + hour_tx = (minute >= 0 && minute < MINUTES.length) ? MINUTES[minute] + : minute + ""; //$NON-NLS-1$ + setText(hour_tx); + repaint(); + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MonthFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MonthFigure.java index 917cd41ef..2fd26b729 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MonthFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MonthFigure.java @@ -1,25 +1,25 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -public class MonthFigure extends BaseFigure { - - private int month = -1; - - public MonthFigure() { - super(); - } - - public int getMonth() { - return month; - } - - public void setMonth(int month) { - this.month = month; - setText(month >= 0 && month < DatePicker.MONTHS.length ? DatePicker.MONTHS[month] - : null); - repaint(); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +public class MonthFigure extends BaseFigure { + + private int month = -1; + + public MonthFigure() { + super(); + } + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + setText(month >= 0 && month < DatePicker.MONTHS.length ? DatePicker.MONTHS[month] + : null); + repaint(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextMonthAnimation.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextMonthAnimation.java index 94c066148..c7f3410d6 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextMonthAnimation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextMonthAnimation.java @@ -1,80 +1,80 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.MONTH; - -import java.util.Calendar; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; - -class NextMonthAnimation extends CalendarAnimation { - - private int newRows = 0; - - public NextMonthAnimation(IAnimationAdvisor advisor) { - super(advisor); - } - - @Override - protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, - int month, int index) { - newDays.add(dayFigure); - if (date.get(DATE) == 1) { - newRows = index / 7; - } - } - - @Override - protected void createNewDays() { - List oldDayFigures = advisor.getPanel().getChildren(); - Calendar date = ((DayFigure) oldDayFigures - .get(oldDayFigures.size() - 1)).getDate(); - for (int r = 0; r < newRows; r++) { - for (int i = 0; i < 7; i++) { - date = (Calendar) date.clone(); - date.add(DATE, 1); - DayFigure dayFigure = new DayFigure(); - dayFigure.setDate(date); - advisor.initNewDay(dayFigure); - newPanel.add(dayFigure); - if (date.get(MONTH) == advisor.getNewMonth()) { - newDays.add(dayFigure); - } - } - } - } - - @Override - protected Rectangle createOldInitConstraint() { - int oldRows = 6; - Rectangle constraint = new Rectangle(); - constraint.width = oldSize.width; - constraint.height = oldSize.height * (oldRows + newRows) / oldRows; - return constraint; - } - - @Override - protected Rectangle createOldFinalConstraint() { - return new Rectangle(0, oldSize.height - oldInitConstraint.height, - oldInitConstraint.width, oldInitConstraint.height); - } - - @Override - protected void removeOldDays() { - IFigure oldPanel = advisor.getPanel(); - while (oldPanel.getChildren().size() > DatePicker.TOTAL_DAYS) { - oldPanel.remove((IFigure) oldPanel.getChildren().get(0)); - } - } - - @Override - protected void updateJobs() { - advisor.addMonthsToRoll(-1); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.MONTH; + +import java.util.Calendar; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; + +class NextMonthAnimation extends CalendarAnimation { + + private int newRows = 0; + + public NextMonthAnimation(IAnimationAdvisor advisor) { + super(advisor); + } + + @Override + protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date, + int month, int index) { + newDays.add(dayFigure); + if (date.get(DATE) == 1) { + newRows = index / 7; + } + } + + @Override + protected void createNewDays() { + List oldDayFigures = advisor.getPanel().getChildren(); + Calendar date = ((DayFigure) oldDayFigures + .get(oldDayFigures.size() - 1)).getDate(); + for (int r = 0; r < newRows; r++) { + for (int i = 0; i < 7; i++) { + date = (Calendar) date.clone(); + date.add(DATE, 1); + DayFigure dayFigure = new DayFigure(); + dayFigure.setDate(date); + advisor.initNewDay(dayFigure); + newPanel.add(dayFigure); + if (date.get(MONTH) == advisor.getNewMonth()) { + newDays.add(dayFigure); + } + } + } + } + + @Override + protected Rectangle createOldInitConstraint() { + int oldRows = 6; + Rectangle constraint = new Rectangle(); + constraint.width = oldSize.width; + constraint.height = oldSize.height * (oldRows + newRows) / oldRows; + return constraint; + } + + @Override + protected Rectangle createOldFinalConstraint() { + return new Rectangle(0, oldSize.height - oldInitConstraint.height, + oldInitConstraint.width, oldInitConstraint.height); + } + + @Override + protected void removeOldDays() { + IFigure oldPanel = advisor.getPanel(); + while (oldPanel.getChildren().size() > DatePicker.TOTAL_DAYS) { + oldPanel.remove((IFigure) oldPanel.getChildren().get(0)); + } + } + + @Override + protected void updateJobs() { + advisor.addMonthsToRoll(-1); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextYearAnimation.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextYearAnimation.java index eecfb0ccb..9cf9618ce 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextYearAnimation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/NextYearAnimation.java @@ -1,81 +1,81 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -import static java.util.Calendar.DATE; -import static java.util.Calendar.MONTH; - -import java.util.Calendar; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Rectangle; - -class NextYearAnimation extends CalendarAnimation { - - private int distance; - - public NextYearAnimation(IAnimationAdvisor advisor) { - super(advisor); - // TODO Auto-generated constructor stub - } - - @Override - protected IFigure createNewPanel() { - IFigure newPanel = new Layer(); - newPanel.setLayoutManager(new DatePanelLayout()); - return newPanel; - } - - @Override - protected void createNewDays() { - Calendar date = DatePicker.getCalendarStart(oldDays.get(0).getDate(), advisor - .getNewYear(), advisor.getNewMonth()); - for (int i = 0; i < DatePicker.TOTAL_DAYS; i++) { - if (i > 0) { - date = (Calendar) date.clone(); - date.add(DATE, 1); - } - DayFigure dayFigure = new DayFigure(); - dayFigure.setDate(date); - advisor.initNewDay(dayFigure); - newPanel.add(dayFigure); - if (date.get(MONTH) == advisor.getNewMonth()) { - newDays.add(dayFigure); - } - } - } - - @Override - protected Rectangle createOldInitConstraint() { - distance = oldSize.width + 10; - return new Rectangle(0, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createOldFinalConstraint() { - return new Rectangle(-distance, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createNewInitConstraint() { - return new Rectangle(distance, 0, oldSize.width, oldSize.height); - } - - @Override - protected Rectangle createNewFinalConstraint() { - return new Rectangle(0, 0, oldSize.width, oldSize.height); - } - - @Override - protected void removeOldDays() { - advisor.getLayer().remove(advisor.getPanel()); - } - - @Override - protected void updateJobs() { - advisor.addYearsToRoll(-1); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +import static java.util.Calendar.DATE; +import static java.util.Calendar.MONTH; + +import java.util.Calendar; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Rectangle; + +class NextYearAnimation extends CalendarAnimation { + + private int distance; + + public NextYearAnimation(IAnimationAdvisor advisor) { + super(advisor); + // TODO Auto-generated constructor stub + } + + @Override + protected IFigure createNewPanel() { + IFigure newPanel = new Layer(); + newPanel.setLayoutManager(new DatePanelLayout()); + return newPanel; + } + + @Override + protected void createNewDays() { + Calendar date = DatePicker.getCalendarStart(oldDays.get(0).getDate(), advisor + .getNewYear(), advisor.getNewMonth()); + for (int i = 0; i < DatePicker.TOTAL_DAYS; i++) { + if (i > 0) { + date = (Calendar) date.clone(); + date.add(DATE, 1); + } + DayFigure dayFigure = new DayFigure(); + dayFigure.setDate(date); + advisor.initNewDay(dayFigure); + newPanel.add(dayFigure); + if (date.get(MONTH) == advisor.getNewMonth()) { + newDays.add(dayFigure); + } + } + } + + @Override + protected Rectangle createOldInitConstraint() { + distance = oldSize.width + 10; + return new Rectangle(0, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createOldFinalConstraint() { + return new Rectangle(-distance, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createNewInitConstraint() { + return new Rectangle(distance, 0, oldSize.width, oldSize.height); + } + + @Override + protected Rectangle createNewFinalConstraint() { + return new Rectangle(0, 0, oldSize.width, oldSize.height); + } + + @Override + protected void removeOldDays() { + advisor.getLayer().remove(advisor.getPanel()); + } + + @Override + protected void updateJobs() { + advisor.addYearsToRoll(-1); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PreselectFeedbackLayer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PreselectFeedbackLayer.java index 659189ccc..e12e07f8c 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PreselectFeedbackLayer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PreselectFeedbackLayer.java @@ -1,30 +1,30 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; - -public class PreselectFeedbackLayer extends Layer { - - public PreselectFeedbackLayer() { - setVisible(false); - } - - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - graphics.setAlpha(0x80); - graphics.setForegroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_DARK_GRAY)); - graphics.setBackgroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_WHITE)); - Rectangle b = getBounds(); - Rectangle box = b.getResized(-1, -1).expand(-1, -1); - int corner = DatePicker.CORNER; - graphics.fillRoundRectangle(box, corner, corner); - graphics.drawRoundRectangle(box, corner, corner); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; + +public class PreselectFeedbackLayer extends Layer { + + public PreselectFeedbackLayer() { + setVisible(false); + } + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + graphics.setAlpha(0x80); + graphics.setForegroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_DARK_GRAY)); + graphics.setBackgroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_WHITE)); + Rectangle b = getBounds(); + Rectangle box = b.getResized(-1, -1).expand(-1, -1); + int corner = DatePicker.CORNER; + graphics.fillRoundRectangle(box, corner, corner); + graphics.drawRoundRectangle(box, corner, corner); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PressFeedbackLayer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PressFeedbackLayer.java index 763e46bde..1fc33c30f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PressFeedbackLayer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/PressFeedbackLayer.java @@ -1,30 +1,30 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; - -public class PressFeedbackLayer extends Layer { - - public PressFeedbackLayer() { - setVisible(false); - } - - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - Rectangle b = getBounds(); - Rectangle box = b.getResized(-1, -1).expand(-1, -1); - int corner = DatePicker.CORNER; - graphics.setAlpha(0x80); - graphics.setForegroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_DARK_GRAY)); - graphics.setBackgroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_GRAY)); - graphics.fillRoundRectangle(box, corner, corner); - graphics.drawRoundRectangle(box, corner, corner); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; + +public class PressFeedbackLayer extends Layer { + + public PressFeedbackLayer() { + setVisible(false); + } + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + Rectangle b = getBounds(); + Rectangle box = b.getResized(-1, -1).expand(-1, -1); + int corner = DatePicker.CORNER; + graphics.setAlpha(0x80); + graphics.setForegroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_DARK_GRAY)); + graphics.setBackgroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_GRAY)); + graphics.fillRoundRectangle(box, corner, corner); + graphics.drawRoundRectangle(box, corner, corner); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/SelectFeedbackLayer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/SelectFeedbackLayer.java index 2f1048f5d..e6628e641 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/SelectFeedbackLayer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/SelectFeedbackLayer.java @@ -1,30 +1,30 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; - -public class SelectFeedbackLayer extends Layer { - - public SelectFeedbackLayer() { - setVisible(false); - } - - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - Rectangle b = getBounds(); - Rectangle box = b.getResized(-1, -1).expand(-1, -1); - int corner = DatePicker.CORNER; - graphics.setAlpha(0xff); - graphics.setForegroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_GRAY)); - graphics.setBackgroundColor(Display.getCurrent() - .getSystemColor(SWT.COLOR_LIST_SELECTION)); - graphics.fillRoundRectangle(box, corner, corner); - graphics.drawRoundRectangle(box, corner, corner); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; + +public class SelectFeedbackLayer extends Layer { + + public SelectFeedbackLayer() { + setVisible(false); + } + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + Rectangle b = getBounds(); + Rectangle box = b.getResized(-1, -1).expand(-1, -1); + int corner = DatePicker.CORNER; + graphics.setAlpha(0xff); + graphics.setForegroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_GRAY)); + graphics.setBackgroundColor(Display.getCurrent() + .getSystemColor(SWT.COLOR_LIST_SELECTION)); + graphics.fillRoundRectangle(box, corner, corner); + graphics.drawRoundRectangle(box, corner, corner); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/TextLayer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/TextLayer.java index addf57f55..0138eb25f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/TextLayer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/TextLayer.java @@ -1,113 +1,113 @@ -package org.xmind.ui.datepicker; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Font; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; - -public class TextLayer extends Layer { - - private int alpha = 0xff; - - private String text; - - private int dx = 0; - - private int dy = 0; - - private Dimension computedSize; - - private String[] candidates; - - private Dimension candidatesSize; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - repaint(); - } - - public void setOffset(int dx, int dy) { - this.dx = dx; - this.dy = dy; - repaint(); - } - - public void setCandidates(String[] candidates) { - this.candidates = candidates; - candidatesSize = null; - revalidate(); - } - - public int getAlpha() { - return alpha; - } - - public void setAlpha(int alpha) { - this.alpha = alpha; - repaint(); - } - - @Override - public void setFont(Font f) { - super.setFont(f); - candidatesSize = null; - } - - @Override - public Dimension getPreferredSize(int wHint, int hHint) { - if (computedSize == null) { - computeSize(wHint, hHint); - } - return computedSize; - } - - private void computeSize(int wHint, int hHint) { - computedSize = GraphicsUtils.getAdvanced().getTextSize( - text == null || "".equals(text) ? "A" : text, getFont()) //$NON-NLS-1$ //$NON-NLS-2$ - .expand(10, 8); - computeCandidatesSize(); - computedSize.union(candidatesSize); - } - - private void computeCandidatesSize() { - if (candidatesSize != null) - return; - candidatesSize = new Dimension(); - if (candidates == null || candidates.length == 0) - return; - for (String str : candidates) { - candidatesSize.union(GraphicsUtils.getAdvanced().getTextSize(str, - getFont())); - } - } - - @Override - public void invalidate() { - super.invalidate(); - computedSize = null; - } - - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - - if (text == null || "".equals(text)) //$NON-NLS-1$ - return; - - graphics.setAlpha(alpha); - graphics.setForegroundColor(getForegroundColor()); - graphics.setBackgroundColor(getBackgroundColor()); - graphics.setFont(getFont()); - Dimension textSize = GraphicsUtils.getAdvanced().getTextSize(text, - getFont()); - Rectangle b = getBounds(); - graphics.drawText(text, b.x + (b.width - textSize.width) / 2 + dx, b.y - + (b.height - textSize.height) / 2 + dy); - } - -} +package org.xmind.ui.datepicker; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Font; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; + +public class TextLayer extends Layer { + + private int alpha = 0xff; + + private String text; + + private int dx = 0; + + private int dy = 0; + + private Dimension computedSize; + + private String[] candidates; + + private Dimension candidatesSize; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + repaint(); + } + + public void setOffset(int dx, int dy) { + this.dx = dx; + this.dy = dy; + repaint(); + } + + public void setCandidates(String[] candidates) { + this.candidates = candidates; + candidatesSize = null; + revalidate(); + } + + public int getAlpha() { + return alpha; + } + + public void setAlpha(int alpha) { + this.alpha = alpha; + repaint(); + } + + @Override + public void setFont(Font f) { + super.setFont(f); + candidatesSize = null; + } + + @Override + public Dimension getPreferredSize(int wHint, int hHint) { + if (computedSize == null) { + computeSize(wHint, hHint); + } + return computedSize; + } + + private void computeSize(int wHint, int hHint) { + computedSize = GraphicsUtils.getAdvanced().getTextSize( + text == null || "".equals(text) ? "A" : text, getFont()) //$NON-NLS-1$ //$NON-NLS-2$ + .expand(10, 8); + computeCandidatesSize(); + computedSize.union(candidatesSize); + } + + private void computeCandidatesSize() { + if (candidatesSize != null) + return; + candidatesSize = new Dimension(); + if (candidates == null || candidates.length == 0) + return; + for (String str : candidates) { + candidatesSize.union(GraphicsUtils.getAdvanced().getTextSize(str, + getFont())); + } + } + + @Override + public void invalidate() { + super.invalidate(); + computedSize = null; + } + + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + + if (text == null || "".equals(text)) //$NON-NLS-1$ + return; + + graphics.setAlpha(alpha); + graphics.setForegroundColor(getForegroundColor()); + graphics.setBackgroundColor(getBackgroundColor()); + graphics.setFont(getFont()); + Dimension textSize = GraphicsUtils.getAdvanced().getTextSize(text, + getFont()); + Rectangle b = getBounds(); + graphics.drawText(text, b.x + (b.width - textSize.width) / 2 + dx, b.y + + (b.height - textSize.height) / 2 + dy); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/YearFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/YearFigure.java index a08db92c6..8105b79bf 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/YearFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/YearFigure.java @@ -1,24 +1,24 @@ -/** - * - */ -package org.xmind.ui.datepicker; - -public class YearFigure extends BaseFigure { - - private int year = -1; - - public YearFigure() { - super(); - } - - public int getYear() { - return year; - } - - public void setYear(int year) { - this.year = year; - setText(year < 0 ? null : "" + year); //$NON-NLS-1$ - repaint(); - } - +/** + * + */ +package org.xmind.ui.datepicker; + +public class YearFigure extends BaseFigure { + + private int year = -1; + + public YearFigure() { + super(); + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + setText(year < 0 ? null : "" + year); //$NON-NLS-1$ + repaint(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/messages.properties b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/messages.properties index bae040cff..aa734c508 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/messages.properties +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/messages.properties @@ -1,29 +1,29 @@ -January=January -Feburary=February -March=March -April=April -May=May -June=June -July=July -August=August -September=September -October=October -November=November -December=December -Monday=M -Tuesday=T -Wednesday=W -Thursday=T -Friday=F -Saturday=S -Sunday=S -TodayPattern=Today -None=(None) -Illegal=(Illegal Date) - -TimeCheckInvalid_label=Invalid Value -TimeCheckInvalidSmall_message=The value is too small, we will set it to a proper one. -TimeCheckInvalidBig_message=The value is too big, we will set it to a proper one. - -DatePicker_Time_AM_text=AM -DatePicker_Time_PM_text=PM +January=January +Feburary=February +March=March +April=April +May=May +June=June +July=July +August=August +September=September +October=October +November=November +December=December +Monday=M +Tuesday=T +Wednesday=W +Thursday=T +Friday=F +Saturday=S +Sunday=S +TodayPattern=Today +None=(None) +Illegal=(Illegal Date) + +TimeCheckInvalid_label=Invalid Value +TimeCheckInvalidSmall_message=The value is too small, we will set it to a proper one. +TimeCheckInvalidBig_message=The value is too big, we will set it to a proper one. + +DatePicker_Time_AM_text=AM +DatePicker_Time_PM_text=PM diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/CategorizedGalleryViewer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/CategorizedGalleryViewer.java index f735ddeb4..895c9fa84 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/CategorizedGalleryViewer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/CategorizedGalleryViewer.java @@ -1,421 +1,421 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.BaseLabelProvider; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.jface.viewers.IFontProvider; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.xmind.gef.EditDomain; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.util.Properties; -import org.xmind.ui.viewers.CategorizedViewer; -import org.xmind.ui.viewers.IGraphicalToolTipProvider; -import org.xmind.ui.viewers.IToolTipProvider; - -public class CategorizedGalleryViewer extends CategorizedViewer { - - private static class DelegatingLabelProvider extends BaseLabelProvider - implements ILabelProvider, IColorProvider, IFontProvider, - IToolTipProvider, IGraphicalToolTipProvider, ILabelDecorator { - - private IBaseLabelProvider labelProvider; - - public DelegatingLabelProvider(IBaseLabelProvider labelProvider) { - this.labelProvider = labelProvider; - } - - public boolean isLabelProperty(Object element, String property) { - return labelProvider.isLabelProperty(element, property); - } - - public void addListener(ILabelProviderListener listener) { - super.addListener(listener); - labelProvider.addListener(listener); - } - - public void removeListener(ILabelProviderListener listener) { - super.removeListener(listener); - labelProvider.removeListener(listener); - } - - public void dispose() { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - labelProvider - .removeListener((ILabelProviderListener) listeners[i]); - } - super.dispose(); - } - - public Font getFont(Object element) { - if (labelProvider instanceof IFontProvider) - return ((IFontProvider) labelProvider).getFont(element); - return null; - } - - public Color getForeground(Object element) { - if (labelProvider instanceof IColorProvider) - return ((IColorProvider) labelProvider).getForeground(element); - return null; - } - - public Color getBackground(Object element) { - if (labelProvider instanceof IColorProvider) - return ((IColorProvider) labelProvider).getBackground(element); - return null; - } - - public Image getImage(Object element) { - if (labelProvider instanceof ILabelProvider) - return ((ILabelProvider) labelProvider).getImage(element); - return null; - } - - public String getText(Object element) { - if (labelProvider instanceof ILabelProvider) - return ((ILabelProvider) labelProvider).getText(element); - return ""; //$NON-NLS-1$ - } - - public String getToolTip(Object element) { - if (labelProvider instanceof IToolTipProvider) - return ((IToolTipProvider) labelProvider).getToolTip(element); - return null; - } - - public IFigure getToolTipFigure(Object element) { - if (labelProvider instanceof IGraphicalToolTipProvider) - return ((IGraphicalToolTipProvider) labelProvider) - .getToolTipFigure(element); - return null; - } - - @Override - public IFigure decorateFigure(IFigure figure, Object element, - IDecorationContext context) { - if (labelProvider instanceof ILabelDecorator) - return ((ILabelDecorator) labelProvider).decorateFigure(figure, - element, context); - return figure; - } - - } - - private Map viewers = new HashMap(); - - private Properties properties = new Properties(); - - private ISelectionChangedListener viewerSelectionChangedListener = new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - if (settingViewerSelections) - return; - - for (GalleryViewer viewer : viewers.values()) { - if (viewer != event.getSelectionProvider()) { - setSelectionToNestedViewer(viewer, - StructuredSelection.EMPTY, false); - } - } - - fireSelectionChanged(new SelectionChangedEvent( - CategorizedGalleryViewer.this, getSelection())); - } - - }; - - private IOpenListener viewerOpenListener = new IOpenListener() { - - public void open(OpenEvent event) { - fireOpen(new OpenEvent(CategorizedGalleryViewer.this, - getSelection())); - } - - }; - - private boolean settingViewerSelections = false; - - private EditDomain editDomain = null; - - private Listener selectionClearer = new Listener() { - public void handleEvent(Event event) { - setSelection(StructuredSelection.EMPTY); - } - }; - - public EditDomain getEditDomain() { - return editDomain; - } - - public void setEditDomain(EditDomain editDomain) { - EditDomain oldEditDomain = this.editDomain; - if (oldEditDomain != null) { - oldEditDomain.dispose(); - } - this.editDomain = editDomain; - for (GalleryViewer viewer : viewers.values()) { - viewer.setEditDomain(editDomain); - } - } - - public Properties getProperties() { - return properties; - } - - protected final void hookSelectionClearer(Control control) { - control.addListener(SWT.MouseDown, selectionClearer); - } - - protected void hookControl(Control control) { - super.hookControl(control); - hookSelectionClearer(control); - hookSelectionClearer(((ScrolledForm) control).getBody()); - } - - protected Control createSectionContent(Composite parent, Object category) { - hookSelectionClearer(parent); - Composite wrap = getWidgetFactory().createComposite(parent, SWT.WRAP); - hookSelectionClearer(wrap); - GridLayout wrapLayout = new GridLayout(1, false); - wrapLayout.marginWidth = 0; - wrapLayout.marginHeight = 0; - wrapLayout.verticalSpacing = 0; - wrapLayout.horizontalSpacing = 0; - wrap.setLayout(wrapLayout); - - GalleryViewer viewer = createNestedViewer(); - configureNestedViewer(viewer, category); - Control control = viewer.createControl(wrap); - getWidgetFactory().adapt(control, false, false); - control.setMenu(control.getParent().getMenu()); - hookNestedViewerControl(viewer, category); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - viewer.setSelection(StructuredSelection.EMPTY); - - viewers.put(category, viewer); - - return wrap; - } - - protected void disposeSectionContent(Composite parent, Object category) { - GalleryViewer viewer = viewers.remove(category); - if (viewer != null) { - Control control = viewer.getControl(); - if (control != null && !control.isDisposed()) { - control.getParent().setMenu(null); - control.setMenu(null); - control.dispose(); - } - } - } - - protected void refreshSectionContent(Control content, Object category, - Object element) { - GalleryViewer viewer = viewers.get(category); - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - if (element != null) { - IPart part = viewer.findPart(element); - if (part != null) { - part.refresh(); - } - } else { - viewer.setInput(getElements(category)); - } - } - } - - protected GalleryViewer createNestedViewer() { - return new GalleryViewer(); - } - - protected void configureNestedViewer(GalleryViewer viewer, - Object category) { - viewer.setProperties(properties); - viewer.setContentProvider(new ArrayContentProvider()); - viewer.setLabelProvider( - new DelegatingLabelProvider(getLabelProvider())); - viewer.setFilters(getFilters()); - viewer.setSorter(getSorter()); - viewer.addSelectionChangedListener(viewerSelectionChangedListener); - viewer.addOpenListener(viewerOpenListener); - viewer.setEditDomain(getEditDomain()); - } - - protected void hookNestedViewerControl(GalleryViewer viewer, - Object category) { - // Disable scrolling feature of this viewer so that all - // scroll events will pass through to the scrolled form: - viewer.getCanvas().setScrollBarVisibility(FigureCanvas.NEVER); - ScrollBar hBar = viewer.getCanvas().getHorizontalBar(); - if (hBar != null) { - hBar.setEnabled(false); - hBar.setVisible(false); - } - ScrollBar vBar = viewer.getCanvas().getVerticalBar(); - if (vBar != null) { - vBar.setEnabled(false); - vBar.setVisible(false); - } - } - - protected void reveal(Object category, final Object element) { - if (element != null) { - final GalleryViewer viewer = viewers.get(category); - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - final IPart part = viewer.findPart(element); - if (part != null && part instanceof IGraphicalPart) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - IFigure fig = ((IGraphicalPart) part).getFigure(); - Point loc = viewer.computeToDisplay( - fig.getBounds().getLocation(), true); - loc = new Point( - getContainer().toControl(loc.x, loc.y)); - reveal(loc.x, loc.y - 10); - } - }); - return; - } - } - } - - super.reveal(category, element); - } - - @SuppressWarnings("unchecked") - protected void fillSelection(Object category, List selection) { - GalleryViewer viewer = viewers.get(category); - if (viewer != null) { - ISelection sel = viewer.getSelection(); - if (sel instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) sel; - selection.addAll(ss.toList()); - } - } - } - - protected void setSelectionToCategory(Object category, ISelection selection, - boolean reveal) { - GalleryViewer viewer = viewers.get(category); - if (viewer != null) { - setSelectionToNestedViewer(viewer, selection, reveal); - } - } - - private void setSelectionToNestedViewer(GalleryViewer viewer, - ISelection selection, boolean reveal) { - settingViewerSelections = true; - try { - viewer.setSelection(selection, reveal); - } finally { - settingViewerSelections = false; - } - } - - public GalleryViewer getNestedViewer(Object category) { - return viewers.get(category); - } - - protected void handleDispose(DisposeEvent event) { - super.handleDispose(event); - viewers.clear(); - } - - public void setLabelProvider(IBaseLabelProvider labelProvider) { - super.setLabelProvider(labelProvider); - for (GalleryViewer viewer : viewers.values()) { - viewer.setLabelProvider(labelProvider); - } - } - - public void setSorter(ViewerSorter sorter) { - super.setSorter(sorter); - for (GalleryViewer viewer : viewers.values()) { - viewer.setSorter(sorter); - } - } - - public void addFilter(ViewerFilter filter) { - super.addFilter(filter); - for (GalleryViewer viewer : viewers.values()) { - viewer.addFilter(filter); - } - } - - public void removeFilter(ViewerFilter filter) { - super.removeFilter(filter); - for (GalleryViewer viewer : viewers.values()) { - viewer.removeFilter(filter); - } - } - - public void setFilters(ViewerFilter... filters) { - super.setFilters(filters); - for (GalleryViewer viewer : viewers.values()) { - viewer.setFilters(filters); - } - } - - protected void doUpdateItem(Widget item, Object element, boolean fullMap) { - super.doUpdateItem(item, element, fullMap); - Object category = getCategory(element); - if (category != null) { - GalleryViewer viewer = viewers.get(category); - if (viewer != null) { - viewer.update(new Object[] { element }); - } - } - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.xmind.gef.EditDomain; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.viewers.CategorizedViewer; +import org.xmind.ui.viewers.IGraphicalToolTipProvider; +import org.xmind.ui.viewers.IToolTipProvider; + +public class CategorizedGalleryViewer extends CategorizedViewer { + + private static class DelegatingLabelProvider extends BaseLabelProvider + implements ILabelProvider, IColorProvider, IFontProvider, + IToolTipProvider, IGraphicalToolTipProvider, ILabelDecorator { + + private IBaseLabelProvider labelProvider; + + public DelegatingLabelProvider(IBaseLabelProvider labelProvider) { + this.labelProvider = labelProvider; + } + + public boolean isLabelProperty(Object element, String property) { + return labelProvider.isLabelProperty(element, property); + } + + public void addListener(ILabelProviderListener listener) { + super.addListener(listener); + labelProvider.addListener(listener); + } + + public void removeListener(ILabelProviderListener listener) { + super.removeListener(listener); + labelProvider.removeListener(listener); + } + + public void dispose() { + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + labelProvider + .removeListener((ILabelProviderListener) listeners[i]); + } + super.dispose(); + } + + public Font getFont(Object element) { + if (labelProvider instanceof IFontProvider) + return ((IFontProvider) labelProvider).getFont(element); + return null; + } + + public Color getForeground(Object element) { + if (labelProvider instanceof IColorProvider) + return ((IColorProvider) labelProvider).getForeground(element); + return null; + } + + public Color getBackground(Object element) { + if (labelProvider instanceof IColorProvider) + return ((IColorProvider) labelProvider).getBackground(element); + return null; + } + + public Image getImage(Object element) { + if (labelProvider instanceof ILabelProvider) + return ((ILabelProvider) labelProvider).getImage(element); + return null; + } + + public String getText(Object element) { + if (labelProvider instanceof ILabelProvider) + return ((ILabelProvider) labelProvider).getText(element); + return ""; //$NON-NLS-1$ + } + + public String getToolTip(Object element) { + if (labelProvider instanceof IToolTipProvider) + return ((IToolTipProvider) labelProvider).getToolTip(element); + return null; + } + + public IFigure getToolTipFigure(Object element) { + if (labelProvider instanceof IGraphicalToolTipProvider) + return ((IGraphicalToolTipProvider) labelProvider) + .getToolTipFigure(element); + return null; + } + + @Override + public IFigure decorateFigure(IFigure figure, Object element, + IDecorationContext context) { + if (labelProvider instanceof ILabelDecorator) + return ((ILabelDecorator) labelProvider).decorateFigure(figure, + element, context); + return figure; + } + + } + + private Map viewers = new HashMap(); + + private Properties properties = new Properties(); + + private ISelectionChangedListener viewerSelectionChangedListener = new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + if (settingViewerSelections) + return; + + for (GalleryViewer viewer : viewers.values()) { + if (viewer != event.getSelectionProvider()) { + setSelectionToNestedViewer(viewer, + StructuredSelection.EMPTY, false); + } + } + + fireSelectionChanged(new SelectionChangedEvent( + CategorizedGalleryViewer.this, getSelection())); + } + + }; + + private IOpenListener viewerOpenListener = new IOpenListener() { + + public void open(OpenEvent event) { + fireOpen(new OpenEvent(CategorizedGalleryViewer.this, + getSelection())); + } + + }; + + private boolean settingViewerSelections = false; + + private EditDomain editDomain = null; + + private Listener selectionClearer = new Listener() { + public void handleEvent(Event event) { + setSelection(StructuredSelection.EMPTY); + } + }; + + public EditDomain getEditDomain() { + return editDomain; + } + + public void setEditDomain(EditDomain editDomain) { + EditDomain oldEditDomain = this.editDomain; + if (oldEditDomain != null) { + oldEditDomain.dispose(); + } + this.editDomain = editDomain; + for (GalleryViewer viewer : viewers.values()) { + viewer.setEditDomain(editDomain); + } + } + + public Properties getProperties() { + return properties; + } + + protected final void hookSelectionClearer(Control control) { + control.addListener(SWT.MouseDown, selectionClearer); + } + + protected void hookControl(Control control) { + super.hookControl(control); + hookSelectionClearer(control); + hookSelectionClearer(((ScrolledForm) control).getBody()); + } + + protected Control createSectionContent(Composite parent, Object category) { + hookSelectionClearer(parent); + Composite wrap = getWidgetFactory().createComposite(parent, SWT.WRAP); + hookSelectionClearer(wrap); + GridLayout wrapLayout = new GridLayout(1, false); + wrapLayout.marginWidth = 0; + wrapLayout.marginHeight = 0; + wrapLayout.verticalSpacing = 0; + wrapLayout.horizontalSpacing = 0; + wrap.setLayout(wrapLayout); + + GalleryViewer viewer = createNestedViewer(); + configureNestedViewer(viewer, category); + Control control = viewer.createControl(wrap); + getWidgetFactory().adapt(control, false, false); + control.setMenu(control.getParent().getMenu()); + hookNestedViewerControl(viewer, category); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + viewer.setSelection(StructuredSelection.EMPTY); + + viewers.put(category, viewer); + + return wrap; + } + + protected void disposeSectionContent(Composite parent, Object category) { + GalleryViewer viewer = viewers.remove(category); + if (viewer != null) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.getParent().setMenu(null); + control.setMenu(null); + control.dispose(); + } + } + } + + protected void refreshSectionContent(Control content, Object category, + Object element) { + GalleryViewer viewer = viewers.get(category); + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + if (element != null) { + IPart part = viewer.findPart(element); + if (part != null) { + part.refresh(); + } + } else { + viewer.setInput(getElements(category)); + } + } + } + + protected GalleryViewer createNestedViewer() { + return new GalleryViewer(); + } + + protected void configureNestedViewer(GalleryViewer viewer, + Object category) { + viewer.setProperties(properties); + viewer.setContentProvider(new ArrayContentProvider()); + viewer.setLabelProvider( + new DelegatingLabelProvider(getLabelProvider())); + viewer.setFilters(getFilters()); + viewer.setSorter(getSorter()); + viewer.addSelectionChangedListener(viewerSelectionChangedListener); + viewer.addOpenListener(viewerOpenListener); + viewer.setEditDomain(getEditDomain()); + } + + protected void hookNestedViewerControl(GalleryViewer viewer, + Object category) { + // Disable scrolling feature of this viewer so that all + // scroll events will pass through to the scrolled form: + viewer.getCanvas().setScrollBarVisibility(FigureCanvas.NEVER); + ScrollBar hBar = viewer.getCanvas().getHorizontalBar(); + if (hBar != null) { + hBar.setEnabled(false); + hBar.setVisible(false); + } + ScrollBar vBar = viewer.getCanvas().getVerticalBar(); + if (vBar != null) { + vBar.setEnabled(false); + vBar.setVisible(false); + } + } + + protected void reveal(Object category, final Object element) { + if (element != null) { + final GalleryViewer viewer = viewers.get(category); + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + final IPart part = viewer.findPart(element); + if (part != null && part instanceof IGraphicalPart) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + IFigure fig = ((IGraphicalPart) part).getFigure(); + Point loc = viewer.computeToDisplay( + fig.getBounds().getLocation(), true); + loc = new Point( + getContainer().toControl(loc.x, loc.y)); + reveal(loc.x, loc.y - 10); + } + }); + return; + } + } + } + + super.reveal(category, element); + } + + @SuppressWarnings("unchecked") + protected void fillSelection(Object category, List selection) { + GalleryViewer viewer = viewers.get(category); + if (viewer != null) { + ISelection sel = viewer.getSelection(); + if (sel instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) sel; + selection.addAll(ss.toList()); + } + } + } + + protected void setSelectionToCategory(Object category, ISelection selection, + boolean reveal) { + GalleryViewer viewer = viewers.get(category); + if (viewer != null) { + setSelectionToNestedViewer(viewer, selection, reveal); + } + } + + private void setSelectionToNestedViewer(GalleryViewer viewer, + ISelection selection, boolean reveal) { + settingViewerSelections = true; + try { + viewer.setSelection(selection, reveal); + } finally { + settingViewerSelections = false; + } + } + + public GalleryViewer getNestedViewer(Object category) { + return viewers.get(category); + } + + protected void handleDispose(DisposeEvent event) { + super.handleDispose(event); + viewers.clear(); + } + + public void setLabelProvider(IBaseLabelProvider labelProvider) { + super.setLabelProvider(labelProvider); + for (GalleryViewer viewer : viewers.values()) { + viewer.setLabelProvider(labelProvider); + } + } + + public void setSorter(ViewerSorter sorter) { + super.setSorter(sorter); + for (GalleryViewer viewer : viewers.values()) { + viewer.setSorter(sorter); + } + } + + public void addFilter(ViewerFilter filter) { + super.addFilter(filter); + for (GalleryViewer viewer : viewers.values()) { + viewer.addFilter(filter); + } + } + + public void removeFilter(ViewerFilter filter) { + super.removeFilter(filter); + for (GalleryViewer viewer : viewers.values()) { + viewer.removeFilter(filter); + } + } + + public void setFilters(ViewerFilter... filters) { + super.setFilters(filters); + for (GalleryViewer viewer : viewers.values()) { + viewer.setFilters(filters); + } + } + + protected void doUpdateItem(Widget item, Object element, boolean fullMap) { + super.doUpdateItem(item, element, fullMap); + Object category = getCategory(element); + if (category != null) { + GalleryViewer viewer = viewers.get(category); + if (viewer != null) { + viewer.update(new Object[] { element }); + } + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPane.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPane.java index 3129cd0b4..35d285020 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPane.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPane.java @@ -1,354 +1,354 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import static org.xmind.ui.gallery.GalleryLayout.ALIGN_CENTER; -import static org.xmind.ui.gallery.GalleryLayout.ALIGN_FILL; - -import java.util.Iterator; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.FlowLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.AdvancedToolbarLayout; -import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; - -public class ContentPane extends Figure { - - private class ContentPaneFlowLayout extends FlowLayout { - - /** - * Holds the necessary information for layout calculations. - */ - private class WorkingData2 { - public Rectangle bounds[], area; - public IFigure row[]; - public int rowHeight, rowWidth, rowCount, rowX, rowY, maxWidth; - } - - private WorkingData2 data2 = null; - - private int minorSpacing2 = 0; - - public ContentPaneFlowLayout(boolean isHorizontal) { - super(isHorizontal); - } - - public void setMinorSpacing2(int minorSpacing2) { - this.minorSpacing2 = minorSpacing2; - } - - public int getMinorSpacing2() { - return minorSpacing2; - } - - @Override - public void layout(IFigure parent) { - data2 = new WorkingData2(); - Rectangle relativeArea = parent.getClientArea(); - data2.area = transposer.t(relativeArea); - - Iterator iterator = parent.getChildren().iterator(); - int dx; - - // Calculate the hints to be passed to children - int wHint = -1; - int hHint = -1; - if (isHorizontal()) - wHint = parent.getClientArea().width; - else - hHint = parent.getClientArea().height; - - initVariables2(parent); - initRow2(); - while (iterator.hasNext()) { - IFigure f = (IFigure) iterator.next(); - Dimension pref = transposer.t(getChildSize(f, wHint, hHint)); - Rectangle r = new Rectangle(0, 0, pref.width, pref.height); - - if (data2.rowCount > 0) { - if (data2.rowWidth + pref.width > data2.maxWidth) - layoutRow(parent); - } - r.x = data2.rowX; - r.y = data2.rowY; - dx = r.width + Math.max(getMinorSpacing(), getMinorSpacing2()); - data2.rowX += dx; - data2.rowWidth += dx; - data2.rowHeight = Math.max(data2.rowHeight, r.height); - data2.row[data2.rowCount] = f; - data2.bounds[data2.rowCount] = r; - data2.rowCount++; - } - if (data2.rowCount != 0) - layoutRow(parent); - data2 = null; - } - - @Override - protected void layoutRow(IFigure parent) { - int majorAdjustment = 0; - int minorAdjustment = 0; - int correctMajorAlignment = getMajorAlignment(); - int correctMinorAlignment = getMinorAlignment(); - - majorAdjustment = data2.area.width - data2.rowWidth - + Math.max(getMinorSpacing(), getMinorSpacing2()); - - switch (correctMajorAlignment) { - case ALIGN_TOPLEFT: - majorAdjustment = 0; - break; - case ALIGN_CENTER: - majorAdjustment /= 2; - break; - case ALIGN_BOTTOMRIGHT: - break; - } - - for (int j = 0; j < data2.rowCount; j++) { - if (isStretchMinorAxis()) { - data2.bounds[j].height = data2.rowHeight; - } else { - minorAdjustment = data2.rowHeight - data2.bounds[j].height; - switch (correctMinorAlignment) { - case ALIGN_TOPLEFT: - minorAdjustment = 0; - break; - case ALIGN_CENTER: - minorAdjustment /= 2; - break; - case ALIGN_BOTTOMRIGHT: - break; - } - data2.bounds[j].y += minorAdjustment; - } - data2.bounds[j].x += majorAdjustment; - - setBoundsOfChild(parent, data2.row[j], - transposer.t(data2.bounds[j])); - } - data2.rowY += getMajorSpacing() + data2.rowHeight; - initRow2(); - } - - private void initRow2() { - data2.rowX = 0; - data2.rowHeight = 0; - data2.rowWidth = 0; - data2.rowCount = 0; - } - - private void initVariables2(IFigure parent) { - data2.row = new IFigure[parent.getChildren().size()]; - data2.bounds = new Rectangle[data2.row.length]; - data2.maxWidth = data2.area.width; - } - } - - private AdvancedToolbarLayout layout = null; - - private FlowLayout wrapLayout = null; - - private int minorAlign = -1; - - private int minorSpacing = -1; - - private SpaceCollaborativeEngine spaceCollaborativeEngine = null; - - /** - * - */ - public ContentPane() { - this(false, false, false); - } - - /** - * @param isHorizontal - * @param stretchMinorAxis - * @param wrap - */ - public ContentPane(boolean isHorizontal, boolean stretchMinorAxis, - boolean wrap) { - if (wrap) { - wrapLayout = new ContentPaneFlowLayout(isHorizontal); - wrapLayout.setStretchMinorAxis(stretchMinorAxis); - wrapLayout.setMajorAlignment(FlowLayout.ALIGN_CENTER); - wrapLayout.setMinorAlignment(FlowLayout.ALIGN_CENTER); - wrapLayout.setMajorSpacing(10); - wrapLayout.setMinorSpacing(5); - super.setLayoutManager(wrapLayout); - } else { - layout = new AdvancedToolbarLayout(isHorizontal); - layout.setStretchMinorAxis(stretchMinorAxis); - layout.setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - layout.setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - layout.setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - layout.setSpacing(10); - super.setLayoutManager(layout); - } - - } - - public void setLayoutManager(LayoutManager manager) { - // Do nothing to prevent external layout manager to be set. - } - - public boolean isHorizontal() { - if (isWrap()) - return wrapLayout.isHorizontal(); - return layout.isHorizontal(); - } - - public void setHorizontal(boolean horizontal) { - if (horizontal == isHorizontal()) - return; - - if (wrapLayout != null) - wrapLayout.setHorizontal(horizontal); - if (layout != null) - layout.setHorizontal(horizontal); - revalidate(); - } - - public boolean isWrap() { - return getLayoutManager() == wrapLayout; - } - - public void setWrap(boolean wrap) { - if (wrap == isWrap()) - return; - if (wrap) { - if (wrapLayout == null) { - boolean horizontal = isHorizontal(); - int majorAlignment = getMajorAlignment(); - int minorAlignment = getMinorAlignment(); - int majorSpacing = getMajorSpacing(); - int minorSpacing = getMinorSpacing(); - wrapLayout = new ContentPaneFlowLayout(horizontal); - wrapLayout.setMajorAlignment(majorAlignment); - wrapLayout.setMajorSpacing(majorSpacing); - wrapLayout.setMinorSpacing(minorSpacing); - boolean fill = minorAlignment == ALIGN_FILL; - wrapLayout.setStretchMinorAxis(fill); - wrapLayout.setMinorAlignment( - fill ? ALIGN_CENTER : minorAlignment); - } - super.setLayoutManager(wrapLayout); - } else { - if (layout == null) { - boolean horizontal = isHorizontal(); - int majorAlignment = getMajorAlignment(); - int minorAlignment = getMinorAlignment(); - layout = new AdvancedToolbarLayout(horizontal); - layout.setMajorAlignment(majorAlignment); - layout.setSpacing(minorSpacing); - boolean fill = minorAlignment == ALIGN_FILL; - layout.setStretchMinorAxis(fill); - layout.setMinorAlignment(fill ? ALIGN_CENTER : minorAlignment); - } - super.setLayoutManager(layout); - } - } - - public int getMajorAlignment() { - if (isWrap()) - return wrapLayout.getMajorAlignment(); - return layout.getMajorAlignment(); - } - - public int getMinorAlignment() { - return minorAlign; - } - - public void setMajorAlignment(int alignment) { - if (alignment == getMajorAlignment()) - return; - - if (wrapLayout != null) - wrapLayout.setMajorAlignment(alignment); - if (layout != null) - layout.setMajorAlignment(alignment); - revalidate(); - } - - public void setMinorAlignment(int alignment) { - if (minorAlign >= 0 && alignment == getMinorAlignment()) - return; - - this.minorAlign = alignment; - boolean fill = alignment == ALIGN_FILL; - if (wrapLayout != null) { - wrapLayout.setStretchMinorAxis(fill); - wrapLayout.setMinorAlignment(fill ? ALIGN_CENTER : alignment); - } - if (layout != null) { - layout.setStretchMinorAxis(fill); - layout.setInnerMinorAlignment(fill ? ALIGN_CENTER : alignment); - } - revalidate(); - } - - public int getMajorSpacing() { - if (isWrap()) - return wrapLayout.getMajorSpacing(); - return layout.getSpacing(); - } - - public void setMajorSpacing(int spacing) { - if (spacing == getMajorSpacing()) - return; - - if (wrapLayout != null) - wrapLayout.setMajorSpacing(spacing); - if (layout != null) - layout.setSpacing(spacing); - revalidate(); - } - - public int getMinorSpacing() { - return minorSpacing; - } - - public void setMinorSpacing(int spacing) { - if (minorSpacing >= 0 && spacing == getMinorSpacing()) - return; - - this.minorSpacing = spacing; - if (wrapLayout != null) - ((ContentPaneFlowLayout) wrapLayout).setMinorSpacing2(spacing); - revalidate(); - } - - @Override - public void invalidate() { - if (getSpaceCollaborativeEngine() != null) { - getSpaceCollaborativeEngine().refreshMinorSpace(); - } - super.invalidate(); - } - - public SpaceCollaborativeEngine getSpaceCollaborativeEngine() { - return spaceCollaborativeEngine; - } - - public void setSpaceCollaborativeEngine( - SpaceCollaborativeEngine spaceCollaborativeEngine) { - this.spaceCollaborativeEngine = spaceCollaborativeEngine; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import static org.xmind.ui.gallery.GalleryLayout.ALIGN_CENTER; +import static org.xmind.ui.gallery.GalleryLayout.ALIGN_FILL; + +import java.util.Iterator; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.AdvancedToolbarLayout; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; + +public class ContentPane extends Figure { + + private class ContentPaneFlowLayout extends FlowLayout { + + /** + * Holds the necessary information for layout calculations. + */ + private class WorkingData2 { + public Rectangle bounds[], area; + public IFigure row[]; + public int rowHeight, rowWidth, rowCount, rowX, rowY, maxWidth; + } + + private WorkingData2 data2 = null; + + private int minorSpacing2 = 0; + + public ContentPaneFlowLayout(boolean isHorizontal) { + super(isHorizontal); + } + + public void setMinorSpacing2(int minorSpacing2) { + this.minorSpacing2 = minorSpacing2; + } + + public int getMinorSpacing2() { + return minorSpacing2; + } + + @Override + public void layout(IFigure parent) { + data2 = new WorkingData2(); + Rectangle relativeArea = parent.getClientArea(); + data2.area = transposer.t(relativeArea); + + Iterator iterator = parent.getChildren().iterator(); + int dx; + + // Calculate the hints to be passed to children + int wHint = -1; + int hHint = -1; + if (isHorizontal()) + wHint = parent.getClientArea().width; + else + hHint = parent.getClientArea().height; + + initVariables2(parent); + initRow2(); + while (iterator.hasNext()) { + IFigure f = (IFigure) iterator.next(); + Dimension pref = transposer.t(getChildSize(f, wHint, hHint)); + Rectangle r = new Rectangle(0, 0, pref.width, pref.height); + + if (data2.rowCount > 0) { + if (data2.rowWidth + pref.width > data2.maxWidth) + layoutRow(parent); + } + r.x = data2.rowX; + r.y = data2.rowY; + dx = r.width + Math.max(getMinorSpacing(), getMinorSpacing2()); + data2.rowX += dx; + data2.rowWidth += dx; + data2.rowHeight = Math.max(data2.rowHeight, r.height); + data2.row[data2.rowCount] = f; + data2.bounds[data2.rowCount] = r; + data2.rowCount++; + } + if (data2.rowCount != 0) + layoutRow(parent); + data2 = null; + } + + @Override + protected void layoutRow(IFigure parent) { + int majorAdjustment = 0; + int minorAdjustment = 0; + int correctMajorAlignment = getMajorAlignment(); + int correctMinorAlignment = getMinorAlignment(); + + majorAdjustment = data2.area.width - data2.rowWidth + + Math.max(getMinorSpacing(), getMinorSpacing2()); + + switch (correctMajorAlignment) { + case ALIGN_TOPLEFT: + majorAdjustment = 0; + break; + case ALIGN_CENTER: + majorAdjustment /= 2; + break; + case ALIGN_BOTTOMRIGHT: + break; + } + + for (int j = 0; j < data2.rowCount; j++) { + if (isStretchMinorAxis()) { + data2.bounds[j].height = data2.rowHeight; + } else { + minorAdjustment = data2.rowHeight - data2.bounds[j].height; + switch (correctMinorAlignment) { + case ALIGN_TOPLEFT: + minorAdjustment = 0; + break; + case ALIGN_CENTER: + minorAdjustment /= 2; + break; + case ALIGN_BOTTOMRIGHT: + break; + } + data2.bounds[j].y += minorAdjustment; + } + data2.bounds[j].x += majorAdjustment; + + setBoundsOfChild(parent, data2.row[j], + transposer.t(data2.bounds[j])); + } + data2.rowY += getMajorSpacing() + data2.rowHeight; + initRow2(); + } + + private void initRow2() { + data2.rowX = 0; + data2.rowHeight = 0; + data2.rowWidth = 0; + data2.rowCount = 0; + } + + private void initVariables2(IFigure parent) { + data2.row = new IFigure[parent.getChildren().size()]; + data2.bounds = new Rectangle[data2.row.length]; + data2.maxWidth = data2.area.width; + } + } + + private AdvancedToolbarLayout layout = null; + + private FlowLayout wrapLayout = null; + + private int minorAlign = -1; + + private int minorSpacing = -1; + + private SpaceCollaborativeEngine spaceCollaborativeEngine = null; + + /** + * + */ + public ContentPane() { + this(false, false, false); + } + + /** + * @param isHorizontal + * @param stretchMinorAxis + * @param wrap + */ + public ContentPane(boolean isHorizontal, boolean stretchMinorAxis, + boolean wrap) { + if (wrap) { + wrapLayout = new ContentPaneFlowLayout(isHorizontal); + wrapLayout.setStretchMinorAxis(stretchMinorAxis); + wrapLayout.setMajorAlignment(FlowLayout.ALIGN_CENTER); + wrapLayout.setMinorAlignment(FlowLayout.ALIGN_CENTER); + wrapLayout.setMajorSpacing(10); + wrapLayout.setMinorSpacing(5); + super.setLayoutManager(wrapLayout); + } else { + layout = new AdvancedToolbarLayout(isHorizontal); + layout.setStretchMinorAxis(stretchMinorAxis); + layout.setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + layout.setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + layout.setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + layout.setSpacing(10); + super.setLayoutManager(layout); + } + + } + + public void setLayoutManager(LayoutManager manager) { + // Do nothing to prevent external layout manager to be set. + } + + public boolean isHorizontal() { + if (isWrap()) + return wrapLayout.isHorizontal(); + return layout.isHorizontal(); + } + + public void setHorizontal(boolean horizontal) { + if (horizontal == isHorizontal()) + return; + + if (wrapLayout != null) + wrapLayout.setHorizontal(horizontal); + if (layout != null) + layout.setHorizontal(horizontal); + revalidate(); + } + + public boolean isWrap() { + return getLayoutManager() == wrapLayout; + } + + public void setWrap(boolean wrap) { + if (wrap == isWrap()) + return; + if (wrap) { + if (wrapLayout == null) { + boolean horizontal = isHorizontal(); + int majorAlignment = getMajorAlignment(); + int minorAlignment = getMinorAlignment(); + int majorSpacing = getMajorSpacing(); + int minorSpacing = getMinorSpacing(); + wrapLayout = new ContentPaneFlowLayout(horizontal); + wrapLayout.setMajorAlignment(majorAlignment); + wrapLayout.setMajorSpacing(majorSpacing); + wrapLayout.setMinorSpacing(minorSpacing); + boolean fill = minorAlignment == ALIGN_FILL; + wrapLayout.setStretchMinorAxis(fill); + wrapLayout.setMinorAlignment( + fill ? ALIGN_CENTER : minorAlignment); + } + super.setLayoutManager(wrapLayout); + } else { + if (layout == null) { + boolean horizontal = isHorizontal(); + int majorAlignment = getMajorAlignment(); + int minorAlignment = getMinorAlignment(); + layout = new AdvancedToolbarLayout(horizontal); + layout.setMajorAlignment(majorAlignment); + layout.setSpacing(minorSpacing); + boolean fill = minorAlignment == ALIGN_FILL; + layout.setStretchMinorAxis(fill); + layout.setMinorAlignment(fill ? ALIGN_CENTER : minorAlignment); + } + super.setLayoutManager(layout); + } + } + + public int getMajorAlignment() { + if (isWrap()) + return wrapLayout.getMajorAlignment(); + return layout.getMajorAlignment(); + } + + public int getMinorAlignment() { + return minorAlign; + } + + public void setMajorAlignment(int alignment) { + if (alignment == getMajorAlignment()) + return; + + if (wrapLayout != null) + wrapLayout.setMajorAlignment(alignment); + if (layout != null) + layout.setMajorAlignment(alignment); + revalidate(); + } + + public void setMinorAlignment(int alignment) { + if (minorAlign >= 0 && alignment == getMinorAlignment()) + return; + + this.minorAlign = alignment; + boolean fill = alignment == ALIGN_FILL; + if (wrapLayout != null) { + wrapLayout.setStretchMinorAxis(fill); + wrapLayout.setMinorAlignment(fill ? ALIGN_CENTER : alignment); + } + if (layout != null) { + layout.setStretchMinorAxis(fill); + layout.setInnerMinorAlignment(fill ? ALIGN_CENTER : alignment); + } + revalidate(); + } + + public int getMajorSpacing() { + if (isWrap()) + return wrapLayout.getMajorSpacing(); + return layout.getSpacing(); + } + + public void setMajorSpacing(int spacing) { + if (spacing == getMajorSpacing()) + return; + + if (wrapLayout != null) + wrapLayout.setMajorSpacing(spacing); + if (layout != null) + layout.setSpacing(spacing); + revalidate(); + } + + public int getMinorSpacing() { + return minorSpacing; + } + + public void setMinorSpacing(int spacing) { + if (minorSpacing >= 0 && spacing == getMinorSpacing()) + return; + + this.minorSpacing = spacing; + if (wrapLayout != null) + ((ContentPaneFlowLayout) wrapLayout).setMinorSpacing2(spacing); + revalidate(); + } + + @Override + public void invalidate() { + if (getSpaceCollaborativeEngine() != null) { + getSpaceCollaborativeEngine().refreshMinorSpace(); + } + super.invalidate(); + } + + public SpaceCollaborativeEngine getSpaceCollaborativeEngine() { + return spaceCollaborativeEngine; + } + + public void setSpaceCollaborativeEngine( + SpaceCollaborativeEngine spaceCollaborativeEngine) { + this.spaceCollaborativeEngine = spaceCollaborativeEngine; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameDecorator.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameDecorator.java index 73d7b0651..d4443b1e0 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameDecorator.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameDecorator.java @@ -1,122 +1,122 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Label; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.jface.viewers.IFontProvider; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.IViewer; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.util.Properties; -import org.xmind.ui.viewers.IGraphicalToolTipProvider; -import org.xmind.ui.viewers.IToolTipProvider; - -public class FrameDecorator extends Decorator { - - public static final FrameDecorator DEFAULT = new FrameDecorator(); - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - FrameFigure frame = (FrameFigure) part.getFigure(); - Object model = part.getModel(); - - IViewer viewer = part.getSite().getViewer(); - Properties properties = viewer.getProperties(); - IBaseLabelProvider labelProvider = (IBaseLabelProvider) viewer - .getAdapter(IBaseLabelProvider.class); - - boolean hideTitle = properties.getBoolean(GalleryViewer.HideTitle, - false); - frame.setHideTitle(hideTitle); - - boolean flat = properties.getBoolean(GalleryViewer.FlatFrames, false); - frame.setFlat(flat); - frame.setContentSize( - (Dimension) properties.get(GalleryViewer.FrameContentSize)); - - int titlePlacement = properties.getInteger(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_TOP.intValue()); - frame.setTitlePlacement(titlePlacement); - if (!hideTitle) { - decorateTitle(frame.getTitle(), model, labelProvider); - } - - boolean useCustomDecorator = properties - .getBoolean(GalleryViewer.CustomContentPaneDecorator, false); - if (useCustomDecorator && labelProvider instanceof ILabelDecorator) { - IDecorationContext context = viewer instanceof IDecorationContext - ? (IDecorationContext) viewer : null; - ((ILabelDecorator) labelProvider) - .decorateFigure(frame.getContentPane(), model, context); - } - - if (labelProvider instanceof IGraphicalToolTipProvider) { - IGraphicalToolTipProvider toolTipProvider = (IGraphicalToolTipProvider) labelProvider; - IFigure toolTipFigure = toolTipProvider.getToolTipFigure(model); - frame.setToolTip(toolTipFigure); - } - if (labelProvider instanceof IToolTipProvider) { - IToolTipProvider toolTipProvider = (IToolTipProvider) labelProvider; - String toolTip = toolTipProvider.getToolTip(model); - if (toolTip == null || "".equals(toolTip)) { //$NON-NLS-1$ - frame.setToolTip(null); - } else { - Label toolTipFigure = new Label(); - toolTipFigure.setText(toolTip); - frame.setToolTip(toolTipFigure); - } - } - - ShadowedLayer layer = frame.getContentPane(); - layer.setBorderWidth( - properties.getInteger(GalleryViewer.ContentPaneBorderWidth, 1)); - Object color = properties.get(GalleryViewer.ContentPaneBorderColor); - if (color != null && color instanceof Color) { - layer.setBorderAlpha(0xff); - layer.setBorderColor((Color) color); - } - - } - - private String getText(Object element, IBaseLabelProvider labelProvider) { - if (labelProvider instanceof ILabelProvider) - return ((ILabelProvider) labelProvider).getText(element); - return null; - } - - protected void decorateTitle(ITextFigure titleFigure, Object model, - IBaseLabelProvider labelProvider) { - String text = getText(model, labelProvider); - if (text == null) - text = ""; //$NON-NLS-1$ - titleFigure.setText(text); - if (labelProvider instanceof IFontProvider) { - IFontProvider fontProvider = (IFontProvider) labelProvider; - titleFigure.setFont(fontProvider.getFont(model)); - } - if (labelProvider instanceof IColorProvider) { - IColorProvider colorProvider = (IColorProvider) labelProvider; - titleFigure.setForegroundColor(colorProvider.getForeground(model)); - titleFigure.setBackgroundColor(colorProvider.getBackground(model)); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.IViewer; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.viewers.IGraphicalToolTipProvider; +import org.xmind.ui.viewers.IToolTipProvider; + +public class FrameDecorator extends Decorator { + + public static final FrameDecorator DEFAULT = new FrameDecorator(); + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + FrameFigure frame = (FrameFigure) part.getFigure(); + Object model = part.getModel(); + + IViewer viewer = part.getSite().getViewer(); + Properties properties = viewer.getProperties(); + IBaseLabelProvider labelProvider = (IBaseLabelProvider) viewer + .getAdapter(IBaseLabelProvider.class); + + boolean hideTitle = properties.getBoolean(GalleryViewer.HideTitle, + false); + frame.setHideTitle(hideTitle); + + boolean flat = properties.getBoolean(GalleryViewer.FlatFrames, false); + frame.setFlat(flat); + frame.setContentSize( + (Dimension) properties.get(GalleryViewer.FrameContentSize)); + + int titlePlacement = properties.getInteger(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_TOP.intValue()); + frame.setTitlePlacement(titlePlacement); + if (!hideTitle) { + decorateTitle(frame.getTitle(), model, labelProvider); + } + + boolean useCustomDecorator = properties + .getBoolean(GalleryViewer.CustomContentPaneDecorator, false); + if (useCustomDecorator && labelProvider instanceof ILabelDecorator) { + IDecorationContext context = viewer instanceof IDecorationContext + ? (IDecorationContext) viewer : null; + ((ILabelDecorator) labelProvider) + .decorateFigure(frame.getContentPane(), model, context); + } + + if (labelProvider instanceof IGraphicalToolTipProvider) { + IGraphicalToolTipProvider toolTipProvider = (IGraphicalToolTipProvider) labelProvider; + IFigure toolTipFigure = toolTipProvider.getToolTipFigure(model); + frame.setToolTip(toolTipFigure); + } + if (labelProvider instanceof IToolTipProvider) { + IToolTipProvider toolTipProvider = (IToolTipProvider) labelProvider; + String toolTip = toolTipProvider.getToolTip(model); + if (toolTip == null || "".equals(toolTip)) { //$NON-NLS-1$ + frame.setToolTip(null); + } else { + Label toolTipFigure = new Label(); + toolTipFigure.setText(toolTip); + frame.setToolTip(toolTipFigure); + } + } + + ShadowedLayer layer = frame.getContentPane(); + layer.setBorderWidth( + properties.getInteger(GalleryViewer.ContentPaneBorderWidth, 1)); + Object color = properties.get(GalleryViewer.ContentPaneBorderColor); + if (color != null && color instanceof Color) { + layer.setBorderAlpha(0xff); + layer.setBorderColor((Color) color); + } + + } + + private String getText(Object element, IBaseLabelProvider labelProvider) { + if (labelProvider instanceof ILabelProvider) + return ((ILabelProvider) labelProvider).getText(element); + return null; + } + + protected void decorateTitle(ITextFigure titleFigure, Object model, + IBaseLabelProvider labelProvider) { + String text = getText(model, labelProvider); + if (text == null) + text = ""; //$NON-NLS-1$ + titleFigure.setText(text); + if (labelProvider instanceof IFontProvider) { + IFontProvider fontProvider = (IFontProvider) labelProvider; + titleFigure.setFont(fontProvider.getFont(model)); + } + if (labelProvider instanceof IColorProvider) { + IColorProvider colorProvider = (IColorProvider) labelProvider; + titleFigure.setForegroundColor(colorProvider.getForeground(model)); + titleFigure.setBackgroundColor(colorProvider.getBackground(model)); + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameFigure.java index c112d2d02..236b6c58d 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FrameFigure.java @@ -1,318 +1,318 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.MarginBorder; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.StackLayout; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.AdvancedToolbarLayout; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.ui.resources.ColorUtils; - -/** - * @author Frank Shaka - */ -public class FrameFigure extends Figure { - - private static final int FLAG_SELECTED = MAX_FLAG << 1; - private static final int FLAG_PRESELECTED = MAX_FLAG << 2; - private static final int FLAG_HIDE_TITLE = MAX_FLAG << 3; - private static final int FLAG_FLAT = MAX_FLAG << 4; - - static { - MAX_FLAG = FLAG_FLAT; - } - - protected static final Color ColorSelected = ColorUtils.getColor("#0070d8"); //$NON-NLS-1$ - protected static final Color ColorSelectedPreselected = ColorUtils - .getColor("#2088e0"); //$NON-NLS-1$ -// protected static final Color ColorInactive = ColorUtils.gray(ColorSelected); - - private static final int PADDING = 6; - - private RotatableWrapLabel title; - - private IFigure titleContainer; - - private IFigure contentContainer; - - private ShadowedLayer contentLayer; - - private int titlePlacement = PositionConstants.TOP; - private Layer contentCover; - - /** - * - */ - public FrameFigure() { - setOpaque(false); - setBorder(new MarginBorder(PADDING)); - FrameBorderLayout layout = new FrameBorderLayout(); - layout.setVerticalSpacing(2); - layout.setHorizontalSpacing(2); - super.setLayoutManager(layout); - - titleContainer = new Layer(); - AdvancedToolbarLayout titleContainerLayout = new AdvancedToolbarLayout(); - titleContainerLayout.setStretchMinorAxis(true); - titleContainer.setLayoutManager(titleContainerLayout); - add(titleContainer, FrameBorderLayout.TOP); - - title = new RotatableWrapLabel(RotatableWrapLabel.NORMAL); - title.setTextAlignment(PositionConstants.CENTER); - title.setAbbreviated(true); - title.setForegroundColor(ColorConstants.black); - titleContainer.add(title, FrameBorderLayout.TOP); - - Layer contentPane = new Layer(); - contentPane.setLayoutManager(new StackLayout()); - add(contentPane, FrameBorderLayout.CENTER); - - contentContainer = new Layer(); - contentPane.add(contentContainer); - AdvancedToolbarLayout contentContainerLayout = new AdvancedToolbarLayout( - true); - contentContainerLayout - .setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - contentContainerLayout - .setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - contentContainerLayout - .setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - contentContainer.setLayoutManager(contentContainerLayout); - - contentLayer = new ShadowedLayer(); - contentLayer.setBorderColor(ColorUtils.getColor(170, 170, 170)); - contentContainer.add(contentLayer); - - contentCover = new Layer(); - AdvancedToolbarLayout presentationLayout = new AdvancedToolbarLayout( - true); - presentationLayout - .setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - presentationLayout - .setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - presentationLayout - .setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); - contentCover.setLayoutManager(presentationLayout); - contentPane.add(contentCover, GEF.LAYER_PRESENTATION); - } - - public void setContentSize(Dimension size) { - if (size == null) { - contentContainer.setPreferredSize(null); - } else { - Insets ins1 = contentContainer.getInsets(); - Insets ins2 = contentLayer.getInsets(); - contentContainer.setPreferredSize( - size.getExpanded(ins1.getWidth(), ins1.getHeight()) - .expand(ins2.getWidth(), ins2.getHeight())); - } - } - - public void setLayoutManager(LayoutManager manager) { - // Prevent external layout manager to be set. - } - - @Override - protected void paintFigure(Graphics graphics) { - boolean preselected = isPreselected(); - boolean selected = isSelected(); - if (selected) { - paintBackground(graphics, ColorSelected, 0xff); - } else if (preselected) { - paintBackground(graphics, ColorSelected, 0x20); - } - super.paintFigure(graphics); - } - - private void paintBackground(Graphics graphics, Color color, int alpha) { - Rectangle b = getBounds(); -// graphics.setAntialias(SWT.ON); - graphics.setAlpha(alpha); - graphics.setBackgroundColor(color); - graphics.fillRectangle(b); - } - - public Layer getContentCover() { - return contentCover; - } - - /** - * @return the slide - */ - public ShadowedLayer getContentPane() { - return contentLayer; - } - - protected IFigure getTitleContainer() { - return titleContainer; - } - - public ITextFigure getTitle() { - return title; - } - - public int getTitleRenderStyle() { - return title.getRenderStyle(); - } - - public void setTitleRenderStyle(int renderStyle) { - title.setRenderStyle(renderStyle); - } - - /** - * @return one of {@link PositionConstants#TOP}, - * {@link PositionConstants#BOTTOM}, {@link PositionConstants#LEFT}, - * {@link PositionConstants#RIGHT} - */ - public int getTitlePlacement() { - return titlePlacement; - } - - /** - * @param textPlacement - * one of {@link PositionConstants#TOP}, - * {@link PositionConstants#BOTTOM}, - * {@link PositionConstants#LEFT}, - * {@link PositionConstants#RIGHT} - */ - public void setTitlePlacement(int textPlacement) { - if (textPlacement == getTitlePlacement()) - return; - this.titlePlacement = textPlacement; - updateTitlePlacement(textPlacement); - } - - private void updateTitlePlacement(int textPlacement) { - Object constraint = null; - switch (textPlacement) { - case PositionConstants.LEFT: - constraint = FrameBorderLayout.LEFT; - title.setTextAlignment(PositionConstants.RIGHT); - break; - case PositionConstants.RIGHT: - constraint = FrameBorderLayout.RIGHT; - title.setTextAlignment(PositionConstants.LEFT); - break; - case PositionConstants.TOP: - constraint = FrameBorderLayout.TOP; - title.setTextAlignment(PositionConstants.CENTER); - break; - case PositionConstants.BOTTOM: - constraint = FrameBorderLayout.BOTTOM; - title.setTextAlignment(PositionConstants.CENTER); - break; - } - if (constraint != null && titleContainer.getParent() == this) { - setConstraint(titleContainer, constraint); - } - } - - public boolean isSelected() { - return getFlag(FLAG_SELECTED); - } - - public void setSelected(boolean selected) { - if (selected == isSelected()) - return; - setFlag(FLAG_SELECTED, selected); - repaint(); - title.setForegroundColor( - selected ? ColorConstants.white : ColorConstants.black); - } - - public void setPreselected(boolean preselected) { - if (preselected == isPreselected()) - return; - setFlag(FLAG_PRESELECTED, preselected); - repaint(); - } - - public boolean isPreselected() { - return getFlag(FLAG_PRESELECTED); - } - - public boolean isPressed() { - return contentLayer.isPressed(); - } - - public void setPressed(boolean pressed) { - if (isFlat()) - return; - contentLayer.setPressed(pressed); - } - - public void press() { - if (isFlat()) - return; - contentLayer.press(); - } - - public void unpress() { - if (isFlat()) - return; - contentLayer.unpress(); - } - - public void togglePressed() { - if (isFlat()) - return; - contentLayer.togglePressed(); - } - - public boolean isHideTitle() { - return getFlag(FLAG_HIDE_TITLE); - } - - public boolean isFlat() { - return getFlag(FLAG_FLAT); - } - - public void setFlat(boolean flat) { - if (flat == isFlat()) - return; - setFlag(FLAG_FLAT, flat); - if (flat) { - contentLayer.setShadowDepths(0); - } else { - contentLayer.setShadowDepths(3); - } - } - - public void setHideTitle(boolean hideTitle) { - boolean oldHideTitle = isHideTitle(); - if (hideTitle == oldHideTitle) - return; - setFlag(FLAG_HIDE_TITLE, hideTitle); - if (hideTitle) { - remove(titleContainer); - } else { - add(titleContainer); - updateTitlePlacement(getTitlePlacement()); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.MarginBorder; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.AdvancedToolbarLayout; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.ui.resources.ColorUtils; + +/** + * @author Frank Shaka + */ +public class FrameFigure extends Figure { + + private static final int FLAG_SELECTED = MAX_FLAG << 1; + private static final int FLAG_PRESELECTED = MAX_FLAG << 2; + private static final int FLAG_HIDE_TITLE = MAX_FLAG << 3; + private static final int FLAG_FLAT = MAX_FLAG << 4; + + static { + MAX_FLAG = FLAG_FLAT; + } + + protected static final Color ColorSelected = ColorUtils.getColor("#0070d8"); //$NON-NLS-1$ + protected static final Color ColorSelectedPreselected = ColorUtils + .getColor("#2088e0"); //$NON-NLS-1$ +// protected static final Color ColorInactive = ColorUtils.gray(ColorSelected); + + private static final int PADDING = 6; + + private RotatableWrapLabel title; + + private IFigure titleContainer; + + private IFigure contentContainer; + + private ShadowedLayer contentLayer; + + private int titlePlacement = PositionConstants.TOP; + private Layer contentCover; + + /** + * + */ + public FrameFigure() { + setOpaque(false); + setBorder(new MarginBorder(PADDING)); + FrameBorderLayout layout = new FrameBorderLayout(); + layout.setVerticalSpacing(2); + layout.setHorizontalSpacing(2); + super.setLayoutManager(layout); + + titleContainer = new Layer(); + AdvancedToolbarLayout titleContainerLayout = new AdvancedToolbarLayout(); + titleContainerLayout.setStretchMinorAxis(true); + titleContainer.setLayoutManager(titleContainerLayout); + add(titleContainer, FrameBorderLayout.TOP); + + title = new RotatableWrapLabel(RotatableWrapLabel.NORMAL); + title.setTextAlignment(PositionConstants.CENTER); + title.setAbbreviated(true); + title.setForegroundColor(ColorConstants.black); + titleContainer.add(title, FrameBorderLayout.TOP); + + Layer contentPane = new Layer(); + contentPane.setLayoutManager(new StackLayout()); + add(contentPane, FrameBorderLayout.CENTER); + + contentContainer = new Layer(); + contentPane.add(contentContainer); + AdvancedToolbarLayout contentContainerLayout = new AdvancedToolbarLayout( + true); + contentContainerLayout + .setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + contentContainerLayout + .setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + contentContainerLayout + .setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + contentContainer.setLayoutManager(contentContainerLayout); + + contentLayer = new ShadowedLayer(); + contentLayer.setBorderColor(ColorUtils.getColor(170, 170, 170)); + contentContainer.add(contentLayer); + + contentCover = new Layer(); + AdvancedToolbarLayout presentationLayout = new AdvancedToolbarLayout( + true); + presentationLayout + .setMajorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + presentationLayout + .setMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + presentationLayout + .setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); + contentCover.setLayoutManager(presentationLayout); + contentPane.add(contentCover, GEF.LAYER_PRESENTATION); + } + + public void setContentSize(Dimension size) { + if (size == null) { + contentContainer.setPreferredSize(null); + } else { + Insets ins1 = contentContainer.getInsets(); + Insets ins2 = contentLayer.getInsets(); + contentContainer.setPreferredSize( + size.getExpanded(ins1.getWidth(), ins1.getHeight()) + .expand(ins2.getWidth(), ins2.getHeight())); + } + } + + public void setLayoutManager(LayoutManager manager) { + // Prevent external layout manager to be set. + } + + @Override + protected void paintFigure(Graphics graphics) { + boolean preselected = isPreselected(); + boolean selected = isSelected(); + if (selected) { + paintBackground(graphics, ColorSelected, 0xff); + } else if (preselected) { + paintBackground(graphics, ColorSelected, 0x20); + } + super.paintFigure(graphics); + } + + private void paintBackground(Graphics graphics, Color color, int alpha) { + Rectangle b = getBounds(); +// graphics.setAntialias(SWT.ON); + graphics.setAlpha(alpha); + graphics.setBackgroundColor(color); + graphics.fillRectangle(b); + } + + public Layer getContentCover() { + return contentCover; + } + + /** + * @return the slide + */ + public ShadowedLayer getContentPane() { + return contentLayer; + } + + protected IFigure getTitleContainer() { + return titleContainer; + } + + public ITextFigure getTitle() { + return title; + } + + public int getTitleRenderStyle() { + return title.getRenderStyle(); + } + + public void setTitleRenderStyle(int renderStyle) { + title.setRenderStyle(renderStyle); + } + + /** + * @return one of {@link PositionConstants#TOP}, + * {@link PositionConstants#BOTTOM}, {@link PositionConstants#LEFT}, + * {@link PositionConstants#RIGHT} + */ + public int getTitlePlacement() { + return titlePlacement; + } + + /** + * @param textPlacement + * one of {@link PositionConstants#TOP}, + * {@link PositionConstants#BOTTOM}, + * {@link PositionConstants#LEFT}, + * {@link PositionConstants#RIGHT} + */ + public void setTitlePlacement(int textPlacement) { + if (textPlacement == getTitlePlacement()) + return; + this.titlePlacement = textPlacement; + updateTitlePlacement(textPlacement); + } + + private void updateTitlePlacement(int textPlacement) { + Object constraint = null; + switch (textPlacement) { + case PositionConstants.LEFT: + constraint = FrameBorderLayout.LEFT; + title.setTextAlignment(PositionConstants.RIGHT); + break; + case PositionConstants.RIGHT: + constraint = FrameBorderLayout.RIGHT; + title.setTextAlignment(PositionConstants.LEFT); + break; + case PositionConstants.TOP: + constraint = FrameBorderLayout.TOP; + title.setTextAlignment(PositionConstants.CENTER); + break; + case PositionConstants.BOTTOM: + constraint = FrameBorderLayout.BOTTOM; + title.setTextAlignment(PositionConstants.CENTER); + break; + } + if (constraint != null && titleContainer.getParent() == this) { + setConstraint(titleContainer, constraint); + } + } + + public boolean isSelected() { + return getFlag(FLAG_SELECTED); + } + + public void setSelected(boolean selected) { + if (selected == isSelected()) + return; + setFlag(FLAG_SELECTED, selected); + repaint(); + title.setForegroundColor( + selected ? ColorConstants.white : ColorConstants.black); + } + + public void setPreselected(boolean preselected) { + if (preselected == isPreselected()) + return; + setFlag(FLAG_PRESELECTED, preselected); + repaint(); + } + + public boolean isPreselected() { + return getFlag(FLAG_PRESELECTED); + } + + public boolean isPressed() { + return contentLayer.isPressed(); + } + + public void setPressed(boolean pressed) { + if (isFlat()) + return; + contentLayer.setPressed(pressed); + } + + public void press() { + if (isFlat()) + return; + contentLayer.press(); + } + + public void unpress() { + if (isFlat()) + return; + contentLayer.unpress(); + } + + public void togglePressed() { + if (isFlat()) + return; + contentLayer.togglePressed(); + } + + public boolean isHideTitle() { + return getFlag(FLAG_HIDE_TITLE); + } + + public boolean isFlat() { + return getFlag(FLAG_FLAT); + } + + public void setFlat(boolean flat) { + if (flat == isFlat()) + return; + setFlag(FLAG_FLAT, flat); + if (flat) { + contentLayer.setShadowDepths(0); + } else { + contentLayer.setShadowDepths(3); + } + } + + public void setHideTitle(boolean hideTitle) { + boolean oldHideTitle = isHideTitle(); + if (hideTitle == oldHideTitle) + return; + setFlag(FLAG_HIDE_TITLE, hideTitle); + if (hideTitle) { + remove(titleContainer); + } else { + add(titleContainer); + updateTitlePlacement(getTitlePlacement()); + } + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FramePart.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FramePart.java index 6b529e025..a48cd03d5 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FramePart.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/FramePart.java @@ -1,233 +1,233 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import org.eclipse.draw2d.AbstractLayout; -import org.eclipse.draw2d.Cursors; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Cursor; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.part.GraphicalEditPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IPartSite; -import org.xmind.gef.part.IRequestHandler; -import org.xmind.gef.policy.NullEditPolicy; -import org.xmind.gef.status.StatusEvent; -import org.xmind.gef.util.Properties; - -public class FramePart extends GraphicalEditPart - implements PropertyChangeListener { - - private static class FrameContentLayout extends AbstractLayout { - - private static Rectangle BOUNDS = new Rectangle(); - - private static Rectangle CHILD_BOUNDS = new Rectangle(); - - private IPartSite site; - - public FrameContentLayout(IPartSite site) { - this.site = site; - } - - public void layout(IFigure container) { - Rectangle area = container.getClientArea(BOUNDS); - int childX, childY, childWidth, childHeight; - for (Object child : container.getChildren()) { - IFigure figure = (IFigure) child; - Dimension childSize = figure.getPreferredSize(area.width, - area.height); - childWidth = Math.min(childSize.width, area.width); - childHeight = Math.min(childSize.height, area.height); - childX = area.x + (area.width - childWidth) / 2; - childY = area.y + (area.height - childHeight) / 2; - CHILD_BOUNDS.setBounds(childX, childY, childWidth, childHeight); - figure.setBounds(CHILD_BOUNDS); - } - } - - @Override - protected Dimension calculatePreferredSize(IFigure container, int wHint, - int hHint) { - Insets insets = container.getInsets(); - Properties properties = site.getProperties(); - Dimension contentSize = (Dimension) properties - .get(GalleryViewer.FrameContentSize); - boolean pack = properties.getBoolean(GalleryViewer.PackFrameContent, - false); - if (contentSize != null && !pack) - return new Dimension(contentSize.width + insets.getWidth(), - contentSize.height + insets.getHeight()); - - int childWHint = contentSize != null ? contentSize.width - : (wHint < 0 ? wHint - : Math.max(0, wHint - insets.getWidth())); - int childHHint = contentSize != null ? contentSize.height - : (hHint < 0 ? hHint - : Math.max(0, hHint - insets.getHeight())); - int childWidth = 0, childHeight = 0; - for (Object child : container.getChildren()) { - Dimension childSize = ((IFigure) child) - .getPreferredSize(childWHint, childHHint); - childWidth = Math.max(childWidth, childSize.width); - childHeight = Math.max(childHeight, childSize.height); - } - - if (contentSize != null) { - childWidth = Math.min(childWidth, contentSize.width); - childHeight = Math.min(childHeight, contentSize.height); - } - - return new Dimension(childWidth + insets.getWidth(), - childHeight + insets.getHeight()); - } - - } - - public FramePart(Object model) { - setModel(model); - setDecorator(FrameDecorator.DEFAULT); - } - - @Override - protected LayoutManager createLayoutManager() { - return new FrameContentLayout(getSite()); - } - - protected IFigure createFigure() { - FrameFigure figure = new FrameFigure(); - Properties properties = getSite().getViewer().getProperties(); - boolean useAdvancedRenderer = properties - .getBoolean(IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); - figure.setTitleRenderStyle(useAdvancedRenderer - ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); - - return figure; - } - - public FrameFigure getFigure() { - return (FrameFigure) super.getFigure(); - } - - public IFigure getContentPane() { - return ((FrameFigure) super.getFigure()).getContentPane(); - } - - /** - * Least element has no child. - */ - protected Object[] getModelChildren(Object model) { - boolean isLeastElement = getSite().getViewer().getProperties() - .getBoolean(GalleryViewer.CustomContentPaneDecorator, false); - return isLeastElement ? new Object[0] : new Object[] { model }; - } - - protected void declareEditPolicies(IRequestHandler reqHandler) { - super.declareEditPolicies(reqHandler); - reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE, - NullEditPolicy.getInstance()); - reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, - GalleryViewer.POLICY_NAVIGABLE); - reqHandler.installEditPolicy(GEF.ROLE_MOVABLE, - GalleryViewer.POLICY_MOVABLE); - } - - protected void register() { - registerModel(getModel()); - super.register(); - } - - protected void unregister() { - super.unregister(); - unregisterModel(getModel()); - } - - protected void handleStatusChanged(StatusEvent event) { - if ((event.key & GEF.PART_SELECTED) != 0) { - setSelected(event.newValue); - } else if ((event.key & GEF.PART_PRESELECTED) != 0) { - setPreselected(event.newValue); - } else if ((event.key & GEF.PART_FOCUSED) != 0) { - getFigure().repaint(); - } else { - super.handleStatusChanged(event); - } - } - - protected void setSelected(boolean selected) { - getFigure().setSelected(selected); - } - - protected void setPreselected(boolean preselected) { - getFigure().setPreselected(preselected); - } - - protected IPart findChildAt(IPart child, Point position) { - if (!child.hasRole(GEF.ROLE_SELECTABLE)) - return null; - return super.findChildAt(child, position); - } - - public Cursor getCursor(Point pos) { - if (getContentPane().containsPoint(pos) && (!getSite().getProperties() - .getBoolean(GalleryViewer.SolidFrames, false) - || getSite().getProperties() - .getBoolean(GalleryViewer.SingleClickToOpen, false))) - return Cursors.HAND; - if (getFigure().getTitle().containsPoint(pos)) { - EditDomain domain = getSite().getDomain(); - if (domain != null && domain.hasTool(GEF.TOOL_EDIT)) - return Cursors.HAND; - } - return null; - } - - @Override - protected void updateChildren() { - super.updateChildren(); - for (IPart child : getChildren()) { - child.update(); - } - } - - protected void onActivated() { - super.onActivated(); - getSite().getViewer().getProperties().addPropertyChangeListener( - IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, this); - } - - protected void onDeactivated() { - getSite().getViewer().getProperties().removePropertyChangeListener( - IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, this); - super.onDeactivated(); - } - - public void propertyChange(PropertyChangeEvent evt) { - boolean useAdvancedRenderer = getSite().getViewer().getProperties() - .getBoolean(IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); - getFigure().setTitleRenderStyle(useAdvancedRenderer - ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.draw2d.AbstractLayout; +import org.eclipse.draw2d.Cursors; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Cursor; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.part.GraphicalEditPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IPartSite; +import org.xmind.gef.part.IRequestHandler; +import org.xmind.gef.policy.NullEditPolicy; +import org.xmind.gef.status.StatusEvent; +import org.xmind.gef.util.Properties; + +public class FramePart extends GraphicalEditPart + implements PropertyChangeListener { + + private static class FrameContentLayout extends AbstractLayout { + + private static Rectangle BOUNDS = new Rectangle(); + + private static Rectangle CHILD_BOUNDS = new Rectangle(); + + private IPartSite site; + + public FrameContentLayout(IPartSite site) { + this.site = site; + } + + public void layout(IFigure container) { + Rectangle area = container.getClientArea(BOUNDS); + int childX, childY, childWidth, childHeight; + for (Object child : container.getChildren()) { + IFigure figure = (IFigure) child; + Dimension childSize = figure.getPreferredSize(area.width, + area.height); + childWidth = Math.min(childSize.width, area.width); + childHeight = Math.min(childSize.height, area.height); + childX = area.x + (area.width - childWidth) / 2; + childY = area.y + (area.height - childHeight) / 2; + CHILD_BOUNDS.setBounds(childX, childY, childWidth, childHeight); + figure.setBounds(CHILD_BOUNDS); + } + } + + @Override + protected Dimension calculatePreferredSize(IFigure container, int wHint, + int hHint) { + Insets insets = container.getInsets(); + Properties properties = site.getProperties(); + Dimension contentSize = (Dimension) properties + .get(GalleryViewer.FrameContentSize); + boolean pack = properties.getBoolean(GalleryViewer.PackFrameContent, + false); + if (contentSize != null && !pack) + return new Dimension(contentSize.width + insets.getWidth(), + contentSize.height + insets.getHeight()); + + int childWHint = contentSize != null ? contentSize.width + : (wHint < 0 ? wHint + : Math.max(0, wHint - insets.getWidth())); + int childHHint = contentSize != null ? contentSize.height + : (hHint < 0 ? hHint + : Math.max(0, hHint - insets.getHeight())); + int childWidth = 0, childHeight = 0; + for (Object child : container.getChildren()) { + Dimension childSize = ((IFigure) child) + .getPreferredSize(childWHint, childHHint); + childWidth = Math.max(childWidth, childSize.width); + childHeight = Math.max(childHeight, childSize.height); + } + + if (contentSize != null) { + childWidth = Math.min(childWidth, contentSize.width); + childHeight = Math.min(childHeight, contentSize.height); + } + + return new Dimension(childWidth + insets.getWidth(), + childHeight + insets.getHeight()); + } + + } + + public FramePart(Object model) { + setModel(model); + setDecorator(FrameDecorator.DEFAULT); + } + + @Override + protected LayoutManager createLayoutManager() { + return new FrameContentLayout(getSite()); + } + + protected IFigure createFigure() { + FrameFigure figure = new FrameFigure(); + Properties properties = getSite().getViewer().getProperties(); + boolean useAdvancedRenderer = properties + .getBoolean(IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); + figure.setTitleRenderStyle(useAdvancedRenderer + ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); + + return figure; + } + + public FrameFigure getFigure() { + return (FrameFigure) super.getFigure(); + } + + public IFigure getContentPane() { + return ((FrameFigure) super.getFigure()).getContentPane(); + } + + /** + * Least element has no child. + */ + protected Object[] getModelChildren(Object model) { + boolean isLeastElement = getSite().getViewer().getProperties() + .getBoolean(GalleryViewer.CustomContentPaneDecorator, false); + return isLeastElement ? new Object[0] : new Object[] { model }; + } + + protected void declareEditPolicies(IRequestHandler reqHandler) { + super.declareEditPolicies(reqHandler); + reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE, + NullEditPolicy.getInstance()); + reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, + GalleryViewer.POLICY_NAVIGABLE); + reqHandler.installEditPolicy(GEF.ROLE_MOVABLE, + GalleryViewer.POLICY_MOVABLE); + } + + protected void register() { + registerModel(getModel()); + super.register(); + } + + protected void unregister() { + super.unregister(); + unregisterModel(getModel()); + } + + protected void handleStatusChanged(StatusEvent event) { + if ((event.key & GEF.PART_SELECTED) != 0) { + setSelected(event.newValue); + } else if ((event.key & GEF.PART_PRESELECTED) != 0) { + setPreselected(event.newValue); + } else if ((event.key & GEF.PART_FOCUSED) != 0) { + getFigure().repaint(); + } else { + super.handleStatusChanged(event); + } + } + + protected void setSelected(boolean selected) { + getFigure().setSelected(selected); + } + + protected void setPreselected(boolean preselected) { + getFigure().setPreselected(preselected); + } + + protected IPart findChildAt(IPart child, Point position) { + if (!child.hasRole(GEF.ROLE_SELECTABLE)) + return null; + return super.findChildAt(child, position); + } + + public Cursor getCursor(Point pos) { + if (getContentPane().containsPoint(pos) && (!getSite().getProperties() + .getBoolean(GalleryViewer.SolidFrames, false) + || getSite().getProperties() + .getBoolean(GalleryViewer.SingleClickToOpen, false))) + return Cursors.HAND; + if (getFigure().getTitle().containsPoint(pos)) { + EditDomain domain = getSite().getDomain(); + if (domain != null && domain.hasTool(GEF.TOOL_EDIT)) + return Cursors.HAND; + } + return null; + } + + @Override + protected void updateChildren() { + super.updateChildren(); + for (IPart child : getChildren()) { + child.update(); + } + } + + protected void onActivated() { + super.onActivated(); + getSite().getViewer().getProperties().addPropertyChangeListener( + IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, this); + } + + protected void onDeactivated() { + getSite().getViewer().getProperties().removePropertyChangeListener( + IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, this); + super.onDeactivated(); + } + + public void propertyChange(PropertyChangeEvent evt) { + boolean useAdvancedRenderer = getSite().getViewer().getProperties() + .getBoolean(IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); + getFigure().setTitleRenderStyle(useAdvancedRenderer + ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryMovablePolicy.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryMovablePolicy.java index ed0348bf5..143e7a1f7 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryMovablePolicy.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryMovablePolicy.java @@ -1,25 +1,25 @@ -package org.xmind.ui.gallery; - -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.policy.AbstractEditPolicy; - -public abstract class GalleryMovablePolicy extends AbstractEditPolicy { - - @Override - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_MOVETO.equals(requestType); - } - - @Override - public void handle(Request request) { - String type = request.getType(); - if (GEF.REQ_MOVETO.equals(type)) { - moveGallery(request); - } - } - - protected abstract void moveGallery(Request request); - -} +package org.xmind.ui.gallery; + +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.policy.AbstractEditPolicy; + +public abstract class GalleryMovablePolicy extends AbstractEditPolicy { + + @Override + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_MOVETO.equals(requestType); + } + + @Override + public void handle(Request request) { + String type = request.getType(); + if (GEF.REQ_MOVETO.equals(type)) { + moveGallery(request); + } + } + + protected abstract void moveGallery(Request request); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryNavigablePolicy.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryNavigablePolicy.java index 009ced82d..9107be365 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryNavigablePolicy.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryNavigablePolicy.java @@ -1,210 +1,210 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import java.util.List; - -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.policy.NavigablePolicy; - -/** - * @author frankshaka - * - */ -public class GalleryNavigablePolicy extends NavigablePolicy { - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.policy.NavigablePolicy#findNavParts(org.xmind.gef.Request, - * java.lang.String, java.util.List, java.util.List) - */ - @Override - protected void findNavParts(Request request, String navType, - List sources, List result) { - FramePart sourceFrame = findSourceFrame(sources, navType); - if (sourceFrame != null) { - IPart p = findNavFrame(request, navType, sourceFrame); - if (p != null) { - result.add(p); - return; - } - } - super.findNavParts(request, navType, sources, result); - } - - /** - * @param request - * @param navType - * @param sourceFrame - * @param result - */ - protected IPart findNavFrame(Request request, String navType, - FramePart sourceFrame) { - IPart parent = sourceFrame.getParent(); - if (parent == null) - return null; - - if (GEF.REQ_NAV_BEGINNING.equals(navType)) { - return findFirstFrameChild(parent); - } else if (GEF.REQ_NAV_END.equals(navType)) { - return findLastFrameChild(parent); - } - - int index = parent.getChildren().indexOf(sourceFrame); - if (GEF.REQ_NAV_UP.equals(navType) || GEF.REQ_NAV_LEFT.equals(navType)) { - IPart p = findFrameChildBackwards(navType, parent, index, - sourceFrame); - if (p != null) - return p; - return findFrameChildForwards(navType, parent, index, sourceFrame); - } else if (GEF.REQ_NAV_DOWN.equals(navType) - || GEF.REQ_NAV_RIGHT.equals(navType)) { - IPart p = findFrameChildForwards(navType, parent, index, - sourceFrame); - if (p != null) - return p; - return findFrameChildBackwards(navType, parent, index, sourceFrame); - } - return null; - } - - /** - * @param navType - * @param parent - * @param index - * @param sourceFrame - * @param result - * @return - */ - private IPart findFrameChildForwards(String navType, IPart parent, - int index, FramePart sourceFrame) { - List children = parent.getChildren(); - for (int i = index + 1; i < children.size(); i++) { - IPart p = children.get(i); - if (p instanceof FramePart) { - FramePart frame = (FramePart) p; - if (isNavFrame(navType, frame, sourceFrame)) - return frame; - } - } - return null; - } - - /** - * @param navType - * @param parent - * @param index - * @param sourceFrame - * @param result - * @return - */ - private IPart findFrameChildBackwards(String navType, IPart parent, - int index, FramePart sourceFrame) { - List children = parent.getChildren(); - for (int i = index - 1; i >= 0; i--) { - IPart p = children.get(i); - if (p instanceof FramePart) { - FramePart frame = (FramePart) p; - if (isNavFrame(navType, frame, sourceFrame)) - return frame; - } - } - return null; - } - - /** - * @param navType - * @param frame - * @param sourceFrame - * @return - */ - private boolean isNavFrame(String navType, FramePart frame, - FramePart sourceFrame) { - Rectangle bounds = frame.getFigure().getBounds(); - Rectangle sourceBounds = sourceFrame.getFigure().getBounds(); - if (GEF.REQ_NAV_UP.equals(navType)) { - int x = sourceBounds.x + sourceBounds.width / 2; - return bounds.y < sourceBounds.y - && bounds.bottom() < sourceBounds.bottom() && bounds.x < x - && bounds.right() > x; - } else if (GEF.REQ_NAV_DOWN.equals(navType)) { - int x = sourceBounds.x + sourceBounds.width / 2; - return bounds.y > sourceBounds.y - && bounds.bottom() > sourceBounds.bottom() && bounds.x < x - && bounds.right() > x; - } else if (GEF.REQ_NAV_LEFT.equals(navType)) { - int y = sourceBounds.y + sourceBounds.height / 2; - return bounds.x < sourceBounds.x - && bounds.right() < sourceBounds.right() && bounds.y < y - && bounds.bottom() > y; - } else if (GEF.REQ_NAV_RIGHT.equals(navType)) { - int y = sourceBounds.y + sourceBounds.height / 2; - return bounds.x > sourceBounds.x - && bounds.right() > sourceBounds.right() && bounds.y < y - && bounds.bottom() > y; - } - return false; - } - - /** - * @param parent - * @param result - * @return - */ - private IPart findLastFrameChild(IPart parent) { - List children = parent.getChildren(); - for (int i = children.size() - 1; i >= 0; i--) { - IPart p = children.get(i); - if (p instanceof FramePart) { - return p; - } - } - return null; - } - - /** - * @param parent - * @param result - * @return - */ - private IPart findFirstFrameChild(IPart parent) { - List children = parent.getChildren(); - for (int i = 0; i < children.size(); i++) { - IPart p = children.get(i); - if (p instanceof FramePart) { - return p; - } - } - return null; - } - - /** - * - * @param sources - * @param navType - * @return - */ - private FramePart findSourceFrame(List sources, String navType) { - if (sources.isEmpty()) - return null; - IPart source = sources.get(0); - return source instanceof FramePart ? (FramePart) source : null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import java.util.List; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.policy.NavigablePolicy; + +/** + * @author frankshaka + * + */ +public class GalleryNavigablePolicy extends NavigablePolicy { + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.policy.NavigablePolicy#findNavParts(org.xmind.gef.Request, + * java.lang.String, java.util.List, java.util.List) + */ + @Override + protected void findNavParts(Request request, String navType, + List sources, List result) { + FramePart sourceFrame = findSourceFrame(sources, navType); + if (sourceFrame != null) { + IPart p = findNavFrame(request, navType, sourceFrame); + if (p != null) { + result.add(p); + return; + } + } + super.findNavParts(request, navType, sources, result); + } + + /** + * @param request + * @param navType + * @param sourceFrame + * @param result + */ + protected IPart findNavFrame(Request request, String navType, + FramePart sourceFrame) { + IPart parent = sourceFrame.getParent(); + if (parent == null) + return null; + + if (GEF.REQ_NAV_BEGINNING.equals(navType)) { + return findFirstFrameChild(parent); + } else if (GEF.REQ_NAV_END.equals(navType)) { + return findLastFrameChild(parent); + } + + int index = parent.getChildren().indexOf(sourceFrame); + if (GEF.REQ_NAV_UP.equals(navType) || GEF.REQ_NAV_LEFT.equals(navType)) { + IPart p = findFrameChildBackwards(navType, parent, index, + sourceFrame); + if (p != null) + return p; + return findFrameChildForwards(navType, parent, index, sourceFrame); + } else if (GEF.REQ_NAV_DOWN.equals(navType) + || GEF.REQ_NAV_RIGHT.equals(navType)) { + IPart p = findFrameChildForwards(navType, parent, index, + sourceFrame); + if (p != null) + return p; + return findFrameChildBackwards(navType, parent, index, sourceFrame); + } + return null; + } + + /** + * @param navType + * @param parent + * @param index + * @param sourceFrame + * @param result + * @return + */ + private IPart findFrameChildForwards(String navType, IPart parent, + int index, FramePart sourceFrame) { + List children = parent.getChildren(); + for (int i = index + 1; i < children.size(); i++) { + IPart p = children.get(i); + if (p instanceof FramePart) { + FramePart frame = (FramePart) p; + if (isNavFrame(navType, frame, sourceFrame)) + return frame; + } + } + return null; + } + + /** + * @param navType + * @param parent + * @param index + * @param sourceFrame + * @param result + * @return + */ + private IPart findFrameChildBackwards(String navType, IPart parent, + int index, FramePart sourceFrame) { + List children = parent.getChildren(); + for (int i = index - 1; i >= 0; i--) { + IPart p = children.get(i); + if (p instanceof FramePart) { + FramePart frame = (FramePart) p; + if (isNavFrame(navType, frame, sourceFrame)) + return frame; + } + } + return null; + } + + /** + * @param navType + * @param frame + * @param sourceFrame + * @return + */ + private boolean isNavFrame(String navType, FramePart frame, + FramePart sourceFrame) { + Rectangle bounds = frame.getFigure().getBounds(); + Rectangle sourceBounds = sourceFrame.getFigure().getBounds(); + if (GEF.REQ_NAV_UP.equals(navType)) { + int x = sourceBounds.x + sourceBounds.width / 2; + return bounds.y < sourceBounds.y + && bounds.bottom() < sourceBounds.bottom() && bounds.x < x + && bounds.right() > x; + } else if (GEF.REQ_NAV_DOWN.equals(navType)) { + int x = sourceBounds.x + sourceBounds.width / 2; + return bounds.y > sourceBounds.y + && bounds.bottom() > sourceBounds.bottom() && bounds.x < x + && bounds.right() > x; + } else if (GEF.REQ_NAV_LEFT.equals(navType)) { + int y = sourceBounds.y + sourceBounds.height / 2; + return bounds.x < sourceBounds.x + && bounds.right() < sourceBounds.right() && bounds.y < y + && bounds.bottom() > y; + } else if (GEF.REQ_NAV_RIGHT.equals(navType)) { + int y = sourceBounds.y + sourceBounds.height / 2; + return bounds.x > sourceBounds.x + && bounds.right() > sourceBounds.right() && bounds.y < y + && bounds.bottom() > y; + } + return false; + } + + /** + * @param parent + * @param result + * @return + */ + private IPart findLastFrameChild(IPart parent) { + List children = parent.getChildren(); + for (int i = children.size() - 1; i >= 0; i--) { + IPart p = children.get(i); + if (p instanceof FramePart) { + return p; + } + } + return null; + } + + /** + * @param parent + * @param result + * @return + */ + private IPart findFirstFrameChild(IPart parent) { + List children = parent.getChildren(); + for (int i = 0; i < children.size(); i++) { + IPart p = children.get(i); + if (p instanceof FramePart) { + return p; + } + } + return null; + } + + /** + * + * @param sources + * @param navType + * @return + */ + private FramePart findSourceFrame(List sources, String navType) { + if (sources.isEmpty()) + return null; + IPart source = sources.get(0); + return source instanceof FramePart ? (FramePart) source : null; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GallerySelectTool.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GallerySelectTool.java index 65f88213a..4d54510ee 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GallerySelectTool.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GallerySelectTool.java @@ -1,164 +1,164 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import org.eclipse.swt.SWT; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.tool.SelectTool; - -public class GallerySelectTool extends SelectTool { - - private FramePart sourceFrame = null; - - private FramePart trackedFrame = null; - - protected boolean isFrameAsButton() { - return !getTargetViewer().getProperties() - .getBoolean(GalleryViewer.SolidFrames, false); - } - - protected boolean isSingleClickToOpen() { - return getTargetViewer().getProperties() - .getBoolean(GalleryViewer.SingleClickToOpen, false); - } - - protected boolean isCursorInTitle(IPart p) { - return p instanceof FramePart && ((FramePart) p).getFigure().getTitle() - .containsPoint(getCursorPosition()); - } - - protected boolean isTitleEditable(IPart p) { - if (getTargetViewer() instanceof GalleryViewer) { - return ((GalleryViewer) getTargetViewer()).isTitleEditable(p); - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.tool.SelectTool#handleMouseDown(org.xmind.gef.event. - * MouseEvent ) - */ - protected boolean handleMouseDown(MouseEvent me) { - FramePart targetFrame = findFrame(me.target); - if (isFrameAsButton()) { - if (targetFrame != null) { - if (targetFrame.getContentPane() - .containsPoint(me.cursorLocation)) { - sourceFrame = targetFrame; - sourceFrame.getFigure().press(); - } - } - } - boolean ret = handleSelectionOnMouseDown(me); - if (isCursorInTitle(me.target) && isTitleEditable(me.target)) { - Request request = new Request(GEF.REQ_EDIT); - request.setDomain(getDomain()); - request.setViewer(getTargetViewer()); - request.setPrimaryTarget(me.target); - startEditing(me.target, request); - ITool et = getTool(GEF.TOOL_EDIT); - if (et != null && et == getDomain().getActiveTool()) { - me.consume(); - } - } else if (isSingleClickToOpen() && me.leftOrRight) { - if (targetFrame != null) { - trackedFrame = targetFrame; - } - } - return ret; - } - - private FramePart findFrame(IPart part) { - while (part != null) { - if (part instanceof FramePart) - return (FramePart) part; - part = part.getParent(); - } - return null; - } - - protected boolean handleSelectionOnMouseDown(MouseEvent me) { - return super.handleMouseDown(me); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.tool.SelectTool#handleMouseUp(org.xmind.gef.event. - * MouseEvent ) - */ - public boolean handleMouseUp(MouseEvent me) { - FramePart targetFrame = findFrame(me.target); - - if (sourceFrame != null) { - sourceFrame.getFigure().unpress(); - sourceFrame = null; - } - boolean handled = super.handleMouseUp(me); - - if (trackedFrame != null && isSingleClickToOpen() && me.leftOrRight) { - if (targetFrame == trackedFrame) { - performOpen(); - } - me.consume(); - } - trackedFrame = null; - - return handled; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.tool.SelectTool#handleMouseDoubleClick(org.xmind.gef.event - * .MouseEvent) - */ - protected boolean handleMouseDoubleClick(MouseEvent me) { - if (me.target instanceof FramePart) { - if (!isSingleClickToOpen() && (!isCursorInTitle(me.target) - || !isTitleEditable(me.target))) { - performOpen(); - me.consume(); - return true; - } - } - return super.handleMouseDoubleClick(me); - } - - protected void performOpen() { - if (!(getTargetViewer() instanceof GalleryViewer)) - return; - GalleryViewer viewer = (GalleryViewer) getTargetViewer(); - viewer.fireOpen(); - } - - @Override - protected boolean handleKeyTraversed(KeyEvent ke) { - if (ke.traverse == SWT.TRAVERSE_RETURN) { - performOpen(); - ke.consume(); - return false; - } - return super.handleKeyTraversed(ke); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import org.eclipse.swt.SWT; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.tool.SelectTool; + +public class GallerySelectTool extends SelectTool { + + private FramePart sourceFrame = null; + + private FramePart trackedFrame = null; + + protected boolean isFrameAsButton() { + return !getTargetViewer().getProperties() + .getBoolean(GalleryViewer.SolidFrames, false); + } + + protected boolean isSingleClickToOpen() { + return getTargetViewer().getProperties() + .getBoolean(GalleryViewer.SingleClickToOpen, false); + } + + protected boolean isCursorInTitle(IPart p) { + return p instanceof FramePart && ((FramePart) p).getFigure().getTitle() + .containsPoint(getCursorPosition()); + } + + protected boolean isTitleEditable(IPart p) { + if (getTargetViewer() instanceof GalleryViewer) { + return ((GalleryViewer) getTargetViewer()).isTitleEditable(p); + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.tool.SelectTool#handleMouseDown(org.xmind.gef.event. + * MouseEvent ) + */ + protected boolean handleMouseDown(MouseEvent me) { + FramePart targetFrame = findFrame(me.target); + if (isFrameAsButton()) { + if (targetFrame != null) { + if (targetFrame.getContentPane() + .containsPoint(me.cursorLocation)) { + sourceFrame = targetFrame; + sourceFrame.getFigure().press(); + } + } + } + boolean ret = handleSelectionOnMouseDown(me); + if (isCursorInTitle(me.target) && isTitleEditable(me.target)) { + Request request = new Request(GEF.REQ_EDIT); + request.setDomain(getDomain()); + request.setViewer(getTargetViewer()); + request.setPrimaryTarget(me.target); + startEditing(me.target, request); + ITool et = getTool(GEF.TOOL_EDIT); + if (et != null && et == getDomain().getActiveTool()) { + me.consume(); + } + } else if (isSingleClickToOpen() && me.leftOrRight) { + if (targetFrame != null) { + trackedFrame = targetFrame; + } + } + return ret; + } + + private FramePart findFrame(IPart part) { + while (part != null) { + if (part instanceof FramePart) + return (FramePart) part; + part = part.getParent(); + } + return null; + } + + protected boolean handleSelectionOnMouseDown(MouseEvent me) { + return super.handleMouseDown(me); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.tool.SelectTool#handleMouseUp(org.xmind.gef.event. + * MouseEvent ) + */ + public boolean handleMouseUp(MouseEvent me) { + FramePart targetFrame = findFrame(me.target); + + if (sourceFrame != null) { + sourceFrame.getFigure().unpress(); + sourceFrame = null; + } + boolean handled = super.handleMouseUp(me); + + if (trackedFrame != null && isSingleClickToOpen() && me.leftOrRight) { + if (targetFrame == trackedFrame) { + performOpen(); + } + me.consume(); + } + trackedFrame = null; + + return handled; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.tool.SelectTool#handleMouseDoubleClick(org.xmind.gef.event + * .MouseEvent) + */ + protected boolean handleMouseDoubleClick(MouseEvent me) { + if (me.target instanceof FramePart) { + if (!isSingleClickToOpen() && (!isCursorInTitle(me.target) + || !isTitleEditable(me.target))) { + performOpen(); + me.consume(); + return true; + } + } + return super.handleMouseDoubleClick(me); + } + + protected void performOpen() { + if (!(getTargetViewer() instanceof GalleryViewer)) + return; + GalleryViewer viewer = (GalleryViewer) getTargetViewer(); + viewer.fireOpen(); + } + + @Override + protected boolean handleKeyTraversed(KeyEvent ke) { + if (ke.traverse == SWT.TRAVERSE_RETURN) { + performOpen(); + ke.consume(); + return false; + } + return super.handleKeyTraversed(ke); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryViewer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryViewer.java index bf7647bf8..a87ed575e 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryViewer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryViewer.java @@ -1,393 +1,393 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.gallery; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.RangeModel; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IFilter; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.LabelProviderChangedEvent; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.part.GraphicalRootEditPart; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; - -public class GalleryViewer extends GraphicalViewer - implements IDecorationContext { - - /** - * Viewer property key indicating whether frames are laid out horizontally - * or vertically. - *

- * Values: true, false - *

- */ - public static final String Horizontal = "org.xmind.ui.gallery.horizontal"; //$NON-NLS-1$ - - /** - * Viewer property key indicating whether frames can wrap. - *

- * Values: true, false - *

- */ - public static final String Wrap = "org.xmind.ui.gallery.wrap"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String HideTitle = "org.xmind.ui.gallery.hideTitle"; //$NON-NLS-1$ - - /** - * Values: GalleryLayout - */ - public static final String Layout = "org.xmind.ui.gallery.layout"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String ImageStretched = "stretched"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String ImageConstrained = "constrained"; //$NON-NLS-1$ - - /** - * Values: {@link org.eclipse.draw2d.geometry.Dimension} - */ - public static final String FrameContentSize = "org.xmind.ui.gallery.frameContentSize"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String PackFrameContent = "org.xmind.ui.gallery.packFrameContent"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String FlatFrames = "org.xmind.ui.gallery.flatFrames"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String SolidFrames = "org.xmind.ui.gallery.solidFrames"; //$NON-NLS-1$ - - /** - * Values: TITLE_TOP, TITLE_BOTTOM, TITLE_LEFT, TITLE_RIGHT - */ - public static final String TitlePlacement = "org.xmind.ui.gallery.titlePlacement"; //$NON-NLS-1$ - - /** - * Values: true, false - */ - public static final String SingleClickToOpen = "org.xmind.ui.gallery.singleClickToOpen"; //$NON-NLS-1$ - - /** - *

- * Determines whether this viewer allows empty selection to be set. This - * property does not work when the input contains no elements because the - * selection will always be empty in this case. - *

- * Values: true, false - */ - public static final String EmptySelectionIgnored = "org.xmind.ui.gallery.emptySelectionIgnored"; //$NON-NLS-1$ - - /** - *

- * Determines whether this viewer takes use of custom decorator to draw - * content pane. - *

- */ - public static final String CustomContentPaneDecorator = "org.xmind.ui.gallery.customDecorateContentPane"; //$NON-NLS-1$ - - public static final String ContentPaneMargins = "org.xmind.ui.gallery.contentPaneMargins"; //$NON-NLS-1$ - - public static final String ContentPaneBorderWidth = "org.xmind.ui.gallery.contentPaneBorderWidth"; //$NON-NLS-1$ - - public static final String ContentPaneBorderColor = "org.xmind.ui.gallery.contentPaneBorderColor"; //$NON-NLS-1$ - - public static final String ContentPaneSpaceCollaborativeEngine = "org.xmind.ui.gallery.contentPaneSpaceCollaborativeEngine"; //$NON-NLS-1$ - - public static final String HorizontalLayout = "org.xmind.ui.gallery.horizontalLayout"; //$NON-NLS-1$ - - /** - * Value for title placement 'top'. - */ - public static final Integer TITLE_TOP = new Integer(PositionConstants.TOP); - - /** - * Value for title placement 'bottom'. - */ - public static final Integer TITLE_BOTTOM = new Integer( - PositionConstants.BOTTOM); - - /** - * Value for title placement 'left'. - */ - public static final Integer TITLE_LEFT = new Integer( - PositionConstants.LEFT); - - /** - * Value for title placement 'right'. - */ - public static final Integer TITLE_RIGHT = new Integer( - PositionConstants.RIGHT); - - public static final String POLICY_NAVIGABLE = "org.xmind.ui.gallery.editPolicy.navigable"; //$NON-NLS-1$ - public static final String POLICY_MOVABLE = "org.xmind.ui.gallery.editPolicy.movable"; //$NON-NLS-1$ - - private class GalleryLabelProviderListener - implements ILabelProviderListener { - public void labelProviderChanged(LabelProviderChangedEvent event) { - update(event.getElements()); - } - } - - private IStructuredContentProvider contentProvider = null; - - private IBaseLabelProvider labelProvider = null; - - private ILabelProviderListener labelProviderListener = new GalleryLabelProviderListener(); - - private List openListeners = null; - - private IFilter titleEditingApprover = null; - - public GalleryViewer() { - setPartFactory(GalleryPartFactory.getDefault()); - setRootPart(new GraphicalRootEditPart()); - } - - public T getAdapter(Class adapter) { - if (IBaseLabelProvider.class.equals(adapter)) - return adapter.cast(getLabelProvider()); - if (IStructuredContentProvider.class.equals(adapter)) - return adapter.cast(getContentProvider()); - return super.getAdapter(adapter); - } - - protected Control internalCreateControl(Composite parent, int style) { - Control control = super.internalCreateControl(parent, style); - control.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - return control; - } - - public void update() { - update(null); - } - - public void update(Object[] elements) { - if (elements == null) { - IPart contents = getRootPart().getContents(); - if (contents.getStatus().isActive()) - contents.refresh(); - for (IPart p : contents.getChildren()) { - if (p.getStatus().isActive()) { - ((IGraphicalPart) p).refresh(); - } - } - } else { - for (Object element : elements) { - IPart p = findPart(element); - if (p != null && p.getStatus().isActive()) { - ((IGraphicalPart) p).refresh(); - } - } - } - } - - public void setContentProvider(IStructuredContentProvider contentProvider) { - IStructuredContentProvider oldContentProvider = this.contentProvider; - this.contentProvider = contentProvider; - if (oldContentProvider != null) { - Object currentInput = getInput(); - oldContentProvider.inputChanged(this, currentInput, null); - oldContentProvider.dispose(); - contentProvider.inputChanged(this, null, currentInput); - refresh(); - } - } - - public IStructuredContentProvider getContentProvider() { - return contentProvider; - } - - public IBaseLabelProvider getLabelProvider() { - if (labelProvider == null) { - labelProvider = new LabelProvider(); - } - return labelProvider; - } - - public void setLabelProvider(IBaseLabelProvider labelProvider) { - if (labelProvider == null) - return; - - IBaseLabelProvider oldLabelProvider = this.labelProvider; - if (labelProvider == oldLabelProvider) - return; - - if (oldLabelProvider != null) { - oldLabelProvider.removeListener(labelProviderListener); - } - this.labelProvider = labelProvider; - labelProviderListener = new GalleryLabelProviderListener(); - labelProvider.addListener(labelProviderListener); - refresh(); - - if (oldLabelProvider != null) { - oldLabelProvider.dispose(); - } - } - - @Override - protected void contentsChanged(Object input, Object oldInput) { - IStructuredContentProvider content = getContentProvider(); - if (content != null) { - content.inputChanged(this, oldInput, input); - } - super.contentsChanged(input, oldInput); - } - - protected void handleDispose(DisposeEvent e) { - if (contentProvider != null) { - contentProvider.inputChanged(this, getInput(), null); - contentProvider.dispose(); - contentProvider = null; - } - if (labelProvider != null) { - labelProvider.removeListener(labelProviderListener); - labelProvider.dispose(); - labelProvider = null; - } - super.handleDispose(e); - } - - public void centerHorizontal() { - FigureCanvas fc = getCanvas(); - if (fc.isDisposed()) - return; - RangeModel horizontal = fc.getViewport().getHorizontalRangeModel(); - int h = (horizontal.getMaximum() - horizontal.getExtent() - + horizontal.getMinimum()) / 2; - fc.scrollToX(h); - } - - public void addOpenListener(IOpenListener listener) { - if (openListeners == null) - openListeners = new ArrayList(); - openListeners.add(listener); - } - - public void removeOpenListener(IOpenListener listener) { - if (openListeners == null) - return; - openListeners.remove(listener); - } - - protected void fireOpen(final OpenEvent event) { - if (openListeners == null) - return; - for (final Object l : openListeners.toArray()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - ((IOpenListener) l).open(event); - } - }); - } - } - - protected void fireOpen() { - fireOpen(new OpenEvent(this, getSelection())); - } - - private List toReveal; - - protected void revealParts(List parts) { - if (toReveal != null) { - toReveal = parts; - } else { - toReveal = parts; - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (toReveal == null || getControl() == null - || getControl().isDisposed()) - return; - - Rectangle r = null; - for (IPart p : toReveal) { - if (p instanceof IGraphicalPart) { - r = Geometry.union(r, ((IGraphicalPart) p) - .getFigure().getBounds()); - } - } - if (r != null) { - ensureVisible(r); - } - toReveal = null; - } - }); - } - } - - @Override - public void setSelection(ISelection selection) { - setSelection(selection, true); - } - - @Override - public void setSelection(ISelection selection, boolean reveal) { - if (getProperties().getBoolean(EmptySelectionIgnored, false) - && selection.isEmpty()) - return; - super.setSelection(selection, reveal); - } - - public IFilter getTitleEditingApprover() { - return titleEditingApprover; - } - - public void setTitleEditingApprover(IFilter titleEditingApprover) { - this.titleEditingApprover = titleEditingApprover; - } - - protected boolean isTitleEditable(IPart p) { - return titleEditingApprover != null && titleEditingApprover.select(p); - } - - public Object getProperty(String key, Object defaultValue) { - return getProperties().get(key, defaultValue); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.gallery; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.RangeModel; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IFilter; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.part.GraphicalRootEditPart; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; + +public class GalleryViewer extends GraphicalViewer + implements IDecorationContext { + + /** + * Viewer property key indicating whether frames are laid out horizontally + * or vertically. + *

+ * Values: true, false + *

+ */ + public static final String Horizontal = "org.xmind.ui.gallery.horizontal"; //$NON-NLS-1$ + + /** + * Viewer property key indicating whether frames can wrap. + *

+ * Values: true, false + *

+ */ + public static final String Wrap = "org.xmind.ui.gallery.wrap"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String HideTitle = "org.xmind.ui.gallery.hideTitle"; //$NON-NLS-1$ + + /** + * Values: GalleryLayout + */ + public static final String Layout = "org.xmind.ui.gallery.layout"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String ImageStretched = "stretched"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String ImageConstrained = "constrained"; //$NON-NLS-1$ + + /** + * Values: {@link org.eclipse.draw2d.geometry.Dimension} + */ + public static final String FrameContentSize = "org.xmind.ui.gallery.frameContentSize"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String PackFrameContent = "org.xmind.ui.gallery.packFrameContent"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String FlatFrames = "org.xmind.ui.gallery.flatFrames"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String SolidFrames = "org.xmind.ui.gallery.solidFrames"; //$NON-NLS-1$ + + /** + * Values: TITLE_TOP, TITLE_BOTTOM, TITLE_LEFT, TITLE_RIGHT + */ + public static final String TitlePlacement = "org.xmind.ui.gallery.titlePlacement"; //$NON-NLS-1$ + + /** + * Values: true, false + */ + public static final String SingleClickToOpen = "org.xmind.ui.gallery.singleClickToOpen"; //$NON-NLS-1$ + + /** + *

+ * Determines whether this viewer allows empty selection to be set. This + * property does not work when the input contains no elements because the + * selection will always be empty in this case. + *

+ * Values: true, false + */ + public static final String EmptySelectionIgnored = "org.xmind.ui.gallery.emptySelectionIgnored"; //$NON-NLS-1$ + + /** + *

+ * Determines whether this viewer takes use of custom decorator to draw + * content pane. + *

+ */ + public static final String CustomContentPaneDecorator = "org.xmind.ui.gallery.customDecorateContentPane"; //$NON-NLS-1$ + + public static final String ContentPaneMargins = "org.xmind.ui.gallery.contentPaneMargins"; //$NON-NLS-1$ + + public static final String ContentPaneBorderWidth = "org.xmind.ui.gallery.contentPaneBorderWidth"; //$NON-NLS-1$ + + public static final String ContentPaneBorderColor = "org.xmind.ui.gallery.contentPaneBorderColor"; //$NON-NLS-1$ + + public static final String ContentPaneSpaceCollaborativeEngine = "org.xmind.ui.gallery.contentPaneSpaceCollaborativeEngine"; //$NON-NLS-1$ + + public static final String HorizontalLayout = "org.xmind.ui.gallery.horizontalLayout"; //$NON-NLS-1$ + + /** + * Value for title placement 'top'. + */ + public static final Integer TITLE_TOP = new Integer(PositionConstants.TOP); + + /** + * Value for title placement 'bottom'. + */ + public static final Integer TITLE_BOTTOM = new Integer( + PositionConstants.BOTTOM); + + /** + * Value for title placement 'left'. + */ + public static final Integer TITLE_LEFT = new Integer( + PositionConstants.LEFT); + + /** + * Value for title placement 'right'. + */ + public static final Integer TITLE_RIGHT = new Integer( + PositionConstants.RIGHT); + + public static final String POLICY_NAVIGABLE = "org.xmind.ui.gallery.editPolicy.navigable"; //$NON-NLS-1$ + public static final String POLICY_MOVABLE = "org.xmind.ui.gallery.editPolicy.movable"; //$NON-NLS-1$ + + private class GalleryLabelProviderListener + implements ILabelProviderListener { + public void labelProviderChanged(LabelProviderChangedEvent event) { + update(event.getElements()); + } + } + + private IStructuredContentProvider contentProvider = null; + + private IBaseLabelProvider labelProvider = null; + + private ILabelProviderListener labelProviderListener = new GalleryLabelProviderListener(); + + private List openListeners = null; + + private IFilter titleEditingApprover = null; + + public GalleryViewer() { + setPartFactory(GalleryPartFactory.getDefault()); + setRootPart(new GraphicalRootEditPart()); + } + + public T getAdapter(Class adapter) { + if (IBaseLabelProvider.class.equals(adapter)) + return adapter.cast(getLabelProvider()); + if (IStructuredContentProvider.class.equals(adapter)) + return adapter.cast(getContentProvider()); + return super.getAdapter(adapter); + } + + protected Control internalCreateControl(Composite parent, int style) { + Control control = super.internalCreateControl(parent, style); + control.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + return control; + } + + public void update() { + update(null); + } + + public void update(Object[] elements) { + if (elements == null) { + IPart contents = getRootPart().getContents(); + if (contents.getStatus().isActive()) + contents.refresh(); + for (IPart p : contents.getChildren()) { + if (p.getStatus().isActive()) { + ((IGraphicalPart) p).refresh(); + } + } + } else { + for (Object element : elements) { + IPart p = findPart(element); + if (p != null && p.getStatus().isActive()) { + ((IGraphicalPart) p).refresh(); + } + } + } + } + + public void setContentProvider(IStructuredContentProvider contentProvider) { + IStructuredContentProvider oldContentProvider = this.contentProvider; + this.contentProvider = contentProvider; + if (oldContentProvider != null) { + Object currentInput = getInput(); + oldContentProvider.inputChanged(this, currentInput, null); + oldContentProvider.dispose(); + contentProvider.inputChanged(this, null, currentInput); + refresh(); + } + } + + public IStructuredContentProvider getContentProvider() { + return contentProvider; + } + + public IBaseLabelProvider getLabelProvider() { + if (labelProvider == null) { + labelProvider = new LabelProvider(); + } + return labelProvider; + } + + public void setLabelProvider(IBaseLabelProvider labelProvider) { + if (labelProvider == null) + return; + + IBaseLabelProvider oldLabelProvider = this.labelProvider; + if (labelProvider == oldLabelProvider) + return; + + if (oldLabelProvider != null) { + oldLabelProvider.removeListener(labelProviderListener); + } + this.labelProvider = labelProvider; + labelProviderListener = new GalleryLabelProviderListener(); + labelProvider.addListener(labelProviderListener); + refresh(); + + if (oldLabelProvider != null) { + oldLabelProvider.dispose(); + } + } + + @Override + protected void contentsChanged(Object input, Object oldInput) { + IStructuredContentProvider content = getContentProvider(); + if (content != null) { + content.inputChanged(this, oldInput, input); + } + super.contentsChanged(input, oldInput); + } + + protected void handleDispose(DisposeEvent e) { + if (contentProvider != null) { + contentProvider.inputChanged(this, getInput(), null); + contentProvider.dispose(); + contentProvider = null; + } + if (labelProvider != null) { + labelProvider.removeListener(labelProviderListener); + labelProvider.dispose(); + labelProvider = null; + } + super.handleDispose(e); + } + + public void centerHorizontal() { + FigureCanvas fc = getCanvas(); + if (fc.isDisposed()) + return; + RangeModel horizontal = fc.getViewport().getHorizontalRangeModel(); + int h = (horizontal.getMaximum() - horizontal.getExtent() + + horizontal.getMinimum()) / 2; + fc.scrollToX(h); + } + + public void addOpenListener(IOpenListener listener) { + if (openListeners == null) + openListeners = new ArrayList(); + openListeners.add(listener); + } + + public void removeOpenListener(IOpenListener listener) { + if (openListeners == null) + return; + openListeners.remove(listener); + } + + protected void fireOpen(final OpenEvent event) { + if (openListeners == null) + return; + for (final Object l : openListeners.toArray()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + ((IOpenListener) l).open(event); + } + }); + } + } + + protected void fireOpen() { + fireOpen(new OpenEvent(this, getSelection())); + } + + private List toReveal; + + protected void revealParts(List parts) { + if (toReveal != null) { + toReveal = parts; + } else { + toReveal = parts; + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (toReveal == null || getControl() == null + || getControl().isDisposed()) + return; + + Rectangle r = null; + for (IPart p : toReveal) { + if (p instanceof IGraphicalPart) { + r = Geometry.union(r, ((IGraphicalPart) p) + .getFigure().getBounds()); + } + } + if (r != null) { + ensureVisible(r); + } + toReveal = null; + } + }); + } + } + + @Override + public void setSelection(ISelection selection) { + setSelection(selection, true); + } + + @Override + public void setSelection(ISelection selection, boolean reveal) { + if (getProperties().getBoolean(EmptySelectionIgnored, false) + && selection.isEmpty()) + return; + super.setSelection(selection, reveal); + } + + public IFilter getTitleEditingApprover() { + return titleEditingApprover; + } + + public void setTitleEditingApprover(IFilter titleEditingApprover) { + this.titleEditingApprover = titleEditingApprover; + } + + protected boolean isTitleEditable(IPart p) { + return titleEditingApprover != null && titleEditingApprover.select(p); + } + + public Object getProperty(String key, Object defaultValue) { + return getProperties().get(key, defaultValue); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/IDecorationContext.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/IDecorationContext.java index f7dff23de..087fab224 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/IDecorationContext.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/IDecorationContext.java @@ -1,7 +1,7 @@ -package org.xmind.ui.gallery; - -public interface IDecorationContext { - - Object getProperty(String key, Object defaultValue); - -} +package org.xmind.ui.gallery; + +public interface IDecorationContext { + + Object getProperty(String key, Object defaultValue); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ILabelDecorator.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ILabelDecorator.java index 1b9be1b8e..1c3917f13 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ILabelDecorator.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ILabelDecorator.java @@ -1,10 +1,10 @@ -package org.xmind.ui.gallery; - -import org.eclipse.draw2d.IFigure; - -public interface ILabelDecorator { - - IFigure decorateFigure(IFigure figure, Object element, - IDecorationContext context); - -} +package org.xmind.ui.gallery; + +import org.eclipse.draw2d.IFigure; + +public interface ILabelDecorator { + + IFigure decorateFigure(IFigure figure, Object element, + IDecorationContext context); + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationAnimationService.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationAnimationService.java index d18649086..3317c9e0f 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationAnimationService.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationAnimationService.java @@ -1,337 +1,337 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutListener; -import org.eclipse.draw2d.UpdateManager; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.service.GraphicalViewerService; - -/** - * @author Frank Shaka - * - */ -public class NavigationAnimationService extends GraphicalViewerService - implements ISelectionChangedListener { - - private static final int DURATION = 100; - -// private static final int INTERVALS = 100; - - private static class ItemState { - - public double state; - - public Rectangle bounds; - - /** - * - */ - public ItemState(NavigationItemFigure figure) { - this.state = figure.getState(); - this.bounds = new Rectangle(figure.getBounds()); - } - - } - - private static class ItemStates { - - private Map states = new HashMap(); - - public IFigure itemParent; - - public IFigure content; - - public IFigure contentParent; - - public Rectangle contentBounds; - - /** - * - */ - public ItemStates(IFigure parent, IFigure content) { - this.itemParent = parent; - List children = parent.getChildren(); - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - states.put(child, new ItemState((NavigationItemFigure) child)); - } - this.content = content; - this.contentParent = content.getParent(); - this.contentBounds = new Rectangle(content.getBounds()); - } - - public Iterator figures() { - return states.keySet().iterator(); - } - - public ItemState getState(IFigure figure) { - return states.get(figure); - } - - public void apply() { - Iterator it = figures(); - while (it.hasNext()) { - IFigure figure = it.next(); - ItemState state = getState(figure); - ((NavigationItemFigure) figure).setState(state.state); - figure.setBounds(state.bounds); - } - content.setBounds(contentBounds); - } - - } - - private class Transition extends LayoutListener.Stub implements Runnable { - - private UpdateManager updateManager; - - private ItemStates sourceStates; - - private ItemStates targetStates; - - private long start = 0; - - private long end = 0; - - /** - * - */ - public Transition(UpdateManager updateManager, ItemStates sourceStates, - ItemStates targetStates) { - this.updateManager = updateManager; - this.sourceStates = sourceStates; - this.targetStates = targetStates; - } - - public void start() { - sourceStates.itemParent.addLayoutListener(this); - sourceStates.contentParent.addLayoutListener(this); - start = System.currentTimeMillis(); - end = start + DURATION; - sourceStates.apply(); - try { - while (System.currentTimeMillis() < end) { - run(); - } - } catch (IllegalStateException e) { - } - targetStates.apply(); - } - - private double getRatio() { - double time = System.currentTimeMillis(); - if (time > end) - return -1; - double ratio = ((double) (time - start)) / DURATION; - return Math.max(0, Math.min(1, ratio)); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.draw2d.LayoutListener.Stub#layout(org.eclipse.draw2d. - * IFigure) - */ - @Override - public boolean layout(IFigure container) { - double r = getRatio(); - if (r < 0) { - return false; - } - if (container == sourceStates.itemParent) { - Rectangle b = new Rectangle(); - List children = container.getChildren(); - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - ItemState s1 = sourceStates.getState(child); - ItemState s2 = targetStates.getState(child); - int x = (int) seg(s1.bounds.x, s2.bounds.x, r); - int y = (int) seg(s1.bounds.y, s2.bounds.y, r); - int w = (int) seg(s1.bounds.width, s2.bounds.width, r); - int h = (int) seg(s1.bounds.height, s2.bounds.height, r); - b.setBounds(x, y, w, h); - child.setBounds(b); - } - } else if (container == sourceStates.contentParent) { - Rectangle b = new Rectangle(); - Rectangle r1 = sourceStates.contentBounds; - Rectangle r2 = targetStates.contentBounds; - b.x = (int) seg(r1.x, r2.x, r); - b.y = (int) seg(r1.y, r2.y, r); - b.width = (int) seg(r1.width, r2.width, r); - b.height = (int) seg(r1.height, r2.height, r); - sourceStates.content.setBounds(b); - } - return true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - public void run() { - double r = getRatio(); - if (r < 0) { - throw new IllegalStateException("Animation is finished."); //$NON-NLS-1$ - } - changeState(r); - sourceStates.itemParent.revalidate(); - updateManager.performUpdate(); - } - - private void changeState(double r) { - Iterator it = sourceStates.figures(); - while (it.hasNext()) { - NavigationItemFigure figure = (NavigationItemFigure) it.next(); - ItemState s1 = sourceStates.getState(figure); - ItemState s2 = targetStates.getState(figure); - figure.setState(seg(s1.state, s2.state, r)); - } - } - - } - -// private States currentStates = null; -// -// private Queue transitions = new LinkedList(); -// -// private Transition runningTransition = null; - - /** - * @param viewer - */ - public NavigationAnimationService(IGraphicalViewer viewer) { - super(viewer); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#activate() - */ - @Override - protected void activate() { - getViewer().addFocusedPartChangedListener(this); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#deactivate() - */ - @Override - protected void deactivate() { - getViewer().removeFocusedPartChangedListener(this); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged( - * org.eclipse.jface.viewers.SelectionChangedEvent) - */ - public void selectionChanged(SelectionChangedEvent event) { - if (!isActive()) - return; - - ItemStates sourceStates = captureStates(); - if (!applySelectionChanges(event.getSelection())) - return; - - UpdateManager updateManager = ((GraphicalViewer) getViewer()) - .getLightweightSystem().getUpdateManager(); - updateManager.performValidation(); - - ItemStates targetStates = captureStates(); - - new Transition(updateManager, sourceStates, targetStates).start(); - } - - /** - * @param selection - */ - private boolean applySelectionChanges(ISelection selection) { - if (selection.isEmpty()) - return false; - - IPart part = getViewer().findPart( - ((IStructuredSelection) selection).getFirstElement()); - if (part == null) - return false; - IPart parent = getViewer().getRootPart().getContents(); - for (IPart child : parent.getChildren()) { - NavigationItemFigure childFigure = (NavigationItemFigure) ((IGraphicalPart) child) - .getFigure(); - if (child == part) { - // focused: - childFigure.setState(1); - childFigure.getParent().setConstraint(childFigure, childFigure); - } else { - // not focused: - childFigure.setState(0); - } - } - ((NavigationContentPart) getViewer().getRootPart().getContents()) - .resetScrollOffset(); - return true; - } - - public ItemStates captureStates() { - IGraphicalPart contentPart = (IGraphicalPart) getViewer().getRootPart() - .getContents(); - return new ItemStates(contentPart.getContentPane(), - contentPart.getFigure()); - } - -// private void runTransition(Transition transition) { -// transitions.offer(transition); -// if (runningTransition != null) -// return; -// runNextTransition(); -// } -// -// private void runNextTransition() { -// if (!isActive()) -// return; -// if (transitions.isEmpty()) -// return; -// runningTransition = transitions.poll(); -// System.out.println("Start: " + runningTransition); -// runningTransition.start(); -// } -// - private static double seg(double min, double max, double ratio) { - return min + (max - min) * ratio; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutListener; +import org.eclipse.draw2d.UpdateManager; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.service.GraphicalViewerService; + +/** + * @author Frank Shaka + * + */ +public class NavigationAnimationService extends GraphicalViewerService + implements ISelectionChangedListener { + + private static final int DURATION = 100; + +// private static final int INTERVALS = 100; + + private static class ItemState { + + public double state; + + public Rectangle bounds; + + /** + * + */ + public ItemState(NavigationItemFigure figure) { + this.state = figure.getState(); + this.bounds = new Rectangle(figure.getBounds()); + } + + } + + private static class ItemStates { + + private Map states = new HashMap(); + + public IFigure itemParent; + + public IFigure content; + + public IFigure contentParent; + + public Rectangle contentBounds; + + /** + * + */ + public ItemStates(IFigure parent, IFigure content) { + this.itemParent = parent; + List children = parent.getChildren(); + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + states.put(child, new ItemState((NavigationItemFigure) child)); + } + this.content = content; + this.contentParent = content.getParent(); + this.contentBounds = new Rectangle(content.getBounds()); + } + + public Iterator figures() { + return states.keySet().iterator(); + } + + public ItemState getState(IFigure figure) { + return states.get(figure); + } + + public void apply() { + Iterator it = figures(); + while (it.hasNext()) { + IFigure figure = it.next(); + ItemState state = getState(figure); + ((NavigationItemFigure) figure).setState(state.state); + figure.setBounds(state.bounds); + } + content.setBounds(contentBounds); + } + + } + + private class Transition extends LayoutListener.Stub implements Runnable { + + private UpdateManager updateManager; + + private ItemStates sourceStates; + + private ItemStates targetStates; + + private long start = 0; + + private long end = 0; + + /** + * + */ + public Transition(UpdateManager updateManager, ItemStates sourceStates, + ItemStates targetStates) { + this.updateManager = updateManager; + this.sourceStates = sourceStates; + this.targetStates = targetStates; + } + + public void start() { + sourceStates.itemParent.addLayoutListener(this); + sourceStates.contentParent.addLayoutListener(this); + start = System.currentTimeMillis(); + end = start + DURATION; + sourceStates.apply(); + try { + while (System.currentTimeMillis() < end) { + run(); + } + } catch (IllegalStateException e) { + } + targetStates.apply(); + } + + private double getRatio() { + double time = System.currentTimeMillis(); + if (time > end) + return -1; + double ratio = ((double) (time - start)) / DURATION; + return Math.max(0, Math.min(1, ratio)); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.LayoutListener.Stub#layout(org.eclipse.draw2d. + * IFigure) + */ + @Override + public boolean layout(IFigure container) { + double r = getRatio(); + if (r < 0) { + return false; + } + if (container == sourceStates.itemParent) { + Rectangle b = new Rectangle(); + List children = container.getChildren(); + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + ItemState s1 = sourceStates.getState(child); + ItemState s2 = targetStates.getState(child); + int x = (int) seg(s1.bounds.x, s2.bounds.x, r); + int y = (int) seg(s1.bounds.y, s2.bounds.y, r); + int w = (int) seg(s1.bounds.width, s2.bounds.width, r); + int h = (int) seg(s1.bounds.height, s2.bounds.height, r); + b.setBounds(x, y, w, h); + child.setBounds(b); + } + } else if (container == sourceStates.contentParent) { + Rectangle b = new Rectangle(); + Rectangle r1 = sourceStates.contentBounds; + Rectangle r2 = targetStates.contentBounds; + b.x = (int) seg(r1.x, r2.x, r); + b.y = (int) seg(r1.y, r2.y, r); + b.width = (int) seg(r1.width, r2.width, r); + b.height = (int) seg(r1.height, r2.height, r); + sourceStates.content.setBounds(b); + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + public void run() { + double r = getRatio(); + if (r < 0) { + throw new IllegalStateException("Animation is finished."); //$NON-NLS-1$ + } + changeState(r); + sourceStates.itemParent.revalidate(); + updateManager.performUpdate(); + } + + private void changeState(double r) { + Iterator it = sourceStates.figures(); + while (it.hasNext()) { + NavigationItemFigure figure = (NavigationItemFigure) it.next(); + ItemState s1 = sourceStates.getState(figure); + ItemState s2 = targetStates.getState(figure); + figure.setState(seg(s1.state, s2.state, r)); + } + } + + } + +// private States currentStates = null; +// +// private Queue transitions = new LinkedList(); +// +// private Transition runningTransition = null; + + /** + * @param viewer + */ + public NavigationAnimationService(IGraphicalViewer viewer) { + super(viewer); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#activate() + */ + @Override + protected void activate() { + getViewer().addFocusedPartChangedListener(this); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#deactivate() + */ + @Override + protected void deactivate() { + getViewer().removeFocusedPartChangedListener(this); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged( + * org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + if (!isActive()) + return; + + ItemStates sourceStates = captureStates(); + if (!applySelectionChanges(event.getSelection())) + return; + + UpdateManager updateManager = ((GraphicalViewer) getViewer()) + .getLightweightSystem().getUpdateManager(); + updateManager.performValidation(); + + ItemStates targetStates = captureStates(); + + new Transition(updateManager, sourceStates, targetStates).start(); + } + + /** + * @param selection + */ + private boolean applySelectionChanges(ISelection selection) { + if (selection.isEmpty()) + return false; + + IPart part = getViewer().findPart( + ((IStructuredSelection) selection).getFirstElement()); + if (part == null) + return false; + IPart parent = getViewer().getRootPart().getContents(); + for (IPart child : parent.getChildren()) { + NavigationItemFigure childFigure = (NavigationItemFigure) ((IGraphicalPart) child) + .getFigure(); + if (child == part) { + // focused: + childFigure.setState(1); + childFigure.getParent().setConstraint(childFigure, childFigure); + } else { + // not focused: + childFigure.setState(0); + } + } + ((NavigationContentPart) getViewer().getRootPart().getContents()) + .resetScrollOffset(); + return true; + } + + public ItemStates captureStates() { + IGraphicalPart contentPart = (IGraphicalPart) getViewer().getRootPart() + .getContents(); + return new ItemStates(contentPart.getContentPane(), + contentPart.getFigure()); + } + +// private void runTransition(Transition transition) { +// transitions.offer(transition); +// if (runningTransition != null) +// return; +// runNextTransition(); +// } +// +// private void runNextTransition() { +// if (!isActive()) +// return; +// if (transitions.isEmpty()) +// return; +// runningTransition = transitions.poll(); +// System.out.println("Start: " + runningTransition); +// runningTransition.start(); +// } +// + private static double seg(double min, double max, double ratio) { + return min + (max - min) * ratio; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationContentPart.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationContentPart.java index 46ea6f951..163fddcb3 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationContentPart.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationContentPart.java @@ -1,82 +1,82 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.xmind.gef.part.GraphicalEditPart; - -/** - * @author Frank Shaka - * - */ -public class NavigationContentPart extends GraphicalEditPart { - - /** - * - */ - public NavigationContentPart(Object model) { - setModel(model); - getFigure(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.GraphicalEditPart#createFigure() - */ - @Override - protected IFigure createFigure() { - IFigure figure = new Layer(); - figure.setOpaque(true); - figure.setBackgroundColor(ColorConstants.black); - figure.setLayoutManager(new NavigationItemLayout()); - return figure; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.Part#getModelChildren(java.lang.Object) - */ - @Override - protected Object[] getModelChildren(Object model) { - IStructuredContentProvider contentProvider = (IStructuredContentProvider) getSite() - .getViewer().getAdapter(IStructuredContentProvider.class); - if (contentProvider != null) { - return contentProvider.getElements(model); - } - return super.getModelChildren(model); - } - - protected void onItemSelection(NavigationItemPart item) { - getFigure().setConstraint(item.getFigure(), item.getFigure()); - } - - public void addScrollOffset(int offset) { - ((NavigationItemLayout) getFigure().getLayoutManager()).addOffset( - getFigure(), offset); - getFigure().revalidate(); - } - - public void resetScrollOffset() { - ((NavigationItemLayout) getFigure().getLayoutManager()) - .resetOffset(getFigure()); - getFigure().revalidate(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.xmind.gef.part.GraphicalEditPart; + +/** + * @author Frank Shaka + * + */ +public class NavigationContentPart extends GraphicalEditPart { + + /** + * + */ + public NavigationContentPart(Object model) { + setModel(model); + getFigure(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.GraphicalEditPart#createFigure() + */ + @Override + protected IFigure createFigure() { + IFigure figure = new Layer(); + figure.setOpaque(true); + figure.setBackgroundColor(ColorConstants.black); + figure.setLayoutManager(new NavigationItemLayout()); + return figure; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.Part#getModelChildren(java.lang.Object) + */ + @Override + protected Object[] getModelChildren(Object model) { + IStructuredContentProvider contentProvider = (IStructuredContentProvider) getSite() + .getViewer().getAdapter(IStructuredContentProvider.class); + if (contentProvider != null) { + return contentProvider.getElements(model); + } + return super.getModelChildren(model); + } + + protected void onItemSelection(NavigationItemPart item) { + getFigure().setConstraint(item.getFigure(), item.getFigure()); + } + + public void addScrollOffset(int offset) { + ((NavigationItemLayout) getFigure().getLayoutManager()).addOffset( + getFigure(), offset); + getFigure().revalidate(); + } + + public void resetScrollOffset() { + ((NavigationItemLayout) getFigure().getLayoutManager()) + .resetOffset(getFigure()); + getFigure().revalidate(); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemFigure.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemFigure.java index 72890e944..d9ca2c5fa 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemFigure.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemFigure.java @@ -1,266 +1,266 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import static org.xmind.ui.gallery.NavigationViewer.BIG_ALPHA; -import static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT; -import static org.xmind.ui.gallery.NavigationViewer.SMALL_ALPHA; -import static org.xmind.ui.gallery.NavigationViewer.SMALL_HEIGHT; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LineBorder; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; - -/** - * @author Frank Shaka - * - */ -public class NavigationItemFigure extends Figure { - - private class MaskBorder extends LineBorder { - - /** - * - */ - public MaskBorder() { - super(ColorConstants.lightGray, 1); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.Border#getInsets(org.eclipse.draw2d.IFigure) - */ - public Insets getInsets(IFigure figure) { - return NO_INSETS; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.Border#paint(org.eclipse.draw2d.IFigure, - * org.eclipse.draw2d.Graphics, org.eclipse.draw2d.geometry.Insets) - */ - public void paint(IFigure figure, Graphics graphics, Insets insets) { - if (alpha > 0) { - tempRect.setBounds(getPaintRectangle(figure, insets)); - graphics.setAlpha(alpha); - graphics.setBackgroundColor(ColorConstants.black); - graphics.fillRectangle(tempRect); - } else { - super.paint(figure, graphics, insets); - } - } - - } - - private static final double MIN_SCALE = ((double) SMALL_HEIGHT) - / ((double) BIG_HEIGHT); - - private static final double MAX_SCALE = 1; - - private Image image = null; - - private String text = null; - - private double state = 0; - - private int alpha = 0; - - /** - * - */ - public NavigationItemFigure() { - setBorder(new MaskBorder()); - setOpaque(true); - setBackgroundColor(ColorConstants.white); - updateState(); - } - - /** - * @return the image - */ - public Image getImage() { - return image; - } - - /** - * @param image - * the image to set - */ - public void setImage(Image image) { - if (image == this.image) - return; - this.image = image; - repaint(); - } - - /** - * @return the text - */ - public String getText() { - return text; - } - - /** - * @param text - * the text to set - */ - public void setText(String text) { - if (text == this.text || (text != null && text.equals(this.text))) - return; - this.text = text; - repaint(); - } - - /** - * @return the state - */ - public double getState() { - return state; - } - - /** - * @param state - * the state to set - */ - public void setState(double state) { - if (state == this.state) - return; - this.state = state; - updateState(); - revalidate(); - } - - private void updateState() { - int s = (int) seg(SMALL_HEIGHT, BIG_HEIGHT, state); - setPreferredSize(s, s); - alpha = (int) seg(SMALL_ALPHA, BIG_ALPHA, state); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics) - */ - @Override - public void paint(Graphics graphics) { - graphics.setAdvanced(true); - graphics.setAntialias(SWT.ON); - super.paint(graphics); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) - */ - @Override - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - - Rectangle b = getBounds(); - float cx = b.x + ((float) b.width) / 2; - float cy = b.y + ((float) b.height) / 2; - double scale = seg(MIN_SCALE, MAX_SCALE, state); - Rectangle r = getClientArea(Rectangle.SINGLETON); - float x = r.x - ((float) BIG_HEIGHT - b.width) / 2 - cx; - float y = r.y - ((float) BIG_HEIGHT - b.height) / 2 - cy; - float w = r.width + (BIG_HEIGHT - b.width); - float h = r.height + (BIG_HEIGHT - b.height); - - graphics.pushState(); - - try { - // Configure graphics: - graphics.translate(cx, cy); - graphics.scale(scale); - - if (image != null) { - paintImage(graphics, x, y, w, h); - } else if (text != null) { - paintText(graphics, x, y, w, h); - } - } finally { - graphics.restoreState(); - graphics.popState(); - } - } - - private void paintImage(Graphics graphics, float x, float y, float w, - float h) { - org.eclipse.swt.graphics.Rectangle ir = image.getBounds(); - float iw = ir.width; - float ih = ir.height; - float tw = iw; - float th = ih; - if (tw > w) { - th = th * w / tw; - tw = w; - } - if (th > h) { - tw = tw * h / th; - th = h; - } - float tx = x + (w - tw) / 2; - float ty = y + (h - th) / 2; - graphics.drawImage(image, 0, 0, (int) iw, (int) ih, (int) tx, (int) ty, - (int) tw, (int) th); - } - - private void paintText(Graphics graphics, float x, float y, float w, float h) { - float m = w * 0.05f; - x += m; - y += m; - w -= m + m; - h -= m + m; - Dimension s = GraphicsUtils.getAdvanced().getTextSize(text, - graphics.getFont()); - float tw = s.width; - float th = s.height; - double ts = 1; - if (tw > w) { - th = th * w / tw; - ts = ts * w / tw; - tw = w; - } - if (th > h) { - tw = tw * h / th; - ts = ts * h / th; - th = h; - } - float tx = x + (w - tw) / 2; - float ty = y + (h - th) / 2; - if (ts == 1) { - graphics.drawText(text, (int) tx, (int) ty); - } else { - graphics.scale(ts); - graphics.drawText(text, (int) (tx / ts), (int) (ty / ts)); - } - } - - private static double seg(double min, double max, double ratio) { - return min + (max - min) * ratio; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import static org.xmind.ui.gallery.NavigationViewer.BIG_ALPHA; +import static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT; +import static org.xmind.ui.gallery.NavigationViewer.SMALL_ALPHA; +import static org.xmind.ui.gallery.NavigationViewer.SMALL_HEIGHT; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LineBorder; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; + +/** + * @author Frank Shaka + * + */ +public class NavigationItemFigure extends Figure { + + private class MaskBorder extends LineBorder { + + /** + * + */ + public MaskBorder() { + super(ColorConstants.lightGray, 1); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.Border#getInsets(org.eclipse.draw2d.IFigure) + */ + public Insets getInsets(IFigure figure) { + return NO_INSETS; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.Border#paint(org.eclipse.draw2d.IFigure, + * org.eclipse.draw2d.Graphics, org.eclipse.draw2d.geometry.Insets) + */ + public void paint(IFigure figure, Graphics graphics, Insets insets) { + if (alpha > 0) { + tempRect.setBounds(getPaintRectangle(figure, insets)); + graphics.setAlpha(alpha); + graphics.setBackgroundColor(ColorConstants.black); + graphics.fillRectangle(tempRect); + } else { + super.paint(figure, graphics, insets); + } + } + + } + + private static final double MIN_SCALE = ((double) SMALL_HEIGHT) + / ((double) BIG_HEIGHT); + + private static final double MAX_SCALE = 1; + + private Image image = null; + + private String text = null; + + private double state = 0; + + private int alpha = 0; + + /** + * + */ + public NavigationItemFigure() { + setBorder(new MaskBorder()); + setOpaque(true); + setBackgroundColor(ColorConstants.white); + updateState(); + } + + /** + * @return the image + */ + public Image getImage() { + return image; + } + + /** + * @param image + * the image to set + */ + public void setImage(Image image) { + if (image == this.image) + return; + this.image = image; + repaint(); + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text + * the text to set + */ + public void setText(String text) { + if (text == this.text || (text != null && text.equals(this.text))) + return; + this.text = text; + repaint(); + } + + /** + * @return the state + */ + public double getState() { + return state; + } + + /** + * @param state + * the state to set + */ + public void setState(double state) { + if (state == this.state) + return; + this.state = state; + updateState(); + revalidate(); + } + + private void updateState() { + int s = (int) seg(SMALL_HEIGHT, BIG_HEIGHT, state); + setPreferredSize(s, s); + alpha = (int) seg(SMALL_ALPHA, BIG_ALPHA, state); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics) + */ + @Override + public void paint(Graphics graphics) { + graphics.setAdvanced(true); + graphics.setAntialias(SWT.ON); + super.paint(graphics); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) + */ + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + + Rectangle b = getBounds(); + float cx = b.x + ((float) b.width) / 2; + float cy = b.y + ((float) b.height) / 2; + double scale = seg(MIN_SCALE, MAX_SCALE, state); + Rectangle r = getClientArea(Rectangle.SINGLETON); + float x = r.x - ((float) BIG_HEIGHT - b.width) / 2 - cx; + float y = r.y - ((float) BIG_HEIGHT - b.height) / 2 - cy; + float w = r.width + (BIG_HEIGHT - b.width); + float h = r.height + (BIG_HEIGHT - b.height); + + graphics.pushState(); + + try { + // Configure graphics: + graphics.translate(cx, cy); + graphics.scale(scale); + + if (image != null) { + paintImage(graphics, x, y, w, h); + } else if (text != null) { + paintText(graphics, x, y, w, h); + } + } finally { + graphics.restoreState(); + graphics.popState(); + } + } + + private void paintImage(Graphics graphics, float x, float y, float w, + float h) { + org.eclipse.swt.graphics.Rectangle ir = image.getBounds(); + float iw = ir.width; + float ih = ir.height; + float tw = iw; + float th = ih; + if (tw > w) { + th = th * w / tw; + tw = w; + } + if (th > h) { + tw = tw * h / th; + th = h; + } + float tx = x + (w - tw) / 2; + float ty = y + (h - th) / 2; + graphics.drawImage(image, 0, 0, (int) iw, (int) ih, (int) tx, (int) ty, + (int) tw, (int) th); + } + + private void paintText(Graphics graphics, float x, float y, float w, float h) { + float m = w * 0.05f; + x += m; + y += m; + w -= m + m; + h -= m + m; + Dimension s = GraphicsUtils.getAdvanced().getTextSize(text, + graphics.getFont()); + float tw = s.width; + float th = s.height; + double ts = 1; + if (tw > w) { + th = th * w / tw; + ts = ts * w / tw; + tw = w; + } + if (th > h) { + tw = tw * h / th; + ts = ts * h / th; + th = h; + } + float tx = x + (w - tw) / 2; + float ty = y + (h - th) / 2; + if (ts == 1) { + graphics.drawText(text, (int) tx, (int) ty); + } else { + graphics.scale(ts); + graphics.drawText(text, (int) (tx / ts), (int) (ty / ts)); + } + } + + private static double seg(double min, double max, double ratio) { + return min + (max - min) * ratio; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemLayout.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemLayout.java index 85f5babc3..21777a3b6 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemLayout.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemLayout.java @@ -1,169 +1,169 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.eclipse.draw2d.AbstractLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; - -/** - * @author Frank Shaka - * - */ -public class NavigationItemLayout extends AbstractLayout { - - private static final int H_SPACING = 10; - - private static final int BIG_TOP_MARGIN = 10; - - private static final int SMALL_TOP_MARGIN = 25; - - private IFigure center = null; - - private Map cache = null; - - private int centerX = -1; - - private int childrenWidth = -1; - - private int offset = 0; - - private int maxOffset = -1; - - private int minOffset = -1; - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure) - */ - public void layout(IFigure container) { - buildCache(container); - Rectangle r = container.getClientArea(Rectangle.SINGLETON); - int x = r.x + r.width / 2 - centerX + offset; - int y = r.y + BIG_TOP_MARGIN; - for (Entry en : cache.entrySet()) { - IFigure child = en.getKey(); - Rectangle b = en.getValue(); - child.setBounds(b.getTranslated(x, y)); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse. - * draw2d.IFigure, int, int) - */ - @Override - protected Dimension calculatePreferredSize(IFigure container, int wHint, - int hHint) { - if (wHint >= 0 && hHint >= 0) - return new Dimension(wHint, hHint); - buildCache(container); - int width = childrenWidth + H_SPACING + H_SPACING; - int height = BIG_HEIGHT + BIG_TOP_MARGIN + BIG_TOP_MARGIN; - return new Dimension(width, height); - } - - private void buildCache(IFigure container) { - if (cache != null) - return; - cache = new HashMap(); - List children = container.getChildren(); - int x = 0; - int min = 1000; - int max = 0; - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - Dimension size = child.getPreferredSize(); - int cx = x + size.width / 2; - int y; - if (child == center) { - centerX = cx; - y = 0; - } else { - y = SMALL_TOP_MARGIN - BIG_TOP_MARGIN; - } - cache.put(child, new Rectangle(x, y, size.width, size.height)); - x += size.width + H_SPACING; - min = Math.min(min, cx); - max = Math.max(max, cx); - } - childrenWidth = x - H_SPACING; - if (centerX < 0) { - centerX = childrenWidth / 2; - } - minOffset = centerX - max; - maxOffset = centerX - min; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d.IFigure - * , java.lang.Object) - */ - @Override - public void setConstraint(IFigure child, Object constraint) { - if (child == constraint) { - this.center = child; - } - super.setConstraint(child, constraint); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.draw2d.AbstractLayout#invalidate() - */ - @Override - public void invalidate() { - super.invalidate(); - cache = null; - centerX = -1; - childrenWidth = -1; - maxOffset = -1; - minOffset = -1; - } - - /** - * @param offset - * the offset to set - */ - public void addOffset(IFigure container, int offset) { - offset += this.offset; - buildCache(container); - this.offset = Math.max(minOffset, Math.min(maxOffset, offset)); - } - - /** - * - */ - public void resetOffset(IFigure container) { - this.offset = 0; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.draw2d.AbstractLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; + +/** + * @author Frank Shaka + * + */ +public class NavigationItemLayout extends AbstractLayout { + + private static final int H_SPACING = 10; + + private static final int BIG_TOP_MARGIN = 10; + + private static final int SMALL_TOP_MARGIN = 25; + + private IFigure center = null; + + private Map cache = null; + + private int centerX = -1; + + private int childrenWidth = -1; + + private int offset = 0; + + private int maxOffset = -1; + + private int minOffset = -1; + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure) + */ + public void layout(IFigure container) { + buildCache(container); + Rectangle r = container.getClientArea(Rectangle.SINGLETON); + int x = r.x + r.width / 2 - centerX + offset; + int y = r.y + BIG_TOP_MARGIN; + for (Entry en : cache.entrySet()) { + IFigure child = en.getKey(); + Rectangle b = en.getValue(); + child.setBounds(b.getTranslated(x, y)); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse. + * draw2d.IFigure, int, int) + */ + @Override + protected Dimension calculatePreferredSize(IFigure container, int wHint, + int hHint) { + if (wHint >= 0 && hHint >= 0) + return new Dimension(wHint, hHint); + buildCache(container); + int width = childrenWidth + H_SPACING + H_SPACING; + int height = BIG_HEIGHT + BIG_TOP_MARGIN + BIG_TOP_MARGIN; + return new Dimension(width, height); + } + + private void buildCache(IFigure container) { + if (cache != null) + return; + cache = new HashMap(); + List children = container.getChildren(); + int x = 0; + int min = 1000; + int max = 0; + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + Dimension size = child.getPreferredSize(); + int cx = x + size.width / 2; + int y; + if (child == center) { + centerX = cx; + y = 0; + } else { + y = SMALL_TOP_MARGIN - BIG_TOP_MARGIN; + } + cache.put(child, new Rectangle(x, y, size.width, size.height)); + x += size.width + H_SPACING; + min = Math.min(min, cx); + max = Math.max(max, cx); + } + childrenWidth = x - H_SPACING; + if (centerX < 0) { + centerX = childrenWidth / 2; + } + minOffset = centerX - max; + maxOffset = centerX - min; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d.IFigure + * , java.lang.Object) + */ + @Override + public void setConstraint(IFigure child, Object constraint) { + if (child == constraint) { + this.center = child; + } + super.setConstraint(child, constraint); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.draw2d.AbstractLayout#invalidate() + */ + @Override + public void invalidate() { + super.invalidate(); + cache = null; + centerX = -1; + childrenWidth = -1; + maxOffset = -1; + minOffset = -1; + } + + /** + * @param offset + * the offset to set + */ + public void addOffset(IFigure container, int offset) { + offset += this.offset; + buildCache(container); + this.offset = Math.max(minOffset, Math.min(maxOffset, offset)); + } + + /** + * + */ + public void resetOffset(IFigure container) { + this.offset = 0; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemNavigablePolicy.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemNavigablePolicy.java index 0830b4b0b..49b9ace9e 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemNavigablePolicy.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemNavigablePolicy.java @@ -1,125 +1,125 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import java.util.List; - -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.policy.IEditPolicy; - -/** - * @author Frank Shaka - * - */ -public class NavigationItemNavigablePolicy implements IEditPolicy { - - public static final NavigationItemNavigablePolicy DEFAULT = new NavigationItemNavigablePolicy(); - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.policy.IEditPolicy#understands(java.lang.String) - */ - public boolean understands(String requestType) { - return GEF.REQ_NAV_LEFT.equals(requestType) - || GEF.REQ_NAV_RIGHT.equals(requestType) - || GEF.REQ_NAV_PREV.equals(requestType) - || GEF.REQ_NAV_NEXT.equals(requestType) - || GEF.REQ_NAV_BEGINNING.equals(requestType) - || GEF.REQ_NAV_END.equals(requestType); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.policy.IEditPolicy#handle(org.xmind.gef.Request) - */ - public void handle(Request request) { - NavigationItemPart item = findItem(request); - if (item == null) - return; - - IPart parent = item.getParent(); - if (parent == null) - return; - - List items = parent.getChildren(); - int index = items.indexOf(item); - if (index < 0) - return; - - String requestType = request.getType(); - if (GEF.REQ_NAV_BEGINNING.equals(requestType)) { - handleNavFirst(request, items); - } else if (GEF.REQ_NAV_END.equals(requestType)) { - handleNavLast(request, items); - } else if (GEF.REQ_NAV_LEFT.equals(requestType) - || GEF.REQ_NAV_PREV.equals(requestType)) { - handleNavPrev(request, items, index); - } else if (GEF.REQ_NAV_RIGHT.equals(requestType) - || GEF.REQ_NAV_NEXT.equals(requestType)) { - handleNavNext(request, items, index); - } - } - - /** - * @param request - */ - private void handleNavFirst(Request request, List items) { - if (items.size() > 0) { - setResult(request, items.get(0)); - } - } - - /** - * @param request - */ - private void handleNavLast(Request request, List items) { - if (items.size() > 0) { - setResult(request, items.get(items.size() - 1)); - } - } - - /** - * @param request - */ - private void handleNavPrev(Request request, List items, int index) { - index = Math.max(0, Math.min(items.size() - 1, index - 1)); - setResult(request, items.get(index)); - } - - /** - * @param request - */ - private void handleNavNext(Request request, List items, int index) { - index = Math.max(0, Math.min(items.size() - 1, index + 1)); - setResult(request, items.get(index)); - } - - private void setResult(Request request, IPart part) { - request.setResult(GEF.RESULT_NAVIGATION, new IPart[] { part }); - } - - private NavigationItemPart findItem(Request request) { - for (IPart part : request.getTargets()) { - if (part instanceof NavigationItemPart) - return (NavigationItemPart) part; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import java.util.List; + +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.policy.IEditPolicy; + +/** + * @author Frank Shaka + * + */ +public class NavigationItemNavigablePolicy implements IEditPolicy { + + public static final NavigationItemNavigablePolicy DEFAULT = new NavigationItemNavigablePolicy(); + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.policy.IEditPolicy#understands(java.lang.String) + */ + public boolean understands(String requestType) { + return GEF.REQ_NAV_LEFT.equals(requestType) + || GEF.REQ_NAV_RIGHT.equals(requestType) + || GEF.REQ_NAV_PREV.equals(requestType) + || GEF.REQ_NAV_NEXT.equals(requestType) + || GEF.REQ_NAV_BEGINNING.equals(requestType) + || GEF.REQ_NAV_END.equals(requestType); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.policy.IEditPolicy#handle(org.xmind.gef.Request) + */ + public void handle(Request request) { + NavigationItemPart item = findItem(request); + if (item == null) + return; + + IPart parent = item.getParent(); + if (parent == null) + return; + + List items = parent.getChildren(); + int index = items.indexOf(item); + if (index < 0) + return; + + String requestType = request.getType(); + if (GEF.REQ_NAV_BEGINNING.equals(requestType)) { + handleNavFirst(request, items); + } else if (GEF.REQ_NAV_END.equals(requestType)) { + handleNavLast(request, items); + } else if (GEF.REQ_NAV_LEFT.equals(requestType) + || GEF.REQ_NAV_PREV.equals(requestType)) { + handleNavPrev(request, items, index); + } else if (GEF.REQ_NAV_RIGHT.equals(requestType) + || GEF.REQ_NAV_NEXT.equals(requestType)) { + handleNavNext(request, items, index); + } + } + + /** + * @param request + */ + private void handleNavFirst(Request request, List items) { + if (items.size() > 0) { + setResult(request, items.get(0)); + } + } + + /** + * @param request + */ + private void handleNavLast(Request request, List items) { + if (items.size() > 0) { + setResult(request, items.get(items.size() - 1)); + } + } + + /** + * @param request + */ + private void handleNavPrev(Request request, List items, int index) { + index = Math.max(0, Math.min(items.size() - 1, index - 1)); + setResult(request, items.get(index)); + } + + /** + * @param request + */ + private void handleNavNext(Request request, List items, int index) { + index = Math.max(0, Math.min(items.size() - 1, index + 1)); + setResult(request, items.get(index)); + } + + private void setResult(Request request, IPart part) { + request.setResult(GEF.RESULT_NAVIGATION, new IPart[] { part }); + } + + private NavigationItemPart findItem(Request request) { + for (IPart part : request.getTargets()) { + if (part instanceof NavigationItemPart) + return (NavigationItemPart) part; + } + return null; + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemPart.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemPart.java index 23681d656..ea6904c0b 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemPart.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationItemPart.java @@ -1,152 +1,152 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.jface.viewers.IFontProvider; -import org.eclipse.jface.viewers.ILabelProvider; -import org.xmind.gef.GEF; -import org.xmind.gef.part.GraphicalEditPart; -import org.xmind.gef.part.IRequestHandler; -import org.xmind.gef.policy.NullEditPolicy; - -/** - * @author Frank Shaka - * - */ -public class NavigationItemPart extends GraphicalEditPart { - - /** - * - */ - public NavigationItemPart(Object model) { - setModel(model); - getFigure(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.GraphicalEditPart#createFigure() - */ - @Override - protected IFigure createFigure() { - return new NavigationItemFigure(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.GraphicalEditPart#updateView() - */ - @Override - protected void updateView() { - super.updateView(); - NavigationItemFigure fig = (NavigationItemFigure) getFigure(); - IBaseLabelProvider labelProvider = (IBaseLabelProvider) getSite() - .getViewer().getAdapter(IBaseLabelProvider.class); - if (labelProvider instanceof ILabelProvider) { - fig.setText(((ILabelProvider) labelProvider).getText(getModel())); - fig.setImage(((ILabelProvider) labelProvider).getImage(getModel())); - } - if (labelProvider instanceof IColorProvider) { - fig.setForegroundColor(((IColorProvider) labelProvider) - .getForeground(getModel())); - fig.setBackgroundColor(((IColorProvider) labelProvider) - .getBackground(getModel())); - } - if (labelProvider instanceof IFontProvider) { - fig.setFont(((IFontProvider) labelProvider).getFont(getModel())); - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.EditPart#declareEditPolicies(org.xmind.gef.part. - * IRequestHandler) - */ - @Override - protected void declareEditPolicies(IRequestHandler reqHandler) { - super.declareEditPolicies(reqHandler); - reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, - NavigationItemNavigablePolicy.DEFAULT); - reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE, - NullEditPolicy.getInstance()); - } - -// /* -// * (non-Javadoc) -// * -// * @see -// * org.xmind.gef.part.Part#handleStatusChanged(org.xmind.gef.status.StatusEvent -// * ) -// */ -// @Override -// protected void handleStatusChanged(StatusEvent event) { -// if (event.key == GEF.PART_SELECTED) { -// if (event.newValue) { -// onSelection(); -// } else { -// onDeselection(); -// } -// } else { -// super.handleStatusChanged(event); -// } -// } -// -// /** -// * -// */ -// private void onDeselection() { -// ((NavigationItemFigure) getFigure()).setState(0); -// } -// -// /** -// * -// */ -// private void onSelection() { -// ((NavigationItemFigure) getFigure()).setState(1); -// IPart parent = getParent(); -// if (parent != null && parent instanceof NavigationContentPart) { -// ((NavigationContentPart) parent).onItemSelection(this); -// } -// } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.EditPart#register() - */ - @Override - protected void register() { - registerModel(getModel()); - super.register(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.part.EditPart#unregister() - */ - @Override - protected void unregister() { - super.unregister(); - unregisterModel(getModel()); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.xmind.gef.GEF; +import org.xmind.gef.part.GraphicalEditPart; +import org.xmind.gef.part.IRequestHandler; +import org.xmind.gef.policy.NullEditPolicy; + +/** + * @author Frank Shaka + * + */ +public class NavigationItemPart extends GraphicalEditPart { + + /** + * + */ + public NavigationItemPart(Object model) { + setModel(model); + getFigure(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.GraphicalEditPart#createFigure() + */ + @Override + protected IFigure createFigure() { + return new NavigationItemFigure(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.GraphicalEditPart#updateView() + */ + @Override + protected void updateView() { + super.updateView(); + NavigationItemFigure fig = (NavigationItemFigure) getFigure(); + IBaseLabelProvider labelProvider = (IBaseLabelProvider) getSite() + .getViewer().getAdapter(IBaseLabelProvider.class); + if (labelProvider instanceof ILabelProvider) { + fig.setText(((ILabelProvider) labelProvider).getText(getModel())); + fig.setImage(((ILabelProvider) labelProvider).getImage(getModel())); + } + if (labelProvider instanceof IColorProvider) { + fig.setForegroundColor(((IColorProvider) labelProvider) + .getForeground(getModel())); + fig.setBackgroundColor(((IColorProvider) labelProvider) + .getBackground(getModel())); + } + if (labelProvider instanceof IFontProvider) { + fig.setFont(((IFontProvider) labelProvider).getFont(getModel())); + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.EditPart#declareEditPolicies(org.xmind.gef.part. + * IRequestHandler) + */ + @Override + protected void declareEditPolicies(IRequestHandler reqHandler) { + super.declareEditPolicies(reqHandler); + reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, + NavigationItemNavigablePolicy.DEFAULT); + reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE, + NullEditPolicy.getInstance()); + } + +// /* +// * (non-Javadoc) +// * +// * @see +// * org.xmind.gef.part.Part#handleStatusChanged(org.xmind.gef.status.StatusEvent +// * ) +// */ +// @Override +// protected void handleStatusChanged(StatusEvent event) { +// if (event.key == GEF.PART_SELECTED) { +// if (event.newValue) { +// onSelection(); +// } else { +// onDeselection(); +// } +// } else { +// super.handleStatusChanged(event); +// } +// } +// +// /** +// * +// */ +// private void onDeselection() { +// ((NavigationItemFigure) getFigure()).setState(0); +// } +// +// /** +// * +// */ +// private void onSelection() { +// ((NavigationItemFigure) getFigure()).setState(1); +// IPart parent = getParent(); +// if (parent != null && parent instanceof NavigationContentPart) { +// ((NavigationContentPart) parent).onItemSelection(this); +// } +// } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.EditPart#register() + */ + @Override + protected void register() { + registerModel(getModel()); + super.register(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.part.EditPart#unregister() + */ + @Override + protected void unregister() { + super.unregister(); + unregisterModel(getModel()); + } + +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationViewer.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationViewer.java index 3c0b2a9ed..b6abdb083 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationViewer.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/NavigationViewer.java @@ -1,286 +1,286 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.gallery; - -import java.util.List; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.LabelProviderChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.part.GraphicalEditPart; -import org.xmind.gef.part.GraphicalRootEditPart; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IPartFactory; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.tool.SelectTool; - -/** - * @author Frank Shaka - * - */ -public class NavigationViewer extends GraphicalViewer { - - private static class NavigationSelectTool extends SelectTool { - - @Override - protected boolean handleMouseDown(MouseEvent me) { - if (me.leftOrRight) { - if (me.target.hasRole(GEF.ROLE_SELECTABLE)) { - selectSingle(me.target); - return true; - } - return super.handleMouseDown(me); - } else { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.tool.SelectTool#select(java.util.List, - * org.xmind.gef.part.IPart) - */ - @Override - protected void select(List toSelect, IPart toFocus) { - if (toSelect.isEmpty()) - return; - super.select(toSelect, toFocus); - } - - } - - private class NavigationScrollHandler implements Listener { - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets - * .Event) - */ - public void handleEvent(Event event) { - int offset = event.count; - offset = (int) (Math.sqrt(Math.abs(offset)) * offset); - ((NavigationContentPart) getRootPart().getContents()) - .addScrollOffset(offset); - } - - } - - public static final int PREF_HEIGHT = 60; - - public static final int BIG_HEIGHT = 70; - - public static final int SMALL_HEIGHT = 50; - - public static final int BIG_ALPHA = 0; - - public static final int SMALL_ALPHA = 40; - - private static class EmptyPart extends GraphicalEditPart { - protected IFigure createFigure() { - return new Figure(); - } - } - - private static IPartFactory DEFAULT_PART_FACTORY = new IPartFactory() { - public IPart createPart(IPart context, Object model) { - if (context instanceof NavigationContentPart) { - return new NavigationItemPart(model); - } else if (context instanceof IRootPart) { - return new NavigationContentPart(model); - } else { - return new EmptyPart(); - } - } - }; - - private class LabelProviderListener implements ILabelProviderListener { - public void labelProviderChanged(LabelProviderChangedEvent event) { - update(event.getElements()); - } - } - - private IStructuredContentProvider contentProvider = null; - - private IBaseLabelProvider labelProvider = null; - - private ILabelProviderListener labelProviderListener = null; - - /** - * - */ - public NavigationViewer() { - setPartFactory(DEFAULT_PART_FACTORY); - setRootPart(new GraphicalRootEditPart()); - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new NavigationSelectTool()); - setEditDomain(editDomain); - NavigationAnimationService animationService = new NavigationAnimationService( - this); - installService(NavigationAnimationService.class, animationService); - animationService.setActive(true); - } - - public T getAdapter(Class adapter) { - if (IContentProvider.class.equals(adapter) - || IStructuredContentProvider.class.equals(adapter)) - return adapter.cast(getContentProvider()); - if (IBaseLabelProvider.class.equals(adapter)) - return adapter.cast(getLabelProvider()); - return super.getAdapter(adapter); - } - - public IStructuredContentProvider getContentProvider() { - return contentProvider; - } - - public void setContentProvider(IStructuredContentProvider contentProvider) { - if (contentProvider == null || contentProvider == this.contentProvider) - return; - IStructuredContentProvider oldContentProvider = this.contentProvider; - this.contentProvider = contentProvider; - if (oldContentProvider != null) { - oldContentProvider.dispose(); - } - contentProvider.inputChanged(this, getInput(), getInput()); - refresh(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.GraphicalViewer#internalInputChanged(java.lang.Object, - * java.lang.Object) - */ - @Override - protected void internalInputChanged(Object input, Object oldInput) { - if (getContentProvider() != null) { - getContentProvider().inputChanged(this, oldInput, input); - } - super.internalInputChanged(input, oldInput); - } - - public void update() { - update(null); - } - - public void update(Object[] elements) { - if (elements == null) { - IPart contents = getRootPart().getContents(); - if (contents.getStatus().isActive()) - contents.refresh(); - for (IPart p : contents.getChildren()) { - if (p.getStatus().isActive()) { - ((IGraphicalPart) p).refresh(); - } - } - } else { - for (Object element : elements) { - IPart p = findPart(element); - if (p != null && p.getStatus().isActive()) { - ((IGraphicalPart) p).refresh(); - } - } - } - } - - public IBaseLabelProvider getLabelProvider() { - if (labelProvider == null) { - labelProvider = new LabelProvider(); - } - return labelProvider; - } - - public void setLabelProvider(IBaseLabelProvider labelProvider) { - if (labelProvider == null) - return; - - IBaseLabelProvider oldLabelProvider = this.labelProvider; - if (labelProvider == oldLabelProvider) - return; - - if (oldLabelProvider != null) { - if (labelProviderListener != null) { - oldLabelProvider.removeListener(labelProviderListener); - } - } - this.labelProvider = labelProvider; - if (labelProviderListener == null) - labelProviderListener = new LabelProviderListener(); - labelProvider.addListener(labelProviderListener); - refresh(); - - if (oldLabelProvider != null) { - oldLabelProvider.dispose(); - } - } - - protected void handleDispose(DisposeEvent e) { - if (labelProvider != null) { - if (labelProviderListener != null) - labelProvider.removeListener(labelProviderListener); - labelProvider.dispose(); - labelProvider = null; - } - if (contentProvider != null) { - contentProvider.dispose(); - contentProvider = null; - } - super.handleDispose(e); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.GraphicalViewer#internalCreateControl(org.eclipse.swt. - * widgets .Composite, int) - */ - @Override - protected Control internalCreateControl(Composite parent, int style) { - FigureCanvas canvas = (FigureCanvas) super.internalCreateControl(parent, - style); - canvas.setScrollBarVisibility(FigureCanvas.NEVER); - getViewport().setContentsTracksWidth(true); - getViewport().setContentsTracksHeight(true); - if (Util.isMac()) { - canvas.addListener(SWT.MouseHorizontalWheel, - new NavigationScrollHandler()); - } else { - canvas.addListener(SWT.MouseVerticalWheel, - new NavigationScrollHandler()); - } - return canvas; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.gallery; + +import java.util.List; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.part.GraphicalEditPart; +import org.xmind.gef.part.GraphicalRootEditPart; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IPartFactory; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.tool.SelectTool; + +/** + * @author Frank Shaka + * + */ +public class NavigationViewer extends GraphicalViewer { + + private static class NavigationSelectTool extends SelectTool { + + @Override + protected boolean handleMouseDown(MouseEvent me) { + if (me.leftOrRight) { + if (me.target.hasRole(GEF.ROLE_SELECTABLE)) { + selectSingle(me.target); + return true; + } + return super.handleMouseDown(me); + } else { + return false; + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.tool.SelectTool#select(java.util.List, + * org.xmind.gef.part.IPart) + */ + @Override + protected void select(List toSelect, IPart toFocus) { + if (toSelect.isEmpty()) + return; + super.select(toSelect, toFocus); + } + + } + + private class NavigationScrollHandler implements Listener { + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets + * .Event) + */ + public void handleEvent(Event event) { + int offset = event.count; + offset = (int) (Math.sqrt(Math.abs(offset)) * offset); + ((NavigationContentPart) getRootPart().getContents()) + .addScrollOffset(offset); + } + + } + + public static final int PREF_HEIGHT = 60; + + public static final int BIG_HEIGHT = 70; + + public static final int SMALL_HEIGHT = 50; + + public static final int BIG_ALPHA = 0; + + public static final int SMALL_ALPHA = 40; + + private static class EmptyPart extends GraphicalEditPart { + protected IFigure createFigure() { + return new Figure(); + } + } + + private static IPartFactory DEFAULT_PART_FACTORY = new IPartFactory() { + public IPart createPart(IPart context, Object model) { + if (context instanceof NavigationContentPart) { + return new NavigationItemPart(model); + } else if (context instanceof IRootPart) { + return new NavigationContentPart(model); + } else { + return new EmptyPart(); + } + } + }; + + private class LabelProviderListener implements ILabelProviderListener { + public void labelProviderChanged(LabelProviderChangedEvent event) { + update(event.getElements()); + } + } + + private IStructuredContentProvider contentProvider = null; + + private IBaseLabelProvider labelProvider = null; + + private ILabelProviderListener labelProviderListener = null; + + /** + * + */ + public NavigationViewer() { + setPartFactory(DEFAULT_PART_FACTORY); + setRootPart(new GraphicalRootEditPart()); + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new NavigationSelectTool()); + setEditDomain(editDomain); + NavigationAnimationService animationService = new NavigationAnimationService( + this); + installService(NavigationAnimationService.class, animationService); + animationService.setActive(true); + } + + public T getAdapter(Class adapter) { + if (IContentProvider.class.equals(adapter) + || IStructuredContentProvider.class.equals(adapter)) + return adapter.cast(getContentProvider()); + if (IBaseLabelProvider.class.equals(adapter)) + return adapter.cast(getLabelProvider()); + return super.getAdapter(adapter); + } + + public IStructuredContentProvider getContentProvider() { + return contentProvider; + } + + public void setContentProvider(IStructuredContentProvider contentProvider) { + if (contentProvider == null || contentProvider == this.contentProvider) + return; + IStructuredContentProvider oldContentProvider = this.contentProvider; + this.contentProvider = contentProvider; + if (oldContentProvider != null) { + oldContentProvider.dispose(); + } + contentProvider.inputChanged(this, getInput(), getInput()); + refresh(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.GraphicalViewer#internalInputChanged(java.lang.Object, + * java.lang.Object) + */ + @Override + protected void internalInputChanged(Object input, Object oldInput) { + if (getContentProvider() != null) { + getContentProvider().inputChanged(this, oldInput, input); + } + super.internalInputChanged(input, oldInput); + } + + public void update() { + update(null); + } + + public void update(Object[] elements) { + if (elements == null) { + IPart contents = getRootPart().getContents(); + if (contents.getStatus().isActive()) + contents.refresh(); + for (IPart p : contents.getChildren()) { + if (p.getStatus().isActive()) { + ((IGraphicalPart) p).refresh(); + } + } + } else { + for (Object element : elements) { + IPart p = findPart(element); + if (p != null && p.getStatus().isActive()) { + ((IGraphicalPart) p).refresh(); + } + } + } + } + + public IBaseLabelProvider getLabelProvider() { + if (labelProvider == null) { + labelProvider = new LabelProvider(); + } + return labelProvider; + } + + public void setLabelProvider(IBaseLabelProvider labelProvider) { + if (labelProvider == null) + return; + + IBaseLabelProvider oldLabelProvider = this.labelProvider; + if (labelProvider == oldLabelProvider) + return; + + if (oldLabelProvider != null) { + if (labelProviderListener != null) { + oldLabelProvider.removeListener(labelProviderListener); + } + } + this.labelProvider = labelProvider; + if (labelProviderListener == null) + labelProviderListener = new LabelProviderListener(); + labelProvider.addListener(labelProviderListener); + refresh(); + + if (oldLabelProvider != null) { + oldLabelProvider.dispose(); + } + } + + protected void handleDispose(DisposeEvent e) { + if (labelProvider != null) { + if (labelProviderListener != null) + labelProvider.removeListener(labelProviderListener); + labelProvider.dispose(); + labelProvider = null; + } + if (contentProvider != null) { + contentProvider.dispose(); + contentProvider = null; + } + super.handleDispose(e); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.GraphicalViewer#internalCreateControl(org.eclipse.swt. + * widgets .Composite, int) + */ + @Override + protected Control internalCreateControl(Composite parent, int style) { + FigureCanvas canvas = (FigureCanvas) super.internalCreateControl(parent, + style); + canvas.setScrollBarVisibility(FigureCanvas.NEVER); + getViewport().setContentsTracksWidth(true); + getViewport().setContentsTracksHeight(true); + if (Util.isMac()) { + canvas.addListener(SWT.MouseHorizontalWheel, + new NavigationScrollHandler()); + } else { + canvas.addListener(SWT.MouseVerticalWheel, + new NavigationScrollHandler()); + } + return canvas; + } +} diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/ui/texteditor/FloatingTextEditTool.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/texteditor/FloatingTextEditTool.java index b26440dbd..9028188f4 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/texteditor/FloatingTextEditTool.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/texteditor/FloatingTextEditTool.java @@ -1,513 +1,513 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.texteditor; - -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CommandStackBase; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.command.ICommandStack2; -import org.xmind.gef.command.ICommandStackDelegate; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.EditTool; -import org.xmind.gef.tool.PartTextSelection; -import org.xmind.ui.viewers.SWTUtils; - -public abstract class FloatingTextEditTool extends EditTool { - - private static final boolean DEBUG = false; - - private class TextCommandStackDelegate extends CommandStackBase - implements ICommandStackDelegate { - - public boolean canExecute(Command command) { - return false; - } - - public boolean canRedo() { - return FloatingTextEditTool.this.canRedo(); - } - - public boolean canUndo() { - //return FloatingTextEditTool.this.canUndo(); - return true; - } - - public void clear() { - } - - public void execute(Command command) { - } - - public String getRedoLabel() { - return FloatingTextEditTool.this.getRedoLabel(); - } - - public String getUndoLabel() { - return FloatingTextEditTool.this.getUndoLabel(); - } - - public void redo() { - FloatingTextEditTool.this.redo(); - } - - public void undo() { - FloatingTextEditTool.this.undo(); - } - - public void fireUpdate() { - fireEvent(GEF.CS_UPDATED); - } - - } - - private class EditorListener extends IFloatingTextEditorListener.Stub - implements Listener { - - public void editingCanceled(TextEvent e) { - if (closingFromTool) - return; - closingFromEditor = true; - cancelEditing(); - closingFromEditor = false; - } - - public void editingFinished(TextEvent e) { - if (closingFromTool) - return; - closingFromEditor = true; - finishEditing(); - closingFromEditor = false; - } - - public void textChanged(TextEvent e) { - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (!getStatus().isStatus(GEF.ST_ACTIVE)) - return; - updateCommandActions(); - } - }); - } - - public void handleEvent(Event event) { - if (event.type == SWT.Dispose) { - uninstallCommandStackDelegate(); - } else if (event.type == SWT.FocusOut) { - final Shell oldShell = getTargetViewer().getControl() - .getShell(); - final Display display = event.display; - display.asyncExec(new Runnable() { - - public void run() { - if (!getStatus().isStatus(GEF.ST_ACTIVE) - || oldShell.isDisposed()) - return; - - if (!display.isDisposed()) { - display.asyncExec(new Runnable() { - - public void run() { - if (display.isDisposed() - || oldShell.isDisposed() - || !getStatus() - .isStatus(GEF.ST_ACTIVE)) - return; - - Shell newShell = display.getActiveShell(); - if (newShell != null - && !newShell.isDisposed() - && !isDescendantShell(newShell, - oldShell)) { - finishEditing(); - } - } - }); - } - } - }); - } - } - - private boolean isDescendantShell(Shell newShell, Shell oldShell) { - Composite parent = newShell.getParent(); - if (parent == null || !(parent instanceof Shell)) - return false; - if (parent == oldShell) - return true; - return isDescendantShell((Shell) parent, oldShell); - } - - } - - private class EditorSelectionChangedListener - implements ISelectionChangedListener { - - public void selectionChanged(SelectionChangedEvent event) { - notifySelectionChange(); - } - - } - - private FloatingTextEditor editor = null; - - private boolean closingFromEditor = false; - - private boolean closingFromTool = false; - - private EditorListener editorListener = null; - - private ISelectionChangedListener editorSelectionChangedListener; - - private boolean notifyingSelectionChange = false; - - private TextCommandStackDelegate delegate = null; - - private ICommandStackDelegate oldDelegate = null; - - private boolean focusOnRequest = true; - - public FloatingTextEditTool() { - this(false); - } - - public FloatingTextEditTool(boolean listensToSelectionChange) { - if (listensToSelectionChange) { - editorSelectionChangedListener = new EditorSelectionChangedListener(); - } else { - editorSelectionChangedListener = null; - } - } - - public FloatingTextEditor getEditor() { - return editor; - } - - public ITextSelection getTextSelection() { - ISelection editorSelection = editor == null ? null - : editor.getSelection(); - if (editorSelection instanceof ITextSelection) { - ITextSelection s = (ITextSelection) editorSelection; - PartTextSelection realSelection = new PartTextSelection(getSource(), - (IDocument) editor.getInput(), s.getOffset(), - s.getLength()); - return realSelection; - } - return null; - } - - public void setTextSelection(ITextSelection selection) { - if (notifyingSelectionChange) - return; - - if (selection != null) { - editor.setSelection(selection, true); - } else { - cancelEditing(); - } - } - - protected void notifySelectionChange() { - if (editorSelectionChangedListener == null) - return; - notifyingSelectionChange = true; - getTargetViewer().setSelection(getTextSelection(), false); - notifyingSelectionChange = false; - } - - @Override - protected void handleEditRequest(Request request) { - focusOnRequest = !request.hasParameter(GEF.PARAM_FOCUS) - || request.isParameter(GEF.PARAM_FOCUS); - super.handleEditRequest(request); - if (getDomain().getActiveTool() == this) { - Object text = request.getParameter(GEF.PARAM_TEXT); - if (text instanceof String) { - if (editor != null && !editor.isClosed()) { - editor.replaceText((String) text); - } - } - Object selection = request.getParameter(GEF.PARAM_TEXT_SELECTION); - if (selection instanceof ITextSelection) { - setTextSelection((ITextSelection) selection); - } - if (focusOnRequest && editor != null && !editor.isClosed()) { - editor.setFocus(); - } - } - } - - protected boolean startEditing(IGraphicalEditPart source) { - IDocument document = getTextContents(source); - if (document == null) - return false; - - if (editor == null) { - editor = createEditor(); - } - if (editor == null) - return false; - - hookEditor(editor); - boolean started = openEditor(editor, document); - if (started) { - notifySelectionChange(); - } - return started; - } - - protected void installCommandStackDelegate() { - ICommandStack cs = getDomain().getCommandStack(); - if (cs != null && cs instanceof ICommandStack2) { - delegate = new TextCommandStackDelegate(); - ICommandStack2 cs2 = (ICommandStack2) cs; - oldDelegate = cs2.getDelegate(); - cs2.setDelegate(delegate); - } - } - - protected void uninstallCommandStackDelegate() { - if (delegate != null) { - ICommandStack cs = getDomain().getCommandStack(); - if (cs != null && cs instanceof ICommandStack2) { - ICommandStack2 cs2 = (ICommandStack2) cs; - cs2.setDelegate(oldDelegate); - } - oldDelegate = null; - delegate = null; - } - } - - protected void updateCommandActions() { - if (delegate != null) { - delegate.fireUpdate(); - } - } - - protected boolean openEditor(FloatingTextEditor editor, - IDocument document) { - boolean wasOpen = !editor.isClosed(); - editor.setInput(document); - boolean isOpen = editor.open(false); - if (isOpen) { - if (editor.canDoOperation(ITextOperationTarget.SELECT_ALL)) { - editor.doOperation(ITextOperationTarget.SELECT_ALL); - } - if (!wasOpen) { - hookEditorControl(editor, editor.getTextViewer()); - } - } - return isOpen; - } - - protected void hookEditorControl(FloatingTextEditor editor, - ITextViewer textViewer) { - installCommandStackDelegate(); - textViewer.getTextWidget().addListener(SWT.FocusOut, - getEditorListener()); - textViewer.getTextWidget().addListener(SWT.Dispose, - getEditorListener()); - } - - protected void cancelEditing() { - if (editor != null) { - if (closingFromEditor) { - unhookEditor(editor); - } else if (!editor.isClosed()) { - closingFromTool = true; - closeEditor(editor, false); - closingFromTool = false; - } - editor = null; - } - super.cancelEditing(); - notifySelectionChange(); - } - - protected void finishEditing() { - if (DEBUG) - System.out.println("Finish Editing"); //$NON-NLS-1$ - if (editor != null) { - if (closingFromEditor) { - unhookEditor(editor); - } else if (!editor.isClosed()) { - closingFromTool = true; - if (DEBUG) - System.out.println("Close editor"); //$NON-NLS-1$ - closeEditor(editor, true); - closingFromTool = false; - } - Object input = editor.getInput(); - if (input instanceof IDocument) { - IDocument document = (IDocument) input; - if (DEBUG) - System.out.println("Perform text modification"); //$NON-NLS-1$ - handleTextModified(getSource(), document); - } - editor = null; - } - super.finishEditing(); - notifySelectionChange(); - } - - protected void closeEditor(FloatingTextEditor editor, boolean finish) { - unhookEditor(editor); - editor.close(finish); - } - - protected abstract IDocument getTextContents(IPart source); - - protected abstract void handleTextModified(IPart source, - IDocument document); - - protected FloatingTextEditor createEditor() { - int style = SWT.BORDER | SWT.V_SCROLL - | (isMultilineAllowed() ? SWT.MULTI : SWT.SINGLE); - if (isWrapAllowed()) { - style |= SWT.WRAP; - } else { - style |= SWT.H_SCROLL; - } - FloatingTextEditor editor = new FloatingTextEditor( - getTargetViewer().getCanvas(), style); - return editor; - } - - protected void hookEditor(FloatingTextEditor editor) { - editor.addFloatingTextEditorListener(getEditorListener()); - if (editorSelectionChangedListener != null) - editor.addSelectionChangedListener(editorSelectionChangedListener); - } - - protected void unhookEditor(FloatingTextEditor editor) { - if (editorSelectionChangedListener != null) - editor.removeSelectionChangedListener( - editorSelectionChangedListener); - editor.removeFloatingTextEditorListener(getEditorListener()); - Display.getCurrent().asyncExec(new Runnable() { - - @Override - public void run() { - restoreFocusControl(); - } - }); - } - - private EditorListener getEditorListener() { - if (editorListener == null) - editorListener = new EditorListener(); - return editorListener; - } - - protected boolean isMultilineAllowed() { - return false; - } - - protected boolean isWrapAllowed() { - return false; - } - - protected void selectAll() { - if (editor != null - && editor.canDoOperation(FloatingTextEditor.SELECT_ALL)) { - editor.doOperation(FloatingTextEditor.SELECT_ALL); - } - } - - protected void copy() { - if (editor != null && editor.canDoOperation(FloatingTextEditor.COPY)) { - editor.doOperation(FloatingTextEditor.COPY); - } - } - - protected void cut() { - if (editor != null && editor.canDoOperation(FloatingTextEditor.CUT)) { - editor.doOperation(FloatingTextEditor.CUT); - } - } - - protected void delete() { - if (editor != null - && editor.canDoOperation(FloatingTextEditor.DELETE)) { - editor.doOperation(FloatingTextEditor.DELETE); - } - } - - protected void paste() { - if (editor != null && editor.canDoOperation(FloatingTextEditor.PASTE)) { - editor.doOperation(FloatingTextEditor.PASTE); - } - } - - protected void undo() { - if (editor != null && editor.canDoOperation(FloatingTextEditor.UNDO)) - editor.doOperation(FloatingTextEditor.UNDO); - } - - protected void redo() { - if (editor != null && editor.canDoOperation(FloatingTextEditor.REDO)) - editor.doOperation(FloatingTextEditor.REDO); - } - - public boolean canUndo() { - return editor != null && editor.canDoOperation(FloatingTextEditor.UNDO); - } - - public boolean canRedo() { - return editor != null && editor.canDoOperation(FloatingTextEditor.REDO); - } - - protected abstract String getUndoLabel(); - - protected abstract String getRedoLabel(); - - protected boolean shouldFinish(KeyEvent ke) { - return SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, SWT.CR); - } - - protected boolean shouldCancel(KeyEvent ke) { - return SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, SWT.ESC); - } - - protected void restoreFocusControl() { - IGraphicalViewer viewer = getTargetViewer(); - if (viewer == null) - return; - - Control control = viewer.getControl(); - if (control == null || control.isDisposed()) - return; - - control.setFocus(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.texteditor; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CommandStackBase; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.command.ICommandStack2; +import org.xmind.gef.command.ICommandStackDelegate; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.EditTool; +import org.xmind.gef.tool.PartTextSelection; +import org.xmind.ui.viewers.SWTUtils; + +public abstract class FloatingTextEditTool extends EditTool { + + private static final boolean DEBUG = false; + + private class TextCommandStackDelegate extends CommandStackBase + implements ICommandStackDelegate { + + public boolean canExecute(Command command) { + return false; + } + + public boolean canRedo() { + return FloatingTextEditTool.this.canRedo(); + } + + public boolean canUndo() { + //return FloatingTextEditTool.this.canUndo(); + return true; + } + + public void clear() { + } + + public void execute(Command command) { + } + + public String getRedoLabel() { + return FloatingTextEditTool.this.getRedoLabel(); + } + + public String getUndoLabel() { + return FloatingTextEditTool.this.getUndoLabel(); + } + + public void redo() { + FloatingTextEditTool.this.redo(); + } + + public void undo() { + FloatingTextEditTool.this.undo(); + } + + public void fireUpdate() { + fireEvent(GEF.CS_UPDATED); + } + + } + + private class EditorListener extends IFloatingTextEditorListener.Stub + implements Listener { + + public void editingCanceled(TextEvent e) { + if (closingFromTool) + return; + closingFromEditor = true; + cancelEditing(); + closingFromEditor = false; + } + + public void editingFinished(TextEvent e) { + if (closingFromTool) + return; + closingFromEditor = true; + finishEditing(); + closingFromEditor = false; + } + + public void textChanged(TextEvent e) { + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (!getStatus().isStatus(GEF.ST_ACTIVE)) + return; + updateCommandActions(); + } + }); + } + + public void handleEvent(Event event) { + if (event.type == SWT.Dispose) { + uninstallCommandStackDelegate(); + } else if (event.type == SWT.FocusOut) { + final Shell oldShell = getTargetViewer().getControl() + .getShell(); + final Display display = event.display; + display.asyncExec(new Runnable() { + + public void run() { + if (!getStatus().isStatus(GEF.ST_ACTIVE) + || oldShell.isDisposed()) + return; + + if (!display.isDisposed()) { + display.asyncExec(new Runnable() { + + public void run() { + if (display.isDisposed() + || oldShell.isDisposed() + || !getStatus() + .isStatus(GEF.ST_ACTIVE)) + return; + + Shell newShell = display.getActiveShell(); + if (newShell != null + && !newShell.isDisposed() + && !isDescendantShell(newShell, + oldShell)) { + finishEditing(); + } + } + }); + } + } + }); + } + } + + private boolean isDescendantShell(Shell newShell, Shell oldShell) { + Composite parent = newShell.getParent(); + if (parent == null || !(parent instanceof Shell)) + return false; + if (parent == oldShell) + return true; + return isDescendantShell((Shell) parent, oldShell); + } + + } + + private class EditorSelectionChangedListener + implements ISelectionChangedListener { + + public void selectionChanged(SelectionChangedEvent event) { + notifySelectionChange(); + } + + } + + private FloatingTextEditor editor = null; + + private boolean closingFromEditor = false; + + private boolean closingFromTool = false; + + private EditorListener editorListener = null; + + private ISelectionChangedListener editorSelectionChangedListener; + + private boolean notifyingSelectionChange = false; + + private TextCommandStackDelegate delegate = null; + + private ICommandStackDelegate oldDelegate = null; + + private boolean focusOnRequest = true; + + public FloatingTextEditTool() { + this(false); + } + + public FloatingTextEditTool(boolean listensToSelectionChange) { + if (listensToSelectionChange) { + editorSelectionChangedListener = new EditorSelectionChangedListener(); + } else { + editorSelectionChangedListener = null; + } + } + + public FloatingTextEditor getEditor() { + return editor; + } + + public ITextSelection getTextSelection() { + ISelection editorSelection = editor == null ? null + : editor.getSelection(); + if (editorSelection instanceof ITextSelection) { + ITextSelection s = (ITextSelection) editorSelection; + PartTextSelection realSelection = new PartTextSelection(getSource(), + (IDocument) editor.getInput(), s.getOffset(), + s.getLength()); + return realSelection; + } + return null; + } + + public void setTextSelection(ITextSelection selection) { + if (notifyingSelectionChange) + return; + + if (selection != null) { + editor.setSelection(selection, true); + } else { + cancelEditing(); + } + } + + protected void notifySelectionChange() { + if (editorSelectionChangedListener == null) + return; + notifyingSelectionChange = true; + getTargetViewer().setSelection(getTextSelection(), false); + notifyingSelectionChange = false; + } + + @Override + protected void handleEditRequest(Request request) { + focusOnRequest = !request.hasParameter(GEF.PARAM_FOCUS) + || request.isParameter(GEF.PARAM_FOCUS); + super.handleEditRequest(request); + if (getDomain().getActiveTool() == this) { + Object text = request.getParameter(GEF.PARAM_TEXT); + if (text instanceof String) { + if (editor != null && !editor.isClosed()) { + editor.replaceText((String) text); + } + } + Object selection = request.getParameter(GEF.PARAM_TEXT_SELECTION); + if (selection instanceof ITextSelection) { + setTextSelection((ITextSelection) selection); + } + if (focusOnRequest && editor != null && !editor.isClosed()) { + editor.setFocus(); + } + } + } + + protected boolean startEditing(IGraphicalEditPart source) { + IDocument document = getTextContents(source); + if (document == null) + return false; + + if (editor == null) { + editor = createEditor(); + } + if (editor == null) + return false; + + hookEditor(editor); + boolean started = openEditor(editor, document); + if (started) { + notifySelectionChange(); + } + return started; + } + + protected void installCommandStackDelegate() { + ICommandStack cs = getDomain().getCommandStack(); + if (cs != null && cs instanceof ICommandStack2) { + delegate = new TextCommandStackDelegate(); + ICommandStack2 cs2 = (ICommandStack2) cs; + oldDelegate = cs2.getDelegate(); + cs2.setDelegate(delegate); + } + } + + protected void uninstallCommandStackDelegate() { + if (delegate != null) { + ICommandStack cs = getDomain().getCommandStack(); + if (cs != null && cs instanceof ICommandStack2) { + ICommandStack2 cs2 = (ICommandStack2) cs; + cs2.setDelegate(oldDelegate); + } + oldDelegate = null; + delegate = null; + } + } + + protected void updateCommandActions() { + if (delegate != null) { + delegate.fireUpdate(); + } + } + + protected boolean openEditor(FloatingTextEditor editor, + IDocument document) { + boolean wasOpen = !editor.isClosed(); + editor.setInput(document); + boolean isOpen = editor.open(false); + if (isOpen) { + if (editor.canDoOperation(ITextOperationTarget.SELECT_ALL)) { + editor.doOperation(ITextOperationTarget.SELECT_ALL); + } + if (!wasOpen) { + hookEditorControl(editor, editor.getTextViewer()); + } + } + return isOpen; + } + + protected void hookEditorControl(FloatingTextEditor editor, + ITextViewer textViewer) { + installCommandStackDelegate(); + textViewer.getTextWidget().addListener(SWT.FocusOut, + getEditorListener()); + textViewer.getTextWidget().addListener(SWT.Dispose, + getEditorListener()); + } + + protected void cancelEditing() { + if (editor != null) { + if (closingFromEditor) { + unhookEditor(editor); + } else if (!editor.isClosed()) { + closingFromTool = true; + closeEditor(editor, false); + closingFromTool = false; + } + editor = null; + } + super.cancelEditing(); + notifySelectionChange(); + } + + protected void finishEditing() { + if (DEBUG) + System.out.println("Finish Editing"); //$NON-NLS-1$ + if (editor != null) { + if (closingFromEditor) { + unhookEditor(editor); + } else if (!editor.isClosed()) { + closingFromTool = true; + if (DEBUG) + System.out.println("Close editor"); //$NON-NLS-1$ + closeEditor(editor, true); + closingFromTool = false; + } + Object input = editor.getInput(); + if (input instanceof IDocument) { + IDocument document = (IDocument) input; + if (DEBUG) + System.out.println("Perform text modification"); //$NON-NLS-1$ + handleTextModified(getSource(), document); + } + editor = null; + } + super.finishEditing(); + notifySelectionChange(); + } + + protected void closeEditor(FloatingTextEditor editor, boolean finish) { + unhookEditor(editor); + editor.close(finish); + } + + protected abstract IDocument getTextContents(IPart source); + + protected abstract void handleTextModified(IPart source, + IDocument document); + + protected FloatingTextEditor createEditor() { + int style = SWT.BORDER | SWT.V_SCROLL + | (isMultilineAllowed() ? SWT.MULTI : SWT.SINGLE); + if (isWrapAllowed()) { + style |= SWT.WRAP; + } else { + style |= SWT.H_SCROLL; + } + FloatingTextEditor editor = new FloatingTextEditor( + getTargetViewer().getCanvas(), style); + return editor; + } + + protected void hookEditor(FloatingTextEditor editor) { + editor.addFloatingTextEditorListener(getEditorListener()); + if (editorSelectionChangedListener != null) + editor.addSelectionChangedListener(editorSelectionChangedListener); + } + + protected void unhookEditor(FloatingTextEditor editor) { + if (editorSelectionChangedListener != null) + editor.removeSelectionChangedListener( + editorSelectionChangedListener); + editor.removeFloatingTextEditorListener(getEditorListener()); + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + restoreFocusControl(); + } + }); + } + + private EditorListener getEditorListener() { + if (editorListener == null) + editorListener = new EditorListener(); + return editorListener; + } + + protected boolean isMultilineAllowed() { + return false; + } + + protected boolean isWrapAllowed() { + return false; + } + + protected void selectAll() { + if (editor != null + && editor.canDoOperation(FloatingTextEditor.SELECT_ALL)) { + editor.doOperation(FloatingTextEditor.SELECT_ALL); + } + } + + protected void copy() { + if (editor != null && editor.canDoOperation(FloatingTextEditor.COPY)) { + editor.doOperation(FloatingTextEditor.COPY); + } + } + + protected void cut() { + if (editor != null && editor.canDoOperation(FloatingTextEditor.CUT)) { + editor.doOperation(FloatingTextEditor.CUT); + } + } + + protected void delete() { + if (editor != null + && editor.canDoOperation(FloatingTextEditor.DELETE)) { + editor.doOperation(FloatingTextEditor.DELETE); + } + } + + protected void paste() { + if (editor != null && editor.canDoOperation(FloatingTextEditor.PASTE)) { + editor.doOperation(FloatingTextEditor.PASTE); + } + } + + protected void undo() { + if (editor != null && editor.canDoOperation(FloatingTextEditor.UNDO)) + editor.doOperation(FloatingTextEditor.UNDO); + } + + protected void redo() { + if (editor != null && editor.canDoOperation(FloatingTextEditor.REDO)) + editor.doOperation(FloatingTextEditor.REDO); + } + + public boolean canUndo() { + return editor != null && editor.canDoOperation(FloatingTextEditor.UNDO); + } + + public boolean canRedo() { + return editor != null && editor.canDoOperation(FloatingTextEditor.REDO); + } + + protected abstract String getUndoLabel(); + + protected abstract String getRedoLabel(); + + protected boolean shouldFinish(KeyEvent ke) { + return SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, SWT.CR); + } + + protected boolean shouldCancel(KeyEvent ke) { + return SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, SWT.ESC); + } + + protected void restoreFocusControl() { + IGraphicalViewer viewer = getTargetViewer(); + if (viewer == null) + return; + + Control control = viewer.getControl(); + if (control == null || control.isDisposed()) + return; + + control.setFocus(); + } +} diff --git a/bundles/org.xmind.gef/.gitignore b/bundles/org.xmind.gef/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.gef/.gitignore +++ b/bundles/org.xmind.gef/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.gef/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.gef/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.gef/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.gef/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.gef/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.gef/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.gef/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.gef/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.gef/META-INF/MANIFEST.MF b/bundles/org.xmind.gef/META-INF/MANIFEST.MF index f089ffa3b..1daa8bbea 100644 --- a/bundles/org.xmind.gef/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.gef/META-INF/MANIFEST.MF @@ -1,35 +1,35 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.gef;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %providerName -Eclipse-LazyStart: true -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.draw2d;visibility:=reexport, - org.eclipse.jface;visibility:=reexport, - org.eclipse.jface.text;visibility:=reexport, - com.ibm.icu, - org.xmind.neuquant -Export-Package: org.xmind.gef, - org.xmind.gef.acc, - org.xmind.gef.command, - org.xmind.gef.dnd, - org.xmind.gef.draw2d, - org.xmind.gef.draw2d.decoration, - org.xmind.gef.draw2d.geometry, - org.xmind.gef.draw2d.graphics, - org.xmind.gef.event, - org.xmind.gef.graphicalpolicy, - org.xmind.gef.image, - org.xmind.gef.internal.image, - org.xmind.gef.part, - org.xmind.gef.policy, - org.xmind.gef.service, - org.xmind.gef.status, - org.xmind.gef.tool, - org.xmind.gef.tree, - org.xmind.gef.util -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.gef;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %providerName +Eclipse-LazyStart: true +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.draw2d;visibility:=reexport, + org.eclipse.jface;visibility:=reexport, + org.eclipse.jface.text;visibility:=reexport, + com.ibm.icu, + org.xmind.neuquant +Export-Package: org.xmind.gef, + org.xmind.gef.acc, + org.xmind.gef.command, + org.xmind.gef.dnd, + org.xmind.gef.draw2d, + org.xmind.gef.draw2d.decoration, + org.xmind.gef.draw2d.geometry, + org.xmind.gef.draw2d.graphics, + org.xmind.gef.event, + org.xmind.gef.graphicalpolicy, + org.xmind.gef.image, + org.xmind.gef.internal.image, + org.xmind.gef.part, + org.xmind.gef.policy, + org.xmind.gef.service, + org.xmind.gef.status, + org.xmind.gef.tool, + org.xmind.gef.tree, + org.xmind.gef.util +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin diff --git a/bundles/org.xmind.gef/about.html b/bundles/org.xmind.gef/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.gef/about.html +++ b/bundles/org.xmind.gef/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

License

- -

Nov 6, 2008

- -

-XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

- - - + + + + +License + + +

License

+ +

Nov 6, 2008

+ +

+XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

+ + + diff --git a/bundles/org.xmind.gef/plugin.properties b/bundles/org.xmind.gef/plugin.properties index 735ab5068..2ccc0bf44 100644 --- a/bundles/org.xmind.gef/plugin.properties +++ b/bundles/org.xmind.gef/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.gef -providerName = XMind Ltd. +#Properties file for org.xmind.gef +providerName = XMind Ltd. pluginName = XMind GEF \ No newline at end of file diff --git a/bundles/org.xmind.gef/pom.xml b/bundles/org.xmind.gef/pom.xml index 2601c11c1..efd2b6bb2 100644 --- a/bundles/org.xmind.gef/pom.xml +++ b/bundles/org.xmind.gef/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.gef - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.gef + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java b/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java index 882b55c1c..3ddc80b5d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java @@ -1,1105 +1,1105 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Widget; -import org.xmind.gef.acc.AccessibleRegistry; -import org.xmind.gef.acc.IAccessible; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IPartFactory; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.part.PartRegistry; -import org.xmind.gef.service.IViewerService; -import org.xmind.gef.service.IViewerService2; -import org.xmind.gef.util.EventListenerSupport; -import org.xmind.gef.util.IEventDispatcher; -import org.xmind.gef.util.Properties; - -/** - * @author Brian Sun - */ -public abstract class AbstractViewer extends Viewer implements IViewer { - - private static final List EMPTY_PART_SELECTION = Collections - .emptyList(); - - private static final String PRE_SELECTION_CHANGED_KEY = "preSelectionChanged"; //$NON-NLS-1$ - - private static final String POST_SELECTION_CHANGED_KEY = "postSelectionChanged"; //$NON-NLS-1$ - - private static final String FOCUSED_PART_CHANGED_KEY = "focusedPartChanged"; //$NON-NLS-1$ - - protected class SelectionSupport implements ISelectionSupport { - - private ArrayList partSelection = null; - - private ITextSelection textSelection = null; - - public List getPartSelection() { - return partSelection == null ? EMPTY_PART_SELECTION : partSelection; - } - - protected boolean trimValidParts() { - if (partSelection == null || partSelection.isEmpty()) - return false; - boolean changed = true; - Iterator it = partSelection.iterator(); - while (it.hasNext()) { - IPart p = it.next(); - if (!isPartSelected(p)) { - changed = true; - it.remove(); - } - } - return changed; - } - - protected boolean isPartSelected(IPart p) { - return p != null && p.getStatus().isActive() - && p.hasRole(GEF.ROLE_SELECTABLE) - && p.getStatus().isSelected(); - } - - public void appendSelection(Object element) { - boolean changed = trimValidParts(); - changed |= internalAppendSelection(findSelectablePart(element)); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - public void appendSelection(List elements) { - boolean changed = trimValidParts(); - changed |= internalAppendSelection(elements); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected boolean internalAppendSelection(List elements) { - boolean changed = false; - for (Object element : elements.toArray()) { - changed |= internalAppendSelection(findSelectablePart(element)); - } - return changed; - } - - protected boolean internalAppendSelection(IPart p) { - if (p == null) - return false; - if (partSelection != null && partSelection.contains(p)) - return false; - - if (partSelection == null) { - partSelection = new ArrayList(); - } else if (partSelection.size() >= 1) { - int selectionConstraint = getSelectionConstraint(); - if ((selectionConstraint & GEF.SEL_MULTI) == 0) - return false; - } - boolean appended = partSelection.add(p); - if (appended) { - setSelected(p); - } - return appended; - } - - protected void setSelected(IPart p) { - p.getStatus().select(); - } - - public void deselect(Object element) { - boolean changed = trimValidParts(); - changed |= internalDeselect(findSelectablePart(element), false); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected boolean internalDeselect(IPart p, boolean force) { - if (p == null) - return false; - if (partSelection == null || !partSelection.contains(p)) - return false; - - if (!force) { - if (partSelection.size() <= 1) { - int selectionConstraint = getSelectionConstraint(); - if ((selectionConstraint & GEF.SEL_EMPTY) == 0) { - return false; - } - } - } - boolean deselected = partSelection.remove(p); - if (deselected) { - setDeselected(p); - } - return deselected; - } - - protected void setDeselected(IPart p) { - p.getStatus().deSelect(); - } - - public void deselectAll(List elements) { - boolean changed = trimValidParts(); - changed |= internalDeselectAll(elements, true, false); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected boolean internalDeselectAll(List elements, - boolean toCheckSelectable, boolean force) { - boolean changed = false; - for (Object element : elements.toArray()) { - IPart part = findPart(element); - if (toCheckSelectable) { - part = findSelectablePart(element); - } - changed |= internalDeselect(part, force); - } - return changed; - } - - public void deselectAll() { - boolean changed = trimValidParts(); - changed |= internalDeselectAll(false); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected boolean internalDeselectAll(boolean force) { - if (partSelection == null || partSelection.isEmpty()) - return false; - return internalDeselectAll(partSelection, false, force); - } - - public ISelection getModelSelection() { - if (textSelection != null) - return textSelection; - if (partSelection == null) - return StructuredSelection.EMPTY; - if (usePartsInSelection()) { - return new StructuredSelection(partSelection); - } - return new StructuredSelection(getModels(partSelection)); - } - - protected List getModels(List parts) { - ArrayList list = new ArrayList(parts.size()); - for (IPart p : parts) { - Object model = getModel(p); - if (model != null && !list.contains(model)) - list.add(model); - } - return list; - } - - protected Object getModel(IPart p) { - if (p == null) - return null; - return p.getModel(); - } - - protected boolean usePartsInSelection() { - return false; - } - - public void selectAll(List elements) { - boolean changed = trimValidParts(); - changed |= internalSelectAll(elements); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected boolean internalSelectAll(List elements) { - boolean changed = internalDeselectAll(!elements.isEmpty()); - changed |= internalAppendSelection(elements); - return changed; - } - - public void selectAll() { - boolean changed = trimValidParts(); - IRootPart rootPart = getRootPart(); - if (rootPart != null) { - List toSelect = collectAllSelectableParts(rootPart, - new ArrayList()); - changed |= internalSelectAll(toSelect); - } - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - protected List collectAllSelectableParts(IPart parent, - List toReturn) { - if (parent != null) { - for (IPart p : parent.getChildren()) { - if (isSelectable(p)) { - toReturn.add(p); - collectAllSelectableParts(p, toReturn); - } - } - } - return toReturn; - } - - public void selectSingle(Object element) { - boolean changed = trimValidParts(); - changed |= internalDeselectAll(true); - changed |= internalAppendSelection(findSelectablePart(element)); - if (changed) { - partSelectionChanged(getPartSelection(), true); - notifyViewerSelectionChanged(); - } - } - - public void setSelection(ISelection selection, boolean reveal) { - boolean changed = trimValidParts(); - if (selection instanceof ITextSelection) { - ITextSelection newTextSelection = (ITextSelection) selection; - changed |= internalSetTextSelection(newTextSelection); - if (changed) { - textSelectionChanged(newTextSelection, reveal); - } - } else if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - List toSelect = collectAllSelectableParts(ss.toArray(), - new ArrayList(), reveal); - changed |= internalSelectAll(toSelect); - if (changed) { - partSelectionChanged(getPartSelection(), reveal); - } - } - if (changed) { - notifyViewerSelectionChanged(); - } - } - - protected List collectAllSelectableParts(Object[] elements, - List toReturn, boolean reveal) { - for (Object element : elements) { - IPart p = findSelectablePart(element); - if (p != null && !toReturn.contains(p)) { - toReturn.add(p); - } - } - return toReturn; - } - - protected void partSelectionChanged(List parts, - boolean reveal) { - if (reveal) { - reveal(parts.toArray()); - } - } - - protected boolean internalSetTextSelection( - ITextSelection newTextSelection) { - if (newTextSelection == this.textSelection - || (newTextSelection != null - && newTextSelection.equals(this.textSelection))) - return false; - this.textSelection = newTextSelection; - return true; - } - - protected void textSelectionChanged(ITextSelection newTextSelection, - boolean reveal) { - // subclass may implement - } - - public IPart findSelectablePart(Object element) { - IPart p = findPart(element); - if (p == null || !isSelectable(p)) - return null; - return p; - } - - public boolean isSelectable(IPart p) { - return p != null && p.getStatus().isActive() - && p.hasRole(GEF.ROLE_SELECTABLE); - } - - protected void notifyViewerSelectionChanged() { - fireSelectionChanged(new SelectionChangedEvent(AbstractViewer.this, - getModelSelection())); - getControl().getAccessible().selectionChanged(); - firePostSelectionChanged(); - } - - public void refresh() { - if (textSelection != null) { - textSelectionChanged(textSelection, true); - return; - } - - if (partSelection != null) { - refreshPartSelection(getRootPart(), partSelection); - } - } - - protected void refreshPartSelection(IPart parent, - List selectedParts) { - if (parent == null) - return; - for (IPart p : parent.getChildren()) { - if (selectedParts.contains(p)) { - setSelected(p); - } else { - setDeselected(p); - } - refreshPartSelection(p, selectedParts); - } - } - - protected int getSelectionConstraint() { - Object value = getProperties().get(GEF.SelectionConstraint); - if (value instanceof Integer) - return ((Integer) value).intValue(); - return GEF.SEL_DEFAULT; - } - - } - - private Control control = null; - - private IRootPart rootPart = null; - - private IPartFactory partFactory = null; - - private PartRegistry partRegistry = null; - - private EditDomain domain = null; - - private Object input = null; - - private List filters = null; - - private ViewerSorter sorter = null; - - private ViewerComparator comparator = null; - - private ISelectionSupport selectionSupport = null; - - private Properties properties = null; - - private IDndSupport dndSupport = null; - - private AccessibleRegistry accRegistry = null; - - private IPart preSelected = null; - - private IPart focused = null; - - private EventListenerSupport listenerSupport = new EventListenerSupport(); - - private Map, IViewerService> serviceRegistry = null; - - private IPartSearchCondition partSearchCondition = null; - - private boolean postSelectionChangedEventScheduled = false; - - protected AbstractViewer() { - } - - @SuppressWarnings("unchecked") - public T getAdapter(Class adapter) { - if (Control.class.equals(adapter) || Widget.class.equals(adapter)) - return adapter.cast(getControl()); - if (IRootPart.class.equals(adapter)) - return adapter.cast(getRootPart()); - if (IPartFactory.class.equals(adapter)) - return adapter.cast(getPartFactory()); - if (PartRegistry.class.equals(adapter)) - return adapter.cast(getPartRegistry()); - if (EditDomain.class.equals(adapter)) - return adapter.cast(getEditDomain()); - if (ISelectionSupport.class.equals(adapter)) - return adapter.cast(getSelectionSupport()); - if (IDndSupport.class.equals(adapter)) - return adapter.cast(getDndSupport()); - if (Properties.class.equals(adapter)) - return adapter.cast(getProperties()); - return null; - } - - public Control createControl(Composite parent) { - return createControl(parent, SWT.NONE); - } - - public Control createControl(Composite parent, int style) { - control = internalCreateControl(parent, style); - Assert.isNotNull(control); - hookControl(control); - return control; - } - - protected abstract Control internalCreateControl(Composite parent, - int style); - - protected void hookControl(Control control) { - control.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - handleDispose(e); - } - }); - if (serviceRegistry != null) { - for (IViewerService service : serviceRegistry.values()) { - service.setControl(control); - } - } - IRootPart rootPart = getRootPart(); - if (rootPart != null) { - rootPart.getStatus().activate(); - } - } - - public Control getControl() { - return control; - } - - public IRootPart getRootPart() { - return rootPart; - } - - public void setRootPart(IRootPart rootPart) { - Assert.isNotNull(rootPart); - IRootPart oldRootPart = this.rootPart; - if (oldRootPart != null) { - oldRootPart.getStatus().deactivate(); - oldRootPart.setViewer(null); - } - this.rootPart = rootPart; - rootPart.setViewer(this); - if (getControl() != null && !getControl().isDisposed()) { - rootPart.getStatus().activate(); - } - //inputChanged(getInput(), getInput()); - } - - public IPartFactory getPartFactory() { - return partFactory; - } - - public void setPartFactory(IPartFactory partFactory) { - if (partFactory == this.partFactory) - return; - Assert.isNotNull(partFactory); - this.partFactory = partFactory; - inputChanged(getInput(), getInput()); - } - - public EditDomain getEditDomain() { - return domain; - } - - public void setEditDomain(EditDomain editDomain) { - this.domain = editDomain; - } - - public Object getInput() { - return input; - } - - public void setInput(Object input) { - Object oldInput = this.input; - this.input = input; - inputChanged(input, oldInput); - } - - protected void inputChanged(Object input, Object oldInput) { - Map preservedDataList = new HashMap(); - List activeServices = getActiveServices(); - if (activeServices != null) { - for (IViewerService service : activeServices) { - if (service instanceof IViewerService2) { - preservedDataList.put(service, - ((IViewerService2) service).preserveData()); - } - service.setActive(false); - } - } - super.inputChanged(input, oldInput); - contentsChanged(input, oldInput); - if (serviceRegistry != null) { - for (IViewerService service : serviceRegistry.values()) { - service.inputChanged(oldInput, input); - } - } - if (activeServices != null) { - for (IViewerService service : activeServices) { - service.setActive(true); - if (service instanceof IViewerService2) { - ((IViewerService2) service) - .restoreData(preservedDataList.get(service)); - } - } - } - fireInputChanged(input, oldInput); - } - - protected void contentsChanged(Object input, Object oldInput) { - IRootPart rootPart = getRootPart(); - if (rootPart != null) { - rootPart.setModel(input); - rootPart.setContents(createContents(rootPart, input)); - } - } - - protected IPart createContents(IRootPart root, Object input) { - if (input == null || getPartFactory() == null) - return null; - return getPartFactory().createPart(root, input); - } - - public boolean setFocus() { - if (getControl() == null || getControl().isDisposed()) - return false; - return getControl().setFocus(); - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.IViewer#setCursor(org.eclipse.swt.graphics.Cursor) - */ - public void setCursor(Cursor cursor) { - if (getControl() == null || getControl().isDisposed()) - return; - getControl().setCursor(cursor); - } - - protected void handleDispose(DisposeEvent e) { - if (serviceRegistry != null) { - for (IViewerService service : serviceRegistry.values()) { - service.dispose(); - } - serviceRegistry.clear(); - serviceRegistry = null; - } - IRootPart rootPart = getRootPart(); - if (rootPart != null) { - rootPart.getStatus().deactivate(); - } - } - - public void addFilter(ViewerFilter filter) { - if (filter == null) - return; - if (filters != null && filters.contains(filter)) - return; - if (filters == null) - filters = new ArrayList(); - filters.add(filter); - refresh(); - } - - public ViewerFilter[] getFilters() { - return filters == null ? new ViewerFilter[0] - : filters.toArray(new ViewerFilter[filters.size()]); - } - - public ViewerSorter getSorter() { - return sorter; - } - - public ViewerComparator getComparator() { - return comparator; - } - - public void removeFilter(ViewerFilter filter) { - if (filter == null || filters == null || filters.isEmpty()) - return; - filters.remove(filter); - refresh(); - } - - public void setFilters(ViewerFilter[] filters) { - if (isFiltersEqual(filters, getFilters())) - return; - if (filters == null || filters.length == 0) - this.filters = null; - else - this.filters = new ArrayList(Arrays.asList(filters)); - refresh(); - } - - protected boolean isFiltersEqual(ViewerFilter[] fs1, ViewerFilter[] fs2) { - if (fs1 == null) - return fs2 == null || fs2.length == 0; - if (fs2 == null) - return fs1.length == 0; - return Arrays.equals(fs1, fs2); - } - - public void setSorter(ViewerSorter sorter) { - if (sorter == this.sorter - || (sorter != null && sorter.equals(this.sorter))) - return; - this.sorter = sorter; - refresh(); - } - - public void setComparator(ViewerComparator comparator) { - if (comparator == this.comparator - || (comparator != null && comparator.equals(this.comparator))) - return; - this.comparator = comparator; - refresh(); - } - - public ISelectionSupport getSelectionSupport() { - if (selectionSupport == null) - selectionSupport = createSelectionSupport(); - return selectionSupport; - } - - protected ISelectionSupport createSelectionSupport() { - return new SelectionSupport(); - } - - public ISelection getSelection() { - return getSelectionSupport().getModelSelection(); - } - - public void setSelection(ISelection selection, boolean reveal) { - getSelectionSupport().setSelection(selection, reveal); - } - - public void reveal(Object[] elements) { - if (elements == null || elements.length == 0) - return; - - ISelectionSupport sd = getSelectionSupport(); - if (sd != null) { - List parts = new ArrayList(); - for (Object element : elements) { - IPart p = sd.findSelectablePart(element); - if (p != null && !parts.contains(p)) - parts.add(p); - } - if (!parts.isEmpty()) { - revealParts(parts); - } - } - } - - protected void revealParts(List parts) { - } - - /** - * @see org.xmind.gef.IViewer#refresh() - */ - public void refresh() { - IRootPart rootPart = getRootPart(); - if (rootPart != null && rootPart.getStatus().isActive()) - treeRefresh(rootPart); - } - - protected void treeRefresh(IPart parent) { - for (IPart child : parent.getChildren()) { - child.refresh(); - treeRefresh(child); - } - } - - public void updateToolTip() { - } - - /** - * @return the partRegistry - */ - public PartRegistry getPartRegistry() { - if (partRegistry == null) - partRegistry = new PartRegistry(); - return partRegistry; - } - - public IPart findPart(Object element) { - if (element instanceof IPart) - return (IPart) element; - if (partRegistry == null) - return null; - return partRegistry.getPartByModel(element); - } - - public IPart findPart(int x, int y) { - return null; - } - - /* - * (non-Javadoc) - * @seeorg.xmind.gef.IViewer#setPartSearchCondition(org.xmind.gef.IViewer. - * IPartSearchCondition) - */ - public void setPartSearchCondition(IPartSearchCondition condition) { - this.partSearchCondition = condition; - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.IViewer#getPartSearchCondition() - */ - public IPartSearchCondition getPartSearchCondition() { - return this.partSearchCondition; - } - - public void setPartRegistry(PartRegistry partRegistry) { - this.partRegistry = partRegistry; - } - - public AccessibleRegistry getAccessibleRegistry() { - if (accRegistry == null) - accRegistry = new AccessibleRegistry(); - return accRegistry; - } - - protected void setAccessibleRegistry(AccessibleRegistry accRegistry) { - this.accRegistry = accRegistry; - } - -// public IModelContentProvider getContentProvider() { -// return modelContentProvider; -// } -// -// public void setContentProvider(IModelContentProvider modelContentProvider) { -// Assert.isNotNull(modelContentProvider); -// IModelContentProvider oldContentProvider = this.modelContentProvider; -// this.modelContentProvider = modelContentProvider; -// if (oldContentProvider != null) { -// oldContentProvider.inputChanged(this, getInput(), null); -// oldContentProvider.dispose(); -// } -// modelContentProvider.inputChanged(this, null, getInput()); -// inputChanged(getInput(), getInput()); -// } - - public Properties getProperties() { - if (properties == null) - properties = new Properties(this); - return properties; - } - - public void setProperties(Properties properties) { - if (this.properties != null) { - this.properties.clear(); - } - if (properties != null) { - getProperties().putAll(properties); - } - } - - public IDndSupport getDndSupport() { - return dndSupport; - } - - public void setDndSupport(IDndSupport dndSupport) { - this.dndSupport = dndSupport; - } - - /** - * @return the listenerSupport - */ - protected EventListenerSupport getListenerSupport() { - return listenerSupport; - } - - public void addPreSelectionChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().addListener(PRE_SELECTION_CHANGED_KEY, listener); - } - - public void removePreSelectionChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().removeListener(PRE_SELECTION_CHANGED_KEY, - listener); - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.viewers.IPostSelectionProvider# - * addPostSelectionChangedListener - * (org.eclipse.jface.viewers.ISelectionChangedListener) - */ - public void addPostSelectionChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().addListener(POST_SELECTION_CHANGED_KEY, listener); - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.viewers.IPostSelectionProvider# - * removePostSelectionChangedListener - * (org.eclipse.jface.viewers.ISelectionChangedListener) - */ - public void removePostSelectionChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().removeListener(POST_SELECTION_CHANGED_KEY, - listener); - } - - protected void firePreSelectionChanged() { - ISelection selection = createPreSelection(); - final SelectionChangedEvent event = new SelectionChangedEvent(this, - selection); - getListenerSupport().fireEvent(PRE_SELECTION_CHANGED_KEY, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((ISelectionChangedListener) listener) - .selectionChanged(event); - } - }); - } - - protected void firePostSelectionChanged() { - if (getControl() == null || getControl().isDisposed()) - return; - - if (postSelectionChangedEventScheduled) - return; - postSelectionChangedEventScheduled = true; - getControl().getDisplay().asyncExec(new Runnable() { - public void run() { - if (getControl() == null || getControl().isDisposed()) - return; - - ISelection selection = getSelection(); - final SelectionChangedEvent event = new SelectionChangedEvent( - AbstractViewer.this, selection); - getListenerSupport().fireEvent(POST_SELECTION_CHANGED_KEY, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((ISelectionChangedListener) listener) - .selectionChanged(event); - } - }); - postSelectionChangedEventScheduled = false; - } - }); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.IViewer#addFocusedChangedListener(org.eclipse.jface.viewers - * .ISelectionChangedListener) - */ - public void addFocusedPartChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().addListener(FOCUSED_PART_CHANGED_KEY, listener); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.IViewer#removeFocusedChangedListener(org.eclipse.jface. - * viewers.ISelectionChangedListener) - */ - public void removeFocusedPartChangedListener( - ISelectionChangedListener listener) { - getListenerSupport().removeListener(FOCUSED_PART_CHANGED_KEY, listener); - } - - protected void fireFocusedPartChanged() { - IPart focusedPart = getFocusedPart(); - ISelection selection; - if (focusedPart == null) { - selection = StructuredSelection.EMPTY; - } else { - selection = new StructuredSelection(focusedPart); - } - final SelectionChangedEvent event = new SelectionChangedEvent(this, - selection); - getListenerSupport().fireEvent(FOCUSED_PART_CHANGED_KEY, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((ISelectionChangedListener) listener) - .selectionChanged(event); - } - }); - } - - public void addInputChangedListener(IInputChangedListener listener) { - getListenerSupport().addListener(IInputChangedListener.class, listener); - } - - public void removeInputChangedListener(IInputChangedListener listener) { - getListenerSupport().removeListener(IInputChangedListener.class, - listener); - } - - protected void fireInputChanged(final Object newInput, - final Object oldInput) { - getListenerSupport().fireEvent(IInputChangedListener.class, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((IInputChangedListener) listener).inputChanged( - AbstractViewer.this, newInput, oldInput); - } - }); - } - - private ISelection createPreSelection() { - return getPreselected() == null ? StructuredSelection.EMPTY - : new StructuredSelection(getPreselected()); - } - - public Object getPreselected() { - return getPartRegistry().getModelByPart(preSelected); - } - - public IPart getPreselectedPart() { - return preSelected; - } - - public void setPreselected(Object element) { - IPart oldPreselected = this.preSelected; - IPart newPreselected = getSelectionSupport() - .findSelectablePart(element); - if (newPreselected == oldPreselected) - return; - - this.preSelected = newPreselected; - if (oldPreselected != null) { - oldPreselected.getStatus().dePreSelect(); - } - if (newPreselected != null) { - newPreselected.getStatus().preSelect(); - } - firePreSelectionChanged(); - } - - public Object getFocused() { - return focused; - } - - public IPart getFocusedPart() { - return getSelectionSupport().findSelectablePart(getFocused()); - } - - public void setFocused(Object element) { - IPart oldFocused = this.focused; - IPart newFocused = getSelectionSupport().findSelectablePart(element); - if (newFocused == oldFocused) - return; - - this.focused = newFocused; - if (oldFocused != null) { - oldFocused.getStatus().lostFocus(); - } - if (newFocused != null) { - newFocused.getStatus().setFocus(); - } - - Control c = getControl(); - if (c != null && !c.isDisposed()) { - IAccessible acc; - if (this.focused != null) { - this.focused.getStatus().setFocus(); - acc = (IAccessible) this.focused.getAdapter(IAccessible.class); - } else { - acc = null; - } - if (acc != null) { - c.getAccessible().setFocus(acc.getAccessibleId()); - } else { - c.getAccessible().setFocus(ACC.CHILDID_SELF); - } - } - fireFocusedPartChanged(); - } - - public IViewerService getService( - Class serviceType) { - if (serviceType == null || serviceRegistry == null) - return null; - return serviceRegistry.get(serviceType); - } - - public boolean hasService(Class serviceType) { - return serviceType != null && serviceRegistry != null - && serviceRegistry.containsKey(serviceType); - } - - public void installService(Class type, - IViewerService service) { - if (type == null || service == null) - return; - if (serviceRegistry == null) - serviceRegistry = new HashMap, IViewerService>(); - serviceRegistry.put(type, service); - if (getControl() != null && !getControl().isDisposed()) { - service.setControl(getControl()); - } - } - - public void uninstallService(Class type) { - if (type == null || serviceRegistry == null) - return; - IViewerService service = serviceRegistry.remove(type); - if (service != null) { - service.dispose(); - } - } - - private List getActiveServices() { - if (serviceRegistry != null) { - ArrayList list = new ArrayList(); - for (IViewerService service : serviceRegistry.values()) { - if (service.isActive()) - list.add(service); - } - return list; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Widget; +import org.xmind.gef.acc.AccessibleRegistry; +import org.xmind.gef.acc.IAccessible; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IPartFactory; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.part.PartRegistry; +import org.xmind.gef.service.IViewerService; +import org.xmind.gef.service.IViewerService2; +import org.xmind.gef.util.EventListenerSupport; +import org.xmind.gef.util.IEventDispatcher; +import org.xmind.gef.util.Properties; + +/** + * @author Brian Sun + */ +public abstract class AbstractViewer extends Viewer implements IViewer { + + private static final List EMPTY_PART_SELECTION = Collections + .emptyList(); + + private static final String PRE_SELECTION_CHANGED_KEY = "preSelectionChanged"; //$NON-NLS-1$ + + private static final String POST_SELECTION_CHANGED_KEY = "postSelectionChanged"; //$NON-NLS-1$ + + private static final String FOCUSED_PART_CHANGED_KEY = "focusedPartChanged"; //$NON-NLS-1$ + + protected class SelectionSupport implements ISelectionSupport { + + private ArrayList partSelection = null; + + private ITextSelection textSelection = null; + + public List getPartSelection() { + return partSelection == null ? EMPTY_PART_SELECTION : partSelection; + } + + protected boolean trimValidParts() { + if (partSelection == null || partSelection.isEmpty()) + return false; + boolean changed = true; + Iterator it = partSelection.iterator(); + while (it.hasNext()) { + IPart p = it.next(); + if (!isPartSelected(p)) { + changed = true; + it.remove(); + } + } + return changed; + } + + protected boolean isPartSelected(IPart p) { + return p != null && p.getStatus().isActive() + && p.hasRole(GEF.ROLE_SELECTABLE) + && p.getStatus().isSelected(); + } + + public void appendSelection(Object element) { + boolean changed = trimValidParts(); + changed |= internalAppendSelection(findSelectablePart(element)); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + public void appendSelection(List elements) { + boolean changed = trimValidParts(); + changed |= internalAppendSelection(elements); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected boolean internalAppendSelection(List elements) { + boolean changed = false; + for (Object element : elements.toArray()) { + changed |= internalAppendSelection(findSelectablePart(element)); + } + return changed; + } + + protected boolean internalAppendSelection(IPart p) { + if (p == null) + return false; + if (partSelection != null && partSelection.contains(p)) + return false; + + if (partSelection == null) { + partSelection = new ArrayList(); + } else if (partSelection.size() >= 1) { + int selectionConstraint = getSelectionConstraint(); + if ((selectionConstraint & GEF.SEL_MULTI) == 0) + return false; + } + boolean appended = partSelection.add(p); + if (appended) { + setSelected(p); + } + return appended; + } + + protected void setSelected(IPart p) { + p.getStatus().select(); + } + + public void deselect(Object element) { + boolean changed = trimValidParts(); + changed |= internalDeselect(findSelectablePart(element), false); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected boolean internalDeselect(IPart p, boolean force) { + if (p == null) + return false; + if (partSelection == null || !partSelection.contains(p)) + return false; + + if (!force) { + if (partSelection.size() <= 1) { + int selectionConstraint = getSelectionConstraint(); + if ((selectionConstraint & GEF.SEL_EMPTY) == 0) { + return false; + } + } + } + boolean deselected = partSelection.remove(p); + if (deselected) { + setDeselected(p); + } + return deselected; + } + + protected void setDeselected(IPart p) { + p.getStatus().deSelect(); + } + + public void deselectAll(List elements) { + boolean changed = trimValidParts(); + changed |= internalDeselectAll(elements, true, false); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected boolean internalDeselectAll(List elements, + boolean toCheckSelectable, boolean force) { + boolean changed = false; + for (Object element : elements.toArray()) { + IPart part = findPart(element); + if (toCheckSelectable) { + part = findSelectablePart(element); + } + changed |= internalDeselect(part, force); + } + return changed; + } + + public void deselectAll() { + boolean changed = trimValidParts(); + changed |= internalDeselectAll(false); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected boolean internalDeselectAll(boolean force) { + if (partSelection == null || partSelection.isEmpty()) + return false; + return internalDeselectAll(partSelection, false, force); + } + + public ISelection getModelSelection() { + if (textSelection != null) + return textSelection; + if (partSelection == null) + return StructuredSelection.EMPTY; + if (usePartsInSelection()) { + return new StructuredSelection(partSelection); + } + return new StructuredSelection(getModels(partSelection)); + } + + protected List getModels(List parts) { + ArrayList list = new ArrayList(parts.size()); + for (IPart p : parts) { + Object model = getModel(p); + if (model != null && !list.contains(model)) + list.add(model); + } + return list; + } + + protected Object getModel(IPart p) { + if (p == null) + return null; + return p.getModel(); + } + + protected boolean usePartsInSelection() { + return false; + } + + public void selectAll(List elements) { + boolean changed = trimValidParts(); + changed |= internalSelectAll(elements); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected boolean internalSelectAll(List elements) { + boolean changed = internalDeselectAll(!elements.isEmpty()); + changed |= internalAppendSelection(elements); + return changed; + } + + public void selectAll() { + boolean changed = trimValidParts(); + IRootPart rootPart = getRootPart(); + if (rootPart != null) { + List toSelect = collectAllSelectableParts(rootPart, + new ArrayList()); + changed |= internalSelectAll(toSelect); + } + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + protected List collectAllSelectableParts(IPart parent, + List toReturn) { + if (parent != null) { + for (IPart p : parent.getChildren()) { + if (isSelectable(p)) { + toReturn.add(p); + collectAllSelectableParts(p, toReturn); + } + } + } + return toReturn; + } + + public void selectSingle(Object element) { + boolean changed = trimValidParts(); + changed |= internalDeselectAll(true); + changed |= internalAppendSelection(findSelectablePart(element)); + if (changed) { + partSelectionChanged(getPartSelection(), true); + notifyViewerSelectionChanged(); + } + } + + public void setSelection(ISelection selection, boolean reveal) { + boolean changed = trimValidParts(); + if (selection instanceof ITextSelection) { + ITextSelection newTextSelection = (ITextSelection) selection; + changed |= internalSetTextSelection(newTextSelection); + if (changed) { + textSelectionChanged(newTextSelection, reveal); + } + } else if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + List toSelect = collectAllSelectableParts(ss.toArray(), + new ArrayList(), reveal); + changed |= internalSelectAll(toSelect); + if (changed) { + partSelectionChanged(getPartSelection(), reveal); + } + } + if (changed) { + notifyViewerSelectionChanged(); + } + } + + protected List collectAllSelectableParts(Object[] elements, + List toReturn, boolean reveal) { + for (Object element : elements) { + IPart p = findSelectablePart(element); + if (p != null && !toReturn.contains(p)) { + toReturn.add(p); + } + } + return toReturn; + } + + protected void partSelectionChanged(List parts, + boolean reveal) { + if (reveal) { + reveal(parts.toArray()); + } + } + + protected boolean internalSetTextSelection( + ITextSelection newTextSelection) { + if (newTextSelection == this.textSelection + || (newTextSelection != null + && newTextSelection.equals(this.textSelection))) + return false; + this.textSelection = newTextSelection; + return true; + } + + protected void textSelectionChanged(ITextSelection newTextSelection, + boolean reveal) { + // subclass may implement + } + + public IPart findSelectablePart(Object element) { + IPart p = findPart(element); + if (p == null || !isSelectable(p)) + return null; + return p; + } + + public boolean isSelectable(IPart p) { + return p != null && p.getStatus().isActive() + && p.hasRole(GEF.ROLE_SELECTABLE); + } + + protected void notifyViewerSelectionChanged() { + fireSelectionChanged(new SelectionChangedEvent(AbstractViewer.this, + getModelSelection())); + getControl().getAccessible().selectionChanged(); + firePostSelectionChanged(); + } + + public void refresh() { + if (textSelection != null) { + textSelectionChanged(textSelection, true); + return; + } + + if (partSelection != null) { + refreshPartSelection(getRootPart(), partSelection); + } + } + + protected void refreshPartSelection(IPart parent, + List selectedParts) { + if (parent == null) + return; + for (IPart p : parent.getChildren()) { + if (selectedParts.contains(p)) { + setSelected(p); + } else { + setDeselected(p); + } + refreshPartSelection(p, selectedParts); + } + } + + protected int getSelectionConstraint() { + Object value = getProperties().get(GEF.SelectionConstraint); + if (value instanceof Integer) + return ((Integer) value).intValue(); + return GEF.SEL_DEFAULT; + } + + } + + private Control control = null; + + private IRootPart rootPart = null; + + private IPartFactory partFactory = null; + + private PartRegistry partRegistry = null; + + private EditDomain domain = null; + + private Object input = null; + + private List filters = null; + + private ViewerSorter sorter = null; + + private ViewerComparator comparator = null; + + private ISelectionSupport selectionSupport = null; + + private Properties properties = null; + + private IDndSupport dndSupport = null; + + private AccessibleRegistry accRegistry = null; + + private IPart preSelected = null; + + private IPart focused = null; + + private EventListenerSupport listenerSupport = new EventListenerSupport(); + + private Map, IViewerService> serviceRegistry = null; + + private IPartSearchCondition partSearchCondition = null; + + private boolean postSelectionChangedEventScheduled = false; + + protected AbstractViewer() { + } + + @SuppressWarnings("unchecked") + public T getAdapter(Class adapter) { + if (Control.class.equals(adapter) || Widget.class.equals(adapter)) + return adapter.cast(getControl()); + if (IRootPart.class.equals(adapter)) + return adapter.cast(getRootPart()); + if (IPartFactory.class.equals(adapter)) + return adapter.cast(getPartFactory()); + if (PartRegistry.class.equals(adapter)) + return adapter.cast(getPartRegistry()); + if (EditDomain.class.equals(adapter)) + return adapter.cast(getEditDomain()); + if (ISelectionSupport.class.equals(adapter)) + return adapter.cast(getSelectionSupport()); + if (IDndSupport.class.equals(adapter)) + return adapter.cast(getDndSupport()); + if (Properties.class.equals(adapter)) + return adapter.cast(getProperties()); + return null; + } + + public Control createControl(Composite parent) { + return createControl(parent, SWT.NONE); + } + + public Control createControl(Composite parent, int style) { + control = internalCreateControl(parent, style); + Assert.isNotNull(control); + hookControl(control); + return control; + } + + protected abstract Control internalCreateControl(Composite parent, + int style); + + protected void hookControl(Control control) { + control.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(e); + } + }); + if (serviceRegistry != null) { + for (IViewerService service : serviceRegistry.values()) { + service.setControl(control); + } + } + IRootPart rootPart = getRootPart(); + if (rootPart != null) { + rootPart.getStatus().activate(); + } + } + + public Control getControl() { + return control; + } + + public IRootPart getRootPart() { + return rootPart; + } + + public void setRootPart(IRootPart rootPart) { + Assert.isNotNull(rootPart); + IRootPart oldRootPart = this.rootPart; + if (oldRootPart != null) { + oldRootPart.getStatus().deactivate(); + oldRootPart.setViewer(null); + } + this.rootPart = rootPart; + rootPart.setViewer(this); + if (getControl() != null && !getControl().isDisposed()) { + rootPart.getStatus().activate(); + } + //inputChanged(getInput(), getInput()); + } + + public IPartFactory getPartFactory() { + return partFactory; + } + + public void setPartFactory(IPartFactory partFactory) { + if (partFactory == this.partFactory) + return; + Assert.isNotNull(partFactory); + this.partFactory = partFactory; + inputChanged(getInput(), getInput()); + } + + public EditDomain getEditDomain() { + return domain; + } + + public void setEditDomain(EditDomain editDomain) { + this.domain = editDomain; + } + + public Object getInput() { + return input; + } + + public void setInput(Object input) { + Object oldInput = this.input; + this.input = input; + inputChanged(input, oldInput); + } + + protected void inputChanged(Object input, Object oldInput) { + Map preservedDataList = new HashMap(); + List activeServices = getActiveServices(); + if (activeServices != null) { + for (IViewerService service : activeServices) { + if (service instanceof IViewerService2) { + preservedDataList.put(service, + ((IViewerService2) service).preserveData()); + } + service.setActive(false); + } + } + super.inputChanged(input, oldInput); + contentsChanged(input, oldInput); + if (serviceRegistry != null) { + for (IViewerService service : serviceRegistry.values()) { + service.inputChanged(oldInput, input); + } + } + if (activeServices != null) { + for (IViewerService service : activeServices) { + service.setActive(true); + if (service instanceof IViewerService2) { + ((IViewerService2) service) + .restoreData(preservedDataList.get(service)); + } + } + } + fireInputChanged(input, oldInput); + } + + protected void contentsChanged(Object input, Object oldInput) { + IRootPart rootPart = getRootPart(); + if (rootPart != null) { + rootPart.setModel(input); + rootPart.setContents(createContents(rootPart, input)); + } + } + + protected IPart createContents(IRootPart root, Object input) { + if (input == null || getPartFactory() == null) + return null; + return getPartFactory().createPart(root, input); + } + + public boolean setFocus() { + if (getControl() == null || getControl().isDisposed()) + return false; + return getControl().setFocus(); + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.IViewer#setCursor(org.eclipse.swt.graphics.Cursor) + */ + public void setCursor(Cursor cursor) { + if (getControl() == null || getControl().isDisposed()) + return; + getControl().setCursor(cursor); + } + + protected void handleDispose(DisposeEvent e) { + if (serviceRegistry != null) { + for (IViewerService service : serviceRegistry.values()) { + service.dispose(); + } + serviceRegistry.clear(); + serviceRegistry = null; + } + IRootPart rootPart = getRootPart(); + if (rootPart != null) { + rootPart.getStatus().deactivate(); + } + } + + public void addFilter(ViewerFilter filter) { + if (filter == null) + return; + if (filters != null && filters.contains(filter)) + return; + if (filters == null) + filters = new ArrayList(); + filters.add(filter); + refresh(); + } + + public ViewerFilter[] getFilters() { + return filters == null ? new ViewerFilter[0] + : filters.toArray(new ViewerFilter[filters.size()]); + } + + public ViewerSorter getSorter() { + return sorter; + } + + public ViewerComparator getComparator() { + return comparator; + } + + public void removeFilter(ViewerFilter filter) { + if (filter == null || filters == null || filters.isEmpty()) + return; + filters.remove(filter); + refresh(); + } + + public void setFilters(ViewerFilter[] filters) { + if (isFiltersEqual(filters, getFilters())) + return; + if (filters == null || filters.length == 0) + this.filters = null; + else + this.filters = new ArrayList(Arrays.asList(filters)); + refresh(); + } + + protected boolean isFiltersEqual(ViewerFilter[] fs1, ViewerFilter[] fs2) { + if (fs1 == null) + return fs2 == null || fs2.length == 0; + if (fs2 == null) + return fs1.length == 0; + return Arrays.equals(fs1, fs2); + } + + public void setSorter(ViewerSorter sorter) { + if (sorter == this.sorter + || (sorter != null && sorter.equals(this.sorter))) + return; + this.sorter = sorter; + refresh(); + } + + public void setComparator(ViewerComparator comparator) { + if (comparator == this.comparator + || (comparator != null && comparator.equals(this.comparator))) + return; + this.comparator = comparator; + refresh(); + } + + public ISelectionSupport getSelectionSupport() { + if (selectionSupport == null) + selectionSupport = createSelectionSupport(); + return selectionSupport; + } + + protected ISelectionSupport createSelectionSupport() { + return new SelectionSupport(); + } + + public ISelection getSelection() { + return getSelectionSupport().getModelSelection(); + } + + public void setSelection(ISelection selection, boolean reveal) { + getSelectionSupport().setSelection(selection, reveal); + } + + public void reveal(Object[] elements) { + if (elements == null || elements.length == 0) + return; + + ISelectionSupport sd = getSelectionSupport(); + if (sd != null) { + List parts = new ArrayList(); + for (Object element : elements) { + IPart p = sd.findSelectablePart(element); + if (p != null && !parts.contains(p)) + parts.add(p); + } + if (!parts.isEmpty()) { + revealParts(parts); + } + } + } + + protected void revealParts(List parts) { + } + + /** + * @see org.xmind.gef.IViewer#refresh() + */ + public void refresh() { + IRootPart rootPart = getRootPart(); + if (rootPart != null && rootPart.getStatus().isActive()) + treeRefresh(rootPart); + } + + protected void treeRefresh(IPart parent) { + for (IPart child : parent.getChildren()) { + child.refresh(); + treeRefresh(child); + } + } + + public void updateToolTip() { + } + + /** + * @return the partRegistry + */ + public PartRegistry getPartRegistry() { + if (partRegistry == null) + partRegistry = new PartRegistry(); + return partRegistry; + } + + public IPart findPart(Object element) { + if (element instanceof IPart) + return (IPart) element; + if (partRegistry == null) + return null; + return partRegistry.getPartByModel(element); + } + + public IPart findPart(int x, int y) { + return null; + } + + /* + * (non-Javadoc) + * @seeorg.xmind.gef.IViewer#setPartSearchCondition(org.xmind.gef.IViewer. + * IPartSearchCondition) + */ + public void setPartSearchCondition(IPartSearchCondition condition) { + this.partSearchCondition = condition; + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.IViewer#getPartSearchCondition() + */ + public IPartSearchCondition getPartSearchCondition() { + return this.partSearchCondition; + } + + public void setPartRegistry(PartRegistry partRegistry) { + this.partRegistry = partRegistry; + } + + public AccessibleRegistry getAccessibleRegistry() { + if (accRegistry == null) + accRegistry = new AccessibleRegistry(); + return accRegistry; + } + + protected void setAccessibleRegistry(AccessibleRegistry accRegistry) { + this.accRegistry = accRegistry; + } + +// public IModelContentProvider getContentProvider() { +// return modelContentProvider; +// } +// +// public void setContentProvider(IModelContentProvider modelContentProvider) { +// Assert.isNotNull(modelContentProvider); +// IModelContentProvider oldContentProvider = this.modelContentProvider; +// this.modelContentProvider = modelContentProvider; +// if (oldContentProvider != null) { +// oldContentProvider.inputChanged(this, getInput(), null); +// oldContentProvider.dispose(); +// } +// modelContentProvider.inputChanged(this, null, getInput()); +// inputChanged(getInput(), getInput()); +// } + + public Properties getProperties() { + if (properties == null) + properties = new Properties(this); + return properties; + } + + public void setProperties(Properties properties) { + if (this.properties != null) { + this.properties.clear(); + } + if (properties != null) { + getProperties().putAll(properties); + } + } + + public IDndSupport getDndSupport() { + return dndSupport; + } + + public void setDndSupport(IDndSupport dndSupport) { + this.dndSupport = dndSupport; + } + + /** + * @return the listenerSupport + */ + protected EventListenerSupport getListenerSupport() { + return listenerSupport; + } + + public void addPreSelectionChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().addListener(PRE_SELECTION_CHANGED_KEY, listener); + } + + public void removePreSelectionChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().removeListener(PRE_SELECTION_CHANGED_KEY, + listener); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IPostSelectionProvider# + * addPostSelectionChangedListener + * (org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void addPostSelectionChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().addListener(POST_SELECTION_CHANGED_KEY, listener); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IPostSelectionProvider# + * removePostSelectionChangedListener + * (org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void removePostSelectionChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().removeListener(POST_SELECTION_CHANGED_KEY, + listener); + } + + protected void firePreSelectionChanged() { + ISelection selection = createPreSelection(); + final SelectionChangedEvent event = new SelectionChangedEvent(this, + selection); + getListenerSupport().fireEvent(PRE_SELECTION_CHANGED_KEY, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((ISelectionChangedListener) listener) + .selectionChanged(event); + } + }); + } + + protected void firePostSelectionChanged() { + if (getControl() == null || getControl().isDisposed()) + return; + + if (postSelectionChangedEventScheduled) + return; + postSelectionChangedEventScheduled = true; + getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + if (getControl() == null || getControl().isDisposed()) + return; + + ISelection selection = getSelection(); + final SelectionChangedEvent event = new SelectionChangedEvent( + AbstractViewer.this, selection); + getListenerSupport().fireEvent(POST_SELECTION_CHANGED_KEY, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((ISelectionChangedListener) listener) + .selectionChanged(event); + } + }); + postSelectionChangedEventScheduled = false; + } + }); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.IViewer#addFocusedChangedListener(org.eclipse.jface.viewers + * .ISelectionChangedListener) + */ + public void addFocusedPartChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().addListener(FOCUSED_PART_CHANGED_KEY, listener); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.IViewer#removeFocusedChangedListener(org.eclipse.jface. + * viewers.ISelectionChangedListener) + */ + public void removeFocusedPartChangedListener( + ISelectionChangedListener listener) { + getListenerSupport().removeListener(FOCUSED_PART_CHANGED_KEY, listener); + } + + protected void fireFocusedPartChanged() { + IPart focusedPart = getFocusedPart(); + ISelection selection; + if (focusedPart == null) { + selection = StructuredSelection.EMPTY; + } else { + selection = new StructuredSelection(focusedPart); + } + final SelectionChangedEvent event = new SelectionChangedEvent(this, + selection); + getListenerSupport().fireEvent(FOCUSED_PART_CHANGED_KEY, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((ISelectionChangedListener) listener) + .selectionChanged(event); + } + }); + } + + public void addInputChangedListener(IInputChangedListener listener) { + getListenerSupport().addListener(IInputChangedListener.class, listener); + } + + public void removeInputChangedListener(IInputChangedListener listener) { + getListenerSupport().removeListener(IInputChangedListener.class, + listener); + } + + protected void fireInputChanged(final Object newInput, + final Object oldInput) { + getListenerSupport().fireEvent(IInputChangedListener.class, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((IInputChangedListener) listener).inputChanged( + AbstractViewer.this, newInput, oldInput); + } + }); + } + + private ISelection createPreSelection() { + return getPreselected() == null ? StructuredSelection.EMPTY + : new StructuredSelection(getPreselected()); + } + + public Object getPreselected() { + return getPartRegistry().getModelByPart(preSelected); + } + + public IPart getPreselectedPart() { + return preSelected; + } + + public void setPreselected(Object element) { + IPart oldPreselected = this.preSelected; + IPart newPreselected = getSelectionSupport() + .findSelectablePart(element); + if (newPreselected == oldPreselected) + return; + + this.preSelected = newPreselected; + if (oldPreselected != null) { + oldPreselected.getStatus().dePreSelect(); + } + if (newPreselected != null) { + newPreselected.getStatus().preSelect(); + } + firePreSelectionChanged(); + } + + public Object getFocused() { + return focused; + } + + public IPart getFocusedPart() { + return getSelectionSupport().findSelectablePart(getFocused()); + } + + public void setFocused(Object element) { + IPart oldFocused = this.focused; + IPart newFocused = getSelectionSupport().findSelectablePart(element); + if (newFocused == oldFocused) + return; + + this.focused = newFocused; + if (oldFocused != null) { + oldFocused.getStatus().lostFocus(); + } + if (newFocused != null) { + newFocused.getStatus().setFocus(); + } + + Control c = getControl(); + if (c != null && !c.isDisposed()) { + IAccessible acc; + if (this.focused != null) { + this.focused.getStatus().setFocus(); + acc = (IAccessible) this.focused.getAdapter(IAccessible.class); + } else { + acc = null; + } + if (acc != null) { + c.getAccessible().setFocus(acc.getAccessibleId()); + } else { + c.getAccessible().setFocus(ACC.CHILDID_SELF); + } + } + fireFocusedPartChanged(); + } + + public IViewerService getService( + Class serviceType) { + if (serviceType == null || serviceRegistry == null) + return null; + return serviceRegistry.get(serviceType); + } + + public boolean hasService(Class serviceType) { + return serviceType != null && serviceRegistry != null + && serviceRegistry.containsKey(serviceType); + } + + public void installService(Class type, + IViewerService service) { + if (type == null || service == null) + return; + if (serviceRegistry == null) + serviceRegistry = new HashMap, IViewerService>(); + serviceRegistry.put(type, service); + if (getControl() != null && !getControl().isDisposed()) { + service.setControl(getControl()); + } + } + + public void uninstallService(Class type) { + if (type == null || serviceRegistry == null) + return; + IViewerService service = serviceRegistry.remove(type); + if (service != null) { + service.dispose(); + } + } + + private List getActiveServices() { + if (serviceRegistry != null) { + ArrayList list = new ArrayList(); + for (IViewerService service : serviceRegistry.values()) { + if (service.isActive()) + list.add(service); + } + return list; + } + return null; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/ArraySourceProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/ArraySourceProvider.java index 18d351dd3..340cfe093 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/ArraySourceProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/ArraySourceProvider.java @@ -1,89 +1,89 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * - * @author Frank Shaka - * - */ -public class ArraySourceProvider implements ISourceProvider { - - private List sources; - - public ArraySourceProvider() { - this.sources = new ArrayList(); - } - - public ArraySourceProvider(Object source) { - this.sources = new ArrayList(); - addSource(source); - } - - public ArraySourceProvider(Collection sources) { - this.sources = new ArrayList(sources.size()); - addSources(sources); - } - - public List getSources() { - return sources; - } - - public Object getSource() { - return sources.isEmpty() ? null : sources.get(0); - } - - public boolean hasSource() { - return !sources.isEmpty(); - } - - public void setSources(Collection newSources) { - this.sources.clear(); - addSources(newSources); - } - - public void setSource(Object source) { - this.sources.clear(); - addSource(source); - } - - public void addSources(Collection newSources) { - for (Object source : newSources) { - addSource(source); - } - } - - public void addSource(Object source) { - if (source != null && !this.sources.contains(source)) { - this.sources.add(source); - } - } - - public void removeSource(Object source) { - this.sources.remove(source); - } - - public void removeSources(Collection sources) { - this.sources.removeAll(sources); - } - - public void removeAllSources() { - this.sources.clear(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * + * @author Frank Shaka + * + */ +public class ArraySourceProvider implements ISourceProvider { + + private List sources; + + public ArraySourceProvider() { + this.sources = new ArrayList(); + } + + public ArraySourceProvider(Object source) { + this.sources = new ArrayList(); + addSource(source); + } + + public ArraySourceProvider(Collection sources) { + this.sources = new ArrayList(sources.size()); + addSources(sources); + } + + public List getSources() { + return sources; + } + + public Object getSource() { + return sources.isEmpty() ? null : sources.get(0); + } + + public boolean hasSource() { + return !sources.isEmpty(); + } + + public void setSources(Collection newSources) { + this.sources.clear(); + addSources(newSources); + } + + public void setSource(Object source) { + this.sources.clear(); + addSource(source); + } + + public void addSources(Collection newSources) { + for (Object source : newSources) { + addSource(source); + } + } + + public void addSource(Object source) { + if (source != null && !this.sources.contains(source)) { + this.sources.add(source); + } + } + + public void removeSource(Object source) { + this.sources.remove(source); + } + + public void removeSources(Collection sources) { + this.sources.removeAll(sources); + } + + public void removeAllSources() { + this.sources.clear(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/Disposable.java b/bundles/org.xmind.gef/src/org/xmind/gef/Disposable.java index 8866b9fff..8d267b4b9 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/Disposable.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/Disposable.java @@ -1,33 +1,33 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -/** - * - * @author Frank Shaka - * - */ -public class Disposable implements IDisposable2 { - - private boolean disposed = false; - - public void dispose() { - this.disposed = true; - } - - public boolean isDisposed() { - return disposed; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +/** + * + * @author Frank Shaka + * + */ +public class Disposable implements IDisposable2 { + + private boolean disposed = false; + + public void dispose() { + this.disposed = true; + } + + public boolean isDisposed() { + return disposed; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/EditDomain.java b/bundles/org.xmind.gef/src/org/xmind/gef/EditDomain.java index 817432703..18f99c830 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/EditDomain.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/EditDomain.java @@ -1,317 +1,317 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.part.PartRoles; -import org.xmind.gef.policy.IEditPolicy; -import org.xmind.gef.policy.NullEditPolicy; -import org.xmind.gef.tool.ITool; - -/** - * @author Brian Sun - */ -public class EditDomain extends Disposable { - - private IViewer targetViewer = null; - - private ITool activeTool = null; - - private String defaultTool = GEF.TOOL_DEFAULT; - - private Map tools = null; - - private PartRoles partRoles = null; - - private Map policies = null; - - private ICommandStack commandStack = null; - - private List listeners = null; - - private Queue requestQueue = new LinkedList(); - - private boolean handlingRequests = false; - - @Override - public void dispose() { - if (activeTool != null) { - activeTool.deactivate(null); - activeTool = null; - } - super.dispose(); - } - - public void installEditPolicy(String policyId, IEditPolicy policy) { - if (policies == null) - policies = new HashMap(); - policies.put(policyId, policy); - } - - public void uninstallEditPolicy(String policyId) { - if (policies == null) - return; - policies.remove(policyId); - } - - public IEditPolicy getEditPolicy(String role, String policyId) { - if (policies != null) { - IEditPolicy policy = policies.get(policyId); - if (policy != null) - return policy; - } - return NullEditPolicy.getInstance(); - } - - /** - * @return the partRoles - */ - public PartRoles getPartRoles() { - if (partRoles == null) { - partRoles = new PartRoles(); - } - return partRoles; - } - - /** - * @return - */ - public ICommandStack getCommandStack() { - return commandStack; - } - - /** - * @param commandStack - * the commandStack to set - */ - public void setCommandStack(ICommandStack commandStack) { - this.commandStack = commandStack; - } - - /** - * - * @return the viewer - * @deprecated use {@link #getTargetViewer()} instead - */ - public IViewer getViewer() { - return this.targetViewer; - } - - /** - * - * @param viewer - * the viewer to set - * @deprecated use {@link IViewer#setEditDomain(EditDomain)} instead - */ - public void setViewer(IViewer viewer) { - viewer.setEditDomain(this); -// if (this.targetViewer != null) { -// this.targetViewer.setEditDomain(null); -// } -// this.targetViewer = viewer; -// if (viewer != null) { -// viewer.setEditDomain(this); -// } - } - - public IViewer getTargetViewer() { - return this.targetViewer; - } - - /** - * @param targetViewer - * the targetViewer to set - */ - public void setTargetViewer(IViewer targetViewer) { - this.targetViewer = targetViewer; - } - -// public List getViewers() { -// if (viewers == null) -// viewers = new ArrayList(); -// return viewers; -// } -// -// /** -// * @param viewer -// * the viewer to set -// */ -// public void addViewer(IViewer viewer) { -// viewer.setDomain(this); -// if (viewers == null) -// viewers = new ArrayList(); -// if (!viewers.contains(viewer)) -// viewers.add(viewer); -// } -// -// public void removeViewer(IViewer viewer) { -// if (viewers == null) -// return; -// if (viewers.remove(viewer)) { -// viewer.setDomain(null); -// } -// } - - public ITool getDefaultTool() { - return tools == null ? null : tools.get(defaultTool); - } - - public String getDefaultToolType() { - return defaultTool; - } - - public void setDefaultTool(String id) { - this.defaultTool = id; - } - - /** - * @return the activeTool - */ - public ITool getActiveTool() { - if (activeTool == null) { - setActiveTool(GEF.TOOL_DEFAULT); - } - return activeTool; - } - - public ITool setActiveTool(String id) { - ITool ret = getTool(id); - if (ret != null) { - setActiveTool(ret); - } - return ret; - } - - /** - * @param activeTool - * the activeTool to set - */ - private void setActiveTool(ITool activeTool) { - if (activeTool == this.activeTool) - return; - ITool oldTool = this.activeTool; - if (oldTool != null) - oldTool.deactivate(activeTool); - this.activeTool = activeTool; - if (activeTool != null) - activeTool.activate(oldTool); - fireActiveToolChanged(oldTool); - } - - public void installTool(String id, ITool tool) { - if (id == null || tool == null) - return; - if (tools == null) - tools = new HashMap(); - tools.put(id, tool); - tool.setDomain(this); - if (defaultTool == null || GEF.TOOL_DEFAULT.equals(defaultTool)) - defaultTool = id; - } - - public ITool getTool(String id) { - if (GEF.TOOL_DEFAULT.equals(id)) - return getDefaultTool(); - return tools == null ? null : tools.get(id); - } - - public boolean hasTool(String id) { - if (GEF.TOOL_DEFAULT.equals(id)) - return hadDefaultTool(); - return tools != null && id != null && tools.containsKey(id); - } - - private boolean hadDefaultTool() { - return tools != null && defaultTool != null - && tools.containsKey(defaultTool); - } - - public void addEditDomainListener(IEditDomainListener listener) { - if (listeners == null) - listeners = new ArrayList(); - listeners.add(listener); - } - - public void removeEditDomainListener(IEditDomainListener listener) { - if (listeners == null) - return; - listeners.remove(listener); - if (listeners.isEmpty()) - listeners = null; - } - - protected void fireActiveToolChanged(ITool oldTool) { - if (listeners == null) - return; - ITool newTool = getActiveTool(); - for (Object listener : listeners.toArray()) { - ((IEditDomainListener) listener) - .activeToolChanged(oldTool, newTool); - } - } - - public void handleRequest(String requestType, IViewer targetViewer) { - handleRequest(new Request(requestType).setViewer(targetViewer)); - } - - public void handleRequest(Request request) { - pushRequestInQueue(request); - ensureRequestHandling(); - } - - /** - * @param request - */ - private void pushRequestInQueue(Request request) { - requestQueue.add(request); - } - - /** - * - */ - private void ensureRequestHandling() { - if (handlingRequests) - return; - - handlingRequests = true; - while (!requestQueue.isEmpty()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - internalHandleRequest(requestQueue.poll()); - } - }); - } - handlingRequests = false; - } - - /** - * @param poll - */ - protected void internalHandleRequest(Request request) { - ITool tool = getActiveTool(); - if (tool != null) { - tool.handleRequest(request); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.part.PartRoles; +import org.xmind.gef.policy.IEditPolicy; +import org.xmind.gef.policy.NullEditPolicy; +import org.xmind.gef.tool.ITool; + +/** + * @author Brian Sun + */ +public class EditDomain extends Disposable { + + private IViewer targetViewer = null; + + private ITool activeTool = null; + + private String defaultTool = GEF.TOOL_DEFAULT; + + private Map tools = null; + + private PartRoles partRoles = null; + + private Map policies = null; + + private ICommandStack commandStack = null; + + private List listeners = null; + + private Queue requestQueue = new LinkedList(); + + private boolean handlingRequests = false; + + @Override + public void dispose() { + if (activeTool != null) { + activeTool.deactivate(null); + activeTool = null; + } + super.dispose(); + } + + public void installEditPolicy(String policyId, IEditPolicy policy) { + if (policies == null) + policies = new HashMap(); + policies.put(policyId, policy); + } + + public void uninstallEditPolicy(String policyId) { + if (policies == null) + return; + policies.remove(policyId); + } + + public IEditPolicy getEditPolicy(String role, String policyId) { + if (policies != null) { + IEditPolicy policy = policies.get(policyId); + if (policy != null) + return policy; + } + return NullEditPolicy.getInstance(); + } + + /** + * @return the partRoles + */ + public PartRoles getPartRoles() { + if (partRoles == null) { + partRoles = new PartRoles(); + } + return partRoles; + } + + /** + * @return + */ + public ICommandStack getCommandStack() { + return commandStack; + } + + /** + * @param commandStack + * the commandStack to set + */ + public void setCommandStack(ICommandStack commandStack) { + this.commandStack = commandStack; + } + + /** + * + * @return the viewer + * @deprecated use {@link #getTargetViewer()} instead + */ + public IViewer getViewer() { + return this.targetViewer; + } + + /** + * + * @param viewer + * the viewer to set + * @deprecated use {@link IViewer#setEditDomain(EditDomain)} instead + */ + public void setViewer(IViewer viewer) { + viewer.setEditDomain(this); +// if (this.targetViewer != null) { +// this.targetViewer.setEditDomain(null); +// } +// this.targetViewer = viewer; +// if (viewer != null) { +// viewer.setEditDomain(this); +// } + } + + public IViewer getTargetViewer() { + return this.targetViewer; + } + + /** + * @param targetViewer + * the targetViewer to set + */ + public void setTargetViewer(IViewer targetViewer) { + this.targetViewer = targetViewer; + } + +// public List getViewers() { +// if (viewers == null) +// viewers = new ArrayList(); +// return viewers; +// } +// +// /** +// * @param viewer +// * the viewer to set +// */ +// public void addViewer(IViewer viewer) { +// viewer.setDomain(this); +// if (viewers == null) +// viewers = new ArrayList(); +// if (!viewers.contains(viewer)) +// viewers.add(viewer); +// } +// +// public void removeViewer(IViewer viewer) { +// if (viewers == null) +// return; +// if (viewers.remove(viewer)) { +// viewer.setDomain(null); +// } +// } + + public ITool getDefaultTool() { + return tools == null ? null : tools.get(defaultTool); + } + + public String getDefaultToolType() { + return defaultTool; + } + + public void setDefaultTool(String id) { + this.defaultTool = id; + } + + /** + * @return the activeTool + */ + public ITool getActiveTool() { + if (activeTool == null) { + setActiveTool(GEF.TOOL_DEFAULT); + } + return activeTool; + } + + public ITool setActiveTool(String id) { + ITool ret = getTool(id); + if (ret != null) { + setActiveTool(ret); + } + return ret; + } + + /** + * @param activeTool + * the activeTool to set + */ + private void setActiveTool(ITool activeTool) { + if (activeTool == this.activeTool) + return; + ITool oldTool = this.activeTool; + if (oldTool != null) + oldTool.deactivate(activeTool); + this.activeTool = activeTool; + if (activeTool != null) + activeTool.activate(oldTool); + fireActiveToolChanged(oldTool); + } + + public void installTool(String id, ITool tool) { + if (id == null || tool == null) + return; + if (tools == null) + tools = new HashMap(); + tools.put(id, tool); + tool.setDomain(this); + if (defaultTool == null || GEF.TOOL_DEFAULT.equals(defaultTool)) + defaultTool = id; + } + + public ITool getTool(String id) { + if (GEF.TOOL_DEFAULT.equals(id)) + return getDefaultTool(); + return tools == null ? null : tools.get(id); + } + + public boolean hasTool(String id) { + if (GEF.TOOL_DEFAULT.equals(id)) + return hadDefaultTool(); + return tools != null && id != null && tools.containsKey(id); + } + + private boolean hadDefaultTool() { + return tools != null && defaultTool != null + && tools.containsKey(defaultTool); + } + + public void addEditDomainListener(IEditDomainListener listener) { + if (listeners == null) + listeners = new ArrayList(); + listeners.add(listener); + } + + public void removeEditDomainListener(IEditDomainListener listener) { + if (listeners == null) + return; + listeners.remove(listener); + if (listeners.isEmpty()) + listeners = null; + } + + protected void fireActiveToolChanged(ITool oldTool) { + if (listeners == null) + return; + ITool newTool = getActiveTool(); + for (Object listener : listeners.toArray()) { + ((IEditDomainListener) listener) + .activeToolChanged(oldTool, newTool); + } + } + + public void handleRequest(String requestType, IViewer targetViewer) { + handleRequest(new Request(requestType).setViewer(targetViewer)); + } + + public void handleRequest(Request request) { + pushRequestInQueue(request); + ensureRequestHandling(); + } + + /** + * @param request + */ + private void pushRequestInQueue(Request request) { + requestQueue.add(request); + } + + /** + * + */ + private void ensureRequestHandling() { + if (handlingRequests) + return; + + handlingRequests = true; + while (!requestQueue.isEmpty()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + internalHandleRequest(requestQueue.poll()); + } + }); + } + handlingRequests = false; + } + + /** + * @param poll + */ + protected void internalHandleRequest(Request request) { + ITool tool = getActiveTool(); + if (tool != null) { + tool.handleRequest(request); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java b/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java index 9f3972cc0..62c1b8e13 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java @@ -1,437 +1,437 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import org.eclipse.jface.util.Util; - -/** - * @author Brian Sun - * @version 2005 - */ -public class GEF { - - /* - * Request Types: - */ - public static final String REQ_DEBUG = "debug"; //$NON-NLS-1$ - - public static final String REQ_SELECT = "select"; //$NON-NLS-1$ - public static final String REQ_SELECT_NONE = "select_none"; //$NON-NLS-1$ - public static final String REQ_SELECT_SINGLE = "select_single"; //$NON-NLS-1$ - public static final String REQ_SELECT_MULTI = "select_multi"; //$NON-NLS-1$ - public static final String REQ_SELECT_ALL = "select_all"; //$NON-NLS-1$ - - public static final String REQ_ZOOM = "zoom"; //$NON-NLS-1$ - public static final String REQ_ZOOMIN = "zoom_in"; //$NON-NLS-1$ - public static final String REQ_ZOOMOUT = "zoom_out"; //$NON-NLS-1$ - public static final String REQ_ACTUALSIZE = "actual_size"; //$NON-NLS-1$ - public static final String REQ_FITSIZE = "fit_size"; //$NON-NLS-1$ - public static final String REQ_FITSELECTION = "fit_selection"; //$NON-NLS-1$ - - public static final String REQ_COPY = "copy"; //$NON-NLS-1$ - public static final String REQ_CUT = "cut"; //$NON-NLS-1$ - public static final String REQ_PASTE = "paste"; //$NON-NLS-1$ - public static final String REQ_REDO = "redo"; //$NON-NLS-1$ - public static final String REQ_UNDO = "undo"; //$NON-NLS-1$ - public static final String REQ_REPEAT = "repeat"; //$NON-NLS-1$ - - public static final String REQ_MODIFY = "modify"; //$NON-NLS-1$ - public static final String REQ_RESIZE = "resize"; //$NON-NLS-1$ - public static final String REQ_EDIT = "edit"; //$NON-NLS-1$ - public static final String REQ_OPEN = "open"; //$NON-NLS-1$ - - public static final String REQ_CANCEL = "cancel"; //$NON-NLS-1$ - public static final String REQ_FINISH = "finish"; //$NON-NLS-1$ - - public static final String REQ_CREATE = "create"; //$NON-NLS-1$ - public static final String REQ_DELETE = "delete"; //$NON-NLS-1$ - public static final String REQ_MOVETO = "move to"; //$NON-NLS-1$ - public static final String REQ_COPYTO = "copy to"; //$NON-NLS-1$ - - public static final String REQ_MOVE_UP = "move_up"; //$NON-NLS-1$ - public static final String REQ_MOVE_DOWN = "move_down"; //$NON-NLS-1$ - public static final String REQ_MOVE_LEFT = "move_left"; //$NON-NLS-1$ - public static final String REQ_MOVE_RIGHT = "move_right"; //$NON-NLS-1$ - - public static final String REQ_NAV_UP = "navigate_up"; //$NON-NLS-1$ - public static final String REQ_NAV_DOWN = "navigate_down"; //$NON-NLS-1$ - public static final String REQ_NAV_LEFT = "navigate_left"; //$NON-NLS-1$ - public static final String REQ_NAV_RIGHT = "navigate_right"; //$NON-NLS-1$ - public static final String REQ_NAV_BEGINNING = "navigate_beginning"; //$NON-NLS-1$ - public static final String REQ_NAV_END = "navigate_end"; //$NON-NLS-1$ - public static final String REQ_NAV_BACK = "navigate_backward"; //$NON-NLS-1$ - public static final String REQ_NAV_FORWARD = "navigate_forward"; //$NON-NLS-1$ - public static final String REQ_NAV_NEXT = "navigate_next"; //$NON-NLS-1$ - public static final String REQ_NAV_PREV = "navigate_previous"; //$NON-NLS-1$ - public static final String REQ_MOVE_PREV = "move_previous"; //$NON-NLS-1$ - public static final String REQ_MOVE_NEXT = "move_next"; //$NON-NLS-1$ - - public static final String REQ_TRAVERSE = "traverse"; //$NON-NLS-1$ - public static final String REQ_GET_TRAVERSABLES = "get_traversables"; //$NON-NLS-1$ - - public static final String REQ_EXTEND = "extend"; //$NON-NLS-1$ - public static final String REQ_COLLAPSE = "collapse"; //$NON-NLS-1$ - public static final String REQ_EXTEND_ALL = "extend_all"; //$NON-NLS-1$ - public static final String REQ_COLLAPSE_ALL = "collapse_all"; //$NON-NLS-1$ - - public static final String REQ_SHOW = "show"; //$NON-NLS-1$ - public static final String REQ_HIDE = "hide"; //$NON-NLS-1$ - public static final String REQ_SHOW_ALL = "show_all"; //$NON-NLS-1$ - public static final String REQ_HIDE_ALL = "hide_all"; //$NON-NLS-1$ - public static final String REQ_SHOW_OTHER = "show_other"; //$NON-NLS-1$ - public static final String REQ_SHOW_ONLY = "show_only"; //$NON-NLS-1$ - - public static final String REQ_ALIGN = "align"; //$NON-NLS-1$ - public static final String REQ_SORT = "sort"; //$NON-NLS-1$ - - public static final String REQ_DROP = "drop"; //$NON-NLS-1$ - - public static final String REQ_CONNECT = "connect"; //$NON-NLS-1$ - - /* - * Tool Status: - */ - public static final int ST_ACTIVE = 1; - public static final int ST_ALT_PRESSED = 1 << 1; - public static final int ST_CONTROL_PRESSED = 1 << 2; - public static final int ST_SHIFT_PRESSED = 1 << 3; - public static final int ST_MOUSE_HOVER = 1 << 4; - public static final int ST_MOUSE_DOUBLECLICKING = 1 << 5; - public static final int ST_MOUSE_PRESSED = 1 << 6; - public static final int ST_MOUSE_DRAGGING = 1 << 7; - public static final int ST_MOUSE_RIGHT = 1 << 8; - public static final int ST_HIDE_CMENU = 1 << 9; - public static final int ST_FORCE_CMENU = 1 << 10; - public static final int ST_NO_DRAGGING = 1 << 11; - public static final int ST_FREE_MOVE_MODE = 1 << 12; - - public static final int ST_MODIFIER_MASK = ST_ALT_PRESSED - | ST_CONTROL_PRESSED | ST_SHIFT_PRESSED; - - /* - * Parts Status: - */ - public static final int PART_ACTIVE = 1; - public static final int PART_SELECTED = 1 << 1; - public static final int PART_PRESELECTED = 1 << 2; - public static final int PART_FOCUSED = 1 << 3; - public static final int PART_SEL_MASK = PART_PRESELECTED | PART_SELECTED - | PART_FOCUSED; - public static final int PART_PRIM_SEL_MASK = PART_SELECTED | PART_FOCUSED; - - /* - * Part Roles: - */ - public static final String ROLE_CANVAS = "canvas role"; //$NON-NLS-1$ - public static final String ROLE_MOVABLE = "movable role"; //$NON-NLS-1$ - public static final String ROLE_MODIFIABLE = "modifiable role"; //$NON-NLS-1$ - public static final String ROLE_SELECTABLE = "selectable role"; //$NON-NLS-1$ - public static final String ROLE_NAVIGABLE = "navigable role"; //$NON-NLS-1$ - public static final String ROLE_TRAVERSABLE = "traversable role"; //$NON-NLS-1$ - public static final String ROLE_CONTAINER = "container role"; //$NON-NLS-1$ - public static final String ROLE_CREATABLE = "creatable role"; //$NON-NLS-1$ - public static final String ROLE_DELETABLE = "deletable role"; //$NON-NLS-1$ - public static final String ROLE_EXTENDABLE = "extendable role"; //$NON-NLS-1$ - public static final String ROLE_SCALABLE = "scalable role"; //$NON-NLS-1$ - public static final String ROLE_EDITABLE = "editable role"; //$NON-NLS-1$ - public static final String ROLE_FILTERABLE = "filterable role"; //$NON-NLS-1$ - public static final String ROLE_CONNECTABLE = "connectable role"; //$NON-NLS-1$ - public static final String ROLE_DROP_TARGET = "drop target role"; //$NON-NLS-1$ - public static final String ROLE_MAP_MOVABLE = "map movable role"; //$NON-NLS-1$ - - public static final String ROLE_SORTABLE = "sortable role"; //$NON-NLS-1$ - - /* - * Command Types: - */ - public static final int CMD_NORMAL = 0; - public static final int CMD_CREATE = 1; - public static final int CMD_DELETE = 2; - public static final int CMD_MODIFY = 3; - - /* - * CommandStack Events: - */ - public static final int CS_PRE_EXECUTE = 1; - public static final int CS_PRE_REDO = 1 << 1; - public static final int CS_PRE_UNDO = 1 << 2; - public static final int CS_POST_EXECUTE = 1 << 3; - public static final int CS_POST_REDO = 1 << 4; - public static final int CS_POST_UNDO = 1 << 5; - public static final int CS_COMMAND_PUSHED = 1 << 6; - public static final int CS_UPDATED = 1 << 7; - - public static final int CS_PRE_MASK = CS_PRE_EXECUTE | CS_PRE_UNDO - | CS_PRE_REDO; - public static final int CS_POST_MASK = CS_POST_EXECUTE | CS_POST_UNDO - | CS_POST_REDO; - - /* - * Tools: - */ - public static final String TOOL_DEFAULT = "default tool"; //$NON-NLS-1$ - public static final String TOOL_SELECT = "select tool"; //$NON-NLS-1$ - public static final String TOOL_AREASELECT = "area select tool"; //$NON-NLS-1$ - public static final String TOOL_TRAVERSE = "traverse tool"; //$NON-NLS-1$ - public static final String TOOL_CREATE = "create tool"; //$NON-NLS-1$ - public static final String TOOL_MOVE = "move tool"; //$NON-NLS-1$ - public static final String TOOL_BROWSE = "browse tool"; //$NON-NLS-1$ - public static final String TOOL_EDIT = "edit tool"; //$NON-NLS-1$ - public static final String TOOL_RESIZE = "resize tool"; //$NON-NLS-1$ - public static final String TOOL_AREACREATE = "area create tool"; //$NON-NLS-1$ - public static final String TOOL_DND = "dnd tool"; //$NON-NLS-1$ - public static final String TOOL_PREVIEW = "preview tool"; //$NON-NLS-1$ - - /* - * Layers: - */ - public static final Object LAYERS_SCALABLE = "scalable layers"; //$NON-NLS-1$ - public static final Object LAYER_BACKGROUND = "background layer"; //$NON-NLS-1$ - public static final Object LAYER_CONTENTS = "contents layer"; //$NON-NLS-1$ - public static final Object LAYER_PRESENTATION = "presentation layer"; //$NON-NLS-1$ - public static final Object LAYER_FEEDBACK = "feedback layer"; //$NON-NLS-1$ - public static final Object LAYER_SHADOW = "shadow layer"; //$NON-NLS-1$ - public static final Object LAYER_HANDLE = "handle layer"; //$NON-NLS-1$ - - /* - * Viewer property - */ - public static final String SelectionConstraint = "selection constraint"; //$NON-NLS-1$ - public static final int SEL_EMPTY = 1; - public static final int SEL_SINGLE = 1 << 1; - public static final int SEL_MULTI = 1 << 2; - public static final int SEL_DEFAULT = SEL_EMPTY | SEL_SINGLE | SEL_MULTI; - - /** - * Font case - */ - public static final int CASE_EMPTY = 0; - public static final int MANUAL = 1; - public static final int UPPERCASE = 1 << 1; - public static final int LOWERCASE = 1 << 2; - public static final int CAPITALIZE = 1 << 3; - - /** - * Request parameter: the source part from which the request is sent, - * typically used by a dragging tool to request the target part to show - * feedback or handle connection command. - *
- *
Values:
- *
a {@link org.xmind.gef.part.IPart}
- *
- */ - public static final String PARAM_SOURCE = "source"; //$NON-NLS-1$ - - /** - * Request parameter: the size of a size request. - *
- *
Values:
- *
a {@link org.eclipse.draw2d.geometry.Dimension}
- *
- */ - public static final String PARAM_SIZE = "size"; //$NON-NLS-1$ - - /** - * Request parameter: the text of a text request. - *
- *
Values:
- *
String
- *
- */ - public static final String PARAM_TEXT = "text"; //$NON-NLS-1$ - - /** - * Request parameter: the position of a position request. - *
- *
Values:
- *
a {@link org.eclipse.draw2d.geometry.Point}
- *
- */ - public static final String PARAM_POSITION = "position"; //$NON-NLS-1$ - - /** - * Request parameter: whether the position is relative. - *
- *
Values:
- *
Boolean
- *
- */ - public static final String PARAM_POSITION_RELATIVE = "positionRelative"; //$NON-NLS-1$ - - /** - * Request parameter: the absolute position of a position request. - *
- *
Values:
- *
a {@link org.eclipse.draw2d.geometry.Point}
- *
- */ - public static final String PARAM_POSITION_ABSOLUTE = "positionAbsolute"; //$NON-NLS-1$ - - /** - * Request parameter: the text selection. - *
- *
Values:
- *
an {@link org.eclipse.jface.text.ITextSelection}
- *
- */ - public static final String PARAM_TEXT_SELECTION = "textSelection"; //$NON-NLS-1$ - - /** - * Request parameter: the scale of a zoom request. - *
- *
Values:
- *
Double
- *
- */ - public static final String PARAM_ZOOM_SCALE = "zoomScale"; //$NON-NLS-1$ - - /** - * Request parameter: the target parent of a 'move to' or 'copy to' request. - *
- *
Values:
- *
a {@link org.xmind.gef.part.IPart}
- *
- */ - public static final String PARAM_PARENT = "parent"; //$NON-NLS-1$ - - /** - * Request parameter: the new index of a 'move to' or 'copy to' request. - *
- *
Values:
- *
an Integer
- *
- */ - public static final String PARAM_INDEX = "index"; //$NON-NLS-1$ - - /** - * Request parameter: the alignment hint of a 'align' request. - *
- *
Values:
- *
LEFT, CENTER, RIGHT, TOP, MIDDLE, BOTTOM
- *
- * - * @see org.eclipse.draw2d.PositionConstants#LEFT - * @see org.eclipse.draw2d.PositionConstants#CENTER - * @see org.eclipse.draw2d.PositionConstants#RIGHT - * @see org.eclipse.draw2d.PositionConstants#TOP - * @see org.eclipse.draw2d.PositionConstants#MIDDLE - * @see org.eclipse.draw2d.PositionConstants#BOTTOM - */ - public static final String PARAM_ALIGNMENT = "alignment"; //$NON-NLS-1$ - - /** - * Request parameter: the method to compare two elements when handling a - * 'sort' request. - */ - public static final String PARAM_COMPARAND = "comparand"; //$NON-NLS-1$ - - /** - * Request parameter: whether the navigation is sequential. - *
- *
Values:
- *
Boolean
- *
- */ - public static final String PARAM_NAV_SEQUENTIAL = "navigationSequential"; //$NON-NLS-1$ - - /** - * Request parameter: the starting part of the sequential navigation. - *
- *
Values:
- *
{@link org.xmind.gef.part.IPart}
- *
- */ - public static final String PARAM_NAV_SEQUENCE_START = "navigationSequenceStart"; //$NON-NLS-1$ - - /** - * Request parameter: file path(s) of a path request. - *
- *
Values:
- *
a single file path (String), or an array of file paths ( - * String[])
- *
- */ - public static final String PARAM_PATH = "paths"; //$NON-NLS-1$ - - /** - * Request parameter: whether to take focus on start. - *
- *
Values:
- *
Boolean
- *
- */ - public static final String PARAM_FOCUS = "focus"; //$NON-NLS-1$ - - /** - * Request parameter: drop operation identifier - *
- *
Values:
- *
{@link org.eclipse.swt.dnd.DND#DROP_NONE}
- *
{@link org.eclipse.swt.dnd.DND#DROP_COPY}
- *
{@link org.eclipse.swt.dnd.DND#DROP_MOVE}
- *
{@link org.eclipse.swt.dnd.DND#DROP_LINK}
- *
{@link org.eclipse.swt.dnd.DND#DROP_DEFAULT}
- *
- */ - public static final String PARAM_DROP_OPERATION = "dropOperation"; //$NON-NLS-1$ - - /** - * Result key of the traverse request to retrieve the traversable parts - * selected by a TraversablePolicy. - *
- *
Values:
- *
an array of parts ({@link org.xmind.gef.part.IPart}[]) - *
- *
- */ - public static final String RESULT_TRAVERSE = "traverseResult"; //$NON-NLS-1$ - - /** - * Result key of the navigation request to retrieve the target parts - * selected by a NavigablePolicy. - *
- *
Values:
- *
an array of parts ({@link org.xmind.gef.part.IPart}[]) - *
- *
- */ - public static final String RESULT_NAVIGATION = "navigationResult"; //$NON-NLS-1$ - - /** - * Result key of the navigation request to retrieve the part to be focused. - *
- *
Values:
- *
an {@link org.xmind.gef.part.IPart}
- *
- */ - public static final String RESULT_NEW_FOCUS = "newFocus"; //$NON-NLS-1$ - - /* - * Graphics Hints: - */ - public static final boolean IS_PLATFORM_SUPPORT_GRADIENT = true; - - private static Boolean textPathSupported = null; - - public static boolean isTextPathSupported() { - if (textPathSupported == null) { - textPathSupported = Boolean.valueOf(Util.isWindows()); - } - return textPathSupported.booleanValue(); - } - - private GEF() { - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import org.eclipse.jface.util.Util; + +/** + * @author Brian Sun + * @version 2005 + */ +public class GEF { + + /* + * Request Types: + */ + public static final String REQ_DEBUG = "debug"; //$NON-NLS-1$ + + public static final String REQ_SELECT = "select"; //$NON-NLS-1$ + public static final String REQ_SELECT_NONE = "select_none"; //$NON-NLS-1$ + public static final String REQ_SELECT_SINGLE = "select_single"; //$NON-NLS-1$ + public static final String REQ_SELECT_MULTI = "select_multi"; //$NON-NLS-1$ + public static final String REQ_SELECT_ALL = "select_all"; //$NON-NLS-1$ + + public static final String REQ_ZOOM = "zoom"; //$NON-NLS-1$ + public static final String REQ_ZOOMIN = "zoom_in"; //$NON-NLS-1$ + public static final String REQ_ZOOMOUT = "zoom_out"; //$NON-NLS-1$ + public static final String REQ_ACTUALSIZE = "actual_size"; //$NON-NLS-1$ + public static final String REQ_FITSIZE = "fit_size"; //$NON-NLS-1$ + public static final String REQ_FITSELECTION = "fit_selection"; //$NON-NLS-1$ + + public static final String REQ_COPY = "copy"; //$NON-NLS-1$ + public static final String REQ_CUT = "cut"; //$NON-NLS-1$ + public static final String REQ_PASTE = "paste"; //$NON-NLS-1$ + public static final String REQ_REDO = "redo"; //$NON-NLS-1$ + public static final String REQ_UNDO = "undo"; //$NON-NLS-1$ + public static final String REQ_REPEAT = "repeat"; //$NON-NLS-1$ + + public static final String REQ_MODIFY = "modify"; //$NON-NLS-1$ + public static final String REQ_RESIZE = "resize"; //$NON-NLS-1$ + public static final String REQ_EDIT = "edit"; //$NON-NLS-1$ + public static final String REQ_OPEN = "open"; //$NON-NLS-1$ + + public static final String REQ_CANCEL = "cancel"; //$NON-NLS-1$ + public static final String REQ_FINISH = "finish"; //$NON-NLS-1$ + + public static final String REQ_CREATE = "create"; //$NON-NLS-1$ + public static final String REQ_DELETE = "delete"; //$NON-NLS-1$ + public static final String REQ_MOVETO = "move to"; //$NON-NLS-1$ + public static final String REQ_COPYTO = "copy to"; //$NON-NLS-1$ + + public static final String REQ_MOVE_UP = "move_up"; //$NON-NLS-1$ + public static final String REQ_MOVE_DOWN = "move_down"; //$NON-NLS-1$ + public static final String REQ_MOVE_LEFT = "move_left"; //$NON-NLS-1$ + public static final String REQ_MOVE_RIGHT = "move_right"; //$NON-NLS-1$ + + public static final String REQ_NAV_UP = "navigate_up"; //$NON-NLS-1$ + public static final String REQ_NAV_DOWN = "navigate_down"; //$NON-NLS-1$ + public static final String REQ_NAV_LEFT = "navigate_left"; //$NON-NLS-1$ + public static final String REQ_NAV_RIGHT = "navigate_right"; //$NON-NLS-1$ + public static final String REQ_NAV_BEGINNING = "navigate_beginning"; //$NON-NLS-1$ + public static final String REQ_NAV_END = "navigate_end"; //$NON-NLS-1$ + public static final String REQ_NAV_BACK = "navigate_backward"; //$NON-NLS-1$ + public static final String REQ_NAV_FORWARD = "navigate_forward"; //$NON-NLS-1$ + public static final String REQ_NAV_NEXT = "navigate_next"; //$NON-NLS-1$ + public static final String REQ_NAV_PREV = "navigate_previous"; //$NON-NLS-1$ + public static final String REQ_MOVE_PREV = "move_previous"; //$NON-NLS-1$ + public static final String REQ_MOVE_NEXT = "move_next"; //$NON-NLS-1$ + + public static final String REQ_TRAVERSE = "traverse"; //$NON-NLS-1$ + public static final String REQ_GET_TRAVERSABLES = "get_traversables"; //$NON-NLS-1$ + + public static final String REQ_EXTEND = "extend"; //$NON-NLS-1$ + public static final String REQ_COLLAPSE = "collapse"; //$NON-NLS-1$ + public static final String REQ_EXTEND_ALL = "extend_all"; //$NON-NLS-1$ + public static final String REQ_COLLAPSE_ALL = "collapse_all"; //$NON-NLS-1$ + + public static final String REQ_SHOW = "show"; //$NON-NLS-1$ + public static final String REQ_HIDE = "hide"; //$NON-NLS-1$ + public static final String REQ_SHOW_ALL = "show_all"; //$NON-NLS-1$ + public static final String REQ_HIDE_ALL = "hide_all"; //$NON-NLS-1$ + public static final String REQ_SHOW_OTHER = "show_other"; //$NON-NLS-1$ + public static final String REQ_SHOW_ONLY = "show_only"; //$NON-NLS-1$ + + public static final String REQ_ALIGN = "align"; //$NON-NLS-1$ + public static final String REQ_SORT = "sort"; //$NON-NLS-1$ + + public static final String REQ_DROP = "drop"; //$NON-NLS-1$ + + public static final String REQ_CONNECT = "connect"; //$NON-NLS-1$ + + /* + * Tool Status: + */ + public static final int ST_ACTIVE = 1; + public static final int ST_ALT_PRESSED = 1 << 1; + public static final int ST_CONTROL_PRESSED = 1 << 2; + public static final int ST_SHIFT_PRESSED = 1 << 3; + public static final int ST_MOUSE_HOVER = 1 << 4; + public static final int ST_MOUSE_DOUBLECLICKING = 1 << 5; + public static final int ST_MOUSE_PRESSED = 1 << 6; + public static final int ST_MOUSE_DRAGGING = 1 << 7; + public static final int ST_MOUSE_RIGHT = 1 << 8; + public static final int ST_HIDE_CMENU = 1 << 9; + public static final int ST_FORCE_CMENU = 1 << 10; + public static final int ST_NO_DRAGGING = 1 << 11; + public static final int ST_FREE_MOVE_MODE = 1 << 12; + + public static final int ST_MODIFIER_MASK = ST_ALT_PRESSED + | ST_CONTROL_PRESSED | ST_SHIFT_PRESSED; + + /* + * Parts Status: + */ + public static final int PART_ACTIVE = 1; + public static final int PART_SELECTED = 1 << 1; + public static final int PART_PRESELECTED = 1 << 2; + public static final int PART_FOCUSED = 1 << 3; + public static final int PART_SEL_MASK = PART_PRESELECTED | PART_SELECTED + | PART_FOCUSED; + public static final int PART_PRIM_SEL_MASK = PART_SELECTED | PART_FOCUSED; + + /* + * Part Roles: + */ + public static final String ROLE_CANVAS = "canvas role"; //$NON-NLS-1$ + public static final String ROLE_MOVABLE = "movable role"; //$NON-NLS-1$ + public static final String ROLE_MODIFIABLE = "modifiable role"; //$NON-NLS-1$ + public static final String ROLE_SELECTABLE = "selectable role"; //$NON-NLS-1$ + public static final String ROLE_NAVIGABLE = "navigable role"; //$NON-NLS-1$ + public static final String ROLE_TRAVERSABLE = "traversable role"; //$NON-NLS-1$ + public static final String ROLE_CONTAINER = "container role"; //$NON-NLS-1$ + public static final String ROLE_CREATABLE = "creatable role"; //$NON-NLS-1$ + public static final String ROLE_DELETABLE = "deletable role"; //$NON-NLS-1$ + public static final String ROLE_EXTENDABLE = "extendable role"; //$NON-NLS-1$ + public static final String ROLE_SCALABLE = "scalable role"; //$NON-NLS-1$ + public static final String ROLE_EDITABLE = "editable role"; //$NON-NLS-1$ + public static final String ROLE_FILTERABLE = "filterable role"; //$NON-NLS-1$ + public static final String ROLE_CONNECTABLE = "connectable role"; //$NON-NLS-1$ + public static final String ROLE_DROP_TARGET = "drop target role"; //$NON-NLS-1$ + public static final String ROLE_MAP_MOVABLE = "map movable role"; //$NON-NLS-1$ + + public static final String ROLE_SORTABLE = "sortable role"; //$NON-NLS-1$ + + /* + * Command Types: + */ + public static final int CMD_NORMAL = 0; + public static final int CMD_CREATE = 1; + public static final int CMD_DELETE = 2; + public static final int CMD_MODIFY = 3; + + /* + * CommandStack Events: + */ + public static final int CS_PRE_EXECUTE = 1; + public static final int CS_PRE_REDO = 1 << 1; + public static final int CS_PRE_UNDO = 1 << 2; + public static final int CS_POST_EXECUTE = 1 << 3; + public static final int CS_POST_REDO = 1 << 4; + public static final int CS_POST_UNDO = 1 << 5; + public static final int CS_COMMAND_PUSHED = 1 << 6; + public static final int CS_UPDATED = 1 << 7; + + public static final int CS_PRE_MASK = CS_PRE_EXECUTE | CS_PRE_UNDO + | CS_PRE_REDO; + public static final int CS_POST_MASK = CS_POST_EXECUTE | CS_POST_UNDO + | CS_POST_REDO; + + /* + * Tools: + */ + public static final String TOOL_DEFAULT = "default tool"; //$NON-NLS-1$ + public static final String TOOL_SELECT = "select tool"; //$NON-NLS-1$ + public static final String TOOL_AREASELECT = "area select tool"; //$NON-NLS-1$ + public static final String TOOL_TRAVERSE = "traverse tool"; //$NON-NLS-1$ + public static final String TOOL_CREATE = "create tool"; //$NON-NLS-1$ + public static final String TOOL_MOVE = "move tool"; //$NON-NLS-1$ + public static final String TOOL_BROWSE = "browse tool"; //$NON-NLS-1$ + public static final String TOOL_EDIT = "edit tool"; //$NON-NLS-1$ + public static final String TOOL_RESIZE = "resize tool"; //$NON-NLS-1$ + public static final String TOOL_AREACREATE = "area create tool"; //$NON-NLS-1$ + public static final String TOOL_DND = "dnd tool"; //$NON-NLS-1$ + public static final String TOOL_PREVIEW = "preview tool"; //$NON-NLS-1$ + + /* + * Layers: + */ + public static final Object LAYERS_SCALABLE = "scalable layers"; //$NON-NLS-1$ + public static final Object LAYER_BACKGROUND = "background layer"; //$NON-NLS-1$ + public static final Object LAYER_CONTENTS = "contents layer"; //$NON-NLS-1$ + public static final Object LAYER_PRESENTATION = "presentation layer"; //$NON-NLS-1$ + public static final Object LAYER_FEEDBACK = "feedback layer"; //$NON-NLS-1$ + public static final Object LAYER_SHADOW = "shadow layer"; //$NON-NLS-1$ + public static final Object LAYER_HANDLE = "handle layer"; //$NON-NLS-1$ + + /* + * Viewer property + */ + public static final String SelectionConstraint = "selection constraint"; //$NON-NLS-1$ + public static final int SEL_EMPTY = 1; + public static final int SEL_SINGLE = 1 << 1; + public static final int SEL_MULTI = 1 << 2; + public static final int SEL_DEFAULT = SEL_EMPTY | SEL_SINGLE | SEL_MULTI; + + /** + * Font case + */ + public static final int CASE_EMPTY = 0; + public static final int MANUAL = 1; + public static final int UPPERCASE = 1 << 1; + public static final int LOWERCASE = 1 << 2; + public static final int CAPITALIZE = 1 << 3; + + /** + * Request parameter: the source part from which the request is sent, + * typically used by a dragging tool to request the target part to show + * feedback or handle connection command. + *
+ *
Values:
+ *
a {@link org.xmind.gef.part.IPart}
+ *
+ */ + public static final String PARAM_SOURCE = "source"; //$NON-NLS-1$ + + /** + * Request parameter: the size of a size request. + *
+ *
Values:
+ *
a {@link org.eclipse.draw2d.geometry.Dimension}
+ *
+ */ + public static final String PARAM_SIZE = "size"; //$NON-NLS-1$ + + /** + * Request parameter: the text of a text request. + *
+ *
Values:
+ *
String
+ *
+ */ + public static final String PARAM_TEXT = "text"; //$NON-NLS-1$ + + /** + * Request parameter: the position of a position request. + *
+ *
Values:
+ *
a {@link org.eclipse.draw2d.geometry.Point}
+ *
+ */ + public static final String PARAM_POSITION = "position"; //$NON-NLS-1$ + + /** + * Request parameter: whether the position is relative. + *
+ *
Values:
+ *
Boolean
+ *
+ */ + public static final String PARAM_POSITION_RELATIVE = "positionRelative"; //$NON-NLS-1$ + + /** + * Request parameter: the absolute position of a position request. + *
+ *
Values:
+ *
a {@link org.eclipse.draw2d.geometry.Point}
+ *
+ */ + public static final String PARAM_POSITION_ABSOLUTE = "positionAbsolute"; //$NON-NLS-1$ + + /** + * Request parameter: the text selection. + *
+ *
Values:
+ *
an {@link org.eclipse.jface.text.ITextSelection}
+ *
+ */ + public static final String PARAM_TEXT_SELECTION = "textSelection"; //$NON-NLS-1$ + + /** + * Request parameter: the scale of a zoom request. + *
+ *
Values:
+ *
Double
+ *
+ */ + public static final String PARAM_ZOOM_SCALE = "zoomScale"; //$NON-NLS-1$ + + /** + * Request parameter: the target parent of a 'move to' or 'copy to' request. + *
+ *
Values:
+ *
a {@link org.xmind.gef.part.IPart}
+ *
+ */ + public static final String PARAM_PARENT = "parent"; //$NON-NLS-1$ + + /** + * Request parameter: the new index of a 'move to' or 'copy to' request. + *
+ *
Values:
+ *
an Integer
+ *
+ */ + public static final String PARAM_INDEX = "index"; //$NON-NLS-1$ + + /** + * Request parameter: the alignment hint of a 'align' request. + *
+ *
Values:
+ *
LEFT, CENTER, RIGHT, TOP, MIDDLE, BOTTOM
+ *
+ * + * @see org.eclipse.draw2d.PositionConstants#LEFT + * @see org.eclipse.draw2d.PositionConstants#CENTER + * @see org.eclipse.draw2d.PositionConstants#RIGHT + * @see org.eclipse.draw2d.PositionConstants#TOP + * @see org.eclipse.draw2d.PositionConstants#MIDDLE + * @see org.eclipse.draw2d.PositionConstants#BOTTOM + */ + public static final String PARAM_ALIGNMENT = "alignment"; //$NON-NLS-1$ + + /** + * Request parameter: the method to compare two elements when handling a + * 'sort' request. + */ + public static final String PARAM_COMPARAND = "comparand"; //$NON-NLS-1$ + + /** + * Request parameter: whether the navigation is sequential. + *
+ *
Values:
+ *
Boolean
+ *
+ */ + public static final String PARAM_NAV_SEQUENTIAL = "navigationSequential"; //$NON-NLS-1$ + + /** + * Request parameter: the starting part of the sequential navigation. + *
+ *
Values:
+ *
{@link org.xmind.gef.part.IPart}
+ *
+ */ + public static final String PARAM_NAV_SEQUENCE_START = "navigationSequenceStart"; //$NON-NLS-1$ + + /** + * Request parameter: file path(s) of a path request. + *
+ *
Values:
+ *
a single file path (String), or an array of file paths ( + * String[])
+ *
+ */ + public static final String PARAM_PATH = "paths"; //$NON-NLS-1$ + + /** + * Request parameter: whether to take focus on start. + *
+ *
Values:
+ *
Boolean
+ *
+ */ + public static final String PARAM_FOCUS = "focus"; //$NON-NLS-1$ + + /** + * Request parameter: drop operation identifier + *
+ *
Values:
+ *
{@link org.eclipse.swt.dnd.DND#DROP_NONE}
+ *
{@link org.eclipse.swt.dnd.DND#DROP_COPY}
+ *
{@link org.eclipse.swt.dnd.DND#DROP_MOVE}
+ *
{@link org.eclipse.swt.dnd.DND#DROP_LINK}
+ *
{@link org.eclipse.swt.dnd.DND#DROP_DEFAULT}
+ *
+ */ + public static final String PARAM_DROP_OPERATION = "dropOperation"; //$NON-NLS-1$ + + /** + * Result key of the traverse request to retrieve the traversable parts + * selected by a TraversablePolicy. + *
+ *
Values:
+ *
an array of parts ({@link org.xmind.gef.part.IPart}[]) + *
+ *
+ */ + public static final String RESULT_TRAVERSE = "traverseResult"; //$NON-NLS-1$ + + /** + * Result key of the navigation request to retrieve the target parts + * selected by a NavigablePolicy. + *
+ *
Values:
+ *
an array of parts ({@link org.xmind.gef.part.IPart}[]) + *
+ *
+ */ + public static final String RESULT_NAVIGATION = "navigationResult"; //$NON-NLS-1$ + + /** + * Result key of the navigation request to retrieve the part to be focused. + *
+ *
Values:
+ *
an {@link org.xmind.gef.part.IPart}
+ *
+ */ + public static final String RESULT_NEW_FOCUS = "newFocus"; //$NON-NLS-1$ + + /* + * Graphics Hints: + */ + public static final boolean IS_PLATFORM_SUPPORT_GRADIENT = true; + + private static Boolean textPathSupported = null; + + public static boolean isTextPathSupported() { + if (textPathSupported == null) { + textPathSupported = Boolean.valueOf(Util.isWindows()); + } + return textPathSupported.booleanValue(); + } + + private GEF() { + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java b/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java index 9f139ee67..b2809f91d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java @@ -1,592 +1,592 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.List; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.LightweightSystem; -import org.eclipse.draw2d.Viewport; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.event.PartsEventDispatcher; -import org.xmind.gef.event.ViewerEventDispatcher; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IGraphicalRootPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.tool.SelectTool; - -/** - * @author Brian Sun - */ -public class GraphicalViewer extends AbstractViewer - implements IGraphicalViewer { - - private static final Point POINT = new Point(); - - protected class GraphicalSelectionSupport extends SelectionSupport { - - public boolean isSelectable(IPart p) { - boolean selectable = super.isSelectable(p); - if (selectable) { - if (p instanceof IGraphicalPart) { - IFigure fig = ((IGraphicalPart) p).getFigure(); - if (fig == null || !fig.isShowing()) - return false; - } - } - return selectable; - } - - protected void partSelectionChanged(List parts, - boolean reveal) { - super.partSelectionChanged(parts, reveal); - if (getEditDomain() != null) { - ITool tool = getEditDomain().getTool(GEF.TOOL_SELECT); - if (tool != null && tool instanceof SelectTool) { - ((SelectTool) tool).resetSeqSelectStart(); - } - IPart focused = findSelectablePart(getFocused()); - if (focused == null || !focused.getStatus().isActive() - || !focused.getStatus().isSelected()) { - setFocused(findSelectedPart(parts)); - } - } - } - - protected IPart findSelectedPart(List parts) { - for (IPart p : parts) { - if (p.getStatus().isActive() && p.getStatus().isSelected()) - return p; - } - return null; - } - } - - private LightweightSystem lws = createLightweightSystem(); - - private ILayerManager layerManager = null; - - private ViewerEventDispatcher eventDispatcher = createEventDispatcher(); - - private ZoomManager zoomManager = null; - - private Viewport viewport = new Viewport(true); - - public GraphicalViewer() { - super(); - lws.setEventDispatcher(eventDispatcher); - lws.setContents(viewport); - } - - public T getAdapter(Class adapter) { - if (LightweightSystem.class.equals(adapter)) - return adapter.cast(getLightweightSystem()); - if (ILayerManager.class.equals(adapter)) - return adapter.cast(getLayerManager()); - if (FigureCanvas.class.equals(adapter)) - return adapter.cast(getCanvas()); - if (ZoomManager.class.equals(adapter)) - return adapter.cast(getZoomManager()); - if (IGraphicalPart.class.equals(adapter)) - return adapter.cast(getRootPart() instanceof IGraphicalPart - ? getRootPart() : null); - if (IFigure.class.equals(adapter)) - return adapter.cast(getRootFigure()); - if (Viewport.class.equals(adapter)) - return adapter.cast(getViewport()); - return super.getAdapter(adapter); - } - - public IGraphicalPart findGraphicalPart(Object model) { - IPart part = findPart(model); - if (part instanceof IGraphicalPart) - return (IGraphicalPart) part; - return null; - } - - public IPart findPart(int x, int y) { - return findPart(convertPoint(x, y)); - } - - protected Point convertPoint(int controlX, int controlY) { - return computeToLayer(POINT.setLocation(controlX, controlY), true); - } - - protected IPart findPart(Point position) { - return findPart(getRootPart(), position); - } - - protected IPart findPart(IPart parent, Point position) { - if (parent == null || !(parent instanceof IGraphicalEditPart)) - return null; - return (((IGraphicalEditPart) parent).findAt(position, - getPartSearchCondition())); - } - - protected LightweightSystem createLightweightSystem() { - return new LightweightSystem(); - } - - public LightweightSystem getLightweightSystem() { - return lws; - } - - protected Viewport getViewport() { - return viewport; - } - - public Control createControl(Composite parent) { - return createControl(parent, SWT.DOUBLE_BUFFERED); - } - - protected Control internalCreateControl(Composite parent, int style) { - //FIXME - FigureCanvas canvas = new FigureCanvas(parent, style, - getLightweightSystem()) { - - @Override - public org.eclipse.swt.graphics.Rectangle computeTrim(int x, int y, - int width, int height) { - org.eclipse.swt.graphics.Rectangle trim = super.computeTrim(x, - y, width, height); - if (!getVerticalBar().isVisible()) { - trim.width = 0; - } - if (!getHorizontalBar().isVisible()) { - trim.height = 0; - } - - return trim; - } - }; - - canvas.setViewport(viewport); - return canvas; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.AbstractViewer#hookControl(org.eclipse.swt.widgets.Control) - */ - @Override - protected void hookControl(Control control) { - if (getEditDomain() != null) { - eventDispatcher.activate(); - } - super.hookControl(control); - } - - public void setRootPart(IRootPart rootPart) { - super.setRootPart(rootPart); - IFigure rootFigure = getRootFigure(); - if (rootFigure instanceof Viewport) { - viewport = (Viewport) rootFigure; - } else { - viewport = new Viewport(true); - viewport.setContents(rootFigure); - } - getLightweightSystem().setContents(viewport); - if (getCanvas() != null && !getCanvas().isDisposed()) { - getCanvas().setViewport(viewport); - } - } - - protected IFigure getRootFigure() { - if (getRootPart() instanceof IGraphicalPart) { - return ((IGraphicalPart) getRootPart()).getFigure(); - } - return null; - } - - protected void revalidateContents() { - getCanvas().layout(true); - } - - protected ViewerEventDispatcher createEventDispatcher() { - return new PartsEventDispatcher(this); - } - -// public ViewerEventDispatcher getEventDispatcher() { -// return eventDispatcher; -// } - - public void setEditDomain(EditDomain editDomain) { - if (getControl() != null && !getControl().isDisposed()) { - eventDispatcher.deactivate(); - } - super.setEditDomain(editDomain); - if (getEditDomain() != null && getControl() != null - && !getControl().isDisposed()) { - eventDispatcher.activate(); - } - } - - public Layer getLayer(Object key) { - return layerManager == null ? null : layerManager.getLayer(key); - } - - public ILayerManager getLayerManager() { - return layerManager; - } - - public void setLayerManager(ILayerManager layerManager) { - this.layerManager = layerManager; - } - - public void updateToolTip() { - if (getControl() != null && !getControl().isDisposed()) { - eventDispatcher.updateToolTip(); - } - } - - public void hideToolTip() { - if (getControl() != null) - getControl().setToolTipText(null); - } - - public FigureCanvas getCanvas() { - return (FigureCanvas) super.getControl(); - } - - public Dimension getSize() { - return new Dimension(getCanvas().getSize()); - } - - public Rectangle getClientArea() { - Rectangle area = new Rectangle(getCanvas().getClientArea()); - area.setLocation(getScrollPosition()); - return area; - } - - public Point getCenterPoint() { - return getViewport().getClientArea().getCenter(); - } - - public void center(Rectangle area) { - center(area.getCenter()); - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.IGraphicalViewer#center(int, int) - */ - public void center(int x, int y) { - Rectangle clientArea = getViewport().getClientArea(); - scrollTo(x - clientArea.width >> 1, y - clientArea.height >> 1); - } - - public void center(Point center) { - center(center.x, center.y); - } - - public void scrollToX(int x) { - if (usesSmoothScroll()) { - getViewport().setHorizontalLocation(x); - } else { - getCanvas().scrollToX(x); - } - } - - public void scrollToY(int y) { - if (usesSmoothScroll()) { - getViewport().setVerticalLocation(y); - } else { - getCanvas().scrollToY(y); - } - } - - public void scrollTo(Point p) { - scrollTo(p.x, p.y); - } - - public void scrollTo(int x, int y) { - if (usesSmoothScroll()) { - getViewport().setViewLocation(x, y); - } else { - getCanvas().scrollTo(x, y); - } - } - - protected boolean usesSmoothScroll() { - return Boolean.TRUE.equals(getProperties().get(VIEWER_SCROLL_SMOOTH)); - } - - /** - * @see org.xmind.gef.IViewer#scrollDelta(org.eclipse.draw2d.geometry.Dimension) - */ - public void scrollDelta(Dimension d) { - scrollTo(getScrollPosition().translate(d)); - } - - /** - * @see org.xmind.gef.IGraphicalViewer#scrollDelta(int, int) - */ - public void scrollDelta(int dx, int dy) { - scrollTo(getScrollPosition().translate(dx, dy)); - } - - /** - * @see org.xmind.gef.IViewer#getScrollPosition() - */ - public Point getScrollPosition() { - return getViewport().getViewLocation(); - } - - /** - * @see org.xmind.gef.IGraphicalViewer#computeToLayer(org.eclipse.draw2d.geometry.Point, - * boolean) - */ - public Point computeToLayer(Point controlPoint, boolean zoomed) { - Point p = getScrollPosition(); - p.translate(controlPoint); - if (zoomed) { - return p.scale(1 / getZoomManager().getScale()); - } - return p; - } - - /** - * @see org.xmind.gef.IGraphicalViewer#computeToControl(org.eclipse.draw2d.geometry.Point, - * boolean) - */ - public Point computeToControl(Point layerPoint, boolean zoomed) { - POINT.setLocation(layerPoint); - if (zoomed) { - POINT.scale(getZoomManager().getScale()); - } - return getScrollPosition().negate().translate(POINT); - } - - public Point computeToDisplay(Point layerPoint, boolean zoomed) { - Point p = computeToControl(layerPoint, zoomed); - org.eclipse.swt.graphics.Point loc = getControl().toDisplay(p.x, p.y); - return p.setLocation(loc.x, loc.y); - } - - public void ensureVisible(Rectangle box) { - box = getZoomManager().getScaled(box); - Rectangle clientArea = getClientArea(); - if (clientArea.contains(box) || box.contains(clientArea)) - return; - ensureVisible(box, clientArea, 0); - } - - public void ensureControlVisible(Rectangle box) { - Rectangle clientArea = new Rectangle(getCanvas().getClientArea()); - if (clientArea.contains(box) || box.contains(clientArea)) - return; - ensureVisible(box, clientArea, 0); - } - - /** - * @param box - * @param clientArea - * @param margin - */ - protected void ensureVisible(Rectangle box, Rectangle clientArea, - int margin) { - int dx = 0; - int dy = 0; - if (box.width > clientArea.width) - dx = box.getCenter().x - clientArea.getCenter().x; - else if (box.x < clientArea.x) - dx = box.x - clientArea.x - margin; - else if (box.right() > clientArea.right()) - dx = box.right() - clientArea.right() + margin; - if (box.height > clientArea.height) - dy = box.getCenter().y - clientArea.getCenter().y; - else if (box.y < clientArea.y) - dy = box.y - clientArea.y - margin; - else if (box.bottom() > clientArea.bottom()) - dy = box.bottom() - clientArea.bottom() + margin; - smoothScrollDelta(dx, dy); - } - - /** - * @param dx - * @param dy - */ - protected void smoothScrollDelta(int dx, int dy) { - scrollDelta(dx, dy); - } - - protected IGraphicalRootPart getGraphicalRootEditPart() { - IRootPart rootPart = getRootPart(); - if (rootPart instanceof IGraphicalRootPart) { - return (IGraphicalRootPart) rootPart; - } - return null; - } - - protected ISelectionSupport createSelectionSupport() { - return new GraphicalSelectionSupport(); - } - - protected void inputChanged(Object input, Object oldInput) { - boolean controlAvailable = getControl() != null - && !getControl().isDisposed(); - if (controlAvailable) { - getControl().setRedraw(false); - } - - ISelection oldSelection = getSelection(); - setSelectionOnInputChanged(StructuredSelection.EMPTY); - double oldScale = getZoomManager().getScale(); - if (controlAvailable && getEditDomain() != null) { - eventDispatcher.deactivate(); - } - internalInputChanged(input, oldInput); - if (controlAvailable && getEditDomain() != null) { - eventDispatcher.activate(); - } - setSelectionOnInputChanged(oldSelection); - if (oldScale >= 0) { - getZoomManager().setScale(oldScale); - } - if (controlAvailable) { - getControl().setRedraw(true); - } - } - - protected void setSelectionOnInputChanged(ISelection selection) { - setSelection(selection); - } - - protected void internalInputChanged(Object input, Object oldInput) { - super.inputChanged(input, oldInput); - } - -// /** -// * @param x -// * @param y -// */ -// protected void alternativeScrollTo(int x, int y) { -// int hOffset = verifyScrollBarOffset(getViewport() -// .getHorizontalRangeModel(), x); -// int vOffset = verifyScrollBarOffset(getViewport() -// .getVerticalRangeModel(), y); -// -// int hOffsetOld = getViewport().getViewLocation().x; -// if (hOffset == hOffsetOld) { -// scrollToY(y); -// return; -// } -// int dx = -hOffset + hOffsetOld; -// -// int vOffsetOld = getViewport().getViewLocation().y; -// if (vOffset == vOffsetOld) { -// scrollToX(x); -// return; -// } -// int dy = -vOffset + vOffsetOld; -// -// Rectangle clientArea = getViewport().getBounds() -// .getCropped(getViewport().getInsets()); -// Rectangle blit = clientArea.getResized(-Math.abs(dx), -Math.abs(dy)); -// Rectangle expose = clientArea.getCopy(); -// Rectangle expose2 = clientArea.getCopy(); -// Point dest = clientArea.getTopLeft(); -// expose.width = Math.abs(dx); -// if (dx < 0) { //Moving left? -// blit.translate(-dx, 0); //Move blit area to the right -// expose.x = dest.x + blit.width; -// } else -// //Moving right -// dest.x += dx; //Move expose area to the right -// -// expose2.height = Math.abs(dy); -// if (dy < 0) { //Moving up? -// blit.translate(0, -dy); //Move blit area down -// expose2.y = dest.y + blit.height; //Move expose area down -// } else -// //Moving down -// dest.y += dy; -// -// // fix for bug 41111 -// Control[] children = getCanvas().getChildren(); -// boolean[] manualMove = new boolean[children.length]; -// for (int i = 0; i < children.length; i++) { -// org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds(); -// manualMove[i] = blit.width <= 0 || blit.height < 0 -// || bounds.x > blit.x + blit.width -// || bounds.y > blit.y + blit.height -// || bounds.x + bounds.width < blit.x -// || bounds.y + bounds.height < blit.y; -// } -// getCanvas().scroll(dest.x, dest.y, blit.x, blit.y, blit.width, -// blit.height, true); -// -// for (int i = 0; i < children.length; i++) { -// org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds(); -// if (manualMove[i]) -// children[i].setBounds(bounds.x + dx, bounds.y, bounds.width, -// bounds.height); -// } -// -// getViewport().setIgnoreScroll(true); -// getViewport().setHorizontalLocation(hOffset); -// getViewport().setVerticalLocation(vOffset); -// getViewport().setIgnoreScroll(false); -// getCanvas().redraw(expose.x, expose.y, expose.width, expose.height, -// true); -// getCanvas().redraw(expose2.x, expose2.y, expose2.width, expose2.height, -// true); -// } -// -// private int verifyScrollBarOffset(RangeModel model, int value) { -// value = Math.max(model.getMinimum(), value); -// return Math.min(model.getMaximum() - model.getExtent(), value); -// } - - public ZoomManager getZoomManager() { - if (zoomManager == null) - zoomManager = new ZoomManager(); - return zoomManager; - } - - public void setZoomManager(ZoomManager zoomManager) { - this.zoomManager = zoomManager; - } - - public void setDndSupport(IDndSupport dndSupport) { - super.setDndSupport(dndSupport); - eventDispatcher.setDndSupport(dndSupport); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.AbstractViewer#setCursor(org.eclipse.swt.graphics.Cursor) - */ - @Override - public void setCursor(Cursor cursor) { - eventDispatcher.setOverridingCursor(cursor); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.List; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.LightweightSystem; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.event.PartsEventDispatcher; +import org.xmind.gef.event.ViewerEventDispatcher; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IGraphicalRootPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.tool.SelectTool; + +/** + * @author Brian Sun + */ +public class GraphicalViewer extends AbstractViewer + implements IGraphicalViewer { + + private static final Point POINT = new Point(); + + protected class GraphicalSelectionSupport extends SelectionSupport { + + public boolean isSelectable(IPart p) { + boolean selectable = super.isSelectable(p); + if (selectable) { + if (p instanceof IGraphicalPart) { + IFigure fig = ((IGraphicalPart) p).getFigure(); + if (fig == null || !fig.isShowing()) + return false; + } + } + return selectable; + } + + protected void partSelectionChanged(List parts, + boolean reveal) { + super.partSelectionChanged(parts, reveal); + if (getEditDomain() != null) { + ITool tool = getEditDomain().getTool(GEF.TOOL_SELECT); + if (tool != null && tool instanceof SelectTool) { + ((SelectTool) tool).resetSeqSelectStart(); + } + IPart focused = findSelectablePart(getFocused()); + if (focused == null || !focused.getStatus().isActive() + || !focused.getStatus().isSelected()) { + setFocused(findSelectedPart(parts)); + } + } + } + + protected IPart findSelectedPart(List parts) { + for (IPart p : parts) { + if (p.getStatus().isActive() && p.getStatus().isSelected()) + return p; + } + return null; + } + } + + private LightweightSystem lws = createLightweightSystem(); + + private ILayerManager layerManager = null; + + private ViewerEventDispatcher eventDispatcher = createEventDispatcher(); + + private ZoomManager zoomManager = null; + + private Viewport viewport = new Viewport(true); + + public GraphicalViewer() { + super(); + lws.setEventDispatcher(eventDispatcher); + lws.setContents(viewport); + } + + public T getAdapter(Class adapter) { + if (LightweightSystem.class.equals(adapter)) + return adapter.cast(getLightweightSystem()); + if (ILayerManager.class.equals(adapter)) + return adapter.cast(getLayerManager()); + if (FigureCanvas.class.equals(adapter)) + return adapter.cast(getCanvas()); + if (ZoomManager.class.equals(adapter)) + return adapter.cast(getZoomManager()); + if (IGraphicalPart.class.equals(adapter)) + return adapter.cast(getRootPart() instanceof IGraphicalPart + ? getRootPart() : null); + if (IFigure.class.equals(adapter)) + return adapter.cast(getRootFigure()); + if (Viewport.class.equals(adapter)) + return adapter.cast(getViewport()); + return super.getAdapter(adapter); + } + + public IGraphicalPart findGraphicalPart(Object model) { + IPart part = findPart(model); + if (part instanceof IGraphicalPart) + return (IGraphicalPart) part; + return null; + } + + public IPart findPart(int x, int y) { + return findPart(convertPoint(x, y)); + } + + protected Point convertPoint(int controlX, int controlY) { + return computeToLayer(POINT.setLocation(controlX, controlY), true); + } + + protected IPart findPart(Point position) { + return findPart(getRootPart(), position); + } + + protected IPart findPart(IPart parent, Point position) { + if (parent == null || !(parent instanceof IGraphicalEditPart)) + return null; + return (((IGraphicalEditPart) parent).findAt(position, + getPartSearchCondition())); + } + + protected LightweightSystem createLightweightSystem() { + return new LightweightSystem(); + } + + public LightweightSystem getLightweightSystem() { + return lws; + } + + protected Viewport getViewport() { + return viewport; + } + + public Control createControl(Composite parent) { + return createControl(parent, SWT.DOUBLE_BUFFERED); + } + + protected Control internalCreateControl(Composite parent, int style) { + //FIXME + FigureCanvas canvas = new FigureCanvas(parent, style, + getLightweightSystem()) { + + @Override + public org.eclipse.swt.graphics.Rectangle computeTrim(int x, int y, + int width, int height) { + org.eclipse.swt.graphics.Rectangle trim = super.computeTrim(x, + y, width, height); + if (!getVerticalBar().isVisible()) { + trim.width = 0; + } + if (!getHorizontalBar().isVisible()) { + trim.height = 0; + } + + return trim; + } + }; + + canvas.setViewport(viewport); + return canvas; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.AbstractViewer#hookControl(org.eclipse.swt.widgets.Control) + */ + @Override + protected void hookControl(Control control) { + if (getEditDomain() != null) { + eventDispatcher.activate(); + } + super.hookControl(control); + } + + public void setRootPart(IRootPart rootPart) { + super.setRootPart(rootPart); + IFigure rootFigure = getRootFigure(); + if (rootFigure instanceof Viewport) { + viewport = (Viewport) rootFigure; + } else { + viewport = new Viewport(true); + viewport.setContents(rootFigure); + } + getLightweightSystem().setContents(viewport); + if (getCanvas() != null && !getCanvas().isDisposed()) { + getCanvas().setViewport(viewport); + } + } + + protected IFigure getRootFigure() { + if (getRootPart() instanceof IGraphicalPart) { + return ((IGraphicalPart) getRootPart()).getFigure(); + } + return null; + } + + protected void revalidateContents() { + getCanvas().layout(true); + } + + protected ViewerEventDispatcher createEventDispatcher() { + return new PartsEventDispatcher(this); + } + +// public ViewerEventDispatcher getEventDispatcher() { +// return eventDispatcher; +// } + + public void setEditDomain(EditDomain editDomain) { + if (getControl() != null && !getControl().isDisposed()) { + eventDispatcher.deactivate(); + } + super.setEditDomain(editDomain); + if (getEditDomain() != null && getControl() != null + && !getControl().isDisposed()) { + eventDispatcher.activate(); + } + } + + public Layer getLayer(Object key) { + return layerManager == null ? null : layerManager.getLayer(key); + } + + public ILayerManager getLayerManager() { + return layerManager; + } + + public void setLayerManager(ILayerManager layerManager) { + this.layerManager = layerManager; + } + + public void updateToolTip() { + if (getControl() != null && !getControl().isDisposed()) { + eventDispatcher.updateToolTip(); + } + } + + public void hideToolTip() { + if (getControl() != null) + getControl().setToolTipText(null); + } + + public FigureCanvas getCanvas() { + return (FigureCanvas) super.getControl(); + } + + public Dimension getSize() { + return new Dimension(getCanvas().getSize()); + } + + public Rectangle getClientArea() { + Rectangle area = new Rectangle(getCanvas().getClientArea()); + area.setLocation(getScrollPosition()); + return area; + } + + public Point getCenterPoint() { + return getViewport().getClientArea().getCenter(); + } + + public void center(Rectangle area) { + center(area.getCenter()); + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.IGraphicalViewer#center(int, int) + */ + public void center(int x, int y) { + Rectangle clientArea = getViewport().getClientArea(); + scrollTo(x - clientArea.width >> 1, y - clientArea.height >> 1); + } + + public void center(Point center) { + center(center.x, center.y); + } + + public void scrollToX(int x) { + if (usesSmoothScroll()) { + getViewport().setHorizontalLocation(x); + } else { + getCanvas().scrollToX(x); + } + } + + public void scrollToY(int y) { + if (usesSmoothScroll()) { + getViewport().setVerticalLocation(y); + } else { + getCanvas().scrollToY(y); + } + } + + public void scrollTo(Point p) { + scrollTo(p.x, p.y); + } + + public void scrollTo(int x, int y) { + if (usesSmoothScroll()) { + getViewport().setViewLocation(x, y); + } else { + getCanvas().scrollTo(x, y); + } + } + + protected boolean usesSmoothScroll() { + return Boolean.TRUE.equals(getProperties().get(VIEWER_SCROLL_SMOOTH)); + } + + /** + * @see org.xmind.gef.IViewer#scrollDelta(org.eclipse.draw2d.geometry.Dimension) + */ + public void scrollDelta(Dimension d) { + scrollTo(getScrollPosition().translate(d)); + } + + /** + * @see org.xmind.gef.IGraphicalViewer#scrollDelta(int, int) + */ + public void scrollDelta(int dx, int dy) { + scrollTo(getScrollPosition().translate(dx, dy)); + } + + /** + * @see org.xmind.gef.IViewer#getScrollPosition() + */ + public Point getScrollPosition() { + return getViewport().getViewLocation(); + } + + /** + * @see org.xmind.gef.IGraphicalViewer#computeToLayer(org.eclipse.draw2d.geometry.Point, + * boolean) + */ + public Point computeToLayer(Point controlPoint, boolean zoomed) { + Point p = getScrollPosition(); + p.translate(controlPoint); + if (zoomed) { + return p.scale(1 / getZoomManager().getScale()); + } + return p; + } + + /** + * @see org.xmind.gef.IGraphicalViewer#computeToControl(org.eclipse.draw2d.geometry.Point, + * boolean) + */ + public Point computeToControl(Point layerPoint, boolean zoomed) { + POINT.setLocation(layerPoint); + if (zoomed) { + POINT.scale(getZoomManager().getScale()); + } + return getScrollPosition().negate().translate(POINT); + } + + public Point computeToDisplay(Point layerPoint, boolean zoomed) { + Point p = computeToControl(layerPoint, zoomed); + org.eclipse.swt.graphics.Point loc = getControl().toDisplay(p.x, p.y); + return p.setLocation(loc.x, loc.y); + } + + public void ensureVisible(Rectangle box) { + box = getZoomManager().getScaled(box); + Rectangle clientArea = getClientArea(); + if (clientArea.contains(box) || box.contains(clientArea)) + return; + ensureVisible(box, clientArea, 0); + } + + public void ensureControlVisible(Rectangle box) { + Rectangle clientArea = new Rectangle(getCanvas().getClientArea()); + if (clientArea.contains(box) || box.contains(clientArea)) + return; + ensureVisible(box, clientArea, 0); + } + + /** + * @param box + * @param clientArea + * @param margin + */ + protected void ensureVisible(Rectangle box, Rectangle clientArea, + int margin) { + int dx = 0; + int dy = 0; + if (box.width > clientArea.width) + dx = box.getCenter().x - clientArea.getCenter().x; + else if (box.x < clientArea.x) + dx = box.x - clientArea.x - margin; + else if (box.right() > clientArea.right()) + dx = box.right() - clientArea.right() + margin; + if (box.height > clientArea.height) + dy = box.getCenter().y - clientArea.getCenter().y; + else if (box.y < clientArea.y) + dy = box.y - clientArea.y - margin; + else if (box.bottom() > clientArea.bottom()) + dy = box.bottom() - clientArea.bottom() + margin; + smoothScrollDelta(dx, dy); + } + + /** + * @param dx + * @param dy + */ + protected void smoothScrollDelta(int dx, int dy) { + scrollDelta(dx, dy); + } + + protected IGraphicalRootPart getGraphicalRootEditPart() { + IRootPart rootPart = getRootPart(); + if (rootPart instanceof IGraphicalRootPart) { + return (IGraphicalRootPart) rootPart; + } + return null; + } + + protected ISelectionSupport createSelectionSupport() { + return new GraphicalSelectionSupport(); + } + + protected void inputChanged(Object input, Object oldInput) { + boolean controlAvailable = getControl() != null + && !getControl().isDisposed(); + if (controlAvailable) { + getControl().setRedraw(false); + } + + ISelection oldSelection = getSelection(); + setSelectionOnInputChanged(StructuredSelection.EMPTY); + double oldScale = getZoomManager().getScale(); + if (controlAvailable && getEditDomain() != null) { + eventDispatcher.deactivate(); + } + internalInputChanged(input, oldInput); + if (controlAvailable && getEditDomain() != null) { + eventDispatcher.activate(); + } + setSelectionOnInputChanged(oldSelection); + if (oldScale >= 0) { + getZoomManager().setScale(oldScale); + } + if (controlAvailable) { + getControl().setRedraw(true); + } + } + + protected void setSelectionOnInputChanged(ISelection selection) { + setSelection(selection); + } + + protected void internalInputChanged(Object input, Object oldInput) { + super.inputChanged(input, oldInput); + } + +// /** +// * @param x +// * @param y +// */ +// protected void alternativeScrollTo(int x, int y) { +// int hOffset = verifyScrollBarOffset(getViewport() +// .getHorizontalRangeModel(), x); +// int vOffset = verifyScrollBarOffset(getViewport() +// .getVerticalRangeModel(), y); +// +// int hOffsetOld = getViewport().getViewLocation().x; +// if (hOffset == hOffsetOld) { +// scrollToY(y); +// return; +// } +// int dx = -hOffset + hOffsetOld; +// +// int vOffsetOld = getViewport().getViewLocation().y; +// if (vOffset == vOffsetOld) { +// scrollToX(x); +// return; +// } +// int dy = -vOffset + vOffsetOld; +// +// Rectangle clientArea = getViewport().getBounds() +// .getCropped(getViewport().getInsets()); +// Rectangle blit = clientArea.getResized(-Math.abs(dx), -Math.abs(dy)); +// Rectangle expose = clientArea.getCopy(); +// Rectangle expose2 = clientArea.getCopy(); +// Point dest = clientArea.getTopLeft(); +// expose.width = Math.abs(dx); +// if (dx < 0) { //Moving left? +// blit.translate(-dx, 0); //Move blit area to the right +// expose.x = dest.x + blit.width; +// } else +// //Moving right +// dest.x += dx; //Move expose area to the right +// +// expose2.height = Math.abs(dy); +// if (dy < 0) { //Moving up? +// blit.translate(0, -dy); //Move blit area down +// expose2.y = dest.y + blit.height; //Move expose area down +// } else +// //Moving down +// dest.y += dy; +// +// // fix for bug 41111 +// Control[] children = getCanvas().getChildren(); +// boolean[] manualMove = new boolean[children.length]; +// for (int i = 0; i < children.length; i++) { +// org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds(); +// manualMove[i] = blit.width <= 0 || blit.height < 0 +// || bounds.x > blit.x + blit.width +// || bounds.y > blit.y + blit.height +// || bounds.x + bounds.width < blit.x +// || bounds.y + bounds.height < blit.y; +// } +// getCanvas().scroll(dest.x, dest.y, blit.x, blit.y, blit.width, +// blit.height, true); +// +// for (int i = 0; i < children.length; i++) { +// org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds(); +// if (manualMove[i]) +// children[i].setBounds(bounds.x + dx, bounds.y, bounds.width, +// bounds.height); +// } +// +// getViewport().setIgnoreScroll(true); +// getViewport().setHorizontalLocation(hOffset); +// getViewport().setVerticalLocation(vOffset); +// getViewport().setIgnoreScroll(false); +// getCanvas().redraw(expose.x, expose.y, expose.width, expose.height, +// true); +// getCanvas().redraw(expose2.x, expose2.y, expose2.width, expose2.height, +// true); +// } +// +// private int verifyScrollBarOffset(RangeModel model, int value) { +// value = Math.max(model.getMinimum(), value); +// return Math.min(model.getMaximum() - model.getExtent(), value); +// } + + public ZoomManager getZoomManager() { + if (zoomManager == null) + zoomManager = new ZoomManager(); + return zoomManager; + } + + public void setZoomManager(ZoomManager zoomManager) { + this.zoomManager = zoomManager; + } + + public void setDndSupport(IDndSupport dndSupport) { + super.setDndSupport(dndSupport); + eventDispatcher.setDndSupport(dndSupport); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.AbstractViewer#setCursor(org.eclipse.swt.graphics.Cursor) + */ + @Override + public void setCursor(Cursor cursor) { + eventDispatcher.setOverridingCursor(cursor); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable.java b/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable.java index 54ab6336c..268c26d87 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -/** - * - * @author Frank Shaka - * - */ -public interface IDisposable { - - void dispose(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +/** + * + * @author Frank Shaka + * + */ +public interface IDisposable { + + void dispose(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable2.java b/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable2.java index 1d6a91fc7..d9fa21bad 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IDisposable2.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -public interface IDisposable2 extends IDisposable { - - boolean isDisposed(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +public interface IDisposable2 extends IDisposable { + + boolean isDisposed(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IEditDomainListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/IEditDomainListener.java index 88139f079..fce9cdbea 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IEditDomainListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IEditDomainListener.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import org.xmind.gef.tool.ITool; - -/** - * @author Frank Shaka - */ -public interface IEditDomainListener { - - public abstract void activeToolChanged(ITool oldTool, ITool newTool); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import org.xmind.gef.tool.ITool; + +/** + * @author Frank Shaka + */ +public interface IEditDomainListener { + + public abstract void activeToolChanged(ITool oldTool, ITool newTool); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IGraphicalViewer.java b/bundles/org.xmind.gef/src/org/xmind/gef/IGraphicalViewer.java index fcf2c485b..b43c726a8 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IGraphicalViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IGraphicalViewer.java @@ -1,116 +1,118 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.part.IGraphicalPart; - -/** - * @author Brian Sun - */ -public interface IGraphicalViewer extends IViewer { - - /** - * A viewer property indicating that this viewer uses 'smooth scrolling' - * behaviour when the canvas is to be moved to a desired view location by - * calling 'scrollTo', 'scrollToX', or 'scrollToY', etc. By turning on - * 'smooth scrolling', the viewer always modifies the viewport's range model - * before updating the canvas, while the default behaviour determines by - * itself when to update the canvas first for efficient painting and - * repainting. 'Smooth scrolling' is typically useful when some figure is - * wanted to stay in a steady position relative to the viewport's client - * area and not to be moved with the canvas before the range model is - * modified. - *

- * Values: Boolean, true to use smooth scroll, - * false otherwise. - *

- */ - String VIEWER_SCROLL_SMOOTH = "scrollSmooth"; //$NON-NLS-1$ - - /** - * A viewer property indicating that the viewer ignores scroll events when - * the cursor is not moved by user while the viewport is being scrolled. The - * default behaviour is to convert scroll events into new 'mouse move' - * events to dispatch. - *

- * Values: Boolean, true to ignore scroll event, - * false otherwise. - *

- */ - String VIEWER_IGNORE_SCROLL_EVENT = "ignoreScrollEvent"; //$NON-NLS-1$ - - /** - * A viewer property indicating that all text figures should be rendered as - * a path. - *

- * Values: Boolean, true to render text as paths, - * false to use default renderer. - *

- */ - String VIEWER_RENDER_TEXT_AS_PATH = "renderTextAsPath"; //$NON-NLS-1$ - - FigureCanvas getCanvas(); - - Dimension getSize(); - - Rectangle getClientArea(); - - void scrollToX(int x); - - void scrollToY(int x); - - void scrollTo(Point p); - - void scrollTo(int x, int y); - - void scrollDelta(Dimension d); - - void scrollDelta(int dx, int dy); - - Point getScrollPosition(); - - void ensureVisible(Rectangle box); - - void center(int x, int y); - - void center(Point cen); - - void center(Rectangle area); - - Point computeToLayer(Point controlPoint, boolean zoomed); - - Point computeToControl(Point layerPoint, boolean zoomed); - - Point computeToDisplay(Point layerPoint, boolean zoomed); - - Point getCenterPoint(); - - Layer getLayer(Object key); - - ILayerManager getLayerManager(); - - void setLayerManager(ILayerManager layerManager); - - ZoomManager getZoomManager(); - - void setZoomManager(ZoomManager zoomManager); - - IGraphicalPart findGraphicalPart(Object model); - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.part.IGraphicalPart; + +/** + * @author Brian Sun + */ +public interface IGraphicalViewer extends IViewer { + + /** + * A viewer property indicating that this viewer uses 'smooth scrolling' + * behaviour when the canvas is to be moved to a desired view location by + * calling 'scrollTo', 'scrollToX', or 'scrollToY', etc. By turning on + * 'smooth scrolling', the viewer always modifies the viewport's range model + * before updating the canvas, while the default behaviour determines by + * itself when to update the canvas first for efficient painting and + * repainting. 'Smooth scrolling' is typically useful when some figure is + * wanted to stay in a steady position relative to the viewport's client + * area and not to be moved with the canvas before the range model is + * modified. + *

+ * Values: Boolean, true to use smooth scroll, + * false otherwise. + *

+ */ + String VIEWER_SCROLL_SMOOTH = "scrollSmooth"; //$NON-NLS-1$ + + /** + * A viewer property indicating that the viewer ignores scroll events when + * the cursor is not moved by user while the viewport is being scrolled. The + * default behaviour is to convert scroll events into new 'mouse move' + * events to dispatch. + *

+ * Values: Boolean, true to ignore scroll event, + * false otherwise. + *

+ */ + String VIEWER_IGNORE_SCROLL_EVENT = "ignoreScrollEvent"; //$NON-NLS-1$ + + String VIEWER_START_DRAG_THRESHOLD = "startDragThreshold"; //$NON-NLS-1$ + + /** + * A viewer property indicating that all text figures should be rendered as + * a path. + *

+ * Values: Boolean, true to render text as paths, + * false to use default renderer. + *

+ */ + String VIEWER_RENDER_TEXT_AS_PATH = "renderTextAsPath"; //$NON-NLS-1$ + + FigureCanvas getCanvas(); + + Dimension getSize(); + + Rectangle getClientArea(); + + void scrollToX(int x); + + void scrollToY(int x); + + void scrollTo(Point p); + + void scrollTo(int x, int y); + + void scrollDelta(Dimension d); + + void scrollDelta(int dx, int dy); + + Point getScrollPosition(); + + void ensureVisible(Rectangle box); + + void center(int x, int y); + + void center(Point cen); + + void center(Rectangle area); + + Point computeToLayer(Point controlPoint, boolean zoomed); + + Point computeToControl(Point layerPoint, boolean zoomed); + + Point computeToDisplay(Point layerPoint, boolean zoomed); + + Point getCenterPoint(); + + Layer getLayer(Object key); + + ILayerManager getLayerManager(); + + void setLayerManager(ILayerManager layerManager); + + ZoomManager getZoomManager(); + + void setZoomManager(ZoomManager zoomManager); + + IGraphicalPart findGraphicalPart(Object model); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IInputChangedListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/IInputChangedListener.java index 557bf047d..afba4fa61 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IInputChangedListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IInputChangedListener.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef; - -/** - * @author Frank Shaka - * - */ -public interface IInputChangedListener { - - void inputChanged(IViewer viewer, Object newInput, Object oldInput); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef; + +/** + * @author Frank Shaka + * + */ +public interface IInputChangedListener { + + void inputChanged(IViewer viewer, Object newInput, Object oldInput); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/ISourceProvider2.java b/bundles/org.xmind.gef/src/org/xmind/gef/ISourceProvider2.java index 8f348d6ff..948e301b0 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/ISourceProvider2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/ISourceProvider2.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -public interface ISourceProvider2 extends ISourceProvider { - - boolean isSourceCollectable(); - - void setSourceCollectable(boolean collectable); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +public interface ISourceProvider2 extends ISourceProvider { + + boolean isSourceCollectable(); + + void setSourceCollectable(boolean collectable); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java b/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java index b6340517e..794b3abe9 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java @@ -1,140 +1,140 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.viewers.IInputSelectionProvider; -import org.eclipse.jface.viewers.IPostSelectionProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Control; -import org.xmind.gef.acc.AccessibleRegistry; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IPartFactory; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.part.PartRegistry; -import org.xmind.gef.service.IViewerService; -import org.xmind.gef.util.Properties; - -/** - * @author Brian Sun - */ -public interface IViewer - extends IAdaptable, IInputSelectionProvider, IPostSelectionProvider { - - public static interface IPartSearchCondition { - - boolean evaluate(IPart part); - - } - - Control getControl(); - - EditDomain getEditDomain(); - - void setEditDomain(EditDomain domain); - - void setInput(Object input); - - void setSelection(ISelection selection, boolean reveal); - - ISelectionSupport getSelectionSupport(); - - void reveal(Object[] elements); - - void updateToolTip(); - - void setCursor(Cursor cursor); - - void addFilter(ViewerFilter filter); - - void removeFilter(ViewerFilter filter); - - ViewerFilter[] getFilters(); - - void setFilters(ViewerFilter[] filters); - - ViewerSorter getSorter(); - - void setSorter(ViewerSorter sorter); - - ViewerComparator getComparator(); - - void setComparator(ViewerComparator comparator); - - IRootPart getRootPart(); - - void setRootPart(IRootPart rootPart); - - IPartFactory getPartFactory(); - - void setPartFactory(IPartFactory partFactory); - - PartRegistry getPartRegistry(); - - IPart findPart(Object element); - - /** - * Coordinates represents position relative to the viewer's control. - * - * @param x - * @param y - * @return - */ - IPart findPart(int x, int y); - - void setPartSearchCondition(IPartSearchCondition condition); - - IPartSearchCondition getPartSearchCondition(); - - Properties getProperties(); - - IDndSupport getDndSupport(); - - AccessibleRegistry getAccessibleRegistry(); - - Object getPreselected(); - - IPart getPreselectedPart(); - - void setPreselected(Object element); - - Object getFocused(); - - IPart getFocusedPart(); - - void setFocused(Object element); - - void addPreSelectionChangedListener(ISelectionChangedListener listener); - - void removePreSelectionChangedListener(ISelectionChangedListener listener); - - void addInputChangedListener(IInputChangedListener listener); - - void removeInputChangedListener(IInputChangedListener listener); - - void addFocusedPartChangedListener(ISelectionChangedListener listener); - - void removeFocusedPartChangedListener(ISelectionChangedListener listener); - - IViewerService getService(Class serviceType); - - boolean hasService(Class serviceType); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.IInputSelectionProvider; +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Control; +import org.xmind.gef.acc.AccessibleRegistry; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IPartFactory; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.part.PartRegistry; +import org.xmind.gef.service.IViewerService; +import org.xmind.gef.util.Properties; + +/** + * @author Brian Sun + */ +public interface IViewer + extends IAdaptable, IInputSelectionProvider, IPostSelectionProvider { + + public static interface IPartSearchCondition { + + boolean evaluate(IPart part); + + } + + Control getControl(); + + EditDomain getEditDomain(); + + void setEditDomain(EditDomain domain); + + void setInput(Object input); + + void setSelection(ISelection selection, boolean reveal); + + ISelectionSupport getSelectionSupport(); + + void reveal(Object[] elements); + + void updateToolTip(); + + void setCursor(Cursor cursor); + + void addFilter(ViewerFilter filter); + + void removeFilter(ViewerFilter filter); + + ViewerFilter[] getFilters(); + + void setFilters(ViewerFilter[] filters); + + ViewerSorter getSorter(); + + void setSorter(ViewerSorter sorter); + + ViewerComparator getComparator(); + + void setComparator(ViewerComparator comparator); + + IRootPart getRootPart(); + + void setRootPart(IRootPart rootPart); + + IPartFactory getPartFactory(); + + void setPartFactory(IPartFactory partFactory); + + PartRegistry getPartRegistry(); + + IPart findPart(Object element); + + /** + * Coordinates represents position relative to the viewer's control. + * + * @param x + * @param y + * @return + */ + IPart findPart(int x, int y); + + void setPartSearchCondition(IPartSearchCondition condition); + + IPartSearchCondition getPartSearchCondition(); + + Properties getProperties(); + + IDndSupport getDndSupport(); + + AccessibleRegistry getAccessibleRegistry(); + + Object getPreselected(); + + IPart getPreselectedPart(); + + void setPreselected(Object element); + + Object getFocused(); + + IPart getFocusedPart(); + + void setFocused(Object element); + + void addPreSelectionChangedListener(ISelectionChangedListener listener); + + void removePreSelectionChangedListener(ISelectionChangedListener listener); + + void addInputChangedListener(IInputChangedListener listener); + + void removeInputChangedListener(IInputChangedListener listener); + + void addFocusedPartChangedListener(ISelectionChangedListener listener); + + void removeFocusedPartChangedListener(ISelectionChangedListener listener); + + IViewerService getService(Class serviceType); + + boolean hasService(Class serviceType); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/IZoomListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/IZoomListener.java index ef8f34db6..40901d972 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IZoomListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IZoomListener.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -/** - * @author Brian Sun - */ -public interface IZoomListener { - - public void scaleChanged(ZoomObject source, double oldValue, double newValue); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +/** + * @author Brian Sun + */ +public interface IZoomListener { + + public void scaleChanged(ZoomObject source, double oldValue, double newValue); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/Request.java b/bundles/org.xmind.gef/src/org/xmind/gef/Request.java index d84c09d53..c39d26ed7 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/Request.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/Request.java @@ -1,288 +1,288 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - * @version 2005 - */ -public class Request { - - private static final List EMPTY_SOURCES = Collections.emptyList(); - - private static final Map EMPTY_PARAMETERS = Collections - .emptyMap(); - - private static final Map EMPTY_RESULTS = Collections - .emptyMap(); - - private static final Collection EMPTY_NAMES = Collections - .emptyList(); - - private String type; - - private EditDomain domain; - - private IViewer viewer; - - private List targets; - - private Map parameters = null; - - private Map results = null; - - private boolean handled = false; - - /** - * @param type - */ - public Request(String type) { - if (type == null) - throw new IllegalArgumentException( - "A request's type must not be null."); //$NON-NLS-1$ - this.type = type; - } - - /** - * @return - */ - public String getType() { - return type; - } - -// /** -// * Change the type of this request. -// *

-// * NOTE: FOR INTERNAL USE ONLY!! -// *

-// * -// * @param type -// */ -// public void internalChangeType(String type) { -// this.type = type; -// } - - public EditDomain getDomain() { - return domain; - } - - public EditDomain getTargetDomain() { - if (domain != null) - return domain; - if (getTargetViewer() != null) - return getTargetViewer().getEditDomain(); - return null; - } - - public ICommandStack getTargetCommandStack() { - EditDomain targetDomain = getTargetDomain(); - if (targetDomain != null) - return targetDomain.getCommandStack(); - return null; - } - - public Request setDomain(EditDomain domain) { - this.domain = domain; - return this; - } - - public Request setViewer(IViewer viewer) { - this.viewer = viewer; - return this; - } - - public IViewer getTargetViewer() { - if (viewer != null) - return viewer; - IPart target = getPrimaryTarget(); - if (target != null) - return target.getSite().getViewer(); - return null; - } - - public List getTargets() { - return targets == null ? EMPTY_SOURCES : targets; - } - - public boolean hasTargets() { - return targets != null && !targets.isEmpty(); - } - - public Request setTargets(List parts) { - if (this.targets == null) { - if (!parts.isEmpty()) - this.targets = new ArrayList(parts); - } else { - this.targets.clear(); - this.targets.addAll(parts); - } - return this; - } - - public IPart getPrimaryTarget() { - return targets == null || targets.isEmpty() ? null : targets.get(0); - } - - public Request setPrimaryTarget(IPart part) { - if (part != null) { - if (targets == null) { - targets = new ArrayList(1); - targets.add(part); - } else { - targets.remove(part); - targets.add(0, part); - } - } - return this; - } - - public Map getParameters() { - return parameters == null ? EMPTY_PARAMETERS : Collections - .unmodifiableMap(parameters); - } - - public Request setParameter(String paramName, Object paramValue) { - if (parameters == null) - parameters = new HashMap(); - parameters.put(paramName, paramValue); - return this; - } - - public Request removeParameter(String paramName) { - if (parameters != null) { - parameters.remove(paramName); - if (parameters.isEmpty()) - parameters = null; - } - return this; - } - - public Request removeAllParameters() { - parameters = null; - return this; - } - - public Collection getParameterNames() { - if (parameters != null) - return parameters.keySet(); - return EMPTY_NAMES; - } - - public Request setParameters(Map parameters) { - if (parameters.isEmpty()) { - this.parameters = null; - } else { - if (this.parameters == null) { - this.parameters = new HashMap(parameters); - } else { - this.parameters.putAll(parameters); - } - } - return this; - } - - public Object getParameter(String paramName) { - return parameters == null ? null : parameters.get(paramName); - } - - public boolean isParameter(String paramName) { - if (parameters == null) - return false; - return Boolean.TRUE.equals(parameters.get(paramName)); - } - - public int getIntParameter(String paramName, int defaultValue) { - Object param = getParameter(paramName); - if (param instanceof Integer) - return ((Integer) param).intValue(); - return defaultValue; - } - - public double getDoubleParameter(String paramName, double defaultValue) { - Object param = getParameter(paramName); - if (param instanceof Double) - return ((Double) param).doubleValue(); - return defaultValue; - } - - public boolean hasParameter(String paramName) { - return parameters != null && parameters.containsKey(paramName); - } - - public Map getResults() { - return results == null ? EMPTY_RESULTS : Collections - .unmodifiableMap(results); - } - - public Request setResult(String resultName, Object resultValue) { - if (results == null) - results = new HashMap(); - results.put(resultName, resultValue); - return this; - } - - public Request removeResult(String resultName) { - if (results != null) { - results.remove(resultName); - if (results.isEmpty()) - results = null; - } - return this; - } - - public Request removeAllResults() { - results = null; - return this; - } - - public Request setResults(Map results) { - if (results.isEmpty()) { - this.results = null; - } else { - if (this.results == null) { - this.results = new HashMap(results); - } else { - this.results.putAll(results); - } - } - return this; - } - - public Object getResult(String resultName) { - return results == null ? null : results.get(resultName); - } - - public boolean hasResult(String resultName) { - return results != null && results.containsKey(resultName); - } - - public boolean isHandled() { - return this.handled; - } - - public void markHandled() { - this.handled = true; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + * @version 2005 + */ +public class Request { + + private static final List EMPTY_SOURCES = Collections.emptyList(); + + private static final Map EMPTY_PARAMETERS = Collections + .emptyMap(); + + private static final Map EMPTY_RESULTS = Collections + .emptyMap(); + + private static final Collection EMPTY_NAMES = Collections + .emptyList(); + + private String type; + + private EditDomain domain; + + private IViewer viewer; + + private List targets; + + private Map parameters = null; + + private Map results = null; + + private boolean handled = false; + + /** + * @param type + */ + public Request(String type) { + if (type == null) + throw new IllegalArgumentException( + "A request's type must not be null."); //$NON-NLS-1$ + this.type = type; + } + + /** + * @return + */ + public String getType() { + return type; + } + +// /** +// * Change the type of this request. +// *

+// * NOTE: FOR INTERNAL USE ONLY!! +// *

+// * +// * @param type +// */ +// public void internalChangeType(String type) { +// this.type = type; +// } + + public EditDomain getDomain() { + return domain; + } + + public EditDomain getTargetDomain() { + if (domain != null) + return domain; + if (getTargetViewer() != null) + return getTargetViewer().getEditDomain(); + return null; + } + + public ICommandStack getTargetCommandStack() { + EditDomain targetDomain = getTargetDomain(); + if (targetDomain != null) + return targetDomain.getCommandStack(); + return null; + } + + public Request setDomain(EditDomain domain) { + this.domain = domain; + return this; + } + + public Request setViewer(IViewer viewer) { + this.viewer = viewer; + return this; + } + + public IViewer getTargetViewer() { + if (viewer != null) + return viewer; + IPart target = getPrimaryTarget(); + if (target != null) + return target.getSite().getViewer(); + return null; + } + + public List getTargets() { + return targets == null ? EMPTY_SOURCES : targets; + } + + public boolean hasTargets() { + return targets != null && !targets.isEmpty(); + } + + public Request setTargets(List parts) { + if (this.targets == null) { + if (!parts.isEmpty()) + this.targets = new ArrayList(parts); + } else { + this.targets.clear(); + this.targets.addAll(parts); + } + return this; + } + + public IPart getPrimaryTarget() { + return targets == null || targets.isEmpty() ? null : targets.get(0); + } + + public Request setPrimaryTarget(IPart part) { + if (part != null) { + if (targets == null) { + targets = new ArrayList(1); + targets.add(part); + } else { + targets.remove(part); + targets.add(0, part); + } + } + return this; + } + + public Map getParameters() { + return parameters == null ? EMPTY_PARAMETERS : Collections + .unmodifiableMap(parameters); + } + + public Request setParameter(String paramName, Object paramValue) { + if (parameters == null) + parameters = new HashMap(); + parameters.put(paramName, paramValue); + return this; + } + + public Request removeParameter(String paramName) { + if (parameters != null) { + parameters.remove(paramName); + if (parameters.isEmpty()) + parameters = null; + } + return this; + } + + public Request removeAllParameters() { + parameters = null; + return this; + } + + public Collection getParameterNames() { + if (parameters != null) + return parameters.keySet(); + return EMPTY_NAMES; + } + + public Request setParameters(Map parameters) { + if (parameters.isEmpty()) { + this.parameters = null; + } else { + if (this.parameters == null) { + this.parameters = new HashMap(parameters); + } else { + this.parameters.putAll(parameters); + } + } + return this; + } + + public Object getParameter(String paramName) { + return parameters == null ? null : parameters.get(paramName); + } + + public boolean isParameter(String paramName) { + if (parameters == null) + return false; + return Boolean.TRUE.equals(parameters.get(paramName)); + } + + public int getIntParameter(String paramName, int defaultValue) { + Object param = getParameter(paramName); + if (param instanceof Integer) + return ((Integer) param).intValue(); + return defaultValue; + } + + public double getDoubleParameter(String paramName, double defaultValue) { + Object param = getParameter(paramName); + if (param instanceof Double) + return ((Double) param).doubleValue(); + return defaultValue; + } + + public boolean hasParameter(String paramName) { + return parameters != null && parameters.containsKey(paramName); + } + + public Map getResults() { + return results == null ? EMPTY_RESULTS : Collections + .unmodifiableMap(results); + } + + public Request setResult(String resultName, Object resultValue) { + if (results == null) + results = new HashMap(); + results.put(resultName, resultValue); + return this; + } + + public Request removeResult(String resultName) { + if (results != null) { + results.remove(resultName); + if (results.isEmpty()) + results = null; + } + return this; + } + + public Request removeAllResults() { + results = null; + return this; + } + + public Request setResults(Map results) { + if (results.isEmpty()) { + this.results = null; + } else { + if (this.results == null) { + this.results = new HashMap(results); + } else { + this.results.putAll(results); + } + } + return this; + } + + public Object getResult(String resultName) { + return results == null ? null : results.get(resultName); + } + + public boolean hasResult(String resultName) { + return results != null && results.containsKey(resultName); + } + + public boolean isHandled() { + return this.handled; + } + + public void markHandled() { + this.handled = true; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/SelectionStack.java b/bundles/org.xmind.gef/src/org/xmind/gef/SelectionStack.java index 049cbd1d8..abdc75758 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/SelectionStack.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/SelectionStack.java @@ -1,187 +1,187 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.command.ICommandStackListener; - -public class SelectionStack implements ISelectionStack, ICommandStackListener { - - private ISelectionProvider selectionProvider = null; - - private ICommandStack commandStack = null; - - private List selections = null; - - private int cursor = 0; - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.mindmap.editor.ISelectionStack#setSelectionProvider(org. - * eclipse.jface.viewers.ISelectionProvider) - */ - public void setSelectionProvider(ISelectionProvider selectionProvider) { - if (selectionProvider == this.selectionProvider) - return; - this.selectionProvider = selectionProvider; - this.selections = null; - this.cursor = 0; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.mindmap.editor.ISelectionStack#setCommandStack(org.xmind - * .gef.command.ICommandStack) - */ - public void setCommandStack(ICommandStack commandStack) { - ICommandStack oldCS = this.commandStack; - if (commandStack == oldCS) - return; - if (oldCS != null) { - oldCS.removeCSListener(this); - } - this.commandStack = commandStack; - if (commandStack != null) { - commandStack.addCSListener(this); - } - } - - public void handleCommandStackEvent(CommandStackEvent event) { - if (selectionProvider == null) - return; - - if (selections == null) - selections = new ArrayList(30); - - if ((event.getStatus() & GEF.CS_PRE_EXECUTE) != 0) - preExecute(); - else if ((event.getStatus() & GEF.CS_PRE_UNDO) != 0) - preUndo(); - else if ((event.getStatus() & GEF.CS_PRE_REDO) != 0) - preRedo(); - else if ((event.getStatus() & GEF.CS_POST_EXECUTE) != 0) - postExecute(); - else if ((event.getStatus() & GEF.CS_POST_UNDO) != 0) - postUndo(); - else if ((event.getStatus() & GEF.CS_POST_REDO) != 0) - postRedo(); - } - - /** - * Snapshots the current selection and push it into stack, and clear all - * cached selections from the current position on. - */ - protected void preExecute() { - clearFromCursor(); - if (cursor >= 0 && cursor <= selections.size()) { - ISelection selection = selectionProvider.getSelection(); - selections.add(cursor, selection); - } - } - - /** - * Clears all cached selections from the current position on. - */ - protected void clearFromCursor() { - if (cursor <= 0) { - selections.clear(); - } else { - while (cursor < selections.size()) { - selections.remove(selections.size() - 1); - } - } - } - - /** - * Try to preserve the previous selection after a command is executed. - */ - protected void postExecute() { - restoreSelection(); - ++cursor; - } - - /** - * Snapshots the current selection and push it into the stack if there's no - * selection on the current position before a command is about to be undone. - */ - protected void preUndo() { - ISelection selection = selectionProvider.getSelection(); - if (cursor == selections.size()) { - selections.add(cursor, selection); - } else if (cursor >= 0 && cursor < selections.size()) { -// ISelection cached = selections.get(cursor); -// if (cached == null) - selections.set(cursor, selection); - } - } - - /** - * Restores the previous selection that had been cached before this command - * was executed or redone. - */ - protected void postUndo() { - --cursor; - restoreSelection(); - } - - /** - * Snapshots the current selection and push it into the stack if there's no - * selection on the current position before a command is about to be redone. - */ - protected void preRedo() { - if (cursor >= 0 && cursor < selections.size()) { -// ISelection cached = selections.get(cursor); -// if (cached == null) { - ISelection selection = selectionProvider.getSelection(); - selections.set(cursor, selection); -// } - } else if (cursor == selections.size()) { - ISelection selection = selectionProvider.getSelection(); - selections.add(cursor, selection); - } - } - - /** - * Restores the previous selection that had been cached before this command - * was undone. - */ - protected void postRedo() { - ++cursor; - restoreSelection(); - } - - /** - * Restores the current selection to the selection provider. Does nothing is - * no selection is accessible. - */ - protected void restoreSelection() { - if (cursor >= 0 && cursor < selections.size()) { - ISelection selection = selections.get(cursor); - if (selection != null) { - selectionProvider.setSelection(selection); - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.command.ICommandStackListener; + +public class SelectionStack implements ISelectionStack, ICommandStackListener { + + private ISelectionProvider selectionProvider = null; + + private ICommandStack commandStack = null; + + private List selections = null; + + private int cursor = 0; + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.mindmap.editor.ISelectionStack#setSelectionProvider(org. + * eclipse.jface.viewers.ISelectionProvider) + */ + public void setSelectionProvider(ISelectionProvider selectionProvider) { + if (selectionProvider == this.selectionProvider) + return; + this.selectionProvider = selectionProvider; + this.selections = null; + this.cursor = 0; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.mindmap.editor.ISelectionStack#setCommandStack(org.xmind + * .gef.command.ICommandStack) + */ + public void setCommandStack(ICommandStack commandStack) { + ICommandStack oldCS = this.commandStack; + if (commandStack == oldCS) + return; + if (oldCS != null) { + oldCS.removeCSListener(this); + } + this.commandStack = commandStack; + if (commandStack != null) { + commandStack.addCSListener(this); + } + } + + public void handleCommandStackEvent(CommandStackEvent event) { + if (selectionProvider == null) + return; + + if (selections == null) + selections = new ArrayList(30); + + if ((event.getStatus() & GEF.CS_PRE_EXECUTE) != 0) + preExecute(); + else if ((event.getStatus() & GEF.CS_PRE_UNDO) != 0) + preUndo(); + else if ((event.getStatus() & GEF.CS_PRE_REDO) != 0) + preRedo(); + else if ((event.getStatus() & GEF.CS_POST_EXECUTE) != 0) + postExecute(); + else if ((event.getStatus() & GEF.CS_POST_UNDO) != 0) + postUndo(); + else if ((event.getStatus() & GEF.CS_POST_REDO) != 0) + postRedo(); + } + + /** + * Snapshots the current selection and push it into stack, and clear all + * cached selections from the current position on. + */ + protected void preExecute() { + clearFromCursor(); + if (cursor >= 0 && cursor <= selections.size()) { + ISelection selection = selectionProvider.getSelection(); + selections.add(cursor, selection); + } + } + + /** + * Clears all cached selections from the current position on. + */ + protected void clearFromCursor() { + if (cursor <= 0) { + selections.clear(); + } else { + while (cursor < selections.size()) { + selections.remove(selections.size() - 1); + } + } + } + + /** + * Try to preserve the previous selection after a command is executed. + */ + protected void postExecute() { + restoreSelection(); + ++cursor; + } + + /** + * Snapshots the current selection and push it into the stack if there's no + * selection on the current position before a command is about to be undone. + */ + protected void preUndo() { + ISelection selection = selectionProvider.getSelection(); + if (cursor == selections.size()) { + selections.add(cursor, selection); + } else if (cursor >= 0 && cursor < selections.size()) { +// ISelection cached = selections.get(cursor); +// if (cached == null) + selections.set(cursor, selection); + } + } + + /** + * Restores the previous selection that had been cached before this command + * was executed or redone. + */ + protected void postUndo() { + --cursor; + restoreSelection(); + } + + /** + * Snapshots the current selection and push it into the stack if there's no + * selection on the current position before a command is about to be redone. + */ + protected void preRedo() { + if (cursor >= 0 && cursor < selections.size()) { +// ISelection cached = selections.get(cursor); +// if (cached == null) { + ISelection selection = selectionProvider.getSelection(); + selections.set(cursor, selection); +// } + } else if (cursor == selections.size()) { + ISelection selection = selectionProvider.getSelection(); + selections.add(cursor, selection); + } + } + + /** + * Restores the previous selection that had been cached before this command + * was undone. + */ + protected void postRedo() { + ++cursor; + restoreSelection(); + } + + /** + * Restores the current selection to the selection provider. Does nothing is + * no selection is accessible. + */ + protected void restoreSelection() { + if (cursor >= 0 && cursor < selections.size()) { + ISelection selection = selections.get(cursor); + if (selection != null) { + selectionProvider.setSelection(selection); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/ZoomManager.java b/bundles/org.xmind.gef/src/org/xmind/gef/ZoomManager.java index 605858a39..898470b4f 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/ZoomManager.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/ZoomManager.java @@ -1,164 +1,164 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; - -/** - * @author Brian Sun - */ -public class ZoomManager extends ZoomObject { - - private double max; - - private double min; - - private double scale = 1; - - public ZoomManager() { - this(0.5d, 2.0d); - } - - public ZoomManager(double min, double max) { - this.min = min; - this.max = max; - } - - public void setConstraints(double min, double max) { - this.min = min; - this.max = max; - setScale(getScale()); - } - - public double getScale() { - return scale; - } - - public void setScale(double scale) { - scale = Math.min(getMax(), Math.max(getMin(), scale)); - internalSetScale(scale); - } - - private void internalSetScale(double scale) { - double oldScale = getScale(); - if (scale == oldScale) - return; - this.scale = scale; - fireScaleChanged(oldScale, getScale()); - } - - public void zoomIn() { - double scale = getScale(); - if (scale >= 1 && scale < 1.2) { - scale = forceMultiple(scale + 0.2, 0.2); - } else if (scale < 1) { - scale = Math.min(1.0, forceMultiple(scale + 0.1, 0.1)); - } else { - scale = forceMultiple(scale + 0.5, 0.5); - } - setScale(scale); - } - - public void zoomOut() { - double scale = getScale(); - if (scale <= 1) { - scale = forceMultiple(scale + 0.09, 0.1) - 0.1; - } else if (scale > 1 && scale <= 1.2) { - scale = forceMultiple(scale + 0.19, 0.2) - 0.2; - } else { - scale = Math.max(1.2, forceMultiple(scale + 0.49, 0.5) - 0.5); - } - setScale(scale); - } - - private static double forceMultiple(double a, double m) { - int x = (int) Math.round(a * 100); - int y = (int) Math.round(m * 100); - int d = x / y; - - double tmp = d * m; - tmp = ((int) (tmp * 100)) / 100.0; - return tmp; - } - - public void actualSize() { - setScale(1.0); - } - - public double getMax() { - return max; - } - - public double getMin() { - return min; - } - - public void fitScale(Dimension box, Dimension client) { - fitScale(box, client, -1, -1); - } - - private double calculateFitScale(Dimension box, Dimension client) { - return Math.min(box.width * 1.0 / client.width, box.height * 1.0 - / client.height); - } - - public void fitScale(Dimension box, Dimension client, double min, double max) { - double scale = calculateFitScale(box, client); - if (min > max) { - double t = max; - max = min; - min = t; - } - if (min > 0 && scale < min) { - if (getScale() > min) - scale = getScale(); - else - scale = min; - } - if (max > 0 && scale > max) { - if (getScale() < max) - scale = getScale(); - else - scale = max; - } - setScale(scale); - } - - public Dimension getScaled(Dimension d) { - return d.getScaled(getScale()); - } - - public Point getScaled(Point p) { - return p.getScaled(getScale()); - } - - public Rectangle getScaled(Rectangle r) { - return r.getCopy().scale(getScale()); - } - - public Dimension getAntiScaled(Dimension d) { - return d.getScaled(1 / getScale()); - } - - public Point getAntiScaled(Point p) { - return p.getScaled(1 / getScale()); - } - - public Rectangle getAntiScaled(Rectangle r) { - return r.getCopy().scale(1 / getScale()); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; + +/** + * @author Brian Sun + */ +public class ZoomManager extends ZoomObject { + + private double max; + + private double min; + + private double scale = 1; + + public ZoomManager() { + this(0.5d, 2.0d); + } + + public ZoomManager(double min, double max) { + this.min = min; + this.max = max; + } + + public void setConstraints(double min, double max) { + this.min = min; + this.max = max; + setScale(getScale()); + } + + public double getScale() { + return scale; + } + + public void setScale(double scale) { + scale = Math.min(getMax(), Math.max(getMin(), scale)); + internalSetScale(scale); + } + + private void internalSetScale(double scale) { + double oldScale = getScale(); + if (scale == oldScale) + return; + this.scale = scale; + fireScaleChanged(oldScale, getScale()); + } + + public void zoomIn() { + double scale = getScale(); + if (scale >= 1 && scale < 1.2) { + scale = forceMultiple(scale + 0.2, 0.2); + } else if (scale < 1) { + scale = Math.min(1.0, forceMultiple(scale + 0.1, 0.1)); + } else { + scale = forceMultiple(scale + 0.5, 0.5); + } + setScale(scale); + } + + public void zoomOut() { + double scale = getScale(); + if (scale <= 1) { + scale = forceMultiple(scale + 0.09, 0.1) - 0.1; + } else if (scale > 1 && scale <= 1.2) { + scale = forceMultiple(scale + 0.19, 0.2) - 0.2; + } else { + scale = Math.max(1.2, forceMultiple(scale + 0.49, 0.5) - 0.5); + } + setScale(scale); + } + + private static double forceMultiple(double a, double m) { + int x = (int) Math.round(a * 100); + int y = (int) Math.round(m * 100); + int d = x / y; + + double tmp = d * m; + tmp = ((int) (tmp * 100)) / 100.0; + return tmp; + } + + public void actualSize() { + setScale(1.0); + } + + public double getMax() { + return max; + } + + public double getMin() { + return min; + } + + public void fitScale(Dimension box, Dimension client) { + fitScale(box, client, -1, -1); + } + + private double calculateFitScale(Dimension box, Dimension client) { + return Math.min(box.width * 1.0 / client.width, box.height * 1.0 + / client.height); + } + + public void fitScale(Dimension box, Dimension client, double min, double max) { + double scale = calculateFitScale(box, client); + if (min > max) { + double t = max; + max = min; + min = t; + } + if (min > 0 && scale < min) { + if (getScale() > min) + scale = getScale(); + else + scale = min; + } + if (max > 0 && scale > max) { + if (getScale() < max) + scale = getScale(); + else + scale = max; + } + setScale(scale); + } + + public Dimension getScaled(Dimension d) { + return d.getScaled(getScale()); + } + + public Point getScaled(Point p) { + return p.getScaled(getScale()); + } + + public Rectangle getScaled(Rectangle r) { + return r.getCopy().scale(getScale()); + } + + public Dimension getAntiScaled(Dimension d) { + return d.getScaled(1 / getScale()); + } + + public Point getAntiScaled(Point p) { + return p.getScaled(1 / getScale()); + } + + public Rectangle getAntiScaled(Rectangle r) { + return r.getCopy().scale(1 / getScale()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStack.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStack.java index 45714d6f9..406e7c52b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStack.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStack.java @@ -1,365 +1,365 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -import static org.xmind.gef.GEF.CS_POST_EXECUTE; -import static org.xmind.gef.GEF.CS_POST_REDO; -import static org.xmind.gef.GEF.CS_POST_UNDO; -import static org.xmind.gef.GEF.CS_PRE_EXECUTE; -import static org.xmind.gef.GEF.CS_PRE_REDO; -import static org.xmind.gef.GEF.CS_PRE_UNDO; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.gef.GEF; - -/** - * @author Brian Sun - */ -public class CommandStack extends CommandStackBase - implements ICommandStack2, ICommandStack3 { - - private class DelegateListener implements ICommandStackListener { - - public void handleCommandStackEvent(CommandStackEvent event) { - fireEvent(event); - } - - } - - protected List commandList; - - private int currentLocation = -1; - - private int saveLocation = -1; - - private boolean alwaysDirty = false; - - private ICommandStackDelegate delegate = null; - - private DelegateListener delegateListener = null; - - private boolean inCompoundCommand = false; - - private Command compoundCommand = null; - - public CommandStack() { - this(DEFAULT_UNDO_LIMIT); - } - - /** - * @param undoLimit - */ - public CommandStack(int undoLimit) { - super(undoLimit); - commandList = new ArrayList(undoLimit); - } - - public void startCompoundCommand() { - if (delegate instanceof ICommandStack3) { - ((ICommandStack3) delegate).startCompoundCommand(); - return; - } - inCompoundCommand = true; - } - - public void endCompoundCommand() { - if (delegate instanceof ICommandStack3) { - ((ICommandStack3) delegate).endCompoundCommand(); - return; - } - inCompoundCommand = false; - if (compoundCommand != null) { - Command command = compoundCommand; - compoundCommand = null; - postExecute(command); - } - } - - public void execute(Command command) { - if (delegate != null && delegate.canExecute(command)) { - delegate.execute(command); - return; - } - - if (command == null || !command.canExecute()) - return; - - fireEvent(command, CS_PRE_EXECUTE); - - beginTransaction(); - command.execute(); - - if (inCompoundCommand) { - if (compoundCommand == null) { - compoundCommand = command; - return; - } else { - endCompoundCommand(); - } - } - - endTransaction(command, CS_PRE_EXECUTE); - postExecute(command); - - } - - private void postExecute(Command command) { - fireEvent(command, CS_POST_EXECUTE); - if (command.canUndo()) { - pushCommand(command); - } - fireEvent(null, GEF.CS_UPDATED); - } - - private void pushCommand(Command cmd) { - discardRedoables(); - commandList.add(cmd); - if (saveLocation > currentLocation) - saveLocation = -1; - currentLocation++; - fireEvent(cmd, GEF.CS_COMMAND_PUSHED); - if (getUndoLimit() > 0 && currentLocation >= getUndoLimit()) { - Command discarded = commandList.remove(0); - if (discarded != null) { - discarded.dispose(); - } - currentLocation--; - if (saveLocation >= 0) - saveLocation--; - alwaysDirty = true; - } - } - - private void discardRedoables() { - while (commandList.size() - 1 > currentLocation) { - Command discarded = commandList.remove(commandList.size() - 1); - if (discarded != null) { - discarded.dispose(); - } - } - } - - /** - * @return the commandList - */ - public List getCommandList() { - return commandList; - } - - public boolean canUndo() { - if (delegate != null) - return delegate.canUndo(); - - return currentLocation >= 0; - } - - public void undo() { - if (delegate != null && delegate.canUndo()) { - delegate.undo(); - return; - } - - Command undoCmd = commandList.get(currentLocation); - if (undoCmd.canUndo()) { - beginTransaction(); - fireEvent(undoCmd, CS_PRE_UNDO); - undoCmd.undo(); - endTransaction(undoCmd, CS_PRE_UNDO); - currentLocation--; - fireEvent(undoCmd, CS_POST_UNDO); - } else { - currentLocation--; - } - fireEvent(null, GEF.CS_UPDATED); - } - - public void undo(boolean discard) { - undo(); - if (discard) { - discardRedoables(); - } - } - - public boolean canRedo() { - if (delegate != null) - return delegate.canRedo(); - - return currentLocation < commandList.size() - 1; - } - - public void redo() { - if (delegate != null && delegate.canRedo()) { - delegate.redo(); - return; - } - - Command redoCmd = commandList.get(currentLocation + 1); - if (redoCmd.canExecute()) { - fireEvent(redoCmd, CS_PRE_REDO); - beginTransaction(); - redoCmd.redo(); - endTransaction(redoCmd, CS_PRE_REDO); - currentLocation++; - fireEvent(redoCmd, CS_POST_REDO); - } else { - currentLocation++; - } - fireEvent(null, GEF.CS_UPDATED); - } - -// /** -// * @deprecated -// */ -// public String getRepeatLabel() { -// if (delegate != null) -// return delegate.getRepeatLabel(); -// return super.getRepeatLabel(); -// } -// -// /** -// * @deprecated -// */ -// public void repeat() { -// if (delegate != null) { -// delegate.repeat(); -// return; -// } -// super.repeat(); -//// execute( commandList.get( currentLocation ).clone() ); -// } - - public boolean isDirty() { - if (delegate != null) - return delegate.isDirty(); - - return saveLocation != currentLocation || alwaysDirty; - } - - public void markSaved() { -// if (delegate != null) { -// delegate.markSaved(); -// return; -// } - - saveLocation = currentLocation; - alwaysDirty = false; - } - - public void clear() { -// if (delegate != null) { -// delegate.clear(); -// return; -// } - - currentLocation = -1; - saveLocation = -1; - for (Command c : commandList) - c.dispose(); - commandList.clear(); - fireEvent(null, GEF.CS_UPDATED); - } - -// /** -// * @see org.xmind.gef.command.ICommandStack#canRepeat() -// * @deprecated -// */ -// public boolean canRepeat() { -// if (delegate != null) -// return delegate.canRepeat(); -// return super.canRepeat(); -//// return currentLocation >= 0 -//// && commandList.get( currentLocation ).canRepeat(); -// } - - /** - * @see org.xmind.gef.command.ICommandStack#getRedoLabel() - */ - public String getRedoLabel() { - if (delegate != null && delegate.canRedo()) - return delegate.getRedoLabel(); - return commandList.get(currentLocation + 1).getLabel(); - } - - /** - * @see org.xmind.gef.command.ICommandStack#getUndoLabel() - */ - public String getUndoLabel() { - if (delegate != null && delegate.canUndo()) - return delegate.getUndoLabel(); - return commandList.get(currentLocation).getLabel(); - } - - public void setUndoLimit(int undoLimit) { -// if (delegate != null) { -// delegate.setUndoLimit(undoLimit); -// return; -// } - super.setUndoLimit(undoLimit); - while (undoLimit > 0 && commandList.size() > undoLimit) { - deleteFirst(); - } - fireEvent(null, GEF.CS_UPDATED); - } - - private void deleteFirst() { - if (commandList.size() > 0) { - Command cmd = commandList.remove(0); - if (cmd != null) { - cmd.dispose(); - if (saveLocation >= 0) - saveLocation--; - if (currentLocation >= 0) - currentLocation--; - alwaysDirty = true; - } - } - } - -// public int getUndoLimit() { -// if (delegate != null) -// return delegate.getUndoLimit(); -// return super.getUndoLimit(); -// } - - public void setDelegate(ICommandStackDelegate delegate) { - if (delegate == this.delegate) - return; - - if (this.delegate != null) { - if (delegateListener != null) { - this.delegate.removeCSListener(delegateListener); - } - } - this.delegate = delegate; - if (delegate != null) { - if (delegateListener == null) - delegateListener = new DelegateListener(); - delegate.addCSListener(delegateListener); - } else { - delegateListener = null; - } - fireEvent(null, GEF.CS_UPDATED); - } - - public ICommandStackDelegate getDelegate() { - return delegate; - } - - public void dispose() { - setDelegate(null); - super.dispose(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +import static org.xmind.gef.GEF.CS_POST_EXECUTE; +import static org.xmind.gef.GEF.CS_POST_REDO; +import static org.xmind.gef.GEF.CS_POST_UNDO; +import static org.xmind.gef.GEF.CS_PRE_EXECUTE; +import static org.xmind.gef.GEF.CS_PRE_REDO; +import static org.xmind.gef.GEF.CS_PRE_UNDO; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.gef.GEF; + +/** + * @author Brian Sun + */ +public class CommandStack extends CommandStackBase + implements ICommandStack2, ICommandStack3 { + + private class DelegateListener implements ICommandStackListener { + + public void handleCommandStackEvent(CommandStackEvent event) { + fireEvent(event); + } + + } + + protected List commandList; + + private int currentLocation = -1; + + private int saveLocation = -1; + + private boolean alwaysDirty = false; + + private ICommandStackDelegate delegate = null; + + private DelegateListener delegateListener = null; + + private boolean inCompoundCommand = false; + + private Command compoundCommand = null; + + public CommandStack() { + this(DEFAULT_UNDO_LIMIT); + } + + /** + * @param undoLimit + */ + public CommandStack(int undoLimit) { + super(undoLimit); + commandList = new ArrayList(undoLimit); + } + + public void startCompoundCommand() { + if (delegate instanceof ICommandStack3) { + ((ICommandStack3) delegate).startCompoundCommand(); + return; + } + inCompoundCommand = true; + } + + public void endCompoundCommand() { + if (delegate instanceof ICommandStack3) { + ((ICommandStack3) delegate).endCompoundCommand(); + return; + } + inCompoundCommand = false; + if (compoundCommand != null) { + Command command = compoundCommand; + compoundCommand = null; + postExecute(command); + } + } + + public void execute(Command command) { + if (delegate != null && delegate.canExecute(command)) { + delegate.execute(command); + return; + } + + if (command == null || !command.canExecute()) + return; + + fireEvent(command, CS_PRE_EXECUTE); + + beginTransaction(); + command.execute(); + + if (inCompoundCommand) { + if (compoundCommand == null) { + compoundCommand = command; + return; + } else { + endCompoundCommand(); + } + } + + endTransaction(command, CS_PRE_EXECUTE); + postExecute(command); + + } + + private void postExecute(Command command) { + fireEvent(command, CS_POST_EXECUTE); + if (command.canUndo()) { + pushCommand(command); + } + fireEvent(null, GEF.CS_UPDATED); + } + + private void pushCommand(Command cmd) { + discardRedoables(); + commandList.add(cmd); + if (saveLocation > currentLocation) + saveLocation = -1; + currentLocation++; + fireEvent(cmd, GEF.CS_COMMAND_PUSHED); + if (getUndoLimit() > 0 && currentLocation >= getUndoLimit()) { + Command discarded = commandList.remove(0); + if (discarded != null) { + discarded.dispose(); + } + currentLocation--; + if (saveLocation >= 0) + saveLocation--; + alwaysDirty = true; + } + } + + private void discardRedoables() { + while (commandList.size() - 1 > currentLocation) { + Command discarded = commandList.remove(commandList.size() - 1); + if (discarded != null) { + discarded.dispose(); + } + } + } + + /** + * @return the commandList + */ + public List getCommandList() { + return commandList; + } + + public boolean canUndo() { + if (delegate != null) + return delegate.canUndo(); + + return currentLocation >= 0; + } + + public void undo() { + if (delegate != null && delegate.canUndo()) { + delegate.undo(); + return; + } + + Command undoCmd = commandList.get(currentLocation); + if (undoCmd.canUndo()) { + beginTransaction(); + fireEvent(undoCmd, CS_PRE_UNDO); + undoCmd.undo(); + endTransaction(undoCmd, CS_PRE_UNDO); + currentLocation--; + fireEvent(undoCmd, CS_POST_UNDO); + } else { + currentLocation--; + } + fireEvent(null, GEF.CS_UPDATED); + } + + public void undo(boolean discard) { + undo(); + if (discard) { + discardRedoables(); + } + } + + public boolean canRedo() { + if (delegate != null) + return delegate.canRedo(); + + return currentLocation < commandList.size() - 1; + } + + public void redo() { + if (delegate != null && delegate.canRedo()) { + delegate.redo(); + return; + } + + Command redoCmd = commandList.get(currentLocation + 1); + if (redoCmd.canExecute()) { + fireEvent(redoCmd, CS_PRE_REDO); + beginTransaction(); + redoCmd.redo(); + endTransaction(redoCmd, CS_PRE_REDO); + currentLocation++; + fireEvent(redoCmd, CS_POST_REDO); + } else { + currentLocation++; + } + fireEvent(null, GEF.CS_UPDATED); + } + +// /** +// * @deprecated +// */ +// public String getRepeatLabel() { +// if (delegate != null) +// return delegate.getRepeatLabel(); +// return super.getRepeatLabel(); +// } +// +// /** +// * @deprecated +// */ +// public void repeat() { +// if (delegate != null) { +// delegate.repeat(); +// return; +// } +// super.repeat(); +//// execute( commandList.get( currentLocation ).clone() ); +// } + + public boolean isDirty() { + if (delegate != null) + return delegate.isDirty(); + + return saveLocation != currentLocation || alwaysDirty; + } + + public void markSaved() { +// if (delegate != null) { +// delegate.markSaved(); +// return; +// } + + saveLocation = currentLocation; + alwaysDirty = false; + } + + public void clear() { +// if (delegate != null) { +// delegate.clear(); +// return; +// } + + currentLocation = -1; + saveLocation = -1; + for (Command c : commandList) + c.dispose(); + commandList.clear(); + fireEvent(null, GEF.CS_UPDATED); + } + +// /** +// * @see org.xmind.gef.command.ICommandStack#canRepeat() +// * @deprecated +// */ +// public boolean canRepeat() { +// if (delegate != null) +// return delegate.canRepeat(); +// return super.canRepeat(); +//// return currentLocation >= 0 +//// && commandList.get( currentLocation ).canRepeat(); +// } + + /** + * @see org.xmind.gef.command.ICommandStack#getRedoLabel() + */ + public String getRedoLabel() { + if (delegate != null && delegate.canRedo()) + return delegate.getRedoLabel(); + return commandList.get(currentLocation + 1).getLabel(); + } + + /** + * @see org.xmind.gef.command.ICommandStack#getUndoLabel() + */ + public String getUndoLabel() { + if (delegate != null && delegate.canUndo()) + return delegate.getUndoLabel(); + return commandList.get(currentLocation).getLabel(); + } + + public void setUndoLimit(int undoLimit) { +// if (delegate != null) { +// delegate.setUndoLimit(undoLimit); +// return; +// } + super.setUndoLimit(undoLimit); + while (undoLimit > 0 && commandList.size() > undoLimit) { + deleteFirst(); + } + fireEvent(null, GEF.CS_UPDATED); + } + + private void deleteFirst() { + if (commandList.size() > 0) { + Command cmd = commandList.remove(0); + if (cmd != null) { + cmd.dispose(); + if (saveLocation >= 0) + saveLocation--; + if (currentLocation >= 0) + currentLocation--; + alwaysDirty = true; + } + } + } + +// public int getUndoLimit() { +// if (delegate != null) +// return delegate.getUndoLimit(); +// return super.getUndoLimit(); +// } + + public void setDelegate(ICommandStackDelegate delegate) { + if (delegate == this.delegate) + return; + + if (this.delegate != null) { + if (delegateListener != null) { + this.delegate.removeCSListener(delegateListener); + } + } + this.delegate = delegate; + if (delegate != null) { + if (delegateListener == null) + delegateListener = new DelegateListener(); + delegate.addCSListener(delegateListener); + } else { + delegateListener = null; + } + fireEvent(null, GEF.CS_UPDATED); + } + + public ICommandStackDelegate getDelegate() { + return delegate; + } + + public void dispose() { + setDelegate(null); + super.dispose(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStackBase.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStackBase.java index 03f77ca01..3ffefe953 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStackBase.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/CommandStackBase.java @@ -1,196 +1,196 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.Disposable; - -/** - * @author Brian Sun - */ -public abstract class CommandStackBase extends Disposable - implements ICommandStack { - - public static int DEFAULT_UNDO_LIMIT = 20; - - private List commandStackListeners = null; - - private List pendingCommandStackListeners = null; - - private List toBeRemovedCommandStackListeners = null; - - private boolean inTransaction = false; - - private int undoLimit; - - /** - * @param undoLimit - */ - public CommandStackBase(int undoLimit) { - this.undoLimit = undoLimit; - } - - /** - * - */ - public CommandStackBase() { - this(DEFAULT_UNDO_LIMIT); - } - - /** - * @see org.xmind.gef.command.ICommandStack#addCSListener(org.xmind.gef.command.ICommandStackListener) - */ - public void addCSListener(ICommandStackListener listener) { - if (inTransaction) { - if (pendingCommandStackListeners == null) { - pendingCommandStackListeners = new ArrayList(); - } - pendingCommandStackListeners.add(listener); - } else { - if (commandStackListeners == null) - commandStackListeners = new ArrayList(); - commandStackListeners.add(listener); - } - } - - /** - * @see org.xmind.gef.command.ICommandStack#removeCSListener(org.xmind.gef.command.ICommandStackListener) - */ - public void removeCSListener(ICommandStackListener listener) { - if (inTransaction) { - if (toBeRemovedCommandStackListeners == null) - toBeRemovedCommandStackListeners = new ArrayList(); - toBeRemovedCommandStackListeners.add(listener); - } else { - if (commandStackListeners != null) { - commandStackListeners.remove(listener); - } - } - } - - protected void beginTransaction() { - inTransaction = true; - } - - protected void endTransaction(Command command, int preStatus) { - inTransaction = false; - if (pendingCommandStackListeners != null - && commandStackListeners != null) { - commandStackListeners.addAll(pendingCommandStackListeners); - } - - if (toBeRemovedCommandStackListeners != null) { - for (ICommandStackListener toBeRemovedListener : toBeRemovedCommandStackListeners) { - if (commandStackListeners != null) - commandStackListeners.remove(toBeRemovedListener); - if (pendingCommandStackListeners != null) - pendingCommandStackListeners.remove(toBeRemovedListener); - } - toBeRemovedCommandStackListeners.clear(); - toBeRemovedCommandStackListeners = null; - } - - if (pendingCommandStackListeners != null) { - fireEvent(command, preStatus, pendingCommandStackListeners); - pendingCommandStackListeners.clear(); - pendingCommandStackListeners = null; - } - } - - private void fireEvent(Command command, int preStatus, - List pendingCommandStackListeners) { - for (Object listener : pendingCommandStackListeners.toArray()) { - ((ICommandStackListener) listener).handleCommandStackEvent( - new CommandStackEvent(this, command, preStatus)); - } - } - - protected void fireEvent(int status) { - if (commandStackListeners == null) - return; - fireEvent(new CommandStackEvent(this, status)); - } - - protected void fireEvent(Command cmd, int status) { - if (commandStackListeners == null) - return; - fireEvent(new CommandStackEvent(this, cmd, status)); - } - - protected void fireEvent(CommandStackEvent event) { - if (commandStackListeners == null) - return; - for (Object listener : commandStackListeners.toArray()) { - ((ICommandStackListener) listener).handleCommandStackEvent(event); - } - } - - /** - * @see org.xmind.framework.Disposable#removeFromLayer(IFigure) - */ - @Override - public void dispose() { - if (commandStackListeners != null) { - commandStackListeners.clear(); - commandStackListeners = null; - } - clear(); - super.dispose(); - } - - /** - * @see org.xmind.gef.command.ICommandStack#getUndoLimit() - */ - public int getUndoLimit() { - return undoLimit; - } - - /** - * @see org.xmind.gef.command.ICommandStack#setUndoLimit(int) - */ - public void setUndoLimit(int undoLimit) { - this.undoLimit = undoLimit; - } - - /** - * @see org.xmind.gef.command.ICommandStack#getRepeatLabel() - * @deprecated - */ - public String getRepeatLabel() { - return getUndoLabel(); - } - - /** - * @deprecated - */ - public boolean canRepeat() { - return false; - } - - /** - * @deprecated - */ - public void repeat() { - } - - public void markSaved() { - } - - public boolean isDirty() { - return canUndo(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.Disposable; + +/** + * @author Brian Sun + */ +public abstract class CommandStackBase extends Disposable + implements ICommandStack { + + public static int DEFAULT_UNDO_LIMIT = 20; + + private List commandStackListeners = null; + + private List pendingCommandStackListeners = null; + + private List toBeRemovedCommandStackListeners = null; + + private boolean inTransaction = false; + + private int undoLimit; + + /** + * @param undoLimit + */ + public CommandStackBase(int undoLimit) { + this.undoLimit = undoLimit; + } + + /** + * + */ + public CommandStackBase() { + this(DEFAULT_UNDO_LIMIT); + } + + /** + * @see org.xmind.gef.command.ICommandStack#addCSListener(org.xmind.gef.command.ICommandStackListener) + */ + public void addCSListener(ICommandStackListener listener) { + if (inTransaction) { + if (pendingCommandStackListeners == null) { + pendingCommandStackListeners = new ArrayList(); + } + pendingCommandStackListeners.add(listener); + } else { + if (commandStackListeners == null) + commandStackListeners = new ArrayList(); + commandStackListeners.add(listener); + } + } + + /** + * @see org.xmind.gef.command.ICommandStack#removeCSListener(org.xmind.gef.command.ICommandStackListener) + */ + public void removeCSListener(ICommandStackListener listener) { + if (inTransaction) { + if (toBeRemovedCommandStackListeners == null) + toBeRemovedCommandStackListeners = new ArrayList(); + toBeRemovedCommandStackListeners.add(listener); + } else { + if (commandStackListeners != null) { + commandStackListeners.remove(listener); + } + } + } + + protected void beginTransaction() { + inTransaction = true; + } + + protected void endTransaction(Command command, int preStatus) { + inTransaction = false; + if (pendingCommandStackListeners != null + && commandStackListeners != null) { + commandStackListeners.addAll(pendingCommandStackListeners); + } + + if (toBeRemovedCommandStackListeners != null) { + for (ICommandStackListener toBeRemovedListener : toBeRemovedCommandStackListeners) { + if (commandStackListeners != null) + commandStackListeners.remove(toBeRemovedListener); + if (pendingCommandStackListeners != null) + pendingCommandStackListeners.remove(toBeRemovedListener); + } + toBeRemovedCommandStackListeners.clear(); + toBeRemovedCommandStackListeners = null; + } + + if (pendingCommandStackListeners != null) { + fireEvent(command, preStatus, pendingCommandStackListeners); + pendingCommandStackListeners.clear(); + pendingCommandStackListeners = null; + } + } + + private void fireEvent(Command command, int preStatus, + List pendingCommandStackListeners) { + for (Object listener : pendingCommandStackListeners.toArray()) { + ((ICommandStackListener) listener).handleCommandStackEvent( + new CommandStackEvent(this, command, preStatus)); + } + } + + protected void fireEvent(int status) { + if (commandStackListeners == null) + return; + fireEvent(new CommandStackEvent(this, status)); + } + + protected void fireEvent(Command cmd, int status) { + if (commandStackListeners == null) + return; + fireEvent(new CommandStackEvent(this, cmd, status)); + } + + protected void fireEvent(CommandStackEvent event) { + if (commandStackListeners == null) + return; + for (Object listener : commandStackListeners.toArray()) { + ((ICommandStackListener) listener).handleCommandStackEvent(event); + } + } + + /** + * @see org.xmind.framework.Disposable#removeFromLayer(IFigure) + */ + @Override + public void dispose() { + if (commandStackListeners != null) { + commandStackListeners.clear(); + commandStackListeners = null; + } + clear(); + super.dispose(); + } + + /** + * @see org.xmind.gef.command.ICommandStack#getUndoLimit() + */ + public int getUndoLimit() { + return undoLimit; + } + + /** + * @see org.xmind.gef.command.ICommandStack#setUndoLimit(int) + */ + public void setUndoLimit(int undoLimit) { + this.undoLimit = undoLimit; + } + + /** + * @see org.xmind.gef.command.ICommandStack#getRepeatLabel() + * @deprecated + */ + public String getRepeatLabel() { + return getUndoLabel(); + } + + /** + * @deprecated + */ + public boolean canRepeat() { + return false; + } + + /** + * @deprecated + */ + public void repeat() { + } + + public void markSaved() { + } + + public boolean isDirty() { + return canUndo(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/CompoundCommand.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/CompoundCommand.java index ed5b7bdf2..6eb1d1100 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/CompoundCommand.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/CompoundCommand.java @@ -1,201 +1,201 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.xmind.gef.GEF; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.ISourceProvider2; - -/** - * @author Brian Sun - */ -public class CompoundCommand extends Command implements ISourceProvider2 { - - private List commands; - - private boolean executing = false; - - private boolean sourceCollectable = true; - - public CompoundCommand(List commands) { - this(EMPTY, commands); - } - - public CompoundCommand(Command... commands) { - this(EMPTY, commands); - } - - public CompoundCommand(String label, List commands) { - super(label); - Assert.isNotNull(commands); - for (Command c : commands) - Assert.isNotNull(c); - this.commands = new ArrayList(commands); - } - - public CompoundCommand(String label, Command... commands) { - super(label); - Assert.isNotNull(commands); - for (Command c : commands) - Assert.isNotNull(c); - List list = Arrays.asList(commands); - this.commands = new ArrayList(list); - } - - public List getCommands() { - return commands; - } - - public int getType() { - boolean hasModifyCommand = false; - for (Command cmd : commands) { - int type = cmd.getType(); - if (type == GEF.CMD_MODIFY && !hasModifyCommand) { - hasModifyCommand = true; - } - if (type != GEF.CMD_NORMAL && type != GEF.CMD_MODIFY) - return type; - } - if (hasModifyCommand) - return GEF.CMD_MODIFY; - return super.getType(); - } - - public boolean hasSource() { - for (Command c : commands) { - if (c instanceof ISourceProvider) { - if (((ISourceProvider) c).hasSource()) - return true; - } - } - return false; - } - - public Object getSource() { - for (Command c : commands) { - if (c instanceof ISourceProvider) { - if (!(c instanceof ISourceProvider2) - || ((ISourceProvider2) c).isSourceCollectable()) { - Object source = ((ISourceProvider) c).getSource(); - if (source != null) - return source; - } - } - } - return null; - } - - public List getSources() { - List sources = new ArrayList(); - for (Command c : commands) { - if (c instanceof ISourceProvider) { - if (!(c instanceof ISourceProvider2) - || ((ISourceProvider2) c).isSourceCollectable()) { - List ss = ((ISourceProvider) c).getSources(); - for (Object s : ss) { - if (s != null && !sources.contains(s)) { - sources.add(s); - } - } - } - } - } - return sources; - } - - public void append(Command command) { - Assert.isNotNull(command); - commands.add(command); -// if (canUndo() && command.canExecute()) { -// command.execute(); -// } - } - - public boolean canExecute() { - for (Command cmd : commands) { - if (cmd.canExecute()) - return true; - } - return false; - } - - public boolean canRedo() { - for (Command cmd : commands) { - if (cmd.canRedo()) - return true; - } - return false; - } - - public boolean canUndo() { - for (Command cmd : commands) { - if (cmd.canUndo()) - return true; - } - return false; - } - - public void execute() { - for (Command cmd : commands) { - if (cmd.canExecute()) - cmd.execute(); - } - executing = true; - super.execute(); - executing = false; - } - - public void redo() { - if (!executing) { - for (Command cmd : commands) { - if (cmd.canRedo()) - cmd.redo(); - } - } - super.redo(); - } - - public void undo() { - for (int i = commands.size() - 1; i >= 0; i--) { - Command cmd = commands.get(i); - if (cmd.canUndo()) - cmd.undo(); - } - super.undo(); - } - - public void dispose() { - if (commands != null) { - for (Command cmd : commands) { - cmd.dispose(); - } - commands = null; - } - super.dispose(); - } - - public boolean isSourceCollectable() { - return sourceCollectable; - } - - public void setSourceCollectable(boolean collectable) { - this.sourceCollectable = collectable; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.xmind.gef.GEF; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.ISourceProvider2; + +/** + * @author Brian Sun + */ +public class CompoundCommand extends Command implements ISourceProvider2 { + + private List commands; + + private boolean executing = false; + + private boolean sourceCollectable = true; + + public CompoundCommand(List commands) { + this(EMPTY, commands); + } + + public CompoundCommand(Command... commands) { + this(EMPTY, commands); + } + + public CompoundCommand(String label, List commands) { + super(label); + Assert.isNotNull(commands); + for (Command c : commands) + Assert.isNotNull(c); + this.commands = new ArrayList(commands); + } + + public CompoundCommand(String label, Command... commands) { + super(label); + Assert.isNotNull(commands); + for (Command c : commands) + Assert.isNotNull(c); + List list = Arrays.asList(commands); + this.commands = new ArrayList(list); + } + + public List getCommands() { + return commands; + } + + public int getType() { + boolean hasModifyCommand = false; + for (Command cmd : commands) { + int type = cmd.getType(); + if (type == GEF.CMD_MODIFY && !hasModifyCommand) { + hasModifyCommand = true; + } + if (type != GEF.CMD_NORMAL && type != GEF.CMD_MODIFY) + return type; + } + if (hasModifyCommand) + return GEF.CMD_MODIFY; + return super.getType(); + } + + public boolean hasSource() { + for (Command c : commands) { + if (c instanceof ISourceProvider) { + if (((ISourceProvider) c).hasSource()) + return true; + } + } + return false; + } + + public Object getSource() { + for (Command c : commands) { + if (c instanceof ISourceProvider) { + if (!(c instanceof ISourceProvider2) + || ((ISourceProvider2) c).isSourceCollectable()) { + Object source = ((ISourceProvider) c).getSource(); + if (source != null) + return source; + } + } + } + return null; + } + + public List getSources() { + List sources = new ArrayList(); + for (Command c : commands) { + if (c instanceof ISourceProvider) { + if (!(c instanceof ISourceProvider2) + || ((ISourceProvider2) c).isSourceCollectable()) { + List ss = ((ISourceProvider) c).getSources(); + for (Object s : ss) { + if (s != null && !sources.contains(s)) { + sources.add(s); + } + } + } + } + } + return sources; + } + + public void append(Command command) { + Assert.isNotNull(command); + commands.add(command); +// if (canUndo() && command.canExecute()) { +// command.execute(); +// } + } + + public boolean canExecute() { + for (Command cmd : commands) { + if (cmd.canExecute()) + return true; + } + return false; + } + + public boolean canRedo() { + for (Command cmd : commands) { + if (cmd.canRedo()) + return true; + } + return false; + } + + public boolean canUndo() { + for (Command cmd : commands) { + if (cmd.canUndo()) + return true; + } + return false; + } + + public void execute() { + for (Command cmd : commands) { + if (cmd.canExecute()) + cmd.execute(); + } + executing = true; + super.execute(); + executing = false; + } + + public void redo() { + if (!executing) { + for (Command cmd : commands) { + if (cmd.canRedo()) + cmd.redo(); + } + } + super.redo(); + } + + public void undo() { + for (int i = commands.size() - 1; i >= 0; i--) { + Command cmd = commands.get(i); + if (cmd.canUndo()) + cmd.undo(); + } + super.undo(); + } + + public void dispose() { + if (commands != null) { + for (Command cmd : commands) { + cmd.dispose(); + } + commands = null; + } + super.dispose(); + } + + public boolean isSourceCollectable() { + return sourceCollectable; + } + + public void setSourceCollectable(boolean collectable) { + this.sourceCollectable = collectable; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack2.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack2.java index 6f9c32205..f77f55386 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack2.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -public interface ICommandStack2 { - - void setDelegate(ICommandStackDelegate delegate); - - ICommandStackDelegate getDelegate(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +public interface ICommandStack2 { + + void setDelegate(ICommandStackDelegate delegate); + + ICommandStackDelegate getDelegate(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack3.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack3.java index 1b1dc2dee..e28a8d255 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack3.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStack3.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -public interface ICommandStack3 { - - void startCompoundCommand(); - - void endCompoundCommand(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +public interface ICommandStack3 { + + void startCompoundCommand(); + + void endCompoundCommand(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackCallback.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackCallback.java index fba462fca..0eafd92c4 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackCallback.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackCallback.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -public interface ICommandStackCallback { - - void stackUpdated(ICommandStack cs); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +public interface ICommandStackCallback { + + void stackUpdated(ICommandStack cs); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackDelegate.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackDelegate.java index 50333b7de..e36c880e2 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackDelegate.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackDelegate.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -public interface ICommandStackDelegate extends ICommandStack { - - boolean canExecute(Command command); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +public interface ICommandStackDelegate extends ICommandStack { + + boolean canExecute(Command command); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackListener.java index e753ced22..0b434f670 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ICommandStackListener.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -/** - * @author Brian Sun - * @version 2005 - */ -public interface ICommandStackListener { - - public void handleCommandStackEvent(CommandStackEvent event); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +/** + * @author Brian Sun + * @version 2005 + */ +public interface ICommandStackListener { + + public void handleCommandStackEvent(CommandStackEvent event); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/command/ModifyCommand.java b/bundles/org.xmind.gef/src/org/xmind/gef/command/ModifyCommand.java index 8afee58e6..7366cbfa4 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/command/ModifyCommand.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/command/ModifyCommand.java @@ -1,133 +1,133 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.command; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.xmind.gef.GEF; -import org.xmind.gef.ISourceProvider; - -public abstract class ModifyCommand extends SourceCommand { - - private Object newValue; - - private Map oldValues = null; - - protected ModifyCommand(Object source, Object newValue) { - super(source); - this.newValue = newValue; - } - - protected ModifyCommand(Collection sources, Object newValue) { - super(sources); - this.newValue = newValue; - } - - protected ModifyCommand(ISourceProvider sourceProvider, Object newValue) { - super(sourceProvider); - this.newValue = newValue; - } - - public int getType() { - return GEF.CMD_MODIFY; - } - - public Object getNewValue() { - return newValue; - } - - public Map getOldValues() { - if (oldValues == null) { - oldValues = new HashMap(); - for (Object source : getSources()) { - oldValues.put(source, getValue(source)); - } - } - return oldValues; - } - - public Object getOldValue(Object source) { - return getOldValues().get(source); - } - - protected abstract Object getValue(Object source); - - public boolean canExecute() { - return !isSameValue(); - } - - protected boolean isSameValue() { - for (Object source : getSources()) { - Object oldValue = getOldValue(source); - if (!isSameValue(oldValue, newValue)) - return false; - } - return true; - } - - public void execute() { - getOldValues(); - super.execute(); - } - - public void redo() { - setNewValues(); - super.redo(); - } - - public void undo() { - setOldValues(); - super.undo(); - } - - protected void setNewValues() { - for (Object source : getSources()) { - setValue(source, newValue); - } - } - - protected void setOldValues() { - for (Object source : getSources()) { - setValue(source, getOldValue(source)); - } - } - - protected abstract void setValue(Object source, Object value); - - public void dispose() { - newValue = null; - oldValues = null; - super.dispose(); - } - - protected boolean isSameValue(Object oldValue, Object newValue) { - return (oldValue == newValue) - || (oldValue != null && oldValue.equals(newValue)); - } - - /** - * An alternate way to set new value. - * - * @param newValue - */ - protected void setNewValue(Object newValue) { - if (this.newValue != null) - return; - - this.newValue = newValue; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.command; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.xmind.gef.GEF; +import org.xmind.gef.ISourceProvider; + +public abstract class ModifyCommand extends SourceCommand { + + private Object newValue; + + private Map oldValues = null; + + protected ModifyCommand(Object source, Object newValue) { + super(source); + this.newValue = newValue; + } + + protected ModifyCommand(Collection sources, Object newValue) { + super(sources); + this.newValue = newValue; + } + + protected ModifyCommand(ISourceProvider sourceProvider, Object newValue) { + super(sourceProvider); + this.newValue = newValue; + } + + public int getType() { + return GEF.CMD_MODIFY; + } + + public Object getNewValue() { + return newValue; + } + + public Map getOldValues() { + if (oldValues == null) { + oldValues = new HashMap(); + for (Object source : getSources()) { + oldValues.put(source, getValue(source)); + } + } + return oldValues; + } + + public Object getOldValue(Object source) { + return getOldValues().get(source); + } + + protected abstract Object getValue(Object source); + + public boolean canExecute() { + return !isSameValue(); + } + + protected boolean isSameValue() { + for (Object source : getSources()) { + Object oldValue = getOldValue(source); + if (!isSameValue(oldValue, newValue)) + return false; + } + return true; + } + + public void execute() { + getOldValues(); + super.execute(); + } + + public void redo() { + setNewValues(); + super.redo(); + } + + public void undo() { + setOldValues(); + super.undo(); + } + + protected void setNewValues() { + for (Object source : getSources()) { + setValue(source, newValue); + } + } + + protected void setOldValues() { + for (Object source : getSources()) { + setValue(source, getOldValue(source)); + } + } + + protected abstract void setValue(Object source, Object value); + + public void dispose() { + newValue = null; + oldValues = null; + super.dispose(); + } + + protected boolean isSameValue(Object oldValue, Object newValue) { + return (oldValue == newValue) + || (oldValue != null && oldValue.equals(newValue)); + } + + /** + * An alternate way to set new value. + * + * @param newValue + */ + protected void setNewValue(Object newValue) { + if (this.newValue != null) + return; + + this.newValue = newValue; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/AbstractAnchor.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/AbstractAnchor.java index 3c2508bbc..e66eb0043 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/AbstractAnchor.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/AbstractAnchor.java @@ -1,225 +1,225 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.FreeformFigure; -import org.eclipse.draw2d.FreeformListener; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; - -public abstract class AbstractAnchor implements IAnchor, FigureListener, - FreeformListener, PropertyChangeListener { - - private List listeners = null; - - private IFigure owner; - - private Set propertiesToMove = null; - - protected AbstractAnchor() { - } - - public AbstractAnchor(IFigure owner) { - setOwner(owner); - } - - protected void setOwner(IFigure owner) { - if (owner == this.owner) - return; - - if (getOwner() != null && hasAnchorListener()) { - unhookOwner(getOwner()); - } - this.owner = owner; - if (getOwner() != null && hasAnchorListener()) { - hookOwner(getOwner()); - } - } - - protected void hookOwner(IFigure owner) { - owner.addFigureListener(this); - if (owner instanceof FreeformFigure) { - ((FreeformFigure) owner).addFreeformListener(this); - } - if (propertiesToMove != null) { - for (String property : propertiesToMove) { - owner.addPropertyChangeListener(property, this); - } - } - } - - protected void unhookOwner(IFigure owner) { - owner.removeFigureListener(this); - if (owner instanceof FreeformFigure) { - ((FreeformFigure) owner).removeFreeformListener(this); - } - if (propertiesToMove != null) { - for (String property : propertiesToMove) { - owner.removePropertyChangeListener(property, this); - } - } - } - - public PrecisionPoint getLocation(int orientation, double expansion) { - switch (orientation) { - case PositionConstants.WEST: - return getWest(expansion); - case PositionConstants.SOUTH: - return getSouth(expansion); - case PositionConstants.NORTH: - return getNorth(expansion); - } - return getEast(expansion); - } - - protected PrecisionPoint getEast(double expansion) { - PrecisionPoint ref = getReferencePoint(); - return getLocation(ref.x + 100, ref.y, expansion); - } - - protected PrecisionPoint getNorth(double expansion) { - PrecisionPoint ref = getReferencePoint(); - return getLocation(ref.x, ref.y - 100, expansion); - } - - protected PrecisionPoint getSouth(double expansion) { - PrecisionPoint ref = getReferencePoint(); - return getLocation(ref.x, ref.y + 100, expansion); - } - - protected PrecisionPoint getWest(double expansion) { - PrecisionPoint ref = getReferencePoint(); - return getLocation(ref.x - 100, ref.y, expansion); - } - - public PrecisionPoint getLocation(PrecisionPoint reference, double expansion) { - return getLocation(reference.x, reference.y, expansion); - } - - public void addAnchorListener(IAnchorListener listener) { - boolean hadListener = hasAnchorListener(); - if (listeners == null) - listeners = new ArrayList(); - listeners.add(listener); - if (!hadListener && hasAnchorListener() && getOwner() != null) { - hookOwner(getOwner()); - } - } - - public IFigure getOwner() { - return owner; - } - - public PrecisionPoint getReferencePoint() { - if (getOwner() == null) - return new PrecisionPoint(); - if (getOwner() instanceof IReferencedFigure) { - return new PrecisionPoint(((IReferencedFigure) getOwner()) - .getReference()); - } - Rectangle r = getOwner().getBounds(); - return new PrecisionPoint(r.x + r.width * 0.5, r.y + r.height * 0.5); - } - - public void removeAnchorListener(IAnchorListener listener) { - if (listeners == null) - return; - boolean hadListener = hasAnchorListener(); - listeners.remove(listener); - if (hadListener && !hasAnchorListener() && getOwner() != null) { - unhookOwner(getOwner()); - } - } - - public void figureMoved(IFigure source) { - fireAnchorMoved(); - } - - public void notifyFreeformExtentChanged() { - fireAnchorMoved(); - } - - protected void fireAnchorMoved() { - if (listeners == null) - return; - for (Object listener : listeners.toArray()) { - ((IAnchorListener) listener).anchorMoved(this); - } - } - - protected boolean hasAnchorListener() { - return listeners != null && !listeners.isEmpty(); - } - - public void addAnchorMoveProperty(String... properties) { - for (String property : properties) { - addMoveProperty(property); - } - fireAnchorMoved(); - } - - /** - * @param property - */ - private void addMoveProperty(String property) { - if (propertiesToMove == null) { - propertiesToMove = new HashSet(); - } - if (!propertiesToMove.contains(property)) { - if (getOwner() != null && hasAnchorListener()) { - getOwner().addPropertyChangeListener(property, this); - } - propertiesToMove.add(property); - } - } - - public void removeAnchorMoveProperty(String... properties) { - if (propertiesToMove == null) - return; - for (String property : properties) { - removeMoveProperty(property); - } - fireAnchorMoved(); - } - - /** - * @param property - */ - private void removeMoveProperty(String property) { - if (getOwner() != null) { - getOwner().removePropertyChangeListener(property, this); - } - propertiesToMove.remove(property); - } - - /* - * (non-Javadoc) - * - * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. - * PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent evt) { - fireAnchorMoved(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.FreeformFigure; +import org.eclipse.draw2d.FreeformListener; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; + +public abstract class AbstractAnchor implements IAnchor, FigureListener, + FreeformListener, PropertyChangeListener { + + private List listeners = null; + + private IFigure owner; + + private Set propertiesToMove = null; + + protected AbstractAnchor() { + } + + public AbstractAnchor(IFigure owner) { + setOwner(owner); + } + + protected void setOwner(IFigure owner) { + if (owner == this.owner) + return; + + if (getOwner() != null && hasAnchorListener()) { + unhookOwner(getOwner()); + } + this.owner = owner; + if (getOwner() != null && hasAnchorListener()) { + hookOwner(getOwner()); + } + } + + protected void hookOwner(IFigure owner) { + owner.addFigureListener(this); + if (owner instanceof FreeformFigure) { + ((FreeformFigure) owner).addFreeformListener(this); + } + if (propertiesToMove != null) { + for (String property : propertiesToMove) { + owner.addPropertyChangeListener(property, this); + } + } + } + + protected void unhookOwner(IFigure owner) { + owner.removeFigureListener(this); + if (owner instanceof FreeformFigure) { + ((FreeformFigure) owner).removeFreeformListener(this); + } + if (propertiesToMove != null) { + for (String property : propertiesToMove) { + owner.removePropertyChangeListener(property, this); + } + } + } + + public PrecisionPoint getLocation(int orientation, double expansion) { + switch (orientation) { + case PositionConstants.WEST: + return getWest(expansion); + case PositionConstants.SOUTH: + return getSouth(expansion); + case PositionConstants.NORTH: + return getNorth(expansion); + } + return getEast(expansion); + } + + protected PrecisionPoint getEast(double expansion) { + PrecisionPoint ref = getReferencePoint(); + return getLocation(ref.x + 100, ref.y, expansion); + } + + protected PrecisionPoint getNorth(double expansion) { + PrecisionPoint ref = getReferencePoint(); + return getLocation(ref.x, ref.y - 100, expansion); + } + + protected PrecisionPoint getSouth(double expansion) { + PrecisionPoint ref = getReferencePoint(); + return getLocation(ref.x, ref.y + 100, expansion); + } + + protected PrecisionPoint getWest(double expansion) { + PrecisionPoint ref = getReferencePoint(); + return getLocation(ref.x - 100, ref.y, expansion); + } + + public PrecisionPoint getLocation(PrecisionPoint reference, double expansion) { + return getLocation(reference.x, reference.y, expansion); + } + + public void addAnchorListener(IAnchorListener listener) { + boolean hadListener = hasAnchorListener(); + if (listeners == null) + listeners = new ArrayList(); + listeners.add(listener); + if (!hadListener && hasAnchorListener() && getOwner() != null) { + hookOwner(getOwner()); + } + } + + public IFigure getOwner() { + return owner; + } + + public PrecisionPoint getReferencePoint() { + if (getOwner() == null) + return new PrecisionPoint(); + if (getOwner() instanceof IReferencedFigure) { + return new PrecisionPoint(((IReferencedFigure) getOwner()) + .getReference()); + } + Rectangle r = getOwner().getBounds(); + return new PrecisionPoint(r.x + r.width * 0.5, r.y + r.height * 0.5); + } + + public void removeAnchorListener(IAnchorListener listener) { + if (listeners == null) + return; + boolean hadListener = hasAnchorListener(); + listeners.remove(listener); + if (hadListener && !hasAnchorListener() && getOwner() != null) { + unhookOwner(getOwner()); + } + } + + public void figureMoved(IFigure source) { + fireAnchorMoved(); + } + + public void notifyFreeformExtentChanged() { + fireAnchorMoved(); + } + + protected void fireAnchorMoved() { + if (listeners == null) + return; + for (Object listener : listeners.toArray()) { + ((IAnchorListener) listener).anchorMoved(this); + } + } + + protected boolean hasAnchorListener() { + return listeners != null && !listeners.isEmpty(); + } + + public void addAnchorMoveProperty(String... properties) { + for (String property : properties) { + addMoveProperty(property); + } + fireAnchorMoved(); + } + + /** + * @param property + */ + private void addMoveProperty(String property) { + if (propertiesToMove == null) { + propertiesToMove = new HashSet(); + } + if (!propertiesToMove.contains(property)) { + if (getOwner() != null && hasAnchorListener()) { + getOwner().addPropertyChangeListener(property, this); + } + propertiesToMove.add(property); + } + } + + public void removeAnchorMoveProperty(String... properties) { + if (propertiesToMove == null) + return; + for (String property : properties) { + removeMoveProperty(property); + } + fireAnchorMoved(); + } + + /** + * @param property + */ + private void removeMoveProperty(String property) { + if (getOwner() != null) { + getOwner().removePropertyChangeListener(property, this); + } + propertiesToMove.remove(property); + } + + /* + * (non-Javadoc) + * + * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. + * PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent evt) { + fireAnchorMoved(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorListener.java index 69cd383ec..aa2039132 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorListener.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -public interface IAnchorListener { - - void anchorMoved(IAnchor anchor); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +public interface IAnchorListener { + + void anchorMoved(IAnchor anchor); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorableFigureListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorableFigureListener.java index c3ebe0d8e..ca17257a6 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorableFigureListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IAnchorableFigureListener.java @@ -1,21 +1,21 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -public interface IAnchorableFigureListener { - - void anchorChanged(IAnchorableFigure source, IAnchor oldAnchor, - IAnchor newAnchor); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +public interface IAnchorableFigureListener { + + void anchorChanged(IAnchorableFigure source, IAnchor oldAnchor, + IAnchor newAnchor); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IDecoratedFigureListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IDecoratedFigureListener.java index 4295b2ed5..4bd908eb3 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IDecoratedFigureListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IDecoratedFigureListener.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.xmind.gef.draw2d.decoration.IDecoration; - -public interface IDecoratedFigureListener { - - void decorationChanged(IDecoratedFigure figure, IDecoration oldDecoration, - IDecoration newDecoration); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.xmind.gef.draw2d.decoration.IDecoration; + +public interface IDecoratedFigureListener { + + void decorationChanged(IDecoratedFigure figure, IDecoration oldDecoration, + IDecoration newDecoration); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IHasCorner.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IHasCorner.java index edfd1fb92..804a587c1 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IHasCorner.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IHasCorner.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -public interface IHasCorner { - - public int getCornerSize(); - - public void setCornerSize( int cornerSize ); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +public interface IHasCorner { + + public int getCornerSize(); + + public void setCornerSize( int cornerSize ); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased.java index dc3863e98..62b0b06ed 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.geometry.Point; - -/** - * @author Frank Shaka - */ -public interface IOriginBased { - - Point getOrigin(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.geometry.Point; + +/** + * @author Frank Shaka + */ +public interface IOriginBased { + + Point getOrigin(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased2.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased2.java index e675d08e6..c37c6509c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IOriginBased2.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.geometry.Point; - -public interface IOriginBased2 extends IOriginBased { - - void setOrigin(Point origin); - - public void setOrigin(int x, int y); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.geometry.Point; + +public interface IOriginBased2 extends IOriginBased { + + void setOrigin(Point origin); + + public void setOrigin(int x, int y); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferenceDescriptor.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferenceDescriptor.java index a2da5625f..2b5044dbd 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferenceDescriptor.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferenceDescriptor.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; - -public interface IReferenceDescriptor { - - public Insets getReferenceDescription(IFigure figure); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; + +public interface IReferenceDescriptor { + + public Insets getReferenceDescription(IFigure figure); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferencedFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferencedFigure.java index ee575c025..27b5f7e7d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferencedFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IReferencedFigure.java @@ -1,135 +1,135 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; - -/** - * Figure based on a reference point. - *

- * The location of a reference point is determined by the distances from that - * reference point to the four sides of the figure's bounds, which is called the - * "reference description", provided by an IReferenceDescriptor. It - * means that, given a specified IReferenceDescriptor and a - * reference point, the figure's preferred bounds can be calculated and those - * bounds can be used by layout managers to determine the figure's size and - * location. - *

- * - * @author Frank Shaka - */ -public interface IReferencedFigure extends IFigure, IOriginBased { - - /** - * Returns the reference point of this figure. Any resizing or translating - * of this figure will cause the reference be re-calculated. - * - * @return the reference point of this figure. - */ - Point getReference(); - - /** - * Sets the location of this figure to fit the given reference point. - * - * @param reference - */ - void setReference(Point reference); - - /** - * Sets the location of this figure to fit the given reference point. - * - * @param referenceX - * @param referenceY - */ - void setReference(int referenceX, int referenceY); - - /** - * Returns the reference description of this figure. - * - * @return the reference description of this figure. - */ - Insets getReferenceDescription(); - - /** - * Returns the preferred client area of this figure based on the given - * reference point. - * - * @param reference - * @return - */ - Rectangle getPreferredClientArea(Point reference); - - /** - * Returns the preferred bounds of this figure based on the given reference - * point. - * - * @param reference - * @return - */ - Rectangle getPreferredBounds(Point reference); - - /** - * Calculates the preferred bounds of this figure based on the given - * reference point, copies the values into the given rectangle and returns - * that rectangle. - * - * @param rect - * @param reference - * @return - */ - Rectangle getPreferredBounds(Rectangle rect, Point reference); - - /** - * Returns the reference descriptor used to describe the reference point of - * this figure. - * - * @return - */ - IReferenceDescriptor getReferenceDescriptor(); - - /** - * Sets the reference descriptor to describe the reference point of this - * figure. - * - * @param descriptor - */ - void setReferenceDescriptor(IReferenceDescriptor descriptor); - - /** - * Returns the orientation of this figure based on the origin location - * obtained from getOrigin(). - * - * @return the orientation of this figure - * @see org.xmind.util.geometry.Geometry#getOrientation(Point, Point) - */ - int getOrientation(); - - /** - * Returns the last calculated reference point. This value maintains the - * calculated reference point through the time when the cached reference - * point is cleared due to some resizing or translating and a new reference - * point is not calculated yet. Reference descriptors may take advantage of - * this value to calculate new reference description, for calling - * {@link #getReference()} when calculating new reference point may cause - * endless recursion or get a newly calculated reference point that's not - * corresponding to the actual state of this figure. - * - * @return the last calculated reference point - */ - Point getLastReference(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; + +/** + * Figure based on a reference point. + *

+ * The location of a reference point is determined by the distances from that + * reference point to the four sides of the figure's bounds, which is called the + * "reference description", provided by an IReferenceDescriptor. It + * means that, given a specified IReferenceDescriptor and a + * reference point, the figure's preferred bounds can be calculated and those + * bounds can be used by layout managers to determine the figure's size and + * location. + *

+ * + * @author Frank Shaka + */ +public interface IReferencedFigure extends IFigure, IOriginBased { + + /** + * Returns the reference point of this figure. Any resizing or translating + * of this figure will cause the reference be re-calculated. + * + * @return the reference point of this figure. + */ + Point getReference(); + + /** + * Sets the location of this figure to fit the given reference point. + * + * @param reference + */ + void setReference(Point reference); + + /** + * Sets the location of this figure to fit the given reference point. + * + * @param referenceX + * @param referenceY + */ + void setReference(int referenceX, int referenceY); + + /** + * Returns the reference description of this figure. + * + * @return the reference description of this figure. + */ + Insets getReferenceDescription(); + + /** + * Returns the preferred client area of this figure based on the given + * reference point. + * + * @param reference + * @return + */ + Rectangle getPreferredClientArea(Point reference); + + /** + * Returns the preferred bounds of this figure based on the given reference + * point. + * + * @param reference + * @return + */ + Rectangle getPreferredBounds(Point reference); + + /** + * Calculates the preferred bounds of this figure based on the given + * reference point, copies the values into the given rectangle and returns + * that rectangle. + * + * @param rect + * @param reference + * @return + */ + Rectangle getPreferredBounds(Rectangle rect, Point reference); + + /** + * Returns the reference descriptor used to describe the reference point of + * this figure. + * + * @return + */ + IReferenceDescriptor getReferenceDescriptor(); + + /** + * Sets the reference descriptor to describe the reference point of this + * figure. + * + * @param descriptor + */ + void setReferenceDescriptor(IReferenceDescriptor descriptor); + + /** + * Returns the orientation of this figure based on the origin location + * obtained from getOrigin(). + * + * @return the orientation of this figure + * @see org.xmind.util.geometry.Geometry#getOrientation(Point, Point) + */ + int getOrientation(); + + /** + * Returns the last calculated reference point. This value maintains the + * calculated reference point through the time when the cached reference + * point is cleared due to some resizing or translating and a new reference + * point is not calculated yet. Reference descriptors may take advantage of + * this value to calculate new reference description, for calling + * {@link #getReference()} when calculating new reference point may cause + * endless recursion or get a newly calculated reference point that's not + * corresponding to the actual state of this figure. + * + * @return the last calculated reference point + */ + Point getLastReference(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatable.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatable.java index 90356afcb..234202537 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatable.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatable.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -/** - * @author Frank Shaka - */ -public interface IRotatable { - - double getRotationDegrees(); - - void setRotationDegrees(double degrees); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +/** + * @author Frank Shaka + */ +public interface IRotatable { + + double getRotationDegrees(); + + void setRotationDegrees(double degrees); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatableReferenceDescriptor.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatableReferenceDescriptor.java index f1325a748..aa28b4470 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatableReferenceDescriptor.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IRotatableReferenceDescriptor.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; - -public interface IRotatableReferenceDescriptor extends IReferenceDescriptor, - IRotatable { - - PrecisionInsets getNormalReferenceDescription(IFigure figure); +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; + +public interface IRotatableReferenceDescriptor extends IReferenceDescriptor, + IRotatable { + + PrecisionInsets getNormalReferenceDescription(IFigure figure); } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IShadowedFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IShadowedFigure.java index c7ac3b6f2..40fbb6996 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IShadowedFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IShadowedFigure.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.Graphics; - -public interface IShadowedFigure { - - void paintShadow(Graphics graphics); - - boolean isShadowShowing(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.Graphics; + +public interface IShadowedFigure { + + void paintShadow(Graphics graphics); + + boolean isShadowShowing(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ISkylightLayer.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ISkylightLayer.java index 202df438c..d01635a15 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ISkylightLayer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ISkylightLayer.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; - -public interface ISkylightLayer extends IFigure { - - void setSkylight(Rectangle skylight); - - Rectangle getSkylight(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; + +public interface ISkylightLayer extends IFigure { + + void setSkylight(Rectangle skylight); + + Rectangle getSkylight(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure.java index b7c8d4667..78c96d053 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; - -public interface ITitledFigure extends IFigure { - - ITextFigure getTitle(); - - void setTitle(ITextFigure title); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; + +public interface ITitledFigure extends IFigure { + + ITextFigure getTitle(); + + void setTitle(ITextFigure title); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure2.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure2.java index 21adeb525..1027fc3d1 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITitledFigure2.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.swt.graphics.TextStyle; - -public interface ITitledFigure2 extends ITitledFigure { - - void setTitleTextStyle(TextStyle textStyle, boolean exclusive); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.swt.graphics.TextStyle; + +public interface ITitledFigure2 extends ITitledFigure { + + void setTitleTextStyle(TextStyle textStyle, boolean exclusive); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITransparentableFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITransparentableFigure.java index deacdd893..041946d3b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITransparentableFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ITransparentableFigure.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; - -/** - * @author Frank Shaka - */ -public interface ITransparentableFigure extends IUseTransparency, IFigure { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; + +/** + * @author Frank Shaka + */ +public interface ITransparentableFigure extends IUseTransparency, IFigure { + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IWrapFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IWrapFigure.java index ba6c2d7f3..7559509ec 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IWrapFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/IWrapFigure.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; - -public interface IWrapFigure extends IFigure { - - int getPrefWidth(); - - void setPrefWidth(int prefWidth); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; + +public interface IWrapFigure extends IFigure { + + int getPrefWidth(); + + void setPrefWidth(int prefWidth); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/KeepVisibleToolTipHelper.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/KeepVisibleToolTipHelper.java index aefa901b0..a672fed4c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/KeepVisibleToolTipHelper.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/KeepVisibleToolTipHelper.java @@ -1,93 +1,93 @@ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.ToolTipHelper; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Control; - -/** - * This will keep the tooltip always visible during mouse hover in. - * - * @author Shawn - * - */ -public class KeepVisibleToolTipHelper extends ToolTipHelper { - - public KeepVisibleToolTipHelper(Control control) { - super(control); - } - - private IFigure currentTipSource; - - private Point computeWindowLocation(IFigure tip, int eventX, int eventY) { - org.eclipse.swt.graphics.Rectangle clientArea = control.getDisplay() - .getClientArea(); - Point preferredLocation = new Point(eventX, eventY + 26); - - Dimension tipSize = getLightweightSystem().getRootFigure() - .getPreferredSize().getExpanded(getShellTrimSize()); - - // Adjust location if tip is going to fall outside display - if (preferredLocation.y + tipSize.height > clientArea.height) - preferredLocation.y = eventY - tipSize.height; - - if (preferredLocation.x + tipSize.width > clientArea.width) - preferredLocation.x -= (preferredLocation.x + tipSize.width) - - clientArea.width; - - return preferredLocation; - } - - public void displayToolTipNear(IFigure hoverSource, IFigure tip, - int eventX, int eventY) { - if (tip != null && hoverSource != currentTipSource) { - getLightweightSystem().setContents(tip); - Point displayPoint = computeWindowLocation(tip, eventX, eventY); - Dimension shellSize = getLightweightSystem().getRootFigure() - .getPreferredSize().getExpanded(getShellTrimSize()); - setShellBounds(displayPoint.x, displayPoint.y, shellSize.width, - shellSize.height); - show(); - currentTipSource = hoverSource; - } - } - - public void dispose() { - if (isShowing()) { - hide(); - } - getShell().dispose(); - } - - protected void hookShellListeners() { - // Close the tooltip window if the mouse enters the tooltip - getShell().addMouseTrackListener(new MouseTrackAdapter() { - public void mouseEnter(org.eclipse.swt.events.MouseEvent e) { - hide(); - currentTipSource = null; - } - }); - } - - public void updateToolTip(IFigure figureUnderMouse, IFigure tip, - int eventX, int eventY) { - /* - * If the cursor is not on any Figures, it has been moved off of the - * control. Hide the tool tip. - */ - if (figureUnderMouse == null) { - if (isShowing()) { - hide(); - } - } - // Makes tooltip appear without a hover event if a tip is currently - // being displayed - if (isShowing() && figureUnderMouse != currentTipSource) { - hide(); - displayToolTipNear(figureUnderMouse, tip, eventX, eventY); - } else if (!isShowing() && figureUnderMouse != currentTipSource) - currentTipSource = null; - } -} +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.ToolTipHelper; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; + +/** + * This will keep the tooltip always visible during mouse hover in. + * + * @author Shawn + * + */ +public class KeepVisibleToolTipHelper extends ToolTipHelper { + + public KeepVisibleToolTipHelper(Control control) { + super(control); + } + + private IFigure currentTipSource; + + private Point computeWindowLocation(IFigure tip, int eventX, int eventY) { + org.eclipse.swt.graphics.Rectangle clientArea = control.getDisplay() + .getClientArea(); + Point preferredLocation = new Point(eventX, eventY + 26); + + Dimension tipSize = getLightweightSystem().getRootFigure() + .getPreferredSize().getExpanded(getShellTrimSize()); + + // Adjust location if tip is going to fall outside display + if (preferredLocation.y + tipSize.height > clientArea.height) + preferredLocation.y = eventY - tipSize.height; + + if (preferredLocation.x + tipSize.width > clientArea.width) + preferredLocation.x -= (preferredLocation.x + tipSize.width) + - clientArea.width; + + return preferredLocation; + } + + public void displayToolTipNear(IFigure hoverSource, IFigure tip, + int eventX, int eventY) { + if (tip != null && hoverSource != currentTipSource) { + getLightweightSystem().setContents(tip); + Point displayPoint = computeWindowLocation(tip, eventX, eventY); + Dimension shellSize = getLightweightSystem().getRootFigure() + .getPreferredSize().getExpanded(getShellTrimSize()); + setShellBounds(displayPoint.x, displayPoint.y, shellSize.width, + shellSize.height); + show(); + currentTipSource = hoverSource; + } + } + + public void dispose() { + if (isShowing()) { + hide(); + } + getShell().dispose(); + } + + protected void hookShellListeners() { + // Close the tooltip window if the mouse enters the tooltip + getShell().addMouseTrackListener(new MouseTrackAdapter() { + public void mouseEnter(org.eclipse.swt.events.MouseEvent e) { + hide(); + currentTipSource = null; + } + }); + } + + public void updateToolTip(IFigure figureUnderMouse, IFigure tip, + int eventX, int eventY) { + /* + * If the cursor is not on any Figures, it has been moved off of the + * control. Hide the tool tip. + */ + if (figureUnderMouse == null) { + if (isShowing()) { + hide(); + } + } + // Makes tooltip appear without a hover event if a tip is currently + // being displayed + if (isShowing() && figureUnderMouse != currentTipSource) { + hide(); + displayToolTipNear(figureUnderMouse, tip, eventX, eventY); + } else if (!isShowing() && figureUnderMouse != currentTipSource) + currentTipSource = null; + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/PathFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/PathFigure.java index aa082f840..d71da77a5 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/PathFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/PathFigure.java @@ -1,188 +1,188 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.Shape; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.internal.DPIUtil; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; - -/** - * @author Frank Shaka - */ -@SuppressWarnings("restriction") -public class PathFigure extends Shape { - - private static final float[] _bounds = new float[4]; - - private Path path = null; - - private boolean outline = true; - - private boolean fill = true; - - private int tolerance = 0; - - /** - * - */ - public PathFigure() { - } - - /** - * @return the path - */ - public Path getPath() { - return path; - } - - /** - * NOTE: It's client's responsibility to dispose the path. - * - * @param path - * the path to set - */ - public void setPath(Path path) { - if (this.path == path || (this.path != null && this.path.equals(path))) - return; - this.path = path; - setBounds(getPreferredBounds()); -// revalidate(); - } - - /** - * @return the tolerance - */ - public int getTolerance() { - return tolerance; - } - - /** - * @param tolerance - * the tolerance to set - */ - public void setTolerance(int tolerance) { - this.tolerance = tolerance; - } - - /** - * @see org.eclipse.draw2d.Shape#fillShape(org.eclipse.draw2d.Graphics) - */ - @Override - protected void fillShape(Graphics graphics) { - if (path != null) - graphics.fillPath(path); - } - - /** - * @see org.eclipse.draw2d.Shape#outlineShape(org.eclipse.draw2d.Graphics) - */ - @Override - protected void outlineShape(Graphics graphics) { - if (path != null) - graphics.drawPath(path); - } - - /** - * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int) - */ - @Override - public Dimension getPreferredSize(int wHint, int hHint) { - if (path != null) { - path.getBounds(_bounds); - if (Util.isWindows()) { - float[] autoScaleDown = DPIUtil.autoScaleDown(_bounds); - _bounds[0] = autoScaleDown[0]; - _bounds[1] = autoScaleDown[1]; - _bounds[2] = autoScaleDown[2]; - _bounds[3] = autoScaleDown[3]; - } - - PrecisionDimension pSize = new PrecisionDimension(_bounds[2], - _bounds[3]); - double halfLine = getLineWidth() * 0.5d + 1.0; - pSize.expand(halfLine, halfLine); - return pSize.toDraw2DDimension(); - } - return super.getPreferredSize(wHint, hHint); - } - - protected Rectangle getPreferredBounds() { - if (path == null) - return new Rectangle(); - path.getBounds(_bounds); - if (Util.isWindows()) { - float[] autoScaleDown = DPIUtil.autoScaleDown(_bounds); - _bounds[0] = autoScaleDown[0]; - _bounds[1] = autoScaleDown[1]; - _bounds[2] = autoScaleDown[2]; - _bounds[3] = autoScaleDown[3]; - } - PrecisionRectangle pRect = new PrecisionRectangle(_bounds[0], - _bounds[1], _bounds[2], _bounds[3]); - double halfLine = getLineWidth() * 0.5d; - pRect.expand(halfLine, halfLine).resize(1.0, 1.0); - return pRect.toDraw2DRectangle(); - } - - /** - * @see org.eclipse.draw2d.Figure#containsPoint(int, int) - */ - @Override - public boolean containsPoint(int x, int y) { - if (!super.containsPoint(x, y) || path == null - || (!hasOutline() && !hasFill())) - return false; - GC gc = new GC(Display.getCurrent()); - gc.setLineWidth(getLineWidth() + tolerance); - gc.setLineStyle(getLineStyle()); - boolean b = path.contains(x, y, gc, !hasFill()); - gc.dispose(); - return b; - } - - /** - * @see org.eclipse.draw2d.Shape#setOutline(boolean) - */ - @Override - public void setOutline(boolean b) { - super.setOutline(b); - this.outline = b; - } - - /** - * @see org.eclipse.draw2d.Shape#setFill(boolean) - */ - @Override - public void setFill(boolean b) { - super.setFill(b); - this.fill = b; - } - - public boolean hasOutline() { - return outline; - } - - public boolean hasFill() { - return fill; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Shape; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.internal.DPIUtil; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; + +/** + * @author Frank Shaka + */ +@SuppressWarnings("restriction") +public class PathFigure extends Shape { + + private static final float[] _bounds = new float[4]; + + private Path path = null; + + private boolean outline = true; + + private boolean fill = true; + + private int tolerance = 0; + + /** + * + */ + public PathFigure() { + } + + /** + * @return the path + */ + public Path getPath() { + return path; + } + + /** + * NOTE: It's client's responsibility to dispose the path. + * + * @param path + * the path to set + */ + public void setPath(Path path) { + if (this.path == path || (this.path != null && this.path.equals(path))) + return; + this.path = path; + setBounds(getPreferredBounds()); +// revalidate(); + } + + /** + * @return the tolerance + */ + public int getTolerance() { + return tolerance; + } + + /** + * @param tolerance + * the tolerance to set + */ + public void setTolerance(int tolerance) { + this.tolerance = tolerance; + } + + /** + * @see org.eclipse.draw2d.Shape#fillShape(org.eclipse.draw2d.Graphics) + */ + @Override + protected void fillShape(Graphics graphics) { + if (path != null) + graphics.fillPath(path); + } + + /** + * @see org.eclipse.draw2d.Shape#outlineShape(org.eclipse.draw2d.Graphics) + */ + @Override + protected void outlineShape(Graphics graphics) { + if (path != null) + graphics.drawPath(path); + } + + /** + * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int) + */ + @Override + public Dimension getPreferredSize(int wHint, int hHint) { + if (path != null) { + path.getBounds(_bounds); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(_bounds); + _bounds[0] = autoScaleDown[0]; + _bounds[1] = autoScaleDown[1]; + _bounds[2] = autoScaleDown[2]; + _bounds[3] = autoScaleDown[3]; + } + + PrecisionDimension pSize = new PrecisionDimension(_bounds[2], + _bounds[3]); + double halfLine = getLineWidth() * 0.5d + 1.0; + pSize.expand(halfLine, halfLine); + return pSize.toDraw2DDimension(); + } + return super.getPreferredSize(wHint, hHint); + } + + protected Rectangle getPreferredBounds() { + if (path == null) + return new Rectangle(); + path.getBounds(_bounds); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(_bounds); + _bounds[0] = autoScaleDown[0]; + _bounds[1] = autoScaleDown[1]; + _bounds[2] = autoScaleDown[2]; + _bounds[3] = autoScaleDown[3]; + } + PrecisionRectangle pRect = new PrecisionRectangle(_bounds[0], + _bounds[1], _bounds[2], _bounds[3]); + double halfLine = getLineWidth() * 0.5d; + pRect.expand(halfLine, halfLine).resize(1.0, 1.0); + return pRect.toDraw2DRectangle(); + } + + /** + * @see org.eclipse.draw2d.Figure#containsPoint(int, int) + */ + @Override + public boolean containsPoint(int x, int y) { + if (!super.containsPoint(x, y) || path == null + || (!hasOutline() && !hasFill())) + return false; + GC gc = new GC(Display.getCurrent()); + gc.setLineWidth(getLineWidth() + tolerance); + gc.setLineStyle(getLineStyle()); + boolean b = path.contains(x, y, gc, !hasFill()); + gc.dispose(); + return b; + } + + /** + * @see org.eclipse.draw2d.Shape#setOutline(boolean) + */ + @Override + public void setOutline(boolean b) { + super.setOutline(b); + this.outline = b; + } + + /** + * @see org.eclipse.draw2d.Shape#setFill(boolean) + */ + @Override + public void setFill(boolean b) { + super.setFill(b); + this.fill = b; + } + + public boolean hasOutline() { + return outline; + } + + public boolean hasFill() { + return fill; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedFigure.java index 99260fe34..4da991cea 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedFigure.java @@ -1,185 +1,185 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; - -public class ReferencedFigure extends Figure implements IReferencedFigure { - - private IReferenceDescriptor referenceDescriptor = null; - - private Insets refDesc = null; - - private Point reference = null; - - private Point lastReference = null; - - public int getOrientation() { - return Geometry.getOrientation(getReference(), getOrigin()); - } - - public Rectangle getPreferredBounds(Point reference) { - return Geometry.getExpanded(reference, getReferenceDescription()); - } - - public Rectangle getPreferredBounds(Rectangle rect, Point reference) { - Insets ins = getReferenceDescription(); - rect.setLocation(reference.x - ins.left, reference.y - ins.top); - rect.setSize(ins.getWidth(), ins.getHeight()); - return rect; - } - - public Rectangle getPreferredClientArea(Point reference) { - if (getLayoutManager() instanceof IReferencedLayout) { - Rectangle area = ((IReferencedLayout) getLayoutManager()) - .getPreferredClientArea(this); - return area.getTranslated(reference); - } - return new Rectangle(0, 0, 0, 0); - } - - public Point getReference() { - if (reference == null) { - reference = calculateReference(getBounds()); - lastReference = reference; - } - return reference; - } - - protected Point calculateReference(Rectangle bounds) { - Insets ins = getReferenceDescription(); - int insWidth = ins.getWidth(); - int insHeight = ins.getHeight(); - int x = bounds.x; - int y = bounds.y; - if (bounds.width == insWidth) { - x += ins.left; - } else if (insWidth > 0) { - x += bounds.width * ins.left / insWidth; - } - if (bounds.height == insHeight) { - y += ins.top; - } else if (insHeight > 0) { - y += bounds.height * ins.top / insHeight; - } - return new Point(x, y); - } - - public Insets getReferenceDescription() { - if (refDesc != null) - return refDesc; - - IReferenceDescriptor descriptor = getReferenceDescriptor(); - if (descriptor != null) { - refDesc = descriptor.getReferenceDescription(this); - } - if (refDesc == null) { - refDesc = calculateDefaultReferenceDescription(getPreferredSize()); - } - return refDesc; - } - - protected Insets calculateDefaultReferenceDescription( - Dimension preferredSize) { - int h = preferredSize.height / 2; - int w = preferredSize.width / 2; - return new Insets(h, w, preferredSize.height - h, preferredSize.width - - w); - } - - public IReferenceDescriptor getReferenceDescriptor() { - return referenceDescriptor; - } - - public void setReference(Point reference) { - if (reference != null) - setReference(reference.x, reference.y); - } - - public void setReference(int referenceX, int referenceY) { - setLocation(calculateLocation(referenceX, referenceY)); - } - - protected Point calculateLocation(int refX, int refY) { - int width = bounds.width; - int height = bounds.height; - Insets ins = getReferenceDescription(); - int insWidth = ins.getWidth(); - int insHeight = ins.getHeight(); - if (width == insWidth) { - refX -= ins.left; - } else if (insWidth > 0) { - refX -= width * ins.left / insWidth; - } - if (height == insHeight) { - refY -= ins.top; - } else if (insHeight > 0) { - refY -= height * ins.top / insHeight; - } - return new Point(refX, refY); - } - - public void setReferenceDescriptor(IReferenceDescriptor descriptor) { - if (descriptor == this.referenceDescriptor) - return; - - this.referenceDescriptor = descriptor; - revalidate(); - } - - public Point getOrigin() { - IOriginBased originBased = getOriginBasedAncestor(this); - if (originBased != null) - return originBased.getOrigin(); - return getReference(); - } - - private IOriginBased getOriginBasedAncestor(IFigure fig) { - IFigure parent = fig.getParent(); - if (parent == null) - return null; - if (parent instanceof IOriginBased) - return (IOriginBased) parent; - return getOriginBasedAncestor(parent); - } - - protected void fireFigureMoved() { - reference = null; - super.fireFigureMoved(); - } - - public void invalidate() { - super.invalidate(); - reference = null; - refDesc = null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.draw2d.IReferencedFigure#getLastReference() - */ - public Point getLastReference() { - if (lastReference == null) - lastReference = getReference(); - return lastReference; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; + +public class ReferencedFigure extends Figure implements IReferencedFigure { + + private IReferenceDescriptor referenceDescriptor = null; + + private Insets refDesc = null; + + private Point reference = null; + + private Point lastReference = null; + + public int getOrientation() { + return Geometry.getOrientation(getReference(), getOrigin()); + } + + public Rectangle getPreferredBounds(Point reference) { + return Geometry.getExpanded(reference, getReferenceDescription()); + } + + public Rectangle getPreferredBounds(Rectangle rect, Point reference) { + Insets ins = getReferenceDescription(); + rect.setLocation(reference.x - ins.left, reference.y - ins.top); + rect.setSize(ins.getWidth(), ins.getHeight()); + return rect; + } + + public Rectangle getPreferredClientArea(Point reference) { + if (getLayoutManager() instanceof IReferencedLayout) { + Rectangle area = ((IReferencedLayout) getLayoutManager()) + .getPreferredClientArea(this); + return area.getTranslated(reference); + } + return new Rectangle(0, 0, 0, 0); + } + + public Point getReference() { + if (reference == null) { + reference = calculateReference(getBounds()); + lastReference = reference; + } + return reference; + } + + protected Point calculateReference(Rectangle bounds) { + Insets ins = getReferenceDescription(); + int insWidth = ins.getWidth(); + int insHeight = ins.getHeight(); + int x = bounds.x; + int y = bounds.y; + if (bounds.width == insWidth) { + x += ins.left; + } else if (insWidth > 0) { + x += bounds.width * ins.left / insWidth; + } + if (bounds.height == insHeight) { + y += ins.top; + } else if (insHeight > 0) { + y += bounds.height * ins.top / insHeight; + } + return new Point(x, y); + } + + public Insets getReferenceDescription() { + if (refDesc != null) + return refDesc; + + IReferenceDescriptor descriptor = getReferenceDescriptor(); + if (descriptor != null) { + refDesc = descriptor.getReferenceDescription(this); + } + if (refDesc == null) { + refDesc = calculateDefaultReferenceDescription(getPreferredSize()); + } + return refDesc; + } + + protected Insets calculateDefaultReferenceDescription( + Dimension preferredSize) { + int h = preferredSize.height / 2; + int w = preferredSize.width / 2; + return new Insets(h, w, preferredSize.height - h, preferredSize.width + - w); + } + + public IReferenceDescriptor getReferenceDescriptor() { + return referenceDescriptor; + } + + public void setReference(Point reference) { + if (reference != null) + setReference(reference.x, reference.y); + } + + public void setReference(int referenceX, int referenceY) { + setLocation(calculateLocation(referenceX, referenceY)); + } + + protected Point calculateLocation(int refX, int refY) { + int width = bounds.width; + int height = bounds.height; + Insets ins = getReferenceDescription(); + int insWidth = ins.getWidth(); + int insHeight = ins.getHeight(); + if (width == insWidth) { + refX -= ins.left; + } else if (insWidth > 0) { + refX -= width * ins.left / insWidth; + } + if (height == insHeight) { + refY -= ins.top; + } else if (insHeight > 0) { + refY -= height * ins.top / insHeight; + } + return new Point(refX, refY); + } + + public void setReferenceDescriptor(IReferenceDescriptor descriptor) { + if (descriptor == this.referenceDescriptor) + return; + + this.referenceDescriptor = descriptor; + revalidate(); + } + + public Point getOrigin() { + IOriginBased originBased = getOriginBasedAncestor(this); + if (originBased != null) + return originBased.getOrigin(); + return getReference(); + } + + private IOriginBased getOriginBasedAncestor(IFigure fig) { + IFigure parent = fig.getParent(); + if (parent == null) + return null; + if (parent instanceof IOriginBased) + return (IOriginBased) parent; + return getOriginBasedAncestor(parent); + } + + protected void fireFigureMoved() { + reference = null; + super.fireFigureMoved(); + } + + public void invalidate() { + super.invalidate(); + reference = null; + refDesc = null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.draw2d.IReferencedFigure#getLastReference() + */ + public Point getLastReference() { + if (lastReference == null) + lastReference = getReference(); + return lastReference; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedLayer.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedLayer.java index 0be6a97bd..1e6cd1ca8 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedLayer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/ReferencedLayer.java @@ -1,181 +1,181 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.FreeformLayer; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; - -public class ReferencedLayer extends FreeformLayer implements IReferencedFigure { - - private IReferenceDescriptor referenceDescriptor = null; - - private Insets refDesc = null; - - private Point reference = null; - - private Point lastReference = null; - - public int getOrientation() { - return Geometry.getOrientation(getReference(), getOrigin()); - } - - public Rectangle getPreferredBounds(Point reference) { - return Geometry.getExpanded(reference, getReferenceDescription()); - } - - public Rectangle getPreferredBounds(Rectangle rect, Point reference) { - Insets ins = getReferenceDescription(); - rect.setLocation(reference.x - ins.left, reference.y - ins.top); - rect.setSize(ins.getWidth(), ins.getHeight()); - return rect; - } - - public Rectangle getPreferredClientArea(Point reference) { - if (getLayoutManager() instanceof IReferencedLayout) { - Rectangle area = ((IReferencedLayout) getLayoutManager()) - .getPreferredClientArea(this); - return area.getTranslated(reference); - } - return new Rectangle(0, 0, 0, 0); - } - - public Point getReference() { - if (reference == null) { - reference = calculateReference(getBounds()); - lastReference = reference; - } - return reference; - } - - protected Point calculateReference(Rectangle bounds) { - Insets ins = getReferenceDescription(); - int insWidth = ins.getWidth(); - int insHeight = ins.getHeight(); - int x = bounds.x; - int y = bounds.y; - if (bounds.width == insWidth) { - x += ins.left; - } else if (insWidth > 0) { - x += bounds.width * ins.left / insWidth; - } - if (bounds.height == insHeight) { - y += ins.top; - } else if (insHeight > 0) { - y += bounds.height * ins.top / insHeight; - } - return new Point(x, y); - } - - public Insets getReferenceDescription() { - if (refDesc != null) - return refDesc; - - IReferenceDescriptor descriptor = getReferenceDescriptor(); - if (descriptor != null) { - refDesc = descriptor.getReferenceDescription(this); - } - if (refDesc == null) { - refDesc = calculateDefaultReferenceDescription(getPreferredSize()); - } - return refDesc; - } - - protected Insets calculateDefaultReferenceDescription( - Dimension preferredSize) { - int h = preferredSize.height / 2; - int w = preferredSize.width / 2; - return new Insets(h, w, preferredSize.height - h, preferredSize.width - - w); - } - - public IReferenceDescriptor getReferenceDescriptor() { - return referenceDescriptor; - } - - public void setReference(Point reference) { - if (reference != null) - setReference(reference.x, reference.y); - } - - public void setReference(int referenceX, int referenceY) { - setLocation(calculateLocation(referenceX, referenceY)); - } - - protected Point calculateLocation(int refX, int refY) { - int width = bounds.width; - int height = bounds.height; - Insets ins = getReferenceDescription(); - int insWidth = ins.getWidth(); - int insHeight = ins.getHeight(); - if (width == insWidth) { - refX -= ins.left; - } else if (insWidth > 0) { - refX -= width * ins.left / insWidth; - } - if (height == insHeight) { - refY -= ins.top; - } else if (insHeight > 0) { - refY -= height * ins.top / insHeight; - } - return new Point(refX, refY); - } - - public void setReferenceDescriptor(IReferenceDescriptor descriptor) { - if (descriptor == this.referenceDescriptor) - return; - - this.referenceDescriptor = descriptor; - revalidate(); - } - - public Point getOrigin() { - IOriginBased originBased = getOriginBasedAncestor(this); - if (originBased != null) - return originBased.getOrigin(); - return getReference(); - } - - private IOriginBased getOriginBasedAncestor(IFigure fig) { - IFigure parent = fig.getParent(); - if (parent == null) - return null; - if (parent instanceof IOriginBased) - return (IOriginBased) parent; - return getOriginBasedAncestor(parent); - } - - public void invalidate() { - refDesc = null; - reference = null; - super.invalidate(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.draw2d.IReferencedFigure#getLastReference() - */ - public Point getLastReference() { - if (lastReference == null) { - lastReference = getReference(); - } - return lastReference; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.FreeformLayer; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; + +public class ReferencedLayer extends FreeformLayer implements IReferencedFigure { + + private IReferenceDescriptor referenceDescriptor = null; + + private Insets refDesc = null; + + private Point reference = null; + + private Point lastReference = null; + + public int getOrientation() { + return Geometry.getOrientation(getReference(), getOrigin()); + } + + public Rectangle getPreferredBounds(Point reference) { + return Geometry.getExpanded(reference, getReferenceDescription()); + } + + public Rectangle getPreferredBounds(Rectangle rect, Point reference) { + Insets ins = getReferenceDescription(); + rect.setLocation(reference.x - ins.left, reference.y - ins.top); + rect.setSize(ins.getWidth(), ins.getHeight()); + return rect; + } + + public Rectangle getPreferredClientArea(Point reference) { + if (getLayoutManager() instanceof IReferencedLayout) { + Rectangle area = ((IReferencedLayout) getLayoutManager()) + .getPreferredClientArea(this); + return area.getTranslated(reference); + } + return new Rectangle(0, 0, 0, 0); + } + + public Point getReference() { + if (reference == null) { + reference = calculateReference(getBounds()); + lastReference = reference; + } + return reference; + } + + protected Point calculateReference(Rectangle bounds) { + Insets ins = getReferenceDescription(); + int insWidth = ins.getWidth(); + int insHeight = ins.getHeight(); + int x = bounds.x; + int y = bounds.y; + if (bounds.width == insWidth) { + x += ins.left; + } else if (insWidth > 0) { + x += bounds.width * ins.left / insWidth; + } + if (bounds.height == insHeight) { + y += ins.top; + } else if (insHeight > 0) { + y += bounds.height * ins.top / insHeight; + } + return new Point(x, y); + } + + public Insets getReferenceDescription() { + if (refDesc != null) + return refDesc; + + IReferenceDescriptor descriptor = getReferenceDescriptor(); + if (descriptor != null) { + refDesc = descriptor.getReferenceDescription(this); + } + if (refDesc == null) { + refDesc = calculateDefaultReferenceDescription(getPreferredSize()); + } + return refDesc; + } + + protected Insets calculateDefaultReferenceDescription( + Dimension preferredSize) { + int h = preferredSize.height / 2; + int w = preferredSize.width / 2; + return new Insets(h, w, preferredSize.height - h, preferredSize.width + - w); + } + + public IReferenceDescriptor getReferenceDescriptor() { + return referenceDescriptor; + } + + public void setReference(Point reference) { + if (reference != null) + setReference(reference.x, reference.y); + } + + public void setReference(int referenceX, int referenceY) { + setLocation(calculateLocation(referenceX, referenceY)); + } + + protected Point calculateLocation(int refX, int refY) { + int width = bounds.width; + int height = bounds.height; + Insets ins = getReferenceDescription(); + int insWidth = ins.getWidth(); + int insHeight = ins.getHeight(); + if (width == insWidth) { + refX -= ins.left; + } else if (insWidth > 0) { + refX -= width * ins.left / insWidth; + } + if (height == insHeight) { + refY -= ins.top; + } else if (insHeight > 0) { + refY -= height * ins.top / insHeight; + } + return new Point(refX, refY); + } + + public void setReferenceDescriptor(IReferenceDescriptor descriptor) { + if (descriptor == this.referenceDescriptor) + return; + + this.referenceDescriptor = descriptor; + revalidate(); + } + + public Point getOrigin() { + IOriginBased originBased = getOriginBasedAncestor(this); + if (originBased != null) + return originBased.getOrigin(); + return getReference(); + } + + private IOriginBased getOriginBasedAncestor(IFigure fig) { + IFigure parent = fig.getParent(); + if (parent == null) + return null; + if (parent instanceof IOriginBased) + return (IOriginBased) parent; + return getOriginBasedAncestor(parent); + } + + public void invalidate() { + refDesc = null; + reference = null; + super.invalidate(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.draw2d.IReferencedFigure#getLastReference() + */ + public Point getLastReference() { + if (lastReference == null) { + lastReference = getReference(); + } + return lastReference; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableSizeableImageFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableSizeableImageFigure.java index 81f2722db..5ca572ae8 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableSizeableImageFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableSizeableImageFigure.java @@ -1,113 +1,113 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Image; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; - -/** - * @author Frank Shaka - */ -public class RotatableSizeableImageFigure extends SizeableImageFigure implements - IRotatableFigure { - - private PrecisionRotator rotator = new PrecisionRotator(); - - private PrecisionDimension normalPrefSize = null; - - private Dimension rotatedPrefSize = null; - - public RotatableSizeableImageFigure() { - } - - public RotatableSizeableImageFigure(Image image) { - super(image); - } - - public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { - if (normalPrefSize == null) { - normalPrefSize = new PrecisionDimension(super.getPreferredSize( - wHint, hHint)); - } - return normalPrefSize; - } - - public Dimension getPreferredSize(int wHint, int hHint) { - if (rotatedPrefSize == null) { - rotatedPrefSize = rotator.td(getNormalPreferredSize(wHint, hHint)) - .toDraw2DDimension(); - } - return rotatedPrefSize; - } - - public void invalidate() { - super.invalidate(); - normalPrefSize = null; - rotatedPrefSize = null; - } - - public double getRotationDegrees() { - return rotator.getAngle(); - } - - public void setRotationDegrees(double angle) { - double oldAngle = getRotationDegrees(); - if (Math.abs(oldAngle - angle) < 0.00000001d) - return; - rotator.setAngle(angle); - revalidate(); - repaint(); - } - - private boolean isRotated() { - return !Geometry.isSameAngleDegree(getRotationDegrees(), 0, 0.0000001); - } - - protected void paintImage(Graphics graphics, Image image, - Dimension imageSize, Rectangle clientArea) { - if (!isRotated()) { - super.paintImage(graphics, image, imageSize, clientArea); - return; - } -// Dimension realClientSize = rotator.a(clientArea.getSize(), -// imageSize.width, -1); - Point center = clientArea.getCenter(); - rotator.setOrigin(center.x, center.y); - PrecisionRectangle r = rotator.r(new PrecisionRectangle(clientArea), - imageSize.width, -1).translate(-center.x, -center.y); -// Rectangle realClientArea = new Rectangle(); -// realClientArea.setSize(realClientSize); -// Dimension delta = realClientSize.getScaled(0.5); -// realClientArea.translate(-delta.width, -delta.height); - - graphics.pushState(); - try { - graphics.translate(center.x, center.y); - graphics.rotate((float) getRotationDegrees()); - super.paintImage(graphics, image, imageSize, r.toDraw2DRectangle()); - graphics.translate(-center.x, -center.y); - } finally { - graphics.popState(); - graphics.restoreState(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Image; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; + +/** + * @author Frank Shaka + */ +public class RotatableSizeableImageFigure extends SizeableImageFigure implements + IRotatableFigure { + + private PrecisionRotator rotator = new PrecisionRotator(); + + private PrecisionDimension normalPrefSize = null; + + private Dimension rotatedPrefSize = null; + + public RotatableSizeableImageFigure() { + } + + public RotatableSizeableImageFigure(Image image) { + super(image); + } + + public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { + if (normalPrefSize == null) { + normalPrefSize = new PrecisionDimension(super.getPreferredSize( + wHint, hHint)); + } + return normalPrefSize; + } + + public Dimension getPreferredSize(int wHint, int hHint) { + if (rotatedPrefSize == null) { + rotatedPrefSize = rotator.td(getNormalPreferredSize(wHint, hHint)) + .toDraw2DDimension(); + } + return rotatedPrefSize; + } + + public void invalidate() { + super.invalidate(); + normalPrefSize = null; + rotatedPrefSize = null; + } + + public double getRotationDegrees() { + return rotator.getAngle(); + } + + public void setRotationDegrees(double angle) { + double oldAngle = getRotationDegrees(); + if (Math.abs(oldAngle - angle) < 0.00000001d) + return; + rotator.setAngle(angle); + revalidate(); + repaint(); + } + + private boolean isRotated() { + return !Geometry.isSameAngleDegree(getRotationDegrees(), 0, 0.0000001); + } + + protected void paintImage(Graphics graphics, Image image, + Dimension imageSize, Rectangle clientArea) { + if (!isRotated()) { + super.paintImage(graphics, image, imageSize, clientArea); + return; + } +// Dimension realClientSize = rotator.a(clientArea.getSize(), +// imageSize.width, -1); + Point center = clientArea.getCenter(); + rotator.setOrigin(center.x, center.y); + PrecisionRectangle r = rotator.r(new PrecisionRectangle(clientArea), + imageSize.width, -1).translate(-center.x, -center.y); +// Rectangle realClientArea = new Rectangle(); +// realClientArea.setSize(realClientSize); +// Dimension delta = realClientSize.getScaled(0.5); +// realClientArea.translate(-delta.width, -delta.height); + + graphics.pushState(); + try { + graphics.translate(center.x, center.y); + graphics.rotate((float) getRotationDegrees()); + super.paintImage(graphics, image, imageSize, r.toDraw2DRectangle()); + graphics.translate(-center.x, -center.y); + } finally { + graphics.popState(); + graphics.restoreState(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableWrapLabel.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableWrapLabel.java index ad668cc59..5d0e9ba38 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableWrapLabel.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/RotatableWrapLabel.java @@ -1,974 +1,962 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.draw2d.AbstractBackground; -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.TextStyle; -import org.eclipse.swt.internal.DPIUtil; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.gef.util.GEFUtils; - -import com.ibm.icu.text.BreakIterator; - -/** - * @author Frank Shaka - */ -@SuppressWarnings("restriction") -public class RotatableWrapLabel extends Figure implements ITextFigure, - IWrapFigure, IRotatableFigure, ITransparentableFigure { - - private static final int FLAG_SINGLE_LINE = MAX_FLAG << 1; - private static final int FLAG_ABBREVIATED = MAX_FLAG << 2; - - static { - MAX_FLAG = FLAG_ABBREVIATED; - } - - private static final float PADDING = 1.5f; - private static final float RIGHT_MARGIN = 1.0f; - private static final float[] RECT = new float[4]; - private static final PrecisionDimension D = new PrecisionDimension(); - private static final PrecisionRectangle R = new PrecisionRectangle(); - - protected static final Dimension NO_TEXT_SIZE = new Dimension(1, 10); - - public static final int NORMAL = 0; - public static final int ADVANCED = 1; - - public static final String ELLIPSE = "..."; //$NON-NLS-1$ - - /* - * Infos: - */ - private String text = ""; //$NON-NLS-1$ - - private TextStyle style = null; - - private int align = PositionConstants.LEFT; - - private int textCase = GEF.MANUAL; - - private int renderStyle = NORMAL; - - private int lineSpacing = -1; - - private int textAlpha = 0xff; - - private int fillAlpha = 0xff; - - private int prefWidth = -1; - - /* - * Caches: - */ - private Dimension cachedPrefSize = null; - private String appliedText = null; - private PrecisionRectangle textArea = null; - private PrecisionDimension nonRotatedPrefSize = null; - private PrecisionInsets rotatedInsets = null; - private int cachedWidthHint = -1; - private static Map textToLabelWidth = new HashMap(); - - private PrecisionRotator rotator = new PrecisionRotator(); - - /** - * - */ - public RotatableWrapLabel() { - } - - public RotatableWrapLabel(String text) { - setCachedPrefWidth(text); - setText(text); - } - - public RotatableWrapLabel(int renderStyle) { - this.renderStyle = renderStyle; - } - - public RotatableWrapLabel(String text, int renderStyle) { - setCachedPrefWidth(text); - setText(text); - this.renderStyle = renderStyle; - } - - public int getPrefWidth() { - return prefWidth; - } - - public void setPrefWidth(int prefWidth) { - if (prefWidth == this.prefWidth) - return; - this.prefWidth = prefWidth; - revalidate(); - repaint(); - } - - public boolean isSingleLine() { - return getFlag(FLAG_SINGLE_LINE); - } - - public void setSingleLine(boolean singleLine) { - if (singleLine == isSingleLine()) - return; - setFlag(FLAG_SINGLE_LINE, singleLine); - revalidate(); - repaint(); - } - - public boolean isAbbreviated() { - return getFlag(FLAG_ABBREVIATED); - } - - public void setAbbreviated(boolean abbreviated) { - if (abbreviated == isAbbreviated()) - return; - setFlag(FLAG_ABBREVIATED, abbreviated); - revalidate(); - repaint(); - } - - public void setMainAlpha(int alpha) { - if (alpha == this.textAlpha) - return; - this.textAlpha = alpha; - repaint(); - } - - public int getMainAlpha() { - return textAlpha; - } - - public void setSubAlpha(int alpha) { - if (alpha == this.fillAlpha) - return; - this.fillAlpha = alpha; - repaint(); - } - - public int getSubAlpha() { - return fillAlpha; - } - - /** - * @see org.xmind.gef.draw2d.ITextFigure#getStyle() - */ - public TextStyle getStyle() { - return style; - } - - public int getRenderStyle() { - return renderStyle; - } - - /** - * @return the text of this label figure (never be null) - */ - public String getText() { - return text; - } - - /** - * @see org.xmind.gef.draw2d.ITextFigure#getTextAlignment() - */ - public int getTextAlignment() { - return align; - } - - /** - * @see org.xmind.gef.draw2d.ITextFigure#getTextCase() - */ - public int getTextCase() { - return textCase; - } - - /** - * Gets the angle in degrees by which the label is rotated. - * - * @return the rotateAngle - */ - public double getRotationDegrees() { - return rotator.getAngle(); - } - - /** - * Sets the angle in degrees by which the label is rotated. - * - * @param degrees - * the rotateAngle to set - */ - public void setRotationDegrees(double degrees) { - double oldAngle = getRotationDegrees(); - rotator.setAngle(degrees); - if (getBorder() instanceof IRotatable) { - ((IRotatable) getBorder()).setRotationDegrees(degrees); - } - if (getLayoutManager() instanceof IRotatable) { - ((IRotatable) getLayoutManager()).setRotationDegrees(degrees); - } - for (Object child : getChildren()) { - if (child instanceof IRotatable) { - ((IRotatable) child).setRotationDegrees(degrees); - } - } - if (degrees != oldAngle) { - revalidate(); - repaint(); - } - } - -// public Rotator getRotator() { -// return rotator.getRotator(); -// } -// -// public void setRotator(Rotator rotator) { -// this.rotator.setRotator(rotator); -// setRotateAngle(rotator.getAngle()); -// } - - /** - * @see org.xmind.gef.draw2d.ITextFigure#setStyle(org.eclipse.swt.graphics.TextStyle) - */ - public void setStyle(TextStyle style) { - if (GEFUtils.equals(this.style, style)) - return; - this.style = style; - if (style != null) { - super.setFont(style.font); - super.setForegroundColor(style.foreground); - } else { - super.setFont(null); - super.setForegroundColor(null); - } - repaint(); - } - - @Override - public void setFont(Font f) { - Font old = getLocalFont(); - super.setFont(f); - if (getLocalFont() != old) { - if (style != null) - style.font = f; - } - } - - @Override - public void setForegroundColor(Color fg) { - Color old = getLocalForegroundColor(); - super.setForegroundColor(fg); - if (getLocalForegroundColor() != old) { - if (style != null) - style.foreground = fg; - } - } - - public void setRenderStyle(int style) { - if (style == this.renderStyle || (style != NORMAL && style != ADVANCED)) - return; - this.renderStyle = style; - revalidate(); - repaint(); - } - - /** - * @see org.xmind.gef.draw2d.ITextFigure#setText(java.lang.String) - */ - public void setText(String text) { - // "text" will never be null. - if (text == null) - text = ""; //$NON-NLS-1$ - String t = text.replaceAll("\\r\\n|\\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ - if (this.text.equals(t)) - return; - this.text = t; - revalidate(); - repaint(); - } - - public void setTextAlignment(int align) { - if (this.align == align) - return; - this.align = align; - repaint(); - } - - public void setTextCase(int textCase) { - if (this.textCase == textCase) - return; - this.textCase = textCase; - revalidate(); - repaint(); - } - - protected void receiveWidthCaches(int wHint) { - if (wHint != cachedWidthHint) { - flushCaches(); - } - cachedWidthHint = wHint; - } - - protected void flushCaches() { - cachedPrefSize = null; - appliedText = null; - textArea = null; - nonRotatedPrefSize = null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int) - */ - @Override - public Dimension getPreferredSize(int wHint, int hHint) { - if (prefSize != null) - return prefSize; - if (prefWidth > 0) { - wHint = Math.max(0, prefWidth - getInsets().getWidth()); - } else if (wHint > 0) { - wHint = Math.max(0, wHint - getInsets().getWidth()); - } - receiveWidthCaches(wHint); - if (getText().length() == 0) - return NO_TEXT_SIZE; - if (cachedPrefSize == null) { - cachedPrefSize = calculateRotatedPreferredSize(wHint, hHint) - .toBiggerDraw2DDimension(); - cachedPrefSize.union(getMinimumSize(wHint, hHint)); - } - return cachedPrefSize; - } - - protected PrecisionDimension calculateRotatedPreferredSize(int wHint, - int hHint) { - PrecisionDimension d = getNormalPreferredSize(wHint, hHint); - return rotator.td(d); - } - - public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { - if (prefWidth > 0) { - wHint = Math.max(0, prefWidth - getInsets().getWidth()); - } else if (wHint > 0) { - wHint = Math.max(0, wHint - getInsets().getWidth()); - } - receiveWidthCaches(wHint); - if (nonRotatedPrefSize == null) { - nonRotatedPrefSize = calculateNormalPreferredSize(wHint); - } - return nonRotatedPrefSize; - } - - /** - * @param hint - * @param hint2 - * @return - */ - protected PrecisionDimension calculateNormalPreferredSize(int wHint) { - PrecisionDimension d = getTextArea(wHint).getSize(); - Insets insets = getInsets(); - d.expand(insets.getWidth(), insets.getHeight()); - return d; - } - - public String getAppliedText() { - return getAppliedText(cachedWidthHint); - } - - protected String getAppliedText(int wHint) { - receiveWidthCaches(wHint); - if (appliedText == null) { - appliedText = calculateAppliedText(wHint); - } - return appliedText; - } - - /** - * @param wHint - * @return - */ - protected String calculateAppliedText(double wHint) { - String theText = getText(); - if (wHint < 0 || theText.length() == 0) - return theText; - - Font f = getFont(); - if (isSingleLine()) { - if (isAbbreviated()) - return getAbbreviatedText(theText, f, wHint); - return theText; - } - - String[] lines = forceSplit(theText); - StringBuilder accumlatedText = new StringBuilder(theText.length() + 10); - for (int lineIndex = 0; lineIndex < lines.length; lineIndex++) { - String line = lines[lineIndex]; - if (line.length() == 0) { - accumlatedText.append('\n'); - } else { - StringBuilder remainingLine = new StringBuilder(line); - int i = 0; - while (remainingLine.length() > 0) { - i = getLineWrapPosition(remainingLine.toString(), f, wHint); - if (i == 0) - break; - - String substring = trim(remainingLine.substring(0, i)); - if (isAbbreviated()) { - substring = getAbbreviatedText(substring, f, wHint); - } - accumlatedText.append(substring); - remainingLine.delete(0, i); - accumlatedText.append('\n'); - } - } - } - if (accumlatedText.charAt(accumlatedText.length() - 1) == '\n') - accumlatedText.deleteCharAt(accumlatedText.length() - 1); - return accumlatedText.toString(); - } - - private static String[] forceSplit(String s) { - List buffer = new ArrayList(s.length()); - int start = 0; - for (int end = 0; end < s.length(); end++) { - char c = s.charAt(end); - if (c == '\n') { - buffer.add(s.substring(start, end)); - start = end + 1; - } - } - buffer.add(s.substring(start)); - return buffer.toArray(new String[buffer.size()]); - } - - private String getAbbreviatedText(String theText, Font f, double wHint) { - String result = theText; - int textLength = result.length(); - if (wHint > 0 && textLength > 0) { - textToLabelWidth.put(text, (int) wHint); - int textWidth = getLooseTextSize(result, f).width; - if (textWidth > wHint) { - int tructionPosition = (int) ((double) result.length() - / (double) (textWidth) * (int) wHint); - if (tructionPosition < textLength) - if (tructionPosition > ELLIPSE.length()) { - tructionPosition -= ELLIPSE.length(); - } - return result.substring(0, tructionPosition) + ELLIPSE; - } - } - return result; - } - - /** - * returns the position of last character within the supplied text that will - * fit within the supplied width. - * - * @param s - * a text string - * @param f - * font used to draw the text string - * @param w - * width in pixels. - */ - protected int getLineWrapPosition(String s, Font f, double w) { - // create an iterator for line breaking positions - BreakIterator iter = BreakIterator.getLineInstance(); - iter.setText(s); - int start = iter.first(); - int end = iter.next(); - - // if the first line segment does not fit in the width, - // determine the position within it where we need to cut - if (getSubTextSize(s, start, end, f).width > w) { - iter = BreakIterator.getWordInstance(); // BreakIterator.getCharacterInstance(); - iter.setText(s); - start = iter.first(); - - // if the first word does not fit in the width, - // just return the full length of the very word - end = iter.next(); - if (end == BreakIterator.DONE) - return iter.last(); - if (getSubTextSize(s, start, end, f).width > w) - return end; - } - - // keep iterating as long as width permits - do - end = iter.next(); - while (end != BreakIterator.DONE - && getSubTextSize(s, start, end, f).width <= w); - return (end == BreakIterator.DONE) ? iter.last() : iter.previous(); - } - - private Dimension getSubTextSize(String s, int start, int end, Font f) { - String t = trim(s.substring(start, end)); - t = getShowText(t, getTextCase()); - Dimension size = getLooseTextSize(t, f); - return size; - } - - protected String getShowText(String t, int textCase) { - switch (textCase) { - case GEF.MANUAL: - return t; - case GEF.UPPERCASE: - return t.toUpperCase(); - case GEF.LOWERCASE: - return t.toLowerCase(); - case GEF.CAPITALIZE: - return capitalize(t); - } - return t; - } - - private String capitalize(String str) { - StringBuffer stringbf = new StringBuffer(); -// Matcher m = Pattern -// .compile("([^\\s])([^\\s]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$ -// .matcher(str); - Matcher m = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$ - .matcher(str); - while (m.find()) { - m.appendReplacement(stringbf, - m.group(1).toUpperCase() + m.group(2).toLowerCase()); - } - return m.appendTail(stringbf).toString(); - } - - private static String trim(String s) { - return s.replaceAll("\\n", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - -// protected PrecisionDimension getTightTextSize(String s, Font f) { -// if (s.length() == 0) { -// int height = GraphicsUtils.getAdvanced().getFontMetrics(f) -// .getHeight(); -// return new PrecisionDimension(0, height); -// } else if (!isNormalRenderStyle()) { -// Path textShape = new Path(Display.getCurrent()); -// textShape.addString(s, 0, 0, f); -// textShape.getBounds(_bounds); -// textShape.dispose(); -// return new PrecisionDimension(_bounds[2], _bounds[3]); -// } -// return getLooseTextSize(s, f); -// } - - protected Dimension getLooseTextSize(String s, Font f) { - if (s.length() == 0) { - int height = GraphicsUtils.getAdvanced().getFontMetrics(f) - .getHeight(); - return new Dimension(0, height); - } - Dimension size = GraphicsUtils.getAdvanced().getTextSize(s, f); - if (!isNormalRenderStyle()) { - Path p = new Path(Display.getCurrent()); - p.addString(s, 0, 0, f); - p.getBounds(RECT); - if (Util.isWindows()) { - float[] autoScaleDown = DPIUtil.autoScaleDown(RECT); - RECT[0] = autoScaleDown[0]; - RECT[1] = autoScaleDown[1]; - RECT[2] = autoScaleDown[2]; - RECT[3] = autoScaleDown[3]; - } - p.dispose(); - size.width = Math.max(size.width, (int) Math.ceil(RECT[2])); - size.height = Math.max(size.height, (int) Math.ceil(RECT[3])); - } - return size; - } - -// protected PrecisionDimension getPrecisionLooseTextSize(String s, Font f) { -// return new PrecisionDimension(getLooseTextSize(s, f)); -// } - - protected PrecisionRectangle getTextArea() { - return getTextArea(cachedWidthHint); - } - - /** - * Returns the area of the label's text. - * - * @param wHint - * @return the area of this label's text - */ - protected PrecisionRectangle getTextArea(int wHint) { - receiveWidthCaches(wHint); - if (textArea == null) { - PrecisionDimension size = calculateTextSize(wHint); - textArea = new PrecisionRectangle(); - float rightMargin = RIGHT_MARGIN; - int height = getFont().getFontData()[0].getHeight(); - if (height > 30) - rightMargin = rightMargin + 5; - textArea.width = size.width + PADDING * 2 + rightMargin; - textArea.height = size.height + PADDING * 2; - textArea.x = -(textArea.width / 2); - textArea.y = -(textArea.height / 2); - } - return textArea; - } - - /** - * Calculates and returns the size of the Label's text. - * - * @param wHint - * @return the size of the label's text, ignoring truncation - */ - protected PrecisionDimension calculateTextSize(int wHint) { - Font f = getFont(); - String theText = getAppliedText(wHint); - String[] split = forceSplit(theText); - PrecisionDimension size = D.setSize(0, 0); - final int textCase = getTextCase(); - for (String s : split) { - String t = getShowText(s, textCase); - Dimension d = getLooseTextSize(t, f); - if (size.height > 0) - size.height += getLineSpacing(); - size.height += d.height; - size.width = Math.max(size.width, d.width); - } - //size.union(getTextExtents(theText, f)); - return size; - } - - public int getLineSpacing() { - if (lineSpacing < 0) - lineSpacing = calculateDefaultLineSpacing(); - return lineSpacing; - } - - public void setLineSpacing(int spacing) { - if (this.lineSpacing >= 0 && spacing == this.lineSpacing) - return; - - this.lineSpacing = spacing; - revalidate(); - repaint(); - } - - protected int calculateDefaultLineSpacing() { - Dimension s1 = getLooseTextSize("X\nX", getFont()); //$NON-NLS-1$ - Dimension s = getLooseTextSize("X", getFont()); //$NON-NLS-1$ - return (int) Math.max(0, s1.height - s.height * 2); - } - - @Override - public Insets getInsets() { - if (isRotated()) - return getRotatedInsets().toDraw2DInsets(); - return super.getInsets(); - } - - protected PrecisionInsets getRotatedInsets() { - if (rotatedInsets == null) - rotatedInsets = calculateRotatedInsets(); - return rotatedInsets; - } - - protected PrecisionInsets calculateRotatedInsets() { - PrecisionInsets ins = new PrecisionInsets(super.getInsets()); - return isRotated() ? rotator.t(ins) : ins; - } - - /** - * @see org.eclipse.draw2d.Figure#invalidate() - */ - @Override - public void invalidate() { - flushCaches(); - rotatedInsets = null; - super.invalidate(); - } - - protected boolean isRotated() { - return Math.abs(getRotationDegrees()) > 0.0000001; - } - - @Override - protected void paintBorder(Graphics graphics) { - graphics.setAlpha(getSubAlpha()); - super.paintBorder(graphics); - } - - /** - * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) - */ - @Override - protected void paintFigure(Graphics graphics) { - graphics.setAntialias(SWT.ON); - graphics.setTextAntialias(SWT.ON); - - if (getBorder() instanceof AbstractBackground) { - int oldAlpha = graphics.getAlpha(); - graphics.setAlpha(getSubAlpha()); - ((AbstractBackground) getBorder()).paintBackground(this, graphics, - NO_INSETS); - graphics.setAlpha(oldAlpha); - } - - PrecisionPoint pCenter = calculateTextCenterLocation(); - Point center = null; - boolean rotated = isRotated(); - - Rectangle clientArea = getClientArea(); - - double wHint = rotator - .r(D.setSize(clientArea.width, clientArea.height)).width; - PrecisionRectangle rect = new PrecisionRectangle( - getTextArea((int) wHint)); - PrecisionDimension d = new PrecisionDimension(getSize()); - Insets ins = getInsets(); - double insWidth = ins.getWidth(); - double insHeight = ins.getHeight(); - if (rotated) { - d = rotator.r(d, -1, rect.height + super.getInsets().getHeight()); - d.expand(-insWidth, -insHeight); - rect.x -= (d.width - rect.width) / 2; - rect.width = d.width; - center = pCenter.toRoundedDraw2DPoint(); - rect.translate(new PrecisionPoint(center).getDifference(pCenter)); - graphics.translate(center); - graphics.rotate((float) getRotationDegrees()); - } else { - d.expand(-insWidth, -insHeight); - rect.x -= (d.width - rect.width) / 2; - rect.width = d.width; - rect.translate(pCenter); - } - - paintTextArea(graphics, rect); - if (rotated && center != null) { - graphics.translate(center.negate()); - graphics.rotate(-(float) getRotationDegrees()); - } - } - - /** - * @return - */ - private PrecisionPoint calculateTextCenterLocation() { - PrecisionRectangle rect = R.setBounds(getBounds()); - return rect.crop(getRotatedInsets()).getCenter(); - } - - /** - * Paints the text area of this label using the given Graphics object.
- *
- * IMPORTANT: Subclasses should never use any method that might - * access clipping in the given Graphics, such as - *
  • {@link Graphics#getClip(Rectangle)},
  • - *
  • {@link Graphics#setClip(Rectangle)},
  • - *
  • {@link Graphics#setClip(org.eclipse.swt.graphics.Path)},
  • - *
  • {@link Graphics#clipRect(Rectangle)},
  • - *
  • {@link Graphics#translate(int, int)},
  • - *
  • {@link Graphics#translate(float, float)},
  • - *
  • {@link Graphics#translate(Point)},
  • - *
  • {@link Graphics#pushState()},
  • - *
  • {@link Graphics#restoreState()},

  • - *
    - * for the given Graphics' coordinates may have been rotated and clipping is - * no longer preserved.
    - *
    - * - * @param graphics - * @param textArea - * @see Graphics#rotate(float) - */ - protected void paintTextArea(Graphics graphics, - PrecisionRectangle textArea) { - if (isOpaque() && getLocalBackgroundColor() != null) { - int oldAlpha = graphics.getAlpha(); - graphics.setAlpha(getSubAlpha()); - Path bg = new Path(Display.getCurrent()); - bg.addRectangle(textArea); - graphics.fillPath(bg); - bg.dispose(); - graphics.setAlpha(oldAlpha); - } - int oldAlpha = graphics.getAlpha(); - graphics.setAlpha(getMainAlpha()); - paintText(graphics, getAppliedText((int) Math.ceil(textArea.width)), - textArea, getFont()); - graphics.setAlpha(oldAlpha); - } - - /** - * IMPORTANT: Subclasses should never use any method that might - * access clipping in the given Graphics, such as - *
  • {@link Graphics#getClip(Rectangle)},
  • - *
  • {@link Graphics#setClip(Rectangle)},
  • - *
  • {@link Graphics#setClip(org.eclipse.swt.graphics.Path)},
  • - *
  • {@link Graphics#clipRect(Rectangle)},
  • - *
  • {@link Graphics#translate(int, int)},
  • - *
  • {@link Graphics#translate(float, float)},
  • - *
  • {@link Graphics#translate(Point)},
  • - *
  • {@link Graphics#pushState()},
  • - *
  • {@link Graphics#restoreState()},

  • - *
    - * for the given Graphics' coordinates may have been rotated and clipping is - * no longer preserved.
    - *
    - * - * @param graphics - * @param text - * @param textArea - */ - protected void paintText(Graphics graphics, String text, - PrecisionRectangle textArea, Font f) { - String[] tokens = forceSplit(text); - float textWidth = (float) textArea.width - PADDING * 2; - float y = (float) textArea.y + PADDING; - float vSpacing = getLineSpacing(); - final int wrapAlignment = getTextAlignment(); - final int textCase = getTextCase(); - boolean isUnderlined = isTextUnderlined(); - boolean isStrikedThrough = isTextStrikedThrough(); - - //graphics.drawRectangle(textArea.toDraw2DRectangle().resize(-1, -1)); - - for (String token : tokens) { - float x = (float) textArea.x + PADDING; - String t = getShowText(token, textCase); - Dimension tokenSize = getLooseTextSize(t, f); - float tokenWidth = tokenSize.width; - float tokenHeight = tokenSize.height; - float tokenHeightHalf = tokenHeight / 2; - - switch (wrapAlignment) { - case PositionConstants.CENTER: - x += (textWidth - tokenWidth) / 2; - break; - case PositionConstants.RIGHT: - x += textWidth - tokenWidth - RIGHT_MARGIN; - break; - } - - paintText(graphics, t, x, y, tokenWidth, tokenHeight, f); - - y += tokenHeight; - - if (isUnderlined) { - Path underline = new Path(Display.getCurrent()); - underline.moveTo(x, y - 1); - underline.lineTo(x + tokenWidth, y - 1); - graphics.drawPath(underline); - underline.dispose(); - } - if (isStrikedThrough) { - Path strikeOutLine = new Path(Display.getCurrent()); - strikeOutLine.moveTo(x, y - tokenHeightHalf + 1); - strikeOutLine.lineTo(x + tokenWidth, y - tokenHeightHalf + 1); - graphics.drawPath(strikeOutLine); - strikeOutLine.dispose(); - } - - y += vSpacing; - } - } - - protected void paintText(Graphics graphics, String token, float x, float y, - float width, float height, Font f) { - if (isNormalRenderStyle()) { - graphics.translate(x, y); - graphics.drawText(token, 0, 0); - graphics.translate(-x, -y); - return; - } - Path shape = new Path(Display.getCurrent()); - shape.addString(token, 0, 0, f); - shape.getBounds(RECT); - if (Util.isWindows()) { - float[] autoScaleDown = DPIUtil.autoScaleDown(RECT); - RECT[0] = autoScaleDown[0]; - RECT[1] = autoScaleDown[1]; - RECT[2] = autoScaleDown[2]; - RECT[3] = autoScaleDown[3]; - } - - float dx = (width - RECT[2]) / 2 - RECT[0]; - float dy = (height - RECT[3]) / 2 - RECT[1]; - if (Math.abs(dx) > 0.0000000001 || Math.abs(dy) > 0.0000000001) { - shape.dispose(); - shape = new Path(Display.getCurrent()); - shape.addString(token, x + dx, y + dy, f); - } - drawTextShape(graphics, shape); - shape.dispose(); - } - - protected void drawTextShape(Graphics graphics, Path shape) { - graphics.setLineStyle(SWT.LINE_SOLID); - graphics.setLineWidth(1); - graphics.setFillRule(SWT.FILL_WINDING); - graphics.setBackgroundColor(graphics.getForegroundColor()); - graphics.fillPath(shape); - } - - protected boolean isNormalRenderStyle() { - return renderStyle == NORMAL; - } - - /** - * @return - */ - private boolean isTextStrikedThrough() { - return getStyle() != null && getStyle().strikeout; - } - - /** - * @return - */ - private boolean isTextUnderlined() { - return getStyle() != null && getStyle().underline; - } - - public String toString() { - return "RotatableWrapLabl (" + getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - private void setCachedPrefWidth(String text) { - Integer cached = textToLabelWidth.get(text); - if (cached != null) - this.prefWidth = cached; - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.draw2d.AbstractBackground; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.TextStyle; +import org.eclipse.swt.internal.DPIUtil; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.gef.util.GEFUtils; + +import com.ibm.icu.text.BreakIterator; + +/** + * @author Frank Shaka + */ +@SuppressWarnings("restriction") +public class RotatableWrapLabel extends Figure implements ITextFigure, + IWrapFigure, IRotatableFigure, ITransparentableFigure { + + private static final int FLAG_SINGLE_LINE = MAX_FLAG << 1; + private static final int FLAG_ABBREVIATED = MAX_FLAG << 2; + + static { + MAX_FLAG = FLAG_ABBREVIATED; + } + + private static final float PADDING = 1.5f; + private static final float RIGHT_MARGIN = 1.0f; + private static final float[] RECT = new float[4]; + private static final PrecisionDimension D = new PrecisionDimension(); + private static final PrecisionRectangle R = new PrecisionRectangle(); + + protected static final Dimension NO_TEXT_SIZE = new Dimension(1, 10); + + public static final int NORMAL = 0; + public static final int ADVANCED = 1; + + public static final String ELLIPSE = "..."; //$NON-NLS-1$ + + /* + * Infos: + */ + private String text = ""; //$NON-NLS-1$ + + private TextStyle style = null; + + private int align = PositionConstants.LEFT; + + private int textCase = GEF.MANUAL; + + private int renderStyle = NORMAL; + + private int lineSpacing = -1; + + private int textAlpha = 0xff; + + private int fillAlpha = 0xff; + + private int prefWidth = -1; + + /* + * Caches: + */ + private Dimension cachedPrefSize = null; + private String appliedText = null; + private PrecisionRectangle textArea = null; + private PrecisionDimension nonRotatedPrefSize = null; + private PrecisionInsets rotatedInsets = null; + private int cachedWidthHint = -1; + + private PrecisionRotator rotator = new PrecisionRotator(); + + /** + * + */ + public RotatableWrapLabel() { + } + + public RotatableWrapLabel(String text) { + setText(text); + } + + public RotatableWrapLabel(int renderStyle) { + this.renderStyle = renderStyle; + } + + public RotatableWrapLabel(String text, int renderStyle) { + setText(text); + this.renderStyle = renderStyle; + } + + public int getPrefWidth() { + return prefWidth; + } + + public void setPrefWidth(int prefWidth) { + if (prefWidth == this.prefWidth) + return; + this.prefWidth = prefWidth; + revalidate(); + repaint(); + } + + public boolean isSingleLine() { + return getFlag(FLAG_SINGLE_LINE); + } + + public void setSingleLine(boolean singleLine) { + if (singleLine == isSingleLine()) + return; + setFlag(FLAG_SINGLE_LINE, singleLine); + revalidate(); + repaint(); + } + + public boolean isAbbreviated() { + return getFlag(FLAG_ABBREVIATED); + } + + public void setAbbreviated(boolean abbreviated) { + if (abbreviated == isAbbreviated()) + return; + setFlag(FLAG_ABBREVIATED, abbreviated); + revalidate(); + repaint(); + } + + public void setMainAlpha(int alpha) { + if (alpha == this.textAlpha) + return; + this.textAlpha = alpha; + repaint(); + } + + public int getMainAlpha() { + return textAlpha; + } + + public void setSubAlpha(int alpha) { + if (alpha == this.fillAlpha) + return; + this.fillAlpha = alpha; + repaint(); + } + + public int getSubAlpha() { + return fillAlpha; + } + + /** + * @see org.xmind.gef.draw2d.ITextFigure#getStyle() + */ + public TextStyle getStyle() { + return style; + } + + public int getRenderStyle() { + return renderStyle; + } + + /** + * @return the text of this label figure (never be null) + */ + public String getText() { + return text; + } + + /** + * @see org.xmind.gef.draw2d.ITextFigure#getTextAlignment() + */ + public int getTextAlignment() { + return align; + } + + /** + * @see org.xmind.gef.draw2d.ITextFigure#getTextCase() + */ + public int getTextCase() { + return textCase; + } + + /** + * Gets the angle in degrees by which the label is rotated. + * + * @return the rotateAngle + */ + public double getRotationDegrees() { + return rotator.getAngle(); + } + + /** + * Sets the angle in degrees by which the label is rotated. + * + * @param degrees + * the rotateAngle to set + */ + public void setRotationDegrees(double degrees) { + double oldAngle = getRotationDegrees(); + rotator.setAngle(degrees); + if (getBorder() instanceof IRotatable) { + ((IRotatable) getBorder()).setRotationDegrees(degrees); + } + if (getLayoutManager() instanceof IRotatable) { + ((IRotatable) getLayoutManager()).setRotationDegrees(degrees); + } + for (Object child : getChildren()) { + if (child instanceof IRotatable) { + ((IRotatable) child).setRotationDegrees(degrees); + } + } + if (degrees != oldAngle) { + revalidate(); + repaint(); + } + } + +// public Rotator getRotator() { +// return rotator.getRotator(); +// } +// +// public void setRotator(Rotator rotator) { +// this.rotator.setRotator(rotator); +// setRotateAngle(rotator.getAngle()); +// } + + /** + * @see org.xmind.gef.draw2d.ITextFigure#setStyle(org.eclipse.swt.graphics.TextStyle) + */ + public void setStyle(TextStyle style) { + if (GEFUtils.equals(this.style, style)) + return; + this.style = style; + if (style != null) { + super.setFont(style.font); + super.setForegroundColor(style.foreground); + } else { + super.setFont(null); + super.setForegroundColor(null); + } + repaint(); + } + + @Override + public void setFont(Font f) { + Font old = getLocalFont(); + super.setFont(f); + if (getLocalFont() != old) { + if (style != null) + style.font = f; + } + } + + @Override + public void setForegroundColor(Color fg) { + Color old = getLocalForegroundColor(); + super.setForegroundColor(fg); + if (getLocalForegroundColor() != old) { + if (style != null) + style.foreground = fg; + } + } + + public void setRenderStyle(int style) { + if (style == this.renderStyle || (style != NORMAL && style != ADVANCED)) + return; + this.renderStyle = style; + revalidate(); + repaint(); + } + + /** + * @see org.xmind.gef.draw2d.ITextFigure#setText(java.lang.String) + */ + public void setText(String text) { + // "text" will never be null. + if (text == null) + text = ""; //$NON-NLS-1$ + String t = text.replaceAll("\\r\\n|\\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + if (this.text.equals(t)) + return; + this.text = t; + revalidate(); + repaint(); + } + + public void setTextAlignment(int align) { + if (this.align == align) + return; + this.align = align; + repaint(); + } + + public void setTextCase(int textCase) { + if (this.textCase == textCase) + return; + this.textCase = textCase; + revalidate(); + repaint(); + } + + protected void receiveWidthCaches(int wHint) { + if (wHint != cachedWidthHint) { + flushCaches(); + } + cachedWidthHint = wHint; + } + + protected void flushCaches() { + cachedPrefSize = null; + appliedText = null; + textArea = null; + nonRotatedPrefSize = null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int) + */ + @Override + public Dimension getPreferredSize(int wHint, int hHint) { + if (prefSize != null) + return prefSize; + if (prefWidth > 0) { + wHint = Math.max(0, prefWidth - getInsets().getWidth()); + } else if (wHint > 0) { + wHint = Math.max(0, wHint - getInsets().getWidth()); + } + receiveWidthCaches(wHint); + if (getText().length() == 0) + return NO_TEXT_SIZE; + if (cachedPrefSize == null) { + cachedPrefSize = calculateRotatedPreferredSize(wHint, hHint) + .toBiggerDraw2DDimension(); + cachedPrefSize.union(getMinimumSize(wHint, hHint)); + } + return cachedPrefSize; + } + + protected PrecisionDimension calculateRotatedPreferredSize(int wHint, + int hHint) { + PrecisionDimension d = getNormalPreferredSize(wHint, hHint); + return rotator.td(d); + } + + public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { + if (prefWidth > 0) { + wHint = Math.max(0, prefWidth - getInsets().getWidth()); + } else if (wHint > 0) { + wHint = Math.max(0, wHint - getInsets().getWidth()); + } + receiveWidthCaches(wHint); + if (nonRotatedPrefSize == null) { + nonRotatedPrefSize = calculateNormalPreferredSize(wHint); + } + return nonRotatedPrefSize; + } + + /** + * @param hint + * @param hint2 + * @return + */ + protected PrecisionDimension calculateNormalPreferredSize(int wHint) { + PrecisionDimension d = getTextArea(wHint).getSize(); + Insets insets = getInsets(); + d.expand(insets.getWidth(), insets.getHeight()); + return d; + } + + public String getAppliedText() { + return getAppliedText(cachedWidthHint); + } + + protected String getAppliedText(int wHint) { + receiveWidthCaches(wHint); + if (appliedText == null) { + appliedText = calculateAppliedText(wHint); + } + return appliedText; + } + + /** + * @param wHint + * @return + */ + protected String calculateAppliedText(double wHint) { + String theText = getText(); + if (wHint < 0 || theText.length() == 0) + return theText; + + Font f = getFont(); + if (isSingleLine()) { + if (isAbbreviated()) + return getAbbreviatedText(theText, f, wHint); + return theText; + } + + String[] lines = forceSplit(theText); + StringBuilder accumlatedText = new StringBuilder(theText.length() + 10); + for (int lineIndex = 0; lineIndex < lines.length; lineIndex++) { + String line = lines[lineIndex]; + if (line.length() == 0) { + accumlatedText.append('\n'); + } else { + StringBuilder remainingLine = new StringBuilder(line); + int i = 0; + while (remainingLine.length() > 0) { + i = getLineWrapPosition(remainingLine.toString(), f, wHint); + if (i == 0) + break; + + String substring = trim(remainingLine.substring(0, i)); + if (isAbbreviated()) { + substring = getAbbreviatedText(substring, f, wHint); + } + accumlatedText.append(substring); + remainingLine.delete(0, i); + accumlatedText.append('\n'); + } + } + } + if (accumlatedText.charAt(accumlatedText.length() - 1) == '\n') + accumlatedText.deleteCharAt(accumlatedText.length() - 1); + return accumlatedText.toString(); + } + + private static String[] forceSplit(String s) { + List buffer = new ArrayList(s.length()); + int start = 0; + for (int end = 0; end < s.length(); end++) { + char c = s.charAt(end); + if (c == '\n') { + buffer.add(s.substring(start, end)); + start = end + 1; + } + } + buffer.add(s.substring(start)); + return buffer.toArray(new String[buffer.size()]); + } + + private String getAbbreviatedText(String theText, Font f, double wHint) { + String result = theText; + int textLength = result.length(); + if (wHint > 0 && textLength > 0) { + int textWidth = getLooseTextSize(result, f).width; + if (textWidth > wHint) { + int tructionPosition = (int) ((double) result.length() + / (double) (textWidth) * (int) wHint); + if (tructionPosition < textLength) + if (tructionPosition > ELLIPSE.length()) { + tructionPosition -= ELLIPSE.length(); + } + return result.substring(0, tructionPosition) + ELLIPSE; + } + } + return result; + } + + /** + * returns the position of last character within the supplied text that will + * fit within the supplied width. + * + * @param s + * a text string + * @param f + * font used to draw the text string + * @param w + * width in pixels. + */ + protected int getLineWrapPosition(String s, Font f, double w) { + // create an iterator for line breaking positions + BreakIterator iter = BreakIterator.getLineInstance(); + iter.setText(s); + int start = iter.first(); + int end = iter.next(); + + // if the first line segment does not fit in the width, + // determine the position within it where we need to cut + if (getSubTextSize(s, start, end, f).width > w) { + iter = BreakIterator.getWordInstance(); // BreakIterator.getCharacterInstance(); + iter.setText(s); + start = iter.first(); + + // if the first word does not fit in the width, + // just return the full length of the very word + end = iter.next(); + if (end == BreakIterator.DONE) + return iter.last(); + if (getSubTextSize(s, start, end, f).width > w) + return end; + } + + // keep iterating as long as width permits + do + end = iter.next(); + while (end != BreakIterator.DONE + && getSubTextSize(s, start, end, f).width <= w); + return (end == BreakIterator.DONE) ? iter.last() : iter.previous(); + } + + private Dimension getSubTextSize(String s, int start, int end, Font f) { + String t = trim(s.substring(start, end)); + t = getShowText(t, getTextCase()); + Dimension size = getLooseTextSize(t, f); + return size; + } + + protected String getShowText(String t, int textCase) { + switch (textCase) { + case GEF.MANUAL: + return t; + case GEF.UPPERCASE: + return t.toUpperCase(); + case GEF.LOWERCASE: + return t.toLowerCase(); + case GEF.CAPITALIZE: + return capitalize(t); + } + return t; + } + + private String capitalize(String str) { + StringBuffer stringbf = new StringBuffer(); +// Matcher m = Pattern +// .compile("([^\\s])([^\\s]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$ +// .matcher(str); + Matcher m = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$ + .matcher(str); + while (m.find()) { + m.appendReplacement(stringbf, + m.group(1).toUpperCase() + m.group(2).toLowerCase()); + } + return m.appendTail(stringbf).toString(); + } + + private static String trim(String s) { + return s.replaceAll("\\n", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + +// protected PrecisionDimension getTightTextSize(String s, Font f) { +// if (s.length() == 0) { +// int height = GraphicsUtils.getAdvanced().getFontMetrics(f) +// .getHeight(); +// return new PrecisionDimension(0, height); +// } else if (!isNormalRenderStyle()) { +// Path textShape = new Path(Display.getCurrent()); +// textShape.addString(s, 0, 0, f); +// textShape.getBounds(_bounds); +// textShape.dispose(); +// return new PrecisionDimension(_bounds[2], _bounds[3]); +// } +// return getLooseTextSize(s, f); +// } + + protected Dimension getLooseTextSize(String s, Font f) { + if (s.length() == 0) { + int height = GraphicsUtils.getAdvanced().getFontMetrics(f) + .getHeight(); + return new Dimension(0, height); + } + Dimension size = GraphicsUtils.getAdvanced().getTextSize(s, f); + if (!isNormalRenderStyle()) { + Path p = new Path(Display.getCurrent()); + p.addString(s, 0, 0, f); + p.getBounds(RECT); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(RECT); + RECT[0] = autoScaleDown[0]; + RECT[1] = autoScaleDown[1]; + RECT[2] = autoScaleDown[2]; + RECT[3] = autoScaleDown[3]; + } + p.dispose(); + size.width = Math.max(size.width, (int) Math.ceil(RECT[2])); + size.height = Math.max(size.height, (int) Math.ceil(RECT[3])); + } + return size; + } + +// protected PrecisionDimension getPrecisionLooseTextSize(String s, Font f) { +// return new PrecisionDimension(getLooseTextSize(s, f)); +// } + + protected PrecisionRectangle getTextArea() { + return getTextArea(cachedWidthHint); + } + + /** + * Returns the area of the label's text. + * + * @param wHint + * @return the area of this label's text + */ + protected PrecisionRectangle getTextArea(int wHint) { + receiveWidthCaches(wHint); + if (textArea == null) { + PrecisionDimension size = calculateTextSize(wHint); + textArea = new PrecisionRectangle(); + float rightMargin = RIGHT_MARGIN; + int height = getFont().getFontData()[0].getHeight(); + if (height > 30) + rightMargin = rightMargin + 5; + textArea.width = size.width + PADDING * 2 + rightMargin; + textArea.height = size.height + PADDING * 2; + textArea.x = -(textArea.width / 2); + textArea.y = -(textArea.height / 2); + } + return textArea; + } + + /** + * Calculates and returns the size of the Label's text. + * + * @param wHint + * @return the size of the label's text, ignoring truncation + */ + protected PrecisionDimension calculateTextSize(int wHint) { + Font f = getFont(); + String theText = getAppliedText(wHint); + String[] split = forceSplit(theText); + PrecisionDimension size = D.setSize(0, 0); + final int textCase = getTextCase(); + for (String s : split) { + String t = getShowText(s, textCase); + Dimension d = getLooseTextSize(t, f); + if (size.height > 0) + size.height += getLineSpacing(); + size.height += d.height; + size.width = Math.max(size.width, d.width); + } + //size.union(getTextExtents(theText, f)); + return size; + } + + public int getLineSpacing() { + if (lineSpacing < 0) + lineSpacing = calculateDefaultLineSpacing(); + return lineSpacing; + } + + public void setLineSpacing(int spacing) { + if (this.lineSpacing >= 0 && spacing == this.lineSpacing) + return; + + this.lineSpacing = spacing; + revalidate(); + repaint(); + } + + protected int calculateDefaultLineSpacing() { + Dimension s1 = getLooseTextSize("X\nX", getFont()); //$NON-NLS-1$ + Dimension s = getLooseTextSize("X", getFont()); //$NON-NLS-1$ + return (int) Math.max(0, s1.height - s.height * 2); + } + + @Override + public Insets getInsets() { + if (isRotated()) + return getRotatedInsets().toDraw2DInsets(); + return super.getInsets(); + } + + protected PrecisionInsets getRotatedInsets() { + if (rotatedInsets == null) + rotatedInsets = calculateRotatedInsets(); + return rotatedInsets; + } + + protected PrecisionInsets calculateRotatedInsets() { + PrecisionInsets ins = new PrecisionInsets(super.getInsets()); + return isRotated() ? rotator.t(ins) : ins; + } + + /** + * @see org.eclipse.draw2d.Figure#invalidate() + */ + @Override + public void invalidate() { + flushCaches(); + rotatedInsets = null; + super.invalidate(); + } + + protected boolean isRotated() { + return Math.abs(getRotationDegrees()) > 0.0000001; + } + + @Override + protected void paintBorder(Graphics graphics) { + graphics.setAlpha(getSubAlpha()); + super.paintBorder(graphics); + } + + /** + * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) + */ + @Override + protected void paintFigure(Graphics graphics) { + graphics.setAntialias(SWT.ON); + graphics.setTextAntialias(SWT.ON); + + if (getBorder() instanceof AbstractBackground) { + int oldAlpha = graphics.getAlpha(); + graphics.setAlpha(getSubAlpha()); + ((AbstractBackground) getBorder()).paintBackground(this, graphics, + NO_INSETS); + graphics.setAlpha(oldAlpha); + } + + PrecisionPoint pCenter = calculateTextCenterLocation(); + Point center = null; + boolean rotated = isRotated(); + + Rectangle clientArea = getClientArea(); + + double wHint = rotator + .r(D.setSize(clientArea.width, clientArea.height)).width; + PrecisionRectangle rect = new PrecisionRectangle( + getTextArea((int) wHint)); + PrecisionDimension d = new PrecisionDimension(getSize()); + Insets ins = getInsets(); + double insWidth = ins.getWidth(); + double insHeight = ins.getHeight(); + if (rotated) { + d = rotator.r(d, -1, rect.height + super.getInsets().getHeight()); + d.expand(-insWidth, -insHeight); + rect.x -= (d.width - rect.width) / 2; + rect.width = d.width; + center = pCenter.toRoundedDraw2DPoint(); + rect.translate(new PrecisionPoint(center).getDifference(pCenter)); + graphics.translate(center); + graphics.rotate((float) getRotationDegrees()); + } else { + d.expand(-insWidth, -insHeight); + rect.x -= (d.width - rect.width) / 2; + rect.width = d.width; + rect.translate(pCenter); + } + + paintTextArea(graphics, rect); + if (rotated && center != null) { + graphics.translate(center.negate()); + graphics.rotate(-(float) getRotationDegrees()); + } + } + + /** + * @return + */ + private PrecisionPoint calculateTextCenterLocation() { + PrecisionRectangle rect = R.setBounds(getBounds()); + return rect.crop(getRotatedInsets()).getCenter(); + } + + /** + * Paints the text area of this label using the given Graphics object.
    + *
    + * IMPORTANT: Subclasses should never use any method that might + * access clipping in the given Graphics, such as + *
  • {@link Graphics#getClip(Rectangle)},
  • + *
  • {@link Graphics#setClip(Rectangle)},
  • + *
  • {@link Graphics#setClip(org.eclipse.swt.graphics.Path)},
  • + *
  • {@link Graphics#clipRect(Rectangle)},
  • + *
  • {@link Graphics#translate(int, int)},
  • + *
  • {@link Graphics#translate(float, float)},
  • + *
  • {@link Graphics#translate(Point)},
  • + *
  • {@link Graphics#pushState()},
  • + *
  • {@link Graphics#restoreState()},

  • + *
    + * for the given Graphics' coordinates may have been rotated and clipping is + * no longer preserved.
    + *
    + * + * @param graphics + * @param textArea + * @see Graphics#rotate(float) + */ + protected void paintTextArea(Graphics graphics, + PrecisionRectangle textArea) { + if (isOpaque() && getLocalBackgroundColor() != null) { + int oldAlpha = graphics.getAlpha(); + graphics.setAlpha(getSubAlpha()); + Path bg = new Path(Display.getCurrent()); + bg.addRectangle(textArea); + graphics.fillPath(bg); + bg.dispose(); + graphics.setAlpha(oldAlpha); + } + int oldAlpha = graphics.getAlpha(); + graphics.setAlpha(getMainAlpha()); + paintText(graphics, getAppliedText((int) Math.ceil(textArea.width)), + textArea, getFont()); + graphics.setAlpha(oldAlpha); + } + + /** + * IMPORTANT: Subclasses should never use any method that might + * access clipping in the given Graphics, such as + *
  • {@link Graphics#getClip(Rectangle)},
  • + *
  • {@link Graphics#setClip(Rectangle)},
  • + *
  • {@link Graphics#setClip(org.eclipse.swt.graphics.Path)},
  • + *
  • {@link Graphics#clipRect(Rectangle)},
  • + *
  • {@link Graphics#translate(int, int)},
  • + *
  • {@link Graphics#translate(float, float)},
  • + *
  • {@link Graphics#translate(Point)},
  • + *
  • {@link Graphics#pushState()},
  • + *
  • {@link Graphics#restoreState()},

  • + *
    + * for the given Graphics' coordinates may have been rotated and clipping is + * no longer preserved.
    + *
    + * + * @param graphics + * @param text + * @param textArea + */ + protected void paintText(Graphics graphics, String text, + PrecisionRectangle textArea, Font f) { + String[] tokens = forceSplit(text); + float textWidth = (float) textArea.width - PADDING * 2; + float y = (float) textArea.y + PADDING; + float vSpacing = getLineSpacing(); + final int wrapAlignment = getTextAlignment(); + final int textCase = getTextCase(); + boolean isUnderlined = isTextUnderlined(); + boolean isStrikedThrough = isTextStrikedThrough(); + + //graphics.drawRectangle(textArea.toDraw2DRectangle().resize(-1, -1)); + + for (String token : tokens) { + float x = (float) textArea.x + PADDING; + String t = getShowText(token, textCase); + Dimension tokenSize = getLooseTextSize(t, f); + float tokenWidth = tokenSize.width; + float tokenHeight = tokenSize.height; + float tokenHeightHalf = tokenHeight / 2; + + switch (wrapAlignment) { + case PositionConstants.CENTER: + x += (textWidth - tokenWidth) / 2; + break; + case PositionConstants.RIGHT: + x += textWidth - tokenWidth - RIGHT_MARGIN; + break; + } + + paintText(graphics, t, x, y, tokenWidth, tokenHeight, f); + + y += tokenHeight; + + if (isUnderlined) { + Path underline = new Path(Display.getCurrent()); + underline.moveTo(x, y - 1); + underline.lineTo(x + tokenWidth, y - 1); + graphics.drawPath(underline); + underline.dispose(); + } + if (isStrikedThrough) { + Path strikeOutLine = new Path(Display.getCurrent()); + strikeOutLine.moveTo(x, y - tokenHeightHalf + 1); + strikeOutLine.lineTo(x + tokenWidth, y - tokenHeightHalf + 1); + graphics.drawPath(strikeOutLine); + strikeOutLine.dispose(); + } + + y += vSpacing; + } + } + + protected void paintText(Graphics graphics, String token, float x, float y, + float width, float height, Font f) { + if (isNormalRenderStyle()) { + graphics.translate(x, y); + graphics.drawText(token, 0, 0); + graphics.translate(-x, -y); + return; + } + Path shape = new Path(Display.getCurrent()); + shape.addString(token, 0, 0, f); + shape.getBounds(RECT); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(RECT); + RECT[0] = autoScaleDown[0]; + RECT[1] = autoScaleDown[1]; + RECT[2] = autoScaleDown[2]; + RECT[3] = autoScaleDown[3]; + } + + float dx = (width - RECT[2]) / 2 - RECT[0]; + float dy = (height - RECT[3]) / 2 - RECT[1]; + if (Math.abs(dx) > 0.0000000001 || Math.abs(dy) > 0.0000000001) { + shape.dispose(); + shape = new Path(Display.getCurrent()); + shape.addString(token, x + dx, y + dy, f); + } + drawTextShape(graphics, shape); + shape.dispose(); + } + + protected void drawTextShape(Graphics graphics, Path shape) { + graphics.setLineStyle(SWT.LINE_SOLID); + graphics.setLineWidth(1); + graphics.setFillRule(SWT.FILL_WINDING); + graphics.setBackgroundColor(graphics.getForegroundColor()); + graphics.fillPath(shape); + } + + protected boolean isNormalRenderStyle() { + return renderStyle == NORMAL; + } + + /** + * @return + */ + private boolean isTextStrikedThrough() { + return getStyle() != null && getStyle().strikeout; + } + + /** + * @return + */ + private boolean isTextUnderlined() { + return getStyle() != null && getStyle().underline; + } + + public String toString() { + return "RotatableWrapLabl (" + getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/AbstractLineDecoration.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/AbstractLineDecoration.java index 34f39569f..dd7b4ac40 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/AbstractLineDecoration.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/AbstractLineDecoration.java @@ -1,119 +1,119 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; - -public abstract class AbstractLineDecoration extends AbstractDecoration - implements ILineDecoration { - - private Color color = null; - - private int width = 1; - - private int lineStyle = SWT.LINE_SOLID; - - protected AbstractLineDecoration() { - super(); - } - - protected AbstractLineDecoration(String id) { - super(id); - } - - /** - * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#getLineColor() - */ - public Color getLineColor() { - return color; - } - - public int getLineStyle() { - return lineStyle; - } - - /** - * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#getLineWidth() - */ - public int getLineWidth() { - return width; - } - - /** - * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#setLineColor(org.eclipse.swt.graphics.Color) - */ - public void setLineColor(IFigure figure, Color color) { - if (color == this.color || (color != null && color.equals(this.color))) - return; - this.color = color; - if (figure != null) { - repaint(figure); - } - } - - public void setLineStyle(IFigure figure, int style) { - if (style == this.lineStyle) - return; - this.lineStyle = style; - if (figure != null) { - repaint(figure); - } - } - - /** - * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#setLineWidth(int) - */ - public void setLineWidth(IFigure figure, int width) { - if (width == this.width) - return; - this.width = width; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - } - - /** - * @see org.xmind.gef.draw2d.decoration.AbstractDecoration#performPaint(org.eclipse.draw2d.IFigure, - * org.eclipse.draw2d.Graphics) - */ - protected void performPaint(IFigure figure, Graphics g) { - g.setAlpha(getAlpha()); - g.setForegroundColor(getLineColor(figure)); - g.setLineWidth(getLineWidth()); - g.setLineStyle(getLineStyle()); - decorateLine(figure, g); - drawLine(figure, g); - } - - protected void decorateLine(IFigure figure, Graphics g) { - } - - /** - * @param figure - * @param g - * draw a line from the source position to the target position - */ - protected abstract void drawLine(IFigure figure, Graphics g); - - protected Color getLineColor(IFigure figure) { - Color c = getLineColor(); - return c == null ? figure.getForegroundColor() : c; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; + +public abstract class AbstractLineDecoration extends AbstractDecoration + implements ILineDecoration { + + private Color color = null; + + private int width = 1; + + private int lineStyle = SWT.LINE_SOLID; + + protected AbstractLineDecoration() { + super(); + } + + protected AbstractLineDecoration(String id) { + super(id); + } + + /** + * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#getLineColor() + */ + public Color getLineColor() { + return color; + } + + public int getLineStyle() { + return lineStyle; + } + + /** + * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#getLineWidth() + */ + public int getLineWidth() { + return width; + } + + /** + * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#setLineColor(org.eclipse.swt.graphics.Color) + */ + public void setLineColor(IFigure figure, Color color) { + if (color == this.color || (color != null && color.equals(this.color))) + return; + this.color = color; + if (figure != null) { + repaint(figure); + } + } + + public void setLineStyle(IFigure figure, int style) { + if (style == this.lineStyle) + return; + this.lineStyle = style; + if (figure != null) { + repaint(figure); + } + } + + /** + * @see org.xmind.ui.mindmap.layers.decorations.IBranchConnectionDecoration#setLineWidth(int) + */ + public void setLineWidth(IFigure figure, int width) { + if (width == this.width) + return; + this.width = width; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + } + + /** + * @see org.xmind.gef.draw2d.decoration.AbstractDecoration#performPaint(org.eclipse.draw2d.IFigure, + * org.eclipse.draw2d.Graphics) + */ + protected void performPaint(IFigure figure, Graphics g) { + g.setAlpha(getAlpha()); + g.setForegroundColor(getLineColor(figure)); + g.setLineWidth(getLineWidth()); + g.setLineStyle(getLineStyle()); + decorateLine(figure, g); + drawLine(figure, g); + } + + protected void decorateLine(IFigure figure, Graphics g) { + } + + /** + * @param figure + * @param g + * draw a line from the source position to the target position + */ + protected abstract void drawLine(IFigure figure, Graphics g); + + protected Color getLineColor(IFigure figure) { + Color c = getLineColor(); + return c == null ? figure.getForegroundColor() : c; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IConnectionDecorationEx.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IConnectionDecorationEx.java index 6cc08310f..892cbc647 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IConnectionDecorationEx.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IConnectionDecorationEx.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; - -public interface IConnectionDecorationEx extends IConnectionDecoration { - - boolean containsPoint(IFigure figure, int x, int y); - - Rectangle getPreferredBounds(IFigure figure); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; + +public interface IConnectionDecorationEx extends IConnectionDecoration { + + boolean containsPoint(IFigure figure, int x, int y); + + Rectangle getPreferredBounds(IFigure figure); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/ICorneredDecoration.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/ICorneredDecoration.java index db814643f..bf5f2f196 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/ICorneredDecoration.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/ICorneredDecoration.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.IFigure; - -public interface ICorneredDecoration extends IDecoration { - - int getCornerSize(); - - void setCornerSize(IFigure figure, int cornerSize); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.IFigure; + +public interface ICorneredDecoration extends IDecoration { + + int getCornerSize(); + + void setCornerSize(IFigure figure, int cornerSize); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IShadowedDecoration.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IShadowedDecoration.java index c4c010e49..068b07a19 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IShadowedDecoration.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/IShadowedDecoration.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; - -public interface IShadowedDecoration { - - void paintShadow(IFigure figure, Graphics graphics); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; + +public interface IShadowedDecoration { + + void paintShadow(IFigure figure, Graphics graphics); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathConnectionDecoration.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathConnectionDecoration.java index c6770cce1..a4e083ff9 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathConnectionDecoration.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathConnectionDecoration.java @@ -1,114 +1,114 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.internal.DPIUtil; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.Path; - -@SuppressWarnings("restriction") -public abstract class PathConnectionDecoration extends - AbstractConnectionDecoration implements IConnectionDecorationEx { - - protected PathConnectionDecoration() { - } - - protected PathConnectionDecoration(String id) { - super(id); - } - - protected boolean usesFill() { - return false; - } - - protected void drawLine(IFigure figure, Graphics graphics) { - if (usesFill()) { - Color bg = graphics.getBackgroundColor(); - graphics.setBackgroundColor(graphics.getForegroundColor()); - Path shape = new Path(Display.getCurrent()); - route(figure, shape); - paintPath(figure, graphics, shape, true); - shape.dispose(); - graphics.setBackgroundColor(bg); - } else { - Path shape = new Path(Display.getCurrent()); - route(figure, shape); - paintPath(figure, graphics, shape, false); - shape.dispose(); - } - } - - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - if (fill) { - graphics.fillPath(path); - } else { - if (getLineWidth() > 0) - graphics.drawPath(path); - } - } - - protected abstract void route(IFigure figure, Path shape); - - public boolean containsPoint(IFigure figure, int x, int y) { - checkValidation(figure); - GC gc = GraphicsUtils.getAdvanced().getGC(); - gc.setLineWidth(getLineWidthForChecking()); - Path shape = new Path(Display.getCurrent()); - route(figure, shape); - boolean usesFill = usesFill(); - boolean ret = shape.contains(x, y, gc, !usesFill); - if (!ret && usesFill && checkOutline(figure)) { - ret = shape.contains(x, y, gc, true); - } - shape.dispose(); - return ret; - } - - protected boolean checkOutline(IFigure figure) { - return true; - } - - protected int getLineWidthForChecking() { - return getLineWidth(); - } - - public Rectangle getPreferredBounds(IFigure figure) { - checkValidation(figure); - Path shape = new Path(Display.getCurrent()); - route(figure, shape); - float[] bounds = new float[4]; - shape.getBounds(bounds); - if (Util.isWindows()) { - float[] autoScaleDown = DPIUtil.autoScaleDown(bounds); - bounds[0] = autoScaleDown[0]; - bounds[1] = autoScaleDown[1]; - bounds[2] = autoScaleDown[2]; - bounds[3] = autoScaleDown[3]; - } - shape.dispose(); - return PrecisionRectangle - .toDraw2DRectangle(bounds[0], bounds[1], bounds[2], bounds[3]) - .expand(getLineWidth(), getLineWidth()); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.internal.DPIUtil; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.Path; + +@SuppressWarnings("restriction") +public abstract class PathConnectionDecoration extends + AbstractConnectionDecoration implements IConnectionDecorationEx { + + protected PathConnectionDecoration() { + } + + protected PathConnectionDecoration(String id) { + super(id); + } + + protected boolean usesFill() { + return false; + } + + protected void drawLine(IFigure figure, Graphics graphics) { + if (usesFill()) { + Color bg = graphics.getBackgroundColor(); + graphics.setBackgroundColor(graphics.getForegroundColor()); + Path shape = new Path(Display.getCurrent()); + route(figure, shape); + paintPath(figure, graphics, shape, true); + shape.dispose(); + graphics.setBackgroundColor(bg); + } else { + Path shape = new Path(Display.getCurrent()); + route(figure, shape); + paintPath(figure, graphics, shape, false); + shape.dispose(); + } + } + + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + if (fill) { + graphics.fillPath(path); + } else { + if (getLineWidth() > 0) + graphics.drawPath(path); + } + } + + protected abstract void route(IFigure figure, Path shape); + + public boolean containsPoint(IFigure figure, int x, int y) { + checkValidation(figure); + GC gc = GraphicsUtils.getAdvanced().getGC(); + gc.setLineWidth(getLineWidthForChecking()); + Path shape = new Path(Display.getCurrent()); + route(figure, shape); + boolean usesFill = usesFill(); + boolean ret = shape.contains(x, y, gc, !usesFill); + if (!ret && usesFill && checkOutline(figure)) { + ret = shape.contains(x, y, gc, true); + } + shape.dispose(); + return ret; + } + + protected boolean checkOutline(IFigure figure) { + return true; + } + + protected int getLineWidthForChecking() { + return getLineWidth(); + } + + public Rectangle getPreferredBounds(IFigure figure) { + checkValidation(figure); + Path shape = new Path(Display.getCurrent()); + route(figure, shape); + float[] bounds = new float[4]; + shape.getBounds(bounds); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(bounds); + bounds[0] = autoScaleDown[0]; + bounds[1] = autoScaleDown[1]; + bounds[2] = autoScaleDown[2]; + bounds[3] = autoScaleDown[3]; + } + shape.dispose(); + return PrecisionRectangle + .toDraw2DRectangle(bounds[0], bounds[1], bounds[2], bounds[3]) + .expand(getLineWidth(), getLineWidth()); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathShapeDecoration.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathShapeDecoration.java index 6959f0a46..db236113c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathShapeDecoration.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/decoration/PathShapeDecoration.java @@ -1,152 +1,152 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.decoration; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.Path; - -public abstract class PathShapeDecoration extends AbstractShapeDecoration - implements IShapeDecorationEx { - - private static final PrecisionPoint REF = new PrecisionPoint(); - - protected static final int FILL = 1; - - protected static final int OUTLINE = 2; - - protected static final int CHECK = 3; - - protected PathShapeDecoration() { - super(); - } - - protected PathShapeDecoration(String id) { - super(id); - } - - protected void paintFill(IFigure figure, Graphics graphics) { - Path shape = new Path(Display.getCurrent()); - sketch(figure, shape, getOutlineBox(figure), FILL); - paintPath(figure, graphics, shape, true); - shape.dispose(); - } - - protected void paintOutline(IFigure figure, Graphics graphics) { - Path shape = new Path(Display.getCurrent()); - sketch(figure, shape, getOutlineBox(figure), OUTLINE); - paintPath(figure, graphics, shape, false); - shape.dispose(); - } - - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - if (fill) { - graphics.fillPath(path); - } else { - if (getLineWidth() > 0) - graphics.drawPath(path); - } - } - - public boolean containsPoint(IFigure figure, int x, int y) { - return containsPoint(figure, x, y, false); - } - - protected boolean containsPoint(IFigure figure, int x, int y, - boolean outline) { - checkValidation(figure); - GC gc = GraphicsUtils.getAdvanced().getGC(); - gc.setLineWidth(getCheckingLineWidth()); - Path shape = new Path(Display.getCurrent()); - sketch(figure, shape, getOutlineBox(figure), CHECK); - boolean ret = shape.contains(x, y, gc, outline); - shape.dispose(); - return ret; - } - - protected int getCheckingLineWidth() { - return getLineWidth(); - } - - /** - * @param figure - * @param shape - * @param box - * @param purpose - * {@link #FILL}, {@link #OUTLINE}, {@link #CHECK} - */ - protected abstract void sketch(IFigure figure, Path shape, Rectangle box, - int purpose); - - public PrecisionPoint getAnchorLocation(IFigure figure, int orientation, - double expansion) { - checkValidation(figure); - switch (orientation) { - case PositionConstants.WEST: - return getWest(figure, expansion); - case PositionConstants.SOUTH: - return getSouth(figure, expansion); - case PositionConstants.NORTH: - return getNorth(figure, expansion); - case PositionConstants.EAST: - return getEast(figure, expansion); - case PositionConstants.CENTER: - return REF.setLocation(figure.getBounds().getCenter()); - } - return null; - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - return Geometry.getChopBoxLocation(refX, refY, getOutlineBox(figure), - expansion); - } - - protected PrecisionPoint getEast(IFigure figure, double expansion) { - PrecisionPoint ref = getReferencePoint(figure, REF); - return getAnchorLocation(figure, ref.x + 100, ref.y, expansion); - } - - protected PrecisionPoint getNorth(IFigure figure, double expansion) { - PrecisionPoint ref = getReferencePoint(figure, REF); - return getAnchorLocation(figure, ref.x, ref.y - 100, expansion); - } - - protected PrecisionPoint getSouth(IFigure figure, double expansion) { - PrecisionPoint ref = getReferencePoint(figure, REF); - return getAnchorLocation(figure, ref.x, ref.y + 100, expansion); - } - - protected PrecisionPoint getWest(IFigure figure, double expansion) { - PrecisionPoint ref = getReferencePoint(figure, REF); - return getAnchorLocation(figure, ref.x - 100, ref.y, expansion); - } - - protected PrecisionPoint getReferencePoint(IFigure figure, - PrecisionPoint result) { - if (figure instanceof IReferencedFigure) - return result.setLocation(((IReferencedFigure) figure) - .getReference()); - return result.setLocation(figure.getBounds().getCenter()); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.decoration; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.Path; + +public abstract class PathShapeDecoration extends AbstractShapeDecoration + implements IShapeDecorationEx { + + private static final PrecisionPoint REF = new PrecisionPoint(); + + protected static final int FILL = 1; + + protected static final int OUTLINE = 2; + + protected static final int CHECK = 3; + + protected PathShapeDecoration() { + super(); + } + + protected PathShapeDecoration(String id) { + super(id); + } + + protected void paintFill(IFigure figure, Graphics graphics) { + Path shape = new Path(Display.getCurrent()); + sketch(figure, shape, getOutlineBox(figure), FILL); + paintPath(figure, graphics, shape, true); + shape.dispose(); + } + + protected void paintOutline(IFigure figure, Graphics graphics) { + Path shape = new Path(Display.getCurrent()); + sketch(figure, shape, getOutlineBox(figure), OUTLINE); + paintPath(figure, graphics, shape, false); + shape.dispose(); + } + + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + if (fill) { + graphics.fillPath(path); + } else { + if (getLineWidth() > 0) + graphics.drawPath(path); + } + } + + public boolean containsPoint(IFigure figure, int x, int y) { + return containsPoint(figure, x, y, false); + } + + protected boolean containsPoint(IFigure figure, int x, int y, + boolean outline) { + checkValidation(figure); + GC gc = GraphicsUtils.getAdvanced().getGC(); + gc.setLineWidth(getCheckingLineWidth()); + Path shape = new Path(Display.getCurrent()); + sketch(figure, shape, getOutlineBox(figure), CHECK); + boolean ret = shape.contains(x, y, gc, outline); + shape.dispose(); + return ret; + } + + protected int getCheckingLineWidth() { + return getLineWidth(); + } + + /** + * @param figure + * @param shape + * @param box + * @param purpose + * {@link #FILL}, {@link #OUTLINE}, {@link #CHECK} + */ + protected abstract void sketch(IFigure figure, Path shape, Rectangle box, + int purpose); + + public PrecisionPoint getAnchorLocation(IFigure figure, int orientation, + double expansion) { + checkValidation(figure); + switch (orientation) { + case PositionConstants.WEST: + return getWest(figure, expansion); + case PositionConstants.SOUTH: + return getSouth(figure, expansion); + case PositionConstants.NORTH: + return getNorth(figure, expansion); + case PositionConstants.EAST: + return getEast(figure, expansion); + case PositionConstants.CENTER: + return REF.setLocation(figure.getBounds().getCenter()); + } + return null; + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + return Geometry.getChopBoxLocation(refX, refY, getOutlineBox(figure), + expansion); + } + + protected PrecisionPoint getEast(IFigure figure, double expansion) { + PrecisionPoint ref = getReferencePoint(figure, REF); + return getAnchorLocation(figure, ref.x + 100, ref.y, expansion); + } + + protected PrecisionPoint getNorth(IFigure figure, double expansion) { + PrecisionPoint ref = getReferencePoint(figure, REF); + return getAnchorLocation(figure, ref.x, ref.y - 100, expansion); + } + + protected PrecisionPoint getSouth(IFigure figure, double expansion) { + PrecisionPoint ref = getReferencePoint(figure, REF); + return getAnchorLocation(figure, ref.x, ref.y + 100, expansion); + } + + protected PrecisionPoint getWest(IFigure figure, double expansion) { + PrecisionPoint ref = getReferencePoint(figure, REF); + return getAnchorLocation(figure, ref.x - 100, ref.y, expansion); + } + + protected PrecisionPoint getReferencePoint(IFigure figure, + PrecisionPoint result) { + if (figure instanceof IReferencedFigure) + return result.setLocation(((IReferencedFigure) figure) + .getReference()); + return result.setLocation(figure.getBounds().getCenter()); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/Geometry.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/Geometry.java index 5472a3568..b0e84797d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/Geometry.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/Geometry.java @@ -1,1119 +1,1119 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.geometry; - -import static java.lang.Math.PI; -import static java.lang.Math.atan; -import static java.lang.Math.cos; -import static java.lang.Math.max; -import static java.lang.Math.sin; -import static java.lang.Math.sqrt; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; - -public class Geometry { - - public static final double MIN_DISTANCE = 0.00000001; - - public static final double TWO_PI = PI * 2; - - public static final double HALF_PI = PI / 2; - - public static final double NEG_HALF_PI = -PI / 2; - - public static final int QUADRANT_ONE = 1; - - public static final int QUADRANT_TWO = 2; - - public static final int QUADRANT_THREE = 3; - - public static final int QUADRANT_FOUR = 4; - - public static final int SIDE_ONE = 1; - - public static final int SIDE_TWO = 2; - - public static final int SIDE_THREE = 3; - - public static final int SIDE_FOUR = 4; - - public static final int SIDE_FIVE = 5; - - public static final int SIDE_SIX = 6; - - public static final int SIDE_SEVEN = 7; - - public static final int SIDE_EIGHT = 8; - - protected Geometry() { - } - - /** - * Calculates the radian angle of the line from (x, y) to (0, 0). - * - * @param x - * The X coordinate - * @param y - * The Y coordinate - * @return The radian angle of the line from (x, y) to (0, 0). Varies from - * -pi(excluded) to pi(included). - * 0 means rightwards; pi/2 means - * downwards; pi means leftwards; -pi/2 - * means upwards. - */ - public static double getAngle(double x, double y) { - if (x == 0) { - if (y > 0) - return HALF_PI; - if (y < 0) - return NEG_HALF_PI; - return 0; - } - double a = atan(y / x); - if (x > 0) - return a; - if (y < 0) - return a - PI; - return a + PI; - } - - public static double getAngle(Dimension d) { - return getAngle(d.width, d.height); - } - - public static double getAngle(PrecisionDimension d) { - return getAngle(d.width, d.height); - } - - public static double getAngle(Point p) { - return getAngle(p.x, p.y); - } - - public static double getAngle(PrecisionPoint p) { - return getAngle(p.x, p.y); - } - - public static double getAngle(Point p, Point origin) { - return getAngle(p.x - origin.x, p.y - origin.y); - } - - public static double getAngle(PrecisionPoint p, PrecisionPoint origin) { - return getAngle(p.x - origin.x, p.y - origin.y); - } - - /** - * - * - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @param deltaAngle - * The angle between the line (x1, y1)-(x, y) and the line (x2, - * y2)-(x1, y1) - * @param amount - * The amount of the ratio of the distance (x1, y1)-(x, y) to the - * distance (x1, y1)-(x2, y2) - * @param minDistance - * The minimum distance from (x1, y1) to (x2, y2) to avoid - * division by zero - * @return An point by the deltaAngle and amount - * from (x1, y1) to (x2, y2). - */ - public static PrecisionPoint getPoint(double x1, double y1, double x2, - double y2, double deltaAngle, double amount, double minDistance, - PrecisionPoint result) { - double dx = x2 - x1; - double dy = y2 - y1; - double d = Math.max(Math.hypot(dx, dy), minDistance); - double angle = getAngle(dx, dy); - return result.setLocation(x1, y1).move(angle + deltaAngle, d * amount); - } - - public static PrecisionPoint getPoint(double x1, double y1, double x2, - double y2, double deltaAngle, double amount, PrecisionPoint result) { - return getPoint(x1, y1, x2, y2, deltaAngle, amount, MIN_DISTANCE, - result); - } - - public static PrecisionPoint getPoint2(double x1, double y1, double x2, - double y2, double deltaAngle, double dist, PrecisionPoint result) { - double dx = x2 - x1; - double dy = y2 - y1; - double angle = getAngle(dx, dy); - return result.setLocation(x1, y1).move(angle + deltaAngle, dist); - } - - /** - * Calculates the amount of the ratio of the distance (x1, y1)-(x, y) to the - * distance (x1, y1)-(x2, y2). - * - * @param x - * @param y - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @param minDistance - * The minimum distance from (x1, y1) to (x2, y2) to avoid - * division by zero - * @return - * @throws IllegalArgumentException - * if minDistance is equal to or less than zero - */ - public static double getAmount(double x, double y, double x1, double y1, - double x2, double y2, double minDistance) { - if (minDistance <= 0) - throw new IllegalArgumentException(); - double d = Math.hypot(x - x1, y - y1); - double d2 = Math.max(Math.hypot(x2 - x1, y2 - y1), minDistance); - return d / d2; - } - - public static double getAmount(double x, double y, double x1, double y1, - double x2, double y2) { - return getAmount(x, y, x1, y1, x2, y2, MIN_DISTANCE); - } - - /** - * Calculates the angle between the line (x1, y1)-(x, y) and the line (x1, - * y1)-(x2, y2). - * - * @param x - * @param y - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @return - */ - public static double getDeltaAngle(double x, double y, double x1, - double y1, double x2, double y2) { - double angle = getAngle(x - x1, y - y1); - double angle2 = getAngle(x2 - x1, y2 - y1); - return constrainAngleRadian(angle - angle2); - } - - /** - * Converts a polar coordinate system to rectangular coordinate system. - * - * @param angle - * The angular coordinate; 0 means rightwards; - * pi/2 means downwards; pi means - * leftwards; -pi/2 means upwards. - * @param distance - * The radial coordinate. - * @return A point representing the given position in rectangular coordinate - * form. - */ - public static Point getPoint(double angle, double distance) { - double x = distance * cos(angle); - double y = distance * sin(angle); - return new Point((int) x, (int) y); - } - - /** - * - * @param angle - * @param distance - * @return - */ - public static Point getPoint(Point p, double angle, double distance) { - return p.getTranslated(getPoint(angle, distance)); - } - - public static boolean isSameAngleDegree(double angle1, double angle2, - double tolerance) { - return Math.abs(constrainAngleDegree(angle1) - - constrainAngleDegree(angle2)) < tolerance; - } - - public static double constrainAngleDegree(double angle) { - angle = angle - ((int) (angle / 360)) * 360; - if (angle < -180) - angle += 360; - else if (angle > 180) - angle -= 360; - return angle; - } - - public static boolean isSameAngleRadian(double angle1, double angle2, - double tolerance) { - return Math.abs(constrainAngleRadian(angle1) - - constrainAngleRadian(angle2)) < tolerance; - } - - public static double constrainAngleRadian(double angle) { - angle = angle - ((int) (angle / TWO_PI)) * TWO_PI; - if (angle < NEG_HALF_PI) - angle += TWO_PI; - else if (angle > PI) - angle -= TWO_PI; - return angle; - } - - public static Insets expand(Insets ins, int exp) { - return ins.add(new Insets(exp, exp, exp, exp)); - } - - public static Insets expand(Insets ins, int width, int height) { - return ins.add(new Insets(height, width, height, width)); - } - - public static Insets getExpanded(Insets ins, int exp) { - return expand(new Insets(ins), exp); - } - - public static Insets getExpanded(Insets ins, int width, int height) { - return expand(new Insets(ins), width, height); - } - - public static Insets union(Insets ins, Insets other) { - if (other == null) - return ins; - return union(ins, other.top, other.left, other.bottom, other.right); - } - - public static Insets union(Insets ins, int top, int left, int bottom, - int right) { - if (ins == null) - return new Insets(top, left, bottom, right); - ins.top = Math.max(ins.top, top); - ins.left = Math.max(ins.left, left); - ins.bottom = Math.max(ins.bottom, bottom); - ins.right = Math.max(ins.right, right); - return ins; - } - - public static Insets add(Insets ins, Insets other) { - if (other == null) - return ins; - if (ins == null) - return new Insets(other); - return ins.add(other); - } - - public static Insets add(Insets ins, int margin) { - return add(ins, margin, margin, margin, margin); - } - - public static Insets add(Insets ins, int top, int left, int bottom, - int right) { - if (ins == null) - return new Insets(top, left, bottom, right); - ins.top += top; - ins.left += left; - ins.bottom += bottom; - ins.right += right; - return ins; - } - - public static Insets getUnioned(Insets ins, Insets other) { - if (other == null) - return ins == null ? null : new Insets(ins); - if (ins == null) - return new Insets(other); - return union(new Insets(ins), other); - } - - public static Insets remove(Insets from, Insets toRemove) { - from.top = max(0, from.top - toRemove.top); - from.bottom = max(0, from.bottom - toRemove.bottom); - from.left = max(0, from.left - toRemove.left); - from.right = max(0, from.right - toRemove.right); - return from; - } - - public static Insets getRemoved(Insets from, Insets toRemove) { - return remove(new Insets(from), toRemove); - } - - public static Insets scale(Insets ins, double scale) { - ins.top = (int) (Math.floor(ins.top * scale)); - ins.left = (int) (Math.floor(ins.left * scale)); - ins.bottom = (int) (Math.floor(ins.bottom * scale)); - ins.right = (int) (Math.floor(ins.right * scale)); - return ins; - } - - public static Insets getScaled(Insets ins, double scale) { - return scale(new Insets(ins), scale); - } - - public static Rectangle shrink(Rectangle r, Insets i) { - r.x += i.left; - r.y += i.top; - r.width -= i.getWidth(); - r.height -= i.getHeight(); - return r; - } - - public static Rectangle getShrinked(Rectangle r, Insets i) { - return shrink(r.getCopy(), i); - } - - public static Insets getCropped(Rectangle box, Rectangle clip) { - Insets ins = new Insets(); - ins.top = clip.y - box.y; - ins.left = clip.x - box.x; - ins.bottom = box.bottom() - clip.bottom(); - ins.right = box.right() - clip.right(); - return ins; - } - - /** - * Calculates distances from a point to the four sides of a rectangle. - * - * @param p - * the point - * @param box - * the rectangle - * @return the distances from the point to the four sides of the rectangle - */ - public static Insets getInsets(Point p, Rectangle box) { - return new Insets(p.y - box.y, p.x - box.x, box.bottom() - p.y, - box.right() - p.x); - } - - public static Rectangle getExpanded(Point p, Insets ins) { - return getExpanded(p.x, p.y, ins); - } - - public static Rectangle getExpanded(int x, int y, Insets ins) { - return new Rectangle(x - ins.left, y - ins.top, ins.getWidth(), - ins.getHeight()); - } - - public static Rectangle getBounds(Rectangle box, boolean outline, - int lineWidth, int expansion) { - if (outline) - box = box.getResized(-lineWidth, -lineWidth); - if (expansion != 0) - box = box.getExpanded(expansion, expansion); - return box; - } - - public static Point getLocation(int orientation, Rectangle box, - boolean outline, int lineWidth, int expansion) { - box = getBounds(box, outline, lineWidth, expansion); - switch (orientation) { - case PositionConstants.EAST: - return box.getRight(); - case PositionConstants.WEST: - return box.getLeft(); - case PositionConstants.SOUTH: - return box.getBottom(); - case PositionConstants.NORTH: - return box.getTop(); - case PositionConstants.NORTH_EAST: - return box.getTopRight(); - case PositionConstants.NORTH_WEST: - return box.getTopLeft(); - case PositionConstants.SOUTH_EAST: - return box.getBottomRight(); - case PositionConstants.SOUTH_WEST: - return box.getBottomLeft(); - } - return box.getCenter(); - } - - /** - * @param originSize - * @param constrainedSize - * @return - */ - public static Dimension getScaledConstrainedSize(Dimension originSize, - Dimension constrainedSize) { - return getScaledConstrainedSize(originSize.width, originSize.height, - constrainedSize.width, constrainedSize.height); - } - - public static Dimension getScaledConstrainedSize(int w, int h, - int maxWidth, int maxHeight) { - if (w == 0 || h == 0) - return new Dimension(); - if (maxWidth < 0 && maxHeight < 0) - return new Dimension(w, h); - if (w <= maxWidth && h <= maxHeight) - return new Dimension(w, h); - int nw = w * maxHeight / h; - int nh = h * maxWidth / w; - if (maxWidth < 0) - return new Dimension(nw, maxHeight); - if (maxHeight < 0) - return new Dimension(maxWidth, nh); - if (nw < maxWidth) - maxWidth = nw; - if (nh < maxHeight) - maxHeight = nh; - return new Dimension(Math.max(1, maxWidth), Math.max(1, maxHeight)); - } - - public static Point getPopupLocation(Dimension size, Rectangle host, - Rectangle display) { - Point p = host.getBottomLeft(); - if (p.y + size.height > display.bottom()) { - p.y = host.y - size.height; - if (p.y < 0) { - p.y = display.y - size.height; - } - } - if (p.y < display.y) { - p.y = display.y; - } - if (p.x + size.width > display.right()) { - p.x = display.right() - size.width; - } - if (p.x < display.x) { - p.x = display.x; - } - return p; - } - - public static int getOrientation(Point p) { - return getOrientation(p.x, p.y, 0, 0); - } - - public static int getOrientation(Point p, Point origin) { - if (p == null) - return PositionConstants.NONE; - return getOrientation(p.x, p.y, origin.x, origin.y); - } - - public static int getOrientation(int x1, int y1, int x2, int y2) { - if (x1 == x2 && y1 < y2) - return PositionConstants.NORTH; - if (x1 > x2 && y1 < y2) - return PositionConstants.NORTH_EAST; - if (x1 > x2 && y1 == y2) - return PositionConstants.EAST; - if (x1 > x2 && y1 > y2) - return PositionConstants.SOUTH_EAST; - if (x1 == x2 && y1 > y2) - return PositionConstants.SOUTH; - if (x1 < x2 && y1 > y2) - return PositionConstants.SOUTH_WEST; - if (x1 < x2 && y1 == y2) - return PositionConstants.WEST; - if (x1 < x2 && y1 < y2) - return PositionConstants.NORTH_WEST; - return PositionConstants.NONE; - } - - public static int getOppositePosition(int position) { - if (position == PositionConstants.EAST) - return PositionConstants.WEST; - if (position == PositionConstants.WEST) - return PositionConstants.EAST; - if (position == PositionConstants.SOUTH) - return PositionConstants.NORTH; - if (position == PositionConstants.NORTH) - return PositionConstants.SOUTH; - if (position == PositionConstants.NORTH_EAST) - return PositionConstants.SOUTH_WEST; - if (position == PositionConstants.NORTH_WEST) - return PositionConstants.SOUTH_EAST; - if (position == PositionConstants.SOUTH_EAST) - return PositionConstants.NORTH_WEST; - if (position == PositionConstants.SOUTH_WEST) - return PositionConstants.NORTH_EAST; - if (position == PositionConstants.NORTH_SOUTH) - return PositionConstants.EAST_WEST; - if (position == PositionConstants.EAST_WEST) - return PositionConstants.NORTH_SOUTH; - return position; - } - - public static Point getPositionWithin(int alignment, Rectangle boundingBox, - Dimension toPlace) { - int x; - if ((alignment & PositionConstants.LEFT) != 0) { - x = boundingBox.x; - } else if ((alignment & PositionConstants.RIGHT) != 0) { - x = boundingBox.right() - toPlace.width; - } else { - x = boundingBox.x + (boundingBox.width - toPlace.width) / 2; - } - int y; - if ((alignment & PositionConstants.TOP) != 0) { - y = boundingBox.y; - } else if ((alignment & PositionConstants.BOTTOM) != 0) { - y = boundingBox.bottom() - toPlace.height; - } else { - y = boundingBox.y + (boundingBox.height - toPlace.height) / 2; - } - return new Point(x, y); - } - - public static Point getRotatedPoint(Point p, double angle) { - angle += getAngle(p); - double distance = p.getDistance(new Point()); - return getPoint(angle, distance); - } - - public static PointList getRotatedRectangle(Rectangle r, double theta) { - PointList pl = new PointList(4); - pl.addPoint(getRotatedPoint(r.getTopLeft(), theta)); - pl.addPoint(getRotatedPoint(r.getTopRight(), theta)); - pl.addPoint(getRotatedPoint(r.getBottomLeft(), theta)); - pl.addPoint(getRotatedPoint(r.getBottomRight(), theta)); - return pl; - } - - public static Dimension getConstrainedSize(Dimension size, - Dimension minSize, Dimension maxSize) { - return new Dimension( - constrain(size.width, minSize.width, maxSize.width), constrain( - size.height, minSize.height, maxSize.height)); - } - - public static int constrain(int i, int min, int max) { - return Math.max(Math.min(i, max), min); - } - - public static double constrain(double d, double min, double max) { - return Math.max(Math.min(d, max), min); - } - - public static Dimension getScaledConstrainedSize2(Dimension size, - Dimension origin, Dimension minSize, Dimension maxSize) { - return getScaledConstrainedSize2(size.width, size.height, - slope(origin), minSize.width, minSize.height, maxSize.width, - maxSize.height); - } - - public static Dimension getScaledConstrainedSize2(double width, - double height, Dimension origin, Dimension minSize, - Dimension maxSize) { - return getScaledConstrainedSize2(width, height, slope(origin), - minSize.width, minSize.height, maxSize.width, maxSize.height); - } - - public static Dimension getScaledConstrainedSize2(double width, - double height, double originWidth, double originHeight, - double minWidth, double minHeight, double maxWidth, double maxHeight) { - return getScaledConstrainedSize2(width, height, - slope(originWidth, originHeight), minWidth, minHeight, - maxWidth, maxHeight); - } - - public static Dimension getScaledConstrainedSize2(double width, - double height, double slope, double minWidth, double minHeight, - double maxWidth, double maxHeight) { - double prefH = constrain(width * slope, minHeight, maxHeight); - if (height < prefH) { - if (height >= 0) - height = prefH; - else - width = constrain(width, minWidth, maxWidth); - } else { - if (height >= 0) - width = constrain(height / slope, minWidth, maxWidth); - } - height = constrain(width * slope, minHeight, maxHeight); - width = constrain(height / slope, minWidth, maxWidth); - return new Dimension((int) (Math.floor(width)), - (int) (Math.floor(height))); - } - - public static double slope(Dimension size) { - return slope(size.width, size.height); - } - - public static double slope(double width, double height) { - return height / width; - } - - /** - * Method getLineSegments. Converts the points of this polyline into a list - * of PrecisionLine objects - * - * @param points - * PointList to get PrecisionLine equivalents of. - * @return List of PrecisionLine objects. - */ - public static List getLineSegments( - List points) { - if (points.size() <= 1) - return new ArrayList(0); - ArrayList lines = new ArrayList( - points.size() - 1); - for (int i = 0; i < points.size() - 1; i++) { - lines.add(new PrecisionLine(points.get(i), points.get(i + 1), - LineType.LineSegment)); - } - return lines; - } - - public static List getLineSegments(PrecisionPoint... points) { - return getLineSegments(Arrays.asList(points)); - } - - /** - * Method getLineSegments. Converts the points of this polyline into a list - * of PrecisionLine objects - * - * @param points - * PointList to get PrecisionLine equivalents of. - * @return List of PrecisionLine objects. - */ - public static List getLineSegments(PrecisionPoint origin, - List points) { - if (points.size() <= 1) - return new ArrayList(0); - - ArrayList lines = new ArrayList( - points.size() - 1); - - for (int i = 0; i < points.size() - 1; i++) { - lines.add(new PrecisionLine(new PrecisionPoint(origin) - .translate(points.get(i)), new PrecisionPoint(origin) - .translate(points.get(i + 1)), LineType.LineSegment)); - } - return lines; - } - - public static PrecisionPoint getRayXLine(PrecisionLine ray, - PrecisionLine line, int tolerance) { - List intersections = ray.getLinesIntersections(line); - for (int i = 0; i < intersections.size(); i++) { - PrecisionPoint p = intersections.get(i); - if (rayContainsPoint(ray, p, tolerance)) - return p; - } - return null; - } - - public static PrecisionPoint getRayXLineSeg(PrecisionLine ray, - PrecisionLine lineSeg, int tolerance) { - List intersections = ray.getLinesIntersections(lineSeg); - for (int i = 0; i < intersections.size(); i++) { - PrecisionPoint p = intersections.get(i); - if (lineSeg.contains(p, tolerance) - && rayContainsPoint(ray, p, tolerance)) - return p; - } - return null; - } - - public static PrecisionPoint getRayXRect(PrecisionLine ray, - PrecisionRectangle r, int tolerance) { - List lines = getLineSegments(r.getTopLeft(), - r.getTopRight(), r.getBottomRight(), r.getBottomLeft(), - r.getTopLeft()); - for (PrecisionLine line : lines) { - PrecisionPoint p = getRayXLineSeg(ray, line, tolerance); - if (p != null) - return p; - } - return null; - } - - public static PrecisionPoint getRayXRectFarther(PrecisionLine ray, - PrecisionRectangle r, int tolerance) { - PrecisionPoint ret = null; - double dist = -1; - List lines = getLineSegments(r.getTopLeft(), - r.getTopRight(), r.getBottomRight(), r.getBottomLeft(), - r.getTopLeft()); - for (PrecisionLine line : lines) { - PrecisionPoint p = getRayXLineSeg(ray, line, tolerance); - if (p != null) { - if (ret == null) { - ret = p; - dist = ret.getDistance(ray.getOrigin()); - } else { - double d = p.getDistance(ray.getOrigin()); - if (d > dist) { - ret = p; - dist = d; - } - } - } - } - return ret; - } - - public static boolean rayContainsPoint(PrecisionLine ray, PrecisionPoint p, - int tolerance) { - return ray.contains(p, tolerance) - || new PrecisionLine(ray.getOrigin(), p).contains( - ray.getTerminus(), tolerance); - } - -// public static PrecisionPoint getCenter( PrecisionPoint p1, PrecisionPoint p2 ) { -// return new PrecisionPoint( ( p1.x + p2.x ) / 2, ( p1.y + p2.y) / 2 ); -// } - - public static Rectangle union(Rectangle r1, Rectangle r2) { - if (r2 == null) - return r1; - if (r1 == null) - return r2.getCopy(); - return r1.union(r2); - } - - public static PrecisionRectangle union(PrecisionRectangle r1, - PrecisionRectangle r2) { - if (r2 == null) - return r1; - if (r1 == null) - return r2.getCopy(); - return r1.union(r2); - } - - public static Rectangle intersect(Rectangle r1, Rectangle r2) { - if (r2 == null) - return r1; - if (r1 == null) - return r2.getCopy(); - return r1.intersect(r2); - } - - public static PrecisionRectangle intersect(PrecisionRectangle r1, - PrecisionRectangle r2) { - if (r2 == null) - return r1; - if (r1 == null) - return r2.getCopy(); - return r1.intersect(r2); - } - - public static PrecisionPoint[] intersectQuadBezier(PrecisionLine line, - double x1, double y1, double x2, double y2, double x3, double y3) { - double u1 = x1 - 2 * x2 + x3; - double v1 = y1 - 2 * y2 + y3; - double u2 = 2 * x2 - 2 * x3; - double v2 = 2 * y2 - 2 * y3; - double u3 = x3; - double v3 = y3; - double[] eq = line.getEquation(); - double a = eq[0] * u1 + eq[1] * v1; - double b = eq[0] * u2 + eq[1] * v2; - double c = eq[0] * u3 + eq[1] * v3 - eq[2]; - double delta = b * b - 4 * a * c; - if (Math.abs(delta) < 0.000000001) { - double t = -b / (2 * a); - if (t >= 0 && t <= 1) { - double x = u1 * t * t + u2 * t + u3; - double y = v1 * t * t + v2 * t + v3; - PrecisionPoint p = new PrecisionPoint(x, y); - if (line.contains(p)) - return new PrecisionPoint[] { p }; - } - } else if (delta > 0) { - double d = Math.sqrt(delta); - List list = new ArrayList(); - double t1 = (-b + d) / (2 * a); - if (t1 >= 0 && t1 <= 1) { - double x = u1 * t1 * t1 + u2 * t1 + u3; - double y = v1 * t1 * t1 + v2 * t1 + v3; - PrecisionPoint p = new PrecisionPoint(x, y); - if (line.contains(p)) { - list.add(p); - } - } - double t2 = (-b - d) / (2 * a); - if (t2 >= 0 && t2 <= 1) { - double x = u1 * t2 * t2 + u2 * t2 + u3; - double y = v1 * t2 * t2 + v2 * t2 + v3; - PrecisionPoint p = new PrecisionPoint(x, y); - if (line.contains(p)) { - list.add(p); - } - } - return list.toArray(new PrecisionPoint[0]); - } - return new PrecisionPoint[0]; - } - - public static PrecisionPoint getChopBoxLocation(double refX, double refY, - Rectangle r, double expansion) { - double centerX = r.x + 0.5 * r.width; - double centerY = r.y + 0.5 * r.height; - double dx = refX - centerX; - double dy = refY - centerY; - if (dx == 0) - return new PrecisionPoint(refX, (dy > 0) ? r.bottom() + expansion - : r.y - expansion); - if (dy == 0) - return new PrecisionPoint((dx > 0) ? r.right() + expansion : r.x - - expansion, refY); - double scale = 0.5 / Math.max(Math.abs(dx) / r.width, Math.abs(dy) - / r.height); - dx *= scale; - dy *= scale; - double d = Math.hypot(dx, dy); - if (d != 0) { - double s = expansion / d; - dx += dx * s; - dy += dy * s; - } - centerX += dx; - centerY += dy; - return new PrecisionPoint(centerX, centerY); - } - - public static Point getChopBoxLocation(int x, int y, Rectangle box) { - float centerX = box.x + 0.5f * box.width; - float centerY = box.y + 0.5f * box.height; - - float dx = x - centerX; - float dy = y - centerY; - -// when preference in the center - if (dx == 0) - return new Point(x, (dy > 0) ? box.bottom() : box.y); - if (dy == 0) - return new Point((dx > 0) ? box.right() : box.x, y); - - // r.width, r.height, dx, and dy are guaranteed to be non-zero. - float scale = 0.5f / Math.max(Math.abs(dx) / box.width, Math.abs(dy) - / box.height); - - dx *= scale; - dy *= scale; - centerX += dx; - centerY += dy; - - return new Point(Math.round(centerX), Math.round(centerY)); - } - - public static Point getChopBoxLocation(Point reference, Rectangle box) { - return getChopBoxLocation(reference.x, reference.y, box); - } - - public static PrecisionPoint getChopOvalLocation(double refX, double refY, - Rectangle r, double expansion) { - double cx = r.x + r.width * 0.5d; - double cy = r.y + r.height * 0.5d; - double rx = refX - cx; - double ry = refY - cy; - if (rx == 0) - return new PrecisionPoint(refX, (ry > 0) ? r.bottom() + expansion - : r.y - expansion); - if (ry == 0) - return new PrecisionPoint((rx > 0) ? r.right() + expansion : r.x - - expansion, refY); - - double scaleX = (rx > 0) ? 0.5d : -0.5d; - double scaleY = (ry > 0) ? 0.5d : -0.5d; - - // ref.x, ref.y, r.width, r.height != 0 => safe to proceed - - double k = (ry * r.width) / (rx * r.height); - k = k * k; - - double dx = r.width * scaleX / sqrt(1 + k); - double dy = r.height * scaleY / sqrt(1 + 1 / k); - double d = Math.hypot(dx, dy); - if (d != 0) { - double s = expansion / d; - dx += dx * s; - dy += dy * s; - } - return new PrecisionPoint(cx + dx, cy + dy); - } - - public static Point getChopOvalLocation(int x, int y, Rectangle r) { - Point ref = r.getCenter().negate().translate(x, y); - - if (ref.x == 0) - return new Point(x, (ref.y > 0) ? r.bottom() : r.y); - if (ref.y == 0) - return new Point((ref.x > 0) ? r.right() : r.x, y); - - float dx = (ref.x > 0) ? 0.5f : -0.5f; - float dy = (ref.y > 0) ? 0.5f : -0.5f; - - // ref.x, ref.y, r.width, r.height != 0 => safe to proceed - - float k = (float) (ref.y * r.width) / (ref.x * r.height); - k = k * k; - - return r.getCenter().translate((int) (r.width * dx / sqrt(1 + k)), - (int) (r.height * dy / sqrt(1 + 1 / k))); - } - - public static Point getChopOvalLocation(Point reference, Rectangle r) { - return getChopOvalLocation(reference.x, reference.y, r); - } - - public static PrecisionPointPair calculatePositionPair(PrecisionPoint from, - PrecisionPoint to, double w) { - PrecisionPointPair result = new PrecisionPointPair(from.getCopy(), - from.getCopy()); - if (from.equals(to)) - return result; - - PrecisionDimension d = from.getDifference(to); - double wScale = d.width == 0 ? 1 : Math.abs(w / d.width); - double hScale = d.height == 0 ? 1 : Math.abs(w / d.height); - d.scale(wScale, hScale); - result.translate(d); - d.width = -d.width; - result.translateFirstPoint(d.transpose()); - result.translateSecondPoint(d.negate()); - - return result; - } - - public static double getDistance(PrecisionPoint p, PrecisionLine line) { - PrecisionPoint p1 = line.getOrigin(); - PrecisionPoint p2 = line.getTerminus(); - double dx = p2.x - p1.x; - double dy = p2.y - p1.y; - if (dx == 0 && dy == 0) - return 0; - if (dy == 0) - return Math.abs(p.y - p1.y); - if (dx == 0) - return Math.abs(p.x - p1.x); - double k = dx / dy; - double m = dy / dx; - double y = (p1.y * k - p1.x + p.y * m + p.x) / (k + m); - double x = (y - p1.y) * k + p1.x; - return Math.hypot(p.x - x, p.y - y); - } - -// * -------------------------- -// * | | | -// * | 3 | 4 | -// * ------------------------------> -// * | | | -// * | 2 | 1 | -// * -------------------------- -// * \/ - public static int getQuadrant(double x, double y, Point center) { - if (x <= center.x && y <= center.y) { - return QUADRANT_THREE; - } else if (x <= center.x && y >= center.y) { - return QUADRANT_TWO; - } else if (x >= center.x && y <= center.y) { - return QUADRANT_FOUR; - } else { - return QUADRANT_ONE; - } - } - - /** - * Calculate angle of point(x,y)->rectangle center; Angles are interpreted - * such that 0 degrees is at the 3 o'clock position. A positive value - * indicates a counter-clockwise rotation while a negative value indicates a - * clockwise rotation. the returned angle is in the range -pi through - * pi. - */ - public static double getAngle(double x, double y, Rectangle r) { - double cx = r.x + r.width * 0.5d; - double cy = r.y + r.height * 0.5d; - - if (x == cx && y >= cy) - return HALF_PI; - if (x == cx && y <= cy) - return NEG_HALF_PI; - - double angrad = Math.atan((y - cy) / (x - cx)); - int quadrant = getQuadrant(x, y, r.getCenter()); - - if (quadrant == QUADRANT_ONE) { - angrad = -angrad; - } else if (quadrant == QUADRANT_TWO) { - angrad = -PI - angrad; - } else if (quadrant == QUADRANT_THREE) { - angrad = PI - angrad; - } else if (quadrant == QUADRANT_FOUR) { - angrad = -angrad; - } - - return angrad; - } - - /** - * Calculate oval angle of point correspondence;Angles are interpreted such - * that 0 degrees is at the 3 o'clock position;the returned angle is in the - * range -pi through pi. - * - * @param x - * x-coordinate of the point on the ellipse - * @param y - * y-coordinate of the point on the ellipse - * @param r - * oval external rectangle - * @return - */ - public static double getOvalAngle(double x, double y, Rectangle r) { - double cx = r.x + r.width * 0.5d; - - double k = 2 * (x - cx) / r.width; - if (k > 1) - k = 1; - if (k < -1) - k = -1; - - double angrad = Math.acos(k); - int quadrant = getQuadrant(x, y, r.getCenter()); - - if (quadrant == QUADRANT_ONE || quadrant == QUADRANT_TWO) { - angrad = -angrad; - } - return angrad; - } - - /** - * Calculate point(x,y) which edge contains. - * - * @param x - * @param y - * @param r - * @return - */ - public static int getSide(double x, double y, Rectangle r) { - double cx = r.x + r.width * 0.5d; - double cy = r.y + r.height * 0.5d; - - if ((x >= r.x && x <= cx) && Math.abs(y - r.y) <= MIN_DISTANCE) { - return SIDE_ONE; - } else if ((x >= cx && x <= r.x + r.width * 1d) - && Math.abs(y - r.y) <= MIN_DISTANCE) { - return SIDE_TWO; - } else if ((y >= r.y && y <= cy) - && Math.abs((x - (r.x + r.width * 1.0d))) <= MIN_DISTANCE) { - return SIDE_THREE; - } else if ((y >= cy && y <= r.y + r.height * 1d) - && Math.abs((x - (r.x + r.width * 1.0d))) <= MIN_DISTANCE) { - return SIDE_FOUR; - } else if ((x >= cx && x <= r.x + r.width * 1d) - && Math.abs((y - (r.y + r.height * 1.0d))) <= MIN_DISTANCE) { - return SIDE_FIVE; - } else if ((x >= r.x && x <= cx) - && Math.abs((y - (r.y + r.height * 1.0d))) <= MIN_DISTANCE) { - return SIDE_SIX; - } else if ((y >= cy && y <= r.y + r.height * 1.0d) - && (Math.abs(x - r.x) <= MIN_DISTANCE)) { - return SIDE_SEVEN; - } else { - return SIDE_EIGHT; - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.geometry; + +import static java.lang.Math.PI; +import static java.lang.Math.atan; +import static java.lang.Math.cos; +import static java.lang.Math.max; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; + +public class Geometry { + + public static final double MIN_DISTANCE = 0.00000001; + + public static final double TWO_PI = PI * 2; + + public static final double HALF_PI = PI / 2; + + public static final double NEG_HALF_PI = -PI / 2; + + public static final int QUADRANT_ONE = 1; + + public static final int QUADRANT_TWO = 2; + + public static final int QUADRANT_THREE = 3; + + public static final int QUADRANT_FOUR = 4; + + public static final int SIDE_ONE = 1; + + public static final int SIDE_TWO = 2; + + public static final int SIDE_THREE = 3; + + public static final int SIDE_FOUR = 4; + + public static final int SIDE_FIVE = 5; + + public static final int SIDE_SIX = 6; + + public static final int SIDE_SEVEN = 7; + + public static final int SIDE_EIGHT = 8; + + protected Geometry() { + } + + /** + * Calculates the radian angle of the line from (x, y) to (0, 0). + * + * @param x + * The X coordinate + * @param y + * The Y coordinate + * @return The radian angle of the line from (x, y) to (0, 0). Varies from + * -pi(excluded) to pi(included). + * 0 means rightwards; pi/2 means + * downwards; pi means leftwards; -pi/2 + * means upwards. + */ + public static double getAngle(double x, double y) { + if (x == 0) { + if (y > 0) + return HALF_PI; + if (y < 0) + return NEG_HALF_PI; + return 0; + } + double a = atan(y / x); + if (x > 0) + return a; + if (y < 0) + return a - PI; + return a + PI; + } + + public static double getAngle(Dimension d) { + return getAngle(d.width, d.height); + } + + public static double getAngle(PrecisionDimension d) { + return getAngle(d.width, d.height); + } + + public static double getAngle(Point p) { + return getAngle(p.x, p.y); + } + + public static double getAngle(PrecisionPoint p) { + return getAngle(p.x, p.y); + } + + public static double getAngle(Point p, Point origin) { + return getAngle(p.x - origin.x, p.y - origin.y); + } + + public static double getAngle(PrecisionPoint p, PrecisionPoint origin) { + return getAngle(p.x - origin.x, p.y - origin.y); + } + + /** + * + * + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @param deltaAngle + * The angle between the line (x1, y1)-(x, y) and the line (x2, + * y2)-(x1, y1) + * @param amount + * The amount of the ratio of the distance (x1, y1)-(x, y) to the + * distance (x1, y1)-(x2, y2) + * @param minDistance + * The minimum distance from (x1, y1) to (x2, y2) to avoid + * division by zero + * @return An point by the deltaAngle and amount + * from (x1, y1) to (x2, y2). + */ + public static PrecisionPoint getPoint(double x1, double y1, double x2, + double y2, double deltaAngle, double amount, double minDistance, + PrecisionPoint result) { + double dx = x2 - x1; + double dy = y2 - y1; + double d = Math.max(Math.hypot(dx, dy), minDistance); + double angle = getAngle(dx, dy); + return result.setLocation(x1, y1).move(angle + deltaAngle, d * amount); + } + + public static PrecisionPoint getPoint(double x1, double y1, double x2, + double y2, double deltaAngle, double amount, PrecisionPoint result) { + return getPoint(x1, y1, x2, y2, deltaAngle, amount, MIN_DISTANCE, + result); + } + + public static PrecisionPoint getPoint2(double x1, double y1, double x2, + double y2, double deltaAngle, double dist, PrecisionPoint result) { + double dx = x2 - x1; + double dy = y2 - y1; + double angle = getAngle(dx, dy); + return result.setLocation(x1, y1).move(angle + deltaAngle, dist); + } + + /** + * Calculates the amount of the ratio of the distance (x1, y1)-(x, y) to the + * distance (x1, y1)-(x2, y2). + * + * @param x + * @param y + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @param minDistance + * The minimum distance from (x1, y1) to (x2, y2) to avoid + * division by zero + * @return + * @throws IllegalArgumentException + * if minDistance is equal to or less than zero + */ + public static double getAmount(double x, double y, double x1, double y1, + double x2, double y2, double minDistance) { + if (minDistance <= 0) + throw new IllegalArgumentException(); + double d = Math.hypot(x - x1, y - y1); + double d2 = Math.max(Math.hypot(x2 - x1, y2 - y1), minDistance); + return d / d2; + } + + public static double getAmount(double x, double y, double x1, double y1, + double x2, double y2) { + return getAmount(x, y, x1, y1, x2, y2, MIN_DISTANCE); + } + + /** + * Calculates the angle between the line (x1, y1)-(x, y) and the line (x1, + * y1)-(x2, y2). + * + * @param x + * @param y + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @return + */ + public static double getDeltaAngle(double x, double y, double x1, + double y1, double x2, double y2) { + double angle = getAngle(x - x1, y - y1); + double angle2 = getAngle(x2 - x1, y2 - y1); + return constrainAngleRadian(angle - angle2); + } + + /** + * Converts a polar coordinate system to rectangular coordinate system. + * + * @param angle + * The angular coordinate; 0 means rightwards; + * pi/2 means downwards; pi means + * leftwards; -pi/2 means upwards. + * @param distance + * The radial coordinate. + * @return A point representing the given position in rectangular coordinate + * form. + */ + public static Point getPoint(double angle, double distance) { + double x = distance * cos(angle); + double y = distance * sin(angle); + return new Point((int) x, (int) y); + } + + /** + * + * @param angle + * @param distance + * @return + */ + public static Point getPoint(Point p, double angle, double distance) { + return p.getTranslated(getPoint(angle, distance)); + } + + public static boolean isSameAngleDegree(double angle1, double angle2, + double tolerance) { + return Math.abs(constrainAngleDegree(angle1) + - constrainAngleDegree(angle2)) < tolerance; + } + + public static double constrainAngleDegree(double angle) { + angle = angle - ((int) (angle / 360)) * 360; + if (angle < -180) + angle += 360; + else if (angle > 180) + angle -= 360; + return angle; + } + + public static boolean isSameAngleRadian(double angle1, double angle2, + double tolerance) { + return Math.abs(constrainAngleRadian(angle1) + - constrainAngleRadian(angle2)) < tolerance; + } + + public static double constrainAngleRadian(double angle) { + angle = angle - ((int) (angle / TWO_PI)) * TWO_PI; + if (angle < NEG_HALF_PI) + angle += TWO_PI; + else if (angle > PI) + angle -= TWO_PI; + return angle; + } + + public static Insets expand(Insets ins, int exp) { + return ins.add(new Insets(exp, exp, exp, exp)); + } + + public static Insets expand(Insets ins, int width, int height) { + return ins.add(new Insets(height, width, height, width)); + } + + public static Insets getExpanded(Insets ins, int exp) { + return expand(new Insets(ins), exp); + } + + public static Insets getExpanded(Insets ins, int width, int height) { + return expand(new Insets(ins), width, height); + } + + public static Insets union(Insets ins, Insets other) { + if (other == null) + return ins; + return union(ins, other.top, other.left, other.bottom, other.right); + } + + public static Insets union(Insets ins, int top, int left, int bottom, + int right) { + if (ins == null) + return new Insets(top, left, bottom, right); + ins.top = Math.max(ins.top, top); + ins.left = Math.max(ins.left, left); + ins.bottom = Math.max(ins.bottom, bottom); + ins.right = Math.max(ins.right, right); + return ins; + } + + public static Insets add(Insets ins, Insets other) { + if (other == null) + return ins; + if (ins == null) + return new Insets(other); + return ins.add(other); + } + + public static Insets add(Insets ins, int margin) { + return add(ins, margin, margin, margin, margin); + } + + public static Insets add(Insets ins, int top, int left, int bottom, + int right) { + if (ins == null) + return new Insets(top, left, bottom, right); + ins.top += top; + ins.left += left; + ins.bottom += bottom; + ins.right += right; + return ins; + } + + public static Insets getUnioned(Insets ins, Insets other) { + if (other == null) + return ins == null ? null : new Insets(ins); + if (ins == null) + return new Insets(other); + return union(new Insets(ins), other); + } + + public static Insets remove(Insets from, Insets toRemove) { + from.top = max(0, from.top - toRemove.top); + from.bottom = max(0, from.bottom - toRemove.bottom); + from.left = max(0, from.left - toRemove.left); + from.right = max(0, from.right - toRemove.right); + return from; + } + + public static Insets getRemoved(Insets from, Insets toRemove) { + return remove(new Insets(from), toRemove); + } + + public static Insets scale(Insets ins, double scale) { + ins.top = (int) (Math.floor(ins.top * scale)); + ins.left = (int) (Math.floor(ins.left * scale)); + ins.bottom = (int) (Math.floor(ins.bottom * scale)); + ins.right = (int) (Math.floor(ins.right * scale)); + return ins; + } + + public static Insets getScaled(Insets ins, double scale) { + return scale(new Insets(ins), scale); + } + + public static Rectangle shrink(Rectangle r, Insets i) { + r.x += i.left; + r.y += i.top; + r.width -= i.getWidth(); + r.height -= i.getHeight(); + return r; + } + + public static Rectangle getShrinked(Rectangle r, Insets i) { + return shrink(r.getCopy(), i); + } + + public static Insets getCropped(Rectangle box, Rectangle clip) { + Insets ins = new Insets(); + ins.top = clip.y - box.y; + ins.left = clip.x - box.x; + ins.bottom = box.bottom() - clip.bottom(); + ins.right = box.right() - clip.right(); + return ins; + } + + /** + * Calculates distances from a point to the four sides of a rectangle. + * + * @param p + * the point + * @param box + * the rectangle + * @return the distances from the point to the four sides of the rectangle + */ + public static Insets getInsets(Point p, Rectangle box) { + return new Insets(p.y - box.y, p.x - box.x, box.bottom() - p.y, + box.right() - p.x); + } + + public static Rectangle getExpanded(Point p, Insets ins) { + return getExpanded(p.x, p.y, ins); + } + + public static Rectangle getExpanded(int x, int y, Insets ins) { + return new Rectangle(x - ins.left, y - ins.top, ins.getWidth(), + ins.getHeight()); + } + + public static Rectangle getBounds(Rectangle box, boolean outline, + int lineWidth, int expansion) { + if (outline) + box = box.getResized(-lineWidth, -lineWidth); + if (expansion != 0) + box = box.getExpanded(expansion, expansion); + return box; + } + + public static Point getLocation(int orientation, Rectangle box, + boolean outline, int lineWidth, int expansion) { + box = getBounds(box, outline, lineWidth, expansion); + switch (orientation) { + case PositionConstants.EAST: + return box.getRight(); + case PositionConstants.WEST: + return box.getLeft(); + case PositionConstants.SOUTH: + return box.getBottom(); + case PositionConstants.NORTH: + return box.getTop(); + case PositionConstants.NORTH_EAST: + return box.getTopRight(); + case PositionConstants.NORTH_WEST: + return box.getTopLeft(); + case PositionConstants.SOUTH_EAST: + return box.getBottomRight(); + case PositionConstants.SOUTH_WEST: + return box.getBottomLeft(); + } + return box.getCenter(); + } + + /** + * @param originSize + * @param constrainedSize + * @return + */ + public static Dimension getScaledConstrainedSize(Dimension originSize, + Dimension constrainedSize) { + return getScaledConstrainedSize(originSize.width, originSize.height, + constrainedSize.width, constrainedSize.height); + } + + public static Dimension getScaledConstrainedSize(int w, int h, + int maxWidth, int maxHeight) { + if (w == 0 || h == 0) + return new Dimension(); + if (maxWidth < 0 && maxHeight < 0) + return new Dimension(w, h); + if (w <= maxWidth && h <= maxHeight) + return new Dimension(w, h); + int nw = w * maxHeight / h; + int nh = h * maxWidth / w; + if (maxWidth < 0) + return new Dimension(nw, maxHeight); + if (maxHeight < 0) + return new Dimension(maxWidth, nh); + if (nw < maxWidth) + maxWidth = nw; + if (nh < maxHeight) + maxHeight = nh; + return new Dimension(Math.max(1, maxWidth), Math.max(1, maxHeight)); + } + + public static Point getPopupLocation(Dimension size, Rectangle host, + Rectangle display) { + Point p = host.getBottomLeft(); + if (p.y + size.height > display.bottom()) { + p.y = host.y - size.height; + if (p.y < 0) { + p.y = display.y - size.height; + } + } + if (p.y < display.y) { + p.y = display.y; + } + if (p.x + size.width > display.right()) { + p.x = display.right() - size.width; + } + if (p.x < display.x) { + p.x = display.x; + } + return p; + } + + public static int getOrientation(Point p) { + return getOrientation(p.x, p.y, 0, 0); + } + + public static int getOrientation(Point p, Point origin) { + if (p == null) + return PositionConstants.NONE; + return getOrientation(p.x, p.y, origin.x, origin.y); + } + + public static int getOrientation(int x1, int y1, int x2, int y2) { + if (x1 == x2 && y1 < y2) + return PositionConstants.NORTH; + if (x1 > x2 && y1 < y2) + return PositionConstants.NORTH_EAST; + if (x1 > x2 && y1 == y2) + return PositionConstants.EAST; + if (x1 > x2 && y1 > y2) + return PositionConstants.SOUTH_EAST; + if (x1 == x2 && y1 > y2) + return PositionConstants.SOUTH; + if (x1 < x2 && y1 > y2) + return PositionConstants.SOUTH_WEST; + if (x1 < x2 && y1 == y2) + return PositionConstants.WEST; + if (x1 < x2 && y1 < y2) + return PositionConstants.NORTH_WEST; + return PositionConstants.NONE; + } + + public static int getOppositePosition(int position) { + if (position == PositionConstants.EAST) + return PositionConstants.WEST; + if (position == PositionConstants.WEST) + return PositionConstants.EAST; + if (position == PositionConstants.SOUTH) + return PositionConstants.NORTH; + if (position == PositionConstants.NORTH) + return PositionConstants.SOUTH; + if (position == PositionConstants.NORTH_EAST) + return PositionConstants.SOUTH_WEST; + if (position == PositionConstants.NORTH_WEST) + return PositionConstants.SOUTH_EAST; + if (position == PositionConstants.SOUTH_EAST) + return PositionConstants.NORTH_WEST; + if (position == PositionConstants.SOUTH_WEST) + return PositionConstants.NORTH_EAST; + if (position == PositionConstants.NORTH_SOUTH) + return PositionConstants.EAST_WEST; + if (position == PositionConstants.EAST_WEST) + return PositionConstants.NORTH_SOUTH; + return position; + } + + public static Point getPositionWithin(int alignment, Rectangle boundingBox, + Dimension toPlace) { + int x; + if ((alignment & PositionConstants.LEFT) != 0) { + x = boundingBox.x; + } else if ((alignment & PositionConstants.RIGHT) != 0) { + x = boundingBox.right() - toPlace.width; + } else { + x = boundingBox.x + (boundingBox.width - toPlace.width) / 2; + } + int y; + if ((alignment & PositionConstants.TOP) != 0) { + y = boundingBox.y; + } else if ((alignment & PositionConstants.BOTTOM) != 0) { + y = boundingBox.bottom() - toPlace.height; + } else { + y = boundingBox.y + (boundingBox.height - toPlace.height) / 2; + } + return new Point(x, y); + } + + public static Point getRotatedPoint(Point p, double angle) { + angle += getAngle(p); + double distance = p.getDistance(new Point()); + return getPoint(angle, distance); + } + + public static PointList getRotatedRectangle(Rectangle r, double theta) { + PointList pl = new PointList(4); + pl.addPoint(getRotatedPoint(r.getTopLeft(), theta)); + pl.addPoint(getRotatedPoint(r.getTopRight(), theta)); + pl.addPoint(getRotatedPoint(r.getBottomLeft(), theta)); + pl.addPoint(getRotatedPoint(r.getBottomRight(), theta)); + return pl; + } + + public static Dimension getConstrainedSize(Dimension size, + Dimension minSize, Dimension maxSize) { + return new Dimension( + constrain(size.width, minSize.width, maxSize.width), constrain( + size.height, minSize.height, maxSize.height)); + } + + public static int constrain(int i, int min, int max) { + return Math.max(Math.min(i, max), min); + } + + public static double constrain(double d, double min, double max) { + return Math.max(Math.min(d, max), min); + } + + public static Dimension getScaledConstrainedSize2(Dimension size, + Dimension origin, Dimension minSize, Dimension maxSize) { + return getScaledConstrainedSize2(size.width, size.height, + slope(origin), minSize.width, minSize.height, maxSize.width, + maxSize.height); + } + + public static Dimension getScaledConstrainedSize2(double width, + double height, Dimension origin, Dimension minSize, + Dimension maxSize) { + return getScaledConstrainedSize2(width, height, slope(origin), + minSize.width, minSize.height, maxSize.width, maxSize.height); + } + + public static Dimension getScaledConstrainedSize2(double width, + double height, double originWidth, double originHeight, + double minWidth, double minHeight, double maxWidth, double maxHeight) { + return getScaledConstrainedSize2(width, height, + slope(originWidth, originHeight), minWidth, minHeight, + maxWidth, maxHeight); + } + + public static Dimension getScaledConstrainedSize2(double width, + double height, double slope, double minWidth, double minHeight, + double maxWidth, double maxHeight) { + double prefH = constrain(width * slope, minHeight, maxHeight); + if (height < prefH) { + if (height >= 0) + height = prefH; + else + width = constrain(width, minWidth, maxWidth); + } else { + if (height >= 0) + width = constrain(height / slope, minWidth, maxWidth); + } + height = constrain(width * slope, minHeight, maxHeight); + width = constrain(height / slope, minWidth, maxWidth); + return new Dimension((int) (Math.floor(width)), + (int) (Math.floor(height))); + } + + public static double slope(Dimension size) { + return slope(size.width, size.height); + } + + public static double slope(double width, double height) { + return height / width; + } + + /** + * Method getLineSegments. Converts the points of this polyline into a list + * of PrecisionLine objects + * + * @param points + * PointList to get PrecisionLine equivalents of. + * @return List of PrecisionLine objects. + */ + public static List getLineSegments( + List points) { + if (points.size() <= 1) + return new ArrayList(0); + ArrayList lines = new ArrayList( + points.size() - 1); + for (int i = 0; i < points.size() - 1; i++) { + lines.add(new PrecisionLine(points.get(i), points.get(i + 1), + LineType.LineSegment)); + } + return lines; + } + + public static List getLineSegments(PrecisionPoint... points) { + return getLineSegments(Arrays.asList(points)); + } + + /** + * Method getLineSegments. Converts the points of this polyline into a list + * of PrecisionLine objects + * + * @param points + * PointList to get PrecisionLine equivalents of. + * @return List of PrecisionLine objects. + */ + public static List getLineSegments(PrecisionPoint origin, + List points) { + if (points.size() <= 1) + return new ArrayList(0); + + ArrayList lines = new ArrayList( + points.size() - 1); + + for (int i = 0; i < points.size() - 1; i++) { + lines.add(new PrecisionLine(new PrecisionPoint(origin) + .translate(points.get(i)), new PrecisionPoint(origin) + .translate(points.get(i + 1)), LineType.LineSegment)); + } + return lines; + } + + public static PrecisionPoint getRayXLine(PrecisionLine ray, + PrecisionLine line, int tolerance) { + List intersections = ray.getLinesIntersections(line); + for (int i = 0; i < intersections.size(); i++) { + PrecisionPoint p = intersections.get(i); + if (rayContainsPoint(ray, p, tolerance)) + return p; + } + return null; + } + + public static PrecisionPoint getRayXLineSeg(PrecisionLine ray, + PrecisionLine lineSeg, int tolerance) { + List intersections = ray.getLinesIntersections(lineSeg); + for (int i = 0; i < intersections.size(); i++) { + PrecisionPoint p = intersections.get(i); + if (lineSeg.contains(p, tolerance) + && rayContainsPoint(ray, p, tolerance)) + return p; + } + return null; + } + + public static PrecisionPoint getRayXRect(PrecisionLine ray, + PrecisionRectangle r, int tolerance) { + List lines = getLineSegments(r.getTopLeft(), + r.getTopRight(), r.getBottomRight(), r.getBottomLeft(), + r.getTopLeft()); + for (PrecisionLine line : lines) { + PrecisionPoint p = getRayXLineSeg(ray, line, tolerance); + if (p != null) + return p; + } + return null; + } + + public static PrecisionPoint getRayXRectFarther(PrecisionLine ray, + PrecisionRectangle r, int tolerance) { + PrecisionPoint ret = null; + double dist = -1; + List lines = getLineSegments(r.getTopLeft(), + r.getTopRight(), r.getBottomRight(), r.getBottomLeft(), + r.getTopLeft()); + for (PrecisionLine line : lines) { + PrecisionPoint p = getRayXLineSeg(ray, line, tolerance); + if (p != null) { + if (ret == null) { + ret = p; + dist = ret.getDistance(ray.getOrigin()); + } else { + double d = p.getDistance(ray.getOrigin()); + if (d > dist) { + ret = p; + dist = d; + } + } + } + } + return ret; + } + + public static boolean rayContainsPoint(PrecisionLine ray, PrecisionPoint p, + int tolerance) { + return ray.contains(p, tolerance) + || new PrecisionLine(ray.getOrigin(), p).contains( + ray.getTerminus(), tolerance); + } + +// public static PrecisionPoint getCenter( PrecisionPoint p1, PrecisionPoint p2 ) { +// return new PrecisionPoint( ( p1.x + p2.x ) / 2, ( p1.y + p2.y) / 2 ); +// } + + public static Rectangle union(Rectangle r1, Rectangle r2) { + if (r2 == null) + return r1; + if (r1 == null) + return r2.getCopy(); + return r1.union(r2); + } + + public static PrecisionRectangle union(PrecisionRectangle r1, + PrecisionRectangle r2) { + if (r2 == null) + return r1; + if (r1 == null) + return r2.getCopy(); + return r1.union(r2); + } + + public static Rectangle intersect(Rectangle r1, Rectangle r2) { + if (r2 == null) + return r1; + if (r1 == null) + return r2.getCopy(); + return r1.intersect(r2); + } + + public static PrecisionRectangle intersect(PrecisionRectangle r1, + PrecisionRectangle r2) { + if (r2 == null) + return r1; + if (r1 == null) + return r2.getCopy(); + return r1.intersect(r2); + } + + public static PrecisionPoint[] intersectQuadBezier(PrecisionLine line, + double x1, double y1, double x2, double y2, double x3, double y3) { + double u1 = x1 - 2 * x2 + x3; + double v1 = y1 - 2 * y2 + y3; + double u2 = 2 * x2 - 2 * x3; + double v2 = 2 * y2 - 2 * y3; + double u3 = x3; + double v3 = y3; + double[] eq = line.getEquation(); + double a = eq[0] * u1 + eq[1] * v1; + double b = eq[0] * u2 + eq[1] * v2; + double c = eq[0] * u3 + eq[1] * v3 - eq[2]; + double delta = b * b - 4 * a * c; + if (Math.abs(delta) < 0.000000001) { + double t = -b / (2 * a); + if (t >= 0 && t <= 1) { + double x = u1 * t * t + u2 * t + u3; + double y = v1 * t * t + v2 * t + v3; + PrecisionPoint p = new PrecisionPoint(x, y); + if (line.contains(p)) + return new PrecisionPoint[] { p }; + } + } else if (delta > 0) { + double d = Math.sqrt(delta); + List list = new ArrayList(); + double t1 = (-b + d) / (2 * a); + if (t1 >= 0 && t1 <= 1) { + double x = u1 * t1 * t1 + u2 * t1 + u3; + double y = v1 * t1 * t1 + v2 * t1 + v3; + PrecisionPoint p = new PrecisionPoint(x, y); + if (line.contains(p)) { + list.add(p); + } + } + double t2 = (-b - d) / (2 * a); + if (t2 >= 0 && t2 <= 1) { + double x = u1 * t2 * t2 + u2 * t2 + u3; + double y = v1 * t2 * t2 + v2 * t2 + v3; + PrecisionPoint p = new PrecisionPoint(x, y); + if (line.contains(p)) { + list.add(p); + } + } + return list.toArray(new PrecisionPoint[0]); + } + return new PrecisionPoint[0]; + } + + public static PrecisionPoint getChopBoxLocation(double refX, double refY, + Rectangle r, double expansion) { + double centerX = r.x + 0.5 * r.width; + double centerY = r.y + 0.5 * r.height; + double dx = refX - centerX; + double dy = refY - centerY; + if (dx == 0) + return new PrecisionPoint(refX, (dy > 0) ? r.bottom() + expansion + : r.y - expansion); + if (dy == 0) + return new PrecisionPoint((dx > 0) ? r.right() + expansion : r.x + - expansion, refY); + double scale = 0.5 / Math.max(Math.abs(dx) / r.width, Math.abs(dy) + / r.height); + dx *= scale; + dy *= scale; + double d = Math.hypot(dx, dy); + if (d != 0) { + double s = expansion / d; + dx += dx * s; + dy += dy * s; + } + centerX += dx; + centerY += dy; + return new PrecisionPoint(centerX, centerY); + } + + public static Point getChopBoxLocation(int x, int y, Rectangle box) { + float centerX = box.x + 0.5f * box.width; + float centerY = box.y + 0.5f * box.height; + + float dx = x - centerX; + float dy = y - centerY; + +// when preference in the center + if (dx == 0) + return new Point(x, (dy > 0) ? box.bottom() : box.y); + if (dy == 0) + return new Point((dx > 0) ? box.right() : box.x, y); + + // r.width, r.height, dx, and dy are guaranteed to be non-zero. + float scale = 0.5f / Math.max(Math.abs(dx) / box.width, Math.abs(dy) + / box.height); + + dx *= scale; + dy *= scale; + centerX += dx; + centerY += dy; + + return new Point(Math.round(centerX), Math.round(centerY)); + } + + public static Point getChopBoxLocation(Point reference, Rectangle box) { + return getChopBoxLocation(reference.x, reference.y, box); + } + + public static PrecisionPoint getChopOvalLocation(double refX, double refY, + Rectangle r, double expansion) { + double cx = r.x + r.width * 0.5d; + double cy = r.y + r.height * 0.5d; + double rx = refX - cx; + double ry = refY - cy; + if (rx == 0) + return new PrecisionPoint(refX, (ry > 0) ? r.bottom() + expansion + : r.y - expansion); + if (ry == 0) + return new PrecisionPoint((rx > 0) ? r.right() + expansion : r.x + - expansion, refY); + + double scaleX = (rx > 0) ? 0.5d : -0.5d; + double scaleY = (ry > 0) ? 0.5d : -0.5d; + + // ref.x, ref.y, r.width, r.height != 0 => safe to proceed + + double k = (ry * r.width) / (rx * r.height); + k = k * k; + + double dx = r.width * scaleX / sqrt(1 + k); + double dy = r.height * scaleY / sqrt(1 + 1 / k); + double d = Math.hypot(dx, dy); + if (d != 0) { + double s = expansion / d; + dx += dx * s; + dy += dy * s; + } + return new PrecisionPoint(cx + dx, cy + dy); + } + + public static Point getChopOvalLocation(int x, int y, Rectangle r) { + Point ref = r.getCenter().negate().translate(x, y); + + if (ref.x == 0) + return new Point(x, (ref.y > 0) ? r.bottom() : r.y); + if (ref.y == 0) + return new Point((ref.x > 0) ? r.right() : r.x, y); + + float dx = (ref.x > 0) ? 0.5f : -0.5f; + float dy = (ref.y > 0) ? 0.5f : -0.5f; + + // ref.x, ref.y, r.width, r.height != 0 => safe to proceed + + float k = (float) (ref.y * r.width) / (ref.x * r.height); + k = k * k; + + return r.getCenter().translate((int) (r.width * dx / sqrt(1 + k)), + (int) (r.height * dy / sqrt(1 + 1 / k))); + } + + public static Point getChopOvalLocation(Point reference, Rectangle r) { + return getChopOvalLocation(reference.x, reference.y, r); + } + + public static PrecisionPointPair calculatePositionPair(PrecisionPoint from, + PrecisionPoint to, double w) { + PrecisionPointPair result = new PrecisionPointPair(from.getCopy(), + from.getCopy()); + if (from.equals(to)) + return result; + + PrecisionDimension d = from.getDifference(to); + double wScale = d.width == 0 ? 1 : Math.abs(w / d.width); + double hScale = d.height == 0 ? 1 : Math.abs(w / d.height); + d.scale(wScale, hScale); + result.translate(d); + d.width = -d.width; + result.translateFirstPoint(d.transpose()); + result.translateSecondPoint(d.negate()); + + return result; + } + + public static double getDistance(PrecisionPoint p, PrecisionLine line) { + PrecisionPoint p1 = line.getOrigin(); + PrecisionPoint p2 = line.getTerminus(); + double dx = p2.x - p1.x; + double dy = p2.y - p1.y; + if (dx == 0 && dy == 0) + return 0; + if (dy == 0) + return Math.abs(p.y - p1.y); + if (dx == 0) + return Math.abs(p.x - p1.x); + double k = dx / dy; + double m = dy / dx; + double y = (p1.y * k - p1.x + p.y * m + p.x) / (k + m); + double x = (y - p1.y) * k + p1.x; + return Math.hypot(p.x - x, p.y - y); + } + +// * -------------------------- +// * | | | +// * | 3 | 4 | +// * ------------------------------> +// * | | | +// * | 2 | 1 | +// * -------------------------- +// * \/ + public static int getQuadrant(double x, double y, Point center) { + if (x <= center.x && y <= center.y) { + return QUADRANT_THREE; + } else if (x <= center.x && y >= center.y) { + return QUADRANT_TWO; + } else if (x >= center.x && y <= center.y) { + return QUADRANT_FOUR; + } else { + return QUADRANT_ONE; + } + } + + /** + * Calculate angle of point(x,y)->rectangle center; Angles are interpreted + * such that 0 degrees is at the 3 o'clock position. A positive value + * indicates a counter-clockwise rotation while a negative value indicates a + * clockwise rotation. the returned angle is in the range -pi through + * pi. + */ + public static double getAngle(double x, double y, Rectangle r) { + double cx = r.x + r.width * 0.5d; + double cy = r.y + r.height * 0.5d; + + if (x == cx && y >= cy) + return HALF_PI; + if (x == cx && y <= cy) + return NEG_HALF_PI; + + double angrad = Math.atan((y - cy) / (x - cx)); + int quadrant = getQuadrant(x, y, r.getCenter()); + + if (quadrant == QUADRANT_ONE) { + angrad = -angrad; + } else if (quadrant == QUADRANT_TWO) { + angrad = -PI - angrad; + } else if (quadrant == QUADRANT_THREE) { + angrad = PI - angrad; + } else if (quadrant == QUADRANT_FOUR) { + angrad = -angrad; + } + + return angrad; + } + + /** + * Calculate oval angle of point correspondence;Angles are interpreted such + * that 0 degrees is at the 3 o'clock position;the returned angle is in the + * range -pi through pi. + * + * @param x + * x-coordinate of the point on the ellipse + * @param y + * y-coordinate of the point on the ellipse + * @param r + * oval external rectangle + * @return + */ + public static double getOvalAngle(double x, double y, Rectangle r) { + double cx = r.x + r.width * 0.5d; + + double k = 2 * (x - cx) / r.width; + if (k > 1) + k = 1; + if (k < -1) + k = -1; + + double angrad = Math.acos(k); + int quadrant = getQuadrant(x, y, r.getCenter()); + + if (quadrant == QUADRANT_ONE || quadrant == QUADRANT_TWO) { + angrad = -angrad; + } + return angrad; + } + + /** + * Calculate point(x,y) which edge contains. + * + * @param x + * @param y + * @param r + * @return + */ + public static int getSide(double x, double y, Rectangle r) { + double cx = r.x + r.width * 0.5d; + double cy = r.y + r.height * 0.5d; + + if ((x >= r.x && x <= cx) && Math.abs(y - r.y) <= MIN_DISTANCE) { + return SIDE_ONE; + } else if ((x >= cx && x <= r.x + r.width * 1d) + && Math.abs(y - r.y) <= MIN_DISTANCE) { + return SIDE_TWO; + } else if ((y >= r.y && y <= cy) + && Math.abs((x - (r.x + r.width * 1.0d))) <= MIN_DISTANCE) { + return SIDE_THREE; + } else if ((y >= cy && y <= r.y + r.height * 1d) + && Math.abs((x - (r.x + r.width * 1.0d))) <= MIN_DISTANCE) { + return SIDE_FOUR; + } else if ((x >= cx && x <= r.x + r.width * 1d) + && Math.abs((y - (r.y + r.height * 1.0d))) <= MIN_DISTANCE) { + return SIDE_FIVE; + } else if ((x >= r.x && x <= cx) + && Math.abs((y - (r.y + r.height * 1.0d))) <= MIN_DISTANCE) { + return SIDE_SIX; + } else if ((y >= cy && y <= r.y + r.height * 1.0d) + && (Math.abs(x - r.x) <= MIN_DISTANCE)) { + return SIDE_SEVEN; + } else { + return SIDE_EIGHT; + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/IBoundsProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/IBoundsProvider.java index 351cc1f14..72f91f2cf 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/IBoundsProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/geometry/IBoundsProvider.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.geometry; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; - -public interface IBoundsProvider { - - public Rectangle getPrefBounds(Object host, Point reference); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.geometry; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; + +public interface IBoundsProvider { + + public Rectangle getPrefBounds(Object host, Point reference); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/AlphaGraphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/AlphaGraphics.java index 143333a63..967a37e1e 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/AlphaGraphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/AlphaGraphics.java @@ -1,463 +1,463 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.LineAttributes; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.TextLayout; -import org.xmind.gef.draw2d.IUseTransparency; - -/** - * @author Frank Shaka - */ -public class AlphaGraphics extends Graphics implements IUseTransparency { - - private Graphics delegate; - - private int alphaMask = 0xff; - - private int localAlpha; - - private GradientPattern localBgPattern; - - private GradientPattern localFgPattern; - - public AlphaGraphics(Graphics delegate) { - this.delegate = delegate; - delegate.pushState(); - this.localAlpha = delegate.getAlpha(); - delegate.setAlpha(getWorkingAlpha(localAlpha)); - } - - protected Graphics getDelegate() { - return delegate; - } - - public int getMainAlpha() { - return alphaMask; - } - - public void setMainAlpha(int alphaMask) { - this.alphaMask = alphaMask; - delegate.setAlpha(getWorkingAlpha(localAlpha)); - } - - public int getSubAlpha() { - return getAlpha(); - } - - public void setSubAlpha(int alpha) { - setAlpha(alpha); - } - - public void setAlpha(int alpha) { - localAlpha = alpha; - delegate.setAlpha(getWorkingAlpha(alpha)); - } - - private int getWorkingAlpha(int alpha) { - return alpha * getMainAlpha() / 0xff; - } - - public int getAlpha() { - return localAlpha; - } - - public void setBackgroundPattern(Pattern pattern) { - if (pattern instanceof GradientPattern) { - GradientPattern gp = (GradientPattern) pattern; - if (localBgPattern != null) - localBgPattern.dispose(); - localBgPattern = new GradientPattern(gp.getDevice(), gp.x1, gp.y1, - gp.x2, gp.y2, gp.color1, getWorkingAlpha(gp.alpha1), - gp.color2, getWorkingAlpha(gp.alpha2)); - delegate.setBackgroundPattern(localBgPattern); - } else { - delegate.setBackgroundPattern(pattern); - } - } - - public void setForegroundPattern(Pattern pattern) { - if (pattern instanceof GradientPattern) { - GradientPattern gp = (GradientPattern) pattern; - if (localFgPattern != null) - localFgPattern.dispose(); - localFgPattern = new GradientPattern(gp.getDevice(), gp.x1, gp.y1, - gp.x2, gp.y2, gp.color1, getWorkingAlpha(gp.alpha1), - gp.color2, getWorkingAlpha(gp.alpha2)); - delegate.setBackgroundPattern(localFgPattern); - } else { - delegate.setForegroundPattern(pattern); - } - } - - public void dispose() { - delegate.popState(); - if (localBgPattern != null) { - localBgPattern.dispose(); - localBgPattern = null; - } - if (localFgPattern != null) { - localFgPattern.dispose(); - localFgPattern = null; - } - } - - // -------------------------- - // Delegating Methods - // -------------------------- - - public void clipRect(Rectangle r) { - delegate.clipRect(r); - } - - public void clipPath(Path path) { - delegate.clipPath(path); - } - - public void drawArc(int x, int y, int w, int h, int offset, int length) { - delegate.drawArc(x, y, w, h, offset, length); - } - - public void drawFocus(int x, int y, int w, int h) { - delegate.drawFocus(x, y, w, h); - } - - public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) { - delegate.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); - } - - public void drawImage(Image srcImage, int x, int y) { - delegate.drawImage(srcImage, x, y); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - delegate.drawLine(x1, y1, x2, y2); - } - - public void drawOval(int x, int y, int w, int h) { - delegate.drawOval(x, y, w, h); - } - - public void drawPath(Path path) { - delegate.drawPath(path); - } - - public void drawPoint(int x, int y) { - delegate.drawPoint(x, y); - } - - public void drawPolygon(int[] points) { - delegate.drawPolygon(points); - } - - public void drawPolygon(PointList points) { - delegate.drawPolygon(points); - } - - public void drawPolyline(int[] points) { - delegate.drawPolyline(points); - } - - public void drawPolyline(PointList points) { - delegate.drawPolyline(points); - } - - public void drawRectangle(int x, int y, int width, int height) { - delegate.drawRectangle(x, y, width, height); - } - - public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - delegate.drawRoundRectangle(r, arcWidth, arcHeight); - } - - public void drawString(String s, int x, int y) { - delegate.drawString(s, x, y); - } - - public void drawText(String s, int x, int y, int style) { - delegate.drawText(s, x, y, style); - } - - public void drawText(String s, int x, int y) { - delegate.drawText(s, x, y); - } - - public void drawTextLayout(TextLayout layout, int x, int y, - int selectionStart, int selectionEnd, Color selectionForeground, - Color selectionBackground) { - delegate.drawTextLayout(layout, x, y, selectionStart, selectionEnd, - selectionForeground, selectionBackground); - } - - public boolean equals(Object obj) { - return super.equals(obj); - } - - public void fillArc(int x, int y, int w, int h, int offset, int length) { - delegate.fillArc(x, y, w, h, offset, length); - } - - public void fillGradient(int x, int y, int w, int h, boolean vertical) { - delegate.fillGradient(x, y, w, h, vertical); - } - - public void fillOval(int x, int y, int w, int h) { - delegate.fillOval(x, y, w, h); - } - - public void fillPath(Path path) { - delegate.fillPath(path); - } - - public void fillPolygon(int[] points) { - delegate.fillPolygon(points); - } - - public void fillPolygon(PointList points) { - delegate.fillPolygon(points); - } - - public void fillRectangle(int x, int y, int width, int height) { - delegate.fillRectangle(x, y, width, height); - } - - public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - delegate.fillRoundRectangle(r, arcWidth, arcHeight); - } - - public void fillString(String s, int x, int y) { - delegate.fillString(s, x, y); - } - - public void fillText(String s, int x, int y) { - delegate.fillText(s, x, y); - } - - public double getAbsoluteScale() { - return delegate.getAbsoluteScale(); - } - - public int getAntialias() { - return delegate.getAntialias(); - } - - public Color getBackgroundColor() { - return delegate.getBackgroundColor(); - } - - public Rectangle getClip(Rectangle rect) { - return delegate.getClip(rect); - } - - public int getFillRule() { - return delegate.getFillRule(); - } - - public Font getFont() { - return delegate.getFont(); - } - - public FontMetrics getFontMetrics() { - return delegate.getFontMetrics(); - } - - public Color getForegroundColor() { - return delegate.getForegroundColor(); - } - - public int getInterpolation() { - return delegate.getInterpolation(); - } - - public int getLineCap() { - return delegate.getLineCap(); - } - - public int getLineJoin() { - return delegate.getLineJoin(); - } - - public int getLineStyle() { - return delegate.getLineStyle(); - } - - public int getLineWidth() { - return delegate.getLineWidth(); - } - - public int getTextAntialias() { - return delegate.getTextAntialias(); - } - - public boolean getXORMode() { - return delegate.getXORMode(); - } - - public int hashCode() { - return delegate.hashCode(); - } - - public void popState() { - delegate.popState(); - } - - public void pushState() { - delegate.pushState(); - } - - public void restoreState() { - delegate.restoreState(); - } - - public void rotate(float degrees) { - delegate.rotate(degrees); - } - - public void scale(double amount) { - delegate.scale(amount); - } - - public void scale(float horizontal, float vertical) { - delegate.scale(horizontal, vertical); - } - - public void setAntialias(int value) { - delegate.setAntialias(value); - } - - public void setBackgroundColor(Color rgb) { - delegate.setBackgroundColor(rgb); - } - - public void setClip(Path path) { - delegate.setClip(path); - } - - public void setClip(Rectangle r) { - delegate.setClip(r); - } - - public void setFillRule(int rule) { - delegate.setFillRule(rule); - } - - public void setFont(Font f) { - delegate.setFont(f); - } - - public void setForegroundColor(Color rgb) { - delegate.setForegroundColor(rgb); - } - - public void setInterpolation(int interpolation) { - delegate.setInterpolation(interpolation); - } - - public void setLineCap(int cap) { - delegate.setLineCap(cap); - } - - public void setLineDash(int[] dash) { - delegate.setLineDash(dash); - } - - public void setLineJoin(int join) { - delegate.setLineJoin(join); - } - - public void setLineStyle(int style) { - delegate.setLineStyle(style); - } - - public void setLineWidth(int width) { - delegate.setLineWidth(width); - } - - public void setTextAntialias(int value) { - delegate.setTextAntialias(value); - } - - public void setXORMode(boolean b) { - delegate.setXORMode(b); - } - - public void shear(float horz, float vert) { - delegate.shear(horz, vert); - } - - public String toString() { - return delegate.toString(); - } - - public void translate(float dx, float dy) { - delegate.translate(dx, dy); - } - - public void translate(int dx, int dy) { - delegate.translate(dx, dy); - } - - // =========================================================== - // Since 3.5 - // =========================================================== - - public void setAdvanced(boolean advanced) { - delegate.setAdvanced(advanced); - } - - public float getLineWidthFloat() { - return delegate.getLineWidthFloat(); - } - - @Override - public LineAttributes getLineAttributes() { - return super.getLineAttributes(); - } - - @Override - public float getLineMiterLimit() { - return super.getLineMiterLimit(); - } - - public boolean getAdvanced() { - return delegate.getAdvanced(); - } - - public void setLineAttributes(LineAttributes attributes) { - delegate.setLineAttributes(attributes); - } - - public void setLineDash(float[] value) { - delegate.setLineDash(value); - }; - - public void setLineMiterLimit(float miterLimit) { - delegate.setLineMiterLimit(miterLimit); - } - - public void setLineWidthFloat(float width) { - delegate.setLineWidthFloat(width); - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.LineAttributes; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.TextLayout; +import org.xmind.gef.draw2d.IUseTransparency; + +/** + * @author Frank Shaka + */ +public class AlphaGraphics extends Graphics implements IUseTransparency { + + private Graphics delegate; + + private int alphaMask = 0xff; + + private int localAlpha; + + private GradientPattern localBgPattern; + + private GradientPattern localFgPattern; + + public AlphaGraphics(Graphics delegate) { + this.delegate = delegate; + delegate.pushState(); + this.localAlpha = delegate.getAlpha(); + delegate.setAlpha(getWorkingAlpha(localAlpha)); + } + + protected Graphics getDelegate() { + return delegate; + } + + public int getMainAlpha() { + return alphaMask; + } + + public void setMainAlpha(int alphaMask) { + this.alphaMask = alphaMask; + delegate.setAlpha(getWorkingAlpha(localAlpha)); + } + + public int getSubAlpha() { + return getAlpha(); + } + + public void setSubAlpha(int alpha) { + setAlpha(alpha); + } + + public void setAlpha(int alpha) { + localAlpha = alpha; + delegate.setAlpha(getWorkingAlpha(alpha)); + } + + private int getWorkingAlpha(int alpha) { + return alpha * getMainAlpha() / 0xff; + } + + public int getAlpha() { + return localAlpha; + } + + public void setBackgroundPattern(Pattern pattern) { + if (pattern instanceof GradientPattern) { + GradientPattern gp = (GradientPattern) pattern; + if (localBgPattern != null) + localBgPattern.dispose(); + localBgPattern = new GradientPattern(gp.getDevice(), gp.x1, gp.y1, + gp.x2, gp.y2, gp.color1, getWorkingAlpha(gp.alpha1), + gp.color2, getWorkingAlpha(gp.alpha2)); + delegate.setBackgroundPattern(localBgPattern); + } else { + delegate.setBackgroundPattern(pattern); + } + } + + public void setForegroundPattern(Pattern pattern) { + if (pattern instanceof GradientPattern) { + GradientPattern gp = (GradientPattern) pattern; + if (localFgPattern != null) + localFgPattern.dispose(); + localFgPattern = new GradientPattern(gp.getDevice(), gp.x1, gp.y1, + gp.x2, gp.y2, gp.color1, getWorkingAlpha(gp.alpha1), + gp.color2, getWorkingAlpha(gp.alpha2)); + delegate.setForegroundPattern(localFgPattern); + } else { + delegate.setForegroundPattern(pattern); + } + } + + public void dispose() { + delegate.popState(); + if (localBgPattern != null) { + localBgPattern.dispose(); + localBgPattern = null; + } + if (localFgPattern != null) { + localFgPattern.dispose(); + localFgPattern = null; + } + } + + // -------------------------- + // Delegating Methods + // -------------------------- + + public void clipRect(Rectangle r) { + delegate.clipRect(r); + } + + public void clipPath(Path path) { + delegate.clipPath(path); + } + + public void drawArc(int x, int y, int w, int h, int offset, int length) { + delegate.drawArc(x, y, w, h, offset, length); + } + + public void drawFocus(int x, int y, int w, int h) { + delegate.drawFocus(x, y, w, h); + } + + public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) { + delegate.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); + } + + public void drawImage(Image srcImage, int x, int y) { + delegate.drawImage(srcImage, x, y); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + delegate.drawLine(x1, y1, x2, y2); + } + + public void drawOval(int x, int y, int w, int h) { + delegate.drawOval(x, y, w, h); + } + + public void drawPath(Path path) { + delegate.drawPath(path); + } + + public void drawPoint(int x, int y) { + delegate.drawPoint(x, y); + } + + public void drawPolygon(int[] points) { + delegate.drawPolygon(points); + } + + public void drawPolygon(PointList points) { + delegate.drawPolygon(points); + } + + public void drawPolyline(int[] points) { + delegate.drawPolyline(points); + } + + public void drawPolyline(PointList points) { + delegate.drawPolyline(points); + } + + public void drawRectangle(int x, int y, int width, int height) { + delegate.drawRectangle(x, y, width, height); + } + + public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + delegate.drawRoundRectangle(r, arcWidth, arcHeight); + } + + public void drawString(String s, int x, int y) { + delegate.drawString(s, x, y); + } + + public void drawText(String s, int x, int y, int style) { + delegate.drawText(s, x, y, style); + } + + public void drawText(String s, int x, int y) { + delegate.drawText(s, x, y); + } + + public void drawTextLayout(TextLayout layout, int x, int y, + int selectionStart, int selectionEnd, Color selectionForeground, + Color selectionBackground) { + delegate.drawTextLayout(layout, x, y, selectionStart, selectionEnd, + selectionForeground, selectionBackground); + } + + public boolean equals(Object obj) { + return super.equals(obj); + } + + public void fillArc(int x, int y, int w, int h, int offset, int length) { + delegate.fillArc(x, y, w, h, offset, length); + } + + public void fillGradient(int x, int y, int w, int h, boolean vertical) { + delegate.fillGradient(x, y, w, h, vertical); + } + + public void fillOval(int x, int y, int w, int h) { + delegate.fillOval(x, y, w, h); + } + + public void fillPath(Path path) { + delegate.fillPath(path); + } + + public void fillPolygon(int[] points) { + delegate.fillPolygon(points); + } + + public void fillPolygon(PointList points) { + delegate.fillPolygon(points); + } + + public void fillRectangle(int x, int y, int width, int height) { + delegate.fillRectangle(x, y, width, height); + } + + public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + delegate.fillRoundRectangle(r, arcWidth, arcHeight); + } + + public void fillString(String s, int x, int y) { + delegate.fillString(s, x, y); + } + + public void fillText(String s, int x, int y) { + delegate.fillText(s, x, y); + } + + public double getAbsoluteScale() { + return delegate.getAbsoluteScale(); + } + + public int getAntialias() { + return delegate.getAntialias(); + } + + public Color getBackgroundColor() { + return delegate.getBackgroundColor(); + } + + public Rectangle getClip(Rectangle rect) { + return delegate.getClip(rect); + } + + public int getFillRule() { + return delegate.getFillRule(); + } + + public Font getFont() { + return delegate.getFont(); + } + + public FontMetrics getFontMetrics() { + return delegate.getFontMetrics(); + } + + public Color getForegroundColor() { + return delegate.getForegroundColor(); + } + + public int getInterpolation() { + return delegate.getInterpolation(); + } + + public int getLineCap() { + return delegate.getLineCap(); + } + + public int getLineJoin() { + return delegate.getLineJoin(); + } + + public int getLineStyle() { + return delegate.getLineStyle(); + } + + public int getLineWidth() { + return delegate.getLineWidth(); + } + + public int getTextAntialias() { + return delegate.getTextAntialias(); + } + + public boolean getXORMode() { + return delegate.getXORMode(); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public void popState() { + delegate.popState(); + } + + public void pushState() { + delegate.pushState(); + } + + public void restoreState() { + delegate.restoreState(); + } + + public void rotate(float degrees) { + delegate.rotate(degrees); + } + + public void scale(double amount) { + delegate.scale(amount); + } + + public void scale(float horizontal, float vertical) { + delegate.scale(horizontal, vertical); + } + + public void setAntialias(int value) { + delegate.setAntialias(value); + } + + public void setBackgroundColor(Color rgb) { + delegate.setBackgroundColor(rgb); + } + + public void setClip(Path path) { + delegate.setClip(path); + } + + public void setClip(Rectangle r) { + delegate.setClip(r); + } + + public void setFillRule(int rule) { + delegate.setFillRule(rule); + } + + public void setFont(Font f) { + delegate.setFont(f); + } + + public void setForegroundColor(Color rgb) { + delegate.setForegroundColor(rgb); + } + + public void setInterpolation(int interpolation) { + delegate.setInterpolation(interpolation); + } + + public void setLineCap(int cap) { + delegate.setLineCap(cap); + } + + public void setLineDash(int[] dash) { + delegate.setLineDash(dash); + } + + public void setLineJoin(int join) { + delegate.setLineJoin(join); + } + + public void setLineStyle(int style) { + delegate.setLineStyle(style); + } + + public void setLineWidth(int width) { + delegate.setLineWidth(width); + } + + public void setTextAntialias(int value) { + delegate.setTextAntialias(value); + } + + public void setXORMode(boolean b) { + delegate.setXORMode(b); + } + + public void shear(float horz, float vert) { + delegate.shear(horz, vert); + } + + public String toString() { + return delegate.toString(); + } + + public void translate(float dx, float dy) { + delegate.translate(dx, dy); + } + + public void translate(int dx, int dy) { + delegate.translate(dx, dy); + } + + // =========================================================== + // Since 3.5 + // =========================================================== + + public void setAdvanced(boolean advanced) { + delegate.setAdvanced(advanced); + } + + public float getLineWidthFloat() { + return delegate.getLineWidthFloat(); + } + + @Override + public LineAttributes getLineAttributes() { + return super.getLineAttributes(); + } + + @Override + public float getLineMiterLimit() { + return super.getLineMiterLimit(); + } + + public boolean getAdvanced() { + return delegate.getAdvanced(); + } + + public void setLineAttributes(LineAttributes attributes) { + delegate.setLineAttributes(attributes); + } + + public void setLineDash(float[] value) { + delegate.setLineDash(value); + }; + + public void setLineMiterLimit(float miterLimit) { + delegate.setLineMiterLimit(miterLimit); + } + + public void setLineWidthFloat(float width) { + delegate.setLineWidthFloat(width); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ColorMaskGraphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ColorMaskGraphics.java index a0801daf0..58fb3770a 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ColorMaskGraphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ColorMaskGraphics.java @@ -1,559 +1,559 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.draw2d.graphics; - -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.LineAttributes; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.TextLayout; - -/** - * @author Frank Shaka - * - */ -public abstract class ColorMaskGraphics extends Graphics { - - private Graphics delegate; - - private Stack fgColors; - - private Stack bgColors; - - private Color localForeground; - - private Color localBackground; - - private int localAlpha; - - private Map workingColors; - - private Stack fgPatterns; - - private Stack bgPatterns; - - private Pattern currentFgPattern; - - private Pattern currentBgPattern; - - public ColorMaskGraphics(Graphics delegate, Object... args) { - this.delegate = delegate; - init(args); - delegate.pushState(); - this.localForeground = delegate.getForegroundColor(); - this.localBackground = delegate.getBackgroundColor(); - pushColors(); - this.localAlpha = delegate.getAlpha(); - delegate.setForegroundColor(getWorkingColor(localForeground)); - delegate.setBackgroundColor(getWorkingColor(localBackground)); - delegate.setAlpha(0xff); - } - - protected void init(Object... args) { - } - - protected abstract RGB getMaskColor(RGB rgb); - - private void pushColors() { - if (fgColors == null) - fgColors = new Stack(); - fgColors.push(localForeground); - if (bgColors == null) - bgColors = new Stack(); - bgColors.push(localBackground); - } - - private void restoreColors() { - if (fgColors != null && !fgColors.isEmpty()) - localForeground = fgColors.peek(); - if (bgColors != null && !bgColors.isEmpty()) - localBackground = bgColors.peek(); - } - - private void popupColors() { - if (fgColors != null && !fgColors.isEmpty()) - localForeground = fgColors.pop(); - if (bgColors != null && !bgColors.isEmpty()) - localBackground = bgColors.pop(); - } - - protected Graphics getDelegate() { - return delegate; - } - - protected Color getWorkingColor(Color c) { - if (c == null) - return null; - RGB rgb = c.getRGB(); - if (workingColors == null) - workingColors = new HashMap(); - Color grayed = workingColors.get(rgb); - if (grayed == null) { - grayed = createWorkingColor(c.getDevice(), rgb); - workingColors.put(rgb, grayed); - } - return grayed; - } - - private Color createWorkingColor(Device device, RGB rgb) { - return new Color(device, getMaskColor(rgb)); - } - - public void setForegroundColor(Color rgb) { - if (rgb.isDisposed()) { - System.out.println("!!!Color Disposed: " + rgb); //$NON-NLS-1$ - } - localForeground = rgb; - delegate.setForegroundColor(getWorkingColor(rgb)); - } - - public void setBackgroundColor(Color rgb) { - localBackground = rgb; - delegate.setBackgroundColor(getWorkingColor(rgb)); - } - - public Color getForegroundColor() { - return localForeground; - } - - public Color getBackgroundColor() { - return localBackground; - } - - public void setAlpha(int alpha) { - this.localAlpha = alpha; - if (alpha == 0) - delegate.setAlpha(alpha); - else - delegate.setAlpha(0xff); - } - - public int getAlpha() { - return localAlpha; - } - - public void setForegroundPattern(Pattern pattern) { - if (currentFgPattern != null) { - currentFgPattern.dispose(); - currentFgPattern = null; - } - if (pattern instanceof GradientPattern) { - GradientPattern gp = (GradientPattern) pattern; - pattern = createGrayedPattern(gp); - currentFgPattern = pattern; - } - delegate.setForegroundPattern(pattern); - } - - public void setBackgroundPattern(Pattern pattern) { - if (currentBgPattern != null) { - currentBgPattern.dispose(); - currentBgPattern = null; - } - if (pattern instanceof GradientPattern) { - GradientPattern gp = (GradientPattern) pattern; - pattern = createGrayedPattern(gp); - currentBgPattern = pattern; - } - delegate.setBackgroundPattern(pattern); - } - - private Pattern createGrayedPattern(GradientPattern p) { - return new GradientPattern(p.getDevice(), p.x1, p.y1, p.x2, p.y2, - getWorkingColor(p.color1), 0xff, getWorkingColor(p.color2), - 0xff); - } - - public void dispose() { - popupColors(); - delegate.popState(); - if (workingColors != null) { - for (Color c : workingColors.values()) { - c.dispose(); - } - workingColors = null; - } - if (currentFgPattern != null) { - currentFgPattern.dispose(); - currentFgPattern = null; - } - if (currentBgPattern != null) { - currentBgPattern.dispose(); - currentBgPattern = null; - } - if (fgPatterns != null) { - for (Pattern p : fgPatterns) { - if (p != null) - p.dispose(); - } - fgPatterns = null; - } - if (bgPatterns != null) { - for (Pattern p : bgPatterns) { - if (p != null) - p.dispose(); - } - bgPatterns = null; - } - } - - public void pushState() { - delegate.pushState(); - pushColors(); - if (fgPatterns == null) - fgPatterns = new Stack(); - fgPatterns.push(currentFgPattern); - currentFgPattern = null; - - if (bgPatterns == null) - bgPatterns = new Stack(); - bgPatterns.push(currentBgPattern); - currentBgPattern = null; - } - - public void popState() { - delegate.popState(); - popupColors(); - if (currentFgPattern != null) { - currentFgPattern.dispose(); - currentFgPattern = null; - } - if (fgPatterns != null) { - currentFgPattern = fgPatterns.pop(); - } - - if (currentBgPattern != null) { - currentBgPattern.dispose(); - currentBgPattern = null; - } - if (bgPatterns != null) { - currentBgPattern = bgPatterns.pop(); - } - } - - public void restoreState() { - delegate.restoreState(); - restoreColors(); - } - - // --------------------------- - // Delegating Methods - // --------------------------- - - public void clipRect(Rectangle r) { - delegate.clipRect(r); - } - - public void clipPath(Path path) { - delegate.clipPath(path); - } - - public void drawArc(int x, int y, int w, int h, int offset, int length) { - delegate.drawArc(x, y, w, h, offset, length); - } - - public void drawFocus(int x, int y, int w, int h) { - delegate.drawFocus(x, y, w, h); - } - - public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) { - delegate.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); - } - - public void drawImage(Image srcImage, int x, int y) { - delegate.drawImage(srcImage, x, y); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - delegate.drawLine(x1, y1, x2, y2); - } - - public void drawOval(int x, int y, int w, int h) { - delegate.drawOval(x, y, w, h); - } - - public void drawPath(Path path) { - delegate.drawPath(path); - } - - public void drawPoint(int x, int y) { - delegate.drawPoint(x, y); - } - - public void drawPolygon(int[] points) { - delegate.drawPolygon(points); - } - - public void drawPolygon(PointList points) { - delegate.drawPolygon(points); - } - - public void drawPolyline(int[] points) { - delegate.drawPolyline(points); - } - - public void drawPolyline(PointList points) { - delegate.drawPolyline(points); - } - - public void drawRectangle(int x, int y, int width, int height) { - delegate.drawRectangle(x, y, width, height); - } - - public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - delegate.drawRoundRectangle(r, arcWidth, arcHeight); - } - - public void drawString(String s, int x, int y) { - delegate.drawString(s, x, y); - } - - public void drawText(String s, int x, int y, int style) { - delegate.drawText(s, x, y, style); - } - - public void drawText(String s, int x, int y) { - delegate.drawText(s, x, y); - } - - public void drawTextLayout(TextLayout layout, int x, int y, - int selectionStart, int selectionEnd, Color selectionForeground, - Color selectionBackground) { - delegate.drawTextLayout(layout, x, y, selectionStart, selectionEnd, - selectionForeground, selectionBackground); - } - - public void fillArc(int x, int y, int w, int h, int offset, int length) { - delegate.fillArc(x, y, w, h, offset, length); - } - - public void fillGradient(int x, int y, int w, int h, boolean vertical) { - delegate.fillGradient(x, y, w, h, vertical); - } - - public void fillOval(int x, int y, int w, int h) { - delegate.fillOval(x, y, w, h); - } - - public void fillPath(Path path) { - delegate.fillPath(path); - } - - public void fillPolygon(int[] points) { - delegate.fillPolygon(points); - } - - public void fillPolygon(PointList points) { - delegate.fillPolygon(points); - } - - public void fillRectangle(int x, int y, int width, int height) { - delegate.fillRectangle(x, y, width, height); - } - - public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - delegate.fillRoundRectangle(r, arcWidth, arcHeight); - } - - public void fillString(String s, int x, int y) { - delegate.fillString(s, x, y); - } - - public void fillText(String s, int x, int y) { - delegate.fillText(s, x, y); - } - - public double getAbsoluteScale() { - return delegate.getAbsoluteScale(); - } - - public int getAntialias() { - return delegate.getAntialias(); - } - - public Rectangle getClip(Rectangle rect) { - return delegate.getClip(rect); - } - - public int getFillRule() { - return delegate.getFillRule(); - } - - public Font getFont() { - return delegate.getFont(); - } - - public FontMetrics getFontMetrics() { - return delegate.getFontMetrics(); - } - - public int getInterpolation() { - return delegate.getInterpolation(); - } - - public int getLineCap() { - return delegate.getLineCap(); - } - - public int getLineJoin() { - return delegate.getLineJoin(); - } - - public int getLineStyle() { - return delegate.getLineStyle(); - } - - public int getLineWidth() { - return delegate.getLineWidth(); - } - - public int getTextAntialias() { - return delegate.getTextAntialias(); - } - - public boolean getXORMode() { - return delegate.getXORMode(); - } - - public void rotate(float degrees) { - delegate.rotate(degrees); - } - - public void scale(double amount) { - delegate.scale(amount); - } - - public void scale(float horizontal, float vertical) { - delegate.scale(horizontal, vertical); - } - - public void setAntialias(int value) { - delegate.setAntialias(value); - } - - public void setClip(Path path) { - delegate.setClip(path); - } - - public void setClip(Rectangle r) { - delegate.setClip(r); - } - - public void setFillRule(int rule) { - delegate.setFillRule(rule); - } - - public void setFont(Font f) { - delegate.setFont(f); - } - - public void setInterpolation(int interpolation) { - delegate.setInterpolation(interpolation); - } - - public void setLineCap(int cap) { - delegate.setLineCap(cap); - } - - public void setLineDash(int[] dash) { - delegate.setLineDash(dash); - } - - public void setLineJoin(int join) { - delegate.setLineJoin(join); - } - - public void setLineStyle(int style) { - delegate.setLineStyle(style); - } - - public void setLineWidth(int width) { - delegate.setLineWidth(width); - } - - public void setTextAntialias(int value) { - delegate.setTextAntialias(value); - } - - public void setXORMode(boolean b) { - delegate.setXORMode(b); - } - - public void shear(float horz, float vert) { - delegate.shear(horz, vert); - } - - public void translate(float dx, float dy) { - delegate.translate(dx, dy); - } - - public void translate(int dx, int dy) { - delegate.translate(dx, dy); - } - - // ========================================================== - // Since 3.5 - // ========================================================== - - public boolean getAdvanced() { - return delegate.getAdvanced(); - } - - public float getLineMiterLimit() { - return delegate.getLineMiterLimit(); - } - - public LineAttributes getLineAttributes() { - return delegate.getLineAttributes(); - } - - public float getLineWidthFloat() { - return delegate.getLineWidthFloat(); - } - - public void setAdvanced(boolean advanced) { - delegate.setAdvanced(advanced); - } - - public void setLineMiterLimit(float miterLimit) { - delegate.setLineMiterLimit(miterLimit); - } - - public void setLineWidthFloat(float width) { - delegate.setLineWidthFloat(width); - } - - public void setLineAttributes(LineAttributes attributes) { - delegate.setLineAttributes(attributes); - } - - public void setLineDash(float[] value) { - delegate.setLineDash(value); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.draw2d.graphics; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.LineAttributes; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.TextLayout; + +/** + * @author Frank Shaka + * + */ +public abstract class ColorMaskGraphics extends Graphics { + + private Graphics delegate; + + private Stack fgColors; + + private Stack bgColors; + + private Color localForeground; + + private Color localBackground; + + private int localAlpha; + + private Map workingColors; + + private Stack fgPatterns; + + private Stack bgPatterns; + + private Pattern currentFgPattern; + + private Pattern currentBgPattern; + + public ColorMaskGraphics(Graphics delegate, Object... args) { + this.delegate = delegate; + init(args); + delegate.pushState(); + this.localForeground = delegate.getForegroundColor(); + this.localBackground = delegate.getBackgroundColor(); + pushColors(); + this.localAlpha = delegate.getAlpha(); + delegate.setForegroundColor(getWorkingColor(localForeground)); + delegate.setBackgroundColor(getWorkingColor(localBackground)); + delegate.setAlpha(0xff); + } + + protected void init(Object... args) { + } + + protected abstract RGB getMaskColor(RGB rgb); + + private void pushColors() { + if (fgColors == null) + fgColors = new Stack(); + fgColors.push(localForeground); + if (bgColors == null) + bgColors = new Stack(); + bgColors.push(localBackground); + } + + private void restoreColors() { + if (fgColors != null && !fgColors.isEmpty()) + localForeground = fgColors.peek(); + if (bgColors != null && !bgColors.isEmpty()) + localBackground = bgColors.peek(); + } + + private void popupColors() { + if (fgColors != null && !fgColors.isEmpty()) + localForeground = fgColors.pop(); + if (bgColors != null && !bgColors.isEmpty()) + localBackground = bgColors.pop(); + } + + protected Graphics getDelegate() { + return delegate; + } + + protected Color getWorkingColor(Color c) { + if (c == null) + return null; + RGB rgb = c.getRGB(); + if (workingColors == null) + workingColors = new HashMap(); + Color grayed = workingColors.get(rgb); + if (grayed == null) { + grayed = createWorkingColor(c.getDevice(), rgb); + workingColors.put(rgb, grayed); + } + return grayed; + } + + private Color createWorkingColor(Device device, RGB rgb) { + return new Color(device, getMaskColor(rgb)); + } + + public void setForegroundColor(Color rgb) { + if (rgb.isDisposed()) { + System.out.println("!!!Color Disposed: " + rgb); //$NON-NLS-1$ + } + localForeground = rgb; + delegate.setForegroundColor(getWorkingColor(rgb)); + } + + public void setBackgroundColor(Color rgb) { + localBackground = rgb; + delegate.setBackgroundColor(getWorkingColor(rgb)); + } + + public Color getForegroundColor() { + return localForeground; + } + + public Color getBackgroundColor() { + return localBackground; + } + + public void setAlpha(int alpha) { + this.localAlpha = alpha; + if (alpha == 0) + delegate.setAlpha(alpha); + else + delegate.setAlpha(0xff); + } + + public int getAlpha() { + return localAlpha; + } + + public void setForegroundPattern(Pattern pattern) { + if (currentFgPattern != null) { + currentFgPattern.dispose(); + currentFgPattern = null; + } + if (pattern instanceof GradientPattern) { + GradientPattern gp = (GradientPattern) pattern; + pattern = createGrayedPattern(gp); + currentFgPattern = pattern; + } + delegate.setForegroundPattern(pattern); + } + + public void setBackgroundPattern(Pattern pattern) { + if (currentBgPattern != null) { + currentBgPattern.dispose(); + currentBgPattern = null; + } + if (pattern instanceof GradientPattern) { + GradientPattern gp = (GradientPattern) pattern; + pattern = createGrayedPattern(gp); + currentBgPattern = pattern; + } + delegate.setBackgroundPattern(pattern); + } + + private Pattern createGrayedPattern(GradientPattern p) { + return new GradientPattern(p.getDevice(), p.x1, p.y1, p.x2, p.y2, + getWorkingColor(p.color1), 0xff, getWorkingColor(p.color2), + 0xff); + } + + public void dispose() { + popupColors(); + delegate.popState(); + if (workingColors != null) { + for (Color c : workingColors.values()) { + c.dispose(); + } + workingColors = null; + } + if (currentFgPattern != null) { + currentFgPattern.dispose(); + currentFgPattern = null; + } + if (currentBgPattern != null) { + currentBgPattern.dispose(); + currentBgPattern = null; + } + if (fgPatterns != null) { + for (Pattern p : fgPatterns) { + if (p != null) + p.dispose(); + } + fgPatterns = null; + } + if (bgPatterns != null) { + for (Pattern p : bgPatterns) { + if (p != null) + p.dispose(); + } + bgPatterns = null; + } + } + + public void pushState() { + delegate.pushState(); + pushColors(); + if (fgPatterns == null) + fgPatterns = new Stack(); + fgPatterns.push(currentFgPattern); + currentFgPattern = null; + + if (bgPatterns == null) + bgPatterns = new Stack(); + bgPatterns.push(currentBgPattern); + currentBgPattern = null; + } + + public void popState() { + delegate.popState(); + popupColors(); + if (currentFgPattern != null) { + currentFgPattern.dispose(); + currentFgPattern = null; + } + if (fgPatterns != null) { + currentFgPattern = fgPatterns.pop(); + } + + if (currentBgPattern != null) { + currentBgPattern.dispose(); + currentBgPattern = null; + } + if (bgPatterns != null) { + currentBgPattern = bgPatterns.pop(); + } + } + + public void restoreState() { + delegate.restoreState(); + restoreColors(); + } + + // --------------------------- + // Delegating Methods + // --------------------------- + + public void clipRect(Rectangle r) { + delegate.clipRect(r); + } + + public void clipPath(Path path) { + delegate.clipPath(path); + } + + public void drawArc(int x, int y, int w, int h, int offset, int length) { + delegate.drawArc(x, y, w, h, offset, length); + } + + public void drawFocus(int x, int y, int w, int h) { + delegate.drawFocus(x, y, w, h); + } + + public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) { + delegate.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); + } + + public void drawImage(Image srcImage, int x, int y) { + delegate.drawImage(srcImage, x, y); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + delegate.drawLine(x1, y1, x2, y2); + } + + public void drawOval(int x, int y, int w, int h) { + delegate.drawOval(x, y, w, h); + } + + public void drawPath(Path path) { + delegate.drawPath(path); + } + + public void drawPoint(int x, int y) { + delegate.drawPoint(x, y); + } + + public void drawPolygon(int[] points) { + delegate.drawPolygon(points); + } + + public void drawPolygon(PointList points) { + delegate.drawPolygon(points); + } + + public void drawPolyline(int[] points) { + delegate.drawPolyline(points); + } + + public void drawPolyline(PointList points) { + delegate.drawPolyline(points); + } + + public void drawRectangle(int x, int y, int width, int height) { + delegate.drawRectangle(x, y, width, height); + } + + public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + delegate.drawRoundRectangle(r, arcWidth, arcHeight); + } + + public void drawString(String s, int x, int y) { + delegate.drawString(s, x, y); + } + + public void drawText(String s, int x, int y, int style) { + delegate.drawText(s, x, y, style); + } + + public void drawText(String s, int x, int y) { + delegate.drawText(s, x, y); + } + + public void drawTextLayout(TextLayout layout, int x, int y, + int selectionStart, int selectionEnd, Color selectionForeground, + Color selectionBackground) { + delegate.drawTextLayout(layout, x, y, selectionStart, selectionEnd, + selectionForeground, selectionBackground); + } + + public void fillArc(int x, int y, int w, int h, int offset, int length) { + delegate.fillArc(x, y, w, h, offset, length); + } + + public void fillGradient(int x, int y, int w, int h, boolean vertical) { + delegate.fillGradient(x, y, w, h, vertical); + } + + public void fillOval(int x, int y, int w, int h) { + delegate.fillOval(x, y, w, h); + } + + public void fillPath(Path path) { + delegate.fillPath(path); + } + + public void fillPolygon(int[] points) { + delegate.fillPolygon(points); + } + + public void fillPolygon(PointList points) { + delegate.fillPolygon(points); + } + + public void fillRectangle(int x, int y, int width, int height) { + delegate.fillRectangle(x, y, width, height); + } + + public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + delegate.fillRoundRectangle(r, arcWidth, arcHeight); + } + + public void fillString(String s, int x, int y) { + delegate.fillString(s, x, y); + } + + public void fillText(String s, int x, int y) { + delegate.fillText(s, x, y); + } + + public double getAbsoluteScale() { + return delegate.getAbsoluteScale(); + } + + public int getAntialias() { + return delegate.getAntialias(); + } + + public Rectangle getClip(Rectangle rect) { + return delegate.getClip(rect); + } + + public int getFillRule() { + return delegate.getFillRule(); + } + + public Font getFont() { + return delegate.getFont(); + } + + public FontMetrics getFontMetrics() { + return delegate.getFontMetrics(); + } + + public int getInterpolation() { + return delegate.getInterpolation(); + } + + public int getLineCap() { + return delegate.getLineCap(); + } + + public int getLineJoin() { + return delegate.getLineJoin(); + } + + public int getLineStyle() { + return delegate.getLineStyle(); + } + + public int getLineWidth() { + return delegate.getLineWidth(); + } + + public int getTextAntialias() { + return delegate.getTextAntialias(); + } + + public boolean getXORMode() { + return delegate.getXORMode(); + } + + public void rotate(float degrees) { + delegate.rotate(degrees); + } + + public void scale(double amount) { + delegate.scale(amount); + } + + public void scale(float horizontal, float vertical) { + delegate.scale(horizontal, vertical); + } + + public void setAntialias(int value) { + delegate.setAntialias(value); + } + + public void setClip(Path path) { + delegate.setClip(path); + } + + public void setClip(Rectangle r) { + delegate.setClip(r); + } + + public void setFillRule(int rule) { + delegate.setFillRule(rule); + } + + public void setFont(Font f) { + delegate.setFont(f); + } + + public void setInterpolation(int interpolation) { + delegate.setInterpolation(interpolation); + } + + public void setLineCap(int cap) { + delegate.setLineCap(cap); + } + + public void setLineDash(int[] dash) { + delegate.setLineDash(dash); + } + + public void setLineJoin(int join) { + delegate.setLineJoin(join); + } + + public void setLineStyle(int style) { + delegate.setLineStyle(style); + } + + public void setLineWidth(int width) { + delegate.setLineWidth(width); + } + + public void setTextAntialias(int value) { + delegate.setTextAntialias(value); + } + + public void setXORMode(boolean b) { + delegate.setXORMode(b); + } + + public void shear(float horz, float vert) { + delegate.shear(horz, vert); + } + + public void translate(float dx, float dy) { + delegate.translate(dx, dy); + } + + public void translate(int dx, int dy) { + delegate.translate(dx, dy); + } + + // ========================================================== + // Since 3.5 + // ========================================================== + + public boolean getAdvanced() { + return delegate.getAdvanced(); + } + + public float getLineMiterLimit() { + return delegate.getLineMiterLimit(); + } + + public LineAttributes getLineAttributes() { + return delegate.getLineAttributes(); + } + + public float getLineWidthFloat() { + return delegate.getLineWidthFloat(); + } + + public void setAdvanced(boolean advanced) { + delegate.setAdvanced(advanced); + } + + public void setLineMiterLimit(float miterLimit) { + delegate.setLineMiterLimit(miterLimit); + } + + public void setLineWidthFloat(float width) { + delegate.setLineWidthFloat(width); + } + + public void setLineAttributes(LineAttributes attributes) { + delegate.setLineAttributes(attributes); + } + + public void setLineDash(float[] value) { + delegate.setLineDash(value); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GradientPattern.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GradientPattern.java index 14b70780a..44dfbdaa3 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GradientPattern.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GradientPattern.java @@ -1,63 +1,63 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Pattern; - -/** - * @author Brian Sun - */ -public class GradientPattern extends Pattern { - - public float x1; - public float y1; - public float x2; - public float y2; - public Color color1; - public Color color2; - public int alpha1; - public int alpha2; - - /** - * - * @param device - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @param color1 - * @param alpha1 - * @param color2 - * @param alpha2 - */ - public GradientPattern(Device device, float x1, float y1, float x2, - float y2, Color color1, int alpha1, Color color2, int alpha2) { - super(device, GraphicsUtils.isCarbonSnowLeopard() ? (int) x1 : x1, - GraphicsUtils.isCarbonSnowLeopard() ? (int) y1 : y1, - GraphicsUtils.isCarbonSnowLeopard() ? (int) x2 : x2, - GraphicsUtils.isCarbonSnowLeopard() ? (int) y2 : y2, color1, - alpha1, color2, alpha2); - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - this.color1 = color1; - this.alpha1 = alpha1; - this.color2 = color2; - this.alpha2 = alpha2; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Pattern; + +/** + * @author Brian Sun + */ +public class GradientPattern extends Pattern { + + public float x1; + public float y1; + public float x2; + public float y2; + public Color color1; + public Color color2; + public int alpha1; + public int alpha2; + + /** + * + * @param device + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @param color1 + * @param alpha1 + * @param color2 + * @param alpha2 + */ + public GradientPattern(Device device, float x1, float y1, float x2, + float y2, Color color1, int alpha1, Color color2, int alpha2) { + super(device, GraphicsUtils.isCarbonSnowLeopard() ? (int) x1 : x1, + GraphicsUtils.isCarbonSnowLeopard() ? (int) y1 : y1, + GraphicsUtils.isCarbonSnowLeopard() ? (int) x2 : x2, + GraphicsUtils.isCarbonSnowLeopard() ? (int) y2 : y2, color1, + alpha1, color2, alpha2); + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + this.color1 = color1; + this.alpha1 = alpha1; + this.color2 = color2; + this.alpha2 = alpha2; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GraphicsUtils.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GraphicsUtils.java index 24171b1dc..a7e311aa5 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GraphicsUtils.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GraphicsUtils.java @@ -1,226 +1,226 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Shell; - -/** - * @author Brian Sun - */ -public class GraphicsUtils { - - private static Boolean carbon = null; - - private static boolean isCarbon() { - if (carbon == null) { - carbon = Boolean.valueOf(Util.isCarbon()); - } - return carbon.booleanValue(); - } - - private static Boolean carbonSnowLeopard = null; - - public static boolean isCarbonSnowLeopard() { - if (carbonSnowLeopard == null) { - if (isCarbon()) { - String osVersion = System.getProperty("os.version"); //$NON-NLS-1$ - if (osVersion != null) { - String[] parts = osVersion.split("\\."); //$NON-NLS-1$ - if (isGreater(parts[0], 10)) { - if (parts.length > 1) { - carbonSnowLeopard = Boolean.valueOf(isGreater( - parts[1], 6)); - } - } - } - } - if (carbonSnowLeopard == null) - carbonSnowLeopard = Boolean.FALSE; - } - return carbonSnowLeopard.booleanValue(); - } - - private static boolean isGreater(String str, int value) { - try { - return Integer.parseInt(str) >= value; - } catch (NumberFormatException e) { - } - return false; - } - - public static void fixGradientBugForCarbon(Graphics graphics, IFigure figure) { - fixGradientBugForCarbon(graphics, figure.getBounds()); - } - - public static void fixGradientBugForCarbon(Graphics graphics, - Rectangle bounds) { - if (isCarbon()) { - graphics.pushState(); - graphics.setAlpha(0); - graphics.setBackgroundColor(ColorConstants.white); - graphics.fillRectangle(bounds); - graphics.restoreState(); - graphics.popState(); - } - } - - private static final GraphicsUtils normal = new GraphicsUtils(false); - private static final GraphicsUtils advanced = new GraphicsUtils(true); - - public static GraphicsUtils getNormal() { - return normal; - } - - public static GraphicsUtils getAdvanced() { - return advanced; - } - - private GC gc = null; - private Font appliedFont = null; - private FontMetrics metrics = null; - - protected GraphicsUtils(boolean advanced) { - getGC().setAdvanced(advanced); - } - - public GC getGC() { - if (gc == null) { - gc = new GC(new Shell()); - } - return gc; - } - - protected void setFont(Font f) { - if (appliedFont == f || f.equals(appliedFont)) - return; - getGC().setFont(f); - appliedFont = f; - metrics = null; - } - - /** - * @return the appliedFont - */ - public Font getAppliedFont() { - return appliedFont; - } - - public Dimension getTextSize(String text, Font font) { - setFont(font); - return getTextSize(text); - } - - public Dimension getStringSize(String string, Font font) { - setFont(font); - return getStringSize(string); - } - - /** - * @param text - * @return - */ - public Dimension getTextSize(String text) { - return new Dimension(getGC().textExtent(text)); - } - - /** - * @param string - * @return - */ - public Dimension getStringSize(String string) { - return new Dimension(getGC().stringExtent(string)); - } - - /** - * Returns the FontMetrics associated with the passed Font. - * - * @param f - * the font - * @return the FontMetrics for the given font - * @see GC#getFontMetrics() - */ - public FontMetrics getFontMetrics(Font f) { - setFont(f); - if (metrics == null) - metrics = getGC().getFontMetrics(); - return metrics; - } - - public static final int CENTER = 0; - - public static final int TRAIL = 1; - - public static final int LEAD = 2; - - public static final int PATH = 3; - - public String constrain(String path, int maxWidth, Font font, - int startPositionHint) { - Dimension size = getTextSize(path, font); - if (size.width > maxWidth) { - StringBuffer sb = new StringBuffer(path); - int right; - int left; - int start; - - switch (startPositionHint) { - case PATH: - left = 1; - right = sb.lastIndexOf(".") - 2; //$NON-NLS-1$ - start = right * 5 / 6; - break; - case LEAD: - left = 0; - right = sb.length() - 2; - start = 0; - break; - case TRAIL: - left = 1; - right = sb.length() - 1; - start = Math.max(right, left); - break; - default: - left = 1; - right = sb.length() - 2; - start = right / 2; - } - sb.replace(start, start + 1, "..."); //$NON-NLS-1$ - size = getTextSize(sb.toString()); - boolean down = true; - while (size.width > maxWidth && start <= right && start > left - && right > left) { - if ((down || (right >= 0 && start + 4 > right)) && start > left) { - start--; - } - down = !down; - sb.replace(start, start + 4, "..."); //$NON-NLS-1$ - if (right >= 0) - right--; - size = getTextSize(sb.toString()); - } - path = sb.toString(); - } - return path; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Shell; + +/** + * @author Brian Sun + */ +public class GraphicsUtils { + + private static Boolean carbon = null; + + private static boolean isCarbon() { + if (carbon == null) { + carbon = Boolean.valueOf(Util.isCarbon()); + } + return carbon.booleanValue(); + } + + private static Boolean carbonSnowLeopard = null; + + public static boolean isCarbonSnowLeopard() { + if (carbonSnowLeopard == null) { + if (isCarbon()) { + String osVersion = System.getProperty("os.version"); //$NON-NLS-1$ + if (osVersion != null) { + String[] parts = osVersion.split("\\."); //$NON-NLS-1$ + if (isGreater(parts[0], 10)) { + if (parts.length > 1) { + carbonSnowLeopard = Boolean.valueOf(isGreater( + parts[1], 6)); + } + } + } + } + if (carbonSnowLeopard == null) + carbonSnowLeopard = Boolean.FALSE; + } + return carbonSnowLeopard.booleanValue(); + } + + private static boolean isGreater(String str, int value) { + try { + return Integer.parseInt(str) >= value; + } catch (NumberFormatException e) { + } + return false; + } + + public static void fixGradientBugForCarbon(Graphics graphics, IFigure figure) { + fixGradientBugForCarbon(graphics, figure.getBounds()); + } + + public static void fixGradientBugForCarbon(Graphics graphics, + Rectangle bounds) { + if (isCarbon()) { + graphics.pushState(); + graphics.setAlpha(0); + graphics.setBackgroundColor(ColorConstants.white); + graphics.fillRectangle(bounds); + graphics.restoreState(); + graphics.popState(); + } + } + + private static final GraphicsUtils normal = new GraphicsUtils(false); + private static final GraphicsUtils advanced = new GraphicsUtils(true); + + public static GraphicsUtils getNormal() { + return normal; + } + + public static GraphicsUtils getAdvanced() { + return advanced; + } + + private GC gc = null; + private Font appliedFont = null; + private FontMetrics metrics = null; + + protected GraphicsUtils(boolean advanced) { + getGC().setAdvanced(advanced); + } + + public GC getGC() { + if (gc == null) { + gc = new GC(new Shell()); + } + return gc; + } + + protected void setFont(Font f) { + if (appliedFont == f || f.equals(appliedFont)) + return; + getGC().setFont(f); + appliedFont = f; + metrics = null; + } + + /** + * @return the appliedFont + */ + public Font getAppliedFont() { + return appliedFont; + } + + public Dimension getTextSize(String text, Font font) { + setFont(font); + return getTextSize(text); + } + + public Dimension getStringSize(String string, Font font) { + setFont(font); + return getStringSize(string); + } + + /** + * @param text + * @return + */ + public Dimension getTextSize(String text) { + return new Dimension(getGC().textExtent(text)); + } + + /** + * @param string + * @return + */ + public Dimension getStringSize(String string) { + return new Dimension(getGC().stringExtent(string)); + } + + /** + * Returns the FontMetrics associated with the passed Font. + * + * @param f + * the font + * @return the FontMetrics for the given font + * @see GC#getFontMetrics() + */ + public FontMetrics getFontMetrics(Font f) { + setFont(f); + if (metrics == null) + metrics = getGC().getFontMetrics(); + return metrics; + } + + public static final int CENTER = 0; + + public static final int TRAIL = 1; + + public static final int LEAD = 2; + + public static final int PATH = 3; + + public String constrain(String path, int maxWidth, Font font, + int startPositionHint) { + Dimension size = getTextSize(path, font); + if (size.width > maxWidth) { + StringBuffer sb = new StringBuffer(path); + int right; + int left; + int start; + + switch (startPositionHint) { + case PATH: + left = 1; + right = sb.lastIndexOf(".") - 2; //$NON-NLS-1$ + start = right * 5 / 6; + break; + case LEAD: + left = 0; + right = sb.length() - 2; + start = 0; + break; + case TRAIL: + left = 1; + right = sb.length() - 1; + start = Math.max(right, left); + break; + default: + left = 1; + right = sb.length() - 2; + start = right / 2; + } + sb.replace(start, start + 1, "..."); //$NON-NLS-1$ + size = getTextSize(sb.toString()); + boolean down = true; + while (size.width > maxWidth && start <= right && start > left + && right > left) { + if ((down || (right >= 0 && start + 4 > right)) && start > left) { + start--; + } + down = !down; + sb.replace(start, start + 4, "..."); //$NON-NLS-1$ + if (right >= 0) + right--; + size = getTextSize(sb.toString()); + } + path = sb.toString(); + } + return path; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GrayedGraphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GrayedGraphics.java index f5d278fbd..91f15b40f 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GrayedGraphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/GrayedGraphics.java @@ -1,35 +1,35 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.swt.graphics.RGB; - -public class GrayedGraphics extends ColorMaskGraphics { - - public GrayedGraphics(Graphics delegate) { - super(delegate); - } - - protected RGB getMaskColor(RGB rgb) { - int l = lightness(rgb.red, rgb.green, rgb.blue); - l += (0xff - l) / 2; - return new RGB(l, l, l); - } - - private static int lightness(int r, int g, int b) { - return (int) (r * 0.3 + g * 0.59 + b * 0.11); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.swt.graphics.RGB; + +public class GrayedGraphics extends ColorMaskGraphics { + + public GrayedGraphics(Graphics delegate) { + super(delegate); + } + + protected RGB getMaskColor(RGB rgb) { + int l = lightness(rgb.red, rgb.green, rgb.blue); + l += (0xff - l) / 2; + return new RGB(l, l, l); + } + + private static int lightness(int r, int g, int b) { + return (int) (r * 0.3 + g * 0.59 + b * 0.11); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Path.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Path.java index b106c13b3..b715f6a41 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Path.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Path.java @@ -1,264 +1,264 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.PathData; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; - -public class Path extends org.eclipse.swt.graphics.Path { - - /** - * @param device - */ - public Path(Device device) { - super(device); - } - - public Path(Device device, PathData data) { - super(device, data); - } - - /** - * @see org.eclipse.swt.graphics.Path#moveTo(float, float) - */ - public void moveTo(PrecisionPoint p) { - super.moveTo((float) p.x, (float) p.y); - } - - public void moveTo(Point p) { - super.moveTo(p.x, p.y); - } - - /** - * @see org.eclipse.swt.graphics.Path#lineTo(float, float) - */ - public void lineTo(PrecisionPoint p) { - super.lineTo((float) p.x, (float) p.y); - } - - public void lineTo(Point p) { - super.lineTo(p.x, p.y); - } - - /** - * @see org.eclipse.swt.graphics.Path#cubicTo(float, float, float, float, - * float, float) - */ - public void cubicTo(PrecisionPoint control1, PrecisionPoint control2, - PrecisionPoint dest) { - super.cubicTo((float) control1.x, (float) control1.y, - (float) control2.x, (float) control2.y, (float) dest.x, - (float) dest.y); - } - - public void cubicTo(Point control1, Point control2, Point dest) { - super.cubicTo(control1.x, control1.y, control2.x, control2.y, dest.x, - dest.y); - } - - /** - * @see org.eclipse.swt.graphics.Path#quadTo(float, float, float, float) - */ - public void quadTo(PrecisionPoint control, PrecisionPoint dest) { - super.quadTo((float) control.x, (float) control.y, (float) dest.x, - (float) dest.y); - } - - public void quadTo(Point control, Point dest) { - super.quadTo(control.x, control.y, dest.x, dest.y); - } - - public void addArc(PrecisionRectangle bounds, float startAngle, - float arcAngle) { - super.addArc((float) bounds.x, (float) bounds.y, (float) bounds.width, - (float) bounds.height, startAngle, arcAngle); - } - - public void addArc(Rectangle bounds, float startAngle, float arcAngle) { - super.addArc(bounds.x, bounds.y, bounds.width, bounds.height, - startAngle, arcAngle); - } - - public void addRectangle(PrecisionRectangle bounds) { - super.addRectangle((float) bounds.x, (float) bounds.y, - (float) bounds.width, (float) bounds.height); - } - - public void addRectangle(Rectangle bounds) { - super.addRectangle(bounds.x, bounds.y, bounds.width, bounds.height); - } - - public void addRoundedRectangle(Rectangle bounds, float corner) { - addRoundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, - corner); - } - - public void addRoundedRectangleByRatio(Rectangle bounds, - float cornerRatio) { - addRoundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, - Math.min(bounds.width, bounds.height) * cornerRatio); - } - - public void addRoundedRectangle(PrecisionRectangle bounds, float corner) { - addRoundedRectangle((float) bounds.x, (float) bounds.y, - (float) bounds.width, (float) bounds.height, corner); - } - - private static final float CORNER_CONTROL_RATIO = 0.447715f; - - public void addRoundedRectangle(float x, float y, float width, float height, - float corner) { - float r = x + width; - float b = y + height; - float x0 = x + width / 2; - float y0 = y + height / 2; - - float x1 = Math.min(x + corner, x0); - moveTo(x1, y); - - float y1 = Math.min(y + corner, y0); - float cx1 = x + (x1 - x) * CORNER_CONTROL_RATIO; - float cy1 = y + (y1 - y) * CORNER_CONTROL_RATIO; - cubicTo(cx1, y, x, cy1, x, y1); - - float y2 = Math.max(b - corner, y0); - lineTo(x, y2); - - float cy2 = b - (b - y2) * CORNER_CONTROL_RATIO; - cubicTo(x, cy2, cx1, b, x1, b); - - float x2 = Math.max(r - corner, x0); - lineTo(x2, b); - - float cx2 = r - (r - x2) * CORNER_CONTROL_RATIO; - cubicTo(cx2, b, r, cy2, r, y2); - - lineTo(r, y1); - - cubicTo(r, cy1, cx2, y, x2, y); - -// float y1 = Math.min(y + corner, y0); -// moveTo(x, y1); - -// float x1 = Math.min(x + corner, x0); -// float cx1 = x + (x1 - x) * CORNER_CONTROL_RATIO; -// float cy1 = y + (y1 - y) * CORNER_CONTROL_RATIO; -// cubicTo(x, cy1, cx1, y, x1, y); -// -// float x2 = Math.max(r - corner, x0); -// lineTo(x2, y); -// -// float cx2 = r - (r - x2) * CORNER_CONTROL_RATIO; -// cubicTo(cx2, y, r, cy1, r, y1); -// -// float y2 = Math.max(b - corner, y0); -// lineTo(r, y2); -// -// float cy2 = b - (b - y2) * CORNER_CONTROL_RATIO; -// cubicTo(r, cy2, cx2, b, x2, b); -// -// lineTo(x1, b); -// -// cubicTo(cx1, b, x, cy2, x, y2); - - close(); - } - - public void addRoundedPolygon(float corner, PrecisionPoint... points) { - if (points == null || points.length < 3) - return; - float[] locs = new float[points.length * 2]; - for (int i = 0; i < points.length; i++) { - PrecisionPoint p = points[i]; - locs[i * 2] = (float) p.x; - locs[i * 2 + 1] = (float) p.y; - } - addRoundedPolygon(corner, locs); - } - - public void addRoundedPolygon(float corner, float... locs) { - if (locs == null || locs.length < 6) - return; - float qc = corner / 4; - int len = locs.length; - float[] last = null; - for (int i = 0; i < len - 1; i += 2) { - float x1 = locs[i]; - float y1 = locs[i + 1]; - float x2 = i < len - 2 ? locs[i + 2] : locs[i - len + 2]; - float y2 = i < len - 2 ? locs[i + 3] : locs[i - len + 3]; - float x3 = i < len - 4 ? locs[i + 4] : locs[i - len + 4]; - float y3 = i < len - 4 ? locs[i + 5] : locs[i - len + 5]; - if (last == null) { - last = calcPoint(x1, y1, x2, y2, corner); - moveTo(last[0], last[1]); - } - float[] p1 = calcPoint(x2, y2, x1, y1, corner); - lineTo(p1[0], p1[1]); - float[] c1 = calcPoint(x2, y2, x1, y1, qc); - float[] c2 = calcPoint(x2, y2, x3, y3, qc); - float[] p2 = calcPoint(x2, y2, x3, y3, corner); - cubicTo(c1[0], c1[1], c2[0], c2[1], p2[0], p2[1]); - last = p2; - } - close(); - } - - private float[] calcPoint(float x1, float y1, float x2, float y2, - float dist) { - float x; - float y; - if (x1 == x2) { - x = x1; - if (y1 == y2) { - y = y1; - } else { - y = y1 + dist; - } - } else { - if (y1 == y2) { - y = y1; - x = x1 + dist; - } else { - float d = (x2 - x1) / (y2 - y1); - float r = (float) (dist / Math.sqrt(d * d + 1)); - if (y2 < y1) - r = -r; - y = r + y1; - x = (y - y1) * d + x1; - } - } - return new float[] { x, y }; - } - - public void addString(String text, PrecisionPoint loc, Font font) { - super.addString(text, (float) loc.x, (float) loc.y, font); - } - - public void addString(String text, Point loc, Font font) { - super.addString(text, loc.x, loc.y, font); - } - - public PrecisionPoint getCurrentPoint() { - float[] current = new float[2]; - getCurrentPoint(current); - return new PrecisionPoint(current[0], current[1]); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.PathData; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; + +public class Path extends org.eclipse.swt.graphics.Path { + + /** + * @param device + */ + public Path(Device device) { + super(device); + } + + public Path(Device device, PathData data) { + super(device, data); + } + + /** + * @see org.eclipse.swt.graphics.Path#moveTo(float, float) + */ + public void moveTo(PrecisionPoint p) { + super.moveTo((float) p.x, (float) p.y); + } + + public void moveTo(Point p) { + super.moveTo(p.x, p.y); + } + + /** + * @see org.eclipse.swt.graphics.Path#lineTo(float, float) + */ + public void lineTo(PrecisionPoint p) { + super.lineTo((float) p.x, (float) p.y); + } + + public void lineTo(Point p) { + super.lineTo(p.x, p.y); + } + + /** + * @see org.eclipse.swt.graphics.Path#cubicTo(float, float, float, float, + * float, float) + */ + public void cubicTo(PrecisionPoint control1, PrecisionPoint control2, + PrecisionPoint dest) { + super.cubicTo((float) control1.x, (float) control1.y, + (float) control2.x, (float) control2.y, (float) dest.x, + (float) dest.y); + } + + public void cubicTo(Point control1, Point control2, Point dest) { + super.cubicTo(control1.x, control1.y, control2.x, control2.y, dest.x, + dest.y); + } + + /** + * @see org.eclipse.swt.graphics.Path#quadTo(float, float, float, float) + */ + public void quadTo(PrecisionPoint control, PrecisionPoint dest) { + super.quadTo((float) control.x, (float) control.y, (float) dest.x, + (float) dest.y); + } + + public void quadTo(Point control, Point dest) { + super.quadTo(control.x, control.y, dest.x, dest.y); + } + + public void addArc(PrecisionRectangle bounds, float startAngle, + float arcAngle) { + super.addArc((float) bounds.x, (float) bounds.y, (float) bounds.width, + (float) bounds.height, startAngle, arcAngle); + } + + public void addArc(Rectangle bounds, float startAngle, float arcAngle) { + super.addArc(bounds.x, bounds.y, bounds.width, bounds.height, + startAngle, arcAngle); + } + + public void addRectangle(PrecisionRectangle bounds) { + super.addRectangle((float) bounds.x, (float) bounds.y, + (float) bounds.width, (float) bounds.height); + } + + public void addRectangle(Rectangle bounds) { + super.addRectangle(bounds.x, bounds.y, bounds.width, bounds.height); + } + + public void addRoundedRectangle(Rectangle bounds, float corner) { + addRoundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, + corner); + } + + public void addRoundedRectangleByRatio(Rectangle bounds, + float cornerRatio) { + addRoundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, + Math.min(bounds.width, bounds.height) * cornerRatio); + } + + public void addRoundedRectangle(PrecisionRectangle bounds, float corner) { + addRoundedRectangle((float) bounds.x, (float) bounds.y, + (float) bounds.width, (float) bounds.height, corner); + } + + private static final float CORNER_CONTROL_RATIO = 0.447715f; + + public void addRoundedRectangle(float x, float y, float width, float height, + float corner) { + float r = x + width; + float b = y + height; + float x0 = x + width / 2; + float y0 = y + height / 2; + + float x1 = Math.min(x + corner, x0); + moveTo(x1, y); + + float y1 = Math.min(y + corner, y0); + float cx1 = x + (x1 - x) * CORNER_CONTROL_RATIO; + float cy1 = y + (y1 - y) * CORNER_CONTROL_RATIO; + cubicTo(cx1, y, x, cy1, x, y1); + + float y2 = Math.max(b - corner, y0); + lineTo(x, y2); + + float cy2 = b - (b - y2) * CORNER_CONTROL_RATIO; + cubicTo(x, cy2, cx1, b, x1, b); + + float x2 = Math.max(r - corner, x0); + lineTo(x2, b); + + float cx2 = r - (r - x2) * CORNER_CONTROL_RATIO; + cubicTo(cx2, b, r, cy2, r, y2); + + lineTo(r, y1); + + cubicTo(r, cy1, cx2, y, x2, y); + +// float y1 = Math.min(y + corner, y0); +// moveTo(x, y1); + +// float x1 = Math.min(x + corner, x0); +// float cx1 = x + (x1 - x) * CORNER_CONTROL_RATIO; +// float cy1 = y + (y1 - y) * CORNER_CONTROL_RATIO; +// cubicTo(x, cy1, cx1, y, x1, y); +// +// float x2 = Math.max(r - corner, x0); +// lineTo(x2, y); +// +// float cx2 = r - (r - x2) * CORNER_CONTROL_RATIO; +// cubicTo(cx2, y, r, cy1, r, y1); +// +// float y2 = Math.max(b - corner, y0); +// lineTo(r, y2); +// +// float cy2 = b - (b - y2) * CORNER_CONTROL_RATIO; +// cubicTo(r, cy2, cx2, b, x2, b); +// +// lineTo(x1, b); +// +// cubicTo(cx1, b, x, cy2, x, y2); + + close(); + } + + public void addRoundedPolygon(float corner, PrecisionPoint... points) { + if (points == null || points.length < 3) + return; + float[] locs = new float[points.length * 2]; + for (int i = 0; i < points.length; i++) { + PrecisionPoint p = points[i]; + locs[i * 2] = (float) p.x; + locs[i * 2 + 1] = (float) p.y; + } + addRoundedPolygon(corner, locs); + } + + public void addRoundedPolygon(float corner, float... locs) { + if (locs == null || locs.length < 6) + return; + float qc = corner / 4; + int len = locs.length; + float[] last = null; + for (int i = 0; i < len - 1; i += 2) { + float x1 = locs[i]; + float y1 = locs[i + 1]; + float x2 = i < len - 2 ? locs[i + 2] : locs[i - len + 2]; + float y2 = i < len - 2 ? locs[i + 3] : locs[i - len + 3]; + float x3 = i < len - 4 ? locs[i + 4] : locs[i - len + 4]; + float y3 = i < len - 4 ? locs[i + 5] : locs[i - len + 5]; + if (last == null) { + last = calcPoint(x1, y1, x2, y2, corner); + moveTo(last[0], last[1]); + } + float[] p1 = calcPoint(x2, y2, x1, y1, corner); + lineTo(p1[0], p1[1]); + float[] c1 = calcPoint(x2, y2, x1, y1, qc); + float[] c2 = calcPoint(x2, y2, x3, y3, qc); + float[] p2 = calcPoint(x2, y2, x3, y3, corner); + cubicTo(c1[0], c1[1], c2[0], c2[1], p2[0], p2[1]); + last = p2; + } + close(); + } + + private float[] calcPoint(float x1, float y1, float x2, float y2, + float dist) { + float x; + float y; + if (x1 == x2) { + x = x1; + if (y1 == y2) { + y = y1; + } else { + y = y1 + dist; + } + } else { + if (y1 == y2) { + y = y1; + x = x1 + dist; + } else { + float d = (x2 - x1) / (y2 - y1); + float r = (float) (dist / Math.sqrt(d * d + 1)); + if (y2 < y1) + r = -r; + y = r + y1; + x = (y - y1) * d + x1; + } + } + return new float[] { x, y }; + } + + public void addString(String text, PrecisionPoint loc, Font font) { + super.addString(text, (float) loc.x, (float) loc.y, font); + } + + public void addString(String text, Point loc, Font font) { + super.addString(text, loc.x, loc.y, font); + } + + public PrecisionPoint getCurrentPoint() { + float[] current = new float[2]; + getCurrentPoint(current); + return new PrecisionPoint(current[0], current[1]); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Rotate90Graphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Rotate90Graphics.java index d960bc1c6..654208bf1 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Rotate90Graphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/Rotate90Graphics.java @@ -1,668 +1,668 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.LineAttributes; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.PathData; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.TextLayout; - -/** - * Rotate the coordinate 90 degrees clockwise. - * - * @author frankshaka - */ -public class Rotate90Graphics extends Graphics { - - private Graphics graphics; - - private Pattern lastBgPattern = null; - - private Pattern lastFgPattern = null; - - public Rotate90Graphics(Graphics realGraphics) { - this.graphics = realGraphics; - } - - protected Graphics getGraphics() { - return graphics; - } - - protected float[] rotate(float x, float y) { - return new float[] { -y, x }; - } - - protected int[] rotate(int x, int y) { - return new int[] { -y, x }; - } - - protected Rectangle rotate(Rectangle r) { - return new Rectangle(-r.y - r.height, r.x, r.height, r.width); - } - - protected Point rotate(Point p) { - return new Point(-p.y, p.x); - } - - protected Path rotate(Path path) { - PathData data = path.getPathData(); - Path newPath = new Path(path.getDevice()); - int index = 0; - float[] points = data.points; - float x, y, cx1, cy1, cx2, cy2; - for (byte type : data.types) { - switch (type) { - case SWT.PATH_MOVE_TO: - x = points[index++]; - y = points[index++]; - newPath.moveTo(-y, x); - break; - case SWT.PATH_LINE_TO: - x = points[index++]; - y = points[index++]; - newPath.lineTo(-y, x); - break; - case SWT.PATH_CUBIC_TO: - x = points[index++]; - y = points[index++]; - cx1 = points[index++]; - cy1 = points[index++]; - cx2 = points[index++]; - cy2 = points[index++]; - newPath.cubicTo(-y, x, -cy1, cx1, -cy2, cx2); - break; - case SWT.PATH_QUAD_TO: - x = points[index++]; - y = points[index++]; - cx1 = points[index++]; - cy1 = points[index++]; - newPath.quadTo(-y, x, -cy1, cx1); - break; - case SWT.PATH_CLOSE: - newPath.close(); - break; - } - } - return newPath; - } - - protected int[] rotate(int[] points) { - int[] newPoints = new int[points.length]; - for (int i = 0; i < points.length; i += 2) { - newPoints[i] = -points[i + 1]; - newPoints[i + 1] = points[i]; - } - return newPoints; - } - - protected PointList rotate(PointList points) { - int size = points.size(); - PointList newPoints = new PointList(size); - for (int i = 0; i < size; i++) { - Point p = points.getPoint(i); - newPoints.setPoint(rotate(p), i); - } - return newPoints; - } - - private Pattern rotate(GradientPattern p) { - GradientPattern p2 = new GradientPattern(p.getDevice(), // - -p.y1, p.x1, // - -p.y2, p.x2, // - p.color1, p.alpha1, // - p.color2, p.alpha2); - return p2; - } - - private Pattern rotate(ImagePattern p) { - ImagePattern p2 = new ImagePattern(p.getDevice(), rotate(p.image)); - return p2; - } - - private Image rotate(Image image) { - - return image; - } - - public void clipRect(Rectangle r) { - graphics.clipRect(rotate(r)); - } - - public void clipPath(Path path) { - Path p2 = rotate((Path) path); - graphics.clipPath(p2); - p2.dispose(); - } - - public void dispose() { - if (lastBgPattern != null) { - lastBgPattern.dispose(); - lastBgPattern = null; - } - if (lastFgPattern != null) { - lastFgPattern.dispose(); - lastFgPattern = null; - } - } - - public void drawArc(int x, int y, int w, int h, int offset, int length) { - graphics.drawArc(-y - h, x, h, w, offset, length); - } - - public void drawFocus(int x, int y, int w, int h) { - graphics.drawFocus(-y - h, x, h, w); - } - - public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void drawImage(Image srcImage, int x, int y) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawImage(srcImage, x, y); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void drawLine(int x1, int y1, int x2, int y2) { - graphics.drawLine(-y1, x1, -y2, x2); - } - - public void drawOval(int x, int y, int w, int h) { - graphics.drawOval(-y - h, x, h, w); - } - - public void drawPath(Path path) { - Path p2 = rotate((Path) path); - graphics.drawPath(p2); - p2.dispose(); - } - - public void drawPoint(int x, int y) { - graphics.drawPoint(-y, x); - } - - public void drawPolygon(int[] points) { - graphics.drawPolygon(rotate(points)); - } - - public void drawPolygon(PointList points) { - graphics.drawPolygon(rotate(points)); - } - - public void drawPolyline(int[] points) { - graphics.drawPolyline(rotate(points)); - } - - public void drawPolyline(PointList points) { - graphics.drawPolyline(rotate(points)); - } - - public void drawRectangle(int x, int y, int width, int height) { - graphics.drawRectangle(-y - height, x, height, width); - } - - public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - graphics.drawRoundRectangle(rotate(r), arcHeight, arcWidth); - } - - public void drawString(String s, int x, int y) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawString(s, x, y); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void drawText(String s, int x, int y, int style) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawText(s, x, y, style); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void drawText(String s, int x, int y) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawText(s, x, y); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void drawTextLayout(TextLayout layout, int x, int y, - int selectionStart, int selectionEnd, Color selectionForeground, - Color selectionBackground) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.drawTextLayout(layout, x, y, selectionStart, selectionEnd, - selectionForeground, selectionBackground); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void fillArc(int x, int y, int w, int h, int offset, int length) { - graphics.fillArc(-y - h, x, h, w, offset, length); - } - - public void fillGradient(int x, int y, int w, int h, boolean vertical) { - graphics.fillGradient(-y - h, x, h, w, !vertical); - } - - public void fillOval(int x, int y, int w, int h) { - graphics.fillOval(-y - h, x, h, w); - } - - public void fillPath(Path path) { - Path p2 = rotate((Path) path); - graphics.fillPath(p2); - p2.dispose(); - } - - public void fillPolygon(int[] points) { - graphics.fillPolygon(rotate(points)); - } - - public void fillPolygon(PointList points) { - graphics.fillPolygon(rotate(points)); - } - - public void fillRectangle(int x, int y, int width, int height) { - graphics.fillRectangle(-y - height, x, height, width); - } - - public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - graphics.fillRoundRectangle(rotate(r), arcHeight, arcWidth); - } - - public void fillString(String s, int x, int y) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.fillString(s, x, y); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public void fillText(String s, int x, int y) { - boolean statePushed = false; - try { - graphics.pushState(); - statePushed = true; - } catch (Throwable t) { - statePushed = false; - } - graphics.rotate(90); - graphics.fillText(s, x, y); - graphics.rotate(-90); - if (statePushed) { - try { - graphics.restoreState(); - graphics.popState(); - } catch (Throwable t) { - } - } - } - - public double getAbsoluteScale() { - return graphics.getAbsoluteScale(); - } - - public int getAlpha() { - return graphics.getAlpha(); - } - - public int getAntialias() { - return graphics.getAntialias(); - } - - public Color getBackgroundColor() { - return graphics.getBackgroundColor(); - } - - public Rectangle getClip(Rectangle rect) { - rect = graphics.getClip(rect); - int rx = rect.y; - int ry = -rect.x - rect.width; - int rw = rect.height; - int rh = rect.width; - rect.x = rx; - rect.y = ry; - rect.width = rw; - rect.height = rh; - return rect; - } - - public int getFillRule() { - return graphics.getFillRule(); - } - - public Font getFont() { - return graphics.getFont(); - } - - public FontMetrics getFontMetrics() { - return graphics.getFontMetrics(); - } - - public Color getForegroundColor() { - return graphics.getForegroundColor(); - } - - public int getInterpolation() { - return graphics.getInterpolation(); - } - - public int getLineCap() { - return graphics.getLineCap(); - } - - public int getLineJoin() { - return graphics.getLineJoin(); - } - - public int getLineStyle() { - return graphics.getLineStyle(); - } - - public int getLineWidth() { - return graphics.getLineWidth(); - } - - public int getTextAntialias() { - return graphics.getTextAntialias(); - } - - public boolean getXORMode() { - return graphics.getXORMode(); - } - - public void popState() { - graphics.popState(); - } - - public void pushState() { - graphics.pushState(); - } - - public void restoreState() { - graphics.restoreState(); - } - - public void rotate(float degrees) { - graphics.rotate(degrees); - } - - public void scale(double amount) { - graphics.scale(amount); - } - - public void scale(float horizontal, float vertical) { - graphics.scale(horizontal, vertical); - } - - public void setAlpha(int alpha) { - graphics.setAlpha(alpha); - } - - public void setAntialias(int value) { - graphics.setAntialias(value); - } - - public void setBackgroundColor(Color rgb) { - graphics.setBackgroundColor(rgb); - } - - public void setBackgroundPattern(Pattern pattern) { - if (lastBgPattern != null) { - lastBgPattern.dispose(); - lastBgPattern = null; - } - if (pattern instanceof GradientPattern) { - Pattern p = rotate((GradientPattern) pattern); - graphics.setBackgroundPattern(p); - lastBgPattern = p; - } else if (pattern instanceof ImagePattern) { - Pattern p = rotate((ImagePattern) pattern); - graphics.setBackgroundPattern(p); - lastBgPattern = p; - } else { - graphics.setBackgroundPattern(pattern); - } - } - - public void setClip(Path path) { - Path p2 = rotate((Path) path); - graphics.setClip(p2); - p2.dispose(); - } - - public void setClip(Rectangle r) { - graphics.setClip(rotate(r)); - } - - public void setFillRule(int rule) { - graphics.setFillRule(rule); - } - - public void setFont(Font f) { - graphics.setFont(f); - } - - public void setForegroundColor(Color rgb) { - graphics.setForegroundColor(rgb); - } - - public void setForegroundPattern(Pattern pattern) { - if (lastFgPattern != null) { - lastFgPattern.dispose(); - lastFgPattern = null; - } - if (pattern instanceof GradientPattern) { - Pattern p = rotate((GradientPattern) pattern); - graphics.setForegroundPattern(p); - lastFgPattern = p; - } else if (pattern instanceof ImagePattern) { - Pattern p = rotate((ImagePattern) pattern); - graphics.setForegroundPattern(p); - lastFgPattern = p; - } else { - graphics.setForegroundPattern(pattern); - } - } - - public void setInterpolation(int interpolation) { - graphics.setInterpolation(interpolation); - } - - public void setLineCap(int cap) { - graphics.setLineCap(cap); - } - - public void setLineDash(int[] dash) { - graphics.setLineDash(dash); - } - - public void setLineJoin(int join) { - graphics.setLineJoin(join); - } - - public void setLineStyle(int style) { - graphics.setLineStyle(style); - } - - public void setLineWidth(int width) { - graphics.setLineWidth(width); - } - - public void setTextAntialias(int value) { - graphics.setTextAntialias(value); - } - - public void setXORMode(boolean b) { - graphics.setXORMode(b); - } - - public void shear(float horz, float vert) { - graphics.shear(horz, vert); - } - - public void translate(float dx, float dy) { - graphics.translate(-dy, dx); - } - - public void translate(int dx, int dy) { - graphics.translate(-dy, dx); - } - - // ========================================================== - // Since 3.5 - // ========================================================== - - public boolean getAdvanced() { - return graphics.getAdvanced(); - } - - public float getLineWidthFloat() { - return graphics.getLineWidthFloat(); - } - - public LineAttributes getLineAttributes() { - return graphics.getLineAttributes(); - } - - public float getLineMiterLimit() { - return graphics.getLineMiterLimit(); - } - - public void setAdvanced(boolean advanced) { - graphics.setAdvanced(advanced); - } - - public void setLineMiterLimit(float miterLimit) { - graphics.setLineMiterLimit(miterLimit); - } - - public void setLineWidthFloat(float width) { - graphics.setLineWidthFloat(width); - } - - public void setLineAttributes(LineAttributes attributes) { - graphics.setLineAttributes(attributes); - } - - public void setLineDash(float[] value) { - graphics.setLineDash(value); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.LineAttributes; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.PathData; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.TextLayout; + +/** + * Rotate the coordinate 90 degrees clockwise. + * + * @author frankshaka + */ +public class Rotate90Graphics extends Graphics { + + private Graphics graphics; + + private Pattern lastBgPattern = null; + + private Pattern lastFgPattern = null; + + public Rotate90Graphics(Graphics realGraphics) { + this.graphics = realGraphics; + } + + protected Graphics getGraphics() { + return graphics; + } + + protected float[] rotate(float x, float y) { + return new float[] { -y, x }; + } + + protected int[] rotate(int x, int y) { + return new int[] { -y, x }; + } + + protected Rectangle rotate(Rectangle r) { + return new Rectangle(-r.y - r.height, r.x, r.height, r.width); + } + + protected Point rotate(Point p) { + return new Point(-p.y, p.x); + } + + protected Path rotate(Path path) { + PathData data = path.getPathData(); + Path newPath = new Path(path.getDevice()); + int index = 0; + float[] points = data.points; + float x, y, cx1, cy1, cx2, cy2; + for (byte type : data.types) { + switch (type) { + case SWT.PATH_MOVE_TO: + x = points[index++]; + y = points[index++]; + newPath.moveTo(-y, x); + break; + case SWT.PATH_LINE_TO: + x = points[index++]; + y = points[index++]; + newPath.lineTo(-y, x); + break; + case SWT.PATH_CUBIC_TO: + x = points[index++]; + y = points[index++]; + cx1 = points[index++]; + cy1 = points[index++]; + cx2 = points[index++]; + cy2 = points[index++]; + newPath.cubicTo(-y, x, -cy1, cx1, -cy2, cx2); + break; + case SWT.PATH_QUAD_TO: + x = points[index++]; + y = points[index++]; + cx1 = points[index++]; + cy1 = points[index++]; + newPath.quadTo(-y, x, -cy1, cx1); + break; + case SWT.PATH_CLOSE: + newPath.close(); + break; + } + } + return newPath; + } + + protected int[] rotate(int[] points) { + int[] newPoints = new int[points.length]; + for (int i = 0; i < points.length; i += 2) { + newPoints[i] = -points[i + 1]; + newPoints[i + 1] = points[i]; + } + return newPoints; + } + + protected PointList rotate(PointList points) { + int size = points.size(); + PointList newPoints = new PointList(size); + for (int i = 0; i < size; i++) { + Point p = points.getPoint(i); + newPoints.setPoint(rotate(p), i); + } + return newPoints; + } + + private Pattern rotate(GradientPattern p) { + GradientPattern p2 = new GradientPattern(p.getDevice(), // + -p.y1, p.x1, // + -p.y2, p.x2, // + p.color1, p.alpha1, // + p.color2, p.alpha2); + return p2; + } + + private Pattern rotate(ImagePattern p) { + ImagePattern p2 = new ImagePattern(p.getDevice(), rotate(p.image)); + return p2; + } + + private Image rotate(Image image) { + + return image; + } + + public void clipRect(Rectangle r) { + graphics.clipRect(rotate(r)); + } + + public void clipPath(Path path) { + Path p2 = rotate((Path) path); + graphics.clipPath(p2); + p2.dispose(); + } + + public void dispose() { + if (lastBgPattern != null) { + lastBgPattern.dispose(); + lastBgPattern = null; + } + if (lastFgPattern != null) { + lastFgPattern.dispose(); + lastFgPattern = null; + } + } + + public void drawArc(int x, int y, int w, int h, int offset, int length) { + graphics.drawArc(-y - h, x, h, w, offset, length); + } + + public void drawFocus(int x, int y, int w, int h) { + graphics.drawFocus(-y - h, x, h, w); + } + + public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void drawImage(Image srcImage, int x, int y) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawImage(srcImage, x, y); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void drawLine(int x1, int y1, int x2, int y2) { + graphics.drawLine(-y1, x1, -y2, x2); + } + + public void drawOval(int x, int y, int w, int h) { + graphics.drawOval(-y - h, x, h, w); + } + + public void drawPath(Path path) { + Path p2 = rotate((Path) path); + graphics.drawPath(p2); + p2.dispose(); + } + + public void drawPoint(int x, int y) { + graphics.drawPoint(-y, x); + } + + public void drawPolygon(int[] points) { + graphics.drawPolygon(rotate(points)); + } + + public void drawPolygon(PointList points) { + graphics.drawPolygon(rotate(points)); + } + + public void drawPolyline(int[] points) { + graphics.drawPolyline(rotate(points)); + } + + public void drawPolyline(PointList points) { + graphics.drawPolyline(rotate(points)); + } + + public void drawRectangle(int x, int y, int width, int height) { + graphics.drawRectangle(-y - height, x, height, width); + } + + public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + graphics.drawRoundRectangle(rotate(r), arcHeight, arcWidth); + } + + public void drawString(String s, int x, int y) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawString(s, x, y); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void drawText(String s, int x, int y, int style) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawText(s, x, y, style); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void drawText(String s, int x, int y) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawText(s, x, y); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void drawTextLayout(TextLayout layout, int x, int y, + int selectionStart, int selectionEnd, Color selectionForeground, + Color selectionBackground) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.drawTextLayout(layout, x, y, selectionStart, selectionEnd, + selectionForeground, selectionBackground); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void fillArc(int x, int y, int w, int h, int offset, int length) { + graphics.fillArc(-y - h, x, h, w, offset, length); + } + + public void fillGradient(int x, int y, int w, int h, boolean vertical) { + graphics.fillGradient(-y - h, x, h, w, !vertical); + } + + public void fillOval(int x, int y, int w, int h) { + graphics.fillOval(-y - h, x, h, w); + } + + public void fillPath(Path path) { + Path p2 = rotate((Path) path); + graphics.fillPath(p2); + p2.dispose(); + } + + public void fillPolygon(int[] points) { + graphics.fillPolygon(rotate(points)); + } + + public void fillPolygon(PointList points) { + graphics.fillPolygon(rotate(points)); + } + + public void fillRectangle(int x, int y, int width, int height) { + graphics.fillRectangle(-y - height, x, height, width); + } + + public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + graphics.fillRoundRectangle(rotate(r), arcHeight, arcWidth); + } + + public void fillString(String s, int x, int y) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.fillString(s, x, y); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public void fillText(String s, int x, int y) { + boolean statePushed = false; + try { + graphics.pushState(); + statePushed = true; + } catch (Throwable t) { + statePushed = false; + } + graphics.rotate(90); + graphics.fillText(s, x, y); + graphics.rotate(-90); + if (statePushed) { + try { + graphics.restoreState(); + graphics.popState(); + } catch (Throwable t) { + } + } + } + + public double getAbsoluteScale() { + return graphics.getAbsoluteScale(); + } + + public int getAlpha() { + return graphics.getAlpha(); + } + + public int getAntialias() { + return graphics.getAntialias(); + } + + public Color getBackgroundColor() { + return graphics.getBackgroundColor(); + } + + public Rectangle getClip(Rectangle rect) { + rect = graphics.getClip(rect); + int rx = rect.y; + int ry = -rect.x - rect.width; + int rw = rect.height; + int rh = rect.width; + rect.x = rx; + rect.y = ry; + rect.width = rw; + rect.height = rh; + return rect; + } + + public int getFillRule() { + return graphics.getFillRule(); + } + + public Font getFont() { + return graphics.getFont(); + } + + public FontMetrics getFontMetrics() { + return graphics.getFontMetrics(); + } + + public Color getForegroundColor() { + return graphics.getForegroundColor(); + } + + public int getInterpolation() { + return graphics.getInterpolation(); + } + + public int getLineCap() { + return graphics.getLineCap(); + } + + public int getLineJoin() { + return graphics.getLineJoin(); + } + + public int getLineStyle() { + return graphics.getLineStyle(); + } + + public int getLineWidth() { + return graphics.getLineWidth(); + } + + public int getTextAntialias() { + return graphics.getTextAntialias(); + } + + public boolean getXORMode() { + return graphics.getXORMode(); + } + + public void popState() { + graphics.popState(); + } + + public void pushState() { + graphics.pushState(); + } + + public void restoreState() { + graphics.restoreState(); + } + + public void rotate(float degrees) { + graphics.rotate(degrees); + } + + public void scale(double amount) { + graphics.scale(amount); + } + + public void scale(float horizontal, float vertical) { + graphics.scale(horizontal, vertical); + } + + public void setAlpha(int alpha) { + graphics.setAlpha(alpha); + } + + public void setAntialias(int value) { + graphics.setAntialias(value); + } + + public void setBackgroundColor(Color rgb) { + graphics.setBackgroundColor(rgb); + } + + public void setBackgroundPattern(Pattern pattern) { + if (lastBgPattern != null) { + lastBgPattern.dispose(); + lastBgPattern = null; + } + if (pattern instanceof GradientPattern) { + Pattern p = rotate((GradientPattern) pattern); + graphics.setBackgroundPattern(p); + lastBgPattern = p; + } else if (pattern instanceof ImagePattern) { + Pattern p = rotate((ImagePattern) pattern); + graphics.setBackgroundPattern(p); + lastBgPattern = p; + } else { + graphics.setBackgroundPattern(pattern); + } + } + + public void setClip(Path path) { + Path p2 = rotate((Path) path); + graphics.setClip(p2); + p2.dispose(); + } + + public void setClip(Rectangle r) { + graphics.setClip(rotate(r)); + } + + public void setFillRule(int rule) { + graphics.setFillRule(rule); + } + + public void setFont(Font f) { + graphics.setFont(f); + } + + public void setForegroundColor(Color rgb) { + graphics.setForegroundColor(rgb); + } + + public void setForegroundPattern(Pattern pattern) { + if (lastFgPattern != null) { + lastFgPattern.dispose(); + lastFgPattern = null; + } + if (pattern instanceof GradientPattern) { + Pattern p = rotate((GradientPattern) pattern); + graphics.setForegroundPattern(p); + lastFgPattern = p; + } else if (pattern instanceof ImagePattern) { + Pattern p = rotate((ImagePattern) pattern); + graphics.setForegroundPattern(p); + lastFgPattern = p; + } else { + graphics.setForegroundPattern(pattern); + } + } + + public void setInterpolation(int interpolation) { + graphics.setInterpolation(interpolation); + } + + public void setLineCap(int cap) { + graphics.setLineCap(cap); + } + + public void setLineDash(int[] dash) { + graphics.setLineDash(dash); + } + + public void setLineJoin(int join) { + graphics.setLineJoin(join); + } + + public void setLineStyle(int style) { + graphics.setLineStyle(style); + } + + public void setLineWidth(int width) { + graphics.setLineWidth(width); + } + + public void setTextAntialias(int value) { + graphics.setTextAntialias(value); + } + + public void setXORMode(boolean b) { + graphics.setXORMode(b); + } + + public void shear(float horz, float vert) { + graphics.shear(horz, vert); + } + + public void translate(float dx, float dy) { + graphics.translate(-dy, dx); + } + + public void translate(int dx, int dy) { + graphics.translate(-dy, dx); + } + + // ========================================================== + // Since 3.5 + // ========================================================== + + public boolean getAdvanced() { + return graphics.getAdvanced(); + } + + public float getLineWidthFloat() { + return graphics.getLineWidthFloat(); + } + + public LineAttributes getLineAttributes() { + return graphics.getLineAttributes(); + } + + public float getLineMiterLimit() { + return graphics.getLineMiterLimit(); + } + + public void setAdvanced(boolean advanced) { + graphics.setAdvanced(advanced); + } + + public void setLineMiterLimit(float miterLimit) { + graphics.setLineMiterLimit(miterLimit); + } + + public void setLineWidthFloat(float width) { + graphics.setLineWidthFloat(width); + } + + public void setLineAttributes(LineAttributes attributes) { + graphics.setLineAttributes(attributes); + } + + public void setLineDash(float[] value) { + graphics.setLineDash(value); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ScaledGraphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ScaledGraphics.java index e96066bdc..ca66bc901 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ScaledGraphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/ScaledGraphics.java @@ -1,1277 +1,1277 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.draw2d.graphics; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.FigureUtilities; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.LineAttributes; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.PathData; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.graphics.TextStyle; -import org.eclipse.swt.widgets.Display; - -public class ScaledGraphics extends Graphics { - - /** - * For Debugging: Once ScaledGraphics is proven to be replaceable by - * {@link Graphics#scale(double)} on all supported platforms, we will turn - * this switch off. Clients should check this value before creating - * ScaledGraphics instances. - */ - public static boolean SCALED_GRAPHICS_ENABLED = false; - - private static class PatternKey { - - GradientPattern pattern; - - double zoom; - - PatternKey() { - } - - PatternKey(GradientPattern pattern, double zoom) { - this.pattern = pattern; - this.zoom = zoom; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof PatternKey)) - return false; - PatternKey that = (PatternKey) obj; - return this.pattern.equals(that.pattern) && this.zoom == that.zoom; - } - - public int hashCode() { - long bits = Double.doubleToLongBits(zoom); - int hc = (int) (bits ^ (bits >>> 32)); - return pattern.hashCode() ^ hc; - } - - void setValues(GradientPattern pattern, double zoom) { - this.pattern = pattern; - this.zoom = zoom; - } - } - - private static class FontHeightCache { - Font font; - int height; - } - - protected static class FontKey { - Font font; - int height; - - protected FontKey() {/* empty constructor */ - } - - protected FontKey(Font font, int height) { - this.font = font; - this.height = height; - } - - public boolean equals(Object obj) { - return (((FontKey) obj).font.equals(font) - && ((FontKey) obj).height == height); - } - - public int hashCode() { - return font.hashCode() ^ height; - } - - protected void setValues(Font font, int height) { - this.font = font; - this.height = height; - } - } - - /** - * The internal state of the scaled graphics. - */ - protected static class State { - private double appliedX; - private double appliedY; - private Font font; - private float lineWidth; - private double zoom; - - private int[] lineDash; - - private Pattern background; - - private Pattern foreground; - - /** - * Constructs a new, uninitialized State object. - */ - protected State() {/* empty constructor */ - } - - /** - * Constructs a new State object and initializes the properties based on - * the given values. - * - * @param zoom - * the zoom factor - * @param x - * the x offset - * @param y - * the y offset - * @param font - * the font - * @param lineWidth - * the line width - */ - protected State(double zoom, double x, double y, Font font, - float lineWidth, int[] lineDash, Pattern background, - Pattern foreground) { - this.zoom = zoom; - this.appliedX = x; - this.appliedY = y; - this.font = font; - this.lineWidth = lineWidth; - this.lineDash = lineDash; - this.background = background; - this.foreground = foreground; - } - - /** - * Sets all the properties of the state object. - * - * @param zoom - * the zoom factor - * @param x - * the x offset - * @param y - * the y offset - * @param font - * the font - * @param lineWidth - * the line width - */ - protected void setValues(double zoom, double x, double y, Font font, - float lineWidth, int[] lineDash, Pattern background, - Pattern foreground) { - this.zoom = zoom; - this.appliedX = x; - this.appliedY = y; - this.font = font; - this.lineWidth = lineWidth; - this.lineDash = lineDash; - this.background = background; - this.foreground = foreground; - } - } - - private static int[][] intArrayCache = new int[8][]; - private final Rectangle tempRECT = new Rectangle(); - - static { - for (int i = 0; i < intArrayCache.length; i++) - intArrayCache[i] = new int[i + 1]; - } - - private boolean allowText = true; - //private static final Point PT = new Point(); - private Map fontCache = new HashMap(); - private Map fontDataCache = new HashMap(); - private FontKey fontKey = new FontKey(); - private double fractionalX; - private double fractionalY; - private Graphics graphics; - private FontHeightCache localCache = new FontHeightCache(); - private Font localFont; - private float localLineWidth; - private List stack = new ArrayList(); - private int stackPointer = 0; - private FontHeightCache targetCache = new FontHeightCache(); - - private double zoom = 1.0; - - private int[] localDash = null; - private Pattern localBackground = null; - private Pattern localForeground = null; - private Map patternCache = new HashMap(); - private PatternKey patternKey = new PatternKey(); - - /** - * Constructs a new ScaledGraphics based on the given Graphics object. - * - * @param g - * the base graphics object - */ - public ScaledGraphics(Graphics g) { - graphics = g; - localFont = g.getFont(); - localLineWidth = g.getLineWidth(); - } - - /** - * @see Graphics#clipRect(Rectangle) - */ - public void clipRect(Rectangle r) { - graphics.clipRect(zoomClipRect(r)); - } - - Font createFont(FontData data) { - return new Font(Display.getCurrent(), data); - } - - /** - * @see Graphics#dispose() - */ - public void dispose() { - //Remove all states from the stack - while (stackPointer > 0) { - popState(); - } - - //Dispose fonts - for (Font font : fontCache.values()) { - font.dispose(); - } - - for (Pattern pattern : patternCache.values()) { - pattern.dispose(); - } - - // Resource manager handles fonts - } - - /** - * @see Graphics#drawArc(int, int, int, int, int, int) - */ - public void drawArc(int x, int y, int w, int h, int offset, int sweep) { - Rectangle z = zoomRect(x, y, w, h); - if (z.isEmpty() || sweep == 0) - return; - graphics.drawArc(z, offset, sweep); - } - - /** - * @see Graphics#drawFocus(int, int, int, int) - */ - public void drawFocus(int x, int y, int w, int h) { - graphics.drawFocus(zoomRect(x, y, w, h)); - } - - /** - * @see Graphics#drawImage(Image, int, int) - */ - public void drawImage(Image srcImage, int x, int y) { - org.eclipse.swt.graphics.Rectangle size = srcImage.getBounds(); - graphics.drawImage(srcImage, 0, 0, size.width, size.height, - (int) (Math.floor((x * zoom + fractionalX))), - (int) (Math.floor((y * zoom + fractionalY))), - (int) (Math.floor((size.width * zoom + fractionalX))), - (int) (Math.floor((size.height * zoom + fractionalY)))); - } - - /** - * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int) - */ - public void drawImage(Image srcImage, int sx, int sy, int sw, int sh, - int tx, int ty, int tw, int th) { - //"t" == target rectangle, "s" = source - - Rectangle t = zoomRect(tx, ty, tw, th); - if (!t.isEmpty()) - graphics.drawImage(srcImage, sx, sy, sw, sh, t.x, t.y, t.width, - t.height); - } - - /** - * @see Graphics#drawLine(int, int, int, int) - */ - public void drawLine(int x1, int y1, int x2, int y2) { - graphics.drawLine((int) (Math.floor((x1 * zoom + fractionalX))), - (int) (Math.floor((y1 * zoom + fractionalY))), - (int) (Math.floor((x2 * zoom + fractionalX))), - (int) (Math.floor((y2 * zoom + fractionalY)))); - } - - /** - * @see Graphics#drawOval(int, int, int, int) - */ - public void drawOval(int x, int y, int w, int h) { - graphics.drawOval(zoomRect(x, y, w, h)); - } - - /** - * @see Graphics#drawPoint(int, int) - */ - public void drawPoint(int x, int y) { - graphics.drawPoint((int) Math.floor(x * zoom + fractionalX), - (int) Math.floor(y * zoom + fractionalY)); - } - - /** - * @see Graphics#drawPolygon(int[]) - */ - public void drawPolygon(int[] points) { - graphics.drawPolygon(zoomPointList(points)); - } - - /** - * @see Graphics#drawPolygon(PointList) - */ - public void drawPolygon(PointList points) { - graphics.drawPolygon(zoomPointList(points.toIntArray())); - } - - /** - * @see Graphics#drawPolyline(int[]) - */ - public void drawPolyline(int[] points) { - graphics.drawPolyline(zoomPointList(points)); - } - - /** - * @see Graphics#drawPolyline(PointList) - */ - public void drawPolyline(PointList points) { - graphics.drawPolyline(zoomPointList(points.toIntArray())); - } - - /** - * @see Graphics#drawRectangle(int, int, int, int) - */ - public void drawRectangle(int x, int y, int w, int h) { - graphics.drawRectangle(zoomRect(x, y, w, h)); - } - - /** - * @see Graphics#drawRoundRectangle(Rectangle, int, int) - */ - public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - graphics.drawRoundRectangle(zoomRect(r.x, r.y, r.width, r.height), - (int) (arcWidth * zoom), (int) (arcHeight * zoom)); - } - - /** - * @see Graphics#drawString(String, int, int) - */ - public void drawString(String s, int x, int y) { - if (allowText) - graphics.drawString(s, zoomTextPoint(x, y)); - } - - /** - * @see Graphics#drawText(String, int, int) - */ - public void drawText(String s, int x, int y) { - if (allowText) - graphics.drawText(s, zoomTextPoint(x, y)); - } - - /** - * @see Graphics#drawText(String, int, int, int) - */ - public void drawText(String s, int x, int y, int style) { - if (allowText) - graphics.drawText(s, zoomTextPoint(x, y), style); - } - - /** - * @see Graphics#drawTextLayout(TextLayout, int, int, int, int, Color, - * Color) - */ - public void drawTextLayout(TextLayout layout, int x, int y, - int selectionStart, int selectionEnd, Color selectionForeground, - Color selectionBackground) { - TextLayout scaled = zoomTextLayout(layout); - graphics.drawTextLayout(scaled, - (int) Math.floor(x * zoom + fractionalX), - (int) Math.floor(y * zoom + fractionalY), selectionStart, - selectionEnd, selectionBackground, selectionForeground); - scaled.dispose(); - } - - /** - * @see Graphics#fillArc(int, int, int, int, int, int) - */ - public void fillArc(int x, int y, int w, int h, int offset, int sweep) { - Rectangle z = zoomFillRect(x, y, w, h); - if (z.isEmpty() || sweep == 0) - return; - graphics.fillArc(z, offset, sweep); - } - - /** - * @see Graphics#fillGradient(int, int, int, int, boolean) - */ - public void fillGradient(int x, int y, int w, int h, boolean vertical) { - graphics.fillGradient(zoomFillRect(x, y, w, h), vertical); - } - - /** - * @see Graphics#fillOval(int, int, int, int) - */ - public void fillOval(int x, int y, int w, int h) { - graphics.fillOval(zoomFillRect(x, y, w, h)); - } - - /** - * @see Graphics#fillPolygon(int[]) - */ - public void fillPolygon(int[] points) { - graphics.fillPolygon(zoomPointList(points)); - } - - /** - * @see Graphics#fillPolygon(PointList) - */ - public void fillPolygon(PointList points) { - graphics.fillPolygon(zoomPointList(points.toIntArray())); - } - - /** - * @see Graphics#fillRectangle(int, int, int, int) - */ - public void fillRectangle(int x, int y, int w, int h) { - graphics.fillRectangle(zoomFillRect(x, y, w, h)); - } - - /** - * @see Graphics#fillRoundRectangle(Rectangle, int, int) - */ - public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { - graphics.fillRoundRectangle(zoomFillRect(r.x, r.y, r.width, r.height), - (int) (arcWidth * zoom), (int) (arcHeight * zoom)); - } - - /** - * @see Graphics#fillString(String, int, int) - */ - public void fillString(String s, int x, int y) { - if (allowText) - graphics.fillString(s, zoomTextPoint(x, y)); - } - - /** - * @see Graphics#fillText(String, int, int) - */ - public void fillText(String s, int x, int y) { - if (allowText) - graphics.fillText(s, zoomTextPoint(x, y)); - } - - /** - * @see Graphics#getAbsoluteScale() - */ - public double getAbsoluteScale() { - return zoom * graphics.getAbsoluteScale(); - } - - /** - * @see Graphics#getAlpha() - */ - public int getAlpha() { - return graphics.getAlpha(); - } - - /** - * @see Graphics#getAntialias() - */ - public int getAntialias() { - return graphics.getAntialias(); - } - - /** - * @see Graphics#getBackgroundColor() - */ - public Color getBackgroundColor() { - return graphics.getBackgroundColor(); - } - - private Font getCachedFont(FontKey key) { - Font font = fontCache.get(key); - if (font != null) - return font; - - key = new FontKey(key.font, key.height); - Font zoomedFont = createZoomedFont(key.font, key.height); - fontCache.put(key, zoomedFont); - return zoomedFont; - } - - private Font createZoomedFont(Font font, int height) { - FontData[] fontData = font.getFontData(); - for (FontData f : fontData) { - f.setHeight(height); - } - return new Font(Display.getCurrent(), fontData); - } - - private FontData getCachedFontData(Font f) { - FontData data = fontDataCache.get(f); - if (data != null) - return data; - data = getLocalFont().getFontData()[0]; - fontDataCache.put(f, data); - return data; - } - - private Pattern getCachedPattern(PatternKey key) { - GradientPattern pattern = patternCache.get(key); - if (pattern != null) - return pattern; - - key = new PatternKey(key.pattern, key.zoom); - pattern = createZoomedPattern(key.pattern); - patternCache.put(key, pattern); - return pattern; - } - - private GradientPattern createZoomedPattern(GradientPattern p1) { - return new GradientPattern(p1.getDevice(), (float) (zoom * p1.x1), - (float) (zoom * p1.y1), (float) (zoom * p1.x2), - (float) (zoom * p1.y2), p1.color1, p1.alpha1, p1.color2, - p1.alpha2); - } - - /** - * @see Graphics#getClip(Rectangle) - */ - public Rectangle getClip(Rectangle rect) { - graphics.getClip(rect); - int x = (int) (rect.x / zoom); - int y = (int) (rect.y / zoom); - /* - * If the clip rectangle is queried, perform an inverse zoom, and take - * the ceiling of the resulting double. This is necessary because - * forward scaling essentially performs a floor() function. Without - * this, figures will think that they don't need to paint when actually - * they do. - */ - rect.width = (int) Math.ceil(rect.right() / zoom) - x; - rect.height = (int) Math.ceil(rect.bottom() / zoom) - y; - rect.x = x; - rect.y = y; - return rect; - } - - /** - * @see Graphics#getFillRule() - */ - public int getFillRule() { - return graphics.getFillRule(); - } - - /** - * @see Graphics#getFont() - */ - public Font getFont() { - return getLocalFont(); - } - - /** - * @see Graphics#getFontMetrics() - */ - public FontMetrics getFontMetrics() { - return FigureUtilities.getFontMetrics(localFont); - } - - /** - * @see Graphics#getForegroundColor() - */ - public Color getForegroundColor() { - return graphics.getForegroundColor(); - } - - /** - * @see Graphics#getInterpolation() - */ - public int getInterpolation() { - return graphics.getInterpolation(); - } - - /** - * @see Graphics#getLineCap() - */ - public int getLineCap() { - return graphics.getLineCap(); - } - - /** - * @see Graphics#getLineJoin() - */ - public int getLineJoin() { - return graphics.getLineJoin(); - } - - /** - * @see Graphics#getLineStyle() - */ - public int getLineStyle() { - return graphics.getLineStyle(); - } - - /** - * @see Graphics#getLineWidth() - */ - public int getLineWidth() { - return (int) getLocalLineWidth(); - } - - public float getLineWidthFloat() { - return getLocalLineWidth(); - } - - protected final Font getLocalFont() { - return localFont; - } - - protected final float getLocalLineWidth() { - return localLineWidth; - } - - /** - * @see Graphics#getTextAntialias() - */ - public int getTextAntialias() { - return graphics.getTextAntialias(); - } - - /** - * @see Graphics#getXORMode() - */ - public boolean getXORMode() { - return graphics.getXORMode(); - } - - /** - * @see Graphics#popState() - */ - public void popState() { - graphics.popState(); - stackPointer--; - restoreLocalState(stack.get(stackPointer)); - if (lastClipPath != null) { - lastClipPath.dispose(); - lastClipPath = null; - } - } - - /** - * @see Graphics#pushState() - */ - public void pushState() { - if (stack.size() > stackPointer) { - State s = stack.get(stackPointer); - s.setValues(zoom, fractionalX, fractionalY, getLocalFont(), - getLocalLineWidth(), localDash, localBackground, - localForeground); - } else { - stack.add(new State(zoom, fractionalX, fractionalY, getLocalFont(), - getLocalLineWidth(), localDash, localBackground, - localForeground)); - } - stackPointer++; - - graphics.pushState(); - } - - protected void restoreLocalState(State state) { - this.fractionalX = state.appliedX; - this.fractionalY = state.appliedY; - setScale(state.zoom); - setLocalFont(state.font); - setLocalLineWidth(state.lineWidth); - setLocalLineDash(state.lineDash); - setLocalBackgroundPattern(state.background); - setLocalForegroundPattern(state.foreground); - } - - /** - * @see Graphics#restoreState() - */ - public void restoreState() { - graphics.restoreState(); - restoreLocalState(stack.get(stackPointer - 1)); - } - - /** - * @see Graphics#scale(double) - */ - public void scale(double amount) { - setScale(zoom * amount); - } - - /** - * This method requires advanced graphics support. A check should be made to - * ensure advanced graphics is supported in the user's environment before - * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. - * - * @see Graphics#setAlpha(int) - */ - public void setAlpha(int alpha) { - graphics.setAlpha(alpha); - } - - /** - * This method requires advanced graphics support. A check should be made to - * ensure advanced graphics is supported in the user's environment before - * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. - * - * @see Graphics#setAntialias(int) - */ - public void setAntialias(int value) { - graphics.setAntialias(value); - } - - /** - * @see Graphics#setBackgroundColor(Color) - */ - public void setBackgroundColor(Color rgb) { - graphics.setBackgroundColor(rgb); - } - - /** - * @see Graphics#setClip(Rectangle) - */ - public void setClip(Rectangle r) { - graphics.setClip(zoomClipRect(r)); - } - - /** - * @see Graphics#setFillRule(int) - */ - public void setFillRule(int rule) { - graphics.setFillRule(rule); - } - - /** - * @see Graphics#setFont(Font) - */ - public void setFont(Font f) { - setLocalFont(f); - } - - /** - * @see Graphics#setForegroundColor(Color) - */ - public void setForegroundColor(Color rgb) { - graphics.setForegroundColor(rgb); - } - - /** - * This method requires advanced graphics support. A check should be made to - * ensure advanced graphics is supported in the user's environment before - * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. - * - * @see org.eclipse.draw2d.Graphics#setInterpolation(int) - */ - public void setInterpolation(int interpolation) { - graphics.setInterpolation(interpolation); - } - - /** - * @see Graphics#setLineCap(int) - */ - public void setLineCap(int cap) { - graphics.setLineCap(cap); - } - - /** - * @see Graphics#setLineDash(int[]) - */ - public void setLineDash(int[] dash) { - setLocalLineDash(dash); - } - - private void setLocalLineDash(int[] dash) { - localDash = dash; - if (dash != null) - graphics.setLineDash(zoomDash(dash)); - } - - /** - * @see Graphics#setLineJoin(int) - */ - public void setLineJoin(int join) { - graphics.setLineJoin(join); - } - - /** - * @see Graphics#setLineStyle(int) - */ - public void setLineStyle(int style) { - graphics.setLineStyle(style); - } - - /** - * @see Graphics#setLineWidth(int) - */ - public void setLineWidth(int width) { - setLineWidthFloat(width); - } - - public void setLineWidthFloat(float width) { - setLocalLineWidth(width); - } - - private void setLocalFont(Font f) { - localFont = f; - graphics.setFont(zoomFont(f)); - } - - private void setLocalLineWidth(float width) { - localLineWidth = width; - graphics.setLineWidth((int) zoomLineWidth(width)); - } - - void setScale(double value) { - if (zoom == value) - return; - this.zoom = value; - graphics.setFont(zoomFont(getLocalFont())); - graphics.setLineWidth((int) zoomLineWidth(getLocalLineWidth())); - if (localDash != null) - graphics.setLineDash(zoomDash(localDash)); - if (localBackground != null) - graphics.setBackgroundPattern(zoomPattern(localBackground)); - if (localForeground != null) - graphics.setForegroundPattern(zoomPattern(localForeground)); - } - - /** - * This method requires advanced graphics support. A check should be made to - * ensure advanced graphics is supported in the user's environment before - * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. - * - * @see Graphics#setTextAntialias(int) - */ - public void setTextAntialias(int value) { - graphics.setTextAntialias(value); - } - - /** - * @see Graphics#setXORMode(boolean) - */ - public void setXORMode(boolean b) { - graphics.setXORMode(b); - } - - /** - * @see Graphics#translate(int, int) - */ - public void translate(int dx, int dy) { - // fractionalX/Y is the fractional part left over from previous - // translates that gets lost in the integer approximation. - double dxFloat = dx * zoom + fractionalX; - double dyFloat = dy * zoom + fractionalY; - fractionalX = dxFloat - Math.floor(dxFloat); - fractionalY = dyFloat - Math.floor(dyFloat); - graphics.translate((int) Math.floor(dxFloat), - (int) Math.floor(dyFloat)); - } - - private Rectangle zoomClipRect(Rectangle r) { - tempRECT.x = (int) (Math.floor(r.x * zoom + fractionalX)); - tempRECT.y = (int) (Math.floor(r.y * zoom + fractionalY)); - tempRECT.width = (int) (Math - .ceil(((r.x + r.width) * zoom + fractionalX))) - tempRECT.x; - tempRECT.height = (int) (Math - .ceil(((r.y + r.height) * zoom + fractionalY))) - tempRECT.y; - return tempRECT; - } - - private Rectangle zoomFillRect(int x, int y, int w, int h) { - tempRECT.x = (int) (Math.floor((x * zoom + fractionalX))); - tempRECT.y = (int) (Math.floor((y * zoom + fractionalY))); - tempRECT.width = (int) (Math.floor(((x + w - 1) * zoom + fractionalX))) - - tempRECT.x + 1; - tempRECT.height = (int) (Math.floor(((y + h - 1) * zoom + fractionalY))) - - tempRECT.y + 1; - return tempRECT; - } - - private Font zoomFont(Font f) { - if (f == null) - f = Display.getCurrent().getSystemFont(); - FontData data = getCachedFontData(f); - int zoomedFontHeight = zoomFontHeight(data.getHeight()); - allowText = zoomedFontHeight > 0; - fontKey.setValues(f, zoomedFontHeight); - return getCachedFont(fontKey); - } - - protected int zoomFontHeight(int height) { - return (int) (zoom * height); - } - - protected float zoomLineWidth(float w) { - return (float) (zoom * w); - } - - private int[] zoomPointList(int[] points) { - int[] scaled = null; - - // Look in cache for a integer array with the same length as 'points' - for (int i = 0; i < intArrayCache.length; i++) { - if (intArrayCache[i].length == points.length) { - scaled = intArrayCache[i]; - - // Move this integer array up one notch in the array - if (i != 0) { - int[] temp = intArrayCache[i - 1]; - intArrayCache[i - 1] = scaled; - intArrayCache[i] = temp; - } - } - } - - // If no match is found, take the one that is last and resize it. - if (scaled == null) { - intArrayCache[intArrayCache.length - 1] = new int[points.length]; - scaled = intArrayCache[intArrayCache.length - 1]; - } - - // Scale the points - for (int i = 0; (i + 1) < points.length; i += 2) { - scaled[i] = (int) (Math.floor((points[i] * zoom + fractionalX))); - scaled[i + 1] = (int) (Math - .floor((points[i + 1] * zoom + fractionalY))); - } - return scaled; - } - - protected Rectangle zoomRect(int x, int y, int w, int h) { - tempRECT.x = (int) (Math.floor(x * zoom + fractionalX)); - tempRECT.y = (int) (Math.floor(y * zoom + fractionalY)); - tempRECT.width = (int) (Math.floor(((x + w) * zoom + fractionalX))) - - tempRECT.x; - tempRECT.height = (int) (Math.floor(((y + h) * zoom + fractionalY))) - - tempRECT.y; - return tempRECT; - } - - private TextLayout zoomTextLayout(TextLayout layout) { - TextLayout zoomed = new TextLayout(Display.getCurrent()); - zoomed.setText(layout.getText()); - - int zoomWidth = -1; - - if (layout.getWidth() != -1) - zoomWidth = ((int) (layout.getWidth() * zoom)); - - if (zoomWidth < -1 || zoomWidth == 0) - return null; - - zoomed.setFont(zoomFont(layout.getFont())); - zoomed.setAlignment(layout.getAlignment()); - zoomed.setAscent(layout.getAscent()); - zoomed.setDescent(layout.getDescent()); - zoomed.setOrientation(layout.getOrientation()); - zoomed.setSegments(layout.getSegments()); - zoomed.setSpacing(layout.getSpacing()); - zoomed.setTabs(layout.getTabs()); - - zoomed.setWidth(zoomWidth); - int length = layout.getText().length(); - if (length > 0) { - int start = 0, offset = 1; - TextStyle style = null, lastStyle = layout.getStyle(0); - for (; offset <= length; offset++) { - if (offset != length - && (style = layout.getStyle(offset)) == lastStyle) - continue; - int end = offset - 1; - - if (lastStyle != null) { - TextStyle zoomedStyle = new TextStyle( - zoomFont(lastStyle.font), lastStyle.foreground, - lastStyle.background); - zoomedStyle.metrics = lastStyle.metrics; - zoomedStyle.rise = lastStyle.rise; - zoomedStyle.strikeout = lastStyle.strikeout; - zoomedStyle.underline = lastStyle.underline; - zoomed.setStyle(zoomedStyle, start, end); - } - lastStyle = style; - start = offset; - } - } - return zoomed; - } - - private Point zoomTextPoint(int x, int y) { - if (localCache.font != localFont) { - //Font is different, re-calculate its height - FontMetrics metric = FigureUtilities.getFontMetrics(localFont); - localCache.height = metric.getHeight() - metric.getDescent(); - localCache.font = localFont; - } - if (targetCache.font != graphics.getFont()) { - FontMetrics metric = graphics.getFontMetrics(); - targetCache.font = graphics.getFont(); - targetCache.height = metric.getHeight() - metric.getDescent(); - } - return new Point(((int) (Math.floor((x * zoom) + fractionalX))), - (int) (Math.floor((y + localCache.height - 1) * zoom - - targetCache.height + 1 + fractionalY))); - } - - protected Graphics getGraphics() { - return graphics; - } - - /** - * @see org.eclipse.draw2d.Graphics#drawPath(org.eclipse.swt.graphics.Path) - */ - @Override - public void drawPath(Path path) { - Path zoomPath = zoomPath(path); - getGraphics().drawPath(zoomPath); - zoomPath.dispose(); - } - - /** - * @see org.eclipse.draw2d.Graphics#fillPath(org.eclipse.swt.graphics.Path) - */ - @Override - public void fillPath(Path path) { - Path zoomPath = zoomPath(path); - getGraphics().fillPath(zoomPath); - zoomPath.dispose(); - } - - /** - * @param path - * @return - */ - private Path zoomPath(Path path) { - PathData data = path.getPathData(); - Path newPath = new Path(path.getDevice()); - int index = 0; - for (byte type : data.types) { - switch (type) { - case SWT.PATH_MOVE_TO: - newPath.moveTo((float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++])); - break; - case SWT.PATH_LINE_TO: - newPath.lineTo((float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++])); - break; - case SWT.PATH_CUBIC_TO: - newPath.cubicTo((float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++])); - break; - case SWT.PATH_QUAD_TO: - newPath.quadTo((float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++]), - (float) (zoom * data.points[index++])); - break; - case SWT.PATH_CLOSE: - newPath.close(); - break; - } - } - return newPath; - } - - /** - * @see org.eclipse.draw2d.Graphics#setBackgroundPattern(org.eclipse.swt.graphics.Pattern) - */ - @Override - public void setBackgroundPattern(Pattern pattern) { - setLocalBackgroundPattern(pattern); - } - - /** - * @see org.eclipse.draw2d.Graphics#setForegroundPattern(org.eclipse.swt.graphics.Pattern) - */ - @Override - public void setForegroundPattern(Pattern pattern) { - setLocalForegroundPattern(pattern); - } - - private void setLocalBackgroundPattern(Pattern pattern) { - localBackground = pattern; - graphics.setBackgroundPattern(zoomPattern(pattern)); - } - - private void setLocalForegroundPattern(Pattern pattern) { - localForeground = pattern; - graphics.setForegroundPattern(zoomPattern(pattern)); - } - - /** - * @param dash - * @return - */ - private int[] zoomDash(int[] dash) { - if (dash == null || dash.length == 0) { - dash = new int[1]; - dash[0] = 1; - return dash; - } - int[] d = new int[dash.length]; - for (int i = 0; i < d.length; i++) { - d[i] = Math.max(1, (int) (zoom * dash[i])); - } - return d; - } - - protected Pattern zoomPattern(Pattern pattern) { - if (!(pattern instanceof GradientPattern)) - return pattern; - patternKey.setValues((GradientPattern) pattern, zoom); - return getCachedPattern(patternKey); - } - - /** - * @see org.eclipse.draw2d.Graphics#rotate(float) - */ - @Override - public void rotate(float degrees) { - graphics.rotate(degrees); - } - - public void translate(float dx, float dy) { - graphics.translate(dx, dy); - } - - private Path lastClipPath = null; - - public void setClip(Path path) { - Path p = path == null ? null : zoomPath(path); - graphics.setClip(p); - if (lastClipPath != null) { - lastClipPath.dispose(); - lastClipPath = null; - } - if (p != path) { - lastClipPath = p; - } - } - - /** - * @see org.eclipse.draw2d.Graphics#clipPath(org.eclipse.swt.graphics.Path) - */ - public void clipPath(Path path) { - Path scaledPath = createScaledPath(path); - try { - graphics.clipPath(scaledPath); - } finally { - scaledPath.dispose(); - } - } - - /** - * Scales given path by zoom factor - * - * @param path - * Path to be scaled - * @return Scaled path - */ - private Path createScaledPath(Path path) { - PathData p = path.getPathData(); - for (int i = 0; i < p.points.length; i += 2) { - p.points[i] = (float) (p.points[i] * zoom + fractionalX); - p.points[i + 1] = (float) (p.points[i + 1] * zoom + fractionalY); - } - Path scaledPath = new Path(path.getDevice()); - int index = 0; - for (int i = 0; i < p.types.length; i++) { - byte type = p.types[i]; - switch (type) { - case SWT.PATH_MOVE_TO: - scaledPath.moveTo(p.points[index], p.points[index + 1]); - index += 2; - break; - case SWT.PATH_LINE_TO: - scaledPath.lineTo(p.points[index], p.points[index + 1]); - index += 2; - break; - case SWT.PATH_CUBIC_TO: - scaledPath.cubicTo(p.points[index], p.points[index + 1], - p.points[index + 2], p.points[index + 3], - p.points[index + 4], p.points[index + 5]); - index += 6; - break; - case SWT.PATH_QUAD_TO: - scaledPath.quadTo(p.points[index], p.points[index + 1], - p.points[index + 2], p.points[index + 3]); - index += 4; - break; - case SWT.PATH_CLOSE: - scaledPath.close(); - break; - } - } - return scaledPath; - } - - // ========================================================== - // Since 3.5 - // ========================================================== - - public boolean getAdvanced() { - return graphics.getAdvanced(); - } - - public LineAttributes getLineAttributes() { - LineAttributes a = graphics.getLineAttributes(); - a.width = getLocalLineWidth(); - return a; - } - - public float getLineMiterLimit() { - return graphics.getLineMiterLimit(); - } - - public void setAdvanced(boolean advanced) { - graphics.setAdvanced(advanced); - } - - public void setLineMiterLimit(float miterLimit) { - graphics.setLineMiterLimit(miterLimit); - } - - public void setLineAttributes(LineAttributes attributes) { - graphics.setLineAttributes(attributes); - setLocalLineWidth(attributes.width); - } - - public void setLineDash(float[] value) { - graphics.setLineDash(value); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.draw2d.graphics; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.FigureUtilities; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.LineAttributes; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.PathData; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.graphics.TextStyle; +import org.eclipse.swt.widgets.Display; + +public class ScaledGraphics extends Graphics { + + /** + * For Debugging: Once ScaledGraphics is proven to be replaceable by + * {@link Graphics#scale(double)} on all supported platforms, we will turn + * this switch off. Clients should check this value before creating + * ScaledGraphics instances. + */ + public static boolean SCALED_GRAPHICS_ENABLED = false; + + private static class PatternKey { + + GradientPattern pattern; + + double zoom; + + PatternKey() { + } + + PatternKey(GradientPattern pattern, double zoom) { + this.pattern = pattern; + this.zoom = zoom; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof PatternKey)) + return false; + PatternKey that = (PatternKey) obj; + return this.pattern.equals(that.pattern) && this.zoom == that.zoom; + } + + public int hashCode() { + long bits = Double.doubleToLongBits(zoom); + int hc = (int) (bits ^ (bits >>> 32)); + return pattern.hashCode() ^ hc; + } + + void setValues(GradientPattern pattern, double zoom) { + this.pattern = pattern; + this.zoom = zoom; + } + } + + private static class FontHeightCache { + Font font; + int height; + } + + protected static class FontKey { + Font font; + int height; + + protected FontKey() {/* empty constructor */ + } + + protected FontKey(Font font, int height) { + this.font = font; + this.height = height; + } + + public boolean equals(Object obj) { + return (((FontKey) obj).font.equals(font) + && ((FontKey) obj).height == height); + } + + public int hashCode() { + return font.hashCode() ^ height; + } + + protected void setValues(Font font, int height) { + this.font = font; + this.height = height; + } + } + + /** + * The internal state of the scaled graphics. + */ + protected static class State { + private double appliedX; + private double appliedY; + private Font font; + private float lineWidth; + private double zoom; + + private int[] lineDash; + + private Pattern background; + + private Pattern foreground; + + /** + * Constructs a new, uninitialized State object. + */ + protected State() {/* empty constructor */ + } + + /** + * Constructs a new State object and initializes the properties based on + * the given values. + * + * @param zoom + * the zoom factor + * @param x + * the x offset + * @param y + * the y offset + * @param font + * the font + * @param lineWidth + * the line width + */ + protected State(double zoom, double x, double y, Font font, + float lineWidth, int[] lineDash, Pattern background, + Pattern foreground) { + this.zoom = zoom; + this.appliedX = x; + this.appliedY = y; + this.font = font; + this.lineWidth = lineWidth; + this.lineDash = lineDash; + this.background = background; + this.foreground = foreground; + } + + /** + * Sets all the properties of the state object. + * + * @param zoom + * the zoom factor + * @param x + * the x offset + * @param y + * the y offset + * @param font + * the font + * @param lineWidth + * the line width + */ + protected void setValues(double zoom, double x, double y, Font font, + float lineWidth, int[] lineDash, Pattern background, + Pattern foreground) { + this.zoom = zoom; + this.appliedX = x; + this.appliedY = y; + this.font = font; + this.lineWidth = lineWidth; + this.lineDash = lineDash; + this.background = background; + this.foreground = foreground; + } + } + + private static int[][] intArrayCache = new int[8][]; + private final Rectangle tempRECT = new Rectangle(); + + static { + for (int i = 0; i < intArrayCache.length; i++) + intArrayCache[i] = new int[i + 1]; + } + + private boolean allowText = true; + //private static final Point PT = new Point(); + private Map fontCache = new HashMap(); + private Map fontDataCache = new HashMap(); + private FontKey fontKey = new FontKey(); + private double fractionalX; + private double fractionalY; + private Graphics graphics; + private FontHeightCache localCache = new FontHeightCache(); + private Font localFont; + private float localLineWidth; + private List stack = new ArrayList(); + private int stackPointer = 0; + private FontHeightCache targetCache = new FontHeightCache(); + + private double zoom = 1.0; + + private int[] localDash = null; + private Pattern localBackground = null; + private Pattern localForeground = null; + private Map patternCache = new HashMap(); + private PatternKey patternKey = new PatternKey(); + + /** + * Constructs a new ScaledGraphics based on the given Graphics object. + * + * @param g + * the base graphics object + */ + public ScaledGraphics(Graphics g) { + graphics = g; + localFont = g.getFont(); + localLineWidth = g.getLineWidth(); + } + + /** + * @see Graphics#clipRect(Rectangle) + */ + public void clipRect(Rectangle r) { + graphics.clipRect(zoomClipRect(r)); + } + + Font createFont(FontData data) { + return new Font(Display.getCurrent(), data); + } + + /** + * @see Graphics#dispose() + */ + public void dispose() { + //Remove all states from the stack + while (stackPointer > 0) { + popState(); + } + + //Dispose fonts + for (Font font : fontCache.values()) { + font.dispose(); + } + + for (Pattern pattern : patternCache.values()) { + pattern.dispose(); + } + + // Resource manager handles fonts + } + + /** + * @see Graphics#drawArc(int, int, int, int, int, int) + */ + public void drawArc(int x, int y, int w, int h, int offset, int sweep) { + Rectangle z = zoomRect(x, y, w, h); + if (z.isEmpty() || sweep == 0) + return; + graphics.drawArc(z, offset, sweep); + } + + /** + * @see Graphics#drawFocus(int, int, int, int) + */ + public void drawFocus(int x, int y, int w, int h) { + graphics.drawFocus(zoomRect(x, y, w, h)); + } + + /** + * @see Graphics#drawImage(Image, int, int) + */ + public void drawImage(Image srcImage, int x, int y) { + org.eclipse.swt.graphics.Rectangle size = srcImage.getBounds(); + graphics.drawImage(srcImage, 0, 0, size.width, size.height, + (int) (Math.floor((x * zoom + fractionalX))), + (int) (Math.floor((y * zoom + fractionalY))), + (int) (Math.floor((size.width * zoom + fractionalX))), + (int) (Math.floor((size.height * zoom + fractionalY)))); + } + + /** + * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int) + */ + public void drawImage(Image srcImage, int sx, int sy, int sw, int sh, + int tx, int ty, int tw, int th) { + //"t" == target rectangle, "s" = source + + Rectangle t = zoomRect(tx, ty, tw, th); + if (!t.isEmpty()) + graphics.drawImage(srcImage, sx, sy, sw, sh, t.x, t.y, t.width, + t.height); + } + + /** + * @see Graphics#drawLine(int, int, int, int) + */ + public void drawLine(int x1, int y1, int x2, int y2) { + graphics.drawLine((int) (Math.floor((x1 * zoom + fractionalX))), + (int) (Math.floor((y1 * zoom + fractionalY))), + (int) (Math.floor((x2 * zoom + fractionalX))), + (int) (Math.floor((y2 * zoom + fractionalY)))); + } + + /** + * @see Graphics#drawOval(int, int, int, int) + */ + public void drawOval(int x, int y, int w, int h) { + graphics.drawOval(zoomRect(x, y, w, h)); + } + + /** + * @see Graphics#drawPoint(int, int) + */ + public void drawPoint(int x, int y) { + graphics.drawPoint((int) Math.floor(x * zoom + fractionalX), + (int) Math.floor(y * zoom + fractionalY)); + } + + /** + * @see Graphics#drawPolygon(int[]) + */ + public void drawPolygon(int[] points) { + graphics.drawPolygon(zoomPointList(points)); + } + + /** + * @see Graphics#drawPolygon(PointList) + */ + public void drawPolygon(PointList points) { + graphics.drawPolygon(zoomPointList(points.toIntArray())); + } + + /** + * @see Graphics#drawPolyline(int[]) + */ + public void drawPolyline(int[] points) { + graphics.drawPolyline(zoomPointList(points)); + } + + /** + * @see Graphics#drawPolyline(PointList) + */ + public void drawPolyline(PointList points) { + graphics.drawPolyline(zoomPointList(points.toIntArray())); + } + + /** + * @see Graphics#drawRectangle(int, int, int, int) + */ + public void drawRectangle(int x, int y, int w, int h) { + graphics.drawRectangle(zoomRect(x, y, w, h)); + } + + /** + * @see Graphics#drawRoundRectangle(Rectangle, int, int) + */ + public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + graphics.drawRoundRectangle(zoomRect(r.x, r.y, r.width, r.height), + (int) (arcWidth * zoom), (int) (arcHeight * zoom)); + } + + /** + * @see Graphics#drawString(String, int, int) + */ + public void drawString(String s, int x, int y) { + if (allowText) + graphics.drawString(s, zoomTextPoint(x, y)); + } + + /** + * @see Graphics#drawText(String, int, int) + */ + public void drawText(String s, int x, int y) { + if (allowText) + graphics.drawText(s, zoomTextPoint(x, y)); + } + + /** + * @see Graphics#drawText(String, int, int, int) + */ + public void drawText(String s, int x, int y, int style) { + if (allowText) + graphics.drawText(s, zoomTextPoint(x, y), style); + } + + /** + * @see Graphics#drawTextLayout(TextLayout, int, int, int, int, Color, + * Color) + */ + public void drawTextLayout(TextLayout layout, int x, int y, + int selectionStart, int selectionEnd, Color selectionForeground, + Color selectionBackground) { + TextLayout scaled = zoomTextLayout(layout); + graphics.drawTextLayout(scaled, + (int) Math.floor(x * zoom + fractionalX), + (int) Math.floor(y * zoom + fractionalY), selectionStart, + selectionEnd, selectionBackground, selectionForeground); + scaled.dispose(); + } + + /** + * @see Graphics#fillArc(int, int, int, int, int, int) + */ + public void fillArc(int x, int y, int w, int h, int offset, int sweep) { + Rectangle z = zoomFillRect(x, y, w, h); + if (z.isEmpty() || sweep == 0) + return; + graphics.fillArc(z, offset, sweep); + } + + /** + * @see Graphics#fillGradient(int, int, int, int, boolean) + */ + public void fillGradient(int x, int y, int w, int h, boolean vertical) { + graphics.fillGradient(zoomFillRect(x, y, w, h), vertical); + } + + /** + * @see Graphics#fillOval(int, int, int, int) + */ + public void fillOval(int x, int y, int w, int h) { + graphics.fillOval(zoomFillRect(x, y, w, h)); + } + + /** + * @see Graphics#fillPolygon(int[]) + */ + public void fillPolygon(int[] points) { + graphics.fillPolygon(zoomPointList(points)); + } + + /** + * @see Graphics#fillPolygon(PointList) + */ + public void fillPolygon(PointList points) { + graphics.fillPolygon(zoomPointList(points.toIntArray())); + } + + /** + * @see Graphics#fillRectangle(int, int, int, int) + */ + public void fillRectangle(int x, int y, int w, int h) { + graphics.fillRectangle(zoomFillRect(x, y, w, h)); + } + + /** + * @see Graphics#fillRoundRectangle(Rectangle, int, int) + */ + public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { + graphics.fillRoundRectangle(zoomFillRect(r.x, r.y, r.width, r.height), + (int) (arcWidth * zoom), (int) (arcHeight * zoom)); + } + + /** + * @see Graphics#fillString(String, int, int) + */ + public void fillString(String s, int x, int y) { + if (allowText) + graphics.fillString(s, zoomTextPoint(x, y)); + } + + /** + * @see Graphics#fillText(String, int, int) + */ + public void fillText(String s, int x, int y) { + if (allowText) + graphics.fillText(s, zoomTextPoint(x, y)); + } + + /** + * @see Graphics#getAbsoluteScale() + */ + public double getAbsoluteScale() { + return zoom * graphics.getAbsoluteScale(); + } + + /** + * @see Graphics#getAlpha() + */ + public int getAlpha() { + return graphics.getAlpha(); + } + + /** + * @see Graphics#getAntialias() + */ + public int getAntialias() { + return graphics.getAntialias(); + } + + /** + * @see Graphics#getBackgroundColor() + */ + public Color getBackgroundColor() { + return graphics.getBackgroundColor(); + } + + private Font getCachedFont(FontKey key) { + Font font = fontCache.get(key); + if (font != null) + return font; + + key = new FontKey(key.font, key.height); + Font zoomedFont = createZoomedFont(key.font, key.height); + fontCache.put(key, zoomedFont); + return zoomedFont; + } + + private Font createZoomedFont(Font font, int height) { + FontData[] fontData = font.getFontData(); + for (FontData f : fontData) { + f.setHeight(height); + } + return new Font(Display.getCurrent(), fontData); + } + + private FontData getCachedFontData(Font f) { + FontData data = fontDataCache.get(f); + if (data != null) + return data; + data = getLocalFont().getFontData()[0]; + fontDataCache.put(f, data); + return data; + } + + private Pattern getCachedPattern(PatternKey key) { + GradientPattern pattern = patternCache.get(key); + if (pattern != null) + return pattern; + + key = new PatternKey(key.pattern, key.zoom); + pattern = createZoomedPattern(key.pattern); + patternCache.put(key, pattern); + return pattern; + } + + private GradientPattern createZoomedPattern(GradientPattern p1) { + return new GradientPattern(p1.getDevice(), (float) (zoom * p1.x1), + (float) (zoom * p1.y1), (float) (zoom * p1.x2), + (float) (zoom * p1.y2), p1.color1, p1.alpha1, p1.color2, + p1.alpha2); + } + + /** + * @see Graphics#getClip(Rectangle) + */ + public Rectangle getClip(Rectangle rect) { + graphics.getClip(rect); + int x = (int) (rect.x / zoom); + int y = (int) (rect.y / zoom); + /* + * If the clip rectangle is queried, perform an inverse zoom, and take + * the ceiling of the resulting double. This is necessary because + * forward scaling essentially performs a floor() function. Without + * this, figures will think that they don't need to paint when actually + * they do. + */ + rect.width = (int) Math.ceil(rect.right() / zoom) - x; + rect.height = (int) Math.ceil(rect.bottom() / zoom) - y; + rect.x = x; + rect.y = y; + return rect; + } + + /** + * @see Graphics#getFillRule() + */ + public int getFillRule() { + return graphics.getFillRule(); + } + + /** + * @see Graphics#getFont() + */ + public Font getFont() { + return getLocalFont(); + } + + /** + * @see Graphics#getFontMetrics() + */ + public FontMetrics getFontMetrics() { + return FigureUtilities.getFontMetrics(localFont); + } + + /** + * @see Graphics#getForegroundColor() + */ + public Color getForegroundColor() { + return graphics.getForegroundColor(); + } + + /** + * @see Graphics#getInterpolation() + */ + public int getInterpolation() { + return graphics.getInterpolation(); + } + + /** + * @see Graphics#getLineCap() + */ + public int getLineCap() { + return graphics.getLineCap(); + } + + /** + * @see Graphics#getLineJoin() + */ + public int getLineJoin() { + return graphics.getLineJoin(); + } + + /** + * @see Graphics#getLineStyle() + */ + public int getLineStyle() { + return graphics.getLineStyle(); + } + + /** + * @see Graphics#getLineWidth() + */ + public int getLineWidth() { + return (int) getLocalLineWidth(); + } + + public float getLineWidthFloat() { + return getLocalLineWidth(); + } + + protected final Font getLocalFont() { + return localFont; + } + + protected final float getLocalLineWidth() { + return localLineWidth; + } + + /** + * @see Graphics#getTextAntialias() + */ + public int getTextAntialias() { + return graphics.getTextAntialias(); + } + + /** + * @see Graphics#getXORMode() + */ + public boolean getXORMode() { + return graphics.getXORMode(); + } + + /** + * @see Graphics#popState() + */ + public void popState() { + graphics.popState(); + stackPointer--; + restoreLocalState(stack.get(stackPointer)); + if (lastClipPath != null) { + lastClipPath.dispose(); + lastClipPath = null; + } + } + + /** + * @see Graphics#pushState() + */ + public void pushState() { + if (stack.size() > stackPointer) { + State s = stack.get(stackPointer); + s.setValues(zoom, fractionalX, fractionalY, getLocalFont(), + getLocalLineWidth(), localDash, localBackground, + localForeground); + } else { + stack.add(new State(zoom, fractionalX, fractionalY, getLocalFont(), + getLocalLineWidth(), localDash, localBackground, + localForeground)); + } + stackPointer++; + + graphics.pushState(); + } + + protected void restoreLocalState(State state) { + this.fractionalX = state.appliedX; + this.fractionalY = state.appliedY; + setScale(state.zoom); + setLocalFont(state.font); + setLocalLineWidth(state.lineWidth); + setLocalLineDash(state.lineDash); + setLocalBackgroundPattern(state.background); + setLocalForegroundPattern(state.foreground); + } + + /** + * @see Graphics#restoreState() + */ + public void restoreState() { + graphics.restoreState(); + restoreLocalState(stack.get(stackPointer - 1)); + } + + /** + * @see Graphics#scale(double) + */ + public void scale(double amount) { + setScale(zoom * amount); + } + + /** + * This method requires advanced graphics support. A check should be made to + * ensure advanced graphics is supported in the user's environment before + * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. + * + * @see Graphics#setAlpha(int) + */ + public void setAlpha(int alpha) { + graphics.setAlpha(alpha); + } + + /** + * This method requires advanced graphics support. A check should be made to + * ensure advanced graphics is supported in the user's environment before + * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. + * + * @see Graphics#setAntialias(int) + */ + public void setAntialias(int value) { + graphics.setAntialias(value); + } + + /** + * @see Graphics#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color rgb) { + graphics.setBackgroundColor(rgb); + } + + /** + * @see Graphics#setClip(Rectangle) + */ + public void setClip(Rectangle r) { + graphics.setClip(zoomClipRect(r)); + } + + /** + * @see Graphics#setFillRule(int) + */ + public void setFillRule(int rule) { + graphics.setFillRule(rule); + } + + /** + * @see Graphics#setFont(Font) + */ + public void setFont(Font f) { + setLocalFont(f); + } + + /** + * @see Graphics#setForegroundColor(Color) + */ + public void setForegroundColor(Color rgb) { + graphics.setForegroundColor(rgb); + } + + /** + * This method requires advanced graphics support. A check should be made to + * ensure advanced graphics is supported in the user's environment before + * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. + * + * @see org.eclipse.draw2d.Graphics#setInterpolation(int) + */ + public void setInterpolation(int interpolation) { + graphics.setInterpolation(interpolation); + } + + /** + * @see Graphics#setLineCap(int) + */ + public void setLineCap(int cap) { + graphics.setLineCap(cap); + } + + /** + * @see Graphics#setLineDash(int[]) + */ + public void setLineDash(int[] dash) { + setLocalLineDash(dash); + } + + private void setLocalLineDash(int[] dash) { + localDash = dash; + if (dash != null) + graphics.setLineDash(zoomDash(dash)); + } + + /** + * @see Graphics#setLineJoin(int) + */ + public void setLineJoin(int join) { + graphics.setLineJoin(join); + } + + /** + * @see Graphics#setLineStyle(int) + */ + public void setLineStyle(int style) { + graphics.setLineStyle(style); + } + + /** + * @see Graphics#setLineWidth(int) + */ + public void setLineWidth(int width) { + setLineWidthFloat(width); + } + + public void setLineWidthFloat(float width) { + setLocalLineWidth(width); + } + + private void setLocalFont(Font f) { + localFont = f; + graphics.setFont(zoomFont(f)); + } + + private void setLocalLineWidth(float width) { + localLineWidth = width; + graphics.setLineWidth((int) zoomLineWidth(width)); + } + + void setScale(double value) { + if (zoom == value) + return; + this.zoom = value; + graphics.setFont(zoomFont(getLocalFont())); + graphics.setLineWidth((int) zoomLineWidth(getLocalLineWidth())); + if (localDash != null) + graphics.setLineDash(zoomDash(localDash)); + if (localBackground != null) + graphics.setBackgroundPattern(zoomPattern(localBackground)); + if (localForeground != null) + graphics.setForegroundPattern(zoomPattern(localForeground)); + } + + /** + * This method requires advanced graphics support. A check should be made to + * ensure advanced graphics is supported in the user's environment before + * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}. + * + * @see Graphics#setTextAntialias(int) + */ + public void setTextAntialias(int value) { + graphics.setTextAntialias(value); + } + + /** + * @see Graphics#setXORMode(boolean) + */ + public void setXORMode(boolean b) { + graphics.setXORMode(b); + } + + /** + * @see Graphics#translate(int, int) + */ + public void translate(int dx, int dy) { + // fractionalX/Y is the fractional part left over from previous + // translates that gets lost in the integer approximation. + double dxFloat = dx * zoom + fractionalX; + double dyFloat = dy * zoom + fractionalY; + fractionalX = dxFloat - Math.floor(dxFloat); + fractionalY = dyFloat - Math.floor(dyFloat); + graphics.translate((int) Math.floor(dxFloat), + (int) Math.floor(dyFloat)); + } + + private Rectangle zoomClipRect(Rectangle r) { + tempRECT.x = (int) (Math.floor(r.x * zoom + fractionalX)); + tempRECT.y = (int) (Math.floor(r.y * zoom + fractionalY)); + tempRECT.width = (int) (Math + .ceil(((r.x + r.width) * zoom + fractionalX))) - tempRECT.x; + tempRECT.height = (int) (Math + .ceil(((r.y + r.height) * zoom + fractionalY))) - tempRECT.y; + return tempRECT; + } + + private Rectangle zoomFillRect(int x, int y, int w, int h) { + tempRECT.x = (int) (Math.floor((x * zoom + fractionalX))); + tempRECT.y = (int) (Math.floor((y * zoom + fractionalY))); + tempRECT.width = (int) (Math.floor(((x + w - 1) * zoom + fractionalX))) + - tempRECT.x + 1; + tempRECT.height = (int) (Math.floor(((y + h - 1) * zoom + fractionalY))) + - tempRECT.y + 1; + return tempRECT; + } + + private Font zoomFont(Font f) { + if (f == null) + f = Display.getCurrent().getSystemFont(); + FontData data = getCachedFontData(f); + int zoomedFontHeight = zoomFontHeight(data.getHeight()); + allowText = zoomedFontHeight > 0; + fontKey.setValues(f, zoomedFontHeight); + return getCachedFont(fontKey); + } + + protected int zoomFontHeight(int height) { + return (int) (zoom * height); + } + + protected float zoomLineWidth(float w) { + return (float) (zoom * w); + } + + private int[] zoomPointList(int[] points) { + int[] scaled = null; + + // Look in cache for a integer array with the same length as 'points' + for (int i = 0; i < intArrayCache.length; i++) { + if (intArrayCache[i].length == points.length) { + scaled = intArrayCache[i]; + + // Move this integer array up one notch in the array + if (i != 0) { + int[] temp = intArrayCache[i - 1]; + intArrayCache[i - 1] = scaled; + intArrayCache[i] = temp; + } + } + } + + // If no match is found, take the one that is last and resize it. + if (scaled == null) { + intArrayCache[intArrayCache.length - 1] = new int[points.length]; + scaled = intArrayCache[intArrayCache.length - 1]; + } + + // Scale the points + for (int i = 0; (i + 1) < points.length; i += 2) { + scaled[i] = (int) (Math.floor((points[i] * zoom + fractionalX))); + scaled[i + 1] = (int) (Math + .floor((points[i + 1] * zoom + fractionalY))); + } + return scaled; + } + + protected Rectangle zoomRect(int x, int y, int w, int h) { + tempRECT.x = (int) (Math.floor(x * zoom + fractionalX)); + tempRECT.y = (int) (Math.floor(y * zoom + fractionalY)); + tempRECT.width = (int) (Math.floor(((x + w) * zoom + fractionalX))) + - tempRECT.x; + tempRECT.height = (int) (Math.floor(((y + h) * zoom + fractionalY))) + - tempRECT.y; + return tempRECT; + } + + private TextLayout zoomTextLayout(TextLayout layout) { + TextLayout zoomed = new TextLayout(Display.getCurrent()); + zoomed.setText(layout.getText()); + + int zoomWidth = -1; + + if (layout.getWidth() != -1) + zoomWidth = ((int) (layout.getWidth() * zoom)); + + if (zoomWidth < -1 || zoomWidth == 0) + return null; + + zoomed.setFont(zoomFont(layout.getFont())); + zoomed.setAlignment(layout.getAlignment()); + zoomed.setAscent(layout.getAscent()); + zoomed.setDescent(layout.getDescent()); + zoomed.setOrientation(layout.getOrientation()); + zoomed.setSegments(layout.getSegments()); + zoomed.setSpacing(layout.getSpacing()); + zoomed.setTabs(layout.getTabs()); + + zoomed.setWidth(zoomWidth); + int length = layout.getText().length(); + if (length > 0) { + int start = 0, offset = 1; + TextStyle style = null, lastStyle = layout.getStyle(0); + for (; offset <= length; offset++) { + if (offset != length + && (style = layout.getStyle(offset)) == lastStyle) + continue; + int end = offset - 1; + + if (lastStyle != null) { + TextStyle zoomedStyle = new TextStyle( + zoomFont(lastStyle.font), lastStyle.foreground, + lastStyle.background); + zoomedStyle.metrics = lastStyle.metrics; + zoomedStyle.rise = lastStyle.rise; + zoomedStyle.strikeout = lastStyle.strikeout; + zoomedStyle.underline = lastStyle.underline; + zoomed.setStyle(zoomedStyle, start, end); + } + lastStyle = style; + start = offset; + } + } + return zoomed; + } + + private Point zoomTextPoint(int x, int y) { + if (localCache.font != localFont) { + //Font is different, re-calculate its height + FontMetrics metric = FigureUtilities.getFontMetrics(localFont); + localCache.height = metric.getHeight() - metric.getDescent(); + localCache.font = localFont; + } + if (targetCache.font != graphics.getFont()) { + FontMetrics metric = graphics.getFontMetrics(); + targetCache.font = graphics.getFont(); + targetCache.height = metric.getHeight() - metric.getDescent(); + } + return new Point(((int) (Math.floor((x * zoom) + fractionalX))), + (int) (Math.floor((y + localCache.height - 1) * zoom + - targetCache.height + 1 + fractionalY))); + } + + protected Graphics getGraphics() { + return graphics; + } + + /** + * @see org.eclipse.draw2d.Graphics#drawPath(org.eclipse.swt.graphics.Path) + */ + @Override + public void drawPath(Path path) { + Path zoomPath = zoomPath(path); + getGraphics().drawPath(zoomPath); + zoomPath.dispose(); + } + + /** + * @see org.eclipse.draw2d.Graphics#fillPath(org.eclipse.swt.graphics.Path) + */ + @Override + public void fillPath(Path path) { + Path zoomPath = zoomPath(path); + getGraphics().fillPath(zoomPath); + zoomPath.dispose(); + } + + /** + * @param path + * @return + */ + private Path zoomPath(Path path) { + PathData data = path.getPathData(); + Path newPath = new Path(path.getDevice()); + int index = 0; + for (byte type : data.types) { + switch (type) { + case SWT.PATH_MOVE_TO: + newPath.moveTo((float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++])); + break; + case SWT.PATH_LINE_TO: + newPath.lineTo((float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++])); + break; + case SWT.PATH_CUBIC_TO: + newPath.cubicTo((float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++])); + break; + case SWT.PATH_QUAD_TO: + newPath.quadTo((float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++]), + (float) (zoom * data.points[index++])); + break; + case SWT.PATH_CLOSE: + newPath.close(); + break; + } + } + return newPath; + } + + /** + * @see org.eclipse.draw2d.Graphics#setBackgroundPattern(org.eclipse.swt.graphics.Pattern) + */ + @Override + public void setBackgroundPattern(Pattern pattern) { + setLocalBackgroundPattern(pattern); + } + + /** + * @see org.eclipse.draw2d.Graphics#setForegroundPattern(org.eclipse.swt.graphics.Pattern) + */ + @Override + public void setForegroundPattern(Pattern pattern) { + setLocalForegroundPattern(pattern); + } + + private void setLocalBackgroundPattern(Pattern pattern) { + localBackground = pattern; + graphics.setBackgroundPattern(zoomPattern(pattern)); + } + + private void setLocalForegroundPattern(Pattern pattern) { + localForeground = pattern; + graphics.setForegroundPattern(zoomPattern(pattern)); + } + + /** + * @param dash + * @return + */ + private int[] zoomDash(int[] dash) { + if (dash == null || dash.length == 0) { + dash = new int[1]; + dash[0] = 1; + return dash; + } + int[] d = new int[dash.length]; + for (int i = 0; i < d.length; i++) { + d[i] = Math.max(1, (int) (zoom * dash[i])); + } + return d; + } + + protected Pattern zoomPattern(Pattern pattern) { + if (!(pattern instanceof GradientPattern)) + return pattern; + patternKey.setValues((GradientPattern) pattern, zoom); + return getCachedPattern(patternKey); + } + + /** + * @see org.eclipse.draw2d.Graphics#rotate(float) + */ + @Override + public void rotate(float degrees) { + graphics.rotate(degrees); + } + + public void translate(float dx, float dy) { + graphics.translate(dx, dy); + } + + private Path lastClipPath = null; + + public void setClip(Path path) { + Path p = path == null ? null : zoomPath(path); + graphics.setClip(p); + if (lastClipPath != null) { + lastClipPath.dispose(); + lastClipPath = null; + } + if (p != path) { + lastClipPath = p; + } + } + + /** + * @see org.eclipse.draw2d.Graphics#clipPath(org.eclipse.swt.graphics.Path) + */ + public void clipPath(Path path) { + Path scaledPath = createScaledPath(path); + try { + graphics.clipPath(scaledPath); + } finally { + scaledPath.dispose(); + } + } + + /** + * Scales given path by zoom factor + * + * @param path + * Path to be scaled + * @return Scaled path + */ + private Path createScaledPath(Path path) { + PathData p = path.getPathData(); + for (int i = 0; i < p.points.length; i += 2) { + p.points[i] = (float) (p.points[i] * zoom + fractionalX); + p.points[i + 1] = (float) (p.points[i + 1] * zoom + fractionalY); + } + Path scaledPath = new Path(path.getDevice()); + int index = 0; + for (int i = 0; i < p.types.length; i++) { + byte type = p.types[i]; + switch (type) { + case SWT.PATH_MOVE_TO: + scaledPath.moveTo(p.points[index], p.points[index + 1]); + index += 2; + break; + case SWT.PATH_LINE_TO: + scaledPath.lineTo(p.points[index], p.points[index + 1]); + index += 2; + break; + case SWT.PATH_CUBIC_TO: + scaledPath.cubicTo(p.points[index], p.points[index + 1], + p.points[index + 2], p.points[index + 3], + p.points[index + 4], p.points[index + 5]); + index += 6; + break; + case SWT.PATH_QUAD_TO: + scaledPath.quadTo(p.points[index], p.points[index + 1], + p.points[index + 2], p.points[index + 3]); + index += 4; + break; + case SWT.PATH_CLOSE: + scaledPath.close(); + break; + } + } + return scaledPath; + } + + // ========================================================== + // Since 3.5 + // ========================================================== + + public boolean getAdvanced() { + return graphics.getAdvanced(); + } + + public LineAttributes getLineAttributes() { + LineAttributes a = graphics.getLineAttributes(); + a.width = getLocalLineWidth(); + return a; + } + + public float getLineMiterLimit() { + return graphics.getLineMiterLimit(); + } + + public void setAdvanced(boolean advanced) { + graphics.setAdvanced(advanced); + } + + public void setLineMiterLimit(float miterLimit) { + graphics.setLineMiterLimit(miterLimit); + } + + public void setLineAttributes(LineAttributes attributes) { + graphics.setLineAttributes(attributes); + setLocalLineWidth(attributes.width); + } + + public void setLineDash(float[] value) { + graphics.setLineDash(value); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/SimpleColorMaskGraphics.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/SimpleColorMaskGraphics.java index 7036f56d8..6557131a1 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/SimpleColorMaskGraphics.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/graphics/SimpleColorMaskGraphics.java @@ -1,58 +1,58 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.draw2d.graphics; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.swt.graphics.RGB; - -/** - * @author Frank Shaka - * - */ -public class SimpleColorMaskGraphics extends ColorMaskGraphics { - - private RGB color; - - /** - * @param delegate - */ - public SimpleColorMaskGraphics(Graphics delegate, RGB color) { - super(delegate, color); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.draw2d.graphics.ColorMaskGraphics#init(java.lang.Object[]) - */ - @Override - protected void init(Object... args) { - this.color = (RGB) args[0]; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.draw2d.graphics.ColorMaskGraphics#getMaskColor(org.eclipse - * .swt.graphics.RGB) - */ - @Override - protected RGB getMaskColor(RGB rgb) { - return color; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.draw2d.graphics; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.swt.graphics.RGB; + +/** + * @author Frank Shaka + * + */ +public class SimpleColorMaskGraphics extends ColorMaskGraphics { + + private RGB color; + + /** + * @param delegate + */ + public SimpleColorMaskGraphics(Graphics delegate, RGB color) { + super(delegate, color); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.draw2d.graphics.ColorMaskGraphics#init(java.lang.Object[]) + */ + @Override + protected void init(Object... args) { + this.color = (RGB) args[0]; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.draw2d.graphics.ColorMaskGraphics#getMaskColor(org.eclipse + * .swt.graphics.RGB) + */ + @Override + protected RGB getMaskColor(RGB rgb) { + return color; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseDragEvent.java b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseDragEvent.java index a3afe8e34..8a9010bcf 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseDragEvent.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseDragEvent.java @@ -1,98 +1,98 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.event; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - */ -public class MouseDragEvent extends MouseEvent { - - /** - * The SWT mouse down event that initially triggered this drag event. - */ - protected org.eclipse.swt.events.MouseEvent startingSWTEvent; - - /** - * The location of the mouse cursor where this drag event got initiated by a - * mouse down event. - */ - public Point startingLocation; - - /** - * The part which was under the mouse cursor when this drag event got - * initiated. - */ - public IPart source; - - public MouseDragEvent(org.eclipse.swt.events.MouseEvent startEvent, - org.eclipse.swt.events.MouseEvent currentEvent, IPart target, - IPart source, Point startLoc, Point currentLoc, boolean leftOrRight) { - this(startEvent, currentEvent, target, source, startLoc, currentLoc, - leftOrRight, 0); - } - - public MouseDragEvent(org.eclipse.swt.events.MouseEvent startEvent, - org.eclipse.swt.events.MouseEvent currentEvent, IPart target, - IPart source, Point startLoc, Point currentLoc, - boolean leftOrRight, int state) { - super(currentEvent, target, leftOrRight, currentLoc, state); - this.startingSWTEvent = startEvent; - this.startingLocation = startLoc; - this.source = source; - } - - public static MouseDragEvent createEvent( - org.eclipse.swt.events.MouseEvent current, MouseDragEvent prev, - Point currentLoc, IPart newTarget) { - return new MouseDragEvent(prev.startingSWTEvent, current, newTarget, - prev.source, prev.startingLocation, currentLoc, - prev.leftOrRight, current.stateMask); - } - -// public MouseDragEvent( MouseDragEvent prev, Point current, IPart hover ) { -// this(prev.host, prev.leftOrRight, prev.startPoint, current, hover, current.getDifference(prev.location) ); -// } - -// public static MouseDragEvent createEvent( IPart host, boolean leftOrRight, int dx, int dy, Point startPoint, Point location ) { -// return new MouseDragEvent( host, leftOrRight, new Dimension(dx, dy), startPoint, location ); -// } - - public static MouseDragEvent createEvent( - org.eclipse.swt.events.MouseEvent start, IPart source, - Point startLoc) { - return new MouseDragEvent(start, start, source, source, startLoc, - startLoc, getButtonState(start.button), start.stateMask); - } - - public Dimension getDisplacement() { - return cursorLocation.getDifference(startingLocation); - } - - public Dimension getSWTDisplacement() { - return new Dimension(currentSWTEvent.x - startingSWTEvent.x, - currentSWTEvent.y - startingSWTEvent.y); - } - - public org.eclipse.swt.events.MouseEvent getStartingSWTEvent() { - return startingSWTEvent; - } - -// public static MouseDragEvent createEvent( MouseDragEvent event, Point location, IPart hover ) { -// return new MouseDragEvent( event, location, hover ); -// } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.event; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + */ +public class MouseDragEvent extends MouseEvent { + + /** + * The SWT mouse down event that initially triggered this drag event. + */ + protected org.eclipse.swt.events.MouseEvent startingSWTEvent; + + /** + * The location of the mouse cursor where this drag event got initiated by a + * mouse down event. + */ + public Point startingLocation; + + /** + * The part which was under the mouse cursor when this drag event got + * initiated. + */ + public IPart source; + + public MouseDragEvent(org.eclipse.swt.events.MouseEvent startEvent, + org.eclipse.swt.events.MouseEvent currentEvent, IPart target, + IPart source, Point startLoc, Point currentLoc, boolean leftOrRight) { + this(startEvent, currentEvent, target, source, startLoc, currentLoc, + leftOrRight, 0); + } + + public MouseDragEvent(org.eclipse.swt.events.MouseEvent startEvent, + org.eclipse.swt.events.MouseEvent currentEvent, IPart target, + IPart source, Point startLoc, Point currentLoc, + boolean leftOrRight, int state) { + super(currentEvent, target, leftOrRight, currentLoc, state); + this.startingSWTEvent = startEvent; + this.startingLocation = startLoc; + this.source = source; + } + + public static MouseDragEvent createEvent( + org.eclipse.swt.events.MouseEvent current, MouseDragEvent prev, + Point currentLoc, IPart newTarget) { + return new MouseDragEvent(prev.startingSWTEvent, current, newTarget, + prev.source, prev.startingLocation, currentLoc, + prev.leftOrRight, current.stateMask); + } + +// public MouseDragEvent( MouseDragEvent prev, Point current, IPart hover ) { +// this(prev.host, prev.leftOrRight, prev.startPoint, current, hover, current.getDifference(prev.location) ); +// } + +// public static MouseDragEvent createEvent( IPart host, boolean leftOrRight, int dx, int dy, Point startPoint, Point location ) { +// return new MouseDragEvent( host, leftOrRight, new Dimension(dx, dy), startPoint, location ); +// } + + public static MouseDragEvent createEvent( + org.eclipse.swt.events.MouseEvent start, IPart source, + Point startLoc) { + return new MouseDragEvent(start, start, source, source, startLoc, + startLoc, getButtonState(start.button), start.stateMask); + } + + public Dimension getDisplacement() { + return cursorLocation.getDifference(startingLocation); + } + + public Dimension getSWTDisplacement() { + return new Dimension(currentSWTEvent.x - startingSWTEvent.x, + currentSWTEvent.y - startingSWTEvent.y); + } + + public org.eclipse.swt.events.MouseEvent getStartingSWTEvent() { + return startingSWTEvent; + } + +// public static MouseDragEvent createEvent( MouseDragEvent event, Point location, IPart hover ) { +// return new MouseDragEvent( event, location, hover ); +// } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseEvent.java b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseEvent.java index d9d3f9d4e..6dd5b65e6 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseEvent.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseEvent.java @@ -1,114 +1,114 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.event; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - * @version 2005 - */ -public class MouseEvent { - - /** - * The current part under the mouse cursor. - */ - public IPart target; - - /** - * True if the mouse button is left, false if - * right. - */ - public boolean leftOrRight; - - /** - * The current location of the mouse cursor, relative to the contents layer. - */ - public Point cursorLocation; - - /** - * The triggering SWT mouse event. - */ - protected org.eclipse.swt.events.MouseEvent currentSWTEvent; - - private boolean consumed = false; - - private int state; - - public MouseEvent(org.eclipse.swt.events.MouseEvent swtEvent, IPart target, - boolean leftOrRight, Point location) { - this(swtEvent, target, leftOrRight, location, swtEvent.stateMask); - } - - public MouseEvent(org.eclipse.swt.events.MouseEvent swtEvent, IPart target, - boolean leftOrRight, Point location, int state) { - this.target = target; - this.leftOrRight = leftOrRight; - this.cursorLocation = location; - this.currentSWTEvent = swtEvent; - this.state = state; - } - - public static MouseEvent createEvent( - org.eclipse.swt.events.MouseEvent swtEvent, IPart host, - Point location, int state) { - return new MouseEvent(swtEvent, host, getButtonState(swtEvent.button), - location, state); - } - - public static MouseEvent createEvent( - org.eclipse.swt.events.MouseEvent swtEvent, IPart host, - Point location) { - return createEvent(swtEvent, host, location, swtEvent.stateMask); - } - -// public static MouseEvent createEvent( org.eclipse.swt.events.MouseEvent me, IPart host ) { -// return new MouseEvent( me, host, getButton( me.button ), new Point( me.x, me.y ) ); -// } - - public static boolean getButtonState(int button) { - return (button == 1 || button == 0); - } - - /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return cursorLocation - + "," + (leftOrRight ? "left" : "right") + "," + target; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - public boolean isConsumed() { - return consumed; - } - - public void consume() { - consumed = true; - } - - public org.eclipse.swt.events.MouseEvent getCurrentSWTEvent() { - return currentSWTEvent; - } - - public boolean isState(int bitMask) { - return (state & bitMask) == bitMask; - } - - // public void consume() { - // if (source!=null) source.consume(); - // } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.event; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + * @version 2005 + */ +public class MouseEvent { + + /** + * The current part under the mouse cursor. + */ + public IPart target; + + /** + * True if the mouse button is left, false if + * right. + */ + public boolean leftOrRight; + + /** + * The current location of the mouse cursor, relative to the contents layer. + */ + public Point cursorLocation; + + /** + * The triggering SWT mouse event. + */ + protected org.eclipse.swt.events.MouseEvent currentSWTEvent; + + private boolean consumed = false; + + private int state; + + public MouseEvent(org.eclipse.swt.events.MouseEvent swtEvent, IPart target, + boolean leftOrRight, Point location) { + this(swtEvent, target, leftOrRight, location, swtEvent.stateMask); + } + + public MouseEvent(org.eclipse.swt.events.MouseEvent swtEvent, IPart target, + boolean leftOrRight, Point location, int state) { + this.target = target; + this.leftOrRight = leftOrRight; + this.cursorLocation = location; + this.currentSWTEvent = swtEvent; + this.state = state; + } + + public static MouseEvent createEvent( + org.eclipse.swt.events.MouseEvent swtEvent, IPart host, + Point location, int state) { + return new MouseEvent(swtEvent, host, getButtonState(swtEvent.button), + location, state); + } + + public static MouseEvent createEvent( + org.eclipse.swt.events.MouseEvent swtEvent, IPart host, + Point location) { + return createEvent(swtEvent, host, location, swtEvent.stateMask); + } + +// public static MouseEvent createEvent( org.eclipse.swt.events.MouseEvent me, IPart host ) { +// return new MouseEvent( me, host, getButton( me.button ), new Point( me.x, me.y ) ); +// } + + public static boolean getButtonState(int button) { + return (button == 1 || button == 0); + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return cursorLocation + + "," + (leftOrRight ? "left" : "right") + "," + target; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + public boolean isConsumed() { + return consumed; + } + + public void consume() { + consumed = true; + } + + public org.eclipse.swt.events.MouseEvent getCurrentSWTEvent() { + return currentSWTEvent; + } + + public boolean isState(int bitMask) { + return (state & bitMask) == bitMask; + } + + // public void consume() { + // if (source!=null) source.consume(); + // } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseWheelEvent.java b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseWheelEvent.java index 69b0047db..3fd48d70b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseWheelEvent.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/event/MouseWheelEvent.java @@ -1,47 +1,47 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.event; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.swt.widgets.Event; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - */ -public class MouseWheelEvent extends MouseEvent { - - public boolean upOrDown; - - public boolean doIt = true; - - public MouseWheelEvent(IPart host, Point location, boolean upOrDown) { - this(host, location, upOrDown, 0); - } - - /** - * @param host - * @param location - */ - public MouseWheelEvent(IPart host, Point location, boolean upOrDown, - int state) { - super(null, host, true, location, state); - this.upOrDown = upOrDown; - } - - public static MouseWheelEvent createEvent(IPart host, Event wheelEvent) { - return new MouseWheelEvent(host, new Point(wheelEvent.x, wheelEvent.y), - wheelEvent.count > 0, wheelEvent.stateMask); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.event; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.swt.widgets.Event; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + */ +public class MouseWheelEvent extends MouseEvent { + + public boolean upOrDown; + + public boolean doIt = true; + + public MouseWheelEvent(IPart host, Point location, boolean upOrDown) { + this(host, location, upOrDown, 0); + } + + /** + * @param host + * @param location + */ + public MouseWheelEvent(IPart host, Point location, boolean upOrDown, + int state) { + super(null, host, true, location, state); + this.upOrDown = upOrDown; + } + + public static MouseWheelEvent createEvent(IPart host, Event wheelEvent) { + return new MouseWheelEvent(host, new Point(wheelEvent.x, wheelEvent.y), + wheelEvent.count > 0, wheelEvent.stateMask); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/event/PartsEventDispatcher.java b/bundles/org.xmind.gef/src/org/xmind/gef/event/PartsEventDispatcher.java index 668e20fa8..370ecb4de 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/event/PartsEventDispatcher.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/event/PartsEventDispatcher.java @@ -1,1411 +1,1430 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.event; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LightweightSystem; -import org.eclipse.draw2d.RangeModel; -import org.eclipse.draw2d.ToolTipHelper; -import org.eclipse.draw2d.Viewport; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTarget; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.DropTargetListener; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.acc.IAccessible; -import org.xmind.gef.dnd.DndData; -import org.xmind.gef.dnd.IDndClient; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.draw2d.KeepVisibleToolTipHelper; -import org.xmind.gef.part.GraphicalEditPart; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.status.IStatusMachine; -import org.xmind.gef.tool.AbstractTool; -import org.xmind.gef.tool.IDragDropHandler; -import org.xmind.gef.tool.IGraphicalTool; -import org.xmind.gef.tool.ITool; - -/** - * @author Brian Sun - */ -public class PartsEventDispatcher extends ViewerEventDispatcher implements - DropTargetListener { - - protected class PartAccessibilityDispatcher extends AccessibilityDispatcher { - - private IAccessible get(int childID) { - if (childID == ACC.CHILDID_SELF || childID == ACC.CHILDID_NONE) { - IPart focused = getFocusedPart(); - if (focused != null) { - IAccessible acc = (IAccessible) focused - .getAdapter(IAccessible.class); - if (acc != null) - return acc; - } - IPart contents = getViewer().getRootPart().getContents(); - if (contents == null) - return null; - return (IAccessible) contents.getAdapter(IAccessible.class); - } - return getViewer().getAccessibleRegistry().getAccessible(childID); - } - - public void getChildAtPoint(AccessibleControlEvent e) { - IPart part = findPart(e.x, e.y); - if (part == null) - return; - IAccessible acc = (IAccessible) part.getAdapter(IAccessible.class); - if (acc != null) { - e.childID = acc.getAccessibleId(); - } - } - - public void getChildCount(AccessibleControlEvent e) { - e.detail = getViewer().getAccessibleRegistry().getNumAccessibles(); - } - - public void getChildren(AccessibleControlEvent e) { - e.children = getViewer().getAccessibleRegistry() - .getAllAccessibleIDs(); - } - - public void getDefaultAction(AccessibleControlEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String defaultAction = acc.getDefaultAction(); - if (defaultAction != null) - e.result = defaultAction; - } - } - - public void getFocus(AccessibleControlEvent e) { - if (control.isFocusControl()) { - IPart focusedPart = getFocusedPart(); - if (focusedPart != null) { - IAccessible acc = (IAccessible) focusedPart - .getAdapter(IAccessible.class); - if (acc != null) { - e.childID = acc.getAccessibleId(); - return; - } - } - e.childID = ACC.CHILDID_SELF; - } else { - e.childID = ACC.CHILDID_NONE; - } - } - - private IPart getFocusedPart() { - Object focused = getViewer().getFocused(); - return focused == null ? null : getViewer().getSelectionSupport() - .findSelectablePart(focused); - } - - public void getLocation(AccessibleControlEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - Rectangle r = acc.getLocation(); - if (r != null) { - e.x = r.x; - e.y = r.y; - if (r.width >= 0) - e.width = r.width; - if (r.height >= 0) - e.height = r.height; - } - } - } - - public void getRole(AccessibleControlEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - int role = acc.getRole(); - if (role >= 0) { - e.detail = role; - } - } - } - - public void getSelection(AccessibleControlEvent e) { - List selectedParts = getViewer().getSelectionSupport() - .getPartSelection(); - if (selectedParts.isEmpty()) { - if (getViewer().getControl().isFocusControl()) { - e.childID = ACC.CHILDID_SELF; - } else { - e.childID = ACC.CHILDID_NONE; - } - return; - } - - List childIds = new ArrayList( - selectedParts.size()); - for (IPart p : selectedParts) { - IAccessible acc = (IAccessible) p.getAdapter(IAccessible.class); - if (acc != null) { - childIds.add(acc.getAccessibleId()); - } - } - if (childIds.isEmpty()) { - e.childID = ACC.CHILDID_NONE; - } else { - e.childID = ACC.CHILDID_MULTIPLE; - e.children = childIds.toArray(); - } - } - - public void getState(AccessibleControlEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - int state = acc.getState(); - if (state >= 0) { - e.detail = state; - } - } - } - - public void getValue(AccessibleControlEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String value = acc.getValue(); - if (value != null) { - e.result = value; - } - } - } - - public void getDescription(AccessibleEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String description = acc.getDescription(); - if (description != null) { - e.result = description; - } - } - } - - public void getHelp(AccessibleEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String help = acc.getHelp(); - if (help != null) { - e.result = help; - } - } - } - - public void getKeyboardShortcut(AccessibleEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String keyboardShortcut = acc.getKeyboardShortcut(); - if (keyboardShortcut != null) - e.result = keyboardShortcut; - } - } - - public void getName(AccessibleEvent e) { - IAccessible acc = get(e.childID); - if (acc != null) { - String name = acc.getName(); - if (name != null) { - e.result = name; - } - } - } - - } - - private static int LONG_PRESSING_ACTIVATION_TIME = 500; - - private ToolTipHelper toolTipHelper; - - private Shell shell = null; - - private DropTarget dropTarget = null; - - private boolean ignoreDoubleClicking = false; - - private boolean ignoreLongPressing = false; - - private boolean ignoreDragging = false; - - private boolean ignoreNextMouseUp = false; - - private MouseDragEvent lastDragEvent = null; - - private MouseEvent currentMouseEvent = null; - - private DragDropEvent currentDropEvent = null; - - private IDragDropHandler dropHandler = null; - - private int pressedMouseButton = 0; - - private PartAccessibilityDispatcher accDispatcher = null; - - private PropertyChangeListener viewportScrollListener = null; - - private RangeModel horizontalRangeModel = null; - - private RangeModel verticalRangeModel = null; - - private boolean mouseHovering = false; - - /** - * @param domain - */ - public PartsEventDispatcher(IGraphicalViewer viewer) { - super(viewer); - } - - public EditDomain getDomain() { - return getViewer().getEditDomain(); - } - - protected void onActivated() { - super.onActivated(); - setIgnoreDoubleClicking(false); - } - - protected void onDeactivated() { - hideToolTip(); - cancelLongPressing(); - - lastDragEvent = null; - currentMouseEvent = null; - currentDropEvent = null; - dropHandler = null; - - setIgnoreDoubleClicking(true); - } - - @Override - public void setControl(Control c) { - if (c == control) - return; - if (control != null && !control.isDisposed()) - throw new RuntimeException( - "Can not set control again once it has been set"); //$NON-NLS-1$ - if (c != null) - c.addDisposeListener(new org.eclipse.swt.events.DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (toolTipHelper != null) - toolTipHelper.dispose(); - } - }); - control = c; - - createDropTarget(c); - } - - protected void createDropTarget(Control c) { - if (dropTarget != null) { - dropTarget.dispose(); - dropTarget = null; - } - - if (getDndSupport() != null) { - dropTarget = new DropTarget(c, getDndSupport().getStyle()); - dropTarget.setTransfer(getDndSupport().getTransfers()); - dropTarget.addDropListener(this); - c.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - disposeDropTarget(); - } - }); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.event.ViewerEventDispatcher#dndSupportChanged(org.xmind - * .gef.dnd.IDndSupport, org.xmind.gef.dnd.IDndSupport) - */ - @Override - protected void dndSupportChanged(IDndSupport oldDndSupport, - IDndSupport newDndSupport) { - super.dndSupportChanged(oldDndSupport, newDndSupport); - if (control != null && !control.isDisposed()) { - createDropTarget(control); - } - } - - protected DropTarget getDropTarget() { - return dropTarget; - } - - protected void disposeDropTarget() { - if (dropTarget != null) { - if (!dropTarget.isDisposed()) { - dropTarget.removeDropListener(this); - } - dropTarget.dispose(); - dropTarget = null; - } - } - - /** - * @param controlX - * @param controlY - * @return - */ - protected Point convertPoint(int controlX, int controlY) { - Point p = new Point(controlX, controlY); - if (getViewer().getControl() != null - && !getViewer().getControl().isDisposed()) { -// if (isScaleLocation()) { - p = getViewer().computeToLayer(p, true); -// } else { -// p.translate(getViewer().getScrollPosition()); -// } - } - return p; - } - - /** - * @param me - * @return - */ - protected MouseEvent convertMouse(org.eclipse.swt.events.MouseEvent me) { - Point pos = convertPoint(me.x, me.y); - return MouseEvent.createEvent(me, findPart(me.x, me.y), pos); - } - - protected MouseEvent convertMouse(org.eclipse.swt.events.MouseEvent me, - IPart host) { - Point pos = convertPoint(me.x, me.y); - return MouseEvent.createEvent(me, host, pos); - } - - /** - * @param me - * @return - */ - protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me) { - Point pos = convertPoint(me.x, me.y); - return MouseDragEvent.createEvent(me, lastDragEvent, pos, - findPart(me.x, me.y)); - } - - protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me, - IPart host) { - Point pos = convertPoint(me.x, me.y); - return MouseDragEvent.createEvent(me, lastDragEvent, pos, host); - } - - protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me, - MouseEvent current) { - return MouseDragEvent.createEvent(me, lastDragEvent, - current.cursorLocation, current.target); - } - - /** - * @param ke - * @return - */ - protected KeyEvent convertKey(org.eclipse.swt.events.KeyEvent ke) { - return KeyEvent.createEvent(ke, isImeOpened()); - } - - protected MouseWheelEvent convertWheel(org.eclipse.swt.widgets.Event e) { - return MouseWheelEvent.createEvent(findPart(e.x, e.y), e); - } - - /** - * @param me - * @return - */ - protected MouseDragEvent createDragEvent( - org.eclipse.swt.events.MouseEvent me) { - Point startPoint = convertPoint(me.x, me.y); - return MouseDragEvent.createEvent(me, findPart(me.x, me.y), startPoint); - } - - public PartAccessibilityDispatcher getPartAccessibilityDispatcher() { - if (accDispatcher == null) - accDispatcher = new PartAccessibilityDispatcher(); - return accDispatcher; - } - - @Override - protected AccessibilityDispatcher getAccessibilityDispatcher() { - return getPartAccessibilityDispatcher(); - } - - protected IPart findPart(int controlX, int controlY) { - IPart part = getViewer().findPart(controlX, controlY); - return part == null ? getViewer().getRootPart() : part; - } - -// /** -// * @param position -// */ -// protected IPart findPart(Point position) { -// return findPart(getViewer().getRootPart(), position); -// } -// -// protected IPart findPart(IPart parent, Point position) { -// if (parent == null) -// return null; -// if (parent instanceof IGraphicalEditPart) { -// return (((IGraphicalEditPart) parent).findAt(position)); -// } -// for (IPart p : parent.getChildren()) { -// IPart ret = findPart(p, position); -// if (ret != null) -// return ret; -// } -// return null; -// } - - protected ITool getActiveTool() { - EditDomain domain = getDomain(); - return domain != null && !domain.isDisposed() ? domain.getActiveTool() - : null; - } - - protected boolean isImeOpened() { - if (shell == null) { - if (control != null & !control.isDisposed()) { - shell = control.getShell(); - } else { - Control viewerControl = getViewer().getControl(); - if (viewerControl != null && !viewerControl.isDisposed()) - shell = viewerControl.getShell(); - } - } - return shell == null ? false : shell.getImeInputMode() != SWT.NONE; - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchFocusGained(org.eclipse.swt.events.FocusEvent) - */ - @Override - public void dispatchFocusGained(FocusEvent e) { - if (!isActive()) - return; -// super.dispatchFocusGained(e); - ITool tool = getActiveTool(); - if (tool != null) { - tool.focusGained(getViewer()); - MouseEvent me = currentMouseEvent; - if (me != null) { - updateCursor(me.cursorLocation, me.target); - } - } else { - super.dispatchFocusGained(e); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchFocusLost(org.eclipse.swt.events.FocusEvent) - */ - @Override - public void dispatchFocusLost(FocusEvent e) { - cancelLongPressing(); - if (!isActive()) - return; -// super.dispatchFocusLost(e); - ITool tool = getActiveTool(); - if (tool != null) { - tool.focusLost(getViewer()); - MouseEvent me = currentMouseEvent; - if (me != null) { - updateCursor(me.cursorLocation, me.target); - } - } else { - super.dispatchFocusLost(e); - } - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyPressed(org.eclipse.swt.events.KeyEvent) - */ - @Override - public void dispatchKeyPressed(org.eclipse.swt.events.KeyEvent e) { - if (!isActive()) - return; -// super.dispatchKeyPressed(e); - ITool tool = getActiveTool(); - if (tool != null) { - KeyEvent ke = convertKey(e); - tool.keyDown(ke, getViewer()); - e.doit = !ke.isConsumed(); - MouseEvent me = currentMouseEvent; - if (me != null && isValidGraphicalPart(me.target)) { - updateCursor(me.cursorLocation, me.target); - } - } else { - super.dispatchKeyPressed(e); - } - if ((e.keyCode & SWT.ESC) != 0) { - lastDragEvent = null; - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyReleased(org.eclipse.swt.events.KeyEvent) - */ - @Override - public void dispatchKeyReleased(org.eclipse.swt.events.KeyEvent e) { - if (!isActive()) - return; -// super.dispatchKeyReleased(e); - ITool tool = getActiveTool(); - if (tool != null) { - KeyEvent ke = convertKey(e); - tool.keyUp(ke, getViewer()); - e.doit = !ke.isConsumed(); - MouseEvent me = currentMouseEvent; - if (me != null && isValidGraphicalPart(me.target)) { - updateCursor(me.cursorLocation, me.target); - } - } else { - super.dispatchKeyReleased(e); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyTraversed(org.eclipse.swt.events.TraverseEvent) - */ - @Override - public void dispatchKeyTraversed(TraverseEvent e) { - if (!isActive()) - return; -// super.dispatchKeyTraversed(e); - ITool tool = getActiveTool(); - if (tool != null) { - KeyEvent ke = convertKey(e); - tool.keyTraversed(ke, getViewer()); - e.doit = !ke.isConsumed(); - e.detail = ke.traverse; - MouseEvent me = currentMouseEvent; - if (me != null && isValidGraphicalPart(me.target)) { - updateCursor(me.cursorLocation, me.target); - } - } else { - super.dispatchKeyTraversed(e); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseDoubleClicked(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseDoubleClicked(org.eclipse.swt.events.MouseEvent me) { - if (!isActive()) - return; - -// super.dispatchMouseDoubleClicked(me); - - cancelToolTipShowing(); - - if (ignoresDoubleClicking()) { - setIgnoreDoubleClicking(false); - return; - } - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseDoubleClick(e, getViewer()); - updateCursor(e.cursorLocation, e.target); - ignoreDragging = e.isConsumed() && pressedMouseButton != 0; - } else { - super.dispatchMouseDoubleClicked(me); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseEntered(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseEntered(org.eclipse.swt.events.MouseEvent me) { - if (!isActive()) - return; -// super.dispatchMouseEntered(me); - mouseHovering = false; - hookScrollBars(); - cancelToolTipShowing(); - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseEntered(e, getViewer()); - updateCursor(e.cursorLocation, e.target); - } else { - super.dispatchMouseEntered(me); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseExited(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseExited(org.eclipse.swt.events.MouseEvent me) { - unhookScrollBars(); - if (!isActive()) - return; -// super.dispatchMouseExited(me); - mouseHovering = false; - cancelToolTipShowing(); - hideToolTip(); - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseExited(e, getViewer()); - updateCursor(e.cursorLocation, e.target); - } else { - super.dispatchMouseExited(me); - } - updateFocus(); - } - - private void hookScrollBars() { - Viewport viewport = getViewer().getCanvas().getViewport(); - horizontalRangeModel = viewport.getHorizontalRangeModel(); - horizontalRangeModel - .addPropertyChangeListener(getViewportScrollListener()); - verticalRangeModel = viewport.getVerticalRangeModel(); - verticalRangeModel - .addPropertyChangeListener(getViewportScrollListener()); - } - - private void unhookScrollBars() { - if (horizontalRangeModel != null) { - horizontalRangeModel - .removePropertyChangeListener(getViewportScrollListener()); - horizontalRangeModel = null; - } - if (verticalRangeModel != null) { - verticalRangeModel - .removePropertyChangeListener(getViewportScrollListener()); - verticalRangeModel = null; - } - } - - private PropertyChangeListener getViewportScrollListener() { - if (viewportScrollListener == null) { - viewportScrollListener = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - dispatchViewerScrolled(evt); - } - }; - } - return viewportScrollListener; - } - - protected void dispatchViewerScrolled(PropertyChangeEvent evt) { - if (lastDragEvent != null - || currentDropEvent != null - || Boolean.TRUE.equals(getViewer().getProperties().get( - IGraphicalViewer.VIEWER_IGNORE_SCROLL_EVENT))) - return; - - Display currentDisplay = Display.getCurrent(); - org.eclipse.swt.graphics.Point loc = currentDisplay.getCursorLocation(); - loc = control.toControl(loc); - org.eclipse.swt.graphics.Rectangle bounds = control.getBounds(); - if (bounds.contains(loc)) { - org.eclipse.swt.widgets.Event event = new org.eclipse.swt.widgets.Event(); - org.eclipse.swt.events.MouseEvent last = currentMouseEvent == null ? null - : currentMouseEvent.currentSWTEvent; - if (last != null) { - event.button = last.button; - event.count = last.count; - event.data = last.data; - event.display = last.display; - event.stateMask = last.stateMask; - event.widget = last.widget; - } else { - event.display = currentDisplay; - event.widget = control; - } - event.time = (int) System.currentTimeMillis(); - event.x = loc.x; - event.y = loc.y; - dispatchMouseMoved(new org.eclipse.swt.events.MouseEvent(event)); - } - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseHover(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseHover(org.eclipse.swt.events.MouseEvent me) { - if (!isActive()) - return; - -// super.dispatchMouseHover(me); - mouseHovering = true; - cancelToolTipShowing(); - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseHover(e, getViewer()); - updateCursor(e.cursorLocation, e.target); - updateToolTip(e); - } else { - super.dispatchMouseHover(me); - } - updateFocus(); - } - - public void cancelToolTipShowing() { - // if ( tooltipTimer != null ) { - // tooltipTimer.cancel(); - // tooltipTimer = null; - // } - } - - public void updateToolTip() { - if (control == null || control.isDisposed()) - return; - hideToolTip(); - if (mouseHovering && currentMouseEvent != null) { - updateToolTip(currentMouseEvent, false); - } - } - - protected void updateToolTip(MouseEvent me, boolean useEventTarget) { - Point cp = null; - org.eclipse.swt.events.MouseEvent e = me.getCurrentSWTEvent(); - if (e != null) { - cp = new Point(e.x, e.y); - } else { - cp = getViewer().computeToControl(me.cursorLocation, true); - } - - IPart target = useEventTarget ? me.target : findPart(cp.x, cp.y); - if (target != null && target instanceof IGraphicalPart) { - ITool tool = getActiveTool(); - IFigure tooltip = null; - if (tool instanceof IGraphicalTool) { - tooltip = ((IGraphicalTool) tool).getToolTip(target, - me.cursorLocation); - } - if (tooltip == null && target instanceof IGraphicalEditPart) { - tooltip = ((IGraphicalEditPart) target) - .findTooltipAt(me.cursorLocation); - } - if (tooltip != null) { - Point absolute = new Point(control.toDisplay(cp.x, cp.y)); - getToolTipHelper().displayToolTipNear( - ((IGraphicalPart) target).getFigure(), tooltip, - absolute.x, absolute.y); - return; - } - } - hideToolTip(); - } - - protected ToolTipHelper getToolTipHelper() { - if (toolTipHelper == null) { - if (currentMouseEvent != null) { - IPart target = currentMouseEvent.target; - if (target != null && target instanceof GraphicalEditPart) { - String actionId = ((GraphicalEditPart) target) - .getActionId(); - if (actionId != null - && (actionId.equals("org.xmind.ui.editNotes") || actionId //$NON-NLS-1$ - .equals("org.xmind.ui.editComments"))) { //$NON-NLS-1$ - toolTipHelper = new KeepVisibleToolTipHelper(control); - } else { - toolTipHelper = new ToolTipHelper(control); - } - } - } - } else { - if (currentMouseEvent != null) { - IPart target = currentMouseEvent.target; - if (target != null && target instanceof GraphicalEditPart) { - String actionId = ((GraphicalEditPart) target) - .getActionId(); - if (actionId != null - && (actionId.equals("org.xmind.ui.editNotes") || actionId //$NON-NLS-1$ - .equals("org.xmind.ui.editComments"))) { //$NON-NLS-1$ - if (!(toolTipHelper instanceof KeepVisibleToolTipHelper)) { - toolTipHelper.dispose(); - toolTipHelper = new KeepVisibleToolTipHelper( - control); - } - } else { - if (toolTipHelper instanceof KeepVisibleToolTipHelper) { - toolTipHelper.dispose(); - toolTipHelper = new ToolTipHelper(control); - } - } - } - } - } - - if (toolTipHelper == null) { - toolTipHelper = new ToolTipHelper(control); - } - - return toolTipHelper; - } - - /** - * @param me - */ - protected void updateToolTip(MouseEvent me) { - updateToolTip(me, true); - } - - protected boolean isValidGraphicalPart(IPart host) { - return host != null && host instanceof IGraphicalPart - && host.getStatus().isActive(); - } - - protected void updateFocus() { - IFigure focusableFigure = null; - IPart focusedPart = getViewer().getFocusedPart(); - if (focusedPart instanceof IGraphicalPart) { - IFigure fig = ((IGraphicalPart) focusedPart).getFigure(); - if (fig.isRequestFocusEnabled()) { - focusableFigure = fig; - } - } - setFocus(focusableFigure); - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseMoved(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseMoved(org.eclipse.swt.events.MouseEvent me) { - if (!isActive()) - return; - - /* - * IMPORTANT: IF brainy is running on JDK 1.6beta, the sentence below - * will fix a huge bug. - */ - if (me.x > 0x8fff) { - me.x -= 65536; - } - /* IMPORTANT: end IF. */ - -// super.dispatchMouseMoved(me); - - mouseHovering = false; - cancelToolTipShowing(); - - receive(me); - - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - if ((me.stateMask & SWT.BUTTON_MASK) != 0 && lastDragEvent != null - && !ignoreDragging) { - lastDragEvent = convertDrag(me, e); - tool.mouseDrag(lastDragEvent, getViewer()); - } else if ((me.stateMask & SWT.BUTTON_MASK) == 0) { - tool.mouseMove(e, getViewer()); - } - updateCursor(e.cursorLocation, e.target); - if (getToolTipHelper().isShowing()) - updateToolTip(e); - } else { - super.dispatchMouseMoved(me); - } - updateFocus(); - } - - private void receive(org.eclipse.swt.events.MouseEvent me) { - readStateMask(me); - MouseEvent current = convertMouse(me); - ITool tool; - if (currentMouseEvent == null - || current.target != currentMouseEvent.target) { - if (currentMouseEvent != null) { - tool = getActiveTool(); - if (tool != null) - tool.mouseExited(currentMouseEvent, getViewer()); - hideToolTip(); - } - if (current.target != null) { - tool = getActiveTool(); - if (tool != null) - tool.mouseEntered(current, getViewer()); - } - } - currentMouseEvent = current; - } - - protected void readStateMask(org.eclipse.swt.events.MouseEvent me) { - ITool tool = getActiveTool(); - if (tool != null && tool instanceof AbstractTool) { - IStatusMachine statusMachine = ((AbstractTool) tool).getStatus(); - int stateMask = me.stateMask; - statusMachine.setStatus(GEF.ST_CONTROL_PRESSED, - (stateMask & SWT.MOD1) != 0); - statusMachine.setStatus(GEF.ST_SHIFT_PRESSED, - (stateMask & SWT.MOD2) != 0); - statusMachine.setStatus(GEF.ST_ALT_PRESSED, - (stateMask & SWT.MOD3) != 0); - } - } - - /** - * - */ - public void hideToolTip() { - if (control != null && !control.isDisposed()) { - getToolTipHelper().updateToolTip(null, null, 0, 0); - } - } - - /** - * @param pos - * @param host - */ - protected void updateCursor(Point pos, IPart host) { - if (!isActive()) - return; - - Cursor currentCursor = null; - ITool tool = getActiveTool(); - if (tool instanceof IGraphicalTool) { - currentCursor = ((IGraphicalTool) tool).getCurrentCursor(pos, host); - } - if (currentCursor == null && host != null - && host instanceof IGraphicalEditPart - && host.getStatus().isActive()) { - currentCursor = ((IGraphicalEditPart) host).getCursor(pos); - } - setCursor(currentCursor); - } - - protected int getLongPressingActivationTime() { - return LONG_PRESSING_ACTIVATION_TIME; - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMousePressed(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMousePressed(org.eclipse.swt.events.MouseEvent me) { - pressedMouseButton = me.button; - if (!isActive()) - return; - -// super.dispatchMousePressed(me); - cancelToolTipShowing(); - lastDragEvent = createDragEvent(me); - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - final MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseDown(e, getViewer()); - if (e.isConsumed()) { - ignoreNextMouseUp = true; - } - updateCursor(e.cursorLocation, e.target); - if (getToolTipHelper().isShowing()) - updateToolTip(e); - ignoreLongPressing = false; - setIgnoreDoubleClicking(e.isConsumed()); - - Display.getCurrent().timerExec(getLongPressingActivationTime(), - new Runnable() { - public void run() { - dispatchMouseLongPressed(e); - } - }); - } else { - super.dispatchMousePressed(me); - setIgnoreDoubleClicking(getCurrentEvent() != null - && getCurrentEvent().isConsumed()); - } - updateFocus(); - } - - /** - * @return the mousePressed - */ - public boolean isMousePressed() { - return pressedMouseButton != 0; - } - - public int getPressedMouseButton() { - return pressedMouseButton; - } - - public boolean ignoresDoubleClicking() { - return ignoreDoubleClicking; - } - - public void setIgnoreDoubleClicking(boolean ignore) { - this.ignoreDoubleClicking = ignore; - } - - public void cancelLongPressing() { - this.ignoreLongPressing = true; - } - - public boolean ignoresLongPressing() { - return ignoreLongPressing; - } - - /** - * @param mouseEvent - */ - public void dispatchMouseLongPressed(MouseEvent me) { - if (!isActive()) - return; - if (!ignoresLongPressing() && me == currentMouseEvent && me != null - && !me.isConsumed()) { - ITool tool = getActiveTool(); - if (tool != null) { - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool) - .setCursorPosition(me.cursorLocation); - } - tool.mouseLongPressed(me, getViewer()); - updateCursor(me.cursorLocation, me.target); - } - } - } - - /** - * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseReleased(org.eclipse.swt.events.MouseEvent) - */ - @Override - public void dispatchMouseReleased(org.eclipse.swt.events.MouseEvent me) { - if (ignoreNextMouseUp) { - ignoreNextMouseUp = false; - return; - } - pressedMouseButton = 0; - ignoreDragging = false; - if (!isActive()) - return; -// super.dispatchMouseReleased(me); - cancelToolTipShowing(); - lastDragEvent = null; - receive(me); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - tool.mouseUp(e, getViewer()); - updateCursor(e.cursorLocation, e.target); - } else { - super.dispatchMouseReleased(me); - } - updateFocus(); - } - - /** - * @see org.eclipse.draw2d.EventDispatcher#dispatchMouseWheelScrolled(org.eclipse.swt.widgets.Event) - */ - @Override - public void dispatchMouseWheelScrolled(org.eclipse.swt.widgets.Event event) { - if (!isActive()) - return; -// super.dispatchMouseWheelScrolled(event); - cancelToolTipShowing(); - ITool tool = getActiveTool(); - if (tool != null) { - MouseEvent e = currentMouseEvent; - if (e != null && tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); - } - MouseWheelEvent mwe = convertWheel(event); - tool.mouseWheelScrolled(mwe, getViewer()); - if (e != null) { - updateCursor(e.cursorLocation, e.target); - } - event.doit = mwe.doIt; - } else { - super.dispatchMouseWheelScrolled(event); - } - } - - protected DragDropEvent createDropEvent(DropTargetEvent e, boolean drop) { - TransferData[] dataTypes; - if (drop && e.currentDataType != null) { - dataTypes = new TransferData[] { e.currentDataType }; - } else { - dataTypes = e.dataTypes; - } - DndData dndData = getDndSupport().parseData(dataTypes, getDropTarget(), - !drop); - if (dndData == null) - return null; - - Point p = new Point(control.toControl(e.x, e.y)); - Point location = convertPoint(p.x, p.y); - IPart host = findPart(p.x, p.y); - DragDropEvent event = DragDropEvent.createFrom(e, host, location); - event.dndData = dndData; - - IDndClient client = getDndSupport().getDndClient(dndData.clientId); - if (event.detail == DND.DROP_DEFAULT) - event.detail = event.operations; - if ((event.detail & DND.DROP_LINK) != 0 - && !client.canLink(dndData.dataType, getViewer(), location, - host)) { - event.detail &= ~DND.DROP_LINK; - } - if ((event.detail & DND.DROP_MOVE) != 0 - && !client.canMove(dndData.dataType, getViewer(), location, - host)) { - event.detail &= ~DND.DROP_MOVE; - } - if ((event.detail & DND.DROP_COPY) != 0 - && !client.canCopy(dndData.dataType, getViewer(), location, - host)) { - event.detail &= ~DND.DROP_COPY; - } - return event; - } - - protected void feedback(DragDropEvent de, DropTargetEvent swtEvent) { - swtEvent.detail = de.detail; - swtEvent.currentDataType = de.dndData.dataType; - updateControl(); - } - - /** - * - */ - private void updateControl() { - LightweightSystem lws; - if (control instanceof FigureCanvas) { - lws = ((FigureCanvas) control).getLightweightSystem(); - } else if (getViewer() instanceof GraphicalViewer) { - lws = ((GraphicalViewer) getViewer()).getLightweightSystem(); - } else if (getViewer().getCanvas() != null - && !getViewer().getCanvas().isDisposed()) { - lws = getViewer().getCanvas().getLightweightSystem(); - } else { - return; - } - lws.getUpdateManager().performUpdate(); - } - - protected IDragDropHandler getDragDropHandler() { - IDragDropHandler handler = null; - ITool tool = getActiveTool(); - if (tool instanceof IDragDropHandler) { - handler = (IDragDropHandler) tool; - } - return handler; - } - - public void dragEnter(DropTargetEvent event) { - if (!isActive()) - return; - dropHandler = null; - currentDropEvent = createDropEvent(event, false); - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - IDragDropHandler handler = getDragDropHandler(); - if (handler != null) { - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - handler.dragStarted(currentDropEvent, getViewer()); - handler.dragEntered(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - } - } - - public void dragLeave(DropTargetEvent event) { - if (!isActive()) - return; - - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - final IDragDropHandler handler = getDragDropHandler(); - if (handler != null) { - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - // The passed-in DropTargetEvent object's contents - // may be invalid, such as position and detail, so we use - // the last DragDropEvent object instead of creating - // a new one, and thus achieve a correct effect that - // the drag operation 'LEAVE' off that every last part - // it ever stayed over. - handler.dragExited(currentDropEvent, getViewer()); - handler.dragDismissed(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - dropHandler = handler; - } - } - - public void dragOperationChanged(DropTargetEvent event) { - if (!isActive()) - return; - currentDropEvent = createDropEvent(event, false); - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - IDragDropHandler handler = getDragDropHandler(); - if (handler != null) { - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - handler.dragOperationChanged(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - } - } - - public void dragOver(DropTargetEvent event) { - if (!isActive()) - return; - DragDropEvent prevDropEvent = currentDropEvent; - currentDropEvent = createDropEvent(event, false); - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - IDragDropHandler handler = getDragDropHandler(); - if (handler != null) { - - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - - // test if the cursor leaves a part and enters another - if (prevDropEvent != null - && prevDropEvent.target != currentDropEvent.target) { - handler.dragExited(prevDropEvent, getViewer()); - handler.dragEntered(currentDropEvent, getViewer()); - } - - handler.dragOver(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - } - } - - public void drop(DropTargetEvent event) { - if (!isActive()) - return; - currentDropEvent = createDropEvent(event, true); - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - IDragDropHandler handler = dropHandler; - if (handler == null) - handler = getDragDropHandler(); - if (handler != null) { - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - handler.drop(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - dropHandler = null; - } - } - - public void dropAccept(DropTargetEvent event) { - if (!isActive()) - return; - currentDropEvent = createDropEvent(event, false); - if (currentDropEvent == null) { - event.detail = DND.DROP_NONE; - return; - } - - IDragDropHandler handler = dropHandler; - if (handler == null) - handler = getDragDropHandler(); - if (handler != null) { - if (handler instanceof IGraphicalTool) { - ((IGraphicalTool) handler) - .setCursorPosition(currentDropEvent.location); - } - handler.dropAccept(currentDropEvent, getViewer()); - feedback(currentDropEvent, event); - } - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.event; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LightweightSystem; +import org.eclipse.draw2d.RangeModel; +import org.eclipse.draw2d.ToolTipHelper; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.acc.IAccessible; +import org.xmind.gef.dnd.DndData; +import org.xmind.gef.dnd.IDndClient; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.draw2d.KeepVisibleToolTipHelper; +import org.xmind.gef.part.GraphicalEditPart; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.status.IStatusMachine; +import org.xmind.gef.tool.AbstractTool; +import org.xmind.gef.tool.IDragDropHandler; +import org.xmind.gef.tool.IGraphicalTool; +import org.xmind.gef.tool.ITool; + +/** + * @author Brian Sun + */ +public class PartsEventDispatcher extends ViewerEventDispatcher + implements DropTargetListener { + + protected class PartAccessibilityDispatcher + extends AccessibilityDispatcher { + + private IAccessible get(int childID) { + if (childID == ACC.CHILDID_SELF || childID == ACC.CHILDID_NONE) { + IPart focused = getFocusedPart(); + if (focused != null) { + IAccessible acc = (IAccessible) focused + .getAdapter(IAccessible.class); + if (acc != null) + return acc; + } + IPart contents = getViewer().getRootPart().getContents(); + if (contents == null) + return null; + return (IAccessible) contents.getAdapter(IAccessible.class); + } + return getViewer().getAccessibleRegistry().getAccessible(childID); + } + + public void getChildAtPoint(AccessibleControlEvent e) { + IPart part = findPart(e.x, e.y); + if (part == null) + return; + IAccessible acc = (IAccessible) part.getAdapter(IAccessible.class); + if (acc != null) { + e.childID = acc.getAccessibleId(); + } + } + + public void getChildCount(AccessibleControlEvent e) { + e.detail = getViewer().getAccessibleRegistry().getNumAccessibles(); + } + + public void getChildren(AccessibleControlEvent e) { + e.children = getViewer().getAccessibleRegistry() + .getAllAccessibleIDs(); + } + + public void getDefaultAction(AccessibleControlEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String defaultAction = acc.getDefaultAction(); + if (defaultAction != null) + e.result = defaultAction; + } + } + + public void getFocus(AccessibleControlEvent e) { + if (control.isFocusControl()) { + IPart focusedPart = getFocusedPart(); + if (focusedPart != null) { + IAccessible acc = (IAccessible) focusedPart + .getAdapter(IAccessible.class); + if (acc != null) { + e.childID = acc.getAccessibleId(); + return; + } + } + e.childID = ACC.CHILDID_SELF; + } else { + e.childID = ACC.CHILDID_NONE; + } + } + + private IPart getFocusedPart() { + Object focused = getViewer().getFocused(); + return focused == null ? null + : getViewer().getSelectionSupport() + .findSelectablePart(focused); + } + + public void getLocation(AccessibleControlEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + Rectangle r = acc.getLocation(); + if (r != null) { + e.x = r.x; + e.y = r.y; + if (r.width >= 0) + e.width = r.width; + if (r.height >= 0) + e.height = r.height; + } + } + } + + public void getRole(AccessibleControlEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + int role = acc.getRole(); + if (role >= 0) { + e.detail = role; + } + } + } + + public void getSelection(AccessibleControlEvent e) { + List selectedParts = getViewer().getSelectionSupport() + .getPartSelection(); + if (selectedParts.isEmpty()) { + if (getViewer().getControl().isFocusControl()) { + e.childID = ACC.CHILDID_SELF; + } else { + e.childID = ACC.CHILDID_NONE; + } + return; + } + + List childIds = new ArrayList( + selectedParts.size()); + for (IPart p : selectedParts) { + IAccessible acc = (IAccessible) p.getAdapter(IAccessible.class); + if (acc != null) { + childIds.add(acc.getAccessibleId()); + } + } + if (childIds.isEmpty()) { + e.childID = ACC.CHILDID_NONE; + } else { + e.childID = ACC.CHILDID_MULTIPLE; + e.children = childIds.toArray(); + } + } + + public void getState(AccessibleControlEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + int state = acc.getState(); + if (state >= 0) { + e.detail = state; + } + } + } + + public void getValue(AccessibleControlEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String value = acc.getValue(); + if (value != null) { + e.result = value; + } + } + } + + public void getDescription(AccessibleEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String description = acc.getDescription(); + if (description != null) { + e.result = description; + } + } + } + + public void getHelp(AccessibleEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String help = acc.getHelp(); + if (help != null) { + e.result = help; + } + } + } + + public void getKeyboardShortcut(AccessibleEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String keyboardShortcut = acc.getKeyboardShortcut(); + if (keyboardShortcut != null) + e.result = keyboardShortcut; + } + } + + public void getName(AccessibleEvent e) { + IAccessible acc = get(e.childID); + if (acc != null) { + String name = acc.getName(); + if (name != null) { + e.result = name; + } + } + } + + } + + private static int LONG_PRESSING_ACTIVATION_TIME = 500; + + private static int DEFAULT_START_DRAG_THRESHOLD = 3; + + private ToolTipHelper toolTipHelper; + + private Shell shell = null; + + private DropTarget dropTarget = null; + + private boolean ignoreDoubleClicking = false; + + private boolean ignoreLongPressing = false; + + private boolean ignoreDragging = false; + + private boolean ignoreNextMouseUp = false; + + private MouseDragEvent lastDragEvent = null; + + private MouseEvent currentMouseEvent = null; + + private DragDropEvent currentDropEvent = null; + + private IDragDropHandler dropHandler = null; + + private int pressedMouseButton = 0; + + private PartAccessibilityDispatcher accDispatcher = null; + + private PropertyChangeListener viewportScrollListener = null; + + private RangeModel horizontalRangeModel = null; + + private RangeModel verticalRangeModel = null; + + private boolean mouseHovering = false; + + private boolean isDraging = false; + + /** + * @param domain + */ + public PartsEventDispatcher(IGraphicalViewer viewer) { + super(viewer); + } + + public EditDomain getDomain() { + return getViewer().getEditDomain(); + } + + protected void onActivated() { + super.onActivated(); + setIgnoreDoubleClicking(false); + } + + protected void onDeactivated() { + hideToolTip(); + cancelLongPressing(); + + lastDragEvent = null; + currentMouseEvent = null; + currentDropEvent = null; + dropHandler = null; + + setIgnoreDoubleClicking(true); + } + + @Override + public void setControl(Control c) { + if (c == control) + return; + if (control != null && !control.isDisposed()) + throw new RuntimeException( + "Can not set control again once it has been set"); //$NON-NLS-1$ + if (c != null) + c.addDisposeListener(new org.eclipse.swt.events.DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (toolTipHelper != null) + toolTipHelper.dispose(); + } + }); + control = c; + + createDropTarget(c); + } + + protected void createDropTarget(Control c) { + if (dropTarget != null) { + dropTarget.dispose(); + dropTarget = null; + } + + if (getDndSupport() != null) { + dropTarget = new DropTarget(c, getDndSupport().getStyle()); + dropTarget.setTransfer(getDndSupport().getTransfers()); + dropTarget.addDropListener(this); + c.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + disposeDropTarget(); + } + }); + } + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.event.ViewerEventDispatcher#dndSupportChanged(org.xmind + * .gef.dnd.IDndSupport, org.xmind.gef.dnd.IDndSupport) + */ + @Override + protected void dndSupportChanged(IDndSupport oldDndSupport, + IDndSupport newDndSupport) { + super.dndSupportChanged(oldDndSupport, newDndSupport); + if (control != null && !control.isDisposed()) { + createDropTarget(control); + } + } + + protected DropTarget getDropTarget() { + return dropTarget; + } + + protected void disposeDropTarget() { + if (dropTarget != null) { + if (!dropTarget.isDisposed()) { + dropTarget.removeDropListener(this); + } + dropTarget.dispose(); + dropTarget = null; + } + } + + /** + * @param controlX + * @param controlY + * @return + */ + protected Point convertPoint(int controlX, int controlY) { + Point p = new Point(controlX, controlY); + if (getViewer().getControl() != null + && !getViewer().getControl().isDisposed()) { +// if (isScaleLocation()) { + p = getViewer().computeToLayer(p, true); +// } else { +// p.translate(getViewer().getScrollPosition()); +// } + } + return p; + } + + /** + * @param me + * @return + */ + protected MouseEvent convertMouse(org.eclipse.swt.events.MouseEvent me) { + Point pos = convertPoint(me.x, me.y); + return MouseEvent.createEvent(me, findPart(me.x, me.y), pos); + } + + protected MouseEvent convertMouse(org.eclipse.swt.events.MouseEvent me, + IPart host) { + Point pos = convertPoint(me.x, me.y); + return MouseEvent.createEvent(me, host, pos); + } + + /** + * @param me + * @return + */ + protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me) { + Point pos = convertPoint(me.x, me.y); + return MouseDragEvent.createEvent(me, lastDragEvent, pos, + findPart(me.x, me.y)); + } + + protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me, + IPart host) { + Point pos = convertPoint(me.x, me.y); + return MouseDragEvent.createEvent(me, lastDragEvent, pos, host); + } + + protected MouseDragEvent convertDrag(org.eclipse.swt.events.MouseEvent me, + MouseEvent current) { + return MouseDragEvent.createEvent(me, lastDragEvent, + current.cursorLocation, current.target); + } + + /** + * @param ke + * @return + */ + protected KeyEvent convertKey(org.eclipse.swt.events.KeyEvent ke) { + return KeyEvent.createEvent(ke, isImeOpened()); + } + + protected MouseWheelEvent convertWheel(org.eclipse.swt.widgets.Event e) { + return MouseWheelEvent.createEvent(findPart(e.x, e.y), e); + } + + /** + * @param me + * @return + */ + protected MouseDragEvent createDragEvent( + org.eclipse.swt.events.MouseEvent me) { + Point startPoint = convertPoint(me.x, me.y); + return MouseDragEvent.createEvent(me, findPart(me.x, me.y), startPoint); + } + + public PartAccessibilityDispatcher getPartAccessibilityDispatcher() { + if (accDispatcher == null) + accDispatcher = new PartAccessibilityDispatcher(); + return accDispatcher; + } + + @Override + protected AccessibilityDispatcher getAccessibilityDispatcher() { + return getPartAccessibilityDispatcher(); + } + + protected IPart findPart(int controlX, int controlY) { + IPart part = getViewer().findPart(controlX, controlY); + return part == null ? getViewer().getRootPart() : part; + } + +// /** +// * @param position +// */ +// protected IPart findPart(Point position) { +// return findPart(getViewer().getRootPart(), position); +// } +// +// protected IPart findPart(IPart parent, Point position) { +// if (parent == null) +// return null; +// if (parent instanceof IGraphicalEditPart) { +// return (((IGraphicalEditPart) parent).findAt(position)); +// } +// for (IPart p : parent.getChildren()) { +// IPart ret = findPart(p, position); +// if (ret != null) +// return ret; +// } +// return null; +// } + + protected ITool getActiveTool() { + EditDomain domain = getDomain(); + return domain != null && !domain.isDisposed() ? domain.getActiveTool() + : null; + } + + protected boolean isImeOpened() { + if (shell == null) { + if (control != null & !control.isDisposed()) { + shell = control.getShell(); + } else { + Control viewerControl = getViewer().getControl(); + if (viewerControl != null && !viewerControl.isDisposed()) + shell = viewerControl.getShell(); + } + } + return shell == null ? false : shell.getImeInputMode() != SWT.NONE; + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchFocusGained(org.eclipse.swt.events.FocusEvent) + */ + @Override + public void dispatchFocusGained(FocusEvent e) { + if (!isActive()) + return; +// super.dispatchFocusGained(e); + ITool tool = getActiveTool(); + if (tool != null) { + tool.focusGained(getViewer()); + MouseEvent me = currentMouseEvent; + if (me != null) { + updateCursor(me.cursorLocation, me.target); + } + } else { + super.dispatchFocusGained(e); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchFocusLost(org.eclipse.swt.events.FocusEvent) + */ + @Override + public void dispatchFocusLost(FocusEvent e) { + cancelLongPressing(); + if (!isActive()) + return; +// super.dispatchFocusLost(e); + ITool tool = getActiveTool(); + if (tool != null) { + tool.focusLost(getViewer()); + MouseEvent me = currentMouseEvent; + if (me != null) { + updateCursor(me.cursorLocation, me.target); + } + } else { + super.dispatchFocusLost(e); + } + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyPressed(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void dispatchKeyPressed(org.eclipse.swt.events.KeyEvent e) { + if (!isActive()) + return; +// super.dispatchKeyPressed(e); + ITool tool = getActiveTool(); + if (tool != null) { + KeyEvent ke = convertKey(e); + tool.keyDown(ke, getViewer()); + e.doit = !ke.isConsumed(); + MouseEvent me = currentMouseEvent; + if (me != null && isValidGraphicalPart(me.target)) { + updateCursor(me.cursorLocation, me.target); + } + } else { + super.dispatchKeyPressed(e); + } + if ((e.keyCode & SWT.ESC) != 0) { + lastDragEvent = null; + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyReleased(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void dispatchKeyReleased(org.eclipse.swt.events.KeyEvent e) { + if (!isActive()) + return; +// super.dispatchKeyReleased(e); + ITool tool = getActiveTool(); + if (tool != null) { + KeyEvent ke = convertKey(e); + tool.keyUp(ke, getViewer()); + e.doit = !ke.isConsumed(); + MouseEvent me = currentMouseEvent; + if (me != null && isValidGraphicalPart(me.target)) { + updateCursor(me.cursorLocation, me.target); + } + } else { + super.dispatchKeyReleased(e); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyTraversed(org.eclipse.swt.events.TraverseEvent) + */ + @Override + public void dispatchKeyTraversed(TraverseEvent e) { + if (!isActive()) + return; +// super.dispatchKeyTraversed(e); + ITool tool = getActiveTool(); + if (tool != null) { + KeyEvent ke = convertKey(e); + tool.keyTraversed(ke, getViewer()); + e.doit = !ke.isConsumed(); + e.detail = ke.traverse; + MouseEvent me = currentMouseEvent; + if (me != null && isValidGraphicalPart(me.target)) { + updateCursor(me.cursorLocation, me.target); + } + } else { + super.dispatchKeyTraversed(e); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseDoubleClicked(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseDoubleClicked( + org.eclipse.swt.events.MouseEvent me) { + if (!isActive()) + return; + +// super.dispatchMouseDoubleClicked(me); + + cancelToolTipShowing(); + + if (ignoresDoubleClicking()) { + setIgnoreDoubleClicking(false); + return; + } + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseDoubleClick(e, getViewer()); + updateCursor(e.cursorLocation, e.target); + ignoreDragging = e.isConsumed() && pressedMouseButton != 0; + } else { + super.dispatchMouseDoubleClicked(me); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseEntered(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseEntered(org.eclipse.swt.events.MouseEvent me) { + if (!isActive()) + return; +// super.dispatchMouseEntered(me); + mouseHovering = false; + hookScrollBars(); + cancelToolTipShowing(); + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseEntered(e, getViewer()); + updateCursor(e.cursorLocation, e.target); + } else { + super.dispatchMouseEntered(me); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseExited(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseExited(org.eclipse.swt.events.MouseEvent me) { + unhookScrollBars(); + if (!isActive()) + return; +// super.dispatchMouseExited(me); + mouseHovering = false; + cancelToolTipShowing(); + hideToolTip(); + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseExited(e, getViewer()); + updateCursor(e.cursorLocation, e.target); + } else { + super.dispatchMouseExited(me); + } + updateFocus(); + } + + private void hookScrollBars() { + Viewport viewport = getViewer().getCanvas().getViewport(); + horizontalRangeModel = viewport.getHorizontalRangeModel(); + horizontalRangeModel + .addPropertyChangeListener(getViewportScrollListener()); + verticalRangeModel = viewport.getVerticalRangeModel(); + verticalRangeModel + .addPropertyChangeListener(getViewportScrollListener()); + } + + private void unhookScrollBars() { + if (horizontalRangeModel != null) { + horizontalRangeModel + .removePropertyChangeListener(getViewportScrollListener()); + horizontalRangeModel = null; + } + if (verticalRangeModel != null) { + verticalRangeModel + .removePropertyChangeListener(getViewportScrollListener()); + verticalRangeModel = null; + } + } + + private PropertyChangeListener getViewportScrollListener() { + if (viewportScrollListener == null) { + viewportScrollListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + dispatchViewerScrolled(evt); + } + }; + } + return viewportScrollListener; + } + + protected void dispatchViewerScrolled(PropertyChangeEvent evt) { + if (lastDragEvent != null || currentDropEvent != null + || Boolean.TRUE.equals(getViewer().getProperties() + .get(IGraphicalViewer.VIEWER_IGNORE_SCROLL_EVENT))) + return; + + Display currentDisplay = Display.getCurrent(); + org.eclipse.swt.graphics.Point loc = currentDisplay.getCursorLocation(); + loc = control.toControl(loc); + org.eclipse.swt.graphics.Rectangle bounds = control.getBounds(); + if (bounds.contains(loc)) { + org.eclipse.swt.widgets.Event event = new org.eclipse.swt.widgets.Event(); + org.eclipse.swt.events.MouseEvent last = currentMouseEvent == null + ? null : currentMouseEvent.currentSWTEvent; + if (last != null) { + event.button = last.button; + event.count = last.count; + event.data = last.data; + event.display = last.display; + event.stateMask = last.stateMask; + event.widget = last.widget; + } else { + event.display = currentDisplay; + event.widget = control; + } + event.time = (int) System.currentTimeMillis(); + event.x = loc.x; + event.y = loc.y; + dispatchMouseMoved(new org.eclipse.swt.events.MouseEvent(event)); + } + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseHover(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseHover(org.eclipse.swt.events.MouseEvent me) { + if (!isActive()) + return; + +// super.dispatchMouseHover(me); + mouseHovering = true; + cancelToolTipShowing(); + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseHover(e, getViewer()); + updateCursor(e.cursorLocation, e.target); + updateToolTip(e); + } else { + super.dispatchMouseHover(me); + } + updateFocus(); + } + + public void cancelToolTipShowing() { + // if ( tooltipTimer != null ) { + // tooltipTimer.cancel(); + // tooltipTimer = null; + // } + } + + public void updateToolTip() { + if (control == null || control.isDisposed()) + return; + hideToolTip(); + if (mouseHovering && currentMouseEvent != null) { + updateToolTip(currentMouseEvent, false); + } + } + + protected void updateToolTip(MouseEvent me, boolean useEventTarget) { + Point cp = null; + org.eclipse.swt.events.MouseEvent e = me.getCurrentSWTEvent(); + if (e != null) { + cp = new Point(e.x, e.y); + } else { + cp = getViewer().computeToControl(me.cursorLocation, true); + } + + IPart target = useEventTarget ? me.target : findPart(cp.x, cp.y); + if (target != null && target instanceof IGraphicalPart) { + ITool tool = getActiveTool(); + IFigure tooltip = null; + if (tool instanceof IGraphicalTool) { + tooltip = ((IGraphicalTool) tool).getToolTip(target, + me.cursorLocation); + } + if (tooltip == null && target instanceof IGraphicalEditPart) { + tooltip = ((IGraphicalEditPart) target) + .findTooltipAt(me.cursorLocation); + } + if (tooltip != null) { + Point absolute = new Point(control.toDisplay(cp.x, cp.y)); + getToolTipHelper().displayToolTipNear( + ((IGraphicalPart) target).getFigure(), tooltip, + absolute.x, absolute.y); + return; + } + } + hideToolTip(); + } + + protected ToolTipHelper getToolTipHelper() { + if (toolTipHelper == null) { + if (currentMouseEvent != null) { + IPart target = currentMouseEvent.target; + if (target != null && target instanceof GraphicalEditPart) { + String actionId = ((GraphicalEditPart) target) + .getActionId(); + if (actionId != null && (actionId + .equals("org.xmind.ui.editNotes") //$NON-NLS-1$ + || actionId.equals("org.xmind.ui.editComments"))) { //$NON-NLS-1$ + toolTipHelper = new KeepVisibleToolTipHelper(control); + } else { + toolTipHelper = new ToolTipHelper(control); + } + } + } + } else { + if (currentMouseEvent != null) { + IPart target = currentMouseEvent.target; + if (target != null && target instanceof GraphicalEditPart) { + String actionId = ((GraphicalEditPart) target) + .getActionId(); + if (actionId != null && (actionId + .equals("org.xmind.ui.editNotes") //$NON-NLS-1$ + || actionId.equals("org.xmind.ui.editComments"))) { //$NON-NLS-1$ + if (!(toolTipHelper instanceof KeepVisibleToolTipHelper)) { + toolTipHelper.dispose(); + toolTipHelper = new KeepVisibleToolTipHelper( + control); + } + } else { + if (toolTipHelper instanceof KeepVisibleToolTipHelper) { + toolTipHelper.dispose(); + toolTipHelper = new ToolTipHelper(control); + } + } + } + } + } + + if (toolTipHelper == null) { + toolTipHelper = new ToolTipHelper(control); + } + + return toolTipHelper; + } + + /** + * @param me + */ + protected void updateToolTip(MouseEvent me) { + updateToolTip(me, true); + } + + protected boolean isValidGraphicalPart(IPart host) { + return host != null && host instanceof IGraphicalPart + && host.getStatus().isActive(); + } + + protected void updateFocus() { + IFigure focusableFigure = null; + IPart focusedPart = getViewer().getFocusedPart(); + if (focusedPart instanceof IGraphicalPart) { + IFigure fig = ((IGraphicalPart) focusedPart).getFigure(); + if (fig.isRequestFocusEnabled()) { + focusableFigure = fig; + } + } + setFocus(focusableFigure); + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseMoved(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseMoved(org.eclipse.swt.events.MouseEvent me) { + if (!isActive()) + return; + + /* + * IMPORTANT: IF brainy is running on JDK 1.6beta, the sentence below + * will fix a huge bug. + */ + if (me.x > 0x8fff) { + me.x -= 65536; + } + /* IMPORTANT: end IF. */ + +// super.dispatchMouseMoved(me); + + mouseHovering = false; + cancelToolTipShowing(); + + receive(me); + + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + if ((me.stateMask & SWT.BUTTON_MASK) != 0 && lastDragEvent != null + && !ignoreDragging) { + lastDragEvent = convertDrag(me, e); + if (!isDraging) { + isDraging = isDragDetected(lastDragEvent, + getViewer().getProperties().getInteger( + IGraphicalViewer.VIEWER_START_DRAG_THRESHOLD, + DEFAULT_START_DRAG_THRESHOLD)); + } + if (isDraging) { + tool.mouseDrag(lastDragEvent, getViewer()); + } + } else if ((me.stateMask & SWT.BUTTON_MASK) == 0) { + tool.mouseMove(e, getViewer()); + } + updateCursor(e.cursorLocation, e.target); + if (getToolTipHelper().isShowing()) + updateToolTip(e); + } else { + super.dispatchMouseMoved(me); + } + updateFocus(); + } + + private boolean isDragDetected(MouseDragEvent me, int threshold) { + int deltaX = Math.abs(me.cursorLocation.x - me.startingLocation.x); + int deltaY = Math.abs(me.cursorLocation.y - me.startingLocation.y); + return deltaX >= threshold || deltaY >= threshold; + } + + private void receive(org.eclipse.swt.events.MouseEvent me) { + readStateMask(me); + MouseEvent current = convertMouse(me); + ITool tool; + if (currentMouseEvent == null + || current.target != currentMouseEvent.target) { + if (currentMouseEvent != null) { + tool = getActiveTool(); + if (tool != null) + tool.mouseExited(currentMouseEvent, getViewer()); + hideToolTip(); + } + if (current.target != null) { + tool = getActiveTool(); + if (tool != null) + tool.mouseEntered(current, getViewer()); + } + } + currentMouseEvent = current; + } + + protected void readStateMask(org.eclipse.swt.events.MouseEvent me) { + ITool tool = getActiveTool(); + if (tool != null && tool instanceof AbstractTool) { + IStatusMachine statusMachine = ((AbstractTool) tool).getStatus(); + int stateMask = me.stateMask; + statusMachine.setStatus(GEF.ST_CONTROL_PRESSED, + (stateMask & SWT.MOD1) != 0); + statusMachine.setStatus(GEF.ST_SHIFT_PRESSED, + (stateMask & SWT.MOD2) != 0); + statusMachine.setStatus(GEF.ST_ALT_PRESSED, + (stateMask & SWT.MOD3) != 0); + } + } + + /** + * + */ + public void hideToolTip() { + if (control != null && !control.isDisposed()) { + getToolTipHelper().updateToolTip(null, null, 0, 0); + } + } + + /** + * @param pos + * @param host + */ + protected void updateCursor(Point pos, IPart host) { + if (!isActive()) + return; + + Cursor currentCursor = null; + ITool tool = getActiveTool(); + if (tool instanceof IGraphicalTool) { + currentCursor = ((IGraphicalTool) tool).getCurrentCursor(pos, host); + } + if (currentCursor == null && host != null + && host instanceof IGraphicalEditPart + && host.getStatus().isActive()) { + currentCursor = ((IGraphicalEditPart) host).getCursor(pos); + } + setCursor(currentCursor); + } + + protected int getLongPressingActivationTime() { + return LONG_PRESSING_ACTIVATION_TIME; + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMousePressed(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMousePressed(org.eclipse.swt.events.MouseEvent me) { + isDraging = false; + pressedMouseButton = me.button; + if (!isActive()) + return; + +// super.dispatchMousePressed(me); + cancelToolTipShowing(); + lastDragEvent = createDragEvent(me); + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + final MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseDown(e, getViewer()); + if (e.isConsumed()) { + ignoreNextMouseUp = true; + } + updateCursor(e.cursorLocation, e.target); + if (getToolTipHelper().isShowing()) + updateToolTip(e); + ignoreLongPressing = false; + setIgnoreDoubleClicking(e.isConsumed()); + + Display.getCurrent().timerExec(getLongPressingActivationTime(), + new Runnable() { + public void run() { + dispatchMouseLongPressed(e); + } + }); + } else { + super.dispatchMousePressed(me); + setIgnoreDoubleClicking(getCurrentEvent() != null + && getCurrentEvent().isConsumed()); + } + updateFocus(); + } + + /** + * @return the mousePressed + */ + public boolean isMousePressed() { + return pressedMouseButton != 0; + } + + public int getPressedMouseButton() { + return pressedMouseButton; + } + + public boolean ignoresDoubleClicking() { + return ignoreDoubleClicking; + } + + public void setIgnoreDoubleClicking(boolean ignore) { + this.ignoreDoubleClicking = ignore; + } + + public void cancelLongPressing() { + this.ignoreLongPressing = true; + } + + public boolean ignoresLongPressing() { + return ignoreLongPressing; + } + + /** + * @param mouseEvent + */ + public void dispatchMouseLongPressed(MouseEvent me) { + if (!isActive()) + return; + if (!ignoresLongPressing() && me == currentMouseEvent && me != null + && !me.isConsumed()) { + ITool tool = getActiveTool(); + if (tool != null) { + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool) + .setCursorPosition(me.cursorLocation); + } + tool.mouseLongPressed(me, getViewer()); + updateCursor(me.cursorLocation, me.target); + } + } + } + + /** + * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchMouseReleased(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void dispatchMouseReleased(org.eclipse.swt.events.MouseEvent me) { + if (ignoreNextMouseUp) { + ignoreNextMouseUp = false; + return; + } + pressedMouseButton = 0; + ignoreDragging = false; + isDraging = false; + if (!isActive()) + return; +// super.dispatchMouseReleased(me); + cancelToolTipShowing(); + lastDragEvent = null; + receive(me); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + tool.mouseUp(e, getViewer()); + updateCursor(e.cursorLocation, e.target); + } else { + super.dispatchMouseReleased(me); + } + updateFocus(); + } + + /** + * @see org.eclipse.draw2d.EventDispatcher#dispatchMouseWheelScrolled(org.eclipse.swt.widgets.Event) + */ + @Override + public void dispatchMouseWheelScrolled( + org.eclipse.swt.widgets.Event event) { + if (!isActive()) + return; +// super.dispatchMouseWheelScrolled(event); + cancelToolTipShowing(); + ITool tool = getActiveTool(); + if (tool != null) { + MouseEvent e = currentMouseEvent; + if (e != null && tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool).setCursorPosition(e.cursorLocation); + } + MouseWheelEvent mwe = convertWheel(event); + tool.mouseWheelScrolled(mwe, getViewer()); + if (e != null) { + updateCursor(e.cursorLocation, e.target); + } + event.doit = mwe.doIt; + } else { + super.dispatchMouseWheelScrolled(event); + } + } + + protected DragDropEvent createDropEvent(DropTargetEvent e, boolean drop) { + TransferData[] dataTypes; + if (drop && e.currentDataType != null) { + dataTypes = new TransferData[] { e.currentDataType }; + } else { + dataTypes = e.dataTypes; + } + DndData dndData = getDndSupport().parseData(dataTypes, getDropTarget(), + !drop); + if (dndData == null) + return null; + + Point p = new Point(control.toControl(e.x, e.y)); + Point location = convertPoint(p.x, p.y); + IPart host = findPart(p.x, p.y); + DragDropEvent event = DragDropEvent.createFrom(e, host, location); + event.dndData = dndData; + + IDndClient client = getDndSupport().getDndClient(dndData.clientId); + if (event.detail == DND.DROP_DEFAULT) + event.detail = event.operations; + if ((event.detail & DND.DROP_LINK) != 0 && !client + .canLink(dndData.dataType, getViewer(), location, host)) { + event.detail &= ~DND.DROP_LINK; + } + if ((event.detail & DND.DROP_MOVE) != 0 && !client + .canMove(dndData.dataType, getViewer(), location, host)) { + event.detail &= ~DND.DROP_MOVE; + } + if ((event.detail & DND.DROP_COPY) != 0 && !client + .canCopy(dndData.dataType, getViewer(), location, host)) { + event.detail &= ~DND.DROP_COPY; + } + return event; + } + + protected void feedback(DragDropEvent de, DropTargetEvent swtEvent) { + swtEvent.detail = de.detail; + swtEvent.currentDataType = de.dndData.dataType; + updateControl(); + } + + /** + * + */ + private void updateControl() { + LightweightSystem lws; + if (control instanceof FigureCanvas) { + lws = ((FigureCanvas) control).getLightweightSystem(); + } else if (getViewer() instanceof GraphicalViewer) { + lws = ((GraphicalViewer) getViewer()).getLightweightSystem(); + } else if (getViewer().getCanvas() != null + && !getViewer().getCanvas().isDisposed()) { + lws = getViewer().getCanvas().getLightweightSystem(); + } else { + return; + } + lws.getUpdateManager().performUpdate(); + } + + protected IDragDropHandler getDragDropHandler() { + IDragDropHandler handler = null; + ITool tool = getActiveTool(); + if (tool instanceof IDragDropHandler) { + handler = (IDragDropHandler) tool; + } + return handler; + } + + public void dragEnter(DropTargetEvent event) { + if (!isActive()) + return; + dropHandler = null; + currentDropEvent = createDropEvent(event, false); + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + IDragDropHandler handler = getDragDropHandler(); + if (handler != null) { + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + handler.dragStarted(currentDropEvent, getViewer()); + handler.dragEntered(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + } + } + + public void dragLeave(DropTargetEvent event) { + if (!isActive()) + return; + + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + final IDragDropHandler handler = getDragDropHandler(); + if (handler != null) { + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + // The passed-in DropTargetEvent object's contents + // may be invalid, such as position and detail, so we use + // the last DragDropEvent object instead of creating + // a new one, and thus achieve a correct effect that + // the drag operation 'LEAVE' off that every last part + // it ever stayed over. + handler.dragExited(currentDropEvent, getViewer()); + handler.dragDismissed(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + dropHandler = handler; + } + } + + public void dragOperationChanged(DropTargetEvent event) { + if (!isActive()) + return; + currentDropEvent = createDropEvent(event, false); + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + IDragDropHandler handler = getDragDropHandler(); + if (handler != null) { + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + handler.dragOperationChanged(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + } + } + + public void dragOver(DropTargetEvent event) { + if (!isActive()) + return; + DragDropEvent prevDropEvent = currentDropEvent; + currentDropEvent = createDropEvent(event, false); + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + IDragDropHandler handler = getDragDropHandler(); + if (handler != null) { + + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + + // test if the cursor leaves a part and enters another + if (prevDropEvent != null + && prevDropEvent.target != currentDropEvent.target) { + handler.dragExited(prevDropEvent, getViewer()); + handler.dragEntered(currentDropEvent, getViewer()); + } + + handler.dragOver(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + } + } + + public void drop(DropTargetEvent event) { + if (!isActive()) + return; + currentDropEvent = createDropEvent(event, true); + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + IDragDropHandler handler = dropHandler; + if (handler == null) + handler = getDragDropHandler(); + if (handler != null) { + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + handler.drop(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + dropHandler = null; + } + } + + public void dropAccept(DropTargetEvent event) { + if (!isActive()) + return; + currentDropEvent = createDropEvent(event, false); + if (currentDropEvent == null) { + event.detail = DND.DROP_NONE; + return; + } + + IDragDropHandler handler = dropHandler; + if (handler == null) + handler = getDragDropHandler(); + if (handler != null) { + if (handler instanceof IGraphicalTool) { + ((IGraphicalTool) handler) + .setCursorPosition(currentDropEvent.location); + } + handler.dropAccept(currentDropEvent, getViewer()); + feedback(currentDropEvent, event); + } + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/event/ViewerEventDispatcher.java b/bundles/org.xmind.gef/src/org/xmind/gef/event/ViewerEventDispatcher.java index 046367ace..f5e91180a 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/event/ViewerEventDispatcher.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/event/ViewerEventDispatcher.java @@ -1,142 +1,142 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.event; - -import org.eclipse.draw2d.SWTEventDispatcher; -import org.eclipse.swt.graphics.Cursor; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.dnd.IDndSupport; - -/** - * @author Frank Shaka - * - */ -public abstract class ViewerEventDispatcher extends SWTEventDispatcher { - - private final IGraphicalViewer viewer; - - private IDndSupport dndSupport = null; - - private Cursor overridingCursor = null; - - private boolean active = false; - - /** - * - */ - public ViewerEventDispatcher(IGraphicalViewer viewer) { - this.viewer = viewer; - } - - /** - * @return the viewer - */ - public IGraphicalViewer getViewer() { - return viewer; - } - - /** - * Activates this event dispatcher. If already activated, does nothing. - */ - public final void activate() { - if (isActive()) - return; - - this.active = true; - onActivated(); - } - - /** - * Deactivate this event dispatcher. If already deactivated, does nothing. - */ - public final void deactivate() { - if (!isActive()) - return; - - this.active = false; - onDeactivated(); - } - - /** - * For subclasses to extend. - */ - protected void onActivated() { - } - - /** - * For subclasses to extend. - */ - protected void onDeactivated() { - } - - /** - * Determines if this event dispatcher has been activated. - * - * @return true if this event dispatcher is activated - */ - public final boolean isActive() { - return this.active; - } - - public void updateToolTip() { - } - - public void setOverridingCursor(Cursor cursor) { - if (cursor == this.overridingCursor) - return; - this.overridingCursor = cursor; - if (cursor == null) { - updateCursor(); - } else { - setCursor(cursor); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.draw2d.SWTEventDispatcher#setCursor(org.eclipse.swt.graphics - * .Cursor) - */ - @Override - protected void setCursor(Cursor c) { - if (overridingCursor != null) { - c = overridingCursor; - } - super.setCursor(c); - } - - /** - * @param dndSupport - * the dndSupport to set - */ - public void setDndSupport(IDndSupport dndSupport) { - if (dndSupport == this.dndSupport) - return; - IDndSupport oldDndSupport = getDndSupport(); - this.dndSupport = dndSupport; - dndSupportChanged(oldDndSupport, getDndSupport()); - } - - protected IDndSupport getDndSupport() { - return this.dndSupport; - } - - protected void dndSupportChanged(IDndSupport oldDndSupport, - IDndSupport newDndSupport) { - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.event; + +import org.eclipse.draw2d.SWTEventDispatcher; +import org.eclipse.swt.graphics.Cursor; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.dnd.IDndSupport; + +/** + * @author Frank Shaka + * + */ +public abstract class ViewerEventDispatcher extends SWTEventDispatcher { + + private final IGraphicalViewer viewer; + + private IDndSupport dndSupport = null; + + private Cursor overridingCursor = null; + + private boolean active = false; + + /** + * + */ + public ViewerEventDispatcher(IGraphicalViewer viewer) { + this.viewer = viewer; + } + + /** + * @return the viewer + */ + public IGraphicalViewer getViewer() { + return viewer; + } + + /** + * Activates this event dispatcher. If already activated, does nothing. + */ + public final void activate() { + if (isActive()) + return; + + this.active = true; + onActivated(); + } + + /** + * Deactivate this event dispatcher. If already deactivated, does nothing. + */ + public final void deactivate() { + if (!isActive()) + return; + + this.active = false; + onDeactivated(); + } + + /** + * For subclasses to extend. + */ + protected void onActivated() { + } + + /** + * For subclasses to extend. + */ + protected void onDeactivated() { + } + + /** + * Determines if this event dispatcher has been activated. + * + * @return true if this event dispatcher is activated + */ + public final boolean isActive() { + return this.active; + } + + public void updateToolTip() { + } + + public void setOverridingCursor(Cursor cursor) { + if (cursor == this.overridingCursor) + return; + this.overridingCursor = cursor; + if (cursor == null) { + updateCursor(); + } else { + setCursor(cursor); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.SWTEventDispatcher#setCursor(org.eclipse.swt.graphics + * .Cursor) + */ + @Override + protected void setCursor(Cursor c) { + if (overridingCursor != null) { + c = overridingCursor; + } + super.setCursor(c); + } + + /** + * @param dndSupport + * the dndSupport to set + */ + public void setDndSupport(IDndSupport dndSupport) { + if (dndSupport == this.dndSupport) + return; + IDndSupport oldDndSupport = getDndSupport(); + this.dndSupport = dndSupport; + dndSupportChanged(oldDndSupport, getDndSupport()); + } + + protected IDndSupport getDndSupport() { + return this.dndSupport; + } + + protected void dndSupportChanged(IDndSupport oldDndSupport, + IDndSupport newDndSupport) { + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/AbstractStyleSelector.java b/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/AbstractStyleSelector.java index c1998b721..d098e7f0e 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/AbstractStyleSelector.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/AbstractStyleSelector.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.graphicalpolicy; - -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.service.StyleOverrideService; - -/** - * @author Frank Shaka - */ -public abstract class AbstractStyleSelector implements IStyleSelector { - - public String getStyleValue(IGraphicalPart part, String key) { - StyleOverrideService styleOverrideService = (StyleOverrideService) part - .getSite().getViewer().getService(StyleOverrideService.class); - if (styleOverrideService != null && styleOverrideService.isActive()) { - String value = styleOverrideService.getValue(part, key); - if (isValidValue(part, key, value)) - return value; - } - return getStyleValue(part, key, null); - } - - public String getStyleValue(IGraphicalPart part, String key, - IStyleValueProvider defaultValueProvider) { - StyleOverrideService styleOverrideService = (StyleOverrideService) part - .getSite().getViewer().getService(StyleOverrideService.class); - if (styleOverrideService != null && styleOverrideService.isActive()) { - String value = styleOverrideService.getValue(part, key); - if (isValidValue(part, key, value)) - return value; - } - String value = getUserValue(part, key); - - if (!isValidValue(part, key, value) && !ignoresAutoValue(part, key)) - value = getAutoValue(part, key, defaultValueProvider); - return value; - } - - protected boolean isValidValue(IGraphicalPart part, String key, String value) { - return value != null; - } - - protected boolean ignoresAutoValue(IGraphicalPart part, String key) { - return false; - } - - public abstract String getUserValue(IGraphicalPart part, String key); - - public String getAutoValue(IGraphicalPart part, String key) { - return getAutoValue(part, key, null); - } - - public abstract String getAutoValue(IGraphicalPart part, String key, - IStyleValueProvider defaultValueProvider); - - public String getOverridedValue(IGraphicalPart part, String key, - String layerName) { - return null; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.graphicalpolicy; + +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.service.StyleOverrideService; + +/** + * @author Frank Shaka + */ +public abstract class AbstractStyleSelector implements IStyleSelector { + + public String getStyleValue(IGraphicalPart part, String key) { + StyleOverrideService styleOverrideService = (StyleOverrideService) part + .getSite().getViewer().getService(StyleOverrideService.class); + if (styleOverrideService != null && styleOverrideService.isActive()) { + String value = styleOverrideService.getValue(part, key); + if (isValidValue(part, key, value)) + return value; + } + return getStyleValue(part, key, null); + } + + public String getStyleValue(IGraphicalPart part, String key, + IStyleValueProvider defaultValueProvider) { + StyleOverrideService styleOverrideService = (StyleOverrideService) part + .getSite().getViewer().getService(StyleOverrideService.class); + if (styleOverrideService != null && styleOverrideService.isActive()) { + String value = styleOverrideService.getValue(part, key); + if (isValidValue(part, key, value)) + return value; + } + String value = getUserValue(part, key); + + if (!isValidValue(part, key, value) && !ignoresAutoValue(part, key)) + value = getAutoValue(part, key, defaultValueProvider); + return value; + } + + protected boolean isValidValue(IGraphicalPart part, String key, String value) { + return value != null; + } + + protected boolean ignoresAutoValue(IGraphicalPart part, String key) { + return false; + } + + public abstract String getUserValue(IGraphicalPart part, String key); + + public String getAutoValue(IGraphicalPart part, String key) { + return getAutoValue(part, key, null); + } + + public abstract String getAutoValue(IGraphicalPart part, String key, + IStyleValueProvider defaultValueProvider); + + public String getOverridedValue(IGraphicalPart part, String key, + String layerName) { + return null; + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/IStyleValueProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/IStyleValueProvider.java index 0f0af1d51..1fef2c724 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/IStyleValueProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/graphicalpolicy/IStyleValueProvider.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.graphicalpolicy; - -import org.xmind.gef.part.IGraphicalPart; - -public interface IStyleValueProvider { - - boolean isKeyInteresting(IGraphicalPart part, String key); - - String getValue(IGraphicalPart part, String key); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.graphicalpolicy; + +import org.xmind.gef.part.IGraphicalPart; + +public interface IStyleValueProvider { + + boolean isKeyInteresting(IGraphicalPart part, String key); + + String getValue(IGraphicalPart part, String key); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/FigureRenderer.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/FigureRenderer.java index 60ad3c6a7..e4bd86a95 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/FigureRenderer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/FigureRenderer.java @@ -1,208 +1,208 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.image; - -import java.util.List; -import java.util.Stack; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.SWTGraphics; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.xmind.gef.draw2d.graphics.ScaledGraphics; - -/** - * @author Frank Shaka - * - */ -public class FigureRenderer implements IRenderer { - - private IFigure[] figures = null; - - private Rectangle bounds = null; - - private double scale = -1; - - /** - * - */ - public FigureRenderer() { - super(); - } - - public void init(IExportSourceProvider source, IExportAreaProvider area) { - setFigures(source.getContents()); - setBounds(area.getExportArea()); - setScale(area.getScale()); - } - - /** - * @param bounds - * the bounds to set - */ - public void setBounds(Rectangle bounds) { - this.bounds = bounds; - } - - /** - * @param scale - * the scale to set - */ - public void setScale(double scale) { - this.scale = scale; - } - - /** - * @param figures - * the figures to set - */ - public void setFigures(IFigure[] figures) { - this.figures = figures; - } - - public Rectangle getBounds() { - return bounds; - } - - /** - * @return the scale - */ - public double getScale() { - return scale; - } - - /** - * @return the figures - */ - public IFigure[] getFigures() { - return figures; - } - - public void render(GC gc) { - render(gc, (Image) null); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.image.IRenderer#render(org.eclipse.swt.graphics.GC) - */ - public void render(GC gc, Image watermark) { - if (figures == null) - return; - - Stack graphicsStack = new Stack(); - SWTGraphics baseGraphics = new SWTGraphics(gc); - graphicsStack.push(baseGraphics); - createGraphics(baseGraphics, graphicsStack); - Graphics graphics = graphicsStack.peek(); - try { - graphics.pushState(); - try { - for (int i = 0; i < figures.length; i++) { - IFigure figure = figures[i]; - figure.paint(graphics); - graphics.restoreState(); - } - - drawWatermarkImage(graphics, watermark); - } finally { - graphics.popState(); - } - } finally { - while (!graphicsStack.isEmpty()) { - graphicsStack.pop().dispose(); - } - } - } - - private void drawWatermarkImage(Graphics graphics, Image watermark) { - if (watermark == null || watermark.isDisposed()) { - return; - } - - graphics.setAlpha(0x19); - - double scale = getScale() > 0 ? getScale() : 1; - int x = bounds.x + bounds.width - - (int) (watermark.getBounds().width * scale); - int y = bounds.y + bounds.height - - (int) (watermark.getBounds().height * scale); - graphics.drawImage(watermark, x, y); - } - - /** - * @param gc - * @param origin - * The origin of the painted content - */ - public void render(GC gc, Point origin) { - if (figures == null) - return; - - Stack graphicsStack = new Stack(); - SWTGraphics baseGraphics = new SWTGraphics(gc); - graphicsStack.push(baseGraphics); - createGraphics(baseGraphics, graphicsStack); - Graphics graphics = graphicsStack.peek(); - try { - graphics.pushState(); - try { - if (origin != null) { - graphics.translate(origin.x, origin.y); - } - for (int i = 0; i < figures.length; i++) { - IFigure figure = figures[i]; - figure.paint(graphics); - } - } finally { - graphics.popState(); - } - } finally { - while (!graphicsStack.isEmpty()) { - graphicsStack.pop().dispose(); - } - } - } - - /** - * @param graphics - * @param stack - */ - protected void createGraphics(Graphics graphics, Stack stack) { - if (bounds != null) { - graphics.translate(-bounds.x, -bounds.y); - } - if (scale > 0) { - if (ScaledGraphics.SCALED_GRAPHICS_ENABLED) { - ScaledGraphics scaledGraphics = new ScaledGraphics(graphics); - scaledGraphics.scale(scale); - stack.push(scaledGraphics); - graphics = scaledGraphics; - } else { - graphics.scale(scale); - } - } - } - - protected Graphics addScaledGraphics(Graphics graphics, - List additionalGraphics) { - return graphics; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.image; + +import java.util.List; +import java.util.Stack; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.SWTGraphics; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.xmind.gef.draw2d.graphics.ScaledGraphics; + +/** + * @author Frank Shaka + * + */ +public class FigureRenderer implements IRenderer { + + private IFigure[] figures = null; + + private Rectangle bounds = null; + + private double scale = -1; + + /** + * + */ + public FigureRenderer() { + super(); + } + + public void init(IExportSourceProvider source, IExportAreaProvider area) { + setFigures(source.getContents()); + setBounds(area.getExportArea()); + setScale(area.getScale()); + } + + /** + * @param bounds + * the bounds to set + */ + public void setBounds(Rectangle bounds) { + this.bounds = bounds; + } + + /** + * @param scale + * the scale to set + */ + public void setScale(double scale) { + this.scale = scale; + } + + /** + * @param figures + * the figures to set + */ + public void setFigures(IFigure[] figures) { + this.figures = figures; + } + + public Rectangle getBounds() { + return bounds; + } + + /** + * @return the scale + */ + public double getScale() { + return scale; + } + + /** + * @return the figures + */ + public IFigure[] getFigures() { + return figures; + } + + public void render(GC gc) { + render(gc, (Image) null); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.image.IRenderer#render(org.eclipse.swt.graphics.GC) + */ + public void render(GC gc, Image watermark) { + if (figures == null) + return; + + Stack graphicsStack = new Stack(); + SWTGraphics baseGraphics = new SWTGraphics(gc); + graphicsStack.push(baseGraphics); + createGraphics(baseGraphics, graphicsStack); + Graphics graphics = graphicsStack.peek(); + try { + graphics.pushState(); + try { + for (int i = 0; i < figures.length; i++) { + IFigure figure = figures[i]; + figure.paint(graphics); + graphics.restoreState(); + } + + drawWatermarkImage(graphics, watermark); + } finally { + graphics.popState(); + } + } finally { + while (!graphicsStack.isEmpty()) { + graphicsStack.pop().dispose(); + } + } + } + + private void drawWatermarkImage(Graphics graphics, Image watermark) { + if (watermark == null || watermark.isDisposed()) { + return; + } + + graphics.setAlpha(0x19); + + double scale = getScale() > 0 ? getScale() : 1; + int x = bounds.x + bounds.width + - (int) (watermark.getBounds().width * scale); + int y = bounds.y + bounds.height + - (int) (watermark.getBounds().height * scale); + graphics.drawImage(watermark, x, y); + } + + /** + * @param gc + * @param origin + * The origin of the painted content + */ + public void render(GC gc, Point origin) { + if (figures == null) + return; + + Stack graphicsStack = new Stack(); + SWTGraphics baseGraphics = new SWTGraphics(gc); + graphicsStack.push(baseGraphics); + createGraphics(baseGraphics, graphicsStack); + Graphics graphics = graphicsStack.peek(); + try { + graphics.pushState(); + try { + if (origin != null) { + graphics.translate(origin.x, origin.y); + } + for (int i = 0; i < figures.length; i++) { + IFigure figure = figures[i]; + figure.paint(graphics); + } + } finally { + graphics.popState(); + } + } finally { + while (!graphicsStack.isEmpty()) { + graphicsStack.pop().dispose(); + } + } + } + + /** + * @param graphics + * @param stack + */ + protected void createGraphics(Graphics graphics, Stack stack) { + if (bounds != null) { + graphics.translate(-bounds.x, -bounds.y); + } + if (scale > 0) { + if (ScaledGraphics.SCALED_GRAPHICS_ENABLED) { + ScaledGraphics scaledGraphics = new ScaledGraphics(graphics); + scaledGraphics.scale(scale); + stack.push(scaledGraphics); + graphics = scaledGraphics; + } else { + graphics.scale(scale); + } + } + } + + protected Graphics addScaledGraphics(Graphics graphics, + List additionalGraphics) { + return graphics; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportAreaProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportAreaProvider.java index ebb79b790..de862819f 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportAreaProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportAreaProvider.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.image; - -import org.eclipse.draw2d.geometry.Rectangle; - -public interface IExportAreaProvider { - - Rectangle getExportArea(); - - double getScale(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.image; + +import org.eclipse.draw2d.geometry.Rectangle; + +public interface IExportAreaProvider { + + Rectangle getExportArea(); + + double getScale(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportSourceProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportSourceProvider.java index c2abd2974..4fdbcaf08 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportSourceProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/IExportSourceProvider.java @@ -1,33 +1,33 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.image; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; - -/** - * @author Frank Shaka - * - */ -public interface IExportSourceProvider { - - IFigure[] getContents(); - - Rectangle getSourceArea(); - - Insets getMargins(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.image; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; + +/** + * @author Frank Shaka + * + */ +public interface IExportSourceProvider { + + IFigure[] getContents(); + + Rectangle getSourceArea(); + + Insets getMargins(); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/IRenderer.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/IRenderer.java index 7f70ffeaf..e007c453b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/IRenderer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/IRenderer.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.image; - -import org.eclipse.swt.graphics.GC; - -/** - * @author Frank Shaka - * - */ -public interface IRenderer { - - void render(GC gc); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.image; + +import org.eclipse.swt.graphics.GC; + +/** + * @author Frank Shaka + * + */ +public interface IRenderer { + + void render(GC gc); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/ImageExportUtils.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/ImageExportUtils.java index 3393e407c..6464eb806 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/ImageExportUtils.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/ImageExportUtils.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.image; - -import java.io.OutputStream; - -import org.eclipse.draw2d.FreeformFigure; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.internal.image.ConstrainedExportAreaProvider; -import org.xmind.gef.internal.image.FittedExportAreaProvider; -import org.xmind.gef.internal.image.MaxPixelsExportAreaProvider; -import org.xmind.gef.internal.image.SWTImageWriter; -import org.xmind.gef.internal.image.StretchedExportAreaProvider; - -public class ImageExportUtils { - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea) { - return createExportAreaProvider(sourceArea, ResizeConstants.RESIZE_NONE, - -1, -1, null); - } - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea, int resizeStrategy) { - return createExportAreaProvider(sourceArea, resizeStrategy, -1, -1, - null); - } - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea, int resizeStrategy, int wHint, int hHint) { - return createExportAreaProvider(sourceArea, resizeStrategy, wHint, - hHint, null); - } - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea, int resizeStrategy, Insets margins) { - return createExportAreaProvider(sourceArea, resizeStrategy, -1, -1, - margins); - } - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea, Insets margins) { - return createExportAreaProvider(sourceArea, ResizeConstants.RESIZE_NONE, - -1, -1, margins); - } - - public static IExportAreaProvider createExportAreaProvider( - Rectangle sourceArea, int resizeStrategy, int wHint, int hHint, - Insets margins) { - switch (resizeStrategy) { - case ResizeConstants.RESIZE_STRETCH: - return new StretchedExportAreaProvider(sourceArea, wHint, hHint, - margins); - case ResizeConstants.RESIZE_FIT: - return new FittedExportAreaProvider(sourceArea, wHint, hHint, - margins); - case ResizeConstants.RESIZE_CONSTRAIN: - return new ConstrainedExportAreaProvider(sourceArea, wHint, hHint, - margins); - case ResizeConstants.RESIZE_MAXPIXELS: - return new MaxPixelsExportAreaProvider(sourceArea, wHint, hHint, - margins); - } - return new ExportAreaProvider(sourceArea, wHint, hHint, margins); - } - - public static ImageWriter createImageWriter(Image image, int format, - OutputStream output) { - return new SWTImageWriter(image, format, output); - } - - public static ImageWriter createImageWriter(ImageData[] imageData, - int format, OutputStream output) { - return new SWTImageWriter(imageData, format, output); - } - - public static Rectangle calcBoundsUnion(IFigure[] figures) { - Rectangle r = null; - for (IFigure figure : figures) { - r = Geometry.union(r, getBounds(figure)); - } - return r; - } - - public static Rectangle calcBoundsIntersection(IFigure[] figures) { - Rectangle r = null; - for (IFigure figure : figures) { - r = Geometry.intersect(r, getBounds(figure)); - } - return r; - } - - public static Rectangle getBounds(IFigure figure) { - if (figure instanceof FreeformFigure) { - return ((FreeformFigure) figure).getFreeformExtent(); - } - return figure.getBounds(); - } - - public static Image createImage(Device device, IExportSourceProvider source, - int resizeStrategy, int wHint, int hHint) { - IExportAreaProvider area = createExportAreaProvider( - source.getSourceArea(), resizeStrategy, wHint, hHint, - source.getMargins()); - FigureRenderer renderer = new FigureRenderer(); - renderer.init(source, area); - return createImage(device, renderer); -// ImageDescriptor imageDescriptor = createImageDescriptor(source, -// resizeStrategy, wHint, hHint); -// return imageDescriptor.createImage(false, device); - } - - public static Image createImage(Device device, FigureRenderer renderer) { - Rectangle bounds = renderer.getBounds(); - Image image = new Image(device, bounds.width, bounds.height); - GC gc = new GC(image); - try { - renderer.render(gc); - } finally { - gc.dispose(); - } - return image; - } - - /** - * - * @param image - * @param stream - * @param format - */ - public static void saveImage(Image image, OutputStream stream, int format) { - ImageData data = image.getImageData(); - ImageLoader saver = new ImageLoader(); - saver.data = new ImageData[] { data }; - saver.save(stream, format); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.image; + +import java.io.OutputStream; + +import org.eclipse.draw2d.FreeformFigure; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.internal.image.ConstrainedExportAreaProvider; +import org.xmind.gef.internal.image.FittedExportAreaProvider; +import org.xmind.gef.internal.image.MaxPixelsExportAreaProvider; +import org.xmind.gef.internal.image.SWTImageWriter; +import org.xmind.gef.internal.image.StretchedExportAreaProvider; + +public class ImageExportUtils { + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea) { + return createExportAreaProvider(sourceArea, ResizeConstants.RESIZE_NONE, + -1, -1, null); + } + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea, int resizeStrategy) { + return createExportAreaProvider(sourceArea, resizeStrategy, -1, -1, + null); + } + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea, int resizeStrategy, int wHint, int hHint) { + return createExportAreaProvider(sourceArea, resizeStrategy, wHint, + hHint, null); + } + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea, int resizeStrategy, Insets margins) { + return createExportAreaProvider(sourceArea, resizeStrategy, -1, -1, + margins); + } + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea, Insets margins) { + return createExportAreaProvider(sourceArea, ResizeConstants.RESIZE_NONE, + -1, -1, margins); + } + + public static IExportAreaProvider createExportAreaProvider( + Rectangle sourceArea, int resizeStrategy, int wHint, int hHint, + Insets margins) { + switch (resizeStrategy) { + case ResizeConstants.RESIZE_STRETCH: + return new StretchedExportAreaProvider(sourceArea, wHint, hHint, + margins); + case ResizeConstants.RESIZE_FIT: + return new FittedExportAreaProvider(sourceArea, wHint, hHint, + margins); + case ResizeConstants.RESIZE_CONSTRAIN: + return new ConstrainedExportAreaProvider(sourceArea, wHint, hHint, + margins); + case ResizeConstants.RESIZE_MAXPIXELS: + return new MaxPixelsExportAreaProvider(sourceArea, wHint, hHint, + margins); + } + return new ExportAreaProvider(sourceArea, wHint, hHint, margins); + } + + public static ImageWriter createImageWriter(Image image, int format, + OutputStream output) { + return new SWTImageWriter(image, format, output); + } + + public static ImageWriter createImageWriter(ImageData[] imageData, + int format, OutputStream output) { + return new SWTImageWriter(imageData, format, output); + } + + public static Rectangle calcBoundsUnion(IFigure[] figures) { + Rectangle r = null; + for (IFigure figure : figures) { + r = Geometry.union(r, getBounds(figure)); + } + return r; + } + + public static Rectangle calcBoundsIntersection(IFigure[] figures) { + Rectangle r = null; + for (IFigure figure : figures) { + r = Geometry.intersect(r, getBounds(figure)); + } + return r; + } + + public static Rectangle getBounds(IFigure figure) { + if (figure instanceof FreeformFigure) { + return ((FreeformFigure) figure).getFreeformExtent(); + } + return figure.getBounds(); + } + + public static Image createImage(Device device, IExportSourceProvider source, + int resizeStrategy, int wHint, int hHint) { + IExportAreaProvider area = createExportAreaProvider( + source.getSourceArea(), resizeStrategy, wHint, hHint, + source.getMargins()); + FigureRenderer renderer = new FigureRenderer(); + renderer.init(source, area); + return createImage(device, renderer); +// ImageDescriptor imageDescriptor = createImageDescriptor(source, +// resizeStrategy, wHint, hHint); +// return imageDescriptor.createImage(false, device); + } + + public static Image createImage(Device device, FigureRenderer renderer) { + Rectangle bounds = renderer.getBounds(); + Image image = new Image(device, bounds.width, bounds.height); + GC gc = new GC(image); + try { + renderer.render(gc); + } finally { + gc.dispose(); + } + return image; + } + + /** + * + * @param image + * @param stream + * @param format + */ + public static void saveImage(Image image, OutputStream stream, int format) { + ImageData data = image.getImageData(); + ImageLoader saver = new ImageLoader(); + saver.data = new ImageData[] { data }; + saver.save(stream, format); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/ResizeConstants.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/ResizeConstants.java index 7ecaa0521..24bf01e2d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/ResizeConstants.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/ResizeConstants.java @@ -1,53 +1,53 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.image; - -public class ResizeConstants { - - /** - * Resize Strategy: Original Size
    - * No resizing should be performed and the image remains its original size. - */ - public static final int RESIZE_NONE = 0; - - /** - * Resize Strategy: Stretch
    - * The image is to be stretched horizontally and vertically to cover - * the whole area. - */ - public static final int RESIZE_STRETCH = 1; - - /** - * Resize Strategy: Fit
    - * The image is to be scaled to fit in the area, which means to get its - * width or height equal to or shorter than the area's. - */ - public static final int RESIZE_FIT = 2; - - /** - * Resize Strategy: Constrain
    - * If the width or height of the image is longer than the area's, the image - * is to be fitted in that area, otherwise, it will remain its orginal size; - */ - public static final int RESIZE_CONSTRAIN = 3; - - /** - * Resize Strategy: Max Pixels
    - * If the total pixels of the image is more than the area's, the image is to - * be fitted into the area's total pixels, keeping the image's width/height - * ratio but disregarding the area's. - */ - public static final int RESIZE_MAXPIXELS = 4; - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.image; + +public class ResizeConstants { + + /** + * Resize Strategy: Original Size
    + * No resizing should be performed and the image remains its original size. + */ + public static final int RESIZE_NONE = 0; + + /** + * Resize Strategy: Stretch
    + * The image is to be stretched horizontally and vertically to cover + * the whole area. + */ + public static final int RESIZE_STRETCH = 1; + + /** + * Resize Strategy: Fit
    + * The image is to be scaled to fit in the area, which means to get its + * width or height equal to or shorter than the area's. + */ + public static final int RESIZE_FIT = 2; + + /** + * Resize Strategy: Constrain
    + * If the width or height of the image is longer than the area's, the image + * is to be fitted in that area, otherwise, it will remain its orginal size; + */ + public static final int RESIZE_CONSTRAIN = 3; + + /** + * Resize Strategy: Max Pixels
    + * If the total pixels of the image is more than the area's, the image is to + * be fitted into the area's total pixels, keeping the image's width/height + * ratio but disregarding the area's. + */ + public static final int RESIZE_MAXPIXELS = 4; + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/image/ViewerExportSourceProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/image/ViewerExportSourceProvider.java index 06d2fd66e..8c8ec1a8a 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/image/ViewerExportSourceProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/image/ViewerExportSourceProvider.java @@ -1,151 +1,151 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.image; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LightweightSystem; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.IGraphicalViewer; - -/** - * @author Frank Shaka - * - */ -public class ViewerExportSourceProvider implements IExportSourceProvider { - - private IGraphicalViewer viewer; - - private Insets margins; - - private IFigure[] contents = null; - - private Rectangle sourceArea = null; - - /** - * - */ - public ViewerExportSourceProvider(IGraphicalViewer viewer, Insets margins) { - this.viewer = viewer; - this.margins = margins; - } - - /** - * - */ - public ViewerExportSourceProvider(IGraphicalViewer viewer, int allMargin) { - this(viewer, new Insets(allMargin)); - } - - public ViewerExportSourceProvider(IGraphicalViewer viewer) { - this(viewer, new Insets(0)); - } - - protected LightweightSystem getLightweightSystem() { - if (viewer instanceof GraphicalViewer) - return ((GraphicalViewer) viewer).getLightweightSystem(); - return viewer.getCanvas().getLightweightSystem(); - } - - public IGraphicalViewer getViewer() { - return this.viewer; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.image.IExportSourceProvider#getContents() - */ - public IFigure[] getContents() { - if (contents == null) { - contents = collectContents(); - } - return contents; - } - - private IFigure[] collectContents() { - List figures = new ArrayList(5); - collectContents(figures); - return figures.toArray(new IFigure[figures.size()]); - } - - /** - * @param figures - */ - protected void collectContents(List figures) { - figures.add(getDefaultFigure()); - } - - /** - * @return - */ - protected IFigure getDefaultFigure() { - IFigure contents = getViewer().getCanvas().getViewport().getContents(); - if (contents != null) - return contents; - IFigure rootFigure = getLightweightSystem().getRootFigure(); - List children = rootFigure.getChildren(); - if (children.size() > 0) { - return (IFigure) children.get(0); - } - return rootFigure; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.image.IExportSourceProvider#getSourceArea() - */ - public Rectangle getSourceArea() { - if (sourceArea == null) { - sourceArea = calculateSourceArea( - getContentsForCalculatingSourceArea()); - } - return sourceArea; - } - - protected IFigure[] getContentsForCalculatingSourceArea() { - List figures = new ArrayList(5); - collectContentsForCalculatingSourceArea(figures); - return figures.toArray(new IFigure[figures.size()]); - } - - protected void collectContentsForCalculatingSourceArea( - List figures) { - collectContents(figures); - } - - /** - * @param contents2 - * @return - */ - protected Rectangle calculateSourceArea(IFigure[] contents) { - return ImageExportUtils.calcBoundsUnion(contents); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.image.IExportSourceProvider#getMargins() - */ - public Insets getMargins() { - return margins; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.image; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LightweightSystem; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.IGraphicalViewer; + +/** + * @author Frank Shaka + * + */ +public class ViewerExportSourceProvider implements IExportSourceProvider { + + private IGraphicalViewer viewer; + + private Insets margins; + + private IFigure[] contents = null; + + private Rectangle sourceArea = null; + + /** + * + */ + public ViewerExportSourceProvider(IGraphicalViewer viewer, Insets margins) { + this.viewer = viewer; + this.margins = margins; + } + + /** + * + */ + public ViewerExportSourceProvider(IGraphicalViewer viewer, int allMargin) { + this(viewer, new Insets(allMargin)); + } + + public ViewerExportSourceProvider(IGraphicalViewer viewer) { + this(viewer, new Insets(0)); + } + + protected LightweightSystem getLightweightSystem() { + if (viewer instanceof GraphicalViewer) + return ((GraphicalViewer) viewer).getLightweightSystem(); + return viewer.getCanvas().getLightweightSystem(); + } + + public IGraphicalViewer getViewer() { + return this.viewer; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.image.IExportSourceProvider#getContents() + */ + public IFigure[] getContents() { + if (contents == null) { + contents = collectContents(); + } + return contents; + } + + private IFigure[] collectContents() { + List figures = new ArrayList(5); + collectContents(figures); + return figures.toArray(new IFigure[figures.size()]); + } + + /** + * @param figures + */ + protected void collectContents(List figures) { + figures.add(getDefaultFigure()); + } + + /** + * @return + */ + protected IFigure getDefaultFigure() { + IFigure contents = getViewer().getCanvas().getViewport().getContents(); + if (contents != null) + return contents; + IFigure rootFigure = getLightweightSystem().getRootFigure(); + List children = rootFigure.getChildren(); + if (children.size() > 0) { + return (IFigure) children.get(0); + } + return rootFigure; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.image.IExportSourceProvider#getSourceArea() + */ + public Rectangle getSourceArea() { + if (sourceArea == null) { + sourceArea = calculateSourceArea( + getContentsForCalculatingSourceArea()); + } + return sourceArea; + } + + protected IFigure[] getContentsForCalculatingSourceArea() { + List figures = new ArrayList(5); + collectContentsForCalculatingSourceArea(figures); + return figures.toArray(new IFigure[figures.size()]); + } + + protected void collectContentsForCalculatingSourceArea( + List figures) { + collectContents(figures); + } + + /** + * @param contents2 + * @return + */ + protected Rectangle calculateSourceArea(IFigure[] contents) { + return ImageExportUtils.calcBoundsUnion(contents); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.image.IExportSourceProvider#getMargins() + */ + public Insets getMargins() { + return margins; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/ImageConverter.java b/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/ImageConverter.java index 2f724b918..7d79d2713 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/ImageConverter.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/ImageConverter.java @@ -1,438 +1,438 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.internal.image; - -import java.awt.image.BufferedImage; -import java.awt.image.WritableRaster; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; -import org.xmind.neuquant.NeuQuant; - -/** - * @author Frank Shaka - */ -public class ImageConverter { - - private static final int DEPTH_256 = 8; - - private static final int OFFSET = 3; - - private static final int MASK = (0xFF >> OFFSET) << OFFSET; - - private static final int INIT_COLOR_DIFFERENCE_THRESHOLD = 255 * 3; - - /** - * @param srcImage - * @return - */ - public static ImageData converTo256Colors(ImageData srcImage) { - return convertDepth_4(srcImage, DEPTH_256); - } - - protected static ImageData convertDepth(ImageData srcImage, int depth) { - int numMaxColors = 1 << depth; - final Map colorOccurrences = new HashMap(); - - /* Calculate occurrences of each color in source image */ - PaletteData srcPalette = srcImage.palette; - for (int i = 0; i < srcImage.width; i++) { - for (int j = 0; j < srcImage.height; j++) { - RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); - - /* - * Cut off lower bits of each color value in order to reduce the - * differences among colors and raise the frequencies of colors - * with lower occurrences. The disadvantage is that it makes the - * image a little distorted since most of the colors will be - * changed. - */ - rgb = getShortenedRGB(rgb); - - int occur = !colorOccurrences.containsKey(rgb) ? 1 - : colorOccurrences.get(rgb) + 1; - colorOccurrences.put(rgb, occur); - } - } - - /* Sort colors by occurrences */ - Set sortedColors = new TreeSet(new Comparator() { - public int compare(RGB o1, RGB o2) { - int x = colorOccurrences.get(o2) - colorOccurrences.get(o1); - return x == 0 ? 1 : x; - } - }); - sortedColors.addAll(colorOccurrences.keySet()); - - /* Filter colors to fit within the max size */ - List newPaletteColors = new ArrayList(sortedColors); - if (newPaletteColors.size() > numMaxColors) - /* Cut off colors with lower occurrrences */ - newPaletteColors = newPaletteColors.subList(0, numMaxColors); - - /* Generate new palette */ - RGB[] colors = newPaletteColors - .toArray(new RGB[newPaletteColors.size()]); - PaletteData newPalette = new PaletteData(colors); - - Map pixelValues = new HashMap(); - for (int i = 0; i < colors.length; i++) { - pixelValues.put(colors[i], i); - } - - Map oldToNew = new HashMap(); - - /* Generate new image from source image with new palette */ - ImageData result = new ImageData(srcImage.width, srcImage.height, - depth, newPalette); - for (int i = 0; i < srcImage.width; i++) { - for (int j = 0; j < srcImage.height; j++) { - RGB oldColor = srcPalette.getRGB(srcImage.getPixel(i, j)); - - /* Convert colors from source image to colors in new palette */ - RGB newColor = oldToNew.get(oldColor); - if (newColor == null) { - newColor = findSimilarColor(oldColor, colors); - oldToNew.put(oldColor, newColor); - } - - result.setPixel(i, j, pixelValues.get(newColor)); - } - } - return result; - } - - /** - * @param rgb - * @return - */ - private static RGB getShortenedRGB(RGB rgb) { - rgb.red = rgb.red & MASK; - rgb.blue = rgb.blue & MASK; - rgb.green = rgb.green & MASK; - return rgb; - } - - private static RGB findSimilarColor(RGB src, RGB[] colors) { - RGB result = null; - int droppingThreshold = INIT_COLOR_DIFFERENCE_THRESHOLD; - for (int i = 0; i < colors.length; i++) { - RGB toTest = colors[i]; - int diff = getColorDifference(src, toTest); - if (diff < droppingThreshold) { - droppingThreshold = diff; - result = toTest; - } - } - return result; - } - - static int getColorDifference(RGB c1, RGB c2) { - return Math.abs(c1.red - c2.red) + Math.abs(c1.green - c2.green) - + Math.abs(c1.blue - c2.blue); - } - - protected static ImageData convertDepth_2(ImageData srcImage, int depth) { - int numMaxColors = 1 << depth; - final Map colorOccurrences = new HashMap(); - - /* Calculate occurrences of each color in source image */ - PaletteData srcPalette = srcImage.palette; - for (int i = 0; i < srcImage.width; i++) { - for (int j = 0; j < srcImage.height; j++) { - RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); - int occur = !colorOccurrences.containsKey(rgb) ? 1 - : colorOccurrences.get(rgb) + 1; - colorOccurrences.put(rgb, occur); - } - } - - IColorReplacingPolicy policy; - if (colorOccurrences.size() <= numMaxColors) { - policy = new SameColorReplacingPolicy(); - } else { - policy = new MinRiskColorReplacingPolicy(); - } - - PaletteData newPalette = new PaletteData(policy.getReplacingColors( - numMaxColors, colorOccurrences)); - Map pixelValues = new HashMap(); - RGB[] rgbs = newPalette.getRGBs(); - for (int i = 0; i < rgbs.length; i++) { - pixelValues.put(rgbs[i], i); - } - - /* Generate new image from source image with new palette */ - ImageData result = new ImageData(srcImage.width, srcImage.height, - depth, newPalette); - for (int i = 0; i < srcImage.width; i++) { - for (int j = 0; j < srcImage.height; j++) { - RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); - RGB newRGB = policy.getReplacedColor(rgb); - result.setPixel(i, j, pixelValues.get(newRGB)); - } - } - return result; - } - -// protected static ImageData convertDepth_3(ImageData srcImage, int depth) { -// EightTreeQuantizer quantizer = new EightTreeQuantizer(depth); -// final Map colorOccurrences = new HashMap(); -// -// /* Calculate occurrences of each color in source image */ -// PaletteData srcPalette = srcImage.palette; -// for (int i = 0; i < srcImage.width; i++) { -// for (int j = 0; j < srcImage.height; j++) { -// RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); -// int occur = !colorOccurrences.containsKey(rgb) ? 1 -// : colorOccurrences.get(rgb) + 1; -// colorOccurrences.put(rgb, occur); -// } -// } -// quantizer.setColorOccurrences(colorOccurrences); -// return quantizer.processImage(srcImage); -// } - - protected static ImageData convertDepth_4(ImageData srcImage, int depth) { - if (depth != DEPTH_256) - throw new IllegalArgumentException(); - NeuQuant nq = new NeuQuant(); - nq.init(srcImage, 1); - PaletteData oldPalette = srcImage.palette; - PaletteData newPalette = new PaletteData(nq.getColourMap()); - int width = srcImage.width; - int height = srcImage.height; - ImageData result = new ImageData(width, height, depth, newPalette); - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - RGB rgb = oldPalette.getRGB(srcImage.getPixel(i, j)); -// rgb = nq.convert( rgb ); -// result.setPixel( i, j, newPalette.getPixel( rgb ) ); -// result.setPixel( i, j, newPalette.getPixel( rgb ) ); - result.setPixel(i, j, nq.lookup(rgb)); - } - } - return result; - } - - private static final PaletteData PALETTE_DATA = new PaletteData(0xFF0000, - 0xFF00, 0xFF); - - /** - * Converts an AWT based buffered image into an SWT Image. This - * will always return an Image that has 24 bit depth regardless - * of the type of AWT buffered image that is passed into the method. - * - * @param srcImage - * the {@link java.awt.image.BufferedImage} to be converted to an - * Image - * @return an Image that represents the same image data as the - * AWT BufferedImage type. - */ - public static Image convert(Device device, BufferedImage srcImage) { - // We can force bitdepth to be 24 bit because BufferedImage getRGB allows us to always - // retrieve 24 bit data regardless of source color depth. - ImageData swtImageData = new ImageData(srcImage.getWidth(), srcImage - .getHeight(), 24, PALETTE_DATA); - - // ensure scansize is aligned on 32 bit. - int scansize = (((srcImage.getWidth() * 3) + 3) * 4) / 4; - - WritableRaster alphaRaster = srcImage.getAlphaRaster(); - byte[] alphaBytes = new byte[srcImage.getWidth()]; - - for (int y = 0; y < srcImage.getHeight(); y++) { - int[] buff = srcImage.getRGB(0, y, srcImage.getWidth(), 1, null, 0, - scansize); - swtImageData.setPixels(0, y, srcImage.getWidth(), buff, 0); - - // check for alpha channel - if (alphaRaster != null) { - int[] alpha = alphaRaster.getPixels(0, y, srcImage.getWidth(), - 1, (int[]) null); - for (int i = 0; i < srcImage.getWidth(); i++) - alphaBytes[i] = (byte) alpha[i]; - swtImageData - .setAlphas(0, y, srcImage.getWidth(), alphaBytes, 0); - } - } - - return new Image(device, swtImageData); - } - - /** - * Converts an swt based image into an AWT BufferedImage. This - * will always return a BufferedImage that is of type - * BufferedImage.TYPE_INT_ARGB regardless of the type of swt - * image that is passed into the method. - * - * @param srcImage - * the {@link org.eclipse.swt.graphics.Image} to be converted to - * a BufferedImage - * @return a BufferedImage that represents the same image data - * as the swt Image - */ - public static BufferedImage convert(Image srcImage) { - - ImageData imageData = srcImage.getImageData(); - int width = imageData.width; - int height = imageData.height; - ImageData maskData = null; - int alpha[] = new int[1]; - - if (imageData.alphaData == null) - maskData = imageData.getTransparencyMask(); - - // now we should have the image data for the bitmap, decompressed in imageData[0].data. - // Convert that to a Buffered Image. - BufferedImage image = new BufferedImage(imageData.width, - imageData.height, BufferedImage.TYPE_INT_ARGB); - - WritableRaster alphaRaster = image.getAlphaRaster(); - - // loop over the imagedata and set each pixel in the BufferedImage to the appropriate color. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - int color = imageData.getPixel(x, y); - - color = translateColor(imageData, color); - image.setRGB(x, y, color); - - // check for alpha channel - if (alphaRaster != null) { - if (imageData.alphaData != null) { - alpha[0] = imageData.getAlpha(x, y); - alphaRaster.setPixel(x, y, alpha); - } else { - // check for transparency mask - if (maskData != null) { - alpha[0] = maskData.getPixel(x, y) == 0 ? 0 : 255; - alphaRaster.setPixel(x, y, alpha); - } - } - } - } - } - - return image; - } - - private static int translateColor(ImageData imageData, int color) { - - int bitCount = imageData.depth; - RGB[] rgb = imageData.getRGBs(); - - if (bitCount == 1 || bitCount == 4 || bitCount == 8) { - // Look up actual rgb value in the rgb array. - if (rgb != null) { - java.awt.Color foo = new java.awt.Color(rgb[color].red, - rgb[color].green, rgb[color].blue); - color = foo.getRGB(); - } else { - color = 0; - } - } else if (bitCount == 16) { - int BLUE_MASK = 0x1f; - int GREEN_MASK = 0x3e0; - int RED_MASK = 0x7C00; - - // Each word in the bitmap array represents a single pixels, 5 bits for each - // red, green and blue. - color = applyRGBMask(color, RED_MASK, GREEN_MASK, BLUE_MASK); - } else if (bitCount == 24) { - // 3 8 bit color values. - int blue = (color & 0x00ff0000) >> 16; - int green = (color & 0x0000ff00) >> 8; - int red = (color & 0x000000ff); - - java.awt.Color foo = new java.awt.Color(red, green, blue); - color = foo.getRGB(); - } else if (bitCount == 32) { - int blue = (color & 0xff000000) >>> 24; - int green = (color & 0x00ff0000) >> 16; - int red = (color & 0x0000ff00) >> 8; - - java.awt.Color foo = new java.awt.Color(red, green, blue); - color = foo.getRGB(); - } - - return color; - } - - private static int applyRGBMask(int color, int redMask, int greenMask, - int blueMask) { - int shiftCount; - int maskSize; - int red; - int green; - int blue; - - shiftCount = getShiftCount(redMask); - maskSize = countBits(redMask); - red = (color & redMask) >>> shiftCount; - // Scale the color value to something between 0 and 255. - red = red * 255 / ((int) Math.pow(2, maskSize) - 1); - - shiftCount = getShiftCount(greenMask); - maskSize = countBits(greenMask); - green = (color & greenMask) >>> shiftCount; - // Scale the color value to something between 0 and 255. - green = green * 255 / ((int) Math.pow(2, maskSize) - 1); - - shiftCount = getShiftCount(blueMask); - maskSize = countBits(blueMask); - blue = (color & blueMask) >>> shiftCount; - // Scale the color value to something between 0 and 255. - blue = blue * 255 / ((int) Math.pow(2, maskSize) - 1); - - java.awt.Color foo = new java.awt.Color(red, green, blue); - color = foo.getRGB(); - - return color; - } - - private static int getShiftCount(int mask) { - int count = 0; - - while (mask != 0 && ((mask & 0x1) == 0)) { - mask = mask >>> 1; - count++; - } - - return count; - } - - private static int countBits(int mask) { - int count = 0; - for (int index = 0; index < 32; index++) { - if ((mask & 0x1) != 0) { - count++; - } - mask = mask >>> 1; - } - - return count; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.internal.image; + +import java.awt.image.BufferedImage; +import java.awt.image.WritableRaster; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; +import org.xmind.neuquant.NeuQuant; + +/** + * @author Frank Shaka + */ +public class ImageConverter { + + private static final int DEPTH_256 = 8; + + private static final int OFFSET = 3; + + private static final int MASK = (0xFF >> OFFSET) << OFFSET; + + private static final int INIT_COLOR_DIFFERENCE_THRESHOLD = 255 * 3; + + /** + * @param srcImage + * @return + */ + public static ImageData converTo256Colors(ImageData srcImage) { + return convertDepth_4(srcImage, DEPTH_256); + } + + protected static ImageData convertDepth(ImageData srcImage, int depth) { + int numMaxColors = 1 << depth; + final Map colorOccurrences = new HashMap(); + + /* Calculate occurrences of each color in source image */ + PaletteData srcPalette = srcImage.palette; + for (int i = 0; i < srcImage.width; i++) { + for (int j = 0; j < srcImage.height; j++) { + RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); + + /* + * Cut off lower bits of each color value in order to reduce the + * differences among colors and raise the frequencies of colors + * with lower occurrences. The disadvantage is that it makes the + * image a little distorted since most of the colors will be + * changed. + */ + rgb = getShortenedRGB(rgb); + + int occur = !colorOccurrences.containsKey(rgb) ? 1 + : colorOccurrences.get(rgb) + 1; + colorOccurrences.put(rgb, occur); + } + } + + /* Sort colors by occurrences */ + Set sortedColors = new TreeSet(new Comparator() { + public int compare(RGB o1, RGB o2) { + int x = colorOccurrences.get(o2) - colorOccurrences.get(o1); + return x == 0 ? 1 : x; + } + }); + sortedColors.addAll(colorOccurrences.keySet()); + + /* Filter colors to fit within the max size */ + List newPaletteColors = new ArrayList(sortedColors); + if (newPaletteColors.size() > numMaxColors) + /* Cut off colors with lower occurrrences */ + newPaletteColors = newPaletteColors.subList(0, numMaxColors); + + /* Generate new palette */ + RGB[] colors = newPaletteColors + .toArray(new RGB[newPaletteColors.size()]); + PaletteData newPalette = new PaletteData(colors); + + Map pixelValues = new HashMap(); + for (int i = 0; i < colors.length; i++) { + pixelValues.put(colors[i], i); + } + + Map oldToNew = new HashMap(); + + /* Generate new image from source image with new palette */ + ImageData result = new ImageData(srcImage.width, srcImage.height, + depth, newPalette); + for (int i = 0; i < srcImage.width; i++) { + for (int j = 0; j < srcImage.height; j++) { + RGB oldColor = srcPalette.getRGB(srcImage.getPixel(i, j)); + + /* Convert colors from source image to colors in new palette */ + RGB newColor = oldToNew.get(oldColor); + if (newColor == null) { + newColor = findSimilarColor(oldColor, colors); + oldToNew.put(oldColor, newColor); + } + + result.setPixel(i, j, pixelValues.get(newColor)); + } + } + return result; + } + + /** + * @param rgb + * @return + */ + private static RGB getShortenedRGB(RGB rgb) { + rgb.red = rgb.red & MASK; + rgb.blue = rgb.blue & MASK; + rgb.green = rgb.green & MASK; + return rgb; + } + + private static RGB findSimilarColor(RGB src, RGB[] colors) { + RGB result = null; + int droppingThreshold = INIT_COLOR_DIFFERENCE_THRESHOLD; + for (int i = 0; i < colors.length; i++) { + RGB toTest = colors[i]; + int diff = getColorDifference(src, toTest); + if (diff < droppingThreshold) { + droppingThreshold = diff; + result = toTest; + } + } + return result; + } + + static int getColorDifference(RGB c1, RGB c2) { + return Math.abs(c1.red - c2.red) + Math.abs(c1.green - c2.green) + + Math.abs(c1.blue - c2.blue); + } + + protected static ImageData convertDepth_2(ImageData srcImage, int depth) { + int numMaxColors = 1 << depth; + final Map colorOccurrences = new HashMap(); + + /* Calculate occurrences of each color in source image */ + PaletteData srcPalette = srcImage.palette; + for (int i = 0; i < srcImage.width; i++) { + for (int j = 0; j < srcImage.height; j++) { + RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); + int occur = !colorOccurrences.containsKey(rgb) ? 1 + : colorOccurrences.get(rgb) + 1; + colorOccurrences.put(rgb, occur); + } + } + + IColorReplacingPolicy policy; + if (colorOccurrences.size() <= numMaxColors) { + policy = new SameColorReplacingPolicy(); + } else { + policy = new MinRiskColorReplacingPolicy(); + } + + PaletteData newPalette = new PaletteData(policy.getReplacingColors( + numMaxColors, colorOccurrences)); + Map pixelValues = new HashMap(); + RGB[] rgbs = newPalette.getRGBs(); + for (int i = 0; i < rgbs.length; i++) { + pixelValues.put(rgbs[i], i); + } + + /* Generate new image from source image with new palette */ + ImageData result = new ImageData(srcImage.width, srcImage.height, + depth, newPalette); + for (int i = 0; i < srcImage.width; i++) { + for (int j = 0; j < srcImage.height; j++) { + RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); + RGB newRGB = policy.getReplacedColor(rgb); + result.setPixel(i, j, pixelValues.get(newRGB)); + } + } + return result; + } + +// protected static ImageData convertDepth_3(ImageData srcImage, int depth) { +// EightTreeQuantizer quantizer = new EightTreeQuantizer(depth); +// final Map colorOccurrences = new HashMap(); +// +// /* Calculate occurrences of each color in source image */ +// PaletteData srcPalette = srcImage.palette; +// for (int i = 0; i < srcImage.width; i++) { +// for (int j = 0; j < srcImage.height; j++) { +// RGB rgb = srcPalette.getRGB(srcImage.getPixel(i, j)); +// int occur = !colorOccurrences.containsKey(rgb) ? 1 +// : colorOccurrences.get(rgb) + 1; +// colorOccurrences.put(rgb, occur); +// } +// } +// quantizer.setColorOccurrences(colorOccurrences); +// return quantizer.processImage(srcImage); +// } + + protected static ImageData convertDepth_4(ImageData srcImage, int depth) { + if (depth != DEPTH_256) + throw new IllegalArgumentException(); + NeuQuant nq = new NeuQuant(); + nq.init(srcImage, 1); + PaletteData oldPalette = srcImage.palette; + PaletteData newPalette = new PaletteData(nq.getColourMap()); + int width = srcImage.width; + int height = srcImage.height; + ImageData result = new ImageData(width, height, depth, newPalette); + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + RGB rgb = oldPalette.getRGB(srcImage.getPixel(i, j)); +// rgb = nq.convert( rgb ); +// result.setPixel( i, j, newPalette.getPixel( rgb ) ); +// result.setPixel( i, j, newPalette.getPixel( rgb ) ); + result.setPixel(i, j, nq.lookup(rgb)); + } + } + return result; + } + + private static final PaletteData PALETTE_DATA = new PaletteData(0xFF0000, + 0xFF00, 0xFF); + + /** + * Converts an AWT based buffered image into an SWT Image. This + * will always return an Image that has 24 bit depth regardless + * of the type of AWT buffered image that is passed into the method. + * + * @param srcImage + * the {@link java.awt.image.BufferedImage} to be converted to an + * Image + * @return an Image that represents the same image data as the + * AWT BufferedImage type. + */ + public static Image convert(Device device, BufferedImage srcImage) { + // We can force bitdepth to be 24 bit because BufferedImage getRGB allows us to always + // retrieve 24 bit data regardless of source color depth. + ImageData swtImageData = new ImageData(srcImage.getWidth(), srcImage + .getHeight(), 24, PALETTE_DATA); + + // ensure scansize is aligned on 32 bit. + int scansize = (((srcImage.getWidth() * 3) + 3) * 4) / 4; + + WritableRaster alphaRaster = srcImage.getAlphaRaster(); + byte[] alphaBytes = new byte[srcImage.getWidth()]; + + for (int y = 0; y < srcImage.getHeight(); y++) { + int[] buff = srcImage.getRGB(0, y, srcImage.getWidth(), 1, null, 0, + scansize); + swtImageData.setPixels(0, y, srcImage.getWidth(), buff, 0); + + // check for alpha channel + if (alphaRaster != null) { + int[] alpha = alphaRaster.getPixels(0, y, srcImage.getWidth(), + 1, (int[]) null); + for (int i = 0; i < srcImage.getWidth(); i++) + alphaBytes[i] = (byte) alpha[i]; + swtImageData + .setAlphas(0, y, srcImage.getWidth(), alphaBytes, 0); + } + } + + return new Image(device, swtImageData); + } + + /** + * Converts an swt based image into an AWT BufferedImage. This + * will always return a BufferedImage that is of type + * BufferedImage.TYPE_INT_ARGB regardless of the type of swt + * image that is passed into the method. + * + * @param srcImage + * the {@link org.eclipse.swt.graphics.Image} to be converted to + * a BufferedImage + * @return a BufferedImage that represents the same image data + * as the swt Image + */ + public static BufferedImage convert(Image srcImage) { + + ImageData imageData = srcImage.getImageData(); + int width = imageData.width; + int height = imageData.height; + ImageData maskData = null; + int alpha[] = new int[1]; + + if (imageData.alphaData == null) + maskData = imageData.getTransparencyMask(); + + // now we should have the image data for the bitmap, decompressed in imageData[0].data. + // Convert that to a Buffered Image. + BufferedImage image = new BufferedImage(imageData.width, + imageData.height, BufferedImage.TYPE_INT_ARGB); + + WritableRaster alphaRaster = image.getAlphaRaster(); + + // loop over the imagedata and set each pixel in the BufferedImage to the appropriate color. + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int color = imageData.getPixel(x, y); + + color = translateColor(imageData, color); + image.setRGB(x, y, color); + + // check for alpha channel + if (alphaRaster != null) { + if (imageData.alphaData != null) { + alpha[0] = imageData.getAlpha(x, y); + alphaRaster.setPixel(x, y, alpha); + } else { + // check for transparency mask + if (maskData != null) { + alpha[0] = maskData.getPixel(x, y) == 0 ? 0 : 255; + alphaRaster.setPixel(x, y, alpha); + } + } + } + } + } + + return image; + } + + private static int translateColor(ImageData imageData, int color) { + + int bitCount = imageData.depth; + RGB[] rgb = imageData.getRGBs(); + + if (bitCount == 1 || bitCount == 4 || bitCount == 8) { + // Look up actual rgb value in the rgb array. + if (rgb != null) { + java.awt.Color foo = new java.awt.Color(rgb[color].red, + rgb[color].green, rgb[color].blue); + color = foo.getRGB(); + } else { + color = 0; + } + } else if (bitCount == 16) { + int BLUE_MASK = 0x1f; + int GREEN_MASK = 0x3e0; + int RED_MASK = 0x7C00; + + // Each word in the bitmap array represents a single pixels, 5 bits for each + // red, green and blue. + color = applyRGBMask(color, RED_MASK, GREEN_MASK, BLUE_MASK); + } else if (bitCount == 24) { + // 3 8 bit color values. + int blue = (color & 0x00ff0000) >> 16; + int green = (color & 0x0000ff00) >> 8; + int red = (color & 0x000000ff); + + java.awt.Color foo = new java.awt.Color(red, green, blue); + color = foo.getRGB(); + } else if (bitCount == 32) { + int blue = (color & 0xff000000) >>> 24; + int green = (color & 0x00ff0000) >> 16; + int red = (color & 0x0000ff00) >> 8; + + java.awt.Color foo = new java.awt.Color(red, green, blue); + color = foo.getRGB(); + } + + return color; + } + + private static int applyRGBMask(int color, int redMask, int greenMask, + int blueMask) { + int shiftCount; + int maskSize; + int red; + int green; + int blue; + + shiftCount = getShiftCount(redMask); + maskSize = countBits(redMask); + red = (color & redMask) >>> shiftCount; + // Scale the color value to something between 0 and 255. + red = red * 255 / ((int) Math.pow(2, maskSize) - 1); + + shiftCount = getShiftCount(greenMask); + maskSize = countBits(greenMask); + green = (color & greenMask) >>> shiftCount; + // Scale the color value to something between 0 and 255. + green = green * 255 / ((int) Math.pow(2, maskSize) - 1); + + shiftCount = getShiftCount(blueMask); + maskSize = countBits(blueMask); + blue = (color & blueMask) >>> shiftCount; + // Scale the color value to something between 0 and 255. + blue = blue * 255 / ((int) Math.pow(2, maskSize) - 1); + + java.awt.Color foo = new java.awt.Color(red, green, blue); + color = foo.getRGB(); + + return color; + } + + private static int getShiftCount(int mask) { + int count = 0; + + while (mask != 0 && ((mask & 0x1) == 0)) { + mask = mask >>> 1; + count++; + } + + return count; + } + + private static int countBits(int mask) { + int count = 0; + for (int index = 0; index < 32; index++) { + if ((mask & 0x1) != 0) { + count++; + } + mask = mask >>> 1; + } + + return count; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/MaxPixelsExportAreaProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/MaxPixelsExportAreaProvider.java index 4c338ffd6..d516b4e74 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/MaxPixelsExportAreaProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/internal/image/MaxPixelsExportAreaProvider.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2010 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.internal.image; - -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.image.ExportAreaProvider; - -/** - * @author Frank Shaka - * - */ -public class MaxPixelsExportAreaProvider extends ExportAreaProvider { - - /** - * @param sourceArea - * @param constrainedWidth - * @param constrainedHeight - * @param margins - */ - public MaxPixelsExportAreaProvider(Rectangle sourceArea, - int constrainedWidth, int constrainedHeight, Insets margins) { - super(sourceArea, constrainedWidth, constrainedHeight, margins); - } - - protected void adjustExportArea() { - exportArea.expand(margins); - int wHint = constrainedWidth > 0 ? constrainedWidth : exportArea.width; - int hHint = constrainedHeight > 0 ? constrainedHeight - : exportArea.height; - int maxPixels = wHint * hHint; - int oldPixels = exportArea.width * exportArea.height; - if (oldPixels > 0 && oldPixels > maxPixels) { - scale = Math.sqrt(maxPixels * 1.0d / oldPixels); - exportArea.scale(scale); - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2010 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.internal.image; + +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.image.ExportAreaProvider; + +/** + * @author Frank Shaka + * + */ +public class MaxPixelsExportAreaProvider extends ExportAreaProvider { + + /** + * @param sourceArea + * @param constrainedWidth + * @param constrainedHeight + * @param margins + */ + public MaxPixelsExportAreaProvider(Rectangle sourceArea, + int constrainedWidth, int constrainedHeight, Insets margins) { + super(sourceArea, constrainedWidth, constrainedHeight, margins); + } + + protected void adjustExportArea() { + exportArea.expand(margins); + int wHint = constrainedWidth > 0 ? constrainedWidth : exportArea.width; + int hHint = constrainedHeight > 0 ? constrainedHeight + : exportArea.height; + int maxPixels = wHint * hHint; + int oldPixels = exportArea.width * exportArea.height; + if (oldPixels > 0 && oldPixels > maxPixels) { + scale = Math.sqrt(maxPixels * 1.0d / oldPixels); + exportArea.scale(scale); + } + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalEditPart.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalEditPart.java index fb0e31567..34d1c8978 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalEditPart.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalEditPart.java @@ -1,237 +1,237 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.part; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.IDecorator; -import org.xmind.gef.IViewer; -import org.xmind.gef.IViewer.IPartSearchCondition; -import org.xmind.gef.NullDecorator; -import org.xmind.gef.draw2d.IUseTransparency; - -/** - * @author Brian Sun - */ -public abstract class GraphicalEditPart extends EditPart - implements IGraphicalEditPart { - - private IFigure figure = null; - - private boolean figureInitiated = false; - - private IDecorator decorator = null; - - public IFigure getFigure() { - if (figure == null) { - figure = createFigure(); - } - return figure; - } - - protected boolean hasFigure() { - return figure != null; - } - - public IFigure getContentPane() { - return getFigure(); - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.part.EditPart#onActivated() - */ - @Override - protected void onActivated() { - super.onActivated(); - if (!figureInitiated) { - initFigure(getFigure()); - figureInitiated = true; - } - } - - protected void initFigure(IFigure figure) { - LayoutManager layout = createLayoutManager(); - if (layout != null) - getContentPane().setLayoutManager(layout); - getDecorator().activate(this, figure); - } - - protected LayoutManager createLayoutManager() { - return null; - } - - protected abstract IFigure createFigure(); - - protected void addChildView(IPart child, int index) { - getContentPane().add(((IGraphicalPart) child).getFigure(), index); - } - - protected void removeChildView(IPart child) { - getContentPane().remove(((IGraphicalPart) child).getFigure()); - } - - public IDecorator getDecorator() { - if (decorator == null) - return NullDecorator.getInstance(); - return decorator; - } - - public void setDecorator(IDecorator decorator) { - this.decorator = decorator; - } - - @Override - protected void onDeactivated() { - super.onDeactivated(); - if (figure != null && figureInitiated) { - getDecorator().deactivate(this, figure); - figureInitiated = false; - } - } - - protected void updateView() { - super.updateView(); - if (getFigure() != null) { - if (!figureInitiated) { - initFigure(getFigure()); - figureInitiated = true; - } - getDecorator().decorate(this, getFigure()); - } - } - - protected void updateChildren() { - super.updateChildren(); - if (getFigure() != null) { - if (!figureInitiated) { - initFigure(getFigure()); - figureInitiated = true; - } - getDecorator().decorateChildren(this, getFigure()); - } - } - - /** - * @see org.xmind.gef.part.Part#getAdapter(java.lang.Class) - */ - public T getAdapter(Class adapter) { - if (adapter == IFigure.class) - return adapter.cast(getFigure()); - if (adapter == IUseTransparency.class) { - IFigure f = getFigure(); - if (f instanceof IUseTransparency) { - return adapter.cast(f); - } - } - if (adapter == IDecorator.class) - return adapter.cast(getDecorator()); - return super.getAdapter(adapter); - } - - /** - * @see org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) - */ - public IPart findAt(Point position) { - return findAt(position, null); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry - * .Point, org.xmind.gef.IViewer.IPartSearchCondition) - */ - public IPart findAt(Point position, IPartSearchCondition condition) { - IPart ret; - ret = findChildAt(position); - if (ret != null) - return ret; - if (containsPoint(position) - && (condition == null || condition.evaluate(this))) { - return this; - } - return null; - } - - protected IPart findChildAt(Point position) { - List children = getChildren(); - for (int i = children.size() - 1; i >= 0; i--) { - IPart child = children.get(i); - IPart ret = findChildAt(child, position); - if (ret != null) - return ret; - } - return null; - } - - protected IPart findChildAt(IPart child, Point position) { - if (child instanceof IGraphicalEditPart) { - return ((IGraphicalEditPart) child).findAt(position); - } - return null; - } - - /** - * @see org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) - */ - public IFigure findTooltipAt(Point position) { - if (containsPoint(position)) - return getFigure().getToolTip(); - return null; - } - - public boolean containsPoint(Point position) { - return getFigure().isShowing() && getFigure().containsPoint(position); - } - - /** - * @see org.xmind.gef.part.IGraphicalEditPart#getCursor(org.eclipse.draw2d.geometry.Point) - */ - public Cursor getCursor(Point pos) { - return null; - } - - public void updateToolTip() { - IFigure fig = getFigure(); - if (fig != null) { - fig.setToolTip(createToolTip()); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (!getStatus().isActive()) - return; - - IViewer viewer = getSite().getViewer(); - if (viewer == null || viewer.getControl().isDisposed()) - return; - - viewer.updateToolTip(); - } - }); - } - } - - protected IFigure createToolTip() { - return null; - } - - public String getActionId() { - return null; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.IDecorator; +import org.xmind.gef.IViewer; +import org.xmind.gef.IViewer.IPartSearchCondition; +import org.xmind.gef.NullDecorator; +import org.xmind.gef.draw2d.IUseTransparency; + +/** + * @author Brian Sun + */ +public abstract class GraphicalEditPart extends EditPart + implements IGraphicalEditPart { + + private IFigure figure = null; + + private boolean figureInitiated = false; + + private IDecorator decorator = null; + + public IFigure getFigure() { + if (figure == null) { + figure = createFigure(); + } + return figure; + } + + protected boolean hasFigure() { + return figure != null; + } + + public IFigure getContentPane() { + return getFigure(); + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.part.EditPart#onActivated() + */ + @Override + protected void onActivated() { + super.onActivated(); + if (!figureInitiated) { + initFigure(getFigure()); + figureInitiated = true; + } + } + + protected void initFigure(IFigure figure) { + LayoutManager layout = createLayoutManager(); + if (layout != null) + getContentPane().setLayoutManager(layout); + getDecorator().activate(this, figure); + } + + protected LayoutManager createLayoutManager() { + return null; + } + + protected abstract IFigure createFigure(); + + protected void addChildView(IPart child, int index) { + getContentPane().add(((IGraphicalPart) child).getFigure(), index); + } + + protected void removeChildView(IPart child) { + getContentPane().remove(((IGraphicalPart) child).getFigure()); + } + + public IDecorator getDecorator() { + if (decorator == null) + return NullDecorator.getInstance(); + return decorator; + } + + public void setDecorator(IDecorator decorator) { + this.decorator = decorator; + } + + @Override + protected void onDeactivated() { + super.onDeactivated(); + if (figure != null && figureInitiated) { + getDecorator().deactivate(this, figure); + figureInitiated = false; + } + } + + protected void updateView() { + super.updateView(); + if (getFigure() != null) { + if (!figureInitiated) { + initFigure(getFigure()); + figureInitiated = true; + } + getDecorator().decorate(this, getFigure()); + } + } + + protected void updateChildren() { + super.updateChildren(); + if (getFigure() != null) { + if (!figureInitiated) { + initFigure(getFigure()); + figureInitiated = true; + } + getDecorator().decorateChildren(this, getFigure()); + } + } + + /** + * @see org.xmind.gef.part.Part#getAdapter(java.lang.Class) + */ + public T getAdapter(Class adapter) { + if (adapter == IFigure.class) + return adapter.cast(getFigure()); + if (adapter == IUseTransparency.class) { + IFigure f = getFigure(); + if (f instanceof IUseTransparency) { + return adapter.cast(f); + } + } + if (adapter == IDecorator.class) + return adapter.cast(getDecorator()); + return super.getAdapter(adapter); + } + + /** + * @see org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) + */ + public IPart findAt(Point position) { + return findAt(position, null); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry + * .Point, org.xmind.gef.IViewer.IPartSearchCondition) + */ + public IPart findAt(Point position, IPartSearchCondition condition) { + IPart ret; + ret = findChildAt(position); + if (ret != null) + return ret; + if (containsPoint(position) + && (condition == null || condition.evaluate(this))) { + return this; + } + return null; + } + + protected IPart findChildAt(Point position) { + List children = getChildren(); + for (int i = children.size() - 1; i >= 0; i--) { + IPart child = children.get(i); + IPart ret = findChildAt(child, position); + if (ret != null) + return ret; + } + return null; + } + + protected IPart findChildAt(IPart child, Point position) { + if (child instanceof IGraphicalEditPart) { + return ((IGraphicalEditPart) child).findAt(position); + } + return null; + } + + /** + * @see org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) + */ + public IFigure findTooltipAt(Point position) { + if (containsPoint(position)) + return getFigure().getToolTip(); + return null; + } + + public boolean containsPoint(Point position) { + return getFigure().isShowing() && getFigure().containsPoint(position); + } + + /** + * @see org.xmind.gef.part.IGraphicalEditPart#getCursor(org.eclipse.draw2d.geometry.Point) + */ + public Cursor getCursor(Point pos) { + return null; + } + + public void updateToolTip() { + IFigure fig = getFigure(); + if (fig != null) { + fig.setToolTip(createToolTip()); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (!getStatus().isActive()) + return; + + IViewer viewer = getSite().getViewer(); + if (viewer == null || viewer.getControl().isDisposed()) + return; + + viewer.updateToolTip(); + } + }); + } + } + + protected IFigure createToolTip() { + return null; + } + + public String getActionId() { + return null; + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartFactory.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartFactory.java index b701ac28f..ea42c737c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartFactory.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartFactory.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.part; - -/** - * @author Brian Sun - */ -public interface IPartFactory { - - public IPart createPart(IPart context, Object model); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +/** + * @author Brian Sun + */ +public interface IPartFactory { + + public IPart createPart(IPart context, Object model); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartListener2.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartListener2.java new file mode 100644 index 000000000..6965a269e --- /dev/null +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/IPartListener2.java @@ -0,0 +1,36 @@ +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +public interface IPartListener2 extends IPartListener { + + public void childAdding(PartEvent event); + + public void childRemoved(PartEvent event); + + public class Stub implements IPartListener2 { + + public void childAdded(PartEvent event) { + } + + public void childRemoving(PartEvent event) { + } + + public void childAdding(PartEvent event) { + } + + public void childRemoved(PartEvent event) { + } + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/NullGraphicalPart.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/NullGraphicalPart.java index a5d10da36..a431aadf3 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/NullGraphicalPart.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/NullGraphicalPart.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.part; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.IFigure; - -public class NullGraphicalPart extends GraphicalEditPart { - - protected IFigure createFigure() { - return new Figure(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.IFigure; + +public class NullGraphicalPart extends GraphicalEditPart { + + protected IFigure createFigure() { + return new Figure(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/Part.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/Part.java index f60ea8994..c4f768400 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/Part.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/Part.java @@ -1,401 +1,425 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.part; - -import static org.xmind.gef.GEF.PART_ACTIVE; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.jface.viewers.ViewerFilter; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.status.IStatusListener; -import org.xmind.gef.status.StatusEvent; - -/** - * @author Administrator - */ -public class Part implements IPart { - - private static final List EMPTY_CHILDREN = Collections.emptyList(); - - private Object model = null; - - private IPart parent = null; - - private List children = null; - - private IPartSite site = null; - - private IPartStatus status = null; - - private List partListeners = null; - - public Part() { - } - - /** - * @see org.xmind.gef.part.IPart#getModel() - */ - public Object getModel() { - return model; - } - - public IPart getParent() { - return parent; - } - - /** - * @param model - * the model to set - */ - public void setModel(Object model) { - if (model == this.model) - return; - this.model = model; - } - - public void setParent(IPart parent) { - if (parent == this) - throw new IllegalArgumentException( - "A part should NOT be set as its own parent."); //$NON-NLS-1$ - this.parent = parent; - } - - public List getChildren() { - if (children == null) - return EMPTY_CHILDREN; - return children; - } - - public void addNotify() { - register(); - for (Object o : getChildren().toArray()) { - ((IPart) o).addNotify(); - } - refresh(); - } - - public void removeNotify() { - getStatus().dePreSelect(); - getStatus().deSelect(); - getStatus().lostFocus(); - for (Object o : getChildren().toArray()) { - ((IPart) o).removeNotify(); - } - unregister(); - } - - protected void addChild(IPart child, int index) { - if (child == null) - return; - - if (child == this) - throw new IllegalArgumentException( - "A part should NOT be added as its own child."); //$NON-NLS-1$ - - if (index == -1) - index = getChildren().size(); - if (children == null) { - children = new ArrayList(); - } - - children.add(index, child); - child.setParent(this); - addChildView(child, index); - child.addNotify(); - - if (getStatus().isActive()) - child.getStatus().activate(); - fireChildAdded(child, index); - } - - protected void removeChild(IPart child) { - if (child == null || child == this) - return; - - int index = getChildren().indexOf(child); - if (index < 0) - return; - - fireRemovingChild(child, index); - if (getStatus().isActive()) - child.getStatus().deactivate(); - - child.removeNotify(); - removeChildView(child); - child.setParent(null); - if (children != null && !children.isEmpty()) - children.remove(child); - } - - protected void addChildView(IPart child, int index) { - } - - protected void removeChildView(IPart child) { - } - - protected void register() { - } - - protected void unregister() { - } - - protected void unregisterModel(Object model) { - PartRegistry partRegistry = getPartRegistry(); - if (partRegistry != null) { - partRegistry.unregister(model, this); - } - } - - protected void registerModel(Object model) { - PartRegistry partRegistry = getPartRegistry(); - if (partRegistry != null) { - partRegistry.register(model, this); - } - } - - protected PartRegistry getPartRegistry() { - return getSite().getPartRegistry(); - } - - public void refresh() { - updateView(); - refreshChildren(); - updateChildren(); - } - - public void update() { - updateView(); - updateChildren(); - } - - protected void updateView() { - } - - protected void updateChildren() { - } - - protected void refreshChildren() { - Map modelToPart = new HashMap(); - List currentChildren = getChildren(); - for (IPart p : currentChildren) { - modelToPart.put(p.getModel(), p); - } - - Object[] newModels = getModelChildren(getModel()); - if (newModels.length > 0) { - IViewer viewer = getSite().getViewer(); - if (viewer != null) { - newModels = getFilteredModelChildren(viewer, getModel(), - newModels); - newModels = getSortedModelChildren(viewer, getModel(), - newModels); - } - } - - int i; - IPartFactory factory = getSite().getPartFactory(); - for (i = 0; i < newModels.length; i++) { - Object model = newModels[i]; - if (i < currentChildren.size()) { - Object m = currentChildren.get(i).getModel(); - if (model == m || model.equals(m)) - continue; - } - - IPart p = modelToPart.get(model); - if (p != null) { - reorderChild(p, i); - } else { - p = createChild(model, factory); - addChild(p, i); - } - } - - Object[] toTrim = currentChildren.toArray(); - for (; i < toTrim.length; i++) { - removeChild((IPart) toTrim[i]); - } - } - - protected void reorderChild(IPart child, int index) { - if (children == null) - return; - - removeChildView(child); - children.remove(child); - children.add(index, child); - addChildView(child, index); - } - - protected IPart createChild(Object modelChild, IPartFactory factory) { - return factory.createPart(this, modelChild); - } - - protected Object[] getSortedModelChildren(IViewer viewer, Object model, - Object[] modelChildren) { - ViewerComparator sorter = viewer.getComparator(); - if (sorter != null) { - sorter.sort((Viewer) viewer, modelChildren); - } - return modelChildren; - } - - protected Object[] getFilteredModelChildren(IViewer viewer, Object model, - Object[] modelChildren) { - ViewerFilter[] filters = viewer.getFilters(); - if (filters != null && filters.length > 0) { - for (ViewerFilter f : filters) { - modelChildren = f.filter((Viewer) viewer, model, modelChildren); - } - } - return modelChildren; - } - - protected Object[] getModelChildren(Object model) { - return new Object[0]; - } - - /** - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public T getAdapter(Class adapter) { - if (adapter == IPartSite.class) - return adapter.cast(getSite()); - if (adapter == IPartStatus.class) - return adapter.cast(getStatus()); - if (getModel() instanceof IAdaptable) - return ((IAdaptable) getModel()).getAdapter(adapter); - return null; - } - - public void addPartListener(IPartListener listener) { - if (partListeners == null) { - partListeners = new ArrayList(); - } - partListeners.add(listener); - } - - public void removePartListener(IPartListener listener) { - if (partListeners != null) { - partListeners.remove(listener); - } - } - - protected void fireChildAdded(IPart child, int index) { - if (partListeners != null) { - PartEvent event = new PartEvent(this, child); - for (Object listener : partListeners.toArray()) { - ((IPartListener) listener).childAdded(event); - } - } - } - - protected void fireRemovingChild(IPart child, int index) { - if (partListeners != null) { - PartEvent event = new PartEvent(this, child); - for (Object listener : partListeners.toArray()) { - ((IPartListener) listener).childRemoving(event); - } - } - } - - public IPartSite getSite() { - if (site == null) { - site = createSite(); - } - return site; - } - - protected IPartSite createSite() { - return new PartSite(this); - } - - /** - * @param site - * the site to set - */ - protected void setSite(IPartSite site) { - this.site = site; - } - - /** - * @see org.xmind.gef.part.IPart#getStatus() - */ - public IPartStatus getStatus() { - if (status == null) { - status = new PartStatus(this); - status.addStatusListener(new IStatusListener() { - public void statusChanged(StatusEvent event) { - if (event.key == PART_ACTIVE) { - if (event.newValue) { - onActivated(); - } else { - onDeactivated(); - } - } else { - handleStatusChanged(event); - } - } - }); - } - return status; - } - - protected void handleStatusChanged(StatusEvent event) { - } - - protected void onActivated() { - for (Object o : getChildren().toArray()) { - ((IPart) o).getStatus().activate(); - } - } - - protected void onDeactivated() { - for (Object p : getChildren().toArray()) { - ((IPart) p).getStatus().deactivate(); - } - } - - @Override - public String toString() { - return getClass().getSimpleName() + "{" + getModel() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Default implementation of the abstract method indicating that this part - * doesn't have any role. Subclasses may override to determine whether or - * not this part has the specific role. - */ - public boolean hasRole(String role) { - return false; - } - - /** - * Default implementation of the abstract method to do nothing. Subclasses - * may override to provide this part with abilities to handle requests. - */ - public void handleRequest(Request request, String role) { - // do nothing - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +import static org.xmind.gef.GEF.PART_ACTIVE; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.viewers.ViewerFilter; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.status.IStatusListener; +import org.xmind.gef.status.StatusEvent; + +/** + * @author Administrator + */ +public class Part implements IPart { + + private static final List EMPTY_CHILDREN = Collections.emptyList(); + + private Object model = null; + + private IPart parent = null; + + private List children = null; + + private IPartSite site = null; + + private IPartStatus status = null; + + private List partListeners = null; + + public Part() { + } + + /** + * @see org.xmind.gef.part.IPart#getModel() + */ + public Object getModel() { + return model; + } + + public IPart getParent() { + return parent; + } + + /** + * @param model + * the model to set + */ + public void setModel(Object model) { + if (model == this.model) + return; + this.model = model; + } + + public void setParent(IPart parent) { + if (parent == this) + throw new IllegalArgumentException( + "A part should NOT be set as its own parent."); //$NON-NLS-1$ + this.parent = parent; + } + + public List getChildren() { + if (children == null) + return EMPTY_CHILDREN; + return children; + } + + public void addNotify() { + register(); + for (Object o : getChildren().toArray()) { + ((IPart) o).addNotify(); + } + refresh(); + } + + public void removeNotify() { + getStatus().dePreSelect(); + getStatus().deSelect(); + getStatus().lostFocus(); + for (Object o : getChildren().toArray()) { + ((IPart) o).removeNotify(); + } + unregister(); + } + + protected void addChild(IPart child, int index) { + if (child == null) + return; + + if (child == this) + throw new IllegalArgumentException( + "A part should NOT be added as its own child."); //$NON-NLS-1$ + + fireAddingChild(child, index); + if (index == -1) + index = getChildren().size(); + if (children == null) { + children = new ArrayList(); + } + + children.add(index, child); + child.setParent(this); + addChildView(child, index); + child.addNotify(); + + if (getStatus().isActive()) + child.getStatus().activate(); + fireChildAdded(child, index); + } + + protected void removeChild(IPart child) { + if (child == null || child == this) + return; + + int index = getChildren().indexOf(child); + if (index < 0) + return; + + fireRemovingChild(child, index); + if (getStatus().isActive()) + child.getStatus().deactivate(); + + child.removeNotify(); + removeChildView(child); + child.setParent(null); + if (children != null && !children.isEmpty()) + children.remove(child); + fireChildRemoved(child, index); + } + + protected void addChildView(IPart child, int index) { + } + + protected void removeChildView(IPart child) { + } + + protected void register() { + } + + protected void unregister() { + } + + protected void unregisterModel(Object model) { + PartRegistry partRegistry = getPartRegistry(); + if (partRegistry != null) { + partRegistry.unregister(model, this); + } + } + + protected void registerModel(Object model) { + PartRegistry partRegistry = getPartRegistry(); + if (partRegistry != null) { + partRegistry.register(model, this); + } + } + + protected PartRegistry getPartRegistry() { + return getSite().getPartRegistry(); + } + + public void refresh() { + updateView(); + refreshChildren(); + updateChildren(); + } + + public void update() { + updateView(); + updateChildren(); + } + + protected void updateView() { + } + + protected void updateChildren() { + } + + protected void refreshChildren() { + Map modelToPart = new HashMap(); + List currentChildren = getChildren(); + for (IPart p : currentChildren) { + modelToPart.put(p.getModel(), p); + } + + Object[] newModels = getModelChildren(getModel()); + if (newModels.length > 0) { + IViewer viewer = getSite().getViewer(); + if (viewer != null) { + newModels = getFilteredModelChildren(viewer, getModel(), + newModels); + newModels = getSortedModelChildren(viewer, getModel(), + newModels); + } + } + + int i; + IPartFactory factory = getSite().getPartFactory(); + for (i = 0; i < newModels.length; i++) { + Object model = newModels[i]; + if (i < currentChildren.size()) { + Object m = currentChildren.get(i).getModel(); + if (model == m || model.equals(m)) + continue; + } + + IPart p = modelToPart.get(model); + if (p != null) { + reorderChild(p, i); + } else { + p = createChild(model, factory); + addChild(p, i); + } + } + + Object[] toTrim = currentChildren.toArray(); + for (; i < toTrim.length; i++) { + removeChild((IPart) toTrim[i]); + } + } + + protected void reorderChild(IPart child, int index) { + if (children == null) + return; + + removeChildView(child); + children.remove(child); + children.add(index, child); + addChildView(child, index); + } + + protected IPart createChild(Object modelChild, IPartFactory factory) { + return factory.createPart(this, modelChild); + } + + protected Object[] getSortedModelChildren(IViewer viewer, Object model, + Object[] modelChildren) { + ViewerComparator sorter = viewer.getComparator(); + if (sorter != null) { + sorter.sort((Viewer) viewer, modelChildren); + } + return modelChildren; + } + + protected Object[] getFilteredModelChildren(IViewer viewer, Object model, + Object[] modelChildren) { + ViewerFilter[] filters = viewer.getFilters(); + if (filters != null && filters.length > 0) { + for (ViewerFilter f : filters) { + modelChildren = f.filter((Viewer) viewer, model, modelChildren); + } + } + return modelChildren; + } + + protected Object[] getModelChildren(Object model) { + return new Object[0]; + } + + /** + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public T getAdapter(Class adapter) { + if (adapter == IPartSite.class) + return adapter.cast(getSite()); + if (adapter == IPartStatus.class) + return adapter.cast(getStatus()); + if (getModel() instanceof IAdaptable) + return ((IAdaptable) getModel()).getAdapter(adapter); + return null; + } + + public void addPartListener(IPartListener listener) { + if (partListeners == null) { + partListeners = new ArrayList(); + } + partListeners.add(listener); + } + + public void removePartListener(IPartListener listener) { + if (partListeners != null) { + partListeners.remove(listener); + } + } + + protected void fireChildAdded(IPart child, int index) { + if (partListeners != null) { + PartEvent event = new PartEvent(this, child); + for (Object listener : partListeners.toArray()) { + ((IPartListener) listener).childAdded(event); + } + } + } + + protected void fireRemovingChild(IPart child, int index) { + if (partListeners != null) { + PartEvent event = new PartEvent(this, child); + for (Object listener : partListeners.toArray()) { + ((IPartListener) listener).childRemoving(event); + } + } + } + + protected void fireAddingChild(IPart child, int index) { + if (partListeners != null) { + PartEvent event = new PartEvent(this, child); + for (Object listener : partListeners.toArray()) { + if (listener instanceof IPartListener2) { + ((IPartListener2) listener).childAdding(event); + } + } + } + } + + protected void fireChildRemoved(IPart child, int index) { + if (partListeners != null) { + PartEvent event = new PartEvent(this, child); + for (Object listener : partListeners.toArray()) { + if (listener instanceof IPartListener2) { + ((IPartListener2) listener).childRemoved(event); + } + } + } + } + + public IPartSite getSite() { + if (site == null) { + site = createSite(); + } + return site; + } + + protected IPartSite createSite() { + return new PartSite(this); + } + + /** + * @param site + * the site to set + */ + protected void setSite(IPartSite site) { + this.site = site; + } + + /** + * @see org.xmind.gef.part.IPart#getStatus() + */ + public IPartStatus getStatus() { + if (status == null) { + status = new PartStatus(this); + status.addStatusListener(new IStatusListener() { + public void statusChanged(StatusEvent event) { + if (event.key == PART_ACTIVE) { + if (event.newValue) { + onActivated(); + } else { + onDeactivated(); + } + } else { + handleStatusChanged(event); + } + } + }); + } + return status; + } + + protected void handleStatusChanged(StatusEvent event) { + } + + protected void onActivated() { + for (Object o : getChildren().toArray()) { + ((IPart) o).getStatus().activate(); + } + } + + protected void onDeactivated() { + for (Object p : getChildren().toArray()) { + ((IPart) p).getStatus().deactivate(); + } + } + + @Override + public String toString() { + return getClass().getSimpleName() + "{" + getModel() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Default implementation of the abstract method indicating that this part + * doesn't have any role. Subclasses may override to determine whether or + * not this part has the specific role. + */ + public boolean hasRole(String role) { + return false; + } + + /** + * Default implementation of the abstract method to do nothing. Subclasses + * may override to provide this part with abilities to handle requests. + */ + public void handleRequest(Request request, String role) { + // do nothing + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/PartRoles.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/PartRoles.java index 72f2ccca6..2c94a6685 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/PartRoles.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/PartRoles.java @@ -1,108 +1,108 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.part; - -import java.util.HashMap; -import java.util.Map; - -import org.xmind.gef.GEF; - -/** - * @author Brian Sun - */ -public class PartRoles { - - private Map reqToRole = new HashMap(); - - public PartRoles() { - setRole(GEF.REQ_SELECT, GEF.ROLE_SELECTABLE); - setRole(GEF.REQ_SELECT_ALL, GEF.ROLE_SELECTABLE); - setRole(GEF.REQ_SELECT_MULTI, GEF.ROLE_SELECTABLE); - setRole(GEF.REQ_SELECT_NONE, GEF.ROLE_SELECTABLE); - setRole(GEF.REQ_SELECT_SINGLE, GEF.ROLE_SELECTABLE); - - setRole(GEF.REQ_CREATE, GEF.ROLE_CREATABLE); - setRole(GEF.REQ_DELETE, GEF.ROLE_DELETABLE); - - setRole(GEF.REQ_EXTEND, GEF.ROLE_EXTENDABLE); - setRole(GEF.REQ_COLLAPSE, GEF.ROLE_EXTENDABLE); - setRole(GEF.REQ_EXTEND_ALL, GEF.ROLE_EXTENDABLE); - setRole(GEF.REQ_COLLAPSE_ALL, GEF.ROLE_EXTENDABLE); - - setRole(GEF.REQ_MOVETO, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_COPYTO, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_RESIZE, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_ALIGN, GEF.ROLE_MOVABLE); - - setRole(GEF.REQ_SORT, GEF.ROLE_SORTABLE); - - setRole(GEF.REQ_MOVE_NEXT, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_MOVE_PREV, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_MOVE_UP, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_MOVE_DOWN, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_MOVE_LEFT, GEF.ROLE_MOVABLE); - setRole(GEF.REQ_MOVE_RIGHT, GEF.ROLE_MOVABLE); - - setRole(GEF.REQ_MODIFY, GEF.ROLE_MODIFIABLE); - - setRole(GEF.REQ_ZOOM, GEF.ROLE_SCALABLE); - setRole(GEF.REQ_ZOOMIN, GEF.ROLE_SCALABLE); - setRole(GEF.REQ_ZOOMOUT, GEF.ROLE_SCALABLE); - setRole(GEF.REQ_ACTUALSIZE, GEF.ROLE_SCALABLE); - setRole(GEF.REQ_FITSIZE, GEF.ROLE_SCALABLE); - setRole(GEF.REQ_FITSELECTION, GEF.ROLE_SCALABLE); - - setRole(GEF.REQ_SHOW_ALL, GEF.ROLE_FILTERABLE); - setRole(GEF.REQ_SHOW_OTHER, GEF.ROLE_FILTERABLE); - setRole(GEF.REQ_HIDE_ALL, GEF.ROLE_FILTERABLE); - setRole(GEF.REQ_SHOW, GEF.ROLE_FILTERABLE); - setRole(GEF.REQ_HIDE, GEF.ROLE_FILTERABLE); - setRole(GEF.REQ_SHOW_ONLY, GEF.ROLE_FILTERABLE); - - setRole(GEF.REQ_COPY, GEF.ROLE_EDITABLE); - setRole(GEF.REQ_CUT, GEF.ROLE_EDITABLE); - setRole(GEF.REQ_PASTE, GEF.ROLE_EDITABLE); - - setRole(GEF.REQ_NAV_UP, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_LEFT, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_END, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_RIGHT, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_BEGINNING, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_DOWN, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_NEXT, GEF.ROLE_NAVIGABLE); - setRole(GEF.REQ_NAV_PREV, GEF.ROLE_NAVIGABLE); - - setRole(GEF.REQ_TRAVERSE, GEF.ROLE_TRAVERSABLE); - setRole(GEF.REQ_GET_TRAVERSABLES, GEF.ROLE_TRAVERSABLE); - - setRole(GEF.REQ_DROP, GEF.ROLE_DROP_TARGET); - } - - public boolean hasRole(String role) { - return reqToRole.containsValue(role); - } - - public boolean hasRequest(String requestType) { - return reqToRole.containsKey(requestType); - } - - public String getRole(String requestType) { - return reqToRole.get(requestType); - } - - public void setRole(String requestType, String role) { - reqToRole.put(requestType, role); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.part; + +import java.util.HashMap; +import java.util.Map; + +import org.xmind.gef.GEF; + +/** + * @author Brian Sun + */ +public class PartRoles { + + private Map reqToRole = new HashMap(); + + public PartRoles() { + setRole(GEF.REQ_SELECT, GEF.ROLE_SELECTABLE); + setRole(GEF.REQ_SELECT_ALL, GEF.ROLE_SELECTABLE); + setRole(GEF.REQ_SELECT_MULTI, GEF.ROLE_SELECTABLE); + setRole(GEF.REQ_SELECT_NONE, GEF.ROLE_SELECTABLE); + setRole(GEF.REQ_SELECT_SINGLE, GEF.ROLE_SELECTABLE); + + setRole(GEF.REQ_CREATE, GEF.ROLE_CREATABLE); + setRole(GEF.REQ_DELETE, GEF.ROLE_DELETABLE); + + setRole(GEF.REQ_EXTEND, GEF.ROLE_EXTENDABLE); + setRole(GEF.REQ_COLLAPSE, GEF.ROLE_EXTENDABLE); + setRole(GEF.REQ_EXTEND_ALL, GEF.ROLE_EXTENDABLE); + setRole(GEF.REQ_COLLAPSE_ALL, GEF.ROLE_EXTENDABLE); + + setRole(GEF.REQ_MOVETO, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_COPYTO, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_RESIZE, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_ALIGN, GEF.ROLE_MOVABLE); + + setRole(GEF.REQ_SORT, GEF.ROLE_SORTABLE); + + setRole(GEF.REQ_MOVE_NEXT, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_MOVE_PREV, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_MOVE_UP, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_MOVE_DOWN, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_MOVE_LEFT, GEF.ROLE_MOVABLE); + setRole(GEF.REQ_MOVE_RIGHT, GEF.ROLE_MOVABLE); + + setRole(GEF.REQ_MODIFY, GEF.ROLE_MODIFIABLE); + + setRole(GEF.REQ_ZOOM, GEF.ROLE_SCALABLE); + setRole(GEF.REQ_ZOOMIN, GEF.ROLE_SCALABLE); + setRole(GEF.REQ_ZOOMOUT, GEF.ROLE_SCALABLE); + setRole(GEF.REQ_ACTUALSIZE, GEF.ROLE_SCALABLE); + setRole(GEF.REQ_FITSIZE, GEF.ROLE_SCALABLE); + setRole(GEF.REQ_FITSELECTION, GEF.ROLE_SCALABLE); + + setRole(GEF.REQ_SHOW_ALL, GEF.ROLE_FILTERABLE); + setRole(GEF.REQ_SHOW_OTHER, GEF.ROLE_FILTERABLE); + setRole(GEF.REQ_HIDE_ALL, GEF.ROLE_FILTERABLE); + setRole(GEF.REQ_SHOW, GEF.ROLE_FILTERABLE); + setRole(GEF.REQ_HIDE, GEF.ROLE_FILTERABLE); + setRole(GEF.REQ_SHOW_ONLY, GEF.ROLE_FILTERABLE); + + setRole(GEF.REQ_COPY, GEF.ROLE_EDITABLE); + setRole(GEF.REQ_CUT, GEF.ROLE_EDITABLE); + setRole(GEF.REQ_PASTE, GEF.ROLE_EDITABLE); + + setRole(GEF.REQ_NAV_UP, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_LEFT, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_END, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_RIGHT, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_BEGINNING, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_DOWN, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_NEXT, GEF.ROLE_NAVIGABLE); + setRole(GEF.REQ_NAV_PREV, GEF.ROLE_NAVIGABLE); + + setRole(GEF.REQ_TRAVERSE, GEF.ROLE_TRAVERSABLE); + setRole(GEF.REQ_GET_TRAVERSABLES, GEF.ROLE_TRAVERSABLE); + + setRole(GEF.REQ_DROP, GEF.ROLE_DROP_TARGET); + } + + public boolean hasRole(String role) { + return reqToRole.containsValue(role); + } + + public boolean hasRequest(String requestType) { + return reqToRole.containsKey(requestType); + } + + public String getRole(String requestType) { + return reqToRole.get(requestType); + } + + public void setRole(String requestType, String role) { + reqToRole.put(requestType, role); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/policy/NavigablePolicy.java b/bundles/org.xmind.gef/src/org/xmind/gef/policy/NavigablePolicy.java index 20fed82e7..ba435bc7d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/policy/NavigablePolicy.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/policy/NavigablePolicy.java @@ -1,98 +1,98 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.policy; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; - -public class NavigablePolicy extends AbstractEditPolicy { - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_NAV_UP.equals(requestType) - || GEF.REQ_NAV_DOWN.equals(requestType) - || GEF.REQ_NAV_LEFT.equals(requestType) - || GEF.REQ_NAV_RIGHT.equals(requestType) - || GEF.REQ_NAV_BEGINNING.equals(requestType) - || GEF.REQ_NAV_END.equals(requestType) - || GEF.REQ_NAV_NEXT.equals(requestType) - || GEF.REQ_NAV_PREV.equals(requestType); - } - - public void handle(Request request) { - String navType = request.getType(); - if (GEF.REQ_NAV_UP.equals(navType) || GEF.REQ_NAV_DOWN.equals(navType) - || GEF.REQ_NAV_LEFT.equals(navType) - || GEF.REQ_NAV_RIGHT.equals(navType) - || GEF.REQ_NAV_BEGINNING.equals(navType) - || GEF.REQ_NAV_END.equals(navType)) { - List sources = request.getTargets(); - List result = new ArrayList(); - IPart seqStart = getSequenceStart(request); - if (seqStart != null) { - findSequentialNavParts(request, navType, seqStart, sources, - result); - } else { - findNavParts(request, navType, sources, result); - } - setNavigationResult(request, result); - } else if (GEF.REQ_NAV_NEXT.equals(navType) - || GEF.REQ_NAV_PREV.equals(navType)) { - IPart source = request.getPrimaryTarget(); - IPart target = findNextOrPrev(source, GEF.REQ_NAV_NEXT - .equals(navType)); - if (target != null) { - setNavigationResult(request, Arrays.asList(target)); - } - } - } - - protected IPart findNextOrPrev(IPart source, boolean nextOrPrev) { - return null; - } - - protected void setNavigationResult(Request request, - List result) { - if (!result.isEmpty()) { - request.setResult(GEF.RESULT_NAVIGATION, result - .toArray(new IPart[result.size()])); - } - } - - protected void findNavParts(Request request, String navType, - List sources, List result) { - result.addAll(sources); - } - - protected void findSequentialNavParts(Request request, String navType, - IPart sequenceStart, List sources, List result) { - result.addAll(sources); - } - - protected IPart getSequenceStart(Request request) { - if (isSequential(request)) { - return (IPart) request.getParameter(GEF.PARAM_NAV_SEQUENCE_START); - } - return null; - } - - protected boolean isSequential(Request request) { - return request.isParameter(GEF.PARAM_NAV_SEQUENTIAL); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.policy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; + +public class NavigablePolicy extends AbstractEditPolicy { + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_NAV_UP.equals(requestType) + || GEF.REQ_NAV_DOWN.equals(requestType) + || GEF.REQ_NAV_LEFT.equals(requestType) + || GEF.REQ_NAV_RIGHT.equals(requestType) + || GEF.REQ_NAV_BEGINNING.equals(requestType) + || GEF.REQ_NAV_END.equals(requestType) + || GEF.REQ_NAV_NEXT.equals(requestType) + || GEF.REQ_NAV_PREV.equals(requestType); + } + + public void handle(Request request) { + String navType = request.getType(); + if (GEF.REQ_NAV_UP.equals(navType) || GEF.REQ_NAV_DOWN.equals(navType) + || GEF.REQ_NAV_LEFT.equals(navType) + || GEF.REQ_NAV_RIGHT.equals(navType) + || GEF.REQ_NAV_BEGINNING.equals(navType) + || GEF.REQ_NAV_END.equals(navType)) { + List sources = request.getTargets(); + List result = new ArrayList(); + IPart seqStart = getSequenceStart(request); + if (seqStart != null) { + findSequentialNavParts(request, navType, seqStart, sources, + result); + } else { + findNavParts(request, navType, sources, result); + } + setNavigationResult(request, result); + } else if (GEF.REQ_NAV_NEXT.equals(navType) + || GEF.REQ_NAV_PREV.equals(navType)) { + IPart source = request.getPrimaryTarget(); + IPart target = findNextOrPrev(source, GEF.REQ_NAV_NEXT + .equals(navType)); + if (target != null) { + setNavigationResult(request, Arrays.asList(target)); + } + } + } + + protected IPart findNextOrPrev(IPart source, boolean nextOrPrev) { + return null; + } + + protected void setNavigationResult(Request request, + List result) { + if (!result.isEmpty()) { + request.setResult(GEF.RESULT_NAVIGATION, result + .toArray(new IPart[result.size()])); + } + } + + protected void findNavParts(Request request, String navType, + List sources, List result) { + result.addAll(sources); + } + + protected void findSequentialNavParts(Request request, String navType, + IPart sequenceStart, List sources, List result) { + result.addAll(sources); + } + + protected IPart getSequenceStart(Request request) { + if (isSequential(request)) { + return (IPart) request.getParameter(GEF.PARAM_NAV_SEQUENCE_START); + } + return null; + } + + protected boolean isSequential(Request request) { + return request.isParameter(GEF.PARAM_NAV_SEQUENTIAL); + } } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/policy/ScalableEditPolicy.java b/bundles/org.xmind.gef/src/org/xmind/gef/policy/ScalableEditPolicy.java index c62a09fbb..bf740670b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/policy/ScalableEditPolicy.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/policy/ScalableEditPolicy.java @@ -56,7 +56,7 @@ public void handle(Request req) { } else if (GEF.REQ_ZOOMOUT.equals(type)) { performZoomOut(getGraphicalViewer(req)); } else if (GEF.REQ_ACTUALSIZE.equals(type)) { - performActualSize(getGraphicalViewer(req)); + performActualSize(req); } else if (GEF.REQ_FITSIZE.equals(type)) { performFitSize(getGraphicalViewer(req)); } else if (GEF.REQ_FITSELECTION.equals(type)) { @@ -76,17 +76,17 @@ protected void preserveCenter(final Runnable action, IGraphicalViewer viewer) { PrecisionPoint center = viewer == null ? null : new PrecisionPoint(viewer.getCenterPoint()); - if (center != null && viewer != null) { - center.scale(1 / viewer.getZoomManager().getScale()); - } + double oldScale = viewer.getZoomManager().getScale(); try { action.run(); } finally { if (viewer != null && center != null) { if (viewer.getZoomManager() != null) - center.scale(viewer.getZoomManager().getScale()); - viewer.center(center.toDraw2DPoint()); + center.scale( + 2 * viewer.getZoomManager().getScale() / oldScale); + if (viewer.getZoomManager().getScale() != oldScale) + viewer.center(center.toDraw2DPoint()); } } } @@ -123,12 +123,31 @@ public void run() { /** * */ - protected void performActualSize(final IGraphicalViewer viewer) { + protected void performActualSize(Request req) { + final IGraphicalViewer viewer = getGraphicalViewer(req); if (viewer == null) return; - viewer.getZoomManager().actualSize(); - viewer.center(0, 0); + List selectedParts = req.getTargets(); + if (selectedParts.isEmpty()) { + selectedParts = viewer.getSelectionSupport().getPartSelection(); + } + if (selectedParts.isEmpty()) + return; + + final Rectangle bounds = getSelectionBounds(viewer, selectedParts); + if (bounds != null) { + IFigure viewport = ((IGraphicalViewer) viewer).getCanvas() + .getViewport(); + viewer.getZoomManager().actualSize(); + bounds.getCenter().scale(viewer.getZoomManager().getScale()); + viewport.getUpdateManager().runWithUpdate(new Runnable() { + public void run() { + viewer.center(bounds.getCopy() + .scale(viewer.getZoomManager().getScale() * 2)); + } + }); + } } /** diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/AbstractViewerService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/AbstractViewerService.java index 58eef8655..3867dab26 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/AbstractViewerService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/AbstractViewerService.java @@ -1,95 +1,95 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import org.eclipse.swt.widgets.Control; -import org.xmind.gef.Disposable; -import org.xmind.gef.IViewer; - -public abstract class AbstractViewerService extends Disposable implements - IViewerService { - - private IViewer viewer; - - private boolean active = false; - - private Control control; - - public AbstractViewerService(IViewer viewer) { - this.viewer = viewer; - } - - public IViewer getViewer() { - return viewer; - } - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - if (active == this.active) - return; - - this.active = active; - if (active) { - if (getControl() != null) { - hookControl(getControl()); - } - activate(); - } else { - deactivate(); - if (getControl() != null) { - unhookControl(getControl()); - } - } - } - - protected abstract void activate(); - - protected abstract void deactivate(); - - public void setControl(Control viewerControl) { - if (viewerControl == this.control) - return; - - if (this.control != null && isActive()) - unhookControl(this.control); - this.control = viewerControl; - if (this.control != null && isActive()) - hookControl(this.control); - } - - public Control getControl() { - return control; - } - - protected void hookControl(Control control) { -// // may override - } - - protected void unhookControl(Control control) { - // may override - } - - public void dispose() { - setControl(null); - setActive(false); - super.dispose(); - } - - public void inputChanged(Object oldInput, Object newInput) { - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import org.eclipse.swt.widgets.Control; +import org.xmind.gef.Disposable; +import org.xmind.gef.IViewer; + +public abstract class AbstractViewerService extends Disposable implements + IViewerService { + + private IViewer viewer; + + private boolean active = false; + + private Control control; + + public AbstractViewerService(IViewer viewer) { + this.viewer = viewer; + } + + public IViewer getViewer() { + return viewer; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + if (active == this.active) + return; + + this.active = active; + if (active) { + if (getControl() != null) { + hookControl(getControl()); + } + activate(); + } else { + deactivate(); + if (getControl() != null) { + unhookControl(getControl()); + } + } + } + + protected abstract void activate(); + + protected abstract void deactivate(); + + public void setControl(Control viewerControl) { + if (viewerControl == this.control) + return; + + if (this.control != null && isActive()) + unhookControl(this.control); + this.control = viewerControl; + if (this.control != null && isActive()) + hookControl(this.control); + } + + public Control getControl() { + return control; + } + + protected void hookControl(Control control) { +// // may override + } + + protected void unhookControl(Control control) { + // may override + } + + public void dispose() { + setControl(null); + setActive(false); + super.dispose(); + } + + public void inputChanged(Object oldInput, Object newInput) { + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/BaseRevealService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/BaseRevealService.java index 92a188a1f..ccef54398 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/BaseRevealService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/BaseRevealService.java @@ -1,89 +1,89 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.service; - -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.util.EventListenerSupport; -import org.xmind.gef.util.IEventDispatcher; - -/** - * @author Frank Shaka - * - */ -public abstract class BaseRevealService extends GraphicalViewerService - implements IRevealService { - - private EventListenerSupport listeners = new EventListenerSupport(); - - /** - * @param viewer - */ - public BaseRevealService(IGraphicalViewer viewer) { - super(viewer); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.service.IRevealService#addRevealServiceListener(org.xmind - * .gef.service.IRevealServiceListener) - */ - public void addRevealServiceListener(IRevealServiceListener listener) { - listeners.addListener(IRevealServiceListener.class, listener); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.service.IRevealService#removeRevealServiceListener(org. - * xmind.gef.service.IRevealServiceListener) - */ - public void removeRevealServiceListener(IRevealServiceListener listener) { - listeners.removeListener(IRevealServiceListener.class, listener); - } - - protected void revealingStarted(final RevealEvent event) { - listeners.fireEvent(IRevealServiceListener.class, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((IRevealServiceListener) listener) - .revealingStarted(event); - } - }); - } - - protected void revealingCanceled(final RevealEvent event) { - listeners.fireEvent(IRevealServiceListener.class, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((IRevealServiceListener) listener) - .revealingCanceled(event); - } - }); - } - - protected void revealingFinished(final RevealEvent event) { - listeners.fireEvent(IRevealServiceListener.class, - new IEventDispatcher() { - public void dispatch(Object listener) { - ((IRevealServiceListener) listener) - .revealingFinished(event); - } - }); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.service; + +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.util.EventListenerSupport; +import org.xmind.gef.util.IEventDispatcher; + +/** + * @author Frank Shaka + * + */ +public abstract class BaseRevealService extends GraphicalViewerService + implements IRevealService { + + private EventListenerSupport listeners = new EventListenerSupport(); + + /** + * @param viewer + */ + public BaseRevealService(IGraphicalViewer viewer) { + super(viewer); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.service.IRevealService#addRevealServiceListener(org.xmind + * .gef.service.IRevealServiceListener) + */ + public void addRevealServiceListener(IRevealServiceListener listener) { + listeners.addListener(IRevealServiceListener.class, listener); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.service.IRevealService#removeRevealServiceListener(org. + * xmind.gef.service.IRevealServiceListener) + */ + public void removeRevealServiceListener(IRevealServiceListener listener) { + listeners.removeListener(IRevealServiceListener.class, listener); + } + + protected void revealingStarted(final RevealEvent event) { + listeners.fireEvent(IRevealServiceListener.class, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((IRevealServiceListener) listener) + .revealingStarted(event); + } + }); + } + + protected void revealingCanceled(final RevealEvent event) { + listeners.fireEvent(IRevealServiceListener.class, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((IRevealServiceListener) listener) + .revealingCanceled(event); + } + }); + } + + protected void revealingFinished(final RevealEvent event) { + listeners.fireEvent(IRevealServiceListener.class, + new IEventDispatcher() { + public void dispatch(Object listener) { + ((IRevealServiceListener) listener) + .revealingFinished(event); + } + }); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/CenterPreservationService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/CenterPreservationService.java index ed0a41287..abd245249 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/CenterPreservationService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/CenterPreservationService.java @@ -1,268 +1,268 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.service; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.draw2d.FreeformFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.Viewport; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; - -/** - * @author Frank Shaka - * - */ -public class CenterPreservationService extends GraphicalViewerService implements - Listener, PropertyChangeListener { - - protected static final Rectangle TEMP_AREA = new Rectangle(); - - private boolean centerOnContents; - - private Display display = null; - - protected Viewport viewport = null; - - protected Point centerPoint = new Point(); - - private boolean mousePressing = false; - - private boolean keyPressing = false; - - private boolean resizedDuringMousePress = false; - - private boolean resizedDuringKeyPress = false; - - /** - * - */ - public CenterPreservationService(IGraphicalViewer viewer) { - this(viewer, false); - } - - /** - * Constructs a new center preservation service. The parameter - * centerOnContents enables/disables the ability to take the - * center of the contents layer as the new center point. - * - * @param viewer - * @param centerOnContents - */ - public CenterPreservationService(IGraphicalViewer viewer, - boolean centerOnContents) { - super(viewer); - this.centerOnContents = centerOnContents; - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.service.AbstractViewerService#hookControl(org.eclipse.swt - * .widgets.Control) - */ - @Override - protected void hookControl(Control control) { - super.hookControl(control); - FigureCanvas canvas = (FigureCanvas) control; - if (canvas != null && !canvas.isDisposed()) { - canvas.addListener(SWT.Resize, this); - canvas.addListener(SWT.FocusIn, this); - canvas.addListener(SWT.FocusOut, this); - canvas.addListener(SWT.Paint, this); - - viewport = canvas.getViewport(); - if (viewport != null) { - viewport.addPropertyChangeListener( - Viewport.PROPERTY_VIEW_LOCATION, this); - } - display = canvas.getDisplay(); - if (display != null) { - display.addFilter(SWT.MouseDown, this); - display.addFilter(SWT.MouseUp, this); - display.addFilter(SWT.KeyDown, this); - display.addFilter(SWT.KeyUp, this); - } - } - mousePressing = false; - keyPressing = false; - resizedDuringMousePress = false; - resizedDuringKeyPress = false; - updateCenterPoint(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.service.AbstractViewerService#unhookControl(org.eclipse - * .swt.widgets.Control) - */ - @Override - protected void unhookControl(Control control) { - FigureCanvas canvas = (FigureCanvas) control; - if (canvas != null && !canvas.isDisposed()) { - canvas.removeListener(SWT.Resize, this); - canvas.removeListener(SWT.FocusIn, this); - canvas.removeListener(SWT.Paint, this); - } - - if (viewport != null) { - viewport.removePropertyChangeListener( - Viewport.PROPERTY_VIEW_LOCATION, this); - } - if (display != null && !display.isDisposed()) { - display.removeFilter(SWT.MouseDown, this); - display.removeFilter(SWT.MouseUp, this); - display.removeFilter(SWT.KeyDown, this); - display.removeFilter(SWT.KeyUp, this); - } - mousePressing = false; - keyPressing = false; - resizedDuringMousePress = false; - resizedDuringKeyPress = false; - super.unhookControl(control); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#activate() - */ - @Override - protected void activate() { - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#deactivate() - */ - @Override - protected void deactivate() { - } - - /* - * (non-Javadoc) - * - * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. - * PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent evt) { - if (!isActive()) - return; - - if ((mousePressing && resizedDuringMousePress) - || (keyPressing && resizedDuringKeyPress)) - return; - - updateCenterPoint(); - } - - private void updateCenterPoint() { - if (!isActive() || viewport == null) - return; - if (centerOnContents) { - Layer layer = getViewer().getLayer(GEF.LAYER_CONTENTS); - Rectangle bounds; - if (layer instanceof FreeformFigure) { - bounds = ((FreeformFigure) layer).getFreeformExtent(); - } else { - bounds = layer.getBounds(); - } - centerPoint.setLocation(bounds.x + bounds.width / 2, bounds.y - + bounds.height / 2); - } else { - Rectangle r = viewport.getClientArea(TEMP_AREA); - centerPoint.setLocation(r.x + r.width / 2, r.y + r.height / 2); - } - } - - private void centerViewportOnResize() { - if (!isActive() || viewport == null) - return; - - Rectangle r = viewport.getClientArea(TEMP_AREA); - viewport.setViewLocation(centerPoint.x - r.width / 2, centerPoint.y - - r.height / 2); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. - * Event) - */ - public void handleEvent(Event event) { - if (!isActive()) - return; - - if (event.type == SWT.Resize) { - if (needsCenterWhenResizing()) { - centerViewportOnResize(); - } - } else if (event.type == SWT.FocusIn || event.type == SWT.Paint) { - // Fix bug: - FigureCanvas fc = (FigureCanvas) event.widget; - org.eclipse.swt.graphics.Rectangle clientArea = fc.getClientArea(); - if (clientArea.width > 0 || clientArea.height > 0) { - centerViewportOnResize(); - fc.removeListener(event.type, this); - } - } else if (event.type == SWT.MouseDown) { - mousePressing = true; - } else if (event.type == SWT.KeyDown) { - keyPressing = true; - } else if (event.type == SWT.MouseUp) { - mousePressing = false; - if (resizedDuringMousePress) { - resizedDuringMousePress = false; - centerViewportOnResize(); - } - } else if (event.type == SWT.KeyUp) { - keyPressing = false; - if (resizedDuringKeyPress) { - resizedDuringKeyPress = false; - centerViewportOnResize(); - } - } - - } - - // If resizing occurs while mouse or key is pressed, - // don't center until mouse or key is released - private boolean needsCenterWhenResizing() { - if (!mousePressing && !keyPressing) - return true; - - if (mousePressing) - resizedDuringMousePress = true; - if (keyPressing) - resizedDuringKeyPress = true; - return false; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.service; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.FreeformFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; + +/** + * @author Frank Shaka + * + */ +public class CenterPreservationService extends GraphicalViewerService implements + Listener, PropertyChangeListener { + + protected static final Rectangle TEMP_AREA = new Rectangle(); + + private boolean centerOnContents; + + private Display display = null; + + protected Viewport viewport = null; + + protected Point centerPoint = new Point(); + + private boolean mousePressing = false; + + private boolean keyPressing = false; + + private boolean resizedDuringMousePress = false; + + private boolean resizedDuringKeyPress = false; + + /** + * + */ + public CenterPreservationService(IGraphicalViewer viewer) { + this(viewer, false); + } + + /** + * Constructs a new center preservation service. The parameter + * centerOnContents enables/disables the ability to take the + * center of the contents layer as the new center point. + * + * @param viewer + * @param centerOnContents + */ + public CenterPreservationService(IGraphicalViewer viewer, + boolean centerOnContents) { + super(viewer); + this.centerOnContents = centerOnContents; + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.service.AbstractViewerService#hookControl(org.eclipse.swt + * .widgets.Control) + */ + @Override + protected void hookControl(Control control) { + super.hookControl(control); + FigureCanvas canvas = (FigureCanvas) control; + if (canvas != null && !canvas.isDisposed()) { + canvas.addListener(SWT.Resize, this); + canvas.addListener(SWT.FocusIn, this); + canvas.addListener(SWT.FocusOut, this); + canvas.addListener(SWT.Paint, this); + + viewport = canvas.getViewport(); + if (viewport != null) { + viewport.addPropertyChangeListener( + Viewport.PROPERTY_VIEW_LOCATION, this); + } + display = canvas.getDisplay(); + if (display != null) { + display.addFilter(SWT.MouseDown, this); + display.addFilter(SWT.MouseUp, this); + display.addFilter(SWT.KeyDown, this); + display.addFilter(SWT.KeyUp, this); + } + } + mousePressing = false; + keyPressing = false; + resizedDuringMousePress = false; + resizedDuringKeyPress = false; + updateCenterPoint(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.service.AbstractViewerService#unhookControl(org.eclipse + * .swt.widgets.Control) + */ + @Override + protected void unhookControl(Control control) { + FigureCanvas canvas = (FigureCanvas) control; + if (canvas != null && !canvas.isDisposed()) { + canvas.removeListener(SWT.Resize, this); + canvas.removeListener(SWT.FocusIn, this); + canvas.removeListener(SWT.Paint, this); + } + + if (viewport != null) { + viewport.removePropertyChangeListener( + Viewport.PROPERTY_VIEW_LOCATION, this); + } + if (display != null && !display.isDisposed()) { + display.removeFilter(SWT.MouseDown, this); + display.removeFilter(SWT.MouseUp, this); + display.removeFilter(SWT.KeyDown, this); + display.removeFilter(SWT.KeyUp, this); + } + mousePressing = false; + keyPressing = false; + resizedDuringMousePress = false; + resizedDuringKeyPress = false; + super.unhookControl(control); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#activate() + */ + @Override + protected void activate() { + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#deactivate() + */ + @Override + protected void deactivate() { + } + + /* + * (non-Javadoc) + * + * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. + * PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent evt) { + if (!isActive()) + return; + + if ((mousePressing && resizedDuringMousePress) + || (keyPressing && resizedDuringKeyPress)) + return; + + updateCenterPoint(); + } + + private void updateCenterPoint() { + if (!isActive() || viewport == null) + return; + if (centerOnContents) { + Layer layer = getViewer().getLayer(GEF.LAYER_CONTENTS); + Rectangle bounds; + if (layer instanceof FreeformFigure) { + bounds = ((FreeformFigure) layer).getFreeformExtent(); + } else { + bounds = layer.getBounds(); + } + centerPoint.setLocation(bounds.x + bounds.width / 2, bounds.y + + bounds.height / 2); + } else { + Rectangle r = viewport.getClientArea(TEMP_AREA); + centerPoint.setLocation(r.x + r.width / 2, r.y + r.height / 2); + } + } + + private void centerViewportOnResize() { + if (!isActive() || viewport == null) + return; + + Rectangle r = viewport.getClientArea(TEMP_AREA); + viewport.setViewLocation(centerPoint.x - r.width / 2, centerPoint.y + - r.height / 2); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. + * Event) + */ + public void handleEvent(Event event) { + if (!isActive()) + return; + + if (event.type == SWT.Resize) { + if (needsCenterWhenResizing()) { + centerViewportOnResize(); + } + } else if (event.type == SWT.FocusIn || event.type == SWT.Paint) { + // Fix bug: + FigureCanvas fc = (FigureCanvas) event.widget; + org.eclipse.swt.graphics.Rectangle clientArea = fc.getClientArea(); + if (clientArea.width > 0 || clientArea.height > 0) { + centerViewportOnResize(); + fc.removeListener(event.type, this); + } + } else if (event.type == SWT.MouseDown) { + mousePressing = true; + } else if (event.type == SWT.KeyDown) { + keyPressing = true; + } else if (event.type == SWT.MouseUp) { + mousePressing = false; + if (resizedDuringMousePress) { + resizedDuringMousePress = false; + centerViewportOnResize(); + } + } else if (event.type == SWT.KeyUp) { + keyPressing = false; + if (resizedDuringKeyPress) { + resizedDuringKeyPress = false; + centerViewportOnResize(); + } + } + + } + + // If resizing occurs while mouse or key is pressed, + // don't center until mouse or key is released + private boolean needsCenterWhenResizing() { + if (!mousePressing && !keyPressing) + return true; + + if (mousePressing) + resizedDuringMousePress = true; + if (keyPressing) + resizedDuringKeyPress = true; + return false; + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/FeedbackService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/FeedbackService.java index 6ede5343f..df0c362d5 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/FeedbackService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/FeedbackService.java @@ -1,483 +1,483 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IZoomListener; -import org.xmind.gef.ZoomManager; -import org.xmind.gef.ZoomObject; -import org.xmind.gef.draw2d.IRotatableFigure; -import org.xmind.gef.draw2d.SelectionFigure; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; - -public class FeedbackService extends GraphicalViewerService implements - IZoomListener, FocusListener, FigureListener, IFeedbackService { - - private static final List NO_FEEDBACK = Collections.emptyList(); - - private IFigure layer; - - private ZoomManager zoom; - - private List feedbacks = null; - - private Map selections = new HashMap(); - - private IColorProvider selectionColorProvider = null; - - private int selectionLineWidth = 2; - - private int selectionCorner = 5; - - public FeedbackService(IGraphicalViewer viewer) { - super(viewer); - } - - public int getSelectionCorner() { - return selectionCorner; - } - - public void setSelectionCorner(int selectionCorner) { - this.selectionCorner = selectionCorner; - } - - public int getSelectionLineWidth() { - return selectionLineWidth; - } - - public void setSelectionLineWidth(int selectionLineWidth) { - this.selectionLineWidth = selectionLineWidth; - } - - public List getFeedbackParts() { - if (feedbacks == null) - return NO_FEEDBACK; - return feedbacks; - } - - protected void activate() { - setZoomManager(getViewer().getZoomManager()); - } - - protected void deactivate() { - setZoomManager(null); - } - - protected void hookControl(Control control) { - control.addFocusListener(this); - } - - protected void unhookControl(Control canvas) { - canvas.removeFocusListener(this); - } - - public void setLayer(IFigure layer) { - IFigure oldLayer = this.layer; - this.layer = layer; - - if (feedbacks != null) { - if (oldLayer == null && layer != null) { - for (IFeedback part : feedbacks) { - part.addToLayer(layer); - part.update(); - } - } else if (oldLayer != null && layer == null) { - for (IFeedback part : feedbacks) { - part.removeFromLayer(oldLayer); - } - } - } - } - - public void focusGained(FocusEvent e) { - if (getControl() != null && !getControl().isDisposed()) { - Display display = getControl().getDisplay(); - if (display != null) { - display.asyncExec(new Runnable() { - public void run() { - if (getControl() != null && !getControl().isDisposed()) - refresh(); - } - }); - } - } - } - - public void focusLost(FocusEvent e) { - if (getControl() != null && !getControl().isDisposed()) { - Display display = getControl().getDisplay(); - if (display != null) { - display.asyncExec(new Runnable() { - public void run() { - if (getControl() != null && !getControl().isDisposed()) - refresh(); - } - }); - } - } - } - - private void setZoomManager(ZoomManager zoom) { - if (this.zoom == zoom) - return; - if (this.zoom != null) - this.zoom.removeZoomListener(this); - this.zoom = zoom; - if (this.zoom != null) - this.zoom.addZoomListener(this); - refresh(); - } - - /** - * @see cn.brainy.gef.core.IZoomListener#scaleChanged(cn.brainy.gef.core.ZoomObject, - * double, double) - */ - public void scaleChanged(ZoomObject source, double oldValue, double newValue) { - if (isActive() && !isDisposed()) { - updateAllFeedback(); - updateAllSelections(); - } - } - - public void refresh() { - if (isActive() && !isDisposed()) { - updateAllFeedback(); - updateAllSelections(); - updateSelectionColors(); - } - } - - private void updateAllFeedback() { - if (feedbacks != null) { - for (Object o : feedbacks.toArray()) { - ((IFeedback) o).update(); - } - } - } - - private void updateAllSelections() { - for (IFigure source : selections.keySet()) { - updateSelection(source); - } - } - - public void addFeedback(IFeedback feedback) { - if (feedback == null) - return; - if (feedbacks != null && feedbacks.contains(feedback)) - return; - - if (feedbacks == null) - feedbacks = new ArrayList(); - feedbacks.add(feedback); - feedback.setZoomManager(zoom); - if (layer != null) - feedback.addToLayer(layer); - feedback.update(); - } - - public void removeFeedback(IFeedback feedback) { - if (feedback == null) - return; - if (feedbacks == null || !feedbacks.contains(feedback)) - return; - - if (layer != null) - feedback.removeFromLayer(layer); - feedback.setZoomManager(null); - feedbacks.remove(feedback); - } - - /** - * @param selectionColorProvider - * the selectionColorProvider to set - */ - public void setSelectionColorProvider(IColorProvider selectionColorProvider) { - this.selectionColorProvider = selectionColorProvider; - } - - /** - * @return the selectionColorProvider - */ - public IColorProvider getSelectionColorProvider() { - return selectionColorProvider; - } - - public SelectionFigure addSelection(IFigure source) { - removeSelection(source); - if (layer == null) - return null; - - SelectionFigure selection = createSelectionFigure(); - selections.put(source, selection); - updateSelection(source); -// updateSelectionColors(); - layer.add(selection); - source.addFigureListener(this); - return selection; - } - - private void updateSelectionColors() { - IColorProvider colorProvider = getSelectionColorProvider(); - if (colorProvider != null) { - Color focusColor; - Color selectionColor; - Color preselectionColor; - Color focusFillColor; - Color selectionFillColor; - Color preselectionFillColor; - boolean disabled = getControl() != null - && !getControl().isDisposed() - && !getControl().isFocusControl(); - if (disabled) { - focusColor = colorProvider.getForeground(DisabledFocusColor); - selectionColor = colorProvider - .getForeground(DisabledSelectionColor); - preselectionColor = colorProvider - .getForeground(DisabledPreselectionColor); - focusFillColor = colorProvider - .getBackground(DisabledFocusColor); - selectionFillColor = colorProvider - .getBackground(DisabledSelectionColor); - preselectionFillColor = colorProvider - .getBackground(DisabledPreselectionColor); - } else { - focusColor = colorProvider.getForeground(FocusColor); - selectionColor = colorProvider.getForeground(SelectionColor); - preselectionColor = colorProvider - .getForeground(PreselectionColor); - focusFillColor = colorProvider.getBackground(FocusColor); - selectionFillColor = colorProvider - .getBackground(SelectionColor); - preselectionFillColor = colorProvider - .getBackground(PreselectionColor); - } - for (SelectionFigure f : selections.values()) { - f.setFocusColor(focusColor); - f.setSelectionColor(selectionColor); - f.setPreselectionColor(preselectionColor); - f.setFocusFillColor(focusFillColor); - f.setSelectionFillColor(selectionFillColor); - f.setPreselectionFillColor(preselectionFillColor); - } - } - } - - /** - * @return - */ - private SelectionFigure createSelectionFigure() { - SelectionFigure f = new SelectionFigure(); - IColorProvider colorProvider = getSelectionColorProvider(); - if (colorProvider != null) { - Color focusColor; - Color selectionColor; - Color preselectionColor; - Color focusFillColor; - Color selectionFillColor; - Color preselectionFillColor; - boolean disabled = getControl() != null - && !getControl().isDisposed() - && !getControl().isFocusControl(); - if (disabled) { - focusColor = colorProvider.getForeground(DisabledFocusColor); - selectionColor = colorProvider - .getForeground(DisabledSelectionColor); - preselectionColor = colorProvider - .getForeground(DisabledPreselectionColor); - focusFillColor = colorProvider - .getBackground(DisabledFocusColor); - selectionFillColor = colorProvider - .getBackground(DisabledSelectionColor); - preselectionFillColor = colorProvider - .getBackground(DisabledPreselectionColor); - } else { - focusColor = colorProvider.getForeground(FocusColor); - selectionColor = colorProvider.getForeground(SelectionColor); - preselectionColor = colorProvider - .getForeground(PreselectionColor); - focusFillColor = colorProvider.getBackground(FocusColor); - selectionFillColor = colorProvider - .getBackground(SelectionColor); - preselectionFillColor = colorProvider - .getBackground(PreselectionColor); - } - f.setFocusColor(focusColor); - f.setSelectionColor(selectionColor); - f.setPreselectionColor(preselectionColor); - f.setFocusFillColor(focusFillColor); - f.setSelectionFillColor(selectionFillColor); - f.setPreselectionFillColor(preselectionFillColor); - } - f.setLineWidth(selectionLineWidth); - return f; - } - - public SelectionFigure removeSelection(IFigure source) { - SelectionFigure old = selections.remove(source); - if (old != null && old.getParent() == layer) { - if (layer != null) - layer.remove(old); - disposeSelection(old); - } - source.removeFigureListener(this); - return old; - } - - /** - * @param source - * @return - */ - public SelectionFigure getSelectionFigure(IFigure source) { - SelectionFigure figure = selections.get(source); - return (figure == null) ? addSelection(source) : figure; - } - - public SelectionFigure setSelected(IFigure source) { - SelectionFigure figure = getSelectionFigure(source); - if (figure != null) { - figure.setFocused(false); - figure.setPreselected(false); - figure.setSelected(true); - } - return figure; - } - - public SelectionFigure setPreselected(IFigure source) { - SelectionFigure figure = getSelectionFigure(source); - if (figure != null) { - figure.setFocused(false); - figure.setSelected(false); - figure.setPreselected(true); - } - return figure; - } - - public SelectionFigure setFocused(IFigure source) { - SelectionFigure figure = getSelectionFigure(source); - if (figure != null) { - figure.setSelected(false); - figure.setPreselected(false); - figure.setFocused(true); - } - return figure; - } - - /** - * @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure) - */ - public void figureMoved(IFigure source) { - updateSelection(source); - } - - private void updateSelection(IFigure source) { - SelectionFigure selection = selections.get(source); - if (selection != null) { - disposeSelection(selection); - org.xmind.gef.draw2d.graphics.Path p = new org.xmind.gef.draw2d.graphics.Path( - Display.getCurrent()); - int lineWidth = selectionLineWidth; - if (zoom != null) { - lineWidth *= zoom.getScale(); - if (lineWidth < 2) - lineWidth = 2; - } - selection.setLineWidth(lineWidth); - int exp = lineWidth; - double halfExp = aZoom(exp * 0.5 + 0.5); - PrecisionRectangle bounds = new PrecisionRectangle(source - .getBounds());//.resize(-1, -1); - - if ("win32".equals(SWT.getPlatform())) { //$NON-NLS-1$ - bounds.resize(-1, -1); - } - if (source instanceof IRotatableFigure - && ((IRotatableFigure) source).getRotationDegrees() != 0) { - IRotatableFigure rf = (IRotatableFigure) source; - PrecisionDimension size = rf.getNormalPreferredSize(-1, -1); - PrecisionPoint c = bounds.getCenter(); - PrecisionRotator r = new PrecisionRotator(c); - r.setAngle(rf.getRotationDegrees()); - PrecisionRectangle b = r.r(bounds, -1, size.height); - b.expand(halfExp, halfExp); - p.addRoundedPolygon(selectionCorner, zoom(r.t(b.getTopLeft())), - zoom(r.t(b.getTopRight())), zoom(r - .t(b.getBottomRight())), zoom(r.t(b - .getBottomLeft()))); - } else { - - p.addRoundedRectangle(zoom(bounds.expand(halfExp, halfExp)), - selectionCorner); - } - selection.setPath(p); -// selection.setBounds(selection.getPreferredBounds()); - } - } - - private double aZoom(double d) { - return zoom == null ? d : d / zoom.getScale(); - } - - private PrecisionPoint zoom(PrecisionPoint p) { - return zoom == null ? p : p.scale(zoom.getScale()); - } - - private PrecisionRectangle zoom(PrecisionRectangle r) { - return zoom == null ? r : r.scale(zoom.getScale()); - } - - private void disposeSelection(SelectionFigure s) { - Path p = s.getPath(); - if (p != null && !p.isDisposed()) { - s.setPath(null); - p.dispose(); - } - } - - public void dispose() { - if (selections != null) { - for (Object key : selections.keySet().toArray()) { - removeSelection((IFigure) key); - } - selections.clear(); - } - super.dispose(); - } - - public void addSkylight(IFigure figure) { - } - - public void removeSkylight(IFigure figure) { - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IZoomListener; +import org.xmind.gef.ZoomManager; +import org.xmind.gef.ZoomObject; +import org.xmind.gef.draw2d.IRotatableFigure; +import org.xmind.gef.draw2d.SelectionFigure; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; + +public class FeedbackService extends GraphicalViewerService implements + IZoomListener, FocusListener, FigureListener, IFeedbackService { + + private static final List NO_FEEDBACK = Collections.emptyList(); + + private IFigure layer; + + private ZoomManager zoom; + + private List feedbacks = null; + + private Map selections = new HashMap(); + + private IColorProvider selectionColorProvider = null; + + private int selectionLineWidth = 2; + + private int selectionCorner = 5; + + public FeedbackService(IGraphicalViewer viewer) { + super(viewer); + } + + public int getSelectionCorner() { + return selectionCorner; + } + + public void setSelectionCorner(int selectionCorner) { + this.selectionCorner = selectionCorner; + } + + public int getSelectionLineWidth() { + return selectionLineWidth; + } + + public void setSelectionLineWidth(int selectionLineWidth) { + this.selectionLineWidth = selectionLineWidth; + } + + public List getFeedbackParts() { + if (feedbacks == null) + return NO_FEEDBACK; + return feedbacks; + } + + protected void activate() { + setZoomManager(getViewer().getZoomManager()); + } + + protected void deactivate() { + setZoomManager(null); + } + + protected void hookControl(Control control) { + control.addFocusListener(this); + } + + protected void unhookControl(Control canvas) { + canvas.removeFocusListener(this); + } + + public void setLayer(IFigure layer) { + IFigure oldLayer = this.layer; + this.layer = layer; + + if (feedbacks != null) { + if (oldLayer == null && layer != null) { + for (IFeedback part : feedbacks) { + part.addToLayer(layer); + part.update(); + } + } else if (oldLayer != null && layer == null) { + for (IFeedback part : feedbacks) { + part.removeFromLayer(oldLayer); + } + } + } + } + + public void focusGained(FocusEvent e) { + if (getControl() != null && !getControl().isDisposed()) { + Display display = getControl().getDisplay(); + if (display != null) { + display.asyncExec(new Runnable() { + public void run() { + if (getControl() != null && !getControl().isDisposed()) + refresh(); + } + }); + } + } + } + + public void focusLost(FocusEvent e) { + if (getControl() != null && !getControl().isDisposed()) { + Display display = getControl().getDisplay(); + if (display != null) { + display.asyncExec(new Runnable() { + public void run() { + if (getControl() != null && !getControl().isDisposed()) + refresh(); + } + }); + } + } + } + + private void setZoomManager(ZoomManager zoom) { + if (this.zoom == zoom) + return; + if (this.zoom != null) + this.zoom.removeZoomListener(this); + this.zoom = zoom; + if (this.zoom != null) + this.zoom.addZoomListener(this); + refresh(); + } + + /** + * @see cn.brainy.gef.core.IZoomListener#scaleChanged(cn.brainy.gef.core.ZoomObject, + * double, double) + */ + public void scaleChanged(ZoomObject source, double oldValue, double newValue) { + if (isActive() && !isDisposed()) { + updateAllFeedback(); + updateAllSelections(); + } + } + + public void refresh() { + if (isActive() && !isDisposed()) { + updateAllFeedback(); + updateAllSelections(); + updateSelectionColors(); + } + } + + private void updateAllFeedback() { + if (feedbacks != null) { + for (Object o : feedbacks.toArray()) { + ((IFeedback) o).update(); + } + } + } + + private void updateAllSelections() { + for (IFigure source : selections.keySet()) { + updateSelection(source); + } + } + + public void addFeedback(IFeedback feedback) { + if (feedback == null) + return; + if (feedbacks != null && feedbacks.contains(feedback)) + return; + + if (feedbacks == null) + feedbacks = new ArrayList(); + feedbacks.add(feedback); + feedback.setZoomManager(zoom); + if (layer != null) + feedback.addToLayer(layer); + feedback.update(); + } + + public void removeFeedback(IFeedback feedback) { + if (feedback == null) + return; + if (feedbacks == null || !feedbacks.contains(feedback)) + return; + + if (layer != null) + feedback.removeFromLayer(layer); + feedback.setZoomManager(null); + feedbacks.remove(feedback); + } + + /** + * @param selectionColorProvider + * the selectionColorProvider to set + */ + public void setSelectionColorProvider(IColorProvider selectionColorProvider) { + this.selectionColorProvider = selectionColorProvider; + } + + /** + * @return the selectionColorProvider + */ + public IColorProvider getSelectionColorProvider() { + return selectionColorProvider; + } + + public SelectionFigure addSelection(IFigure source) { + removeSelection(source); + if (layer == null) + return null; + + SelectionFigure selection = createSelectionFigure(); + selections.put(source, selection); + updateSelection(source); +// updateSelectionColors(); + layer.add(selection); + source.addFigureListener(this); + return selection; + } + + private void updateSelectionColors() { + IColorProvider colorProvider = getSelectionColorProvider(); + if (colorProvider != null) { + Color focusColor; + Color selectionColor; + Color preselectionColor; + Color focusFillColor; + Color selectionFillColor; + Color preselectionFillColor; + boolean disabled = getControl() != null + && !getControl().isDisposed() + && !getControl().isFocusControl(); + if (disabled) { + focusColor = colorProvider.getForeground(DisabledFocusColor); + selectionColor = colorProvider + .getForeground(DisabledSelectionColor); + preselectionColor = colorProvider + .getForeground(DisabledPreselectionColor); + focusFillColor = colorProvider + .getBackground(DisabledFocusColor); + selectionFillColor = colorProvider + .getBackground(DisabledSelectionColor); + preselectionFillColor = colorProvider + .getBackground(DisabledPreselectionColor); + } else { + focusColor = colorProvider.getForeground(FocusColor); + selectionColor = colorProvider.getForeground(SelectionColor); + preselectionColor = colorProvider + .getForeground(PreselectionColor); + focusFillColor = colorProvider.getBackground(FocusColor); + selectionFillColor = colorProvider + .getBackground(SelectionColor); + preselectionFillColor = colorProvider + .getBackground(PreselectionColor); + } + for (SelectionFigure f : selections.values()) { + f.setFocusColor(focusColor); + f.setSelectionColor(selectionColor); + f.setPreselectionColor(preselectionColor); + f.setFocusFillColor(focusFillColor); + f.setSelectionFillColor(selectionFillColor); + f.setPreselectionFillColor(preselectionFillColor); + } + } + } + + /** + * @return + */ + private SelectionFigure createSelectionFigure() { + SelectionFigure f = new SelectionFigure(); + IColorProvider colorProvider = getSelectionColorProvider(); + if (colorProvider != null) { + Color focusColor; + Color selectionColor; + Color preselectionColor; + Color focusFillColor; + Color selectionFillColor; + Color preselectionFillColor; + boolean disabled = getControl() != null + && !getControl().isDisposed() + && !getControl().isFocusControl(); + if (disabled) { + focusColor = colorProvider.getForeground(DisabledFocusColor); + selectionColor = colorProvider + .getForeground(DisabledSelectionColor); + preselectionColor = colorProvider + .getForeground(DisabledPreselectionColor); + focusFillColor = colorProvider + .getBackground(DisabledFocusColor); + selectionFillColor = colorProvider + .getBackground(DisabledSelectionColor); + preselectionFillColor = colorProvider + .getBackground(DisabledPreselectionColor); + } else { + focusColor = colorProvider.getForeground(FocusColor); + selectionColor = colorProvider.getForeground(SelectionColor); + preselectionColor = colorProvider + .getForeground(PreselectionColor); + focusFillColor = colorProvider.getBackground(FocusColor); + selectionFillColor = colorProvider + .getBackground(SelectionColor); + preselectionFillColor = colorProvider + .getBackground(PreselectionColor); + } + f.setFocusColor(focusColor); + f.setSelectionColor(selectionColor); + f.setPreselectionColor(preselectionColor); + f.setFocusFillColor(focusFillColor); + f.setSelectionFillColor(selectionFillColor); + f.setPreselectionFillColor(preselectionFillColor); + } + f.setLineWidth(selectionLineWidth); + return f; + } + + public SelectionFigure removeSelection(IFigure source) { + SelectionFigure old = selections.remove(source); + if (old != null && old.getParent() == layer) { + if (layer != null) + layer.remove(old); + disposeSelection(old); + } + source.removeFigureListener(this); + return old; + } + + /** + * @param source + * @return + */ + public SelectionFigure getSelectionFigure(IFigure source) { + SelectionFigure figure = selections.get(source); + return (figure == null) ? addSelection(source) : figure; + } + + public SelectionFigure setSelected(IFigure source) { + SelectionFigure figure = getSelectionFigure(source); + if (figure != null) { + figure.setFocused(false); + figure.setPreselected(false); + figure.setSelected(true); + } + return figure; + } + + public SelectionFigure setPreselected(IFigure source) { + SelectionFigure figure = getSelectionFigure(source); + if (figure != null) { + figure.setFocused(false); + figure.setSelected(false); + figure.setPreselected(true); + } + return figure; + } + + public SelectionFigure setFocused(IFigure source) { + SelectionFigure figure = getSelectionFigure(source); + if (figure != null) { + figure.setSelected(false); + figure.setPreselected(false); + figure.setFocused(true); + } + return figure; + } + + /** + * @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure) + */ + public void figureMoved(IFigure source) { + updateSelection(source); + } + + private void updateSelection(IFigure source) { + SelectionFigure selection = selections.get(source); + if (selection != null) { + disposeSelection(selection); + org.xmind.gef.draw2d.graphics.Path p = new org.xmind.gef.draw2d.graphics.Path( + Display.getCurrent()); + int lineWidth = selectionLineWidth; + if (zoom != null) { + lineWidth *= zoom.getScale(); + if (lineWidth < 2) + lineWidth = 2; + } + selection.setLineWidth(lineWidth); + int exp = lineWidth; + double halfExp = aZoom(exp * 0.5 + 0.5); + PrecisionRectangle bounds = new PrecisionRectangle(source + .getBounds());//.resize(-1, -1); + + if ("win32".equals(SWT.getPlatform())) { //$NON-NLS-1$ + bounds.resize(-1, -1); + } + if (source instanceof IRotatableFigure + && ((IRotatableFigure) source).getRotationDegrees() != 0) { + IRotatableFigure rf = (IRotatableFigure) source; + PrecisionDimension size = rf.getNormalPreferredSize(-1, -1); + PrecisionPoint c = bounds.getCenter(); + PrecisionRotator r = new PrecisionRotator(c); + r.setAngle(rf.getRotationDegrees()); + PrecisionRectangle b = r.r(bounds, -1, size.height); + b.expand(halfExp, halfExp); + p.addRoundedPolygon(selectionCorner, zoom(r.t(b.getTopLeft())), + zoom(r.t(b.getTopRight())), zoom(r + .t(b.getBottomRight())), zoom(r.t(b + .getBottomLeft()))); + } else { + + p.addRoundedRectangle(zoom(bounds.expand(halfExp, halfExp)), + selectionCorner); + } + selection.setPath(p); +// selection.setBounds(selection.getPreferredBounds()); + } + } + + private double aZoom(double d) { + return zoom == null ? d : d / zoom.getScale(); + } + + private PrecisionPoint zoom(PrecisionPoint p) { + return zoom == null ? p : p.scale(zoom.getScale()); + } + + private PrecisionRectangle zoom(PrecisionRectangle r) { + return zoom == null ? r : r.scale(zoom.getScale()); + } + + private void disposeSelection(SelectionFigure s) { + Path p = s.getPath(); + if (p != null && !p.isDisposed()) { + s.setPath(null); + p.dispose(); + } + } + + public void dispose() { + if (selections != null) { + for (Object key : selections.keySet().toArray()) { + removeSelection((IFigure) key); + } + selections.clear(); + } + super.dispose(); + } + + public void addSkylight(IFigure figure) { + } + + public void removeSkylight(IFigure figure) { + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/IPointProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/IPointProvider.java index 282ec75a4..e34be5a40 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/IPointProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/IPointProvider.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import org.eclipse.draw2d.geometry.Point; - -public interface IPointProvider { - - Point getPoint(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import org.eclipse.draw2d.geometry.Point; + +public interface IPointProvider { + + Point getPoint(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRectangleProvider.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRectangleProvider.java index 4027bfcb6..35b12598c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRectangleProvider.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRectangleProvider.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import org.eclipse.draw2d.geometry.Rectangle; - -public interface IRectangleProvider { - - Rectangle getRectangle(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import org.eclipse.draw2d.geometry.Rectangle; + +public interface IRectangleProvider { + + Rectangle getRectangle(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealService.java index cd3573487..b745f5d98 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealService.java @@ -1,26 +1,26 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import org.eclipse.jface.viewers.ISelection; - -public interface IRevealService extends IViewerService { - - void reveal(ISelection selection); - - void addRevealServiceListener(IRevealServiceListener listener); - - void removeRevealServiceListener(IRevealServiceListener listener); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import org.eclipse.jface.viewers.ISelection; + +public interface IRevealService extends IViewerService { + + void reveal(ISelection selection); + + void addRevealServiceListener(IRevealServiceListener listener); + + void removeRevealServiceListener(IRevealServiceListener listener); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealServiceListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealServiceListener.java index b607a8c91..fefd05360 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealServiceListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/IRevealServiceListener.java @@ -1,29 +1,29 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.service; - -/** - * @author Frank Shaka - * - */ -public interface IRevealServiceListener { - - void revealingStarted(RevealEvent event); - - void revealingCanceled(RevealEvent event); - - void revealingFinished(RevealEvent event); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.service; + +/** + * @author Frank Shaka + * + */ +public interface IRevealServiceListener { + + void revealingStarted(RevealEvent event); + + void revealingCanceled(RevealEvent event); + + void revealingFinished(RevealEvent event); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/IViewerService2.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/IViewerService2.java index 45a2e4daa..e97360bd2 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/IViewerService2.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/IViewerService2.java @@ -1,20 +1,20 @@ -package org.xmind.gef.service; - -public interface IViewerService2 { - - /** - * Get essential data to preserve before this service is deactivated. - * - * @return the data to preserve - */ - Object preserveData(); - - /** - * Restore preserved data after this service is activated. - * - * @param data - * the data to preserve - */ - void restoreData(Object data); - -} +package org.xmind.gef.service; + +public interface IViewerService2 { + + /** + * Get essential data to preserve before this service is deactivated. + * + * @return the data to preserve + */ + Object preserveData(); + + /** + * Restore preserved data after this service is activated. + * + * @param data + * the data to preserve + */ + void restoreData(Object data); + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/RevealEvent.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/RevealEvent.java index 3a8f48b37..b836a7a69 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/RevealEvent.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/RevealEvent.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.service; - -import java.util.EventObject; -import java.util.List; - -import org.xmind.gef.part.IGraphicalPart; - -/** - * @author Frank Shaka - * - */ -public class RevealEvent extends EventObject { - - /** - * - */ - private static final long serialVersionUID = 6690604795694135622L; - - private List partsToReveal; - - /** - * @param source - */ - public RevealEvent(Object source, List partsToReveal) { - super(source); - this.partsToReveal = partsToReveal; - } - - /** - * @return the partsToReveal - */ - public List getPartsToReveal() { - return partsToReveal; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.service; + +import java.util.EventObject; +import java.util.List; + +import org.xmind.gef.part.IGraphicalPart; + +/** + * @author Frank Shaka + * + */ +public class RevealEvent extends EventObject { + + /** + * + */ + private static final long serialVersionUID = 6690604795694135622L; + + private List partsToReveal; + + /** + * @param source + */ + public RevealEvent(Object source, List partsToReveal) { + super(source); + this.partsToReveal = partsToReveal; + } + + /** + * @return the partsToReveal + */ + public List getPartsToReveal() { + return partsToReveal; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/StyleOverrideService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/StyleOverrideService.java index faf585be8..f2cf04717 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/StyleOverrideService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/StyleOverrideService.java @@ -1,30 +1,30 @@ -package org.xmind.gef.service; - -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.graphicalpolicy.IStyleValueProvider; -import org.xmind.gef.part.IGraphicalPart; - -public class StyleOverrideService extends GraphicalViewerService implements - IStyleValueProvider { - - public StyleOverrideService(IGraphicalViewer viewer) { - super(viewer); - } - - public boolean isKeyInteresting(IGraphicalPart part, String key) { - return false; - } - - public String getValue(IGraphicalPart part, String key) { - return null; - } - - @Override - protected void activate() { - } - - @Override - protected void deactivate() { - } - -} +package org.xmind.gef.service; + +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.graphicalpolicy.IStyleValueProvider; +import org.xmind.gef.part.IGraphicalPart; + +public class StyleOverrideService extends GraphicalViewerService implements + IStyleValueProvider { + + public StyleOverrideService(IGraphicalViewer viewer) { + super(viewer); + } + + public boolean isKeyInteresting(IGraphicalPart part, String key) { + return false; + } + + public String getValue(IGraphicalPart part, String key) { + return null; + } + + @Override + protected void activate() { + } + + @Override + protected void deactivate() { + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/service/ZoomingAndPanningRevealService.java b/bundles/org.xmind.gef/src/org/xmind/gef/service/ZoomingAndPanningRevealService.java index ece1cfaf5..8023e1260 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/service/ZoomingAndPanningRevealService.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/service/ZoomingAndPanningRevealService.java @@ -1,441 +1,447 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.service; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.part.IGraphicalPart; - -public abstract class ZoomingAndPanningRevealService extends BaseRevealService { - - private class RevealJob implements Runnable { - - private Display display; - - private List toReveal; - - private long startTime = -1; - - private boolean canceled = false; - - private int elapsedSteps = -1; - - public RevealJob(Display display, List toReveal) { - this.display = display; - this.toReveal = toReveal; - } - - public void cancel() { - boolean oldCanceled = this.canceled; - setCanceled(); - if (!oldCanceled) { - revealingCanceled(new RevealEvent( - ZoomingAndPanningRevealService.this, toReveal)); - } - } - - private void setCanceled() { - canceled = true; - } - - public void run() { - if (canceled) - return; - - Control control = getViewer().getControl(); - if (control == null || control.isDisposed()) { - setCanceled(); - return; - } - - if (!isAnimationEnabled()) { - finish(); - return; - } - - long currentTime = System.currentTimeMillis(); - if (startTime < 0) - startTime = currentTime; - - int elapsedTime = (int) (currentTime - startTime); - int remainingTime = getDuration() - elapsedTime; - if (remainingTime <= 0) { - finish(); - return; - } - - double intervals = INTERVALS; - if (elapsedSteps < 0) { - elapsedSteps = 0; - intervals += 10; - } else { - intervals += (((double) (currentTime - startTime - - INTERVALS * elapsedSteps)) / elapsedSteps); - } - - int remainingSteps = (int) ((remainingTime + intervals - 1) - / intervals); - if (remainingSteps <= 0) { - finish(); - return; - } - - Rectangle revealBounds = getRevealBounds(toReveal); - if (revealBounds == null) { - cancel(); - return; - } - - doStep(toReveal, revealBounds, remainingSteps); - - display.timerExec(INTERVALS, this); - elapsedSteps++; - } - - public void finish() { - setCanceled(); - revealJobFinished(toReveal); - } - - } - - private static final int INTERVALS = 20; - - private int duration = 200; - - private int delay = 100; - - private RevealJob job = null; - - private double cachedScale = -1; - - private boolean centered = false; - - private int spacing = 20; - - private boolean zoomed = false; - - private boolean animationEnabled = true; - - private boolean shouldRevealOnIntersection = true; - - protected ZoomingAndPanningRevealService(IGraphicalViewer viewer) { - super(viewer); - } - - public int getDuration() { - return duration; - } - - public void setDuration(int duration) { - this.duration = duration; - } - - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - public void setCentered(boolean centered) { - this.centered = centered; - } - - public boolean isCentered() { - return this.centered; - } - - public void setSpacing(int spacing) { - this.spacing = spacing; - } - - public int getSpacing() { - return this.spacing; - } - - /** - * @param zoomed - * the zoomed to set - */ - public void setZoomed(boolean zoomed) { - this.zoomed = zoomed; - } - - public void setShouldRevealOnIntersection(boolean should) { - this.shouldRevealOnIntersection = should; - } - - public boolean isShouldRevealOnIntersection() { - return shouldRevealOnIntersection; - } - - /** - * @return the zoomed - */ - public boolean isZoomed() { - return this.zoomed; - } - - public void setAnimationEnabled(boolean animationEnabled) { - this.animationEnabled = animationEnabled; - } - - protected boolean isAnimationEnabled() { - return animationEnabled; - } - - protected void activate() { - } - - protected void deactivate() { - } - - public void reveal(ISelection selection) { - if (!isActive()) - return; - - startReveal(selection); - } - - protected void startReveal(ISelection selection) { - if (job != null) { - job.cancel(); - job = null; - } - cachedScale = -1; - - List toReveal = collectPartsToReveal(selection); - if (toReveal != null && shouldReveal(toReveal)) { - Display display = Display.getCurrent(); - job = new RevealJob(display, toReveal); - display.timerExec(delay, job); - revealingStarted(new RevealEvent(this, toReveal)); - } - } - - protected boolean shouldReveal(List toReveal) { - return !toReveal.isEmpty(); - } - - protected double calcTargetScale(List toReveal, - Rectangle revealBounds) { - if (!isZoomed()) - return -1; - - if (cachedScale > 0) - return cachedScale; - - Rectangle clientArea = getViewer().getClientArea(); - int width = revealBounds.width; - int height = revealBounds.height; - - double scale = 2.3d; - - double w = width * scale; - double h = height * scale; - - double minWidth = clientArea.width * 0.08d; - double minHeight = clientArea.height * 0.08d; - - if (w < minWidth || h < minHeight) { - double s1 = w < minWidth ? minWidth / width : scale; - double s2 = h < minHeight ? minHeight / height : scale; - scale = Math.max(s1, s2); - w = width * scale; - h = height * scale; - } - - double maxWidth = clientArea.width * 0.6d; - double maxHeight = clientArea.height * 0.6d; - if (w > maxWidth || h > maxHeight) { - double s1 = w > maxWidth ? maxWidth / width : scale; - double s2 = h > maxHeight ? maxHeight / height : scale; - scale = Math.min(s1, s2); - } - - cachedScale = scale; - return scale; - } - - protected PrecisionPoint calcTargetCenter(List toReveal, - Rectangle revealBounds, double targetScale) { - if (isCentered()) { - return new PrecisionPoint(revealBounds.getCenter()); - } else { - return calcLeastTargetCenter(toReveal, revealBounds, targetScale); - } - } - - /** - * @param toReveal - * @param revealBounds - * @param targetScale - * @return - */ - protected PrecisionPoint calcLeastTargetCenter( - List toReveal, Rectangle revealBounds, - double targetScale) { - Rectangle clientArea = getViewerClientArea(); - revealBounds.expand(getSpacing(), getSpacing()); - if (shouldReveal(revealBounds, clientArea)) { - int dx = 0; - int dy = 0; - int margin = 50; - int offsetH = clientArea.getBottom().y - clientArea.getCenter().y; - int offsetV = clientArea.getRight().x - clientArea.getCenter().x; - if (revealBounds.width > clientArea.width) - dx = revealBounds.x - clientArea.getCenter().x; - else if (revealBounds.x < clientArea.x) - dx = revealBounds.x + offsetV - margin - getSpacing(); - else if (revealBounds.right() > clientArea.right()) - dx = revealBounds.right() - offsetV + margin + getSpacing(); - - if (revealBounds.height > clientArea.height) - dy = revealBounds.y - clientArea.getCenter().y; - else if (revealBounds.y < clientArea.y) - dy = revealBounds.y + offsetH - margin - getSpacing(); - else if (revealBounds.bottom() > clientArea.bottom()) - dy = revealBounds.bottom() - offsetH + margin + getSpacing(); - return getViewerCenterPoint(getViewerScale()).translate(dx, dy); - } - return null; - } - - protected boolean shouldReveal(Rectangle revealBounds, - Rectangle clientArea) { - if (isShouldRevealOnIntersection()) { - return !clientArea.contains(revealBounds) - && !revealBounds.contains(clientArea); - } - return clientArea.bottom() < revealBounds.bottom() - || clientArea.getTop().y > revealBounds.y; - } - - protected Rectangle getViewerClientArea() { - Rectangle clientArea = getViewer().getClientArea(); - return getViewer().getZoomManager().getAntiScaled(clientArea); - } - - protected Rectangle getRevealBounds(List parts) { - Rectangle r = null; - for (IGraphicalPart p : parts) { - r = Geometry.union(r, getRevealBounds(p)); - } - return r; - } - - protected Rectangle getRevealBounds(IGraphicalPart p) { - return p.getFigure().getBounds(); - } - - protected double getViewerScale() { - return getViewer().getZoomManager().getScale(); - } - - protected PrecisionPoint getViewerCenterPoint(double scale) { - return new PrecisionPoint(getViewer().getCenterPoint()) - .scale(1 / scale); - } - - protected List collectPartsToReveal(ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - List list = new ArrayList( - ss.size()); - for (Object o : ss.toList()) { - IGraphicalPart p = getViewer().findGraphicalPart(o); - if (p != null && !exclude(p)) { - list.add(p); - } - } - return list; - } - return null; - } - - protected boolean exclude(IGraphicalPart part) { - return false; - } - - protected void finishCurrentJob() { - if (job != null) { - job.finish(); - job = null; - } - } - - protected void cancelCurrentJob() { - if (job != null) { - job.cancel(); - job = null; - } - } - - protected void revealJobFinished(List toReveal) { - -// Rectangle revealBounds = getRevealBounds(toReveal); -// if (revealBounds != null) { -// double targetScale = calcTargetScale(toReveal, revealBounds); -// PrecisionPoint targetCenter = calcTargetCenter(toReveal, -// revealBounds, targetScale); -// if (targetScale > 0) { -// getViewer().getZoomManager().setScale(targetScale); -// } -// if (targetCenter != null) { -// getViewer().center(targetCenter.getScaled(getViewerScale()) -// .toRoundedDraw2DPoint()); -// } -// } - revealingFinished(new RevealEvent(this, toReveal)); - } - - protected void doStep(List toReveal, Rectangle revealBounds, - int remainingSteps) { - double scale = getViewerScale(); - PrecisionPoint center = getViewerCenterPoint(scale); - double targetScale = calcTargetScale(toReveal, revealBounds); - PrecisionPoint targetCenter = calcTargetCenter(toReveal, revealBounds, - targetScale); - - if (targetScale > 0) { - double remainingScale = targetScale - scale; - double stepScale = remainingScale / remainingSteps; - scale += stepScale; - getViewer().getZoomManager().setScale(scale); - } - - if (targetCenter != null) { - double horizontalOffset = targetCenter.x - center.x; - double verticalOffset = targetCenter.y - center.y; - double stepX = horizontalOffset / remainingSteps; - double stepY = verticalOffset / remainingSteps; - center.x += stepX; - center.y += stepY; - getViewer().center(targetCenter.getScaled(getViewerScale()) - .toRoundedDraw2DPoint()); - } - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.service; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.part.IGraphicalPart; + +public abstract class ZoomingAndPanningRevealService extends BaseRevealService { + + private class RevealJob implements Runnable { + + private Display display; + + private List toReveal; + + private long startTime = -1; + + private boolean canceled = false; + + private int elapsedSteps = -1; + + public RevealJob(Display display, List toReveal) { + this.display = display; + this.toReveal = toReveal; + } + + public void cancel() { + boolean oldCanceled = this.canceled; + setCanceled(); + if (!oldCanceled) { + revealingCanceled(new RevealEvent( + ZoomingAndPanningRevealService.this, toReveal)); + } + } + + private void setCanceled() { + canceled = true; + } + + public void run() { + if (canceled) + return; + + Control control = getViewer().getControl(); + if (control == null || control.isDisposed()) { + setCanceled(); + return; + } + + if (!isAnimationEnabled()) { + finish(); + return; + } + + long currentTime = System.currentTimeMillis(); + if (startTime < 0) + startTime = currentTime; + + int elapsedTime = (int) (currentTime - startTime); + int remainingTime = getDuration() - elapsedTime; + if (remainingTime <= 0) { + finish(); + return; + } + + double intervals = INTERVALS; + if (elapsedSteps < 0) { + elapsedSteps = 0; + intervals += 10; + } else { + intervals += (((double) (currentTime - startTime + - INTERVALS * elapsedSteps)) / elapsedSteps); + } + + int remainingSteps = (int) ((remainingTime + intervals - 1) + / intervals); + if (remainingSteps <= 0) { + finish(); + return; + } + + Rectangle revealBounds = getRevealBounds(toReveal); + if (revealBounds == null) { + cancel(); + return; + } + + doStep(toReveal, revealBounds, remainingSteps); + + display.timerExec(INTERVALS, this); + elapsedSteps++; + } + + public void finish() { + setCanceled(); + revealJobFinished(toReveal); + } + + } + + private static final int INTERVALS = 20; + + private int duration = 200; + + private int delay = 100; + + private RevealJob job = null; + + private double cachedScale = -1; + + private boolean centered = false; + + private int spacing = 20; + + private boolean zoomed = false; + + private boolean animationEnabled = true; + + private boolean shouldRevealOnIntersection = true; + + protected ZoomingAndPanningRevealService(IGraphicalViewer viewer) { + super(viewer); + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int getDelay() { + return delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public void setCentered(boolean centered) { + this.centered = centered; + } + + public boolean isCentered() { + return this.centered; + } + + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + public int getSpacing() { + return this.spacing; + } + + /** + * @param zoomed + * the zoomed to set + */ + public void setZoomed(boolean zoomed) { + this.zoomed = zoomed; + } + + public void setShouldRevealOnIntersection(boolean should) { + this.shouldRevealOnIntersection = should; + } + + public boolean isShouldRevealOnIntersection() { + return shouldRevealOnIntersection; + } + + /** + * @return the zoomed + */ + public boolean isZoomed() { + return this.zoomed; + } + + public void setAnimationEnabled(boolean animationEnabled) { + this.animationEnabled = animationEnabled; + } + + protected boolean isAnimationEnabled() { + return animationEnabled; + } + + protected void activate() { + } + + protected void deactivate() { + } + + public void reveal(ISelection selection) { + if (!isActive()) + return; + + startReveal(selection); + } + + protected void startReveal(ISelection selection) { + if (job != null) { + job.cancel(); + job = null; + } + cachedScale = -1; + + List toReveal = collectPartsToReveal(selection); + if (toReveal != null && shouldReveal(toReveal)) { + Display display = Display.getCurrent(); + job = new RevealJob(display, toReveal); + display.timerExec(delay, job); + revealingStarted(new RevealEvent(this, toReveal)); + } + } + + protected boolean shouldReveal(List toReveal) { + return !toReveal.isEmpty(); + } + + protected double calcTargetScale(List toReveal, + Rectangle revealBounds) { + if (!isZoomed()) + return -1; + + if (cachedScale > 0) + return cachedScale; + + Rectangle clientArea = getViewer().getClientArea(); + int width = revealBounds.width; + int height = revealBounds.height; + + double scale = 2.3d; + + double w = width * scale; + double h = height * scale; + + double minWidth = clientArea.width * 0.08d; + double minHeight = clientArea.height * 0.08d; + + if (w < minWidth || h < minHeight) { + double s1 = w < minWidth ? minWidth / width : scale; + double s2 = h < minHeight ? minHeight / height : scale; + scale = Math.max(s1, s2); + w = width * scale; + h = height * scale; + } + + double maxWidth = clientArea.width * 0.6d; + double maxHeight = clientArea.height * 0.6d; + if (w > maxWidth || h > maxHeight) { + double s1 = w > maxWidth ? maxWidth / width : scale; + double s2 = h > maxHeight ? maxHeight / height : scale; + scale = Math.min(s1, s2); + } + + cachedScale = scale; + return scale; + } + + protected PrecisionPoint calcTargetCenter(List toReveal, + Rectangle revealBounds, double targetScale) { + if (isCentered()) { + return new PrecisionPoint(revealBounds.getCenter()); + } else { + return calcLeastTargetCenter(toReveal, revealBounds, targetScale); + } + } + + /** + * @param toReveal + * @param revealBounds + * @param targetScale + * @return + */ + protected PrecisionPoint calcLeastTargetCenter( + List toReveal, Rectangle revealBounds, + double targetScale) { + + Rectangle clientArea = getViewerClientArea(); + revealBounds.expand(getSpacing(), getSpacing()); + if (shouldReveal(revealBounds, clientArea)) { + int dx = 0; + int dy = 0; + int margin = 50; + int offsetH = clientArea.width >> 1; + int offsetV = clientArea.height >> 1; + + if (revealBounds.x < clientArea.x) { + dx = revealBounds.x + offsetH - margin - getSpacing(); + } else if (revealBounds.right() > clientArea.right()) { + dx = revealBounds.right() - offsetH + margin + getSpacing(); + } + + if (revealBounds.y < clientArea.y) { + dy = revealBounds.y + offsetV - margin - getSpacing(); + } else if (revealBounds.bottom() > clientArea.bottom()) { + dy = revealBounds.bottom() - offsetV + margin + getSpacing(); + } + + dx = (int) (dx == 0 ? getViewerCenterPoint(getViewerScale()).x + : dx); + dy = (int) (dy == 0 ? getViewerCenterPoint(getViewerScale()).y + : dy); + + return getViewerCenterPoint(getViewerScale()).translate(dx, dy); + } + return null; + } + + protected boolean shouldReveal(Rectangle revealBounds, + Rectangle clientArea) { + if (isShouldRevealOnIntersection()) { + return !clientArea.contains(revealBounds) + && !revealBounds.contains(clientArea); + } + return clientArea.bottom() < revealBounds.bottom() + || clientArea.getTop().y > revealBounds.y + || clientArea.right() < revealBounds.right() + || clientArea.getLeft().x > revealBounds.x; + } + + protected Rectangle getViewerClientArea() { + Rectangle clientArea = getViewer().getClientArea(); + return getViewer().getZoomManager().getAntiScaled(clientArea); + } + + protected Rectangle getRevealBounds(List parts) { + Rectangle r = null; + for (IGraphicalPart p : parts) { + r = Geometry.union(r, getRevealBounds(p)); + } + return r; + } + + protected Rectangle getRevealBounds(IGraphicalPart p) { + return p.getFigure().getBounds(); + } + + protected double getViewerScale() { + return getViewer().getZoomManager().getScale(); + } + + protected PrecisionPoint getViewerCenterPoint(double scale) { + return new PrecisionPoint(getViewer().getCenterPoint()) + .scale(1 / scale); + } + + protected List collectPartsToReveal(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + List list = new ArrayList( + ss.size()); + for (Object o : ss.toList()) { + IGraphicalPart p = getViewer().findGraphicalPart(o); + if (p != null && !exclude(p)) { + list.add(p); + } + } + return list; + } + return null; + } + + protected boolean exclude(IGraphicalPart part) { + return false; + } + + protected void finishCurrentJob() { + if (job != null) { + job.finish(); + job = null; + } + } + + protected void cancelCurrentJob() { + if (job != null) { + job.cancel(); + job = null; + } + } + + protected void revealJobFinished(List toReveal) { + + Rectangle revealBounds = getRevealBounds(toReveal); + if (revealBounds != null) { + double targetScale = calcTargetScale(toReveal, revealBounds); + PrecisionPoint targetCenter = calcTargetCenter(toReveal, + revealBounds, targetScale); + if (targetScale > 0) { + getViewer().getZoomManager().setScale(targetScale); + } + if (targetCenter != null) { + getViewer().center(targetCenter.getScaled(getViewerScale()) + .toRoundedDraw2DPoint()); + } + } + revealingFinished(new RevealEvent(this, toReveal)); + } + + protected void doStep(List toReveal, Rectangle revealBounds, + int remainingSteps) { + double scale = getViewerScale(); + PrecisionPoint center = getViewerCenterPoint(scale); + double targetScale = calcTargetScale(toReveal, revealBounds); + PrecisionPoint targetCenter = calcTargetCenter(toReveal, revealBounds, + targetScale); + + if (targetScale > 0) { + double remainingScale = targetScale - scale; + double stepScale = remainingScale / remainingSteps; + scale += stepScale; + getViewer().getZoomManager().setScale(scale); + } + if (targetCenter != null) { + double horizontalOffset = targetCenter.x - center.x; + double verticalOffset = targetCenter.y - center.y; + double stepX = horizontalOffset / remainingSteps; + double stepY = verticalOffset / remainingSteps; + center.x += stepX; + center.y += stepY; + getViewer().center(targetCenter.getScaled(getViewerScale()) + .toRoundedDraw2DPoint()); + } + } +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/status/IStatusListener.java b/bundles/org.xmind.gef/src/org/xmind/gef/status/IStatusListener.java index 1a0f977a2..561acbab9 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/status/IStatusListener.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/status/IStatusListener.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.status; - - -/** - * @author Brian Sun - */ -public interface IStatusListener { - - public void statusChanged( StatusEvent event ); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.status; + + +/** + * @author Brian Sun + */ +public interface IStatusListener { + + public void statusChanged( StatusEvent event ); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/AbstractTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/AbstractTool.java index 676975bdb..eb7334982 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/AbstractTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/AbstractTool.java @@ -1,589 +1,589 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import static org.xmind.gef.GEF.ST_ACTIVE; -import static org.xmind.gef.GEF.ST_ALT_PRESSED; -import static org.xmind.gef.GEF.ST_CONTROL_PRESSED; -import static org.xmind.gef.GEF.ST_SHIFT_PRESSED; - -import java.util.List; - -import org.eclipse.swt.SWT; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.event.DragDropEvent; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.event.MouseDragEvent; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.event.MouseWheelEvent; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.status.IStatusMachine; -import org.xmind.gef.status.StatusMachine2; - -/** - * @author Brian Sun - */ -public abstract class AbstractTool implements ITool, IDragDropHandler { - -// private String type; - - private EditDomain domain = null; - - private IStatusMachine statusMachine = null; - - private String contextId = null; - -// private IViewer targetViewer = null; - -// private List requestQueue = new ArrayList(5); -// -// private boolean handlingQueue = false; - -// public void setType(String type) { -// this.type = type; -// } -// -// public String getType() { -// return type; -// } - - /** - * @return the contextId - */ - public String getContextId() { - return contextId; - } - - /** - * @param contextId - * the contextId to set - */ - public void setContextId(String contextId) { - this.contextId = contextId; - } - - public EditDomain getDomain() { - return domain; - } - - public void setDomain(EditDomain domain) { - this.domain = domain; - } - - public IViewer getTargetViewer() { -// if (targetViewer == null) { -// targetViewer = getDomain().getViewer(); -// } - return getDomain().getTargetViewer(); - } - - public void setTargetViewer(IViewer viewer) { - getDomain().setTargetViewer(viewer); - } - - /** - * IMPORTANT: this method is not intended to be subclassed and - * should only be called by EditDomain. Clients may extend the protected - * method {@link #onActivated(ITool)} instead. - * - * @see org.xmind.gef.tool.ITool#activate(ITool) - */ - public final void activate(ITool prevTool) { - if (getStatus().isStatus(ST_ACTIVE)) - return; - - getStatus().setStatus(ST_ACTIVE, true); - onActivated(prevTool); - } - - /** - * IMPORTANT: this method is not intended to be subclassed and - * should only be called by EditDomain. Clients may extend the protected - * method {@link #onDeactivated(ITool)} instead. - * - * @see org.xmind.gef.tool.ITool#deactivate(ITool) - */ - public final void deactivate(ITool nextTool) { - if (!getStatus().isStatus(ST_ACTIVE)) - return; - - getStatus().setStatus(ST_ACTIVE, false); - onDeactivated(nextTool); - } - - /** - * This method is called after the activation of this tool and may by - * extended clients. - * - * @param prevTool - */ - protected void onActivated(ITool prevTool) { - } - - /** - * This method is called after the deactivation of this tool and may by - * extended by clients. - * - * @param nextTool - */ - protected void onDeactivated(ITool nextTool) { - if (nextTool != null) { - copyStatus(nextTool); - } - } - - /** - * @param next - */ - protected ITool copyStatus(ITool next) { - if (next instanceof AbstractTool) { - IStatusMachine nextStatus = ((AbstractTool) next).getStatus(); - IStatusMachine status = getStatus(); - copyStatus(ST_CONTROL_PRESSED, status, nextStatus); - copyStatus(ST_SHIFT_PRESSED, status, nextStatus); - copyStatus(ST_ALT_PRESSED, status, nextStatus); - ((AbstractTool) next).setTargetViewer(getTargetViewer()); - } - return next; - } - - /** - * @return the statusMachine - */ - public IStatusMachine getStatus() { - if (statusMachine == null) { - statusMachine = new StatusMachine2(); - } - return statusMachine; - } - - /** - * @param key - * @param fromStatus - * @param toStatus - */ - private void copyStatus(int key, IStatusMachine fromStatus, - IStatusMachine toStatus) { - toStatus.setStatus(key, fromStatus.isStatus(key)); - } - - public ITool changeActiveTool(String toolType) { - domain.setActiveTool(toolType); - return domain.getActiveTool(); - } - - protected ITool getTool(String toolType) { - return domain.getTool(toolType); - } - - /** - * @see org.xmind.gef.tool.ITool#focusGained() - */ - public void focusGained(IViewer viewer) { - setTargetViewer(viewer); - handleFocusGained(); - } - - protected boolean handleFocusGained() { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#focusLost() - */ - public void focusLost(IViewer viewer) { - setTargetViewer(viewer); - handleFocusLost(); - } - - protected boolean handleFocusLost() { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#keyDown(org.xmind.gef.event.KeyEvent) - */ - public void keyDown(KeyEvent ke, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(ke, true); - handleKeyDown(ke); - } - - protected boolean handleKeyDown(KeyEvent ke) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#keyUp(org.xmind.gef.event.KeyEvent) - */ - public void keyUp(KeyEvent ke, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(ke, false); - handleKeyUp(ke); - } - - protected boolean handleKeyUp(KeyEvent ke) { - return false; - } - - protected void captureModifier(KeyEvent ke, boolean pressed) { - if ((ke.keyCode & SWT.MOD1) != 0) - getStatus().setStatus(ST_CONTROL_PRESSED, pressed); - if ((ke.keyCode & SWT.MOD2) != 0) - getStatus().setStatus(ST_SHIFT_PRESSED, pressed); - if ((ke.keyCode & SWT.MOD3) != 0) - getStatus().setStatus(ST_ALT_PRESSED, pressed); - } - - protected void captureModifier(MouseEvent me) { - getStatus().setStatus(ST_CONTROL_PRESSED, me.isState(SWT.MOD1)); - getStatus().setStatus(ST_SHIFT_PRESSED, me.isState(SWT.MOD2)); - getStatus().setStatus(ST_ALT_PRESSED, me.isState(SWT.MOD3)); - } - - /** - * @see org.xmind.gef.tool.ITool#keyTraversed(org.xmind.gef.event.KeyEvent) - */ - public void keyTraversed(KeyEvent ke, IViewer viewer) { - setTargetViewer(viewer); - handleKeyTraversed(ke); - } - - protected boolean handleKeyTraversed(KeyEvent ke) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseDoubleClick(org.xmind.gef.event.MouseEvent) - */ - public void mouseDoubleClick(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseDoubleClick(me); - } - - protected boolean handleMouseDoubleClick(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseDown(org.xmind.gef.event.MouseEvent) - */ - public void mouseDown(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseDown(me); - } - - protected boolean handleMouseDown(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseLongPressed(org.xmind.gef.event.MouseEvent) - */ - public void mouseLongPressed(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleLongPressed(me); - } - - protected boolean handleLongPressed(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseDrag(org.xmind.gef.event.MouseEvent) - */ - public void mouseDrag(MouseDragEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseDrag(me); - } - - protected boolean handleMouseDrag(MouseDragEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseHover(org.xmind.gef.event.MouseEvent) - */ - public void mouseHover(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseHover(me); - } - - protected boolean handleMouseHover(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseMove(org.xmind.gef.event.MouseEvent) - */ - public void mouseMove(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseMove(me); - } - - protected boolean handleMouseMove(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseUp(org.xmind.gef.event.MouseEvent) - */ - public void mouseUp(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseUp(me); - } - - protected boolean handleMouseUp(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseEntered(org.xmind.gef.event.MouseEvent) - */ - public void mouseEntered(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseEntered(me); - } - - protected boolean handleMouseEntered(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseExited(org.xmind.gef.event.MouseEvent) - */ - public void mouseExited(MouseEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleMouseExited(me); - } - - protected boolean handleMouseExited(MouseEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.ITool#mouseWheelScrolled(org.xmind.gef.event.MouseWheelEvent) - */ - public void mouseWheelScrolled(MouseWheelEvent me, IViewer viewer) { - setTargetViewer(viewer); - captureModifier(me); - handleWheelScrolled(me); - } - - protected boolean handleWheelScrolled(MouseWheelEvent me) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#dragEntered(org.xmind.gef.event.DragDropEvent) - */ - public void dragEntered(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragEntered(de); - } - - protected boolean handleDragEntered(DragDropEvent de) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#dragExited(org.xmind.gef.event.DragDropEvent) - */ - public void dragExited(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragExited(de); - } - - protected boolean handleDragExited(DragDropEvent de) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#dragOver(org.xmind.gef.event.DragDropEvent) - */ - public void dragOver(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragOver(de); - } - - protected boolean handleDragOver(DragDropEvent de) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#dragOperationChanged(org.xmind.gef.event.DragDropEvent) - */ - public void dragOperationChanged(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragOperationChanged(de); - } - - protected boolean handleDragOperationChanged(DragDropEvent de) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#drop(org.xmind.gef.event.DragDropEvent) - */ - public void drop(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDrop(de); - } - - protected boolean handleDrop(DragDropEvent de) { - return false; - } - - /** - * @see org.xmind.gef.tool.IDragDropHandler#dropAccept(org.xmind.gef.event.DragDropEvent) - */ - public void dropAccept(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDropAccept(de); - } - - protected boolean handleDropAccept(DragDropEvent de) { - return false; - } - - public void dragDismissed(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragDismissed(de); - } - - protected boolean handleDragDismissed(DragDropEvent de) { - return false; - } - - public void dragStarted(DragDropEvent de, IViewer viewer) { - setTargetViewer(viewer); - handleDragStarted(de); - } - - protected boolean handleDragStarted(DragDropEvent de) { - return false; - } - - /** - * @deprecated see {@link ITool#handleRequest(String, IViewer)} - */ - public final void handleRequest(String requestType, IViewer targetViewer) { -// setTargetViewer(targetViewer); -// Request request = new Request(requestType); -// request.setViewer(targetViewer); -// handleRequest(request); - getDomain().handleRequest(requestType, targetViewer); - } - - /** - * @see org.xmind.gef.tool.ITool#handleRequest(org.xmind.gef.Request) - */ - public final void handleRequest(Request request) { - setTargetViewer(request.getTargetViewer()); - internalHandleRequest(request); - } - - protected void internalHandleRequest(Request request) { - if (request.hasTargets()) { - handleTargetedRequest(request); - } else { - handleNonTargetedRequest(request); - } - } - -// protected final void handleSingleRequest(Request request) { -// if (request.getTargetViewer() == null) { -// request.setViewer(getTargetViewer()); -// } -// if (request.getTargetDomain() == null) { -// request.setDomain(getDomain()); -// } -// } - - protected void handleTargetedRequest(Request request) { - IPart target = request.getPrimaryTarget(); - String role = getDomain().getPartRoles().getRole(request.getType()); - if (target == null || target instanceof IRootPart) { - if (role != null) { - target = findPartByRole(role, target == null ? request - .getTargetViewer().getRootPart() : target); - } - } - if (target != null) { - target.handleRequest(request, role); - } - } - - protected void handleNonTargetedRequest(Request request) { - String type = request.getType(); - String role = getDomain().getPartRoles().getRole(type); - if (role != null) { - IPart part = findPartByRole(role, request.getTargetViewer() - .getRootPart()); - if (part != null && part.hasRole(role)) { - part.handleRequest(request, role); - } - } - } - - protected IPart findPartByRole(String role, IPart parent) { - for (IPart p : parent.getChildren()) { - if (p.hasRole(role)) - return p; - IPart child = findPartByRole(role, p); - if (child != null) - return child; - } - return null; - } - - protected Request createTargetedRequest(String type, IViewer viewer, - boolean includeRootPartIfEmpty) { - return fillTargets( - new Request(type).setViewer(viewer).setDomain(getDomain()), - viewer, includeRootPartIfEmpty); - } - - protected Request fillTargets(Request request, IViewer viewer, - boolean includeRootPartIfEmpty) { - List parts = getSelectedParts(viewer); - if (parts.isEmpty()) { - if (includeRootPartIfEmpty) - request.setPrimaryTarget(viewer.getRootPart()); - } else { - request.setTargets(parts); -// IPart focusedPart = viewer.getFocusedPart(); -// if (parts.contains(focusedPart)) -// request.setPrimaryTarget(focusedPart); - } - return request; - } - - protected List getSelectedParts(IViewer viewer) { - return viewer.getSelectionSupport().getPartSelection(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import static org.xmind.gef.GEF.ST_ACTIVE; +import static org.xmind.gef.GEF.ST_ALT_PRESSED; +import static org.xmind.gef.GEF.ST_CONTROL_PRESSED; +import static org.xmind.gef.GEF.ST_SHIFT_PRESSED; + +import java.util.List; + +import org.eclipse.swt.SWT; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.event.DragDropEvent; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.event.MouseDragEvent; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.event.MouseWheelEvent; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.status.IStatusMachine; +import org.xmind.gef.status.StatusMachine2; + +/** + * @author Brian Sun + */ +public abstract class AbstractTool implements ITool, IDragDropHandler { + +// private String type; + + private EditDomain domain = null; + + private IStatusMachine statusMachine = null; + + private String contextId = null; + +// private IViewer targetViewer = null; + +// private List requestQueue = new ArrayList(5); +// +// private boolean handlingQueue = false; + +// public void setType(String type) { +// this.type = type; +// } +// +// public String getType() { +// return type; +// } + + /** + * @return the contextId + */ + public String getContextId() { + return contextId; + } + + /** + * @param contextId + * the contextId to set + */ + public void setContextId(String contextId) { + this.contextId = contextId; + } + + public EditDomain getDomain() { + return domain; + } + + public void setDomain(EditDomain domain) { + this.domain = domain; + } + + public IViewer getTargetViewer() { +// if (targetViewer == null) { +// targetViewer = getDomain().getViewer(); +// } + return getDomain().getTargetViewer(); + } + + public void setTargetViewer(IViewer viewer) { + getDomain().setTargetViewer(viewer); + } + + /** + * IMPORTANT: this method is not intended to be subclassed and + * should only be called by EditDomain. Clients may extend the protected + * method {@link #onActivated(ITool)} instead. + * + * @see org.xmind.gef.tool.ITool#activate(ITool) + */ + public final void activate(ITool prevTool) { + if (getStatus().isStatus(ST_ACTIVE)) + return; + + getStatus().setStatus(ST_ACTIVE, true); + onActivated(prevTool); + } + + /** + * IMPORTANT: this method is not intended to be subclassed and + * should only be called by EditDomain. Clients may extend the protected + * method {@link #onDeactivated(ITool)} instead. + * + * @see org.xmind.gef.tool.ITool#deactivate(ITool) + */ + public final void deactivate(ITool nextTool) { + if (!getStatus().isStatus(ST_ACTIVE)) + return; + + getStatus().setStatus(ST_ACTIVE, false); + onDeactivated(nextTool); + } + + /** + * This method is called after the activation of this tool and may by + * extended clients. + * + * @param prevTool + */ + protected void onActivated(ITool prevTool) { + } + + /** + * This method is called after the deactivation of this tool and may by + * extended by clients. + * + * @param nextTool + */ + protected void onDeactivated(ITool nextTool) { + if (nextTool != null) { + copyStatus(nextTool); + } + } + + /** + * @param next + */ + protected ITool copyStatus(ITool next) { + if (next instanceof AbstractTool) { + IStatusMachine nextStatus = ((AbstractTool) next).getStatus(); + IStatusMachine status = getStatus(); + copyStatus(ST_CONTROL_PRESSED, status, nextStatus); + copyStatus(ST_SHIFT_PRESSED, status, nextStatus); + copyStatus(ST_ALT_PRESSED, status, nextStatus); + ((AbstractTool) next).setTargetViewer(getTargetViewer()); + } + return next; + } + + /** + * @return the statusMachine + */ + public IStatusMachine getStatus() { + if (statusMachine == null) { + statusMachine = new StatusMachine2(); + } + return statusMachine; + } + + /** + * @param key + * @param fromStatus + * @param toStatus + */ + private void copyStatus(int key, IStatusMachine fromStatus, + IStatusMachine toStatus) { + toStatus.setStatus(key, fromStatus.isStatus(key)); + } + + public ITool changeActiveTool(String toolType) { + domain.setActiveTool(toolType); + return domain.getActiveTool(); + } + + protected ITool getTool(String toolType) { + return domain.getTool(toolType); + } + + /** + * @see org.xmind.gef.tool.ITool#focusGained() + */ + public void focusGained(IViewer viewer) { + setTargetViewer(viewer); + handleFocusGained(); + } + + protected boolean handleFocusGained() { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#focusLost() + */ + public void focusLost(IViewer viewer) { + setTargetViewer(viewer); + handleFocusLost(); + } + + protected boolean handleFocusLost() { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#keyDown(org.xmind.gef.event.KeyEvent) + */ + public void keyDown(KeyEvent ke, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(ke, true); + handleKeyDown(ke); + } + + protected boolean handleKeyDown(KeyEvent ke) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#keyUp(org.xmind.gef.event.KeyEvent) + */ + public void keyUp(KeyEvent ke, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(ke, false); + handleKeyUp(ke); + } + + protected boolean handleKeyUp(KeyEvent ke) { + return false; + } + + protected void captureModifier(KeyEvent ke, boolean pressed) { + if ((ke.keyCode & SWT.MOD1) != 0) + getStatus().setStatus(ST_CONTROL_PRESSED, pressed); + if ((ke.keyCode & SWT.MOD2) != 0) + getStatus().setStatus(ST_SHIFT_PRESSED, pressed); + if ((ke.keyCode & SWT.MOD3) != 0) + getStatus().setStatus(ST_ALT_PRESSED, pressed); + } + + protected void captureModifier(MouseEvent me) { + getStatus().setStatus(ST_CONTROL_PRESSED, me.isState(SWT.MOD1)); + getStatus().setStatus(ST_SHIFT_PRESSED, me.isState(SWT.MOD2)); + getStatus().setStatus(ST_ALT_PRESSED, me.isState(SWT.MOD3)); + } + + /** + * @see org.xmind.gef.tool.ITool#keyTraversed(org.xmind.gef.event.KeyEvent) + */ + public void keyTraversed(KeyEvent ke, IViewer viewer) { + setTargetViewer(viewer); + handleKeyTraversed(ke); + } + + protected boolean handleKeyTraversed(KeyEvent ke) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseDoubleClick(org.xmind.gef.event.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseDoubleClick(me); + } + + protected boolean handleMouseDoubleClick(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseDown(org.xmind.gef.event.MouseEvent) + */ + public void mouseDown(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseDown(me); + } + + protected boolean handleMouseDown(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseLongPressed(org.xmind.gef.event.MouseEvent) + */ + public void mouseLongPressed(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleLongPressed(me); + } + + protected boolean handleLongPressed(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseDrag(org.xmind.gef.event.MouseEvent) + */ + public void mouseDrag(MouseDragEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseDrag(me); + } + + protected boolean handleMouseDrag(MouseDragEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseHover(org.xmind.gef.event.MouseEvent) + */ + public void mouseHover(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseHover(me); + } + + protected boolean handleMouseHover(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseMove(org.xmind.gef.event.MouseEvent) + */ + public void mouseMove(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseMove(me); + } + + protected boolean handleMouseMove(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseUp(org.xmind.gef.event.MouseEvent) + */ + public void mouseUp(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseUp(me); + } + + protected boolean handleMouseUp(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseEntered(org.xmind.gef.event.MouseEvent) + */ + public void mouseEntered(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseEntered(me); + } + + protected boolean handleMouseEntered(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseExited(org.xmind.gef.event.MouseEvent) + */ + public void mouseExited(MouseEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleMouseExited(me); + } + + protected boolean handleMouseExited(MouseEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.ITool#mouseWheelScrolled(org.xmind.gef.event.MouseWheelEvent) + */ + public void mouseWheelScrolled(MouseWheelEvent me, IViewer viewer) { + setTargetViewer(viewer); + captureModifier(me); + handleWheelScrolled(me); + } + + protected boolean handleWheelScrolled(MouseWheelEvent me) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#dragEntered(org.xmind.gef.event.DragDropEvent) + */ + public void dragEntered(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragEntered(de); + } + + protected boolean handleDragEntered(DragDropEvent de) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#dragExited(org.xmind.gef.event.DragDropEvent) + */ + public void dragExited(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragExited(de); + } + + protected boolean handleDragExited(DragDropEvent de) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#dragOver(org.xmind.gef.event.DragDropEvent) + */ + public void dragOver(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragOver(de); + } + + protected boolean handleDragOver(DragDropEvent de) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#dragOperationChanged(org.xmind.gef.event.DragDropEvent) + */ + public void dragOperationChanged(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragOperationChanged(de); + } + + protected boolean handleDragOperationChanged(DragDropEvent de) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#drop(org.xmind.gef.event.DragDropEvent) + */ + public void drop(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDrop(de); + } + + protected boolean handleDrop(DragDropEvent de) { + return false; + } + + /** + * @see org.xmind.gef.tool.IDragDropHandler#dropAccept(org.xmind.gef.event.DragDropEvent) + */ + public void dropAccept(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDropAccept(de); + } + + protected boolean handleDropAccept(DragDropEvent de) { + return false; + } + + public void dragDismissed(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragDismissed(de); + } + + protected boolean handleDragDismissed(DragDropEvent de) { + return false; + } + + public void dragStarted(DragDropEvent de, IViewer viewer) { + setTargetViewer(viewer); + handleDragStarted(de); + } + + protected boolean handleDragStarted(DragDropEvent de) { + return false; + } + + /** + * @deprecated see {@link ITool#handleRequest(String, IViewer)} + */ + public final void handleRequest(String requestType, IViewer targetViewer) { +// setTargetViewer(targetViewer); +// Request request = new Request(requestType); +// request.setViewer(targetViewer); +// handleRequest(request); + getDomain().handleRequest(requestType, targetViewer); + } + + /** + * @see org.xmind.gef.tool.ITool#handleRequest(org.xmind.gef.Request) + */ + public final void handleRequest(Request request) { + setTargetViewer(request.getTargetViewer()); + internalHandleRequest(request); + } + + protected void internalHandleRequest(Request request) { + if (request.hasTargets()) { + handleTargetedRequest(request); + } else { + handleNonTargetedRequest(request); + } + } + +// protected final void handleSingleRequest(Request request) { +// if (request.getTargetViewer() == null) { +// request.setViewer(getTargetViewer()); +// } +// if (request.getTargetDomain() == null) { +// request.setDomain(getDomain()); +// } +// } + + protected void handleTargetedRequest(Request request) { + IPart target = request.getPrimaryTarget(); + String role = getDomain().getPartRoles().getRole(request.getType()); + if (target == null || target instanceof IRootPart) { + if (role != null) { + target = findPartByRole(role, target == null ? request + .getTargetViewer().getRootPart() : target); + } + } + if (target != null) { + target.handleRequest(request, role); + } + } + + protected void handleNonTargetedRequest(Request request) { + String type = request.getType(); + String role = getDomain().getPartRoles().getRole(type); + if (role != null) { + IPart part = findPartByRole(role, request.getTargetViewer() + .getRootPart()); + if (part != null && part.hasRole(role)) { + part.handleRequest(request, role); + } + } + } + + protected IPart findPartByRole(String role, IPart parent) { + for (IPart p : parent.getChildren()) { + if (p.hasRole(role)) + return p; + IPart child = findPartByRole(role, p); + if (child != null) + return child; + } + return null; + } + + protected Request createTargetedRequest(String type, IViewer viewer, + boolean includeRootPartIfEmpty) { + return fillTargets( + new Request(type).setViewer(viewer).setDomain(getDomain()), + viewer, includeRootPartIfEmpty); + } + + protected Request fillTargets(Request request, IViewer viewer, + boolean includeRootPartIfEmpty) { + List parts = getSelectedParts(viewer); + if (parts.isEmpty()) { + if (includeRootPartIfEmpty) + request.setPrimaryTarget(viewer.getRootPart()); + } else { + request.setTargets(parts); +// IPart focusedPart = viewer.getFocusedPart(); +// if (parts.contains(focusedPart)) +// request.setPrimaryTarget(focusedPart); + } + return request; + } + + protected List getSelectedParts(IViewer viewer) { + return viewer.getSelectionSupport().getPartSelection(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/BrowsingTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/BrowsingTool.java index 57466f7af..d9e2e2e04 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/BrowsingTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/BrowsingTool.java @@ -1,120 +1,120 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import org.eclipse.draw2d.Cursors; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Menu; -import org.xmind.gef.IViewer; -import org.xmind.gef.event.MouseDragEvent; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - * @version 2005 - */ -public class BrowsingTool extends DraggingTool { - - private static final Point SCROLL_POSITION = new Point(); - - private Point startScrollPosition = null; - - private boolean hidePopupMenu = false; - -// private Menu preservedMenu = null; -// -// private Control menuOwner = null; - - protected void start() { - startScrollPosition = new Point(getTargetViewer().getScrollPosition()); - } - - protected void end() { - } - - /** - * @see org.xmind.gef.tool.GraphicalTool#getCurrentCursor(org.eclipse.draw2d.geometry.Point, - * IPart) - */ - @Override - public Cursor getCurrentCursor(Point pos, IPart host) { - return Cursors.HAND; - } - - public void mouseDrag(MouseDragEvent me, IViewer viewer) { - super.mouseDrag(me, viewer); - if (!me.leftOrRight) { - if (!hidePopupMenu) - hidePopupMenu = true; - } - } - - public void mouseUp(MouseEvent me, IViewer viewer) { - super.mouseUp(me, viewer); - if (hidePopupMenu) { - Control control = viewer.getControl(); - if (control != null && !control.isDisposed()) { - Menu menu = control.getMenu(); - if (menu != null && !menu.isDisposed()) { - menu.setVisible(false); - } - } - } - hidePopupMenu = false; -// if (preservedMenu != null && !preservedMenu.isDisposed() -// && menuOwner != null && !menuOwner.isDisposed()) { -// menuOwner.getMenu().setVisible(false); -// menuOwner.setMenu(preservedMenu); -// } -// menuOwner = null; -// preservedMenu = null; -// if (!me.leftOrRight && preservedMenu != null && menuOwner != null) { -// Display.getCurrent().asyncExec(new Runnable() { -// public void run() { -// if (preservedMenu != null && !preservedMenu.isDisposed() -// && menuOwner != null && !menuOwner.isDisposed()) { -// menuOwner.setMenu(preservedMenu); -// } -// menuOwner = null; -// preservedMenu = null; -// } -// }); -// } else { -// preservedMenu = null; -// menuOwner = null; -// } - } - -// protected boolean handleMouseUp(MouseEvent me) { -// boolean ret = super.handleMouseUp(me); -//// ITool currentTool = getDomain().getActiveTool(); -//// if (!me.leftOrRight && currentTool instanceof AbstractTool) { -//// ((AbstractTool) currentTool).getStatus().setStatus( -//// GEF.ST_HIDE_CMENU, true); -//// } -// return ret; -// } - - protected void onDragging(Point cursorPosition, MouseDragEvent me) { - if (startScrollPosition != null) { - SCROLL_POSITION.setLocation(startScrollPosition); - SCROLL_POSITION.translate(me.getSWTDisplacement().negate()); - getTargetViewer().scrollTo(SCROLL_POSITION); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import org.eclipse.draw2d.Cursors; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.xmind.gef.IViewer; +import org.xmind.gef.event.MouseDragEvent; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + * @version 2005 + */ +public class BrowsingTool extends DraggingTool { + + private static final Point SCROLL_POSITION = new Point(); + + private Point startScrollPosition = null; + + private boolean hidePopupMenu = false; + +// private Menu preservedMenu = null; +// +// private Control menuOwner = null; + + protected void start() { + startScrollPosition = new Point(getTargetViewer().getScrollPosition()); + } + + protected void end() { + } + + /** + * @see org.xmind.gef.tool.GraphicalTool#getCurrentCursor(org.eclipse.draw2d.geometry.Point, + * IPart) + */ + @Override + public Cursor getCurrentCursor(Point pos, IPart host) { + return Cursors.HAND; + } + + public void mouseDrag(MouseDragEvent me, IViewer viewer) { + super.mouseDrag(me, viewer); + if (!me.leftOrRight) { + if (!hidePopupMenu) + hidePopupMenu = true; + } + } + + public void mouseUp(MouseEvent me, IViewer viewer) { + super.mouseUp(me, viewer); + if (hidePopupMenu) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + Menu menu = control.getMenu(); + if (menu != null && !menu.isDisposed()) { + menu.setVisible(false); + } + } + } + hidePopupMenu = false; +// if (preservedMenu != null && !preservedMenu.isDisposed() +// && menuOwner != null && !menuOwner.isDisposed()) { +// menuOwner.getMenu().setVisible(false); +// menuOwner.setMenu(preservedMenu); +// } +// menuOwner = null; +// preservedMenu = null; +// if (!me.leftOrRight && preservedMenu != null && menuOwner != null) { +// Display.getCurrent().asyncExec(new Runnable() { +// public void run() { +// if (preservedMenu != null && !preservedMenu.isDisposed() +// && menuOwner != null && !menuOwner.isDisposed()) { +// menuOwner.setMenu(preservedMenu); +// } +// menuOwner = null; +// preservedMenu = null; +// } +// }); +// } else { +// preservedMenu = null; +// menuOwner = null; +// } + } + +// protected boolean handleMouseUp(MouseEvent me) { +// boolean ret = super.handleMouseUp(me); +//// ITool currentTool = getDomain().getActiveTool(); +//// if (!me.leftOrRight && currentTool instanceof AbstractTool) { +//// ((AbstractTool) currentTool).getStatus().setStatus( +//// GEF.ST_HIDE_CMENU, true); +//// } +// return ret; +// } + + protected void onDragging(Point cursorPosition, MouseDragEvent me) { + if (startScrollPosition != null) { + SCROLL_POSITION.setLocation(startScrollPosition); + SCROLL_POSITION.translate(me.getSWTDisplacement().negate()); + getTargetViewer().scrollTo(SCROLL_POSITION); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/EditTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/EditTool.java index 611c31a1d..df080115b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/EditTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/EditTool.java @@ -1,280 +1,280 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.jface.viewers.StructuredSelection; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - * @version 2005 - */ -public abstract class EditTool extends GraphicalTool implements ISourceTool { - - private IGraphicalEditPart source; - - private boolean remainActive = false; - - private Set editRequestTypes = new HashSet(); - - private Request lastForwardedRequest = null; - - public IGraphicalEditPart getSource() { - return source; - } - - public void setSource(IGraphicalEditPart source) { - this.source = source; - } - - /** - * @see org.xmind.gef.tool.AbstractTool#onActivated(ITool) - */ - @Override - protected void onActivated(ITool prevTool) { - super.onActivated(prevTool); - refreshStatus(); - } - - @Override - protected void onDeactivated(ITool nextTool) { - finishEditing(); - super.onDeactivated(nextTool); - } - - /** - * - */ - protected void refreshStatus() { - getStatus().setStatus(GEF.ST_CONTROL_PRESSED, false); - getStatus().setStatus(GEF.ST_SHIFT_PRESSED, false); - getStatus().setStatus(GEF.ST_ALT_PRESSED, false); - } - - protected void handleEditRequest(Request request) { - IPart target = request.getPrimaryTarget(); - if (target instanceof IGraphicalEditPart) { - IGraphicalEditPart newSource = (IGraphicalEditPart) target; - if (canEdit(newSource)) { - if (newSource != getSource()) { - remainActive = true; - finishEditing(); - remainActive = false; - } - setSource(newSource); - if (acceptEditRequest(request)) { - if (shouldUpdateSelectionOnEdit(newSource, request)) { - getTargetViewer().setSelection( - new StructuredSelection(newSource), true); - } - if (!startEditing(getSource())) { - changeActiveTool(GEF.TOOL_DEFAULT); - } - } else { - finishEditing(); - } - } else { - finishEditing(); - if (request != lastForwardedRequest) { - lastForwardedRequest = request; - getDomain().handleRequest(request); - } - } - } - } - - /** - * @param newSource - * @param request - * @return - */ - protected boolean shouldUpdateSelectionOnEdit(IGraphicalEditPart newSource, - Request request) { - return true; - } - - protected boolean canEdit(IGraphicalEditPart target) { - return true; - } - - protected boolean acceptEditRequest(Request request) { - return true; - } - - /** - * @param source - * @return - */ - protected boolean startEditing(IGraphicalEditPart source) { - return false; - } - - protected void cancelEditing() { - if (!remainActive) - changeActiveTool(GEF.TOOL_DEFAULT); - } - - protected void finishEditing() { - if (!remainActive) - changeActiveTool(GEF.TOOL_DEFAULT); - } - - protected boolean isViewRequest(String reqType) { - String role = getDomain().getPartRoles().getRole(reqType); - return isViewRole(role); - } - - protected boolean isViewRole(String role) { - return GEF.ROLE_SELECTABLE.equals(role) - || GEF.ROLE_SCALABLE.equals(role) - || GEF.ROLE_MODIFIABLE.equals(role); - } - - protected Collection getEditRequestTypes() { - return editRequestTypes; - } - - protected void addEditRequestType(String reqType) { - editRequestTypes.add(reqType); - } - - protected void removeEditRequestType(String reqType) { - editRequestTypes.remove(reqType); - } - - protected void internalHandleRequest(Request request) { - if (request.getTargetViewer() == null - || request.getTargetViewer() != getTargetViewer()) { - super.internalHandleRequest(request); - return; - } - String requestType = request.getType(); - if (GEF.REQ_EDIT.equals(requestType) - || getEditRequestTypes().contains(requestType)) { - handleEditRequest(request); - } else if (GEF.REQ_SELECT_ALL.equals(requestType)) { - selectAll(); - } else if (GEF.REQ_COPY.equals(requestType)) { - copy(); - } else if (GEF.REQ_CUT.equals(requestType)) { - cut(); - } else if (GEF.REQ_PASTE.equals(requestType)) { - paste(); - } else if (GEF.REQ_DELETE.equals(requestType)) { - delete(); - } else if (GEF.REQ_CANCEL.equals(requestType)) { - cancelEditing(); - } else if (GEF.REQ_FINISH.equals(requestType)) { - finishEditing(); - } else if (GEF.REQ_REDO.equals(requestType)) { - if (canRedo()) { - redo(); - } - } else if (GEF.REQ_UNDO.equals(requestType)) { - if (canUndo()) { - undo(); - } - } else if (isViewRequest(requestType)) { - getDomain().getDefaultTool().handleRequest(request); - } else { - finishEditing(); - if (!getStatus().isStatus(GEF.ST_ACTIVE)) { - getDomain().handleRequest(request); - } else { - getDomain().getDefaultTool().handleRequest(request); - } - } - } - -// protected void internalHandleRequest(Request request) { -// super.handleSingleRequest(request); -// } - - protected void selectAll() { - } - - protected void copy() { - } - - protected void cut() { - } - - protected void paste() { - } - - protected void delete() { - } - - protected void undo() { - } - - protected void redo() { - } - - public boolean canUndo() { - return false; - } - - public boolean canRedo() { - return false; - } - - protected boolean handleMouseDown(MouseEvent me) { - if (shouldFinishOnMouseDown(me)) { - finishEditing(); - ITool activeTool = getDomain().getActiveTool(); - if (activeTool != this) - activeTool.mouseDown(me, getTargetViewer()); - return true; - } else { - return super.handleMouseDown(me); - } - } - - protected boolean shouldFinishOnMouseDown(MouseEvent me) { - return me.target != getSource(); - } - - protected boolean handleKeyUp(KeyEvent ke) { - if (shouldFinish(ke)) { - finishEditing(); - return true; - } else if (shouldCancel(ke)) { - cancelEditing(); - return true; - } - return super.handleKeyUp(ke); - } - - protected abstract boolean shouldCancel(KeyEvent ke); - - protected abstract boolean shouldFinish(KeyEvent ke); - - protected boolean handleMouseEntered(MouseEvent me) { - if (me.target.hasRole(GEF.ROLE_SELECTABLE)) { - getTargetViewer().setPreselected(me.target); - } - return super.handleMouseEntered(me); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jface.viewers.StructuredSelection; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + * @version 2005 + */ +public abstract class EditTool extends GraphicalTool implements ISourceTool { + + private IGraphicalEditPart source; + + private boolean remainActive = false; + + private Set editRequestTypes = new HashSet(); + + private Request lastForwardedRequest = null; + + public IGraphicalEditPart getSource() { + return source; + } + + public void setSource(IGraphicalEditPart source) { + this.source = source; + } + + /** + * @see org.xmind.gef.tool.AbstractTool#onActivated(ITool) + */ + @Override + protected void onActivated(ITool prevTool) { + super.onActivated(prevTool); + refreshStatus(); + } + + @Override + protected void onDeactivated(ITool nextTool) { + finishEditing(); + super.onDeactivated(nextTool); + } + + /** + * + */ + protected void refreshStatus() { + getStatus().setStatus(GEF.ST_CONTROL_PRESSED, false); + getStatus().setStatus(GEF.ST_SHIFT_PRESSED, false); + getStatus().setStatus(GEF.ST_ALT_PRESSED, false); + } + + protected void handleEditRequest(Request request) { + IPart target = request.getPrimaryTarget(); + if (target instanceof IGraphicalEditPart) { + IGraphicalEditPart newSource = (IGraphicalEditPart) target; + if (canEdit(newSource)) { + if (newSource != getSource()) { + remainActive = true; + finishEditing(); + remainActive = false; + } + setSource(newSource); + if (acceptEditRequest(request)) { + if (shouldUpdateSelectionOnEdit(newSource, request)) { + getTargetViewer().setSelection( + new StructuredSelection(newSource), true); + } + if (!startEditing(getSource())) { + changeActiveTool(GEF.TOOL_DEFAULT); + } + } else { + finishEditing(); + } + } else { + finishEditing(); + if (request != lastForwardedRequest) { + lastForwardedRequest = request; + getDomain().handleRequest(request); + } + } + } + } + + /** + * @param newSource + * @param request + * @return + */ + protected boolean shouldUpdateSelectionOnEdit(IGraphicalEditPart newSource, + Request request) { + return true; + } + + protected boolean canEdit(IGraphicalEditPart target) { + return true; + } + + protected boolean acceptEditRequest(Request request) { + return true; + } + + /** + * @param source + * @return + */ + protected boolean startEditing(IGraphicalEditPart source) { + return false; + } + + protected void cancelEditing() { + if (!remainActive) + changeActiveTool(GEF.TOOL_DEFAULT); + } + + protected void finishEditing() { + if (!remainActive) + changeActiveTool(GEF.TOOL_DEFAULT); + } + + protected boolean isViewRequest(String reqType) { + String role = getDomain().getPartRoles().getRole(reqType); + return isViewRole(role); + } + + protected boolean isViewRole(String role) { + return GEF.ROLE_SELECTABLE.equals(role) + || GEF.ROLE_SCALABLE.equals(role) + || GEF.ROLE_MODIFIABLE.equals(role); + } + + protected Collection getEditRequestTypes() { + return editRequestTypes; + } + + protected void addEditRequestType(String reqType) { + editRequestTypes.add(reqType); + } + + protected void removeEditRequestType(String reqType) { + editRequestTypes.remove(reqType); + } + + protected void internalHandleRequest(Request request) { + if (request.getTargetViewer() == null + || request.getTargetViewer() != getTargetViewer()) { + super.internalHandleRequest(request); + return; + } + String requestType = request.getType(); + if (GEF.REQ_EDIT.equals(requestType) + || getEditRequestTypes().contains(requestType)) { + handleEditRequest(request); + } else if (GEF.REQ_SELECT_ALL.equals(requestType)) { + selectAll(); + } else if (GEF.REQ_COPY.equals(requestType)) { + copy(); + } else if (GEF.REQ_CUT.equals(requestType)) { + cut(); + } else if (GEF.REQ_PASTE.equals(requestType)) { + paste(); + } else if (GEF.REQ_DELETE.equals(requestType)) { + delete(); + } else if (GEF.REQ_CANCEL.equals(requestType)) { + cancelEditing(); + } else if (GEF.REQ_FINISH.equals(requestType)) { + finishEditing(); + } else if (GEF.REQ_REDO.equals(requestType)) { + if (canRedo()) { + redo(); + } + } else if (GEF.REQ_UNDO.equals(requestType)) { + if (canUndo()) { + undo(); + } + } else if (isViewRequest(requestType)) { + getDomain().getDefaultTool().handleRequest(request); + } else { + finishEditing(); + if (!getStatus().isStatus(GEF.ST_ACTIVE)) { + getDomain().handleRequest(request); + } else { + getDomain().getDefaultTool().handleRequest(request); + } + } + } + +// protected void internalHandleRequest(Request request) { +// super.handleSingleRequest(request); +// } + + protected void selectAll() { + } + + protected void copy() { + } + + protected void cut() { + } + + protected void paste() { + } + + protected void delete() { + } + + protected void undo() { + } + + protected void redo() { + } + + public boolean canUndo() { + return false; + } + + public boolean canRedo() { + return false; + } + + protected boolean handleMouseDown(MouseEvent me) { + if (shouldFinishOnMouseDown(me)) { + finishEditing(); + ITool activeTool = getDomain().getActiveTool(); + if (activeTool != this) + activeTool.mouseDown(me, getTargetViewer()); + return true; + } else { + return super.handleMouseDown(me); + } + } + + protected boolean shouldFinishOnMouseDown(MouseEvent me) { + return me.target != getSource(); + } + + protected boolean handleKeyUp(KeyEvent ke) { + if (shouldFinish(ke)) { + finishEditing(); + return true; + } else if (shouldCancel(ke)) { + cancelEditing(); + return true; + } + return super.handleKeyUp(ke); + } + + protected abstract boolean shouldCancel(KeyEvent ke); + + protected abstract boolean shouldFinish(KeyEvent ke); + + protected boolean handleMouseEntered(MouseEvent me) { + if (me.target.hasRole(GEF.ROLE_SELECTABLE)) { + getTargetViewer().setPreselected(me.target); + } + return super.handleMouseEntered(me); + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/IEditTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/IEditTool.java index 660b07b0f..0d5ab5591 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/IEditTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/IEditTool.java @@ -1,31 +1,31 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -/** - * - * @author frankshaka - * @deprecated Use EditTool instead. - */ -public interface IEditTool { - - boolean canUndo(); - - boolean canRedo(); - - String getUndoLabel(); - - String getRedoLabel(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +/** + * + * @author frankshaka + * @deprecated Use EditTool instead. + */ +public interface IEditTool { + + boolean canUndo(); + + boolean canRedo(); + + String getUndoLabel(); + + String getRedoLabel(); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/ISourceTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/ISourceTool.java index 1f445342c..52aec5602 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/ISourceTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/ISourceTool.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import org.xmind.gef.part.IGraphicalEditPart; - -public interface ISourceTool { - - IGraphicalEditPart getSource(); - - void setSource(IGraphicalEditPart source); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import org.xmind.gef.part.IGraphicalEditPart; + +public interface ISourceTool { + + IGraphicalEditPart getSource(); + + void setSource(IGraphicalEditPart source); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/ITextEditTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/ITextEditTool.java index 2fa57b47e..6785fb66d 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/ITextEditTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/ITextEditTool.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import org.eclipse.jface.text.ITextSelection; - -public interface ITextEditTool { - - ITextSelection getTextSelection(); - - void setTextSelection(ITextSelection selection); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import org.eclipse.jface.text.ITextSelection; + +public interface ITextEditTool { + + ITextSelection getTextSelection(); + + void setTextSelection(ITextSelection selection); + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tool/SelectTool.java b/bundles/org.xmind.gef/src/org/xmind/gef/tool/SelectTool.java index 83fd4b7fb..68e84361f 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tool/SelectTool.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tool/SelectTool.java @@ -1,551 +1,551 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tool; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.xmind.gef.GEF; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.event.MouseDragEvent; -import org.xmind.gef.event.MouseEvent; -import org.xmind.gef.event.MouseWheelEvent; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IPart; - -/** - * @author Brian Sun - */ -public class SelectTool extends GraphicalTool { - - private static final List EMPTY_PARTS = Collections.emptyList(); - - private IPart sequenceStart = null; - - private boolean ignoreResetSeqStart = false; - - private IPart toSelectOnMouseUp = null; - - protected void setToSelectOnMouseUp(IPart part) { - toSelectOnMouseUp = part; - } - - public void mouseDoubleClick(MouseEvent me, IViewer viewer) { - setToSelectOnMouseUp(null); - super.mouseDoubleClick(me, viewer); - } - - protected boolean handleMouseDoubleClick(MouseEvent me) { - if (me.leftOrRight) { - IPart source = (IPart) me.target; - if (source.hasRole(GEF.ROLE_EDITABLE)) { - resetSeqSelectStart(); - handleEditRequest(createEditRequestOnDoubleClick(source, me)); - me.consume(); - return true; - } - } - return super.handleMouseDoubleClick(me); - } - - protected Request createEditRequestOnDoubleClick(IPart source, MouseEvent me) { - return new Request(GEF.REQ_EDIT).setPrimaryTarget(me.target) - .setDomain(getDomain()).setViewer(getTargetViewer()); - } - - public void mouseDown(MouseEvent me, IViewer viewer) { - setToSelectOnMouseUp(null); - super.mouseDown(me, viewer); - } - - protected boolean handleMouseDown(MouseEvent me) { - getStatus().setStatus(GEF.ST_MOUSE_PRESSED, true); - getStatus().setStatus(GEF.ST_MOUSE_RIGHT, !me.leftOrRight); - if (isToSelectOnMouseUp(me.target, getTargetViewer())) { - setToSelectOnMouseUp(me.target); - } else { - mouseSelect(me.target); - } - return true; - } - - /** - * @param target - */ - protected void mouseSelect(IPart target) { - if (target.hasRole(GEF.ROLE_SELECTABLE)) { - if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { - getTargetViewer().setFocused(target); - } else if (!target.getStatus().isSelected()) { - if (getStatus().isStatus(GEF.ST_SHIFT_PRESSED) - && getTargetViewer().getFocused() != null) { - sequenceSelect(target); - } else { - selectSingle(target); - } - } - } else if (!getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { - handleSelectNone(getTargetViewer()); - } - } - - protected boolean isToSelectOnMouseUp(IPart part, IViewer viewer) { - return part == viewer.getRootPart(); - } - - public void mouseDrag(MouseDragEvent me, IViewer viewer) { - setToSelectOnMouseUp(null); - super.mouseDrag(me, viewer); - } - - protected boolean handleMouseDrag(MouseDragEvent me) { - resetSeqSelectStart(); - if (getStatus().isStatus(GEF.ST_NO_DRAGGING)) { - me.consume(); - return true; - } - - IPart dragSource = me.source; - String toolType = null; - if (canStartBrowsing(dragSource, me)) { - toolType = getBrowseToolId(); - } else { - if (canMove(dragSource, me)) { - toolType = getMoveTool(dragSource, me); - } else if (dragSource == getTargetViewer().getRootPart()) { - toolType = getAreaSelectToolId(); - } - } - ITool tool = getTool(toolType); - if (tool != null && tool != this) { - changeToMoveTool(toolType, tool, dragSource, me); - me.consume(); - return true; - } - return super.handleMouseDrag(me); - } - - protected String getBrowseToolId() { - return GEF.TOOL_BROWSE; - } - - protected String getAreaSelectToolId() { - return GEF.TOOL_AREASELECT; - } - - protected void changeToMoveTool(String moveToolType, ITool moveTool, - IPart dragSource, MouseDragEvent me) { - if (moveTool instanceof ISourceTool - && dragSource instanceof IGraphicalEditPart) { - ((ISourceTool) moveTool).setSource((IGraphicalEditPart) dragSource); - } - if (moveTool instanceof IGraphicalTool) { - ((IGraphicalTool) moveTool).setCursorPosition(getCursorPosition()); - } - if (moveTool instanceof IDraggingTool) { - ((IDraggingTool) moveTool).setStartingPosition(me.startingLocation); - } - changeActiveTool(moveToolType); - if (moveTool == getDomain().getActiveTool()) { - moveTool.mouseDrag(me, getTargetViewer()); - } - } - - protected boolean canStartBrowsing(IPart host, MouseDragEvent me) { - return getStatus().isStatus(GEF.ST_MOUSE_RIGHT) - || (getStatus().isStatus(GEF.ST_MOUSE_PRESSED) && host - .hasRole(GEF.ROLE_MAP_MOVABLE)); - } - - protected boolean canMove(IPart host, MouseDragEvent me) { - return host.hasRole(GEF.ROLE_MOVABLE); - } - - protected String getMoveTool(IPart source, MouseDragEvent me) { - return GEF.TOOL_MOVE; - } - - protected boolean handleMouseEntered(MouseEvent me) { - IPart target = me.target; - if (target != null && target.hasRole(GEF.ROLE_SELECTABLE)) { - setPreSelected(target); - } else { - setPreSelected(null); - } - return super.handleMouseEntered(me); - } - - protected void setPreSelected(IPart target) { - getTargetViewer().setPreselected(target); - } - - protected boolean handleMouseHover(MouseEvent me) { - getStatus().setStatus(GEF.ST_MOUSE_HOVER, true); - return super.handleMouseHover(me); - } - - public void mouseLongPressed(MouseEvent me, IViewer viewer) { - setToSelectOnMouseUp(null); - super.mouseLongPressed(me, viewer); - } - - protected boolean handleLongPressed(MouseEvent me) { - if (me.leftOrRight && !getStatus().isStatus(GEF.ST_SHIFT_PRESSED) - && !getStatus().isStatus(GEF.ST_CONTROL_PRESSED) - && !getStatus().isStatus(GEF.ST_ALT_PRESSED)) { - String browseToolId = getBrowseToolId(); - if (browseToolId != null) { - ITool tool = getTool(browseToolId); - if (tool != null) { - if (tool instanceof IDraggingTool) { - ((IDraggingTool) tool) - .setStartingPosition(getCursorPosition()); - } - if (tool instanceof IGraphicalTool) { - ((IGraphicalTool) tool) - .setCursorPosition(getCursorPosition()); - } - changeActiveTool(browseToolId); - if (tool == getDomain().getActiveTool()) { - me.consume(); - } - return true; - } - } - } - return super.handleLongPressed(me); - } - - public void mouseMove(MouseEvent me, IViewer viewer) { - setToSelectOnMouseUp(null); - super.mouseMove(me, viewer); - } - - protected boolean handleMouseMove(MouseEvent me) { - getStatus().setStatus(GEF.ST_MOUSE_HOVER, false); - return super.handleMouseMove(me); - } - - /** - * @see org.xmind.gef.tool.AbstractTool#mouseUp(org.xmind.gef.event.MouseEvent) - */ - @Override - public boolean handleMouseUp(MouseEvent me) { - getStatus().setStatus(GEF.ST_NO_DRAGGING, false); - getStatus().setStatus(GEF.ST_MOUSE_PRESSED, false); - IPart host = me.target; - if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { - if (host.hasRole(GEF.ROLE_SELECTABLE)) { - multiSelect(host); - } - } - if (toSelectOnMouseUp != null) { - mouseSelect(toSelectOnMouseUp); - setToSelectOnMouseUp(null); - } - if (!me.leftOrRight) { - getStatus().setStatus(GEF.ST_MOUSE_RIGHT, false); - if (!getStatus().isStatus(GEF.ST_HIDE_CMENU)) { - IGraphicalViewer viewer = getTargetViewer(); - if (viewer instanceof GraphicalViewer) { - ((GraphicalViewer) viewer).hideToolTip(); - } - } - } - return true; - } - - protected boolean handleKeyDown(KeyEvent ke) { - int state = ke.getState(); - int key = ke.keyCode; - IGraphicalViewer viewer = getTargetViewer(); - if (viewer != null) { - if (isNavigationKey(state, key)) { - return handleNavigationKeyDown(viewer, state, key); - } - } - return super.handleKeyDown(ke); - } - - protected boolean handleNavigationKeyDown(IGraphicalViewer viewer, - int state, int key) { - String type = getNavigationRequestType(key); - if (type != null) { - Request request = createTargetedRequest(type, viewer, false); - request.setPrimaryTarget(viewer.getFocusedPart()); - if (request.hasTargets()) { - boolean sequential = isSequentialNavigation(state); - if (sequential) { - request.setParameter(GEF.PARAM_NAV_SEQUENTIAL, Boolean.TRUE); - if (getSequenceStart() == null) { - IPart newStart = request.getPrimaryTarget(); - setSequenceStart(newStart); - } - request.setParameter(GEF.PARAM_NAV_SEQUENCE_START, - getSequenceStart()); - } - return handleNavRequest(request, sequential); - } - } - return true; - } - - protected boolean handleNavRequest(Request request, boolean sequential) { - getDomain().handleRequest(request); - Object result = request.getResult(GEF.RESULT_NAVIGATION); - if (result != null && result instanceof IPart[]) { - IPart[] toSelect = (IPart[]) result; - IPart toFocus = (IPart) request.getResult(GEF.RESULT_NEW_FOCUS); - navigateTo(Arrays.asList(toSelect), toFocus, sequential); - return true; - } - return false; - } - - protected void navigateTo(List toSelect, boolean sequential) { - navigateTo(toSelect, null, sequential); - } - - protected void navigateTo(List toSelect, IPart toFocus, - boolean sequential) { - if (sequential) { - ignoreResetSeqStart = true; - } - select(toSelect, - toFocus == null || !toSelect.contains(toFocus) ? (toSelect - .isEmpty() ? null : toSelect.get(0)) : toFocus); - if (sequential) - ignoreResetSeqStart = false; - } - - protected boolean isNavigationKey(int state, int key) { - if (state == 0 || state == SWT.MOD2) { - return key == SWT.ARROW_UP || key == SWT.ARROW_DOWN - || key == SWT.ARROW_LEFT || key == SWT.ARROW_RIGHT - || key == SWT.HOME || key == SWT.END; - } - return false; - } - - protected boolean isSequentialNavigation(int state) { - return state == SWT.MOD2; - } - - protected String getNavigationRequestType(int key) { - switch (key) { - case SWT.ARROW_UP: - return GEF.REQ_NAV_UP; - case SWT.ARROW_DOWN: - return GEF.REQ_NAV_DOWN; - case SWT.ARROW_LEFT: - return GEF.REQ_NAV_LEFT; - case SWT.ARROW_RIGHT: - return GEF.REQ_NAV_RIGHT; - case SWT.HOME: - return GEF.REQ_NAV_BEGINNING; - case SWT.END: - return GEF.REQ_NAV_END; - } - return null; - } - - protected void handleNonTargetedRequest(Request request) { - String requestType = request.getType(); - if (GEF.REQ_UNDO.equals(requestType)) { - ICommandStack cs = getDomain().getCommandStack(); - if (cs.canUndo()) - cs.undo(); - return; - } else if (GEF.REQ_REDO.equals(requestType)) { - ICommandStack cs = getDomain().getCommandStack(); - if (cs.canRedo()) - cs.redo(); - return; - } else if (request.getTargetViewer() != null) { - if (GEF.REQ_SELECT_NONE.equals(requestType)) { - handleSelectNone(request.getTargetViewer()); - return; - } else if (GEF.REQ_SELECT_ALL.equals(requestType)) { - handleSelectAll(request.getTargetViewer()); - return; - } else if (allowsFillTargets(request)) { - fillTargets(request, request.getTargetViewer(), false); - if (request.hasTargets()) { - handleTargetedRequest(request); - return; - } - } - } - super.handleNonTargetedRequest(request); - } - - protected boolean allowsFillTargets(Request request) { - return true; - } - - protected void handleTargetedRequest(Request request) { - String requestType = request.getType(); - if (GEF.REQ_SELECT.equals(requestType)) { - select(request.getTargets(), request.getPrimaryTarget()); - } else if (GEF.REQ_SELECT_SINGLE.equals(requestType)) { - selectSingle(request.getPrimaryTarget()); - } else if (GEF.REQ_EDIT.equals(requestType)) { - handleEditRequest(request); - } else { - super.handleTargetedRequest(request); - } - } - - protected void handleSelectAll(IViewer viewer) { - List allSelectable = collectAllSelectable(viewer.getRootPart(), - new ArrayList()); - IPart toFocus = getTargetViewer().getFocusedPart(); - select(allSelectable, toFocus); - } - - protected List collectAllSelectable(IPart parent, List results) { - for (IPart child : parent.getChildren()) { - if (isSelectableOnSelectAll(child)) { - results.add(child); - } - collectAllSelectable(child, results); - } - return results; - } - - protected boolean isSelectableOnSelectAll(IPart child) { - return getTargetViewer().getSelectionSupport().isSelectable(child); - } - - /** - * @return the lastSeqStart - */ - public IPart getSequenceStart() { - return sequenceStart; - } - - protected List getSequenceParts(IPart start, IPart end) { - return Arrays.asList(start, end); - } - - protected void select(List toSelect, IPart toFocus) { - IGraphicalViewer viewer = getTargetViewer(); - if (viewer != null) { - IPart lastFocused = viewer.getFocusedPart(); - viewer.setSelection(new StructuredSelection(toSelect), true); - resetSeqSelectStart(); - viewer.setFocused(getToFocus(toFocus, lastFocused)); - } - } - - protected IPart getToFocus(IPart toFocus, IPart lastFocused) { - if (isFocusable(toFocus, lastFocused)) { - return toFocus; - } - return null; - } - - protected boolean isFocusable(IPart toFocus, IPart lastFocused) { - if (lastFocused != null && lastFocused.getStatus().isSelected()) - return true; - return toFocus != null && toFocus.getStatus().isSelected(); - } - - protected void multiSelect(IPart host) { - if (!host.getStatus().isSelected()) { - getTargetViewer().getSelectionSupport().appendSelection(host); - } else { - getTargetViewer().getSelectionSupport().deselect(host); - } - } - - protected void handleSelectNone(IViewer viewer) { - select(EMPTY_PARTS, null); - } - - protected void selectSingle(IPart target) { - select(Collections.singletonList(target), target); - } - - protected void sequenceSelect(IPart target) { - if (getSequenceStart() == null) { - setSequenceStart(getTargetViewer().getFocusedPart()); - } - List seqParts = getSequenceParts(getSequenceStart(), target); - if (seqParts != null && !seqParts.isEmpty()) { - ignoreResetSeqStart = true; - select(seqParts, target); - ignoreResetSeqStart = false; - } - } - - protected void setSequenceStart(IPart start) { - this.sequenceStart = start; - } - - public void resetSeqSelectStart() { - if (ignoreResetSeqStart) - return; - setSequenceStart(null); - } - - protected void handleEditRequest(Request request) { - startEditing(request.getPrimaryTarget(), request); - } - - protected void startEditing(IPart source, Request request) { - //selectSingle(source); - String editToolType = getEditTool(source, request); - ITool et = getTool(editToolType); - if (et != null && et != this) { - changeActiveTool(editToolType); - if (et == getDomain().getActiveTool()) { - et.handleRequest(request); - } - } - } - - protected String getEditTool(IPart source, Request request) { - return GEF.TOOL_EDIT; - } - - @Override - protected boolean handleWheelScrolled(MouseWheelEvent me) { - if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { - if (handleZoomByScroll(me)) - return true; - } - return super.handleWheelScrolled(me); - } - - protected boolean handleZoomByScroll(MouseWheelEvent me) { - if (me.upOrDown) { - getDomain().handleRequest(GEF.REQ_ZOOMIN, getTargetViewer()); - } else { - getDomain().handleRequest(GEF.REQ_ZOOMOUT, getTargetViewer()); - } - me.doIt = false; - return true; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tool; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.xmind.gef.GEF; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.event.MouseDragEvent; +import org.xmind.gef.event.MouseEvent; +import org.xmind.gef.event.MouseWheelEvent; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IPart; + +/** + * @author Brian Sun + */ +public class SelectTool extends GraphicalTool { + + private static final List EMPTY_PARTS = Collections.emptyList(); + + private IPart sequenceStart = null; + + private boolean ignoreResetSeqStart = false; + + private IPart toSelectOnMouseUp = null; + + protected void setToSelectOnMouseUp(IPart part) { + toSelectOnMouseUp = part; + } + + public void mouseDoubleClick(MouseEvent me, IViewer viewer) { + setToSelectOnMouseUp(null); + super.mouseDoubleClick(me, viewer); + } + + protected boolean handleMouseDoubleClick(MouseEvent me) { + if (me.leftOrRight) { + IPart source = (IPart) me.target; + if (source.hasRole(GEF.ROLE_EDITABLE)) { + resetSeqSelectStart(); + handleEditRequest(createEditRequestOnDoubleClick(source, me)); + me.consume(); + return true; + } + } + return super.handleMouseDoubleClick(me); + } + + protected Request createEditRequestOnDoubleClick(IPart source, MouseEvent me) { + return new Request(GEF.REQ_EDIT).setPrimaryTarget(me.target) + .setDomain(getDomain()).setViewer(getTargetViewer()); + } + + public void mouseDown(MouseEvent me, IViewer viewer) { + setToSelectOnMouseUp(null); + super.mouseDown(me, viewer); + } + + protected boolean handleMouseDown(MouseEvent me) { + getStatus().setStatus(GEF.ST_MOUSE_PRESSED, true); + getStatus().setStatus(GEF.ST_MOUSE_RIGHT, !me.leftOrRight); + if (isToSelectOnMouseUp(me.target, getTargetViewer())) { + setToSelectOnMouseUp(me.target); + } else { + mouseSelect(me.target); + } + return true; + } + + /** + * @param target + */ + protected void mouseSelect(IPart target) { + if (target.hasRole(GEF.ROLE_SELECTABLE)) { + if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { + getTargetViewer().setFocused(target); + } else if (!target.getStatus().isSelected()) { + if (getStatus().isStatus(GEF.ST_SHIFT_PRESSED) + && getTargetViewer().getFocused() != null) { + sequenceSelect(target); + } else { + selectSingle(target); + } + } + } else if (!getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { + handleSelectNone(getTargetViewer()); + } + } + + protected boolean isToSelectOnMouseUp(IPart part, IViewer viewer) { + return part == viewer.getRootPart(); + } + + public void mouseDrag(MouseDragEvent me, IViewer viewer) { + setToSelectOnMouseUp(null); + super.mouseDrag(me, viewer); + } + + protected boolean handleMouseDrag(MouseDragEvent me) { + resetSeqSelectStart(); + if (getStatus().isStatus(GEF.ST_NO_DRAGGING)) { + me.consume(); + return true; + } + + IPart dragSource = me.source; + String toolType = null; + if (canStartBrowsing(dragSource, me)) { + toolType = getBrowseToolId(); + } else { + if (canMove(dragSource, me)) { + toolType = getMoveTool(dragSource, me); + } else if (dragSource == getTargetViewer().getRootPart()) { + toolType = getAreaSelectToolId(); + } + } + ITool tool = getTool(toolType); + if (tool != null && tool != this) { + changeToMoveTool(toolType, tool, dragSource, me); + me.consume(); + return true; + } + return super.handleMouseDrag(me); + } + + protected String getBrowseToolId() { + return GEF.TOOL_BROWSE; + } + + protected String getAreaSelectToolId() { + return GEF.TOOL_AREASELECT; + } + + protected void changeToMoveTool(String moveToolType, ITool moveTool, + IPart dragSource, MouseDragEvent me) { + if (moveTool instanceof ISourceTool + && dragSource instanceof IGraphicalEditPart) { + ((ISourceTool) moveTool).setSource((IGraphicalEditPart) dragSource); + } + if (moveTool instanceof IGraphicalTool) { + ((IGraphicalTool) moveTool).setCursorPosition(getCursorPosition()); + } + if (moveTool instanceof IDraggingTool) { + ((IDraggingTool) moveTool).setStartingPosition(me.startingLocation); + } + changeActiveTool(moveToolType); + if (moveTool == getDomain().getActiveTool()) { + moveTool.mouseDrag(me, getTargetViewer()); + } + } + + protected boolean canStartBrowsing(IPart host, MouseDragEvent me) { + return getStatus().isStatus(GEF.ST_MOUSE_RIGHT) + || (getStatus().isStatus(GEF.ST_MOUSE_PRESSED) && host + .hasRole(GEF.ROLE_MAP_MOVABLE)); + } + + protected boolean canMove(IPart host, MouseDragEvent me) { + return host.hasRole(GEF.ROLE_MOVABLE); + } + + protected String getMoveTool(IPart source, MouseDragEvent me) { + return GEF.TOOL_MOVE; + } + + protected boolean handleMouseEntered(MouseEvent me) { + IPart target = me.target; + if (target != null && target.hasRole(GEF.ROLE_SELECTABLE)) { + setPreSelected(target); + } else { + setPreSelected(null); + } + return super.handleMouseEntered(me); + } + + protected void setPreSelected(IPart target) { + getTargetViewer().setPreselected(target); + } + + protected boolean handleMouseHover(MouseEvent me) { + getStatus().setStatus(GEF.ST_MOUSE_HOVER, true); + return super.handleMouseHover(me); + } + + public void mouseLongPressed(MouseEvent me, IViewer viewer) { + setToSelectOnMouseUp(null); + super.mouseLongPressed(me, viewer); + } + + protected boolean handleLongPressed(MouseEvent me) { + if (me.leftOrRight && !getStatus().isStatus(GEF.ST_SHIFT_PRESSED) + && !getStatus().isStatus(GEF.ST_CONTROL_PRESSED) + && !getStatus().isStatus(GEF.ST_ALT_PRESSED)) { + String browseToolId = getBrowseToolId(); + if (browseToolId != null) { + ITool tool = getTool(browseToolId); + if (tool != null) { + if (tool instanceof IDraggingTool) { + ((IDraggingTool) tool) + .setStartingPosition(getCursorPosition()); + } + if (tool instanceof IGraphicalTool) { + ((IGraphicalTool) tool) + .setCursorPosition(getCursorPosition()); + } + changeActiveTool(browseToolId); + if (tool == getDomain().getActiveTool()) { + me.consume(); + } + return true; + } + } + } + return super.handleLongPressed(me); + } + + public void mouseMove(MouseEvent me, IViewer viewer) { + setToSelectOnMouseUp(null); + super.mouseMove(me, viewer); + } + + protected boolean handleMouseMove(MouseEvent me) { + getStatus().setStatus(GEF.ST_MOUSE_HOVER, false); + return super.handleMouseMove(me); + } + + /** + * @see org.xmind.gef.tool.AbstractTool#mouseUp(org.xmind.gef.event.MouseEvent) + */ + @Override + public boolean handleMouseUp(MouseEvent me) { + getStatus().setStatus(GEF.ST_NO_DRAGGING, false); + getStatus().setStatus(GEF.ST_MOUSE_PRESSED, false); + IPart host = me.target; + if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { + if (host.hasRole(GEF.ROLE_SELECTABLE)) { + multiSelect(host); + } + } + if (toSelectOnMouseUp != null) { + mouseSelect(toSelectOnMouseUp); + setToSelectOnMouseUp(null); + } + if (!me.leftOrRight) { + getStatus().setStatus(GEF.ST_MOUSE_RIGHT, false); + if (!getStatus().isStatus(GEF.ST_HIDE_CMENU)) { + IGraphicalViewer viewer = getTargetViewer(); + if (viewer instanceof GraphicalViewer) { + ((GraphicalViewer) viewer).hideToolTip(); + } + } + } + return true; + } + + protected boolean handleKeyDown(KeyEvent ke) { + int state = ke.getState(); + int key = ke.keyCode; + IGraphicalViewer viewer = getTargetViewer(); + if (viewer != null) { + if (isNavigationKey(state, key)) { + return handleNavigationKeyDown(viewer, state, key); + } + } + return super.handleKeyDown(ke); + } + + protected boolean handleNavigationKeyDown(IGraphicalViewer viewer, + int state, int key) { + String type = getNavigationRequestType(key); + if (type != null) { + Request request = createTargetedRequest(type, viewer, false); + request.setPrimaryTarget(viewer.getFocusedPart()); + if (request.hasTargets()) { + boolean sequential = isSequentialNavigation(state); + if (sequential) { + request.setParameter(GEF.PARAM_NAV_SEQUENTIAL, Boolean.TRUE); + if (getSequenceStart() == null) { + IPart newStart = request.getPrimaryTarget(); + setSequenceStart(newStart); + } + request.setParameter(GEF.PARAM_NAV_SEQUENCE_START, + getSequenceStart()); + } + return handleNavRequest(request, sequential); + } + } + return true; + } + + protected boolean handleNavRequest(Request request, boolean sequential) { + getDomain().handleRequest(request); + Object result = request.getResult(GEF.RESULT_NAVIGATION); + if (result != null && result instanceof IPart[]) { + IPart[] toSelect = (IPart[]) result; + IPart toFocus = (IPart) request.getResult(GEF.RESULT_NEW_FOCUS); + navigateTo(Arrays.asList(toSelect), toFocus, sequential); + return true; + } + return false; + } + + protected void navigateTo(List toSelect, boolean sequential) { + navigateTo(toSelect, null, sequential); + } + + protected void navigateTo(List toSelect, IPart toFocus, + boolean sequential) { + if (sequential) { + ignoreResetSeqStart = true; + } + select(toSelect, + toFocus == null || !toSelect.contains(toFocus) ? (toSelect + .isEmpty() ? null : toSelect.get(0)) : toFocus); + if (sequential) + ignoreResetSeqStart = false; + } + + protected boolean isNavigationKey(int state, int key) { + if (state == 0 || state == SWT.MOD2) { + return key == SWT.ARROW_UP || key == SWT.ARROW_DOWN + || key == SWT.ARROW_LEFT || key == SWT.ARROW_RIGHT + || key == SWT.HOME || key == SWT.END; + } + return false; + } + + protected boolean isSequentialNavigation(int state) { + return state == SWT.MOD2; + } + + protected String getNavigationRequestType(int key) { + switch (key) { + case SWT.ARROW_UP: + return GEF.REQ_NAV_UP; + case SWT.ARROW_DOWN: + return GEF.REQ_NAV_DOWN; + case SWT.ARROW_LEFT: + return GEF.REQ_NAV_LEFT; + case SWT.ARROW_RIGHT: + return GEF.REQ_NAV_RIGHT; + case SWT.HOME: + return GEF.REQ_NAV_BEGINNING; + case SWT.END: + return GEF.REQ_NAV_END; + } + return null; + } + + protected void handleNonTargetedRequest(Request request) { + String requestType = request.getType(); + if (GEF.REQ_UNDO.equals(requestType)) { + ICommandStack cs = getDomain().getCommandStack(); + if (cs.canUndo()) + cs.undo(); + return; + } else if (GEF.REQ_REDO.equals(requestType)) { + ICommandStack cs = getDomain().getCommandStack(); + if (cs.canRedo()) + cs.redo(); + return; + } else if (request.getTargetViewer() != null) { + if (GEF.REQ_SELECT_NONE.equals(requestType)) { + handleSelectNone(request.getTargetViewer()); + return; + } else if (GEF.REQ_SELECT_ALL.equals(requestType)) { + handleSelectAll(request.getTargetViewer()); + return; + } else if (allowsFillTargets(request)) { + fillTargets(request, request.getTargetViewer(), false); + if (request.hasTargets()) { + handleTargetedRequest(request); + return; + } + } + } + super.handleNonTargetedRequest(request); + } + + protected boolean allowsFillTargets(Request request) { + return true; + } + + protected void handleTargetedRequest(Request request) { + String requestType = request.getType(); + if (GEF.REQ_SELECT.equals(requestType)) { + select(request.getTargets(), request.getPrimaryTarget()); + } else if (GEF.REQ_SELECT_SINGLE.equals(requestType)) { + selectSingle(request.getPrimaryTarget()); + } else if (GEF.REQ_EDIT.equals(requestType)) { + handleEditRequest(request); + } else { + super.handleTargetedRequest(request); + } + } + + protected void handleSelectAll(IViewer viewer) { + List allSelectable = collectAllSelectable(viewer.getRootPart(), + new ArrayList()); + IPart toFocus = getTargetViewer().getFocusedPart(); + select(allSelectable, toFocus); + } + + protected List collectAllSelectable(IPart parent, List results) { + for (IPart child : parent.getChildren()) { + if (isSelectableOnSelectAll(child)) { + results.add(child); + } + collectAllSelectable(child, results); + } + return results; + } + + protected boolean isSelectableOnSelectAll(IPart child) { + return getTargetViewer().getSelectionSupport().isSelectable(child); + } + + /** + * @return the lastSeqStart + */ + public IPart getSequenceStart() { + return sequenceStart; + } + + protected List getSequenceParts(IPart start, IPart end) { + return Arrays.asList(start, end); + } + + protected void select(List toSelect, IPart toFocus) { + IGraphicalViewer viewer = getTargetViewer(); + if (viewer != null) { + IPart lastFocused = viewer.getFocusedPart(); + viewer.setSelection(new StructuredSelection(toSelect), true); + resetSeqSelectStart(); + viewer.setFocused(getToFocus(toFocus, lastFocused)); + } + } + + protected IPart getToFocus(IPart toFocus, IPart lastFocused) { + if (isFocusable(toFocus, lastFocused)) { + return toFocus; + } + return null; + } + + protected boolean isFocusable(IPart toFocus, IPart lastFocused) { + if (lastFocused != null && lastFocused.getStatus().isSelected()) + return true; + return toFocus != null && toFocus.getStatus().isSelected(); + } + + protected void multiSelect(IPart host) { + if (!host.getStatus().isSelected()) { + getTargetViewer().getSelectionSupport().appendSelection(host); + } else { + getTargetViewer().getSelectionSupport().deselect(host); + } + } + + protected void handleSelectNone(IViewer viewer) { + select(EMPTY_PARTS, null); + } + + protected void selectSingle(IPart target) { + select(Collections.singletonList(target), target); + } + + protected void sequenceSelect(IPart target) { + if (getSequenceStart() == null) { + setSequenceStart(getTargetViewer().getFocusedPart()); + } + List seqParts = getSequenceParts(getSequenceStart(), target); + if (seqParts != null && !seqParts.isEmpty()) { + ignoreResetSeqStart = true; + select(seqParts, target); + ignoreResetSeqStart = false; + } + } + + protected void setSequenceStart(IPart start) { + this.sequenceStart = start; + } + + public void resetSeqSelectStart() { + if (ignoreResetSeqStart) + return; + setSequenceStart(null); + } + + protected void handleEditRequest(Request request) { + startEditing(request.getPrimaryTarget(), request); + } + + protected void startEditing(IPart source, Request request) { + //selectSingle(source); + String editToolType = getEditTool(source, request); + ITool et = getTool(editToolType); + if (et != null && et != this) { + changeActiveTool(editToolType); + if (et == getDomain().getActiveTool()) { + et.handleRequest(request); + } + } + } + + protected String getEditTool(IPart source, Request request) { + return GEF.TOOL_EDIT; + } + + @Override + protected boolean handleWheelScrolled(MouseWheelEvent me) { + if (getStatus().isStatus(GEF.ST_CONTROL_PRESSED)) { + if (handleZoomByScroll(me)) + return true; + } + return super.handleWheelScrolled(me); + } + + protected boolean handleZoomByScroll(MouseWheelEvent me) { + if (me.upOrDown) { + getDomain().handleRequest(GEF.REQ_ZOOMIN, getTargetViewer()); + } else { + getDomain().handleRequest(GEF.REQ_ZOOMOUT, getTargetViewer()); + } + me.doIt = false; + return true; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/tree/ITreeRootPart.java b/bundles/org.xmind.gef/src/org/xmind/gef/tree/ITreeRootPart.java index f52283579..951048070 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/tree/ITreeRootPart.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/tree/ITreeRootPart.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.tree; - -import org.xmind.gef.part.IRootPart; - -/** - * @author Brian Sun - */ -public interface ITreeRootPart extends ITreePart, IRootPart { +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.tree; + +import org.xmind.gef.part.IRootPart; + +/** + * @author Brian Sun + */ +public interface ITreeRootPart extends ITreePart, IRootPart { } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/util/EventListenerSupport.java b/bundles/org.xmind.gef/src/org/xmind/gef/util/EventListenerSupport.java index fea3ffd3f..5e33bd2d1 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/util/EventListenerSupport.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/util/EventListenerSupport.java @@ -1,80 +1,80 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.util; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; - -/** - * @author Frank Shaka - * - */ -public class EventListenerSupport { - - private Map> map = new HashMap>(); - - public void addListener(Object type, Object listener) { - List list = map.get(type); - if (list == null) { - list = new ArrayList(); - map.put(type, list); - } - list.add(listener); - } - - public void removeListener(Object type, Object listener) { - List list = map.get(type); - if (list != null) { - list.remove(listener); - if (list.isEmpty()) { - map.remove(type); - } - } - } - - public void clear(Object type) { - map.remove(type); - } - - public void clearAll() { - map.clear(); - } - - public boolean isEmpty(Object type) { - List list = map.get(type); - return list == null || list.isEmpty(); - } - - public void fireEvent(Object type, final IEventDispatcher dispatcher) { - List list = map.get(type); - if (list != null && !list.isEmpty()) { - Object[] listeners = list.toArray(); - for (int i = 0; i < listeners.length; i++) { - final Object listener = listeners[i]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - dispatcher.dispatch(listener); - } - }); - } - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; + +/** + * @author Frank Shaka + * + */ +public class EventListenerSupport { + + private Map> map = new HashMap>(); + + public void addListener(Object type, Object listener) { + List list = map.get(type); + if (list == null) { + list = new ArrayList(); + map.put(type, list); + } + list.add(listener); + } + + public void removeListener(Object type, Object listener) { + List list = map.get(type); + if (list != null) { + list.remove(listener); + if (list.isEmpty()) { + map.remove(type); + } + } + } + + public void clear(Object type) { + map.remove(type); + } + + public void clearAll() { + map.clear(); + } + + public boolean isEmpty(Object type) { + List list = map.get(type); + return list == null || list.isEmpty(); + } + + public void fireEvent(Object type, final IEventDispatcher dispatcher) { + List list = map.get(type); + if (list != null && !list.isEmpty()) { + Object[] listeners = list.toArray(); + for (int i = 0; i < listeners.length; i++) { + final Object listener = listeners[i]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + dispatcher.dispatch(listener); + } + }); + } + } + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/util/GEFUtils.java b/bundles/org.xmind.gef/src/org/xmind/gef/util/GEFUtils.java index 0ac891616..9f1419813 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/util/GEFUtils.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/util/GEFUtils.java @@ -1,107 +1,107 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.util; - -import org.eclipse.draw2d.Cursors; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.TextStyle; - -public class GEFUtils { - - private GEFUtils() { - } - - /** - * @param ort - */ - public static Cursor getPositionCursor(int ort) { - switch (ort) { - case PositionConstants.EAST: - return Cursors.SIZEE; - case PositionConstants.WEST: - return Cursors.SIZEW; - case PositionConstants.NORTH: - return Cursors.SIZEN; - case PositionConstants.SOUTH: - return Cursors.SIZES; - case PositionConstants.NORTH_EAST: - return Cursors.SIZENE; - case PositionConstants.SOUTH_WEST: - return Cursors.SIZESW; - case PositionConstants.NORTH_WEST: - return Cursors.SIZENW; - case PositionConstants.SOUTH_EAST: - return Cursors.SIZESE; - } - return null; - } - - public static boolean equals(TextStyle style1, TextStyle style2) { - if (style1 == style2) - return true; - if (style1 == null && style2 != null) - return false; - if (style1 != null && style2 == null) - return false; - - if (style1.foreground != null) { - if (!style1.foreground.equals(style2.foreground)) - return false; - } else if (style2.foreground != null) - return false; - if (style1.background != null) { - if (!style1.background.equals(style2.background)) - return false; - } else if (style2.background != null) - return false; - if (style1.font != null) { - if (!equals(style1.font, style2.font)) - return false; - } else if (style2.font != null) - return false; - if (style1.metrics != null || style2.metrics != null) - return false; - if (style1.underline != style2.underline) - return false; - if (style1.strikeout != style2.strikeout) - return false; - if (style1.rise != style2.rise) - return false; - return true; - } - - public static boolean equals(Font f1, Font f2) { - if (f1 == f2) - return true; - if (f1 == null && f2 != null) - return false; - if (f2 == null && f1 != null) - return false; - - if (!Util.isMac()) - return f1.equals(f2); - - if (f1.isDisposed() || f2.isDisposed()) - return false; - - FontData fd1 = f1.getFontData()[0]; - FontData fd2 = f2.getFontData()[0]; - return fd1.equals(fd2); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.util; + +import org.eclipse.draw2d.Cursors; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.TextStyle; + +public class GEFUtils { + + private GEFUtils() { + } + + /** + * @param ort + */ + public static Cursor getPositionCursor(int ort) { + switch (ort) { + case PositionConstants.EAST: + return Cursors.SIZEE; + case PositionConstants.WEST: + return Cursors.SIZEW; + case PositionConstants.NORTH: + return Cursors.SIZEN; + case PositionConstants.SOUTH: + return Cursors.SIZES; + case PositionConstants.NORTH_EAST: + return Cursors.SIZENE; + case PositionConstants.SOUTH_WEST: + return Cursors.SIZESW; + case PositionConstants.NORTH_WEST: + return Cursors.SIZENW; + case PositionConstants.SOUTH_EAST: + return Cursors.SIZESE; + } + return null; + } + + public static boolean equals(TextStyle style1, TextStyle style2) { + if (style1 == style2) + return true; + if (style1 == null && style2 != null) + return false; + if (style1 != null && style2 == null) + return false; + + if (style1.foreground != null) { + if (!style1.foreground.equals(style2.foreground)) + return false; + } else if (style2.foreground != null) + return false; + if (style1.background != null) { + if (!style1.background.equals(style2.background)) + return false; + } else if (style2.background != null) + return false; + if (style1.font != null) { + if (!equals(style1.font, style2.font)) + return false; + } else if (style2.font != null) + return false; + if (style1.metrics != null || style2.metrics != null) + return false; + if (style1.underline != style2.underline) + return false; + if (style1.strikeout != style2.strikeout) + return false; + if (style1.rise != style2.rise) + return false; + return true; + } + + public static boolean equals(Font f1, Font f2) { + if (f1 == f2) + return true; + if (f1 == null && f2 != null) + return false; + if (f2 == null && f1 != null) + return false; + + if (!Util.isMac()) + return f1.equals(f2); + + if (f1.isDisposed() || f2.isDisposed()) + return false; + + FontData fd1 = f1.getFontData()[0]; + FontData fd2 = f2.getFontData()[0]; + return fd1.equals(fd2); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/util/IEventDispatcher.java b/bundles/org.xmind.gef/src/org/xmind/gef/util/IEventDispatcher.java index 2833fb568..d0bd99ee5 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/util/IEventDispatcher.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/util/IEventDispatcher.java @@ -1,19 +1,19 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.gef.util; - -public interface IEventDispatcher { - void dispatch(Object listener); +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.gef.util; + +public interface IEventDispatcher { + void dispatch(Object listener); } \ No newline at end of file diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/util/Properties.java b/bundles/org.xmind.gef/src/org/xmind/gef/util/Properties.java index 581da8c0f..8600804fc 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/util/Properties.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/util/Properties.java @@ -1,178 +1,178 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.gef.util; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -/** - * @author Frank Shaka - */ -public class Properties implements Cloneable { - - private Object source; - - private Map contents = new HashMap(); - - private PropertyChangeSupport eventSupport; - - public Properties() { - this.source = this; - this.eventSupport = new PropertyChangeSupport(this); - } - - public Properties(Object source) { - this.source = source; - this.eventSupport = new PropertyChangeSupport(source); - } - - public Properties(Properties another) { - this(); - putAll(another); - } - - public Properties(Object source, Properties another) { - this(source); - putAll(another); - } - - /** - * @return the delegate - */ - protected PropertyChangeSupport getDelegate() { - return eventSupport; - } - - public void set(String key, boolean value) { - set(key, Boolean.valueOf(value)); - } - - public void set(String key, int value) { - set(key, Integer.valueOf(value)); - } - - public void set(String key, Object value) { - Object oldValue = contents.get(key); - if (value != null && !value.equals(oldValue)) { - contents.put(key, value); - eventSupport.firePropertyChange(key, oldValue, value); - } else if (value == null && value != oldValue) { - contents.remove(key); - eventSupport.firePropertyChange(key, oldValue, value); - } - } - - public void putAll(Properties another) { - if (another == null) - return; - - for (Entry entry : another.contents.entrySet()) { - set(entry.getKey(), entry.getValue()); - } - } - - public Collection keySet() { - return contents.keySet(); - } - - public void remove(String key) { - set(key, null); - } - - public Object get(String key) { - return contents.get(key); - } - - public Object get(String key, Object defaultValue) { - Object value = contents.get(key); - return value == null ? defaultValue : value; - } - - public boolean getBoolean(String key, boolean defaultValue) { - Object value = get(key); - return value instanceof Boolean ? ((Boolean) value).booleanValue() - : defaultValue; - - } - - public int getInteger(String key, int defaultValue) { - Object value = get(key); - return value instanceof Integer ? ((Integer) value).intValue() - : defaultValue; - } - - public String getString(String key, String defaultValue) { - Object value = get(key); - return value instanceof String ? (String) value : defaultValue; - } - - public void clear() { - Iterator ite = contents.keySet().iterator(); - while (ite.hasNext()) { - String key = ite.next(); - Object oldValue = contents.get(key); - ite.remove(); - if (oldValue != null) { - eventSupport.firePropertyChange(key, oldValue, null); - } - } - } - - public boolean isEmpty() { - return contents.isEmpty(); - } - - public boolean hasKey(String key) { - return contents.containsKey(key); - } - - public boolean hasValue(Object value) { - return contents.containsValue(value); - } - - /** - * @see java.lang.Object#clone() - */ - @Override - public Properties clone() { - Properties newInstance = source == this ? new Properties() - : new Properties(source); - newInstance.contents.putAll(this.contents); - return newInstance; - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - eventSupport.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - eventSupport.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - eventSupport.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - eventSupport.removePropertyChangeListener(propertyName, listener); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.gef.util; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +/** + * @author Frank Shaka + */ +public class Properties implements Cloneable { + + private Object source; + + private Map contents = new HashMap(); + + private PropertyChangeSupport eventSupport; + + public Properties() { + this.source = this; + this.eventSupport = new PropertyChangeSupport(this); + } + + public Properties(Object source) { + this.source = source; + this.eventSupport = new PropertyChangeSupport(source); + } + + public Properties(Properties another) { + this(); + putAll(another); + } + + public Properties(Object source, Properties another) { + this(source); + putAll(another); + } + + /** + * @return the delegate + */ + protected PropertyChangeSupport getDelegate() { + return eventSupport; + } + + public void set(String key, boolean value) { + set(key, Boolean.valueOf(value)); + } + + public void set(String key, int value) { + set(key, Integer.valueOf(value)); + } + + public void set(String key, Object value) { + Object oldValue = contents.get(key); + if (value != null && !value.equals(oldValue)) { + contents.put(key, value); + eventSupport.firePropertyChange(key, oldValue, value); + } else if (value == null && value != oldValue) { + contents.remove(key); + eventSupport.firePropertyChange(key, oldValue, value); + } + } + + public void putAll(Properties another) { + if (another == null) + return; + + for (Entry entry : another.contents.entrySet()) { + set(entry.getKey(), entry.getValue()); + } + } + + public Collection keySet() { + return contents.keySet(); + } + + public void remove(String key) { + set(key, null); + } + + public Object get(String key) { + return contents.get(key); + } + + public Object get(String key, Object defaultValue) { + Object value = contents.get(key); + return value == null ? defaultValue : value; + } + + public boolean getBoolean(String key, boolean defaultValue) { + Object value = get(key); + return value instanceof Boolean ? ((Boolean) value).booleanValue() + : defaultValue; + + } + + public int getInteger(String key, int defaultValue) { + Object value = get(key); + return value instanceof Integer ? ((Integer) value).intValue() + : defaultValue; + } + + public String getString(String key, String defaultValue) { + Object value = get(key); + return value instanceof String ? (String) value : defaultValue; + } + + public void clear() { + Iterator ite = contents.keySet().iterator(); + while (ite.hasNext()) { + String key = ite.next(); + Object oldValue = contents.get(key); + ite.remove(); + if (oldValue != null) { + eventSupport.firePropertyChange(key, oldValue, null); + } + } + } + + public boolean isEmpty() { + return contents.isEmpty(); + } + + public boolean hasKey(String key) { + return contents.containsKey(key); + } + + public boolean hasValue(Object value) { + return contents.containsValue(value); + } + + /** + * @see java.lang.Object#clone() + */ + @Override + public Properties clone() { + Properties newInstance = source == this ? new Properties() + : new Properties(source); + newInstance.contents.putAll(this.contents); + return newInstance; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + eventSupport.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + eventSupport.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + eventSupport.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + eventSupport.removePropertyChangeListener(propertyName, listener); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.neuquant/.gitignore b/bundles/org.xmind.neuquant/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.neuquant/.gitignore +++ b/bundles/org.xmind.neuquant/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.neuquant/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.neuquant/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.neuquant/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.neuquant/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.neuquant/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.neuquant/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.neuquant/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.neuquant/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.ui.prefs index 5ff980f2f..6a418ff47 100644 --- a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.ui.prefs @@ -1,3 +1,3 @@ -eclipse.preferences.version=1 -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 +eclipse.preferences.version=1 +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 diff --git a/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF b/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF index c122e97ec..fb359ef8e 100644 --- a/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.neuquant -Bundle-Version: 3.7.0.qualifier -Bundle-Vendor: %providerName -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Require-Bundle: org.eclipse.swt -Export-Package: org.xmind.neuquant -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.neuquant +Bundle-Version: 3.7.0.qualifier +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Require-Bundle: org.eclipse.swt +Export-Package: org.xmind.neuquant +Bundle-Localization: plugin diff --git a/bundles/org.xmind.neuquant/about.html b/bundles/org.xmind.neuquant/about.html index 6021b6889..cf7d3ddd6 100644 --- a/bundles/org.xmind.neuquant/about.html +++ b/bundles/org.xmind.neuquant/about.html @@ -1,35 +1,35 @@ - - - - -About - - -

    About This Content

    - -

    -Copyright (c) 1994 Anthony Dekker -

    - -

    -NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See -"Kohonen neural networks for optimal colour quantization" in -"Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a -discussion of the algorithm. See also -http://members.ozemail.com.au/~dekker/NEUQUANT.HTML -

    - -

    -Any party obtaining a copy of these files from the author, directly or -indirectly, is granted, free of charge, a full and unrestricted irrevocable, -world-wide, paid up, royalty-free, nonexclusive right and license to deal in -this software and documentation files (the "Software"), including without -limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons who -receive copies from any such party to do so, with the only requirement being -that this copyright notice remain intact. -

    - - + + + + +About + + +

    About This Content

    + +

    +Copyright (c) 1994 Anthony Dekker +

    + +

    +NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See +"Kohonen neural networks for optimal colour quantization" in +"Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a +discussion of the algorithm. See also +http://members.ozemail.com.au/~dekker/NEUQUANT.HTML +

    + +

    +Any party obtaining a copy of these files from the author, directly or +indirectly, is granted, free of charge, a full and unrestricted irrevocable, +world-wide, paid up, royalty-free, nonexclusive right and license to deal in +this software and documentation files (the "Software"), including without +limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons who +receive copies from any such party to do so, with the only requirement being +that this copyright notice remain intact. +

    + + \ No newline at end of file diff --git a/bundles/org.xmind.neuquant/plugin.properties b/bundles/org.xmind.neuquant/plugin.properties index d9eed7474..c6943fd82 100644 --- a/bundles/org.xmind.neuquant/plugin.properties +++ b/bundles/org.xmind.neuquant/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.neuquant -providerName = Anthony Dekker +#Properties file for org.xmind.neuquant +providerName = Anthony Dekker pluginName = NeuQuant Image Quantization \ No newline at end of file diff --git a/bundles/org.xmind.neuquant/pom.xml b/bundles/org.xmind.neuquant/pom.xml index d39e14eec..0b7c68c5e 100644 --- a/bundles/org.xmind.neuquant/pom.xml +++ b/bundles/org.xmind.neuquant/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.neuquant - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.neuquant + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.classpath b/bundles/org.xmind.org.freehep.vectorgraphics/.classpath index 2d1a4302f..64c5e31b7 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.classpath +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.gitignore b/bundles/org.xmind.org.freehep.vectorgraphics/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.gitignore +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.project b/bundles/org.xmind.org.freehep.vectorgraphics/.project index f49b68135..4088ffb20 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.project +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.project @@ -1,28 +1,28 @@ - - - org.xmind.org.freehep.vectorgraphics - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.org.freehep.vectorgraphics + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.core.prefs index f4d3df6d2..024a0b67b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.core.prefs @@ -1,23 +1,23 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.pde.prefs index 7a0277731..0387c6e30 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.org.freehep.vectorgraphics/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=2 -compilers.p.discouraged-class=2 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=2 +compilers.p.discouraged-class=2 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF b/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF index 7bfa95b83..6fb463093 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF @@ -1,17 +1,17 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.xmind.org.freehep.vectorgraphics;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.xmind.org.freehep.graphics2d, - org.xmind.org.freehep.graphics2d.font, - org.xmind.org.freehep.graphicsio, - org.xmind.org.freehep.graphicsio.font, - org.xmind.org.freehep.graphicsio.pdf, - org.xmind.org.freehep.graphicsio.raw, - org.xmind.org.freehep.util, - org.xmind.org.freehep.util.images, - org.xmind.org.freehep.util.io -Bundle-ActivationPolicy: lazy -Bundle-Name: %pluginName -Bundle-Vendor: %providerName +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.xmind.org.freehep.vectorgraphics;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.xmind.org.freehep.graphics2d, + org.xmind.org.freehep.graphics2d.font, + org.xmind.org.freehep.graphicsio, + org.xmind.org.freehep.graphicsio.font, + org.xmind.org.freehep.graphicsio.pdf, + org.xmind.org.freehep.graphicsio.raw, + org.xmind.org.freehep.util, + org.xmind.org.freehep.util.images, + org.xmind.org.freehep.util.io +Bundle-ActivationPolicy: lazy +Bundle-Name: %pluginName +Bundle-Vendor: %providerName diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.org.freehep.vectorgraphics/OSGI-INF/l10n/bundle.properties index 5a7301e85..b9da566a2 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.org.freehep.vectorgraphics/OSGI-INF/l10n/bundle.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.de.erichseifert.vectorgraphics2d -providerName = XMind Ltd. -pluginName = Vector Graphics IO +#Properties file for org.xmind.de.erichseifert.vectorgraphics2d +providerName = XMind Ltd. +pluginName = Vector Graphics IO diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/about.html b/bundles/org.xmind.org.freehep.vectorgraphics/about.html index 61ecea348..32d0ade4c 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/about.html +++ b/bundles/org.xmind.org.freehep.vectorgraphics/about.html @@ -1,630 +1,630 @@ - - - - -About - - -

    About This Content

    - -

    Oct 15, 2015

    -

    License

    - -

    -FreeHEP GraphicsIO is licensed under the terms of the GNU Lesser General Public License v2.1, which is also available at http://www.gnu.org/licenses/old-licenses/lgpl-2.1 -

    - -

    -

    - -

    GNU LESSER GENERAL PUBLIC LICENSE

    -

    -Version 2.1, February 1999 -

    - -
    Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    -51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    -Everyone is permitted to copy and distribute verbatim copies
    -of this license document, but changing it is not allowed.
    -
    -[This is the first released version of the Lesser GPL.  It also counts
    - as the successor of the GNU Library Public License, version 2, hence
    - the version number 2.1.]
    -
    - - -

    Preamble

    - -

    - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. -

    -

    - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. -

    -

    - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. -

    -

    - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. -

    -

    - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. -

    -

    - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. -

    -

    - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. -

    -

    - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. -

    -

    - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. -

    -

    - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. -

    -

    - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. -

    -

    - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. -

    -

    - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. -

    -

    - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. -

    -

    - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. -

    - -

    TERMS AND CONDITIONS FOR COPYING, -DISTRIBUTION AND MODIFICATION

    - - -

    -0. -This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". -

    -

    - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. -

    -

    - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) -

    -

    - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. -

    -

    - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. -

    -

    -1. -You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. -

    -

    - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. -

    -

    -2. -You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: -

    - -
      -
    • a) - The modified work must itself be a software library.
    • -
    • b) - You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change.
    • - -
    • c) - You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License.
    • - -
    • d) - If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. -

      - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.)

    • -
    - -

    -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Library, and can be -reasonably considered independent and separate works in themselves, then -this License, and its terms, do not apply to those sections when you -distribute them as separate works. But when you distribute the same -sections as part of a whole which is a work based on the Library, the -distribution of the whole must be on the terms of this License, whose -permissions for other licensees extend to the entire whole, and thus to -each and every part regardless of who wrote it. -

    -

    -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise -the right to control the distribution of derivative or collective works -based on the Library. -

    -

    -In addition, mere aggregation of another work not based on the Library with -the Library (or with a work based on the Library) on a volume of a storage -or distribution medium does not bring the other work under the scope of -this License. -

    -

    -3. -You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. -

    -

    - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. -

    -

    - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. -

    -

    -4. -You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. -

    -

    - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. -

    -

    -5. -A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. -

    -

    - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. -

    -

    - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. -

    -

    - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) -

    -

    - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. -

    -

    -6. -As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. -

    -

    - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: -

    - -
      -
    • a) Accompany the work with the complete - corresponding machine-readable source code for the Library - including whatever changes were used in the work (which must be - distributed under Sections 1 and 2 above); and, if the work is an - executable linked with the Library, with the complete - machine-readable "work that uses the Library", as object code - and/or source code, so that the user can modify the Library and - then relink to produce a modified executable containing the - modified Library. (It is understood that the user who changes the - contents of definitions files in the Library will not necessarily - be able to recompile the application to use the modified - definitions.)
    • - -
    • b) Use a suitable shared library mechanism - for linking with the Library. A suitable mechanism is one that - (1) uses at run time a copy of the library already present on the - user's computer system, rather than copying library functions into - the executable, and (2) will operate properly with a modified - version of the library, if the user installs one, as long as the - modified version is interface-compatible with the version that the - work was made with.
    • - -
    • c) Accompany the work with a written offer, - valid for at least three years, to give the same user the - materials specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution.
    • - -
    • d) If distribution of the work is made by - offering access to copy from a designated place, offer equivalent - access to copy the above specified materials from the same - place.
    • - -
    • e) Verify that the user has already received - a copy of these materials or that you have already sent this user - a copy.
    • -
    - -

    - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. -

    -

    - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. -

    -

    -7. You may place library facilities that are a work -based on the Library side-by-side in a single library together with -other library facilities not covered by this License, and distribute -such a combined library, provided that the separate distribution of -the work based on the Library and of the other library facilities is -otherwise permitted, and provided that you do these two things: -

    - -
      -
    • a) Accompany the combined library with a copy - of the same work based on the Library, uncombined with any other - library facilities. This must be distributed under the terms of - the Sections above.
    • - -
    • b) Give prominent notice with the combined - library of the fact that part of it is a work based on the - Library, and explaining where to find the accompanying uncombined - form of the same work.
    • -
    - -

    -8. You may not copy, modify, sublicense, link with, -or distribute the Library except as expressly provided under this -License. Any attempt otherwise to copy, modify, sublicense, link -with, or distribute the Library is void, and will automatically -terminate your rights under this License. However, parties who have -received copies, or rights, from you under this License will not have -their licenses terminated so long as such parties remain in full -compliance. -

    -

    -9. -You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. -

    -

    -10. -Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. -

    -

    -11. -If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. -

    -

    -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. -

    -

    -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. -

    -

    -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -

    -

    -12. -If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. -

    -

    -13. -The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. -

    -

    -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. -

    -

    -14. -If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. -

    -

    -NO WARRANTY -

    -

    -15. -BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -

    -

    -16. -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. -

    - -

    END OF TERMS AND CONDITIONS

    - -

    How to Apply These Terms to Your New -Libraries

    -

    - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). -

    -

    - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. -

    - -
    one line to give the library's name and an idea of what it does.
    -Copyright (C) year  name of author
    -
    -This library is free software; you can redistribute it and/or
    -modify it under the terms of the GNU Lesser General Public
    -License as published by the Free Software Foundation; either
    -version 2.1 of the License, or (at your option) any later version.
    -
    -This library is distributed in the hope that it will be useful,
    -but WITHOUT ANY WARRANTY; without even the implied warranty of
    -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    -Lesser General Public License for more details.
    -
    -You should have received a copy of the GNU Lesser General Public
    -License along with this library; if not, write to the Free Software
    -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    -
    - -

    -Also add information on how to contact you by electronic and paper mail. -

    -

    -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: -

    - -
    Yoyodyne, Inc., hereby disclaims all copyright interest in
    -the library `Frob' (a library for tweaking knobs) written
    -by James Random Hacker.
    -
    -signature of Ty Coon, 1 April 1990
    -Ty Coon, President of Vice
    -
    - -

    -That's all there is to it!

    - - - + + + + +About + + +

    About This Content

    + +

    Oct 15, 2015

    +

    License

    + +

    +FreeHEP GraphicsIO is licensed under the terms of the GNU Lesser General Public License v2.1, which is also available at http://www.gnu.org/licenses/old-licenses/lgpl-2.1 +

    + +

    +

    + +

    GNU LESSER GENERAL PUBLIC LICENSE

    +

    +Version 2.1, February 1999 +

    + +
    Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    +51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    +Everyone is permitted to copy and distribute verbatim copies
    +of this license document, but changing it is not allowed.
    +
    +[This is the first released version of the Lesser GPL.  It also counts
    + as the successor of the GNU Library Public License, version 2, hence
    + the version number 2.1.]
    +
    + + +

    Preamble

    + +

    + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. +

    +

    + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. +

    +

    + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. +

    +

    + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. +

    +

    + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. +

    +

    + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. +

    +

    + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +

    +

    + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. +

    +

    + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. +

    +

    + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. +

    +

    + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. +

    +

    + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. +

    +

    + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. +

    +

    + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. +

    +

    + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +

    + +

    TERMS AND CONDITIONS FOR COPYING, +DISTRIBUTION AND MODIFICATION

    + + +

    +0. +This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". +

    +

    + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. +

    +

    + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) +

    +

    + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. +

    +

    + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. +

    +

    +1. +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. +

    +

    + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +

    +

    +2. +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: +

    + +
      +
    • a) + The modified work must itself be a software library.
    • +
    • b) + You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change.
    • + +
    • c) + You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License.
    • + +
    • d) + If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. +

      + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.)

    • +
    + +

    +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be +reasonably considered independent and separate works in themselves, then +this License, and its terms, do not apply to those sections when you +distribute them as separate works. But when you distribute the same +sections as part of a whole which is a work based on the Library, the +distribution of the whole must be on the terms of this License, whose +permissions for other licensees extend to the entire whole, and thus to +each and every part regardless of who wrote it. +

    +

    +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works +based on the Library. +

    +

    +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of +this License. +

    +

    +3. +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +

    +

    + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. +

    +

    + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. +

    +

    +4. +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. +

    +

    + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. +

    +

    +5. +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. +

    +

    + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. +

    +

    + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. +

    +

    + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) +

    +

    + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +

    +

    +6. +As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. +

    +

    + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: +

    + +
      +
    • a) Accompany the work with the complete + corresponding machine-readable source code for the Library + including whatever changes were used in the work (which must be + distributed under Sections 1 and 2 above); and, if the work is an + executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code + and/or source code, so that the user can modify the Library and + then relink to produce a modified executable containing the + modified Library. (It is understood that the user who changes the + contents of definitions files in the Library will not necessarily + be able to recompile the application to use the modified + definitions.)
    • + +
    • b) Use a suitable shared library mechanism + for linking with the Library. A suitable mechanism is one that + (1) uses at run time a copy of the library already present on the + user's computer system, rather than copying library functions into + the executable, and (2) will operate properly with a modified + version of the library, if the user installs one, as long as the + modified version is interface-compatible with the version that the + work was made with.
    • + +
    • c) Accompany the work with a written offer, + valid for at least three years, to give the same user the + materials specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution.
    • + +
    • d) If distribution of the work is made by + offering access to copy from a designated place, offer equivalent + access to copy the above specified materials from the same + place.
    • + +
    • e) Verify that the user has already received + a copy of these materials or that you have already sent this user + a copy.
    • +
    + +

    + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. +

    +

    + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +

    +

    +7. You may place library facilities that are a work +based on the Library side-by-side in a single library together with +other library facilities not covered by this License, and distribute +such a combined library, provided that the separate distribution of +the work based on the Library and of the other library facilities is +otherwise permitted, and provided that you do these two things: +

    + +
      +
    • a) Accompany the combined library with a copy + of the same work based on the Library, uncombined with any other + library facilities. This must be distributed under the terms of + the Sections above.
    • + +
    • b) Give prominent notice with the combined + library of the fact that part of it is a work based on the + Library, and explaining where to find the accompanying uncombined + form of the same work.
    • +
    + +

    +8. You may not copy, modify, sublicense, link with, +or distribute the Library except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense, link +with, or distribute the Library is void, and will automatically +terminate your rights under this License. However, parties who have +received copies, or rights, from you under this License will not have +their licenses terminated so long as such parties remain in full +compliance. +

    +

    +9. +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. +

    +

    +10. +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +

    +

    +11. +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. +

    +

    +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. +

    +

    +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. +

    +

    +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +

    +

    +12. +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. +

    +

    +13. +The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. +

    +

    +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +

    +

    +14. +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. +

    +

    +NO WARRANTY +

    +

    +15. +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +

    +

    +16. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +

    + +

    END OF TERMS AND CONDITIONS

    + +

    How to Apply These Terms to Your New +Libraries

    +

    + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). +

    +

    + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. +

    + +
    one line to give the library's name and an idea of what it does.
    +Copyright (C) year  name of author
    +
    +This library is free software; you can redistribute it and/or
    +modify it under the terms of the GNU Lesser General Public
    +License as published by the Free Software Foundation; either
    +version 2.1 of the License, or (at your option) any later version.
    +
    +This library is distributed in the hope that it will be useful,
    +but WITHOUT ANY WARRANTY; without even the implied warranty of
    +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +Lesser General Public License for more details.
    +
    +You should have received a copy of the GNU Lesser General Public
    +License along with this library; if not, write to the Free Software
    +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    +
    + +

    +Also add information on how to contact you by electronic and paper mail. +

    +

    +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: +

    + +
    Yoyodyne, Inc., hereby disclaims all copyright interest in
    +the library `Frob' (a library for tweaking knobs) written
    +by James Random Hacker.
    +
    +signature of Ty Coon, 1 April 1990
    +Ty Coon, President of Vice
    +
    + +

    +That's all there is to it!

    + + + \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/build.properties b/bundles/org.xmind.org.freehep.vectorgraphics/build.properties index 077590941..fe851b194 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/build.properties +++ b/bundles/org.xmind.org.freehep.vectorgraphics/build.properties @@ -1,7 +1,7 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - OSGI-INF/,\ - .,\ - about.html -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + OSGI-INF/,\ + .,\ + about.html +src.includes = about.html diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml b/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml index 0c7ff56c0..c23e340ef 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml +++ b/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.orbit - org.xmind.org.freehep.vectorgraphics - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.orbit + org.xmind.org.freehep.vectorgraphics + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/AbstractVectorGraphics.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/AbstractVectorGraphics.java index f7f771832..36572caba 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/AbstractVectorGraphics.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/AbstractVectorGraphics.java @@ -1,817 +1,817 @@ -// Copyright 2000-2007, FreeHEP -package org.xmind.org.freehep.graphics2d; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Insets; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Area; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.text.AttributedCharacterIterator; -import java.util.Properties; - -import org.xmind.org.freehep.graphics2d.font.FontUtilities; -import org.xmind.org.freehep.util.UserProperties; - -/** - * This class implements all conversions from integer to double as well as a few - * other convenience functions. It also handles the different drawSymbol and - * fillSymbol methods and print colors. The drawing of framed strings is broken - * down to lower level methods. - * - * @author Simon Fischer - * @author Mark Donszelmann - * @author Steffen Greiffenberg - * @author Jason Wong - */ -public abstract class AbstractVectorGraphics extends VectorGraphics { - - private UserProperties properties; - - private String creator; - - private boolean isDeviceIndependent; - - private SymbolShape cachedShape; - - private int colorMode; - - private Color backgroundColor; - - private Color currentColor; - - private Paint currentPaint; - - private Font currentFont; - - public AbstractVectorGraphics() { - properties = new UserProperties(); - creator = "XMind"; //$NON-NLS-1$ - isDeviceIndependent = false; - cachedShape = new SymbolShape(); - colorMode = PrintColor.COLOR; - - // all of these have to be set in the subclasses - currentFont = null; - backgroundColor = null; - currentColor = null; - currentPaint = null; - } - - protected AbstractVectorGraphics(AbstractVectorGraphics graphics) { - super(); - properties = graphics.properties; - creator = graphics.creator; - isDeviceIndependent = graphics.isDeviceIndependent; - cachedShape = graphics.cachedShape; - - backgroundColor = graphics.backgroundColor; - currentColor = graphics.currentColor; - currentPaint = graphics.currentPaint; - colorMode = graphics.colorMode; - currentFont = graphics.currentFont; - } - - public void setProperties(Properties newProperties) { - if (newProperties == null) - return; - properties.setProperties(newProperties); - } - - protected void initProperties(Properties defaults) { - properties = new UserProperties(); - properties.setProperties(defaults); - } - - protected Properties getProperties() { - return properties; - } - - public String getProperty(String key) { - return properties.getProperty(key); - } - - public Color getPropertyColor(String key) { - return properties.getPropertyColor(key); - } - - public Rectangle getPropertyRectangle(String key) { - return properties.getPropertyRectangle(key); - } - - public Insets getPropertyInsets(String key) { - return properties.getPropertyInsets(key); - } - - public Dimension getPropertyDimension(String key) { - return properties.getPropertyDimension(key); - } - - public int getPropertyInt(String key) { - return properties.getPropertyInt(key); - } - - public double getPropertyDouble(String key) { - return properties.getPropertyDouble(key); - } - - public boolean isProperty(String key) { - return properties.isProperty(key); - } - - public String getCreator() { - return creator; - } - - public void setCreator(String creator) { - if (creator != null) { - this.creator = creator; - } - } - - public boolean isDeviceIndependent() { - return isDeviceIndependent; - } - - public void setDeviceIndependent(boolean isDeviceIndependent) { - this.isDeviceIndependent = isDeviceIndependent; - } - - /** - * Gets the current font. - * - * @return current font - */ - public Font getFont() { - return currentFont; - } - - /** - * Sets the current font. - * - * @param font - * to be set - */ - public void setFont(Font font) { - if (font == null) - return; - - // FIXME: maybe add delayed setting - currentFont = font; - } - - public void drawSymbol(int x, int y, int size, int symbol) { - drawSymbol((double) x, (double) y, (double) size, symbol); - } - - public void fillSymbol(int x, int y, int size, int symbol) { - fillSymbol((double) x, (double) y, (double) size, symbol); - } - - public void fillAndDrawSymbol(int x, int y, int size, int symbol, - Color fillColor) { - fillAndDrawSymbol((double) x, (double) y, (double) size, symbol, - fillColor); - } - - public void drawSymbol(double x, double y, double size, int symbol) { - if (size <= 0) - return; - drawSymbol(this, x, y, size, symbol); - } - - protected void drawSymbol(VectorGraphics g, double x, double y, - double size, int symbol) { - switch (symbol) { - case SYMBOL_VLINE: - case SYMBOL_STAR: - case SYMBOL_HLINE: - case SYMBOL_PLUS: - case SYMBOL_CROSS: - case SYMBOL_BOX: - case SYMBOL_UP_TRIANGLE: - case SYMBOL_DN_TRIANGLE: - case SYMBOL_DIAMOND: - cachedShape.create(symbol, x, y, size); - g.draw(cachedShape); - break; - - case SYMBOL_CIRCLE: { - double diameter = Math.max(1, size); - diameter += (diameter % 2); - g.drawOval(x - diameter / 2, y - diameter / 2, diameter, diameter); - break; - } - } - } - - public void fillSymbol(double x, double y, double size, int symbol) { - if (size <= 0) - return; - fillSymbol(this, x, y, size, symbol); - } - - protected void fillSymbol(VectorGraphics g, double x, double y, - double size, int symbol) { - switch (symbol) { - case SYMBOL_VLINE: - case SYMBOL_STAR: - case SYMBOL_HLINE: - case SYMBOL_PLUS: - case SYMBOL_CROSS: - cachedShape.create(symbol, x, y, size); - g.draw(cachedShape); - break; - - case SYMBOL_BOX: - case SYMBOL_UP_TRIANGLE: - case SYMBOL_DN_TRIANGLE: - case SYMBOL_DIAMOND: - cachedShape.create(symbol, x, y, size); - g.fill(cachedShape); - break; - - case SYMBOL_CIRCLE: { - double diameter = Math.max(1, size); - diameter += (diameter % 2); - g.fillOval(x - diameter / 2, y - diameter / 2, diameter, diameter); - break; - } - } - } - - public void fillAndDrawSymbol(double x, double y, double size, int symbol, - Color fillColor) { - Color color = getColor(); - setColor(fillColor); - fillSymbol(x, y, size, symbol); - setColor(color); - drawSymbol(x, y, size, symbol); - } - - public void fillAndDraw(Shape s, Color fillColor) { - Color color = getColor(); - setColor(fillColor); - fill(s); - setColor(color); - draw(s); - } - - // --------------------------------------------------------- - // -------------------- WRAPPER METHODS -------------------- - // -------------------- int -> double -------------------- - // needs a bias in some cases - // --------------------------------------------------------- - - private static final double bias = 0.5; - - public void clearRect(int x, int y, int width, int height) { - clearRect((double) x + bias, (double) y + bias, (double) width, - (double) height); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - drawLine((double) x1 + bias, (double) y1 + bias, (double) x2 + bias, - (double) y2 + bias); - } - - public void drawRect(int x, int y, int width, int height) { - drawRect((double) x + bias, (double) y + bias, (double) width, - (double) height); - } - - public void fillRect(int x, int y, int width, int height) { - fillRect((double) x, (double) y, (double) width, (double) height); - } - - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - drawArc((double) x + bias, (double) y + bias, (double) width, - (double) height, (double) startAngle, (double) arcAngle); - } - - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - fillArc((double) x, (double) y, (double) width, (double) height, - (double) startAngle, (double) arcAngle); - } - - public void drawOval(int x, int y, int width, int height) { - drawOval((double) x + bias, (double) y + bias, (double) width, - (double) height); - } - - public void fillOval(int x, int y, int width, int height) { - fillOval((double) x, (double) y, (double) width, (double) height); - } - - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - drawRoundRect((double) x + bias, (double) y + bias, (double) width, - (double) height, (double) arcWidth, (double) arcHeight); - } - - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - fillRoundRect((double) x, (double) y, (double) width, (double) height, - (double) arcWidth, (double) arcHeight); - } - - public void translate(int x, int y) { - translate((double) x, (double) y); - } - - /*-------------------------------------------------------------------------------- - | 8.1. stroke/linewidth - *--------------------------------------------------------------------------------*/ - public void setLineWidth(int width) { - setLineWidth((double) width); - } - - public void setLineWidth(double width) { - Stroke stroke = getStroke(); - if (stroke instanceof BasicStroke) { - BasicStroke cs = (BasicStroke) stroke; - if (cs.getLineWidth() != width) { - stroke = new BasicStroke((float) width, cs.getEndCap(), - cs.getLineJoin(), cs.getMiterLimit(), - cs.getDashArray(), cs.getDashPhase()); - setStroke(stroke); - } - } else { - stroke = new BasicStroke((float) width); - setStroke(stroke); - } - } - - public void drawString(String str, int x, int y) { - drawString(str, (double) x, (double) y); - } - - public void drawString(String s, float x, float y) { - drawString(s, (double) x, (double) y); - } - - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - drawString(iterator, (float) x, (float) y); - } - - /** - * Draws frame and banner for a TextLayout, which is used for calculation - * auf ajustment - * - * @param tl - * TextLayout for frame calculation - * @param x - * coordinate to draw string - * @param y - * coordinate to draw string - * @param horizontal - * alignment of the text - * @param vertical - * alignment of the text - * @param framed - * true if text is surrounded by a frame - * @param frameColor - * color of the frame - * @param frameWidth - * witdh of the frame - * @param banner - * true if the frame is filled by a banner - * @param bannerColor - * color of the banner - * @return Offset for the string inside the frame - */ - private Point2D drawFrameAndBanner(TextLayout tl, double x, double y, - int horizontal, int vertical, boolean framed, Color frameColor, - double frameWidth, boolean banner, Color bannerColor) { - - // calculate string bounds for alignment - Rectangle2D bounds = tl.getBounds(); - - // calculate real bounds - bounds.setRect(bounds.getX(), bounds.getY(), - // care for Italic fonts too - Math.max(tl.getAdvance(), bounds.getWidth()), - bounds.getHeight()); - - // add x and y - AffineTransform at = AffineTransform.getTranslateInstance(x, y); - - // horizontal alignment - if (horizontal == TEXT_RIGHT) { - at.translate(-bounds.getWidth(), 0); - } else if (horizontal == TEXT_CENTER) { - at.translate(-bounds.getWidth() / 2, 0); - } - - // vertical alignment - if (vertical == TEXT_BASELINE) { - // no translation needed - } else if (vertical == TEXT_TOP) { - at.translate(0, -bounds.getY()); - } else if (vertical == TEXT_CENTER) { - // the following adds supersript ascent too, - // so it does not work - // at.translate(0, tl.getAscent() / 2); - // this is nearly the same - at.translate(0, tl.getDescent()); - } else if (vertical == TEXT_BOTTOM) { - at.translate(0, -bounds.getHeight() - bounds.getY()); - } - - // transform the bounds - bounds = at.createTransformedShape(bounds).getBounds2D(); - // create the result with the same transformation - Point2D result = at.transform(new Point2D.Double(0, 0), - new Point2D.Double()); - - // space between string and border - double adjustment = (getFont().getSize2D() * 2) / 10; - - // add the adjustment - bounds.setRect(bounds.getX() - adjustment, bounds.getY() - adjustment, - bounds.getWidth() + 2 * adjustment, bounds.getHeight() + 2 - * adjustment); - - if (banner) { - Paint paint = getPaint(); - setColor(bannerColor); - fill(bounds); - setPaint(paint); - } - if (framed) { - Paint paint = getPaint(); - Stroke stroke = getStroke(); - setColor(frameColor); - setLineWidth(frameWidth); - draw(bounds); - setPaint(paint); - setStroke(stroke); - } - - return result; - } - - /** - * Draws frame, banner and aligned text inside - * - * @param str - * text to be drawn - * @param x - * coordinate to draw string - * @param y - * coordinate to draw string - * @param horizontal - * alignment of the text - * @param vertical - * alignment of the text - * @param framed - * true if text is surrounded by a frame - * @param frameColor - * color of the frame - * @param frameWidth - * witdh of the frame - * @param banner - * true if the frame is filled by a banner - * @param bannerColor - * color of the banner - */ - public void drawString(String str, double x, double y, int horizontal, - int vertical, boolean framed, Color frameColor, double frameWidth, - boolean banner, Color bannerColor) { - - // change the x offset for the next drawing - // FIXME: change y offset for vertical text - TextLayout tl = new TextLayout(str, - FontUtilities.getAttributes(getFont()), getFontRenderContext()); - - // draw the frame - Point2D offset = drawFrameAndBanner(tl, x, y, horizontal, vertical, - framed, frameColor, frameWidth, banner, bannerColor); - - // draw the string - drawString(str, offset.getX(), offset.getY()); - } - - /** - * Draws the tagged string parsed by a {@link TagHandler} and adds a border - * specified by the parameters - * - * @param str - * Tagged text to be drawn - * @param x - * coordinate to draw string - * @param y - * coordinate to draw string - * @param horizontal - * alignment of the text - * @param vertical - * alignment of the text - * @param framed - * true if text is surrounded by a frame - * @param frameColor - * color of the frame - * @param frameWidth - * witdh of the frame - * @param banner - * true if the frame is filled by a banner - * @param bannerColor - * color of the banner - */ - public void drawString(TagString str, double x, double y, int horizontal, - int vertical, boolean framed, Color frameColor, double frameWidth, - boolean banner, Color bannerColor) { - - GenericTagHandler tagHandler = new GenericTagHandler(this); - TextLayout tl = tagHandler.createTextLayout(str, - getFont().getSize2D() / 7.5); - - // draw the frame - Point2D offset = drawFrameAndBanner(tl, x, y, horizontal, vertical, - framed, frameColor, frameWidth, banner, bannerColor); - - // FIXME: not quite clear why correction is needed - // see {@link GenericTagHandler#superscriptCorrection - tagHandler.print(str, offset.getX(), offset.getY(), getFont() - .getSize2D() / 7.5); - } - - // ------------------ other wrapper methods ---------------- - - public void drawString(String str, double x, double y, int horizontal, - int vertical) { - drawString(str, x, y, horizontal, vertical, false, null, 0, false, null); - } - - public void drawString(TagString str, double x, double y) { - drawString(str, x, y, TEXT_LEFT, TEXT_BASELINE); - } - - public void drawString(TagString str, double x, double y, int horizontal, - int vertical) { - drawString(str, x, y, horizontal, vertical, false, null, 0, false, null); - } - - /* 8.2. paint/color */ - public int getColorMode() { - return colorMode; - } - - public void setColorMode(int colorMode) { - this.colorMode = colorMode; - } - - /** - * Gets the background color. - * - * @return background color - */ - public Color getBackground() { - return backgroundColor; - } - - /** - * Sets the background color. - * - * @param color - * background color to be set - */ - public void setBackground(Color color) { - backgroundColor = color; - } - - /** - * Sets the current color and the current paint. Calls writePaint(Color). - * - * @param color - * to be set - */ - public void setColor(Color color) { - if (color == null) - return; - - currentColor = color; - currentPaint = color; - } - - /** - * Gets the current color. - * - * @return the current color - */ - public Color getColor() { - return currentColor; - } - - /** - * Sets the current paint. - * - * @param paint - * to be set - */ - public void setPaint(Paint paint) { - if (paint == null) - return; - - if (!(paint instanceof Color)) - currentColor = null; - currentPaint = paint; - } - - /** - * Gets the current paint. - * - * @return paint current paint - */ - public Paint getPaint() { - return currentPaint; - } - - /** - * Returns a printColor created from the original printColor, based on the - * ColorMode. If you run getPrintColor on it again you still get the same - * color, so that it does not matter if you convert it more than once. - */ - protected Color getPrintColor(Color color) { - // shortcut if mode is COLOR for speed - if (colorMode == PrintColor.COLOR) - return color; - - // otherwise... - PrintColor printColor = PrintColor.createPrintColor(color); - return printColor.getColor(colorMode); - } - - public void rotate(double theta, double x, double y) { - translate(x, y); - rotate(theta); - translate(-x, -y); - } - - public void drawArc(double x, double y, double width, double height, - double startAngle, double arcAngle) { - draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, - Arc2D.OPEN)); - } - - public void drawLine(double x1, double y1, double x2, double y2) { - draw(new Line2D.Double(x1, y1, x2, y2)); - } - - public void drawOval(double x, double y, double width, double height) { - draw(new Ellipse2D.Double(x, y, width, height)); - } - - public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { - draw(createShape(xPoints, yPoints, nPoints, false, true)); - } - - public void drawPolyline(double[] xPoints, double[] yPoints, int nPoints) { - draw(createShape(xPoints, yPoints, nPoints, false)); - } - - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { - draw(createShape(xPoints, yPoints, nPoints, true, true)); - } - - public void drawPolygon(double[] xPoints, double[] yPoints, int nPoints) { - draw(createShape(xPoints, yPoints, nPoints, true)); - } - - public void drawRect(double x, double y, double width, double height) { - draw(new Rectangle2D.Double(x, y, width, height)); - } - - public void drawRoundRect(double x, double y, double width, double height, - double arcWidth, double arcHeight) { - draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth, - arcHeight)); - } - - public void fillArc(double x, double y, double width, double height, - double startAngle, double arcAngle) { - fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, - Arc2D.PIE)); - } - - public void fillOval(double x, double y, double width, double height) { - fill(new Ellipse2D.Double(x, y, width, height)); - } - - public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { - fill(createShape(xPoints, yPoints, nPoints, true, false)); - } - - public void fillPolygon(double[] xPoints, double[] yPoints, int nPoints) { - fill(createShape(xPoints, yPoints, nPoints, true)); - } - - public void fillRect(double x, double y, double width, double height) { - fill(new Rectangle2D.Double(x, y, width, height)); - } - - public void fillRoundRect(double x, double y, double width, double height, - double arcWidth, double arcHeight) { - fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth, - arcHeight)); - } - - /** - * Creates a polyline/polygon shape from a set of points. Needs to be - * defined in subclass because its implementations could be device specific - * - * @param xPoints - * X coordinates of the polyline. - * @param yPoints - * Y coordinates of the polyline. - * @param nPoints - * number of points of the polyline. - * @param close - * is shape closed - */ - protected abstract Shape createShape(double[] xPoints, double[] yPoints, - int nPoints, boolean close); - - /** - * Creates a polyline/polygon shape from a set of points. Needs a bias! - * - * @param xPoints - * X coordinates of the polyline. - * @param yPoints - * Y coordinates of the polyline. - * @param nPoints - * number of points of the polyline. - * @param close - * is shape closed - */ - protected Shape createShape(int[] xPoints, int[] yPoints, int nPoints, - boolean close, boolean biased) { - - float offset = biased ? (float) bias : 0.0f; - GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); - if (nPoints > 0) { - path.moveTo(xPoints[0] + offset, yPoints[0] + offset); - int lastX = xPoints[0]; - int lastY = yPoints[0]; - if (close && (Math.abs(xPoints[nPoints - 1] - lastX) < 1) - && (Math.abs(yPoints[nPoints - 1] - lastY) < 1)) { - nPoints--; - } - for (int i = 1; i < nPoints; i++) { - if ((Math.abs(xPoints[i] - lastX) > 1) - || (Math.abs(yPoints[i] - lastY) > 1)) { - path.lineTo(xPoints[i] + offset, yPoints[i] + offset); - lastX = xPoints[i]; - lastY = yPoints[i]; - } - } - if (close) - path.closePath(); - } - return path; - } - - /** - * Checks whether or not the specified Shape intersects the - * specified {@link Rectangle}, which is in device space. - * - * @param rect - * the area in device space to check for a hit - * @param s - * the Shape to check for a hit - * @param onStroke - * flag used to choose between testing the stroked or the filled - * shape. - * @see java.awt.Graphics2D#hit(Rectangle, Shape, boolean) - */ - public boolean hit(Rectangle rect, Shape s, boolean onStroke) { - if (onStroke && getStroke() != null) { - s = getStroke().createStrokedShape(s); - } - - if (getTransform() != null) { - s = getTransform().createTransformedShape(s); - } - - Area area = new Area(s); - if (getClip() != null) { - area.intersect(new Area(getClip())); - } - - return area.intersects(rect); - } -} +// Copyright 2000-2007, FreeHEP +package org.xmind.org.freehep.graphics2d; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Insets; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.text.AttributedCharacterIterator; +import java.util.Properties; + +import org.xmind.org.freehep.graphics2d.font.FontUtilities; +import org.xmind.org.freehep.util.UserProperties; + +/** + * This class implements all conversions from integer to double as well as a few + * other convenience functions. It also handles the different drawSymbol and + * fillSymbol methods and print colors. The drawing of framed strings is broken + * down to lower level methods. + * + * @author Simon Fischer + * @author Mark Donszelmann + * @author Steffen Greiffenberg + * @author Jason Wong + */ +public abstract class AbstractVectorGraphics extends VectorGraphics { + + private UserProperties properties; + + private String creator; + + private boolean isDeviceIndependent; + + private SymbolShape cachedShape; + + private int colorMode; + + private Color backgroundColor; + + private Color currentColor; + + private Paint currentPaint; + + private Font currentFont; + + public AbstractVectorGraphics() { + properties = new UserProperties(); + creator = "XMind"; //$NON-NLS-1$ + isDeviceIndependent = false; + cachedShape = new SymbolShape(); + colorMode = PrintColor.COLOR; + + // all of these have to be set in the subclasses + currentFont = null; + backgroundColor = null; + currentColor = null; + currentPaint = null; + } + + protected AbstractVectorGraphics(AbstractVectorGraphics graphics) { + super(); + properties = graphics.properties; + creator = graphics.creator; + isDeviceIndependent = graphics.isDeviceIndependent; + cachedShape = graphics.cachedShape; + + backgroundColor = graphics.backgroundColor; + currentColor = graphics.currentColor; + currentPaint = graphics.currentPaint; + colorMode = graphics.colorMode; + currentFont = graphics.currentFont; + } + + public void setProperties(Properties newProperties) { + if (newProperties == null) + return; + properties.setProperties(newProperties); + } + + protected void initProperties(Properties defaults) { + properties = new UserProperties(); + properties.setProperties(defaults); + } + + protected Properties getProperties() { + return properties; + } + + public String getProperty(String key) { + return properties.getProperty(key); + } + + public Color getPropertyColor(String key) { + return properties.getPropertyColor(key); + } + + public Rectangle getPropertyRectangle(String key) { + return properties.getPropertyRectangle(key); + } + + public Insets getPropertyInsets(String key) { + return properties.getPropertyInsets(key); + } + + public Dimension getPropertyDimension(String key) { + return properties.getPropertyDimension(key); + } + + public int getPropertyInt(String key) { + return properties.getPropertyInt(key); + } + + public double getPropertyDouble(String key) { + return properties.getPropertyDouble(key); + } + + public boolean isProperty(String key) { + return properties.isProperty(key); + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + if (creator != null) { + this.creator = creator; + } + } + + public boolean isDeviceIndependent() { + return isDeviceIndependent; + } + + public void setDeviceIndependent(boolean isDeviceIndependent) { + this.isDeviceIndependent = isDeviceIndependent; + } + + /** + * Gets the current font. + * + * @return current font + */ + public Font getFont() { + return currentFont; + } + + /** + * Sets the current font. + * + * @param font + * to be set + */ + public void setFont(Font font) { + if (font == null) + return; + + // FIXME: maybe add delayed setting + currentFont = font; + } + + public void drawSymbol(int x, int y, int size, int symbol) { + drawSymbol((double) x, (double) y, (double) size, symbol); + } + + public void fillSymbol(int x, int y, int size, int symbol) { + fillSymbol((double) x, (double) y, (double) size, symbol); + } + + public void fillAndDrawSymbol(int x, int y, int size, int symbol, + Color fillColor) { + fillAndDrawSymbol((double) x, (double) y, (double) size, symbol, + fillColor); + } + + public void drawSymbol(double x, double y, double size, int symbol) { + if (size <= 0) + return; + drawSymbol(this, x, y, size, symbol); + } + + protected void drawSymbol(VectorGraphics g, double x, double y, + double size, int symbol) { + switch (symbol) { + case SYMBOL_VLINE: + case SYMBOL_STAR: + case SYMBOL_HLINE: + case SYMBOL_PLUS: + case SYMBOL_CROSS: + case SYMBOL_BOX: + case SYMBOL_UP_TRIANGLE: + case SYMBOL_DN_TRIANGLE: + case SYMBOL_DIAMOND: + cachedShape.create(symbol, x, y, size); + g.draw(cachedShape); + break; + + case SYMBOL_CIRCLE: { + double diameter = Math.max(1, size); + diameter += (diameter % 2); + g.drawOval(x - diameter / 2, y - diameter / 2, diameter, diameter); + break; + } + } + } + + public void fillSymbol(double x, double y, double size, int symbol) { + if (size <= 0) + return; + fillSymbol(this, x, y, size, symbol); + } + + protected void fillSymbol(VectorGraphics g, double x, double y, + double size, int symbol) { + switch (symbol) { + case SYMBOL_VLINE: + case SYMBOL_STAR: + case SYMBOL_HLINE: + case SYMBOL_PLUS: + case SYMBOL_CROSS: + cachedShape.create(symbol, x, y, size); + g.draw(cachedShape); + break; + + case SYMBOL_BOX: + case SYMBOL_UP_TRIANGLE: + case SYMBOL_DN_TRIANGLE: + case SYMBOL_DIAMOND: + cachedShape.create(symbol, x, y, size); + g.fill(cachedShape); + break; + + case SYMBOL_CIRCLE: { + double diameter = Math.max(1, size); + diameter += (diameter % 2); + g.fillOval(x - diameter / 2, y - diameter / 2, diameter, diameter); + break; + } + } + } + + public void fillAndDrawSymbol(double x, double y, double size, int symbol, + Color fillColor) { + Color color = getColor(); + setColor(fillColor); + fillSymbol(x, y, size, symbol); + setColor(color); + drawSymbol(x, y, size, symbol); + } + + public void fillAndDraw(Shape s, Color fillColor) { + Color color = getColor(); + setColor(fillColor); + fill(s); + setColor(color); + draw(s); + } + + // --------------------------------------------------------- + // -------------------- WRAPPER METHODS -------------------- + // -------------------- int -> double -------------------- + // needs a bias in some cases + // --------------------------------------------------------- + + private static final double bias = 0.5; + + public void clearRect(int x, int y, int width, int height) { + clearRect((double) x + bias, (double) y + bias, (double) width, + (double) height); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + drawLine((double) x1 + bias, (double) y1 + bias, (double) x2 + bias, + (double) y2 + bias); + } + + public void drawRect(int x, int y, int width, int height) { + drawRect((double) x + bias, (double) y + bias, (double) width, + (double) height); + } + + public void fillRect(int x, int y, int width, int height) { + fillRect((double) x, (double) y, (double) width, (double) height); + } + + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + drawArc((double) x + bias, (double) y + bias, (double) width, + (double) height, (double) startAngle, (double) arcAngle); + } + + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + fillArc((double) x, (double) y, (double) width, (double) height, + (double) startAngle, (double) arcAngle); + } + + public void drawOval(int x, int y, int width, int height) { + drawOval((double) x + bias, (double) y + bias, (double) width, + (double) height); + } + + public void fillOval(int x, int y, int width, int height) { + fillOval((double) x, (double) y, (double) width, (double) height); + } + + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + drawRoundRect((double) x + bias, (double) y + bias, (double) width, + (double) height, (double) arcWidth, (double) arcHeight); + } + + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + fillRoundRect((double) x, (double) y, (double) width, (double) height, + (double) arcWidth, (double) arcHeight); + } + + public void translate(int x, int y) { + translate((double) x, (double) y); + } + + /*-------------------------------------------------------------------------------- + | 8.1. stroke/linewidth + *--------------------------------------------------------------------------------*/ + public void setLineWidth(int width) { + setLineWidth((double) width); + } + + public void setLineWidth(double width) { + Stroke stroke = getStroke(); + if (stroke instanceof BasicStroke) { + BasicStroke cs = (BasicStroke) stroke; + if (cs.getLineWidth() != width) { + stroke = new BasicStroke((float) width, cs.getEndCap(), + cs.getLineJoin(), cs.getMiterLimit(), + cs.getDashArray(), cs.getDashPhase()); + setStroke(stroke); + } + } else { + stroke = new BasicStroke((float) width); + setStroke(stroke); + } + } + + public void drawString(String str, int x, int y) { + drawString(str, (double) x, (double) y); + } + + public void drawString(String s, float x, float y) { + drawString(s, (double) x, (double) y); + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + drawString(iterator, (float) x, (float) y); + } + + /** + * Draws frame and banner for a TextLayout, which is used for calculation + * auf ajustment + * + * @param tl + * TextLayout for frame calculation + * @param x + * coordinate to draw string + * @param y + * coordinate to draw string + * @param horizontal + * alignment of the text + * @param vertical + * alignment of the text + * @param framed + * true if text is surrounded by a frame + * @param frameColor + * color of the frame + * @param frameWidth + * witdh of the frame + * @param banner + * true if the frame is filled by a banner + * @param bannerColor + * color of the banner + * @return Offset for the string inside the frame + */ + private Point2D drawFrameAndBanner(TextLayout tl, double x, double y, + int horizontal, int vertical, boolean framed, Color frameColor, + double frameWidth, boolean banner, Color bannerColor) { + + // calculate string bounds for alignment + Rectangle2D bounds = tl.getBounds(); + + // calculate real bounds + bounds.setRect(bounds.getX(), bounds.getY(), + // care for Italic fonts too + Math.max(tl.getAdvance(), bounds.getWidth()), + bounds.getHeight()); + + // add x and y + AffineTransform at = AffineTransform.getTranslateInstance(x, y); + + // horizontal alignment + if (horizontal == TEXT_RIGHT) { + at.translate(-bounds.getWidth(), 0); + } else if (horizontal == TEXT_CENTER) { + at.translate(-bounds.getWidth() / 2, 0); + } + + // vertical alignment + if (vertical == TEXT_BASELINE) { + // no translation needed + } else if (vertical == TEXT_TOP) { + at.translate(0, -bounds.getY()); + } else if (vertical == TEXT_CENTER) { + // the following adds supersript ascent too, + // so it does not work + // at.translate(0, tl.getAscent() / 2); + // this is nearly the same + at.translate(0, tl.getDescent()); + } else if (vertical == TEXT_BOTTOM) { + at.translate(0, -bounds.getHeight() - bounds.getY()); + } + + // transform the bounds + bounds = at.createTransformedShape(bounds).getBounds2D(); + // create the result with the same transformation + Point2D result = at.transform(new Point2D.Double(0, 0), + new Point2D.Double()); + + // space between string and border + double adjustment = (getFont().getSize2D() * 2) / 10; + + // add the adjustment + bounds.setRect(bounds.getX() - adjustment, bounds.getY() - adjustment, + bounds.getWidth() + 2 * adjustment, bounds.getHeight() + 2 + * adjustment); + + if (banner) { + Paint paint = getPaint(); + setColor(bannerColor); + fill(bounds); + setPaint(paint); + } + if (framed) { + Paint paint = getPaint(); + Stroke stroke = getStroke(); + setColor(frameColor); + setLineWidth(frameWidth); + draw(bounds); + setPaint(paint); + setStroke(stroke); + } + + return result; + } + + /** + * Draws frame, banner and aligned text inside + * + * @param str + * text to be drawn + * @param x + * coordinate to draw string + * @param y + * coordinate to draw string + * @param horizontal + * alignment of the text + * @param vertical + * alignment of the text + * @param framed + * true if text is surrounded by a frame + * @param frameColor + * color of the frame + * @param frameWidth + * witdh of the frame + * @param banner + * true if the frame is filled by a banner + * @param bannerColor + * color of the banner + */ + public void drawString(String str, double x, double y, int horizontal, + int vertical, boolean framed, Color frameColor, double frameWidth, + boolean banner, Color bannerColor) { + + // change the x offset for the next drawing + // FIXME: change y offset for vertical text + TextLayout tl = new TextLayout(str, + FontUtilities.getAttributes(getFont()), getFontRenderContext()); + + // draw the frame + Point2D offset = drawFrameAndBanner(tl, x, y, horizontal, vertical, + framed, frameColor, frameWidth, banner, bannerColor); + + // draw the string + drawString(str, offset.getX(), offset.getY()); + } + + /** + * Draws the tagged string parsed by a {@link TagHandler} and adds a border + * specified by the parameters + * + * @param str + * Tagged text to be drawn + * @param x + * coordinate to draw string + * @param y + * coordinate to draw string + * @param horizontal + * alignment of the text + * @param vertical + * alignment of the text + * @param framed + * true if text is surrounded by a frame + * @param frameColor + * color of the frame + * @param frameWidth + * witdh of the frame + * @param banner + * true if the frame is filled by a banner + * @param bannerColor + * color of the banner + */ + public void drawString(TagString str, double x, double y, int horizontal, + int vertical, boolean framed, Color frameColor, double frameWidth, + boolean banner, Color bannerColor) { + + GenericTagHandler tagHandler = new GenericTagHandler(this); + TextLayout tl = tagHandler.createTextLayout(str, + getFont().getSize2D() / 7.5); + + // draw the frame + Point2D offset = drawFrameAndBanner(tl, x, y, horizontal, vertical, + framed, frameColor, frameWidth, banner, bannerColor); + + // FIXME: not quite clear why correction is needed + // see {@link GenericTagHandler#superscriptCorrection + tagHandler.print(str, offset.getX(), offset.getY(), getFont() + .getSize2D() / 7.5); + } + + // ------------------ other wrapper methods ---------------- + + public void drawString(String str, double x, double y, int horizontal, + int vertical) { + drawString(str, x, y, horizontal, vertical, false, null, 0, false, null); + } + + public void drawString(TagString str, double x, double y) { + drawString(str, x, y, TEXT_LEFT, TEXT_BASELINE); + } + + public void drawString(TagString str, double x, double y, int horizontal, + int vertical) { + drawString(str, x, y, horizontal, vertical, false, null, 0, false, null); + } + + /* 8.2. paint/color */ + public int getColorMode() { + return colorMode; + } + + public void setColorMode(int colorMode) { + this.colorMode = colorMode; + } + + /** + * Gets the background color. + * + * @return background color + */ + public Color getBackground() { + return backgroundColor; + } + + /** + * Sets the background color. + * + * @param color + * background color to be set + */ + public void setBackground(Color color) { + backgroundColor = color; + } + + /** + * Sets the current color and the current paint. Calls writePaint(Color). + * + * @param color + * to be set + */ + public void setColor(Color color) { + if (color == null) + return; + + currentColor = color; + currentPaint = color; + } + + /** + * Gets the current color. + * + * @return the current color + */ + public Color getColor() { + return currentColor; + } + + /** + * Sets the current paint. + * + * @param paint + * to be set + */ + public void setPaint(Paint paint) { + if (paint == null) + return; + + if (!(paint instanceof Color)) + currentColor = null; + currentPaint = paint; + } + + /** + * Gets the current paint. + * + * @return paint current paint + */ + public Paint getPaint() { + return currentPaint; + } + + /** + * Returns a printColor created from the original printColor, based on the + * ColorMode. If you run getPrintColor on it again you still get the same + * color, so that it does not matter if you convert it more than once. + */ + protected Color getPrintColor(Color color) { + // shortcut if mode is COLOR for speed + if (colorMode == PrintColor.COLOR) + return color; + + // otherwise... + PrintColor printColor = PrintColor.createPrintColor(color); + return printColor.getColor(colorMode); + } + + public void rotate(double theta, double x, double y) { + translate(x, y); + rotate(theta); + translate(-x, -y); + } + + public void drawArc(double x, double y, double width, double height, + double startAngle, double arcAngle) { + draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, + Arc2D.OPEN)); + } + + public void drawLine(double x1, double y1, double x2, double y2) { + draw(new Line2D.Double(x1, y1, x2, y2)); + } + + public void drawOval(double x, double y, double width, double height) { + draw(new Ellipse2D.Double(x, y, width, height)); + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + draw(createShape(xPoints, yPoints, nPoints, false, true)); + } + + public void drawPolyline(double[] xPoints, double[] yPoints, int nPoints) { + draw(createShape(xPoints, yPoints, nPoints, false)); + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + draw(createShape(xPoints, yPoints, nPoints, true, true)); + } + + public void drawPolygon(double[] xPoints, double[] yPoints, int nPoints) { + draw(createShape(xPoints, yPoints, nPoints, true)); + } + + public void drawRect(double x, double y, double width, double height) { + draw(new Rectangle2D.Double(x, y, width, height)); + } + + public void drawRoundRect(double x, double y, double width, double height, + double arcWidth, double arcHeight) { + draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth, + arcHeight)); + } + + public void fillArc(double x, double y, double width, double height, + double startAngle, double arcAngle) { + fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, + Arc2D.PIE)); + } + + public void fillOval(double x, double y, double width, double height) { + fill(new Ellipse2D.Double(x, y, width, height)); + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + fill(createShape(xPoints, yPoints, nPoints, true, false)); + } + + public void fillPolygon(double[] xPoints, double[] yPoints, int nPoints) { + fill(createShape(xPoints, yPoints, nPoints, true)); + } + + public void fillRect(double x, double y, double width, double height) { + fill(new Rectangle2D.Double(x, y, width, height)); + } + + public void fillRoundRect(double x, double y, double width, double height, + double arcWidth, double arcHeight) { + fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth, + arcHeight)); + } + + /** + * Creates a polyline/polygon shape from a set of points. Needs to be + * defined in subclass because its implementations could be device specific + * + * @param xPoints + * X coordinates of the polyline. + * @param yPoints + * Y coordinates of the polyline. + * @param nPoints + * number of points of the polyline. + * @param close + * is shape closed + */ + protected abstract Shape createShape(double[] xPoints, double[] yPoints, + int nPoints, boolean close); + + /** + * Creates a polyline/polygon shape from a set of points. Needs a bias! + * + * @param xPoints + * X coordinates of the polyline. + * @param yPoints + * Y coordinates of the polyline. + * @param nPoints + * number of points of the polyline. + * @param close + * is shape closed + */ + protected Shape createShape(int[] xPoints, int[] yPoints, int nPoints, + boolean close, boolean biased) { + + float offset = biased ? (float) bias : 0.0f; + GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + if (nPoints > 0) { + path.moveTo(xPoints[0] + offset, yPoints[0] + offset); + int lastX = xPoints[0]; + int lastY = yPoints[0]; + if (close && (Math.abs(xPoints[nPoints - 1] - lastX) < 1) + && (Math.abs(yPoints[nPoints - 1] - lastY) < 1)) { + nPoints--; + } + for (int i = 1; i < nPoints; i++) { + if ((Math.abs(xPoints[i] - lastX) > 1) + || (Math.abs(yPoints[i] - lastY) > 1)) { + path.lineTo(xPoints[i] + offset, yPoints[i] + offset); + lastX = xPoints[i]; + lastY = yPoints[i]; + } + } + if (close) + path.closePath(); + } + return path; + } + + /** + * Checks whether or not the specified Shape intersects the + * specified {@link Rectangle}, which is in device space. + * + * @param rect + * the area in device space to check for a hit + * @param s + * the Shape to check for a hit + * @param onStroke + * flag used to choose between testing the stroked or the filled + * shape. + * @see java.awt.Graphics2D#hit(Rectangle, Shape, boolean) + */ + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + if (onStroke && getStroke() != null) { + s = getStroke().createStrokedShape(s); + } + + if (getTransform() != null) { + s = getTransform().createTransformedShape(s); + } + + Area area = new Area(s); + if (getClip() != null) { + area.intersect(new Area(getClip())); + } + + return area.intersects(rect); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/ArrayPath.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/ArrayPath.java index 88a7a60a4..28f76e949 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/ArrayPath.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/ArrayPath.java @@ -1,197 +1,197 @@ -// Copyright 2004, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -/** - * This class can be used in a transient way to deal with the drawing or filling - * of an array of double points as a polyline/polygon. The class implements a - * shape and comes with an associated iterator. - * - * @author Mark Donszelmann - * @version $Id: ArrayPath.java 8584 2006-08-10 23:06:37Z duns $ - */ -public class ArrayPath implements Shape { - - private class ArrayPathIterator implements PathIterator { - - private double[] xPoints, yPoints; - - private double lastX, lastY; - - private int nPoints; - - private boolean closed; - - private int resolution; - - private int currentPoint; - - private boolean isDone; - - private ArrayPathIterator(double[] xPoints, double[] yPoints, - int nPoints, boolean closed, int resolution) { - this.xPoints = xPoints; - this.yPoints = yPoints; - this.nPoints = nPoints; - this.closed = closed; - this.resolution = resolution; - currentPoint = 0; - isDone = nPoints == 0; - } - - public boolean isDone() { - return isDone; - } - - public void next() { - currentPoint++; - while ((currentPoint < nPoints - 1) - && (Math.abs(xPoints[currentPoint] - lastX) < resolution) - && (Math.abs(yPoints[currentPoint] - lastY) < resolution)) { - currentPoint++; - } - - if (closed - && (currentPoint == nPoints - 1) - && (Math.abs(xPoints[currentPoint] - xPoints[0]) < resolution) - && (Math.abs(yPoints[currentPoint] - yPoints[0]) < resolution)) { - currentPoint++; // skip last point since it is same as first - } - - isDone = (closed) ? currentPoint > nPoints - : currentPoint >= nPoints; - } - - public int currentSegment(double[] coords) { - if (closed && (currentPoint == nPoints)) { - return PathIterator.SEG_CLOSE; - } - - coords[0] = lastX = xPoints[currentPoint]; - coords[1] = lastY = yPoints[currentPoint]; - return (currentPoint == 0) ? PathIterator.SEG_MOVETO - : PathIterator.SEG_LINETO; - } - - public int currentSegment(float[] coords) { - if (closed && (currentPoint == nPoints)) { - return PathIterator.SEG_CLOSE; - } - - lastX = xPoints[currentPoint]; - lastY = yPoints[currentPoint]; - coords[0] = (float) lastX; - coords[1] = (float) lastY; - return (currentPoint == 0) ? PathIterator.SEG_MOVETO - : PathIterator.SEG_LINETO; - } - - public int getWindingRule() { - return PathIterator.WIND_NON_ZERO; - } - } - - private double[] xPoints, yPoints; - - private int nPoints; - - private boolean closed; - - private int resolution; - - public ArrayPath(double[] xPoints, double[] yPoints, int nPoints, - boolean closed, int resolution) { - this.xPoints = xPoints; - this.yPoints = yPoints; - this.nPoints = nPoints; - this.closed = closed; - this.resolution = resolution; - } - - public boolean contains(double x, double y) { - // conservative guess - return false; - } - - public boolean contains(double x, double y, double w, double h) { - // conservative guess - return false; - } - - public boolean contains(Point2D p) { - return contains(p.getX(), p.getY()); - } - - public boolean contains(Rectangle2D r) { - return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - public boolean intersects(double x, double y, double w, double h) { - // conservative guess - return true; - } - - public boolean intersects(Rectangle2D r) { - return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - public PathIterator getPathIterator(AffineTransform at, double flatness) { - return getPathIterator(at); - } - - public Rectangle2D getBounds2D() { - double x1, y1, x2, y2; - int i = nPoints; - if (i > 0) { - i--; - y1 = y2 = yPoints[i]; - x1 = x2 = xPoints[i]; - while (i > 0) { - i--; - double y = yPoints[i]; - double x = xPoints[i]; - if (x < x1) - x1 = x; - if (y < y1) - y1 = y; - if (x > x2) - x2 = x; - if (y > y2) - y2 = y; - } - } else { - x1 = y1 = x2 = y2 = 0.0f; - } - return new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1); - } - - public Rectangle getBounds() { - return getBounds2D().getBounds(); - } - - public PathIterator getPathIterator(AffineTransform t) { - double[] transformedXPoints = xPoints; - double[] transformedYPoints = yPoints; - if (t != null) { - // FIXME, this seems a silly slow way to deal with this. - transformedXPoints = new double[nPoints]; - transformedYPoints = new double[nPoints]; - Point2D s = new Point2D.Double(); - Point2D d = new Point2D.Double(); - for (int i = 0; i < nPoints; i++) { - s.setLocation(xPoints[i], yPoints[i]); - t.transform(s, d); - transformedXPoints[i] = d.getX(); - transformedYPoints[i] = d.getY(); - } - } - return new ArrayPathIterator(transformedXPoints, transformedYPoints, - nPoints, closed, resolution); - } -} +// Copyright 2004, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +/** + * This class can be used in a transient way to deal with the drawing or filling + * of an array of double points as a polyline/polygon. The class implements a + * shape and comes with an associated iterator. + * + * @author Mark Donszelmann + * @version $Id: ArrayPath.java 8584 2006-08-10 23:06:37Z duns $ + */ +public class ArrayPath implements Shape { + + private class ArrayPathIterator implements PathIterator { + + private double[] xPoints, yPoints; + + private double lastX, lastY; + + private int nPoints; + + private boolean closed; + + private int resolution; + + private int currentPoint; + + private boolean isDone; + + private ArrayPathIterator(double[] xPoints, double[] yPoints, + int nPoints, boolean closed, int resolution) { + this.xPoints = xPoints; + this.yPoints = yPoints; + this.nPoints = nPoints; + this.closed = closed; + this.resolution = resolution; + currentPoint = 0; + isDone = nPoints == 0; + } + + public boolean isDone() { + return isDone; + } + + public void next() { + currentPoint++; + while ((currentPoint < nPoints - 1) + && (Math.abs(xPoints[currentPoint] - lastX) < resolution) + && (Math.abs(yPoints[currentPoint] - lastY) < resolution)) { + currentPoint++; + } + + if (closed + && (currentPoint == nPoints - 1) + && (Math.abs(xPoints[currentPoint] - xPoints[0]) < resolution) + && (Math.abs(yPoints[currentPoint] - yPoints[0]) < resolution)) { + currentPoint++; // skip last point since it is same as first + } + + isDone = (closed) ? currentPoint > nPoints + : currentPoint >= nPoints; + } + + public int currentSegment(double[] coords) { + if (closed && (currentPoint == nPoints)) { + return PathIterator.SEG_CLOSE; + } + + coords[0] = lastX = xPoints[currentPoint]; + coords[1] = lastY = yPoints[currentPoint]; + return (currentPoint == 0) ? PathIterator.SEG_MOVETO + : PathIterator.SEG_LINETO; + } + + public int currentSegment(float[] coords) { + if (closed && (currentPoint == nPoints)) { + return PathIterator.SEG_CLOSE; + } + + lastX = xPoints[currentPoint]; + lastY = yPoints[currentPoint]; + coords[0] = (float) lastX; + coords[1] = (float) lastY; + return (currentPoint == 0) ? PathIterator.SEG_MOVETO + : PathIterator.SEG_LINETO; + } + + public int getWindingRule() { + return PathIterator.WIND_NON_ZERO; + } + } + + private double[] xPoints, yPoints; + + private int nPoints; + + private boolean closed; + + private int resolution; + + public ArrayPath(double[] xPoints, double[] yPoints, int nPoints, + boolean closed, int resolution) { + this.xPoints = xPoints; + this.yPoints = yPoints; + this.nPoints = nPoints; + this.closed = closed; + this.resolution = resolution; + } + + public boolean contains(double x, double y) { + // conservative guess + return false; + } + + public boolean contains(double x, double y, double w, double h) { + // conservative guess + return false; + } + + public boolean contains(Point2D p) { + return contains(p.getX(), p.getY()); + } + + public boolean contains(Rectangle2D r) { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + public boolean intersects(double x, double y, double w, double h) { + // conservative guess + return true; + } + + public boolean intersects(Rectangle2D r) { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + public PathIterator getPathIterator(AffineTransform at, double flatness) { + return getPathIterator(at); + } + + public Rectangle2D getBounds2D() { + double x1, y1, x2, y2; + int i = nPoints; + if (i > 0) { + i--; + y1 = y2 = yPoints[i]; + x1 = x2 = xPoints[i]; + while (i > 0) { + i--; + double y = yPoints[i]; + double x = xPoints[i]; + if (x < x1) + x1 = x; + if (y < y1) + y1 = y; + if (x > x2) + x2 = x; + if (y > y2) + y2 = y; + } + } else { + x1 = y1 = x2 = y2 = 0.0f; + } + return new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1); + } + + public Rectangle getBounds() { + return getBounds2D().getBounds(); + } + + public PathIterator getPathIterator(AffineTransform t) { + double[] transformedXPoints = xPoints; + double[] transformedYPoints = yPoints; + if (t != null) { + // FIXME, this seems a silly slow way to deal with this. + transformedXPoints = new double[nPoints]; + transformedYPoints = new double[nPoints]; + Point2D s = new Point2D.Double(); + Point2D d = new Point2D.Double(); + for (int i = 0; i < nPoints; i++) { + s.setLocation(xPoints[i], yPoints[i]); + t.transform(s, d); + transformedXPoints[i] = d.getX(); + transformedYPoints[i] = d.getY(); + } + } + return new ArrayPathIterator(transformedXPoints, transformedYPoints, + nPoints, closed, resolution); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/GenericTagHandler.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/GenericTagHandler.java index e4323b903..7b7fe050d 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/GenericTagHandler.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/GenericTagHandler.java @@ -1,334 +1,334 @@ -// Copyright FreeHEP, 2000-2007 -package org.xmind.org.freehep.graphics2d; - -import java.awt.Graphics2D; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.text.AttributedString; -import java.util.Hashtable; -import java.util.Stack; -import java.util.Vector; - -import org.xmind.org.freehep.graphics2d.font.FontUtilities; - -/** - * The class converts HTML tags like in instances of {@link TextAttribute}. - * - * @author Mark Donszelmann - * @author Steffen Greiffenberg - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class GenericTagHandler extends TagHandler { - - /** - * TextAttribute for overline, not a standard - */ - public static Integer UNDERLINE_OVERLINE = new Integer(128); - - /** - * context to draw AttributedString - */ - private Graphics2D graphics; - - /** - * text without any tags, e.g. "text" would become "text". filled - * by {@link #text(String)} - */ - private StringBuffer clearedText; - - /** - * stores AttributeEntries created by {@link #closeTag(String)} - */ - private Vector attributes; - - /** - * stores all open tags, e.g. "" an the position on which it placed in - * text. Filled by {@link #openTag(String)}, emptied and translated into - * attributes by {@link #closeTag(String)} - */ - private Hashtable tags; - - /** - * store the names of font families before they are changed by openTag() - */ - private Stack fontFamilyStack; - - /** - * if we aplly TextAttribute.SUPERSCRIPT with correction of transformation - * the text is to high / to low by some points - */ - private double superscriptCorrection; - - /** - * creates a tag handler for printing text and calculating its size - * - * @param graphics - * stores the font for calculations - */ - public GenericTagHandler(Graphics2D graphics) { - super(); - this.graphics = graphics; - this.clearedText = new StringBuffer(); - this.tags = new Hashtable(); - } - - /** - * prints the tagged string at x:y - * - * @param s - * string to print using the stored graphics - * @param x - * coordinate for drawing - * @param y - * coordinate for drawing - * @param superscriptCorrection - * correction for to high / to low text - */ - public void print(TagString s, double x, double y, - double superscriptCorrection) { - - fontFamilyStack = new Stack(); - - this.clearedText = new StringBuffer(); - this.attributes = new Vector(); - this.superscriptCorrection = superscriptCorrection; - - parse(s); - - // close all open tags to ensure all - // open attributes are applied - while (tags.size() > 0) { - closeTag((String) tags.keys().nextElement()); - } - - // create attributed string to print - // with current font settings - AttributedString attributedString = new AttributedString( - clearedText.toString(), FontUtilities.getAttributes(graphics - .getFont())); - - // aplly attributes - for (int i = 0; i < attributes.size(); i++) { - ((AttributeEntry) attributes.elementAt(i)).apply(attributedString); - } - - graphics.drawString(attributedString.getIterator(), (float) x, - (float) y); - } - - /** - * calculates the string bounds using the current font of {@link #graphics}. - * - * @param s - * string to calculate - * @return bouding box after parsing s - */ - public TextLayout createTextLayout(TagString s, double superscriptCorrection) { - - fontFamilyStack = new Stack(); - - this.clearedText = new StringBuffer(); - this.attributes = new Vector(); - this.superscriptCorrection = superscriptCorrection; - - parse(s); - - // close all open tags to ensure all - // open attributes are applied - while (tags.size() > 0) { - closeTag((String) tags.keys().nextElement()); - } - - // create attributed string to print - // with current font settings - AttributedString attributedString = new AttributedString( - clearedText.toString(), FontUtilities.getAttributes(graphics - .getFont())); - - // aplly attributes - for (int i = 0; i < attributes.size(); i++) { - ((AttributeEntry) attributes.elementAt(i)).apply(attributedString); - } - - // create the layout - return new TextLayout(attributedString.getIterator(), - graphics.getFontRenderContext()); - } - - /** - * handles bold , italic , superscript , subscript , - * vertical , overline , underline , strikethrough , - * underline dashed , underline dotted and typewriter - * - * @param tag - * one of the known tags, otherwise the overloaded methode is - * called - * @return empty string or the result of the overloaded method - */ - // FIXME: check if we can support overline and vertical? - protected String openTag(String tag) { - // store position of parser for openening tag only if - // it the first openened, e.g. texttext2 will draw - // text and text2 in bold weight - if (!tags.containsKey(tag)) { - tags.put(tag, new Integer(clearedText.length())); - } - return ""; - } - - /** - * closes the given html tag. It doesn't matter, if that one was opened, so - * closes a too, because the use the same - * TextAttribute.UNDERLINE. - * - * @param tag - * to close - * @return empty string or the result of the overloaded method - */ - protected String closeTag(String tag) { - // begin is stored in 'tags' - int begin; - - // do nothing if tag wasn't opened - if (!tags.containsKey(tag)) { - return super.closeTag(tag); - } else { - begin = ((Integer) tags.get(tag)).intValue(); - tags.remove(tag); - } - - // change attributes - if (tag.equalsIgnoreCase("b")) { - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)); - } else if (tag.equalsIgnoreCase("i")) { - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)); - } else if (tag.equalsIgnoreCase("s") || tag.equalsIgnoreCase("strike")) { - this.attributes - .add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.STRIKETHROUGH, - TextAttribute.STRIKETHROUGH_ON)); - } else if (tag.equalsIgnoreCase("udash")) { - this.attributes - .add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.UNDERLINE, - TextAttribute.UNDERLINE_LOW_DASHED)); - } else if (tag.equalsIgnoreCase("udot")) { - this.attributes - .add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.UNDERLINE, - TextAttribute.UNDERLINE_LOW_DOTTED)); - } else if (tag.equalsIgnoreCase("u")) { - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)); - } else if (tag.equalsIgnoreCase("tt")) { - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.FAMILY, fontFamilyStack.pop())); - } else if (tag.equalsIgnoreCase("v")) { - // vertical = false; - } else if (tag.equalsIgnoreCase("over")) { - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.UNDERLINE, UNDERLINE_OVERLINE)); - } else if (tag.equalsIgnoreCase("sup")) { - - // FIXME: not quite clear why this is necessary - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.TRANSFORM, AffineTransform - .getTranslateInstance(0, superscriptCorrection))); - - this.attributes - .add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.SUPERSCRIPT, - TextAttribute.SUPERSCRIPT_SUPER)); - - } else if (tag.equalsIgnoreCase("sub")) { - - // FIXME: not quite clear why this is necessary - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.TRANSFORM, AffineTransform - .getTranslateInstance(0, -superscriptCorrection))); - - this.attributes.add(new AttributeEntry(begin, clearedText.length(), - TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB)); - } else { - return super.closeTag(tag); - } - - // set the font - return ""; - } - - /** - * calculates miny und maxy for {@link #createTextLayout(TagString, double)} - * . If {@link #print} is set, text is drawed using - * {@link Graphics2D#drawString(String, float, float)} of {@link #graphics} - * - * @param text - * text to draw - * @return unmodified text parameter - */ - protected String text(String text) { - // appand text as cleared - clearedText.append(text); - - return text; - } - - /** - * Helper to store an TextAttribute, its value and the range it should cover - * in text. Entries are created by - * {@link GenericTagHandler#closeTag(String)} and apllied in - * {@link GenericTagHandler#print(TagString, double, double, double)} - */ - private class AttributeEntry { - - /** - * start offset in text - */ - private int begin; - - /** - * end position for TextAttribute in text - */ - private int end; - - /** - * the TextAttribute key to layout the text, e.g. TextAttribute.WEIGHT - */ - private TextAttribute textAttribute; - - /** - * the TextAttribute key to layout the text, e.g. - * TextAttribute.WEIGHT_BOLD - */ - private Object value; - - /** - * stores the given parameters - * - * @param begin - * @param end - * @param textAttribute - * @param value - */ - protected AttributeEntry(int begin, int end, - TextAttribute textAttribute, Object value) { - this.begin = begin; - this.end = end; - this.textAttribute = textAttribute; - this.value = value; - } - - /** - * apply the stored attributes to as - * - * @param as - */ - protected void apply(AttributedString as) { - as.addAttribute(textAttribute, value, begin, end); - } - } -} +// Copyright FreeHEP, 2000-2007 +package org.xmind.org.freehep.graphics2d; + +import java.awt.Graphics2D; +import java.awt.font.TextAttribute; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.text.AttributedString; +import java.util.Hashtable; +import java.util.Stack; +import java.util.Vector; + +import org.xmind.org.freehep.graphics2d.font.FontUtilities; + +/** + * The class converts HTML tags like in instances of {@link TextAttribute}. + * + * @author Mark Donszelmann + * @author Steffen Greiffenberg + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class GenericTagHandler extends TagHandler { + + /** + * TextAttribute for overline, not a standard + */ + public static Integer UNDERLINE_OVERLINE = new Integer(128); + + /** + * context to draw AttributedString + */ + private Graphics2D graphics; + + /** + * text without any tags, e.g. "text" would become "text". filled + * by {@link #text(String)} + */ + private StringBuffer clearedText; + + /** + * stores AttributeEntries created by {@link #closeTag(String)} + */ + private Vector attributes; + + /** + * stores all open tags, e.g. "" an the position on which it placed in + * text. Filled by {@link #openTag(String)}, emptied and translated into + * attributes by {@link #closeTag(String)} + */ + private Hashtable tags; + + /** + * store the names of font families before they are changed by openTag() + */ + private Stack fontFamilyStack; + + /** + * if we aplly TextAttribute.SUPERSCRIPT with correction of transformation + * the text is to high / to low by some points + */ + private double superscriptCorrection; + + /** + * creates a tag handler for printing text and calculating its size + * + * @param graphics + * stores the font for calculations + */ + public GenericTagHandler(Graphics2D graphics) { + super(); + this.graphics = graphics; + this.clearedText = new StringBuffer(); + this.tags = new Hashtable(); + } + + /** + * prints the tagged string at x:y + * + * @param s + * string to print using the stored graphics + * @param x + * coordinate for drawing + * @param y + * coordinate for drawing + * @param superscriptCorrection + * correction for to high / to low text + */ + public void print(TagString s, double x, double y, + double superscriptCorrection) { + + fontFamilyStack = new Stack(); + + this.clearedText = new StringBuffer(); + this.attributes = new Vector(); + this.superscriptCorrection = superscriptCorrection; + + parse(s); + + // close all open tags to ensure all + // open attributes are applied + while (tags.size() > 0) { + closeTag((String) tags.keys().nextElement()); + } + + // create attributed string to print + // with current font settings + AttributedString attributedString = new AttributedString( + clearedText.toString(), FontUtilities.getAttributes(graphics + .getFont())); + + // aplly attributes + for (int i = 0; i < attributes.size(); i++) { + ((AttributeEntry) attributes.elementAt(i)).apply(attributedString); + } + + graphics.drawString(attributedString.getIterator(), (float) x, + (float) y); + } + + /** + * calculates the string bounds using the current font of {@link #graphics}. + * + * @param s + * string to calculate + * @return bouding box after parsing s + */ + public TextLayout createTextLayout(TagString s, double superscriptCorrection) { + + fontFamilyStack = new Stack(); + + this.clearedText = new StringBuffer(); + this.attributes = new Vector(); + this.superscriptCorrection = superscriptCorrection; + + parse(s); + + // close all open tags to ensure all + // open attributes are applied + while (tags.size() > 0) { + closeTag((String) tags.keys().nextElement()); + } + + // create attributed string to print + // with current font settings + AttributedString attributedString = new AttributedString( + clearedText.toString(), FontUtilities.getAttributes(graphics + .getFont())); + + // aplly attributes + for (int i = 0; i < attributes.size(); i++) { + ((AttributeEntry) attributes.elementAt(i)).apply(attributedString); + } + + // create the layout + return new TextLayout(attributedString.getIterator(), + graphics.getFontRenderContext()); + } + + /** + * handles bold , italic , superscript , subscript , + * vertical , overline , underline , strikethrough , + * underline dashed , underline dotted and typewriter + * + * @param tag + * one of the known tags, otherwise the overloaded methode is + * called + * @return empty string or the result of the overloaded method + */ + // FIXME: check if we can support overline and vertical? + protected String openTag(String tag) { + // store position of parser for openening tag only if + // it the first openened, e.g. texttext2 will draw + // text and text2 in bold weight + if (!tags.containsKey(tag)) { + tags.put(tag, new Integer(clearedText.length())); + } + return ""; + } + + /** + * closes the given html tag. It doesn't matter, if that one was opened, so + * closes a too, because the use the same + * TextAttribute.UNDERLINE. + * + * @param tag + * to close + * @return empty string or the result of the overloaded method + */ + protected String closeTag(String tag) { + // begin is stored in 'tags' + int begin; + + // do nothing if tag wasn't opened + if (!tags.containsKey(tag)) { + return super.closeTag(tag); + } else { + begin = ((Integer) tags.get(tag)).intValue(); + tags.remove(tag); + } + + // change attributes + if (tag.equalsIgnoreCase("b")) { + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)); + } else if (tag.equalsIgnoreCase("i")) { + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)); + } else if (tag.equalsIgnoreCase("s") || tag.equalsIgnoreCase("strike")) { + this.attributes + .add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.STRIKETHROUGH, + TextAttribute.STRIKETHROUGH_ON)); + } else if (tag.equalsIgnoreCase("udash")) { + this.attributes + .add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.UNDERLINE, + TextAttribute.UNDERLINE_LOW_DASHED)); + } else if (tag.equalsIgnoreCase("udot")) { + this.attributes + .add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.UNDERLINE, + TextAttribute.UNDERLINE_LOW_DOTTED)); + } else if (tag.equalsIgnoreCase("u")) { + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)); + } else if (tag.equalsIgnoreCase("tt")) { + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.FAMILY, fontFamilyStack.pop())); + } else if (tag.equalsIgnoreCase("v")) { + // vertical = false; + } else if (tag.equalsIgnoreCase("over")) { + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.UNDERLINE, UNDERLINE_OVERLINE)); + } else if (tag.equalsIgnoreCase("sup")) { + + // FIXME: not quite clear why this is necessary + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.TRANSFORM, AffineTransform + .getTranslateInstance(0, superscriptCorrection))); + + this.attributes + .add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.SUPERSCRIPT, + TextAttribute.SUPERSCRIPT_SUPER)); + + } else if (tag.equalsIgnoreCase("sub")) { + + // FIXME: not quite clear why this is necessary + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.TRANSFORM, AffineTransform + .getTranslateInstance(0, -superscriptCorrection))); + + this.attributes.add(new AttributeEntry(begin, clearedText.length(), + TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB)); + } else { + return super.closeTag(tag); + } + + // set the font + return ""; + } + + /** + * calculates miny und maxy for {@link #createTextLayout(TagString, double)} + * . If {@link #print} is set, text is drawed using + * {@link Graphics2D#drawString(String, float, float)} of {@link #graphics} + * + * @param text + * text to draw + * @return unmodified text parameter + */ + protected String text(String text) { + // appand text as cleared + clearedText.append(text); + + return text; + } + + /** + * Helper to store an TextAttribute, its value and the range it should cover + * in text. Entries are created by + * {@link GenericTagHandler#closeTag(String)} and apllied in + * {@link GenericTagHandler#print(TagString, double, double, double)} + */ + private class AttributeEntry { + + /** + * start offset in text + */ + private int begin; + + /** + * end position for TextAttribute in text + */ + private int end; + + /** + * the TextAttribute key to layout the text, e.g. TextAttribute.WEIGHT + */ + private TextAttribute textAttribute; + + /** + * the TextAttribute key to layout the text, e.g. + * TextAttribute.WEIGHT_BOLD + */ + private Object value; + + /** + * stores the given parameters + * + * @param begin + * @param end + * @param textAttribute + * @param value + */ + protected AttributeEntry(int begin, int end, + TextAttribute textAttribute, Object value) { + this.begin = begin; + this.end = end; + this.textAttribute = textAttribute; + this.value = value; + } + + /** + * apply the stored attributes to as + * + * @param as + */ + protected void apply(AttributedString as) { + as.addAttribute(textAttribute, value, begin, end); + } + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PixelGraphics2D.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PixelGraphics2D.java index 940bc1813..7b1d737fc 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PixelGraphics2D.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PixelGraphics2D.java @@ -1,647 +1,647 @@ -// Copyright 2000-2006, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.Transparency; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.awt.print.PrinterGraphics; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.text.AttributedCharacterIterator; -import java.util.HashMap; -import java.util.Map; - -import org.xmind.org.freehep.graphics2d.font.FontEncoder; - -/** - * @author Charles Loomis - * @author Mark Donszelmann - * @author Jason Wong - */ -public class PixelGraphics2D extends AbstractVectorGraphics { - - public final static RenderingHints.Key KEY_SYMBOL_BLIT = new SymbolBlitKey(); - - public final static Object VALUE_SYMBOL_BLIT_ON = Boolean.TRUE; - - public final static Object VALUE_SYMBOL_BLIT_OFF = Boolean.FALSE; - - static class SymbolBlitKey extends RenderingHints.Key { - public SymbolBlitKey() { - super(94025); - } - - public boolean isCompatibleValue(Object o) { - if (o.equals(VALUE_SYMBOL_BLIT_ON)) - return true; - if (o.equals(VALUE_SYMBOL_BLIT_OFF)) - return true; - return false; - } - - public String toString() { - return "Symbol Blitting enable key"; //$NON-NLS-1$ - } - } - - // The host graphics context. - protected Graphics2D hostGraphics; - - protected double lineWidth; - - protected int resolution; - - // tag handler - protected GenericTagHandler tagHandler; - - // fast symbol handling, FIXME: does not work for fillAndDraw - private static final int MAX_BLIT_SIZE = 32; - - private static Map symbols; - - private WebColor webColor; - - // graphics environment stuff - private static boolean displayX11; - - private static boolean displayLocal; - - static { - symbols = new HashMap(); - - displayX11 = false; - displayLocal = false; - try { - Class clazz = Class.forName("sun.awt.X11GraphicsEnvironment"); //$NON-NLS-1$ - displayX11 = true; - Method method = clazz - .getMethod("isDisplayLocal", (Class[]) null); //$NON-NLS-1$ - Boolean result = (Boolean) method.invoke(null, - new Object[] { null }); - displayLocal = result.booleanValue(); - } catch (ClassNotFoundException e) { - // Windows case... - displayLocal = true; - } catch (IllegalAccessException e) { - // ignored - } catch (NoSuchMethodException e) { - // ignored - } catch (InvocationTargetException e) { - // ignored - } catch (ClassCastException e) { - // ignored - } catch (SecurityException e) { - // ignored - } catch (UnsatisfiedLinkError e) { - // ignored - } catch (NullPointerException e) { - // ignored - } catch (Exception e) { - // ignored - } - } - - public PixelGraphics2D(Graphics graphics) { - this(); - setHostGraphics(graphics); - } - - /** - */ - protected PixelGraphics2D(PixelGraphics2D graphics) { - super(graphics); - setHostGraphics(graphics.hostGraphics.create()); - } - - /** - * Constructor for the case that you only know the hostgraphics later on. - * NOTE: make sure you call setHostGraphics afterwards. - */ - protected PixelGraphics2D() { - super(); - } - - protected void setHostGraphics(Graphics graphics) { - hostGraphics = (Graphics2D) graphics; - resolution = (graphics instanceof PrinterGraphics) ? 0 : 1; - tagHandler = new GenericTagHandler(hostGraphics); - - super.setBackground(hostGraphics.getBackground()); - super.setColor(hostGraphics.getColor()); - super.setPaint(hostGraphics.getPaint()); - super.setFont(hostGraphics.getFont()); - - Stroke s = hostGraphics.getStroke(); - if (s instanceof BasicStroke) { - lineWidth = ((BasicStroke) s).getLineWidth(); - } - webColor = WebColor.create(getColor()); - setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_ON); - } - - public void startExport() { - } - - public void endExport() { - } - - public void printComment(String comment) { - } - - public Graphics create(double x, double y, double width, double height) { - PixelGraphics2D graphics = new PixelGraphics2D(this); - graphics.translate(x, y); - graphics.clipRect(0, 0, width, height); - return graphics; - } - - // // - // The methods which follow are those necessary for the Graphics - // and Graphics2D contexts. These simply call the appropriate - // method on the underlying graphics context. - // // - - public void clearRect(int x, int y, int width, int height) { - hostGraphics.clearRect(x, y, width, height); - } - - public void clipRect(int x, int y, int width, int height) { - hostGraphics.clipRect(x, y, width, height); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - hostGraphics.copyArea(x, y, width, height, dx, dy); - } - - public Graphics create() { - return new PixelGraphics2D(this); - } - - public void dispose() { - hostGraphics.dispose(); - } - - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - hostGraphics.drawArc(x, y, width, height, startAngle, arcAngle); - } - - public boolean drawImage(Image img, int x, int y, Color bgcolor, - ImageObserver observer) { - return hostGraphics.drawImage(img, x, y, getPrintColor(bgcolor), - observer); - } - - public boolean drawImage(Image img, int x, int y, ImageObserver observer) { - return hostGraphics.drawImage(img, x, y, observer); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, - Color bgcolor, ImageObserver observer) { - return hostGraphics.drawImage(img, x, y, width, height, - getPrintColor(bgcolor), observer); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, - ImageObserver observer) { - return hostGraphics.drawImage(img, x, y, width, height, observer); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, Color bgcolor, - ImageObserver observer) { - return hostGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, - sy2, getPrintColor(bgcolor), observer); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - return hostGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, - sy2, observer); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - hostGraphics.drawLine(x1, y1, x2, y2); - } - - public void drawOval(int x, int y, int width, int height) { - hostGraphics.drawOval(x, y, width, height); - } - - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { - hostGraphics.drawPolygon(xPoints, yPoints, nPoints); - } - - public void drawPolygon(Polygon p) { - hostGraphics.drawPolygon(p); - } - - public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { - hostGraphics.drawPolyline(xPoints, yPoints, nPoints); - } - - public void drawRect(int x, int y, int width, int height) { - hostGraphics.drawRect(x, y, width, height); - } - - public void drawString(String str, int x, int y) { - str = FontEncoder.getEncodedString(str, getFont().getName()); - hostGraphics.drawString(str, x, y); - } - - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - hostGraphics.fillArc(x, y, width, height, startAngle, arcAngle); - } - - public void fillOval(int x, int y, int width, int height) { - hostGraphics.fillOval(x, y, width, height); - } - - public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { - hostGraphics.fillPolygon(xPoints, yPoints, nPoints); - } - - public void fillPolygon(Polygon p) { - hostGraphics.fillPolygon(p); - } - - public void fillRect(int x, int y, int width, int height) { - hostGraphics.fillRect(x, y, width, height); - } - - public void drawSymbol(double x, double y, double size, int symbol) { - if (size <= 0) - return; - - int intSize = (int) Math.ceil(size); - if ((intSize > MAX_BLIT_SIZE) - || (lineWidth != 1.0) - || !isDisplayLocal() - || (getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON) - || (getRenderingHint(KEY_SYMBOL_BLIT) == VALUE_SYMBOL_BLIT_OFF)) { - super.drawSymbol(x, y, size, symbol); - return; - } - - blitSymbol(x, y, intSize, symbol, false); - } - - public void fillSymbol(double x, double y, double size, int symbol) { - if (size <= 0) - return; - - int intSize = (int) Math.ceil(size); - if ((intSize > MAX_BLIT_SIZE) - || (lineWidth != 1.0) - || !isDisplayLocal() - || (getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON) - || (getRenderingHint(KEY_SYMBOL_BLIT) == VALUE_SYMBOL_BLIT_OFF)) { - super.fillSymbol(x, y, size, symbol); - return; - } - - blitSymbol(x, y, intSize, symbol, true); - } - - // FIXME: overridden to avoid blitting - public void fillAndDrawSymbol(double x, double y, double size, int symbol, - Color fillColor) { - Color color = getColor(); - setColor(fillColor); - super.fillSymbol(x, y, size, symbol); - setColor(color); - super.drawSymbol(x, y, size, symbol); - } - - private void blitSymbol(double x, double y, int size, int symbol, - boolean fill) { - Image[][][] images = (Image[][][]) symbols.get(webColor); - if (images == null) { - images = new Image[2][NUMBER_OF_SYMBOLS][MAX_BLIT_SIZE]; - symbols.put(webColor, images); - } - - Image image = images[fill ? 1 : 0][symbol][size - 1]; - int imageSize = size + 1; - double imageSize2 = imageSize / 2.0; - if (image == null) { - image = getDeviceConfiguration().createCompatibleImage( - imageSize + 1, imageSize + 1, Transparency.BITMASK); - VectorGraphics imageGraphics = VectorGraphics.create(image - .getGraphics()); - Composite composite = imageGraphics.getComposite(); - imageGraphics.setComposite(AlphaComposite.Clear); - imageGraphics.fillRect(0, 0, size, size); - imageGraphics.setComposite(composite); - imageGraphics.setColor(getColor()); - if (fill) { - fillSymbol(imageGraphics, imageSize2, imageSize2, size, symbol); - } else { - drawSymbol(imageGraphics, imageSize2, imageSize2, size, symbol); - } - images[fill ? 1 : 0][symbol][size - 1] = image; - } - drawImage(image, (int) (x - imageSize2), (int) (y - imageSize2), null); - } - - public void setLineWidth(double width) { - super.setLineWidth(width); - lineWidth = width; - } - - public Shape getClip() { - return hostGraphics.getClip(); - } - - public Rectangle getClipBounds() { - return hostGraphics.getClipBounds(); - } - - public Rectangle getClipBounds(Rectangle r) { - return hostGraphics.getClipBounds(r); - } - - public FontMetrics getFontMetrics(Font f) { - return hostGraphics.getFontMetrics(f); - } - - public void setClip(int x, int y, int width, int height) { - hostGraphics.setClip(x, y, width, height); - } - - public void setClip(Shape clip) { - hostGraphics.setClip(clip); - } - - @SuppressWarnings("nls") - public void setFont(Font font) { - if (font == null) - return; - - super.setFont(font); - if (font.getName().equals("Symbol") - || font.getName().equals("ZapfDingbats")) { - Font newFont = new Font("Serif", font.getSize(), font.getStyle()); - font = newFont.deriveFont(font.getSize2D()); - } - hostGraphics.setFont(font); - } - - public void setColor(Color color) { - if (color == null) - return; - - if (color.equals(getColor())) - return; - - super.setColor(color); - hostGraphics.setColor(getPrintColor(color)); - webColor = WebColor.create(color); - } - - public void setPaint(Paint paint) { - if (paint == null) - return; - - if (paint.equals(getPaint())) - return; - - if (paint instanceof Color) { - setColor((Color) paint); - } else { - super.setPaint(paint); - hostGraphics.setPaint(paint); - } - } - - public void setPaintMode() { - hostGraphics.setPaintMode(); - } - - public void setXORMode(Color c1) { - hostGraphics.setXORMode(getPrintColor(c1)); - } - - public void translate(int x, int y) { - hostGraphics.translate(x, y); - } - - // // - // The ones from the Graphic2D context. This overrides some - // methods defined in VectorGraphics2D by simply calling the - // underlying host graphics context. - // // - - @SuppressWarnings("rawtypes") - public void addRenderingHints(Map hints) { - hostGraphics.addRenderingHints(hints); - } - - public void clip(Shape clip) { - hostGraphics.clip(clip); - } - - public void draw(Shape s) { - hostGraphics.draw(s); - } - - public void drawGlyphVector(GlyphVector g, float x, float y) { - hostGraphics.drawGlyphVector(g, x, y); - } - - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { - hostGraphics.drawImage(img, op, x, y); - } - - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - return hostGraphics.drawImage(img, xform, obs); - } - - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - hostGraphics.drawRenderableImage(img, xform); - } - - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - hostGraphics.drawRenderedImage(img, xform); - } - - public void drawString(AttributedCharacterIterator iterator, float x, - float y) { - hostGraphics.drawString(iterator, x, y); - } - - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - hostGraphics.drawString(iterator, x, y); - } - - public void drawString(String str, float x, float y) { - str = FontEncoder.getEncodedString(str, getFont().getName()); - hostGraphics.drawString(str, x, y); - } - - public void fill(Shape s) { - hostGraphics.fill(s); - } - - public Composite getComposite() { - return hostGraphics.getComposite(); - } - - public GraphicsConfiguration getDeviceConfiguration() { - return hostGraphics.getDeviceConfiguration(); - } - - public FontRenderContext getFontRenderContext() { - return hostGraphics.getFontRenderContext(); - } - - public Object getRenderingHint(RenderingHints.Key hintKey) { - return hostGraphics.getRenderingHint(hintKey); - } - - public RenderingHints getRenderingHints() { - return hostGraphics.getRenderingHints(); - } - - public Stroke getStroke() { - return hostGraphics.getStroke(); - } - - public AffineTransform getTransform() { - return hostGraphics.getTransform(); - } - - public boolean hit(Rectangle rect, Shape s, boolean onStroke) { - return hostGraphics.hit(rect, s, onStroke); - } - - public void rotate(double theta) { - hostGraphics.rotate(theta); - } - - public void rotate(double theta, double x, double y) { - hostGraphics.rotate(theta, x, y); - } - - public void scale(double sx, double sy) { - hostGraphics.scale(sx, sy); - } - - public void setBackground(Color color) { - super.setBackground(color); - hostGraphics.setBackground(getPrintColor(color)); - } - - public void setComposite(Composite comp) { - hostGraphics.setComposite(comp); - } - - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { - hostGraphics.setRenderingHint(hintKey, hintValue); - } - - @SuppressWarnings("rawtypes") - public void setRenderingHints(Map hints) { - hostGraphics.setRenderingHints(hints); - } - - public void setStroke(Stroke s) { - hostGraphics.setStroke(s); - } - - public void setTransform(AffineTransform Tx) { - hostGraphics.setTransform(Tx); - } - - public void shear(double shx, double shy) { - hostGraphics.shear(shx, shy); - } - - public void transform(AffineTransform Tx) { - hostGraphics.transform(Tx); - } - - public void translate(double tx, double ty) { - hostGraphics.translate(tx, ty); - } - - // // - // The following methods are those specific to the VectorGraphics - // interfaces, but which are simple extensions of integer method - // calls to doubles. - // // - - public void clearRect(double x, double y, double width, double height) { - clearRect((int) x, (int) y, (int) width, (int) height); - } - - public void clipRect(double x, double y, double width, double height) { - clipRect((int) x, (int) y, (int) width, (int) height); - } - - public void drawString(String str, double x, double y) { - drawString(str, (int) Math.round(x), (int) Math.round(y)); - } - - public void setClip(double x, double y, double width, double height) { - setClip(new Rectangle2D.Double(x, y, width, height)); - } - - public String toString() { - return "PixelGraphics2D[" + hostGraphics.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public static boolean isDisplayX11() { - return displayX11; - } - - public static boolean isDisplayLocal() { - return displayLocal; - } - - /** - * Implementation of createShape makes sure that the points are different by - * at least one pixel. - */ - protected Shape createShape(double[] xPoints, double[] yPoints, - int nPoints, boolean close) { - return new ArrayPath(xPoints, yPoints, nPoints, close, resolution); - } - /* - * protected GeneralPath createShape(double[] xPoints, double[] yPoints, int - * nPoints, boolean close) { GeneralPath path = new - * GeneralPath(GeneralPath.WIND_EVEN_ODD); if (nPoints > 0) { - * path.moveTo((float)xPoints[0], (float)yPoints[0]); double lastX = - * xPoints[0]; double lastY = yPoints[0]; if (close && - * (Math.abs(xPoints[nPoints-1] - lastX) < resolution) && - * (Math.abs(yPoints[nPoints-1] - lastY) < resolution)) { nPoints--; } for - * (int i = 1; i < nPoints; i++) { if ((Math.abs(xPoints[i] - lastX) > - * resolution) || (Math.abs(yPoints[i] - lastY) > resolution)) { - * path.lineTo((float)xPoints[i], (float)yPoints[i]); lastX = xPoints[i]; - * lastY = yPoints[i]; } } if (close) path.closePath(); } return path; } - */ -} +// Copyright 2000-2006, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.Transparency; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.awt.print.PrinterGraphics; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.Map; + +import org.xmind.org.freehep.graphics2d.font.FontEncoder; + +/** + * @author Charles Loomis + * @author Mark Donszelmann + * @author Jason Wong + */ +public class PixelGraphics2D extends AbstractVectorGraphics { + + public final static RenderingHints.Key KEY_SYMBOL_BLIT = new SymbolBlitKey(); + + public final static Object VALUE_SYMBOL_BLIT_ON = Boolean.TRUE; + + public final static Object VALUE_SYMBOL_BLIT_OFF = Boolean.FALSE; + + static class SymbolBlitKey extends RenderingHints.Key { + public SymbolBlitKey() { + super(94025); + } + + public boolean isCompatibleValue(Object o) { + if (o.equals(VALUE_SYMBOL_BLIT_ON)) + return true; + if (o.equals(VALUE_SYMBOL_BLIT_OFF)) + return true; + return false; + } + + public String toString() { + return "Symbol Blitting enable key"; //$NON-NLS-1$ + } + } + + // The host graphics context. + protected Graphics2D hostGraphics; + + protected double lineWidth; + + protected int resolution; + + // tag handler + protected GenericTagHandler tagHandler; + + // fast symbol handling, FIXME: does not work for fillAndDraw + private static final int MAX_BLIT_SIZE = 32; + + private static Map symbols; + + private WebColor webColor; + + // graphics environment stuff + private static boolean displayX11; + + private static boolean displayLocal; + + static { + symbols = new HashMap(); + + displayX11 = false; + displayLocal = false; + try { + Class clazz = Class.forName("sun.awt.X11GraphicsEnvironment"); //$NON-NLS-1$ + displayX11 = true; + Method method = clazz + .getMethod("isDisplayLocal", (Class[]) null); //$NON-NLS-1$ + Boolean result = (Boolean) method.invoke(null, + new Object[] { null }); + displayLocal = result.booleanValue(); + } catch (ClassNotFoundException e) { + // Windows case... + displayLocal = true; + } catch (IllegalAccessException e) { + // ignored + } catch (NoSuchMethodException e) { + // ignored + } catch (InvocationTargetException e) { + // ignored + } catch (ClassCastException e) { + // ignored + } catch (SecurityException e) { + // ignored + } catch (UnsatisfiedLinkError e) { + // ignored + } catch (NullPointerException e) { + // ignored + } catch (Exception e) { + // ignored + } + } + + public PixelGraphics2D(Graphics graphics) { + this(); + setHostGraphics(graphics); + } + + /** + */ + protected PixelGraphics2D(PixelGraphics2D graphics) { + super(graphics); + setHostGraphics(graphics.hostGraphics.create()); + } + + /** + * Constructor for the case that you only know the hostgraphics later on. + * NOTE: make sure you call setHostGraphics afterwards. + */ + protected PixelGraphics2D() { + super(); + } + + protected void setHostGraphics(Graphics graphics) { + hostGraphics = (Graphics2D) graphics; + resolution = (graphics instanceof PrinterGraphics) ? 0 : 1; + tagHandler = new GenericTagHandler(hostGraphics); + + super.setBackground(hostGraphics.getBackground()); + super.setColor(hostGraphics.getColor()); + super.setPaint(hostGraphics.getPaint()); + super.setFont(hostGraphics.getFont()); + + Stroke s = hostGraphics.getStroke(); + if (s instanceof BasicStroke) { + lineWidth = ((BasicStroke) s).getLineWidth(); + } + webColor = WebColor.create(getColor()); + setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_ON); + } + + public void startExport() { + } + + public void endExport() { + } + + public void printComment(String comment) { + } + + public Graphics create(double x, double y, double width, double height) { + PixelGraphics2D graphics = new PixelGraphics2D(this); + graphics.translate(x, y); + graphics.clipRect(0, 0, width, height); + return graphics; + } + + // // + // The methods which follow are those necessary for the Graphics + // and Graphics2D contexts. These simply call the appropriate + // method on the underlying graphics context. + // // + + public void clearRect(int x, int y, int width, int height) { + hostGraphics.clearRect(x, y, width, height); + } + + public void clipRect(int x, int y, int width, int height) { + hostGraphics.clipRect(x, y, width, height); + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + hostGraphics.copyArea(x, y, width, height, dx, dy); + } + + public Graphics create() { + return new PixelGraphics2D(this); + } + + public void dispose() { + hostGraphics.dispose(); + } + + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + hostGraphics.drawArc(x, y, width, height, startAngle, arcAngle); + } + + public boolean drawImage(Image img, int x, int y, Color bgcolor, + ImageObserver observer) { + return hostGraphics.drawImage(img, x, y, getPrintColor(bgcolor), + observer); + } + + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + return hostGraphics.drawImage(img, x, y, observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { + return hostGraphics.drawImage(img, x, y, width, height, + getPrintColor(bgcolor), observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { + return hostGraphics.drawImage(img, x, y, width, height, observer); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) { + return hostGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, + sy2, getPrintColor(bgcolor), observer); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + return hostGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, + sy2, observer); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + hostGraphics.drawLine(x1, y1, x2, y2); + } + + public void drawOval(int x, int y, int width, int height) { + hostGraphics.drawOval(x, y, width, height); + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + hostGraphics.drawPolygon(xPoints, yPoints, nPoints); + } + + public void drawPolygon(Polygon p) { + hostGraphics.drawPolygon(p); + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + hostGraphics.drawPolyline(xPoints, yPoints, nPoints); + } + + public void drawRect(int x, int y, int width, int height) { + hostGraphics.drawRect(x, y, width, height); + } + + public void drawString(String str, int x, int y) { + str = FontEncoder.getEncodedString(str, getFont().getName()); + hostGraphics.drawString(str, x, y); + } + + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + hostGraphics.fillArc(x, y, width, height, startAngle, arcAngle); + } + + public void fillOval(int x, int y, int width, int height) { + hostGraphics.fillOval(x, y, width, height); + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + hostGraphics.fillPolygon(xPoints, yPoints, nPoints); + } + + public void fillPolygon(Polygon p) { + hostGraphics.fillPolygon(p); + } + + public void fillRect(int x, int y, int width, int height) { + hostGraphics.fillRect(x, y, width, height); + } + + public void drawSymbol(double x, double y, double size, int symbol) { + if (size <= 0) + return; + + int intSize = (int) Math.ceil(size); + if ((intSize > MAX_BLIT_SIZE) + || (lineWidth != 1.0) + || !isDisplayLocal() + || (getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON) + || (getRenderingHint(KEY_SYMBOL_BLIT) == VALUE_SYMBOL_BLIT_OFF)) { + super.drawSymbol(x, y, size, symbol); + return; + } + + blitSymbol(x, y, intSize, symbol, false); + } + + public void fillSymbol(double x, double y, double size, int symbol) { + if (size <= 0) + return; + + int intSize = (int) Math.ceil(size); + if ((intSize > MAX_BLIT_SIZE) + || (lineWidth != 1.0) + || !isDisplayLocal() + || (getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON) + || (getRenderingHint(KEY_SYMBOL_BLIT) == VALUE_SYMBOL_BLIT_OFF)) { + super.fillSymbol(x, y, size, symbol); + return; + } + + blitSymbol(x, y, intSize, symbol, true); + } + + // FIXME: overridden to avoid blitting + public void fillAndDrawSymbol(double x, double y, double size, int symbol, + Color fillColor) { + Color color = getColor(); + setColor(fillColor); + super.fillSymbol(x, y, size, symbol); + setColor(color); + super.drawSymbol(x, y, size, symbol); + } + + private void blitSymbol(double x, double y, int size, int symbol, + boolean fill) { + Image[][][] images = (Image[][][]) symbols.get(webColor); + if (images == null) { + images = new Image[2][NUMBER_OF_SYMBOLS][MAX_BLIT_SIZE]; + symbols.put(webColor, images); + } + + Image image = images[fill ? 1 : 0][symbol][size - 1]; + int imageSize = size + 1; + double imageSize2 = imageSize / 2.0; + if (image == null) { + image = getDeviceConfiguration().createCompatibleImage( + imageSize + 1, imageSize + 1, Transparency.BITMASK); + VectorGraphics imageGraphics = VectorGraphics.create(image + .getGraphics()); + Composite composite = imageGraphics.getComposite(); + imageGraphics.setComposite(AlphaComposite.Clear); + imageGraphics.fillRect(0, 0, size, size); + imageGraphics.setComposite(composite); + imageGraphics.setColor(getColor()); + if (fill) { + fillSymbol(imageGraphics, imageSize2, imageSize2, size, symbol); + } else { + drawSymbol(imageGraphics, imageSize2, imageSize2, size, symbol); + } + images[fill ? 1 : 0][symbol][size - 1] = image; + } + drawImage(image, (int) (x - imageSize2), (int) (y - imageSize2), null); + } + + public void setLineWidth(double width) { + super.setLineWidth(width); + lineWidth = width; + } + + public Shape getClip() { + return hostGraphics.getClip(); + } + + public Rectangle getClipBounds() { + return hostGraphics.getClipBounds(); + } + + public Rectangle getClipBounds(Rectangle r) { + return hostGraphics.getClipBounds(r); + } + + public FontMetrics getFontMetrics(Font f) { + return hostGraphics.getFontMetrics(f); + } + + public void setClip(int x, int y, int width, int height) { + hostGraphics.setClip(x, y, width, height); + } + + public void setClip(Shape clip) { + hostGraphics.setClip(clip); + } + + @SuppressWarnings("nls") + public void setFont(Font font) { + if (font == null) + return; + + super.setFont(font); + if (font.getName().equals("Symbol") + || font.getName().equals("ZapfDingbats")) { + Font newFont = new Font("Serif", font.getSize(), font.getStyle()); + font = newFont.deriveFont(font.getSize2D()); + } + hostGraphics.setFont(font); + } + + public void setColor(Color color) { + if (color == null) + return; + + if (color.equals(getColor())) + return; + + super.setColor(color); + hostGraphics.setColor(getPrintColor(color)); + webColor = WebColor.create(color); + } + + public void setPaint(Paint paint) { + if (paint == null) + return; + + if (paint.equals(getPaint())) + return; + + if (paint instanceof Color) { + setColor((Color) paint); + } else { + super.setPaint(paint); + hostGraphics.setPaint(paint); + } + } + + public void setPaintMode() { + hostGraphics.setPaintMode(); + } + + public void setXORMode(Color c1) { + hostGraphics.setXORMode(getPrintColor(c1)); + } + + public void translate(int x, int y) { + hostGraphics.translate(x, y); + } + + // // + // The ones from the Graphic2D context. This overrides some + // methods defined in VectorGraphics2D by simply calling the + // underlying host graphics context. + // // + + @SuppressWarnings("rawtypes") + public void addRenderingHints(Map hints) { + hostGraphics.addRenderingHints(hints); + } + + public void clip(Shape clip) { + hostGraphics.clip(clip); + } + + public void draw(Shape s) { + hostGraphics.draw(s); + } + + public void drawGlyphVector(GlyphVector g, float x, float y) { + hostGraphics.drawGlyphVector(g, x, y); + } + + public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { + hostGraphics.drawImage(img, op, x, y); + } + + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { + return hostGraphics.drawImage(img, xform, obs); + } + + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + hostGraphics.drawRenderableImage(img, xform); + } + + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + hostGraphics.drawRenderedImage(img, xform); + } + + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + hostGraphics.drawString(iterator, x, y); + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + hostGraphics.drawString(iterator, x, y); + } + + public void drawString(String str, float x, float y) { + str = FontEncoder.getEncodedString(str, getFont().getName()); + hostGraphics.drawString(str, x, y); + } + + public void fill(Shape s) { + hostGraphics.fill(s); + } + + public Composite getComposite() { + return hostGraphics.getComposite(); + } + + public GraphicsConfiguration getDeviceConfiguration() { + return hostGraphics.getDeviceConfiguration(); + } + + public FontRenderContext getFontRenderContext() { + return hostGraphics.getFontRenderContext(); + } + + public Object getRenderingHint(RenderingHints.Key hintKey) { + return hostGraphics.getRenderingHint(hintKey); + } + + public RenderingHints getRenderingHints() { + return hostGraphics.getRenderingHints(); + } + + public Stroke getStroke() { + return hostGraphics.getStroke(); + } + + public AffineTransform getTransform() { + return hostGraphics.getTransform(); + } + + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + return hostGraphics.hit(rect, s, onStroke); + } + + public void rotate(double theta) { + hostGraphics.rotate(theta); + } + + public void rotate(double theta, double x, double y) { + hostGraphics.rotate(theta, x, y); + } + + public void scale(double sx, double sy) { + hostGraphics.scale(sx, sy); + } + + public void setBackground(Color color) { + super.setBackground(color); + hostGraphics.setBackground(getPrintColor(color)); + } + + public void setComposite(Composite comp) { + hostGraphics.setComposite(comp); + } + + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { + hostGraphics.setRenderingHint(hintKey, hintValue); + } + + @SuppressWarnings("rawtypes") + public void setRenderingHints(Map hints) { + hostGraphics.setRenderingHints(hints); + } + + public void setStroke(Stroke s) { + hostGraphics.setStroke(s); + } + + public void setTransform(AffineTransform Tx) { + hostGraphics.setTransform(Tx); + } + + public void shear(double shx, double shy) { + hostGraphics.shear(shx, shy); + } + + public void transform(AffineTransform Tx) { + hostGraphics.transform(Tx); + } + + public void translate(double tx, double ty) { + hostGraphics.translate(tx, ty); + } + + // // + // The following methods are those specific to the VectorGraphics + // interfaces, but which are simple extensions of integer method + // calls to doubles. + // // + + public void clearRect(double x, double y, double width, double height) { + clearRect((int) x, (int) y, (int) width, (int) height); + } + + public void clipRect(double x, double y, double width, double height) { + clipRect((int) x, (int) y, (int) width, (int) height); + } + + public void drawString(String str, double x, double y) { + drawString(str, (int) Math.round(x), (int) Math.round(y)); + } + + public void setClip(double x, double y, double width, double height) { + setClip(new Rectangle2D.Double(x, y, width, height)); + } + + public String toString() { + return "PixelGraphics2D[" + hostGraphics.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static boolean isDisplayX11() { + return displayX11; + } + + public static boolean isDisplayLocal() { + return displayLocal; + } + + /** + * Implementation of createShape makes sure that the points are different by + * at least one pixel. + */ + protected Shape createShape(double[] xPoints, double[] yPoints, + int nPoints, boolean close) { + return new ArrayPath(xPoints, yPoints, nPoints, close, resolution); + } + /* + * protected GeneralPath createShape(double[] xPoints, double[] yPoints, int + * nPoints, boolean close) { GeneralPath path = new + * GeneralPath(GeneralPath.WIND_EVEN_ODD); if (nPoints > 0) { + * path.moveTo((float)xPoints[0], (float)yPoints[0]); double lastX = + * xPoints[0]; double lastY = yPoints[0]; if (close && + * (Math.abs(xPoints[nPoints-1] - lastX) < resolution) && + * (Math.abs(yPoints[nPoints-1] - lastY) < resolution)) { nPoints--; } for + * (int i = 1; i < nPoints; i++) { if ((Math.abs(xPoints[i] - lastX) > + * resolution) || (Math.abs(yPoints[i] - lastY) > resolution)) { + * path.lineTo((float)xPoints[i], (float)yPoints[i]); lastX = xPoints[i]; + * lastY = yPoints[i]; } } if (close) path.closePath(); } return path; } + */ +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PrintColor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PrintColor.java index 6400a7f39..6e6d211cb 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PrintColor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/PrintColor.java @@ -1,161 +1,161 @@ -// Copyright 2002, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.Color; -import java.awt.color.ColorSpace; - -/** - * Print color for printing and display in color, grayscale and black/white. - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PrintColor extends Color { - - /** - * - */ - private static final long serialVersionUID = -6797837867994533237L; - - public static final int COLOR = 0; - - public static final int GRAYSCALE = 1; - - public static final int BLACK_AND_WHITE = 2; - - protected static Color[] defaultColors = { Color.RED, Color.GREEN, - Color.BLUE, Color.CYAN, Color.MAGENTA, Color.YELLOW, Color.ORANGE, - Color.PINK, Color.WHITE, Color.LIGHT_GRAY, Color.GRAY, - Color.DARK_GRAY, Color.BLACK }; - - protected float asGray; - - protected boolean asBlack; - - private static void testColorValueRange(float asGray) { - boolean rangeError = false; - String badComponentString = ""; - if (asGray < 0.0f || asGray > 1.0f) { - rangeError = true; - badComponentString = badComponentString + " asGray"; - } - if (rangeError) { - throw new IllegalArgumentException( - "PrintColor parameter outside of expected range:" - + badComponentString); - } - } - - public PrintColor(float red, float green, float blue, float asGray, - boolean asBlack) { - this(red, green, blue, 1.0f, asGray, asBlack); - } - - public PrintColor(float red, float green, float blue, float alpha, - float asGray, boolean asBlack) { - super(red, green, blue, alpha); - this.asGray = asGray; - this.asBlack = asBlack; - testColorValueRange(asGray); - } - - public PrintColor(Color color, float asGray, boolean asBlack) { - super(color.getRed(), color.getGreen(), color.getBlue(), color - .getAlpha()); - this.asGray = asGray; - this.asBlack = asBlack; - testColorValueRange(asGray); - } - - public float getAsGray() { - return asGray; - } - - public boolean getAsBlack() { - return asBlack; - } - - public PrintColor getColor(int mode) { - // FIXME does not handle invisibility - switch (mode) { - case COLOR: - return this; - case GRAYSCALE: - return new PrintColor(getAsGray(), getAsGray(), getAsGray(), - getAlpha() / 255.0f, getAsGray(), getAsBlack()); - case BLACK_AND_WHITE: - if (getAsBlack()) { - return new PrintColor(Color.black, getAsGray(), getAsBlack()); - } else { - return new PrintColor(Color.white, getAsGray(), getAsBlack()); - } - default: - throw new IllegalArgumentException( - "ColorMode on PrintColor out of range: " + mode); - } - } - - public static PrintColor createPrintColor(Color color) { - if (color == null) { - return null; - } - - if (color instanceof PrintColor) { - return (PrintColor) color; - } - - // convert a awt.Color to some reasonable PrintColor. - // pure white converts to black, and vice versa. - float[] gray = ColorSpace.getInstance(ColorSpace.CS_GRAY).fromRGB( - color.getRGBComponents(null)); - if (gray[0] == 0.0f) { - gray[0] = 1.0f; - } else if (gray[0] == 1.0f) { - gray[0] = 0.0f; - } - return new PrintColor(color, gray[0], !color.equals(Color.black)); - } - - /** - * @return a color from the standard java colors - */ - public static Color getDefaultColor(int index) { - if ((index < 0) || (index >= defaultColors.length)) - throw new IllegalArgumentException( - "PrintColor.getDefaultColor index outside of expected range: " - + index); - return createPrintColor(defaultColors[index]); - } - - // FIXME, should return PrintColor - public static Color mixColor(Color c1, Color c2) { - int red = (c1.getRed() + c2.getRed()) / 2; - int green = (c1.getGreen() + c2.getGreen()) / 2; - int blue = (c1.getBlue() + c2.getBlue()) / 2; - return new Color(red, green, blue); - } - - public int hashCode() { - // FIXME could make something better here - return super.hashCode(); - } - - public boolean equals(Object obj) { - return super.equals(obj) && obj instanceof PrintColor - && ((PrintColor) obj).asGray == this.asGray - && ((PrintColor) obj).asBlack == this.asBlack; - } - - public String toString() { - return super.toString() + ", asGray: " + asGray + ", asBlack: " - + asBlack; - } - - public static PrintColor invert(Color color) { - PrintColor printColor = createPrintColor(color); - return new PrintColor(new Color(printColor.getRGB() ^ 0x00808080), - (printColor.getAsGray() + 0.5f) % 1.0f, - !printColor.getAsBlack()); - } -} +// Copyright 2002, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.Color; +import java.awt.color.ColorSpace; + +/** + * Print color for printing and display in color, grayscale and black/white. + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PrintColor extends Color { + + /** + * + */ + private static final long serialVersionUID = -6797837867994533237L; + + public static final int COLOR = 0; + + public static final int GRAYSCALE = 1; + + public static final int BLACK_AND_WHITE = 2; + + protected static Color[] defaultColors = { Color.RED, Color.GREEN, + Color.BLUE, Color.CYAN, Color.MAGENTA, Color.YELLOW, Color.ORANGE, + Color.PINK, Color.WHITE, Color.LIGHT_GRAY, Color.GRAY, + Color.DARK_GRAY, Color.BLACK }; + + protected float asGray; + + protected boolean asBlack; + + private static void testColorValueRange(float asGray) { + boolean rangeError = false; + String badComponentString = ""; + if (asGray < 0.0f || asGray > 1.0f) { + rangeError = true; + badComponentString = badComponentString + " asGray"; + } + if (rangeError) { + throw new IllegalArgumentException( + "PrintColor parameter outside of expected range:" + + badComponentString); + } + } + + public PrintColor(float red, float green, float blue, float asGray, + boolean asBlack) { + this(red, green, blue, 1.0f, asGray, asBlack); + } + + public PrintColor(float red, float green, float blue, float alpha, + float asGray, boolean asBlack) { + super(red, green, blue, alpha); + this.asGray = asGray; + this.asBlack = asBlack; + testColorValueRange(asGray); + } + + public PrintColor(Color color, float asGray, boolean asBlack) { + super(color.getRed(), color.getGreen(), color.getBlue(), color + .getAlpha()); + this.asGray = asGray; + this.asBlack = asBlack; + testColorValueRange(asGray); + } + + public float getAsGray() { + return asGray; + } + + public boolean getAsBlack() { + return asBlack; + } + + public PrintColor getColor(int mode) { + // FIXME does not handle invisibility + switch (mode) { + case COLOR: + return this; + case GRAYSCALE: + return new PrintColor(getAsGray(), getAsGray(), getAsGray(), + getAlpha() / 255.0f, getAsGray(), getAsBlack()); + case BLACK_AND_WHITE: + if (getAsBlack()) { + return new PrintColor(Color.black, getAsGray(), getAsBlack()); + } else { + return new PrintColor(Color.white, getAsGray(), getAsBlack()); + } + default: + throw new IllegalArgumentException( + "ColorMode on PrintColor out of range: " + mode); + } + } + + public static PrintColor createPrintColor(Color color) { + if (color == null) { + return null; + } + + if (color instanceof PrintColor) { + return (PrintColor) color; + } + + // convert a awt.Color to some reasonable PrintColor. + // pure white converts to black, and vice versa. + float[] gray = ColorSpace.getInstance(ColorSpace.CS_GRAY).fromRGB( + color.getRGBComponents(null)); + if (gray[0] == 0.0f) { + gray[0] = 1.0f; + } else if (gray[0] == 1.0f) { + gray[0] = 0.0f; + } + return new PrintColor(color, gray[0], !color.equals(Color.black)); + } + + /** + * @return a color from the standard java colors + */ + public static Color getDefaultColor(int index) { + if ((index < 0) || (index >= defaultColors.length)) + throw new IllegalArgumentException( + "PrintColor.getDefaultColor index outside of expected range: " + + index); + return createPrintColor(defaultColors[index]); + } + + // FIXME, should return PrintColor + public static Color mixColor(Color c1, Color c2) { + int red = (c1.getRed() + c2.getRed()) / 2; + int green = (c1.getGreen() + c2.getGreen()) / 2; + int blue = (c1.getBlue() + c2.getBlue()) / 2; + return new Color(red, green, blue); + } + + public int hashCode() { + // FIXME could make something better here + return super.hashCode(); + } + + public boolean equals(Object obj) { + return super.equals(obj) && obj instanceof PrintColor + && ((PrintColor) obj).asGray == this.asGray + && ((PrintColor) obj).asBlack == this.asBlack; + } + + public String toString() { + return super.toString() + ", asGray: " + asGray + ", asBlack: " + + asBlack; + } + + public static PrintColor invert(Color color) { + PrintColor printColor = createPrintColor(color); + return new PrintColor(new Color(printColor.getRGB() ^ 0x00808080), + (printColor.getAsGray() + 0.5f) % 1.0f, + !printColor.getAsBlack()); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/SymbolShape.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/SymbolShape.java index f37b5ec1d..92843c736 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/SymbolShape.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/SymbolShape.java @@ -1,400 +1,400 @@ -// Copyright 2001-2004, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -/** - * This class can be used to create and render simple shapes quickly and without - * memory allocation. A common point array is used for all created shapes. The - * factory methods don't return a new shape, but set the object to the selected - * shape. Hence, the class is not thread-safe and only one PathIterator can be - * used at the same time.
    - * - * @author Simon Fischer - * @author Jason Wong - */ -public class SymbolShape implements Shape { - - private static final double SQRT_2 = Math.sqrt(2.); - - private static final double SQRT_3 = Math.sqrt(3.); - - private class ArrayPathIterator implements PathIterator { - - private int currentPoint = 0; - - private double[] points; - - private int[] type; - - private int numberOfPoints; - - private ArrayPathIterator(double[] points, int[] type) { - this.points = points; - this.type = type; - } - - public boolean isDone() { - return currentPoint >= numberOfPoints; - } - - public void next() { - currentPoint++; - } - - public int currentSegment(double[] coords) { - coords[0] = points[2 * currentPoint]; - coords[1] = points[2 * currentPoint + 1]; - return type[currentPoint]; - } - - public int currentSegment(float[] coords) { - coords[0] = (float) points[2 * currentPoint]; - coords[1] = (float) points[2 * currentPoint + 1]; - return type[currentPoint]; - } - - public int getWindingRule() { - return PathIterator.WIND_NON_ZERO; - } - - private void reset() { - currentPoint = 0; - } - - private void done() { - currentPoint = numberOfPoints; - } - } - - private double points[]; - - private int type[]; - - private ArrayPathIterator pathIterator; - - private double x, y; - - private double size; - - private int symbol; - - public SymbolShape() { - ensureNumberOfPoints(10); - type[0] = PathIterator.SEG_MOVETO; - for (int i = 1; i < type.length; i++) { - type[i] = PathIterator.SEG_LINETO; - } - this.pathIterator = new ArrayPathIterator(points, type); - } - - public boolean contains(double x, double y) { - return getBounds2D().contains(x, y); - } - - public boolean contains(double x, double y, double w, double h) { - return contains(x, y) && contains(x + w, y) && contains(x, y + h) - && contains(x + w, y + h); - } - - public boolean contains(Point2D p) { - return contains(p.getX(), p.getY()); - } - - public boolean contains(Rectangle2D r) { - return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - /** Returns true, if at least one of the points is contained by the shape. */ - public boolean intersects(double x, double y, double w, double h) { - return contains(x, y) || contains(x + w, y) || contains(x, y + h) - || contains(x + w, y + h); - } - - public boolean intersects(Rectangle2D r) { - return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - public PathIterator getPathIterator(AffineTransform at, double flatness) { - return getPathIterator(at); - } - - public Rectangle2D getBounds2D() { - return new Rectangle2D.Double(x - size / 2, y - size / 2, size, size); - } - - public Rectangle getBounds() { - return getBounds2D().getBounds(); - } - - public PathIterator getPathIterator(AffineTransform t) { - if (t != null) { - t.transform(points, 0, pathIterator.points, 0, points.length / 2); - } - // if (!pathIterator.isDone()) { - // System.err.println("SymbolShape: concurrent PathIterator - // requested!"); - // } - pathIterator.reset(); - return pathIterator; - } - - // -------------------- factory methods -------------------- - - private void createNew(int n) { - // if (!pathIterator.isDone()) { - // System.err.println("SymbolShape: concurrent modification!"); - // } - ensureNumberOfPoints(n); - pathIterator.numberOfPoints = n; - pathIterator.done(); - } - - /** - * Type must be one of the symbols defined in VectorGraphicsConstants except - * TYPE_CIRCLE. - * - * @see org.xmind.org.freehep.graphics2d.VectorGraphicsConstants - */ - public void create(int symbol, double x, double y, double size) { - this.symbol = symbol; - this.x = x; - this.y = y; - this.size = size; - switch (symbol) { - case VectorGraphicsConstants.SYMBOL_VLINE: - createVLine(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_HLINE: - createHLine(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_PLUS: - createPlus(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_CROSS: - createCross(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_STAR: - createStar(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_BOX: - createBox(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_UP_TRIANGLE: - createUpTriangle(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_DN_TRIANGLE: - createDownTriangle(x, y, size); - break; - case VectorGraphicsConstants.SYMBOL_DIAMOND: - createDiamond(x, y, size); - break; - } - } - - @SuppressWarnings("nls") - public String toString() { - return getClass() + ": " + symbol + " (" + x + ", " + y + ") size: " - + size; - } - - private void createHLine(double x, double y, double size) { - createNew(2); - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x - size / 2; - points[1] = y; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x + size / 2; - points[3] = y; - } - - private void createVLine(double x, double y, double size) { - createNew(2); - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x; - points[1] = y - size / 2; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x; - points[3] = y + size / 2; - } - - private void createPlus(double x, double y, double size) { - createNew(4); - double length = size / 2.; - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x + length; - points[1] = y; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x - length; - points[3] = y; - - type[2] = PathIterator.SEG_MOVETO; - points[4] = x; - points[5] = y + length; - - type[3] = PathIterator.SEG_LINETO; - points[6] = x; - points[7] = y - length; - } - - private void createCross(double x, double y, double size) { - createNew(4); - double side = size / 2. / SQRT_2; - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x - side; - points[1] = y - side; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x + side; - points[3] = y + side; - - type[2] = PathIterator.SEG_MOVETO; - points[4] = x + side; - points[5] = y - side; - - type[3] = PathIterator.SEG_LINETO; - points[6] = x - side; - points[7] = y + side; - } - - private void createStar(double x, double y, double size) { - createNew(8); - - double delta = size / 2.; - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x; - points[1] = y - delta; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x; - points[3] = y + delta; - - type[2] = PathIterator.SEG_MOVETO; - points[4] = x - delta; - points[5] = y; - - type[3] = PathIterator.SEG_LINETO; - points[6] = x + delta; - points[7] = y; - - delta = size / 2. / SQRT_2; - - type[4] = PathIterator.SEG_MOVETO; - points[8] = x - delta; - points[9] = y - delta; - - type[5] = PathIterator.SEG_LINETO; - points[10] = x + delta; - points[11] = y + delta; - - type[6] = PathIterator.SEG_MOVETO; - points[12] = x + delta; - points[13] = y - delta; - - type[7] = PathIterator.SEG_LINETO; - points[14] = x - delta; - points[15] = y + delta; - } - - private void createUpTriangle(double x, double y, double size) { - createNew(4); - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x; - points[1] = y - size / SQRT_3; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x - size / 2.; - points[3] = y + (-size / SQRT_3 + size * SQRT_3 / 2.); - - type[2] = PathIterator.SEG_LINETO; - points[4] = x + size / 2.; - points[5] = y + (-size / SQRT_3 + size * SQRT_3 / 2.); - - type[3] = PathIterator.SEG_CLOSE; - } - - private void createDownTriangle(double x, double y, double size) { - createNew(4); - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x; - points[1] = y + size / SQRT_3; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x - size / 2.; - points[3] = y - (-size / SQRT_3 + size * SQRT_3 / 2.); - - type[2] = PathIterator.SEG_LINETO; - points[4] = x + size / 2.; - points[5] = y - (-size / SQRT_3 + size * SQRT_3 / 2.); - - type[3] = PathIterator.SEG_CLOSE; - } - - private void createDiamond(double x, double y, double size) { - createNew(5); - double length = size / 2.; - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x + length; - points[1] = y; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x; - points[3] = y + length; - - type[2] = PathIterator.SEG_LINETO; - points[4] = x - length; - points[5] = y; - - type[3] = PathIterator.SEG_LINETO; - points[6] = x; - points[7] = y - length; - - type[4] = PathIterator.SEG_CLOSE; - } - - private void createBox(double x, double y, double size) { - createNew(5); - double side = size / SQRT_2 / 2; - - type[0] = PathIterator.SEG_MOVETO; - points[0] = x - side; - points[1] = y - side; - - type[1] = PathIterator.SEG_LINETO; - points[2] = x + side + 1; - points[3] = y - side; - - type[2] = PathIterator.SEG_LINETO; - points[4] = x + side + 1; - points[5] = y + side + 1; - - type[3] = PathIterator.SEG_LINETO; - points[6] = x - side; - points[7] = y + side + 1; - - type[4] = PathIterator.SEG_CLOSE; - } - - private void ensureNumberOfPoints(int n) { - if ((type == null) || (type.length < n)) { - this.points = new double[n * 2]; - this.type = new int[n]; - } - } -} +// Copyright 2001-2004, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +/** + * This class can be used to create and render simple shapes quickly and without + * memory allocation. A common point array is used for all created shapes. The + * factory methods don't return a new shape, but set the object to the selected + * shape. Hence, the class is not thread-safe and only one PathIterator can be + * used at the same time.
    + * + * @author Simon Fischer + * @author Jason Wong + */ +public class SymbolShape implements Shape { + + private static final double SQRT_2 = Math.sqrt(2.); + + private static final double SQRT_3 = Math.sqrt(3.); + + private class ArrayPathIterator implements PathIterator { + + private int currentPoint = 0; + + private double[] points; + + private int[] type; + + private int numberOfPoints; + + private ArrayPathIterator(double[] points, int[] type) { + this.points = points; + this.type = type; + } + + public boolean isDone() { + return currentPoint >= numberOfPoints; + } + + public void next() { + currentPoint++; + } + + public int currentSegment(double[] coords) { + coords[0] = points[2 * currentPoint]; + coords[1] = points[2 * currentPoint + 1]; + return type[currentPoint]; + } + + public int currentSegment(float[] coords) { + coords[0] = (float) points[2 * currentPoint]; + coords[1] = (float) points[2 * currentPoint + 1]; + return type[currentPoint]; + } + + public int getWindingRule() { + return PathIterator.WIND_NON_ZERO; + } + + private void reset() { + currentPoint = 0; + } + + private void done() { + currentPoint = numberOfPoints; + } + } + + private double points[]; + + private int type[]; + + private ArrayPathIterator pathIterator; + + private double x, y; + + private double size; + + private int symbol; + + public SymbolShape() { + ensureNumberOfPoints(10); + type[0] = PathIterator.SEG_MOVETO; + for (int i = 1; i < type.length; i++) { + type[i] = PathIterator.SEG_LINETO; + } + this.pathIterator = new ArrayPathIterator(points, type); + } + + public boolean contains(double x, double y) { + return getBounds2D().contains(x, y); + } + + public boolean contains(double x, double y, double w, double h) { + return contains(x, y) && contains(x + w, y) && contains(x, y + h) + && contains(x + w, y + h); + } + + public boolean contains(Point2D p) { + return contains(p.getX(), p.getY()); + } + + public boolean contains(Rectangle2D r) { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + /** Returns true, if at least one of the points is contained by the shape. */ + public boolean intersects(double x, double y, double w, double h) { + return contains(x, y) || contains(x + w, y) || contains(x, y + h) + || contains(x + w, y + h); + } + + public boolean intersects(Rectangle2D r) { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + public PathIterator getPathIterator(AffineTransform at, double flatness) { + return getPathIterator(at); + } + + public Rectangle2D getBounds2D() { + return new Rectangle2D.Double(x - size / 2, y - size / 2, size, size); + } + + public Rectangle getBounds() { + return getBounds2D().getBounds(); + } + + public PathIterator getPathIterator(AffineTransform t) { + if (t != null) { + t.transform(points, 0, pathIterator.points, 0, points.length / 2); + } + // if (!pathIterator.isDone()) { + // System.err.println("SymbolShape: concurrent PathIterator + // requested!"); + // } + pathIterator.reset(); + return pathIterator; + } + + // -------------------- factory methods -------------------- + + private void createNew(int n) { + // if (!pathIterator.isDone()) { + // System.err.println("SymbolShape: concurrent modification!"); + // } + ensureNumberOfPoints(n); + pathIterator.numberOfPoints = n; + pathIterator.done(); + } + + /** + * Type must be one of the symbols defined in VectorGraphicsConstants except + * TYPE_CIRCLE. + * + * @see org.xmind.org.freehep.graphics2d.VectorGraphicsConstants + */ + public void create(int symbol, double x, double y, double size) { + this.symbol = symbol; + this.x = x; + this.y = y; + this.size = size; + switch (symbol) { + case VectorGraphicsConstants.SYMBOL_VLINE: + createVLine(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_HLINE: + createHLine(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_PLUS: + createPlus(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_CROSS: + createCross(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_STAR: + createStar(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_BOX: + createBox(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_UP_TRIANGLE: + createUpTriangle(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_DN_TRIANGLE: + createDownTriangle(x, y, size); + break; + case VectorGraphicsConstants.SYMBOL_DIAMOND: + createDiamond(x, y, size); + break; + } + } + + @SuppressWarnings("nls") + public String toString() { + return getClass() + ": " + symbol + " (" + x + ", " + y + ") size: " + + size; + } + + private void createHLine(double x, double y, double size) { + createNew(2); + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x - size / 2; + points[1] = y; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x + size / 2; + points[3] = y; + } + + private void createVLine(double x, double y, double size) { + createNew(2); + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x; + points[1] = y - size / 2; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x; + points[3] = y + size / 2; + } + + private void createPlus(double x, double y, double size) { + createNew(4); + double length = size / 2.; + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x + length; + points[1] = y; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x - length; + points[3] = y; + + type[2] = PathIterator.SEG_MOVETO; + points[4] = x; + points[5] = y + length; + + type[3] = PathIterator.SEG_LINETO; + points[6] = x; + points[7] = y - length; + } + + private void createCross(double x, double y, double size) { + createNew(4); + double side = size / 2. / SQRT_2; + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x - side; + points[1] = y - side; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x + side; + points[3] = y + side; + + type[2] = PathIterator.SEG_MOVETO; + points[4] = x + side; + points[5] = y - side; + + type[3] = PathIterator.SEG_LINETO; + points[6] = x - side; + points[7] = y + side; + } + + private void createStar(double x, double y, double size) { + createNew(8); + + double delta = size / 2.; + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x; + points[1] = y - delta; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x; + points[3] = y + delta; + + type[2] = PathIterator.SEG_MOVETO; + points[4] = x - delta; + points[5] = y; + + type[3] = PathIterator.SEG_LINETO; + points[6] = x + delta; + points[7] = y; + + delta = size / 2. / SQRT_2; + + type[4] = PathIterator.SEG_MOVETO; + points[8] = x - delta; + points[9] = y - delta; + + type[5] = PathIterator.SEG_LINETO; + points[10] = x + delta; + points[11] = y + delta; + + type[6] = PathIterator.SEG_MOVETO; + points[12] = x + delta; + points[13] = y - delta; + + type[7] = PathIterator.SEG_LINETO; + points[14] = x - delta; + points[15] = y + delta; + } + + private void createUpTriangle(double x, double y, double size) { + createNew(4); + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x; + points[1] = y - size / SQRT_3; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x - size / 2.; + points[3] = y + (-size / SQRT_3 + size * SQRT_3 / 2.); + + type[2] = PathIterator.SEG_LINETO; + points[4] = x + size / 2.; + points[5] = y + (-size / SQRT_3 + size * SQRT_3 / 2.); + + type[3] = PathIterator.SEG_CLOSE; + } + + private void createDownTriangle(double x, double y, double size) { + createNew(4); + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x; + points[1] = y + size / SQRT_3; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x - size / 2.; + points[3] = y - (-size / SQRT_3 + size * SQRT_3 / 2.); + + type[2] = PathIterator.SEG_LINETO; + points[4] = x + size / 2.; + points[5] = y - (-size / SQRT_3 + size * SQRT_3 / 2.); + + type[3] = PathIterator.SEG_CLOSE; + } + + private void createDiamond(double x, double y, double size) { + createNew(5); + double length = size / 2.; + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x + length; + points[1] = y; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x; + points[3] = y + length; + + type[2] = PathIterator.SEG_LINETO; + points[4] = x - length; + points[5] = y; + + type[3] = PathIterator.SEG_LINETO; + points[6] = x; + points[7] = y - length; + + type[4] = PathIterator.SEG_CLOSE; + } + + private void createBox(double x, double y, double size) { + createNew(5); + double side = size / SQRT_2 / 2; + + type[0] = PathIterator.SEG_MOVETO; + points[0] = x - side; + points[1] = y - side; + + type[1] = PathIterator.SEG_LINETO; + points[2] = x + side + 1; + points[3] = y - side; + + type[2] = PathIterator.SEG_LINETO; + points[4] = x + side + 1; + points[5] = y + side + 1; + + type[3] = PathIterator.SEG_LINETO; + points[6] = x - side; + points[7] = y + side + 1; + + type[4] = PathIterator.SEG_CLOSE; + } + + private void ensureNumberOfPoints(int n) { + if ((type == null) || (type.length < n)) { + this.points = new double[n * 2]; + this.type = new int[n]; + } + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagHandler.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagHandler.java index 96f5ee62b..c0e258fc3 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagHandler.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagHandler.java @@ -1,157 +1,157 @@ -// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. -package org.xmind.org.freehep.graphics2d; - -/** - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class TagHandler { - - public TagHandler() { - } - - /** - * parses string and calls methods for every tag and every not recognized - * entity The characters < and > have to be written as < and > while - * the & is written as & - * - * The following three methods are called: defaultEntity(entity) for & - * < > " ' entity(entity) for all other entities - * openTag(tag) for all endTag(tag) for all text(text) for - * all text - * - * The startTag, endTag and text methods returns a string which is added to - * the fully parsed string. - * - * Strings returned from the entity methods will show up in the text methods - * parameter. - * - * It returns the fully parsed string, including any additions made by the - * three methods above. - */ - @SuppressWarnings("nls") - public String parse(TagString string) { - String src = string.toString(); - StringBuffer parsedString = new StringBuffer(); - StringBuffer textString = new StringBuffer(); - int i = 0; - int p = 0; - try { - while (i < src.length()) { - switch (src.charAt(i)) { - case '&': - // handle entities - // look for closing ';' - i++; - p = i; - while (src.charAt(i) != ';') { - i++; - } - String ent = src.substring(p, i); - if (ent.equals("amp") || ent.equals("gt") - || ent.equals("lt") || ent.equals("quot") - || ent.equals("apos")) { - textString.append(defaultEntity(ent)); - } else { - textString.append(entity(ent)); - } - break; - - case '<': - // handle tags - - // handle any outstanding text - if (textString.length() > 0) { - parsedString.append(text(textString.toString())); - textString = new StringBuffer(); - } - - // look for closing '>' - i++; - p = i; - while (src.charAt(i) != '>') { - i++; - } - - if (src.charAt(p) == '/') { - parsedString.append(closeTag(src.substring(p + 1, i))); - } else { - parsedString.append(openTag(src.substring(p, i))); - } - break; - default: - // just move the pointer - textString.append(src.charAt(i)); - break; - } // switch - i++; - } // while - - } catch (ArrayIndexOutOfBoundsException aoobe) { - // just abort, but give most of the string - parsedString.append("!PARSEERROR!"); - } - - // final part - if (textString.length() > 0) { - parsedString.append(text(textString.toString())); - } - return parsedString.toString(); - } - - @SuppressWarnings("nls") - protected String defaultEntity(String entity) { - StringBuffer dst = new StringBuffer(); - if (entity.equals("amp")) { - dst.append('&'); - } else if (entity.equals("gt")) { - dst.append('>'); - } else if (entity.equals("lt")) { - dst.append('<'); - } else if (entity.equals("quot")) { - dst.append('"'); - } else if (entity.equals("apos")) { - dst.append('\''); - } - return dst.toString(); - } - - protected String entity(String entity) { - StringBuffer dst = new StringBuffer(); - dst.append('&'); - dst.append(entity); - dst.append(';'); - return dst.toString(); - } - - protected String openTag(String tag) { - StringBuffer dst = new StringBuffer(); - dst.append('<'); - dst.append(tag); - dst.append('>'); - return dst.toString(); - } - - protected String closeTag(String tag) { - StringBuffer dst = new StringBuffer(); - dst.append("'); - return dst.toString(); - } - - protected String text(String text) { - return text; - } - - @SuppressWarnings("nls") - public static void main(String[] args) { - String text = "<VectorGraphics & CardAdapter>"; - - TagString s = new TagString(text); - TagHandler handler = new TagHandler(); - System.out.println("\"" + s + "\""); - System.out.println(handler.parse(s)); - } -} +// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. +package org.xmind.org.freehep.graphics2d; + +/** + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class TagHandler { + + public TagHandler() { + } + + /** + * parses string and calls methods for every tag and every not recognized + * entity The characters < and > have to be written as < and > while + * the & is written as & + * + * The following three methods are called: defaultEntity(entity) for & + * < > " ' entity(entity) for all other entities + * openTag(tag) for all endTag(tag) for all text(text) for + * all text + * + * The startTag, endTag and text methods returns a string which is added to + * the fully parsed string. + * + * Strings returned from the entity methods will show up in the text methods + * parameter. + * + * It returns the fully parsed string, including any additions made by the + * three methods above. + */ + @SuppressWarnings("nls") + public String parse(TagString string) { + String src = string.toString(); + StringBuffer parsedString = new StringBuffer(); + StringBuffer textString = new StringBuffer(); + int i = 0; + int p = 0; + try { + while (i < src.length()) { + switch (src.charAt(i)) { + case '&': + // handle entities + // look for closing ';' + i++; + p = i; + while (src.charAt(i) != ';') { + i++; + } + String ent = src.substring(p, i); + if (ent.equals("amp") || ent.equals("gt") + || ent.equals("lt") || ent.equals("quot") + || ent.equals("apos")) { + textString.append(defaultEntity(ent)); + } else { + textString.append(entity(ent)); + } + break; + + case '<': + // handle tags + + // handle any outstanding text + if (textString.length() > 0) { + parsedString.append(text(textString.toString())); + textString = new StringBuffer(); + } + + // look for closing '>' + i++; + p = i; + while (src.charAt(i) != '>') { + i++; + } + + if (src.charAt(p) == '/') { + parsedString.append(closeTag(src.substring(p + 1, i))); + } else { + parsedString.append(openTag(src.substring(p, i))); + } + break; + default: + // just move the pointer + textString.append(src.charAt(i)); + break; + } // switch + i++; + } // while + + } catch (ArrayIndexOutOfBoundsException aoobe) { + // just abort, but give most of the string + parsedString.append("!PARSEERROR!"); + } + + // final part + if (textString.length() > 0) { + parsedString.append(text(textString.toString())); + } + return parsedString.toString(); + } + + @SuppressWarnings("nls") + protected String defaultEntity(String entity) { + StringBuffer dst = new StringBuffer(); + if (entity.equals("amp")) { + dst.append('&'); + } else if (entity.equals("gt")) { + dst.append('>'); + } else if (entity.equals("lt")) { + dst.append('<'); + } else if (entity.equals("quot")) { + dst.append('"'); + } else if (entity.equals("apos")) { + dst.append('\''); + } + return dst.toString(); + } + + protected String entity(String entity) { + StringBuffer dst = new StringBuffer(); + dst.append('&'); + dst.append(entity); + dst.append(';'); + return dst.toString(); + } + + protected String openTag(String tag) { + StringBuffer dst = new StringBuffer(); + dst.append('<'); + dst.append(tag); + dst.append('>'); + return dst.toString(); + } + + protected String closeTag(String tag) { + StringBuffer dst = new StringBuffer(); + dst.append("'); + return dst.toString(); + } + + protected String text(String text) { + return text; + } + + @SuppressWarnings("nls") + public static void main(String[] args) { + String text = "<VectorGraphics & CardAdapter>"; + + TagString s = new TagString(text); + TagHandler handler = new TagHandler(); + System.out.println("\"" + s + "\""); + System.out.println(handler.parse(s)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagString.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagString.java index e7773398c..3edb10783 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagString.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/TagString.java @@ -1,29 +1,29 @@ -// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. -package org.xmind.org.freehep.graphics2d; - - -/** - * - * @author Mark Donszelmann - * @version $Id: TagString.java 8584 2006-08-10 23:06:37Z duns $ - */ -public class TagString { - - private String string; - - public TagString(String value) { - string = value; - } - - public int hashCode() { - return string.hashCode(); - } - - public boolean equals(Object obj) { - return string.equals(obj); - } - - public String toString() { - return string; - } -} +// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. +package org.xmind.org.freehep.graphics2d; + + +/** + * + * @author Mark Donszelmann + * @version $Id: TagString.java 8584 2006-08-10 23:06:37Z duns $ + */ +public class TagString { + + private String string; + + public TagString(String value) { + string = value; + } + + public int hashCode() { + return string.hashCode(); + } + + public boolean equals(Object obj) { + return string.equals(obj); + } + + public String toString() { + return string; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphics.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphics.java index 08d07aa03..ab5d6ceff 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphics.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphics.java @@ -1,647 +1,647 @@ -// Copyright 2000-2007, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.text.AttributedCharacterIterator; -import java.util.Hashtable; -import java.util.Map; -import java.util.Properties; - -/** - * The drawing methods which are guaranteed to work for the various output - * formats of the VectorGraphics system on the Java 2 platform. All methods are - * re-declared abstract, since this class inherits from Graphics2D and we would - * not want to actually or accidentally use any of those methods, except for the - * ones noted. - * - * Some int methods need to call their super.methods otherwise the compiler - * cannot make a distinction if it needs to convert int to doubles or call the - * super int method. - * - * Note that many of these routines modify the current transformation matrix. To - * guard against unintended side effects the following method should be used: - * - *
    - * 
    - *  Graphics2D tempGraphics = (Graphics2D) originalGraphics.create();
    - *  tempGraphics.setStroke(originalGraphics.getStroke());
    - *  tempGraphics.rotate(...);
    - *  tempGraphics.translate(...);
    - *  ...drawing methods on tempGraphics...
    - *  tempGraphics.dispose();
    - * 
    - * 
    - * - * where originalGraphics is the original Graphics2D - * object. Note that dispose must be called when the drawing - * finishes on tempGraphics and that no drawing should be done on - * originalGraphics until dispose has been called. - * - * @author Charles Loomis - * @author Mark Donszelmann - * @author Jason Wong - */ -public abstract class VectorGraphics extends Graphics2D implements - VectorGraphicsConstants { - - public abstract void setProperties(Properties newProperties); - - protected abstract void initProperties(Properties defaults); - - protected abstract Properties getProperties(); - - public abstract String getProperty(String key); - - public abstract Color getPropertyColor(String key); - - public abstract Rectangle getPropertyRectangle(String key); - - public abstract Dimension getPropertyDimension(String key); - - public abstract int getPropertyInt(String key); - - public abstract double getPropertyDouble(String key); - - public abstract boolean isProperty(String key); - - // // - // Methods defined in java.awt.Graphics (alphabetical) - // // - - public abstract void clearRect(int x, int y, int width, int height); - - public abstract void clipRect(int x, int y, int width, int height); - - public abstract void copyArea(int x, int y, int width, int height, int dx, - int dy); - - public abstract Graphics create(); - - // NOTE: implemented in Graphics, must be implemented here otherwise the - // compiler - // cannot choose between converting ints to doubles or calling the - // superclass. - public Graphics create(int x, int y, int width, int height) { - return super.create(x, y, width, height); - } - - public abstract void dispose(); - - // NOTE: implemented in Graphics - // public abstract void draw3DRect(int x, int y, - // int width, int height, - // boolean raised); - public abstract void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle); - - // NOTE: implemented in Graphics - // public abstract void drawBytes(byte[] data, int offset, - // int length, - // int x, int y); - // NOTE: implemented in Graphics - // public abstract void drawChars(char[] data, int offset, - // int length, - // int x, int y); - public abstract boolean drawImage(Image image, int x, int y, - ImageObserver observer); - - public abstract boolean drawImage(Image image, int x, int y, int width, - int height, ImageObserver observer); - - public abstract boolean drawImage(Image image, int x, int y, Color bgColor, - ImageObserver observer); - - public abstract boolean drawImage(Image image, int x, int y, int width, - int height, Color bgColor, ImageObserver observer); - - public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2, - int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer); - - public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2, - int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor, - ImageObserver observer); - - public abstract void drawLine(int x1, int y1, int x2, int y2); - - public abstract void drawOval(int x, int y, int width, int height); - - public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints); - - // NOTE implemented in Graphics - // public abstract void drawPolygon(Polygon p); - public abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints); - - public abstract void drawRect(int x, int y, int width, int height); - - public abstract void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight); - - public abstract void drawString(AttributedCharacterIterator iterator, - int x, int y); - - public abstract void drawString(String str, int x, int y); - - // NOTE: implemented in Graphics - // public abstract void fill3DRect(int x, int y, - // int width, int height, - // boolean raised); - public abstract void fillArc(int x, int y, int width, int height, - int startAngle, int arcAngle); - - public abstract void fillOval(int x, int y, int width, int height); - - public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints); - - // NOTE: implemented in Graphics - // public abstract void fillPolygon(Polygon p); - public abstract void fillRect(int x, int y, int width, int height); - - public abstract void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight); - - // NOTE: implemented in Graphics - // public abstract void finalize(); - public abstract Shape getClip(); - - public abstract Rectangle getClipBounds(); - - public abstract Rectangle getClipBounds(Rectangle r); - - // NOTE: implemented in Graphics - // public abstract Rectangle getClipRect(); - public abstract Color getColor(); - - public abstract Font getFont(); - - // NOTE: implemented in Graphics - // public abstract FontMetrics getFontMetrics(); - public abstract FontMetrics getFontMetrics(Font font); - - // NOTE: implemented in Graphics - // public abstract boolean hitClip(int x, int y, int width, int height); - public abstract void setClip(int x, int y, int width, int height); - - public abstract void setClip(Shape clip); - - public abstract void setColor(Color c); - - public abstract void setFont(Font font); - - public abstract void setPaintMode(); - - public abstract void setXORMode(Color c1); - - public abstract String toString(); - - public abstract void translate(int x, int y); - - // // - // Methods from java.awt.Graphics2D (alphabetical) - // // - @SuppressWarnings("rawtypes") - public abstract void addRenderingHints(Map hints); - - public abstract void clip(Shape s); - - public abstract void draw(Shape s); - - // NOTE: overridden in Graphics2D - // public abstract void draw3DRect(int x, int y, int width, int height, - // boolean raised); - public abstract void drawGlyphVector(GlyphVector g, float x, float y); - - public abstract void drawImage(BufferedImage img, BufferedImageOp op, - int x, int y); - - public abstract boolean drawImage(Image img, AffineTransform xform, - ImageObserver obs); - - public abstract void drawRenderableImage(RenderableImage img, - AffineTransform xform); - - public abstract void drawRenderedImage(RenderedImage img, - AffineTransform xform); - - public abstract void drawString(AttributedCharacterIterator iterator, - float x, float y); - - // NOTE: overridden in Graphics2D - // public abstract void drawString(AttributedCharacterIterator iterator, int - // x, int y); - // NOTE: redefined in Graphics2D - // public abstract void drawString(String str, int x, int y); - public abstract void drawString(String str, float x, float y); - - public abstract void fill(Shape s); - - /** - * Fills an are with the given paint using in offscreen BufferedImage. Used - * for drawing GradientPaint or image - * - * @param shape - * Shape usede as clipping area - * @param paint - * Paint used - */ - protected void fill(Shape shape, Paint paint) { - Rectangle2D bounds = shape.getBounds2D(); - - // create image - BufferedImage image = new BufferedImage((int) Math.ceil(bounds - .getWidth()) + 1, (int) Math.ceil(bounds.getHeight()) + 1, - BufferedImage.TYPE_INT_ARGB); - - // fill background - Graphics2D graphics = image.createGraphics(); - graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, - 0.0f)); - graphics.fill(graphics.getDeviceConfiguration().getBounds()); - graphics.setComposite(AlphaComposite.SrcOver); - - // draw paint - graphics.setPaint(paint); - graphics.translate(-bounds.getMinX(), -bounds.getMinY()); - graphics.fill(shape); - graphics.dispose(); - - // draw image - Shape clip = getClip(); - clip(shape); - drawImage(image, (int) bounds.getX(), (int) bounds.getY(), null); - setClip(clip); - } - - // NOTE: overridden in Graphics2D - // public abstract void fill3DRect(int x, int y, - // int width, int height, - // boolean raised); - public abstract Color getBackground(); - - public abstract Composite getComposite(); - - public abstract GraphicsConfiguration getDeviceConfiguration(); - - public abstract FontRenderContext getFontRenderContext(); - - public abstract Paint getPaint(); - - public abstract Object getRenderingHint(RenderingHints.Key inteKey); - - public abstract RenderingHints getRenderingHints(); - - public abstract Stroke getStroke(); - - public abstract AffineTransform getTransform(); - - public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke); - - public abstract void rotate(double theta); - - public abstract void rotate(double theta, double x, double y); - - public abstract void scale(double sx, double sy); - - public abstract void setBackground(Color color); - - public abstract void setComposite(Composite comp); - - public abstract void setPaint(Paint paint); - - public abstract void setRenderingHint(RenderingHints.Key hintKey, - Object hintValue); - - @SuppressWarnings("rawtypes") - public abstract void setRenderingHints(Map hints); - - public abstract void setStroke(Stroke s); - - public abstract void setTransform(AffineTransform xform); - - public abstract void shear(double shx, double shy); - - public abstract void transform(AffineTransform xform); - - public abstract void translate(double tx, double ty); - - // NOTE: redefines in Graphics2D - // public abstract void translate(int x, int y); - - /* - * ========================================================================== - * =========== - * - * Methods added to VectorGraphics (alphabetical) - * - * ========================================================================== - * =========== - */ - - public abstract void clearRect(double x, double y, double width, - double height); - - public abstract void clipRect(double x, double y, double width, - double height); - - public abstract Graphics create(double x, double y, double width, - double height); - - /** - * Draws an arc. Uses Arc2D to call draw(Shape). - * - */ - public abstract void drawArc(double x, double y, double width, - double height, double startAngle, double arcAngle); - - /** - * Draws a straight line. Uses Line2D to call draw(Shape). - * - */ - public abstract void drawLine(double x1, double y1, double x2, double y2); - - /** - * Draws an oval. Uses Ellipse2D to call draw(Shape). - * - */ - public abstract void drawOval(double x, double y, double width, - double height); - - /** - * Draws a polygon. Uses createShape(...) to call draw(Shape). - * - */ - public abstract void drawPolygon(double[] xPoints, double[] yPoints, - int nPoints); - - /** - * Draws a polyline. Uses createShape(...) to call draw(Shape). - * - */ - public abstract void drawPolyline(double[] xPoints, double[] yPoints, - int nPoints); - - /** - * Draws a rectangle. Uses Rectangle2D to call draw(Shape). - * - */ - public abstract void drawRect(double x, double y, double width, - double height); - - /** - * Draws a rounded rectangle. Uses RoundRectangle2D to call draw(Shape). - * - */ - public abstract void drawRoundRect(double x, double y, double width, - double height, double arcWidth, double arcHeight); - - public abstract void drawSymbol(int x, int y, int size, int symbol); - - public abstract void drawSymbol(double x, double y, double size, int symbol); - - public abstract void fillSymbol(int x, int y, int size, int symbol); - - public abstract void fillSymbol(double x, double y, double size, int symbol); - - public abstract void fillAndDrawSymbol(int x, int y, int size, int symbol, - Color fillColor); - - public abstract void fillAndDrawSymbol(double x, double y, double size, - int symbol, Color fillColor); - - /** - * Draws a string. - * - */ - public abstract void drawString(String str, double x, double y); - - public abstract void drawString(TagString str, double x, double y); - - public abstract void drawString(String str, double x, double y, - int horizontal, int vertical); - - public abstract void drawString(TagString str, double x, double y, - int horizontal, int vertical); - - /** - * Draws a string with a lot of parameters. - * - * @param str - * text to be drawn - * @param x - * coordinate to draw string - * @param y - * coordinate to draw string - * @param horizontal - * alignment of the text - * @param vertical - * alignment of the text - * @param framed - * true if text is surrounded by a frame - * @param frameColor - * color of the frame - * @param frameWidth - * witdh of the frame - * @param banner - * true if the frame is filled by a banner - * @param bannerColor - * color of the banner - */ - public abstract void drawString(String str, double x, double y, - int horizontal, int vertical, boolean framed, Color frameColor, - double frameWidth, boolean banner, Color bannerColor); - - /** - * Draws a TagString with a lot of parameters. - * - * @param str - * Tagged text to be drawn - * @param x - * coordinate to draw string - * @param y - * coordinate to draw string - * @param horizontal - * alignment of the text - * @param vertical - * alignment of the text - * @param framed - * true if text is surrounded by a frame - * @param frameColor - * color of the frame - * @param frameWidth - * witdh of the frame - * @param banner - * true if the frame is filled by a banner - * @param bannerColor - * color of the banner - */ - public abstract void drawString(TagString str, double x, double y, - int horizontal, int vertical, boolean framed, Color frameColor, - double frameWidth, boolean banner, Color bannerColor); - - public abstract void endExport(); - - public abstract void fillAndDraw(Shape s, Color fillColor); - - /** - * Fills an arc. Uses Arc2D to call fill(Shape). - * - */ - public abstract void fillArc(double x, double y, double width, - double height, double startAngle, double arcAngle); - - /** - * Fills an oval. Uses Ellipse2D to call fill(Shape). - * - */ - public abstract void fillOval(double x, double y, double width, - double height); - - /** - * Fills a polygon. Uses createShape(...) to call fill(Shape). - * - */ - public abstract void fillPolygon(double[] xPoints, double[] yPoints, - int nPoints); - - /** - * Fills a rectangle. Uses Rectangle2D to call fill(Shape). - * - */ - public abstract void fillRect(double x, double y, double width, - double height); - - /** - * Fills a rounded rectangle. Uses RoundRectangle2D to call fill(Shape). - * - */ - public abstract void fillRoundRect(double x, double y, double width, - double height, double arcWidth, double arcHeight); - - public abstract int getColorMode(); - - public abstract String getCreator(); - - public abstract boolean isDeviceIndependent(); - - public abstract void printComment(String comment); - - public abstract void setClip(double x, double y, double width, double height); - - public abstract void setColorMode(int colorMode); - - public abstract void setCreator(String creator); - - public abstract void setDeviceIndependent(boolean isDeviceIndependent); - - public abstract void setLineWidth(int width); - - public abstract void setLineWidth(double width); - - public abstract void startExport(); - - // STATIC stuff below - public static VectorGraphics create(Graphics g) { - if ((g != null) && !(g instanceof VectorGraphics)) { - return new PixelGraphics2D(g); - } - return (VectorGraphics) g; - } - - // STATIC stuff below - private static Hashtable symbols = new Hashtable( - 15); - - static { - symbols.put("vline", new Integer(SYMBOL_VLINE)); //$NON-NLS-1$ - symbols.put("hline", new Integer(SYMBOL_HLINE)); //$NON-NLS-1$ - symbols.put("plus", new Integer(SYMBOL_PLUS)); //$NON-NLS-1$ - symbols.put("cross", new Integer(SYMBOL_CROSS)); //$NON-NLS-1$ - symbols.put("star", new Integer(SYMBOL_STAR)); //$NON-NLS-1$ - symbols.put("circle", new Integer(SYMBOL_CIRCLE)); //$NON-NLS-1$ - symbols.put("box", new Integer(SYMBOL_BOX)); //$NON-NLS-1$ - symbols.put("up_triangle", new Integer(SYMBOL_UP_TRIANGLE)); //$NON-NLS-1$ - symbols.put("dn_triangle", new Integer(SYMBOL_DN_TRIANGLE)); //$NON-NLS-1$ - symbols.put("diamond", new Integer(SYMBOL_DIAMOND)); //$NON-NLS-1$ - } - - private static Hashtable alignments = new Hashtable( - 6); - - static { - alignments.put("baseline", new Integer(TEXT_BASELINE)); //$NON-NLS-1$ - alignments.put("left", new Integer(TEXT_LEFT)); //$NON-NLS-1$ - alignments.put("top", new Integer(TEXT_TOP)); //$NON-NLS-1$ - alignments.put("middle", new Integer(TEXT_CENTER)); //$NON-NLS-1$ - alignments.put("center", new Integer(TEXT_CENTER)); //$NON-NLS-1$ - alignments.put("right", new Integer(TEXT_RIGHT)); //$NON-NLS-1$ - alignments.put("bottom", new Integer(TEXT_BOTTOM)); //$NON-NLS-1$ - } - - public static int getTextAlignment(String name) { - Integer i = (Integer) alignments.get(name.toLowerCase()); - return (i != null) ? i.intValue() : TEXT_CENTER; - } - - public static int getSymbol(String name) { - Integer i = (Integer) symbols.get(name.toLowerCase()); - return (i != null) ? i.intValue() : SYMBOL_PLUS; - } - - public static double getYalignment(double y, double ascent, double descent, - int alignment) { - // vertical alignment - switch (alignment) { - case TEXT_TOP: - y = y + ascent - descent; - break; - case TEXT_CENTER: - y = y + ((ascent + descent) / 2) - descent; - break; - case TEXT_BOTTOM: - y = y - descent; - break; - case TEXT_BASELINE: - default: - break; - } - return y; - } - - public static double getXalignment(double x, double width, int alignment) { - // horizontal alignment - switch (alignment) { - case TEXT_CENTER: - x = x - (width / 2); - break; - case TEXT_RIGHT: - x = x - width; - break; - case TEXT_LEFT: - default: - break; - } - return x; - } -} +// Copyright 2000-2007, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.text.AttributedCharacterIterator; +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; + +/** + * The drawing methods which are guaranteed to work for the various output + * formats of the VectorGraphics system on the Java 2 platform. All methods are + * re-declared abstract, since this class inherits from Graphics2D and we would + * not want to actually or accidentally use any of those methods, except for the + * ones noted. + * + * Some int methods need to call their super.methods otherwise the compiler + * cannot make a distinction if it needs to convert int to doubles or call the + * super int method. + * + * Note that many of these routines modify the current transformation matrix. To + * guard against unintended side effects the following method should be used: + * + *
    + * 
    + *  Graphics2D tempGraphics = (Graphics2D) originalGraphics.create();
    + *  tempGraphics.setStroke(originalGraphics.getStroke());
    + *  tempGraphics.rotate(...);
    + *  tempGraphics.translate(...);
    + *  ...drawing methods on tempGraphics...
    + *  tempGraphics.dispose();
    + * 
    + * 
    + * + * where originalGraphics is the original Graphics2D + * object. Note that dispose must be called when the drawing + * finishes on tempGraphics and that no drawing should be done on + * originalGraphics until dispose has been called. + * + * @author Charles Loomis + * @author Mark Donszelmann + * @author Jason Wong + */ +public abstract class VectorGraphics extends Graphics2D implements + VectorGraphicsConstants { + + public abstract void setProperties(Properties newProperties); + + protected abstract void initProperties(Properties defaults); + + protected abstract Properties getProperties(); + + public abstract String getProperty(String key); + + public abstract Color getPropertyColor(String key); + + public abstract Rectangle getPropertyRectangle(String key); + + public abstract Dimension getPropertyDimension(String key); + + public abstract int getPropertyInt(String key); + + public abstract double getPropertyDouble(String key); + + public abstract boolean isProperty(String key); + + // // + // Methods defined in java.awt.Graphics (alphabetical) + // // + + public abstract void clearRect(int x, int y, int width, int height); + + public abstract void clipRect(int x, int y, int width, int height); + + public abstract void copyArea(int x, int y, int width, int height, int dx, + int dy); + + public abstract Graphics create(); + + // NOTE: implemented in Graphics, must be implemented here otherwise the + // compiler + // cannot choose between converting ints to doubles or calling the + // superclass. + public Graphics create(int x, int y, int width, int height) { + return super.create(x, y, width, height); + } + + public abstract void dispose(); + + // NOTE: implemented in Graphics + // public abstract void draw3DRect(int x, int y, + // int width, int height, + // boolean raised); + public abstract void drawArc(int x, int y, int width, int height, + int startAngle, int arcAngle); + + // NOTE: implemented in Graphics + // public abstract void drawBytes(byte[] data, int offset, + // int length, + // int x, int y); + // NOTE: implemented in Graphics + // public abstract void drawChars(char[] data, int offset, + // int length, + // int x, int y); + public abstract boolean drawImage(Image image, int x, int y, + ImageObserver observer); + + public abstract boolean drawImage(Image image, int x, int y, int width, + int height, ImageObserver observer); + + public abstract boolean drawImage(Image image, int x, int y, Color bgColor, + ImageObserver observer); + + public abstract boolean drawImage(Image image, int x, int y, int width, + int height, Color bgColor, ImageObserver observer); + + public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2, + int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer); + + public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2, + int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor, + ImageObserver observer); + + public abstract void drawLine(int x1, int y1, int x2, int y2); + + public abstract void drawOval(int x, int y, int width, int height); + + public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints); + + // NOTE implemented in Graphics + // public abstract void drawPolygon(Polygon p); + public abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints); + + public abstract void drawRect(int x, int y, int width, int height); + + public abstract void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight); + + public abstract void drawString(AttributedCharacterIterator iterator, + int x, int y); + + public abstract void drawString(String str, int x, int y); + + // NOTE: implemented in Graphics + // public abstract void fill3DRect(int x, int y, + // int width, int height, + // boolean raised); + public abstract void fillArc(int x, int y, int width, int height, + int startAngle, int arcAngle); + + public abstract void fillOval(int x, int y, int width, int height); + + public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints); + + // NOTE: implemented in Graphics + // public abstract void fillPolygon(Polygon p); + public abstract void fillRect(int x, int y, int width, int height); + + public abstract void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight); + + // NOTE: implemented in Graphics + // public abstract void finalize(); + public abstract Shape getClip(); + + public abstract Rectangle getClipBounds(); + + public abstract Rectangle getClipBounds(Rectangle r); + + // NOTE: implemented in Graphics + // public abstract Rectangle getClipRect(); + public abstract Color getColor(); + + public abstract Font getFont(); + + // NOTE: implemented in Graphics + // public abstract FontMetrics getFontMetrics(); + public abstract FontMetrics getFontMetrics(Font font); + + // NOTE: implemented in Graphics + // public abstract boolean hitClip(int x, int y, int width, int height); + public abstract void setClip(int x, int y, int width, int height); + + public abstract void setClip(Shape clip); + + public abstract void setColor(Color c); + + public abstract void setFont(Font font); + + public abstract void setPaintMode(); + + public abstract void setXORMode(Color c1); + + public abstract String toString(); + + public abstract void translate(int x, int y); + + // // + // Methods from java.awt.Graphics2D (alphabetical) + // // + @SuppressWarnings("rawtypes") + public abstract void addRenderingHints(Map hints); + + public abstract void clip(Shape s); + + public abstract void draw(Shape s); + + // NOTE: overridden in Graphics2D + // public abstract void draw3DRect(int x, int y, int width, int height, + // boolean raised); + public abstract void drawGlyphVector(GlyphVector g, float x, float y); + + public abstract void drawImage(BufferedImage img, BufferedImageOp op, + int x, int y); + + public abstract boolean drawImage(Image img, AffineTransform xform, + ImageObserver obs); + + public abstract void drawRenderableImage(RenderableImage img, + AffineTransform xform); + + public abstract void drawRenderedImage(RenderedImage img, + AffineTransform xform); + + public abstract void drawString(AttributedCharacterIterator iterator, + float x, float y); + + // NOTE: overridden in Graphics2D + // public abstract void drawString(AttributedCharacterIterator iterator, int + // x, int y); + // NOTE: redefined in Graphics2D + // public abstract void drawString(String str, int x, int y); + public abstract void drawString(String str, float x, float y); + + public abstract void fill(Shape s); + + /** + * Fills an are with the given paint using in offscreen BufferedImage. Used + * for drawing GradientPaint or image + * + * @param shape + * Shape usede as clipping area + * @param paint + * Paint used + */ + protected void fill(Shape shape, Paint paint) { + Rectangle2D bounds = shape.getBounds2D(); + + // create image + BufferedImage image = new BufferedImage((int) Math.ceil(bounds + .getWidth()) + 1, (int) Math.ceil(bounds.getHeight()) + 1, + BufferedImage.TYPE_INT_ARGB); + + // fill background + Graphics2D graphics = image.createGraphics(); + graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, + 0.0f)); + graphics.fill(graphics.getDeviceConfiguration().getBounds()); + graphics.setComposite(AlphaComposite.SrcOver); + + // draw paint + graphics.setPaint(paint); + graphics.translate(-bounds.getMinX(), -bounds.getMinY()); + graphics.fill(shape); + graphics.dispose(); + + // draw image + Shape clip = getClip(); + clip(shape); + drawImage(image, (int) bounds.getX(), (int) bounds.getY(), null); + setClip(clip); + } + + // NOTE: overridden in Graphics2D + // public abstract void fill3DRect(int x, int y, + // int width, int height, + // boolean raised); + public abstract Color getBackground(); + + public abstract Composite getComposite(); + + public abstract GraphicsConfiguration getDeviceConfiguration(); + + public abstract FontRenderContext getFontRenderContext(); + + public abstract Paint getPaint(); + + public abstract Object getRenderingHint(RenderingHints.Key inteKey); + + public abstract RenderingHints getRenderingHints(); + + public abstract Stroke getStroke(); + + public abstract AffineTransform getTransform(); + + public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke); + + public abstract void rotate(double theta); + + public abstract void rotate(double theta, double x, double y); + + public abstract void scale(double sx, double sy); + + public abstract void setBackground(Color color); + + public abstract void setComposite(Composite comp); + + public abstract void setPaint(Paint paint); + + public abstract void setRenderingHint(RenderingHints.Key hintKey, + Object hintValue); + + @SuppressWarnings("rawtypes") + public abstract void setRenderingHints(Map hints); + + public abstract void setStroke(Stroke s); + + public abstract void setTransform(AffineTransform xform); + + public abstract void shear(double shx, double shy); + + public abstract void transform(AffineTransform xform); + + public abstract void translate(double tx, double ty); + + // NOTE: redefines in Graphics2D + // public abstract void translate(int x, int y); + + /* + * ========================================================================== + * =========== + * + * Methods added to VectorGraphics (alphabetical) + * + * ========================================================================== + * =========== + */ + + public abstract void clearRect(double x, double y, double width, + double height); + + public abstract void clipRect(double x, double y, double width, + double height); + + public abstract Graphics create(double x, double y, double width, + double height); + + /** + * Draws an arc. Uses Arc2D to call draw(Shape). + * + */ + public abstract void drawArc(double x, double y, double width, + double height, double startAngle, double arcAngle); + + /** + * Draws a straight line. Uses Line2D to call draw(Shape). + * + */ + public abstract void drawLine(double x1, double y1, double x2, double y2); + + /** + * Draws an oval. Uses Ellipse2D to call draw(Shape). + * + */ + public abstract void drawOval(double x, double y, double width, + double height); + + /** + * Draws a polygon. Uses createShape(...) to call draw(Shape). + * + */ + public abstract void drawPolygon(double[] xPoints, double[] yPoints, + int nPoints); + + /** + * Draws a polyline. Uses createShape(...) to call draw(Shape). + * + */ + public abstract void drawPolyline(double[] xPoints, double[] yPoints, + int nPoints); + + /** + * Draws a rectangle. Uses Rectangle2D to call draw(Shape). + * + */ + public abstract void drawRect(double x, double y, double width, + double height); + + /** + * Draws a rounded rectangle. Uses RoundRectangle2D to call draw(Shape). + * + */ + public abstract void drawRoundRect(double x, double y, double width, + double height, double arcWidth, double arcHeight); + + public abstract void drawSymbol(int x, int y, int size, int symbol); + + public abstract void drawSymbol(double x, double y, double size, int symbol); + + public abstract void fillSymbol(int x, int y, int size, int symbol); + + public abstract void fillSymbol(double x, double y, double size, int symbol); + + public abstract void fillAndDrawSymbol(int x, int y, int size, int symbol, + Color fillColor); + + public abstract void fillAndDrawSymbol(double x, double y, double size, + int symbol, Color fillColor); + + /** + * Draws a string. + * + */ + public abstract void drawString(String str, double x, double y); + + public abstract void drawString(TagString str, double x, double y); + + public abstract void drawString(String str, double x, double y, + int horizontal, int vertical); + + public abstract void drawString(TagString str, double x, double y, + int horizontal, int vertical); + + /** + * Draws a string with a lot of parameters. + * + * @param str + * text to be drawn + * @param x + * coordinate to draw string + * @param y + * coordinate to draw string + * @param horizontal + * alignment of the text + * @param vertical + * alignment of the text + * @param framed + * true if text is surrounded by a frame + * @param frameColor + * color of the frame + * @param frameWidth + * witdh of the frame + * @param banner + * true if the frame is filled by a banner + * @param bannerColor + * color of the banner + */ + public abstract void drawString(String str, double x, double y, + int horizontal, int vertical, boolean framed, Color frameColor, + double frameWidth, boolean banner, Color bannerColor); + + /** + * Draws a TagString with a lot of parameters. + * + * @param str + * Tagged text to be drawn + * @param x + * coordinate to draw string + * @param y + * coordinate to draw string + * @param horizontal + * alignment of the text + * @param vertical + * alignment of the text + * @param framed + * true if text is surrounded by a frame + * @param frameColor + * color of the frame + * @param frameWidth + * witdh of the frame + * @param banner + * true if the frame is filled by a banner + * @param bannerColor + * color of the banner + */ + public abstract void drawString(TagString str, double x, double y, + int horizontal, int vertical, boolean framed, Color frameColor, + double frameWidth, boolean banner, Color bannerColor); + + public abstract void endExport(); + + public abstract void fillAndDraw(Shape s, Color fillColor); + + /** + * Fills an arc. Uses Arc2D to call fill(Shape). + * + */ + public abstract void fillArc(double x, double y, double width, + double height, double startAngle, double arcAngle); + + /** + * Fills an oval. Uses Ellipse2D to call fill(Shape). + * + */ + public abstract void fillOval(double x, double y, double width, + double height); + + /** + * Fills a polygon. Uses createShape(...) to call fill(Shape). + * + */ + public abstract void fillPolygon(double[] xPoints, double[] yPoints, + int nPoints); + + /** + * Fills a rectangle. Uses Rectangle2D to call fill(Shape). + * + */ + public abstract void fillRect(double x, double y, double width, + double height); + + /** + * Fills a rounded rectangle. Uses RoundRectangle2D to call fill(Shape). + * + */ + public abstract void fillRoundRect(double x, double y, double width, + double height, double arcWidth, double arcHeight); + + public abstract int getColorMode(); + + public abstract String getCreator(); + + public abstract boolean isDeviceIndependent(); + + public abstract void printComment(String comment); + + public abstract void setClip(double x, double y, double width, double height); + + public abstract void setColorMode(int colorMode); + + public abstract void setCreator(String creator); + + public abstract void setDeviceIndependent(boolean isDeviceIndependent); + + public abstract void setLineWidth(int width); + + public abstract void setLineWidth(double width); + + public abstract void startExport(); + + // STATIC stuff below + public static VectorGraphics create(Graphics g) { + if ((g != null) && !(g instanceof VectorGraphics)) { + return new PixelGraphics2D(g); + } + return (VectorGraphics) g; + } + + // STATIC stuff below + private static Hashtable symbols = new Hashtable( + 15); + + static { + symbols.put("vline", new Integer(SYMBOL_VLINE)); //$NON-NLS-1$ + symbols.put("hline", new Integer(SYMBOL_HLINE)); //$NON-NLS-1$ + symbols.put("plus", new Integer(SYMBOL_PLUS)); //$NON-NLS-1$ + symbols.put("cross", new Integer(SYMBOL_CROSS)); //$NON-NLS-1$ + symbols.put("star", new Integer(SYMBOL_STAR)); //$NON-NLS-1$ + symbols.put("circle", new Integer(SYMBOL_CIRCLE)); //$NON-NLS-1$ + symbols.put("box", new Integer(SYMBOL_BOX)); //$NON-NLS-1$ + symbols.put("up_triangle", new Integer(SYMBOL_UP_TRIANGLE)); //$NON-NLS-1$ + symbols.put("dn_triangle", new Integer(SYMBOL_DN_TRIANGLE)); //$NON-NLS-1$ + symbols.put("diamond", new Integer(SYMBOL_DIAMOND)); //$NON-NLS-1$ + } + + private static Hashtable alignments = new Hashtable( + 6); + + static { + alignments.put("baseline", new Integer(TEXT_BASELINE)); //$NON-NLS-1$ + alignments.put("left", new Integer(TEXT_LEFT)); //$NON-NLS-1$ + alignments.put("top", new Integer(TEXT_TOP)); //$NON-NLS-1$ + alignments.put("middle", new Integer(TEXT_CENTER)); //$NON-NLS-1$ + alignments.put("center", new Integer(TEXT_CENTER)); //$NON-NLS-1$ + alignments.put("right", new Integer(TEXT_RIGHT)); //$NON-NLS-1$ + alignments.put("bottom", new Integer(TEXT_BOTTOM)); //$NON-NLS-1$ + } + + public static int getTextAlignment(String name) { + Integer i = (Integer) alignments.get(name.toLowerCase()); + return (i != null) ? i.intValue() : TEXT_CENTER; + } + + public static int getSymbol(String name) { + Integer i = (Integer) symbols.get(name.toLowerCase()); + return (i != null) ? i.intValue() : SYMBOL_PLUS; + } + + public static double getYalignment(double y, double ascent, double descent, + int alignment) { + // vertical alignment + switch (alignment) { + case TEXT_TOP: + y = y + ascent - descent; + break; + case TEXT_CENTER: + y = y + ((ascent + descent) / 2) - descent; + break; + case TEXT_BOTTOM: + y = y - descent; + break; + case TEXT_BASELINE: + default: + break; + } + return y; + } + + public static double getXalignment(double x, double width, int alignment) { + // horizontal alignment + switch (alignment) { + case TEXT_CENTER: + x = x - (width / 2); + break; + case TEXT_RIGHT: + x = x - width; + break; + case TEXT_LEFT: + default: + break; + } + return x; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphicsConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphicsConstants.java index 126e1b782..792d72905 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphicsConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/VectorGraphicsConstants.java @@ -1,128 +1,128 @@ -// University of Santa Cruz, California, USA and -// CERN, Geneva, Switzerland, Copyright (c) 2000 -package org.xmind.org.freehep.graphics2d; - -/** - * This interface defines useful constants for users of the VectorGraphics - * interface. - * - * @author Charles Loomis - * @author Jason Wong - */ -public interface VectorGraphicsConstants { - - // // - // Symbol definitions - // // - - /** - * Vertical line (|) symbol. - */ - final public static int SYMBOL_VLINE = 0; - - /** - * Horizontal line (-) symbol. - */ - final public static int SYMBOL_HLINE = 1; - - /** - * Plus-shaped (+) symbol. - */ - final public static int SYMBOL_PLUS = 2; - - /** - * An x-shaped (x) symbol. - */ - final public static int SYMBOL_CROSS = 3; - - /** - * An eight-point star created by combining the plus and cross symbols. - */ - final public static int SYMBOL_STAR = 4; - - /** - * An open circle (o) symbol. - */ - final public static int SYMBOL_CIRCLE = 5; - - /** - * An open square symbol. - */ - final public static int SYMBOL_BOX = 6; - - /** - * An open equilateral triangle pointing up. - */ - final public static int SYMBOL_UP_TRIANGLE = 7; - - /** - * An open equilateral triangle pointing down. - */ - final public static int SYMBOL_DN_TRIANGLE = 8; - - /** - * An open square symbol rotated by 45 degrees. - */ - final public static int SYMBOL_DIAMOND = 9; - - /** - * The number of defined symbols. Used in implementations of the - * VectorGraphics interfaces. - */ - final public static int NUMBER_OF_SYMBOLS = 10; - - // // - // Text alignment definitions - // // - - /** - * Constant indicating that a string should be aligned vertically with the - * baseline of the text. This is the default in drawString calls which do - * not specify an alignment. - */ - public static final int TEXT_BASELINE = 0; - - /** - * Constant indicating that a string should be aligned vertically with the - * top of the text. - */ - public static final int TEXT_TOP = 1; - - /** - * Constant indicating that a string should be aligned vertically with the - * bottom of the text. - */ - public static final int TEXT_BOTTOM = 3; - - /** - * Constant indicating that a string should be aligned by the center. This - * is used for both horizontal and vertical alignment. - */ - public static final int TEXT_CENTER = 2; - - /** - * Constant indicating that a string should be aligned horizontally with the - * left side of the text. This is the default for drawString calls which do - * not specify an alignment. - */ - public static final int TEXT_LEFT = 1; - - /** - * Constant indicating that the string should be aligned horizontally with - * the right side of the text. - */ - public static final int TEXT_RIGHT = 3; - - /** - * Constant indicating the maximum number of vertical alignments. Used in - * implementation of the VectorGraphics interfaces. - */ - public static final int NUMBER_OF_VERTICAL_ALIGNMENTS = 4; - - /** - * Constant indicating the maximum number of horizontal alignments. Used in - * implementation of the VectorGraphics interfaces. - */ - public static final int NUMBER_OF_HORIZ_ALIGNMENTS = 4; - -} +// University of Santa Cruz, California, USA and +// CERN, Geneva, Switzerland, Copyright (c) 2000 +package org.xmind.org.freehep.graphics2d; + +/** + * This interface defines useful constants for users of the VectorGraphics + * interface. + * + * @author Charles Loomis + * @author Jason Wong + */ +public interface VectorGraphicsConstants { + + // // + // Symbol definitions + // // + + /** + * Vertical line (|) symbol. + */ + final public static int SYMBOL_VLINE = 0; + + /** + * Horizontal line (-) symbol. + */ + final public static int SYMBOL_HLINE = 1; + + /** + * Plus-shaped (+) symbol. + */ + final public static int SYMBOL_PLUS = 2; + + /** + * An x-shaped (x) symbol. + */ + final public static int SYMBOL_CROSS = 3; + + /** + * An eight-point star created by combining the plus and cross symbols. + */ + final public static int SYMBOL_STAR = 4; + + /** + * An open circle (o) symbol. + */ + final public static int SYMBOL_CIRCLE = 5; + + /** + * An open square symbol. + */ + final public static int SYMBOL_BOX = 6; + + /** + * An open equilateral triangle pointing up. + */ + final public static int SYMBOL_UP_TRIANGLE = 7; + + /** + * An open equilateral triangle pointing down. + */ + final public static int SYMBOL_DN_TRIANGLE = 8; + + /** + * An open square symbol rotated by 45 degrees. + */ + final public static int SYMBOL_DIAMOND = 9; + + /** + * The number of defined symbols. Used in implementations of the + * VectorGraphics interfaces. + */ + final public static int NUMBER_OF_SYMBOLS = 10; + + // // + // Text alignment definitions + // // + + /** + * Constant indicating that a string should be aligned vertically with the + * baseline of the text. This is the default in drawString calls which do + * not specify an alignment. + */ + public static final int TEXT_BASELINE = 0; + + /** + * Constant indicating that a string should be aligned vertically with the + * top of the text. + */ + public static final int TEXT_TOP = 1; + + /** + * Constant indicating that a string should be aligned vertically with the + * bottom of the text. + */ + public static final int TEXT_BOTTOM = 3; + + /** + * Constant indicating that a string should be aligned by the center. This + * is used for both horizontal and vertical alignment. + */ + public static final int TEXT_CENTER = 2; + + /** + * Constant indicating that a string should be aligned horizontally with the + * left side of the text. This is the default for drawString calls which do + * not specify an alignment. + */ + public static final int TEXT_LEFT = 1; + + /** + * Constant indicating that the string should be aligned horizontally with + * the right side of the text. + */ + public static final int TEXT_RIGHT = 3; + + /** + * Constant indicating the maximum number of vertical alignments. Used in + * implementation of the VectorGraphics interfaces. + */ + public static final int NUMBER_OF_VERTICAL_ALIGNMENTS = 4; + + /** + * Constant indicating the maximum number of horizontal alignments. Used in + * implementation of the VectorGraphics interfaces. + */ + public static final int NUMBER_OF_HORIZ_ALIGNMENTS = 4; + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/WebColor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/WebColor.java index 48be01d57..6bc6fffdf 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/WebColor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/WebColor.java @@ -1,96 +1,96 @@ -// Copyright 2002, FreeHEP. -package org.xmind.org.freehep.graphics2d; - -import java.awt.Color; - -/** - * WebColor which adheres to the web color set consisting of 216 equally spaced - * colors, which include black and white. The spacing is 0x33, which makes the - * smallest value 0x00 and the largest 0xFF. These colors are guaranteed to work - * in browsers without dithering. WebColors are opaque. - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class WebColor extends Color { - - private static final long serialVersionUID = 8824104766106043154L; - - private final static int space = 0x33; - - private final static int space2 = space / 2; - - // redefine all java colors in terms of WebColors - public final static WebColor white = new WebColor(Color.WHITE); - - public final static WebColor WHITE = white; - - public final static WebColor lightGray = new WebColor(Color.LIGHT_GRAY); - - public final static WebColor LIGHT_GRAY = lightGray; - - public final static WebColor gray = new WebColor(Color.GRAY); - - public final static WebColor GRAY = gray; - - public final static WebColor darkGray = new WebColor(Color.DARK_GRAY); - - public final static WebColor DARK_GRAY = darkGray; - - public final static WebColor black = new WebColor(Color.BLACK); - - public final static WebColor BLACK = black; - - public final static WebColor red = new WebColor(Color.RED); - - public final static WebColor RED = red; - - public final static WebColor pink = new WebColor(Color.PINK); - - public final static WebColor PINK = pink; - - public final static WebColor orange = new WebColor(Color.ORANGE); - - public final static WebColor ORANGE = orange; - - public final static WebColor yellow = new WebColor(Color.YELLOW); - - public final static WebColor YELLOW = yellow; - - public final static WebColor green = new WebColor(Color.GREEN); - - public final static WebColor GREEN = green; - - public final static WebColor magenta = new WebColor(Color.MAGENTA); - - public final static WebColor MAGENTA = magenta; - - public final static WebColor cyan = new WebColor(Color.CYAN); - - public final static WebColor CYAN = cyan; - - public final static WebColor blue = new WebColor(Color.BLUE); - - public final static WebColor BLUE = blue; - - public WebColor(int red, int green, int blue) { - super(((red + space2) / space) * space, ((green + space2) / space) - * space, ((blue + space2) / space) * space); - } - - public WebColor(Color color) { - this(color.getRed(), color.getGreen(), color.getBlue()); - } - - public WebColor(float red, float green, float blue) { - this((int) (red * 255), (int) (green * 255), (int) (blue * 255)); - } - - public static WebColor create(Color color) { - if (color == null) - return null; - if (color instanceof WebColor) - return (WebColor) color; - return new WebColor(color); - } -} +// Copyright 2002, FreeHEP. +package org.xmind.org.freehep.graphics2d; + +import java.awt.Color; + +/** + * WebColor which adheres to the web color set consisting of 216 equally spaced + * colors, which include black and white. The spacing is 0x33, which makes the + * smallest value 0x00 and the largest 0xFF. These colors are guaranteed to work + * in browsers without dithering. WebColors are opaque. + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class WebColor extends Color { + + private static final long serialVersionUID = 8824104766106043154L; + + private final static int space = 0x33; + + private final static int space2 = space / 2; + + // redefine all java colors in terms of WebColors + public final static WebColor white = new WebColor(Color.WHITE); + + public final static WebColor WHITE = white; + + public final static WebColor lightGray = new WebColor(Color.LIGHT_GRAY); + + public final static WebColor LIGHT_GRAY = lightGray; + + public final static WebColor gray = new WebColor(Color.GRAY); + + public final static WebColor GRAY = gray; + + public final static WebColor darkGray = new WebColor(Color.DARK_GRAY); + + public final static WebColor DARK_GRAY = darkGray; + + public final static WebColor black = new WebColor(Color.BLACK); + + public final static WebColor BLACK = black; + + public final static WebColor red = new WebColor(Color.RED); + + public final static WebColor RED = red; + + public final static WebColor pink = new WebColor(Color.PINK); + + public final static WebColor PINK = pink; + + public final static WebColor orange = new WebColor(Color.ORANGE); + + public final static WebColor ORANGE = orange; + + public final static WebColor yellow = new WebColor(Color.YELLOW); + + public final static WebColor YELLOW = yellow; + + public final static WebColor green = new WebColor(Color.GREEN); + + public final static WebColor GREEN = green; + + public final static WebColor magenta = new WebColor(Color.MAGENTA); + + public final static WebColor MAGENTA = magenta; + + public final static WebColor cyan = new WebColor(Color.CYAN); + + public final static WebColor CYAN = cyan; + + public final static WebColor blue = new WebColor(Color.BLUE); + + public final static WebColor BLUE = blue; + + public WebColor(int red, int green, int blue) { + super(((red + space2) / space) * space, ((green + space2) / space) + * space, ((blue + space2) / space) * space); + } + + public WebColor(Color color) { + this(color.getRed(), color.getGreen(), color.getBlue()); + } + + public WebColor(float red, float green, float blue) { + this((int) (red * 255), (int) (green * 255), (int) (blue * 255)); + } + + public static WebColor create(Color color) { + if (color == null) + return null; + if (color instanceof WebColor) + return (WebColor) color; + return new WebColor(color); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/AbstractCharTable.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/AbstractCharTable.java index 958f2592a..60cf3e6ca 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/AbstractCharTable.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/AbstractCharTable.java @@ -1,36 +1,36 @@ -//Copyright 2001-2005 FreeHep -package org.xmind.org.freehep.graphics2d.font; - -/** - * Abstract Character Table, inherited by all the Generated Encoding Tables - * - * @author Simon Fischer - * @author Jason Wong - */ -public abstract class AbstractCharTable implements CharTable { - - public int toEncoding(char unicode) { - try { - String name = toName(unicode); - if (name == null) - return 0; - int enc = toEncoding(name); - if (enc > 255) { - System.out.println("toEncoding() returned illegal value for '" //$NON-NLS-1$ - + name + "': " + enc); //$NON-NLS-1$ - return 0; - } - return enc; - } catch (Exception e) { - return 0; - } - } - - public String toName(char c) { - return toName(new Character(c)); - } - - public String toName(Integer enc) { - return toName(enc.intValue()); - } -} +//Copyright 2001-2005 FreeHep +package org.xmind.org.freehep.graphics2d.font; + +/** + * Abstract Character Table, inherited by all the Generated Encoding Tables + * + * @author Simon Fischer + * @author Jason Wong + */ +public abstract class AbstractCharTable implements CharTable { + + public int toEncoding(char unicode) { + try { + String name = toName(unicode); + if (name == null) + return 0; + int enc = toEncoding(name); + if (enc > 255) { + System.out.println("toEncoding() returned illegal value for '" //$NON-NLS-1$ + + name + "': " + enc); //$NON-NLS-1$ + return 0; + } + return enc; + } catch (Exception e) { + return 0; + } + } + + public String toName(char c) { + return toName(new Character(c)); + } + + public String toName(Integer enc) { + return toName(enc.intValue()); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/CharTable.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/CharTable.java index ad00f5c04..a9a1e533b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/CharTable.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/CharTable.java @@ -1,89 +1,89 @@ -//Copyright 2001-2005 FreeHep -package org.xmind.org.freehep.graphics2d.font; - -/** - * Provides conversions between unicodes, names, and encodings for any - * particular encoding. - * - * @author Sami Kama - * @author Jason Wong - */ -public interface CharTable { - - /** - * Converts unicode character to name. - * - * @param c - * unicode character - * @return name - */ - public String toName(char c); - - /** - * Converts unicode Character object to name. - * - * @param c - * unicode Character object - * @return name - */ - public String toName(Character c); - - /** - * Converts character code into a name. - * - * @param enc - * code - * @return name - */ - public String toName(int enc); - - /** - * Converts character code Integer object into a name. - * - * @param enc - * code Integer object - * @return name - */ - public String toName(Integer enc); - - /** - * Converts name into character code. - * - * @param name - * name of the character - * @return character code - */ - public int toEncoding(String name); - - /** - * Converts a unicode into a character code. - * - * @param unicode - * unicode character - * @return character code - */ - public int toEncoding(char unicode); - - /** - * Converts a name to a unicode character. - * - * @param name - * of the character - * @return unicode character - */ - public char toUnicode(String name); - - /** - * Returns the name of the table. - * - * @return table name - */ - public String getName(); - - /** - * Returns the encoding name of the table. - * - * @return encoding name - */ - public String getEncoding(); -} +//Copyright 2001-2005 FreeHep +package org.xmind.org.freehep.graphics2d.font; + +/** + * Provides conversions between unicodes, names, and encodings for any + * particular encoding. + * + * @author Sami Kama + * @author Jason Wong + */ +public interface CharTable { + + /** + * Converts unicode character to name. + * + * @param c + * unicode character + * @return name + */ + public String toName(char c); + + /** + * Converts unicode Character object to name. + * + * @param c + * unicode Character object + * @return name + */ + public String toName(Character c); + + /** + * Converts character code into a name. + * + * @param enc + * code + * @return name + */ + public String toName(int enc); + + /** + * Converts character code Integer object into a name. + * + * @param enc + * code Integer object + * @return name + */ + public String toName(Integer enc); + + /** + * Converts name into character code. + * + * @param name + * name of the character + * @return character code + */ + public int toEncoding(String name); + + /** + * Converts a unicode into a character code. + * + * @param unicode + * unicode character + * @return character code + */ + public int toEncoding(char unicode); + + /** + * Converts a name to a unicode character. + * + * @param name + * of the character + * @return unicode character + */ + public char toUnicode(String name); + + /** + * Returns the name of the table. + * + * @return table name + */ + public String getName(); + + /** + * Returns the encoding name of the table. + * + * @return encoding name + */ + public String getEncoding(); +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Expert.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Expert.java index 9808e11fe..ac5545597 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Expert.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Expert.java @@ -1,874 +1,874 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated Expert Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class Expert extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public Expert() { - unicodeToName.put(new Character((char) 0xF7E6), "AEsmall"); - nameToUnicode.put("AEsmall", new Character((char) 0xF7E6)); - nameToEnc.put("AEsmall", new Integer(190)); - encToName[190] = "AEsmall"; - - unicodeToName.put(new Character((char) 0xF7E1), "Aacutesmall"); - nameToUnicode.put("Aacutesmall", new Character((char) 0xF7E1)); - nameToEnc.put("Aacutesmall", new Integer(135)); - encToName[135] = "Aacutesmall"; - - unicodeToName.put(new Character((char) 0xF7E2), "Acircumflexsmall"); - nameToUnicode.put("Acircumflexsmall", new Character((char) 0xF7E2)); - nameToEnc.put("Acircumflexsmall", new Integer(137)); - encToName[137] = "Acircumflexsmall"; - - unicodeToName.put(new Character((char) 0xF7B4), "Acutesmall"); - nameToUnicode.put("Acutesmall", new Character((char) 0xF7B4)); - nameToEnc.put("Acutesmall", new Integer(39)); - encToName[39] = "Acutesmall"; - - unicodeToName.put(new Character((char) 0xF7E4), "Adieresissmall"); - nameToUnicode.put("Adieresissmall", new Character((char) 0xF7E4)); - nameToEnc.put("Adieresissmall", new Integer(138)); - encToName[138] = "Adieresissmall"; - - unicodeToName.put(new Character((char) 0xF7E0), "Agravesmall"); - nameToUnicode.put("Agravesmall", new Character((char) 0xF7E0)); - nameToEnc.put("Agravesmall", new Integer(136)); - encToName[136] = "Agravesmall"; - - unicodeToName.put(new Character((char) 0xF7E5), "Aringsmall"); - nameToUnicode.put("Aringsmall", new Character((char) 0xF7E5)); - nameToEnc.put("Aringsmall", new Integer(140)); - encToName[140] = "Aringsmall"; - - unicodeToName.put(new Character((char) 0xF761), "Asmall"); - nameToUnicode.put("Asmall", new Character((char) 0xF761)); - nameToEnc.put("Asmall", new Integer(97)); - encToName[97] = "Asmall"; - - unicodeToName.put(new Character((char) 0xF7E3), "Atildesmall"); - nameToUnicode.put("Atildesmall", new Character((char) 0xF7E3)); - nameToEnc.put("Atildesmall", new Integer(139)); - encToName[139] = "Atildesmall"; - - unicodeToName.put(new Character((char) 0xF6F4), "Brevesmall"); - nameToUnicode.put("Brevesmall", new Character((char) 0xF6F4)); - nameToEnc.put("Brevesmall", new Integer(243)); - encToName[243] = "Brevesmall"; - - unicodeToName.put(new Character((char) 0xF762), "Bsmall"); - nameToUnicode.put("Bsmall", new Character((char) 0xF762)); - nameToEnc.put("Bsmall", new Integer(98)); - encToName[98] = "Bsmall"; - - unicodeToName.put(new Character((char) 0xF6F5), "Caronsmall"); - nameToUnicode.put("Caronsmall", new Character((char) 0xF6F5)); - nameToEnc.put("Caronsmall", new Integer(174)); - encToName[174] = "Caronsmall"; - - unicodeToName.put(new Character((char) 0xF7E7), "Ccedillasmall"); - nameToUnicode.put("Ccedillasmall", new Character((char) 0xF7E7)); - nameToEnc.put("Ccedillasmall", new Integer(141)); - encToName[141] = "Ccedillasmall"; - - unicodeToName.put(new Character((char) 0xF7B8), "Cedillasmall"); - nameToUnicode.put("Cedillasmall", new Character((char) 0xF7B8)); - nameToEnc.put("Cedillasmall", new Integer(201)); - encToName[201] = "Cedillasmall"; - - unicodeToName.put(new Character((char) 0xF6F6), "Circumflexsmall"); - nameToUnicode.put("Circumflexsmall", new Character((char) 0xF6F6)); - nameToEnc.put("Circumflexsmall", new Integer(94)); - encToName[94] = "Circumflexsmall"; - - unicodeToName.put(new Character((char) 0xF763), "Csmall"); - nameToUnicode.put("Csmall", new Character((char) 0xF763)); - nameToEnc.put("Csmall", new Integer(99)); - encToName[99] = "Csmall"; - - unicodeToName.put(new Character((char) 0xF7A8), "Dieresissmall"); - nameToUnicode.put("Dieresissmall", new Character((char) 0xF7A8)); - nameToEnc.put("Dieresissmall", new Integer(172)); - encToName[172] = "Dieresissmall"; - - unicodeToName.put(new Character((char) 0xF6F7), "Dotaccentsmall"); - nameToUnicode.put("Dotaccentsmall", new Character((char) 0xF6F7)); - nameToEnc.put("Dotaccentsmall", new Integer(250)); - encToName[250] = "Dotaccentsmall"; - - unicodeToName.put(new Character((char) 0xF764), "Dsmall"); - nameToUnicode.put("Dsmall", new Character((char) 0xF764)); - nameToEnc.put("Dsmall", new Integer(100)); - encToName[100] = "Dsmall"; - - unicodeToName.put(new Character((char) 0xF7E9), "Eacutesmall"); - nameToUnicode.put("Eacutesmall", new Character((char) 0xF7E9)); - nameToEnc.put("Eacutesmall", new Integer(142)); - encToName[142] = "Eacutesmall"; - - unicodeToName.put(new Character((char) 0xF7EA), "Ecircumflexsmall"); - nameToUnicode.put("Ecircumflexsmall", new Character((char) 0xF7EA)); - nameToEnc.put("Ecircumflexsmall", new Integer(144)); - encToName[144] = "Ecircumflexsmall"; - - unicodeToName.put(new Character((char) 0xF7EB), "Edieresissmall"); - nameToUnicode.put("Edieresissmall", new Character((char) 0xF7EB)); - nameToEnc.put("Edieresissmall", new Integer(145)); - encToName[145] = "Edieresissmall"; - - unicodeToName.put(new Character((char) 0xF7E8), "Egravesmall"); - nameToUnicode.put("Egravesmall", new Character((char) 0xF7E8)); - nameToEnc.put("Egravesmall", new Integer(143)); - encToName[143] = "Egravesmall"; - - unicodeToName.put(new Character((char) 0xF765), "Esmall"); - nameToUnicode.put("Esmall", new Character((char) 0xF765)); - nameToEnc.put("Esmall", new Integer(101)); - encToName[101] = "Esmall"; - - unicodeToName.put(new Character((char) 0xF7F0), "Ethsmall"); - nameToUnicode.put("Ethsmall", new Character((char) 0xF7F0)); - nameToEnc.put("Ethsmall", new Integer(68)); - encToName[68] = "Ethsmall"; - - unicodeToName.put(new Character((char) 0xF766), "Fsmall"); - nameToUnicode.put("Fsmall", new Character((char) 0xF766)); - nameToEnc.put("Fsmall", new Integer(102)); - encToName[102] = "Fsmall"; - - unicodeToName.put(new Character((char) 0xF760), "Gravesmall"); - nameToUnicode.put("Gravesmall", new Character((char) 0xF760)); - nameToEnc.put("Gravesmall", new Integer(96)); - encToName[96] = "Gravesmall"; - - unicodeToName.put(new Character((char) 0xF767), "Gsmall"); - nameToUnicode.put("Gsmall", new Character((char) 0xF767)); - nameToEnc.put("Gsmall", new Integer(103)); - encToName[103] = "Gsmall"; - - unicodeToName.put(new Character((char) 0xF768), "Hsmall"); - nameToUnicode.put("Hsmall", new Character((char) 0xF768)); - nameToEnc.put("Hsmall", new Integer(104)); - encToName[104] = "Hsmall"; - - unicodeToName.put(new Character((char) 0xF6F8), "Hungarumlautsmall"); - nameToUnicode.put("Hungarumlautsmall", new Character((char) 0xF6F8)); - nameToEnc.put("Hungarumlautsmall", new Integer(34)); - encToName[34] = "Hungarumlautsmall"; - - unicodeToName.put(new Character((char) 0xF7ED), "Iacutesmall"); - nameToUnicode.put("Iacutesmall", new Character((char) 0xF7ED)); - nameToEnc.put("Iacutesmall", new Integer(146)); - encToName[146] = "Iacutesmall"; - - unicodeToName.put(new Character((char) 0xF7EE), "Icircumflexsmall"); - nameToUnicode.put("Icircumflexsmall", new Character((char) 0xF7EE)); - nameToEnc.put("Icircumflexsmall", new Integer(148)); - encToName[148] = "Icircumflexsmall"; - - unicodeToName.put(new Character((char) 0xF7EF), "Idieresissmall"); - nameToUnicode.put("Idieresissmall", new Character((char) 0xF7EF)); - nameToEnc.put("Idieresissmall", new Integer(149)); - encToName[149] = "Idieresissmall"; - - unicodeToName.put(new Character((char) 0xF7EC), "Igravesmall"); - nameToUnicode.put("Igravesmall", new Character((char) 0xF7EC)); - nameToEnc.put("Igravesmall", new Integer(147)); - encToName[147] = "Igravesmall"; - - unicodeToName.put(new Character((char) 0xF769), "Ismall"); - nameToUnicode.put("Ismall", new Character((char) 0xF769)); - nameToEnc.put("Ismall", new Integer(105)); - encToName[105] = "Ismall"; - - unicodeToName.put(new Character((char) 0xF76A), "Jsmall"); - nameToUnicode.put("Jsmall", new Character((char) 0xF76A)); - nameToEnc.put("Jsmall", new Integer(106)); - encToName[106] = "Jsmall"; - - unicodeToName.put(new Character((char) 0xF76B), "Ksmall"); - nameToUnicode.put("Ksmall", new Character((char) 0xF76B)); - nameToEnc.put("Ksmall", new Integer(107)); - encToName[107] = "Ksmall"; - - unicodeToName.put(new Character((char) 0xF6F9), "Lslashsmall"); - nameToUnicode.put("Lslashsmall", new Character((char) 0xF6F9)); - nameToEnc.put("Lslashsmall", new Integer(194)); - encToName[194] = "Lslashsmall"; - - unicodeToName.put(new Character((char) 0xF76C), "Lsmall"); - nameToUnicode.put("Lsmall", new Character((char) 0xF76C)); - nameToEnc.put("Lsmall", new Integer(108)); - encToName[108] = "Lsmall"; - - unicodeToName.put(new Character((char) 0xF7AF), "Macronsmall"); - nameToUnicode.put("Macronsmall", new Character((char) 0xF7AF)); - nameToEnc.put("Macronsmall", new Integer(244)); - encToName[244] = "Macronsmall"; - - unicodeToName.put(new Character((char) 0xF76D), "Msmall"); - nameToUnicode.put("Msmall", new Character((char) 0xF76D)); - nameToEnc.put("Msmall", new Integer(109)); - encToName[109] = "Msmall"; - - unicodeToName.put(new Character((char) 0xF76E), "Nsmall"); - nameToUnicode.put("Nsmall", new Character((char) 0xF76E)); - nameToEnc.put("Nsmall", new Integer(110)); - encToName[110] = "Nsmall"; - - unicodeToName.put(new Character((char) 0xF7F1), "Ntildesmall"); - nameToUnicode.put("Ntildesmall", new Character((char) 0xF7F1)); - nameToEnc.put("Ntildesmall", new Integer(150)); - encToName[150] = "Ntildesmall"; - - unicodeToName.put(new Character((char) 0xF6FA), "OEsmall"); - nameToUnicode.put("OEsmall", new Character((char) 0xF6FA)); - nameToEnc.put("OEsmall", new Integer(207)); - encToName[207] = "OEsmall"; - - unicodeToName.put(new Character((char) 0xF7F3), "Oacutesmall"); - nameToUnicode.put("Oacutesmall", new Character((char) 0xF7F3)); - nameToEnc.put("Oacutesmall", new Integer(151)); - encToName[151] = "Oacutesmall"; - - unicodeToName.put(new Character((char) 0xF7F4), "Ocircumflexsmall"); - nameToUnicode.put("Ocircumflexsmall", new Character((char) 0xF7F4)); - nameToEnc.put("Ocircumflexsmall", new Integer(153)); - encToName[153] = "Ocircumflexsmall"; - - unicodeToName.put(new Character((char) 0xF7F6), "Odieresissmall"); - nameToUnicode.put("Odieresissmall", new Character((char) 0xF7F6)); - nameToEnc.put("Odieresissmall", new Integer(154)); - encToName[154] = "Odieresissmall"; - - unicodeToName.put(new Character((char) 0xF6FB), "Ogoneksmall"); - nameToUnicode.put("Ogoneksmall", new Character((char) 0xF6FB)); - nameToEnc.put("Ogoneksmall", new Integer(242)); - encToName[242] = "Ogoneksmall"; - - unicodeToName.put(new Character((char) 0xF7F2), "Ogravesmall"); - nameToUnicode.put("Ogravesmall", new Character((char) 0xF7F2)); - nameToEnc.put("Ogravesmall", new Integer(152)); - encToName[152] = "Ogravesmall"; - - unicodeToName.put(new Character((char) 0xF7F8), "Oslashsmall"); - nameToUnicode.put("Oslashsmall", new Character((char) 0xF7F8)); - nameToEnc.put("Oslashsmall", new Integer(191)); - encToName[191] = "Oslashsmall"; - - unicodeToName.put(new Character((char) 0xF76F), "Osmall"); - nameToUnicode.put("Osmall", new Character((char) 0xF76F)); - nameToEnc.put("Osmall", new Integer(111)); - encToName[111] = "Osmall"; - - unicodeToName.put(new Character((char) 0xF7F5), "Otildesmall"); - nameToUnicode.put("Otildesmall", new Character((char) 0xF7F5)); - nameToEnc.put("Otildesmall", new Integer(155)); - encToName[155] = "Otildesmall"; - - unicodeToName.put(new Character((char) 0xF770), "Psmall"); - nameToUnicode.put("Psmall", new Character((char) 0xF770)); - nameToEnc.put("Psmall", new Integer(112)); - encToName[112] = "Psmall"; - - unicodeToName.put(new Character((char) 0xF771), "Qsmall"); - nameToUnicode.put("Qsmall", new Character((char) 0xF771)); - nameToEnc.put("Qsmall", new Integer(113)); - encToName[113] = "Qsmall"; - - unicodeToName.put(new Character((char) 0xF6FC), "Ringsmall"); - nameToUnicode.put("Ringsmall", new Character((char) 0xF6FC)); - nameToEnc.put("Ringsmall", new Integer(251)); - encToName[251] = "Ringsmall"; - - unicodeToName.put(new Character((char) 0xF772), "Rsmall"); - nameToUnicode.put("Rsmall", new Character((char) 0xF772)); - nameToEnc.put("Rsmall", new Integer(114)); - encToName[114] = "Rsmall"; - - unicodeToName.put(new Character((char) 0xF6FD), "Scaronsmall"); - nameToUnicode.put("Scaronsmall", new Character((char) 0xF6FD)); - nameToEnc.put("Scaronsmall", new Integer(167)); - encToName[167] = "Scaronsmall"; - - unicodeToName.put(new Character((char) 0xF773), "Ssmall"); - nameToUnicode.put("Ssmall", new Character((char) 0xF773)); - nameToEnc.put("Ssmall", new Integer(115)); - encToName[115] = "Ssmall"; - - unicodeToName.put(new Character((char) 0xF7FE), "Thornsmall"); - nameToUnicode.put("Thornsmall", new Character((char) 0xF7FE)); - nameToEnc.put("Thornsmall", new Integer(185)); - encToName[185] = "Thornsmall"; - - unicodeToName.put(new Character((char) 0xF6FE), "Tildesmall"); - nameToUnicode.put("Tildesmall", new Character((char) 0xF6FE)); - nameToEnc.put("Tildesmall", new Integer(126)); - encToName[126] = "Tildesmall"; - - unicodeToName.put(new Character((char) 0xF774), "Tsmall"); - nameToUnicode.put("Tsmall", new Character((char) 0xF774)); - nameToEnc.put("Tsmall", new Integer(116)); - encToName[116] = "Tsmall"; - - unicodeToName.put(new Character((char) 0xF7FA), "Uacutesmall"); - nameToUnicode.put("Uacutesmall", new Character((char) 0xF7FA)); - nameToEnc.put("Uacutesmall", new Integer(156)); - encToName[156] = "Uacutesmall"; - - unicodeToName.put(new Character((char) 0xF7FB), "Ucircumflexsmall"); - nameToUnicode.put("Ucircumflexsmall", new Character((char) 0xF7FB)); - nameToEnc.put("Ucircumflexsmall", new Integer(158)); - encToName[158] = "Ucircumflexsmall"; - - unicodeToName.put(new Character((char) 0xF7FC), "Udieresissmall"); - nameToUnicode.put("Udieresissmall", new Character((char) 0xF7FC)); - nameToEnc.put("Udieresissmall", new Integer(159)); - encToName[159] = "Udieresissmall"; - - unicodeToName.put(new Character((char) 0xF7F9), "Ugravesmall"); - nameToUnicode.put("Ugravesmall", new Character((char) 0xF7F9)); - nameToEnc.put("Ugravesmall", new Integer(157)); - encToName[157] = "Ugravesmall"; - - unicodeToName.put(new Character((char) 0xF775), "Usmall"); - nameToUnicode.put("Usmall", new Character((char) 0xF775)); - nameToEnc.put("Usmall", new Integer(117)); - encToName[117] = "Usmall"; - - unicodeToName.put(new Character((char) 0xF776), "Vsmall"); - nameToUnicode.put("Vsmall", new Character((char) 0xF776)); - nameToEnc.put("Vsmall", new Integer(118)); - encToName[118] = "Vsmall"; - - unicodeToName.put(new Character((char) 0xF777), "Wsmall"); - nameToUnicode.put("Wsmall", new Character((char) 0xF777)); - nameToEnc.put("Wsmall", new Integer(119)); - encToName[119] = "Wsmall"; - - unicodeToName.put(new Character((char) 0xF778), "Xsmall"); - nameToUnicode.put("Xsmall", new Character((char) 0xF778)); - nameToEnc.put("Xsmall", new Integer(120)); - encToName[120] = "Xsmall"; - - unicodeToName.put(new Character((char) 0xF7FD), "Yacutesmall"); - nameToUnicode.put("Yacutesmall", new Character((char) 0xF7FD)); - nameToEnc.put("Yacutesmall", new Integer(180)); - encToName[180] = "Yacutesmall"; - - unicodeToName.put(new Character((char) 0xF7FF), "Ydieresissmall"); - nameToUnicode.put("Ydieresissmall", new Character((char) 0xF7FF)); - nameToEnc.put("Ydieresissmall", new Integer(216)); - encToName[216] = "Ydieresissmall"; - - unicodeToName.put(new Character((char) 0xF779), "Ysmall"); - nameToUnicode.put("Ysmall", new Character((char) 0xF779)); - nameToEnc.put("Ysmall", new Integer(121)); - encToName[121] = "Ysmall"; - - unicodeToName.put(new Character((char) 0xF6FF), "Zcaronsmall"); - nameToUnicode.put("Zcaronsmall", new Character((char) 0xF6FF)); - nameToEnc.put("Zcaronsmall", new Integer(189)); - encToName[189] = "Zcaronsmall"; - - unicodeToName.put(new Character((char) 0xF77A), "Zsmall"); - nameToUnicode.put("Zsmall", new Character((char) 0xF77A)); - nameToEnc.put("Zsmall", new Integer(122)); - encToName[122] = "Zsmall"; - - unicodeToName.put(new Character((char) 0xfe60), "ampersandsmall"); - nameToUnicode.put("ampersandsmall", new Character((char) 0xfe60)); - nameToEnc.put("ampersandsmall", new Integer(38)); - encToName[38] = "ampersandsmall"; - - unicodeToName.put(new Character((char) 0xF6E9), "asuperior"); - nameToUnicode.put("asuperior", new Character((char) 0xF6E9)); - nameToEnc.put("asuperior", new Integer(129)); - encToName[129] = "asuperior"; - - unicodeToName.put(new Character((char) 0xF6EA), "bsuperior"); - nameToUnicode.put("bsuperior", new Character((char) 0xF6EA)); - nameToEnc.put("bsuperior", new Integer(245)); - encToName[245] = "bsuperior"; - - unicodeToName.put(new Character((char) 0xF6DF), "centinferior"); - nameToUnicode.put("centinferior", new Character((char) 0xF6DF)); - nameToEnc.put("centinferior", new Integer(169)); - encToName[169] = "centinferior"; - - unicodeToName.put(new Character((char) 0xF7A2), "centoldstyle"); - nameToUnicode.put("centoldstyle", new Character((char) 0xF7A2)); - nameToEnc.put("centoldstyle", new Integer(35)); - encToName[35] = "centoldstyle"; - - unicodeToName.put(new Character((char) 0xF6E0), "centsuperior"); - nameToUnicode.put("centsuperior", new Character((char) 0xF6E0)); - nameToEnc.put("centsuperior", new Integer(130)); - encToName[130] = "centsuperior"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x20a1), "colonmonetary"); - nameToUnicode.put("colonmonetary", new Character((char) 0x20a1)); - nameToEnc.put("colonmonetary", new Integer(123)); - encToName[123] = "colonmonetary"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0xF6E1), "commainferior"); - nameToUnicode.put("commainferior", new Character((char) 0xF6E1)); - nameToEnc.put("commainferior", new Integer(178)); - encToName[178] = "commainferior"; - - unicodeToName.put(new Character((char) 0xF6E2), "commasuperior"); - nameToUnicode.put("commasuperior", new Character((char) 0xF6E2)); - nameToEnc.put("commasuperior", new Integer(248)); - encToName[248] = "commasuperior"; - - unicodeToName.put(new Character((char) 0xF6E3), "dollarinferior"); - nameToUnicode.put("dollarinferior", new Character((char) 0xF6E3)); - nameToEnc.put("dollarinferior", new Integer(182)); - encToName[182] = "dollarinferior"; - - unicodeToName.put(new Character((char) 0xF724), "dollaroldstyle"); - nameToUnicode.put("dollaroldstyle", new Character((char) 0xF724)); - nameToEnc.put("dollaroldstyle", new Integer(36)); - encToName[36] = "dollaroldstyle"; - - unicodeToName.put(new Character((char) 0xF6E4), "dollarsuperior"); - nameToUnicode.put("dollarsuperior", new Character((char) 0xF6E4)); - nameToEnc.put("dollarsuperior", new Integer(37)); - encToName[37] = "dollarsuperior"; - - unicodeToName.put(new Character((char) 0xF6EB), "dsuperior"); - nameToUnicode.put("dsuperior", new Character((char) 0xF6EB)); - nameToEnc.put("dsuperior", new Integer(235)); - encToName[235] = "dsuperior"; - - unicodeToName.put(new Character((char) 0x2088), "eightinferior"); - nameToUnicode.put("eightinferior", new Character((char) 0x2088)); - nameToEnc.put("eightinferior", new Integer(165)); - encToName[165] = "eightinferior"; - - unicodeToName.put(new Character((char) 0xF738), "eightoldstyle"); - nameToUnicode.put("eightoldstyle", new Character((char) 0xF738)); - nameToEnc.put("eightoldstyle", new Integer(56)); - encToName[56] = "eightoldstyle"; - - unicodeToName.put(new Character((char) 0x2078), "eightsuperior"); - nameToUnicode.put("eightsuperior", new Character((char) 0x2078)); - nameToEnc.put("eightsuperior", new Integer(161)); - encToName[161] = "eightsuperior"; - - unicodeToName.put(new Character((char) 0xF6EC), "esuperior"); - nameToUnicode.put("esuperior", new Character((char) 0xF6EC)); - nameToEnc.put("esuperior", new Integer(228)); - encToName[228] = "esuperior"; - - unicodeToName.put(new Character((char) 0xF7A1), "exclamdownsmall"); - nameToUnicode.put("exclamdownsmall", new Character((char) 0xF7A1)); - nameToEnc.put("exclamdownsmall", new Integer(214)); - encToName[214] = "exclamdownsmall"; - - unicodeToName.put(new Character((char) 0xfe57), "exclamsmall"); - nameToUnicode.put("exclamsmall", new Character((char) 0xfe57)); - nameToEnc.put("exclamsmall", new Integer(33)); - encToName[33] = "exclamsmall"; - - unicodeToName.put(new Character((char) 0xfb00), "ff"); - nameToUnicode.put("ff", new Character((char) 0xfb00)); - nameToEnc.put("ff", new Integer(86)); - encToName[86] = "ff"; - - unicodeToName.put(new Character((char) 0xfb03), "ffi"); - nameToUnicode.put("ffi", new Character((char) 0xfb03)); - nameToEnc.put("ffi", new Integer(89)); - encToName[89] = "ffi"; - - unicodeToName.put(new Character((char) 0xfb04), "ffl"); - nameToUnicode.put("ffl", new Character((char) 0xfb04)); - nameToEnc.put("ffl", new Integer(90)); - encToName[90] = "ffl"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - nameToEnc.put("fi", new Integer(87)); - encToName[87] = "fi"; - - unicodeToName.put(new Character((char) 0x2012), "figuredash"); - nameToUnicode.put("figuredash", new Character((char) 0x2012)); - nameToEnc.put("figuredash", new Integer(208)); - encToName[208] = "figuredash"; - - unicodeToName.put(new Character((char) 0x215d), "fiveeighths"); - nameToUnicode.put("fiveeighths", new Character((char) 0x215d)); - nameToEnc.put("fiveeighths", new Integer(76)); - encToName[76] = "fiveeighths"; - - unicodeToName.put(new Character((char) 0x2085), "fiveinferior"); - nameToUnicode.put("fiveinferior", new Character((char) 0x2085)); - nameToEnc.put("fiveinferior", new Integer(176)); - encToName[176] = "fiveinferior"; - - unicodeToName.put(new Character((char) 0xF735), "fiveoldstyle"); - nameToUnicode.put("fiveoldstyle", new Character((char) 0xF735)); - nameToEnc.put("fiveoldstyle", new Integer(53)); - encToName[53] = "fiveoldstyle"; - - unicodeToName.put(new Character((char) 0x2075), "fivesuperior"); - nameToUnicode.put("fivesuperior", new Character((char) 0x2075)); - nameToEnc.put("fivesuperior", new Integer(222)); - encToName[222] = "fivesuperior"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - nameToEnc.put("fl", new Integer(88)); - encToName[88] = "fl"; - - unicodeToName.put(new Character((char) 0x2084), "fourinferior"); - nameToUnicode.put("fourinferior", new Character((char) 0x2084)); - nameToEnc.put("fourinferior", new Integer(162)); - encToName[162] = "fourinferior"; - - unicodeToName.put(new Character((char) 0xF734), "fouroldstyle"); - nameToUnicode.put("fouroldstyle", new Character((char) 0xF734)); - nameToEnc.put("fouroldstyle", new Integer(52)); - encToName[52] = "fouroldstyle"; - - unicodeToName.put(new Character((char) 0x2074), "foursuperior"); - nameToUnicode.put("foursuperior", new Character((char) 0x2074)); - nameToEnc.put("foursuperior", new Integer(221)); - encToName[221] = "foursuperior"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - nameToEnc.put("fraction", new Integer(47)); - encToName[47] = "fraction"; - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(45)); - encToName[45] = "hyphen"; - - unicodeToName.put(new Character((char) 0x208b), "hypheninferior"); - nameToUnicode.put("hypheninferior", new Character((char) 0x208b)); - nameToEnc.put("hypheninferior", new Integer(95)); - encToName[95] = "hypheninferior"; - - unicodeToName.put(new Character((char) 0x207b), "hyphensuperior"); - nameToUnicode.put("hyphensuperior", new Character((char) 0x207b)); - nameToEnc.put("hyphensuperior", new Integer(209)); - encToName[209] = "hyphensuperior"; - - unicodeToName.put(new Character((char) 0xF6ED), "isuperior"); - nameToUnicode.put("isuperior", new Character((char) 0xF6ED)); - nameToEnc.put("isuperior", new Integer(233)); - encToName[233] = "isuperior"; - - unicodeToName.put(new Character((char) 0xF6EE), "lsuperior"); - nameToUnicode.put("lsuperior", new Character((char) 0xF6EE)); - nameToEnc.put("lsuperior", new Integer(241)); - encToName[241] = "lsuperior"; - - unicodeToName.put(new Character((char) 0xF6EF), "msuperior"); - nameToUnicode.put("msuperior", new Character((char) 0xF6EF)); - nameToEnc.put("msuperior", new Integer(247)); - encToName[247] = "msuperior"; - - unicodeToName.put(new Character((char) 0x2089), "nineinferior"); - nameToUnicode.put("nineinferior", new Character((char) 0x2089)); - nameToEnc.put("nineinferior", new Integer(187)); - encToName[187] = "nineinferior"; - - unicodeToName.put(new Character((char) 0xF739), "nineoldstyle"); - nameToUnicode.put("nineoldstyle", new Character((char) 0xF739)); - nameToEnc.put("nineoldstyle", new Integer(57)); - encToName[57] = "nineoldstyle"; - - unicodeToName.put(new Character((char) 0x2079), "ninesuperior"); - nameToUnicode.put("ninesuperior", new Character((char) 0x2079)); - nameToEnc.put("ninesuperior", new Integer(225)); - encToName[225] = "ninesuperior"; - - unicodeToName.put(new Character((char) 0x207f), "nsuperior"); - nameToUnicode.put("nsuperior", new Character((char) 0x207f)); - nameToEnc.put("nsuperior", new Integer(246)); - encToName[246] = "nsuperior"; - - unicodeToName.put(new Character((char) 0x2024), "onedotenleader"); - nameToUnicode.put("onedotenleader", new Character((char) 0x2024)); - nameToEnc.put("onedotenleader", new Integer(43)); - encToName[43] = "onedotenleader"; - - unicodeToName.put(new Character((char) 0x215b), "oneeight"); - nameToUnicode.put("oneeight", new Character((char) 0x215b)); - nameToEnc.put("oneeight", new Integer(74)); - encToName[74] = "oneeight"; - - unicodeToName.put(new Character((char) 0xF6DC), "onefitted"); - nameToUnicode.put("onefitted", new Character((char) 0xF6DC)); - nameToEnc.put("onefitted", new Integer(124)); - encToName[124] = "onefitted"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - nameToEnc.put("onehalf", new Integer(72)); - encToName[72] = "onehalf"; - - unicodeToName.put(new Character((char) 0x2081), "oneinferior"); - nameToUnicode.put("oneinferior", new Character((char) 0x2081)); - nameToEnc.put("oneinferior", new Integer(193)); - encToName[193] = "oneinferior"; - - unicodeToName.put(new Character((char) 0xF731), "oneoldstyle"); - nameToUnicode.put("oneoldstyle", new Character((char) 0xF731)); - nameToEnc.put("oneoldstyle", new Integer(49)); - encToName[49] = "oneoldstyle"; - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - nameToEnc.put("onequarter", new Integer(71)); - encToName[71] = "onequarter"; - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - nameToEnc.put("onesuperior", new Integer(218)); - encToName[218] = "onesuperior"; - - unicodeToName.put(new Character((char) 0x2153), "onethird"); - nameToUnicode.put("onethird", new Character((char) 0x2153)); - nameToEnc.put("onethird", new Integer(78)); - encToName[78] = "onethird"; - - unicodeToName.put(new Character((char) 0xF6F0), "osuperior"); - nameToUnicode.put("osuperior", new Character((char) 0xF6F0)); - nameToEnc.put("osuperior", new Integer(175)); - encToName[175] = "osuperior"; - - unicodeToName.put(new Character((char) 0x208d), "parenleftinferior"); - nameToUnicode.put("parenleftinferior", new Character((char) 0x208d)); - nameToEnc.put("parenleftinferior", new Integer(91)); - encToName[91] = "parenleftinferior"; - - unicodeToName.put(new Character((char) 0x207d), "parenleftsuperior"); - nameToUnicode.put("parenleftsuperior", new Character((char) 0x207d)); - nameToEnc.put("parenleftsuperior", new Integer(40)); - encToName[40] = "parenleftsuperior"; - - unicodeToName.put(new Character((char) 0x208e), "parenrightinferior"); - nameToUnicode.put("parenrightinferior", new Character((char) 0x208e)); - nameToEnc.put("parenrightinferior", new Integer(93)); - encToName[93] = "parenrightinferior"; - - unicodeToName.put(new Character((char) 0x207e), "parenrightsuperior"); - nameToUnicode.put("parenrightsuperior", new Character((char) 0x207e)); - nameToEnc.put("parenrightsuperior", new Integer(41)); - encToName[41] = "parenrightsuperior"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0xF6E7), "periodinferior"); - nameToUnicode.put("periodinferior", new Character((char) 0xF6E7)); - nameToEnc.put("periodinferior", new Integer(179)); - encToName[179] = "periodinferior"; - - unicodeToName.put(new Character((char) 0xF6E8), "periodsuperior"); - nameToUnicode.put("periodsuperior", new Character((char) 0xF6E8)); - nameToEnc.put("periodsuperior", new Integer(249)); - encToName[249] = "periodsuperior"; - - unicodeToName.put(new Character((char) 0xF7BF), "questiondownsmall"); - nameToUnicode.put("questiondownsmall", new Character((char) 0xF7BF)); - nameToEnc.put("questiondownsmall", new Integer(192)); - encToName[192] = "questiondownsmall"; - - unicodeToName.put(new Character((char) 0xfe56), "questionsmall"); - nameToUnicode.put("questionsmall", new Character((char) 0xfe56)); - nameToEnc.put("questionsmall", new Integer(63)); - encToName[63] = "questionsmall"; - - unicodeToName.put(new Character((char) 0xF6F1), "rsuperior"); - nameToUnicode.put("rsuperior", new Character((char) 0xF6F1)); - nameToEnc.put("rsuperior", new Integer(229)); - encToName[229] = "rsuperior"; - - unicodeToName.put(new Character((char) 0xF6DD), "rupiah"); - nameToUnicode.put("rupiah", new Character((char) 0xF6DD)); - nameToEnc.put("rupiah", new Integer(125)); - encToName[125] = "rupiah"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x215e), "seveneighths"); - nameToUnicode.put("seveneighths", new Character((char) 0x215e)); - nameToEnc.put("seveneighths", new Integer(77)); - encToName[77] = "seveneighths"; - - unicodeToName.put(new Character((char) 0x2087), "seveninferior"); - nameToUnicode.put("seveninferior", new Character((char) 0x2087)); - nameToEnc.put("seveninferior", new Integer(166)); - encToName[166] = "seveninferior"; - - unicodeToName.put(new Character((char) 0xF737), "sevenoldstyle"); - nameToUnicode.put("sevenoldstyle", new Character((char) 0xF737)); - nameToEnc.put("sevenoldstyle", new Integer(55)); - encToName[55] = "sevenoldstyle"; - - unicodeToName.put(new Character((char) 0x2077), "sevensuperior"); - nameToUnicode.put("sevensuperior", new Character((char) 0x2077)); - nameToEnc.put("sevensuperior", new Integer(224)); - encToName[224] = "sevensuperior"; - - unicodeToName.put(new Character((char) 0x2086), "sixinferior"); - nameToUnicode.put("sixinferior", new Character((char) 0x2086)); - nameToEnc.put("sixinferior", new Integer(164)); - encToName[164] = "sixinferior"; - - unicodeToName.put(new Character((char) 0xF736), "sixoldstyle"); - nameToUnicode.put("sixoldstyle", new Character((char) 0xF736)); - nameToEnc.put("sixoldstyle", new Integer(54)); - encToName[54] = "sixoldstyle"; - - unicodeToName.put(new Character((char) 0x2076), "sixsuperior"); - nameToUnicode.put("sixsuperior", new Character((char) 0x2076)); - nameToEnc.put("sixsuperior", new Integer(223)); - encToName[223] = "sixsuperior"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0xF6F2), "ssuperior"); - nameToUnicode.put("ssuperior", new Character((char) 0xF6F2)); - nameToEnc.put("ssuperior", new Integer(234)); - encToName[234] = "ssuperior"; - - unicodeToName.put(new Character((char) 0x215c), "threeeighths"); - nameToUnicode.put("threeeighths", new Character((char) 0x215c)); - nameToEnc.put("threeeighths", new Integer(75)); - encToName[75] = "threeeighths"; - - unicodeToName.put(new Character((char) 0x2083), "threeinferior"); - nameToUnicode.put("threeinferior", new Character((char) 0x2083)); - nameToEnc.put("threeinferior", new Integer(163)); - encToName[163] = "threeinferior"; - - unicodeToName.put(new Character((char) 0xF733), "threeoldstyle"); - nameToUnicode.put("threeoldstyle", new Character((char) 0xF733)); - nameToEnc.put("threeoldstyle", new Integer(51)); - encToName[51] = "threeoldstyle"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - nameToEnc.put("threequarters", new Integer(73)); - encToName[73] = "threequarters"; - - unicodeToName.put(new Character((char) 0xfe58), "threequartersemdash"); - nameToUnicode.put("threequartersemdash", new Character((char) 0xfe58)); - nameToEnc.put("threequartersemdash", new Integer(61)); - encToName[61] = "threequartersemdash"; - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - nameToEnc.put("threesuperior", new Integer(220)); - encToName[220] = "threesuperior"; - - unicodeToName.put(new Character((char) 0xF6F3), "tsuperior"); - nameToUnicode.put("tsuperior", new Character((char) 0xF6F3)); - nameToEnc.put("tsuperior", new Integer(230)); - encToName[230] = "tsuperior"; - - unicodeToName.put(new Character((char) 0x2025), "twodotenleader"); - nameToUnicode.put("twodotenleader", new Character((char) 0x2025)); - nameToEnc.put("twodotenleader", new Integer(42)); - encToName[42] = "twodotenleader"; - - unicodeToName.put(new Character((char) 0x2082), "twoinferior"); - nameToUnicode.put("twoinferior", new Character((char) 0x2082)); - nameToEnc.put("twoinferior", new Integer(170)); - encToName[170] = "twoinferior"; - - unicodeToName.put(new Character((char) 0xF732), "twooldstyle"); - nameToUnicode.put("twooldstyle", new Character((char) 0xF732)); - nameToEnc.put("twooldstyle", new Integer(50)); - encToName[50] = "twooldstyle"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - nameToEnc.put("twosuperior", new Integer(219)); - encToName[219] = "twosuperior"; - - unicodeToName.put(new Character((char) 0x2154), "twothirds"); - nameToUnicode.put("twothirds", new Character((char) 0x2154)); - nameToEnc.put("twothirds", new Integer(79)); - encToName[79] = "twothirds"; - - unicodeToName.put(new Character((char) 0x2080), "zeroinferior"); - nameToUnicode.put("zeroinferior", new Character((char) 0x2080)); - nameToEnc.put("zeroinferior", new Integer(188)); - encToName[188] = "zeroinferior"; - - unicodeToName.put(new Character((char) 0xF730), "zerooldstyle"); - nameToUnicode.put("zerooldstyle", new Character((char) 0xF730)); - nameToEnc.put("zerooldstyle", new Integer(48)); - encToName[48] = "zerooldstyle"; - - unicodeToName.put(new Character((char) 0x2070), "zerosuperior"); - nameToUnicode.put("zerosuperior", new Character((char) 0x2070)); - nameToEnc.put("zerosuperior", new Integer(226)); - encToName[226] = "zerosuperior"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Expert"); //$NON-NLS-1$ - } - - public String getEncoding() { - return (""); //$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated Expert Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class Expert extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public Expert() { + unicodeToName.put(new Character((char) 0xF7E6), "AEsmall"); + nameToUnicode.put("AEsmall", new Character((char) 0xF7E6)); + nameToEnc.put("AEsmall", new Integer(190)); + encToName[190] = "AEsmall"; + + unicodeToName.put(new Character((char) 0xF7E1), "Aacutesmall"); + nameToUnicode.put("Aacutesmall", new Character((char) 0xF7E1)); + nameToEnc.put("Aacutesmall", new Integer(135)); + encToName[135] = "Aacutesmall"; + + unicodeToName.put(new Character((char) 0xF7E2), "Acircumflexsmall"); + nameToUnicode.put("Acircumflexsmall", new Character((char) 0xF7E2)); + nameToEnc.put("Acircumflexsmall", new Integer(137)); + encToName[137] = "Acircumflexsmall"; + + unicodeToName.put(new Character((char) 0xF7B4), "Acutesmall"); + nameToUnicode.put("Acutesmall", new Character((char) 0xF7B4)); + nameToEnc.put("Acutesmall", new Integer(39)); + encToName[39] = "Acutesmall"; + + unicodeToName.put(new Character((char) 0xF7E4), "Adieresissmall"); + nameToUnicode.put("Adieresissmall", new Character((char) 0xF7E4)); + nameToEnc.put("Adieresissmall", new Integer(138)); + encToName[138] = "Adieresissmall"; + + unicodeToName.put(new Character((char) 0xF7E0), "Agravesmall"); + nameToUnicode.put("Agravesmall", new Character((char) 0xF7E0)); + nameToEnc.put("Agravesmall", new Integer(136)); + encToName[136] = "Agravesmall"; + + unicodeToName.put(new Character((char) 0xF7E5), "Aringsmall"); + nameToUnicode.put("Aringsmall", new Character((char) 0xF7E5)); + nameToEnc.put("Aringsmall", new Integer(140)); + encToName[140] = "Aringsmall"; + + unicodeToName.put(new Character((char) 0xF761), "Asmall"); + nameToUnicode.put("Asmall", new Character((char) 0xF761)); + nameToEnc.put("Asmall", new Integer(97)); + encToName[97] = "Asmall"; + + unicodeToName.put(new Character((char) 0xF7E3), "Atildesmall"); + nameToUnicode.put("Atildesmall", new Character((char) 0xF7E3)); + nameToEnc.put("Atildesmall", new Integer(139)); + encToName[139] = "Atildesmall"; + + unicodeToName.put(new Character((char) 0xF6F4), "Brevesmall"); + nameToUnicode.put("Brevesmall", new Character((char) 0xF6F4)); + nameToEnc.put("Brevesmall", new Integer(243)); + encToName[243] = "Brevesmall"; + + unicodeToName.put(new Character((char) 0xF762), "Bsmall"); + nameToUnicode.put("Bsmall", new Character((char) 0xF762)); + nameToEnc.put("Bsmall", new Integer(98)); + encToName[98] = "Bsmall"; + + unicodeToName.put(new Character((char) 0xF6F5), "Caronsmall"); + nameToUnicode.put("Caronsmall", new Character((char) 0xF6F5)); + nameToEnc.put("Caronsmall", new Integer(174)); + encToName[174] = "Caronsmall"; + + unicodeToName.put(new Character((char) 0xF7E7), "Ccedillasmall"); + nameToUnicode.put("Ccedillasmall", new Character((char) 0xF7E7)); + nameToEnc.put("Ccedillasmall", new Integer(141)); + encToName[141] = "Ccedillasmall"; + + unicodeToName.put(new Character((char) 0xF7B8), "Cedillasmall"); + nameToUnicode.put("Cedillasmall", new Character((char) 0xF7B8)); + nameToEnc.put("Cedillasmall", new Integer(201)); + encToName[201] = "Cedillasmall"; + + unicodeToName.put(new Character((char) 0xF6F6), "Circumflexsmall"); + nameToUnicode.put("Circumflexsmall", new Character((char) 0xF6F6)); + nameToEnc.put("Circumflexsmall", new Integer(94)); + encToName[94] = "Circumflexsmall"; + + unicodeToName.put(new Character((char) 0xF763), "Csmall"); + nameToUnicode.put("Csmall", new Character((char) 0xF763)); + nameToEnc.put("Csmall", new Integer(99)); + encToName[99] = "Csmall"; + + unicodeToName.put(new Character((char) 0xF7A8), "Dieresissmall"); + nameToUnicode.put("Dieresissmall", new Character((char) 0xF7A8)); + nameToEnc.put("Dieresissmall", new Integer(172)); + encToName[172] = "Dieresissmall"; + + unicodeToName.put(new Character((char) 0xF6F7), "Dotaccentsmall"); + nameToUnicode.put("Dotaccentsmall", new Character((char) 0xF6F7)); + nameToEnc.put("Dotaccentsmall", new Integer(250)); + encToName[250] = "Dotaccentsmall"; + + unicodeToName.put(new Character((char) 0xF764), "Dsmall"); + nameToUnicode.put("Dsmall", new Character((char) 0xF764)); + nameToEnc.put("Dsmall", new Integer(100)); + encToName[100] = "Dsmall"; + + unicodeToName.put(new Character((char) 0xF7E9), "Eacutesmall"); + nameToUnicode.put("Eacutesmall", new Character((char) 0xF7E9)); + nameToEnc.put("Eacutesmall", new Integer(142)); + encToName[142] = "Eacutesmall"; + + unicodeToName.put(new Character((char) 0xF7EA), "Ecircumflexsmall"); + nameToUnicode.put("Ecircumflexsmall", new Character((char) 0xF7EA)); + nameToEnc.put("Ecircumflexsmall", new Integer(144)); + encToName[144] = "Ecircumflexsmall"; + + unicodeToName.put(new Character((char) 0xF7EB), "Edieresissmall"); + nameToUnicode.put("Edieresissmall", new Character((char) 0xF7EB)); + nameToEnc.put("Edieresissmall", new Integer(145)); + encToName[145] = "Edieresissmall"; + + unicodeToName.put(new Character((char) 0xF7E8), "Egravesmall"); + nameToUnicode.put("Egravesmall", new Character((char) 0xF7E8)); + nameToEnc.put("Egravesmall", new Integer(143)); + encToName[143] = "Egravesmall"; + + unicodeToName.put(new Character((char) 0xF765), "Esmall"); + nameToUnicode.put("Esmall", new Character((char) 0xF765)); + nameToEnc.put("Esmall", new Integer(101)); + encToName[101] = "Esmall"; + + unicodeToName.put(new Character((char) 0xF7F0), "Ethsmall"); + nameToUnicode.put("Ethsmall", new Character((char) 0xF7F0)); + nameToEnc.put("Ethsmall", new Integer(68)); + encToName[68] = "Ethsmall"; + + unicodeToName.put(new Character((char) 0xF766), "Fsmall"); + nameToUnicode.put("Fsmall", new Character((char) 0xF766)); + nameToEnc.put("Fsmall", new Integer(102)); + encToName[102] = "Fsmall"; + + unicodeToName.put(new Character((char) 0xF760), "Gravesmall"); + nameToUnicode.put("Gravesmall", new Character((char) 0xF760)); + nameToEnc.put("Gravesmall", new Integer(96)); + encToName[96] = "Gravesmall"; + + unicodeToName.put(new Character((char) 0xF767), "Gsmall"); + nameToUnicode.put("Gsmall", new Character((char) 0xF767)); + nameToEnc.put("Gsmall", new Integer(103)); + encToName[103] = "Gsmall"; + + unicodeToName.put(new Character((char) 0xF768), "Hsmall"); + nameToUnicode.put("Hsmall", new Character((char) 0xF768)); + nameToEnc.put("Hsmall", new Integer(104)); + encToName[104] = "Hsmall"; + + unicodeToName.put(new Character((char) 0xF6F8), "Hungarumlautsmall"); + nameToUnicode.put("Hungarumlautsmall", new Character((char) 0xF6F8)); + nameToEnc.put("Hungarumlautsmall", new Integer(34)); + encToName[34] = "Hungarumlautsmall"; + + unicodeToName.put(new Character((char) 0xF7ED), "Iacutesmall"); + nameToUnicode.put("Iacutesmall", new Character((char) 0xF7ED)); + nameToEnc.put("Iacutesmall", new Integer(146)); + encToName[146] = "Iacutesmall"; + + unicodeToName.put(new Character((char) 0xF7EE), "Icircumflexsmall"); + nameToUnicode.put("Icircumflexsmall", new Character((char) 0xF7EE)); + nameToEnc.put("Icircumflexsmall", new Integer(148)); + encToName[148] = "Icircumflexsmall"; + + unicodeToName.put(new Character((char) 0xF7EF), "Idieresissmall"); + nameToUnicode.put("Idieresissmall", new Character((char) 0xF7EF)); + nameToEnc.put("Idieresissmall", new Integer(149)); + encToName[149] = "Idieresissmall"; + + unicodeToName.put(new Character((char) 0xF7EC), "Igravesmall"); + nameToUnicode.put("Igravesmall", new Character((char) 0xF7EC)); + nameToEnc.put("Igravesmall", new Integer(147)); + encToName[147] = "Igravesmall"; + + unicodeToName.put(new Character((char) 0xF769), "Ismall"); + nameToUnicode.put("Ismall", new Character((char) 0xF769)); + nameToEnc.put("Ismall", new Integer(105)); + encToName[105] = "Ismall"; + + unicodeToName.put(new Character((char) 0xF76A), "Jsmall"); + nameToUnicode.put("Jsmall", new Character((char) 0xF76A)); + nameToEnc.put("Jsmall", new Integer(106)); + encToName[106] = "Jsmall"; + + unicodeToName.put(new Character((char) 0xF76B), "Ksmall"); + nameToUnicode.put("Ksmall", new Character((char) 0xF76B)); + nameToEnc.put("Ksmall", new Integer(107)); + encToName[107] = "Ksmall"; + + unicodeToName.put(new Character((char) 0xF6F9), "Lslashsmall"); + nameToUnicode.put("Lslashsmall", new Character((char) 0xF6F9)); + nameToEnc.put("Lslashsmall", new Integer(194)); + encToName[194] = "Lslashsmall"; + + unicodeToName.put(new Character((char) 0xF76C), "Lsmall"); + nameToUnicode.put("Lsmall", new Character((char) 0xF76C)); + nameToEnc.put("Lsmall", new Integer(108)); + encToName[108] = "Lsmall"; + + unicodeToName.put(new Character((char) 0xF7AF), "Macronsmall"); + nameToUnicode.put("Macronsmall", new Character((char) 0xF7AF)); + nameToEnc.put("Macronsmall", new Integer(244)); + encToName[244] = "Macronsmall"; + + unicodeToName.put(new Character((char) 0xF76D), "Msmall"); + nameToUnicode.put("Msmall", new Character((char) 0xF76D)); + nameToEnc.put("Msmall", new Integer(109)); + encToName[109] = "Msmall"; + + unicodeToName.put(new Character((char) 0xF76E), "Nsmall"); + nameToUnicode.put("Nsmall", new Character((char) 0xF76E)); + nameToEnc.put("Nsmall", new Integer(110)); + encToName[110] = "Nsmall"; + + unicodeToName.put(new Character((char) 0xF7F1), "Ntildesmall"); + nameToUnicode.put("Ntildesmall", new Character((char) 0xF7F1)); + nameToEnc.put("Ntildesmall", new Integer(150)); + encToName[150] = "Ntildesmall"; + + unicodeToName.put(new Character((char) 0xF6FA), "OEsmall"); + nameToUnicode.put("OEsmall", new Character((char) 0xF6FA)); + nameToEnc.put("OEsmall", new Integer(207)); + encToName[207] = "OEsmall"; + + unicodeToName.put(new Character((char) 0xF7F3), "Oacutesmall"); + nameToUnicode.put("Oacutesmall", new Character((char) 0xF7F3)); + nameToEnc.put("Oacutesmall", new Integer(151)); + encToName[151] = "Oacutesmall"; + + unicodeToName.put(new Character((char) 0xF7F4), "Ocircumflexsmall"); + nameToUnicode.put("Ocircumflexsmall", new Character((char) 0xF7F4)); + nameToEnc.put("Ocircumflexsmall", new Integer(153)); + encToName[153] = "Ocircumflexsmall"; + + unicodeToName.put(new Character((char) 0xF7F6), "Odieresissmall"); + nameToUnicode.put("Odieresissmall", new Character((char) 0xF7F6)); + nameToEnc.put("Odieresissmall", new Integer(154)); + encToName[154] = "Odieresissmall"; + + unicodeToName.put(new Character((char) 0xF6FB), "Ogoneksmall"); + nameToUnicode.put("Ogoneksmall", new Character((char) 0xF6FB)); + nameToEnc.put("Ogoneksmall", new Integer(242)); + encToName[242] = "Ogoneksmall"; + + unicodeToName.put(new Character((char) 0xF7F2), "Ogravesmall"); + nameToUnicode.put("Ogravesmall", new Character((char) 0xF7F2)); + nameToEnc.put("Ogravesmall", new Integer(152)); + encToName[152] = "Ogravesmall"; + + unicodeToName.put(new Character((char) 0xF7F8), "Oslashsmall"); + nameToUnicode.put("Oslashsmall", new Character((char) 0xF7F8)); + nameToEnc.put("Oslashsmall", new Integer(191)); + encToName[191] = "Oslashsmall"; + + unicodeToName.put(new Character((char) 0xF76F), "Osmall"); + nameToUnicode.put("Osmall", new Character((char) 0xF76F)); + nameToEnc.put("Osmall", new Integer(111)); + encToName[111] = "Osmall"; + + unicodeToName.put(new Character((char) 0xF7F5), "Otildesmall"); + nameToUnicode.put("Otildesmall", new Character((char) 0xF7F5)); + nameToEnc.put("Otildesmall", new Integer(155)); + encToName[155] = "Otildesmall"; + + unicodeToName.put(new Character((char) 0xF770), "Psmall"); + nameToUnicode.put("Psmall", new Character((char) 0xF770)); + nameToEnc.put("Psmall", new Integer(112)); + encToName[112] = "Psmall"; + + unicodeToName.put(new Character((char) 0xF771), "Qsmall"); + nameToUnicode.put("Qsmall", new Character((char) 0xF771)); + nameToEnc.put("Qsmall", new Integer(113)); + encToName[113] = "Qsmall"; + + unicodeToName.put(new Character((char) 0xF6FC), "Ringsmall"); + nameToUnicode.put("Ringsmall", new Character((char) 0xF6FC)); + nameToEnc.put("Ringsmall", new Integer(251)); + encToName[251] = "Ringsmall"; + + unicodeToName.put(new Character((char) 0xF772), "Rsmall"); + nameToUnicode.put("Rsmall", new Character((char) 0xF772)); + nameToEnc.put("Rsmall", new Integer(114)); + encToName[114] = "Rsmall"; + + unicodeToName.put(new Character((char) 0xF6FD), "Scaronsmall"); + nameToUnicode.put("Scaronsmall", new Character((char) 0xF6FD)); + nameToEnc.put("Scaronsmall", new Integer(167)); + encToName[167] = "Scaronsmall"; + + unicodeToName.put(new Character((char) 0xF773), "Ssmall"); + nameToUnicode.put("Ssmall", new Character((char) 0xF773)); + nameToEnc.put("Ssmall", new Integer(115)); + encToName[115] = "Ssmall"; + + unicodeToName.put(new Character((char) 0xF7FE), "Thornsmall"); + nameToUnicode.put("Thornsmall", new Character((char) 0xF7FE)); + nameToEnc.put("Thornsmall", new Integer(185)); + encToName[185] = "Thornsmall"; + + unicodeToName.put(new Character((char) 0xF6FE), "Tildesmall"); + nameToUnicode.put("Tildesmall", new Character((char) 0xF6FE)); + nameToEnc.put("Tildesmall", new Integer(126)); + encToName[126] = "Tildesmall"; + + unicodeToName.put(new Character((char) 0xF774), "Tsmall"); + nameToUnicode.put("Tsmall", new Character((char) 0xF774)); + nameToEnc.put("Tsmall", new Integer(116)); + encToName[116] = "Tsmall"; + + unicodeToName.put(new Character((char) 0xF7FA), "Uacutesmall"); + nameToUnicode.put("Uacutesmall", new Character((char) 0xF7FA)); + nameToEnc.put("Uacutesmall", new Integer(156)); + encToName[156] = "Uacutesmall"; + + unicodeToName.put(new Character((char) 0xF7FB), "Ucircumflexsmall"); + nameToUnicode.put("Ucircumflexsmall", new Character((char) 0xF7FB)); + nameToEnc.put("Ucircumflexsmall", new Integer(158)); + encToName[158] = "Ucircumflexsmall"; + + unicodeToName.put(new Character((char) 0xF7FC), "Udieresissmall"); + nameToUnicode.put("Udieresissmall", new Character((char) 0xF7FC)); + nameToEnc.put("Udieresissmall", new Integer(159)); + encToName[159] = "Udieresissmall"; + + unicodeToName.put(new Character((char) 0xF7F9), "Ugravesmall"); + nameToUnicode.put("Ugravesmall", new Character((char) 0xF7F9)); + nameToEnc.put("Ugravesmall", new Integer(157)); + encToName[157] = "Ugravesmall"; + + unicodeToName.put(new Character((char) 0xF775), "Usmall"); + nameToUnicode.put("Usmall", new Character((char) 0xF775)); + nameToEnc.put("Usmall", new Integer(117)); + encToName[117] = "Usmall"; + + unicodeToName.put(new Character((char) 0xF776), "Vsmall"); + nameToUnicode.put("Vsmall", new Character((char) 0xF776)); + nameToEnc.put("Vsmall", new Integer(118)); + encToName[118] = "Vsmall"; + + unicodeToName.put(new Character((char) 0xF777), "Wsmall"); + nameToUnicode.put("Wsmall", new Character((char) 0xF777)); + nameToEnc.put("Wsmall", new Integer(119)); + encToName[119] = "Wsmall"; + + unicodeToName.put(new Character((char) 0xF778), "Xsmall"); + nameToUnicode.put("Xsmall", new Character((char) 0xF778)); + nameToEnc.put("Xsmall", new Integer(120)); + encToName[120] = "Xsmall"; + + unicodeToName.put(new Character((char) 0xF7FD), "Yacutesmall"); + nameToUnicode.put("Yacutesmall", new Character((char) 0xF7FD)); + nameToEnc.put("Yacutesmall", new Integer(180)); + encToName[180] = "Yacutesmall"; + + unicodeToName.put(new Character((char) 0xF7FF), "Ydieresissmall"); + nameToUnicode.put("Ydieresissmall", new Character((char) 0xF7FF)); + nameToEnc.put("Ydieresissmall", new Integer(216)); + encToName[216] = "Ydieresissmall"; + + unicodeToName.put(new Character((char) 0xF779), "Ysmall"); + nameToUnicode.put("Ysmall", new Character((char) 0xF779)); + nameToEnc.put("Ysmall", new Integer(121)); + encToName[121] = "Ysmall"; + + unicodeToName.put(new Character((char) 0xF6FF), "Zcaronsmall"); + nameToUnicode.put("Zcaronsmall", new Character((char) 0xF6FF)); + nameToEnc.put("Zcaronsmall", new Integer(189)); + encToName[189] = "Zcaronsmall"; + + unicodeToName.put(new Character((char) 0xF77A), "Zsmall"); + nameToUnicode.put("Zsmall", new Character((char) 0xF77A)); + nameToEnc.put("Zsmall", new Integer(122)); + encToName[122] = "Zsmall"; + + unicodeToName.put(new Character((char) 0xfe60), "ampersandsmall"); + nameToUnicode.put("ampersandsmall", new Character((char) 0xfe60)); + nameToEnc.put("ampersandsmall", new Integer(38)); + encToName[38] = "ampersandsmall"; + + unicodeToName.put(new Character((char) 0xF6E9), "asuperior"); + nameToUnicode.put("asuperior", new Character((char) 0xF6E9)); + nameToEnc.put("asuperior", new Integer(129)); + encToName[129] = "asuperior"; + + unicodeToName.put(new Character((char) 0xF6EA), "bsuperior"); + nameToUnicode.put("bsuperior", new Character((char) 0xF6EA)); + nameToEnc.put("bsuperior", new Integer(245)); + encToName[245] = "bsuperior"; + + unicodeToName.put(new Character((char) 0xF6DF), "centinferior"); + nameToUnicode.put("centinferior", new Character((char) 0xF6DF)); + nameToEnc.put("centinferior", new Integer(169)); + encToName[169] = "centinferior"; + + unicodeToName.put(new Character((char) 0xF7A2), "centoldstyle"); + nameToUnicode.put("centoldstyle", new Character((char) 0xF7A2)); + nameToEnc.put("centoldstyle", new Integer(35)); + encToName[35] = "centoldstyle"; + + unicodeToName.put(new Character((char) 0xF6E0), "centsuperior"); + nameToUnicode.put("centsuperior", new Character((char) 0xF6E0)); + nameToEnc.put("centsuperior", new Integer(130)); + encToName[130] = "centsuperior"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x20a1), "colonmonetary"); + nameToUnicode.put("colonmonetary", new Character((char) 0x20a1)); + nameToEnc.put("colonmonetary", new Integer(123)); + encToName[123] = "colonmonetary"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0xF6E1), "commainferior"); + nameToUnicode.put("commainferior", new Character((char) 0xF6E1)); + nameToEnc.put("commainferior", new Integer(178)); + encToName[178] = "commainferior"; + + unicodeToName.put(new Character((char) 0xF6E2), "commasuperior"); + nameToUnicode.put("commasuperior", new Character((char) 0xF6E2)); + nameToEnc.put("commasuperior", new Integer(248)); + encToName[248] = "commasuperior"; + + unicodeToName.put(new Character((char) 0xF6E3), "dollarinferior"); + nameToUnicode.put("dollarinferior", new Character((char) 0xF6E3)); + nameToEnc.put("dollarinferior", new Integer(182)); + encToName[182] = "dollarinferior"; + + unicodeToName.put(new Character((char) 0xF724), "dollaroldstyle"); + nameToUnicode.put("dollaroldstyle", new Character((char) 0xF724)); + nameToEnc.put("dollaroldstyle", new Integer(36)); + encToName[36] = "dollaroldstyle"; + + unicodeToName.put(new Character((char) 0xF6E4), "dollarsuperior"); + nameToUnicode.put("dollarsuperior", new Character((char) 0xF6E4)); + nameToEnc.put("dollarsuperior", new Integer(37)); + encToName[37] = "dollarsuperior"; + + unicodeToName.put(new Character((char) 0xF6EB), "dsuperior"); + nameToUnicode.put("dsuperior", new Character((char) 0xF6EB)); + nameToEnc.put("dsuperior", new Integer(235)); + encToName[235] = "dsuperior"; + + unicodeToName.put(new Character((char) 0x2088), "eightinferior"); + nameToUnicode.put("eightinferior", new Character((char) 0x2088)); + nameToEnc.put("eightinferior", new Integer(165)); + encToName[165] = "eightinferior"; + + unicodeToName.put(new Character((char) 0xF738), "eightoldstyle"); + nameToUnicode.put("eightoldstyle", new Character((char) 0xF738)); + nameToEnc.put("eightoldstyle", new Integer(56)); + encToName[56] = "eightoldstyle"; + + unicodeToName.put(new Character((char) 0x2078), "eightsuperior"); + nameToUnicode.put("eightsuperior", new Character((char) 0x2078)); + nameToEnc.put("eightsuperior", new Integer(161)); + encToName[161] = "eightsuperior"; + + unicodeToName.put(new Character((char) 0xF6EC), "esuperior"); + nameToUnicode.put("esuperior", new Character((char) 0xF6EC)); + nameToEnc.put("esuperior", new Integer(228)); + encToName[228] = "esuperior"; + + unicodeToName.put(new Character((char) 0xF7A1), "exclamdownsmall"); + nameToUnicode.put("exclamdownsmall", new Character((char) 0xF7A1)); + nameToEnc.put("exclamdownsmall", new Integer(214)); + encToName[214] = "exclamdownsmall"; + + unicodeToName.put(new Character((char) 0xfe57), "exclamsmall"); + nameToUnicode.put("exclamsmall", new Character((char) 0xfe57)); + nameToEnc.put("exclamsmall", new Integer(33)); + encToName[33] = "exclamsmall"; + + unicodeToName.put(new Character((char) 0xfb00), "ff"); + nameToUnicode.put("ff", new Character((char) 0xfb00)); + nameToEnc.put("ff", new Integer(86)); + encToName[86] = "ff"; + + unicodeToName.put(new Character((char) 0xfb03), "ffi"); + nameToUnicode.put("ffi", new Character((char) 0xfb03)); + nameToEnc.put("ffi", new Integer(89)); + encToName[89] = "ffi"; + + unicodeToName.put(new Character((char) 0xfb04), "ffl"); + nameToUnicode.put("ffl", new Character((char) 0xfb04)); + nameToEnc.put("ffl", new Integer(90)); + encToName[90] = "ffl"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + nameToEnc.put("fi", new Integer(87)); + encToName[87] = "fi"; + + unicodeToName.put(new Character((char) 0x2012), "figuredash"); + nameToUnicode.put("figuredash", new Character((char) 0x2012)); + nameToEnc.put("figuredash", new Integer(208)); + encToName[208] = "figuredash"; + + unicodeToName.put(new Character((char) 0x215d), "fiveeighths"); + nameToUnicode.put("fiveeighths", new Character((char) 0x215d)); + nameToEnc.put("fiveeighths", new Integer(76)); + encToName[76] = "fiveeighths"; + + unicodeToName.put(new Character((char) 0x2085), "fiveinferior"); + nameToUnicode.put("fiveinferior", new Character((char) 0x2085)); + nameToEnc.put("fiveinferior", new Integer(176)); + encToName[176] = "fiveinferior"; + + unicodeToName.put(new Character((char) 0xF735), "fiveoldstyle"); + nameToUnicode.put("fiveoldstyle", new Character((char) 0xF735)); + nameToEnc.put("fiveoldstyle", new Integer(53)); + encToName[53] = "fiveoldstyle"; + + unicodeToName.put(new Character((char) 0x2075), "fivesuperior"); + nameToUnicode.put("fivesuperior", new Character((char) 0x2075)); + nameToEnc.put("fivesuperior", new Integer(222)); + encToName[222] = "fivesuperior"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + nameToEnc.put("fl", new Integer(88)); + encToName[88] = "fl"; + + unicodeToName.put(new Character((char) 0x2084), "fourinferior"); + nameToUnicode.put("fourinferior", new Character((char) 0x2084)); + nameToEnc.put("fourinferior", new Integer(162)); + encToName[162] = "fourinferior"; + + unicodeToName.put(new Character((char) 0xF734), "fouroldstyle"); + nameToUnicode.put("fouroldstyle", new Character((char) 0xF734)); + nameToEnc.put("fouroldstyle", new Integer(52)); + encToName[52] = "fouroldstyle"; + + unicodeToName.put(new Character((char) 0x2074), "foursuperior"); + nameToUnicode.put("foursuperior", new Character((char) 0x2074)); + nameToEnc.put("foursuperior", new Integer(221)); + encToName[221] = "foursuperior"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + nameToEnc.put("fraction", new Integer(47)); + encToName[47] = "fraction"; + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(45)); + encToName[45] = "hyphen"; + + unicodeToName.put(new Character((char) 0x208b), "hypheninferior"); + nameToUnicode.put("hypheninferior", new Character((char) 0x208b)); + nameToEnc.put("hypheninferior", new Integer(95)); + encToName[95] = "hypheninferior"; + + unicodeToName.put(new Character((char) 0x207b), "hyphensuperior"); + nameToUnicode.put("hyphensuperior", new Character((char) 0x207b)); + nameToEnc.put("hyphensuperior", new Integer(209)); + encToName[209] = "hyphensuperior"; + + unicodeToName.put(new Character((char) 0xF6ED), "isuperior"); + nameToUnicode.put("isuperior", new Character((char) 0xF6ED)); + nameToEnc.put("isuperior", new Integer(233)); + encToName[233] = "isuperior"; + + unicodeToName.put(new Character((char) 0xF6EE), "lsuperior"); + nameToUnicode.put("lsuperior", new Character((char) 0xF6EE)); + nameToEnc.put("lsuperior", new Integer(241)); + encToName[241] = "lsuperior"; + + unicodeToName.put(new Character((char) 0xF6EF), "msuperior"); + nameToUnicode.put("msuperior", new Character((char) 0xF6EF)); + nameToEnc.put("msuperior", new Integer(247)); + encToName[247] = "msuperior"; + + unicodeToName.put(new Character((char) 0x2089), "nineinferior"); + nameToUnicode.put("nineinferior", new Character((char) 0x2089)); + nameToEnc.put("nineinferior", new Integer(187)); + encToName[187] = "nineinferior"; + + unicodeToName.put(new Character((char) 0xF739), "nineoldstyle"); + nameToUnicode.put("nineoldstyle", new Character((char) 0xF739)); + nameToEnc.put("nineoldstyle", new Integer(57)); + encToName[57] = "nineoldstyle"; + + unicodeToName.put(new Character((char) 0x2079), "ninesuperior"); + nameToUnicode.put("ninesuperior", new Character((char) 0x2079)); + nameToEnc.put("ninesuperior", new Integer(225)); + encToName[225] = "ninesuperior"; + + unicodeToName.put(new Character((char) 0x207f), "nsuperior"); + nameToUnicode.put("nsuperior", new Character((char) 0x207f)); + nameToEnc.put("nsuperior", new Integer(246)); + encToName[246] = "nsuperior"; + + unicodeToName.put(new Character((char) 0x2024), "onedotenleader"); + nameToUnicode.put("onedotenleader", new Character((char) 0x2024)); + nameToEnc.put("onedotenleader", new Integer(43)); + encToName[43] = "onedotenleader"; + + unicodeToName.put(new Character((char) 0x215b), "oneeight"); + nameToUnicode.put("oneeight", new Character((char) 0x215b)); + nameToEnc.put("oneeight", new Integer(74)); + encToName[74] = "oneeight"; + + unicodeToName.put(new Character((char) 0xF6DC), "onefitted"); + nameToUnicode.put("onefitted", new Character((char) 0xF6DC)); + nameToEnc.put("onefitted", new Integer(124)); + encToName[124] = "onefitted"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + nameToEnc.put("onehalf", new Integer(72)); + encToName[72] = "onehalf"; + + unicodeToName.put(new Character((char) 0x2081), "oneinferior"); + nameToUnicode.put("oneinferior", new Character((char) 0x2081)); + nameToEnc.put("oneinferior", new Integer(193)); + encToName[193] = "oneinferior"; + + unicodeToName.put(new Character((char) 0xF731), "oneoldstyle"); + nameToUnicode.put("oneoldstyle", new Character((char) 0xF731)); + nameToEnc.put("oneoldstyle", new Integer(49)); + encToName[49] = "oneoldstyle"; + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + nameToEnc.put("onequarter", new Integer(71)); + encToName[71] = "onequarter"; + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + nameToEnc.put("onesuperior", new Integer(218)); + encToName[218] = "onesuperior"; + + unicodeToName.put(new Character((char) 0x2153), "onethird"); + nameToUnicode.put("onethird", new Character((char) 0x2153)); + nameToEnc.put("onethird", new Integer(78)); + encToName[78] = "onethird"; + + unicodeToName.put(new Character((char) 0xF6F0), "osuperior"); + nameToUnicode.put("osuperior", new Character((char) 0xF6F0)); + nameToEnc.put("osuperior", new Integer(175)); + encToName[175] = "osuperior"; + + unicodeToName.put(new Character((char) 0x208d), "parenleftinferior"); + nameToUnicode.put("parenleftinferior", new Character((char) 0x208d)); + nameToEnc.put("parenleftinferior", new Integer(91)); + encToName[91] = "parenleftinferior"; + + unicodeToName.put(new Character((char) 0x207d), "parenleftsuperior"); + nameToUnicode.put("parenleftsuperior", new Character((char) 0x207d)); + nameToEnc.put("parenleftsuperior", new Integer(40)); + encToName[40] = "parenleftsuperior"; + + unicodeToName.put(new Character((char) 0x208e), "parenrightinferior"); + nameToUnicode.put("parenrightinferior", new Character((char) 0x208e)); + nameToEnc.put("parenrightinferior", new Integer(93)); + encToName[93] = "parenrightinferior"; + + unicodeToName.put(new Character((char) 0x207e), "parenrightsuperior"); + nameToUnicode.put("parenrightsuperior", new Character((char) 0x207e)); + nameToEnc.put("parenrightsuperior", new Integer(41)); + encToName[41] = "parenrightsuperior"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0xF6E7), "periodinferior"); + nameToUnicode.put("periodinferior", new Character((char) 0xF6E7)); + nameToEnc.put("periodinferior", new Integer(179)); + encToName[179] = "periodinferior"; + + unicodeToName.put(new Character((char) 0xF6E8), "periodsuperior"); + nameToUnicode.put("periodsuperior", new Character((char) 0xF6E8)); + nameToEnc.put("periodsuperior", new Integer(249)); + encToName[249] = "periodsuperior"; + + unicodeToName.put(new Character((char) 0xF7BF), "questiondownsmall"); + nameToUnicode.put("questiondownsmall", new Character((char) 0xF7BF)); + nameToEnc.put("questiondownsmall", new Integer(192)); + encToName[192] = "questiondownsmall"; + + unicodeToName.put(new Character((char) 0xfe56), "questionsmall"); + nameToUnicode.put("questionsmall", new Character((char) 0xfe56)); + nameToEnc.put("questionsmall", new Integer(63)); + encToName[63] = "questionsmall"; + + unicodeToName.put(new Character((char) 0xF6F1), "rsuperior"); + nameToUnicode.put("rsuperior", new Character((char) 0xF6F1)); + nameToEnc.put("rsuperior", new Integer(229)); + encToName[229] = "rsuperior"; + + unicodeToName.put(new Character((char) 0xF6DD), "rupiah"); + nameToUnicode.put("rupiah", new Character((char) 0xF6DD)); + nameToEnc.put("rupiah", new Integer(125)); + encToName[125] = "rupiah"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x215e), "seveneighths"); + nameToUnicode.put("seveneighths", new Character((char) 0x215e)); + nameToEnc.put("seveneighths", new Integer(77)); + encToName[77] = "seveneighths"; + + unicodeToName.put(new Character((char) 0x2087), "seveninferior"); + nameToUnicode.put("seveninferior", new Character((char) 0x2087)); + nameToEnc.put("seveninferior", new Integer(166)); + encToName[166] = "seveninferior"; + + unicodeToName.put(new Character((char) 0xF737), "sevenoldstyle"); + nameToUnicode.put("sevenoldstyle", new Character((char) 0xF737)); + nameToEnc.put("sevenoldstyle", new Integer(55)); + encToName[55] = "sevenoldstyle"; + + unicodeToName.put(new Character((char) 0x2077), "sevensuperior"); + nameToUnicode.put("sevensuperior", new Character((char) 0x2077)); + nameToEnc.put("sevensuperior", new Integer(224)); + encToName[224] = "sevensuperior"; + + unicodeToName.put(new Character((char) 0x2086), "sixinferior"); + nameToUnicode.put("sixinferior", new Character((char) 0x2086)); + nameToEnc.put("sixinferior", new Integer(164)); + encToName[164] = "sixinferior"; + + unicodeToName.put(new Character((char) 0xF736), "sixoldstyle"); + nameToUnicode.put("sixoldstyle", new Character((char) 0xF736)); + nameToEnc.put("sixoldstyle", new Integer(54)); + encToName[54] = "sixoldstyle"; + + unicodeToName.put(new Character((char) 0x2076), "sixsuperior"); + nameToUnicode.put("sixsuperior", new Character((char) 0x2076)); + nameToEnc.put("sixsuperior", new Integer(223)); + encToName[223] = "sixsuperior"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0xF6F2), "ssuperior"); + nameToUnicode.put("ssuperior", new Character((char) 0xF6F2)); + nameToEnc.put("ssuperior", new Integer(234)); + encToName[234] = "ssuperior"; + + unicodeToName.put(new Character((char) 0x215c), "threeeighths"); + nameToUnicode.put("threeeighths", new Character((char) 0x215c)); + nameToEnc.put("threeeighths", new Integer(75)); + encToName[75] = "threeeighths"; + + unicodeToName.put(new Character((char) 0x2083), "threeinferior"); + nameToUnicode.put("threeinferior", new Character((char) 0x2083)); + nameToEnc.put("threeinferior", new Integer(163)); + encToName[163] = "threeinferior"; + + unicodeToName.put(new Character((char) 0xF733), "threeoldstyle"); + nameToUnicode.put("threeoldstyle", new Character((char) 0xF733)); + nameToEnc.put("threeoldstyle", new Integer(51)); + encToName[51] = "threeoldstyle"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + nameToEnc.put("threequarters", new Integer(73)); + encToName[73] = "threequarters"; + + unicodeToName.put(new Character((char) 0xfe58), "threequartersemdash"); + nameToUnicode.put("threequartersemdash", new Character((char) 0xfe58)); + nameToEnc.put("threequartersemdash", new Integer(61)); + encToName[61] = "threequartersemdash"; + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + nameToEnc.put("threesuperior", new Integer(220)); + encToName[220] = "threesuperior"; + + unicodeToName.put(new Character((char) 0xF6F3), "tsuperior"); + nameToUnicode.put("tsuperior", new Character((char) 0xF6F3)); + nameToEnc.put("tsuperior", new Integer(230)); + encToName[230] = "tsuperior"; + + unicodeToName.put(new Character((char) 0x2025), "twodotenleader"); + nameToUnicode.put("twodotenleader", new Character((char) 0x2025)); + nameToEnc.put("twodotenleader", new Integer(42)); + encToName[42] = "twodotenleader"; + + unicodeToName.put(new Character((char) 0x2082), "twoinferior"); + nameToUnicode.put("twoinferior", new Character((char) 0x2082)); + nameToEnc.put("twoinferior", new Integer(170)); + encToName[170] = "twoinferior"; + + unicodeToName.put(new Character((char) 0xF732), "twooldstyle"); + nameToUnicode.put("twooldstyle", new Character((char) 0xF732)); + nameToEnc.put("twooldstyle", new Integer(50)); + encToName[50] = "twooldstyle"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + nameToEnc.put("twosuperior", new Integer(219)); + encToName[219] = "twosuperior"; + + unicodeToName.put(new Character((char) 0x2154), "twothirds"); + nameToUnicode.put("twothirds", new Character((char) 0x2154)); + nameToEnc.put("twothirds", new Integer(79)); + encToName[79] = "twothirds"; + + unicodeToName.put(new Character((char) 0x2080), "zeroinferior"); + nameToUnicode.put("zeroinferior", new Character((char) 0x2080)); + nameToEnc.put("zeroinferior", new Integer(188)); + encToName[188] = "zeroinferior"; + + unicodeToName.put(new Character((char) 0xF730), "zerooldstyle"); + nameToUnicode.put("zerooldstyle", new Character((char) 0xF730)); + nameToEnc.put("zerooldstyle", new Integer(48)); + encToName[48] = "zerooldstyle"; + + unicodeToName.put(new Character((char) 0x2070), "zerosuperior"); + nameToUnicode.put("zerosuperior", new Character((char) 0x2070)); + nameToEnc.put("zerosuperior", new Integer(226)); + encToName[226] = "zerosuperior"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Expert"); //$NON-NLS-1$ + } + + public String getEncoding() { + return (""); //$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontEncoder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontEncoder.java index ba61e2bde..d8306a10b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontEncoder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontEncoder.java @@ -1,32 +1,32 @@ -// Copyright 2005, FreeHEP. -package org.xmind.org.freehep.graphics2d.font; - - -public class FontEncoder { - - private FontEncoder() { - } - - public static String getEncodedString(String string, String tableName) { - CharTable charTable = Lookup.getInstance().getTable(tableName); - return getEncodedString(string, charTable); - } - - /** - * Returns an unicode encoded string from an ascii encoded string, using the - * supplied table. - */ - public static String getEncodedString(String string, CharTable charTable) { - if (charTable == null) - return string; - - StringBuffer s = new StringBuffer(); - for (int i = 0; i < string.length(); i++) { - int enc = string.charAt(i); - String name = charTable.toName(enc); - s.append((name != null) ? charTable.toUnicode(name) : (char) enc); - } - return s.toString(); - } - +// Copyright 2005, FreeHEP. +package org.xmind.org.freehep.graphics2d.font; + + +public class FontEncoder { + + private FontEncoder() { + } + + public static String getEncodedString(String string, String tableName) { + CharTable charTable = Lookup.getInstance().getTable(tableName); + return getEncodedString(string, charTable); + } + + /** + * Returns an unicode encoded string from an ascii encoded string, using the + * supplied table. + */ + public static String getEncodedString(String string, CharTable charTable) { + if (charTable == null) + return string; + + StringBuffer s = new StringBuffer(); + for (int i = 0; i < string.length(); i++) { + int enc = string.charAt(i); + String name = charTable.toName(enc); + s.append((name != null) ? charTable.toUnicode(name) : (char) enc); + } + return s.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontUtilities.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontUtilities.java index d42dd5065..1b32de022 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontUtilities.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/FontUtilities.java @@ -1,172 +1,172 @@ -// Copyright FreeHEP, 2003-2007 -package org.xmind.org.freehep.graphics2d.font; - -import java.awt.Font; -import java.awt.GraphicsEnvironment; -import java.awt.font.TextAttribute; -import java.io.IOException; -import java.util.Arrays; -import java.util.Hashtable; -import java.util.List; -import java.util.Properties; - -/** - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class FontUtilities { - - private FontUtilities() { - } - - public static List getAllAvailableFonts() { - return Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment() - .getAvailableFontFamilyNames()); - } - - private static final Properties windowsFonts = new Properties(); - static { - // Looks like Unicode MS makes thinner characters - // List fontNames = getAllAvailableFonts(); - // String arial = fontNames.contains("Arial Unicode MS") ? "Arial - // Unicode MS" : "Arial"; - String arial = "Arial"; //$NON-NLS-1$ - - // logical fonts - windowsFonts.setProperty("Dialog", arial); //$NON-NLS-1$ - windowsFonts.setProperty("DialogInput", "Courier New"); //$NON-NLS-1$ //$NON-NLS-2$ - windowsFonts.setProperty("Serif", "Times New Roman"); //$NON-NLS-1$//$NON-NLS-2$ - windowsFonts.setProperty("SansSerif", arial); //$NON-NLS-1$ - windowsFonts.setProperty("Monospaced", "Courier New"); //$NON-NLS-1$ //$NON-NLS-2$ - - // pdf fonts - windowsFonts.setProperty("Courier", "Courier New"); //$NON-NLS-1$//$NON-NLS-2$ - windowsFonts.setProperty("Helvetica", arial); //$NON-NLS-1$ - windowsFonts.setProperty("Times-Roman", "Times New Roman"); //$NON-NLS-1$ //$NON-NLS-2$ - windowsFonts.setProperty("TimesRoman", "Times New Roman"); //$NON-NLS-1$//$NON-NLS-2$ - windowsFonts.setProperty("Times", "Times New Roman"); //$NON-NLS-1$ //$NON-NLS-2$ - windowsFonts.setProperty("Symbol", "Arial Unicode MS"); //$NON-NLS-1$ //$NON-NLS-2$ - windowsFonts.setProperty("ZapfDingbats", "Arial Unicode MS"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public static String getWindowsFontName(String fontName) { - return windowsFonts.getProperty(fontName, fontName); - } - - /** - * @deprecated use - * org.xmind.org.freehep.graphics2d.font.FontEncoder.getEncodedString() - */ - public static String getEncodedString(String string, String tableName) { - return FontEncoder.getEncodedString(string, tableName); - } - - /** - * Returns an unicode encoded string from an ascii encoded string, using the - * supplied table. - * - * @deprecated use - * org.xmind.org.freehep.graphics2d.font.FontEncoder.getEncodedString() - */ - public static String getEncodedString(String string, CharTable charTable) { - return FontEncoder.getEncodedString(string, charTable); - } - - public interface ShowString { - public void showString(Font font, String string) throws IOException; - } - - private static final CharTable STANDARD_CHAR_TABLES[] = { null, - Lookup.getInstance().getTable("Symbol"), //$NON-NLS-1$ - Lookup.getInstance().getTable("Zapfdingbats") }; //$NON-NLS-1$ - - private static final Font STANDARD_FONT[] = { null, - new Font("Symbol", Font.PLAIN, 10), //$NON-NLS-1$ - new Font("ZapfDingbats", Font.PLAIN, 10), }; //$NON-NLS-1$ - - /** - * Shows a String and switches the encoding (and font) everytime the unicode - * characters leave the range of the curent encoding. Outside the range of - * the given latinTable, Symbol and ZapfDingbats are checked. If none of - * these three encodings contain the unicode character, an undefined - * character is used. - */ - public static void showString(Font font, String string, - CharTable latinTable, ShowString device) throws IOException { - - if (latinTable == null) - throw new RuntimeException( - "FontUtilities.showString(...): latinTable cannot be 'null'"); //$NON-NLS-1$ - - STANDARD_FONT[0] = font; - STANDARD_FONT[1] = new Font("Symbol", Font.PLAIN, font.getSize()); //$NON-NLS-1$ - STANDARD_FONT[2] = new Font("ZapfDingbats", Font.PLAIN, font.getSize()); //$NON-NLS-1$ - STANDARD_CHAR_TABLES[0] = latinTable; - - char[] chars = string.toCharArray(); - String out = ""; //$NON-NLS-1$ - int lastTable = 0; - - for (int i = 0; i < chars.length; i++) { - - // find out suitable table and encoding of this character - // try last table first - int table = lastTable; - char encoding = (char) STANDARD_CHAR_TABLES[table] - .toEncoding(chars[i]); - // no success -> try all other tables - if (encoding == 0) { - table = -1; - do { - table++; - if (table != lastTable) { // we already checked that - encoding = (char) STANDARD_CHAR_TABLES[table] - .toEncoding(chars[i]); - } - } while ((encoding == 0) - && (table < STANDARD_CHAR_TABLES.length - 1)); - } - if (encoding == 0) - table = lastTable; - - if ((table != lastTable) && (!out.equals(""))) { //$NON-NLS-1$ - // if font changes, write the old font and string so far - device.showString(STANDARD_FONT[lastTable], out); - out = ""; //$NON-NLS-1$ - } - // append character to out - out += encoding; - lastTable = table; - } - - device.showString(STANDARD_FONT[lastTable], out); - } - - /** - * there is a bug in the jdk 1.6 which makes Font.getAttributes() not work - * correctly. The method does not return all values. What we dow here is - * using the old JDK 1.5 method. - * - * @param font - * font - * @return Attributes of font - */ - public static Hashtable getAttributes(Font font) { - Hashtable result = new Hashtable( - 7, (float) 0.9); - result.put(TextAttribute.TRANSFORM, font.getTransform()); - result.put(TextAttribute.FAMILY, font.getName()); - result.put(TextAttribute.SIZE, new Float(font.getSize2D())); - result.put(TextAttribute.WEIGHT, - (font.getStyle() & Font.BOLD) != 0 ? TextAttribute.WEIGHT_BOLD - : TextAttribute.WEIGHT_REGULAR); - result.put( - TextAttribute.POSTURE, - (font.getStyle() & Font.ITALIC) != 0 ? TextAttribute.POSTURE_OBLIQUE - : TextAttribute.POSTURE_REGULAR); - result.put(TextAttribute.SUPERSCRIPT, new Integer(0 /* no getter! */)); - result.put(TextAttribute.WIDTH, new Float(1 /* no getter */)); - return result; - } +// Copyright FreeHEP, 2003-2007 +package org.xmind.org.freehep.graphics2d.font; + +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.awt.font.TextAttribute; +import java.io.IOException; +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; +import java.util.Properties; + +/** + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class FontUtilities { + + private FontUtilities() { + } + + public static List getAllAvailableFonts() { + return Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment() + .getAvailableFontFamilyNames()); + } + + private static final Properties windowsFonts = new Properties(); + static { + // Looks like Unicode MS makes thinner characters + // List fontNames = getAllAvailableFonts(); + // String arial = fontNames.contains("Arial Unicode MS") ? "Arial + // Unicode MS" : "Arial"; + String arial = "Arial"; //$NON-NLS-1$ + + // logical fonts + windowsFonts.setProperty("Dialog", arial); //$NON-NLS-1$ + windowsFonts.setProperty("DialogInput", "Courier New"); //$NON-NLS-1$ //$NON-NLS-2$ + windowsFonts.setProperty("Serif", "Times New Roman"); //$NON-NLS-1$//$NON-NLS-2$ + windowsFonts.setProperty("SansSerif", arial); //$NON-NLS-1$ + windowsFonts.setProperty("Monospaced", "Courier New"); //$NON-NLS-1$ //$NON-NLS-2$ + + // pdf fonts + windowsFonts.setProperty("Courier", "Courier New"); //$NON-NLS-1$//$NON-NLS-2$ + windowsFonts.setProperty("Helvetica", arial); //$NON-NLS-1$ + windowsFonts.setProperty("Times-Roman", "Times New Roman"); //$NON-NLS-1$ //$NON-NLS-2$ + windowsFonts.setProperty("TimesRoman", "Times New Roman"); //$NON-NLS-1$//$NON-NLS-2$ + windowsFonts.setProperty("Times", "Times New Roman"); //$NON-NLS-1$ //$NON-NLS-2$ + windowsFonts.setProperty("Symbol", "Arial Unicode MS"); //$NON-NLS-1$ //$NON-NLS-2$ + windowsFonts.setProperty("ZapfDingbats", "Arial Unicode MS"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static String getWindowsFontName(String fontName) { + return windowsFonts.getProperty(fontName, fontName); + } + + /** + * @deprecated use + * org.xmind.org.freehep.graphics2d.font.FontEncoder.getEncodedString() + */ + public static String getEncodedString(String string, String tableName) { + return FontEncoder.getEncodedString(string, tableName); + } + + /** + * Returns an unicode encoded string from an ascii encoded string, using the + * supplied table. + * + * @deprecated use + * org.xmind.org.freehep.graphics2d.font.FontEncoder.getEncodedString() + */ + public static String getEncodedString(String string, CharTable charTable) { + return FontEncoder.getEncodedString(string, charTable); + } + + public interface ShowString { + public void showString(Font font, String string) throws IOException; + } + + private static final CharTable STANDARD_CHAR_TABLES[] = { null, + Lookup.getInstance().getTable("Symbol"), //$NON-NLS-1$ + Lookup.getInstance().getTable("Zapfdingbats") }; //$NON-NLS-1$ + + private static final Font STANDARD_FONT[] = { null, + new Font("Symbol", Font.PLAIN, 10), //$NON-NLS-1$ + new Font("ZapfDingbats", Font.PLAIN, 10), }; //$NON-NLS-1$ + + /** + * Shows a String and switches the encoding (and font) everytime the unicode + * characters leave the range of the curent encoding. Outside the range of + * the given latinTable, Symbol and ZapfDingbats are checked. If none of + * these three encodings contain the unicode character, an undefined + * character is used. + */ + public static void showString(Font font, String string, + CharTable latinTable, ShowString device) throws IOException { + + if (latinTable == null) + throw new RuntimeException( + "FontUtilities.showString(...): latinTable cannot be 'null'"); //$NON-NLS-1$ + + STANDARD_FONT[0] = font; + STANDARD_FONT[1] = new Font("Symbol", Font.PLAIN, font.getSize()); //$NON-NLS-1$ + STANDARD_FONT[2] = new Font("ZapfDingbats", Font.PLAIN, font.getSize()); //$NON-NLS-1$ + STANDARD_CHAR_TABLES[0] = latinTable; + + char[] chars = string.toCharArray(); + String out = ""; //$NON-NLS-1$ + int lastTable = 0; + + for (int i = 0; i < chars.length; i++) { + + // find out suitable table and encoding of this character + // try last table first + int table = lastTable; + char encoding = (char) STANDARD_CHAR_TABLES[table] + .toEncoding(chars[i]); + // no success -> try all other tables + if (encoding == 0) { + table = -1; + do { + table++; + if (table != lastTable) { // we already checked that + encoding = (char) STANDARD_CHAR_TABLES[table] + .toEncoding(chars[i]); + } + } while ((encoding == 0) + && (table < STANDARD_CHAR_TABLES.length - 1)); + } + if (encoding == 0) + table = lastTable; + + if ((table != lastTable) && (!out.equals(""))) { //$NON-NLS-1$ + // if font changes, write the old font and string so far + device.showString(STANDARD_FONT[lastTable], out); + out = ""; //$NON-NLS-1$ + } + // append character to out + out += encoding; + lastTable = table; + } + + device.showString(STANDARD_FONT[lastTable], out); + } + + /** + * there is a bug in the jdk 1.6 which makes Font.getAttributes() not work + * correctly. The method does not return all values. What we dow here is + * using the old JDK 1.5 method. + * + * @param font + * font + * @return Attributes of font + */ + public static Hashtable getAttributes(Font font) { + Hashtable result = new Hashtable( + 7, (float) 0.9); + result.put(TextAttribute.TRANSFORM, font.getTransform()); + result.put(TextAttribute.FAMILY, font.getName()); + result.put(TextAttribute.SIZE, new Float(font.getSize2D())); + result.put(TextAttribute.WEIGHT, + (font.getStyle() & Font.BOLD) != 0 ? TextAttribute.WEIGHT_BOLD + : TextAttribute.WEIGHT_REGULAR); + result.put( + TextAttribute.POSTURE, + (font.getStyle() & Font.ITALIC) != 0 ? TextAttribute.POSTURE_OBLIQUE + : TextAttribute.POSTURE_REGULAR); + result.put(TextAttribute.SUPERSCRIPT, new Integer(0 /* no getter! */)); + result.put(TextAttribute.WIDTH, new Float(1 /* no getter */)); + return result; + } } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/ISOLatin.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/ISOLatin.java index 14d95f2bb..3386e774b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/ISOLatin.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/ISOLatin.java @@ -1,1136 +1,1136 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated ISOLatin Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class ISOLatin extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public ISOLatin() { - unicodeToName.put(new Character((char) 0x0041), "A"); - nameToUnicode.put("A", new Character((char) 0x0041)); - nameToEnc.put("A", new Integer(65)); - encToName[65] = "A"; - - unicodeToName.put(new Character((char) 0x00c6), "AE"); - nameToUnicode.put("AE", new Character((char) 0x00c6)); - nameToEnc.put("AE", new Integer(225)); - encToName[225] = "AE"; - - unicodeToName.put(new Character((char) 0x00c1), "Aacute"); - nameToUnicode.put("Aacute", new Character((char) 0x00c1)); - nameToEnc.put("Aacute", new Integer(193)); - encToName[193] = "Aacute"; - - unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); - nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); - nameToEnc.put("Acircumflex", new Integer(194)); - encToName[194] = "Acircumflex"; - - unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); - nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); - nameToEnc.put("Adieresis", new Integer(196)); - encToName[196] = "Adieresis"; - - unicodeToName.put(new Character((char) 0x00c0), "Agrave"); - nameToUnicode.put("Agrave", new Character((char) 0x00c0)); - nameToEnc.put("Agrave", new Integer(192)); - encToName[192] = "Agrave"; - - unicodeToName.put(new Character((char) 0x00c5), "Aring"); - nameToUnicode.put("Aring", new Character((char) 0x00c5)); - nameToEnc.put("Aring", new Integer(197)); - encToName[197] = "Aring"; - - unicodeToName.put(new Character((char) 0x00c3), "Atilde"); - nameToUnicode.put("Atilde", new Character((char) 0x00c3)); - nameToEnc.put("Atilde", new Integer(195)); - encToName[195] = "Atilde"; - - unicodeToName.put(new Character((char) 0x0042), "B"); - nameToUnicode.put("B", new Character((char) 0x0042)); - nameToEnc.put("B", new Integer(66)); - encToName[66] = "B"; - - unicodeToName.put(new Character((char) 0x0043), "C"); - nameToUnicode.put("C", new Character((char) 0x0043)); - nameToEnc.put("C", new Integer(67)); - encToName[67] = "C"; - - unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); - nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); - nameToEnc.put("Ccedilla", new Integer(199)); - encToName[199] = "Ccedilla"; - - unicodeToName.put(new Character((char) 0x0044), "D"); - nameToUnicode.put("D", new Character((char) 0x0044)); - nameToEnc.put("D", new Integer(68)); - encToName[68] = "D"; - - unicodeToName.put(new Character((char) 0x0045), "E"); - nameToUnicode.put("E", new Character((char) 0x0045)); - nameToEnc.put("E", new Integer(69)); - encToName[69] = "E"; - - unicodeToName.put(new Character((char) 0x00c9), "Eacute"); - nameToUnicode.put("Eacute", new Character((char) 0x00c9)); - nameToEnc.put("Eacute", new Integer(201)); - encToName[201] = "Eacute"; - - unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); - nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); - nameToEnc.put("Ecircumflex", new Integer(202)); - encToName[202] = "Ecircumflex"; - - unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); - nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); - nameToEnc.put("Edieresis", new Integer(203)); - encToName[203] = "Edieresis"; - - unicodeToName.put(new Character((char) 0x00c8), "Egrave"); - nameToUnicode.put("Egrave", new Character((char) 0x00c8)); - nameToEnc.put("Egrave", new Integer(200)); - encToName[200] = "Egrave"; - - unicodeToName.put(new Character((char) 0x00d0), "Eth"); - nameToUnicode.put("Eth", new Character((char) 0x00d0)); - nameToEnc.put("Eth", new Integer(208)); - encToName[208] = "Eth"; - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - - unicodeToName.put(new Character((char) 0x0046), "F"); - nameToUnicode.put("F", new Character((char) 0x0046)); - nameToEnc.put("F", new Integer(70)); - encToName[70] = "F"; - - unicodeToName.put(new Character((char) 0x0047), "G"); - nameToUnicode.put("G", new Character((char) 0x0047)); - nameToEnc.put("G", new Integer(71)); - encToName[71] = "G"; - - unicodeToName.put(new Character((char) 0x0048), "H"); - nameToUnicode.put("H", new Character((char) 0x0048)); - nameToEnc.put("H", new Integer(72)); - encToName[72] = "H"; - - unicodeToName.put(new Character((char) 0x0049), "I"); - nameToUnicode.put("I", new Character((char) 0x0049)); - nameToEnc.put("I", new Integer(73)); - encToName[73] = "I"; - - unicodeToName.put(new Character((char) 0x00cd), "Iacute"); - nameToUnicode.put("Iacute", new Character((char) 0x00cd)); - nameToEnc.put("Iacute", new Integer(205)); - encToName[205] = "Iacute"; - - unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); - nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); - nameToEnc.put("Icircumflex", new Integer(206)); - encToName[206] = "Icircumflex"; - - unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); - nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); - nameToEnc.put("Idieresis", new Integer(207)); - encToName[207] = "Idieresis"; - - unicodeToName.put(new Character((char) 0x00cc), "Igrave"); - nameToUnicode.put("Igrave", new Character((char) 0x00cc)); - nameToEnc.put("Igrave", new Integer(204)); - encToName[204] = "Igrave"; - - unicodeToName.put(new Character((char) 0x004a), "J"); - nameToUnicode.put("J", new Character((char) 0x004a)); - nameToEnc.put("J", new Integer(74)); - encToName[74] = "J"; - - unicodeToName.put(new Character((char) 0x004b), "K"); - nameToUnicode.put("K", new Character((char) 0x004b)); - nameToEnc.put("K", new Integer(75)); - encToName[75] = "K"; - - unicodeToName.put(new Character((char) 0x004c), "L"); - nameToUnicode.put("L", new Character((char) 0x004c)); - nameToEnc.put("L", new Integer(76)); - encToName[76] = "L"; - - unicodeToName.put(new Character((char) 0x0141), "Lslash"); - nameToUnicode.put("Lslash", new Character((char) 0x0141)); - - unicodeToName.put(new Character((char) 0x004d), "M"); - nameToUnicode.put("M", new Character((char) 0x004d)); - nameToEnc.put("M", new Integer(77)); - encToName[77] = "M"; - - unicodeToName.put(new Character((char) 0x004e), "N"); - nameToUnicode.put("N", new Character((char) 0x004e)); - nameToEnc.put("N", new Integer(78)); - encToName[78] = "N"; - - unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); - nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); - nameToEnc.put("Ntilde", new Integer(209)); - encToName[209] = "Ntilde"; - - unicodeToName.put(new Character((char) 0x004f), "O"); - nameToUnicode.put("O", new Character((char) 0x004f)); - nameToEnc.put("O", new Integer(79)); - encToName[79] = "O"; - - unicodeToName.put(new Character((char) 0x0152), "OE"); - nameToUnicode.put("OE", new Character((char) 0x0152)); - - unicodeToName.put(new Character((char) 0x00d2), "Oacute"); - nameToUnicode.put("Oacute", new Character((char) 0x00d2)); - nameToEnc.put("Oacute", new Integer(211)); - encToName[211] = "Oacute"; - - unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); - nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); - nameToEnc.put("Ocircumflex", new Integer(212)); - encToName[212] = "Ocircumflex"; - - unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); - nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); - nameToEnc.put("Odieresis", new Integer(214)); - encToName[214] = "Odieresis"; - - unicodeToName.put(new Character((char) 0x00d3), "Ograve"); - nameToUnicode.put("Ograve", new Character((char) 0x00d3)); - nameToEnc.put("Ograve", new Integer(210)); - encToName[210] = "Ograve"; - - unicodeToName.put(new Character((char) 0x00d8), "Oslash"); - nameToUnicode.put("Oslash", new Character((char) 0x00d8)); - nameToEnc.put("Oslash", new Integer(216)); - encToName[216] = "Oslash"; - - unicodeToName.put(new Character((char) 0x00d5), "Otilde"); - nameToUnicode.put("Otilde", new Character((char) 0x00d5)); - nameToEnc.put("Otilde", new Integer(213)); - encToName[213] = "Otilde"; - - unicodeToName.put(new Character((char) 0x0050), "P"); - nameToUnicode.put("P", new Character((char) 0x0050)); - nameToEnc.put("P", new Integer(80)); - encToName[80] = "P"; - - unicodeToName.put(new Character((char) 0x0051), "Q"); - nameToUnicode.put("Q", new Character((char) 0x0051)); - nameToEnc.put("Q", new Integer(81)); - encToName[81] = "Q"; - - unicodeToName.put(new Character((char) 0x0052), "R"); - nameToUnicode.put("R", new Character((char) 0x0052)); - nameToEnc.put("R", new Integer(82)); - encToName[82] = "R"; - - unicodeToName.put(new Character((char) 0x0053), "S"); - nameToUnicode.put("S", new Character((char) 0x0053)); - nameToEnc.put("S", new Integer(83)); - encToName[83] = "S"; - - unicodeToName.put(new Character((char) 0x0160), "Scaron"); - nameToUnicode.put("Scaron", new Character((char) 0x0160)); - - unicodeToName.put(new Character((char) 0x0054), "T"); - nameToUnicode.put("T", new Character((char) 0x0054)); - nameToEnc.put("T", new Integer(84)); - encToName[84] = "T"; - - unicodeToName.put(new Character((char) 0x00de), "Thorn"); - nameToUnicode.put("Thorn", new Character((char) 0x00de)); - nameToEnc.put("Thorn", new Integer(222)); - encToName[222] = "Thorn"; - - unicodeToName.put(new Character((char) 0x0055), "U"); - nameToUnicode.put("U", new Character((char) 0x0055)); - nameToEnc.put("U", new Integer(85)); - encToName[85] = "U"; - - unicodeToName.put(new Character((char) 0x00da), "Uacute"); - nameToUnicode.put("Uacute", new Character((char) 0x00da)); - nameToEnc.put("Uacute", new Integer(218)); - encToName[218] = "Uacute"; - - unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); - nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); - nameToEnc.put("Ucircumflex", new Integer(219)); - encToName[219] = "Ucircumflex"; - - unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); - nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); - nameToEnc.put("Udieresis", new Integer(220)); - encToName[220] = "Udieresis"; - - unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); - nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); - nameToEnc.put("Ugrave", new Integer(217)); - encToName[217] = "Ugrave"; - - unicodeToName.put(new Character((char) 0x0056), "V"); - nameToUnicode.put("V", new Character((char) 0x0056)); - nameToEnc.put("V", new Integer(86)); - encToName[86] = "V"; - - unicodeToName.put(new Character((char) 0x0057), "W"); - nameToUnicode.put("W", new Character((char) 0x0057)); - nameToEnc.put("W", new Integer(87)); - encToName[87] = "W"; - - unicodeToName.put(new Character((char) 0x0058), "X"); - nameToUnicode.put("X", new Character((char) 0x0058)); - nameToEnc.put("X", new Integer(88)); - encToName[88] = "X"; - - unicodeToName.put(new Character((char) 0x0059), "Y"); - nameToUnicode.put("Y", new Character((char) 0x0059)); - nameToEnc.put("Y", new Integer(89)); - encToName[89] = "Y"; - - unicodeToName.put(new Character((char) 0x00dd), "Yacute"); - nameToUnicode.put("Yacute", new Character((char) 0x00dd)); - nameToEnc.put("Yacute", new Integer(221)); - encToName[221] = "Yacute"; - - unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); - nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); - - unicodeToName.put(new Character((char) 0x005a), "Z"); - nameToUnicode.put("Z", new Character((char) 0x005a)); - nameToEnc.put("Z", new Integer(90)); - encToName[90] = "Z"; - - unicodeToName.put(new Character((char) 0x017d), "Zcaron"); - nameToUnicode.put("Zcaron", new Character((char) 0x017d)); - - unicodeToName.put(new Character((char) 0x0061), "a"); - nameToUnicode.put("a", new Character((char) 0x0061)); - nameToEnc.put("a", new Integer(97)); - encToName[97] = "a"; - - unicodeToName.put(new Character((char) 0x00e1), "aacute"); - nameToUnicode.put("aacute", new Character((char) 0x00e1)); - nameToEnc.put("aacute", new Integer(225)); - encToName[225] = "aacute"; - - unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); - nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); - nameToEnc.put("acircumflex", new Integer(226)); - encToName[226] = "acircumflex"; - - unicodeToName.put(new Character((char) 0x00b4), "acute"); - nameToUnicode.put("acute", new Character((char) 0x00b4)); - nameToEnc.put("acute", new Integer(180)); - encToName[180] = "acute"; - - unicodeToName.put(new Character((char) 0x00e4), "adieresis"); - nameToUnicode.put("adieresis", new Character((char) 0x00e4)); - nameToEnc.put("adieresis", new Integer(228)); - encToName[228] = "adieresis"; - - unicodeToName.put(new Character((char) 0x00e6), "ae"); - nameToUnicode.put("ae", new Character((char) 0x00e6)); - nameToEnc.put("ae", new Integer(230)); - encToName[230] = "ae"; - - unicodeToName.put(new Character((char) 0x00e0), "agrave"); - nameToUnicode.put("agrave", new Character((char) 0x00e0)); - nameToEnc.put("agrave", new Integer(224)); - encToName[224] = "agrave"; - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x00e5), "aring"); - nameToUnicode.put("aring", new Character((char) 0x00e5)); - nameToEnc.put("aring", new Integer(229)); - encToName[229] = "aring"; - - unicodeToName.put(new Character((char) 0x005e), "asciicircum"); - nameToUnicode.put("asciicircum", new Character((char) 0x005e)); - nameToEnc.put("asciicircum", new Integer(94)); - encToName[94] = "asciicircum"; - - unicodeToName.put(new Character((char) 0x007e), "asciitilde"); - nameToUnicode.put("asciitilde", new Character((char) 0x007e)); - nameToEnc.put("asciitilde", new Integer(126)); - encToName[126] = "asciitilde"; - - unicodeToName.put(new Character((char) 0x002a), "asterisk"); - nameToUnicode.put("asterisk", new Character((char) 0x002a)); - nameToEnc.put("asterisk", new Integer(42)); - encToName[42] = "asterisk"; - - unicodeToName.put(new Character((char) 0x0040), "at"); - nameToUnicode.put("at", new Character((char) 0x0040)); - nameToEnc.put("at", new Integer(64)); - encToName[64] = "at"; - - unicodeToName.put(new Character((char) 0x00e3), "atilde"); - nameToUnicode.put("atilde", new Character((char) 0x00e3)); - nameToEnc.put("atilde", new Integer(227)); - encToName[227] = "atilde"; - - unicodeToName.put(new Character((char) 0x0062), "b"); - nameToUnicode.put("b", new Character((char) 0x0062)); - nameToEnc.put("b", new Integer(98)); - encToName[98] = "b"; - - unicodeToName.put(new Character((char) 0x005c), "backslash"); - nameToUnicode.put("backslash", new Character((char) 0x005c)); - nameToEnc.put("backslash", new Integer(92)); - encToName[92] = "backslash"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0x02d8), "breve"); - nameToUnicode.put("breve", new Character((char) 0x02d8)); - nameToEnc.put("breve", new Integer(150)); - encToName[150] = "breve"; - - unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); - nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); - nameToEnc.put("brokenbar", new Integer(166)); - encToName[166] = "brokenbar"; - - unicodeToName.put(new Character((char) 0x2022), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2022)); - - unicodeToName.put(new Character((char) 0x0063), "c"); - nameToUnicode.put("c", new Character((char) 0x0063)); - nameToEnc.put("c", new Integer(99)); - encToName[99] = "c"; - - unicodeToName.put(new Character((char) 0x02c7), "caron"); - nameToUnicode.put("caron", new Character((char) 0x02c7)); - nameToEnc.put("caron", new Integer(159)); - encToName[159] = "caron"; - - unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); - nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); - nameToEnc.put("ccedilla", new Integer(231)); - encToName[231] = "ccedilla"; - - unicodeToName.put(new Character((char) 0x00b8), "cedilla"); - nameToUnicode.put("cedilla", new Character((char) 0x00b8)); - nameToEnc.put("cedilla", new Integer(184)); - encToName[184] = "cedilla"; - - unicodeToName.put(new Character((char) 0x00a2), "cent"); - nameToUnicode.put("cent", new Character((char) 0x00a2)); - nameToEnc.put("cent", new Integer(162)); - encToName[162] = "cent"; - - unicodeToName.put(new Character((char) 0x02c6), "circumflex"); - nameToUnicode.put("circumflex", new Character((char) 0x02c6)); - nameToEnc.put("circumflex", new Integer(147)); - encToName[147] = "circumflex"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x00a9), "copyright"); - nameToUnicode.put("copyright", new Character((char) 0x00a9)); - nameToEnc.put("copyright", new Integer(169)); - encToName[169] = "copyright"; - - unicodeToName.put(new Character((char) 0x00a4), "currency"); - nameToUnicode.put("currency", new Character((char) 0x00a4)); - nameToEnc.put("currency", new Integer(164)); - encToName[164] = "currency"; - - unicodeToName.put(new Character((char) 0x0064), "d"); - nameToUnicode.put("d", new Character((char) 0x0064)); - nameToEnc.put("d", new Integer(100)); - encToName[100] = "d"; - - unicodeToName.put(new Character((char) 0x2020), "dagger"); - nameToUnicode.put("dagger", new Character((char) 0x2020)); - - unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); - nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - nameToEnc.put("degree", new Integer(176)); - encToName[176] = "degree"; - - unicodeToName.put(new Character((char) 0x00a8), "dieresis"); - nameToUnicode.put("dieresis", new Character((char) 0x00a8)); - nameToEnc.put("dieresis", new Integer(168)); - encToName[168] = "dieresis"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - nameToEnc.put("divide", new Integer(183)); - encToName[183] = "divide"; - - unicodeToName.put(new Character((char) 0x0024), "dollar"); - nameToUnicode.put("dollar", new Character((char) 0x0024)); - nameToEnc.put("dollar", new Integer(36)); - encToName[36] = "dollar"; - - unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); - nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); - nameToEnc.put("dotaccent", new Integer(151)); - encToName[151] = "dotaccent"; - - unicodeToName.put(new Character((char) 0x0131), "dotlessi"); - nameToUnicode.put("dotlessi", new Character((char) 0x0131)); - nameToEnc.put("dotlessi", new Integer(144)); - encToName[144] = "dotlessi"; - - unicodeToName.put(new Character((char) 0x0065), "e"); - nameToUnicode.put("e", new Character((char) 0x0065)); - nameToEnc.put("e", new Integer(101)); - encToName[101] = "e"; - - unicodeToName.put(new Character((char) 0x00e9), "eacute"); - nameToUnicode.put("eacute", new Character((char) 0x00e9)); - nameToEnc.put("eacute", new Integer(233)); - encToName[233] = "eacute"; - - unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); - nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); - nameToEnc.put("ecircumflex", new Integer(234)); - encToName[234] = "ecircumflex"; - - unicodeToName.put(new Character((char) 0x00eb), "edieresis"); - nameToUnicode.put("edieresis", new Character((char) 0x00eb)); - nameToEnc.put("edieresis", new Integer(235)); - encToName[235] = "edieresis"; - - unicodeToName.put(new Character((char) 0x00e8), "egrave"); - nameToUnicode.put("egrave", new Character((char) 0x00e8)); - nameToEnc.put("egrave", new Integer(232)); - encToName[232] = "egrave"; - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - - unicodeToName.put(new Character((char) 0x002d), "emdash"); - nameToUnicode.put("emdash", new Character((char) 0x002d)); - - unicodeToName.put(new Character((char) 0x002d), "endash"); - nameToUnicode.put("endash", new Character((char) 0x002d)); - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x00f0), "eth"); - nameToUnicode.put("eth", new Character((char) 0x00f0)); - nameToEnc.put("eth", new Integer(240)); - encToName[240] = "eth"; - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); - nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); - nameToEnc.put("exclamdown", new Integer(161)); - encToName[161] = "exclamdown"; - - unicodeToName.put(new Character((char) 0x0066), "f"); - nameToUnicode.put("f", new Character((char) 0x0066)); - nameToEnc.put("f", new Integer(102)); - encToName[102] = "f"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - - unicodeToName.put(new Character((char) 0x0067), "g"); - nameToUnicode.put("g", new Character((char) 0x0067)); - nameToEnc.put("g", new Integer(103)); - encToName[103] = "g"; - - unicodeToName.put(new Character((char) 0x00df), "germandbls"); - nameToUnicode.put("germandbls", new Character((char) 0x00df)); - nameToEnc.put("germandbls", new Integer(223)); - encToName[223] = "germandbls"; - - unicodeToName.put(new Character((char) 0x0060), "grave"); - nameToUnicode.put("grave", new Character((char) 0x0060)); - nameToEnc.put("grave", new Integer(145)); - encToName[145] = "grave"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); - nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); - nameToEnc.put("guillemotleft", new Integer(171)); - encToName[171] = "guillemotleft"; - - unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); - nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); - nameToEnc.put("guillemotright", new Integer(187)); - encToName[187] = "guillemotright"; - - unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); - nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); - - unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); - nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); - - unicodeToName.put(new Character((char) 0x0068), "h"); - nameToUnicode.put("h", new Character((char) 0x0068)); - nameToEnc.put("h", new Integer(104)); - encToName[104] = "h"; - - unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); - nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); - nameToEnc.put("hungarumlaut", new Integer(157)); - encToName[157] = "hungarumlaut"; - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(173)); - encToName[173] = "hyphen"; - - unicodeToName.put(new Character((char) 0x0069), "i"); - nameToUnicode.put("i", new Character((char) 0x0069)); - nameToEnc.put("i", new Integer(105)); - encToName[105] = "i"; - - unicodeToName.put(new Character((char) 0x00ed), "iacute"); - nameToUnicode.put("iacute", new Character((char) 0x00ed)); - nameToEnc.put("iacute", new Integer(237)); - encToName[237] = "iacute"; - - unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); - nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); - nameToEnc.put("icircumflex", new Integer(238)); - encToName[238] = "icircumflex"; - - unicodeToName.put(new Character((char) 0x00ef), "idieresis"); - nameToUnicode.put("idieresis", new Character((char) 0x00ef)); - nameToEnc.put("idieresis", new Integer(239)); - encToName[239] = "idieresis"; - - unicodeToName.put(new Character((char) 0x00ec), "igrave"); - nameToUnicode.put("igrave", new Character((char) 0x00ec)); - nameToEnc.put("igrave", new Integer(236)); - encToName[236] = "igrave"; - - unicodeToName.put(new Character((char) 0x006a), "j"); - nameToUnicode.put("j", new Character((char) 0x006a)); - nameToEnc.put("j", new Integer(106)); - encToName[106] = "j"; - - unicodeToName.put(new Character((char) 0x006b), "k"); - nameToUnicode.put("k", new Character((char) 0x006b)); - nameToEnc.put("k", new Integer(107)); - encToName[107] = "k"; - - unicodeToName.put(new Character((char) 0x006c), "l"); - nameToUnicode.put("l", new Character((char) 0x006c)); - nameToEnc.put("l", new Integer(108)); - encToName[108] = "l"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - nameToEnc.put("logicalnot", new Integer(172)); - encToName[172] = "logicalnot"; - - unicodeToName.put(new Character((char) 0x0142), "lslash"); - nameToUnicode.put("lslash", new Character((char) 0x0142)); - - unicodeToName.put(new Character((char) 0x006d), "m"); - nameToUnicode.put("m", new Character((char) 0x006d)); - nameToEnc.put("m", new Integer(109)); - encToName[109] = "m"; - - unicodeToName.put(new Character((char) 0x00af), "macron"); - nameToUnicode.put("macron", new Character((char) 0x00af)); - nameToEnc.put("macron", new Integer(175)); - encToName[175] = "macron"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - nameToEnc.put("minus", new Integer(45)); - encToName[45] = "minus"; - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - nameToEnc.put("mu", new Integer(181)); - encToName[181] = "mu"; - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - nameToEnc.put("multiply", new Integer(215)); - encToName[215] = "multiply"; - - unicodeToName.put(new Character((char) 0x006e), "n"); - nameToUnicode.put("n", new Character((char) 0x006e)); - nameToEnc.put("n", new Integer(110)); - encToName[110] = "n"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x00f1), "ntilde"); - nameToUnicode.put("ntilde", new Character((char) 0x00f1)); - nameToEnc.put("ntilde", new Integer(241)); - encToName[241] = "ntilde"; - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x006f), "o"); - nameToUnicode.put("o", new Character((char) 0x006f)); - nameToEnc.put("o", new Integer(111)); - encToName[111] = "o"; - - unicodeToName.put(new Character((char) 0x00f3), "oacute"); - nameToUnicode.put("oacute", new Character((char) 0x00f3)); - nameToEnc.put("oacute", new Integer(243)); - encToName[243] = "oacute"; - - unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); - nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); - nameToEnc.put("ocircumflex", new Integer(244)); - encToName[244] = "ocircumflex"; - - unicodeToName.put(new Character((char) 0x00f6), "odieresis"); - nameToUnicode.put("odieresis", new Character((char) 0x00f6)); - nameToEnc.put("odieresis", new Integer(246)); - encToName[246] = "odieresis"; - - unicodeToName.put(new Character((char) 0x0153), "oe"); - nameToUnicode.put("oe", new Character((char) 0x0153)); - - unicodeToName.put(new Character((char) 0x02db), "ogonek"); - nameToUnicode.put("ogonek", new Character((char) 0x02db)); - nameToEnc.put("ogonek", new Integer(158)); - encToName[158] = "ogonek"; - - unicodeToName.put(new Character((char) 0x00f2), "ograve"); - nameToUnicode.put("ograve", new Character((char) 0x00f2)); - nameToEnc.put("ograve", new Integer(242)); - encToName[242] = "ograve"; - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - nameToEnc.put("onehalf", new Integer(189)); - encToName[189] = "onehalf"; - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - nameToEnc.put("onequarter", new Integer(188)); - encToName[188] = "onequarter"; - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - nameToEnc.put("onesuperior", new Integer(185)); - encToName[185] = "onesuperior"; - - unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); - nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); - nameToEnc.put("ordfeminine", new Integer(170)); - encToName[170] = "ordfeminine"; - - unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); - nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); - nameToEnc.put("ordmasculine", new Integer(186)); - encToName[186] = "ordmasculine"; - - unicodeToName.put(new Character((char) 0x00f8), "oslash"); - nameToUnicode.put("oslash", new Character((char) 0x00f8)); - nameToEnc.put("oslash", new Integer(248)); - encToName[248] = "oslash"; - - unicodeToName.put(new Character((char) 0x00f5), "otilde"); - nameToUnicode.put("otilde", new Character((char) 0x00f5)); - nameToEnc.put("otilde", new Integer(245)); - encToName[245] = "otilde"; - - unicodeToName.put(new Character((char) 0x0070), "p"); - nameToUnicode.put("p", new Character((char) 0x0070)); - nameToEnc.put("p", new Integer(112)); - encToName[112] = "p"; - - unicodeToName.put(new Character((char) 0x00b6), "paragraph"); - nameToUnicode.put("paragraph", new Character((char) 0x00b6)); - nameToEnc.put("paragraph", new Integer(182)); - encToName[182] = "paragraph"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); - nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); - nameToEnc.put("periodcentered", new Integer(183)); - encToName[183] = "periodcentered"; - - unicodeToName.put(new Character((char) 0x2030), "perthousand"); - nameToUnicode.put("perthousand", new Character((char) 0x2030)); - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - nameToEnc.put("plusminus", new Integer(177)); - encToName[177] = "plusminus"; - - unicodeToName.put(new Character((char) 0x0071), "q"); - nameToUnicode.put("q", new Character((char) 0x0071)); - nameToEnc.put("q", new Integer(113)); - encToName[113] = "q"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x00bf), "questiondown"); - nameToUnicode.put("questiondown", new Character((char) 0x00bf)); - nameToEnc.put("questiondown", new Integer(191)); - encToName[191] = "questiondown"; - - unicodeToName.put(new Character((char) 0x0022), "quotedbl"); - nameToUnicode.put("quotedbl", new Character((char) 0x0022)); - nameToEnc.put("quotedbl", new Integer(34)); - encToName[34] = "quotedbl"; - - unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); - nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); - - unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); - nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); - - unicodeToName.put(new Character((char) 0x201d), "quotedblright"); - nameToUnicode.put("quotedblright", new Character((char) 0x201d)); - - unicodeToName.put(new Character((char) 0x0060), "quoteleft"); - nameToUnicode.put("quoteleft", new Character((char) 0x0060)); - nameToEnc.put("quoteleft", new Integer(96)); - encToName[96] = "quoteleft"; - - unicodeToName.put(new Character((char) 0x0027), "quoteright"); - nameToUnicode.put("quoteright", new Character((char) 0x0027)); - nameToEnc.put("quoteright", new Integer(39)); - encToName[39] = "quoteright"; - - unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); - nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); - - unicodeToName.put(new Character((char) 0x0027), "quotesingle"); - nameToUnicode.put("quotesingle", new Character((char) 0x0027)); - - unicodeToName.put(new Character((char) 0x0072), "r"); - nameToUnicode.put("r", new Character((char) 0x0072)); - nameToEnc.put("r", new Integer(114)); - encToName[114] = "r"; - - unicodeToName.put(new Character((char) 0x00ae), "registered"); - nameToUnicode.put("registered", new Character((char) 0x00ae)); - nameToEnc.put("registered", new Integer(174)); - encToName[174] = "registered"; - - unicodeToName.put(new Character((char) 0x02da), "ring"); - nameToUnicode.put("ring", new Character((char) 0x02da)); - nameToEnc.put("ring", new Integer(154)); - encToName[154] = "ring"; - - unicodeToName.put(new Character((char) 0x0073), "s"); - nameToUnicode.put("s", new Character((char) 0x0073)); - nameToEnc.put("s", new Integer(115)); - encToName[115] = "s"; - - unicodeToName.put(new Character((char) 0x0161), "scaron"); - nameToUnicode.put("scaron", new Character((char) 0x0161)); - - unicodeToName.put(new Character((char) 0x00a7), "section"); - nameToUnicode.put("section", new Character((char) 0x00a7)); - nameToEnc.put("section", new Integer(167)); - encToName[167] = "section"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x00a3), "sterling"); - nameToUnicode.put("sterling", new Character((char) 0x00a3)); - nameToEnc.put("sterling", new Integer(163)); - encToName[163] = "sterling"; - - unicodeToName.put(new Character((char) 0x0074), "t"); - nameToUnicode.put("t", new Character((char) 0x0074)); - nameToEnc.put("t", new Integer(116)); - encToName[116] = "t"; - - unicodeToName.put(new Character((char) 0x00fe), "thorn"); - nameToUnicode.put("thorn", new Character((char) 0x00fe)); - nameToEnc.put("thorn", new Integer(254)); - encToName[254] = "thorn"; - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - nameToEnc.put("threequarters", new Integer(190)); - encToName[190] = "threequarters"; - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - nameToEnc.put("threesuperior", new Integer(179)); - encToName[179] = "threesuperior"; - - unicodeToName.put(new Character((char) 0x02dc), "tilde"); - nameToUnicode.put("tilde", new Character((char) 0x02dc)); - nameToEnc.put("tilde", new Integer(148)); - encToName[148] = "tilde"; - - unicodeToName.put(new Character((char) 0x2122), "trademark"); - nameToUnicode.put("trademark", new Character((char) 0x2122)); - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - nameToEnc.put("twosuperior", new Integer(178)); - encToName[178] = "twosuperior"; - - unicodeToName.put(new Character((char) 0x0075), "u"); - nameToUnicode.put("u", new Character((char) 0x0075)); - nameToEnc.put("u", new Integer(117)); - encToName[117] = "u"; - - unicodeToName.put(new Character((char) 0x00fa), "uacute"); - nameToUnicode.put("uacute", new Character((char) 0x00fa)); - nameToEnc.put("uacute", new Integer(250)); - encToName[250] = "uacute"; - - unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); - nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); - nameToEnc.put("ucircumflex", new Integer(251)); - encToName[251] = "ucircumflex"; - - unicodeToName.put(new Character((char) 0x00fc), "udieresis"); - nameToUnicode.put("udieresis", new Character((char) 0x00fc)); - nameToEnc.put("udieresis", new Integer(252)); - encToName[252] = "udieresis"; - - unicodeToName.put(new Character((char) 0x00f9), "ugrave"); - nameToUnicode.put("ugrave", new Character((char) 0x00f9)); - nameToEnc.put("ugrave", new Integer(249)); - encToName[249] = "ugrave"; - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x0076), "v"); - nameToUnicode.put("v", new Character((char) 0x0076)); - nameToEnc.put("v", new Integer(118)); - encToName[118] = "v"; - - unicodeToName.put(new Character((char) 0x0077), "w"); - nameToUnicode.put("w", new Character((char) 0x0077)); - nameToEnc.put("w", new Integer(119)); - encToName[119] = "w"; - - unicodeToName.put(new Character((char) 0x0078), "x"); - nameToUnicode.put("x", new Character((char) 0x0078)); - nameToEnc.put("x", new Integer(120)); - encToName[120] = "x"; - - unicodeToName.put(new Character((char) 0x0079), "y"); - nameToUnicode.put("y", new Character((char) 0x0079)); - nameToEnc.put("y", new Integer(121)); - encToName[121] = "y"; - - unicodeToName.put(new Character((char) 0x00fd), "yacute"); - nameToUnicode.put("yacute", new Character((char) 0x00fd)); - nameToEnc.put("yacute", new Integer(253)); - encToName[253] = "yacute"; - - unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); - nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); - nameToEnc.put("ydieresis", new Integer(255)); - encToName[255] = "ydieresis"; - - unicodeToName.put(new Character((char) 0x00a5), "yen"); - nameToUnicode.put("yen", new Character((char) 0x00a5)); - nameToEnc.put("yen", new Integer(165)); - encToName[165] = "yen"; - - unicodeToName.put(new Character((char) 0x007a), "z"); - nameToUnicode.put("z", new Character((char) 0x007a)); - nameToEnc.put("z", new Integer(122)); - encToName[122] = "z"; - - unicodeToName.put(new Character((char) 0x017e), "zcaron"); - nameToUnicode.put("zcaron", new Character((char) 0x017e)); - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Latin");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("ISO");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated ISOLatin Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class ISOLatin extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public ISOLatin() { + unicodeToName.put(new Character((char) 0x0041), "A"); + nameToUnicode.put("A", new Character((char) 0x0041)); + nameToEnc.put("A", new Integer(65)); + encToName[65] = "A"; + + unicodeToName.put(new Character((char) 0x00c6), "AE"); + nameToUnicode.put("AE", new Character((char) 0x00c6)); + nameToEnc.put("AE", new Integer(225)); + encToName[225] = "AE"; + + unicodeToName.put(new Character((char) 0x00c1), "Aacute"); + nameToUnicode.put("Aacute", new Character((char) 0x00c1)); + nameToEnc.put("Aacute", new Integer(193)); + encToName[193] = "Aacute"; + + unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); + nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); + nameToEnc.put("Acircumflex", new Integer(194)); + encToName[194] = "Acircumflex"; + + unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); + nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); + nameToEnc.put("Adieresis", new Integer(196)); + encToName[196] = "Adieresis"; + + unicodeToName.put(new Character((char) 0x00c0), "Agrave"); + nameToUnicode.put("Agrave", new Character((char) 0x00c0)); + nameToEnc.put("Agrave", new Integer(192)); + encToName[192] = "Agrave"; + + unicodeToName.put(new Character((char) 0x00c5), "Aring"); + nameToUnicode.put("Aring", new Character((char) 0x00c5)); + nameToEnc.put("Aring", new Integer(197)); + encToName[197] = "Aring"; + + unicodeToName.put(new Character((char) 0x00c3), "Atilde"); + nameToUnicode.put("Atilde", new Character((char) 0x00c3)); + nameToEnc.put("Atilde", new Integer(195)); + encToName[195] = "Atilde"; + + unicodeToName.put(new Character((char) 0x0042), "B"); + nameToUnicode.put("B", new Character((char) 0x0042)); + nameToEnc.put("B", new Integer(66)); + encToName[66] = "B"; + + unicodeToName.put(new Character((char) 0x0043), "C"); + nameToUnicode.put("C", new Character((char) 0x0043)); + nameToEnc.put("C", new Integer(67)); + encToName[67] = "C"; + + unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); + nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); + nameToEnc.put("Ccedilla", new Integer(199)); + encToName[199] = "Ccedilla"; + + unicodeToName.put(new Character((char) 0x0044), "D"); + nameToUnicode.put("D", new Character((char) 0x0044)); + nameToEnc.put("D", new Integer(68)); + encToName[68] = "D"; + + unicodeToName.put(new Character((char) 0x0045), "E"); + nameToUnicode.put("E", new Character((char) 0x0045)); + nameToEnc.put("E", new Integer(69)); + encToName[69] = "E"; + + unicodeToName.put(new Character((char) 0x00c9), "Eacute"); + nameToUnicode.put("Eacute", new Character((char) 0x00c9)); + nameToEnc.put("Eacute", new Integer(201)); + encToName[201] = "Eacute"; + + unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); + nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); + nameToEnc.put("Ecircumflex", new Integer(202)); + encToName[202] = "Ecircumflex"; + + unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); + nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); + nameToEnc.put("Edieresis", new Integer(203)); + encToName[203] = "Edieresis"; + + unicodeToName.put(new Character((char) 0x00c8), "Egrave"); + nameToUnicode.put("Egrave", new Character((char) 0x00c8)); + nameToEnc.put("Egrave", new Integer(200)); + encToName[200] = "Egrave"; + + unicodeToName.put(new Character((char) 0x00d0), "Eth"); + nameToUnicode.put("Eth", new Character((char) 0x00d0)); + nameToEnc.put("Eth", new Integer(208)); + encToName[208] = "Eth"; + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + + unicodeToName.put(new Character((char) 0x0046), "F"); + nameToUnicode.put("F", new Character((char) 0x0046)); + nameToEnc.put("F", new Integer(70)); + encToName[70] = "F"; + + unicodeToName.put(new Character((char) 0x0047), "G"); + nameToUnicode.put("G", new Character((char) 0x0047)); + nameToEnc.put("G", new Integer(71)); + encToName[71] = "G"; + + unicodeToName.put(new Character((char) 0x0048), "H"); + nameToUnicode.put("H", new Character((char) 0x0048)); + nameToEnc.put("H", new Integer(72)); + encToName[72] = "H"; + + unicodeToName.put(new Character((char) 0x0049), "I"); + nameToUnicode.put("I", new Character((char) 0x0049)); + nameToEnc.put("I", new Integer(73)); + encToName[73] = "I"; + + unicodeToName.put(new Character((char) 0x00cd), "Iacute"); + nameToUnicode.put("Iacute", new Character((char) 0x00cd)); + nameToEnc.put("Iacute", new Integer(205)); + encToName[205] = "Iacute"; + + unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); + nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); + nameToEnc.put("Icircumflex", new Integer(206)); + encToName[206] = "Icircumflex"; + + unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); + nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); + nameToEnc.put("Idieresis", new Integer(207)); + encToName[207] = "Idieresis"; + + unicodeToName.put(new Character((char) 0x00cc), "Igrave"); + nameToUnicode.put("Igrave", new Character((char) 0x00cc)); + nameToEnc.put("Igrave", new Integer(204)); + encToName[204] = "Igrave"; + + unicodeToName.put(new Character((char) 0x004a), "J"); + nameToUnicode.put("J", new Character((char) 0x004a)); + nameToEnc.put("J", new Integer(74)); + encToName[74] = "J"; + + unicodeToName.put(new Character((char) 0x004b), "K"); + nameToUnicode.put("K", new Character((char) 0x004b)); + nameToEnc.put("K", new Integer(75)); + encToName[75] = "K"; + + unicodeToName.put(new Character((char) 0x004c), "L"); + nameToUnicode.put("L", new Character((char) 0x004c)); + nameToEnc.put("L", new Integer(76)); + encToName[76] = "L"; + + unicodeToName.put(new Character((char) 0x0141), "Lslash"); + nameToUnicode.put("Lslash", new Character((char) 0x0141)); + + unicodeToName.put(new Character((char) 0x004d), "M"); + nameToUnicode.put("M", new Character((char) 0x004d)); + nameToEnc.put("M", new Integer(77)); + encToName[77] = "M"; + + unicodeToName.put(new Character((char) 0x004e), "N"); + nameToUnicode.put("N", new Character((char) 0x004e)); + nameToEnc.put("N", new Integer(78)); + encToName[78] = "N"; + + unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); + nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); + nameToEnc.put("Ntilde", new Integer(209)); + encToName[209] = "Ntilde"; + + unicodeToName.put(new Character((char) 0x004f), "O"); + nameToUnicode.put("O", new Character((char) 0x004f)); + nameToEnc.put("O", new Integer(79)); + encToName[79] = "O"; + + unicodeToName.put(new Character((char) 0x0152), "OE"); + nameToUnicode.put("OE", new Character((char) 0x0152)); + + unicodeToName.put(new Character((char) 0x00d2), "Oacute"); + nameToUnicode.put("Oacute", new Character((char) 0x00d2)); + nameToEnc.put("Oacute", new Integer(211)); + encToName[211] = "Oacute"; + + unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); + nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); + nameToEnc.put("Ocircumflex", new Integer(212)); + encToName[212] = "Ocircumflex"; + + unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); + nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); + nameToEnc.put("Odieresis", new Integer(214)); + encToName[214] = "Odieresis"; + + unicodeToName.put(new Character((char) 0x00d3), "Ograve"); + nameToUnicode.put("Ograve", new Character((char) 0x00d3)); + nameToEnc.put("Ograve", new Integer(210)); + encToName[210] = "Ograve"; + + unicodeToName.put(new Character((char) 0x00d8), "Oslash"); + nameToUnicode.put("Oslash", new Character((char) 0x00d8)); + nameToEnc.put("Oslash", new Integer(216)); + encToName[216] = "Oslash"; + + unicodeToName.put(new Character((char) 0x00d5), "Otilde"); + nameToUnicode.put("Otilde", new Character((char) 0x00d5)); + nameToEnc.put("Otilde", new Integer(213)); + encToName[213] = "Otilde"; + + unicodeToName.put(new Character((char) 0x0050), "P"); + nameToUnicode.put("P", new Character((char) 0x0050)); + nameToEnc.put("P", new Integer(80)); + encToName[80] = "P"; + + unicodeToName.put(new Character((char) 0x0051), "Q"); + nameToUnicode.put("Q", new Character((char) 0x0051)); + nameToEnc.put("Q", new Integer(81)); + encToName[81] = "Q"; + + unicodeToName.put(new Character((char) 0x0052), "R"); + nameToUnicode.put("R", new Character((char) 0x0052)); + nameToEnc.put("R", new Integer(82)); + encToName[82] = "R"; + + unicodeToName.put(new Character((char) 0x0053), "S"); + nameToUnicode.put("S", new Character((char) 0x0053)); + nameToEnc.put("S", new Integer(83)); + encToName[83] = "S"; + + unicodeToName.put(new Character((char) 0x0160), "Scaron"); + nameToUnicode.put("Scaron", new Character((char) 0x0160)); + + unicodeToName.put(new Character((char) 0x0054), "T"); + nameToUnicode.put("T", new Character((char) 0x0054)); + nameToEnc.put("T", new Integer(84)); + encToName[84] = "T"; + + unicodeToName.put(new Character((char) 0x00de), "Thorn"); + nameToUnicode.put("Thorn", new Character((char) 0x00de)); + nameToEnc.put("Thorn", new Integer(222)); + encToName[222] = "Thorn"; + + unicodeToName.put(new Character((char) 0x0055), "U"); + nameToUnicode.put("U", new Character((char) 0x0055)); + nameToEnc.put("U", new Integer(85)); + encToName[85] = "U"; + + unicodeToName.put(new Character((char) 0x00da), "Uacute"); + nameToUnicode.put("Uacute", new Character((char) 0x00da)); + nameToEnc.put("Uacute", new Integer(218)); + encToName[218] = "Uacute"; + + unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); + nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); + nameToEnc.put("Ucircumflex", new Integer(219)); + encToName[219] = "Ucircumflex"; + + unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); + nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); + nameToEnc.put("Udieresis", new Integer(220)); + encToName[220] = "Udieresis"; + + unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); + nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); + nameToEnc.put("Ugrave", new Integer(217)); + encToName[217] = "Ugrave"; + + unicodeToName.put(new Character((char) 0x0056), "V"); + nameToUnicode.put("V", new Character((char) 0x0056)); + nameToEnc.put("V", new Integer(86)); + encToName[86] = "V"; + + unicodeToName.put(new Character((char) 0x0057), "W"); + nameToUnicode.put("W", new Character((char) 0x0057)); + nameToEnc.put("W", new Integer(87)); + encToName[87] = "W"; + + unicodeToName.put(new Character((char) 0x0058), "X"); + nameToUnicode.put("X", new Character((char) 0x0058)); + nameToEnc.put("X", new Integer(88)); + encToName[88] = "X"; + + unicodeToName.put(new Character((char) 0x0059), "Y"); + nameToUnicode.put("Y", new Character((char) 0x0059)); + nameToEnc.put("Y", new Integer(89)); + encToName[89] = "Y"; + + unicodeToName.put(new Character((char) 0x00dd), "Yacute"); + nameToUnicode.put("Yacute", new Character((char) 0x00dd)); + nameToEnc.put("Yacute", new Integer(221)); + encToName[221] = "Yacute"; + + unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); + nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); + + unicodeToName.put(new Character((char) 0x005a), "Z"); + nameToUnicode.put("Z", new Character((char) 0x005a)); + nameToEnc.put("Z", new Integer(90)); + encToName[90] = "Z"; + + unicodeToName.put(new Character((char) 0x017d), "Zcaron"); + nameToUnicode.put("Zcaron", new Character((char) 0x017d)); + + unicodeToName.put(new Character((char) 0x0061), "a"); + nameToUnicode.put("a", new Character((char) 0x0061)); + nameToEnc.put("a", new Integer(97)); + encToName[97] = "a"; + + unicodeToName.put(new Character((char) 0x00e1), "aacute"); + nameToUnicode.put("aacute", new Character((char) 0x00e1)); + nameToEnc.put("aacute", new Integer(225)); + encToName[225] = "aacute"; + + unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); + nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); + nameToEnc.put("acircumflex", new Integer(226)); + encToName[226] = "acircumflex"; + + unicodeToName.put(new Character((char) 0x00b4), "acute"); + nameToUnicode.put("acute", new Character((char) 0x00b4)); + nameToEnc.put("acute", new Integer(180)); + encToName[180] = "acute"; + + unicodeToName.put(new Character((char) 0x00e4), "adieresis"); + nameToUnicode.put("adieresis", new Character((char) 0x00e4)); + nameToEnc.put("adieresis", new Integer(228)); + encToName[228] = "adieresis"; + + unicodeToName.put(new Character((char) 0x00e6), "ae"); + nameToUnicode.put("ae", new Character((char) 0x00e6)); + nameToEnc.put("ae", new Integer(230)); + encToName[230] = "ae"; + + unicodeToName.put(new Character((char) 0x00e0), "agrave"); + nameToUnicode.put("agrave", new Character((char) 0x00e0)); + nameToEnc.put("agrave", new Integer(224)); + encToName[224] = "agrave"; + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x00e5), "aring"); + nameToUnicode.put("aring", new Character((char) 0x00e5)); + nameToEnc.put("aring", new Integer(229)); + encToName[229] = "aring"; + + unicodeToName.put(new Character((char) 0x005e), "asciicircum"); + nameToUnicode.put("asciicircum", new Character((char) 0x005e)); + nameToEnc.put("asciicircum", new Integer(94)); + encToName[94] = "asciicircum"; + + unicodeToName.put(new Character((char) 0x007e), "asciitilde"); + nameToUnicode.put("asciitilde", new Character((char) 0x007e)); + nameToEnc.put("asciitilde", new Integer(126)); + encToName[126] = "asciitilde"; + + unicodeToName.put(new Character((char) 0x002a), "asterisk"); + nameToUnicode.put("asterisk", new Character((char) 0x002a)); + nameToEnc.put("asterisk", new Integer(42)); + encToName[42] = "asterisk"; + + unicodeToName.put(new Character((char) 0x0040), "at"); + nameToUnicode.put("at", new Character((char) 0x0040)); + nameToEnc.put("at", new Integer(64)); + encToName[64] = "at"; + + unicodeToName.put(new Character((char) 0x00e3), "atilde"); + nameToUnicode.put("atilde", new Character((char) 0x00e3)); + nameToEnc.put("atilde", new Integer(227)); + encToName[227] = "atilde"; + + unicodeToName.put(new Character((char) 0x0062), "b"); + nameToUnicode.put("b", new Character((char) 0x0062)); + nameToEnc.put("b", new Integer(98)); + encToName[98] = "b"; + + unicodeToName.put(new Character((char) 0x005c), "backslash"); + nameToUnicode.put("backslash", new Character((char) 0x005c)); + nameToEnc.put("backslash", new Integer(92)); + encToName[92] = "backslash"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0x02d8), "breve"); + nameToUnicode.put("breve", new Character((char) 0x02d8)); + nameToEnc.put("breve", new Integer(150)); + encToName[150] = "breve"; + + unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); + nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); + nameToEnc.put("brokenbar", new Integer(166)); + encToName[166] = "brokenbar"; + + unicodeToName.put(new Character((char) 0x2022), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2022)); + + unicodeToName.put(new Character((char) 0x0063), "c"); + nameToUnicode.put("c", new Character((char) 0x0063)); + nameToEnc.put("c", new Integer(99)); + encToName[99] = "c"; + + unicodeToName.put(new Character((char) 0x02c7), "caron"); + nameToUnicode.put("caron", new Character((char) 0x02c7)); + nameToEnc.put("caron", new Integer(159)); + encToName[159] = "caron"; + + unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); + nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); + nameToEnc.put("ccedilla", new Integer(231)); + encToName[231] = "ccedilla"; + + unicodeToName.put(new Character((char) 0x00b8), "cedilla"); + nameToUnicode.put("cedilla", new Character((char) 0x00b8)); + nameToEnc.put("cedilla", new Integer(184)); + encToName[184] = "cedilla"; + + unicodeToName.put(new Character((char) 0x00a2), "cent"); + nameToUnicode.put("cent", new Character((char) 0x00a2)); + nameToEnc.put("cent", new Integer(162)); + encToName[162] = "cent"; + + unicodeToName.put(new Character((char) 0x02c6), "circumflex"); + nameToUnicode.put("circumflex", new Character((char) 0x02c6)); + nameToEnc.put("circumflex", new Integer(147)); + encToName[147] = "circumflex"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x00a9), "copyright"); + nameToUnicode.put("copyright", new Character((char) 0x00a9)); + nameToEnc.put("copyright", new Integer(169)); + encToName[169] = "copyright"; + + unicodeToName.put(new Character((char) 0x00a4), "currency"); + nameToUnicode.put("currency", new Character((char) 0x00a4)); + nameToEnc.put("currency", new Integer(164)); + encToName[164] = "currency"; + + unicodeToName.put(new Character((char) 0x0064), "d"); + nameToUnicode.put("d", new Character((char) 0x0064)); + nameToEnc.put("d", new Integer(100)); + encToName[100] = "d"; + + unicodeToName.put(new Character((char) 0x2020), "dagger"); + nameToUnicode.put("dagger", new Character((char) 0x2020)); + + unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); + nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + nameToEnc.put("degree", new Integer(176)); + encToName[176] = "degree"; + + unicodeToName.put(new Character((char) 0x00a8), "dieresis"); + nameToUnicode.put("dieresis", new Character((char) 0x00a8)); + nameToEnc.put("dieresis", new Integer(168)); + encToName[168] = "dieresis"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + nameToEnc.put("divide", new Integer(183)); + encToName[183] = "divide"; + + unicodeToName.put(new Character((char) 0x0024), "dollar"); + nameToUnicode.put("dollar", new Character((char) 0x0024)); + nameToEnc.put("dollar", new Integer(36)); + encToName[36] = "dollar"; + + unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); + nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); + nameToEnc.put("dotaccent", new Integer(151)); + encToName[151] = "dotaccent"; + + unicodeToName.put(new Character((char) 0x0131), "dotlessi"); + nameToUnicode.put("dotlessi", new Character((char) 0x0131)); + nameToEnc.put("dotlessi", new Integer(144)); + encToName[144] = "dotlessi"; + + unicodeToName.put(new Character((char) 0x0065), "e"); + nameToUnicode.put("e", new Character((char) 0x0065)); + nameToEnc.put("e", new Integer(101)); + encToName[101] = "e"; + + unicodeToName.put(new Character((char) 0x00e9), "eacute"); + nameToUnicode.put("eacute", new Character((char) 0x00e9)); + nameToEnc.put("eacute", new Integer(233)); + encToName[233] = "eacute"; + + unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); + nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); + nameToEnc.put("ecircumflex", new Integer(234)); + encToName[234] = "ecircumflex"; + + unicodeToName.put(new Character((char) 0x00eb), "edieresis"); + nameToUnicode.put("edieresis", new Character((char) 0x00eb)); + nameToEnc.put("edieresis", new Integer(235)); + encToName[235] = "edieresis"; + + unicodeToName.put(new Character((char) 0x00e8), "egrave"); + nameToUnicode.put("egrave", new Character((char) 0x00e8)); + nameToEnc.put("egrave", new Integer(232)); + encToName[232] = "egrave"; + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + + unicodeToName.put(new Character((char) 0x002d), "emdash"); + nameToUnicode.put("emdash", new Character((char) 0x002d)); + + unicodeToName.put(new Character((char) 0x002d), "endash"); + nameToUnicode.put("endash", new Character((char) 0x002d)); + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x00f0), "eth"); + nameToUnicode.put("eth", new Character((char) 0x00f0)); + nameToEnc.put("eth", new Integer(240)); + encToName[240] = "eth"; + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); + nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); + nameToEnc.put("exclamdown", new Integer(161)); + encToName[161] = "exclamdown"; + + unicodeToName.put(new Character((char) 0x0066), "f"); + nameToUnicode.put("f", new Character((char) 0x0066)); + nameToEnc.put("f", new Integer(102)); + encToName[102] = "f"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + + unicodeToName.put(new Character((char) 0x0067), "g"); + nameToUnicode.put("g", new Character((char) 0x0067)); + nameToEnc.put("g", new Integer(103)); + encToName[103] = "g"; + + unicodeToName.put(new Character((char) 0x00df), "germandbls"); + nameToUnicode.put("germandbls", new Character((char) 0x00df)); + nameToEnc.put("germandbls", new Integer(223)); + encToName[223] = "germandbls"; + + unicodeToName.put(new Character((char) 0x0060), "grave"); + nameToUnicode.put("grave", new Character((char) 0x0060)); + nameToEnc.put("grave", new Integer(145)); + encToName[145] = "grave"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); + nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); + nameToEnc.put("guillemotleft", new Integer(171)); + encToName[171] = "guillemotleft"; + + unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); + nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); + nameToEnc.put("guillemotright", new Integer(187)); + encToName[187] = "guillemotright"; + + unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); + nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); + + unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); + nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); + + unicodeToName.put(new Character((char) 0x0068), "h"); + nameToUnicode.put("h", new Character((char) 0x0068)); + nameToEnc.put("h", new Integer(104)); + encToName[104] = "h"; + + unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); + nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); + nameToEnc.put("hungarumlaut", new Integer(157)); + encToName[157] = "hungarumlaut"; + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(173)); + encToName[173] = "hyphen"; + + unicodeToName.put(new Character((char) 0x0069), "i"); + nameToUnicode.put("i", new Character((char) 0x0069)); + nameToEnc.put("i", new Integer(105)); + encToName[105] = "i"; + + unicodeToName.put(new Character((char) 0x00ed), "iacute"); + nameToUnicode.put("iacute", new Character((char) 0x00ed)); + nameToEnc.put("iacute", new Integer(237)); + encToName[237] = "iacute"; + + unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); + nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); + nameToEnc.put("icircumflex", new Integer(238)); + encToName[238] = "icircumflex"; + + unicodeToName.put(new Character((char) 0x00ef), "idieresis"); + nameToUnicode.put("idieresis", new Character((char) 0x00ef)); + nameToEnc.put("idieresis", new Integer(239)); + encToName[239] = "idieresis"; + + unicodeToName.put(new Character((char) 0x00ec), "igrave"); + nameToUnicode.put("igrave", new Character((char) 0x00ec)); + nameToEnc.put("igrave", new Integer(236)); + encToName[236] = "igrave"; + + unicodeToName.put(new Character((char) 0x006a), "j"); + nameToUnicode.put("j", new Character((char) 0x006a)); + nameToEnc.put("j", new Integer(106)); + encToName[106] = "j"; + + unicodeToName.put(new Character((char) 0x006b), "k"); + nameToUnicode.put("k", new Character((char) 0x006b)); + nameToEnc.put("k", new Integer(107)); + encToName[107] = "k"; + + unicodeToName.put(new Character((char) 0x006c), "l"); + nameToUnicode.put("l", new Character((char) 0x006c)); + nameToEnc.put("l", new Integer(108)); + encToName[108] = "l"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + nameToEnc.put("logicalnot", new Integer(172)); + encToName[172] = "logicalnot"; + + unicodeToName.put(new Character((char) 0x0142), "lslash"); + nameToUnicode.put("lslash", new Character((char) 0x0142)); + + unicodeToName.put(new Character((char) 0x006d), "m"); + nameToUnicode.put("m", new Character((char) 0x006d)); + nameToEnc.put("m", new Integer(109)); + encToName[109] = "m"; + + unicodeToName.put(new Character((char) 0x00af), "macron"); + nameToUnicode.put("macron", new Character((char) 0x00af)); + nameToEnc.put("macron", new Integer(175)); + encToName[175] = "macron"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + nameToEnc.put("minus", new Integer(45)); + encToName[45] = "minus"; + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + nameToEnc.put("mu", new Integer(181)); + encToName[181] = "mu"; + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + nameToEnc.put("multiply", new Integer(215)); + encToName[215] = "multiply"; + + unicodeToName.put(new Character((char) 0x006e), "n"); + nameToUnicode.put("n", new Character((char) 0x006e)); + nameToEnc.put("n", new Integer(110)); + encToName[110] = "n"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x00f1), "ntilde"); + nameToUnicode.put("ntilde", new Character((char) 0x00f1)); + nameToEnc.put("ntilde", new Integer(241)); + encToName[241] = "ntilde"; + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x006f), "o"); + nameToUnicode.put("o", new Character((char) 0x006f)); + nameToEnc.put("o", new Integer(111)); + encToName[111] = "o"; + + unicodeToName.put(new Character((char) 0x00f3), "oacute"); + nameToUnicode.put("oacute", new Character((char) 0x00f3)); + nameToEnc.put("oacute", new Integer(243)); + encToName[243] = "oacute"; + + unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); + nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); + nameToEnc.put("ocircumflex", new Integer(244)); + encToName[244] = "ocircumflex"; + + unicodeToName.put(new Character((char) 0x00f6), "odieresis"); + nameToUnicode.put("odieresis", new Character((char) 0x00f6)); + nameToEnc.put("odieresis", new Integer(246)); + encToName[246] = "odieresis"; + + unicodeToName.put(new Character((char) 0x0153), "oe"); + nameToUnicode.put("oe", new Character((char) 0x0153)); + + unicodeToName.put(new Character((char) 0x02db), "ogonek"); + nameToUnicode.put("ogonek", new Character((char) 0x02db)); + nameToEnc.put("ogonek", new Integer(158)); + encToName[158] = "ogonek"; + + unicodeToName.put(new Character((char) 0x00f2), "ograve"); + nameToUnicode.put("ograve", new Character((char) 0x00f2)); + nameToEnc.put("ograve", new Integer(242)); + encToName[242] = "ograve"; + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + nameToEnc.put("onehalf", new Integer(189)); + encToName[189] = "onehalf"; + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + nameToEnc.put("onequarter", new Integer(188)); + encToName[188] = "onequarter"; + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + nameToEnc.put("onesuperior", new Integer(185)); + encToName[185] = "onesuperior"; + + unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); + nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); + nameToEnc.put("ordfeminine", new Integer(170)); + encToName[170] = "ordfeminine"; + + unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); + nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); + nameToEnc.put("ordmasculine", new Integer(186)); + encToName[186] = "ordmasculine"; + + unicodeToName.put(new Character((char) 0x00f8), "oslash"); + nameToUnicode.put("oslash", new Character((char) 0x00f8)); + nameToEnc.put("oslash", new Integer(248)); + encToName[248] = "oslash"; + + unicodeToName.put(new Character((char) 0x00f5), "otilde"); + nameToUnicode.put("otilde", new Character((char) 0x00f5)); + nameToEnc.put("otilde", new Integer(245)); + encToName[245] = "otilde"; + + unicodeToName.put(new Character((char) 0x0070), "p"); + nameToUnicode.put("p", new Character((char) 0x0070)); + nameToEnc.put("p", new Integer(112)); + encToName[112] = "p"; + + unicodeToName.put(new Character((char) 0x00b6), "paragraph"); + nameToUnicode.put("paragraph", new Character((char) 0x00b6)); + nameToEnc.put("paragraph", new Integer(182)); + encToName[182] = "paragraph"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); + nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); + nameToEnc.put("periodcentered", new Integer(183)); + encToName[183] = "periodcentered"; + + unicodeToName.put(new Character((char) 0x2030), "perthousand"); + nameToUnicode.put("perthousand", new Character((char) 0x2030)); + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + nameToEnc.put("plusminus", new Integer(177)); + encToName[177] = "plusminus"; + + unicodeToName.put(new Character((char) 0x0071), "q"); + nameToUnicode.put("q", new Character((char) 0x0071)); + nameToEnc.put("q", new Integer(113)); + encToName[113] = "q"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x00bf), "questiondown"); + nameToUnicode.put("questiondown", new Character((char) 0x00bf)); + nameToEnc.put("questiondown", new Integer(191)); + encToName[191] = "questiondown"; + + unicodeToName.put(new Character((char) 0x0022), "quotedbl"); + nameToUnicode.put("quotedbl", new Character((char) 0x0022)); + nameToEnc.put("quotedbl", new Integer(34)); + encToName[34] = "quotedbl"; + + unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); + nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); + + unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); + nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); + + unicodeToName.put(new Character((char) 0x201d), "quotedblright"); + nameToUnicode.put("quotedblright", new Character((char) 0x201d)); + + unicodeToName.put(new Character((char) 0x0060), "quoteleft"); + nameToUnicode.put("quoteleft", new Character((char) 0x0060)); + nameToEnc.put("quoteleft", new Integer(96)); + encToName[96] = "quoteleft"; + + unicodeToName.put(new Character((char) 0x0027), "quoteright"); + nameToUnicode.put("quoteright", new Character((char) 0x0027)); + nameToEnc.put("quoteright", new Integer(39)); + encToName[39] = "quoteright"; + + unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); + nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); + + unicodeToName.put(new Character((char) 0x0027), "quotesingle"); + nameToUnicode.put("quotesingle", new Character((char) 0x0027)); + + unicodeToName.put(new Character((char) 0x0072), "r"); + nameToUnicode.put("r", new Character((char) 0x0072)); + nameToEnc.put("r", new Integer(114)); + encToName[114] = "r"; + + unicodeToName.put(new Character((char) 0x00ae), "registered"); + nameToUnicode.put("registered", new Character((char) 0x00ae)); + nameToEnc.put("registered", new Integer(174)); + encToName[174] = "registered"; + + unicodeToName.put(new Character((char) 0x02da), "ring"); + nameToUnicode.put("ring", new Character((char) 0x02da)); + nameToEnc.put("ring", new Integer(154)); + encToName[154] = "ring"; + + unicodeToName.put(new Character((char) 0x0073), "s"); + nameToUnicode.put("s", new Character((char) 0x0073)); + nameToEnc.put("s", new Integer(115)); + encToName[115] = "s"; + + unicodeToName.put(new Character((char) 0x0161), "scaron"); + nameToUnicode.put("scaron", new Character((char) 0x0161)); + + unicodeToName.put(new Character((char) 0x00a7), "section"); + nameToUnicode.put("section", new Character((char) 0x00a7)); + nameToEnc.put("section", new Integer(167)); + encToName[167] = "section"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x00a3), "sterling"); + nameToUnicode.put("sterling", new Character((char) 0x00a3)); + nameToEnc.put("sterling", new Integer(163)); + encToName[163] = "sterling"; + + unicodeToName.put(new Character((char) 0x0074), "t"); + nameToUnicode.put("t", new Character((char) 0x0074)); + nameToEnc.put("t", new Integer(116)); + encToName[116] = "t"; + + unicodeToName.put(new Character((char) 0x00fe), "thorn"); + nameToUnicode.put("thorn", new Character((char) 0x00fe)); + nameToEnc.put("thorn", new Integer(254)); + encToName[254] = "thorn"; + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + nameToEnc.put("threequarters", new Integer(190)); + encToName[190] = "threequarters"; + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + nameToEnc.put("threesuperior", new Integer(179)); + encToName[179] = "threesuperior"; + + unicodeToName.put(new Character((char) 0x02dc), "tilde"); + nameToUnicode.put("tilde", new Character((char) 0x02dc)); + nameToEnc.put("tilde", new Integer(148)); + encToName[148] = "tilde"; + + unicodeToName.put(new Character((char) 0x2122), "trademark"); + nameToUnicode.put("trademark", new Character((char) 0x2122)); + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + nameToEnc.put("twosuperior", new Integer(178)); + encToName[178] = "twosuperior"; + + unicodeToName.put(new Character((char) 0x0075), "u"); + nameToUnicode.put("u", new Character((char) 0x0075)); + nameToEnc.put("u", new Integer(117)); + encToName[117] = "u"; + + unicodeToName.put(new Character((char) 0x00fa), "uacute"); + nameToUnicode.put("uacute", new Character((char) 0x00fa)); + nameToEnc.put("uacute", new Integer(250)); + encToName[250] = "uacute"; + + unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); + nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); + nameToEnc.put("ucircumflex", new Integer(251)); + encToName[251] = "ucircumflex"; + + unicodeToName.put(new Character((char) 0x00fc), "udieresis"); + nameToUnicode.put("udieresis", new Character((char) 0x00fc)); + nameToEnc.put("udieresis", new Integer(252)); + encToName[252] = "udieresis"; + + unicodeToName.put(new Character((char) 0x00f9), "ugrave"); + nameToUnicode.put("ugrave", new Character((char) 0x00f9)); + nameToEnc.put("ugrave", new Integer(249)); + encToName[249] = "ugrave"; + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x0076), "v"); + nameToUnicode.put("v", new Character((char) 0x0076)); + nameToEnc.put("v", new Integer(118)); + encToName[118] = "v"; + + unicodeToName.put(new Character((char) 0x0077), "w"); + nameToUnicode.put("w", new Character((char) 0x0077)); + nameToEnc.put("w", new Integer(119)); + encToName[119] = "w"; + + unicodeToName.put(new Character((char) 0x0078), "x"); + nameToUnicode.put("x", new Character((char) 0x0078)); + nameToEnc.put("x", new Integer(120)); + encToName[120] = "x"; + + unicodeToName.put(new Character((char) 0x0079), "y"); + nameToUnicode.put("y", new Character((char) 0x0079)); + nameToEnc.put("y", new Integer(121)); + encToName[121] = "y"; + + unicodeToName.put(new Character((char) 0x00fd), "yacute"); + nameToUnicode.put("yacute", new Character((char) 0x00fd)); + nameToEnc.put("yacute", new Integer(253)); + encToName[253] = "yacute"; + + unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); + nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); + nameToEnc.put("ydieresis", new Integer(255)); + encToName[255] = "ydieresis"; + + unicodeToName.put(new Character((char) 0x00a5), "yen"); + nameToUnicode.put("yen", new Character((char) 0x00a5)); + nameToEnc.put("yen", new Integer(165)); + encToName[165] = "yen"; + + unicodeToName.put(new Character((char) 0x007a), "z"); + nameToUnicode.put("z", new Character((char) 0x007a)); + nameToEnc.put("z", new Integer(122)); + encToName[122] = "z"; + + unicodeToName.put(new Character((char) 0x017e), "zcaron"); + nameToUnicode.put("zcaron", new Character((char) 0x017e)); + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Latin");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("ISO");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Lookup.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Lookup.java index 2c9a76d0e..811bea039 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Lookup.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Lookup.java @@ -1,120 +1,120 @@ -//Copyright 2001-2005 FreeHEP. -package org.xmind.org.freehep.graphics2d.font; - -/** - * Lookup class provides conversion between different encodings and character - * tables using character name, encoding index, and unicode. In order to add new - * tables original code should be modified. - * - * @author Sami Kama - * @version $Id: freehep-graphics2d/src/main/java/org/freehep/graphics2d/font/Lookup.java 7aee336a8992 2005/11/25 23:19:05 duns $ - */ -public class Lookup { - private static Lookup instance; - - private CharTable[] tables; - - public static Lookup getInstance() { - if (instance == null) { - instance = new Lookup(); - } - return (instance); - } - - private int ntables = 8; - - private Lookup() { - tables = new CharTable[ntables]; - tables[0] = new Symbol(); - tables[1] = new Expert(); - tables[2] = new Zapfdingbats(); - tables[3] = new STDLatin(); - tables[4] = new MACLatin(); - tables[5] = new WINLatin(); - tables[6] = new PDFLatin(); - tables[7] = new ISOLatin(); - - } - - /** - * Converts a name to unicode. This method takes name of the character and - * returns character as a unicode character. - * - * @return requested unicode character. - */ - public char toUnicode(String name) { - for (int i = 0; i < ntables; i++) { - char uc = tables[i].toUnicode(name); - if (uc != '\uffff') - return (uc); - } - return ('\uffff'); - } - - /** - * Converts a unicode character to name. - * - * @return requested character name. - */ - public String toName(char uc) { - for (int i = 0; i < ntables; i++) { - String name = tables[i].toName(uc); - if (name != null) - return (name); - } - return (null); - } - - /** - * Converts a unicode character to name. - * - * @return requested character name. - */ - public String toName(Character uc) { - for (int i = 0; i < ntables; i++) { - String name = tables[i].toName(uc); - if (name != null) - return (name); - } - return (null); - } - - /** - * Gives the requested encoding table Valid table names can be requested - * with a call to - * - * @see #getTableNames(). - * - * @return requested encoding. - */ - public CharTable getTable(String tableName) { - for (int i = 0; i < ntables; i++) { - String tblName = tables[i].getEncoding() + tables[i].getName(); - if (tblName.equalsIgnoreCase(tableName)) - return (tables[i]); - } - return (null); - } - - /** - * Gives the total number of tables included in the file - * - * @return number of tables - */ - public int getNumberOfTables() { - return (ntables); - } - - /** - * Gives the names of tables that can be used in a string array. - * - * @return An array of String[] containing the table names - */ - public String[] getTableNames() { - String[] tblnames = new String[ntables]; - for (int i = 0; i < ntables; i++) { - tblnames[i] = tables[i].getEncoding() + tables[i].getName(); - } - return tblnames; - } +//Copyright 2001-2005 FreeHEP. +package org.xmind.org.freehep.graphics2d.font; + +/** + * Lookup class provides conversion between different encodings and character + * tables using character name, encoding index, and unicode. In order to add new + * tables original code should be modified. + * + * @author Sami Kama + * @version $Id: freehep-graphics2d/src/main/java/org/freehep/graphics2d/font/Lookup.java 7aee336a8992 2005/11/25 23:19:05 duns $ + */ +public class Lookup { + private static Lookup instance; + + private CharTable[] tables; + + public static Lookup getInstance() { + if (instance == null) { + instance = new Lookup(); + } + return (instance); + } + + private int ntables = 8; + + private Lookup() { + tables = new CharTable[ntables]; + tables[0] = new Symbol(); + tables[1] = new Expert(); + tables[2] = new Zapfdingbats(); + tables[3] = new STDLatin(); + tables[4] = new MACLatin(); + tables[5] = new WINLatin(); + tables[6] = new PDFLatin(); + tables[7] = new ISOLatin(); + + } + + /** + * Converts a name to unicode. This method takes name of the character and + * returns character as a unicode character. + * + * @return requested unicode character. + */ + public char toUnicode(String name) { + for (int i = 0; i < ntables; i++) { + char uc = tables[i].toUnicode(name); + if (uc != '\uffff') + return (uc); + } + return ('\uffff'); + } + + /** + * Converts a unicode character to name. + * + * @return requested character name. + */ + public String toName(char uc) { + for (int i = 0; i < ntables; i++) { + String name = tables[i].toName(uc); + if (name != null) + return (name); + } + return (null); + } + + /** + * Converts a unicode character to name. + * + * @return requested character name. + */ + public String toName(Character uc) { + for (int i = 0; i < ntables; i++) { + String name = tables[i].toName(uc); + if (name != null) + return (name); + } + return (null); + } + + /** + * Gives the requested encoding table Valid table names can be requested + * with a call to + * + * @see #getTableNames(). + * + * @return requested encoding. + */ + public CharTable getTable(String tableName) { + for (int i = 0; i < ntables; i++) { + String tblName = tables[i].getEncoding() + tables[i].getName(); + if (tblName.equalsIgnoreCase(tableName)) + return (tables[i]); + } + return (null); + } + + /** + * Gives the total number of tables included in the file + * + * @return number of tables + */ + public int getNumberOfTables() { + return (ntables); + } + + /** + * Gives the names of tables that can be used in a string array. + * + * @return An array of String[] containing the table names + */ + public String[] getTableNames() { + String[] tblnames = new String[ntables]; + for (int i = 0; i < ntables; i++) { + tblnames[i] = tables[i].getEncoding() + tables[i].getName(); + } + return tblnames; + } } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/MACLatin.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/MACLatin.java index 34715b03b..7799feebc 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/MACLatin.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/MACLatin.java @@ -1,1150 +1,1150 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated MACLatin Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class MACLatin extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public MACLatin() { - unicodeToName.put(new Character((char) 0x0041), "A"); - nameToUnicode.put("A", new Character((char) 0x0041)); - nameToEnc.put("A", new Integer(65)); - encToName[65] = "A"; - - unicodeToName.put(new Character((char) 0x00c6), "AE"); - nameToUnicode.put("AE", new Character((char) 0x00c6)); - nameToEnc.put("AE", new Integer(174)); - encToName[174] = "AE"; - - unicodeToName.put(new Character((char) 0x00c1), "Aacute"); - nameToUnicode.put("Aacute", new Character((char) 0x00c1)); - nameToEnc.put("Aacute", new Integer(231)); - encToName[231] = "Aacute"; - - unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); - nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); - nameToEnc.put("Acircumflex", new Integer(229)); - encToName[229] = "Acircumflex"; - - unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); - nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); - nameToEnc.put("Adieresis", new Integer(128)); - encToName[128] = "Adieresis"; - - unicodeToName.put(new Character((char) 0x00c0), "Agrave"); - nameToUnicode.put("Agrave", new Character((char) 0x00c0)); - nameToEnc.put("Agrave", new Integer(203)); - encToName[203] = "Agrave"; - - unicodeToName.put(new Character((char) 0x00c5), "Aring"); - nameToUnicode.put("Aring", new Character((char) 0x00c5)); - nameToEnc.put("Aring", new Integer(129)); - encToName[129] = "Aring"; - - unicodeToName.put(new Character((char) 0x00c3), "Atilde"); - nameToUnicode.put("Atilde", new Character((char) 0x00c3)); - nameToEnc.put("Atilde", new Integer(204)); - encToName[204] = "Atilde"; - - unicodeToName.put(new Character((char) 0x0042), "B"); - nameToUnicode.put("B", new Character((char) 0x0042)); - nameToEnc.put("B", new Integer(66)); - encToName[66] = "B"; - - unicodeToName.put(new Character((char) 0x0043), "C"); - nameToUnicode.put("C", new Character((char) 0x0043)); - nameToEnc.put("C", new Integer(67)); - encToName[67] = "C"; - - unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); - nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); - nameToEnc.put("Ccedilla", new Integer(130)); - encToName[130] = "Ccedilla"; - - unicodeToName.put(new Character((char) 0x0044), "D"); - nameToUnicode.put("D", new Character((char) 0x0044)); - nameToEnc.put("D", new Integer(68)); - encToName[68] = "D"; - - unicodeToName.put(new Character((char) 0x0045), "E"); - nameToUnicode.put("E", new Character((char) 0x0045)); - nameToEnc.put("E", new Integer(69)); - encToName[69] = "E"; - - unicodeToName.put(new Character((char) 0x00c9), "Eacute"); - nameToUnicode.put("Eacute", new Character((char) 0x00c9)); - nameToEnc.put("Eacute", new Integer(131)); - encToName[131] = "Eacute"; - - unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); - nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); - nameToEnc.put("Ecircumflex", new Integer(230)); - encToName[230] = "Ecircumflex"; - - unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); - nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); - nameToEnc.put("Edieresis", new Integer(232)); - encToName[232] = "Edieresis"; - - unicodeToName.put(new Character((char) 0x00c8), "Egrave"); - nameToUnicode.put("Egrave", new Character((char) 0x00c8)); - nameToEnc.put("Egrave", new Integer(233)); - encToName[233] = "Egrave"; - - unicodeToName.put(new Character((char) 0x00d0), "Eth"); - nameToUnicode.put("Eth", new Character((char) 0x00d0)); - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - - unicodeToName.put(new Character((char) 0x0046), "F"); - nameToUnicode.put("F", new Character((char) 0x0046)); - nameToEnc.put("F", new Integer(70)); - encToName[70] = "F"; - - unicodeToName.put(new Character((char) 0x0047), "G"); - nameToUnicode.put("G", new Character((char) 0x0047)); - nameToEnc.put("G", new Integer(71)); - encToName[71] = "G"; - - unicodeToName.put(new Character((char) 0x0048), "H"); - nameToUnicode.put("H", new Character((char) 0x0048)); - nameToEnc.put("H", new Integer(72)); - encToName[72] = "H"; - - unicodeToName.put(new Character((char) 0x0049), "I"); - nameToUnicode.put("I", new Character((char) 0x0049)); - nameToEnc.put("I", new Integer(73)); - encToName[73] = "I"; - - unicodeToName.put(new Character((char) 0x00cd), "Iacute"); - nameToUnicode.put("Iacute", new Character((char) 0x00cd)); - nameToEnc.put("Iacute", new Integer(234)); - encToName[234] = "Iacute"; - - unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); - nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); - nameToEnc.put("Icircumflex", new Integer(235)); - encToName[235] = "Icircumflex"; - - unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); - nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); - nameToEnc.put("Idieresis", new Integer(236)); - encToName[236] = "Idieresis"; - - unicodeToName.put(new Character((char) 0x00cc), "Igrave"); - nameToUnicode.put("Igrave", new Character((char) 0x00cc)); - nameToEnc.put("Igrave", new Integer(237)); - encToName[237] = "Igrave"; - - unicodeToName.put(new Character((char) 0x004a), "J"); - nameToUnicode.put("J", new Character((char) 0x004a)); - nameToEnc.put("J", new Integer(74)); - encToName[74] = "J"; - - unicodeToName.put(new Character((char) 0x004b), "K"); - nameToUnicode.put("K", new Character((char) 0x004b)); - nameToEnc.put("K", new Integer(75)); - encToName[75] = "K"; - - unicodeToName.put(new Character((char) 0x004c), "L"); - nameToUnicode.put("L", new Character((char) 0x004c)); - nameToEnc.put("L", new Integer(76)); - encToName[76] = "L"; - - unicodeToName.put(new Character((char) 0x0141), "Lslash"); - nameToUnicode.put("Lslash", new Character((char) 0x0141)); - - unicodeToName.put(new Character((char) 0x004d), "M"); - nameToUnicode.put("M", new Character((char) 0x004d)); - nameToEnc.put("M", new Integer(77)); - encToName[77] = "M"; - - unicodeToName.put(new Character((char) 0x004e), "N"); - nameToUnicode.put("N", new Character((char) 0x004e)); - nameToEnc.put("N", new Integer(78)); - encToName[78] = "N"; - - unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); - nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); - nameToEnc.put("Ntilde", new Integer(132)); - encToName[132] = "Ntilde"; - - unicodeToName.put(new Character((char) 0x004f), "O"); - nameToUnicode.put("O", new Character((char) 0x004f)); - nameToEnc.put("O", new Integer(79)); - encToName[79] = "O"; - - unicodeToName.put(new Character((char) 0x0152), "OE"); - nameToUnicode.put("OE", new Character((char) 0x0152)); - nameToEnc.put("OE", new Integer(206)); - encToName[206] = "OE"; - - unicodeToName.put(new Character((char) 0x00d2), "Oacute"); - nameToUnicode.put("Oacute", new Character((char) 0x00d2)); - nameToEnc.put("Oacute", new Integer(238)); - encToName[238] = "Oacute"; - - unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); - nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); - nameToEnc.put("Ocircumflex", new Integer(239)); - encToName[239] = "Ocircumflex"; - - unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); - nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); - nameToEnc.put("Odieresis", new Integer(133)); - encToName[133] = "Odieresis"; - - unicodeToName.put(new Character((char) 0x00d3), "Ograve"); - nameToUnicode.put("Ograve", new Character((char) 0x00d3)); - nameToEnc.put("Ograve", new Integer(241)); - encToName[241] = "Ograve"; - - unicodeToName.put(new Character((char) 0x00d8), "Oslash"); - nameToUnicode.put("Oslash", new Character((char) 0x00d8)); - nameToEnc.put("Oslash", new Integer(175)); - encToName[175] = "Oslash"; - - unicodeToName.put(new Character((char) 0x00d5), "Otilde"); - nameToUnicode.put("Otilde", new Character((char) 0x00d5)); - nameToEnc.put("Otilde", new Integer(205)); - encToName[205] = "Otilde"; - - unicodeToName.put(new Character((char) 0x0050), "P"); - nameToUnicode.put("P", new Character((char) 0x0050)); - nameToEnc.put("P", new Integer(80)); - encToName[80] = "P"; - - unicodeToName.put(new Character((char) 0x0051), "Q"); - nameToUnicode.put("Q", new Character((char) 0x0051)); - nameToEnc.put("Q", new Integer(81)); - encToName[81] = "Q"; - - unicodeToName.put(new Character((char) 0x0052), "R"); - nameToUnicode.put("R", new Character((char) 0x0052)); - nameToEnc.put("R", new Integer(82)); - encToName[82] = "R"; - - unicodeToName.put(new Character((char) 0x0053), "S"); - nameToUnicode.put("S", new Character((char) 0x0053)); - nameToEnc.put("S", new Integer(83)); - encToName[83] = "S"; - - unicodeToName.put(new Character((char) 0x0160), "Scaron"); - nameToUnicode.put("Scaron", new Character((char) 0x0160)); - - unicodeToName.put(new Character((char) 0x0054), "T"); - nameToUnicode.put("T", new Character((char) 0x0054)); - nameToEnc.put("T", new Integer(84)); - encToName[84] = "T"; - - unicodeToName.put(new Character((char) 0x00de), "Thorn"); - nameToUnicode.put("Thorn", new Character((char) 0x00de)); - - unicodeToName.put(new Character((char) 0x0055), "U"); - nameToUnicode.put("U", new Character((char) 0x0055)); - nameToEnc.put("U", new Integer(85)); - encToName[85] = "U"; - - unicodeToName.put(new Character((char) 0x00da), "Uacute"); - nameToUnicode.put("Uacute", new Character((char) 0x00da)); - nameToEnc.put("Uacute", new Integer(242)); - encToName[242] = "Uacute"; - - unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); - nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); - nameToEnc.put("Ucircumflex", new Integer(243)); - encToName[243] = "Ucircumflex"; - - unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); - nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); - nameToEnc.put("Udieresis", new Integer(134)); - encToName[134] = "Udieresis"; - - unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); - nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); - nameToEnc.put("Ugrave", new Integer(244)); - encToName[244] = "Ugrave"; - - unicodeToName.put(new Character((char) 0x0056), "V"); - nameToUnicode.put("V", new Character((char) 0x0056)); - nameToEnc.put("V", new Integer(86)); - encToName[86] = "V"; - - unicodeToName.put(new Character((char) 0x0057), "W"); - nameToUnicode.put("W", new Character((char) 0x0057)); - nameToEnc.put("W", new Integer(87)); - encToName[87] = "W"; - - unicodeToName.put(new Character((char) 0x0058), "X"); - nameToUnicode.put("X", new Character((char) 0x0058)); - nameToEnc.put("X", new Integer(88)); - encToName[88] = "X"; - - unicodeToName.put(new Character((char) 0x0059), "Y"); - nameToUnicode.put("Y", new Character((char) 0x0059)); - nameToEnc.put("Y", new Integer(89)); - encToName[89] = "Y"; - - unicodeToName.put(new Character((char) 0x00dd), "Yacute"); - nameToUnicode.put("Yacute", new Character((char) 0x00dd)); - - unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); - nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); - nameToEnc.put("Ydieresis", new Integer(217)); - encToName[217] = "Ydieresis"; - - unicodeToName.put(new Character((char) 0x005a), "Z"); - nameToUnicode.put("Z", new Character((char) 0x005a)); - nameToEnc.put("Z", new Integer(90)); - encToName[90] = "Z"; - - unicodeToName.put(new Character((char) 0x017d), "Zcaron"); - nameToUnicode.put("Zcaron", new Character((char) 0x017d)); - - unicodeToName.put(new Character((char) 0x0061), "a"); - nameToUnicode.put("a", new Character((char) 0x0061)); - nameToEnc.put("a", new Integer(97)); - encToName[97] = "a"; - - unicodeToName.put(new Character((char) 0x00e1), "aacute"); - nameToUnicode.put("aacute", new Character((char) 0x00e1)); - nameToEnc.put("aacute", new Integer(135)); - encToName[135] = "aacute"; - - unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); - nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); - nameToEnc.put("acircumflex", new Integer(137)); - encToName[137] = "acircumflex"; - - unicodeToName.put(new Character((char) 0x00b4), "acute"); - nameToUnicode.put("acute", new Character((char) 0x00b4)); - nameToEnc.put("acute", new Integer(171)); - encToName[171] = "acute"; - - unicodeToName.put(new Character((char) 0x00e4), "adieresis"); - nameToUnicode.put("adieresis", new Character((char) 0x00e4)); - nameToEnc.put("adieresis", new Integer(138)); - encToName[138] = "adieresis"; - - unicodeToName.put(new Character((char) 0x00e6), "ae"); - nameToUnicode.put("ae", new Character((char) 0x00e6)); - nameToEnc.put("ae", new Integer(190)); - encToName[190] = "ae"; - - unicodeToName.put(new Character((char) 0x00e0), "agrave"); - nameToUnicode.put("agrave", new Character((char) 0x00e0)); - nameToEnc.put("agrave", new Integer(136)); - encToName[136] = "agrave"; - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x00e5), "aring"); - nameToUnicode.put("aring", new Character((char) 0x00e5)); - nameToEnc.put("aring", new Integer(140)); - encToName[140] = "aring"; - - unicodeToName.put(new Character((char) 0x005e), "asciicircum"); - nameToUnicode.put("asciicircum", new Character((char) 0x005e)); - nameToEnc.put("asciicircum", new Integer(94)); - encToName[94] = "asciicircum"; - - unicodeToName.put(new Character((char) 0x007e), "asciitilde"); - nameToUnicode.put("asciitilde", new Character((char) 0x007e)); - nameToEnc.put("asciitilde", new Integer(126)); - encToName[126] = "asciitilde"; - - unicodeToName.put(new Character((char) 0x002a), "asterisk"); - nameToUnicode.put("asterisk", new Character((char) 0x002a)); - nameToEnc.put("asterisk", new Integer(42)); - encToName[42] = "asterisk"; - - unicodeToName.put(new Character((char) 0x0040), "at"); - nameToUnicode.put("at", new Character((char) 0x0040)); - nameToEnc.put("at", new Integer(64)); - encToName[64] = "at"; - - unicodeToName.put(new Character((char) 0x00e3), "atilde"); - nameToUnicode.put("atilde", new Character((char) 0x00e3)); - nameToEnc.put("atilde", new Integer(139)); - encToName[139] = "atilde"; - - unicodeToName.put(new Character((char) 0x0062), "b"); - nameToUnicode.put("b", new Character((char) 0x0062)); - nameToEnc.put("b", new Integer(98)); - encToName[98] = "b"; - - unicodeToName.put(new Character((char) 0x005c), "backslash"); - nameToUnicode.put("backslash", new Character((char) 0x005c)); - nameToEnc.put("backslash", new Integer(92)); - encToName[92] = "backslash"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0x02d8), "breve"); - nameToUnicode.put("breve", new Character((char) 0x02d8)); - nameToEnc.put("breve", new Integer(249)); - encToName[249] = "breve"; - - unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); - nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); - - unicodeToName.put(new Character((char) 0x2022), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2022)); - nameToEnc.put("bullet", new Integer(165)); - encToName[165] = "bullet"; - - unicodeToName.put(new Character((char) 0x0063), "c"); - nameToUnicode.put("c", new Character((char) 0x0063)); - nameToEnc.put("c", new Integer(99)); - encToName[99] = "c"; - - unicodeToName.put(new Character((char) 0x02c7), "caron"); - nameToUnicode.put("caron", new Character((char) 0x02c7)); - nameToEnc.put("caron", new Integer(255)); - encToName[255] = "caron"; - - unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); - nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); - nameToEnc.put("ccedilla", new Integer(141)); - encToName[141] = "ccedilla"; - - unicodeToName.put(new Character((char) 0x00b8), "cedilla"); - nameToUnicode.put("cedilla", new Character((char) 0x00b8)); - nameToEnc.put("cedilla", new Integer(252)); - encToName[252] = "cedilla"; - - unicodeToName.put(new Character((char) 0x00a2), "cent"); - nameToUnicode.put("cent", new Character((char) 0x00a2)); - nameToEnc.put("cent", new Integer(162)); - encToName[162] = "cent"; - - unicodeToName.put(new Character((char) 0x02c6), "circumflex"); - nameToUnicode.put("circumflex", new Character((char) 0x02c6)); - nameToEnc.put("circumflex", new Integer(246)); - encToName[246] = "circumflex"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x00a9), "copyright"); - nameToUnicode.put("copyright", new Character((char) 0x00a9)); - nameToEnc.put("copyright", new Integer(169)); - encToName[169] = "copyright"; - - unicodeToName.put(new Character((char) 0x00a4), "currency"); - nameToUnicode.put("currency", new Character((char) 0x00a4)); - nameToEnc.put("currency", new Integer(219)); - encToName[219] = "currency"; - - unicodeToName.put(new Character((char) 0x0064), "d"); - nameToUnicode.put("d", new Character((char) 0x0064)); - nameToEnc.put("d", new Integer(100)); - encToName[100] = "d"; - - unicodeToName.put(new Character((char) 0x2020), "dagger"); - nameToUnicode.put("dagger", new Character((char) 0x2020)); - nameToEnc.put("dagger", new Integer(160)); - encToName[160] = "dagger"; - - unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); - nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); - nameToEnc.put("daggerdbl", new Integer(224)); - encToName[224] = "daggerdbl"; - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - nameToEnc.put("degree", new Integer(161)); - encToName[161] = "degree"; - - unicodeToName.put(new Character((char) 0x00a8), "dieresis"); - nameToUnicode.put("dieresis", new Character((char) 0x00a8)); - nameToEnc.put("dieresis", new Integer(172)); - encToName[172] = "dieresis"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - nameToEnc.put("divide", new Integer(214)); - encToName[214] = "divide"; - - unicodeToName.put(new Character((char) 0x0024), "dollar"); - nameToUnicode.put("dollar", new Character((char) 0x0024)); - nameToEnc.put("dollar", new Integer(36)); - encToName[36] = "dollar"; - - unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); - nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); - nameToEnc.put("dotaccent", new Integer(250)); - encToName[250] = "dotaccent"; - - unicodeToName.put(new Character((char) 0x0131), "dotlessi"); - nameToUnicode.put("dotlessi", new Character((char) 0x0131)); - nameToEnc.put("dotlessi", new Integer(245)); - encToName[245] = "dotlessi"; - - unicodeToName.put(new Character((char) 0x0065), "e"); - nameToUnicode.put("e", new Character((char) 0x0065)); - nameToEnc.put("e", new Integer(101)); - encToName[101] = "e"; - - unicodeToName.put(new Character((char) 0x00e9), "eacute"); - nameToUnicode.put("eacute", new Character((char) 0x00e9)); - nameToEnc.put("eacute", new Integer(142)); - encToName[142] = "eacute"; - - unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); - nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); - nameToEnc.put("ecircumflex", new Integer(144)); - encToName[144] = "ecircumflex"; - - unicodeToName.put(new Character((char) 0x00eb), "edieresis"); - nameToUnicode.put("edieresis", new Character((char) 0x00eb)); - nameToEnc.put("edieresis", new Integer(145)); - encToName[145] = "edieresis"; - - unicodeToName.put(new Character((char) 0x00e8), "egrave"); - nameToUnicode.put("egrave", new Character((char) 0x00e8)); - nameToEnc.put("egrave", new Integer(143)); - encToName[143] = "egrave"; - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - nameToEnc.put("ellipsis", new Integer(201)); - encToName[201] = "ellipsis"; - - unicodeToName.put(new Character((char) 0x002d), "emdash"); - nameToUnicode.put("emdash", new Character((char) 0x002d)); - nameToEnc.put("emdash", new Integer(209)); - encToName[209] = "emdash"; - - unicodeToName.put(new Character((char) 0x002d), "endash"); - nameToUnicode.put("endash", new Character((char) 0x002d)); - nameToEnc.put("endash", new Integer(208)); - encToName[208] = "endash"; - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x00f0), "eth"); - nameToUnicode.put("eth", new Character((char) 0x00f0)); - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); - nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); - nameToEnc.put("exclamdown", new Integer(193)); - encToName[193] = "exclamdown"; - - unicodeToName.put(new Character((char) 0x0066), "f"); - nameToUnicode.put("f", new Character((char) 0x0066)); - nameToEnc.put("f", new Integer(102)); - encToName[102] = "f"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - nameToEnc.put("fi", new Integer(222)); - encToName[222] = "fi"; - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - nameToEnc.put("fl", new Integer(223)); - encToName[223] = "fl"; - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - nameToEnc.put("florin", new Integer(196)); - encToName[196] = "florin"; - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - nameToEnc.put("fraction", new Integer(218)); - encToName[218] = "fraction"; - - unicodeToName.put(new Character((char) 0x0067), "g"); - nameToUnicode.put("g", new Character((char) 0x0067)); - nameToEnc.put("g", new Integer(103)); - encToName[103] = "g"; - - unicodeToName.put(new Character((char) 0x00df), "germandbls"); - nameToUnicode.put("germandbls", new Character((char) 0x00df)); - nameToEnc.put("germandbls", new Integer(167)); - encToName[167] = "germandbls"; - - unicodeToName.put(new Character((char) 0x0060), "grave"); - nameToUnicode.put("grave", new Character((char) 0x0060)); - nameToEnc.put("grave", new Integer(96)); - encToName[96] = "grave"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); - nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); - nameToEnc.put("guillemotleft", new Integer(199)); - encToName[199] = "guillemotleft"; - - unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); - nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); - nameToEnc.put("guillemotright", new Integer(200)); - encToName[200] = "guillemotright"; - - unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); - nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); - nameToEnc.put("guilsinglleft", new Integer(220)); - encToName[220] = "guilsinglleft"; - - unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); - nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); - nameToEnc.put("guilsinglright", new Integer(221)); - encToName[221] = "guilsinglright"; - - unicodeToName.put(new Character((char) 0x0068), "h"); - nameToUnicode.put("h", new Character((char) 0x0068)); - nameToEnc.put("h", new Integer(104)); - encToName[104] = "h"; - - unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); - nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); - nameToEnc.put("hungarumlaut", new Integer(253)); - encToName[253] = "hungarumlaut"; - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(45)); - encToName[45] = "hyphen"; - - unicodeToName.put(new Character((char) 0x0069), "i"); - nameToUnicode.put("i", new Character((char) 0x0069)); - nameToEnc.put("i", new Integer(105)); - encToName[105] = "i"; - - unicodeToName.put(new Character((char) 0x00ed), "iacute"); - nameToUnicode.put("iacute", new Character((char) 0x00ed)); - nameToEnc.put("iacute", new Integer(146)); - encToName[146] = "iacute"; - - unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); - nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); - nameToEnc.put("icircumflex", new Integer(148)); - encToName[148] = "icircumflex"; - - unicodeToName.put(new Character((char) 0x00ef), "idieresis"); - nameToUnicode.put("idieresis", new Character((char) 0x00ef)); - nameToEnc.put("idieresis", new Integer(149)); - encToName[149] = "idieresis"; - - unicodeToName.put(new Character((char) 0x00ec), "igrave"); - nameToUnicode.put("igrave", new Character((char) 0x00ec)); - nameToEnc.put("igrave", new Integer(147)); - encToName[147] = "igrave"; - - unicodeToName.put(new Character((char) 0x006a), "j"); - nameToUnicode.put("j", new Character((char) 0x006a)); - nameToEnc.put("j", new Integer(106)); - encToName[106] = "j"; - - unicodeToName.put(new Character((char) 0x006b), "k"); - nameToUnicode.put("k", new Character((char) 0x006b)); - nameToEnc.put("k", new Integer(107)); - encToName[107] = "k"; - - unicodeToName.put(new Character((char) 0x006c), "l"); - nameToUnicode.put("l", new Character((char) 0x006c)); - nameToEnc.put("l", new Integer(108)); - encToName[108] = "l"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - nameToEnc.put("logicalnot", new Integer(194)); - encToName[194] = "logicalnot"; - - unicodeToName.put(new Character((char) 0x0142), "lslash"); - nameToUnicode.put("lslash", new Character((char) 0x0142)); - - unicodeToName.put(new Character((char) 0x006d), "m"); - nameToUnicode.put("m", new Character((char) 0x006d)); - nameToEnc.put("m", new Integer(109)); - encToName[109] = "m"; - - unicodeToName.put(new Character((char) 0x00af), "macron"); - nameToUnicode.put("macron", new Character((char) 0x00af)); - nameToEnc.put("macron", new Integer(248)); - encToName[248] = "macron"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - nameToEnc.put("mu", new Integer(181)); - encToName[181] = "mu"; - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - - unicodeToName.put(new Character((char) 0x006e), "n"); - nameToUnicode.put("n", new Character((char) 0x006e)); - nameToEnc.put("n", new Integer(110)); - encToName[110] = "n"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x00f1), "ntilde"); - nameToUnicode.put("ntilde", new Character((char) 0x00f1)); - nameToEnc.put("ntilde", new Integer(150)); - encToName[150] = "ntilde"; - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x006f), "o"); - nameToUnicode.put("o", new Character((char) 0x006f)); - nameToEnc.put("o", new Integer(111)); - encToName[111] = "o"; - - unicodeToName.put(new Character((char) 0x00f3), "oacute"); - nameToUnicode.put("oacute", new Character((char) 0x00f3)); - nameToEnc.put("oacute", new Integer(151)); - encToName[151] = "oacute"; - - unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); - nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); - nameToEnc.put("ocircumflex", new Integer(153)); - encToName[153] = "ocircumflex"; - - unicodeToName.put(new Character((char) 0x00f6), "odieresis"); - nameToUnicode.put("odieresis", new Character((char) 0x00f6)); - nameToEnc.put("odieresis", new Integer(154)); - encToName[154] = "odieresis"; - - unicodeToName.put(new Character((char) 0x0153), "oe"); - nameToUnicode.put("oe", new Character((char) 0x0153)); - nameToEnc.put("oe", new Integer(207)); - encToName[207] = "oe"; - - unicodeToName.put(new Character((char) 0x02db), "ogonek"); - nameToUnicode.put("ogonek", new Character((char) 0x02db)); - nameToEnc.put("ogonek", new Integer(254)); - encToName[254] = "ogonek"; - - unicodeToName.put(new Character((char) 0x00f2), "ograve"); - nameToUnicode.put("ograve", new Character((char) 0x00f2)); - nameToEnc.put("ograve", new Integer(152)); - encToName[152] = "ograve"; - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - - unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); - nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); - nameToEnc.put("ordfeminine", new Integer(187)); - encToName[187] = "ordfeminine"; - - unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); - nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); - nameToEnc.put("ordmasculine", new Integer(188)); - encToName[188] = "ordmasculine"; - - unicodeToName.put(new Character((char) 0x00f8), "oslash"); - nameToUnicode.put("oslash", new Character((char) 0x00f8)); - nameToEnc.put("oslash", new Integer(191)); - encToName[191] = "oslash"; - - unicodeToName.put(new Character((char) 0x00f5), "otilde"); - nameToUnicode.put("otilde", new Character((char) 0x00f5)); - nameToEnc.put("otilde", new Integer(155)); - encToName[155] = "otilde"; - - unicodeToName.put(new Character((char) 0x0070), "p"); - nameToUnicode.put("p", new Character((char) 0x0070)); - nameToEnc.put("p", new Integer(112)); - encToName[112] = "p"; - - unicodeToName.put(new Character((char) 0x00b6), "paragraph"); - nameToUnicode.put("paragraph", new Character((char) 0x00b6)); - nameToEnc.put("paragraph", new Integer(166)); - encToName[166] = "paragraph"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); - nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); - nameToEnc.put("periodcentered", new Integer(225)); - encToName[225] = "periodcentered"; - - unicodeToName.put(new Character((char) 0x2030), "perthousand"); - nameToUnicode.put("perthousand", new Character((char) 0x2030)); - nameToEnc.put("perthousand", new Integer(228)); - encToName[228] = "perthousand"; - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - nameToEnc.put("plusminus", new Integer(177)); - encToName[177] = "plusminus"; - - unicodeToName.put(new Character((char) 0x0071), "q"); - nameToUnicode.put("q", new Character((char) 0x0071)); - nameToEnc.put("q", new Integer(113)); - encToName[113] = "q"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x00bf), "questiondown"); - nameToUnicode.put("questiondown", new Character((char) 0x00bf)); - nameToEnc.put("questiondown", new Integer(192)); - encToName[192] = "questiondown"; - - unicodeToName.put(new Character((char) 0x0022), "quotedbl"); - nameToUnicode.put("quotedbl", new Character((char) 0x0022)); - nameToEnc.put("quotedbl", new Integer(34)); - encToName[34] = "quotedbl"; - - unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); - nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); - nameToEnc.put("quotedblbase", new Integer(227)); - encToName[227] = "quotedblbase"; - - unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); - nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); - nameToEnc.put("quotedblleft", new Integer(210)); - encToName[210] = "quotedblleft"; - - unicodeToName.put(new Character((char) 0x201d), "quotedblright"); - nameToUnicode.put("quotedblright", new Character((char) 0x201d)); - nameToEnc.put("quotedblright", new Integer(211)); - encToName[211] = "quotedblright"; - - unicodeToName.put(new Character((char) 0x0060), "quoteleft"); - nameToUnicode.put("quoteleft", new Character((char) 0x0060)); - nameToEnc.put("quoteleft", new Integer(212)); - encToName[212] = "quoteleft"; - - unicodeToName.put(new Character((char) 0x0027), "quoteright"); - nameToUnicode.put("quoteright", new Character((char) 0x0027)); - nameToEnc.put("quoteright", new Integer(213)); - encToName[213] = "quoteright"; - - unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); - nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); - nameToEnc.put("quotesinglbase", new Integer(226)); - encToName[226] = "quotesinglbase"; - - unicodeToName.put(new Character((char) 0x0027), "quotesingle"); - nameToUnicode.put("quotesingle", new Character((char) 0x0027)); - nameToEnc.put("quotesingle", new Integer(39)); - encToName[39] = "quotesingle"; - - unicodeToName.put(new Character((char) 0x0072), "r"); - nameToUnicode.put("r", new Character((char) 0x0072)); - nameToEnc.put("r", new Integer(114)); - encToName[114] = "r"; - - unicodeToName.put(new Character((char) 0x00ae), "registered"); - nameToUnicode.put("registered", new Character((char) 0x00ae)); - nameToEnc.put("registered", new Integer(168)); - encToName[168] = "registered"; - - unicodeToName.put(new Character((char) 0x02da), "ring"); - nameToUnicode.put("ring", new Character((char) 0x02da)); - nameToEnc.put("ring", new Integer(251)); - encToName[251] = "ring"; - - unicodeToName.put(new Character((char) 0x0073), "s"); - nameToUnicode.put("s", new Character((char) 0x0073)); - nameToEnc.put("s", new Integer(115)); - encToName[115] = "s"; - - unicodeToName.put(new Character((char) 0x0161), "scaron"); - nameToUnicode.put("scaron", new Character((char) 0x0161)); - - unicodeToName.put(new Character((char) 0x00a7), "section"); - nameToUnicode.put("section", new Character((char) 0x00a7)); - nameToEnc.put("section", new Integer(164)); - encToName[164] = "section"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x00a3), "sterling"); - nameToUnicode.put("sterling", new Character((char) 0x00a3)); - nameToEnc.put("sterling", new Integer(163)); - encToName[163] = "sterling"; - - unicodeToName.put(new Character((char) 0x0074), "t"); - nameToUnicode.put("t", new Character((char) 0x0074)); - nameToEnc.put("t", new Integer(116)); - encToName[116] = "t"; - - unicodeToName.put(new Character((char) 0x00fe), "thorn"); - nameToUnicode.put("thorn", new Character((char) 0x00fe)); - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - - unicodeToName.put(new Character((char) 0x02dc), "tilde"); - nameToUnicode.put("tilde", new Character((char) 0x02dc)); - nameToEnc.put("tilde", new Integer(247)); - encToName[247] = "tilde"; - - unicodeToName.put(new Character((char) 0x2122), "trademark"); - nameToUnicode.put("trademark", new Character((char) 0x2122)); - nameToEnc.put("trademark", new Integer(170)); - encToName[170] = "trademark"; - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - - unicodeToName.put(new Character((char) 0x0075), "u"); - nameToUnicode.put("u", new Character((char) 0x0075)); - nameToEnc.put("u", new Integer(117)); - encToName[117] = "u"; - - unicodeToName.put(new Character((char) 0x00fa), "uacute"); - nameToUnicode.put("uacute", new Character((char) 0x00fa)); - nameToEnc.put("uacute", new Integer(156)); - encToName[156] = "uacute"; - - unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); - nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); - nameToEnc.put("ucircumflex", new Integer(158)); - encToName[158] = "ucircumflex"; - - unicodeToName.put(new Character((char) 0x00fc), "udieresis"); - nameToUnicode.put("udieresis", new Character((char) 0x00fc)); - nameToEnc.put("udieresis", new Integer(159)); - encToName[159] = "udieresis"; - - unicodeToName.put(new Character((char) 0x00f9), "ugrave"); - nameToUnicode.put("ugrave", new Character((char) 0x00f9)); - nameToEnc.put("ugrave", new Integer(157)); - encToName[157] = "ugrave"; - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x0076), "v"); - nameToUnicode.put("v", new Character((char) 0x0076)); - nameToEnc.put("v", new Integer(118)); - encToName[118] = "v"; - - unicodeToName.put(new Character((char) 0x0077), "w"); - nameToUnicode.put("w", new Character((char) 0x0077)); - nameToEnc.put("w", new Integer(119)); - encToName[119] = "w"; - - unicodeToName.put(new Character((char) 0x0078), "x"); - nameToUnicode.put("x", new Character((char) 0x0078)); - nameToEnc.put("x", new Integer(120)); - encToName[120] = "x"; - - unicodeToName.put(new Character((char) 0x0079), "y"); - nameToUnicode.put("y", new Character((char) 0x0079)); - nameToEnc.put("y", new Integer(121)); - encToName[121] = "y"; - - unicodeToName.put(new Character((char) 0x00fd), "yacute"); - nameToUnicode.put("yacute", new Character((char) 0x00fd)); - - unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); - nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); - nameToEnc.put("ydieresis", new Integer(216)); - encToName[216] = "ydieresis"; - - unicodeToName.put(new Character((char) 0x00a5), "yen"); - nameToUnicode.put("yen", new Character((char) 0x00a5)); - nameToEnc.put("yen", new Integer(180)); - encToName[180] = "yen"; - - unicodeToName.put(new Character((char) 0x007a), "z"); - nameToUnicode.put("z", new Character((char) 0x007a)); - nameToEnc.put("z", new Integer(122)); - encToName[122] = "z"; - - unicodeToName.put(new Character((char) 0x017e), "zcaron"); - nameToUnicode.put("zcaron", new Character((char) 0x017e)); - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Latin");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("MAC");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated MACLatin Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class MACLatin extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public MACLatin() { + unicodeToName.put(new Character((char) 0x0041), "A"); + nameToUnicode.put("A", new Character((char) 0x0041)); + nameToEnc.put("A", new Integer(65)); + encToName[65] = "A"; + + unicodeToName.put(new Character((char) 0x00c6), "AE"); + nameToUnicode.put("AE", new Character((char) 0x00c6)); + nameToEnc.put("AE", new Integer(174)); + encToName[174] = "AE"; + + unicodeToName.put(new Character((char) 0x00c1), "Aacute"); + nameToUnicode.put("Aacute", new Character((char) 0x00c1)); + nameToEnc.put("Aacute", new Integer(231)); + encToName[231] = "Aacute"; + + unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); + nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); + nameToEnc.put("Acircumflex", new Integer(229)); + encToName[229] = "Acircumflex"; + + unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); + nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); + nameToEnc.put("Adieresis", new Integer(128)); + encToName[128] = "Adieresis"; + + unicodeToName.put(new Character((char) 0x00c0), "Agrave"); + nameToUnicode.put("Agrave", new Character((char) 0x00c0)); + nameToEnc.put("Agrave", new Integer(203)); + encToName[203] = "Agrave"; + + unicodeToName.put(new Character((char) 0x00c5), "Aring"); + nameToUnicode.put("Aring", new Character((char) 0x00c5)); + nameToEnc.put("Aring", new Integer(129)); + encToName[129] = "Aring"; + + unicodeToName.put(new Character((char) 0x00c3), "Atilde"); + nameToUnicode.put("Atilde", new Character((char) 0x00c3)); + nameToEnc.put("Atilde", new Integer(204)); + encToName[204] = "Atilde"; + + unicodeToName.put(new Character((char) 0x0042), "B"); + nameToUnicode.put("B", new Character((char) 0x0042)); + nameToEnc.put("B", new Integer(66)); + encToName[66] = "B"; + + unicodeToName.put(new Character((char) 0x0043), "C"); + nameToUnicode.put("C", new Character((char) 0x0043)); + nameToEnc.put("C", new Integer(67)); + encToName[67] = "C"; + + unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); + nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); + nameToEnc.put("Ccedilla", new Integer(130)); + encToName[130] = "Ccedilla"; + + unicodeToName.put(new Character((char) 0x0044), "D"); + nameToUnicode.put("D", new Character((char) 0x0044)); + nameToEnc.put("D", new Integer(68)); + encToName[68] = "D"; + + unicodeToName.put(new Character((char) 0x0045), "E"); + nameToUnicode.put("E", new Character((char) 0x0045)); + nameToEnc.put("E", new Integer(69)); + encToName[69] = "E"; + + unicodeToName.put(new Character((char) 0x00c9), "Eacute"); + nameToUnicode.put("Eacute", new Character((char) 0x00c9)); + nameToEnc.put("Eacute", new Integer(131)); + encToName[131] = "Eacute"; + + unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); + nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); + nameToEnc.put("Ecircumflex", new Integer(230)); + encToName[230] = "Ecircumflex"; + + unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); + nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); + nameToEnc.put("Edieresis", new Integer(232)); + encToName[232] = "Edieresis"; + + unicodeToName.put(new Character((char) 0x00c8), "Egrave"); + nameToUnicode.put("Egrave", new Character((char) 0x00c8)); + nameToEnc.put("Egrave", new Integer(233)); + encToName[233] = "Egrave"; + + unicodeToName.put(new Character((char) 0x00d0), "Eth"); + nameToUnicode.put("Eth", new Character((char) 0x00d0)); + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + + unicodeToName.put(new Character((char) 0x0046), "F"); + nameToUnicode.put("F", new Character((char) 0x0046)); + nameToEnc.put("F", new Integer(70)); + encToName[70] = "F"; + + unicodeToName.put(new Character((char) 0x0047), "G"); + nameToUnicode.put("G", new Character((char) 0x0047)); + nameToEnc.put("G", new Integer(71)); + encToName[71] = "G"; + + unicodeToName.put(new Character((char) 0x0048), "H"); + nameToUnicode.put("H", new Character((char) 0x0048)); + nameToEnc.put("H", new Integer(72)); + encToName[72] = "H"; + + unicodeToName.put(new Character((char) 0x0049), "I"); + nameToUnicode.put("I", new Character((char) 0x0049)); + nameToEnc.put("I", new Integer(73)); + encToName[73] = "I"; + + unicodeToName.put(new Character((char) 0x00cd), "Iacute"); + nameToUnicode.put("Iacute", new Character((char) 0x00cd)); + nameToEnc.put("Iacute", new Integer(234)); + encToName[234] = "Iacute"; + + unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); + nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); + nameToEnc.put("Icircumflex", new Integer(235)); + encToName[235] = "Icircumflex"; + + unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); + nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); + nameToEnc.put("Idieresis", new Integer(236)); + encToName[236] = "Idieresis"; + + unicodeToName.put(new Character((char) 0x00cc), "Igrave"); + nameToUnicode.put("Igrave", new Character((char) 0x00cc)); + nameToEnc.put("Igrave", new Integer(237)); + encToName[237] = "Igrave"; + + unicodeToName.put(new Character((char) 0x004a), "J"); + nameToUnicode.put("J", new Character((char) 0x004a)); + nameToEnc.put("J", new Integer(74)); + encToName[74] = "J"; + + unicodeToName.put(new Character((char) 0x004b), "K"); + nameToUnicode.put("K", new Character((char) 0x004b)); + nameToEnc.put("K", new Integer(75)); + encToName[75] = "K"; + + unicodeToName.put(new Character((char) 0x004c), "L"); + nameToUnicode.put("L", new Character((char) 0x004c)); + nameToEnc.put("L", new Integer(76)); + encToName[76] = "L"; + + unicodeToName.put(new Character((char) 0x0141), "Lslash"); + nameToUnicode.put("Lslash", new Character((char) 0x0141)); + + unicodeToName.put(new Character((char) 0x004d), "M"); + nameToUnicode.put("M", new Character((char) 0x004d)); + nameToEnc.put("M", new Integer(77)); + encToName[77] = "M"; + + unicodeToName.put(new Character((char) 0x004e), "N"); + nameToUnicode.put("N", new Character((char) 0x004e)); + nameToEnc.put("N", new Integer(78)); + encToName[78] = "N"; + + unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); + nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); + nameToEnc.put("Ntilde", new Integer(132)); + encToName[132] = "Ntilde"; + + unicodeToName.put(new Character((char) 0x004f), "O"); + nameToUnicode.put("O", new Character((char) 0x004f)); + nameToEnc.put("O", new Integer(79)); + encToName[79] = "O"; + + unicodeToName.put(new Character((char) 0x0152), "OE"); + nameToUnicode.put("OE", new Character((char) 0x0152)); + nameToEnc.put("OE", new Integer(206)); + encToName[206] = "OE"; + + unicodeToName.put(new Character((char) 0x00d2), "Oacute"); + nameToUnicode.put("Oacute", new Character((char) 0x00d2)); + nameToEnc.put("Oacute", new Integer(238)); + encToName[238] = "Oacute"; + + unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); + nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); + nameToEnc.put("Ocircumflex", new Integer(239)); + encToName[239] = "Ocircumflex"; + + unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); + nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); + nameToEnc.put("Odieresis", new Integer(133)); + encToName[133] = "Odieresis"; + + unicodeToName.put(new Character((char) 0x00d3), "Ograve"); + nameToUnicode.put("Ograve", new Character((char) 0x00d3)); + nameToEnc.put("Ograve", new Integer(241)); + encToName[241] = "Ograve"; + + unicodeToName.put(new Character((char) 0x00d8), "Oslash"); + nameToUnicode.put("Oslash", new Character((char) 0x00d8)); + nameToEnc.put("Oslash", new Integer(175)); + encToName[175] = "Oslash"; + + unicodeToName.put(new Character((char) 0x00d5), "Otilde"); + nameToUnicode.put("Otilde", new Character((char) 0x00d5)); + nameToEnc.put("Otilde", new Integer(205)); + encToName[205] = "Otilde"; + + unicodeToName.put(new Character((char) 0x0050), "P"); + nameToUnicode.put("P", new Character((char) 0x0050)); + nameToEnc.put("P", new Integer(80)); + encToName[80] = "P"; + + unicodeToName.put(new Character((char) 0x0051), "Q"); + nameToUnicode.put("Q", new Character((char) 0x0051)); + nameToEnc.put("Q", new Integer(81)); + encToName[81] = "Q"; + + unicodeToName.put(new Character((char) 0x0052), "R"); + nameToUnicode.put("R", new Character((char) 0x0052)); + nameToEnc.put("R", new Integer(82)); + encToName[82] = "R"; + + unicodeToName.put(new Character((char) 0x0053), "S"); + nameToUnicode.put("S", new Character((char) 0x0053)); + nameToEnc.put("S", new Integer(83)); + encToName[83] = "S"; + + unicodeToName.put(new Character((char) 0x0160), "Scaron"); + nameToUnicode.put("Scaron", new Character((char) 0x0160)); + + unicodeToName.put(new Character((char) 0x0054), "T"); + nameToUnicode.put("T", new Character((char) 0x0054)); + nameToEnc.put("T", new Integer(84)); + encToName[84] = "T"; + + unicodeToName.put(new Character((char) 0x00de), "Thorn"); + nameToUnicode.put("Thorn", new Character((char) 0x00de)); + + unicodeToName.put(new Character((char) 0x0055), "U"); + nameToUnicode.put("U", new Character((char) 0x0055)); + nameToEnc.put("U", new Integer(85)); + encToName[85] = "U"; + + unicodeToName.put(new Character((char) 0x00da), "Uacute"); + nameToUnicode.put("Uacute", new Character((char) 0x00da)); + nameToEnc.put("Uacute", new Integer(242)); + encToName[242] = "Uacute"; + + unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); + nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); + nameToEnc.put("Ucircumflex", new Integer(243)); + encToName[243] = "Ucircumflex"; + + unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); + nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); + nameToEnc.put("Udieresis", new Integer(134)); + encToName[134] = "Udieresis"; + + unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); + nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); + nameToEnc.put("Ugrave", new Integer(244)); + encToName[244] = "Ugrave"; + + unicodeToName.put(new Character((char) 0x0056), "V"); + nameToUnicode.put("V", new Character((char) 0x0056)); + nameToEnc.put("V", new Integer(86)); + encToName[86] = "V"; + + unicodeToName.put(new Character((char) 0x0057), "W"); + nameToUnicode.put("W", new Character((char) 0x0057)); + nameToEnc.put("W", new Integer(87)); + encToName[87] = "W"; + + unicodeToName.put(new Character((char) 0x0058), "X"); + nameToUnicode.put("X", new Character((char) 0x0058)); + nameToEnc.put("X", new Integer(88)); + encToName[88] = "X"; + + unicodeToName.put(new Character((char) 0x0059), "Y"); + nameToUnicode.put("Y", new Character((char) 0x0059)); + nameToEnc.put("Y", new Integer(89)); + encToName[89] = "Y"; + + unicodeToName.put(new Character((char) 0x00dd), "Yacute"); + nameToUnicode.put("Yacute", new Character((char) 0x00dd)); + + unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); + nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); + nameToEnc.put("Ydieresis", new Integer(217)); + encToName[217] = "Ydieresis"; + + unicodeToName.put(new Character((char) 0x005a), "Z"); + nameToUnicode.put("Z", new Character((char) 0x005a)); + nameToEnc.put("Z", new Integer(90)); + encToName[90] = "Z"; + + unicodeToName.put(new Character((char) 0x017d), "Zcaron"); + nameToUnicode.put("Zcaron", new Character((char) 0x017d)); + + unicodeToName.put(new Character((char) 0x0061), "a"); + nameToUnicode.put("a", new Character((char) 0x0061)); + nameToEnc.put("a", new Integer(97)); + encToName[97] = "a"; + + unicodeToName.put(new Character((char) 0x00e1), "aacute"); + nameToUnicode.put("aacute", new Character((char) 0x00e1)); + nameToEnc.put("aacute", new Integer(135)); + encToName[135] = "aacute"; + + unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); + nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); + nameToEnc.put("acircumflex", new Integer(137)); + encToName[137] = "acircumflex"; + + unicodeToName.put(new Character((char) 0x00b4), "acute"); + nameToUnicode.put("acute", new Character((char) 0x00b4)); + nameToEnc.put("acute", new Integer(171)); + encToName[171] = "acute"; + + unicodeToName.put(new Character((char) 0x00e4), "adieresis"); + nameToUnicode.put("adieresis", new Character((char) 0x00e4)); + nameToEnc.put("adieresis", new Integer(138)); + encToName[138] = "adieresis"; + + unicodeToName.put(new Character((char) 0x00e6), "ae"); + nameToUnicode.put("ae", new Character((char) 0x00e6)); + nameToEnc.put("ae", new Integer(190)); + encToName[190] = "ae"; + + unicodeToName.put(new Character((char) 0x00e0), "agrave"); + nameToUnicode.put("agrave", new Character((char) 0x00e0)); + nameToEnc.put("agrave", new Integer(136)); + encToName[136] = "agrave"; + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x00e5), "aring"); + nameToUnicode.put("aring", new Character((char) 0x00e5)); + nameToEnc.put("aring", new Integer(140)); + encToName[140] = "aring"; + + unicodeToName.put(new Character((char) 0x005e), "asciicircum"); + nameToUnicode.put("asciicircum", new Character((char) 0x005e)); + nameToEnc.put("asciicircum", new Integer(94)); + encToName[94] = "asciicircum"; + + unicodeToName.put(new Character((char) 0x007e), "asciitilde"); + nameToUnicode.put("asciitilde", new Character((char) 0x007e)); + nameToEnc.put("asciitilde", new Integer(126)); + encToName[126] = "asciitilde"; + + unicodeToName.put(new Character((char) 0x002a), "asterisk"); + nameToUnicode.put("asterisk", new Character((char) 0x002a)); + nameToEnc.put("asterisk", new Integer(42)); + encToName[42] = "asterisk"; + + unicodeToName.put(new Character((char) 0x0040), "at"); + nameToUnicode.put("at", new Character((char) 0x0040)); + nameToEnc.put("at", new Integer(64)); + encToName[64] = "at"; + + unicodeToName.put(new Character((char) 0x00e3), "atilde"); + nameToUnicode.put("atilde", new Character((char) 0x00e3)); + nameToEnc.put("atilde", new Integer(139)); + encToName[139] = "atilde"; + + unicodeToName.put(new Character((char) 0x0062), "b"); + nameToUnicode.put("b", new Character((char) 0x0062)); + nameToEnc.put("b", new Integer(98)); + encToName[98] = "b"; + + unicodeToName.put(new Character((char) 0x005c), "backslash"); + nameToUnicode.put("backslash", new Character((char) 0x005c)); + nameToEnc.put("backslash", new Integer(92)); + encToName[92] = "backslash"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0x02d8), "breve"); + nameToUnicode.put("breve", new Character((char) 0x02d8)); + nameToEnc.put("breve", new Integer(249)); + encToName[249] = "breve"; + + unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); + nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); + + unicodeToName.put(new Character((char) 0x2022), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2022)); + nameToEnc.put("bullet", new Integer(165)); + encToName[165] = "bullet"; + + unicodeToName.put(new Character((char) 0x0063), "c"); + nameToUnicode.put("c", new Character((char) 0x0063)); + nameToEnc.put("c", new Integer(99)); + encToName[99] = "c"; + + unicodeToName.put(new Character((char) 0x02c7), "caron"); + nameToUnicode.put("caron", new Character((char) 0x02c7)); + nameToEnc.put("caron", new Integer(255)); + encToName[255] = "caron"; + + unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); + nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); + nameToEnc.put("ccedilla", new Integer(141)); + encToName[141] = "ccedilla"; + + unicodeToName.put(new Character((char) 0x00b8), "cedilla"); + nameToUnicode.put("cedilla", new Character((char) 0x00b8)); + nameToEnc.put("cedilla", new Integer(252)); + encToName[252] = "cedilla"; + + unicodeToName.put(new Character((char) 0x00a2), "cent"); + nameToUnicode.put("cent", new Character((char) 0x00a2)); + nameToEnc.put("cent", new Integer(162)); + encToName[162] = "cent"; + + unicodeToName.put(new Character((char) 0x02c6), "circumflex"); + nameToUnicode.put("circumflex", new Character((char) 0x02c6)); + nameToEnc.put("circumflex", new Integer(246)); + encToName[246] = "circumflex"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x00a9), "copyright"); + nameToUnicode.put("copyright", new Character((char) 0x00a9)); + nameToEnc.put("copyright", new Integer(169)); + encToName[169] = "copyright"; + + unicodeToName.put(new Character((char) 0x00a4), "currency"); + nameToUnicode.put("currency", new Character((char) 0x00a4)); + nameToEnc.put("currency", new Integer(219)); + encToName[219] = "currency"; + + unicodeToName.put(new Character((char) 0x0064), "d"); + nameToUnicode.put("d", new Character((char) 0x0064)); + nameToEnc.put("d", new Integer(100)); + encToName[100] = "d"; + + unicodeToName.put(new Character((char) 0x2020), "dagger"); + nameToUnicode.put("dagger", new Character((char) 0x2020)); + nameToEnc.put("dagger", new Integer(160)); + encToName[160] = "dagger"; + + unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); + nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); + nameToEnc.put("daggerdbl", new Integer(224)); + encToName[224] = "daggerdbl"; + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + nameToEnc.put("degree", new Integer(161)); + encToName[161] = "degree"; + + unicodeToName.put(new Character((char) 0x00a8), "dieresis"); + nameToUnicode.put("dieresis", new Character((char) 0x00a8)); + nameToEnc.put("dieresis", new Integer(172)); + encToName[172] = "dieresis"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + nameToEnc.put("divide", new Integer(214)); + encToName[214] = "divide"; + + unicodeToName.put(new Character((char) 0x0024), "dollar"); + nameToUnicode.put("dollar", new Character((char) 0x0024)); + nameToEnc.put("dollar", new Integer(36)); + encToName[36] = "dollar"; + + unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); + nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); + nameToEnc.put("dotaccent", new Integer(250)); + encToName[250] = "dotaccent"; + + unicodeToName.put(new Character((char) 0x0131), "dotlessi"); + nameToUnicode.put("dotlessi", new Character((char) 0x0131)); + nameToEnc.put("dotlessi", new Integer(245)); + encToName[245] = "dotlessi"; + + unicodeToName.put(new Character((char) 0x0065), "e"); + nameToUnicode.put("e", new Character((char) 0x0065)); + nameToEnc.put("e", new Integer(101)); + encToName[101] = "e"; + + unicodeToName.put(new Character((char) 0x00e9), "eacute"); + nameToUnicode.put("eacute", new Character((char) 0x00e9)); + nameToEnc.put("eacute", new Integer(142)); + encToName[142] = "eacute"; + + unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); + nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); + nameToEnc.put("ecircumflex", new Integer(144)); + encToName[144] = "ecircumflex"; + + unicodeToName.put(new Character((char) 0x00eb), "edieresis"); + nameToUnicode.put("edieresis", new Character((char) 0x00eb)); + nameToEnc.put("edieresis", new Integer(145)); + encToName[145] = "edieresis"; + + unicodeToName.put(new Character((char) 0x00e8), "egrave"); + nameToUnicode.put("egrave", new Character((char) 0x00e8)); + nameToEnc.put("egrave", new Integer(143)); + encToName[143] = "egrave"; + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + nameToEnc.put("ellipsis", new Integer(201)); + encToName[201] = "ellipsis"; + + unicodeToName.put(new Character((char) 0x002d), "emdash"); + nameToUnicode.put("emdash", new Character((char) 0x002d)); + nameToEnc.put("emdash", new Integer(209)); + encToName[209] = "emdash"; + + unicodeToName.put(new Character((char) 0x002d), "endash"); + nameToUnicode.put("endash", new Character((char) 0x002d)); + nameToEnc.put("endash", new Integer(208)); + encToName[208] = "endash"; + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x00f0), "eth"); + nameToUnicode.put("eth", new Character((char) 0x00f0)); + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); + nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); + nameToEnc.put("exclamdown", new Integer(193)); + encToName[193] = "exclamdown"; + + unicodeToName.put(new Character((char) 0x0066), "f"); + nameToUnicode.put("f", new Character((char) 0x0066)); + nameToEnc.put("f", new Integer(102)); + encToName[102] = "f"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + nameToEnc.put("fi", new Integer(222)); + encToName[222] = "fi"; + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + nameToEnc.put("fl", new Integer(223)); + encToName[223] = "fl"; + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + nameToEnc.put("florin", new Integer(196)); + encToName[196] = "florin"; + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + nameToEnc.put("fraction", new Integer(218)); + encToName[218] = "fraction"; + + unicodeToName.put(new Character((char) 0x0067), "g"); + nameToUnicode.put("g", new Character((char) 0x0067)); + nameToEnc.put("g", new Integer(103)); + encToName[103] = "g"; + + unicodeToName.put(new Character((char) 0x00df), "germandbls"); + nameToUnicode.put("germandbls", new Character((char) 0x00df)); + nameToEnc.put("germandbls", new Integer(167)); + encToName[167] = "germandbls"; + + unicodeToName.put(new Character((char) 0x0060), "grave"); + nameToUnicode.put("grave", new Character((char) 0x0060)); + nameToEnc.put("grave", new Integer(96)); + encToName[96] = "grave"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); + nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); + nameToEnc.put("guillemotleft", new Integer(199)); + encToName[199] = "guillemotleft"; + + unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); + nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); + nameToEnc.put("guillemotright", new Integer(200)); + encToName[200] = "guillemotright"; + + unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); + nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); + nameToEnc.put("guilsinglleft", new Integer(220)); + encToName[220] = "guilsinglleft"; + + unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); + nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); + nameToEnc.put("guilsinglright", new Integer(221)); + encToName[221] = "guilsinglright"; + + unicodeToName.put(new Character((char) 0x0068), "h"); + nameToUnicode.put("h", new Character((char) 0x0068)); + nameToEnc.put("h", new Integer(104)); + encToName[104] = "h"; + + unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); + nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); + nameToEnc.put("hungarumlaut", new Integer(253)); + encToName[253] = "hungarumlaut"; + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(45)); + encToName[45] = "hyphen"; + + unicodeToName.put(new Character((char) 0x0069), "i"); + nameToUnicode.put("i", new Character((char) 0x0069)); + nameToEnc.put("i", new Integer(105)); + encToName[105] = "i"; + + unicodeToName.put(new Character((char) 0x00ed), "iacute"); + nameToUnicode.put("iacute", new Character((char) 0x00ed)); + nameToEnc.put("iacute", new Integer(146)); + encToName[146] = "iacute"; + + unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); + nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); + nameToEnc.put("icircumflex", new Integer(148)); + encToName[148] = "icircumflex"; + + unicodeToName.put(new Character((char) 0x00ef), "idieresis"); + nameToUnicode.put("idieresis", new Character((char) 0x00ef)); + nameToEnc.put("idieresis", new Integer(149)); + encToName[149] = "idieresis"; + + unicodeToName.put(new Character((char) 0x00ec), "igrave"); + nameToUnicode.put("igrave", new Character((char) 0x00ec)); + nameToEnc.put("igrave", new Integer(147)); + encToName[147] = "igrave"; + + unicodeToName.put(new Character((char) 0x006a), "j"); + nameToUnicode.put("j", new Character((char) 0x006a)); + nameToEnc.put("j", new Integer(106)); + encToName[106] = "j"; + + unicodeToName.put(new Character((char) 0x006b), "k"); + nameToUnicode.put("k", new Character((char) 0x006b)); + nameToEnc.put("k", new Integer(107)); + encToName[107] = "k"; + + unicodeToName.put(new Character((char) 0x006c), "l"); + nameToUnicode.put("l", new Character((char) 0x006c)); + nameToEnc.put("l", new Integer(108)); + encToName[108] = "l"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + nameToEnc.put("logicalnot", new Integer(194)); + encToName[194] = "logicalnot"; + + unicodeToName.put(new Character((char) 0x0142), "lslash"); + nameToUnicode.put("lslash", new Character((char) 0x0142)); + + unicodeToName.put(new Character((char) 0x006d), "m"); + nameToUnicode.put("m", new Character((char) 0x006d)); + nameToEnc.put("m", new Integer(109)); + encToName[109] = "m"; + + unicodeToName.put(new Character((char) 0x00af), "macron"); + nameToUnicode.put("macron", new Character((char) 0x00af)); + nameToEnc.put("macron", new Integer(248)); + encToName[248] = "macron"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + nameToEnc.put("mu", new Integer(181)); + encToName[181] = "mu"; + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + + unicodeToName.put(new Character((char) 0x006e), "n"); + nameToUnicode.put("n", new Character((char) 0x006e)); + nameToEnc.put("n", new Integer(110)); + encToName[110] = "n"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x00f1), "ntilde"); + nameToUnicode.put("ntilde", new Character((char) 0x00f1)); + nameToEnc.put("ntilde", new Integer(150)); + encToName[150] = "ntilde"; + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x006f), "o"); + nameToUnicode.put("o", new Character((char) 0x006f)); + nameToEnc.put("o", new Integer(111)); + encToName[111] = "o"; + + unicodeToName.put(new Character((char) 0x00f3), "oacute"); + nameToUnicode.put("oacute", new Character((char) 0x00f3)); + nameToEnc.put("oacute", new Integer(151)); + encToName[151] = "oacute"; + + unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); + nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); + nameToEnc.put("ocircumflex", new Integer(153)); + encToName[153] = "ocircumflex"; + + unicodeToName.put(new Character((char) 0x00f6), "odieresis"); + nameToUnicode.put("odieresis", new Character((char) 0x00f6)); + nameToEnc.put("odieresis", new Integer(154)); + encToName[154] = "odieresis"; + + unicodeToName.put(new Character((char) 0x0153), "oe"); + nameToUnicode.put("oe", new Character((char) 0x0153)); + nameToEnc.put("oe", new Integer(207)); + encToName[207] = "oe"; + + unicodeToName.put(new Character((char) 0x02db), "ogonek"); + nameToUnicode.put("ogonek", new Character((char) 0x02db)); + nameToEnc.put("ogonek", new Integer(254)); + encToName[254] = "ogonek"; + + unicodeToName.put(new Character((char) 0x00f2), "ograve"); + nameToUnicode.put("ograve", new Character((char) 0x00f2)); + nameToEnc.put("ograve", new Integer(152)); + encToName[152] = "ograve"; + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + + unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); + nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); + nameToEnc.put("ordfeminine", new Integer(187)); + encToName[187] = "ordfeminine"; + + unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); + nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); + nameToEnc.put("ordmasculine", new Integer(188)); + encToName[188] = "ordmasculine"; + + unicodeToName.put(new Character((char) 0x00f8), "oslash"); + nameToUnicode.put("oslash", new Character((char) 0x00f8)); + nameToEnc.put("oslash", new Integer(191)); + encToName[191] = "oslash"; + + unicodeToName.put(new Character((char) 0x00f5), "otilde"); + nameToUnicode.put("otilde", new Character((char) 0x00f5)); + nameToEnc.put("otilde", new Integer(155)); + encToName[155] = "otilde"; + + unicodeToName.put(new Character((char) 0x0070), "p"); + nameToUnicode.put("p", new Character((char) 0x0070)); + nameToEnc.put("p", new Integer(112)); + encToName[112] = "p"; + + unicodeToName.put(new Character((char) 0x00b6), "paragraph"); + nameToUnicode.put("paragraph", new Character((char) 0x00b6)); + nameToEnc.put("paragraph", new Integer(166)); + encToName[166] = "paragraph"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); + nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); + nameToEnc.put("periodcentered", new Integer(225)); + encToName[225] = "periodcentered"; + + unicodeToName.put(new Character((char) 0x2030), "perthousand"); + nameToUnicode.put("perthousand", new Character((char) 0x2030)); + nameToEnc.put("perthousand", new Integer(228)); + encToName[228] = "perthousand"; + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + nameToEnc.put("plusminus", new Integer(177)); + encToName[177] = "plusminus"; + + unicodeToName.put(new Character((char) 0x0071), "q"); + nameToUnicode.put("q", new Character((char) 0x0071)); + nameToEnc.put("q", new Integer(113)); + encToName[113] = "q"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x00bf), "questiondown"); + nameToUnicode.put("questiondown", new Character((char) 0x00bf)); + nameToEnc.put("questiondown", new Integer(192)); + encToName[192] = "questiondown"; + + unicodeToName.put(new Character((char) 0x0022), "quotedbl"); + nameToUnicode.put("quotedbl", new Character((char) 0x0022)); + nameToEnc.put("quotedbl", new Integer(34)); + encToName[34] = "quotedbl"; + + unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); + nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); + nameToEnc.put("quotedblbase", new Integer(227)); + encToName[227] = "quotedblbase"; + + unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); + nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); + nameToEnc.put("quotedblleft", new Integer(210)); + encToName[210] = "quotedblleft"; + + unicodeToName.put(new Character((char) 0x201d), "quotedblright"); + nameToUnicode.put("quotedblright", new Character((char) 0x201d)); + nameToEnc.put("quotedblright", new Integer(211)); + encToName[211] = "quotedblright"; + + unicodeToName.put(new Character((char) 0x0060), "quoteleft"); + nameToUnicode.put("quoteleft", new Character((char) 0x0060)); + nameToEnc.put("quoteleft", new Integer(212)); + encToName[212] = "quoteleft"; + + unicodeToName.put(new Character((char) 0x0027), "quoteright"); + nameToUnicode.put("quoteright", new Character((char) 0x0027)); + nameToEnc.put("quoteright", new Integer(213)); + encToName[213] = "quoteright"; + + unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); + nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); + nameToEnc.put("quotesinglbase", new Integer(226)); + encToName[226] = "quotesinglbase"; + + unicodeToName.put(new Character((char) 0x0027), "quotesingle"); + nameToUnicode.put("quotesingle", new Character((char) 0x0027)); + nameToEnc.put("quotesingle", new Integer(39)); + encToName[39] = "quotesingle"; + + unicodeToName.put(new Character((char) 0x0072), "r"); + nameToUnicode.put("r", new Character((char) 0x0072)); + nameToEnc.put("r", new Integer(114)); + encToName[114] = "r"; + + unicodeToName.put(new Character((char) 0x00ae), "registered"); + nameToUnicode.put("registered", new Character((char) 0x00ae)); + nameToEnc.put("registered", new Integer(168)); + encToName[168] = "registered"; + + unicodeToName.put(new Character((char) 0x02da), "ring"); + nameToUnicode.put("ring", new Character((char) 0x02da)); + nameToEnc.put("ring", new Integer(251)); + encToName[251] = "ring"; + + unicodeToName.put(new Character((char) 0x0073), "s"); + nameToUnicode.put("s", new Character((char) 0x0073)); + nameToEnc.put("s", new Integer(115)); + encToName[115] = "s"; + + unicodeToName.put(new Character((char) 0x0161), "scaron"); + nameToUnicode.put("scaron", new Character((char) 0x0161)); + + unicodeToName.put(new Character((char) 0x00a7), "section"); + nameToUnicode.put("section", new Character((char) 0x00a7)); + nameToEnc.put("section", new Integer(164)); + encToName[164] = "section"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x00a3), "sterling"); + nameToUnicode.put("sterling", new Character((char) 0x00a3)); + nameToEnc.put("sterling", new Integer(163)); + encToName[163] = "sterling"; + + unicodeToName.put(new Character((char) 0x0074), "t"); + nameToUnicode.put("t", new Character((char) 0x0074)); + nameToEnc.put("t", new Integer(116)); + encToName[116] = "t"; + + unicodeToName.put(new Character((char) 0x00fe), "thorn"); + nameToUnicode.put("thorn", new Character((char) 0x00fe)); + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + + unicodeToName.put(new Character((char) 0x02dc), "tilde"); + nameToUnicode.put("tilde", new Character((char) 0x02dc)); + nameToEnc.put("tilde", new Integer(247)); + encToName[247] = "tilde"; + + unicodeToName.put(new Character((char) 0x2122), "trademark"); + nameToUnicode.put("trademark", new Character((char) 0x2122)); + nameToEnc.put("trademark", new Integer(170)); + encToName[170] = "trademark"; + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + + unicodeToName.put(new Character((char) 0x0075), "u"); + nameToUnicode.put("u", new Character((char) 0x0075)); + nameToEnc.put("u", new Integer(117)); + encToName[117] = "u"; + + unicodeToName.put(new Character((char) 0x00fa), "uacute"); + nameToUnicode.put("uacute", new Character((char) 0x00fa)); + nameToEnc.put("uacute", new Integer(156)); + encToName[156] = "uacute"; + + unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); + nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); + nameToEnc.put("ucircumflex", new Integer(158)); + encToName[158] = "ucircumflex"; + + unicodeToName.put(new Character((char) 0x00fc), "udieresis"); + nameToUnicode.put("udieresis", new Character((char) 0x00fc)); + nameToEnc.put("udieresis", new Integer(159)); + encToName[159] = "udieresis"; + + unicodeToName.put(new Character((char) 0x00f9), "ugrave"); + nameToUnicode.put("ugrave", new Character((char) 0x00f9)); + nameToEnc.put("ugrave", new Integer(157)); + encToName[157] = "ugrave"; + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x0076), "v"); + nameToUnicode.put("v", new Character((char) 0x0076)); + nameToEnc.put("v", new Integer(118)); + encToName[118] = "v"; + + unicodeToName.put(new Character((char) 0x0077), "w"); + nameToUnicode.put("w", new Character((char) 0x0077)); + nameToEnc.put("w", new Integer(119)); + encToName[119] = "w"; + + unicodeToName.put(new Character((char) 0x0078), "x"); + nameToUnicode.put("x", new Character((char) 0x0078)); + nameToEnc.put("x", new Integer(120)); + encToName[120] = "x"; + + unicodeToName.put(new Character((char) 0x0079), "y"); + nameToUnicode.put("y", new Character((char) 0x0079)); + nameToEnc.put("y", new Integer(121)); + encToName[121] = "y"; + + unicodeToName.put(new Character((char) 0x00fd), "yacute"); + nameToUnicode.put("yacute", new Character((char) 0x00fd)); + + unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); + nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); + nameToEnc.put("ydieresis", new Integer(216)); + encToName[216] = "ydieresis"; + + unicodeToName.put(new Character((char) 0x00a5), "yen"); + nameToUnicode.put("yen", new Character((char) 0x00a5)); + nameToEnc.put("yen", new Integer(180)); + encToName[180] = "yen"; + + unicodeToName.put(new Character((char) 0x007a), "z"); + nameToUnicode.put("z", new Character((char) 0x007a)); + nameToEnc.put("z", new Integer(122)); + encToName[122] = "z"; + + unicodeToName.put(new Character((char) 0x017e), "zcaron"); + nameToUnicode.put("zcaron", new Character((char) 0x017e)); + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Latin");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("MAC");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/PDFLatin.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/PDFLatin.java index 6d42c0bed..48226d507 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/PDFLatin.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/PDFLatin.java @@ -1,1194 +1,1194 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated PDFLatin Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class PDFLatin extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public PDFLatin() { - unicodeToName.put(new Character((char) 0x0041), "A"); - nameToUnicode.put("A", new Character((char) 0x0041)); - nameToEnc.put("A", new Integer(65)); - encToName[65] = "A"; - - unicodeToName.put(new Character((char) 0x00c6), "AE"); - nameToUnicode.put("AE", new Character((char) 0x00c6)); - nameToEnc.put("AE", new Integer(198)); - encToName[198] = "AE"; - - unicodeToName.put(new Character((char) 0x00c1), "Aacute"); - nameToUnicode.put("Aacute", new Character((char) 0x00c1)); - nameToEnc.put("Aacute", new Integer(193)); - encToName[193] = "Aacute"; - - unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); - nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); - nameToEnc.put("Acircumflex", new Integer(194)); - encToName[194] = "Acircumflex"; - - unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); - nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); - nameToEnc.put("Adieresis", new Integer(196)); - encToName[196] = "Adieresis"; - - unicodeToName.put(new Character((char) 0x00c0), "Agrave"); - nameToUnicode.put("Agrave", new Character((char) 0x00c0)); - nameToEnc.put("Agrave", new Integer(192)); - encToName[192] = "Agrave"; - - unicodeToName.put(new Character((char) 0x00c5), "Aring"); - nameToUnicode.put("Aring", new Character((char) 0x00c5)); - nameToEnc.put("Aring", new Integer(197)); - encToName[197] = "Aring"; - - unicodeToName.put(new Character((char) 0x00c3), "Atilde"); - nameToUnicode.put("Atilde", new Character((char) 0x00c3)); - nameToEnc.put("Atilde", new Integer(195)); - encToName[195] = "Atilde"; - - unicodeToName.put(new Character((char) 0x0042), "B"); - nameToUnicode.put("B", new Character((char) 0x0042)); - nameToEnc.put("B", new Integer(66)); - encToName[66] = "B"; - - unicodeToName.put(new Character((char) 0x0043), "C"); - nameToUnicode.put("C", new Character((char) 0x0043)); - nameToEnc.put("C", new Integer(67)); - encToName[67] = "C"; - - unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); - nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); - nameToEnc.put("Ccedilla", new Integer(199)); - encToName[199] = "Ccedilla"; - - unicodeToName.put(new Character((char) 0x0044), "D"); - nameToUnicode.put("D", new Character((char) 0x0044)); - nameToEnc.put("D", new Integer(68)); - encToName[68] = "D"; - - unicodeToName.put(new Character((char) 0x0045), "E"); - nameToUnicode.put("E", new Character((char) 0x0045)); - nameToEnc.put("E", new Integer(69)); - encToName[69] = "E"; - - unicodeToName.put(new Character((char) 0x00c9), "Eacute"); - nameToUnicode.put("Eacute", new Character((char) 0x00c9)); - nameToEnc.put("Eacute", new Integer(201)); - encToName[201] = "Eacute"; - - unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); - nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); - nameToEnc.put("Ecircumflex", new Integer(202)); - encToName[202] = "Ecircumflex"; - - unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); - nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); - nameToEnc.put("Edieresis", new Integer(203)); - encToName[203] = "Edieresis"; - - unicodeToName.put(new Character((char) 0x00c8), "Egrave"); - nameToUnicode.put("Egrave", new Character((char) 0x00c8)); - nameToEnc.put("Egrave", new Integer(200)); - encToName[200] = "Egrave"; - - unicodeToName.put(new Character((char) 0x00d0), "Eth"); - nameToUnicode.put("Eth", new Character((char) 0x00d0)); - nameToEnc.put("Eth", new Integer(208)); - encToName[208] = "Eth"; - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - nameToEnc.put("Euro", new Integer(160)); - encToName[160] = "Euro"; - - unicodeToName.put(new Character((char) 0x0046), "F"); - nameToUnicode.put("F", new Character((char) 0x0046)); - nameToEnc.put("F", new Integer(70)); - encToName[70] = "F"; - - unicodeToName.put(new Character((char) 0x0047), "G"); - nameToUnicode.put("G", new Character((char) 0x0047)); - nameToEnc.put("G", new Integer(71)); - encToName[71] = "G"; - - unicodeToName.put(new Character((char) 0x0048), "H"); - nameToUnicode.put("H", new Character((char) 0x0048)); - nameToEnc.put("H", new Integer(72)); - encToName[72] = "H"; - - unicodeToName.put(new Character((char) 0x0049), "I"); - nameToUnicode.put("I", new Character((char) 0x0049)); - nameToEnc.put("I", new Integer(73)); - encToName[73] = "I"; - - unicodeToName.put(new Character((char) 0x00cd), "Iacute"); - nameToUnicode.put("Iacute", new Character((char) 0x00cd)); - nameToEnc.put("Iacute", new Integer(205)); - encToName[205] = "Iacute"; - - unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); - nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); - nameToEnc.put("Icircumflex", new Integer(206)); - encToName[206] = "Icircumflex"; - - unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); - nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); - nameToEnc.put("Idieresis", new Integer(207)); - encToName[207] = "Idieresis"; - - unicodeToName.put(new Character((char) 0x00cc), "Igrave"); - nameToUnicode.put("Igrave", new Character((char) 0x00cc)); - nameToEnc.put("Igrave", new Integer(204)); - encToName[204] = "Igrave"; - - unicodeToName.put(new Character((char) 0x004a), "J"); - nameToUnicode.put("J", new Character((char) 0x004a)); - nameToEnc.put("J", new Integer(74)); - encToName[74] = "J"; - - unicodeToName.put(new Character((char) 0x004b), "K"); - nameToUnicode.put("K", new Character((char) 0x004b)); - nameToEnc.put("K", new Integer(75)); - encToName[75] = "K"; - - unicodeToName.put(new Character((char) 0x004c), "L"); - nameToUnicode.put("L", new Character((char) 0x004c)); - nameToEnc.put("L", new Integer(76)); - encToName[76] = "L"; - - unicodeToName.put(new Character((char) 0x0141), "Lslash"); - nameToUnicode.put("Lslash", new Character((char) 0x0141)); - nameToEnc.put("Lslash", new Integer(149)); - encToName[149] = "Lslash"; - - unicodeToName.put(new Character((char) 0x004d), "M"); - nameToUnicode.put("M", new Character((char) 0x004d)); - nameToEnc.put("M", new Integer(77)); - encToName[77] = "M"; - - unicodeToName.put(new Character((char) 0x004e), "N"); - nameToUnicode.put("N", new Character((char) 0x004e)); - nameToEnc.put("N", new Integer(78)); - encToName[78] = "N"; - - unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); - nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); - nameToEnc.put("Ntilde", new Integer(209)); - encToName[209] = "Ntilde"; - - unicodeToName.put(new Character((char) 0x004f), "O"); - nameToUnicode.put("O", new Character((char) 0x004f)); - nameToEnc.put("O", new Integer(79)); - encToName[79] = "O"; - - unicodeToName.put(new Character((char) 0x0152), "OE"); - nameToUnicode.put("OE", new Character((char) 0x0152)); - nameToEnc.put("OE", new Integer(150)); - encToName[150] = "OE"; - - unicodeToName.put(new Character((char) 0x00d2), "Oacute"); - nameToUnicode.put("Oacute", new Character((char) 0x00d2)); - nameToEnc.put("Oacute", new Integer(211)); - encToName[211] = "Oacute"; - - unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); - nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); - nameToEnc.put("Ocircumflex", new Integer(212)); - encToName[212] = "Ocircumflex"; - - unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); - nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); - nameToEnc.put("Odieresis", new Integer(214)); - encToName[214] = "Odieresis"; - - unicodeToName.put(new Character((char) 0x00d3), "Ograve"); - nameToUnicode.put("Ograve", new Character((char) 0x00d3)); - nameToEnc.put("Ograve", new Integer(210)); - encToName[210] = "Ograve"; - - unicodeToName.put(new Character((char) 0x00d8), "Oslash"); - nameToUnicode.put("Oslash", new Character((char) 0x00d8)); - nameToEnc.put("Oslash", new Integer(216)); - encToName[216] = "Oslash"; - - unicodeToName.put(new Character((char) 0x00d5), "Otilde"); - nameToUnicode.put("Otilde", new Character((char) 0x00d5)); - nameToEnc.put("Otilde", new Integer(213)); - encToName[213] = "Otilde"; - - unicodeToName.put(new Character((char) 0x0050), "P"); - nameToUnicode.put("P", new Character((char) 0x0050)); - nameToEnc.put("P", new Integer(80)); - encToName[80] = "P"; - - unicodeToName.put(new Character((char) 0x0051), "Q"); - nameToUnicode.put("Q", new Character((char) 0x0051)); - nameToEnc.put("Q", new Integer(81)); - encToName[81] = "Q"; - - unicodeToName.put(new Character((char) 0x0052), "R"); - nameToUnicode.put("R", new Character((char) 0x0052)); - nameToEnc.put("R", new Integer(82)); - encToName[82] = "R"; - - unicodeToName.put(new Character((char) 0x0053), "S"); - nameToUnicode.put("S", new Character((char) 0x0053)); - nameToEnc.put("S", new Integer(83)); - encToName[83] = "S"; - - unicodeToName.put(new Character((char) 0x0160), "Scaron"); - nameToUnicode.put("Scaron", new Character((char) 0x0160)); - nameToEnc.put("Scaron", new Integer(151)); - encToName[151] = "Scaron"; - - unicodeToName.put(new Character((char) 0x0054), "T"); - nameToUnicode.put("T", new Character((char) 0x0054)); - nameToEnc.put("T", new Integer(84)); - encToName[84] = "T"; - - unicodeToName.put(new Character((char) 0x00de), "Thorn"); - nameToUnicode.put("Thorn", new Character((char) 0x00de)); - nameToEnc.put("Thorn", new Integer(222)); - encToName[222] = "Thorn"; - - unicodeToName.put(new Character((char) 0x0055), "U"); - nameToUnicode.put("U", new Character((char) 0x0055)); - nameToEnc.put("U", new Integer(85)); - encToName[85] = "U"; - - unicodeToName.put(new Character((char) 0x00da), "Uacute"); - nameToUnicode.put("Uacute", new Character((char) 0x00da)); - nameToEnc.put("Uacute", new Integer(218)); - encToName[218] = "Uacute"; - - unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); - nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); - nameToEnc.put("Ucircumflex", new Integer(219)); - encToName[219] = "Ucircumflex"; - - unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); - nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); - nameToEnc.put("Udieresis", new Integer(220)); - encToName[220] = "Udieresis"; - - unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); - nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); - nameToEnc.put("Ugrave", new Integer(217)); - encToName[217] = "Ugrave"; - - unicodeToName.put(new Character((char) 0x0056), "V"); - nameToUnicode.put("V", new Character((char) 0x0056)); - nameToEnc.put("V", new Integer(86)); - encToName[86] = "V"; - - unicodeToName.put(new Character((char) 0x0057), "W"); - nameToUnicode.put("W", new Character((char) 0x0057)); - nameToEnc.put("W", new Integer(87)); - encToName[87] = "W"; - - unicodeToName.put(new Character((char) 0x0058), "X"); - nameToUnicode.put("X", new Character((char) 0x0058)); - nameToEnc.put("X", new Integer(88)); - encToName[88] = "X"; - - unicodeToName.put(new Character((char) 0x0059), "Y"); - nameToUnicode.put("Y", new Character((char) 0x0059)); - nameToEnc.put("Y", new Integer(89)); - encToName[89] = "Y"; - - unicodeToName.put(new Character((char) 0x00dd), "Yacute"); - nameToUnicode.put("Yacute", new Character((char) 0x00dd)); - nameToEnc.put("Yacute", new Integer(221)); - encToName[221] = "Yacute"; - - unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); - nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); - nameToEnc.put("Ydieresis", new Integer(152)); - encToName[152] = "Ydieresis"; - - unicodeToName.put(new Character((char) 0x005a), "Z"); - nameToUnicode.put("Z", new Character((char) 0x005a)); - nameToEnc.put("Z", new Integer(90)); - encToName[90] = "Z"; - - unicodeToName.put(new Character((char) 0x017d), "Zcaron"); - nameToUnicode.put("Zcaron", new Character((char) 0x017d)); - nameToEnc.put("Zcaron", new Integer(153)); - encToName[153] = "Zcaron"; - - unicodeToName.put(new Character((char) 0x0061), "a"); - nameToUnicode.put("a", new Character((char) 0x0061)); - nameToEnc.put("a", new Integer(97)); - encToName[97] = "a"; - - unicodeToName.put(new Character((char) 0x00e1), "aacute"); - nameToUnicode.put("aacute", new Character((char) 0x00e1)); - nameToEnc.put("aacute", new Integer(225)); - encToName[225] = "aacute"; - - unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); - nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); - nameToEnc.put("acircumflex", new Integer(226)); - encToName[226] = "acircumflex"; - - unicodeToName.put(new Character((char) 0x00b4), "acute"); - nameToUnicode.put("acute", new Character((char) 0x00b4)); - nameToEnc.put("acute", new Integer(180)); - encToName[180] = "acute"; - - unicodeToName.put(new Character((char) 0x00e4), "adieresis"); - nameToUnicode.put("adieresis", new Character((char) 0x00e4)); - nameToEnc.put("adieresis", new Integer(228)); - encToName[228] = "adieresis"; - - unicodeToName.put(new Character((char) 0x00e6), "ae"); - nameToUnicode.put("ae", new Character((char) 0x00e6)); - nameToEnc.put("ae", new Integer(230)); - encToName[230] = "ae"; - - unicodeToName.put(new Character((char) 0x00e0), "agrave"); - nameToUnicode.put("agrave", new Character((char) 0x00e0)); - nameToEnc.put("agrave", new Integer(224)); - encToName[224] = "agrave"; - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x00e5), "aring"); - nameToUnicode.put("aring", new Character((char) 0x00e5)); - nameToEnc.put("aring", new Integer(229)); - encToName[229] = "aring"; - - unicodeToName.put(new Character((char) 0x005e), "asciicircum"); - nameToUnicode.put("asciicircum", new Character((char) 0x005e)); - nameToEnc.put("asciicircum", new Integer(94)); - encToName[94] = "asciicircum"; - - unicodeToName.put(new Character((char) 0x007e), "asciitilde"); - nameToUnicode.put("asciitilde", new Character((char) 0x007e)); - nameToEnc.put("asciitilde", new Integer(126)); - encToName[126] = "asciitilde"; - - unicodeToName.put(new Character((char) 0x002a), "asterisk"); - nameToUnicode.put("asterisk", new Character((char) 0x002a)); - nameToEnc.put("asterisk", new Integer(42)); - encToName[42] = "asterisk"; - - unicodeToName.put(new Character((char) 0x0040), "at"); - nameToUnicode.put("at", new Character((char) 0x0040)); - nameToEnc.put("at", new Integer(64)); - encToName[64] = "at"; - - unicodeToName.put(new Character((char) 0x00e3), "atilde"); - nameToUnicode.put("atilde", new Character((char) 0x00e3)); - nameToEnc.put("atilde", new Integer(227)); - encToName[227] = "atilde"; - - unicodeToName.put(new Character((char) 0x0062), "b"); - nameToUnicode.put("b", new Character((char) 0x0062)); - nameToEnc.put("b", new Integer(98)); - encToName[98] = "b"; - - unicodeToName.put(new Character((char) 0x005c), "backslash"); - nameToUnicode.put("backslash", new Character((char) 0x005c)); - nameToEnc.put("backslash", new Integer(92)); - encToName[92] = "backslash"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0x02d8), "breve"); - nameToUnicode.put("breve", new Character((char) 0x02d8)); - nameToEnc.put("breve", new Integer(24)); - encToName[24] = "breve"; - - unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); - nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); - nameToEnc.put("brokenbar", new Integer(166)); - encToName[166] = "brokenbar"; - - unicodeToName.put(new Character((char) 0x2022), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2022)); - nameToEnc.put("bullet", new Integer(128)); - encToName[128] = "bullet"; - - unicodeToName.put(new Character((char) 0x0063), "c"); - nameToUnicode.put("c", new Character((char) 0x0063)); - nameToEnc.put("c", new Integer(99)); - encToName[99] = "c"; - - unicodeToName.put(new Character((char) 0x02c7), "caron"); - nameToUnicode.put("caron", new Character((char) 0x02c7)); - nameToEnc.put("caron", new Integer(25)); - encToName[25] = "caron"; - - unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); - nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); - nameToEnc.put("ccedilla", new Integer(231)); - encToName[231] = "ccedilla"; - - unicodeToName.put(new Character((char) 0x00b8), "cedilla"); - nameToUnicode.put("cedilla", new Character((char) 0x00b8)); - nameToEnc.put("cedilla", new Integer(184)); - encToName[184] = "cedilla"; - - unicodeToName.put(new Character((char) 0x00a2), "cent"); - nameToUnicode.put("cent", new Character((char) 0x00a2)); - nameToEnc.put("cent", new Integer(162)); - encToName[162] = "cent"; - - unicodeToName.put(new Character((char) 0x02c6), "circumflex"); - nameToUnicode.put("circumflex", new Character((char) 0x02c6)); - nameToEnc.put("circumflex", new Integer(26)); - encToName[26] = "circumflex"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x00a9), "copyright"); - nameToUnicode.put("copyright", new Character((char) 0x00a9)); - nameToEnc.put("copyright", new Integer(169)); - encToName[169] = "copyright"; - - unicodeToName.put(new Character((char) 0x00a4), "currency"); - nameToUnicode.put("currency", new Character((char) 0x00a4)); - nameToEnc.put("currency", new Integer(164)); - encToName[164] = "currency"; - - unicodeToName.put(new Character((char) 0x0064), "d"); - nameToUnicode.put("d", new Character((char) 0x0064)); - nameToEnc.put("d", new Integer(100)); - encToName[100] = "d"; - - unicodeToName.put(new Character((char) 0x2020), "dagger"); - nameToUnicode.put("dagger", new Character((char) 0x2020)); - nameToEnc.put("dagger", new Integer(129)); - encToName[129] = "dagger"; - - unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); - nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); - nameToEnc.put("daggerdbl", new Integer(130)); - encToName[130] = "daggerdbl"; - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - nameToEnc.put("degree", new Integer(176)); - encToName[176] = "degree"; - - unicodeToName.put(new Character((char) 0x00a8), "dieresis"); - nameToUnicode.put("dieresis", new Character((char) 0x00a8)); - nameToEnc.put("dieresis", new Integer(168)); - encToName[168] = "dieresis"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - nameToEnc.put("divide", new Integer(247)); - encToName[247] = "divide"; - - unicodeToName.put(new Character((char) 0x0024), "dollar"); - nameToUnicode.put("dollar", new Character((char) 0x0024)); - nameToEnc.put("dollar", new Integer(36)); - encToName[36] = "dollar"; - - unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); - nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); - nameToEnc.put("dotaccent", new Integer(27)); - encToName[27] = "dotaccent"; - - unicodeToName.put(new Character((char) 0x0131), "dotlessi"); - nameToUnicode.put("dotlessi", new Character((char) 0x0131)); - nameToEnc.put("dotlessi", new Integer(154)); - encToName[154] = "dotlessi"; - - unicodeToName.put(new Character((char) 0x0065), "e"); - nameToUnicode.put("e", new Character((char) 0x0065)); - nameToEnc.put("e", new Integer(101)); - encToName[101] = "e"; - - unicodeToName.put(new Character((char) 0x00e9), "eacute"); - nameToUnicode.put("eacute", new Character((char) 0x00e9)); - nameToEnc.put("eacute", new Integer(233)); - encToName[233] = "eacute"; - - unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); - nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); - nameToEnc.put("ecircumflex", new Integer(234)); - encToName[234] = "ecircumflex"; - - unicodeToName.put(new Character((char) 0x00eb), "edieresis"); - nameToUnicode.put("edieresis", new Character((char) 0x00eb)); - nameToEnc.put("edieresis", new Integer(235)); - encToName[235] = "edieresis"; - - unicodeToName.put(new Character((char) 0x00e8), "egrave"); - nameToUnicode.put("egrave", new Character((char) 0x00e8)); - nameToEnc.put("egrave", new Integer(232)); - encToName[232] = "egrave"; - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - nameToEnc.put("ellipsis", new Integer(131)); - encToName[131] = "ellipsis"; - - unicodeToName.put(new Character((char) 0x002d), "emdash"); - nameToUnicode.put("emdash", new Character((char) 0x002d)); - nameToEnc.put("emdash", new Integer(132)); - encToName[132] = "emdash"; - - unicodeToName.put(new Character((char) 0x002d), "endash"); - nameToUnicode.put("endash", new Character((char) 0x002d)); - nameToEnc.put("endash", new Integer(133)); - encToName[133] = "endash"; - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x00f0), "eth"); - nameToUnicode.put("eth", new Character((char) 0x00f0)); - nameToEnc.put("eth", new Integer(240)); - encToName[240] = "eth"; - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); - nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); - nameToEnc.put("exclamdown", new Integer(161)); - encToName[161] = "exclamdown"; - - unicodeToName.put(new Character((char) 0x0066), "f"); - nameToUnicode.put("f", new Character((char) 0x0066)); - nameToEnc.put("f", new Integer(102)); - encToName[102] = "f"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - nameToEnc.put("fi", new Integer(147)); - encToName[147] = "fi"; - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - nameToEnc.put("fl", new Integer(148)); - encToName[148] = "fl"; - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - nameToEnc.put("florin", new Integer(134)); - encToName[134] = "florin"; - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - nameToEnc.put("fraction", new Integer(135)); - encToName[135] = "fraction"; - - unicodeToName.put(new Character((char) 0x0067), "g"); - nameToUnicode.put("g", new Character((char) 0x0067)); - nameToEnc.put("g", new Integer(103)); - encToName[103] = "g"; - - unicodeToName.put(new Character((char) 0x00df), "germandbls"); - nameToUnicode.put("germandbls", new Character((char) 0x00df)); - nameToEnc.put("germandbls", new Integer(223)); - encToName[223] = "germandbls"; - - unicodeToName.put(new Character((char) 0x0060), "grave"); - nameToUnicode.put("grave", new Character((char) 0x0060)); - nameToEnc.put("grave", new Integer(96)); - encToName[96] = "grave"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); - nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); - nameToEnc.put("guillemotleft", new Integer(171)); - encToName[171] = "guillemotleft"; - - unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); - nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); - nameToEnc.put("guillemotright", new Integer(187)); - encToName[187] = "guillemotright"; - - unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); - nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); - nameToEnc.put("guilsinglleft", new Integer(136)); - encToName[136] = "guilsinglleft"; - - unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); - nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); - nameToEnc.put("guilsinglright", new Integer(137)); - encToName[137] = "guilsinglright"; - - unicodeToName.put(new Character((char) 0x0068), "h"); - nameToUnicode.put("h", new Character((char) 0x0068)); - nameToEnc.put("h", new Integer(104)); - encToName[104] = "h"; - - unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); - nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); - nameToEnc.put("hungarumlaut", new Integer(28)); - encToName[28] = "hungarumlaut"; - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(45)); - encToName[45] = "hyphen"; - - unicodeToName.put(new Character((char) 0x0069), "i"); - nameToUnicode.put("i", new Character((char) 0x0069)); - nameToEnc.put("i", new Integer(105)); - encToName[105] = "i"; - - unicodeToName.put(new Character((char) 0x00ed), "iacute"); - nameToUnicode.put("iacute", new Character((char) 0x00ed)); - nameToEnc.put("iacute", new Integer(237)); - encToName[237] = "iacute"; - - unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); - nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); - nameToEnc.put("icircumflex", new Integer(238)); - encToName[238] = "icircumflex"; - - unicodeToName.put(new Character((char) 0x00ef), "idieresis"); - nameToUnicode.put("idieresis", new Character((char) 0x00ef)); - nameToEnc.put("idieresis", new Integer(239)); - encToName[239] = "idieresis"; - - unicodeToName.put(new Character((char) 0x00ec), "igrave"); - nameToUnicode.put("igrave", new Character((char) 0x00ec)); - nameToEnc.put("igrave", new Integer(236)); - encToName[236] = "igrave"; - - unicodeToName.put(new Character((char) 0x006a), "j"); - nameToUnicode.put("j", new Character((char) 0x006a)); - nameToEnc.put("j", new Integer(106)); - encToName[106] = "j"; - - unicodeToName.put(new Character((char) 0x006b), "k"); - nameToUnicode.put("k", new Character((char) 0x006b)); - nameToEnc.put("k", new Integer(107)); - encToName[107] = "k"; - - unicodeToName.put(new Character((char) 0x006c), "l"); - nameToUnicode.put("l", new Character((char) 0x006c)); - nameToEnc.put("l", new Integer(108)); - encToName[108] = "l"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - nameToEnc.put("logicalnot", new Integer(172)); - encToName[172] = "logicalnot"; - - unicodeToName.put(new Character((char) 0x0142), "lslash"); - nameToUnicode.put("lslash", new Character((char) 0x0142)); - nameToEnc.put("lslash", new Integer(155)); - encToName[155] = "lslash"; - - unicodeToName.put(new Character((char) 0x006d), "m"); - nameToUnicode.put("m", new Character((char) 0x006d)); - nameToEnc.put("m", new Integer(109)); - encToName[109] = "m"; - - unicodeToName.put(new Character((char) 0x00af), "macron"); - nameToUnicode.put("macron", new Character((char) 0x00af)); - nameToEnc.put("macron", new Integer(175)); - encToName[175] = "macron"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - nameToEnc.put("minus", new Integer(138)); - encToName[138] = "minus"; - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - nameToEnc.put("mu", new Integer(181)); - encToName[181] = "mu"; - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - nameToEnc.put("multiply", new Integer(215)); - encToName[215] = "multiply"; - - unicodeToName.put(new Character((char) 0x006e), "n"); - nameToUnicode.put("n", new Character((char) 0x006e)); - nameToEnc.put("n", new Integer(110)); - encToName[110] = "n"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x00f1), "ntilde"); - nameToUnicode.put("ntilde", new Character((char) 0x00f1)); - nameToEnc.put("ntilde", new Integer(241)); - encToName[241] = "ntilde"; - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x006f), "o"); - nameToUnicode.put("o", new Character((char) 0x006f)); - nameToEnc.put("o", new Integer(111)); - encToName[111] = "o"; - - unicodeToName.put(new Character((char) 0x00f3), "oacute"); - nameToUnicode.put("oacute", new Character((char) 0x00f3)); - nameToEnc.put("oacute", new Integer(243)); - encToName[243] = "oacute"; - - unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); - nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); - nameToEnc.put("ocircumflex", new Integer(244)); - encToName[244] = "ocircumflex"; - - unicodeToName.put(new Character((char) 0x00f6), "odieresis"); - nameToUnicode.put("odieresis", new Character((char) 0x00f6)); - nameToEnc.put("odieresis", new Integer(246)); - encToName[246] = "odieresis"; - - unicodeToName.put(new Character((char) 0x0153), "oe"); - nameToUnicode.put("oe", new Character((char) 0x0153)); - nameToEnc.put("oe", new Integer(156)); - encToName[156] = "oe"; - - unicodeToName.put(new Character((char) 0x02db), "ogonek"); - nameToUnicode.put("ogonek", new Character((char) 0x02db)); - nameToEnc.put("ogonek", new Integer(29)); - encToName[29] = "ogonek"; - - unicodeToName.put(new Character((char) 0x00f2), "ograve"); - nameToUnicode.put("ograve", new Character((char) 0x00f2)); - nameToEnc.put("ograve", new Integer(242)); - encToName[242] = "ograve"; - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - nameToEnc.put("onehalf", new Integer(189)); - encToName[189] = "onehalf"; - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - nameToEnc.put("onequarter", new Integer(188)); - encToName[188] = "onequarter"; - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - nameToEnc.put("onesuperior", new Integer(185)); - encToName[185] = "onesuperior"; - - unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); - nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); - nameToEnc.put("ordfeminine", new Integer(170)); - encToName[170] = "ordfeminine"; - - unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); - nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); - nameToEnc.put("ordmasculine", new Integer(186)); - encToName[186] = "ordmasculine"; - - unicodeToName.put(new Character((char) 0x00f8), "oslash"); - nameToUnicode.put("oslash", new Character((char) 0x00f8)); - nameToEnc.put("oslash", new Integer(248)); - encToName[248] = "oslash"; - - unicodeToName.put(new Character((char) 0x00f5), "otilde"); - nameToUnicode.put("otilde", new Character((char) 0x00f5)); - nameToEnc.put("otilde", new Integer(245)); - encToName[245] = "otilde"; - - unicodeToName.put(new Character((char) 0x0070), "p"); - nameToUnicode.put("p", new Character((char) 0x0070)); - nameToEnc.put("p", new Integer(112)); - encToName[112] = "p"; - - unicodeToName.put(new Character((char) 0x00b6), "paragraph"); - nameToUnicode.put("paragraph", new Character((char) 0x00b6)); - nameToEnc.put("paragraph", new Integer(182)); - encToName[182] = "paragraph"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); - nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); - nameToEnc.put("periodcentered", new Integer(183)); - encToName[183] = "periodcentered"; - - unicodeToName.put(new Character((char) 0x2030), "perthousand"); - nameToUnicode.put("perthousand", new Character((char) 0x2030)); - nameToEnc.put("perthousand", new Integer(139)); - encToName[139] = "perthousand"; - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - nameToEnc.put("plusminus", new Integer(177)); - encToName[177] = "plusminus"; - - unicodeToName.put(new Character((char) 0x0071), "q"); - nameToUnicode.put("q", new Character((char) 0x0071)); - nameToEnc.put("q", new Integer(113)); - encToName[113] = "q"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x00bf), "questiondown"); - nameToUnicode.put("questiondown", new Character((char) 0x00bf)); - nameToEnc.put("questiondown", new Integer(191)); - encToName[191] = "questiondown"; - - unicodeToName.put(new Character((char) 0x0022), "quotedbl"); - nameToUnicode.put("quotedbl", new Character((char) 0x0022)); - nameToEnc.put("quotedbl", new Integer(34)); - encToName[34] = "quotedbl"; - - unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); - nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); - nameToEnc.put("quotedblbase", new Integer(140)); - encToName[140] = "quotedblbase"; - - unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); - nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); - nameToEnc.put("quotedblleft", new Integer(141)); - encToName[141] = "quotedblleft"; - - unicodeToName.put(new Character((char) 0x201d), "quotedblright"); - nameToUnicode.put("quotedblright", new Character((char) 0x201d)); - nameToEnc.put("quotedblright", new Integer(142)); - encToName[142] = "quotedblright"; - - unicodeToName.put(new Character((char) 0x0060), "quoteleft"); - nameToUnicode.put("quoteleft", new Character((char) 0x0060)); - nameToEnc.put("quoteleft", new Integer(143)); - encToName[143] = "quoteleft"; - - unicodeToName.put(new Character((char) 0x0027), "quoteright"); - nameToUnicode.put("quoteright", new Character((char) 0x0027)); - nameToEnc.put("quoteright", new Integer(144)); - encToName[144] = "quoteright"; - - unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); - nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); - nameToEnc.put("quotesinglbase", new Integer(145)); - encToName[145] = "quotesinglbase"; - - unicodeToName.put(new Character((char) 0x0027), "quotesingle"); - nameToUnicode.put("quotesingle", new Character((char) 0x0027)); - nameToEnc.put("quotesingle", new Integer(39)); - encToName[39] = "quotesingle"; - - unicodeToName.put(new Character((char) 0x0072), "r"); - nameToUnicode.put("r", new Character((char) 0x0072)); - nameToEnc.put("r", new Integer(114)); - encToName[114] = "r"; - - unicodeToName.put(new Character((char) 0x00ae), "registered"); - nameToUnicode.put("registered", new Character((char) 0x00ae)); - nameToEnc.put("registered", new Integer(174)); - encToName[174] = "registered"; - - unicodeToName.put(new Character((char) 0x02da), "ring"); - nameToUnicode.put("ring", new Character((char) 0x02da)); - nameToEnc.put("ring", new Integer(30)); - encToName[30] = "ring"; - - unicodeToName.put(new Character((char) 0x0073), "s"); - nameToUnicode.put("s", new Character((char) 0x0073)); - nameToEnc.put("s", new Integer(115)); - encToName[115] = "s"; - - unicodeToName.put(new Character((char) 0x0161), "scaron"); - nameToUnicode.put("scaron", new Character((char) 0x0161)); - nameToEnc.put("scaron", new Integer(157)); - encToName[157] = "scaron"; - - unicodeToName.put(new Character((char) 0x00a7), "section"); - nameToUnicode.put("section", new Character((char) 0x00a7)); - nameToEnc.put("section", new Integer(167)); - encToName[167] = "section"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x00a3), "sterling"); - nameToUnicode.put("sterling", new Character((char) 0x00a3)); - nameToEnc.put("sterling", new Integer(163)); - encToName[163] = "sterling"; - - unicodeToName.put(new Character((char) 0x0074), "t"); - nameToUnicode.put("t", new Character((char) 0x0074)); - nameToEnc.put("t", new Integer(116)); - encToName[116] = "t"; - - unicodeToName.put(new Character((char) 0x00fe), "thorn"); - nameToUnicode.put("thorn", new Character((char) 0x00fe)); - nameToEnc.put("thorn", new Integer(254)); - encToName[254] = "thorn"; - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - nameToEnc.put("threequarters", new Integer(190)); - encToName[190] = "threequarters"; - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - nameToEnc.put("threesuperior", new Integer(179)); - encToName[179] = "threesuperior"; - - unicodeToName.put(new Character((char) 0x02dc), "tilde"); - nameToUnicode.put("tilde", new Character((char) 0x02dc)); - nameToEnc.put("tilde", new Integer(31)); - encToName[31] = "tilde"; - - unicodeToName.put(new Character((char) 0x2122), "trademark"); - nameToUnicode.put("trademark", new Character((char) 0x2122)); - nameToEnc.put("trademark", new Integer(146)); - encToName[146] = "trademark"; - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - nameToEnc.put("twosuperior", new Integer(178)); - encToName[178] = "twosuperior"; - - unicodeToName.put(new Character((char) 0x0075), "u"); - nameToUnicode.put("u", new Character((char) 0x0075)); - nameToEnc.put("u", new Integer(117)); - encToName[117] = "u"; - - unicodeToName.put(new Character((char) 0x00fa), "uacute"); - nameToUnicode.put("uacute", new Character((char) 0x00fa)); - nameToEnc.put("uacute", new Integer(250)); - encToName[250] = "uacute"; - - unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); - nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); - nameToEnc.put("ucircumflex", new Integer(251)); - encToName[251] = "ucircumflex"; - - unicodeToName.put(new Character((char) 0x00fc), "udieresis"); - nameToUnicode.put("udieresis", new Character((char) 0x00fc)); - nameToEnc.put("udieresis", new Integer(252)); - encToName[252] = "udieresis"; - - unicodeToName.put(new Character((char) 0x00f9), "ugrave"); - nameToUnicode.put("ugrave", new Character((char) 0x00f9)); - nameToEnc.put("ugrave", new Integer(249)); - encToName[249] = "ugrave"; - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x0076), "v"); - nameToUnicode.put("v", new Character((char) 0x0076)); - nameToEnc.put("v", new Integer(118)); - encToName[118] = "v"; - - unicodeToName.put(new Character((char) 0x0077), "w"); - nameToUnicode.put("w", new Character((char) 0x0077)); - nameToEnc.put("w", new Integer(119)); - encToName[119] = "w"; - - unicodeToName.put(new Character((char) 0x0078), "x"); - nameToUnicode.put("x", new Character((char) 0x0078)); - nameToEnc.put("x", new Integer(120)); - encToName[120] = "x"; - - unicodeToName.put(new Character((char) 0x0079), "y"); - nameToUnicode.put("y", new Character((char) 0x0079)); - nameToEnc.put("y", new Integer(121)); - encToName[121] = "y"; - - unicodeToName.put(new Character((char) 0x00fd), "yacute"); - nameToUnicode.put("yacute", new Character((char) 0x00fd)); - nameToEnc.put("yacute", new Integer(253)); - encToName[253] = "yacute"; - - unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); - nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); - nameToEnc.put("ydieresis", new Integer(255)); - encToName[255] = "ydieresis"; - - unicodeToName.put(new Character((char) 0x00a5), "yen"); - nameToUnicode.put("yen", new Character((char) 0x00a5)); - nameToEnc.put("yen", new Integer(165)); - encToName[165] = "yen"; - - unicodeToName.put(new Character((char) 0x007a), "z"); - nameToUnicode.put("z", new Character((char) 0x007a)); - nameToEnc.put("z", new Integer(122)); - encToName[122] = "z"; - - unicodeToName.put(new Character((char) 0x017e), "zcaron"); - nameToUnicode.put("zcaron", new Character((char) 0x017e)); - nameToEnc.put("zcaron", new Integer(158)); - encToName[158] = "zcaron"; - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Latin");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("PDF");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated PDFLatin Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class PDFLatin extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public PDFLatin() { + unicodeToName.put(new Character((char) 0x0041), "A"); + nameToUnicode.put("A", new Character((char) 0x0041)); + nameToEnc.put("A", new Integer(65)); + encToName[65] = "A"; + + unicodeToName.put(new Character((char) 0x00c6), "AE"); + nameToUnicode.put("AE", new Character((char) 0x00c6)); + nameToEnc.put("AE", new Integer(198)); + encToName[198] = "AE"; + + unicodeToName.put(new Character((char) 0x00c1), "Aacute"); + nameToUnicode.put("Aacute", new Character((char) 0x00c1)); + nameToEnc.put("Aacute", new Integer(193)); + encToName[193] = "Aacute"; + + unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); + nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); + nameToEnc.put("Acircumflex", new Integer(194)); + encToName[194] = "Acircumflex"; + + unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); + nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); + nameToEnc.put("Adieresis", new Integer(196)); + encToName[196] = "Adieresis"; + + unicodeToName.put(new Character((char) 0x00c0), "Agrave"); + nameToUnicode.put("Agrave", new Character((char) 0x00c0)); + nameToEnc.put("Agrave", new Integer(192)); + encToName[192] = "Agrave"; + + unicodeToName.put(new Character((char) 0x00c5), "Aring"); + nameToUnicode.put("Aring", new Character((char) 0x00c5)); + nameToEnc.put("Aring", new Integer(197)); + encToName[197] = "Aring"; + + unicodeToName.put(new Character((char) 0x00c3), "Atilde"); + nameToUnicode.put("Atilde", new Character((char) 0x00c3)); + nameToEnc.put("Atilde", new Integer(195)); + encToName[195] = "Atilde"; + + unicodeToName.put(new Character((char) 0x0042), "B"); + nameToUnicode.put("B", new Character((char) 0x0042)); + nameToEnc.put("B", new Integer(66)); + encToName[66] = "B"; + + unicodeToName.put(new Character((char) 0x0043), "C"); + nameToUnicode.put("C", new Character((char) 0x0043)); + nameToEnc.put("C", new Integer(67)); + encToName[67] = "C"; + + unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); + nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); + nameToEnc.put("Ccedilla", new Integer(199)); + encToName[199] = "Ccedilla"; + + unicodeToName.put(new Character((char) 0x0044), "D"); + nameToUnicode.put("D", new Character((char) 0x0044)); + nameToEnc.put("D", new Integer(68)); + encToName[68] = "D"; + + unicodeToName.put(new Character((char) 0x0045), "E"); + nameToUnicode.put("E", new Character((char) 0x0045)); + nameToEnc.put("E", new Integer(69)); + encToName[69] = "E"; + + unicodeToName.put(new Character((char) 0x00c9), "Eacute"); + nameToUnicode.put("Eacute", new Character((char) 0x00c9)); + nameToEnc.put("Eacute", new Integer(201)); + encToName[201] = "Eacute"; + + unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); + nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); + nameToEnc.put("Ecircumflex", new Integer(202)); + encToName[202] = "Ecircumflex"; + + unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); + nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); + nameToEnc.put("Edieresis", new Integer(203)); + encToName[203] = "Edieresis"; + + unicodeToName.put(new Character((char) 0x00c8), "Egrave"); + nameToUnicode.put("Egrave", new Character((char) 0x00c8)); + nameToEnc.put("Egrave", new Integer(200)); + encToName[200] = "Egrave"; + + unicodeToName.put(new Character((char) 0x00d0), "Eth"); + nameToUnicode.put("Eth", new Character((char) 0x00d0)); + nameToEnc.put("Eth", new Integer(208)); + encToName[208] = "Eth"; + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + nameToEnc.put("Euro", new Integer(160)); + encToName[160] = "Euro"; + + unicodeToName.put(new Character((char) 0x0046), "F"); + nameToUnicode.put("F", new Character((char) 0x0046)); + nameToEnc.put("F", new Integer(70)); + encToName[70] = "F"; + + unicodeToName.put(new Character((char) 0x0047), "G"); + nameToUnicode.put("G", new Character((char) 0x0047)); + nameToEnc.put("G", new Integer(71)); + encToName[71] = "G"; + + unicodeToName.put(new Character((char) 0x0048), "H"); + nameToUnicode.put("H", new Character((char) 0x0048)); + nameToEnc.put("H", new Integer(72)); + encToName[72] = "H"; + + unicodeToName.put(new Character((char) 0x0049), "I"); + nameToUnicode.put("I", new Character((char) 0x0049)); + nameToEnc.put("I", new Integer(73)); + encToName[73] = "I"; + + unicodeToName.put(new Character((char) 0x00cd), "Iacute"); + nameToUnicode.put("Iacute", new Character((char) 0x00cd)); + nameToEnc.put("Iacute", new Integer(205)); + encToName[205] = "Iacute"; + + unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); + nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); + nameToEnc.put("Icircumflex", new Integer(206)); + encToName[206] = "Icircumflex"; + + unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); + nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); + nameToEnc.put("Idieresis", new Integer(207)); + encToName[207] = "Idieresis"; + + unicodeToName.put(new Character((char) 0x00cc), "Igrave"); + nameToUnicode.put("Igrave", new Character((char) 0x00cc)); + nameToEnc.put("Igrave", new Integer(204)); + encToName[204] = "Igrave"; + + unicodeToName.put(new Character((char) 0x004a), "J"); + nameToUnicode.put("J", new Character((char) 0x004a)); + nameToEnc.put("J", new Integer(74)); + encToName[74] = "J"; + + unicodeToName.put(new Character((char) 0x004b), "K"); + nameToUnicode.put("K", new Character((char) 0x004b)); + nameToEnc.put("K", new Integer(75)); + encToName[75] = "K"; + + unicodeToName.put(new Character((char) 0x004c), "L"); + nameToUnicode.put("L", new Character((char) 0x004c)); + nameToEnc.put("L", new Integer(76)); + encToName[76] = "L"; + + unicodeToName.put(new Character((char) 0x0141), "Lslash"); + nameToUnicode.put("Lslash", new Character((char) 0x0141)); + nameToEnc.put("Lslash", new Integer(149)); + encToName[149] = "Lslash"; + + unicodeToName.put(new Character((char) 0x004d), "M"); + nameToUnicode.put("M", new Character((char) 0x004d)); + nameToEnc.put("M", new Integer(77)); + encToName[77] = "M"; + + unicodeToName.put(new Character((char) 0x004e), "N"); + nameToUnicode.put("N", new Character((char) 0x004e)); + nameToEnc.put("N", new Integer(78)); + encToName[78] = "N"; + + unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); + nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); + nameToEnc.put("Ntilde", new Integer(209)); + encToName[209] = "Ntilde"; + + unicodeToName.put(new Character((char) 0x004f), "O"); + nameToUnicode.put("O", new Character((char) 0x004f)); + nameToEnc.put("O", new Integer(79)); + encToName[79] = "O"; + + unicodeToName.put(new Character((char) 0x0152), "OE"); + nameToUnicode.put("OE", new Character((char) 0x0152)); + nameToEnc.put("OE", new Integer(150)); + encToName[150] = "OE"; + + unicodeToName.put(new Character((char) 0x00d2), "Oacute"); + nameToUnicode.put("Oacute", new Character((char) 0x00d2)); + nameToEnc.put("Oacute", new Integer(211)); + encToName[211] = "Oacute"; + + unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); + nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); + nameToEnc.put("Ocircumflex", new Integer(212)); + encToName[212] = "Ocircumflex"; + + unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); + nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); + nameToEnc.put("Odieresis", new Integer(214)); + encToName[214] = "Odieresis"; + + unicodeToName.put(new Character((char) 0x00d3), "Ograve"); + nameToUnicode.put("Ograve", new Character((char) 0x00d3)); + nameToEnc.put("Ograve", new Integer(210)); + encToName[210] = "Ograve"; + + unicodeToName.put(new Character((char) 0x00d8), "Oslash"); + nameToUnicode.put("Oslash", new Character((char) 0x00d8)); + nameToEnc.put("Oslash", new Integer(216)); + encToName[216] = "Oslash"; + + unicodeToName.put(new Character((char) 0x00d5), "Otilde"); + nameToUnicode.put("Otilde", new Character((char) 0x00d5)); + nameToEnc.put("Otilde", new Integer(213)); + encToName[213] = "Otilde"; + + unicodeToName.put(new Character((char) 0x0050), "P"); + nameToUnicode.put("P", new Character((char) 0x0050)); + nameToEnc.put("P", new Integer(80)); + encToName[80] = "P"; + + unicodeToName.put(new Character((char) 0x0051), "Q"); + nameToUnicode.put("Q", new Character((char) 0x0051)); + nameToEnc.put("Q", new Integer(81)); + encToName[81] = "Q"; + + unicodeToName.put(new Character((char) 0x0052), "R"); + nameToUnicode.put("R", new Character((char) 0x0052)); + nameToEnc.put("R", new Integer(82)); + encToName[82] = "R"; + + unicodeToName.put(new Character((char) 0x0053), "S"); + nameToUnicode.put("S", new Character((char) 0x0053)); + nameToEnc.put("S", new Integer(83)); + encToName[83] = "S"; + + unicodeToName.put(new Character((char) 0x0160), "Scaron"); + nameToUnicode.put("Scaron", new Character((char) 0x0160)); + nameToEnc.put("Scaron", new Integer(151)); + encToName[151] = "Scaron"; + + unicodeToName.put(new Character((char) 0x0054), "T"); + nameToUnicode.put("T", new Character((char) 0x0054)); + nameToEnc.put("T", new Integer(84)); + encToName[84] = "T"; + + unicodeToName.put(new Character((char) 0x00de), "Thorn"); + nameToUnicode.put("Thorn", new Character((char) 0x00de)); + nameToEnc.put("Thorn", new Integer(222)); + encToName[222] = "Thorn"; + + unicodeToName.put(new Character((char) 0x0055), "U"); + nameToUnicode.put("U", new Character((char) 0x0055)); + nameToEnc.put("U", new Integer(85)); + encToName[85] = "U"; + + unicodeToName.put(new Character((char) 0x00da), "Uacute"); + nameToUnicode.put("Uacute", new Character((char) 0x00da)); + nameToEnc.put("Uacute", new Integer(218)); + encToName[218] = "Uacute"; + + unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); + nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); + nameToEnc.put("Ucircumflex", new Integer(219)); + encToName[219] = "Ucircumflex"; + + unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); + nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); + nameToEnc.put("Udieresis", new Integer(220)); + encToName[220] = "Udieresis"; + + unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); + nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); + nameToEnc.put("Ugrave", new Integer(217)); + encToName[217] = "Ugrave"; + + unicodeToName.put(new Character((char) 0x0056), "V"); + nameToUnicode.put("V", new Character((char) 0x0056)); + nameToEnc.put("V", new Integer(86)); + encToName[86] = "V"; + + unicodeToName.put(new Character((char) 0x0057), "W"); + nameToUnicode.put("W", new Character((char) 0x0057)); + nameToEnc.put("W", new Integer(87)); + encToName[87] = "W"; + + unicodeToName.put(new Character((char) 0x0058), "X"); + nameToUnicode.put("X", new Character((char) 0x0058)); + nameToEnc.put("X", new Integer(88)); + encToName[88] = "X"; + + unicodeToName.put(new Character((char) 0x0059), "Y"); + nameToUnicode.put("Y", new Character((char) 0x0059)); + nameToEnc.put("Y", new Integer(89)); + encToName[89] = "Y"; + + unicodeToName.put(new Character((char) 0x00dd), "Yacute"); + nameToUnicode.put("Yacute", new Character((char) 0x00dd)); + nameToEnc.put("Yacute", new Integer(221)); + encToName[221] = "Yacute"; + + unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); + nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); + nameToEnc.put("Ydieresis", new Integer(152)); + encToName[152] = "Ydieresis"; + + unicodeToName.put(new Character((char) 0x005a), "Z"); + nameToUnicode.put("Z", new Character((char) 0x005a)); + nameToEnc.put("Z", new Integer(90)); + encToName[90] = "Z"; + + unicodeToName.put(new Character((char) 0x017d), "Zcaron"); + nameToUnicode.put("Zcaron", new Character((char) 0x017d)); + nameToEnc.put("Zcaron", new Integer(153)); + encToName[153] = "Zcaron"; + + unicodeToName.put(new Character((char) 0x0061), "a"); + nameToUnicode.put("a", new Character((char) 0x0061)); + nameToEnc.put("a", new Integer(97)); + encToName[97] = "a"; + + unicodeToName.put(new Character((char) 0x00e1), "aacute"); + nameToUnicode.put("aacute", new Character((char) 0x00e1)); + nameToEnc.put("aacute", new Integer(225)); + encToName[225] = "aacute"; + + unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); + nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); + nameToEnc.put("acircumflex", new Integer(226)); + encToName[226] = "acircumflex"; + + unicodeToName.put(new Character((char) 0x00b4), "acute"); + nameToUnicode.put("acute", new Character((char) 0x00b4)); + nameToEnc.put("acute", new Integer(180)); + encToName[180] = "acute"; + + unicodeToName.put(new Character((char) 0x00e4), "adieresis"); + nameToUnicode.put("adieresis", new Character((char) 0x00e4)); + nameToEnc.put("adieresis", new Integer(228)); + encToName[228] = "adieresis"; + + unicodeToName.put(new Character((char) 0x00e6), "ae"); + nameToUnicode.put("ae", new Character((char) 0x00e6)); + nameToEnc.put("ae", new Integer(230)); + encToName[230] = "ae"; + + unicodeToName.put(new Character((char) 0x00e0), "agrave"); + nameToUnicode.put("agrave", new Character((char) 0x00e0)); + nameToEnc.put("agrave", new Integer(224)); + encToName[224] = "agrave"; + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x00e5), "aring"); + nameToUnicode.put("aring", new Character((char) 0x00e5)); + nameToEnc.put("aring", new Integer(229)); + encToName[229] = "aring"; + + unicodeToName.put(new Character((char) 0x005e), "asciicircum"); + nameToUnicode.put("asciicircum", new Character((char) 0x005e)); + nameToEnc.put("asciicircum", new Integer(94)); + encToName[94] = "asciicircum"; + + unicodeToName.put(new Character((char) 0x007e), "asciitilde"); + nameToUnicode.put("asciitilde", new Character((char) 0x007e)); + nameToEnc.put("asciitilde", new Integer(126)); + encToName[126] = "asciitilde"; + + unicodeToName.put(new Character((char) 0x002a), "asterisk"); + nameToUnicode.put("asterisk", new Character((char) 0x002a)); + nameToEnc.put("asterisk", new Integer(42)); + encToName[42] = "asterisk"; + + unicodeToName.put(new Character((char) 0x0040), "at"); + nameToUnicode.put("at", new Character((char) 0x0040)); + nameToEnc.put("at", new Integer(64)); + encToName[64] = "at"; + + unicodeToName.put(new Character((char) 0x00e3), "atilde"); + nameToUnicode.put("atilde", new Character((char) 0x00e3)); + nameToEnc.put("atilde", new Integer(227)); + encToName[227] = "atilde"; + + unicodeToName.put(new Character((char) 0x0062), "b"); + nameToUnicode.put("b", new Character((char) 0x0062)); + nameToEnc.put("b", new Integer(98)); + encToName[98] = "b"; + + unicodeToName.put(new Character((char) 0x005c), "backslash"); + nameToUnicode.put("backslash", new Character((char) 0x005c)); + nameToEnc.put("backslash", new Integer(92)); + encToName[92] = "backslash"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0x02d8), "breve"); + nameToUnicode.put("breve", new Character((char) 0x02d8)); + nameToEnc.put("breve", new Integer(24)); + encToName[24] = "breve"; + + unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); + nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); + nameToEnc.put("brokenbar", new Integer(166)); + encToName[166] = "brokenbar"; + + unicodeToName.put(new Character((char) 0x2022), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2022)); + nameToEnc.put("bullet", new Integer(128)); + encToName[128] = "bullet"; + + unicodeToName.put(new Character((char) 0x0063), "c"); + nameToUnicode.put("c", new Character((char) 0x0063)); + nameToEnc.put("c", new Integer(99)); + encToName[99] = "c"; + + unicodeToName.put(new Character((char) 0x02c7), "caron"); + nameToUnicode.put("caron", new Character((char) 0x02c7)); + nameToEnc.put("caron", new Integer(25)); + encToName[25] = "caron"; + + unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); + nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); + nameToEnc.put("ccedilla", new Integer(231)); + encToName[231] = "ccedilla"; + + unicodeToName.put(new Character((char) 0x00b8), "cedilla"); + nameToUnicode.put("cedilla", new Character((char) 0x00b8)); + nameToEnc.put("cedilla", new Integer(184)); + encToName[184] = "cedilla"; + + unicodeToName.put(new Character((char) 0x00a2), "cent"); + nameToUnicode.put("cent", new Character((char) 0x00a2)); + nameToEnc.put("cent", new Integer(162)); + encToName[162] = "cent"; + + unicodeToName.put(new Character((char) 0x02c6), "circumflex"); + nameToUnicode.put("circumflex", new Character((char) 0x02c6)); + nameToEnc.put("circumflex", new Integer(26)); + encToName[26] = "circumflex"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x00a9), "copyright"); + nameToUnicode.put("copyright", new Character((char) 0x00a9)); + nameToEnc.put("copyright", new Integer(169)); + encToName[169] = "copyright"; + + unicodeToName.put(new Character((char) 0x00a4), "currency"); + nameToUnicode.put("currency", new Character((char) 0x00a4)); + nameToEnc.put("currency", new Integer(164)); + encToName[164] = "currency"; + + unicodeToName.put(new Character((char) 0x0064), "d"); + nameToUnicode.put("d", new Character((char) 0x0064)); + nameToEnc.put("d", new Integer(100)); + encToName[100] = "d"; + + unicodeToName.put(new Character((char) 0x2020), "dagger"); + nameToUnicode.put("dagger", new Character((char) 0x2020)); + nameToEnc.put("dagger", new Integer(129)); + encToName[129] = "dagger"; + + unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); + nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); + nameToEnc.put("daggerdbl", new Integer(130)); + encToName[130] = "daggerdbl"; + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + nameToEnc.put("degree", new Integer(176)); + encToName[176] = "degree"; + + unicodeToName.put(new Character((char) 0x00a8), "dieresis"); + nameToUnicode.put("dieresis", new Character((char) 0x00a8)); + nameToEnc.put("dieresis", new Integer(168)); + encToName[168] = "dieresis"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + nameToEnc.put("divide", new Integer(247)); + encToName[247] = "divide"; + + unicodeToName.put(new Character((char) 0x0024), "dollar"); + nameToUnicode.put("dollar", new Character((char) 0x0024)); + nameToEnc.put("dollar", new Integer(36)); + encToName[36] = "dollar"; + + unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); + nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); + nameToEnc.put("dotaccent", new Integer(27)); + encToName[27] = "dotaccent"; + + unicodeToName.put(new Character((char) 0x0131), "dotlessi"); + nameToUnicode.put("dotlessi", new Character((char) 0x0131)); + nameToEnc.put("dotlessi", new Integer(154)); + encToName[154] = "dotlessi"; + + unicodeToName.put(new Character((char) 0x0065), "e"); + nameToUnicode.put("e", new Character((char) 0x0065)); + nameToEnc.put("e", new Integer(101)); + encToName[101] = "e"; + + unicodeToName.put(new Character((char) 0x00e9), "eacute"); + nameToUnicode.put("eacute", new Character((char) 0x00e9)); + nameToEnc.put("eacute", new Integer(233)); + encToName[233] = "eacute"; + + unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); + nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); + nameToEnc.put("ecircumflex", new Integer(234)); + encToName[234] = "ecircumflex"; + + unicodeToName.put(new Character((char) 0x00eb), "edieresis"); + nameToUnicode.put("edieresis", new Character((char) 0x00eb)); + nameToEnc.put("edieresis", new Integer(235)); + encToName[235] = "edieresis"; + + unicodeToName.put(new Character((char) 0x00e8), "egrave"); + nameToUnicode.put("egrave", new Character((char) 0x00e8)); + nameToEnc.put("egrave", new Integer(232)); + encToName[232] = "egrave"; + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + nameToEnc.put("ellipsis", new Integer(131)); + encToName[131] = "ellipsis"; + + unicodeToName.put(new Character((char) 0x002d), "emdash"); + nameToUnicode.put("emdash", new Character((char) 0x002d)); + nameToEnc.put("emdash", new Integer(132)); + encToName[132] = "emdash"; + + unicodeToName.put(new Character((char) 0x002d), "endash"); + nameToUnicode.put("endash", new Character((char) 0x002d)); + nameToEnc.put("endash", new Integer(133)); + encToName[133] = "endash"; + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x00f0), "eth"); + nameToUnicode.put("eth", new Character((char) 0x00f0)); + nameToEnc.put("eth", new Integer(240)); + encToName[240] = "eth"; + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); + nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); + nameToEnc.put("exclamdown", new Integer(161)); + encToName[161] = "exclamdown"; + + unicodeToName.put(new Character((char) 0x0066), "f"); + nameToUnicode.put("f", new Character((char) 0x0066)); + nameToEnc.put("f", new Integer(102)); + encToName[102] = "f"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + nameToEnc.put("fi", new Integer(147)); + encToName[147] = "fi"; + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + nameToEnc.put("fl", new Integer(148)); + encToName[148] = "fl"; + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + nameToEnc.put("florin", new Integer(134)); + encToName[134] = "florin"; + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + nameToEnc.put("fraction", new Integer(135)); + encToName[135] = "fraction"; + + unicodeToName.put(new Character((char) 0x0067), "g"); + nameToUnicode.put("g", new Character((char) 0x0067)); + nameToEnc.put("g", new Integer(103)); + encToName[103] = "g"; + + unicodeToName.put(new Character((char) 0x00df), "germandbls"); + nameToUnicode.put("germandbls", new Character((char) 0x00df)); + nameToEnc.put("germandbls", new Integer(223)); + encToName[223] = "germandbls"; + + unicodeToName.put(new Character((char) 0x0060), "grave"); + nameToUnicode.put("grave", new Character((char) 0x0060)); + nameToEnc.put("grave", new Integer(96)); + encToName[96] = "grave"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); + nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); + nameToEnc.put("guillemotleft", new Integer(171)); + encToName[171] = "guillemotleft"; + + unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); + nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); + nameToEnc.put("guillemotright", new Integer(187)); + encToName[187] = "guillemotright"; + + unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); + nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); + nameToEnc.put("guilsinglleft", new Integer(136)); + encToName[136] = "guilsinglleft"; + + unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); + nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); + nameToEnc.put("guilsinglright", new Integer(137)); + encToName[137] = "guilsinglright"; + + unicodeToName.put(new Character((char) 0x0068), "h"); + nameToUnicode.put("h", new Character((char) 0x0068)); + nameToEnc.put("h", new Integer(104)); + encToName[104] = "h"; + + unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); + nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); + nameToEnc.put("hungarumlaut", new Integer(28)); + encToName[28] = "hungarumlaut"; + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(45)); + encToName[45] = "hyphen"; + + unicodeToName.put(new Character((char) 0x0069), "i"); + nameToUnicode.put("i", new Character((char) 0x0069)); + nameToEnc.put("i", new Integer(105)); + encToName[105] = "i"; + + unicodeToName.put(new Character((char) 0x00ed), "iacute"); + nameToUnicode.put("iacute", new Character((char) 0x00ed)); + nameToEnc.put("iacute", new Integer(237)); + encToName[237] = "iacute"; + + unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); + nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); + nameToEnc.put("icircumflex", new Integer(238)); + encToName[238] = "icircumflex"; + + unicodeToName.put(new Character((char) 0x00ef), "idieresis"); + nameToUnicode.put("idieresis", new Character((char) 0x00ef)); + nameToEnc.put("idieresis", new Integer(239)); + encToName[239] = "idieresis"; + + unicodeToName.put(new Character((char) 0x00ec), "igrave"); + nameToUnicode.put("igrave", new Character((char) 0x00ec)); + nameToEnc.put("igrave", new Integer(236)); + encToName[236] = "igrave"; + + unicodeToName.put(new Character((char) 0x006a), "j"); + nameToUnicode.put("j", new Character((char) 0x006a)); + nameToEnc.put("j", new Integer(106)); + encToName[106] = "j"; + + unicodeToName.put(new Character((char) 0x006b), "k"); + nameToUnicode.put("k", new Character((char) 0x006b)); + nameToEnc.put("k", new Integer(107)); + encToName[107] = "k"; + + unicodeToName.put(new Character((char) 0x006c), "l"); + nameToUnicode.put("l", new Character((char) 0x006c)); + nameToEnc.put("l", new Integer(108)); + encToName[108] = "l"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + nameToEnc.put("logicalnot", new Integer(172)); + encToName[172] = "logicalnot"; + + unicodeToName.put(new Character((char) 0x0142), "lslash"); + nameToUnicode.put("lslash", new Character((char) 0x0142)); + nameToEnc.put("lslash", new Integer(155)); + encToName[155] = "lslash"; + + unicodeToName.put(new Character((char) 0x006d), "m"); + nameToUnicode.put("m", new Character((char) 0x006d)); + nameToEnc.put("m", new Integer(109)); + encToName[109] = "m"; + + unicodeToName.put(new Character((char) 0x00af), "macron"); + nameToUnicode.put("macron", new Character((char) 0x00af)); + nameToEnc.put("macron", new Integer(175)); + encToName[175] = "macron"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + nameToEnc.put("minus", new Integer(138)); + encToName[138] = "minus"; + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + nameToEnc.put("mu", new Integer(181)); + encToName[181] = "mu"; + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + nameToEnc.put("multiply", new Integer(215)); + encToName[215] = "multiply"; + + unicodeToName.put(new Character((char) 0x006e), "n"); + nameToUnicode.put("n", new Character((char) 0x006e)); + nameToEnc.put("n", new Integer(110)); + encToName[110] = "n"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x00f1), "ntilde"); + nameToUnicode.put("ntilde", new Character((char) 0x00f1)); + nameToEnc.put("ntilde", new Integer(241)); + encToName[241] = "ntilde"; + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x006f), "o"); + nameToUnicode.put("o", new Character((char) 0x006f)); + nameToEnc.put("o", new Integer(111)); + encToName[111] = "o"; + + unicodeToName.put(new Character((char) 0x00f3), "oacute"); + nameToUnicode.put("oacute", new Character((char) 0x00f3)); + nameToEnc.put("oacute", new Integer(243)); + encToName[243] = "oacute"; + + unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); + nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); + nameToEnc.put("ocircumflex", new Integer(244)); + encToName[244] = "ocircumflex"; + + unicodeToName.put(new Character((char) 0x00f6), "odieresis"); + nameToUnicode.put("odieresis", new Character((char) 0x00f6)); + nameToEnc.put("odieresis", new Integer(246)); + encToName[246] = "odieresis"; + + unicodeToName.put(new Character((char) 0x0153), "oe"); + nameToUnicode.put("oe", new Character((char) 0x0153)); + nameToEnc.put("oe", new Integer(156)); + encToName[156] = "oe"; + + unicodeToName.put(new Character((char) 0x02db), "ogonek"); + nameToUnicode.put("ogonek", new Character((char) 0x02db)); + nameToEnc.put("ogonek", new Integer(29)); + encToName[29] = "ogonek"; + + unicodeToName.put(new Character((char) 0x00f2), "ograve"); + nameToUnicode.put("ograve", new Character((char) 0x00f2)); + nameToEnc.put("ograve", new Integer(242)); + encToName[242] = "ograve"; + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + nameToEnc.put("onehalf", new Integer(189)); + encToName[189] = "onehalf"; + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + nameToEnc.put("onequarter", new Integer(188)); + encToName[188] = "onequarter"; + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + nameToEnc.put("onesuperior", new Integer(185)); + encToName[185] = "onesuperior"; + + unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); + nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); + nameToEnc.put("ordfeminine", new Integer(170)); + encToName[170] = "ordfeminine"; + + unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); + nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); + nameToEnc.put("ordmasculine", new Integer(186)); + encToName[186] = "ordmasculine"; + + unicodeToName.put(new Character((char) 0x00f8), "oslash"); + nameToUnicode.put("oslash", new Character((char) 0x00f8)); + nameToEnc.put("oslash", new Integer(248)); + encToName[248] = "oslash"; + + unicodeToName.put(new Character((char) 0x00f5), "otilde"); + nameToUnicode.put("otilde", new Character((char) 0x00f5)); + nameToEnc.put("otilde", new Integer(245)); + encToName[245] = "otilde"; + + unicodeToName.put(new Character((char) 0x0070), "p"); + nameToUnicode.put("p", new Character((char) 0x0070)); + nameToEnc.put("p", new Integer(112)); + encToName[112] = "p"; + + unicodeToName.put(new Character((char) 0x00b6), "paragraph"); + nameToUnicode.put("paragraph", new Character((char) 0x00b6)); + nameToEnc.put("paragraph", new Integer(182)); + encToName[182] = "paragraph"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); + nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); + nameToEnc.put("periodcentered", new Integer(183)); + encToName[183] = "periodcentered"; + + unicodeToName.put(new Character((char) 0x2030), "perthousand"); + nameToUnicode.put("perthousand", new Character((char) 0x2030)); + nameToEnc.put("perthousand", new Integer(139)); + encToName[139] = "perthousand"; + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + nameToEnc.put("plusminus", new Integer(177)); + encToName[177] = "plusminus"; + + unicodeToName.put(new Character((char) 0x0071), "q"); + nameToUnicode.put("q", new Character((char) 0x0071)); + nameToEnc.put("q", new Integer(113)); + encToName[113] = "q"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x00bf), "questiondown"); + nameToUnicode.put("questiondown", new Character((char) 0x00bf)); + nameToEnc.put("questiondown", new Integer(191)); + encToName[191] = "questiondown"; + + unicodeToName.put(new Character((char) 0x0022), "quotedbl"); + nameToUnicode.put("quotedbl", new Character((char) 0x0022)); + nameToEnc.put("quotedbl", new Integer(34)); + encToName[34] = "quotedbl"; + + unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); + nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); + nameToEnc.put("quotedblbase", new Integer(140)); + encToName[140] = "quotedblbase"; + + unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); + nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); + nameToEnc.put("quotedblleft", new Integer(141)); + encToName[141] = "quotedblleft"; + + unicodeToName.put(new Character((char) 0x201d), "quotedblright"); + nameToUnicode.put("quotedblright", new Character((char) 0x201d)); + nameToEnc.put("quotedblright", new Integer(142)); + encToName[142] = "quotedblright"; + + unicodeToName.put(new Character((char) 0x0060), "quoteleft"); + nameToUnicode.put("quoteleft", new Character((char) 0x0060)); + nameToEnc.put("quoteleft", new Integer(143)); + encToName[143] = "quoteleft"; + + unicodeToName.put(new Character((char) 0x0027), "quoteright"); + nameToUnicode.put("quoteright", new Character((char) 0x0027)); + nameToEnc.put("quoteright", new Integer(144)); + encToName[144] = "quoteright"; + + unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); + nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); + nameToEnc.put("quotesinglbase", new Integer(145)); + encToName[145] = "quotesinglbase"; + + unicodeToName.put(new Character((char) 0x0027), "quotesingle"); + nameToUnicode.put("quotesingle", new Character((char) 0x0027)); + nameToEnc.put("quotesingle", new Integer(39)); + encToName[39] = "quotesingle"; + + unicodeToName.put(new Character((char) 0x0072), "r"); + nameToUnicode.put("r", new Character((char) 0x0072)); + nameToEnc.put("r", new Integer(114)); + encToName[114] = "r"; + + unicodeToName.put(new Character((char) 0x00ae), "registered"); + nameToUnicode.put("registered", new Character((char) 0x00ae)); + nameToEnc.put("registered", new Integer(174)); + encToName[174] = "registered"; + + unicodeToName.put(new Character((char) 0x02da), "ring"); + nameToUnicode.put("ring", new Character((char) 0x02da)); + nameToEnc.put("ring", new Integer(30)); + encToName[30] = "ring"; + + unicodeToName.put(new Character((char) 0x0073), "s"); + nameToUnicode.put("s", new Character((char) 0x0073)); + nameToEnc.put("s", new Integer(115)); + encToName[115] = "s"; + + unicodeToName.put(new Character((char) 0x0161), "scaron"); + nameToUnicode.put("scaron", new Character((char) 0x0161)); + nameToEnc.put("scaron", new Integer(157)); + encToName[157] = "scaron"; + + unicodeToName.put(new Character((char) 0x00a7), "section"); + nameToUnicode.put("section", new Character((char) 0x00a7)); + nameToEnc.put("section", new Integer(167)); + encToName[167] = "section"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x00a3), "sterling"); + nameToUnicode.put("sterling", new Character((char) 0x00a3)); + nameToEnc.put("sterling", new Integer(163)); + encToName[163] = "sterling"; + + unicodeToName.put(new Character((char) 0x0074), "t"); + nameToUnicode.put("t", new Character((char) 0x0074)); + nameToEnc.put("t", new Integer(116)); + encToName[116] = "t"; + + unicodeToName.put(new Character((char) 0x00fe), "thorn"); + nameToUnicode.put("thorn", new Character((char) 0x00fe)); + nameToEnc.put("thorn", new Integer(254)); + encToName[254] = "thorn"; + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + nameToEnc.put("threequarters", new Integer(190)); + encToName[190] = "threequarters"; + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + nameToEnc.put("threesuperior", new Integer(179)); + encToName[179] = "threesuperior"; + + unicodeToName.put(new Character((char) 0x02dc), "tilde"); + nameToUnicode.put("tilde", new Character((char) 0x02dc)); + nameToEnc.put("tilde", new Integer(31)); + encToName[31] = "tilde"; + + unicodeToName.put(new Character((char) 0x2122), "trademark"); + nameToUnicode.put("trademark", new Character((char) 0x2122)); + nameToEnc.put("trademark", new Integer(146)); + encToName[146] = "trademark"; + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + nameToEnc.put("twosuperior", new Integer(178)); + encToName[178] = "twosuperior"; + + unicodeToName.put(new Character((char) 0x0075), "u"); + nameToUnicode.put("u", new Character((char) 0x0075)); + nameToEnc.put("u", new Integer(117)); + encToName[117] = "u"; + + unicodeToName.put(new Character((char) 0x00fa), "uacute"); + nameToUnicode.put("uacute", new Character((char) 0x00fa)); + nameToEnc.put("uacute", new Integer(250)); + encToName[250] = "uacute"; + + unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); + nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); + nameToEnc.put("ucircumflex", new Integer(251)); + encToName[251] = "ucircumflex"; + + unicodeToName.put(new Character((char) 0x00fc), "udieresis"); + nameToUnicode.put("udieresis", new Character((char) 0x00fc)); + nameToEnc.put("udieresis", new Integer(252)); + encToName[252] = "udieresis"; + + unicodeToName.put(new Character((char) 0x00f9), "ugrave"); + nameToUnicode.put("ugrave", new Character((char) 0x00f9)); + nameToEnc.put("ugrave", new Integer(249)); + encToName[249] = "ugrave"; + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x0076), "v"); + nameToUnicode.put("v", new Character((char) 0x0076)); + nameToEnc.put("v", new Integer(118)); + encToName[118] = "v"; + + unicodeToName.put(new Character((char) 0x0077), "w"); + nameToUnicode.put("w", new Character((char) 0x0077)); + nameToEnc.put("w", new Integer(119)); + encToName[119] = "w"; + + unicodeToName.put(new Character((char) 0x0078), "x"); + nameToUnicode.put("x", new Character((char) 0x0078)); + nameToEnc.put("x", new Integer(120)); + encToName[120] = "x"; + + unicodeToName.put(new Character((char) 0x0079), "y"); + nameToUnicode.put("y", new Character((char) 0x0079)); + nameToEnc.put("y", new Integer(121)); + encToName[121] = "y"; + + unicodeToName.put(new Character((char) 0x00fd), "yacute"); + nameToUnicode.put("yacute", new Character((char) 0x00fd)); + nameToEnc.put("yacute", new Integer(253)); + encToName[253] = "yacute"; + + unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); + nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); + nameToEnc.put("ydieresis", new Integer(255)); + encToName[255] = "ydieresis"; + + unicodeToName.put(new Character((char) 0x00a5), "yen"); + nameToUnicode.put("yen", new Character((char) 0x00a5)); + nameToEnc.put("yen", new Integer(165)); + encToName[165] = "yen"; + + unicodeToName.put(new Character((char) 0x007a), "z"); + nameToUnicode.put("z", new Character((char) 0x007a)); + nameToEnc.put("z", new Integer(122)); + encToName[122] = "z"; + + unicodeToName.put(new Character((char) 0x017e), "zcaron"); + nameToUnicode.put("zcaron", new Character((char) 0x017e)); + nameToEnc.put("zcaron", new Integer(158)); + encToName[158] = "zcaron"; + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Latin");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("PDF");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/STDLatin.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/STDLatin.java index bff0193ea..b00edea6f 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/STDLatin.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/STDLatin.java @@ -1,1034 +1,1034 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated STDLatin Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class STDLatin extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public STDLatin() { - unicodeToName.put(new Character((char) 0x0041), "A"); - nameToUnicode.put("A", new Character((char) 0x0041)); - nameToEnc.put("A", new Integer(65)); - encToName[65] = "A"; - - unicodeToName.put(new Character((char) 0x00c6), "AE"); - nameToUnicode.put("AE", new Character((char) 0x00c6)); - nameToEnc.put("AE", new Integer(225)); - encToName[225] = "AE"; - - unicodeToName.put(new Character((char) 0x00c1), "Aacute"); - nameToUnicode.put("Aacute", new Character((char) 0x00c1)); - - unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); - nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); - - unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); - nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); - - unicodeToName.put(new Character((char) 0x00c0), "Agrave"); - nameToUnicode.put("Agrave", new Character((char) 0x00c0)); - - unicodeToName.put(new Character((char) 0x00c5), "Aring"); - nameToUnicode.put("Aring", new Character((char) 0x00c5)); - - unicodeToName.put(new Character((char) 0x00c3), "Atilde"); - nameToUnicode.put("Atilde", new Character((char) 0x00c3)); - - unicodeToName.put(new Character((char) 0x0042), "B"); - nameToUnicode.put("B", new Character((char) 0x0042)); - nameToEnc.put("B", new Integer(66)); - encToName[66] = "B"; - - unicodeToName.put(new Character((char) 0x0043), "C"); - nameToUnicode.put("C", new Character((char) 0x0043)); - nameToEnc.put("C", new Integer(67)); - encToName[67] = "C"; - - unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); - nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); - - unicodeToName.put(new Character((char) 0x0044), "D"); - nameToUnicode.put("D", new Character((char) 0x0044)); - nameToEnc.put("D", new Integer(68)); - encToName[68] = "D"; - - unicodeToName.put(new Character((char) 0x0045), "E"); - nameToUnicode.put("E", new Character((char) 0x0045)); - nameToEnc.put("E", new Integer(69)); - encToName[69] = "E"; - - unicodeToName.put(new Character((char) 0x00c9), "Eacute"); - nameToUnicode.put("Eacute", new Character((char) 0x00c9)); - - unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); - nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); - - unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); - nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); - - unicodeToName.put(new Character((char) 0x00c8), "Egrave"); - nameToUnicode.put("Egrave", new Character((char) 0x00c8)); - - unicodeToName.put(new Character((char) 0x00d0), "Eth"); - nameToUnicode.put("Eth", new Character((char) 0x00d0)); - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - - unicodeToName.put(new Character((char) 0x0046), "F"); - nameToUnicode.put("F", new Character((char) 0x0046)); - nameToEnc.put("F", new Integer(70)); - encToName[70] = "F"; - - unicodeToName.put(new Character((char) 0x0047), "G"); - nameToUnicode.put("G", new Character((char) 0x0047)); - nameToEnc.put("G", new Integer(71)); - encToName[71] = "G"; - - unicodeToName.put(new Character((char) 0x0048), "H"); - nameToUnicode.put("H", new Character((char) 0x0048)); - nameToEnc.put("H", new Integer(72)); - encToName[72] = "H"; - - unicodeToName.put(new Character((char) 0x0049), "I"); - nameToUnicode.put("I", new Character((char) 0x0049)); - nameToEnc.put("I", new Integer(73)); - encToName[73] = "I"; - - unicodeToName.put(new Character((char) 0x00cd), "Iacute"); - nameToUnicode.put("Iacute", new Character((char) 0x00cd)); - - unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); - nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); - - unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); - nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); - - unicodeToName.put(new Character((char) 0x00cc), "Igrave"); - nameToUnicode.put("Igrave", new Character((char) 0x00cc)); - - unicodeToName.put(new Character((char) 0x004a), "J"); - nameToUnicode.put("J", new Character((char) 0x004a)); - nameToEnc.put("J", new Integer(74)); - encToName[74] = "J"; - - unicodeToName.put(new Character((char) 0x004b), "K"); - nameToUnicode.put("K", new Character((char) 0x004b)); - nameToEnc.put("K", new Integer(75)); - encToName[75] = "K"; - - unicodeToName.put(new Character((char) 0x004c), "L"); - nameToUnicode.put("L", new Character((char) 0x004c)); - nameToEnc.put("L", new Integer(76)); - encToName[76] = "L"; - - unicodeToName.put(new Character((char) 0x0141), "Lslash"); - nameToUnicode.put("Lslash", new Character((char) 0x0141)); - nameToEnc.put("Lslash", new Integer(232)); - encToName[232] = "Lslash"; - - unicodeToName.put(new Character((char) 0x004d), "M"); - nameToUnicode.put("M", new Character((char) 0x004d)); - nameToEnc.put("M", new Integer(77)); - encToName[77] = "M"; - - unicodeToName.put(new Character((char) 0x004e), "N"); - nameToUnicode.put("N", new Character((char) 0x004e)); - nameToEnc.put("N", new Integer(78)); - encToName[78] = "N"; - - unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); - nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); - - unicodeToName.put(new Character((char) 0x004f), "O"); - nameToUnicode.put("O", new Character((char) 0x004f)); - nameToEnc.put("O", new Integer(79)); - encToName[79] = "O"; - - unicodeToName.put(new Character((char) 0x0152), "OE"); - nameToUnicode.put("OE", new Character((char) 0x0152)); - nameToEnc.put("OE", new Integer(234)); - encToName[234] = "OE"; - - unicodeToName.put(new Character((char) 0x00d2), "Oacute"); - nameToUnicode.put("Oacute", new Character((char) 0x00d2)); - - unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); - nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); - - unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); - nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); - - unicodeToName.put(new Character((char) 0x00d3), "Ograve"); - nameToUnicode.put("Ograve", new Character((char) 0x00d3)); - - unicodeToName.put(new Character((char) 0x00d8), "Oslash"); - nameToUnicode.put("Oslash", new Character((char) 0x00d8)); - nameToEnc.put("Oslash", new Integer(233)); - encToName[233] = "Oslash"; - - unicodeToName.put(new Character((char) 0x00d5), "Otilde"); - nameToUnicode.put("Otilde", new Character((char) 0x00d5)); - - unicodeToName.put(new Character((char) 0x0050), "P"); - nameToUnicode.put("P", new Character((char) 0x0050)); - nameToEnc.put("P", new Integer(80)); - encToName[80] = "P"; - - unicodeToName.put(new Character((char) 0x0051), "Q"); - nameToUnicode.put("Q", new Character((char) 0x0051)); - nameToEnc.put("Q", new Integer(81)); - encToName[81] = "Q"; - - unicodeToName.put(new Character((char) 0x0052), "R"); - nameToUnicode.put("R", new Character((char) 0x0052)); - nameToEnc.put("R", new Integer(82)); - encToName[82] = "R"; - - unicodeToName.put(new Character((char) 0x0053), "S"); - nameToUnicode.put("S", new Character((char) 0x0053)); - nameToEnc.put("S", new Integer(83)); - encToName[83] = "S"; - - unicodeToName.put(new Character((char) 0x0160), "Scaron"); - nameToUnicode.put("Scaron", new Character((char) 0x0160)); - - unicodeToName.put(new Character((char) 0x0054), "T"); - nameToUnicode.put("T", new Character((char) 0x0054)); - nameToEnc.put("T", new Integer(84)); - encToName[84] = "T"; - - unicodeToName.put(new Character((char) 0x00de), "Thorn"); - nameToUnicode.put("Thorn", new Character((char) 0x00de)); - - unicodeToName.put(new Character((char) 0x0055), "U"); - nameToUnicode.put("U", new Character((char) 0x0055)); - nameToEnc.put("U", new Integer(85)); - encToName[85] = "U"; - - unicodeToName.put(new Character((char) 0x00da), "Uacute"); - nameToUnicode.put("Uacute", new Character((char) 0x00da)); - - unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); - nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); - - unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); - nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); - - unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); - nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); - - unicodeToName.put(new Character((char) 0x0056), "V"); - nameToUnicode.put("V", new Character((char) 0x0056)); - nameToEnc.put("V", new Integer(86)); - encToName[86] = "V"; - - unicodeToName.put(new Character((char) 0x0057), "W"); - nameToUnicode.put("W", new Character((char) 0x0057)); - nameToEnc.put("W", new Integer(87)); - encToName[87] = "W"; - - unicodeToName.put(new Character((char) 0x0058), "X"); - nameToUnicode.put("X", new Character((char) 0x0058)); - nameToEnc.put("X", new Integer(88)); - encToName[88] = "X"; - - unicodeToName.put(new Character((char) 0x0059), "Y"); - nameToUnicode.put("Y", new Character((char) 0x0059)); - nameToEnc.put("Y", new Integer(89)); - encToName[89] = "Y"; - - unicodeToName.put(new Character((char) 0x00dd), "Yacute"); - nameToUnicode.put("Yacute", new Character((char) 0x00dd)); - - unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); - nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); - - unicodeToName.put(new Character((char) 0x005a), "Z"); - nameToUnicode.put("Z", new Character((char) 0x005a)); - nameToEnc.put("Z", new Integer(90)); - encToName[90] = "Z"; - - unicodeToName.put(new Character((char) 0x017d), "Zcaron"); - nameToUnicode.put("Zcaron", new Character((char) 0x017d)); - - unicodeToName.put(new Character((char) 0x0061), "a"); - nameToUnicode.put("a", new Character((char) 0x0061)); - nameToEnc.put("a", new Integer(97)); - encToName[97] = "a"; - - unicodeToName.put(new Character((char) 0x00e1), "aacute"); - nameToUnicode.put("aacute", new Character((char) 0x00e1)); - - unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); - nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); - - unicodeToName.put(new Character((char) 0x00b4), "acute"); - nameToUnicode.put("acute", new Character((char) 0x00b4)); - nameToEnc.put("acute", new Integer(194)); - encToName[194] = "acute"; - - unicodeToName.put(new Character((char) 0x00e4), "adieresis"); - nameToUnicode.put("adieresis", new Character((char) 0x00e4)); - - unicodeToName.put(new Character((char) 0x00e6), "ae"); - nameToUnicode.put("ae", new Character((char) 0x00e6)); - nameToEnc.put("ae", new Integer(241)); - encToName[241] = "ae"; - - unicodeToName.put(new Character((char) 0x00e0), "agrave"); - nameToUnicode.put("agrave", new Character((char) 0x00e0)); - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x00e5), "aring"); - nameToUnicode.put("aring", new Character((char) 0x00e5)); - - unicodeToName.put(new Character((char) 0x005e), "asciicircum"); - nameToUnicode.put("asciicircum", new Character((char) 0x005e)); - nameToEnc.put("asciicircum", new Integer(94)); - encToName[94] = "asciicircum"; - - unicodeToName.put(new Character((char) 0x007e), "asciitilde"); - nameToUnicode.put("asciitilde", new Character((char) 0x007e)); - nameToEnc.put("asciitilde", new Integer(126)); - encToName[126] = "asciitilde"; - - unicodeToName.put(new Character((char) 0x002a), "asterisk"); - nameToUnicode.put("asterisk", new Character((char) 0x002a)); - nameToEnc.put("asterisk", new Integer(42)); - encToName[42] = "asterisk"; - - unicodeToName.put(new Character((char) 0x0040), "at"); - nameToUnicode.put("at", new Character((char) 0x0040)); - nameToEnc.put("at", new Integer(64)); - encToName[64] = "at"; - - unicodeToName.put(new Character((char) 0x00e3), "atilde"); - nameToUnicode.put("atilde", new Character((char) 0x00e3)); - - unicodeToName.put(new Character((char) 0x0062), "b"); - nameToUnicode.put("b", new Character((char) 0x0062)); - nameToEnc.put("b", new Integer(98)); - encToName[98] = "b"; - - unicodeToName.put(new Character((char) 0x005c), "backslash"); - nameToUnicode.put("backslash", new Character((char) 0x005c)); - nameToEnc.put("backslash", new Integer(92)); - encToName[92] = "backslash"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0x02d8), "breve"); - nameToUnicode.put("breve", new Character((char) 0x02d8)); - nameToEnc.put("breve", new Integer(198)); - encToName[198] = "breve"; - - unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); - nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); - - unicodeToName.put(new Character((char) 0x2022), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2022)); - nameToEnc.put("bullet", new Integer(183)); - encToName[183] = "bullet"; - - unicodeToName.put(new Character((char) 0x0063), "c"); - nameToUnicode.put("c", new Character((char) 0x0063)); - nameToEnc.put("c", new Integer(99)); - encToName[99] = "c"; - - unicodeToName.put(new Character((char) 0x02c7), "caron"); - nameToUnicode.put("caron", new Character((char) 0x02c7)); - nameToEnc.put("caron", new Integer(207)); - encToName[207] = "caron"; - - unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); - nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); - - unicodeToName.put(new Character((char) 0x00b8), "cedilla"); - nameToUnicode.put("cedilla", new Character((char) 0x00b8)); - nameToEnc.put("cedilla", new Integer(203)); - encToName[203] = "cedilla"; - - unicodeToName.put(new Character((char) 0x00a2), "cent"); - nameToUnicode.put("cent", new Character((char) 0x00a2)); - nameToEnc.put("cent", new Integer(162)); - encToName[162] = "cent"; - - unicodeToName.put(new Character((char) 0x02c6), "circumflex"); - nameToUnicode.put("circumflex", new Character((char) 0x02c6)); - nameToEnc.put("circumflex", new Integer(195)); - encToName[195] = "circumflex"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x00a9), "copyright"); - nameToUnicode.put("copyright", new Character((char) 0x00a9)); - - unicodeToName.put(new Character((char) 0x00a4), "currency"); - nameToUnicode.put("currency", new Character((char) 0x00a4)); - nameToEnc.put("currency", new Integer(168)); - encToName[168] = "currency"; - - unicodeToName.put(new Character((char) 0x0064), "d"); - nameToUnicode.put("d", new Character((char) 0x0064)); - nameToEnc.put("d", new Integer(100)); - encToName[100] = "d"; - - unicodeToName.put(new Character((char) 0x2020), "dagger"); - nameToUnicode.put("dagger", new Character((char) 0x2020)); - nameToEnc.put("dagger", new Integer(178)); - encToName[178] = "dagger"; - - unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); - nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); - nameToEnc.put("daggerdbl", new Integer(179)); - encToName[179] = "daggerdbl"; - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - - unicodeToName.put(new Character((char) 0x00a8), "dieresis"); - nameToUnicode.put("dieresis", new Character((char) 0x00a8)); - nameToEnc.put("dieresis", new Integer(200)); - encToName[200] = "dieresis"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - - unicodeToName.put(new Character((char) 0x0024), "dollar"); - nameToUnicode.put("dollar", new Character((char) 0x0024)); - nameToEnc.put("dollar", new Integer(36)); - encToName[36] = "dollar"; - - unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); - nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); - nameToEnc.put("dotaccent", new Integer(199)); - encToName[199] = "dotaccent"; - - unicodeToName.put(new Character((char) 0x0131), "dotlessi"); - nameToUnicode.put("dotlessi", new Character((char) 0x0131)); - nameToEnc.put("dotlessi", new Integer(245)); - encToName[245] = "dotlessi"; - - unicodeToName.put(new Character((char) 0x0065), "e"); - nameToUnicode.put("e", new Character((char) 0x0065)); - nameToEnc.put("e", new Integer(101)); - encToName[101] = "e"; - - unicodeToName.put(new Character((char) 0x00e9), "eacute"); - nameToUnicode.put("eacute", new Character((char) 0x00e9)); - - unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); - nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); - - unicodeToName.put(new Character((char) 0x00eb), "edieresis"); - nameToUnicode.put("edieresis", new Character((char) 0x00eb)); - - unicodeToName.put(new Character((char) 0x00e8), "egrave"); - nameToUnicode.put("egrave", new Character((char) 0x00e8)); - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - nameToEnc.put("ellipsis", new Integer(188)); - encToName[188] = "ellipsis"; - - unicodeToName.put(new Character((char) 0x002d), "emdash"); - nameToUnicode.put("emdash", new Character((char) 0x002d)); - nameToEnc.put("emdash", new Integer(208)); - encToName[208] = "emdash"; - - unicodeToName.put(new Character((char) 0x002d), "endash"); - nameToUnicode.put("endash", new Character((char) 0x002d)); - nameToEnc.put("endash", new Integer(177)); - encToName[177] = "endash"; - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x00f0), "eth"); - nameToUnicode.put("eth", new Character((char) 0x00f0)); - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); - nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); - nameToEnc.put("exclamdown", new Integer(161)); - encToName[161] = "exclamdown"; - - unicodeToName.put(new Character((char) 0x0066), "f"); - nameToUnicode.put("f", new Character((char) 0x0066)); - nameToEnc.put("f", new Integer(102)); - encToName[102] = "f"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - nameToEnc.put("fi", new Integer(174)); - encToName[174] = "fi"; - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - nameToEnc.put("fl", new Integer(175)); - encToName[175] = "fl"; - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - nameToEnc.put("florin", new Integer(166)); - encToName[166] = "florin"; - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - nameToEnc.put("fraction", new Integer(164)); - encToName[164] = "fraction"; - - unicodeToName.put(new Character((char) 0x0067), "g"); - nameToUnicode.put("g", new Character((char) 0x0067)); - nameToEnc.put("g", new Integer(103)); - encToName[103] = "g"; - - unicodeToName.put(new Character((char) 0x00df), "germandbls"); - nameToUnicode.put("germandbls", new Character((char) 0x00df)); - nameToEnc.put("germandbls", new Integer(251)); - encToName[251] = "germandbls"; - - unicodeToName.put(new Character((char) 0x0060), "grave"); - nameToUnicode.put("grave", new Character((char) 0x0060)); - nameToEnc.put("grave", new Integer(193)); - encToName[193] = "grave"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); - nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); - nameToEnc.put("guillemotleft", new Integer(171)); - encToName[171] = "guillemotleft"; - - unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); - nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); - nameToEnc.put("guillemotright", new Integer(187)); - encToName[187] = "guillemotright"; - - unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); - nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); - nameToEnc.put("guilsinglleft", new Integer(172)); - encToName[172] = "guilsinglleft"; - - unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); - nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); - nameToEnc.put("guilsinglright", new Integer(173)); - encToName[173] = "guilsinglright"; - - unicodeToName.put(new Character((char) 0x0068), "h"); - nameToUnicode.put("h", new Character((char) 0x0068)); - nameToEnc.put("h", new Integer(104)); - encToName[104] = "h"; - - unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); - nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); - nameToEnc.put("hungarumlaut", new Integer(205)); - encToName[205] = "hungarumlaut"; - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(45)); - encToName[45] = "hyphen"; - - unicodeToName.put(new Character((char) 0x0069), "i"); - nameToUnicode.put("i", new Character((char) 0x0069)); - nameToEnc.put("i", new Integer(105)); - encToName[105] = "i"; - - unicodeToName.put(new Character((char) 0x00ed), "iacute"); - nameToUnicode.put("iacute", new Character((char) 0x00ed)); - - unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); - nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); - - unicodeToName.put(new Character((char) 0x00ef), "idieresis"); - nameToUnicode.put("idieresis", new Character((char) 0x00ef)); - - unicodeToName.put(new Character((char) 0x00ec), "igrave"); - nameToUnicode.put("igrave", new Character((char) 0x00ec)); - - unicodeToName.put(new Character((char) 0x006a), "j"); - nameToUnicode.put("j", new Character((char) 0x006a)); - nameToEnc.put("j", new Integer(106)); - encToName[106] = "j"; - - unicodeToName.put(new Character((char) 0x006b), "k"); - nameToUnicode.put("k", new Character((char) 0x006b)); - nameToEnc.put("k", new Integer(107)); - encToName[107] = "k"; - - unicodeToName.put(new Character((char) 0x006c), "l"); - nameToUnicode.put("l", new Character((char) 0x006c)); - nameToEnc.put("l", new Integer(108)); - encToName[108] = "l"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - - unicodeToName.put(new Character((char) 0x0142), "lslash"); - nameToUnicode.put("lslash", new Character((char) 0x0142)); - nameToEnc.put("lslash", new Integer(248)); - encToName[248] = "lslash"; - - unicodeToName.put(new Character((char) 0x006d), "m"); - nameToUnicode.put("m", new Character((char) 0x006d)); - nameToEnc.put("m", new Integer(109)); - encToName[109] = "m"; - - unicodeToName.put(new Character((char) 0x00af), "macron"); - nameToUnicode.put("macron", new Character((char) 0x00af)); - nameToEnc.put("macron", new Integer(197)); - encToName[197] = "macron"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - - unicodeToName.put(new Character((char) 0x006e), "n"); - nameToUnicode.put("n", new Character((char) 0x006e)); - nameToEnc.put("n", new Integer(110)); - encToName[110] = "n"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x00f1), "ntilde"); - nameToUnicode.put("ntilde", new Character((char) 0x00f1)); - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x006f), "o"); - nameToUnicode.put("o", new Character((char) 0x006f)); - nameToEnc.put("o", new Integer(111)); - encToName[111] = "o"; - - unicodeToName.put(new Character((char) 0x00f3), "oacute"); - nameToUnicode.put("oacute", new Character((char) 0x00f3)); - - unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); - nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); - - unicodeToName.put(new Character((char) 0x00f6), "odieresis"); - nameToUnicode.put("odieresis", new Character((char) 0x00f6)); - - unicodeToName.put(new Character((char) 0x0153), "oe"); - nameToUnicode.put("oe", new Character((char) 0x0153)); - nameToEnc.put("oe", new Integer(250)); - encToName[250] = "oe"; - - unicodeToName.put(new Character((char) 0x02db), "ogonek"); - nameToUnicode.put("ogonek", new Character((char) 0x02db)); - nameToEnc.put("ogonek", new Integer(206)); - encToName[206] = "ogonek"; - - unicodeToName.put(new Character((char) 0x00f2), "ograve"); - nameToUnicode.put("ograve", new Character((char) 0x00f2)); - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - - unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); - nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); - nameToEnc.put("ordfeminine", new Integer(227)); - encToName[227] = "ordfeminine"; - - unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); - nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); - nameToEnc.put("ordmasculine", new Integer(235)); - encToName[235] = "ordmasculine"; - - unicodeToName.put(new Character((char) 0x00f8), "oslash"); - nameToUnicode.put("oslash", new Character((char) 0x00f8)); - nameToEnc.put("oslash", new Integer(249)); - encToName[249] = "oslash"; - - unicodeToName.put(new Character((char) 0x00f5), "otilde"); - nameToUnicode.put("otilde", new Character((char) 0x00f5)); - - unicodeToName.put(new Character((char) 0x0070), "p"); - nameToUnicode.put("p", new Character((char) 0x0070)); - nameToEnc.put("p", new Integer(112)); - encToName[112] = "p"; - - unicodeToName.put(new Character((char) 0x00b6), "paragraph"); - nameToUnicode.put("paragraph", new Character((char) 0x00b6)); - nameToEnc.put("paragraph", new Integer(182)); - encToName[182] = "paragraph"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); - nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); - nameToEnc.put("periodcentered", new Integer(180)); - encToName[180] = "periodcentered"; - - unicodeToName.put(new Character((char) 0x2030), "perthousand"); - nameToUnicode.put("perthousand", new Character((char) 0x2030)); - nameToEnc.put("perthousand", new Integer(189)); - encToName[189] = "perthousand"; - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - - unicodeToName.put(new Character((char) 0x0071), "q"); - nameToUnicode.put("q", new Character((char) 0x0071)); - nameToEnc.put("q", new Integer(113)); - encToName[113] = "q"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x00bf), "questiondown"); - nameToUnicode.put("questiondown", new Character((char) 0x00bf)); - nameToEnc.put("questiondown", new Integer(191)); - encToName[191] = "questiondown"; - - unicodeToName.put(new Character((char) 0x0022), "quotedbl"); - nameToUnicode.put("quotedbl", new Character((char) 0x0022)); - nameToEnc.put("quotedbl", new Integer(34)); - encToName[34] = "quotedbl"; - - unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); - nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); - nameToEnc.put("quotedblbase", new Integer(185)); - encToName[185] = "quotedblbase"; - - unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); - nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); - nameToEnc.put("quotedblleft", new Integer(170)); - encToName[170] = "quotedblleft"; - - unicodeToName.put(new Character((char) 0x201d), "quotedblright"); - nameToUnicode.put("quotedblright", new Character((char) 0x201d)); - nameToEnc.put("quotedblright", new Integer(186)); - encToName[186] = "quotedblright"; - - unicodeToName.put(new Character((char) 0x0060), "quoteleft"); - nameToUnicode.put("quoteleft", new Character((char) 0x0060)); - nameToEnc.put("quoteleft", new Integer(96)); - encToName[96] = "quoteleft"; - - unicodeToName.put(new Character((char) 0x0027), "quoteright"); - nameToUnicode.put("quoteright", new Character((char) 0x0027)); - nameToEnc.put("quoteright", new Integer(39)); - encToName[39] = "quoteright"; - - unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); - nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); - nameToEnc.put("quotesinglbase", new Integer(184)); - encToName[184] = "quotesinglbase"; - - unicodeToName.put(new Character((char) 0x0027), "quotesingle"); - nameToUnicode.put("quotesingle", new Character((char) 0x0027)); - nameToEnc.put("quotesingle", new Integer(169)); - encToName[169] = "quotesingle"; - - unicodeToName.put(new Character((char) 0x0072), "r"); - nameToUnicode.put("r", new Character((char) 0x0072)); - nameToEnc.put("r", new Integer(114)); - encToName[114] = "r"; - - unicodeToName.put(new Character((char) 0x00ae), "registered"); - nameToUnicode.put("registered", new Character((char) 0x00ae)); - - unicodeToName.put(new Character((char) 0x02da), "ring"); - nameToUnicode.put("ring", new Character((char) 0x02da)); - nameToEnc.put("ring", new Integer(202)); - encToName[202] = "ring"; - - unicodeToName.put(new Character((char) 0x0073), "s"); - nameToUnicode.put("s", new Character((char) 0x0073)); - nameToEnc.put("s", new Integer(115)); - encToName[115] = "s"; - - unicodeToName.put(new Character((char) 0x0161), "scaron"); - nameToUnicode.put("scaron", new Character((char) 0x0161)); - - unicodeToName.put(new Character((char) 0x00a7), "section"); - nameToUnicode.put("section", new Character((char) 0x00a7)); - nameToEnc.put("section", new Integer(167)); - encToName[167] = "section"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x00a3), "sterling"); - nameToUnicode.put("sterling", new Character((char) 0x00a3)); - nameToEnc.put("sterling", new Integer(163)); - encToName[163] = "sterling"; - - unicodeToName.put(new Character((char) 0x0074), "t"); - nameToUnicode.put("t", new Character((char) 0x0074)); - nameToEnc.put("t", new Integer(116)); - encToName[116] = "t"; - - unicodeToName.put(new Character((char) 0x00fe), "thorn"); - nameToUnicode.put("thorn", new Character((char) 0x00fe)); - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - - unicodeToName.put(new Character((char) 0x02dc), "tilde"); - nameToUnicode.put("tilde", new Character((char) 0x02dc)); - nameToEnc.put("tilde", new Integer(196)); - encToName[196] = "tilde"; - - unicodeToName.put(new Character((char) 0x2122), "trademark"); - nameToUnicode.put("trademark", new Character((char) 0x2122)); - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - - unicodeToName.put(new Character((char) 0x0075), "u"); - nameToUnicode.put("u", new Character((char) 0x0075)); - nameToEnc.put("u", new Integer(117)); - encToName[117] = "u"; - - unicodeToName.put(new Character((char) 0x00fa), "uacute"); - nameToUnicode.put("uacute", new Character((char) 0x00fa)); - - unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); - nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); - - unicodeToName.put(new Character((char) 0x00fc), "udieresis"); - nameToUnicode.put("udieresis", new Character((char) 0x00fc)); - - unicodeToName.put(new Character((char) 0x00f9), "ugrave"); - nameToUnicode.put("ugrave", new Character((char) 0x00f9)); - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x0076), "v"); - nameToUnicode.put("v", new Character((char) 0x0076)); - nameToEnc.put("v", new Integer(118)); - encToName[118] = "v"; - - unicodeToName.put(new Character((char) 0x0077), "w"); - nameToUnicode.put("w", new Character((char) 0x0077)); - nameToEnc.put("w", new Integer(119)); - encToName[119] = "w"; - - unicodeToName.put(new Character((char) 0x0078), "x"); - nameToUnicode.put("x", new Character((char) 0x0078)); - nameToEnc.put("x", new Integer(120)); - encToName[120] = "x"; - - unicodeToName.put(new Character((char) 0x0079), "y"); - nameToUnicode.put("y", new Character((char) 0x0079)); - nameToEnc.put("y", new Integer(121)); - encToName[121] = "y"; - - unicodeToName.put(new Character((char) 0x00fd), "yacute"); - nameToUnicode.put("yacute", new Character((char) 0x00fd)); - - unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); - nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); - - unicodeToName.put(new Character((char) 0x00a5), "yen"); - nameToUnicode.put("yen", new Character((char) 0x00a5)); - nameToEnc.put("yen", new Integer(165)); - encToName[165] = "yen"; - - unicodeToName.put(new Character((char) 0x007a), "z"); - nameToUnicode.put("z", new Character((char) 0x007a)); - nameToEnc.put("z", new Integer(122)); - encToName[122] = "z"; - - unicodeToName.put(new Character((char) 0x017e), "zcaron"); - nameToUnicode.put("zcaron", new Character((char) 0x017e)); - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Latin");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("STD");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated STDLatin Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class STDLatin extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public STDLatin() { + unicodeToName.put(new Character((char) 0x0041), "A"); + nameToUnicode.put("A", new Character((char) 0x0041)); + nameToEnc.put("A", new Integer(65)); + encToName[65] = "A"; + + unicodeToName.put(new Character((char) 0x00c6), "AE"); + nameToUnicode.put("AE", new Character((char) 0x00c6)); + nameToEnc.put("AE", new Integer(225)); + encToName[225] = "AE"; + + unicodeToName.put(new Character((char) 0x00c1), "Aacute"); + nameToUnicode.put("Aacute", new Character((char) 0x00c1)); + + unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); + nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); + + unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); + nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); + + unicodeToName.put(new Character((char) 0x00c0), "Agrave"); + nameToUnicode.put("Agrave", new Character((char) 0x00c0)); + + unicodeToName.put(new Character((char) 0x00c5), "Aring"); + nameToUnicode.put("Aring", new Character((char) 0x00c5)); + + unicodeToName.put(new Character((char) 0x00c3), "Atilde"); + nameToUnicode.put("Atilde", new Character((char) 0x00c3)); + + unicodeToName.put(new Character((char) 0x0042), "B"); + nameToUnicode.put("B", new Character((char) 0x0042)); + nameToEnc.put("B", new Integer(66)); + encToName[66] = "B"; + + unicodeToName.put(new Character((char) 0x0043), "C"); + nameToUnicode.put("C", new Character((char) 0x0043)); + nameToEnc.put("C", new Integer(67)); + encToName[67] = "C"; + + unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); + nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); + + unicodeToName.put(new Character((char) 0x0044), "D"); + nameToUnicode.put("D", new Character((char) 0x0044)); + nameToEnc.put("D", new Integer(68)); + encToName[68] = "D"; + + unicodeToName.put(new Character((char) 0x0045), "E"); + nameToUnicode.put("E", new Character((char) 0x0045)); + nameToEnc.put("E", new Integer(69)); + encToName[69] = "E"; + + unicodeToName.put(new Character((char) 0x00c9), "Eacute"); + nameToUnicode.put("Eacute", new Character((char) 0x00c9)); + + unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); + nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); + + unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); + nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); + + unicodeToName.put(new Character((char) 0x00c8), "Egrave"); + nameToUnicode.put("Egrave", new Character((char) 0x00c8)); + + unicodeToName.put(new Character((char) 0x00d0), "Eth"); + nameToUnicode.put("Eth", new Character((char) 0x00d0)); + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + + unicodeToName.put(new Character((char) 0x0046), "F"); + nameToUnicode.put("F", new Character((char) 0x0046)); + nameToEnc.put("F", new Integer(70)); + encToName[70] = "F"; + + unicodeToName.put(new Character((char) 0x0047), "G"); + nameToUnicode.put("G", new Character((char) 0x0047)); + nameToEnc.put("G", new Integer(71)); + encToName[71] = "G"; + + unicodeToName.put(new Character((char) 0x0048), "H"); + nameToUnicode.put("H", new Character((char) 0x0048)); + nameToEnc.put("H", new Integer(72)); + encToName[72] = "H"; + + unicodeToName.put(new Character((char) 0x0049), "I"); + nameToUnicode.put("I", new Character((char) 0x0049)); + nameToEnc.put("I", new Integer(73)); + encToName[73] = "I"; + + unicodeToName.put(new Character((char) 0x00cd), "Iacute"); + nameToUnicode.put("Iacute", new Character((char) 0x00cd)); + + unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); + nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); + + unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); + nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); + + unicodeToName.put(new Character((char) 0x00cc), "Igrave"); + nameToUnicode.put("Igrave", new Character((char) 0x00cc)); + + unicodeToName.put(new Character((char) 0x004a), "J"); + nameToUnicode.put("J", new Character((char) 0x004a)); + nameToEnc.put("J", new Integer(74)); + encToName[74] = "J"; + + unicodeToName.put(new Character((char) 0x004b), "K"); + nameToUnicode.put("K", new Character((char) 0x004b)); + nameToEnc.put("K", new Integer(75)); + encToName[75] = "K"; + + unicodeToName.put(new Character((char) 0x004c), "L"); + nameToUnicode.put("L", new Character((char) 0x004c)); + nameToEnc.put("L", new Integer(76)); + encToName[76] = "L"; + + unicodeToName.put(new Character((char) 0x0141), "Lslash"); + nameToUnicode.put("Lslash", new Character((char) 0x0141)); + nameToEnc.put("Lslash", new Integer(232)); + encToName[232] = "Lslash"; + + unicodeToName.put(new Character((char) 0x004d), "M"); + nameToUnicode.put("M", new Character((char) 0x004d)); + nameToEnc.put("M", new Integer(77)); + encToName[77] = "M"; + + unicodeToName.put(new Character((char) 0x004e), "N"); + nameToUnicode.put("N", new Character((char) 0x004e)); + nameToEnc.put("N", new Integer(78)); + encToName[78] = "N"; + + unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); + nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); + + unicodeToName.put(new Character((char) 0x004f), "O"); + nameToUnicode.put("O", new Character((char) 0x004f)); + nameToEnc.put("O", new Integer(79)); + encToName[79] = "O"; + + unicodeToName.put(new Character((char) 0x0152), "OE"); + nameToUnicode.put("OE", new Character((char) 0x0152)); + nameToEnc.put("OE", new Integer(234)); + encToName[234] = "OE"; + + unicodeToName.put(new Character((char) 0x00d2), "Oacute"); + nameToUnicode.put("Oacute", new Character((char) 0x00d2)); + + unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); + nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); + + unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); + nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); + + unicodeToName.put(new Character((char) 0x00d3), "Ograve"); + nameToUnicode.put("Ograve", new Character((char) 0x00d3)); + + unicodeToName.put(new Character((char) 0x00d8), "Oslash"); + nameToUnicode.put("Oslash", new Character((char) 0x00d8)); + nameToEnc.put("Oslash", new Integer(233)); + encToName[233] = "Oslash"; + + unicodeToName.put(new Character((char) 0x00d5), "Otilde"); + nameToUnicode.put("Otilde", new Character((char) 0x00d5)); + + unicodeToName.put(new Character((char) 0x0050), "P"); + nameToUnicode.put("P", new Character((char) 0x0050)); + nameToEnc.put("P", new Integer(80)); + encToName[80] = "P"; + + unicodeToName.put(new Character((char) 0x0051), "Q"); + nameToUnicode.put("Q", new Character((char) 0x0051)); + nameToEnc.put("Q", new Integer(81)); + encToName[81] = "Q"; + + unicodeToName.put(new Character((char) 0x0052), "R"); + nameToUnicode.put("R", new Character((char) 0x0052)); + nameToEnc.put("R", new Integer(82)); + encToName[82] = "R"; + + unicodeToName.put(new Character((char) 0x0053), "S"); + nameToUnicode.put("S", new Character((char) 0x0053)); + nameToEnc.put("S", new Integer(83)); + encToName[83] = "S"; + + unicodeToName.put(new Character((char) 0x0160), "Scaron"); + nameToUnicode.put("Scaron", new Character((char) 0x0160)); + + unicodeToName.put(new Character((char) 0x0054), "T"); + nameToUnicode.put("T", new Character((char) 0x0054)); + nameToEnc.put("T", new Integer(84)); + encToName[84] = "T"; + + unicodeToName.put(new Character((char) 0x00de), "Thorn"); + nameToUnicode.put("Thorn", new Character((char) 0x00de)); + + unicodeToName.put(new Character((char) 0x0055), "U"); + nameToUnicode.put("U", new Character((char) 0x0055)); + nameToEnc.put("U", new Integer(85)); + encToName[85] = "U"; + + unicodeToName.put(new Character((char) 0x00da), "Uacute"); + nameToUnicode.put("Uacute", new Character((char) 0x00da)); + + unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); + nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); + + unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); + nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); + + unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); + nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); + + unicodeToName.put(new Character((char) 0x0056), "V"); + nameToUnicode.put("V", new Character((char) 0x0056)); + nameToEnc.put("V", new Integer(86)); + encToName[86] = "V"; + + unicodeToName.put(new Character((char) 0x0057), "W"); + nameToUnicode.put("W", new Character((char) 0x0057)); + nameToEnc.put("W", new Integer(87)); + encToName[87] = "W"; + + unicodeToName.put(new Character((char) 0x0058), "X"); + nameToUnicode.put("X", new Character((char) 0x0058)); + nameToEnc.put("X", new Integer(88)); + encToName[88] = "X"; + + unicodeToName.put(new Character((char) 0x0059), "Y"); + nameToUnicode.put("Y", new Character((char) 0x0059)); + nameToEnc.put("Y", new Integer(89)); + encToName[89] = "Y"; + + unicodeToName.put(new Character((char) 0x00dd), "Yacute"); + nameToUnicode.put("Yacute", new Character((char) 0x00dd)); + + unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); + nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); + + unicodeToName.put(new Character((char) 0x005a), "Z"); + nameToUnicode.put("Z", new Character((char) 0x005a)); + nameToEnc.put("Z", new Integer(90)); + encToName[90] = "Z"; + + unicodeToName.put(new Character((char) 0x017d), "Zcaron"); + nameToUnicode.put("Zcaron", new Character((char) 0x017d)); + + unicodeToName.put(new Character((char) 0x0061), "a"); + nameToUnicode.put("a", new Character((char) 0x0061)); + nameToEnc.put("a", new Integer(97)); + encToName[97] = "a"; + + unicodeToName.put(new Character((char) 0x00e1), "aacute"); + nameToUnicode.put("aacute", new Character((char) 0x00e1)); + + unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); + nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); + + unicodeToName.put(new Character((char) 0x00b4), "acute"); + nameToUnicode.put("acute", new Character((char) 0x00b4)); + nameToEnc.put("acute", new Integer(194)); + encToName[194] = "acute"; + + unicodeToName.put(new Character((char) 0x00e4), "adieresis"); + nameToUnicode.put("adieresis", new Character((char) 0x00e4)); + + unicodeToName.put(new Character((char) 0x00e6), "ae"); + nameToUnicode.put("ae", new Character((char) 0x00e6)); + nameToEnc.put("ae", new Integer(241)); + encToName[241] = "ae"; + + unicodeToName.put(new Character((char) 0x00e0), "agrave"); + nameToUnicode.put("agrave", new Character((char) 0x00e0)); + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x00e5), "aring"); + nameToUnicode.put("aring", new Character((char) 0x00e5)); + + unicodeToName.put(new Character((char) 0x005e), "asciicircum"); + nameToUnicode.put("asciicircum", new Character((char) 0x005e)); + nameToEnc.put("asciicircum", new Integer(94)); + encToName[94] = "asciicircum"; + + unicodeToName.put(new Character((char) 0x007e), "asciitilde"); + nameToUnicode.put("asciitilde", new Character((char) 0x007e)); + nameToEnc.put("asciitilde", new Integer(126)); + encToName[126] = "asciitilde"; + + unicodeToName.put(new Character((char) 0x002a), "asterisk"); + nameToUnicode.put("asterisk", new Character((char) 0x002a)); + nameToEnc.put("asterisk", new Integer(42)); + encToName[42] = "asterisk"; + + unicodeToName.put(new Character((char) 0x0040), "at"); + nameToUnicode.put("at", new Character((char) 0x0040)); + nameToEnc.put("at", new Integer(64)); + encToName[64] = "at"; + + unicodeToName.put(new Character((char) 0x00e3), "atilde"); + nameToUnicode.put("atilde", new Character((char) 0x00e3)); + + unicodeToName.put(new Character((char) 0x0062), "b"); + nameToUnicode.put("b", new Character((char) 0x0062)); + nameToEnc.put("b", new Integer(98)); + encToName[98] = "b"; + + unicodeToName.put(new Character((char) 0x005c), "backslash"); + nameToUnicode.put("backslash", new Character((char) 0x005c)); + nameToEnc.put("backslash", new Integer(92)); + encToName[92] = "backslash"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0x02d8), "breve"); + nameToUnicode.put("breve", new Character((char) 0x02d8)); + nameToEnc.put("breve", new Integer(198)); + encToName[198] = "breve"; + + unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); + nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); + + unicodeToName.put(new Character((char) 0x2022), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2022)); + nameToEnc.put("bullet", new Integer(183)); + encToName[183] = "bullet"; + + unicodeToName.put(new Character((char) 0x0063), "c"); + nameToUnicode.put("c", new Character((char) 0x0063)); + nameToEnc.put("c", new Integer(99)); + encToName[99] = "c"; + + unicodeToName.put(new Character((char) 0x02c7), "caron"); + nameToUnicode.put("caron", new Character((char) 0x02c7)); + nameToEnc.put("caron", new Integer(207)); + encToName[207] = "caron"; + + unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); + nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); + + unicodeToName.put(new Character((char) 0x00b8), "cedilla"); + nameToUnicode.put("cedilla", new Character((char) 0x00b8)); + nameToEnc.put("cedilla", new Integer(203)); + encToName[203] = "cedilla"; + + unicodeToName.put(new Character((char) 0x00a2), "cent"); + nameToUnicode.put("cent", new Character((char) 0x00a2)); + nameToEnc.put("cent", new Integer(162)); + encToName[162] = "cent"; + + unicodeToName.put(new Character((char) 0x02c6), "circumflex"); + nameToUnicode.put("circumflex", new Character((char) 0x02c6)); + nameToEnc.put("circumflex", new Integer(195)); + encToName[195] = "circumflex"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x00a9), "copyright"); + nameToUnicode.put("copyright", new Character((char) 0x00a9)); + + unicodeToName.put(new Character((char) 0x00a4), "currency"); + nameToUnicode.put("currency", new Character((char) 0x00a4)); + nameToEnc.put("currency", new Integer(168)); + encToName[168] = "currency"; + + unicodeToName.put(new Character((char) 0x0064), "d"); + nameToUnicode.put("d", new Character((char) 0x0064)); + nameToEnc.put("d", new Integer(100)); + encToName[100] = "d"; + + unicodeToName.put(new Character((char) 0x2020), "dagger"); + nameToUnicode.put("dagger", new Character((char) 0x2020)); + nameToEnc.put("dagger", new Integer(178)); + encToName[178] = "dagger"; + + unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); + nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); + nameToEnc.put("daggerdbl", new Integer(179)); + encToName[179] = "daggerdbl"; + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + + unicodeToName.put(new Character((char) 0x00a8), "dieresis"); + nameToUnicode.put("dieresis", new Character((char) 0x00a8)); + nameToEnc.put("dieresis", new Integer(200)); + encToName[200] = "dieresis"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + + unicodeToName.put(new Character((char) 0x0024), "dollar"); + nameToUnicode.put("dollar", new Character((char) 0x0024)); + nameToEnc.put("dollar", new Integer(36)); + encToName[36] = "dollar"; + + unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); + nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); + nameToEnc.put("dotaccent", new Integer(199)); + encToName[199] = "dotaccent"; + + unicodeToName.put(new Character((char) 0x0131), "dotlessi"); + nameToUnicode.put("dotlessi", new Character((char) 0x0131)); + nameToEnc.put("dotlessi", new Integer(245)); + encToName[245] = "dotlessi"; + + unicodeToName.put(new Character((char) 0x0065), "e"); + nameToUnicode.put("e", new Character((char) 0x0065)); + nameToEnc.put("e", new Integer(101)); + encToName[101] = "e"; + + unicodeToName.put(new Character((char) 0x00e9), "eacute"); + nameToUnicode.put("eacute", new Character((char) 0x00e9)); + + unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); + nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); + + unicodeToName.put(new Character((char) 0x00eb), "edieresis"); + nameToUnicode.put("edieresis", new Character((char) 0x00eb)); + + unicodeToName.put(new Character((char) 0x00e8), "egrave"); + nameToUnicode.put("egrave", new Character((char) 0x00e8)); + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + nameToEnc.put("ellipsis", new Integer(188)); + encToName[188] = "ellipsis"; + + unicodeToName.put(new Character((char) 0x002d), "emdash"); + nameToUnicode.put("emdash", new Character((char) 0x002d)); + nameToEnc.put("emdash", new Integer(208)); + encToName[208] = "emdash"; + + unicodeToName.put(new Character((char) 0x002d), "endash"); + nameToUnicode.put("endash", new Character((char) 0x002d)); + nameToEnc.put("endash", new Integer(177)); + encToName[177] = "endash"; + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x00f0), "eth"); + nameToUnicode.put("eth", new Character((char) 0x00f0)); + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); + nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); + nameToEnc.put("exclamdown", new Integer(161)); + encToName[161] = "exclamdown"; + + unicodeToName.put(new Character((char) 0x0066), "f"); + nameToUnicode.put("f", new Character((char) 0x0066)); + nameToEnc.put("f", new Integer(102)); + encToName[102] = "f"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + nameToEnc.put("fi", new Integer(174)); + encToName[174] = "fi"; + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + nameToEnc.put("fl", new Integer(175)); + encToName[175] = "fl"; + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + nameToEnc.put("florin", new Integer(166)); + encToName[166] = "florin"; + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + nameToEnc.put("fraction", new Integer(164)); + encToName[164] = "fraction"; + + unicodeToName.put(new Character((char) 0x0067), "g"); + nameToUnicode.put("g", new Character((char) 0x0067)); + nameToEnc.put("g", new Integer(103)); + encToName[103] = "g"; + + unicodeToName.put(new Character((char) 0x00df), "germandbls"); + nameToUnicode.put("germandbls", new Character((char) 0x00df)); + nameToEnc.put("germandbls", new Integer(251)); + encToName[251] = "germandbls"; + + unicodeToName.put(new Character((char) 0x0060), "grave"); + nameToUnicode.put("grave", new Character((char) 0x0060)); + nameToEnc.put("grave", new Integer(193)); + encToName[193] = "grave"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); + nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); + nameToEnc.put("guillemotleft", new Integer(171)); + encToName[171] = "guillemotleft"; + + unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); + nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); + nameToEnc.put("guillemotright", new Integer(187)); + encToName[187] = "guillemotright"; + + unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); + nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); + nameToEnc.put("guilsinglleft", new Integer(172)); + encToName[172] = "guilsinglleft"; + + unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); + nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); + nameToEnc.put("guilsinglright", new Integer(173)); + encToName[173] = "guilsinglright"; + + unicodeToName.put(new Character((char) 0x0068), "h"); + nameToUnicode.put("h", new Character((char) 0x0068)); + nameToEnc.put("h", new Integer(104)); + encToName[104] = "h"; + + unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); + nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); + nameToEnc.put("hungarumlaut", new Integer(205)); + encToName[205] = "hungarumlaut"; + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(45)); + encToName[45] = "hyphen"; + + unicodeToName.put(new Character((char) 0x0069), "i"); + nameToUnicode.put("i", new Character((char) 0x0069)); + nameToEnc.put("i", new Integer(105)); + encToName[105] = "i"; + + unicodeToName.put(new Character((char) 0x00ed), "iacute"); + nameToUnicode.put("iacute", new Character((char) 0x00ed)); + + unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); + nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); + + unicodeToName.put(new Character((char) 0x00ef), "idieresis"); + nameToUnicode.put("idieresis", new Character((char) 0x00ef)); + + unicodeToName.put(new Character((char) 0x00ec), "igrave"); + nameToUnicode.put("igrave", new Character((char) 0x00ec)); + + unicodeToName.put(new Character((char) 0x006a), "j"); + nameToUnicode.put("j", new Character((char) 0x006a)); + nameToEnc.put("j", new Integer(106)); + encToName[106] = "j"; + + unicodeToName.put(new Character((char) 0x006b), "k"); + nameToUnicode.put("k", new Character((char) 0x006b)); + nameToEnc.put("k", new Integer(107)); + encToName[107] = "k"; + + unicodeToName.put(new Character((char) 0x006c), "l"); + nameToUnicode.put("l", new Character((char) 0x006c)); + nameToEnc.put("l", new Integer(108)); + encToName[108] = "l"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + + unicodeToName.put(new Character((char) 0x0142), "lslash"); + nameToUnicode.put("lslash", new Character((char) 0x0142)); + nameToEnc.put("lslash", new Integer(248)); + encToName[248] = "lslash"; + + unicodeToName.put(new Character((char) 0x006d), "m"); + nameToUnicode.put("m", new Character((char) 0x006d)); + nameToEnc.put("m", new Integer(109)); + encToName[109] = "m"; + + unicodeToName.put(new Character((char) 0x00af), "macron"); + nameToUnicode.put("macron", new Character((char) 0x00af)); + nameToEnc.put("macron", new Integer(197)); + encToName[197] = "macron"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + + unicodeToName.put(new Character((char) 0x006e), "n"); + nameToUnicode.put("n", new Character((char) 0x006e)); + nameToEnc.put("n", new Integer(110)); + encToName[110] = "n"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x00f1), "ntilde"); + nameToUnicode.put("ntilde", new Character((char) 0x00f1)); + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x006f), "o"); + nameToUnicode.put("o", new Character((char) 0x006f)); + nameToEnc.put("o", new Integer(111)); + encToName[111] = "o"; + + unicodeToName.put(new Character((char) 0x00f3), "oacute"); + nameToUnicode.put("oacute", new Character((char) 0x00f3)); + + unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); + nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); + + unicodeToName.put(new Character((char) 0x00f6), "odieresis"); + nameToUnicode.put("odieresis", new Character((char) 0x00f6)); + + unicodeToName.put(new Character((char) 0x0153), "oe"); + nameToUnicode.put("oe", new Character((char) 0x0153)); + nameToEnc.put("oe", new Integer(250)); + encToName[250] = "oe"; + + unicodeToName.put(new Character((char) 0x02db), "ogonek"); + nameToUnicode.put("ogonek", new Character((char) 0x02db)); + nameToEnc.put("ogonek", new Integer(206)); + encToName[206] = "ogonek"; + + unicodeToName.put(new Character((char) 0x00f2), "ograve"); + nameToUnicode.put("ograve", new Character((char) 0x00f2)); + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + + unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); + nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); + nameToEnc.put("ordfeminine", new Integer(227)); + encToName[227] = "ordfeminine"; + + unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); + nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); + nameToEnc.put("ordmasculine", new Integer(235)); + encToName[235] = "ordmasculine"; + + unicodeToName.put(new Character((char) 0x00f8), "oslash"); + nameToUnicode.put("oslash", new Character((char) 0x00f8)); + nameToEnc.put("oslash", new Integer(249)); + encToName[249] = "oslash"; + + unicodeToName.put(new Character((char) 0x00f5), "otilde"); + nameToUnicode.put("otilde", new Character((char) 0x00f5)); + + unicodeToName.put(new Character((char) 0x0070), "p"); + nameToUnicode.put("p", new Character((char) 0x0070)); + nameToEnc.put("p", new Integer(112)); + encToName[112] = "p"; + + unicodeToName.put(new Character((char) 0x00b6), "paragraph"); + nameToUnicode.put("paragraph", new Character((char) 0x00b6)); + nameToEnc.put("paragraph", new Integer(182)); + encToName[182] = "paragraph"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); + nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); + nameToEnc.put("periodcentered", new Integer(180)); + encToName[180] = "periodcentered"; + + unicodeToName.put(new Character((char) 0x2030), "perthousand"); + nameToUnicode.put("perthousand", new Character((char) 0x2030)); + nameToEnc.put("perthousand", new Integer(189)); + encToName[189] = "perthousand"; + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + + unicodeToName.put(new Character((char) 0x0071), "q"); + nameToUnicode.put("q", new Character((char) 0x0071)); + nameToEnc.put("q", new Integer(113)); + encToName[113] = "q"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x00bf), "questiondown"); + nameToUnicode.put("questiondown", new Character((char) 0x00bf)); + nameToEnc.put("questiondown", new Integer(191)); + encToName[191] = "questiondown"; + + unicodeToName.put(new Character((char) 0x0022), "quotedbl"); + nameToUnicode.put("quotedbl", new Character((char) 0x0022)); + nameToEnc.put("quotedbl", new Integer(34)); + encToName[34] = "quotedbl"; + + unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); + nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); + nameToEnc.put("quotedblbase", new Integer(185)); + encToName[185] = "quotedblbase"; + + unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); + nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); + nameToEnc.put("quotedblleft", new Integer(170)); + encToName[170] = "quotedblleft"; + + unicodeToName.put(new Character((char) 0x201d), "quotedblright"); + nameToUnicode.put("quotedblright", new Character((char) 0x201d)); + nameToEnc.put("quotedblright", new Integer(186)); + encToName[186] = "quotedblright"; + + unicodeToName.put(new Character((char) 0x0060), "quoteleft"); + nameToUnicode.put("quoteleft", new Character((char) 0x0060)); + nameToEnc.put("quoteleft", new Integer(96)); + encToName[96] = "quoteleft"; + + unicodeToName.put(new Character((char) 0x0027), "quoteright"); + nameToUnicode.put("quoteright", new Character((char) 0x0027)); + nameToEnc.put("quoteright", new Integer(39)); + encToName[39] = "quoteright"; + + unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); + nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); + nameToEnc.put("quotesinglbase", new Integer(184)); + encToName[184] = "quotesinglbase"; + + unicodeToName.put(new Character((char) 0x0027), "quotesingle"); + nameToUnicode.put("quotesingle", new Character((char) 0x0027)); + nameToEnc.put("quotesingle", new Integer(169)); + encToName[169] = "quotesingle"; + + unicodeToName.put(new Character((char) 0x0072), "r"); + nameToUnicode.put("r", new Character((char) 0x0072)); + nameToEnc.put("r", new Integer(114)); + encToName[114] = "r"; + + unicodeToName.put(new Character((char) 0x00ae), "registered"); + nameToUnicode.put("registered", new Character((char) 0x00ae)); + + unicodeToName.put(new Character((char) 0x02da), "ring"); + nameToUnicode.put("ring", new Character((char) 0x02da)); + nameToEnc.put("ring", new Integer(202)); + encToName[202] = "ring"; + + unicodeToName.put(new Character((char) 0x0073), "s"); + nameToUnicode.put("s", new Character((char) 0x0073)); + nameToEnc.put("s", new Integer(115)); + encToName[115] = "s"; + + unicodeToName.put(new Character((char) 0x0161), "scaron"); + nameToUnicode.put("scaron", new Character((char) 0x0161)); + + unicodeToName.put(new Character((char) 0x00a7), "section"); + nameToUnicode.put("section", new Character((char) 0x00a7)); + nameToEnc.put("section", new Integer(167)); + encToName[167] = "section"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x00a3), "sterling"); + nameToUnicode.put("sterling", new Character((char) 0x00a3)); + nameToEnc.put("sterling", new Integer(163)); + encToName[163] = "sterling"; + + unicodeToName.put(new Character((char) 0x0074), "t"); + nameToUnicode.put("t", new Character((char) 0x0074)); + nameToEnc.put("t", new Integer(116)); + encToName[116] = "t"; + + unicodeToName.put(new Character((char) 0x00fe), "thorn"); + nameToUnicode.put("thorn", new Character((char) 0x00fe)); + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + + unicodeToName.put(new Character((char) 0x02dc), "tilde"); + nameToUnicode.put("tilde", new Character((char) 0x02dc)); + nameToEnc.put("tilde", new Integer(196)); + encToName[196] = "tilde"; + + unicodeToName.put(new Character((char) 0x2122), "trademark"); + nameToUnicode.put("trademark", new Character((char) 0x2122)); + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + + unicodeToName.put(new Character((char) 0x0075), "u"); + nameToUnicode.put("u", new Character((char) 0x0075)); + nameToEnc.put("u", new Integer(117)); + encToName[117] = "u"; + + unicodeToName.put(new Character((char) 0x00fa), "uacute"); + nameToUnicode.put("uacute", new Character((char) 0x00fa)); + + unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); + nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); + + unicodeToName.put(new Character((char) 0x00fc), "udieresis"); + nameToUnicode.put("udieresis", new Character((char) 0x00fc)); + + unicodeToName.put(new Character((char) 0x00f9), "ugrave"); + nameToUnicode.put("ugrave", new Character((char) 0x00f9)); + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x0076), "v"); + nameToUnicode.put("v", new Character((char) 0x0076)); + nameToEnc.put("v", new Integer(118)); + encToName[118] = "v"; + + unicodeToName.put(new Character((char) 0x0077), "w"); + nameToUnicode.put("w", new Character((char) 0x0077)); + nameToEnc.put("w", new Integer(119)); + encToName[119] = "w"; + + unicodeToName.put(new Character((char) 0x0078), "x"); + nameToUnicode.put("x", new Character((char) 0x0078)); + nameToEnc.put("x", new Integer(120)); + encToName[120] = "x"; + + unicodeToName.put(new Character((char) 0x0079), "y"); + nameToUnicode.put("y", new Character((char) 0x0079)); + nameToEnc.put("y", new Integer(121)); + encToName[121] = "y"; + + unicodeToName.put(new Character((char) 0x00fd), "yacute"); + nameToUnicode.put("yacute", new Character((char) 0x00fd)); + + unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); + nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); + + unicodeToName.put(new Character((char) 0x00a5), "yen"); + nameToUnicode.put("yen", new Character((char) 0x00a5)); + nameToEnc.put("yen", new Integer(165)); + encToName[165] = "yen"; + + unicodeToName.put(new Character((char) 0x007a), "z"); + nameToUnicode.put("z", new Character((char) 0x007a)); + nameToEnc.put("z", new Integer(122)); + encToName[122] = "z"; + + unicodeToName.put(new Character((char) 0x017e), "zcaron"); + nameToUnicode.put("zcaron", new Character((char) 0x017e)); + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Latin");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("STD");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Symbol.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Symbol.java index 3b9f1c118..4b1024443 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Symbol.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Symbol.java @@ -1,994 +1,994 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated Symbol Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class Symbol extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public Symbol() { - unicodeToName.put(new Character((char) 0x0391), "Alpha"); - nameToUnicode.put("Alpha", new Character((char) 0x0391)); - nameToEnc.put("Alpha", new Integer(65)); - encToName[65] = "Alpha"; - - unicodeToName.put(new Character((char) 0x0392), "Beta"); - nameToUnicode.put("Beta", new Character((char) 0x0392)); - nameToEnc.put("Beta", new Integer(66)); - encToName[66] = "Beta"; - - unicodeToName.put(new Character((char) 0x03a7), "Chi"); - nameToUnicode.put("Chi", new Character((char) 0x03a7)); - nameToEnc.put("Chi", new Integer(67)); - encToName[67] = "Chi"; - - unicodeToName.put(new Character((char) 0x0394), "Delta"); - nameToUnicode.put("Delta", new Character((char) 0x0394)); - nameToEnc.put("Delta", new Integer(68)); - encToName[68] = "Delta"; - - unicodeToName.put(new Character((char) 0x0395), "Epsilon"); - nameToUnicode.put("Epsilon", new Character((char) 0x0395)); - nameToEnc.put("Epsilon", new Integer(69)); - encToName[69] = "Epsilon"; - - unicodeToName.put(new Character((char) 0x0397), "Eta"); - nameToUnicode.put("Eta", new Character((char) 0x0397)); - nameToEnc.put("Eta", new Integer(72)); - encToName[72] = "Eta"; - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - nameToEnc.put("Euro", new Integer(160)); - encToName[160] = "Euro"; - - unicodeToName.put(new Character((char) 0x0393), "Gamma"); - nameToUnicode.put("Gamma", new Character((char) 0x0393)); - nameToEnc.put("Gamma", new Integer(71)); - encToName[71] = "Gamma"; - - unicodeToName.put(new Character((char) 0x2111), "Ifraktur"); - nameToUnicode.put("Ifraktur", new Character((char) 0x2111)); - nameToEnc.put("Ifraktur", new Integer(193)); - encToName[193] = "Ifraktur"; - - unicodeToName.put(new Character((char) 0x0399), "Iota"); - nameToUnicode.put("Iota", new Character((char) 0x0399)); - nameToEnc.put("Iota", new Integer(73)); - encToName[73] = "Iota"; - - unicodeToName.put(new Character((char) 0x039a), "Kappa"); - nameToUnicode.put("Kappa", new Character((char) 0x039a)); - nameToEnc.put("Kappa", new Integer(75)); - encToName[75] = "Kappa"; - - unicodeToName.put(new Character((char) 0x039b), "Lambda"); - nameToUnicode.put("Lambda", new Character((char) 0x039b)); - nameToEnc.put("Lambda", new Integer(76)); - encToName[76] = "Lambda"; - - unicodeToName.put(new Character((char) 0x039c), "Mu"); - nameToUnicode.put("Mu", new Character((char) 0x039c)); - nameToEnc.put("Mu", new Integer(77)); - encToName[77] = "Mu"; - - unicodeToName.put(new Character((char) 0x039d), "Nu"); - nameToUnicode.put("Nu", new Character((char) 0x039d)); - nameToEnc.put("Nu", new Integer(78)); - encToName[78] = "Nu"; - - unicodeToName.put(new Character((char) 0x03a9), "Omega"); - nameToUnicode.put("Omega", new Character((char) 0x03a9)); - nameToEnc.put("Omega", new Integer(87)); - encToName[87] = "Omega"; - - unicodeToName.put(new Character((char) 0x039f), "Omicron"); - nameToUnicode.put("Omicron", new Character((char) 0x039f)); - nameToEnc.put("Omicron", new Integer(79)); - encToName[79] = "Omicron"; - - unicodeToName.put(new Character((char) 0x03a6), "Phi"); - nameToUnicode.put("Phi", new Character((char) 0x03a6)); - nameToEnc.put("Phi", new Integer(70)); - encToName[70] = "Phi"; - - unicodeToName.put(new Character((char) 0x03a0), "Pi"); - nameToUnicode.put("Pi", new Character((char) 0x03a0)); - nameToEnc.put("Pi", new Integer(80)); - encToName[80] = "Pi"; - - unicodeToName.put(new Character((char) 0x03a8), "Psi"); - nameToUnicode.put("Psi", new Character((char) 0x03a8)); - nameToEnc.put("Psi", new Integer(89)); - encToName[89] = "Psi"; - - unicodeToName.put(new Character((char) 0x211c), "Rfractur"); - nameToUnicode.put("Rfractur", new Character((char) 0x211c)); - nameToEnc.put("Rfractur", new Integer(194)); - encToName[194] = "Rfractur"; - - unicodeToName.put(new Character((char) 0x03a1), "Rho"); - nameToUnicode.put("Rho", new Character((char) 0x03a1)); - nameToEnc.put("Rho", new Integer(82)); - encToName[82] = "Rho"; - - unicodeToName.put(new Character((char) 0x03a3), "Sigma"); - nameToUnicode.put("Sigma", new Character((char) 0x03a3)); - nameToEnc.put("Sigma", new Integer(83)); - encToName[83] = "Sigma"; - - unicodeToName.put(new Character((char) 0x03a4), "Tau"); - nameToUnicode.put("Tau", new Character((char) 0x03a4)); - nameToEnc.put("Tau", new Integer(84)); - encToName[84] = "Tau"; - - unicodeToName.put(new Character((char) 0x0398), "Theta"); - nameToUnicode.put("Theta", new Character((char) 0x0398)); - nameToEnc.put("Theta", new Integer(81)); - encToName[81] = "Theta"; - - unicodeToName.put(new Character((char) 0x0059), "Upsilon"); - nameToUnicode.put("Upsilon", new Character((char) 0x0059)); - nameToEnc.put("Upsilon", new Integer(85)); - encToName[85] = "Upsilon"; - - unicodeToName.put(new Character((char) 0x03a5), "Upsilon1"); - nameToUnicode.put("Upsilon1", new Character((char) 0x03a5)); - nameToEnc.put("Upsilon1", new Integer(161)); - encToName[161] = "Upsilon1"; - - unicodeToName.put(new Character((char) 0x039e), "Xi"); - nameToUnicode.put("Xi", new Character((char) 0x039e)); - nameToEnc.put("Xi", new Integer(88)); - encToName[88] = "Xi"; - - unicodeToName.put(new Character((char) 0x0396), "Zeta"); - nameToUnicode.put("Zeta", new Character((char) 0x0396)); - nameToEnc.put("Zeta", new Integer(90)); - encToName[90] = "Zeta"; - - unicodeToName.put(new Character((char) 0x2135), "aleph"); - nameToUnicode.put("aleph", new Character((char) 0x2135)); - nameToEnc.put("aleph", new Integer(192)); - encToName[192] = "aleph"; - - unicodeToName.put(new Character((char) 0x03b1), "alpha"); - nameToUnicode.put("alpha", new Character((char) 0x03b1)); - nameToEnc.put("alpha", new Integer(97)); - encToName[97] = "alpha"; - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x2220), "angle"); - nameToUnicode.put("angle", new Character((char) 0x2220)); - nameToEnc.put("angle", new Integer(208)); - encToName[208] = "angle"; - - unicodeToName.put(new Character((char) 0x2329), "angleleft"); - nameToUnicode.put("angleleft", new Character((char) 0x2329)); - nameToEnc.put("angleleft", new Integer(225)); - encToName[225] = "angleleft"; - - unicodeToName.put(new Character((char) 0x232a), "angleright"); - nameToUnicode.put("angleright", new Character((char) 0x232a)); - nameToEnc.put("angleright", new Integer(241)); - encToName[241] = "angleright"; - - unicodeToName.put(new Character((char) 0x2248), "approxequal"); - nameToUnicode.put("approxequal", new Character((char) 0x2248)); - nameToEnc.put("approxequal", new Integer(187)); - encToName[187] = "approxequal"; - - unicodeToName.put(new Character((char) 0x2194), "arrowboth"); - nameToUnicode.put("arrowboth", new Character((char) 0x2194)); - nameToEnc.put("arrowboth", new Integer(171)); - encToName[171] = "arrowboth"; - - unicodeToName.put(new Character((char) 0x21d4), "arrowdblboth"); - nameToUnicode.put("arrowdblboth", new Character((char) 0x21d4)); - nameToEnc.put("arrowdblboth", new Integer(219)); - encToName[219] = "arrowdblboth"; - - unicodeToName.put(new Character((char) 0x21d3), "arrowdbldown"); - nameToUnicode.put("arrowdbldown", new Character((char) 0x21d3)); - nameToEnc.put("arrowdbldown", new Integer(223)); - encToName[223] = "arrowdbldown"; - - unicodeToName.put(new Character((char) 0x21d0), "arrowdblleft"); - nameToUnicode.put("arrowdblleft", new Character((char) 0x21d0)); - nameToEnc.put("arrowdblleft", new Integer(220)); - encToName[220] = "arrowdblleft"; - - unicodeToName.put(new Character((char) 0x21d2), "arrowdblright"); - nameToUnicode.put("arrowdblright", new Character((char) 0x21d2)); - nameToEnc.put("arrowdblright", new Integer(222)); - encToName[222] = "arrowdblright"; - - unicodeToName.put(new Character((char) 0x21d1), "arrowdblup"); - nameToUnicode.put("arrowdblup", new Character((char) 0x21d1)); - nameToEnc.put("arrowdblup", new Integer(221)); - encToName[221] = "arrowdblup"; - - unicodeToName.put(new Character((char) 0x2193), "arrowdown"); - nameToUnicode.put("arrowdown", new Character((char) 0x2193)); - nameToEnc.put("arrowdown", new Integer(175)); - encToName[175] = "arrowdown"; - - unicodeToName.put(new Character((char) 0xF8E7), "arrowhorizex"); - nameToUnicode.put("arrowhorizex", new Character((char) 0xF8E7)); - nameToEnc.put("arrowhorizex", new Integer(190)); - encToName[190] = "arrowhorizex"; - - unicodeToName.put(new Character((char) 0x2190), "arrowleft"); - nameToUnicode.put("arrowleft", new Character((char) 0x2190)); - nameToEnc.put("arrowleft", new Integer(172)); - encToName[172] = "arrowleft"; - - unicodeToName.put(new Character((char) 0x2192), "arrowright"); - nameToUnicode.put("arrowright", new Character((char) 0x2192)); - nameToEnc.put("arrowright", new Integer(174)); - encToName[174] = "arrowright"; - - unicodeToName.put(new Character((char) 0x2191), "arrowup"); - nameToUnicode.put("arrowup", new Character((char) 0x2191)); - nameToEnc.put("arrowup", new Integer(173)); - encToName[173] = "arrowup"; - - unicodeToName.put(new Character((char) 0xF8E8), "arrowvertex"); - nameToUnicode.put("arrowvertex", new Character((char) 0xF8E8)); - nameToEnc.put("arrowvertex", new Integer(189)); - encToName[189] = "arrowvertex"; - - unicodeToName.put(new Character((char) 0x2217), "asteriskmath"); - nameToUnicode.put("asteriskmath", new Character((char) 0x2217)); - nameToEnc.put("asteriskmath", new Integer(42)); - encToName[42] = "asteriskmath"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x03b2), "beta"); - nameToUnicode.put("beta", new Character((char) 0x03b2)); - nameToEnc.put("beta", new Integer(98)); - encToName[98] = "beta"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0xF8F1), "bracelefttp"); - nameToUnicode.put("bracelefttp", new Character((char) 0xF8F1)); - nameToEnc.put("bracelefttp", new Integer(236)); - encToName[236] = "bracelefttp"; - - unicodeToName.put(new Character((char) 0xF8F2), "braceleftmid"); - nameToUnicode.put("braceleftmid", new Character((char) 0xF8F2)); - nameToEnc.put("braceleftmid", new Integer(237)); - encToName[237] = "braceleftmid"; - - unicodeToName.put(new Character((char) 0xF8F3), "braceleftbt"); - nameToUnicode.put("braceleftbt", new Character((char) 0xF8F3)); - nameToEnc.put("braceleftbt", new Integer(238)); - encToName[238] = "braceleftbt"; - - unicodeToName.put(new Character((char) 0xF8FC), "bracerighttp"); - nameToUnicode.put("bracerighttp", new Character((char) 0xF8FC)); - nameToEnc.put("bracerighttp", new Integer(252)); - encToName[252] = "bracerighttp"; - - unicodeToName.put(new Character((char) 0xF8FD), "bracerightmid"); - nameToUnicode.put("bracerightmid", new Character((char) 0xF8FD)); - nameToEnc.put("bracerightmid", new Integer(253)); - encToName[253] = "bracerightmid"; - - unicodeToName.put(new Character((char) 0xF8FE), "bracerightbt"); - nameToUnicode.put("bracerightbt", new Character((char) 0xF8FE)); - nameToEnc.put("bracerightbt", new Integer(254)); - encToName[254] = "bracerightbt"; - - unicodeToName.put(new Character((char) 0xF8F4), "braceex"); - nameToUnicode.put("braceex", new Character((char) 0xF8F4)); - nameToEnc.put("braceex", new Integer(239)); - encToName[239] = "braceex"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0xF8EE), "bracketlefttp"); - nameToUnicode.put("bracketlefttp", new Character((char) 0xF8EE)); - nameToEnc.put("bracketlefttp", new Integer(233)); - encToName[233] = "bracketlefttp"; - - unicodeToName.put(new Character((char) 0xF8EF), "bracketleftex"); - nameToUnicode.put("bracketleftex", new Character((char) 0xF8EF)); - nameToEnc.put("bracketleftex", new Integer(234)); - encToName[234] = "bracketleftex"; - - unicodeToName.put(new Character((char) 0xF8F0), "bracketleftbt"); - nameToUnicode.put("bracketleftbt", new Character((char) 0xF8F0)); - nameToEnc.put("bracketleftbt", new Integer(235)); - encToName[235] = "bracketleftbt"; - - unicodeToName.put(new Character((char) 0xF8F9), "bracketrighttp"); - nameToUnicode.put("bracketrighttp", new Character((char) 0xF8F9)); - nameToEnc.put("bracketrighttp", new Integer(249)); - encToName[249] = "bracketrighttp"; - - unicodeToName.put(new Character((char) 0xF8FA), "bracketrightex"); - nameToUnicode.put("bracketrightex", new Character((char) 0xF8FA)); - nameToEnc.put("bracketrightex", new Integer(250)); - encToName[250] = "bracketrightex"; - - unicodeToName.put(new Character((char) 0xF8FB), "bracketrightbt"); - nameToUnicode.put("bracketrightbt", new Character((char) 0xF8FB)); - nameToEnc.put("bracketrightbt", new Integer(251)); - encToName[251] = "bracketrightbt"; - - unicodeToName.put(new Character((char) 0x2219), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2219)); - nameToEnc.put("bullet", new Integer(183)); - encToName[183] = "bullet"; - - unicodeToName.put(new Character((char) 0x21b5), "carriagereturn"); - nameToUnicode.put("carriagereturn", new Character((char) 0x21b5)); - nameToEnc.put("carriagereturn", new Integer(191)); - encToName[191] = "carriagereturn"; - - unicodeToName.put(new Character((char) 0x03c7), "chi"); - nameToUnicode.put("chi", new Character((char) 0x03c7)); - nameToEnc.put("chi", new Integer(99)); - encToName[99] = "chi"; - - unicodeToName.put(new Character((char) 0x2297), "circlemultiply"); - nameToUnicode.put("circlemultiply", new Character((char) 0x2297)); - nameToEnc.put("circlemultiply", new Integer(196)); - encToName[196] = "circlemultiply"; - - unicodeToName.put(new Character((char) 0x2295), "circleplus"); - nameToUnicode.put("circleplus", new Character((char) 0x2295)); - nameToEnc.put("circleplus", new Integer(197)); - encToName[197] = "circleplus"; - - unicodeToName.put(new Character((char) 0x2663), "club"); - nameToUnicode.put("club", new Character((char) 0x2663)); - nameToEnc.put("club", new Integer(167)); - encToName[167] = "club"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x2245), "congruent"); - nameToUnicode.put("congruent", new Character((char) 0x2245)); - nameToEnc.put("congruent", new Integer(64)); - encToName[64] = "congruent"; - - unicodeToName.put(new Character((char) 0xF8E9), "copyrightsans"); - nameToUnicode.put("copyrightsans", new Character((char) 0xF8E9)); - nameToEnc.put("copyrightsans", new Integer(227)); - encToName[227] = "copyrightsans"; - - unicodeToName.put(new Character((char) 0xF6D9), "copyrightserif"); - nameToUnicode.put("copyrightserif", new Character((char) 0xF6D9)); - nameToEnc.put("copyrightserif", new Integer(211)); - encToName[211] = "copyrightserif"; - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - nameToEnc.put("degree", new Integer(176)); - encToName[176] = "degree"; - - unicodeToName.put(new Character((char) 0x03b4), "delta"); - nameToUnicode.put("delta", new Character((char) 0x03b4)); - nameToEnc.put("delta", new Integer(100)); - encToName[100] = "delta"; - - unicodeToName.put(new Character((char) 0x2666), "diamond"); - nameToUnicode.put("diamond", new Character((char) 0x2666)); - nameToEnc.put("diamond", new Integer(168)); - encToName[168] = "diamond"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - nameToEnc.put("divide", new Integer(184)); - encToName[184] = "divide"; - - unicodeToName.put(new Character((char) 0x22c5), "dotmath"); - nameToUnicode.put("dotmath", new Character((char) 0x22c5)); - nameToEnc.put("dotmath", new Integer(215)); - encToName[215] = "dotmath"; - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2208), "element"); - nameToUnicode.put("element", new Character((char) 0x2208)); - nameToEnc.put("element", new Integer(206)); - encToName[206] = "element"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - nameToEnc.put("ellipsis", new Integer(188)); - encToName[188] = "ellipsis"; - - unicodeToName.put(new Character((char) 0x2205), "emptyset"); - nameToUnicode.put("emptyset", new Character((char) 0x2205)); - nameToEnc.put("emptyset", new Integer(198)); - encToName[198] = "emptyset"; - - unicodeToName.put(new Character((char) 0x03b5), "epsilon"); - nameToUnicode.put("epsilon", new Character((char) 0x03b5)); - nameToEnc.put("epsilon", new Integer(101)); - encToName[101] = "epsilon"; - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x2261), "equivalence"); - nameToUnicode.put("equivalence", new Character((char) 0x2261)); - nameToEnc.put("equivalence", new Integer(186)); - encToName[186] = "equivalence"; - - unicodeToName.put(new Character((char) 0x03b7), "eta"); - nameToUnicode.put("eta", new Character((char) 0x03b7)); - nameToEnc.put("eta", new Integer(104)); - encToName[104] = "eta"; - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x2203), "existential"); - nameToUnicode.put("existential", new Character((char) 0x2203)); - nameToEnc.put("existential", new Integer(36)); - encToName[36] = "existential"; - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - nameToEnc.put("florin", new Integer(166)); - encToName[166] = "florin"; - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - nameToEnc.put("fraction", new Integer(164)); - encToName[164] = "fraction"; - - unicodeToName.put(new Character((char) 0x03b3), "gamma"); - nameToUnicode.put("gamma", new Character((char) 0x03b3)); - nameToEnc.put("gamma", new Integer(103)); - encToName[103] = "gamma"; - - unicodeToName.put(new Character((char) 0x2207), "gradient"); - nameToUnicode.put("gradient", new Character((char) 0x2207)); - nameToEnc.put("gradient", new Integer(209)); - encToName[209] = "gradient"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x2265), "greaterequal"); - nameToUnicode.put("greaterequal", new Character((char) 0x2265)); - nameToEnc.put("greaterequal", new Integer(179)); - encToName[179] = "greaterequal"; - - unicodeToName.put(new Character((char) 0x2660), "heart"); - nameToUnicode.put("heart", new Character((char) 0x2660)); - nameToEnc.put("heart", new Integer(169)); - encToName[169] = "heart"; - - unicodeToName.put(new Character((char) 0x221e), "infinity"); - nameToUnicode.put("infinity", new Character((char) 0x221e)); - nameToEnc.put("infinity", new Integer(165)); - encToName[165] = "infinity"; - - unicodeToName.put(new Character((char) 0x222b), "integral"); - nameToUnicode.put("integral", new Character((char) 0x222b)); - nameToEnc.put("integral", new Integer(242)); - encToName[242] = "integral"; - - unicodeToName.put(new Character((char) 0x2320), "integraltp"); - nameToUnicode.put("integraltp", new Character((char) 0x2320)); - nameToEnc.put("integraltp", new Integer(243)); - encToName[243] = "integraltp"; - - unicodeToName.put(new Character((char) 0xF8F5), "integralex"); - nameToUnicode.put("integralex", new Character((char) 0xF8F5)); - nameToEnc.put("integralex", new Integer(244)); - encToName[244] = "integralex"; - - unicodeToName.put(new Character((char) 0x2321), "integralbt"); - nameToUnicode.put("integralbt", new Character((char) 0x2321)); - nameToEnc.put("integralbt", new Integer(245)); - encToName[245] = "integralbt"; - - unicodeToName.put(new Character((char) 0x2229), "intersection"); - nameToUnicode.put("intersection", new Character((char) 0x2229)); - nameToEnc.put("intersection", new Integer(199)); - encToName[199] = "intersection"; - - unicodeToName.put(new Character((char) 0x03b9), "iota"); - nameToUnicode.put("iota", new Character((char) 0x03b9)); - nameToEnc.put("iota", new Integer(105)); - encToName[105] = "iota"; - - unicodeToName.put(new Character((char) 0x03ba), "kappa"); - nameToUnicode.put("kappa", new Character((char) 0x03ba)); - nameToEnc.put("kappa", new Integer(107)); - encToName[107] = "kappa"; - - unicodeToName.put(new Character((char) 0x03bb), "lambda"); - nameToUnicode.put("lambda", new Character((char) 0x03bb)); - nameToEnc.put("lambda", new Integer(108)); - encToName[108] = "lambda"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x2264), "lessequal"); - nameToUnicode.put("lessequal", new Character((char) 0x2264)); - nameToEnc.put("lessequal", new Integer(163)); - encToName[163] = "lessequal"; - - unicodeToName.put(new Character((char) 0x2227), "logicaland"); - nameToUnicode.put("logicaland", new Character((char) 0x2227)); - nameToEnc.put("logicaland", new Integer(217)); - encToName[217] = "logicaland"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - nameToEnc.put("logicalnot", new Integer(216)); - encToName[216] = "logicalnot"; - - unicodeToName.put(new Character((char) 0x2228), "logicalor"); - nameToUnicode.put("logicalor", new Character((char) 0x2228)); - nameToEnc.put("logicalor", new Integer(218)); - encToName[218] = "logicalor"; - - unicodeToName.put(new Character((char) 0x25ca), "lozenge"); - nameToUnicode.put("lozenge", new Character((char) 0x25ca)); - nameToEnc.put("lozenge", new Integer(224)); - encToName[224] = "lozenge"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - nameToEnc.put("minus", new Integer(45)); - encToName[45] = "minus"; - - unicodeToName.put(new Character((char) 0x2032), "minute"); - nameToUnicode.put("minute", new Character((char) 0x2032)); - nameToEnc.put("minute", new Integer(162)); - encToName[162] = "minute"; - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - nameToEnc.put("mu", new Integer(109)); - encToName[109] = "mu"; - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - nameToEnc.put("multiply", new Integer(180)); - encToName[180] = "multiply"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x2209), "notelement"); - nameToUnicode.put("notelement", new Character((char) 0x2209)); - nameToEnc.put("notelement", new Integer(207)); - encToName[207] = "notelement"; - - unicodeToName.put(new Character((char) 0x2260), "notequal"); - nameToUnicode.put("notequal", new Character((char) 0x2260)); - nameToEnc.put("notequal", new Integer(185)); - encToName[185] = "notequal"; - - unicodeToName.put(new Character((char) 0x2284), "notsubset"); - nameToUnicode.put("notsubset", new Character((char) 0x2284)); - nameToEnc.put("notsubset", new Integer(203)); - encToName[203] = "notsubset"; - - unicodeToName.put(new Character((char) 0x03bd), "nu"); - nameToUnicode.put("nu", new Character((char) 0x03bd)); - nameToEnc.put("nu", new Integer(110)); - encToName[110] = "nu"; - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x03c9), "omega"); - nameToUnicode.put("omega", new Character((char) 0x03c9)); - nameToEnc.put("omega", new Integer(119)); - encToName[119] = "omega"; - - unicodeToName.put(new Character((char) 0x03d6), "omega1"); - nameToUnicode.put("omega1", new Character((char) 0x03d6)); - nameToEnc.put("omega1", new Integer(118)); - encToName[118] = "omega1"; - - unicodeToName.put(new Character((char) 0x03bf), "omicron"); - nameToUnicode.put("omicron", new Character((char) 0x03bf)); - nameToEnc.put("omicron", new Integer(111)); - encToName[111] = "omicron"; - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0xF8EB), "parenlefttp"); - nameToUnicode.put("parenlefttp", new Character((char) 0xF8EB)); - nameToEnc.put("parenlefttp", new Integer(230)); - encToName[230] = "parenlefttp"; - - unicodeToName.put(new Character((char) 0xF8EC), "parenleftex"); - nameToUnicode.put("parenleftex", new Character((char) 0xF8EC)); - nameToEnc.put("parenleftex", new Integer(231)); - encToName[231] = "parenleftex"; - - unicodeToName.put(new Character((char) 0xF8ED), "parenleftbt"); - nameToUnicode.put("parenleftbt", new Character((char) 0xF8ED)); - nameToEnc.put("parenleftbt", new Integer(232)); - encToName[232] = "parenleftbt"; - - unicodeToName.put(new Character((char) 0xF8F6), "parenrighttp"); - nameToUnicode.put("parenrighttp", new Character((char) 0xF8F6)); - nameToEnc.put("parenrighttp", new Integer(246)); - encToName[246] = "parenrighttp"; - - unicodeToName.put(new Character((char) 0xF8F7), "parenrightex"); - nameToUnicode.put("parenrightex", new Character((char) 0xF8F7)); - nameToEnc.put("parenrightex", new Integer(247)); - encToName[247] = "parenrightex"; - - unicodeToName.put(new Character((char) 0xF8F8), "parenrightbt"); - nameToUnicode.put("parenrightbt", new Character((char) 0xF8F8)); - nameToEnc.put("parenrightbt", new Integer(248)); - encToName[248] = "parenrightbt"; - - unicodeToName.put(new Character((char) 0x2202), "partialdiff"); - nameToUnicode.put("partialdiff", new Character((char) 0x2202)); - nameToEnc.put("partialdiff", new Integer(182)); - encToName[182] = "partialdiff"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x22a5), "perpendicular"); - nameToUnicode.put("perpendicular", new Character((char) 0x22a5)); - nameToEnc.put("perpendicular", new Integer(94)); - encToName[94] = "perpendicular"; - - unicodeToName.put(new Character((char) 0x03d5), "phi"); - nameToUnicode.put("phi", new Character((char) 0x03d5)); - nameToEnc.put("phi", new Integer(102)); - encToName[102] = "phi"; - - unicodeToName.put(new Character((char) 0x03c6), "phi1"); - nameToUnicode.put("phi1", new Character((char) 0x03c6)); - nameToEnc.put("phi1", new Integer(106)); - encToName[106] = "phi1"; - - unicodeToName.put(new Character((char) 0x03c0), "pi"); - nameToUnicode.put("pi", new Character((char) 0x03c0)); - nameToEnc.put("pi", new Integer(112)); - encToName[112] = "pi"; - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - nameToEnc.put("plusminus", new Integer(177)); - encToName[177] = "plusminus"; - - unicodeToName.put(new Character((char) 0x220f), "product"); - nameToUnicode.put("product", new Character((char) 0x220f)); - nameToEnc.put("product", new Integer(213)); - encToName[213] = "product"; - - unicodeToName.put(new Character((char) 0x2282), "propersubset"); - nameToUnicode.put("propersubset", new Character((char) 0x2282)); - nameToEnc.put("propersubset", new Integer(204)); - encToName[204] = "propersubset"; - - unicodeToName.put(new Character((char) 0x2283), "propersuperset"); - nameToUnicode.put("propersuperset", new Character((char) 0x2283)); - nameToEnc.put("propersuperset", new Integer(201)); - encToName[201] = "propersuperset"; - - unicodeToName.put(new Character((char) 0x221d), "proportional"); - nameToUnicode.put("proportional", new Character((char) 0x221d)); - nameToEnc.put("proportional", new Integer(181)); - encToName[181] = "proportional"; - - unicodeToName.put(new Character((char) 0x03c8), "psi"); - nameToUnicode.put("psi", new Character((char) 0x03c8)); - nameToEnc.put("psi", new Integer(121)); - encToName[121] = "psi"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x221a), "radical"); - nameToUnicode.put("radical", new Character((char) 0x221a)); - nameToEnc.put("radical", new Integer(214)); - encToName[214] = "radical"; - - unicodeToName.put(new Character((char) 0xF8E5), "radicalex"); - nameToUnicode.put("radicalex", new Character((char) 0xF8E5)); - nameToEnc.put("radicalex", new Integer(96)); - encToName[96] = "radicalex"; - - unicodeToName.put(new Character((char) 0x2286), "reflexsubset"); - nameToUnicode.put("reflexsubset", new Character((char) 0x2286)); - nameToEnc.put("reflexsubset", new Integer(205)); - encToName[205] = "reflexsubset"; - - unicodeToName.put(new Character((char) 0x2287), "reflexsuperset"); - nameToUnicode.put("reflexsuperset", new Character((char) 0x2287)); - nameToEnc.put("reflexsuperset", new Integer(202)); - encToName[202] = "reflexsuperset"; - - unicodeToName.put(new Character((char) 0xF8E8), "registersans"); - nameToUnicode.put("registersans", new Character((char) 0xF8E8)); - nameToEnc.put("registersans", new Integer(226)); - encToName[226] = "registersans"; - - unicodeToName.put(new Character((char) 0xF6DA), "registerserif"); - nameToUnicode.put("registerserif", new Character((char) 0xF6DA)); - nameToEnc.put("registerserif", new Integer(210)); - encToName[210] = "registerserif"; - - unicodeToName.put(new Character((char) 0x03c1), "rho"); - nameToUnicode.put("rho", new Character((char) 0x03c1)); - nameToEnc.put("rho", new Integer(114)); - encToName[114] = "rho"; - - unicodeToName.put(new Character((char) 0x2033), "second"); - nameToUnicode.put("second", new Character((char) 0x2033)); - nameToEnc.put("second", new Integer(178)); - encToName[178] = "second"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x03c3), "sigma"); - nameToUnicode.put("sigma", new Character((char) 0x03c3)); - nameToEnc.put("sigma", new Integer(115)); - encToName[115] = "sigma"; - - unicodeToName.put(new Character((char) 0x03c2), "sigma1"); - nameToUnicode.put("sigma1", new Character((char) 0x03c2)); - nameToEnc.put("sigma1", new Integer(86)); - encToName[86] = "sigma1"; - - unicodeToName.put(new Character((char) 0x223c), "similar"); - nameToUnicode.put("similar", new Character((char) 0x223c)); - nameToEnc.put("similar", new Integer(126)); - encToName[126] = "similar"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x2660), "spade"); - nameToUnicode.put("spade", new Character((char) 0x2660)); - nameToEnc.put("spade", new Integer(170)); - encToName[170] = "spade"; - - unicodeToName.put(new Character((char) 0x220b), "suchthat"); - nameToUnicode.put("suchthat", new Character((char) 0x220b)); - nameToEnc.put("suchthat", new Integer(39)); - encToName[39] = "suchthat"; - - unicodeToName.put(new Character((char) 0x2211), "summation"); - nameToUnicode.put("summation", new Character((char) 0x2211)); - nameToEnc.put("summation", new Integer(229)); - encToName[229] = "summation"; - - unicodeToName.put(new Character((char) 0x03c4), "tau"); - nameToUnicode.put("tau", new Character((char) 0x03c4)); - nameToEnc.put("tau", new Integer(116)); - encToName[116] = "tau"; - - unicodeToName.put(new Character((char) 0x2234), "therefore"); - nameToUnicode.put("therefore", new Character((char) 0x2234)); - nameToEnc.put("therefore", new Integer(92)); - encToName[92] = "therefore"; - - unicodeToName.put(new Character((char) 0x03b8), "theta"); - nameToUnicode.put("theta", new Character((char) 0x03b8)); - nameToEnc.put("theta", new Integer(113)); - encToName[113] = "theta"; - - unicodeToName.put(new Character((char) 0x03d1), "theta1"); - nameToUnicode.put("theta1", new Character((char) 0x03d1)); - nameToEnc.put("theta1", new Integer(74)); - encToName[74] = "theta1"; - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0xF8EA), "trademarksans"); - nameToUnicode.put("trademarksans", new Character((char) 0xF8EA)); - nameToEnc.put("trademarksans", new Integer(228)); - encToName[228] = "trademarksans"; - - unicodeToName.put(new Character((char) 0xF6DB), "trademarkserif"); - nameToUnicode.put("trademarkserif", new Character((char) 0xF6DB)); - nameToEnc.put("trademarkserif", new Integer(212)); - encToName[212] = "trademarkserif"; - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x222a), "union"); - nameToUnicode.put("union", new Character((char) 0x222a)); - nameToEnc.put("union", new Integer(200)); - encToName[200] = "union"; - - unicodeToName.put(new Character((char) 0x2200), "universal"); - nameToUnicode.put("universal", new Character((char) 0x2200)); - nameToEnc.put("universal", new Integer(34)); - encToName[34] = "universal"; - - unicodeToName.put(new Character((char) 0x03c5), "upsilon"); - nameToUnicode.put("upsilon", new Character((char) 0x03c5)); - nameToEnc.put("upsilon", new Integer(117)); - encToName[117] = "upsilon"; - - unicodeToName.put(new Character((char) 0x2118), "weierstrass"); - nameToUnicode.put("weierstrass", new Character((char) 0x2118)); - nameToEnc.put("weierstrass", new Integer(195)); - encToName[195] = "weierstrass"; - - unicodeToName.put(new Character((char) 0x03be), "xi"); - nameToUnicode.put("xi", new Character((char) 0x03be)); - nameToEnc.put("xi", new Integer(120)); - encToName[120] = "xi"; - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - unicodeToName.put(new Character((char) 0x03b6), "zeta"); - nameToUnicode.put("zeta", new Character((char) 0x03b6)); - nameToEnc.put("zeta", new Integer(122)); - encToName[122] = "zeta"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Symbol");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated Symbol Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class Symbol extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public Symbol() { + unicodeToName.put(new Character((char) 0x0391), "Alpha"); + nameToUnicode.put("Alpha", new Character((char) 0x0391)); + nameToEnc.put("Alpha", new Integer(65)); + encToName[65] = "Alpha"; + + unicodeToName.put(new Character((char) 0x0392), "Beta"); + nameToUnicode.put("Beta", new Character((char) 0x0392)); + nameToEnc.put("Beta", new Integer(66)); + encToName[66] = "Beta"; + + unicodeToName.put(new Character((char) 0x03a7), "Chi"); + nameToUnicode.put("Chi", new Character((char) 0x03a7)); + nameToEnc.put("Chi", new Integer(67)); + encToName[67] = "Chi"; + + unicodeToName.put(new Character((char) 0x0394), "Delta"); + nameToUnicode.put("Delta", new Character((char) 0x0394)); + nameToEnc.put("Delta", new Integer(68)); + encToName[68] = "Delta"; + + unicodeToName.put(new Character((char) 0x0395), "Epsilon"); + nameToUnicode.put("Epsilon", new Character((char) 0x0395)); + nameToEnc.put("Epsilon", new Integer(69)); + encToName[69] = "Epsilon"; + + unicodeToName.put(new Character((char) 0x0397), "Eta"); + nameToUnicode.put("Eta", new Character((char) 0x0397)); + nameToEnc.put("Eta", new Integer(72)); + encToName[72] = "Eta"; + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + nameToEnc.put("Euro", new Integer(160)); + encToName[160] = "Euro"; + + unicodeToName.put(new Character((char) 0x0393), "Gamma"); + nameToUnicode.put("Gamma", new Character((char) 0x0393)); + nameToEnc.put("Gamma", new Integer(71)); + encToName[71] = "Gamma"; + + unicodeToName.put(new Character((char) 0x2111), "Ifraktur"); + nameToUnicode.put("Ifraktur", new Character((char) 0x2111)); + nameToEnc.put("Ifraktur", new Integer(193)); + encToName[193] = "Ifraktur"; + + unicodeToName.put(new Character((char) 0x0399), "Iota"); + nameToUnicode.put("Iota", new Character((char) 0x0399)); + nameToEnc.put("Iota", new Integer(73)); + encToName[73] = "Iota"; + + unicodeToName.put(new Character((char) 0x039a), "Kappa"); + nameToUnicode.put("Kappa", new Character((char) 0x039a)); + nameToEnc.put("Kappa", new Integer(75)); + encToName[75] = "Kappa"; + + unicodeToName.put(new Character((char) 0x039b), "Lambda"); + nameToUnicode.put("Lambda", new Character((char) 0x039b)); + nameToEnc.put("Lambda", new Integer(76)); + encToName[76] = "Lambda"; + + unicodeToName.put(new Character((char) 0x039c), "Mu"); + nameToUnicode.put("Mu", new Character((char) 0x039c)); + nameToEnc.put("Mu", new Integer(77)); + encToName[77] = "Mu"; + + unicodeToName.put(new Character((char) 0x039d), "Nu"); + nameToUnicode.put("Nu", new Character((char) 0x039d)); + nameToEnc.put("Nu", new Integer(78)); + encToName[78] = "Nu"; + + unicodeToName.put(new Character((char) 0x03a9), "Omega"); + nameToUnicode.put("Omega", new Character((char) 0x03a9)); + nameToEnc.put("Omega", new Integer(87)); + encToName[87] = "Omega"; + + unicodeToName.put(new Character((char) 0x039f), "Omicron"); + nameToUnicode.put("Omicron", new Character((char) 0x039f)); + nameToEnc.put("Omicron", new Integer(79)); + encToName[79] = "Omicron"; + + unicodeToName.put(new Character((char) 0x03a6), "Phi"); + nameToUnicode.put("Phi", new Character((char) 0x03a6)); + nameToEnc.put("Phi", new Integer(70)); + encToName[70] = "Phi"; + + unicodeToName.put(new Character((char) 0x03a0), "Pi"); + nameToUnicode.put("Pi", new Character((char) 0x03a0)); + nameToEnc.put("Pi", new Integer(80)); + encToName[80] = "Pi"; + + unicodeToName.put(new Character((char) 0x03a8), "Psi"); + nameToUnicode.put("Psi", new Character((char) 0x03a8)); + nameToEnc.put("Psi", new Integer(89)); + encToName[89] = "Psi"; + + unicodeToName.put(new Character((char) 0x211c), "Rfractur"); + nameToUnicode.put("Rfractur", new Character((char) 0x211c)); + nameToEnc.put("Rfractur", new Integer(194)); + encToName[194] = "Rfractur"; + + unicodeToName.put(new Character((char) 0x03a1), "Rho"); + nameToUnicode.put("Rho", new Character((char) 0x03a1)); + nameToEnc.put("Rho", new Integer(82)); + encToName[82] = "Rho"; + + unicodeToName.put(new Character((char) 0x03a3), "Sigma"); + nameToUnicode.put("Sigma", new Character((char) 0x03a3)); + nameToEnc.put("Sigma", new Integer(83)); + encToName[83] = "Sigma"; + + unicodeToName.put(new Character((char) 0x03a4), "Tau"); + nameToUnicode.put("Tau", new Character((char) 0x03a4)); + nameToEnc.put("Tau", new Integer(84)); + encToName[84] = "Tau"; + + unicodeToName.put(new Character((char) 0x0398), "Theta"); + nameToUnicode.put("Theta", new Character((char) 0x0398)); + nameToEnc.put("Theta", new Integer(81)); + encToName[81] = "Theta"; + + unicodeToName.put(new Character((char) 0x0059), "Upsilon"); + nameToUnicode.put("Upsilon", new Character((char) 0x0059)); + nameToEnc.put("Upsilon", new Integer(85)); + encToName[85] = "Upsilon"; + + unicodeToName.put(new Character((char) 0x03a5), "Upsilon1"); + nameToUnicode.put("Upsilon1", new Character((char) 0x03a5)); + nameToEnc.put("Upsilon1", new Integer(161)); + encToName[161] = "Upsilon1"; + + unicodeToName.put(new Character((char) 0x039e), "Xi"); + nameToUnicode.put("Xi", new Character((char) 0x039e)); + nameToEnc.put("Xi", new Integer(88)); + encToName[88] = "Xi"; + + unicodeToName.put(new Character((char) 0x0396), "Zeta"); + nameToUnicode.put("Zeta", new Character((char) 0x0396)); + nameToEnc.put("Zeta", new Integer(90)); + encToName[90] = "Zeta"; + + unicodeToName.put(new Character((char) 0x2135), "aleph"); + nameToUnicode.put("aleph", new Character((char) 0x2135)); + nameToEnc.put("aleph", new Integer(192)); + encToName[192] = "aleph"; + + unicodeToName.put(new Character((char) 0x03b1), "alpha"); + nameToUnicode.put("alpha", new Character((char) 0x03b1)); + nameToEnc.put("alpha", new Integer(97)); + encToName[97] = "alpha"; + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x2220), "angle"); + nameToUnicode.put("angle", new Character((char) 0x2220)); + nameToEnc.put("angle", new Integer(208)); + encToName[208] = "angle"; + + unicodeToName.put(new Character((char) 0x2329), "angleleft"); + nameToUnicode.put("angleleft", new Character((char) 0x2329)); + nameToEnc.put("angleleft", new Integer(225)); + encToName[225] = "angleleft"; + + unicodeToName.put(new Character((char) 0x232a), "angleright"); + nameToUnicode.put("angleright", new Character((char) 0x232a)); + nameToEnc.put("angleright", new Integer(241)); + encToName[241] = "angleright"; + + unicodeToName.put(new Character((char) 0x2248), "approxequal"); + nameToUnicode.put("approxequal", new Character((char) 0x2248)); + nameToEnc.put("approxequal", new Integer(187)); + encToName[187] = "approxequal"; + + unicodeToName.put(new Character((char) 0x2194), "arrowboth"); + nameToUnicode.put("arrowboth", new Character((char) 0x2194)); + nameToEnc.put("arrowboth", new Integer(171)); + encToName[171] = "arrowboth"; + + unicodeToName.put(new Character((char) 0x21d4), "arrowdblboth"); + nameToUnicode.put("arrowdblboth", new Character((char) 0x21d4)); + nameToEnc.put("arrowdblboth", new Integer(219)); + encToName[219] = "arrowdblboth"; + + unicodeToName.put(new Character((char) 0x21d3), "arrowdbldown"); + nameToUnicode.put("arrowdbldown", new Character((char) 0x21d3)); + nameToEnc.put("arrowdbldown", new Integer(223)); + encToName[223] = "arrowdbldown"; + + unicodeToName.put(new Character((char) 0x21d0), "arrowdblleft"); + nameToUnicode.put("arrowdblleft", new Character((char) 0x21d0)); + nameToEnc.put("arrowdblleft", new Integer(220)); + encToName[220] = "arrowdblleft"; + + unicodeToName.put(new Character((char) 0x21d2), "arrowdblright"); + nameToUnicode.put("arrowdblright", new Character((char) 0x21d2)); + nameToEnc.put("arrowdblright", new Integer(222)); + encToName[222] = "arrowdblright"; + + unicodeToName.put(new Character((char) 0x21d1), "arrowdblup"); + nameToUnicode.put("arrowdblup", new Character((char) 0x21d1)); + nameToEnc.put("arrowdblup", new Integer(221)); + encToName[221] = "arrowdblup"; + + unicodeToName.put(new Character((char) 0x2193), "arrowdown"); + nameToUnicode.put("arrowdown", new Character((char) 0x2193)); + nameToEnc.put("arrowdown", new Integer(175)); + encToName[175] = "arrowdown"; + + unicodeToName.put(new Character((char) 0xF8E7), "arrowhorizex"); + nameToUnicode.put("arrowhorizex", new Character((char) 0xF8E7)); + nameToEnc.put("arrowhorizex", new Integer(190)); + encToName[190] = "arrowhorizex"; + + unicodeToName.put(new Character((char) 0x2190), "arrowleft"); + nameToUnicode.put("arrowleft", new Character((char) 0x2190)); + nameToEnc.put("arrowleft", new Integer(172)); + encToName[172] = "arrowleft"; + + unicodeToName.put(new Character((char) 0x2192), "arrowright"); + nameToUnicode.put("arrowright", new Character((char) 0x2192)); + nameToEnc.put("arrowright", new Integer(174)); + encToName[174] = "arrowright"; + + unicodeToName.put(new Character((char) 0x2191), "arrowup"); + nameToUnicode.put("arrowup", new Character((char) 0x2191)); + nameToEnc.put("arrowup", new Integer(173)); + encToName[173] = "arrowup"; + + unicodeToName.put(new Character((char) 0xF8E8), "arrowvertex"); + nameToUnicode.put("arrowvertex", new Character((char) 0xF8E8)); + nameToEnc.put("arrowvertex", new Integer(189)); + encToName[189] = "arrowvertex"; + + unicodeToName.put(new Character((char) 0x2217), "asteriskmath"); + nameToUnicode.put("asteriskmath", new Character((char) 0x2217)); + nameToEnc.put("asteriskmath", new Integer(42)); + encToName[42] = "asteriskmath"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x03b2), "beta"); + nameToUnicode.put("beta", new Character((char) 0x03b2)); + nameToEnc.put("beta", new Integer(98)); + encToName[98] = "beta"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0xF8F1), "bracelefttp"); + nameToUnicode.put("bracelefttp", new Character((char) 0xF8F1)); + nameToEnc.put("bracelefttp", new Integer(236)); + encToName[236] = "bracelefttp"; + + unicodeToName.put(new Character((char) 0xF8F2), "braceleftmid"); + nameToUnicode.put("braceleftmid", new Character((char) 0xF8F2)); + nameToEnc.put("braceleftmid", new Integer(237)); + encToName[237] = "braceleftmid"; + + unicodeToName.put(new Character((char) 0xF8F3), "braceleftbt"); + nameToUnicode.put("braceleftbt", new Character((char) 0xF8F3)); + nameToEnc.put("braceleftbt", new Integer(238)); + encToName[238] = "braceleftbt"; + + unicodeToName.put(new Character((char) 0xF8FC), "bracerighttp"); + nameToUnicode.put("bracerighttp", new Character((char) 0xF8FC)); + nameToEnc.put("bracerighttp", new Integer(252)); + encToName[252] = "bracerighttp"; + + unicodeToName.put(new Character((char) 0xF8FD), "bracerightmid"); + nameToUnicode.put("bracerightmid", new Character((char) 0xF8FD)); + nameToEnc.put("bracerightmid", new Integer(253)); + encToName[253] = "bracerightmid"; + + unicodeToName.put(new Character((char) 0xF8FE), "bracerightbt"); + nameToUnicode.put("bracerightbt", new Character((char) 0xF8FE)); + nameToEnc.put("bracerightbt", new Integer(254)); + encToName[254] = "bracerightbt"; + + unicodeToName.put(new Character((char) 0xF8F4), "braceex"); + nameToUnicode.put("braceex", new Character((char) 0xF8F4)); + nameToEnc.put("braceex", new Integer(239)); + encToName[239] = "braceex"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0xF8EE), "bracketlefttp"); + nameToUnicode.put("bracketlefttp", new Character((char) 0xF8EE)); + nameToEnc.put("bracketlefttp", new Integer(233)); + encToName[233] = "bracketlefttp"; + + unicodeToName.put(new Character((char) 0xF8EF), "bracketleftex"); + nameToUnicode.put("bracketleftex", new Character((char) 0xF8EF)); + nameToEnc.put("bracketleftex", new Integer(234)); + encToName[234] = "bracketleftex"; + + unicodeToName.put(new Character((char) 0xF8F0), "bracketleftbt"); + nameToUnicode.put("bracketleftbt", new Character((char) 0xF8F0)); + nameToEnc.put("bracketleftbt", new Integer(235)); + encToName[235] = "bracketleftbt"; + + unicodeToName.put(new Character((char) 0xF8F9), "bracketrighttp"); + nameToUnicode.put("bracketrighttp", new Character((char) 0xF8F9)); + nameToEnc.put("bracketrighttp", new Integer(249)); + encToName[249] = "bracketrighttp"; + + unicodeToName.put(new Character((char) 0xF8FA), "bracketrightex"); + nameToUnicode.put("bracketrightex", new Character((char) 0xF8FA)); + nameToEnc.put("bracketrightex", new Integer(250)); + encToName[250] = "bracketrightex"; + + unicodeToName.put(new Character((char) 0xF8FB), "bracketrightbt"); + nameToUnicode.put("bracketrightbt", new Character((char) 0xF8FB)); + nameToEnc.put("bracketrightbt", new Integer(251)); + encToName[251] = "bracketrightbt"; + + unicodeToName.put(new Character((char) 0x2219), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2219)); + nameToEnc.put("bullet", new Integer(183)); + encToName[183] = "bullet"; + + unicodeToName.put(new Character((char) 0x21b5), "carriagereturn"); + nameToUnicode.put("carriagereturn", new Character((char) 0x21b5)); + nameToEnc.put("carriagereturn", new Integer(191)); + encToName[191] = "carriagereturn"; + + unicodeToName.put(new Character((char) 0x03c7), "chi"); + nameToUnicode.put("chi", new Character((char) 0x03c7)); + nameToEnc.put("chi", new Integer(99)); + encToName[99] = "chi"; + + unicodeToName.put(new Character((char) 0x2297), "circlemultiply"); + nameToUnicode.put("circlemultiply", new Character((char) 0x2297)); + nameToEnc.put("circlemultiply", new Integer(196)); + encToName[196] = "circlemultiply"; + + unicodeToName.put(new Character((char) 0x2295), "circleplus"); + nameToUnicode.put("circleplus", new Character((char) 0x2295)); + nameToEnc.put("circleplus", new Integer(197)); + encToName[197] = "circleplus"; + + unicodeToName.put(new Character((char) 0x2663), "club"); + nameToUnicode.put("club", new Character((char) 0x2663)); + nameToEnc.put("club", new Integer(167)); + encToName[167] = "club"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x2245), "congruent"); + nameToUnicode.put("congruent", new Character((char) 0x2245)); + nameToEnc.put("congruent", new Integer(64)); + encToName[64] = "congruent"; + + unicodeToName.put(new Character((char) 0xF8E9), "copyrightsans"); + nameToUnicode.put("copyrightsans", new Character((char) 0xF8E9)); + nameToEnc.put("copyrightsans", new Integer(227)); + encToName[227] = "copyrightsans"; + + unicodeToName.put(new Character((char) 0xF6D9), "copyrightserif"); + nameToUnicode.put("copyrightserif", new Character((char) 0xF6D9)); + nameToEnc.put("copyrightserif", new Integer(211)); + encToName[211] = "copyrightserif"; + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + nameToEnc.put("degree", new Integer(176)); + encToName[176] = "degree"; + + unicodeToName.put(new Character((char) 0x03b4), "delta"); + nameToUnicode.put("delta", new Character((char) 0x03b4)); + nameToEnc.put("delta", new Integer(100)); + encToName[100] = "delta"; + + unicodeToName.put(new Character((char) 0x2666), "diamond"); + nameToUnicode.put("diamond", new Character((char) 0x2666)); + nameToEnc.put("diamond", new Integer(168)); + encToName[168] = "diamond"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + nameToEnc.put("divide", new Integer(184)); + encToName[184] = "divide"; + + unicodeToName.put(new Character((char) 0x22c5), "dotmath"); + nameToUnicode.put("dotmath", new Character((char) 0x22c5)); + nameToEnc.put("dotmath", new Integer(215)); + encToName[215] = "dotmath"; + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2208), "element"); + nameToUnicode.put("element", new Character((char) 0x2208)); + nameToEnc.put("element", new Integer(206)); + encToName[206] = "element"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + nameToEnc.put("ellipsis", new Integer(188)); + encToName[188] = "ellipsis"; + + unicodeToName.put(new Character((char) 0x2205), "emptyset"); + nameToUnicode.put("emptyset", new Character((char) 0x2205)); + nameToEnc.put("emptyset", new Integer(198)); + encToName[198] = "emptyset"; + + unicodeToName.put(new Character((char) 0x03b5), "epsilon"); + nameToUnicode.put("epsilon", new Character((char) 0x03b5)); + nameToEnc.put("epsilon", new Integer(101)); + encToName[101] = "epsilon"; + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x2261), "equivalence"); + nameToUnicode.put("equivalence", new Character((char) 0x2261)); + nameToEnc.put("equivalence", new Integer(186)); + encToName[186] = "equivalence"; + + unicodeToName.put(new Character((char) 0x03b7), "eta"); + nameToUnicode.put("eta", new Character((char) 0x03b7)); + nameToEnc.put("eta", new Integer(104)); + encToName[104] = "eta"; + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x2203), "existential"); + nameToUnicode.put("existential", new Character((char) 0x2203)); + nameToEnc.put("existential", new Integer(36)); + encToName[36] = "existential"; + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + nameToEnc.put("florin", new Integer(166)); + encToName[166] = "florin"; + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + nameToEnc.put("fraction", new Integer(164)); + encToName[164] = "fraction"; + + unicodeToName.put(new Character((char) 0x03b3), "gamma"); + nameToUnicode.put("gamma", new Character((char) 0x03b3)); + nameToEnc.put("gamma", new Integer(103)); + encToName[103] = "gamma"; + + unicodeToName.put(new Character((char) 0x2207), "gradient"); + nameToUnicode.put("gradient", new Character((char) 0x2207)); + nameToEnc.put("gradient", new Integer(209)); + encToName[209] = "gradient"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x2265), "greaterequal"); + nameToUnicode.put("greaterequal", new Character((char) 0x2265)); + nameToEnc.put("greaterequal", new Integer(179)); + encToName[179] = "greaterequal"; + + unicodeToName.put(new Character((char) 0x2660), "heart"); + nameToUnicode.put("heart", new Character((char) 0x2660)); + nameToEnc.put("heart", new Integer(169)); + encToName[169] = "heart"; + + unicodeToName.put(new Character((char) 0x221e), "infinity"); + nameToUnicode.put("infinity", new Character((char) 0x221e)); + nameToEnc.put("infinity", new Integer(165)); + encToName[165] = "infinity"; + + unicodeToName.put(new Character((char) 0x222b), "integral"); + nameToUnicode.put("integral", new Character((char) 0x222b)); + nameToEnc.put("integral", new Integer(242)); + encToName[242] = "integral"; + + unicodeToName.put(new Character((char) 0x2320), "integraltp"); + nameToUnicode.put("integraltp", new Character((char) 0x2320)); + nameToEnc.put("integraltp", new Integer(243)); + encToName[243] = "integraltp"; + + unicodeToName.put(new Character((char) 0xF8F5), "integralex"); + nameToUnicode.put("integralex", new Character((char) 0xF8F5)); + nameToEnc.put("integralex", new Integer(244)); + encToName[244] = "integralex"; + + unicodeToName.put(new Character((char) 0x2321), "integralbt"); + nameToUnicode.put("integralbt", new Character((char) 0x2321)); + nameToEnc.put("integralbt", new Integer(245)); + encToName[245] = "integralbt"; + + unicodeToName.put(new Character((char) 0x2229), "intersection"); + nameToUnicode.put("intersection", new Character((char) 0x2229)); + nameToEnc.put("intersection", new Integer(199)); + encToName[199] = "intersection"; + + unicodeToName.put(new Character((char) 0x03b9), "iota"); + nameToUnicode.put("iota", new Character((char) 0x03b9)); + nameToEnc.put("iota", new Integer(105)); + encToName[105] = "iota"; + + unicodeToName.put(new Character((char) 0x03ba), "kappa"); + nameToUnicode.put("kappa", new Character((char) 0x03ba)); + nameToEnc.put("kappa", new Integer(107)); + encToName[107] = "kappa"; + + unicodeToName.put(new Character((char) 0x03bb), "lambda"); + nameToUnicode.put("lambda", new Character((char) 0x03bb)); + nameToEnc.put("lambda", new Integer(108)); + encToName[108] = "lambda"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x2264), "lessequal"); + nameToUnicode.put("lessequal", new Character((char) 0x2264)); + nameToEnc.put("lessequal", new Integer(163)); + encToName[163] = "lessequal"; + + unicodeToName.put(new Character((char) 0x2227), "logicaland"); + nameToUnicode.put("logicaland", new Character((char) 0x2227)); + nameToEnc.put("logicaland", new Integer(217)); + encToName[217] = "logicaland"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + nameToEnc.put("logicalnot", new Integer(216)); + encToName[216] = "logicalnot"; + + unicodeToName.put(new Character((char) 0x2228), "logicalor"); + nameToUnicode.put("logicalor", new Character((char) 0x2228)); + nameToEnc.put("logicalor", new Integer(218)); + encToName[218] = "logicalor"; + + unicodeToName.put(new Character((char) 0x25ca), "lozenge"); + nameToUnicode.put("lozenge", new Character((char) 0x25ca)); + nameToEnc.put("lozenge", new Integer(224)); + encToName[224] = "lozenge"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + nameToEnc.put("minus", new Integer(45)); + encToName[45] = "minus"; + + unicodeToName.put(new Character((char) 0x2032), "minute"); + nameToUnicode.put("minute", new Character((char) 0x2032)); + nameToEnc.put("minute", new Integer(162)); + encToName[162] = "minute"; + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + nameToEnc.put("mu", new Integer(109)); + encToName[109] = "mu"; + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + nameToEnc.put("multiply", new Integer(180)); + encToName[180] = "multiply"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x2209), "notelement"); + nameToUnicode.put("notelement", new Character((char) 0x2209)); + nameToEnc.put("notelement", new Integer(207)); + encToName[207] = "notelement"; + + unicodeToName.put(new Character((char) 0x2260), "notequal"); + nameToUnicode.put("notequal", new Character((char) 0x2260)); + nameToEnc.put("notequal", new Integer(185)); + encToName[185] = "notequal"; + + unicodeToName.put(new Character((char) 0x2284), "notsubset"); + nameToUnicode.put("notsubset", new Character((char) 0x2284)); + nameToEnc.put("notsubset", new Integer(203)); + encToName[203] = "notsubset"; + + unicodeToName.put(new Character((char) 0x03bd), "nu"); + nameToUnicode.put("nu", new Character((char) 0x03bd)); + nameToEnc.put("nu", new Integer(110)); + encToName[110] = "nu"; + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x03c9), "omega"); + nameToUnicode.put("omega", new Character((char) 0x03c9)); + nameToEnc.put("omega", new Integer(119)); + encToName[119] = "omega"; + + unicodeToName.put(new Character((char) 0x03d6), "omega1"); + nameToUnicode.put("omega1", new Character((char) 0x03d6)); + nameToEnc.put("omega1", new Integer(118)); + encToName[118] = "omega1"; + + unicodeToName.put(new Character((char) 0x03bf), "omicron"); + nameToUnicode.put("omicron", new Character((char) 0x03bf)); + nameToEnc.put("omicron", new Integer(111)); + encToName[111] = "omicron"; + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0xF8EB), "parenlefttp"); + nameToUnicode.put("parenlefttp", new Character((char) 0xF8EB)); + nameToEnc.put("parenlefttp", new Integer(230)); + encToName[230] = "parenlefttp"; + + unicodeToName.put(new Character((char) 0xF8EC), "parenleftex"); + nameToUnicode.put("parenleftex", new Character((char) 0xF8EC)); + nameToEnc.put("parenleftex", new Integer(231)); + encToName[231] = "parenleftex"; + + unicodeToName.put(new Character((char) 0xF8ED), "parenleftbt"); + nameToUnicode.put("parenleftbt", new Character((char) 0xF8ED)); + nameToEnc.put("parenleftbt", new Integer(232)); + encToName[232] = "parenleftbt"; + + unicodeToName.put(new Character((char) 0xF8F6), "parenrighttp"); + nameToUnicode.put("parenrighttp", new Character((char) 0xF8F6)); + nameToEnc.put("parenrighttp", new Integer(246)); + encToName[246] = "parenrighttp"; + + unicodeToName.put(new Character((char) 0xF8F7), "parenrightex"); + nameToUnicode.put("parenrightex", new Character((char) 0xF8F7)); + nameToEnc.put("parenrightex", new Integer(247)); + encToName[247] = "parenrightex"; + + unicodeToName.put(new Character((char) 0xF8F8), "parenrightbt"); + nameToUnicode.put("parenrightbt", new Character((char) 0xF8F8)); + nameToEnc.put("parenrightbt", new Integer(248)); + encToName[248] = "parenrightbt"; + + unicodeToName.put(new Character((char) 0x2202), "partialdiff"); + nameToUnicode.put("partialdiff", new Character((char) 0x2202)); + nameToEnc.put("partialdiff", new Integer(182)); + encToName[182] = "partialdiff"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x22a5), "perpendicular"); + nameToUnicode.put("perpendicular", new Character((char) 0x22a5)); + nameToEnc.put("perpendicular", new Integer(94)); + encToName[94] = "perpendicular"; + + unicodeToName.put(new Character((char) 0x03d5), "phi"); + nameToUnicode.put("phi", new Character((char) 0x03d5)); + nameToEnc.put("phi", new Integer(102)); + encToName[102] = "phi"; + + unicodeToName.put(new Character((char) 0x03c6), "phi1"); + nameToUnicode.put("phi1", new Character((char) 0x03c6)); + nameToEnc.put("phi1", new Integer(106)); + encToName[106] = "phi1"; + + unicodeToName.put(new Character((char) 0x03c0), "pi"); + nameToUnicode.put("pi", new Character((char) 0x03c0)); + nameToEnc.put("pi", new Integer(112)); + encToName[112] = "pi"; + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + nameToEnc.put("plusminus", new Integer(177)); + encToName[177] = "plusminus"; + + unicodeToName.put(new Character((char) 0x220f), "product"); + nameToUnicode.put("product", new Character((char) 0x220f)); + nameToEnc.put("product", new Integer(213)); + encToName[213] = "product"; + + unicodeToName.put(new Character((char) 0x2282), "propersubset"); + nameToUnicode.put("propersubset", new Character((char) 0x2282)); + nameToEnc.put("propersubset", new Integer(204)); + encToName[204] = "propersubset"; + + unicodeToName.put(new Character((char) 0x2283), "propersuperset"); + nameToUnicode.put("propersuperset", new Character((char) 0x2283)); + nameToEnc.put("propersuperset", new Integer(201)); + encToName[201] = "propersuperset"; + + unicodeToName.put(new Character((char) 0x221d), "proportional"); + nameToUnicode.put("proportional", new Character((char) 0x221d)); + nameToEnc.put("proportional", new Integer(181)); + encToName[181] = "proportional"; + + unicodeToName.put(new Character((char) 0x03c8), "psi"); + nameToUnicode.put("psi", new Character((char) 0x03c8)); + nameToEnc.put("psi", new Integer(121)); + encToName[121] = "psi"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x221a), "radical"); + nameToUnicode.put("radical", new Character((char) 0x221a)); + nameToEnc.put("radical", new Integer(214)); + encToName[214] = "radical"; + + unicodeToName.put(new Character((char) 0xF8E5), "radicalex"); + nameToUnicode.put("radicalex", new Character((char) 0xF8E5)); + nameToEnc.put("radicalex", new Integer(96)); + encToName[96] = "radicalex"; + + unicodeToName.put(new Character((char) 0x2286), "reflexsubset"); + nameToUnicode.put("reflexsubset", new Character((char) 0x2286)); + nameToEnc.put("reflexsubset", new Integer(205)); + encToName[205] = "reflexsubset"; + + unicodeToName.put(new Character((char) 0x2287), "reflexsuperset"); + nameToUnicode.put("reflexsuperset", new Character((char) 0x2287)); + nameToEnc.put("reflexsuperset", new Integer(202)); + encToName[202] = "reflexsuperset"; + + unicodeToName.put(new Character((char) 0xF8E8), "registersans"); + nameToUnicode.put("registersans", new Character((char) 0xF8E8)); + nameToEnc.put("registersans", new Integer(226)); + encToName[226] = "registersans"; + + unicodeToName.put(new Character((char) 0xF6DA), "registerserif"); + nameToUnicode.put("registerserif", new Character((char) 0xF6DA)); + nameToEnc.put("registerserif", new Integer(210)); + encToName[210] = "registerserif"; + + unicodeToName.put(new Character((char) 0x03c1), "rho"); + nameToUnicode.put("rho", new Character((char) 0x03c1)); + nameToEnc.put("rho", new Integer(114)); + encToName[114] = "rho"; + + unicodeToName.put(new Character((char) 0x2033), "second"); + nameToUnicode.put("second", new Character((char) 0x2033)); + nameToEnc.put("second", new Integer(178)); + encToName[178] = "second"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x03c3), "sigma"); + nameToUnicode.put("sigma", new Character((char) 0x03c3)); + nameToEnc.put("sigma", new Integer(115)); + encToName[115] = "sigma"; + + unicodeToName.put(new Character((char) 0x03c2), "sigma1"); + nameToUnicode.put("sigma1", new Character((char) 0x03c2)); + nameToEnc.put("sigma1", new Integer(86)); + encToName[86] = "sigma1"; + + unicodeToName.put(new Character((char) 0x223c), "similar"); + nameToUnicode.put("similar", new Character((char) 0x223c)); + nameToEnc.put("similar", new Integer(126)); + encToName[126] = "similar"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x2660), "spade"); + nameToUnicode.put("spade", new Character((char) 0x2660)); + nameToEnc.put("spade", new Integer(170)); + encToName[170] = "spade"; + + unicodeToName.put(new Character((char) 0x220b), "suchthat"); + nameToUnicode.put("suchthat", new Character((char) 0x220b)); + nameToEnc.put("suchthat", new Integer(39)); + encToName[39] = "suchthat"; + + unicodeToName.put(new Character((char) 0x2211), "summation"); + nameToUnicode.put("summation", new Character((char) 0x2211)); + nameToEnc.put("summation", new Integer(229)); + encToName[229] = "summation"; + + unicodeToName.put(new Character((char) 0x03c4), "tau"); + nameToUnicode.put("tau", new Character((char) 0x03c4)); + nameToEnc.put("tau", new Integer(116)); + encToName[116] = "tau"; + + unicodeToName.put(new Character((char) 0x2234), "therefore"); + nameToUnicode.put("therefore", new Character((char) 0x2234)); + nameToEnc.put("therefore", new Integer(92)); + encToName[92] = "therefore"; + + unicodeToName.put(new Character((char) 0x03b8), "theta"); + nameToUnicode.put("theta", new Character((char) 0x03b8)); + nameToEnc.put("theta", new Integer(113)); + encToName[113] = "theta"; + + unicodeToName.put(new Character((char) 0x03d1), "theta1"); + nameToUnicode.put("theta1", new Character((char) 0x03d1)); + nameToEnc.put("theta1", new Integer(74)); + encToName[74] = "theta1"; + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0xF8EA), "trademarksans"); + nameToUnicode.put("trademarksans", new Character((char) 0xF8EA)); + nameToEnc.put("trademarksans", new Integer(228)); + encToName[228] = "trademarksans"; + + unicodeToName.put(new Character((char) 0xF6DB), "trademarkserif"); + nameToUnicode.put("trademarkserif", new Character((char) 0xF6DB)); + nameToEnc.put("trademarkserif", new Integer(212)); + encToName[212] = "trademarkserif"; + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x222a), "union"); + nameToUnicode.put("union", new Character((char) 0x222a)); + nameToEnc.put("union", new Integer(200)); + encToName[200] = "union"; + + unicodeToName.put(new Character((char) 0x2200), "universal"); + nameToUnicode.put("universal", new Character((char) 0x2200)); + nameToEnc.put("universal", new Integer(34)); + encToName[34] = "universal"; + + unicodeToName.put(new Character((char) 0x03c5), "upsilon"); + nameToUnicode.put("upsilon", new Character((char) 0x03c5)); + nameToEnc.put("upsilon", new Integer(117)); + encToName[117] = "upsilon"; + + unicodeToName.put(new Character((char) 0x2118), "weierstrass"); + nameToUnicode.put("weierstrass", new Character((char) 0x2118)); + nameToEnc.put("weierstrass", new Integer(195)); + encToName[195] = "weierstrass"; + + unicodeToName.put(new Character((char) 0x03be), "xi"); + nameToUnicode.put("xi", new Character((char) 0x03be)); + nameToEnc.put("xi", new Integer(120)); + encToName[120] = "xi"; + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + unicodeToName.put(new Character((char) 0x03b6), "zeta"); + nameToUnicode.put("zeta", new Character((char) 0x03b6)); + nameToEnc.put("zeta", new Integer(122)); + encToName[122] = "zeta"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Symbol");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/WINLatin.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/WINLatin.java index 1e5a10a8d..d551170b6 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/WINLatin.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/WINLatin.java @@ -1,1168 +1,1168 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated WINLatin Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class WINLatin extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public WINLatin() { - unicodeToName.put(new Character((char) 0x0041), "A"); - nameToUnicode.put("A", new Character((char) 0x0041)); - nameToEnc.put("A", new Integer(65)); - encToName[65] = "A"; - - unicodeToName.put(new Character((char) 0x00c6), "AE"); - nameToUnicode.put("AE", new Character((char) 0x00c6)); - nameToEnc.put("AE", new Integer(198)); - encToName[198] = "AE"; - - unicodeToName.put(new Character((char) 0x00c1), "Aacute"); - nameToUnicode.put("Aacute", new Character((char) 0x00c1)); - nameToEnc.put("Aacute", new Integer(193)); - encToName[193] = "Aacute"; - - unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); - nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); - nameToEnc.put("Acircumflex", new Integer(194)); - encToName[194] = "Acircumflex"; - - unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); - nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); - nameToEnc.put("Adieresis", new Integer(196)); - encToName[196] = "Adieresis"; - - unicodeToName.put(new Character((char) 0x00c0), "Agrave"); - nameToUnicode.put("Agrave", new Character((char) 0x00c0)); - nameToEnc.put("Agrave", new Integer(192)); - encToName[192] = "Agrave"; - - unicodeToName.put(new Character((char) 0x00c5), "Aring"); - nameToUnicode.put("Aring", new Character((char) 0x00c5)); - nameToEnc.put("Aring", new Integer(197)); - encToName[197] = "Aring"; - - unicodeToName.put(new Character((char) 0x00c3), "Atilde"); - nameToUnicode.put("Atilde", new Character((char) 0x00c3)); - nameToEnc.put("Atilde", new Integer(195)); - encToName[195] = "Atilde"; - - unicodeToName.put(new Character((char) 0x0042), "B"); - nameToUnicode.put("B", new Character((char) 0x0042)); - nameToEnc.put("B", new Integer(66)); - encToName[66] = "B"; - - unicodeToName.put(new Character((char) 0x0043), "C"); - nameToUnicode.put("C", new Character((char) 0x0043)); - nameToEnc.put("C", new Integer(67)); - encToName[67] = "C"; - - unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); - nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); - nameToEnc.put("Ccedilla", new Integer(199)); - encToName[199] = "Ccedilla"; - - unicodeToName.put(new Character((char) 0x0044), "D"); - nameToUnicode.put("D", new Character((char) 0x0044)); - nameToEnc.put("D", new Integer(68)); - encToName[68] = "D"; - - unicodeToName.put(new Character((char) 0x0045), "E"); - nameToUnicode.put("E", new Character((char) 0x0045)); - nameToEnc.put("E", new Integer(69)); - encToName[69] = "E"; - - unicodeToName.put(new Character((char) 0x00c9), "Eacute"); - nameToUnicode.put("Eacute", new Character((char) 0x00c9)); - nameToEnc.put("Eacute", new Integer(201)); - encToName[201] = "Eacute"; - - unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); - nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); - nameToEnc.put("Ecircumflex", new Integer(202)); - encToName[202] = "Ecircumflex"; - - unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); - nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); - nameToEnc.put("Edieresis", new Integer(203)); - encToName[203] = "Edieresis"; - - unicodeToName.put(new Character((char) 0x00c8), "Egrave"); - nameToUnicode.put("Egrave", new Character((char) 0x00c8)); - nameToEnc.put("Egrave", new Integer(200)); - encToName[200] = "Egrave"; - - unicodeToName.put(new Character((char) 0x00d0), "Eth"); - nameToUnicode.put("Eth", new Character((char) 0x00d0)); - nameToEnc.put("Eth", new Integer(208)); - encToName[208] = "Eth"; - - unicodeToName.put(new Character((char) 0x20ac), "Euro"); - nameToUnicode.put("Euro", new Character((char) 0x20ac)); - nameToEnc.put("Euro", new Integer(128)); - encToName[128] = "Euro"; - - unicodeToName.put(new Character((char) 0x0046), "F"); - nameToUnicode.put("F", new Character((char) 0x0046)); - nameToEnc.put("F", new Integer(70)); - encToName[70] = "F"; - - unicodeToName.put(new Character((char) 0x0047), "G"); - nameToUnicode.put("G", new Character((char) 0x0047)); - nameToEnc.put("G", new Integer(71)); - encToName[71] = "G"; - - unicodeToName.put(new Character((char) 0x0048), "H"); - nameToUnicode.put("H", new Character((char) 0x0048)); - nameToEnc.put("H", new Integer(72)); - encToName[72] = "H"; - - unicodeToName.put(new Character((char) 0x0049), "I"); - nameToUnicode.put("I", new Character((char) 0x0049)); - nameToEnc.put("I", new Integer(73)); - encToName[73] = "I"; - - unicodeToName.put(new Character((char) 0x00cd), "Iacute"); - nameToUnicode.put("Iacute", new Character((char) 0x00cd)); - nameToEnc.put("Iacute", new Integer(205)); - encToName[205] = "Iacute"; - - unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); - nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); - nameToEnc.put("Icircumflex", new Integer(206)); - encToName[206] = "Icircumflex"; - - unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); - nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); - nameToEnc.put("Idieresis", new Integer(207)); - encToName[207] = "Idieresis"; - - unicodeToName.put(new Character((char) 0x00cc), "Igrave"); - nameToUnicode.put("Igrave", new Character((char) 0x00cc)); - nameToEnc.put("Igrave", new Integer(204)); - encToName[204] = "Igrave"; - - unicodeToName.put(new Character((char) 0x004a), "J"); - nameToUnicode.put("J", new Character((char) 0x004a)); - nameToEnc.put("J", new Integer(74)); - encToName[74] = "J"; - - unicodeToName.put(new Character((char) 0x004b), "K"); - nameToUnicode.put("K", new Character((char) 0x004b)); - nameToEnc.put("K", new Integer(75)); - encToName[75] = "K"; - - unicodeToName.put(new Character((char) 0x004c), "L"); - nameToUnicode.put("L", new Character((char) 0x004c)); - nameToEnc.put("L", new Integer(76)); - encToName[76] = "L"; - - unicodeToName.put(new Character((char) 0x0141), "Lslash"); - nameToUnicode.put("Lslash", new Character((char) 0x0141)); - - unicodeToName.put(new Character((char) 0x004d), "M"); - nameToUnicode.put("M", new Character((char) 0x004d)); - nameToEnc.put("M", new Integer(77)); - encToName[77] = "M"; - - unicodeToName.put(new Character((char) 0x004e), "N"); - nameToUnicode.put("N", new Character((char) 0x004e)); - nameToEnc.put("N", new Integer(78)); - encToName[78] = "N"; - - unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); - nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); - nameToEnc.put("Ntilde", new Integer(209)); - encToName[209] = "Ntilde"; - - unicodeToName.put(new Character((char) 0x004f), "O"); - nameToUnicode.put("O", new Character((char) 0x004f)); - nameToEnc.put("O", new Integer(79)); - encToName[79] = "O"; - - unicodeToName.put(new Character((char) 0x0152), "OE"); - nameToUnicode.put("OE", new Character((char) 0x0152)); - nameToEnc.put("OE", new Integer(140)); - encToName[140] = "OE"; - - unicodeToName.put(new Character((char) 0x00d2), "Oacute"); - nameToUnicode.put("Oacute", new Character((char) 0x00d2)); - nameToEnc.put("Oacute", new Integer(211)); - encToName[211] = "Oacute"; - - unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); - nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); - nameToEnc.put("Ocircumflex", new Integer(212)); - encToName[212] = "Ocircumflex"; - - unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); - nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); - nameToEnc.put("Odieresis", new Integer(214)); - encToName[214] = "Odieresis"; - - unicodeToName.put(new Character((char) 0x00d3), "Ograve"); - nameToUnicode.put("Ograve", new Character((char) 0x00d3)); - nameToEnc.put("Ograve", new Integer(210)); - encToName[210] = "Ograve"; - - unicodeToName.put(new Character((char) 0x00d8), "Oslash"); - nameToUnicode.put("Oslash", new Character((char) 0x00d8)); - nameToEnc.put("Oslash", new Integer(216)); - encToName[216] = "Oslash"; - - unicodeToName.put(new Character((char) 0x00d5), "Otilde"); - nameToUnicode.put("Otilde", new Character((char) 0x00d5)); - nameToEnc.put("Otilde", new Integer(213)); - encToName[213] = "Otilde"; - - unicodeToName.put(new Character((char) 0x0050), "P"); - nameToUnicode.put("P", new Character((char) 0x0050)); - nameToEnc.put("P", new Integer(80)); - encToName[80] = "P"; - - unicodeToName.put(new Character((char) 0x0051), "Q"); - nameToUnicode.put("Q", new Character((char) 0x0051)); - nameToEnc.put("Q", new Integer(81)); - encToName[81] = "Q"; - - unicodeToName.put(new Character((char) 0x0052), "R"); - nameToUnicode.put("R", new Character((char) 0x0052)); - nameToEnc.put("R", new Integer(82)); - encToName[82] = "R"; - - unicodeToName.put(new Character((char) 0x0053), "S"); - nameToUnicode.put("S", new Character((char) 0x0053)); - nameToEnc.put("S", new Integer(83)); - encToName[83] = "S"; - - unicodeToName.put(new Character((char) 0x0160), "Scaron"); - nameToUnicode.put("Scaron", new Character((char) 0x0160)); - nameToEnc.put("Scaron", new Integer(138)); - encToName[138] = "Scaron"; - - unicodeToName.put(new Character((char) 0x0054), "T"); - nameToUnicode.put("T", new Character((char) 0x0054)); - nameToEnc.put("T", new Integer(84)); - encToName[84] = "T"; - - unicodeToName.put(new Character((char) 0x00de), "Thorn"); - nameToUnicode.put("Thorn", new Character((char) 0x00de)); - nameToEnc.put("Thorn", new Integer(222)); - encToName[222] = "Thorn"; - - unicodeToName.put(new Character((char) 0x0055), "U"); - nameToUnicode.put("U", new Character((char) 0x0055)); - nameToEnc.put("U", new Integer(85)); - encToName[85] = "U"; - - unicodeToName.put(new Character((char) 0x00da), "Uacute"); - nameToUnicode.put("Uacute", new Character((char) 0x00da)); - nameToEnc.put("Uacute", new Integer(218)); - encToName[218] = "Uacute"; - - unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); - nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); - nameToEnc.put("Ucircumflex", new Integer(219)); - encToName[219] = "Ucircumflex"; - - unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); - nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); - nameToEnc.put("Udieresis", new Integer(220)); - encToName[220] = "Udieresis"; - - unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); - nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); - nameToEnc.put("Ugrave", new Integer(217)); - encToName[217] = "Ugrave"; - - unicodeToName.put(new Character((char) 0x0056), "V"); - nameToUnicode.put("V", new Character((char) 0x0056)); - nameToEnc.put("V", new Integer(86)); - encToName[86] = "V"; - - unicodeToName.put(new Character((char) 0x0057), "W"); - nameToUnicode.put("W", new Character((char) 0x0057)); - nameToEnc.put("W", new Integer(87)); - encToName[87] = "W"; - - unicodeToName.put(new Character((char) 0x0058), "X"); - nameToUnicode.put("X", new Character((char) 0x0058)); - nameToEnc.put("X", new Integer(88)); - encToName[88] = "X"; - - unicodeToName.put(new Character((char) 0x0059), "Y"); - nameToUnicode.put("Y", new Character((char) 0x0059)); - nameToEnc.put("Y", new Integer(89)); - encToName[89] = "Y"; - - unicodeToName.put(new Character((char) 0x00dd), "Yacute"); - nameToUnicode.put("Yacute", new Character((char) 0x00dd)); - nameToEnc.put("Yacute", new Integer(221)); - encToName[221] = "Yacute"; - - unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); - nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); - nameToEnc.put("Ydieresis", new Integer(159)); - encToName[159] = "Ydieresis"; - - unicodeToName.put(new Character((char) 0x005a), "Z"); - nameToUnicode.put("Z", new Character((char) 0x005a)); - nameToEnc.put("Z", new Integer(90)); - encToName[90] = "Z"; - - unicodeToName.put(new Character((char) 0x017d), "Zcaron"); - nameToUnicode.put("Zcaron", new Character((char) 0x017d)); - nameToEnc.put("Zcaron", new Integer(142)); - encToName[142] = "Zcaron"; - - unicodeToName.put(new Character((char) 0x0061), "a"); - nameToUnicode.put("a", new Character((char) 0x0061)); - nameToEnc.put("a", new Integer(97)); - encToName[97] = "a"; - - unicodeToName.put(new Character((char) 0x00e1), "aacute"); - nameToUnicode.put("aacute", new Character((char) 0x00e1)); - nameToEnc.put("aacute", new Integer(225)); - encToName[225] = "aacute"; - - unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); - nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); - nameToEnc.put("acircumflex", new Integer(226)); - encToName[226] = "acircumflex"; - - unicodeToName.put(new Character((char) 0x00b4), "acute"); - nameToUnicode.put("acute", new Character((char) 0x00b4)); - nameToEnc.put("acute", new Integer(180)); - encToName[180] = "acute"; - - unicodeToName.put(new Character((char) 0x00e4), "adieresis"); - nameToUnicode.put("adieresis", new Character((char) 0x00e4)); - nameToEnc.put("adieresis", new Integer(228)); - encToName[228] = "adieresis"; - - unicodeToName.put(new Character((char) 0x00e6), "ae"); - nameToUnicode.put("ae", new Character((char) 0x00e6)); - nameToEnc.put("ae", new Integer(230)); - encToName[230] = "ae"; - - unicodeToName.put(new Character((char) 0x00e0), "agrave"); - nameToUnicode.put("agrave", new Character((char) 0x00e0)); - nameToEnc.put("agrave", new Integer(224)); - encToName[224] = "agrave"; - - unicodeToName.put(new Character((char) 0x0026), "ampersand"); - nameToUnicode.put("ampersand", new Character((char) 0x0026)); - nameToEnc.put("ampersand", new Integer(38)); - encToName[38] = "ampersand"; - - unicodeToName.put(new Character((char) 0x00e5), "aring"); - nameToUnicode.put("aring", new Character((char) 0x00e5)); - nameToEnc.put("aring", new Integer(229)); - encToName[229] = "aring"; - - unicodeToName.put(new Character((char) 0x005e), "asciicircum"); - nameToUnicode.put("asciicircum", new Character((char) 0x005e)); - nameToEnc.put("asciicircum", new Integer(94)); - encToName[94] = "asciicircum"; - - unicodeToName.put(new Character((char) 0x007e), "asciitilde"); - nameToUnicode.put("asciitilde", new Character((char) 0x007e)); - nameToEnc.put("asciitilde", new Integer(126)); - encToName[126] = "asciitilde"; - - unicodeToName.put(new Character((char) 0x002a), "asterisk"); - nameToUnicode.put("asterisk", new Character((char) 0x002a)); - nameToEnc.put("asterisk", new Integer(42)); - encToName[42] = "asterisk"; - - unicodeToName.put(new Character((char) 0x0040), "at"); - nameToUnicode.put("at", new Character((char) 0x0040)); - nameToEnc.put("at", new Integer(64)); - encToName[64] = "at"; - - unicodeToName.put(new Character((char) 0x00e3), "atilde"); - nameToUnicode.put("atilde", new Character((char) 0x00e3)); - nameToEnc.put("atilde", new Integer(227)); - encToName[227] = "atilde"; - - unicodeToName.put(new Character((char) 0x0062), "b"); - nameToUnicode.put("b", new Character((char) 0x0062)); - nameToEnc.put("b", new Integer(98)); - encToName[98] = "b"; - - unicodeToName.put(new Character((char) 0x005c), "backslash"); - nameToUnicode.put("backslash", new Character((char) 0x005c)); - nameToEnc.put("backslash", new Integer(92)); - encToName[92] = "backslash"; - - unicodeToName.put(new Character((char) 0x007c), "bar"); - nameToUnicode.put("bar", new Character((char) 0x007c)); - nameToEnc.put("bar", new Integer(124)); - encToName[124] = "bar"; - - unicodeToName.put(new Character((char) 0x007b), "braceleft"); - nameToUnicode.put("braceleft", new Character((char) 0x007b)); - nameToEnc.put("braceleft", new Integer(123)); - encToName[123] = "braceleft"; - - unicodeToName.put(new Character((char) 0x007d), "braceright"); - nameToUnicode.put("braceright", new Character((char) 0x007d)); - nameToEnc.put("braceright", new Integer(125)); - encToName[125] = "braceright"; - - unicodeToName.put(new Character((char) 0x005b), "bracketleft"); - nameToUnicode.put("bracketleft", new Character((char) 0x005b)); - nameToEnc.put("bracketleft", new Integer(91)); - encToName[91] = "bracketleft"; - - unicodeToName.put(new Character((char) 0x005d), "bracketright"); - nameToUnicode.put("bracketright", new Character((char) 0x005d)); - nameToEnc.put("bracketright", new Integer(93)); - encToName[93] = "bracketright"; - - unicodeToName.put(new Character((char) 0x02d8), "breve"); - nameToUnicode.put("breve", new Character((char) 0x02d8)); - - unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); - nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); - nameToEnc.put("brokenbar", new Integer(166)); - encToName[166] = "brokenbar"; - - unicodeToName.put(new Character((char) 0x2022), "bullet"); - nameToUnicode.put("bullet", new Character((char) 0x2022)); - nameToEnc.put("bullet", new Integer(149)); - encToName[149] = "bullet"; - - unicodeToName.put(new Character((char) 0x0063), "c"); - nameToUnicode.put("c", new Character((char) 0x0063)); - nameToEnc.put("c", new Integer(99)); - encToName[99] = "c"; - - unicodeToName.put(new Character((char) 0x02c7), "caron"); - nameToUnicode.put("caron", new Character((char) 0x02c7)); - - unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); - nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); - nameToEnc.put("ccedilla", new Integer(231)); - encToName[231] = "ccedilla"; - - unicodeToName.put(new Character((char) 0x00b8), "cedilla"); - nameToUnicode.put("cedilla", new Character((char) 0x00b8)); - nameToEnc.put("cedilla", new Integer(184)); - encToName[184] = "cedilla"; - - unicodeToName.put(new Character((char) 0x00a2), "cent"); - nameToUnicode.put("cent", new Character((char) 0x00a2)); - nameToEnc.put("cent", new Integer(162)); - encToName[162] = "cent"; - - unicodeToName.put(new Character((char) 0x02c6), "circumflex"); - nameToUnicode.put("circumflex", new Character((char) 0x02c6)); - nameToEnc.put("circumflex", new Integer(136)); - encToName[136] = "circumflex"; - - unicodeToName.put(new Character((char) 0x003a), "colon"); - nameToUnicode.put("colon", new Character((char) 0x003a)); - nameToEnc.put("colon", new Integer(58)); - encToName[58] = "colon"; - - unicodeToName.put(new Character((char) 0x002c), "comma"); - nameToUnicode.put("comma", new Character((char) 0x002c)); - nameToEnc.put("comma", new Integer(44)); - encToName[44] = "comma"; - - unicodeToName.put(new Character((char) 0x00a9), "copyright"); - nameToUnicode.put("copyright", new Character((char) 0x00a9)); - nameToEnc.put("copyright", new Integer(169)); - encToName[169] = "copyright"; - - unicodeToName.put(new Character((char) 0x00a4), "currency"); - nameToUnicode.put("currency", new Character((char) 0x00a4)); - nameToEnc.put("currency", new Integer(164)); - encToName[164] = "currency"; - - unicodeToName.put(new Character((char) 0x0064), "d"); - nameToUnicode.put("d", new Character((char) 0x0064)); - nameToEnc.put("d", new Integer(100)); - encToName[100] = "d"; - - unicodeToName.put(new Character((char) 0x2020), "dagger"); - nameToUnicode.put("dagger", new Character((char) 0x2020)); - nameToEnc.put("dagger", new Integer(134)); - encToName[134] = "dagger"; - - unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); - nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); - nameToEnc.put("daggerdbl", new Integer(135)); - encToName[135] = "daggerdbl"; - - unicodeToName.put(new Character((char) 0x00b0), "degree"); - nameToUnicode.put("degree", new Character((char) 0x00b0)); - nameToEnc.put("degree", new Integer(176)); - encToName[176] = "degree"; - - unicodeToName.put(new Character((char) 0x00a8), "dieresis"); - nameToUnicode.put("dieresis", new Character((char) 0x00a8)); - nameToEnc.put("dieresis", new Integer(168)); - encToName[168] = "dieresis"; - - unicodeToName.put(new Character((char) 0x00f7), "divide"); - nameToUnicode.put("divide", new Character((char) 0x00f7)); - nameToEnc.put("divide", new Integer(247)); - encToName[247] = "divide"; - - unicodeToName.put(new Character((char) 0x0024), "dollar"); - nameToUnicode.put("dollar", new Character((char) 0x0024)); - nameToEnc.put("dollar", new Integer(36)); - encToName[36] = "dollar"; - - unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); - nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); - - unicodeToName.put(new Character((char) 0x0131), "dotlessi"); - nameToUnicode.put("dotlessi", new Character((char) 0x0131)); - - unicodeToName.put(new Character((char) 0x0065), "e"); - nameToUnicode.put("e", new Character((char) 0x0065)); - nameToEnc.put("e", new Integer(101)); - encToName[101] = "e"; - - unicodeToName.put(new Character((char) 0x00e9), "eacute"); - nameToUnicode.put("eacute", new Character((char) 0x00e9)); - nameToEnc.put("eacute", new Integer(233)); - encToName[233] = "eacute"; - - unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); - nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); - nameToEnc.put("ecircumflex", new Integer(234)); - encToName[234] = "ecircumflex"; - - unicodeToName.put(new Character((char) 0x00eb), "edieresis"); - nameToUnicode.put("edieresis", new Character((char) 0x00eb)); - nameToEnc.put("edieresis", new Integer(235)); - encToName[235] = "edieresis"; - - unicodeToName.put(new Character((char) 0x00e8), "egrave"); - nameToUnicode.put("egrave", new Character((char) 0x00e8)); - nameToEnc.put("egrave", new Integer(232)); - encToName[232] = "egrave"; - - unicodeToName.put(new Character((char) 0x0038), "eight"); - nameToUnicode.put("eight", new Character((char) 0x0038)); - nameToEnc.put("eight", new Integer(56)); - encToName[56] = "eight"; - - unicodeToName.put(new Character((char) 0x2026), "ellipsis"); - nameToUnicode.put("ellipsis", new Character((char) 0x2026)); - nameToEnc.put("ellipsis", new Integer(133)); - encToName[133] = "ellipsis"; - - unicodeToName.put(new Character((char) 0x002d), "emdash"); - nameToUnicode.put("emdash", new Character((char) 0x002d)); - nameToEnc.put("emdash", new Integer(151)); - encToName[151] = "emdash"; - - unicodeToName.put(new Character((char) 0x002d), "endash"); - nameToUnicode.put("endash", new Character((char) 0x002d)); - nameToEnc.put("endash", new Integer(150)); - encToName[150] = "endash"; - - unicodeToName.put(new Character((char) 0x003d), "equal"); - nameToUnicode.put("equal", new Character((char) 0x003d)); - nameToEnc.put("equal", new Integer(61)); - encToName[61] = "equal"; - - unicodeToName.put(new Character((char) 0x00f0), "eth"); - nameToUnicode.put("eth", new Character((char) 0x00f0)); - nameToEnc.put("eth", new Integer(240)); - encToName[240] = "eth"; - - unicodeToName.put(new Character((char) 0x0021), "exclam"); - nameToUnicode.put("exclam", new Character((char) 0x0021)); - nameToEnc.put("exclam", new Integer(33)); - encToName[33] = "exclam"; - - unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); - nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); - nameToEnc.put("exclamdown", new Integer(161)); - encToName[161] = "exclamdown"; - - unicodeToName.put(new Character((char) 0x0066), "f"); - nameToUnicode.put("f", new Character((char) 0x0066)); - nameToEnc.put("f", new Integer(102)); - encToName[102] = "f"; - - unicodeToName.put(new Character((char) 0xfb01), "fi"); - nameToUnicode.put("fi", new Character((char) 0xfb01)); - - unicodeToName.put(new Character((char) 0x0035), "five"); - nameToUnicode.put("five", new Character((char) 0x0035)); - nameToEnc.put("five", new Integer(53)); - encToName[53] = "five"; - - unicodeToName.put(new Character((char) 0xfb02), "fl"); - nameToUnicode.put("fl", new Character((char) 0xfb02)); - - unicodeToName.put(new Character((char) 0x0192), "florin"); - nameToUnicode.put("florin", new Character((char) 0x0192)); - nameToEnc.put("florin", new Integer(131)); - encToName[131] = "florin"; - - unicodeToName.put(new Character((char) 0x0034), "four"); - nameToUnicode.put("four", new Character((char) 0x0034)); - nameToEnc.put("four", new Integer(52)); - encToName[52] = "four"; - - unicodeToName.put(new Character((char) 0x2044), "fraction"); - nameToUnicode.put("fraction", new Character((char) 0x2044)); - - unicodeToName.put(new Character((char) 0x0067), "g"); - nameToUnicode.put("g", new Character((char) 0x0067)); - nameToEnc.put("g", new Integer(103)); - encToName[103] = "g"; - - unicodeToName.put(new Character((char) 0x00df), "germandbls"); - nameToUnicode.put("germandbls", new Character((char) 0x00df)); - nameToEnc.put("germandbls", new Integer(223)); - encToName[223] = "germandbls"; - - unicodeToName.put(new Character((char) 0x0060), "grave"); - nameToUnicode.put("grave", new Character((char) 0x0060)); - nameToEnc.put("grave", new Integer(96)); - encToName[96] = "grave"; - - unicodeToName.put(new Character((char) 0x003e), "greater"); - nameToUnicode.put("greater", new Character((char) 0x003e)); - nameToEnc.put("greater", new Integer(62)); - encToName[62] = "greater"; - - unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); - nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); - nameToEnc.put("guillemotleft", new Integer(171)); - encToName[171] = "guillemotleft"; - - unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); - nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); - nameToEnc.put("guillemotright", new Integer(187)); - encToName[187] = "guillemotright"; - - unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); - nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); - nameToEnc.put("guilsinglleft", new Integer(139)); - encToName[139] = "guilsinglleft"; - - unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); - nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); - nameToEnc.put("guilsinglright", new Integer(155)); - encToName[155] = "guilsinglright"; - - unicodeToName.put(new Character((char) 0x0068), "h"); - nameToUnicode.put("h", new Character((char) 0x0068)); - nameToEnc.put("h", new Integer(104)); - encToName[104] = "h"; - - unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); - nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); - - unicodeToName.put(new Character((char) 0x002d), "hyphen"); - nameToUnicode.put("hyphen", new Character((char) 0x002d)); - nameToEnc.put("hyphen", new Integer(45)); - encToName[45] = "hyphen"; - - unicodeToName.put(new Character((char) 0x0069), "i"); - nameToUnicode.put("i", new Character((char) 0x0069)); - nameToEnc.put("i", new Integer(105)); - encToName[105] = "i"; - - unicodeToName.put(new Character((char) 0x00ed), "iacute"); - nameToUnicode.put("iacute", new Character((char) 0x00ed)); - nameToEnc.put("iacute", new Integer(237)); - encToName[237] = "iacute"; - - unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); - nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); - nameToEnc.put("icircumflex", new Integer(238)); - encToName[238] = "icircumflex"; - - unicodeToName.put(new Character((char) 0x00ef), "idieresis"); - nameToUnicode.put("idieresis", new Character((char) 0x00ef)); - nameToEnc.put("idieresis", new Integer(239)); - encToName[239] = "idieresis"; - - unicodeToName.put(new Character((char) 0x00ec), "igrave"); - nameToUnicode.put("igrave", new Character((char) 0x00ec)); - nameToEnc.put("igrave", new Integer(236)); - encToName[236] = "igrave"; - - unicodeToName.put(new Character((char) 0x006a), "j"); - nameToUnicode.put("j", new Character((char) 0x006a)); - nameToEnc.put("j", new Integer(106)); - encToName[106] = "j"; - - unicodeToName.put(new Character((char) 0x006b), "k"); - nameToUnicode.put("k", new Character((char) 0x006b)); - nameToEnc.put("k", new Integer(107)); - encToName[107] = "k"; - - unicodeToName.put(new Character((char) 0x006c), "l"); - nameToUnicode.put("l", new Character((char) 0x006c)); - nameToEnc.put("l", new Integer(108)); - encToName[108] = "l"; - - unicodeToName.put(new Character((char) 0x003c), "less"); - nameToUnicode.put("less", new Character((char) 0x003c)); - nameToEnc.put("less", new Integer(60)); - encToName[60] = "less"; - - unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); - nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); - nameToEnc.put("logicalnot", new Integer(172)); - encToName[172] = "logicalnot"; - - unicodeToName.put(new Character((char) 0x0142), "lslash"); - nameToUnicode.put("lslash", new Character((char) 0x0142)); - - unicodeToName.put(new Character((char) 0x006d), "m"); - nameToUnicode.put("m", new Character((char) 0x006d)); - nameToEnc.put("m", new Integer(109)); - encToName[109] = "m"; - - unicodeToName.put(new Character((char) 0x00af), "macron"); - nameToUnicode.put("macron", new Character((char) 0x00af)); - nameToEnc.put("macron", new Integer(175)); - encToName[175] = "macron"; - - unicodeToName.put(new Character((char) 0x2212), "minus"); - nameToUnicode.put("minus", new Character((char) 0x2212)); - - unicodeToName.put(new Character((char) 0x03bc), "mu"); - nameToUnicode.put("mu", new Character((char) 0x03bc)); - nameToEnc.put("mu", new Integer(181)); - encToName[181] = "mu"; - - unicodeToName.put(new Character((char) 0x00d7), "multiply"); - nameToUnicode.put("multiply", new Character((char) 0x00d7)); - nameToEnc.put("multiply", new Integer(215)); - encToName[215] = "multiply"; - - unicodeToName.put(new Character((char) 0x006e), "n"); - nameToUnicode.put("n", new Character((char) 0x006e)); - nameToEnc.put("n", new Integer(110)); - encToName[110] = "n"; - - unicodeToName.put(new Character((char) 0x0039), "nine"); - nameToUnicode.put("nine", new Character((char) 0x0039)); - nameToEnc.put("nine", new Integer(57)); - encToName[57] = "nine"; - - unicodeToName.put(new Character((char) 0x00f1), "ntilde"); - nameToUnicode.put("ntilde", new Character((char) 0x00f1)); - nameToEnc.put("ntilde", new Integer(241)); - encToName[241] = "ntilde"; - - unicodeToName.put(new Character((char) 0x0023), "numbersign"); - nameToUnicode.put("numbersign", new Character((char) 0x0023)); - nameToEnc.put("numbersign", new Integer(35)); - encToName[35] = "numbersign"; - - unicodeToName.put(new Character((char) 0x006f), "o"); - nameToUnicode.put("o", new Character((char) 0x006f)); - nameToEnc.put("o", new Integer(111)); - encToName[111] = "o"; - - unicodeToName.put(new Character((char) 0x00f3), "oacute"); - nameToUnicode.put("oacute", new Character((char) 0x00f3)); - nameToEnc.put("oacute", new Integer(243)); - encToName[243] = "oacute"; - - unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); - nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); - nameToEnc.put("ocircumflex", new Integer(244)); - encToName[244] = "ocircumflex"; - - unicodeToName.put(new Character((char) 0x00f6), "odieresis"); - nameToUnicode.put("odieresis", new Character((char) 0x00f6)); - nameToEnc.put("odieresis", new Integer(246)); - encToName[246] = "odieresis"; - - unicodeToName.put(new Character((char) 0x0153), "oe"); - nameToUnicode.put("oe", new Character((char) 0x0153)); - nameToEnc.put("oe", new Integer(156)); - encToName[156] = "oe"; - - unicodeToName.put(new Character((char) 0x02db), "ogonek"); - nameToUnicode.put("ogonek", new Character((char) 0x02db)); - - unicodeToName.put(new Character((char) 0x00f2), "ograve"); - nameToUnicode.put("ograve", new Character((char) 0x00f2)); - nameToEnc.put("ograve", new Integer(242)); - encToName[242] = "ograve"; - - unicodeToName.put(new Character((char) 0x0031), "one"); - nameToUnicode.put("one", new Character((char) 0x0031)); - nameToEnc.put("one", new Integer(49)); - encToName[49] = "one"; - - unicodeToName.put(new Character((char) 0x00bd), "onehalf"); - nameToUnicode.put("onehalf", new Character((char) 0x00bd)); - nameToEnc.put("onehalf", new Integer(189)); - encToName[189] = "onehalf"; - - unicodeToName.put(new Character((char) 0x00bc), "onequarter"); - nameToUnicode.put("onequarter", new Character((char) 0x00bc)); - nameToEnc.put("onequarter", new Integer(188)); - encToName[188] = "onequarter"; - - unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); - nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); - nameToEnc.put("onesuperior", new Integer(185)); - encToName[185] = "onesuperior"; - - unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); - nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); - nameToEnc.put("ordfeminine", new Integer(170)); - encToName[170] = "ordfeminine"; - - unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); - nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); - nameToEnc.put("ordmasculine", new Integer(186)); - encToName[186] = "ordmasculine"; - - unicodeToName.put(new Character((char) 0x00f8), "oslash"); - nameToUnicode.put("oslash", new Character((char) 0x00f8)); - nameToEnc.put("oslash", new Integer(248)); - encToName[248] = "oslash"; - - unicodeToName.put(new Character((char) 0x00f5), "otilde"); - nameToUnicode.put("otilde", new Character((char) 0x00f5)); - nameToEnc.put("otilde", new Integer(245)); - encToName[245] = "otilde"; - - unicodeToName.put(new Character((char) 0x0070), "p"); - nameToUnicode.put("p", new Character((char) 0x0070)); - nameToEnc.put("p", new Integer(112)); - encToName[112] = "p"; - - unicodeToName.put(new Character((char) 0x00b6), "paragraph"); - nameToUnicode.put("paragraph", new Character((char) 0x00b6)); - nameToEnc.put("paragraph", new Integer(182)); - encToName[182] = "paragraph"; - - unicodeToName.put(new Character((char) 0x0028), "parenleft"); - nameToUnicode.put("parenleft", new Character((char) 0x0028)); - nameToEnc.put("parenleft", new Integer(40)); - encToName[40] = "parenleft"; - - unicodeToName.put(new Character((char) 0x0029), "parenright"); - nameToUnicode.put("parenright", new Character((char) 0x0029)); - nameToEnc.put("parenright", new Integer(41)); - encToName[41] = "parenright"; - - unicodeToName.put(new Character((char) 0x0025), "percent"); - nameToUnicode.put("percent", new Character((char) 0x0025)); - nameToEnc.put("percent", new Integer(37)); - encToName[37] = "percent"; - - unicodeToName.put(new Character((char) 0x002e), "period"); - nameToUnicode.put("period", new Character((char) 0x002e)); - nameToEnc.put("period", new Integer(46)); - encToName[46] = "period"; - - unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); - nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); - nameToEnc.put("periodcentered", new Integer(183)); - encToName[183] = "periodcentered"; - - unicodeToName.put(new Character((char) 0x2030), "perthousand"); - nameToUnicode.put("perthousand", new Character((char) 0x2030)); - nameToEnc.put("perthousand", new Integer(137)); - encToName[137] = "perthousand"; - - unicodeToName.put(new Character((char) 0x002b), "plus"); - nameToUnicode.put("plus", new Character((char) 0x002b)); - nameToEnc.put("plus", new Integer(43)); - encToName[43] = "plus"; - - unicodeToName.put(new Character((char) 0x00b1), "plusminus"); - nameToUnicode.put("plusminus", new Character((char) 0x00b1)); - nameToEnc.put("plusminus", new Integer(177)); - encToName[177] = "plusminus"; - - unicodeToName.put(new Character((char) 0x0071), "q"); - nameToUnicode.put("q", new Character((char) 0x0071)); - nameToEnc.put("q", new Integer(113)); - encToName[113] = "q"; - - unicodeToName.put(new Character((char) 0x003f), "question"); - nameToUnicode.put("question", new Character((char) 0x003f)); - nameToEnc.put("question", new Integer(63)); - encToName[63] = "question"; - - unicodeToName.put(new Character((char) 0x00bf), "questiondown"); - nameToUnicode.put("questiondown", new Character((char) 0x00bf)); - nameToEnc.put("questiondown", new Integer(191)); - encToName[191] = "questiondown"; - - unicodeToName.put(new Character((char) 0x0022), "quotedbl"); - nameToUnicode.put("quotedbl", new Character((char) 0x0022)); - nameToEnc.put("quotedbl", new Integer(34)); - encToName[34] = "quotedbl"; - - unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); - nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); - nameToEnc.put("quotedblbase", new Integer(132)); - encToName[132] = "quotedblbase"; - - unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); - nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); - nameToEnc.put("quotedblleft", new Integer(147)); - encToName[147] = "quotedblleft"; - - unicodeToName.put(new Character((char) 0x201d), "quotedblright"); - nameToUnicode.put("quotedblright", new Character((char) 0x201d)); - nameToEnc.put("quotedblright", new Integer(148)); - encToName[148] = "quotedblright"; - - unicodeToName.put(new Character((char) 0x0060), "quoteleft"); - nameToUnicode.put("quoteleft", new Character((char) 0x0060)); - nameToEnc.put("quoteleft", new Integer(145)); - encToName[145] = "quoteleft"; - - unicodeToName.put(new Character((char) 0x0027), "quoteright"); - nameToUnicode.put("quoteright", new Character((char) 0x0027)); - nameToEnc.put("quoteright", new Integer(146)); - encToName[146] = "quoteright"; - - unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); - nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); - nameToEnc.put("quotesinglbase", new Integer(130)); - encToName[130] = "quotesinglbase"; - - unicodeToName.put(new Character((char) 0x0027), "quotesingle"); - nameToUnicode.put("quotesingle", new Character((char) 0x0027)); - nameToEnc.put("quotesingle", new Integer(39)); - encToName[39] = "quotesingle"; - - unicodeToName.put(new Character((char) 0x0072), "r"); - nameToUnicode.put("r", new Character((char) 0x0072)); - nameToEnc.put("r", new Integer(114)); - encToName[114] = "r"; - - unicodeToName.put(new Character((char) 0x00ae), "registered"); - nameToUnicode.put("registered", new Character((char) 0x00ae)); - nameToEnc.put("registered", new Integer(174)); - encToName[174] = "registered"; - - unicodeToName.put(new Character((char) 0x02da), "ring"); - nameToUnicode.put("ring", new Character((char) 0x02da)); - - unicodeToName.put(new Character((char) 0x0073), "s"); - nameToUnicode.put("s", new Character((char) 0x0073)); - nameToEnc.put("s", new Integer(115)); - encToName[115] = "s"; - - unicodeToName.put(new Character((char) 0x0161), "scaron"); - nameToUnicode.put("scaron", new Character((char) 0x0161)); - nameToEnc.put("scaron", new Integer(154)); - encToName[154] = "scaron"; - - unicodeToName.put(new Character((char) 0x00a7), "section"); - nameToUnicode.put("section", new Character((char) 0x00a7)); - nameToEnc.put("section", new Integer(167)); - encToName[167] = "section"; - - unicodeToName.put(new Character((char) 0x003b), "semicolon"); - nameToUnicode.put("semicolon", new Character((char) 0x003b)); - nameToEnc.put("semicolon", new Integer(59)); - encToName[59] = "semicolon"; - - unicodeToName.put(new Character((char) 0x0037), "seven"); - nameToUnicode.put("seven", new Character((char) 0x0037)); - nameToEnc.put("seven", new Integer(55)); - encToName[55] = "seven"; - - unicodeToName.put(new Character((char) 0x0036), "six"); - nameToUnicode.put("six", new Character((char) 0x0036)); - nameToEnc.put("six", new Integer(54)); - encToName[54] = "six"; - - unicodeToName.put(new Character((char) 0x002f), "slash"); - nameToUnicode.put("slash", new Character((char) 0x002f)); - nameToEnc.put("slash", new Integer(47)); - encToName[47] = "slash"; - - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x00a3), "sterling"); - nameToUnicode.put("sterling", new Character((char) 0x00a3)); - nameToEnc.put("sterling", new Integer(163)); - encToName[163] = "sterling"; - - unicodeToName.put(new Character((char) 0x0074), "t"); - nameToUnicode.put("t", new Character((char) 0x0074)); - nameToEnc.put("t", new Integer(116)); - encToName[116] = "t"; - - unicodeToName.put(new Character((char) 0x00fe), "thorn"); - nameToUnicode.put("thorn", new Character((char) 0x00fe)); - nameToEnc.put("thorn", new Integer(254)); - encToName[254] = "thorn"; - - unicodeToName.put(new Character((char) 0x0033), "three"); - nameToUnicode.put("three", new Character((char) 0x0033)); - nameToEnc.put("three", new Integer(51)); - encToName[51] = "three"; - - unicodeToName.put(new Character((char) 0x00be), "threequarters"); - nameToUnicode.put("threequarters", new Character((char) 0x00be)); - nameToEnc.put("threequarters", new Integer(190)); - encToName[190] = "threequarters"; - - unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); - nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); - nameToEnc.put("threesuperior", new Integer(179)); - encToName[179] = "threesuperior"; - - unicodeToName.put(new Character((char) 0x02dc), "tilde"); - nameToUnicode.put("tilde", new Character((char) 0x02dc)); - nameToEnc.put("tilde", new Integer(152)); - encToName[152] = "tilde"; - - unicodeToName.put(new Character((char) 0x2122), "trademark"); - nameToUnicode.put("trademark", new Character((char) 0x2122)); - nameToEnc.put("trademark", new Integer(153)); - encToName[153] = "trademark"; - - unicodeToName.put(new Character((char) 0x0032), "two"); - nameToUnicode.put("two", new Character((char) 0x0032)); - nameToEnc.put("two", new Integer(50)); - encToName[50] = "two"; - - unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); - nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); - nameToEnc.put("twosuperior", new Integer(178)); - encToName[178] = "twosuperior"; - - unicodeToName.put(new Character((char) 0x0075), "u"); - nameToUnicode.put("u", new Character((char) 0x0075)); - nameToEnc.put("u", new Integer(117)); - encToName[117] = "u"; - - unicodeToName.put(new Character((char) 0x00fa), "uacute"); - nameToUnicode.put("uacute", new Character((char) 0x00fa)); - nameToEnc.put("uacute", new Integer(250)); - encToName[250] = "uacute"; - - unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); - nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); - nameToEnc.put("ucircumflex", new Integer(251)); - encToName[251] = "ucircumflex"; - - unicodeToName.put(new Character((char) 0x00fc), "udieresis"); - nameToUnicode.put("udieresis", new Character((char) 0x00fc)); - nameToEnc.put("udieresis", new Integer(252)); - encToName[252] = "udieresis"; - - unicodeToName.put(new Character((char) 0x00f9), "ugrave"); - nameToUnicode.put("ugrave", new Character((char) 0x00f9)); - nameToEnc.put("ugrave", new Integer(249)); - encToName[249] = "ugrave"; - - unicodeToName.put(new Character((char) 0x005f), "underscore"); - nameToUnicode.put("underscore", new Character((char) 0x005f)); - nameToEnc.put("underscore", new Integer(95)); - encToName[95] = "underscore"; - - unicodeToName.put(new Character((char) 0x0076), "v"); - nameToUnicode.put("v", new Character((char) 0x0076)); - nameToEnc.put("v", new Integer(118)); - encToName[118] = "v"; - - unicodeToName.put(new Character((char) 0x0077), "w"); - nameToUnicode.put("w", new Character((char) 0x0077)); - nameToEnc.put("w", new Integer(119)); - encToName[119] = "w"; - - unicodeToName.put(new Character((char) 0x0078), "x"); - nameToUnicode.put("x", new Character((char) 0x0078)); - nameToEnc.put("x", new Integer(120)); - encToName[120] = "x"; - - unicodeToName.put(new Character((char) 0x0079), "y"); - nameToUnicode.put("y", new Character((char) 0x0079)); - nameToEnc.put("y", new Integer(121)); - encToName[121] = "y"; - - unicodeToName.put(new Character((char) 0x00fd), "yacute"); - nameToUnicode.put("yacute", new Character((char) 0x00fd)); - nameToEnc.put("yacute", new Integer(253)); - encToName[253] = "yacute"; - - unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); - nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); - nameToEnc.put("ydieresis", new Integer(255)); - encToName[255] = "ydieresis"; - - unicodeToName.put(new Character((char) 0x00a5), "yen"); - nameToUnicode.put("yen", new Character((char) 0x00a5)); - nameToEnc.put("yen", new Integer(165)); - encToName[165] = "yen"; - - unicodeToName.put(new Character((char) 0x007a), "z"); - nameToUnicode.put("z", new Character((char) 0x007a)); - nameToEnc.put("z", new Integer(122)); - encToName[122] = "z"; - - unicodeToName.put(new Character((char) 0x017e), "zcaron"); - nameToUnicode.put("zcaron", new Character((char) 0x017e)); - nameToEnc.put("zcaron", new Integer(158)); - encToName[158] = "zcaron"; - - unicodeToName.put(new Character((char) 0x0030), "zero"); - nameToUnicode.put("zero", new Character((char) 0x0030)); - nameToEnc.put("zero", new Integer(48)); - encToName[48] = "zero"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Latin");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("WIN");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated WINLatin Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class WINLatin extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public WINLatin() { + unicodeToName.put(new Character((char) 0x0041), "A"); + nameToUnicode.put("A", new Character((char) 0x0041)); + nameToEnc.put("A", new Integer(65)); + encToName[65] = "A"; + + unicodeToName.put(new Character((char) 0x00c6), "AE"); + nameToUnicode.put("AE", new Character((char) 0x00c6)); + nameToEnc.put("AE", new Integer(198)); + encToName[198] = "AE"; + + unicodeToName.put(new Character((char) 0x00c1), "Aacute"); + nameToUnicode.put("Aacute", new Character((char) 0x00c1)); + nameToEnc.put("Aacute", new Integer(193)); + encToName[193] = "Aacute"; + + unicodeToName.put(new Character((char) 0x00c2), "Acircumflex"); + nameToUnicode.put("Acircumflex", new Character((char) 0x00c2)); + nameToEnc.put("Acircumflex", new Integer(194)); + encToName[194] = "Acircumflex"; + + unicodeToName.put(new Character((char) 0x00c4), "Adieresis"); + nameToUnicode.put("Adieresis", new Character((char) 0x00c4)); + nameToEnc.put("Adieresis", new Integer(196)); + encToName[196] = "Adieresis"; + + unicodeToName.put(new Character((char) 0x00c0), "Agrave"); + nameToUnicode.put("Agrave", new Character((char) 0x00c0)); + nameToEnc.put("Agrave", new Integer(192)); + encToName[192] = "Agrave"; + + unicodeToName.put(new Character((char) 0x00c5), "Aring"); + nameToUnicode.put("Aring", new Character((char) 0x00c5)); + nameToEnc.put("Aring", new Integer(197)); + encToName[197] = "Aring"; + + unicodeToName.put(new Character((char) 0x00c3), "Atilde"); + nameToUnicode.put("Atilde", new Character((char) 0x00c3)); + nameToEnc.put("Atilde", new Integer(195)); + encToName[195] = "Atilde"; + + unicodeToName.put(new Character((char) 0x0042), "B"); + nameToUnicode.put("B", new Character((char) 0x0042)); + nameToEnc.put("B", new Integer(66)); + encToName[66] = "B"; + + unicodeToName.put(new Character((char) 0x0043), "C"); + nameToUnicode.put("C", new Character((char) 0x0043)); + nameToEnc.put("C", new Integer(67)); + encToName[67] = "C"; + + unicodeToName.put(new Character((char) 0x00c7), "Ccedilla"); + nameToUnicode.put("Ccedilla", new Character((char) 0x00c7)); + nameToEnc.put("Ccedilla", new Integer(199)); + encToName[199] = "Ccedilla"; + + unicodeToName.put(new Character((char) 0x0044), "D"); + nameToUnicode.put("D", new Character((char) 0x0044)); + nameToEnc.put("D", new Integer(68)); + encToName[68] = "D"; + + unicodeToName.put(new Character((char) 0x0045), "E"); + nameToUnicode.put("E", new Character((char) 0x0045)); + nameToEnc.put("E", new Integer(69)); + encToName[69] = "E"; + + unicodeToName.put(new Character((char) 0x00c9), "Eacute"); + nameToUnicode.put("Eacute", new Character((char) 0x00c9)); + nameToEnc.put("Eacute", new Integer(201)); + encToName[201] = "Eacute"; + + unicodeToName.put(new Character((char) 0x00ca), "Ecircumflex"); + nameToUnicode.put("Ecircumflex", new Character((char) 0x00ca)); + nameToEnc.put("Ecircumflex", new Integer(202)); + encToName[202] = "Ecircumflex"; + + unicodeToName.put(new Character((char) 0x00cb), "Edieresis"); + nameToUnicode.put("Edieresis", new Character((char) 0x00cb)); + nameToEnc.put("Edieresis", new Integer(203)); + encToName[203] = "Edieresis"; + + unicodeToName.put(new Character((char) 0x00c8), "Egrave"); + nameToUnicode.put("Egrave", new Character((char) 0x00c8)); + nameToEnc.put("Egrave", new Integer(200)); + encToName[200] = "Egrave"; + + unicodeToName.put(new Character((char) 0x00d0), "Eth"); + nameToUnicode.put("Eth", new Character((char) 0x00d0)); + nameToEnc.put("Eth", new Integer(208)); + encToName[208] = "Eth"; + + unicodeToName.put(new Character((char) 0x20ac), "Euro"); + nameToUnicode.put("Euro", new Character((char) 0x20ac)); + nameToEnc.put("Euro", new Integer(128)); + encToName[128] = "Euro"; + + unicodeToName.put(new Character((char) 0x0046), "F"); + nameToUnicode.put("F", new Character((char) 0x0046)); + nameToEnc.put("F", new Integer(70)); + encToName[70] = "F"; + + unicodeToName.put(new Character((char) 0x0047), "G"); + nameToUnicode.put("G", new Character((char) 0x0047)); + nameToEnc.put("G", new Integer(71)); + encToName[71] = "G"; + + unicodeToName.put(new Character((char) 0x0048), "H"); + nameToUnicode.put("H", new Character((char) 0x0048)); + nameToEnc.put("H", new Integer(72)); + encToName[72] = "H"; + + unicodeToName.put(new Character((char) 0x0049), "I"); + nameToUnicode.put("I", new Character((char) 0x0049)); + nameToEnc.put("I", new Integer(73)); + encToName[73] = "I"; + + unicodeToName.put(new Character((char) 0x00cd), "Iacute"); + nameToUnicode.put("Iacute", new Character((char) 0x00cd)); + nameToEnc.put("Iacute", new Integer(205)); + encToName[205] = "Iacute"; + + unicodeToName.put(new Character((char) 0x00ce), "Icircumflex"); + nameToUnicode.put("Icircumflex", new Character((char) 0x00ce)); + nameToEnc.put("Icircumflex", new Integer(206)); + encToName[206] = "Icircumflex"; + + unicodeToName.put(new Character((char) 0x00cf), "Idieresis"); + nameToUnicode.put("Idieresis", new Character((char) 0x00cf)); + nameToEnc.put("Idieresis", new Integer(207)); + encToName[207] = "Idieresis"; + + unicodeToName.put(new Character((char) 0x00cc), "Igrave"); + nameToUnicode.put("Igrave", new Character((char) 0x00cc)); + nameToEnc.put("Igrave", new Integer(204)); + encToName[204] = "Igrave"; + + unicodeToName.put(new Character((char) 0x004a), "J"); + nameToUnicode.put("J", new Character((char) 0x004a)); + nameToEnc.put("J", new Integer(74)); + encToName[74] = "J"; + + unicodeToName.put(new Character((char) 0x004b), "K"); + nameToUnicode.put("K", new Character((char) 0x004b)); + nameToEnc.put("K", new Integer(75)); + encToName[75] = "K"; + + unicodeToName.put(new Character((char) 0x004c), "L"); + nameToUnicode.put("L", new Character((char) 0x004c)); + nameToEnc.put("L", new Integer(76)); + encToName[76] = "L"; + + unicodeToName.put(new Character((char) 0x0141), "Lslash"); + nameToUnicode.put("Lslash", new Character((char) 0x0141)); + + unicodeToName.put(new Character((char) 0x004d), "M"); + nameToUnicode.put("M", new Character((char) 0x004d)); + nameToEnc.put("M", new Integer(77)); + encToName[77] = "M"; + + unicodeToName.put(new Character((char) 0x004e), "N"); + nameToUnicode.put("N", new Character((char) 0x004e)); + nameToEnc.put("N", new Integer(78)); + encToName[78] = "N"; + + unicodeToName.put(new Character((char) 0x00d1), "Ntilde"); + nameToUnicode.put("Ntilde", new Character((char) 0x00d1)); + nameToEnc.put("Ntilde", new Integer(209)); + encToName[209] = "Ntilde"; + + unicodeToName.put(new Character((char) 0x004f), "O"); + nameToUnicode.put("O", new Character((char) 0x004f)); + nameToEnc.put("O", new Integer(79)); + encToName[79] = "O"; + + unicodeToName.put(new Character((char) 0x0152), "OE"); + nameToUnicode.put("OE", new Character((char) 0x0152)); + nameToEnc.put("OE", new Integer(140)); + encToName[140] = "OE"; + + unicodeToName.put(new Character((char) 0x00d2), "Oacute"); + nameToUnicode.put("Oacute", new Character((char) 0x00d2)); + nameToEnc.put("Oacute", new Integer(211)); + encToName[211] = "Oacute"; + + unicodeToName.put(new Character((char) 0x00d4), "Ocircumflex"); + nameToUnicode.put("Ocircumflex", new Character((char) 0x00d4)); + nameToEnc.put("Ocircumflex", new Integer(212)); + encToName[212] = "Ocircumflex"; + + unicodeToName.put(new Character((char) 0x00d6), "Odieresis"); + nameToUnicode.put("Odieresis", new Character((char) 0x00d6)); + nameToEnc.put("Odieresis", new Integer(214)); + encToName[214] = "Odieresis"; + + unicodeToName.put(new Character((char) 0x00d3), "Ograve"); + nameToUnicode.put("Ograve", new Character((char) 0x00d3)); + nameToEnc.put("Ograve", new Integer(210)); + encToName[210] = "Ograve"; + + unicodeToName.put(new Character((char) 0x00d8), "Oslash"); + nameToUnicode.put("Oslash", new Character((char) 0x00d8)); + nameToEnc.put("Oslash", new Integer(216)); + encToName[216] = "Oslash"; + + unicodeToName.put(new Character((char) 0x00d5), "Otilde"); + nameToUnicode.put("Otilde", new Character((char) 0x00d5)); + nameToEnc.put("Otilde", new Integer(213)); + encToName[213] = "Otilde"; + + unicodeToName.put(new Character((char) 0x0050), "P"); + nameToUnicode.put("P", new Character((char) 0x0050)); + nameToEnc.put("P", new Integer(80)); + encToName[80] = "P"; + + unicodeToName.put(new Character((char) 0x0051), "Q"); + nameToUnicode.put("Q", new Character((char) 0x0051)); + nameToEnc.put("Q", new Integer(81)); + encToName[81] = "Q"; + + unicodeToName.put(new Character((char) 0x0052), "R"); + nameToUnicode.put("R", new Character((char) 0x0052)); + nameToEnc.put("R", new Integer(82)); + encToName[82] = "R"; + + unicodeToName.put(new Character((char) 0x0053), "S"); + nameToUnicode.put("S", new Character((char) 0x0053)); + nameToEnc.put("S", new Integer(83)); + encToName[83] = "S"; + + unicodeToName.put(new Character((char) 0x0160), "Scaron"); + nameToUnicode.put("Scaron", new Character((char) 0x0160)); + nameToEnc.put("Scaron", new Integer(138)); + encToName[138] = "Scaron"; + + unicodeToName.put(new Character((char) 0x0054), "T"); + nameToUnicode.put("T", new Character((char) 0x0054)); + nameToEnc.put("T", new Integer(84)); + encToName[84] = "T"; + + unicodeToName.put(new Character((char) 0x00de), "Thorn"); + nameToUnicode.put("Thorn", new Character((char) 0x00de)); + nameToEnc.put("Thorn", new Integer(222)); + encToName[222] = "Thorn"; + + unicodeToName.put(new Character((char) 0x0055), "U"); + nameToUnicode.put("U", new Character((char) 0x0055)); + nameToEnc.put("U", new Integer(85)); + encToName[85] = "U"; + + unicodeToName.put(new Character((char) 0x00da), "Uacute"); + nameToUnicode.put("Uacute", new Character((char) 0x00da)); + nameToEnc.put("Uacute", new Integer(218)); + encToName[218] = "Uacute"; + + unicodeToName.put(new Character((char) 0x00db), "Ucircumflex"); + nameToUnicode.put("Ucircumflex", new Character((char) 0x00db)); + nameToEnc.put("Ucircumflex", new Integer(219)); + encToName[219] = "Ucircumflex"; + + unicodeToName.put(new Character((char) 0x00dc), "Udieresis"); + nameToUnicode.put("Udieresis", new Character((char) 0x00dc)); + nameToEnc.put("Udieresis", new Integer(220)); + encToName[220] = "Udieresis"; + + unicodeToName.put(new Character((char) 0x00d9), "Ugrave"); + nameToUnicode.put("Ugrave", new Character((char) 0x00d9)); + nameToEnc.put("Ugrave", new Integer(217)); + encToName[217] = "Ugrave"; + + unicodeToName.put(new Character((char) 0x0056), "V"); + nameToUnicode.put("V", new Character((char) 0x0056)); + nameToEnc.put("V", new Integer(86)); + encToName[86] = "V"; + + unicodeToName.put(new Character((char) 0x0057), "W"); + nameToUnicode.put("W", new Character((char) 0x0057)); + nameToEnc.put("W", new Integer(87)); + encToName[87] = "W"; + + unicodeToName.put(new Character((char) 0x0058), "X"); + nameToUnicode.put("X", new Character((char) 0x0058)); + nameToEnc.put("X", new Integer(88)); + encToName[88] = "X"; + + unicodeToName.put(new Character((char) 0x0059), "Y"); + nameToUnicode.put("Y", new Character((char) 0x0059)); + nameToEnc.put("Y", new Integer(89)); + encToName[89] = "Y"; + + unicodeToName.put(new Character((char) 0x00dd), "Yacute"); + nameToUnicode.put("Yacute", new Character((char) 0x00dd)); + nameToEnc.put("Yacute", new Integer(221)); + encToName[221] = "Yacute"; + + unicodeToName.put(new Character((char) 0x0178), "Ydieresis"); + nameToUnicode.put("Ydieresis", new Character((char) 0x0178)); + nameToEnc.put("Ydieresis", new Integer(159)); + encToName[159] = "Ydieresis"; + + unicodeToName.put(new Character((char) 0x005a), "Z"); + nameToUnicode.put("Z", new Character((char) 0x005a)); + nameToEnc.put("Z", new Integer(90)); + encToName[90] = "Z"; + + unicodeToName.put(new Character((char) 0x017d), "Zcaron"); + nameToUnicode.put("Zcaron", new Character((char) 0x017d)); + nameToEnc.put("Zcaron", new Integer(142)); + encToName[142] = "Zcaron"; + + unicodeToName.put(new Character((char) 0x0061), "a"); + nameToUnicode.put("a", new Character((char) 0x0061)); + nameToEnc.put("a", new Integer(97)); + encToName[97] = "a"; + + unicodeToName.put(new Character((char) 0x00e1), "aacute"); + nameToUnicode.put("aacute", new Character((char) 0x00e1)); + nameToEnc.put("aacute", new Integer(225)); + encToName[225] = "aacute"; + + unicodeToName.put(new Character((char) 0x00e2), "acircumflex"); + nameToUnicode.put("acircumflex", new Character((char) 0x00e2)); + nameToEnc.put("acircumflex", new Integer(226)); + encToName[226] = "acircumflex"; + + unicodeToName.put(new Character((char) 0x00b4), "acute"); + nameToUnicode.put("acute", new Character((char) 0x00b4)); + nameToEnc.put("acute", new Integer(180)); + encToName[180] = "acute"; + + unicodeToName.put(new Character((char) 0x00e4), "adieresis"); + nameToUnicode.put("adieresis", new Character((char) 0x00e4)); + nameToEnc.put("adieresis", new Integer(228)); + encToName[228] = "adieresis"; + + unicodeToName.put(new Character((char) 0x00e6), "ae"); + nameToUnicode.put("ae", new Character((char) 0x00e6)); + nameToEnc.put("ae", new Integer(230)); + encToName[230] = "ae"; + + unicodeToName.put(new Character((char) 0x00e0), "agrave"); + nameToUnicode.put("agrave", new Character((char) 0x00e0)); + nameToEnc.put("agrave", new Integer(224)); + encToName[224] = "agrave"; + + unicodeToName.put(new Character((char) 0x0026), "ampersand"); + nameToUnicode.put("ampersand", new Character((char) 0x0026)); + nameToEnc.put("ampersand", new Integer(38)); + encToName[38] = "ampersand"; + + unicodeToName.put(new Character((char) 0x00e5), "aring"); + nameToUnicode.put("aring", new Character((char) 0x00e5)); + nameToEnc.put("aring", new Integer(229)); + encToName[229] = "aring"; + + unicodeToName.put(new Character((char) 0x005e), "asciicircum"); + nameToUnicode.put("asciicircum", new Character((char) 0x005e)); + nameToEnc.put("asciicircum", new Integer(94)); + encToName[94] = "asciicircum"; + + unicodeToName.put(new Character((char) 0x007e), "asciitilde"); + nameToUnicode.put("asciitilde", new Character((char) 0x007e)); + nameToEnc.put("asciitilde", new Integer(126)); + encToName[126] = "asciitilde"; + + unicodeToName.put(new Character((char) 0x002a), "asterisk"); + nameToUnicode.put("asterisk", new Character((char) 0x002a)); + nameToEnc.put("asterisk", new Integer(42)); + encToName[42] = "asterisk"; + + unicodeToName.put(new Character((char) 0x0040), "at"); + nameToUnicode.put("at", new Character((char) 0x0040)); + nameToEnc.put("at", new Integer(64)); + encToName[64] = "at"; + + unicodeToName.put(new Character((char) 0x00e3), "atilde"); + nameToUnicode.put("atilde", new Character((char) 0x00e3)); + nameToEnc.put("atilde", new Integer(227)); + encToName[227] = "atilde"; + + unicodeToName.put(new Character((char) 0x0062), "b"); + nameToUnicode.put("b", new Character((char) 0x0062)); + nameToEnc.put("b", new Integer(98)); + encToName[98] = "b"; + + unicodeToName.put(new Character((char) 0x005c), "backslash"); + nameToUnicode.put("backslash", new Character((char) 0x005c)); + nameToEnc.put("backslash", new Integer(92)); + encToName[92] = "backslash"; + + unicodeToName.put(new Character((char) 0x007c), "bar"); + nameToUnicode.put("bar", new Character((char) 0x007c)); + nameToEnc.put("bar", new Integer(124)); + encToName[124] = "bar"; + + unicodeToName.put(new Character((char) 0x007b), "braceleft"); + nameToUnicode.put("braceleft", new Character((char) 0x007b)); + nameToEnc.put("braceleft", new Integer(123)); + encToName[123] = "braceleft"; + + unicodeToName.put(new Character((char) 0x007d), "braceright"); + nameToUnicode.put("braceright", new Character((char) 0x007d)); + nameToEnc.put("braceright", new Integer(125)); + encToName[125] = "braceright"; + + unicodeToName.put(new Character((char) 0x005b), "bracketleft"); + nameToUnicode.put("bracketleft", new Character((char) 0x005b)); + nameToEnc.put("bracketleft", new Integer(91)); + encToName[91] = "bracketleft"; + + unicodeToName.put(new Character((char) 0x005d), "bracketright"); + nameToUnicode.put("bracketright", new Character((char) 0x005d)); + nameToEnc.put("bracketright", new Integer(93)); + encToName[93] = "bracketright"; + + unicodeToName.put(new Character((char) 0x02d8), "breve"); + nameToUnicode.put("breve", new Character((char) 0x02d8)); + + unicodeToName.put(new Character((char) 0x00a6), "brokenbar"); + nameToUnicode.put("brokenbar", new Character((char) 0x00a6)); + nameToEnc.put("brokenbar", new Integer(166)); + encToName[166] = "brokenbar"; + + unicodeToName.put(new Character((char) 0x2022), "bullet"); + nameToUnicode.put("bullet", new Character((char) 0x2022)); + nameToEnc.put("bullet", new Integer(149)); + encToName[149] = "bullet"; + + unicodeToName.put(new Character((char) 0x0063), "c"); + nameToUnicode.put("c", new Character((char) 0x0063)); + nameToEnc.put("c", new Integer(99)); + encToName[99] = "c"; + + unicodeToName.put(new Character((char) 0x02c7), "caron"); + nameToUnicode.put("caron", new Character((char) 0x02c7)); + + unicodeToName.put(new Character((char) 0x00e7), "ccedilla"); + nameToUnicode.put("ccedilla", new Character((char) 0x00e7)); + nameToEnc.put("ccedilla", new Integer(231)); + encToName[231] = "ccedilla"; + + unicodeToName.put(new Character((char) 0x00b8), "cedilla"); + nameToUnicode.put("cedilla", new Character((char) 0x00b8)); + nameToEnc.put("cedilla", new Integer(184)); + encToName[184] = "cedilla"; + + unicodeToName.put(new Character((char) 0x00a2), "cent"); + nameToUnicode.put("cent", new Character((char) 0x00a2)); + nameToEnc.put("cent", new Integer(162)); + encToName[162] = "cent"; + + unicodeToName.put(new Character((char) 0x02c6), "circumflex"); + nameToUnicode.put("circumflex", new Character((char) 0x02c6)); + nameToEnc.put("circumflex", new Integer(136)); + encToName[136] = "circumflex"; + + unicodeToName.put(new Character((char) 0x003a), "colon"); + nameToUnicode.put("colon", new Character((char) 0x003a)); + nameToEnc.put("colon", new Integer(58)); + encToName[58] = "colon"; + + unicodeToName.put(new Character((char) 0x002c), "comma"); + nameToUnicode.put("comma", new Character((char) 0x002c)); + nameToEnc.put("comma", new Integer(44)); + encToName[44] = "comma"; + + unicodeToName.put(new Character((char) 0x00a9), "copyright"); + nameToUnicode.put("copyright", new Character((char) 0x00a9)); + nameToEnc.put("copyright", new Integer(169)); + encToName[169] = "copyright"; + + unicodeToName.put(new Character((char) 0x00a4), "currency"); + nameToUnicode.put("currency", new Character((char) 0x00a4)); + nameToEnc.put("currency", new Integer(164)); + encToName[164] = "currency"; + + unicodeToName.put(new Character((char) 0x0064), "d"); + nameToUnicode.put("d", new Character((char) 0x0064)); + nameToEnc.put("d", new Integer(100)); + encToName[100] = "d"; + + unicodeToName.put(new Character((char) 0x2020), "dagger"); + nameToUnicode.put("dagger", new Character((char) 0x2020)); + nameToEnc.put("dagger", new Integer(134)); + encToName[134] = "dagger"; + + unicodeToName.put(new Character((char) 0x2021), "daggerdbl"); + nameToUnicode.put("daggerdbl", new Character((char) 0x2021)); + nameToEnc.put("daggerdbl", new Integer(135)); + encToName[135] = "daggerdbl"; + + unicodeToName.put(new Character((char) 0x00b0), "degree"); + nameToUnicode.put("degree", new Character((char) 0x00b0)); + nameToEnc.put("degree", new Integer(176)); + encToName[176] = "degree"; + + unicodeToName.put(new Character((char) 0x00a8), "dieresis"); + nameToUnicode.put("dieresis", new Character((char) 0x00a8)); + nameToEnc.put("dieresis", new Integer(168)); + encToName[168] = "dieresis"; + + unicodeToName.put(new Character((char) 0x00f7), "divide"); + nameToUnicode.put("divide", new Character((char) 0x00f7)); + nameToEnc.put("divide", new Integer(247)); + encToName[247] = "divide"; + + unicodeToName.put(new Character((char) 0x0024), "dollar"); + nameToUnicode.put("dollar", new Character((char) 0x0024)); + nameToEnc.put("dollar", new Integer(36)); + encToName[36] = "dollar"; + + unicodeToName.put(new Character((char) 0x02d9), "dotaccent"); + nameToUnicode.put("dotaccent", new Character((char) 0x02d9)); + + unicodeToName.put(new Character((char) 0x0131), "dotlessi"); + nameToUnicode.put("dotlessi", new Character((char) 0x0131)); + + unicodeToName.put(new Character((char) 0x0065), "e"); + nameToUnicode.put("e", new Character((char) 0x0065)); + nameToEnc.put("e", new Integer(101)); + encToName[101] = "e"; + + unicodeToName.put(new Character((char) 0x00e9), "eacute"); + nameToUnicode.put("eacute", new Character((char) 0x00e9)); + nameToEnc.put("eacute", new Integer(233)); + encToName[233] = "eacute"; + + unicodeToName.put(new Character((char) 0x00ea), "ecircumflex"); + nameToUnicode.put("ecircumflex", new Character((char) 0x00ea)); + nameToEnc.put("ecircumflex", new Integer(234)); + encToName[234] = "ecircumflex"; + + unicodeToName.put(new Character((char) 0x00eb), "edieresis"); + nameToUnicode.put("edieresis", new Character((char) 0x00eb)); + nameToEnc.put("edieresis", new Integer(235)); + encToName[235] = "edieresis"; + + unicodeToName.put(new Character((char) 0x00e8), "egrave"); + nameToUnicode.put("egrave", new Character((char) 0x00e8)); + nameToEnc.put("egrave", new Integer(232)); + encToName[232] = "egrave"; + + unicodeToName.put(new Character((char) 0x0038), "eight"); + nameToUnicode.put("eight", new Character((char) 0x0038)); + nameToEnc.put("eight", new Integer(56)); + encToName[56] = "eight"; + + unicodeToName.put(new Character((char) 0x2026), "ellipsis"); + nameToUnicode.put("ellipsis", new Character((char) 0x2026)); + nameToEnc.put("ellipsis", new Integer(133)); + encToName[133] = "ellipsis"; + + unicodeToName.put(new Character((char) 0x002d), "emdash"); + nameToUnicode.put("emdash", new Character((char) 0x002d)); + nameToEnc.put("emdash", new Integer(151)); + encToName[151] = "emdash"; + + unicodeToName.put(new Character((char) 0x002d), "endash"); + nameToUnicode.put("endash", new Character((char) 0x002d)); + nameToEnc.put("endash", new Integer(150)); + encToName[150] = "endash"; + + unicodeToName.put(new Character((char) 0x003d), "equal"); + nameToUnicode.put("equal", new Character((char) 0x003d)); + nameToEnc.put("equal", new Integer(61)); + encToName[61] = "equal"; + + unicodeToName.put(new Character((char) 0x00f0), "eth"); + nameToUnicode.put("eth", new Character((char) 0x00f0)); + nameToEnc.put("eth", new Integer(240)); + encToName[240] = "eth"; + + unicodeToName.put(new Character((char) 0x0021), "exclam"); + nameToUnicode.put("exclam", new Character((char) 0x0021)); + nameToEnc.put("exclam", new Integer(33)); + encToName[33] = "exclam"; + + unicodeToName.put(new Character((char) 0x00a1), "exclamdown"); + nameToUnicode.put("exclamdown", new Character((char) 0x00a1)); + nameToEnc.put("exclamdown", new Integer(161)); + encToName[161] = "exclamdown"; + + unicodeToName.put(new Character((char) 0x0066), "f"); + nameToUnicode.put("f", new Character((char) 0x0066)); + nameToEnc.put("f", new Integer(102)); + encToName[102] = "f"; + + unicodeToName.put(new Character((char) 0xfb01), "fi"); + nameToUnicode.put("fi", new Character((char) 0xfb01)); + + unicodeToName.put(new Character((char) 0x0035), "five"); + nameToUnicode.put("five", new Character((char) 0x0035)); + nameToEnc.put("five", new Integer(53)); + encToName[53] = "five"; + + unicodeToName.put(new Character((char) 0xfb02), "fl"); + nameToUnicode.put("fl", new Character((char) 0xfb02)); + + unicodeToName.put(new Character((char) 0x0192), "florin"); + nameToUnicode.put("florin", new Character((char) 0x0192)); + nameToEnc.put("florin", new Integer(131)); + encToName[131] = "florin"; + + unicodeToName.put(new Character((char) 0x0034), "four"); + nameToUnicode.put("four", new Character((char) 0x0034)); + nameToEnc.put("four", new Integer(52)); + encToName[52] = "four"; + + unicodeToName.put(new Character((char) 0x2044), "fraction"); + nameToUnicode.put("fraction", new Character((char) 0x2044)); + + unicodeToName.put(new Character((char) 0x0067), "g"); + nameToUnicode.put("g", new Character((char) 0x0067)); + nameToEnc.put("g", new Integer(103)); + encToName[103] = "g"; + + unicodeToName.put(new Character((char) 0x00df), "germandbls"); + nameToUnicode.put("germandbls", new Character((char) 0x00df)); + nameToEnc.put("germandbls", new Integer(223)); + encToName[223] = "germandbls"; + + unicodeToName.put(new Character((char) 0x0060), "grave"); + nameToUnicode.put("grave", new Character((char) 0x0060)); + nameToEnc.put("grave", new Integer(96)); + encToName[96] = "grave"; + + unicodeToName.put(new Character((char) 0x003e), "greater"); + nameToUnicode.put("greater", new Character((char) 0x003e)); + nameToEnc.put("greater", new Integer(62)); + encToName[62] = "greater"; + + unicodeToName.put(new Character((char) 0x00ab), "guillemotleft"); + nameToUnicode.put("guillemotleft", new Character((char) 0x00ab)); + nameToEnc.put("guillemotleft", new Integer(171)); + encToName[171] = "guillemotleft"; + + unicodeToName.put(new Character((char) 0x00bb), "guillemotright"); + nameToUnicode.put("guillemotright", new Character((char) 0x00bb)); + nameToEnc.put("guillemotright", new Integer(187)); + encToName[187] = "guillemotright"; + + unicodeToName.put(new Character((char) 0x2039), "guilsinglleft"); + nameToUnicode.put("guilsinglleft", new Character((char) 0x2039)); + nameToEnc.put("guilsinglleft", new Integer(139)); + encToName[139] = "guilsinglleft"; + + unicodeToName.put(new Character((char) 0x203a), "guilsinglright"); + nameToUnicode.put("guilsinglright", new Character((char) 0x203a)); + nameToEnc.put("guilsinglright", new Integer(155)); + encToName[155] = "guilsinglright"; + + unicodeToName.put(new Character((char) 0x0068), "h"); + nameToUnicode.put("h", new Character((char) 0x0068)); + nameToEnc.put("h", new Integer(104)); + encToName[104] = "h"; + + unicodeToName.put(new Character((char) 0x02ba), "hungarumlaut"); + nameToUnicode.put("hungarumlaut", new Character((char) 0x02ba)); + + unicodeToName.put(new Character((char) 0x002d), "hyphen"); + nameToUnicode.put("hyphen", new Character((char) 0x002d)); + nameToEnc.put("hyphen", new Integer(45)); + encToName[45] = "hyphen"; + + unicodeToName.put(new Character((char) 0x0069), "i"); + nameToUnicode.put("i", new Character((char) 0x0069)); + nameToEnc.put("i", new Integer(105)); + encToName[105] = "i"; + + unicodeToName.put(new Character((char) 0x00ed), "iacute"); + nameToUnicode.put("iacute", new Character((char) 0x00ed)); + nameToEnc.put("iacute", new Integer(237)); + encToName[237] = "iacute"; + + unicodeToName.put(new Character((char) 0x00ee), "icircumflex"); + nameToUnicode.put("icircumflex", new Character((char) 0x00ee)); + nameToEnc.put("icircumflex", new Integer(238)); + encToName[238] = "icircumflex"; + + unicodeToName.put(new Character((char) 0x00ef), "idieresis"); + nameToUnicode.put("idieresis", new Character((char) 0x00ef)); + nameToEnc.put("idieresis", new Integer(239)); + encToName[239] = "idieresis"; + + unicodeToName.put(new Character((char) 0x00ec), "igrave"); + nameToUnicode.put("igrave", new Character((char) 0x00ec)); + nameToEnc.put("igrave", new Integer(236)); + encToName[236] = "igrave"; + + unicodeToName.put(new Character((char) 0x006a), "j"); + nameToUnicode.put("j", new Character((char) 0x006a)); + nameToEnc.put("j", new Integer(106)); + encToName[106] = "j"; + + unicodeToName.put(new Character((char) 0x006b), "k"); + nameToUnicode.put("k", new Character((char) 0x006b)); + nameToEnc.put("k", new Integer(107)); + encToName[107] = "k"; + + unicodeToName.put(new Character((char) 0x006c), "l"); + nameToUnicode.put("l", new Character((char) 0x006c)); + nameToEnc.put("l", new Integer(108)); + encToName[108] = "l"; + + unicodeToName.put(new Character((char) 0x003c), "less"); + nameToUnicode.put("less", new Character((char) 0x003c)); + nameToEnc.put("less", new Integer(60)); + encToName[60] = "less"; + + unicodeToName.put(new Character((char) 0x00ac), "logicalnot"); + nameToUnicode.put("logicalnot", new Character((char) 0x00ac)); + nameToEnc.put("logicalnot", new Integer(172)); + encToName[172] = "logicalnot"; + + unicodeToName.put(new Character((char) 0x0142), "lslash"); + nameToUnicode.put("lslash", new Character((char) 0x0142)); + + unicodeToName.put(new Character((char) 0x006d), "m"); + nameToUnicode.put("m", new Character((char) 0x006d)); + nameToEnc.put("m", new Integer(109)); + encToName[109] = "m"; + + unicodeToName.put(new Character((char) 0x00af), "macron"); + nameToUnicode.put("macron", new Character((char) 0x00af)); + nameToEnc.put("macron", new Integer(175)); + encToName[175] = "macron"; + + unicodeToName.put(new Character((char) 0x2212), "minus"); + nameToUnicode.put("minus", new Character((char) 0x2212)); + + unicodeToName.put(new Character((char) 0x03bc), "mu"); + nameToUnicode.put("mu", new Character((char) 0x03bc)); + nameToEnc.put("mu", new Integer(181)); + encToName[181] = "mu"; + + unicodeToName.put(new Character((char) 0x00d7), "multiply"); + nameToUnicode.put("multiply", new Character((char) 0x00d7)); + nameToEnc.put("multiply", new Integer(215)); + encToName[215] = "multiply"; + + unicodeToName.put(new Character((char) 0x006e), "n"); + nameToUnicode.put("n", new Character((char) 0x006e)); + nameToEnc.put("n", new Integer(110)); + encToName[110] = "n"; + + unicodeToName.put(new Character((char) 0x0039), "nine"); + nameToUnicode.put("nine", new Character((char) 0x0039)); + nameToEnc.put("nine", new Integer(57)); + encToName[57] = "nine"; + + unicodeToName.put(new Character((char) 0x00f1), "ntilde"); + nameToUnicode.put("ntilde", new Character((char) 0x00f1)); + nameToEnc.put("ntilde", new Integer(241)); + encToName[241] = "ntilde"; + + unicodeToName.put(new Character((char) 0x0023), "numbersign"); + nameToUnicode.put("numbersign", new Character((char) 0x0023)); + nameToEnc.put("numbersign", new Integer(35)); + encToName[35] = "numbersign"; + + unicodeToName.put(new Character((char) 0x006f), "o"); + nameToUnicode.put("o", new Character((char) 0x006f)); + nameToEnc.put("o", new Integer(111)); + encToName[111] = "o"; + + unicodeToName.put(new Character((char) 0x00f3), "oacute"); + nameToUnicode.put("oacute", new Character((char) 0x00f3)); + nameToEnc.put("oacute", new Integer(243)); + encToName[243] = "oacute"; + + unicodeToName.put(new Character((char) 0x00f4), "ocircumflex"); + nameToUnicode.put("ocircumflex", new Character((char) 0x00f4)); + nameToEnc.put("ocircumflex", new Integer(244)); + encToName[244] = "ocircumflex"; + + unicodeToName.put(new Character((char) 0x00f6), "odieresis"); + nameToUnicode.put("odieresis", new Character((char) 0x00f6)); + nameToEnc.put("odieresis", new Integer(246)); + encToName[246] = "odieresis"; + + unicodeToName.put(new Character((char) 0x0153), "oe"); + nameToUnicode.put("oe", new Character((char) 0x0153)); + nameToEnc.put("oe", new Integer(156)); + encToName[156] = "oe"; + + unicodeToName.put(new Character((char) 0x02db), "ogonek"); + nameToUnicode.put("ogonek", new Character((char) 0x02db)); + + unicodeToName.put(new Character((char) 0x00f2), "ograve"); + nameToUnicode.put("ograve", new Character((char) 0x00f2)); + nameToEnc.put("ograve", new Integer(242)); + encToName[242] = "ograve"; + + unicodeToName.put(new Character((char) 0x0031), "one"); + nameToUnicode.put("one", new Character((char) 0x0031)); + nameToEnc.put("one", new Integer(49)); + encToName[49] = "one"; + + unicodeToName.put(new Character((char) 0x00bd), "onehalf"); + nameToUnicode.put("onehalf", new Character((char) 0x00bd)); + nameToEnc.put("onehalf", new Integer(189)); + encToName[189] = "onehalf"; + + unicodeToName.put(new Character((char) 0x00bc), "onequarter"); + nameToUnicode.put("onequarter", new Character((char) 0x00bc)); + nameToEnc.put("onequarter", new Integer(188)); + encToName[188] = "onequarter"; + + unicodeToName.put(new Character((char) 0x00b9), "onesuperior"); + nameToUnicode.put("onesuperior", new Character((char) 0x00b9)); + nameToEnc.put("onesuperior", new Integer(185)); + encToName[185] = "onesuperior"; + + unicodeToName.put(new Character((char) 0x00aa), "ordfeminine"); + nameToUnicode.put("ordfeminine", new Character((char) 0x00aa)); + nameToEnc.put("ordfeminine", new Integer(170)); + encToName[170] = "ordfeminine"; + + unicodeToName.put(new Character((char) 0x00ba), "ordmasculine"); + nameToUnicode.put("ordmasculine", new Character((char) 0x00ba)); + nameToEnc.put("ordmasculine", new Integer(186)); + encToName[186] = "ordmasculine"; + + unicodeToName.put(new Character((char) 0x00f8), "oslash"); + nameToUnicode.put("oslash", new Character((char) 0x00f8)); + nameToEnc.put("oslash", new Integer(248)); + encToName[248] = "oslash"; + + unicodeToName.put(new Character((char) 0x00f5), "otilde"); + nameToUnicode.put("otilde", new Character((char) 0x00f5)); + nameToEnc.put("otilde", new Integer(245)); + encToName[245] = "otilde"; + + unicodeToName.put(new Character((char) 0x0070), "p"); + nameToUnicode.put("p", new Character((char) 0x0070)); + nameToEnc.put("p", new Integer(112)); + encToName[112] = "p"; + + unicodeToName.put(new Character((char) 0x00b6), "paragraph"); + nameToUnicode.put("paragraph", new Character((char) 0x00b6)); + nameToEnc.put("paragraph", new Integer(182)); + encToName[182] = "paragraph"; + + unicodeToName.put(new Character((char) 0x0028), "parenleft"); + nameToUnicode.put("parenleft", new Character((char) 0x0028)); + nameToEnc.put("parenleft", new Integer(40)); + encToName[40] = "parenleft"; + + unicodeToName.put(new Character((char) 0x0029), "parenright"); + nameToUnicode.put("parenright", new Character((char) 0x0029)); + nameToEnc.put("parenright", new Integer(41)); + encToName[41] = "parenright"; + + unicodeToName.put(new Character((char) 0x0025), "percent"); + nameToUnicode.put("percent", new Character((char) 0x0025)); + nameToEnc.put("percent", new Integer(37)); + encToName[37] = "percent"; + + unicodeToName.put(new Character((char) 0x002e), "period"); + nameToUnicode.put("period", new Character((char) 0x002e)); + nameToEnc.put("period", new Integer(46)); + encToName[46] = "period"; + + unicodeToName.put(new Character((char) 0x00b7), "periodcentered"); + nameToUnicode.put("periodcentered", new Character((char) 0x00b7)); + nameToEnc.put("periodcentered", new Integer(183)); + encToName[183] = "periodcentered"; + + unicodeToName.put(new Character((char) 0x2030), "perthousand"); + nameToUnicode.put("perthousand", new Character((char) 0x2030)); + nameToEnc.put("perthousand", new Integer(137)); + encToName[137] = "perthousand"; + + unicodeToName.put(new Character((char) 0x002b), "plus"); + nameToUnicode.put("plus", new Character((char) 0x002b)); + nameToEnc.put("plus", new Integer(43)); + encToName[43] = "plus"; + + unicodeToName.put(new Character((char) 0x00b1), "plusminus"); + nameToUnicode.put("plusminus", new Character((char) 0x00b1)); + nameToEnc.put("plusminus", new Integer(177)); + encToName[177] = "plusminus"; + + unicodeToName.put(new Character((char) 0x0071), "q"); + nameToUnicode.put("q", new Character((char) 0x0071)); + nameToEnc.put("q", new Integer(113)); + encToName[113] = "q"; + + unicodeToName.put(new Character((char) 0x003f), "question"); + nameToUnicode.put("question", new Character((char) 0x003f)); + nameToEnc.put("question", new Integer(63)); + encToName[63] = "question"; + + unicodeToName.put(new Character((char) 0x00bf), "questiondown"); + nameToUnicode.put("questiondown", new Character((char) 0x00bf)); + nameToEnc.put("questiondown", new Integer(191)); + encToName[191] = "questiondown"; + + unicodeToName.put(new Character((char) 0x0022), "quotedbl"); + nameToUnicode.put("quotedbl", new Character((char) 0x0022)); + nameToEnc.put("quotedbl", new Integer(34)); + encToName[34] = "quotedbl"; + + unicodeToName.put(new Character((char) 0x201e), "quotedblbase"); + nameToUnicode.put("quotedblbase", new Character((char) 0x201e)); + nameToEnc.put("quotedblbase", new Integer(132)); + encToName[132] = "quotedblbase"; + + unicodeToName.put(new Character((char) 0x201c), "quotedblleft"); + nameToUnicode.put("quotedblleft", new Character((char) 0x201c)); + nameToEnc.put("quotedblleft", new Integer(147)); + encToName[147] = "quotedblleft"; + + unicodeToName.put(new Character((char) 0x201d), "quotedblright"); + nameToUnicode.put("quotedblright", new Character((char) 0x201d)); + nameToEnc.put("quotedblright", new Integer(148)); + encToName[148] = "quotedblright"; + + unicodeToName.put(new Character((char) 0x0060), "quoteleft"); + nameToUnicode.put("quoteleft", new Character((char) 0x0060)); + nameToEnc.put("quoteleft", new Integer(145)); + encToName[145] = "quoteleft"; + + unicodeToName.put(new Character((char) 0x0027), "quoteright"); + nameToUnicode.put("quoteright", new Character((char) 0x0027)); + nameToEnc.put("quoteright", new Integer(146)); + encToName[146] = "quoteright"; + + unicodeToName.put(new Character((char) 0x201a), "quotesinglbase"); + nameToUnicode.put("quotesinglbase", new Character((char) 0x201a)); + nameToEnc.put("quotesinglbase", new Integer(130)); + encToName[130] = "quotesinglbase"; + + unicodeToName.put(new Character((char) 0x0027), "quotesingle"); + nameToUnicode.put("quotesingle", new Character((char) 0x0027)); + nameToEnc.put("quotesingle", new Integer(39)); + encToName[39] = "quotesingle"; + + unicodeToName.put(new Character((char) 0x0072), "r"); + nameToUnicode.put("r", new Character((char) 0x0072)); + nameToEnc.put("r", new Integer(114)); + encToName[114] = "r"; + + unicodeToName.put(new Character((char) 0x00ae), "registered"); + nameToUnicode.put("registered", new Character((char) 0x00ae)); + nameToEnc.put("registered", new Integer(174)); + encToName[174] = "registered"; + + unicodeToName.put(new Character((char) 0x02da), "ring"); + nameToUnicode.put("ring", new Character((char) 0x02da)); + + unicodeToName.put(new Character((char) 0x0073), "s"); + nameToUnicode.put("s", new Character((char) 0x0073)); + nameToEnc.put("s", new Integer(115)); + encToName[115] = "s"; + + unicodeToName.put(new Character((char) 0x0161), "scaron"); + nameToUnicode.put("scaron", new Character((char) 0x0161)); + nameToEnc.put("scaron", new Integer(154)); + encToName[154] = "scaron"; + + unicodeToName.put(new Character((char) 0x00a7), "section"); + nameToUnicode.put("section", new Character((char) 0x00a7)); + nameToEnc.put("section", new Integer(167)); + encToName[167] = "section"; + + unicodeToName.put(new Character((char) 0x003b), "semicolon"); + nameToUnicode.put("semicolon", new Character((char) 0x003b)); + nameToEnc.put("semicolon", new Integer(59)); + encToName[59] = "semicolon"; + + unicodeToName.put(new Character((char) 0x0037), "seven"); + nameToUnicode.put("seven", new Character((char) 0x0037)); + nameToEnc.put("seven", new Integer(55)); + encToName[55] = "seven"; + + unicodeToName.put(new Character((char) 0x0036), "six"); + nameToUnicode.put("six", new Character((char) 0x0036)); + nameToEnc.put("six", new Integer(54)); + encToName[54] = "six"; + + unicodeToName.put(new Character((char) 0x002f), "slash"); + nameToUnicode.put("slash", new Character((char) 0x002f)); + nameToEnc.put("slash", new Integer(47)); + encToName[47] = "slash"; + + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x00a3), "sterling"); + nameToUnicode.put("sterling", new Character((char) 0x00a3)); + nameToEnc.put("sterling", new Integer(163)); + encToName[163] = "sterling"; + + unicodeToName.put(new Character((char) 0x0074), "t"); + nameToUnicode.put("t", new Character((char) 0x0074)); + nameToEnc.put("t", new Integer(116)); + encToName[116] = "t"; + + unicodeToName.put(new Character((char) 0x00fe), "thorn"); + nameToUnicode.put("thorn", new Character((char) 0x00fe)); + nameToEnc.put("thorn", new Integer(254)); + encToName[254] = "thorn"; + + unicodeToName.put(new Character((char) 0x0033), "three"); + nameToUnicode.put("three", new Character((char) 0x0033)); + nameToEnc.put("three", new Integer(51)); + encToName[51] = "three"; + + unicodeToName.put(new Character((char) 0x00be), "threequarters"); + nameToUnicode.put("threequarters", new Character((char) 0x00be)); + nameToEnc.put("threequarters", new Integer(190)); + encToName[190] = "threequarters"; + + unicodeToName.put(new Character((char) 0x00b3), "threesuperior"); + nameToUnicode.put("threesuperior", new Character((char) 0x00b3)); + nameToEnc.put("threesuperior", new Integer(179)); + encToName[179] = "threesuperior"; + + unicodeToName.put(new Character((char) 0x02dc), "tilde"); + nameToUnicode.put("tilde", new Character((char) 0x02dc)); + nameToEnc.put("tilde", new Integer(152)); + encToName[152] = "tilde"; + + unicodeToName.put(new Character((char) 0x2122), "trademark"); + nameToUnicode.put("trademark", new Character((char) 0x2122)); + nameToEnc.put("trademark", new Integer(153)); + encToName[153] = "trademark"; + + unicodeToName.put(new Character((char) 0x0032), "two"); + nameToUnicode.put("two", new Character((char) 0x0032)); + nameToEnc.put("two", new Integer(50)); + encToName[50] = "two"; + + unicodeToName.put(new Character((char) 0x00b2), "twosuperior"); + nameToUnicode.put("twosuperior", new Character((char) 0x00b2)); + nameToEnc.put("twosuperior", new Integer(178)); + encToName[178] = "twosuperior"; + + unicodeToName.put(new Character((char) 0x0075), "u"); + nameToUnicode.put("u", new Character((char) 0x0075)); + nameToEnc.put("u", new Integer(117)); + encToName[117] = "u"; + + unicodeToName.put(new Character((char) 0x00fa), "uacute"); + nameToUnicode.put("uacute", new Character((char) 0x00fa)); + nameToEnc.put("uacute", new Integer(250)); + encToName[250] = "uacute"; + + unicodeToName.put(new Character((char) 0x00fb), "ucircumflex"); + nameToUnicode.put("ucircumflex", new Character((char) 0x00fb)); + nameToEnc.put("ucircumflex", new Integer(251)); + encToName[251] = "ucircumflex"; + + unicodeToName.put(new Character((char) 0x00fc), "udieresis"); + nameToUnicode.put("udieresis", new Character((char) 0x00fc)); + nameToEnc.put("udieresis", new Integer(252)); + encToName[252] = "udieresis"; + + unicodeToName.put(new Character((char) 0x00f9), "ugrave"); + nameToUnicode.put("ugrave", new Character((char) 0x00f9)); + nameToEnc.put("ugrave", new Integer(249)); + encToName[249] = "ugrave"; + + unicodeToName.put(new Character((char) 0x005f), "underscore"); + nameToUnicode.put("underscore", new Character((char) 0x005f)); + nameToEnc.put("underscore", new Integer(95)); + encToName[95] = "underscore"; + + unicodeToName.put(new Character((char) 0x0076), "v"); + nameToUnicode.put("v", new Character((char) 0x0076)); + nameToEnc.put("v", new Integer(118)); + encToName[118] = "v"; + + unicodeToName.put(new Character((char) 0x0077), "w"); + nameToUnicode.put("w", new Character((char) 0x0077)); + nameToEnc.put("w", new Integer(119)); + encToName[119] = "w"; + + unicodeToName.put(new Character((char) 0x0078), "x"); + nameToUnicode.put("x", new Character((char) 0x0078)); + nameToEnc.put("x", new Integer(120)); + encToName[120] = "x"; + + unicodeToName.put(new Character((char) 0x0079), "y"); + nameToUnicode.put("y", new Character((char) 0x0079)); + nameToEnc.put("y", new Integer(121)); + encToName[121] = "y"; + + unicodeToName.put(new Character((char) 0x00fd), "yacute"); + nameToUnicode.put("yacute", new Character((char) 0x00fd)); + nameToEnc.put("yacute", new Integer(253)); + encToName[253] = "yacute"; + + unicodeToName.put(new Character((char) 0x00ff), "ydieresis"); + nameToUnicode.put("ydieresis", new Character((char) 0x00ff)); + nameToEnc.put("ydieresis", new Integer(255)); + encToName[255] = "ydieresis"; + + unicodeToName.put(new Character((char) 0x00a5), "yen"); + nameToUnicode.put("yen", new Character((char) 0x00a5)); + nameToEnc.put("yen", new Integer(165)); + encToName[165] = "yen"; + + unicodeToName.put(new Character((char) 0x007a), "z"); + nameToUnicode.put("z", new Character((char) 0x007a)); + nameToEnc.put("z", new Integer(122)); + encToName[122] = "z"; + + unicodeToName.put(new Character((char) 0x017e), "zcaron"); + nameToUnicode.put("zcaron", new Character((char) 0x017e)); + nameToEnc.put("zcaron", new Integer(158)); + encToName[158] = "zcaron"; + + unicodeToName.put(new Character((char) 0x0030), "zero"); + nameToUnicode.put("zero", new Character((char) 0x0030)); + nameToEnc.put("zero", new Integer(48)); + encToName[48] = "zero"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Latin");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("WIN");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Zapfdingbats.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Zapfdingbats.java index 9cc39c9e8..600600b9b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Zapfdingbats.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphics2d/font/Zapfdingbats.java @@ -1,989 +1,989 @@ -//Generated by CharTableConverter -//!!DO NOT EDIT -package org.xmind.org.freehep.graphics2d.font; - -import java.util.Hashtable; - -/** - * Generated Zapfdingbats Encoding Table. - * - * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter - * @author Jason Wong - */ -public class Zapfdingbats extends AbstractCharTable { - private Hashtable unicodeToName = new Hashtable(); - private Hashtable nameToUnicode = new Hashtable(); - private Hashtable nameToEnc = new Hashtable(); - private String[] encToName = new String[256]; - - @SuppressWarnings("nls") - public Zapfdingbats() { - unicodeToName.put(new Character((char) 0x0020), "space"); - nameToUnicode.put("space", new Character((char) 0x0020)); - nameToEnc.put("space", new Integer(32)); - encToName[32] = "space"; - - unicodeToName.put(new Character((char) 0x2701), "a1"); - nameToUnicode.put("a1", new Character((char) 0x2701)); - nameToEnc.put("a1", new Integer(33)); - encToName[33] = "a1"; - - unicodeToName.put(new Character((char) 0x2702), "a2"); - nameToUnicode.put("a2", new Character((char) 0x2702)); - nameToEnc.put("a2", new Integer(34)); - encToName[34] = "a2"; - - unicodeToName.put(new Character((char) 0x2703), "a202"); - nameToUnicode.put("a202", new Character((char) 0x2703)); - nameToEnc.put("a202", new Integer(35)); - encToName[35] = "a202"; - - unicodeToName.put(new Character((char) 0x2704), "a3"); - nameToUnicode.put("a3", new Character((char) 0x2704)); - nameToEnc.put("a3", new Integer(36)); - encToName[36] = "a3"; - - unicodeToName.put(new Character((char) 0x260e), "a4"); - nameToUnicode.put("a4", new Character((char) 0x260e)); - nameToEnc.put("a4", new Integer(37)); - encToName[37] = "a4"; - - unicodeToName.put(new Character((char) 0x2706), "a5"); - nameToUnicode.put("a5", new Character((char) 0x2706)); - nameToEnc.put("a5", new Integer(38)); - encToName[38] = "a5"; - - unicodeToName.put(new Character((char) 0x2707), "a119"); - nameToUnicode.put("a119", new Character((char) 0x2707)); - nameToEnc.put("a119", new Integer(39)); - encToName[39] = "a119"; - - unicodeToName.put(new Character((char) 0x2708), "a118"); - nameToUnicode.put("a118", new Character((char) 0x2708)); - nameToEnc.put("a118", new Integer(40)); - encToName[40] = "a118"; - - unicodeToName.put(new Character((char) 0x2709), "a117"); - nameToUnicode.put("a117", new Character((char) 0x2709)); - nameToEnc.put("a117", new Integer(41)); - encToName[41] = "a117"; - - unicodeToName.put(new Character((char) 0x261b), "a11"); - nameToUnicode.put("a11", new Character((char) 0x261b)); - nameToEnc.put("a11", new Integer(42)); - encToName[42] = "a11"; - - unicodeToName.put(new Character((char) 0x261e), "a12"); - nameToUnicode.put("a12", new Character((char) 0x261e)); - nameToEnc.put("a12", new Integer(43)); - encToName[43] = "a12"; - - unicodeToName.put(new Character((char) 0x270c), "a13"); - nameToUnicode.put("a13", new Character((char) 0x270c)); - nameToEnc.put("a13", new Integer(44)); - encToName[44] = "a13"; - - unicodeToName.put(new Character((char) 0x270d), "a14"); - nameToUnicode.put("a14", new Character((char) 0x270d)); - nameToEnc.put("a14", new Integer(45)); - encToName[45] = "a14"; - - unicodeToName.put(new Character((char) 0x270e), "a15"); - nameToUnicode.put("a15", new Character((char) 0x270e)); - nameToEnc.put("a15", new Integer(46)); - encToName[46] = "a15"; - - unicodeToName.put(new Character((char) 0x270f), "a16"); - nameToUnicode.put("a16", new Character((char) 0x270f)); - nameToEnc.put("a16", new Integer(47)); - encToName[47] = "a16"; - - unicodeToName.put(new Character((char) 0x2710), "a105"); - nameToUnicode.put("a105", new Character((char) 0x2710)); - nameToEnc.put("a105", new Integer(48)); - encToName[48] = "a105"; - - unicodeToName.put(new Character((char) 0x2711), "a17"); - nameToUnicode.put("a17", new Character((char) 0x2711)); - nameToEnc.put("a17", new Integer(49)); - encToName[49] = "a17"; - - unicodeToName.put(new Character((char) 0x2712), "a18"); - nameToUnicode.put("a18", new Character((char) 0x2712)); - nameToEnc.put("a18", new Integer(50)); - encToName[50] = "a18"; - - unicodeToName.put(new Character((char) 0x2713), "a19"); - nameToUnicode.put("a19", new Character((char) 0x2713)); - nameToEnc.put("a19", new Integer(51)); - encToName[51] = "a19"; - - unicodeToName.put(new Character((char) 0x2714), "a20"); - nameToUnicode.put("a20", new Character((char) 0x2714)); - nameToEnc.put("a20", new Integer(52)); - encToName[52] = "a20"; - - unicodeToName.put(new Character((char) 0x2715), "a21"); - nameToUnicode.put("a21", new Character((char) 0x2715)); - nameToEnc.put("a21", new Integer(53)); - encToName[53] = "a21"; - - unicodeToName.put(new Character((char) 0x2716), "a22"); - nameToUnicode.put("a22", new Character((char) 0x2716)); - nameToEnc.put("a22", new Integer(54)); - encToName[54] = "a22"; - - unicodeToName.put(new Character((char) 0x2717), "a23"); - nameToUnicode.put("a23", new Character((char) 0x2717)); - nameToEnc.put("a23", new Integer(55)); - encToName[55] = "a23"; - - unicodeToName.put(new Character((char) 0x2718), "a24"); - nameToUnicode.put("a24", new Character((char) 0x2718)); - nameToEnc.put("a24", new Integer(56)); - encToName[56] = "a24"; - - unicodeToName.put(new Character((char) 0x2719), "a25"); - nameToUnicode.put("a25", new Character((char) 0x2719)); - nameToEnc.put("a25", new Integer(57)); - encToName[57] = "a25"; - - unicodeToName.put(new Character((char) 0x271a), "a26"); - nameToUnicode.put("a26", new Character((char) 0x271a)); - nameToEnc.put("a26", new Integer(58)); - encToName[58] = "a26"; - - unicodeToName.put(new Character((char) 0x271b), "a27"); - nameToUnicode.put("a27", new Character((char) 0x271b)); - nameToEnc.put("a27", new Integer(59)); - encToName[59] = "a27"; - - unicodeToName.put(new Character((char) 0x271c), "a28"); - nameToUnicode.put("a28", new Character((char) 0x271c)); - nameToEnc.put("a28", new Integer(60)); - encToName[60] = "a28"; - - unicodeToName.put(new Character((char) 0x271d), "a6"); - nameToUnicode.put("a6", new Character((char) 0x271d)); - nameToEnc.put("a6", new Integer(61)); - encToName[61] = "a6"; - - unicodeToName.put(new Character((char) 0x271e), "a7"); - nameToUnicode.put("a7", new Character((char) 0x271e)); - nameToEnc.put("a7", new Integer(62)); - encToName[62] = "a7"; - - unicodeToName.put(new Character((char) 0x271f), "a8"); - nameToUnicode.put("a8", new Character((char) 0x271f)); - nameToEnc.put("a8", new Integer(63)); - encToName[63] = "a8"; - - unicodeToName.put(new Character((char) 0x2720), "a9"); - nameToUnicode.put("a9", new Character((char) 0x2720)); - nameToEnc.put("a9", new Integer(64)); - encToName[64] = "a9"; - - unicodeToName.put(new Character((char) 0x2721), "a10"); - nameToUnicode.put("a10", new Character((char) 0x2721)); - nameToEnc.put("a10", new Integer(65)); - encToName[65] = "a10"; - - unicodeToName.put(new Character((char) 0x2722), "a29"); - nameToUnicode.put("a29", new Character((char) 0x2722)); - nameToEnc.put("a29", new Integer(66)); - encToName[66] = "a29"; - - unicodeToName.put(new Character((char) 0x2723), "a30"); - nameToUnicode.put("a30", new Character((char) 0x2723)); - nameToEnc.put("a30", new Integer(67)); - encToName[67] = "a30"; - - unicodeToName.put(new Character((char) 0x2724), "a31"); - nameToUnicode.put("a31", new Character((char) 0x2724)); - nameToEnc.put("a31", new Integer(68)); - encToName[68] = "a31"; - - unicodeToName.put(new Character((char) 0x2725), "a32"); - nameToUnicode.put("a32", new Character((char) 0x2725)); - nameToEnc.put("a32", new Integer(69)); - encToName[69] = "a32"; - - unicodeToName.put(new Character((char) 0x2726), "a33"); - nameToUnicode.put("a33", new Character((char) 0x2726)); - nameToEnc.put("a33", new Integer(70)); - encToName[70] = "a33"; - - unicodeToName.put(new Character((char) 0x2727), "a34"); - nameToUnicode.put("a34", new Character((char) 0x2727)); - nameToEnc.put("a34", new Integer(71)); - encToName[71] = "a34"; - - unicodeToName.put(new Character((char) 0x2605), "a35"); - nameToUnicode.put("a35", new Character((char) 0x2605)); - nameToEnc.put("a35", new Integer(72)); - encToName[72] = "a35"; - - unicodeToName.put(new Character((char) 0x2729), "a36"); - nameToUnicode.put("a36", new Character((char) 0x2729)); - nameToEnc.put("a36", new Integer(73)); - encToName[73] = "a36"; - - unicodeToName.put(new Character((char) 0x272a), "a37"); - nameToUnicode.put("a37", new Character((char) 0x272a)); - nameToEnc.put("a37", new Integer(74)); - encToName[74] = "a37"; - - unicodeToName.put(new Character((char) 0x272b), "a38"); - nameToUnicode.put("a38", new Character((char) 0x272b)); - nameToEnc.put("a38", new Integer(75)); - encToName[75] = "a38"; - - unicodeToName.put(new Character((char) 0x272c), "a39"); - nameToUnicode.put("a39", new Character((char) 0x272c)); - nameToEnc.put("a39", new Integer(76)); - encToName[76] = "a39"; - - unicodeToName.put(new Character((char) 0x272d), "a40"); - nameToUnicode.put("a40", new Character((char) 0x272d)); - nameToEnc.put("a40", new Integer(77)); - encToName[77] = "a40"; - - unicodeToName.put(new Character((char) 0x272e), "a41"); - nameToUnicode.put("a41", new Character((char) 0x272e)); - nameToEnc.put("a41", new Integer(78)); - encToName[78] = "a41"; - - unicodeToName.put(new Character((char) 0x272f), "a42"); - nameToUnicode.put("a42", new Character((char) 0x272f)); - nameToEnc.put("a42", new Integer(79)); - encToName[79] = "a42"; - - unicodeToName.put(new Character((char) 0x2730), "a43"); - nameToUnicode.put("a43", new Character((char) 0x2730)); - nameToEnc.put("a43", new Integer(80)); - encToName[80] = "a43"; - - unicodeToName.put(new Character((char) 0x2731), "a44"); - nameToUnicode.put("a44", new Character((char) 0x2731)); - nameToEnc.put("a44", new Integer(81)); - encToName[81] = "a44"; - - unicodeToName.put(new Character((char) 0x2732), "a45"); - nameToUnicode.put("a45", new Character((char) 0x2732)); - nameToEnc.put("a45", new Integer(82)); - encToName[82] = "a45"; - - unicodeToName.put(new Character((char) 0x2733), "a46"); - nameToUnicode.put("a46", new Character((char) 0x2733)); - nameToEnc.put("a46", new Integer(83)); - encToName[83] = "a46"; - - unicodeToName.put(new Character((char) 0x2734), "a47"); - nameToUnicode.put("a47", new Character((char) 0x2734)); - nameToEnc.put("a47", new Integer(84)); - encToName[84] = "a47"; - - unicodeToName.put(new Character((char) 0x2735), "a48"); - nameToUnicode.put("a48", new Character((char) 0x2735)); - nameToEnc.put("a48", new Integer(85)); - encToName[85] = "a48"; - - unicodeToName.put(new Character((char) 0x2736), "a49"); - nameToUnicode.put("a49", new Character((char) 0x2736)); - nameToEnc.put("a49", new Integer(86)); - encToName[86] = "a49"; - - unicodeToName.put(new Character((char) 0x2737), "a50"); - nameToUnicode.put("a50", new Character((char) 0x2737)); - nameToEnc.put("a50", new Integer(87)); - encToName[87] = "a50"; - - unicodeToName.put(new Character((char) 0x2738), "a51"); - nameToUnicode.put("a51", new Character((char) 0x2738)); - nameToEnc.put("a51", new Integer(88)); - encToName[88] = "a51"; - - unicodeToName.put(new Character((char) 0x2739), "a52"); - nameToUnicode.put("a52", new Character((char) 0x2739)); - nameToEnc.put("a52", new Integer(89)); - encToName[89] = "a52"; - - unicodeToName.put(new Character((char) 0x273a), "a53"); - nameToUnicode.put("a53", new Character((char) 0x273a)); - nameToEnc.put("a53", new Integer(90)); - encToName[90] = "a53"; - - unicodeToName.put(new Character((char) 0x273b), "a54"); - nameToUnicode.put("a54", new Character((char) 0x273b)); - nameToEnc.put("a54", new Integer(91)); - encToName[91] = "a54"; - - unicodeToName.put(new Character((char) 0x273c), "a55"); - nameToUnicode.put("a55", new Character((char) 0x273c)); - nameToEnc.put("a55", new Integer(92)); - encToName[92] = "a55"; - - unicodeToName.put(new Character((char) 0x273d), "a56"); - nameToUnicode.put("a56", new Character((char) 0x273d)); - nameToEnc.put("a56", new Integer(93)); - encToName[93] = "a56"; - - unicodeToName.put(new Character((char) 0x273e), "a57"); - nameToUnicode.put("a57", new Character((char) 0x273e)); - nameToEnc.put("a57", new Integer(94)); - encToName[94] = "a57"; - - unicodeToName.put(new Character((char) 0x273f), "a58"); - nameToUnicode.put("a58", new Character((char) 0x273f)); - nameToEnc.put("a58", new Integer(95)); - encToName[95] = "a58"; - - unicodeToName.put(new Character((char) 0x2740), "a59"); - nameToUnicode.put("a59", new Character((char) 0x2740)); - nameToEnc.put("a59", new Integer(96)); - encToName[96] = "a59"; - - unicodeToName.put(new Character((char) 0x2741), "a60"); - nameToUnicode.put("a60", new Character((char) 0x2741)); - nameToEnc.put("a60", new Integer(97)); - encToName[97] = "a60"; - - unicodeToName.put(new Character((char) 0x2742), "a61"); - nameToUnicode.put("a61", new Character((char) 0x2742)); - nameToEnc.put("a61", new Integer(98)); - encToName[98] = "a61"; - - unicodeToName.put(new Character((char) 0x2743), "a62"); - nameToUnicode.put("a62", new Character((char) 0x2743)); - nameToEnc.put("a62", new Integer(99)); - encToName[99] = "a62"; - - unicodeToName.put(new Character((char) 0x2744), "a63"); - nameToUnicode.put("a63", new Character((char) 0x2744)); - nameToEnc.put("a63", new Integer(100)); - encToName[100] = "a63"; - - unicodeToName.put(new Character((char) 0x2745), "a64"); - nameToUnicode.put("a64", new Character((char) 0x2745)); - nameToEnc.put("a64", new Integer(101)); - encToName[101] = "a64"; - - unicodeToName.put(new Character((char) 0x2746), "a65"); - nameToUnicode.put("a65", new Character((char) 0x2746)); - nameToEnc.put("a65", new Integer(102)); - encToName[102] = "a65"; - - unicodeToName.put(new Character((char) 0x2747), "a66"); - nameToUnicode.put("a66", new Character((char) 0x2747)); - nameToEnc.put("a66", new Integer(103)); - encToName[103] = "a66"; - - unicodeToName.put(new Character((char) 0x2748), "a67"); - nameToUnicode.put("a67", new Character((char) 0x2748)); - nameToEnc.put("a67", new Integer(104)); - encToName[104] = "a67"; - - unicodeToName.put(new Character((char) 0x2749), "a68"); - nameToUnicode.put("a68", new Character((char) 0x2749)); - nameToEnc.put("a68", new Integer(105)); - encToName[105] = "a68"; - - unicodeToName.put(new Character((char) 0x274a), "a69"); - nameToUnicode.put("a69", new Character((char) 0x274a)); - nameToEnc.put("a69", new Integer(106)); - encToName[106] = "a69"; - - unicodeToName.put(new Character((char) 0x274b), "a70"); - nameToUnicode.put("a70", new Character((char) 0x274b)); - nameToEnc.put("a70", new Integer(107)); - encToName[107] = "a70"; - - unicodeToName.put(new Character((char) 0x25cf), "a71"); - nameToUnicode.put("a71", new Character((char) 0x25cf)); - nameToEnc.put("a71", new Integer(108)); - encToName[108] = "a71"; - - unicodeToName.put(new Character((char) 0x274d), "a72"); - nameToUnicode.put("a72", new Character((char) 0x274d)); - nameToEnc.put("a72", new Integer(109)); - encToName[109] = "a72"; - - unicodeToName.put(new Character((char) 0x25a0), "a73"); - nameToUnicode.put("a73", new Character((char) 0x25a0)); - nameToEnc.put("a73", new Integer(110)); - encToName[110] = "a73"; - - unicodeToName.put(new Character((char) 0x274f), "a74"); - nameToUnicode.put("a74", new Character((char) 0x274f)); - nameToEnc.put("a74", new Integer(111)); - encToName[111] = "a74"; - - unicodeToName.put(new Character((char) 0x2750), "a203"); - nameToUnicode.put("a203", new Character((char) 0x2750)); - nameToEnc.put("a203", new Integer(112)); - encToName[112] = "a203"; - - unicodeToName.put(new Character((char) 0x2751), "a75"); - nameToUnicode.put("a75", new Character((char) 0x2751)); - nameToEnc.put("a75", new Integer(113)); - encToName[113] = "a75"; - - unicodeToName.put(new Character((char) 0x2752), "a204"); - nameToUnicode.put("a204", new Character((char) 0x2752)); - nameToEnc.put("a204", new Integer(114)); - encToName[114] = "a204"; - - unicodeToName.put(new Character((char) 0x25b2), "a76"); - nameToUnicode.put("a76", new Character((char) 0x25b2)); - nameToEnc.put("a76", new Integer(115)); - encToName[115] = "a76"; - - unicodeToName.put(new Character((char) 0x25bc), "a77"); - nameToUnicode.put("a77", new Character((char) 0x25bc)); - nameToEnc.put("a77", new Integer(116)); - encToName[116] = "a77"; - - unicodeToName.put(new Character((char) 0x25c6), "a78"); - nameToUnicode.put("a78", new Character((char) 0x25c6)); - nameToEnc.put("a78", new Integer(117)); - encToName[117] = "a78"; - - unicodeToName.put(new Character((char) 0x2756), "a79"); - nameToUnicode.put("a79", new Character((char) 0x2756)); - nameToEnc.put("a79", new Integer(118)); - encToName[118] = "a79"; - - unicodeToName.put(new Character((char) 0x25d7), "a81"); - nameToUnicode.put("a81", new Character((char) 0x25d7)); - nameToEnc.put("a81", new Integer(119)); - encToName[119] = "a81"; - - unicodeToName.put(new Character((char) 0x2758), "a82"); - nameToUnicode.put("a82", new Character((char) 0x2758)); - nameToEnc.put("a82", new Integer(120)); - encToName[120] = "a82"; - - unicodeToName.put(new Character((char) 0x2759), "a83"); - nameToUnicode.put("a83", new Character((char) 0x2759)); - nameToEnc.put("a83", new Integer(121)); - encToName[121] = "a83"; - - unicodeToName.put(new Character((char) 0x275a), "a84"); - nameToUnicode.put("a84", new Character((char) 0x275a)); - nameToEnc.put("a84", new Integer(122)); - encToName[122] = "a84"; - - unicodeToName.put(new Character((char) 0x275b), "a97"); - nameToUnicode.put("a97", new Character((char) 0x275b)); - nameToEnc.put("a97", new Integer(123)); - encToName[123] = "a97"; - - unicodeToName.put(new Character((char) 0x275c), "a98"); - nameToUnicode.put("a98", new Character((char) 0x275c)); - nameToEnc.put("a98", new Integer(124)); - encToName[124] = "a98"; - - unicodeToName.put(new Character((char) 0x275d), "a99"); - nameToUnicode.put("a99", new Character((char) 0x275d)); - nameToEnc.put("a99", new Integer(125)); - encToName[125] = "a99"; - - unicodeToName.put(new Character((char) 0x275e), "a100"); - nameToUnicode.put("a100", new Character((char) 0x275e)); - nameToEnc.put("a100", new Integer(126)); - encToName[126] = "a100"; - - unicodeToName.put(new Character((char) 0x2761), "a101"); - nameToUnicode.put("a101", new Character((char) 0x2761)); - nameToEnc.put("a101", new Integer(161)); - encToName[161] = "a101"; - - unicodeToName.put(new Character((char) 0x2762), "a102"); - nameToUnicode.put("a102", new Character((char) 0x2762)); - nameToEnc.put("a102", new Integer(162)); - encToName[162] = "a102"; - - unicodeToName.put(new Character((char) 0x2763), "a103"); - nameToUnicode.put("a103", new Character((char) 0x2763)); - nameToEnc.put("a103", new Integer(163)); - encToName[163] = "a103"; - - unicodeToName.put(new Character((char) 0x2764), "a104"); - nameToUnicode.put("a104", new Character((char) 0x2764)); - nameToEnc.put("a104", new Integer(164)); - encToName[164] = "a104"; - - unicodeToName.put(new Character((char) 0x2765), "a106"); - nameToUnicode.put("a106", new Character((char) 0x2765)); - nameToEnc.put("a106", new Integer(165)); - encToName[165] = "a106"; - - unicodeToName.put(new Character((char) 0x2766), "a107"); - nameToUnicode.put("a107", new Character((char) 0x2766)); - nameToEnc.put("a107", new Integer(166)); - encToName[166] = "a107"; - - unicodeToName.put(new Character((char) 0x2767), "a108"); - nameToUnicode.put("a108", new Character((char) 0x2767)); - nameToEnc.put("a108", new Integer(167)); - encToName[167] = "a108"; - - unicodeToName.put(new Character((char) 0x2663), "a112"); - nameToUnicode.put("a112", new Character((char) 0x2663)); - nameToEnc.put("a112", new Integer(168)); - encToName[168] = "a112"; - - unicodeToName.put(new Character((char) 0x2666), "a111"); - nameToUnicode.put("a111", new Character((char) 0x2666)); - nameToEnc.put("a111", new Integer(169)); - encToName[169] = "a111"; - - unicodeToName.put(new Character((char) 0x2665), "a110"); - nameToUnicode.put("a110", new Character((char) 0x2665)); - nameToEnc.put("a110", new Integer(170)); - encToName[170] = "a110"; - - unicodeToName.put(new Character((char) 0x2660), "a109"); - nameToUnicode.put("a109", new Character((char) 0x2660)); - nameToEnc.put("a109", new Integer(171)); - encToName[171] = "a109"; - - unicodeToName.put(new Character((char) 0x2460), "a120"); - nameToUnicode.put("a120", new Character((char) 0x2460)); - nameToEnc.put("a120", new Integer(172)); - encToName[172] = "a120"; - - unicodeToName.put(new Character((char) 0x2461), "a121"); - nameToUnicode.put("a121", new Character((char) 0x2461)); - nameToEnc.put("a121", new Integer(173)); - encToName[173] = "a121"; - - unicodeToName.put(new Character((char) 0x2462), "a122"); - nameToUnicode.put("a122", new Character((char) 0x2462)); - nameToEnc.put("a122", new Integer(174)); - encToName[174] = "a122"; - - unicodeToName.put(new Character((char) 0x2463), "a123"); - nameToUnicode.put("a123", new Character((char) 0x2463)); - nameToEnc.put("a123", new Integer(175)); - encToName[175] = "a123"; - - unicodeToName.put(new Character((char) 0x2464), "a124"); - nameToUnicode.put("a124", new Character((char) 0x2464)); - nameToEnc.put("a124", new Integer(176)); - encToName[176] = "a124"; - - unicodeToName.put(new Character((char) 0x2465), "a125"); - nameToUnicode.put("a125", new Character((char) 0x2465)); - nameToEnc.put("a125", new Integer(177)); - encToName[177] = "a125"; - - unicodeToName.put(new Character((char) 0x2466), "a126"); - nameToUnicode.put("a126", new Character((char) 0x2466)); - nameToEnc.put("a126", new Integer(178)); - encToName[178] = "a126"; - - unicodeToName.put(new Character((char) 0x2467), "a127"); - nameToUnicode.put("a127", new Character((char) 0x2467)); - nameToEnc.put("a127", new Integer(179)); - encToName[179] = "a127"; - - unicodeToName.put(new Character((char) 0x2468), "a128"); - nameToUnicode.put("a128", new Character((char) 0x2468)); - nameToEnc.put("a128", new Integer(180)); - encToName[180] = "a128"; - - unicodeToName.put(new Character((char) 0x2469), "a129"); - nameToUnicode.put("a129", new Character((char) 0x2469)); - nameToEnc.put("a129", new Integer(181)); - encToName[181] = "a129"; - - unicodeToName.put(new Character((char) 0x2776), "a130"); - nameToUnicode.put("a130", new Character((char) 0x2776)); - nameToEnc.put("a130", new Integer(182)); - encToName[182] = "a130"; - - unicodeToName.put(new Character((char) 0x2777), "a131"); - nameToUnicode.put("a131", new Character((char) 0x2777)); - nameToEnc.put("a131", new Integer(183)); - encToName[183] = "a131"; - - unicodeToName.put(new Character((char) 0x2778), "a132"); - nameToUnicode.put("a132", new Character((char) 0x2778)); - nameToEnc.put("a132", new Integer(184)); - encToName[184] = "a132"; - - unicodeToName.put(new Character((char) 0x2779), "a133"); - nameToUnicode.put("a133", new Character((char) 0x2779)); - nameToEnc.put("a133", new Integer(185)); - encToName[185] = "a133"; - - unicodeToName.put(new Character((char) 0x277a), "a134"); - nameToUnicode.put("a134", new Character((char) 0x277a)); - nameToEnc.put("a134", new Integer(186)); - encToName[186] = "a134"; - - unicodeToName.put(new Character((char) 0x277b), "a135"); - nameToUnicode.put("a135", new Character((char) 0x277b)); - nameToEnc.put("a135", new Integer(187)); - encToName[187] = "a135"; - - unicodeToName.put(new Character((char) 0x277c), "a136"); - nameToUnicode.put("a136", new Character((char) 0x277c)); - nameToEnc.put("a136", new Integer(188)); - encToName[188] = "a136"; - - unicodeToName.put(new Character((char) 0x277d), "a137"); - nameToUnicode.put("a137", new Character((char) 0x277d)); - nameToEnc.put("a137", new Integer(189)); - encToName[189] = "a137"; - - unicodeToName.put(new Character((char) 0x277e), "a138"); - nameToUnicode.put("a138", new Character((char) 0x277e)); - nameToEnc.put("a138", new Integer(190)); - encToName[190] = "a138"; - - unicodeToName.put(new Character((char) 0x277f), "a139"); - nameToUnicode.put("a139", new Character((char) 0x277f)); - nameToEnc.put("a139", new Integer(191)); - encToName[191] = "a139"; - - unicodeToName.put(new Character((char) 0x2780), "a140"); - nameToUnicode.put("a140", new Character((char) 0x2780)); - nameToEnc.put("a140", new Integer(192)); - encToName[192] = "a140"; - - unicodeToName.put(new Character((char) 0x2781), "a141"); - nameToUnicode.put("a141", new Character((char) 0x2781)); - nameToEnc.put("a141", new Integer(193)); - encToName[193] = "a141"; - - unicodeToName.put(new Character((char) 0x2782), "a142"); - nameToUnicode.put("a142", new Character((char) 0x2782)); - nameToEnc.put("a142", new Integer(194)); - encToName[194] = "a142"; - - unicodeToName.put(new Character((char) 0x2783), "a143"); - nameToUnicode.put("a143", new Character((char) 0x2783)); - nameToEnc.put("a143", new Integer(195)); - encToName[195] = "a143"; - - unicodeToName.put(new Character((char) 0x2784), "a144"); - nameToUnicode.put("a144", new Character((char) 0x2784)); - nameToEnc.put("a144", new Integer(196)); - encToName[196] = "a144"; - - unicodeToName.put(new Character((char) 0x2785), "a145"); - nameToUnicode.put("a145", new Character((char) 0x2785)); - nameToEnc.put("a145", new Integer(197)); - encToName[197] = "a145"; - - unicodeToName.put(new Character((char) 0x2786), "a146"); - nameToUnicode.put("a146", new Character((char) 0x2786)); - nameToEnc.put("a146", new Integer(198)); - encToName[198] = "a146"; - - unicodeToName.put(new Character((char) 0x2787), "a147"); - nameToUnicode.put("a147", new Character((char) 0x2787)); - nameToEnc.put("a147", new Integer(199)); - encToName[199] = "a147"; - - unicodeToName.put(new Character((char) 0x2788), "a148"); - nameToUnicode.put("a148", new Character((char) 0x2788)); - nameToEnc.put("a148", new Integer(200)); - encToName[200] = "a148"; - - unicodeToName.put(new Character((char) 0x2789), "a149"); - nameToUnicode.put("a149", new Character((char) 0x2789)); - nameToEnc.put("a149", new Integer(201)); - encToName[201] = "a149"; - - unicodeToName.put(new Character((char) 0x278a), "a150"); - nameToUnicode.put("a150", new Character((char) 0x278a)); - nameToEnc.put("a150", new Integer(202)); - encToName[202] = "a150"; - - unicodeToName.put(new Character((char) 0x278b), "a151"); - nameToUnicode.put("a151", new Character((char) 0x278b)); - nameToEnc.put("a151", new Integer(203)); - encToName[203] = "a151"; - - unicodeToName.put(new Character((char) 0x278c), "a152"); - nameToUnicode.put("a152", new Character((char) 0x278c)); - nameToEnc.put("a152", new Integer(204)); - encToName[204] = "a152"; - - unicodeToName.put(new Character((char) 0x278d), "a153"); - nameToUnicode.put("a153", new Character((char) 0x278d)); - nameToEnc.put("a153", new Integer(205)); - encToName[205] = "a153"; - - unicodeToName.put(new Character((char) 0x278e), "a154"); - nameToUnicode.put("a154", new Character((char) 0x278e)); - nameToEnc.put("a154", new Integer(206)); - encToName[206] = "a154"; - - unicodeToName.put(new Character((char) 0x278f), "a155"); - nameToUnicode.put("a155", new Character((char) 0x278f)); - nameToEnc.put("a155", new Integer(207)); - encToName[207] = "a155"; - - unicodeToName.put(new Character((char) 0x2790), "a156"); - nameToUnicode.put("a156", new Character((char) 0x2790)); - nameToEnc.put("a156", new Integer(208)); - encToName[208] = "a156"; - - unicodeToName.put(new Character((char) 0x2791), "a157"); - nameToUnicode.put("a157", new Character((char) 0x2791)); - nameToEnc.put("a157", new Integer(209)); - encToName[209] = "a157"; - - unicodeToName.put(new Character((char) 0x2792), "a158"); - nameToUnicode.put("a158", new Character((char) 0x2792)); - nameToEnc.put("a158", new Integer(210)); - encToName[210] = "a158"; - - unicodeToName.put(new Character((char) 0x2793), "a159"); - nameToUnicode.put("a159", new Character((char) 0x2793)); - nameToEnc.put("a159", new Integer(211)); - encToName[211] = "a159"; - - unicodeToName.put(new Character((char) 0x2794), "a160"); - nameToUnicode.put("a160", new Character((char) 0x2794)); - nameToEnc.put("a160", new Integer(212)); - encToName[212] = "a160"; - - unicodeToName.put(new Character((char) 0x2192), "a161"); - nameToUnicode.put("a161", new Character((char) 0x2192)); - nameToEnc.put("a161", new Integer(213)); - encToName[213] = "a161"; - - unicodeToName.put(new Character((char) 0x2194), "a163"); - nameToUnicode.put("a163", new Character((char) 0x2194)); - nameToEnc.put("a163", new Integer(214)); - encToName[214] = "a163"; - - unicodeToName.put(new Character((char) 0x2195), "a164"); - nameToUnicode.put("a164", new Character((char) 0x2195)); - nameToEnc.put("a164", new Integer(215)); - encToName[215] = "a164"; - - unicodeToName.put(new Character((char) 0x2798), "a196"); - nameToUnicode.put("a196", new Character((char) 0x2798)); - nameToEnc.put("a196", new Integer(216)); - encToName[216] = "a196"; - - unicodeToName.put(new Character((char) 0x2799), "a165"); - nameToUnicode.put("a165", new Character((char) 0x2799)); - nameToEnc.put("a165", new Integer(217)); - encToName[217] = "a165"; - - unicodeToName.put(new Character((char) 0x279a), "a192"); - nameToUnicode.put("a192", new Character((char) 0x279a)); - nameToEnc.put("a192", new Integer(218)); - encToName[218] = "a192"; - - unicodeToName.put(new Character((char) 0x279b), "a166"); - nameToUnicode.put("a166", new Character((char) 0x279b)); - nameToEnc.put("a166", new Integer(219)); - encToName[219] = "a166"; - - unicodeToName.put(new Character((char) 0x279c), "a167"); - nameToUnicode.put("a167", new Character((char) 0x279c)); - nameToEnc.put("a167", new Integer(220)); - encToName[220] = "a167"; - - unicodeToName.put(new Character((char) 0x279d), "a168"); - nameToUnicode.put("a168", new Character((char) 0x279d)); - nameToEnc.put("a168", new Integer(221)); - encToName[221] = "a168"; - - unicodeToName.put(new Character((char) 0x279e), "a169"); - nameToUnicode.put("a169", new Character((char) 0x279e)); - nameToEnc.put("a169", new Integer(222)); - encToName[222] = "a169"; - - unicodeToName.put(new Character((char) 0x279f), "a170"); - nameToUnicode.put("a170", new Character((char) 0x279f)); - nameToEnc.put("a170", new Integer(223)); - encToName[223] = "a170"; - - unicodeToName.put(new Character((char) 0x27a0), "a171"); - nameToUnicode.put("a171", new Character((char) 0x27a0)); - nameToEnc.put("a171", new Integer(224)); - encToName[224] = "a171"; - - unicodeToName.put(new Character((char) 0x27a1), "a172"); - nameToUnicode.put("a172", new Character((char) 0x27a1)); - nameToEnc.put("a172", new Integer(225)); - encToName[225] = "a172"; - - unicodeToName.put(new Character((char) 0x27a2), "a173"); - nameToUnicode.put("a173", new Character((char) 0x27a2)); - nameToEnc.put("a173", new Integer(226)); - encToName[226] = "a173"; - - unicodeToName.put(new Character((char) 0x27a3), "a162"); - nameToUnicode.put("a162", new Character((char) 0x27a3)); - nameToEnc.put("a162", new Integer(227)); - encToName[227] = "a162"; - - unicodeToName.put(new Character((char) 0x27a4), "a174"); - nameToUnicode.put("a174", new Character((char) 0x27a4)); - nameToEnc.put("a174", new Integer(228)); - encToName[228] = "a174"; - - unicodeToName.put(new Character((char) 0x27a5), "a175"); - nameToUnicode.put("a175", new Character((char) 0x27a5)); - nameToEnc.put("a175", new Integer(229)); - encToName[229] = "a175"; - - unicodeToName.put(new Character((char) 0x27a6), "a176"); - nameToUnicode.put("a176", new Character((char) 0x27a6)); - nameToEnc.put("a176", new Integer(230)); - encToName[230] = "a176"; - - unicodeToName.put(new Character((char) 0x27a7), "a177"); - nameToUnicode.put("a177", new Character((char) 0x27a7)); - nameToEnc.put("a177", new Integer(231)); - encToName[231] = "a177"; - - unicodeToName.put(new Character((char) 0x27a8), "a178"); - nameToUnicode.put("a178", new Character((char) 0x27a8)); - nameToEnc.put("a178", new Integer(232)); - encToName[232] = "a178"; - - unicodeToName.put(new Character((char) 0x27a9), "a179"); - nameToUnicode.put("a179", new Character((char) 0x27a9)); - nameToEnc.put("a179", new Integer(233)); - encToName[233] = "a179"; - - unicodeToName.put(new Character((char) 0x27aa), "a193"); - nameToUnicode.put("a193", new Character((char) 0x27aa)); - nameToEnc.put("a193", new Integer(234)); - encToName[234] = "a193"; - - unicodeToName.put(new Character((char) 0x27ab), "a180"); - nameToUnicode.put("a180", new Character((char) 0x27ab)); - nameToEnc.put("a180", new Integer(235)); - encToName[235] = "a180"; - - unicodeToName.put(new Character((char) 0x27ac), "a199"); - nameToUnicode.put("a199", new Character((char) 0x27ac)); - nameToEnc.put("a199", new Integer(236)); - encToName[236] = "a199"; - - unicodeToName.put(new Character((char) 0x27ad), "a181"); - nameToUnicode.put("a181", new Character((char) 0x27ad)); - nameToEnc.put("a181", new Integer(237)); - encToName[237] = "a181"; - - unicodeToName.put(new Character((char) 0x27ae), "a200"); - nameToUnicode.put("a200", new Character((char) 0x27ae)); - nameToEnc.put("a200", new Integer(238)); - encToName[238] = "a200"; - - unicodeToName.put(new Character((char) 0x27af), "a182"); - nameToUnicode.put("a182", new Character((char) 0x27af)); - nameToEnc.put("a182", new Integer(239)); - encToName[239] = "a182"; - - unicodeToName.put(new Character((char) 0x27b1), "a201"); - nameToUnicode.put("a201", new Character((char) 0x27b1)); - nameToEnc.put("a201", new Integer(241)); - encToName[241] = "a201"; - - unicodeToName.put(new Character((char) 0x27b2), "a183"); - nameToUnicode.put("a183", new Character((char) 0x27b2)); - nameToEnc.put("a183", new Integer(242)); - encToName[242] = "a183"; - - unicodeToName.put(new Character((char) 0x27b3), "a184"); - nameToUnicode.put("a184", new Character((char) 0x27b3)); - nameToEnc.put("a184", new Integer(243)); - encToName[243] = "a184"; - - unicodeToName.put(new Character((char) 0x27b4), "a197"); - nameToUnicode.put("a197", new Character((char) 0x27b4)); - nameToEnc.put("a197", new Integer(244)); - encToName[244] = "a197"; - - unicodeToName.put(new Character((char) 0x27b5), "a185"); - nameToUnicode.put("a185", new Character((char) 0x27b5)); - nameToEnc.put("a185", new Integer(245)); - encToName[245] = "a185"; - - unicodeToName.put(new Character((char) 0x27b6), "a194"); - nameToUnicode.put("a194", new Character((char) 0x27b6)); - nameToEnc.put("a194", new Integer(246)); - encToName[246] = "a194"; - - unicodeToName.put(new Character((char) 0x27b7), "a198"); - nameToUnicode.put("a198", new Character((char) 0x27b7)); - nameToEnc.put("a198", new Integer(247)); - encToName[247] = "a198"; - - unicodeToName.put(new Character((char) 0x27b8), "a186"); - nameToUnicode.put("a186", new Character((char) 0x27b8)); - nameToEnc.put("a186", new Integer(248)); - encToName[248] = "a186"; - - unicodeToName.put(new Character((char) 0x27b9), "a195"); - nameToUnicode.put("a195", new Character((char) 0x27b9)); - nameToEnc.put("a195", new Integer(249)); - encToName[249] = "a195"; - - unicodeToName.put(new Character((char) 0x27ba), "a187"); - nameToUnicode.put("a187", new Character((char) 0x27ba)); - nameToEnc.put("a187", new Integer(250)); - encToName[250] = "a187"; - - unicodeToName.put(new Character((char) 0x27bb), "a188"); - nameToUnicode.put("a188", new Character((char) 0x27bb)); - nameToEnc.put("a188", new Integer(251)); - encToName[251] = "a188"; - - unicodeToName.put(new Character((char) 0x27bc), "a189"); - nameToUnicode.put("a189", new Character((char) 0x27bc)); - nameToEnc.put("a189", new Integer(252)); - encToName[252] = "a189"; - - unicodeToName.put(new Character((char) 0x27bd), "a190"); - nameToUnicode.put("a190", new Character((char) 0x27bd)); - nameToEnc.put("a190", new Integer(253)); - encToName[253] = "a190"; - - unicodeToName.put(new Character((char) 0x27be), "a191"); - nameToUnicode.put("a191", new Character((char) 0x27be)); - nameToEnc.put("a191", new Integer(254)); - encToName[254] = "a191"; - - } - - public String toName(Character c) { - return ((String) unicodeToName.get(c)); - } - - public String toName(int enc) { - if (enc != 0) - return (encToName[enc]); - return (null); - } - - public int toEncoding(String name) { - return (((Integer) (nameToEnc.get(name))).intValue()); - } - - public char toUnicode(String name) { - return (((Character) (nameToUnicode.get(name))).charValue()); - } - - public String getName() { - return ("Zapfdingbats");//$NON-NLS-1$ - } - - public String getEncoding() { - return ("");//$NON-NLS-1$ - } - -} +//Generated by CharTableConverter +//!!DO NOT EDIT +package org.xmind.org.freehep.graphics2d.font; + +import java.util.Hashtable; + +/** + * Generated Zapfdingbats Encoding Table. + * + * @author org.xmind.org.freehep.graphics2d.font.CharTableConverter + * @author Jason Wong + */ +public class Zapfdingbats extends AbstractCharTable { + private Hashtable unicodeToName = new Hashtable(); + private Hashtable nameToUnicode = new Hashtable(); + private Hashtable nameToEnc = new Hashtable(); + private String[] encToName = new String[256]; + + @SuppressWarnings("nls") + public Zapfdingbats() { + unicodeToName.put(new Character((char) 0x0020), "space"); + nameToUnicode.put("space", new Character((char) 0x0020)); + nameToEnc.put("space", new Integer(32)); + encToName[32] = "space"; + + unicodeToName.put(new Character((char) 0x2701), "a1"); + nameToUnicode.put("a1", new Character((char) 0x2701)); + nameToEnc.put("a1", new Integer(33)); + encToName[33] = "a1"; + + unicodeToName.put(new Character((char) 0x2702), "a2"); + nameToUnicode.put("a2", new Character((char) 0x2702)); + nameToEnc.put("a2", new Integer(34)); + encToName[34] = "a2"; + + unicodeToName.put(new Character((char) 0x2703), "a202"); + nameToUnicode.put("a202", new Character((char) 0x2703)); + nameToEnc.put("a202", new Integer(35)); + encToName[35] = "a202"; + + unicodeToName.put(new Character((char) 0x2704), "a3"); + nameToUnicode.put("a3", new Character((char) 0x2704)); + nameToEnc.put("a3", new Integer(36)); + encToName[36] = "a3"; + + unicodeToName.put(new Character((char) 0x260e), "a4"); + nameToUnicode.put("a4", new Character((char) 0x260e)); + nameToEnc.put("a4", new Integer(37)); + encToName[37] = "a4"; + + unicodeToName.put(new Character((char) 0x2706), "a5"); + nameToUnicode.put("a5", new Character((char) 0x2706)); + nameToEnc.put("a5", new Integer(38)); + encToName[38] = "a5"; + + unicodeToName.put(new Character((char) 0x2707), "a119"); + nameToUnicode.put("a119", new Character((char) 0x2707)); + nameToEnc.put("a119", new Integer(39)); + encToName[39] = "a119"; + + unicodeToName.put(new Character((char) 0x2708), "a118"); + nameToUnicode.put("a118", new Character((char) 0x2708)); + nameToEnc.put("a118", new Integer(40)); + encToName[40] = "a118"; + + unicodeToName.put(new Character((char) 0x2709), "a117"); + nameToUnicode.put("a117", new Character((char) 0x2709)); + nameToEnc.put("a117", new Integer(41)); + encToName[41] = "a117"; + + unicodeToName.put(new Character((char) 0x261b), "a11"); + nameToUnicode.put("a11", new Character((char) 0x261b)); + nameToEnc.put("a11", new Integer(42)); + encToName[42] = "a11"; + + unicodeToName.put(new Character((char) 0x261e), "a12"); + nameToUnicode.put("a12", new Character((char) 0x261e)); + nameToEnc.put("a12", new Integer(43)); + encToName[43] = "a12"; + + unicodeToName.put(new Character((char) 0x270c), "a13"); + nameToUnicode.put("a13", new Character((char) 0x270c)); + nameToEnc.put("a13", new Integer(44)); + encToName[44] = "a13"; + + unicodeToName.put(new Character((char) 0x270d), "a14"); + nameToUnicode.put("a14", new Character((char) 0x270d)); + nameToEnc.put("a14", new Integer(45)); + encToName[45] = "a14"; + + unicodeToName.put(new Character((char) 0x270e), "a15"); + nameToUnicode.put("a15", new Character((char) 0x270e)); + nameToEnc.put("a15", new Integer(46)); + encToName[46] = "a15"; + + unicodeToName.put(new Character((char) 0x270f), "a16"); + nameToUnicode.put("a16", new Character((char) 0x270f)); + nameToEnc.put("a16", new Integer(47)); + encToName[47] = "a16"; + + unicodeToName.put(new Character((char) 0x2710), "a105"); + nameToUnicode.put("a105", new Character((char) 0x2710)); + nameToEnc.put("a105", new Integer(48)); + encToName[48] = "a105"; + + unicodeToName.put(new Character((char) 0x2711), "a17"); + nameToUnicode.put("a17", new Character((char) 0x2711)); + nameToEnc.put("a17", new Integer(49)); + encToName[49] = "a17"; + + unicodeToName.put(new Character((char) 0x2712), "a18"); + nameToUnicode.put("a18", new Character((char) 0x2712)); + nameToEnc.put("a18", new Integer(50)); + encToName[50] = "a18"; + + unicodeToName.put(new Character((char) 0x2713), "a19"); + nameToUnicode.put("a19", new Character((char) 0x2713)); + nameToEnc.put("a19", new Integer(51)); + encToName[51] = "a19"; + + unicodeToName.put(new Character((char) 0x2714), "a20"); + nameToUnicode.put("a20", new Character((char) 0x2714)); + nameToEnc.put("a20", new Integer(52)); + encToName[52] = "a20"; + + unicodeToName.put(new Character((char) 0x2715), "a21"); + nameToUnicode.put("a21", new Character((char) 0x2715)); + nameToEnc.put("a21", new Integer(53)); + encToName[53] = "a21"; + + unicodeToName.put(new Character((char) 0x2716), "a22"); + nameToUnicode.put("a22", new Character((char) 0x2716)); + nameToEnc.put("a22", new Integer(54)); + encToName[54] = "a22"; + + unicodeToName.put(new Character((char) 0x2717), "a23"); + nameToUnicode.put("a23", new Character((char) 0x2717)); + nameToEnc.put("a23", new Integer(55)); + encToName[55] = "a23"; + + unicodeToName.put(new Character((char) 0x2718), "a24"); + nameToUnicode.put("a24", new Character((char) 0x2718)); + nameToEnc.put("a24", new Integer(56)); + encToName[56] = "a24"; + + unicodeToName.put(new Character((char) 0x2719), "a25"); + nameToUnicode.put("a25", new Character((char) 0x2719)); + nameToEnc.put("a25", new Integer(57)); + encToName[57] = "a25"; + + unicodeToName.put(new Character((char) 0x271a), "a26"); + nameToUnicode.put("a26", new Character((char) 0x271a)); + nameToEnc.put("a26", new Integer(58)); + encToName[58] = "a26"; + + unicodeToName.put(new Character((char) 0x271b), "a27"); + nameToUnicode.put("a27", new Character((char) 0x271b)); + nameToEnc.put("a27", new Integer(59)); + encToName[59] = "a27"; + + unicodeToName.put(new Character((char) 0x271c), "a28"); + nameToUnicode.put("a28", new Character((char) 0x271c)); + nameToEnc.put("a28", new Integer(60)); + encToName[60] = "a28"; + + unicodeToName.put(new Character((char) 0x271d), "a6"); + nameToUnicode.put("a6", new Character((char) 0x271d)); + nameToEnc.put("a6", new Integer(61)); + encToName[61] = "a6"; + + unicodeToName.put(new Character((char) 0x271e), "a7"); + nameToUnicode.put("a7", new Character((char) 0x271e)); + nameToEnc.put("a7", new Integer(62)); + encToName[62] = "a7"; + + unicodeToName.put(new Character((char) 0x271f), "a8"); + nameToUnicode.put("a8", new Character((char) 0x271f)); + nameToEnc.put("a8", new Integer(63)); + encToName[63] = "a8"; + + unicodeToName.put(new Character((char) 0x2720), "a9"); + nameToUnicode.put("a9", new Character((char) 0x2720)); + nameToEnc.put("a9", new Integer(64)); + encToName[64] = "a9"; + + unicodeToName.put(new Character((char) 0x2721), "a10"); + nameToUnicode.put("a10", new Character((char) 0x2721)); + nameToEnc.put("a10", new Integer(65)); + encToName[65] = "a10"; + + unicodeToName.put(new Character((char) 0x2722), "a29"); + nameToUnicode.put("a29", new Character((char) 0x2722)); + nameToEnc.put("a29", new Integer(66)); + encToName[66] = "a29"; + + unicodeToName.put(new Character((char) 0x2723), "a30"); + nameToUnicode.put("a30", new Character((char) 0x2723)); + nameToEnc.put("a30", new Integer(67)); + encToName[67] = "a30"; + + unicodeToName.put(new Character((char) 0x2724), "a31"); + nameToUnicode.put("a31", new Character((char) 0x2724)); + nameToEnc.put("a31", new Integer(68)); + encToName[68] = "a31"; + + unicodeToName.put(new Character((char) 0x2725), "a32"); + nameToUnicode.put("a32", new Character((char) 0x2725)); + nameToEnc.put("a32", new Integer(69)); + encToName[69] = "a32"; + + unicodeToName.put(new Character((char) 0x2726), "a33"); + nameToUnicode.put("a33", new Character((char) 0x2726)); + nameToEnc.put("a33", new Integer(70)); + encToName[70] = "a33"; + + unicodeToName.put(new Character((char) 0x2727), "a34"); + nameToUnicode.put("a34", new Character((char) 0x2727)); + nameToEnc.put("a34", new Integer(71)); + encToName[71] = "a34"; + + unicodeToName.put(new Character((char) 0x2605), "a35"); + nameToUnicode.put("a35", new Character((char) 0x2605)); + nameToEnc.put("a35", new Integer(72)); + encToName[72] = "a35"; + + unicodeToName.put(new Character((char) 0x2729), "a36"); + nameToUnicode.put("a36", new Character((char) 0x2729)); + nameToEnc.put("a36", new Integer(73)); + encToName[73] = "a36"; + + unicodeToName.put(new Character((char) 0x272a), "a37"); + nameToUnicode.put("a37", new Character((char) 0x272a)); + nameToEnc.put("a37", new Integer(74)); + encToName[74] = "a37"; + + unicodeToName.put(new Character((char) 0x272b), "a38"); + nameToUnicode.put("a38", new Character((char) 0x272b)); + nameToEnc.put("a38", new Integer(75)); + encToName[75] = "a38"; + + unicodeToName.put(new Character((char) 0x272c), "a39"); + nameToUnicode.put("a39", new Character((char) 0x272c)); + nameToEnc.put("a39", new Integer(76)); + encToName[76] = "a39"; + + unicodeToName.put(new Character((char) 0x272d), "a40"); + nameToUnicode.put("a40", new Character((char) 0x272d)); + nameToEnc.put("a40", new Integer(77)); + encToName[77] = "a40"; + + unicodeToName.put(new Character((char) 0x272e), "a41"); + nameToUnicode.put("a41", new Character((char) 0x272e)); + nameToEnc.put("a41", new Integer(78)); + encToName[78] = "a41"; + + unicodeToName.put(new Character((char) 0x272f), "a42"); + nameToUnicode.put("a42", new Character((char) 0x272f)); + nameToEnc.put("a42", new Integer(79)); + encToName[79] = "a42"; + + unicodeToName.put(new Character((char) 0x2730), "a43"); + nameToUnicode.put("a43", new Character((char) 0x2730)); + nameToEnc.put("a43", new Integer(80)); + encToName[80] = "a43"; + + unicodeToName.put(new Character((char) 0x2731), "a44"); + nameToUnicode.put("a44", new Character((char) 0x2731)); + nameToEnc.put("a44", new Integer(81)); + encToName[81] = "a44"; + + unicodeToName.put(new Character((char) 0x2732), "a45"); + nameToUnicode.put("a45", new Character((char) 0x2732)); + nameToEnc.put("a45", new Integer(82)); + encToName[82] = "a45"; + + unicodeToName.put(new Character((char) 0x2733), "a46"); + nameToUnicode.put("a46", new Character((char) 0x2733)); + nameToEnc.put("a46", new Integer(83)); + encToName[83] = "a46"; + + unicodeToName.put(new Character((char) 0x2734), "a47"); + nameToUnicode.put("a47", new Character((char) 0x2734)); + nameToEnc.put("a47", new Integer(84)); + encToName[84] = "a47"; + + unicodeToName.put(new Character((char) 0x2735), "a48"); + nameToUnicode.put("a48", new Character((char) 0x2735)); + nameToEnc.put("a48", new Integer(85)); + encToName[85] = "a48"; + + unicodeToName.put(new Character((char) 0x2736), "a49"); + nameToUnicode.put("a49", new Character((char) 0x2736)); + nameToEnc.put("a49", new Integer(86)); + encToName[86] = "a49"; + + unicodeToName.put(new Character((char) 0x2737), "a50"); + nameToUnicode.put("a50", new Character((char) 0x2737)); + nameToEnc.put("a50", new Integer(87)); + encToName[87] = "a50"; + + unicodeToName.put(new Character((char) 0x2738), "a51"); + nameToUnicode.put("a51", new Character((char) 0x2738)); + nameToEnc.put("a51", new Integer(88)); + encToName[88] = "a51"; + + unicodeToName.put(new Character((char) 0x2739), "a52"); + nameToUnicode.put("a52", new Character((char) 0x2739)); + nameToEnc.put("a52", new Integer(89)); + encToName[89] = "a52"; + + unicodeToName.put(new Character((char) 0x273a), "a53"); + nameToUnicode.put("a53", new Character((char) 0x273a)); + nameToEnc.put("a53", new Integer(90)); + encToName[90] = "a53"; + + unicodeToName.put(new Character((char) 0x273b), "a54"); + nameToUnicode.put("a54", new Character((char) 0x273b)); + nameToEnc.put("a54", new Integer(91)); + encToName[91] = "a54"; + + unicodeToName.put(new Character((char) 0x273c), "a55"); + nameToUnicode.put("a55", new Character((char) 0x273c)); + nameToEnc.put("a55", new Integer(92)); + encToName[92] = "a55"; + + unicodeToName.put(new Character((char) 0x273d), "a56"); + nameToUnicode.put("a56", new Character((char) 0x273d)); + nameToEnc.put("a56", new Integer(93)); + encToName[93] = "a56"; + + unicodeToName.put(new Character((char) 0x273e), "a57"); + nameToUnicode.put("a57", new Character((char) 0x273e)); + nameToEnc.put("a57", new Integer(94)); + encToName[94] = "a57"; + + unicodeToName.put(new Character((char) 0x273f), "a58"); + nameToUnicode.put("a58", new Character((char) 0x273f)); + nameToEnc.put("a58", new Integer(95)); + encToName[95] = "a58"; + + unicodeToName.put(new Character((char) 0x2740), "a59"); + nameToUnicode.put("a59", new Character((char) 0x2740)); + nameToEnc.put("a59", new Integer(96)); + encToName[96] = "a59"; + + unicodeToName.put(new Character((char) 0x2741), "a60"); + nameToUnicode.put("a60", new Character((char) 0x2741)); + nameToEnc.put("a60", new Integer(97)); + encToName[97] = "a60"; + + unicodeToName.put(new Character((char) 0x2742), "a61"); + nameToUnicode.put("a61", new Character((char) 0x2742)); + nameToEnc.put("a61", new Integer(98)); + encToName[98] = "a61"; + + unicodeToName.put(new Character((char) 0x2743), "a62"); + nameToUnicode.put("a62", new Character((char) 0x2743)); + nameToEnc.put("a62", new Integer(99)); + encToName[99] = "a62"; + + unicodeToName.put(new Character((char) 0x2744), "a63"); + nameToUnicode.put("a63", new Character((char) 0x2744)); + nameToEnc.put("a63", new Integer(100)); + encToName[100] = "a63"; + + unicodeToName.put(new Character((char) 0x2745), "a64"); + nameToUnicode.put("a64", new Character((char) 0x2745)); + nameToEnc.put("a64", new Integer(101)); + encToName[101] = "a64"; + + unicodeToName.put(new Character((char) 0x2746), "a65"); + nameToUnicode.put("a65", new Character((char) 0x2746)); + nameToEnc.put("a65", new Integer(102)); + encToName[102] = "a65"; + + unicodeToName.put(new Character((char) 0x2747), "a66"); + nameToUnicode.put("a66", new Character((char) 0x2747)); + nameToEnc.put("a66", new Integer(103)); + encToName[103] = "a66"; + + unicodeToName.put(new Character((char) 0x2748), "a67"); + nameToUnicode.put("a67", new Character((char) 0x2748)); + nameToEnc.put("a67", new Integer(104)); + encToName[104] = "a67"; + + unicodeToName.put(new Character((char) 0x2749), "a68"); + nameToUnicode.put("a68", new Character((char) 0x2749)); + nameToEnc.put("a68", new Integer(105)); + encToName[105] = "a68"; + + unicodeToName.put(new Character((char) 0x274a), "a69"); + nameToUnicode.put("a69", new Character((char) 0x274a)); + nameToEnc.put("a69", new Integer(106)); + encToName[106] = "a69"; + + unicodeToName.put(new Character((char) 0x274b), "a70"); + nameToUnicode.put("a70", new Character((char) 0x274b)); + nameToEnc.put("a70", new Integer(107)); + encToName[107] = "a70"; + + unicodeToName.put(new Character((char) 0x25cf), "a71"); + nameToUnicode.put("a71", new Character((char) 0x25cf)); + nameToEnc.put("a71", new Integer(108)); + encToName[108] = "a71"; + + unicodeToName.put(new Character((char) 0x274d), "a72"); + nameToUnicode.put("a72", new Character((char) 0x274d)); + nameToEnc.put("a72", new Integer(109)); + encToName[109] = "a72"; + + unicodeToName.put(new Character((char) 0x25a0), "a73"); + nameToUnicode.put("a73", new Character((char) 0x25a0)); + nameToEnc.put("a73", new Integer(110)); + encToName[110] = "a73"; + + unicodeToName.put(new Character((char) 0x274f), "a74"); + nameToUnicode.put("a74", new Character((char) 0x274f)); + nameToEnc.put("a74", new Integer(111)); + encToName[111] = "a74"; + + unicodeToName.put(new Character((char) 0x2750), "a203"); + nameToUnicode.put("a203", new Character((char) 0x2750)); + nameToEnc.put("a203", new Integer(112)); + encToName[112] = "a203"; + + unicodeToName.put(new Character((char) 0x2751), "a75"); + nameToUnicode.put("a75", new Character((char) 0x2751)); + nameToEnc.put("a75", new Integer(113)); + encToName[113] = "a75"; + + unicodeToName.put(new Character((char) 0x2752), "a204"); + nameToUnicode.put("a204", new Character((char) 0x2752)); + nameToEnc.put("a204", new Integer(114)); + encToName[114] = "a204"; + + unicodeToName.put(new Character((char) 0x25b2), "a76"); + nameToUnicode.put("a76", new Character((char) 0x25b2)); + nameToEnc.put("a76", new Integer(115)); + encToName[115] = "a76"; + + unicodeToName.put(new Character((char) 0x25bc), "a77"); + nameToUnicode.put("a77", new Character((char) 0x25bc)); + nameToEnc.put("a77", new Integer(116)); + encToName[116] = "a77"; + + unicodeToName.put(new Character((char) 0x25c6), "a78"); + nameToUnicode.put("a78", new Character((char) 0x25c6)); + nameToEnc.put("a78", new Integer(117)); + encToName[117] = "a78"; + + unicodeToName.put(new Character((char) 0x2756), "a79"); + nameToUnicode.put("a79", new Character((char) 0x2756)); + nameToEnc.put("a79", new Integer(118)); + encToName[118] = "a79"; + + unicodeToName.put(new Character((char) 0x25d7), "a81"); + nameToUnicode.put("a81", new Character((char) 0x25d7)); + nameToEnc.put("a81", new Integer(119)); + encToName[119] = "a81"; + + unicodeToName.put(new Character((char) 0x2758), "a82"); + nameToUnicode.put("a82", new Character((char) 0x2758)); + nameToEnc.put("a82", new Integer(120)); + encToName[120] = "a82"; + + unicodeToName.put(new Character((char) 0x2759), "a83"); + nameToUnicode.put("a83", new Character((char) 0x2759)); + nameToEnc.put("a83", new Integer(121)); + encToName[121] = "a83"; + + unicodeToName.put(new Character((char) 0x275a), "a84"); + nameToUnicode.put("a84", new Character((char) 0x275a)); + nameToEnc.put("a84", new Integer(122)); + encToName[122] = "a84"; + + unicodeToName.put(new Character((char) 0x275b), "a97"); + nameToUnicode.put("a97", new Character((char) 0x275b)); + nameToEnc.put("a97", new Integer(123)); + encToName[123] = "a97"; + + unicodeToName.put(new Character((char) 0x275c), "a98"); + nameToUnicode.put("a98", new Character((char) 0x275c)); + nameToEnc.put("a98", new Integer(124)); + encToName[124] = "a98"; + + unicodeToName.put(new Character((char) 0x275d), "a99"); + nameToUnicode.put("a99", new Character((char) 0x275d)); + nameToEnc.put("a99", new Integer(125)); + encToName[125] = "a99"; + + unicodeToName.put(new Character((char) 0x275e), "a100"); + nameToUnicode.put("a100", new Character((char) 0x275e)); + nameToEnc.put("a100", new Integer(126)); + encToName[126] = "a100"; + + unicodeToName.put(new Character((char) 0x2761), "a101"); + nameToUnicode.put("a101", new Character((char) 0x2761)); + nameToEnc.put("a101", new Integer(161)); + encToName[161] = "a101"; + + unicodeToName.put(new Character((char) 0x2762), "a102"); + nameToUnicode.put("a102", new Character((char) 0x2762)); + nameToEnc.put("a102", new Integer(162)); + encToName[162] = "a102"; + + unicodeToName.put(new Character((char) 0x2763), "a103"); + nameToUnicode.put("a103", new Character((char) 0x2763)); + nameToEnc.put("a103", new Integer(163)); + encToName[163] = "a103"; + + unicodeToName.put(new Character((char) 0x2764), "a104"); + nameToUnicode.put("a104", new Character((char) 0x2764)); + nameToEnc.put("a104", new Integer(164)); + encToName[164] = "a104"; + + unicodeToName.put(new Character((char) 0x2765), "a106"); + nameToUnicode.put("a106", new Character((char) 0x2765)); + nameToEnc.put("a106", new Integer(165)); + encToName[165] = "a106"; + + unicodeToName.put(new Character((char) 0x2766), "a107"); + nameToUnicode.put("a107", new Character((char) 0x2766)); + nameToEnc.put("a107", new Integer(166)); + encToName[166] = "a107"; + + unicodeToName.put(new Character((char) 0x2767), "a108"); + nameToUnicode.put("a108", new Character((char) 0x2767)); + nameToEnc.put("a108", new Integer(167)); + encToName[167] = "a108"; + + unicodeToName.put(new Character((char) 0x2663), "a112"); + nameToUnicode.put("a112", new Character((char) 0x2663)); + nameToEnc.put("a112", new Integer(168)); + encToName[168] = "a112"; + + unicodeToName.put(new Character((char) 0x2666), "a111"); + nameToUnicode.put("a111", new Character((char) 0x2666)); + nameToEnc.put("a111", new Integer(169)); + encToName[169] = "a111"; + + unicodeToName.put(new Character((char) 0x2665), "a110"); + nameToUnicode.put("a110", new Character((char) 0x2665)); + nameToEnc.put("a110", new Integer(170)); + encToName[170] = "a110"; + + unicodeToName.put(new Character((char) 0x2660), "a109"); + nameToUnicode.put("a109", new Character((char) 0x2660)); + nameToEnc.put("a109", new Integer(171)); + encToName[171] = "a109"; + + unicodeToName.put(new Character((char) 0x2460), "a120"); + nameToUnicode.put("a120", new Character((char) 0x2460)); + nameToEnc.put("a120", new Integer(172)); + encToName[172] = "a120"; + + unicodeToName.put(new Character((char) 0x2461), "a121"); + nameToUnicode.put("a121", new Character((char) 0x2461)); + nameToEnc.put("a121", new Integer(173)); + encToName[173] = "a121"; + + unicodeToName.put(new Character((char) 0x2462), "a122"); + nameToUnicode.put("a122", new Character((char) 0x2462)); + nameToEnc.put("a122", new Integer(174)); + encToName[174] = "a122"; + + unicodeToName.put(new Character((char) 0x2463), "a123"); + nameToUnicode.put("a123", new Character((char) 0x2463)); + nameToEnc.put("a123", new Integer(175)); + encToName[175] = "a123"; + + unicodeToName.put(new Character((char) 0x2464), "a124"); + nameToUnicode.put("a124", new Character((char) 0x2464)); + nameToEnc.put("a124", new Integer(176)); + encToName[176] = "a124"; + + unicodeToName.put(new Character((char) 0x2465), "a125"); + nameToUnicode.put("a125", new Character((char) 0x2465)); + nameToEnc.put("a125", new Integer(177)); + encToName[177] = "a125"; + + unicodeToName.put(new Character((char) 0x2466), "a126"); + nameToUnicode.put("a126", new Character((char) 0x2466)); + nameToEnc.put("a126", new Integer(178)); + encToName[178] = "a126"; + + unicodeToName.put(new Character((char) 0x2467), "a127"); + nameToUnicode.put("a127", new Character((char) 0x2467)); + nameToEnc.put("a127", new Integer(179)); + encToName[179] = "a127"; + + unicodeToName.put(new Character((char) 0x2468), "a128"); + nameToUnicode.put("a128", new Character((char) 0x2468)); + nameToEnc.put("a128", new Integer(180)); + encToName[180] = "a128"; + + unicodeToName.put(new Character((char) 0x2469), "a129"); + nameToUnicode.put("a129", new Character((char) 0x2469)); + nameToEnc.put("a129", new Integer(181)); + encToName[181] = "a129"; + + unicodeToName.put(new Character((char) 0x2776), "a130"); + nameToUnicode.put("a130", new Character((char) 0x2776)); + nameToEnc.put("a130", new Integer(182)); + encToName[182] = "a130"; + + unicodeToName.put(new Character((char) 0x2777), "a131"); + nameToUnicode.put("a131", new Character((char) 0x2777)); + nameToEnc.put("a131", new Integer(183)); + encToName[183] = "a131"; + + unicodeToName.put(new Character((char) 0x2778), "a132"); + nameToUnicode.put("a132", new Character((char) 0x2778)); + nameToEnc.put("a132", new Integer(184)); + encToName[184] = "a132"; + + unicodeToName.put(new Character((char) 0x2779), "a133"); + nameToUnicode.put("a133", new Character((char) 0x2779)); + nameToEnc.put("a133", new Integer(185)); + encToName[185] = "a133"; + + unicodeToName.put(new Character((char) 0x277a), "a134"); + nameToUnicode.put("a134", new Character((char) 0x277a)); + nameToEnc.put("a134", new Integer(186)); + encToName[186] = "a134"; + + unicodeToName.put(new Character((char) 0x277b), "a135"); + nameToUnicode.put("a135", new Character((char) 0x277b)); + nameToEnc.put("a135", new Integer(187)); + encToName[187] = "a135"; + + unicodeToName.put(new Character((char) 0x277c), "a136"); + nameToUnicode.put("a136", new Character((char) 0x277c)); + nameToEnc.put("a136", new Integer(188)); + encToName[188] = "a136"; + + unicodeToName.put(new Character((char) 0x277d), "a137"); + nameToUnicode.put("a137", new Character((char) 0x277d)); + nameToEnc.put("a137", new Integer(189)); + encToName[189] = "a137"; + + unicodeToName.put(new Character((char) 0x277e), "a138"); + nameToUnicode.put("a138", new Character((char) 0x277e)); + nameToEnc.put("a138", new Integer(190)); + encToName[190] = "a138"; + + unicodeToName.put(new Character((char) 0x277f), "a139"); + nameToUnicode.put("a139", new Character((char) 0x277f)); + nameToEnc.put("a139", new Integer(191)); + encToName[191] = "a139"; + + unicodeToName.put(new Character((char) 0x2780), "a140"); + nameToUnicode.put("a140", new Character((char) 0x2780)); + nameToEnc.put("a140", new Integer(192)); + encToName[192] = "a140"; + + unicodeToName.put(new Character((char) 0x2781), "a141"); + nameToUnicode.put("a141", new Character((char) 0x2781)); + nameToEnc.put("a141", new Integer(193)); + encToName[193] = "a141"; + + unicodeToName.put(new Character((char) 0x2782), "a142"); + nameToUnicode.put("a142", new Character((char) 0x2782)); + nameToEnc.put("a142", new Integer(194)); + encToName[194] = "a142"; + + unicodeToName.put(new Character((char) 0x2783), "a143"); + nameToUnicode.put("a143", new Character((char) 0x2783)); + nameToEnc.put("a143", new Integer(195)); + encToName[195] = "a143"; + + unicodeToName.put(new Character((char) 0x2784), "a144"); + nameToUnicode.put("a144", new Character((char) 0x2784)); + nameToEnc.put("a144", new Integer(196)); + encToName[196] = "a144"; + + unicodeToName.put(new Character((char) 0x2785), "a145"); + nameToUnicode.put("a145", new Character((char) 0x2785)); + nameToEnc.put("a145", new Integer(197)); + encToName[197] = "a145"; + + unicodeToName.put(new Character((char) 0x2786), "a146"); + nameToUnicode.put("a146", new Character((char) 0x2786)); + nameToEnc.put("a146", new Integer(198)); + encToName[198] = "a146"; + + unicodeToName.put(new Character((char) 0x2787), "a147"); + nameToUnicode.put("a147", new Character((char) 0x2787)); + nameToEnc.put("a147", new Integer(199)); + encToName[199] = "a147"; + + unicodeToName.put(new Character((char) 0x2788), "a148"); + nameToUnicode.put("a148", new Character((char) 0x2788)); + nameToEnc.put("a148", new Integer(200)); + encToName[200] = "a148"; + + unicodeToName.put(new Character((char) 0x2789), "a149"); + nameToUnicode.put("a149", new Character((char) 0x2789)); + nameToEnc.put("a149", new Integer(201)); + encToName[201] = "a149"; + + unicodeToName.put(new Character((char) 0x278a), "a150"); + nameToUnicode.put("a150", new Character((char) 0x278a)); + nameToEnc.put("a150", new Integer(202)); + encToName[202] = "a150"; + + unicodeToName.put(new Character((char) 0x278b), "a151"); + nameToUnicode.put("a151", new Character((char) 0x278b)); + nameToEnc.put("a151", new Integer(203)); + encToName[203] = "a151"; + + unicodeToName.put(new Character((char) 0x278c), "a152"); + nameToUnicode.put("a152", new Character((char) 0x278c)); + nameToEnc.put("a152", new Integer(204)); + encToName[204] = "a152"; + + unicodeToName.put(new Character((char) 0x278d), "a153"); + nameToUnicode.put("a153", new Character((char) 0x278d)); + nameToEnc.put("a153", new Integer(205)); + encToName[205] = "a153"; + + unicodeToName.put(new Character((char) 0x278e), "a154"); + nameToUnicode.put("a154", new Character((char) 0x278e)); + nameToEnc.put("a154", new Integer(206)); + encToName[206] = "a154"; + + unicodeToName.put(new Character((char) 0x278f), "a155"); + nameToUnicode.put("a155", new Character((char) 0x278f)); + nameToEnc.put("a155", new Integer(207)); + encToName[207] = "a155"; + + unicodeToName.put(new Character((char) 0x2790), "a156"); + nameToUnicode.put("a156", new Character((char) 0x2790)); + nameToEnc.put("a156", new Integer(208)); + encToName[208] = "a156"; + + unicodeToName.put(new Character((char) 0x2791), "a157"); + nameToUnicode.put("a157", new Character((char) 0x2791)); + nameToEnc.put("a157", new Integer(209)); + encToName[209] = "a157"; + + unicodeToName.put(new Character((char) 0x2792), "a158"); + nameToUnicode.put("a158", new Character((char) 0x2792)); + nameToEnc.put("a158", new Integer(210)); + encToName[210] = "a158"; + + unicodeToName.put(new Character((char) 0x2793), "a159"); + nameToUnicode.put("a159", new Character((char) 0x2793)); + nameToEnc.put("a159", new Integer(211)); + encToName[211] = "a159"; + + unicodeToName.put(new Character((char) 0x2794), "a160"); + nameToUnicode.put("a160", new Character((char) 0x2794)); + nameToEnc.put("a160", new Integer(212)); + encToName[212] = "a160"; + + unicodeToName.put(new Character((char) 0x2192), "a161"); + nameToUnicode.put("a161", new Character((char) 0x2192)); + nameToEnc.put("a161", new Integer(213)); + encToName[213] = "a161"; + + unicodeToName.put(new Character((char) 0x2194), "a163"); + nameToUnicode.put("a163", new Character((char) 0x2194)); + nameToEnc.put("a163", new Integer(214)); + encToName[214] = "a163"; + + unicodeToName.put(new Character((char) 0x2195), "a164"); + nameToUnicode.put("a164", new Character((char) 0x2195)); + nameToEnc.put("a164", new Integer(215)); + encToName[215] = "a164"; + + unicodeToName.put(new Character((char) 0x2798), "a196"); + nameToUnicode.put("a196", new Character((char) 0x2798)); + nameToEnc.put("a196", new Integer(216)); + encToName[216] = "a196"; + + unicodeToName.put(new Character((char) 0x2799), "a165"); + nameToUnicode.put("a165", new Character((char) 0x2799)); + nameToEnc.put("a165", new Integer(217)); + encToName[217] = "a165"; + + unicodeToName.put(new Character((char) 0x279a), "a192"); + nameToUnicode.put("a192", new Character((char) 0x279a)); + nameToEnc.put("a192", new Integer(218)); + encToName[218] = "a192"; + + unicodeToName.put(new Character((char) 0x279b), "a166"); + nameToUnicode.put("a166", new Character((char) 0x279b)); + nameToEnc.put("a166", new Integer(219)); + encToName[219] = "a166"; + + unicodeToName.put(new Character((char) 0x279c), "a167"); + nameToUnicode.put("a167", new Character((char) 0x279c)); + nameToEnc.put("a167", new Integer(220)); + encToName[220] = "a167"; + + unicodeToName.put(new Character((char) 0x279d), "a168"); + nameToUnicode.put("a168", new Character((char) 0x279d)); + nameToEnc.put("a168", new Integer(221)); + encToName[221] = "a168"; + + unicodeToName.put(new Character((char) 0x279e), "a169"); + nameToUnicode.put("a169", new Character((char) 0x279e)); + nameToEnc.put("a169", new Integer(222)); + encToName[222] = "a169"; + + unicodeToName.put(new Character((char) 0x279f), "a170"); + nameToUnicode.put("a170", new Character((char) 0x279f)); + nameToEnc.put("a170", new Integer(223)); + encToName[223] = "a170"; + + unicodeToName.put(new Character((char) 0x27a0), "a171"); + nameToUnicode.put("a171", new Character((char) 0x27a0)); + nameToEnc.put("a171", new Integer(224)); + encToName[224] = "a171"; + + unicodeToName.put(new Character((char) 0x27a1), "a172"); + nameToUnicode.put("a172", new Character((char) 0x27a1)); + nameToEnc.put("a172", new Integer(225)); + encToName[225] = "a172"; + + unicodeToName.put(new Character((char) 0x27a2), "a173"); + nameToUnicode.put("a173", new Character((char) 0x27a2)); + nameToEnc.put("a173", new Integer(226)); + encToName[226] = "a173"; + + unicodeToName.put(new Character((char) 0x27a3), "a162"); + nameToUnicode.put("a162", new Character((char) 0x27a3)); + nameToEnc.put("a162", new Integer(227)); + encToName[227] = "a162"; + + unicodeToName.put(new Character((char) 0x27a4), "a174"); + nameToUnicode.put("a174", new Character((char) 0x27a4)); + nameToEnc.put("a174", new Integer(228)); + encToName[228] = "a174"; + + unicodeToName.put(new Character((char) 0x27a5), "a175"); + nameToUnicode.put("a175", new Character((char) 0x27a5)); + nameToEnc.put("a175", new Integer(229)); + encToName[229] = "a175"; + + unicodeToName.put(new Character((char) 0x27a6), "a176"); + nameToUnicode.put("a176", new Character((char) 0x27a6)); + nameToEnc.put("a176", new Integer(230)); + encToName[230] = "a176"; + + unicodeToName.put(new Character((char) 0x27a7), "a177"); + nameToUnicode.put("a177", new Character((char) 0x27a7)); + nameToEnc.put("a177", new Integer(231)); + encToName[231] = "a177"; + + unicodeToName.put(new Character((char) 0x27a8), "a178"); + nameToUnicode.put("a178", new Character((char) 0x27a8)); + nameToEnc.put("a178", new Integer(232)); + encToName[232] = "a178"; + + unicodeToName.put(new Character((char) 0x27a9), "a179"); + nameToUnicode.put("a179", new Character((char) 0x27a9)); + nameToEnc.put("a179", new Integer(233)); + encToName[233] = "a179"; + + unicodeToName.put(new Character((char) 0x27aa), "a193"); + nameToUnicode.put("a193", new Character((char) 0x27aa)); + nameToEnc.put("a193", new Integer(234)); + encToName[234] = "a193"; + + unicodeToName.put(new Character((char) 0x27ab), "a180"); + nameToUnicode.put("a180", new Character((char) 0x27ab)); + nameToEnc.put("a180", new Integer(235)); + encToName[235] = "a180"; + + unicodeToName.put(new Character((char) 0x27ac), "a199"); + nameToUnicode.put("a199", new Character((char) 0x27ac)); + nameToEnc.put("a199", new Integer(236)); + encToName[236] = "a199"; + + unicodeToName.put(new Character((char) 0x27ad), "a181"); + nameToUnicode.put("a181", new Character((char) 0x27ad)); + nameToEnc.put("a181", new Integer(237)); + encToName[237] = "a181"; + + unicodeToName.put(new Character((char) 0x27ae), "a200"); + nameToUnicode.put("a200", new Character((char) 0x27ae)); + nameToEnc.put("a200", new Integer(238)); + encToName[238] = "a200"; + + unicodeToName.put(new Character((char) 0x27af), "a182"); + nameToUnicode.put("a182", new Character((char) 0x27af)); + nameToEnc.put("a182", new Integer(239)); + encToName[239] = "a182"; + + unicodeToName.put(new Character((char) 0x27b1), "a201"); + nameToUnicode.put("a201", new Character((char) 0x27b1)); + nameToEnc.put("a201", new Integer(241)); + encToName[241] = "a201"; + + unicodeToName.put(new Character((char) 0x27b2), "a183"); + nameToUnicode.put("a183", new Character((char) 0x27b2)); + nameToEnc.put("a183", new Integer(242)); + encToName[242] = "a183"; + + unicodeToName.put(new Character((char) 0x27b3), "a184"); + nameToUnicode.put("a184", new Character((char) 0x27b3)); + nameToEnc.put("a184", new Integer(243)); + encToName[243] = "a184"; + + unicodeToName.put(new Character((char) 0x27b4), "a197"); + nameToUnicode.put("a197", new Character((char) 0x27b4)); + nameToEnc.put("a197", new Integer(244)); + encToName[244] = "a197"; + + unicodeToName.put(new Character((char) 0x27b5), "a185"); + nameToUnicode.put("a185", new Character((char) 0x27b5)); + nameToEnc.put("a185", new Integer(245)); + encToName[245] = "a185"; + + unicodeToName.put(new Character((char) 0x27b6), "a194"); + nameToUnicode.put("a194", new Character((char) 0x27b6)); + nameToEnc.put("a194", new Integer(246)); + encToName[246] = "a194"; + + unicodeToName.put(new Character((char) 0x27b7), "a198"); + nameToUnicode.put("a198", new Character((char) 0x27b7)); + nameToEnc.put("a198", new Integer(247)); + encToName[247] = "a198"; + + unicodeToName.put(new Character((char) 0x27b8), "a186"); + nameToUnicode.put("a186", new Character((char) 0x27b8)); + nameToEnc.put("a186", new Integer(248)); + encToName[248] = "a186"; + + unicodeToName.put(new Character((char) 0x27b9), "a195"); + nameToUnicode.put("a195", new Character((char) 0x27b9)); + nameToEnc.put("a195", new Integer(249)); + encToName[249] = "a195"; + + unicodeToName.put(new Character((char) 0x27ba), "a187"); + nameToUnicode.put("a187", new Character((char) 0x27ba)); + nameToEnc.put("a187", new Integer(250)); + encToName[250] = "a187"; + + unicodeToName.put(new Character((char) 0x27bb), "a188"); + nameToUnicode.put("a188", new Character((char) 0x27bb)); + nameToEnc.put("a188", new Integer(251)); + encToName[251] = "a188"; + + unicodeToName.put(new Character((char) 0x27bc), "a189"); + nameToUnicode.put("a189", new Character((char) 0x27bc)); + nameToEnc.put("a189", new Integer(252)); + encToName[252] = "a189"; + + unicodeToName.put(new Character((char) 0x27bd), "a190"); + nameToUnicode.put("a190", new Character((char) 0x27bd)); + nameToEnc.put("a190", new Integer(253)); + encToName[253] = "a190"; + + unicodeToName.put(new Character((char) 0x27be), "a191"); + nameToUnicode.put("a191", new Character((char) 0x27be)); + nameToEnc.put("a191", new Integer(254)); + encToName[254] = "a191"; + + } + + public String toName(Character c) { + return ((String) unicodeToName.get(c)); + } + + public String toName(int enc) { + if (enc != 0) + return (encToName[enc]); + return (null); + } + + public int toEncoding(String name) { + return (((Integer) (nameToEnc.get(name))).intValue()); + } + + public char toUnicode(String name) { + return (((Character) (nameToUnicode.get(name))).charValue()); + } + + public String getName() { + return ("Zapfdingbats");//$NON-NLS-1$ + } + + public String getEncoding() { + return ("");//$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractPathConstructor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractPathConstructor.java index 86d6b5692..6818ad72f 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractPathConstructor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractPathConstructor.java @@ -1,76 +1,76 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.graphicsio; - -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.io.IOException; - -/** - * Implements some of the PathConstructor functionality - * - * @author Mark Donszelmann - */ -public abstract class AbstractPathConstructor implements PathConstructor { - - protected double currentX, currentY; - - protected AbstractPathConstructor() { - currentX = 0; - currentY = 0; - } - - public void flush() throws IOException { - currentX = 0; - currentY = 0; - } - - public boolean addPath(Shape s) throws IOException { - return addPath(s, null); - } - - public boolean addPath(Shape s, AffineTransform transform) - throws IOException { - return addPath(this, s, transform); - } - - public static boolean addPath(PathConstructor out, Shape s, - AffineTransform transform) throws IOException { - PathIterator path = s.getPathIterator(transform); - double[] coords = new double[6]; - double pathStartX = 0.; - double pathStartY = 0.; - while (!path.isDone()) { - int segType = path.currentSegment(coords); - - switch (segType) { - case PathIterator.SEG_MOVETO: - out.move(coords[0], coords[1]); - pathStartX = coords[0]; - pathStartY = coords[1]; - break; - case PathIterator.SEG_LINETO: - out.line(coords[0], coords[1]); - break; - case PathIterator.SEG_QUADTO: - out.quad(coords[0], coords[1], coords[2], coords[3]); - break; - case PathIterator.SEG_CUBICTO: - out.cubic(coords[0], coords[1], coords[2], coords[3], - coords[4], coords[5]); - break; - case PathIterator.SEG_CLOSE: - out.closePath(pathStartX, pathStartY); - break; - } - // Move to the next segment. - path.next(); - } - out.flush(); - return (path.getWindingRule() == PathIterator.WIND_EVEN_ODD); - } - - public static boolean isEvenOdd(Shape s) { - return s.getPathIterator(null).getWindingRule() == PathIterator.WIND_EVEN_ODD; - } -} +// Copyright 2001 freehep +package org.xmind.org.freehep.graphicsio; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.io.IOException; + +/** + * Implements some of the PathConstructor functionality + * + * @author Mark Donszelmann + */ +public abstract class AbstractPathConstructor implements PathConstructor { + + protected double currentX, currentY; + + protected AbstractPathConstructor() { + currentX = 0; + currentY = 0; + } + + public void flush() throws IOException { + currentX = 0; + currentY = 0; + } + + public boolean addPath(Shape s) throws IOException { + return addPath(s, null); + } + + public boolean addPath(Shape s, AffineTransform transform) + throws IOException { + return addPath(this, s, transform); + } + + public static boolean addPath(PathConstructor out, Shape s, + AffineTransform transform) throws IOException { + PathIterator path = s.getPathIterator(transform); + double[] coords = new double[6]; + double pathStartX = 0.; + double pathStartY = 0.; + while (!path.isDone()) { + int segType = path.currentSegment(coords); + + switch (segType) { + case PathIterator.SEG_MOVETO: + out.move(coords[0], coords[1]); + pathStartX = coords[0]; + pathStartY = coords[1]; + break; + case PathIterator.SEG_LINETO: + out.line(coords[0], coords[1]); + break; + case PathIterator.SEG_QUADTO: + out.quad(coords[0], coords[1], coords[2], coords[3]); + break; + case PathIterator.SEG_CUBICTO: + out.cubic(coords[0], coords[1], coords[2], coords[3], + coords[4], coords[5]); + break; + case PathIterator.SEG_CLOSE: + out.closePath(pathStartX, pathStartY); + break; + } + // Move to the next segment. + path.next(); + } + out.flush(); + return (path.getWindingRule() == PathIterator.WIND_EVEN_ODD); + } + + public static boolean isEvenOdd(Shape s) { + return s.getPathIterator(null).getWindingRule() == PathIterator.WIND_EVEN_ODD; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractVectorGraphicsIO.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractVectorGraphicsIO.java index 5f854c8a4..1b5f66e4a 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractVectorGraphicsIO.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/AbstractVectorGraphicsIO.java @@ -1,1530 +1,1530 @@ -// Copyright 2000-2007, FreeHEP -package org.xmind.org.freehep.graphicsio; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Component; -import java.awt.Composite; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.GradientPaint; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.MediaTracker; -import java.awt.Paint; -import java.awt.Panel; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.TexturePaint; -import java.awt.Toolkit; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Area; -import java.awt.geom.GeneralPath; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.CropImageFilter; -import java.awt.image.FilteredImageSource; -import java.awt.image.ImageFilter; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderContext; -import java.awt.image.renderable.RenderableImage; -import java.io.IOException; -import java.text.AttributedCharacterIterator; -import java.text.AttributedCharacterIterator.Attribute; -import java.util.Map; - -import org.xmind.org.freehep.graphics2d.font.FontEncoder; -import org.xmind.org.freehep.graphics2d.font.FontUtilities; -import org.xmind.org.freehep.util.images.ImageUtilities; - -/** - * This class provides an abstract VectorGraphicsIO class for specific output - * drivers. - * - * @author Charles Loomis - * @author Mark Donszelmann - * @author Steffen Greiffenberg - * @author Jason Wong - */ -public abstract class AbstractVectorGraphicsIO extends VectorGraphicsIO { - - private static final String rootKey = AbstractVectorGraphicsIO.class - .getName(); - - public static final String EMIT_WARNINGS = rootKey + ".EMIT_WARNINGS"; //$NON-NLS-1$ - - public static final String TEXT_AS_SHAPES = rootKey + "." //$NON-NLS-1$ - + FontConstants.TEXT_AS_SHAPES; - - public static final String EMIT_ERRORS = rootKey + ".EMIT_ERRORS"; //$NON-NLS-1$ - - public static final String CLIP = rootKey + ".CLIP"; //$NON-NLS-1$ - - /* - * ========================================================================== - * ====== Table of Contents: ------------------ 1. Constructors & Factory - * Methods 2. Document Settings 3. Header, Trailer, Multipage & Comments 3.1 - * Header & Trailer 3.2 MultipageDocument methods 4. Create & Dispose 5. - * Drawing Methods 5.1. shapes (draw/fill) 5.1.1. lines, rectangles, round - * rectangles 5.1.2. polylines, polygons 5.1.3. ovals, arcs 5.1.4. shapes - * 5.2. Images 5.3. Strings 6. Transformations 7. Clipping 8. Graphics State - * / Settings 8.1. stroke/linewidth 8.2. paint/color 8.3. font 8.4. - * rendering hints 9. Auxiliary 10. Private/Utility Methods - * ================== - * ============================================================== - */ - - private Dimension size; - - private Component component; - - private boolean doRestoreOnDispose; - - private Rectangle deviceClip; - - /** - * Untransformed clipping Area defined by the user - */ - private Area userClip; - - private AffineTransform currentTransform; - - // only for use in writeSetTransform to calculate the difference. - private AffineTransform oldTransform = new AffineTransform(); - - private Composite currentComposite; - - private Stroke currentStroke; - - private RenderingHints hints; - - /* - * ========================================================================== - * ====== 1. Constructors & Factory Methods - * ================================== - * ============================================== - */ - - /** - * Constructs a Graphics context with the following graphics state: - *
      - *
    • Paint: black - *
    • Font: Dailog, Plain, 12pt - *
    • Stroke: Linewidth 1.0; No Dashing; Miter Join Style; Miter Limit 10; - * Square Endcaps; - *
    • Transform: Identity - *
    • Composite: AlphaComposite.SRC_OVER - *
    • Clip: Rectangle(0, 0, size.width, size.height) - *
    - * - * @param size - * rectangle specifying the bounds of the image - * @param doRestoreOnDispose - * true if writeGraphicsRestore() should be called when this - * graphics context is disposed of. - */ - protected AbstractVectorGraphicsIO(Dimension size, - boolean doRestoreOnDispose) { - super(); - - this.size = size; - this.component = null; - this.doRestoreOnDispose = doRestoreOnDispose; - - deviceClip = (size != null ? new Rectangle(0, 0, size.width, - size.height) : null); - userClip = null; - currentTransform = new AffineTransform(); - currentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); - currentStroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, - BasicStroke.JOIN_MITER, 10.0f, null, 0.0f); - - super.setColor(Color.BLACK); - super.setBackground(Color.BLACK); - super.setFont(new Font("Dialog", Font.PLAIN, 12)); //$NON-NLS-1$ - - // Initialize the rendering hints. - hints = new RenderingHints(null); - } - - /** - * Constructs a Graphics context with the following graphics state: - *
      - *
    • Paint: The color of the component. - *
    • Font: The font of the component. - *
    • Stroke: Linewidth 1.0; No Dashing; Miter Join Style; Miter Limit 10; - * Square Endcaps; - *
    • Transform: The getDefaultTransform for the GraphicsConfiguration of - * the component. - *
    • Composite: AlphaComposite.SRC_OVER - *
    • Clip: The size of the component, Rectangle(0, 0, size.width, - * size.height) - *
    - * - * @param component - * to be used to initialize the values of the graphics state - * @param doRestoreOnDispose - * true if writeGraphicsRestore() should be called when this - * graphics context is disposed of. - */ - protected AbstractVectorGraphicsIO(Component component, - boolean doRestoreOnDispose) { - super(); - - this.size = component.getSize(); - this.component = component; - this.doRestoreOnDispose = doRestoreOnDispose; - - deviceClip = (size != null ? new Rectangle(0, 0, size.width, - size.height) : null); - userClip = null; - GraphicsConfiguration gc = component.getGraphicsConfiguration(); - currentTransform = (gc != null) ? gc.getDefaultTransform() - : new AffineTransform(); - currentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); - currentStroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, - BasicStroke.JOIN_MITER, 10.0f, null, 0.0f); - - super.setFont(component.getFont()); - super.setBackground(component.getBackground()); - super.setColor(component.getForeground()); - - // Initialize the rendering hints. - hints = new RenderingHints(null); - } - - /** - * Constructs a subgraphics context. - * - * @param graphics - * context to clone from - * @param doRestoreOnDispose - * true if writeGraphicsRestore() should be called when this - * graphics context is disposed of. - */ - protected AbstractVectorGraphicsIO(AbstractVectorGraphicsIO graphics, - boolean doRestoreOnDispose) { - super(graphics); - this.doRestoreOnDispose = doRestoreOnDispose; - - size = new Dimension(graphics.size); - component = graphics.component; - - deviceClip = new Rectangle(graphics.deviceClip); - userClip = (graphics.userClip != null) ? new Area(graphics.userClip) - : null; - currentTransform = new AffineTransform(graphics.currentTransform); - currentComposite = graphics.currentComposite; - currentStroke = graphics.currentStroke; - hints = graphics.hints; - } - - /* - * ========================================================================== - * ====== | 2. Document Settings - * ============================================ - * ==================================== - */ - public Dimension getSize() { - return size; - } - - public Component getComponent() { - return component; - } - - /* - * ========================================================================== - * ====== | 3. Header, Trailer, Multipage & Comments - * ======================== - * ======================================================== - */ - /* 3.1 Header & Trailer */ - @Override - public void startExport() { - try { - writeHeader(); - - // delegate this to openPage if it is a MultiPage document - if (!(this instanceof MultiPageDocument)) { - writeGraphicsState(); - writeBackground(); - } - } catch (IOException e) { - handleException(e); - } - } - - @Override - public void endExport() { - try { - dispose(); - writeTrailer(); - closeStream(); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Called to write the header part of the output. - */ - public abstract void writeHeader() throws IOException; - - /** - * Called to write the initial graphics state. - */ - public void writeGraphicsState() throws IOException { - writePaint(getPrintColor(getColor())); - - writeSetTransform(getTransform()); - - // writeStroke(getStroke()); - - setClip(getClip()); - - // Silly assignment, Font is written when String is drawed and "extra" - // writeFont does not exist - // setFont(getFont()); - - // Silly assignment and "extra" writeComposite does not exist - // setComposite(getComposite); - } - - public abstract void writeBackground() throws IOException; - - /** - * Called to write the trailing part of the output. - */ - public abstract void writeTrailer() throws IOException; - - /** - * Called to close the stream you are writing to. - */ - public abstract void closeStream() throws IOException; - - public void printComment(String comment) { - try { - writeComment(comment); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Called to Write out a comment. - * - * @param comment - * to be written - */ - public abstract void writeComment(String comment) throws IOException; - - /* 3.2 MultipageDocument methods */ - protected void resetClip(Rectangle clip) { - deviceClip = clip; - userClip = null; - } - - /* - * ========================================================================== - * ====== 4. Create & Dispose - * ================================================ - * ================================ - */ - /** - * Disposes of the graphics context. If on creation restoreOnDispose was - * true, writeGraphicsRestore() will be called. - */ - public void dispose() { - try { - // Swing sometimes calls dispose several times for a given - // graphics object. Ensure that the grestore is only written - // once if this happens. - if (doRestoreOnDispose) { - writeGraphicsRestore(); - doRestoreOnDispose = false; - } - } catch (IOException e) { - handleException(e); - } - } - - /** - * Writes out the save of a graphics context for a later restore. Some - * implementations keep track of this by hand if the output format does not - * support it. - */ - protected abstract void writeGraphicsSave() throws IOException; - - /** - * Writes out the restore of a graphics context. Some implementations keep - * track of this by hand if the output format does not support it. - */ - protected abstract void writeGraphicsRestore() throws IOException; - - /* - * ========================================================================== - * ====== | 5. Drawing Methods - * ============================================== - * ================================== - */ - - /* 5.3. Images */ - public boolean drawImage(Image image, int x, int y, ImageObserver observer) { - int imageWidth = image.getWidth(observer); - int imageHeight = image.getHeight(observer); - return drawImage(image, x, y, x + imageWidth, y + imageHeight, 0, 0, - imageWidth, imageHeight, null, observer); - } - - public boolean drawImage(Image image, int x, int y, int width, int height, - ImageObserver observer) { - int imageWidth = image.getWidth(observer); - int imageHeight = image.getHeight(observer); - return drawImage(image, x, y, x + width, y + height, 0, 0, imageWidth, - imageHeight, null, observer); - } - - public boolean drawImage(Image image, int x, int y, int width, int height, - Color bgColor, ImageObserver observer) { - int imageWidth = image.getWidth(observer); - int imageHeight = image.getHeight(observer); - return drawImage(image, x, y, x + width, y + height, 0, 0, imageWidth, - imageHeight, bgColor, observer); - } - - public boolean drawImage(Image image, int x, int y, Color bgColor, - ImageObserver observer) { - int imageWidth = image.getWidth(observer); - int imageHeight = image.getHeight(observer); - return drawImage(image, x, y, x + imageWidth, y + imageHeight, 0, 0, - imageWidth, imageHeight, bgColor, observer); - } - - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, - observer); - } - - public boolean drawImage(Image image, AffineTransform xform, - ImageObserver observer) { - drawRenderedImage( - ImageUtilities.createRenderedImage(image, observer, null), - xform); - return true; - } - - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { - drawImage(op.filter(img, null), x, y, null); - } - - // NOTE: not tested yet!!! - public void drawRenderableImage(RenderableImage image, AffineTransform xform) { - drawRenderedImage(image.createRendering(new RenderContext( - new AffineTransform(), getRenderingHints())), xform); - } - - /** - * Draw and resizes (transparent) image. Calls writeImage(...). - * - * @param image - * image to be drawn - * @param dx1 - * destination image bounds - * @param dy1 - * destination image bounds - * @param dx2 - * destination image bounds - * @param dy2 - * destination image bounds - * @param sx1 - * source image bounds - * @param sy1 - * source image bounds - * @param sx2 - * source image bounds - * @param sy2 - * source image bounds - * @param bgColor - * background color - * @param observer - * for updates if image still incomplete - * @return true if successful - */ - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, Color bgColor, - ImageObserver observer) { - try { - int srcX = Math.min(sx1, sx2); - int srcY = Math.min(sy1, sy2); - int srcWidth = Math.abs(sx2 - sx1); - int srcHeight = Math.abs(sy2 - sy1); - int width = Math.abs(dx2 - dx1); - int height = Math.abs(dy2 - dy1); - - if ((srcX != 0) || (srcY != 0) - || (srcWidth != image.getWidth(observer)) - || (srcHeight != image.getHeight(observer))) { - // crop the source image - ImageFilter crop = new CropImageFilter(srcX, srcY, srcWidth, - srcHeight); - image = Toolkit.getDefaultToolkit().createImage( - new FilteredImageSource(image.getSource(), crop)); - MediaTracker mediaTracker = new MediaTracker(new Panel()); - mediaTracker.addImage(image, 0); - try { - mediaTracker.waitForAll(); - } catch (InterruptedException e) { - handleException(e); - } - } - - boolean flipHorizontal = (dx2 < dx1) ^ (sx2 < sx1); // src flipped - // and not dest - // flipped or - // vice versa - boolean flipVertical = (dy2 < dy1) ^ (sy2 < sy1); // <=> source - // flipped XOR - // dest flipped - - double tx = (flipHorizontal) ? (double) dx2 : (double) dx1; - double ty = (flipVertical) ? (double) dy2 : (double) dy1; - - double sx = (double) width / srcWidth; - sx = flipHorizontal ? -1 * sx : sx; - double sy = (double) height / srcHeight; - sy = flipVertical ? -1 * sy : sy; - - writeImage(ImageUtilities.createRenderedImage(image, observer, - bgColor), new AffineTransform(sx, 0, 0, sy, tx, ty), - bgColor); - return true; - } catch (IOException e) { - handleException(e); - return false; - } - } - - /* - * // first use the original orientation int clippingWidth = Math.abs(sx2 - - * sx1); int clippingHeight = Math.abs(sy2 - sy1); int sulX = Math.min(sx1, - * sx2); int sulY = Math.min(sy1, sy2); Image background = null; if (bgColor - * != null) { // Draw the image on the background color // maybe we could - * crop it and fill the transparent pixels in one go // by means of a - * filter. background = new BufferedImage(clippingWidth, clippingHeight, - * BufferedImage.TYPE_INT_ARGB); Graphics bgGfx = background.getGraphics(); - * bgGfx.drawImage(image, 0, 0, clippingWidth, clippingWidth, sulX, sulY, - * sulX+clippingWidth, sulY+clippingHeight, getPrintColor(bgColor), - * observer); } else { // crop the source image ImageFilter crop = new - * CropImageFilter(sulX, sulY, clippingWidth, clippingHeight); background = - * Toolkit.getDefaultToolkit().createImage(new - * FilteredImageSource(image.getSource(), crop)); MediaTracker mediaTracker - * = new MediaTracker(new Panel()); mediaTracker.addImage(background, 0); - * try { mediaTracker.waitForAll(); } catch (InterruptedException e) { - * handleException(e); } } // now flip the image if necessary boolean - * flipHorizontal = (dx2 source flipped XOR dest flipped int destWidth = Math.abs(dx2-dx1); - * int destHeight = Math.abs(dy2-dy1); try { return writeImage(background, - * flipHorizontal ? dx2 : dx1, flipVertical ? dy2 : dy1, flipHorizontal ? - * -destWidth : destWidth, flipVertical ? -destHeight : destHeight, (bgColor - * == null), observer); } catch (IOException e) { return false; } } - */ - /** - * Draws a rendered image using a transform. - * - * @param image - * to be drawn - * @param xform - * transform to be used on the image - */ - public void drawRenderedImage(RenderedImage image, AffineTransform xform) { - try { - writeImage(image, xform, null); - } catch (Exception e) { - handleException(e); - } - } - - protected abstract void writeImage(RenderedImage image, - AffineTransform xform, Color bkg) throws IOException; - - /** - * Clears rectangle by painting it with the backgroundColor. - * - * @param x - * rectangle to be cleared. - * @param y - * rectangle to be cleared. - * @param width - * rectangle to be cleared. - * @param height - * rectangle to be cleared. - */ - public void clearRect(double x, double y, double width, double height) { - Paint temp = getPaint(); - setPaint(getBackground()); - fillRect(x, y, width, height); - setPaint(temp); - } - - /** - * Draws the string at (x, y). If TEXT_AS_SHAPES is set - * {@link #drawGlyphVector(java.awt.font.GlyphVector, float, float)} is - * used, otherwise {@link #writeString(String, double, double)} for a more - * direct output of the string. - * - * @param string - * @param x - * @param y - */ - public void drawString(String string, double x, double y) { - // something to draw? - if (string == null || string.equals("")) { //$NON-NLS-1$ - return; - } - - // draw strings directly? - if (isProperty(TEXT_AS_SHAPES)) { - - Font font = getFont(); - - // NOTE, see FVG-199, createGlyphVector does not seem to create the - // proper glyphcodes - // for either ZapfDingbats or Symbol. We use our own encoding which - // seems to work... - String fontName = font.getName(); - if (fontName.equals("Symbol") || fontName.equals("ZapfDingbats")) { //$NON-NLS-1$ //$NON-NLS-2$ - string = FontEncoder.getEncodedString(string, fontName); - // use a standard font, not Symbol. - font = new Font("Serif", font.getStyle(), font.getSize()); //$NON-NLS-1$ - } - - // create glyph - GlyphVector gv = font.createGlyphVector(getFontRenderContext(), - string); - - // draw it - drawGlyphVector(gv, (float) x, (float) y); - } else { - // write string directly - try { - writeString(string, x, y); - } catch (IOException e) { - handleException(e); - } - } - } - - protected abstract void writeString(String string, double x, double y) - throws IOException; - - /** - * Use the transformation of the glyphvector and draw it - * - * @param g - * @param x - * @param y - */ - public void drawGlyphVector(GlyphVector g, float x, float y) { - fill(g.getOutline(x, y)); - } - - public void drawString(AttributedCharacterIterator iterator, float x, - float y) { - - // TextLayout draws the iterator as glyph vector - // thats why we use it only in the case of TEXT_AS_SHAPES, - // otherwise tagged strings are always written as glyphs - if (isProperty(TEXT_AS_SHAPES)) { - // draws all attributes - TextLayout tl = new TextLayout(iterator, getFontRenderContext()); - tl.draw(this, x, y); - } else { - // reset to that font at the end - Font font = getFont(); - - // initial attributes, we us TextAttribute.equals() rather - // than Font.equals() because using Font.equals() we do - // not get a 'false' if underline etc. is changed - Map attributes = FontUtilities - .getAttributes(font); - - // stores all characters which are written with the same font - // if font is changed the buffer will be written and cleared - // after it - StringBuffer sb = new StringBuffer(); - - for (char c = iterator.first(); c != AttributedCharacterIterator.DONE; c = iterator - .next()) { - - // append c if font is not changed - if (attributes.equals(iterator.getAttributes())) { - sb.append(c); - - } else { - // TextLayout does not like 0 length strings - if (sb.length() > 0) { - // draw sb if font is changed - drawString(sb.toString(), x, y); - - // change the x offset for the next drawing - // FIXME: change y offset for vertical text - TextLayout tl = new TextLayout(sb.toString(), - attributes, getFontRenderContext()); - - // calculate real width - x = x - + Math.max(tl.getAdvance(), (float) tl - .getBounds().getWidth()); - } - - // empty sb - sb = new StringBuffer(); - sb.append(c); - - // change the font - attributes = iterator.getAttributes(); - setFont(new Font(attributes)); - } - } - - // draw the rest - if (sb.length() > 0) { - drawString(sb.toString(), x, y); - } - - // use the old font for the next string drawing - setFont(font); - } - } - - /* - * ========================================================================== - * ====== | 6. Transformations - * ============================================== - * ================================== - */ - /** - * Get the current transform. - * - * @return current transform - */ - public AffineTransform getTransform() { - return new AffineTransform(currentTransform); - } - - /** - * Set the current transform. Calls writeSetTransform(Transform). - * - * @param transform - * to be set - */ - public void setTransform(AffineTransform transform) { - // Fix for FREEHEP-569 - oldTransform.setTransform(currentTransform); - currentTransform.setTransform(transform); - try { - writeSetTransform(transform); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Transforms the current transform. Calls writeTransform(Transform) - * - * @param transform - * to be applied - */ - public void transform(AffineTransform transform) { - currentTransform.concatenate(transform); - try { - writeTransform(transform); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Translates the current transform. Calls writeTransform(Transform) - * - * @param x - * amount by which to translate - * @param y - * amount by which to translate - */ - public void translate(double x, double y) { - currentTransform.translate(x, y); - try { - writeTransform(new AffineTransform(1, 0, 0, 1, x, y)); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Rotate the current transform over the Z-axis. Calls - * writeTransform(Transform). Rotating with a positive angle theta rotates - * points on the positive x axis toward the positive y axis. - * - * @param theta - * radians over which to rotate - */ - public void rotate(double theta) { - currentTransform.rotate(theta); - try { - writeTransform(new AffineTransform(Math.cos(theta), - Math.sin(theta), -Math.sin(theta), Math.cos(theta), 0, 0)); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Scales the current transform. Calls writeTransform(Transform). - * - * @param sx - * amount used for scaling - * @param sy - * amount used for scaling - */ - public void scale(double sx, double sy) { - currentTransform.scale(sx, sy); - try { - writeTransform(new AffineTransform(sx, 0, 0, sy, 0, 0)); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Shears the current transform. Calls writeTransform(Transform). - * - * @param shx - * amount for shearing - * @param shy - * amount for shearing - */ - public void shear(double shx, double shy) { - currentTransform.shear(shx, shy); - try { - writeTransform(new AffineTransform(1, shy, shx, 1, 0, 0)); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Writes out the transform as it needs to be concatenated to the internal - * transform of the output format. If there is no implementation of an - * internal transform, then this method needs to do nothing, BUT all - * coordinates need to be transformed by the currentTransform before being - * written out. - * - * @param transform - * to be written - */ - protected abstract void writeTransform(AffineTransform transform) - throws IOException; - - /** - * Clears any existing transformation and sets the a new one. The default - * implementation calls writeTransform using the inverted affine transform - * to calculate it. s * - * - * @param transform - * to be written - */ - protected void writeSetTransform(AffineTransform transform) - throws IOException { - try { - AffineTransform deltaTransform = new AffineTransform(transform); - deltaTransform.concatenate(oldTransform.createInverse()); - writeTransform(deltaTransform); - } catch (NoninvertibleTransformException e) { - // ignored... - System.err.println("Warning: (ignored) Could not invert matrix: " //$NON-NLS-1$ - + oldTransform); - } - } - - /* - * ========================================================================== - * ====== | 7. Clipping - * ====================================================== - * ========================== - */ - - /** - * Gets the current clip in form of a Shape (Rectangle). - * - * @return current clip - */ - public Shape getClip() { - return (userClip != null) ? new Area(untransformShape(userClip)) : null; - } - - /** - * Gets the current clip in form of a Rectangle. - * - * @return current clip - */ - public Rectangle getClipBounds() { - Shape clip = getClip(); - return (clip != null) ? getClip().getBounds() : null; - } - - /** - * Gets the current clip in form of a Rectangle. - * - * @return current clip - */ - public Rectangle getClipBounds(Rectangle r) { - Rectangle bounds = getClipBounds(); - if (bounds != null) - r.setBounds(bounds); - return r; - } - - /** - * Clips rectangle. Calls clip(Rectangle). - * - * @param x - * rectangle for clipping - * @param y - * rectangle for clipping - * @param width - * rectangle for clipping - * @param height - * rectangle for clipping - */ - public void clipRect(int x, int y, int width, int height) { - clip(new Rectangle(x, y, width, height)); - } - - /** - * Clips rectangle. Calls clip(Rectangle2D). - * - * @param x - * rectangle for clipping - * @param y - * rectangle for clipping - * @param width - * rectangle for clipping - * @param height - * rectangle for clipping - */ - public void clipRect(double x, double y, double width, double height) { - clip(new Rectangle2D.Double(x, y, width, height)); - } - - /** - * Clips rectangle. Calls clip(Rectangle). - * - * @param x - * rectangle for clipping - * @param y - * rectangle for clipping - * @param width - * rectangle for clipping - * @param height - * rectangle for clipping - */ - public void setClip(int x, int y, int width, int height) { - setClip(new Rectangle(x, y, width, height)); - } - - /** - * Clips rectangle. Calls clip(Rectangle2D). - * - * @param x - * rectangle for clipping - * @param y - * rectangle for clipping - * @param width - * rectangle for clipping - * @param height - * rectangle for clipping - */ - public void setClip(double x, double y, double width, double height) { - setClip(new Rectangle2D.Double(x, y, width, height)); - } - - /** - * Clips shape. Clears userClip and calls clip(Shape). - * - * @param s - * used for clipping - */ - public void setClip(Shape s) { - Shape ts = transformShape(s); - userClip = (ts != null) ? new Area(ts) : null; - - try { - writeSetClip(s); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Clips using given shape. Dispatches to writeClip(Rectangle), - * writeClip(Rectangle2D) or writeClip(Shape). - * - * @param s - * used for clipping - */ - public void clip(Shape s) { - Shape ts = transformShape(s); - if (userClip != null) { - if (ts != null) { - userClip.intersect(new Area(ts)); - } else { - userClip = null; - } - } else { - userClip = (ts != null) ? new Area(ts) : null; - } - - try { - writeClip(s); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Write out Shape clip. - * - * @param shape - * to be used for clipping - */ - protected abstract void writeClip(Shape shape) throws IOException; - - /** - * Write out Shape clip. - * - * @param shape - * to be used for clipping - */ - protected abstract void writeSetClip(Shape shape) throws IOException; - - /* - * ========================================================================== - * ====== | 8. Graphics State - * ================================================ - * ================================ - */ - /* 8.1. stroke/linewidth */ - /** - * Get the current stroke. - * - * @return current stroke - */ - public Stroke getStroke() { - return currentStroke; - } - - /** - * Sets the current stroke. Calls writeStroke if stroke is unequal to the - * current stroke. - * - * @param stroke - * to be set - */ - public void setStroke(Stroke stroke) { - if (stroke.equals(currentStroke)) { - return; - } - try { - writeStroke(stroke); - } catch (IOException e) { - handleException(e); - } - currentStroke = stroke; - } - - /** - * Writes the current stroke. If stroke is an instance of BasicStroke it - * will call writeWidth, writeCap, writeJoin, writeMiterLimit and writeDash, - * if any were different than the current stroke. - */ - protected void writeStroke(Stroke stroke) throws IOException { - if (stroke instanceof BasicStroke) { - BasicStroke ns = (BasicStroke) stroke; - - // get the current values for comparison if available, - // otherwise set them to -1="undefined" - int currentCap = -1, currentJoin = -1; - float currentWidth = -1, currentLimit = -1, currentDashPhase = -1; - float[] currentDashArray = null; - if ((currentStroke != null) - && (currentStroke instanceof BasicStroke)) { - BasicStroke cs = (BasicStroke) currentStroke; - currentCap = cs.getEndCap(); - currentJoin = cs.getLineJoin(); - currentWidth = cs.getLineWidth(); - currentLimit = cs.getMiterLimit(); - currentDashArray = cs.getDashArray(); - currentDashPhase = cs.getDashPhase(); - } - - // Check the linewidth. - float width = ns.getLineWidth(); - // if (currentWidth != width) { - writeWidth(width); - // } - - // Check the line caps. - int cap = ns.getEndCap(); - if (currentCap != cap) { - writeCap(cap); - } - - // Check the line joins. - int join = ns.getLineJoin(); - if (currentJoin != join) { - writeJoin(join); - } - - // Check the miter limit and validity of value - float limit = ns.getMiterLimit(); - if ((currentLimit != limit) && (limit >= 1.0f)) { - writeMiterLimit(limit); - } - - // Check to see if there are differences in the phase or dash - // if (!Arrays.equals(currentDashArray, ns.getDashArray()) - // || (currentDashPhase != ns.getDashPhase())) { - - // write the dashing parameters - if (ns.getDashArray() != null) { - writeDash(ns.getDashArray(), ns.getDashPhase()); - } else { - writeDash(new float[0], ns.getDashPhase()); - } - // } - } - } - - /** - * Writes out the width of the stroke. - * - * @param width - * of the stroke - */ - protected void writeWidth(float width) throws IOException { - writeWarning(getClass() + ": writeWidth() not implemented."); //$NON-NLS-1$ - } - - /** - * Writes out the cap of the stroke. - * - * @param cap - * of the stroke - */ - protected void writeCap(int cap) throws IOException { - writeWarning(getClass() + ": writeCap() not implemented."); //$NON-NLS-1$ - } - - /** - * Writes out the join of the stroke. - * - * @param join - * of the stroke - */ - protected void writeJoin(int join) throws IOException { - writeWarning(getClass() + ": writeJoin() not implemented."); //$NON-NLS-1$ - } - - /** - * Writes out the miter limit of the stroke. - * - * @param limit - * miter limit of the stroke - */ - protected void writeMiterLimit(float limit) throws IOException { - writeWarning(getClass() + ": writeMiterLimit() not implemented."); //$NON-NLS-1$ - } - - /** - * Writes out the dash of the stroke. - * - * @param dash - * dash pattern, empty array is solid line - * @param phase - * of the dash pattern - */ - protected void writeDash(float[] dash, float phase) throws IOException { - // for backward compatibility - double[] dd = new double[dash.length]; - for (int i = 0; i < dash.length; i++) { - dd[i] = dash[i]; - } - writeDash(dd, (double) phase); - } - - /** - * Writes out the dash of the stroke. - * - * @deprecated use writeDash(float[], float) - * @param dash - * dash pattern, empty array is solid line - * @param phase - * of the dash pattern - */ - protected void writeDash(double[] dash, double phase) throws IOException { - writeWarning(getClass() + ": writeDash() not implemented."); //$NON-NLS-1$ - } - - /* 8.2 Paint */ - public void setColor(Color color) { - if (color == null) - return; - - // if (color.equals(getColor())) - // return; - - try { - super.setColor(color); - writePaint(getPrintColor(color)); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Sets the current paint. Dispatches to writePaint(Color), - * writePaint(GradientPaint), writePaint(TexturePaint paint) or - * writePaint(Paint). In the case paint is a Color the current color is also - * changed. - * - * @param paint - * to be set - */ - public void setPaint(Paint paint) { - if (paint == null) - return; - - // if (paint.equals(getPaint())) - // return; - - try { - if (paint instanceof Color) { - setColor((Color) paint); - } else if (paint instanceof GradientPaint) { - super.setPaint(paint); - writePaint((GradientPaint) paint); - } else if (paint instanceof TexturePaint) { - super.setPaint(paint); - writePaint((TexturePaint) paint); - } else { - super.setPaint(paint); - writePaint(paint); - } - } catch (IOException e) { - handleException(e); - } - } - - /** - * Writes out paint as the given color. - * - * @param color - * to be written - */ - protected abstract void writePaint(Color color) throws IOException; - - /** - * Writes out paint as the given gradient. - * - * @param paint - * to be written - */ - protected abstract void writePaint(GradientPaint paint) throws IOException; - - /** - * Writes out paint as the given texture. - * - * @param paint - * to be written - */ - protected abstract void writePaint(TexturePaint paint) throws IOException; - - /** - * Writes out paint. - * - * @param paint - * to be written - */ - protected abstract void writePaint(Paint paint) throws IOException; - - /* 8.3. font */ - /** - * Gets the current font render context. This returns an standard - * FontRenderContext with anti-aliasing and uses fractional metrics. - * - * @return current font render context - */ - public FontRenderContext getFontRenderContext() { - // NOTE: not sure? - // Fixed for VG-285 - return new FontRenderContext(new AffineTransform(1, 0, 0, 1, 0, 0), - true, true); - } - - /** - * Gets the fontmetrics. - * - * @deprecated - * @param font - * to be used for retrieving fontmetrics - * @return fontmetrics for given font - */ - public FontMetrics getFontMetrics(Font font) { - return Toolkit.getDefaultToolkit().getFontMetrics(font); - } - - /* 8.4. rendering hints */ - /** - * Gets a copy of the rendering hints. - * - * @return clone of table of rendering hints. - */ - public RenderingHints getRenderingHints() { - return (RenderingHints) hints.clone(); - } - - /** - * Adds to table of rendering hints. - * - * @param hints - * table to be added - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void addRenderingHints(Map hints) { - hints.putAll(hints); - } - - /** - * Sets table of rendering hints. - * - * @param hints - * table to be set - */ - @SuppressWarnings("rawtypes") - public void setRenderingHints(Map hints) { - this.hints.clear(); - if (hints instanceof RenderingHints) { - RenderingHints renderingHints = (RenderingHints) hints; - this.hints.putAll((Map) renderingHints.clone()); - } else { - this.hints.putAll(hints); - } - } - - /** - * Gets a given rendering hint. - * - * @param key - * hint key - * @return hint associated to key - */ - public Object getRenderingHint(RenderingHints.Key key) { - return hints.get(key); - } - - /** - * Sets a given rendering hint. - * - * @param key - * hint key - * @param hint - * to be associated with key - */ - public void setRenderingHint(RenderingHints.Key key, Object hint) { - // extra protection, failed on under MacOS X 10.2.6, jdk 1.4.1_01-39/14 - if ((key == null) || (hint == null)) - return; - hints.put(key, hint); - } - - /** - * Sets the current font. - * - * @param font - * to be set - */ - public void setFont(Font font) { - if (font == null) - return; - - // FIXME: maybe add delayed setting - super.setFont(font); - - // write the font - try { - writeFont(font); - } catch (IOException e) { - handleException(e); - } - } - - /** - * Writes the font - * - * @param font - * to be written - */ - protected abstract void writeFont(Font font) throws IOException; - - /* - * ========================================================================== - * ====== | 9. Auxiliary - * ==================================================== - * ============================ - */ - /** - * Gets current composite. - * - * @return current composite - */ - public Composite getComposite() { - return currentComposite; - } - - /** - * Sets current composite. - * - * @param composite - * to be set - */ - public void setComposite(Composite composite) { - currentComposite = composite; - } - - /** - * Handles an exception which has been caught. Dispatches exception to - * writeWarning for UnsupportedOperationExceptions and writeError for others - * - * @param exception - * to be handled - */ - protected void handleException(Exception exception) { - if (exception instanceof UnsupportedOperationException) { - writeWarning(exception); - } else { - writeError(exception); - } - } - - /** - * Writes out a warning, by default to System.err. - * - * @param exception - * warning to be written - */ - protected void writeWarning(Exception exception) { - writeWarning(exception.getMessage()); - } - - /** - * Writes out a warning, by default to System.err. - * - * @param warning - * to be written - */ - protected void writeWarning(String warning) { - if (isProperty(EMIT_WARNINGS)) { - System.err.println(warning); - } - } - - /** - * Writes out an error, by default the stack trace is printed. - * - * @param exception - * error to be reported - */ - protected void writeError(Exception exception) { - throw new RuntimeException(exception); - // FIXME decide what we should do - /* - * if (isProperty(EMIT_ERRORS)) { System.err.println(exception); - * exception.printStackTrace(System.err); } - */ - } - - protected Shape createShape(double[] xPoints, double[] yPoints, - int nPoints, boolean close) { - GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); - if (nPoints > 0) { - path.moveTo((float) xPoints[0], (float) yPoints[0]); - for (int i = 1; i < nPoints; i++) { - path.lineTo((float) xPoints[i], (float) yPoints[i]); - } - if (close) - path.closePath(); - } - return path; - } - - private Shape transformShape(AffineTransform at, Shape s) { - if (s == null) - return null; - return at.createTransformedShape(s); - } - - private Shape transformShape(Shape s) { - return transformShape(getTransform(), s); - } - - private Shape untransformShape(Shape s) { - if (s == null) - return null; - try { - return transformShape(getTransform().createInverse(), s); - } catch (NoninvertibleTransformException e) { - return null; - } - } - - /** - * Draws an overline for the text at (x, y). The method is usesefull for - * drivers that do not support overlines by itself. - * - * @param text - * text for width calulation - * @param font - * font for width calulation - * @param x - * position of text - * @param y - * position of text - */ - protected void overLine(String text, Font font, float x, float y) { - TextLayout layout = new TextLayout(text, font, getFontRenderContext()); - float width = Math.max(layout.getAdvance(), (float) layout.getBounds() - .getWidth()); - - GeneralPath path = new GeneralPath(); - path.moveTo(x, - y + (float) layout.getBounds().getY() - layout.getAscent()); - path.lineTo(x + width, - y + (float) layout.getBounds().getY() - layout.getAscent() - - layout.getAscent()); - draw(path); - } -} +// Copyright 2000-2007, FreeHEP +package org.xmind.org.freehep.graphicsio; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GradientPaint; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Paint; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.TexturePaint; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.CropImageFilter; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderContext; +import java.awt.image.renderable.RenderableImage; +import java.io.IOException; +import java.text.AttributedCharacterIterator; +import java.text.AttributedCharacterIterator.Attribute; +import java.util.Map; + +import org.xmind.org.freehep.graphics2d.font.FontEncoder; +import org.xmind.org.freehep.graphics2d.font.FontUtilities; +import org.xmind.org.freehep.util.images.ImageUtilities; + +/** + * This class provides an abstract VectorGraphicsIO class for specific output + * drivers. + * + * @author Charles Loomis + * @author Mark Donszelmann + * @author Steffen Greiffenberg + * @author Jason Wong + */ +public abstract class AbstractVectorGraphicsIO extends VectorGraphicsIO { + + private static final String rootKey = AbstractVectorGraphicsIO.class + .getName(); + + public static final String EMIT_WARNINGS = rootKey + ".EMIT_WARNINGS"; //$NON-NLS-1$ + + public static final String TEXT_AS_SHAPES = rootKey + "." //$NON-NLS-1$ + + FontConstants.TEXT_AS_SHAPES; + + public static final String EMIT_ERRORS = rootKey + ".EMIT_ERRORS"; //$NON-NLS-1$ + + public static final String CLIP = rootKey + ".CLIP"; //$NON-NLS-1$ + + /* + * ========================================================================== + * ====== Table of Contents: ------------------ 1. Constructors & Factory + * Methods 2. Document Settings 3. Header, Trailer, Multipage & Comments 3.1 + * Header & Trailer 3.2 MultipageDocument methods 4. Create & Dispose 5. + * Drawing Methods 5.1. shapes (draw/fill) 5.1.1. lines, rectangles, round + * rectangles 5.1.2. polylines, polygons 5.1.3. ovals, arcs 5.1.4. shapes + * 5.2. Images 5.3. Strings 6. Transformations 7. Clipping 8. Graphics State + * / Settings 8.1. stroke/linewidth 8.2. paint/color 8.3. font 8.4. + * rendering hints 9. Auxiliary 10. Private/Utility Methods + * ================== + * ============================================================== + */ + + private Dimension size; + + private Component component; + + private boolean doRestoreOnDispose; + + private Rectangle deviceClip; + + /** + * Untransformed clipping Area defined by the user + */ + private Area userClip; + + private AffineTransform currentTransform; + + // only for use in writeSetTransform to calculate the difference. + private AffineTransform oldTransform = new AffineTransform(); + + private Composite currentComposite; + + private Stroke currentStroke; + + private RenderingHints hints; + + /* + * ========================================================================== + * ====== 1. Constructors & Factory Methods + * ================================== + * ============================================== + */ + + /** + * Constructs a Graphics context with the following graphics state: + *
      + *
    • Paint: black + *
    • Font: Dailog, Plain, 12pt + *
    • Stroke: Linewidth 1.0; No Dashing; Miter Join Style; Miter Limit 10; + * Square Endcaps; + *
    • Transform: Identity + *
    • Composite: AlphaComposite.SRC_OVER + *
    • Clip: Rectangle(0, 0, size.width, size.height) + *
    + * + * @param size + * rectangle specifying the bounds of the image + * @param doRestoreOnDispose + * true if writeGraphicsRestore() should be called when this + * graphics context is disposed of. + */ + protected AbstractVectorGraphicsIO(Dimension size, + boolean doRestoreOnDispose) { + super(); + + this.size = size; + this.component = null; + this.doRestoreOnDispose = doRestoreOnDispose; + + deviceClip = (size != null ? new Rectangle(0, 0, size.width, + size.height) : null); + userClip = null; + currentTransform = new AffineTransform(); + currentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); + currentStroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_MITER, 10.0f, null, 0.0f); + + super.setColor(Color.BLACK); + super.setBackground(Color.BLACK); + super.setFont(new Font("Dialog", Font.PLAIN, 12)); //$NON-NLS-1$ + + // Initialize the rendering hints. + hints = new RenderingHints(null); + } + + /** + * Constructs a Graphics context with the following graphics state: + *
      + *
    • Paint: The color of the component. + *
    • Font: The font of the component. + *
    • Stroke: Linewidth 1.0; No Dashing; Miter Join Style; Miter Limit 10; + * Square Endcaps; + *
    • Transform: The getDefaultTransform for the GraphicsConfiguration of + * the component. + *
    • Composite: AlphaComposite.SRC_OVER + *
    • Clip: The size of the component, Rectangle(0, 0, size.width, + * size.height) + *
    + * + * @param component + * to be used to initialize the values of the graphics state + * @param doRestoreOnDispose + * true if writeGraphicsRestore() should be called when this + * graphics context is disposed of. + */ + protected AbstractVectorGraphicsIO(Component component, + boolean doRestoreOnDispose) { + super(); + + this.size = component.getSize(); + this.component = component; + this.doRestoreOnDispose = doRestoreOnDispose; + + deviceClip = (size != null ? new Rectangle(0, 0, size.width, + size.height) : null); + userClip = null; + GraphicsConfiguration gc = component.getGraphicsConfiguration(); + currentTransform = (gc != null) ? gc.getDefaultTransform() + : new AffineTransform(); + currentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); + currentStroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_MITER, 10.0f, null, 0.0f); + + super.setFont(component.getFont()); + super.setBackground(component.getBackground()); + super.setColor(component.getForeground()); + + // Initialize the rendering hints. + hints = new RenderingHints(null); + } + + /** + * Constructs a subgraphics context. + * + * @param graphics + * context to clone from + * @param doRestoreOnDispose + * true if writeGraphicsRestore() should be called when this + * graphics context is disposed of. + */ + protected AbstractVectorGraphicsIO(AbstractVectorGraphicsIO graphics, + boolean doRestoreOnDispose) { + super(graphics); + this.doRestoreOnDispose = doRestoreOnDispose; + + size = new Dimension(graphics.size); + component = graphics.component; + + deviceClip = new Rectangle(graphics.deviceClip); + userClip = (graphics.userClip != null) ? new Area(graphics.userClip) + : null; + currentTransform = new AffineTransform(graphics.currentTransform); + currentComposite = graphics.currentComposite; + currentStroke = graphics.currentStroke; + hints = graphics.hints; + } + + /* + * ========================================================================== + * ====== | 2. Document Settings + * ============================================ + * ==================================== + */ + public Dimension getSize() { + return size; + } + + public Component getComponent() { + return component; + } + + /* + * ========================================================================== + * ====== | 3. Header, Trailer, Multipage & Comments + * ======================== + * ======================================================== + */ + /* 3.1 Header & Trailer */ + @Override + public void startExport() { + try { + writeHeader(); + + // delegate this to openPage if it is a MultiPage document + if (!(this instanceof MultiPageDocument)) { + writeGraphicsState(); + writeBackground(); + } + } catch (IOException e) { + handleException(e); + } + } + + @Override + public void endExport() { + try { + dispose(); + writeTrailer(); + closeStream(); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Called to write the header part of the output. + */ + public abstract void writeHeader() throws IOException; + + /** + * Called to write the initial graphics state. + */ + public void writeGraphicsState() throws IOException { + writePaint(getPrintColor(getColor())); + + writeSetTransform(getTransform()); + + // writeStroke(getStroke()); + + setClip(getClip()); + + // Silly assignment, Font is written when String is drawed and "extra" + // writeFont does not exist + // setFont(getFont()); + + // Silly assignment and "extra" writeComposite does not exist + // setComposite(getComposite); + } + + public abstract void writeBackground() throws IOException; + + /** + * Called to write the trailing part of the output. + */ + public abstract void writeTrailer() throws IOException; + + /** + * Called to close the stream you are writing to. + */ + public abstract void closeStream() throws IOException; + + public void printComment(String comment) { + try { + writeComment(comment); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Called to Write out a comment. + * + * @param comment + * to be written + */ + public abstract void writeComment(String comment) throws IOException; + + /* 3.2 MultipageDocument methods */ + protected void resetClip(Rectangle clip) { + deviceClip = clip; + userClip = null; + } + + /* + * ========================================================================== + * ====== 4. Create & Dispose + * ================================================ + * ================================ + */ + /** + * Disposes of the graphics context. If on creation restoreOnDispose was + * true, writeGraphicsRestore() will be called. + */ + public void dispose() { + try { + // Swing sometimes calls dispose several times for a given + // graphics object. Ensure that the grestore is only written + // once if this happens. + if (doRestoreOnDispose) { + writeGraphicsRestore(); + doRestoreOnDispose = false; + } + } catch (IOException e) { + handleException(e); + } + } + + /** + * Writes out the save of a graphics context for a later restore. Some + * implementations keep track of this by hand if the output format does not + * support it. + */ + protected abstract void writeGraphicsSave() throws IOException; + + /** + * Writes out the restore of a graphics context. Some implementations keep + * track of this by hand if the output format does not support it. + */ + protected abstract void writeGraphicsRestore() throws IOException; + + /* + * ========================================================================== + * ====== | 5. Drawing Methods + * ============================================== + * ================================== + */ + + /* 5.3. Images */ + public boolean drawImage(Image image, int x, int y, ImageObserver observer) { + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + return drawImage(image, x, y, x + imageWidth, y + imageHeight, 0, 0, + imageWidth, imageHeight, null, observer); + } + + public boolean drawImage(Image image, int x, int y, int width, int height, + ImageObserver observer) { + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + return drawImage(image, x, y, x + width, y + height, 0, 0, imageWidth, + imageHeight, null, observer); + } + + public boolean drawImage(Image image, int x, int y, int width, int height, + Color bgColor, ImageObserver observer) { + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + return drawImage(image, x, y, x + width, y + height, 0, 0, imageWidth, + imageHeight, bgColor, observer); + } + + public boolean drawImage(Image image, int x, int y, Color bgColor, + ImageObserver observer) { + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + return drawImage(image, x, y, x + imageWidth, y + imageHeight, 0, 0, + imageWidth, imageHeight, bgColor, observer); + } + + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, + observer); + } + + public boolean drawImage(Image image, AffineTransform xform, + ImageObserver observer) { + drawRenderedImage( + ImageUtilities.createRenderedImage(image, observer, null), + xform); + return true; + } + + public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { + drawImage(op.filter(img, null), x, y, null); + } + + // NOTE: not tested yet!!! + public void drawRenderableImage(RenderableImage image, AffineTransform xform) { + drawRenderedImage(image.createRendering(new RenderContext( + new AffineTransform(), getRenderingHints())), xform); + } + + /** + * Draw and resizes (transparent) image. Calls writeImage(...). + * + * @param image + * image to be drawn + * @param dx1 + * destination image bounds + * @param dy1 + * destination image bounds + * @param dx2 + * destination image bounds + * @param dy2 + * destination image bounds + * @param sx1 + * source image bounds + * @param sy1 + * source image bounds + * @param sx2 + * source image bounds + * @param sy2 + * source image bounds + * @param bgColor + * background color + * @param observer + * for updates if image still incomplete + * @return true if successful + */ + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgColor, + ImageObserver observer) { + try { + int srcX = Math.min(sx1, sx2); + int srcY = Math.min(sy1, sy2); + int srcWidth = Math.abs(sx2 - sx1); + int srcHeight = Math.abs(sy2 - sy1); + int width = Math.abs(dx2 - dx1); + int height = Math.abs(dy2 - dy1); + + if ((srcX != 0) || (srcY != 0) + || (srcWidth != image.getWidth(observer)) + || (srcHeight != image.getHeight(observer))) { + // crop the source image + ImageFilter crop = new CropImageFilter(srcX, srcY, srcWidth, + srcHeight); + image = Toolkit.getDefaultToolkit().createImage( + new FilteredImageSource(image.getSource(), crop)); + MediaTracker mediaTracker = new MediaTracker(new Panel()); + mediaTracker.addImage(image, 0); + try { + mediaTracker.waitForAll(); + } catch (InterruptedException e) { + handleException(e); + } + } + + boolean flipHorizontal = (dx2 < dx1) ^ (sx2 < sx1); // src flipped + // and not dest + // flipped or + // vice versa + boolean flipVertical = (dy2 < dy1) ^ (sy2 < sy1); // <=> source + // flipped XOR + // dest flipped + + double tx = (flipHorizontal) ? (double) dx2 : (double) dx1; + double ty = (flipVertical) ? (double) dy2 : (double) dy1; + + double sx = (double) width / srcWidth; + sx = flipHorizontal ? -1 * sx : sx; + double sy = (double) height / srcHeight; + sy = flipVertical ? -1 * sy : sy; + + writeImage(ImageUtilities.createRenderedImage(image, observer, + bgColor), new AffineTransform(sx, 0, 0, sy, tx, ty), + bgColor); + return true; + } catch (IOException e) { + handleException(e); + return false; + } + } + + /* + * // first use the original orientation int clippingWidth = Math.abs(sx2 - + * sx1); int clippingHeight = Math.abs(sy2 - sy1); int sulX = Math.min(sx1, + * sx2); int sulY = Math.min(sy1, sy2); Image background = null; if (bgColor + * != null) { // Draw the image on the background color // maybe we could + * crop it and fill the transparent pixels in one go // by means of a + * filter. background = new BufferedImage(clippingWidth, clippingHeight, + * BufferedImage.TYPE_INT_ARGB); Graphics bgGfx = background.getGraphics(); + * bgGfx.drawImage(image, 0, 0, clippingWidth, clippingWidth, sulX, sulY, + * sulX+clippingWidth, sulY+clippingHeight, getPrintColor(bgColor), + * observer); } else { // crop the source image ImageFilter crop = new + * CropImageFilter(sulX, sulY, clippingWidth, clippingHeight); background = + * Toolkit.getDefaultToolkit().createImage(new + * FilteredImageSource(image.getSource(), crop)); MediaTracker mediaTracker + * = new MediaTracker(new Panel()); mediaTracker.addImage(background, 0); + * try { mediaTracker.waitForAll(); } catch (InterruptedException e) { + * handleException(e); } } // now flip the image if necessary boolean + * flipHorizontal = (dx2 source flipped XOR dest flipped int destWidth = Math.abs(dx2-dx1); + * int destHeight = Math.abs(dy2-dy1); try { return writeImage(background, + * flipHorizontal ? dx2 : dx1, flipVertical ? dy2 : dy1, flipHorizontal ? + * -destWidth : destWidth, flipVertical ? -destHeight : destHeight, (bgColor + * == null), observer); } catch (IOException e) { return false; } } + */ + /** + * Draws a rendered image using a transform. + * + * @param image + * to be drawn + * @param xform + * transform to be used on the image + */ + public void drawRenderedImage(RenderedImage image, AffineTransform xform) { + try { + writeImage(image, xform, null); + } catch (Exception e) { + handleException(e); + } + } + + protected abstract void writeImage(RenderedImage image, + AffineTransform xform, Color bkg) throws IOException; + + /** + * Clears rectangle by painting it with the backgroundColor. + * + * @param x + * rectangle to be cleared. + * @param y + * rectangle to be cleared. + * @param width + * rectangle to be cleared. + * @param height + * rectangle to be cleared. + */ + public void clearRect(double x, double y, double width, double height) { + Paint temp = getPaint(); + setPaint(getBackground()); + fillRect(x, y, width, height); + setPaint(temp); + } + + /** + * Draws the string at (x, y). If TEXT_AS_SHAPES is set + * {@link #drawGlyphVector(java.awt.font.GlyphVector, float, float)} is + * used, otherwise {@link #writeString(String, double, double)} for a more + * direct output of the string. + * + * @param string + * @param x + * @param y + */ + public void drawString(String string, double x, double y) { + // something to draw? + if (string == null || string.equals("")) { //$NON-NLS-1$ + return; + } + + // draw strings directly? + if (isProperty(TEXT_AS_SHAPES)) { + + Font font = getFont(); + + // NOTE, see FVG-199, createGlyphVector does not seem to create the + // proper glyphcodes + // for either ZapfDingbats or Symbol. We use our own encoding which + // seems to work... + String fontName = font.getName(); + if (fontName.equals("Symbol") || fontName.equals("ZapfDingbats")) { //$NON-NLS-1$ //$NON-NLS-2$ + string = FontEncoder.getEncodedString(string, fontName); + // use a standard font, not Symbol. + font = new Font("Serif", font.getStyle(), font.getSize()); //$NON-NLS-1$ + } + + // create glyph + GlyphVector gv = font.createGlyphVector(getFontRenderContext(), + string); + + // draw it + drawGlyphVector(gv, (float) x, (float) y); + } else { + // write string directly + try { + writeString(string, x, y); + } catch (IOException e) { + handleException(e); + } + } + } + + protected abstract void writeString(String string, double x, double y) + throws IOException; + + /** + * Use the transformation of the glyphvector and draw it + * + * @param g + * @param x + * @param y + */ + public void drawGlyphVector(GlyphVector g, float x, float y) { + fill(g.getOutline(x, y)); + } + + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + + // TextLayout draws the iterator as glyph vector + // thats why we use it only in the case of TEXT_AS_SHAPES, + // otherwise tagged strings are always written as glyphs + if (isProperty(TEXT_AS_SHAPES)) { + // draws all attributes + TextLayout tl = new TextLayout(iterator, getFontRenderContext()); + tl.draw(this, x, y); + } else { + // reset to that font at the end + Font font = getFont(); + + // initial attributes, we us TextAttribute.equals() rather + // than Font.equals() because using Font.equals() we do + // not get a 'false' if underline etc. is changed + Map attributes = FontUtilities + .getAttributes(font); + + // stores all characters which are written with the same font + // if font is changed the buffer will be written and cleared + // after it + StringBuffer sb = new StringBuffer(); + + for (char c = iterator.first(); c != AttributedCharacterIterator.DONE; c = iterator + .next()) { + + // append c if font is not changed + if (attributes.equals(iterator.getAttributes())) { + sb.append(c); + + } else { + // TextLayout does not like 0 length strings + if (sb.length() > 0) { + // draw sb if font is changed + drawString(sb.toString(), x, y); + + // change the x offset for the next drawing + // FIXME: change y offset for vertical text + TextLayout tl = new TextLayout(sb.toString(), + attributes, getFontRenderContext()); + + // calculate real width + x = x + + Math.max(tl.getAdvance(), (float) tl + .getBounds().getWidth()); + } + + // empty sb + sb = new StringBuffer(); + sb.append(c); + + // change the font + attributes = iterator.getAttributes(); + setFont(new Font(attributes)); + } + } + + // draw the rest + if (sb.length() > 0) { + drawString(sb.toString(), x, y); + } + + // use the old font for the next string drawing + setFont(font); + } + } + + /* + * ========================================================================== + * ====== | 6. Transformations + * ============================================== + * ================================== + */ + /** + * Get the current transform. + * + * @return current transform + */ + public AffineTransform getTransform() { + return new AffineTransform(currentTransform); + } + + /** + * Set the current transform. Calls writeSetTransform(Transform). + * + * @param transform + * to be set + */ + public void setTransform(AffineTransform transform) { + // Fix for FREEHEP-569 + oldTransform.setTransform(currentTransform); + currentTransform.setTransform(transform); + try { + writeSetTransform(transform); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Transforms the current transform. Calls writeTransform(Transform) + * + * @param transform + * to be applied + */ + public void transform(AffineTransform transform) { + currentTransform.concatenate(transform); + try { + writeTransform(transform); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Translates the current transform. Calls writeTransform(Transform) + * + * @param x + * amount by which to translate + * @param y + * amount by which to translate + */ + public void translate(double x, double y) { + currentTransform.translate(x, y); + try { + writeTransform(new AffineTransform(1, 0, 0, 1, x, y)); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Rotate the current transform over the Z-axis. Calls + * writeTransform(Transform). Rotating with a positive angle theta rotates + * points on the positive x axis toward the positive y axis. + * + * @param theta + * radians over which to rotate + */ + public void rotate(double theta) { + currentTransform.rotate(theta); + try { + writeTransform(new AffineTransform(Math.cos(theta), + Math.sin(theta), -Math.sin(theta), Math.cos(theta), 0, 0)); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Scales the current transform. Calls writeTransform(Transform). + * + * @param sx + * amount used for scaling + * @param sy + * amount used for scaling + */ + public void scale(double sx, double sy) { + currentTransform.scale(sx, sy); + try { + writeTransform(new AffineTransform(sx, 0, 0, sy, 0, 0)); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Shears the current transform. Calls writeTransform(Transform). + * + * @param shx + * amount for shearing + * @param shy + * amount for shearing + */ + public void shear(double shx, double shy) { + currentTransform.shear(shx, shy); + try { + writeTransform(new AffineTransform(1, shy, shx, 1, 0, 0)); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Writes out the transform as it needs to be concatenated to the internal + * transform of the output format. If there is no implementation of an + * internal transform, then this method needs to do nothing, BUT all + * coordinates need to be transformed by the currentTransform before being + * written out. + * + * @param transform + * to be written + */ + protected abstract void writeTransform(AffineTransform transform) + throws IOException; + + /** + * Clears any existing transformation and sets the a new one. The default + * implementation calls writeTransform using the inverted affine transform + * to calculate it. s * + * + * @param transform + * to be written + */ + protected void writeSetTransform(AffineTransform transform) + throws IOException { + try { + AffineTransform deltaTransform = new AffineTransform(transform); + deltaTransform.concatenate(oldTransform.createInverse()); + writeTransform(deltaTransform); + } catch (NoninvertibleTransformException e) { + // ignored... + System.err.println("Warning: (ignored) Could not invert matrix: " //$NON-NLS-1$ + + oldTransform); + } + } + + /* + * ========================================================================== + * ====== | 7. Clipping + * ====================================================== + * ========================== + */ + + /** + * Gets the current clip in form of a Shape (Rectangle). + * + * @return current clip + */ + public Shape getClip() { + return (userClip != null) ? new Area(untransformShape(userClip)) : null; + } + + /** + * Gets the current clip in form of a Rectangle. + * + * @return current clip + */ + public Rectangle getClipBounds() { + Shape clip = getClip(); + return (clip != null) ? getClip().getBounds() : null; + } + + /** + * Gets the current clip in form of a Rectangle. + * + * @return current clip + */ + public Rectangle getClipBounds(Rectangle r) { + Rectangle bounds = getClipBounds(); + if (bounds != null) + r.setBounds(bounds); + return r; + } + + /** + * Clips rectangle. Calls clip(Rectangle). + * + * @param x + * rectangle for clipping + * @param y + * rectangle for clipping + * @param width + * rectangle for clipping + * @param height + * rectangle for clipping + */ + public void clipRect(int x, int y, int width, int height) { + clip(new Rectangle(x, y, width, height)); + } + + /** + * Clips rectangle. Calls clip(Rectangle2D). + * + * @param x + * rectangle for clipping + * @param y + * rectangle for clipping + * @param width + * rectangle for clipping + * @param height + * rectangle for clipping + */ + public void clipRect(double x, double y, double width, double height) { + clip(new Rectangle2D.Double(x, y, width, height)); + } + + /** + * Clips rectangle. Calls clip(Rectangle). + * + * @param x + * rectangle for clipping + * @param y + * rectangle for clipping + * @param width + * rectangle for clipping + * @param height + * rectangle for clipping + */ + public void setClip(int x, int y, int width, int height) { + setClip(new Rectangle(x, y, width, height)); + } + + /** + * Clips rectangle. Calls clip(Rectangle2D). + * + * @param x + * rectangle for clipping + * @param y + * rectangle for clipping + * @param width + * rectangle for clipping + * @param height + * rectangle for clipping + */ + public void setClip(double x, double y, double width, double height) { + setClip(new Rectangle2D.Double(x, y, width, height)); + } + + /** + * Clips shape. Clears userClip and calls clip(Shape). + * + * @param s + * used for clipping + */ + public void setClip(Shape s) { + Shape ts = transformShape(s); + userClip = (ts != null) ? new Area(ts) : null; + + try { + writeSetClip(s); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Clips using given shape. Dispatches to writeClip(Rectangle), + * writeClip(Rectangle2D) or writeClip(Shape). + * + * @param s + * used for clipping + */ + public void clip(Shape s) { + Shape ts = transformShape(s); + if (userClip != null) { + if (ts != null) { + userClip.intersect(new Area(ts)); + } else { + userClip = null; + } + } else { + userClip = (ts != null) ? new Area(ts) : null; + } + + try { + writeClip(s); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Write out Shape clip. + * + * @param shape + * to be used for clipping + */ + protected abstract void writeClip(Shape shape) throws IOException; + + /** + * Write out Shape clip. + * + * @param shape + * to be used for clipping + */ + protected abstract void writeSetClip(Shape shape) throws IOException; + + /* + * ========================================================================== + * ====== | 8. Graphics State + * ================================================ + * ================================ + */ + /* 8.1. stroke/linewidth */ + /** + * Get the current stroke. + * + * @return current stroke + */ + public Stroke getStroke() { + return currentStroke; + } + + /** + * Sets the current stroke. Calls writeStroke if stroke is unequal to the + * current stroke. + * + * @param stroke + * to be set + */ + public void setStroke(Stroke stroke) { + if (stroke.equals(currentStroke)) { + return; + } + try { + writeStroke(stroke); + } catch (IOException e) { + handleException(e); + } + currentStroke = stroke; + } + + /** + * Writes the current stroke. If stroke is an instance of BasicStroke it + * will call writeWidth, writeCap, writeJoin, writeMiterLimit and writeDash, + * if any were different than the current stroke. + */ + protected void writeStroke(Stroke stroke) throws IOException { + if (stroke instanceof BasicStroke) { + BasicStroke ns = (BasicStroke) stroke; + + // get the current values for comparison if available, + // otherwise set them to -1="undefined" + int currentCap = -1, currentJoin = -1; + float currentWidth = -1, currentLimit = -1, currentDashPhase = -1; + float[] currentDashArray = null; + if ((currentStroke != null) + && (currentStroke instanceof BasicStroke)) { + BasicStroke cs = (BasicStroke) currentStroke; + currentCap = cs.getEndCap(); + currentJoin = cs.getLineJoin(); + currentWidth = cs.getLineWidth(); + currentLimit = cs.getMiterLimit(); + currentDashArray = cs.getDashArray(); + currentDashPhase = cs.getDashPhase(); + } + + // Check the linewidth. + float width = ns.getLineWidth(); + // if (currentWidth != width) { + writeWidth(width); + // } + + // Check the line caps. + int cap = ns.getEndCap(); + if (currentCap != cap) { + writeCap(cap); + } + + // Check the line joins. + int join = ns.getLineJoin(); + if (currentJoin != join) { + writeJoin(join); + } + + // Check the miter limit and validity of value + float limit = ns.getMiterLimit(); + if ((currentLimit != limit) && (limit >= 1.0f)) { + writeMiterLimit(limit); + } + + // Check to see if there are differences in the phase or dash + // if (!Arrays.equals(currentDashArray, ns.getDashArray()) + // || (currentDashPhase != ns.getDashPhase())) { + + // write the dashing parameters + if (ns.getDashArray() != null) { + writeDash(ns.getDashArray(), ns.getDashPhase()); + } else { + writeDash(new float[0], ns.getDashPhase()); + } + // } + } + } + + /** + * Writes out the width of the stroke. + * + * @param width + * of the stroke + */ + protected void writeWidth(float width) throws IOException { + writeWarning(getClass() + ": writeWidth() not implemented."); //$NON-NLS-1$ + } + + /** + * Writes out the cap of the stroke. + * + * @param cap + * of the stroke + */ + protected void writeCap(int cap) throws IOException { + writeWarning(getClass() + ": writeCap() not implemented."); //$NON-NLS-1$ + } + + /** + * Writes out the join of the stroke. + * + * @param join + * of the stroke + */ + protected void writeJoin(int join) throws IOException { + writeWarning(getClass() + ": writeJoin() not implemented."); //$NON-NLS-1$ + } + + /** + * Writes out the miter limit of the stroke. + * + * @param limit + * miter limit of the stroke + */ + protected void writeMiterLimit(float limit) throws IOException { + writeWarning(getClass() + ": writeMiterLimit() not implemented."); //$NON-NLS-1$ + } + + /** + * Writes out the dash of the stroke. + * + * @param dash + * dash pattern, empty array is solid line + * @param phase + * of the dash pattern + */ + protected void writeDash(float[] dash, float phase) throws IOException { + // for backward compatibility + double[] dd = new double[dash.length]; + for (int i = 0; i < dash.length; i++) { + dd[i] = dash[i]; + } + writeDash(dd, (double) phase); + } + + /** + * Writes out the dash of the stroke. + * + * @deprecated use writeDash(float[], float) + * @param dash + * dash pattern, empty array is solid line + * @param phase + * of the dash pattern + */ + protected void writeDash(double[] dash, double phase) throws IOException { + writeWarning(getClass() + ": writeDash() not implemented."); //$NON-NLS-1$ + } + + /* 8.2 Paint */ + public void setColor(Color color) { + if (color == null) + return; + + // if (color.equals(getColor())) + // return; + + try { + super.setColor(color); + writePaint(getPrintColor(color)); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Sets the current paint. Dispatches to writePaint(Color), + * writePaint(GradientPaint), writePaint(TexturePaint paint) or + * writePaint(Paint). In the case paint is a Color the current color is also + * changed. + * + * @param paint + * to be set + */ + public void setPaint(Paint paint) { + if (paint == null) + return; + + // if (paint.equals(getPaint())) + // return; + + try { + if (paint instanceof Color) { + setColor((Color) paint); + } else if (paint instanceof GradientPaint) { + super.setPaint(paint); + writePaint((GradientPaint) paint); + } else if (paint instanceof TexturePaint) { + super.setPaint(paint); + writePaint((TexturePaint) paint); + } else { + super.setPaint(paint); + writePaint(paint); + } + } catch (IOException e) { + handleException(e); + } + } + + /** + * Writes out paint as the given color. + * + * @param color + * to be written + */ + protected abstract void writePaint(Color color) throws IOException; + + /** + * Writes out paint as the given gradient. + * + * @param paint + * to be written + */ + protected abstract void writePaint(GradientPaint paint) throws IOException; + + /** + * Writes out paint as the given texture. + * + * @param paint + * to be written + */ + protected abstract void writePaint(TexturePaint paint) throws IOException; + + /** + * Writes out paint. + * + * @param paint + * to be written + */ + protected abstract void writePaint(Paint paint) throws IOException; + + /* 8.3. font */ + /** + * Gets the current font render context. This returns an standard + * FontRenderContext with anti-aliasing and uses fractional metrics. + * + * @return current font render context + */ + public FontRenderContext getFontRenderContext() { + // NOTE: not sure? + // Fixed for VG-285 + return new FontRenderContext(new AffineTransform(1, 0, 0, 1, 0, 0), + true, true); + } + + /** + * Gets the fontmetrics. + * + * @deprecated + * @param font + * to be used for retrieving fontmetrics + * @return fontmetrics for given font + */ + public FontMetrics getFontMetrics(Font font) { + return Toolkit.getDefaultToolkit().getFontMetrics(font); + } + + /* 8.4. rendering hints */ + /** + * Gets a copy of the rendering hints. + * + * @return clone of table of rendering hints. + */ + public RenderingHints getRenderingHints() { + return (RenderingHints) hints.clone(); + } + + /** + * Adds to table of rendering hints. + * + * @param hints + * table to be added + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void addRenderingHints(Map hints) { + hints.putAll(hints); + } + + /** + * Sets table of rendering hints. + * + * @param hints + * table to be set + */ + @SuppressWarnings("rawtypes") + public void setRenderingHints(Map hints) { + this.hints.clear(); + if (hints instanceof RenderingHints) { + RenderingHints renderingHints = (RenderingHints) hints; + this.hints.putAll((Map) renderingHints.clone()); + } else { + this.hints.putAll(hints); + } + } + + /** + * Gets a given rendering hint. + * + * @param key + * hint key + * @return hint associated to key + */ + public Object getRenderingHint(RenderingHints.Key key) { + return hints.get(key); + } + + /** + * Sets a given rendering hint. + * + * @param key + * hint key + * @param hint + * to be associated with key + */ + public void setRenderingHint(RenderingHints.Key key, Object hint) { + // extra protection, failed on under MacOS X 10.2.6, jdk 1.4.1_01-39/14 + if ((key == null) || (hint == null)) + return; + hints.put(key, hint); + } + + /** + * Sets the current font. + * + * @param font + * to be set + */ + public void setFont(Font font) { + if (font == null) + return; + + // FIXME: maybe add delayed setting + super.setFont(font); + + // write the font + try { + writeFont(font); + } catch (IOException e) { + handleException(e); + } + } + + /** + * Writes the font + * + * @param font + * to be written + */ + protected abstract void writeFont(Font font) throws IOException; + + /* + * ========================================================================== + * ====== | 9. Auxiliary + * ==================================================== + * ============================ + */ + /** + * Gets current composite. + * + * @return current composite + */ + public Composite getComposite() { + return currentComposite; + } + + /** + * Sets current composite. + * + * @param composite + * to be set + */ + public void setComposite(Composite composite) { + currentComposite = composite; + } + + /** + * Handles an exception which has been caught. Dispatches exception to + * writeWarning for UnsupportedOperationExceptions and writeError for others + * + * @param exception + * to be handled + */ + protected void handleException(Exception exception) { + if (exception instanceof UnsupportedOperationException) { + writeWarning(exception); + } else { + writeError(exception); + } + } + + /** + * Writes out a warning, by default to System.err. + * + * @param exception + * warning to be written + */ + protected void writeWarning(Exception exception) { + writeWarning(exception.getMessage()); + } + + /** + * Writes out a warning, by default to System.err. + * + * @param warning + * to be written + */ + protected void writeWarning(String warning) { + if (isProperty(EMIT_WARNINGS)) { + System.err.println(warning); + } + } + + /** + * Writes out an error, by default the stack trace is printed. + * + * @param exception + * error to be reported + */ + protected void writeError(Exception exception) { + throw new RuntimeException(exception); + // FIXME decide what we should do + /* + * if (isProperty(EMIT_ERRORS)) { System.err.println(exception); + * exception.printStackTrace(System.err); } + */ + } + + protected Shape createShape(double[] xPoints, double[] yPoints, + int nPoints, boolean close) { + GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + if (nPoints > 0) { + path.moveTo((float) xPoints[0], (float) yPoints[0]); + for (int i = 1; i < nPoints; i++) { + path.lineTo((float) xPoints[i], (float) yPoints[i]); + } + if (close) + path.closePath(); + } + return path; + } + + private Shape transformShape(AffineTransform at, Shape s) { + if (s == null) + return null; + return at.createTransformedShape(s); + } + + private Shape transformShape(Shape s) { + return transformShape(getTransform(), s); + } + + private Shape untransformShape(Shape s) { + if (s == null) + return null; + try { + return transformShape(getTransform().createInverse(), s); + } catch (NoninvertibleTransformException e) { + return null; + } + } + + /** + * Draws an overline for the text at (x, y). The method is usesefull for + * drivers that do not support overlines by itself. + * + * @param text + * text for width calulation + * @param font + * font for width calulation + * @param x + * position of text + * @param y + * position of text + */ + protected void overLine(String text, Font font, float x, float y) { + TextLayout layout = new TextLayout(text, font, getFontRenderContext()); + float width = Math.max(layout.getAdvance(), (float) layout.getBounds() + .getWidth()); + + GeneralPath path = new GeneralPath(); + path.moveTo(x, + y + (float) layout.getBounds().getY() - layout.getAscent()); + path.lineTo(x + width, + y + (float) layout.getBounds().getY() - layout.getAscent() + - layout.getAscent()); + draw(path); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/FontConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/FontConstants.java index e80bd312b..f42b549dd 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/FontConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/FontConstants.java @@ -1,28 +1,28 @@ -// Copyright 2003, FreeHEP. -package org.xmind.org.freehep.graphicsio; - -/** - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class FontConstants { - - private FontConstants() { - } - - // Font Embedding - public static final String EMBED_FONTS = "EmbedFonts"; //$NON-NLS-1$ - - public static final String EMBED_FONTS_AS = "EmbedFontsAs"; //$NON-NLS-1$ - - public static final String EMBED_FONTS_TYPE1 = "Type1"; //$NON-NLS-1$ - - public static final String EMBED_FONTS_TYPE3 = "Type3"; //$NON-NLS-1$ - - public static final String TEXT_AS_SHAPES = "TEXT_AS_SHAPES"; //$NON-NLS-1$ - - public static final String[] getEmbedFontsAsList() { - return new String[] { EMBED_FONTS_TYPE1, EMBED_FONTS_TYPE3 }; - } -} +// Copyright 2003, FreeHEP. +package org.xmind.org.freehep.graphicsio; + +/** + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class FontConstants { + + private FontConstants() { + } + + // Font Embedding + public static final String EMBED_FONTS = "EmbedFonts"; //$NON-NLS-1$ + + public static final String EMBED_FONTS_AS = "EmbedFontsAs"; //$NON-NLS-1$ + + public static final String EMBED_FONTS_TYPE1 = "Type1"; //$NON-NLS-1$ + + public static final String EMBED_FONTS_TYPE3 = "Type3"; //$NON-NLS-1$ + + public static final String TEXT_AS_SHAPES = "TEXT_AS_SHAPES"; //$NON-NLS-1$ + + public static final String[] getEmbedFontsAsList() { + return new String[] { EMBED_FONTS_TYPE1, EMBED_FONTS_TYPE3 }; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageConstants.java index 34bc4551a..b6ae6636e 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageConstants.java @@ -1,159 +1,159 @@ -// Copyright 2003-2007, FreeHEP. -package org.xmind.org.freehep.graphicsio; - -/** - * - * @author Mark Donszelmann - * @author Steffen Greiffenberg - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class ImageConstants { - - private ImageConstants() { - } - - /** - * general purpose data compression / decompression - */ - public static final String ZLIB = "ZLIB"; - - /** - * image format "raw" - */ - public static final String RAW = "RAW"; - - /** - * image format "portable network graphics" - */ - public static final String PNG = "PNG"; - - /** - * image format "joint photographic experts group" - */ - public static final String JPG = "JPG"; - - /** - * image format "joint photographic experts group" - */ - public static final String JPEG = "JPEG"; - - /** - * image format "graphics interchange format " - */ - public static final String GIF = "GIF"; - - /** - * image format "portable pixmap" - */ - public static final String PPM = "PPM"; - - /** - * image format "bitmap" - */ - public static final String BMP = "BMP"; - - /** - * image format "windows bitmap" - */ - public static final String WBMP = "WBMP"; - - /** - * image format "enhanced metafile" - */ - public static final String EMF = "EMF"; - - /** - * image format "java" - */ - public static final String JAVA = "JAVA"; - - /** - * image format "scalable vector graphic" - */ - public static final String SVG = "SVG"; - - /** - * image format "shockwave flash" - */ - public static final String SWF = "SWF"; - - /** - * image / document format "portable document format" - */ - public static final String PDF = "PDF"; - - /** - * image / document format "postscript" - */ - public static final String PS = "PS"; - - /** - * key for {@link org.xmind.org.freehep.util.UserProperties} that stores image format - */ - public static final String WRITE_IMAGES_AS = "WriteImagesAs"; - - /** - * key for {@link org.xmind.org.freehep.util.UserProperties} that stores a - * {@link java.awt.Dimension} for image size - */ - public static final String IMAGE_SIZE = "ImageSize"; - - /** - * value for {@link org.xmind.org.freehep.util.UserProperties} with key IMAGE_SIZE - * (alternative for a certain dimension to choose cmallest image size) - */ - public static final String SMALLEST = "Smallest Size"; - - /** - * used for ASCII 85 encoding using a - * {@link org.xmind.org.freehep.util.io.ASCII85OutputStream} - * - * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, - * String, String, java.util.Properties) - */ - public final static String ENCODING_ASCII85 = "ASCII85"; - - /** - * zip encoding used for converting Images to byte[] - * - * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, - * String, String, java.util.Properties) - */ - public final static String ENCODING_FLATE = "Flate"; - - /** - * used for compressed ASCII 85 encoding using a - * {@link org.xmind.org.freehep.util.io.ASCII85OutputStream} - * - * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, - * String, String, java.util.Properties) - */ - public final static String ENCODING_FLATE_ASCII85 = ENCODING_FLATE + "-" - + ENCODING_ASCII85; - - /** - * Discrete Cosine Transform for JPEG uses an ASCII85OutputStream - * - * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, - * String, String, java.util.Properties) - */ - public final static String ENCODING_DCT = "DCT"; - - /** - * RGB ColorModel used by org.xmind.org.freehep.graphicsio.pdf.PDFStream and - * org.xmind.org.freehep.graphicsio.ps.PSGraphics2D - */ - public static final String COLOR_MODEL_RGB = "RGB"; - - /** - * Alpha (?) ColorModel used by org.xmind.org.freehep.graphicsio.swf.DefineBitsJPEG3 - */ - public static final String COLOR_MODEL_A = "A"; - - /** - * ColorModel used by org.xmind.org.freehep.graphicsio.swf.DefineBitsLossless - */ - public static final String COLOR_MODEL_ARGB = "*ARGB"; - -} +// Copyright 2003-2007, FreeHEP. +package org.xmind.org.freehep.graphicsio; + +/** + * + * @author Mark Donszelmann + * @author Steffen Greiffenberg + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class ImageConstants { + + private ImageConstants() { + } + + /** + * general purpose data compression / decompression + */ + public static final String ZLIB = "ZLIB"; + + /** + * image format "raw" + */ + public static final String RAW = "RAW"; + + /** + * image format "portable network graphics" + */ + public static final String PNG = "PNG"; + + /** + * image format "joint photographic experts group" + */ + public static final String JPG = "JPG"; + + /** + * image format "joint photographic experts group" + */ + public static final String JPEG = "JPEG"; + + /** + * image format "graphics interchange format " + */ + public static final String GIF = "GIF"; + + /** + * image format "portable pixmap" + */ + public static final String PPM = "PPM"; + + /** + * image format "bitmap" + */ + public static final String BMP = "BMP"; + + /** + * image format "windows bitmap" + */ + public static final String WBMP = "WBMP"; + + /** + * image format "enhanced metafile" + */ + public static final String EMF = "EMF"; + + /** + * image format "java" + */ + public static final String JAVA = "JAVA"; + + /** + * image format "scalable vector graphic" + */ + public static final String SVG = "SVG"; + + /** + * image format "shockwave flash" + */ + public static final String SWF = "SWF"; + + /** + * image / document format "portable document format" + */ + public static final String PDF = "PDF"; + + /** + * image / document format "postscript" + */ + public static final String PS = "PS"; + + /** + * key for {@link org.xmind.org.freehep.util.UserProperties} that stores image format + */ + public static final String WRITE_IMAGES_AS = "WriteImagesAs"; + + /** + * key for {@link org.xmind.org.freehep.util.UserProperties} that stores a + * {@link java.awt.Dimension} for image size + */ + public static final String IMAGE_SIZE = "ImageSize"; + + /** + * value for {@link org.xmind.org.freehep.util.UserProperties} with key IMAGE_SIZE + * (alternative for a certain dimension to choose cmallest image size) + */ + public static final String SMALLEST = "Smallest Size"; + + /** + * used for ASCII 85 encoding using a + * {@link org.xmind.org.freehep.util.io.ASCII85OutputStream} + * + * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, + * String, String, java.util.Properties) + */ + public final static String ENCODING_ASCII85 = "ASCII85"; + + /** + * zip encoding used for converting Images to byte[] + * + * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, + * String, String, java.util.Properties) + */ + public final static String ENCODING_FLATE = "Flate"; + + /** + * used for compressed ASCII 85 encoding using a + * {@link org.xmind.org.freehep.util.io.ASCII85OutputStream} + * + * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, + * String, String, java.util.Properties) + */ + public final static String ENCODING_FLATE_ASCII85 = ENCODING_FLATE + "-" + + ENCODING_ASCII85; + + /** + * Discrete Cosine Transform for JPEG uses an ASCII85OutputStream + * + * @see org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, + * String, String, java.util.Properties) + */ + public final static String ENCODING_DCT = "DCT"; + + /** + * RGB ColorModel used by org.xmind.org.freehep.graphicsio.pdf.PDFStream and + * org.xmind.org.freehep.graphicsio.ps.PSGraphics2D + */ + public static final String COLOR_MODEL_RGB = "RGB"; + + /** + * Alpha (?) ColorModel used by org.xmind.org.freehep.graphicsio.swf.DefineBitsJPEG3 + */ + public static final String COLOR_MODEL_A = "A"; + + /** + * ColorModel used by org.xmind.org.freehep.graphicsio.swf.DefineBitsLossless + */ + public static final String COLOR_MODEL_ARGB = "*ARGB"; + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageGraphics2D.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageGraphics2D.java index cb4bfc468..86ec35ad5 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageGraphics2D.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageGraphics2D.java @@ -1,602 +1,602 @@ -// Copyright 2003-2007, FreeHEP. -package org.xmind.org.freehep.graphicsio; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.awt.image.RenderedImage; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.imageio.IIOImage; -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.imageio.stream.ImageInputStream; -import javax.imageio.stream.ImageOutputStream; - -import org.xmind.org.freehep.graphics2d.PixelGraphics2D; -import org.xmind.org.freehep.graphicsio.raw.RawImageWriteParam; -import org.xmind.org.freehep.graphicsio.raw.RawImageWriter; -import org.xmind.org.freehep.graphicsio.raw.RawImageWriterSpi; -import org.xmind.org.freehep.util.UserProperties; -import org.xmind.org.freehep.util.images.ImageUtilities; -import org.xmind.org.freehep.util.io.ASCII85OutputStream; -import org.xmind.org.freehep.util.io.FlateOutputStream; - -/** - * Generic class for generating bitmap outputs from an image. - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class ImageGraphics2D extends PixelGraphics2D { - - private final static String alwaysCompressedFormats[] = { - ImageConstants.JPG.toLowerCase(), - ImageConstants.JPEG.toLowerCase(), ImageConstants.GIF.toLowerCase() }; - - private final static String nonTransparentFormats[] = { - ImageConstants.JPG.toLowerCase(), - ImageConstants.JPEG.toLowerCase(), ImageConstants.PPM.toLowerCase() }; - - public static final String rootKey = "org.xmind.org.freehep.graphicsio"; - - // our general properties - public static final String TRANSPARENT = "." + PageConstants.TRANSPARENT; - - public static final String BACKGROUND = "." + PageConstants.BACKGROUND; - - public static final String BACKGROUND_COLOR = "." - + PageConstants.BACKGROUND_COLOR; - - // our image properties - public static final String ANTIALIAS = ".Antialias"; - - public static final String ANTIALIAS_TEXT = ".AntialiasText"; - - // standard image properties - public static final String PROGRESSIVE = ".Progressive"; - - public static final String COMPRESS = ".Compress"; - - public static final String COMPRESS_MODE = ".CompressMode"; - - public static final String COMPRESS_DESCRIPTION = ".CompressDescription"; - - public static final String COMPRESS_QUALITY = ".CompressQuality"; - - private static final Map defaultProperties = new HashMap(); - - public static Properties getDefaultProperties(String format) { - UserProperties properties = (UserProperties) defaultProperties - .get(format); - if (properties == null) { - properties = new UserProperties(); - defaultProperties.put(format, properties); - - String formatKey = rootKey + "." + format; - - // set our parameters - if (canWriteTransparent(format)) { - properties.setProperty(formatKey + TRANSPARENT, true); - properties.setProperty(formatKey + BACKGROUND, false); - properties - .setProperty(formatKey + BACKGROUND_COLOR, Color.GRAY); - } else { - properties.setProperty(formatKey + BACKGROUND, false); - properties - .setProperty(formatKey + BACKGROUND_COLOR, Color.GRAY); - } - - // set our parameters - properties.setProperty(formatKey + ANTIALIAS, true); - properties.setProperty(formatKey + ANTIALIAS_TEXT, true); - - // copy parameters from specific format - ImageWriter writer = getPreferredImageWriter(format); - if (writer != null) { - ImageWriteParam param = writer.getDefaultWriteParam(); - - // compression - if (param.canWriteCompressed()) { - param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - properties.setProperty(formatKey + COMPRESS, true); - String[] compressionTypes = param.getCompressionTypes(); - String compressionType = param.getCompressionType(); - properties.setProperty(formatKey + COMPRESS_MODE, - compressionType != null ? compressionType - : compressionTypes[0]); - properties.setProperty(formatKey + COMPRESS_DESCRIPTION, - "Custom"); - float compressionQuality = 0.0f; - try { - compressionQuality = param.getCompressionQuality(); - } catch (IllegalStateException e) { - // ignored - } - properties.setProperty(formatKey + COMPRESS_QUALITY, - compressionQuality); - } else { - properties.setProperty(formatKey + COMPRESS, false); - properties.setProperty(formatKey + COMPRESS_MODE, ""); - properties.setProperty(formatKey + COMPRESS_DESCRIPTION, - "Custom"); - properties.setProperty(formatKey + COMPRESS_QUALITY, 0.0f); - } - - // progressive - if (param.canWriteProgressive()) { - properties - .setProperty( - formatKey + PROGRESSIVE, - param.getProgressiveMode() != ImageWriteParam.MODE_DISABLED); - } else { - properties.setProperty(formatKey + PROGRESSIVE, false); - } - } else { - System.err.println(ImageGraphics2D.class - + ": No writer for format '" + format + "'."); - } - } - return properties; - } - - public void setProperties(Properties newProperties) { - if (newProperties == null) - return; - - String formatKey = rootKey + "." + format; - Properties formatProperties = new Properties(); - for (Enumeration e = newProperties.propertyNames(); e - .hasMoreElements();) { - String key = (String) e.nextElement(); - String value = newProperties.getProperty(key); - if (key.indexOf("." + format) < 0) { - key = formatKey + key; - } - formatProperties.setProperty(key, value); - } - super.setProperties(formatProperties); - - setPropertiesOnGraphics(); - } - - private void setPropertiesOnGraphics() { - String formatKey = rootKey + "." + format; - if (isProperty(formatKey + ANTIALIAS)) { - setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - } else { - setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF); - } - - if (isProperty(formatKey + ANTIALIAS_TEXT)) { - setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - } else { - setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); - } - - if (isProperty(formatKey + TRANSPARENT)) { - setBackground(null); - } else if (isProperty(formatKey + BACKGROUND)) { - setBackground(getPropertyColor(formatKey + BACKGROUND_COLOR)); - } else { - setBackground(component != null ? component.getBackground() - : Color.WHITE); - } - } - - private void setHintsOnGraphics() { - if (format.equalsIgnoreCase(ImageConstants.JPG)) { - // since we draw JPG on non-transparent background, we cannot blit - // compatible images - setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_OFF); - } else { - setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_ON); - } - - } - - protected OutputStream os; - - protected BufferedImage image; - - protected String format; - - protected Component component; - - public ImageGraphics2D(File file, Dimension size, String format) - throws FileNotFoundException { - this(new FileOutputStream(file), size, format); - } - - public ImageGraphics2D(File file, Component component, String format) - throws FileNotFoundException { - this(new FileOutputStream(file), component, format); - } - - public ImageGraphics2D(OutputStream os, Dimension size, String format) { - super(); - init(os, size, format); - component = null; - } - - public ImageGraphics2D(OutputStream os, Component component, String format) { - super(); - this.component = component; - init(os, component.getSize(), format); - - setColor(component.getForeground()); - GraphicsConfiguration gc = component.getGraphicsConfiguration(); - if (gc != null) - setTransform(gc.getDefaultTransform()); - } - - private void init(OutputStream os, Dimension size, String format) { - this.os = os; - this.format = format; - - initProperties(getDefaultProperties(format)); - - // create actual graphics - image = createBufferedImage(format, size.width, size.height); - setHostGraphics(image.getGraphics()); - - // set graphics properties - setPropertiesOnGraphics(); - - // set graphics hints - setHintsOnGraphics(); - - // Ensure that a clipping path is set on this graphics - // context. This avoids a null pointer exception inside of - // a JLayeredPane when printing. - hostGraphics.clipRect(0, 0, size.width, size.height); - } - - protected ImageGraphics2D(ImageGraphics2D graphics) { - super(graphics); - image = graphics.image; - os = graphics.os; - format = graphics.format; - - // make sure all hints are copied. - setHintsOnGraphics(); - } - - public Graphics create() { - return new ImageGraphics2D(this); - } - - public Graphics create(double x, double y, double width, double height) { - ImageGraphics2D imageGraphics = new ImageGraphics2D(this); - imageGraphics.translate(x, y); - imageGraphics.clipRect(0, 0, width, height); - return imageGraphics; - } - - public void startExport() { - if (getBackground() != null) { - clearRect(0.0, 0.0, image.getWidth(), image.getHeight()); - } - } - - public void endExport() { - try { - write(); - closeStream(); - } catch (IOException e) { - handleException(e); - } - } - - protected void write() throws IOException { - writeImage((RenderedImage) image, format, getProperties(), os); - } - - public void closeStream() throws IOException { - os.close(); - } - - /** - * Handles an exception which has been caught. Dispatches exception to - * writeWarning for UnsupportedOperationExceptions and writeError for others - * - * @param exception - * to be handled - */ - protected void handleException(Exception exception) { - System.err.println(exception); - } - - /** - * creates an empty image - * - * @param format - * e.g. {@link ImageConstants#BMP} or {ImageConstants#PNG} - * @param width - * image width - * @param height - * image height - * @return offscreen buffered image - */ - public static BufferedImage createBufferedImage(String format, int width, - int height) { - - // NOTE: special case for WBMP which only - // supports on color band with sample size 1 - // (which means black / white with no gray scale) - if (ImageConstants.WBMP.equalsIgnoreCase(format)) { - return new BufferedImage(width, height, - BufferedImage.TYPE_BYTE_BINARY); - } - - // NOTE: special case for JPEG which has no Alpha - if (ImageConstants.JPG.equalsIgnoreCase(format)) { - return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - } - - // NOTE: special case for BMP which has no Alpha - if (ImageConstants.BMP.equalsIgnoreCase(format)) { - return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - } - - return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - } - - public static BufferedImage generateThumbnail(Component component, - Dimension size) { - int longSide = Math.max(size.width, size.height); - if (longSide < 0) - return null; - - int componentWidth = component.getBounds().width; - int componentHeight = component.getBounds().height; - - BufferedImage image = new BufferedImage(componentWidth, - componentHeight, BufferedImage.TYPE_INT_ARGB); - Graphics imageGraphics = image.getGraphics(); - component.print(imageGraphics); - - int width = longSide; - int height = longSide; - if (componentWidth < componentHeight) { - width = componentWidth * size.height / componentHeight; - } else { - height = componentHeight * size.width / componentWidth; - } - - BufferedImage scaled = new BufferedImage(width, height, - BufferedImage.TYPE_INT_ARGB); - Graphics scaledGraphics = scaled.getGraphics(); - scaledGraphics.drawImage(image, 0, 0, width, height, null); - - return scaled; - } - - public static void writeImage(Image image, String format, - Properties properties, OutputStream os) throws IOException { - // FIXME hardcoded background - writeImage( - ImageUtilities.createRenderedImage(image, null, Color.black), - format, properties, os); - } - - public static void writeImage(RenderedImage image, String format, - Properties properties, OutputStream os) throws IOException { - - ImageWriter writer = getPreferredImageWriter(format); - if (writer == null) - throw new IOException(ImageGraphics2D.class - + ": No writer for format '" + format + "'."); - - // get the parameters for this format - UserProperties user = new UserProperties(properties); - ImageWriteParam param = writer.getDefaultWriteParam(); - if (param instanceof ImageParamConverter) { - param = ((ImageParamConverter) param).getWriteParam(user); - } - - // now set the standard write parameters - String formatKey = rootKey + "." + format; - if (param.canWriteCompressed()) { - if (user.isProperty(formatKey + COMPRESS)) { - if (user.getProperty(formatKey + COMPRESS_MODE).equals("")) { - param.setCompressionMode(ImageWriteParam.MODE_DEFAULT); - } else { - param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - param.setCompressionType(user.getProperty(formatKey - + COMPRESS_MODE)); - param.setCompressionQuality(user.getPropertyFloat(formatKey - + COMPRESS_QUALITY)); - } - } else { - if (canWriteUncompressed(format)) { - param.setCompressionMode(ImageWriteParam.MODE_DISABLED); - } - } - } - if (param.canWriteProgressive()) { - if (user.isProperty(formatKey + PROGRESSIVE)) { - param.setProgressiveMode(ImageWriteParam.MODE_DEFAULT); - } else { - param.setProgressiveMode(ImageWriteParam.MODE_DISABLED); - } - } - - // write the image - ImageOutputStream ios = ImageIO.createImageOutputStream(os); - writer.setOutput(ios); - writer.write(null, new IIOImage(image, null, null), param); - writer.dispose(); - try { - ios.close(); - } catch (Exception e) { - - } - } - - public static ImageWriter getPreferredImageWriter(String format) { - if (ImageConstants.RAW.toLowerCase().equals(format)) { - return (ImageWriter) new RawImageWriter(new RawImageWriterSpi()); - } - return (ImageWriter) getImageWriters( - ImageIO.getImageWritersByFormatName(format)).first(); - } - - public static ImageWriter getPreferredImageWriterForMIMEType(String mimeType) { - return (ImageWriter) getImageWriters( - ImageIO.getImageWritersByMIMEType(mimeType)).first(); - } - - public static SortedSet getImageWriters( - Iterator iterator) { - // look for a writer that supports the given format, - // BUT prefer our own "org.xmind.org.freehep." - // over "com.sun.imageio." over "com.sun.media." over others - SortedSet imageWriters = new TreeSet( - new Comparator() { - private int order(Object o) { - String className = o.getClass().getName(); - if (className.startsWith("org.xmind.org.freehep.")) { - return 0; - } else if (className.startsWith("com.sun.imageio.")) { - return 1; - } else if (className.startsWith("com.sun.media.")) { - return 2; - } - return 3; - } - - public int compare(Object arg0, Object arg1) { - int order0 = order(arg0); - int order1 = order(arg1); - return order0 < order1 ? -1 : order0 > order1 ? 1 : 0; - } - }); - while (iterator.hasNext()) { - imageWriters.add((ImageWriter) iterator.next()); - } - return imageWriters; - } - - public static BufferedImage readImage(String format, InputStream is) - throws IOException { - Iterator iterator = ImageIO - .getImageReadersByFormatName(format.toLowerCase()); - if (!iterator.hasNext()) { - throw new IOException(ImageGraphics2D.class - + ": No reader for format '" + format + "'."); - } - ImageReader reader = (ImageReader) iterator.next(); - - ImageInputStream iis = ImageIO.createImageInputStream(is); - reader.setInput(iis, true); - BufferedImage image = reader.read(0); - reader.dispose(); - iis.close(); - return image; - } - - public static boolean canWriteUncompressed(String format) { - // Method forgotten by Sun, BUG# 4856395. - // If param.canWriteCompressed() is true, then it may be that - // the format always needs to be compressed... GIF and JPG are among of - // them. - return !Arrays.asList(alwaysCompressedFormats).contains( - format.toLowerCase()); - } - - public static boolean canWriteTransparent(String format) { - return !Arrays.asList(nonTransparentFormats).contains( - format.toLowerCase()); - } - - /** - * @param bkg - * Background color for the image - * @return Properties used to create a RAW image - * @param code - * Color encoding, e.g. {@link ImageConstants#COLOR_MODEL_RGB} - */ - public static UserProperties getRAWProperties(Color bkg, String code) { - UserProperties result = new UserProperties(); - result.setProperty(RawImageWriteParam.BACKGROUND, bkg); - result.setProperty(RawImageWriteParam.CODE, code); - result.setProperty(RawImageWriteParam.PAD, 1); - return result; - } - - /** - * Converts a given image to byte[] - * - * @throws IOException - * thrown by - * {@link #writeImage(java.awt.image.RenderedImage, String, java.util.Properties, java.io.OutputStream)} - * @param image - * Image to convert - * @param format - * e.g. {@link ImageConstants#JPG}, {@link ImageConstants#PNG}, - * {@link ImageConstants#RAW} - * @param props - * Properties for writing, e.g. - * {@link org.xmind.org.freehep.graphicsio.raw.RawImageWriteParam#BACKGROUND} - * @param encoding - * {@link ImageConstants#ENCODING_ASCII85}, - * {@link ImageConstants#ENCODING_FLATE} or null - * @return bytes representing the image - */ - public static byte[] toByteArray(RenderedImage image, String format, - String encoding, Properties props) throws IOException { - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - OutputStream os = bos; - - if (ImageConstants.ENCODING_ASCII85.equals(encoding) - || ImageConstants.ENCODING_FLATE_ASCII85.equals(encoding)) { - os = new ASCII85OutputStream(os); - } - - if (ImageConstants.ENCODING_FLATE.equals(encoding) - || ImageConstants.ENCODING_FLATE_ASCII85.equals(encoding)) { - os = new FlateOutputStream(os); - } - - // avoid NPE - if (props == null) { - props = new Properties(); - } - - // write image into the stream - ImageGraphics2D.writeImage(image, format.toLowerCase(), props, os); - os.close(); - - // return reulting bytes from stream - return bos.toByteArray(); - } -} +// Copyright 2003-2007, FreeHEP. +package org.xmind.org.freehep.graphicsio; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; + +import org.xmind.org.freehep.graphics2d.PixelGraphics2D; +import org.xmind.org.freehep.graphicsio.raw.RawImageWriteParam; +import org.xmind.org.freehep.graphicsio.raw.RawImageWriter; +import org.xmind.org.freehep.graphicsio.raw.RawImageWriterSpi; +import org.xmind.org.freehep.util.UserProperties; +import org.xmind.org.freehep.util.images.ImageUtilities; +import org.xmind.org.freehep.util.io.ASCII85OutputStream; +import org.xmind.org.freehep.util.io.FlateOutputStream; + +/** + * Generic class for generating bitmap outputs from an image. + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class ImageGraphics2D extends PixelGraphics2D { + + private final static String alwaysCompressedFormats[] = { + ImageConstants.JPG.toLowerCase(), + ImageConstants.JPEG.toLowerCase(), ImageConstants.GIF.toLowerCase() }; + + private final static String nonTransparentFormats[] = { + ImageConstants.JPG.toLowerCase(), + ImageConstants.JPEG.toLowerCase(), ImageConstants.PPM.toLowerCase() }; + + public static final String rootKey = "org.xmind.org.freehep.graphicsio"; + + // our general properties + public static final String TRANSPARENT = "." + PageConstants.TRANSPARENT; + + public static final String BACKGROUND = "." + PageConstants.BACKGROUND; + + public static final String BACKGROUND_COLOR = "." + + PageConstants.BACKGROUND_COLOR; + + // our image properties + public static final String ANTIALIAS = ".Antialias"; + + public static final String ANTIALIAS_TEXT = ".AntialiasText"; + + // standard image properties + public static final String PROGRESSIVE = ".Progressive"; + + public static final String COMPRESS = ".Compress"; + + public static final String COMPRESS_MODE = ".CompressMode"; + + public static final String COMPRESS_DESCRIPTION = ".CompressDescription"; + + public static final String COMPRESS_QUALITY = ".CompressQuality"; + + private static final Map defaultProperties = new HashMap(); + + public static Properties getDefaultProperties(String format) { + UserProperties properties = (UserProperties) defaultProperties + .get(format); + if (properties == null) { + properties = new UserProperties(); + defaultProperties.put(format, properties); + + String formatKey = rootKey + "." + format; + + // set our parameters + if (canWriteTransparent(format)) { + properties.setProperty(formatKey + TRANSPARENT, true); + properties.setProperty(formatKey + BACKGROUND, false); + properties + .setProperty(formatKey + BACKGROUND_COLOR, Color.GRAY); + } else { + properties.setProperty(formatKey + BACKGROUND, false); + properties + .setProperty(formatKey + BACKGROUND_COLOR, Color.GRAY); + } + + // set our parameters + properties.setProperty(formatKey + ANTIALIAS, true); + properties.setProperty(formatKey + ANTIALIAS_TEXT, true); + + // copy parameters from specific format + ImageWriter writer = getPreferredImageWriter(format); + if (writer != null) { + ImageWriteParam param = writer.getDefaultWriteParam(); + + // compression + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + properties.setProperty(formatKey + COMPRESS, true); + String[] compressionTypes = param.getCompressionTypes(); + String compressionType = param.getCompressionType(); + properties.setProperty(formatKey + COMPRESS_MODE, + compressionType != null ? compressionType + : compressionTypes[0]); + properties.setProperty(formatKey + COMPRESS_DESCRIPTION, + "Custom"); + float compressionQuality = 0.0f; + try { + compressionQuality = param.getCompressionQuality(); + } catch (IllegalStateException e) { + // ignored + } + properties.setProperty(formatKey + COMPRESS_QUALITY, + compressionQuality); + } else { + properties.setProperty(formatKey + COMPRESS, false); + properties.setProperty(formatKey + COMPRESS_MODE, ""); + properties.setProperty(formatKey + COMPRESS_DESCRIPTION, + "Custom"); + properties.setProperty(formatKey + COMPRESS_QUALITY, 0.0f); + } + + // progressive + if (param.canWriteProgressive()) { + properties + .setProperty( + formatKey + PROGRESSIVE, + param.getProgressiveMode() != ImageWriteParam.MODE_DISABLED); + } else { + properties.setProperty(formatKey + PROGRESSIVE, false); + } + } else { + System.err.println(ImageGraphics2D.class + + ": No writer for format '" + format + "'."); + } + } + return properties; + } + + public void setProperties(Properties newProperties) { + if (newProperties == null) + return; + + String formatKey = rootKey + "." + format; + Properties formatProperties = new Properties(); + for (Enumeration e = newProperties.propertyNames(); e + .hasMoreElements();) { + String key = (String) e.nextElement(); + String value = newProperties.getProperty(key); + if (key.indexOf("." + format) < 0) { + key = formatKey + key; + } + formatProperties.setProperty(key, value); + } + super.setProperties(formatProperties); + + setPropertiesOnGraphics(); + } + + private void setPropertiesOnGraphics() { + String formatKey = rootKey + "." + format; + if (isProperty(formatKey + ANTIALIAS)) { + setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } else { + setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + } + + if (isProperty(formatKey + ANTIALIAS_TEXT)) { + setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } else { + setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + } + + if (isProperty(formatKey + TRANSPARENT)) { + setBackground(null); + } else if (isProperty(formatKey + BACKGROUND)) { + setBackground(getPropertyColor(formatKey + BACKGROUND_COLOR)); + } else { + setBackground(component != null ? component.getBackground() + : Color.WHITE); + } + } + + private void setHintsOnGraphics() { + if (format.equalsIgnoreCase(ImageConstants.JPG)) { + // since we draw JPG on non-transparent background, we cannot blit + // compatible images + setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_OFF); + } else { + setRenderingHint(KEY_SYMBOL_BLIT, VALUE_SYMBOL_BLIT_ON); + } + + } + + protected OutputStream os; + + protected BufferedImage image; + + protected String format; + + protected Component component; + + public ImageGraphics2D(File file, Dimension size, String format) + throws FileNotFoundException { + this(new FileOutputStream(file), size, format); + } + + public ImageGraphics2D(File file, Component component, String format) + throws FileNotFoundException { + this(new FileOutputStream(file), component, format); + } + + public ImageGraphics2D(OutputStream os, Dimension size, String format) { + super(); + init(os, size, format); + component = null; + } + + public ImageGraphics2D(OutputStream os, Component component, String format) { + super(); + this.component = component; + init(os, component.getSize(), format); + + setColor(component.getForeground()); + GraphicsConfiguration gc = component.getGraphicsConfiguration(); + if (gc != null) + setTransform(gc.getDefaultTransform()); + } + + private void init(OutputStream os, Dimension size, String format) { + this.os = os; + this.format = format; + + initProperties(getDefaultProperties(format)); + + // create actual graphics + image = createBufferedImage(format, size.width, size.height); + setHostGraphics(image.getGraphics()); + + // set graphics properties + setPropertiesOnGraphics(); + + // set graphics hints + setHintsOnGraphics(); + + // Ensure that a clipping path is set on this graphics + // context. This avoids a null pointer exception inside of + // a JLayeredPane when printing. + hostGraphics.clipRect(0, 0, size.width, size.height); + } + + protected ImageGraphics2D(ImageGraphics2D graphics) { + super(graphics); + image = graphics.image; + os = graphics.os; + format = graphics.format; + + // make sure all hints are copied. + setHintsOnGraphics(); + } + + public Graphics create() { + return new ImageGraphics2D(this); + } + + public Graphics create(double x, double y, double width, double height) { + ImageGraphics2D imageGraphics = new ImageGraphics2D(this); + imageGraphics.translate(x, y); + imageGraphics.clipRect(0, 0, width, height); + return imageGraphics; + } + + public void startExport() { + if (getBackground() != null) { + clearRect(0.0, 0.0, image.getWidth(), image.getHeight()); + } + } + + public void endExport() { + try { + write(); + closeStream(); + } catch (IOException e) { + handleException(e); + } + } + + protected void write() throws IOException { + writeImage((RenderedImage) image, format, getProperties(), os); + } + + public void closeStream() throws IOException { + os.close(); + } + + /** + * Handles an exception which has been caught. Dispatches exception to + * writeWarning for UnsupportedOperationExceptions and writeError for others + * + * @param exception + * to be handled + */ + protected void handleException(Exception exception) { + System.err.println(exception); + } + + /** + * creates an empty image + * + * @param format + * e.g. {@link ImageConstants#BMP} or {ImageConstants#PNG} + * @param width + * image width + * @param height + * image height + * @return offscreen buffered image + */ + public static BufferedImage createBufferedImage(String format, int width, + int height) { + + // NOTE: special case for WBMP which only + // supports on color band with sample size 1 + // (which means black / white with no gray scale) + if (ImageConstants.WBMP.equalsIgnoreCase(format)) { + return new BufferedImage(width, height, + BufferedImage.TYPE_BYTE_BINARY); + } + + // NOTE: special case for JPEG which has no Alpha + if (ImageConstants.JPG.equalsIgnoreCase(format)) { + return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } + + // NOTE: special case for BMP which has no Alpha + if (ImageConstants.BMP.equalsIgnoreCase(format)) { + return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } + + return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + } + + public static BufferedImage generateThumbnail(Component component, + Dimension size) { + int longSide = Math.max(size.width, size.height); + if (longSide < 0) + return null; + + int componentWidth = component.getBounds().width; + int componentHeight = component.getBounds().height; + + BufferedImage image = new BufferedImage(componentWidth, + componentHeight, BufferedImage.TYPE_INT_ARGB); + Graphics imageGraphics = image.getGraphics(); + component.print(imageGraphics); + + int width = longSide; + int height = longSide; + if (componentWidth < componentHeight) { + width = componentWidth * size.height / componentHeight; + } else { + height = componentHeight * size.width / componentWidth; + } + + BufferedImage scaled = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + Graphics scaledGraphics = scaled.getGraphics(); + scaledGraphics.drawImage(image, 0, 0, width, height, null); + + return scaled; + } + + public static void writeImage(Image image, String format, + Properties properties, OutputStream os) throws IOException { + // FIXME hardcoded background + writeImage( + ImageUtilities.createRenderedImage(image, null, Color.black), + format, properties, os); + } + + public static void writeImage(RenderedImage image, String format, + Properties properties, OutputStream os) throws IOException { + + ImageWriter writer = getPreferredImageWriter(format); + if (writer == null) + throw new IOException(ImageGraphics2D.class + + ": No writer for format '" + format + "'."); + + // get the parameters for this format + UserProperties user = new UserProperties(properties); + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param instanceof ImageParamConverter) { + param = ((ImageParamConverter) param).getWriteParam(user); + } + + // now set the standard write parameters + String formatKey = rootKey + "." + format; + if (param.canWriteCompressed()) { + if (user.isProperty(formatKey + COMPRESS)) { + if (user.getProperty(formatKey + COMPRESS_MODE).equals("")) { + param.setCompressionMode(ImageWriteParam.MODE_DEFAULT); + } else { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionType(user.getProperty(formatKey + + COMPRESS_MODE)); + param.setCompressionQuality(user.getPropertyFloat(formatKey + + COMPRESS_QUALITY)); + } + } else { + if (canWriteUncompressed(format)) { + param.setCompressionMode(ImageWriteParam.MODE_DISABLED); + } + } + } + if (param.canWriteProgressive()) { + if (user.isProperty(formatKey + PROGRESSIVE)) { + param.setProgressiveMode(ImageWriteParam.MODE_DEFAULT); + } else { + param.setProgressiveMode(ImageWriteParam.MODE_DISABLED); + } + } + + // write the image + ImageOutputStream ios = ImageIO.createImageOutputStream(os); + writer.setOutput(ios); + writer.write(null, new IIOImage(image, null, null), param); + writer.dispose(); + try { + ios.close(); + } catch (Exception e) { + + } + } + + public static ImageWriter getPreferredImageWriter(String format) { + if (ImageConstants.RAW.toLowerCase().equals(format)) { + return (ImageWriter) new RawImageWriter(new RawImageWriterSpi()); + } + return (ImageWriter) getImageWriters( + ImageIO.getImageWritersByFormatName(format)).first(); + } + + public static ImageWriter getPreferredImageWriterForMIMEType(String mimeType) { + return (ImageWriter) getImageWriters( + ImageIO.getImageWritersByMIMEType(mimeType)).first(); + } + + public static SortedSet getImageWriters( + Iterator iterator) { + // look for a writer that supports the given format, + // BUT prefer our own "org.xmind.org.freehep." + // over "com.sun.imageio." over "com.sun.media." over others + SortedSet imageWriters = new TreeSet( + new Comparator() { + private int order(Object o) { + String className = o.getClass().getName(); + if (className.startsWith("org.xmind.org.freehep.")) { + return 0; + } else if (className.startsWith("com.sun.imageio.")) { + return 1; + } else if (className.startsWith("com.sun.media.")) { + return 2; + } + return 3; + } + + public int compare(Object arg0, Object arg1) { + int order0 = order(arg0); + int order1 = order(arg1); + return order0 < order1 ? -1 : order0 > order1 ? 1 : 0; + } + }); + while (iterator.hasNext()) { + imageWriters.add((ImageWriter) iterator.next()); + } + return imageWriters; + } + + public static BufferedImage readImage(String format, InputStream is) + throws IOException { + Iterator iterator = ImageIO + .getImageReadersByFormatName(format.toLowerCase()); + if (!iterator.hasNext()) { + throw new IOException(ImageGraphics2D.class + + ": No reader for format '" + format + "'."); + } + ImageReader reader = (ImageReader) iterator.next(); + + ImageInputStream iis = ImageIO.createImageInputStream(is); + reader.setInput(iis, true); + BufferedImage image = reader.read(0); + reader.dispose(); + iis.close(); + return image; + } + + public static boolean canWriteUncompressed(String format) { + // Method forgotten by Sun, BUG# 4856395. + // If param.canWriteCompressed() is true, then it may be that + // the format always needs to be compressed... GIF and JPG are among of + // them. + return !Arrays.asList(alwaysCompressedFormats).contains( + format.toLowerCase()); + } + + public static boolean canWriteTransparent(String format) { + return !Arrays.asList(nonTransparentFormats).contains( + format.toLowerCase()); + } + + /** + * @param bkg + * Background color for the image + * @return Properties used to create a RAW image + * @param code + * Color encoding, e.g. {@link ImageConstants#COLOR_MODEL_RGB} + */ + public static UserProperties getRAWProperties(Color bkg, String code) { + UserProperties result = new UserProperties(); + result.setProperty(RawImageWriteParam.BACKGROUND, bkg); + result.setProperty(RawImageWriteParam.CODE, code); + result.setProperty(RawImageWriteParam.PAD, 1); + return result; + } + + /** + * Converts a given image to byte[] + * + * @throws IOException + * thrown by + * {@link #writeImage(java.awt.image.RenderedImage, String, java.util.Properties, java.io.OutputStream)} + * @param image + * Image to convert + * @param format + * e.g. {@link ImageConstants#JPG}, {@link ImageConstants#PNG}, + * {@link ImageConstants#RAW} + * @param props + * Properties for writing, e.g. + * {@link org.xmind.org.freehep.graphicsio.raw.RawImageWriteParam#BACKGROUND} + * @param encoding + * {@link ImageConstants#ENCODING_ASCII85}, + * {@link ImageConstants#ENCODING_FLATE} or null + * @return bytes representing the image + */ + public static byte[] toByteArray(RenderedImage image, String format, + String encoding, Properties props) throws IOException { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + OutputStream os = bos; + + if (ImageConstants.ENCODING_ASCII85.equals(encoding) + || ImageConstants.ENCODING_FLATE_ASCII85.equals(encoding)) { + os = new ASCII85OutputStream(os); + } + + if (ImageConstants.ENCODING_FLATE.equals(encoding) + || ImageConstants.ENCODING_FLATE_ASCII85.equals(encoding)) { + os = new FlateOutputStream(os); + } + + // avoid NPE + if (props == null) { + props = new Properties(); + } + + // write image into the stream + ImageGraphics2D.writeImage(image, format.toLowerCase(), props, os); + os.close(); + + // return reulting bytes from stream + return bos.toByteArray(); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageParamConverter.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageParamConverter.java index 591ee2094..cce98ef36 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageParamConverter.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/ImageParamConverter.java @@ -1,23 +1,23 @@ -// Copyright 2003, FreeHEP. -package org.xmind.org.freehep.graphicsio; - - -import java.util.Properties; - -import javax.imageio.ImageWriteParam; - -/** - * This interface is to be implemented by sub classes of ImageWriteParam to make - * properties available to the ImageWriter as an ImageWriteParam object. - * - * @author Mark Donszelmann - * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/ImageParamConverter.java 4a3e7879b7eb 2006/08/11 17:39:56 duns $ - */ -public interface ImageParamConverter { - - /** - * Returns a subclass of ImageWriteParam with all the instance variable set - * according to the properties - */ - public ImageWriteParam getWriteParam(Properties properties); -} +// Copyright 2003, FreeHEP. +package org.xmind.org.freehep.graphicsio; + + +import java.util.Properties; + +import javax.imageio.ImageWriteParam; + +/** + * This interface is to be implemented by sub classes of ImageWriteParam to make + * properties available to the ImageWriter as an ImageWriteParam object. + * + * @author Mark Donszelmann + * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/ImageParamConverter.java 4a3e7879b7eb 2006/08/11 17:39:56 duns $ + */ +public interface ImageParamConverter { + + /** + * Returns a subclass of ImageWriteParam with all the instance variable set + * according to the properties + */ + public ImageWriteParam getWriteParam(Properties properties); +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/InfoConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/InfoConstants.java index be7bf5a80..5664ffd54 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/InfoConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/InfoConstants.java @@ -1,26 +1,26 @@ -// Copyright 2003, FreeHEP. -package org.xmind.org.freehep.graphicsio; - -/** - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class InfoConstants { - - private InfoConstants() { - } - - public static final String CREATOR = "Creator"; - - public static final String AUTHOR = "Author"; - - public static final String TITLE = "Title"; - - public static final String SUBJECT = "Subject"; - - public static final String KEYWORDS = "Keywords"; - - public static final String FOR = "For"; -} +// Copyright 2003, FreeHEP. +package org.xmind.org.freehep.graphicsio; + +/** + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class InfoConstants { + + private InfoConstants() { + } + + public static final String CREATOR = "Creator"; + + public static final String AUTHOR = "Author"; + + public static final String TITLE = "Title"; + + public static final String SUBJECT = "Subject"; + + public static final String KEYWORDS = "Keywords"; + + public static final String FOR = "For"; +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/MultiPageDocument.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/MultiPageDocument.java index 9dc18036d..aee44ecd1 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/MultiPageDocument.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/MultiPageDocument.java @@ -1,29 +1,29 @@ -package org.xmind.org.freehep.graphicsio; - -import java.awt.Dimension; -import java.awt.Font; -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.TagString; - -public interface MultiPageDocument { - - public void setMultiPage(boolean isMultiPage); - - public boolean isMultiPage(); - - /** Set the headline of all pages. */ - public void setHeader(Font font, TagString left, TagString center, - TagString right, int underlineThickness); - - /** Set the footline of all pages. */ - public void setFooter(Font font, TagString left, TagString center, - TagString right, int underlineThickness); - - /** Start the next page */ - public void openPage(Dimension size, String title) throws IOException; - - /** End the current page. */ - public void closePage() throws IOException; - +package org.xmind.org.freehep.graphicsio; + +import java.awt.Dimension; +import java.awt.Font; +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.TagString; + +public interface MultiPageDocument { + + public void setMultiPage(boolean isMultiPage); + + public boolean isMultiPage(); + + /** Set the headline of all pages. */ + public void setHeader(Font font, TagString left, TagString center, + TagString right, int underlineThickness); + + /** Set the footline of all pages. */ + public void setFooter(Font font, TagString left, TagString center, + TagString right, int underlineThickness); + + /** Start the next page */ + public void openPage(Dimension size, String title) throws IOException; + + /** End the current page. */ + public void closePage() throws IOException; + } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PageConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PageConstants.java index 1ca056c3b..7d1762e6c 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PageConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PageConstants.java @@ -1,33 +1,33 @@ -// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. -package org.xmind.org.freehep.graphicsio; - - -/** - * This class defines a set of constants which describe a page. Convenience - * objects are provided for various margins, orientations, rescaling, and - * standard page sizes. - * - * @author Charles Loomis - * @author Mark Donszelmann - * @author Jason Wong - */ -public class PageConstants { - - private PageConstants() { - } - - public static final String FIT_TO_PAGE = "FitToPage"; //$NON-NLS-1$ - - public static final String TRANSPARENT = "Transparent"; //$NON-NLS-1$ - - public static final String BACKGROUND = "Background"; //$NON-NLS-1$ - - public static final String BACKGROUND_COLOR = "BackgroundColor"; //$NON-NLS-1$ - - public static final String ORIENTATION = "Orientation"; //$NON-NLS-1$ - - public static final String PAGE_SIZE = "PageSize"; //$NON-NLS-1$ - - public static final String PAGE_MARGINS = "PageMargins"; //$NON-NLS-1$ - -} +// Copyright 2000, CERN, Geneva, Switzerland and University of Santa Cruz, California, U.S.A. +package org.xmind.org.freehep.graphicsio; + + +/** + * This class defines a set of constants which describe a page. Convenience + * objects are provided for various margins, orientations, rescaling, and + * standard page sizes. + * + * @author Charles Loomis + * @author Mark Donszelmann + * @author Jason Wong + */ +public class PageConstants { + + private PageConstants() { + } + + public static final String FIT_TO_PAGE = "FitToPage"; //$NON-NLS-1$ + + public static final String TRANSPARENT = "Transparent"; //$NON-NLS-1$ + + public static final String BACKGROUND = "Background"; //$NON-NLS-1$ + + public static final String BACKGROUND_COLOR = "BackgroundColor"; //$NON-NLS-1$ + + public static final String ORIENTATION = "Orientation"; //$NON-NLS-1$ + + public static final String PAGE_SIZE = "PageSize"; //$NON-NLS-1$ + + public static final String PAGE_MARGINS = "PageMargins"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PathConstructor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PathConstructor.java index d6451ba16..10d09ddfa 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PathConstructor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/PathConstructor.java @@ -1,73 +1,73 @@ -// Copyright 2001-2004 freehep -package org.xmind.org.freehep.graphicsio; - -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.io.IOException; - -/** - * Interface for objects that are capable of constructing paths. Path painting - * (stroking or filling) is not included. - * - * @author Simon Fischer - * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/PathConstructor.java 5641ca92a537 2005/11/26 00:15:35 duns $ - */ -public interface PathConstructor { - - /** - * Makes (x,y) the current point. - */ - public void move(double x, double y) throws IOException; - - /** - * Draws a line from the current point to (x,y) and make (x,y) the current - * point. - */ - public void line(double x, double y) throws IOException; - - /** - * Draws a quadratic bezier curve from the current point to (x2, y2) using - * the control point (x1, y1) and make (x2, y2) the current point. - */ - public void quad(double x1, double y1, double x2, double y2) - throws IOException; - - /** - * Draws a cubic bezier curve from the current point to (x3, y3) using the - * control points (x1, y1) and (x2, y2) and make (x3, y3) the current point. - */ - public void cubic(double x1, double y1, double x2, double y2, double x3, - double y3) throws IOException; - - /** - * Closes the path by drawing a straight line to the last point which was - * argument to move. - */ - public void closePath(double x0, double y0) throws IOException; - - /** - * Flushes any cached info to the output file. The path is complete at this - * point. - */ - public void flush() throws IOException; - - /** - * Adds the points of the shape using path construction - * operators. The path is neither stroked nor filled. - * - * @return true if even-odd winding rule should be used, false if non-zero - * winding rule should be used. - */ - public boolean addPath(Shape s) throws IOException; - - /** - * Adds the points of the shape using path construction - * operators, using the given transform. The path is neither stroked nor - * filled. - * - * @return true if even-odd winding rule should be used, false if non-zero - * winding rule should be used. - */ - public boolean addPath(Shape s, AffineTransform transform) - throws IOException; -} +// Copyright 2001-2004 freehep +package org.xmind.org.freehep.graphicsio; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.io.IOException; + +/** + * Interface for objects that are capable of constructing paths. Path painting + * (stroking or filling) is not included. + * + * @author Simon Fischer + * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/PathConstructor.java 5641ca92a537 2005/11/26 00:15:35 duns $ + */ +public interface PathConstructor { + + /** + * Makes (x,y) the current point. + */ + public void move(double x, double y) throws IOException; + + /** + * Draws a line from the current point to (x,y) and make (x,y) the current + * point. + */ + public void line(double x, double y) throws IOException; + + /** + * Draws a quadratic bezier curve from the current point to (x2, y2) using + * the control point (x1, y1) and make (x2, y2) the current point. + */ + public void quad(double x1, double y1, double x2, double y2) + throws IOException; + + /** + * Draws a cubic bezier curve from the current point to (x3, y3) using the + * control points (x1, y1) and (x2, y2) and make (x3, y3) the current point. + */ + public void cubic(double x1, double y1, double x2, double y2, double x3, + double y3) throws IOException; + + /** + * Closes the path by drawing a straight line to the last point which was + * argument to move. + */ + public void closePath(double x0, double y0) throws IOException; + + /** + * Flushes any cached info to the output file. The path is complete at this + * point. + */ + public void flush() throws IOException; + + /** + * Adds the points of the shape using path construction + * operators. The path is neither stroked nor filled. + * + * @return true if even-odd winding rule should be used, false if non-zero + * winding rule should be used. + */ + public boolean addPath(Shape s) throws IOException; + + /** + * Adds the points of the shape using path construction + * operators, using the given transform. The path is neither stroked nor + * filled. + * + * @return true if even-odd winding rule should be used, false if non-zero + * winding rule should be used. + */ + public boolean addPath(Shape s, AffineTransform transform) + throws IOException; +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/QuadToCubicPathConstructor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/QuadToCubicPathConstructor.java index a3c4668cf..e92de9fcf 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/QuadToCubicPathConstructor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/QuadToCubicPathConstructor.java @@ -1,53 +1,53 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.graphicsio; - -import java.io.IOException; - -/** - * Implements the Quadratic Bezier Curve PathConstructor functionality in terms - * of Cubic Bezier Curves - * - * @author Mark Donszelmann - * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/QuadToCubicPathConstructor.java 5641ca92a537 2005/11/26 00:15:35 duns $ - */ -public abstract class QuadToCubicPathConstructor extends - AbstractPathConstructor { - - protected QuadToCubicPathConstructor() { - super(); - } - - public void move(double x, double y) throws IOException { - currentX = x; - currentY = y; - } - - public void line(double x, double y) throws IOException { - currentX = x; - currentY = y; - } - - public void quad(double x1, double y1, double x2, double y2) - throws IOException { - double xctrl1 = x1 + (currentX - x1) / 3.; - double yctrl1 = y1 + (currentY - y1) / 3.; - double xctrl2 = x1 + (x2 - x1) / 3.; - double yctrl2 = y1 + (y2 - y1) / 3.; - - cubic(xctrl1, yctrl1, xctrl2, yctrl2, x2, y2); - - currentX = x2; - currentY = y2; - } - - public void cubic(double x1, double y1, double x2, double y2, double x3, - double y3) throws IOException { - currentX = x3; - currentY = y3; - } - - public void closePath(double x0, double y0) throws IOException { - currentX = 0; - currentY = 0; - } -} +// Copyright 2001 freehep +package org.xmind.org.freehep.graphicsio; + +import java.io.IOException; + +/** + * Implements the Quadratic Bezier Curve PathConstructor functionality in terms + * of Cubic Bezier Curves + * + * @author Mark Donszelmann + * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/QuadToCubicPathConstructor.java 5641ca92a537 2005/11/26 00:15:35 duns $ + */ +public abstract class QuadToCubicPathConstructor extends + AbstractPathConstructor { + + protected QuadToCubicPathConstructor() { + super(); + } + + public void move(double x, double y) throws IOException { + currentX = x; + currentY = y; + } + + public void line(double x, double y) throws IOException { + currentX = x; + currentY = y; + } + + public void quad(double x1, double y1, double x2, double y2) + throws IOException { + double xctrl1 = x1 + (currentX - x1) / 3.; + double yctrl1 = y1 + (currentY - y1) / 3.; + double xctrl2 = x1 + (x2 - x1) / 3.; + double yctrl2 = y1 + (y2 - y1) / 3.; + + cubic(xctrl1, yctrl1, xctrl2, yctrl2, x2, y2); + + currentX = x2; + currentY = y2; + } + + public void cubic(double x1, double y1, double x2, double y2, double x3, + double y3) throws IOException { + currentX = x3; + currentY = y3; + } + + public void closePath(double x0, double y0) throws IOException { + currentX = 0; + currentY = 0; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/VectorGraphicsIO.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/VectorGraphicsIO.java index 5f64d2e92..0c55be425 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/VectorGraphicsIO.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/VectorGraphicsIO.java @@ -1,75 +1,75 @@ -// Copyright 2000-2002 FreeHEP -package org.xmind.org.freehep.graphicsio; - -import java.awt.Dimension; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; - -import org.xmind.org.freehep.graphics2d.AbstractVectorGraphics; - -/** - * This class provides specifies added methods for VectorGraphicsIO. All added - * methods are declared abstract. - * - * @author Charles Loomis - * @author Mark Donszelmann - * @version $Id: VectorGraphicsIO.java 8584 2006-08-10 23:06:37Z duns $ - */ -public abstract class VectorGraphicsIO extends AbstractVectorGraphics { - - public VectorGraphicsIO() { - super(); - } - - public VectorGraphicsIO(VectorGraphicsIO graphics) { - super(graphics); - } - - public abstract Dimension getSize(); - - public abstract void printComment(String comment); - - /** - * copies the full file referenced by filenam onto the os (PrintWriter). The - * file location is relative to the current class - * - * @param object from which to refer to resource file - * @param fileName name of file to be copied - * @param os output to copy the file to - */ - public static void copyResourceTo(Object object, String fileName, - PrintStream os) { - copyResourceTo(object, fileName, new PrintWriter( - new OutputStreamWriter(os))); - } - - public static void copyResourceTo(Object object, String fileName, - PrintWriter os) { - InputStream is = null; - BufferedReader br = null; - try { - is = object.getClass().getResourceAsStream(fileName); - br = new BufferedReader(new InputStreamReader(is)); - String s; - while ((s = br.readLine()) != null) { - os.println(s); - } - os.flush(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (br != null) - br.close(); - if (is != null) - is.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} +// Copyright 2000-2002 FreeHEP +package org.xmind.org.freehep.graphicsio; + +import java.awt.Dimension; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.PrintWriter; + +import org.xmind.org.freehep.graphics2d.AbstractVectorGraphics; + +/** + * This class provides specifies added methods for VectorGraphicsIO. All added + * methods are declared abstract. + * + * @author Charles Loomis + * @author Mark Donszelmann + * @version $Id: VectorGraphicsIO.java 8584 2006-08-10 23:06:37Z duns $ + */ +public abstract class VectorGraphicsIO extends AbstractVectorGraphics { + + public VectorGraphicsIO() { + super(); + } + + public VectorGraphicsIO(VectorGraphicsIO graphics) { + super(graphics); + } + + public abstract Dimension getSize(); + + public abstract void printComment(String comment); + + /** + * copies the full file referenced by filenam onto the os (PrintWriter). The + * file location is relative to the current class + * + * @param object from which to refer to resource file + * @param fileName name of file to be copied + * @param os output to copy the file to + */ + public static void copyResourceTo(Object object, String fileName, + PrintStream os) { + copyResourceTo(object, fileName, new PrintWriter( + new OutputStreamWriter(os))); + } + + public static void copyResourceTo(Object object, String fileName, + PrintWriter os) { + InputStream is = null; + BufferedReader br = null; + try { + is = object.getClass().getResourceAsStream(fileName); + br = new BufferedReader(new InputStreamReader(is)); + String s; + while ((s = br.readLine()) != null) { + os.println(s); + } + os.flush(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (br != null) + br.close(); + if (is != null) + is.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/CharstringEncoder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/CharstringEncoder.java index f414b1af6..057eadaa2 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/CharstringEncoder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/CharstringEncoder.java @@ -1,177 +1,177 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.graphicsio.font; - -import java.awt.Shape; -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.org.freehep.graphicsio.QuadToCubicPathConstructor; - -/** - * Encoder to encode "CharStrings" used in PostScript and Type 1 Fonts. - * - * @author Simon Fischer - * @author Jason Wong - */ -public class CharstringEncoder extends QuadToCubicPathConstructor { - - private static final int LAST_POINT = 0; - - private static final int HORIZONTAL = 1; - - private static final int VERTICAL = 2; - - private static final int BOTH = 3; - - private OutputStream out; - - private int currentX, currentY; - - public CharstringEncoder(OutputStream out) { - this.out = out; - currentX = currentY = 0; - } - - private int writeNumber(double v) throws IOException { - int round = (int) Math.round(v); - writeNumber(round); - return round; - } - - private void writeNumber(int v) throws IOException { - if ((v >= -107) && (v <= 107)) { - out.write(v + 139); - } else if ((v >= 108) && (v <= 1131)) { - int highByte = (v - 108) / 256; - out.write(highByte + 247); - out.write(v - 108 - 256 * highByte); - } else if ((v >= -1131) && (v <= -108)) { - int highByte = (v + 108) / 256; - out.write(-highByte + 251); - out.write(-(v + 108 - 256 * highByte)); - } else { - out.write(255); - // copied from DataOutputStream correct? '>>>'? - out.write((v >>> 24) & 0xFF); - out.write((v >>> 16) & 0xFF); - out.write((v >>> 8) & 0xFF); - out.write((v >>> 0) & 0xFF); - } - } - - protected void writeCommand(int com) throws IOException { - if (com >= 31) - throw new IOException("Charstring command out of range: " + com); //$NON-NLS-1$ - out.write(com); - } - - protected void writeExtCommand(int com) throws IOException { - out.write(12); - out.write(com); - } - - // -------------------- PATH CONSTRUCTION -------------------- - - private void writePoint(double x, double y) throws IOException { - currentX += writeNumber(x - currentX); - currentY += writeNumber(y - currentY); - } - - private void writeX(double x) throws IOException { - currentX += writeNumber(x - currentX); - } - - private void writeY(double y) throws IOException { - currentY += writeNumber(y - currentY); - } - - // -------------------- start/end -------------------- - - public void startChar(double sidebearing, double width) throws IOException { - currentX = writeNumber(sidebearing); - writeNumber(width); - writeCommand(13); - } - - public void endchar() throws IOException { - writeCommand(14); - } - - // -------------------- path construction -------------------- - - private int to(double x, double y) throws IOException { - // writePoint(x, y); - // return BOTH; - - int rx = (int) Math.round(x); - int ry = (int) Math.round(y); - - if (rx == currentX) { - if (ry == currentY) { - return LAST_POINT; - } else { - writeY(y); - return VERTICAL; - } - } else if (ry == currentY) { - writeX(x); - return HORIZONTAL; - } else { - writePoint(x, y); - return BOTH; - } - } - - public void move(double x, double y) throws IOException { - switch (to(x, y)) { - case BOTH: - writeCommand(21); - break; - case HORIZONTAL: - writeCommand(22); - break; - case VERTICAL: - writeCommand(4); - break; - case LAST_POINT: - break; - } - super.move(x, y); - } - - public void line(double x, double y) throws IOException { - switch (to(x, y)) { - case BOTH: - writeCommand(5); - break; - case HORIZONTAL: - writeCommand(6); - break; - case VERTICAL: - writeCommand(7); - break; - case LAST_POINT: - break; - } - super.line(x, y); - } - - public void cubic(double x1, double y1, double x2, double y2, double x3, - double y3) throws IOException { - writePoint(x1, y1); - writePoint(x2, y2); - writePoint(x3, y3); - writeCommand(8); - super.cubic(x1, y1, x2, y2, x3, y3); - } - - public void closePath(double x0, double y0) throws IOException { - writeCommand(9); - super.closePath(x0, y0); - } - - public void drawPath(Shape s) throws IOException { - addPath(s); - } - -} +// Copyright 2001 freehep +package org.xmind.org.freehep.graphicsio.font; + +import java.awt.Shape; +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.org.freehep.graphicsio.QuadToCubicPathConstructor; + +/** + * Encoder to encode "CharStrings" used in PostScript and Type 1 Fonts. + * + * @author Simon Fischer + * @author Jason Wong + */ +public class CharstringEncoder extends QuadToCubicPathConstructor { + + private static final int LAST_POINT = 0; + + private static final int HORIZONTAL = 1; + + private static final int VERTICAL = 2; + + private static final int BOTH = 3; + + private OutputStream out; + + private int currentX, currentY; + + public CharstringEncoder(OutputStream out) { + this.out = out; + currentX = currentY = 0; + } + + private int writeNumber(double v) throws IOException { + int round = (int) Math.round(v); + writeNumber(round); + return round; + } + + private void writeNumber(int v) throws IOException { + if ((v >= -107) && (v <= 107)) { + out.write(v + 139); + } else if ((v >= 108) && (v <= 1131)) { + int highByte = (v - 108) / 256; + out.write(highByte + 247); + out.write(v - 108 - 256 * highByte); + } else if ((v >= -1131) && (v <= -108)) { + int highByte = (v + 108) / 256; + out.write(-highByte + 251); + out.write(-(v + 108 - 256 * highByte)); + } else { + out.write(255); + // copied from DataOutputStream correct? '>>>'? + out.write((v >>> 24) & 0xFF); + out.write((v >>> 16) & 0xFF); + out.write((v >>> 8) & 0xFF); + out.write((v >>> 0) & 0xFF); + } + } + + protected void writeCommand(int com) throws IOException { + if (com >= 31) + throw new IOException("Charstring command out of range: " + com); //$NON-NLS-1$ + out.write(com); + } + + protected void writeExtCommand(int com) throws IOException { + out.write(12); + out.write(com); + } + + // -------------------- PATH CONSTRUCTION -------------------- + + private void writePoint(double x, double y) throws IOException { + currentX += writeNumber(x - currentX); + currentY += writeNumber(y - currentY); + } + + private void writeX(double x) throws IOException { + currentX += writeNumber(x - currentX); + } + + private void writeY(double y) throws IOException { + currentY += writeNumber(y - currentY); + } + + // -------------------- start/end -------------------- + + public void startChar(double sidebearing, double width) throws IOException { + currentX = writeNumber(sidebearing); + writeNumber(width); + writeCommand(13); + } + + public void endchar() throws IOException { + writeCommand(14); + } + + // -------------------- path construction -------------------- + + private int to(double x, double y) throws IOException { + // writePoint(x, y); + // return BOTH; + + int rx = (int) Math.round(x); + int ry = (int) Math.round(y); + + if (rx == currentX) { + if (ry == currentY) { + return LAST_POINT; + } else { + writeY(y); + return VERTICAL; + } + } else if (ry == currentY) { + writeX(x); + return HORIZONTAL; + } else { + writePoint(x, y); + return BOTH; + } + } + + public void move(double x, double y) throws IOException { + switch (to(x, y)) { + case BOTH: + writeCommand(21); + break; + case HORIZONTAL: + writeCommand(22); + break; + case VERTICAL: + writeCommand(4); + break; + case LAST_POINT: + break; + } + super.move(x, y); + } + + public void line(double x, double y) throws IOException { + switch (to(x, y)) { + case BOTH: + writeCommand(5); + break; + case HORIZONTAL: + writeCommand(6); + break; + case VERTICAL: + writeCommand(7); + break; + case LAST_POINT: + break; + } + super.line(x, y); + } + + public void cubic(double x1, double y1, double x2, double y2, double x3, + double y3) throws IOException { + writePoint(x1, y1); + writePoint(x2, y2); + writePoint(x3, y3); + writeCommand(8); + super.cubic(x1, y1, x2, y2, x3, y3); + } + + public void closePath(double x0, double y0) throws IOException { + writeCommand(9); + super.closePath(x0, y0); + } + + public void drawPath(Shape s) throws IOException { + addPath(s); + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedder.java index 80c23b621..7f9cde9da 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedder.java @@ -1,169 +1,169 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.font; - -import java.awt.Font; -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphMetrics; -import java.awt.font.GlyphVector; -import java.awt.geom.GeneralPath; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.font.CharTable; - -/** - * A FontIncluder that also embeds all glyphs. Subclasses must implement the - * writeGlyph method which is called for all defined (up to 256) - * characters and the notdefined character. These method calls are bracketed by - * openGlyphs() and closeGlyph(). All invocations of methods - * that are abstract in this class succeed the method calls of the superclass - * FontIncluder (especially closeIncludeFont()!) All of these - * calls are again succeeded by closeEmbedFont.
    - * The abstract methods are called in the following order: - *
      - *
    • openIncludeFont - *
    • writeEncoding - *
    • closeIncludeFont - *
    • writeWidths - *
    • openGlyphs - *
    • loop over all glyphs: openGlyphs - *
    • closeGlyphs - *
    • closeEmbedFont - *
    - * - * @author Simon Fischer - * @author Jason Wong - */ -public abstract class FontEmbedder extends FontIncluder { - - public static final String NOTDEF = ".notdef"; //$NON-NLS-1$ - - /** - * Writes a single glyph to the file. A null value for glyphMetrics - * indicates the undefined character. In this case the value of - * unicodeName equals the value of NOTDEF (= - * .notdef). - * - * @param unicodeName - * the character's name according to the unicode standard - * @param glyph - * the shape that represents this glyph - * @param glyphMetrics - * the metrics of this glyph - */ - protected abstract void writeGlyph(String unicodeName, Shape glyph, - GlyphMetrics glyphMetrics) throws IOException; - - /** Writes the character widths to the file. */ - protected abstract void writeWidths(double[] widths) throws IOException; - - /** - * Called before the glyph loop starts. Does nothing by default but can be - * implemented. - */ - protected void openGlyphs() throws IOException { - } - - /** - * Called after the glyph loop ends. Does nothing by default but can be - * implemented. - */ - protected void closeGlyphs() throws IOException { - } - - protected abstract void closeEmbedFont() throws IOException; - - private double[] widths; - - private GlyphVector glyphs; - - private Font font; // FONTHACK - - public FontEmbedder(FontRenderContext context) { - super(context); - } - - protected double[] getAdvanceWidths() { - if (widths == null) { - // figure out the widths of the characters if not yet done - widths = new double[256]; - for (int i = 0; i < widths.length; i++) { - widths[i] = glyphs.getGlyphMetrics(i).getAdvance(); - // in case of undefined character set to width of undefined - // symbol - if (getCharName(i) == null) { - widths[i] = getUndefinedWidth(); - } - } - } - return widths; - } - - protected double getAdvanceWidth(int character) { - return getAdvanceWidths()[character]; - } - - protected Shape getGlyph(int i) { - // This one-line implementation produces different results under JDK 1.3 - // and 1.4 - // return glyphs.getGlyphOutline(i); - - // The substitute code attempts to work around this by using defensive - // programming - // See code marked FONTHACK elsewhere in this file - // Create a GlyphVector for this single character. - FontRenderContext orig = getContext(); - FontRenderContext frc = new FontRenderContext(null, - orig.isAntiAliased(), orig.usesFractionalMetrics()); - Shape shape = font.createGlyphVector(frc, new char[] { getUnicode(i) }) - .getGlyphOutline(0); - return orig.getTransform().createTransformedShape(shape); - } - - protected GlyphMetrics getGlyphMetrics(int i) { - return glyphs.getGlyphMetrics(i); - } - - public void includeFont(Font font, CharTable charTable, String name) - throws IOException { - - glyphs = null; - widths = null; - // FONTHACK: Needed by hacked version of getGlyph() - this.font = font; - - super.includeFont(font, charTable, name); - - this.glyphs = font.createGlyphVector(getContext(), getUnicode()); - - writeWidths(getAdvanceWidths()); - - try { - - openGlyphs(); - - // write the glyphs - for (int i = 0; i < 256; i++) { - if (getCharName(i) != null) { - writeGlyph(getCharName(i), getGlyph(i), getGlyphMetrics(i)); - } - } - writeGlyph(NOTDEF, createUndefined(), null); - - closeGlyphs(); - closeEmbedFont(); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - private Shape createUndefined() { - GeneralPath ud = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 10); - ud.append(new Rectangle2D.Double(0, 0, FONT_SIZE, FONT_SIZE), false); - ud.append(new Rectangle2D.Double(FONT_SIZE / 20, FONT_SIZE / 20, - 18 * FONT_SIZE / 20, 18 * FONT_SIZE / 20), false); - return ud; - } -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.font; + +import java.awt.Font; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.font.CharTable; + +/** + * A FontIncluder that also embeds all glyphs. Subclasses must implement the + * writeGlyph method which is called for all defined (up to 256) + * characters and the notdefined character. These method calls are bracketed by + * openGlyphs() and closeGlyph(). All invocations of methods + * that are abstract in this class succeed the method calls of the superclass + * FontIncluder (especially closeIncludeFont()!) All of these + * calls are again succeeded by closeEmbedFont.
    + * The abstract methods are called in the following order: + *
      + *
    • openIncludeFont + *
    • writeEncoding + *
    • closeIncludeFont + *
    • writeWidths + *
    • openGlyphs + *
    • loop over all glyphs: openGlyphs + *
    • closeGlyphs + *
    • closeEmbedFont + *
    + * + * @author Simon Fischer + * @author Jason Wong + */ +public abstract class FontEmbedder extends FontIncluder { + + public static final String NOTDEF = ".notdef"; //$NON-NLS-1$ + + /** + * Writes a single glyph to the file. A null value for glyphMetrics + * indicates the undefined character. In this case the value of + * unicodeName equals the value of NOTDEF (= + * .notdef). + * + * @param unicodeName + * the character's name according to the unicode standard + * @param glyph + * the shape that represents this glyph + * @param glyphMetrics + * the metrics of this glyph + */ + protected abstract void writeGlyph(String unicodeName, Shape glyph, + GlyphMetrics glyphMetrics) throws IOException; + + /** Writes the character widths to the file. */ + protected abstract void writeWidths(double[] widths) throws IOException; + + /** + * Called before the glyph loop starts. Does nothing by default but can be + * implemented. + */ + protected void openGlyphs() throws IOException { + } + + /** + * Called after the glyph loop ends. Does nothing by default but can be + * implemented. + */ + protected void closeGlyphs() throws IOException { + } + + protected abstract void closeEmbedFont() throws IOException; + + private double[] widths; + + private GlyphVector glyphs; + + private Font font; // FONTHACK + + public FontEmbedder(FontRenderContext context) { + super(context); + } + + protected double[] getAdvanceWidths() { + if (widths == null) { + // figure out the widths of the characters if not yet done + widths = new double[256]; + for (int i = 0; i < widths.length; i++) { + widths[i] = glyphs.getGlyphMetrics(i).getAdvance(); + // in case of undefined character set to width of undefined + // symbol + if (getCharName(i) == null) { + widths[i] = getUndefinedWidth(); + } + } + } + return widths; + } + + protected double getAdvanceWidth(int character) { + return getAdvanceWidths()[character]; + } + + protected Shape getGlyph(int i) { + // This one-line implementation produces different results under JDK 1.3 + // and 1.4 + // return glyphs.getGlyphOutline(i); + + // The substitute code attempts to work around this by using defensive + // programming + // See code marked FONTHACK elsewhere in this file + // Create a GlyphVector for this single character. + FontRenderContext orig = getContext(); + FontRenderContext frc = new FontRenderContext(null, + orig.isAntiAliased(), orig.usesFractionalMetrics()); + Shape shape = font.createGlyphVector(frc, new char[] { getUnicode(i) }) + .getGlyphOutline(0); + return orig.getTransform().createTransformedShape(shape); + } + + protected GlyphMetrics getGlyphMetrics(int i) { + return glyphs.getGlyphMetrics(i); + } + + public void includeFont(Font font, CharTable charTable, String name) + throws IOException { + + glyphs = null; + widths = null; + // FONTHACK: Needed by hacked version of getGlyph() + this.font = font; + + super.includeFont(font, charTable, name); + + this.glyphs = font.createGlyphVector(getContext(), getUnicode()); + + writeWidths(getAdvanceWidths()); + + try { + + openGlyphs(); + + // write the glyphs + for (int i = 0; i < 256; i++) { + if (getCharName(i) != null) { + writeGlyph(getCharName(i), getGlyph(i), getGlyphMetrics(i)); + } + } + writeGlyph(NOTDEF, createUndefined(), null); + + closeGlyphs(); + closeEmbedFont(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Shape createUndefined() { + GeneralPath ud = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 10); + ud.append(new Rectangle2D.Double(0, 0, FONT_SIZE, FONT_SIZE), false); + ud.append(new Rectangle2D.Double(FONT_SIZE / 20, FONT_SIZE / 20, + 18 * FONT_SIZE / 20, 18 * FONT_SIZE / 20), false); + return ud; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedderType1.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedderType1.java index 15df827a9..8ece3a098 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedderType1.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontEmbedderType1.java @@ -1,229 +1,229 @@ -// Copyright 2001-2009 freehep -package org.xmind.org.freehep.graphicsio.font; - -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphMetrics; -import java.awt.geom.Rectangle2D; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.util.io.ASCIIHexOutputStream; -import org.xmind.org.freehep.util.io.CountedByteOutputStream; -import org.xmind.org.freehep.util.io.EEXECEncryption; - -/** - * Font embedder for type 1 fonts. The output can be directly fed into a ps file - * or as a FontFile to a pdf file.

    Todo

    - *
      - *
    • use subroutines for accents - *
    • add more hints - *
    - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class FontEmbedderType1 extends FontEmbedder { - - /** Defines whether or not eexec encryption is used. */ - private static final boolean ENCRYPT = true; - - /** - * Defines whether or not encrypted part should be hex encoded (otherwise it - * is binary). - */ - private static final boolean HEX_ENC = true; - - /** - * Defines whether or not encrypted charstrings should be hex encoded - * Ghostview crashes when set to true. The freehep ps interpreter handles it - * correctly. - */ - private static boolean HEX_ENC_CHARSTRINGS = false; - - private PrintStream fontFile, encrypted; - - private CountedByteOutputStream byteCounter; - - private int asciiEnd, encEnd; // remember the lengths of the three - // portions - - private boolean addZeros; - - public FontEmbedderType1(FontRenderContext context, OutputStream out, - boolean addZeros) { - super(context); - this.byteCounter = new CountedByteOutputStream(out); - this.fontFile = new PrintStream(byteCounter); - this.addZeros = addZeros; - asciiEnd = encEnd = -1; - } - - protected void writeWidths(double[] w) throws IOException { - } - - protected void writeEncoding(CharTable t) throws IOException { - fontFile.println("/Encoding 256 array"); - fontFile.println("0 1 255 {1 index exch /.notdef put} for"); // set - // undefined - // to - // .notdef - // ?? - for (int i = 0; i < 256; i++) { - String charName = t.toName(i); - if (charName != null) - fontFile.println("dup " + i + " /" + charName + " put"); - } - fontFile.println("readonly def"); - } - - protected void openIncludeFont() throws IOException { - - // begin clear text ascii portion - fontFile.println("%!FontType1-1.0: " + getFont().getName()); // unknown - // version - // number - // fontFile.println("%%CreationDate: " + - // DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL). - // format(new Date())); - fontFile.println("% Generated by: " + getClass().getName()); - fontFile.println("11 dict begin"); - - fontFile.println("/FontInfo 8 dict dup begin"); - fontFile.println("/FullName (" + getFont().getPSName() - + ") readonly def"); - fontFile.println("/FamilyName (" + getFont().getFamily() - + ") readonly def"); - fontFile.println("end readonly def"); - - fontFile.println("/FontName /" + getFontName() + " def"); - fontFile.println("/PaintType 0 def"); - fontFile.println("/FontType 1 def"); - fontFile.println("/FontMatrix [" + 1 / FONT_SIZE + " 0.0 0.0 " + 1 - / FONT_SIZE + " 0.0 0.0] readonly def"); - } - - protected void closeIncludeFont() { - - Rectangle2D boundingBox = getFontBBox(); - int llx = (int) Math.round(boundingBox.getX()); - int lly = (int) Math.round(boundingBox.getY()); - int urx = (int) Math.round(boundingBox.getX() + boundingBox.getWidth()); - int ury = (int) Math - .round(boundingBox.getY() + boundingBox.getHeight()); - fontFile.println("/FontBBox {" + llx + " " + lly + " " + urx + " " - + ury + "} readonly def"); - - fontFile.println("currentdict end"); - - // begin encrypted portion - if (ENCRYPT) { - fontFile.print("currentfile eexec "); - asciiEnd = byteCounter.getCount(); - } - fontFile.flush(); - } - - protected void openGlyphs() throws IOException { - // begin encryption - if (ENCRYPT) { - if (HEX_ENC) { - encrypted = new PrintStream(new EEXECEncryption( - new ASCIIHexOutputStream(fontFile), - EEXECEncryption.EEXEC_R)); - } else { - encrypted = new PrintStream(new EEXECEncryption(fontFile, - EEXECEncryption.EEXEC_R)); - } - } else { - encrypted = fontFile; - } - - // begin the Private dictionary - encrypted.println("dup /Private 8 dict dup begin"); - encrypted - .println("/RD {string currentfile exch readstring pop} executeonly def"); - encrypted.println("/ND {noaccess def} executeonly def"); - encrypted.println("/NP {noaccess put} executeonly def"); - encrypted.println("/BlueValues [] def"); // ??? - encrypted.println("/MinFeature {16 16} def"); - encrypted.println("/password 5839 def"); - encrypted.print("2 index "); - encrypted.println("/CharStrings " + (getNODefinedChars() + 1) - + " dict dup begin"); - } - - protected void closeGlyphs() throws IOException { - encrypted.println("end"); // end Private - encrypted.println("end"); // end CharStrings - } - - protected void closeEmbedFont() throws IOException { - encrypted.println("readonly put"); - encrypted.println("noaccess put"); - encrypted.println("dup /FontName get exch definefont pop"); - encrypted.print("mark"); - if (ENCRYPT) { - encrypted.print(" currentfile closefile "); - } - encrypted.flush(); - encEnd = byteCounter.getCount(); - if (!ENCRYPT) - asciiEnd = encEnd; - - if (addZeros) { - fontFile.println(); - for (int i = 0; i < 16; i++) - fontFile.println("00000000000000000000000000000000"); - fontFile.println("cleartomark"); - } - } - - protected void writeGlyph(String characterName, Shape glyph, - GlyphMetrics glyphMetrics) throws IOException { - - // FIXME: find out why Acrobat Reader displays some characters displaced - // when - // using the correct sidebearing. A value of 0 looks good - double sidebearing = glyphMetrics != null ? glyphMetrics.getLSB() : 0; - // double sidebearing = 0; - - // write the binary charstring to a buffer - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - CharstringEncoder charString = (HEX_ENC_CHARSTRINGS ? new CharstringEncoder( - new EEXECEncryption(new ASCIIHexOutputStream(bytes), - EEXECEncryption.CHARSTRING_R)) : new CharstringEncoder( - new EEXECEncryption(bytes, EEXECEncryption.CHARSTRING_R))); - - charString.startChar(sidebearing, - (glyphMetrics != null ? glyphMetrics.getAdvance() - : getUndefinedWidth())); // bounds.getWidth()); - charString.drawPath(glyph); - charString.endchar(); - - // write the buffer to the encrypted fontFile - byte[] binaryString = bytes.toByteArray(); - encrypted.print("/" + characterName + " " + binaryString.length - + " RD "); - for (int i = 0; i < binaryString.length; i++) { - encrypted.write(binaryString[i] & 0x00ff); - } - encrypted.println("ND"); - encrypted.flush(); - } - - /** Returns the length of the ascii portion of the output. */ - public int getAsciiLength() { - return asciiEnd; - } - - /** Returns the length of the encrypted portion of the output. */ - public int getEncryptedLength() { - return encEnd - asciiEnd; - } - -} +// Copyright 2001-2009 freehep +package org.xmind.org.freehep.graphicsio.font; + +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.geom.Rectangle2D; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.util.io.ASCIIHexOutputStream; +import org.xmind.org.freehep.util.io.CountedByteOutputStream; +import org.xmind.org.freehep.util.io.EEXECEncryption; + +/** + * Font embedder for type 1 fonts. The output can be directly fed into a ps file + * or as a FontFile to a pdf file.

    Todo

    + *
      + *
    • use subroutines for accents + *
    • add more hints + *
    + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class FontEmbedderType1 extends FontEmbedder { + + /** Defines whether or not eexec encryption is used. */ + private static final boolean ENCRYPT = true; + + /** + * Defines whether or not encrypted part should be hex encoded (otherwise it + * is binary). + */ + private static final boolean HEX_ENC = true; + + /** + * Defines whether or not encrypted charstrings should be hex encoded + * Ghostview crashes when set to true. The freehep ps interpreter handles it + * correctly. + */ + private static boolean HEX_ENC_CHARSTRINGS = false; + + private PrintStream fontFile, encrypted; + + private CountedByteOutputStream byteCounter; + + private int asciiEnd, encEnd; // remember the lengths of the three + // portions + + private boolean addZeros; + + public FontEmbedderType1(FontRenderContext context, OutputStream out, + boolean addZeros) { + super(context); + this.byteCounter = new CountedByteOutputStream(out); + this.fontFile = new PrintStream(byteCounter); + this.addZeros = addZeros; + asciiEnd = encEnd = -1; + } + + protected void writeWidths(double[] w) throws IOException { + } + + protected void writeEncoding(CharTable t) throws IOException { + fontFile.println("/Encoding 256 array"); + fontFile.println("0 1 255 {1 index exch /.notdef put} for"); // set + // undefined + // to + // .notdef + // ?? + for (int i = 0; i < 256; i++) { + String charName = t.toName(i); + if (charName != null) + fontFile.println("dup " + i + " /" + charName + " put"); + } + fontFile.println("readonly def"); + } + + protected void openIncludeFont() throws IOException { + + // begin clear text ascii portion + fontFile.println("%!FontType1-1.0: " + getFont().getName()); // unknown + // version + // number + // fontFile.println("%%CreationDate: " + + // DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL). + // format(new Date())); + fontFile.println("% Generated by: " + getClass().getName()); + fontFile.println("11 dict begin"); + + fontFile.println("/FontInfo 8 dict dup begin"); + fontFile.println("/FullName (" + getFont().getPSName() + + ") readonly def"); + fontFile.println("/FamilyName (" + getFont().getFamily() + + ") readonly def"); + fontFile.println("end readonly def"); + + fontFile.println("/FontName /" + getFontName() + " def"); + fontFile.println("/PaintType 0 def"); + fontFile.println("/FontType 1 def"); + fontFile.println("/FontMatrix [" + 1 / FONT_SIZE + " 0.0 0.0 " + 1 + / FONT_SIZE + " 0.0 0.0] readonly def"); + } + + protected void closeIncludeFont() { + + Rectangle2D boundingBox = getFontBBox(); + int llx = (int) Math.round(boundingBox.getX()); + int lly = (int) Math.round(boundingBox.getY()); + int urx = (int) Math.round(boundingBox.getX() + boundingBox.getWidth()); + int ury = (int) Math + .round(boundingBox.getY() + boundingBox.getHeight()); + fontFile.println("/FontBBox {" + llx + " " + lly + " " + urx + " " + + ury + "} readonly def"); + + fontFile.println("currentdict end"); + + // begin encrypted portion + if (ENCRYPT) { + fontFile.print("currentfile eexec "); + asciiEnd = byteCounter.getCount(); + } + fontFile.flush(); + } + + protected void openGlyphs() throws IOException { + // begin encryption + if (ENCRYPT) { + if (HEX_ENC) { + encrypted = new PrintStream(new EEXECEncryption( + new ASCIIHexOutputStream(fontFile), + EEXECEncryption.EEXEC_R)); + } else { + encrypted = new PrintStream(new EEXECEncryption(fontFile, + EEXECEncryption.EEXEC_R)); + } + } else { + encrypted = fontFile; + } + + // begin the Private dictionary + encrypted.println("dup /Private 8 dict dup begin"); + encrypted + .println("/RD {string currentfile exch readstring pop} executeonly def"); + encrypted.println("/ND {noaccess def} executeonly def"); + encrypted.println("/NP {noaccess put} executeonly def"); + encrypted.println("/BlueValues [] def"); // ??? + encrypted.println("/MinFeature {16 16} def"); + encrypted.println("/password 5839 def"); + encrypted.print("2 index "); + encrypted.println("/CharStrings " + (getNODefinedChars() + 1) + + " dict dup begin"); + } + + protected void closeGlyphs() throws IOException { + encrypted.println("end"); // end Private + encrypted.println("end"); // end CharStrings + } + + protected void closeEmbedFont() throws IOException { + encrypted.println("readonly put"); + encrypted.println("noaccess put"); + encrypted.println("dup /FontName get exch definefont pop"); + encrypted.print("mark"); + if (ENCRYPT) { + encrypted.print(" currentfile closefile "); + } + encrypted.flush(); + encEnd = byteCounter.getCount(); + if (!ENCRYPT) + asciiEnd = encEnd; + + if (addZeros) { + fontFile.println(); + for (int i = 0; i < 16; i++) + fontFile.println("00000000000000000000000000000000"); + fontFile.println("cleartomark"); + } + } + + protected void writeGlyph(String characterName, Shape glyph, + GlyphMetrics glyphMetrics) throws IOException { + + // FIXME: find out why Acrobat Reader displays some characters displaced + // when + // using the correct sidebearing. A value of 0 looks good + double sidebearing = glyphMetrics != null ? glyphMetrics.getLSB() : 0; + // double sidebearing = 0; + + // write the binary charstring to a buffer + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + CharstringEncoder charString = (HEX_ENC_CHARSTRINGS ? new CharstringEncoder( + new EEXECEncryption(new ASCIIHexOutputStream(bytes), + EEXECEncryption.CHARSTRING_R)) : new CharstringEncoder( + new EEXECEncryption(bytes, EEXECEncryption.CHARSTRING_R))); + + charString.startChar(sidebearing, + (glyphMetrics != null ? glyphMetrics.getAdvance() + : getUndefinedWidth())); // bounds.getWidth()); + charString.drawPath(glyph); + charString.endchar(); + + // write the buffer to the encrypted fontFile + byte[] binaryString = bytes.toByteArray(); + encrypted.print("/" + characterName + " " + binaryString.length + + " RD "); + for (int i = 0; i < binaryString.length; i++) { + encrypted.write(binaryString[i] & 0x00ff); + } + encrypted.println("ND"); + encrypted.flush(); + } + + /** Returns the length of the ascii portion of the output. */ + public int getAsciiLength() { + return asciiEnd; + } + + /** Returns the length of the encrypted portion of the output. */ + public int getEncryptedLength() { + return encEnd - asciiEnd; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontIncluder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontIncluder.java index d3e65b16c..c8017de46 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontIncluder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontIncluder.java @@ -1,154 +1,154 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.font; - -import java.awt.Font; -import java.awt.font.FontRenderContext; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.font.CharTable; - -/** - * Instances of this class write the information into documents (ps or pdf) that - * is necessary in order to include or embed fonts. In order to guarantee a - * time-invariant interface the main methods to implement by subclasses - * includeFont takes no arguments. All necessary data should be - * available by getter methods which can easily be added.
    - * The abstract methods are called in the following order: - *
      - *
    • openIncludeFont - *
    • writeEncoding - *
    • closeIncludeFont - *
    - * - * @author Simon Fischer - * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/font/FontIncluder.java 5641ca92a537 2005/11/26 00:15:35 duns $ - */ -public abstract class FontIncluder { - - public static final double FONT_SIZE = 1000; - - // -------------------- abstract methods -------------------- - - /** - * Writes the given information about the font into the file. When this - * method is called all getXXX() are guaranteed to return - * reasonable values. - */ - protected abstract void openIncludeFont() throws IOException; - - /** Writes the encoding table to the file. */ - protected abstract void writeEncoding(CharTable charTable) - throws IOException; - - /** Does nothing, but can be implemented by subclasses if necessary. */ - protected void closeIncludeFont() throws IOException { - } - - // ----------------------------------------------------------- - - private FontRenderContext context; - - private Rectangle2D fontBBox; - - private Font font; - - private String fontName; - - private CharTable charTable; - - private char[] unicode; - - private String[] charName; - - private int noDefinedChars; - - public FontIncluder(FontRenderContext context) { - this.context = context; - this.noDefinedChars = -1; - } - - // ----------------------------------------------------------- - - protected FontRenderContext getContext() { - return context; - } - - protected String getFontName() { - return fontName; - } - - protected Font getFont() { - return font; - } - - protected CharTable getEncodingTable() { - return charTable; - } - - protected Rectangle2D getFontBBox() { - return fontBBox; - } - - protected String getCharName(int i) { - return charName[i]; - } - - protected char getUnicode(int i) { - return unicode[i]; - } - - protected char[] getUnicode() { - return unicode; - } - - protected int getNODefinedChars() { - return noDefinedChars; - } - - // ----------------------------------------------------------- - - /** - * Embed this font to the file. - * - * @param font The font to include - * @param name The name under which this font is addressed within the - * document (can be retrieved by getFontName()) - */ - public void includeFont(Font font, CharTable charTable, String name) - throws IOException { - - unicode = null; - charName = null; - - this.font = font; - this.charTable = charTable; - this.fontName = name; - - // figure out the maximum bounding box for all characters - this.fontBBox = font.getMaxCharBounds(context); - - // figure out the unicodes and character names and - // create a glyph vector containing the 256 glyphs of the font - this.noDefinedChars = 0; - this.unicode = new char[256]; - this.charName = new String[256]; - for (int i = 0; i < unicode.length; i++) { - charName[i] = charTable.toName(i); - if (charName[i] != null) { - unicode[i] = charTable.toUnicode(charName[i]); - noDefinedChars++; - } else { - unicode[i] = 0; - } - } - - openIncludeFont(); - writeEncoding(charTable); - closeIncludeFont(); - } - - protected double getUndefinedWidth() { - return FONT_SIZE; - } -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.font; + +import java.awt.Font; +import java.awt.font.FontRenderContext; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.font.CharTable; + +/** + * Instances of this class write the information into documents (ps or pdf) that + * is necessary in order to include or embed fonts. In order to guarantee a + * time-invariant interface the main methods to implement by subclasses + * includeFont takes no arguments. All necessary data should be + * available by getter methods which can easily be added.
    + * The abstract methods are called in the following order: + *
      + *
    • openIncludeFont + *
    • writeEncoding + *
    • closeIncludeFont + *
    + * + * @author Simon Fischer + * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/font/FontIncluder.java 5641ca92a537 2005/11/26 00:15:35 duns $ + */ +public abstract class FontIncluder { + + public static final double FONT_SIZE = 1000; + + // -------------------- abstract methods -------------------- + + /** + * Writes the given information about the font into the file. When this + * method is called all getXXX() are guaranteed to return + * reasonable values. + */ + protected abstract void openIncludeFont() throws IOException; + + /** Writes the encoding table to the file. */ + protected abstract void writeEncoding(CharTable charTable) + throws IOException; + + /** Does nothing, but can be implemented by subclasses if necessary. */ + protected void closeIncludeFont() throws IOException { + } + + // ----------------------------------------------------------- + + private FontRenderContext context; + + private Rectangle2D fontBBox; + + private Font font; + + private String fontName; + + private CharTable charTable; + + private char[] unicode; + + private String[] charName; + + private int noDefinedChars; + + public FontIncluder(FontRenderContext context) { + this.context = context; + this.noDefinedChars = -1; + } + + // ----------------------------------------------------------- + + protected FontRenderContext getContext() { + return context; + } + + protected String getFontName() { + return fontName; + } + + protected Font getFont() { + return font; + } + + protected CharTable getEncodingTable() { + return charTable; + } + + protected Rectangle2D getFontBBox() { + return fontBBox; + } + + protected String getCharName(int i) { + return charName[i]; + } + + protected char getUnicode(int i) { + return unicode[i]; + } + + protected char[] getUnicode() { + return unicode; + } + + protected int getNODefinedChars() { + return noDefinedChars; + } + + // ----------------------------------------------------------- + + /** + * Embed this font to the file. + * + * @param font The font to include + * @param name The name under which this font is addressed within the + * document (can be retrieved by getFontName()) + */ + public void includeFont(Font font, CharTable charTable, String name) + throws IOException { + + unicode = null; + charName = null; + + this.font = font; + this.charTable = charTable; + this.fontName = name; + + // figure out the maximum bounding box for all characters + this.fontBBox = font.getMaxCharBounds(context); + + // figure out the unicodes and character names and + // create a glyph vector containing the 256 glyphs of the font + this.noDefinedChars = 0; + this.unicode = new char[256]; + this.charName = new String[256]; + for (int i = 0; i < unicode.length; i++) { + charName[i] = charTable.toName(i); + if (charName[i] != null) { + unicode[i] = charTable.toUnicode(charName[i]); + noDefinedChars++; + } else { + unicode[i] = 0; + } + } + + openIncludeFont(); + writeEncoding(charTable); + closeIncludeFont(); + } + + protected double getUndefinedWidth() { + return FONT_SIZE; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontTable.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontTable.java index 75d31de78..ad1ac5edb 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontTable.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/font/FontTable.java @@ -1,235 +1,235 @@ -// Copyright 2001-2007 freehep -package org.xmind.org.freehep.graphicsio.font; - -import java.awt.Font; -import java.awt.font.TextAttribute; -import java.io.IOException; -import java.util.Collection; -import java.util.Hashtable; -import java.util.Map; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.graphics2d.font.FontUtilities; -import org.xmind.org.freehep.graphics2d.font.Lookup; - -/** - * A table to remember which fonts were used while writing a document. - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public abstract class FontTable { - - protected class Entry { - private Font font; - - private String ref; - - private CharTable encoding; - - private boolean written; - - private Entry(Font f, CharTable encoding) { - // get attributes of font for the stored default font - Map attributes = FontUtilities - .getAttributes(f); - - // set default font size - attributes.put(TextAttribute.SIZE, - new Float(FontEmbedder.FONT_SIZE)); - - // remove font transformations - attributes.remove(TextAttribute.TRANSFORM); - attributes.remove(TextAttribute.SUPERSCRIPT); - - this.font = new Font(attributes); - - this.ref = createFontReference(this.font); - this.encoding = encoding; - this.written = false; - } - - public Font getFont() { - return font; - } - - public String getReference() { - return ref; - } - - protected void setReference(String ref) { - this.ref = ref; - } - - public CharTable getEncoding() { - return encoding; - } - - public void setWritten(boolean written) { - this.written = written; - } - - public boolean isWritten() { - return written; - } - - public String toString() { - return ref + "=" + font; - } - } - - private Hashtable table; - - public FontTable() { - this.table = new Hashtable(); - } - - /** - * Returns a default CharTable to be used for normal text (not Symbol or - * Dingbats). - */ - public abstract CharTable getEncodingTable(); - - /** - * Called whenever a specific font is used for the first time. Subclasses - * may use this method to include the font instantly. This method may change - * the value of the reference by calling e.setReference(String) - * e.g. if it wants to substitute the font by a standard font that can be - * addressed under a name different from the generated one. - */ - protected abstract void firstRequest(Entry e, boolean embed, String embedAs) - throws IOException; - - /** Creates a unique reference to address this font. */ - protected abstract String createFontReference(Font f); - - protected abstract Font substituteFont(Font font); - - /** - * Returns a name for this font that can be used in the document. A new name - * is generated if the font was not used yet. For different fontsizes the - * same name is returned. - */ - public String fontReference(Font font, boolean embed, String embedAs) { - // look for stored font - font = substituteFont(font); - String key = getKey(font); - Entry e = (Entry) table.get(key); - - // create new one - if (e == null) { - e = new Entry(font, getEncodingTable(font)); - try { - firstRequest(e, embed, embedAs); - } catch (IOException exc) { - exc.printStackTrace(); - } - table.put(key, e); - } - - return e.ref; - } - - /** - * To embed all derivations of a font too (with underline, strikethrough - * etc.) the key consists all these attributes. - * - * @param font - * ist attributes are used - * @return something like Helvetica[BOLD:1][ITALIC:0][UNDERLINE:1] - */ - private String getKey(Font font) { - Map attributes = FontUtilities.getAttributes(font); - - StringBuffer result = new StringBuffer(font.getName()); - - // bold - result.append("[WEIGHT:"); - result.append(attributes.get(TextAttribute.WEIGHT)); - result.append("]"); - - // italic - result.append("[POSTURE:"); - result.append(attributes.get(TextAttribute.POSTURE)); - result.append("]"); - - // underline is not handled as an font property - // result.append("[UNDERLINE:"); - // result.append(attributes.get(TextAttribute.UNDERLINE)); - // result.append("]"); - - // strike through is not handled as an font property - // result.append("[STRIKETHROUGH:"); - // result.append(attributes.get(TextAttribute.STRIKETHROUGH)); - // result.append("]"); - - // SUPERSCRIPT is apllied by font.getTransformation() - // leave this as a reminder! - // result.append("["); - // result.append(attributes.get(TextAttribute.SUPERSCRIPT)); - // result.append("]"); - - // width is not handled as an font property - // result.append("[WIDTH:"); - // result.append(attributes.get(TextAttribute.WIDTH)); - // result.append("]"); - - return result.toString(); - } - - /** - * creates a normalized attribute map, e.g. - * java.awt.Font[family=Dialog,name=dialog.bold,style=plain,size=20] becomes - * java.awt.Font[family=Dialog,name=Dialog,style=bold,size=20] - * - * @param attributes - */ - public static void normalize(Map attributes) { - // get name - String family = (String) attributes.get(TextAttribute.FAMILY); - - // Java font names could end with ".plain" ".bold" - // and ".italic". We have to convert this to an - // attribute first - if (family.toLowerCase().endsWith(".bold")) { - attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); - // cut the ".bold" - int pos = family.toLowerCase().indexOf(".bold"); - family = family.substring(0, pos); - } else if (family.toLowerCase().endsWith(".italic")) { - attributes - .put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); - // cut the ".italic" - int pos = family.toLowerCase().indexOf(".italic"); - family = family.substring(0, pos); - } else if (family.toLowerCase().endsWith(".plain")) { - // cut the ".plain" - int pos = family.toLowerCase().indexOf(".plain"); - family = family.substring(0, pos); - } - - // first character up - family = family.substring(0, 1).toUpperCase() - + family.substring(1, family.length()); - attributes.put(TextAttribute.FAMILY, family); - } - - /** - * Returns a Collection view of all fonts. The elements of the collection - * are Entries. - */ - public Collection getEntries() { - return table.values(); - } - - private CharTable getEncodingTable(Font font) { - String fontname = font.getName().toLowerCase(); - if (fontname.indexOf("symbol") >= 0) - return Lookup.getInstance().getTable("Symbol"); - if (fontname.indexOf("zapfdingbats") >= 0) - return Lookup.getInstance().getTable("Zapfdingbats"); - return getEncodingTable(); - } - -} +// Copyright 2001-2007 freehep +package org.xmind.org.freehep.graphicsio.font; + +import java.awt.Font; +import java.awt.font.TextAttribute; +import java.io.IOException; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Map; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.graphics2d.font.FontUtilities; +import org.xmind.org.freehep.graphics2d.font.Lookup; + +/** + * A table to remember which fonts were used while writing a document. + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public abstract class FontTable { + + protected class Entry { + private Font font; + + private String ref; + + private CharTable encoding; + + private boolean written; + + private Entry(Font f, CharTable encoding) { + // get attributes of font for the stored default font + Map attributes = FontUtilities + .getAttributes(f); + + // set default font size + attributes.put(TextAttribute.SIZE, + new Float(FontEmbedder.FONT_SIZE)); + + // remove font transformations + attributes.remove(TextAttribute.TRANSFORM); + attributes.remove(TextAttribute.SUPERSCRIPT); + + this.font = new Font(attributes); + + this.ref = createFontReference(this.font); + this.encoding = encoding; + this.written = false; + } + + public Font getFont() { + return font; + } + + public String getReference() { + return ref; + } + + protected void setReference(String ref) { + this.ref = ref; + } + + public CharTable getEncoding() { + return encoding; + } + + public void setWritten(boolean written) { + this.written = written; + } + + public boolean isWritten() { + return written; + } + + public String toString() { + return ref + "=" + font; + } + } + + private Hashtable table; + + public FontTable() { + this.table = new Hashtable(); + } + + /** + * Returns a default CharTable to be used for normal text (not Symbol or + * Dingbats). + */ + public abstract CharTable getEncodingTable(); + + /** + * Called whenever a specific font is used for the first time. Subclasses + * may use this method to include the font instantly. This method may change + * the value of the reference by calling e.setReference(String) + * e.g. if it wants to substitute the font by a standard font that can be + * addressed under a name different from the generated one. + */ + protected abstract void firstRequest(Entry e, boolean embed, String embedAs) + throws IOException; + + /** Creates a unique reference to address this font. */ + protected abstract String createFontReference(Font f); + + protected abstract Font substituteFont(Font font); + + /** + * Returns a name for this font that can be used in the document. A new name + * is generated if the font was not used yet. For different fontsizes the + * same name is returned. + */ + public String fontReference(Font font, boolean embed, String embedAs) { + // look for stored font + font = substituteFont(font); + String key = getKey(font); + Entry e = (Entry) table.get(key); + + // create new one + if (e == null) { + e = new Entry(font, getEncodingTable(font)); + try { + firstRequest(e, embed, embedAs); + } catch (IOException exc) { + exc.printStackTrace(); + } + table.put(key, e); + } + + return e.ref; + } + + /** + * To embed all derivations of a font too (with underline, strikethrough + * etc.) the key consists all these attributes. + * + * @param font + * ist attributes are used + * @return something like Helvetica[BOLD:1][ITALIC:0][UNDERLINE:1] + */ + private String getKey(Font font) { + Map attributes = FontUtilities.getAttributes(font); + + StringBuffer result = new StringBuffer(font.getName()); + + // bold + result.append("[WEIGHT:"); + result.append(attributes.get(TextAttribute.WEIGHT)); + result.append("]"); + + // italic + result.append("[POSTURE:"); + result.append(attributes.get(TextAttribute.POSTURE)); + result.append("]"); + + // underline is not handled as an font property + // result.append("[UNDERLINE:"); + // result.append(attributes.get(TextAttribute.UNDERLINE)); + // result.append("]"); + + // strike through is not handled as an font property + // result.append("[STRIKETHROUGH:"); + // result.append(attributes.get(TextAttribute.STRIKETHROUGH)); + // result.append("]"); + + // SUPERSCRIPT is apllied by font.getTransformation() + // leave this as a reminder! + // result.append("["); + // result.append(attributes.get(TextAttribute.SUPERSCRIPT)); + // result.append("]"); + + // width is not handled as an font property + // result.append("[WIDTH:"); + // result.append(attributes.get(TextAttribute.WIDTH)); + // result.append("]"); + + return result.toString(); + } + + /** + * creates a normalized attribute map, e.g. + * java.awt.Font[family=Dialog,name=dialog.bold,style=plain,size=20] becomes + * java.awt.Font[family=Dialog,name=Dialog,style=bold,size=20] + * + * @param attributes + */ + public static void normalize(Map attributes) { + // get name + String family = (String) attributes.get(TextAttribute.FAMILY); + + // Java font names could end with ".plain" ".bold" + // and ".italic". We have to convert this to an + // attribute first + if (family.toLowerCase().endsWith(".bold")) { + attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); + // cut the ".bold" + int pos = family.toLowerCase().indexOf(".bold"); + family = family.substring(0, pos); + } else if (family.toLowerCase().endsWith(".italic")) { + attributes + .put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); + // cut the ".italic" + int pos = family.toLowerCase().indexOf(".italic"); + family = family.substring(0, pos); + } else if (family.toLowerCase().endsWith(".plain")) { + // cut the ".plain" + int pos = family.toLowerCase().indexOf(".plain"); + family = family.substring(0, pos); + } + + // first character up + family = family.substring(0, 1).toUpperCase() + + family.substring(1, family.length()); + attributes.put(TextAttribute.FAMILY, family); + } + + /** + * Returns a Collection view of all fonts. The elements of the collection + * are Entries. + */ + public Collection getEntries() { + return table.values(); + } + + private CharTable getEncodingTable(Font font) { + String fontname = font.getName().toLowerCase(); + if (fontname.indexOf("symbol") >= 0) + return Lookup.getInstance().getTable("Symbol"); + if (fontname.indexOf("zapfdingbats") >= 0) + return Lookup.getInstance().getTable("Zapfdingbats"); + return getEncodingTable(); + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/ImageBytes.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/ImageBytes.java index 1e2d61894..39845cae6 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/ImageBytes.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/ImageBytes.java @@ -1,132 +1,132 @@ -// Copyright 2000-2007 FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Color; -import java.awt.image.RenderedImage; -import java.io.IOException; - -import org.xmind.org.freehep.graphicsio.ImageConstants; -import org.xmind.org.freehep.graphicsio.ImageGraphics2D; - -/** - * PDF writes images as ZLIB or JPEG. This class converts an image to a byte[]. - * If neither {@link ImageConstants#ZLIB} nor {@link ImageConstants#JPEG} is - * passed the smallest size is stored for {@link #getBytes()}. The method - * {@link #getFormat()} returns the used format. - * - * @author Steffen Greiffenberg - * @version $Revision$ - */ -class ImageBytes { - - /** - * Used format during creation of bytes - */ - private String format; - - /** - * Bytes in given format - */ - private byte[] bytes; - - /** - * Encodes the passed image - * - * @param image - * image to convert - * @param bkg - * background color - * @param format - * format could be {@link ImageConstants#ZLIB} or - * {@link ImageConstants#JPEG} - * @param colorModel - * e.g. - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} - * @throws IOException - * thrown by - * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} - */ - public ImageBytes(RenderedImage image, Color bkg, String format, - String colorModel) throws IOException { - - // ZLIB encoding, transparent images allways require ZLIB - if (ImageConstants.ZLIB.equals(format) - || (image.getColorModel().hasAlpha() && (bkg == null))) { - bytes = toZLIB(image, bkg, colorModel); - this.format = ImageConstants.ZLIB; - } - - // JPG encoding - else if (ImageConstants.JPEG.equals(format)) { - bytes = toJPG(image); - this.format = ImageConstants.JPG; - } else { - // calculate both byte arrays - byte[] jpgBytes = toJPG(image); - byte[] zlibBytes = toZLIB(image, bkg, colorModel); - - // compare sizes to determine smalles format - if (jpgBytes.length < 0.5 * zlibBytes.length) { - bytes = jpgBytes; - this.format = ImageConstants.JPG; - } else { - bytes = zlibBytes; - this.format = ImageConstants.ZLIB; - } - } - } - - /** - * Creates the ZLIB Bytes for PDF images - * - * @param image - * image to convert - * @param bkg - * background color - * @param colorModel - * e.g. - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} - * @return bytes - * @throws IOException - * thrown by - * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} - */ - private byte[] toZLIB(RenderedImage image, Color bkg, String colorModel) - throws IOException { - return ImageGraphics2D.toByteArray(image, ImageConstants.RAW, - ImageConstants.ENCODING_FLATE_ASCII85, - ImageGraphics2D.getRAWProperties(bkg, colorModel)); - } - - /** - * Creates the JPG bytes for PDF images - * - * @param image - * image to convert - * @return bytes - * @throws IOException - * thrown by - * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} - */ - private byte[] toJPG(RenderedImage image) throws IOException { - return ImageGraphics2D.toByteArray(image, ImageConstants.JPG, - ImageConstants.ENCODING_ASCII85, null); - } - - /** - * @return bytes - */ - public byte[] getBytes() { - return bytes; - } - - /** - * @return used encoding format - */ - public String getFormat() { - return format; - } -} -/** - * $Log$ - */ +// Copyright 2000-2007 FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Color; +import java.awt.image.RenderedImage; +import java.io.IOException; + +import org.xmind.org.freehep.graphicsio.ImageConstants; +import org.xmind.org.freehep.graphicsio.ImageGraphics2D; + +/** + * PDF writes images as ZLIB or JPEG. This class converts an image to a byte[]. + * If neither {@link ImageConstants#ZLIB} nor {@link ImageConstants#JPEG} is + * passed the smallest size is stored for {@link #getBytes()}. The method + * {@link #getFormat()} returns the used format. + * + * @author Steffen Greiffenberg + * @version $Revision$ + */ +class ImageBytes { + + /** + * Used format during creation of bytes + */ + private String format; + + /** + * Bytes in given format + */ + private byte[] bytes; + + /** + * Encodes the passed image + * + * @param image + * image to convert + * @param bkg + * background color + * @param format + * format could be {@link ImageConstants#ZLIB} or + * {@link ImageConstants#JPEG} + * @param colorModel + * e.g. + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} + * @throws IOException + * thrown by + * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} + */ + public ImageBytes(RenderedImage image, Color bkg, String format, + String colorModel) throws IOException { + + // ZLIB encoding, transparent images allways require ZLIB + if (ImageConstants.ZLIB.equals(format) + || (image.getColorModel().hasAlpha() && (bkg == null))) { + bytes = toZLIB(image, bkg, colorModel); + this.format = ImageConstants.ZLIB; + } + + // JPG encoding + else if (ImageConstants.JPEG.equals(format)) { + bytes = toJPG(image); + this.format = ImageConstants.JPG; + } else { + // calculate both byte arrays + byte[] jpgBytes = toJPG(image); + byte[] zlibBytes = toZLIB(image, bkg, colorModel); + + // compare sizes to determine smalles format + if (jpgBytes.length < 0.5 * zlibBytes.length) { + bytes = jpgBytes; + this.format = ImageConstants.JPG; + } else { + bytes = zlibBytes; + this.format = ImageConstants.ZLIB; + } + } + } + + /** + * Creates the ZLIB Bytes for PDF images + * + * @param image + * image to convert + * @param bkg + * background color + * @param colorModel + * e.g. + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#COLOR_MODEL_RGB} + * @return bytes + * @throws IOException + * thrown by + * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} + */ + private byte[] toZLIB(RenderedImage image, Color bkg, String colorModel) + throws IOException { + return ImageGraphics2D.toByteArray(image, ImageConstants.RAW, + ImageConstants.ENCODING_FLATE_ASCII85, + ImageGraphics2D.getRAWProperties(bkg, colorModel)); + } + + /** + * Creates the JPG bytes for PDF images + * + * @param image + * image to convert + * @return bytes + * @throws IOException + * thrown by + * {@link org.xmind.org.freehep.graphicsio.ImageGraphics2D#toByteArray(java.awt.image.RenderedImage, String, String, java.util.Properties)} + */ + private byte[] toJPG(RenderedImage image) throws IOException { + return ImageGraphics2D.toByteArray(image, ImageConstants.JPG, + ImageConstants.ENCODING_ASCII85, null); + } + + /** + * @return bytes + */ + public byte[] getBytes() { + return bytes; + } + + /** + * @return used encoding format + */ + public String getFormat() { + return format; + } +} +/** + * $Log$ + */ diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDF.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDF.java index 55da829b2..629283c1a 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDF.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDF.java @@ -1,120 +1,120 @@ -// Copyright 2000-2005 FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.text.DecimalFormat; -import java.util.Hashtable; -import java.util.Vector; - -/** - * Implements the lookup tables. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDF { - - private int generationNumber = 0; - - // PDFRefs stored by name - private Hashtable refsByName = new Hashtable(); - - // PDFRefs stored by number - private Vector refsByNumber = new Vector(); - - // Offsets stored by refnumber - private Vector xrefsByNumber = new Vector(); - - private int startXref = 0; - - protected PDFByteWriter out; - - PDF(PDFByteWriter out) { - this.out = out; - // add dummy element to refsByNumber and xrefsByNumber - refsByNumber.addElement(new PDFRef("Dummy", 0, 0)); - xrefsByNumber.addElement(new Integer(999999)); - } - - public PDFName name(String name) { - return new PDFName(name); - } - - public PDFRef ref(String name) { - if (name == null) - return null; - PDFRef ref = (PDFRef) refsByName.get(name); - if (ref == null) { - int refNumber = refsByNumber.size(); - ref = new PDFRef(name, refNumber, generationNumber); - refsByName.put(name, ref); - refsByNumber.add(ref); - xrefsByNumber.add(null); - } - return ref; - } - - public PDFRef[] ref(String[] names) { - PDFRef[] refs = new PDFRef[names.length]; - for (int i = 0; i < names.length; i++) { - refs[i] = ref(names[i]); - } - return refs; - } - - protected void setXRef(int objectNumber, int offset) { - xrefsByNumber.set(objectNumber, new Integer(offset)); - } - - protected void xref() throws IOException { - DecimalFormat offsetFormat = new DecimalFormat("0000000000"); - DecimalFormat linkFormat = new DecimalFormat("00000"); - startXref = out.getCount(); - out.printPlain("xref"); - out.println(); - out.printPlain(0 + " " + xrefsByNumber.size()); - out.println(); - - // the free list header - out.printPlain(offsetFormat.format(0) + " " + linkFormat.format(65535) - + " f\r\n"); - - // the used list - for (int i = 1; i < xrefsByNumber.size(); i++) { - Integer offsetObject = (Integer) xrefsByNumber.get(i); - if (offsetObject != null) { - int offset = offsetObject.intValue(); - out.printPlain(offsetFormat.format(offset) + " " - + linkFormat.format(0) + " n\r\n"); - } else { - PDFRef ref = (PDFRef) refsByNumber.get(i); - System.err.println("PDFWriter: PDFRef '" + ref.getName() - + "' is used but not defined."); - } - } - - out.println(); - } - - protected void trailer(String rootName, String docInfoName) - throws IOException { - out.println("trailer"); - PDFDictionary dictionary = new PDFDictionary(this, out); - dictionary.entry("Size", refsByName.size()); - dictionary.entry("Root", ref(rootName)); - if (docInfoName != null) - dictionary.entry("Info", ref(docInfoName)); - dictionary.close(); - - out.println(); - } - - protected void startxref() throws IOException { - out.println("startxref"); - out.println(startXref); - - out.println(); - } +// Copyright 2000-2005 FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Implements the lookup tables. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDF { + + private int generationNumber = 0; + + // PDFRefs stored by name + private Hashtable refsByName = new Hashtable(); + + // PDFRefs stored by number + private Vector refsByNumber = new Vector(); + + // Offsets stored by refnumber + private Vector xrefsByNumber = new Vector(); + + private int startXref = 0; + + protected PDFByteWriter out; + + PDF(PDFByteWriter out) { + this.out = out; + // add dummy element to refsByNumber and xrefsByNumber + refsByNumber.addElement(new PDFRef("Dummy", 0, 0)); + xrefsByNumber.addElement(new Integer(999999)); + } + + public PDFName name(String name) { + return new PDFName(name); + } + + public PDFRef ref(String name) { + if (name == null) + return null; + PDFRef ref = (PDFRef) refsByName.get(name); + if (ref == null) { + int refNumber = refsByNumber.size(); + ref = new PDFRef(name, refNumber, generationNumber); + refsByName.put(name, ref); + refsByNumber.add(ref); + xrefsByNumber.add(null); + } + return ref; + } + + public PDFRef[] ref(String[] names) { + PDFRef[] refs = new PDFRef[names.length]; + for (int i = 0; i < names.length; i++) { + refs[i] = ref(names[i]); + } + return refs; + } + + protected void setXRef(int objectNumber, int offset) { + xrefsByNumber.set(objectNumber, new Integer(offset)); + } + + protected void xref() throws IOException { + DecimalFormat offsetFormat = new DecimalFormat("0000000000"); + DecimalFormat linkFormat = new DecimalFormat("00000"); + startXref = out.getCount(); + out.printPlain("xref"); + out.println(); + out.printPlain(0 + " " + xrefsByNumber.size()); + out.println(); + + // the free list header + out.printPlain(offsetFormat.format(0) + " " + linkFormat.format(65535) + + " f\r\n"); + + // the used list + for (int i = 1; i < xrefsByNumber.size(); i++) { + Integer offsetObject = (Integer) xrefsByNumber.get(i); + if (offsetObject != null) { + int offset = offsetObject.intValue(); + out.printPlain(offsetFormat.format(offset) + " " + + linkFormat.format(0) + " n\r\n"); + } else { + PDFRef ref = (PDFRef) refsByNumber.get(i); + System.err.println("PDFWriter: PDFRef '" + ref.getName() + + "' is used but not defined."); + } + } + + out.println(); + } + + protected void trailer(String rootName, String docInfoName) + throws IOException { + out.println("trailer"); + PDFDictionary dictionary = new PDFDictionary(this, out); + dictionary.entry("Size", refsByName.size()); + dictionary.entry("Root", ref(rootName)); + if (docInfoName != null) + dictionary.entry("Info", ref(docInfoName)); + dictionary.close(); + + out.println(); + } + + protected void startxref() throws IOException { + out.println("startxref"); + out.println(startXref); + + out.println(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFByteWriter.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFByteWriter.java index f50dad1fb..2bdf124d6 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFByteWriter.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFByteWriter.java @@ -1,109 +1,109 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.org.freehep.util.io.CountedByteOutputStream; - -/** - * Implements the real writer for the PDFWriter. This class does byte-counting - * to eventually build the cross-reference table, block length counting for the - * length of streams, and platform dependent end-of-line characters. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFByteWriter extends CountedByteOutputStream implements - PDFConstants { - - private int indent; - - private String indentString = " "; - - PDFByteWriter(OutputStream out) { - super(out); - indent = 0; - } - - public void write(String s) throws IOException { - write(s.getBytes("ISO-8859-1")); - } - - public void close() throws IOException { - out.close(); - super.close(); - } - - public void print(String string) throws IOException { - for (int i = 0; i < indent; i++) { - write(indentString); - } - printPlain(string); - } - - public void printPlain(String string) throws IOException { - write(string); - } - - public void println() throws IOException { - write(EOL); - } - - public void indent() { - indent++; - } - - public void outdent() { - if (indent > 0) { - indent--; - } - } - - // Convenience methods - public void println(String string) throws IOException { - print(string); - println(); - } - - public void print(int number) throws IOException { - print(Integer.toString(number)); - } - - public void println(int number) throws IOException { - print(number); - println(); - } - - public void printPlain(int number) throws IOException { - printPlain(Integer.toString(number)); - } - - public void print(double number) throws IOException { - print(Double.toString(number)); - } - - public void println(double number) throws IOException { - print(number); - println(); - } - - public void printPlain(double number) throws IOException { - printPlain(Double.toString(number)); - } - - public void print(Object object) throws IOException { - print(object.toString()); - } - - public void println(Object object) throws IOException { - print(object); - println(); - } - - public void printPlain(Object object) throws IOException { - printPlain(object.toString()); - } - +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.org.freehep.util.io.CountedByteOutputStream; + +/** + * Implements the real writer for the PDFWriter. This class does byte-counting + * to eventually build the cross-reference table, block length counting for the + * length of streams, and platform dependent end-of-line characters. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFByteWriter extends CountedByteOutputStream implements + PDFConstants { + + private int indent; + + private String indentString = " "; + + PDFByteWriter(OutputStream out) { + super(out); + indent = 0; + } + + public void write(String s) throws IOException { + write(s.getBytes("ISO-8859-1")); + } + + public void close() throws IOException { + out.close(); + super.close(); + } + + public void print(String string) throws IOException { + for (int i = 0; i < indent; i++) { + write(indentString); + } + printPlain(string); + } + + public void printPlain(String string) throws IOException { + write(string); + } + + public void println() throws IOException { + write(EOL); + } + + public void indent() { + indent++; + } + + public void outdent() { + if (indent > 0) { + indent--; + } + } + + // Convenience methods + public void println(String string) throws IOException { + print(string); + println(); + } + + public void print(int number) throws IOException { + print(Integer.toString(number)); + } + + public void println(int number) throws IOException { + print(number); + println(); + } + + public void printPlain(int number) throws IOException { + printPlain(Integer.toString(number)); + } + + public void print(double number) throws IOException { + print(Double.toString(number)); + } + + public void println(double number) throws IOException { + print(number); + println(); + } + + public void printPlain(double number) throws IOException { + printPlain(Double.toString(number)); + } + + public void print(Object object) throws IOException { + print(object.toString()); + } + + public void println(Object object) throws IOException { + print(object); + println(); + } + + public void printPlain(Object object) throws IOException { + printPlain(object.toString()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCatalog.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCatalog.java index a5f453885..cc4aeb0b0 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCatalog.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCatalog.java @@ -1,75 +1,75 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements the Catalog Dictionary (see Table 3.15). - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFCatalog extends PDFDictionary { - - PDFCatalog(PDF pdf, PDFByteWriter writer, PDFObject parent, PDFRef pageTree) - throws IOException { - super(pdf, writer, parent); - entry("Type", pdf.name("Catalog")); - entry("Pages", pageTree); - } - - /* - * public void setPageLabels(PDFNumberTree pageLabels) { entry("PageLabels", - * pageLabels); } - */ - - public void setNames(String names) throws IOException { - entry("Names", pdf.ref(names)); - } - - public void setDests(String dests) throws IOException { - entry("Dests", pdf.ref(dests)); - } - - public void setViewerPreferences(String viewerPreferences) - throws IOException { - entry("ViewerPreferences", pdf.ref(viewerPreferences)); - } - - public void setPageLayout(String pageLayout) throws IOException { - entry("PageLayout", pdf.name(pageLayout)); - } - - public void setPageMode(String pageMode) throws IOException { - entry("PageMode", pdf.name(pageMode)); - } - - public void setOutlines(String outlines) throws IOException { - entry("Outlines", pdf.ref(outlines)); - } - - public void setThreads(String threads) throws IOException { - entry("Threads", pdf.ref(threads)); - } - - public void setOpenAction(Object[] openAction) throws IOException { - entry("OpenAction", openAction); - } - - public void setURI(String uri) throws IOException { - entry("URI", pdf.ref(uri)); - } - - public void setAcroForm(String acroForm) throws IOException { - entry("AcroForm", pdf.ref(acroForm)); - } - - public void setStructTreeRoot(String structTreeRoot) throws IOException { - entry("StructTreeRoot", pdf.ref(structTreeRoot)); - } - - public void setSpiderInfo(String spiderInfo) throws IOException { - entry("SpiderInfo", pdf.ref(spiderInfo)); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements the Catalog Dictionary (see Table 3.15). + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFCatalog extends PDFDictionary { + + PDFCatalog(PDF pdf, PDFByteWriter writer, PDFObject parent, PDFRef pageTree) + throws IOException { + super(pdf, writer, parent); + entry("Type", pdf.name("Catalog")); + entry("Pages", pageTree); + } + + /* + * public void setPageLabels(PDFNumberTree pageLabels) { entry("PageLabels", + * pageLabels); } + */ + + public void setNames(String names) throws IOException { + entry("Names", pdf.ref(names)); + } + + public void setDests(String dests) throws IOException { + entry("Dests", pdf.ref(dests)); + } + + public void setViewerPreferences(String viewerPreferences) + throws IOException { + entry("ViewerPreferences", pdf.ref(viewerPreferences)); + } + + public void setPageLayout(String pageLayout) throws IOException { + entry("PageLayout", pdf.name(pageLayout)); + } + + public void setPageMode(String pageMode) throws IOException { + entry("PageMode", pdf.name(pageMode)); + } + + public void setOutlines(String outlines) throws IOException { + entry("Outlines", pdf.ref(outlines)); + } + + public void setThreads(String threads) throws IOException { + entry("Threads", pdf.ref(threads)); + } + + public void setOpenAction(Object[] openAction) throws IOException { + entry("OpenAction", openAction); + } + + public void setURI(String uri) throws IOException { + entry("URI", pdf.ref(uri)); + } + + public void setAcroForm(String acroForm) throws IOException { + entry("AcroForm", pdf.ref(acroForm)); + } + + public void setStructTreeRoot(String structTreeRoot) throws IOException { + entry("StructTreeRoot", pdf.ref(structTreeRoot)); + } + + public void setSpiderInfo(String spiderInfo) throws IOException { + entry("SpiderInfo", pdf.ref(spiderInfo)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCharTableWriter.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCharTableWriter.java index 3224f19a4..78fdfcea8 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCharTableWriter.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFCharTableWriter.java @@ -1,42 +1,42 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.graphicsio.font.FontEmbedder; - -/** - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFCharTableWriter implements PDFRedundanceTracker.Writer { - - private static PDFCharTableWriter ctw; - - public static PDFCharTableWriter getInstance() { - if (ctw == null) - ctw = new PDFCharTableWriter(); - return ctw; - } - - public void writeObject(Object object, PDFRef ref, PDFWriter pdf) - throws IOException { - - CharTable charTable = (CharTable) object; - - PDFDictionary encoding = pdf.openDictionary(ref.getName()); - encoding.entry("Type", pdf.name("Encoding")); - - Object[] differences = new Object[257]; - differences[0] = new Integer(0); - for (int i = 0; i < 256; i++) { - String charName = charTable.toName(i); - differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf - .name(FontEmbedder.NOTDEF); - } - encoding.entry("Differences", differences); - - pdf.close(encoding); - } -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.graphicsio.font.FontEmbedder; + +/** + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFCharTableWriter implements PDFRedundanceTracker.Writer { + + private static PDFCharTableWriter ctw; + + public static PDFCharTableWriter getInstance() { + if (ctw == null) + ctw = new PDFCharTableWriter(); + return ctw; + } + + public void writeObject(Object object, PDFRef ref, PDFWriter pdf) + throws IOException { + + CharTable charTable = (CharTable) object; + + PDFDictionary encoding = pdf.openDictionary(ref.getName()); + encoding.entry("Type", pdf.name("Encoding")); + + Object[] differences = new Object[257]; + differences[0] = new Integer(0); + for (int i = 0; i < 256; i++) { + String charName = charTable.toName(i); + differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf + .name(FontEmbedder.NOTDEF); + } + encoding.entry("Differences", differences); + + pdf.close(encoding); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFConstants.java index 635eaa243..c6735439a 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFConstants.java @@ -1,55 +1,55 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.text.SimpleDateFormat; - -/** - * Specifies constants for use with the PDFWriter, PDFStream and PDFUtil. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public interface PDFConstants { - - public final static String EOL = System.getProperty("line.separator"); - - // - // Constants for PDFStream - // - - // Line Cap Styles (see Table 4.4) - public static final int CAP_BUTT = 0; - - public static final int CAP_ROUND = 1; - - public static final int CAP_SQUARE = 2; - - // Line Join Styles (see Table 4.5) - public static final int JOIN_MITTER = 0; - - public static final int JOIN_ROUND = 1; - - public static final int JOIN_BEVEL = 2; - - // Rendering Modes (see Table 5.3) - public static final int MODE_FILL = 0; - - public static final int MODE_STROKE = 1; - - public static final int MODE_FILL_STROKE = 2; - - public static final int MODE_INVISIBLE = 3; - - public static final int MODE_FILL_CLIP = 4; - - public static final int MODE_STROKE_CLIP = 5; - - public static final int MODE_FILL_STROKE_CLIP = 6; - - public static final int MODE_CLIP = 7; - - // Date Format for PDF: (D:YYYYMMDDHHmmSSOHH'mm') - public static final SimpleDateFormat dateFormat = new SimpleDateFormat( - "yyyyMMddHHmmss"); -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.text.SimpleDateFormat; + +/** + * Specifies constants for use with the PDFWriter, PDFStream and PDFUtil. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public interface PDFConstants { + + public final static String EOL = System.getProperty("line.separator"); + + // + // Constants for PDFStream + // + + // Line Cap Styles (see Table 4.4) + public static final int CAP_BUTT = 0; + + public static final int CAP_ROUND = 1; + + public static final int CAP_SQUARE = 2; + + // Line Join Styles (see Table 4.5) + public static final int JOIN_MITTER = 0; + + public static final int JOIN_ROUND = 1; + + public static final int JOIN_BEVEL = 2; + + // Rendering Modes (see Table 5.3) + public static final int MODE_FILL = 0; + + public static final int MODE_STROKE = 1; + + public static final int MODE_FILL_STROKE = 2; + + public static final int MODE_INVISIBLE = 3; + + public static final int MODE_FILL_CLIP = 4; + + public static final int MODE_STROKE_CLIP = 5; + + public static final int MODE_FILL_STROKE_CLIP = 6; + + public static final int MODE_CLIP = 7; + + // Date Format for PDF: (D:YYYYMMDDHHmmSSOHH'mm') + public static final SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyyMMddHHmmss"); +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDictionary.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDictionary.java index 8a7afaa75..0780f9c88 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDictionary.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDictionary.java @@ -1,163 +1,163 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.util.Calendar; - -/** - * Implements a PDF Dictionary. All PDFObjects (including java Strings and - * arrays) can be entered into the dictionary. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFDictionary implements PDFConstants { - - private String open = null; - - protected PDFByteWriter out; - - private boolean ok; - - private PDFObject object; - - protected PDF pdf; - - PDFDictionary(PDF pdf, PDFByteWriter writer) throws IOException { - this(pdf, writer, null); - } - - PDFDictionary(PDF pdf, PDFByteWriter writer, PDFObject parent) - throws IOException { - this.pdf = pdf; - object = parent; - out = writer; - out.println("<< "); - out.indent(); - ok = true; - } - - void close() throws IOException { - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - out.outdent(); - out.println(">>"); - if (object != null) - object.close(); - ok = false; - } - - public void entry(String key, String string) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " (" + PDFUtil.escape(string) + ")"); - } - - public void entry(String key, PDFName name) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + name); - } - - public void entry(String key, int number) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + number); - } - - public void entry(String key, double number) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + PDFUtil.fixedPrecision(number)); - } - - public void entry(String key, boolean bool) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + (bool ? "true" : "false")); - } - - public void entry(String key, PDFRef ref) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + ref); - } - - public void entry(String key, Calendar date) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.println("/" + key + " " + PDFUtil.date(date)); - } - - public void entry(String key, Object[] objs) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.print("/" + key + " ["); - for (int i = 0; i < objs.length; i++) { - if (i != 0) - out.printPlain(" "); - out.printPlain(objs[i]); - } - out.printPlain("]"); - out.println(); - } - - public void entry(String key, int[] numbers) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.print("/" + key + " ["); - for (int i = 0; i < numbers.length; i++) { - if (i != 0) - out.printPlain(" "); - out.printPlain(numbers[i]); - } - out.printPlain("]"); - out.println(); - } - - public void entry(String key, double[] numbers) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.print("/" + key + " ["); - for (int i = 0; i < numbers.length; i++) { - if (i != 0) - out.printPlain(" "); - out.printPlain(PDFUtil.fixedPrecision(numbers[i])); - } - out.printPlain("]"); - out.println(); - } - - public void entry(String key, boolean[] bool) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - out.print("/" + key + " ["); - for (int i = 0; i < bool.length; i++) { - if (i != 0) - out.printPlain(" "); - out.printPlain(bool[i] ? "true" : "false"); - } - out.printPlain("]"); - out.println(); - } - - public PDFDictionary openDictionary(String name) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFDictionary: " + name; - out.println("/" + name); - PDFDictionary dictionary = new PDFDictionary(pdf, out); - return dictionary; - } - - public void close(PDFDictionary dictionary) throws IOException { - dictionary.close(); - open = null; - } - -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.util.Calendar; + +/** + * Implements a PDF Dictionary. All PDFObjects (including java Strings and + * arrays) can be entered into the dictionary. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFDictionary implements PDFConstants { + + private String open = null; + + protected PDFByteWriter out; + + private boolean ok; + + private PDFObject object; + + protected PDF pdf; + + PDFDictionary(PDF pdf, PDFByteWriter writer) throws IOException { + this(pdf, writer, null); + } + + PDFDictionary(PDF pdf, PDFByteWriter writer, PDFObject parent) + throws IOException { + this.pdf = pdf; + object = parent; + out = writer; + out.println("<< "); + out.indent(); + ok = true; + } + + void close() throws IOException { + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + out.outdent(); + out.println(">>"); + if (object != null) + object.close(); + ok = false; + } + + public void entry(String key, String string) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " (" + PDFUtil.escape(string) + ")"); + } + + public void entry(String key, PDFName name) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + name); + } + + public void entry(String key, int number) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + number); + } + + public void entry(String key, double number) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + PDFUtil.fixedPrecision(number)); + } + + public void entry(String key, boolean bool) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + (bool ? "true" : "false")); + } + + public void entry(String key, PDFRef ref) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + ref); + } + + public void entry(String key, Calendar date) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.println("/" + key + " " + PDFUtil.date(date)); + } + + public void entry(String key, Object[] objs) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.print("/" + key + " ["); + for (int i = 0; i < objs.length; i++) { + if (i != 0) + out.printPlain(" "); + out.printPlain(objs[i]); + } + out.printPlain("]"); + out.println(); + } + + public void entry(String key, int[] numbers) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.print("/" + key + " ["); + for (int i = 0; i < numbers.length; i++) { + if (i != 0) + out.printPlain(" "); + out.printPlain(numbers[i]); + } + out.printPlain("]"); + out.println(); + } + + public void entry(String key, double[] numbers) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.print("/" + key + " ["); + for (int i = 0; i < numbers.length; i++) { + if (i != 0) + out.printPlain(" "); + out.printPlain(PDFUtil.fixedPrecision(numbers[i])); + } + out.printPlain("]"); + out.println(); + } + + public void entry(String key, boolean[] bool) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + out.print("/" + key + " ["); + for (int i = 0; i < bool.length; i++) { + if (i != 0) + out.printPlain(" "); + out.printPlain(bool[i] ? "true" : "false"); + } + out.printPlain("]"); + out.println(); + } + + public PDFDictionary openDictionary(String name) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFDictionary: " + name; + out.println("/" + name); + PDFDictionary dictionary = new PDFDictionary(pdf, out); + return dictionary; + } + + public void close(PDFDictionary dictionary) throws IOException { + dictionary.close(); + open = null; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDocInfo.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDocInfo.java index 8e15a24ab..1d1c35324 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDocInfo.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFDocInfo.java @@ -1,56 +1,56 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.util.Calendar; - -/** - * Implements the Document Information Dictionary (see Table 8.2). - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFDocInfo extends PDFDictionary { - - PDFDocInfo(PDF pdf, PDFByteWriter writer, PDFObject parent) - throws IOException { - super(pdf, writer, parent); - } - - public void setTitle(String title) throws IOException { - entry("Title", title); - } - - public void setAuthor(String author) throws IOException { - entry("Author", author); - } - - public void setSubject(String subject) throws IOException { - entry("Subject", subject); - } - - public void setKeywords(String keywords) throws IOException { - entry("Keywords", keywords); - } - - public void setCreator(String creator) throws IOException { - entry("Creator", creator); - } - - public void setProducer(String producer) throws IOException { - entry("Producer", producer); - } - - public void setCreationDate(Calendar date) throws IOException { - entry("CreationDate", date); - } - - public void setModificationDate(Calendar date) throws IOException { - entry("ModDate", date); - } - - public void setTrapped(String name) throws IOException { - entry("Trapped", pdf.name(name)); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.util.Calendar; + +/** + * Implements the Document Information Dictionary (see Table 8.2). + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFDocInfo extends PDFDictionary { + + PDFDocInfo(PDF pdf, PDFByteWriter writer, PDFObject parent) + throws IOException { + super(pdf, writer, parent); + } + + public void setTitle(String title) throws IOException { + entry("Title", title); + } + + public void setAuthor(String author) throws IOException { + entry("Author", author); + } + + public void setSubject(String subject) throws IOException { + entry("Subject", subject); + } + + public void setKeywords(String keywords) throws IOException { + entry("Keywords", keywords); + } + + public void setCreator(String creator) throws IOException { + entry("Creator", creator); + } + + public void setProducer(String producer) throws IOException { + entry("Producer", producer); + } + + public void setCreationDate(Calendar date) throws IOException { + entry("CreationDate", date); + } + + public void setModificationDate(Calendar date) throws IOException { + entry("ModDate", date); + } + + public void setTrapped(String name) throws IOException { + entry("Trapped", pdf.name(name)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedder.java index 0c11e238b..1986c4896 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedder.java @@ -1,121 +1,121 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.font.FontRenderContext; -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.graphicsio.font.FontEmbedder; - -/** - * Superclass of all FontEmbedders for PDF documents. Subclasses must implement - * all abstract methods which are called in the following order: - *

      - *
    • addAdditionalEntries - *
    • addAdditionalInitDicts - *
    • writeGlyph once for each glyph in the order of the encoding - *
    - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public abstract class PDFFontEmbedder extends FontEmbedder { - - /** sloppily declared protected */ - protected PDFWriter pdf; - - private PDFDictionary fontDict; - - private String reference; - - private PDFRedundanceTracker redundanceTracker; - - public PDFFontEmbedder(FontRenderContext context, PDFWriter pdf, - String reference, PDFRedundanceTracker tracker) { - super(context); - this.pdf = pdf; - this.reference = reference; - this.redundanceTracker = tracker; - } - - /** Returns the font subtype (currently only Type3). */ - protected abstract String getSubtype(); - - /** Add additional entries to the font Dictionary. */ - protected abstract void addAdditionalEntries(PDFDictionary fontDict) - throws IOException; - - /** - * Add additional dicionaries to the PDFWriter which may be referenced by - * entries generated by addAdditionalEntries() - */ - protected abstract void addAdditionalInitDicts() throws IOException; - - /** - * Returns the reference String that identifies the font dictionary. Use - * this reference plus underscore plus suffix for other dictionaries. - */ - protected String getReference() { - return reference; - } - - protected void openIncludeFont() throws IOException { - - fontDict = pdf.openDictionary(reference); - - fontDict.entry("Type", pdf.name("Font")); - fontDict.entry("Subtype", pdf.name(getSubtype())); - fontDict.entry("Name", pdf.name(getFontName())); - - fontDict.entry("FirstChar", 0); - fontDict.entry("LastChar", 255); - // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); - fontDict.entry("Encoding", redundanceTracker.getReference( - getEncodingTable(), PDFCharTableWriter.getInstance())); - fontDict.entry("Widths", pdf.ref(reference + "Widths")); - - addAdditionalEntries(fontDict); - - pdf.close(fontDict); - - addAdditionalInitDicts(); - } - - protected void closeEmbedFont() { - } - - protected void writeWidths(double[] widths) throws IOException { - Object[] widthsObj = new Object[256]; - for (int i = 0; i < widthsObj.length; i++) { - widthsObj[i] = new Double(widths[i]); - } - pdf.object(reference + "Widths", widthsObj); - } - - protected void writeEncoding(CharTable charTable) throws IOException { - // writeEncoding(pdf, reference+"Encoding", charTable); - } - - public static void writeEncoding(PDFWriter pdf, String ref, - CharTable charTable) throws IOException { - PDFDictionary encoding = pdf.openDictionary(ref); - encoding.entry("Type", pdf.name("Encoding")); - - Object[] differences = new Object[257]; - differences[0] = new Integer(0); - for (int i = 0; i < 256; i++) { - String charName = charTable.toName(i); - differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf - .name(NOTDEF); - } - encoding.entry("Differences", differences); - - pdf.close(encoding); - } - - protected String createCharacterReference(String characterName) { - return "Glyph_" + reference + ":" + characterName; - } - -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.font.FontRenderContext; +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.graphicsio.font.FontEmbedder; + +/** + * Superclass of all FontEmbedders for PDF documents. Subclasses must implement + * all abstract methods which are called in the following order: + *
      + *
    • addAdditionalEntries + *
    • addAdditionalInitDicts + *
    • writeGlyph once for each glyph in the order of the encoding + *
    + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public abstract class PDFFontEmbedder extends FontEmbedder { + + /** sloppily declared protected */ + protected PDFWriter pdf; + + private PDFDictionary fontDict; + + private String reference; + + private PDFRedundanceTracker redundanceTracker; + + public PDFFontEmbedder(FontRenderContext context, PDFWriter pdf, + String reference, PDFRedundanceTracker tracker) { + super(context); + this.pdf = pdf; + this.reference = reference; + this.redundanceTracker = tracker; + } + + /** Returns the font subtype (currently only Type3). */ + protected abstract String getSubtype(); + + /** Add additional entries to the font Dictionary. */ + protected abstract void addAdditionalEntries(PDFDictionary fontDict) + throws IOException; + + /** + * Add additional dicionaries to the PDFWriter which may be referenced by + * entries generated by addAdditionalEntries() + */ + protected abstract void addAdditionalInitDicts() throws IOException; + + /** + * Returns the reference String that identifies the font dictionary. Use + * this reference plus underscore plus suffix for other dictionaries. + */ + protected String getReference() { + return reference; + } + + protected void openIncludeFont() throws IOException { + + fontDict = pdf.openDictionary(reference); + + fontDict.entry("Type", pdf.name("Font")); + fontDict.entry("Subtype", pdf.name(getSubtype())); + fontDict.entry("Name", pdf.name(getFontName())); + + fontDict.entry("FirstChar", 0); + fontDict.entry("LastChar", 255); + // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); + fontDict.entry("Encoding", redundanceTracker.getReference( + getEncodingTable(), PDFCharTableWriter.getInstance())); + fontDict.entry("Widths", pdf.ref(reference + "Widths")); + + addAdditionalEntries(fontDict); + + pdf.close(fontDict); + + addAdditionalInitDicts(); + } + + protected void closeEmbedFont() { + } + + protected void writeWidths(double[] widths) throws IOException { + Object[] widthsObj = new Object[256]; + for (int i = 0; i < widthsObj.length; i++) { + widthsObj[i] = new Double(widths[i]); + } + pdf.object(reference + "Widths", widthsObj); + } + + protected void writeEncoding(CharTable charTable) throws IOException { + // writeEncoding(pdf, reference+"Encoding", charTable); + } + + public static void writeEncoding(PDFWriter pdf, String ref, + CharTable charTable) throws IOException { + PDFDictionary encoding = pdf.openDictionary(ref); + encoding.entry("Type", pdf.name("Encoding")); + + Object[] differences = new Object[257]; + differences[0] = new Integer(0); + for (int i = 0; i < 256; i++) { + String charName = charTable.toName(i); + differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf + .name(NOTDEF); + } + encoding.entry("Differences", differences); + + pdf.close(encoding); + } + + protected String createCharacterReference(String characterName) { + return "Glyph_" + reference + ":" + characterName; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType1.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType1.java index 4b200ce58..73db0781c 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType1.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType1.java @@ -1,136 +1,136 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.font.FontRenderContext; -import java.awt.font.LineMetrics; -import java.awt.geom.Rectangle2D; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.xmind.org.freehep.graphicsio.font.FontEmbedderType1; - -/** - * Font embedder for type one fonts in pdf documents. - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFFontEmbedderType1 extends FontEmbedderType1 { - - private ByteArrayOutputStream byteBuffer; - - private String reference; - - private PDFWriter pdf; - - private PDFStream fontFile; - - private PDFRedundanceTracker redundanceTracker; - - public static PDFFontEmbedderType1 create(FontRenderContext context, - PDFWriter pdf, String reference, PDFRedundanceTracker tracker) { - return new PDFFontEmbedderType1(context, pdf, reference, - new ByteArrayOutputStream(), tracker); - } - - private PDFFontEmbedderType1(FontRenderContext context, PDFWriter pdf, - String reference, ByteArrayOutputStream byteOut, - PDFRedundanceTracker tracker) { - super(context, byteOut, false); - this.byteBuffer = byteOut; - this.pdf = pdf; - this.reference = reference; - this.redundanceTracker = tracker; - } - - private String getReference() { - return reference; - } - - // FIXME: The StemV entry is missing in the FontDescriptor dictionary, but - // it - // does not cause the Acrobat Reader to crash. - protected void openIncludeFont() throws IOException { - super.openIncludeFont(); - - PDFDictionary fontDict = pdf.openDictionary(reference); - - fontDict.entry("Type", pdf.name("Font")); - fontDict.entry("Subtype", pdf.name("Type1")); - fontDict.entry("Name", pdf.name(getFontName())); - - fontDict.entry("FirstChar", 0); - fontDict.entry("LastChar", 255); - // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); - fontDict.entry("Encoding", redundanceTracker.getReference( - getEncodingTable(), PDFCharTableWriter.getInstance())); - - fontDict.entry("Widths", pdf.ref(reference + "Widths")); - - fontDict.entry("BaseFont", pdf.name(getFontName())); // = FontName in - // font program - fontDict.entry("FontDescriptor", - pdf.ref(getReference() + "FontDescriptor")); - - pdf.close(fontDict); - - PDFDictionary fontDescriptor = pdf.openDictionary(getReference() - + "FontDescriptor"); - fontDescriptor.entry("Type", pdf.name("FontDescriptor")); - - LineMetrics metrics = getFont().getLineMetrics("mM", getContext()); - fontDescriptor.entry("Ascent", metrics.getAscent()); - fontDescriptor.entry("Descent", metrics.getDescent()); - fontDescriptor.entry("FontName", pdf.name(getFontName())); - fontDescriptor.entry("Flags", 32); - fontDescriptor.entry("CapHeight", metrics.getAscent()); - fontDescriptor.entry("ItalicAngle", getFont().getItalicAngle()); - // fontDescriptor.entry("StemV", 0); - Rectangle2D boundingBox = getFontBBox(); - double llx = boundingBox.getX(); - double lly = boundingBox.getY(); - double urx = boundingBox.getX() + boundingBox.getWidth(); - double ury = boundingBox.getY() + boundingBox.getHeight(); - fontDescriptor.entry("FontBBox", new double[] { llx, lly, urx, ury }); - - fontDescriptor.entry("FontFile", pdf.ref(getReference() + "FontFile")); - - pdf.close(fontDescriptor); - - } - - protected void writeWidths(double[] widths) throws IOException { - super.writeWidths(widths); - Object[] widthsObj = new Object[256]; - for (int i = 0; i < widthsObj.length; i++) - widthsObj[i] = new Integer((int) Math.round(widths[i])); - pdf.object(reference + "Widths", widthsObj); - } - - // protected void writeEncoding(CharTable charTable) throws IOException { - // super.writeEncoding(charTable); - // FontEmbedderPDF.writeEncoding(pdf, getReference()+"Encoding", charTable); - // } - - protected void openGlyphs() throws IOException { - super.openGlyphs(); - } - - protected void closeEmbedFont() throws IOException { - super.closeEmbedFont(); - - fontFile = pdf.openStream(getReference() + "FontFile", new String[] { - "Flate", "ASCII85" }); - fontFile.entry("Length1", getAsciiLength()); - fontFile.entry("Length2", getEncryptedLength()); - fontFile.entry("Length3", 0); // leave it to the viewer application to - // add the 512 zeros - - String file = byteBuffer.toString("US-ASCII"); - fontFile.print(file); - - pdf.close(fontFile); - } - -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.font.FontRenderContext; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.xmind.org.freehep.graphicsio.font.FontEmbedderType1; + +/** + * Font embedder for type one fonts in pdf documents. + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFFontEmbedderType1 extends FontEmbedderType1 { + + private ByteArrayOutputStream byteBuffer; + + private String reference; + + private PDFWriter pdf; + + private PDFStream fontFile; + + private PDFRedundanceTracker redundanceTracker; + + public static PDFFontEmbedderType1 create(FontRenderContext context, + PDFWriter pdf, String reference, PDFRedundanceTracker tracker) { + return new PDFFontEmbedderType1(context, pdf, reference, + new ByteArrayOutputStream(), tracker); + } + + private PDFFontEmbedderType1(FontRenderContext context, PDFWriter pdf, + String reference, ByteArrayOutputStream byteOut, + PDFRedundanceTracker tracker) { + super(context, byteOut, false); + this.byteBuffer = byteOut; + this.pdf = pdf; + this.reference = reference; + this.redundanceTracker = tracker; + } + + private String getReference() { + return reference; + } + + // FIXME: The StemV entry is missing in the FontDescriptor dictionary, but + // it + // does not cause the Acrobat Reader to crash. + protected void openIncludeFont() throws IOException { + super.openIncludeFont(); + + PDFDictionary fontDict = pdf.openDictionary(reference); + + fontDict.entry("Type", pdf.name("Font")); + fontDict.entry("Subtype", pdf.name("Type1")); + fontDict.entry("Name", pdf.name(getFontName())); + + fontDict.entry("FirstChar", 0); + fontDict.entry("LastChar", 255); + // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); + fontDict.entry("Encoding", redundanceTracker.getReference( + getEncodingTable(), PDFCharTableWriter.getInstance())); + + fontDict.entry("Widths", pdf.ref(reference + "Widths")); + + fontDict.entry("BaseFont", pdf.name(getFontName())); // = FontName in + // font program + fontDict.entry("FontDescriptor", + pdf.ref(getReference() + "FontDescriptor")); + + pdf.close(fontDict); + + PDFDictionary fontDescriptor = pdf.openDictionary(getReference() + + "FontDescriptor"); + fontDescriptor.entry("Type", pdf.name("FontDescriptor")); + + LineMetrics metrics = getFont().getLineMetrics("mM", getContext()); + fontDescriptor.entry("Ascent", metrics.getAscent()); + fontDescriptor.entry("Descent", metrics.getDescent()); + fontDescriptor.entry("FontName", pdf.name(getFontName())); + fontDescriptor.entry("Flags", 32); + fontDescriptor.entry("CapHeight", metrics.getAscent()); + fontDescriptor.entry("ItalicAngle", getFont().getItalicAngle()); + // fontDescriptor.entry("StemV", 0); + Rectangle2D boundingBox = getFontBBox(); + double llx = boundingBox.getX(); + double lly = boundingBox.getY(); + double urx = boundingBox.getX() + boundingBox.getWidth(); + double ury = boundingBox.getY() + boundingBox.getHeight(); + fontDescriptor.entry("FontBBox", new double[] { llx, lly, urx, ury }); + + fontDescriptor.entry("FontFile", pdf.ref(getReference() + "FontFile")); + + pdf.close(fontDescriptor); + + } + + protected void writeWidths(double[] widths) throws IOException { + super.writeWidths(widths); + Object[] widthsObj = new Object[256]; + for (int i = 0; i < widthsObj.length; i++) + widthsObj[i] = new Integer((int) Math.round(widths[i])); + pdf.object(reference + "Widths", widthsObj); + } + + // protected void writeEncoding(CharTable charTable) throws IOException { + // super.writeEncoding(charTable); + // FontEmbedderPDF.writeEncoding(pdf, getReference()+"Encoding", charTable); + // } + + protected void openGlyphs() throws IOException { + super.openGlyphs(); + } + + protected void closeEmbedFont() throws IOException { + super.closeEmbedFont(); + + fontFile = pdf.openStream(getReference() + "FontFile", new String[] { + "Flate", "ASCII85" }); + fontFile.entry("Length1", getAsciiLength()); + fontFile.entry("Length2", getEncryptedLength()); + fontFile.entry("Length3", 0); // leave it to the viewer application to + // add the 512 zeros + + String file = byteBuffer.toString("US-ASCII"); + fontFile.print(file); + + pdf.close(fontFile); + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType3.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType3.java index f0e15d1b2..c9adeb887 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType3.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontEmbedderType3.java @@ -1,87 +1,87 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphMetrics; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -/** - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFFontEmbedderType3 extends PDFFontEmbedder { - - public PDFFontEmbedderType3(FontRenderContext context, PDFWriter pdf, - String reference, PDFRedundanceTracker tracker) { - super(context, pdf, reference, tracker); - } - - protected String getSubtype() { - return "Type3"; - } - - protected void addAdditionalEntries(PDFDictionary fontDict) - throws IOException { - Rectangle2D boundingBox = getFontBBox(); - double llx = boundingBox.getX(); - double lly = boundingBox.getY(); - double urx = boundingBox.getX() + boundingBox.getWidth(); - double ury = boundingBox.getY() + boundingBox.getHeight(); - fontDict.entry("FontBBox", new double[] { llx, lly, urx, ury }); - - fontDict.entry("FontMatrix", new double[] { 1 / FONT_SIZE, 0, 0, - 1 / FONT_SIZE, 0, 0 }); - - fontDict.entry("CharProcs", pdf.ref(getReference() + "CharProcs")); - - PDFDictionary resources = fontDict.openDictionary("Resources"); - resources.entry("ProcSet", new Object[] { pdf.name("PDF") }); - fontDict.close(resources); - } - - protected void addAdditionalInitDicts() throws IOException { - // CharProcs - PDFDictionary charProcs = pdf.openDictionary(getReference() - + "CharProcs"); - // boolean undefined = false; - for (int i = 0; i < 256; i++) { - String charName = getEncodingTable().toName(i); - if (charName != null) { - charProcs.entry(charName, - pdf.ref(createCharacterReference(charName))); - } else { - // undefined = true; - } - } - // if (undefined) - charProcs.entry(NOTDEF, pdf.ref(createCharacterReference(NOTDEF))); - pdf.close(charProcs); - } - - protected void writeGlyph(String characterName, Shape glyph, - GlyphMetrics glyphMetrics) throws IOException { - - PDFStream glyphStream = pdf.openStream( - createCharacterReference(characterName), new String[] { - "Flate", "ASCII85" }); - - Rectangle2D bounds = glyphMetrics != null ? glyphMetrics.getBounds2D() - : glyph.getBounds2D(); - double advance = glyphMetrics != null ? glyphMetrics.getAdvance() - : getUndefinedWidth(); - glyphStream.glyph(advance, 0, bounds.getX(), bounds.getY(), - bounds.getX() + bounds.getWidth(), - bounds.getY() + bounds.getHeight()); - - boolean windingRule = glyphStream.drawPath(glyph); - if (windingRule) { - glyphStream.fillEvenOdd(); - } else { - glyphStream.fill(); - } - pdf.close(glyphStream); - } -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +/** + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFFontEmbedderType3 extends PDFFontEmbedder { + + public PDFFontEmbedderType3(FontRenderContext context, PDFWriter pdf, + String reference, PDFRedundanceTracker tracker) { + super(context, pdf, reference, tracker); + } + + protected String getSubtype() { + return "Type3"; + } + + protected void addAdditionalEntries(PDFDictionary fontDict) + throws IOException { + Rectangle2D boundingBox = getFontBBox(); + double llx = boundingBox.getX(); + double lly = boundingBox.getY(); + double urx = boundingBox.getX() + boundingBox.getWidth(); + double ury = boundingBox.getY() + boundingBox.getHeight(); + fontDict.entry("FontBBox", new double[] { llx, lly, urx, ury }); + + fontDict.entry("FontMatrix", new double[] { 1 / FONT_SIZE, 0, 0, + 1 / FONT_SIZE, 0, 0 }); + + fontDict.entry("CharProcs", pdf.ref(getReference() + "CharProcs")); + + PDFDictionary resources = fontDict.openDictionary("Resources"); + resources.entry("ProcSet", new Object[] { pdf.name("PDF") }); + fontDict.close(resources); + } + + protected void addAdditionalInitDicts() throws IOException { + // CharProcs + PDFDictionary charProcs = pdf.openDictionary(getReference() + + "CharProcs"); + // boolean undefined = false; + for (int i = 0; i < 256; i++) { + String charName = getEncodingTable().toName(i); + if (charName != null) { + charProcs.entry(charName, + pdf.ref(createCharacterReference(charName))); + } else { + // undefined = true; + } + } + // if (undefined) + charProcs.entry(NOTDEF, pdf.ref(createCharacterReference(NOTDEF))); + pdf.close(charProcs); + } + + protected void writeGlyph(String characterName, Shape glyph, + GlyphMetrics glyphMetrics) throws IOException { + + PDFStream glyphStream = pdf.openStream( + createCharacterReference(characterName), new String[] { + "Flate", "ASCII85" }); + + Rectangle2D bounds = glyphMetrics != null ? glyphMetrics.getBounds2D() + : glyph.getBounds2D(); + double advance = glyphMetrics != null ? glyphMetrics.getAdvance() + : getUndefinedWidth(); + glyphStream.glyph(advance, 0, bounds.getX(), bounds.getY(), + bounds.getX() + bounds.getWidth(), + bounds.getY() + bounds.getHeight()); + + boolean windingRule = glyphStream.drawPath(glyph); + if (windingRule) { + glyphStream.fillEvenOdd(); + } else { + glyphStream.fill(); + } + pdf.close(glyphStream); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontIncluder.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontIncluder.java index 5fa640746..dfb785a0a 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontIncluder.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontIncluder.java @@ -1,127 +1,127 @@ -// Copyright 2001-2005 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Font; -import java.awt.font.FontRenderContext; -import java.io.IOException; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.graphicsio.font.FontIncluder; - -/** - * Includes one of the 14 Type1 fonts in PDF documents - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFFontIncluder extends FontIncluder { - - private static final int PLAIN = 0; - - private static final int BOLD = 1; - - private static final int ITALIC = 2; - - private static final int BOLDITALIC = 3; - - private static final int COURIER = 0; - - private static final int HELVETICA = 1; - - private static final int TIMES = 2; - - private static final int SYMBOL = 3; - - private static final int DINGBATS = 4; - - private static final String[][] STANDARD_FONT = { - { "Courier", "Courier-Bold", "Courier-Oblique", - "Courier-BoldOblique" }, - { "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", - "Helvetica-BoldOblique" }, - { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic" }, - { "Symbol" }, { "ZapfDingbats" } }; - - private PDFWriter pdf; - - private String reference; - - private PDFRedundanceTracker redundanceTracker; - - public PDFFontIncluder(FontRenderContext context, PDFWriter pdf, - String reference, PDFRedundanceTracker redundanceTracker) { - super(context); - this.pdf = pdf; - this.reference = reference; - this.redundanceTracker = redundanceTracker; - } - - protected void openIncludeFont() throws IOException { - - int style = getFontStyle(getFont()); - int fontBaseIndex = getFontBaseIndex(getFont()); - - PDFDictionary font = pdf.openDictionary(reference); - font.entry("Type", pdf.name("Font")); - font.entry("Subtype", pdf.name("Type1")); - font.entry("Name", pdf.name(reference)); - font.entry("BaseFont", pdf.name(STANDARD_FONT[fontBaseIndex][style])); - // font.entry("Encoding", pdf.ref(reference+"Encoding")); - font.entry("Encoding", redundanceTracker.getReference( - getEncodingTable(), PDFCharTableWriter.getInstance())); - pdf.close(font); - } - - protected void writeEncoding(CharTable charTable) throws IOException { - } - - public static boolean isStandardFont(Font font) { - String fontName = font.getName().toLowerCase(); - return (fontName.indexOf("helvetica") >= 0) - || (fontName.indexOf("times") >= 0) - || (fontName.indexOf("courier") >= 0) - || (fontName.indexOf("symbol") >= 0) - || (fontName.indexOf("dingbats") >= 0); - } - - /** Returns the index of the standard font according to STANDARD_FONT. */ - private static int getFontBaseIndex(Font font) { - String fontName = font.getName().toLowerCase(); - if (fontName.indexOf("helvetica") >= 0) { - return HELVETICA; - } else if (fontName.indexOf("times") >= 0) { - return TIMES; - } else if (fontName.indexOf("courier") >= 0) { - return COURIER; - } else if (fontName.indexOf("symbol") >= 0) { - return SYMBOL; - } else if (fontName.indexOf("dingbats") >= 0) { - return DINGBATS; - } else { - // use HELVETICA as default - return HELVETICA; - } - } - - /** Returns the index of the respective entry in STANDARD_FONT[fontIndex]. */ - private static int getFontStyle(Font font) { - int fontBase = getFontBaseIndex(font); - if ((fontBase >= 0) && (STANDARD_FONT[fontBase].length == 1)) - return PLAIN; - if (fontBase < 0) - return -1; - if (font.isBold()) { - if (font.isItalic()) { - return BOLDITALIC; - } else { - return BOLD; - } - } else { - if (font.isItalic()) - return ITALIC; - } - return PLAIN; - } - -} +// Copyright 2001-2005 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Font; +import java.awt.font.FontRenderContext; +import java.io.IOException; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.graphicsio.font.FontIncluder; + +/** + * Includes one of the 14 Type1 fonts in PDF documents + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFFontIncluder extends FontIncluder { + + private static final int PLAIN = 0; + + private static final int BOLD = 1; + + private static final int ITALIC = 2; + + private static final int BOLDITALIC = 3; + + private static final int COURIER = 0; + + private static final int HELVETICA = 1; + + private static final int TIMES = 2; + + private static final int SYMBOL = 3; + + private static final int DINGBATS = 4; + + private static final String[][] STANDARD_FONT = { + { "Courier", "Courier-Bold", "Courier-Oblique", + "Courier-BoldOblique" }, + { "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", + "Helvetica-BoldOblique" }, + { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic" }, + { "Symbol" }, { "ZapfDingbats" } }; + + private PDFWriter pdf; + + private String reference; + + private PDFRedundanceTracker redundanceTracker; + + public PDFFontIncluder(FontRenderContext context, PDFWriter pdf, + String reference, PDFRedundanceTracker redundanceTracker) { + super(context); + this.pdf = pdf; + this.reference = reference; + this.redundanceTracker = redundanceTracker; + } + + protected void openIncludeFont() throws IOException { + + int style = getFontStyle(getFont()); + int fontBaseIndex = getFontBaseIndex(getFont()); + + PDFDictionary font = pdf.openDictionary(reference); + font.entry("Type", pdf.name("Font")); + font.entry("Subtype", pdf.name("Type1")); + font.entry("Name", pdf.name(reference)); + font.entry("BaseFont", pdf.name(STANDARD_FONT[fontBaseIndex][style])); + // font.entry("Encoding", pdf.ref(reference+"Encoding")); + font.entry("Encoding", redundanceTracker.getReference( + getEncodingTable(), PDFCharTableWriter.getInstance())); + pdf.close(font); + } + + protected void writeEncoding(CharTable charTable) throws IOException { + } + + public static boolean isStandardFont(Font font) { + String fontName = font.getName().toLowerCase(); + return (fontName.indexOf("helvetica") >= 0) + || (fontName.indexOf("times") >= 0) + || (fontName.indexOf("courier") >= 0) + || (fontName.indexOf("symbol") >= 0) + || (fontName.indexOf("dingbats") >= 0); + } + + /** Returns the index of the standard font according to STANDARD_FONT. */ + private static int getFontBaseIndex(Font font) { + String fontName = font.getName().toLowerCase(); + if (fontName.indexOf("helvetica") >= 0) { + return HELVETICA; + } else if (fontName.indexOf("times") >= 0) { + return TIMES; + } else if (fontName.indexOf("courier") >= 0) { + return COURIER; + } else if (fontName.indexOf("symbol") >= 0) { + return SYMBOL; + } else if (fontName.indexOf("dingbats") >= 0) { + return DINGBATS; + } else { + // use HELVETICA as default + return HELVETICA; + } + } + + /** Returns the index of the respective entry in STANDARD_FONT[fontIndex]. */ + private static int getFontStyle(Font font) { + int fontBase = getFontBaseIndex(font); + if ((fontBase >= 0) && (STANDARD_FONT[fontBase].length == 1)) + return PLAIN; + if (fontBase < 0) + return -1; + if (font.isBold()) { + if (font.isItalic()) { + return BOLDITALIC; + } else { + return BOLD; + } + } else { + if (font.isItalic()) + return ITALIC; + } + return PLAIN; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontTable.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontTable.java index a0320c779..0bfb04c40 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontTable.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFFontTable.java @@ -1,125 +1,125 @@ -// Copyright 2001-2003, FreeHEP. -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Font; -import java.awt.font.FontRenderContext; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; -import java.util.Properties; - -import org.xmind.org.freehep.graphics2d.font.CharTable; -import org.xmind.org.freehep.graphics2d.font.Lookup; -import org.xmind.org.freehep.graphicsio.FontConstants; -import org.xmind.org.freehep.graphicsio.font.FontIncluder; -import org.xmind.org.freehep.graphicsio.font.FontTable; - -/** - * A table to remember which fonts were used while writing a pdf document. - * Entries to resource dictionaries and embedding of fonts can be done when the - * drawing is finished by calling addAll(). - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFFontTable extends FontTable { - - private int currentFontIndex = 1; - - private PDFWriter pdf; - - private PDFRedundanceTracker tracker; - - public PDFFontTable(PDFWriter pdf) { - super(); - this.pdf = pdf; - this.tracker = new PDFRedundanceTracker(pdf); - } - - /** Adds all fonts to a dictionary named "FontList". */ - public int addFontDictionary() throws IOException { - Collection fonts = getEntries(); - if (fonts.size() > 0) { - PDFDictionary fontList = pdf.openDictionary("FontList"); - for (Iterator i = fonts.iterator(); i.hasNext();) { - Entry e = (Entry) i.next(); - fontList.entry(e.getReference(), pdf.ref(e.getReference())); - } - pdf.close(fontList); - } - return fonts.size(); - } - - /** Embeds all not yet embedded fonts to the file. */ - public void embedAll(FontRenderContext context, boolean embed, - String embedAs) throws IOException { - Collection col = getEntries(); - Iterator i = col.iterator(); - while (i.hasNext()) { - Entry e = (Entry) i.next(); - if (!e.isWritten()) { - e.setWritten(true); - - FontIncluder fontIncluder = null; - if (PDFFontIncluder.isStandardFont(e.getFont())) { - embed = false; - } - - if (embed) { - if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE3)) { - fontIncluder = new PDFFontEmbedderType3(context, pdf, - e.getReference(), tracker); - } else if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE1)) { - fontIncluder = PDFFontEmbedderType1.create(context, - pdf, e.getReference(), tracker); - } else { - System.out - .println("PDFFontTable: invalid value for embedAs: " - + embedAs); - } - } else { - fontIncluder = new PDFFontIncluder(context, pdf, - e.getReference(), tracker); - } - fontIncluder.includeFont(e.getFont(), e.getEncoding(), - e.getReference()); - } - } - tracker.writeAll(); - } - - public CharTable getEncodingTable() { - return Lookup.getInstance().getTable("PDFLatin"); - } - - public void firstRequest(Entry e, boolean embed, String embedAs) { - } - - private static final Properties replaceFonts = new Properties(); - static { - replaceFonts.setProperty("Dialog", "Helvetica"); - replaceFonts.setProperty("DialogInput", "Courier"); - replaceFonts.setProperty("Serif", "TimesRoman"); - replaceFonts.setProperty("SansSerif", "Helvetica"); - replaceFonts.setProperty("Monospaced", "Courier"); - } - - protected Font substituteFont(Font font) { - String fontName = replaceFonts.getProperty(font.getName(), null); - if (fontName != null) { - Font newFont = new Font(fontName, font.getSize(), font.getStyle()); - font = newFont.deriveFont(font.getSize2D()); - } - return font; - } - - /** - * Creates the reference by numbering them. - * - * @return "F"+currentFontIndex - */ - protected String createFontReference(Font f) { - return "F" + (currentFontIndex++); - } -} +// Copyright 2001-2003, FreeHEP. +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Font; +import java.awt.font.FontRenderContext; +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import java.util.Properties; + +import org.xmind.org.freehep.graphics2d.font.CharTable; +import org.xmind.org.freehep.graphics2d.font.Lookup; +import org.xmind.org.freehep.graphicsio.FontConstants; +import org.xmind.org.freehep.graphicsio.font.FontIncluder; +import org.xmind.org.freehep.graphicsio.font.FontTable; + +/** + * A table to remember which fonts were used while writing a pdf document. + * Entries to resource dictionaries and embedding of fonts can be done when the + * drawing is finished by calling addAll(). + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFFontTable extends FontTable { + + private int currentFontIndex = 1; + + private PDFWriter pdf; + + private PDFRedundanceTracker tracker; + + public PDFFontTable(PDFWriter pdf) { + super(); + this.pdf = pdf; + this.tracker = new PDFRedundanceTracker(pdf); + } + + /** Adds all fonts to a dictionary named "FontList". */ + public int addFontDictionary() throws IOException { + Collection fonts = getEntries(); + if (fonts.size() > 0) { + PDFDictionary fontList = pdf.openDictionary("FontList"); + for (Iterator i = fonts.iterator(); i.hasNext();) { + Entry e = (Entry) i.next(); + fontList.entry(e.getReference(), pdf.ref(e.getReference())); + } + pdf.close(fontList); + } + return fonts.size(); + } + + /** Embeds all not yet embedded fonts to the file. */ + public void embedAll(FontRenderContext context, boolean embed, + String embedAs) throws IOException { + Collection col = getEntries(); + Iterator i = col.iterator(); + while (i.hasNext()) { + Entry e = (Entry) i.next(); + if (!e.isWritten()) { + e.setWritten(true); + + FontIncluder fontIncluder = null; + if (PDFFontIncluder.isStandardFont(e.getFont())) { + embed = false; + } + + if (embed) { + if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE3)) { + fontIncluder = new PDFFontEmbedderType3(context, pdf, + e.getReference(), tracker); + } else if (embedAs.equals(FontConstants.EMBED_FONTS_TYPE1)) { + fontIncluder = PDFFontEmbedderType1.create(context, + pdf, e.getReference(), tracker); + } else { + System.out + .println("PDFFontTable: invalid value for embedAs: " + + embedAs); + } + } else { + fontIncluder = new PDFFontIncluder(context, pdf, + e.getReference(), tracker); + } + fontIncluder.includeFont(e.getFont(), e.getEncoding(), + e.getReference()); + } + } + tracker.writeAll(); + } + + public CharTable getEncodingTable() { + return Lookup.getInstance().getTable("PDFLatin"); + } + + public void firstRequest(Entry e, boolean embed, String embedAs) { + } + + private static final Properties replaceFonts = new Properties(); + static { + replaceFonts.setProperty("Dialog", "Helvetica"); + replaceFonts.setProperty("DialogInput", "Courier"); + replaceFonts.setProperty("Serif", "TimesRoman"); + replaceFonts.setProperty("SansSerif", "Helvetica"); + replaceFonts.setProperty("Monospaced", "Courier"); + } + + protected Font substituteFont(Font font) { + String fontName = replaceFonts.getProperty(font.getName(), null); + if (fontName != null) { + Font newFont = new Font(fontName, font.getSize(), font.getStyle()); + font = newFont.deriveFont(font.getSize2D()); + } + return font; + } + + /** + * Creates the reference by numbering them. + * + * @return "F"+currentFontIndex + */ + protected String createFontReference(Font f) { + return "F" + (currentFontIndex++); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFGraphics2D.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFGraphics2D.java index 621af0862..63b9113ac 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFGraphics2D.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFGraphics2D.java @@ -1,960 +1,960 @@ -// Copyright 2000-2007, FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GradientPaint; -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.Insets; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.TexturePaint; -import java.awt.font.LineMetrics; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.RenderedImage; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.xmind.org.freehep.graphics2d.TagString; -import org.xmind.org.freehep.graphics2d.font.FontUtilities; -import org.xmind.org.freehep.graphics2d.font.Lookup; -import org.xmind.org.freehep.graphicsio.AbstractVectorGraphicsIO; -import org.xmind.org.freehep.graphicsio.FontConstants; -import org.xmind.org.freehep.graphicsio.ImageConstants; -import org.xmind.org.freehep.graphicsio.InfoConstants; -import org.xmind.org.freehep.graphicsio.MultiPageDocument; -import org.xmind.org.freehep.graphicsio.PageConstants; -import org.xmind.org.freehep.util.UserProperties; - -/** - * Implementation of VectorGraphics that writes the output to a PDF - * file. Users of this class have to generate a PDFWriter and create an - * instance by invoking the factory method or the constructor. Document specific - * settings like page size can then be made by the appropriate setter methods. - * Before starting to draw, startExport() must be called. When drawing - * is finished, call endExport(). - * - * @author Simon Fischer - * @author Mark Donszelmann - * @author Jason Wong - */ - -@SuppressWarnings("nls") -public class PDFGraphics2D extends AbstractVectorGraphicsIO implements - MultiPageDocument, FontUtilities.ShowString { - - private static final String ROOT_KEY = PDFGraphics2D.class.getName(); - - public static final String VERSION6 = "Acrobat Reader 6.x"; - - public static final String VERSION5 = "Acrobat Reader 5.x"; - - public static final String VERSION4 = "Acrobat Reader 4.x"; - - public static final String TRANSPARENT = ROOT_KEY + "." - + PageConstants.TRANSPARENT; - - public static final String BACKGROUND = ROOT_KEY + "." - + PageConstants.BACKGROUND; - - public static final String BACKGROUND_COLOR = ROOT_KEY + "." - + PageConstants.BACKGROUND_COLOR; - - public static final String PAGE_SIZE = ROOT_KEY + "." - + PageConstants.PAGE_SIZE; - - public static final String PAGE_MARGINS = ROOT_KEY + "." - + PageConstants.PAGE_MARGINS; - - public static final String FIT_TO_PAGE = ROOT_KEY + "." - + PageConstants.FIT_TO_PAGE; - - public static final String EMBED_FONTS = ROOT_KEY + "." - + FontConstants.EMBED_FONTS; - - public static final String EMBED_FONTS_AS = ROOT_KEY + "." - + FontConstants.EMBED_FONTS_AS; - - public static final String THUMBNAILS = ROOT_KEY + ".Thumbnails"; - - public static final String COMPRESS = ROOT_KEY + ".Compress"; - - public static final String VERSION = ROOT_KEY + ".Version"; - - public static final String WRITE_IMAGES_AS = ROOT_KEY + "." - + ImageConstants.WRITE_IMAGES_AS; - - public static final String AUTHOR = ROOT_KEY + "." + InfoConstants.AUTHOR; - - public static final String TITLE = ROOT_KEY + "." + InfoConstants.TITLE; - - public static final String SUBJECT = ROOT_KEY + "." + InfoConstants.SUBJECT; - - public static final String KEYWORDS = ROOT_KEY + "." - + InfoConstants.KEYWORDS; - - private static final UserProperties defaultProperties = new UserProperties(); - static { - defaultProperties.setProperty(TRANSPARENT, true); - defaultProperties.setProperty(BACKGROUND, false); - defaultProperties.setProperty(BACKGROUND_COLOR, Color.RED); - - defaultProperties.setProperty(VERSION, VERSION5); - defaultProperties.setProperty(COMPRESS, false); - defaultProperties.setProperty(PAGE_SIZE, new Dimension(595, 842)); - defaultProperties.setProperty(PAGE_MARGINS, new Insets(20, 20, 20, 20)); - - defaultProperties.setProperty(FIT_TO_PAGE, true); - defaultProperties.setProperty(EMBED_FONTS, false); - defaultProperties.setProperty(EMBED_FONTS_AS, - FontConstants.EMBED_FONTS_TYPE3); - defaultProperties.setProperty(THUMBNAILS, defaultProperties - .getProperty(VERSION).equals(VERSION4)); - defaultProperties.setProperty(WRITE_IMAGES_AS, ImageConstants.SMALLEST); - - defaultProperties.setProperty(AUTHOR, ""); - defaultProperties.setProperty(TITLE, ""); - defaultProperties.setProperty(SUBJECT, ""); - defaultProperties.setProperty(KEYWORDS, ""); - - defaultProperties.setProperty(CLIP, true); - defaultProperties.setProperty(TEXT_AS_SHAPES, true); - } - - public static Properties getDefaultProperties() { - return defaultProperties; - } - - public static void setDefaultProperties(Properties newProperties) { - defaultProperties.setProperties(newProperties); - } - - public static final String version = "$Revision$"; - - private static final String PDF_VERSION = "1.4"; - - private static final String[] COMPRESS_FILTERS = { - ImageConstants.ENCODING_FLATE, ImageConstants.ENCODING_ASCII85 }; - - private static final String[] NO_FILTERS = {}; - - private static final double FONTSIZE_CORRECTION = 1.0; - - /* - * Not Used private static final CharTable STANDARD_CHAR_TABLES[] = { - * Lookup.getInstance().getTable("PDFLatin"), - * Lookup.getInstance().getTable("Symbol"), - * Lookup.getInstance().getTable("Zapfdingbats") }; - * - * private static final Font STANDARD_FONT[] = { null, new Font("Symbol", - * Font.PLAIN, 10), new Font("ZapfDingbats", Font.PLAIN, 10), }; - */ - - private OutputStream ros; - - private PDFWriter os; - - private PDFStream pageStream; - - // Remember some things to do - private PDFFontTable fontTable; // Remember which standard fonts were used - - private PDFImageDelayQueue delayImageQueue; // Remember images XObjects to - - // include in the file - - private PDFPaintDelayQueue delayPaintQueue; // Remember patterns to include - - // in the file - - // multipage - private int currentPage; - - private boolean multiPage; - - private TagString[] headerText; - - private int headerUnderline; - - private Font headerFont; - - private TagString[] footerText; - - private int footerUnderline; - - private Font footerFont; - - private List titles; - - // extra pointers - int alphaIndex; - - Map extGStates; - - // Other - private String producer; - - /* - * ======================================================================== - * 1. Constructors & Factory Methods - * ======================================================================== - */ - - public PDFGraphics2D(File file, Dimension size) - throws FileNotFoundException { - this(new FileOutputStream(file), size); - } - - public PDFGraphics2D(OutputStream ros, Dimension size) { - super(size, false); - init(ros); - } - - private void init(OutputStream ros) { - this.ros = new BufferedOutputStream(ros); - - currentPage = 0; - multiPage = false; - titles = new ArrayList(); - initProperties(defaultProperties); - } - - /** Clone constructor */ - protected PDFGraphics2D(PDFGraphics2D graphics, boolean doRestoreOnDispose) { - super(graphics, doRestoreOnDispose); - - this.os = graphics.os; - this.pageStream = graphics.pageStream; - - this.delayImageQueue = graphics.delayImageQueue; - this.delayPaintQueue = graphics.delayPaintQueue; - this.fontTable = graphics.fontTable; - - this.currentPage = graphics.currentPage; - this.multiPage = graphics.multiPage; - this.titles = graphics.titles; - - this.alphaIndex = graphics.alphaIndex; - this.extGStates = graphics.extGStates; - } - - /* - * ======================================================================== - * 2. Document Settings - * ======================================================================== - */ - - private void setProperty(String key, Dimension value) { - UserProperties properties = (UserProperties) getProperties(); - properties.setProperty(key, value); - } - - private void setProperty(String key, Insets value) { - UserProperties properties = (UserProperties) getProperties(); - properties.setProperty(key, value); - } - - public void setMultiPage(boolean multiPage) { - this.multiPage = multiPage; - } - - public boolean isMultiPage() { - return multiPage; - } - - public void setPageSize(Dimension size) { - setProperty(PAGE_SIZE, size); - } - - public void setMargin(Insets margins) { - setProperty(PAGE_MARGINS, margins); - } - - public void setProducer(String producer) { - this.producer = producer; - } - - /** - * Set the clipping enabled flag. This will affect all output operations - * after this call completes. In some circumstances the clipping region is - * set incorrectly (not yet understood; AWT seems to not correctly dispose - * of graphic contexts). A workaround is to simply switch it off. - */ - public static void setClipEnabled(boolean enabled) { - defaultProperties.setProperty(CLIP, enabled); - } - - /* - * ======================================================================== - * 3. Header, Trailer, Multipage & Comments - * ======================================================================== - */ - /* 3.1 Header & Trailer */ - - /** - * Writes the catalog, docinfo, preferences, and (as we use only single page - * output the page tree. - */ - @Override - public void writeHeader() throws IOException { - os = new PDFWriter(new BufferedOutputStream(ros), PDF_VERSION); - - delayImageQueue = new PDFImageDelayQueue(os); - delayPaintQueue = new PDFPaintDelayQueue(os, delayImageQueue); - - fontTable = new PDFFontTable(os); - - PDFDocInfo info = os.openDocInfo("DocInfo"); - info.setTitle(getProperty(TITLE)); - info.setAuthor(getProperty(AUTHOR)); - info.setSubject(getProperty(SUBJECT)); - info.setKeywords(getProperty(KEYWORDS)); - - info.setCreator(getCreator()); - info.setProducer(producer == null ? "" : producer); - if (!isDeviceIndependent()) { - Calendar now = Calendar.getInstance(); - info.setCreationDate(now); - info.setModificationDate(now); - } - info.setTrapped("False"); - os.close(info); - - // catalog - PDFCatalog catalog = os.openCatalog("Catalog", "RootPage"); - catalog.setOutlines("Outlines"); - catalog.setPageMode("UseOutlines"); - catalog.setViewerPreferences("Preferences"); - catalog.setOpenAction(new Object[] { os.ref("Page1"), os.name("Fit") }); - os.close(catalog); - - // preferences - PDFViewerPreferences prefs = os.openViewerPreferences("Preferences"); - prefs.setFitWindow(true); - prefs.setCenterWindow(false); - os.close(prefs); - - // extra stuff - alphaIndex = 1; - extGStates = new HashMap(); - - // hide the multipage functionality to the user in case of single page - // output by opening the first and only page immediately - if (!isMultiPage()) { - openPage(getSize(), null); - } - } - - public void writeBackground() { - if (isProperty(TRANSPARENT)) { - setBackground(null); - } else if (isProperty(BACKGROUND)) { - setBackground(getPropertyColor(BACKGROUND_COLOR)); - clearRect(0.0, 0.0, getSize().width, getSize().height); - } else { - setBackground(Color.WHITE); - clearRect(0.0, 0.0, getSize().width, getSize().height); - } - } - - public void writeTrailer() throws IOException { - if (!isMultiPage()) - closePage(); - - // pages - PDFPageTree pages = os.openPageTree("RootPage", null); - for (int i = 1; i <= currentPage; i++) { - pages.addPage("Page" + i); - } - - Dimension pageSize = getPropertyDimension(PAGE_SIZE); - pages.setMediaBox(0, 0, pageSize.getWidth(), pageSize.getHeight()); - pages.setResources("Resources"); - os.close(pages); - - // ProcSet - os.object("PageProcSet", new Object[] { os.name("PDF"), - os.name("Text"), os.name("ImageC") }); - - // Font - int nFonts = fontTable.addFontDictionary(); - - // XObject - int nXObjects = delayImageQueue.addXObjects(); - - // Pattern - int nPatterns = delayPaintQueue.addPatterns(); - - // ExtGState - if (extGStates.size() > 0) { - PDFDictionary extGState = os.openDictionary("ExtGState"); - - for (Iterator i = extGStates.keySet().iterator(); i - .hasNext();) { - Float alpha = (Float) i.next(); - String alphaName = (String) extGStates.get(alpha); - PDFDictionary alphaDictionary = extGState - .openDictionary(alphaName); - alphaDictionary.entry("ca", alpha.floatValue()); - alphaDictionary.entry("CA", alpha.floatValue()); - alphaDictionary.entry("BM", os.name("Normal")); - alphaDictionary.entry("AIS", false); - extGState.close(alphaDictionary); - } - os.close(extGState); - } - - // resources - PDFDictionary resources = os.openDictionary("Resources"); - resources.entry("ProcSet", os.ref("PageProcSet")); - if (nFonts > 0) - resources.entry("Font", os.ref("FontList")); - if (nXObjects > 0) - resources.entry("XObject", os.ref("XObjects")); - if (nPatterns > 0) - resources.entry("Pattern", os.ref("Pattern")); - if (extGStates.size() > 0) - resources.entry("ExtGState", os.ref("ExtGState")); - os.close(resources); - - // outlines - PDFOutlineList outlines = os.openOutlineList("Outlines", "Outline1", - "Outline" + currentPage); - os.close(outlines); - - for (int i = 1; i <= currentPage; i++) { - String prev = i > 1 ? "Outline" + (i - 1) : null; - String next = i < currentPage ? "Outline" + (i + 1) : null; - PDFOutline outline = os.openOutline("Outline" + i, - (String) titles.get(i - 1), "Outlines", prev, next); - outline.setDest(new Object[] { os.ref("Page" + i), os.name("Fit") }); - os.close(outline); - } - - // delayed objects (images, patterns, fonts) - processDelayed(); - } - - public void closeStream() throws IOException { - os.close(); - } - - private void processDelayed() throws IOException { - delayImageQueue.processAll(); - delayPaintQueue.processAll(); - fontTable.embedAll(getFontRenderContext(), isProperty(EMBED_FONTS), - getProperty(EMBED_FONTS_AS)); - } - - /* 3.2 MultipageDocument methods */ - public void openPage(Dimension size, String title) throws IOException { - resetClip(new Rectangle(0, 0, size.width, size.height)); - - if (pageStream != null) { - writeWarning("Page " + currentPage + " already open. " - + "Call closePage() before starting a new one."); - return; - } - - // BufferedImage thumbnail = null; - // prepare thumbnail if possible - // if ((component != null) && isProperty(PDFGraphics2D.THUMBNAILS)) { - // thumbnail = ImageGraphics2D.generateThumbnail(component, - // getPropertyDimension(PDFGraphics2D.THUMBNAIL_SIZE)); - // } - - currentPage++; - - if (title == null) - title = "Page " + currentPage + " (untitled)"; - titles.add(title); - - PDFPage page = os.openPage("Page" + currentPage, "RootPage"); - page.setContents("PageContents" + currentPage); - - // if (thumbnail != null) - // page.setThumb("Thumb" + currentPage); - - os.close(page); - - // if (thumbnail != null) { - // PDFStream thumbnailStream = os.openStream("Thumb" + currentPage); - // thumbnailStream.image(thumbnail, Color.black, ImageConstants.ZLIB); - // os.close(thumbnailStream); - // } - - pageStream = os.openStream("PageContents" + currentPage, - isProperty(COMPRESS) ? COMPRESS_FILTERS : NO_FILTERS); - - // transform the coordinate system as necessary - // 1. flip the coordinate system down and translate it upwards again - // so that the origin is the upper left corner of the page. - AffineTransform pageTrafo = new AffineTransform(); - pageTrafo.scale(1, -1); - Dimension pageSize = getPropertyDimension(PAGE_SIZE); - Insets margins = getPropertyInsets(PAGE_MARGINS); - pageTrafo - .translate(margins.left, -(pageSize.getHeight() - margins.top)); - - // in between write the header and footer (which should not be scaled!) - writeHeadline(pageTrafo); - writeFootline(pageTrafo); - - // 2. check whether we have to rescale the image to fit onto the page - double scaleFactor = Math.min(getWidth() / size.width, getHeight() - / size.height); - if ((scaleFactor < 1) || isProperty(FIT_TO_PAGE)) { - pageTrafo.scale(scaleFactor, scaleFactor); - } else { - scaleFactor = 1; - } - - // 3. center the image on the page - double dx = (getWidth() - size.width * scaleFactor) / 2 / scaleFactor; - double dy = (getHeight() - size.height * scaleFactor) / 2 / scaleFactor; - pageTrafo.translate(dx, dy); - - writeTransform(pageTrafo); - - // save the graphics context resets before setClip - writeGraphicsSave(); - - clipRect(0, 0, size.width, size.height); - - // save the graphics context resets before setClip - writeGraphicsSave(); - - delayPaintQueue.setPageMatrix(pageTrafo); - - writeGraphicsState(); - writeBackground(); - } - - public void closePage() throws IOException { - if (pageStream == null) { - writeWarning("Page " + currentPage + " already closed. " - + "Call openPage() to start a new one."); - return; - } - writeGraphicsRestore(); - writeGraphicsRestore(); - os.close(pageStream); - pageStream = null; - - processDelayed(); // This does not work properly with acrobat reader 4! - } - - public void setHeader(Font font, TagString left, TagString center, - TagString right, int underlineThickness) { - this.headerFont = font; - this.headerText = new TagString[3]; - this.headerText[0] = left; - this.headerText[1] = center; - this.headerText[2] = right; - this.headerUnderline = underlineThickness; - } - - public void setFooter(Font font, TagString left, TagString center, - TagString right, int underlineThickness) { - this.footerFont = font; - this.footerText = new TagString[3]; - this.footerText[0] = left; - this.footerText[1] = center; - this.footerText[2] = right; - this.footerUnderline = underlineThickness; - } - - private void writeHeadline(AffineTransform pageTrafo) throws IOException { - if (headerText != null) { - LineMetrics metrics = headerFont.getLineMetrics("mM", - getFontRenderContext()); - writeLine(pageTrafo, headerFont, headerText, -metrics.getLeading() - - headerFont.getSize2D() / 2, TEXT_BOTTOM, - -headerFont.getSize2D() / 2, headerUnderline); - } - } - - private void writeFootline(AffineTransform pageTrafo) throws IOException { - if (footerText != null) { - LineMetrics metrics = footerFont.getLineMetrics("mM", - getFontRenderContext()); - double y = getHeight() + footerFont.getSize2D() / 2; - writeLine(pageTrafo, footerFont, footerText, - y + metrics.getLeading(), TEXT_TOP, y, footerUnderline); - } - } - - private void writeLine(AffineTransform trafo, Font font, TagString[] text, - double ty, int yAlign, double ly, int underline) throws IOException { - writeGraphicsSave(); - setColor(Color.black); - setFont(font); - writeTransform(trafo); - if (text[0] != null) - drawString(text[0], 0, ty, TEXT_LEFT, yAlign); - if (text[1] != null) - drawString(text[1], getWidth() / 2, ty, TEXT_CENTER, yAlign); - if (text[2] != null) - drawString(text[2], getWidth(), ty, TEXT_RIGHT, yAlign); - if (underline >= 0) { - setLineWidth((double) underline); - drawLine(0, ly, getWidth(), ly); - } - writeGraphicsRestore(); - } - - /* - * ======================================================================== - * 4. Create & Dispose - * ======================================================================== - */ - - @Override - public Graphics create() { - try { - writeGraphicsSave(); - } catch (IOException e) { - handleException(e); - } - return new PDFGraphics2D(this, true); - } - - public Graphics create(double x, double y, double width, double height) { - try { - writeGraphicsSave(); - } catch (IOException e) { - handleException(e); - } - PDFGraphics2D graphics = new PDFGraphics2D(this, true); - graphics.translate(x, y); - graphics.clipRect(0, 0, width, height); - return graphics; - } - - protected void writeGraphicsSave() throws IOException { - pageStream.save(); - } - - protected void writeGraphicsRestore() throws IOException { - pageStream.restore(); - } - - /* - * ======================================================================== - * 5. Drawing Methods - * ======================================================================== - */ - public void draw(Shape s) { - try { - if (getStroke() instanceof BasicStroke) { - // in this case we've already handled the stroke - pageStream.drawPath(s); - pageStream.stroke(); - } else { - // otherwise handle it now - pageStream.drawPath(getStroke().createStrokedShape(s)); - pageStream.fill(); - } - } catch (IOException e) { - handleException(e); - } - } - - public void fill(Shape s) { - try { - boolean eofill = pageStream.drawPath(s); - if (eofill) { - pageStream.fillEvenOdd(); - } else { - pageStream.fill(); - } - } catch (IOException e) { - handleException(e); - } - } - - /* 5.2 Images */ - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - writeWarning(getClass() - + ": copyArea(int, int, int, int, int, int) not implemented."); - } - - protected void writeImage(RenderedImage image, AffineTransform xform, - Color bkg) throws IOException { - PDFName ref = delayImageQueue.delayImage(image, bkg, - getProperty(WRITE_IMAGES_AS)); - - AffineTransform imageTransform = new AffineTransform(image.getWidth(), - 0.0, 0.0, -image.getHeight(), 0.0, image.getHeight()); - xform.concatenate(imageTransform); - - writeGraphicsSave(); - pageStream.matrix(xform); - pageStream.xObject(ref); - writeGraphicsRestore(); - } - - /* 5.3. Strings */ - protected void writeString(String str, double x, double y) - throws IOException { - // save the graphics context, especially the transformation matrix - writeGraphicsSave(); - - // translate the offset to x and y - AffineTransform at = new AffineTransform(1, 0, 0, 1, x, y); - // transform for font - at.concatenate(getFont().getTransform()); - // mirror the matrix - at.scale(1, -1); - - // write transform - writeTransform(at); - - pageStream.beginText(); - pageStream.text(0, 0); - showCharacterCodes(str); - pageStream.endText(); - - // restore the transformation matrix - writeGraphicsRestore(); - } - - /* - * ======================================================================== - * 6. Transformations - * ======================================================================== - */ - /** Write the given transformation matrix to the file. */ - protected void writeTransform(AffineTransform t) throws IOException { - pageStream.matrix(t); - } - - /* - * ======================================================================== - * 7. Clipping - * ======================================================================== - */ - protected void writeSetClip(Shape s) throws IOException { - // clear old clip - try { - AffineTransform at = getTransform(); - Stroke stroke = getStroke(); - - writeGraphicsRestore(); - writeGraphicsSave(); - - writeStroke(stroke); - writeTransform(at); - } catch (IOException e) { - handleException(e); - } - - // write clip - writeClip(s); - } - - protected void writeClip(Shape s) throws IOException { - if (s == null || !isProperty(CLIP)) { - return; - } - - if (s instanceof Rectangle2D) { - pageStream.move(((Rectangle2D) s).getMinX(), - ((Rectangle2D) s).getMinY()); - pageStream.line(((Rectangle2D) s).getMaxX(), - ((Rectangle2D) s).getMinY()); - pageStream.line(((Rectangle2D) s).getMaxX(), - ((Rectangle2D) s).getMaxY()); - pageStream.line(((Rectangle2D) s).getMinX(), - ((Rectangle2D) s).getMaxY()); - pageStream.closePath(); - pageStream.clip(); - pageStream.endPath(); - } else { - boolean eoclip = pageStream.drawPath(s); - if (eoclip) { - pageStream.clipEvenOdd(); - } else { - pageStream.clip(); - } - - pageStream.endPath(); - } - } - - /* - * ======================================================================== - * 8. Graphics State - * ======================================================================== - */ - /* 8.1. stroke/linewidth */ - protected void writeWidth(float width) throws IOException { - pageStream.width(width); - } - - protected void writeCap(int cap) throws IOException { - switch (cap) { - default: - case BasicStroke.CAP_BUTT: - pageStream.cap(0); - break; - case BasicStroke.CAP_ROUND: - pageStream.cap(1); - break; - case BasicStroke.CAP_SQUARE: - pageStream.cap(2); - break; - } - } - - protected void writeJoin(int join) throws IOException { - switch (join) { - default: - case BasicStroke.JOIN_MITER: - pageStream.join(0); - break; - case BasicStroke.JOIN_ROUND: - pageStream.join(1); - break; - case BasicStroke.JOIN_BEVEL: - pageStream.join(2); - break; - } - } - - protected void writeMiterLimit(float limit) throws IOException { - pageStream.miterLimit(limit); - } - - protected void writeDash(float[] dash, float phase) throws IOException { - pageStream.dash(dash, phase); - } - - /* 8.2. paint/color */ - public void setPaintMode() { - writeWarning(getClass() + ": setPaintMode() not implemented."); - } - - public void setXORMode(Color c1) { - writeWarning(getClass() + ": setXORMode(Color) not implemented."); - } - - protected void writePaint(Color c) throws IOException { - float[] cc = c.getRGBComponents(null); - Float alpha = new Float(cc[3]); - String alphaName = (String) extGStates.get(alpha); - if (alphaName == null) { - alphaName = "Alpha" + alphaIndex; - alphaIndex++; - extGStates.put(alpha, alphaName); - } - pageStream.state(os.name(alphaName)); - pageStream.colorSpace(cc[0], cc[1], cc[2]); - pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]); - } - - protected void writePaint(GradientPaint c) throws IOException { - writePaint((Paint) c); - } - - protected void writePaint(TexturePaint c) throws IOException { - writePaint((Paint) c); - } - - protected void writePaint(Paint paint) throws IOException { - pageStream.colorSpace(os.name("Pattern")); - pageStream.colorSpaceStroke(os.name("Pattern")); - PDFName shadingName = delayPaintQueue.delayPaint(paint, getTransform(), - getProperty(WRITE_IMAGES_AS)); - pageStream.colorSpace(null, shadingName); - pageStream.colorSpaceStroke(new double[] {}, shadingName); - } - - protected void setNonStrokeColor(Color c) throws IOException { - float[] cc = c.getRGBColorComponents(null); - pageStream.colorSpace(cc[0], cc[1], cc[2]); - } - - protected void setStrokeColor(Color c) throws IOException { - float[] cc = c.getRGBColorComponents(null); - pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]); - } - - /* 8.3. font */ - protected void writeFont(Font font) throws IOException { - // written when needed - } - - /* - * ======================================================================== - * 9. Auxiliary - * ======================================================================== - */ - public GraphicsConfiguration getDeviceConfiguration() { - writeWarning(getClass() + ": getDeviceConfiguration() not implemented."); - return null; - } - - public void writeComment(String comment) throws IOException { - // comments are ignored and disabled, because they confuse compressed - // streams - } - - public String toString() { - return "PDFGraphics2D"; - } - - /* - * ======================================================================== - * 10. Private/Utility - * ======================================================================== - */ - public void showString(Font font, String str) throws IOException { - String fontRef = fontTable.fontReference(font, isProperty(EMBED_FONTS), - getProperty(EMBED_FONTS_AS)); - pageStream.font(os.name(fontRef), font.getSize() * FONTSIZE_CORRECTION); - pageStream.show(str); - } - - /** - * See the comment of VectorGraphicsUtitlies1. - * - * @see FontUtilities#showString(java.awt.Font, String, - * org.xmind.org.freehep.graphics2d.font.CharTable, - * org.xmind.org.freehep.graphics2d.font.FontUtilities.ShowString) - */ - private void showCharacterCodes(String str) throws IOException { - FontUtilities.showString(getFont(), str, - Lookup.getInstance().getTable("PDFLatin"), this); - } - - private double getWidth() { - Dimension pageSize = getPropertyDimension(PAGE_SIZE); - Insets margins = getPropertyInsets(PAGE_MARGINS); - return pageSize.getWidth() - margins.left - margins.right; - } - - private double getHeight() { - Dimension pageSize = getPropertyDimension(PAGE_SIZE); - Insets margins = getPropertyInsets(PAGE_MARGINS); - return pageSize.getHeight() - margins.top - margins.bottom; - } - -} +// Copyright 2000-2007, FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Insets; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.TexturePaint; +import java.awt.font.LineMetrics; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.RenderedImage; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.xmind.org.freehep.graphics2d.TagString; +import org.xmind.org.freehep.graphics2d.font.FontUtilities; +import org.xmind.org.freehep.graphics2d.font.Lookup; +import org.xmind.org.freehep.graphicsio.AbstractVectorGraphicsIO; +import org.xmind.org.freehep.graphicsio.FontConstants; +import org.xmind.org.freehep.graphicsio.ImageConstants; +import org.xmind.org.freehep.graphicsio.InfoConstants; +import org.xmind.org.freehep.graphicsio.MultiPageDocument; +import org.xmind.org.freehep.graphicsio.PageConstants; +import org.xmind.org.freehep.util.UserProperties; + +/** + * Implementation of VectorGraphics that writes the output to a PDF + * file. Users of this class have to generate a PDFWriter and create an + * instance by invoking the factory method or the constructor. Document specific + * settings like page size can then be made by the appropriate setter methods. + * Before starting to draw, startExport() must be called. When drawing + * is finished, call endExport(). + * + * @author Simon Fischer + * @author Mark Donszelmann + * @author Jason Wong + */ + +@SuppressWarnings("nls") +public class PDFGraphics2D extends AbstractVectorGraphicsIO implements + MultiPageDocument, FontUtilities.ShowString { + + private static final String ROOT_KEY = PDFGraphics2D.class.getName(); + + public static final String VERSION6 = "Acrobat Reader 6.x"; + + public static final String VERSION5 = "Acrobat Reader 5.x"; + + public static final String VERSION4 = "Acrobat Reader 4.x"; + + public static final String TRANSPARENT = ROOT_KEY + "." + + PageConstants.TRANSPARENT; + + public static final String BACKGROUND = ROOT_KEY + "." + + PageConstants.BACKGROUND; + + public static final String BACKGROUND_COLOR = ROOT_KEY + "." + + PageConstants.BACKGROUND_COLOR; + + public static final String PAGE_SIZE = ROOT_KEY + "." + + PageConstants.PAGE_SIZE; + + public static final String PAGE_MARGINS = ROOT_KEY + "." + + PageConstants.PAGE_MARGINS; + + public static final String FIT_TO_PAGE = ROOT_KEY + "." + + PageConstants.FIT_TO_PAGE; + + public static final String EMBED_FONTS = ROOT_KEY + "." + + FontConstants.EMBED_FONTS; + + public static final String EMBED_FONTS_AS = ROOT_KEY + "." + + FontConstants.EMBED_FONTS_AS; + + public static final String THUMBNAILS = ROOT_KEY + ".Thumbnails"; + + public static final String COMPRESS = ROOT_KEY + ".Compress"; + + public static final String VERSION = ROOT_KEY + ".Version"; + + public static final String WRITE_IMAGES_AS = ROOT_KEY + "." + + ImageConstants.WRITE_IMAGES_AS; + + public static final String AUTHOR = ROOT_KEY + "." + InfoConstants.AUTHOR; + + public static final String TITLE = ROOT_KEY + "." + InfoConstants.TITLE; + + public static final String SUBJECT = ROOT_KEY + "." + InfoConstants.SUBJECT; + + public static final String KEYWORDS = ROOT_KEY + "." + + InfoConstants.KEYWORDS; + + private static final UserProperties defaultProperties = new UserProperties(); + static { + defaultProperties.setProperty(TRANSPARENT, true); + defaultProperties.setProperty(BACKGROUND, false); + defaultProperties.setProperty(BACKGROUND_COLOR, Color.RED); + + defaultProperties.setProperty(VERSION, VERSION5); + defaultProperties.setProperty(COMPRESS, false); + defaultProperties.setProperty(PAGE_SIZE, new Dimension(595, 842)); + defaultProperties.setProperty(PAGE_MARGINS, new Insets(20, 20, 20, 20)); + + defaultProperties.setProperty(FIT_TO_PAGE, true); + defaultProperties.setProperty(EMBED_FONTS, false); + defaultProperties.setProperty(EMBED_FONTS_AS, + FontConstants.EMBED_FONTS_TYPE3); + defaultProperties.setProperty(THUMBNAILS, defaultProperties + .getProperty(VERSION).equals(VERSION4)); + defaultProperties.setProperty(WRITE_IMAGES_AS, ImageConstants.SMALLEST); + + defaultProperties.setProperty(AUTHOR, ""); + defaultProperties.setProperty(TITLE, ""); + defaultProperties.setProperty(SUBJECT, ""); + defaultProperties.setProperty(KEYWORDS, ""); + + defaultProperties.setProperty(CLIP, true); + defaultProperties.setProperty(TEXT_AS_SHAPES, true); + } + + public static Properties getDefaultProperties() { + return defaultProperties; + } + + public static void setDefaultProperties(Properties newProperties) { + defaultProperties.setProperties(newProperties); + } + + public static final String version = "$Revision$"; + + private static final String PDF_VERSION = "1.4"; + + private static final String[] COMPRESS_FILTERS = { + ImageConstants.ENCODING_FLATE, ImageConstants.ENCODING_ASCII85 }; + + private static final String[] NO_FILTERS = {}; + + private static final double FONTSIZE_CORRECTION = 1.0; + + /* + * Not Used private static final CharTable STANDARD_CHAR_TABLES[] = { + * Lookup.getInstance().getTable("PDFLatin"), + * Lookup.getInstance().getTable("Symbol"), + * Lookup.getInstance().getTable("Zapfdingbats") }; + * + * private static final Font STANDARD_FONT[] = { null, new Font("Symbol", + * Font.PLAIN, 10), new Font("ZapfDingbats", Font.PLAIN, 10), }; + */ + + private OutputStream ros; + + private PDFWriter os; + + private PDFStream pageStream; + + // Remember some things to do + private PDFFontTable fontTable; // Remember which standard fonts were used + + private PDFImageDelayQueue delayImageQueue; // Remember images XObjects to + + // include in the file + + private PDFPaintDelayQueue delayPaintQueue; // Remember patterns to include + + // in the file + + // multipage + private int currentPage; + + private boolean multiPage; + + private TagString[] headerText; + + private int headerUnderline; + + private Font headerFont; + + private TagString[] footerText; + + private int footerUnderline; + + private Font footerFont; + + private List titles; + + // extra pointers + int alphaIndex; + + Map extGStates; + + // Other + private String producer; + + /* + * ======================================================================== + * 1. Constructors & Factory Methods + * ======================================================================== + */ + + public PDFGraphics2D(File file, Dimension size) + throws FileNotFoundException { + this(new FileOutputStream(file), size); + } + + public PDFGraphics2D(OutputStream ros, Dimension size) { + super(size, false); + init(ros); + } + + private void init(OutputStream ros) { + this.ros = new BufferedOutputStream(ros); + + currentPage = 0; + multiPage = false; + titles = new ArrayList(); + initProperties(defaultProperties); + } + + /** Clone constructor */ + protected PDFGraphics2D(PDFGraphics2D graphics, boolean doRestoreOnDispose) { + super(graphics, doRestoreOnDispose); + + this.os = graphics.os; + this.pageStream = graphics.pageStream; + + this.delayImageQueue = graphics.delayImageQueue; + this.delayPaintQueue = graphics.delayPaintQueue; + this.fontTable = graphics.fontTable; + + this.currentPage = graphics.currentPage; + this.multiPage = graphics.multiPage; + this.titles = graphics.titles; + + this.alphaIndex = graphics.alphaIndex; + this.extGStates = graphics.extGStates; + } + + /* + * ======================================================================== + * 2. Document Settings + * ======================================================================== + */ + + private void setProperty(String key, Dimension value) { + UserProperties properties = (UserProperties) getProperties(); + properties.setProperty(key, value); + } + + private void setProperty(String key, Insets value) { + UserProperties properties = (UserProperties) getProperties(); + properties.setProperty(key, value); + } + + public void setMultiPage(boolean multiPage) { + this.multiPage = multiPage; + } + + public boolean isMultiPage() { + return multiPage; + } + + public void setPageSize(Dimension size) { + setProperty(PAGE_SIZE, size); + } + + public void setMargin(Insets margins) { + setProperty(PAGE_MARGINS, margins); + } + + public void setProducer(String producer) { + this.producer = producer; + } + + /** + * Set the clipping enabled flag. This will affect all output operations + * after this call completes. In some circumstances the clipping region is + * set incorrectly (not yet understood; AWT seems to not correctly dispose + * of graphic contexts). A workaround is to simply switch it off. + */ + public static void setClipEnabled(boolean enabled) { + defaultProperties.setProperty(CLIP, enabled); + } + + /* + * ======================================================================== + * 3. Header, Trailer, Multipage & Comments + * ======================================================================== + */ + /* 3.1 Header & Trailer */ + + /** + * Writes the catalog, docinfo, preferences, and (as we use only single page + * output the page tree. + */ + @Override + public void writeHeader() throws IOException { + os = new PDFWriter(new BufferedOutputStream(ros), PDF_VERSION); + + delayImageQueue = new PDFImageDelayQueue(os); + delayPaintQueue = new PDFPaintDelayQueue(os, delayImageQueue); + + fontTable = new PDFFontTable(os); + + PDFDocInfo info = os.openDocInfo("DocInfo"); + info.setTitle(getProperty(TITLE)); + info.setAuthor(getProperty(AUTHOR)); + info.setSubject(getProperty(SUBJECT)); + info.setKeywords(getProperty(KEYWORDS)); + + info.setCreator(getCreator()); + info.setProducer(producer == null ? "" : producer); + if (!isDeviceIndependent()) { + Calendar now = Calendar.getInstance(); + info.setCreationDate(now); + info.setModificationDate(now); + } + info.setTrapped("False"); + os.close(info); + + // catalog + PDFCatalog catalog = os.openCatalog("Catalog", "RootPage"); + catalog.setOutlines("Outlines"); + catalog.setPageMode("UseOutlines"); + catalog.setViewerPreferences("Preferences"); + catalog.setOpenAction(new Object[] { os.ref("Page1"), os.name("Fit") }); + os.close(catalog); + + // preferences + PDFViewerPreferences prefs = os.openViewerPreferences("Preferences"); + prefs.setFitWindow(true); + prefs.setCenterWindow(false); + os.close(prefs); + + // extra stuff + alphaIndex = 1; + extGStates = new HashMap(); + + // hide the multipage functionality to the user in case of single page + // output by opening the first and only page immediately + if (!isMultiPage()) { + openPage(getSize(), null); + } + } + + public void writeBackground() { + if (isProperty(TRANSPARENT)) { + setBackground(null); + } else if (isProperty(BACKGROUND)) { + setBackground(getPropertyColor(BACKGROUND_COLOR)); + clearRect(0.0, 0.0, getSize().width, getSize().height); + } else { + setBackground(Color.WHITE); + clearRect(0.0, 0.0, getSize().width, getSize().height); + } + } + + public void writeTrailer() throws IOException { + if (!isMultiPage()) + closePage(); + + // pages + PDFPageTree pages = os.openPageTree("RootPage", null); + for (int i = 1; i <= currentPage; i++) { + pages.addPage("Page" + i); + } + + Dimension pageSize = getPropertyDimension(PAGE_SIZE); + pages.setMediaBox(0, 0, pageSize.getWidth(), pageSize.getHeight()); + pages.setResources("Resources"); + os.close(pages); + + // ProcSet + os.object("PageProcSet", new Object[] { os.name("PDF"), + os.name("Text"), os.name("ImageC") }); + + // Font + int nFonts = fontTable.addFontDictionary(); + + // XObject + int nXObjects = delayImageQueue.addXObjects(); + + // Pattern + int nPatterns = delayPaintQueue.addPatterns(); + + // ExtGState + if (extGStates.size() > 0) { + PDFDictionary extGState = os.openDictionary("ExtGState"); + + for (Iterator i = extGStates.keySet().iterator(); i + .hasNext();) { + Float alpha = (Float) i.next(); + String alphaName = (String) extGStates.get(alpha); + PDFDictionary alphaDictionary = extGState + .openDictionary(alphaName); + alphaDictionary.entry("ca", alpha.floatValue()); + alphaDictionary.entry("CA", alpha.floatValue()); + alphaDictionary.entry("BM", os.name("Normal")); + alphaDictionary.entry("AIS", false); + extGState.close(alphaDictionary); + } + os.close(extGState); + } + + // resources + PDFDictionary resources = os.openDictionary("Resources"); + resources.entry("ProcSet", os.ref("PageProcSet")); + if (nFonts > 0) + resources.entry("Font", os.ref("FontList")); + if (nXObjects > 0) + resources.entry("XObject", os.ref("XObjects")); + if (nPatterns > 0) + resources.entry("Pattern", os.ref("Pattern")); + if (extGStates.size() > 0) + resources.entry("ExtGState", os.ref("ExtGState")); + os.close(resources); + + // outlines + PDFOutlineList outlines = os.openOutlineList("Outlines", "Outline1", + "Outline" + currentPage); + os.close(outlines); + + for (int i = 1; i <= currentPage; i++) { + String prev = i > 1 ? "Outline" + (i - 1) : null; + String next = i < currentPage ? "Outline" + (i + 1) : null; + PDFOutline outline = os.openOutline("Outline" + i, + (String) titles.get(i - 1), "Outlines", prev, next); + outline.setDest(new Object[] { os.ref("Page" + i), os.name("Fit") }); + os.close(outline); + } + + // delayed objects (images, patterns, fonts) + processDelayed(); + } + + public void closeStream() throws IOException { + os.close(); + } + + private void processDelayed() throws IOException { + delayImageQueue.processAll(); + delayPaintQueue.processAll(); + fontTable.embedAll(getFontRenderContext(), isProperty(EMBED_FONTS), + getProperty(EMBED_FONTS_AS)); + } + + /* 3.2 MultipageDocument methods */ + public void openPage(Dimension size, String title) throws IOException { + resetClip(new Rectangle(0, 0, size.width, size.height)); + + if (pageStream != null) { + writeWarning("Page " + currentPage + " already open. " + + "Call closePage() before starting a new one."); + return; + } + + // BufferedImage thumbnail = null; + // prepare thumbnail if possible + // if ((component != null) && isProperty(PDFGraphics2D.THUMBNAILS)) { + // thumbnail = ImageGraphics2D.generateThumbnail(component, + // getPropertyDimension(PDFGraphics2D.THUMBNAIL_SIZE)); + // } + + currentPage++; + + if (title == null) + title = "Page " + currentPage + " (untitled)"; + titles.add(title); + + PDFPage page = os.openPage("Page" + currentPage, "RootPage"); + page.setContents("PageContents" + currentPage); + + // if (thumbnail != null) + // page.setThumb("Thumb" + currentPage); + + os.close(page); + + // if (thumbnail != null) { + // PDFStream thumbnailStream = os.openStream("Thumb" + currentPage); + // thumbnailStream.image(thumbnail, Color.black, ImageConstants.ZLIB); + // os.close(thumbnailStream); + // } + + pageStream = os.openStream("PageContents" + currentPage, + isProperty(COMPRESS) ? COMPRESS_FILTERS : NO_FILTERS); + + // transform the coordinate system as necessary + // 1. flip the coordinate system down and translate it upwards again + // so that the origin is the upper left corner of the page. + AffineTransform pageTrafo = new AffineTransform(); + pageTrafo.scale(1, -1); + Dimension pageSize = getPropertyDimension(PAGE_SIZE); + Insets margins = getPropertyInsets(PAGE_MARGINS); + pageTrafo + .translate(margins.left, -(pageSize.getHeight() - margins.top)); + + // in between write the header and footer (which should not be scaled!) + writeHeadline(pageTrafo); + writeFootline(pageTrafo); + + // 2. check whether we have to rescale the image to fit onto the page + double scaleFactor = Math.min(getWidth() / size.width, getHeight() + / size.height); + if ((scaleFactor < 1) || isProperty(FIT_TO_PAGE)) { + pageTrafo.scale(scaleFactor, scaleFactor); + } else { + scaleFactor = 1; + } + + // 3. center the image on the page + double dx = (getWidth() - size.width * scaleFactor) / 2 / scaleFactor; + double dy = (getHeight() - size.height * scaleFactor) / 2 / scaleFactor; + pageTrafo.translate(dx, dy); + + writeTransform(pageTrafo); + + // save the graphics context resets before setClip + writeGraphicsSave(); + + clipRect(0, 0, size.width, size.height); + + // save the graphics context resets before setClip + writeGraphicsSave(); + + delayPaintQueue.setPageMatrix(pageTrafo); + + writeGraphicsState(); + writeBackground(); + } + + public void closePage() throws IOException { + if (pageStream == null) { + writeWarning("Page " + currentPage + " already closed. " + + "Call openPage() to start a new one."); + return; + } + writeGraphicsRestore(); + writeGraphicsRestore(); + os.close(pageStream); + pageStream = null; + + processDelayed(); // This does not work properly with acrobat reader 4! + } + + public void setHeader(Font font, TagString left, TagString center, + TagString right, int underlineThickness) { + this.headerFont = font; + this.headerText = new TagString[3]; + this.headerText[0] = left; + this.headerText[1] = center; + this.headerText[2] = right; + this.headerUnderline = underlineThickness; + } + + public void setFooter(Font font, TagString left, TagString center, + TagString right, int underlineThickness) { + this.footerFont = font; + this.footerText = new TagString[3]; + this.footerText[0] = left; + this.footerText[1] = center; + this.footerText[2] = right; + this.footerUnderline = underlineThickness; + } + + private void writeHeadline(AffineTransform pageTrafo) throws IOException { + if (headerText != null) { + LineMetrics metrics = headerFont.getLineMetrics("mM", + getFontRenderContext()); + writeLine(pageTrafo, headerFont, headerText, -metrics.getLeading() + - headerFont.getSize2D() / 2, TEXT_BOTTOM, + -headerFont.getSize2D() / 2, headerUnderline); + } + } + + private void writeFootline(AffineTransform pageTrafo) throws IOException { + if (footerText != null) { + LineMetrics metrics = footerFont.getLineMetrics("mM", + getFontRenderContext()); + double y = getHeight() + footerFont.getSize2D() / 2; + writeLine(pageTrafo, footerFont, footerText, + y + metrics.getLeading(), TEXT_TOP, y, footerUnderline); + } + } + + private void writeLine(AffineTransform trafo, Font font, TagString[] text, + double ty, int yAlign, double ly, int underline) throws IOException { + writeGraphicsSave(); + setColor(Color.black); + setFont(font); + writeTransform(trafo); + if (text[0] != null) + drawString(text[0], 0, ty, TEXT_LEFT, yAlign); + if (text[1] != null) + drawString(text[1], getWidth() / 2, ty, TEXT_CENTER, yAlign); + if (text[2] != null) + drawString(text[2], getWidth(), ty, TEXT_RIGHT, yAlign); + if (underline >= 0) { + setLineWidth((double) underline); + drawLine(0, ly, getWidth(), ly); + } + writeGraphicsRestore(); + } + + /* + * ======================================================================== + * 4. Create & Dispose + * ======================================================================== + */ + + @Override + public Graphics create() { + try { + writeGraphicsSave(); + } catch (IOException e) { + handleException(e); + } + return new PDFGraphics2D(this, true); + } + + public Graphics create(double x, double y, double width, double height) { + try { + writeGraphicsSave(); + } catch (IOException e) { + handleException(e); + } + PDFGraphics2D graphics = new PDFGraphics2D(this, true); + graphics.translate(x, y); + graphics.clipRect(0, 0, width, height); + return graphics; + } + + protected void writeGraphicsSave() throws IOException { + pageStream.save(); + } + + protected void writeGraphicsRestore() throws IOException { + pageStream.restore(); + } + + /* + * ======================================================================== + * 5. Drawing Methods + * ======================================================================== + */ + public void draw(Shape s) { + try { + if (getStroke() instanceof BasicStroke) { + // in this case we've already handled the stroke + pageStream.drawPath(s); + pageStream.stroke(); + } else { + // otherwise handle it now + pageStream.drawPath(getStroke().createStrokedShape(s)); + pageStream.fill(); + } + } catch (IOException e) { + handleException(e); + } + } + + public void fill(Shape s) { + try { + boolean eofill = pageStream.drawPath(s); + if (eofill) { + pageStream.fillEvenOdd(); + } else { + pageStream.fill(); + } + } catch (IOException e) { + handleException(e); + } + } + + /* 5.2 Images */ + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + writeWarning(getClass() + + ": copyArea(int, int, int, int, int, int) not implemented."); + } + + protected void writeImage(RenderedImage image, AffineTransform xform, + Color bkg) throws IOException { + PDFName ref = delayImageQueue.delayImage(image, bkg, + getProperty(WRITE_IMAGES_AS)); + + AffineTransform imageTransform = new AffineTransform(image.getWidth(), + 0.0, 0.0, -image.getHeight(), 0.0, image.getHeight()); + xform.concatenate(imageTransform); + + writeGraphicsSave(); + pageStream.matrix(xform); + pageStream.xObject(ref); + writeGraphicsRestore(); + } + + /* 5.3. Strings */ + protected void writeString(String str, double x, double y) + throws IOException { + // save the graphics context, especially the transformation matrix + writeGraphicsSave(); + + // translate the offset to x and y + AffineTransform at = new AffineTransform(1, 0, 0, 1, x, y); + // transform for font + at.concatenate(getFont().getTransform()); + // mirror the matrix + at.scale(1, -1); + + // write transform + writeTransform(at); + + pageStream.beginText(); + pageStream.text(0, 0); + showCharacterCodes(str); + pageStream.endText(); + + // restore the transformation matrix + writeGraphicsRestore(); + } + + /* + * ======================================================================== + * 6. Transformations + * ======================================================================== + */ + /** Write the given transformation matrix to the file. */ + protected void writeTransform(AffineTransform t) throws IOException { + pageStream.matrix(t); + } + + /* + * ======================================================================== + * 7. Clipping + * ======================================================================== + */ + protected void writeSetClip(Shape s) throws IOException { + // clear old clip + try { + AffineTransform at = getTransform(); + Stroke stroke = getStroke(); + + writeGraphicsRestore(); + writeGraphicsSave(); + + writeStroke(stroke); + writeTransform(at); + } catch (IOException e) { + handleException(e); + } + + // write clip + writeClip(s); + } + + protected void writeClip(Shape s) throws IOException { + if (s == null || !isProperty(CLIP)) { + return; + } + + if (s instanceof Rectangle2D) { + pageStream.move(((Rectangle2D) s).getMinX(), + ((Rectangle2D) s).getMinY()); + pageStream.line(((Rectangle2D) s).getMaxX(), + ((Rectangle2D) s).getMinY()); + pageStream.line(((Rectangle2D) s).getMaxX(), + ((Rectangle2D) s).getMaxY()); + pageStream.line(((Rectangle2D) s).getMinX(), + ((Rectangle2D) s).getMaxY()); + pageStream.closePath(); + pageStream.clip(); + pageStream.endPath(); + } else { + boolean eoclip = pageStream.drawPath(s); + if (eoclip) { + pageStream.clipEvenOdd(); + } else { + pageStream.clip(); + } + + pageStream.endPath(); + } + } + + /* + * ======================================================================== + * 8. Graphics State + * ======================================================================== + */ + /* 8.1. stroke/linewidth */ + protected void writeWidth(float width) throws IOException { + pageStream.width(width); + } + + protected void writeCap(int cap) throws IOException { + switch (cap) { + default: + case BasicStroke.CAP_BUTT: + pageStream.cap(0); + break; + case BasicStroke.CAP_ROUND: + pageStream.cap(1); + break; + case BasicStroke.CAP_SQUARE: + pageStream.cap(2); + break; + } + } + + protected void writeJoin(int join) throws IOException { + switch (join) { + default: + case BasicStroke.JOIN_MITER: + pageStream.join(0); + break; + case BasicStroke.JOIN_ROUND: + pageStream.join(1); + break; + case BasicStroke.JOIN_BEVEL: + pageStream.join(2); + break; + } + } + + protected void writeMiterLimit(float limit) throws IOException { + pageStream.miterLimit(limit); + } + + protected void writeDash(float[] dash, float phase) throws IOException { + pageStream.dash(dash, phase); + } + + /* 8.2. paint/color */ + public void setPaintMode() { + writeWarning(getClass() + ": setPaintMode() not implemented."); + } + + public void setXORMode(Color c1) { + writeWarning(getClass() + ": setXORMode(Color) not implemented."); + } + + protected void writePaint(Color c) throws IOException { + float[] cc = c.getRGBComponents(null); + Float alpha = new Float(cc[3]); + String alphaName = (String) extGStates.get(alpha); + if (alphaName == null) { + alphaName = "Alpha" + alphaIndex; + alphaIndex++; + extGStates.put(alpha, alphaName); + } + pageStream.state(os.name(alphaName)); + pageStream.colorSpace(cc[0], cc[1], cc[2]); + pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]); + } + + protected void writePaint(GradientPaint c) throws IOException { + writePaint((Paint) c); + } + + protected void writePaint(TexturePaint c) throws IOException { + writePaint((Paint) c); + } + + protected void writePaint(Paint paint) throws IOException { + pageStream.colorSpace(os.name("Pattern")); + pageStream.colorSpaceStroke(os.name("Pattern")); + PDFName shadingName = delayPaintQueue.delayPaint(paint, getTransform(), + getProperty(WRITE_IMAGES_AS)); + pageStream.colorSpace(null, shadingName); + pageStream.colorSpaceStroke(new double[] {}, shadingName); + } + + protected void setNonStrokeColor(Color c) throws IOException { + float[] cc = c.getRGBColorComponents(null); + pageStream.colorSpace(cc[0], cc[1], cc[2]); + } + + protected void setStrokeColor(Color c) throws IOException { + float[] cc = c.getRGBColorComponents(null); + pageStream.colorSpaceStroke(cc[0], cc[1], cc[2]); + } + + /* 8.3. font */ + protected void writeFont(Font font) throws IOException { + // written when needed + } + + /* + * ======================================================================== + * 9. Auxiliary + * ======================================================================== + */ + public GraphicsConfiguration getDeviceConfiguration() { + writeWarning(getClass() + ": getDeviceConfiguration() not implemented."); + return null; + } + + public void writeComment(String comment) throws IOException { + // comments are ignored and disabled, because they confuse compressed + // streams + } + + public String toString() { + return "PDFGraphics2D"; + } + + /* + * ======================================================================== + * 10. Private/Utility + * ======================================================================== + */ + public void showString(Font font, String str) throws IOException { + String fontRef = fontTable.fontReference(font, isProperty(EMBED_FONTS), + getProperty(EMBED_FONTS_AS)); + pageStream.font(os.name(fontRef), font.getSize() * FONTSIZE_CORRECTION); + pageStream.show(str); + } + + /** + * See the comment of VectorGraphicsUtitlies1. + * + * @see FontUtilities#showString(java.awt.Font, String, + * org.xmind.org.freehep.graphics2d.font.CharTable, + * org.xmind.org.freehep.graphics2d.font.FontUtilities.ShowString) + */ + private void showCharacterCodes(String str) throws IOException { + FontUtilities.showString(getFont(), str, + Lookup.getInstance().getTable("PDFLatin"), this); + } + + private double getWidth() { + Dimension pageSize = getPropertyDimension(PAGE_SIZE); + Insets margins = getPropertyInsets(PAGE_MARGINS); + return pageSize.getWidth() - margins.left - margins.right; + } + + private double getHeight() { + Dimension pageSize = getPropertyDimension(PAGE_SIZE); + Insets margins = getPropertyInsets(PAGE_MARGINS); + return pageSize.getHeight() - margins.top - margins.bottom; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFImageDelayQueue.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFImageDelayQueue.java index b09835424..b6a054deb 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFImageDelayQueue.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFImageDelayQueue.java @@ -1,116 +1,116 @@ -// Copyright 2001-2005, FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Color; -import java.awt.image.RenderedImage; -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Delay Image objects for writing XObjects to the pdf file when the - * pageStream is complete. Caches identical images to only write them once. - * - * @author Simon Fischer - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFImageDelayQueue { - - private int currentNumber = 0; - - private class Entry { - private RenderedImage image; - - private String name, maskName; - - private Color bkg; - - private String writeAs; - - private boolean written; - - private Entry(RenderedImage image, Color bkg, String writeAs) { - this.image = image; - this.bkg = bkg; - this.writeAs = writeAs; - this.name = "Img" + (currentNumber++); - if (image.getColorModel().hasAlpha() && (bkg == null)) { - maskName = name + "Mask"; - } else { - maskName = null; - } - this.written = false; - } - } - - private Map imageMap; - - private List imageList; - - private PDFWriter pdf; - - public PDFImageDelayQueue(PDFWriter pdf) { - this.pdf = pdf; - this.imageMap = new HashMap(); - this.imageList = new LinkedList(); - } - - public PDFName delayImage(RenderedImage image, Color bkg, String writeAs) { - Entry entry = (Entry) imageMap.get(image); - if (entry == null) { - entry = new Entry(image, bkg, writeAs); - imageMap.put(image, entry); - imageList.add(entry); - } - - return pdf.name(entry.name); - } - - /** Creates a stream for every delayed image that is not written yet. */ - public void processAll() throws IOException { - for (Iterator i = imageList.iterator(); i.hasNext();) { - Entry entry = (Entry) i.next(); - - if (!entry.written) { - entry.written = true; - - PDFStream img = pdf.openStream(entry.name); - img.entry("Subtype", pdf.name("Image")); - if (entry.maskName != null) - img.entry("SMask", pdf.ref(entry.maskName)); - img.image(entry.image, entry.bkg, entry.writeAs); - pdf.close(img); - - if (entry.maskName != null) { - PDFStream mask = pdf.openStream(entry.maskName); - mask.entry("Subtype", pdf.name("Image")); - mask.imageMask(entry.image, entry.writeAs); - pdf.close(mask); - } - } - } - } - - /** - * Adds all names to the dictionary which should be the value of the - * resources dicionrary's /XObject entry. - */ - public int addXObjects() throws IOException { - if (imageList.size() > 0) { - PDFDictionary xobj = pdf.openDictionary("XObjects"); - for (Iterator i = imageList.iterator(); i.hasNext();) { - Entry entry = (Entry) i.next(); - xobj.entry(entry.name, pdf.ref(entry.name)); - if (entry.maskName != null) - xobj.entry(entry.maskName, pdf.ref(entry.maskName)); - } - pdf.close(xobj); - } - return imageList.size(); - } -} +// Copyright 2001-2005, FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Color; +import java.awt.image.RenderedImage; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Delay Image objects for writing XObjects to the pdf file when the + * pageStream is complete. Caches identical images to only write them once. + * + * @author Simon Fischer + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFImageDelayQueue { + + private int currentNumber = 0; + + private class Entry { + private RenderedImage image; + + private String name, maskName; + + private Color bkg; + + private String writeAs; + + private boolean written; + + private Entry(RenderedImage image, Color bkg, String writeAs) { + this.image = image; + this.bkg = bkg; + this.writeAs = writeAs; + this.name = "Img" + (currentNumber++); + if (image.getColorModel().hasAlpha() && (bkg == null)) { + maskName = name + "Mask"; + } else { + maskName = null; + } + this.written = false; + } + } + + private Map imageMap; + + private List imageList; + + private PDFWriter pdf; + + public PDFImageDelayQueue(PDFWriter pdf) { + this.pdf = pdf; + this.imageMap = new HashMap(); + this.imageList = new LinkedList(); + } + + public PDFName delayImage(RenderedImage image, Color bkg, String writeAs) { + Entry entry = (Entry) imageMap.get(image); + if (entry == null) { + entry = new Entry(image, bkg, writeAs); + imageMap.put(image, entry); + imageList.add(entry); + } + + return pdf.name(entry.name); + } + + /** Creates a stream for every delayed image that is not written yet. */ + public void processAll() throws IOException { + for (Iterator i = imageList.iterator(); i.hasNext();) { + Entry entry = (Entry) i.next(); + + if (!entry.written) { + entry.written = true; + + PDFStream img = pdf.openStream(entry.name); + img.entry("Subtype", pdf.name("Image")); + if (entry.maskName != null) + img.entry("SMask", pdf.ref(entry.maskName)); + img.image(entry.image, entry.bkg, entry.writeAs); + pdf.close(img); + + if (entry.maskName != null) { + PDFStream mask = pdf.openStream(entry.maskName); + mask.entry("Subtype", pdf.name("Image")); + mask.imageMask(entry.image, entry.writeAs); + pdf.close(mask); + } + } + } + } + + /** + * Adds all names to the dictionary which should be the value of the + * resources dicionrary's /XObject entry. + */ + public int addXObjects() throws IOException { + if (imageList.size() > 0) { + PDFDictionary xobj = pdf.openDictionary("XObjects"); + for (Iterator i = imageList.iterator(); i.hasNext();) { + Entry entry = (Entry) i.next(); + xobj.entry(entry.name, pdf.ref(entry.name)); + if (entry.maskName != null) + xobj.entry(entry.maskName, pdf.ref(entry.maskName)); + } + pdf.close(xobj); + } + return imageList.size(); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFName.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFName.java index 4fd4923da..9ba6358a2 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFName.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFName.java @@ -1,21 +1,21 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -/** - * Specifies a PDFName object. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class PDFName implements PDFConstants { - - private String name; - - PDFName(String name) { - this.name = name; - } - - public String toString() { - return "/" + name; //$NON-NLS-1$ - } +package org.xmind.org.freehep.graphicsio.pdf; + +/** + * Specifies a PDFName object. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class PDFName implements PDFConstants { + + private String name; + + PDFName(String name) { + this.name = name; + } + + public String toString() { + return "/" + name; //$NON-NLS-1$ + } } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFObject.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFObject.java index f744709f6..ef90c49b4 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFObject.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFObject.java @@ -1,176 +1,176 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements a numbered PDFObject. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFObject implements PDFConstants { - - protected PDF pdf; - - private PDFByteWriter out; - - private String open; - - private boolean ok; - - PDFObject(PDF pdf, PDFByteWriter writer, int objectNumber, - int generationNumber) throws IOException { - this.pdf = pdf; - out = writer; - out.println(objectNumber + " " + generationNumber + " obj"); - out.indent(); - ok = true; - } - - void close() throws IOException { - out.outdent(); - out.println("endobj"); - out.println(); - ok = false; - } - - public void entry(int number) throws IOException { - if (!ok) - System.err.println("PDFWriter: 'PDFObject' was closed"); - out.println(number); - } - - public void entry(Object[] objs) throws IOException { - if (!ok) - System.err.println("PDFWriter: 'PDFObject' was closed"); - out.print("["); - for (int i = 0; i < objs.length; i++) { - if (i != 0) - out.printPlain(" "); - out.printPlain(objs[i]); - } - out.printPlain("]"); - out.println(); - } - - // public void entry(String string) throws IOException { - // if (!ok) System.err.println("PDFWriter: 'PDFObject' was closed"); - // out.println("("+PDFUtil.escape(string)+")"); - // } - - PDFDictionary openDictionary() throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDictionary' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFDictionary"; - PDFDictionary dictionary = new PDFDictionary(pdf, out, this); - return dictionary; - } - - void close(PDFDictionary dictionary) throws IOException { - dictionary.close(); - open = null; - } - - PDFStream openStream(String name, String[] encode) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFStream' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFStream"; - PDFStream stream = new PDFStream(pdf, out, name, this, encode); - return stream; - } - - void close(PDFStream stream) throws IOException { - stream.close(); - open = null; - } - - PDFDocInfo openDocInfo(PDF pdf) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFDocInfo' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFDocInfo"; - PDFDocInfo info = new PDFDocInfo(pdf, out, this); - return info; - } - - PDFCatalog openCatalog(PDF pdf, PDFRef pageTree) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFCatalog' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFCatalog"; - PDFCatalog catalog = new PDFCatalog(pdf, out, this, pageTree); - return catalog; - } - - PDFPageTree openPageTree(PDF pdf, PDFRef parent) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFPageTree' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFPageTree"; - PDFPageTree tree = new PDFPageTree(pdf, out, this, parent); - return tree; - } - - PDFPage openPage(PDF pdf, PDFRef parent) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFPage' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFPage"; - PDFPage page = new PDFPage(pdf, out, this, parent); - return page; - } - - PDFViewerPreferences openViewerPreferences(PDF pdf) throws IOException { - if (!ok) - System.err - .println("PDFWriter error: 'PDFViewerPreferences' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFViewerPreferences"; - PDFViewerPreferences prefs = new PDFViewerPreferences(pdf, out, this); - return prefs; - } - - PDFOutlineList openOutlineList(PDF pdf, PDFRef first, PDFRef last) - throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFOutlineList' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFOutlineList"; - PDFOutlineList list = new PDFOutlineList(pdf, out, this, first, last); - return list; - } - - PDFOutline openOutline(PDF pdf, PDFRef parent, String title, PDFRef prev, - PDFRef next) throws IOException { - if (!ok) - System.err.println("PDFWriter error: 'PDFOutline' was closed"); - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFOutline"; - PDFOutline outline = new PDFOutline(pdf, out, this, parent, title, - prev, next); - return outline; - } - -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements a numbered PDFObject. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFObject implements PDFConstants { + + protected PDF pdf; + + private PDFByteWriter out; + + private String open; + + private boolean ok; + + PDFObject(PDF pdf, PDFByteWriter writer, int objectNumber, + int generationNumber) throws IOException { + this.pdf = pdf; + out = writer; + out.println(objectNumber + " " + generationNumber + " obj"); + out.indent(); + ok = true; + } + + void close() throws IOException { + out.outdent(); + out.println("endobj"); + out.println(); + ok = false; + } + + public void entry(int number) throws IOException { + if (!ok) + System.err.println("PDFWriter: 'PDFObject' was closed"); + out.println(number); + } + + public void entry(Object[] objs) throws IOException { + if (!ok) + System.err.println("PDFWriter: 'PDFObject' was closed"); + out.print("["); + for (int i = 0; i < objs.length; i++) { + if (i != 0) + out.printPlain(" "); + out.printPlain(objs[i]); + } + out.printPlain("]"); + out.println(); + } + + // public void entry(String string) throws IOException { + // if (!ok) System.err.println("PDFWriter: 'PDFObject' was closed"); + // out.println("("+PDFUtil.escape(string)+")"); + // } + + PDFDictionary openDictionary() throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDictionary' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFDictionary"; + PDFDictionary dictionary = new PDFDictionary(pdf, out, this); + return dictionary; + } + + void close(PDFDictionary dictionary) throws IOException { + dictionary.close(); + open = null; + } + + PDFStream openStream(String name, String[] encode) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFStream' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFStream"; + PDFStream stream = new PDFStream(pdf, out, name, this, encode); + return stream; + } + + void close(PDFStream stream) throws IOException { + stream.close(); + open = null; + } + + PDFDocInfo openDocInfo(PDF pdf) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFDocInfo' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFDocInfo"; + PDFDocInfo info = new PDFDocInfo(pdf, out, this); + return info; + } + + PDFCatalog openCatalog(PDF pdf, PDFRef pageTree) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFCatalog' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFCatalog"; + PDFCatalog catalog = new PDFCatalog(pdf, out, this, pageTree); + return catalog; + } + + PDFPageTree openPageTree(PDF pdf, PDFRef parent) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFPageTree' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFPageTree"; + PDFPageTree tree = new PDFPageTree(pdf, out, this, parent); + return tree; + } + + PDFPage openPage(PDF pdf, PDFRef parent) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFPage' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFPage"; + PDFPage page = new PDFPage(pdf, out, this, parent); + return page; + } + + PDFViewerPreferences openViewerPreferences(PDF pdf) throws IOException { + if (!ok) + System.err + .println("PDFWriter error: 'PDFViewerPreferences' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFViewerPreferences"; + PDFViewerPreferences prefs = new PDFViewerPreferences(pdf, out, this); + return prefs; + } + + PDFOutlineList openOutlineList(PDF pdf, PDFRef first, PDFRef last) + throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFOutlineList' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFOutlineList"; + PDFOutlineList list = new PDFOutlineList(pdf, out, this, first, last); + return list; + } + + PDFOutline openOutline(PDF pdf, PDFRef parent, String title, PDFRef prev, + PDFRef next) throws IOException { + if (!ok) + System.err.println("PDFWriter error: 'PDFOutline' was closed"); + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFOutline"; + PDFOutline outline = new PDFOutline(pdf, out, this, parent, title, + prev, next); + return outline; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutline.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutline.java index d2eabcd5a..4ade824b2 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutline.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutline.java @@ -1,55 +1,55 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements the Outline Item Dictionary (see Table 7.4). - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFOutline extends PDFDictionary { - - PDFOutline(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent, - String title, PDFRef prev, PDFRef next) throws IOException { - super(pdf, writer, object); - entry("Parent", parent); - entry("Title", title); - entry("Prev", prev); - entry("Next", next); - } - - public void setFirst(String first) throws IOException { - entry("First", pdf.ref(first)); - } - - public void setLast(String last) throws IOException { - entry("Last", pdf.ref(last)); - } - - public void setCount(int count) throws IOException { - entry("Count", count); - } - - public void setDest(PDFName dest) throws IOException { - entry("Dest", dest); - } - - public void setDest(String dest) throws IOException { - entry("Dest", dest); - } - - public void setDest(Object[] dest) throws IOException { - entry("Dest", dest); - } - - public void setA(String a) throws IOException { - entry("A", pdf.ref(a)); - } - - public void setSE(String se) throws IOException { - entry("SE", pdf.ref(se)); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements the Outline Item Dictionary (see Table 7.4). + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFOutline extends PDFDictionary { + + PDFOutline(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent, + String title, PDFRef prev, PDFRef next) throws IOException { + super(pdf, writer, object); + entry("Parent", parent); + entry("Title", title); + entry("Prev", prev); + entry("Next", next); + } + + public void setFirst(String first) throws IOException { + entry("First", pdf.ref(first)); + } + + public void setLast(String last) throws IOException { + entry("Last", pdf.ref(last)); + } + + public void setCount(int count) throws IOException { + entry("Count", count); + } + + public void setDest(PDFName dest) throws IOException { + entry("Dest", dest); + } + + public void setDest(String dest) throws IOException { + entry("Dest", dest); + } + + public void setDest(Object[] dest) throws IOException { + entry("Dest", dest); + } + + public void setA(String a) throws IOException { + entry("A", pdf.ref(a)); + } + + public void setSE(String se) throws IOException { + entry("SE", pdf.ref(se)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutlineList.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutlineList.java index e2f18c1b1..adcdb4de1 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutlineList.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFOutlineList.java @@ -1,26 +1,26 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements the Outline Dictionary (see Table 7.3). - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFOutlineList extends PDFDictionary { - - PDFOutlineList(PDF pdf, PDFByteWriter writer, PDFObject object, - PDFRef first, PDFRef last) throws IOException { - super(pdf, writer, object); - entry("Type", pdf.name("Outlines")); - entry("First", first); - entry("Last", last); - } - - public void setCount(int count) throws IOException { - entry("Count", count); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements the Outline Dictionary (see Table 7.3). + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFOutlineList extends PDFDictionary { + + PDFOutlineList(PDF pdf, PDFByteWriter writer, PDFObject object, + PDFRef first, PDFRef last) throws IOException { + super(pdf, writer, object); + entry("Type", pdf.name("Outlines")); + entry("First", first); + entry("Last", last); + } + + public void setCount(int count) throws IOException { + entry("Count", count); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPage.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPage.java index 56d3c5bf1..612de2108 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPage.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPage.java @@ -1,92 +1,92 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.util.Calendar; - -/** - * Implements the Page Object (see Table 3.17). Inheritable Page Attributes are - * in PDFPageBase. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFPage extends PDFPageBase { - - PDFPage(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) - throws IOException { - super(pdf, writer, object, parent); - entry("Type", pdf.name("Page")); - } - - public void setBleedBox(double x, double y, double w, double h) - throws IOException { - double[] rectangle = { x, y, w, h }; - entry("BleedBox", rectangle); - } - - public void setTrimBox(double x, double y, double w, double h) - throws IOException { - double[] rectangle = { x, y, w, h }; - entry("TrimBox", rectangle); - } - - public void setArtBox(double x, double y, double w, double h) - throws IOException { - double[] rectangle = { x, y, w, h }; - entry("ArtBox", rectangle); - } - - public void setContents(String content) throws IOException { - entry("Contents", pdf.ref(content)); - } - - public void setThumb(String thumb) throws IOException { - entry("Thumb", pdf.ref(thumb)); - } - - public void setB(String[] b) throws IOException { - entry("B", pdf.ref(b)); - } - - public void setDur(double dur) throws IOException { - entry("Dur", dur); - } - - public void setTrans(String trans) throws IOException { - entry("Trans", pdf.ref(trans)); - } - - public void setAnnots(String[] annots) throws IOException { - entry("Annots", pdf.ref(annots)); - } - - public void setAA(String aa) throws IOException { - entry("AA", pdf.ref(aa)); - } - - public void setPieceInfo(String pieceInfo) throws IOException { - entry("PieceInfo", pdf.ref(pieceInfo)); - } - - public void setLastModified(Calendar date) throws IOException { - entry("LastModified", date); - } - - public void setStructParents(int structParents) throws IOException { - entry("StructParents", structParents); - } - - public void setID(String id) throws IOException { - entry("ID", id); - } - - public void setPZ(double pz) throws IOException { - entry("PZ", pz); - } - - public void setSeparationInfo(String separationInfo) throws IOException { - entry("SeparationInfo", pdf.ref(separationInfo)); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.util.Calendar; + +/** + * Implements the Page Object (see Table 3.17). Inheritable Page Attributes are + * in PDFPageBase. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFPage extends PDFPageBase { + + PDFPage(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) + throws IOException { + super(pdf, writer, object, parent); + entry("Type", pdf.name("Page")); + } + + public void setBleedBox(double x, double y, double w, double h) + throws IOException { + double[] rectangle = { x, y, w, h }; + entry("BleedBox", rectangle); + } + + public void setTrimBox(double x, double y, double w, double h) + throws IOException { + double[] rectangle = { x, y, w, h }; + entry("TrimBox", rectangle); + } + + public void setArtBox(double x, double y, double w, double h) + throws IOException { + double[] rectangle = { x, y, w, h }; + entry("ArtBox", rectangle); + } + + public void setContents(String content) throws IOException { + entry("Contents", pdf.ref(content)); + } + + public void setThumb(String thumb) throws IOException { + entry("Thumb", pdf.ref(thumb)); + } + + public void setB(String[] b) throws IOException { + entry("B", pdf.ref(b)); + } + + public void setDur(double dur) throws IOException { + entry("Dur", dur); + } + + public void setTrans(String trans) throws IOException { + entry("Trans", pdf.ref(trans)); + } + + public void setAnnots(String[] annots) throws IOException { + entry("Annots", pdf.ref(annots)); + } + + public void setAA(String aa) throws IOException { + entry("AA", pdf.ref(aa)); + } + + public void setPieceInfo(String pieceInfo) throws IOException { + entry("PieceInfo", pdf.ref(pieceInfo)); + } + + public void setLastModified(Calendar date) throws IOException { + entry("LastModified", date); + } + + public void setStructParents(int structParents) throws IOException { + entry("StructParents", structParents); + } + + public void setID(String id) throws IOException { + entry("ID", id); + } + + public void setPZ(double pz) throws IOException { + entry("PZ", pz); + } + + public void setSeparationInfo(String separationInfo) throws IOException { + entry("SeparationInfo", pdf.ref(separationInfo)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageBase.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageBase.java index 29e48b624..7c5dac341 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageBase.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageBase.java @@ -1,44 +1,44 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements the Page Base Node to accomodate Inheritance of Page Attributes - * (see Table 3.17) - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public abstract class PDFPageBase extends PDFDictionary { - - protected PDFPageBase(PDF pdf, PDFByteWriter writer, PDFObject object, - PDFRef parent) throws IOException { - super(pdf, writer, object); - entry("Parent", parent); - } - - // - // Inheritable items go here - // - public void setResources(String resources) throws IOException { - entry("Resources", pdf.ref(resources)); - } - - public void setMediaBox(double x, double y, double w, double h) - throws IOException { - double[] rectangle = { x, y, w, h }; - entry("MediaBox", rectangle); - } - - public void setCropBox(double x, double y, double w, double h) - throws IOException { - double[] rectangle = { x, y, w, h }; - entry("CropBox", rectangle); - } - - public void setRotate(int rotate) throws IOException { - entry("Rotate", rotate); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements the Page Base Node to accomodate Inheritance of Page Attributes + * (see Table 3.17) + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public abstract class PDFPageBase extends PDFDictionary { + + protected PDFPageBase(PDF pdf, PDFByteWriter writer, PDFObject object, + PDFRef parent) throws IOException { + super(pdf, writer, object); + entry("Parent", parent); + } + + // + // Inheritable items go here + // + public void setResources(String resources) throws IOException { + entry("Resources", pdf.ref(resources)); + } + + public void setMediaBox(double x, double y, double w, double h) + throws IOException { + double[] rectangle = { x, y, w, h }; + entry("MediaBox", rectangle); + } + + public void setCropBox(double x, double y, double w, double h) + throws IOException { + double[] rectangle = { x, y, w, h }; + entry("CropBox", rectangle); + } + + public void setRotate(int rotate) throws IOException { + entry("Rotate", rotate); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageTree.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageTree.java index e4e8e0863..96c68f682 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageTree.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPageTree.java @@ -1,35 +1,35 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.util.Vector; - -/** - * Implements the Page Tree Node (see Table 3.16). - *

    - * - * @author Mark Donszelmann - * @version $Id: PDFPageTree.java 8584 2006-08-10 23:06:37Z duns $ - */ - -public class PDFPageTree extends PDFPageBase { - - Vector pages = new Vector(); - - PDFPageTree(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) - throws IOException { - super(pdf, writer, object, parent); - entry("Type", pdf.name("Pages")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public void addPage(String name) { - pages.add(pdf.ref(name)); - } - - void close() throws IOException { - Object[] kids = new Object[pages.size()]; - pages.copyInto(kids); - entry("Kids", kids); //$NON-NLS-1$ - entry("Count", kids.length); //$NON-NLS-1$ - super.close(); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.util.Vector; + +/** + * Implements the Page Tree Node (see Table 3.16). + *

    + * + * @author Mark Donszelmann + * @version $Id: PDFPageTree.java 8584 2006-08-10 23:06:37Z duns $ + */ + +public class PDFPageTree extends PDFPageBase { + + Vector pages = new Vector(); + + PDFPageTree(PDF pdf, PDFByteWriter writer, PDFObject object, PDFRef parent) + throws IOException { + super(pdf, writer, object, parent); + entry("Type", pdf.name("Pages")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void addPage(String name) { + pages.add(pdf.ref(name)); + } + + void close() throws IOException { + Object[] kids = new Object[pages.size()]; + pages.copyInto(kids); + entry("Kids", kids); //$NON-NLS-1$ + entry("Count", kids.length); //$NON-NLS-1$ + super.close(); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPaintDelayQueue.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPaintDelayQueue.java index f5c88b2f3..0bc3dfea3 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPaintDelayQueue.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPaintDelayQueue.java @@ -1,262 +1,262 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.GradientPaint; -import java.awt.Paint; -import java.awt.TexturePaint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -/** - * Delay Paint objects (gradient/texture, not color) for writing - * pattern/shading/function dictionaries to the pdf file when the pageStream is - * complete.
    - * TODO: - reuse pattern dictionaries if possible - cyclic function not working - * yet (ps calculation) - * - * @author Simon Fischer - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFPaintDelayQueue { - - private static int currentNumber = 0; - - private class Entry { - private Paint paint; - - private String name; - - private AffineTransform trafo; - - private String writeAs; - - private boolean written; - - private Entry(Paint paint, AffineTransform trafo, String writeAs) { - this.paint = paint; - this.trafo = trafo; - this.writeAs = writeAs; - this.name = "Paint" + (currentNumber++); - this.written = false; - } - } - - private List paintList; - - private PDFWriter pdf; - - // private PDFImageDelayQueue imageDelayQueue; - - private AffineTransform pageMatrix; - - /** Don't forget to call setPageMatrix(). */ - public PDFPaintDelayQueue(PDFWriter pdf, PDFImageDelayQueue imageDelayQueue) { - this.pdf = pdf; - this.paintList = new LinkedList(); - // this.imageDelayQueue = imageDelayQueue; - this.pageMatrix = new AffineTransform(); - } - - /** - * Call this method in order to inform this class about the transformation - * that is necessary to map the pattern's coordinate space to the default - * coordinate system of the parent's content stream (in our case the - * flipping of the page). - */ - public void setPageMatrix(AffineTransform t) { - pageMatrix = new AffineTransform(t); - } - - public PDFName delayPaint(Paint paint, AffineTransform transform, - String writeAs) { - Entry e = new Entry(paint, transform, writeAs); - paintList.add(e); - return pdf.name(e.name); - } - - /** Creates a stream for every delayed image. */ - public void processAll() throws IOException { - ListIterator i = paintList.listIterator(); - while (i.hasNext()) { - Entry e = (Entry) i.next(); - - if (!e.written) { - e.written = true; - if (e.paint instanceof GradientPaint) { - addGradientPaint(e); - } else if (e.paint instanceof TexturePaint) { - addTexturePaint(e); - } else { - System.err.println("PDFWriter: Paint of class '" - + e.paint.getClass() + "' not supported."); - // FIXME, we could write a color here, to keep the file - // valid. - } - } - } - } - - /** - * Adds all names to the dictionary which should be the value of the - * resources dicionrary's /Pattern entry. - */ - public int addPatterns() throws IOException { - if (paintList.size() > 0) { - PDFDictionary patterns = pdf.openDictionary("Pattern"); - ListIterator i = paintList.listIterator(); - while (i.hasNext()) { - Entry e = (Entry) i.next(); - patterns.entry(e.name, pdf.ref(e.name)); - } - pdf.close(patterns); - } - return paintList.size(); - } - - private void addGradientPaint(Entry e) throws IOException { - GradientPaint gp = (GradientPaint) e.paint; - - // open the pattern dictionary - PDFDictionary pattern = pdf.openDictionary(e.name); - pattern.entry("Type", pdf.name("Pattern")); - pattern.entry("PatternType", 2); - setMatrix(pattern, e, 0, 0); - - // the shading subdictionary - PDFDictionary shading = pattern.openDictionary("Shading"); - shading.entry("ShadingType", 2); - shading.entry("ColorSpace", pdf.name("DeviceRGB")); - Point2D p1 = gp.getPoint1(); - Point2D p2 = gp.getPoint2(); - shading.entry("Coords", new double[] { p1.getX(), p1.getY(), p2.getX(), - p2.getY() }); - double[] domain = new double[] { 0, 1 }; - shading.entry("Domain", domain); - - // the function subdictionary (necessarily by reference, because - // the type 4 function is a stream) - String functionRef = e.name + "Function"; - shading.entry("Function", pdf.ref(functionRef)); - shading.entry("Extend", new boolean[] { true, true }); - - pattern.close(shading); - - pdf.close(pattern); - - // get color components and generate the functions - float[] col0 = new float[3]; - gp.getColor1().getRGBColorComponents(col0); - double c0[] = new double[] { col0[0], col0[1], col0[2] }; - float[] col1 = new float[3]; - gp.getColor2().getRGBColorComponents(col1); - double c1[] = new double[] { col1[0], col1[1], col1[2] }; - if (gp.isCyclic()) { - // FIXME: cyclic function only eveluated between 0 and 1 for short - // range, not repetitive. - // addCyclicFunction(functionRef, c0, c1, domain); - addLinearFunction(functionRef, c0, c1, domain); - } else { - addLinearFunction(functionRef, c0, c1, domain); - } - } - - /** Writes a type 2 (exponential) function (exponent N=1) to the pdf file. */ - private void addLinearFunction(String functionRef, double[] c0, - double[] c1, double[] dom) throws IOException { - PDFDictionary function = pdf.openDictionary(functionRef); - function.entry("FunctionType", 2); - function.entry("Domain", dom); - function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. }); - function.entry("C0", c0); - function.entry("C1", c1); - function.entry("N", 1); - pdf.close(function); - } - - /** - * Writes a type 4 (PostScript calculator) function that describes a - * triangle function to the pdf file. - */ - // NOT USED - protected void addCyclicFunction(String functionRef, double[] c0, - double[] c1, double[] dom) throws IOException { - // PDFStream function = pdf.openStream(functionRef, new String[] { - // "Flate", "ASCII85" }); - PDFStream function = pdf.openStream(functionRef); - function.entry("FunctionType", 4); - // function.entry("Domain", new double[] {-1000.0, 1000.0} ); - function.entry("Domain", dom); - function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. }); - function.println("{"); - /* - * function.println("2 mod"); function.println("1 sub"); - * function.println("abs"); function.println("1 exch sub"); - */ - // function.println("sin"); - for (int i = 0; i < 3; i++) { - if (i < 2) - function.println("dup"); - function.println((c1[i] - c0[i]) + " mul"); - function.println(c0[i] + " add"); - if (i < 2) - function.println("exch"); - } - - // function.println("pop 0.8 0.0 0.0"); - - function.println("}"); - pdf.close(function); - } - - private void addTexturePaint(Entry e) throws IOException { - TexturePaint tp = (TexturePaint) e.paint; - - // open the pattern stream that also holds the inlined picture - PDFStream pattern = pdf.openStream(e.name, null); // image is encoded. - pattern.entry("Type", pdf.name("Pattern")); - pattern.entry("PatternType", 1); - pattern.entry("PaintType", 1); - BufferedImage image = tp.getImage(); - pattern.entry("TilingType", 1); - double width = tp.getAnchorRect().getWidth(); - double height = tp.getAnchorRect().getHeight(); - double offsX = tp.getAnchorRect().getX(); - double offsY = tp.getAnchorRect().getY(); - pattern.entry("BBox", new double[] { 0, 0, width, height }); - pattern.entry("XStep", width); - pattern.entry("YStep", height); - PDFDictionary resources = pattern.openDictionary("Resources"); - resources.entry("ProcSet", - new Object[] { pdf.name("PDF"), pdf.name("ImageC") }); - pattern.close(resources); - setMatrix(pattern, e, offsX, offsY); - - // scale the tiling image to the correct size - pattern.matrix(width, 0, 0, -height, 0, height); - - pattern.inlineImage(image, null, e.writeAs); - pdf.close(pattern); - } - - /** - * Sets both the page (flip) matrix and the actual transformation matrix - * plus a translation offset (which may of course be be 0). - */ - private void setMatrix(PDFDictionary dict, Entry e, double translX, - double translY) throws IOException { - // concatenate the page matrix and the actual transformation matrix - AffineTransform trafo = new AffineTransform(pageMatrix); - trafo.concatenate(e.trafo); - trafo.translate(translX, translY); - double[] matrix = new double[6]; - trafo.getMatrix(matrix); - dict.entry("Matrix", new double[] { matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5] }); - } -} +// Copyright 2001 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.GradientPaint; +import java.awt.Paint; +import java.awt.TexturePaint; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +/** + * Delay Paint objects (gradient/texture, not color) for writing + * pattern/shading/function dictionaries to the pdf file when the pageStream is + * complete.
    + * TODO: - reuse pattern dictionaries if possible - cyclic function not working + * yet (ps calculation) + * + * @author Simon Fischer + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFPaintDelayQueue { + + private static int currentNumber = 0; + + private class Entry { + private Paint paint; + + private String name; + + private AffineTransform trafo; + + private String writeAs; + + private boolean written; + + private Entry(Paint paint, AffineTransform trafo, String writeAs) { + this.paint = paint; + this.trafo = trafo; + this.writeAs = writeAs; + this.name = "Paint" + (currentNumber++); + this.written = false; + } + } + + private List paintList; + + private PDFWriter pdf; + + // private PDFImageDelayQueue imageDelayQueue; + + private AffineTransform pageMatrix; + + /** Don't forget to call setPageMatrix(). */ + public PDFPaintDelayQueue(PDFWriter pdf, PDFImageDelayQueue imageDelayQueue) { + this.pdf = pdf; + this.paintList = new LinkedList(); + // this.imageDelayQueue = imageDelayQueue; + this.pageMatrix = new AffineTransform(); + } + + /** + * Call this method in order to inform this class about the transformation + * that is necessary to map the pattern's coordinate space to the default + * coordinate system of the parent's content stream (in our case the + * flipping of the page). + */ + public void setPageMatrix(AffineTransform t) { + pageMatrix = new AffineTransform(t); + } + + public PDFName delayPaint(Paint paint, AffineTransform transform, + String writeAs) { + Entry e = new Entry(paint, transform, writeAs); + paintList.add(e); + return pdf.name(e.name); + } + + /** Creates a stream for every delayed image. */ + public void processAll() throws IOException { + ListIterator i = paintList.listIterator(); + while (i.hasNext()) { + Entry e = (Entry) i.next(); + + if (!e.written) { + e.written = true; + if (e.paint instanceof GradientPaint) { + addGradientPaint(e); + } else if (e.paint instanceof TexturePaint) { + addTexturePaint(e); + } else { + System.err.println("PDFWriter: Paint of class '" + + e.paint.getClass() + "' not supported."); + // FIXME, we could write a color here, to keep the file + // valid. + } + } + } + } + + /** + * Adds all names to the dictionary which should be the value of the + * resources dicionrary's /Pattern entry. + */ + public int addPatterns() throws IOException { + if (paintList.size() > 0) { + PDFDictionary patterns = pdf.openDictionary("Pattern"); + ListIterator i = paintList.listIterator(); + while (i.hasNext()) { + Entry e = (Entry) i.next(); + patterns.entry(e.name, pdf.ref(e.name)); + } + pdf.close(patterns); + } + return paintList.size(); + } + + private void addGradientPaint(Entry e) throws IOException { + GradientPaint gp = (GradientPaint) e.paint; + + // open the pattern dictionary + PDFDictionary pattern = pdf.openDictionary(e.name); + pattern.entry("Type", pdf.name("Pattern")); + pattern.entry("PatternType", 2); + setMatrix(pattern, e, 0, 0); + + // the shading subdictionary + PDFDictionary shading = pattern.openDictionary("Shading"); + shading.entry("ShadingType", 2); + shading.entry("ColorSpace", pdf.name("DeviceRGB")); + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + shading.entry("Coords", new double[] { p1.getX(), p1.getY(), p2.getX(), + p2.getY() }); + double[] domain = new double[] { 0, 1 }; + shading.entry("Domain", domain); + + // the function subdictionary (necessarily by reference, because + // the type 4 function is a stream) + String functionRef = e.name + "Function"; + shading.entry("Function", pdf.ref(functionRef)); + shading.entry("Extend", new boolean[] { true, true }); + + pattern.close(shading); + + pdf.close(pattern); + + // get color components and generate the functions + float[] col0 = new float[3]; + gp.getColor1().getRGBColorComponents(col0); + double c0[] = new double[] { col0[0], col0[1], col0[2] }; + float[] col1 = new float[3]; + gp.getColor2().getRGBColorComponents(col1); + double c1[] = new double[] { col1[0], col1[1], col1[2] }; + if (gp.isCyclic()) { + // FIXME: cyclic function only eveluated between 0 and 1 for short + // range, not repetitive. + // addCyclicFunction(functionRef, c0, c1, domain); + addLinearFunction(functionRef, c0, c1, domain); + } else { + addLinearFunction(functionRef, c0, c1, domain); + } + } + + /** Writes a type 2 (exponential) function (exponent N=1) to the pdf file. */ + private void addLinearFunction(String functionRef, double[] c0, + double[] c1, double[] dom) throws IOException { + PDFDictionary function = pdf.openDictionary(functionRef); + function.entry("FunctionType", 2); + function.entry("Domain", dom); + function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. }); + function.entry("C0", c0); + function.entry("C1", c1); + function.entry("N", 1); + pdf.close(function); + } + + /** + * Writes a type 4 (PostScript calculator) function that describes a + * triangle function to the pdf file. + */ + // NOT USED + protected void addCyclicFunction(String functionRef, double[] c0, + double[] c1, double[] dom) throws IOException { + // PDFStream function = pdf.openStream(functionRef, new String[] { + // "Flate", "ASCII85" }); + PDFStream function = pdf.openStream(functionRef); + function.entry("FunctionType", 4); + // function.entry("Domain", new double[] {-1000.0, 1000.0} ); + function.entry("Domain", dom); + function.entry("Range", new double[] { 0., 1., 0., 1., 0., 1. }); + function.println("{"); + /* + * function.println("2 mod"); function.println("1 sub"); + * function.println("abs"); function.println("1 exch sub"); + */ + // function.println("sin"); + for (int i = 0; i < 3; i++) { + if (i < 2) + function.println("dup"); + function.println((c1[i] - c0[i]) + " mul"); + function.println(c0[i] + " add"); + if (i < 2) + function.println("exch"); + } + + // function.println("pop 0.8 0.0 0.0"); + + function.println("}"); + pdf.close(function); + } + + private void addTexturePaint(Entry e) throws IOException { + TexturePaint tp = (TexturePaint) e.paint; + + // open the pattern stream that also holds the inlined picture + PDFStream pattern = pdf.openStream(e.name, null); // image is encoded. + pattern.entry("Type", pdf.name("Pattern")); + pattern.entry("PatternType", 1); + pattern.entry("PaintType", 1); + BufferedImage image = tp.getImage(); + pattern.entry("TilingType", 1); + double width = tp.getAnchorRect().getWidth(); + double height = tp.getAnchorRect().getHeight(); + double offsX = tp.getAnchorRect().getX(); + double offsY = tp.getAnchorRect().getY(); + pattern.entry("BBox", new double[] { 0, 0, width, height }); + pattern.entry("XStep", width); + pattern.entry("YStep", height); + PDFDictionary resources = pattern.openDictionary("Resources"); + resources.entry("ProcSet", + new Object[] { pdf.name("PDF"), pdf.name("ImageC") }); + pattern.close(resources); + setMatrix(pattern, e, offsX, offsY); + + // scale the tiling image to the correct size + pattern.matrix(width, 0, 0, -height, 0, height); + + pattern.inlineImage(image, null, e.writeAs); + pdf.close(pattern); + } + + /** + * Sets both the page (flip) matrix and the actual transformation matrix + * plus a translation offset (which may of course be be 0). + */ + private void setMatrix(PDFDictionary dict, Entry e, double translX, + double translY) throws IOException { + // concatenate the page matrix and the actual transformation matrix + AffineTransform trafo = new AffineTransform(pageMatrix); + trafo.concatenate(e.trafo); + trafo.translate(translX, translY); + double[] matrix = new double[6]; + trafo.getMatrix(matrix); + dict.entry("Matrix", new double[] { matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] }); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPathConstructor.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPathConstructor.java index 38c5c04b4..86965ef54 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPathConstructor.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFPathConstructor.java @@ -1,40 +1,40 @@ -// Copyright 2002 FreeHEP. -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -import org.xmind.org.freehep.graphicsio.QuadToCubicPathConstructor; - -/** - * @author Mark Donszelmann - * @version $Id: freehep-graphicsio-pdf/src/main/java/org/freehep/graphicsio/pdf/PDFPathConstructor.java f493ff6e61b2 2005/12/01 18:46:43 duns $ - */ -public class PDFPathConstructor extends QuadToCubicPathConstructor { - private PDFStream stream; - - public PDFPathConstructor(PDFStream stream) { - super(); - this.stream = stream; - } - - public void move(double x, double y) throws IOException { - stream.move(x, y); - super.move(x, y); - } - - public void line(double x, double y) throws IOException { - stream.line(x, y); - super.line(x, y); - } - - public void cubic(double x1, double y1, double x2, double y2, double x3, - double y3) throws IOException { - stream.cubic(x1, y1, x2, y2, x3, y3); - super.cubic(x1, y1, x2, y2, x3, y3); - } - - public void closePath(double x0, double y0) throws IOException { - stream.closePath(); - super.closePath(x0, y0); - } -} +// Copyright 2002 FreeHEP. +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +import org.xmind.org.freehep.graphicsio.QuadToCubicPathConstructor; + +/** + * @author Mark Donszelmann + * @version $Id: freehep-graphicsio-pdf/src/main/java/org/freehep/graphicsio/pdf/PDFPathConstructor.java f493ff6e61b2 2005/12/01 18:46:43 duns $ + */ +public class PDFPathConstructor extends QuadToCubicPathConstructor { + private PDFStream stream; + + public PDFPathConstructor(PDFStream stream) { + super(); + this.stream = stream; + } + + public void move(double x, double y) throws IOException { + stream.move(x, y); + super.move(x, y); + } + + public void line(double x, double y) throws IOException { + stream.line(x, y); + super.line(x, y); + } + + public void cubic(double x1, double y1, double x2, double y2, double x3, + double y3) throws IOException { + stream.cubic(x1, y1, x2, y2, x3, y3); + super.cubic(x1, y1, x2, y2, x3, y3); + } + + public void closePath(double x0, double y0) throws IOException { + stream.closePath(); + super.closePath(x0, y0); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRedundanceTracker.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRedundanceTracker.java index 28a8c0300..d0a75a5ac 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRedundanceTracker.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRedundanceTracker.java @@ -1,126 +1,126 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.util.Collection; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.Vector; - -/** - * This class keeps track of all kinds of objects written to a pdf file and - * avoids to write them several times instead of referencing the same object - * several times. Right now only encoding tables are supported. - * - * An implementation for images and paint would be possible. - * - * @author Simon Fischer - * @author Jason Wong - */ -public class PDFRedundanceTracker { - - /** - * To be implemented by Writers which write objects that may already have - * been written. - */ - public interface Writer { - public void writeObject(Object o, PDFRef reference, PDFWriter pdf) - throws IOException; - } - - private class Entry { - private static final String REF_PREFIX = "PDF_RTObj"; //$NON-NLS-1$ - - private Object object; - - private Writer writer; - - private boolean written; - - private PDFRef reference; - - private Object groupID; - - private Entry(Object o, Object groupID, Writer w) { - this.object = o; - this.groupID = groupID; - this.writer = w; - this.written = false; - this.reference = pdf.ref(REF_PREFIX + (refCount++)); - } - } - - private static int refCount = 1; - - private PDFWriter pdf; - - private Map objects; - - private Vector orderedObjects; // to keep order - - public PDFRedundanceTracker(PDFWriter pdf) { - this.pdf = pdf; - objects = new Hashtable(); - orderedObjects = new Vector(); - } - - /** - * Returns a reference that points to object. When this method is - * called several times for the same object (according to its hash code) the - * same reference is returned. When writeAll() is called the - * writer's writeObject() method will be called once with - * object as argument.
    - * The groupID is only used for getGroup() - */ - public PDFRef getReference(Object object, Object groupID, Writer writer) { - Object o = objects.get(object); - if (o != null) { - return ((Entry) o).reference; - } else { - Entry entry = new Entry(object, groupID, writer); - objects.put(object, entry); - orderedObjects.add(entry); - return entry.reference; - } - } - - public PDFRef getReference(Object object, Writer writer) { - return getReference(object, null, writer); - } - - /** - * Writes all objects that are not yet written. If the method is called - * several times then each times only the new objects are written. - */ - public void writeAll() { - Iterator i = orderedObjects.iterator(); - while (i.hasNext()) { - Entry entry = (Entry) i.next(); - if (!entry.written) { - try { - // System.out.println("PDFRT: Writing: " + entry.object); - entry.writer - .writeObject(entry.object, entry.reference, pdf); - entry.written = true; - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - /** Returns all objects belonging to a particular group. */ - public Collection getGroup(Object groupID) { - Collection result = new LinkedList(); - Iterator i = orderedObjects.iterator(); - while (i.hasNext()) { - Entry entry = (Entry) i.next(); - if (groupID.equals(entry.groupID)) { - result.add(entry.object); - } - } - return result; - } -} +// Copyright 2001 freehep +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Vector; + +/** + * This class keeps track of all kinds of objects written to a pdf file and + * avoids to write them several times instead of referencing the same object + * several times. Right now only encoding tables are supported. + * + * An implementation for images and paint would be possible. + * + * @author Simon Fischer + * @author Jason Wong + */ +public class PDFRedundanceTracker { + + /** + * To be implemented by Writers which write objects that may already have + * been written. + */ + public interface Writer { + public void writeObject(Object o, PDFRef reference, PDFWriter pdf) + throws IOException; + } + + private class Entry { + private static final String REF_PREFIX = "PDF_RTObj"; //$NON-NLS-1$ + + private Object object; + + private Writer writer; + + private boolean written; + + private PDFRef reference; + + private Object groupID; + + private Entry(Object o, Object groupID, Writer w) { + this.object = o; + this.groupID = groupID; + this.writer = w; + this.written = false; + this.reference = pdf.ref(REF_PREFIX + (refCount++)); + } + } + + private static int refCount = 1; + + private PDFWriter pdf; + + private Map objects; + + private Vector orderedObjects; // to keep order + + public PDFRedundanceTracker(PDFWriter pdf) { + this.pdf = pdf; + objects = new Hashtable(); + orderedObjects = new Vector(); + } + + /** + * Returns a reference that points to object. When this method is + * called several times for the same object (according to its hash code) the + * same reference is returned. When writeAll() is called the + * writer's writeObject() method will be called once with + * object as argument.
    + * The groupID is only used for getGroup() + */ + public PDFRef getReference(Object object, Object groupID, Writer writer) { + Object o = objects.get(object); + if (o != null) { + return ((Entry) o).reference; + } else { + Entry entry = new Entry(object, groupID, writer); + objects.put(object, entry); + orderedObjects.add(entry); + return entry.reference; + } + } + + public PDFRef getReference(Object object, Writer writer) { + return getReference(object, null, writer); + } + + /** + * Writes all objects that are not yet written. If the method is called + * several times then each times only the new objects are written. + */ + public void writeAll() { + Iterator i = orderedObjects.iterator(); + while (i.hasNext()) { + Entry entry = (Entry) i.next(); + if (!entry.written) { + try { + // System.out.println("PDFRT: Writing: " + entry.object); + entry.writer + .writeObject(entry.object, entry.reference, pdf); + entry.written = true; + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** Returns all objects belonging to a particular group. */ + public Collection getGroup(Object groupID) { + Collection result = new LinkedList(); + Iterator i = orderedObjects.iterator(); + while (i.hasNext()) { + Entry entry = (Entry) i.next(); + if (groupID.equals(entry.groupID)) { + result.add(entry.object); + } + } + return result; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRef.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRef.java index 2c86ec136..309dfbcb5 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRef.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFRef.java @@ -1,42 +1,42 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -/** - * This class implements a numbered reference to a PDFObject. Internally the - * class keeps track of the numbers. The user only sees its logical name. Only - * generation 0 is used in this PDFWriter, since we do not allow for updates of - * the PDF file. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class PDFRef implements PDFConstants { - - private String name; - - private int objectNumber; - - private int generationNumber; - - PDFRef(String name, int objectNumber, int generationNumber) { - this.name = name; - this.objectNumber = objectNumber; - this.generationNumber = generationNumber; - } - - public String getName() { - return name; - } - - public int getObjectNumber() { - return objectNumber; - } - - public int getGenerationNumber() { - return generationNumber; - } - - public String toString() { - return objectNumber + " " + generationNumber + " R"; //$NON-NLS-1$ //$NON-NLS-2$ - } +package org.xmind.org.freehep.graphicsio.pdf; + +/** + * This class implements a numbered reference to a PDFObject. Internally the + * class keeps track of the numbers. The user only sees its logical name. Only + * generation 0 is used in this PDFWriter, since we do not allow for updates of + * the PDF file. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class PDFRef implements PDFConstants { + + private String name; + + private int objectNumber; + + private int generationNumber; + + PDFRef(String name, int objectNumber, int generationNumber) { + this.name = name; + this.objectNumber = objectNumber; + this.generationNumber = generationNumber; + } + + public String getName() { + return name; + } + + public int getObjectNumber() { + return objectNumber; + } + + public int getGenerationNumber() { + return generationNumber; + } + + public String toString() { + return objectNumber + " " + generationNumber + " R"; //$NON-NLS-1$ //$NON-NLS-2$ + } } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFStream.java index 6120520fc..f1f1e1a86 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFStream.java @@ -1,760 +1,760 @@ -// Copyright 2000-2007, FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.awt.Color; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.image.RenderedImage; -import java.io.IOException; -import java.io.OutputStream; - -import org.xmind.org.freehep.graphicsio.ImageConstants; -import org.xmind.org.freehep.util.io.ASCII85OutputStream; -import org.xmind.org.freehep.util.io.ASCIIHexOutputStream; -import org.xmind.org.freehep.util.io.CountedByteOutputStream; -import org.xmind.org.freehep.util.io.FinishableOutputStream; -import org.xmind.org.freehep.util.io.FlateOutputStream; - -/** - * This class allows you to write/print into a PDFStream. Several methods are - * available to specify the content of a page, image. This class performs some - * error checking, while writing the stream. - *

    - * The stream allows to write dictionary entries. The /Length entry is written - * automatically, referencing an object which will also be written just after - * the stream is closed and the length is calculated. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFStream extends PDFDictionary implements PDFConstants { - - private String name; - - private PDFObject object; - - private boolean dictionaryOpen; - - private OutputStream[] stream; - - private CountedByteOutputStream byteCountStream; - - private String[] encode; - - PDFStream(PDF pdf, PDFByteWriter writer, String name, PDFObject parent, - String[] encode) throws IOException { - super(pdf, writer); - this.name = name; - object = parent; - if (object == null) - System.err - .println("PDFWriter: 'PDFStream' cannot have a null parent"); - // first write the dictionary - dictionaryOpen = true; - this.encode = encode; - } - - /** - * Starts the stream, writes out the filters using the preset encoding, and - * encodes the stream. - */ - private void startStream() throws IOException { - startStream(encode); - } - - /** - * Starts the stream, writes out the filters using the given encoding, and - * encodes the stream. - */ - private void startStream(String[] encode) throws IOException { - if (dictionaryOpen) { - PDFName[] filters = decodeFilters(encode); - if (filters != null) - entry("Filter", filters); - - super.close(); - dictionaryOpen = false; - out.printPlain("stream\n"); - - byteCountStream = new CountedByteOutputStream(out); - stream = openFilters(byteCountStream, encode); - } - } - - private void write(int b) throws IOException { - startStream(); - stream[0].write(b); - } - - private void write(byte[] b) throws IOException { - for (int i = 0; i < b.length; i++) { - write((int) b[i]); - } - } - - private static PDFName[] decodeFilters(String[] encode) { - PDFName[] filters = null; - if ((encode != null) && (encode.length != 0)) { - filters = new PDFName[encode.length]; - for (int i = 0; i < filters.length; i++) { - filters[i] = new PDFName(encode[encode.length - i - 1] - + "Decode"); - } - } - return filters; - } - - // open new stream using Standard Filters (see table 3.5) - // stream[0] is the one to write to, the last one is s - private static OutputStream[] openFilters(OutputStream s, String[] filters) { - OutputStream[] os; - if ((filters != null) && (filters.length != 0)) { - os = new OutputStream[filters.length + 1]; - os[os.length - 1] = s; - for (int i = os.length - 2; i >= 0; i--) { - if (filters[i].equals("ASCIIHex")) { - os[i] = new ASCIIHexOutputStream(os[i + 1]); - } else if (filters[i].equals("ASCII85")) { - os[i] = new ASCII85OutputStream(os[i + 1]); - } else if (filters[i].equals("Flate")) { - os[i] = new FlateOutputStream(os[i + 1]); - } else if (filters[i].equals("DCT")) { - os[i] = os[i + 1]; - } else { - System.err.println("PDFWriter: unknown stream format: " - + filters[i]); - } - } - } else { - os = new OutputStream[1]; - os[0] = s; - } - return os; - } - - // stream[0] is the first one to finish, the last one is not finished - private static void closeFilters(OutputStream[] s) throws IOException { - for (int i = 0; i < s.length - 1; i++) { - s[i].flush(); - if (s[i] instanceof FinishableOutputStream) { - ((FinishableOutputStream) s[i]).finish(); - } - } - s[s.length - 1].flush(); - } - - private void write(String s) throws IOException { - byte[] b = s.getBytes("ISO-8859-1"); - for (int i = 0; i < b.length; i++) { - write(b[i]); - } - } - - void close() throws IOException { - closeFilters(stream); - stream = null; - out.printPlain("\nendstream"); - out.println(); - object.close(); - - if (gStates > 0) { - System.err - .println("PDFStream: unbalanced saves()/restores(), too many saves: " - + gStates); - } - } - - String getName() { - return name; - } - - public int getLength() { - return byteCountStream.getCount(); - } - - public void print(String s) throws IOException { - write(s); - } - - public void println(String s) throws IOException { - write(s); - write(EOL); - } - - public void comment(String comment) throws IOException { - println("% " + comment); - } - - // ========================================================================== - // PDFStream Operators according to Table 4.1 - // ========================================================================== - - // - // Graphics State operators (see Table 4.7) - // - private int gStates = 0; - - public void save() throws IOException { - println("q"); - gStates++; - } - - public void restore() throws IOException { - if (gStates <= 0) { - System.err - .println("PDFStream: unbalanced saves()/restores(), too many restores"); - } - gStates--; - println("Q"); - } - - public void matrix(AffineTransform xform) throws IOException { - matrix(xform.getScaleX(), xform.getShearY(), xform.getShearX(), - xform.getScaleY(), xform.getTranslateX(), xform.getTranslateY()); - } - - public void matrix(double m00, double m10, double m01, double m11, - double m02, double m12) throws IOException { - println(PDFUtil.fixedPrecision(m00) + " " + PDFUtil.fixedPrecision(m10) - + " " + PDFUtil.fixedPrecision(m01) + " " - + PDFUtil.fixedPrecision(m11) + " " - + PDFUtil.fixedPrecision(m02) + " " - + PDFUtil.fixedPrecision(m12) + " cm"); - } - - public void width(double width) throws IOException { - println(PDFUtil.fixedPrecision(width) + " w"); - } - - public void cap(int capStyle) throws IOException { - println(capStyle + " J"); - } - - public void join(int joinStyle) throws IOException { - println(joinStyle + " j"); - } - - public void miterLimit(double limit) throws IOException { - println(PDFUtil.fixedPrecision(limit) + " M"); - } - - public void dash(int[] dash, double phase) throws IOException { - print("["); - for (int i = 0; i < dash.length; i++) { - print(" " + PDFUtil.fixedPrecision(dash[i])); - } - println("] " + PDFUtil.fixedPrecision(phase) + " d"); - } - - public void dash(float[] dash, double phase) throws IOException { - print("["); - for (int i = 0; i < dash.length; i++) { - print(" " + PDFUtil.fixedPrecision(dash[i])); - } - println("] " + PDFUtil.fixedPrecision(phase) + " d"); - } - - public void flatness(double flatness) throws IOException { - println(PDFUtil.fixedPrecision(flatness) + " i"); - } - - public void state(PDFName stateDictionary) throws IOException { - println(stateDictionary + " gs"); - } - - // - // Path Construction operators (see Table 4.9) - // - public void cubic(double x1, double y1, double x2, double y2, double x3, - double y3) throws IOException { - println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1) - + " " + PDFUtil.fixedPrecision(x2) + " " - + PDFUtil.fixedPrecision(y2) + " " + PDFUtil.fixedPrecision(x3) - + " " + PDFUtil.fixedPrecision(y3) + " c"); - } - - public void cubicV(double x2, double y2, double x3, double y3) - throws IOException { - println(PDFUtil.fixedPrecision(x2) + " " + PDFUtil.fixedPrecision(y2) - + " " + PDFUtil.fixedPrecision(x3) + " " - + PDFUtil.fixedPrecision(y3) + " v"); - } - - public void cubicY(double x1, double y1, double x3, double y3) - throws IOException { - println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1) - + " " + PDFUtil.fixedPrecision(x3) + " " - + PDFUtil.fixedPrecision(y3) + " y"); - } - - public void move(double x, double y) throws IOException { - println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) - + " m"); - } - - public void line(double x, double y) throws IOException { - println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) - + " l"); - } - - public void closePath() throws IOException { - println("h"); - } - - public void rectangle(double x, double y, double width, double height) - throws IOException { - println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) - + " " + PDFUtil.fixedPrecision(width) + " " - + PDFUtil.fixedPrecision(height) + " re"); - } - - // - // Path Painting operators (see Table 4.10) - // - public void stroke() throws IOException { - println("S"); - } - - public void closeAndStroke() throws IOException { - println("s"); - } - - public void fill() throws IOException { - println("f"); - } - - public void fillEvenOdd() throws IOException { - println("f*"); - } - - public void fillAndStroke() throws IOException { - println("B"); - } - - public void fillEvenOddAndStroke() throws IOException { - println("B*"); - } - - public void closeFillAndStroke() throws IOException { - println("b"); - } - - public void closeFillEvenOddAndStroke() throws IOException { - println("b*"); - } - - public void endPath() throws IOException { - println("n"); - } - - // - // Clipping Path operators (see Table 4.11) - // - public void clip() throws IOException { - println("W"); - } - - public void clipEvenOdd() throws IOException { - println("W*"); - } - - // - // Text Object operators (see Table 5.4) - // - private boolean textOpen = false; - - public void beginText() throws IOException { - if (textOpen) - System.err.println("PDFStream: nested beginText() not allowed."); - println("BT"); - textOpen = true; - } - - public void endText() throws IOException { - if (!textOpen) - System.err - .println("PDFStream: unbalanced use of beginText()/endText()."); - println("ET"); - textOpen = false; - } - - // - // Text State operators (see Table 5.2) - // - public void charSpace(double charSpace) throws IOException { - println(PDFUtil.fixedPrecision(charSpace) + " Tc"); - } - - public void wordSpace(double wordSpace) throws IOException { - println(PDFUtil.fixedPrecision(wordSpace) + " Tw"); - } - - public void scale(double scale) throws IOException { - println(PDFUtil.fixedPrecision(scale) + " Tz"); - } - - public void leading(double leading) throws IOException { - println(PDFUtil.fixedPrecision(leading) + " TL"); - } - - private boolean fontWasSet = false; - - public void font(PDFName fontName, double size) throws IOException { - println(fontName + " " + PDFUtil.fixedPrecision(size) + " Tf"); - fontWasSet = true; - } - - public void rendering(int mode) throws IOException { - println(mode + " Tr"); - } - - public void rise(double rise) throws IOException { - println(PDFUtil.fixedPrecision(rise) + " Ts"); - } - - // - // Text Positioning operators (see Table 5.5) - // - public void text(double x, double y) throws IOException { - println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) - + " Td"); - } - - public void textLeading(double x, double y) throws IOException { - println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) - + " TD"); - } - - public void textMatrix(double a, double b, double c, double d, double e, - double f) throws IOException { - println(PDFUtil.fixedPrecision(a) + " " + PDFUtil.fixedPrecision(b) - + " " + PDFUtil.fixedPrecision(c) + " " - + PDFUtil.fixedPrecision(d) + " " + PDFUtil.fixedPrecision(e) - + " " + PDFUtil.fixedPrecision(f) + " Tm"); - } - - public void textLine() throws IOException { - println("T*"); - } - - // - // Text Showing operators (see Table 5.6) - // - public void show(String text) throws IOException { - if (!fontWasSet) - System.err - .println("PDFStream: cannot use Text Showing operator before font is set."); - if (!textOpen) - System.err - .println("PDFStream: Text Showing operator only allowed inside Text section."); - println("(" + PDFUtil.escape(text) + ") Tj"); - } - - public void showLine(String text) throws IOException { - if (!fontWasSet) - System.err - .println("PDFStream: cannot use Text Showing operator before font is set."); - if (!textOpen) - System.err - .println("PDFStream: Text Showing operator only allowed inside Text section."); - println("(" + PDFUtil.escape(text) + ") '"); - } - - public void showLine(double wordSpace, double charSpace, String text) - throws IOException { - if (!fontWasSet) - System.err - .println("PDFStream: cannot use Text Showing operator before font is set."); - if (!textOpen) - System.err - .println("PDFStream: Text Showing operator only allowed inside Text section."); - println(PDFUtil.fixedPrecision(wordSpace) + " " - + PDFUtil.fixedPrecision(charSpace) + " (" - + PDFUtil.escape(text) + ") \""); - } - - public void show(Object[] array) throws IOException { - print("["); - for (int i = 0; i < array.length; i++) { - Object object = array[i]; - if (object instanceof String) { - print(" (" + PDFUtil.escape(object.toString()) + ")"); - } else if (object instanceof Integer) { - print(" " + ((Integer) object).intValue()); - } else if (object instanceof Double) { - print(" " + ((Double) object).doubleValue()); - } else { - System.err - .println("PDFStream: input array of operator TJ may only contain objects of type 'String', 'Integer' or 'Double'"); - } - } - println("] TJ"); - } - - // - // Type 3 Font operators (see Table 5.10) - // - public void glyph(double wx, double wy) throws IOException { - println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy) - + " d0"); - } - - public void glyph(double wx, double wy, double llx, double lly, double urx, - double ury) throws IOException { - println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy) - + " " + PDFUtil.fixedPrecision(llx) + " " - + PDFUtil.fixedPrecision(lly) + " " - + PDFUtil.fixedPrecision(urx) + " " - + PDFUtil.fixedPrecision(ury) + " d1"); - } - - // - // Color operators (see Table 4.21) - // - public void colorSpace(PDFName colorSpace) throws IOException { - println(colorSpace + " cs"); - } - - public void colorSpaceStroke(PDFName colorSpace) throws IOException { - println(colorSpace + " CS"); - } - - public void colorSpace(double[] color) throws IOException { - for (int i = 0; i < color.length; i++) { - print(" " + color[i]); - } - println(" scn"); - } - - public void colorSpaceStroke(double[] color) throws IOException { - for (int i = 0; i < color.length; i++) { - print(" " + color[i]); - } - println(" SCN"); - } - - public void colorSpace(double[] color, PDFName name) throws IOException { - if (color != null) { - for (int i = 0; i < color.length; i++) { - print(PDFUtil.fixedPrecision(color[i]) + " "); - } - } - println(name + " scn"); - } - - public void colorSpaceStroke(double[] color, PDFName name) - throws IOException { - if (color != null) { - for (int i = 0; i < color.length; i++) { - print(PDFUtil.fixedPrecision(color[i]) + " "); - } - } - println(name + " SCN"); - } - - public void colorSpace(double g) throws IOException { - println(PDFUtil.fixedPrecision(g) + " g"); - } - - public void colorSpaceStroke(double g) throws IOException { - println(PDFUtil.fixedPrecision(g) + " G"); - } - - public void colorSpace(double r, double g, double b) throws IOException { - println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g) - + " " + PDFUtil.fixedPrecision(b) + " rg"); - } - - public void colorSpaceStroke(double r, double g, double b) - throws IOException { - println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g) - + " " + PDFUtil.fixedPrecision(b) + " RG"); - } - - public void colorSpace(double c, double m, double y, double k) - throws IOException { - println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m) - + " " + PDFUtil.fixedPrecision(y) + " " - + PDFUtil.fixedPrecision(k) + " k"); - } - - public void colorSpaceStroke(double c, double m, double y, double k) - throws IOException { - println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m) - + " " + PDFUtil.fixedPrecision(y) + " " - + PDFUtil.fixedPrecision(k) + " K"); - } - - // - // Shading Pattern operator (see Table 4.24) - // - public void shade(PDFName name) throws IOException { - println(name + " sh"); - } - - /** - * returns the decode-format for an image -format - * - * @param encode - * {@link ImageConstants#ZLIB} or {@link ImageConstants#JPG} - * @return {@link #decodeFilters(String[])} - */ - private PDFName[] getFilterName(String encode) { - if (ImageConstants.ZLIB.equals(encode)) { - return decodeFilters(new String[] { ImageConstants.ENCODING_FLATE, - ImageConstants.ENCODING_ASCII85 }); - } - - if (ImageConstants.JPG.equals(encode)) { - return decodeFilters(new String[] { ImageConstants.ENCODING_DCT, - ImageConstants.ENCODING_ASCII85 }); - } - - throw new IllegalArgumentException("unknown image encoding " + encode - + " for PDFStream"); - } - - /** - * Image convenience function (see Table 4.35). Ouputs the data of the image - * using "DeviceRGB" colorspace, and the requested encodings - * - * @param image - * Image to write - * @param bkg - * Background color, null for transparent image - * @param encode - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#ZLIB} or - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#JPG} - * @throws java.io.IOException - * thrown by ImageBytes - */ - public void image(RenderedImage image, Color bkg, String encode) - throws IOException { - - ImageBytes bytes = new ImageBytes(image, bkg, encode, - ImageConstants.COLOR_MODEL_RGB); - - entry("Width", image.getWidth()); - entry("Height", image.getHeight()); - entry("ColorSpace", pdf.name("DeviceRGB")); - entry("BitsPerComponent", 8); - entry("Filter", getFilterName(bytes.getFormat())); - write(bytes.getBytes()); - } - - public void imageMask(RenderedImage image, String encode) - throws IOException { - - ImageBytes bytes = new ImageBytes(image, null, encode, - ImageConstants.COLOR_MODEL_A); - - entry("Width", image.getWidth()); - entry("Height", image.getHeight()); - entry("BitsPerComponent", 8); - entry("ColorSpace", pdf.name("DeviceGray")); - entry("Filter", getFilterName(bytes.getFormat())); - write(bytes.getBytes()); - } - - /** - * Inline Image convenience function (see Table 4.39 and 4.40). Ouputs the - * data of the image using "DeviceRGB" colorspace, and the requested - * encoding. - * - * @param image - * Image to write - * @param bkg - * Background color, null for transparent image - * @param encode - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#ZLIB} or - * {@link org.xmind.org.freehep.graphicsio.ImageConstants#JPG} - * @throws java.io.IOException - * thrown by ImageBytes - */ - public void inlineImage(RenderedImage image, Color bkg, String encode) - throws IOException { - - ImageBytes bytes = new ImageBytes(image, bkg, ImageConstants.JPG, - ImageConstants.COLOR_MODEL_RGB); - - println("BI"); - imageInfo("Width", image.getWidth()); - imageInfo("Height", image.getHeight()); - imageInfo("ColorSpace", pdf.name("DeviceRGB")); - imageInfo("BitsPerComponent", 8); - - imageInfo("Filter", getFilterName(bytes.getFormat())); - print("ID\n"); - - write(bytes.getBytes()); - - println("\nEI"); - } - - // - // In-line Image operators (see Table 4.38) - // - private void imageInfo(String key, int number) throws IOException { - println("/" + key + " " + number); - } - - private void imageInfo(String key, PDFName name) throws IOException { - println("/" + key + " " + name); - } - - private void imageInfo(String key, Object[] array) throws IOException { - print("/" + key + " ["); - for (int i = 0; i < array.length; i++) { - print(" " + array[i]); - } - println("]"); - } - - /** - * Draws the points of the shape using path construction - * operators. The path is neither stroked nor filled. - * - * @return true if even-odd winding rule should be used, false if non-zero - * winding rule should be used. - */ - public boolean drawPath(Shape s) throws IOException { - PDFPathConstructor path = new PDFPathConstructor(this); - return path.addPath(s); - } - - // - // XObject operators (see Table 4.34) - // - public void xObject(PDFName name) throws IOException { - println(name + " Do"); - } - - // - // Marked Content operators (see Table 8.5) - // - // FIXME: missing all - - // - // Compatibility operators (see Table 3.19) - // - private boolean compatibilityOpen = false; - - public void beginCompatibility() throws IOException { - if (compatibilityOpen) - System.err - .println("PDFStream: nested use of Compatibility sections not allowed."); - println("BX"); - compatibilityOpen = true; - } - - public void endCompatibility() throws IOException { - if (!compatibilityOpen) - System.err - .println("PDFStream: unbalanced use of begin/endCompatibilty()."); - println("EX"); - compatibilityOpen = false; - } - -} +// Copyright 2000-2007, FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.awt.Color; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.image.RenderedImage; +import java.io.IOException; +import java.io.OutputStream; + +import org.xmind.org.freehep.graphicsio.ImageConstants; +import org.xmind.org.freehep.util.io.ASCII85OutputStream; +import org.xmind.org.freehep.util.io.ASCIIHexOutputStream; +import org.xmind.org.freehep.util.io.CountedByteOutputStream; +import org.xmind.org.freehep.util.io.FinishableOutputStream; +import org.xmind.org.freehep.util.io.FlateOutputStream; + +/** + * This class allows you to write/print into a PDFStream. Several methods are + * available to specify the content of a page, image. This class performs some + * error checking, while writing the stream. + *

    + * The stream allows to write dictionary entries. The /Length entry is written + * automatically, referencing an object which will also be written just after + * the stream is closed and the length is calculated. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFStream extends PDFDictionary implements PDFConstants { + + private String name; + + private PDFObject object; + + private boolean dictionaryOpen; + + private OutputStream[] stream; + + private CountedByteOutputStream byteCountStream; + + private String[] encode; + + PDFStream(PDF pdf, PDFByteWriter writer, String name, PDFObject parent, + String[] encode) throws IOException { + super(pdf, writer); + this.name = name; + object = parent; + if (object == null) + System.err + .println("PDFWriter: 'PDFStream' cannot have a null parent"); + // first write the dictionary + dictionaryOpen = true; + this.encode = encode; + } + + /** + * Starts the stream, writes out the filters using the preset encoding, and + * encodes the stream. + */ + private void startStream() throws IOException { + startStream(encode); + } + + /** + * Starts the stream, writes out the filters using the given encoding, and + * encodes the stream. + */ + private void startStream(String[] encode) throws IOException { + if (dictionaryOpen) { + PDFName[] filters = decodeFilters(encode); + if (filters != null) + entry("Filter", filters); + + super.close(); + dictionaryOpen = false; + out.printPlain("stream\n"); + + byteCountStream = new CountedByteOutputStream(out); + stream = openFilters(byteCountStream, encode); + } + } + + private void write(int b) throws IOException { + startStream(); + stream[0].write(b); + } + + private void write(byte[] b) throws IOException { + for (int i = 0; i < b.length; i++) { + write((int) b[i]); + } + } + + private static PDFName[] decodeFilters(String[] encode) { + PDFName[] filters = null; + if ((encode != null) && (encode.length != 0)) { + filters = new PDFName[encode.length]; + for (int i = 0; i < filters.length; i++) { + filters[i] = new PDFName(encode[encode.length - i - 1] + + "Decode"); + } + } + return filters; + } + + // open new stream using Standard Filters (see table 3.5) + // stream[0] is the one to write to, the last one is s + private static OutputStream[] openFilters(OutputStream s, String[] filters) { + OutputStream[] os; + if ((filters != null) && (filters.length != 0)) { + os = new OutputStream[filters.length + 1]; + os[os.length - 1] = s; + for (int i = os.length - 2; i >= 0; i--) { + if (filters[i].equals("ASCIIHex")) { + os[i] = new ASCIIHexOutputStream(os[i + 1]); + } else if (filters[i].equals("ASCII85")) { + os[i] = new ASCII85OutputStream(os[i + 1]); + } else if (filters[i].equals("Flate")) { + os[i] = new FlateOutputStream(os[i + 1]); + } else if (filters[i].equals("DCT")) { + os[i] = os[i + 1]; + } else { + System.err.println("PDFWriter: unknown stream format: " + + filters[i]); + } + } + } else { + os = new OutputStream[1]; + os[0] = s; + } + return os; + } + + // stream[0] is the first one to finish, the last one is not finished + private static void closeFilters(OutputStream[] s) throws IOException { + for (int i = 0; i < s.length - 1; i++) { + s[i].flush(); + if (s[i] instanceof FinishableOutputStream) { + ((FinishableOutputStream) s[i]).finish(); + } + } + s[s.length - 1].flush(); + } + + private void write(String s) throws IOException { + byte[] b = s.getBytes("ISO-8859-1"); + for (int i = 0; i < b.length; i++) { + write(b[i]); + } + } + + void close() throws IOException { + closeFilters(stream); + stream = null; + out.printPlain("\nendstream"); + out.println(); + object.close(); + + if (gStates > 0) { + System.err + .println("PDFStream: unbalanced saves()/restores(), too many saves: " + + gStates); + } + } + + String getName() { + return name; + } + + public int getLength() { + return byteCountStream.getCount(); + } + + public void print(String s) throws IOException { + write(s); + } + + public void println(String s) throws IOException { + write(s); + write(EOL); + } + + public void comment(String comment) throws IOException { + println("% " + comment); + } + + // ========================================================================== + // PDFStream Operators according to Table 4.1 + // ========================================================================== + + // + // Graphics State operators (see Table 4.7) + // + private int gStates = 0; + + public void save() throws IOException { + println("q"); + gStates++; + } + + public void restore() throws IOException { + if (gStates <= 0) { + System.err + .println("PDFStream: unbalanced saves()/restores(), too many restores"); + } + gStates--; + println("Q"); + } + + public void matrix(AffineTransform xform) throws IOException { + matrix(xform.getScaleX(), xform.getShearY(), xform.getShearX(), + xform.getScaleY(), xform.getTranslateX(), xform.getTranslateY()); + } + + public void matrix(double m00, double m10, double m01, double m11, + double m02, double m12) throws IOException { + println(PDFUtil.fixedPrecision(m00) + " " + PDFUtil.fixedPrecision(m10) + + " " + PDFUtil.fixedPrecision(m01) + " " + + PDFUtil.fixedPrecision(m11) + " " + + PDFUtil.fixedPrecision(m02) + " " + + PDFUtil.fixedPrecision(m12) + " cm"); + } + + public void width(double width) throws IOException { + println(PDFUtil.fixedPrecision(width) + " w"); + } + + public void cap(int capStyle) throws IOException { + println(capStyle + " J"); + } + + public void join(int joinStyle) throws IOException { + println(joinStyle + " j"); + } + + public void miterLimit(double limit) throws IOException { + println(PDFUtil.fixedPrecision(limit) + " M"); + } + + public void dash(int[] dash, double phase) throws IOException { + print("["); + for (int i = 0; i < dash.length; i++) { + print(" " + PDFUtil.fixedPrecision(dash[i])); + } + println("] " + PDFUtil.fixedPrecision(phase) + " d"); + } + + public void dash(float[] dash, double phase) throws IOException { + print("["); + for (int i = 0; i < dash.length; i++) { + print(" " + PDFUtil.fixedPrecision(dash[i])); + } + println("] " + PDFUtil.fixedPrecision(phase) + " d"); + } + + public void flatness(double flatness) throws IOException { + println(PDFUtil.fixedPrecision(flatness) + " i"); + } + + public void state(PDFName stateDictionary) throws IOException { + println(stateDictionary + " gs"); + } + + // + // Path Construction operators (see Table 4.9) + // + public void cubic(double x1, double y1, double x2, double y2, double x3, + double y3) throws IOException { + println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1) + + " " + PDFUtil.fixedPrecision(x2) + " " + + PDFUtil.fixedPrecision(y2) + " " + PDFUtil.fixedPrecision(x3) + + " " + PDFUtil.fixedPrecision(y3) + " c"); + } + + public void cubicV(double x2, double y2, double x3, double y3) + throws IOException { + println(PDFUtil.fixedPrecision(x2) + " " + PDFUtil.fixedPrecision(y2) + + " " + PDFUtil.fixedPrecision(x3) + " " + + PDFUtil.fixedPrecision(y3) + " v"); + } + + public void cubicY(double x1, double y1, double x3, double y3) + throws IOException { + println(PDFUtil.fixedPrecision(x1) + " " + PDFUtil.fixedPrecision(y1) + + " " + PDFUtil.fixedPrecision(x3) + " " + + PDFUtil.fixedPrecision(y3) + " y"); + } + + public void move(double x, double y) throws IOException { + println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) + + " m"); + } + + public void line(double x, double y) throws IOException { + println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) + + " l"); + } + + public void closePath() throws IOException { + println("h"); + } + + public void rectangle(double x, double y, double width, double height) + throws IOException { + println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) + + " " + PDFUtil.fixedPrecision(width) + " " + + PDFUtil.fixedPrecision(height) + " re"); + } + + // + // Path Painting operators (see Table 4.10) + // + public void stroke() throws IOException { + println("S"); + } + + public void closeAndStroke() throws IOException { + println("s"); + } + + public void fill() throws IOException { + println("f"); + } + + public void fillEvenOdd() throws IOException { + println("f*"); + } + + public void fillAndStroke() throws IOException { + println("B"); + } + + public void fillEvenOddAndStroke() throws IOException { + println("B*"); + } + + public void closeFillAndStroke() throws IOException { + println("b"); + } + + public void closeFillEvenOddAndStroke() throws IOException { + println("b*"); + } + + public void endPath() throws IOException { + println("n"); + } + + // + // Clipping Path operators (see Table 4.11) + // + public void clip() throws IOException { + println("W"); + } + + public void clipEvenOdd() throws IOException { + println("W*"); + } + + // + // Text Object operators (see Table 5.4) + // + private boolean textOpen = false; + + public void beginText() throws IOException { + if (textOpen) + System.err.println("PDFStream: nested beginText() not allowed."); + println("BT"); + textOpen = true; + } + + public void endText() throws IOException { + if (!textOpen) + System.err + .println("PDFStream: unbalanced use of beginText()/endText()."); + println("ET"); + textOpen = false; + } + + // + // Text State operators (see Table 5.2) + // + public void charSpace(double charSpace) throws IOException { + println(PDFUtil.fixedPrecision(charSpace) + " Tc"); + } + + public void wordSpace(double wordSpace) throws IOException { + println(PDFUtil.fixedPrecision(wordSpace) + " Tw"); + } + + public void scale(double scale) throws IOException { + println(PDFUtil.fixedPrecision(scale) + " Tz"); + } + + public void leading(double leading) throws IOException { + println(PDFUtil.fixedPrecision(leading) + " TL"); + } + + private boolean fontWasSet = false; + + public void font(PDFName fontName, double size) throws IOException { + println(fontName + " " + PDFUtil.fixedPrecision(size) + " Tf"); + fontWasSet = true; + } + + public void rendering(int mode) throws IOException { + println(mode + " Tr"); + } + + public void rise(double rise) throws IOException { + println(PDFUtil.fixedPrecision(rise) + " Ts"); + } + + // + // Text Positioning operators (see Table 5.5) + // + public void text(double x, double y) throws IOException { + println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) + + " Td"); + } + + public void textLeading(double x, double y) throws IOException { + println(PDFUtil.fixedPrecision(x) + " " + PDFUtil.fixedPrecision(y) + + " TD"); + } + + public void textMatrix(double a, double b, double c, double d, double e, + double f) throws IOException { + println(PDFUtil.fixedPrecision(a) + " " + PDFUtil.fixedPrecision(b) + + " " + PDFUtil.fixedPrecision(c) + " " + + PDFUtil.fixedPrecision(d) + " " + PDFUtil.fixedPrecision(e) + + " " + PDFUtil.fixedPrecision(f) + " Tm"); + } + + public void textLine() throws IOException { + println("T*"); + } + + // + // Text Showing operators (see Table 5.6) + // + public void show(String text) throws IOException { + if (!fontWasSet) + System.err + .println("PDFStream: cannot use Text Showing operator before font is set."); + if (!textOpen) + System.err + .println("PDFStream: Text Showing operator only allowed inside Text section."); + println("(" + PDFUtil.escape(text) + ") Tj"); + } + + public void showLine(String text) throws IOException { + if (!fontWasSet) + System.err + .println("PDFStream: cannot use Text Showing operator before font is set."); + if (!textOpen) + System.err + .println("PDFStream: Text Showing operator only allowed inside Text section."); + println("(" + PDFUtil.escape(text) + ") '"); + } + + public void showLine(double wordSpace, double charSpace, String text) + throws IOException { + if (!fontWasSet) + System.err + .println("PDFStream: cannot use Text Showing operator before font is set."); + if (!textOpen) + System.err + .println("PDFStream: Text Showing operator only allowed inside Text section."); + println(PDFUtil.fixedPrecision(wordSpace) + " " + + PDFUtil.fixedPrecision(charSpace) + " (" + + PDFUtil.escape(text) + ") \""); + } + + public void show(Object[] array) throws IOException { + print("["); + for (int i = 0; i < array.length; i++) { + Object object = array[i]; + if (object instanceof String) { + print(" (" + PDFUtil.escape(object.toString()) + ")"); + } else if (object instanceof Integer) { + print(" " + ((Integer) object).intValue()); + } else if (object instanceof Double) { + print(" " + ((Double) object).doubleValue()); + } else { + System.err + .println("PDFStream: input array of operator TJ may only contain objects of type 'String', 'Integer' or 'Double'"); + } + } + println("] TJ"); + } + + // + // Type 3 Font operators (see Table 5.10) + // + public void glyph(double wx, double wy) throws IOException { + println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy) + + " d0"); + } + + public void glyph(double wx, double wy, double llx, double lly, double urx, + double ury) throws IOException { + println(PDFUtil.fixedPrecision(wx) + " " + PDFUtil.fixedPrecision(wy) + + " " + PDFUtil.fixedPrecision(llx) + " " + + PDFUtil.fixedPrecision(lly) + " " + + PDFUtil.fixedPrecision(urx) + " " + + PDFUtil.fixedPrecision(ury) + " d1"); + } + + // + // Color operators (see Table 4.21) + // + public void colorSpace(PDFName colorSpace) throws IOException { + println(colorSpace + " cs"); + } + + public void colorSpaceStroke(PDFName colorSpace) throws IOException { + println(colorSpace + " CS"); + } + + public void colorSpace(double[] color) throws IOException { + for (int i = 0; i < color.length; i++) { + print(" " + color[i]); + } + println(" scn"); + } + + public void colorSpaceStroke(double[] color) throws IOException { + for (int i = 0; i < color.length; i++) { + print(" " + color[i]); + } + println(" SCN"); + } + + public void colorSpace(double[] color, PDFName name) throws IOException { + if (color != null) { + for (int i = 0; i < color.length; i++) { + print(PDFUtil.fixedPrecision(color[i]) + " "); + } + } + println(name + " scn"); + } + + public void colorSpaceStroke(double[] color, PDFName name) + throws IOException { + if (color != null) { + for (int i = 0; i < color.length; i++) { + print(PDFUtil.fixedPrecision(color[i]) + " "); + } + } + println(name + " SCN"); + } + + public void colorSpace(double g) throws IOException { + println(PDFUtil.fixedPrecision(g) + " g"); + } + + public void colorSpaceStroke(double g) throws IOException { + println(PDFUtil.fixedPrecision(g) + " G"); + } + + public void colorSpace(double r, double g, double b) throws IOException { + println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g) + + " " + PDFUtil.fixedPrecision(b) + " rg"); + } + + public void colorSpaceStroke(double r, double g, double b) + throws IOException { + println(PDFUtil.fixedPrecision(r) + " " + PDFUtil.fixedPrecision(g) + + " " + PDFUtil.fixedPrecision(b) + " RG"); + } + + public void colorSpace(double c, double m, double y, double k) + throws IOException { + println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m) + + " " + PDFUtil.fixedPrecision(y) + " " + + PDFUtil.fixedPrecision(k) + " k"); + } + + public void colorSpaceStroke(double c, double m, double y, double k) + throws IOException { + println(PDFUtil.fixedPrecision(c) + " " + PDFUtil.fixedPrecision(m) + + " " + PDFUtil.fixedPrecision(y) + " " + + PDFUtil.fixedPrecision(k) + " K"); + } + + // + // Shading Pattern operator (see Table 4.24) + // + public void shade(PDFName name) throws IOException { + println(name + " sh"); + } + + /** + * returns the decode-format for an image -format + * + * @param encode + * {@link ImageConstants#ZLIB} or {@link ImageConstants#JPG} + * @return {@link #decodeFilters(String[])} + */ + private PDFName[] getFilterName(String encode) { + if (ImageConstants.ZLIB.equals(encode)) { + return decodeFilters(new String[] { ImageConstants.ENCODING_FLATE, + ImageConstants.ENCODING_ASCII85 }); + } + + if (ImageConstants.JPG.equals(encode)) { + return decodeFilters(new String[] { ImageConstants.ENCODING_DCT, + ImageConstants.ENCODING_ASCII85 }); + } + + throw new IllegalArgumentException("unknown image encoding " + encode + + " for PDFStream"); + } + + /** + * Image convenience function (see Table 4.35). Ouputs the data of the image + * using "DeviceRGB" colorspace, and the requested encodings + * + * @param image + * Image to write + * @param bkg + * Background color, null for transparent image + * @param encode + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#ZLIB} or + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#JPG} + * @throws java.io.IOException + * thrown by ImageBytes + */ + public void image(RenderedImage image, Color bkg, String encode) + throws IOException { + + ImageBytes bytes = new ImageBytes(image, bkg, encode, + ImageConstants.COLOR_MODEL_RGB); + + entry("Width", image.getWidth()); + entry("Height", image.getHeight()); + entry("ColorSpace", pdf.name("DeviceRGB")); + entry("BitsPerComponent", 8); + entry("Filter", getFilterName(bytes.getFormat())); + write(bytes.getBytes()); + } + + public void imageMask(RenderedImage image, String encode) + throws IOException { + + ImageBytes bytes = new ImageBytes(image, null, encode, + ImageConstants.COLOR_MODEL_A); + + entry("Width", image.getWidth()); + entry("Height", image.getHeight()); + entry("BitsPerComponent", 8); + entry("ColorSpace", pdf.name("DeviceGray")); + entry("Filter", getFilterName(bytes.getFormat())); + write(bytes.getBytes()); + } + + /** + * Inline Image convenience function (see Table 4.39 and 4.40). Ouputs the + * data of the image using "DeviceRGB" colorspace, and the requested + * encoding. + * + * @param image + * Image to write + * @param bkg + * Background color, null for transparent image + * @param encode + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#ZLIB} or + * {@link org.xmind.org.freehep.graphicsio.ImageConstants#JPG} + * @throws java.io.IOException + * thrown by ImageBytes + */ + public void inlineImage(RenderedImage image, Color bkg, String encode) + throws IOException { + + ImageBytes bytes = new ImageBytes(image, bkg, ImageConstants.JPG, + ImageConstants.COLOR_MODEL_RGB); + + println("BI"); + imageInfo("Width", image.getWidth()); + imageInfo("Height", image.getHeight()); + imageInfo("ColorSpace", pdf.name("DeviceRGB")); + imageInfo("BitsPerComponent", 8); + + imageInfo("Filter", getFilterName(bytes.getFormat())); + print("ID\n"); + + write(bytes.getBytes()); + + println("\nEI"); + } + + // + // In-line Image operators (see Table 4.38) + // + private void imageInfo(String key, int number) throws IOException { + println("/" + key + " " + number); + } + + private void imageInfo(String key, PDFName name) throws IOException { + println("/" + key + " " + name); + } + + private void imageInfo(String key, Object[] array) throws IOException { + print("/" + key + " ["); + for (int i = 0; i < array.length; i++) { + print(" " + array[i]); + } + println("]"); + } + + /** + * Draws the points of the shape using path construction + * operators. The path is neither stroked nor filled. + * + * @return true if even-odd winding rule should be used, false if non-zero + * winding rule should be used. + */ + public boolean drawPath(Shape s) throws IOException { + PDFPathConstructor path = new PDFPathConstructor(this); + return path.addPath(s); + } + + // + // XObject operators (see Table 4.34) + // + public void xObject(PDFName name) throws IOException { + println(name + " Do"); + } + + // + // Marked Content operators (see Table 8.5) + // + // FIXME: missing all + + // + // Compatibility operators (see Table 3.19) + // + private boolean compatibilityOpen = false; + + public void beginCompatibility() throws IOException { + if (compatibilityOpen) + System.err + .println("PDFStream: nested use of Compatibility sections not allowed."); + println("BX"); + compatibilityOpen = true; + } + + public void endCompatibility() throws IOException { + if (!compatibilityOpen) + System.err + .println("PDFStream: unbalanced use of begin/endCompatibilty()."); + println("EX"); + compatibilityOpen = false; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFUtil.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFUtil.java index 36485a88b..629f4376b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFUtil.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFUtil.java @@ -1,71 +1,71 @@ -// Copyright 2004, FreeHEP. -package org.xmind.org.freehep.graphicsio.pdf; - -import java.text.DecimalFormat; -import java.util.Calendar; - -import org.xmind.org.freehep.util.ScientificFormat; - -/** - * Utility functions for the PDFWriter. This class handles escaping of strings, - * formatting of dates, ... - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class PDFUtil implements PDFConstants { - - // static class - private PDFUtil() { - } - - public static String escape(String string) { - StringBuffer escape = new StringBuffer(); - - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - switch (c) { - case '(': - case ')': - case '\\': - escape.append('\\'); - escape.append(c); - break; - default: - escape.append(c); - break; - } - } - return escape.toString(); - } - - @SuppressWarnings("nls") - public static String date(Calendar date) { - int offset = date.get(Calendar.ZONE_OFFSET) - + date.get(Calendar.DST_OFFSET); - - String tz; - if (offset == 0) { - tz = "Z"; - } else { - DecimalFormat fmt = new DecimalFormat("00"); - int tzh = Math.abs(offset / 3600000); - int tzm = Math.abs(offset % 3600000); - if (offset > 0) { - tz = "+" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; - } else { - tz = "-" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; - } - } - return "(D:" + dateFormat.format(date.getTime()) + tz + ")"; - } - - private static final ScientificFormat scientific = new ScientificFormat(5, - 100, false); - - public static String fixedPrecision(double v) { - return scientific.format(v); - } - -} +// Copyright 2004, FreeHEP. +package org.xmind.org.freehep.graphicsio.pdf; + +import java.text.DecimalFormat; +import java.util.Calendar; + +import org.xmind.org.freehep.util.ScientificFormat; + +/** + * Utility functions for the PDFWriter. This class handles escaping of strings, + * formatting of dates, ... + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class PDFUtil implements PDFConstants { + + // static class + private PDFUtil() { + } + + public static String escape(String string) { + StringBuffer escape = new StringBuffer(); + + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); + switch (c) { + case '(': + case ')': + case '\\': + escape.append('\\'); + escape.append(c); + break; + default: + escape.append(c); + break; + } + } + return escape.toString(); + } + + @SuppressWarnings("nls") + public static String date(Calendar date) { + int offset = date.get(Calendar.ZONE_OFFSET) + + date.get(Calendar.DST_OFFSET); + + String tz; + if (offset == 0) { + tz = "Z"; + } else { + DecimalFormat fmt = new DecimalFormat("00"); + int tzh = Math.abs(offset / 3600000); + int tzm = Math.abs(offset % 3600000); + if (offset > 0) { + tz = "+" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; + } else { + tz = "-" + fmt.format(tzh) + "'" + fmt.format(tzm) + "'"; + } + } + return "(D:" + dateFormat.format(date.getTime()) + tz + ")"; + } + + private static final ScientificFormat scientific = new ScientificFormat(5, + 100, false); + + public static String fixedPrecision(double v) { + return scientific.format(v); + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFViewerPreferences.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFViewerPreferences.java index 413f2b8b3..3071af6cc 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFViewerPreferences.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFViewerPreferences.java @@ -1,47 +1,47 @@ -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; - -/** - * Implements the Viewer Preferences (see Table 7.1). - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFViewerPreferences extends PDFDictionary { - - PDFViewerPreferences(PDF pdf, PDFByteWriter writer, PDFObject object) - throws IOException { - super(pdf, writer, object); - } - - public void setHideToolbar(boolean hide) throws IOException { - entry("HideToolbar", hide); - } - - public void setHideMenubar(boolean hide) throws IOException { - entry("HideMenubar", hide); - } - - public void setHideWindowUI(boolean hide) throws IOException { - entry("HideWindowUI", hide); - } - - public void setFitWindow(boolean fit) throws IOException { - entry("FitWindow", fit); - } - - public void setCenterWindow(boolean center) throws IOException { - entry("CenterWindow", center); - } - - public void setNonFullScreenPageMode(String mode) throws IOException { - entry("NonFullScreenPageMode", pdf.name(mode)); - } - - public void setDirection(String direction) throws IOException { - entry("Direction", pdf.name(direction)); - } -} +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; + +/** + * Implements the Viewer Preferences (see Table 7.1). + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFViewerPreferences extends PDFDictionary { + + PDFViewerPreferences(PDF pdf, PDFByteWriter writer, PDFObject object) + throws IOException { + super(pdf, writer, object); + } + + public void setHideToolbar(boolean hide) throws IOException { + entry("HideToolbar", hide); + } + + public void setHideMenubar(boolean hide) throws IOException { + entry("HideMenubar", hide); + } + + public void setHideWindowUI(boolean hide) throws IOException { + entry("HideWindowUI", hide); + } + + public void setFitWindow(boolean fit) throws IOException { + entry("FitWindow", fit); + } + + public void setCenterWindow(boolean center) throws IOException { + entry("CenterWindow", center); + } + + public void setNonFullScreenPageMode(String mode) throws IOException { + entry("NonFullScreenPageMode", pdf.name(mode)); + } + + public void setDirection(String direction) throws IOException { + entry("Direction", pdf.name(direction)); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFWriter.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFWriter.java index 89bfaa7b1..9ab79a626 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFWriter.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/pdf/PDFWriter.java @@ -1,227 +1,227 @@ -// Copyright 2000-2005 FreeHEP -package org.xmind.org.freehep.graphicsio.pdf; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * This class creates a PDF file/stream. It keeps track of all logical PDF - * objects in the PDF file, will create a cross-reference table and do some - * error checking while writing the file. - *

    - * This class takes care of wrapping both PDFStreams and PDFDictionaries into - * PDFObjects. - *

    - * - * @author Mark Donszelmann - * @author Jason Wong - */ -@SuppressWarnings("nls") -public class PDFWriter extends PDF implements PDFConstants { - - private String open = null; - - public PDFWriter(OutputStream out) throws IOException { - this(out, "1.3"); - } - - public PDFWriter(OutputStream writer, String version) throws IOException { - super(new PDFByteWriter(writer)); - - // PDF version - out.println("%PDF-" + version); - - // Make sure intelligent readers understand that binary may be included - out.print("%"); - out.write(0xE2); - out.write(0xE3); - out.write(0xCF); - out.write(0xD3); - out.println(); - out.println(); - } - - public void close(String catalogName, String docInfoName) - throws IOException { - // FIXME, check for dangling references - - xref(); - trailer(catalogName, docInfoName); - startxref(); - out.printPlain("%%EOF"); - out.println(); - out.close(); - } - - public void comment(String comment) throws IOException { - out.println("% " + comment); - } - - public void object(String name, Object[] objs) throws IOException { - PDFObject object = openObject(name); - object.entry(objs); - close(object); - } - - public void object(String name, int number) throws IOException { - PDFObject object = openObject(name); - object.entry(number); - close(object); - } - - // public void object(String name, String string) throws IOException { - // PDFObject object = openObject(name); - // object.entry(string); - // close(object); - // } - - public PDFObject openObject(String name) throws IOException { - // FIXME: check if name was already written! - if (open != null) - System.err - .println("PDFWriter error: '" + open + "' was not closed"); - open = "PDFObject: " + name; - - PDFRef ref = ref(name); - int objectNumber = ref.getObjectNumber(); - - setXRef(objectNumber, out.getCount()); - PDFObject obj = new PDFObject(this, out, objectNumber, - ref.getGenerationNumber()); - return obj; - } - - public void close(PDFObject object) throws IOException { - object.close(); - open = null; - } - - public PDFDictionary openDictionary(String name) throws IOException { - PDFObject object = openObject(name); - PDFDictionary dictionary = object.openDictionary(); - return dictionary; - } - - public void close(PDFDictionary dictionary) throws IOException { - dictionary.close(); - open = null; - } - - private static final String lengthSuffix = "-length"; - - public PDFStream openStream(String name) throws IOException { - return openStream(name, null); - } - - public PDFStream openStream(String name, String[] encode) - throws IOException { - PDFObject object = openObject(name); - PDFStream stream = object.openStream(name, encode); - stream.entry("Length", ref(name + lengthSuffix)); - return stream; - } - - public void close(PDFStream stream) throws IOException { - stream.close(); - open = null; - object(stream.getName() + lengthSuffix, stream.getLength()); - } - - // - // high level interface - // - private String catalogName; - - private String docInfoName; - - public void close() throws IOException { - close(catalogName, docInfoName); - } - - public PDFDocInfo openDocInfo(String name) throws IOException { - docInfoName = name; - PDFObject object = openObject(name); - PDFDocInfo info = object.openDocInfo(this); - return info; - } - - public void close(PDFDocInfo info) throws IOException { - info.close(); - open = null; - } - - public PDFCatalog openCatalog(String name, String pageTree) - throws IOException { - catalogName = name; - PDFObject object = openObject(name); - PDFCatalog catalog = object.openCatalog(this, ref(pageTree)); - return catalog; - } - - public void close(PDFCatalog catalog) throws IOException { - catalog.close(); - open = null; - } - - public PDFPageTree openPageTree(String name, String parent) - throws IOException { - PDFObject object = openObject(name); - PDFPageTree tree = object.openPageTree(this, ref(parent)); - return tree; - } - - public void close(PDFPageTree tree) throws IOException { - tree.close(); - open = null; - } - - public PDFPage openPage(String name, String parent) throws IOException { - PDFObject object = openObject(name); - PDFPage page = object.openPage(this, ref(parent)); - return page; - } - - public void close(PDFPage page) throws IOException { - page.close(); - open = null; - } - - public PDFViewerPreferences openViewerPreferences(String name) - throws IOException { - PDFObject object = openObject(name); - PDFViewerPreferences prefs = object.openViewerPreferences(this); - return prefs; - } - - public void close(PDFViewerPreferences prefs) throws IOException { - prefs.close(); - open = null; - } - - public PDFOutlineList openOutlineList(String name, String first, String next) - throws IOException { - PDFObject object = openObject(name); - PDFOutlineList list = object.openOutlineList(this, ref(first), - ref(next)); - return list; - } - - public void close(PDFOutlineList list) throws IOException { - list.close(); - open = null; - } - - public PDFOutline openOutline(String name, String title, String parent, - String prev, String next) throws IOException { - PDFObject object = openObject(name); - PDFOutline outline = object.openOutline(this, ref(parent), title, - ref(prev), ref(next)); - return outline; - } - - public void close(PDFOutline outline) throws IOException { - outline.close(); - open = null; - } - -} +// Copyright 2000-2005 FreeHEP +package org.xmind.org.freehep.graphicsio.pdf; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * This class creates a PDF file/stream. It keeps track of all logical PDF + * objects in the PDF file, will create a cross-reference table and do some + * error checking while writing the file. + *

    + * This class takes care of wrapping both PDFStreams and PDFDictionaries into + * PDFObjects. + *

    + * + * @author Mark Donszelmann + * @author Jason Wong + */ +@SuppressWarnings("nls") +public class PDFWriter extends PDF implements PDFConstants { + + private String open = null; + + public PDFWriter(OutputStream out) throws IOException { + this(out, "1.3"); + } + + public PDFWriter(OutputStream writer, String version) throws IOException { + super(new PDFByteWriter(writer)); + + // PDF version + out.println("%PDF-" + version); + + // Make sure intelligent readers understand that binary may be included + out.print("%"); + out.write(0xE2); + out.write(0xE3); + out.write(0xCF); + out.write(0xD3); + out.println(); + out.println(); + } + + public void close(String catalogName, String docInfoName) + throws IOException { + // FIXME, check for dangling references + + xref(); + trailer(catalogName, docInfoName); + startxref(); + out.printPlain("%%EOF"); + out.println(); + out.close(); + } + + public void comment(String comment) throws IOException { + out.println("% " + comment); + } + + public void object(String name, Object[] objs) throws IOException { + PDFObject object = openObject(name); + object.entry(objs); + close(object); + } + + public void object(String name, int number) throws IOException { + PDFObject object = openObject(name); + object.entry(number); + close(object); + } + + // public void object(String name, String string) throws IOException { + // PDFObject object = openObject(name); + // object.entry(string); + // close(object); + // } + + public PDFObject openObject(String name) throws IOException { + // FIXME: check if name was already written! + if (open != null) + System.err + .println("PDFWriter error: '" + open + "' was not closed"); + open = "PDFObject: " + name; + + PDFRef ref = ref(name); + int objectNumber = ref.getObjectNumber(); + + setXRef(objectNumber, out.getCount()); + PDFObject obj = new PDFObject(this, out, objectNumber, + ref.getGenerationNumber()); + return obj; + } + + public void close(PDFObject object) throws IOException { + object.close(); + open = null; + } + + public PDFDictionary openDictionary(String name) throws IOException { + PDFObject object = openObject(name); + PDFDictionary dictionary = object.openDictionary(); + return dictionary; + } + + public void close(PDFDictionary dictionary) throws IOException { + dictionary.close(); + open = null; + } + + private static final String lengthSuffix = "-length"; + + public PDFStream openStream(String name) throws IOException { + return openStream(name, null); + } + + public PDFStream openStream(String name, String[] encode) + throws IOException { + PDFObject object = openObject(name); + PDFStream stream = object.openStream(name, encode); + stream.entry("Length", ref(name + lengthSuffix)); + return stream; + } + + public void close(PDFStream stream) throws IOException { + stream.close(); + open = null; + object(stream.getName() + lengthSuffix, stream.getLength()); + } + + // + // high level interface + // + private String catalogName; + + private String docInfoName; + + public void close() throws IOException { + close(catalogName, docInfoName); + } + + public PDFDocInfo openDocInfo(String name) throws IOException { + docInfoName = name; + PDFObject object = openObject(name); + PDFDocInfo info = object.openDocInfo(this); + return info; + } + + public void close(PDFDocInfo info) throws IOException { + info.close(); + open = null; + } + + public PDFCatalog openCatalog(String name, String pageTree) + throws IOException { + catalogName = name; + PDFObject object = openObject(name); + PDFCatalog catalog = object.openCatalog(this, ref(pageTree)); + return catalog; + } + + public void close(PDFCatalog catalog) throws IOException { + catalog.close(); + open = null; + } + + public PDFPageTree openPageTree(String name, String parent) + throws IOException { + PDFObject object = openObject(name); + PDFPageTree tree = object.openPageTree(this, ref(parent)); + return tree; + } + + public void close(PDFPageTree tree) throws IOException { + tree.close(); + open = null; + } + + public PDFPage openPage(String name, String parent) throws IOException { + PDFObject object = openObject(name); + PDFPage page = object.openPage(this, ref(parent)); + return page; + } + + public void close(PDFPage page) throws IOException { + page.close(); + open = null; + } + + public PDFViewerPreferences openViewerPreferences(String name) + throws IOException { + PDFObject object = openObject(name); + PDFViewerPreferences prefs = object.openViewerPreferences(this); + return prefs; + } + + public void close(PDFViewerPreferences prefs) throws IOException { + prefs.close(); + open = null; + } + + public PDFOutlineList openOutlineList(String name, String first, String next) + throws IOException { + PDFObject object = openObject(name); + PDFOutlineList list = object.openOutlineList(this, ref(first), + ref(next)); + return list; + } + + public void close(PDFOutlineList list) throws IOException { + list.close(); + open = null; + } + + public PDFOutline openOutline(String name, String title, String parent, + String prev, String next) throws IOException { + PDFObject object = openObject(name); + PDFOutline outline = object.openOutline(this, ref(parent), title, + ref(prev), ref(next)); + return outline; + } + + public void close(PDFOutline outline) throws IOException { + outline.close(); + open = null; + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriteParam.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriteParam.java index e608d15d6..54562f7a2 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriteParam.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriteParam.java @@ -1,71 +1,71 @@ -// Copyright 2003, FreeHEP -package org.xmind.org.freehep.graphicsio.raw; - -import java.awt.Color; -import java.util.Locale; -import java.util.Properties; - -import javax.imageio.ImageWriteParam; - -import org.xmind.org.freehep.graphicsio.ImageParamConverter; -import org.xmind.org.freehep.util.UserProperties; - -/** - * @author Jason Wong - */ -public class RawImageWriteParam extends ImageWriteParam implements - ImageParamConverter { - - private final static String rootKey = RawImageWriteParam.class.getName(); - - public final static String BACKGROUND = rootKey + ".Background"; //$NON-NLS-1$ - - public final static String CODE = rootKey + ".Code"; //$NON-NLS-1$ - - public final static String PAD = rootKey + ".Pad"; //$NON-NLS-1$ - - private Color bkg; - - private String code; - - private int pad; - - public RawImageWriteParam(Locale locale) { - super(locale); - bkg = null; - code = "ARGB"; //$NON-NLS-1$ - pad = 1; - } - - public ImageWriteParam getWriteParam(Properties properties) { - UserProperties p = new UserProperties(properties); - setBackground(p.getPropertyColor(BACKGROUND, bkg)); - setCode(p.getProperty(CODE, code)); - setPad(p.getPropertyInt(PAD, pad)); - return this; - } - - public Color getBackground() { - return bkg; - } - - public void setBackground(Color bkg) { - this.bkg = bkg; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public int getPad() { - return pad; - } - - public void setPad(int pad) { - this.pad = pad; - } -} +// Copyright 2003, FreeHEP +package org.xmind.org.freehep.graphicsio.raw; + +import java.awt.Color; +import java.util.Locale; +import java.util.Properties; + +import javax.imageio.ImageWriteParam; + +import org.xmind.org.freehep.graphicsio.ImageParamConverter; +import org.xmind.org.freehep.util.UserProperties; + +/** + * @author Jason Wong + */ +public class RawImageWriteParam extends ImageWriteParam implements + ImageParamConverter { + + private final static String rootKey = RawImageWriteParam.class.getName(); + + public final static String BACKGROUND = rootKey + ".Background"; //$NON-NLS-1$ + + public final static String CODE = rootKey + ".Code"; //$NON-NLS-1$ + + public final static String PAD = rootKey + ".Pad"; //$NON-NLS-1$ + + private Color bkg; + + private String code; + + private int pad; + + public RawImageWriteParam(Locale locale) { + super(locale); + bkg = null; + code = "ARGB"; //$NON-NLS-1$ + pad = 1; + } + + public ImageWriteParam getWriteParam(Properties properties) { + UserProperties p = new UserProperties(properties); + setBackground(p.getPropertyColor(BACKGROUND, bkg)); + setCode(p.getProperty(CODE, code)); + setPad(p.getPropertyInt(PAD, pad)); + return this; + } + + public Color getBackground() { + return bkg; + } + + public void setBackground(Color bkg) { + this.bkg = bkg; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public int getPad() { + return pad; + } + + public void setPad(int pad) { + this.pad = pad; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriter.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriter.java index 440d40984..e0caf8b01 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriter.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriter.java @@ -1,73 +1,73 @@ -// Copyright 2003, FreeHEP -package org.xmind.org.freehep.graphicsio.raw; - -import java.awt.image.RenderedImage; -import java.io.IOException; - -import javax.imageio.IIOImage; -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.stream.ImageOutputStream; - -import org.xmind.org.freehep.util.images.ImageUtilities; - -/** - * - * @author Jason Wong - */ -public class RawImageWriter extends ImageWriter { - - public RawImageWriter(RawImageWriterSpi originatingProvider) { - super(originatingProvider); - } - - public void write(IIOMetadata streamMetadata, IIOImage image, - ImageWriteParam param) throws IOException { - if (image == null) - throw new IllegalArgumentException("image == null"); //$NON-NLS-1$ - - if (image.hasRaster()) - throw new UnsupportedOperationException("Cannot write rasters"); //$NON-NLS-1$ - - Object output = getOutput(); - if (output == null) - throw new IllegalStateException("output was not set"); //$NON-NLS-1$ - - if (param == null) - param = getDefaultWriteParam(); - - ImageOutputStream ios = (ImageOutputStream) output; - RenderedImage ri = image.getRenderedImage(); - - RawImageWriteParam rawParam = (RawImageWriteParam) param; - byte[] bytes = ImageUtilities.getBytes(ri, rawParam.getBackground(), - rawParam.getCode(), rawParam.getPad()); - ios.write(bytes); - ios.close(); - } - - public IIOMetadata convertStreamMetadata(IIOMetadata inData, - ImageWriteParam param) { - return null; - } - - public IIOMetadata convertImageMetadata(IIOMetadata inData, - ImageTypeSpecifier imageType, ImageWriteParam param) { - return null; - } - - public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, - ImageWriteParam param) { - return null; - } - - public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) { - return null; - } - - public ImageWriteParam getDefaultWriteParam() { - return new RawImageWriteParam(getLocale()); - } -} +// Copyright 2003, FreeHEP +package org.xmind.org.freehep.graphicsio.raw; + +import java.awt.image.RenderedImage; +import java.io.IOException; + +import javax.imageio.IIOImage; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageOutputStream; + +import org.xmind.org.freehep.util.images.ImageUtilities; + +/** + * + * @author Jason Wong + */ +public class RawImageWriter extends ImageWriter { + + public RawImageWriter(RawImageWriterSpi originatingProvider) { + super(originatingProvider); + } + + public void write(IIOMetadata streamMetadata, IIOImage image, + ImageWriteParam param) throws IOException { + if (image == null) + throw new IllegalArgumentException("image == null"); //$NON-NLS-1$ + + if (image.hasRaster()) + throw new UnsupportedOperationException("Cannot write rasters"); //$NON-NLS-1$ + + Object output = getOutput(); + if (output == null) + throw new IllegalStateException("output was not set"); //$NON-NLS-1$ + + if (param == null) + param = getDefaultWriteParam(); + + ImageOutputStream ios = (ImageOutputStream) output; + RenderedImage ri = image.getRenderedImage(); + + RawImageWriteParam rawParam = (RawImageWriteParam) param; + byte[] bytes = ImageUtilities.getBytes(ri, rawParam.getBackground(), + rawParam.getCode(), rawParam.getPad()); + ios.write(bytes); + ios.close(); + } + + public IIOMetadata convertStreamMetadata(IIOMetadata inData, + ImageWriteParam param) { + return null; + } + + public IIOMetadata convertImageMetadata(IIOMetadata inData, + ImageTypeSpecifier imageType, ImageWriteParam param) { + return null; + } + + public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, + ImageWriteParam param) { + return null; + } + + public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) { + return null; + } + + public ImageWriteParam getDefaultWriteParam() { + return new RawImageWriteParam(getLocale()); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriterSpi.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriterSpi.java index 789bda494..3ae1aca0e 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriterSpi.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/graphicsio/raw/RawImageWriterSpi.java @@ -1,41 +1,41 @@ -// Copyright 2003-2006, FreeHEP -package org.xmind.org.freehep.graphicsio.raw; - -import java.io.IOException; -import java.util.Locale; - -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.ImageWriter; -import javax.imageio.spi.ImageWriterSpi; -import javax.imageio.stream.ImageOutputStream; - -/** - * - * @author Jason Wong - */ -public class RawImageWriterSpi extends ImageWriterSpi { - - @SuppressWarnings("nls") - public RawImageWriterSpi() { - super("FreeHEP Java Libraries, http://java.freehep.org/", "1.0", - new String[] { "raw" }, new String[] { "raw" }, - new String[] { "image/x-raw" }, - "org.xmind.org.freehep.graphicsio.raw.RawImageWriter", - new Class[] { ImageOutputStream.class }, null, false, null, null, null, null, - false, null, null, null, null); - } - - public String getDescription(Locale locale) { - return "FreeHEP RAW Image Format"; //$NON-NLS-1$ - } - - public ImageWriter createWriterInstance(Object extension) - throws IOException { - return new RawImageWriter(this); - } - - public boolean canEncodeImage(ImageTypeSpecifier type) { - // FIXME - return true; - } -} +// Copyright 2003-2006, FreeHEP +package org.xmind.org.freehep.graphicsio.raw; + +import java.io.IOException; +import java.util.Locale; + +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; + +/** + * + * @author Jason Wong + */ +public class RawImageWriterSpi extends ImageWriterSpi { + + @SuppressWarnings("nls") + public RawImageWriterSpi() { + super("FreeHEP Java Libraries, http://java.freehep.org/", "1.0", + new String[] { "raw" }, new String[] { "raw" }, + new String[] { "image/x-raw" }, + "org.xmind.org.freehep.graphicsio.raw.RawImageWriter", + new Class[] { ImageOutputStream.class }, null, false, null, null, null, null, + false, null, null, null, null); + } + + public String getDescription(Locale locale) { + return "FreeHEP RAW Image Format"; //$NON-NLS-1$ + } + + public ImageWriter createWriterInstance(Object extension) + throws IOException { + return new RawImageWriter(this); + } + + public boolean canEncodeImage(ImageTypeSpecifier type) { + // FIXME + return true; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/DoubleWithError.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/DoubleWithError.java index ccf1007ca..7d2dde897 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/DoubleWithError.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/DoubleWithError.java @@ -1,94 +1,94 @@ -package org.xmind.org.freehep.util; - -/** - * A class that encapsulates a value and its error. - * Primarily for use with ScientificFormat - * - * @see ScientificFormat - * - * @author Tony Johnson - * @author Mark Donszelmann - * @version $Id: DoubleWithError.java 8584 2006-08-10 23:06:37Z duns $ - */ -public class DoubleWithError -{ - public DoubleWithError(double value, double error) - { - this.value = value; - this.error = error; - this.asymmetricError = false; - } - - public DoubleWithError(double value, double plusError, double minError) - { - this.value = value; - this.error = plusError; - this.minError = minError; - this.asymmetricError = true; - } - - public void setError(double error) - { - this.error = error; - this.asymmetricError = false; - } - - public void setError(double plusError, double minError) - { - this.error = plusError; - this.minError = minError; - this.asymmetricError = true; - } - - public double getError() - { - // FIXME: what do we return here if this has an asymmetric error - return error; - } - - public double getPlusError() - { - return error; - } - - public double getMinError() - { - return (asymmetricError) ? minError : error; - } - - public boolean hasAsymmetricError() - { - return asymmetricError; - } - - public void setValue(double value) - { - this.value = value; - } - - public double getValue() - { - return value; - } - - public String toString() - { - if (asymmetricError) - { - return String.valueOf(value)+plus+error+minus+minError; - } - else - { - return String.valueOf(value)+plusorminus+error; - } - } - // Not private because used by scientific format - final static char plusorminus = '\u00b1'; - final static char plus = '+'; - final static char minus = '-'; - private double value; - - private double error; - private boolean asymmetricError; - private double minError; -} +package org.xmind.org.freehep.util; + +/** + * A class that encapsulates a value and its error. + * Primarily for use with ScientificFormat + * + * @see ScientificFormat + * + * @author Tony Johnson + * @author Mark Donszelmann + * @version $Id: DoubleWithError.java 8584 2006-08-10 23:06:37Z duns $ + */ +public class DoubleWithError +{ + public DoubleWithError(double value, double error) + { + this.value = value; + this.error = error; + this.asymmetricError = false; + } + + public DoubleWithError(double value, double plusError, double minError) + { + this.value = value; + this.error = plusError; + this.minError = minError; + this.asymmetricError = true; + } + + public void setError(double error) + { + this.error = error; + this.asymmetricError = false; + } + + public void setError(double plusError, double minError) + { + this.error = plusError; + this.minError = minError; + this.asymmetricError = true; + } + + public double getError() + { + // FIXME: what do we return here if this has an asymmetric error + return error; + } + + public double getPlusError() + { + return error; + } + + public double getMinError() + { + return (asymmetricError) ? minError : error; + } + + public boolean hasAsymmetricError() + { + return asymmetricError; + } + + public void setValue(double value) + { + this.value = value; + } + + public double getValue() + { + return value; + } + + public String toString() + { + if (asymmetricError) + { + return String.valueOf(value)+plus+error+minus+minError; + } + else + { + return String.valueOf(value)+plusorminus+error; + } + } + // Not private because used by scientific format + final static char plusorminus = '\u00b1'; + final static char plus = '+'; + final static char minus = '-'; + private double value; + + private double error; + private boolean asymmetricError; + private double minError; +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/ScientificFormat.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/ScientificFormat.java index 871ae46d6..c321c6561 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/ScientificFormat.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/ScientificFormat.java @@ -1,251 +1,251 @@ -package org.xmind.org.freehep.util; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; -import java.util.Locale; - -/** - * This code formats numbers in Scientific Notation. The input Number object is - * returned as a ScientificFormated string. There are two output styles: Pure - * and Standard scientific notation. Pure formatted numbers have precisely the - * number of digits specified by the significant digits (sigDig) parameter and - * always specify a Base 10 Exponential(E). Standard formated numbers have the - * number of digits specified by the significant digits (sigDig) parameter but - * will not have a Base 10 Exponential(E) if the number of digits in the - * mantissa <= maxWidth. - * - * @author Paul Spence - * @author Mark Donszelmann - * @author Jason Wong - */ - -public class ScientificFormat extends Format { - /** - * The number of significant digits the number is formatted to is recorded - * by sigDigit. The maximum width allowed for the returned String is - * recorded by MaxWidth - */ - private int sigDigit = 5; - private int maxWidth = 8; - private boolean sciNote = false; // set to true for pure Scientific Notation - private DecimalFormat decimalFormat; - private static final long serialVersionUID = -1182686857248711235L; - - public ScientificFormat() { - - } - - /** - * Sets the significant digits, maximum allowable width and number - * formatting style (SciNote == true for Pure formatting). - */ - public ScientificFormat(int sigDigit, int maxWidth, boolean SciNote) { - setSigDigits(sigDigit); - setMaxWidth(maxWidth); - setScientificNotationStyle(SciNote); - } - - /** - * Implementation of inherited abstract method. Checks to see if object to - * be formatted is of type Number. If so casts the Number object to double - * and calls the format method. Returns the result. - */ - public StringBuffer format(Object obj, StringBuffer toAppendTo, - FieldPosition pos) { - if (obj instanceof Number) { - String result = format(((Number) obj).doubleValue()); - return toAppendTo.append(result); - } else if (obj instanceof DoubleWithError) { - DoubleWithError dwe = (DoubleWithError) obj; - toAppendTo.append(format(dwe.getValue())); - if (dwe.hasAsymmetricError()) { - toAppendTo.append(DoubleWithError.plus); - int errorSigDigit = resolveErrorSigDigit(dwe.getValue(), - dwe.getPlusError()); - toAppendTo.append(format(dwe.getPlusError(), errorSigDigit)); - - toAppendTo.append(DoubleWithError.minus); - errorSigDigit = resolveErrorSigDigit(dwe.getValue(), - dwe.getMinError()); - toAppendTo.append(format(dwe.getMinError(), errorSigDigit)); - } else { - toAppendTo.append(DoubleWithError.plusorminus); - int errorSigDigit = resolveErrorSigDigit(dwe.getValue(), - dwe.getError()); - toAppendTo.append(format(dwe.getError(), errorSigDigit)); - } - return toAppendTo; - } else - throw new IllegalArgumentException( - "Cannot format given Object as a Number"); //$NON-NLS-1$ - } - - /** - * Dummy implementation of inherited abstract method. - */ - public Object parseObject(String source, ParsePosition pos) { - return null; - } - - /** - * Returns the number of significant digits - */ - public int getSigDigits() { - return sigDigit; - } - - /** - * Returns the maximum allowable width of formatted number excluding any - * exponentials - */ - public int getMaxWidth() { - return maxWidth; - } - - /** - * Returns the formatting style: True means Pure scientific formatting, - * False means standard. - */ - public boolean getScientificNotationStyle() { - return sciNote; - } - - /** - * Sets the number of significant digits for the formatted number - */ - public void setSigDigits(int SigDigit) { - if (SigDigit < 1) - throw new IllegalArgumentException("sigDigit"); //$NON-NLS-1$ - sigDigit = SigDigit; - decimalFormat = null; - } - - /** - * Sets the maximum allowable length of the formattted number mantissa - * before exponential notation is used. - */ - public void setMaxWidth(int mWidth) { - if (mWidth < 3) - throw new IllegalArgumentException("maxWidth"); //$NON-NLS-1$ - maxWidth = mWidth; - } - - /** - * Sets the format style used. There are two output styles: Pure and - * Standard scientific notation. Pure formatted numbers have precisely the - * number of digits specified by the significant digits (sigDig) parameter - * and always specify a Base 10 Exponential(E). Standard formated numbers - * have the number of digits specified by the significant digits (sigDig) - * parameter but will not have a Base 10 Exponential(E) if the number of - * digits in the mantissa <= maxWidth. - */ - public void setScientificNotationStyle(boolean sciNote) { - this.sciNote = sciNote; - } - - // simplify method for taking log base 10 of x - private final static double k = 1 / Math.log(10); - - private double Log10(double x) { - if (x == 0) - return 0; - else - return Math.log(x) * k; - } - - private int resolveErrorSigDigit(double x, double dx) { - // dx should never be negative - dx = Math.abs(dx); - // make x +ve cause negative doesn't effect sigdigits - x = Math.abs(x); - - // these circumstances errorsigdit does equal sigdigit, excluding - // infinity and Nan which are handled by format - if (dx == 0 || Double.isInfinite(dx) || Double.isNaN(dx) || dx >= x) - return sigDigit; - - // fail cases for log, method fails to handle - if (x == 0 || Double.isInfinite(x) || Double.isNaN(x)) - return sigDigit; - - // otherwise solve for cases when dx maxWidth) - return preliminaryResult; - if (exponent < -maxWidth + sigDig + 1) - return preliminaryResult; - - // We need to fix up the result - - int sign = preliminaryResult.charAt(0) == '-' ? 1 : 0; - StringBuffer result = new StringBuffer(preliminaryResult.substring( - sign, sign + 1) + preliminaryResult.substring(sign + 2, ePos)); - - if (exponent >= sigDig) { - for (int i = sigDig; i < exponent; i++) - result.append('0'); - } else if (exponent < 0) { - result.insert(0, "."); //$NON-NLS-1$ - for (int i = exponent; i < 0; i++) - result.insert(1, '0'); - } else { - result.insert(exponent, '.'); - } - if (sign > 0) - result.insert(0, '-'); - return result.toString(); - } - // /** - // * Format a number plus error using scientific notation - // */ - // public String formatError(double d,double dx) - // { - // return format(dx, resolveErrorSigDigit(d, dx)); - // } - +package org.xmind.org.freehep.util; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParsePosition; +import java.util.Locale; + +/** + * This code formats numbers in Scientific Notation. The input Number object is + * returned as a ScientificFormated string. There are two output styles: Pure + * and Standard scientific notation. Pure formatted numbers have precisely the + * number of digits specified by the significant digits (sigDig) parameter and + * always specify a Base 10 Exponential(E). Standard formated numbers have the + * number of digits specified by the significant digits (sigDig) parameter but + * will not have a Base 10 Exponential(E) if the number of digits in the + * mantissa <= maxWidth. + * + * @author Paul Spence + * @author Mark Donszelmann + * @author Jason Wong + */ + +public class ScientificFormat extends Format { + /** + * The number of significant digits the number is formatted to is recorded + * by sigDigit. The maximum width allowed for the returned String is + * recorded by MaxWidth + */ + private int sigDigit = 5; + private int maxWidth = 8; + private boolean sciNote = false; // set to true for pure Scientific Notation + private DecimalFormat decimalFormat; + private static final long serialVersionUID = -1182686857248711235L; + + public ScientificFormat() { + + } + + /** + * Sets the significant digits, maximum allowable width and number + * formatting style (SciNote == true for Pure formatting). + */ + public ScientificFormat(int sigDigit, int maxWidth, boolean SciNote) { + setSigDigits(sigDigit); + setMaxWidth(maxWidth); + setScientificNotationStyle(SciNote); + } + + /** + * Implementation of inherited abstract method. Checks to see if object to + * be formatted is of type Number. If so casts the Number object to double + * and calls the format method. Returns the result. + */ + public StringBuffer format(Object obj, StringBuffer toAppendTo, + FieldPosition pos) { + if (obj instanceof Number) { + String result = format(((Number) obj).doubleValue()); + return toAppendTo.append(result); + } else if (obj instanceof DoubleWithError) { + DoubleWithError dwe = (DoubleWithError) obj; + toAppendTo.append(format(dwe.getValue())); + if (dwe.hasAsymmetricError()) { + toAppendTo.append(DoubleWithError.plus); + int errorSigDigit = resolveErrorSigDigit(dwe.getValue(), + dwe.getPlusError()); + toAppendTo.append(format(dwe.getPlusError(), errorSigDigit)); + + toAppendTo.append(DoubleWithError.minus); + errorSigDigit = resolveErrorSigDigit(dwe.getValue(), + dwe.getMinError()); + toAppendTo.append(format(dwe.getMinError(), errorSigDigit)); + } else { + toAppendTo.append(DoubleWithError.plusorminus); + int errorSigDigit = resolveErrorSigDigit(dwe.getValue(), + dwe.getError()); + toAppendTo.append(format(dwe.getError(), errorSigDigit)); + } + return toAppendTo; + } else + throw new IllegalArgumentException( + "Cannot format given Object as a Number"); //$NON-NLS-1$ + } + + /** + * Dummy implementation of inherited abstract method. + */ + public Object parseObject(String source, ParsePosition pos) { + return null; + } + + /** + * Returns the number of significant digits + */ + public int getSigDigits() { + return sigDigit; + } + + /** + * Returns the maximum allowable width of formatted number excluding any + * exponentials + */ + public int getMaxWidth() { + return maxWidth; + } + + /** + * Returns the formatting style: True means Pure scientific formatting, + * False means standard. + */ + public boolean getScientificNotationStyle() { + return sciNote; + } + + /** + * Sets the number of significant digits for the formatted number + */ + public void setSigDigits(int SigDigit) { + if (SigDigit < 1) + throw new IllegalArgumentException("sigDigit"); //$NON-NLS-1$ + sigDigit = SigDigit; + decimalFormat = null; + } + + /** + * Sets the maximum allowable length of the formattted number mantissa + * before exponential notation is used. + */ + public void setMaxWidth(int mWidth) { + if (mWidth < 3) + throw new IllegalArgumentException("maxWidth"); //$NON-NLS-1$ + maxWidth = mWidth; + } + + /** + * Sets the format style used. There are two output styles: Pure and + * Standard scientific notation. Pure formatted numbers have precisely the + * number of digits specified by the significant digits (sigDig) parameter + * and always specify a Base 10 Exponential(E). Standard formated numbers + * have the number of digits specified by the significant digits (sigDig) + * parameter but will not have a Base 10 Exponential(E) if the number of + * digits in the mantissa <= maxWidth. + */ + public void setScientificNotationStyle(boolean sciNote) { + this.sciNote = sciNote; + } + + // simplify method for taking log base 10 of x + private final static double k = 1 / Math.log(10); + + private double Log10(double x) { + if (x == 0) + return 0; + else + return Math.log(x) * k; + } + + private int resolveErrorSigDigit(double x, double dx) { + // dx should never be negative + dx = Math.abs(dx); + // make x +ve cause negative doesn't effect sigdigits + x = Math.abs(x); + + // these circumstances errorsigdit does equal sigdigit, excluding + // infinity and Nan which are handled by format + if (dx == 0 || Double.isInfinite(dx) || Double.isNaN(dx) || dx >= x) + return sigDigit; + + // fail cases for log, method fails to handle + if (x == 0 || Double.isInfinite(x) || Double.isNaN(x)) + return sigDigit; + + // otherwise solve for cases when dx maxWidth) + return preliminaryResult; + if (exponent < -maxWidth + sigDig + 1) + return preliminaryResult; + + // We need to fix up the result + + int sign = preliminaryResult.charAt(0) == '-' ? 1 : 0; + StringBuffer result = new StringBuffer(preliminaryResult.substring( + sign, sign + 1) + preliminaryResult.substring(sign + 2, ePos)); + + if (exponent >= sigDig) { + for (int i = sigDig; i < exponent; i++) + result.append('0'); + } else if (exponent < 0) { + result.insert(0, "."); //$NON-NLS-1$ + for (int i = exponent; i < 0; i++) + result.insert(1, '0'); + } else { + result.insert(exponent, '.'); + } + if (sign > 0) + result.insert(0, '-'); + return result.toString(); + } + // /** + // * Format a number plus error using scientific notation + // */ + // public String formatError(double d,double dx) + // { + // return format(dx, resolveErrorSigDigit(d, dx)); + // } + } \ No newline at end of file diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/UserProperties.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/UserProperties.java index cf199396c..26a3623cd 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/UserProperties.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/UserProperties.java @@ -1,313 +1,313 @@ -// Copyright 2003, FreeHEP. -package org.xmind.org.freehep.util; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Insets; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; - -/** - * Special property class which allows typed properties to be set and returned. - * It also allows the hookup of two default property objects to be searched if - * this property object does not contain the property. - * - * FIXME check what org.xmind.org.freehep.application.PropertyUtilities.java has to offer - * and merge, or not - * - * FIXME: This class does not seem general enough to be a "public" utility. - * Should be improved and merged with PropertyUtilities, or moved into the - * graphicsio package (tonyj) - * - * @author Mark Donszelmann - * @author Jason Wong - */ - -public class UserProperties extends Properties { - - /** - * - */ - private static final long serialVersionUID = 3297483251864528952L; - protected Properties altDefaults; - - public UserProperties() { - super(); - altDefaults = new Properties(); - } - - public UserProperties(Properties defaults) { - super(defaults); - altDefaults = new Properties(); - } - - /** - * Constructs UserProperties with a defaults and altDefaults table, which - * are searched in that order. - */ - public UserProperties(Properties defaults, Properties altDefaults) { - super(defaults); - this.altDefaults = altDefaults; - } - - public Enumeration propertyNames() { - - List list = new ArrayList(); - - for (Enumeration e = super.propertyNames(); e.hasMoreElements();) { - list.add(e.nextElement()); - } - if (altDefaults != null) { - for (Enumeration e = altDefaults.propertyNames(); e - .hasMoreElements();) { - list.add(e.nextElement()); - } - } - - return Collections.enumeration(list); - } - - /** - * Copies properties, including its defaults into this UserProperties - */ - public void setProperties(Properties properties) { - for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) { - String key = (String) e.nextElement(); - setProperty(key, properties.getProperty(key)); - } - } - - public Object setProperty(String key, String value) { - if (value == null) - return super.setProperty(key, "null"); //$NON-NLS-1$ - return super.setProperty(key, value); - } - - public Object setProperty(String key, String[] value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - String[] value) { - if (value == null) - return properties.setProperty(key, "null"); //$NON-NLS-1$ - - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < value.length; i++) { - if (i != 0) - sb.append(", "); //$NON-NLS-1$ - sb.append(value[i]); - } - return properties.setProperty(key, sb.toString()); - } - - public Object setProperty(String key, Color value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - Color value) { - if (value == null) - return properties.setProperty(key, "null"); //$NON-NLS-1$ - return properties.setProperty(key, - value.getRed() + ", " + value.getGreen() + ", " //$NON-NLS-1$ //$NON-NLS-2$ - + value.getBlue() + ", " + value.getAlpha()); //$NON-NLS-1$ - } - - public Object setProperty(String key, Rectangle value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - Rectangle value) { - if (value == null) - return properties.setProperty(key, "null"); //$NON-NLS-1$ - return properties.setProperty(key, value.x + ", " + value.y + ", " //$NON-NLS-1$ //$NON-NLS-2$ - + value.width + ", " + value.height); //$NON-NLS-1$ - } - - public Object setProperty(String key, Insets value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - Insets value) { - if (value == null) - return properties.setProperty(key, "null"); //$NON-NLS-1$ - return properties.setProperty(key, value.top + ", " + value.left + ", " //$NON-NLS-1$ //$NON-NLS-2$ - + value.bottom + ", " + value.right); //$NON-NLS-1$ - } - - public Object setProperty(String key, Dimension value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - Dimension value) { - if (value == null) - return properties.setProperty(key, "null"); //$NON-NLS-1$ - return properties.setProperty(key, value.width + ", " + value.height); //$NON-NLS-1$ - } - - public Object setProperty(String key, int value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - int value) { - return properties.setProperty(key, Integer.toString(value)); - } - - public Object setProperty(String key, double value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - double value) { - return properties.setProperty(key, Double.toString(value)); - } - - public Object setProperty(String key, float value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - float value) { - return properties.setProperty(key, Float.toString(value)); - } - - public Object setProperty(String key, boolean value) { - return setProperty(this, key, value); - } - - public static Object setProperty(Properties properties, String key, - boolean value) { - return properties.setProperty(key, Boolean.toString(value)); - } - - public String getProperty(String key) { - String value = super.getProperty(key); - return value != null ? value : altDefaults.getProperty(key); - } - - public String getProperty(String key, String def) { - String value = getProperty(key); - return value != null ? value : def; - } - - public String[] getPropertyStringArray(String key) { - return getPropertyStringArray(key, null); - } - - public String[] getPropertyStringArray(String key, String[] def) { - String s = getProperty(key); - if (s == null) - return def; - if (s.equals("null")) //$NON-NLS-1$ - return null; - - return s.split(", "); //$NON-NLS-1$ - } - - public Color getPropertyColor(String key) { - return getPropertyColor(key, null); - } - - public Color getPropertyColor(String key, Color def) { - String s = getProperty(key); - if (s == null) - return def; - if (s.equals("null")) //$NON-NLS-1$ - return null; - - String[] r = s.split(", "); //$NON-NLS-1$ - return new Color(Integer.parseInt(r[0]), Integer.parseInt(r[1]), - Integer.parseInt(r[2]), Integer.parseInt(r[3])); - } - - public Rectangle getPropertyRectangle(String key) { - return getPropertyRectangle(key, null); - } - - public Rectangle getPropertyRectangle(String key, Rectangle def) { - String s = getProperty(key); - if (s == null) - return def; - if (s.equals("null")) //$NON-NLS-1$ - return null; - - String[] r = s.split(", "); //$NON-NLS-1$ - return new Rectangle(Integer.parseInt(r[0]), Integer.parseInt(r[1]), - Integer.parseInt(r[2]), Integer.parseInt(r[3])); - } - - public Insets getPropertyInsets(String key) { - return getPropertyInsets(key, null); - } - - public Insets getPropertyInsets(String key, Insets def) { - String s = getProperty(key); - if (s == null) - return def; - if (s.equals("null")) //$NON-NLS-1$ - return null; - - String[] r = s.split(", "); //$NON-NLS-1$ - return new Insets(Integer.parseInt(r[0]), Integer.parseInt(r[1]), - Integer.parseInt(r[2]), Integer.parseInt(r[3])); - } - - public Dimension getPropertyDimension(String key) { - return getPropertyDimension(key, null); - } - - public Dimension getPropertyDimension(String key, Dimension def) { - String s = getProperty(key); - if (s == null) - return def; - if (s.equals("null")) //$NON-NLS-1$ - return null; - - String[] d = s.split(", "); //$NON-NLS-1$ - return new Dimension(Integer.parseInt(d[0]), Integer.parseInt(d[1])); - } - - public int getPropertyInt(String key) { - return getPropertyInt(key, 0); - } - - public int getPropertyInt(String key, int def) { - // FIXME: Yow!, two unnecessary object creations for each key lookup. - return new Integer(getProperty(key, Integer.toString(def))).intValue(); - } - - public double getPropertyDouble(String key) { - return getPropertyDouble(key, 0.0); - } - - public double getPropertyDouble(String key, double def) { - return new Double(getProperty(key, Double.toString(def))).doubleValue(); - } - - public float getPropertyFloat(String key) { - return getPropertyFloat(key, 0.0f); - } - - public float getPropertyFloat(String key, float def) { - return new Float(getProperty(key, Float.toString(def))).floatValue(); - } - - public boolean isProperty(String key) { - return isProperty(key, false); - } - - public boolean isProperty(String key, boolean def) { - return new Boolean(getProperty(key, Boolean.toString(def))) - .booleanValue(); - } - -} +// Copyright 2003, FreeHEP. +package org.xmind.org.freehep.util; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; + +/** + * Special property class which allows typed properties to be set and returned. + * It also allows the hookup of two default property objects to be searched if + * this property object does not contain the property. + * + * FIXME check what org.xmind.org.freehep.application.PropertyUtilities.java has to offer + * and merge, or not + * + * FIXME: This class does not seem general enough to be a "public" utility. + * Should be improved and merged with PropertyUtilities, or moved into the + * graphicsio package (tonyj) + * + * @author Mark Donszelmann + * @author Jason Wong + */ + +public class UserProperties extends Properties { + + /** + * + */ + private static final long serialVersionUID = 3297483251864528952L; + protected Properties altDefaults; + + public UserProperties() { + super(); + altDefaults = new Properties(); + } + + public UserProperties(Properties defaults) { + super(defaults); + altDefaults = new Properties(); + } + + /** + * Constructs UserProperties with a defaults and altDefaults table, which + * are searched in that order. + */ + public UserProperties(Properties defaults, Properties altDefaults) { + super(defaults); + this.altDefaults = altDefaults; + } + + public Enumeration propertyNames() { + + List list = new ArrayList(); + + for (Enumeration e = super.propertyNames(); e.hasMoreElements();) { + list.add(e.nextElement()); + } + if (altDefaults != null) { + for (Enumeration e = altDefaults.propertyNames(); e + .hasMoreElements();) { + list.add(e.nextElement()); + } + } + + return Collections.enumeration(list); + } + + /** + * Copies properties, including its defaults into this UserProperties + */ + public void setProperties(Properties properties) { + for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) { + String key = (String) e.nextElement(); + setProperty(key, properties.getProperty(key)); + } + } + + public Object setProperty(String key, String value) { + if (value == null) + return super.setProperty(key, "null"); //$NON-NLS-1$ + return super.setProperty(key, value); + } + + public Object setProperty(String key, String[] value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + String[] value) { + if (value == null) + return properties.setProperty(key, "null"); //$NON-NLS-1$ + + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < value.length; i++) { + if (i != 0) + sb.append(", "); //$NON-NLS-1$ + sb.append(value[i]); + } + return properties.setProperty(key, sb.toString()); + } + + public Object setProperty(String key, Color value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + Color value) { + if (value == null) + return properties.setProperty(key, "null"); //$NON-NLS-1$ + return properties.setProperty(key, + value.getRed() + ", " + value.getGreen() + ", " //$NON-NLS-1$ //$NON-NLS-2$ + + value.getBlue() + ", " + value.getAlpha()); //$NON-NLS-1$ + } + + public Object setProperty(String key, Rectangle value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + Rectangle value) { + if (value == null) + return properties.setProperty(key, "null"); //$NON-NLS-1$ + return properties.setProperty(key, value.x + ", " + value.y + ", " //$NON-NLS-1$ //$NON-NLS-2$ + + value.width + ", " + value.height); //$NON-NLS-1$ + } + + public Object setProperty(String key, Insets value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + Insets value) { + if (value == null) + return properties.setProperty(key, "null"); //$NON-NLS-1$ + return properties.setProperty(key, value.top + ", " + value.left + ", " //$NON-NLS-1$ //$NON-NLS-2$ + + value.bottom + ", " + value.right); //$NON-NLS-1$ + } + + public Object setProperty(String key, Dimension value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + Dimension value) { + if (value == null) + return properties.setProperty(key, "null"); //$NON-NLS-1$ + return properties.setProperty(key, value.width + ", " + value.height); //$NON-NLS-1$ + } + + public Object setProperty(String key, int value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + int value) { + return properties.setProperty(key, Integer.toString(value)); + } + + public Object setProperty(String key, double value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + double value) { + return properties.setProperty(key, Double.toString(value)); + } + + public Object setProperty(String key, float value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + float value) { + return properties.setProperty(key, Float.toString(value)); + } + + public Object setProperty(String key, boolean value) { + return setProperty(this, key, value); + } + + public static Object setProperty(Properties properties, String key, + boolean value) { + return properties.setProperty(key, Boolean.toString(value)); + } + + public String getProperty(String key) { + String value = super.getProperty(key); + return value != null ? value : altDefaults.getProperty(key); + } + + public String getProperty(String key, String def) { + String value = getProperty(key); + return value != null ? value : def; + } + + public String[] getPropertyStringArray(String key) { + return getPropertyStringArray(key, null); + } + + public String[] getPropertyStringArray(String key, String[] def) { + String s = getProperty(key); + if (s == null) + return def; + if (s.equals("null")) //$NON-NLS-1$ + return null; + + return s.split(", "); //$NON-NLS-1$ + } + + public Color getPropertyColor(String key) { + return getPropertyColor(key, null); + } + + public Color getPropertyColor(String key, Color def) { + String s = getProperty(key); + if (s == null) + return def; + if (s.equals("null")) //$NON-NLS-1$ + return null; + + String[] r = s.split(", "); //$NON-NLS-1$ + return new Color(Integer.parseInt(r[0]), Integer.parseInt(r[1]), + Integer.parseInt(r[2]), Integer.parseInt(r[3])); + } + + public Rectangle getPropertyRectangle(String key) { + return getPropertyRectangle(key, null); + } + + public Rectangle getPropertyRectangle(String key, Rectangle def) { + String s = getProperty(key); + if (s == null) + return def; + if (s.equals("null")) //$NON-NLS-1$ + return null; + + String[] r = s.split(", "); //$NON-NLS-1$ + return new Rectangle(Integer.parseInt(r[0]), Integer.parseInt(r[1]), + Integer.parseInt(r[2]), Integer.parseInt(r[3])); + } + + public Insets getPropertyInsets(String key) { + return getPropertyInsets(key, null); + } + + public Insets getPropertyInsets(String key, Insets def) { + String s = getProperty(key); + if (s == null) + return def; + if (s.equals("null")) //$NON-NLS-1$ + return null; + + String[] r = s.split(", "); //$NON-NLS-1$ + return new Insets(Integer.parseInt(r[0]), Integer.parseInt(r[1]), + Integer.parseInt(r[2]), Integer.parseInt(r[3])); + } + + public Dimension getPropertyDimension(String key) { + return getPropertyDimension(key, null); + } + + public Dimension getPropertyDimension(String key, Dimension def) { + String s = getProperty(key); + if (s == null) + return def; + if (s.equals("null")) //$NON-NLS-1$ + return null; + + String[] d = s.split(", "); //$NON-NLS-1$ + return new Dimension(Integer.parseInt(d[0]), Integer.parseInt(d[1])); + } + + public int getPropertyInt(String key) { + return getPropertyInt(key, 0); + } + + public int getPropertyInt(String key, int def) { + // FIXME: Yow!, two unnecessary object creations for each key lookup. + return new Integer(getProperty(key, Integer.toString(def))).intValue(); + } + + public double getPropertyDouble(String key) { + return getPropertyDouble(key, 0.0); + } + + public double getPropertyDouble(String key, double def) { + return new Double(getProperty(key, Double.toString(def))).doubleValue(); + } + + public float getPropertyFloat(String key) { + return getPropertyFloat(key, 0.0f); + } + + public float getPropertyFloat(String key, float def) { + return new Float(getProperty(key, Float.toString(def))).floatValue(); + } + + public boolean isProperty(String key) { + return isProperty(key, false); + } + + public boolean isProperty(String key, boolean def) { + return new Boolean(getProperty(key, Boolean.toString(def))) + .booleanValue(); + } + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/images/ImageUtilities.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/images/ImageUtilities.java index a40c97b34..0c02bffd1 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/images/ImageUtilities.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/images/ImageUtilities.java @@ -1,172 +1,172 @@ -// Copyright 2001-2007, FreeHEP. -package org.xmind.org.freehep.util.images; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.ImageObserver; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; - -/** - * @author Mark Donszelmann - * @version $Id: ImageUtilities.java 10366 2007-01-22 19:16:34Z duns $ - */ -public class ImageUtilities { - - private ImageUtilities() { - } - - public static RenderedImage createRenderedImage(Image image, - ImageObserver observer, Color bkg) { - if ((bkg == null) && (image instanceof RenderedImage)) - return (RenderedImage) image; - - BufferedImage bufferedImage = new BufferedImage( - image.getWidth(observer), image.getHeight(observer), - (bkg == null) ? BufferedImage.TYPE_INT_ARGB - : BufferedImage.TYPE_INT_RGB); - Graphics g = bufferedImage.getGraphics(); - if (bkg == null) { - g.drawImage(image, 0, 0, observer); - } else { - g.drawImage(image, 0, 0, bkg, observer); - } - return bufferedImage; - } - - public static BufferedImage createBufferedImage(RenderedImage image, - ImageObserver observer, Color bkg) { - if (image instanceof BufferedImage) - return (BufferedImage) image; - throw new IllegalArgumentException("not supperted " + image.getClass()); //$NON-NLS-1$ - } - - public static BufferedImage createBufferedImage(Image image, - ImageObserver observer, Color bkg) { - if ((bkg == null) && (image instanceof BufferedImage)) - return (BufferedImage) image; - return (BufferedImage) createRenderedImage(image, observer, bkg); - } - - public static RenderedImage createRenderedImage(RenderedImage image, - Color bkg) { - if (bkg == null) - return image; - - BufferedImage bufferedImage = new BufferedImage(image.getWidth(), - image.getHeight(), BufferedImage.TYPE_INT_RGB); - Graphics2D g = (Graphics2D) bufferedImage.getGraphics(); - g.setBackground(bkg); - g.clearRect(0, 0, image.getWidth(), image.getHeight()); - g.drawRenderedImage(image, new AffineTransform()); - return bufferedImage; - } - - public static byte[] getBytes(Image image, Color bkg, String code, int pad, - ImageObserver observer) { - return getBytes(createRenderedImage(image, observer, bkg), bkg, code, - pad); - } - - /** - * Returns the bytes of an image. - * - * @param image - * to be converted to bytes - * @param bkg - * the color to be used for alpha-multiplication - * @param code - * ARGB, A, or BGR, ... you may also use *ARGB to pre-multiply - * with alpha - * @param pad - * number of bytes to pad the scanline with (1=byte, 2=short, - * 4=int, ...) - */ - public static byte[] getBytes(RenderedImage image, Color bkg, String code, - int pad) { - if (pad < 1) - pad = 1; - - Raster raster = image.getData(); - - int width = image.getWidth(); - int height = image.getHeight(); - - boolean preMultiply = (code.charAt(0) == '*'); - if (preMultiply) - code = code.substring(1); - - int pixelSize = code.length(); - - int size = width * height * pixelSize; - size += (width % pad) * height; - int index = 0; - byte[] bytes = new byte[size]; - - ColorModel colorModel = image.getColorModel(); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - - int argb = colorModel.getRGB(raster.getDataElements(x, y, - (Object) null)); - int a = ((argb >> 24) & 0xFF); - int r = ((argb >> 16) & 0xFF); - int g = ((argb >> 8) & 0xFF); - int b = ((argb >> 0) & 0xFF); - - // Check the transparancy. If transparent substitute - // the background color. - if (preMultiply && (a < 0xFF)) { - if (bkg == null) - bkg = Color.BLACK; - double alpha = a / 255.0; - r = (int) (alpha * r + (1 - alpha) * bkg.getRed()); - g = (int) (alpha * g + (1 - alpha) * bkg.getGreen()); - b = (int) (alpha * b + (1 - alpha) * bkg.getBlue()); - } - - for (int i = 0; i < code.length(); i++) { - switch (code.charAt(i)) { - case 'a': - case 'A': - bytes[index] = (byte) a; - break; - - case 'r': - case 'R': - bytes[index] = (byte) r; - break; - - case 'g': - case 'G': - bytes[index] = (byte) g; - break; - - case 'b': - case 'B': - bytes[index] = (byte) b; - break; - - default: - System.err.println(ImageUtilities.class.getClass() - + ": Invalid code in '" + code + "'"); //$NON-NLS-1$ //$NON-NLS-2$ - break; - } - index++; - } - } - for (int i = 0; i < (width % pad); i++) { - bytes[index] = 0; - index++; - } - } - - return bytes; - } -} +// Copyright 2001-2007, FreeHEP. +package org.xmind.org.freehep.util.images; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; + +/** + * @author Mark Donszelmann + * @version $Id: ImageUtilities.java 10366 2007-01-22 19:16:34Z duns $ + */ +public class ImageUtilities { + + private ImageUtilities() { + } + + public static RenderedImage createRenderedImage(Image image, + ImageObserver observer, Color bkg) { + if ((bkg == null) && (image instanceof RenderedImage)) + return (RenderedImage) image; + + BufferedImage bufferedImage = new BufferedImage( + image.getWidth(observer), image.getHeight(observer), + (bkg == null) ? BufferedImage.TYPE_INT_ARGB + : BufferedImage.TYPE_INT_RGB); + Graphics g = bufferedImage.getGraphics(); + if (bkg == null) { + g.drawImage(image, 0, 0, observer); + } else { + g.drawImage(image, 0, 0, bkg, observer); + } + return bufferedImage; + } + + public static BufferedImage createBufferedImage(RenderedImage image, + ImageObserver observer, Color bkg) { + if (image instanceof BufferedImage) + return (BufferedImage) image; + throw new IllegalArgumentException("not supperted " + image.getClass()); //$NON-NLS-1$ + } + + public static BufferedImage createBufferedImage(Image image, + ImageObserver observer, Color bkg) { + if ((bkg == null) && (image instanceof BufferedImage)) + return (BufferedImage) image; + return (BufferedImage) createRenderedImage(image, observer, bkg); + } + + public static RenderedImage createRenderedImage(RenderedImage image, + Color bkg) { + if (bkg == null) + return image; + + BufferedImage bufferedImage = new BufferedImage(image.getWidth(), + image.getHeight(), BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D) bufferedImage.getGraphics(); + g.setBackground(bkg); + g.clearRect(0, 0, image.getWidth(), image.getHeight()); + g.drawRenderedImage(image, new AffineTransform()); + return bufferedImage; + } + + public static byte[] getBytes(Image image, Color bkg, String code, int pad, + ImageObserver observer) { + return getBytes(createRenderedImage(image, observer, bkg), bkg, code, + pad); + } + + /** + * Returns the bytes of an image. + * + * @param image + * to be converted to bytes + * @param bkg + * the color to be used for alpha-multiplication + * @param code + * ARGB, A, or BGR, ... you may also use *ARGB to pre-multiply + * with alpha + * @param pad + * number of bytes to pad the scanline with (1=byte, 2=short, + * 4=int, ...) + */ + public static byte[] getBytes(RenderedImage image, Color bkg, String code, + int pad) { + if (pad < 1) + pad = 1; + + Raster raster = image.getData(); + + int width = image.getWidth(); + int height = image.getHeight(); + + boolean preMultiply = (code.charAt(0) == '*'); + if (preMultiply) + code = code.substring(1); + + int pixelSize = code.length(); + + int size = width * height * pixelSize; + size += (width % pad) * height; + int index = 0; + byte[] bytes = new byte[size]; + + ColorModel colorModel = image.getColorModel(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + + int argb = colorModel.getRGB(raster.getDataElements(x, y, + (Object) null)); + int a = ((argb >> 24) & 0xFF); + int r = ((argb >> 16) & 0xFF); + int g = ((argb >> 8) & 0xFF); + int b = ((argb >> 0) & 0xFF); + + // Check the transparancy. If transparent substitute + // the background color. + if (preMultiply && (a < 0xFF)) { + if (bkg == null) + bkg = Color.BLACK; + double alpha = a / 255.0; + r = (int) (alpha * r + (1 - alpha) * bkg.getRed()); + g = (int) (alpha * g + (1 - alpha) * bkg.getGreen()); + b = (int) (alpha * b + (1 - alpha) * bkg.getBlue()); + } + + for (int i = 0; i < code.length(); i++) { + switch (code.charAt(i)) { + case 'a': + case 'A': + bytes[index] = (byte) a; + break; + + case 'r': + case 'R': + bytes[index] = (byte) r; + break; + + case 'g': + case 'G': + bytes[index] = (byte) g; + break; + + case 'b': + case 'B': + bytes[index] = (byte) b; + break; + + default: + System.err.println(ImageUtilities.class.getClass() + + ": Invalid code in '" + code + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + break; + } + index++; + } + } + for (int i = 0; i < (width % pad); i++) { + bytes[index] = 0; + index++; + } + } + + return bytes; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85.java index 381f806d6..24bcbc6b5 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85.java @@ -1,38 +1,38 @@ -// Copyright 2001, FreeHEP. -package org.xmind.org.freehep.util.io; - -/** - * Constants for the ASCII85 encoding. - * - * @author Mark Donszelmann - * @version $Id: src/main/java/org/freehep/util/io/ASCII85.java 96b41b903496 - * 2005/11/21 19:50:18 duns $ - */ -public interface ASCII85 { - - /** - * Maxmimum line length for ASCII85 - */ - public final static int MAX_CHARS_PER_LINE = 80; - - /** - * 85^1 - */ - public static long a85p1 = 85; - - /** - * 85^2 - */ - public static long a85p2 = a85p1 * a85p1; - - /** - * 85^3 - */ - public static long a85p3 = a85p2 * a85p1; - - /** - * 85^4 - */ - public static long a85p4 = a85p3 * a85p1; - -} +// Copyright 2001, FreeHEP. +package org.xmind.org.freehep.util.io; + +/** + * Constants for the ASCII85 encoding. + * + * @author Mark Donszelmann + * @version $Id: src/main/java/org/freehep/util/io/ASCII85.java 96b41b903496 + * 2005/11/21 19:50:18 duns $ + */ +public interface ASCII85 { + + /** + * Maxmimum line length for ASCII85 + */ + public final static int MAX_CHARS_PER_LINE = 80; + + /** + * 85^1 + */ + public static long a85p1 = 85; + + /** + * 85^2 + */ + public static long a85p2 = a85p1 * a85p1; + + /** + * 85^3 + */ + public static long a85p3 = a85p2 * a85p1; + + /** + * 85^4 + */ + public static long a85p4 = a85p3 * a85p1; + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85OutputStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85OutputStream.java index d1cdd96f5..0fbc6f8b1 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85OutputStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCII85OutputStream.java @@ -1,134 +1,134 @@ -// Copyright 2001-2007, FreeHEP. -package org.xmind.org.freehep.util.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * The ASCII85InputStream encodes binary data as ASCII base-85 encoding. The - * exact definition of ASCII base-85 encoding can be found in the PostScript - * Language Reference (3rd ed.) chapter 3.13.3. - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class ASCII85OutputStream extends FilterOutputStream implements ASCII85, - FinishableOutputStream { - - private boolean end; - - private int characters; - - private int b[] = new int[4]; - - private int bIndex; - - private int c[] = new int[5]; - - private String newline = "\n"; //$NON-NLS-1$ - - /** - * Create an ASCII85 Output Stream from given stream - * - * @param out - * output stream to use - */ - public ASCII85OutputStream(OutputStream out) { - super(out); - characters = MAX_CHARS_PER_LINE; - end = false; - bIndex = 0; - try { - newline = System.getProperty("line.separator"); //$NON-NLS-1$ - } catch (SecurityException e) { - // ignored; - } - } - - @Override - public void write(int a) throws IOException { - b[bIndex] = a & 0x00FF; - bIndex++; - if (bIndex >= b.length) { - writeTuple(); - bIndex = 0; - } - } - - public void finish() throws IOException { - if (!end) { - end = true; - if (bIndex > 0) { - writeTuple(); - } - writeEOD(); - flush(); - if (out instanceof FinishableOutputStream) { - ((FinishableOutputStream) out).finish(); - } - } - } - - @Override - public void close() throws IOException { - finish(); - super.close(); - } - - private void writeTuple() throws IOException { - // fill the rest - for (int i = bIndex; i < b.length; i++) { - b[i] = 0; - } - - // convert - long d = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) & 0x00000000FFFFFFFFL; - - c[0] = (int) (d / a85p4 + '!'); - d = d % a85p4; - c[1] = (int) (d / a85p3 + '!'); - d = d % a85p3; - c[2] = (int) (d / a85p2 + '!'); - d = d % a85p2; - c[3] = (int) (d / a85p1 + '!'); - c[4] = (int) (d % a85p1 + '!'); - - // convert !!!!! to z - if ((bIndex >= b.length) && (c[0] == '!') && (c[1] == '!') - && (c[2] == '!') && (c[3] == '!') && (c[4] == '!')) { - writeChar('z'); - } else { - for (int i = 0; i < bIndex + 1; i++) { - writeChar(c[i]); - } - } - } - - // Fix for IO-7 - private void writeEOD() throws IOException { - if (characters <= 1) { - characters = MAX_CHARS_PER_LINE; - writeNewLine(); - } - characters -= 2; - super.write('~'); - super.write('>'); - } - - private void writeChar(int b) throws IOException { - if (characters == 0) { - characters = MAX_CHARS_PER_LINE; - writeNewLine(); - } - characters--; - super.write(b); - } - - private void writeNewLine() throws IOException { - // write a newline - for (int i = 0; i < newline.length(); i++) { - super.write(newline.charAt(i)); - } - } -} +// Copyright 2001-2007, FreeHEP. +package org.xmind.org.freehep.util.io; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * The ASCII85InputStream encodes binary data as ASCII base-85 encoding. The + * exact definition of ASCII base-85 encoding can be found in the PostScript + * Language Reference (3rd ed.) chapter 3.13.3. + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class ASCII85OutputStream extends FilterOutputStream implements ASCII85, + FinishableOutputStream { + + private boolean end; + + private int characters; + + private int b[] = new int[4]; + + private int bIndex; + + private int c[] = new int[5]; + + private String newline = "\n"; //$NON-NLS-1$ + + /** + * Create an ASCII85 Output Stream from given stream + * + * @param out + * output stream to use + */ + public ASCII85OutputStream(OutputStream out) { + super(out); + characters = MAX_CHARS_PER_LINE; + end = false; + bIndex = 0; + try { + newline = System.getProperty("line.separator"); //$NON-NLS-1$ + } catch (SecurityException e) { + // ignored; + } + } + + @Override + public void write(int a) throws IOException { + b[bIndex] = a & 0x00FF; + bIndex++; + if (bIndex >= b.length) { + writeTuple(); + bIndex = 0; + } + } + + public void finish() throws IOException { + if (!end) { + end = true; + if (bIndex > 0) { + writeTuple(); + } + writeEOD(); + flush(); + if (out instanceof FinishableOutputStream) { + ((FinishableOutputStream) out).finish(); + } + } + } + + @Override + public void close() throws IOException { + finish(); + super.close(); + } + + private void writeTuple() throws IOException { + // fill the rest + for (int i = bIndex; i < b.length; i++) { + b[i] = 0; + } + + // convert + long d = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) & 0x00000000FFFFFFFFL; + + c[0] = (int) (d / a85p4 + '!'); + d = d % a85p4; + c[1] = (int) (d / a85p3 + '!'); + d = d % a85p3; + c[2] = (int) (d / a85p2 + '!'); + d = d % a85p2; + c[3] = (int) (d / a85p1 + '!'); + c[4] = (int) (d % a85p1 + '!'); + + // convert !!!!! to z + if ((bIndex >= b.length) && (c[0] == '!') && (c[1] == '!') + && (c[2] == '!') && (c[3] == '!') && (c[4] == '!')) { + writeChar('z'); + } else { + for (int i = 0; i < bIndex + 1; i++) { + writeChar(c[i]); + } + } + } + + // Fix for IO-7 + private void writeEOD() throws IOException { + if (characters <= 1) { + characters = MAX_CHARS_PER_LINE; + writeNewLine(); + } + characters -= 2; + super.write('~'); + super.write('>'); + } + + private void writeChar(int b) throws IOException { + if (characters == 0) { + characters = MAX_CHARS_PER_LINE; + writeNewLine(); + } + characters--; + super.write(b); + } + + private void writeNewLine() throws IOException { + // write a newline + for (int i = 0; i < newline.length(); i++) { + super.write(newline.charAt(i)); + } + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCIIHexOutputStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCIIHexOutputStream.java index 2ac4351e0..bc3a57853 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCIIHexOutputStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/ASCIIHexOutputStream.java @@ -1,95 +1,95 @@ -// Copyright 2001, FreeHEP. -package org.xmind.org.freehep.util.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * The ASCIIHexOutputStream encodes binary data as ASCII Hexadecimal. The exact - * definition of ASCII Hex encoding can be found in the PostScript Language - * Reference (3rd ed.) chapter 3.13.3. - * - * @author Mark Donszelmann - * @author Jason Wong - */ -public class ASCIIHexOutputStream extends FilterOutputStream implements - FinishableOutputStream { - - private final static int MAX_CHARS_PER_LINE = 80; - - private int characters; - - private boolean end; - - private String newline = "\n"; //$NON-NLS-1$ - - /** - * Create an ASCIIHex Output Stream for given stream. - * - * @param out - * output stream to use - */ - public ASCIIHexOutputStream(OutputStream out) { - super(out); - characters = MAX_CHARS_PER_LINE; - end = false; - try { - newline = System.getProperty("line.separator"); //$NON-NLS-1$ - } catch (SecurityException e) { - // ignored; - } - } - - @Override - public void write(int b) throws IOException { - String s = Integer.toHexString(b & 0x00FF); - switch (s.length()) { - case 1: - writeChar('0'); - writeChar(s.charAt(0)); - break; - case 2: - writeChar(s.charAt(0)); - writeChar(s.charAt(1)); - break; - default: - throw new IOException("ASCIIHexOutputStream: byte '" + b //$NON-NLS-1$ - + "' was encoded in less than 1 or more than 2 chars"); //$NON-NLS-1$ - } - } - - public void finish() throws IOException { - if (!end) { - end = true; - writeChar('>'); - writeNewLine(); - flush(); - if (out instanceof FinishableOutputStream) { - ((FinishableOutputStream) out).finish(); - } - } - } - - @Override - public void close() throws IOException { - finish(); - super.close(); - } - - private void writeChar(int b) throws IOException { - if (characters == 0) { - characters = MAX_CHARS_PER_LINE; - writeNewLine(); - } - characters--; - super.write(b); - } - - private void writeNewLine() throws IOException { - // write a newline - for (int i = 0; i < newline.length(); i++) { - super.write(newline.charAt(i)); - } - } -} +// Copyright 2001, FreeHEP. +package org.xmind.org.freehep.util.io; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * The ASCIIHexOutputStream encodes binary data as ASCII Hexadecimal. The exact + * definition of ASCII Hex encoding can be found in the PostScript Language + * Reference (3rd ed.) chapter 3.13.3. + * + * @author Mark Donszelmann + * @author Jason Wong + */ +public class ASCIIHexOutputStream extends FilterOutputStream implements + FinishableOutputStream { + + private final static int MAX_CHARS_PER_LINE = 80; + + private int characters; + + private boolean end; + + private String newline = "\n"; //$NON-NLS-1$ + + /** + * Create an ASCIIHex Output Stream for given stream. + * + * @param out + * output stream to use + */ + public ASCIIHexOutputStream(OutputStream out) { + super(out); + characters = MAX_CHARS_PER_LINE; + end = false; + try { + newline = System.getProperty("line.separator"); //$NON-NLS-1$ + } catch (SecurityException e) { + // ignored; + } + } + + @Override + public void write(int b) throws IOException { + String s = Integer.toHexString(b & 0x00FF); + switch (s.length()) { + case 1: + writeChar('0'); + writeChar(s.charAt(0)); + break; + case 2: + writeChar(s.charAt(0)); + writeChar(s.charAt(1)); + break; + default: + throw new IOException("ASCIIHexOutputStream: byte '" + b //$NON-NLS-1$ + + "' was encoded in less than 1 or more than 2 chars"); //$NON-NLS-1$ + } + } + + public void finish() throws IOException { + if (!end) { + end = true; + writeChar('>'); + writeNewLine(); + flush(); + if (out instanceof FinishableOutputStream) { + ((FinishableOutputStream) out).finish(); + } + } + } + + @Override + public void close() throws IOException { + finish(); + super.close(); + } + + private void writeChar(int b) throws IOException { + if (characters == 0) { + characters = MAX_CHARS_PER_LINE; + writeNewLine(); + } + characters--; + super.write(b); + } + + private void writeNewLine() throws IOException { + // write a newline + for (int i = 0; i < newline.length(); i++) { + super.write(newline.charAt(i)); + } + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/CountedByteOutputStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/CountedByteOutputStream.java index bf76d7f35..97e74552e 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/CountedByteOutputStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/CountedByteOutputStream.java @@ -1,54 +1,54 @@ -// Copyright 2001, FreeHEP. -package org.xmind.org.freehep.util.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * The CountedByteOutputStream counts the number of bytes written. - * - * @author Mark Donszelmann - * @version $Id: src/main/java/org/freehep/util/io/CountedByteOutputStream.java - * 96b41b903496 2005/11/21 19:50:18 duns $ - */ -public class CountedByteOutputStream extends FilterOutputStream { - - private int count; - - /** - * Creates a Counted Bytes output stream from the given stream. - * - * @param out - * stream to write to - */ - public CountedByteOutputStream(OutputStream out) { - super(out); - count = 0; - } - - @Override - public void write(int b) throws IOException { - out.write(b); - count++; - } - - @Override - public void write(byte[] b) throws IOException { - out.write(b); - count += b.length; - } - - @Override - public void write(byte[] b, int offset, int len) throws IOException { - out.write(b, offset, len); - count += len; - } - - /** - * @return number of bytes written. - */ - public int getCount() { - return count; - } -} +// Copyright 2001, FreeHEP. +package org.xmind.org.freehep.util.io; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * The CountedByteOutputStream counts the number of bytes written. + * + * @author Mark Donszelmann + * @version $Id: src/main/java/org/freehep/util/io/CountedByteOutputStream.java + * 96b41b903496 2005/11/21 19:50:18 duns $ + */ +public class CountedByteOutputStream extends FilterOutputStream { + + private int count; + + /** + * Creates a Counted Bytes output stream from the given stream. + * + * @param out + * stream to write to + */ + public CountedByteOutputStream(OutputStream out) { + super(out); + count = 0; + } + + @Override + public void write(int b) throws IOException { + out.write(b); + count++; + } + + @Override + public void write(byte[] b) throws IOException { + out.write(b); + count += b.length; + } + + @Override + public void write(byte[] b, int offset, int len) throws IOException { + out.write(b, offset, len); + count += len; + } + + /** + * @return number of bytes written. + */ + public int getCount() { + return count; + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECConstants.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECConstants.java index 2d5f02b20..6fafc4843 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECConstants.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECConstants.java @@ -1,38 +1,38 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.util.io; - -/** - * Constants for the EEXEC encoding (used by Type1 Fonts). - * - * @author Simon Fischer - * @version $Id: src/main/java/org/freehep/util/io/EEXECConstants.java - * 96b41b903496 2005/11/21 19:50:18 duns $ - */ -public interface EEXECConstants { - - /** - * Constant for EEXEC - */ - public static final char N = 4; - - /** - * Constant for EEXEC - */ - public static final char C1 = 52845; - - /** - * Constant for EEXEC - */ - public static final char C2 = 22719; - - /** - * Constant for EEXEC - */ - public static final char EEXEC_R = 55665; - - /** - * Constant for EEXEC - */ - public static final char CHARSTRING_R = 4330; - -} +// Copyright 2001 freehep +package org.xmind.org.freehep.util.io; + +/** + * Constants for the EEXEC encoding (used by Type1 Fonts). + * + * @author Simon Fischer + * @version $Id: src/main/java/org/freehep/util/io/EEXECConstants.java + * 96b41b903496 2005/11/21 19:50:18 duns $ + */ +public interface EEXECConstants { + + /** + * Constant for EEXEC + */ + public static final char N = 4; + + /** + * Constant for EEXEC + */ + public static final char C1 = 52845; + + /** + * Constant for EEXEC + */ + public static final char C2 = 22719; + + /** + * Constant for EEXEC + */ + public static final char EEXEC_R = 55665; + + /** + * Constant for EEXEC + */ + public static final char CHARSTRING_R = 4330; + +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECEncryption.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECEncryption.java index 2ca451d4f..1b379e01f 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECEncryption.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/EEXECEncryption.java @@ -1,133 +1,133 @@ -// Copyright 2001 freehep -package org.xmind.org.freehep.util.io; - -//import java.util.Random; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Encrypts using the EEXEC form (Used by Type 1 fonts). - * - * @author Simon Fischer - * @author Jason Wong - */ -public class EEXECEncryption extends OutputStream implements EEXECConstants { - - private int n, c1, c2, r; - - private OutputStream out; - - private boolean first = true; - - /** - * Creates an EEXECEncryption from given stream. - * - * @param out - * stream to write - */ - public EEXECEncryption(OutputStream out) { - this(out, EEXEC_R, N); - } - - /** - * Creates an EEXECEncryption from given stream. - * - * @param out - * stream to write - * @param r - */ - public EEXECEncryption(OutputStream out, int r) { - this(out, r, N); - } - - /** - * Creates an EEXECEncryption from given stream. - * - * @param out - * stream to write - * @param r - * @param n - */ - public EEXECEncryption(OutputStream out, int r, int n) { - this.out = out; - this.c1 = C1; - this.c2 = C2; - this.r = r; - this.n = n; - - } - - private int encrypt(int plainByte) { - int cipher = (plainByte ^ (r >>> 8)) % 256; - r = ((cipher + r) * c1 + c2) % 65536; - return cipher; - } - - @Override - public void write(int b) throws IOException { - if (first) { - for (int i = 0; i < n; i++) { - out.write(encrypt(0)); - } - first = false; - } - - out.write(encrypt(b)); - } - - @Override - public void flush() throws IOException { - super.flush(); - out.flush(); - } - - @Override - public void close() throws IOException { - flush(); - super.close(); - out.close(); - } - - private static class IntOutputStream extends OutputStream { - int[] chars; - - int i; - - private IntOutputStream(int size) { - chars = new int[size]; - i = 0; - } - - @Override - public void write(int b) { - chars[i++] = b; - } // str += (char)b; } - - // public String getString() { return str; } - private int[] getInts() { - return chars; - } - } - - /** - * Encrypt array of characters. - * - * @param chars - * int array to encrypt - * @param r - * @param n - * @return encrypted array - * @throws IOException - * if write fails (never happens) - */ - public static int[] encryptString(int[] chars, int r, int n) - throws IOException { - IntOutputStream resultStr = new IntOutputStream(chars.length + 4); - EEXECEncryption eout = new EEXECEncryption(resultStr, r, n); - for (int i = 0; i < chars.length; i++) { - eout.write(chars[i]); - } - eout.close(); - return resultStr.getInts(); - } -} +// Copyright 2001 freehep +package org.xmind.org.freehep.util.io; + +//import java.util.Random; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Encrypts using the EEXEC form (Used by Type 1 fonts). + * + * @author Simon Fischer + * @author Jason Wong + */ +public class EEXECEncryption extends OutputStream implements EEXECConstants { + + private int n, c1, c2, r; + + private OutputStream out; + + private boolean first = true; + + /** + * Creates an EEXECEncryption from given stream. + * + * @param out + * stream to write + */ + public EEXECEncryption(OutputStream out) { + this(out, EEXEC_R, N); + } + + /** + * Creates an EEXECEncryption from given stream. + * + * @param out + * stream to write + * @param r + */ + public EEXECEncryption(OutputStream out, int r) { + this(out, r, N); + } + + /** + * Creates an EEXECEncryption from given stream. + * + * @param out + * stream to write + * @param r + * @param n + */ + public EEXECEncryption(OutputStream out, int r, int n) { + this.out = out; + this.c1 = C1; + this.c2 = C2; + this.r = r; + this.n = n; + + } + + private int encrypt(int plainByte) { + int cipher = (plainByte ^ (r >>> 8)) % 256; + r = ((cipher + r) * c1 + c2) % 65536; + return cipher; + } + + @Override + public void write(int b) throws IOException { + if (first) { + for (int i = 0; i < n; i++) { + out.write(encrypt(0)); + } + first = false; + } + + out.write(encrypt(b)); + } + + @Override + public void flush() throws IOException { + super.flush(); + out.flush(); + } + + @Override + public void close() throws IOException { + flush(); + super.close(); + out.close(); + } + + private static class IntOutputStream extends OutputStream { + int[] chars; + + int i; + + private IntOutputStream(int size) { + chars = new int[size]; + i = 0; + } + + @Override + public void write(int b) { + chars[i++] = b; + } // str += (char)b; } + + // public String getString() { return str; } + private int[] getInts() { + return chars; + } + } + + /** + * Encrypt array of characters. + * + * @param chars + * int array to encrypt + * @param r + * @param n + * @return encrypted array + * @throws IOException + * if write fails (never happens) + */ + public static int[] encryptString(int[] chars, int r, int n) + throws IOException { + IntOutputStream resultStr = new IntOutputStream(chars.length + 4); + EEXECEncryption eout = new EEXECEncryption(resultStr, r, n); + for (int i = 0; i < chars.length; i++) { + eout.write(chars[i]); + } + eout.close(); + return resultStr.getInts(); + } +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FinishableOutputStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FinishableOutputStream.java index c508a2569..a6e6dd52a 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FinishableOutputStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FinishableOutputStream.java @@ -1,25 +1,25 @@ -// Copyright 2001, FreeHEP. -package org.xmind.org.freehep.util.io; - -import java.io.IOException; - -/** - * The FinishableOutputStream allows a generic way of calling finish on an - * output stream without closing it. - * - * @author Mark Donszelmann - * @version $Id: src/main/java/org/freehep/util/io/FinishableOutputStream.java - * 96b41b903496 2005/11/21 19:50:18 duns $ - */ -public interface FinishableOutputStream { - - /** - * Finishes the current outputstream (compresses, flushes, caluclates CRC) - * and writes whatever is left in the buffers, but does not close the - * stream. - * - * @throws IOException - * if write fails - */ - public void finish() throws IOException; -} +// Copyright 2001, FreeHEP. +package org.xmind.org.freehep.util.io; + +import java.io.IOException; + +/** + * The FinishableOutputStream allows a generic way of calling finish on an + * output stream without closing it. + * + * @author Mark Donszelmann + * @version $Id: src/main/java/org/freehep/util/io/FinishableOutputStream.java + * 96b41b903496 2005/11/21 19:50:18 duns $ + */ +public interface FinishableOutputStream { + + /** + * Finishes the current outputstream (compresses, flushes, caluclates CRC) + * and writes whatever is left in the buffers, but does not close the + * stream. + * + * @throws IOException + * if write fails + */ + public void finish() throws IOException; +} diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FlateOutputStream.java b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FlateOutputStream.java index 99cf03238..6c5f6064b 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FlateOutputStream.java +++ b/bundles/org.xmind.org.freehep.vectorgraphics/src/org/xmind/org/freehep/util/io/FlateOutputStream.java @@ -1,37 +1,37 @@ -// Copyright 2001-2005, FreeHEP. -package org.xmind.org.freehep.util.io; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.zip.DeflaterOutputStream; - -/** - * The FlateOutputStream uses the Deflate mechanism to compress data. The exact - * definition of Deflate encoding can be found in the PostScript Language - * Reference (3rd ed.) chapter 3.13.3. - * - * @author Mark Donszelmann - * @version $Id: src/main/java/org/freehep/util/io/FlateOutputStream.java - * 96b41b903496 2005/11/21 19:50:18 duns $ - */ -public class FlateOutputStream extends DeflaterOutputStream implements - FinishableOutputStream { - - /** - * Creates a (In-)Flate output stream. - * - * @param out - * stream to write to - */ - public FlateOutputStream(OutputStream out) { - super(out); - } - - @Override - public void finish() throws IOException { - super.finish(); - if (out instanceof FinishableOutputStream) { - ((FinishableOutputStream) out).finish(); - } - } -} +// Copyright 2001-2005, FreeHEP. +package org.xmind.org.freehep.util.io; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.DeflaterOutputStream; + +/** + * The FlateOutputStream uses the Deflate mechanism to compress data. The exact + * definition of Deflate encoding can be found in the PostScript Language + * Reference (3rd ed.) chapter 3.13.3. + * + * @author Mark Donszelmann + * @version $Id: src/main/java/org/freehep/util/io/FlateOutputStream.java + * 96b41b903496 2005/11/21 19:50:18 duns $ + */ +public class FlateOutputStream extends DeflaterOutputStream implements + FinishableOutputStream { + + /** + * Creates a (In-)Flate output stream. + * + * @param out + * stream to write to + */ + public FlateOutputStream(OutputStream out) { + super(out); + } + + @Override + public void finish() throws IOException { + super.finish(); + if (out instanceof FinishableOutputStream) { + ((FinishableOutputStream) out).finish(); + } + } +} diff --git a/bundles/org.xmind.ui.browser/.gitignore b/bundles/org.xmind.ui.browser/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.browser/.gitignore +++ b/bundles/org.xmind.ui.browser/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.browser/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF index 85a432d96..a42b374a8 100644 --- a/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF @@ -1,25 +1,25 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.browser;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.internal.browser.BrowserPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.core.net, - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.command;bundle-version="[3.7.0,3.8.0)" -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.ui.browser; - uses:="org.eclipse.jface.action, - org.xmind.ui.animation, - org.eclipse.ui, - org.eclipse.swt.graphics, - org.eclipse.swt.widgets, - org.eclipse.jface.dialogs, - org.eclipse.swt.browser", - org.xmind.ui.internal.browser;x-internal:=true, - org.xmind.ui.internal.browser.actions;x-internal:=true -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.browser;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.internal.browser.BrowserPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.net, + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.command;bundle-version="[3.7.0,3.8.0)" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.ui.browser; + uses:="org.eclipse.jface.action, + org.xmind.ui.animation, + org.eclipse.ui, + org.eclipse.swt.graphics, + org.eclipse.swt.widgets, + org.eclipse.jface.dialogs, + org.eclipse.swt.browser", + org.xmind.ui.internal.browser;x-internal:=true, + org.xmind.ui.internal.browser.actions;x-internal:=true +Bundle-Localization: plugin diff --git a/bundles/org.xmind.ui.browser/about.html b/bundles/org.xmind.ui.browser/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.ui.browser/about.html +++ b/bundles/org.xmind.ui.browser/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

    License

    - -

    Nov 6, 2008

    - -

    -XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

    - - - + + + + +License + + +

    License

    + +

    Nov 6, 2008

    + +

    +XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

    + + + diff --git a/bundles/org.xmind.ui.browser/plugin.properties b/bundles/org.xmind.ui.browser/plugin.properties index 056b4fe33..2b2a632a3 100644 --- a/bundles/org.xmind.ui.browser/plugin.properties +++ b/bundles/org.xmind.ui.browser/plugin.properties @@ -1,7 +1,7 @@ -#Properties file for org.xmind.ui.browser -providerName = XMind Ltd. -pluginName = XMind Browser -prefPage.browser.name = Web Browser -editor.browserEditor.name = Web Browser -view.browserView.name = Web Browser +#Properties file for org.xmind.ui.browser +providerName = XMind Ltd. +pluginName = XMind Browser +prefPage.browser.name = Web Browser +editor.browserEditor.name = Web Browser +view.browserView.name = Web Browser extension-point.name = Browser Viewer Contributions \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/plugin.xml b/bundles/org.xmind.ui.browser/plugin.xml index 7dfc67a55..fbc4aac9a 100644 --- a/bundles/org.xmind.ui.browser/plugin.xml +++ b/bundles/org.xmind.ui.browser/plugin.xml @@ -1,5 +1,5 @@ - - - - - + + + + + diff --git a/bundles/org.xmind.ui.browser/pom.xml b/bundles/org.xmind.ui.browser/pom.xml index 685382216..dcdedf0a4 100644 --- a/bundles/org.xmind.ui.browser/pom.xml +++ b/bundles/org.xmind.ui.browser/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.browser - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.browser + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/BrowserDialog.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/BrowserDialog.java index 160b81be5..6204b67c6 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/BrowserDialog.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/BrowserDialog.java @@ -1,223 +1,223 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.browser; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTError; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.LocationEvent; -import org.eclipse.swt.browser.LocationListener; -import org.eclipse.swt.browser.StatusTextEvent; -import org.eclipse.swt.browser.StatusTextListener; -import org.eclipse.swt.browser.TitleEvent; -import org.eclipse.swt.browser.TitleListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PartInitException; - -/** - * @author briansun - */ -public abstract class BrowserDialog extends Dialog { - - protected static final String COMMAND_PROTOCOL = "xmind://"; //$NON-NLS-1$ - - protected static final String COMMAND_CANCEL = "cancel"; //$NON-NLS-1$ - - protected static final String COMMAND_SKIP = "skip"; //$NON-NLS-1$ - - protected static final String COMMAND_OPEN = "open"; //$NON-NLS-1$ - - private class BrowserListener implements StatusTextListener, TitleListener, - LocationListener { - - /** - * @see org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt.browser.StatusTextEvent) - */ - public void changed(StatusTextEvent event) { - checkCommand(event.text); - } - - /** - * @see org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser.TitleEvent) - */ - public void changed(TitleEvent event) { - String t = event.title; - if (t != null && t.startsWith("xmind:")) //$NON-NLS-1$ - browser.getShell().setText(t.substring(6)); - } - - /** - * @see org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt.browser.LocationEvent) - */ - public void changed(LocationEvent event) { - } - - /** - * @see org.eclipse.swt.browser.LocationListener#changing(org.eclipse.swt.browser.LocationEvent) - */ - public void changing(LocationEvent event) { - if (checkCommand(event.location)) - event.doit = false; - } - - private boolean checkCommand(String href) { - if (href.startsWith(COMMAND_PROTOCOL)) { - String commandLine = href.substring(COMMAND_PROTOCOL.length()); - return execCommandLine(commandLine); - } - return false; - } - - } - - private Browser browser; - - private BrowserListener browserListener = new BrowserListener(); - - /** - * @param parentWindow - */ - public BrowserDialog(Shell parent) { - super(parent); - } - - /** - * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite) - */ - @Override - protected Control createContents(Composite parent) { - try { - browser = new Browser(parent, SWT.MOZILLA); - } catch (SWTError e) { - browser = new Browser(parent, SWT.NONE); - } - browser.setLayoutData(new GridData(GridData.FILL_BOTH)); - browser.addStatusTextListener(browserListener); - browser.addTitleListener(browserListener); - browser.addLocationListener(browserListener); - - String text = getInitialText(); - if (text != null) - browser.setText(text); - else { - String url = getInitialURL(); - if (url != null) - browser.setUrl(url); - } - - if (Util.isMac()) - browser.refresh(); - return browser; - } - - protected Browser getBrowser() { - return browser; - } - - /** - * @see org.eclipse.jface.dialogs.Dialog#getInitialSize() - */ - @Override - protected Point getInitialSize() { - return new Point(500, 325); - } - - /** - * @see org.eclipse.jface.dialogs.Dialog#getInitialLocation(org.eclipse.swt.graphics.Point) - */ - @Override - protected Point getInitialLocation(Point initialSize) { - Rectangle r = Display.getCurrent().getClientArea(); - return new Point((r.width - initialSize.x) / 2, - (r.height - initialSize.y) / 2); - } - - /** - * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) - */ - @Override - protected void createButtonsForButtonBar(Composite parent) { - // use html buttons - } - - protected String getInitialText() { - return null; - } - - protected String getInitialURL() { - return null; - } - - protected boolean execCommandLine(String commandLine) { - String[] commands = commandLine.split("/"); //$NON-NLS-1$ - if (commands.length > 1) { - String commandName = commands[0]; - String[] params = new String[commands.length - 1]; - System.arraycopy(commands, 1, params, 0, commands.length - 1); - return execCommand(commandName, params); - } - return false; - } - - protected boolean execCommand(String commandName, String[] params) { - if (COMMAND_CANCEL.equals(commandName)) { - return performCancel(); - } else if (COMMAND_SKIP.equals(commandName)) { - return performSkip(); - } else if (COMMAND_OPEN.equals(commandName)) { - return performOpen(params); - } - return false; - } - - protected boolean performOpen(String[] params) { - if (params.length > 0) { - String url = params[0]; - try { - url = URLDecoder.decode(url, "utf-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - } - try { - BrowserSupport.getInstance().createBrowser().openURL(url); - return true; - } catch (PartInitException e) { - // TODO handle this - } - } - return false; - } - - protected boolean performSkip() { - setReturnCode(IDialogConstants.CLOSE_ID); - return super.close(); - } - - protected boolean performCancel() { - setReturnCode(CANCEL); - return super.close(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.browser; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.LocationEvent; +import org.eclipse.swt.browser.LocationListener; +import org.eclipse.swt.browser.StatusTextEvent; +import org.eclipse.swt.browser.StatusTextListener; +import org.eclipse.swt.browser.TitleEvent; +import org.eclipse.swt.browser.TitleListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PartInitException; + +/** + * @author briansun + */ +public abstract class BrowserDialog extends Dialog { + + protected static final String COMMAND_PROTOCOL = "xmind://"; //$NON-NLS-1$ + + protected static final String COMMAND_CANCEL = "cancel"; //$NON-NLS-1$ + + protected static final String COMMAND_SKIP = "skip"; //$NON-NLS-1$ + + protected static final String COMMAND_OPEN = "open"; //$NON-NLS-1$ + + private class BrowserListener implements StatusTextListener, TitleListener, + LocationListener { + + /** + * @see org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt.browser.StatusTextEvent) + */ + public void changed(StatusTextEvent event) { + checkCommand(event.text); + } + + /** + * @see org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser.TitleEvent) + */ + public void changed(TitleEvent event) { + String t = event.title; + if (t != null && t.startsWith("xmind:")) //$NON-NLS-1$ + browser.getShell().setText(t.substring(6)); + } + + /** + * @see org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt.browser.LocationEvent) + */ + public void changed(LocationEvent event) { + } + + /** + * @see org.eclipse.swt.browser.LocationListener#changing(org.eclipse.swt.browser.LocationEvent) + */ + public void changing(LocationEvent event) { + if (checkCommand(event.location)) + event.doit = false; + } + + private boolean checkCommand(String href) { + if (href.startsWith(COMMAND_PROTOCOL)) { + String commandLine = href.substring(COMMAND_PROTOCOL.length()); + return execCommandLine(commandLine); + } + return false; + } + + } + + private Browser browser; + + private BrowserListener browserListener = new BrowserListener(); + + /** + * @param parentWindow + */ + public BrowserDialog(Shell parent) { + super(parent); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createContents(Composite parent) { + try { + browser = new Browser(parent, SWT.MOZILLA); + } catch (SWTError e) { + browser = new Browser(parent, SWT.NONE); + } + browser.setLayoutData(new GridData(GridData.FILL_BOTH)); + browser.addStatusTextListener(browserListener); + browser.addTitleListener(browserListener); + browser.addLocationListener(browserListener); + + String text = getInitialText(); + if (text != null) + browser.setText(text); + else { + String url = getInitialURL(); + if (url != null) + browser.setUrl(url); + } + + if (Util.isMac()) + browser.refresh(); + return browser; + } + + protected Browser getBrowser() { + return browser; + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#getInitialSize() + */ + @Override + protected Point getInitialSize() { + return new Point(500, 325); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#getInitialLocation(org.eclipse.swt.graphics.Point) + */ + @Override + protected Point getInitialLocation(Point initialSize) { + Rectangle r = Display.getCurrent().getClientArea(); + return new Point((r.width - initialSize.x) / 2, + (r.height - initialSize.y) / 2); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + // use html buttons + } + + protected String getInitialText() { + return null; + } + + protected String getInitialURL() { + return null; + } + + protected boolean execCommandLine(String commandLine) { + String[] commands = commandLine.split("/"); //$NON-NLS-1$ + if (commands.length > 1) { + String commandName = commands[0]; + String[] params = new String[commands.length - 1]; + System.arraycopy(commands, 1, params, 0, commands.length - 1); + return execCommand(commandName, params); + } + return false; + } + + protected boolean execCommand(String commandName, String[] params) { + if (COMMAND_CANCEL.equals(commandName)) { + return performCancel(); + } else if (COMMAND_SKIP.equals(commandName)) { + return performSkip(); + } else if (COMMAND_OPEN.equals(commandName)) { + return performOpen(params); + } + return false; + } + + protected boolean performOpen(String[] params) { + if (params.length > 0) { + String url = params[0]; + try { + url = URLDecoder.decode(url, "utf-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + } + try { + BrowserSupport.getInstance().createBrowser().openURL(url); + return true; + } catch (PartInitException e) { + // TODO handle this + } + } + return false; + } + + protected boolean performSkip() { + setReturnCode(IDialogConstants.CLOSE_ID); + return super.close(); + } + + protected boolean performCancel() { + setReturnCode(CANCEL); + return super.close(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewer.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewer.java index 8be704fa7..498623117 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewer.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewer.java @@ -1,56 +1,56 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.browser; - -import java.beans.PropertyChangeListener; - -import org.eclipse.swt.widgets.Control; -import org.xmind.ui.animation.AnimationViewer; - -/** - * @author briansun - */ -public interface IBrowserViewer { - - String PROPERTY_TITLE = "title"; //$NON-NLS-1$ - - String PROPERTY_LOCATION = "location"; //$NON-NLS-1$ - - String PROPERTY_STATUS = "status"; //$NON-NLS-1$ - - boolean setURL(String url); - - boolean setText(String html); - - String getURL(); - - AnimationViewer getBusyIndicator(); - - Control getControl(); - - IBrowserViewerContainer getContainer(); - - void addPropertyChangeListener(PropertyChangeListener listener); - - void removePropertyChangeListener(PropertyChangeListener listener); - - void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener); - - void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener); - - void setFocus(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.browser; + +import java.beans.PropertyChangeListener; + +import org.eclipse.swt.widgets.Control; +import org.xmind.ui.animation.AnimationViewer; + +/** + * @author briansun + */ +public interface IBrowserViewer { + + String PROPERTY_TITLE = "title"; //$NON-NLS-1$ + + String PROPERTY_LOCATION = "location"; //$NON-NLS-1$ + + String PROPERTY_STATUS = "status"; //$NON-NLS-1$ + + boolean setURL(String url); + + boolean setText(String html); + + String getURL(); + + AnimationViewer getBusyIndicator(); + + Control getControl(); + + IBrowserViewerContainer getContainer(); + + void addPropertyChangeListener(PropertyChangeListener listener); + + void removePropertyChangeListener(PropertyChangeListener listener); + + void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener); + + void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener); + + void setFocus(); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContainer.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContainer.java index 1442161c0..d628ebc22 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContainer.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContainer.java @@ -1,55 +1,55 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.browser; - -import org.eclipse.swt.browser.Browser; -import org.eclipse.ui.IActionBars; - -public interface IBrowserViewerContainer { - - String getClientId(); - - /** - * Closes the container. - * - * @return - */ - boolean close(); - - /** - * Returns the action bars of the container. - * - * @return action bars of the container or null if not - * available. - */ - IActionBars getActionBars(); - - /** - * Opens the url in the external browser if internal browser failed to - * create. - * - * @param url - */ - void openInExternalBrowser(String url); - - /** - * Creates a new browser instance for the viewer to open a new browser - * window on. - * - * @return a Browser instance or null if not - * available. - */ - Browser openNewBrowser(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.browser; + +import org.eclipse.swt.browser.Browser; +import org.eclipse.ui.IActionBars; + +public interface IBrowserViewerContainer { + + String getClientId(); + + /** + * Closes the container. + * + * @return + */ + boolean close(); + + /** + * Returns the action bars of the container. + * + * @return action bars of the container or null if not + * available. + */ + IActionBars getActionBars(); + + /** + * Opens the url in the external browser if internal browser failed to + * create. + * + * @param url + */ + void openInExternalBrowser(String url); + + /** + * Creates a new browser instance for the viewer to open a new browser + * window on. + * + * @return a Browser instance or null if not + * available. + */ + Browser openNewBrowser(); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution.java index a437bcdc7..e05f25b93 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution.java @@ -1,34 +1,34 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.browser; - -import org.eclipse.jface.action.IContributionManager; - -/** - * - * @author Frank Shaka - * - */ -public interface IBrowserViewerContribution { - - /** - * Contribution items filled in must implement fill(Composite) - * method. - * - * @param viewer - * @param toolBar - */ - void fillToolBar(IBrowserViewer viewer, IContributionManager toolBar); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.browser; + +import org.eclipse.jface.action.IContributionManager; + +/** + * + * @author Frank Shaka + * + */ +public interface IBrowserViewerContribution { + + /** + * Contribution items filled in must implement fill(Composite) + * method. + * + * @param viewer + * @param toolBar + */ + void fillToolBar(IBrowserViewer viewer, IContributionManager toolBar); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution2.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution2.java index 04c443862..2ec2b931c 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution2.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IBrowserViewerContribution2.java @@ -1,36 +1,36 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.browser; - - -/** - * @author Frank Shaka - * - */ -public interface IBrowserViewerContribution2 { - - /** - * - * @param viewer - */ - void installBrowserListeners(IBrowserViewer viewer); - - /** - * - * @param viewer - */ - void uninstallBrowserListeners(IBrowserViewer viewer); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.browser; + + +/** + * @author Frank Shaka + * + */ +public interface IBrowserViewerContribution2 { + + /** + * + * @param viewer + */ + void installBrowserListeners(IBrowserViewer viewer); + + /** + * + * @param viewer + */ + void uninstallBrowserListeners(IBrowserViewer viewer); + +} diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IPropertyChangingListener.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IPropertyChangingListener.java index a67a9008a..ef9becf5b 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IPropertyChangingListener.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/IPropertyChangingListener.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.browser; - -/** - * @author Frank Shaka - * - */ -public interface IPropertyChangingListener { - - void propertyChanging(PropertyChangingEvent event); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.browser; + +/** + * @author Frank Shaka + * + */ +public interface IPropertyChangingListener { + + void propertyChanging(PropertyChangingEvent event); + +} diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/PropertyChangingEvent.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/PropertyChangingEvent.java index e2a0ad539..ae41aebba 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/PropertyChangingEvent.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/browser/PropertyChangingEvent.java @@ -1,44 +1,44 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.browser; - -import java.beans.PropertyChangeEvent; - -/** - * @author Frank Shaka - * - */ -public class PropertyChangingEvent extends PropertyChangeEvent { - - /** - * - */ - private static final long serialVersionUID = 6238615584441475137L; - - public boolean doit; - - /** - * @param source - * @param propertyName - * @param oldValue - * @param newValue - */ - public PropertyChangingEvent(Object source, String propertyName, - Object oldValue, Object newValue, boolean doit) { - super(source, propertyName, oldValue, newValue); - this.doit = doit; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.browser; + +import java.beans.PropertyChangeEvent; + +/** + * @author Frank Shaka + * + */ +public class PropertyChangingEvent extends PropertyChangeEvent { + + /** + * + */ + private static final long serialVersionUID = 6238615584441475137L; + + public boolean doit; + + /** + * @param source + * @param propertyName + * @param oldValue + * @param newValue + */ + public PropertyChangingEvent(Object source, String propertyName, + Object oldValue, Object newValue, boolean doit) { + super(source, propertyName, oldValue, newValue); + this.doit = doit; + } + +} diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserEditorActionContributor.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserEditorActionContributor.java index c2a36d30c..1ffaef8b6 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserEditorActionContributor.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserEditorActionContributor.java @@ -1,140 +1,140 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.part.EditorActionBarContributor; -import org.xmind.ui.browser.BrowserSupport; -import org.xmind.ui.browser.IBrowser; -import org.xmind.ui.browser.IBrowserSupport; - -public class BrowserEditorActionContributor extends EditorActionBarContributor { - - private static class OpenInExternalAction extends Action { - - private InternalBrowserEditor editor; - - /** - * - */ - public OpenInExternalAction() { - super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, - BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); - setToolTipText( - BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); - setEnabled(false); - } - - /** - * @param editor - * the editor to set - */ - public void setEditor(InternalBrowserEditor editor) { - this.editor = editor; - setEnabled(editor != null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (editor == null) - return; - - BrowserViewer viewer = editor.getViewer(); - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - IBrowser browser = BrowserSupport.getInstance() - .createBrowser(IBrowserSupport.AS_EXTERNAL); - try { - browser.openURL(viewer.getURL()); - } catch (PartInitException e) { - BrowserPlugin.log(e); - } - } - } - - private OpenInExternalAction openInExternalAction; - - /* - * (non-Javadoc) - * - * @seeorg.eclipse.ui.part.EditorActionBarContributor#init(org.eclipse.ui. - * IActionBars) - */ - @Override - public void init(IActionBars bars) { - openInExternalAction = new OpenInExternalAction(); - super.init(bars); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(org. - * eclipse .jface.action.IMenuManager) - */ - @Override - public void contributeToMenu(IMenuManager menuManager) { - IMenuManager fileMenu = menuManager - .findMenuUsingPath(IWorkbenchActionConstants.M_FILE); - if (fileMenu != null) { - if (fileMenu.find(IWorkbenchActionConstants.OPEN_EXT) != null) { - fileMenu.prependToGroup(IWorkbenchActionConstants.OPEN_EXT, - openInExternalAction); - } - } - } - - @Override - public void contributeToToolBar(IToolBarManager toolBarManager) { -// super.contributeToToolBar(toolBarManager); -// toolBarManager.add(openInExternalAction); - } - - public void setActiveEditor(IEditorPart targetEditor) { - if (targetEditor instanceof InternalBrowserEditor) { - InternalBrowserEditor editor = (InternalBrowserEditor) targetEditor; - openInExternalAction.setEditor(editor); - - IActionBars bars = getActionBars(); - setHandler(bars, ActionFactory.COPY.getId(), editor); - setHandler(bars, ActionFactory.CUT.getId(), editor); - setHandler(bars, ActionFactory.PASTE.getId(), editor); - setHandler(bars, ActionFactory.DELETE.getId(), editor); - } - } - - private void setHandler(IActionBars bars, String actionId, - InternalBrowserEditor editor) { - IAction handler = editor.getAction(actionId); - if (handler != null) { - bars.setGlobalActionHandler(actionId, handler); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.part.EditorActionBarContributor; +import org.xmind.ui.browser.BrowserSupport; +import org.xmind.ui.browser.IBrowser; +import org.xmind.ui.browser.IBrowserSupport; + +public class BrowserEditorActionContributor extends EditorActionBarContributor { + + private static class OpenInExternalAction extends Action { + + private InternalBrowserEditor editor; + + /** + * + */ + public OpenInExternalAction() { + super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, + BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); + setToolTipText( + BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); + setEnabled(false); + } + + /** + * @param editor + * the editor to set + */ + public void setEditor(InternalBrowserEditor editor) { + this.editor = editor; + setEnabled(editor != null); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (editor == null) + return; + + BrowserViewer viewer = editor.getViewer(); + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + IBrowser browser = BrowserSupport.getInstance() + .createBrowser(IBrowserSupport.AS_EXTERNAL); + try { + browser.openURL(viewer.getURL()); + } catch (PartInitException e) { + BrowserPlugin.log(e); + } + } + } + + private OpenInExternalAction openInExternalAction; + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.ui.part.EditorActionBarContributor#init(org.eclipse.ui. + * IActionBars) + */ + @Override + public void init(IActionBars bars) { + openInExternalAction = new OpenInExternalAction(); + super.init(bars); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(org. + * eclipse .jface.action.IMenuManager) + */ + @Override + public void contributeToMenu(IMenuManager menuManager) { + IMenuManager fileMenu = menuManager + .findMenuUsingPath(IWorkbenchActionConstants.M_FILE); + if (fileMenu != null) { + if (fileMenu.find(IWorkbenchActionConstants.OPEN_EXT) != null) { + fileMenu.prependToGroup(IWorkbenchActionConstants.OPEN_EXT, + openInExternalAction); + } + } + } + + @Override + public void contributeToToolBar(IToolBarManager toolBarManager) { +// super.contributeToToolBar(toolBarManager); +// toolBarManager.add(openInExternalAction); + } + + public void setActiveEditor(IEditorPart targetEditor) { + if (targetEditor instanceof InternalBrowserEditor) { + InternalBrowserEditor editor = (InternalBrowserEditor) targetEditor; + openInExternalAction.setEditor(editor); + + IActionBars bars = getActionBars(); + setHandler(bars, ActionFactory.COPY.getId(), editor); + setHandler(bars, ActionFactory.CUT.getId(), editor); + setHandler(bars, ActionFactory.PASTE.getId(), editor); + setHandler(bars, ActionFactory.DELETE.getId(), editor); + } + } + + private void setHandler(IActionBars bars, String actionId, + InternalBrowserEditor editor) { + IAction handler = editor.getAction(actionId); + if (handler != null) { + bars.setGlobalActionHandler(actionId, handler); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserImages.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserImages.java index 574511600..b7f628df9 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserImages.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserImages.java @@ -1,91 +1,91 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.browser; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.ImageRegistry; -import org.eclipse.swt.graphics.Image; - -public class BrowserImages { - - public static final String PATH_ICONS = "icons/"; //$NON-NLS-1$ - - public static final String PATH_ENABLED = PATH_ICONS + "e/"; //$NON-NLS-1$ - - public static final String PATH_DISABLED = PATH_ICONS + "d/"; //$NON-NLS-1$ - - public static final String XMIND = PATH_ICONS + "xmind.16.png"; //$NON-NLS-1$ - - public static final String BROWSER = PATH_ICONS + "browser.gif"; //$NON-NLS-1$ - - public static final String BACKWARD = "backward_nav.gif"; //$NON-NLS-1$ - - public static final String FORWARD = "forward_nav.gif"; //$NON-NLS-1$ - - public static final String REFRESH = "refresh_nav.gif"; //$NON-NLS-1$ - - public static final String STOP = "nav_stop.gif"; //$NON-NLS-1$ - - public static final String GO = "nav_go.gif"; //$NON-NLS-1$ - - private static Map cache = new HashMap(); - - private static ImageDescriptor[] busyImages = null; - - public static ImageDescriptor getImageDescriptor(String path) { - ImageDescriptor img = cache.get(path); - if (img == null) { - img = BrowserPlugin - .imageDescriptorFromPlugin(BrowserPlugin.PLUGIN_ID, path); - if (img != null) - cache.put(path, img); - } - return img; - } - - public static ImageDescriptor getImageDescriptor(String fileName, - boolean enabled) { - String path = (enabled ? PATH_ENABLED : PATH_DISABLED) + fileName; - return getImageDescriptor(path); - } - - public static Image getImage(String path) { - ImageRegistry reg = BrowserPlugin.getDefault().getImageRegistry(); - Image image = reg.get(path); - if (image == null) { - reg.put(path, getImageDescriptor(path)); - image = reg.get(path); - } - return image; - } - - public static Image getImage(String fileName, boolean enabled) { - String path = (enabled ? PATH_ENABLED : PATH_DISABLED) + fileName; - return getImage(path); - } - - public static ImageDescriptor[] getBusyImages() { - if (busyImages == null) { - busyImages = new ImageDescriptor[12]; - for (int i = 0; i < 12; i++) { - String path = String.format(PATH_ICONS + "busy/busy_f%02d.gif", //$NON-NLS-1$ - (i + 1)); - busyImages[i] = getImageDescriptor(path); - } - } - return busyImages; - } - -} +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.browser; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + +public class BrowserImages { + + public static final String PATH_ICONS = "icons/"; //$NON-NLS-1$ + + public static final String PATH_ENABLED = PATH_ICONS + "e/"; //$NON-NLS-1$ + + public static final String PATH_DISABLED = PATH_ICONS + "d/"; //$NON-NLS-1$ + + public static final String XMIND = PATH_ICONS + "xmind.16.png"; //$NON-NLS-1$ + + public static final String BROWSER = PATH_ICONS + "browser.gif"; //$NON-NLS-1$ + + public static final String BACKWARD = "backward_nav.gif"; //$NON-NLS-1$ + + public static final String FORWARD = "forward_nav.gif"; //$NON-NLS-1$ + + public static final String REFRESH = "refresh_nav.gif"; //$NON-NLS-1$ + + public static final String STOP = "nav_stop.gif"; //$NON-NLS-1$ + + public static final String GO = "nav_go.gif"; //$NON-NLS-1$ + + private static Map cache = new HashMap(); + + private static ImageDescriptor[] busyImages = null; + + public static ImageDescriptor getImageDescriptor(String path) { + ImageDescriptor img = cache.get(path); + if (img == null) { + img = BrowserPlugin + .imageDescriptorFromPlugin(BrowserPlugin.PLUGIN_ID, path); + if (img != null) + cache.put(path, img); + } + return img; + } + + public static ImageDescriptor getImageDescriptor(String fileName, + boolean enabled) { + String path = (enabled ? PATH_ENABLED : PATH_DISABLED) + fileName; + return getImageDescriptor(path); + } + + public static Image getImage(String path) { + ImageRegistry reg = BrowserPlugin.getDefault().getImageRegistry(); + Image image = reg.get(path); + if (image == null) { + reg.put(path, getImageDescriptor(path)); + image = reg.get(path); + } + return image; + } + + public static Image getImage(String fileName, boolean enabled) { + String path = (enabled ? PATH_ENABLED : PATH_DISABLED) + fileName; + return getImage(path); + } + + public static ImageDescriptor[] getBusyImages() { + if (busyImages == null) { + busyImages = new ImageDescriptor[12]; + for (int i = 0; i < 12; i++) { + String path = String.format(PATH_ICONS + "busy/busy_f%02d.gif", //$NON-NLS-1$ + (i + 1)); + busyImages[i] = getImageDescriptor(path); + } + } + return busyImages; + } + +} diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserMessages.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserMessages.java index 75a2a85a5..724031f88 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserMessages.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserMessages.java @@ -1,49 +1,49 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import org.eclipse.osgi.util.NLS; - -public class BrowserMessages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.ui.internal.browser.messages"; //$NON-NLS-1$ - - public static String BrowserText_Details; - public static String BrowserText_EmbeddedBrowserUnavailableInfo; - public static String BrowserText_OpenFileLinkToolTip; - public static String BrowserText_ProblemDetails; - public static String BrowserText_ProblemDetailsTitle; - public static String BrowserViewer_NextPage_toolTip; - public static String BrowserViewer_PrevPage_toolTip; - public static String BrowserViewer_Refresh_toolTip; - public static String BrowserViewer_Stop_toolTip; - public static String ExternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message; - public static String InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message; - public static String BrowserPrefPage_title; - public static String BrowserPrefPage_description; - public static String BrowserPrefPage_InternalBrowser_text; - public static String BrowserPrefPage_ExternalBrowser_text; - public static String BrowserEditor_title; - public static String BrowserEditor_ErrorInvalidEditorInput_message; - public static String BrowserView_OpenInExternalBrowser_text; - public static String BrowserView_OpenInExternalBrowser_toolTip; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, BrowserMessages.class); - } - - private BrowserMessages() { - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import org.eclipse.osgi.util.NLS; + +public class BrowserMessages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.ui.internal.browser.messages"; //$NON-NLS-1$ + + public static String BrowserText_Details; + public static String BrowserText_EmbeddedBrowserUnavailableInfo; + public static String BrowserText_OpenFileLinkToolTip; + public static String BrowserText_ProblemDetails; + public static String BrowserText_ProblemDetailsTitle; + public static String BrowserViewer_NextPage_toolTip; + public static String BrowserViewer_PrevPage_toolTip; + public static String BrowserViewer_Refresh_toolTip; + public static String BrowserViewer_Stop_toolTip; + public static String ExternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message; + public static String InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message; + public static String BrowserPrefPage_title; + public static String BrowserPrefPage_description; + public static String BrowserPrefPage_InternalBrowser_text; + public static String BrowserPrefPage_ExternalBrowser_text; + public static String BrowserEditor_title; + public static String BrowserEditor_ErrorInvalidEditorInput_message; + public static String BrowserView_OpenInExternalBrowser_text; + public static String BrowserView_OpenInExternalBrowser_toolTip; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, BrowserMessages.class); + } + + private BrowserMessages() { + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPref.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPref.java index fc06d636d..a1c0f7aeb 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPref.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPref.java @@ -1,135 +1,135 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.StringTokenizer; - -import org.eclipse.jface.preference.IPreferenceStore; - -public class BrowserPref { - - protected static final String PREF_INTERNAL_WEB_BROWSER_HISTORY = "internalWebBrowserHistory"; //$NON-NLS-1$ - - protected static final String PREF_BROWSER_CHOICE = "browserChoice"; //$NON-NLS-1$ - - public static final int INTERNAL = 1; - - public static final int EXTERNAL = 0; - - private BrowserPref() { - } - - /** - * Returns the preference store. - * - * @return the preference store - */ - protected static IPreferenceStore getPreferenceStore() { - return BrowserPlugin.getDefault().getPreferenceStore(); - } - - /** - * Returns the Web browser history list. - * - * @return java.util.List - */ - public static List getInternalWebBrowserHistory() { - String temp = getPreferenceStore().getString( - PREF_INTERNAL_WEB_BROWSER_HISTORY); - StringTokenizer st = new StringTokenizer(temp, "|*|"); //$NON-NLS-1$ - List l = new ArrayList(); - while (st.hasMoreTokens()) { - String s = st.nextToken(); - l.add(s); - } - return l; - } - - /** - * Sets the Web browser history. - * - * @param list - * the history - */ - public static void setInternalWebBrowserHistory(List list) { - StringBuffer sb = new StringBuffer(); - if (list != null) { - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - String s = iterator.next(); - sb.append(s); - sb.append("|*|"); //$NON-NLS-1$ - } - } - getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_HISTORY, - sb.toString()); -// BrowserPlugin.getDefault().savePluginPreferences(); -// InstanceScope instanceScope = new InstanceScope(); -// String bundId = String.valueOf(BrowserPlugin.getDefault().getBundle() -// .getBundleId()); -// try { -// instanceScope.getNode(bundId).flush(); -// } catch (BackingStoreException e) { -// e.printStackTrace(); -// } - } - - /** - * Returns whether the internal browser is used by default - * - * @return true if the internal browser is used by default - */ - public static boolean isDefaultUseInternalBrowser() { - return BrowserUtil.canUseInternalWebBrowser(); - } - - /** - * Returns whether the system browser is used by default - * - * @return true if the system browser is used by default - */ - public static boolean isDefaultUseSystemBrowser() { - return BrowserUtil.canUseSystemBrowser(); - } - - /** - * Returns whether the internal or external browser is being used - * - * @return one of INTERNAL or EXTERNAL. - */ - public static int getBrowserChoice() { - int choice = getPreferenceStore().getInt(PREF_BROWSER_CHOICE); - if (choice == 2) - return EXTERNAL; - if (choice == INTERNAL && !BrowserUtil.canUseInternalWebBrowser()) - return EXTERNAL; - return choice; - } - - /** - * Sets whether the internal, system and external browser is used - * - * @param choice - * INTERNAL, SYSTEM and - * EXTERNAL - */ - public static void setBrowserChoice(int choice) { - getPreferenceStore().setValue(PREF_BROWSER_CHOICE, choice); -// BrowserPlugin.getDefault().savePluginPreferences(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.jface.preference.IPreferenceStore; + +public class BrowserPref { + + protected static final String PREF_INTERNAL_WEB_BROWSER_HISTORY = "internalWebBrowserHistory"; //$NON-NLS-1$ + + protected static final String PREF_BROWSER_CHOICE = "browserChoice"; //$NON-NLS-1$ + + public static final int INTERNAL = 1; + + public static final int EXTERNAL = 0; + + private BrowserPref() { + } + + /** + * Returns the preference store. + * + * @return the preference store + */ + protected static IPreferenceStore getPreferenceStore() { + return BrowserPlugin.getDefault().getPreferenceStore(); + } + + /** + * Returns the Web browser history list. + * + * @return java.util.List + */ + public static List getInternalWebBrowserHistory() { + String temp = getPreferenceStore().getString( + PREF_INTERNAL_WEB_BROWSER_HISTORY); + StringTokenizer st = new StringTokenizer(temp, "|*|"); //$NON-NLS-1$ + List l = new ArrayList(); + while (st.hasMoreTokens()) { + String s = st.nextToken(); + l.add(s); + } + return l; + } + + /** + * Sets the Web browser history. + * + * @param list + * the history + */ + public static void setInternalWebBrowserHistory(List list) { + StringBuffer sb = new StringBuffer(); + if (list != null) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + String s = iterator.next(); + sb.append(s); + sb.append("|*|"); //$NON-NLS-1$ + } + } + getPreferenceStore().setValue(PREF_INTERNAL_WEB_BROWSER_HISTORY, + sb.toString()); +// BrowserPlugin.getDefault().savePluginPreferences(); +// InstanceScope instanceScope = new InstanceScope(); +// String bundId = String.valueOf(BrowserPlugin.getDefault().getBundle() +// .getBundleId()); +// try { +// instanceScope.getNode(bundId).flush(); +// } catch (BackingStoreException e) { +// e.printStackTrace(); +// } + } + + /** + * Returns whether the internal browser is used by default + * + * @return true if the internal browser is used by default + */ + public static boolean isDefaultUseInternalBrowser() { + return BrowserUtil.canUseInternalWebBrowser(); + } + + /** + * Returns whether the system browser is used by default + * + * @return true if the system browser is used by default + */ + public static boolean isDefaultUseSystemBrowser() { + return BrowserUtil.canUseSystemBrowser(); + } + + /** + * Returns whether the internal or external browser is being used + * + * @return one of INTERNAL or EXTERNAL. + */ + public static int getBrowserChoice() { + int choice = getPreferenceStore().getInt(PREF_BROWSER_CHOICE); + if (choice == 2) + return EXTERNAL; + if (choice == INTERNAL && !BrowserUtil.canUseInternalWebBrowser()) + return EXTERNAL; + return choice; + } + + /** + * Sets whether the internal, system and external browser is used + * + * @param choice + * INTERNAL, SYSTEM and + * EXTERNAL + */ + public static void setBrowserChoice(int choice) { + getPreferenceStore().setValue(PREF_BROWSER_CHOICE, choice); +// BrowserPlugin.getDefault().savePluginPreferences(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPrefPage.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPrefPage.java index 797ce78db..c3abb9a55 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPrefPage.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserPrefPage.java @@ -1,122 +1,122 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -public class BrowserPrefPage extends PreferencePage implements - IWorkbenchPreferencePage { - - private Button internal; - - private Button external; - - public BrowserPrefPage() { - super(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse - * .swt.widgets.Composite) - */ - protected Control createContents(Composite parent) { - initializeDialogUnits(parent); - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - layout.horizontalSpacing = convertHorizontalDLUsToPixels(4); - layout.verticalSpacing = convertVerticalDLUsToPixels(3); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); - composite.setLayoutData(data); - - Label label = new Label(composite, SWT.WRAP); - label.setText(BrowserMessages.BrowserPrefPage_description); - data = new GridData(SWT.FILL, SWT.NONE, false, false); - data.horizontalSpan = 2; - data.widthHint = 275; - label.setLayoutData(data); - - internal = new Button(composite, SWT.RADIO); - internal.setText(BrowserMessages.BrowserPrefPage_InternalBrowser_text); - data = new GridData(SWT.FILL, SWT.NONE, true, false); - data.horizontalSpan = 2; - internal.setLayoutData(data); - - if (!BrowserUtil.canUseInternalWebBrowser()) - internal.setEnabled(false); - - external = new Button(composite, SWT.RADIO); - external.setText(BrowserMessages.BrowserPrefPage_ExternalBrowser_text); - data = new GridData(SWT.FILL, SWT.NONE, true, false); - data.horizontalSpan = 2; - external.setLayoutData(data); - - internal.setSelection(BrowserPref.getBrowserChoice() == BrowserPref.INTERNAL); - external.setSelection(BrowserPref.getBrowserChoice() == BrowserPref.EXTERNAL); - Dialog.applyDialogFont(composite); - return composite; - } - - public void init(IWorkbench workbench) { - // do nothing - } - - /** - * - */ - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - setTitle(BrowserMessages.BrowserPrefPage_title); - } - - /** - * Performs special processing when this page's Defaults button has been - * pressed. - */ - protected void performDefaults() { - internal.setSelection(!BrowserPref.isDefaultUseSystemBrowser()); - external.setSelection(BrowserPref.isDefaultUseSystemBrowser()); - super.performDefaults(); - } - - /** - * Method declared on IPreferencePage. Subclasses should override - */ - public boolean performOk() { - int choice; - if (internal.getSelection()) - choice = BrowserPref.INTERNAL; - else - choice = BrowserPref.EXTERNAL; - BrowserPref.setBrowserChoice(choice); - return true; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class BrowserPrefPage extends PreferencePage implements + IWorkbenchPreferencePage { + + private Button internal; + + private Button external; + + public BrowserPrefPage() { + super(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse + * .swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + initializeDialogUnits(parent); + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.horizontalSpacing = convertHorizontalDLUsToPixels(4); + layout.verticalSpacing = convertVerticalDLUsToPixels(3); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); + composite.setLayoutData(data); + + Label label = new Label(composite, SWT.WRAP); + label.setText(BrowserMessages.BrowserPrefPage_description); + data = new GridData(SWT.FILL, SWT.NONE, false, false); + data.horizontalSpan = 2; + data.widthHint = 275; + label.setLayoutData(data); + + internal = new Button(composite, SWT.RADIO); + internal.setText(BrowserMessages.BrowserPrefPage_InternalBrowser_text); + data = new GridData(SWT.FILL, SWT.NONE, true, false); + data.horizontalSpan = 2; + internal.setLayoutData(data); + + if (!BrowserUtil.canUseInternalWebBrowser()) + internal.setEnabled(false); + + external = new Button(composite, SWT.RADIO); + external.setText(BrowserMessages.BrowserPrefPage_ExternalBrowser_text); + data = new GridData(SWT.FILL, SWT.NONE, true, false); + data.horizontalSpan = 2; + external.setLayoutData(data); + + internal.setSelection(BrowserPref.getBrowserChoice() == BrowserPref.INTERNAL); + external.setSelection(BrowserPref.getBrowserChoice() == BrowserPref.EXTERNAL); + Dialog.applyDialogFont(composite); + return composite; + } + + public void init(IWorkbench workbench) { + // do nothing + } + + /** + * + */ + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) + setTitle(BrowserMessages.BrowserPrefPage_title); + } + + /** + * Performs special processing when this page's Defaults button has been + * pressed. + */ + protected void performDefaults() { + internal.setSelection(!BrowserPref.isDefaultUseSystemBrowser()); + external.setSelection(BrowserPref.isDefaultUseSystemBrowser()); + super.performDefaults(); + } + + /** + * Method declared on IPreferencePage. Subclasses should override + */ + public boolean performOk() { + int choice; + if (internal.getSelection()) + choice = BrowserPref.INTERNAL; + else + choice = BrowserPref.EXTERNAL; + BrowserPref.setBrowserChoice(choice); + return true; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserSupportImpl.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserSupportImpl.java index 7cd088d3d..bf21a6525 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserSupportImpl.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserSupportImpl.java @@ -1,160 +1,160 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import java.util.HashMap; - -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.browser.IBrowser; -import org.xmind.ui.browser.IBrowserSupport; - -public class BrowserSupportImpl implements IBrowserSupport { - - private static class InternalMap extends HashMap { - - /** - * - */ - private static final long serialVersionUID = -6399662915430504209L; - - public InternalMap() { - super(4); - } - - } - - private static final String DEFAULT_CLIENT_ID = "org.xmind.ui.defaultBrowser"; //$NON-NLS-1$ - - private HashMap browsers = new HashMap(); - - public IBrowser createBrowser() { - return createBrowser(AS_DEFAULT, DEFAULT_CLIENT_ID, null, null); - } - - public IBrowser createBrowser(int style) { - return createBrowser(style, DEFAULT_CLIENT_ID, null, null); - } - - public IBrowser createBrowser(String browserClientId) { - return createBrowser(AS_DEFAULT, browserClientId, null, null); - } - - public IBrowser createBrowser(int style, String browserClientId) { - return createBrowser(style, browserClientId, null, null); - } - - public IBrowser createBrowser(int style, String browserClientId, - String name, String tooltip) { -// //If OS is linux,force to use external browser as a temporary solution for linux browser bug. -// if (Platform.OS_LINUX.equals(Platform.getOS())) { -// style = AS_EXTERNAL; -// } - - //Force to use external browser - style = AS_EXTERNAL; - - String browserId = BrowserUtil.encodeStyle( - browserClientId == null ? DEFAULT_CLIENT_ID : browserClientId, - style); - IBrowser existingBrowser = getExistingBrowser(style, browserId); - if (existingBrowser != null && matchesStyle(existingBrowser, style)) { - if (existingBrowser instanceof InternalBrowser) { - ((InternalBrowser) existingBrowser).setName(name); - ((InternalBrowser) existingBrowser).setTooltip(tooltip); - } - return existingBrowser; - } - - IBrowser newBrowser = doCreateBrowser(style, browserId, name, tooltip); - registerBrowser(newBrowser); - return newBrowser; - } - - private boolean matchesStyle(IBrowser browser, int style) { - if (isInternal(style)) - return browser instanceof InternalBrowser; - if (isExternal(style)) - return browser instanceof ExternalBrowser; - return browser instanceof DefaultBrowser; - } - - private IBrowser getExistingBrowser(int style, String browserClientId) { - Object object = browsers.get(browserClientId); - if (object != null) { - if (object instanceof IBrowser && isExternal(style)) - return (IBrowser) object; - if (object instanceof InternalMap && isInternal(style)) { - InternalMap map = (InternalMap) object; - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - return map.get(BrowserUtil.getWindowKey(window)); - } - } - } - return null; - } - - private boolean isInternal(int style) { - return (style & AS_INTERNAL) != 0 || ((style & IMPL_TYPES) == 0 - && BrowserPref.getBrowserChoice() == BrowserPref.INTERNAL); - } - - private boolean isExternal(int style) { - return style == AS_EXTERNAL || ((style & IMPL_TYPES) == 0 - && BrowserPref.getBrowserChoice() == BrowserPref.EXTERNAL); - } - - private IBrowser doCreateBrowser(int style, String browserClientId, - String name, String tooltip) { - /// no longer support internal browsers - return new ExternalBrowser(browserClientId); - } - - private void registerBrowser(IBrowser browser) { - String clientId = browser.getClientId(); - Object object = browsers.get(clientId); - if (browser instanceof InternalBrowser) { - Object key = ((InternalBrowser) browser).getWindowKey(); - if (object instanceof InternalMap) { - ((InternalMap) object).put(key, browser); - } else { - InternalMap map = new InternalMap(); - map.put(key, browser); - object = map; - } - } else { - object = browser; - } - browsers.put(clientId, object); - } - - void removeInternalBrowser(InternalBrowser browser) { - String id = browser.getClientId(); - Object key = browser.getWindowKey(); - Object object = browsers.get(id); - if (object instanceof InternalMap) { - InternalMap map = (InternalMap) object; - if (map != null) { - map.remove(key); - if (map.isEmpty()) - browsers.remove(id); - } - } else { - browsers.remove(id); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import java.util.HashMap; + +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.browser.IBrowser; +import org.xmind.ui.browser.IBrowserSupport; + +public class BrowserSupportImpl implements IBrowserSupport { + + private static class InternalMap extends HashMap { + + /** + * + */ + private static final long serialVersionUID = -6399662915430504209L; + + public InternalMap() { + super(4); + } + + } + + private static final String DEFAULT_CLIENT_ID = "org.xmind.ui.defaultBrowser"; //$NON-NLS-1$ + + private HashMap browsers = new HashMap(); + + public IBrowser createBrowser() { + return createBrowser(AS_DEFAULT, DEFAULT_CLIENT_ID, null, null); + } + + public IBrowser createBrowser(int style) { + return createBrowser(style, DEFAULT_CLIENT_ID, null, null); + } + + public IBrowser createBrowser(String browserClientId) { + return createBrowser(AS_DEFAULT, browserClientId, null, null); + } + + public IBrowser createBrowser(int style, String browserClientId) { + return createBrowser(style, browserClientId, null, null); + } + + public IBrowser createBrowser(int style, String browserClientId, + String name, String tooltip) { +// //If OS is linux,force to use external browser as a temporary solution for linux browser bug. +// if (Platform.OS_LINUX.equals(Platform.getOS())) { +// style = AS_EXTERNAL; +// } + + //Force to use external browser + style = AS_EXTERNAL; + + String browserId = BrowserUtil.encodeStyle( + browserClientId == null ? DEFAULT_CLIENT_ID : browserClientId, + style); + IBrowser existingBrowser = getExistingBrowser(style, browserId); + if (existingBrowser != null && matchesStyle(existingBrowser, style)) { + if (existingBrowser instanceof InternalBrowser) { + ((InternalBrowser) existingBrowser).setName(name); + ((InternalBrowser) existingBrowser).setTooltip(tooltip); + } + return existingBrowser; + } + + IBrowser newBrowser = doCreateBrowser(style, browserId, name, tooltip); + registerBrowser(newBrowser); + return newBrowser; + } + + private boolean matchesStyle(IBrowser browser, int style) { + if (isInternal(style)) + return browser instanceof InternalBrowser; + if (isExternal(style)) + return browser instanceof ExternalBrowser; + return browser instanceof DefaultBrowser; + } + + private IBrowser getExistingBrowser(int style, String browserClientId) { + Object object = browsers.get(browserClientId); + if (object != null) { + if (object instanceof IBrowser && isExternal(style)) + return (IBrowser) object; + if (object instanceof InternalMap && isInternal(style)) { + InternalMap map = (InternalMap) object; + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window != null) { + return map.get(BrowserUtil.getWindowKey(window)); + } + } + } + return null; + } + + private boolean isInternal(int style) { + return (style & AS_INTERNAL) != 0 || ((style & IMPL_TYPES) == 0 + && BrowserPref.getBrowserChoice() == BrowserPref.INTERNAL); + } + + private boolean isExternal(int style) { + return style == AS_EXTERNAL || ((style & IMPL_TYPES) == 0 + && BrowserPref.getBrowserChoice() == BrowserPref.EXTERNAL); + } + + private IBrowser doCreateBrowser(int style, String browserClientId, + String name, String tooltip) { + /// no longer support internal browsers + return new ExternalBrowser(browserClientId); + } + + private void registerBrowser(IBrowser browser) { + String clientId = browser.getClientId(); + Object object = browsers.get(clientId); + if (browser instanceof InternalBrowser) { + Object key = ((InternalBrowser) browser).getWindowKey(); + if (object instanceof InternalMap) { + ((InternalMap) object).put(key, browser); + } else { + InternalMap map = new InternalMap(); + map.put(key, browser); + object = map; + } + } else { + object = browser; + } + browsers.put(clientId, object); + } + + void removeInternalBrowser(InternalBrowser browser) { + String id = browser.getClientId(); + Object key = browser.getWindowKey(); + Object object = browsers.get(id); + if (object instanceof InternalMap) { + InternalMap map = (InternalMap) object; + if (map != null) { + map.remove(key); + if (map.isEmpty()) + browsers.remove(id); + } + } else { + browsers.remove(id); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserUtil.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserUtil.java index d817f04ec..4a42fc93a 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserUtil.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserUtil.java @@ -1,203 +1,203 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URLEncoder; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -public class BrowserUtil { - - private static final String BROWSER_PACKAGE_NAME = "org.eclipse.swt.browser.Browser"; //$NON-NLS-1$ - - private static Boolean isInternalBrowserOperational = null; - - private BrowserUtil() { - } - - public static Object getWindowKey(IWorkbenchWindow window) { - return new Integer(window.hashCode()); - } - - public static boolean gotoUrl(String url) { - if (url != null && !BrowserUtil.isWindows()) { - int index = url.indexOf(" "); //$NON-NLS-1$ - while (index >= 0) { - url = url.substring(0, index) + "%20" //$NON-NLS-1$ - + url.substring(index + 1); - index = url.indexOf(" "); //$NON-NLS-1$ - } - } - - boolean success = false; - try { - success = Program.launch(url); - } catch (Throwable th) { - Program program = Program.findProgram("html"); //$NON-NLS-1$ - if (program == null) { - program = Program.findProgram("htm"); //$NON-NLS-1$ - } - try { - if (program != null) - success = program.execute(url); - } catch (Throwable t) { - } - } - return success; - } - - /** - * Returns true if we're running on Windows. - * - * @return boolean - */ - public static boolean isWindows() { - String os = System.getProperty("os.name"); //$NON-NLS-1$ - if (os != null && os.toLowerCase().indexOf("win") >= 0) //$NON-NLS-1$ - return true; - return false; - } - - public static boolean canUseInternalWebBrowser() { - // if we have already figured this out, don't do it again. - if (isInternalBrowserOperational != null) - return isInternalBrowserOperational.booleanValue(); - - // check for the class - try { - Class.forName(BROWSER_PACKAGE_NAME); - } catch (ClassNotFoundException e) { - isInternalBrowserOperational = new Boolean(false); - return false; - } - - // try loading it - Shell shell = null; - try { - shell = new Shell(PlatformUI.getWorkbench().getDisplay()); - new Browser(shell, SWT.NONE); - isInternalBrowserOperational = new Boolean(true); - return true; - } catch (Throwable t) { - BrowserPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, BrowserPlugin.PLUGIN_ID, 0, - "Internal browser is not available: " //$NON-NLS-1$ - + t.getMessage(), - null)); - isInternalBrowserOperational = new Boolean(false); - return false; - } finally { - if (shell != null) - shell.dispose(); - } - } - - public static boolean canUseSystemBrowser() { - // Disabling system browser on Solaris due to bug 94497 - if (Platform.OS_SOLARIS.equals(Platform.getOS())) - return false; - return true; //Program.findProgram("html") != null; - } - - public static String encodeStyle(String clientId, int style) { - return clientId + "-" + style; //$NON-NLS-1$ - } - - public static int decodeStyle(String id) { - return Integer.parseInt(id.substring(id.lastIndexOf('-') + 1)); - } - - public static String decodeClientId(String id) { - return id.substring(0, id.lastIndexOf('-')); - } - - public static String normalizeURL(String url) { - if (url == null || "".equals(url)) //$NON-NLS-1$ - return url; - - if (!url.startsWith("http:") && !url.startsWith("https:")) //$NON-NLS-1$ //$NON-NLS-2$ - return url; - - URI uri; - try { - uri = new URI(url); - url = uri.toString(); - } catch (Exception ignore) { - uri = null; - } - - if (uri != null) { - String host = uri.getHost(); - if (host != null && host.endsWith(".xmind.net")) //$NON-NLS-1$ - /// make our server decide where exactly this url should go - return makeRedirectURL(url); - } - - return url; - } - - public static String makeRedirectURL(String url) { - StringBuffer buffer = new StringBuffer(100); - buffer.append("http://www.xmind.net/xmind/go?r="); //$NON-NLS-1$ - buffer.append(encode(url)); - buffer.append("&u="); //$NON-NLS-1$ - String user = System.getProperty("net.xmind.signin.account.user"); //$NON-NLS-1$ - if (user != null) { - buffer.append(encode(user)); - } - buffer.append("&t="); //$NON-NLS-1$ - String token = System.getProperty("net.xmind.signin.account.token"); //$NON-NLS-1$ - if (token != null) { - buffer.append(encode(token)); - buffer.append("&exp="); //$NON-NLS-1$ - buffer.append(encode(System - .getProperty("net.xmind.signin.account.expireDate", ""))); //$NON-NLS-1$ //$NON-NLS-2$ - } - String distributionId = System - .getProperty("org.xmind.product.distribution.id"); //$NON-NLS-1$ - if (distributionId != null) { - buffer.append("&distrib="); //$NON-NLS-1$ - buffer.append(encode(distributionId)); - } - buffer.append("&nl="); //$NON-NLS-1$ - buffer.append(encode(Platform.getNL())); - buffer.append("&os="); //$NON-NLS-1$ - buffer.append(encode(Platform.getOS())); - buffer.append("&arch="); //$NON-NLS-1$ - buffer.append(encode(Platform.getOSArch())); - buffer.append("&app="); //$NON-NLS-1$ - buffer.append(encode(Platform.getProduct().getApplication())); - - return buffer.toString(); - } - - private static String encode(String text) { - try { - return URLEncoder.encode(text, "UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - return text; - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLEncoder; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +public class BrowserUtil { + + private static final String BROWSER_PACKAGE_NAME = "org.eclipse.swt.browser.Browser"; //$NON-NLS-1$ + + private static Boolean isInternalBrowserOperational = null; + + private BrowserUtil() { + } + + public static Object getWindowKey(IWorkbenchWindow window) { + return new Integer(window.hashCode()); + } + + public static boolean gotoUrl(String url) { + if (url != null && !BrowserUtil.isWindows()) { + int index = url.indexOf(" "); //$NON-NLS-1$ + while (index >= 0) { + url = url.substring(0, index) + "%20" //$NON-NLS-1$ + + url.substring(index + 1); + index = url.indexOf(" "); //$NON-NLS-1$ + } + } + + boolean success = false; + try { + success = Program.launch(url); + } catch (Throwable th) { + Program program = Program.findProgram("html"); //$NON-NLS-1$ + if (program == null) { + program = Program.findProgram("htm"); //$NON-NLS-1$ + } + try { + if (program != null) + success = program.execute(url); + } catch (Throwable t) { + } + } + return success; + } + + /** + * Returns true if we're running on Windows. + * + * @return boolean + */ + public static boolean isWindows() { + String os = System.getProperty("os.name"); //$NON-NLS-1$ + if (os != null && os.toLowerCase().indexOf("win") >= 0) //$NON-NLS-1$ + return true; + return false; + } + + public static boolean canUseInternalWebBrowser() { + // if we have already figured this out, don't do it again. + if (isInternalBrowserOperational != null) + return isInternalBrowserOperational.booleanValue(); + + // check for the class + try { + Class.forName(BROWSER_PACKAGE_NAME); + } catch (ClassNotFoundException e) { + isInternalBrowserOperational = new Boolean(false); + return false; + } + + // try loading it + Shell shell = null; + try { + shell = new Shell(PlatformUI.getWorkbench().getDisplay()); + new Browser(shell, SWT.NONE); + isInternalBrowserOperational = new Boolean(true); + return true; + } catch (Throwable t) { + BrowserPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, BrowserPlugin.PLUGIN_ID, 0, + "Internal browser is not available: " //$NON-NLS-1$ + + t.getMessage(), + null)); + isInternalBrowserOperational = new Boolean(false); + return false; + } finally { + if (shell != null) + shell.dispose(); + } + } + + public static boolean canUseSystemBrowser() { + // Disabling system browser on Solaris due to bug 94497 + if (Platform.OS_SOLARIS.equals(Platform.getOS())) + return false; + return true; //Program.findProgram("html") != null; + } + + public static String encodeStyle(String clientId, int style) { + return clientId + "-" + style; //$NON-NLS-1$ + } + + public static int decodeStyle(String id) { + return Integer.parseInt(id.substring(id.lastIndexOf('-') + 1)); + } + + public static String decodeClientId(String id) { + return id.substring(0, id.lastIndexOf('-')); + } + + public static String normalizeURL(String url) { + if (url == null || "".equals(url)) //$NON-NLS-1$ + return url; + + if (!url.startsWith("http:") && !url.startsWith("https:")) //$NON-NLS-1$ //$NON-NLS-2$ + return url; + + URI uri; + try { + uri = new URI(url); + url = uri.toString(); + } catch (Exception ignore) { + uri = null; + } + + if (uri != null) { + String host = uri.getHost(); + if (host != null && host.endsWith(".xmind.net")) //$NON-NLS-1$ + /// make our server decide where exactly this url should go + return makeRedirectURL(url); + } + + return url; + } + + public static String makeRedirectURL(String url) { + StringBuffer buffer = new StringBuffer(100); + buffer.append("http://www.xmind.net/xmind/go?r="); //$NON-NLS-1$ + buffer.append(encode(url)); + buffer.append("&u="); //$NON-NLS-1$ + String user = System.getProperty("net.xmind.signin.account.user"); //$NON-NLS-1$ + if (user != null) { + buffer.append(encode(user)); + } + buffer.append("&t="); //$NON-NLS-1$ + String token = System.getProperty("net.xmind.signin.account.token"); //$NON-NLS-1$ + if (token != null) { + buffer.append(encode(token)); + buffer.append("&exp="); //$NON-NLS-1$ + buffer.append(encode(System + .getProperty("net.xmind.signin.account.expireDate", ""))); //$NON-NLS-1$ //$NON-NLS-2$ + } + String distributionId = System + .getProperty("org.xmind.product.distribution.id"); //$NON-NLS-1$ + if (distributionId != null) { + buffer.append("&distrib="); //$NON-NLS-1$ + buffer.append(encode(distributionId)); + } + buffer.append("&nl="); //$NON-NLS-1$ + buffer.append(encode(Platform.getNL())); + buffer.append("&os="); //$NON-NLS-1$ + buffer.append(encode(Platform.getOS())); + buffer.append("&arch="); //$NON-NLS-1$ + buffer.append(encode(Platform.getOSArch())); + buffer.append("&app="); //$NON-NLS-1$ + buffer.append(encode(Platform.getProduct().getApplication())); + + return buffer.toString(); + } + + private static String encode(String text) { + try { + return URLEncoder.encode(text, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + return text; + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserViewer.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserViewer.java index f4f28f819..828641c97 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserViewer.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/BrowserViewer.java @@ -1,1410 +1,1410 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.browser; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTError; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.CloseWindowListener; -import org.eclipse.swt.browser.LocationEvent; -import org.eclipse.swt.browser.LocationListener; -import org.eclipse.swt.browser.OpenWindowListener; -import org.eclipse.swt.browser.ProgressEvent; -import org.eclipse.swt.browser.ProgressListener; -import org.eclipse.swt.browser.StatusTextEvent; -import org.eclipse.swt.browser.StatusTextListener; -import org.eclipse.swt.browser.TitleEvent; -import org.eclipse.swt.browser.TitleListener; -import org.eclipse.swt.browser.VisibilityWindowListener; -import org.eclipse.swt.browser.WindowEvent; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.dnd.Clipboard; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.ui.PartInitException; -import org.xmind.ui.animation.AnimationViewer; -import org.xmind.ui.animation.IAnimationContentProvider; -import org.xmind.ui.browser.BrowserSupport; -import org.xmind.ui.browser.IBrowser; -import org.xmind.ui.browser.IBrowserSupport; -import org.xmind.ui.browser.IBrowserViewer; -import org.xmind.ui.browser.IBrowserViewerContainer; -import org.xmind.ui.browser.IBrowserViewerContribution; -import org.xmind.ui.browser.IBrowserViewerContribution2; -import org.xmind.ui.browser.IPropertyChangingListener; -import org.xmind.ui.browser.PropertyChangingEvent; -import org.xmind.ui.viewers.ImageCachedLabelProvider; - -/** - * A viewer implementing a web browser. It provides an embeded SWT Browser - * widget with an optional toolbar consisting of a URL combo box, back & forward - * buttons, a refresh button and a home logo. - */ -public class BrowserViewer implements IBrowserViewer { - - private static Object DEFAULT_BUSY_PICTURES = null; - - private static class BusyIndicatorContentProvider - extends ArrayContentProvider implements IAnimationContentProvider { - public long getDuration(Object element) { - return SWT.DEFAULT; // use default duration - } - - public Object getStaticElement(Object inputElement, Object[] elements) { - return elements[0]; - } - } - - private static class BusyIndicatorLabelProvider - extends ImageCachedLabelProvider { - protected Image createImage(Object element) { - if (element instanceof ImageDescriptor) { - ImageDescriptor desc = (ImageDescriptor) element; - return desc.createImage(false); - } - return null; - } - } - - private class OpenInExternalAction extends Action { - - public OpenInExternalAction() { - super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, - BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); - setToolTipText( - BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); - } - - public void run() { - IBrowser browser = BrowserSupport.getInstance() - .createBrowser(IBrowserSupport.AS_EXTERNAL); - try { - browser.openURL(getURL()); - } catch (PartInitException e) { - BrowserPlugin.log(e); - } - } - } - - private class BackAction extends Action { - public BackAction() { - super(BrowserMessages.BrowserViewer_PrevPage_toolTip, BrowserImages - .getImageDescriptor(BrowserImages.BACKWARD, true)); - setToolTipText(BrowserMessages.BrowserViewer_PrevPage_toolTip); - setDisabledImageDescriptor(BrowserImages - .getImageDescriptor(BrowserImages.BACKWARD, false)); - } - - public void run() { - back(); - } - } - - private class ForwardAction extends Action { - public ForwardAction() { - super(BrowserMessages.BrowserViewer_NextPage_toolTip, BrowserImages - .getImageDescriptor(BrowserImages.FORWARD, true)); - setToolTipText(BrowserMessages.BrowserViewer_NextPage_toolTip); - setDisabledImageDescriptor(BrowserImages - .getImageDescriptor(BrowserImages.FORWARD, false)); - } - - public void run() { - forward(); - } - } - - private class StopRefreshAction extends Action { - private boolean stop = false; - - public StopRefreshAction() { - setRefresh(); - } - - public void setStop() { - stop = true; - setText(BrowserMessages.BrowserViewer_Stop_toolTip); - setToolTipText(BrowserMessages.BrowserViewer_Stop_toolTip); - setImageDescriptor( - BrowserImages.getImageDescriptor(BrowserImages.STOP, true)); - setDisabledImageDescriptor(BrowserImages - .getImageDescriptor(BrowserImages.STOP, false)); - } - - public void setRefresh() { - stop = false; - setText(BrowserMessages.BrowserViewer_Refresh_toolTip); - setToolTipText(BrowserMessages.BrowserViewer_Refresh_toolTip); - setImageDescriptor(BrowserImages - .getImageDescriptor(BrowserImages.REFRESH, true)); - setDisabledImageDescriptor(BrowserImages - .getImageDescriptor(BrowserImages.REFRESH, false)); - } - - public void run() { - if (stop) { - stop(); - } else { - refresh(); - } - } - } - - protected class BrowserListener implements LocationListener, - OpenWindowListener, VisibilityWindowListener, CloseWindowListener, - ProgressListener, TitleListener, StatusTextListener { - - private String locationText; - - private String titleText; - - private String statusText; - - public void hook(Browser browser) { - browser.addLocationListener(this); - browser.addOpenWindowListener(this); - browser.addVisibilityWindowListener(this); - browser.addCloseWindowListener(this); - browser.addProgressListener(this); - browser.addTitleListener(this); - browser.addStatusTextListener(this); - } - - public void unhook(Browser browser) { - browser.removeLocationListener(this); - browser.removeOpenWindowListener(this); - browser.removeVisibilityWindowListener(this); - browser.removeCloseWindowListener(this); - browser.removeProgressListener(this); - browser.removeTitleListener(this); - browser.removeStatusTextListener(this); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt. - * browser.LocationEvent) - */ - public void changed(LocationEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (!event.top) - return; - if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ - String oldLocation = locationText; - locationText = event.location; - if (location != null) { - location.setText(event.location); - } - addToHistory(event.location); - updateHistory(); - firePropertyChangeEvent(PROPERTY_LOCATION, oldLocation, - event.location); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.LocationListener#changing(org.eclipse.swt - * .browser.LocationEvent) - */ - public void changing(LocationEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ - event.doit = firePropertyChangingEvent(PROPERTY_LOCATION, - locationText, event.location, event.doit); - if (event.doit && redirect) { - event.location = makeRedirectUrl(event.location); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.browser.OpenWindowListener#open(org.eclipse.swt. - * browser .WindowEvent) - */ - public void open(WindowEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (container != null) { - event.browser = container.openNewBrowser(); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.VisibilityWindowListener#hide(org.eclipse - * .swt.browser.WindowEvent) - */ - public void hide(WindowEvent event) { - // do nothing - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.VisibilityWindowListener#show(org.eclipse - * .swt.browser.WindowEvent) - */ - public void show(WindowEvent event) { -// if (event.widget == browser) { -// if (composite.getParent() instanceof Shell) { -// Shell shell = (Shell) composite.getParent(); -// if (event.location != null) -// shell.setLocation(event.location); -// if (event.size != null) -// shell.setSize(shell.computeSize(event.size.x, -// event.size.y)); -// shell.open(); -// } -// } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.CloseWindowListener#close(org.eclipse.swt - * .browser.WindowEvent) - */ - public void close(WindowEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (container != null) { - container.close(); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.ProgressListener#changed(org.eclipse.swt. - * browser.ProgressEvent) - */ - public void changed(ProgressEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (event.total == 0) - return; - - boolean done = (event.current == event.total); - - int percentProgress = event.current * 100 / event.total; - if (container != null) { - IProgressMonitor monitor = container.getActionBars() - .getStatusLineManager().getProgressMonitor(); - if (done) { - monitor.done(); - progressWorked = 0; - } else if (progressWorked == 0) { - monitor.beginTask("", event.total); //$NON-NLS-1$ - progressWorked = percentProgress; - } else { - monitor.worked(event.current - progressWorked); - progressWorked = event.current; - } - } - - if (homeBusy != null) { - if (!homeBusy.isAnimating() && !done) - setLoading(true); - else if (homeBusy.isAnimating() && done) // once the progress hits - // 100 percent, done, set - // busy to false - setLoading(false); - } - - updateBackNextBusy(); - updateHistory(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.ProgressListener#completed(org.eclipse.swt - * .browser.ProgressEvent) - */ - public void completed(ProgressEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - if (container != null) { - IProgressMonitor monitor = container.getActionBars() - .getStatusLineManager().getProgressMonitor(); - monitor.done(); - } - setLoading(false); - updateBackNextBusy(); - updateHistory(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser - * .TitleEvent) - */ - public void changed(TitleEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - String oldTitle = titleText; - titleText = event.title; - firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, titleText); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt - * .browser.StatusTextEvent) - */ - public void changed(StatusTextEvent event) { - if (getControl() == null || getControl().isDisposed()) - return; - boolean doit = true; - String oldStatus = statusText; - if (!firePropertyChangingEvent(PROPERTY_STATUS, oldStatus, - event.text, doit)) { - event.text = ""; //$NON-NLS-1$ - } - if (container != null) { - IStatusLineManager status = container.getActionBars() - .getStatusLineManager(); - status.setMessage(event.text); - } - statusText = event.text; - firePropertyChangeEvent(PROPERTY_STATUS, oldStatus, statusText); - } - - } - - private static final int MAX_HISTORY = 50; - - private static final String URL_HOME = "http://www.xmind.net"; //$NON-NLS-1$ - - private static List URL_HISTORY; - - private Composite composite; - - private boolean mozilla; - - private Clipboard clipboard; - - private Composite toolBar; - - private ToolBarManager actionBar; - - private Combo location; - - private AnimationViewer homeBusy; - - private boolean loading; - - private Composite browserContainer; - - private Browser browser; - -// private Browser alternateBrowser; - - private BrowserListener browserListener; - - private BrowserErrorText errorText; - -// private boolean newWindow; - - private IBrowserViewerContainer container; - - private int progressWorked = 0; - - private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( - this); - - private BackAction backAction; - - private ForwardAction forwardAction; - - private StopRefreshAction stopRefreshAction; - - private boolean redirect = true; - - private int style = 0; - - private Label description; - - public BrowserViewer(Composite parent, int style) { - this(parent, style, null); - } - - public BrowserViewer(Composite parent, int style, - IBrowserViewerContainer container) { - this.style = style; - this.container = container; - this.composite = new Composite(parent, style); - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - layout.numColumns = 1; - this.composite.setLayout(layout); - this.composite - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - createContents(this.composite); - hookControl(this.composite); - } - - public int getStyle() { - return style; - } - - Label getDescriptionLabel() { - return description; - } - - protected void hookControl(Control control) { - control.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - handleDispose(); - } - }); - for (IBrowserViewerContribution contribution : BrowserContributionManager - .getInstance().getContributions()) { - if (contribution instanceof IBrowserViewerContribution2) { - ((IBrowserViewerContribution2) contribution) - .installBrowserListeners(this); - } - } - } - - protected void createContents(Composite parent) { - clipboard = new Clipboard(parent.getDisplay()); - createToolBar(parent); - createBrowser(parent); - updateWithStyle(); - updateHistory(); - updateBackNextBusy(); -// if (browserContainer != null) { -// } else { -// errorText.getControl().setLayoutData( -// new GridData(SWT.FILL, SWT.FILL, true, true)); -// } -// addBrowserListeners(browser); - } - - protected void createToolBar(Composite parent) { - toolBar = new Composite(parent, SWT.NONE); - GridLayout toolbarLayout = new GridLayout(); - toolbarLayout.marginHeight = 2; - toolbarLayout.marginWidth = 2; - toolbarLayout.horizontalSpacing = 5; - toolbarLayout.verticalSpacing = 0; - toolBar.setLayout(toolbarLayout); - toolBar.setLayoutData( - new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - createActionBar(toolBar); - createLocationBar(toolBar); - //forbid extra contributions, such as SearchBoxContribution - //if accept in the future, we can delete browserViewerContributions extension about search box. -// createExtraContributions(toolBar); - createHomeBusyIndicator(toolBar); - toolbarLayout.numColumns = toolBar.getChildren().length; - } - -// private void createExtraContributions(final Composite toolbarContainer) { -// ContributionManager manager = new ContributionManager() { -// public void update(boolean force) { -// if ((style & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) == 0) { -// for (IContributionItem item : getItems()) { -// item.fill(toolbarContainer); -// } -// } -// } -// }; -// for (IBrowserViewerContribution contribution : BrowserContributionManager -// .getInstance().getContributions()) { -// contribution.fillToolBar(this, manager); -// } -// manager.update(true); -// } - - private void createActionBar(Composite parent) { - actionBar = new ToolBarManager(SWT.FLAT); - actionBar.add(new OpenInExternalAction()); - actionBar.add(backAction = new BackAction()); - actionBar.add(forwardAction = new ForwardAction()); - actionBar.add(stopRefreshAction = new StopRefreshAction()); - actionBar.createControl(parent); - actionBar.getControl().setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, false, false)); - } - - private void createLocationBar(Composite parent) { - location = new Combo(parent, SWT.BORDER | SWT.DROP_DOWN); - location.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - description = new Label(parent, SWT.NONE); - description.setText(""); //$NON-NLS-1$ - description - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - updateHistory(); - - /* - * We ignore selection event to avoid unneccessary selection (e.g. mouse - * scrolling in the combo, arrow up/down, or even showing drop-down on - * some platforms). User must press Enter whenver they have selected an - * item in order to go to that URL. - */ -// location.addSelectionListener(new SelectionAdapter() { -// @Override -// public void widgetSelected(SelectionEvent we) { -// try { -// if (location.getSelectionIndex() != -1) -// setURL(location.getItem(location.getSelectionIndex())); -// } catch (Exception ignore) { -// } -// } -// }); - location.addListener(SWT.FocusIn, new Listener() { - public void handleEvent(Event event) { - int end = location.getText().length(); - location.setSelection(new Point(0, end)); - } - }); - location.addListener(SWT.DefaultSelection, new Listener() { - public void handleEvent(Event e) { - setURL(location.getText()); - } - }); - } - - protected void createHomeBusyIndicator(Composite parenet) { - homeBusy = new AnimationViewer(parenet, SWT.NONE); - homeBusy.setContentProvider(new BusyIndicatorContentProvider()); - homeBusy.setLabelProvider(new BusyIndicatorLabelProvider()); - homeBusy.setInput(getDefaultBusyPictures()); - homeBusy.getControl() - .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); - homeBusy.getControl().addListener(SWT.MouseDown, new Listener() { - public void handleEvent(Event event) { - setURL(URL_HOME); - } - }); - } - - public AnimationViewer getBusyIndicator() { - return homeBusy; - } - - protected void createBrowser(Composite parent) { - browserContainer = new Composite(parent, SWT.NONE); - browserContainer.setLayout(new StackLayout()); - browserContainer - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - Browser b = null; -// try { -// // try Mozilla -// b = createBrowser(browserContainer, SWT.MOZILLA | SWT.BORDER); -// mozilla = true; -// } catch (SWTError e) { -// mozilla = false; - try { - // try default browser - b = createBrowser(browserContainer, SWT.NONE); - } catch (SWTError e2) { - if (e2.code != SWT.ERROR_NO_HANDLES) { - return; - } - // show error text - errorText = new BrowserErrorText(browserContainer, this, e2); - } -// } - if (b != null) { - this.browser = b; - } - - mozilla = b != null && "mozilla".equals(b.getBrowserType()); //$NON-NLS-1$ - if (mozilla) - new MozillaPref(this); - - browserListener = new BrowserListener(); - - if (browser != null) { - browserListener.hook(browser); - show(browser); - } else { - show(errorText.getControl()); - } - } - - private void show(Control control) { - ((StackLayout) browserContainer.getLayout()).topControl = control; - for (Control c : browserContainer.getChildren()) { - c.setVisible(c == control); - } - browserContainer.layout(); - } - -// private void changeBrowser() { -// if (errorText != null) -// return; -// -// ensureAlternateBrowser(); -// if (alternateBrowser == null || alternateBrowser.isDisposed()) -// return; -// -// browserListener.unhook(browser); -// -// Browser temp = alternateBrowser; -// alternateBrowser = browser; -// browser = temp; -// -// browserListener.hook(browser); -// show(browser); -// } -// -// private void ensureAlternateBrowser() { -// if (alternateBrowser != null && !alternateBrowser.isDisposed()) -// return; -// -// if (errorText != null) -// return; -// -// try { -// if (mozilla) { -// alternateBrowser = new Browser(browserContainer, SWT.MOZILLA -// | SWT.BORDER); -// } else { -// alternateBrowser = new Browser(browserContainer, SWT.NONE); -// } -// -// } catch (SWTError e) { -// if (e.code != SWT.ERROR_NO_HANDLES) { -// return; -// } -// errorText = new BrowserErrorText(browserContainer, this, e); -// } -// -// if (alternateBrowser != null) { -// alternateBrowser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, -// true, true)); -// } else { -// errorText.getControl().setLayoutData( -// new GridData(SWT.FILL, SWT.FILL, true, true)); -// } -// } - - private Browser createBrowser(Composite parent, int style) { - return new Browser(parent, style); - } - - public void changeStyle(int newStyle) { - this.style = newStyle; - if (composite != null && !composite.isDisposed()) { - updateWithStyle(); - } - } - - protected void updateWithStyle() { - boolean locationVisible = (style - & IBrowserSupport.NO_LOCATION_BAR) == 0; - location.setVisible(locationVisible); - ((GridData) location.getLayoutData()).exclude = !locationVisible; - - boolean descriptionVisible = !locationVisible; - description.setVisible(descriptionVisible); - ((GridData) description.getLayoutData()).exclude = !descriptionVisible; - - toolBar.layout(true); - - boolean hasToolBar = (style & IBrowserSupport.NO_TOOLBAR) == 0; - toolBar.setVisible(hasToolBar); - ((GridData) toolBar.getLayoutData()).exclude = !hasToolBar; - - composite.layout(true); - } - - public Browser getBrowser() { - return browser; - } - - public Control getControl() { - return composite; - } - - private void home() { - if (browser == null || browser.isDisposed()) - return; - browser.setText(""); //$NON-NLS-1$ - } - - /** - * Loads a URL. - * - * @param url - * the URL to be loaded - * @return true if the operation was successful and false otherwise. - * @exception IllegalArgumentException - *
      - *
    • ERROR_NULL_ARGUMENT - if the url is null
    • - *
    - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - * @see #getURL() - */ - public boolean setURL(String url) { - return setURL(url, true); - } - - private boolean setURL(String url, boolean browse) { - if (url == null) { - home(); - return true; - } - - if ("xmind".equalsIgnoreCase(url)) //$NON-NLS-1$ - url = URL_HOME; - - if (redirect) { - url = makeRedirectUrl(url); - } - - if (browse) - navigate(url); - - addToHistory(url); - updateHistory(); - return true; - } - - protected void updateBackNextBusy() { - if (backAction != null) - backAction.setEnabled(isBackEnabled()); - if (forwardAction != null) - forwardAction.setEnabled(isForwardEnabled()); - if (homeBusy != null && homeBusy.getControl() != null - && !homeBusy.getControl().isDisposed()) { - if (loading) { - homeBusy.start(); - } else { - homeBusy.stop(); - } - } - } - -// /** -// * -// */ -// private void addBrowserListeners(Browser browser) { -// if (browser == null) -// return; -// -// browser.addStatusTextListener(new StatusTextListener() { -// public void changed(StatusTextEvent event) { -// if (container != null) { -// IStatusLineManager status = container.getActionBars() -// .getStatusLineManager(); -// status.setMessage(event.text); -// } -// } -// }); -// -// /* -// * Add listener for new window creation. Use just the same browser for -// * the new window. -// */ -// browser.addOpenWindowListener(new OpenWindowListener() { -// public void open(WindowEvent event) { -// event.browser = BrowserViewer.this.browser; -// -// // Forget about the following way.... -// -//// Display display = Display.getCurrent(); -//// final Shell tempShell = new Shell(display); -//// tempShell.setBounds(-100, -100, 50, 50); -//// tempShell.setLayout(new FillLayout()); -//// BrowserViewer tempBrowserViewer = new BrowserViewer(tempShell, -//// 0, null); -//// tempBrowserViewer.newWindow = true; -//// Browser tempBrowser = tempBrowserViewer.browser; -//// tempBrowser.addLocationListener(new LocationListener() { -//// -//// public void changing(LocationEvent event) { -//// } -//// -//// public void changed(LocationEvent event) { -//// String url = event.location; -//// if (container != null && url != null && !"".equals(url)) { //$NON-NLS-1$ -//// container.openInExternalBrowser(url); -//// } -//// tempShell.close(); -//// tempShell.dispose(); -//// } -//// -//// }); -//// event.browser = tempBrowser; -// } -// }); -// -// browser.addVisibilityWindowListener(new VisibilityWindowListener() { -// public void hide(WindowEvent e) { -// } -// -// public void show(WindowEvent e) { -// Browser browser2 = (Browser) e.widget; -// if (browser2.getParent().getParent() instanceof Shell) { -// Shell shell = (Shell) browser2.getParent().getParent(); -// if (e.location != null) -// shell.setLocation(e.location); -// if (e.size != null) -// shell.setSize(shell.computeSize(e.size.x, e.size.y)); -// shell.open(); -// } -// } -// }); -// -// browser.addCloseWindowListener(new CloseWindowListener() { -// public void close(WindowEvent event) { -// // if shell is not null, it must be a secondary popup window, -// // else its an editor window -//// if (newWindow) { -//// getControl().getShell().dispose(); -//// } else { -//// container.close(); -//// } -// } -// }); -// -// browser.addProgressListener(new ProgressListener() { -// public void changed(ProgressEvent event) { -// if (event.total == 0) -// return; -// -// boolean done = (event.current == event.total); -// -// int percentProgress = event.current * 100 / event.total; -// if (container != null) { -// IProgressMonitor monitor = container.getActionBars() -// .getStatusLineManager().getProgressMonitor(); -// if (done) { -// monitor.done(); -// progressWorked = 0; -// } else if (progressWorked == 0) { -// monitor.beginTask("", event.total); //$NON-NLS-1$ -// progressWorked = percentProgress; -// } else { -// monitor.worked(event.current - progressWorked); -// progressWorked = event.current; -// } -// } -// -// if (!homeBusy.isAnimating() && !done) -// setLoading(true); -// else if (homeBusy.isAnimating() && done) // once the progress hits -// // 100 percent, done, set -// // busy to false -// setLoading(false); -// -// updateBackNextBusy(); -// updateHistory(); -// } -// -// public void completed(ProgressEvent event) { -// if (container != null) { -// IProgressMonitor monitor = container.getActionBars() -// .getStatusLineManager().getProgressMonitor(); -// monitor.done(); -// } -// setLoading(false); -// updateBackNextBusy(); -// updateHistory(); -// } -// }); -// -// browser.addLocationListener(new LocationListener() { -// public void changed(LocationEvent event) { -// if (!event.top) -// return; -// if (location != null) { -// if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ -// String oldLocation = location.getText(); -// location.setText(event.location); -// addToHistory(event.location); -// updateHistory(); -// firePropertyChangeEvent(PROPERTY_LOCATION, -// event.location, oldLocation); -// } -// } -// } -// -// public void changing(LocationEvent event) { -// // do nothing -// } -// }); -// -// browser.addTitleListener(new TitleListener() { -// public void changed(TitleEvent event) { -// String oldTitle = title; -// title = event.title; -// firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, title); -// } -// }); -// -// } - - public Combo getLocationBar() { - return location; - } - - public Clipboard getClipboard() { - return clipboard; - } - - public void copy() { - if (location == null || location.isDisposed() - || !location.isFocusControl()) - return; - - location.copy(); - } - - public void cut() { - if (location == null || location.isDisposed() - || !location.isFocusControl()) - return; - - location.cut(); - } - - public void delete() { - if (location == null || location.isDisposed() - || !location.isFocusControl()) - return; - - String text = location.getText(); - Point selection = location.getSelection(); - if (selection.y > selection.x) { - text = text.substring(0, selection.x) + text.substring(selection.y); - location.setText(text); - location.setSelection(new Point(selection.x, selection.x)); - } - } - - public void paste() { - if (location == null || location.isDisposed() - || !location.isFocusControl()) - return; - - location.paste(); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - propertyChangeSupport.addPropertyChangeListener(listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - propertyChangeSupport.removePropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - propertyChangeSupport.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - propertyChangeSupport.removePropertyChangeListener(propertyName, - listener); - } - - protected void firePropertyChangeEvent(String propertyName, Object oldValue, - Object newValue) { - propertyChangeSupport.firePropertyChange(propertyName, oldValue, - newValue); - } - - protected boolean firePropertyChangingEvent(String propertyName, - Object oldValue, Object newValue, boolean doit) { - PropertyChangingEvent event = new PropertyChangingEvent(this, - propertyName, oldValue, newValue, doit); - PropertyChangeListener[] listeners = propertyChangeSupport - .getPropertyChangeListeners(); - if (firePropertyChangingEvent(listeners, event)) { - listeners = propertyChangeSupport - .getPropertyChangeListeners(propertyName); - return firePropertyChangingEvent(listeners, event); - } - return event.doit; - } - - private boolean firePropertyChangingEvent( - PropertyChangeListener[] listeners, PropertyChangingEvent event) { - for (Object pcl : listeners) { - if (pcl instanceof IPropertyChangingListener) { - try { - ((IPropertyChangingListener) pcl).propertyChanging(event); - } catch (Throwable ignore) { - } - } - } - return event.doit; - } - - /** - * Navigate to the next session history item. Convenience method that calls - * the underlying SWT browser. - * - * @return true if the operation was successful and - * false otherwise - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - */ - public boolean forward() { - if (browser == null || browser.isDisposed()) - return false; - boolean forward = browser.forward(); - if (!forward) { - - } - return forward; - } - - /** - * Navigate to the previous session history item. Convenience method that - * calls the underlying SWT browser. - * - * @return true if the operation was successful and - * false otherwise - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - */ - public boolean back() { - if (browser == null || browser.isDisposed()) - return false; - return browser.back(); - } - - /** - * Returns true if the receiver can navigate to the previous - * session history item, and false otherwise. Convenience - * method that calls the underlying SWT browser. - * - * @return the receiver's back command enabled state - * @exception SWTException - *
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
    • - *
    - */ - public boolean isBackEnabled() { - if (browser == null || browser.isDisposed()) - return false; - return browser.isBackEnabled(); - } - - /** - * Returns true if the receiver can navigate to the next - * session history item, and false otherwise. Convenience - * method that calls the underlying SWT browser. - * - * @return the receiver's forward command enabled state - * @exception SWTException - *
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
    • - *
    - */ - public boolean isForwardEnabled() { - if (browser == null || browser.isDisposed()) - return false; - return browser.isForwardEnabled(); - } - - /** - * Stop any loading and rendering activity. Convenience method that calls - * the underlying SWT browser. - * - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - */ - public void stop() { - if (browser != null && !browser.isDisposed()) - browser.stop(); - setLoading(false); - } - - public boolean setText(String html) { - return false; - } - - private boolean navigate(String url) { - if (url != null && url.equals(getURL())) { - refresh(); - return true; - } - if (browser != null && !browser.isDisposed()) - return browser.setUrl(url); - if (errorText != null && errorText.getControl() != null - && !errorText.getControl().isDisposed()) - return errorText.setUrl(url); - return false; - } - - /** - * Refresh the current page. Convenience method that calls the underlying - * SWT browser. - * - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - */ - public void refresh() { - if (browser != null) { - if (!browser.isDisposed()) - browser.refresh(); - } else { - if (errorText != null && errorText.getControl() != null - && !errorText.getControl().isDisposed()) - errorText.refresh(); - } - try { - Thread.sleep(50); - } catch (Exception ignore) { - } - } - - protected void addToHistory(String url) { - if (URL_HISTORY == null) - URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); - int found = -1; - int size = URL_HISTORY.size(); - for (int i = 0; i < size; i++) { - String s = URL_HISTORY.get(i); - if (s.equals(url)) { - found = i; - break; - } - } - - if (found == -1) { - if (size >= MAX_HISTORY) - URL_HISTORY.remove(size - 1); - URL_HISTORY.add(0, url); - BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); - } else if (found != 0) { - URL_HISTORY.remove(found); - URL_HISTORY.add(0, url); - BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); - } - } - - protected void handleDispose() { - for (IBrowserViewerContribution contribution : BrowserContributionManager - .getInstance().getContributions()) { - if (contribution instanceof IBrowserViewerContribution2) { - ((IBrowserViewerContribution2) contribution) - .uninstallBrowserListeners(this); - } - } - if (this.container != null) { - IStatusLineManager manager = this.container.getActionBars() - .getStatusLineManager(); - if (manager != null) - manager.getProgressMonitor().done(); - } - homeBusy = null; - browser = null; - errorText = null; - if (clipboard != null) - clipboard.dispose(); - clipboard = null; - } - - private void setLoading(boolean loading) { - this.loading = loading; - if (loading) { - if (stopRefreshAction != null) { - stopRefreshAction.setStop(); - } - } else { - if (stopRefreshAction != null) { - stopRefreshAction.setRefresh(); - } - if (homeBusy != null && homeBusy.getControl() != null - && !homeBusy.getControl().isDisposed()) - homeBusy.stop(); - if (container != null) { - IProgressMonitor monitor = container.getActionBars() - .getStatusLineManager().getProgressMonitor(); - monitor.done(); - } - } - } - - /** - * Returns the current URL. Convenience method that calls the underlying SWT - * browser. - * - * @return the current URL or an empty String if there is no - * current URL - * @exception SWTException - *
      - *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong - * thread
    • - *
    • ERROR_WIDGET_DISPOSED when the widget has been - * disposed
    • - *
    - * @see #setURL(String) - */ - public String getURL() { - if (browser != null) - return browser.getUrl(); - return errorText.getUrl(); - } - - protected void updateHistory() { - if (location == null || location.isDisposed()) - return; - - String temp = location.getText(); - if (URL_HISTORY == null) - URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); - - String[] historyList = new String[URL_HISTORY.size()]; - URL_HISTORY.toArray(historyList); - location.setItems(historyList); - - location.setText(temp); - } - - public IBrowserViewerContainer getContainer() { - return container; - } - - public void setFocus() { - if (browser != null && !browser.isDisposed()) { - if (browser.setFocus()) { - updateHistory(); - } else if (location != null) { - location.setFocus(); - } - } - } - - /** - * @return the mozilla - */ - public boolean isMozilla() { - return mozilla; - } - - public BackAction getBackAction() { - return backAction; - } - - public ForwardAction getForwardAction() { - return forwardAction; - } - - public StopRefreshAction getStopRefreshAction() { - return stopRefreshAction; - } - - private static Object getDefaultBusyPictures() { - if (DEFAULT_BUSY_PICTURES == null) { - ArrayList list = new ArrayList( - 13); - list.add(BrowserImages.getImageDescriptor(BrowserImages.XMIND)); - list.addAll(Arrays.asList(BrowserImages.getBusyImages())); - DEFAULT_BUSY_PICTURES = list.toArray(); - } - return DEFAULT_BUSY_PICTURES; - } - - private String makeRedirectUrl(String source) { - if (!source.startsWith("file:")) { //$NON-NLS-1$ - try { - return BrowserUtil.makeRedirectURL(source); - } catch (Throwable e) { - //ignore - } finally { - redirect = false; - } - } - return source; - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.browser; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.CloseWindowListener; +import org.eclipse.swt.browser.LocationEvent; +import org.eclipse.swt.browser.LocationListener; +import org.eclipse.swt.browser.OpenWindowListener; +import org.eclipse.swt.browser.ProgressEvent; +import org.eclipse.swt.browser.ProgressListener; +import org.eclipse.swt.browser.StatusTextEvent; +import org.eclipse.swt.browser.StatusTextListener; +import org.eclipse.swt.browser.TitleEvent; +import org.eclipse.swt.browser.TitleListener; +import org.eclipse.swt.browser.VisibilityWindowListener; +import org.eclipse.swt.browser.WindowEvent; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.PartInitException; +import org.xmind.ui.animation.AnimationViewer; +import org.xmind.ui.animation.IAnimationContentProvider; +import org.xmind.ui.browser.BrowserSupport; +import org.xmind.ui.browser.IBrowser; +import org.xmind.ui.browser.IBrowserSupport; +import org.xmind.ui.browser.IBrowserViewer; +import org.xmind.ui.browser.IBrowserViewerContainer; +import org.xmind.ui.browser.IBrowserViewerContribution; +import org.xmind.ui.browser.IBrowserViewerContribution2; +import org.xmind.ui.browser.IPropertyChangingListener; +import org.xmind.ui.browser.PropertyChangingEvent; +import org.xmind.ui.viewers.ImageCachedLabelProvider; + +/** + * A viewer implementing a web browser. It provides an embeded SWT Browser + * widget with an optional toolbar consisting of a URL combo box, back & forward + * buttons, a refresh button and a home logo. + */ +public class BrowserViewer implements IBrowserViewer { + + private static Object DEFAULT_BUSY_PICTURES = null; + + private static class BusyIndicatorContentProvider + extends ArrayContentProvider implements IAnimationContentProvider { + public long getDuration(Object element) { + return SWT.DEFAULT; // use default duration + } + + public Object getStaticElement(Object inputElement, Object[] elements) { + return elements[0]; + } + } + + private static class BusyIndicatorLabelProvider + extends ImageCachedLabelProvider { + protected Image createImage(Object element) { + if (element instanceof ImageDescriptor) { + ImageDescriptor desc = (ImageDescriptor) element; + return desc.createImage(false); + } + return null; + } + } + + private class OpenInExternalAction extends Action { + + public OpenInExternalAction() { + super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, + BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); + setToolTipText( + BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); + } + + public void run() { + IBrowser browser = BrowserSupport.getInstance() + .createBrowser(IBrowserSupport.AS_EXTERNAL); + try { + browser.openURL(getURL()); + } catch (PartInitException e) { + BrowserPlugin.log(e); + } + } + } + + private class BackAction extends Action { + public BackAction() { + super(BrowserMessages.BrowserViewer_PrevPage_toolTip, BrowserImages + .getImageDescriptor(BrowserImages.BACKWARD, true)); + setToolTipText(BrowserMessages.BrowserViewer_PrevPage_toolTip); + setDisabledImageDescriptor(BrowserImages + .getImageDescriptor(BrowserImages.BACKWARD, false)); + } + + public void run() { + back(); + } + } + + private class ForwardAction extends Action { + public ForwardAction() { + super(BrowserMessages.BrowserViewer_NextPage_toolTip, BrowserImages + .getImageDescriptor(BrowserImages.FORWARD, true)); + setToolTipText(BrowserMessages.BrowserViewer_NextPage_toolTip); + setDisabledImageDescriptor(BrowserImages + .getImageDescriptor(BrowserImages.FORWARD, false)); + } + + public void run() { + forward(); + } + } + + private class StopRefreshAction extends Action { + private boolean stop = false; + + public StopRefreshAction() { + setRefresh(); + } + + public void setStop() { + stop = true; + setText(BrowserMessages.BrowserViewer_Stop_toolTip); + setToolTipText(BrowserMessages.BrowserViewer_Stop_toolTip); + setImageDescriptor( + BrowserImages.getImageDescriptor(BrowserImages.STOP, true)); + setDisabledImageDescriptor(BrowserImages + .getImageDescriptor(BrowserImages.STOP, false)); + } + + public void setRefresh() { + stop = false; + setText(BrowserMessages.BrowserViewer_Refresh_toolTip); + setToolTipText(BrowserMessages.BrowserViewer_Refresh_toolTip); + setImageDescriptor(BrowserImages + .getImageDescriptor(BrowserImages.REFRESH, true)); + setDisabledImageDescriptor(BrowserImages + .getImageDescriptor(BrowserImages.REFRESH, false)); + } + + public void run() { + if (stop) { + stop(); + } else { + refresh(); + } + } + } + + protected class BrowserListener implements LocationListener, + OpenWindowListener, VisibilityWindowListener, CloseWindowListener, + ProgressListener, TitleListener, StatusTextListener { + + private String locationText; + + private String titleText; + + private String statusText; + + public void hook(Browser browser) { + browser.addLocationListener(this); + browser.addOpenWindowListener(this); + browser.addVisibilityWindowListener(this); + browser.addCloseWindowListener(this); + browser.addProgressListener(this); + browser.addTitleListener(this); + browser.addStatusTextListener(this); + } + + public void unhook(Browser browser) { + browser.removeLocationListener(this); + browser.removeOpenWindowListener(this); + browser.removeVisibilityWindowListener(this); + browser.removeCloseWindowListener(this); + browser.removeProgressListener(this); + browser.removeTitleListener(this); + browser.removeStatusTextListener(this); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt. + * browser.LocationEvent) + */ + public void changed(LocationEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (!event.top) + return; + if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ + String oldLocation = locationText; + locationText = event.location; + if (location != null) { + location.setText(event.location); + } + addToHistory(event.location); + updateHistory(); + firePropertyChangeEvent(PROPERTY_LOCATION, oldLocation, + event.location); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.LocationListener#changing(org.eclipse.swt + * .browser.LocationEvent) + */ + public void changing(LocationEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ + event.doit = firePropertyChangingEvent(PROPERTY_LOCATION, + locationText, event.location, event.doit); + if (event.doit && redirect) { + event.location = makeRedirectUrl(event.location); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.browser.OpenWindowListener#open(org.eclipse.swt. + * browser .WindowEvent) + */ + public void open(WindowEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (container != null) { + event.browser = container.openNewBrowser(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.VisibilityWindowListener#hide(org.eclipse + * .swt.browser.WindowEvent) + */ + public void hide(WindowEvent event) { + // do nothing + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.VisibilityWindowListener#show(org.eclipse + * .swt.browser.WindowEvent) + */ + public void show(WindowEvent event) { +// if (event.widget == browser) { +// if (composite.getParent() instanceof Shell) { +// Shell shell = (Shell) composite.getParent(); +// if (event.location != null) +// shell.setLocation(event.location); +// if (event.size != null) +// shell.setSize(shell.computeSize(event.size.x, +// event.size.y)); +// shell.open(); +// } +// } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.CloseWindowListener#close(org.eclipse.swt + * .browser.WindowEvent) + */ + public void close(WindowEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (container != null) { + container.close(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.ProgressListener#changed(org.eclipse.swt. + * browser.ProgressEvent) + */ + public void changed(ProgressEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (event.total == 0) + return; + + boolean done = (event.current == event.total); + + int percentProgress = event.current * 100 / event.total; + if (container != null) { + IProgressMonitor monitor = container.getActionBars() + .getStatusLineManager().getProgressMonitor(); + if (done) { + monitor.done(); + progressWorked = 0; + } else if (progressWorked == 0) { + monitor.beginTask("", event.total); //$NON-NLS-1$ + progressWorked = percentProgress; + } else { + monitor.worked(event.current - progressWorked); + progressWorked = event.current; + } + } + + if (homeBusy != null) { + if (!homeBusy.isAnimating() && !done) + setLoading(true); + else if (homeBusy.isAnimating() && done) // once the progress hits + // 100 percent, done, set + // busy to false + setLoading(false); + } + + updateBackNextBusy(); + updateHistory(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.ProgressListener#completed(org.eclipse.swt + * .browser.ProgressEvent) + */ + public void completed(ProgressEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + if (container != null) { + IProgressMonitor monitor = container.getActionBars() + .getStatusLineManager().getProgressMonitor(); + monitor.done(); + } + setLoading(false); + updateBackNextBusy(); + updateHistory(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser + * .TitleEvent) + */ + public void changed(TitleEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + String oldTitle = titleText; + titleText = event.title; + firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, titleText); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt + * .browser.StatusTextEvent) + */ + public void changed(StatusTextEvent event) { + if (getControl() == null || getControl().isDisposed()) + return; + boolean doit = true; + String oldStatus = statusText; + if (!firePropertyChangingEvent(PROPERTY_STATUS, oldStatus, + event.text, doit)) { + event.text = ""; //$NON-NLS-1$ + } + if (container != null) { + IStatusLineManager status = container.getActionBars() + .getStatusLineManager(); + status.setMessage(event.text); + } + statusText = event.text; + firePropertyChangeEvent(PROPERTY_STATUS, oldStatus, statusText); + } + + } + + private static final int MAX_HISTORY = 50; + + private static final String URL_HOME = "http://www.xmind.net"; //$NON-NLS-1$ + + private static List URL_HISTORY; + + private Composite composite; + + private boolean mozilla; + + private Clipboard clipboard; + + private Composite toolBar; + + private ToolBarManager actionBar; + + private Combo location; + + private AnimationViewer homeBusy; + + private boolean loading; + + private Composite browserContainer; + + private Browser browser; + +// private Browser alternateBrowser; + + private BrowserListener browserListener; + + private BrowserErrorText errorText; + +// private boolean newWindow; + + private IBrowserViewerContainer container; + + private int progressWorked = 0; + + private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( + this); + + private BackAction backAction; + + private ForwardAction forwardAction; + + private StopRefreshAction stopRefreshAction; + + private boolean redirect = true; + + private int style = 0; + + private Label description; + + public BrowserViewer(Composite parent, int style) { + this(parent, style, null); + } + + public BrowserViewer(Composite parent, int style, + IBrowserViewerContainer container) { + this.style = style; + this.container = container; + this.composite = new Composite(parent, style); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.numColumns = 1; + this.composite.setLayout(layout); + this.composite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + createContents(this.composite); + hookControl(this.composite); + } + + public int getStyle() { + return style; + } + + Label getDescriptionLabel() { + return description; + } + + protected void hookControl(Control control) { + control.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + for (IBrowserViewerContribution contribution : BrowserContributionManager + .getInstance().getContributions()) { + if (contribution instanceof IBrowserViewerContribution2) { + ((IBrowserViewerContribution2) contribution) + .installBrowserListeners(this); + } + } + } + + protected void createContents(Composite parent) { + clipboard = new Clipboard(parent.getDisplay()); + createToolBar(parent); + createBrowser(parent); + updateWithStyle(); + updateHistory(); + updateBackNextBusy(); +// if (browserContainer != null) { +// } else { +// errorText.getControl().setLayoutData( +// new GridData(SWT.FILL, SWT.FILL, true, true)); +// } +// addBrowserListeners(browser); + } + + protected void createToolBar(Composite parent) { + toolBar = new Composite(parent, SWT.NONE); + GridLayout toolbarLayout = new GridLayout(); + toolbarLayout.marginHeight = 2; + toolbarLayout.marginWidth = 2; + toolbarLayout.horizontalSpacing = 5; + toolbarLayout.verticalSpacing = 0; + toolBar.setLayout(toolbarLayout); + toolBar.setLayoutData( + new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + createActionBar(toolBar); + createLocationBar(toolBar); + //forbid extra contributions, such as SearchBoxContribution + //if accept in the future, we can delete browserViewerContributions extension about search box. +// createExtraContributions(toolBar); + createHomeBusyIndicator(toolBar); + toolbarLayout.numColumns = toolBar.getChildren().length; + } + +// private void createExtraContributions(final Composite toolbarContainer) { +// ContributionManager manager = new ContributionManager() { +// public void update(boolean force) { +// if ((style & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) == 0) { +// for (IContributionItem item : getItems()) { +// item.fill(toolbarContainer); +// } +// } +// } +// }; +// for (IBrowserViewerContribution contribution : BrowserContributionManager +// .getInstance().getContributions()) { +// contribution.fillToolBar(this, manager); +// } +// manager.update(true); +// } + + private void createActionBar(Composite parent) { + actionBar = new ToolBarManager(SWT.FLAT); + actionBar.add(new OpenInExternalAction()); + actionBar.add(backAction = new BackAction()); + actionBar.add(forwardAction = new ForwardAction()); + actionBar.add(stopRefreshAction = new StopRefreshAction()); + actionBar.createControl(parent); + actionBar.getControl().setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, false, false)); + } + + private void createLocationBar(Composite parent) { + location = new Combo(parent, SWT.BORDER | SWT.DROP_DOWN); + location.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + description = new Label(parent, SWT.NONE); + description.setText(""); //$NON-NLS-1$ + description + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + updateHistory(); + + /* + * We ignore selection event to avoid unneccessary selection (e.g. mouse + * scrolling in the combo, arrow up/down, or even showing drop-down on + * some platforms). User must press Enter whenver they have selected an + * item in order to go to that URL. + */ +// location.addSelectionListener(new SelectionAdapter() { +// @Override +// public void widgetSelected(SelectionEvent we) { +// try { +// if (location.getSelectionIndex() != -1) +// setURL(location.getItem(location.getSelectionIndex())); +// } catch (Exception ignore) { +// } +// } +// }); + location.addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) { + int end = location.getText().length(); + location.setSelection(new Point(0, end)); + } + }); + location.addListener(SWT.DefaultSelection, new Listener() { + public void handleEvent(Event e) { + setURL(location.getText()); + } + }); + } + + protected void createHomeBusyIndicator(Composite parenet) { + homeBusy = new AnimationViewer(parenet, SWT.NONE); + homeBusy.setContentProvider(new BusyIndicatorContentProvider()); + homeBusy.setLabelProvider(new BusyIndicatorLabelProvider()); + homeBusy.setInput(getDefaultBusyPictures()); + homeBusy.getControl() + .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + homeBusy.getControl().addListener(SWT.MouseDown, new Listener() { + public void handleEvent(Event event) { + setURL(URL_HOME); + } + }); + } + + public AnimationViewer getBusyIndicator() { + return homeBusy; + } + + protected void createBrowser(Composite parent) { + browserContainer = new Composite(parent, SWT.NONE); + browserContainer.setLayout(new StackLayout()); + browserContainer + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Browser b = null; +// try { +// // try Mozilla +// b = createBrowser(browserContainer, SWT.MOZILLA | SWT.BORDER); +// mozilla = true; +// } catch (SWTError e) { +// mozilla = false; + try { + // try default browser + b = createBrowser(browserContainer, SWT.NONE); + } catch (SWTError e2) { + if (e2.code != SWT.ERROR_NO_HANDLES) { + return; + } + // show error text + errorText = new BrowserErrorText(browserContainer, this, e2); + } +// } + if (b != null) { + this.browser = b; + } + + mozilla = b != null && "mozilla".equals(b.getBrowserType()); //$NON-NLS-1$ + if (mozilla) + new MozillaPref(this); + + browserListener = new BrowserListener(); + + if (browser != null) { + browserListener.hook(browser); + show(browser); + } else { + show(errorText.getControl()); + } + } + + private void show(Control control) { + ((StackLayout) browserContainer.getLayout()).topControl = control; + for (Control c : browserContainer.getChildren()) { + c.setVisible(c == control); + } + browserContainer.layout(); + } + +// private void changeBrowser() { +// if (errorText != null) +// return; +// +// ensureAlternateBrowser(); +// if (alternateBrowser == null || alternateBrowser.isDisposed()) +// return; +// +// browserListener.unhook(browser); +// +// Browser temp = alternateBrowser; +// alternateBrowser = browser; +// browser = temp; +// +// browserListener.hook(browser); +// show(browser); +// } +// +// private void ensureAlternateBrowser() { +// if (alternateBrowser != null && !alternateBrowser.isDisposed()) +// return; +// +// if (errorText != null) +// return; +// +// try { +// if (mozilla) { +// alternateBrowser = new Browser(browserContainer, SWT.MOZILLA +// | SWT.BORDER); +// } else { +// alternateBrowser = new Browser(browserContainer, SWT.NONE); +// } +// +// } catch (SWTError e) { +// if (e.code != SWT.ERROR_NO_HANDLES) { +// return; +// } +// errorText = new BrowserErrorText(browserContainer, this, e); +// } +// +// if (alternateBrowser != null) { +// alternateBrowser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, +// true, true)); +// } else { +// errorText.getControl().setLayoutData( +// new GridData(SWT.FILL, SWT.FILL, true, true)); +// } +// } + + private Browser createBrowser(Composite parent, int style) { + return new Browser(parent, style); + } + + public void changeStyle(int newStyle) { + this.style = newStyle; + if (composite != null && !composite.isDisposed()) { + updateWithStyle(); + } + } + + protected void updateWithStyle() { + boolean locationVisible = (style + & IBrowserSupport.NO_LOCATION_BAR) == 0; + location.setVisible(locationVisible); + ((GridData) location.getLayoutData()).exclude = !locationVisible; + + boolean descriptionVisible = !locationVisible; + description.setVisible(descriptionVisible); + ((GridData) description.getLayoutData()).exclude = !descriptionVisible; + + toolBar.layout(true); + + boolean hasToolBar = (style & IBrowserSupport.NO_TOOLBAR) == 0; + toolBar.setVisible(hasToolBar); + ((GridData) toolBar.getLayoutData()).exclude = !hasToolBar; + + composite.layout(true); + } + + public Browser getBrowser() { + return browser; + } + + public Control getControl() { + return composite; + } + + private void home() { + if (browser == null || browser.isDisposed()) + return; + browser.setText(""); //$NON-NLS-1$ + } + + /** + * Loads a URL. + * + * @param url + * the URL to be loaded + * @return true if the operation was successful and false otherwise. + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the url is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + * @see #getURL() + */ + public boolean setURL(String url) { + return setURL(url, true); + } + + private boolean setURL(String url, boolean browse) { + if (url == null) { + home(); + return true; + } + + if ("xmind".equalsIgnoreCase(url)) //$NON-NLS-1$ + url = URL_HOME; + + if (redirect) { + url = makeRedirectUrl(url); + } + + if (browse) + navigate(url); + + addToHistory(url); + updateHistory(); + return true; + } + + protected void updateBackNextBusy() { + if (backAction != null) + backAction.setEnabled(isBackEnabled()); + if (forwardAction != null) + forwardAction.setEnabled(isForwardEnabled()); + if (homeBusy != null && homeBusy.getControl() != null + && !homeBusy.getControl().isDisposed()) { + if (loading) { + homeBusy.start(); + } else { + homeBusy.stop(); + } + } + } + +// /** +// * +// */ +// private void addBrowserListeners(Browser browser) { +// if (browser == null) +// return; +// +// browser.addStatusTextListener(new StatusTextListener() { +// public void changed(StatusTextEvent event) { +// if (container != null) { +// IStatusLineManager status = container.getActionBars() +// .getStatusLineManager(); +// status.setMessage(event.text); +// } +// } +// }); +// +// /* +// * Add listener for new window creation. Use just the same browser for +// * the new window. +// */ +// browser.addOpenWindowListener(new OpenWindowListener() { +// public void open(WindowEvent event) { +// event.browser = BrowserViewer.this.browser; +// +// // Forget about the following way.... +// +//// Display display = Display.getCurrent(); +//// final Shell tempShell = new Shell(display); +//// tempShell.setBounds(-100, -100, 50, 50); +//// tempShell.setLayout(new FillLayout()); +//// BrowserViewer tempBrowserViewer = new BrowserViewer(tempShell, +//// 0, null); +//// tempBrowserViewer.newWindow = true; +//// Browser tempBrowser = tempBrowserViewer.browser; +//// tempBrowser.addLocationListener(new LocationListener() { +//// +//// public void changing(LocationEvent event) { +//// } +//// +//// public void changed(LocationEvent event) { +//// String url = event.location; +//// if (container != null && url != null && !"".equals(url)) { //$NON-NLS-1$ +//// container.openInExternalBrowser(url); +//// } +//// tempShell.close(); +//// tempShell.dispose(); +//// } +//// +//// }); +//// event.browser = tempBrowser; +// } +// }); +// +// browser.addVisibilityWindowListener(new VisibilityWindowListener() { +// public void hide(WindowEvent e) { +// } +// +// public void show(WindowEvent e) { +// Browser browser2 = (Browser) e.widget; +// if (browser2.getParent().getParent() instanceof Shell) { +// Shell shell = (Shell) browser2.getParent().getParent(); +// if (e.location != null) +// shell.setLocation(e.location); +// if (e.size != null) +// shell.setSize(shell.computeSize(e.size.x, e.size.y)); +// shell.open(); +// } +// } +// }); +// +// browser.addCloseWindowListener(new CloseWindowListener() { +// public void close(WindowEvent event) { +// // if shell is not null, it must be a secondary popup window, +// // else its an editor window +//// if (newWindow) { +//// getControl().getShell().dispose(); +//// } else { +//// container.close(); +//// } +// } +// }); +// +// browser.addProgressListener(new ProgressListener() { +// public void changed(ProgressEvent event) { +// if (event.total == 0) +// return; +// +// boolean done = (event.current == event.total); +// +// int percentProgress = event.current * 100 / event.total; +// if (container != null) { +// IProgressMonitor monitor = container.getActionBars() +// .getStatusLineManager().getProgressMonitor(); +// if (done) { +// monitor.done(); +// progressWorked = 0; +// } else if (progressWorked == 0) { +// monitor.beginTask("", event.total); //$NON-NLS-1$ +// progressWorked = percentProgress; +// } else { +// monitor.worked(event.current - progressWorked); +// progressWorked = event.current; +// } +// } +// +// if (!homeBusy.isAnimating() && !done) +// setLoading(true); +// else if (homeBusy.isAnimating() && done) // once the progress hits +// // 100 percent, done, set +// // busy to false +// setLoading(false); +// +// updateBackNextBusy(); +// updateHistory(); +// } +// +// public void completed(ProgressEvent event) { +// if (container != null) { +// IProgressMonitor monitor = container.getActionBars() +// .getStatusLineManager().getProgressMonitor(); +// monitor.done(); +// } +// setLoading(false); +// updateBackNextBusy(); +// updateHistory(); +// } +// }); +// +// browser.addLocationListener(new LocationListener() { +// public void changed(LocationEvent event) { +// if (!event.top) +// return; +// if (location != null) { +// if (!"about:blank".equals(event.location)) { //$NON-NLS-1$ +// String oldLocation = location.getText(); +// location.setText(event.location); +// addToHistory(event.location); +// updateHistory(); +// firePropertyChangeEvent(PROPERTY_LOCATION, +// event.location, oldLocation); +// } +// } +// } +// +// public void changing(LocationEvent event) { +// // do nothing +// } +// }); +// +// browser.addTitleListener(new TitleListener() { +// public void changed(TitleEvent event) { +// String oldTitle = title; +// title = event.title; +// firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, title); +// } +// }); +// +// } + + public Combo getLocationBar() { + return location; + } + + public Clipboard getClipboard() { + return clipboard; + } + + public void copy() { + if (location == null || location.isDisposed() + || !location.isFocusControl()) + return; + + location.copy(); + } + + public void cut() { + if (location == null || location.isDisposed() + || !location.isFocusControl()) + return; + + location.cut(); + } + + public void delete() { + if (location == null || location.isDisposed() + || !location.isFocusControl()) + return; + + String text = location.getText(); + Point selection = location.getSelection(); + if (selection.y > selection.x) { + text = text.substring(0, selection.x) + text.substring(selection.y); + location.setText(text); + location.setSelection(new Point(selection.x, selection.x)); + } + } + + public void paste() { + if (location == null || location.isDisposed() + || !location.isFocusControl()) + return; + + location.paste(); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + propertyChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + propertyChangeSupport.removePropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + propertyChangeSupport.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + propertyChangeSupport.removePropertyChangeListener(propertyName, + listener); + } + + protected void firePropertyChangeEvent(String propertyName, Object oldValue, + Object newValue) { + propertyChangeSupport.firePropertyChange(propertyName, oldValue, + newValue); + } + + protected boolean firePropertyChangingEvent(String propertyName, + Object oldValue, Object newValue, boolean doit) { + PropertyChangingEvent event = new PropertyChangingEvent(this, + propertyName, oldValue, newValue, doit); + PropertyChangeListener[] listeners = propertyChangeSupport + .getPropertyChangeListeners(); + if (firePropertyChangingEvent(listeners, event)) { + listeners = propertyChangeSupport + .getPropertyChangeListeners(propertyName); + return firePropertyChangingEvent(listeners, event); + } + return event.doit; + } + + private boolean firePropertyChangingEvent( + PropertyChangeListener[] listeners, PropertyChangingEvent event) { + for (Object pcl : listeners) { + if (pcl instanceof IPropertyChangingListener) { + try { + ((IPropertyChangingListener) pcl).propertyChanging(event); + } catch (Throwable ignore) { + } + } + } + return event.doit; + } + + /** + * Navigate to the next session history item. Convenience method that calls + * the underlying SWT browser. + * + * @return true if the operation was successful and + * false otherwise + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + */ + public boolean forward() { + if (browser == null || browser.isDisposed()) + return false; + boolean forward = browser.forward(); + if (!forward) { + + } + return forward; + } + + /** + * Navigate to the previous session history item. Convenience method that + * calls the underlying SWT browser. + * + * @return true if the operation was successful and + * false otherwise + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + */ + public boolean back() { + if (browser == null || browser.isDisposed()) + return false; + return browser.back(); + } + + /** + * Returns true if the receiver can navigate to the previous + * session history item, and false otherwise. Convenience + * method that calls the underlying SWT browser. + * + * @return the receiver's back command enabled state + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
    • + *
    + */ + public boolean isBackEnabled() { + if (browser == null || browser.isDisposed()) + return false; + return browser.isBackEnabled(); + } + + /** + * Returns true if the receiver can navigate to the next + * session history item, and false otherwise. Convenience + * method that calls the underlying SWT browser. + * + * @return the receiver's forward command enabled state + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
    • + *
    + */ + public boolean isForwardEnabled() { + if (browser == null || browser.isDisposed()) + return false; + return browser.isForwardEnabled(); + } + + /** + * Stop any loading and rendering activity. Convenience method that calls + * the underlying SWT browser. + * + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + */ + public void stop() { + if (browser != null && !browser.isDisposed()) + browser.stop(); + setLoading(false); + } + + public boolean setText(String html) { + return false; + } + + private boolean navigate(String url) { + if (url != null && url.equals(getURL())) { + refresh(); + return true; + } + if (browser != null && !browser.isDisposed()) + return browser.setUrl(url); + if (errorText != null && errorText.getControl() != null + && !errorText.getControl().isDisposed()) + return errorText.setUrl(url); + return false; + } + + /** + * Refresh the current page. Convenience method that calls the underlying + * SWT browser. + * + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + */ + public void refresh() { + if (browser != null) { + if (!browser.isDisposed()) + browser.refresh(); + } else { + if (errorText != null && errorText.getControl() != null + && !errorText.getControl().isDisposed()) + errorText.refresh(); + } + try { + Thread.sleep(50); + } catch (Exception ignore) { + } + } + + protected void addToHistory(String url) { + if (URL_HISTORY == null) + URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); + int found = -1; + int size = URL_HISTORY.size(); + for (int i = 0; i < size; i++) { + String s = URL_HISTORY.get(i); + if (s.equals(url)) { + found = i; + break; + } + } + + if (found == -1) { + if (size >= MAX_HISTORY) + URL_HISTORY.remove(size - 1); + URL_HISTORY.add(0, url); + BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); + } else if (found != 0) { + URL_HISTORY.remove(found); + URL_HISTORY.add(0, url); + BrowserPref.setInternalWebBrowserHistory(URL_HISTORY); + } + } + + protected void handleDispose() { + for (IBrowserViewerContribution contribution : BrowserContributionManager + .getInstance().getContributions()) { + if (contribution instanceof IBrowserViewerContribution2) { + ((IBrowserViewerContribution2) contribution) + .uninstallBrowserListeners(this); + } + } + if (this.container != null) { + IStatusLineManager manager = this.container.getActionBars() + .getStatusLineManager(); + if (manager != null) + manager.getProgressMonitor().done(); + } + homeBusy = null; + browser = null; + errorText = null; + if (clipboard != null) + clipboard.dispose(); + clipboard = null; + } + + private void setLoading(boolean loading) { + this.loading = loading; + if (loading) { + if (stopRefreshAction != null) { + stopRefreshAction.setStop(); + } + } else { + if (stopRefreshAction != null) { + stopRefreshAction.setRefresh(); + } + if (homeBusy != null && homeBusy.getControl() != null + && !homeBusy.getControl().isDisposed()) + homeBusy.stop(); + if (container != null) { + IProgressMonitor monitor = container.getActionBars() + .getStatusLineManager().getProgressMonitor(); + monitor.done(); + } + } + } + + /** + * Returns the current URL. Convenience method that calls the underlying SWT + * browser. + * + * @return the current URL or an empty String if there is no + * current URL + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS when called from the wrong + * thread
    • + *
    • ERROR_WIDGET_DISPOSED when the widget has been + * disposed
    • + *
    + * @see #setURL(String) + */ + public String getURL() { + if (browser != null) + return browser.getUrl(); + return errorText.getUrl(); + } + + protected void updateHistory() { + if (location == null || location.isDisposed()) + return; + + String temp = location.getText(); + if (URL_HISTORY == null) + URL_HISTORY = BrowserPref.getInternalWebBrowserHistory(); + + String[] historyList = new String[URL_HISTORY.size()]; + URL_HISTORY.toArray(historyList); + location.setItems(historyList); + + location.setText(temp); + } + + public IBrowserViewerContainer getContainer() { + return container; + } + + public void setFocus() { + if (browser != null && !browser.isDisposed()) { + if (browser.setFocus()) { + updateHistory(); + } else if (location != null) { + location.setFocus(); + } + } + } + + /** + * @return the mozilla + */ + public boolean isMozilla() { + return mozilla; + } + + public BackAction getBackAction() { + return backAction; + } + + public ForwardAction getForwardAction() { + return forwardAction; + } + + public StopRefreshAction getStopRefreshAction() { + return stopRefreshAction; + } + + private static Object getDefaultBusyPictures() { + if (DEFAULT_BUSY_PICTURES == null) { + ArrayList list = new ArrayList( + 13); + list.add(BrowserImages.getImageDescriptor(BrowserImages.XMIND)); + list.addAll(Arrays.asList(BrowserImages.getBusyImages())); + DEFAULT_BUSY_PICTURES = list.toArray(); + } + return DEFAULT_BUSY_PICTURES; + } + + private String makeRedirectUrl(String source) { + if (!source.startsWith("file:")) { //$NON-NLS-1$ + try { + return BrowserUtil.makeRedirectURL(source); + } catch (Throwable e) { + //ignore + } finally { + redirect = false; + } + } + return source; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/ExternalWebBrowser.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/ExternalWebBrowser.java index 256fd89ad..82a6421f2 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/ExternalWebBrowser.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/ExternalWebBrowser.java @@ -1,55 +1,55 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.browser; - -import java.net.URL; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.program.Program; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.browser.AbstractWebBrowser; - -public class ExternalWebBrowser extends AbstractWebBrowser { - - public ExternalWebBrowser(String id) { - super(id); - } - - public void openURL(URL url) throws PartInitException { - String urlText = null; - - if (url != null) - urlText = url.toExternalForm(); - - // change spaces to "%20" - if (urlText != null && !BrowserUtil.isWindows()) { - int index = urlText.indexOf(" "); //$NON-NLS-1$ - while (index >= 0) { - urlText = urlText.substring(0, index) + "%20" //$NON-NLS-1$ - + urlText.substring(index + 1); - index = urlText.indexOf(" "); //$NON-NLS-1$ - } - } - Program program = Program.findProgram("html"); //$NON-NLS-1$ - if (program != null) { - if (program.execute(urlText)) - return; - } - if (!Program.launch(urlText)) - throw new PartInitException( - NLS - .bind( - BrowserMessages.ExternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message, - url.toExternalForm())); - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.browser; + +import java.net.URL; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.program.Program; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.browser.AbstractWebBrowser; + +public class ExternalWebBrowser extends AbstractWebBrowser { + + public ExternalWebBrowser(String id) { + super(id); + } + + public void openURL(URL url) throws PartInitException { + String urlText = null; + + if (url != null) + urlText = url.toExternalForm(); + + // change spaces to "%20" + if (urlText != null && !BrowserUtil.isWindows()) { + int index = urlText.indexOf(" "); //$NON-NLS-1$ + while (index >= 0) { + urlText = urlText.substring(0, index) + "%20" //$NON-NLS-1$ + + urlText.substring(index + 1); + index = urlText.indexOf(" "); //$NON-NLS-1$ + } + } + Program program = Program.findProgram("html"); //$NON-NLS-1$ + if (program != null) { + if (program.execute(urlText)) + return; + } + if (!Program.launch(urlText)) + throw new PartInitException( + NLS + .bind( + BrowserMessages.ExternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message, + url.toExternalForm())); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowser.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowser.java index 16a2009a3..c6b5cca58 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowser.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowser.java @@ -1,232 +1,232 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.browser.IWebBrowser; -import org.eclipse.ui.browser.IWorkbenchBrowserSupport; -import org.xmind.core.command.Command; -import org.xmind.core.command.CommandJob; -import org.xmind.core.command.ICommand; -import org.xmind.ui.browser.IBrowser; - -public class InternalBrowser implements IBrowser { - - private BrowserSupportImpl support; - - private String clientId; - - private Object windowKey = null; - - private boolean asEditor; - - private int browserStyle; - - private String name; - - private String tooltip; - - private IWorkbenchPart part; - - private IPartListener listener; - - private IWebBrowser workbenchBrowser; - - public InternalBrowser(BrowserSupportImpl support, String clientId, - boolean asEditor, int style) { - this.support = support; - this.clientId = clientId; - this.asEditor = asEditor; - this.browserStyle = style; - } - - public IWorkbenchPart getPart() { - return part; - } - - public String getClientId() { - return clientId; - } - - public void openURL(String url) throws PartInitException { - ICommand command = Command.parseURI(url); - if (command != null) { - new CommandJob(command, null).schedule(); - return; - } - - url = BrowserUtil.normalizeURL(url); - - try { - doOpenURL(url); - } catch (PartInitException e) { - doOpenURLByWorkbenchBrowser(url); - } - } - - protected void doOpenURL(String url) throws PartInitException { - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - IWorkbenchPage page = window == null ? null : window.getActivePage(); - - if (page == null) - throw new PartInitException( - BrowserMessages.InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message); - - if (part instanceof IEditorPart) { - ((IEditorPart) part).init(((IEditorPart) part).getEditorSite(), - createEditorInput(url)); - page.activate(part); - } else { - if (asEditor) { - part = page.openEditor(createEditorInput(url), - InternalBrowserEditor.BROWSER_EDITOR_ID); - } else { - part = page.showView(InternalBrowserView.BROWSER_VIEW_ID, - clientId, IWorkbenchPage.VIEW_ACTIVATE); - if (part instanceof InternalBrowserView) { - ((InternalBrowserView) part).changeStyle(browserStyle); - ((InternalBrowserView) part).openURL(url); - } - } - hookPart(page, part); - } - } - - /** - * @param url - * @return - */ - private BrowserEditorInput createEditorInput(String url) { - BrowserEditorInput input = new BrowserEditorInput(url, clientId, - browserStyle); - input.setName(this.name); - input.setToolTipText(this.tooltip); - return input; - } - - private void hookPart(final IWorkbenchPage page, - IWorkbenchPart editorPart) { - listener = new IPartListener() { - public void partActivated(IWorkbenchPart part) { - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - if (part.equals(InternalBrowser.this.part)) { - InternalBrowser.this.part = null; - page.removePartListener(listener); - support.removeInternalBrowser(InternalBrowser.this); - } - } - - public void partDeactivated(IWorkbenchPart part) { - } - - public void partOpened(IWorkbenchPart part) { - } - }; - page.addPartListener(listener); - } - - protected void doOpenURLByWorkbenchBrowser(String url) - throws PartInitException { - try { - URL theURL = new URL(url); - getWorkbenchBrowser().openURL(theURL); - } catch (MalformedURLException e) { - throw new PartInitException( - BrowserMessages.InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message); - } - } - - private IWebBrowser getWorkbenchBrowser() throws PartInitException { - if (workbenchBrowser == null) { - workbenchBrowser = createWorkbenchBrowser(); - } - return workbenchBrowser; - } - - protected IWebBrowser createWorkbenchBrowser() throws PartInitException { - return PlatformUI.getWorkbench().getBrowserSupport().createBrowser( - IWorkbenchBrowserSupport.AS_EDITOR - | IWorkbenchBrowserSupport.LOCATION_BAR - | IWorkbenchBrowserSupport.NAVIGATION_BAR, - getClientId(), name, tooltip); - } - - public void setName(String name) { - this.name = name; - } - - public void setTooltip(String tooltip) { - this.tooltip = tooltip; - } - - public String getName() { - return name; - } - - public String getTooltip() { - return tooltip; - } - - public Object getWindowKey() { - if (windowKey == null) { - windowKey = createWindowKey(); - } - return windowKey; - } - - private Object createWindowKey() { - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window == null) - return this; - return BrowserUtil.getWindowKey(window); - } - - public void close() { - if (part != null) { - if (part instanceof IEditorPart) { - part.getSite().getPage().closeEditor((IEditorPart) part, false); - } else { - part.getSite().getPage().hideView((IViewPart) part); - } - } - if (workbenchBrowser != null) { - workbenchBrowser.close(); - } - } - - public void setText(String text) throws PartInitException { - doOpenURL(null); - if (part != null && part instanceof InternalBrowserEditor) { - ((InternalBrowserEditor) part).setText(text); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.browser.IWebBrowser; +import org.eclipse.ui.browser.IWorkbenchBrowserSupport; +import org.xmind.core.command.Command; +import org.xmind.core.command.CommandJob; +import org.xmind.core.command.ICommand; +import org.xmind.ui.browser.IBrowser; + +public class InternalBrowser implements IBrowser { + + private BrowserSupportImpl support; + + private String clientId; + + private Object windowKey = null; + + private boolean asEditor; + + private int browserStyle; + + private String name; + + private String tooltip; + + private IWorkbenchPart part; + + private IPartListener listener; + + private IWebBrowser workbenchBrowser; + + public InternalBrowser(BrowserSupportImpl support, String clientId, + boolean asEditor, int style) { + this.support = support; + this.clientId = clientId; + this.asEditor = asEditor; + this.browserStyle = style; + } + + public IWorkbenchPart getPart() { + return part; + } + + public String getClientId() { + return clientId; + } + + public void openURL(String url) throws PartInitException { + ICommand command = Command.parseURI(url); + if (command != null) { + new CommandJob(command, null).schedule(); + return; + } + + url = BrowserUtil.normalizeURL(url); + + try { + doOpenURL(url); + } catch (PartInitException e) { + doOpenURLByWorkbenchBrowser(url); + } + } + + protected void doOpenURL(String url) throws PartInitException { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + IWorkbenchPage page = window == null ? null : window.getActivePage(); + + if (page == null) + throw new PartInitException( + BrowserMessages.InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message); + + if (part instanceof IEditorPart) { + ((IEditorPart) part).init(((IEditorPart) part).getEditorSite(), + createEditorInput(url)); + page.activate(part); + } else { + if (asEditor) { + part = page.openEditor(createEditorInput(url), + InternalBrowserEditor.BROWSER_EDITOR_ID); + } else { + part = page.showView(InternalBrowserView.BROWSER_VIEW_ID, + clientId, IWorkbenchPage.VIEW_ACTIVATE); + if (part instanceof InternalBrowserView) { + ((InternalBrowserView) part).changeStyle(browserStyle); + ((InternalBrowserView) part).openURL(url); + } + } + hookPart(page, part); + } + } + + /** + * @param url + * @return + */ + private BrowserEditorInput createEditorInput(String url) { + BrowserEditorInput input = new BrowserEditorInput(url, clientId, + browserStyle); + input.setName(this.name); + input.setToolTipText(this.tooltip); + return input; + } + + private void hookPart(final IWorkbenchPage page, + IWorkbenchPart editorPart) { + listener = new IPartListener() { + public void partActivated(IWorkbenchPart part) { + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + if (part.equals(InternalBrowser.this.part)) { + InternalBrowser.this.part = null; + page.removePartListener(listener); + support.removeInternalBrowser(InternalBrowser.this); + } + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + }; + page.addPartListener(listener); + } + + protected void doOpenURLByWorkbenchBrowser(String url) + throws PartInitException { + try { + URL theURL = new URL(url); + getWorkbenchBrowser().openURL(theURL); + } catch (MalformedURLException e) { + throw new PartInitException( + BrowserMessages.InternalWebBrowser_ErrorCouldNotLaunchWebBrowser_message); + } + } + + private IWebBrowser getWorkbenchBrowser() throws PartInitException { + if (workbenchBrowser == null) { + workbenchBrowser = createWorkbenchBrowser(); + } + return workbenchBrowser; + } + + protected IWebBrowser createWorkbenchBrowser() throws PartInitException { + return PlatformUI.getWorkbench().getBrowserSupport().createBrowser( + IWorkbenchBrowserSupport.AS_EDITOR + | IWorkbenchBrowserSupport.LOCATION_BAR + | IWorkbenchBrowserSupport.NAVIGATION_BAR, + getClientId(), name, tooltip); + } + + public void setName(String name) { + this.name = name; + } + + public void setTooltip(String tooltip) { + this.tooltip = tooltip; + } + + public String getName() { + return name; + } + + public String getTooltip() { + return tooltip; + } + + public Object getWindowKey() { + if (windowKey == null) { + windowKey = createWindowKey(); + } + return windowKey; + } + + private Object createWindowKey() { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) + return this; + return BrowserUtil.getWindowKey(window); + } + + public void close() { + if (part != null) { + if (part instanceof IEditorPart) { + part.getSite().getPage().closeEditor((IEditorPart) part, false); + } else { + part.getSite().getPage().hideView((IViewPart) part); + } + } + if (workbenchBrowser != null) { + workbenchBrowser.close(); + } + } + + public void setText(String text) throws PartInitException { + doOpenURL(null); + if (part != null && part instanceof InternalBrowserEditor) { + ((InternalBrowserEditor) part).setText(text); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserEditor.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserEditor.java index 0cb3330c0..16d94c7b3 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserEditor.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserEditor.java @@ -1,334 +1,334 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.browser; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.part.EditorPart; -import org.xmind.ui.browser.IBrowserSupport; -import org.xmind.ui.browser.IBrowserViewer; -import org.xmind.ui.browser.IBrowserViewerContainer; -import org.xmind.ui.internal.browser.actions.CopyAction; -import org.xmind.ui.internal.browser.actions.CutAction; -import org.xmind.ui.internal.browser.actions.DeleteAction; -import org.xmind.ui.internal.browser.actions.PasteAction; - -public class InternalBrowserEditor extends EditorPart - implements IBrowserViewerContainer { - - public static final String BROWSER_EDITOR_ID = "org.xmind.ui.browser.editor"; //$NON-NLS-1$ - - private BrowserViewer viewer; - - private String initialURL; - - private Image image; - - private Map actions; - - private boolean disposed; - - private boolean lockName; - - public String getClientId() { - return getBrowserEditorInput().getClientId(); - } - - public IAction getAction(String id) { - return actions == null ? null : actions.get(id); - } - - public void doSave(IProgressMonitor monitor) { - } - - public void doSaveAs() { - } - - public void init(IEditorSite site, IEditorInput input) - throws PartInitException { - if (input instanceof BrowserEditorInput) { - BrowserEditorInput bei = (BrowserEditorInput) input; - initialURL = null; - if (bei.getURL() != null) - initialURL = bei.getURL(); - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.setURL(initialURL); -// int style = bei.getStyle(); -// if ((style & IBrowserSupport.NO_LOCATION_BAR) != 0 && (style -// & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) != 0) { -// style |= IBrowserSupport.NO_TOOLBAR; -// } -// viewer.changeStyle(style); -// site.getWorkbenchWindow().getActivePage().activate(this); -// if (initialURL != null -// && ((style & IBrowserSupport.NO_TOOLBAR) == 0 && (style -// & IBrowserSupport.NO_LOCATION_BAR) == 0)) { -// setContentDescription(initialURL); -// } else { -// setContentDescription(""); //$NON-NLS-1$ -// } - } - - setPartName(bei.getName()); - setTitleToolTip(bei.getToolTipText()); - lockName = bei.isNameLocked(); - - Image oldImage = image; - ImageDescriptor id = bei.getImageDescriptor(); - image = id.createImage(); - - setTitleImage(image); - if (oldImage != null && !oldImage.isDisposed()) - oldImage.dispose(); - } else - throw new PartInitException(NLS.bind( - BrowserMessages.BrowserEditor_ErrorInvalidEditorInput_message, - input.getName())); - - setSite(site); - setInput(input); - } - - public boolean isDirty() { - return false; - } - - public boolean isSaveAsAllowed() { - return false; - } - - public void dispose() { - if (image != null && !image.isDisposed()) - image.dispose(); - image = null; - - super.dispose(); - disposed = true; - } - - public boolean isDisposed() { - return disposed; - } - - public void createPartControl(final Composite parent) { - int style = getBrowserEditorInput().getStyle(); - viewer = new BrowserViewer(parent, style, this); - viewer.setURL(initialURL); - - addAction(new CopyAction(viewer)); - addAction(new CutAction(viewer)); - addAction(new PasteAction(viewer)); - addAction(new DeleteAction(viewer)); - - PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - if (lockName) - return; - if (IBrowserViewer.PROPERTY_TITLE - .equals(event.getPropertyName())) { - if (event.getNewValue() != null) - setPartName((String) event.getNewValue()); - } else if (IBrowserViewer.PROPERTY_LOCATION - .equals(event.getPropertyName())) { - String location = (String) event.getNewValue(); - int currentStyle = getBrowserEditorInput().getStyle(); - if (location == null || ((currentStyle - & IBrowserSupport.NO_TOOLBAR) == 0 - && (currentStyle - & IBrowserSupport.NO_LOCATION_BAR) == 0)) { - location = ""; //$NON-NLS-1$ - } - Label descriptionLabel = viewer.getDescriptionLabel(); - if (descriptionLabel != null - && !descriptionLabel.isDisposed()) { - descriptionLabel.setText(location); - descriptionLabel.setToolTipText(location); - } - } - } - }; - viewer.addPropertyChangeListener(propertyChangeListener); - - viewer.getBusyIndicator() - .addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - if (!parent.isDisposed()) { - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - if (!parent.isDisposed() && image != null - && !image.isDisposed()) { - Image currentImage = viewer - .getBusyIndicator() - .getCurrentImage(); - if (currentImage == null - || !viewer.getBusyIndicator() - .isAnimating()) { - setTitleImage(image); - } else { - setTitleImage(currentImage); - } - } - } - }); - } - } - }); - } - - private void addAction(IAction action) { - String actionId = action.getId(); - if (actionId == null) - return; - - if (actions == null) - actions = new HashMap(); - actions.put(actionId, action); - } - - /** - * Returns the web editor input, if available. If the input was of another - * type, null is returned. - * - * @return org.eclipse.ui.internal.browser.IWebBrowserEditorInput - */ - protected BrowserEditorInput getBrowserEditorInput() { - return (BrowserEditorInput) getEditorInput(); - } - - /** - * Open the input in the internal Web browser. - */ - public static void open(BrowserEditorInput input) { - IWorkbenchWindow workbenchWindow = BrowserPlugin.getDefault() - .getWorkbench().getActiveWorkbenchWindow(); - IWorkbenchPage page = workbenchWindow.getActivePage(); - - try { - IEditorReference[] editors = page.getEditorReferences(); - int size = editors.length; - for (int i = 0; i < size; i++) { - if (BROWSER_EDITOR_ID.equals(editors[i].getId())) { - IEditorPart editor = editors[i].getEditor(true); - if (editor != null - && editor instanceof InternalBrowserEditor) { - InternalBrowserEditor editor2 = (InternalBrowserEditor) editor; - BrowserEditorInput input2 = editor2 - .getBrowserEditorInput(); - if (input2 == null || input.canReplaceInput(input2)) { - editor.init(editor.getEditorSite(), input); - return; - } - } - } - } - - page.openEditor(input, InternalBrowserEditor.BROWSER_EDITOR_ID); - } catch (Exception e) { - } - } - - public void setFocus() { - if (viewer != null) - viewer.setFocus(); - } - - public BrowserViewer getViewer() { - return viewer; - } - - public boolean close() { - final boolean[] result = new boolean[1]; - Display.getDefault().asyncExec(new Runnable() { - public void run() { - result[0] = getEditorSite().getPage() - .closeEditor(InternalBrowserEditor.this, false); - } - }); - return result[0]; - } - - public IActionBars getActionBars() { - return getEditorSite().getActionBars(); - } - - public void openInExternalBrowser(String url) { - BrowserUtil.gotoUrl(url); - } - - public void setText(String html) { - if (viewer != null && !viewer.getControl().isDisposed()) { - viewer.setText(html); - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.browser.IBrowserViewerContainer#openNewBrowser() - */ - public Browser openNewBrowser() { - final Browser[] ret = new Browser[1]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - final BrowserEditorInput input = new BrowserEditorInput("", //$NON-NLS-1$ - getNewSecondaryId(), - getBrowserEditorInput().getStyle()); - IEditorPart editor = getSite().getPage().openEditor(input, - BROWSER_EDITOR_ID); - if (editor instanceof InternalBrowserEditor) { - ret[0] = ((InternalBrowserEditor) editor).getViewer() - .getBrowser(); - } - } - }); - return ret[0]; - } - - private static Map numbers = new HashMap(); - - private String getNewSecondaryId() { - Integer num = numbers.get(getClientId()); - if (num == null) { - num = Integer.valueOf(1); - } else { - num = Integer.valueOf(num.intValue() + 1); - } - numbers.put(getClientId(), num); - return getClientId() + "-" + num.toString(); //$NON-NLS-1$ - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.browser; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; +import org.xmind.ui.browser.IBrowserSupport; +import org.xmind.ui.browser.IBrowserViewer; +import org.xmind.ui.browser.IBrowserViewerContainer; +import org.xmind.ui.internal.browser.actions.CopyAction; +import org.xmind.ui.internal.browser.actions.CutAction; +import org.xmind.ui.internal.browser.actions.DeleteAction; +import org.xmind.ui.internal.browser.actions.PasteAction; + +public class InternalBrowserEditor extends EditorPart + implements IBrowserViewerContainer { + + public static final String BROWSER_EDITOR_ID = "org.xmind.ui.browser.editor"; //$NON-NLS-1$ + + private BrowserViewer viewer; + + private String initialURL; + + private Image image; + + private Map actions; + + private boolean disposed; + + private boolean lockName; + + public String getClientId() { + return getBrowserEditorInput().getClientId(); + } + + public IAction getAction(String id) { + return actions == null ? null : actions.get(id); + } + + public void doSave(IProgressMonitor monitor) { + } + + public void doSaveAs() { + } + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + if (input instanceof BrowserEditorInput) { + BrowserEditorInput bei = (BrowserEditorInput) input; + initialURL = null; + if (bei.getURL() != null) + initialURL = bei.getURL(); + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.setURL(initialURL); +// int style = bei.getStyle(); +// if ((style & IBrowserSupport.NO_LOCATION_BAR) != 0 && (style +// & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) != 0) { +// style |= IBrowserSupport.NO_TOOLBAR; +// } +// viewer.changeStyle(style); +// site.getWorkbenchWindow().getActivePage().activate(this); +// if (initialURL != null +// && ((style & IBrowserSupport.NO_TOOLBAR) == 0 && (style +// & IBrowserSupport.NO_LOCATION_BAR) == 0)) { +// setContentDescription(initialURL); +// } else { +// setContentDescription(""); //$NON-NLS-1$ +// } + } + + setPartName(bei.getName()); + setTitleToolTip(bei.getToolTipText()); + lockName = bei.isNameLocked(); + + Image oldImage = image; + ImageDescriptor id = bei.getImageDescriptor(); + image = id.createImage(); + + setTitleImage(image); + if (oldImage != null && !oldImage.isDisposed()) + oldImage.dispose(); + } else + throw new PartInitException(NLS.bind( + BrowserMessages.BrowserEditor_ErrorInvalidEditorInput_message, + input.getName())); + + setSite(site); + setInput(input); + } + + public boolean isDirty() { + return false; + } + + public boolean isSaveAsAllowed() { + return false; + } + + public void dispose() { + if (image != null && !image.isDisposed()) + image.dispose(); + image = null; + + super.dispose(); + disposed = true; + } + + public boolean isDisposed() { + return disposed; + } + + public void createPartControl(final Composite parent) { + int style = getBrowserEditorInput().getStyle(); + viewer = new BrowserViewer(parent, style, this); + viewer.setURL(initialURL); + + addAction(new CopyAction(viewer)); + addAction(new CutAction(viewer)); + addAction(new PasteAction(viewer)); + addAction(new DeleteAction(viewer)); + + PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (lockName) + return; + if (IBrowserViewer.PROPERTY_TITLE + .equals(event.getPropertyName())) { + if (event.getNewValue() != null) + setPartName((String) event.getNewValue()); + } else if (IBrowserViewer.PROPERTY_LOCATION + .equals(event.getPropertyName())) { + String location = (String) event.getNewValue(); + int currentStyle = getBrowserEditorInput().getStyle(); + if (location == null || ((currentStyle + & IBrowserSupport.NO_TOOLBAR) == 0 + && (currentStyle + & IBrowserSupport.NO_LOCATION_BAR) == 0)) { + location = ""; //$NON-NLS-1$ + } + Label descriptionLabel = viewer.getDescriptionLabel(); + if (descriptionLabel != null + && !descriptionLabel.isDisposed()) { + descriptionLabel.setText(location); + descriptionLabel.setToolTipText(location); + } + } + } + }; + viewer.addPropertyChangeListener(propertyChangeListener); + + viewer.getBusyIndicator() + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + if (!parent.isDisposed()) { + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!parent.isDisposed() && image != null + && !image.isDisposed()) { + Image currentImage = viewer + .getBusyIndicator() + .getCurrentImage(); + if (currentImage == null + || !viewer.getBusyIndicator() + .isAnimating()) { + setTitleImage(image); + } else { + setTitleImage(currentImage); + } + } + } + }); + } + } + }); + } + + private void addAction(IAction action) { + String actionId = action.getId(); + if (actionId == null) + return; + + if (actions == null) + actions = new HashMap(); + actions.put(actionId, action); + } + + /** + * Returns the web editor input, if available. If the input was of another + * type, null is returned. + * + * @return org.eclipse.ui.internal.browser.IWebBrowserEditorInput + */ + protected BrowserEditorInput getBrowserEditorInput() { + return (BrowserEditorInput) getEditorInput(); + } + + /** + * Open the input in the internal Web browser. + */ + public static void open(BrowserEditorInput input) { + IWorkbenchWindow workbenchWindow = BrowserPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow(); + IWorkbenchPage page = workbenchWindow.getActivePage(); + + try { + IEditorReference[] editors = page.getEditorReferences(); + int size = editors.length; + for (int i = 0; i < size; i++) { + if (BROWSER_EDITOR_ID.equals(editors[i].getId())) { + IEditorPart editor = editors[i].getEditor(true); + if (editor != null + && editor instanceof InternalBrowserEditor) { + InternalBrowserEditor editor2 = (InternalBrowserEditor) editor; + BrowserEditorInput input2 = editor2 + .getBrowserEditorInput(); + if (input2 == null || input.canReplaceInput(input2)) { + editor.init(editor.getEditorSite(), input); + return; + } + } + } + } + + page.openEditor(input, InternalBrowserEditor.BROWSER_EDITOR_ID); + } catch (Exception e) { + } + } + + public void setFocus() { + if (viewer != null) + viewer.setFocus(); + } + + public BrowserViewer getViewer() { + return viewer; + } + + public boolean close() { + final boolean[] result = new boolean[1]; + Display.getDefault().asyncExec(new Runnable() { + public void run() { + result[0] = getEditorSite().getPage() + .closeEditor(InternalBrowserEditor.this, false); + } + }); + return result[0]; + } + + public IActionBars getActionBars() { + return getEditorSite().getActionBars(); + } + + public void openInExternalBrowser(String url) { + BrowserUtil.gotoUrl(url); + } + + public void setText(String html) { + if (viewer != null && !viewer.getControl().isDisposed()) { + viewer.setText(html); + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.browser.IBrowserViewerContainer#openNewBrowser() + */ + public Browser openNewBrowser() { + final Browser[] ret = new Browser[1]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + final BrowserEditorInput input = new BrowserEditorInput("", //$NON-NLS-1$ + getNewSecondaryId(), + getBrowserEditorInput().getStyle()); + IEditorPart editor = getSite().getPage().openEditor(input, + BROWSER_EDITOR_ID); + if (editor instanceof InternalBrowserEditor) { + ret[0] = ((InternalBrowserEditor) editor).getViewer() + .getBrowser(); + } + } + }); + return ret[0]; + } + + private static Map numbers = new HashMap(); + + private String getNewSecondaryId() { + Integer num = numbers.get(getClientId()); + if (num == null) { + num = Integer.valueOf(1); + } else { + num = Integer.valueOf(num.intValue() + 1); + } + numbers.put(getClientId(), num); + return getClientId() + "-" + num.toString(); //$NON-NLS-1$ + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserView.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserView.java index 215640792..5e6dce978 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserView.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/InternalBrowserView.java @@ -1,307 +1,307 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.GroupMarker; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.part.ViewPart; -import org.xmind.ui.browser.BrowserSupport; -import org.xmind.ui.browser.IBrowser; -import org.xmind.ui.browser.IBrowserSupport; -import org.xmind.ui.browser.IBrowserViewer; -import org.xmind.ui.browser.IBrowserViewerContainer; -import org.xmind.ui.internal.browser.actions.CopyAction; -import org.xmind.ui.internal.browser.actions.CutAction; -import org.xmind.ui.internal.browser.actions.DeleteAction; -import org.xmind.ui.internal.browser.actions.PasteAction; - -public class InternalBrowserView extends ViewPart - implements IBrowserViewerContainer { - - private class OpenInExternalAction extends Action { - /** - * - */ - public OpenInExternalAction() { - super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, - BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); - setToolTipText( - BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - IBrowser browser = BrowserSupport.getInstance() - .createBrowser(IBrowserSupport.AS_EXTERNAL); - try { - browser.openURL(viewer.getURL()); - } catch (PartInitException e) { - BrowserPlugin.log(e); - } - } - } - - public static final String BROWSER_VIEW_ID = "org.xmind.ui.BrowserView"; //$NON-NLS-1$ - - private static final String GROUP_CONTROLS = "org.xmind.ui.browser.controls"; //$NON-NLS-1$ - - private static final String KEY_STYLE = "style"; //$NON-NLS-1$ - - private BrowserViewer viewer; - - private String clientId; - - private int style; - - private ActionContributionItem backActionItem = null; - - private ActionContributionItem forwardActionItem = null; - - private ActionContributionItem stopRefreshActionItem = null; - - public void setClientId(String clientId) { - this.clientId = clientId; - } - - public void changeStyle(int newStyle) { - if ((newStyle & IBrowserSupport.NO_LOCATION_BAR) != 0 - && (newStyle & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) != 0) { - newStyle |= IBrowserSupport.NO_TOOLBAR; - } - this.style = newStyle; - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - int oldStyle = viewer.getStyle(); - viewer.changeStyle(newStyle); - boolean hadNoToolBar = (oldStyle & IBrowserSupport.NO_TOOLBAR) != 0; - boolean hasNoToolBar = (newStyle & IBrowserSupport.NO_TOOLBAR) != 0; - if (hasNoToolBar && !hadNoToolBar) { - IToolBarManager toolBar = getViewSite().getActionBars() - .getToolBarManager(); - removeControls(toolBar); - toolBar.update(true); - } else if (hadNoToolBar && !hasNoToolBar) { - IToolBarManager toolBar = getViewSite().getActionBars() - .getToolBarManager(); - addControls(toolBar); - toolBar.update(true); - } - } - } - - private void removeControls(IToolBarManager toolBar) { - if (backActionItem != null) { - toolBar.remove(backActionItem); - backActionItem.dispose(); - backActionItem = null; - } - if (forwardActionItem != null) { - toolBar.remove(forwardActionItem); - forwardActionItem.dispose(); - forwardActionItem = null; - } - if (stopRefreshActionItem != null) { - toolBar.remove(stopRefreshActionItem); - stopRefreshActionItem.dispose(); - stopRefreshActionItem = null; - } - } - - private void addControls(IToolBarManager toolBar) { - stopRefreshActionItem = new ActionContributionItem( - viewer.getStopRefreshAction()); - toolBar.prependToGroup(GROUP_CONTROLS, stopRefreshActionItem); - forwardActionItem = new ActionContributionItem( - viewer.getForwardAction()); - toolBar.prependToGroup(GROUP_CONTROLS, forwardActionItem); - backActionItem = new ActionContributionItem(viewer.getBackAction()); - toolBar.prependToGroup(GROUP_CONTROLS, backActionItem); - } - - @Override - public void saveState(IMemento memento) { - memento.putInteger(KEY_STYLE, style); - super.saveState(memento); - } - - @Override - public void init(IViewSite site, IMemento memento) - throws PartInitException { - this.clientId = site.getSecondaryId(); - Integer styleValue = memento == null ? null - : memento.getInteger(KEY_STYLE); - this.style = styleValue == null ? SWT.NONE : styleValue.intValue(); - super.init(site, memento); - } - - public void createPartControl(final Composite parent) { - viewer = new BrowserViewer(parent, style, this); - initActions(); - final Image defaultImage = getTitleImage(); - viewer.getBusyIndicator() - .addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - if (!parent.isDisposed()) { - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - if (!parent.isDisposed() - && defaultImage != null - && !defaultImage.isDisposed()) { - Image currentImage = viewer - .getBusyIndicator() - .getCurrentImage(); - if (currentImage == null - || !viewer.getBusyIndicator() - .isAnimating()) { - setTitleImage(defaultImage); - } else { - setTitleImage(currentImage); - } - } - } - }); - } - } - }); - } - - /** - * - */ - private void initActions() { - IActionBars actionBars = getViewSite().getActionBars(); - - OpenInExternalAction openInExternalAction = new OpenInExternalAction(); - - IMenuManager menu = actionBars.getMenuManager(); - menu.add(new GroupMarker(GROUP_CONTROLS)); - menu.add(openInExternalAction); - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - -// IToolBarManager toolBar = actionBars.getToolBarManager(); -// toolBar.add(new GroupMarker(GROUP_CONTROLS)); -// toolBar.add(openInExternalAction); -// toolBar.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - - registerAction(actionBars, new CopyAction(viewer)); - registerAction(actionBars, new CutAction(viewer)); - registerAction(actionBars, new PasteAction(viewer)); - registerAction(actionBars, new DeleteAction(viewer)); - -// if ((style & IBrowserSupport.NO_TOOLBAR) != 0) { -// addControls(toolBar); -// } - } - - private void registerAction(IActionBars actionBars, IAction action) { - actionBars.setGlobalActionHandler(action.getId(), action); - } - - public void setFocus() { - viewer.setFocus(); - } - - public void openURL(String url) { - if (viewer != null && !viewer.getControl().isDisposed()) { - viewer.setURL(url); - } - } - - public BrowserViewer getViewer() { - return viewer; - } - - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter == IBrowserViewer.class) - return viewer; - if (adapter == IBrowserViewerContainer.class) - return this; - return super.getAdapter(adapter); - } - - public boolean close() { - try { - getSite().getPage().hideView(this); - return true; - } catch (Exception e) { - return false; - } - } - - public IActionBars getActionBars() { - return getViewSite().getActionBars(); - } - - public String getClientId() { - return clientId; - } - - public void openInExternalBrowser(String url) { - BrowserUtil.gotoUrl(url); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.browser.IBrowserViewerContainer#openNewBrowser() - */ - public Browser openNewBrowser() { - final Browser[] ret = new Browser[1]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IBrowser browser = BrowserSupport.getInstance().createBrowser( - IBrowserSupport.AS_EDITOR, getClientId()); - browser.openURL(""); //$NON-NLS-1$ - if (browser instanceof InternalBrowser) { - IWorkbenchPart part = ((InternalBrowser) browser).getPart(); - if (part instanceof InternalBrowserEditor) { - ret[0] = ((InternalBrowserEditor) part).getViewer() - .getBrowser(); - } - } - } - }); - return ret[0]; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.xmind.ui.browser.BrowserSupport; +import org.xmind.ui.browser.IBrowser; +import org.xmind.ui.browser.IBrowserSupport; +import org.xmind.ui.browser.IBrowserViewer; +import org.xmind.ui.browser.IBrowserViewerContainer; +import org.xmind.ui.internal.browser.actions.CopyAction; +import org.xmind.ui.internal.browser.actions.CutAction; +import org.xmind.ui.internal.browser.actions.DeleteAction; +import org.xmind.ui.internal.browser.actions.PasteAction; + +public class InternalBrowserView extends ViewPart + implements IBrowserViewerContainer { + + private class OpenInExternalAction extends Action { + /** + * + */ + public OpenInExternalAction() { + super(BrowserMessages.BrowserView_OpenInExternalBrowser_text, + BrowserImages.getImageDescriptor(BrowserImages.BROWSER)); + setToolTipText( + BrowserMessages.BrowserView_OpenInExternalBrowser_toolTip); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + IBrowser browser = BrowserSupport.getInstance() + .createBrowser(IBrowserSupport.AS_EXTERNAL); + try { + browser.openURL(viewer.getURL()); + } catch (PartInitException e) { + BrowserPlugin.log(e); + } + } + } + + public static final String BROWSER_VIEW_ID = "org.xmind.ui.BrowserView"; //$NON-NLS-1$ + + private static final String GROUP_CONTROLS = "org.xmind.ui.browser.controls"; //$NON-NLS-1$ + + private static final String KEY_STYLE = "style"; //$NON-NLS-1$ + + private BrowserViewer viewer; + + private String clientId; + + private int style; + + private ActionContributionItem backActionItem = null; + + private ActionContributionItem forwardActionItem = null; + + private ActionContributionItem stopRefreshActionItem = null; + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public void changeStyle(int newStyle) { + if ((newStyle & IBrowserSupport.NO_LOCATION_BAR) != 0 + && (newStyle & IBrowserSupport.NO_EXTRA_CONTRIBUTIONS) != 0) { + newStyle |= IBrowserSupport.NO_TOOLBAR; + } + this.style = newStyle; + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + int oldStyle = viewer.getStyle(); + viewer.changeStyle(newStyle); + boolean hadNoToolBar = (oldStyle & IBrowserSupport.NO_TOOLBAR) != 0; + boolean hasNoToolBar = (newStyle & IBrowserSupport.NO_TOOLBAR) != 0; + if (hasNoToolBar && !hadNoToolBar) { + IToolBarManager toolBar = getViewSite().getActionBars() + .getToolBarManager(); + removeControls(toolBar); + toolBar.update(true); + } else if (hadNoToolBar && !hasNoToolBar) { + IToolBarManager toolBar = getViewSite().getActionBars() + .getToolBarManager(); + addControls(toolBar); + toolBar.update(true); + } + } + } + + private void removeControls(IToolBarManager toolBar) { + if (backActionItem != null) { + toolBar.remove(backActionItem); + backActionItem.dispose(); + backActionItem = null; + } + if (forwardActionItem != null) { + toolBar.remove(forwardActionItem); + forwardActionItem.dispose(); + forwardActionItem = null; + } + if (stopRefreshActionItem != null) { + toolBar.remove(stopRefreshActionItem); + stopRefreshActionItem.dispose(); + stopRefreshActionItem = null; + } + } + + private void addControls(IToolBarManager toolBar) { + stopRefreshActionItem = new ActionContributionItem( + viewer.getStopRefreshAction()); + toolBar.prependToGroup(GROUP_CONTROLS, stopRefreshActionItem); + forwardActionItem = new ActionContributionItem( + viewer.getForwardAction()); + toolBar.prependToGroup(GROUP_CONTROLS, forwardActionItem); + backActionItem = new ActionContributionItem(viewer.getBackAction()); + toolBar.prependToGroup(GROUP_CONTROLS, backActionItem); + } + + @Override + public void saveState(IMemento memento) { + memento.putInteger(KEY_STYLE, style); + super.saveState(memento); + } + + @Override + public void init(IViewSite site, IMemento memento) + throws PartInitException { + this.clientId = site.getSecondaryId(); + Integer styleValue = memento == null ? null + : memento.getInteger(KEY_STYLE); + this.style = styleValue == null ? SWT.NONE : styleValue.intValue(); + super.init(site, memento); + } + + public void createPartControl(final Composite parent) { + viewer = new BrowserViewer(parent, style, this); + initActions(); + final Image defaultImage = getTitleImage(); + viewer.getBusyIndicator() + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + if (!parent.isDisposed()) { + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!parent.isDisposed() + && defaultImage != null + && !defaultImage.isDisposed()) { + Image currentImage = viewer + .getBusyIndicator() + .getCurrentImage(); + if (currentImage == null + || !viewer.getBusyIndicator() + .isAnimating()) { + setTitleImage(defaultImage); + } else { + setTitleImage(currentImage); + } + } + } + }); + } + } + }); + } + + /** + * + */ + private void initActions() { + IActionBars actionBars = getViewSite().getActionBars(); + + OpenInExternalAction openInExternalAction = new OpenInExternalAction(); + + IMenuManager menu = actionBars.getMenuManager(); + menu.add(new GroupMarker(GROUP_CONTROLS)); + menu.add(openInExternalAction); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + +// IToolBarManager toolBar = actionBars.getToolBarManager(); +// toolBar.add(new GroupMarker(GROUP_CONTROLS)); +// toolBar.add(openInExternalAction); +// toolBar.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + + registerAction(actionBars, new CopyAction(viewer)); + registerAction(actionBars, new CutAction(viewer)); + registerAction(actionBars, new PasteAction(viewer)); + registerAction(actionBars, new DeleteAction(viewer)); + +// if ((style & IBrowserSupport.NO_TOOLBAR) != 0) { +// addControls(toolBar); +// } + } + + private void registerAction(IActionBars actionBars, IAction action) { + actionBars.setGlobalActionHandler(action.getId(), action); + } + + public void setFocus() { + viewer.setFocus(); + } + + public void openURL(String url) { + if (viewer != null && !viewer.getControl().isDisposed()) { + viewer.setURL(url); + } + } + + public BrowserViewer getViewer() { + return viewer; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter == IBrowserViewer.class) + return viewer; + if (adapter == IBrowserViewerContainer.class) + return this; + return super.getAdapter(adapter); + } + + public boolean close() { + try { + getSite().getPage().hideView(this); + return true; + } catch (Exception e) { + return false; + } + } + + public IActionBars getActionBars() { + return getViewSite().getActionBars(); + } + + public String getClientId() { + return clientId; + } + + public void openInExternalBrowser(String url) { + BrowserUtil.gotoUrl(url); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.browser.IBrowserViewerContainer#openNewBrowser() + */ + public Browser openNewBrowser() { + final Browser[] ret = new Browser[1]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IBrowser browser = BrowserSupport.getInstance().createBrowser( + IBrowserSupport.AS_EDITOR, getClientId()); + browser.openURL(""); //$NON-NLS-1$ + if (browser instanceof InternalBrowser) { + IWorkbenchPart part = ((InternalBrowser) browser).getPart(); + if (part instanceof InternalBrowserEditor) { + ret[0] = ((InternalBrowserEditor) part).getViewer() + .getBrowser(); + } + } + } + }); + return ret[0]; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/actions/CutAction.java b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/actions/CutAction.java index ec5b88e9a..d7a74d919 100644 --- a/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/actions/CutAction.java +++ b/bundles/org.xmind.ui.browser/src/org/xmind/ui/internal/browser/actions/CutAction.java @@ -1,29 +1,29 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.browser.actions; - -import org.eclipse.ui.actions.ActionFactory; -import org.xmind.ui.internal.browser.BrowserViewer; - -public class CutAction extends BrowserAction { - - public CutAction(BrowserViewer viewer) { - super(viewer, ActionFactory.CUT.getId()); - } - - public void run() { - getViewer().cut(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.browser.actions; + +import org.eclipse.ui.actions.ActionFactory; +import org.xmind.ui.internal.browser.BrowserViewer; + +public class CutAction extends BrowserAction { + + public CutAction(BrowserViewer viewer) { + super(viewer, ActionFactory.CUT.getId()); + } + + public void run() { + getViewer().cut(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.dashboard/.classpath b/bundles/org.xmind.ui.dashboard/.classpath index 8a8f1668c..ad32c83a7 100644 --- a/bundles/org.xmind.ui.dashboard/.classpath +++ b/bundles/org.xmind.ui.dashboard/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/bundles/org.xmind.ui.dashboard/.gitignore b/bundles/org.xmind.ui.dashboard/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.dashboard/.gitignore +++ b/bundles/org.xmind.ui.dashboard/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.dashboard/.project b/bundles/org.xmind.ui.dashboard/.project index 491e9f9cb..1d57f26f2 100644 --- a/bundles/org.xmind.ui.dashboard/.project +++ b/bundles/org.xmind.ui.dashboard/.project @@ -1,28 +1,28 @@ - - - org.xmind.ui.dashboard - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.ui.dashboard + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.core.prefs index d0a82fcaa..c1b0d45ee 100644 --- a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.core.prefs @@ -1,385 +1,385 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.ui.prefs index 7fa345e81..5e1fe7958 100644 --- a/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.dashboard/.settings/org.eclipse.jdt.ui.prefs @@ -1,55 +1,55 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=true +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF index b20cd6834..d1751839c 100644 --- a/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Dashboard -Bundle-SymbolicName: org.xmind.ui.dashboard;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.internal.dashboard.DashboardPlugin -Bundle-Vendor: XMind Ltd -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.ui.internal.dashboard, - org.xmind.ui.internal.dashboard.pages -Bundle-ClassPath: . +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Dashboard +Bundle-SymbolicName: org.xmind.ui.dashboard;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.internal.dashboard.DashboardPlugin +Bundle-Vendor: XMind Ltd +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.ui.internal.dashboard, + org.xmind.ui.internal.dashboard.pages +Bundle-ClassPath: . diff --git a/bundles/org.xmind.ui.dashboard/build.properties b/bundles/org.xmind.ui.dashboard/build.properties index 6663a129e..34dd11ddd 100644 --- a/bundles/org.xmind.ui.dashboard/build.properties +++ b/bundles/org.xmind.ui.dashboard/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . -source.. = src/ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . +source.. = src/ diff --git a/bundles/org.xmind.ui.dashboard/pom.xml b/bundles/org.xmind.ui.dashboard/pom.xml index 4fa896a9c..820c11679 100644 --- a/bundles/org.xmind.ui.dashboard/pom.xml +++ b/bundles/org.xmind.ui.dashboard/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.dashboard - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.dashboard + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/DashboardPlugin.java b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/DashboardPlugin.java index bb89cc1c2..b68b41647 100644 --- a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/DashboardPlugin.java +++ b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/DashboardPlugin.java @@ -1,50 +1,50 @@ -package org.xmind.ui.internal.dashboard; - -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class DashboardPlugin extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.ui.dashboard"; //$NON-NLS-1$ - - // The shared instance - private static DashboardPlugin plugin; - - /** - * The constructor - */ - public DashboardPlugin() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static DashboardPlugin getDefault() { - return plugin; - } - -} +package org.xmind.ui.internal.dashboard; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class DashboardPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.ui.dashboard"; //$NON-NLS-1$ + + // The shared instance + private static DashboardPlugin plugin; + + /** + * The constructor + */ + public DashboardPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static DashboardPlugin getDefault() { + return plugin; + } + +} diff --git a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/DashboardPage.java b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/DashboardPage.java index 59335890f..e57cd9723 100644 --- a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/DashboardPage.java +++ b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/DashboardPage.java @@ -1,18 +1,18 @@ -package org.xmind.ui.internal.dashboard.pages; - -import org.eclipse.jface.dialogs.DialogPage; - -public abstract class DashboardPage extends DialogPage - implements IDashboardPage { - - private IDashboardContext context = null; - - public void setContext(IDashboardContext container) { - this.context = container; - } - - protected IDashboardContext getContext() { - return context; - } - -} +package org.xmind.ui.internal.dashboard.pages; + +import org.eclipse.jface.dialogs.DialogPage; + +public abstract class DashboardPage extends DialogPage + implements IDashboardPage { + + private IDashboardContext context = null; + + public void setContext(IDashboardContext container) { + this.context = container; + } + + protected IDashboardContext getContext() { + return context; + } + +} diff --git a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardContext.java b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardContext.java index 0bc13a64a..41561d337 100644 --- a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardContext.java +++ b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardContext.java @@ -1,98 +1,98 @@ -package org.xmind.ui.internal.dashboard.pages; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.ui.IEditorInput; - -public interface IDashboardContext extends IAdaptable { - - /** - * Hides the dashboard explicitly. - */ - void hideDashboard(); - - /** - * Allows the command specified by the given id to be enabled via normal - * mechanism. Commands that are not registered via this method will be - * forcibly set to disabled, no matter whether there are active handlers - * available. - * - * @param commandId - * the command id to set enabled - */ - void registerAvailableCommandId(String commandId); - - /** - * Registers the popup menu specified by the given id within the dashboard. - * Registered menus will be extended with menu contributions. - * - * @param menuParent - * the parent for the context menu, e.g. a Control in SWT - * @param menuId - * the id of the context menu to use - * @return true if registration succeeded else - * false - */ - boolean registerContextMenu(Object menuParent, String menuId); - - /** - * Opens a new editor for the given input in the current window. - * - * @param input - * the input to edit - * @param editorId - * the editor id specifying which type of editor to use - */ - boolean openEditor(IEditorInput input, String editorId); - - /** - * Opens a new view in the current window. - * - * @param viewId - * the view id specifying which type of view to open - */ - boolean showView(String viewId); - - /** - * Retrieves a dashboard state string associated with the given key that was - * set by previous calls to {@link #setPersistedState(String, String)}. - * Persisted states are preserved across program sessions. - * - * @param key - * a string that should NEVER be null - * @return a string associated with the key, or null if no such - * value is available - * @throws IllegalArgumentException - * if the key is null - */ - String getPersistedState(String key); - - /** - * Sets a dashboard state string to be associated with the given key. - * Persisted states are preserved across program sessions. - * - * @param key - * a string that should NEVER be null - * @param value - * a string, or null to clear previously set values - * associated with the given key - * @throws IllegalArgumentException - * if the key is null - */ - void setPersistedState(String key, String value); - - /** - * @param key - * @return - */ - Object getContextVariable(String key); - - /** - * @param key - * @return - */ - T getContextVariable(Class key); - - void setSelectionProvider(ISelectionProvider selectionProvider); - -} +package org.xmind.ui.internal.dashboard.pages; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.IEditorInput; + +public interface IDashboardContext extends IAdaptable { + + /** + * Hides the dashboard explicitly. + */ + void hideDashboard(); + + /** + * Allows the command specified by the given id to be enabled via normal + * mechanism. Commands that are not registered via this method will be + * forcibly set to disabled, no matter whether there are active handlers + * available. + * + * @param commandId + * the command id to set enabled + */ + void registerAvailableCommandId(String commandId); + + /** + * Registers the popup menu specified by the given id within the dashboard. + * Registered menus will be extended with menu contributions. + * + * @param menuParent + * the parent for the context menu, e.g. a Control in SWT + * @param menuId + * the id of the context menu to use + * @return true if registration succeeded else + * false + */ + boolean registerContextMenu(Object menuParent, String menuId); + + /** + * Opens a new editor for the given input in the current window. + * + * @param input + * the input to edit + * @param editorId + * the editor id specifying which type of editor to use + */ + boolean openEditor(IEditorInput input, String editorId); + + /** + * Opens a new view in the current window. + * + * @param viewId + * the view id specifying which type of view to open + */ + boolean showView(String viewId); + + /** + * Retrieves a dashboard state string associated with the given key that was + * set by previous calls to {@link #setPersistedState(String, String)}. + * Persisted states are preserved across program sessions. + * + * @param key + * a string that should NEVER be null + * @return a string associated with the key, or null if no such + * value is available + * @throws IllegalArgumentException + * if the key is null + */ + String getPersistedState(String key); + + /** + * Sets a dashboard state string to be associated with the given key. + * Persisted states are preserved across program sessions. + * + * @param key + * a string that should NEVER be null + * @param value + * a string, or null to clear previously set values + * associated with the given key + * @throws IllegalArgumentException + * if the key is null + */ + void setPersistedState(String key, String value); + + /** + * @param key + * @return + */ + Object getContextVariable(String key); + + /** + * @param key + * @return + */ + T getContextVariable(Class key); + + void setSelectionProvider(ISelectionProvider selectionProvider); + +} diff --git a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardPage.java b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardPage.java index 1241fa790..4e50ed479 100644 --- a/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardPage.java +++ b/bundles/org.xmind.ui.dashboard/src/org/xmind/ui/internal/dashboard/pages/IDashboardPage.java @@ -1,11 +1,11 @@ -package org.xmind.ui.internal.dashboard.pages; - -import org.eclipse.jface.dialogs.IDialogPage; - -public interface IDashboardPage extends IDialogPage { - - void setContext(IDashboardContext container); - - void setFocus(); - -} +package org.xmind.ui.internal.dashboard.pages; + +import org.eclipse.jface.dialogs.IDialogPage; + +public interface IDashboardPage extends IDialogPage { + + void setContext(IDashboardContext container); + + void setFocus(); + +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/.classpath b/bundles/org.xmind.ui.exports.vector.svg/.classpath index 861dce6eb..d804c65b3 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.classpath +++ b/bundles/org.xmind.ui.exports.vector.svg/.classpath @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.exports.vector.svg/.gitignore b/bundles/org.xmind.ui.exports.vector.svg/.gitignore index 2caedc74c..e978127ff 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.gitignore +++ b/bundles/org.xmind.ui.exports.vector.svg/.gitignore @@ -1,16 +1,16 @@ -.metadata -bin/** -tmp/** -tmp/**/* -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folders containing Maven build results -target/ +.metadata +bin/** +tmp/** +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folders containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.exports.vector.svg/.project b/bundles/org.xmind.ui.exports.vector.svg/.project index 1787e099a..54df7e631 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.project +++ b/bundles/org.xmind.ui.exports.vector.svg/.project @@ -1,28 +1,28 @@ - - - org.xmind.ui.exports.vector.svg - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.ui.exports.vector.svg + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs index a63f9374d..47d8b7758 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs @@ -1,411 +1,411 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.ui.exports.vector.svg/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.exports.vector.svg/META-INF/MANIFEST.MF index 431cfc813..9a2ff3a85 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.exports.vector.svg/META-INF/MANIFEST.MF @@ -1,20 +1,20 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.exports.vector.svg;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.internal.exports.vector.svg.SvgPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.xmind.ui;bundle-version="[3.7.0,3.8.0)", - org.xmind.de.erichseifert.vectorgraphics2d;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.exports.vector;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)" -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Bundle-Localization: plugin -Bundle-ClassPath: . -Export-Package: org.xmind.ui.exports.vector.svg, - org.xmind.ui.internal.exports.vector.svg +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.exports.vector.svg;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.internal.exports.vector.svg.SvgPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.xmind.ui;bundle-version="[3.7.0,3.8.0)", + org.xmind.de.erichseifert.vectorgraphics2d;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.exports.vector;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin +Bundle-ClassPath: . +Export-Package: org.xmind.ui.exports.vector.svg, + org.xmind.ui.internal.exports.vector.svg diff --git a/bundles/org.xmind.ui.exports.vector.svg/about.html b/bundles/org.xmind.ui.exports.vector.svg/about.html index be8519f05..ff9083efa 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/about.html +++ b/bundles/org.xmind.ui.exports.vector.svg/about.html @@ -1,19 +1,19 @@ - - - - -About - - -

    About This Content

    - -

    Jun 27, 2012

    - -

    -XMind Plus/Pro release under the terms of the XMIND PROPRIETARY LICENSE AGREEMENT. -

    - - - + + + + +About + + +

    About This Content

    + +

    Jun 27, 2012

    + +

    +XMind Plus/Pro release under the terms of the XMIND PROPRIETARY LICENSE AGREEMENT. +

    + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.exports.vector.svg/build.properties b/bundles/org.xmind.ui.exports.vector.svg/build.properties index 223e2e481..9f45063bc 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/build.properties +++ b/bundles/org.xmind.ui.exports.vector.svg/build.properties @@ -1,9 +1,9 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html,\ - icons/,\ - plugin.properties,\ - plugin.xml -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + icons/,\ + plugin.properties,\ + plugin.xml +src.includes = about.html diff --git a/bundles/org.xmind.ui.exports.vector.svg/plugin.properties b/bundles/org.xmind.ui.exports.vector.svg/plugin.properties index 9bc3b9868..ad1e08f4f 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/plugin.properties +++ b/bundles/org.xmind.ui.exports.vector.svg/plugin.properties @@ -1,4 +1,4 @@ -#Properties file for org.xmind.ui.exports.vector.svg -providerName = XMind Ltd. -pluginName = XMind Export Support For Svg +#Properties file for org.xmind.ui.exports.vector.svg +providerName = XMind Ltd. +pluginName = XMind Export Support For Svg exportWizard.svg.name = SVG File \ No newline at end of file diff --git a/bundles/org.xmind.ui.exports.vector.svg/plugin.xml b/bundles/org.xmind.ui.exports.vector.svg/plugin.xml index 326b01db9..289cad4d9 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/plugin.xml +++ b/bundles/org.xmind.ui.exports.vector.svg/plugin.xml @@ -1,15 +1,15 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.exports.vector.svg/pom.xml b/bundles/org.xmind.ui.exports.vector.svg/pom.xml index d2e299e51..ef5d7926f 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/pom.xml +++ b/bundles/org.xmind.ui.exports.vector.svg/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.exports.vector.svg - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.exports.vector.svg + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/exports/vector/svg/SVGGenerator.java b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/exports/vector/svg/SVGGenerator.java index 8e7d975af..ef1c9c8c5 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/exports/vector/svg/SVGGenerator.java +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/exports/vector/svg/SVGGenerator.java @@ -1,135 +1,130 @@ -package org.xmind.ui.exports.vector.svg; - -import static org.xmind.gef.IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH; - -import java.io.File; -import java.io.InterruptedIOException; -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.xmind.core.Core; -import org.xmind.gef.util.Properties; -import org.xmind.ui.internal.exports.vector.svg.SVGExporter; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.util.Logger; -import org.xmind.ui.util.MindMapUtils; -import org.xmind.ui.wizards.IExporter; - -public class SVGGenerator { - - private IMindMap mindmap; - - private IMindMapViewer sourceViewer; - - private Display display; - - private Shell parentShell; - - private boolean renderAsPath; - - private boolean plusVisible; - - private boolean minusVisible; - - public SVGGenerator(IMindMap mindmap, IMindMapViewer sourceViewer, - Display display, Shell parentShell, boolean renderAsPath, - boolean plusVisible, boolean minusVisible) { - this.mindmap = mindmap; - this.sourceViewer = sourceViewer; - this.display = display; - this.parentShell = parentShell; - this.renderAsPath = renderAsPath; - this.plusVisible = plusVisible; - this.minusVisible = minusVisible; - } - - //This method may have a long delay, so as best invoke it in a independent thread. - public File generate() { - if (doGenerate()) { - return new File(getTargetPath()); - } else { - return null; - } - } - - private boolean doGenerate() { - try { - try { - doGenerate(display, parentShell); - } catch (OutOfMemoryError e) { - try { - throw new Exception("Image is too large.", e); //$NON-NLS-1$ - } catch (Exception e2) { - throw new InvocationTargetException(e2); - } - } - return true; - } catch (Throwable e) { - if (e instanceof InterruptedException - || e instanceof InterruptedIOException) { - return false; - } - while (e instanceof InvocationTargetException) { - Throwable t = ((InvocationTargetException) e).getCause(); - if (t == null) - break; - e = t; - } - final Throwable ex = e; - display.asyncExec(new Runnable() { - - public void run() { - handleExportException(ex); - } - - }); - } - return false; - } - - private void doGenerate(Display display, Shell parentShell) - throws InvocationTargetException, InterruptedException { - IExporter exporter = createExporter(); - if (!exporter.canStart()) - throw new InterruptedException(); - - exporter.start(display, parentShell); - exporter.end(); - } - - private IExporter createExporter() { - SVGExporter exporter = new SVGExporter(mindmap.getSheet(), - mindmap.getCentralTopic(), getTargetPath(), sourceViewer, - null) { - - @Override - protected void initProperties(Properties properties) { - properties.set(IMindMapViewer.PLUS_VISIBLE, plusVisible); - properties.set(IMindMapViewer.MINUS_VISIBLE, minusVisible); - properties.set(VIEWER_RENDER_TEXT_AS_PATH, renderAsPath); - } - }; - - exporter.init(); - return exporter; - } - - private String getTargetPath() { - return Core.getWorkspace().getTempFile("svg/" + getSuggestedFileName()); //$NON-NLS-1$ - } - - private String getSuggestedFileName() { - String fileName = mindmap.getCentralTopic().getTitleText(); - String replacedFileName = MindMapUtils.trimFileName(fileName); - return replacedFileName + ".svg"; //$NON-NLS-1$ - } - - private void handleExportException(Throwable e) { - Logger.log(e, - NLS.bind("Error occurred when generating {0} file.", "SVG")); //$NON-NLS-1$//$NON-NLS-2$ - } - -} +package org.xmind.ui.exports.vector.svg; + +import static org.xmind.gef.IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH; + +import java.io.File; +import java.io.InterruptedIOException; +import java.lang.reflect.InvocationTargetException; +import java.util.UUID; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.xmind.core.Core; +import org.xmind.gef.util.Properties; +import org.xmind.ui.internal.exports.vector.svg.SVGExporter; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.util.Logger; +import org.xmind.ui.wizards.IExporter; + +public class SVGGenerator { + + private IMindMap mindmap; + + private IMindMapViewer sourceViewer; + + private Display display; + + private Shell parentShell; + + private boolean renderAsPath; + + private boolean plusVisible; + + private boolean minusVisible; + + public SVGGenerator(IMindMap mindmap, IMindMapViewer sourceViewer, + Display display, Shell parentShell, boolean renderAsPath, + boolean plusVisible, boolean minusVisible) { + this.mindmap = mindmap; + this.sourceViewer = sourceViewer; + this.display = display; + this.parentShell = parentShell; + this.renderAsPath = renderAsPath; + this.plusVisible = plusVisible; + this.minusVisible = minusVisible; + } + + //This method may have a long delay, so as best invoke it in a independent thread. + public File generate() { + if (doGenerate()) { + return new File(getTargetPath()); + } else { + return null; + } + } + + private boolean doGenerate() { + try { + try { + doGenerate(display, parentShell); + } catch (OutOfMemoryError e) { + try { + throw new Exception("Image is too large.", e); //$NON-NLS-1$ + } catch (Exception e2) { + throw new InvocationTargetException(e2); + } + } + return true; + } catch (Throwable e) { + if (e instanceof InterruptedException + || e instanceof InterruptedIOException) { + return false; + } + while (e instanceof InvocationTargetException) { + Throwable t = ((InvocationTargetException) e).getCause(); + if (t == null) + break; + e = t; + } + final Throwable ex = e; + display.asyncExec(new Runnable() { + + public void run() { + handleExportException(ex); + } + + }); + } + return false; + } + + private void doGenerate(Display display, Shell parentShell) + throws InvocationTargetException, InterruptedException { + IExporter exporter = createExporter(); + if (!exporter.canStart()) + throw new InterruptedException(); + + exporter.start(display, parentShell); + exporter.end(); + } + + private IExporter createExporter() { + SVGExporter exporter = new SVGExporter(mindmap.getSheet(), + mindmap.getCentralTopic(), getTargetPath(), sourceViewer, + null) { + + @Override + protected void initProperties(Properties properties) { + properties.set(IMindMapViewer.PLUS_VISIBLE, plusVisible); + properties.set(IMindMapViewer.MINUS_VISIBLE, minusVisible); + properties.set(VIEWER_RENDER_TEXT_AS_PATH, renderAsPath); + } + }; + + exporter.init(); + return exporter; + } + + private String getTargetPath() { + return Core.getWorkspace() + .getTempFile("svg/" + UUID.randomUUID().toString() + ".svg"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void handleExportException(Throwable e) { + Logger.log(e, + NLS.bind("Error occurred when generating {0} file.", "SVG")); //$NON-NLS-1$//$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/Messages.java b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/Messages.java index 9cc8abcde..500e4ddd8 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/Messages.java +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/Messages.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.exports.vector.svg; - -import org.eclipse.osgi.util.NLS; - -/** - * @author Jason Wong - */ -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.xmind.ui.internal.exports.vector.svg.messages"; //$NON-NLS-1$ - - public static String SVGWizard_WindowTitle; - public static String SVGWizard_FormatName; - public static String SVGPage_Title; - public static String SVGPage_Description; - public static String SVGPage_FilterName; - public static String SVGExportJob_Name; - - public static String SVGExportWizard_showMinusCheck_text; - - public static String SVGExportWizard_showPlusCheck_text; - - public static String ExportPage_Launching; - - public static String ExportWizard_Collapse_Expand_text; - - static { - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.exports.vector.svg; + +import org.eclipse.osgi.util.NLS; + +/** + * @author Jason Wong + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.xmind.ui.internal.exports.vector.svg.messages"; //$NON-NLS-1$ + + public static String SVGWizard_WindowTitle; + public static String SVGWizard_FormatName; + public static String SVGPage_Title; + public static String SVGPage_Description; + public static String SVGPage_FilterName; + public static String SVGExportJob_Name; + + public static String SVGExportWizard_showMinusCheck_text; + + public static String SVGExportWizard_showPlusCheck_text; + + public static String ExportPage_Launching; + + public static String ExportWizard_Collapse_Expand_text; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExportWizard.java b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExportWizard.java index b5b6e76dc..ff2a04336 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExportWizard.java +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExportWizard.java @@ -1,312 +1,312 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.exports.vector.svg; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.wizards.AbstractMindMapExportPage; -import org.xmind.ui.wizards.DocumentExportWizard; -import org.xmind.ui.wizards.ExportContants; -import org.xmind.ui.wizards.IExporter; - -/** - * @author Jason Wong - */ -public class SVGExportWizard extends DocumentExportWizard { - - private static final String PAGE_NAME = "org.xmind.ui.export.svgExportPage"; //$NON-NLS-1$ - - private static final String SECTION_NAME = "org.xmind.ui.export.svg"; //$NON-NLS-1$ - - private static final String SVG_EXT = ".svg"; //$NON-NLS-1$ - - private class SVGExportPage extends AbstractMindMapExportPage { - - private Button showPlusCheck; - - private Button showMinusCheck; - - public SVGExportPage() { - super(PAGE_NAME, Messages.SVGPage_Title); - setDescription(Messages.SVGPage_Description); - } - - protected void setDialogFilters(FileDialog dialog, - List filterNames, List filterExtensions) { - filterNames.add(0, Messages.SVGPage_FilterName); - filterExtensions.add(0, "*" + SVG_EXT); //$NON-NLS-1$ - super.setDialogFilters(dialog, filterNames, filterExtensions); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 25; - layout.marginTop = 20; - composite.setLayout(layout); - setControl(composite); - - Control setupGroup = createSetupControls(composite); - setupGroup.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - Control fileGroup = createFileControls(composite); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = 210; - fileGroup.setLayoutData(gridData); - } - - private Control createSetupControls(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createShowPlusMinusControls(composite); - return composite; - } - - private void createShowPlusMinusControls(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 15; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - Label label = new Label(composite, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - label.setText(Messages.ExportWizard_Collapse_Expand_text); - - Composite rightGroup = new Composite(composite, SWT.NONE); - GridLayout gridLayout2 = new GridLayout(1, false); - gridLayout2.marginWidth = 0; - gridLayout2.marginHeight = 0; - gridLayout2.verticalSpacing = 15; - gridLayout2.horizontalSpacing = 0; - gridLayout2.marginLeft = 15; - rightGroup.setLayout(gridLayout2); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); - gridData.widthHint = 300; - gridData.heightHint = SWT.DEFAULT; - rightGroup.setLayoutData(gridData); - - createShowPlusCheck(rightGroup); - createShowMinusCheck(rightGroup); - - initPlusMinusCheckState(); - } - - private void createShowPlusCheck(Composite parent) { - showPlusCheck = createPlusMinusCheck(parent, - Messages.SVGExportWizard_showPlusCheck_text, - MindMapUI.getImages().get("plus.png", true).createImage()); //$NON-NLS-1$ - } - - private void createShowMinusCheck(Composite parent) { - showMinusCheck = createPlusMinusCheck(parent, - Messages.SVGExportWizard_showMinusCheck_text, - MindMapUI.getImages().get("minus.png", true).createImage()); //$NON-NLS-1$ - } - - private Button createPlusMinusCheck(Composite parent, String text, - Image image) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false)); - - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 5; - composite.setLayout(gridLayout); - - Button check = new Button(composite, SWT.CHECK); - check.setBackground(composite.getBackground()); - check.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - check.setText(text); - - Label imageLabel = new Label(composite, SWT.NONE); - imageLabel.setBackground(composite.getBackground()); - imageLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - imageLabel.setImage(image); - - hookWidget(check, SWT.Selection); - - return check; - } - - private void initPlusMinusCheckState() { - boolean plusVisible = getBoolean(getDialogSettings(), - ExportContants.PLUS_VISIBLE, - ExportContants.DEFAULT_PLUS_VISIBLE); - boolean minusVisible = getBoolean(getDialogSettings(), - ExportContants.MINUS_VISIBLE, - ExportContants.DEFAULT_MINUS_VISIBLE); - - showPlusCheck.setSelection(plusVisible); - showMinusCheck.setSelection(minusVisible); - } - - private boolean getBoolean(IDialogSettings settings, String key, - boolean defaultValue) { - boolean value = defaultValue; - if (settings.get(key) != null) { - value = settings.getBoolean(key); - } - - return value; - } - - @Override - protected void handleWidgetEvent(Event event) { - if (event.widget == showPlusCheck) { - setProperty(ExportContants.PLUS_VISIBLE, - showPlusCheck.getSelection()); - } else if (event.widget == showMinusCheck) { - setProperty(ExportContants.MINUS_VISIBLE, - showMinusCheck.getSelection()); - } else { - super.handleWidgetEvent(event); - } - } - - private void setProperty(String key, boolean value) { - getDialogSettings().put(key, value); - } - } - - private SVGExportPage page; - - public SVGExportWizard() { - setWindowTitle(Messages.SVGWizard_WindowTitle); - setDialogSettings(SvgPlugin.getDialogSettings(SECTION_NAME)); - setDefaultPageImageDescriptor( - MindMapUI.getImages().getWizBan(IMindMapImages.WIZ_EXPORT)); - } - - @Override - protected IExporter createExporter() { - IMindMap mindmap = getSourceMindMap(); - SVGExporter exporter = new SVGExporter(mindmap.getSheet(), - mindmap.getCentralTopic(), getTargetPath(), getSourceViewer(), - getDialogSettings()); - exporter.setDialogSettings(getDialogSettings()); - exporter.init(); - return exporter; - } - - @Override - public void openFile(String path, IProgressMonitor monitor) { - boolean edgeExcuteFlag = false; - if (new File(path).exists()) { - monitor.subTask(Messages.ExportPage_Launching); - if (isWin10OrHigher()) { - try { - edgeExcuteFlag = true; - Runtime.getRuntime() - .exec("cmd.exe /c \"start microsoft-edge:" //$NON-NLS-1$ - + new File(path).toURI().toString() + "\""); //$NON-NLS-1$ - } catch (IOException e) { - e.printStackTrace(); - } - } - if (!edgeExcuteFlag) - Program.launch(path); - } - } - - public boolean isWin10OrHigher() { - String osVersion = System.getProperty("os.version"); //$NON-NLS-1$ - String osName = System.getProperty("os.name"); //$NON-NLS-1$ - if (osName.indexOf("Windows") != -1) //$NON-NLS-1$ - if (osVersion.indexOf("10.") != -1 //$NON-NLS-1$ - || Double.valueOf(osVersion) > 6.2 - && Double.valueOf(osVersion) < 7.0) - return true; - return false; - } - - @Override - protected void addValidPages() { - addPage(page = new SVGExportPage()); - } - - @Override - protected String getFormatName() { - return Messages.SVGWizard_FormatName; - } - - @Override - protected boolean isExtensionCompatible(String path, String extension) { - return super.isExtensionCompatible(path, extension) - && SVG_EXT.equalsIgnoreCase(extension); - } - - @Override - protected void handleExportException(Throwable e) { - super.handleExportException(e); - page.setErrorMessage(e.getLocalizedMessage()); - } - - protected String getSuggestedFileName() { - return super.getSuggestedFileName() + SVG_EXT; - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.wizards.DocumentExportWizard#doExport(org.eclipse.core. - * runtime.IProgressMonitor, org.eclipse.swt.widgets.Display, - * org.eclipse.swt.widgets.Shell) - */ - @Override - protected void doExport(IProgressMonitor monitor, Display display, - Shell parentShell) - throws InvocationTargetException, InterruptedException { - SvgPlugin.getDefault().getUsageDataCollector() - .increase("ExportToSVGCount"); //$NON-NLS-1$ - super.doExport(monitor, display, parentShell); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.exports.vector.svg; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.wizards.AbstractMindMapExportPage; +import org.xmind.ui.wizards.DocumentExportWizard; +import org.xmind.ui.wizards.ExportContants; +import org.xmind.ui.wizards.IExporter; + +/** + * @author Jason Wong + */ +public class SVGExportWizard extends DocumentExportWizard { + + private static final String PAGE_NAME = "org.xmind.ui.export.svgExportPage"; //$NON-NLS-1$ + + private static final String SECTION_NAME = "org.xmind.ui.export.svg"; //$NON-NLS-1$ + + private static final String SVG_EXT = ".svg"; //$NON-NLS-1$ + + private class SVGExportPage extends AbstractMindMapExportPage { + + private Button showPlusCheck; + + private Button showMinusCheck; + + public SVGExportPage() { + super(PAGE_NAME, Messages.SVGPage_Title); + setDescription(Messages.SVGPage_Description); + } + + protected void setDialogFilters(FileDialog dialog, + List filterNames, List filterExtensions) { + filterNames.add(0, Messages.SVGPage_FilterName); + filterExtensions.add(0, "*" + SVG_EXT); //$NON-NLS-1$ + super.setDialogFilters(dialog, filterNames, filterExtensions); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 25; + layout.marginTop = 20; + composite.setLayout(layout); + setControl(composite); + + Control setupGroup = createSetupControls(composite); + setupGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + Control fileGroup = createFileControls(composite); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = 210; + fileGroup.setLayoutData(gridData); + } + + private Control createSetupControls(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createShowPlusMinusControls(composite); + return composite; + } + + private void createShowPlusMinusControls(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 15; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + Label label = new Label(composite, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + label.setText(Messages.ExportWizard_Collapse_Expand_text); + + Composite rightGroup = new Composite(composite, SWT.NONE); + GridLayout gridLayout2 = new GridLayout(1, false); + gridLayout2.marginWidth = 0; + gridLayout2.marginHeight = 0; + gridLayout2.verticalSpacing = 15; + gridLayout2.horizontalSpacing = 0; + gridLayout2.marginLeft = 15; + rightGroup.setLayout(gridLayout2); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); + gridData.widthHint = 300; + gridData.heightHint = SWT.DEFAULT; + rightGroup.setLayoutData(gridData); + + createShowPlusCheck(rightGroup); + createShowMinusCheck(rightGroup); + + initPlusMinusCheckState(); + } + + private void createShowPlusCheck(Composite parent) { + showPlusCheck = createPlusMinusCheck(parent, + Messages.SVGExportWizard_showPlusCheck_text, + MindMapUI.getImages().get("plus.png", true).createImage()); //$NON-NLS-1$ + } + + private void createShowMinusCheck(Composite parent) { + showMinusCheck = createPlusMinusCheck(parent, + Messages.SVGExportWizard_showMinusCheck_text, + MindMapUI.getImages().get("minus.png", true).createImage()); //$NON-NLS-1$ + } + + private Button createPlusMinusCheck(Composite parent, String text, + Image image) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData( + new GridData(SWT.LEFT, SWT.CENTER, false, false)); + + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 5; + composite.setLayout(gridLayout); + + Button check = new Button(composite, SWT.CHECK); + check.setBackground(composite.getBackground()); + check.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + check.setText(text); + + Label imageLabel = new Label(composite, SWT.NONE); + imageLabel.setBackground(composite.getBackground()); + imageLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + imageLabel.setImage(image); + + hookWidget(check, SWT.Selection); + + return check; + } + + private void initPlusMinusCheckState() { + boolean plusVisible = getBoolean(getDialogSettings(), + ExportContants.PLUS_VISIBLE, + ExportContants.DEFAULT_PLUS_VISIBLE); + boolean minusVisible = getBoolean(getDialogSettings(), + ExportContants.MINUS_VISIBLE, + ExportContants.DEFAULT_MINUS_VISIBLE); + + showPlusCheck.setSelection(plusVisible); + showMinusCheck.setSelection(minusVisible); + } + + private boolean getBoolean(IDialogSettings settings, String key, + boolean defaultValue) { + boolean value = defaultValue; + if (settings.get(key) != null) { + value = settings.getBoolean(key); + } + + return value; + } + + @Override + protected void handleWidgetEvent(Event event) { + if (event.widget == showPlusCheck) { + setProperty(ExportContants.PLUS_VISIBLE, + showPlusCheck.getSelection()); + } else if (event.widget == showMinusCheck) { + setProperty(ExportContants.MINUS_VISIBLE, + showMinusCheck.getSelection()); + } else { + super.handleWidgetEvent(event); + } + } + + private void setProperty(String key, boolean value) { + getDialogSettings().put(key, value); + } + } + + private SVGExportPage page; + + public SVGExportWizard() { + setWindowTitle(Messages.SVGWizard_WindowTitle); + setDialogSettings(SvgPlugin.getDialogSettings(SECTION_NAME)); + setDefaultPageImageDescriptor( + MindMapUI.getImages().getWizBan(IMindMapImages.WIZ_EXPORT)); + } + + @Override + protected IExporter createExporter() { + IMindMap mindmap = getSourceMindMap(); + SVGExporter exporter = new SVGExporter(mindmap.getSheet(), + mindmap.getCentralTopic(), getTargetPath(), getSourceViewer(), + getDialogSettings()); + exporter.setDialogSettings(getDialogSettings()); + exporter.init(); + return exporter; + } + + @Override + public void openFile(String path, IProgressMonitor monitor) { + boolean edgeExcuteFlag = false; + if (new File(path).exists()) { + monitor.subTask(Messages.ExportPage_Launching); + if (isWin10OrHigher()) { + try { + edgeExcuteFlag = true; + Runtime.getRuntime() + .exec("cmd.exe /c \"start microsoft-edge:" //$NON-NLS-1$ + + new File(path).toURI().toString() + "\""); //$NON-NLS-1$ + } catch (IOException e) { + e.printStackTrace(); + } + } + if (!edgeExcuteFlag) + Program.launch(path); + } + } + + public boolean isWin10OrHigher() { + String osVersion = System.getProperty("os.version"); //$NON-NLS-1$ + String osName = System.getProperty("os.name"); //$NON-NLS-1$ + if (osName.indexOf("Windows") != -1) //$NON-NLS-1$ + if (osVersion.indexOf("10.") != -1 //$NON-NLS-1$ + || Double.valueOf(osVersion) > 6.2 + && Double.valueOf(osVersion) < 7.0) + return true; + return false; + } + + @Override + protected void addValidPages() { + addPage(page = new SVGExportPage()); + } + + @Override + protected String getFormatName() { + return Messages.SVGWizard_FormatName; + } + + @Override + protected boolean isExtensionCompatible(String path, String extension) { + return super.isExtensionCompatible(path, extension) + && SVG_EXT.equalsIgnoreCase(extension); + } + + @Override + protected void handleExportException(Throwable e) { + super.handleExportException(e); + page.setErrorMessage(e.getLocalizedMessage()); + } + + protected String getSuggestedFileName() { + return super.getSuggestedFileName() + SVG_EXT; + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.wizards.DocumentExportWizard#doExport(org.eclipse.core. + * runtime.IProgressMonitor, org.eclipse.swt.widgets.Display, + * org.eclipse.swt.widgets.Shell) + */ + @Override + protected void doExport(IProgressMonitor monitor, Display display, + Shell parentShell) + throws InvocationTargetException, InterruptedException { + SvgPlugin.getDefault().getUsageDataCollector() + .increase("ExportToSVGCount"); //$NON-NLS-1$ + super.doExport(monitor, display, parentShell); + } + +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExporter.java b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExporter.java index 65d4c0027..77c59591e 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExporter.java +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SVGExporter.java @@ -1,202 +1,202 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.exports.vector.svg; - -import static org.xmind.gef.IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH; - -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.de.erichseifert.vectorgraphics2d.SVGGraphics2D; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.util.Properties; -import org.xmind.ui.exports.vector.graphics.GraphicsToGraphics2DAdaptor; -import org.xmind.ui.internal.figures.SheetFigure; -import org.xmind.ui.mindmap.GhostShellProvider; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.MindMapExportViewer; -import org.xmind.ui.viewers.ICompositeProvider; -import org.xmind.ui.wizards.ExportContants; -import org.xmind.ui.wizards.Exporter; -import org.xmind.ui.wizards.IExportPart; - -/** - * @author Jason Wong - */ -public class SVGExporter extends Exporter { - - private static final int DEFAULT_MARGIN = 15; - - private ISheet sheet; - - private String targetPath; - - private IGraphicalViewer viewer; - - private IGraphicalViewer exportViewer; - - private ICompositeProvider compositeProvider; - - private Rectangle bounds; - - private SVGGraphics2D svgGenerator; - - private GraphicsToGraphics2DAdaptor adaptor; - - private IDialogSettings settings; - - public SVGExporter(ISheet sheet, ITopic centralTopic, String targetPath, - IGraphicalViewer viewer, IDialogSettings settings) { - super(sheet, centralTopic); - this.sheet = sheet; - this.targetPath = targetPath; - this.viewer = viewer; - this.settings = settings; - } - - public void init() { - bounds = getFigureBounds(); - svgGenerator = new SVGGraphics2D(0, 0, bounds.width, bounds.height); - } - - private Rectangle getFigureBounds() { - Rectangle extent = getSheetFigure().getFreeformExtent(); - return new Rectangle(0, 0, extent.width + DEFAULT_MARGIN * 2, - extent.height + DEFAULT_MARGIN * 2); - } - - @Override - public void start(final Display display, Shell shell) - throws InvocationTargetException { - super.start(display, shell); - - adaptor = new GraphicsToGraphics2DAdaptor(svgGenerator, bounds, - display); - setTranslate(adaptor); - compositeProvider = new GhostShellProvider(display); - - display.syncExec(new Runnable() { - - public void run() { - exportViewer = new MindMapExportViewer(compositeProvider, - viewer.getAdapter(IMindMap.class), - viewer.getProperties()); - Properties properties = exportViewer.getProperties(); - initProperties(properties); - - exportViewer.getCanvas().getLightweightSystem() - .getUpdateManager().performValidation(); - exportViewer.getLayer(GEF.LAYER_BACKGROUND).paint(adaptor); - exportViewer.getLayer(GEF.LAYER_CONTENTS).paint(adaptor); - } - }); - } - - protected void initProperties(Properties properties) { - //set plus minus visibility - boolean plusVisible = getBoolean(settings, ExportContants.PLUS_VISIBLE, - ExportContants.DEFAULT_PLUS_VISIBLE); - boolean minusVisible = getBoolean(settings, - ExportContants.MINUS_VISIBLE, - ExportContants.DEFAULT_MINUS_VISIBLE); - properties.set(IMindMapViewer.PLUS_VISIBLE, plusVisible); - properties.set(IMindMapViewer.MINUS_VISIBLE, minusVisible); - - if (Platform.OS_LINUX.equals(Platform.getOS())) { - properties.set(VIEWER_RENDER_TEXT_AS_PATH, false); - } else { - properties.set(VIEWER_RENDER_TEXT_AS_PATH, true); - } - } - - private boolean getBoolean(IDialogSettings settings, String key, - boolean defaultValue) { - boolean value = defaultValue; - if (settings.get(key) != null) { - value = settings.getBoolean(key); - } - - return value; - } - - @Override - protected void write(IProgressMonitor monitor, IExportPart part) - throws InvocationTargetException, InterruptedException { - } - - @Override - public void end() throws InvocationTargetException { - try { - Writer out = new OutputStreamWriter( - new FileOutputStream(targetPath), "UTF-8"); //$NON-NLS-1$ - out.write(svgGenerator.toString()); - out.close(); - adaptor.dispose(); - cleanUpSources(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void cleanUpSources() { - if (exportViewer != null) { - if (exportViewer.getControl() != null) { - getDisplay().syncExec(new Runnable() { - public void run() { - exportViewer.getControl().dispose(); - } - }); - } - exportViewer = null; - } - if (compositeProvider instanceof GhostShellProvider) { - getDisplay().syncExec(new Runnable() { - public void run() { - ((GhostShellProvider) compositeProvider).dispose(); - } - }); - compositeProvider = null; - } - } - - @Override - public boolean canStart() { - return true; - } - - private SheetFigure getSheetFigure() { - return (SheetFigure) viewer.findGraphicalPart(sheet).getContentPane(); - } - - private void setTranslate(GraphicsToGraphics2DAdaptor graphicsAdaptor) { - Rectangle extent = getSheetFigure().getFreeformExtent(); - int translateX = DEFAULT_MARGIN - extent.x; - int translateY = DEFAULT_MARGIN - extent.y; - - graphicsAdaptor.translate(translateX, translateY); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.exports.vector.svg; + +import static org.xmind.gef.IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH; + +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.de.erichseifert.vectorgraphics2d.SVGGraphics2D; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.util.Properties; +import org.xmind.ui.exports.vector.graphics.GraphicsToGraphics2DAdaptor; +import org.xmind.ui.internal.figures.SheetFigure; +import org.xmind.ui.mindmap.GhostShellProvider; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.MindMapExportViewer; +import org.xmind.ui.viewers.ICompositeProvider; +import org.xmind.ui.wizards.ExportContants; +import org.xmind.ui.wizards.Exporter; +import org.xmind.ui.wizards.IExportPart; + +/** + * @author Jason Wong + */ +public class SVGExporter extends Exporter { + + private static final int DEFAULT_MARGIN = 15; + + private ISheet sheet; + + private String targetPath; + + private IGraphicalViewer viewer; + + private IGraphicalViewer exportViewer; + + private ICompositeProvider compositeProvider; + + private Rectangle bounds; + + private SVGGraphics2D svgGenerator; + + private GraphicsToGraphics2DAdaptor adaptor; + + private IDialogSettings settings; + + public SVGExporter(ISheet sheet, ITopic centralTopic, String targetPath, + IGraphicalViewer viewer, IDialogSettings settings) { + super(sheet, centralTopic); + this.sheet = sheet; + this.targetPath = targetPath; + this.viewer = viewer; + this.settings = settings; + } + + public void init() { + bounds = getFigureBounds(); + svgGenerator = new SVGGraphics2D(0, 0, bounds.width, bounds.height); + } + + private Rectangle getFigureBounds() { + Rectangle extent = getSheetFigure().getFreeformExtent(); + return new Rectangle(0, 0, extent.width + DEFAULT_MARGIN * 2, + extent.height + DEFAULT_MARGIN * 2); + } + + @Override + public void start(final Display display, Shell shell) + throws InvocationTargetException { + super.start(display, shell); + + adaptor = new GraphicsToGraphics2DAdaptor(svgGenerator, bounds, + display); + setTranslate(adaptor); + compositeProvider = new GhostShellProvider(display); + + display.syncExec(new Runnable() { + + public void run() { + exportViewer = new MindMapExportViewer(compositeProvider, + viewer.getAdapter(IMindMap.class), + viewer.getProperties()); + Properties properties = exportViewer.getProperties(); + initProperties(properties); + + exportViewer.getCanvas().getLightweightSystem() + .getUpdateManager().performValidation(); + exportViewer.getLayer(GEF.LAYER_BACKGROUND).paint(adaptor); + exportViewer.getLayer(GEF.LAYER_CONTENTS).paint(adaptor); + } + }); + } + + protected void initProperties(Properties properties) { + //set plus minus visibility + boolean plusVisible = getBoolean(settings, ExportContants.PLUS_VISIBLE, + ExportContants.DEFAULT_PLUS_VISIBLE); + boolean minusVisible = getBoolean(settings, + ExportContants.MINUS_VISIBLE, + ExportContants.DEFAULT_MINUS_VISIBLE); + properties.set(IMindMapViewer.PLUS_VISIBLE, plusVisible); + properties.set(IMindMapViewer.MINUS_VISIBLE, minusVisible); + + if (Platform.OS_LINUX.equals(Platform.getOS())) { + properties.set(VIEWER_RENDER_TEXT_AS_PATH, false); + } else { + properties.set(VIEWER_RENDER_TEXT_AS_PATH, true); + } + } + + private boolean getBoolean(IDialogSettings settings, String key, + boolean defaultValue) { + boolean value = defaultValue; + if (settings.get(key) != null) { + value = settings.getBoolean(key); + } + + return value; + } + + @Override + protected void write(IProgressMonitor monitor, IExportPart part) + throws InvocationTargetException, InterruptedException { + } + + @Override + public void end() throws InvocationTargetException { + try { + Writer out = new OutputStreamWriter( + new FileOutputStream(targetPath), "UTF-8"); //$NON-NLS-1$ + out.write(svgGenerator.toString()); + out.close(); + adaptor.dispose(); + cleanUpSources(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void cleanUpSources() { + if (exportViewer != null) { + if (exportViewer.getControl() != null) { + getDisplay().syncExec(new Runnable() { + public void run() { + exportViewer.getControl().dispose(); + } + }); + } + exportViewer = null; + } + if (compositeProvider instanceof GhostShellProvider) { + getDisplay().syncExec(new Runnable() { + public void run() { + ((GhostShellProvider) compositeProvider).dispose(); + } + }); + compositeProvider = null; + } + } + + @Override + public boolean canStart() { + return true; + } + + private SheetFigure getSheetFigure() { + return (SheetFigure) viewer.findGraphicalPart(sheet).getContentPane(); + } + + private void setTranslate(GraphicsToGraphics2DAdaptor graphicsAdaptor) { + Rectangle extent = getSheetFigure().getFreeformExtent(); + int translateX = DEFAULT_MARGIN - extent.x; + int translateY = DEFAULT_MARGIN - extent.y; + + graphicsAdaptor.translate(translateX, translateY); + } + +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SvgPlugin.java b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SvgPlugin.java index df282382f..5548b7e51 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SvgPlugin.java +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/SvgPlugin.java @@ -1,101 +1,101 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.exports.vector.svg; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; -import org.xmind.core.usagedata.IUsageDataSampler; - -/** - * @author Jason Wong - */ -public class SvgPlugin extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.ui.exports.vector.svg"; //$NON-NLS-1$ - - // The shared instance - private static SvgPlugin plugin; - - private ServiceTracker usageDataTracker; - - /** - * The constructor - */ - public SvgPlugin() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. - * BundleContext ) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - - usageDataTracker = new ServiceTracker(context, IUsageDataSampler.class, - null); - usageDataTracker.open(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. - * BundleContext ) - */ - public void stop(BundleContext context) throws Exception { - usageDataTracker.close(); - usageDataTracker = null; - - plugin = null; - super.stop(context); - } - - public IUsageDataSampler getUsageDataCollector() { - IUsageDataSampler service = usageDataTracker == null ? null : usageDataTracker.getService(); - return service == null ? IUsageDataSampler.NULL : service; - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static SvgPlugin getDefault() { - return plugin; - } - - public static IDialogSettings getDialogSettings(String sectionName) { - IDialogSettings ds = getDefault().getDialogSettings(); - if (sectionName == null) - return ds; - IDialogSettings section = ds.getSection(sectionName); - if (section == null) { - section = ds.addNewSection(sectionName); - } - return section; - } - - public static void log(Throwable e, String message) { - getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.exports.vector.svg; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; +import org.xmind.core.usagedata.IUsageDataSampler; + +/** + * @author Jason Wong + */ +public class SvgPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.ui.exports.vector.svg"; //$NON-NLS-1$ + + // The shared instance + private static SvgPlugin plugin; + + private ServiceTracker usageDataTracker; + + /** + * The constructor + */ + public SvgPlugin() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. + * BundleContext ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + usageDataTracker = new ServiceTracker(context, IUsageDataSampler.class, + null); + usageDataTracker.open(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. + * BundleContext ) + */ + public void stop(BundleContext context) throws Exception { + usageDataTracker.close(); + usageDataTracker = null; + + plugin = null; + super.stop(context); + } + + public IUsageDataSampler getUsageDataCollector() { + IUsageDataSampler service = usageDataTracker == null ? null : usageDataTracker.getService(); + return service == null ? IUsageDataSampler.NULL : service; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static SvgPlugin getDefault() { + return plugin; + } + + public static IDialogSettings getDialogSettings(String sectionName) { + IDialogSettings ds = getDefault().getDialogSettings(); + if (sectionName == null) + return ds; + IDialogSettings section = ds.getSection(sectionName); + if (section == null) { + section = ds.addNewSection(sectionName); + } + return section; + } + + public static void log(Throwable e, String message) { + getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + +} diff --git a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/messages.properties b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/messages.properties index d2cba1c83..5311c529b 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/messages.properties +++ b/bundles/org.xmind.ui.exports.vector.svg/src/org/xmind/ui/internal/exports/vector/svg/messages.properties @@ -1,11 +1,11 @@ -SVGWizard_WindowTitle=Export SVG -SVGWizard_FormatName=SVG -SVGPage_Title=Export SVG -SVGPage_Description=Generate SVG Image -SVGPage_FilterName=SVG (*.svg) -SVGExportJob_Name=Exporting to SVG -SVGExportWizard_showMinusCheck_text=Export Collapse Icon: -SVGExportWizard_showPlusCheck_text=Export Expand Icon: - -ExportPage_Launching= -ExportWizard_Collapse_Expand_text=Collapse && Expand Icons: +SVGWizard_WindowTitle=Export SVG +SVGWizard_FormatName=SVG +SVGPage_Title=Export SVG +SVGPage_Description=Generate SVG Image +SVGPage_FilterName=SVG (*.svg) +SVGExportJob_Name=Exporting to SVG +SVGExportWizard_showMinusCheck_text=Export Collapse Icon: +SVGExportWizard_showPlusCheck_text=Export Expand Icon: + +ExportPage_Launching= +ExportWizard_Collapse_Expand_text=Collapse && Expand Icons: diff --git a/bundles/org.xmind.ui.exports.vector/.classpath b/bundles/org.xmind.ui.exports.vector/.classpath index 861dce6eb..d804c65b3 100644 --- a/bundles/org.xmind.ui.exports.vector/.classpath +++ b/bundles/org.xmind.ui.exports.vector/.classpath @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.exports.vector/.gitignore b/bundles/org.xmind.ui.exports.vector/.gitignore index 2caedc74c..e978127ff 100644 --- a/bundles/org.xmind.ui.exports.vector/.gitignore +++ b/bundles/org.xmind.ui.exports.vector/.gitignore @@ -1,16 +1,16 @@ -.metadata -bin/** -tmp/** -tmp/**/* -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folders containing Maven build results -target/ +.metadata +bin/** +tmp/** +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folders containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.exports.vector/.project b/bundles/org.xmind.ui.exports.vector/.project index 9d31b2bb7..1119fd125 100644 --- a/bundles/org.xmind.ui.exports.vector/.project +++ b/bundles/org.xmind.ui.exports.vector/.project @@ -1,28 +1,28 @@ - - - org.xmind.ui.exports.vector - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.ui.exports.vector + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.core.prefs index a63f9374d..47d8b7758 100644 --- a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.core.prefs @@ -1,411 +1,411 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.ui.prefs index 082f3415f..9ee76f471 100644 --- a/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.exports.vector/.settings/org.eclipse.jdt.ui.prefs @@ -1,62 +1,62 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF index 8a251b600..ae11c8ca1 100644 --- a/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF @@ -1,15 +1,15 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.exports.vector;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.exports.vector.VectorPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.xmind.ui;bundle-version="[3.7.0,3.8.0)" -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Bundle-Localization: plugin -Bundle-ClassPath: . -Export-Package: org.xmind.ui.exports.vector.graphics +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.exports.vector;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.exports.vector.VectorPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.xmind.ui;bundle-version="[3.7.0,3.8.0)" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin +Bundle-ClassPath: . +Export-Package: org.xmind.ui.exports.vector.graphics diff --git a/bundles/org.xmind.ui.exports.vector/about.html b/bundles/org.xmind.ui.exports.vector/about.html index be8519f05..ff9083efa 100644 --- a/bundles/org.xmind.ui.exports.vector/about.html +++ b/bundles/org.xmind.ui.exports.vector/about.html @@ -1,19 +1,19 @@ - - - - -About - - -

    About This Content

    - -

    Jun 27, 2012

    - -

    -XMind Plus/Pro release under the terms of the XMIND PROPRIETARY LICENSE AGREEMENT. -

    - - - + + + + +About + + +

    About This Content

    + +

    Jun 27, 2012

    + +

    +XMind Plus/Pro release under the terms of the XMIND PROPRIETARY LICENSE AGREEMENT. +

    + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.exports.vector/build.properties b/bundles/org.xmind.ui.exports.vector/build.properties index 1b08f841b..cdd2db7f1 100644 --- a/bundles/org.xmind.ui.exports.vector/build.properties +++ b/bundles/org.xmind.ui.exports.vector/build.properties @@ -1,7 +1,7 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html,\ - plugin.properties -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + plugin.properties +src.includes = about.html diff --git a/bundles/org.xmind.ui.exports.vector/plugin.properties b/bundles/org.xmind.ui.exports.vector/plugin.properties index 5f249d68e..f7a3aa39e 100644 --- a/bundles/org.xmind.ui.exports.vector/plugin.properties +++ b/bundles/org.xmind.ui.exports.vector/plugin.properties @@ -1,3 +1,3 @@ -#Properties file for org.xmind.ui.exports.vector -providerName = XMind Ltd. +#Properties file for org.xmind.ui.exports.vector +providerName = XMind Ltd. pluginName = XMind Export Support For Vector Graphics \ No newline at end of file diff --git a/bundles/org.xmind.ui.exports.vector/pom.xml b/bundles/org.xmind.ui.exports.vector/pom.xml index 363074f51..b6304ca01 100644 --- a/bundles/org.xmind.ui.exports.vector/pom.xml +++ b/bundles/org.xmind.ui.exports.vector/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.exports.vector - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.exports.vector + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/VectorPlugin.java b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/VectorPlugin.java index 96261326d..c36a5028b 100644 --- a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/VectorPlugin.java +++ b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/VectorPlugin.java @@ -1,88 +1,88 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.exports.vector; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -/** - * @author Jason Wong - */ -public class VectorPlugin extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.ui.exports.vector"; //$NON-NLS-1$ - - // The shared instance - private static VectorPlugin plugin; - - /** - * The constructor - */ - public VectorPlugin() { - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext - * ) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext - * ) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static VectorPlugin getDefault() { - return plugin; - } - - public static IDialogSettings getDialogSettings(String sectionName) { - IDialogSettings ds = getDefault().getDialogSettings(); - if (sectionName == null) - return ds; - IDialogSettings section = ds.getSection(sectionName); - if (section == null) { - section = ds.addNewSection(sectionName); - } - return section; - } - - public static void log(Throwable e, String message) { - getDefault().getLog().log( - new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.exports.vector; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * @author Jason Wong + */ +public class VectorPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.ui.exports.vector"; //$NON-NLS-1$ + + // The shared instance + private static VectorPlugin plugin; + + /** + * The constructor + */ + public VectorPlugin() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static VectorPlugin getDefault() { + return plugin; + } + + public static IDialogSettings getDialogSettings(String sectionName) { + IDialogSettings ds = getDefault().getDialogSettings(); + if (sectionName == null) + return ds; + IDialogSettings section = ds.getSection(sectionName); + if (section == null) { + section = ds.addNewSection(sectionName); + } + return section; + } + + public static void log(Throwable e, String message) { + getDefault().getLog().log( + new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + +} diff --git a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GdiFont.java b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GdiFont.java index 5bce0cbd4..a5b657287 100644 --- a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GdiFont.java +++ b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GdiFont.java @@ -1,111 +1,111 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.exports.vector.graphics; - -import java.awt.Font; - -/** - * @author Jason Wong - * - */ -public class GdiFont { - private int m_height = 12; - private boolean m_bItalic = false; - private boolean m_bUnderlined = false; - private boolean m_bBold = false; - private boolean m_bStrikeout = false; - private String m_faceName = "SanSerif"; //$NON-NLS-1$ - - private int m_escapement = 0; - - /** - * Creates a default font. - */ - public GdiFont() { - // Nothing to initialize. - } - - /** - * Copy constructor - * - * @param font - */ - GdiFont(GdiFont font) { - m_height = font.m_height; - m_bItalic = font.m_bItalic; - m_bBold = font.m_bBold; - m_faceName = font.m_faceName; - m_bUnderlined = font.m_bUnderlined; - m_escapement = font.m_escapement; - m_bStrikeout = font.m_bStrikeout; - } - - /** - * Creates a font with the specified parameters. - * - * @param height - * Height of the font - * @param bItalic - * Whether or not the font is italic - * @param bUnderlined - * Whether or not the font is underlined - * @param bStrikeout - * Whether or not the font is a strikout font - * @param bBold - * Whether or not the font is bold - * @param faceName - * Name of the font - * @param escapement - * Font escapement (angle) of the text to be drawn. - */ - public GdiFont(int height, boolean bItalic, boolean bUnderlined, - boolean bStrikeout, boolean bBold, String faceName, int escapement) { - m_height = height; - m_bItalic = bItalic; - m_bBold = bBold; - m_faceName = faceName; - m_bUnderlined = bUnderlined; - m_escapement = escapement; - m_bStrikeout = bStrikeout; - } - - /** - * @return The Java font object that represents most of the attributes for - * drawing the font. - */ - public Font getFont() { - int style = Font.PLAIN; - - if (m_bItalic) { - style = Font.ITALIC; - } - - if (m_bBold) { - style = Font.BOLD; - } - - if (m_bItalic && m_bBold) { - style = Font.ITALIC + Font.BOLD; - } - - return new Font(m_faceName, style, m_height); - } - - /** - * @return The angle at which to draw the font. - */ - public int getEscapement() { - return m_escapement; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.exports.vector.graphics; + +import java.awt.Font; + +/** + * @author Jason Wong + * + */ +public class GdiFont { + private int m_height = 12; + private boolean m_bItalic = false; + private boolean m_bUnderlined = false; + private boolean m_bBold = false; + private boolean m_bStrikeout = false; + private String m_faceName = "SanSerif"; //$NON-NLS-1$ + + private int m_escapement = 0; + + /** + * Creates a default font. + */ + public GdiFont() { + // Nothing to initialize. + } + + /** + * Copy constructor + * + * @param font + */ + GdiFont(GdiFont font) { + m_height = font.m_height; + m_bItalic = font.m_bItalic; + m_bBold = font.m_bBold; + m_faceName = font.m_faceName; + m_bUnderlined = font.m_bUnderlined; + m_escapement = font.m_escapement; + m_bStrikeout = font.m_bStrikeout; + } + + /** + * Creates a font with the specified parameters. + * + * @param height + * Height of the font + * @param bItalic + * Whether or not the font is italic + * @param bUnderlined + * Whether or not the font is underlined + * @param bStrikeout + * Whether or not the font is a strikout font + * @param bBold + * Whether or not the font is bold + * @param faceName + * Name of the font + * @param escapement + * Font escapement (angle) of the text to be drawn. + */ + public GdiFont(int height, boolean bItalic, boolean bUnderlined, + boolean bStrikeout, boolean bBold, String faceName, int escapement) { + m_height = height; + m_bItalic = bItalic; + m_bBold = bBold; + m_faceName = faceName; + m_bUnderlined = bUnderlined; + m_escapement = escapement; + m_bStrikeout = bStrikeout; + } + + /** + * @return The Java font object that represents most of the attributes for + * drawing the font. + */ + public Font getFont() { + int style = Font.PLAIN; + + if (m_bItalic) { + style = Font.ITALIC; + } + + if (m_bBold) { + style = Font.BOLD; + } + + if (m_bItalic && m_bBold) { + style = Font.ITALIC + Font.BOLD; + } + + return new Font(m_faceName, style, m_height); + } + + /** + * @return The angle at which to draw the font. + */ + public int getEscapement() { + return m_escapement; + } +} diff --git a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GraphicsToGraphics2DAdaptor.java b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GraphicsToGraphics2DAdaptor.java index 2083c8b90..be2626a46 100644 --- a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GraphicsToGraphics2DAdaptor.java +++ b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/GraphicsToGraphics2DAdaptor.java @@ -1,1715 +1,1715 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.exports.vector.graphics; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Composite; -import java.awt.GradientPaint; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.Polygon; -import java.awt.RenderingHints; -import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.util.Stack; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.SWTGraphics; -import org.eclipse.draw2d.TextUtilities; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.PointList; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.LineAttributes; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.PathData; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.graphics.GradientPattern; - -/** - * @author Jason Wong - */ -public class GraphicsToGraphics2DAdaptor extends Graphics { - private static class State { - - public int translateX = 0; - - public int translateY = 0; - - /** - * clipping rectangle x coordinate - */ - public int clipX = 0; - /** - * clipping rectangle y coordinate - */ - public int clipY = 0; - /** - * clipping rectangle width - */ - public int clipW = 0; - /** - * clipping rectangle height - */ - public int clipH = 0; - - /** Font value **/ - /** - * cached font - */ - public Font font; - - /** - * cached xor mode value - */ - public boolean XorMode = false; - /** - * cached foreground color - */ - public Color fgColor; - /** - * cached background color - */ - public Color bgColor; - /** - * cached foreground color - */ - public Pattern fgPattern; - /** - * cached background pattern - */ - public Pattern bgPattern; - - /** - * cached alpha value - */ - public int alpha; - - /** - * Line attributes value - */ - public LineAttributes lineAttributes = new LineAttributes(1); - - int graphicHints; - - /** - * Copy the values from a given state to this state - * - * @param state - * the state to copy from - */ - public void copyFrom(State state) { - translateX = state.translateX; - translateY = state.translateY; - - clipX = state.clipX; - clipY = state.clipY; - clipW = state.clipW; - clipH = state.clipH; - - font = state.font; - fgColor = state.fgColor; - bgColor = state.bgColor; - - bgPattern = state.bgPattern; - fgPattern = state.fgPattern; - - XorMode = state.XorMode; - alpha = state.alpha; - graphicHints = state.graphicHints; - - lineAttributes = SWTGraphics.clone(state.lineAttributes); - } - } - - static final int ADVANCED_GRAPHICS_MASK; - static final int ADVANCED_SHIFT; - static final int FILL_RULE_MASK; - static final int FILL_RULE_SHIFT; - static final int FILL_RULE_WHOLE_NUMBER = -1; - - /* - * It's consistent with SWTGraphics flags in case some other flags from - * SWTGraphics need to be here - */ - static { - FILL_RULE_SHIFT = 14; - ADVANCED_SHIFT = 15; - FILL_RULE_MASK = 1 << FILL_RULE_SHIFT; // If changed to more than 1-bit, - // check references! - ADVANCED_GRAPHICS_MASK = 1 << ADVANCED_SHIFT; - } - - private SWTGraphics swtGraphics; - private Graphics2D graphics2D; - private BasicStroke stroke; - private Stack states = new Stack(); - private final State currentState = new State(); - private final State appliedState = new State(); - - /** - * Some strings, Asian string in particular, are painted differently between - * SWT and AWT. SWT falls back to some default locale font if Asian string - * cannot be painted with the current font - this is done via the platform. - * AWT, unlike platform biased SWT, does not. Hence, Asian string widths are - * very different between SWT and AWT. To workaround the issue, if the flag - * below is set to true then once SWT and AWT string width are - * not equal, a bitmap of the SWT string will be painted. Otherwise the - * string is always painted with AWT Graphics 2D string rendering. - */ - protected boolean paintNotCompatibleStringsAsBitmaps = true; - - @SuppressWarnings("unused") - private static final TextUtilities TEXT_UTILITIES = new TextUtilities(); - - private Rectangle relativeClipRegion; - - private org.eclipse.swt.graphics.Rectangle viewBox; - private Image image; - - /** - * x coordinate for graphics translation - */ - private int transX = 0; - /** - * y coordinate for graphics translation - */ - private int transY = 0; - - /** - * current rotation angle - */ - private float angle; - /** - * The x coordinate of the rotation point - */ - private int rotateX; - /** - * The y coordinate of the rotation point - */ - private int rotateY; - - /** - * horizontal scale - */ - private float horizontalScale = 1.0f; - - /** - * vertical scale - */ - private float verticalScale = 1.0f; - - /** - * Constructor - * - * @param graphics - * the Graphics2D object that this object is - * delegating calls to. - * @param viewPort - * the Rectangle that defines the logical area being - * rendered by the graphics object. - */ - public GraphicsToGraphics2DAdaptor(Graphics2D graphics, Rectangle viewPort, - Display display) { - this(graphics, new org.eclipse.swt.graphics.Rectangle(viewPort.x, - viewPort.y, viewPort.width, viewPort.height), display); - } - - private Display display; - - private static int rotateOrientation = 0; - - /** - * Alternate Constructor that takes an swt Rectangle - * - * @param graphics - * the Graphics2D object that this object is - * delegating calls to. - * @param viewPort - * the org.eclipse.swt.graphics.Rectangle that - * defines the logical area being rendered by the graphics - * object. - */ - public GraphicsToGraphics2DAdaptor(Graphics2D graphics, - org.eclipse.swt.graphics.Rectangle viewPort, Display display) { - - this.display = display; - - // Save the ViewPort to add to the root DOM element - viewBox = viewPort; - - // Create the SWT Graphics Object - createSWTGraphics(); - - // Initialize the SVG Graphics Object - initSVGGraphics(graphics); - - // Initialize the States - init(); - } - - /** - * This is a helper method used to create the SWT Graphics object - */ - private void createSWTGraphics() { - - // we need this temp Rect just to instantiate an swt image in order to - // keep - // state, the size of this Rect is of no consequence and we just set it - // to - // such a small size in order to minimize memory allocation - org.eclipse.swt.graphics.Rectangle tempRect = new org.eclipse.swt.graphics.Rectangle( - 0, 0, 10, 10); - image = new Image(display, tempRect); - GC gc = new GC(image); - swtGraphics = new SWTGraphics(gc); - } - - /** - * Create the SVG graphics object and initializes it with the current line - * style and width - */ - private void initSVGGraphics(Graphics2D graphics) { - this.graphics2D = graphics; - - relativeClipRegion = new Rectangle(viewBox.x, viewBox.y, viewBox.width, - viewBox.height); - - // Initialize the line style and width - stroke = new BasicStroke(swtGraphics.getLineWidth(), - BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 0, null, 0); - LineAttributes lineAttributes = new LineAttributes(1); - swtGraphics.getLineAttributes(lineAttributes); - setLineAttributes(lineAttributes); - setFillRule(swtGraphics.getFillRule()); - setAdvanced(swtGraphics.getAdvanced()); - getGraphics2D().setStroke(stroke); - } - - /** - * This method should only be called by the constructor. Initializes state - * information for the currentState - */ - private void init() { - - // Initialize drawing styles - setForegroundColor(getForegroundColor()); - setBackgroundColor(getBackgroundColor()); - setXORMode(getXORMode()); - - // Initialize Font - setFont(getFont()); - currentState.font = appliedState.font = getFont(); - - // Initialize translations - currentState.translateX = appliedState.translateX = transX; - currentState.translateY = appliedState.translateY = transY; - - // Initialize Clip Regions - currentState.clipX = appliedState.clipX = relativeClipRegion.x; - currentState.clipY = appliedState.clipY = relativeClipRegion.y; - currentState.clipW = appliedState.clipW = relativeClipRegion.width; - currentState.clipH = appliedState.clipH = relativeClipRegion.height; - - currentState.alpha = appliedState.alpha = getAlpha(); - } - - /** - * Verifies that the applied state is up to date with the current state and - * updates the applied state accordingly. - */ - protected void checkState() { - if (appliedState.font != currentState.font) { - appliedState.font = currentState.font; - - setFont(currentState.font); - } - - if (appliedState.clipX != currentState.clipX - || appliedState.clipY != currentState.clipY - || appliedState.clipW != currentState.clipW - || appliedState.clipH != currentState.clipH) { - - appliedState.clipX = currentState.clipX; - appliedState.clipY = currentState.clipY; - appliedState.clipW = currentState.clipW; - appliedState.clipH = currentState.clipH; - - if (rotateOrientation != 0) { - if (currentState.bgColor.equals(currentState.fgColor)) { - double p = Math.pow(currentState.clipW, 2) - + Math.pow(currentState.clipH, 2); - int newWidth = Math.round((float) Math.sqrt(p)); - currentState.clipX = currentState.clipX - - (newWidth - currentState.clipW) / 2; - currentState.clipW = newWidth; - } - } - - // Adjust the clip for SVG - getGraphics2D().setClip(currentState.clipX - 1, - currentState.clipY - 1, currentState.clipW + 2, - currentState.clipH + 2); - } - - if (appliedState.alpha != currentState.alpha) { - appliedState.alpha = currentState.alpha; - - setAlpha(currentState.alpha); - } - - appliedState.graphicHints = currentState.graphicHints; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#clipRect(org.eclipse.draw2d.geometry. - * Rectangle ) - */ - @Override - public void clipRect(Rectangle rect) { - relativeClipRegion.intersect(rect); - setClipAbsolute(relativeClipRegion.x + transX, - relativeClipRegion.y + transY, relativeClipRegion.width, - relativeClipRegion.height); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#dispose() - */ - @Override - public void dispose() { - rotateOrientation = 0; - swtGraphics.dispose(); - - if (image != null) { - image.dispose(); - } - - states.clear(); - } - - /** - * This method is used to convert an SWT Color to an AWT Color. - * - * @param toConvert - * SWT Color to convert - * @return AWT Color - */ - protected java.awt.Color getColor(Color toConvert) { - - return new java.awt.Color(toConvert.getRed(), toConvert.getGreen(), - toConvert.getBlue(), getAlpha()); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawArc(int, int, int, int, int, int) - */ - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, - int endAngle) { - - Arc2D arc = new Arc2D.Float(x + transX, y + transY, width - 1, height, - startAngle, endAngle, Arc2D.OPEN); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(arc); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillArc(int, int, int, int, int, int) - */ - @Override - public void fillArc(int x, int y, int w, int h, int offset, int length) { - - Arc2D arc = new Arc2D.Float(x + transX, y + transY, w, h, offset, - length, Arc2D.OPEN); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); - getGraphics2D().fill(arc); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawFocus(int, int, int, int) - */ - @Override - public void drawFocus(int x, int y, int w, int h) { - drawRectangle(x, y, w, h); - } - - @Override - public void drawTextLayout(TextLayout layout, int x, int y, - int selectionStart, int selectionEnd, Color selectionForeground, - Color selectionBackground) { - checkState(); - if (!layout.getBounds().isEmpty()) { - Image image = new Image(display, layout.getBounds().width, - layout.getBounds().height); - GC gc = new GC(image); - cloneGC(gc); - layout.draw(gc, 0, 0, selectionStart, selectionEnd, - selectionForeground, selectionBackground); - - ImageData imageData = image.getImageData(); - imageData.transparentPixel = imageData.palette - .getPixel(getBackgroundColor().getRGB()); - - gc.dispose(); - image.dispose(); - - getGraphics2D().drawImage( - ImageConverter.convertFromImageData(imageData), x + transX, - y + transY, null); - } - } - - private void cloneGC(GC gc) { - gc.setAdvanced(getAdvanced()); - gc.setAlpha(getAlpha()); - gc.setAntialias(getAntialias()); - gc.setFillRule(getFillRule()); - gc.setFont(getFont()); - gc.setInterpolation(getInterpolation()); - gc.setLineAttributes(getLineAttributes()); - gc.setTextAntialias(getTextAntialias()); - gc.setBackground(getBackgroundColor()); - gc.setForeground(getForegroundColor()); - } - - @Override - public int getInterpolation() { - return swtGraphics.getInterpolation(); - } - - @Override - public LineAttributes getLineAttributes() { - LineAttributes la = new LineAttributes(1); - swtGraphics.getLineAttributes(la); - return la; - } - - @Override - public int getTextAntialias() { - return swtGraphics.getTextAntialias(); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, - * int, int) - */ - @Override - public void drawImage(Image srcImage, int xpos, int ypos) { - - // Translate the Coordinates - xpos += transX; - ypos += transY; - - // Convert the SWT Image into an AWT BufferedImage - BufferedImage toDraw = ImageConverter.convert(srcImage); - - checkState(); - getGraphics2D().drawImage(toDraw, - new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos), null); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, - * int, int, int, int, int, int, int, int) - */ - @Override - public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) { - - x2 += transX; - y2 += transY; - - BufferedImage toDraw = ImageConverter.convert(srcImage); - checkState(); - getGraphics2D().drawImage(toDraw, x2, y2, w2, h2, null); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawLine(int, int, int, int) - */ - @Override - public void drawLine(int x1, int y1, int x2, int y2) { - - Line2D line = new Line2D.Float(x1 + transX, y1 + transY, x2 + transX, - y2 + transY); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(line); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawOval(int, int, int, int) - */ - @Override - public void drawOval(int x, int y, int w, int h) { - - Ellipse2D ellipse = new Ellipse2D.Float(x + transX, y + transY, w, h); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(ellipse); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillOval(int, int, int, int) - */ - @Override - public void fillOval(int x, int y, int w, int h) { - - Ellipse2D ellipse = new Ellipse2D.Float(x + transX, y + transY, w - 1, - h - 1); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); - getGraphics2D().fill(ellipse); - } - - private Polygon createPolygon(PointList pointList) { - - Polygon toCreate = new Polygon(); - - for (int i = 0; i < pointList.size(); i++) { - Point pt = pointList.getPoint(i); - - toCreate.addPoint(pt.x + transX, pt.y + transY); - } - - return toCreate; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawPolygon(org.eclipse.draw2d.geometry. - * PointList ) - */ - @Override - public void drawPolygon(PointList pointList) { - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(createPolygon(pointList)); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillPolygon(org.eclipse.draw2d.geometry. - * PointList ) - */ - @Override - public void fillPolygon(PointList pointList) { - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); - getGraphics2D().fill(createPolygon(pointList)); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#drawPolyline(org.eclipse.draw2d.geometry. - * PointList) - */ - @Override - public void drawPolyline(PointList pointList) { - - // Draw polylines as a series of lines - for (int x = 1; x < pointList.size(); x++) { - - Point p1 = pointList.getPoint(x - 1); - Point p2 = pointList.getPoint(x); - - drawLine(p1.x, p1.y, p2.x, p2.y); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawRectangle(int, int, int, int) - */ - @Override - public void drawRectangle(int x, int y, int w, int h) { - Rectangle2D rect = new Rectangle2D.Float(x + transX, y + transY, w, h); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(rect); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillRectangle(int, int, int, int) - */ - @Override - public void fillRectangle(int x, int y, int width, int height) { - - Rectangle2D rect = new Rectangle2D.Float(x + transX, y + transY, width, - height); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); - getGraphics2D().fill(rect); - } - - public void fillRectangle(int width, int height, Color bgColor) { - Rectangle2D rect = new Rectangle2D.Float(0, 0, width, height); - checkState(); - getGraphics2D().setPaint(getColor(bgColor)); - getGraphics2D().fill(rect); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawRoundRectangle(org.eclipse.draw2d. - * geometry .Rectangle, int, int) - */ - @Override - public void drawRoundRectangle(Rectangle rect, int arcWidth, - int arcHeight) { - - RoundRectangle2D roundRect = new RoundRectangle2D.Float(rect.x + transX, - rect.y + transY, rect.width, rect.height, arcWidth, arcHeight); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(roundRect); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillRoundRectangle(org.eclipse.draw2d. - * geometry .Rectangle, int, int) - */ - @Override - public void fillRoundRectangle(Rectangle rect, int arcWidth, - int arcHeight) { - - RoundRectangle2D roundRect = new RoundRectangle2D.Float(rect.x + transX, - rect.y + transY, rect.width, rect.height, arcWidth, arcHeight); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); - getGraphics2D().fill(roundRect); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawText(java.lang.String, int, int) - */ - @Override - public void drawText(String s, int x, int y) { - drawString(s, x, y); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawString(java.lang.String, int, int) - */ - - // private static Dimension swtStringSize; - - @Override - public void drawString(String s, int x, int y) { - if (s == null) - return; - java.awt.FontMetrics metrics = getGraphics2D().getFontMetrics(); - int stringLength = metrics.stringWidth(s); - // if (!this.display.isDisposed()) { - // Runnable runnable = new Runnable() { - // public void run() { - // swtStringSize = TEXT_UTILITIES.getStringExtents(str, - // swtGraphics.getFont()); - // } - // }; - // display.syncExec(runnable); - // } - - float xpos = x + transX; - float ypos = y + transY; - int lineWidth; - - // if (paintNotCompatibleStringsAsBitmaps - // && Math.abs(swtStringSize.width - stringLength) > 2) { - // // create SWT bitmap of the string then - // Image image = new Image(display, swtStringSize.width + 1, - // swtStringSize.height + 1); - // GC gc = new GC(image); - // gc.setForeground(getForegroundColor()); - // gc.setBackground(getBackgroundColor()); - // gc.setAntialias(getAntialias()); - // gc.setFont(getFont()); - // gc.drawString(s, 0, 0); - // gc.dispose(); - // ImageData data = image.getImageData(); - // image.dispose(); - // RGB backgroundRGB = getBackgroundColor().getRGB(); - // for (int i = 0; i < data.width; i++) { - // for (int j = 0; j < data.height; j++) { - // if (data.palette.getRGB(data.getPixel(i, j)).equals( - // backgroundRGB)) { - // data.setAlpha(i, j, 0); - // } else { - // data.setAlpha(i, j, 255); - // } - // } - // } - // getGraphics2D().drawImage( - // ImageConverter.convertFromImageData(data), - // new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos), null); - // stringLength = swtStringSize.width; - // } else { - - ypos += metrics.getAscent(); - - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().drawString(s, xpos, ypos); - if (Platform.OS_LINUX.equals(Platform.getOS())) - swtGraphics.drawString(s, (int) xpos, (int) ypos); - // } - - if (isFontUnderlined(getFont())) { - int baseline = y + metrics.getAscent(); - lineWidth = getLineWidth(); - - setLineWidth(1); - drawLine(x, baseline, x + stringLength, baseline); - setLineWidth(lineWidth); - } - - if (isFontStrikeout(getFont())) { - int strikeline = y + (metrics.getHeight() / 2); - lineWidth = getLineWidth(); - - setLineWidth(1); - drawLine(x, strikeline, x + stringLength, strikeline); - setLineWidth(lineWidth); - } - - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillString(java.lang.String, int, int) - */ - @Override - public void fillString(String s, int x, int y) { - // Not implemented - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillText(java.lang.String, int, int) - */ - @Override - public void fillText(String s, int x, int y) { - // Not implemented - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getBackgroundColor() - */ - @Override - public Color getBackgroundColor() { - return swtGraphics.getBackgroundColor(); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#getClip(org.eclipse.draw2d.geometry.Rectangle - * ) - */ - @Override - public Rectangle getClip(Rectangle rect) { - rect.setBounds(relativeClipRegion); - return rect; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getFont() - */ - @Override - public Font getFont() { - return swtGraphics.getFont(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getFontMetrics() - */ - @Override - public FontMetrics getFontMetrics() { - return swtGraphics.getFontMetrics(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getForegroundColor() - */ - @Override - public Color getForegroundColor() { - return swtGraphics.getForegroundColor(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getLineStyle() - */ - @Override - public int getLineStyle() { - return swtGraphics.getLineStyle(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getLineWidth() - */ - @Override - public int getLineWidth() { - return swtGraphics.getLineWidth(); - } - - @Override - public float getLineWidthFloat() { - return swtGraphics.getLineWidthFloat(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getXORMode() - */ - @Override - public boolean getXORMode() { - return swtGraphics.getXORMode(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#popState() - */ - @Override - public void popState() { - swtGraphics.popState(); - - restoreState(states.pop()); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#pushState() - */ - @Override - public void pushState() { - swtGraphics.pushState(); - if (angle != 0) { - getGraphics2D().rotate(Math.toRadians(360 - angle), rotateX, - rotateY); - angle = 0; - } - - // Make a copy of the current state and push it onto the stack - State toPush = new State(); - toPush.copyFrom(currentState); - states.push(toPush); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#restoreState() - */ - @Override - public void restoreState() { - swtGraphics.restoreState(); - - restoreState(states.peek()); - } - - private void restoreState(State state) { - - setBackgroundColor(state.bgColor); - setForegroundColor(state.fgColor); - - setBackgroundPattern(state.bgPattern); - setForegroundPattern(state.fgPattern); - - setLineAttributes(state.lineAttributes); - setXORMode(state.XorMode); - - setClipAbsolute(state.clipX, state.clipY, state.clipW, state.clipH); - - transX = currentState.translateX = state.translateX; - transY = currentState.translateY = state.translateY; - - relativeClipRegion.x = state.clipX - transX; - relativeClipRegion.y = state.clipY - transY; - relativeClipRegion.width = state.clipW; - relativeClipRegion.height = state.clipH; - - currentState.font = state.font; - currentState.alpha = state.alpha; - - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#scale(double) - */ - @Override - public void scale(double amount) { - scale((float) amount, (float) amount); - } - - @Override - public void scale(float horizontal, float vertical) { - if (horizontal == -1 || vertical == -1) { - horizontalScale *= horizontal; - verticalScale *= vertical; - } else { - horizontalScale = horizontal; - verticalScale = vertical; - } - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#setBackgroundColor(org.eclipse.swt.graphics - * .Color) - */ - @Override - public void setBackgroundColor(Color rgb) { - currentState.bgColor = rgb; - swtGraphics.setBackgroundColor(rgb); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#setClip(org.eclipse.draw2d.geometry.Rectangle - * ) - */ - @Override - public void setClip(Rectangle rect) { - relativeClipRegion.x = rect.x; - relativeClipRegion.y = rect.y; - relativeClipRegion.width = rect.width; - relativeClipRegion.height = rect.height; - - setClipAbsolute(rect.x + transX, rect.y + transY, rect.width, - rect.height); - } - - /** - * Sets the current clip values - * - * @param x - * the x value - * @param y - * the y value - * @param width - * the width value - * @param height - * the height value - */ - private void setClipAbsolute(int x, int y, int width, int height) { - currentState.clipX = x; - currentState.clipY = y; - currentState.clipW = width; - currentState.clipH = height; - } - - private boolean isFontUnderlined(Font f) { - return false; - } - - private boolean isFontStrikeout(Font f) { - return false; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setFont(org.eclipse.swt.graphics.Font) - */ - @Override - public void setFont(Font f) { - swtGraphics.setFont(f); - currentState.font = f; - - FontData[] fontInfo = f.getFontData(); - - if (fontInfo[0] != null) { - - int height = fontInfo[0].getHeight(); - - // float fsize = height * (float) display.getDPI().x / 72.0f; - float fsize = height * 72.0f / 72.0f; - height = Math.round(fsize); - - int style = fontInfo[0].getStyle(); - boolean bItalic = (style & SWT.ITALIC) == SWT.ITALIC; - boolean bBold = (style & SWT.BOLD) == SWT.BOLD; - String faceName = fontInfo[0].getName(); - int escapement = 0; - - boolean bUnderline = isFontUnderlined(f); - boolean bStrikeout = isFontStrikeout(f); - - GdiFont font = new GdiFont(height, bItalic, bUnderline, bStrikeout, - bBold, faceName, escapement); - - getGraphics2D().setFont(font.getFont()); - } - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.draw2d.Graphics#setForegroundColor(org.eclipse.swt.graphics - * .Color) - */ - @Override - public void setForegroundColor(Color rgb) { - currentState.fgColor = rgb; - swtGraphics.setForegroundColor(rgb); - } - - /** - * Sets the dash pattern when the custom line style is in use. Because this - * feature is rarely used, the dash pattern may not be preserved when - * calling {@link #pushState()} and {@link #popState()}. - * - * @param dash - * the pixel pattern - */ - @Override - public void setLineDash(int[] dash) { - float dashFlt[] = new float[dash.length]; - for (int i = 0; i < dash.length; i++) { - dashFlt[i] = dash[i]; - } - setLineDash(dashFlt); - } - - @Override - public void setLineDash(float[] dash) { - currentState.lineAttributes.dash = dash; - setLineStyle(SWTGraphics.LINE_CUSTOM); - swtGraphics.setLineDash(dash); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setLineStyle(int) - */ - @Override - public void setLineStyle(int style) { - currentState.lineAttributes.style = style; - swtGraphics.setLineStyle(style); - } - - /** - * ignored - */ - @Override - public void setLineMiterLimit(float miterLimit) { - // do nothing - swtGraphics.setLineMiterLimit(miterLimit); - } - - /** - * ignored - */ - @Override - public void setLineCap(int cap) { - // do nothing - } - - /** - * ignored - */ - @Override - public void setLineJoin(int join) { - // do nothing - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setLineWidth(int) - */ - @Override - public void setLineWidth(int width) { - setLineWidthFloat(width); - } - - @Override - public void setLineWidthFloat(float width) { - currentState.lineAttributes.width = width; - swtGraphics.setLineWidthFloat(width); - } - - @Override - public void setLineAttributes(LineAttributes lineAttributes) { - SWTGraphics.copyLineAttributes(currentState.lineAttributes, - lineAttributes); - swtGraphics.setLineAttributes(lineAttributes); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setXORMode(boolean) - */ - @Override - public void setXORMode(boolean xorMode) { - currentState.XorMode = xorMode; - swtGraphics.setXORMode(xorMode); - } - - /** - * Sets the current translation values - * - * @param x - * the x translation value - * @param y - * the y translation value - */ - private void setTranslation(int x, int y) { - transX = currentState.translateX = x; - transY = currentState.translateY = y; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#translate(int, int) - */ - @Override - public void translate(int dx, int dy) { - swtGraphics.translate(dx, dy); - - setTranslation(transX + dx, transY + dy); - relativeClipRegion.x -= dx; - relativeClipRegion.y -= dy; - } - - @Override - public void translate(float dx, float dy) { - dx *= horizontalScale; - dy *= verticalScale; - swtGraphics.translate(dx, dy); - - setTranslation(transX + (int) dx, transY + (int) dy); - relativeClipRegion.x -= dx; - relativeClipRegion.y -= dy; - } - - /** - * @return the Graphics2D that this is delegating to. - */ - protected Graphics2D getGraphics2D() { - return graphics2D; - } - - /** - * @return Returns the swtGraphics. - */ - private SWTGraphics getSWTGraphics() { - return swtGraphics; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillGradient(int, int, int, int, - * boolean) - */ - @Override - public void fillGradient(int x, int y, int w, int h, boolean vertical) { - GradientPaint gradient; - - checkState(); - - // Gradients in SWT start with Foreground Color and end at Background - java.awt.Color start = getColor(getSWTGraphics().getForegroundColor()); - java.awt.Color stop = getColor(getSWTGraphics().getBackgroundColor()); - - // Create the Gradient based on horizontal or vertical - if (vertical) { - gradient = new GradientPaint(x + transX, y + transY, start, - x + transX, y + h + transY, stop); - } else { - gradient = new GradientPaint(x + transX, y + transY, start, - x + w + transX, y + transY, stop); - } - - Paint oldPaint = getGraphics2D().getPaint(); - getGraphics2D().setPaint(gradient); - getGraphics2D() - .fill(new Rectangle2D.Double(x + transX, y + transY, w, h)); - getGraphics2D().setPaint(oldPaint); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#drawPath(org.eclipse.swt.graphics.Path) - */ - @Override - public void drawPath(Path path) { - GeneralPath pathAWT = createPathAWT(path); - // getGraphics2D().draw(pathAWT); - checkState(); - getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); - getGraphics2D().setStroke(createStroke()); - getGraphics2D().draw(pathAWT); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#fillPath(org.eclipse.swt.graphics.Path) - */ - @Override - public void fillPath(Path path) { - checkState(); - if (currentState.bgPattern == null - || !(currentState.bgPattern instanceof GradientPattern)) { - getGraphics2D() - .setPaint(getColor(swtGraphics.getBackgroundColor())); - } else { - GradientPattern gp = (GradientPattern) currentState.bgPattern; - getGraphics2D().setPaint(getColor(gp.color2)); - } - getGraphics2D().fill(createPathAWT(path)); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setClip(org.eclipse.swt.graphics.Path) - */ - @Override - public void setClip(Path path) { - if (((appliedState.graphicHints ^ currentState.graphicHints) - & FILL_RULE_MASK) != 0) { - // If there is a pending change to the fill rule, apply it first. - // As long as the FILL_RULE is stored in a single bit, just toggling - // it works. - appliedState.graphicHints ^= FILL_RULE_MASK; - } - getGraphics2D().setClip(createPathAWT(path)); - appliedState.clipX = currentState.clipX = 0; - appliedState.clipY = currentState.clipY = 0; - appliedState.clipW = currentState.clipW = 0; - appliedState.clipH = currentState.clipH = 0; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getFillRule() - */ - @Override - public int getFillRule() { - return ((currentState.graphicHints & FILL_RULE_MASK) >> FILL_RULE_SHIFT) - - FILL_RULE_WHOLE_NUMBER; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setFillRule(int) - */ - @Override - public void setFillRule(int rule) { - currentState.graphicHints &= ~FILL_RULE_MASK; - currentState.graphicHints |= (rule - + FILL_RULE_WHOLE_NUMBER) << FILL_RULE_SHIFT; - } - - private GeneralPath createPathAWT(Path path) { - GeneralPath pathAWT = new GeneralPath(); - PathData pathData = path.getPathData(); - int idx = 0; - for (int i = 0; i < pathData.types.length; i++) { - switch (pathData.types[i]) { - case SWT.PATH_MOVE_TO: - pathAWT.moveTo( - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY); - break; - case SWT.PATH_LINE_TO: - pathAWT.lineTo( - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY); - break; - case SWT.PATH_CUBIC_TO: - pathAWT.curveTo( - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY, - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY, - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY); - break; - case SWT.PATH_QUAD_TO: - pathAWT.quadTo( - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY, - pathData.points[idx++] * horizontalScale + transX, - pathData.points[idx++] * verticalScale + transY); - break; - case SWT.PATH_CLOSE: - pathAWT.closePath(); - break; - default: - dispose(); - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - int swtWindingRule = ((appliedState.graphicHints - & FILL_RULE_MASK) >> FILL_RULE_SHIFT) - FILL_RULE_WHOLE_NUMBER; - if (swtWindingRule == SWT.FILL_WINDING) { - pathAWT.setWindingRule(GeneralPath.WIND_NON_ZERO); - } else if (swtWindingRule == SWT.FILL_EVEN_ODD) { - pathAWT.setWindingRule(GeneralPath.WIND_EVEN_ODD); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return pathAWT; - } - - /* - * (non-Javadoc) - * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal. - * DrawableRenderedImage #allowDelayRender() - */ - public boolean shouldAllowDelayRender() { - return false; - } - - /* - * (non-Javadoc) - * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal. - * DrawableRenderedImage #getMaximumRenderSize() - */ - public Dimension getMaximumRenderSize() { - return null; - } - - /** - * Accessor method to return the translation offset for the graphics object - * - * @return Point x coordinate for graphics translation - */ - protected Point getTranslationOffset() { - return new Point(transX, transY); - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#getAntialias() - */ - @Override - public int getAntialias() { - Object antiAlias = getGraphics2D() - .getRenderingHint(RenderingHints.KEY_ANTIALIASING); - if (antiAlias != null) { - if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_ON)) - return SWT.ON; - else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) - return SWT.OFF; - else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) - return SWT.DEFAULT; - } - - return SWT.DEFAULT; - } - - /* - * (non-Javadoc) - * @see org.eclipse.draw2d.Graphics#setAntialias(int) - */ - @Override - public void setAntialias(int value) { - if (value == SWT.ON) { - getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - } else if (value == SWT.OFF) { - getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF); - } - setAdvanced(true); - } - - @Override - public int getAlpha() { - return swtGraphics.getAlpha(); - } - - @Override - public void setAlpha(int alpha) { - alpha = Math.min(255, alpha); - swtGraphics.setAlpha(alpha); - currentState.alpha = alpha; - - Composite composite = getGraphics2D().getComposite(); - if (composite instanceof AlphaComposite) { - AlphaComposite newComposite = AlphaComposite.getInstance( - ((AlphaComposite) composite).getRule(), - (float) alpha / (float) 255); - getGraphics2D().setComposite(newComposite); - } - } - - protected BasicStroke getStroke() { - return stroke; - } - - protected void setStroke(BasicStroke stroke) { - this.stroke = stroke; - getGraphics2D().setStroke(stroke); - } - - /** - * Sets and retirns AWT Stroke based on the value of - * LineAttributes within the current state object - * - * @return the new AWT stroke - */ - private Stroke createStroke() { - float factor = currentState.lineAttributes.width > 0 - ? currentState.lineAttributes.width : 3; - float awt_dash[]; - int awt_cap; - int awt_join; - - switch (currentState.lineAttributes.style) { - case SWTGraphics.LINE_DASH: - awt_dash = new float[] { factor * 6, factor * 3 }; - break; - case SWTGraphics.LINE_DASHDOT: - awt_dash = new float[] { factor * 3, factor, factor, factor }; - break; - case SWTGraphics.LINE_DASHDOTDOT: - awt_dash = new float[] { factor * 3, factor, factor, factor, factor, - factor }; - break; - case SWTGraphics.LINE_DOT: - awt_dash = new float[] { factor, factor }; - break; - case SWTGraphics.LINE_CUSTOM: - awt_dash = currentState.lineAttributes.dash; - break; - default: - awt_dash = null; - } - - switch (currentState.lineAttributes.cap) { - case SWT.CAP_FLAT: - awt_cap = BasicStroke.CAP_BUTT; - break; - case SWT.CAP_ROUND: - awt_cap = BasicStroke.CAP_ROUND; - break; - case SWT.CAP_SQUARE: - awt_cap = BasicStroke.CAP_SQUARE; - break; - default: - awt_cap = BasicStroke.CAP_BUTT; - } - - switch (currentState.lineAttributes.join) { - case SWT.JOIN_BEVEL: - awt_join = BasicStroke.JOIN_BEVEL; - break; - case SWT.JOIN_MITER: - awt_join = BasicStroke.JOIN_MITER; - break; - case SWT.JOIN_ROUND: - awt_join = BasicStroke.JOIN_ROUND; - default: - awt_join = BasicStroke.JOIN_MITER; - } - - /* - * SWT paints line width == 0 as if it is == 1, so AWT is synced up with - * that below. - */ - stroke = new BasicStroke( - currentState.lineAttributes.width != 0 - ? currentState.lineAttributes.width : 1, - awt_cap, awt_join, currentState.lineAttributes.miterLimit, - awt_dash, currentState.lineAttributes.dashOffset); - return stroke; - } - - @Override - public boolean getAdvanced() { - return (currentState.graphicHints & ADVANCED_GRAPHICS_MASK) != 0; - } - - @Override - public void setAdvanced(boolean value) { - if (value) { - currentState.graphicHints |= ADVANCED_GRAPHICS_MASK; - } else { - currentState.graphicHints &= ~ADVANCED_GRAPHICS_MASK; - } - } - - @Override - public void clipPath(Path path) { - if (((appliedState.graphicHints ^ currentState.graphicHints) - & FILL_RULE_MASK) != 0) { - // If there is a pending change to the fill rule, apply it first. - // As long as the FILL_RULE is stored in a single bit, just toggling - // it works. - appliedState.graphicHints ^= FILL_RULE_MASK; - } - setClip(path); - getGraphics2D().clipRect(relativeClipRegion.x + transX, - relativeClipRegion.y + transY, relativeClipRegion.width, - relativeClipRegion.height); - java.awt.Rectangle bounds = getGraphics2D().getClip().getBounds(); - relativeClipRegion = new Rectangle(bounds.x, bounds.y, bounds.width, - bounds.height); - } - - @Override - public void rotate(float degrees) { - if (rotateOrientation == 0) { - if (degrees > 0) - rotateOrientation = 1; - else if (degrees < 0) - rotateOrientation = -1; - } - - /* - * Method was introduced to fix Bug 368146. With this at place no - * exceptions happens during SVG export (which happened as soon as a - * rotatable object like an ellipse is contained in the diagram), but - * the object is still not rotated in the exported SVG graphics. - */ - if (swtGraphics.getAdvanced()) { - swtGraphics.rotate(degrees); - } - /* - * The rotation has to be forwarded to the SVG Graphics object. This - * rotation is stateful, all drawing actions thereafter will be rotated. - * Thus the rotation coordinates have to be remembered and the rotation - * needs to be inverted before the next object is drawn. The inverted - * rotation is hence triggered in pushState(). Fix for Bug 369241 - */ - rotateDetail(degrees); - if (this.angle == 0.0) { - rotateOrientation = 0 - rotateOrientation; - rotateDetail(degrees); - } - } - - private void rotateDetail(float degrees) { - if ((rotateOrientation == 1 && degrees > 0) - || (rotateOrientation == -1 && degrees < 0)) { - getGraphics2D().rotate(Math.toRadians(degrees), - currentState.translateX, currentState.translateY); - this.angle = degrees; - this.rotateX = currentState.translateX; - this.rotateY = currentState.translateY; - } - } - - @Override - public int getLineCap() { - return SWT.CAP_FLAT; - } - - @Override - public int getLineJoin() { - return SWT.JOIN_MITER; - } - - @Override - public float getLineMiterLimit() { - return 0; - } - - @Override - public void setBackgroundPattern(Pattern pattern) { - currentState.bgPattern = pattern; - } - - @Override - public void setForegroundPattern(Pattern pattern) { - currentState.fgPattern = pattern; - } - - @Override - public void setInterpolation(int interpolation) { - // do nothing - } - - @Override - public void setLineDashOffset(float value) { - // do nothing - } - - @Override - public void setTextAntialias(int value) { - // do nothing - } - - @Override - public void shear(float horz, float vert) { - // do nothing - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.exports.vector.graphics; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Composite; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.util.Stack; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.SWTGraphics; +import org.eclipse.draw2d.TextUtilities; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.LineAttributes; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.PathData; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.graphics.GradientPattern; + +/** + * @author Jason Wong + */ +public class GraphicsToGraphics2DAdaptor extends Graphics { + private static class State { + + public int translateX = 0; + + public int translateY = 0; + + /** + * clipping rectangle x coordinate + */ + public int clipX = 0; + /** + * clipping rectangle y coordinate + */ + public int clipY = 0; + /** + * clipping rectangle width + */ + public int clipW = 0; + /** + * clipping rectangle height + */ + public int clipH = 0; + + /** Font value **/ + /** + * cached font + */ + public Font font; + + /** + * cached xor mode value + */ + public boolean XorMode = false; + /** + * cached foreground color + */ + public Color fgColor; + /** + * cached background color + */ + public Color bgColor; + /** + * cached foreground color + */ + public Pattern fgPattern; + /** + * cached background pattern + */ + public Pattern bgPattern; + + /** + * cached alpha value + */ + public int alpha; + + /** + * Line attributes value + */ + public LineAttributes lineAttributes = new LineAttributes(1); + + int graphicHints; + + /** + * Copy the values from a given state to this state + * + * @param state + * the state to copy from + */ + public void copyFrom(State state) { + translateX = state.translateX; + translateY = state.translateY; + + clipX = state.clipX; + clipY = state.clipY; + clipW = state.clipW; + clipH = state.clipH; + + font = state.font; + fgColor = state.fgColor; + bgColor = state.bgColor; + + bgPattern = state.bgPattern; + fgPattern = state.fgPattern; + + XorMode = state.XorMode; + alpha = state.alpha; + graphicHints = state.graphicHints; + + lineAttributes = SWTGraphics.clone(state.lineAttributes); + } + } + + static final int ADVANCED_GRAPHICS_MASK; + static final int ADVANCED_SHIFT; + static final int FILL_RULE_MASK; + static final int FILL_RULE_SHIFT; + static final int FILL_RULE_WHOLE_NUMBER = -1; + + /* + * It's consistent with SWTGraphics flags in case some other flags from + * SWTGraphics need to be here + */ + static { + FILL_RULE_SHIFT = 14; + ADVANCED_SHIFT = 15; + FILL_RULE_MASK = 1 << FILL_RULE_SHIFT; // If changed to more than 1-bit, + // check references! + ADVANCED_GRAPHICS_MASK = 1 << ADVANCED_SHIFT; + } + + private SWTGraphics swtGraphics; + private Graphics2D graphics2D; + private BasicStroke stroke; + private Stack states = new Stack(); + private final State currentState = new State(); + private final State appliedState = new State(); + + /** + * Some strings, Asian string in particular, are painted differently between + * SWT and AWT. SWT falls back to some default locale font if Asian string + * cannot be painted with the current font - this is done via the platform. + * AWT, unlike platform biased SWT, does not. Hence, Asian string widths are + * very different between SWT and AWT. To workaround the issue, if the flag + * below is set to true then once SWT and AWT string width are + * not equal, a bitmap of the SWT string will be painted. Otherwise the + * string is always painted with AWT Graphics 2D string rendering. + */ + protected boolean paintNotCompatibleStringsAsBitmaps = true; + + @SuppressWarnings("unused") + private static final TextUtilities TEXT_UTILITIES = new TextUtilities(); + + private Rectangle relativeClipRegion; + + private org.eclipse.swt.graphics.Rectangle viewBox; + private Image image; + + /** + * x coordinate for graphics translation + */ + private int transX = 0; + /** + * y coordinate for graphics translation + */ + private int transY = 0; + + /** + * current rotation angle + */ + private float angle; + /** + * The x coordinate of the rotation point + */ + private int rotateX; + /** + * The y coordinate of the rotation point + */ + private int rotateY; + + /** + * horizontal scale + */ + private float horizontalScale = 1.0f; + + /** + * vertical scale + */ + private float verticalScale = 1.0f; + + /** + * Constructor + * + * @param graphics + * the Graphics2D object that this object is + * delegating calls to. + * @param viewPort + * the Rectangle that defines the logical area being + * rendered by the graphics object. + */ + public GraphicsToGraphics2DAdaptor(Graphics2D graphics, Rectangle viewPort, + Display display) { + this(graphics, new org.eclipse.swt.graphics.Rectangle(viewPort.x, + viewPort.y, viewPort.width, viewPort.height), display); + } + + private Display display; + + private static int rotateOrientation = 0; + + /** + * Alternate Constructor that takes an swt Rectangle + * + * @param graphics + * the Graphics2D object that this object is + * delegating calls to. + * @param viewPort + * the org.eclipse.swt.graphics.Rectangle that + * defines the logical area being rendered by the graphics + * object. + */ + public GraphicsToGraphics2DAdaptor(Graphics2D graphics, + org.eclipse.swt.graphics.Rectangle viewPort, Display display) { + + this.display = display; + + // Save the ViewPort to add to the root DOM element + viewBox = viewPort; + + // Create the SWT Graphics Object + createSWTGraphics(); + + // Initialize the SVG Graphics Object + initSVGGraphics(graphics); + + // Initialize the States + init(); + } + + /** + * This is a helper method used to create the SWT Graphics object + */ + private void createSWTGraphics() { + + // we need this temp Rect just to instantiate an swt image in order to + // keep + // state, the size of this Rect is of no consequence and we just set it + // to + // such a small size in order to minimize memory allocation + org.eclipse.swt.graphics.Rectangle tempRect = new org.eclipse.swt.graphics.Rectangle( + 0, 0, 10, 10); + image = new Image(display, tempRect); + GC gc = new GC(image); + swtGraphics = new SWTGraphics(gc); + } + + /** + * Create the SVG graphics object and initializes it with the current line + * style and width + */ + private void initSVGGraphics(Graphics2D graphics) { + this.graphics2D = graphics; + + relativeClipRegion = new Rectangle(viewBox.x, viewBox.y, viewBox.width, + viewBox.height); + + // Initialize the line style and width + stroke = new BasicStroke(swtGraphics.getLineWidth(), + BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 0, null, 0); + LineAttributes lineAttributes = new LineAttributes(1); + swtGraphics.getLineAttributes(lineAttributes); + setLineAttributes(lineAttributes); + setFillRule(swtGraphics.getFillRule()); + setAdvanced(swtGraphics.getAdvanced()); + getGraphics2D().setStroke(stroke); + } + + /** + * This method should only be called by the constructor. Initializes state + * information for the currentState + */ + private void init() { + + // Initialize drawing styles + setForegroundColor(getForegroundColor()); + setBackgroundColor(getBackgroundColor()); + setXORMode(getXORMode()); + + // Initialize Font + setFont(getFont()); + currentState.font = appliedState.font = getFont(); + + // Initialize translations + currentState.translateX = appliedState.translateX = transX; + currentState.translateY = appliedState.translateY = transY; + + // Initialize Clip Regions + currentState.clipX = appliedState.clipX = relativeClipRegion.x; + currentState.clipY = appliedState.clipY = relativeClipRegion.y; + currentState.clipW = appliedState.clipW = relativeClipRegion.width; + currentState.clipH = appliedState.clipH = relativeClipRegion.height; + + currentState.alpha = appliedState.alpha = getAlpha(); + } + + /** + * Verifies that the applied state is up to date with the current state and + * updates the applied state accordingly. + */ + protected void checkState() { + if (appliedState.font != currentState.font) { + appliedState.font = currentState.font; + + setFont(currentState.font); + } + + if (appliedState.clipX != currentState.clipX + || appliedState.clipY != currentState.clipY + || appliedState.clipW != currentState.clipW + || appliedState.clipH != currentState.clipH) { + + appliedState.clipX = currentState.clipX; + appliedState.clipY = currentState.clipY; + appliedState.clipW = currentState.clipW; + appliedState.clipH = currentState.clipH; + + if (rotateOrientation != 0) { + if (currentState.bgColor.equals(currentState.fgColor)) { + double p = Math.pow(currentState.clipW, 2) + + Math.pow(currentState.clipH, 2); + int newWidth = Math.round((float) Math.sqrt(p)); + currentState.clipX = currentState.clipX + - (newWidth - currentState.clipW) / 2; + currentState.clipW = newWidth; + } + } + + // Adjust the clip for SVG + getGraphics2D().setClip(currentState.clipX - 1, + currentState.clipY - 1, currentState.clipW + 2, + currentState.clipH + 2); + } + + if (appliedState.alpha != currentState.alpha) { + appliedState.alpha = currentState.alpha; + + setAlpha(currentState.alpha); + } + + appliedState.graphicHints = currentState.graphicHints; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#clipRect(org.eclipse.draw2d.geometry. + * Rectangle ) + */ + @Override + public void clipRect(Rectangle rect) { + relativeClipRegion.intersect(rect); + setClipAbsolute(relativeClipRegion.x + transX, + relativeClipRegion.y + transY, relativeClipRegion.width, + relativeClipRegion.height); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#dispose() + */ + @Override + public void dispose() { + rotateOrientation = 0; + swtGraphics.dispose(); + + if (image != null) { + image.dispose(); + } + + states.clear(); + } + + /** + * This method is used to convert an SWT Color to an AWT Color. + * + * @param toConvert + * SWT Color to convert + * @return AWT Color + */ + protected java.awt.Color getColor(Color toConvert) { + + return new java.awt.Color(toConvert.getRed(), toConvert.getGreen(), + toConvert.getBlue(), getAlpha()); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawArc(int, int, int, int, int, int) + */ + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, + int endAngle) { + + Arc2D arc = new Arc2D.Float(x + transX, y + transY, width - 1, height, + startAngle, endAngle, Arc2D.OPEN); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(arc); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillArc(int, int, int, int, int, int) + */ + @Override + public void fillArc(int x, int y, int w, int h, int offset, int length) { + + Arc2D arc = new Arc2D.Float(x + transX, y + transY, w, h, offset, + length, Arc2D.OPEN); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); + getGraphics2D().fill(arc); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawFocus(int, int, int, int) + */ + @Override + public void drawFocus(int x, int y, int w, int h) { + drawRectangle(x, y, w, h); + } + + @Override + public void drawTextLayout(TextLayout layout, int x, int y, + int selectionStart, int selectionEnd, Color selectionForeground, + Color selectionBackground) { + checkState(); + if (!layout.getBounds().isEmpty()) { + Image image = new Image(display, layout.getBounds().width, + layout.getBounds().height); + GC gc = new GC(image); + cloneGC(gc); + layout.draw(gc, 0, 0, selectionStart, selectionEnd, + selectionForeground, selectionBackground); + + ImageData imageData = image.getImageData(); + imageData.transparentPixel = imageData.palette + .getPixel(getBackgroundColor().getRGB()); + + gc.dispose(); + image.dispose(); + + getGraphics2D().drawImage( + ImageConverter.convertFromImageData(imageData), x + transX, + y + transY, null); + } + } + + private void cloneGC(GC gc) { + gc.setAdvanced(getAdvanced()); + gc.setAlpha(getAlpha()); + gc.setAntialias(getAntialias()); + gc.setFillRule(getFillRule()); + gc.setFont(getFont()); + gc.setInterpolation(getInterpolation()); + gc.setLineAttributes(getLineAttributes()); + gc.setTextAntialias(getTextAntialias()); + gc.setBackground(getBackgroundColor()); + gc.setForeground(getForegroundColor()); + } + + @Override + public int getInterpolation() { + return swtGraphics.getInterpolation(); + } + + @Override + public LineAttributes getLineAttributes() { + LineAttributes la = new LineAttributes(1); + swtGraphics.getLineAttributes(la); + return la; + } + + @Override + public int getTextAntialias() { + return swtGraphics.getTextAntialias(); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, + * int, int) + */ + @Override + public void drawImage(Image srcImage, int xpos, int ypos) { + + // Translate the Coordinates + xpos += transX; + ypos += transY; + + // Convert the SWT Image into an AWT BufferedImage + BufferedImage toDraw = ImageConverter.convert(srcImage); + + checkState(); + getGraphics2D().drawImage(toDraw, + new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos), null); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, + * int, int, int, int, int, int, int, int) + */ + @Override + public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) { + + x2 += transX; + y2 += transY; + + BufferedImage toDraw = ImageConverter.convert(srcImage); + checkState(); + getGraphics2D().drawImage(toDraw, x2, y2, w2, h2, null); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawLine(int, int, int, int) + */ + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + + Line2D line = new Line2D.Float(x1 + transX, y1 + transY, x2 + transX, + y2 + transY); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(line); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawOval(int, int, int, int) + */ + @Override + public void drawOval(int x, int y, int w, int h) { + + Ellipse2D ellipse = new Ellipse2D.Float(x + transX, y + transY, w, h); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(ellipse); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillOval(int, int, int, int) + */ + @Override + public void fillOval(int x, int y, int w, int h) { + + Ellipse2D ellipse = new Ellipse2D.Float(x + transX, y + transY, w - 1, + h - 1); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); + getGraphics2D().fill(ellipse); + } + + private Polygon createPolygon(PointList pointList) { + + Polygon toCreate = new Polygon(); + + for (int i = 0; i < pointList.size(); i++) { + Point pt = pointList.getPoint(i); + + toCreate.addPoint(pt.x + transX, pt.y + transY); + } + + return toCreate; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawPolygon(org.eclipse.draw2d.geometry. + * PointList ) + */ + @Override + public void drawPolygon(PointList pointList) { + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(createPolygon(pointList)); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillPolygon(org.eclipse.draw2d.geometry. + * PointList ) + */ + @Override + public void fillPolygon(PointList pointList) { + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); + getGraphics2D().fill(createPolygon(pointList)); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#drawPolyline(org.eclipse.draw2d.geometry. + * PointList) + */ + @Override + public void drawPolyline(PointList pointList) { + + // Draw polylines as a series of lines + for (int x = 1; x < pointList.size(); x++) { + + Point p1 = pointList.getPoint(x - 1); + Point p2 = pointList.getPoint(x); + + drawLine(p1.x, p1.y, p2.x, p2.y); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawRectangle(int, int, int, int) + */ + @Override + public void drawRectangle(int x, int y, int w, int h) { + Rectangle2D rect = new Rectangle2D.Float(x + transX, y + transY, w, h); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(rect); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillRectangle(int, int, int, int) + */ + @Override + public void fillRectangle(int x, int y, int width, int height) { + + Rectangle2D rect = new Rectangle2D.Float(x + transX, y + transY, width, + height); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); + getGraphics2D().fill(rect); + } + + public void fillRectangle(int width, int height, Color bgColor) { + Rectangle2D rect = new Rectangle2D.Float(0, 0, width, height); + checkState(); + getGraphics2D().setPaint(getColor(bgColor)); + getGraphics2D().fill(rect); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawRoundRectangle(org.eclipse.draw2d. + * geometry .Rectangle, int, int) + */ + @Override + public void drawRoundRectangle(Rectangle rect, int arcWidth, + int arcHeight) { + + RoundRectangle2D roundRect = new RoundRectangle2D.Float(rect.x + transX, + rect.y + transY, rect.width, rect.height, arcWidth, arcHeight); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(roundRect); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillRoundRectangle(org.eclipse.draw2d. + * geometry .Rectangle, int, int) + */ + @Override + public void fillRoundRectangle(Rectangle rect, int arcWidth, + int arcHeight) { + + RoundRectangle2D roundRect = new RoundRectangle2D.Float(rect.x + transX, + rect.y + transY, rect.width, rect.height, arcWidth, arcHeight); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor())); + getGraphics2D().fill(roundRect); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawText(java.lang.String, int, int) + */ + @Override + public void drawText(String s, int x, int y) { + drawString(s, x, y); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawString(java.lang.String, int, int) + */ + + // private static Dimension swtStringSize; + + @Override + public void drawString(String s, int x, int y) { + if (s == null) + return; + java.awt.FontMetrics metrics = getGraphics2D().getFontMetrics(); + int stringLength = metrics.stringWidth(s); + // if (!this.display.isDisposed()) { + // Runnable runnable = new Runnable() { + // public void run() { + // swtStringSize = TEXT_UTILITIES.getStringExtents(str, + // swtGraphics.getFont()); + // } + // }; + // display.syncExec(runnable); + // } + + float xpos = x + transX; + float ypos = y + transY; + int lineWidth; + + // if (paintNotCompatibleStringsAsBitmaps + // && Math.abs(swtStringSize.width - stringLength) > 2) { + // // create SWT bitmap of the string then + // Image image = new Image(display, swtStringSize.width + 1, + // swtStringSize.height + 1); + // GC gc = new GC(image); + // gc.setForeground(getForegroundColor()); + // gc.setBackground(getBackgroundColor()); + // gc.setAntialias(getAntialias()); + // gc.setFont(getFont()); + // gc.drawString(s, 0, 0); + // gc.dispose(); + // ImageData data = image.getImageData(); + // image.dispose(); + // RGB backgroundRGB = getBackgroundColor().getRGB(); + // for (int i = 0; i < data.width; i++) { + // for (int j = 0; j < data.height; j++) { + // if (data.palette.getRGB(data.getPixel(i, j)).equals( + // backgroundRGB)) { + // data.setAlpha(i, j, 0); + // } else { + // data.setAlpha(i, j, 255); + // } + // } + // } + // getGraphics2D().drawImage( + // ImageConverter.convertFromImageData(data), + // new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos), null); + // stringLength = swtStringSize.width; + // } else { + + ypos += metrics.getAscent(); + + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().drawString(s, xpos, ypos); + if (Platform.OS_LINUX.equals(Platform.getOS())) + swtGraphics.drawString(s, (int) xpos, (int) ypos); + // } + + if (isFontUnderlined(getFont())) { + int baseline = y + metrics.getAscent(); + lineWidth = getLineWidth(); + + setLineWidth(1); + drawLine(x, baseline, x + stringLength, baseline); + setLineWidth(lineWidth); + } + + if (isFontStrikeout(getFont())) { + int strikeline = y + (metrics.getHeight() / 2); + lineWidth = getLineWidth(); + + setLineWidth(1); + drawLine(x, strikeline, x + stringLength, strikeline); + setLineWidth(lineWidth); + } + + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillString(java.lang.String, int, int) + */ + @Override + public void fillString(String s, int x, int y) { + // Not implemented + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillText(java.lang.String, int, int) + */ + @Override + public void fillText(String s, int x, int y) { + // Not implemented + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getBackgroundColor() + */ + @Override + public Color getBackgroundColor() { + return swtGraphics.getBackgroundColor(); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#getClip(org.eclipse.draw2d.geometry.Rectangle + * ) + */ + @Override + public Rectangle getClip(Rectangle rect) { + rect.setBounds(relativeClipRegion); + return rect; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getFont() + */ + @Override + public Font getFont() { + return swtGraphics.getFont(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getFontMetrics() + */ + @Override + public FontMetrics getFontMetrics() { + return swtGraphics.getFontMetrics(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getForegroundColor() + */ + @Override + public Color getForegroundColor() { + return swtGraphics.getForegroundColor(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getLineStyle() + */ + @Override + public int getLineStyle() { + return swtGraphics.getLineStyle(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getLineWidth() + */ + @Override + public int getLineWidth() { + return swtGraphics.getLineWidth(); + } + + @Override + public float getLineWidthFloat() { + return swtGraphics.getLineWidthFloat(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getXORMode() + */ + @Override + public boolean getXORMode() { + return swtGraphics.getXORMode(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#popState() + */ + @Override + public void popState() { + swtGraphics.popState(); + + restoreState(states.pop()); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#pushState() + */ + @Override + public void pushState() { + swtGraphics.pushState(); + if (angle != 0) { + getGraphics2D().rotate(Math.toRadians(360 - angle), rotateX, + rotateY); + angle = 0; + } + + // Make a copy of the current state and push it onto the stack + State toPush = new State(); + toPush.copyFrom(currentState); + states.push(toPush); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#restoreState() + */ + @Override + public void restoreState() { + swtGraphics.restoreState(); + + restoreState(states.peek()); + } + + private void restoreState(State state) { + + setBackgroundColor(state.bgColor); + setForegroundColor(state.fgColor); + + setBackgroundPattern(state.bgPattern); + setForegroundPattern(state.fgPattern); + + setLineAttributes(state.lineAttributes); + setXORMode(state.XorMode); + + setClipAbsolute(state.clipX, state.clipY, state.clipW, state.clipH); + + transX = currentState.translateX = state.translateX; + transY = currentState.translateY = state.translateY; + + relativeClipRegion.x = state.clipX - transX; + relativeClipRegion.y = state.clipY - transY; + relativeClipRegion.width = state.clipW; + relativeClipRegion.height = state.clipH; + + currentState.font = state.font; + currentState.alpha = state.alpha; + + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#scale(double) + */ + @Override + public void scale(double amount) { + scale((float) amount, (float) amount); + } + + @Override + public void scale(float horizontal, float vertical) { + if (horizontal == -1 || vertical == -1) { + horizontalScale *= horizontal; + verticalScale *= vertical; + } else { + horizontalScale = horizontal; + verticalScale = vertical; + } + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#setBackgroundColor(org.eclipse.swt.graphics + * .Color) + */ + @Override + public void setBackgroundColor(Color rgb) { + currentState.bgColor = rgb; + swtGraphics.setBackgroundColor(rgb); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#setClip(org.eclipse.draw2d.geometry.Rectangle + * ) + */ + @Override + public void setClip(Rectangle rect) { + relativeClipRegion.x = rect.x; + relativeClipRegion.y = rect.y; + relativeClipRegion.width = rect.width; + relativeClipRegion.height = rect.height; + + setClipAbsolute(rect.x + transX, rect.y + transY, rect.width, + rect.height); + } + + /** + * Sets the current clip values + * + * @param x + * the x value + * @param y + * the y value + * @param width + * the width value + * @param height + * the height value + */ + private void setClipAbsolute(int x, int y, int width, int height) { + currentState.clipX = x; + currentState.clipY = y; + currentState.clipW = width; + currentState.clipH = height; + } + + private boolean isFontUnderlined(Font f) { + return false; + } + + private boolean isFontStrikeout(Font f) { + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setFont(org.eclipse.swt.graphics.Font) + */ + @Override + public void setFont(Font f) { + swtGraphics.setFont(f); + currentState.font = f; + + FontData[] fontInfo = f.getFontData(); + + if (fontInfo[0] != null) { + + int height = fontInfo[0].getHeight(); + + // float fsize = height * (float) display.getDPI().x / 72.0f; + float fsize = height * 72.0f / 72.0f; + height = Math.round(fsize); + + int style = fontInfo[0].getStyle(); + boolean bItalic = (style & SWT.ITALIC) == SWT.ITALIC; + boolean bBold = (style & SWT.BOLD) == SWT.BOLD; + String faceName = fontInfo[0].getName(); + int escapement = 0; + + boolean bUnderline = isFontUnderlined(f); + boolean bStrikeout = isFontStrikeout(f); + + GdiFont font = new GdiFont(height, bItalic, bUnderline, bStrikeout, + bBold, faceName, escapement); + + getGraphics2D().setFont(font.getFont()); + } + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.draw2d.Graphics#setForegroundColor(org.eclipse.swt.graphics + * .Color) + */ + @Override + public void setForegroundColor(Color rgb) { + currentState.fgColor = rgb; + swtGraphics.setForegroundColor(rgb); + } + + /** + * Sets the dash pattern when the custom line style is in use. Because this + * feature is rarely used, the dash pattern may not be preserved when + * calling {@link #pushState()} and {@link #popState()}. + * + * @param dash + * the pixel pattern + */ + @Override + public void setLineDash(int[] dash) { + float dashFlt[] = new float[dash.length]; + for (int i = 0; i < dash.length; i++) { + dashFlt[i] = dash[i]; + } + setLineDash(dashFlt); + } + + @Override + public void setLineDash(float[] dash) { + currentState.lineAttributes.dash = dash; + setLineStyle(SWTGraphics.LINE_CUSTOM); + swtGraphics.setLineDash(dash); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setLineStyle(int) + */ + @Override + public void setLineStyle(int style) { + currentState.lineAttributes.style = style; + swtGraphics.setLineStyle(style); + } + + /** + * ignored + */ + @Override + public void setLineMiterLimit(float miterLimit) { + // do nothing + swtGraphics.setLineMiterLimit(miterLimit); + } + + /** + * ignored + */ + @Override + public void setLineCap(int cap) { + // do nothing + } + + /** + * ignored + */ + @Override + public void setLineJoin(int join) { + // do nothing + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setLineWidth(int) + */ + @Override + public void setLineWidth(int width) { + setLineWidthFloat(width); + } + + @Override + public void setLineWidthFloat(float width) { + currentState.lineAttributes.width = width; + swtGraphics.setLineWidthFloat(width); + } + + @Override + public void setLineAttributes(LineAttributes lineAttributes) { + SWTGraphics.copyLineAttributes(currentState.lineAttributes, + lineAttributes); + swtGraphics.setLineAttributes(lineAttributes); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setXORMode(boolean) + */ + @Override + public void setXORMode(boolean xorMode) { + currentState.XorMode = xorMode; + swtGraphics.setXORMode(xorMode); + } + + /** + * Sets the current translation values + * + * @param x + * the x translation value + * @param y + * the y translation value + */ + private void setTranslation(int x, int y) { + transX = currentState.translateX = x; + transY = currentState.translateY = y; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#translate(int, int) + */ + @Override + public void translate(int dx, int dy) { + swtGraphics.translate(dx, dy); + + setTranslation(transX + dx, transY + dy); + relativeClipRegion.x -= dx; + relativeClipRegion.y -= dy; + } + + @Override + public void translate(float dx, float dy) { + dx *= horizontalScale; + dy *= verticalScale; + swtGraphics.translate(dx, dy); + + setTranslation(transX + (int) dx, transY + (int) dy); + relativeClipRegion.x -= dx; + relativeClipRegion.y -= dy; + } + + /** + * @return the Graphics2D that this is delegating to. + */ + protected Graphics2D getGraphics2D() { + return graphics2D; + } + + /** + * @return Returns the swtGraphics. + */ + private SWTGraphics getSWTGraphics() { + return swtGraphics; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillGradient(int, int, int, int, + * boolean) + */ + @Override + public void fillGradient(int x, int y, int w, int h, boolean vertical) { + GradientPaint gradient; + + checkState(); + + // Gradients in SWT start with Foreground Color and end at Background + java.awt.Color start = getColor(getSWTGraphics().getForegroundColor()); + java.awt.Color stop = getColor(getSWTGraphics().getBackgroundColor()); + + // Create the Gradient based on horizontal or vertical + if (vertical) { + gradient = new GradientPaint(x + transX, y + transY, start, + x + transX, y + h + transY, stop); + } else { + gradient = new GradientPaint(x + transX, y + transY, start, + x + w + transX, y + transY, stop); + } + + Paint oldPaint = getGraphics2D().getPaint(); + getGraphics2D().setPaint(gradient); + getGraphics2D() + .fill(new Rectangle2D.Double(x + transX, y + transY, w, h)); + getGraphics2D().setPaint(oldPaint); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#drawPath(org.eclipse.swt.graphics.Path) + */ + @Override + public void drawPath(Path path) { + GeneralPath pathAWT = createPathAWT(path); + // getGraphics2D().draw(pathAWT); + checkState(); + getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor())); + getGraphics2D().setStroke(createStroke()); + getGraphics2D().draw(pathAWT); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#fillPath(org.eclipse.swt.graphics.Path) + */ + @Override + public void fillPath(Path path) { + checkState(); + if (currentState.bgPattern == null + || !(currentState.bgPattern instanceof GradientPattern)) { + getGraphics2D() + .setPaint(getColor(swtGraphics.getBackgroundColor())); + } else { + GradientPattern gp = (GradientPattern) currentState.bgPattern; + getGraphics2D().setPaint(getColor(gp.color2)); + } + getGraphics2D().fill(createPathAWT(path)); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setClip(org.eclipse.swt.graphics.Path) + */ + @Override + public void setClip(Path path) { + if (((appliedState.graphicHints ^ currentState.graphicHints) + & FILL_RULE_MASK) != 0) { + // If there is a pending change to the fill rule, apply it first. + // As long as the FILL_RULE is stored in a single bit, just toggling + // it works. + appliedState.graphicHints ^= FILL_RULE_MASK; + } + getGraphics2D().setClip(createPathAWT(path)); + appliedState.clipX = currentState.clipX = 0; + appliedState.clipY = currentState.clipY = 0; + appliedState.clipW = currentState.clipW = 0; + appliedState.clipH = currentState.clipH = 0; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getFillRule() + */ + @Override + public int getFillRule() { + return ((currentState.graphicHints & FILL_RULE_MASK) >> FILL_RULE_SHIFT) + - FILL_RULE_WHOLE_NUMBER; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setFillRule(int) + */ + @Override + public void setFillRule(int rule) { + currentState.graphicHints &= ~FILL_RULE_MASK; + currentState.graphicHints |= (rule + + FILL_RULE_WHOLE_NUMBER) << FILL_RULE_SHIFT; + } + + private GeneralPath createPathAWT(Path path) { + GeneralPath pathAWT = new GeneralPath(); + PathData pathData = path.getPathData(); + int idx = 0; + for (int i = 0; i < pathData.types.length; i++) { + switch (pathData.types[i]) { + case SWT.PATH_MOVE_TO: + pathAWT.moveTo( + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY); + break; + case SWT.PATH_LINE_TO: + pathAWT.lineTo( + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY); + break; + case SWT.PATH_CUBIC_TO: + pathAWT.curveTo( + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY, + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY, + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY); + break; + case SWT.PATH_QUAD_TO: + pathAWT.quadTo( + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY, + pathData.points[idx++] * horizontalScale + transX, + pathData.points[idx++] * verticalScale + transY); + break; + case SWT.PATH_CLOSE: + pathAWT.closePath(); + break; + default: + dispose(); + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + int swtWindingRule = ((appliedState.graphicHints + & FILL_RULE_MASK) >> FILL_RULE_SHIFT) - FILL_RULE_WHOLE_NUMBER; + if (swtWindingRule == SWT.FILL_WINDING) { + pathAWT.setWindingRule(GeneralPath.WIND_NON_ZERO); + } else if (swtWindingRule == SWT.FILL_EVEN_ODD) { + pathAWT.setWindingRule(GeneralPath.WIND_EVEN_ODD); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return pathAWT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal. + * DrawableRenderedImage #allowDelayRender() + */ + public boolean shouldAllowDelayRender() { + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal. + * DrawableRenderedImage #getMaximumRenderSize() + */ + public Dimension getMaximumRenderSize() { + return null; + } + + /** + * Accessor method to return the translation offset for the graphics object + * + * @return Point x coordinate for graphics translation + */ + protected Point getTranslationOffset() { + return new Point(transX, transY); + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#getAntialias() + */ + @Override + public int getAntialias() { + Object antiAlias = getGraphics2D() + .getRenderingHint(RenderingHints.KEY_ANTIALIASING); + if (antiAlias != null) { + if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_ON)) + return SWT.ON; + else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) + return SWT.OFF; + else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) + return SWT.DEFAULT; + } + + return SWT.DEFAULT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.draw2d.Graphics#setAntialias(int) + */ + @Override + public void setAntialias(int value) { + if (value == SWT.ON) { + getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } else if (value == SWT.OFF) { + getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + } + setAdvanced(true); + } + + @Override + public int getAlpha() { + return swtGraphics.getAlpha(); + } + + @Override + public void setAlpha(int alpha) { + alpha = Math.min(255, alpha); + swtGraphics.setAlpha(alpha); + currentState.alpha = alpha; + + Composite composite = getGraphics2D().getComposite(); + if (composite instanceof AlphaComposite) { + AlphaComposite newComposite = AlphaComposite.getInstance( + ((AlphaComposite) composite).getRule(), + (float) alpha / (float) 255); + getGraphics2D().setComposite(newComposite); + } + } + + protected BasicStroke getStroke() { + return stroke; + } + + protected void setStroke(BasicStroke stroke) { + this.stroke = stroke; + getGraphics2D().setStroke(stroke); + } + + /** + * Sets and retirns AWT Stroke based on the value of + * LineAttributes within the current state object + * + * @return the new AWT stroke + */ + private Stroke createStroke() { + float factor = currentState.lineAttributes.width > 0 + ? currentState.lineAttributes.width : 3; + float awt_dash[]; + int awt_cap; + int awt_join; + + switch (currentState.lineAttributes.style) { + case SWTGraphics.LINE_DASH: + awt_dash = new float[] { factor * 6, factor * 3 }; + break; + case SWTGraphics.LINE_DASHDOT: + awt_dash = new float[] { factor * 3, factor, factor, factor }; + break; + case SWTGraphics.LINE_DASHDOTDOT: + awt_dash = new float[] { factor * 3, factor, factor, factor, factor, + factor }; + break; + case SWTGraphics.LINE_DOT: + awt_dash = new float[] { factor, factor }; + break; + case SWTGraphics.LINE_CUSTOM: + awt_dash = currentState.lineAttributes.dash; + break; + default: + awt_dash = null; + } + + switch (currentState.lineAttributes.cap) { + case SWT.CAP_FLAT: + awt_cap = BasicStroke.CAP_BUTT; + break; + case SWT.CAP_ROUND: + awt_cap = BasicStroke.CAP_ROUND; + break; + case SWT.CAP_SQUARE: + awt_cap = BasicStroke.CAP_SQUARE; + break; + default: + awt_cap = BasicStroke.CAP_BUTT; + } + + switch (currentState.lineAttributes.join) { + case SWT.JOIN_BEVEL: + awt_join = BasicStroke.JOIN_BEVEL; + break; + case SWT.JOIN_MITER: + awt_join = BasicStroke.JOIN_MITER; + break; + case SWT.JOIN_ROUND: + awt_join = BasicStroke.JOIN_ROUND; + default: + awt_join = BasicStroke.JOIN_MITER; + } + + /* + * SWT paints line width == 0 as if it is == 1, so AWT is synced up with + * that below. + */ + stroke = new BasicStroke( + currentState.lineAttributes.width != 0 + ? currentState.lineAttributes.width : 1, + awt_cap, awt_join, currentState.lineAttributes.miterLimit, + awt_dash, currentState.lineAttributes.dashOffset); + return stroke; + } + + @Override + public boolean getAdvanced() { + return (currentState.graphicHints & ADVANCED_GRAPHICS_MASK) != 0; + } + + @Override + public void setAdvanced(boolean value) { + if (value) { + currentState.graphicHints |= ADVANCED_GRAPHICS_MASK; + } else { + currentState.graphicHints &= ~ADVANCED_GRAPHICS_MASK; + } + } + + @Override + public void clipPath(Path path) { + if (((appliedState.graphicHints ^ currentState.graphicHints) + & FILL_RULE_MASK) != 0) { + // If there is a pending change to the fill rule, apply it first. + // As long as the FILL_RULE is stored in a single bit, just toggling + // it works. + appliedState.graphicHints ^= FILL_RULE_MASK; + } + setClip(path); + getGraphics2D().clipRect(relativeClipRegion.x + transX, + relativeClipRegion.y + transY, relativeClipRegion.width, + relativeClipRegion.height); + java.awt.Rectangle bounds = getGraphics2D().getClip().getBounds(); + relativeClipRegion = new Rectangle(bounds.x, bounds.y, bounds.width, + bounds.height); + } + + @Override + public void rotate(float degrees) { + if (rotateOrientation == 0) { + if (degrees > 0) + rotateOrientation = 1; + else if (degrees < 0) + rotateOrientation = -1; + } + + /* + * Method was introduced to fix Bug 368146. With this at place no + * exceptions happens during SVG export (which happened as soon as a + * rotatable object like an ellipse is contained in the diagram), but + * the object is still not rotated in the exported SVG graphics. + */ + if (swtGraphics.getAdvanced()) { + swtGraphics.rotate(degrees); + } + /* + * The rotation has to be forwarded to the SVG Graphics object. This + * rotation is stateful, all drawing actions thereafter will be rotated. + * Thus the rotation coordinates have to be remembered and the rotation + * needs to be inverted before the next object is drawn. The inverted + * rotation is hence triggered in pushState(). Fix for Bug 369241 + */ + rotateDetail(degrees); + if (this.angle == 0.0) { + rotateOrientation = 0 - rotateOrientation; + rotateDetail(degrees); + } + } + + private void rotateDetail(float degrees) { + if ((rotateOrientation == 1 && degrees > 0) + || (rotateOrientation == -1 && degrees < 0)) { + getGraphics2D().rotate(Math.toRadians(degrees), + currentState.translateX, currentState.translateY); + this.angle = degrees; + this.rotateX = currentState.translateX; + this.rotateY = currentState.translateY; + } + } + + @Override + public int getLineCap() { + return SWT.CAP_FLAT; + } + + @Override + public int getLineJoin() { + return SWT.JOIN_MITER; + } + + @Override + public float getLineMiterLimit() { + return 0; + } + + @Override + public void setBackgroundPattern(Pattern pattern) { + currentState.bgPattern = pattern; + } + + @Override + public void setForegroundPattern(Pattern pattern) { + currentState.fgPattern = pattern; + } + + @Override + public void setInterpolation(int interpolation) { + // do nothing + } + + @Override + public void setLineDashOffset(float value) { + // do nothing + } + + @Override + public void setTextAntialias(int value) { + // do nothing + } + + @Override + public void shear(float horz, float vert) { + // do nothing + } + +} diff --git a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/ImageConverter.java b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/ImageConverter.java index 172e73262..154384e4d 100644 --- a/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/ImageConverter.java +++ b/bundles/org.xmind.ui.exports.vector/src/org/xmind/ui/exports/vector/graphics/ImageConverter.java @@ -1,182 +1,182 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2013 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.exports.vector.graphics; - -import java.awt.image.BufferedImage; -import java.awt.image.WritableRaster; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; - -/** - * @author Jason Wong - */ -public class ImageConverter { - - private static final PaletteData PALETTE_DATA = new PaletteData(0xFF0000, - 0xFF00, 0xFF); - - /** - * Converts an AWT based buffered image into an SWT Image. This - * will always return an Image that has 24 bit depth regardless - * of the type of AWT buffered image that is passed into the method. - * - * @param srcImage - * the {@link java.awt.image.BufferedImage} to be converted to an - * Image - * @return an Image that represents the same image data as the - * AWT BufferedImage type. - */ - public static Image convert(BufferedImage srcImage, Display display) { - return new Image(display, convertToImageData(srcImage)); - } - - /** - * //Before - * - * public static Image convert(BufferedImage srcImage) { return new - * Image(Util.getdisplay(),converToImageData(srcImage)); } - */ - - /** - * Converts an AWT based buffered image into an SWT ImageData. - * This will always return an ImageData that has 24 bit depth - * regardless of the type of AWT buffered image that is passed into the - * method. - * - * @param srcImage - * the {@link java.awt.image.BufferedImage} to be converted to an - * Image - * @return an Image that represents the same image data as the - * AWT BufferedImage type. - * - * @since 1.3.1 - */ - public static ImageData convertToImageData(BufferedImage srcImage) { - // We can force bitdepth to be 24 bit because BufferedImage getRGB - // allows us to always - // retrieve 24 bit data regardless of source color depth. - ImageData swtImageData = new ImageData(srcImage.getWidth(), - srcImage.getHeight(), 24, PALETTE_DATA); - - // ensure scansize is aligned on 32 bit. - int scansize = (((srcImage.getWidth() * 3) + 3) * 4) / 4; - - WritableRaster alphaRaster = srcImage.getAlphaRaster(); - byte[] alphaBytes = new byte[srcImage.getWidth()]; - - for (int y = 0; y < srcImage.getHeight(); y++) { - int[] buff = srcImage.getRGB(0, y, srcImage.getWidth(), 1, null, 0, - scansize); - swtImageData.setPixels(0, y, srcImage.getWidth(), buff, 0); - - // check for alpha channel - if (alphaRaster != null) { - int[] alpha = alphaRaster.getPixels(0, y, srcImage.getWidth(), - 1, (int[]) null); - for (int i = 0; i < srcImage.getWidth(); i++) - alphaBytes[i] = (byte) alpha[i]; - swtImageData - .setAlphas(0, y, srcImage.getWidth(), alphaBytes, 0); - } - } - return swtImageData; - } - - /** - * Converts an swt based image into an AWT BufferedImage. This - * will always return a BufferedImage that is of type - * BufferedImage.TYPE_INT_ARGB regardless of the type of swt - * image that is passed into the method. - * - * @param srcImage - * the {@link org.eclipse.swt.graphics.Image} to be converted to - * a BufferedImage - * @return a BufferedImage that represents the same image data - * as the swt Image - */ - public static BufferedImage convert(Image srcImage) { - return convertFromImageData(srcImage.getImageData()); - } - - /** - * Converts an swt based image data into an AWT BufferedImage. - * This will always return a BufferedImage that is of type - * BufferedImage.TYPE_INT_ARGB regardless of the type of swt - * image that is passed into the method. - * - * @param imageData - * the {@link org.eclipse.swt.graphics.Image} to be converted to - * a BufferedImage - * @return a BufferedImage that represents the same image data - * as the swt Image - * - * @since 1.3.1 - */ - public static BufferedImage convertFromImageData(ImageData imageData) { - int width = imageData.width; - int height = imageData.height; - ImageData maskData = null; - int alpha[] = new int[1]; - - if (imageData.alphaData == null) - maskData = imageData.getTransparencyMask(); - - // now we should have the image data for the bitmap, decompressed in - // imageData[0].data. - // Convert that to a Buffered Image. - BufferedImage image = new BufferedImage(imageData.width, - imageData.height, BufferedImage.TYPE_INT_ARGB); - WritableRaster alphaRaster = image.getAlphaRaster(); - - // loop over the imagedata and set each pixel in the BufferedImage to - // the appropriate color. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - RGB color = imageData.palette.getRGB(imageData.getPixel(x, y)); - image.setRGB(x, y, new java.awt.Color(color.red, color.green, - color.blue).getRGB()); - - // check for alpha channel - if (alphaRaster != null) { - if (imageData.alphaData != null) { - int al = imageData.getAlpha(x, y); - if (al == 0) { - image.setRGB(x, y, - new java.awt.Color(255, 255, 255).getRGB()); - } else { - image.setRGB(x, y, new java.awt.Color(color.red, - color.green, color.blue).getRGB()); - } - alpha[0] = imageData.getAlpha(x, y); - alphaRaster.setPixel(x, y, alpha); - } else { - // check for transparency mask - if (maskData != null) { - alpha[0] = maskData.getPixel(x, y) == 0 ? 0 : 255; - alphaRaster.setPixel(x, y, alpha); - } - } - } - } - } - - return image; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2013 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.exports.vector.graphics; + +import java.awt.image.BufferedImage; +import java.awt.image.WritableRaster; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +/** + * @author Jason Wong + */ +public class ImageConverter { + + private static final PaletteData PALETTE_DATA = new PaletteData(0xFF0000, + 0xFF00, 0xFF); + + /** + * Converts an AWT based buffered image into an SWT Image. This + * will always return an Image that has 24 bit depth regardless + * of the type of AWT buffered image that is passed into the method. + * + * @param srcImage + * the {@link java.awt.image.BufferedImage} to be converted to an + * Image + * @return an Image that represents the same image data as the + * AWT BufferedImage type. + */ + public static Image convert(BufferedImage srcImage, Display display) { + return new Image(display, convertToImageData(srcImage)); + } + + /** + * //Before + * + * public static Image convert(BufferedImage srcImage) { return new + * Image(Util.getdisplay(),converToImageData(srcImage)); } + */ + + /** + * Converts an AWT based buffered image into an SWT ImageData. + * This will always return an ImageData that has 24 bit depth + * regardless of the type of AWT buffered image that is passed into the + * method. + * + * @param srcImage + * the {@link java.awt.image.BufferedImage} to be converted to an + * Image + * @return an Image that represents the same image data as the + * AWT BufferedImage type. + * + * @since 1.3.1 + */ + public static ImageData convertToImageData(BufferedImage srcImage) { + // We can force bitdepth to be 24 bit because BufferedImage getRGB + // allows us to always + // retrieve 24 bit data regardless of source color depth. + ImageData swtImageData = new ImageData(srcImage.getWidth(), + srcImage.getHeight(), 24, PALETTE_DATA); + + // ensure scansize is aligned on 32 bit. + int scansize = (((srcImage.getWidth() * 3) + 3) * 4) / 4; + + WritableRaster alphaRaster = srcImage.getAlphaRaster(); + byte[] alphaBytes = new byte[srcImage.getWidth()]; + + for (int y = 0; y < srcImage.getHeight(); y++) { + int[] buff = srcImage.getRGB(0, y, srcImage.getWidth(), 1, null, 0, + scansize); + swtImageData.setPixels(0, y, srcImage.getWidth(), buff, 0); + + // check for alpha channel + if (alphaRaster != null) { + int[] alpha = alphaRaster.getPixels(0, y, srcImage.getWidth(), + 1, (int[]) null); + for (int i = 0; i < srcImage.getWidth(); i++) + alphaBytes[i] = (byte) alpha[i]; + swtImageData + .setAlphas(0, y, srcImage.getWidth(), alphaBytes, 0); + } + } + return swtImageData; + } + + /** + * Converts an swt based image into an AWT BufferedImage. This + * will always return a BufferedImage that is of type + * BufferedImage.TYPE_INT_ARGB regardless of the type of swt + * image that is passed into the method. + * + * @param srcImage + * the {@link org.eclipse.swt.graphics.Image} to be converted to + * a BufferedImage + * @return a BufferedImage that represents the same image data + * as the swt Image + */ + public static BufferedImage convert(Image srcImage) { + return convertFromImageData(srcImage.getImageData()); + } + + /** + * Converts an swt based image data into an AWT BufferedImage. + * This will always return a BufferedImage that is of type + * BufferedImage.TYPE_INT_ARGB regardless of the type of swt + * image that is passed into the method. + * + * @param imageData + * the {@link org.eclipse.swt.graphics.Image} to be converted to + * a BufferedImage + * @return a BufferedImage that represents the same image data + * as the swt Image + * + * @since 1.3.1 + */ + public static BufferedImage convertFromImageData(ImageData imageData) { + int width = imageData.width; + int height = imageData.height; + ImageData maskData = null; + int alpha[] = new int[1]; + + if (imageData.alphaData == null) + maskData = imageData.getTransparencyMask(); + + // now we should have the image data for the bitmap, decompressed in + // imageData[0].data. + // Convert that to a Buffered Image. + BufferedImage image = new BufferedImage(imageData.width, + imageData.height, BufferedImage.TYPE_INT_ARGB); + WritableRaster alphaRaster = image.getAlphaRaster(); + + // loop over the imagedata and set each pixel in the BufferedImage to + // the appropriate color. + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + RGB color = imageData.palette.getRGB(imageData.getPixel(x, y)); + image.setRGB(x, y, new java.awt.Color(color.red, color.green, + color.blue).getRGB()); + + // check for alpha channel + if (alphaRaster != null) { + if (imageData.alphaData != null) { + int al = imageData.getAlpha(x, y); + if (al == 0) { + image.setRGB(x, y, + new java.awt.Color(255, 255, 255).getRGB()); + } else { + image.setRGB(x, y, new java.awt.Color(color.red, + color.green, color.blue).getRGB()); + } + alpha[0] = imageData.getAlpha(x, y); + alphaRaster.setPixel(x, y, alpha); + } else { + // check for transparency mask + if (maskData != null) { + alpha[0] = maskData.getPixel(x, y) == 0 ? 0 : 255; + alphaRaster.setPixel(x, y, alpha); + } + } + } + } + } + + return image; + } + +} diff --git a/bundles/org.xmind.ui.fishbone/.gitignore b/bundles/org.xmind.ui.fishbone/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.fishbone/.gitignore +++ b/bundles/org.xmind.ui.fishbone/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF index 841db1c0d..e31fca26f 100644 --- a/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF @@ -1,15 +1,15 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.fishbone;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.internal.fishbone.FishboneUIPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.xmind.ui;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)" -Eclipse-LazyStart: true -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Bundle-Localization: plugin +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.fishbone;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.internal.fishbone.FishboneUIPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.xmind.ui;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)" +Eclipse-LazyStart: true +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin diff --git a/bundles/org.xmind.ui.fishbone/about.html b/bundles/org.xmind.ui.fishbone/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.ui.fishbone/about.html +++ b/bundles/org.xmind.ui.fishbone/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

    License

    - -

    Nov 6, 2008

    - -

    -XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

    - - - + + + + +License + + +

    License

    + +

    Nov 6, 2008

    + +

    +XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

    + + + diff --git a/bundles/org.xmind.ui.fishbone/build.properties b/bundles/org.xmind.ui.fishbone/build.properties index 7915e442d..e393e414b 100644 --- a/bundles/org.xmind.ui.fishbone/build.properties +++ b/bundles/org.xmind.ui.fishbone/build.properties @@ -1,9 +1,9 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - icons/,\ - about.html,\ - plugin.properties -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/,\ + about.html,\ + plugin.properties +src.includes = about.html diff --git a/bundles/org.xmind.ui.fishbone/plugin.properties b/bundles/org.xmind.ui.fishbone/plugin.properties index 51ed10018..08f7872c2 100644 --- a/bundles/org.xmind.ui.fishbone/plugin.properties +++ b/bundles/org.xmind.ui.fishbone/plugin.properties @@ -1,12 +1,12 @@ -#Properties file for org.xmind.ui.fishbone -providerName = XMind Ltd. -pluginName = XMind Fishbone -branchPolicy.fishbone.leftHeaded.name = Fishbone (Left Headed) -branchPolicy.fishbone.rightHeaded.name = Fishbone (Right Headed) -topicShape.fishhead.left.name = Fishhead (Left) -topicShape.fishhead.right.name = Fishhead (Right) -topicShape.fishbone.name = Fishbone Topic Decoration -branchConnection.fishbone.name = Fishbone Branch Connection -branchDecoration.fishbone.main.name = Main Fishbone Branch Decoration -branchDecoration.fishbone.sub.name = Sub Fishbone Branch Decoration +#Properties file for org.xmind.ui.fishbone +providerName = XMind Ltd. +pluginName = XMind Fishbone +branchPolicy.fishbone.leftHeaded.name = Fishbone (Left Headed) +branchPolicy.fishbone.rightHeaded.name = Fishbone (Right Headed) +topicShape.fishhead.left.name = Fishhead (Left) +topicShape.fishhead.right.name = Fishhead (Right) +topicShape.fishbone.name = Fishbone Topic Decoration +branchConnection.fishbone.name = Fishbone Branch Connection +branchDecoration.fishbone.main.name = Main Fishbone Branch Decoration +branchDecoration.fishbone.sub.name = Sub Fishbone Branch Decoration branchPolicyCategory.name = Fishbone Diagram \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/plugin.xml b/bundles/org.xmind.ui.fishbone/plugin.xml index 2c2f48d6f..f6cab68be 100644 --- a/bundles/org.xmind.ui.fishbone/plugin.xml +++ b/bundles/org.xmind.ui.fishbone/plugin.xml @@ -1,1025 +1,1025 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.fishbone/pom.xml b/bundles/org.xmind.ui.fishbone/pom.xml index e3c8bf5e3..65039c82b 100644 --- a/bundles/org.xmind.ui.fishbone/pom.xml +++ b/bundles/org.xmind.ui.fishbone/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.fishbone - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.fishbone + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneBranchConnection.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneBranchConnection.java index 4f0bbf70e..2f3699185 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneBranchConnection.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneBranchConnection.java @@ -1,164 +1,164 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.decorations; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionLine; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractBranchConnection; -import org.xmind.ui.internal.fishbone.structures.ISubDirection; -import org.xmind.ui.mindmap.IBranchPart; - -public class FishboneBranchConnection extends AbstractBranchConnection { - - private IBranchPart branch; - - private PrecisionPoint joint = null; - - public FishboneBranchConnection(IBranchPart branch, String id) { - super(id); - this.branch = branch; - } - - protected boolean usesFill() { - return false; - } - - protected void route(IFigure figure, Path shape) { - PrecisionPoint sp = getSourcePosition(figure); - PrecisionPoint tp = getTargetPosition(figure); - shape.moveTo(sp); - if (joint != null) { - shape.lineTo(joint); - } - shape.lineTo(tp); - } - - protected void reroute(IFigure figure, PrecisionPoint sourcePos, - PrecisionPoint targetPos, boolean validating) { - IAnchor sa = getSourceAnchor(); - IAnchor ta = getTargetAnchor(); - if (sa != null && ta != null) { - PrecisionPoint p1 = sa.getLocation(Geometry - .getOppositePosition(getSourceOrientation()), 0); - PrecisionPoint p2 = sa.getLocation(getSourceOrientation(), - getSourceExpansion()); - PrecisionPoint p3 = ta.getLocation(getTargetOrientation(), - getTargetExpansion()); - PrecisionPoint p4 = ta.getLocation(Geometry - .getOppositePosition(getTargetOrientation()), 0); - PrecisionPoint j = calcJoint(p1, p2, p3, p4); - if (j == null) { - if (p3.getDistance2(p2) > p4.getDistance2(p2)) { - PrecisionPoint temp = p3; - p3 = p4; - p4 = temp; - } - j = calcJoint2(ta.getOwner(), p1, p2, p3, p4); - } - if (needsSourceLine(ta.getOwner())) { - joint = j; - sourcePos.setLocation(p2); - targetPos.setLocation(calcTarget(ta.getOwner(), p3, p4)); - } else { - joint = null; - sourcePos.setLocation(j); - targetPos.setLocation(calcTarget(ta.getOwner(), p3, p4)); - } - } - } - - private PrecisionPoint calcJoint2(IFigure child, PrecisionPoint p1, - PrecisionPoint p2, PrecisionPoint p3, PrecisionPoint p4) { - double angle = calcAngle(p1, p2, p3, p4); - PrecisionPoint p6 = p3.getMoved(Math.toRadians(angle), 100); - PrecisionPoint j = calcJoint(p1, p2, p3, p6); - if (j == null) - return p3; - return j; - } - - private double calcAngle(PrecisionPoint p1, PrecisionPoint p2, - PrecisionPoint p3, PrecisionPoint p4) { - if (Math.abs(p1.y - p2.y) < 2) { - if (p1.x > p2.x) { - if (p3.y < p1.y) - return ISubDirection.NWR.getRotateAngle(); - return ISubDirection.SWR.getRotateAngle(); - } - if (p3.y < p1.y) - return ISubDirection.NER.getRotateAngle(); - return ISubDirection.SER.getRotateAngle(); - } - return 0; - } - - private PrecisionPoint calcJoint(PrecisionPoint p1, PrecisionPoint p2, - PrecisionPoint p3, PrecisionPoint p4) { - if (isParalell(p1, p2, p3, p4)) - return null; - PrecisionLine line1 = new PrecisionLine(p1, p2, - PrecisionLine.LineType.Line); - PrecisionLine line2 = new PrecisionLine(p4, p3, - PrecisionLine.LineType.Line); - return line1.intersect(line2); - } - - private boolean isParalell(PrecisionPoint p1, PrecisionPoint p2, - PrecisionPoint p3, PrecisionPoint p4) { - double dx1 = p1.x - p2.x; - double dy1 = p1.y - p2.y; - double dx2 = p3.x - p4.x; - double dy2 = p3.y - p4.y; - if (Math.abs(dx1) < 2) - return Math.abs(dx2) < 2; - if (Math.abs(dy1) < 2) - return Math.abs(dy2) < 2; - double s1 = dy1 / dx1; - double s2 = dy2 / dx2; - return Math.abs(s1 / s2 - 1) < 0.01; - } - - private PrecisionPoint calcTarget(IFigure child, PrecisionPoint p3, - PrecisionPoint p4) { -// if (child != null && child instanceof IDecoratedFigure) { -// IDecoration decoration = ((IDecoratedFigure) child).getDecoration(); -// if (decoration instanceof FishboneTopicDecoration) -// return p4; -// } - return p3; - } - - private boolean needsSourceLine(IFigure child) { - return child == null || !isChild(child, branch.getFigure()); - } - - private boolean isChild(IFigure figure, IFigure branchFigure) { - IFigure parent = figure.getParent(); - if (parent == branchFigure) - return true; - if (parent == null || parent == branchFigure.getParent()) - return false; - return isChild(parent, branchFigure); - } - - public void invalidate() { - joint = null; - super.invalidate(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.decorations; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionLine; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractBranchConnection; +import org.xmind.ui.internal.fishbone.structures.ISubDirection; +import org.xmind.ui.mindmap.IBranchPart; + +public class FishboneBranchConnection extends AbstractBranchConnection { + + private IBranchPart branch; + + private PrecisionPoint joint = null; + + public FishboneBranchConnection(IBranchPart branch, String id) { + super(id); + this.branch = branch; + } + + protected boolean usesFill() { + return false; + } + + protected void route(IFigure figure, Path shape) { + PrecisionPoint sp = getSourcePosition(figure); + PrecisionPoint tp = getTargetPosition(figure); + shape.moveTo(sp); + if (joint != null) { + shape.lineTo(joint); + } + shape.lineTo(tp); + } + + protected void reroute(IFigure figure, PrecisionPoint sourcePos, + PrecisionPoint targetPos, boolean validating) { + IAnchor sa = getSourceAnchor(); + IAnchor ta = getTargetAnchor(); + if (sa != null && ta != null) { + PrecisionPoint p1 = sa.getLocation(Geometry + .getOppositePosition(getSourceOrientation()), 0); + PrecisionPoint p2 = sa.getLocation(getSourceOrientation(), + getSourceExpansion()); + PrecisionPoint p3 = ta.getLocation(getTargetOrientation(), + getTargetExpansion()); + PrecisionPoint p4 = ta.getLocation(Geometry + .getOppositePosition(getTargetOrientation()), 0); + PrecisionPoint j = calcJoint(p1, p2, p3, p4); + if (j == null) { + if (p3.getDistance2(p2) > p4.getDistance2(p2)) { + PrecisionPoint temp = p3; + p3 = p4; + p4 = temp; + } + j = calcJoint2(ta.getOwner(), p1, p2, p3, p4); + } + if (needsSourceLine(ta.getOwner())) { + joint = j; + sourcePos.setLocation(p2); + targetPos.setLocation(calcTarget(ta.getOwner(), p3, p4)); + } else { + joint = null; + sourcePos.setLocation(j); + targetPos.setLocation(calcTarget(ta.getOwner(), p3, p4)); + } + } + } + + private PrecisionPoint calcJoint2(IFigure child, PrecisionPoint p1, + PrecisionPoint p2, PrecisionPoint p3, PrecisionPoint p4) { + double angle = calcAngle(p1, p2, p3, p4); + PrecisionPoint p6 = p3.getMoved(Math.toRadians(angle), 100); + PrecisionPoint j = calcJoint(p1, p2, p3, p6); + if (j == null) + return p3; + return j; + } + + private double calcAngle(PrecisionPoint p1, PrecisionPoint p2, + PrecisionPoint p3, PrecisionPoint p4) { + if (Math.abs(p1.y - p2.y) < 2) { + if (p1.x > p2.x) { + if (p3.y < p1.y) + return ISubDirection.NWR.getRotateAngle(); + return ISubDirection.SWR.getRotateAngle(); + } + if (p3.y < p1.y) + return ISubDirection.NER.getRotateAngle(); + return ISubDirection.SER.getRotateAngle(); + } + return 0; + } + + private PrecisionPoint calcJoint(PrecisionPoint p1, PrecisionPoint p2, + PrecisionPoint p3, PrecisionPoint p4) { + if (isParalell(p1, p2, p3, p4)) + return null; + PrecisionLine line1 = new PrecisionLine(p1, p2, + PrecisionLine.LineType.Line); + PrecisionLine line2 = new PrecisionLine(p4, p3, + PrecisionLine.LineType.Line); + return line1.intersect(line2); + } + + private boolean isParalell(PrecisionPoint p1, PrecisionPoint p2, + PrecisionPoint p3, PrecisionPoint p4) { + double dx1 = p1.x - p2.x; + double dy1 = p1.y - p2.y; + double dx2 = p3.x - p4.x; + double dy2 = p3.y - p4.y; + if (Math.abs(dx1) < 2) + return Math.abs(dx2) < 2; + if (Math.abs(dy1) < 2) + return Math.abs(dy2) < 2; + double s1 = dy1 / dx1; + double s2 = dy2 / dx2; + return Math.abs(s1 / s2 - 1) < 0.01; + } + + private PrecisionPoint calcTarget(IFigure child, PrecisionPoint p3, + PrecisionPoint p4) { +// if (child != null && child instanceof IDecoratedFigure) { +// IDecoration decoration = ((IDecoratedFigure) child).getDecoration(); +// if (decoration instanceof FishboneTopicDecoration) +// return p4; +// } + return p3; + } + + private boolean needsSourceLine(IFigure child) { + return child == null || !isChild(child, branch.getFigure()); + } + + private boolean isChild(IFigure figure, IFigure branchFigure) { + IFigure parent = figure.getParent(); + if (parent == branchFigure) + return true; + if (parent == null || parent == branchFigure.getParent()) + return false; + return isChild(parent, branchFigure); + } + + public void invalidate() { + joint = null; + super.invalidate(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneTopicDecoration.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneTopicDecoration.java index e4d2cc288..33eb8a88f 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneTopicDecoration.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishboneTopicDecoration.java @@ -1,174 +1,174 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.decorations; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.IRotatableReferencedFigure; -import org.xmind.gef.draw2d.geometry.PrecisionLine; -import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionPointList; -import org.xmind.gef.draw2d.geometry.PrecisionPolygon; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.draw2d.graphics.GradientPattern; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; -import org.xmind.ui.resources.ColorUtils; - -public class FishboneTopicDecoration extends AbstractTopicDecoration { - - private static final Point CENTER = new Point(0, 0); - - private PrecisionRotator rotator = null; - - private PrecisionPolygon points = null; - - protected PrecisionRotator r() { - if (rotator == null) { - rotator = new PrecisionRotator(); - } - return rotator; - } - - public void invalidate() { - points = null; - super.invalidate(); - } - - public void validate(IFigure figure) { - if (points == null) - points = calcPoints(figure); - super.validate(figure); - } - - private PrecisionPolygon calcPoints(IFigure figure) { - PrecisionPolygon polygon = new PrecisionPolygon(4); - IRotatableReferencedFigure rf = (IRotatableReferencedFigure) figure; - r().setAngle(rf.getRotationDegrees()); - r().setOrigin(CENTER.x, CENTER.y); - PrecisionRectangle bounds = rf.getNormalPreferredBounds(CENTER) - .getExpanded(-getLineWidth(), -getLineWidth()); - polygon.setPoint(r().tp(bounds.getTopLeft()), 0); - polygon.setPoint(r().tp(bounds.getTopRight()), 1); - polygon.setPoint(r().tp(bounds.getBottomRight()), 2); - polygon.setPoint(r().tp(bounds.getBottomLeft()), 3); - return polygon; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - double cx = box.x + box.width * 0.5d; - double cy = box.y + box.height * 0.5d; - if (points == null) - points = calcPoints(figure); - PrecisionPoint p = points.getPoint(0); - shape.moveTo((float) (cx + p.x), (float) (cy + p.y)); - for (int i = 1; i < 4; i++) { - lineTo(shape, cx, cy, points.getPoint(i)); - } - shape.close(); - } - - private void lineTo(Path shape, double cx, double cy, PrecisionPoint p) { - shape.lineTo((float) (cx + p.x), (float) (cy + p.y)); - } - - protected Pattern createGradientPattern(IFigure figure, int alpha, - Color bgColor) { - return super.createGradientPattern(figure, alpha, bgColor); - } - - /** - * Create oblique background pattern for fishbone topics. - * - * @param figure - * the figure - * @param alpha - * the alpha - * @param color - * the color - * - * @return a new gradient pattern - * @deprecated The gradient pattern on carbon (Mac OS X 10.6+) creates - * gradient "blocks" when the starting point is not - * vertical/horizontal to the ending point. - */ - protected Pattern createObliquePattern(IFigure figure, int alpha, - Color color) { - Rectangle b = figure.getBounds(); - double cx = b.x + b.width * 0.5; - double cy = b.y + b.height * 0.5; - PrecisionPoint p1 = points.getPoint(0); - PrecisionPoint p2 = points.getPoint(3); - Pattern p = new GradientPattern(Display.getCurrent(), // - (float) (cx + p1.x), (float) (cy + p1.y), // - (float) (cx + p2.x), (float) (cy + p2.y), // - ColorUtils.gradientLighter(color), alpha, // - color, alpha); - return p; - } - - protected void paintOutline(IFigure figure, Graphics graphics) { - // don't paint outline - } - - protected PrecisionPoint getEast(IFigure figure, double expansion) { - PrecisionPoint center = new PrecisionPoint( - figure.getBounds().getCenter()); - return center.translate(points.getPoint(2)); - } - - protected PrecisionPoint getWest(IFigure figure, double expansion) { - PrecisionPoint center = new PrecisionPoint( - figure.getBounds().getCenter()); - return center.translate(points.getPoint(3)); - } - - protected PrecisionPoint getNorth(IFigure figure, double expansion) { - PrecisionPoint center = new PrecisionPoint( - figure.getBounds().getCenter()); - return center - .translate(points.getPoint(0).getCenter(points.getPoint(1))); - } - - protected PrecisionPoint getSouth(IFigure figure, double expansion) { - PrecisionPoint center = new PrecisionPoint( - figure.getBounds().getCenter()); - return center - .translate(points.getPoint(3).getCenter(points.getPoint(2))); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - checkValidation(figure); - Rectangle r = figure.getBounds(); - double cx = r.x + r.width * 0.5d; - double cy = r.y + r.height * 0.5d; - PrecisionLine ray = new PrecisionLine(cx, cy, refX, refY, LineType.Ray); - PrecisionPolygon polygon = points.getCopy(); - polygon.translate(cx, cy); - PrecisionPointList result = polygon.intersect(ray, 0.000001); - if (result.isEmpty()) - return polygon.getPoint(0); - return result.getPoint(0); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.decorations; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.IRotatableReferencedFigure; +import org.xmind.gef.draw2d.geometry.PrecisionLine; +import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionPointList; +import org.xmind.gef.draw2d.geometry.PrecisionPolygon; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.draw2d.graphics.GradientPattern; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; +import org.xmind.ui.resources.ColorUtils; + +public class FishboneTopicDecoration extends AbstractTopicDecoration { + + private static final Point CENTER = new Point(0, 0); + + private PrecisionRotator rotator = null; + + private PrecisionPolygon points = null; + + protected PrecisionRotator r() { + if (rotator == null) { + rotator = new PrecisionRotator(); + } + return rotator; + } + + public void invalidate() { + points = null; + super.invalidate(); + } + + public void validate(IFigure figure) { + if (points == null) + points = calcPoints(figure); + super.validate(figure); + } + + private PrecisionPolygon calcPoints(IFigure figure) { + PrecisionPolygon polygon = new PrecisionPolygon(4); + IRotatableReferencedFigure rf = (IRotatableReferencedFigure) figure; + r().setAngle(rf.getRotationDegrees()); + r().setOrigin(CENTER.x, CENTER.y); + PrecisionRectangle bounds = rf.getNormalPreferredBounds(CENTER) + .getExpanded(-getLineWidth(), -getLineWidth()); + polygon.setPoint(r().tp(bounds.getTopLeft()), 0); + polygon.setPoint(r().tp(bounds.getTopRight()), 1); + polygon.setPoint(r().tp(bounds.getBottomRight()), 2); + polygon.setPoint(r().tp(bounds.getBottomLeft()), 3); + return polygon; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + double cx = box.x + box.width * 0.5d; + double cy = box.y + box.height * 0.5d; + if (points == null) + points = calcPoints(figure); + PrecisionPoint p = points.getPoint(0); + shape.moveTo((float) (cx + p.x), (float) (cy + p.y)); + for (int i = 1; i < 4; i++) { + lineTo(shape, cx, cy, points.getPoint(i)); + } + shape.close(); + } + + private void lineTo(Path shape, double cx, double cy, PrecisionPoint p) { + shape.lineTo((float) (cx + p.x), (float) (cy + p.y)); + } + + protected Pattern createGradientPattern(IFigure figure, int alpha, + Color bgColor) { + return super.createGradientPattern(figure, alpha, bgColor); + } + + /** + * Create oblique background pattern for fishbone topics. + * + * @param figure + * the figure + * @param alpha + * the alpha + * @param color + * the color + * + * @return a new gradient pattern + * @deprecated The gradient pattern on carbon (Mac OS X 10.6+) creates + * gradient "blocks" when the starting point is not + * vertical/horizontal to the ending point. + */ + protected Pattern createObliquePattern(IFigure figure, int alpha, + Color color) { + Rectangle b = figure.getBounds(); + double cx = b.x + b.width * 0.5; + double cy = b.y + b.height * 0.5; + PrecisionPoint p1 = points.getPoint(0); + PrecisionPoint p2 = points.getPoint(3); + Pattern p = new GradientPattern(Display.getCurrent(), // + (float) (cx + p1.x), (float) (cy + p1.y), // + (float) (cx + p2.x), (float) (cy + p2.y), // + ColorUtils.gradientLighter(color), alpha, // + color, alpha); + return p; + } + + protected void paintOutline(IFigure figure, Graphics graphics) { + // don't paint outline + } + + protected PrecisionPoint getEast(IFigure figure, double expansion) { + PrecisionPoint center = new PrecisionPoint( + figure.getBounds().getCenter()); + return center.translate(points.getPoint(2)); + } + + protected PrecisionPoint getWest(IFigure figure, double expansion) { + PrecisionPoint center = new PrecisionPoint( + figure.getBounds().getCenter()); + return center.translate(points.getPoint(3)); + } + + protected PrecisionPoint getNorth(IFigure figure, double expansion) { + PrecisionPoint center = new PrecisionPoint( + figure.getBounds().getCenter()); + return center + .translate(points.getPoint(0).getCenter(points.getPoint(1))); + } + + protected PrecisionPoint getSouth(IFigure figure, double expansion) { + PrecisionPoint center = new PrecisionPoint( + figure.getBounds().getCenter()); + return center + .translate(points.getPoint(3).getCenter(points.getPoint(2))); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + checkValidation(figure); + Rectangle r = figure.getBounds(); + double cx = r.x + r.width * 0.5d; + double cy = r.y + r.height * 0.5d; + PrecisionLine ray = new PrecisionLine(cx, cy, refX, refY, LineType.Ray); + PrecisionPolygon polygon = points.getCopy(); + polygon.translate(cx, cy); + PrecisionPointList result = polygon.intersect(ray, 0.000001); + if (result.isEmpty()) + return polygon.getPoint(0); + return result.getPoint(0); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/LeftFishheadTopicDecoration.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/LeftFishheadTopicDecoration.java index 70a536526..840682d63 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/LeftFishheadTopicDecoration.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/LeftFishheadTopicDecoration.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.graphics.Path; - -public class LeftFishheadTopicDecoration extends FishheadTopicDecoration { - - public LeftFishheadTopicDecoration() { - super(false); - } - - public Path createClippingPath(IFigure figure) { - Path shape = new Path(Display.getCurrent()); - Rectangle box = getOutlineBox(figure); - - Insets ins = figure.getInsets(); - Rectangle clientArea = box.getShrinked(ins); - - float x = box.x - + clientArea.width * FishheadTopicDecoration.headConScale; - float y = box.y + box.height * 0.5f; - - shape.moveTo(box.right(), box.y); - - shape.quadTo(x, box.y, box.x, y); - - shape.quadTo(x, box.bottom(), box.right(), box.bottom()); - - shape.close(); - - return shape; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.graphics.Path; + +public class LeftFishheadTopicDecoration extends FishheadTopicDecoration { + + public LeftFishheadTopicDecoration() { + super(false); + } + + public Path createClippingPath(IFigure figure) { + Path shape = new Path(Display.getCurrent()); + Rectangle box = getOutlineBox(figure); + + Insets ins = figure.getInsets(); + Rectangle clientArea = box.getShrinked(ins); + + float x = box.x + + clientArea.width * FishheadTopicDecoration.headConScale; + float y = box.y + box.height * 0.5f; + + shape.moveTo(box.right(), box.y); + + shape.quadTo(x, box.y, box.x, y); + + shape.quadTo(x, box.bottom(), box.right(), box.bottom()); + + shape.close(); + + return shape; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/MainFishboneBranchDecoration.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/MainFishboneBranchDecoration.java index e4525f65c..fd8467851 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/MainFishboneBranchDecoration.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/MainFishboneBranchDecoration.java @@ -1,265 +1,265 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.decorations; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IDecoratedFigure; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.decoration.AbstractDecoration; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.draw2d.decoration.IShapeDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.graphics.GradientPattern; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.ITopicDecoration; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; - -public class MainFishboneBranchDecoration extends AbstractDecoration { - - private IBranchPart branch; - - private IPrecisionTransformer hf = new PrecisionHorizontalFlipper(); - - private PrecisionPoint lineStart = null; - - private PrecisionPoint lineEnd = null; - - private PrecisionPoint tailTop = null; - - private PrecisionPoint tailBottom = null; - - public static final int TailLength = 30; - - public MainFishboneBranchDecoration(IBranchPart branch, String id) { - super(id); - this.branch = branch; - } - - public void validate(IFigure figure) { - super.validate(figure); - if (branch.isFolded() || branch.getSubBranches().isEmpty()) { - setVisible(figure, false); - return; - } - - setVisible(figure, true); - - PrecisionPoint ref = getReference(figure); - hf.setOrigin(ref); - int orientation = branch.getConnections().getSourceOrientation(); - hf.setEnabled(orientation == PositionConstants.WEST); - - PrecisionRectangle r = getChildrenBounds(figure); - PrecisionRectangle b = hf.tr(getTopicBounds(ref)); - PrecisionPoint source = hf.rp(new PrecisionPoint(b.right() - 1, ref.y)); - PrecisionPoint target = hf - .rp(new PrecisionPoint(hf.tr(r).right(), ref.y)); - double tailX = target.x - + (source.x < target.x ? MainFishboneBranchDecoration.TailLength - : -MainFishboneBranchDecoration.TailLength); - double tw = Math.max(0, Math.min(b.height / 2, - Math.min(target.y - r.y, r.bottom() - target.y))); - - this.lineStart = source; - this.lineEnd = target; - this.tailTop = new PrecisionPoint(tailX, target.y - tw); - this.tailBottom = new PrecisionPoint(tailX, target.y + tw); - } - - private PrecisionRectangle getTopicBounds(PrecisionPoint ref) { - ITopicPart topicPart = branch.getTopicPart(); - if (topicPart != null) { - return new PrecisionRectangle(topicPart.getFigure().getBounds()); - } - return new PrecisionRectangle(ref.x, ref.y, 0, 0); - } - - private PrecisionRectangle getChildrenBounds(IFigure figure) { - PrecisionRectangle r = null; - ITopicPart topicPart = branch.getTopicPart(); - if (topicPart != null) { - r = Geometry.union(r, - new PrecisionRectangle(topicPart.getFigure().getBounds())); - } - for (IBranchPart subBranch : branch.getSubBranches()) { - r = Geometry.union(r, - new PrecisionRectangle(subBranch.getFigure().getBounds())); - } - if (r != null) - return r; - return new PrecisionRectangle(figure.getBounds()); - } - - private PrecisionPoint getReference(IFigure figure) { - ITopicPart topicPart = branch.getTopicPart(); - if (topicPart != null) { - return new PrecisionPoint( - ((IReferencedFigure) topicPart.getFigure()).getReference()); - } - return new PrecisionPoint(figure.getBounds().getCenter()); - } - - public void invalidate() { - lineStart = null; - lineEnd = null; - tailTop = null; - tailBottom = null; - super.invalidate(); - } - - protected void performPaint(IFigure figure, Graphics graphics) { - if (lineStart == null || lineEnd == null || tailTop == null - || tailBottom == null) - return; - - ITopicDecoration topicDecoration = getTopicDecoration(); - if (topicDecoration == null) - return; - - Color lineColor = topicDecoration.getLineColor(); - Color fillColor = topicDecoration.getFillColor(); - - if (lineColor == null) - return; - - int lineWidth = Math.max(1, topicDecoration.getLineWidth()); - int lineStyle = topicDecoration.getLineStyle(); - - graphics.setAlpha(getAlpha()); - graphics.setLineStyle(lineStyle); - graphics.setAntialias(SWT.ON); - - Path shape = new Path(Display.getCurrent()); - if (branch.getConnections().isTapered()) { - graphics.setLineWidth(lineWidth); - shape.moveTo( - (float) lineStart.x + (lineStart.x < lineEnd.x ? -1 : 1), - (float) (lineStart.y - lineWidth * 5 - 0)); - shape.lineTo( - (float) lineStart.x + (lineStart.x < lineEnd.x ? -1 : 1), - (float) (lineStart.y + lineWidth * 5 + 0)); - shape.lineTo((float) lineEnd.x, - (float) (lineEnd.y + lineWidth * 0.5)); - shape.lineTo((float) lineEnd.x, - (float) (lineEnd.y - lineWidth * 0.5)); - shape.close(); - graphics.setBackgroundColor(lineColor); - graphics.fillPath(shape); - -// shape.moveTo(lineStart); -// shape.lineTo(lineEnd); -// graphics.setForegroundColor(lineColor); -// graphics.setLineWidth(lineWidth * 5); -// graphics.drawPath(shape); - } else { - shape.moveTo(lineStart); - shape.lineTo(lineEnd); - graphics.setForegroundColor(lineColor); - graphics.setLineWidth(lineWidth); - graphics.drawPath(shape); - } - shape.dispose(); - - shape = new Path(Display.getCurrent()); - shape.moveTo(lineEnd); - shape.lineTo(tailTop); - shape.lineTo(tailBottom); - shape.lineTo(lineEnd); - shape.close(); - - if (fillColor != null) { - Pattern pattern = null; - if (isGradient()) { - PrecisionRectangle r = new PrecisionRectangle(tailTop, - tailBottom).union(lineEnd); - pattern = createPattern(figure, getAlpha(), fillColor, r); - if (pattern != null) { - graphics.pushState(); - graphics.setBackgroundPattern(pattern); - } - } else { - graphics.setAlpha(getAlpha()); - graphics.setBackgroundColor(fillColor); - } - graphics.fillPath(shape); - if (pattern != null) { - graphics.popState(); - pattern.dispose(); - } - } - - if (lineColor != null) { - graphics.setForegroundColor(lineColor); - graphics.setLineWidth(lineWidth); - graphics.setLineStyle(lineStyle); - graphics.setAlpha(getAlpha()); - graphics.drawPath(shape); - } - - shape.dispose(); - } - - private ITopicDecoration getTopicDecoration() { - ITopicPart topicPart = branch.getTopicPart(); - if (topicPart != null) { - IFigure topicFigure = topicPart.getFigure(); - if (topicFigure instanceof IDecoratedFigure) { - IDecoration decoration = ((IDecoratedFigure) topicFigure) - .getDecoration(); - if (decoration instanceof ITopicDecoration) - return (ITopicDecoration) decoration; - } - } - return null; - } - - private Pattern createPattern(IFigure figure, int alpha, Color color, - PrecisionRectangle r) { - int delta = (int) (r.height * 0.4); - Pattern p = new GradientPattern(Display.getCurrent(), // - (float) r.x, (float) (r.y - delta), // - (float) r.x, (float) (r.y + r.height), // - ColorConstants.white, alpha, color, alpha); - return p; - } - - private boolean isGradient() { - ITopicPart topicPart = branch.getTopicPart(); - if (topicPart != null) { - IFigure figure = topicPart.getFigure(); - if (figure instanceof IDecoratedFigure) { - IDecoration decoration = ((IDecoratedFigure) figure) - .getDecoration(); - if (decoration instanceof IShapeDecoration) { - return ((IShapeDecoration) decoration).isGradient(); - } - } - } - return GEF.IS_PLATFORM_SUPPORT_GRADIENT; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.decorations; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IDecoratedFigure; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.decoration.AbstractDecoration; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.draw2d.decoration.IShapeDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.graphics.GradientPattern; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.ITopicDecoration; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; + +public class MainFishboneBranchDecoration extends AbstractDecoration { + + private IBranchPart branch; + + private IPrecisionTransformer hf = new PrecisionHorizontalFlipper(); + + private PrecisionPoint lineStart = null; + + private PrecisionPoint lineEnd = null; + + private PrecisionPoint tailTop = null; + + private PrecisionPoint tailBottom = null; + + public static final int TailLength = 30; + + public MainFishboneBranchDecoration(IBranchPart branch, String id) { + super(id); + this.branch = branch; + } + + public void validate(IFigure figure) { + super.validate(figure); + if (branch.isFolded() || branch.getSubBranches().isEmpty()) { + setVisible(figure, false); + return; + } + + setVisible(figure, true); + + PrecisionPoint ref = getReference(figure); + hf.setOrigin(ref); + int orientation = branch.getConnections().getSourceOrientation(); + hf.setEnabled(orientation == PositionConstants.WEST); + + PrecisionRectangle r = getChildrenBounds(figure); + PrecisionRectangle b = hf.tr(getTopicBounds(ref)); + PrecisionPoint source = hf.rp(new PrecisionPoint(b.right() - 1, ref.y)); + PrecisionPoint target = hf + .rp(new PrecisionPoint(hf.tr(r).right(), ref.y)); + double tailX = target.x + + (source.x < target.x ? MainFishboneBranchDecoration.TailLength + : -MainFishboneBranchDecoration.TailLength); + double tw = Math.max(0, Math.min(b.height / 2, + Math.min(target.y - r.y, r.bottom() - target.y))); + + this.lineStart = source; + this.lineEnd = target; + this.tailTop = new PrecisionPoint(tailX, target.y - tw); + this.tailBottom = new PrecisionPoint(tailX, target.y + tw); + } + + private PrecisionRectangle getTopicBounds(PrecisionPoint ref) { + ITopicPart topicPart = branch.getTopicPart(); + if (topicPart != null) { + return new PrecisionRectangle(topicPart.getFigure().getBounds()); + } + return new PrecisionRectangle(ref.x, ref.y, 0, 0); + } + + private PrecisionRectangle getChildrenBounds(IFigure figure) { + PrecisionRectangle r = null; + ITopicPart topicPart = branch.getTopicPart(); + if (topicPart != null) { + r = Geometry.union(r, + new PrecisionRectangle(topicPart.getFigure().getBounds())); + } + for (IBranchPart subBranch : branch.getSubBranches()) { + r = Geometry.union(r, + new PrecisionRectangle(subBranch.getFigure().getBounds())); + } + if (r != null) + return r; + return new PrecisionRectangle(figure.getBounds()); + } + + private PrecisionPoint getReference(IFigure figure) { + ITopicPart topicPart = branch.getTopicPart(); + if (topicPart != null) { + return new PrecisionPoint( + ((IReferencedFigure) topicPart.getFigure()).getReference()); + } + return new PrecisionPoint(figure.getBounds().getCenter()); + } + + public void invalidate() { + lineStart = null; + lineEnd = null; + tailTop = null; + tailBottom = null; + super.invalidate(); + } + + protected void performPaint(IFigure figure, Graphics graphics) { + if (lineStart == null || lineEnd == null || tailTop == null + || tailBottom == null) + return; + + ITopicDecoration topicDecoration = getTopicDecoration(); + if (topicDecoration == null) + return; + + Color lineColor = topicDecoration.getLineColor(); + Color fillColor = topicDecoration.getFillColor(); + + if (lineColor == null) + return; + + int lineWidth = Math.max(1, topicDecoration.getLineWidth()); + int lineStyle = topicDecoration.getLineStyle(); + + graphics.setAlpha(getAlpha()); + graphics.setLineStyle(lineStyle); + graphics.setAntialias(SWT.ON); + + Path shape = new Path(Display.getCurrent()); + if (branch.getConnections().isTapered()) { + graphics.setLineWidth(lineWidth); + shape.moveTo( + (float) lineStart.x + (lineStart.x < lineEnd.x ? -1 : 1), + (float) (lineStart.y - lineWidth * 5 - 0)); + shape.lineTo( + (float) lineStart.x + (lineStart.x < lineEnd.x ? -1 : 1), + (float) (lineStart.y + lineWidth * 5 + 0)); + shape.lineTo((float) lineEnd.x, + (float) (lineEnd.y + lineWidth * 0.5)); + shape.lineTo((float) lineEnd.x, + (float) (lineEnd.y - lineWidth * 0.5)); + shape.close(); + graphics.setBackgroundColor(lineColor); + graphics.fillPath(shape); + +// shape.moveTo(lineStart); +// shape.lineTo(lineEnd); +// graphics.setForegroundColor(lineColor); +// graphics.setLineWidth(lineWidth * 5); +// graphics.drawPath(shape); + } else { + shape.moveTo(lineStart); + shape.lineTo(lineEnd); + graphics.setForegroundColor(lineColor); + graphics.setLineWidth(lineWidth); + graphics.drawPath(shape); + } + shape.dispose(); + + shape = new Path(Display.getCurrent()); + shape.moveTo(lineEnd); + shape.lineTo(tailTop); + shape.lineTo(tailBottom); + shape.lineTo(lineEnd); + shape.close(); + + if (fillColor != null) { + Pattern pattern = null; + if (isGradient()) { + PrecisionRectangle r = new PrecisionRectangle(tailTop, + tailBottom).union(lineEnd); + pattern = createPattern(figure, getAlpha(), fillColor, r); + if (pattern != null) { + graphics.pushState(); + graphics.setBackgroundPattern(pattern); + } + } else { + graphics.setAlpha(getAlpha()); + graphics.setBackgroundColor(fillColor); + } + graphics.fillPath(shape); + if (pattern != null) { + graphics.popState(); + pattern.dispose(); + } + } + + if (lineColor != null) { + graphics.setForegroundColor(lineColor); + graphics.setLineWidth(lineWidth); + graphics.setLineStyle(lineStyle); + graphics.setAlpha(getAlpha()); + graphics.drawPath(shape); + } + + shape.dispose(); + } + + private ITopicDecoration getTopicDecoration() { + ITopicPart topicPart = branch.getTopicPart(); + if (topicPart != null) { + IFigure topicFigure = topicPart.getFigure(); + if (topicFigure instanceof IDecoratedFigure) { + IDecoration decoration = ((IDecoratedFigure) topicFigure) + .getDecoration(); + if (decoration instanceof ITopicDecoration) + return (ITopicDecoration) decoration; + } + } + return null; + } + + private Pattern createPattern(IFigure figure, int alpha, Color color, + PrecisionRectangle r) { + int delta = (int) (r.height * 0.4); + Pattern p = new GradientPattern(Display.getCurrent(), // + (float) r.x, (float) (r.y - delta), // + (float) r.x, (float) (r.y + r.height), // + ColorConstants.white, alpha, color, alpha); + return p; + } + + private boolean isGradient() { + ITopicPart topicPart = branch.getTopicPart(); + if (topicPart != null) { + IFigure figure = topicPart.getFigure(); + if (figure instanceof IDecoratedFigure) { + IDecoration decoration = ((IDecoratedFigure) figure) + .getDecoration(); + if (decoration instanceof IShapeDecoration) { + return ((IShapeDecoration) decoration).isGradient(); + } + } + } + return GEF.IS_PLATFORM_SUPPORT_GRADIENT; + } + +} diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/RightFishheadTopicDecoration.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/RightFishheadTopicDecoration.java index 8a8fd7e70..41ffcea03 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/RightFishheadTopicDecoration.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/RightFishheadTopicDecoration.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.graphics.Path; - -public class RightFishheadTopicDecoration extends FishheadTopicDecoration { - - public RightFishheadTopicDecoration() { - super(true); - } - - public Path createClippingPath(IFigure figure) { - Path shape = new Path(Display.getCurrent()); - Rectangle box = getOutlineBox(figure); - - Insets ins = figure.getInsets(); - Rectangle clientArea = box.getShrinked(ins); - - float x = box.right() - - clientArea.width * FishheadTopicDecoration.headConScale; - float y = box.y + box.height * 0.5f; - - shape.moveTo(box.x, box.bottom()); - - shape.quadTo(x, box.bottom(), box.right(), y); - - shape.quadTo(x, box.y, box.x, box.y); - - shape.close(); - - return shape; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.graphics.Path; + +public class RightFishheadTopicDecoration extends FishheadTopicDecoration { + + public RightFishheadTopicDecoration() { + super(true); + } + + public Path createClippingPath(IFigure figure) { + Path shape = new Path(Display.getCurrent()); + Rectangle box = getOutlineBox(figure); + + Insets ins = figure.getInsets(); + Rectangle clientArea = box.getShrinked(ins); + + float x = box.right() + - clientArea.width * FishheadTopicDecoration.headConScale; + float y = box.y + box.height * 0.5f; + + shape.moveTo(box.x, box.bottom()); + + shape.quadTo(x, box.bottom(), box.right(), y); + + shape.quadTo(x, box.y, box.x, box.y); + + shape.close(); + + return shape; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/AbstractSubFishboneDirection.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/AbstractSubFishboneDirection.java index 9d8c3576d..f3655dc8c 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/AbstractSubFishboneDirection.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/AbstractSubFishboneDirection.java @@ -1,101 +1,101 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.mindmap.IBranchPart; - -public abstract class AbstractSubFishboneDirection implements ISubDirection { - - private boolean rotated; - - private boolean downwards; - - private boolean rightHeaded; - - private boolean childrenTraverseReversed; - - private double rotateAngle; - - private int sourceOrientation; - - private int childTargetOrientation; - -// private String childNavType; - - protected AbstractSubFishboneDirection(double rotateAngle, - boolean downwards, boolean rightHeaded, - boolean childrenTraverseReversed, int sourceOrientation, - int childTargetOrientation) { - this.rotated = true; - this.rotateAngle = rotateAngle; - this.downwards = downwards; - this.rightHeaded = rightHeaded; - this.childrenTraverseReversed = childrenTraverseReversed; - this.sourceOrientation = sourceOrientation; - this.childTargetOrientation = childTargetOrientation; -// this.childNavType = childNavType; - } - - protected AbstractSubFishboneDirection(boolean downwards, - boolean rightHeaded, boolean childrenTraverseReversed, - int sourceOrientation, int childTargetOrientation) { - this.rotated = false; - this.rotateAngle = 0; - this.downwards = downwards; - this.rightHeaded = rightHeaded; - this.childrenTraverseReversed = childrenTraverseReversed; - this.sourceOrientation = sourceOrientation; - this.childTargetOrientation = childTargetOrientation; -// this.childNavType = childNavType; - } - - public int getSourceOrientation() { - return sourceOrientation; - } - - public int getChildTargetOrientation() { - return childTargetOrientation; - } - - public double getRotateAngle() { - return rotateAngle; - } - - public boolean isRotated() { - return rotated; - } - - public boolean isChildrenTraverseReversed() { - return childrenTraverseReversed; - } - - public boolean isDownwards() { - return downwards; - } - - public boolean isRightHeaded() { - return rightHeaded; - } - -// public String getChildNavigationType() { -// return childNavType; -// } - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.mindmap.IBranchPart; + +public abstract class AbstractSubFishboneDirection implements ISubDirection { + + private boolean rotated; + + private boolean downwards; + + private boolean rightHeaded; + + private boolean childrenTraverseReversed; + + private double rotateAngle; + + private int sourceOrientation; + + private int childTargetOrientation; + +// private String childNavType; + + protected AbstractSubFishboneDirection(double rotateAngle, + boolean downwards, boolean rightHeaded, + boolean childrenTraverseReversed, int sourceOrientation, + int childTargetOrientation) { + this.rotated = true; + this.rotateAngle = rotateAngle; + this.downwards = downwards; + this.rightHeaded = rightHeaded; + this.childrenTraverseReversed = childrenTraverseReversed; + this.sourceOrientation = sourceOrientation; + this.childTargetOrientation = childTargetOrientation; +// this.childNavType = childNavType; + } + + protected AbstractSubFishboneDirection(boolean downwards, + boolean rightHeaded, boolean childrenTraverseReversed, + int sourceOrientation, int childTargetOrientation) { + this.rotated = false; + this.rotateAngle = 0; + this.downwards = downwards; + this.rightHeaded = rightHeaded; + this.childrenTraverseReversed = childrenTraverseReversed; + this.sourceOrientation = sourceOrientation; + this.childTargetOrientation = childTargetOrientation; +// this.childNavType = childNavType; + } + + public int getSourceOrientation() { + return sourceOrientation; + } + + public int getChildTargetOrientation() { + return childTargetOrientation; + } + + public double getRotateAngle() { + return rotateAngle; + } + + public boolean isRotated() { + return rotated; + } + + public boolean isChildrenTraverseReversed() { + return childrenTraverseReversed; + } + + public boolean isDownwards() { + return downwards; + } + + public boolean isRightHeaded() { + return rightHeaded; + } + +// public String getChildNavigationType() { +// return childNavType; +// } + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneBranchHook.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneBranchHook.java index 904dd9338..e06807fa5 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneBranchHook.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneBranchHook.java @@ -1,188 +1,194 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IDecoratedFigure; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IPartListener; -import org.xmind.gef.part.PartEvent; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IRangeListener; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.RangeEvent; - -public class FishboneBranchHook implements IBranchHook, FigureListener, - IPartListener, IRangeListener { - - private IBranchPart branch; - -// private List topicListeners = new ArrayList(); -// -// private Map> rangeListeners = new HashMap>(); - - public void hook(IBranchPart branch) { - this.branch = branch; - branch.getFigure().addFigureListener(this); - branch.addPartListener(this); - for (IBoundaryPart b : branch.getBoundaries()) { - b.addRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.addRangeListener(this); - } -// ITopic topic = branch.getTopic(); -// if (topic instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) topic; -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryRemove, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryRemove, this)); -// topicListeners.add(source.registerCoreEventListener(Core.TopicAdd, -// this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.TopicRemove, this)); -// } -// for (IBoundary boundary : topic.getBoundaries()) { -// registerRangeListeners(boundary); -// } -// for (ISummary summary : topic.getSummaries()) { -// registerRangeListeners(summary); -// } - } - - public void unhook(IBranchPart branch) { -// unregister(topicListeners); -// for (List regs : rangeListeners.values()) { -// unregister(regs); -// } - for (IBoundaryPart b : branch.getBoundaries()) { - b.removeRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.removeRangeListener(this); - } - branch.removePartListener(this); - branch.getFigure().removeFigureListener(this); - updateSubBranches(branch); - } - -// private void unregister(List listeners) { -// for (ICoreEventRegistration reg : listeners) { -// reg.unregister(); -// } -// } - -// public void handleCoreEvent(CoreEvent event) { -// String type = event.getType(); -// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { -// Object range = event.getTarget(); -// registerRangeListeners(range); -// updateSubBranches(branch); -// } else if (Core.BoundaryRemove.equals(type) -// || Core.SummaryRemove.equals(type)) { -// Object range = event.getTarget(); -// List list = rangeListeners.remove(range); -// if (list != null) { -// unregister(list); -// } -// updateSubBranches(branch); -// } else if (Core.Range.equals(type)) {// || Core.EndIndex.equals(type)) { -//// } else if (Core.Range.equals(type) || Core.EndIndex.equals(type)) { -// if (isHeadBranch(branch)) { -// branch.getFigure().invalidate(); -// branch.update(); -// updateSubBranches(branch); -// } -// } else if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) { -// if (ITopic.ATTACHED.equals(event.getData())) { -// updateSubBranches(branch); -// } -// } -// } - -// private boolean isHeadBranch(IBranchPart branch) { -// IBranchPart parent = branch.getParentBranch(); -// if (parent == null) -// return true; -// String parentPolicyId = parent.getBranchPolicyId(); -// return !branch.getBranchPolicyId().equals(parentPolicyId); -//// String structureId = (String) branch.getCacheManager().getCache( -//// IBranchPolicy.CACHE_STRUCTURE_ALGORITHM_ID); -//// return Fishbone.STRUCTURE_LEFT_HEADED.equals(structureId) -//// || Fishbone.STRUCTURE_RIGHT_HEADED.equals(structureId); -// } - -// private void registerRangeListeners(Object range) { -// if (range instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) range; -// List list = new ArrayList(); -// list.add(source.registerCoreEventListener(Core.Range, this)); -// //list.add(source.registerCoreEventListener(Core.EndIndex, this)); -// rangeListeners.put(range, list); -// } -// } - - public void figureMoved(IFigure source) { - IDecoration decoration = ((IDecoratedFigure) branch.getFigure()) - .getDecoration(); - if (decoration != null) { - decoration.invalidate(); - } - } - - private void updateSubBranches(IBranchPart branch) { - for (IBranchPart subBranch : branch.getSubBranches()) { - flushChildStructureType(subBranch); - subBranch.treeUpdate(false); - } - } - - private void flushChildStructureType(IBranchPart subBranch) { - subBranch.getBranchPolicy().flushStructureCache(subBranch, false, true); - } - - public void childAdded(PartEvent event) { - if (event.child instanceof IBranchPart) { - updateSubBranches(branch); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - updateSubBranches(branch); - ((IBranchRangePart) event.child).addRangeListener(this); - } - } - - public void childRemoving(PartEvent event) { - if (event.child instanceof IBranchPart) { - updateSubBranches(branch); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - updateSubBranches(branch); - ((IBranchRangePart) event.child).removeRangeListener(this); - } - } - - public void rangeChanged(RangeEvent event) { - updateSubBranches(branch); - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IDecoratedFigure; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IPartListener2; +import org.xmind.gef.part.PartEvent; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IRangeListener; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.RangeEvent; + +public class FishboneBranchHook + implements IBranchHook, FigureListener, IPartListener2, IRangeListener { + + private IBranchPart branch; + +// private List topicListeners = new ArrayList(); +// +// private Map> rangeListeners = new HashMap>(); + + public void hook(IBranchPart branch) { + this.branch = branch; + branch.getFigure().addFigureListener(this); + branch.addPartListener(this); + for (IBoundaryPart b : branch.getBoundaries()) { + b.addRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.addRangeListener(this); + } +// ITopic topic = branch.getTopic(); +// if (topic instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) topic; +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryRemove, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryRemove, this)); +// topicListeners.add(source.registerCoreEventListener(Core.TopicAdd, +// this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.TopicRemove, this)); +// } +// for (IBoundary boundary : topic.getBoundaries()) { +// registerRangeListeners(boundary); +// } +// for (ISummary summary : topic.getSummaries()) { +// registerRangeListeners(summary); +// } + } + + public void unhook(IBranchPart branch) { +// unregister(topicListeners); +// for (List regs : rangeListeners.values()) { +// unregister(regs); +// } + for (IBoundaryPart b : branch.getBoundaries()) { + b.removeRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.removeRangeListener(this); + } + branch.removePartListener(this); + branch.getFigure().removeFigureListener(this); + updateSubBranches(branch); + } + +// private void unregister(List listeners) { +// for (ICoreEventRegistration reg : listeners) { +// reg.unregister(); +// } +// } + +// public void handleCoreEvent(CoreEvent event) { +// String type = event.getType(); +// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { +// Object range = event.getTarget(); +// registerRangeListeners(range); +// updateSubBranches(branch); +// } else if (Core.BoundaryRemove.equals(type) +// || Core.SummaryRemove.equals(type)) { +// Object range = event.getTarget(); +// List list = rangeListeners.remove(range); +// if (list != null) { +// unregister(list); +// } +// updateSubBranches(branch); +// } else if (Core.Range.equals(type)) {// || Core.EndIndex.equals(type)) { +//// } else if (Core.Range.equals(type) || Core.EndIndex.equals(type)) { +// if (isHeadBranch(branch)) { +// branch.getFigure().invalidate(); +// branch.update(); +// updateSubBranches(branch); +// } +// } else if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) { +// if (ITopic.ATTACHED.equals(event.getData())) { +// updateSubBranches(branch); +// } +// } +// } + +// private boolean isHeadBranch(IBranchPart branch) { +// IBranchPart parent = branch.getParentBranch(); +// if (parent == null) +// return true; +// String parentPolicyId = parent.getBranchPolicyId(); +// return !branch.getBranchPolicyId().equals(parentPolicyId); +//// String structureId = (String) branch.getCacheManager().getCache( +//// IBranchPolicy.CACHE_STRUCTURE_ALGORITHM_ID); +//// return Fishbone.STRUCTURE_LEFT_HEADED.equals(structureId) +//// || Fishbone.STRUCTURE_RIGHT_HEADED.equals(structureId); +// } + +// private void registerRangeListeners(Object range) { +// if (range instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) range; +// List list = new ArrayList(); +// list.add(source.registerCoreEventListener(Core.Range, this)); +// //list.add(source.registerCoreEventListener(Core.EndIndex, this)); +// rangeListeners.put(range, list); +// } +// } + + public void figureMoved(IFigure source) { + IDecoration decoration = ((IDecoratedFigure) branch.getFigure()) + .getDecoration(); + if (decoration != null) { + decoration.invalidate(); + } + } + + private void updateSubBranches(IBranchPart branch) { + for (IBranchPart subBranch : branch.getSubBranches()) { + flushChildStructureType(subBranch); + subBranch.treeUpdate(false); + } + } + + private void flushChildStructureType(IBranchPart subBranch) { + subBranch.getBranchPolicy().flushStructureCache(subBranch, false, true); + } + + public void childAdding(PartEvent event) { + } + + public void childAdded(PartEvent event) { + if (event.child instanceof IBranchPart) { + updateSubBranches(branch); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + updateSubBranches(branch); + ((IBranchRangePart) event.child).addRangeListener(this); + } + } + + public void childRemoving(PartEvent event) { + } + + public void childRemoved(PartEvent event) { + if (event.child instanceof IBranchPart) { + updateSubBranches(branch); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + updateSubBranches(branch); + ((IBranchRangePart) event.child).removeRangeListener(this); + } + } + + public void rangeChanged(RangeEvent event) { + updateSubBranches(branch); + } + +} diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneData.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneData.java index b0da82be5..811b09a0f 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneData.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/FishboneData.java @@ -1,71 +1,71 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.ui.mindmap.IBranchPart; - -public class FishboneData { - - public PrecisionInsets topicRefIns; - - public PrecisionInsets rTopicRefIns; - - public PrecisionInsets branchRefIns; - - public PrecisionInsets rBranchRefIns; - - private Map childOffsets = null; - - public void addChildOffset(IBranchPart subBranch, PrecisionPoint offset) { - if (childOffsets == null) - childOffsets = new HashMap(); - childOffsets.put(subBranch, offset); - } - - private PrecisionPoint getChildOffset(IBranchPart subBranch) { - return childOffsets == null ? null : childOffsets.get(subBranch); - } - - private PrecisionPoint getChildPrefRef(IBranchPart subBranch, - PrecisionPoint ref) { - - PrecisionPoint offset = getChildOffset(subBranch); - return offset == null ? null : ref.getTranslated(offset); - } - - public Rectangle getChildPrefBounds(IBranchPart subBranch, - PrecisionPoint ref) { - - PrecisionPoint childRef = getChildPrefRef(subBranch, ref); - if (childRef != null) { - Point draw2DPoint = childRef.toDraw2DPoint(); - IReferencedFigure figure = (IReferencedFigure) subBranch - .getFigure(); - - Rectangle bounds = figure.getPreferredBounds(draw2DPoint); - - return bounds; - } - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.ui.mindmap.IBranchPart; + +public class FishboneData { + + public PrecisionInsets topicRefIns; + + public PrecisionInsets rTopicRefIns; + + public PrecisionInsets branchRefIns; + + public PrecisionInsets rBranchRefIns; + + private Map childOffsets = null; + + public void addChildOffset(IBranchPart subBranch, PrecisionPoint offset) { + if (childOffsets == null) + childOffsets = new HashMap(); + childOffsets.put(subBranch, offset); + } + + private PrecisionPoint getChildOffset(IBranchPart subBranch) { + return childOffsets == null ? null : childOffsets.get(subBranch); + } + + private PrecisionPoint getChildPrefRef(IBranchPart subBranch, + PrecisionPoint ref) { + + PrecisionPoint offset = getChildOffset(subBranch); + return offset == null ? null : ref.getTranslated(offset); + } + + public Rectangle getChildPrefBounds(IBranchPart subBranch, + PrecisionPoint ref) { + + PrecisionPoint childRef = getChildPrefRef(subBranch, ref); + if (childRef != null) { + Point draw2DPoint = childRef.toDraw2DPoint(); + IReferencedFigure figure = (IReferencedFigure) subBranch + .getFigure(); + + Rectangle bounds = figure.getPreferredBounds(draw2DPoint); + + return bounds; + } + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/ISubDirection.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/ISubDirection.java index 792755ca1..6230dfbe9 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/ISubDirection.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/ISubDirection.java @@ -1,78 +1,78 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.PositionConstants; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.mindmap.IBranchPart; - -public interface ISubDirection extends PositionConstants { - - ISubDirection NER = new NorthEastRotated(); - - ISubDirection NE = new NorthEastNormal(); - - ISubDirection SER = new SouthEastRotated(); - - ISubDirection SE = new SouthEastNormal(); - - ISubDirection NWR = new NorthWestRotated(); - - ISubDirection NW = new NorthWestNormal(); - - ISubDirection SWR = new SouthWestRotated(); - - ISubDirection SW = new SouthWestNormal(); - - boolean isRotated(); - - boolean isRightHeaded(); - - boolean isDownwards(); - - boolean isChildrenTraverseReversed(); - - int getSourceOrientation(); - - int getChildTargetOrientation(); - -// /** -// * Returns the request type with which a navigation request is performed -// * into navigating to a fishbone branch's child. -// * -// * @return one of {@link org.xmind.gef.GEF#REQ_NAV_UP}, -// * {@link org.xmind.gef.GEF#REQ_NAV_DOWN}, -// * {@link org.xmind.gef.GEF#REQ_NAV_LEFT}, -// * {@link org.xmind.gef.GEF#REQ_NAV_RIGHT} -// */ -// String getChildNavigationType(); - -// int calcNavigation(int direction); - - double getRotateAngle(); - - ISubDirection getSubDirection(); - - void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches); - - void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.PositionConstants; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.mindmap.IBranchPart; + +public interface ISubDirection extends PositionConstants { + + ISubDirection NER = new NorthEastRotated(); + + ISubDirection NE = new NorthEastNormal(); + + ISubDirection SER = new SouthEastRotated(); + + ISubDirection SE = new SouthEastNormal(); + + ISubDirection NWR = new NorthWestRotated(); + + ISubDirection NW = new NorthWestNormal(); + + ISubDirection SWR = new SouthWestRotated(); + + ISubDirection SW = new SouthWestNormal(); + + boolean isRotated(); + + boolean isRightHeaded(); + + boolean isDownwards(); + + boolean isChildrenTraverseReversed(); + + int getSourceOrientation(); + + int getChildTargetOrientation(); + +// /** +// * Returns the request type with which a navigation request is performed +// * into navigating to a fishbone branch's child. +// * +// * @return one of {@link org.xmind.gef.GEF#REQ_NAV_UP}, +// * {@link org.xmind.gef.GEF#REQ_NAV_DOWN}, +// * {@link org.xmind.gef.GEF#REQ_NAV_LEFT}, +// * {@link org.xmind.gef.GEF#REQ_NAV_RIGHT} +// */ +// String getChildNavigationType(); + +// int calcNavigation(int direction); + + double getRotateAngle(); + + ISubDirection getSubDirection(); + + void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches); + + void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/LeftHeadedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/LeftHeadedStructure.java index b48b4e0c3..4135f86d7 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/LeftHeadedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/LeftHeadedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class LeftHeadedStructure extends MainFishboneStructure { - - public LeftHeadedStructure() { - super(IMainDirection.LeftHeaded); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class LeftHeadedStructure extends MainFishboneStructure { + + public LeftHeadedStructure() { + super(IMainDirection.LeftHeaded); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneData.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneData.java index 5913c6893..20dec5528 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneData.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneData.java @@ -1,85 +1,85 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.gef.draw2d.geometry.HorizontalFlipper; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; -import org.xmind.gef.draw2d.geometry.PrecisionVerticalFlipper; -import org.xmind.ui.branch.BranchStructureData; -import org.xmind.ui.mindmap.IBranchPart; - -public class MainFishboneData extends BranchStructureData { - - private Set upwardBranches = null; - - public final ITransformer hf = new HorizontalFlipper(); - - public final IPrecisionTransformer phf = new PrecisionHorizontalFlipper(); - - public final IPrecisionTransformer pvf = new PrecisionVerticalFlipper(); - - public final Side upSide = new Side(); - - public final Side downSide = new Side(); - - public MainFishboneData(IBranchPart branch, boolean transformerEnabled) { - super(branch); - this.hf.setEnabled(transformerEnabled); - this.phf.setEnabled(transformerEnabled); - } - - public void setOrigin(Point origin) { - hf.setOrigin(origin); - phf.setOrigin(origin.x, origin.y); - pvf.setOrigin(phf.getOrigin()); - } - - public boolean isUpwardBranch(int index) { - return getUpwardBranches().contains(index); - } - - private Set getUpwardBranches() { - if (upwardBranches == null) { - upwardBranches = calcUpwardBranches(); - } - return upwardBranches; - } - - private Set calcUpwardBranches() { - HashSet set = new HashSet(); - int i = 0; - IBranchPart lastChild = null; - boolean upwards = true; - for (IBranchPart subBranch : getBranch().getSubBranches()) { - if (lastChild == null) { - set.add(i); - } else { - if (!isInSameRange(lastChild, subBranch)) { - upwards = !upwards; - } - if (upwards) - set.add(i); - } - lastChild = subBranch; - i++; - } - return set; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.draw2d.geometry.HorizontalFlipper; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; +import org.xmind.gef.draw2d.geometry.PrecisionVerticalFlipper; +import org.xmind.ui.branch.BranchStructureData; +import org.xmind.ui.mindmap.IBranchPart; + +public class MainFishboneData extends BranchStructureData { + + private Set upwardBranches = null; + + public final ITransformer hf = new HorizontalFlipper(); + + public final IPrecisionTransformer phf = new PrecisionHorizontalFlipper(); + + public final IPrecisionTransformer pvf = new PrecisionVerticalFlipper(); + + public final Side upSide = new Side(); + + public final Side downSide = new Side(); + + public MainFishboneData(IBranchPart branch, boolean transformerEnabled) { + super(branch); + this.hf.setEnabled(transformerEnabled); + this.phf.setEnabled(transformerEnabled); + } + + public void setOrigin(Point origin) { + hf.setOrigin(origin); + phf.setOrigin(origin.x, origin.y); + pvf.setOrigin(phf.getOrigin()); + } + + public boolean isUpwardBranch(int index) { + return getUpwardBranches().contains(index); + } + + private Set getUpwardBranches() { + if (upwardBranches == null) { + upwardBranches = calcUpwardBranches(); + } + return upwardBranches; + } + + private Set calcUpwardBranches() { + HashSet set = new HashSet(); + int i = 0; + IBranchPart lastChild = null; + boolean upwards = true; + for (IBranchPart subBranch : getBranch().getSubBranches()) { + if (lastChild == null) { + set.add(i); + } else { + if (!isInSameRange(lastChild, subBranch)) { + upwards = !upwards; + } + if (upwards) + set.add(i); + } + lastChild = subBranch; + i++; + } + return set; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneStructure.java index 1d47f9c2d..f33c5c1d7 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/MainFishboneStructure.java @@ -1,661 +1,661 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.ReferencedLayoutData; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.internal.figures.TopicFigure; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.internal.fishbone.decorations.MainFishboneBranchDecoration; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.INodePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -@SuppressWarnings("restriction") -public class MainFishboneStructure extends AbstractBranchStructure { - - private static final double sin = Math.sin(Math - .toRadians(Fishbone.RotateAngle)); - - private static final double cos = Math.cos(Math - .toRadians(Fishbone.RotateAngle)); - - private static final double fMajor = 0.5d; - private static final double fMinor = 5d; - - private final IMainDirection direction; - - public MainFishboneStructure(IMainDirection direction) { - this.direction = direction; - } - - protected void addExtraSpaces(IBranchPart branch, ReferencedLayoutData data) { - super.addExtraSpaces(branch, data); - Insets insets = new Insets(); - if (direction == IMainDirection.LeftHeaded) { - insets.right = MainFishboneBranchDecoration.TailLength + 5; - } else { - insets.left = MainFishboneBranchDecoration.TailLength + 5; - } - data.addMargins(insets); - } - - protected void doFillPlusMinus(IBranchPart branch, - IPlusMinusPart plusMinus, LayoutInfo info) { - Point ref = info.getReference(); - MainFishboneData fd = getCastedData(branch); - fd.setOrigin(ref); - - Rectangle topicBounds = info.getCheckedClientArea(); - topicBounds = fd.hf.tr(topicBounds); - - IFigure figure = plusMinus.getFigure(); - Dimension size = figure.getPreferredSize(); - - int x = topicBounds.right() + 1; - int y = ref.y - size.height / 2; - - Rectangle r = new Rectangle(x, y, size.width, size.height); - info.put(figure, fd.hf.rr(r)); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - double mainSpacing = getMajorSpacing(branch) * fMajor; - double subSpacing = getMinorSpacing(branch) * fMinor; - - Point ref = info.getReference(); - MainFishboneData fd = getCastedData(branch); - fd.setOrigin(ref); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = fd.hf.tr(refBounds); - - fd.upSide.start(refBounds.right() + mainSpacing); - fd.downSide.start(fd.upSide.right + subSpacing); - - int num = subBranches.size(); - - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); -// int y = ref.y; - Side lastSide = fd.downSide; - double width = 0.0; - for (int i = 0; i < num; i++) { - IBranchPart subBranch = subBranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - - Insets ins = helper.getInsets(subBranch); - - boolean upwards = getCastedData(branch).isUpwardBranch(i); - Side side = upwards ? fd.upSide : fd.downSide; - - IPrecisionTransformer pvf = fd.pvf; - pvf.setEnabled(!upwards); - -// PrecisionInsets fChildBorder = pvf.ti(fd.phf -// .ti(new PrecisionInsets(subBranchFigure.getInsets()))); - PrecisionInsets fChildBorder = pvf.ti(fd.phf - .ti(new PrecisionInsets(ins))); - - if (fChildBorder.left != 0) { - side.useRight = false; - } - - PrecisionRectangle childBounds = new PrecisionRectangle(); - double joint; - double rotatedBottom; - - IBranchPolicy branchPolicy = subBranch.getBranchPolicy(); - IStructure sa = branchPolicy.getStructure(subBranch); - FishboneData sub = getFishboneData(subBranch, sa); - - if (sub != null) { - PrecisionInsets fChildBranchRotated = pvf.ti(fd.phf - .ti(sub.rBranchRefIns)); - PrecisionInsets fChildBranchNormal = fd.phf - .ti(sub.branchRefIns); - PrecisionInsets fChildTopicNormal = fd.phf.ti(sub.topicRefIns); - - double left = fChildBranchRotated.left + fChildBorder.left; - double bottom = fChildBranchRotated.bottom + mainSpacing - + fChildBorder.bottom; - - double jointOff = left - - (bottom * cos - fChildTopicNormal.bottom) / sin; - - if (side.useRight) { - double rotatedSpacing = (fChildBranchNormal.top + fChildTopicNormal.bottom) - / sin; - joint = side.rotatedBottom + rotatedSpacing; - } else { - joint = Math.max(side.right, side.right + jointOff); - } - if (!upwards || i > 0) { - joint = Math.max(joint, lastSide.lastJoint + subSpacing); - } - - Dimension size = subBranchFigure.getPreferredSize(); - childBounds.setSize(size.width, size.height); - - childBounds.x = joint - jointOff; - if (side == fd.upSide) { - childBounds.y = ref.y - size.height - mainSpacing - - fChildBorder.bottom; - } else { - childBounds.y = ref.y + mainSpacing + fChildBorder.bottom;/////////// - } - if (fChildBorder.getHeight() != 0) - if (width <= childBounds.right()) - width = childBounds.right(); - - rotatedBottom = joint - + (fChildBranchNormal.bottom - fChildTopicNormal.bottom) - / sin + subSpacing; - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - ((IReferencedFigure) subBranchFigure) - .getReferenceDescription()); - PrecisionInsets fChildBranchNormal = pvf.ti(fd.phf - .ti(childBranchNormal)); - double bottom = fChildBranchNormal.bottom + mainSpacing; - double rotatedSpacing = fChildBranchNormal.top * cos / sin; - if (side.useRight) { - joint = side.rotatedBottom + rotatedSpacing; - } else { - joint = side.right; - } - if (!upwards || i > 0) { - joint = Math.max(joint, lastSide.lastJoint + subSpacing); - } - double jointOff = bottom * cos / sin; - Dimension size = subBranchFigure.getPreferredSize(); - childBounds.setSize(size.width, size.height); - - childBounds.x = joint + jointOff; - if (side == fd.upSide) { - childBounds.y = ref.y - size.height - mainSpacing - - fChildBorder.bottom;//// - } else { - childBounds.y = ref.y + mainSpacing + fChildBorder.bottom;// - } - - if (fChildBorder.getHeight() != 0) - if (width <= childBounds.right()) - width = childBounds.right(); - - rotatedBottom = joint + fChildBranchNormal.getWidth() - + fChildBranchNormal.bottom * cos / sin + subSpacing; - } - - if (insertion != null && i >= insertion.getIndex()) { - childBounds.x += insertion.getSize().width; - } - - IPrecisionTransformer phf = fd.phf; - PrecisionRectangle precRect = phf.rr(childBounds); - Rectangle rect = precRect.toDraw2DRectangle(); - - info.put(subBranchFigure, rect); - - side.lastJoint = joint; - side.useRight = fChildBorder.right == 0; - side.rotatedBottom = rotatedBottom; - - if (side.useRight) - side.right = childBounds.right() + subSpacing / 3; - else - side.right = width + subSpacing / 3; - lastSide = side; - } - } - - private FishboneData getFishboneData(IBranchPart subBranch, IStructure sa) { - if (sa instanceof SubFishboneStructure) { - return ((SubFishboneStructure) sa).getCastedData(subBranch) - .getFishboneData(); - } - return null; - } - - protected Object createStructureData(IBranchPart branch) { - return new MainFishboneData(branch, direction.isTransformerEnabled()); - } - - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return super.isValidStructureData(branch, data) - && (data instanceof MainFishboneData); - } - - protected MainFishboneData getCastedData(IBranchPart branch) { - return (MainFishboneData) super.getStructureData(branch); - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - Point childRef = key.getFigure().getReference(); - Point branchRef = getReference(branch); - MainFishboneData fd = getCastedData(branch); - fd.setOrigin(branchRef); - PrecisionPoint source = calcSourceAnchorLocation(branch); - int jointOffset = calcChildJointOffset(branch, key.getFeedback(), - source); - if (jointOffset > 0) { - int range; - Rectangle childrenNodesBounds = getChildrenNodesBounds(branch); - if (childrenNodesBounds != null) { - Rectangle r = fd.hf.tr(childrenNodesBounds); - range = r.right() - branchRef.x + MindMapUI.SEARCH_RANGE / 2; - } else { - range = MindMapUI.SEARCH_RANGE; - } - if (jointOffset < range) { - int dy = Math.abs(childRef.y - branchRef.y); - if (dy < MindMapUI.SEARCH_RANGE) - return dy; - } - } - return super.calcChildDistance(branch, key); - } - - private PrecisionPoint calcSourceAnchorLocation(IBranchPart branch) { - return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) - .getLocation(getSourceOrientation(branch), 0); - } - - private Rectangle getChildrenNodesBounds(IBranchPart branch) { - Rectangle r = null; - for (IBranchPart subbranch : branch.getSubBranches()) { - r = Geometry.union(r, subbranch.getTopicPart().getFigure() - .getBounds()); - } - return r; - } - - private int calcChildJointOffset(IBranchPart branch, IBranchPart child, - PrecisionPoint source) { - double angle = calcChildRotateAngle(branch, child); - PrecisionPoint target = calcChildTargetLocation(branch, child, source); - PrecisionDimension d = target.getDifference(source); - int w = (int) Math.floor(d.height / Math.tan(Math.toRadians(angle)) - + 0.0000001); - int offset = (int) Math.floor(d.width - w + 0.0000001); - if (direction == IMainDirection.RightHeaded) - return -offset; - return offset; - } - - private PrecisionPoint calcChildTargetLocation(IBranchPart branch, - IBranchPart child, PrecisionPoint source) { - ITopicPart topic = child.getTopicPart(); - if (topic instanceof INodePart) { - IAnchor anchor = ((INodePart) topic).getTargetAnchor(branch); - if (anchor != null) { - return anchor.getLocation( - getChildTargetOrientation(branch, child), 0); - } - } - return new PrecisionPoint(getReference(child)); - } - - public boolean isChildUpwards(IBranchPart branch, IBranchPart child) { - return isChildUpwards(branch, child, - branch.getSubBranches().indexOf(child)); - } - - private boolean isChildUpwards(IBranchPart branch, IBranchPart child, - int childIndex) { - if (childIndex < 0) { - Point branchRef = getReference(branch); - Point childRef = getReference(child); - return childRef.y < branchRef.y; - } - return getCastedData(branch).isUpwardBranch(childIndex); - } - - private Point getReference(IBranchPart branch) { - ITopicPart topic = branch.getTopicPart(); - if (topic != null) - return ((IReferencedFigure) topic.getFigure()).getReference(); - return ((IReferencedFigure) branch.getFigure()).getReference(); - } - - private double calcChildRotateAngle(IBranchPart branch, IBranchPart child) { - return isChildUpwards(branch, child) ? direction.getUpRotated() - .getRotateAngle() : direction.getDownRotated().getRotateAngle(); -// return direction.getChildRotateAngle(isChildUpwards(branch, child)); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - PrecisionPoint source = calcSourceAnchorLocation(branch); - int jointOffset = calcChildJointOffset(branch, key.getFeedback(), - source); - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - - IInsertion lastInsertion = getCurrentInsertion(branch); - int ret = 0; - for (int i = 0; i < num; i++) { - IBranchPart subBranch = subBranches.get(i); - int j = calcChildJointOffset(branch, subBranch, source); - if (lastInsertion != null && i >= lastInsertion.getIndex()) { - j -= lastInsertion.getSize().width; - } - - int hint = j; - if (jointOffset < hint) - return ret; - if (withDisabled || subBranch.getFigure().isEnabled()) - ret++; - } - return withDisabled ? num : -1; - } - - private static final Dimension INSERTION_SIZE = new Dimension(30, 1); - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return new Insertion(branch, calcInsIndex(branch, key, true), - INSERTION_SIZE); - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_DOWN.equals(navReqType) - || GEF.REQ_NAV_UP.equals(navReqType)) { - int childIndex = sourceChild.getBranchIndex(); - boolean upwards = isChildUpwards(branch, sourceChild, childIndex); - if ((upwards && GEF.REQ_NAV_DOWN.equals(navReqType)) - || (!upwards && GEF.REQ_NAV_UP.equals(navReqType))) { - for (int i = childIndex - 1; i >= 0; i--) { - IBranchPart sub = branch.getSubBranches().get(i); - if (isChildUpwards(branch, sub, i) != upwards) - return sub.getTopicPart(); - } - return getSubTopicPart(branch, childIndex + 1); - } - } else { - boolean next = (direction == IMainDirection.LeftHeaded && GEF.REQ_NAV_RIGHT - .equals(navReqType)) - || (direction == IMainDirection.RightHeaded && GEF.REQ_NAV_LEFT - .equals(navReqType)); - boolean prev = (direction == IMainDirection.LeftHeaded && GEF.REQ_NAV_LEFT - .equals(navReqType)) - || (direction == IMainDirection.RightHeaded && GEF.REQ_NAV_RIGHT - .equals(navReqType)); - if (next || prev) { - int childIndex = sourceChild.getBranchIndex(); - boolean upwards = isChildUpwards(branch, sourceChild, - childIndex); - for (int i = prev ? childIndex - 1 : childIndex + 1; prev ? i >= 0 - : i < branch.getSubBranches().size();) { - IBranchPart sub = branch.getSubBranches().get(i); - if (isChildUpwards(branch, sourceChild, i) == upwards) { - return sub.getTopicPart(); - } - if (prev) { - i--; - } else { - i++; - } - } - if (prev && !sequential) { - IPart prevTopic = getSubTopicPart(branch, childIndex - 1); - if (prevTopic != null) - return prevTopic; - return branch.getTopicPart(); - } - return getSubTopicPart(branch, childIndex + 1); - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (direction == IMainDirection.RightHeaded) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } else { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } - return super.calcNavigation(branch, navReqType); - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - int index = branch.getSubBranches().indexOf(subBranch); - if (index < 0) - return direction == IMainDirection.RightHeaded ? PositionConstants.EAST - : PositionConstants.WEST; - if (isChildUpwards(branch, subBranch, index)) { - if (direction == IMainDirection.RightHeaded) - return PositionConstants.EAST; - return PositionConstants.WEST; - } - if (direction == IMainDirection.RightHeaded) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - - public int getSourceOrientation(IBranchPart branch) { - if (direction == IMainDirection.RightHeaded) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - if (direction == IMainDirection.RightHeaded) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - List enclosing = summary.getEnclosingBranches(); - if (!enclosing.isEmpty()) { - if (getCastedData(branch).isUpwardBranch( - enclosing.get(0).getBranchIndex())) - return PositionConstants.NORTH; - return PositionConstants.SOUTH; - } - return PositionConstants.NORTH; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.EAST) { - if (this.direction == IMainDirection.RightHeaded) - return -1; - return 1; - } else if (direction == PositionConstants.WEST) { - if (this.direction == IMainDirection.RightHeaded) - return 1; - return -1; - } - return super.getQuickMoveOffset(branch, child, direction); - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - int index = calcInsIndex(branch, key, true); - - if (index == subBranches.size()) { - return calcInventPosition(subBranches.get(index - 1), null, key, - false); - } - return calcInventPosition(subBranches.get(index), null, key, true); - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - Dimension inventSize = key.getInvent().getSize(); - boolean upWard = (index + 1) % 2 == 0; - boolean leftWard = IMainDirection.LeftHeaded.equals(direction); - - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - Dimension size = sub.getTopicPart().getFigure().getSize(); - - double w = (size.height * sin - size.width * cos) - / (sin * sin - cos * cos); - - double deltaX = size.width * 0.5d - w * cos + inventSize.width - * 0.5d + inventSize.width * cos * 0.5d; - double deltaY = upWard ? (-size.height + inventSize.width * sin) * 0.5d - : (size.height - inventSize.width * sin) * 0.5d; - - return getReference(sub).getTranslated(leftWard ? deltaX : -deltaX, - deltaY); - } - - return calcInsertPosition(branch, child, key); - } - - @Override - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isBeforeOrientation) { - Dimension inventSize = key.getInvent().getSize(); - Dimension insSize = key.getFigure().getSize(); - - double deltaY = inventSize.width * sin * 0.5d; - - boolean upwards = isChildUpwards(orientation.getParentBranch(), - orientation); - - double y = upwards ^ isBeforeOrientation ? deltaY : -deltaY; - - double x; - if (isBeforeOrientation) { - double offset = calcBeforeOffset(orientation); - - double deltaX = (insSize.height / sin - inventSize.width * cos - inventSize.width) * 0.5d; - - x = offset - + (direction.equals(IMainDirection.RightHeaded) ? deltaX - : -deltaX); - } else { - Rectangle pBounds = orientation.getParentBranch().getFigure() - .getBounds(); - - x = direction.equals(IMainDirection.RightHeaded) ? pBounds.x - : pBounds.right(); - } - - return new Point().getTranslated(x, y); - } - - private double calcBeforeOffset(IBranchPart branch) { - double offset = 0.0d; - double cot = cos / sin; - - List callouts = branch.getCalloutBranches(); - if (callouts == null || callouts.isEmpty()) { - IFigure figure = branch.getTopicPart().getFigure(); - Rectangle bounds = figure.getBounds(); - double height = ((TopicFigure) figure) - .getNormalPreferredBounds(new Point()).height; - double delta = height * cos * cot; - offset = direction.equals(IMainDirection.RightHeaded) ? bounds - .right() + delta : bounds.x - delta; - } else { - Rectangle bounds = branch.getFigure().getBounds(); - offset = direction.equals(IMainDirection.RightHeaded) ? bounds - .right() : bounds.x; - - for (IBranchPart callout : callouts) { - Rectangle calloutBounds = callout.getFigure().getBounds(); - if (direction.equals(ISubDirection.NE)) { - Point tl = calloutBounds.getTopLeft(); - offset = Math.min(offset, tl.x - (-tl.y) * cot); - } else if (direction.equals(ISubDirection.SE)) { - Point bl = calloutBounds.getBottomLeft(); - offset = Math.min(offset, bl.x - (bl.y) * cot); - } else if (direction.equals(ISubDirection.NW)) { - Point tr = calloutBounds.getTopRight(); - offset = Math.max(offset, tr.x + (tr.y) * cot); - } else { - Point br = calloutBounds.getBottomRight(); - offset = Math.max(offset, br.x + (br.y) * cot); - } - } - } - - return offset; - } - - @Override - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - double minorSpacing = getMinorSpacing(branch) * fMinor; - double x = branch.getFigure().getSize().width * 0.5d - + key.getFigure().getSize().width * 0.5d; - return getFigureLocation(branch.getFigure()).getTranslated( - IMainDirection.LeftHeaded.equals(direction) ? x : -x, - -minorSpacing); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.ReferencedLayoutData; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.internal.figures.TopicFigure; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.internal.fishbone.decorations.MainFishboneBranchDecoration; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.INodePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +@SuppressWarnings("restriction") +public class MainFishboneStructure extends AbstractBranchStructure { + + private static final double sin = Math.sin(Math + .toRadians(Fishbone.RotateAngle)); + + private static final double cos = Math.cos(Math + .toRadians(Fishbone.RotateAngle)); + + private static final double fMajor = 0.5d; + private static final double fMinor = 5d; + + private final IMainDirection direction; + + public MainFishboneStructure(IMainDirection direction) { + this.direction = direction; + } + + protected void addExtraSpaces(IBranchPart branch, ReferencedLayoutData data) { + super.addExtraSpaces(branch, data); + Insets insets = new Insets(); + if (direction == IMainDirection.LeftHeaded) { + insets.right = MainFishboneBranchDecoration.TailLength + 5; + } else { + insets.left = MainFishboneBranchDecoration.TailLength + 5; + } + data.addMargins(insets); + } + + protected void doFillPlusMinus(IBranchPart branch, + IPlusMinusPart plusMinus, LayoutInfo info) { + Point ref = info.getReference(); + MainFishboneData fd = getCastedData(branch); + fd.setOrigin(ref); + + Rectangle topicBounds = info.getCheckedClientArea(); + topicBounds = fd.hf.tr(topicBounds); + + IFigure figure = plusMinus.getFigure(); + Dimension size = figure.getPreferredSize(); + + int x = topicBounds.right() + 1; + int y = ref.y - size.height / 2; + + Rectangle r = new Rectangle(x, y, size.width, size.height); + info.put(figure, fd.hf.rr(r)); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + double mainSpacing = getMajorSpacing(branch) * fMajor; + double subSpacing = getMinorSpacing(branch) * fMinor; + + Point ref = info.getReference(); + MainFishboneData fd = getCastedData(branch); + fd.setOrigin(ref); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = fd.hf.tr(refBounds); + + fd.upSide.start(refBounds.right() + mainSpacing); + fd.downSide.start(fd.upSide.right + subSpacing); + + int num = subBranches.size(); + + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); +// int y = ref.y; + Side lastSide = fd.downSide; + double width = 0.0; + for (int i = 0; i < num; i++) { + IBranchPart subBranch = subBranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + + Insets ins = helper.getInsets(subBranch); + + boolean upwards = getCastedData(branch).isUpwardBranch(i); + Side side = upwards ? fd.upSide : fd.downSide; + + IPrecisionTransformer pvf = fd.pvf; + pvf.setEnabled(!upwards); + +// PrecisionInsets fChildBorder = pvf.ti(fd.phf +// .ti(new PrecisionInsets(subBranchFigure.getInsets()))); + PrecisionInsets fChildBorder = pvf.ti(fd.phf + .ti(new PrecisionInsets(ins))); + + if (fChildBorder.left != 0) { + side.useRight = false; + } + + PrecisionRectangle childBounds = new PrecisionRectangle(); + double joint; + double rotatedBottom; + + IBranchPolicy branchPolicy = subBranch.getBranchPolicy(); + IStructure sa = branchPolicy.getStructure(subBranch); + FishboneData sub = getFishboneData(subBranch, sa); + + if (sub != null) { + PrecisionInsets fChildBranchRotated = pvf.ti(fd.phf + .ti(sub.rBranchRefIns)); + PrecisionInsets fChildBranchNormal = fd.phf + .ti(sub.branchRefIns); + PrecisionInsets fChildTopicNormal = fd.phf.ti(sub.topicRefIns); + + double left = fChildBranchRotated.left + fChildBorder.left; + double bottom = fChildBranchRotated.bottom + mainSpacing + + fChildBorder.bottom; + + double jointOff = left + - (bottom * cos - fChildTopicNormal.bottom) / sin; + + if (side.useRight) { + double rotatedSpacing = (fChildBranchNormal.top + fChildTopicNormal.bottom) + / sin; + joint = side.rotatedBottom + rotatedSpacing; + } else { + joint = Math.max(side.right, side.right + jointOff); + } + if (!upwards || i > 0) { + joint = Math.max(joint, lastSide.lastJoint + subSpacing); + } + + Dimension size = subBranchFigure.getPreferredSize(); + childBounds.setSize(size.width, size.height); + + childBounds.x = joint - jointOff; + if (side == fd.upSide) { + childBounds.y = ref.y - size.height - mainSpacing + - fChildBorder.bottom; + } else { + childBounds.y = ref.y + mainSpacing + fChildBorder.bottom;/////////// + } + if (fChildBorder.getHeight() != 0) + if (width <= childBounds.right()) + width = childBounds.right(); + + rotatedBottom = joint + + (fChildBranchNormal.bottom - fChildTopicNormal.bottom) + / sin + subSpacing; + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + ((IReferencedFigure) subBranchFigure) + .getReferenceDescription()); + PrecisionInsets fChildBranchNormal = pvf.ti(fd.phf + .ti(childBranchNormal)); + double bottom = fChildBranchNormal.bottom + mainSpacing; + double rotatedSpacing = fChildBranchNormal.top * cos / sin; + if (side.useRight) { + joint = side.rotatedBottom + rotatedSpacing; + } else { + joint = side.right; + } + if (!upwards || i > 0) { + joint = Math.max(joint, lastSide.lastJoint + subSpacing); + } + double jointOff = bottom * cos / sin; + Dimension size = subBranchFigure.getPreferredSize(); + childBounds.setSize(size.width, size.height); + + childBounds.x = joint + jointOff; + if (side == fd.upSide) { + childBounds.y = ref.y - size.height - mainSpacing + - fChildBorder.bottom;//// + } else { + childBounds.y = ref.y + mainSpacing + fChildBorder.bottom;// + } + + if (fChildBorder.getHeight() != 0) + if (width <= childBounds.right()) + width = childBounds.right(); + + rotatedBottom = joint + fChildBranchNormal.getWidth() + + fChildBranchNormal.bottom * cos / sin + subSpacing; + } + + if (insertion != null && i >= insertion.getIndex()) { + childBounds.x += insertion.getSize().width; + } + + IPrecisionTransformer phf = fd.phf; + PrecisionRectangle precRect = phf.rr(childBounds); + Rectangle rect = precRect.toDraw2DRectangle(); + + info.put(subBranchFigure, rect); + + side.lastJoint = joint; + side.useRight = fChildBorder.right == 0; + side.rotatedBottom = rotatedBottom; + + if (side.useRight) + side.right = childBounds.right() + subSpacing / 3; + else + side.right = width + subSpacing / 3; + lastSide = side; + } + } + + private FishboneData getFishboneData(IBranchPart subBranch, IStructure sa) { + if (sa instanceof SubFishboneStructure) { + return ((SubFishboneStructure) sa).getCastedData(subBranch) + .getFishboneData(); + } + return null; + } + + protected Object createStructureData(IBranchPart branch) { + return new MainFishboneData(branch, direction.isTransformerEnabled()); + } + + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return super.isValidStructureData(branch, data) + && (data instanceof MainFishboneData); + } + + protected MainFishboneData getCastedData(IBranchPart branch) { + return (MainFishboneData) super.getStructureData(branch); + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + Point childRef = key.getFigure().getReference(); + Point branchRef = getReference(branch); + MainFishboneData fd = getCastedData(branch); + fd.setOrigin(branchRef); + PrecisionPoint source = calcSourceAnchorLocation(branch); + int jointOffset = calcChildJointOffset(branch, key.getFeedback(), + source); + if (jointOffset > 0) { + int range; + Rectangle childrenNodesBounds = getChildrenNodesBounds(branch); + if (childrenNodesBounds != null) { + Rectangle r = fd.hf.tr(childrenNodesBounds); + range = r.right() - branchRef.x + MindMapUI.SEARCH_RANGE / 2; + } else { + range = MindMapUI.SEARCH_RANGE; + } + if (jointOffset < range) { + int dy = Math.abs(childRef.y - branchRef.y); + if (dy < MindMapUI.SEARCH_RANGE) + return dy; + } + } + return super.calcChildDistance(branch, key); + } + + private PrecisionPoint calcSourceAnchorLocation(IBranchPart branch) { + return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) + .getLocation(getSourceOrientation(branch), 0); + } + + private Rectangle getChildrenNodesBounds(IBranchPart branch) { + Rectangle r = null; + for (IBranchPart subbranch : branch.getSubBranches()) { + r = Geometry.union(r, subbranch.getTopicPart().getFigure() + .getBounds()); + } + return r; + } + + private int calcChildJointOffset(IBranchPart branch, IBranchPart child, + PrecisionPoint source) { + double angle = calcChildRotateAngle(branch, child); + PrecisionPoint target = calcChildTargetLocation(branch, child, source); + PrecisionDimension d = target.getDifference(source); + int w = (int) Math.floor(d.height / Math.tan(Math.toRadians(angle)) + + 0.0000001); + int offset = (int) Math.floor(d.width - w + 0.0000001); + if (direction == IMainDirection.RightHeaded) + return -offset; + return offset; + } + + private PrecisionPoint calcChildTargetLocation(IBranchPart branch, + IBranchPart child, PrecisionPoint source) { + ITopicPart topic = child.getTopicPart(); + if (topic instanceof INodePart) { + IAnchor anchor = ((INodePart) topic).getTargetAnchor(branch); + if (anchor != null) { + return anchor.getLocation( + getChildTargetOrientation(branch, child), 0); + } + } + return new PrecisionPoint(getReference(child)); + } + + public boolean isChildUpwards(IBranchPart branch, IBranchPart child) { + return isChildUpwards(branch, child, + branch.getSubBranches().indexOf(child)); + } + + private boolean isChildUpwards(IBranchPart branch, IBranchPart child, + int childIndex) { + if (childIndex < 0) { + Point branchRef = getReference(branch); + Point childRef = getReference(child); + return childRef.y < branchRef.y; + } + return getCastedData(branch).isUpwardBranch(childIndex); + } + + private Point getReference(IBranchPart branch) { + ITopicPart topic = branch.getTopicPart(); + if (topic != null) + return ((IReferencedFigure) topic.getFigure()).getReference(); + return ((IReferencedFigure) branch.getFigure()).getReference(); + } + + private double calcChildRotateAngle(IBranchPart branch, IBranchPart child) { + return isChildUpwards(branch, child) ? direction.getUpRotated() + .getRotateAngle() : direction.getDownRotated().getRotateAngle(); +// return direction.getChildRotateAngle(isChildUpwards(branch, child)); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + PrecisionPoint source = calcSourceAnchorLocation(branch); + int jointOffset = calcChildJointOffset(branch, key.getFeedback(), + source); + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + + IInsertion lastInsertion = getCurrentInsertion(branch); + int ret = 0; + for (int i = 0; i < num; i++) { + IBranchPart subBranch = subBranches.get(i); + int j = calcChildJointOffset(branch, subBranch, source); + if (lastInsertion != null && i >= lastInsertion.getIndex()) { + j -= lastInsertion.getSize().width; + } + + int hint = j; + if (jointOffset < hint) + return ret; + if (withDisabled || subBranch.getFigure().isEnabled()) + ret++; + } + return withDisabled ? num : -1; + } + + private static final Dimension INSERTION_SIZE = new Dimension(30, 1); + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return new Insertion(branch, calcInsIndex(branch, key, true), + INSERTION_SIZE); + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_DOWN.equals(navReqType) + || GEF.REQ_NAV_UP.equals(navReqType)) { + int childIndex = sourceChild.getBranchIndex(); + boolean upwards = isChildUpwards(branch, sourceChild, childIndex); + if ((upwards && GEF.REQ_NAV_DOWN.equals(navReqType)) + || (!upwards && GEF.REQ_NAV_UP.equals(navReqType))) { + for (int i = childIndex - 1; i >= 0; i--) { + IBranchPart sub = branch.getSubBranches().get(i); + if (isChildUpwards(branch, sub, i) != upwards) + return sub.getTopicPart(); + } + return getSubTopicPart(branch, childIndex + 1); + } + } else { + boolean next = (direction == IMainDirection.LeftHeaded && GEF.REQ_NAV_RIGHT + .equals(navReqType)) + || (direction == IMainDirection.RightHeaded && GEF.REQ_NAV_LEFT + .equals(navReqType)); + boolean prev = (direction == IMainDirection.LeftHeaded && GEF.REQ_NAV_LEFT + .equals(navReqType)) + || (direction == IMainDirection.RightHeaded && GEF.REQ_NAV_RIGHT + .equals(navReqType)); + if (next || prev) { + int childIndex = sourceChild.getBranchIndex(); + boolean upwards = isChildUpwards(branch, sourceChild, + childIndex); + for (int i = prev ? childIndex - 1 : childIndex + 1; prev ? i >= 0 + : i < branch.getSubBranches().size();) { + IBranchPart sub = branch.getSubBranches().get(i); + if (isChildUpwards(branch, sourceChild, i) == upwards) { + return sub.getTopicPart(); + } + if (prev) { + i--; + } else { + i++; + } + } + if (prev && !sequential) { + IPart prevTopic = getSubTopicPart(branch, childIndex - 1); + if (prevTopic != null) + return prevTopic; + return branch.getTopicPart(); + } + return getSubTopicPart(branch, childIndex + 1); + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (direction == IMainDirection.RightHeaded) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } else { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } + return super.calcNavigation(branch, navReqType); + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + int index = branch.getSubBranches().indexOf(subBranch); + if (index < 0) + return direction == IMainDirection.RightHeaded ? PositionConstants.EAST + : PositionConstants.WEST; + if (isChildUpwards(branch, subBranch, index)) { + if (direction == IMainDirection.RightHeaded) + return PositionConstants.EAST; + return PositionConstants.WEST; + } + if (direction == IMainDirection.RightHeaded) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + + public int getSourceOrientation(IBranchPart branch) { + if (direction == IMainDirection.RightHeaded) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + if (direction == IMainDirection.RightHeaded) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + List enclosing = summary.getEnclosingBranches(); + if (!enclosing.isEmpty()) { + if (getCastedData(branch).isUpwardBranch( + enclosing.get(0).getBranchIndex())) + return PositionConstants.NORTH; + return PositionConstants.SOUTH; + } + return PositionConstants.NORTH; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.EAST) { + if (this.direction == IMainDirection.RightHeaded) + return -1; + return 1; + } else if (direction == PositionConstants.WEST) { + if (this.direction == IMainDirection.RightHeaded) + return 1; + return -1; + } + return super.getQuickMoveOffset(branch, child, direction); + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + int index = calcInsIndex(branch, key, true); + + if (index == subBranches.size()) { + return calcInventPosition(subBranches.get(index - 1), null, key, + false); + } + return calcInventPosition(subBranches.get(index), null, key, true); + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + Dimension inventSize = key.getInvent().getSize(); + boolean upWard = (index + 1) % 2 == 0; + boolean leftWard = IMainDirection.LeftHeaded.equals(direction); + + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + Dimension size = sub.getTopicPart().getFigure().getSize(); + + double w = (size.height * sin - size.width * cos) + / (sin * sin - cos * cos); + + double deltaX = size.width * 0.5d - w * cos + inventSize.width + * 0.5d + inventSize.width * cos * 0.5d; + double deltaY = upWard ? (-size.height + inventSize.width * sin) * 0.5d + : (size.height - inventSize.width * sin) * 0.5d; + + return getReference(sub).getTranslated(leftWard ? deltaX : -deltaX, + deltaY); + } + + return calcInsertPosition(branch, child, key); + } + + @Override + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isBeforeOrientation) { + Dimension inventSize = key.getInvent().getSize(); + Dimension insSize = key.getFigure().getSize(); + + double deltaY = inventSize.width * sin * 0.5d; + + boolean upwards = isChildUpwards(orientation.getParentBranch(), + orientation); + + double y = upwards ^ isBeforeOrientation ? deltaY : -deltaY; + + double x; + if (isBeforeOrientation) { + double offset = calcBeforeOffset(orientation); + + double deltaX = (insSize.height / sin - inventSize.width * cos - inventSize.width) * 0.5d; + + x = offset + + (direction.equals(IMainDirection.RightHeaded) ? deltaX + : -deltaX); + } else { + Rectangle pBounds = orientation.getParentBranch().getFigure() + .getBounds(); + + x = direction.equals(IMainDirection.RightHeaded) ? pBounds.x + : pBounds.right(); + } + + return new Point().getTranslated(x, y); + } + + private double calcBeforeOffset(IBranchPart branch) { + double offset = 0.0d; + double cot = cos / sin; + + List callouts = branch.getCalloutBranches(); + if (callouts == null || callouts.isEmpty()) { + IFigure figure = branch.getTopicPart().getFigure(); + Rectangle bounds = figure.getBounds(); + double height = ((TopicFigure) figure) + .getNormalPreferredBounds(new Point()).height; + double delta = height * cos * cot; + offset = direction.equals(IMainDirection.RightHeaded) ? bounds + .right() + delta : bounds.x - delta; + } else { + Rectangle bounds = branch.getFigure().getBounds(); + offset = direction.equals(IMainDirection.RightHeaded) ? bounds + .right() : bounds.x; + + for (IBranchPart callout : callouts) { + Rectangle calloutBounds = callout.getFigure().getBounds(); + if (direction.equals(ISubDirection.NE)) { + Point tl = calloutBounds.getTopLeft(); + offset = Math.min(offset, tl.x - (-tl.y) * cot); + } else if (direction.equals(ISubDirection.SE)) { + Point bl = calloutBounds.getBottomLeft(); + offset = Math.min(offset, bl.x - (bl.y) * cot); + } else if (direction.equals(ISubDirection.NW)) { + Point tr = calloutBounds.getTopRight(); + offset = Math.max(offset, tr.x + (tr.y) * cot); + } else { + Point br = calloutBounds.getBottomRight(); + offset = Math.max(offset, br.x + (br.y) * cot); + } + } + } + + return offset; + } + + @Override + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + double minorSpacing = getMinorSpacing(branch) * fMinor; + double x = branch.getFigure().getSize().width * 0.5d + + key.getFigure().getSize().width * 0.5d; + return getFigureLocation(branch.getFigure()).getTranslated( + IMainDirection.LeftHeaded.equals(direction) ? x : -x, + -minorSpacing); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NENormalStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NENormalStructure.java index 5c7ef40d7..1526efe55 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NENormalStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NENormalStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class NENormalStructure extends SubFishboneStructure { - - public NENormalStructure() { - super(ISubDirection.NE); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class NENormalStructure extends SubFishboneStructure { + + public NENormalStructure() { + super(ISubDirection.NE); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NERotatedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NERotatedStructure.java index 0ed2f0083..4c643bc53 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NERotatedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NERotatedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class NERotatedStructure extends SubFishboneStructure { - - public NERotatedStructure() { - super(ISubDirection.NER); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class NERotatedStructure extends SubFishboneStructure { + + public NERotatedStructure() { + super(ISubDirection.NER); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWNormalStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWNormalStructure.java index cef6929a1..4fa5ca247 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWNormalStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWNormalStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class NWNormalStructure extends SubFishboneStructure { - - public NWNormalStructure() { - super(ISubDirection.NW); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class NWNormalStructure extends SubFishboneStructure { + + public NWNormalStructure() { + super(ISubDirection.NW); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWRotatedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWRotatedStructure.java index ae6ce5c73..a7a036dd5 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWRotatedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NWRotatedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class NWRotatedStructure extends SubFishboneStructure { - - public NWRotatedStructure() { - super(ISubDirection.NWR); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class NWRotatedStructure extends SubFishboneStructure { + + public NWRotatedStructure() { + super(ISubDirection.NWR); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastNormal.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastNormal.java index 143d79f75..3cbdbbe85 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastNormal.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastNormal.java @@ -1,267 +1,267 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.util.MindMapUtils; - -public class NorthEastNormal extends AbstractSubFishboneDirection { - - public NorthEastNormal() { - super(false, false, false, EAST, WEST); - } - - public ISubDirection getSubDirection() { - return NER; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - - PrecisionPoint origin = h.getOrigin(); - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - double sin = r.sin(); - double ctg = r.cos() / r.sin(); - - PrecisionPoint joint = origin.getTranslated( - h.ti(data.branchRefIns).right, hTopicIns.bottom); - - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - joint.x += plusMinus.getFigure().getPreferredSize().width; - } - PrecisionPoint joint2 = joint.getCopy(); - - IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, - IInsertion.CACHE_INSERTION); - int insIndex = insertion == null ? -1 : insertion.getIndex(); - Dimension insSize = insertion == null ? null : insertion.getSize(); - double insHeight = insSize == null ? 0 : insSize.height; - - IStructure structure = branch.getBranchPolicy().getStructure(branch); - BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) - .getBoundaryLayoutHelper(branch); - //to track record the longest topic's length while it in horizon direction - double dxT = 0.0; - double width = 0.0; - double len = 0.0; - for (int i = 0; i < subbranches.size(); i++) { - IBranchPart subBranch = subbranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - - PrecisionInsets hChildBranch; - PrecisionInsets rhChildBranch; - - Insets ins = helper.getInsets(subBranch); - PrecisionInsets hChildBorder = h.t(new PrecisionInsets(ins)); - PrecisionInsets rhChildBorder = r.ti(hChildBorder); - - IStructure bsa = subBranch.getBranchPolicy() - .getStructure(subBranch); - if (bsa instanceof SubFishboneStructure) { - SubFishboneStructure sfsa = (SubFishboneStructure) bsa; - FishboneData subData = sfsa.getCastedData(subBranch) - .getFishboneData(); - hChildBranch = h.ti(subData.branchRefIns); - - rhChildBranch = h.ti(subData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - ((IReferencedFigure) subBranchFigure) - .getReferenceDescription()); - rhChildBranch = h.ti(childBranchNormal); - hChildBranch = r.ti(rhChildBranch); - } - - double dy = -rhChildBranch.bottom - hChildBorder.bottom; - double dx1 = Math.abs(dy * ctg); - double dx; - if (hChildBorder.right != 0) { - dx = hChildBorder.right + rhChildBranch.left; - } else { - double dx2 = Math.abs(hChildBranch.top / sin); - dx = dx1 + dx2; - } - - if (insIndex >= 0 && i == insIndex) { - dx += Math.abs(insHeight / sin); - } - - PrecisionPoint hChildRef; - if (hChildBorder.right != 0) { - joint.x = joint2.x; - hChildRef = joint2.getTranslated(dx, dy); - } else { - joint2.x = joint.x; - hChildRef = joint.getTranslated(dx, dy); - } - hChildRef.y -= hChildBorder.bottom; - - if (hChildBorder.getHeight() != 0) { - if (dxT <= hChildBranch.getWidth() * r.cos() + joint.x) - //the longest topic's length while it in horizon direction - dxT = hChildBranch.getWidth() * r.cos() + joint.x; - if (width <= rhChildBranch.right) { - width = rhChildBranch.right; - len = joint.x + dx + width; - } - } - - PrecisionPoint rhChildRef = r.tp(hChildRef); - - hBranchBounds.union(rhChildBranch.getBounds(hChildRef).expand( - hChildBorder)); - rhBranchBounds.union(hChildBranch.getBounds(rhChildRef).expand( - rhChildBorder)); - - data.addChildOffset(subBranch, h.rp(hChildRef)); - - double jdx; - if (hChildBorder.left != 0) { - double dx3 = Math.abs(hChildBranch.bottom / sin); - //the whole boundary's length in horizon direction - double dxB = joint.x + dx1 - dx3 + rhChildBranch.right - + hChildBorder.left; - if (dxT < dxB) - dx += hChildBorder.left + rhChildBranch.right; - else { - double d = joint.x + dx; - double cha = len - d; - dx += rhChildBorder.left + cha; - } - jdx = dx; - } else { - double dx3 = Math.abs(hChildBranch.bottom / sin); - jdx = dx - dx1 + dx3; - dx += rhChildBranch.right; - } - - joint2.x += dx + spacing; - joint.x += jdx + spacing; - - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - if (!extraBranch) - return; - List calloutBranches = branch.getCalloutBranches(); - PrecisionPoint origin = h.getOrigin(); - - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); - PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); -// PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds(origin); - - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - double tan = r.sin() / r.cos(); - - double pBottomLineX = hTopicBounds.x; - double pBottomLineY = hTopicBounds.y; - - for (int i = 0; i < calloutBranches.size(); i++) { - IBranchPart calloutBranch = calloutBranches.get(i); - Dimension calloutTopicSize = calloutBranch.getTopicPart() - .getFigure().getPreferredSize(); - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; - - IStructure structure = calloutBranch.getBranchPolicy() - .getStructure(calloutBranch); - if (structure instanceof SubFishboneStructure) { - FishboneData calloutData = ((SubFishboneStructure) structure) - .getCastedData(calloutBranch).getFishboneData(); - hChildBranchIns = h.ti(calloutData.branchRefIns); - rhChildBranchIns = h.ti(calloutData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - calloutBranchFigure.getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - double dx = originPosition ? 0 : position.x; - double dy = originPosition ? -10 - calloutTopicSize.height / 2 - - hTopicIns.getHeight() : position.y; - - PrecisionPoint hChildRef = origin.getTranslated(h.tp(dx, dy)); - PrecisionRectangle hChildBounds = hChildBranchIns - .getBounds(hChildRef); - - boolean touchParentTopic = hChildBounds.intersects(hTopicBounds); - if (touchParentTopic) { - hChildRef = origin - .getTranslated(hChildRef.x, - dy > 0 ? hChildBranchIns.top + hTopicIns.bottom - + 10 : -(hChildBranchIns.bottom - + hTopicIns.top + 10)); - hChildBounds = hChildBranchIns.getBounds(hChildRef); - } - - double distBottom = (-tan * (hChildBounds.x - pBottomLineX) - + pBottomLineY - hChildBounds.y) - / Math.sqrt(tan * tan + 1); - - if (distBottom > 0) { - hChildRef = hChildRef.getTranslated(distBottom / r.sin(), 0); - hChildBounds = hChildBranchIns.getBounds(hChildRef); - } - - PrecisionPoint rhChildRef = r.tp(hChildRef); - data.addChildOffset(calloutBranch, h.rp(hChildRef)); - - hBranchBounds.union(hChildBranchIns.getBounds(hChildRef)); - rhBranchBounds.union(rhChildBranchIns.getBounds(rhChildRef)); - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.util.MindMapUtils; + +public class NorthEastNormal extends AbstractSubFishboneDirection { + + public NorthEastNormal() { + super(false, false, false, EAST, WEST); + } + + public ISubDirection getSubDirection() { + return NER; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + + PrecisionPoint origin = h.getOrigin(); + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + double sin = r.sin(); + double ctg = r.cos() / r.sin(); + + PrecisionPoint joint = origin.getTranslated( + h.ti(data.branchRefIns).right, hTopicIns.bottom); + + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + joint.x += plusMinus.getFigure().getPreferredSize().width; + } + PrecisionPoint joint2 = joint.getCopy(); + + IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, + IInsertion.CACHE_INSERTION); + int insIndex = insertion == null ? -1 : insertion.getIndex(); + Dimension insSize = insertion == null ? null : insertion.getSize(); + double insHeight = insSize == null ? 0 : insSize.height; + + IStructure structure = branch.getBranchPolicy().getStructure(branch); + BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) + .getBoundaryLayoutHelper(branch); + //to track record the longest topic's length while it in horizon direction + double dxT = 0.0; + double width = 0.0; + double len = 0.0; + for (int i = 0; i < subbranches.size(); i++) { + IBranchPart subBranch = subbranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + + PrecisionInsets hChildBranch; + PrecisionInsets rhChildBranch; + + Insets ins = helper.getInsets(subBranch); + PrecisionInsets hChildBorder = h.t(new PrecisionInsets(ins)); + PrecisionInsets rhChildBorder = r.ti(hChildBorder); + + IStructure bsa = subBranch.getBranchPolicy() + .getStructure(subBranch); + if (bsa instanceof SubFishboneStructure) { + SubFishboneStructure sfsa = (SubFishboneStructure) bsa; + FishboneData subData = sfsa.getCastedData(subBranch) + .getFishboneData(); + hChildBranch = h.ti(subData.branchRefIns); + + rhChildBranch = h.ti(subData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + ((IReferencedFigure) subBranchFigure) + .getReferenceDescription()); + rhChildBranch = h.ti(childBranchNormal); + hChildBranch = r.ti(rhChildBranch); + } + + double dy = -rhChildBranch.bottom - hChildBorder.bottom; + double dx1 = Math.abs(dy * ctg); + double dx; + if (hChildBorder.right != 0) { + dx = hChildBorder.right + rhChildBranch.left; + } else { + double dx2 = Math.abs(hChildBranch.top / sin); + dx = dx1 + dx2; + } + + if (insIndex >= 0 && i == insIndex) { + dx += Math.abs(insHeight / sin); + } + + PrecisionPoint hChildRef; + if (hChildBorder.right != 0) { + joint.x = joint2.x; + hChildRef = joint2.getTranslated(dx, dy); + } else { + joint2.x = joint.x; + hChildRef = joint.getTranslated(dx, dy); + } + hChildRef.y -= hChildBorder.bottom; + + if (hChildBorder.getHeight() != 0) { + if (dxT <= hChildBranch.getWidth() * r.cos() + joint.x) + //the longest topic's length while it in horizon direction + dxT = hChildBranch.getWidth() * r.cos() + joint.x; + if (width <= rhChildBranch.right) { + width = rhChildBranch.right; + len = joint.x + dx + width; + } + } + + PrecisionPoint rhChildRef = r.tp(hChildRef); + + hBranchBounds.union(rhChildBranch.getBounds(hChildRef).expand( + hChildBorder)); + rhBranchBounds.union(hChildBranch.getBounds(rhChildRef).expand( + rhChildBorder)); + + data.addChildOffset(subBranch, h.rp(hChildRef)); + + double jdx; + if (hChildBorder.left != 0) { + double dx3 = Math.abs(hChildBranch.bottom / sin); + //the whole boundary's length in horizon direction + double dxB = joint.x + dx1 - dx3 + rhChildBranch.right + + hChildBorder.left; + if (dxT < dxB) + dx += hChildBorder.left + rhChildBranch.right; + else { + double d = joint.x + dx; + double cha = len - d; + dx += rhChildBorder.left + cha; + } + jdx = dx; + } else { + double dx3 = Math.abs(hChildBranch.bottom / sin); + jdx = dx - dx1 + dx3; + dx += rhChildBranch.right; + } + + joint2.x += dx + spacing; + joint.x += jdx + spacing; + + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + if (!extraBranch) + return; + List calloutBranches = branch.getCalloutBranches(); + PrecisionPoint origin = h.getOrigin(); + + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); + PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); +// PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds(origin); + + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + double tan = r.sin() / r.cos(); + + double pBottomLineX = hTopicBounds.x; + double pBottomLineY = hTopicBounds.y; + + for (int i = 0; i < calloutBranches.size(); i++) { + IBranchPart calloutBranch = calloutBranches.get(i); + Dimension calloutTopicSize = calloutBranch.getTopicPart() + .getFigure().getPreferredSize(); + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; + + IStructure structure = calloutBranch.getBranchPolicy() + .getStructure(calloutBranch); + if (structure instanceof SubFishboneStructure) { + FishboneData calloutData = ((SubFishboneStructure) structure) + .getCastedData(calloutBranch).getFishboneData(); + hChildBranchIns = h.ti(calloutData.branchRefIns); + rhChildBranchIns = h.ti(calloutData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + calloutBranchFigure.getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + double dx = originPosition ? 0 : position.x; + double dy = originPosition ? -10 - calloutTopicSize.height / 2 + - hTopicIns.getHeight() : position.y; + + PrecisionPoint hChildRef = origin.getTranslated(h.tp(dx, dy)); + PrecisionRectangle hChildBounds = hChildBranchIns + .getBounds(hChildRef); + + boolean touchParentTopic = hChildBounds.intersects(hTopicBounds); + if (touchParentTopic) { + hChildRef = origin + .getTranslated(hChildRef.x, + dy > 0 ? hChildBranchIns.top + hTopicIns.bottom + + 10 : -(hChildBranchIns.bottom + + hTopicIns.top + 10)); + hChildBounds = hChildBranchIns.getBounds(hChildRef); + } + + double distBottom = (-tan * (hChildBounds.x - pBottomLineX) + + pBottomLineY - hChildBounds.y) + / Math.sqrt(tan * tan + 1); + + if (distBottom > 0) { + hChildRef = hChildRef.getTranslated(distBottom / r.sin(), 0); + hChildBounds = hChildBranchIns.getBounds(hChildRef); + } + + PrecisionPoint rhChildRef = r.tp(hChildRef); + data.addChildOffset(calloutBranch, h.rp(hChildRef)); + + hBranchBounds.union(hChildBranchIns.getBounds(hChildRef)); + rhBranchBounds.union(rhChildBranchIns.getBounds(rhChildRef)); + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastRotated.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastRotated.java index b186a2d73..32b465a80 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastRotated.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthEastRotated.java @@ -1,236 +1,236 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.util.MindMapUtils; - -public class NorthEastRotated extends AbstractSubFishboneDirection { - - public NorthEastRotated() { - super(-Fishbone.RotateAngle, false, false, true, EAST, WEST); - } - - public ISubDirection getSubDirection() { - return NE; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - - PrecisionPoint origin = h.getOrigin(); - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - double sin = r.sin(); - double ctg = r.cos() / r.sin(); - subbranches = new ArrayList(subbranches); - Collections.reverse(subbranches); - - PrecisionPoint joint = origin.getTranslated(0, hTopicIns.bottom); - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - joint.x += plusMinus.getFigure().getPreferredSize().width; - } - - IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, - IInsertion.CACHE_INSERTION); - int insIndex = insertion == null ? -1 : subbranches.size() - - insertion.getIndex(); - Dimension insSize = insertion == null ? null : insertion.getSize(); - double insHeight = insSize == null ? 0 : insSize.height; - - IStructure structure = branch.getBranchPolicy().getStructure(branch); - BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) - .getBoundaryLayoutHelper(branch); - - for (int i = 0; i < subbranches.size(); i++) { - IBranchPart subBranch = subbranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; -// PrecisionInsets hChildBorder = h.ti(new PrecisionInsets( -// subBranchFigure.getInsets())); - Insets ins = helper.getInsets(subBranch); -// PrecisionInsets preciseIns = h.ri(new PrecisionInsets(ins)); - PrecisionInsets hChildBorder = h.ti(new PrecisionInsets(ins)); - PrecisionInsets rhChildBorder = r.ti(hChildBorder); - - IStructure bsa = subBranch.getBranchPolicy() - .getStructure(subBranch); - if (bsa instanceof SubFishboneStructure) { - SubFishboneStructure sa = (SubFishboneStructure) bsa; - FishboneData subData = sa.getCastedData(subBranch) - .getFishboneData(); - hChildBranchIns = h.ti(subData.branchRefIns); - rhChildBranchIns = h.ti(subData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - ((IReferencedFigure) subBranchFigure) - .getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - double dy = rhChildBranchIns.top; - double dx1 = Math - .abs((hChildBorder.bottom + hChildBranchIns.bottom) / sin); - if (insIndex >= 0 && i == insIndex) { - dx1 += Math.abs(insHeight / sin); - } - - double dx2 = Math.abs(dy * ctg); - double dx = dx1 + dx2; - - PrecisionPoint hChildRef = joint.getTranslated(dx, dy); - PrecisionPoint rhChildRef = r.rp(hChildRef); - - data.addChildOffset(subBranch, h.rp(rhChildRef)); - - hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( - rhChildBorder)); - rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( - hChildBorder)); - double dx3 = Math.abs((hChildBorder.top + hChildBranchIns.top) - / sin); - joint.x += dx1 + dx3 + spacing; - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - if (!extraBranch) - return; - List calloutBranches = branch.getCalloutBranches(); - PrecisionPoint origin = h.getOrigin(); - - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); -// PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); - PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds( - origin); - double tan = r.sin() / r.cos(); - - double bottomLineX = hTopicIns.bottom / r.sin(); - double bottomLineY = 0; - - double topLineX = -hTopicIns.top / r.sin(); - double topLineY = 0; - - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - for (int i = 0; i < calloutBranches.size(); i++) { - IBranchPart calloutBranch = calloutBranches.get(i); - Dimension calloutTopicSize = calloutBranch.getTopicPart() - .getFigure().getPreferredSize(); - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; - - IStructure structure = calloutBranch.getBranchPolicy() - .getStructure(calloutBranch); - if (structure instanceof SubFishboneStructure) { - FishboneData calloutData = ((SubFishboneStructure) structure) - .getCastedData(calloutBranch).getFishboneData(); - hChildBranchIns = h.ti(calloutData.branchRefIns); - rhChildBranchIns = h.ti(calloutData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - calloutBranchFigure.getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - double dx = originPosition ? -(0.5 * hTopicIns.getHeight() - / r.sin() + calloutTopicSize.width / 2) : position.x; - double dy = originPosition ? -10 - calloutTopicSize.height - : position.y; - - PrecisionPoint rhChildRef = origin.getTranslated(h.tp(dx, dy)); - PrecisionRectangle hChildBounds = hChildBranchIns - .getBounds(rhChildRef); - - double distTop = (-tan - * (hChildBounds.getBottomRight().x - topLineX) + topLineY - hChildBounds - .getBottomRight().y) / Math.sqrt(tan * tan + 1); - double distBottom = (-tan - * (hChildBounds.getBottomRight().x - bottomLineX) - + bottomLineY - hChildBounds.getBottomRight().y) - / Math.sqrt(tan * tan + 1); - double distLimit = hChildBounds.bottom() - rhTopicBounds.bottom(); - - if (distLimit > 0) { - rhChildRef = rhChildRef.getTranslated(0, -distLimit); - hChildBounds = hChildBranchIns.getBounds(rhChildRef); - } - -// boolean upDown = distUP > 0; - if (distBottom < 0) { - rhChildRef = rhChildRef.getTranslated(distBottom / r.sin(), 0); - hChildBounds = hChildBranchIns.getBounds(rhChildRef); - } - - if (hChildBounds.toDraw2DRectangle().touches( - rhTopicBounds.toDraw2DRectangle()) - && distTop < 0) { - rhChildRef = rhChildRef.getTranslated(distTop / r.sin(), 0); - } - - PrecisionPoint hChildRef = r.tp(rhChildRef); - data.addChildOffset(calloutBranch, h.rp(rhChildRef)); - - hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef)); - rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef)); - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.util.MindMapUtils; + +public class NorthEastRotated extends AbstractSubFishboneDirection { + + public NorthEastRotated() { + super(-Fishbone.RotateAngle, false, false, true, EAST, WEST); + } + + public ISubDirection getSubDirection() { + return NE; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + + PrecisionPoint origin = h.getOrigin(); + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + double sin = r.sin(); + double ctg = r.cos() / r.sin(); + subbranches = new ArrayList(subbranches); + Collections.reverse(subbranches); + + PrecisionPoint joint = origin.getTranslated(0, hTopicIns.bottom); + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + joint.x += plusMinus.getFigure().getPreferredSize().width; + } + + IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, + IInsertion.CACHE_INSERTION); + int insIndex = insertion == null ? -1 : subbranches.size() + - insertion.getIndex(); + Dimension insSize = insertion == null ? null : insertion.getSize(); + double insHeight = insSize == null ? 0 : insSize.height; + + IStructure structure = branch.getBranchPolicy().getStructure(branch); + BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) + .getBoundaryLayoutHelper(branch); + + for (int i = 0; i < subbranches.size(); i++) { + IBranchPart subBranch = subbranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; +// PrecisionInsets hChildBorder = h.ti(new PrecisionInsets( +// subBranchFigure.getInsets())); + Insets ins = helper.getInsets(subBranch); +// PrecisionInsets preciseIns = h.ri(new PrecisionInsets(ins)); + PrecisionInsets hChildBorder = h.ti(new PrecisionInsets(ins)); + PrecisionInsets rhChildBorder = r.ti(hChildBorder); + + IStructure bsa = subBranch.getBranchPolicy() + .getStructure(subBranch); + if (bsa instanceof SubFishboneStructure) { + SubFishboneStructure sa = (SubFishboneStructure) bsa; + FishboneData subData = sa.getCastedData(subBranch) + .getFishboneData(); + hChildBranchIns = h.ti(subData.branchRefIns); + rhChildBranchIns = h.ti(subData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + ((IReferencedFigure) subBranchFigure) + .getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + double dy = rhChildBranchIns.top; + double dx1 = Math + .abs((hChildBorder.bottom + hChildBranchIns.bottom) / sin); + if (insIndex >= 0 && i == insIndex) { + dx1 += Math.abs(insHeight / sin); + } + + double dx2 = Math.abs(dy * ctg); + double dx = dx1 + dx2; + + PrecisionPoint hChildRef = joint.getTranslated(dx, dy); + PrecisionPoint rhChildRef = r.rp(hChildRef); + + data.addChildOffset(subBranch, h.rp(rhChildRef)); + + hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( + rhChildBorder)); + rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( + hChildBorder)); + double dx3 = Math.abs((hChildBorder.top + hChildBranchIns.top) + / sin); + joint.x += dx1 + dx3 + spacing; + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + if (!extraBranch) + return; + List calloutBranches = branch.getCalloutBranches(); + PrecisionPoint origin = h.getOrigin(); + + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); +// PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); + PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds( + origin); + double tan = r.sin() / r.cos(); + + double bottomLineX = hTopicIns.bottom / r.sin(); + double bottomLineY = 0; + + double topLineX = -hTopicIns.top / r.sin(); + double topLineY = 0; + + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + for (int i = 0; i < calloutBranches.size(); i++) { + IBranchPart calloutBranch = calloutBranches.get(i); + Dimension calloutTopicSize = calloutBranch.getTopicPart() + .getFigure().getPreferredSize(); + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; + + IStructure structure = calloutBranch.getBranchPolicy() + .getStructure(calloutBranch); + if (structure instanceof SubFishboneStructure) { + FishboneData calloutData = ((SubFishboneStructure) structure) + .getCastedData(calloutBranch).getFishboneData(); + hChildBranchIns = h.ti(calloutData.branchRefIns); + rhChildBranchIns = h.ti(calloutData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + calloutBranchFigure.getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + double dx = originPosition ? -(0.5 * hTopicIns.getHeight() + / r.sin() + calloutTopicSize.width / 2) : position.x; + double dy = originPosition ? -10 - calloutTopicSize.height + : position.y; + + PrecisionPoint rhChildRef = origin.getTranslated(h.tp(dx, dy)); + PrecisionRectangle hChildBounds = hChildBranchIns + .getBounds(rhChildRef); + + double distTop = (-tan + * (hChildBounds.getBottomRight().x - topLineX) + topLineY - hChildBounds + .getBottomRight().y) / Math.sqrt(tan * tan + 1); + double distBottom = (-tan + * (hChildBounds.getBottomRight().x - bottomLineX) + + bottomLineY - hChildBounds.getBottomRight().y) + / Math.sqrt(tan * tan + 1); + double distLimit = hChildBounds.bottom() - rhTopicBounds.bottom(); + + if (distLimit > 0) { + rhChildRef = rhChildRef.getTranslated(0, -distLimit); + hChildBounds = hChildBranchIns.getBounds(rhChildRef); + } + +// boolean upDown = distUP > 0; + if (distBottom < 0) { + rhChildRef = rhChildRef.getTranslated(distBottom / r.sin(), 0); + hChildBounds = hChildBranchIns.getBounds(rhChildRef); + } + + if (hChildBounds.toDraw2DRectangle().touches( + rhTopicBounds.toDraw2DRectangle()) + && distTop < 0) { + rhChildRef = rhChildRef.getTranslated(distTop / r.sin(), 0); + } + + PrecisionPoint hChildRef = r.tp(rhChildRef); + data.addChildOffset(calloutBranch, h.rp(rhChildRef)); + + hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef)); + rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef)); + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestNormal.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestNormal.java index 55590c753..d639a3f1a 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestNormal.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestNormal.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.mindmap.IBranchPart; - -public class NorthWestNormal extends AbstractSubFishboneDirection { - - public NorthWestNormal() { - super(false, true, false, WEST, EAST); - } - - public ISubDirection getSubDirection() { - return NWR; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - NE.fillFishboneData(branch, data, h, r, spacing, subbranches); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - NE.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.mindmap.IBranchPart; + +public class NorthWestNormal extends AbstractSubFishboneDirection { + + public NorthWestNormal() { + super(false, true, false, WEST, EAST); + } + + public ISubDirection getSubDirection() { + return NWR; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + NE.fillFishboneData(branch, data, h, r, spacing, subbranches); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + NE.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestRotated.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestRotated.java index 463d22e67..679bd4928 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestRotated.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/NorthWestRotated.java @@ -1,46 +1,46 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.mindmap.IBranchPart; - -public class NorthWestRotated extends AbstractSubFishboneDirection { - - public NorthWestRotated() { - super(Fishbone.RotateAngle, false, true, true, WEST, EAST); - } - - public ISubDirection getSubDirection() { - return NW; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - NER.fillFishboneData(branch, data, h, r, spacing, subbranches); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - NER.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.mindmap.IBranchPart; + +public class NorthWestRotated extends AbstractSubFishboneDirection { + + public NorthWestRotated() { + super(Fishbone.RotateAngle, false, true, true, WEST, EAST); + } + + public ISubDirection getSubDirection() { + return NW; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + NER.fillFishboneData(branch, data, h, r, spacing, subbranches); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + NER.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/RightHeadedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/RightHeadedStructure.java index 7963d03b4..cd214b743 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/RightHeadedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/RightHeadedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class RightHeadedStructure extends MainFishboneStructure { - - public RightHeadedStructure() { - super(IMainDirection.RightHeaded); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class RightHeadedStructure extends MainFishboneStructure { + + public RightHeadedStructure() { + super(IMainDirection.RightHeaded); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SENormalStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SENormalStructure.java index 906f46a6e..a33e373ea 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SENormalStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SENormalStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class SENormalStructure extends SubFishboneStructure { - - public SENormalStructure() { - super(ISubDirection.SE); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class SENormalStructure extends SubFishboneStructure { + + public SENormalStructure() { + super(ISubDirection.SE); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SERotatedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SERotatedStructure.java index 1881f0fce..5c31c9a25 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SERotatedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SERotatedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class SERotatedStructure extends SubFishboneStructure { - - public SERotatedStructure() { - super(ISubDirection.SER); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class SERotatedStructure extends SubFishboneStructure { + + public SERotatedStructure() { + super(ISubDirection.SER); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWNormalStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWNormalStructure.java index ae80d6ca5..4e088c18a 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWNormalStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWNormalStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class SWNormalStructure extends SubFishboneStructure { - - public SWNormalStructure() { - super(ISubDirection.SW); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class SWNormalStructure extends SubFishboneStructure { + + public SWNormalStructure() { + super(ISubDirection.SW); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWRotatedStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWRotatedStructure.java index 4178dfc7b..e8ec61071 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWRotatedStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SWRotatedStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -public class SWRotatedStructure extends SubFishboneStructure { - - public SWRotatedStructure() { - super(ISubDirection.SWR); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +public class SWRotatedStructure extends SubFishboneStructure { + + public SWRotatedStructure() { + super(ISubDirection.SWR); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/Side.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/Side.java index 9dfeea986..c1a6608c6 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/Side.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/Side.java @@ -1,33 +1,33 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -class Side { - - double lastJoint; - - double rotatedBottom; - - double right; - - boolean useRight = false; - - void start(double x) { - this.right = x; - this.rotatedBottom = x; - this.lastJoint = 0; - this.useRight = false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +class Side { + + double lastJoint; + + double rotatedBottom; + + double right; + + boolean useRight = false; + + void start(double x) { + this.right = x; + this.rotatedBottom = x; + this.lastJoint = 0; + this.useRight = false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastNormal.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastNormal.java index d72f13865..bc3b85657 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastNormal.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastNormal.java @@ -1,282 +1,282 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ILabelPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.util.MindMapUtils; - -public class SouthEastNormal extends AbstractSubFishboneDirection { - - public SouthEastNormal() { - super(true, false, false, EAST, EAST); - } - - public ISubDirection getSubDirection() { - return SER; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - PrecisionPoint origin = h.getOrigin(); - PrecisionInsets hTopicNormal = h.ti(data.topicRefIns); - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - double sin = r.sin(); - double ctg = r.cos() / r.sin(); - - PrecisionPoint joint = origin.getTranslated( - h.ti(data.branchRefIns).right, hTopicNormal.bottom); - ILabelPart label = branch.getLabel(); - if (label != null && label.getFigure().isVisible()) { - joint.y -= label.getFigure().getPreferredSize().height; - } - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - joint.x += plusMinus.getFigure().getPreferredSize().width; - } - - IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, - IInsertion.CACHE_INSERTION); - int insIndex = insertion == null ? -1 : insertion.getIndex(); - Dimension insSize = insertion == null ? null : insertion.getSize(); - double insHeight = insSize == null ? 0 : insSize.height; - - IStructure structure = branch.getBranchPolicy().getStructure(branch); - BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) - .getBoundaryLayoutHelper(branch); - - PrecisionPoint joint2 = joint.getCopy(); - - double dxT = 0.0; - double width = 0.0; - double len = 0.0; - for (int i = 0; i < subbranches.size(); i++) { - IBranchPart subBranch = subbranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; - -// PrecisionInsets hChildBorder = h.t(new PrecisionInsets( -// subBranchFigure.getInsets())); - Insets ins = helper.getInsets(subBranch); -// PrecisionInsets preciseIns = h.t(new PrecisionInsets(ins)); - PrecisionInsets hChildBorder = h.t(new PrecisionInsets(ins)); - PrecisionInsets rhChildBorder = r.ti(hChildBorder); - - IStructure bsa = subBranch.getBranchPolicy() - .getStructure(subBranch); - if (bsa instanceof SubFishboneStructure) { - SubFishboneStructure sfsa = (SubFishboneStructure) bsa; - FishboneData subData = sfsa.getCastedData(subBranch) - .getFishboneData(); - rhChildBranchIns = h.ti(subData.rBranchRefIns); - hChildBranchIns = h.ti(subData.branchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - ((IReferencedFigure) subBranchFigure) - .getReferenceDescription()); - rhChildBranchIns = h.ti(childBranchNormal); - hChildBranchIns = r.ti(rhChildBranchIns); - } - double dy = rhChildBranchIns.top + hChildBorder.top; - double dx1 = Math.abs(dy * ctg); - double dx; - if (hChildBorder.left != 0) { -// if (hChildBorder.right != 0) { - dx = hChildBorder.left + rhChildBranchIns.left; -// dx = hChildBorder.right + rhChildBranchIns.left; - } else { - double dx2 = Math.abs(hChildBranchIns.top / sin); - dx = dx1 + dx2; - } - - if (insIndex >= 0 && i == insIndex) { - dx += Math.abs(insHeight / sin); - } - - PrecisionPoint hChildRef; -// if (hChildBorder.left != 0) { - if (hChildBorder.right != 0) { - hChildRef = joint2.getTranslated(dx, dy); - joint.x = joint2.x; - } else { - hChildRef = joint.getTranslated(dx, dy); - joint2.x = joint.x; - } - hChildRef.y += hChildBorder.bottom; - - if (hChildBorder.getHeight() != 0) { - //the longest topic's length while it in horizon direction - if (dxT <= Math.abs(hChildBranchIns.getWidth() * r.cos()) - + joint.x) - dxT = Math.abs(hChildBranchIns.getWidth() * r.cos()) - + joint.x; - if (width <= rhChildBranchIns.right) { - width = rhChildBranchIns.right; - len = joint.x + dx + width; - } - } - - PrecisionPoint rhChildRef = r.tp(hChildRef); - data.addChildOffset(subBranch, h.rp(hChildRef)); - - hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( - hChildBorder)); - rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( - rhChildBorder)); - double jdx; - if (hChildBorder.left != 0) { - double dx3 = Math.abs(hChildBranchIns.bottom / sin); - //the whole boundary's length in horizon direction - double dxB = joint.x + dx1 - dx3 + rhChildBranchIns.right - + hChildBorder.left; - if (dxT < dxB) - dx += hChildBorder.left + rhChildBranchIns.right; - else { - double d = joint.x + dx; - double cha = len - d; - dx += rhChildBorder.left + cha; - } - jdx = dx; - } else { - double dx3 = Math.abs(hChildBranchIns.bottom / sin); - jdx = dx - dx1 + dx3; - dx += rhChildBranchIns.right; - } - joint2.x += dx + spacing; - joint.x += jdx + spacing; - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - if (!extraBranch) - return; - List calloutBranches = branch.getCalloutBranches(); - PrecisionPoint origin = h.getOrigin(); - - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); - PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); -// PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds(origin); - - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - double tan = r.sin() / r.cos(); - - double pBottomLineX = hTopicBounds.x; - double pBottomLineY = hTopicBounds.y; - - for (int i = 0; i < calloutBranches.size(); i++) { - IBranchPart calloutBranch = calloutBranches.get(i); - Dimension calloutTopicSize = calloutBranch.getTopicPart() - .getFigure().getPreferredSize(); - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; - - IStructure structure = calloutBranch.getBranchPolicy() - .getStructure(calloutBranch); - if (structure instanceof SubFishboneStructure) { - FishboneData calloutData = ((SubFishboneStructure) structure) - .getCastedData(calloutBranch).getFishboneData(); - hChildBranchIns = h.ti(calloutData.branchRefIns); - rhChildBranchIns = h.ti(calloutData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - calloutBranchFigure.getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - double dx = originPosition ? 0 : position.x; - double dy = originPosition ? -10 - calloutTopicSize.height / 2 - - hTopicIns.getHeight() : position.y; - - PrecisionPoint hChildRef = origin.getTranslated(h.tp(dx, dy)); - PrecisionRectangle hChildBounds = hChildBranchIns - .getBounds(hChildRef); - -// double distLimitX = hChildBounds.x - hTopicBounds.x; -// -// if (distLimitX < 0) { -// hChildRef = hChildRef.getTranslated(-distLimitX, 0); -// hChildBounds = hChildBranchIns.getBounds(hChildRef); -// } - - boolean touchParentTopic = hChildBounds.intersects(hTopicBounds); - if (touchParentTopic) { - hChildRef = origin - .getTranslated(hChildRef.x, - dy > 0 ? hChildBranchIns.top + hTopicIns.bottom - + 10 : -(hChildBranchIns.bottom - + hTopicIns.top + 10)); - hChildBounds = hChildBranchIns.getBounds(hChildRef); - } - - double distBottom = (-tan - * (hChildBounds.getBottomLeft().x - pBottomLineX) - + pBottomLineY - hChildBounds.getBottomLeft().y) - / Math.sqrt(tan * tan + 1); - - if (distBottom < 0) { - hChildRef = hChildRef.getTranslated(-distBottom / r.sin(), 0); - hChildBounds = hChildBranchIns.getBounds(hChildRef); - } - - PrecisionPoint rhChildRef = r.tp(hChildRef); - data.addChildOffset(calloutBranch, h.rp(hChildRef)); - - hBranchBounds.union(hChildBranchIns.getBounds(hChildRef)); - rhBranchBounds.union(rhChildBranchIns.getBounds(rhChildRef)); - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ILabelPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.util.MindMapUtils; + +public class SouthEastNormal extends AbstractSubFishboneDirection { + + public SouthEastNormal() { + super(true, false, false, EAST, EAST); + } + + public ISubDirection getSubDirection() { + return SER; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + PrecisionPoint origin = h.getOrigin(); + PrecisionInsets hTopicNormal = h.ti(data.topicRefIns); + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + double sin = r.sin(); + double ctg = r.cos() / r.sin(); + + PrecisionPoint joint = origin.getTranslated( + h.ti(data.branchRefIns).right, hTopicNormal.bottom); + ILabelPart label = branch.getLabel(); + if (label != null && label.getFigure().isVisible()) { + joint.y -= label.getFigure().getPreferredSize().height; + } + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + joint.x += plusMinus.getFigure().getPreferredSize().width; + } + + IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, + IInsertion.CACHE_INSERTION); + int insIndex = insertion == null ? -1 : insertion.getIndex(); + Dimension insSize = insertion == null ? null : insertion.getSize(); + double insHeight = insSize == null ? 0 : insSize.height; + + IStructure structure = branch.getBranchPolicy().getStructure(branch); + BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) + .getBoundaryLayoutHelper(branch); + + PrecisionPoint joint2 = joint.getCopy(); + + double dxT = 0.0; + double width = 0.0; + double len = 0.0; + for (int i = 0; i < subbranches.size(); i++) { + IBranchPart subBranch = subbranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; + +// PrecisionInsets hChildBorder = h.t(new PrecisionInsets( +// subBranchFigure.getInsets())); + Insets ins = helper.getInsets(subBranch); +// PrecisionInsets preciseIns = h.t(new PrecisionInsets(ins)); + PrecisionInsets hChildBorder = h.t(new PrecisionInsets(ins)); + PrecisionInsets rhChildBorder = r.ti(hChildBorder); + + IStructure bsa = subBranch.getBranchPolicy() + .getStructure(subBranch); + if (bsa instanceof SubFishboneStructure) { + SubFishboneStructure sfsa = (SubFishboneStructure) bsa; + FishboneData subData = sfsa.getCastedData(subBranch) + .getFishboneData(); + rhChildBranchIns = h.ti(subData.rBranchRefIns); + hChildBranchIns = h.ti(subData.branchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + ((IReferencedFigure) subBranchFigure) + .getReferenceDescription()); + rhChildBranchIns = h.ti(childBranchNormal); + hChildBranchIns = r.ti(rhChildBranchIns); + } + double dy = rhChildBranchIns.top + hChildBorder.top; + double dx1 = Math.abs(dy * ctg); + double dx; + if (hChildBorder.left != 0) { +// if (hChildBorder.right != 0) { + dx = hChildBorder.left + rhChildBranchIns.left; +// dx = hChildBorder.right + rhChildBranchIns.left; + } else { + double dx2 = Math.abs(hChildBranchIns.top / sin); + dx = dx1 + dx2; + } + + if (insIndex >= 0 && i == insIndex) { + dx += Math.abs(insHeight / sin); + } + + PrecisionPoint hChildRef; +// if (hChildBorder.left != 0) { + if (hChildBorder.right != 0) { + hChildRef = joint2.getTranslated(dx, dy); + joint.x = joint2.x; + } else { + hChildRef = joint.getTranslated(dx, dy); + joint2.x = joint.x; + } + hChildRef.y += hChildBorder.bottom; + + if (hChildBorder.getHeight() != 0) { + //the longest topic's length while it in horizon direction + if (dxT <= Math.abs(hChildBranchIns.getWidth() * r.cos()) + + joint.x) + dxT = Math.abs(hChildBranchIns.getWidth() * r.cos()) + + joint.x; + if (width <= rhChildBranchIns.right) { + width = rhChildBranchIns.right; + len = joint.x + dx + width; + } + } + + PrecisionPoint rhChildRef = r.tp(hChildRef); + data.addChildOffset(subBranch, h.rp(hChildRef)); + + hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( + hChildBorder)); + rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( + rhChildBorder)); + double jdx; + if (hChildBorder.left != 0) { + double dx3 = Math.abs(hChildBranchIns.bottom / sin); + //the whole boundary's length in horizon direction + double dxB = joint.x + dx1 - dx3 + rhChildBranchIns.right + + hChildBorder.left; + if (dxT < dxB) + dx += hChildBorder.left + rhChildBranchIns.right; + else { + double d = joint.x + dx; + double cha = len - d; + dx += rhChildBorder.left + cha; + } + jdx = dx; + } else { + double dx3 = Math.abs(hChildBranchIns.bottom / sin); + jdx = dx - dx1 + dx3; + dx += rhChildBranchIns.right; + } + joint2.x += dx + spacing; + joint.x += jdx + spacing; + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + if (!extraBranch) + return; + List calloutBranches = branch.getCalloutBranches(); + PrecisionPoint origin = h.getOrigin(); + + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); + PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); +// PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds(origin); + + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + double tan = r.sin() / r.cos(); + + double pBottomLineX = hTopicBounds.x; + double pBottomLineY = hTopicBounds.y; + + for (int i = 0; i < calloutBranches.size(); i++) { + IBranchPart calloutBranch = calloutBranches.get(i); + Dimension calloutTopicSize = calloutBranch.getTopicPart() + .getFigure().getPreferredSize(); + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; + + IStructure structure = calloutBranch.getBranchPolicy() + .getStructure(calloutBranch); + if (structure instanceof SubFishboneStructure) { + FishboneData calloutData = ((SubFishboneStructure) structure) + .getCastedData(calloutBranch).getFishboneData(); + hChildBranchIns = h.ti(calloutData.branchRefIns); + rhChildBranchIns = h.ti(calloutData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + calloutBranchFigure.getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + double dx = originPosition ? 0 : position.x; + double dy = originPosition ? -10 - calloutTopicSize.height / 2 + - hTopicIns.getHeight() : position.y; + + PrecisionPoint hChildRef = origin.getTranslated(h.tp(dx, dy)); + PrecisionRectangle hChildBounds = hChildBranchIns + .getBounds(hChildRef); + +// double distLimitX = hChildBounds.x - hTopicBounds.x; +// +// if (distLimitX < 0) { +// hChildRef = hChildRef.getTranslated(-distLimitX, 0); +// hChildBounds = hChildBranchIns.getBounds(hChildRef); +// } + + boolean touchParentTopic = hChildBounds.intersects(hTopicBounds); + if (touchParentTopic) { + hChildRef = origin + .getTranslated(hChildRef.x, + dy > 0 ? hChildBranchIns.top + hTopicIns.bottom + + 10 : -(hChildBranchIns.bottom + + hTopicIns.top + 10)); + hChildBounds = hChildBranchIns.getBounds(hChildRef); + } + + double distBottom = (-tan + * (hChildBounds.getBottomLeft().x - pBottomLineX) + + pBottomLineY - hChildBounds.getBottomLeft().y) + / Math.sqrt(tan * tan + 1); + + if (distBottom < 0) { + hChildRef = hChildRef.getTranslated(-distBottom / r.sin(), 0); + hChildBounds = hChildBranchIns.getBounds(hChildRef); + } + + PrecisionPoint rhChildRef = r.tp(hChildRef); + data.addChildOffset(calloutBranch, h.rp(hChildRef)); + + hBranchBounds.union(hChildBranchIns.getBounds(hChildRef)); + rhBranchBounds.union(rhChildBranchIns.getBounds(rhChildRef)); + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastRotated.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastRotated.java index 6c5fb596a..fb6175555 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastRotated.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthEastRotated.java @@ -1,231 +1,231 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.util.MindMapUtils; - -public class SouthEastRotated extends AbstractSubFishboneDirection { - - public SouthEastRotated() { - super(Fishbone.RotateAngle - 180.0d, true, false, false, WEST, WEST); - } - - public ISubDirection getSubDirection() { - return SE; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - PrecisionPoint origin = h.getOrigin(); - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - double sin = r.sin(); - double ctg = r.cos() / r.sin(); - - PrecisionPoint joint = origin.getTranslated(0,//-hTopicIns.left, - hTopicIns.bottom); - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - joint.x -= plusMinus.getFigure().getPreferredSize().width; - } - - IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, - IInsertion.CACHE_INSERTION); - int insIndex = insertion == null ? -1 : insertion.getIndex(); - Dimension insSize = insertion == null ? null : insertion.getSize(); - double insHeight = insSize == null ? 0 : insSize.height; - - IStructure structure = branch.getBranchPolicy().getStructure(branch); - BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) - .getBoundaryLayoutHelper(branch); - - for (int i = 0; i < subbranches.size(); i++) { - IBranchPart subBranch = subbranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; -// PrecisionInsets hChildBorder = h.ti(new PrecisionInsets( -// subBranchFigure.getInsets())); - Insets ins = helper.getInsets(subBranch); -// PrecisionInsets preciseIns = h.ri(new PrecisionInsets(ins)); - PrecisionInsets hChildBorder = h.ti(new PrecisionInsets(ins)); - PrecisionInsets rhChildBorder = r.ti(hChildBorder); - - IStructure bsa = subBranch.getBranchPolicy() - .getStructure(subBranch); - if (bsa instanceof SubFishboneStructure) { - SubFishboneStructure sfsa = (SubFishboneStructure) bsa; - FishboneData subData = sfsa.getCastedData(subBranch) - .getFishboneData(); - hChildBranchIns = h.ti(subData.branchRefIns); - rhChildBranchIns = h.ti(subData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - ((IReferencedFigure) subBranchFigure) - .getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - double dy = rhChildBranchIns.top; - double dx1 = Math.abs((hChildBorder.top + hChildBranchIns.top) - / sin); - if (insIndex >= 0 && i == insIndex) { - dx1 += Math.abs(insHeight / sin); - } - - double dx2 = Math.abs(dy * ctg); - double dx = dx1 + dx2; - - PrecisionPoint hChildRef = joint.getTranslated(-dx, dy + 3); - PrecisionPoint rhChildRef = r.rp(hChildRef); - - data.addChildOffset(subBranch, h.rp(rhChildRef)); - - hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( - rhChildBorder)); - rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( - hChildBorder)); - double dx3 = Math - .abs((hChildBorder.bottom + hChildBranchIns.bottom) / sin); - joint.x -= dx1 + dx3 + spacing; - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - if (!extraBranch) - return; - List calloutBranches = branch.getCalloutBranches(); - PrecisionPoint origin = h.getOrigin(); - - PrecisionInsets hTopicIns = h.ti(data.topicRefIns); -// PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); - PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds( - origin); - double tan = r.sin() / r.cos(); - - double bottomLineX = hTopicIns.bottom / r.sin(); - double bottomLineY = 0; - - double topLineX = -hTopicIns.top / r.sin(); - double topLineY = 0; - - PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( - origin); - PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( - origin); - - for (int i = 0; i < calloutBranches.size(); i++) { - IBranchPart calloutBranch = calloutBranches.get(i); - Dimension calloutTopicSize = calloutBranch.getTopicPart() - .getFigure().getPreferredSize(); - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - PrecisionInsets hChildBranchIns; - PrecisionInsets rhChildBranchIns; - - IStructure structure = calloutBranch.getBranchPolicy() - .getStructure(calloutBranch); - if (structure instanceof SubFishboneStructure) { - FishboneData calloutData = ((SubFishboneStructure) structure) - .getCastedData(calloutBranch).getFishboneData(); - hChildBranchIns = h.ti(calloutData.branchRefIns); - rhChildBranchIns = h.ti(calloutData.rBranchRefIns); - } else { - PrecisionInsets childBranchNormal = new PrecisionInsets( - calloutBranchFigure.getReferenceDescription()); - hChildBranchIns = h.ti(childBranchNormal); - rhChildBranchIns = r.ti(hChildBranchIns); - } - - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - double dx = originPosition ? -(0.5 * hTopicIns.getHeight() - / r.sin() + calloutTopicSize.width / 2) : position.x; - double dy = originPosition ? 10 + calloutTopicSize.height - : position.y; - - PrecisionPoint rhChildRef = origin.getTranslated(h.tp(dx, dy)); - PrecisionRectangle hChildBounds = hChildBranchIns - .getBounds(rhChildRef); - - double distTop = (-tan * (hChildBounds.getTopRight().x - topLineX) - + topLineY - hChildBounds.getTopRight().y) - / Math.sqrt(tan * tan + 1); - double distBottom = (-tan - * (hChildBounds.getTopRight().x - bottomLineX) - + bottomLineY - hChildBounds.getTopRight().y) - / Math.sqrt(tan * tan + 1); - double distLimit = hChildBounds.y - rhTopicBounds.y; - - if (distLimit < 0) { - rhChildRef = rhChildRef.getTranslated(0, -distLimit); - hChildBounds = hChildBranchIns.getBounds(rhChildRef); - } - - if (distBottom > 0) { - rhChildRef = rhChildRef.getTranslated(-distBottom / r.sin(), 0); - hChildBounds = hChildBranchIns.getBounds(rhChildRef); - } - - if (hChildBounds.toDraw2DRectangle().touches( - rhTopicBounds.toDraw2DRectangle()) - && distTop > 0) { - rhChildRef = rhChildRef.getTranslated(-distTop / r.sin(), 0); - } - - PrecisionPoint hChildRef = r.tp(rhChildRef); - data.addChildOffset(calloutBranch, h.rp(rhChildRef)); - - hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef)); - rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef)); - } - data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); - data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.util.MindMapUtils; + +public class SouthEastRotated extends AbstractSubFishboneDirection { + + public SouthEastRotated() { + super(Fishbone.RotateAngle - 180.0d, true, false, false, WEST, WEST); + } + + public ISubDirection getSubDirection() { + return SE; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + PrecisionPoint origin = h.getOrigin(); + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + double sin = r.sin(); + double ctg = r.cos() / r.sin(); + + PrecisionPoint joint = origin.getTranslated(0,//-hTopicIns.left, + hTopicIns.bottom); + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + joint.x -= plusMinus.getFigure().getPreferredSize().width; + } + + IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, + IInsertion.CACHE_INSERTION); + int insIndex = insertion == null ? -1 : insertion.getIndex(); + Dimension insSize = insertion == null ? null : insertion.getSize(); + double insHeight = insSize == null ? 0 : insSize.height; + + IStructure structure = branch.getBranchPolicy().getStructure(branch); + BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) + .getBoundaryLayoutHelper(branch); + + for (int i = 0; i < subbranches.size(); i++) { + IBranchPart subBranch = subbranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; +// PrecisionInsets hChildBorder = h.ti(new PrecisionInsets( +// subBranchFigure.getInsets())); + Insets ins = helper.getInsets(subBranch); +// PrecisionInsets preciseIns = h.ri(new PrecisionInsets(ins)); + PrecisionInsets hChildBorder = h.ti(new PrecisionInsets(ins)); + PrecisionInsets rhChildBorder = r.ti(hChildBorder); + + IStructure bsa = subBranch.getBranchPolicy() + .getStructure(subBranch); + if (bsa instanceof SubFishboneStructure) { + SubFishboneStructure sfsa = (SubFishboneStructure) bsa; + FishboneData subData = sfsa.getCastedData(subBranch) + .getFishboneData(); + hChildBranchIns = h.ti(subData.branchRefIns); + rhChildBranchIns = h.ti(subData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + ((IReferencedFigure) subBranchFigure) + .getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + double dy = rhChildBranchIns.top; + double dx1 = Math.abs((hChildBorder.top + hChildBranchIns.top) + / sin); + if (insIndex >= 0 && i == insIndex) { + dx1 += Math.abs(insHeight / sin); + } + + double dx2 = Math.abs(dy * ctg); + double dx = dx1 + dx2; + + PrecisionPoint hChildRef = joint.getTranslated(-dx, dy + 3); + PrecisionPoint rhChildRef = r.rp(hChildRef); + + data.addChildOffset(subBranch, h.rp(rhChildRef)); + + hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( + rhChildBorder)); + rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( + hChildBorder)); + double dx3 = Math + .abs((hChildBorder.bottom + hChildBranchIns.bottom) / sin); + joint.x -= dx1 + dx3 + spacing; + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + if (!extraBranch) + return; + List calloutBranches = branch.getCalloutBranches(); + PrecisionPoint origin = h.getOrigin(); + + PrecisionInsets hTopicIns = h.ti(data.topicRefIns); +// PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); + PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds( + origin); + double tan = r.sin() / r.cos(); + + double bottomLineX = hTopicIns.bottom / r.sin(); + double bottomLineY = 0; + + double topLineX = -hTopicIns.top / r.sin(); + double topLineY = 0; + + PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( + origin); + PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( + origin); + + for (int i = 0; i < calloutBranches.size(); i++) { + IBranchPart calloutBranch = calloutBranches.get(i); + Dimension calloutTopicSize = calloutBranch.getTopicPart() + .getFigure().getPreferredSize(); + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + PrecisionInsets hChildBranchIns; + PrecisionInsets rhChildBranchIns; + + IStructure structure = calloutBranch.getBranchPolicy() + .getStructure(calloutBranch); + if (structure instanceof SubFishboneStructure) { + FishboneData calloutData = ((SubFishboneStructure) structure) + .getCastedData(calloutBranch).getFishboneData(); + hChildBranchIns = h.ti(calloutData.branchRefIns); + rhChildBranchIns = h.ti(calloutData.rBranchRefIns); + } else { + PrecisionInsets childBranchNormal = new PrecisionInsets( + calloutBranchFigure.getReferenceDescription()); + hChildBranchIns = h.ti(childBranchNormal); + rhChildBranchIns = r.ti(hChildBranchIns); + } + + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + double dx = originPosition ? -(0.5 * hTopicIns.getHeight() + / r.sin() + calloutTopicSize.width / 2) : position.x; + double dy = originPosition ? 10 + calloutTopicSize.height + : position.y; + + PrecisionPoint rhChildRef = origin.getTranslated(h.tp(dx, dy)); + PrecisionRectangle hChildBounds = hChildBranchIns + .getBounds(rhChildRef); + + double distTop = (-tan * (hChildBounds.getTopRight().x - topLineX) + + topLineY - hChildBounds.getTopRight().y) + / Math.sqrt(tan * tan + 1); + double distBottom = (-tan + * (hChildBounds.getTopRight().x - bottomLineX) + + bottomLineY - hChildBounds.getTopRight().y) + / Math.sqrt(tan * tan + 1); + double distLimit = hChildBounds.y - rhTopicBounds.y; + + if (distLimit < 0) { + rhChildRef = rhChildRef.getTranslated(0, -distLimit); + hChildBounds = hChildBranchIns.getBounds(rhChildRef); + } + + if (distBottom > 0) { + rhChildRef = rhChildRef.getTranslated(-distBottom / r.sin(), 0); + hChildBounds = hChildBranchIns.getBounds(rhChildRef); + } + + if (hChildBounds.toDraw2DRectangle().touches( + rhTopicBounds.toDraw2DRectangle()) + && distTop > 0) { + rhChildRef = rhChildRef.getTranslated(-distTop / r.sin(), 0); + } + + PrecisionPoint hChildRef = r.tp(rhChildRef); + data.addChildOffset(calloutBranch, h.rp(rhChildRef)); + + hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef)); + rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef)); + } + data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); + data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestNormal.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestNormal.java index 08c1b341f..12109dd30 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestNormal.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestNormal.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.mindmap.IBranchPart; - -public class SouthWestNormal extends AbstractSubFishboneDirection { - - public SouthWestNormal() { - super(true, true, false, WEST, WEST); - } - - public ISubDirection getSubDirection() { - return SWR; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - SE.fillFishboneData(branch, data, h, r, spacing, subbranches); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - SE.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.mindmap.IBranchPart; + +public class SouthWestNormal extends AbstractSubFishboneDirection { + + public SouthWestNormal() { + super(true, true, false, WEST, WEST); + } + + public ISubDirection getSubDirection() { + return SWR; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + SE.fillFishboneData(branch, data, h, r, spacing, subbranches); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + SE.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestRotated.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestRotated.java index d24219353..b76257560 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestRotated.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SouthWestRotated.java @@ -1,46 +1,46 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.mindmap.IBranchPart; - -public class SouthWestRotated extends AbstractSubFishboneDirection { - - public SouthWestRotated() { - super(180.0d - Fishbone.RotateAngle, true, true, false, EAST, EAST); - } - - public ISubDirection getSubDirection() { - return SW; - } - - public void fillFishboneData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - List subbranches) { - SER.fillFishboneData(branch, data, h, r, spacing, subbranches); - } - - @Override - public void fillFishboneExtraData(IBranchPart branch, FishboneData data, - IPrecisionTransformer h, PrecisionRotator r, double spacing, - boolean extraBranch) { - SER.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.mindmap.IBranchPart; + +public class SouthWestRotated extends AbstractSubFishboneDirection { + + public SouthWestRotated() { + super(180.0d - Fishbone.RotateAngle, true, true, false, EAST, EAST); + } + + public ISubDirection getSubDirection() { + return SW; + } + + public void fillFishboneData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + List subbranches) { + SER.fillFishboneData(branch, data, h, r, spacing, subbranches); + } + + @Override + public void fillFishboneExtraData(IBranchPart branch, FishboneData data, + IPrecisionTransformer h, PrecisionRotator r, double spacing, + boolean extraBranch) { + SER.fillFishboneExtraData(branch, data, h, r, spacing, extraBranch); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneData.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneData.java index d068a1883..5348c4c53 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneData.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneData.java @@ -1,146 +1,146 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IRotatableFigure; -import org.xmind.gef.draw2d.IRotatableReferencedFigure; -import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.ui.branch.BranchStructureData; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ILabelPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; - -public class SubFishboneData extends BranchStructureData { - - private static final int PADDING = 1; - - private static final double fMinor = 1d; - - private ISubDirection direction; - - private FishboneData data = null; - - private double padding = -1; - - public final IPrecisionTransformer h = new PrecisionHorizontalFlipper(); - - public final PrecisionRotator r1 = new PrecisionRotator(); - - public final PrecisionRotator r2 = new PrecisionRotator(); - - public SubFishboneData(IBranchPart branch, ISubDirection direction) { - super(branch); - this.direction = direction; - r1.setAngle(direction.isRotated() ? direction.getRotateAngle() - : direction.getSubDirection().getRotateAngle()); - r1.setEnabled(direction.isRotated()); - h.setEnabled(direction.isRightHeaded()); - r2.setAngle(h.isEnabled() ? r1.getAngle() : -r1.getAngle()); - } - - public FishboneData getFishboneData() { - if (data == null) { - data = createFishboneData(); - } - return data; - } - - public double getPadding() { - if (padding < 0) { - padding = calcPadding(); - } - return padding; - } - - private double calcPadding() { - int p = PADDING; - IStyleSelector ss = getBranch().getBranchPolicy().getStyleSelector( - getBranch()); - int lineWidth = StyleUtils.getInteger(getBranch(), ss, - Styles.LineWidth, 1); - p += lineWidth * 0.5d; - return p; - } - - private FishboneData createFishboneData() { - FishboneData data = new FishboneData(); - ITopicPart topicPart = getBranch().getTopicPart(); - if (topicPart != null) { - IFigure figure = topicPart.getFigure(); - if (figure instanceof IRotatableReferencedFigure) { - data.topicRefIns = new PrecisionInsets( - ((IRotatableReferencedFigure) figure) - .getNormalReferenceDescription()); - } - } - ILabelPart label = getBranch().getLabel(); - if (label != null && label.getFigure().isVisible()) { - IFigure labelFigure = label.getFigure(); - PrecisionDimension size; - if (labelFigure instanceof IRotatableFigure) { - size = ((IRotatableFigure) labelFigure).getNormalPreferredSize( - -1, -1); - } else { - size = new PrecisionDimension(label.getFigure() - .getPreferredSize()); - } - if (data.topicRefIns == null) { - data.topicRefIns = new PrecisionInsets(0, size.width / 2, - size.height, size.width / 2); - } else { - data.topicRefIns.left = Math.max(data.topicRefIns.left, - size.width / 2); - data.topicRefIns.right = Math.max(data.topicRefIns.right, - size.width / 2); - data.topicRefIns.bottom += size.height; - } - } - if (data.topicRefIns == null) { - data.topicRefIns = new PrecisionInsets(); - } - data.rTopicRefIns = h.ri(r2.ti(h.ti(data.topicRefIns))); - - data.branchRefIns = new PrecisionInsets(data.topicRefIns); - data.rBranchRefIns = h.ri(r2.ti(h.ti(data.branchRefIns))); - - List calloutBranches = getBranch().getCalloutBranches(); - if (!calloutBranches.isEmpty() && !getBranch().isFolded()) { - this.direction.fillFishboneExtraData(getBranch(), data, h, r2, 0, - true); - } - - if (!getSubBranches().isEmpty() && !getBranch().isFolded()) { - double spacing = getMinorSpacing() * fMinor; - this.direction.fillFishboneData(getBranch(), data, h, r2, spacing, - getSubBranches()); - - double padding = getPadding(); - data.branchRefIns.add(padding); - data.rBranchRefIns.add(padding); - } - - return data; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IRotatableFigure; +import org.xmind.gef.draw2d.IRotatableReferencedFigure; +import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionHorizontalFlipper; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.ui.branch.BranchStructureData; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ILabelPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; + +public class SubFishboneData extends BranchStructureData { + + private static final int PADDING = 1; + + private static final double fMinor = 1d; + + private ISubDirection direction; + + private FishboneData data = null; + + private double padding = -1; + + public final IPrecisionTransformer h = new PrecisionHorizontalFlipper(); + + public final PrecisionRotator r1 = new PrecisionRotator(); + + public final PrecisionRotator r2 = new PrecisionRotator(); + + public SubFishboneData(IBranchPart branch, ISubDirection direction) { + super(branch); + this.direction = direction; + r1.setAngle(direction.isRotated() ? direction.getRotateAngle() + : direction.getSubDirection().getRotateAngle()); + r1.setEnabled(direction.isRotated()); + h.setEnabled(direction.isRightHeaded()); + r2.setAngle(h.isEnabled() ? r1.getAngle() : -r1.getAngle()); + } + + public FishboneData getFishboneData() { + if (data == null) { + data = createFishboneData(); + } + return data; + } + + public double getPadding() { + if (padding < 0) { + padding = calcPadding(); + } + return padding; + } + + private double calcPadding() { + int p = PADDING; + IStyleSelector ss = getBranch().getBranchPolicy().getStyleSelector( + getBranch()); + int lineWidth = StyleUtils.getInteger(getBranch(), ss, + Styles.LineWidth, 1); + p += lineWidth * 0.5d; + return p; + } + + private FishboneData createFishboneData() { + FishboneData data = new FishboneData(); + ITopicPart topicPart = getBranch().getTopicPart(); + if (topicPart != null) { + IFigure figure = topicPart.getFigure(); + if (figure instanceof IRotatableReferencedFigure) { + data.topicRefIns = new PrecisionInsets( + ((IRotatableReferencedFigure) figure) + .getNormalReferenceDescription()); + } + } + ILabelPart label = getBranch().getLabel(); + if (label != null && label.getFigure().isVisible()) { + IFigure labelFigure = label.getFigure(); + PrecisionDimension size; + if (labelFigure instanceof IRotatableFigure) { + size = ((IRotatableFigure) labelFigure).getNormalPreferredSize( + -1, -1); + } else { + size = new PrecisionDimension(label.getFigure() + .getPreferredSize()); + } + if (data.topicRefIns == null) { + data.topicRefIns = new PrecisionInsets(0, size.width / 2, + size.height, size.width / 2); + } else { + data.topicRefIns.left = Math.max(data.topicRefIns.left, + size.width / 2); + data.topicRefIns.right = Math.max(data.topicRefIns.right, + size.width / 2); + data.topicRefIns.bottom += size.height; + } + } + if (data.topicRefIns == null) { + data.topicRefIns = new PrecisionInsets(); + } + data.rTopicRefIns = h.ri(r2.ti(h.ti(data.topicRefIns))); + + data.branchRefIns = new PrecisionInsets(data.topicRefIns); + data.rBranchRefIns = h.ri(r2.ti(h.ti(data.branchRefIns))); + + List calloutBranches = getBranch().getCalloutBranches(); + if (!calloutBranches.isEmpty() && !getBranch().isFolded()) { + this.direction.fillFishboneExtraData(getBranch(), data, h, r2, 0, + true); + } + + if (!getSubBranches().isEmpty() && !getBranch().isFolded()) { + double spacing = getMinorSpacing() * fMinor; + this.direction.fillFishboneData(getBranch(), data, h, r2, spacing, + getSubBranches()); + + double padding = getPadding(); + data.branchRefIns.add(padding); + data.rBranchRefIns.add(padding); + } + + return data; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneStructure.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneStructure.java index cbdb6b3c7..104fd0df6 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneStructure.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/structures/SubFishboneStructure.java @@ -1,707 +1,707 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.fishbone.structures; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.IRotatableReferencedFigure; -import org.xmind.gef.draw2d.ReferencedLayoutData; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.HorizontalFlipper; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionLine; -import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; -import org.xmind.gef.draw2d.geometry.PrecisionLine.Side; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.internal.figures.TopicFigure; -import org.xmind.ui.internal.fishbone.Fishbone; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.INodePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -@SuppressWarnings("restriction") -public class SubFishboneStructure extends AbstractBranchStructure { - - private static final double sin = Math.sin(Math - .toRadians(Fishbone.RotateAngle)); - - private static final double cos = Math.cos(Math - .toRadians(Fishbone.RotateAngle)); - - private ISubDirection direction; - - private ITransformer t = new HorizontalFlipper(); - - public SubFishboneStructure(ISubDirection direction) { - this.direction = direction; - this.t.setEnabled(false); - } - - private double getPadding(IBranchPart branch) { - return getCastedData(branch).getPadding(); - } - - public void fillLayoutData(IBranchPart branch, ReferencedLayoutData data) { - super.fillLayoutData(branch, data); - data.addMargins(new Insets((int) Math.ceil(getPadding(branch)))); - } - - protected void doFillPlusMinus(IBranchPart branch, - IPlusMinusPart plusMinus, LayoutInfo info) { - Point ref = info.getReference(); - SubFishboneData fd = getCastedData(branch); - fd.r1.setOrigin(ref.x, ref.y); - IFigure figure = plusMinus.getFigure(); - Dimension size = figure.getPreferredSize(); - PrecisionRectangle topicBounds = getNormalTopicBounds(branch, ref); - int orientation = getSourceOrientation(branch); - double halfWidth = size.width * 0.5d; - double halfHeight = size.height * 0.5d; - double centerX = orientation == PositionConstants.WEST ? topicBounds.x - - halfWidth : topicBounds.right() + halfWidth; - PrecisionPoint center = fd.r1.tp(new PrecisionPoint(centerX, ref.y)); - Point loc = center.translate(-halfWidth, -halfHeight).toDraw2DPoint(); - info.put(figure, new Rectangle(loc, size)); - } - - private PrecisionRectangle getNormalTopicBounds(IBranchPart branch, - Point ref) { - ITopicPart topic = branch.getTopicPart(); - if (topic != null) { - IFigure figure = topic.getFigure(); - if (figure instanceof IRotatableReferencedFigure) - return ((IRotatableReferencedFigure) figure) - .getNormalPreferredBounds(ref); - } - return new PrecisionRectangle(ref.x, ref.y, 0, 0); - } - - @Override - protected BoundaryLayoutHelper getBoundaryLayoutHelper(IBranchPart branch) { - return super.getBoundaryLayoutHelper(branch); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - Point ref = info.getReference(); - FishboneData fd = getCastedData(branch).getFishboneData(); - for (IBranchPart subBranch : subBranches) { - IFigure figure = subBranch.getFigure(); - Rectangle rect = fd.getChildPrefBounds(subBranch, - new PrecisionPoint(ref)); - - if (rect != null) - info.put(figure, rect); - } - } - - @Override - protected void doFillCalloutBranches(IBranchPart branch, - List calloutBranches, LayoutInfo info) { - Point ref = info.getReference(); - FishboneData fd = getCastedData(branch).getFishboneData(); - for (IBranchPart calloutBranch : calloutBranches) { - IFigure figure = calloutBranch.getFigure(); - Rectangle rect = fd.getChildPrefBounds(calloutBranch, - new PrecisionPoint(ref)); - if (rect != null) - info.put(figure, rect); - } - } - - protected Object createStructureData(IBranchPart branch) { - return new SubFishboneData(branch, direction); - } - - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return super.isValidStructureData(branch, data) - && (data instanceof SubFishboneData); - } - - protected SubFishboneData getCastedData(IBranchPart branch) { - return (SubFishboneData) super.getStructureData(branch); - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - PrecisionLine boneLine = getBoneLine(branch); - PrecisionPoint source = calcSourceLocation(branch, boneLine); - PrecisionLine sourceRay = getBoneRay(source); - List subBranches = branch.getSubBranches(); - boolean folded = branch.isFolded(); -// PrecisionPoint offset = calcChildOffset(branch, key.getFeedback(), -// boneLine, sourceRay); - PrecisionLine childBoneLine = getChildBoneLine(branch, - key.getFeedback()); - double offset = calcChildOffset(boneLine, sourceRay, childBoneLine); - if (offset > 0) { - double range; - if (!subBranches.isEmpty() && !folded) { - int lastIndex = direction.isChildrenTraverseReversed() ? 0 - : subBranches.size() - 1; - IBranchPart lastChild = subBranches.get(lastIndex); -// PrecisionPoint lastOffset = calcChildOffset(branch, lastChild, -// boneLine, sourceRay); - double lastOffset = calcChildOffset(boneLine, sourceRay, - getChildBoneLine(branch, lastChild)); - range = lastOffset + MindMapUI.SEARCH_RANGE; - } else { - range = MindMapUI.SEARCH_RANGE; - } - if (offset < range) { - double distance = calcChildDistance(boneLine, childBoneLine); - if (distance > 0 && distance < MindMapUI.SEARCH_RANGE) - return Math.max(1, (int) distance); - } - } - return super.calcChildDistance(branch, key); - } - - private double calcChildDistance(PrecisionLine boneLine, - PrecisionLine childLine) { - PrecisionPoint target = childLine.getOrigin(); - Side childSide = boneLine.getSide(target); - if (needsCalcChildDistance(childSide)) - return Geometry.getDistance(target, boneLine); - return -1; - } - - private double calcChildOffset(PrecisionLine boneLine, - PrecisionLine sourceRay, PrecisionLine childLine) { - PrecisionPoint joint = boneLine.intersect(childLine); - PrecisionDimension offset = joint.getDifference(sourceRay.getOrigin()); - double off = offset.getDiagonal(); - if (!sourceRay.contains(joint)) { - off = -off; - } - return off; - } - - private boolean needsCalcChildDistance(Side childSide) { - if (childSide == Side.Right) - return direction == ISubDirection.NER - || direction == ISubDirection.SE - || direction == ISubDirection.NW - || direction == ISubDirection.SWR; - if (childSide == Side.Left) - return direction == ISubDirection.NE - || direction == ISubDirection.SER - || direction == ISubDirection.NWR - || direction == ISubDirection.SW; - return false; - } - -// private PrecisionPoint calcChildOffset(IBranchPart branch, -// IBranchPart child, PrecisionPoint source) { -// -// PrecisionPoint target = calcChildTargetLocation(branch, child, source); -// PrecisionDimension d = target.getDifference(source); -// SubFishboneStructureData fd = getCastedData(branch); -// double w = d.height * fd.r1.cos() / fd.r1.sin(); -// double jointOffset = d.width - w; -// if (direction.isRightHeaded()) -// jointOffset = -jointOffset; -// double distance = direction.isDownwards() ? d.height : -d.height; -// PrecisionPoint offset = new PrecisionPoint(jointOffset, distance); -// return direction.isRotated() ? offset.transpose() : offset; -// } - - private PrecisionLine getBoneLine(IBranchPart branch) { - IAnchor anchor = ((INodePart) branch.getTopicPart()) - .getSourceAnchor(branch); - int orientation = getSourceOrientation(branch); - PrecisionPoint p1 = anchor.getLocation( - Geometry.getOppositePosition(orientation), 0); - PrecisionPoint p2 = anchor.getLocation(orientation, 0); - return new PrecisionLine(p1, p2, LineType.Line); - } - - private PrecisionLine getChildBoneLine(IBranchPart branch, IBranchPart child) { - IAnchor anchor = ((INodePart) child.getTopicPart()) - .getTargetAnchor(branch); - int orientation = getChildTargetOrientation(branch, child); - PrecisionPoint p1 = anchor.getLocation(orientation, 0); - double angle = direction.getSubDirection().getRotateAngle(); - PrecisionPoint p2 = p1.getMoved(Math.toRadians(angle), 100); - return new PrecisionLine(p1, p2, LineType.Line); - } - - private PrecisionPoint calcSourceLocation(IBranchPart branch, - PrecisionLine boneLine) { - if (!branch.getSubBranches().isEmpty() && !branch.isFolded() - && direction.isRotated()) { - PrecisionPoint ref = new PrecisionPoint(((IReferencedFigure) branch - .getTopicPart().getFigure()).getReference()); - PrecisionPoint p = ref.getMoved( - Math.toRadians(-direction.getRotateAngle()), 100); - return boneLine.intersect(new PrecisionLine(ref, p, LineType.Line)); - } - return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) - .getLocation(getSourceOrientation(branch), 0); - } - - private PrecisionLine getBoneRay(PrecisionPoint p) { - double angle = direction.getRotateAngle(); - if (direction == ISubDirection.SER || direction == ISubDirection.NWR - || direction == ISubDirection.NW - || direction == ISubDirection.SW) { - angle = 180 + angle; - } - return new PrecisionLine(p, p.getMoved(Math.toRadians(angle), 100), - LineType.Ray); - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return new Insertion(branch, calcInsIndex(branch, key, true), key - .getFigure().getSize()); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - PrecisionLine boneLine = getBoneLine(branch); - PrecisionPoint source = calcSourceLocation(branch, boneLine); - PrecisionLine sourceRay = getBoneRay(source); - double offset = calcChildOffset(boneLine, sourceRay, - getChildBoneLine(branch, key.getFeedback())); - - boolean reversed = direction.isChildrenTraverseReversed(); - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - int ret = 0; - for (IBranchPart subBranch : subBranches) { - double subOffset = calcChildOffset(boneLine, sourceRay, - getChildBoneLine(branch, subBranch)); - if (reversed) { - if (offset > subOffset) - return ret; - } else { - if (offset < subOffset) - return ret; - } - if (withDisabled || subBranch.getFigure().isEnabled()) { - ret++; - } - } - return withDisabled ? num : -1; - } - -// private PrecisionPoint calcSourceLocation(IBranchPart branch) { -//// return new PrecisionPoint(((IReferencedFigure) branch.getTopicPart() -//// .getFigure()).getReference()); -// return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) -// .getLocation(calcSourceOrientation(branch), 0); -// } -// -// private PrecisionPoint calcChildTargetLocation(IBranchPart branch, -// IBranchPart child, PrecisionPoint source) { -// ITopicPart topic = child.getTopicPart(); -// if (topic instanceof INodePart) { -// IAnchor anchor = ((INodePart) topic).getTargetAnchor(branch); -// if (anchor != null) { -// return anchor.getLocation(calcChildTargetOrientation(branch, -// child), 0); -// } -// } -// return new PrecisionPoint(getReference(child)); -// } - -// private Point getReference(IBranchPart branch) { -// ITopicPart topic = branch.getTopicPart(); -// if (topic != null) -// return ((IReferencedFigure) topic.getFigure()).getReference(); -// return ((IReferencedFigure) branch.getFigure()).getReference(); -// } - -// public Object calcNavigation(IBranchPart branch, int direction) { -// int nav = this.direction.calcNavigation(direction); -// if (nav == GEF.NAVI_PREV && branch.getBranchIndex() == 0) -// nav = GEF.NAVI_PARENT; -// return nav; -// } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (direction.isRotated()) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (direction.isRightHeaded()) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return branch.getTopicPart(); - } - } else { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return branch.getTopicPart(); - } - } - } - } else { - String prevType = direction.isRightHeaded() ? GEF.REQ_NAV_RIGHT - : GEF.REQ_NAV_LEFT; - String nextType = direction.isRightHeaded() ? GEF.REQ_NAV_LEFT - : GEF.REQ_NAV_RIGHT; - if (prevType.equals(navReqType)) { - ITopicPart prev = getSubTopicPart(branch, - sourceChild.getBranchIndex() - 1); - if (prev == null && !sequential) - return branch.getTopicPart(); - return prev; - } else if (nextType.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (isNavChild(branch, navReqType)) { - if (direction.isChildrenTraverseReversed()) - return getSubTopicPart(branch, - branch.getSubBranches().size() - 1); - return getSubTopicPart(branch, 0); - } - return super.calcNavigation(branch, navReqType); - } - - private boolean isNavChild(IBranchPart branch, String navReqType) { - if (direction.isRotated()) { - if (direction.isDownwards()) { - if (GEF.REQ_NAV_DOWN.equals(navReqType)) - return true; - } else { - if (GEF.REQ_NAV_UP.equals(navReqType)) - return true; - } - } - if (direction.isRightHeaded()) - return GEF.REQ_NAV_LEFT.equals(navReqType); - return GEF.REQ_NAV_RIGHT.equals(navReqType); - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - if (!branch.getSubBranches().contains(subBranch)) { - return direction.isRightHeaded() ? PositionConstants.EAST - : PositionConstants.WEST; - } - return direction.getChildTargetOrientation(); - } - - public int getSourceOrientation(IBranchPart branch) { - return direction.getSourceOrientation(); - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return getRangeGrowthDirection(); - } - - private int getRangeGrowthDirection() { - if (direction.isRotated()) - return PositionConstants.SOUTH; - return direction.isRightHeaded() ? PositionConstants.EAST - : PositionConstants.WEST; - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - if (direction.isRotated()) - return direction.isRightHeaded() ? PositionConstants.EAST - : PositionConstants.EAST; - return direction.isDownwards() ? PositionConstants.SOUTH - : PositionConstants.NORTH; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - int rangeGrowthDirection = getRangeGrowthDirection(); - if (direction == rangeGrowthDirection) - return 1; - if (direction == Geometry.getOppositePosition(rangeGrowthDirection)) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - int index = calcInsIndex(branch, key, true); - - if (index == subBranches.size()) { - return calcInventPosition(subBranches.get(index - 1), null, key, - false); - } - return calcInventPosition(subBranches.get(index), null, key, true); - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - Dimension inventSize = key.getInvent().getSize(); - - if (index == oldIndex) { - if (direction.isRotated()) { - IBranchPart sub = subBranches.get(index); - Dimension size = sub.getTopicPart().getFigure().getSize(); - int deltaX = (size.width - inventSize.width) / 2; - - return getFigureLocation(sub.getFigure()).getTranslated( - direction.isRightHeaded() ? deltaX : -deltaX, 0); - } else { - IBranchPart sub = subBranches.get(index); - Dimension size = sub.getTopicPart().getFigure().getSize(); - - double w = (size.height * sin - size.width * cos) - / (sin * sin - cos * cos); - - double deltaX = size.width * 0.5d - w * cos + inventSize.width - * 0.5d + inventSize.width * cos * 0.5d; - double deltaY = direction.isDownwards() ? (-size.height + inventSize.width - * sin) * 0.5d - : (size.height - inventSize.width * sin) * 0.5d; - - return getFigureLocation(sub.getFigure()).getTranslated( - direction.isRightHeaded() ? -deltaX : deltaX, deltaY); - } - } - - return calcInsertPosition(branch, child, key); - } - - @Override - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - if (direction.isRotated()) - return calcFirstNormalPosition(branch, key); - else - return clacFirstRotatedPosition(branch, key); - } - - private Point calcFirstNormalPosition(IBranchPart branch, - ParentSearchKey key) { - Dimension size = branch.getTopicPart().getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - double h = (size.width * sin - size.height * cos) - / (sin * sin - cos * cos); - double x = h * sin * 0.5d + inventSize.height * cos / sin - + inventSize.width * 0.5d; - - return getFigureLocation(branch.getFigure()).getTranslated( - direction.isRightHeaded() ? -x : x, - direction.isDownwards() ? inventSize.height * 0.5d - : -inventSize.height * 0.5d); - } - - private Point clacFirstRotatedPosition(IBranchPart branch, - ParentSearchKey key) { - Dimension size = branch.getTopicPart().getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - double x = size.width * 0.5d + key.getFigure().getSize().height * sin - * 0.5d + inventSize.width * (1 + cos) * 0.5d; - - return getFigureLocation(branch.getFigure()).getTranslated( - direction.isRightHeaded() ? -x : x, - size.height - * 0.5d - + (direction.isDownwards() ? inventSize.width * sin - * 0.5d : -inventSize.width * sin * 0.5d)); - } - - @Override - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isBeforeOrientation) { - if (direction.isRotated()) - return calcNormalPosition(orientation, key, isBeforeOrientation); - else - return calcRotatedPosition(orientation, key, isBeforeOrientation); - - } - - private Point calcNormalPosition(IBranchPart orientation, - ParentSearchKey key, boolean isBeforeOrientation) { - Dimension subSize = orientation.getTopicPart().getFigure().getSize(); - Point loc = getFigureLocation(orientation.getTopicPart().getFigure()); - Rectangle bounds = orientation.getFigure().getBounds(); - int top = bounds.y; - int bottom = bounds.bottom(); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - double cot = cos / sin; - - double x; - - double right = loc.x + (subSize.width - inventSize.width) * 0.5d; - double left = loc.x - (subSize.width - inventSize.width) * 0.5d; - if (isBeforeOrientation) { - if (direction.equals(ISubDirection.NWR)) { - x = right - - (loc.y - top - subSize.height * 0.5d + (insSize.height + inventSize.height) * 0.5d) - * cot; - } else if (direction.equals(ISubDirection.SWR)) { - x = right - + (loc.y - top + subSize.height * 0.5d + (insSize.height - inventSize.height) * 0.5d) - * cot; - } else if (direction.equals(ISubDirection.NER)) { - x = left - + (loc.y - top - subSize.height * 0.5 + (insSize.height + inventSize.height) * 0.5d) - * cot; - } else { - x = left - - (loc.y - top + subSize.height * 0.5 + (insSize.height - inventSize.height) * 0.5d) - * cot; - } - } else { - if (direction.equals(ISubDirection.NWR)) { - x = right - + (bottom - loc.y + subSize.height * 0.5d + (insSize.height - inventSize.height) * 0.5d) - * cot; - } else if (direction.equals(ISubDirection.SWR)) { - x = right - - (bottom - loc.y - subSize.height * 0.5d + (insSize.height + inventSize.height) * 0.5d) - * cot; - } else if (direction.equals(ISubDirection.NER)) { - x = left - - (top - loc.y + subSize.height * 0.5 + (insSize.height - inventSize.height) * 0.5d) - * cot; - } else { - x = left - + (bottom - loc.y - subSize.height * 0.5 + (insSize.height + inventSize.height) * 0.5d) - * cot; - } - } - - double y; - if (isBeforeOrientation) - y = top - (insSize.height) * 0.5d; - else - y = bottom + (insSize.height) * 0.5d; - - return new Point().getTranslated(x, y); - } - - private Point calcRotatedPosition(IBranchPart orientation, - ParentSearchKey key, boolean isBeforeOrientation) { - double baseY = getBoneLine(orientation.getParentBranch()).getOrigin().y; - Dimension inventSize = key.getInvent().getSize(); - Dimension insSize = key.getFigure().getSize(); - - double deltaY = inventSize.width * sin * 0.5d; - double y = baseY + (direction.isDownwards() ? deltaY : -deltaY); - - double x; - if (isBeforeOrientation) { - double offset = calcBeforeOffset(orientation); - - double deltaX = (insSize.height / sin - inventSize.width * cos - inventSize.width) * 0.5d; - - x = offset + (direction.isRightHeaded() ? deltaX : -deltaX); - } else { - Rectangle pBounds = orientation.getParentBranch().getFigure() - .getBounds(); - - x = direction.isRightHeaded() ? pBounds.x - - (inventSize.width * cos + inventSize.width) * 0.5 - : pBounds.right() - + (inventSize.width * cos + inventSize.width) * 0.5; - } - - return new Point().getTranslated(x, y); - } - - private double calcBeforeOffset(IBranchPart branch) { - double offset = 0.0d; - PrecisionLine boneLine = getBoneLine(branch.getParentBranch()); - - double cot = cos / sin; - - List callouts = branch.getCalloutBranches(); - if (callouts == null || callouts.isEmpty()) { - IFigure figure = branch.getTopicPart().getFigure(); - Rectangle bounds = figure.getBounds(); - double height = ((TopicFigure) figure) - .getNormalPreferredBounds(new Point()).height; - double delta = height * cos * cot; - offset = direction.isRightHeaded() ? bounds.right() + delta - : bounds.x - delta; - } else { - double y = boneLine.getOrigin().y; - Rectangle bounds = branch.getFigure().getBounds(); - offset = direction.isRightHeaded() ? bounds.right() : bounds.x; - - for (IBranchPart callout : callouts) { - Rectangle calloutBounds = callout.getFigure().getBounds(); - if (direction.equals(ISubDirection.NE)) { - Point tl = calloutBounds.getTopLeft(); - offset = Math.min(offset, tl.x - (y - tl.y) * cot); - } else if (direction.equals(ISubDirection.SE)) { - Point bl = calloutBounds.getBottomLeft(); - offset = Math.min(offset, bl.x - (bl.y - y) * cot); - } else if (direction.equals(ISubDirection.NW)) { - Point tr = calloutBounds.getTopRight(); - offset = Math.max(offset, tr.x + (y - tr.y) * cot); - } else { - Point br = calloutBounds.getBottomRight(); - offset = Math.max(offset, br.x + (br.y - y) * cot); - } - } - } - - return offset; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.fishbone.structures; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.IRotatableReferencedFigure; +import org.xmind.gef.draw2d.ReferencedLayoutData; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.HorizontalFlipper; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionLine; +import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; +import org.xmind.gef.draw2d.geometry.PrecisionLine.Side; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.internal.figures.TopicFigure; +import org.xmind.ui.internal.fishbone.Fishbone; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.INodePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +@SuppressWarnings("restriction") +public class SubFishboneStructure extends AbstractBranchStructure { + + private static final double sin = Math.sin(Math + .toRadians(Fishbone.RotateAngle)); + + private static final double cos = Math.cos(Math + .toRadians(Fishbone.RotateAngle)); + + private ISubDirection direction; + + private ITransformer t = new HorizontalFlipper(); + + public SubFishboneStructure(ISubDirection direction) { + this.direction = direction; + this.t.setEnabled(false); + } + + private double getPadding(IBranchPart branch) { + return getCastedData(branch).getPadding(); + } + + public void fillLayoutData(IBranchPart branch, ReferencedLayoutData data) { + super.fillLayoutData(branch, data); + data.addMargins(new Insets((int) Math.ceil(getPadding(branch)))); + } + + protected void doFillPlusMinus(IBranchPart branch, + IPlusMinusPart plusMinus, LayoutInfo info) { + Point ref = info.getReference(); + SubFishboneData fd = getCastedData(branch); + fd.r1.setOrigin(ref.x, ref.y); + IFigure figure = plusMinus.getFigure(); + Dimension size = figure.getPreferredSize(); + PrecisionRectangle topicBounds = getNormalTopicBounds(branch, ref); + int orientation = getSourceOrientation(branch); + double halfWidth = size.width * 0.5d; + double halfHeight = size.height * 0.5d; + double centerX = orientation == PositionConstants.WEST ? topicBounds.x + - halfWidth : topicBounds.right() + halfWidth; + PrecisionPoint center = fd.r1.tp(new PrecisionPoint(centerX, ref.y)); + Point loc = center.translate(-halfWidth, -halfHeight).toDraw2DPoint(); + info.put(figure, new Rectangle(loc, size)); + } + + private PrecisionRectangle getNormalTopicBounds(IBranchPart branch, + Point ref) { + ITopicPart topic = branch.getTopicPart(); + if (topic != null) { + IFigure figure = topic.getFigure(); + if (figure instanceof IRotatableReferencedFigure) + return ((IRotatableReferencedFigure) figure) + .getNormalPreferredBounds(ref); + } + return new PrecisionRectangle(ref.x, ref.y, 0, 0); + } + + @Override + protected BoundaryLayoutHelper getBoundaryLayoutHelper(IBranchPart branch) { + return super.getBoundaryLayoutHelper(branch); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + Point ref = info.getReference(); + FishboneData fd = getCastedData(branch).getFishboneData(); + for (IBranchPart subBranch : subBranches) { + IFigure figure = subBranch.getFigure(); + Rectangle rect = fd.getChildPrefBounds(subBranch, + new PrecisionPoint(ref)); + + if (rect != null) + info.put(figure, rect); + } + } + + @Override + protected void doFillCalloutBranches(IBranchPart branch, + List calloutBranches, LayoutInfo info) { + Point ref = info.getReference(); + FishboneData fd = getCastedData(branch).getFishboneData(); + for (IBranchPart calloutBranch : calloutBranches) { + IFigure figure = calloutBranch.getFigure(); + Rectangle rect = fd.getChildPrefBounds(calloutBranch, + new PrecisionPoint(ref)); + if (rect != null) + info.put(figure, rect); + } + } + + protected Object createStructureData(IBranchPart branch) { + return new SubFishboneData(branch, direction); + } + + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return super.isValidStructureData(branch, data) + && (data instanceof SubFishboneData); + } + + protected SubFishboneData getCastedData(IBranchPart branch) { + return (SubFishboneData) super.getStructureData(branch); + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + PrecisionLine boneLine = getBoneLine(branch); + PrecisionPoint source = calcSourceLocation(branch, boneLine); + PrecisionLine sourceRay = getBoneRay(source); + List subBranches = branch.getSubBranches(); + boolean folded = branch.isFolded(); +// PrecisionPoint offset = calcChildOffset(branch, key.getFeedback(), +// boneLine, sourceRay); + PrecisionLine childBoneLine = getChildBoneLine(branch, + key.getFeedback()); + double offset = calcChildOffset(boneLine, sourceRay, childBoneLine); + if (offset > 0) { + double range; + if (!subBranches.isEmpty() && !folded) { + int lastIndex = direction.isChildrenTraverseReversed() ? 0 + : subBranches.size() - 1; + IBranchPart lastChild = subBranches.get(lastIndex); +// PrecisionPoint lastOffset = calcChildOffset(branch, lastChild, +// boneLine, sourceRay); + double lastOffset = calcChildOffset(boneLine, sourceRay, + getChildBoneLine(branch, lastChild)); + range = lastOffset + MindMapUI.SEARCH_RANGE; + } else { + range = MindMapUI.SEARCH_RANGE; + } + if (offset < range) { + double distance = calcChildDistance(boneLine, childBoneLine); + if (distance > 0 && distance < MindMapUI.SEARCH_RANGE) + return Math.max(1, (int) distance); + } + } + return super.calcChildDistance(branch, key); + } + + private double calcChildDistance(PrecisionLine boneLine, + PrecisionLine childLine) { + PrecisionPoint target = childLine.getOrigin(); + Side childSide = boneLine.getSide(target); + if (needsCalcChildDistance(childSide)) + return Geometry.getDistance(target, boneLine); + return -1; + } + + private double calcChildOffset(PrecisionLine boneLine, + PrecisionLine sourceRay, PrecisionLine childLine) { + PrecisionPoint joint = boneLine.intersect(childLine); + PrecisionDimension offset = joint.getDifference(sourceRay.getOrigin()); + double off = offset.getDiagonal(); + if (!sourceRay.contains(joint)) { + off = -off; + } + return off; + } + + private boolean needsCalcChildDistance(Side childSide) { + if (childSide == Side.Right) + return direction == ISubDirection.NER + || direction == ISubDirection.SE + || direction == ISubDirection.NW + || direction == ISubDirection.SWR; + if (childSide == Side.Left) + return direction == ISubDirection.NE + || direction == ISubDirection.SER + || direction == ISubDirection.NWR + || direction == ISubDirection.SW; + return false; + } + +// private PrecisionPoint calcChildOffset(IBranchPart branch, +// IBranchPart child, PrecisionPoint source) { +// +// PrecisionPoint target = calcChildTargetLocation(branch, child, source); +// PrecisionDimension d = target.getDifference(source); +// SubFishboneStructureData fd = getCastedData(branch); +// double w = d.height * fd.r1.cos() / fd.r1.sin(); +// double jointOffset = d.width - w; +// if (direction.isRightHeaded()) +// jointOffset = -jointOffset; +// double distance = direction.isDownwards() ? d.height : -d.height; +// PrecisionPoint offset = new PrecisionPoint(jointOffset, distance); +// return direction.isRotated() ? offset.transpose() : offset; +// } + + private PrecisionLine getBoneLine(IBranchPart branch) { + IAnchor anchor = ((INodePart) branch.getTopicPart()) + .getSourceAnchor(branch); + int orientation = getSourceOrientation(branch); + PrecisionPoint p1 = anchor.getLocation( + Geometry.getOppositePosition(orientation), 0); + PrecisionPoint p2 = anchor.getLocation(orientation, 0); + return new PrecisionLine(p1, p2, LineType.Line); + } + + private PrecisionLine getChildBoneLine(IBranchPart branch, IBranchPart child) { + IAnchor anchor = ((INodePart) child.getTopicPart()) + .getTargetAnchor(branch); + int orientation = getChildTargetOrientation(branch, child); + PrecisionPoint p1 = anchor.getLocation(orientation, 0); + double angle = direction.getSubDirection().getRotateAngle(); + PrecisionPoint p2 = p1.getMoved(Math.toRadians(angle), 100); + return new PrecisionLine(p1, p2, LineType.Line); + } + + private PrecisionPoint calcSourceLocation(IBranchPart branch, + PrecisionLine boneLine) { + if (!branch.getSubBranches().isEmpty() && !branch.isFolded() + && direction.isRotated()) { + PrecisionPoint ref = new PrecisionPoint(((IReferencedFigure) branch + .getTopicPart().getFigure()).getReference()); + PrecisionPoint p = ref.getMoved( + Math.toRadians(-direction.getRotateAngle()), 100); + return boneLine.intersect(new PrecisionLine(ref, p, LineType.Line)); + } + return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) + .getLocation(getSourceOrientation(branch), 0); + } + + private PrecisionLine getBoneRay(PrecisionPoint p) { + double angle = direction.getRotateAngle(); + if (direction == ISubDirection.SER || direction == ISubDirection.NWR + || direction == ISubDirection.NW + || direction == ISubDirection.SW) { + angle = 180 + angle; + } + return new PrecisionLine(p, p.getMoved(Math.toRadians(angle), 100), + LineType.Ray); + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return new Insertion(branch, calcInsIndex(branch, key, true), key + .getFigure().getSize()); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + PrecisionLine boneLine = getBoneLine(branch); + PrecisionPoint source = calcSourceLocation(branch, boneLine); + PrecisionLine sourceRay = getBoneRay(source); + double offset = calcChildOffset(boneLine, sourceRay, + getChildBoneLine(branch, key.getFeedback())); + + boolean reversed = direction.isChildrenTraverseReversed(); + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + int ret = 0; + for (IBranchPart subBranch : subBranches) { + double subOffset = calcChildOffset(boneLine, sourceRay, + getChildBoneLine(branch, subBranch)); + if (reversed) { + if (offset > subOffset) + return ret; + } else { + if (offset < subOffset) + return ret; + } + if (withDisabled || subBranch.getFigure().isEnabled()) { + ret++; + } + } + return withDisabled ? num : -1; + } + +// private PrecisionPoint calcSourceLocation(IBranchPart branch) { +//// return new PrecisionPoint(((IReferencedFigure) branch.getTopicPart() +//// .getFigure()).getReference()); +// return ((INodePart) branch.getTopicPart()).getSourceAnchor(branch) +// .getLocation(calcSourceOrientation(branch), 0); +// } +// +// private PrecisionPoint calcChildTargetLocation(IBranchPart branch, +// IBranchPart child, PrecisionPoint source) { +// ITopicPart topic = child.getTopicPart(); +// if (topic instanceof INodePart) { +// IAnchor anchor = ((INodePart) topic).getTargetAnchor(branch); +// if (anchor != null) { +// return anchor.getLocation(calcChildTargetOrientation(branch, +// child), 0); +// } +// } +// return new PrecisionPoint(getReference(child)); +// } + +// private Point getReference(IBranchPart branch) { +// ITopicPart topic = branch.getTopicPart(); +// if (topic != null) +// return ((IReferencedFigure) topic.getFigure()).getReference(); +// return ((IReferencedFigure) branch.getFigure()).getReference(); +// } + +// public Object calcNavigation(IBranchPart branch, int direction) { +// int nav = this.direction.calcNavigation(direction); +// if (nav == GEF.NAVI_PREV && branch.getBranchIndex() == 0) +// nav = GEF.NAVI_PARENT; +// return nav; +// } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (direction.isRotated()) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (direction.isRightHeaded()) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return branch.getTopicPart(); + } + } else { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return branch.getTopicPart(); + } + } + } + } else { + String prevType = direction.isRightHeaded() ? GEF.REQ_NAV_RIGHT + : GEF.REQ_NAV_LEFT; + String nextType = direction.isRightHeaded() ? GEF.REQ_NAV_LEFT + : GEF.REQ_NAV_RIGHT; + if (prevType.equals(navReqType)) { + ITopicPart prev = getSubTopicPart(branch, + sourceChild.getBranchIndex() - 1); + if (prev == null && !sequential) + return branch.getTopicPart(); + return prev; + } else if (nextType.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (isNavChild(branch, navReqType)) { + if (direction.isChildrenTraverseReversed()) + return getSubTopicPart(branch, + branch.getSubBranches().size() - 1); + return getSubTopicPart(branch, 0); + } + return super.calcNavigation(branch, navReqType); + } + + private boolean isNavChild(IBranchPart branch, String navReqType) { + if (direction.isRotated()) { + if (direction.isDownwards()) { + if (GEF.REQ_NAV_DOWN.equals(navReqType)) + return true; + } else { + if (GEF.REQ_NAV_UP.equals(navReqType)) + return true; + } + } + if (direction.isRightHeaded()) + return GEF.REQ_NAV_LEFT.equals(navReqType); + return GEF.REQ_NAV_RIGHT.equals(navReqType); + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + if (!branch.getSubBranches().contains(subBranch)) { + return direction.isRightHeaded() ? PositionConstants.EAST + : PositionConstants.WEST; + } + return direction.getChildTargetOrientation(); + } + + public int getSourceOrientation(IBranchPart branch) { + return direction.getSourceOrientation(); + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return getRangeGrowthDirection(); + } + + private int getRangeGrowthDirection() { + if (direction.isRotated()) + return PositionConstants.SOUTH; + return direction.isRightHeaded() ? PositionConstants.EAST + : PositionConstants.WEST; + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + if (direction.isRotated()) + return direction.isRightHeaded() ? PositionConstants.EAST + : PositionConstants.EAST; + return direction.isDownwards() ? PositionConstants.SOUTH + : PositionConstants.NORTH; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + int rangeGrowthDirection = getRangeGrowthDirection(); + if (direction == rangeGrowthDirection) + return 1; + if (direction == Geometry.getOppositePosition(rangeGrowthDirection)) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + int index = calcInsIndex(branch, key, true); + + if (index == subBranches.size()) { + return calcInventPosition(subBranches.get(index - 1), null, key, + false); + } + return calcInventPosition(subBranches.get(index), null, key, true); + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + Dimension inventSize = key.getInvent().getSize(); + + if (index == oldIndex) { + if (direction.isRotated()) { + IBranchPart sub = subBranches.get(index); + Dimension size = sub.getTopicPart().getFigure().getSize(); + int deltaX = (size.width - inventSize.width) / 2; + + return getFigureLocation(sub.getFigure()).getTranslated( + direction.isRightHeaded() ? deltaX : -deltaX, 0); + } else { + IBranchPart sub = subBranches.get(index); + Dimension size = sub.getTopicPart().getFigure().getSize(); + + double w = (size.height * sin - size.width * cos) + / (sin * sin - cos * cos); + + double deltaX = size.width * 0.5d - w * cos + inventSize.width + * 0.5d + inventSize.width * cos * 0.5d; + double deltaY = direction.isDownwards() ? (-size.height + inventSize.width + * sin) * 0.5d + : (size.height - inventSize.width * sin) * 0.5d; + + return getFigureLocation(sub.getFigure()).getTranslated( + direction.isRightHeaded() ? -deltaX : deltaX, deltaY); + } + } + + return calcInsertPosition(branch, child, key); + } + + @Override + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + if (direction.isRotated()) + return calcFirstNormalPosition(branch, key); + else + return clacFirstRotatedPosition(branch, key); + } + + private Point calcFirstNormalPosition(IBranchPart branch, + ParentSearchKey key) { + Dimension size = branch.getTopicPart().getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + double h = (size.width * sin - size.height * cos) + / (sin * sin - cos * cos); + double x = h * sin * 0.5d + inventSize.height * cos / sin + + inventSize.width * 0.5d; + + return getFigureLocation(branch.getFigure()).getTranslated( + direction.isRightHeaded() ? -x : x, + direction.isDownwards() ? inventSize.height * 0.5d + : -inventSize.height * 0.5d); + } + + private Point clacFirstRotatedPosition(IBranchPart branch, + ParentSearchKey key) { + Dimension size = branch.getTopicPart().getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + double x = size.width * 0.5d + key.getFigure().getSize().height * sin + * 0.5d + inventSize.width * (1 + cos) * 0.5d; + + return getFigureLocation(branch.getFigure()).getTranslated( + direction.isRightHeaded() ? -x : x, + size.height + * 0.5d + + (direction.isDownwards() ? inventSize.width * sin + * 0.5d : -inventSize.width * sin * 0.5d)); + } + + @Override + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isBeforeOrientation) { + if (direction.isRotated()) + return calcNormalPosition(orientation, key, isBeforeOrientation); + else + return calcRotatedPosition(orientation, key, isBeforeOrientation); + + } + + private Point calcNormalPosition(IBranchPart orientation, + ParentSearchKey key, boolean isBeforeOrientation) { + Dimension subSize = orientation.getTopicPart().getFigure().getSize(); + Point loc = getFigureLocation(orientation.getTopicPart().getFigure()); + Rectangle bounds = orientation.getFigure().getBounds(); + int top = bounds.y; + int bottom = bounds.bottom(); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + double cot = cos / sin; + + double x; + + double right = loc.x + (subSize.width - inventSize.width) * 0.5d; + double left = loc.x - (subSize.width - inventSize.width) * 0.5d; + if (isBeforeOrientation) { + if (direction.equals(ISubDirection.NWR)) { + x = right + - (loc.y - top - subSize.height * 0.5d + (insSize.height + inventSize.height) * 0.5d) + * cot; + } else if (direction.equals(ISubDirection.SWR)) { + x = right + + (loc.y - top + subSize.height * 0.5d + (insSize.height - inventSize.height) * 0.5d) + * cot; + } else if (direction.equals(ISubDirection.NER)) { + x = left + + (loc.y - top - subSize.height * 0.5 + (insSize.height + inventSize.height) * 0.5d) + * cot; + } else { + x = left + - (loc.y - top + subSize.height * 0.5 + (insSize.height - inventSize.height) * 0.5d) + * cot; + } + } else { + if (direction.equals(ISubDirection.NWR)) { + x = right + + (bottom - loc.y + subSize.height * 0.5d + (insSize.height - inventSize.height) * 0.5d) + * cot; + } else if (direction.equals(ISubDirection.SWR)) { + x = right + - (bottom - loc.y - subSize.height * 0.5d + (insSize.height + inventSize.height) * 0.5d) + * cot; + } else if (direction.equals(ISubDirection.NER)) { + x = left + - (top - loc.y + subSize.height * 0.5 + (insSize.height - inventSize.height) * 0.5d) + * cot; + } else { + x = left + + (bottom - loc.y - subSize.height * 0.5 + (insSize.height + inventSize.height) * 0.5d) + * cot; + } + } + + double y; + if (isBeforeOrientation) + y = top - (insSize.height) * 0.5d; + else + y = bottom + (insSize.height) * 0.5d; + + return new Point().getTranslated(x, y); + } + + private Point calcRotatedPosition(IBranchPart orientation, + ParentSearchKey key, boolean isBeforeOrientation) { + double baseY = getBoneLine(orientation.getParentBranch()).getOrigin().y; + Dimension inventSize = key.getInvent().getSize(); + Dimension insSize = key.getFigure().getSize(); + + double deltaY = inventSize.width * sin * 0.5d; + double y = baseY + (direction.isDownwards() ? deltaY : -deltaY); + + double x; + if (isBeforeOrientation) { + double offset = calcBeforeOffset(orientation); + + double deltaX = (insSize.height / sin - inventSize.width * cos - inventSize.width) * 0.5d; + + x = offset + (direction.isRightHeaded() ? deltaX : -deltaX); + } else { + Rectangle pBounds = orientation.getParentBranch().getFigure() + .getBounds(); + + x = direction.isRightHeaded() ? pBounds.x + - (inventSize.width * cos + inventSize.width) * 0.5 + : pBounds.right() + + (inventSize.width * cos + inventSize.width) * 0.5; + } + + return new Point().getTranslated(x, y); + } + + private double calcBeforeOffset(IBranchPart branch) { + double offset = 0.0d; + PrecisionLine boneLine = getBoneLine(branch.getParentBranch()); + + double cot = cos / sin; + + List callouts = branch.getCalloutBranches(); + if (callouts == null || callouts.isEmpty()) { + IFigure figure = branch.getTopicPart().getFigure(); + Rectangle bounds = figure.getBounds(); + double height = ((TopicFigure) figure) + .getNormalPreferredBounds(new Point()).height; + double delta = height * cos * cot; + offset = direction.isRightHeaded() ? bounds.right() + delta + : bounds.x - delta; + } else { + double y = boneLine.getOrigin().y; + Rectangle bounds = branch.getFigure().getBounds(); + offset = direction.isRightHeaded() ? bounds.right() : bounds.x; + + for (IBranchPart callout : callouts) { + Rectangle calloutBounds = callout.getFigure().getBounds(); + if (direction.equals(ISubDirection.NE)) { + Point tl = calloutBounds.getTopLeft(); + offset = Math.min(offset, tl.x - (y - tl.y) * cot); + } else if (direction.equals(ISubDirection.SE)) { + Point bl = calloutBounds.getBottomLeft(); + offset = Math.min(offset, bl.x - (bl.y - y) * cot); + } else if (direction.equals(ISubDirection.NW)) { + Point tr = calloutBounds.getTopRight(); + offset = Math.max(offset, tr.x + (y - tr.y) * cot); + } else { + Point br = calloutBounds.getBottomRight(); + offset = Math.max(offset, br.x + (br.y - y) * cot); + } + } + } + + return offset; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.imports/.classpath b/bundles/org.xmind.ui.imports/.classpath index 742923031..3b873edfc 100644 --- a/bundles/org.xmind.ui.imports/.classpath +++ b/bundles/org.xmind.ui.imports/.classpath @@ -3,8 +3,8 @@ - + diff --git a/bundles/org.xmind.ui.imports/.gitignore b/bundles/org.xmind.ui.imports/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.imports/.gitignore +++ b/bundles/org.xmind.ui.imports/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.imports/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF index 1640b6483..ed900a37c 100644 --- a/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF @@ -1,20 +1,20 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.imports;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-Activator: org.xmind.ui.internal.imports.ImportPlugin -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.xmind.core.io;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)" -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ActivationPolicy: lazy -Export-Package: org.xmind.ui.internal.imports;x-internal:=true, - org.xmind.ui.internal.imports.freemind;x-internal:=true, - org.xmind.ui.internal.imports.mm;x-internal:=true -Bundle-Localization: plugin -Import-Package: org.json, - org.xmind.core.usagedata +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.imports;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-Activator: org.xmind.ui.internal.imports.ImportPlugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.xmind.core.io;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.mindmap;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", + org.json;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.xmind.ui.internal.imports;x-internal:=true, + org.xmind.ui.internal.imports.freemind;x-internal:=true, + org.xmind.ui.internal.imports.mm;x-internal:=true +Bundle-Localization: plugin diff --git a/bundles/org.xmind.ui.imports/about.html b/bundles/org.xmind.ui.imports/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.ui.imports/about.html +++ b/bundles/org.xmind.ui.imports/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

    License

    - -

    Nov 6, 2008

    - -

    -XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

    - - - + + + + +License + + +

    License

    + +

    Nov 6, 2008

    + +

    +XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

    + + + diff --git a/bundles/org.xmind.ui.imports/plugin.properties b/bundles/org.xmind.ui.imports/plugin.properties index b4c35afb3..d377539fc 100644 --- a/bundles/org.xmind.ui.imports/plugin.properties +++ b/bundles/org.xmind.ui.imports/plugin.properties @@ -1,9 +1,9 @@ -#Properties file for org.xmind.ui.imports -providerName = XMind Ltd. -pluginName = XMind Import Supports -importWizard.mindmanager.name = Mindjet Mindmanager -importWizard.freemind.name = FreeMind -importWizard.workbook.name = XMind Workbook -importWizard.opml.name = OPML -importWizard.lighten.name = Lighten -importWizard.novamind.name = NovaMind +#Properties file for org.xmind.ui.imports +providerName = XMind Ltd. +pluginName = XMind Import Supports +importWizard.mindmanager.name = Mindjet Mindmanager +importWizard.freemind.name = FreeMind +importWizard.workbook.name = XMind Workbook +importWizard.opml.name = OPML +importWizard.lighten.name = Lighten +importWizard.novamind.name = NovaMind diff --git a/bundles/org.xmind.ui.imports/plugin.xml b/bundles/org.xmind.ui.imports/plugin.xml index d0e30d48e..fd0b43dce 100644 --- a/bundles/org.xmind.ui.imports/plugin.xml +++ b/bundles/org.xmind.ui.imports/plugin.xml @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.imports/pom.xml b/bundles/org.xmind.ui.imports/pom.xml index 00d576758..b3ee4e692 100644 --- a/bundles/org.xmind.ui.imports/pom.xml +++ b/bundles/org.xmind.ui.imports/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.imports - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.imports + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImportWizard.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImportWizard.java index f4509004b..4eeb17dcd 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImportWizard.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImportWizard.java @@ -1,108 +1,108 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.imports.freemind; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.freemind.FreeMindConstants; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.imports.ImportPlugin; -import org.xmind.ui.wizards.AbstractMindMapImportPage; -import org.xmind.ui.wizards.AbstractMindMapImportWizard; -import org.xmind.ui.wizards.MindMapImporter; - -public class FreeMindImportWizard extends AbstractMindMapImportWizard { - - private static final String SETTINGS_ID = "org.xmind.ui.imports.FreeMind"; //$NON-NLS-1$ - - private static final String PAGE_ID = "importFreeMind"; //$NON-NLS-1$ - - private static final String EXT = "*" + FreeMindConstants.FILE_EXTENSION; //$NON-NLS-1$ - - private class FreeMindImportPage extends AbstractMindMapImportPage { - - protected FreeMindImportPage() { - super(PAGE_ID, ImportMessages.FreeMindImportPage_title); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 15; - composite.setLayout(layout); - setControl(composite); - - Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); - - Control destinationControl = createDestinationControl(composite); - destinationControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, - true, true)); - - updateStatus(); - - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - openBrowseDialog(); - } - }); - } - - protected FileDialog createBrowseDialog() { - FileDialog dialog = super.createBrowseDialog(); - dialog.setFilterExtensions(new String[] { EXT }); - dialog.setFilterNames(new String[] { NLS.bind( - ImportMessages.FreeMindImportPage_FilterName, EXT) }); - return dialog; - } - } - - private FreeMindImportPage page; - - public FreeMindImportWizard() { - IDialogSettings settings = ImportPlugin.getDefault() - .getDialogSettings().getSection(SETTINGS_ID); - if (settings == null) { - settings = ImportPlugin.getDefault().getDialogSettings() - .addNewSection(SETTINGS_ID); - } - setDialogSettings(settings); - setWindowTitle(ImportMessages.FreeMindImportWizard_windowTitle); - } - - public void addPages() { - addPage(page = new FreeMindImportPage()); - } - - protected MindMapImporter createImporter(String sourcePath, - IWorkbook targetWorkbook) { - return new FreeMindImporter(sourcePath, targetWorkbook); - } - - protected String getApplicationId() { - return "FreeMind"; //$NON-NLS-1$ - } - - protected void handleExportException(Throwable e) { - super.handleExportException(e); - page.setErrorMessage(e.getLocalizedMessage()); - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.imports.freemind; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.IWorkbook; +import org.xmind.core.io.freemind.FreeMindConstants; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.imports.ImportPlugin; +import org.xmind.ui.wizards.AbstractMindMapImportPage; +import org.xmind.ui.wizards.AbstractMindMapImportWizard; +import org.xmind.ui.wizards.MindMapImporter; + +public class FreeMindImportWizard extends AbstractMindMapImportWizard { + + private static final String SETTINGS_ID = "org.xmind.ui.imports.FreeMind"; //$NON-NLS-1$ + + private static final String PAGE_ID = "importFreeMind"; //$NON-NLS-1$ + + private static final String EXT = "*" + FreeMindConstants.FILE_EXTENSION; //$NON-NLS-1$ + + private class FreeMindImportPage extends AbstractMindMapImportPage { + + protected FreeMindImportPage() { + super(PAGE_ID, ImportMessages.FreeMindImportPage_title); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + composite.setLayout(layout); + setControl(composite); + + Control fileGroup = createFileControls(composite); + fileGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false)); + + Control destinationControl = createDestinationControl(composite); + destinationControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + true, true)); + + updateStatus(); + + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + openBrowseDialog(); + } + }); + } + + protected FileDialog createBrowseDialog() { + FileDialog dialog = super.createBrowseDialog(); + dialog.setFilterExtensions(new String[] { EXT }); + dialog.setFilterNames(new String[] { NLS.bind( + ImportMessages.FreeMindImportPage_FilterName, EXT) }); + return dialog; + } + } + + private FreeMindImportPage page; + + public FreeMindImportWizard() { + IDialogSettings settings = ImportPlugin.getDefault() + .getDialogSettings().getSection(SETTINGS_ID); + if (settings == null) { + settings = ImportPlugin.getDefault().getDialogSettings() + .addNewSection(SETTINGS_ID); + } + setDialogSettings(settings); + setWindowTitle(ImportMessages.FreeMindImportWizard_windowTitle); + } + + public void addPages() { + addPage(page = new FreeMindImportPage()); + } + + protected MindMapImporter createImporter(String sourcePath, + IWorkbook targetWorkbook) { + return new FreeMindImporter(sourcePath, targetWorkbook); + } + + protected String getApplicationId() { + return "FreeMind"; //$NON-NLS-1$ + } + + protected void handleExportException(Throwable e) { + super.handleExportException(e); + page.setErrorMessage(e.getLocalizedMessage()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImporter.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImporter.java index f9fe7e543..c8923c912 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImporter.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/freemind/FreeMindImporter.java @@ -1,743 +1,748 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.imports.freemind; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Stack; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.IFileEntry; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IImage; -import org.xmind.core.INotes; -import org.xmind.core.IParagraph; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISpan; -import org.xmind.core.ITextSpan; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.ResourceMappingManager; -import org.xmind.core.io.freemind.FreeMindConstants; -import org.xmind.core.io.freemind.FreeMindResourceMappingManager; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.imports.ImporterUtils; -import org.xmind.ui.io.MonitoredInputStream; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.wizards.MindMapImporter; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class FreeMindImporter extends MindMapImporter - implements FreeMindConstants, ErrorHandler { - - private class LinkPoint { - ITopic end1; - ITopic end2; - - public LinkPoint(Element ele) { - String id1 = att(ele, "ID"); //$NON-NLS-1$ - end1 = findLinkTopic(id1); - Element linkNode = child(ele, "arrowlink"); //$NON-NLS-1$ - String id2 = att(linkNode, "DESTINATION"); //$NON-NLS-1$ - end2 = findLinkTopic(id2); - } - - private ITopic findLinkTopic(String id) { - if (idMap == null || idMap.isEmpty()) - return null; - String topicId = idMap.get(id); - return getTargetWorkbook().findTopic(topicId); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj != null && !(obj instanceof LinkPoint)) - return false; - LinkPoint that = (LinkPoint) obj; - return this.end1 == that.end1 && this.end2 == that.end2; - } - } - - private class NotesImporter { - IHtmlNotesContent content; - IParagraph currentParagraph = null; - Stack styleStack = new Stack(); - - public NotesImporter(IHtmlNotesContent content) { - this.content = content; - } - - public void importFrom(Element htmlEle) throws InterruptedException { - checkInterrupted(); - String tagName = DOMUtils.getLocalName(htmlEle.getTagName()); - boolean isParagraph = "p".equalsIgnoreCase(tagName) //$NON-NLS-1$ - || "li".equalsIgnoreCase(tagName); //$NON-NLS-1$ - IStyle style = pushStyle(htmlEle, - isParagraph ? IStyle.PARAGRAPH : IStyle.TEXT); - if (isParagraph) - addParagraph(); - - NodeList nl = htmlEle.getChildNodes(); - for (int i = 0; i < nl.getLength(); i++) { - Node node = nl.item(i); - short nodeType = node.getNodeType(); - if (nodeType == Node.TEXT_NODE) { - addText(node.getTextContent()); - } else if (nodeType == Node.ELEMENT_NODE) { - importFrom((Element) node); - } - } - popStyle(style); - } - - private void addText(String text) { - if (text == null) - return; - text = text.trim(); - if ("".equals(text)) //$NON-NLS-1$ - return; - ITextSpan textSpan = content.createTextSpan(text); - addSpan(textSpan); - } - - private void addSpan(ISpan span) { - if (currentParagraph == null) - addParagraph(); - currentParagraph.addSpan(span); - registerStyle(span, Styles.FontFamily, Styles.FontSize, - Styles.TextColor, Styles.FontWeight, Styles.TextDecoration, - Styles.FontStyle); - } - - private void addParagraph() { - currentParagraph = content.createParagraph(); - content.addParagraph(currentParagraph); - registerStyle(currentParagraph, Styles.TextAlign); - } - - private void registerStyle(IStyled host, String... keys) { - for (IStyle style : styleStack) { - registerStyle(host, style, keys); - } - } - - private void registerStyle(IStyled host, IStyle style, String... keys) { - for (String key : keys) { - String value = style.getProperty(key); - if (value != null) - FreeMindImporter.this.registerStyle(host, key, value); - } - } - - private IStyle pushStyle(Element ele, String type) { - IStyle style = getStyleSheet().createStyle(type); - receiveStyle(ele, style); - if (style.isEmpty()) - style = null; - else - styleStack.push(style); - return style; - } - - private void receiveStyle(Element ele, IStyle style) { - String alignStyle = att(ele, "style"); //$NON-NLS-1$ - if (alignStyle != null) { - String align = FreeMindImporter.this.parseAlign(alignStyle); - style.setProperty(Styles.TextAlign, align); - } - String name = ele.getTagName(); - if ("b".equalsIgnoreCase(name)) //$NON-NLS-1$ - style.setProperty(Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); - else if ("i".equalsIgnoreCase(name)) //$NON-NLS-1$ - style.setProperty(Styles.FontStyle, Styles.FONT_STYLE_ITALIC); - else if ("u".equalsIgnoreCase(name)) //$NON-NLS-1$ - style.setProperty(Styles.TextDecoration, - Styles.TEXT_DECORATION_UNDERLINE); - else if ("font".equalsIgnoreCase(name)) { //$NON-NLS-1$ - String fontFamily = att(ele, "face"); //$NON-NLS-1$ - if (fontFamily != null) - style.setProperty(Styles.FontWeight, fontFamily); - String color = att(ele, "color"); //$NON-NLS-1$ - if (color != null) - style.setProperty(Styles.TextColor, color); - String size = att(ele, "size"); //$NON-NLS-1$ - if (size != null) { - String fontSize = FreeMindImporter.this.parseSize(size); - style.setProperty(Styles.FontSize, fontSize + "pt"); //$NON-NLS-1$ - } - } - } - - private void popStyle(IStyle style) { - if (style == null) - return; - if (!styleSheet.isEmpty() && styleStack.peek() == style) - styleStack.pop(); - } - } - - private static ResourceMappingManager mappings = null; - - private List linkEles = null; - - private Map idMap = new HashMap(); - - private Map styleMap = new HashMap(); - - private Map topicHyperMap = null; - - private IStyleSheet styleSheet = null; - - private StringBuilder topicText = null; - - public FreeMindImporter(String sourcePath, IWorkbook targetWorkbook) { - super(sourcePath, targetWorkbook); - } - - public FreeMindImporter(String sourcePath) { - super(sourcePath); - } - - public void build() throws InvocationTargetException, InterruptedException { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ImportFromFreeMindCount"); //$NON-NLS-1$ - try { - DocumentBuilder builder = getDocumentBuilder(); - builder.setErrorHandler(this); - Document doc; - InputStream in = new FileInputStream(getSourcePath()); - try { - in = new MonitoredInputStream(in, getMonitor()); - doc = builder.parse(in); - } finally { - builder.setErrorHandler(null); - try { - in.close(); - } catch (IOException e) { - } - } - checkInterrupted(); - Element rootElement = doc.getDocumentElement(); - loadSheet(rootElement); - - checkInterrupted(); - arrangeStyles(); - - checkInterrupted(); - dealTopicHyperlinks(); - - } catch (Throwable e) { - throw new InvocationTargetException(e); - } finally { - idMap = null; - styleMap = null; - } - postBuilded(); - } - - private void dealTopicHyperlinks() { - if (topicHyperMap == null || topicHyperMap.isEmpty()) - return; - for (Entry entry : topicHyperMap.entrySet()) { - ITopic topic = entry.getKey(); - String nodeId = entry.getValue(); - if (idMap == null || idMap.isEmpty()) - break; - String topicId = idMap.get(nodeId); - if (topicId == null) - continue; - topic.setHyperlink("xmind:#" + topicId); //$NON-NLS-1$ - } - } - - private void arrangeStyles() throws InterruptedException { - IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); - for (Entry entry : styleMap.entrySet()) { - checkInterrupted(); - IStyled styleOwned = entry.getKey(); - IStyle style = entry.getValue(); - IStyle importStyle = targetStyleSheet.importStyle(style); - if (importStyle != null) - styleOwned.setStyleId(importStyle.getId()); - } - } - - private void loadSheet(Element rootEle) throws InterruptedException { - checkInterrupted(); - ISheet sheet = getTargetWorkbook().createSheet(); - sheet.setTitleText("sheet1"); //$NON-NLS-1$ - Element nodeEle = child(rootEle, "node"); //$NON-NLS-1$ - if (nodeEle != null) - loadTopic(sheet.getRootTopic(), nodeEle); - else - sheet.getRootTopic() - .setTitleText(ImportMessages.Importer_CentralTopic); - - if (linkEles != null && !linkEles.isEmpty()) - loadRelationship(); - - addTargetSheet(sheet); - } - - private void loadRelationship() { - for (Element linkEle : linkEles) { - if (linkEle == null) - continue; - LinkPoint link = new LinkPoint(linkEle); - ITopic end1 = link.end1; - ITopic end2 = link.end2; - if (end1 != null && end2 != null) { - IRelationship relationship = getTargetWorkbook() - .createRelationship(end1, end2); - relationship.setEnd1Id(end1.getId()); - relationship.setEnd2Id(end2.getId()); - - Element arrowEle = child(linkEle, "arrowlink"); //$NON-NLS-1$ - loadLinkShape(relationship, arrowEle); - loadLinkColor(relationship, arrowEle); - } - } - } - - private void loadLinkColor(IRelationship relationship, Element arrowEle) { - String color = att(arrowEle, "COLOR"); //$NON-NLS-1$ - if (color == null) - return; - registerStyle(relationship, Styles.LineColor, color); - } - - private void loadLinkShape(IRelationship relationship, Element arrowEle) { - String startArrow = att(arrowEle, "STARTARROW"); //$NON-NLS-1$ - String startShape = parseArrowShape(startArrow); - registerStyle(relationship, Styles.ArrowBeginClass, startShape); - String endArrow = att(arrowEle, "ENDARROW"); //$NON-NLS-1$ - String endShape = parseArrowShape(endArrow); - registerStyle(relationship, Styles.ArrowEndClass, endShape); - } - - private String parseArrowShape(String shape) { - if ("Default".equals(shape)) //$NON-NLS-1$ - return "org.xmind.arrowShape.normal"; //$NON-NLS-1$ - return "org.xmind.arrowShape.none"; //$NON-NLS-1$ - } - - private void loadTopic(ITopic topic, Element nodeEle) - throws InterruptedException { - checkInterrupted(); - String id = att(nodeEle, "ID"); //$NON-NLS-1$ - if (id != null) { - idMap.put(id, topic.getId()); - } - - checkInterrupted(); - String text = att(nodeEle, "TEXT"); //$NON-NLS-1$ - if (text == null) - text = ImporterUtils.getDefaultTopicTitle(topic); - else if (text.contains("../../../../")) { //$NON-NLS-1$ - int index = text.indexOf("../../../../"); //$NON-NLS-1$ - String path = text.substring(index + "../../../../".length(), text //$NON-NLS-1$ - .length() - 2); - loadImage(topic, path); - text = ImporterUtils.getDefaultTopicTitle(topic); - } - topic.setTitleText(text); - - checkInterrupted(); - String folded = att(nodeEle, "FOLDED"); //$NON-NLS-1$ - if (folded != null && "true".equals(folded)) //$NON-NLS-1$ - topic.setFolded(true); - - checkInterrupted(); - if (!topic.isRoot()) { - Element ele = child(nodeEle, "cloud"); //$NON-NLS-1$ - if (ele != null) { - IBoundary boundary = getTargetWorkbook().createBoundary(); - int index = topic.getIndex(); - boundary.setStartIndex(index); - boundary.setEndIndex(index); - topic.getParent().addBoundary(boundary); - } - } - - checkInterrupted(); - String link = att(nodeEle, "LINK"); //$NON-NLS-1$ - if (link != null) { - if (link.startsWith("../../../../")) { //$NON-NLS-1$ - String hyperlink = link.substring("../../../../".length()); //$NON-NLS-1$ - topic.setHyperlink("file:" + hyperlink); //$NON-NLS-1$ - } else if (link.startsWith("#")) { //$NON-NLS-1$ - String nodeId = link.substring(1); - if (topicHyperMap == null) - topicHyperMap = new HashMap(); - topicHyperMap.put(topic, nodeId); - } else { - topic.setHyperlink(link); - } - } - - checkInterrupted(); - String backgroundColor = att(nodeEle, "BACKGROUND_COLOR"); //$NON-NLS-1$ - registerStyle(topic, Styles.FillColor, backgroundColor); - - checkInterrupted(); - String foregroundColor = att(nodeEle, "COLOR"); //$NON-NLS-1$ - registerStyle(topic, Styles.TextColor, foregroundColor); - - checkInterrupted(); - Element fontEle = child(nodeEle, "font"); //$NON-NLS-1$ - loadFont(fontEle, topic); - - checkInterrupted(); - Element linkNode = child(nodeEle, "arrowlink"); //$NON-NLS-1$ - if (linkNode != null) { - if (linkEles == null) - linkEles = new ArrayList(); - linkEles.add(nodeEle); - } - - Iterator iconIter = children(nodeEle, "icon"); //$NON-NLS-1$ - while (iconIter.hasNext()) { - checkInterrupted(); - Element iconEle = iconIter.next(); - String builtIn = att(iconEle, "BUILTIN"); //$NON-NLS-1$ - if (builtIn != null) { - String markerId = getTransferred("marker", builtIn, null); //$NON-NLS-1$ - if (markerId == null) - markerId = "other-question"; //$NON-NLS-1$ - topic.addMarker(markerId); - } - } - - checkInterrupted(); - Element hookEle = child(nodeEle, "hook"); //$NON-NLS-1$ - if (hookEle != null) { - String name = att(hookEle, "NAME"); //$NON-NLS-1$ - if ("accessories/plugins/NodeNote.properties".equals(name)) { //$NON-NLS-1$ - Element notesEle = child(hookEle, "text"); //$NON-NLS-1$ - if (notesEle != null) - loadNotesContent(topic, notesEle); - } - } - - Iterator notesIter = children(nodeEle, "richcontent"); //$NON-NLS-1$ - while (notesIter.hasNext()) { - checkInterrupted(); - Element richEle = notesIter.next(); - String type = att(richEle, "TYPE"); //$NON-NLS-1$ - if (type != null && "NOTE".equals(type)) { //$NON-NLS-1$ - Element htmlEle = child(richEle, "html"); //$NON-NLS-1$ - if (htmlEle != null) { - IHtmlNotesContent notesContent = (IHtmlNotesContent) getTargetWorkbook() - .createNotesContent(INotes.HTML); - NotesImporter notesImport = new NotesImporter(notesContent); - notesImport.importFrom(htmlEle); - topic.getNotes().setContent(INotes.HTML, notesContent); - } - } else if ("NODE".equals(type)) { //$NON-NLS-1$ - topicText = null; - Element htmlEle = child(richEle, "html"); //$NON-NLS-1$ - if (htmlEle != null) { - loadNode(topic, htmlEle); - } - if (topicText != null) { - text = topicText.toString().trim(); - } else { - text = ImporterUtils.getDefaultTopicTitle(topic); - } - topic.setTitleText(text); - } - } - - Iterator nodeIter = children(nodeEle, "node"); //$NON-NLS-1$ - while (nodeIter.hasNext()) { - checkInterrupted(); - Element subNodeEle = nodeIter.next(); - ITopic subTopic = getTargetWorkbook().createTopic(); - topic.add(subTopic); - loadTopic(subTopic, subNodeEle); - } - } - - private void loadNotesContent(ITopic topic, Element ele) { - String text = ele.getTextContent().trim(); - if (text == null) - return; - IHtmlNotesContent notesContent = (IHtmlNotesContent) getTargetWorkbook() - .createNotesContent(INotes.HTML); - ITextSpan span = notesContent.createTextSpan(text); - IParagraph paragraph = notesContent.createParagraph(); - paragraph.addSpan(span); - notesContent.addParagraph(paragraph); - topic.getNotes().setContent(INotes.HTML, notesContent); - } - - private void loadNode(ITopic topic, Element element) - throws InterruptedException { - checkInterrupted(); - String tagName = DOMUtils.getLocalName(element.getTagName()); - if ("img".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ - String src = att(element, "src"); //$NON-NLS-1$ - if (src.startsWith("../../../../")) { //$NON-NLS-1$ - String path = src.substring("../../../../".length()); //$NON-NLS-1$ - loadImage(topic, path); - } else { - String path = getSourcePath().substring(0, - getSourcePath().lastIndexOf("\\") + 1) + src;//$NON-NLS-1$ - loadImage(topic, path); - } - } else if ("p".equalsIgnoreCase(tagName) //$NON-NLS-1$ - || "li".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ - String text = element.getTextContent().trim(); - if (text != null) { - if (topicText == null) - topicText = new StringBuilder(); - topicText.append(text); - topicText.append('\n'); - } - - String align = att(element, "style"); //$NON-NLS-1$ - if (align != null) { - String value = parseAlign(align); - registerStyle(topic, Styles.TextAlign, value); - } - } else if ("b".equalsIgnoreCase(tagName)) //$NON-NLS-1$ - registerStyle(topic, Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); - else if ("i".equalsIgnoreCase(tagName)) //$NON-NLS-1$ - registerStyle(topic, Styles.FontStyle, Styles.FONT_STYLE_ITALIC); - else if ("font".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ - String fontFamily = att(element, "face"); //$NON-NLS-1$ - if (fontFamily != null) - registerStyle(topic, Styles.FontWeight, fontFamily); - String color = att(element, "color"); //$NON-NLS-1$ - if (color != null) - registerStyle(topic, Styles.TextColor, color); - String size = att(element, "size"); //$NON-NLS-1$ - if (size != null) - registerStyle(topic, Styles.FontSize, parseSize(size)); - } - - Element[] children = DOMUtils.getChildElements(element); - for (Element ele : children) { - loadNode(topic, ele); - } - } - - private void loadImage(ITopic topic, String path) - throws InterruptedException { - checkInterrupted(); - IFileEntry imgEntry = loadAttachment(path); - if (imgEntry != null) { - IImage image = topic.getImage(); - image.setSource(HyperlinkUtils.toAttachmentURL(imgEntry.getPath())); - } - } - - private IFileEntry loadAttachment(String path) throws InterruptedException { - checkInterrupted(); - try { - IFileEntry entry = getTargetWorkbook().getManifest() - .createAttachmentFromFilePath(path); - return entry; - } catch (IOException e) { - log(e, "failed to create attachment from: " + path); //$NON-NLS-1$ - } - return null; - } - - private void loadFont(Element fontEle, ITopic topic) { - if (fontEle == null) - return; - String fontName = att(fontEle, "NAME"); //$NON-NLS-1$ - String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName : fontName; - if (fontName != null) { - registerStyle(topic, Styles.FontFamily, fontName); - } - String size = att(fontEle, "SIZE"); //$NON-NLS-1$ - if (size != null) { - registerStyle(topic, Styles.FontSize, size); - } - String italic = att(fontEle, "ITALIC"); //$NON-NLS-1$ - if ("true".equalsIgnoreCase(italic)) { //$NON-NLS-1$ - registerStyle(topic, Styles.FontStyle, Styles.FONT_STYLE_ITALIC); - } - String bold = att(fontEle, "BOLD"); //$NON-NLS-1$ - if ("true".equalsIgnoreCase(bold)) //$NON-NLS-1$ - registerStyle(topic, Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); - } - - private void registerStyle(IStyled styleOwned, String key, String value) { - if (value == null) - return; - IStyle style = styleMap.get(styleOwned); - if (style == null) { - style = getStyleSheet().createStyle(styleOwned.getStyleType()); - getStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); - styleMap.put(styleOwned, style); - } - style.setProperty(key, value); - } - - private String parseSize(String size) { - if ("2".equals(size)) //$NON-NLS-1$ - return "10"; //$NON-NLS-1$ - else if ("3".equals(size)) //$NON-NLS-1$ - return "12"; //$NON-NLS-1$ - else if ("4".equals(size)) //$NON-NLS-1$ - return "14"; //$NON-NLS-1$ - else if ("5".equals(size)) //$NON-NLS-1$ - return "18"; //$NON-NLS-1$ - else if ("6".equals(size)) //$NON-NLS-1$ - return "24"; //$NON-NLS-1$ - return "8"; //$NON-NLS-1$ - } - - private String parseAlign(String align) { - if (align.endsWith(Styles.ALIGN_CENTER)) - return Styles.ALIGN_CENTER; - else if (align.endsWith(Styles.ALIGN_RIGHT)) - return Styles.ALIGN_RIGHT; - return Styles.ALIGN_LEFT; - } - - private IStyleSheet getStyleSheet() { - if (styleSheet == null) - styleSheet = Core.getStyleSheetBuilder().createStyleSheet(); - return styleSheet; - } - - private String getTransferred(String type, String sourceId, - String defaultId) { - if (sourceId != null) { - ResourceMappingManager mappings = getMappings(); - if (mappings != null) { - String destination = mappings.getDestination(type, sourceId); - if (destination != null) - return destination; - } - } - return defaultId; - } - - private ResourceMappingManager getMappings() { - if (mappings == null) - mappings = createMappings(); - return mappings; - } - - private ResourceMappingManager createMappings() { - return FreeMindResourceMappingManager.getInstance(); - } - - private void checkInterrupted() throws InterruptedException { - if (getMonitor().isCanceled()) - throw new InterruptedException(); - } - - private DocumentBuilder getDocumentBuilder() - throws ParserConfigurationException { - return DOMUtils.getDefaultDocumentBuilder(); - } - - private static Element child(Element parentEle, String childTag) { - return children(parentEle, childTag).next(); - } - - private static Iterator children(final Element parentEle, - final String childTag) { - return new Iterator() { - String tag = DOMUtils.getLocalName(childTag); - Iterator it = DOMUtils.childElementIter(parentEle); - Element next = findNext(); - - public void remove() { - } - - private Element findNext() { - while (it.hasNext()) { - Element ele = it.next(); - if (DOMUtils.getLocalName(ele.getTagName()) - .equalsIgnoreCase(tag)) { - return ele; - } - } - return null; - } - - public Element next() { - Element result = next; - next = findNext(); - return result; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - private static String att(Element ele, String attName) { - if (ele.hasAttribute(attName)) - return ele.getAttribute(attName); - - attName = DOMUtils.getLocalName(attName); - NamedNodeMap atts = ele.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) { - Node att = atts.item(i); - if (attName.equalsIgnoreCase( - DOMUtils.getLocalName(att.getNodeName()))) { - return att.getNodeValue(); - } - } - return null; - } - - public void error(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void fatalError(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void warning(SAXParseException exception) throws SAXException { - log(exception, null); - } -} +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.imports.freemind; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Stack; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.IFileEntry; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IImage; +import org.xmind.core.INotes; +import org.xmind.core.IParagraph; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISpan; +import org.xmind.core.ITextSpan; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.StyleSheetImpl; +import org.xmind.core.io.ResourceMappingManager; +import org.xmind.core.io.freemind.FreeMindConstants; +import org.xmind.core.io.freemind.FreeMindResourceMappingManager; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.imports.ImporterUtils; +import org.xmind.ui.io.MonitoredInputStream; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.wizards.MindMapImporter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class FreeMindImporter extends MindMapImporter + implements FreeMindConstants, ErrorHandler { + + private class LinkPoint { + ITopic end1; + ITopic end2; + + public LinkPoint(Element ele) { + String id1 = att(ele, "ID"); //$NON-NLS-1$ + end1 = findLinkTopic(id1); + Element linkNode = child(ele, "arrowlink"); //$NON-NLS-1$ + String id2 = att(linkNode, "DESTINATION"); //$NON-NLS-1$ + end2 = findLinkTopic(id2); + } + + private ITopic findLinkTopic(String id) { + if (idMap == null || idMap.isEmpty()) + return null; + String topicId = idMap.get(id); + return getTargetWorkbook().findTopic(topicId); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj != null && !(obj instanceof LinkPoint)) + return false; + LinkPoint that = (LinkPoint) obj; + return this.end1 == that.end1 && this.end2 == that.end2; + } + } + + private class NotesImporter { + IHtmlNotesContent content; + IParagraph currentParagraph = null; + Stack styleStack = new Stack(); + + public NotesImporter(IHtmlNotesContent content) { + this.content = content; + } + + public void importFrom(Element htmlEle) throws InterruptedException { + checkInterrupted(); + String tagName = DOMUtils.getLocalName(htmlEle.getTagName()); + boolean isParagraph = "p".equalsIgnoreCase(tagName) //$NON-NLS-1$ + || "li".equalsIgnoreCase(tagName); //$NON-NLS-1$ + IStyle style = pushStyle(htmlEle, + isParagraph ? IStyle.PARAGRAPH : IStyle.TEXT); + if (isParagraph) + addParagraph(); + + NodeList nl = htmlEle.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + short nodeType = node.getNodeType(); + if (nodeType == Node.TEXT_NODE) { + addText(node.getTextContent()); + } else if (nodeType == Node.ELEMENT_NODE) { + importFrom((Element) node); + } + } + popStyle(style); + } + + private void addText(String text) { + if (text == null) + return; + text = text.trim(); + if ("".equals(text)) //$NON-NLS-1$ + return; + ITextSpan textSpan = content.createTextSpan(text); + addSpan(textSpan); + } + + private void addSpan(ISpan span) { + if (currentParagraph == null) + addParagraph(); + currentParagraph.addSpan(span); + registerStyle(span, Styles.FontFamily, Styles.FontSize, + Styles.TextColor, Styles.FontWeight, Styles.TextDecoration, + Styles.FontStyle); + } + + private void addParagraph() { + currentParagraph = content.createParagraph(); + content.addParagraph(currentParagraph); + registerStyle(currentParagraph, Styles.TextAlign); + } + + private void registerStyle(IStyled host, String... keys) { + for (IStyle style : styleStack) { + registerStyle(host, style, keys); + } + } + + private void registerStyle(IStyled host, IStyle style, String... keys) { + for (String key : keys) { + String value = style.getProperty(key); + if (value != null) + FreeMindImporter.this.registerStyle(host, key, value); + } + } + + private IStyle pushStyle(Element ele, String type) { + IStyle style = getStyleSheet().createStyle(type); + receiveStyle(ele, style); + if (style.isEmpty()) + style = null; + else + styleStack.push(style); + return style; + } + + private void receiveStyle(Element ele, IStyle style) { + String alignStyle = att(ele, "style"); //$NON-NLS-1$ + if (alignStyle != null) { + String align = FreeMindImporter.this.parseAlign(alignStyle); + style.setProperty(Styles.TextAlign, align); + } + String name = ele.getTagName(); + if ("b".equalsIgnoreCase(name)) //$NON-NLS-1$ + style.setProperty(Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); + else if ("i".equalsIgnoreCase(name)) //$NON-NLS-1$ + style.setProperty(Styles.FontStyle, Styles.FONT_STYLE_ITALIC); + else if ("u".equalsIgnoreCase(name)) //$NON-NLS-1$ + style.setProperty(Styles.TextDecoration, + Styles.TEXT_DECORATION_UNDERLINE); + else if ("font".equalsIgnoreCase(name)) { //$NON-NLS-1$ + String fontFamily = att(ele, "face"); //$NON-NLS-1$ + if (fontFamily != null) + style.setProperty(Styles.FontWeight, fontFamily); + String color = att(ele, "color"); //$NON-NLS-1$ + if (color != null) + style.setProperty(Styles.TextColor, color); + String size = att(ele, "size"); //$NON-NLS-1$ + if (size != null) { + String fontSize = FreeMindImporter.this.parseSize(size); + style.setProperty(Styles.FontSize, fontSize + "pt"); //$NON-NLS-1$ + } + } + } + + private void popStyle(IStyle style) { + if (style == null) + return; + if (!styleSheet.isEmpty() && styleStack.peek() == style) + styleStack.pop(); + } + } + + private static ResourceMappingManager mappings = null; + + private List linkEles = null; + + private Map idMap = new HashMap(); + + private Map styleMap = new HashMap(); + + private Map topicHyperMap = null; + + private IStyleSheet styleSheet = null; + + private StringBuilder topicText = null; + + public FreeMindImporter(String sourcePath, IWorkbook targetWorkbook) { + super(sourcePath, targetWorkbook); + } + + public FreeMindImporter(String sourcePath) { + super(sourcePath); + } + + public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.IMPORT_FROM_FREE_MIND_COUNT); + try { + DocumentBuilder builder = getDocumentBuilder(); + builder.setErrorHandler(this); + Document doc; + InputStream in = new FileInputStream(getSourcePath()); + try { + in = new MonitoredInputStream(in, getMonitor()); + doc = builder.parse(in); + } finally { + builder.setErrorHandler(null); + try { + in.close(); + } catch (IOException e) { + } + } + checkInterrupted(); + Element rootElement = doc.getDocumentElement(); + loadSheet(rootElement); + + checkInterrupted(); + arrangeStyles(); + + checkInterrupted(); + dealTopicHyperlinks(); + + } catch (Throwable e) { + throw new InvocationTargetException(e); + } finally { + idMap = null; + styleMap = null; + } + postBuilded(); + } + + private void dealTopicHyperlinks() { + if (topicHyperMap == null || topicHyperMap.isEmpty()) + return; + for (Entry entry : topicHyperMap.entrySet()) { + ITopic topic = entry.getKey(); + String nodeId = entry.getValue(); + if (idMap == null || idMap.isEmpty()) + break; + String topicId = idMap.get(nodeId); + if (topicId == null) + continue; + topic.setHyperlink("xmind:#" + topicId); //$NON-NLS-1$ + } + } + + private void arrangeStyles() throws InterruptedException { + IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); + for (Entry entry : styleMap.entrySet()) { + checkInterrupted(); + IStyled styleOwned = entry.getKey(); + IStyle style = entry.getValue(); + IStyle importStyle = targetStyleSheet.importStyle(style); + if (importStyle != null) + styleOwned.setStyleId(importStyle.getId()); + } + } + + private void loadSheet(Element rootEle) throws InterruptedException { + checkInterrupted(); + ISheet sheet = getTargetWorkbook().createSheet(); + sheet.setTitleText("sheet1"); //$NON-NLS-1$ + Element nodeEle = child(rootEle, "node"); //$NON-NLS-1$ + if (nodeEle != null) + loadTopic(sheet.getRootTopic(), nodeEle); + else + sheet.getRootTopic() + .setTitleText(ImportMessages.Importer_CentralTopic); + + if (linkEles != null && !linkEles.isEmpty()) + loadRelationship(); + + addTargetSheet(sheet); + } + + private void loadRelationship() { + for (Element linkEle : linkEles) { + if (linkEle == null) + continue; + LinkPoint link = new LinkPoint(linkEle); + ITopic end1 = link.end1; + ITopic end2 = link.end2; + if (end1 != null && end2 != null) { + IRelationship relationship = getTargetWorkbook() + .createRelationship(end1, end2); + relationship.setEnd1Id(end1.getId()); + relationship.setEnd2Id(end2.getId()); + + Element arrowEle = child(linkEle, "arrowlink"); //$NON-NLS-1$ + loadLinkShape(relationship, arrowEle); + loadLinkColor(relationship, arrowEle); + } + } + } + + private void loadLinkColor(IRelationship relationship, Element arrowEle) { + String color = att(arrowEle, "COLOR"); //$NON-NLS-1$ + if (color == null) + return; + registerStyle(relationship, Styles.LineColor, color); + } + + private void loadLinkShape(IRelationship relationship, Element arrowEle) { + String startArrow = att(arrowEle, "STARTARROW"); //$NON-NLS-1$ + String startShape = parseArrowShape(startArrow); + registerStyle(relationship, Styles.ArrowBeginClass, startShape); + String endArrow = att(arrowEle, "ENDARROW"); //$NON-NLS-1$ + String endShape = parseArrowShape(endArrow); + registerStyle(relationship, Styles.ArrowEndClass, endShape); + } + + private String parseArrowShape(String shape) { + if ("Default".equals(shape)) //$NON-NLS-1$ + return "org.xmind.arrowShape.normal"; //$NON-NLS-1$ + return "org.xmind.arrowShape.none"; //$NON-NLS-1$ + } + + private void loadTopic(ITopic topic, Element nodeEle) + throws InterruptedException { + checkInterrupted(); + String id = att(nodeEle, "ID"); //$NON-NLS-1$ + if (id != null) { + idMap.put(id, topic.getId()); + } + + checkInterrupted(); + String text = att(nodeEle, "TEXT"); //$NON-NLS-1$ + if (text == null) + text = ImporterUtils.getDefaultTopicTitle(topic); + else if (text.contains("../../../../")) { //$NON-NLS-1$ + int index = text.indexOf("../../../../"); //$NON-NLS-1$ + String path = text.substring(index + "../../../../".length(), text //$NON-NLS-1$ + .length() - 2); + loadImage(topic, path); + text = ImporterUtils.getDefaultTopicTitle(topic); + } + topic.setTitleText(text); + + checkInterrupted(); + String folded = att(nodeEle, "FOLDED"); //$NON-NLS-1$ + if (folded != null && "true".equals(folded)) //$NON-NLS-1$ + topic.setFolded(true); + + checkInterrupted(); + if (!topic.isRoot()) { + Element ele = child(nodeEle, "cloud"); //$NON-NLS-1$ + if (ele != null) { + IBoundary boundary = getTargetWorkbook().createBoundary(); + int index = topic.getIndex(); + boundary.setStartIndex(index); + boundary.setEndIndex(index); + topic.getParent().addBoundary(boundary); + } + } + + checkInterrupted(); + String link = att(nodeEle, "LINK"); //$NON-NLS-1$ + if (link != null) { + if (link.startsWith("../../../../")) { //$NON-NLS-1$ + String hyperlink = link.substring("../../../../".length()); //$NON-NLS-1$ + topic.setHyperlink("file:" + hyperlink); //$NON-NLS-1$ + } else if (link.startsWith("#")) { //$NON-NLS-1$ + String nodeId = link.substring(1); + if (topicHyperMap == null) + topicHyperMap = new HashMap(); + topicHyperMap.put(topic, nodeId); + } else { + topic.setHyperlink(link); + } + } + + checkInterrupted(); + String backgroundColor = att(nodeEle, "BACKGROUND_COLOR"); //$NON-NLS-1$ + registerStyle(topic, Styles.FillColor, backgroundColor); + + checkInterrupted(); + String foregroundColor = att(nodeEle, "COLOR"); //$NON-NLS-1$ + registerStyle(topic, Styles.TextColor, foregroundColor); + + checkInterrupted(); + Element fontEle = child(nodeEle, "font"); //$NON-NLS-1$ + loadFont(fontEle, topic); + + checkInterrupted(); + Element linkNode = child(nodeEle, "arrowlink"); //$NON-NLS-1$ + if (linkNode != null) { + if (linkEles == null) + linkEles = new ArrayList(); + linkEles.add(nodeEle); + } + + Iterator iconIter = children(nodeEle, "icon"); //$NON-NLS-1$ + while (iconIter.hasNext()) { + checkInterrupted(); + Element iconEle = iconIter.next(); + String builtIn = att(iconEle, "BUILTIN"); //$NON-NLS-1$ + if (builtIn != null) { + String markerId = getTransferred("marker", builtIn, null); //$NON-NLS-1$ + if (markerId == null) + markerId = "other-question"; //$NON-NLS-1$ + topic.addMarker(markerId); + } + } + + checkInterrupted(); + Element hookEle = child(nodeEle, "hook"); //$NON-NLS-1$ + if (hookEle != null) { + String name = att(hookEle, "NAME"); //$NON-NLS-1$ + if ("accessories/plugins/NodeNote.properties".equals(name)) { //$NON-NLS-1$ + Element notesEle = child(hookEle, "text"); //$NON-NLS-1$ + if (notesEle != null) + loadNotesContent(topic, notesEle); + } + } + + Iterator notesIter = children(nodeEle, "richcontent"); //$NON-NLS-1$ + while (notesIter.hasNext()) { + checkInterrupted(); + Element richEle = notesIter.next(); + String type = att(richEle, "TYPE"); //$NON-NLS-1$ + if (type != null && "NOTE".equals(type)) { //$NON-NLS-1$ + Element htmlEle = child(richEle, "html"); //$NON-NLS-1$ + if (htmlEle != null) { + IHtmlNotesContent notesContent = (IHtmlNotesContent) getTargetWorkbook() + .createNotesContent(INotes.HTML); + NotesImporter notesImport = new NotesImporter(notesContent); + notesImport.importFrom(htmlEle); + topic.getNotes().setContent(INotes.HTML, notesContent); + } + } else if ("NODE".equals(type)) { //$NON-NLS-1$ + topicText = null; + Element htmlEle = child(richEle, "html"); //$NON-NLS-1$ + if (htmlEle != null) { + loadNode(topic, htmlEle); + } + if (topicText != null) { + text = topicText.toString().trim(); + } else { + text = ImporterUtils.getDefaultTopicTitle(topic); + } + topic.setTitleText(text); + } + } + + Iterator nodeIter = children(nodeEle, "node"); //$NON-NLS-1$ + while (nodeIter.hasNext()) { + checkInterrupted(); + Element subNodeEle = nodeIter.next(); + ITopic subTopic = getTargetWorkbook().createTopic(); + topic.add(subTopic); + loadTopic(subTopic, subNodeEle); + } + } + + private void loadNotesContent(ITopic topic, Element ele) { + String text = ele.getTextContent().trim(); + if (text == null) + return; + IHtmlNotesContent notesContent = (IHtmlNotesContent) getTargetWorkbook() + .createNotesContent(INotes.HTML); + ITextSpan span = notesContent.createTextSpan(text); + IParagraph paragraph = notesContent.createParagraph(); + paragraph.addSpan(span); + notesContent.addParagraph(paragraph); + topic.getNotes().setContent(INotes.HTML, notesContent); + } + + private void loadNode(ITopic topic, Element element) + throws InterruptedException { + checkInterrupted(); + String tagName = DOMUtils.getLocalName(element.getTagName()); + if ("img".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ + String src = att(element, "src"); //$NON-NLS-1$ + if (src.startsWith("../../../../")) { //$NON-NLS-1$ + String path = src.substring("../../../../".length()); //$NON-NLS-1$ + loadImage(topic, path); + } else { + String path = getSourcePath().substring(0, + getSourcePath().lastIndexOf("\\") + 1) + src;//$NON-NLS-1$ + loadImage(topic, path); + } + } else if ("p".equalsIgnoreCase(tagName) //$NON-NLS-1$ + || "li".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ + String text = element.getTextContent().trim(); + if (text != null) { + if (topicText == null) + topicText = new StringBuilder(); + topicText.append(text); + topicText.append('\n'); + } + + String align = att(element, "style"); //$NON-NLS-1$ + if (align != null) { + String value = parseAlign(align); + registerStyle(topic, Styles.TextAlign, value); + } + } else if ("b".equalsIgnoreCase(tagName)) //$NON-NLS-1$ + registerStyle(topic, Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); + else if ("i".equalsIgnoreCase(tagName)) //$NON-NLS-1$ + registerStyle(topic, Styles.FontStyle, Styles.FONT_STYLE_ITALIC); + else if ("font".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ + String fontFamily = att(element, "face"); //$NON-NLS-1$ + if (fontFamily != null) + registerStyle(topic, Styles.FontWeight, fontFamily); + String color = att(element, "color"); //$NON-NLS-1$ + if (color != null) + registerStyle(topic, Styles.TextColor, color); + String size = att(element, "size"); //$NON-NLS-1$ + if (size != null) + registerStyle(topic, Styles.FontSize, parseSize(size)); + } + + Element[] children = DOMUtils.getChildElements(element); + for (Element ele : children) { + loadNode(topic, ele); + } + } + + private void loadImage(ITopic topic, String path) + throws InterruptedException { + checkInterrupted(); + IFileEntry imgEntry = loadAttachment(path); + if (imgEntry != null) { + IImage image = topic.getImage(); + image.setSource(HyperlinkUtils.toAttachmentURL(imgEntry.getPath())); + } + } + + private IFileEntry loadAttachment(String path) throws InterruptedException { + checkInterrupted(); + try { + IFileEntry entry = getTargetWorkbook().getManifest() + .createAttachmentFromFilePath(path); + return entry; + } catch (IOException e) { + log(e, "failed to create attachment from: " + path); //$NON-NLS-1$ + } + return null; + } + + private void loadFont(Element fontEle, ITopic topic) { + if (fontEle == null) + return; + String fontName = att(fontEle, "NAME"); //$NON-NLS-1$ + String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName : fontName; + if (fontName != null) { + registerStyle(topic, Styles.FontFamily, fontName); + } + String size = att(fontEle, "SIZE"); //$NON-NLS-1$ + if (size != null) { + registerStyle(topic, Styles.FontSize, size); + } + String italic = att(fontEle, "ITALIC"); //$NON-NLS-1$ + if ("true".equalsIgnoreCase(italic)) { //$NON-NLS-1$ + registerStyle(topic, Styles.FontStyle, Styles.FONT_STYLE_ITALIC); + } + String bold = att(fontEle, "BOLD"); //$NON-NLS-1$ + if ("true".equalsIgnoreCase(bold)) //$NON-NLS-1$ + registerStyle(topic, Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); + } + + private void registerStyle(IStyled styleOwned, String key, String value) { + if (value == null) + return; + IStyle style = styleMap.get(styleOwned); + if (style == null) { + style = getStyleSheet().createStyle(styleOwned.getStyleType()); + getStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); + styleMap.put(styleOwned, style); + } + style.setProperty(key, value); + } + + private String parseSize(String size) { + if ("2".equals(size)) //$NON-NLS-1$ + return "10"; //$NON-NLS-1$ + else if ("3".equals(size)) //$NON-NLS-1$ + return "12"; //$NON-NLS-1$ + else if ("4".equals(size)) //$NON-NLS-1$ + return "14"; //$NON-NLS-1$ + else if ("5".equals(size)) //$NON-NLS-1$ + return "18"; //$NON-NLS-1$ + else if ("6".equals(size)) //$NON-NLS-1$ + return "24"; //$NON-NLS-1$ + return "8"; //$NON-NLS-1$ + } + + private String parseAlign(String align) { + if (align.endsWith(Styles.ALIGN_CENTER)) + return Styles.ALIGN_CENTER; + else if (align.endsWith(Styles.ALIGN_RIGHT)) + return Styles.ALIGN_RIGHT; + return Styles.ALIGN_LEFT; + } + + private IStyleSheet getStyleSheet() { + if (styleSheet == null) { + styleSheet = Core.getStyleSheetBuilder().createStyleSheet(); + ((StyleSheetImpl) styleSheet) + .setManifest(getTargetWorkbook().getManifest()); + } + return styleSheet; + } + + private String getTransferred(String type, String sourceId, + String defaultId) { + if (sourceId != null) { + ResourceMappingManager mappings = getMappings(); + if (mappings != null) { + String destination = mappings.getDestination(type, sourceId); + if (destination != null) + return destination; + } + } + return defaultId; + } + + private ResourceMappingManager getMappings() { + if (mappings == null) + mappings = createMappings(); + return mappings; + } + + private ResourceMappingManager createMappings() { + return FreeMindResourceMappingManager.getInstance(); + } + + private void checkInterrupted() throws InterruptedException { + if (getMonitor().isCanceled()) + throw new InterruptedException(); + } + + private DocumentBuilder getDocumentBuilder() + throws ParserConfigurationException { + return DOMUtils.getDefaultDocumentBuilder(); + } + + private static Element child(Element parentEle, String childTag) { + return children(parentEle, childTag).next(); + } + + private static Iterator children(final Element parentEle, + final String childTag) { + return new Iterator() { + String tag = DOMUtils.getLocalName(childTag); + Iterator it = DOMUtils.childElementIter(parentEle); + Element next = findNext(); + + public void remove() { + } + + private Element findNext() { + while (it.hasNext()) { + Element ele = it.next(); + if (DOMUtils.getLocalName(ele.getTagName()) + .equalsIgnoreCase(tag)) { + return ele; + } + } + return null; + } + + public Element next() { + Element result = next; + next = findNext(); + return result; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + private static String att(Element ele, String attName) { + if (ele.hasAttribute(attName)) + return ele.getAttribute(attName); + + attName = DOMUtils.getLocalName(attName); + NamedNodeMap atts = ele.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node att = atts.item(i); + if (attName.equalsIgnoreCase( + DOMUtils.getLocalName(att.getNodeName()))) { + return att.getNodeValue(); + } + } + return null; + } + + public void error(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void fatalError(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void warning(SAXParseException exception) throws SAXException { + log(exception, null); + } +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenConstants.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenConstants.java index b96d6e7e3..90db1b26d 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenConstants.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenConstants.java @@ -1,60 +1,60 @@ -package org.xmind.ui.internal.imports.lighten; - -public interface LightenConstants { - - public static final String CONTENT_FILE_NAME = "content.json"; //$NON-NLS-1$ - - public static final String SHEET_ATTR_CREATE_TIME = "createTime";//$NON-NLS-1$//unmapped - public static final String SHEET_ATTR_STYLE = "style";//$NON-NLS-1$ - public static final String SHEET_ATTR_SKE_THEME = "skeletonTheme";//$NON-NLS-1$ - public static final String SHEET_ATTR_ID = "id";//$NON-NLS-1$ - public static final String SHEET_ATTR_UPDATE_TIME = "updateTime";//$NON-NLS-1$ - public static final String SHEET_ATTR_CLR_THEME = "colorTheme";//$NON-NLS-1$ - public static final String SHEET_ATTR_MAP_NAME = "mapName";//$NON-NLS-1$ //unmapped - public static final String SHEET_ATTR_ROOT = "rootTopic";//$NON-NLS-1$ - public static final String SHEET_ATTR_RELATION = "relationships";//$NON-NLS-1$ - public static final String SHEET_ATTR_RIGHT_NUM = "rightNumber";//$NON-NLS-1$ - - public static final String TOPIC_ATTR_DETACH = "detach";//$NON-NLS-1$ - public static final String TOPIC_ATTR_STYLE = "style";//$NON-NLS-1$ - public static final String TOPIC_ATTR_FOLDED = "folded";//$NON-NLS-1$ - public static final String TOPIC_ATTR_ID = "id";//$NON-NLS-1$ - public static final String TOPIC_ATTR_CHK_LIST = "checkList";//$NON-NLS-1$ - public static final String TOPIC_ATTR_TITLE = "title";//$NON-NLS-1$ - public static final String TOPIC_ATTR_POS = "position";//$NON-NLS-1$ - public static final String TOPIC_ATTR_NOTE = "note";//$NON-NLS-1$ - public static final String TOPIC_ATTR_HIGHLT = "hightlight";//$NON-NLS-1$ //UNMAP? - public static final String TOPIC_ATTR_SUBTOPIC = "subtopics";//$NON-NLS-1$ - public static final String TOPIC_ATTR_CHECKBOX = "checkboxStatus";//$NON-NLS-1$ - - public static final String NOTE_ATTR_TEXT = "text";//$NON-NLS-1$ - - public static final String RELATION_START_ID = "startNodeId";//$NON-NLS-1$ - public static final String RELATION_END_ID = "endNodeId";//$NON-NLS-1$ - public static final String RELATION_CTRL_POINT1 = "controlPoint1";//$NON-NLS-1$ - public static final String RELATION_CTRL_POINT2 = "controlPoint2";//$NON-NLS-1$ - public static final String RELATION_ID = "id";//$NON-NLS-1$ - - public static final String THEME_ATTR_NAME = "name";//$NON-NLS-1$ - public static final String THEME_ATTR_PALETTE = "palette";//$NON-NLS-1$ - public static final String THEME_ATTR_MAIN = "topicStyleForMain";//$NON-NLS-1$ - public static final String THEME_ATTR_SUB = "topicStyleForSubtopic";//$NON-NLS-1$ - public static final String THEME_ATTR_MAP = "mapStyle";//$NON-NLS-1$ - public static final String THEME_ATTR_CENTRAL = "topicStyleForCentral";//$NON-NLS-1$ - public static final String THEME_ATTR_FLOAT = "topicStyleForFloating";//$NON-NLS-1$ - public static final String THEME_ATTR_RELATION = "relationshipStyle";//$NON-NLS-1$ - - public static final String STYLE_ATTR_LINE_CLR = "lineColor";//$NON-NLS-1$ - public static final String STYLE_ATTR_LINE_TYPE = "lineType";//$NON-NLS-1$ - public static final String STYLE_ATTR_FILL_CLR = "fillColor";//$NON-NLS-1$ - public static final String STYLE_ATTR_FONT_NAME = "fontName";//$NON-NLS-1$ - public static final String STYLE_ATTR_FONT_FAMILY = "fontFamily";//$NON-NLS-1$ - public static final String STYLE_ATTR_FONT_CLR = "fontColor";//$NON-NLS-1$ - public static final String STYLE_ATTR_FONT_WEIGHT = "fontWeight"; //$NON-NLS-1$ - public static final String STYLE_ATTR_TOPIC_SHAPE = "topicShape";//$NON-NLS-1$ - public static final String STYLE_ATTR_TOPIC_MARGIN = "topicMargin";//$NON-NLS-1$ - public static final String STYLE_ATTR_CORNER_RADIUS = "cornerRadius";//$NON-NLS-1$ - public static final String STYLE_ATTR_LINE_WIDTH = "lineWidth";//$NON-NLS-1$ - public static final String STYLE_ATTR_TAPERED = "taperedLine"; //$NON-NLS-1$ - -} +package org.xmind.ui.internal.imports.lighten; + +public interface LightenConstants { + + public static final String CONTENT_FILE_NAME = "content.json"; //$NON-NLS-1$ + + public static final String SHEET_ATTR_CREATE_TIME = "createTime";//$NON-NLS-1$//unmapped + public static final String SHEET_ATTR_STYLE = "style";//$NON-NLS-1$ + public static final String SHEET_ATTR_SKE_THEME = "skeletonTheme";//$NON-NLS-1$ + public static final String SHEET_ATTR_ID = "id";//$NON-NLS-1$ + public static final String SHEET_ATTR_UPDATE_TIME = "updateTime";//$NON-NLS-1$ + public static final String SHEET_ATTR_CLR_THEME = "colorTheme";//$NON-NLS-1$ + public static final String SHEET_ATTR_MAP_NAME = "mapName";//$NON-NLS-1$ //unmapped + public static final String SHEET_ATTR_ROOT = "rootTopic";//$NON-NLS-1$ + public static final String SHEET_ATTR_RELATION = "relationships";//$NON-NLS-1$ + public static final String SHEET_ATTR_RIGHT_NUM = "rightNumber";//$NON-NLS-1$ + + public static final String TOPIC_ATTR_DETACH = "detach";//$NON-NLS-1$ + public static final String TOPIC_ATTR_STYLE = "style";//$NON-NLS-1$ + public static final String TOPIC_ATTR_FOLDED = "folded";//$NON-NLS-1$ + public static final String TOPIC_ATTR_ID = "id";//$NON-NLS-1$ + public static final String TOPIC_ATTR_CHK_LIST = "checkList";//$NON-NLS-1$ + public static final String TOPIC_ATTR_TITLE = "title";//$NON-NLS-1$ + public static final String TOPIC_ATTR_POS = "position";//$NON-NLS-1$ + public static final String TOPIC_ATTR_NOTE = "note";//$NON-NLS-1$ + public static final String TOPIC_ATTR_HIGHLT = "hightlight";//$NON-NLS-1$ //UNMAP? + public static final String TOPIC_ATTR_SUBTOPIC = "subtopics";//$NON-NLS-1$ + public static final String TOPIC_ATTR_CHECKBOX = "checkboxStatus";//$NON-NLS-1$ + + public static final String NOTE_ATTR_TEXT = "text";//$NON-NLS-1$ + + public static final String RELATION_START_ID = "startNodeId";//$NON-NLS-1$ + public static final String RELATION_END_ID = "endNodeId";//$NON-NLS-1$ + public static final String RELATION_CTRL_POINT1 = "controlPoint1";//$NON-NLS-1$ + public static final String RELATION_CTRL_POINT2 = "controlPoint2";//$NON-NLS-1$ + public static final String RELATION_ID = "id";//$NON-NLS-1$ + + public static final String THEME_ATTR_NAME = "name";//$NON-NLS-1$ + public static final String THEME_ATTR_PALETTE = "palette";//$NON-NLS-1$ + public static final String THEME_ATTR_MAIN = "topicStyleForMain";//$NON-NLS-1$ + public static final String THEME_ATTR_SUB = "topicStyleForSubtopic";//$NON-NLS-1$ + public static final String THEME_ATTR_MAP = "mapStyle";//$NON-NLS-1$ + public static final String THEME_ATTR_CENTRAL = "topicStyleForCentral";//$NON-NLS-1$ + public static final String THEME_ATTR_FLOAT = "topicStyleForFloating";//$NON-NLS-1$ + public static final String THEME_ATTR_RELATION = "relationshipStyle";//$NON-NLS-1$ + + public static final String STYLE_ATTR_LINE_CLR = "lineColor";//$NON-NLS-1$ + public static final String STYLE_ATTR_LINE_TYPE = "lineType";//$NON-NLS-1$ + public static final String STYLE_ATTR_FILL_CLR = "fillColor";//$NON-NLS-1$ + public static final String STYLE_ATTR_FONT_NAME = "fontName";//$NON-NLS-1$ + public static final String STYLE_ATTR_FONT_FAMILY = "fontFamily";//$NON-NLS-1$ + public static final String STYLE_ATTR_FONT_CLR = "fontColor";//$NON-NLS-1$ + public static final String STYLE_ATTR_FONT_WEIGHT = "fontWeight"; //$NON-NLS-1$ + public static final String STYLE_ATTR_TOPIC_SHAPE = "topicShape";//$NON-NLS-1$ + public static final String STYLE_ATTR_TOPIC_MARGIN = "topicMargin";//$NON-NLS-1$ + public static final String STYLE_ATTR_CORNER_RADIUS = "cornerRadius";//$NON-NLS-1$ + public static final String STYLE_ATTR_LINE_WIDTH = "lineWidth";//$NON-NLS-1$ + public static final String STYLE_ATTR_TAPERED = "taperedLine"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImportWizard.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImportWizard.java index 1b7362ed5..b7bd246ff 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImportWizard.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImportWizard.java @@ -1,79 +1,79 @@ -package org.xmind.ui.internal.imports.lighten; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.wizards.AbstractMindMapImportPage; -import org.xmind.ui.wizards.AbstractMindMapImportWizard; -import org.xmind.ui.wizards.MindMapImporter; - -public class LightenImportWizard extends AbstractMindMapImportWizard { - - private final static String PAGE_ID = "importLighten"; //$NON-NLS-1$ - - private final static String FILE_FORMAT = "*.lighten"; //$NON-NLS-1$ - - @Override - protected MindMapImporter createImporter(String sourcePath, - IWorkbook targetWorkbook) { - return new LightenImporter(sourcePath, targetWorkbook); - } - - @Override - protected String getApplicationId() { - return "Lighten"; //$NON-NLS-1$ - } - - @Override - public void addPages() { - addPage(new LightenImportPage()); - } - - private class LightenImportPage extends AbstractMindMapImportPage { - - protected LightenImportPage() { - super(PAGE_ID, ImportMessages.LightenImportPage_title); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 15; - composite.setLayout(layout); - setControl(composite); - - Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - - Control destinationControl = createDestinationControl(composite); - destinationControl.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - updateStatus(); - - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - openBrowseDialog(); - } - }); - } - - @Override - protected FileDialog createBrowseDialog() { - FileDialog dialog = super.createBrowseDialog(); - dialog.setFilterExtensions(new String[] { FILE_FORMAT }); - dialog.setFilterNames(new String[] { - NLS.bind(ImportMessages.LightenImportPage_FilterName, - FILE_FORMAT) }); - return dialog; - } - } - -} +package org.xmind.ui.internal.imports.lighten; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.IWorkbook; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.wizards.AbstractMindMapImportPage; +import org.xmind.ui.wizards.AbstractMindMapImportWizard; +import org.xmind.ui.wizards.MindMapImporter; + +public class LightenImportWizard extends AbstractMindMapImportWizard { + + private final static String PAGE_ID = "importLighten"; //$NON-NLS-1$ + + private final static String FILE_FORMAT = "*.lighten"; //$NON-NLS-1$ + + @Override + protected MindMapImporter createImporter(String sourcePath, + IWorkbook targetWorkbook) { + return new LightenImporter(sourcePath, targetWorkbook); + } + + @Override + protected String getApplicationId() { + return "Lighten"; //$NON-NLS-1$ + } + + @Override + public void addPages() { + addPage(new LightenImportPage()); + } + + private class LightenImportPage extends AbstractMindMapImportPage { + + protected LightenImportPage() { + super(PAGE_ID, ImportMessages.LightenImportPage_title); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + composite.setLayout(layout); + setControl(composite); + + Control fileGroup = createFileControls(composite); + fileGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + + Control destinationControl = createDestinationControl(composite); + destinationControl.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + updateStatus(); + + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + openBrowseDialog(); + } + }); + } + + @Override + protected FileDialog createBrowseDialog() { + FileDialog dialog = super.createBrowseDialog(); + dialog.setFilterExtensions(new String[] { FILE_FORMAT }); + dialog.setFilterNames(new String[] { + NLS.bind(ImportMessages.LightenImportPage_FilterName, + FILE_FORMAT) }); + return dialog; + } + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImporter.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImporter.java index 96194e1c3..9559f3cad 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImporter.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/lighten/LightenImporter.java @@ -1,406 +1,407 @@ -package org.xmind.ui.internal.imports.lighten; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.xmind.core.IControlPoint; -import org.xmind.core.INotes; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.dom.DOMConstants; -import org.xmind.core.internal.dom.PlainNotesContentImpl; -import org.xmind.core.internal.dom.SheetImpl; -import org.xmind.core.internal.dom.TopicExtensionElementImpl; -import org.xmind.core.internal.dom.TopicExtensionImpl; -import org.xmind.core.internal.dom.TopicImpl; -import org.xmind.core.internal.dom.WorkbookImpl; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.Point; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.style.Styles; -import org.xmind.ui.wizards.MindMapImporter; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class LightenImporter extends MindMapImporter implements ErrorHandler { - - private ISheet targetSheet; - private IStyleSheet targetStyleSheet; - private IStyle theme; - private Map styleMap; - - private static final String PIXEL_POINT = "pt"; //$NON-NLS-1$ - - public LightenImporter(String sourcePath, IWorkbook targetWorkbook) { - super(sourcePath, targetWorkbook); - } - - @Override - public void build() throws InvocationTargetException, InterruptedException { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ImportFromLightenCount"); //$NON-NLS-1$ - ZipInputStream zis = null; - try { - getMonitor().beginTask(null, 100); - zis = new ZipInputStream(new FileInputStream(getSourcePath())); - ZipEntry entry; - JSONObject json = null; - while ((entry = zis.getNextEntry()) != null) - if (LightenConstants.CONTENT_FILE_NAME - .equals(entry.getName())) { - getMonitor().worked(40); - BufferedInputStream bis = new BufferedInputStream(zis); - BufferedReader reader = new BufferedReader( - new InputStreamReader(bis, "utf-8")); //$NON-NLS-1$ - StringBuilder sb = new StringBuilder(); - String read; - while ((read = reader.readLine()) != null) { - sb.append(read).append('\n'); - } - json = new JSONObject(sb.toString()); - getMonitor().worked(10); - } - zis.close(); - zis = null; - - if (json != null) { - addTargetSheet(parseJsonIntoWorkbook(json)); - } - getMonitor().worked(50); - getMonitor().done(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (zis != null) { - try { - zis.closeEntry(); - zis.close(); - } catch (Exception e) { - zis = null; - } - } - } - postBuilded(); - } - - private ISheet parseJsonIntoWorkbook(JSONObject json) { - WorkbookImpl workbook = (WorkbookImpl) getTargetWorkbook(); - targetSheet = workbook.createSheet(); - SheetImpl sheet = (SheetImpl) targetSheet; - - if (targetStyleSheet == null) { - targetStyleSheet = workbook.getStyleSheet(); - } - if (styleMap == null) { - styleMap = new HashMap(); - } - - if (json.has(LightenConstants.SHEET_ATTR_SKE_THEME)) - parseTheme( - json.getJSONObject(LightenConstants.SHEET_ATTR_SKE_THEME)); - if (json.has(LightenConstants.SHEET_ATTR_UPDATE_TIME)) - sheet.getImplementation().setAttribute(DOMConstants.ATTR_TIMESTAMP, - ((Long) ((Double) (json.getDouble( - LightenConstants.SHEET_ATTR_UPDATE_TIME) * 1000)) - .longValue()).toString()); - - if (json.has(LightenConstants.SHEET_ATTR_ROOT)) { - JSONObject rootTopicJson = (JSONObject) json - .get(LightenConstants.SHEET_ATTR_ROOT); - ITopic rootTopic = parseTopic(rootTopicJson, sheet); - sheet.replaceRootTopic(rootTopic); - if (json.has(LightenConstants.SHEET_ATTR_RIGHT_NUM)) { - TopicExtensionImpl topicExtension = (TopicExtensionImpl) rootTopic - .createExtension("org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ - TopicExtensionElementImpl element = (TopicExtensionElementImpl) topicExtension - .getContent().getCreatedChild("right-number"); //$NON-NLS-1$ - element.setTextContent(((Integer) json - .getInt(LightenConstants.SHEET_ATTR_RIGHT_NUM)) - .toString()); - } - } - - if (json.has(LightenConstants.SHEET_ATTR_RELATION)) { - JSONArray relationshipsJson = json - .getJSONArray(LightenConstants.SHEET_ATTR_RELATION); - for (int i = 0; i < relationshipsJson.length(); i++) { - JSONObject relationshipJson = relationshipsJson - .getJSONObject(i); - IRelationship relationship = workbook.createRelationship(); - relationship.setEnd1Id(relationshipJson - .getString(LightenConstants.RELATION_START_ID)); - relationship.setEnd2Id(relationshipJson - .getString(LightenConstants.RELATION_END_ID)); - if (relationshipJson - .has(LightenConstants.RELATION_CTRL_POINT1)) { - IControlPoint controlPoint1 = relationship - .getControlPoint(0); - controlPoint1.setPosition(deserializePoint(relationshipJson - .getString(LightenConstants.RELATION_CTRL_POINT1))); - } - if (relationshipJson - .has(LightenConstants.RELATION_CTRL_POINT2)) { - IControlPoint controlPoint2 = relationship - .getControlPoint(1); - controlPoint2.setPosition(deserializePoint(relationshipJson - .getString(LightenConstants.RELATION_CTRL_POINT2))); - } - - sheet.addRelationship(relationship); - } - } - - if (json.has(LightenConstants.SHEET_ATTR_CLR_THEME)) { - String themeName = parseTheme( - json.getJSONObject(LightenConstants.SHEET_ATTR_CLR_THEME)); - importStyleAndTheme(themeName); - } - - return targetSheet; - } - - private ITopic parseTopic(JSONObject json, ISheet sheet) { - IWorkbook workbook = sheet.getOwnedWorkbook(); - TopicImpl topic = (TopicImpl) workbook.createTopic(); - - if (json.has(LightenConstants.TOPIC_ATTR_TITLE)) - topic.setTitleText( - json.getString(LightenConstants.TOPIC_ATTR_TITLE)); - if (json.has(LightenConstants.TOPIC_ATTR_ID)) - topic.getImplementation().setAttribute(DOMConstants.ATTR_ID, - json.getString(LightenConstants.TOPIC_ATTR_ID)); - - if (json.has(LightenConstants.TOPIC_ATTR_SUBTOPIC)) { - JSONArray subtopicJson = json - .getJSONArray(LightenConstants.TOPIC_ATTR_SUBTOPIC); - for (int i = 0; i < subtopicJson.length(); i++) { - ITopic subtopic = parseTopic(subtopicJson.getJSONObject(i), - sheet); - topic.add(subtopic); - } - } - - if (json.has(LightenConstants.TOPIC_ATTR_NOTE)) { - JSONObject notesJson = json - .getJSONObject(LightenConstants.TOPIC_ATTR_NOTE); - if (notesJson.has(LightenConstants.NOTE_ATTR_TEXT)) { - INotes notes = topic.getNotes(); - PlainNotesContentImpl plainNotes = (PlainNotesContentImpl) workbook - .createNotesContent(INotes.PLAIN); - try { - plainNotes.setTextContent(notesJson - .getString(LightenConstants.NOTE_ATTR_TEXT)); - } catch (Exception e) { - } - notes.setContent(INotes.PLAIN, plainNotes); - } - } - - if (json.has(LightenConstants.TOPIC_ATTR_DETACH) - && json.getBoolean(LightenConstants.TOPIC_ATTR_DETACH) - && json.has(LightenConstants.TOPIC_ATTR_POS)) { - topic.setPosition(deserializePoint( - json.getString(LightenConstants.TOPIC_ATTR_POS))); - } - - if (json.has(LightenConstants.TOPIC_ATTR_FOLDED)) - topic.setFolded( - json.getBoolean(LightenConstants.TOPIC_ATTR_FOLDED)); - - if (json.has(LightenConstants.TOPIC_ATTR_STYLE)) - setTopicStyle(topic, - json.getJSONObject(LightenConstants.TOPIC_ATTR_STYLE)); - - return topic; - } - - private Point deserializePoint(String point) { - int commaPos = point.indexOf(','); - int x = Double.valueOf(point.substring(1, commaPos)).intValue(); - int y = Double - .valueOf(point.substring(commaPos + 1, point.length() - 1)) - .intValue(); - return new Point(x, y); - } - - private String parseTheme(JSONObject json) { - String name = json.getString(LightenConstants.THEME_ATTR_NAME); - - if (json.has(LightenConstants.THEME_ATTR_MAIN)) - parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_MAIN_TOPIC, - json.getJSONObject(LightenConstants.THEME_ATTR_MAIN)); - - if (json.has(LightenConstants.THEME_ATTR_SUB)) - parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_SUB_TOPIC, - json.getJSONObject(LightenConstants.THEME_ATTR_SUB)); - - if (json.has(LightenConstants.THEME_ATTR_MAP)) - parseThemeStyle(IStyle.MAP, Styles.FAMILY_MAP, - json.getJSONObject(LightenConstants.THEME_ATTR_MAP)); - - if (json.has(LightenConstants.THEME_ATTR_CENTRAL)) - parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_CENTRAL_TOPIC, - json.getJSONObject(LightenConstants.THEME_ATTR_CENTRAL)); - - if (json.has(LightenConstants.THEME_ATTR_FLOAT)) - parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_FLOATING_TOPIC, - json.getJSONObject(LightenConstants.THEME_ATTR_FLOAT)); - - if (json.has(LightenConstants.THEME_ATTR_RELATION)) - parseThemeStyle(IStyle.RELATIONSHIP, Styles.FAMILY_RELATIONSHIP, - json.getJSONObject(LightenConstants.THEME_ATTR_RELATION)); - - return name; - } - - private void parseThemeStyle(String type, String styleFamily, - JSONObject json) { - if (json.has(LightenConstants.STYLE_ATTR_LINE_CLR)) - registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_COLOR, - colorToRgb(json - .getString(LightenConstants.STYLE_ATTR_LINE_CLR))); - if (json.has(LightenConstants.STYLE_ATTR_FILL_CLR)) - registerTheme(type, styleFamily, DOMConstants.ATTR_FILL, colorToRgb( - json.getString(LightenConstants.STYLE_ATTR_FILL_CLR))); - if (json.has(LightenConstants.STYLE_ATTR_FONT_FAMILY)) - registerTheme(type, styleFamily, DOMConstants.ATTR_FONT_FAMILY, - json.getString(LightenConstants.STYLE_ATTR_FONT_FAMILY)); - if (json.has(LightenConstants.STYLE_ATTR_FONT_CLR)) - registerTheme(type, styleFamily, DOMConstants.ATTR_COLOR, - colorToRgb(json - .getString(LightenConstants.STYLE_ATTR_FONT_CLR))); - if (json.has(LightenConstants.STYLE_ATTR_CORNER_RADIUS)) - registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_CORNER, - json.getInt(LightenConstants.STYLE_ATTR_CORNER_RADIUS) - + PIXEL_POINT); - if (json.has(LightenConstants.STYLE_ATTR_LINE_WIDTH)) - registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_WIDTH, - json.getInt(LightenConstants.STYLE_ATTR_LINE_WIDTH) - + PIXEL_POINT); - - } - - private void registerStyle(IStyled styleOwner, String key, String value) { - if (value == null) - return; - - IStyle style = styleMap.get(styleOwner); - if (style == null) { - style = targetStyleSheet.createStyle(styleOwner.getStyleType()); - targetStyleSheet.addStyle(style, IStyleSheet.NORMAL_STYLES); - styleMap.put(styleOwner, style); - } - style.setProperty(key, value); - } - - private void registerTheme(String type, String styleFamily, String styleKey, - String styleValue) { - if (styleFamily == null || styleKey == null || styleValue == null) - return; - - if (theme == null) { - theme = targetStyleSheet.createStyle(IStyle.THEME); - targetStyleSheet.addStyle(theme, IStyleSheet.MASTER_STYLES); - } - - IStyle defaultStyle = theme.getDefaultStyle(styleFamily); - if (defaultStyle == null) { - defaultStyle = targetStyleSheet.createStyle(type); - targetStyleSheet.addStyle(defaultStyle, - IStyleSheet.AUTOMATIC_STYLES); - theme.setDefaultStyleId(styleFamily, defaultStyle.getId()); - } - defaultStyle.setProperty(styleKey, styleValue); - } - - private void importStyleAndTheme(String themeName) { - IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); - for (Entry entry : styleMap.entrySet()) { - IStyled styled = entry.getKey(); - IStyle style = entry.getValue(); - IStyle imported = targetStyleSheet.importStyle(style); - if (imported != null) { - styled.setStyleId(imported.getId()); - } - } - - if (theme != null) { - theme.setName(themeName); - IStyle imported = targetStyleSheet.importStyle(theme); - if (imported != null) { - targetSheet.setThemeId(imported.getId()); - } - } - - } - - private String colorToRgb(String colorPoint) { - if ("0.00".equals(colorPoint.substring(colorPoint.lastIndexOf(',') + 1, //$NON-NLS-1$ - colorPoint.length() - 1).trim())) {//ignore when opacity is 0.00 - return null; - } - - StringBuilder sb = new StringBuilder().append('#'); - char[] chars = colorPoint.toCharArray(); - StringBuilder splitBuilder = new StringBuilder(); - for (char c : chars) { - if (c != '{' && c != ' ') { - if (c == ',') { - String value = Integer.toHexString( - Integer.valueOf(splitBuilder.toString())); - if (value.length() == 1) { - sb.append('0'); - } - sb.append(value); - splitBuilder = new StringBuilder(); - } else { - splitBuilder.append(c); - } - } - } - return sb.toString(); - } - - private void setTopicStyle(ITopic topic, JSONObject json) { - if (json.has(LightenConstants.STYLE_ATTR_LINE_CLR)) { - registerStyle(topic, DOMConstants.ATTR_LINE_COLOR, colorToRgb( - json.getString(LightenConstants.STYLE_ATTR_LINE_CLR))); - } - if (json.has(LightenConstants.STYLE_ATTR_FONT_CLR)) { - registerStyle(topic, DOMConstants.ATTR_COLOR, colorToRgb( - json.getString(LightenConstants.STYLE_ATTR_FONT_CLR))); - } - if (json.has(LightenConstants.STYLE_ATTR_FONT_WEIGHT)) { - registerStyle(topic, DOMConstants.ATTR_FONT_WEIGHT, - json.getString(LightenConstants.STYLE_ATTR_FONT_WEIGHT)); - } - } - - public void error(SAXParseException arg0) throws SAXException { - log(arg0, null); - } - - public void fatalError(SAXParseException arg0) throws SAXException { - log(arg0, null); - } - - public void warning(SAXParseException arg0) throws SAXException { - log(arg0, null); - } - -} +package org.xmind.ui.internal.imports.lighten; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.xmind.core.IControlPoint; +import org.xmind.core.INotes; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.DOMConstants; +import org.xmind.core.internal.dom.PlainNotesContentImpl; +import org.xmind.core.internal.dom.SheetImpl; +import org.xmind.core.internal.dom.TopicExtensionElementImpl; +import org.xmind.core.internal.dom.TopicExtensionImpl; +import org.xmind.core.internal.dom.TopicImpl; +import org.xmind.core.internal.dom.WorkbookImpl; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.Point; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.style.Styles; +import org.xmind.ui.wizards.MindMapImporter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class LightenImporter extends MindMapImporter implements ErrorHandler { + + private ISheet targetSheet; + private IStyleSheet targetStyleSheet; + private IStyle theme; + private Map styleMap; + + private static final String PIXEL_POINT = "pt"; //$NON-NLS-1$ + + public LightenImporter(String sourcePath, IWorkbook targetWorkbook) { + super(sourcePath, targetWorkbook); + } + + @Override + public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.IMPORT_FROM_LIGHTEN_COUNT); + ZipInputStream zis = null; + try { + getMonitor().beginTask(null, 100); + zis = new ZipInputStream(new FileInputStream(getSourcePath())); + ZipEntry entry; + JSONObject json = null; + while ((entry = zis.getNextEntry()) != null) + if (LightenConstants.CONTENT_FILE_NAME + .equals(entry.getName())) { + getMonitor().worked(40); + BufferedInputStream bis = new BufferedInputStream(zis); + BufferedReader reader = new BufferedReader( + new InputStreamReader(bis, "utf-8")); //$NON-NLS-1$ + StringBuilder sb = new StringBuilder(); + String read; + while ((read = reader.readLine()) != null) { + sb.append(read).append('\n'); + } + json = new JSONObject(sb.toString()); + getMonitor().worked(10); + } + zis.close(); + zis = null; + + if (json != null) { + addTargetSheet(parseJsonIntoWorkbook(json)); + } + getMonitor().worked(50); + getMonitor().done(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (zis != null) { + try { + zis.closeEntry(); + zis.close(); + } catch (Exception e) { + zis = null; + } + } + } + postBuilded(); + } + + private ISheet parseJsonIntoWorkbook(JSONObject json) { + WorkbookImpl workbook = (WorkbookImpl) getTargetWorkbook(); + targetSheet = workbook.createSheet(); + SheetImpl sheet = (SheetImpl) targetSheet; + + if (targetStyleSheet == null) { + targetStyleSheet = workbook.getStyleSheet(); + } + if (styleMap == null) { + styleMap = new HashMap(); + } + + if (json.has(LightenConstants.SHEET_ATTR_SKE_THEME)) + parseTheme( + json.getJSONObject(LightenConstants.SHEET_ATTR_SKE_THEME)); + if (json.has(LightenConstants.SHEET_ATTR_UPDATE_TIME)) + sheet.getImplementation().setAttribute(DOMConstants.ATTR_TIMESTAMP, + ((Long) ((Double) (json.getDouble( + LightenConstants.SHEET_ATTR_UPDATE_TIME) * 1000)) + .longValue()).toString()); + + if (json.has(LightenConstants.SHEET_ATTR_ROOT)) { + JSONObject rootTopicJson = (JSONObject) json + .get(LightenConstants.SHEET_ATTR_ROOT); + ITopic rootTopic = parseTopic(rootTopicJson, sheet); + sheet.replaceRootTopic(rootTopic); + if (json.has(LightenConstants.SHEET_ATTR_RIGHT_NUM)) { + TopicExtensionImpl topicExtension = (TopicExtensionImpl) rootTopic + .createExtension("org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ + TopicExtensionElementImpl element = (TopicExtensionElementImpl) topicExtension + .getContent().getCreatedChild("right-number"); //$NON-NLS-1$ + element.setTextContent(((Integer) json + .getInt(LightenConstants.SHEET_ATTR_RIGHT_NUM)) + .toString()); + } + } + + if (json.has(LightenConstants.SHEET_ATTR_RELATION)) { + JSONArray relationshipsJson = json + .getJSONArray(LightenConstants.SHEET_ATTR_RELATION); + for (int i = 0; i < relationshipsJson.length(); i++) { + JSONObject relationshipJson = relationshipsJson + .getJSONObject(i); + IRelationship relationship = workbook.createRelationship(); + relationship.setEnd1Id(relationshipJson + .getString(LightenConstants.RELATION_START_ID)); + relationship.setEnd2Id(relationshipJson + .getString(LightenConstants.RELATION_END_ID)); + if (relationshipJson + .has(LightenConstants.RELATION_CTRL_POINT1)) { + IControlPoint controlPoint1 = relationship + .getControlPoint(0); + controlPoint1.setPosition(deserializePoint(relationshipJson + .getString(LightenConstants.RELATION_CTRL_POINT1))); + } + if (relationshipJson + .has(LightenConstants.RELATION_CTRL_POINT2)) { + IControlPoint controlPoint2 = relationship + .getControlPoint(1); + controlPoint2.setPosition(deserializePoint(relationshipJson + .getString(LightenConstants.RELATION_CTRL_POINT2))); + } + + sheet.addRelationship(relationship); + } + } + + if (json.has(LightenConstants.SHEET_ATTR_CLR_THEME)) { + String themeName = parseTheme( + json.getJSONObject(LightenConstants.SHEET_ATTR_CLR_THEME)); + importStyleAndTheme(themeName); + } + + return targetSheet; + } + + private ITopic parseTopic(JSONObject json, ISheet sheet) { + IWorkbook workbook = sheet.getOwnedWorkbook(); + TopicImpl topic = (TopicImpl) workbook.createTopic(); + + if (json.has(LightenConstants.TOPIC_ATTR_TITLE)) + topic.setTitleText( + json.getString(LightenConstants.TOPIC_ATTR_TITLE)); + if (json.has(LightenConstants.TOPIC_ATTR_ID)) + topic.getImplementation().setAttribute(DOMConstants.ATTR_ID, + json.getString(LightenConstants.TOPIC_ATTR_ID)); + + if (json.has(LightenConstants.TOPIC_ATTR_SUBTOPIC)) { + JSONArray subtopicJson = json + .getJSONArray(LightenConstants.TOPIC_ATTR_SUBTOPIC); + for (int i = 0; i < subtopicJson.length(); i++) { + ITopic subtopic = parseTopic(subtopicJson.getJSONObject(i), + sheet); + topic.add(subtopic); + } + } + + if (json.has(LightenConstants.TOPIC_ATTR_NOTE)) { + JSONObject notesJson = json + .getJSONObject(LightenConstants.TOPIC_ATTR_NOTE); + if (notesJson.has(LightenConstants.NOTE_ATTR_TEXT)) { + INotes notes = topic.getNotes(); + PlainNotesContentImpl plainNotes = (PlainNotesContentImpl) workbook + .createNotesContent(INotes.PLAIN); + try { + plainNotes.setTextContent(notesJson + .getString(LightenConstants.NOTE_ATTR_TEXT)); + } catch (Exception e) { + } + notes.setContent(INotes.PLAIN, plainNotes); + } + } + + if (json.has(LightenConstants.TOPIC_ATTR_DETACH) + && json.getBoolean(LightenConstants.TOPIC_ATTR_DETACH) + && json.has(LightenConstants.TOPIC_ATTR_POS)) { + topic.setPosition(deserializePoint( + json.getString(LightenConstants.TOPIC_ATTR_POS))); + } + + if (json.has(LightenConstants.TOPIC_ATTR_FOLDED)) + topic.setFolded( + json.getBoolean(LightenConstants.TOPIC_ATTR_FOLDED)); + + if (json.has(LightenConstants.TOPIC_ATTR_STYLE)) + setTopicStyle(topic, + json.getJSONObject(LightenConstants.TOPIC_ATTR_STYLE)); + + return topic; + } + + private Point deserializePoint(String point) { + int commaPos = point.indexOf(','); + int x = Double.valueOf(point.substring(1, commaPos)).intValue(); + int y = Double + .valueOf(point.substring(commaPos + 1, point.length() - 1)) + .intValue(); + return new Point(x, y); + } + + private String parseTheme(JSONObject json) { + String name = json.getString(LightenConstants.THEME_ATTR_NAME); + + if (json.has(LightenConstants.THEME_ATTR_MAIN)) + parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_MAIN_TOPIC, + json.getJSONObject(LightenConstants.THEME_ATTR_MAIN)); + + if (json.has(LightenConstants.THEME_ATTR_SUB)) + parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_SUB_TOPIC, + json.getJSONObject(LightenConstants.THEME_ATTR_SUB)); + + if (json.has(LightenConstants.THEME_ATTR_MAP)) + parseThemeStyle(IStyle.MAP, Styles.FAMILY_MAP, + json.getJSONObject(LightenConstants.THEME_ATTR_MAP)); + + if (json.has(LightenConstants.THEME_ATTR_CENTRAL)) + parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_CENTRAL_TOPIC, + json.getJSONObject(LightenConstants.THEME_ATTR_CENTRAL)); + + if (json.has(LightenConstants.THEME_ATTR_FLOAT)) + parseThemeStyle(IStyle.TOPIC, Styles.FAMILY_FLOATING_TOPIC, + json.getJSONObject(LightenConstants.THEME_ATTR_FLOAT)); + + if (json.has(LightenConstants.THEME_ATTR_RELATION)) + parseThemeStyle(IStyle.RELATIONSHIP, Styles.FAMILY_RELATIONSHIP, + json.getJSONObject(LightenConstants.THEME_ATTR_RELATION)); + + return name; + } + + private void parseThemeStyle(String type, String styleFamily, + JSONObject json) { + if (json.has(LightenConstants.STYLE_ATTR_LINE_CLR)) + registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_COLOR, + colorToRgb(json + .getString(LightenConstants.STYLE_ATTR_LINE_CLR))); + if (json.has(LightenConstants.STYLE_ATTR_FILL_CLR)) + registerTheme(type, styleFamily, DOMConstants.ATTR_FILL, colorToRgb( + json.getString(LightenConstants.STYLE_ATTR_FILL_CLR))); + if (json.has(LightenConstants.STYLE_ATTR_FONT_FAMILY)) + registerTheme(type, styleFamily, DOMConstants.ATTR_FONT_FAMILY, + json.getString(LightenConstants.STYLE_ATTR_FONT_FAMILY)); + if (json.has(LightenConstants.STYLE_ATTR_FONT_CLR)) + registerTheme(type, styleFamily, DOMConstants.ATTR_COLOR, + colorToRgb(json + .getString(LightenConstants.STYLE_ATTR_FONT_CLR))); + if (json.has(LightenConstants.STYLE_ATTR_CORNER_RADIUS)) + registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_CORNER, + json.getInt(LightenConstants.STYLE_ATTR_CORNER_RADIUS) + + PIXEL_POINT); + if (json.has(LightenConstants.STYLE_ATTR_LINE_WIDTH)) + registerTheme(type, styleFamily, DOMConstants.ATTR_LINE_WIDTH, + json.getInt(LightenConstants.STYLE_ATTR_LINE_WIDTH) + + PIXEL_POINT); + + } + + private void registerStyle(IStyled styleOwner, String key, String value) { + if (value == null) + return; + + IStyle style = styleMap.get(styleOwner); + if (style == null) { + style = targetStyleSheet.createStyle(styleOwner.getStyleType()); + targetStyleSheet.addStyle(style, IStyleSheet.NORMAL_STYLES); + styleMap.put(styleOwner, style); + } + style.setProperty(key, value); + } + + private void registerTheme(String type, String styleFamily, String styleKey, + String styleValue) { + if (styleFamily == null || styleKey == null || styleValue == null) + return; + + if (theme == null) { + theme = targetStyleSheet.createStyle(IStyle.THEME); + targetStyleSheet.addStyle(theme, IStyleSheet.MASTER_STYLES); + } + + IStyle defaultStyle = theme.getDefaultStyle(styleFamily); + if (defaultStyle == null) { + defaultStyle = targetStyleSheet.createStyle(type); + targetStyleSheet.addStyle(defaultStyle, + IStyleSheet.AUTOMATIC_STYLES); + theme.setDefaultStyleId(styleFamily, defaultStyle.getId()); + } + defaultStyle.setProperty(styleKey, styleValue); + } + + private void importStyleAndTheme(String themeName) { + IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); + for (Entry entry : styleMap.entrySet()) { + IStyled styled = entry.getKey(); + IStyle style = entry.getValue(); + IStyle imported = targetStyleSheet.importStyle(style); + if (imported != null) { + styled.setStyleId(imported.getId()); + } + } + + if (theme != null) { + theme.setName(themeName); + IStyle imported = targetStyleSheet.importStyle(theme); + if (imported != null) { + targetSheet.setThemeId(imported.getId()); + } + } + + } + + private String colorToRgb(String colorPoint) { + if ("0.00".equals(colorPoint.substring(colorPoint.lastIndexOf(',') + 1, //$NON-NLS-1$ + colorPoint.length() - 1).trim())) {//ignore when opacity is 0.00 + return null; + } + + StringBuilder sb = new StringBuilder().append('#'); + char[] chars = colorPoint.toCharArray(); + StringBuilder splitBuilder = new StringBuilder(); + for (char c : chars) { + if (c != '{' && c != ' ') { + if (c == ',') { + String value = Integer.toHexString( + Integer.valueOf(splitBuilder.toString())); + if (value.length() == 1) { + sb.append('0'); + } + sb.append(value); + splitBuilder = new StringBuilder(); + } else { + splitBuilder.append(c); + } + } + } + return sb.toString(); + } + + private void setTopicStyle(ITopic topic, JSONObject json) { + if (json.has(LightenConstants.STYLE_ATTR_LINE_CLR)) { + registerStyle(topic, DOMConstants.ATTR_LINE_COLOR, colorToRgb( + json.getString(LightenConstants.STYLE_ATTR_LINE_CLR))); + } + if (json.has(LightenConstants.STYLE_ATTR_FONT_CLR)) { + registerStyle(topic, DOMConstants.ATTR_COLOR, colorToRgb( + json.getString(LightenConstants.STYLE_ATTR_FONT_CLR))); + } + if (json.has(LightenConstants.STYLE_ATTR_FONT_WEIGHT)) { + registerStyle(topic, DOMConstants.ATTR_FONT_WEIGHT, + json.getString(LightenConstants.STYLE_ATTR_FONT_WEIGHT)); + } + } + + public void error(SAXParseException arg0) throws SAXException { + log(arg0, null); + } + + public void fatalError(SAXParseException arg0) throws SAXException { + log(arg0, null); + } + + public void warning(SAXParseException arg0) throws SAXException { + log(arg0, null); + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImportWizard.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImportWizard.java index 2c9ae51eb..006d7cd69 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImportWizard.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImportWizard.java @@ -1,108 +1,108 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.imports.mm; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.mindmanager.MMConstants; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.imports.ImportPlugin; -import org.xmind.ui.wizards.AbstractMindMapImportPage; -import org.xmind.ui.wizards.AbstractMindMapImportWizard; -import org.xmind.ui.wizards.MindMapImporter; - -public class MindManagerImportWizard extends AbstractMindMapImportWizard { - - private static final String SETTINGS_ID = "org.xmind.ui.imports.MindManager"; //$NON-NLS-1$ - - private static final String PAGE_ID = "importMindManager"; //$NON-NLS-1$ - - private static final String EXT = "*" + MMConstants.FILE_EXTENSION; //$NON-NLS-1$ - - private class MindManagerImportPage extends AbstractMindMapImportPage { - - protected MindManagerImportPage() { - super(PAGE_ID, ImportMessages.MindManagerImportPage_title); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 15; - composite.setLayout(layout); - setControl(composite); - - Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); - - Control destinationControl = createDestinationControl(composite); - destinationControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, - true, true)); - - updateStatus(); - - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - openBrowseDialog(); - } - }); - } - - protected FileDialog createBrowseDialog() { - FileDialog dialog = super.createBrowseDialog(); - dialog.setFilterExtensions(new String[] { EXT }); - dialog.setFilterNames(new String[] { NLS.bind( - ImportMessages.MindManagerImportPage_FilterName, EXT) }); - return dialog; - } - } - - private MindManagerImportPage page; - - public MindManagerImportWizard() { - IDialogSettings settings = ImportPlugin.getDefault() - .getDialogSettings().getSection(SETTINGS_ID); - if (settings == null) { - settings = ImportPlugin.getDefault().getDialogSettings() - .addNewSection(SETTINGS_ID); - } - setDialogSettings(settings); - setWindowTitle(ImportMessages.MindManagerImportWizard_windowTitle); - } - - public void addPages() { - addPage(page = new MindManagerImportPage()); - } - - protected String getApplicationId() { - return "MindManager"; //$NON-NLS-1$ - } - - protected MindMapImporter createImporter(String sourcePath, - IWorkbook targetWorkbook) { - return new MindManagerImporter(sourcePath, targetWorkbook); - } - - protected void handleExportException(Throwable e) { - super.handleExportException(e); - page.setErrorMessage(e.getLocalizedMessage()); - } - +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.imports.mm; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.IWorkbook; +import org.xmind.core.io.mindmanager.MMConstants; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.imports.ImportPlugin; +import org.xmind.ui.wizards.AbstractMindMapImportPage; +import org.xmind.ui.wizards.AbstractMindMapImportWizard; +import org.xmind.ui.wizards.MindMapImporter; + +public class MindManagerImportWizard extends AbstractMindMapImportWizard { + + private static final String SETTINGS_ID = "org.xmind.ui.imports.MindManager"; //$NON-NLS-1$ + + private static final String PAGE_ID = "importMindManager"; //$NON-NLS-1$ + + private static final String EXT = "*" + MMConstants.FILE_EXTENSION; //$NON-NLS-1$ + + private class MindManagerImportPage extends AbstractMindMapImportPage { + + protected MindManagerImportPage() { + super(PAGE_ID, ImportMessages.MindManagerImportPage_title); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + composite.setLayout(layout); + setControl(composite); + + Control fileGroup = createFileControls(composite); + fileGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + false)); + + Control destinationControl = createDestinationControl(composite); + destinationControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + true, true)); + + updateStatus(); + + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + openBrowseDialog(); + } + }); + } + + protected FileDialog createBrowseDialog() { + FileDialog dialog = super.createBrowseDialog(); + dialog.setFilterExtensions(new String[] { EXT }); + dialog.setFilterNames(new String[] { NLS.bind( + ImportMessages.MindManagerImportPage_FilterName, EXT) }); + return dialog; + } + } + + private MindManagerImportPage page; + + public MindManagerImportWizard() { + IDialogSettings settings = ImportPlugin.getDefault() + .getDialogSettings().getSection(SETTINGS_ID); + if (settings == null) { + settings = ImportPlugin.getDefault().getDialogSettings() + .addNewSection(SETTINGS_ID); + } + setDialogSettings(settings); + setWindowTitle(ImportMessages.MindManagerImportWizard_windowTitle); + } + + public void addPages() { + addPage(page = new MindManagerImportPage()); + } + + protected String getApplicationId() { + return "MindManager"; //$NON-NLS-1$ + } + + protected MindMapImporter createImporter(String sourcePath, + IWorkbook targetWorkbook) { + return new MindManagerImporter(sourcePath, targetWorkbook); + } + + protected void handleExportException(Throwable e) { + super.handleExportException(e); + page.setErrorMessage(e.getLocalizedMessage()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImporter.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImporter.java index 9d30055af..f6e1655db 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImporter.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/mm/MindManagerImporter.java @@ -1,2119 +1,2120 @@ -/* - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed - * under the Eclipse Public License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: XMind Ltd. - initial API and implementation - */ -package org.xmind.ui.internal.imports.mm; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.osgi.util.NLS; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IBoundary; -import org.xmind.core.IFileEntry; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IIdentifiable; -import org.xmind.core.IImage; -import org.xmind.core.IImageSpan; -import org.xmind.core.ILegend; -import org.xmind.core.INotes; -import org.xmind.core.INumbering; -import org.xmind.core.IParagraph; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISpan; -import org.xmind.core.ISummary; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.ITopicRange; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.dom.NumberUtils; -import org.xmind.core.internal.dom.StyleSheetImpl; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; -import org.xmind.core.io.ResourceMappingManager; -import org.xmind.core.io.mindmanager.MMConstants; -import org.xmind.core.io.mindmanager.MMResourceMappingManager; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.imports.ImporterUtils; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.io.MonitoredInputStream; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.wizards.MindMapImporter; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class MindManagerImporter extends MindMapImporter - implements MMConstants, ErrorHandler { - - private static final Pattern DATE_PATTERN = Pattern.compile( - "((\\d+)-(\\d{1,2})-(\\d{1,2}))T((\\d{1,2}):(\\d{1,2}):(\\d{1,2}))"); //$NON-NLS-1$ - - private static final String TRANSPARENT_VALUE = "0.00"; //$NON-NLS-1$ - - private static Pattern OID_PATTERN = null; - - private class NotesImporter { - - IParagraph currentParagraph = null; -// IBaseParagraph currentParagraph = null; - - Stack styleStack = new Stack(); - - IHtmlNotesContent content; - - public NotesImporter(IHtmlNotesContent content) { - this.content = content; - } - - public void loadFrom(Element notesGroupEle, Element element) - throws InterruptedException { - checkInterrupted(); - String tagName = DOMUtils.getLocalName(element.getTagName()); - - if ("br".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ - addParagraph(); - return; - } - - boolean isParagraph = "p".equalsIgnoreCase(tagName) //$NON-NLS-1$ - || "li".equalsIgnoreCase(tagName); //$NON-NLS-1$ - IStyle style = pushStyle(element, - isParagraph ? IStyle.PARAGRAPH : IStyle.TEXT); - - if (isParagraph) { - addParagraph(); - } else if ("img".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ - - addImage(notesGroupEle, element); - - } - - NodeList nl = element.getChildNodes(); - for (int i = 0; i < nl.getLength(); i++) { - Node node = nl.item(i); - short nodeType = node.getNodeType(); - if (nodeType == Node.TEXT_NODE) { - addText(node.getTextContent()); - } else if (nodeType == Node.ELEMENT_NODE) { - loadFrom(notesGroupEle, (Element) node); - } - } - - popStyle(style); - } - - private void addText(String text) { - if (text == null) - return; - text = text.trim(); - if ("".equals(text)) //$NON-NLS-1$ - return; - - addSpan(content.createTextSpan(text)); - } - - private void addImage(Element notesGroupEle, Element imgEle) - throws InterruptedException { - Iterator it = children(notesGroupEle, "ap:NotesData"); //$NON-NLS-1$ - while (it.hasNext()) { - Element notesDataEle = it.next(); - String imgUri = att(notesDataEle, "ImageUri"); //$NON-NLS-1$ - String sourceImg = att(imgEle, "src"); //$NON-NLS-1$ - if (imgUri != null && sourceImg != null - && imgUri.equals(sourceImg)) { - loadImageAtt(imgUri, loadUri(notesDataEle)); - String srcUrl = loadUri(notesDataEle); - if (srcUrl != null) { - String entryPath = idMap.get(srcUrl); - if (entryPath != null) { - addSpan(content.createImageSpan(HyperlinkUtils - .toAttachmentPath(entryPath))); - } - } - } - } - - } - - private void addSpan(ISpan span) { - if (currentParagraph == null) - addParagraph(); - - currentParagraph.addSpan(span); - - if (!(span instanceof IImageSpan)) { - registerStyle(span, Styles.FontFamily, Styles.FontSize, - Styles.TextColor, Styles.FontWeight, - Styles.TextDecoration, Styles.FontStyle); - } - } - - private void addParagraph() { - currentParagraph = content.createParagraph(); -// currentParagraph = content -// .createParagraph(IBaseParagraph.GENERAL_PARAGRAPH); - content.addParagraph(currentParagraph); - registerStyle(currentParagraph, Styles.TextAlign); - } - - private void registerStyle(IStyled host, String... keys) { - for (IStyle style : styleStack) { - registerStyle(host, style, keys); - } - } - - private void registerStyle(IStyled host, IStyle style, String... keys) { - for (String key : keys) { - String value = style.getProperty(key); - if (value != null) { - MindManagerImporter.this.registerStyle(host, key, value); - } - } - } - - private IStyle pushStyle(Element ele, String type) { - IStyle style = getTempStyleSheet().createStyle(type); - receiveStyle(ele, style); - if (style.isEmpty()) { - style = null; - } else { - styleStack.push(style); - } - return style; - } - - private void receiveStyle(Element ele, IStyle style) { - String align = parseAlign(att(ele, "align")); //$NON-NLS-1$ - if (align != null) { - style.setProperty(Styles.TextAlign, align); - } - - String name = ele.getTagName(); - if ("b".equalsIgnoreCase(name)) { //$NON-NLS-1$ - style.setProperty(Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); - } else if ("i".equalsIgnoreCase(name)) { //$NON-NLS-1$ - style.setProperty(Styles.FontStyle, Styles.FONT_STYLE_ITALIC); - } else if ("u".equalsIgnoreCase(name)) { //$NON-NLS-1$ - style.setProperty(Styles.TextDecoration, - Styles.TEXT_DECORATION_UNDERLINE); - } else if ("s".equalsIgnoreCase(name)) { //$NON-NLS-1$ - style.setProperty(Styles.TextDecoration, - Styles.TEXT_DECORATION_LINE_THROUGH); - } else if ("font".equalsIgnoreCase(name)) { //$NON-NLS-1$ - String fontName = att(ele, "face"); //$NON-NLS-1$ - String availableFontName = FontUtils - .getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName - : fontName; - if (fontName != null) { - style.setProperty(Styles.FontFamily, fontName); - } - } else if ("span".equalsIgnoreCase(name)) { //$NON-NLS-1$ - if ("font".equalsIgnoreCase( //$NON-NLS-1$ - ((Element) ele.getParentNode()).getTagName())) { - String color = att((Element) ele.getParentNode(), "color"); //$NON-NLS-1$ - style.setProperty(Styles.TextColor, color); - } - } - - String styleContent = att(ele, "style"); //$NON-NLS-1$ - if (styleContent != null) { - receiveStyleContent(style, styleContent); - } - - } - - private String parseAlign(String align) { - if (align != null) { - if (Styles.ALIGN_CENTER.equalsIgnoreCase(align) // - || Styles.ALIGN_LEFT.equalsIgnoreCase(align) // - || Styles.ALIGN_RIGHT.equalsIgnoreCase(align)) - return align; - } - return null; - } - - private void receiveStyleContent(IStyle style, String styleContent) { - String[] items = styleContent.trim().split(";"); //$NON-NLS-1$ - for (String item : items) { - item = item.trim(); - int colonIndex = item.indexOf(':'); - if (colonIndex > 0) { - String key = item.substring(0, colonIndex).trim(); - String value = item.substring(colonIndex + 1).trim(); - receiveStyleItem(style, key, value); - } - } - } - - private void receiveStyleItem(IStyle style, String key, String value) { - if ("color".equalsIgnoreCase(key)) { //$NON-NLS-1$ - String color = parseColor(value); - if (color != null) { - style.setProperty(Styles.TextColor, color); - } - } else if ("font-size".equalsIgnoreCase(key)) { //$NON-NLS-1$ - int fontSize = NumberUtils.safeParseInt(value, -1); - if (fontSize > 0) { - style.setProperty(Styles.FontSize, - StyleUtils.addUnitPoint(fontSize)); - } - } - } - - private void popStyle(IStyle style) { - if (style == null) - return; - - if (styleStack != null && styleStack.peek() == style) { - styleStack.pop(); - } - } - - private String parseColor(String color) { - return color; -// if (color != null) { -// return ColorUtils.toString(ColorUtils.toRGB(color)); -// } -// return null; - } - - } - - private static final String DOCUMENT_XML = "Document.xml"; //$NON-NLS-1$ - - private static final double DPM = 72 / 25.4; - - private static ResourceMappingManager mappings = null; - -// private ZipFile sourceFile; - private IStorage tempStorage; - - private IInputSource tempSource; - - private ISheet targetSheet; - - private Map idMap = new HashMap(30); - - private IStyleSheet tempStyleSheet = null; - - private Map styleMap = new HashMap(30); - - private IStyle theme = null; - - private Map> topicLinkMap = new HashMap>( - 10); - - public MindManagerImporter(String sourcePath) { - super(sourcePath); - } - - public MindManagerImporter(String sourcePath, IWorkbook targetWorkbook) { - super(sourcePath, targetWorkbook); - } - - public void build() throws InvocationTargetException, InterruptedException { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ImportFromMindManagerCount"); //$NON-NLS-1$ - getMonitor().beginTask(null, 100); - try { - getMonitor() - .subTask(ImportMessages.MindManagerImporter_ReadingContent); - - tempStorage = createTemporaryStorage(); - extractSourceFileToTemporaryStorage(); - tempSource = tempStorage.getInputSource(); -// sourceFile = new ZipFile(getSourcePath()); -// ZipEntry docEntry = sourceFile.getEntry(DOCUMENT_XML); - - Document doc = readContents(); - - getMonitor().worked(45); - checkInterrupted(); - - getMonitor().subTask( - ImportMessages.MindManagerImporter_ReadingElements); - loadSheet(doc.getDocumentElement()); - setTopicLinks(); - getMonitor().worked(45); - - checkInterrupted(); - getMonitor().subTask( - ImportMessages.MindManagerImporter_ArrangingStyles); - arrangeStyles(); - getMonitor().worked(5); - - checkInterrupted(); - getMonitor().subTask( - ImportMessages.MindManagerImporter_GeneratingTheme); - generateTheme(); - getMonitor().worked(5); - getMonitor().done(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } finally { - clearTempStorage(); - } - postBuilded(); - } - - private Document readContents() throws Exception { - InputStream docEntryStream = tempSource.getEntryStream(DOCUMENT_XML); - if (docEntryStream == null) - throw new IOException("No content entry"); //$NON-NLS-1$ - - DocumentBuilder builder = getDocumentBuilder(); - builder.setErrorHandler(this); -// InputStream in = sourceFile.getInputStream(docEntryStream); -// in = new MonitoredInputStream(in, getMonitor()); - InputStream in = new MonitoredInputStream(docEntryStream, getMonitor()); - Document doc; - try { - doc = builder.parse(in); - } finally { - builder.setErrorHandler(null); - try { - in.close(); - } catch (Exception e) { - } - } - return doc; - } - - /** - * @return - */ - private IStorage createTemporaryStorage() throws IOException { - String id = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", //$NON-NLS-1$ - System.currentTimeMillis()); - File tempDir = FileUtils.ensureDirectory(new File( - Core.getWorkspace().getTempDir("import/mindmanager"), id)); //$NON-NLS-1$ - return new DirectoryStorage(tempDir); - } - - private void extractSourceFileToTemporaryStorage() - throws IOException, CoreException { - FileInputStream fin = new FileInputStream(getSourcePath()); - try { - ZipInputStream zin = new ZipInputStream(new MonitoredInputStream( - new BufferedInputStream(fin), getMonitor())); - try { - FileUtils.extractZipFile(zin, tempStorage.getOutputTarget()); - } finally { - zin.close(); - } - } finally { - fin.close(); - } - - } - - private void checkInterrupted() throws InterruptedException { - if (getMonitor().isCanceled()) - throw new InterruptedException(); - } - - private void clearTempStorage() { - if (tempStorage != null) { - tempStorage.clear(); - tempStorage = null; - } -// if (sourceFile != null) { -// try { -// sourceFile.close(); -// } catch (IOException e) { -// } -// } -// sourceFile = null; - } - - private void loadSheet(Element docEle) throws InterruptedException { - checkInterrupted(); - - targetSheet = getTargetWorkbook().createSheet(); - - Element oneTopicEle = child(docEle, "OneTopic"); //$NON-NLS-1$ - if (oneTopicEle != null) { - loadRootTopic(oneTopicEle); - } - - Element relsEle = child(docEle, "Relationships"); //$NON-NLS-1$ - if (relsEle != null) { - loadRelationships(relsEle); - } - - Element styleGroupEle = child(docEle, "StyleGroup"); //$NON-NLS-1$ - if (styleGroupEle != null) { - loadStyleGroup(styleGroupEle); - } - - Element markersGroupEle = child(docEle, "MarkersSetGroup"); //$NON-NLS-1$ - if (markersGroupEle != null) { - loadMarkersGroup(markersGroupEle); - } - - addTargetSheet(targetSheet); - } - - public ISheet getTargetSheet() { - return targetSheet; - } - - private void arrangeStyles() throws InterruptedException { - IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); - for (Entry en : styleMap.entrySet()) { - checkInterrupted(); - IStyled styleOwner = en.getKey(); - IStyle style = en.getValue(); - IStyle importedStyle = targetStyleSheet.importStyle(style); - if (importedStyle != null) { - styleOwner.setStyleId(importedStyle.getId()); - } - } - } - - private void loadMarkersGroup(Element markersGroupEle) - throws InterruptedException { - checkInterrupted(); - ILegend legend = getTargetSheet().getLegend(); - Element markersSetsEle = child(markersGroupEle, "ap:IconMarkersSets"); //$NON-NLS-1$ - if (markersSetsEle != null) { - Iterator it = children(markersSetsEle, - "ap:IconMarkersSet"); //$NON-NLS-1$ - while (it.hasNext()) { - checkInterrupted(); - Element markersSetEle = it.next(); - loadLegendMarkers(markersSetEle, legend, "ap:IconMarkers", //$NON-NLS-1$ - "ap:IconMarker", //$NON-NLS-1$ - "ap:OneStockIcon", //$NON-NLS-1$ - "IconType"); //$NON-NLS-1$ - } - } - - loadLegendMarkers(markersGroupEle, legend, "ap:IconMarkers", //$NON-NLS-1$ - "ap:IconMarker", //$NON-NLS-1$ - "ap:OneStockIcon", //$NON-NLS-1$ - "IconType"); //$NON-NLS-1$ - loadLegendMarkers(markersGroupEle, legend, "ap:TaskPercentageMarkers", //$NON-NLS-1$ - "ap:TaskPercentageMarker", //$NON-NLS-1$ - "ap:TaskPercentage", //$NON-NLS-1$ - "TaskPercentage"); //$NON-NLS-1$ - loadLegendMarkers(markersGroupEle, legend, "ap:TaskPriorityMarkers", //$NON-NLS-1$ - "ap:TaskPriorityMarker", //$NON-NLS-1$ - "ap:TaskPriority", //$NON-NLS-1$ - "TaskPriority" //$NON-NLS-1$ - ); - } - - private void loadLegendMarkers(Element markersSetEle, ILegend legend, - String markersEleName, String markerEleName, String iconEleName, - String iconAttrName) throws InterruptedException { - checkInterrupted(); - Element markersEle = child(markersSetEle, markersEleName); - if (markersEle != null) - loadLegendMarkers(markersEle, legend, markerEleName, iconEleName, - iconAttrName); - } - - private void loadLegendMarkers(Element markersEle, ILegend legend, - String markerEleName, String iconEleName, String iconAttrName) - throws InterruptedException { - checkInterrupted(); - Iterator it = children(markersEle, markerEleName); - while (it.hasNext()) { - checkInterrupted(); - Element markerEle = it.next(); - Element iconEle = child(markerEle, iconEleName); - if (iconEle != null) { - String type = att(iconEle, iconAttrName); - if (type != null) { - String markerId = getMapping("marker", type, null); //$NON-NLS-1$ - if (markerId != null) { - String name = loadName(markerEle); - legend.setMarkerDescription(markerId, name); - } - } - } - } - } - - private static String loadName(Element parentEle) { - return loadName(parentEle, null); - } - - private static String loadName(Element parentEle, String eleName) { - if (eleName == null) - eleName = "ap:Name"; //$NON-NLS-1$ - Element ele = child(parentEle, eleName); - if (ele != null) { - return att(ele, "Name"); //$NON-NLS-1$ - } - return null; - } - - private void loadStyleGroup(Element styleGroupEle) - throws InterruptedException { - checkInterrupted(); - loadTopicTheme(styleGroupEle); - loadRelTheme(styleGroupEle); - loadBoundaryTheme(styleGroupEle); - loadSheetStyle(styleGroupEle); - } - - private void loadSheetStyle(Element styleGroupEle) - throws InterruptedException { - checkInterrupted(); - ISheet sheet = getTargetSheet(); - Element structureEle = child(styleGroupEle, "ap:Structure"); //$NON-NLS-1$ - if (structureEle != null) { - Float lineWidth = parseFloat( - att(structureEle, "MainTopicLineWidth")); //$NON-NLS-1$ - if (lineWidth != null && lineWidth.floatValue() > 3.0f) { - registerStyle(sheet, Styles.LineTapered, Styles.TAPERED); - } - } - - Element bgFillEle = child(styleGroupEle, "ap:BackgroundFill"); //$NON-NLS-1$ - if (bgFillEle != null) { - String fillColor = parseColor(att(bgFillEle, "FillColor")); //$NON-NLS-1$ - if (fillColor != null) { - registerStyle(sheet, Styles.FillColor, fillColor); - } - } - - Element bgImgEle = child(styleGroupEle, "ap:BackgroundImageData"); //$NON-NLS-1$ - if (bgImgEle != null) { - String uri = loadUri(bgImgEle); - if (uri != null) { - IFileEntry entry = loadAttachment(null, uri, "*.png"); //$NON-NLS-1$ - if (entry != null && entry.getSize() > 0) { - registerStyle(sheet, Styles.Background, - HyperlinkUtils.toAttachmentURL(entry.getPath())); - int transparency = NumberUtils - .safeParseInt(att(bgImgEle, "Transparency"), -1); //$NON-NLS-1$ - if (transparency >= 0) { - double opacity = (100 - transparency) * 1.0 / 100; - registerStyle(sheet, Styles.Opacity, - String.format("%.2f", opacity)); //$NON-NLS-1$ - } - } - } - } - } - - private void loadBoundaryTheme(Element styleGroupEle) - throws InterruptedException { - checkInterrupted(); - Element parentEle = child(styleGroupEle, "ap:BoundaryDefaultsGroup"); //$NON-NLS-1$ - if (parentEle == null) - return; - - loadThemeColor(parentEle, true, true, true, IStyle.BOUNDARY, - Styles.FAMILY_BOUNDARY); - loadThemeLineStyle(parentEle, IStyle.BOUNDARY, Styles.FAMILY_BOUNDARY); - loadThemeBoundaryShape(parentEle, Styles.FAMILY_BOUNDARY); - } - - private void loadThemeBoundaryShape(Element parentEle, String styleFamily) - throws InterruptedException { - checkInterrupted(); - Element ele = child(parentEle, "ap:DefaultBoundaryShape"); //$NON-NLS-1$ - if (ele == null) - return; - - String shape = parseBoundaryShape(att(ele, "BoundaryShape")); //$NON-NLS-1$ - registerTheme(IStyle.BOUNDARY, styleFamily, Styles.ShapeClass, shape); - } - - private void loadThemeLineStyle(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - Element ele = child(parentEle, "ap:DefaultLineStyle"); //$NON-NLS-1$ - if (ele == null) - return; - - String linePattern = parseLinePattern(att(ele, "LineDashStyle")); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.LinePattern, linePattern); - - String lineWidth = parseLineWidth(att(ele, "LineWidth")); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.LineWidth, lineWidth); - } - - private void loadRelTheme(Element styleGroupEle) - throws InterruptedException { - checkInterrupted(); - Element parentEle = child(styleGroupEle, - "ap:RelationshipDefaultsGroup"); //$NON-NLS-1$ - if (parentEle == null) - return; - - loadThemeColor(parentEle, false, false, true, IStyle.RELATIONSHIP, - Styles.FAMILY_RELATIONSHIP); - loadThemeLineStyle(parentEle, IStyle.RELATIONSHIP, - Styles.FAMILY_RELATIONSHIP); - loadThemeArrowStyle(parentEle, Styles.FAMILY_RELATIONSHIP); - loadThemeRelShape(parentEle, Styles.FAMILY_RELATIONSHIP); - } - - private void loadThemeRelShape(Element parentEle, String styleFamily) - throws InterruptedException { - checkInterrupted(); - Element relShapeEle = child(parentEle, - "ap:DefaultRelationshipLineShape"); //$NON-NLS-1$ - if (relShapeEle == null) - return; - - String shape = parseRelationshipShape(att(relShapeEle, "LineShape")); //$NON-NLS-1$ - registerTheme(IStyle.RELATIONSHIP, styleFamily, Styles.ShapeClass, - shape); - } - - private void loadThemeArrowStyle(Element parentEle, String styleFamily) - throws InterruptedException { - checkInterrupted(); - Iterator it = children(parentEle, "ap:DefaultConnectionStyle"); //$NON-NLS-1$ - while (it.hasNext()) { - checkInterrupted(); - Element ele = it.next(); - int index = NumberUtils.safeParseInt(att(ele, "Index"), -1); //$NON-NLS-1$ - if (index == 0 || index == 1) { - String shape = parseConnShape(att(ele, "ConnectionShape")); //$NON-NLS-1$ - if (shape != null) { - String styleKey = index == 0 ? Styles.ArrowBeginClass - : Styles.ArrowEndClass; - registerTheme(IStyle.RELATIONSHIP, styleFamily, styleKey, - shape); - } - } - } - } - - private void loadThemeColor(Element parentEle, boolean fill, - boolean fillAlpha, boolean line, String type, String styleFamily) - throws InterruptedException { - checkInterrupted(); - Element colorEle = child(parentEle, "ap:DefaultColor"); //$NON-NLS-1$ - if (colorEle == null) - return; - - if (fill || fillAlpha) { - String fillColor = att(colorEle, "FillColor"); //$NON-NLS-1$ - if (fill) { - registerTheme(type, styleFamily, Styles.FillColor, - parseColor(fillColor)); - } - if (fillAlpha) { - registerTheme(type, styleFamily, Styles.Opacity, - parseAlpha(fillColor)); - } - } - - if (line) { - String lineColor = att(colorEle, "LineColor"); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.LineColor, - parseColor(lineColor)); - } - } - - private void loadTopicTheme(Element styleGroupEle) - throws InterruptedException { - checkInterrupted(); - Element rootEle = child(styleGroupEle, "ap:RootTopicDefaultsGroup"); //$NON-NLS-1$ - if (rootEle != null) { - loadTopicTheme(rootEle, null, null, Styles.FAMILY_CENTRAL_TOPIC); - } - - int deepestLevel = 0; - Element realSubEle = null; - Iterator it = children(rootEle, - "ap:RootSubTopicDefaultsGroup"); //$NON-NLS-1$ - while (it.hasNext()) { - Element subEle = it.next(); - int level = NumberUtils.safeParseInt(att(subEle, "Level"), -1); //$NON-NLS-1$ - if (level == 0) { - loadTopicTheme(subEle, null, null, Styles.FAMILY_MAIN_TOPIC); - } else if (level > 0) { - if (level > deepestLevel) { - deepestLevel = level; - realSubEle = subEle; - } - } - } - - if (realSubEle != null) { - loadTopicTheme(realSubEle, null, null, Styles.FAMILY_SUB_TOPIC); - } - - Element floatingEle = child(styleGroupEle, - "ap:LabelTopicDefaultsGroup"); //$NON-NLS-1$ - if (floatingEle != null) { - loadTopicTheme(floatingEle, "ap:DefaultLabelFloatingTopicShape", //$NON-NLS-1$ - "LabelFloatingTopicShape", Styles.FAMILY_FLOATING_TOPIC); //$NON-NLS-1$ - } - } - - private void loadTopicTheme(Element parentEle, String shapeEleName, - String shapeAttrName, String styleFamily) - throws InterruptedException { - checkInterrupted(); - loadThemeColor(parentEle, true, false, true, IStyle.TOPIC, styleFamily); - loadThemeTextStyle(parentEle, styleFamily); - loadThemeTopicShape(parentEle, shapeEleName, shapeAttrName, - styleFamily); - loadThemeBranchStyle(parentEle, styleFamily); - } - - private void loadThemeBranchStyle(Element parentEle, String styleFamily) - throws InterruptedException { - checkInterrupted(); - Element ele = child(parentEle, "ap:DefaultSubTopicsShape"); //$NON-NLS-1$ - if (ele == null) - return; - - String branchConn = parseBranchConn( - att(ele, "SubTopicsConnectionStyle")); //$NON-NLS-1$ - registerTheme(IStyle.TOPIC, styleFamily, Styles.LineClass, branchConn); - } - - private static String parseBranchConn(String connStyle) { - return getMapping("branchConnection", connStyle, null); //$NON-NLS-1$ - } - - private void loadThemeTopicShape(Element parentEle, String shapeEleName, - String shapeAttrName, String styleFamily) - throws InterruptedException { - checkInterrupted(); - if (shapeEleName == null) - shapeEleName = "ap:DefaultSubTopicShape"; //$NON-NLS-1$ - Element shapeEle = child(parentEle, shapeEleName); - if (shapeEle == null) - return; - - if (shapeAttrName == null) - shapeAttrName = "SubTopicShape"; //$NON-NLS-1$ - String shape = parseTopicShape(att(shapeEle, shapeAttrName)); - registerTheme(IStyle.TOPIC, styleFamily, Styles.ShapeClass, shape); - } - - private void loadThemeTextStyle(Element parentEle, String themeKey) - throws InterruptedException { - checkInterrupted(); - Element textEle = child(parentEle, "ap:Text"); //$NON-NLS-1$ - if (textEle == null) - return; - - loadThemeFont(textEle, IStyle.TOPIC, themeKey); - } - - private void loadThemeFont(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - Element fontEle = child(parentEle, "ap:Font"); //$NON-NLS-1$ - if (fontEle == null) - return; - - String color = parseColor(att(fontEle, "Color")); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.TextColor, color); - - String fontName = att(fontEle, "Name"); //$NON-NLS-1$ - String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName : fontName; - registerTheme(type, styleFamily, Styles.FontFamily, fontName); - - String size = att(fontEle, "Size"); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.FontSize, size); - - String bold = att(fontEle, "Bold"); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.FontWeight, - Boolean.parseBoolean(bold) ? Styles.FONT_WEIGHT_BOLD : null); - - String italic = att(fontEle, "Italic"); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.FontStyle, - Boolean.parseBoolean(italic) ? Styles.FONT_STYLE_ITALIC : null); - - boolean underline = Boolean.parseBoolean(att(fontEle, "Underline")); //$NON-NLS-1$ - boolean strikeout = Boolean.parseBoolean(att(fontEle, "Strikethrough")); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.TextDecoration, - StyleUtils.toTextDecoration(underline, strikeout)); - } - - private void registerTheme(String type, String styleFamily, String styleKey, - String styleValue) throws InterruptedException { - checkInterrupted(); - if (styleFamily == null || styleKey == null || styleValue == null) - return; - - if (theme == null) { - theme = getTempStyleSheet().createStyle(IStyle.THEME); - getTempStyleSheet().addStyle(theme, IStyleSheet.MASTER_STYLES); - } - - IStyle defaultStyle = theme.getDefaultStyle(styleFamily); - if (defaultStyle == null) { - defaultStyle = getTempStyleSheet().createStyle(type); - getTempStyleSheet().addStyle(defaultStyle, - IStyleSheet.AUTOMATIC_STYLES); - } - defaultStyle.setProperty(styleKey, styleValue); - } - - private void generateTheme() throws InterruptedException { - checkInterrupted(); - if (theme != null) { - IStyle importedTheme = getTargetWorkbook().getStyleSheet() - .importStyle(theme); - if (importedTheme != null) { - getTargetSheet().setThemeId(importedTheme.getId()); - } - } - } - - private void loadRelationships(Element relsEle) - throws InterruptedException { - checkInterrupted(); - Iterator it = children(relsEle, "ap:Relationship"); //$NON-NLS-1$ - while (it.hasNext()) { - Element relEle = it.next(); - loadRelationship(relEle); - } - } - - private void loadRelationship(Element relEle) throws InterruptedException { - checkInterrupted(); - IRelationship rel = getTargetWorkbook().createRelationship(); - getTargetSheet().addRelationship(rel); - loadOId(relEle, rel); - boolean autoRouting = loadAutoRouting(relEle); - loadConnections(relEle, rel, autoRouting); - loadLineStyle(relEle, rel); - loadRelLineShape(relEle, rel); - } - - private void loadRelLineShape(Element relEle, IRelationship rel) - throws InterruptedException { - checkInterrupted(); - Element relShapeEle = child(relEle, "ap:RelationshipLineShape"); //$NON-NLS-1$ - if (relShapeEle == null) - return; - String shape = parseRelationshipShape(att(relShapeEle, "LineShape")); //$NON-NLS-1$ - registerStyle(rel, Styles.ShapeClass, shape); - } - - private static String parseRelationshipShape(String shape) { - return getMapping("relationshipShape", shape, null); //$NON-NLS-1$ - } - - private void loadConnections(Element relEle, IRelationship rel, - boolean autoRouting) throws InterruptedException { - checkInterrupted(); - Iterator it = children(relEle, "ap:ConnectionGroup"); //$NON-NLS-1$ - while (it.hasNext()) { - Element connGroupEle = it.next(); - loadRelConnection(connGroupEle, rel, autoRouting); - } - } - - private void loadRelConnection(Element connGroupEle, IRelationship rel, - boolean autoRouting) throws InterruptedException { - checkInterrupted(); - int index = NumberUtils.safeParseInt(att(connGroupEle, "Index"), -1); //$NON-NLS-1$ - if (index != 0 && index != 1) - return; - - Element connEle = child(connGroupEle, "ap:Connection"); //$NON-NLS-1$ - if (connEle == null) - return; - - Element refEle = child(connEle, "ap:ObjectReference"); //$NON-NLS-1$ - if (refEle == null) - return; - - String oIdRef = att(refEle, "OIdRef"); //$NON-NLS-1$ - String endId = idMap.get(oIdRef); - if (endId == null) - return; - - if (index == 0) { - rel.setEnd1Id(endId); - } else { - rel.setEnd2Id(endId); - } - - if (!autoRouting || connEle != null) { - String cx = att(connEle, "CX"); //$NON-NLS-1$ - String cy = att(connEle, "CY"); //$NON-NLS-1$ - if (cx != null && cy != null) { - Float x = parseFloat(cx); - Float y = parseFloat(cy); - if (x != null && y != null) { - rel.getControlPoint(index).setPosition( - mm2Dots(x.floatValue()), mm2Dots(y.floatValue())); - } - } - } - - Element connStyleEle = child(connGroupEle, "ap:ConnectionStyle"); //$NON-NLS-1$ - if (connStyleEle != null) { - String arrowShape = parseConnShape( - att(connStyleEle, "ConnectionShape")); //$NON-NLS-1$ - String styleKey = index == 0 ? Styles.ArrowBeginClass - : Styles.ArrowEndClass; - registerStyle(rel, styleKey, arrowShape); - } - } - - private static String parseConnShape(String shape) { - return getMapping("arrowShape", shape, null); //$NON-NLS-1$ - } - - private boolean loadAutoRouting(Element relEle) - throws InterruptedException { - checkInterrupted(); - Element autoRouteEle = child(relEle, "ap:AutoRoute"); //$NON-NLS-1$ - if (autoRouteEle != null) { - return Boolean.parseBoolean(att(autoRouteEle, "AutoRouting")); //$NON-NLS-1$ - } - return false; - } - - private void loadRootTopic(Element oneTopicEle) - throws InterruptedException { - checkInterrupted(); - Element topicEle = child(oneTopicEle, "Topic"); //$NON-NLS-1$ - if (topicEle != null) { - loadTopicContent(topicEle, getTargetSheet().getRootTopic()); - } - } - - private void loadTopicContent(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - loadOId(topicEle, topic); - loadTitle(topicEle, topic); - loadColor(topicEle, topic, false); - loadPosition(topicEle, topic); - loadTopicViewGroup(topicEle, topic); - loadImage(topicEle, topic); - loadTopicShape(topicEle, topic); - loadHyperlink(topicEle, topic); - loadMarkers(topicEle, topic); - loadLabels(topicEle, topic); - loadNotes(topicEle, topic); - loadTask(topicEle, topic); - loadNumbering(topicEle, topic); - - loadSubTopics(topicEle, topic); - loadDetachedSubTopics(topicEle, topic); - loadBoundary(topicEle, topic); - loadStructure(topicEle, topic); - loadAttachments(topicEle, topic); - } - - private void loadAttachments(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element attGroupEle = child(topicEle, "ap:AttachmentGroup"); //$NON-NLS-1$ - if (attGroupEle == null) - return; - - Iterator it = children(attGroupEle, "ap:AttachmentData"); //$NON-NLS-1$ - while (it.hasNext()) { - Element attDataEle = it.next(); - String uri = loadUri(attDataEle); - if (uri != null) { - String oId = att(attDataEle, "AttachmentId"); //$NON-NLS-1$ - String name = att(attDataEle, "FileName"); //$NON-NLS-1$ - IFileEntry entry = loadAttachment(oId, uri, name); - if (entry != null) { - if (name == null) - name = new File(entry.getPath()).getName(); - ITopic attTopic = getTargetWorkbook().createTopic(); - attTopic.setTitleText(name); - attTopic.setHyperlink( - HyperlinkUtils.toAttachmentURL(entry.getPath())); - topic.add(attTopic, ITopic.ATTACHED); - } - } - } - } - - private void loadStructure(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element subTopicsShapeEle = child(topicEle, "ap:SubTopicsShape"); //$NON-NLS-1$ - if (subTopicsShapeEle == null) - return; - - String line = parseBranchConnection( - att(subTopicsShapeEle, "SubTopicsConnectionStyle")); //$NON-NLS-1$ - registerStyle(topic, Styles.LineClass, line); - - String structureClass = parseStructureType(subTopicsShapeEle); - topic.setStructureClass(structureClass); - } - - private static String parseStructureType(Element ele) { - String align = att(ele, "SubTopicsAlignment"); //$NON-NLS-1$ - String growth = att(ele, "SubTopicsGrowth"); //$NON-NLS-1$ - String growthDir = att(ele, "SubTopicsGrowthDirection"); //$NON-NLS-1$ - if (umCenter.equals(align) && umHorizontal.equals(growth)) { - if (umLeftAndRight.equals(growthDir)) - return "org.xmind.ui.map.clockwise"; //$NON-NLS-1$ - if (umRight.equals(growthDir)) - return "org.xmind.ui.logic.right"; //$NON-NLS-1$ - if (umLeft.equals(growthDir)) - return "org.xmind.ui.logic.left"; //$NON-NLS-1$ - } else if (umVertical.equals(growth) - && umMiddle.equals(att(ele, "SubTopicsVerticalAlignment"))) { //$NON-NLS-1$ - String vgd = att(ele, "SubTopicsVerticalGrowthDirection"); //$NON-NLS-1$ - if (umDown.equals(vgd) || umUpAndDown.equals(vgd)) - return "org.xmind.ui.org-chart.down"; //$NON-NLS-1$ - if (umUp.equals(vgd)) - return "org.xmind.ui.org-chart.up"; //$NON-NLS-1$ - } else if (umBottom.equals(align) && umHorizontal.equals(growth)) { - if (umRight.equals(growthDir) || umLeftAndRight.equals(growthDir)) - return "org.xmind.ui.tree.right"; //$NON-NLS-1$ - if (umLeft.equals(growthDir)) - return "org.xmind.ui.tree.left"; //$NON-NLS-1$ - } - return null; - } - - private static String parseBranchConnection(String lineShape) { - return getMapping("branchConnection", lineShape, null); //$NON-NLS-1$ - } - - private void loadBoundary(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - if (topic.isRoot()) - return; - - Element oneBoundaryEle = child(topicEle, "ap:OneBoundary"); //$NON-NLS-1$ - if (oneBoundaryEle == null) - return; - - Element boundaryEle = child(oneBoundaryEle, "ap:Boundary"); //$NON-NLS-1$ - if (boundaryEle == null) - return; - - checkInterrupted(); - String boundaryShape = getBoundaryShape(boundaryEle); - String shape = parseSummaryShape(boundaryShape); - ITopicRange range; - ITopic parent; - if (shape != null && topic.isAttached()) { - ISummary summary = getTargetWorkbook().createSummary(); - parent = topic.getParent(); - int index = topic.getIndex(); - summary.setStartIndex(index); - summary.setEndIndex(index); - parent.addSummary(summary); - range = summary; - } else { - shape = parseBoundaryShape(boundaryShape); - IBoundary boundary = getTargetWorkbook().createBoundary(); - if (topic.isAttached()) { - parent = topic.getParent(); - int index = topic.getIndex(); - boundary.setStartIndex(index); - boundary.setEndIndex(index); - parent.addBoundary(boundary); - } else { - parent = null; - boundary.setMasterBoundary(true); - topic.addBoundary(boundary); - } - range = boundary; - } - loadOId(boundaryEle, (IIdentifiable) range); - loadColor(boundaryEle, (IStyled) range, true); - loadLineStyle(boundaryEle, (IStyled) range); - registerStyle((IStyled) range, Styles.ShapeClass, shape); - - if (range instanceof ISummary && parent != null) { - ISummary summary = (ISummary) range; - ITopic summaryTopic = getTargetWorkbook().createTopic(); - parent.add(summaryTopic, ITopic.SUMMARY); - summary.setTopicId(summaryTopic.getId()); - - Element summaryTopicEle = getSummaryTopicEle(boundaryEle); - if (summaryTopicEle != null) { - loadTopicContent(summaryTopicEle, summaryTopic); - } else { - summaryTopic.setTitleText(" "); //$NON-NLS-1$ - registerStyle(summaryTopic, Styles.ShapeClass, - "org.xmind.topicShape.noBorder"); //$NON-NLS-1$ - } - } else if (range instanceof IBoundary) { - IBoundary boundary = (IBoundary) range; - Element boundaryTopicEle = getSummaryTopicEle(boundaryEle); - if (boundaryTopicEle != null) { - loadTitle(boundaryTopicEle, boundary); - } - } - } - - private Element getSummaryTopicEle(Element boundaryEle) { - Element oneSummaryTopicEle = child(boundaryEle, "ap:OneSummaryTopic"); //$NON-NLS-1$ - if (oneSummaryTopicEle != null) { - return child(oneSummaryTopicEle, "ap:Topic"); //$NON-NLS-1$ - } - return null; - } - - private String getBoundaryShape(Element boundaryEle) { - Element shapeEle = child(boundaryEle, "ap:BoundaryShape"); //$NON-NLS-1$ - if (shapeEle != null) { - return att(shapeEle, "BoundaryShape"); //$NON-NLS-1$ - } - return null; - } - - private static String parseBoundaryShape(String shape) { - return getMapping("boundaryShape", shape, null); //$NON-NLS-1$ - } - - private static String parseSummaryShape(String shape) { - return getMapping("summaryShape", shape, null); //$NON-NLS-1$ - } - - private void loadLineStyle(Element parentEle, IStyled host) - throws InterruptedException { - checkInterrupted(); - Element lineColor = child(parentEle, "ap:Color"); //$NON-NLS-1$ - if (lineColor != null) { - String color = att(lineColor, "LineColor");//$NON-NLS-1$ - if (color != null) { - registerStyle(host, Styles.LineColor, "#" + color.substring(2)); //$NON-NLS-1$ - } - } - - Element lineStyleEle = child(parentEle, "ap:LineStyle"); //$NON-NLS-1$ - if (lineStyleEle == null) - return; - - String linePattern = parseLinePattern( - att(lineStyleEle, "LineDashStyle")); //$NON-NLS-1$ - registerStyle(host, Styles.LinePattern, linePattern); - - String width = parseLineWidth(att(lineStyleEle, "LineWidth")); //$NON-NLS-1$ - registerStyle(host, Styles.LineWidth, width); - } - - private static String parseLineWidth(String width) { - Float w = parseFloat(width); - if (w != null) { - if (w <= 1.0) - return "1"; //$NON-NLS-1$ - if (w <= 2.25) - return "2"; //$NON-NLS-1$ - if (w <= 3.0) - return "3"; //$NON-NLS-1$ - if (w <= 4.5) - return "4"; //$NON-NLS-1$ - return "5"; //$NON-NLS-1$ - } - return null; - } - - private static String parseLinePattern(String dashStyle) { - return getMapping("lineStyle", dashStyle, null); //$NON-NLS-1$ - } - - private void loadDetachedSubTopics(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element subTopicsEle = child(topicEle, "ap:FloatingTopics"); //$NON-NLS-1$ - if (subTopicsEle != null) { - Iterator it = children(subTopicsEle, "ap:Topic"); //$NON-NLS-1$ - while (it.hasNext()) { - Element subTopicEle = it.next(); - ITopic subTopic = getTargetWorkbook().createTopic(); - Element item = child(subTopicEle, "ap:Offset"); //$NON-NLS-1$ - if (item != null && item.hasAttribute("OffsetPriority")) //$NON-NLS-1$ - topic.add(subTopic, ITopic.DETACHED); - else - topic.add(subTopic, ITopic.CALLOUT); - loadTopicContent(subTopicEle, subTopic); - } - } - } - - private void loadSubTopics(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element subTopicsEle = child(topicEle, "ap:SubTopics"); //$NON-NLS-1$ - if (subTopicsEle != null) { - Iterator it = children(subTopicsEle, "ap:Topic"); //$NON-NLS-1$ - while (it.hasNext()) { - Element subTopicEle = it.next(); - ITopic subTopic = getTargetWorkbook().createTopic(); - topic.add(subTopic, ITopic.ATTACHED); - loadTopicContent(subTopicEle, subTopic); - } - } - } - - private final static String NUMBER_FORMAT_NONE = "org.xmind.numbering.none"; //$NON-NLS-1$ - - private final static String NUMBER_FORMAT_ARABIC = "org.xmind.numbering.arabic"; //$NON-NLS-1$ - - private final static String NUMBER_FORMAT_ROMAN = "org.xmind.numbering.roman"; //$NON-NLS-1$ - - private final static String NUMBER_FORMAT_LOWERCASE = "org.xmind.numbering.lowercase"; //$NON-NLS-1$ - - private final static String NUMBER_FORMAT_UPPERCASE = "org.xmind.numbering.uppercase"; //$NON-NLS-1$ - - private Map numberingEles; - - private void loadNumbering(Element topicEle, ITopic topic) { - Element numberingEle = findNumberingEle(topicEle, topic); - if (numberingEle == null) - return; - - int maxDepth = getMaxDepth(numberingEle); - int topicDepth = getTopicDepth(topic); - String numberFormat = getNumberFormat(numberingEle, topicDepth); - if (numberFormat == null) - return; - - String prefix = getNumberingPrefix(numberingEle, topicDepth); - INumbering numbering = topic.getNumbering(); - - if ((maxDepth - topicDepth) >= 0) - numbering.setFormat(numberFormat); - else - numbering.setFormat(NUMBER_FORMAT_NONE); - - if (topicDepth == 1) - numbering.setPrependsParentNumbers(false); - numbering.setPrefix(prefix); - } - - private String getNumberFormat(Element numberingEle, int depth) { - String numbering = att(numberingEle, "cst1:Numbering"); //$NON-NLS-1$ - if (numbering == null) - return null; - - int formatIndex = (depth - 1) * 2; - if (formatIndex < 0 || (formatIndex + 1) > numbering.length()) - return NUMBER_FORMAT_NONE; - - String numberFormat = numbering.substring(formatIndex, formatIndex + 1); - if ("1".equals(numberFormat)) //$NON-NLS-1$ - return NUMBER_FORMAT_ARABIC; - if ("I".equals(numberFormat) || "i".equals(numberFormat)) //$NON-NLS-1$ //$NON-NLS-2$ - return NUMBER_FORMAT_ROMAN; - if ("A".equals(numberFormat)) //$NON-NLS-1$ - return NUMBER_FORMAT_UPPERCASE; - if ("a".equals(numberFormat)) //$NON-NLS-1$ - return NUMBER_FORMAT_LOWERCASE; - return NUMBER_FORMAT_NONE; - } - - private String getNumberingPrefix(Element numberingEle, int topicDepth) { - String preFix = att(numberingEle, "cst0:Level" + topicDepth + "Text"); //$NON-NLS-1$ //$NON-NLS-2$ - return preFix == null ? "" : preFix; //$NON-NLS-1$ - } - - private int getMaxDepth(Element numberingEle) { - String depth = att(numberingEle, "cst1:Depth"); //$NON-NLS-1$ - return Integer.parseInt(depth == null ? "1" //$NON-NLS-1$ - : depth); - } - - private int getTopicDepth(ITopic topic) { - if (numberingEles == null) - return 0; - - int topicDepth = 1; - while (topic != null) { - Element numberingEle = numberingEles.get(topic); - if (numberingEle != null) - return topicDepth; - topic = topic.getParent(); - topicDepth++; - } - return 0; - } - - private Element findNumberingEle(Element topicEle, ITopic topic) { - if (topicEle == null) - return null; - - Element numberingEle = child(topicEle, "cor:Custom"); //$NON-NLS-1$ - if (numberingEle != null) { - if (numberingEles == null) - numberingEles = new HashMap(); - numberingEles.put(topic, numberingEle); - return numberingEle; - } - return findParentNumbering(topic); - } - - private Element findParentNumbering(ITopic topic) { - if (numberingEles == null) - return null; - - int topicDepth = 1; - while (topic.getParent() != null) { - topic = topic.getParent(); - Element numberingEle = numberingEles.get(topic); - if (numberingEle != null - && (getMaxDepth(numberingEle) >= topicDepth)) - return numberingEle; - topicDepth++; - } - return null; - } - - private void loadNotes(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element notesGroupEle = child(topicEle, "ap:NotesGroup"); //$NON-NLS-1$ - if (notesGroupEle == null) - return; - -// Iterator it = children(notesGroupEle, "ap:NotesData"); //$NON-NLS-1$ -// while (it.hasNext()) { -// Element notesDataEle = it.next(); -// String imgUri = att(notesDataEle, "ImageUri"); //$NON-NLS-1$ -// String binaryUri = loadUri(notesDataEle); -// uriMap.put(imgUri, binaryUri); -// loadImageAtt(imgUri, binaryUri); -// } - - Element notesXhtmlDataEle = child(notesGroupEle, "ap:NotesXhtmlData"); //$NON-NLS-1$ - if (notesXhtmlDataEle != null) { - String bookmarks = getBookmarks(topicEle, topic); - - String plain = att(notesXhtmlDataEle, "PreviewPlainText"); //$NON-NLS-1$ - if (plain != null) { - IPlainNotesContent content = (IPlainNotesContent) getTargetWorkbook() - .createNotesContent(INotes.PLAIN); - content.setTextContent(bookmarks + plain); - topic.getNotes().setContent(INotes.PLAIN, content); - } - - Element htmlEle = child(notesXhtmlDataEle, "xhtml:html"); //$NON-NLS-1$ - if (htmlEle != null) { - IHtmlNotesContent content = (IHtmlNotesContent) getTargetWorkbook() - .createNotesContent(INotes.HTML); - loadHtmlNotes(notesGroupEle, htmlEle, content, bookmarks); - topic.getNotes().setContent(INotes.HTML, content); - } - } - } - - private void loadHtmlNotes(Element notesGroupEle, Element htmlEle, - IHtmlNotesContent content, String bookmarks) - throws InterruptedException { - NotesImporter notesImporter = new NotesImporter(content); - notesImporter.addText(bookmarks); - notesImporter.loadFrom(notesGroupEle, htmlEle); - } - - private void loadImageAtt(String imgUri, String uri) - throws InterruptedException { - checkInterrupted(); - loadAttachment(null, uri, "*.png"); //$NON-NLS-1$ - } - - private String getBookmarks(Element topicEle, ITopic topic) { - Element bookmarkEle = child(topicEle, "ap:Bookmark"); //$NON-NLS-1$ - if (bookmarkEle == null) - return ""; //$NON-NLS-1$ - - String bookmarkName = att(bookmarkEle, "Name"); //$NON-NLS-1$ - if (bookmarkName != null) { - return bookmarkName + '\r'; - } - - return ""; //$NON-NLS-1$ - } - - private void loadLabels(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element labelsEle = child(topicEle, "ap:TextLabels"); //$NON-NLS-1$ - if (labelsEle == null) - return; - - Iterator it = children(labelsEle, "ap:TextLabel"); //$NON-NLS-1$ - while (it.hasNext()) { - checkInterrupted(); - String label = att(it.next(), "TextLabelName"); //$NON-NLS-1$ - if (label != null) { - topic.addLabel(label); - } - } - } - - private void loadMarkers(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element taskEle = child(topicEle, "ap:Task"); //$NON-NLS-1$ - if (taskEle != null) { - addMarker(topic, att(taskEle, "TaskPriority")); //$NON-NLS-1$ - addMarker(topic, att(taskEle, "TaskPercentage")); //$NON-NLS-1$ - } - - Element iconsGroupEle = child(topicEle, "ap:IconsGroup"); //$NON-NLS-1$ - if (iconsGroupEle != null) { - Element iconsEle = child(iconsGroupEle, "ap:Icons"); //$NON-NLS-1$ - if (iconsEle != null) { - Iterator it = children(iconsEle, "ap:Icon"); //$NON-NLS-1$ - while (it.hasNext()) { - addMarker(topic, att(it.next(), "IconType")); //$NON-NLS-1$ - } - } - } - } - - private void addMarker(ITopic topic, String mmIconId) - throws InterruptedException { - checkInterrupted(); - if (mmIconId != null) { - String markerId = parseMarkerId(mmIconId); - if (markerId != null) { - topic.addMarker(markerId); - } - } - } - - @SuppressWarnings("nls") - private void addCheckPoint(ITopicExtensionElement content, - String hasCheckPoint) { - if (hasCheckPoint != null && hasCheckPoint.equals("true")) { - content.setAttribute("check-point", "true"); - } - } - - private static String parseMarkerId(String mmIconId) { - return getMapping("marker", mmIconId, "other-question"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - private void loadHyperlink(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element hyperlinkEle = child(topicEle, "ap:Hyperlink"); //$NON-NLS-1$ - if (hyperlinkEle == null) - return; - - String url = att(hyperlinkEle, "Url"); //$NON-NLS-1$ - if (url != null) { - if (url.startsWith("#xpointer(")) { //$NON-NLS-1$ - Matcher m = getOIdPattern().matcher(url); - if (m.find()) { - String OId = m.group(1); - recordTopicLink(OId, topic); - } - return; - } else if (!url.startsWith("http://") //$NON-NLS-1$ - && !url.startsWith("https://")) { //$NON-NLS-1$ - String path; - if (url.startsWith("\"") && url.endsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$ - path = url.substring(1, url.length() - 1); - } else { - path = url; - } - String absolute = att(hyperlinkEle, "Absolute"); //$NON-NLS-1$ - url = FilePathParser.toURI(path, - absolute != null && !Boolean.parseBoolean(absolute)); - } - topic.setHyperlink(url); - } - } - - private static Pattern getOIdPattern() { - if (OID_PATTERN == null) { - OID_PATTERN = Pattern.compile("@OId='([^']*)'"); //$NON-NLS-1$ - } - return OID_PATTERN; - } - - private void loadTopicShape(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element shapeEle = child(topicEle, "ap:SubTopicShape"); //$NON-NLS-1$ - if (shapeEle == null) - return; - - String shape = parseTopicShape(att(shapeEle, "SubTopicShape")); //$NON-NLS-1$ - registerStyle(topic, Styles.ShapeClass, shape); - } - - private static String parseTopicShape(String shape) { - return getMapping("topicShape", shape, null); //$NON-NLS-1$ - } - - private void loadImage(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element oneImageEle = child(topicEle, "ap:OneImage"); //$NON-NLS-1$ - if (oneImageEle == null) - return; - - Element imageEle = child(oneImageEle, "ap:Image"); //$NON-NLS-1$ - if (imageEle == null) - return; - - String oId = att(imageEle, "OId"); //$NON-NLS-1$ - - Element imageDataEle = child(imageEle, "ap:ImageData"); //$NON-NLS-1$ - if (imageDataEle == null) - return; - - String uri = loadUri(imageDataEle); - IFileEntry imgEntry = loadAttachment(oId, uri, "*.png"); //$NON-NLS-1$ - if (imgEntry == null) - return; - - IImage image = topic.getImage(); - image.setSource(HyperlinkUtils.toAttachmentURL(imgEntry.getPath())); - - Element sizeEle = child(imageEle, "ap:ImageSize"); //$NON-NLS-1$ - if (sizeEle != null) { - String width = att(sizeEle, "Width"); //$NON-NLS-1$ - String height = att(sizeEle, "Height"); //$NON-NLS-1$ - Float w = parseFloat(width); - Float h = parseFloat(height); - image.setSize( - w == null ? IImage.UNSPECIFIED : mm2Dots(w.floatValue()), - h == null ? IImage.UNSPECIFIED : mm2Dots(h.floatValue())); - } - - String position = null; - Element topicLayoutEle = child(topicEle, "ap:TopicLayout"); //$NON-NLS-1$ - if (topicLayoutEle != null) { - position = att(topicLayoutEle, "TopicTextAndImagePosition"); //$NON-NLS-1$ - } - image.setAlignment(parseImageAlign(position)); - } - - private IFileEntry loadAttachment(String oId, String uri, - String proposalName) throws InterruptedException { - checkInterrupted(); - if (uri == null) - return null; - - if (idMap.containsKey(uri)) { - String path = idMap.get(uri); - if (path != null) { - return getTargetWorkbook().getManifest().getFileEntry(path); - } - return null; - } - - String path = null; - if (uri.startsWith(MMARCH)) { - String mmEntryPath = uri.substring(MMARCH.length()); -// ZipEntry mmEntry = sourceFile.getEntry(mmEntryPath); -// if (mmEntry != null) { - InputStream mmEntryStream = tempSource.getEntryStream(mmEntryPath); - if (mmEntryStream == null) { -// log(new FileNotFoundException(), -// "No such entry: " + mmEntryPath); //$NON-NLS-1$ - return null; - } -// try { -// InputStream in = sourceFile.getInputStream(mmEntry); -// in = new MonitoredInputStream(in, getMonitor()); - if (proposalName != null) { - if (proposalName.startsWith("*.")) { //$NON-NLS-1$ - String ext = proposalName.substring(1); - String oldName = new File(mmEntryPath).getName(); - proposalName = FileUtils.getNoExtensionFileName(oldName) - + ext; - } - } - InputStream in = new MonitoredInputStream(mmEntryStream, - getMonitor()); - try { - IFileEntry entry = getTargetWorkbook().getManifest() - .createAttachmentFromStream(in, proposalName); - path = entry.getPath(); - } catch (IOException e) { - log(e, "Failed to create attachment from: " //$NON-NLS-1$ - + mmEntryPath); - } finally { - try { - in.close(); - } catch (IOException e) { - } - } - } - idMap.put(uri, path); - return getTargetWorkbook().getManifest().getFileEntry(path); - } - - private static String parseImageAlign(String position) { - return getMapping("imageAlignment", position, IImage.RIGHT); //$NON-NLS-1$ - } - - private static String loadUri(Element ele) { - if (ele != null) { - Element uriEle = child(ele, "cor:Uri"); //$NON-NLS-1$ - if (uriEle != null) { - return uriEle.getTextContent(); - } - } - return null; - } - - private void loadTopicViewGroup(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element viewGroupEle = child(topicEle, "ap:TopicViewGroup"); //$NON-NLS-1$ - if (viewGroupEle != null) { - Element collapsedEle = child(viewGroupEle, "ap:Collapsed"); //$NON-NLS-1$ - if (collapsedEle != null) { - String c = att(collapsedEle, "Collapsed"); //$NON-NLS-1$ - if (Boolean.parseBoolean(c)) { - topic.setFolded(true); - } - } - } - } - - private void loadPosition(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element offsetEle = child(topicEle, "ap:Offset"); //$NON-NLS-1$ - if (offsetEle != null) { - String cx = att(offsetEle, "CX"); //$NON-NLS-1$ - String cy = att(offsetEle, "CY"); //$NON-NLS-1$ - Float x = parseFloat(cx); - Float y = parseFloat(cy); - if (x != null && y != null && x.floatValue() != 0 - && y.floatValue() != 0) { - topic.setPosition(mm2Dots(x), mm2Dots(y)); - } - } - } - - private static Float parseFloat(String value) { - if (value != null) { - try { - return Float.valueOf(value); - } catch (Throwable e) { - } - } - return null; - } - - private void loadTask(Element ownerEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - Element taskEle = child(ownerEle, "ap:Task"); //$NON-NLS-1$ - if (taskEle == null) - return; - - ITopicExtensionElement taskContent = null; - String startDate = att(taskEle, "StartDate"); //$NON-NLS-1$ - if (startDate != null) { - Matcher m = DATE_PATTERN.matcher(startDate); - if (m.find()) { - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("start-date"); //$NON-NLS-1$ - ITopicExtensionElement ele = taskContent - .createChild("start-date"); //$NON-NLS-1$ - ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ - } - } - - String endDate = att(taskEle, "DeadlineDate"); //$NON-NLS-1$; - if (endDate != null) { - Matcher m = DATE_PATTERN.matcher(endDate); - if (m.find()) { - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("end-date");//$NON-NLS-1$ - ITopicExtensionElement ele = taskContent - .createChild("end-date"); //$NON-NLS-1$ - ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ - - } - } - - String resources = att(taskEle, "Resources"); //$NON-NLS-1$ - if (resources != null) { - String[] resourceArray = resources.split("; "); //$NON-NLS-1$ - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("assigned-to");//$NON-NLS-1$ - ITopicExtensionElement ele = taskContent.createChild("assigned-to"); //$NON-NLS-1$ - ele.setTextContent(resources); - for (String resource : resourceArray) { - topic.addLabel(NLS.bind( - ImportMessages.MindManagerImporter_ResourceLabel, - resource.replaceAll(",", ";"))); //$NON-NLS-1$//$NON-NLS-2$ - } - } - - String durationHours = att(taskEle, "DurationHours"); //$NON-NLS-1$ - if (durationHours != null) { - String durationLabel = null; - String durationUnit = att(taskEle, "DurationUnit"); //$NON-NLS-1$ - if (durationUnit != null) { - try { - int hours = Integer.parseInt(durationHours); - if ("urn:mindjet:Month".equals(durationUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.MindManagerImporter_Months, - hours / 160); - } else if ("urn:mindjet:Week".equals(durationUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.MindManagerImporter_Weeks, - hours / 40); - } else if ("urn:mindjet:Day".equals(durationUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.MindManagerImporter_Days, - hours / 8); - } - } catch (NumberFormatException e) { - } - } - if (durationLabel == null) { - durationLabel = NLS.bind( - ImportMessages.MindManagerImporter_Hours, - durationHours); - } - topic.addLabel( - NLS.bind(ImportMessages.MindManagerImporter_DurationLabel, - durationLabel)); - } - - addCheckPoint(ensureTaskContent(topic, taskContent), - att(taskEle, "Milestone")); //$NON-NLS-1$ - } - - private static ITopicExtensionElement ensureTaskContent(ITopic topic, - ITopicExtensionElement taskContent) { - if (taskContent != null) - return taskContent; - ITopicExtension ext = topic.createExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ - return ext.getContent(); - } - - private void loadTitle(Element ownerEle, ITitled titleOwner) - throws InterruptedException { - checkInterrupted(); - Element textEle = child(ownerEle, "ap:Text"); //$NON-NLS-1$ - String title = textEle == null ? null : att(textEle, "PlainText"); //$NON-NLS-1$ - if (title == null && titleOwner instanceof ITopic) { - title = ImporterUtils.getDefaultTopicTitle((ITopic) titleOwner); - } - if (title != null) { - titleOwner.setTitleText(title); - } - - if (textEle != null && titleOwner instanceof IStyled) { - Element fontEle = child(textEle, "ap:Font"); //$NON-NLS-1$ - if (fontEle != null) { - loadFont(fontEle, (IStyled) titleOwner); - } - String align = textEle == null ? null - : att(textEle, "TextAlignment"); //$NON-NLS-1$ - if (align != null) { - loadTextAlignment(align, (IStyled) titleOwner); - } - } - } - - private void loadTextAlignment(String align, IStyled styleOwner) { - if (align.startsWith("urn:mindjet:")) { //$NON-NLS-1$ - int len = "urn:mindjet:".length(); //$NON-NLS-1$ - String textAlign = align.substring(len).toLowerCase(); - registerStyle(styleOwner, Styles.TextAlign, textAlign); - } - } - - private void loadFont(Element fontEle, IStyled styleOwner) - throws InterruptedException { - checkInterrupted(); - registerStyle(styleOwner, Styles.TextColor, - parseColor(att(fontEle, "Color"))); //$NON-NLS-1$ - - String fontName = att(fontEle, "Name"); //$NON-NLS-1$ - String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName : fontName; - registerStyle(styleOwner, Styles.FontFamily, fontName); - - registerStyle(styleOwner, Styles.FontSize, - parseFontSize(att(fontEle, "Size"))); //$NON-NLS-1$ - registerStyle(styleOwner, Styles.FontWeight, - Boolean.parseBoolean(att(fontEle, "Bold")) //$NON-NLS-1$ - ? Styles.FONT_WEIGHT_BOLD : null); - registerStyle(styleOwner, Styles.FontStyle, - Boolean.parseBoolean(att(fontEle, "Italic")) //$NON-NLS-1$ - ? Styles.FONT_STYLE_ITALIC : null); - String textDecoration = StyleUtils.toTextDecoration( - Boolean.parseBoolean(att(fontEle, "Underline")), Boolean //$NON-NLS-1$ - .parseBoolean(att(fontEle, "Strikethrough"))); //$NON-NLS-1$ - registerStyle(styleOwner, Styles.TextDecoration, textDecoration); - } - - private static String parseFontSize(String size) { - if (size != null) { - try { - double value = Double.parseDouble(size); - size = StyleUtils.addUnitPoint((int) value); - } catch (Throwable e) { - } - } - return size; - } - - private void loadColor(Element parentEle, IStyled host, boolean transparent) - throws InterruptedException { - checkInterrupted(); - Element colorEle = child(parentEle, "ap:Color"); //$NON-NLS-1$ - if (colorEle != null) { - String fillColor = att(colorEle, "FillColor"); //$NON-NLS-1$ - String opacity = parseAlpha(fillColor); - if (opacity != null && !opacity.equals(TRANSPARENT_VALUE)) - registerStyle(host, Styles.FillColor, parseColor(fillColor)); - if (transparent) { - registerStyle(host, Styles.Opacity, opacity); - } - - String lineColor = att(colorEle, "LineColor"); //$NON-NLS-1$ - registerStyle(host, Styles.LineColor, parseColor(lineColor)); - } - } - - private IStyleSheet getTempStyleSheet() { - if (tempStyleSheet == null) { - tempStyleSheet = Core.getStyleSheetBuilder().createStyleSheet(); - ((StyleSheetImpl) tempStyleSheet) - .setManifest(getTargetWorkbook().getManifest()); - } - return tempStyleSheet; - } - - private void registerStyle(IStyled styleOwner, String key, String value) { - if (value == null) - return; - - IStyle style = styleMap.get(styleOwner); - if (style == null) { - style = getTempStyleSheet().createStyle(styleOwner.getStyleType()); - getTempStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); - styleMap.put(styleOwner, style); - } - if (Styles.TextDecoration.equals(key)) { - String oldValue = style.getProperty(key); - if (oldValue != null && !oldValue.contains(value)) { - boolean underline = oldValue - .contains(Styles.TEXT_DECORATION_UNDERLINE) - || value.contains(Styles.TEXT_DECORATION_UNDERLINE); - boolean strikeout = oldValue - .contains(Styles.TEXT_DECORATION_LINE_THROUGH) - || value.contains(Styles.TEXT_DECORATION_LINE_THROUGH); - value = StyleUtils.toTextDecoration(underline, strikeout); - } - } - style.setProperty(key, value); - } - - private static String parseAlpha(String mmColor) { - if (mmColor != null) { - try { - int alpha = Integer.parseInt(mmColor.substring(0, 1), 16); - double opacity = ((double) alpha) * 100 / 255; - return String.format("%.2f", opacity); //$NON-NLS-1$ - } catch (Throwable t) { - } - } - return null; - } - - private static String parseColor(String mmColor) { - if (mmColor != null) { - int r; - int g; - int b; - try { - r = Integer.parseInt(mmColor.substring(2, 4), 16); - g = Integer.parseInt(mmColor.substring(4, 6), 16); - b = Integer.parseInt(mmColor.substring(6, 8), 16); - return ColorUtils.toString(r, g, b); - } catch (Throwable t) { - } - } - return null; - } - - private void loadOId(Element mmEle, IIdentifiable element) { - String OId = att(mmEle, "OId"); //$NON-NLS-1$ - if (OId != null) { - idMap.put(OId, element.getId()); - } - } - - private void recordTopicLink(String OId, ITopic sourceTopic) { - List topics = topicLinkMap.get(OId); - if (topics == null) { - topics = new ArrayList(); - topicLinkMap.put(OId, topics); - } - topics.add(sourceTopic); - } - - private void setTopicLinks() { - for (Entry> en : topicLinkMap.entrySet()) { - String id = idMap.get(en.getKey()); - if (id != null) { - for (ITopic topic : en.getValue()) { - topic.setHyperlink(HyperlinkUtils.toInternalURL(id)); - } - } - } - } - - private static Element child(Element parentEle, String childTag) { - return children(parentEle, childTag).next(); - } - - private static Iterator children(final Element parentEle, - final String childTag) { - return new Iterator() { - - String tag = DOMUtils.getLocalName(childTag); - - Iterator it = DOMUtils.childElementIter(parentEle); - - Element next = findNext(); - - public void remove() { - } - - private Element findNext() { - while (it.hasNext()) { - Element ele = it.next(); - if (DOMUtils.getLocalName(ele.getTagName()) - .equalsIgnoreCase(tag)) { - return ele; - } - } - return null; - } - - public Element next() { - Element result = next; - next = findNext(); - return result; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - private static String att(Element ele, String attName) { - if (ele.hasAttribute(attName)) - return ele.getAttribute(attName); - - attName = DOMUtils.getLocalName(attName); - NamedNodeMap atts = ele.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) { - Node att = atts.item(i); - if (attName.equalsIgnoreCase( - DOMUtils.getLocalName(att.getNodeName()))) { - return att.getNodeValue(); - } - } - return null; - } - - private static int mm2Dots(float mm) { - return (int) (mm * DPM); - } - - private static String getMapping(String type, String sourceId, - String defaultId) { - if (sourceId != null) { - String destination = getMappings().getDestination(type, sourceId); - if (destination != null) - return destination; - } - return defaultId; - } - - private static ResourceMappingManager getMappings() { - if (mappings == null) { - mappings = createMappings(); - } - return mappings; - } - - private static ResourceMappingManager createMappings() { - return MMResourceMappingManager.getInstance(); - } - - private static DocumentBuilder getDocumentBuilder() - throws ParserConfigurationException { - return DOMUtils.getDefaultDocumentBuilder(); - } - - public void error(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void fatalError(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void warning(SAXParseException exception) throws SAXException { - log(exception, null); - } - -} +/* + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed + * under the Eclipse Public License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: XMind Ltd. - initial API and implementation + */ +package org.xmind.ui.internal.imports.mm; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.osgi.util.NLS; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IBoundary; +import org.xmind.core.IFileEntry; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IIdentifiable; +import org.xmind.core.IImage; +import org.xmind.core.IImageSpan; +import org.xmind.core.ILegend; +import org.xmind.core.INotes; +import org.xmind.core.INumbering; +import org.xmind.core.IParagraph; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISpan; +import org.xmind.core.ISummary; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.ITopicRange; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.NumberUtils; +import org.xmind.core.internal.dom.StyleSheetImpl; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; +import org.xmind.core.io.ResourceMappingManager; +import org.xmind.core.io.mindmanager.MMConstants; +import org.xmind.core.io.mindmanager.MMResourceMappingManager; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.imports.ImporterUtils; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.io.MonitoredInputStream; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.wizards.MindMapImporter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class MindManagerImporter extends MindMapImporter + implements MMConstants, ErrorHandler { + + private static final Pattern DATE_PATTERN = Pattern.compile( + "((\\d+)-(\\d{1,2})-(\\d{1,2}))T((\\d{1,2}):(\\d{1,2}):(\\d{1,2}))"); //$NON-NLS-1$ + + private static final String TRANSPARENT_VALUE = "0.00"; //$NON-NLS-1$ + + private static Pattern OID_PATTERN = null; + + private class NotesImporter { + + IParagraph currentParagraph = null; +// IBaseParagraph currentParagraph = null; + + Stack styleStack = new Stack(); + + IHtmlNotesContent content; + + public NotesImporter(IHtmlNotesContent content) { + this.content = content; + } + + public void loadFrom(Element notesGroupEle, Element element) + throws InterruptedException { + checkInterrupted(); + String tagName = DOMUtils.getLocalName(element.getTagName()); + + if ("br".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ + addParagraph(); + return; + } + + boolean isParagraph = "p".equalsIgnoreCase(tagName) //$NON-NLS-1$ + || "li".equalsIgnoreCase(tagName); //$NON-NLS-1$ + IStyle style = pushStyle(element, + isParagraph ? IStyle.PARAGRAPH : IStyle.TEXT); + + if (isParagraph) { + addParagraph(); + } else if ("img".equalsIgnoreCase(tagName)) { //$NON-NLS-1$ + + addImage(notesGroupEle, element); + + } + + NodeList nl = element.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + short nodeType = node.getNodeType(); + if (nodeType == Node.TEXT_NODE) { + addText(node.getTextContent()); + } else if (nodeType == Node.ELEMENT_NODE) { + loadFrom(notesGroupEle, (Element) node); + } + } + + popStyle(style); + } + + private void addText(String text) { + if (text == null) + return; + text = text.trim(); + if ("".equals(text)) //$NON-NLS-1$ + return; + + addSpan(content.createTextSpan(text)); + } + + private void addImage(Element notesGroupEle, Element imgEle) + throws InterruptedException { + Iterator it = children(notesGroupEle, "ap:NotesData"); //$NON-NLS-1$ + while (it.hasNext()) { + Element notesDataEle = it.next(); + String imgUri = att(notesDataEle, "ImageUri"); //$NON-NLS-1$ + String sourceImg = att(imgEle, "src"); //$NON-NLS-1$ + if (imgUri != null && sourceImg != null + && imgUri.equals(sourceImg)) { + loadImageAtt(imgUri, loadUri(notesDataEle)); + String srcUrl = loadUri(notesDataEle); + if (srcUrl != null) { + String entryPath = idMap.get(srcUrl); + if (entryPath != null) { + addSpan(content.createImageSpan(HyperlinkUtils + .toAttachmentPath(entryPath))); + } + } + } + } + + } + + private void addSpan(ISpan span) { + if (currentParagraph == null) + addParagraph(); + + currentParagraph.addSpan(span); + + if (!(span instanceof IImageSpan)) { + registerStyle(span, Styles.FontFamily, Styles.FontSize, + Styles.TextColor, Styles.FontWeight, + Styles.TextDecoration, Styles.FontStyle); + } + } + + private void addParagraph() { + currentParagraph = content.createParagraph(); +// currentParagraph = content +// .createParagraph(IBaseParagraph.GENERAL_PARAGRAPH); + content.addParagraph(currentParagraph); + registerStyle(currentParagraph, Styles.TextAlign); + } + + private void registerStyle(IStyled host, String... keys) { + for (IStyle style : styleStack) { + registerStyle(host, style, keys); + } + } + + private void registerStyle(IStyled host, IStyle style, String... keys) { + for (String key : keys) { + String value = style.getProperty(key); + if (value != null) { + MindManagerImporter.this.registerStyle(host, key, value); + } + } + } + + private IStyle pushStyle(Element ele, String type) { + IStyle style = getTempStyleSheet().createStyle(type); + receiveStyle(ele, style); + if (style.isEmpty()) { + style = null; + } else { + styleStack.push(style); + } + return style; + } + + private void receiveStyle(Element ele, IStyle style) { + String align = parseAlign(att(ele, "align")); //$NON-NLS-1$ + if (align != null) { + style.setProperty(Styles.TextAlign, align); + } + + String name = ele.getTagName(); + if ("b".equalsIgnoreCase(name)) { //$NON-NLS-1$ + style.setProperty(Styles.FontWeight, Styles.FONT_WEIGHT_BOLD); + } else if ("i".equalsIgnoreCase(name)) { //$NON-NLS-1$ + style.setProperty(Styles.FontStyle, Styles.FONT_STYLE_ITALIC); + } else if ("u".equalsIgnoreCase(name)) { //$NON-NLS-1$ + style.setProperty(Styles.TextDecoration, + Styles.TEXT_DECORATION_UNDERLINE); + } else if ("s".equalsIgnoreCase(name)) { //$NON-NLS-1$ + style.setProperty(Styles.TextDecoration, + Styles.TEXT_DECORATION_LINE_THROUGH); + } else if ("font".equalsIgnoreCase(name)) { //$NON-NLS-1$ + String fontName = att(ele, "face"); //$NON-NLS-1$ + String availableFontName = FontUtils + .getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName + : fontName; + if (fontName != null) { + style.setProperty(Styles.FontFamily, fontName); + } + } else if ("span".equalsIgnoreCase(name)) { //$NON-NLS-1$ + if ("font".equalsIgnoreCase( //$NON-NLS-1$ + ((Element) ele.getParentNode()).getTagName())) { + String color = att((Element) ele.getParentNode(), "color"); //$NON-NLS-1$ + style.setProperty(Styles.TextColor, color); + } + } + + String styleContent = att(ele, "style"); //$NON-NLS-1$ + if (styleContent != null) { + receiveStyleContent(style, styleContent); + } + + } + + private String parseAlign(String align) { + if (align != null) { + if (Styles.ALIGN_CENTER.equalsIgnoreCase(align) // + || Styles.ALIGN_LEFT.equalsIgnoreCase(align) // + || Styles.ALIGN_RIGHT.equalsIgnoreCase(align)) + return align; + } + return null; + } + + private void receiveStyleContent(IStyle style, String styleContent) { + String[] items = styleContent.trim().split(";"); //$NON-NLS-1$ + for (String item : items) { + item = item.trim(); + int colonIndex = item.indexOf(':'); + if (colonIndex > 0) { + String key = item.substring(0, colonIndex).trim(); + String value = item.substring(colonIndex + 1).trim(); + receiveStyleItem(style, key, value); + } + } + } + + private void receiveStyleItem(IStyle style, String key, String value) { + if ("color".equalsIgnoreCase(key)) { //$NON-NLS-1$ + String color = parseColor(value); + if (color != null) { + style.setProperty(Styles.TextColor, color); + } + } else if ("font-size".equalsIgnoreCase(key)) { //$NON-NLS-1$ + int fontSize = NumberUtils.safeParseInt(value, -1); + if (fontSize > 0) { + style.setProperty(Styles.FontSize, + StyleUtils.addUnitPoint(fontSize)); + } + } + } + + private void popStyle(IStyle style) { + if (style == null) + return; + + if (styleStack != null && styleStack.peek() == style) { + styleStack.pop(); + } + } + + private String parseColor(String color) { + return color; +// if (color != null) { +// return ColorUtils.toString(ColorUtils.toRGB(color)); +// } +// return null; + } + + } + + private static final String DOCUMENT_XML = "Document.xml"; //$NON-NLS-1$ + + private static final double DPM = 72 / 25.4; + + private static ResourceMappingManager mappings = null; + +// private ZipFile sourceFile; + private IStorage tempStorage; + + private IInputSource tempSource; + + private ISheet targetSheet; + + private Map idMap = new HashMap(30); + + private IStyleSheet tempStyleSheet = null; + + private Map styleMap = new HashMap(30); + + private IStyle theme = null; + + private Map> topicLinkMap = new HashMap>( + 10); + + public MindManagerImporter(String sourcePath) { + super(sourcePath); + } + + public MindManagerImporter(String sourcePath, IWorkbook targetWorkbook) { + super(sourcePath, targetWorkbook); + } + + public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.IMPORT_FROM_MIND_MANAGER_COUNT); + getMonitor().beginTask(null, 100); + try { + getMonitor() + .subTask(ImportMessages.MindManagerImporter_ReadingContent); + + tempStorage = createTemporaryStorage(); + extractSourceFileToTemporaryStorage(); + tempSource = tempStorage.getInputSource(); +// sourceFile = new ZipFile(getSourcePath()); +// ZipEntry docEntry = sourceFile.getEntry(DOCUMENT_XML); + + Document doc = readContents(); + + getMonitor().worked(45); + checkInterrupted(); + + getMonitor().subTask( + ImportMessages.MindManagerImporter_ReadingElements); + loadSheet(doc.getDocumentElement()); + setTopicLinks(); + getMonitor().worked(45); + + checkInterrupted(); + getMonitor().subTask( + ImportMessages.MindManagerImporter_ArrangingStyles); + arrangeStyles(); + getMonitor().worked(5); + + checkInterrupted(); + getMonitor().subTask( + ImportMessages.MindManagerImporter_GeneratingTheme); + generateTheme(); + getMonitor().worked(5); + getMonitor().done(); + } catch (Exception e) { + throw new InvocationTargetException(e); + } finally { + clearTempStorage(); + } + postBuilded(); + } + + private Document readContents() throws Exception { + InputStream docEntryStream = tempSource.getEntryStream(DOCUMENT_XML); + if (docEntryStream == null) + throw new IOException("No content entry"); //$NON-NLS-1$ + + DocumentBuilder builder = getDocumentBuilder(); + builder.setErrorHandler(this); +// InputStream in = sourceFile.getInputStream(docEntryStream); +// in = new MonitoredInputStream(in, getMonitor()); + InputStream in = new MonitoredInputStream(docEntryStream, getMonitor()); + Document doc; + try { + doc = builder.parse(in); + } finally { + builder.setErrorHandler(null); + try { + in.close(); + } catch (Exception e) { + } + } + return doc; + } + + /** + * @return + */ + private IStorage createTemporaryStorage() throws IOException { + String id = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", //$NON-NLS-1$ + System.currentTimeMillis()); + File tempDir = FileUtils.ensureDirectory(new File( + Core.getWorkspace().getTempDir("import/mindmanager"), id)); //$NON-NLS-1$ + return new DirectoryStorage(tempDir); + } + + private void extractSourceFileToTemporaryStorage() + throws IOException, CoreException { + FileInputStream fin = new FileInputStream(getSourcePath()); + try { + ZipInputStream zin = new ZipInputStream(new MonitoredInputStream( + new BufferedInputStream(fin), getMonitor())); + try { + FileUtils.extractZipFile(zin, tempStorage.getOutputTarget()); + } finally { + zin.close(); + } + } finally { + fin.close(); + } + + } + + private void checkInterrupted() throws InterruptedException { + if (getMonitor().isCanceled()) + throw new InterruptedException(); + } + + private void clearTempStorage() { + if (tempStorage != null) { + tempStorage.clear(); + tempStorage = null; + } +// if (sourceFile != null) { +// try { +// sourceFile.close(); +// } catch (IOException e) { +// } +// } +// sourceFile = null; + } + + private void loadSheet(Element docEle) throws InterruptedException { + checkInterrupted(); + + targetSheet = getTargetWorkbook().createSheet(); + + Element oneTopicEle = child(docEle, "OneTopic"); //$NON-NLS-1$ + if (oneTopicEle != null) { + loadRootTopic(oneTopicEle); + } + + Element relsEle = child(docEle, "Relationships"); //$NON-NLS-1$ + if (relsEle != null) { + loadRelationships(relsEle); + } + + Element styleGroupEle = child(docEle, "StyleGroup"); //$NON-NLS-1$ + if (styleGroupEle != null) { + loadStyleGroup(styleGroupEle); + } + + Element markersGroupEle = child(docEle, "MarkersSetGroup"); //$NON-NLS-1$ + if (markersGroupEle != null) { + loadMarkersGroup(markersGroupEle); + } + + addTargetSheet(targetSheet); + } + + public ISheet getTargetSheet() { + return targetSheet; + } + + private void arrangeStyles() throws InterruptedException { + IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); + for (Entry en : styleMap.entrySet()) { + checkInterrupted(); + IStyled styleOwner = en.getKey(); + IStyle style = en.getValue(); + IStyle importedStyle = targetStyleSheet.importStyle(style); + if (importedStyle != null) { + styleOwner.setStyleId(importedStyle.getId()); + } + } + } + + private void loadMarkersGroup(Element markersGroupEle) + throws InterruptedException { + checkInterrupted(); + ILegend legend = getTargetSheet().getLegend(); + Element markersSetsEle = child(markersGroupEle, "ap:IconMarkersSets"); //$NON-NLS-1$ + if (markersSetsEle != null) { + Iterator it = children(markersSetsEle, + "ap:IconMarkersSet"); //$NON-NLS-1$ + while (it.hasNext()) { + checkInterrupted(); + Element markersSetEle = it.next(); + loadLegendMarkers(markersSetEle, legend, "ap:IconMarkers", //$NON-NLS-1$ + "ap:IconMarker", //$NON-NLS-1$ + "ap:OneStockIcon", //$NON-NLS-1$ + "IconType"); //$NON-NLS-1$ + } + } + + loadLegendMarkers(markersGroupEle, legend, "ap:IconMarkers", //$NON-NLS-1$ + "ap:IconMarker", //$NON-NLS-1$ + "ap:OneStockIcon", //$NON-NLS-1$ + "IconType"); //$NON-NLS-1$ + loadLegendMarkers(markersGroupEle, legend, "ap:TaskPercentageMarkers", //$NON-NLS-1$ + "ap:TaskPercentageMarker", //$NON-NLS-1$ + "ap:TaskPercentage", //$NON-NLS-1$ + "TaskPercentage"); //$NON-NLS-1$ + loadLegendMarkers(markersGroupEle, legend, "ap:TaskPriorityMarkers", //$NON-NLS-1$ + "ap:TaskPriorityMarker", //$NON-NLS-1$ + "ap:TaskPriority", //$NON-NLS-1$ + "TaskPriority" //$NON-NLS-1$ + ); + } + + private void loadLegendMarkers(Element markersSetEle, ILegend legend, + String markersEleName, String markerEleName, String iconEleName, + String iconAttrName) throws InterruptedException { + checkInterrupted(); + Element markersEle = child(markersSetEle, markersEleName); + if (markersEle != null) + loadLegendMarkers(markersEle, legend, markerEleName, iconEleName, + iconAttrName); + } + + private void loadLegendMarkers(Element markersEle, ILegend legend, + String markerEleName, String iconEleName, String iconAttrName) + throws InterruptedException { + checkInterrupted(); + Iterator it = children(markersEle, markerEleName); + while (it.hasNext()) { + checkInterrupted(); + Element markerEle = it.next(); + Element iconEle = child(markerEle, iconEleName); + if (iconEle != null) { + String type = att(iconEle, iconAttrName); + if (type != null) { + String markerId = getMapping("marker", type, null); //$NON-NLS-1$ + if (markerId != null) { + String name = loadName(markerEle); + legend.setMarkerDescription(markerId, name); + } + } + } + } + } + + private static String loadName(Element parentEle) { + return loadName(parentEle, null); + } + + private static String loadName(Element parentEle, String eleName) { + if (eleName == null) + eleName = "ap:Name"; //$NON-NLS-1$ + Element ele = child(parentEle, eleName); + if (ele != null) { + return att(ele, "Name"); //$NON-NLS-1$ + } + return null; + } + + private void loadStyleGroup(Element styleGroupEle) + throws InterruptedException { + checkInterrupted(); + loadTopicTheme(styleGroupEle); + loadRelTheme(styleGroupEle); + loadBoundaryTheme(styleGroupEle); + loadSheetStyle(styleGroupEle); + } + + private void loadSheetStyle(Element styleGroupEle) + throws InterruptedException { + checkInterrupted(); + ISheet sheet = getTargetSheet(); + Element structureEle = child(styleGroupEle, "ap:Structure"); //$NON-NLS-1$ + if (structureEle != null) { + Float lineWidth = parseFloat( + att(structureEle, "MainTopicLineWidth")); //$NON-NLS-1$ + if (lineWidth != null && lineWidth.floatValue() > 3.0f) { + registerStyle(sheet, Styles.LineTapered, Styles.TAPERED); + } + } + + Element bgFillEle = child(styleGroupEle, "ap:BackgroundFill"); //$NON-NLS-1$ + if (bgFillEle != null) { + String fillColor = parseColor(att(bgFillEle, "FillColor")); //$NON-NLS-1$ + if (fillColor != null) { + registerStyle(sheet, Styles.FillColor, fillColor); + } + } + + Element bgImgEle = child(styleGroupEle, "ap:BackgroundImageData"); //$NON-NLS-1$ + if (bgImgEle != null) { + String uri = loadUri(bgImgEle); + if (uri != null) { + IFileEntry entry = loadAttachment(null, uri, "*.png"); //$NON-NLS-1$ + if (entry != null && entry.getSize() > 0) { + registerStyle(sheet, Styles.Background, + HyperlinkUtils.toAttachmentURL(entry.getPath())); + int transparency = NumberUtils + .safeParseInt(att(bgImgEle, "Transparency"), -1); //$NON-NLS-1$ + if (transparency >= 0) { + double opacity = (100 - transparency) * 1.0 / 100; + registerStyle(sheet, Styles.Opacity, + String.format("%.2f", opacity)); //$NON-NLS-1$ + } + } + } + } + } + + private void loadBoundaryTheme(Element styleGroupEle) + throws InterruptedException { + checkInterrupted(); + Element parentEle = child(styleGroupEle, "ap:BoundaryDefaultsGroup"); //$NON-NLS-1$ + if (parentEle == null) + return; + + loadThemeColor(parentEle, true, true, true, IStyle.BOUNDARY, + Styles.FAMILY_BOUNDARY); + loadThemeLineStyle(parentEle, IStyle.BOUNDARY, Styles.FAMILY_BOUNDARY); + loadThemeBoundaryShape(parentEle, Styles.FAMILY_BOUNDARY); + } + + private void loadThemeBoundaryShape(Element parentEle, String styleFamily) + throws InterruptedException { + checkInterrupted(); + Element ele = child(parentEle, "ap:DefaultBoundaryShape"); //$NON-NLS-1$ + if (ele == null) + return; + + String shape = parseBoundaryShape(att(ele, "BoundaryShape")); //$NON-NLS-1$ + registerTheme(IStyle.BOUNDARY, styleFamily, Styles.ShapeClass, shape); + } + + private void loadThemeLineStyle(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + Element ele = child(parentEle, "ap:DefaultLineStyle"); //$NON-NLS-1$ + if (ele == null) + return; + + String linePattern = parseLinePattern(att(ele, "LineDashStyle")); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.LinePattern, linePattern); + + String lineWidth = parseLineWidth(att(ele, "LineWidth")); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.LineWidth, lineWidth); + } + + private void loadRelTheme(Element styleGroupEle) + throws InterruptedException { + checkInterrupted(); + Element parentEle = child(styleGroupEle, + "ap:RelationshipDefaultsGroup"); //$NON-NLS-1$ + if (parentEle == null) + return; + + loadThemeColor(parentEle, false, false, true, IStyle.RELATIONSHIP, + Styles.FAMILY_RELATIONSHIP); + loadThemeLineStyle(parentEle, IStyle.RELATIONSHIP, + Styles.FAMILY_RELATIONSHIP); + loadThemeArrowStyle(parentEle, Styles.FAMILY_RELATIONSHIP); + loadThemeRelShape(parentEle, Styles.FAMILY_RELATIONSHIP); + } + + private void loadThemeRelShape(Element parentEle, String styleFamily) + throws InterruptedException { + checkInterrupted(); + Element relShapeEle = child(parentEle, + "ap:DefaultRelationshipLineShape"); //$NON-NLS-1$ + if (relShapeEle == null) + return; + + String shape = parseRelationshipShape(att(relShapeEle, "LineShape")); //$NON-NLS-1$ + registerTheme(IStyle.RELATIONSHIP, styleFamily, Styles.ShapeClass, + shape); + } + + private void loadThemeArrowStyle(Element parentEle, String styleFamily) + throws InterruptedException { + checkInterrupted(); + Iterator it = children(parentEle, "ap:DefaultConnectionStyle"); //$NON-NLS-1$ + while (it.hasNext()) { + checkInterrupted(); + Element ele = it.next(); + int index = NumberUtils.safeParseInt(att(ele, "Index"), -1); //$NON-NLS-1$ + if (index == 0 || index == 1) { + String shape = parseConnShape(att(ele, "ConnectionShape")); //$NON-NLS-1$ + if (shape != null) { + String styleKey = index == 0 ? Styles.ArrowBeginClass + : Styles.ArrowEndClass; + registerTheme(IStyle.RELATIONSHIP, styleFamily, styleKey, + shape); + } + } + } + } + + private void loadThemeColor(Element parentEle, boolean fill, + boolean fillAlpha, boolean line, String type, String styleFamily) + throws InterruptedException { + checkInterrupted(); + Element colorEle = child(parentEle, "ap:DefaultColor"); //$NON-NLS-1$ + if (colorEle == null) + return; + + if (fill || fillAlpha) { + String fillColor = att(colorEle, "FillColor"); //$NON-NLS-1$ + if (fill) { + registerTheme(type, styleFamily, Styles.FillColor, + parseColor(fillColor)); + } + if (fillAlpha) { + registerTheme(type, styleFamily, Styles.Opacity, + parseAlpha(fillColor)); + } + } + + if (line) { + String lineColor = att(colorEle, "LineColor"); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.LineColor, + parseColor(lineColor)); + } + } + + private void loadTopicTheme(Element styleGroupEle) + throws InterruptedException { + checkInterrupted(); + Element rootEle = child(styleGroupEle, "ap:RootTopicDefaultsGroup"); //$NON-NLS-1$ + if (rootEle != null) { + loadTopicTheme(rootEle, null, null, Styles.FAMILY_CENTRAL_TOPIC); + } + + int deepestLevel = 0; + Element realSubEle = null; + Iterator it = children(rootEle, + "ap:RootSubTopicDefaultsGroup"); //$NON-NLS-1$ + while (it.hasNext()) { + Element subEle = it.next(); + int level = NumberUtils.safeParseInt(att(subEle, "Level"), -1); //$NON-NLS-1$ + if (level == 0) { + loadTopicTheme(subEle, null, null, Styles.FAMILY_MAIN_TOPIC); + } else if (level > 0) { + if (level > deepestLevel) { + deepestLevel = level; + realSubEle = subEle; + } + } + } + + if (realSubEle != null) { + loadTopicTheme(realSubEle, null, null, Styles.FAMILY_SUB_TOPIC); + } + + Element floatingEle = child(styleGroupEle, + "ap:LabelTopicDefaultsGroup"); //$NON-NLS-1$ + if (floatingEle != null) { + loadTopicTheme(floatingEle, "ap:DefaultLabelFloatingTopicShape", //$NON-NLS-1$ + "LabelFloatingTopicShape", Styles.FAMILY_FLOATING_TOPIC); //$NON-NLS-1$ + } + } + + private void loadTopicTheme(Element parentEle, String shapeEleName, + String shapeAttrName, String styleFamily) + throws InterruptedException { + checkInterrupted(); + loadThemeColor(parentEle, true, false, true, IStyle.TOPIC, styleFamily); + loadThemeTextStyle(parentEle, styleFamily); + loadThemeTopicShape(parentEle, shapeEleName, shapeAttrName, + styleFamily); + loadThemeBranchStyle(parentEle, styleFamily); + } + + private void loadThemeBranchStyle(Element parentEle, String styleFamily) + throws InterruptedException { + checkInterrupted(); + Element ele = child(parentEle, "ap:DefaultSubTopicsShape"); //$NON-NLS-1$ + if (ele == null) + return; + + String branchConn = parseBranchConn( + att(ele, "SubTopicsConnectionStyle")); //$NON-NLS-1$ + registerTheme(IStyle.TOPIC, styleFamily, Styles.LineClass, branchConn); + } + + private static String parseBranchConn(String connStyle) { + return getMapping("branchConnection", connStyle, null); //$NON-NLS-1$ + } + + private void loadThemeTopicShape(Element parentEle, String shapeEleName, + String shapeAttrName, String styleFamily) + throws InterruptedException { + checkInterrupted(); + if (shapeEleName == null) + shapeEleName = "ap:DefaultSubTopicShape"; //$NON-NLS-1$ + Element shapeEle = child(parentEle, shapeEleName); + if (shapeEle == null) + return; + + if (shapeAttrName == null) + shapeAttrName = "SubTopicShape"; //$NON-NLS-1$ + String shape = parseTopicShape(att(shapeEle, shapeAttrName)); + registerTheme(IStyle.TOPIC, styleFamily, Styles.ShapeClass, shape); + } + + private void loadThemeTextStyle(Element parentEle, String themeKey) + throws InterruptedException { + checkInterrupted(); + Element textEle = child(parentEle, "ap:Text"); //$NON-NLS-1$ + if (textEle == null) + return; + + loadThemeFont(textEle, IStyle.TOPIC, themeKey); + } + + private void loadThemeFont(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + Element fontEle = child(parentEle, "ap:Font"); //$NON-NLS-1$ + if (fontEle == null) + return; + + String color = parseColor(att(fontEle, "Color")); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.TextColor, color); + + String fontName = att(fontEle, "Name"); //$NON-NLS-1$ + String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName : fontName; + registerTheme(type, styleFamily, Styles.FontFamily, fontName); + + String size = att(fontEle, "Size"); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.FontSize, size); + + String bold = att(fontEle, "Bold"); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.FontWeight, + Boolean.parseBoolean(bold) ? Styles.FONT_WEIGHT_BOLD : null); + + String italic = att(fontEle, "Italic"); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.FontStyle, + Boolean.parseBoolean(italic) ? Styles.FONT_STYLE_ITALIC : null); + + boolean underline = Boolean.parseBoolean(att(fontEle, "Underline")); //$NON-NLS-1$ + boolean strikeout = Boolean.parseBoolean(att(fontEle, "Strikethrough")); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.TextDecoration, + StyleUtils.toTextDecoration(underline, strikeout)); + } + + private void registerTheme(String type, String styleFamily, String styleKey, + String styleValue) throws InterruptedException { + checkInterrupted(); + if (styleFamily == null || styleKey == null || styleValue == null) + return; + + if (theme == null) { + theme = getTempStyleSheet().createStyle(IStyle.THEME); + getTempStyleSheet().addStyle(theme, IStyleSheet.MASTER_STYLES); + } + + IStyle defaultStyle = theme.getDefaultStyle(styleFamily); + if (defaultStyle == null) { + defaultStyle = getTempStyleSheet().createStyle(type); + getTempStyleSheet().addStyle(defaultStyle, + IStyleSheet.AUTOMATIC_STYLES); + } + defaultStyle.setProperty(styleKey, styleValue); + } + + private void generateTheme() throws InterruptedException { + checkInterrupted(); + if (theme != null) { + IStyle importedTheme = getTargetWorkbook().getStyleSheet() + .importStyle(theme); + if (importedTheme != null) { + getTargetSheet().setThemeId(importedTheme.getId()); + } + } + } + + private void loadRelationships(Element relsEle) + throws InterruptedException { + checkInterrupted(); + Iterator it = children(relsEle, "ap:Relationship"); //$NON-NLS-1$ + while (it.hasNext()) { + Element relEle = it.next(); + loadRelationship(relEle); + } + } + + private void loadRelationship(Element relEle) throws InterruptedException { + checkInterrupted(); + IRelationship rel = getTargetWorkbook().createRelationship(); + getTargetSheet().addRelationship(rel); + loadOId(relEle, rel); + boolean autoRouting = loadAutoRouting(relEle); + loadConnections(relEle, rel, autoRouting); + loadLineStyle(relEle, rel); + loadRelLineShape(relEle, rel); + } + + private void loadRelLineShape(Element relEle, IRelationship rel) + throws InterruptedException { + checkInterrupted(); + Element relShapeEle = child(relEle, "ap:RelationshipLineShape"); //$NON-NLS-1$ + if (relShapeEle == null) + return; + String shape = parseRelationshipShape(att(relShapeEle, "LineShape")); //$NON-NLS-1$ + registerStyle(rel, Styles.ShapeClass, shape); + } + + private static String parseRelationshipShape(String shape) { + return getMapping("relationshipShape", shape, null); //$NON-NLS-1$ + } + + private void loadConnections(Element relEle, IRelationship rel, + boolean autoRouting) throws InterruptedException { + checkInterrupted(); + Iterator it = children(relEle, "ap:ConnectionGroup"); //$NON-NLS-1$ + while (it.hasNext()) { + Element connGroupEle = it.next(); + loadRelConnection(connGroupEle, rel, autoRouting); + } + } + + private void loadRelConnection(Element connGroupEle, IRelationship rel, + boolean autoRouting) throws InterruptedException { + checkInterrupted(); + int index = NumberUtils.safeParseInt(att(connGroupEle, "Index"), -1); //$NON-NLS-1$ + if (index != 0 && index != 1) + return; + + Element connEle = child(connGroupEle, "ap:Connection"); //$NON-NLS-1$ + if (connEle == null) + return; + + Element refEle = child(connEle, "ap:ObjectReference"); //$NON-NLS-1$ + if (refEle == null) + return; + + String oIdRef = att(refEle, "OIdRef"); //$NON-NLS-1$ + String endId = idMap.get(oIdRef); + if (endId == null) + return; + + if (index == 0) { + rel.setEnd1Id(endId); + } else { + rel.setEnd2Id(endId); + } + + if (!autoRouting || connEle != null) { + String cx = att(connEle, "CX"); //$NON-NLS-1$ + String cy = att(connEle, "CY"); //$NON-NLS-1$ + if (cx != null && cy != null) { + Float x = parseFloat(cx); + Float y = parseFloat(cy); + if (x != null && y != null) { + rel.getControlPoint(index).setPosition( + mm2Dots(x.floatValue()), mm2Dots(y.floatValue())); + } + } + } + + Element connStyleEle = child(connGroupEle, "ap:ConnectionStyle"); //$NON-NLS-1$ + if (connStyleEle != null) { + String arrowShape = parseConnShape( + att(connStyleEle, "ConnectionShape")); //$NON-NLS-1$ + String styleKey = index == 0 ? Styles.ArrowBeginClass + : Styles.ArrowEndClass; + registerStyle(rel, styleKey, arrowShape); + } + } + + private static String parseConnShape(String shape) { + return getMapping("arrowShape", shape, null); //$NON-NLS-1$ + } + + private boolean loadAutoRouting(Element relEle) + throws InterruptedException { + checkInterrupted(); + Element autoRouteEle = child(relEle, "ap:AutoRoute"); //$NON-NLS-1$ + if (autoRouteEle != null) { + return Boolean.parseBoolean(att(autoRouteEle, "AutoRouting")); //$NON-NLS-1$ + } + return false; + } + + private void loadRootTopic(Element oneTopicEle) + throws InterruptedException { + checkInterrupted(); + Element topicEle = child(oneTopicEle, "Topic"); //$NON-NLS-1$ + if (topicEle != null) { + loadTopicContent(topicEle, getTargetSheet().getRootTopic()); + } + } + + private void loadTopicContent(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + loadOId(topicEle, topic); + loadTitle(topicEle, topic); + loadColor(topicEle, topic, false); + loadPosition(topicEle, topic); + loadTopicViewGroup(topicEle, topic); + loadImage(topicEle, topic); + loadTopicShape(topicEle, topic); + loadHyperlink(topicEle, topic); + loadMarkers(topicEle, topic); + loadLabels(topicEle, topic); + loadNotes(topicEle, topic); + loadTask(topicEle, topic); + loadNumbering(topicEle, topic); + + loadSubTopics(topicEle, topic); + loadDetachedSubTopics(topicEle, topic); + loadBoundary(topicEle, topic); + loadStructure(topicEle, topic); + loadAttachments(topicEle, topic); + } + + private void loadAttachments(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element attGroupEle = child(topicEle, "ap:AttachmentGroup"); //$NON-NLS-1$ + if (attGroupEle == null) + return; + + Iterator it = children(attGroupEle, "ap:AttachmentData"); //$NON-NLS-1$ + while (it.hasNext()) { + Element attDataEle = it.next(); + String uri = loadUri(attDataEle); + if (uri != null) { + String oId = att(attDataEle, "AttachmentId"); //$NON-NLS-1$ + String name = att(attDataEle, "FileName"); //$NON-NLS-1$ + IFileEntry entry = loadAttachment(oId, uri, name); + if (entry != null) { + if (name == null) + name = new File(entry.getPath()).getName(); + ITopic attTopic = getTargetWorkbook().createTopic(); + attTopic.setTitleText(name); + attTopic.setHyperlink( + HyperlinkUtils.toAttachmentURL(entry.getPath())); + topic.add(attTopic, ITopic.ATTACHED); + } + } + } + } + + private void loadStructure(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element subTopicsShapeEle = child(topicEle, "ap:SubTopicsShape"); //$NON-NLS-1$ + if (subTopicsShapeEle == null) + return; + + String line = parseBranchConnection( + att(subTopicsShapeEle, "SubTopicsConnectionStyle")); //$NON-NLS-1$ + registerStyle(topic, Styles.LineClass, line); + + String structureClass = parseStructureType(subTopicsShapeEle); + topic.setStructureClass(structureClass); + } + + private static String parseStructureType(Element ele) { + String align = att(ele, "SubTopicsAlignment"); //$NON-NLS-1$ + String growth = att(ele, "SubTopicsGrowth"); //$NON-NLS-1$ + String growthDir = att(ele, "SubTopicsGrowthDirection"); //$NON-NLS-1$ + if (umCenter.equals(align) && umHorizontal.equals(growth)) { + if (umLeftAndRight.equals(growthDir)) + return "org.xmind.ui.map.clockwise"; //$NON-NLS-1$ + if (umRight.equals(growthDir)) + return "org.xmind.ui.logic.right"; //$NON-NLS-1$ + if (umLeft.equals(growthDir)) + return "org.xmind.ui.logic.left"; //$NON-NLS-1$ + } else if (umVertical.equals(growth) + && umMiddle.equals(att(ele, "SubTopicsVerticalAlignment"))) { //$NON-NLS-1$ + String vgd = att(ele, "SubTopicsVerticalGrowthDirection"); //$NON-NLS-1$ + if (umDown.equals(vgd) || umUpAndDown.equals(vgd)) + return "org.xmind.ui.org-chart.down"; //$NON-NLS-1$ + if (umUp.equals(vgd)) + return "org.xmind.ui.org-chart.up"; //$NON-NLS-1$ + } else if (umBottom.equals(align) && umHorizontal.equals(growth)) { + if (umRight.equals(growthDir) || umLeftAndRight.equals(growthDir)) + return "org.xmind.ui.tree.right"; //$NON-NLS-1$ + if (umLeft.equals(growthDir)) + return "org.xmind.ui.tree.left"; //$NON-NLS-1$ + } + return null; + } + + private static String parseBranchConnection(String lineShape) { + return getMapping("branchConnection", lineShape, null); //$NON-NLS-1$ + } + + private void loadBoundary(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + if (topic.isRoot()) + return; + + Element oneBoundaryEle = child(topicEle, "ap:OneBoundary"); //$NON-NLS-1$ + if (oneBoundaryEle == null) + return; + + Element boundaryEle = child(oneBoundaryEle, "ap:Boundary"); //$NON-NLS-1$ + if (boundaryEle == null) + return; + + checkInterrupted(); + String boundaryShape = getBoundaryShape(boundaryEle); + String shape = parseSummaryShape(boundaryShape); + ITopicRange range; + ITopic parent; + if (shape != null && topic.isAttached()) { + ISummary summary = getTargetWorkbook().createSummary(); + parent = topic.getParent(); + int index = topic.getIndex(); + summary.setStartIndex(index); + summary.setEndIndex(index); + parent.addSummary(summary); + range = summary; + } else { + shape = parseBoundaryShape(boundaryShape); + IBoundary boundary = getTargetWorkbook().createBoundary(); + if (topic.isAttached()) { + parent = topic.getParent(); + int index = topic.getIndex(); + boundary.setStartIndex(index); + boundary.setEndIndex(index); + parent.addBoundary(boundary); + } else { + parent = null; + boundary.setMasterBoundary(true); + topic.addBoundary(boundary); + } + range = boundary; + } + loadOId(boundaryEle, (IIdentifiable) range); + loadColor(boundaryEle, (IStyled) range, true); + loadLineStyle(boundaryEle, (IStyled) range); + registerStyle((IStyled) range, Styles.ShapeClass, shape); + + if (range instanceof ISummary && parent != null) { + ISummary summary = (ISummary) range; + ITopic summaryTopic = getTargetWorkbook().createTopic(); + parent.add(summaryTopic, ITopic.SUMMARY); + summary.setTopicId(summaryTopic.getId()); + + Element summaryTopicEle = getSummaryTopicEle(boundaryEle); + if (summaryTopicEle != null) { + loadTopicContent(summaryTopicEle, summaryTopic); + } else { + summaryTopic.setTitleText(" "); //$NON-NLS-1$ + registerStyle(summaryTopic, Styles.ShapeClass, + "org.xmind.topicShape.noBorder"); //$NON-NLS-1$ + } + } else if (range instanceof IBoundary) { + IBoundary boundary = (IBoundary) range; + Element boundaryTopicEle = getSummaryTopicEle(boundaryEle); + if (boundaryTopicEle != null) { + loadTitle(boundaryTopicEle, boundary); + } + } + } + + private Element getSummaryTopicEle(Element boundaryEle) { + Element oneSummaryTopicEle = child(boundaryEle, "ap:OneSummaryTopic"); //$NON-NLS-1$ + if (oneSummaryTopicEle != null) { + return child(oneSummaryTopicEle, "ap:Topic"); //$NON-NLS-1$ + } + return null; + } + + private String getBoundaryShape(Element boundaryEle) { + Element shapeEle = child(boundaryEle, "ap:BoundaryShape"); //$NON-NLS-1$ + if (shapeEle != null) { + return att(shapeEle, "BoundaryShape"); //$NON-NLS-1$ + } + return null; + } + + private static String parseBoundaryShape(String shape) { + return getMapping("boundaryShape", shape, null); //$NON-NLS-1$ + } + + private static String parseSummaryShape(String shape) { + return getMapping("summaryShape", shape, null); //$NON-NLS-1$ + } + + private void loadLineStyle(Element parentEle, IStyled host) + throws InterruptedException { + checkInterrupted(); + Element lineColor = child(parentEle, "ap:Color"); //$NON-NLS-1$ + if (lineColor != null) { + String color = att(lineColor, "LineColor");//$NON-NLS-1$ + if (color != null) { + registerStyle(host, Styles.LineColor, "#" + color.substring(2)); //$NON-NLS-1$ + } + } + + Element lineStyleEle = child(parentEle, "ap:LineStyle"); //$NON-NLS-1$ + if (lineStyleEle == null) + return; + + String linePattern = parseLinePattern( + att(lineStyleEle, "LineDashStyle")); //$NON-NLS-1$ + registerStyle(host, Styles.LinePattern, linePattern); + + String width = parseLineWidth(att(lineStyleEle, "LineWidth")); //$NON-NLS-1$ + registerStyle(host, Styles.LineWidth, width); + } + + private static String parseLineWidth(String width) { + Float w = parseFloat(width); + if (w != null) { + if (w <= 1.0) + return "1"; //$NON-NLS-1$ + if (w <= 2.25) + return "2"; //$NON-NLS-1$ + if (w <= 3.0) + return "3"; //$NON-NLS-1$ + if (w <= 4.5) + return "4"; //$NON-NLS-1$ + return "5"; //$NON-NLS-1$ + } + return null; + } + + private static String parseLinePattern(String dashStyle) { + return getMapping("lineStyle", dashStyle, null); //$NON-NLS-1$ + } + + private void loadDetachedSubTopics(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element subTopicsEle = child(topicEle, "ap:FloatingTopics"); //$NON-NLS-1$ + if (subTopicsEle != null) { + Iterator it = children(subTopicsEle, "ap:Topic"); //$NON-NLS-1$ + while (it.hasNext()) { + Element subTopicEle = it.next(); + ITopic subTopic = getTargetWorkbook().createTopic(); + Element item = child(subTopicEle, "ap:Offset"); //$NON-NLS-1$ + if (item != null && item.hasAttribute("OffsetPriority")) //$NON-NLS-1$ + topic.add(subTopic, ITopic.DETACHED); + else + topic.add(subTopic, ITopic.CALLOUT); + loadTopicContent(subTopicEle, subTopic); + } + } + } + + private void loadSubTopics(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element subTopicsEle = child(topicEle, "ap:SubTopics"); //$NON-NLS-1$ + if (subTopicsEle != null) { + Iterator it = children(subTopicsEle, "ap:Topic"); //$NON-NLS-1$ + while (it.hasNext()) { + Element subTopicEle = it.next(); + ITopic subTopic = getTargetWorkbook().createTopic(); + topic.add(subTopic, ITopic.ATTACHED); + loadTopicContent(subTopicEle, subTopic); + } + } + } + + private final static String NUMBER_FORMAT_NONE = "org.xmind.numbering.none"; //$NON-NLS-1$ + + private final static String NUMBER_FORMAT_ARABIC = "org.xmind.numbering.arabic"; //$NON-NLS-1$ + + private final static String NUMBER_FORMAT_ROMAN = "org.xmind.numbering.roman"; //$NON-NLS-1$ + + private final static String NUMBER_FORMAT_LOWERCASE = "org.xmind.numbering.lowercase"; //$NON-NLS-1$ + + private final static String NUMBER_FORMAT_UPPERCASE = "org.xmind.numbering.uppercase"; //$NON-NLS-1$ + + private Map numberingEles; + + private void loadNumbering(Element topicEle, ITopic topic) { + Element numberingEle = findNumberingEle(topicEle, topic); + if (numberingEle == null) + return; + + int maxDepth = getMaxDepth(numberingEle); + int topicDepth = getTopicDepth(topic); + String numberFormat = getNumberFormat(numberingEle, topicDepth); + if (numberFormat == null) + return; + + String prefix = getNumberingPrefix(numberingEle, topicDepth); + INumbering numbering = topic.getNumbering(); + + if ((maxDepth - topicDepth) >= 0) + numbering.setFormat(numberFormat); + else + numbering.setFormat(NUMBER_FORMAT_NONE); + + if (topicDepth == 1) + numbering.setPrependsParentNumbers(false); + numbering.setPrefix(prefix); + } + + private String getNumberFormat(Element numberingEle, int depth) { + String numbering = att(numberingEle, "cst1:Numbering"); //$NON-NLS-1$ + if (numbering == null) + return null; + + int formatIndex = (depth - 1) * 2; + if (formatIndex < 0 || (formatIndex + 1) > numbering.length()) + return NUMBER_FORMAT_NONE; + + String numberFormat = numbering.substring(formatIndex, formatIndex + 1); + if ("1".equals(numberFormat)) //$NON-NLS-1$ + return NUMBER_FORMAT_ARABIC; + if ("I".equals(numberFormat) || "i".equals(numberFormat)) //$NON-NLS-1$ //$NON-NLS-2$ + return NUMBER_FORMAT_ROMAN; + if ("A".equals(numberFormat)) //$NON-NLS-1$ + return NUMBER_FORMAT_UPPERCASE; + if ("a".equals(numberFormat)) //$NON-NLS-1$ + return NUMBER_FORMAT_LOWERCASE; + return NUMBER_FORMAT_NONE; + } + + private String getNumberingPrefix(Element numberingEle, int topicDepth) { + String preFix = att(numberingEle, "cst0:Level" + topicDepth + "Text"); //$NON-NLS-1$ //$NON-NLS-2$ + return preFix == null ? "" : preFix; //$NON-NLS-1$ + } + + private int getMaxDepth(Element numberingEle) { + String depth = att(numberingEle, "cst1:Depth"); //$NON-NLS-1$ + return Integer.parseInt(depth == null ? "1" //$NON-NLS-1$ + : depth); + } + + private int getTopicDepth(ITopic topic) { + if (numberingEles == null) + return 0; + + int topicDepth = 1; + while (topic != null) { + Element numberingEle = numberingEles.get(topic); + if (numberingEle != null) + return topicDepth; + topic = topic.getParent(); + topicDepth++; + } + return 0; + } + + private Element findNumberingEle(Element topicEle, ITopic topic) { + if (topicEle == null) + return null; + + Element numberingEle = child(topicEle, "cor:Custom"); //$NON-NLS-1$ + if (numberingEle != null) { + if (numberingEles == null) + numberingEles = new HashMap(); + numberingEles.put(topic, numberingEle); + return numberingEle; + } + return findParentNumbering(topic); + } + + private Element findParentNumbering(ITopic topic) { + if (numberingEles == null) + return null; + + int topicDepth = 1; + while (topic.getParent() != null) { + topic = topic.getParent(); + Element numberingEle = numberingEles.get(topic); + if (numberingEle != null + && (getMaxDepth(numberingEle) >= topicDepth)) + return numberingEle; + topicDepth++; + } + return null; + } + + private void loadNotes(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element notesGroupEle = child(topicEle, "ap:NotesGroup"); //$NON-NLS-1$ + if (notesGroupEle == null) + return; + +// Iterator it = children(notesGroupEle, "ap:NotesData"); //$NON-NLS-1$ +// while (it.hasNext()) { +// Element notesDataEle = it.next(); +// String imgUri = att(notesDataEle, "ImageUri"); //$NON-NLS-1$ +// String binaryUri = loadUri(notesDataEle); +// uriMap.put(imgUri, binaryUri); +// loadImageAtt(imgUri, binaryUri); +// } + + Element notesXhtmlDataEle = child(notesGroupEle, "ap:NotesXhtmlData"); //$NON-NLS-1$ + if (notesXhtmlDataEle != null) { + String bookmarks = getBookmarks(topicEle, topic); + + String plain = att(notesXhtmlDataEle, "PreviewPlainText"); //$NON-NLS-1$ + if (plain != null) { + IPlainNotesContent content = (IPlainNotesContent) getTargetWorkbook() + .createNotesContent(INotes.PLAIN); + content.setTextContent(bookmarks + plain); + topic.getNotes().setContent(INotes.PLAIN, content); + } + + Element htmlEle = child(notesXhtmlDataEle, "xhtml:html"); //$NON-NLS-1$ + if (htmlEle != null) { + IHtmlNotesContent content = (IHtmlNotesContent) getTargetWorkbook() + .createNotesContent(INotes.HTML); + loadHtmlNotes(notesGroupEle, htmlEle, content, bookmarks); + topic.getNotes().setContent(INotes.HTML, content); + } + } + } + + private void loadHtmlNotes(Element notesGroupEle, Element htmlEle, + IHtmlNotesContent content, String bookmarks) + throws InterruptedException { + NotesImporter notesImporter = new NotesImporter(content); + notesImporter.addText(bookmarks); + notesImporter.loadFrom(notesGroupEle, htmlEle); + } + + private void loadImageAtt(String imgUri, String uri) + throws InterruptedException { + checkInterrupted(); + loadAttachment(null, uri, "*.png"); //$NON-NLS-1$ + } + + private String getBookmarks(Element topicEle, ITopic topic) { + Element bookmarkEle = child(topicEle, "ap:Bookmark"); //$NON-NLS-1$ + if (bookmarkEle == null) + return ""; //$NON-NLS-1$ + + String bookmarkName = att(bookmarkEle, "Name"); //$NON-NLS-1$ + if (bookmarkName != null) { + return bookmarkName + '\r'; + } + + return ""; //$NON-NLS-1$ + } + + private void loadLabels(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element labelsEle = child(topicEle, "ap:TextLabels"); //$NON-NLS-1$ + if (labelsEle == null) + return; + + Iterator it = children(labelsEle, "ap:TextLabel"); //$NON-NLS-1$ + while (it.hasNext()) { + checkInterrupted(); + String label = att(it.next(), "TextLabelName"); //$NON-NLS-1$ + if (label != null) { + topic.addLabel(label); + } + } + } + + private void loadMarkers(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element taskEle = child(topicEle, "ap:Task"); //$NON-NLS-1$ + if (taskEle != null) { + addMarker(topic, att(taskEle, "TaskPriority")); //$NON-NLS-1$ + addMarker(topic, att(taskEle, "TaskPercentage")); //$NON-NLS-1$ + } + + Element iconsGroupEle = child(topicEle, "ap:IconsGroup"); //$NON-NLS-1$ + if (iconsGroupEle != null) { + Element iconsEle = child(iconsGroupEle, "ap:Icons"); //$NON-NLS-1$ + if (iconsEle != null) { + Iterator it = children(iconsEle, "ap:Icon"); //$NON-NLS-1$ + while (it.hasNext()) { + addMarker(topic, att(it.next(), "IconType")); //$NON-NLS-1$ + } + } + } + } + + private void addMarker(ITopic topic, String mmIconId) + throws InterruptedException { + checkInterrupted(); + if (mmIconId != null) { + String markerId = parseMarkerId(mmIconId); + if (markerId != null) { + topic.addMarker(markerId); + } + } + } + + @SuppressWarnings("nls") + private void addCheckPoint(ITopicExtensionElement content, + String hasCheckPoint) { + if (hasCheckPoint != null && hasCheckPoint.equals("true")) { + content.setAttribute("check-point", "true"); + } + } + + private static String parseMarkerId(String mmIconId) { + return getMapping("marker", mmIconId, "other-question"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void loadHyperlink(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element hyperlinkEle = child(topicEle, "ap:Hyperlink"); //$NON-NLS-1$ + if (hyperlinkEle == null) + return; + + String url = att(hyperlinkEle, "Url"); //$NON-NLS-1$ + if (url != null) { + if (url.startsWith("#xpointer(")) { //$NON-NLS-1$ + Matcher m = getOIdPattern().matcher(url); + if (m.find()) { + String OId = m.group(1); + recordTopicLink(OId, topic); + } + return; + } else if (!url.startsWith("http://") //$NON-NLS-1$ + && !url.startsWith("https://")) { //$NON-NLS-1$ + String path; + if (url.startsWith("\"") && url.endsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$ + path = url.substring(1, url.length() - 1); + } else { + path = url; + } + String absolute = att(hyperlinkEle, "Absolute"); //$NON-NLS-1$ + url = FilePathParser.toURI(path, + absolute != null && !Boolean.parseBoolean(absolute)); + } + topic.setHyperlink(url); + } + } + + private static Pattern getOIdPattern() { + if (OID_PATTERN == null) { + OID_PATTERN = Pattern.compile("@OId='([^']*)'"); //$NON-NLS-1$ + } + return OID_PATTERN; + } + + private void loadTopicShape(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element shapeEle = child(topicEle, "ap:SubTopicShape"); //$NON-NLS-1$ + if (shapeEle == null) + return; + + String shape = parseTopicShape(att(shapeEle, "SubTopicShape")); //$NON-NLS-1$ + registerStyle(topic, Styles.ShapeClass, shape); + } + + private static String parseTopicShape(String shape) { + return getMapping("topicShape", shape, null); //$NON-NLS-1$ + } + + private void loadImage(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element oneImageEle = child(topicEle, "ap:OneImage"); //$NON-NLS-1$ + if (oneImageEle == null) + return; + + Element imageEle = child(oneImageEle, "ap:Image"); //$NON-NLS-1$ + if (imageEle == null) + return; + + String oId = att(imageEle, "OId"); //$NON-NLS-1$ + + Element imageDataEle = child(imageEle, "ap:ImageData"); //$NON-NLS-1$ + if (imageDataEle == null) + return; + + String uri = loadUri(imageDataEle); + IFileEntry imgEntry = loadAttachment(oId, uri, "*.png"); //$NON-NLS-1$ + if (imgEntry == null) + return; + + IImage image = topic.getImage(); + image.setSource(HyperlinkUtils.toAttachmentURL(imgEntry.getPath())); + + Element sizeEle = child(imageEle, "ap:ImageSize"); //$NON-NLS-1$ + if (sizeEle != null) { + String width = att(sizeEle, "Width"); //$NON-NLS-1$ + String height = att(sizeEle, "Height"); //$NON-NLS-1$ + Float w = parseFloat(width); + Float h = parseFloat(height); + image.setSize( + w == null ? IImage.UNSPECIFIED : mm2Dots(w.floatValue()), + h == null ? IImage.UNSPECIFIED : mm2Dots(h.floatValue())); + } + + String position = null; + Element topicLayoutEle = child(topicEle, "ap:TopicLayout"); //$NON-NLS-1$ + if (topicLayoutEle != null) { + position = att(topicLayoutEle, "TopicTextAndImagePosition"); //$NON-NLS-1$ + } + image.setAlignment(parseImageAlign(position)); + } + + private IFileEntry loadAttachment(String oId, String uri, + String proposalName) throws InterruptedException { + checkInterrupted(); + if (uri == null) + return null; + + if (idMap.containsKey(uri)) { + String path = idMap.get(uri); + if (path != null) { + return getTargetWorkbook().getManifest().getFileEntry(path); + } + return null; + } + + String path = null; + if (uri.startsWith(MMARCH)) { + String mmEntryPath = uri.substring(MMARCH.length()); +// ZipEntry mmEntry = sourceFile.getEntry(mmEntryPath); +// if (mmEntry != null) { + InputStream mmEntryStream = tempSource.getEntryStream(mmEntryPath); + if (mmEntryStream == null) { +// log(new FileNotFoundException(), +// "No such entry: " + mmEntryPath); //$NON-NLS-1$ + return null; + } +// try { +// InputStream in = sourceFile.getInputStream(mmEntry); +// in = new MonitoredInputStream(in, getMonitor()); + if (proposalName != null) { + if (proposalName.startsWith("*.")) { //$NON-NLS-1$ + String ext = proposalName.substring(1); + String oldName = new File(mmEntryPath).getName(); + proposalName = FileUtils.getNoExtensionFileName(oldName) + + ext; + } + } + InputStream in = new MonitoredInputStream(mmEntryStream, + getMonitor()); + try { + IFileEntry entry = getTargetWorkbook().getManifest() + .createAttachmentFromStream(in, proposalName); + path = entry.getPath(); + } catch (IOException e) { + log(e, "Failed to create attachment from: " //$NON-NLS-1$ + + mmEntryPath); + } finally { + try { + in.close(); + } catch (IOException e) { + } + } + } + idMap.put(uri, path); + return getTargetWorkbook().getManifest().getFileEntry(path); + } + + private static String parseImageAlign(String position) { + return getMapping("imageAlignment", position, IImage.RIGHT); //$NON-NLS-1$ + } + + private static String loadUri(Element ele) { + if (ele != null) { + Element uriEle = child(ele, "cor:Uri"); //$NON-NLS-1$ + if (uriEle != null) { + return uriEle.getTextContent(); + } + } + return null; + } + + private void loadTopicViewGroup(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element viewGroupEle = child(topicEle, "ap:TopicViewGroup"); //$NON-NLS-1$ + if (viewGroupEle != null) { + Element collapsedEle = child(viewGroupEle, "ap:Collapsed"); //$NON-NLS-1$ + if (collapsedEle != null) { + String c = att(collapsedEle, "Collapsed"); //$NON-NLS-1$ + if (Boolean.parseBoolean(c)) { + topic.setFolded(true); + } + } + } + } + + private void loadPosition(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element offsetEle = child(topicEle, "ap:Offset"); //$NON-NLS-1$ + if (offsetEle != null) { + String cx = att(offsetEle, "CX"); //$NON-NLS-1$ + String cy = att(offsetEle, "CY"); //$NON-NLS-1$ + Float x = parseFloat(cx); + Float y = parseFloat(cy); + if (x != null && y != null && x.floatValue() != 0 + && y.floatValue() != 0) { + topic.setPosition(mm2Dots(x), mm2Dots(y)); + } + } + } + + private static Float parseFloat(String value) { + if (value != null) { + try { + return Float.valueOf(value); + } catch (Throwable e) { + } + } + return null; + } + + private void loadTask(Element ownerEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + Element taskEle = child(ownerEle, "ap:Task"); //$NON-NLS-1$ + if (taskEle == null) + return; + + ITopicExtensionElement taskContent = null; + String startDate = att(taskEle, "StartDate"); //$NON-NLS-1$ + if (startDate != null) { + Matcher m = DATE_PATTERN.matcher(startDate); + if (m.find()) { + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("start-date"); //$NON-NLS-1$ + ITopicExtensionElement ele = taskContent + .createChild("start-date"); //$NON-NLS-1$ + ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ + } + } + + String endDate = att(taskEle, "DeadlineDate"); //$NON-NLS-1$; + if (endDate != null) { + Matcher m = DATE_PATTERN.matcher(endDate); + if (m.find()) { + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("end-date");//$NON-NLS-1$ + ITopicExtensionElement ele = taskContent + .createChild("end-date"); //$NON-NLS-1$ + ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ + + } + } + + String resources = att(taskEle, "Resources"); //$NON-NLS-1$ + if (resources != null) { + String[] resourceArray = resources.split("; "); //$NON-NLS-1$ + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("assigned-to");//$NON-NLS-1$ + ITopicExtensionElement ele = taskContent.createChild("assigned-to"); //$NON-NLS-1$ + ele.setTextContent(resources); + for (String resource : resourceArray) { + topic.addLabel(NLS.bind( + ImportMessages.MindManagerImporter_ResourceLabel, + resource.replaceAll(",", ";"))); //$NON-NLS-1$//$NON-NLS-2$ + } + } + + String durationHours = att(taskEle, "DurationHours"); //$NON-NLS-1$ + if (durationHours != null) { + String durationLabel = null; + String durationUnit = att(taskEle, "DurationUnit"); //$NON-NLS-1$ + if (durationUnit != null) { + try { + int hours = Integer.parseInt(durationHours); + if ("urn:mindjet:Month".equals(durationUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.MindManagerImporter_Months, + hours / 160); + } else if ("urn:mindjet:Week".equals(durationUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.MindManagerImporter_Weeks, + hours / 40); + } else if ("urn:mindjet:Day".equals(durationUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.MindManagerImporter_Days, + hours / 8); + } + } catch (NumberFormatException e) { + } + } + if (durationLabel == null) { + durationLabel = NLS.bind( + ImportMessages.MindManagerImporter_Hours, + durationHours); + } + topic.addLabel( + NLS.bind(ImportMessages.MindManagerImporter_DurationLabel, + durationLabel)); + } + + addCheckPoint(ensureTaskContent(topic, taskContent), + att(taskEle, "Milestone")); //$NON-NLS-1$ + } + + private static ITopicExtensionElement ensureTaskContent(ITopic topic, + ITopicExtensionElement taskContent) { + if (taskContent != null) + return taskContent; + ITopicExtension ext = topic.createExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + return ext.getContent(); + } + + private void loadTitle(Element ownerEle, ITitled titleOwner) + throws InterruptedException { + checkInterrupted(); + Element textEle = child(ownerEle, "ap:Text"); //$NON-NLS-1$ + String title = textEle == null ? null : att(textEle, "PlainText"); //$NON-NLS-1$ + if (title == null && titleOwner instanceof ITopic) { + title = ImporterUtils.getDefaultTopicTitle((ITopic) titleOwner); + } + if (title != null) { + titleOwner.setTitleText(title); + } + + if (textEle != null && titleOwner instanceof IStyled) { + Element fontEle = child(textEle, "ap:Font"); //$NON-NLS-1$ + if (fontEle != null) { + loadFont(fontEle, (IStyled) titleOwner); + } + String align = textEle == null ? null + : att(textEle, "TextAlignment"); //$NON-NLS-1$ + if (align != null) { + loadTextAlignment(align, (IStyled) titleOwner); + } + } + } + + private void loadTextAlignment(String align, IStyled styleOwner) { + if (align.startsWith("urn:mindjet:")) { //$NON-NLS-1$ + int len = "urn:mindjet:".length(); //$NON-NLS-1$ + String textAlign = align.substring(len).toLowerCase(); + registerStyle(styleOwner, Styles.TextAlign, textAlign); + } + } + + private void loadFont(Element fontEle, IStyled styleOwner) + throws InterruptedException { + checkInterrupted(); + registerStyle(styleOwner, Styles.TextColor, + parseColor(att(fontEle, "Color"))); //$NON-NLS-1$ + + String fontName = att(fontEle, "Name"); //$NON-NLS-1$ + String availableFontName = FontUtils.getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName : fontName; + registerStyle(styleOwner, Styles.FontFamily, fontName); + + registerStyle(styleOwner, Styles.FontSize, + parseFontSize(att(fontEle, "Size"))); //$NON-NLS-1$ + registerStyle(styleOwner, Styles.FontWeight, + Boolean.parseBoolean(att(fontEle, "Bold")) //$NON-NLS-1$ + ? Styles.FONT_WEIGHT_BOLD : null); + registerStyle(styleOwner, Styles.FontStyle, + Boolean.parseBoolean(att(fontEle, "Italic")) //$NON-NLS-1$ + ? Styles.FONT_STYLE_ITALIC : null); + String textDecoration = StyleUtils.toTextDecoration( + Boolean.parseBoolean(att(fontEle, "Underline")), Boolean //$NON-NLS-1$ + .parseBoolean(att(fontEle, "Strikethrough"))); //$NON-NLS-1$ + registerStyle(styleOwner, Styles.TextDecoration, textDecoration); + } + + private static String parseFontSize(String size) { + if (size != null) { + try { + double value = Double.parseDouble(size); + size = StyleUtils.addUnitPoint((int) value); + } catch (Throwable e) { + } + } + return size; + } + + private void loadColor(Element parentEle, IStyled host, boolean transparent) + throws InterruptedException { + checkInterrupted(); + Element colorEle = child(parentEle, "ap:Color"); //$NON-NLS-1$ + if (colorEle != null) { + String fillColor = att(colorEle, "FillColor"); //$NON-NLS-1$ + String opacity = parseAlpha(fillColor); + if (opacity != null && !opacity.equals(TRANSPARENT_VALUE)) + registerStyle(host, Styles.FillColor, parseColor(fillColor)); + if (transparent) { + registerStyle(host, Styles.Opacity, opacity); + } + + String lineColor = att(colorEle, "LineColor"); //$NON-NLS-1$ + registerStyle(host, Styles.LineColor, parseColor(lineColor)); + } + } + + private IStyleSheet getTempStyleSheet() { + if (tempStyleSheet == null) { + tempStyleSheet = Core.getStyleSheetBuilder().createStyleSheet(); + ((StyleSheetImpl) tempStyleSheet) + .setManifest(getTargetWorkbook().getManifest()); + } + return tempStyleSheet; + } + + private void registerStyle(IStyled styleOwner, String key, String value) { + if (value == null) + return; + + IStyle style = styleMap.get(styleOwner); + if (style == null) { + style = getTempStyleSheet().createStyle(styleOwner.getStyleType()); + getTempStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); + styleMap.put(styleOwner, style); + } + if (Styles.TextDecoration.equals(key)) { + String oldValue = style.getProperty(key); + if (oldValue != null && !oldValue.contains(value)) { + boolean underline = oldValue + .contains(Styles.TEXT_DECORATION_UNDERLINE) + || value.contains(Styles.TEXT_DECORATION_UNDERLINE); + boolean strikeout = oldValue + .contains(Styles.TEXT_DECORATION_LINE_THROUGH) + || value.contains(Styles.TEXT_DECORATION_LINE_THROUGH); + value = StyleUtils.toTextDecoration(underline, strikeout); + } + } + style.setProperty(key, value); + } + + private static String parseAlpha(String mmColor) { + if (mmColor != null) { + try { + int alpha = Integer.parseInt(mmColor.substring(0, 1), 16); + double opacity = ((double) alpha) * 100 / 255; + return String.format("%.2f", opacity); //$NON-NLS-1$ + } catch (Throwable t) { + } + } + return null; + } + + private static String parseColor(String mmColor) { + if (mmColor != null) { + int r; + int g; + int b; + try { + r = Integer.parseInt(mmColor.substring(2, 4), 16); + g = Integer.parseInt(mmColor.substring(4, 6), 16); + b = Integer.parseInt(mmColor.substring(6, 8), 16); + return ColorUtils.toString(r, g, b); + } catch (Throwable t) { + } + } + return null; + } + + private void loadOId(Element mmEle, IIdentifiable element) { + String OId = att(mmEle, "OId"); //$NON-NLS-1$ + if (OId != null) { + idMap.put(OId, element.getId()); + } + } + + private void recordTopicLink(String OId, ITopic sourceTopic) { + List topics = topicLinkMap.get(OId); + if (topics == null) { + topics = new ArrayList(); + topicLinkMap.put(OId, topics); + } + topics.add(sourceTopic); + } + + private void setTopicLinks() { + for (Entry> en : topicLinkMap.entrySet()) { + String id = idMap.get(en.getKey()); + if (id != null) { + for (ITopic topic : en.getValue()) { + topic.setHyperlink(HyperlinkUtils.toInternalURL(id)); + } + } + } + } + + private static Element child(Element parentEle, String childTag) { + return children(parentEle, childTag).next(); + } + + private static Iterator children(final Element parentEle, + final String childTag) { + return new Iterator() { + + String tag = DOMUtils.getLocalName(childTag); + + Iterator it = DOMUtils.childElementIter(parentEle); + + Element next = findNext(); + + public void remove() { + } + + private Element findNext() { + while (it.hasNext()) { + Element ele = it.next(); + if (DOMUtils.getLocalName(ele.getTagName()) + .equalsIgnoreCase(tag)) { + return ele; + } + } + return null; + } + + public Element next() { + Element result = next; + next = findNext(); + return result; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + private static String att(Element ele, String attName) { + if (ele.hasAttribute(attName)) + return ele.getAttribute(attName); + + attName = DOMUtils.getLocalName(attName); + NamedNodeMap atts = ele.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node att = atts.item(i); + if (attName.equalsIgnoreCase( + DOMUtils.getLocalName(att.getNodeName()))) { + return att.getNodeValue(); + } + } + return null; + } + + private static int mm2Dots(float mm) { + return (int) (mm * DPM); + } + + private static String getMapping(String type, String sourceId, + String defaultId) { + if (sourceId != null) { + String destination = getMappings().getDestination(type, sourceId); + if (destination != null) + return destination; + } + return defaultId; + } + + private static ResourceMappingManager getMappings() { + if (mappings == null) { + mappings = createMappings(); + } + return mappings; + } + + private static ResourceMappingManager createMappings() { + return MMResourceMappingManager.getInstance(); + } + + private static DocumentBuilder getDocumentBuilder() + throws ParserConfigurationException { + return DOMUtils.getDefaultDocumentBuilder(); + } + + public void error(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void fatalError(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void warning(SAXParseException exception) throws SAXException { + log(exception, null); + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NMConstants.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NMConstants.java index 9649eb32a..cfbc443fc 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NMConstants.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NMConstants.java @@ -1,11 +1,11 @@ -package org.xmind.ui.internal.imports.novamind; - -/** - * @author lyn - */ - -public interface NMConstants { - - String FILE_EXTENSION = ".nm5"; //$NON-NLS-1$ - -} +package org.xmind.ui.internal.imports.novamind; + +/** + * @author lyn + */ + +public interface NMConstants { + + String FILE_EXTENSION = ".nm5"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImportWizard.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImportWizard.java index 31c2978cd..c9572b692 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImportWizard.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImportWizard.java @@ -1,102 +1,102 @@ -package org.xmind.ui.internal.imports.novamind; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.imports.ImportPlugin; -import org.xmind.ui.wizards.AbstractMindMapImportPage; -import org.xmind.ui.wizards.AbstractMindMapImportWizard; -import org.xmind.ui.wizards.MindMapImporter; - -/** - * @author lyn - */ - -public class NovaMindImportWizard extends AbstractMindMapImportWizard { - - private static final String SETTINGS_ID = "org.xmind.ui.imports.NovaMind"; //$NON-NLS-1$ - - private static final String PAGE_ID = "importNovaMind"; //$NON-NLS-1$ - - private static final String EXT = "*" + NMConstants.FILE_EXTENSION; //$NON-NLS-1$ - - private class NovaMindImportPage extends AbstractMindMapImportPage { - - protected NovaMindImportPage() { - super(PAGE_ID, ImportMessages.NovaMindImportPage_title); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 15; - composite.setLayout(layout); - setControl(composite); - - Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - - Control destinationControl = createDestinationControl(composite); - destinationControl.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - updateStatus(); - - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - openBrowseDialog(); - } - }); - } - - protected FileDialog createBrowseDialog() { - FileDialog dialog = super.createBrowseDialog(); - dialog.setFilterExtensions(new String[] { EXT }); - dialog.setFilterNames(new String[] { NLS.bind( - ImportMessages.NovaMindImportPage_FileDialog_Filter_name, - EXT) }); - return dialog; - } - - } - - private NovaMindImportPage page; - - public NovaMindImportWizard() { - IDialogSettings settings = ImportPlugin.getDefault().getDialogSettings() - .getSection(SETTINGS_ID); - if (settings == null) { - settings = ImportPlugin.getDefault().getDialogSettings() - .addNewSection(SETTINGS_ID); - } - setDialogSettings(settings); - setWindowTitle(ImportMessages.NovaMindImportWizard_windowTitle); - } - - public void addPages() { - addPage(page = new NovaMindImportPage()); - } - - protected MindMapImporter createImporter(String sourcePath, - IWorkbook targetWorkbook) { - return new NovaMindImporter(sourcePath, targetWorkbook); - } - - protected String getApplicationId() { - return "NovaMind"; //$NON-NLS-1$ - } - - protected void handleExportException(Throwable e) { - super.handleExportException(e); - page.setErrorMessage(e.getLocalizedMessage()); - } - -} +package org.xmind.ui.internal.imports.novamind; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.IWorkbook; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.imports.ImportPlugin; +import org.xmind.ui.wizards.AbstractMindMapImportPage; +import org.xmind.ui.wizards.AbstractMindMapImportWizard; +import org.xmind.ui.wizards.MindMapImporter; + +/** + * @author lyn + */ + +public class NovaMindImportWizard extends AbstractMindMapImportWizard { + + private static final String SETTINGS_ID = "org.xmind.ui.imports.NovaMind"; //$NON-NLS-1$ + + private static final String PAGE_ID = "importNovaMind"; //$NON-NLS-1$ + + private static final String EXT = "*" + NMConstants.FILE_EXTENSION; //$NON-NLS-1$ + + private class NovaMindImportPage extends AbstractMindMapImportPage { + + protected NovaMindImportPage() { + super(PAGE_ID, ImportMessages.NovaMindImportPage_title); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + composite.setLayout(layout); + setControl(composite); + + Control fileGroup = createFileControls(composite); + fileGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + + Control destinationControl = createDestinationControl(composite); + destinationControl.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + updateStatus(); + + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + openBrowseDialog(); + } + }); + } + + protected FileDialog createBrowseDialog() { + FileDialog dialog = super.createBrowseDialog(); + dialog.setFilterExtensions(new String[] { EXT }); + dialog.setFilterNames(new String[] { NLS.bind( + ImportMessages.NovaMindImportPage_FileDialog_Filter_name, + EXT) }); + return dialog; + } + + } + + private NovaMindImportPage page; + + public NovaMindImportWizard() { + IDialogSettings settings = ImportPlugin.getDefault().getDialogSettings() + .getSection(SETTINGS_ID); + if (settings == null) { + settings = ImportPlugin.getDefault().getDialogSettings() + .addNewSection(SETTINGS_ID); + } + setDialogSettings(settings); + setWindowTitle(ImportMessages.NovaMindImportWizard_windowTitle); + } + + public void addPages() { + addPage(page = new NovaMindImportPage()); + } + + protected MindMapImporter createImporter(String sourcePath, + IWorkbook targetWorkbook) { + return new NovaMindImporter(sourcePath, targetWorkbook); + } + + protected String getApplicationId() { + return "NovaMind"; //$NON-NLS-1$ + } + + protected void handleExportException(Throwable e) { + super.handleExportException(e); + page.setErrorMessage(e.getLocalizedMessage()); + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImporter.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImporter.java index 68f81e59c..e5f2bd52f 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImporter.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindImporter.java @@ -1,2002 +1,2003 @@ -package org.xmind.ui.internal.imports.novamind; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; - -import org.eclipse.osgi.util.NLS; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IBoundary; -import org.xmind.core.IFileEntry; -import org.xmind.core.IHtmlNotesContent; -import org.xmind.core.IHyperlinkSpan; -import org.xmind.core.IIdentifiable; -import org.xmind.core.IImage; -import org.xmind.core.INotes; -import org.xmind.core.INumbering; -import org.xmind.core.IParagraph; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISpan; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.Image; -import org.xmind.core.internal.dom.StyleSheetImpl; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IStorage; -import org.xmind.core.io.ResourceMappingManager; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.io.MonitoredInputStream; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.wizards.MindMapImporter; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * @author lyn - */ - -public class NovaMindImporter extends MindMapImporter - implements NMConstants, ErrorHandler { - - private static final Pattern DATE_PATTERN = Pattern.compile( - "((\\d+)-(\\d{1,2})-(\\d{1,2}))T((\\d{1,2}):(\\d{1,2}):(\\d{1,2}))"); //$NON-NLS-1$ - - private static final String TRANSPARENT_VALUE = "0.00"; //$NON-NLS-1$ - - private static final double DPM = 1d; - - private static final String CONTENT_XML = "content.xml"; //$NON-NLS-1$ - - private static final String MANIFEST_XML = "manifest.xml"; //$NON-NLS-1$ - - private static final String STYLE_SHEET_XML = "style-sheet.xml"; //$NON-NLS-1$ - - private static final String SEP = File.separator; - - private static final String RESOURCES_FOLDER = "Resources" + SEP; //$NON-NLS-1$ - - private class NotesImporter { - - IParagraph currentParagraph = null; - - IHtmlNotesContent content; - - public NotesImporter(IHtmlNotesContent content) { - this.content = content; - } - - public void loadFrom(Element notesEle) throws InterruptedException { - checkInterrupted(); - - Element richTextEle = child(notesEle, "rich-text"); //$NON-NLS-1$ - if (richTextEle == null) - return; - - NodeList nl = richTextEle.getChildNodes(); - - for (int i = 0; i < nl.getLength(); i++) { - Node node = nl.item(i); - String nodeName = node.getNodeName(); - if ("text-run".equals(nodeName)) { //$NON-NLS-1$ - loadText(node); - } else if ("hyperlink".equals(nodeName)) { //$NON-NLS-1$ - /// TODO add hyperlink to notes - - NamedNodeMap atts = node.getAttributes(); - Node href = atts.getNamedItem("url"); //$NON-NLS-1$ - IHyperlinkSpan linkSpan = content - .createHyperlinkSpan(href.getTextContent()); - addSpan(node, linkSpan); - - NodeList hnl = node.getChildNodes(); - for (int j = 0; j < hnl.getLength(); j++) { - Node hNode = hnl.item(j); - if (hNode != null - && "text-run".equals(hNode.getNodeName())) { //$NON-NLS-1$ - loadText(hNode); - } - } - } - } - } - - private void loadText(Node node) throws InterruptedException { - NodeList ps = node.getChildNodes(); - for (int pi = 0; pi < ps.getLength(); pi++) { - Node p = ps.item(pi); - if (p.getNodeType() == Node.TEXT_NODE) { - addText(node, p.getTextContent()); - } else if ("p".equals(p.getNodeName())) { //$NON-NLS-1$ - addParagraph(node); - } - } - } - - private void addText(Node node, String text) - throws InterruptedException { - if (text == null || "".equals(text)) //$NON-NLS-1$ - return; - - addSpan(node, content.createTextSpan(text)); - } - - private void addSpan(Node node, ISpan span) - throws InterruptedException { - if (currentParagraph == null) - addParagraph(node); - - currentParagraph.addSpan(span); - loadStyle(node, span); - loadAlign(node, currentParagraph); - } - - private void addParagraph(Node node) throws InterruptedException { - currentParagraph = content.createParagraph(); - content.addParagraph(currentParagraph); - loadAlign(node, currentParagraph); - } - - @SuppressWarnings({ "nls" }) - private void loadStyle(Node node, IStyled host) - throws InterruptedException { - checkInterrupted(); - - NamedNodeMap atts = node.getAttributes(); - - Node nmColorNode = atts.getNamedItem("font-color"); - if (nmColorNode != null) { - String nmColor = nmColorNode.getTextContent(); - nmColor = NovaMindImporter.this.realNmColor(nmColor); - registerStyle(host, Styles.TextColor, - parseColor(nmColor.substring(3))); - } - Node fontSizeNode = atts.getNamedItem("font-size"); - if (fontSizeNode != null) - registerStyle(host, Styles.FontSize, NovaMindImporter - .parseFontSize(fontSizeNode.getTextContent())); - - Node boldNode = atts.getNamedItem("bold"); - if (boldNode != null) - registerStyle(host, Styles.FontWeight, - Boolean.parseBoolean(boldNode.getTextContent()) - ? Styles.FONT_WEIGHT_BOLD : null); - - Node italicNode = atts.getNamedItem("italic"); - if (italicNode != null) - registerStyle(host, Styles.FontStyle, - Boolean.parseBoolean(italicNode.getTextContent()) - ? Styles.FONT_STYLE_ITALIC : null); - - String textDecoration = StyleUtils.toTextDecoration( - atts.getNamedItem("underline-style") != null, - atts.getNamedItem("strikethrough-style") != null); - registerStyle(host, Styles.TextDecoration, textDecoration); - - String fontName = null; - Node macFontNameNode = atts.getNamedItem("mac-font-name"); - if (macFontNameNode != null) - fontName = macFontNameNode.getTextContent(); - - if (fontName == null || "".equals(fontName)) { - Node windowsFontNameNode = atts - .getNamedItem("windows-font-name"); - if (windowsFontNameNode != null) - fontName = windowsFontNameNode.getTextContent(); - } - - if (fontName != null) { - String availableFontName = FontUtils - .getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName - : fontName; - registerStyle(host, Styles.FontFamily, fontName); - } - } - - private void loadAlign(Node node, IStyled host) - throws InterruptedException { - checkInterrupted(); - - NamedNodeMap atts = node.getAttributes(); - - Node alignmentNode = atts.getNamedItem("alignment"); //$NON-NLS-1$ - if (alignmentNode != null) - registerStyle(host, Styles.TextAlign, - alignmentNode.getTextContent().toLowerCase()); - } - - } - - private static ResourceMappingManager mappings = null; - - private IStorage tempStorage; - - private IInputSource tempSource; - - private Document content; - - private Document manifest; - - private Document styleSheet; - - private ISheet targetSheet; - - private Map styleMap = new HashMap(30); - - private IStyle theme = null; - - private IStyleSheet tempStyleSheet = null; - - private Map topicIdMap = new HashMap(30); - - private Map refIdMap = new HashMap(30); - - private Map> topicLinkMap = new HashMap>( - 10); - - private Map resourceRefMap = new HashMap(); - - private Map resourceMap = new HashMap(30); - - private Map themeRefMap = new HashMap(); - - private Map assignRefMap = new HashMap(); - - private NovaMindImporter(String sourcePath) { - super(sourcePath); - } - - public NovaMindImporter(String sourcePath, IWorkbook targetWorkbook) { - super(sourcePath, targetWorkbook); - } - - public void build() throws InvocationTargetException, InterruptedException { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ImportFromNovaCount"); //$NON-NLS-1$ - getMonitor().beginTask(null, 100); - try { - getMonitor() - .subTask(ImportMessages.MindManagerImporter_ReadingContent); - - tempStorage = createTemporaryStorage(); - extractSourceFileToTemporaryStorage(); - tempSource = tempStorage.getInputSource(); - - content = readFile(CONTENT_XML); - manifest = readFile(MANIFEST_XML); - styleSheet = readFile(STYLE_SHEET_XML); - - getMonitor().worked(45); - checkInterrupted(); - - getMonitor().subTask( - ImportMessages.MindManagerImporter_ReadingElements); - loadWorkbook(content.getDocumentElement()); - setTopicLinks(); - getMonitor().worked(45); - - checkInterrupted(); - getMonitor().subTask( - ImportMessages.MindManagerImporter_ArrangingStyles); - arrangeStyles(); - getMonitor().worked(5); - - checkInterrupted(); - getMonitor().subTask( - ImportMessages.MindManagerImporter_GeneratingTheme); - generateTheme(); - getMonitor().worked(5); - getMonitor().done(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } finally { - clearTempStorage(); - } - postBuilded(); - } - - private Document readFile(String name) throws Exception { - InputStream docEntryStream = tempSource.getEntryStream(name); - if (docEntryStream == null) - throw new IOException("No content entry"); //$NON-NLS-1$ - - DocumentBuilder builder = getDocumentBuilder(); - builder.setErrorHandler(this); - InputStream in = new MonitoredInputStream(docEntryStream, getMonitor()); - Document doc; - try { - doc = builder.parse(in); - } finally { - builder.setErrorHandler(null); - try { - in.close(); - } catch (Exception e) { - } - } - return doc; - } - - private IStorage createTemporaryStorage() throws IOException { - String id = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", //$NON-NLS-1$ - System.currentTimeMillis()); - File tempDir = FileUtils.ensureDirectory(new File( - Core.getWorkspace().getTempDir("import/mindmanager"), id)); //$NON-NLS-1$ - return new DirectoryStorage(tempDir); - } - - private void extractSourceFileToTemporaryStorage() - throws IOException, CoreException { - FileInputStream fin = new FileInputStream(getSourcePath()); - try { - ZipInputStream zin = new ZipInputStream(new MonitoredInputStream( - new BufferedInputStream(fin), getMonitor())); - try { - FileUtils.extractZipFile(zin, tempStorage.getOutputTarget()); - } finally { - zin.close(); - } - } finally { - fin.close(); - } - - } - - private void checkInterrupted() throws InterruptedException { - if (getMonitor().isCanceled()) - throw new InterruptedException(); - } - - private void clearTempStorage() { - if (tempStorage != null) { - tempStorage.clear(); - tempStorage = null; - } - } - - private void loadWorkbook(Element docEle) throws InterruptedException { - checkInterrupted(); - - Element workbookEle = child(docEle, "maps"); //$NON-NLS-1$ - if (workbookEle == null) - return; - - Element sheetEle = child(workbookEle, "map"); //$NON-NLS-1$ - if (sheetEle == null) - return; - - loadSheet(sheetEle); - } - - private void loadSheet(Element sheetEle) throws InterruptedException { - checkInterrupted(); - - targetSheet = getTargetWorkbook().createSheet(); - - Element topicEle = child(sheetEle, "topic-node"); //$NON-NLS-1$ - if (topicEle != null) - loadRootTopic(topicEle); - - Element relationshipsEle = child(sheetEle, "link-lines"); //$NON-NLS-1$ - if (relationshipsEle != null) - loadRelationships(relationshipsEle); - - String themeRef = att(sheetEle, "theme-ref"); //$NON-NLS-1$ - Element themeEle = findThemeEle(themeRef); - if (themeEle != null) - loadTheme(themeEle); - - addTargetSheet(targetSheet); - } - - public ISheet getTargetSheet() { - return targetSheet; - } - - private void loadRootTopic(Element topicEle) throws InterruptedException { - checkInterrupted(); - - ITopic rootTopic = getTargetSheet().getRootTopic(); - loadTopic(topicEle, rootTopic); - - Element subTopicsEle = child(topicEle, "sub-topics"); //$NON-NLS-1$ - if (subTopicsEle != null) - loadSubElements(subTopicsEle, rootTopic); - } - - private void loadSubElements(Element topicsEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Iterator subElements = children(topicsEle, "topic-node"); //$NON-NLS-1$ - - while (subElements.hasNext()) { - Element subElement = subElements.next(); - - String type = att(subElement, "type"); //$NON-NLS-1$ - - if ("Boundary".equals(type)) { //$NON-NLS-1$ - loadBoundary(subElement, topic); - } else { - ITopic subTopic = addElement(topic, subElement, type); - - loadTopic(subElement, subTopic); - - Element subTopicsEle = child(subElement, "sub-topics"); //$NON-NLS-1$ - if (subTopicsEle != null) - loadSubElements(subTopicsEle, subTopic); - } - - } - } - - private void loadTopic(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - loadOId(topicEle, topic); - loadTopicContent(topicEle, topic); - - loadTopicNodeStyle(topicEle, topic); - } - - private ITopic addElement(ITopic topic, Element topicEle, String type) { - ITopic subTopic = getTargetWorkbook().createTopic(); - - if ("FloatingTopic".equals(type)) //$NON-NLS-1$ - topic.add(subTopic, ITopic.DETACHED); - else if ("Callout".equals(type)) //$NON-NLS-1$ - topic.add(subTopic, ITopic.CALLOUT); - else - topic.add(subTopic); - - return subTopic; - } - - private void loadOId(Element nmEle, IIdentifiable element) { - String OId = att(nmEle, "id"); //$NON-NLS-1$ - if (OId != null) - topicIdMap.put(OId, element.getId()); - } - - private void loadTopicContent(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - String id = att(topicEle, "id"); //$NON-NLS-1$ - String ref = att(topicEle, "topic-ref"); //$NON-NLS-1$ - refIdMap.put(ref, id); - Element contentEle = findTopicContentEle(ref); - if (contentEle == null) - return; - - loadTitleText(contentEle, topic); - loadNotes(contentEle, topic); - loadHyperlink(contentEle, topic); - loadAttachments(contentEle, topic); - loadImages(contentEle, topic); - loadTask(contentEle, topic); - } - - private Element findTopicContentEle(String refId) - throws InterruptedException { - checkInterrupted(); - - if (refId == null) - return null; - - Element contentEle = content.getDocumentElement(); - - Element topicsEle = child(contentEle, "topics"); //$NON-NLS-1$ - - if (topicsEle == null) - return null; - - Iterator topicEles = children(topicsEle, "topic"); //$NON-NLS-1$ - - while (topicEles.hasNext()) { - Element topic = topicEles.next(); - String id = att(topic, "id"); //$NON-NLS-1$ - - if (refId.equals(id)) - return topic; - } - - return null; - } - - private void loadTitleText(Element contentEle, ITopic topic) - throws InterruptedException { - Element text = child(contentEle, "rich-text"); //$NON-NLS-1$ - if (text == null) - return; - - Element titleRun = child(text, "text-run"); //$NON-NLS-1$ - if (titleRun == null) - return; - - topic.setTitleText(titleRun.getTextContent()); - loadTextStyle(titleRun, topic); - } - - private void loadNotes(Element contentEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element notesEle = child(contentEle, "notes"); //$NON-NLS-1$ - if (notesEle == null) - return; - - IHtmlNotesContent content = (IHtmlNotesContent) getTargetWorkbook() - .createNotesContent(INotes.HTML); - NotesImporter notesImporter = new NotesImporter(content); - notesImporter.loadFrom(notesEle); - topic.getNotes().setContent(INotes.HTML, content); - } - - private void loadHyperlink(Element contentEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element linksEle = child(contentEle, "links"); //$NON-NLS-1$ - if (linksEle == null) - return; - - Iterator it = children(linksEle, "link"); //$NON-NLS-1$ - - while (it.hasNext()) { - Element linkDataEle = it.next(); - String url = att(linkDataEle, "url"); //$NON-NLS-1$ - if (url == null) - continue; - - String name = att(linkDataEle, "display-name"); //$NON-NLS-1$ - if (name == null || "".equals(name)) //$NON-NLS-1$ - name = url; - ITopic linkTopic = getTargetWorkbook().createTopic(); - linkTopic.setTitleText(name); - topic.add(linkTopic); - - if (url.startsWith("novamind://topic/")) { //$NON-NLS-1$ - recordTopicLink(url.replace("novamind://topic/", ""), //$NON-NLS-1$//$NON-NLS-2$ - linkTopic); - continue; - } else if (!HyperlinkUtils.isLinkToWeb(url)) { - url = FilePathParser.toURI(url, false); - } - linkTopic.setHyperlink(url); - - } - } - - private void loadAttachments(Element contentEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - if (manifest == null) - return; - - Element attachmentsEle = child(contentEle, "attachments"); //$NON-NLS-1$ - if (attachmentsEle == null) - return; - - Iterator attachmentEles = children(attachmentsEle, - "attachment"); //$NON-NLS-1$ - - while (attachmentEles.hasNext()) { - Element attDataEle = attachmentEles.next(); - IFileEntry entry = getResourceFileEntry(attDataEle); - if (entry != null) { - ITopic attTopic = getTargetWorkbook().createTopic(); - String title = getResourceTitle(attDataEle); - attTopic.setTitleText(title == null - ? new File(entry.getPath()).getName() : title); - attTopic.setHyperlink( - HyperlinkUtils.toAttachmentURL(entry.getPath())); - topic.add(attTopic, ITopic.ATTACHED); - } - } - } - - private void loadImages(Element contentEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - if (manifest == null) - return; - - loadImage(contentEle, topic, "top-image", IImage.TOP, 0, 64); //$NON-NLS-1$ - loadImage(contentEle, topic, "bottom-image", IImage.BOTTOM, 0, 64); //$NON-NLS-1$ - loadImage(contentEle, topic, "left-image", Image.LEFT, 64, 0); //$NON-NLS-1$ - loadImage(contentEle, topic, "right-image", Image.RIGHT, 64, 0); //$NON-NLS-1$ - } - - private void loadImage(Element contentEle, ITopic topic, String imageAtt, - String alignment, int w, int h) throws InterruptedException { - Element imageEle = child(contentEle, imageAtt); - if (imageEle != null) { - IFileEntry entry = getResourceFileEntry(imageEle); - if (entry != null) { - String title = getResourceTitle(imageEle); - ITopic attTopic = getTargetWorkbook().createTopic(); - attTopic.setTitleText(title == null - ? new File(entry.getPath()).getName() : title); - IImage image = attTopic.getImage(); - image.setSource( - HyperlinkUtils.toAttachmentURL(entry.getPath())); - image.setAlignment(alignment); - image.setSize(w == 0 ? IImage.UNSPECIFIED : w, - h == 0 ? IImage.UNSPECIFIED : h); - topic.add(attTopic); - } - } - } - - private void loadTask(Element contentEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element taskEle = child(contentEle, "project-task"); //$NON-NLS-1$ - if (taskEle == null) - return; - - ITopicExtensionElement taskContent = null; - String priority = att(taskEle, "priority"); //$NON-NLS-1$ - loadMarker(topic, parsePriority(priority)); - - String pc = att(taskEle, "percentage-complete"); //$NON-NLS-1$ - loadMarker(topic, parsePercentage(pc)); - - if (pc != null) { - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("progress"); //$NON-NLS-1$ - ITopicExtensionElement ele = taskContent.createChild("progress"); //$NON-NLS-1$ - ele.setTextContent(pc); - } - - String start = att(taskEle, "start-time"); //$NON-NLS-1$ - if (start != null && !"".equals(start)) { //$NON-NLS-1$ - Matcher m = DATE_PATTERN.matcher(start); - if (m.find()) { - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("start-date"); //$NON-NLS-1$ - ITopicExtensionElement ele = taskContent - .createChild("start-date"); //$NON-NLS-1$ - ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ - } - } - - String end = att(taskEle, "end-time"); //$NON-NLS-1$ - if (end != null) { - Matcher m = DATE_PATTERN.matcher(end); - if (m.find()) { - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("end-date");//$NON-NLS-1$ - ITopicExtensionElement ele = taskContent - .createChild("end-date"); //$NON-NLS-1$ - ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ - } - } - - String duration = att(taskEle, "duration"); //$NON-NLS-1$ - String dUnit = att(taskEle, "duration-unit"); //$NON-NLS-1$ - if (duration != null && !"".equals(duration)) { //$NON-NLS-1$ - String durationLabel = null; - if ("Years".equals(dUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Years_label, - duration); - } else if ("Months".equals(dUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Months_label, - duration); - } else if ("Weeks".equals(dUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Weeks_label, - duration); - } else if ("Hours".equals(dUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Hours_label, - duration); - } else if ("Minutes".equals(dUnit)) { //$NON-NLS-1$ - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Minutes_label, - duration); - } else { - durationLabel = NLS.bind( - ImportMessages.NovaMindImporter_Duration_Days_label, - duration); - } - - topic.addLabel( - NLS.bind(ImportMessages.NovaMindImporter_Duration_label, - durationLabel)); - } - - Element resourcesEle = child(taskEle, "assigned-resources"); //$NON-NLS-1$ - if (resourcesEle != null) { - Iterator it = children(resourcesEle, - "project-resource-ref"); //$NON-NLS-1$ - String assigns = ""; //$NON-NLS-1$ - while (it.hasNext()) { - Element next = it.next(); - String ref = next.getTextContent(); - assigns += findAssign(ref) + ","; //$NON-NLS-1$ - } - if (assigns != null && !"".equals(assigns)) { //$NON-NLS-1$ - assigns = assigns.substring(0, assigns.length() - 2); - taskContent = ensureTaskContent(topic, taskContent); - taskContent.deleteChildren("assigned-to");//$NON-NLS-1$ - ITopicExtensionElement ele = taskContent - .createChild("assigned-to"); //$NON-NLS-1$ - ele.setTextContent(assigns); - topic.addLabel( - NLS.bind(ImportMessages.NovaMindImporter_Resource_label, - assigns.replaceAll(",", ";"))); //$NON-NLS-1$//$NON-NLS-2$ - } - } - } - - private void loadMarker(ITopic topic, String markerId) - throws InterruptedException { - checkInterrupted(); - - if (markerId != null) - topic.addMarker(markerId); - } - - private static String parsePriority(String nmPriority) { - if (nmPriority == null) - return null; - - try { - int priority = Integer.parseInt(nmPriority); - switch (priority) { - case 1: - return "priority-1"; //$NON-NLS-1$ - case 2: - return "priority-2"; //$NON-NLS-1$ - case 3: - return "priority-3"; //$NON-NLS-1$ - case 4: - return "priority-4"; //$NON-NLS-1$ - case 5: - return "priority-5"; //$NON-NLS-1$ - case 6: - return "priority-6"; //$NON-NLS-1$ - case 7: - return "priority-7"; //$NON-NLS-1$ - case 8: - return "priority-8"; //$NON-NLS-1$ - case 9: - return "priority-9"; //$NON-NLS-1$ - } - } catch (NumberFormatException e) { - } - - return null; - } - - @SuppressWarnings("nls") - private static String parsePercentage(String nmPercentage) { - if (nmPercentage == null) - return null; - - try { - int pc = Integer.parseInt(nmPercentage); - if (pc < 12) - return "task-start"; - if (pc < 25) - return "task-oct"; - if (pc < 37) - return "task-quarter"; - if (pc < 50) - return "task-3oct"; - if (pc < 62) - return "task-half"; - if (pc < 75) - return "task-5oct"; - if (pc < 87) - return "task-3quar"; - if (pc < 100) - return "task-7oct"; - if (pc == 100) - return "task-done"; - } catch (NumberFormatException e) { - } - return null; - } - - private void loadTextStyle(Element titleEle, IStyled host) - throws InterruptedException { - checkInterrupted(); - - String nmColor = att(titleEle, "font-color"); //$NON-NLS-1$ - if (nmColor != null) { - nmColor = realNmColor(nmColor); - registerStyle(host, Styles.TextColor, - parseColor(nmColor.substring(3))); - } - - registerStyle(host, Styles.FontSize, - parseFontSize(att(titleEle, "font-size"))); //$NON-NLS-1$ - registerStyle(host, Styles.FontWeight, - Boolean.parseBoolean(att(titleEle, "bold")) //$NON-NLS-1$ - ? Styles.FONT_WEIGHT_BOLD : null); - registerStyle(host, Styles.FontStyle, - Boolean.parseBoolean(att(titleEle, "italic")) //$NON-NLS-1$ - ? Styles.FONT_STYLE_ITALIC : null); - String textDecoration = StyleUtils.toTextDecoration( - att(titleEle, "underline-style") != null, //$NON-NLS-1$ - att(titleEle, "strikethrough-style") != null); //$NON-NLS-1$ - registerStyle(host, Styles.TextDecoration, textDecoration); - String alignment = att(titleEle, "alignment"); //$NON-NLS-1$ - if (alignment != null) - registerStyle(host, Styles.TextAlign, alignment.toLowerCase()); - - String fontName = att(titleEle, "mac-font-name"); //$NON-NLS-1$ - if (fontName == null) - fontName = att(titleEle, "windows-font-name"); //$NON-NLS-1$ - - if (fontName != null) { - String availableFontName = FontUtils - .getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName : fontName; - registerStyle(host, Styles.FontFamily, fontName); - } - - } - - private void loadTopicNodeStyle(Element topicEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element nodeViewEle = child(topicEle, "topic-node-view"); //$NON-NLS-1$ - if (nodeViewEle == null) - return; - - loadPosition(nodeViewEle, topic); - - Element nodeStyleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ - if (nodeStyleEle == null) - return; - - loadFillStyle(nodeStyleEle, topic, null); - loadShapeStyle(nodeStyleEle, topic); - loadLineStyle(nodeStyleEle, topic); - loadStructure(nodeStyleEle, topic); - loadConnectionStyle(nodeStyleEle, topic); - loadNumbering(nodeStyleEle, topic); - } - - private void loadPosition(Element nodeViewEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - String location = att(nodeViewEle, "manual-location"); //$NON-NLS-1$ - if ((location == null || "".equals(location)) //$NON-NLS-1$ - && (ITopic.DETACHED.equals(topic.getType()) - || ITopic.CALLOUT.equals(topic.getType()))) - location = att(nodeViewEle, "location"); //$NON-NLS-1$ - - if (location == null || "".equals(location)) //$NON-NLS-1$ - return; - - String[] split = location.split(","); //$NON-NLS-1$ - if (split.length != 2) - return; - - Float x = parseFloat(split[0]); - Float y = parseFloat(split[1]); - if (x != null && y != null && x.floatValue() != 0 - && y.floatValue() != 0) { - topic.setPosition(mm2Dots(x), mm2Dots(y)); - } - } - - private void loadFillStyle(Element nodeStyleEle, IStyled host, - String defaultColor) throws InterruptedException { - checkInterrupted(); - - Element fillStyleEle = child(nodeStyleEle, "fill-style"); //$NON-NLS-1$ - if (fillStyleEle == null) - return; - - String nmColor = getFillValue(fillStyleEle); - if (nmColor == null) { - if (defaultColor == null) - return; - nmColor = defaultColor; - } - - nmColor = realNmColor(nmColor); - - String opacity = parseAlpha(nmColor); - String fillColor = parseColor(nmColor.substring(3)); - if (opacity != null && !opacity.equals(TRANSPARENT_VALUE)) - registerStyle(host, Styles.Opacity, opacity); - - if (fillColor != null) - registerStyle(host, Styles.FillColor, fillColor); - } - - private String realNmColor(String nmColor) { - if (!nmColor.startsWith("#")) //$NON-NLS-1$ - nmColor = getMapping("nmColor", nmColor, "#FFFFF"); //$NON-NLS-1$//$NON-NLS-2$ - return nmColor; - } - - private String getFillValue(Element fillStyleEle) - throws InterruptedException { - checkInterrupted(); - - String fillValue = null; - - Element advancedGradientEle = child(fillStyleEle, "advanced-gradient"); //$NON-NLS-1$ - if (advancedGradientEle != null) { - Element advancedColors = child(advancedGradientEle, "colors"); //$NON-NLS-1$ - if (advancedColors != null) { - Element colorEle = child(advancedColors, "color-stop"); //$NON-NLS-1$ - if (colorEle != null) - fillValue = att(colorEle, "color"); //$NON-NLS-1$ - } - } - - if (fillValue == null) { - Element simpleGradientEle = child(fillStyleEle, "simple-gradient"); //$NON-NLS-1$ - if (simpleGradientEle != null) { - String sColor = att(simpleGradientEle, "start-color"); //$NON-NLS-1$ - String eColor = att(simpleGradientEle, "end-color"); //$NON-NLS-1$ - fillValue = sColor != null ? sColor : eColor; - } - } - - if (fillValue == null) { - Element solidColorEle = child(fillStyleEle, "solid-color"); //$NON-NLS-1$ - if (solidColorEle != null) - fillValue = att(solidColorEle, "color"); //$NON-NLS-1$ - } - - return fillValue; - } - - private String parseAlpha(String color) { - if (color != null && color.startsWith("#")) { //$NON-NLS-1$ - try { - int alpha = Integer.parseInt(color.substring(1, 2), 16); - double opacity = ((double) alpha) * 100 / 255; - return String.format("%.2f", opacity); //$NON-NLS-1$ - } catch (Exception e) { - } - } - - return null; - } - - private static String parseColor(String color) { - if (color != null) { - int r; - int g; - int b; - try { - r = Integer.parseInt(color.substring(0, 2), 16); - g = Integer.parseInt(color.substring(2, 4), 16); - b = Integer.parseInt(color.substring(4, 6), 16); - return ColorUtils.toString(r, g, b); - } catch (Throwable t) { - } - } - return null; - } - - private static String parseFontSize(String size) { - if (size != null) { - try { - double value = Double.parseDouble(size); - size = StyleUtils.addUnitPoint((int) value); - } catch (Exception e) { - } - } - return size; - } - - private void loadShapeStyle(Element nodeStyleEle, IStyled host) - throws InterruptedException { - checkInterrupted(); - - Element shapeStyleEle = child(nodeStyleEle, "shape-style"); //$NON-NLS-1$ - if (shapeStyleEle == null) - return; - - if (host instanceof ITopic) { - Element topicShapeEle = child(shapeStyleEle, "topic-shape-style"); //$NON-NLS-1$ - if (topicShapeEle != null) { - String shape = att(topicShapeEle, "type"); //$NON-NLS-1$ - if (ITopic.CALLOUT.equals(((ITopic) host).getType())) - registerStyle(host, Styles.CalloutShapeClass, - parseCalloutShape(shape)); - else - registerStyle(host, Styles.ShapeClass, - parseTopicShape(shape)); - } - - } - - if (host instanceof IBoundary) { - Element boundaryShapeEle = child(shapeStyleEle, - "boundary-shape-style"); //$NON-NLS-1$ - if (boundaryShapeEle != null) - registerStyle(host, Styles.ShapeClass, - parseBoundaryShape(att(boundaryShapeEle, "type"))); //$NON-NLS-1$ - - } - - } - - private void loadLineStyle(Element nodeStyleEle, IStyled host) - throws InterruptedException { - checkInterrupted(); - - Element lineStyleEle = child(nodeStyleEle, "line-style"); //$NON-NLS-1$ - if (lineStyleEle == null) - return; - - String nmColor = att(lineStyleEle, "color"); //$NON-NLS-1$ - if (nmColor != null) { - nmColor = realNmColor(nmColor); - registerStyle(host, Styles.LineColor, - parseColor(nmColor.substring(3))); - } - - String width = parseLineWidth(att(lineStyleEle, "stroke-width")); //$NON-NLS-1$ - registerStyle(host, Styles.LineWidth, width); - - String stroke = att(lineStyleEle, "draws-stroke"); //$NON-NLS-1$ - if (Boolean.parseBoolean(stroke)) - registerStyle(host, Styles.BorderLineWidth, "0"); //$NON-NLS-1$ - - String linePattern = att(lineStyleEle, "dash"); //$NON-NLS-1$ - registerStyle(host, Styles.LinePattern, parseLinePattern(linePattern)); - } - - private static String parseLinePattern(String linePattern) { - if (linePattern == null) - return Styles.LINE_PATTERN_SOLID; - - char c = linePattern.charAt(0); - - switch (c) { - case 'b': - case 'e': - case 'i': - case 'r': - return Styles.LINE_PATTERN_DASH; - case 'c': - case 'f': - case 'l': - case 's': - case 'y': - return Styles.LINE_PATTERN_DOT; - case 'd': - case 'g': - case 'j': - case 'm': - case 'o': - case 'p': - case 't': - case 'v': - case 'w': - return Styles.LINE_PATTERN_DASH_DOT; - case 'h': - case 'k': - case 'n': - case 'q': - case 'u': - case 'x': - return Styles.LINE_PATTERN_DASH_DOT_DOT; - } - - return Styles.LINE_PATTERN_SOLID; - } - - private static String parseLineWidth(String width) { - if (width == null) - return null; - - Float w = parseFloat(width.replace("pt", "")); //$NON-NLS-1$ //$NON-NLS-2$ - if (w != null) { - if (w <= 2) - return "1"; //$NON-NLS-1$ - if (w <= 4) - return "2"; //$NON-NLS-1$ - if (w <= 6) - return "3"; //$NON-NLS-1$ - if (w <= 8) - return "4"; //$NON-NLS-1$ - return "5"; //$NON-NLS-1$ - } - return null; - } - - private static Float parseFloat(String value) { - if (value != null) { - try { - return Float.valueOf(value); - } catch (Throwable e) { - } - } - return null; - } - - private void loadStructure(Element styleEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element layoutStyle = child(styleEle, "children-layout-style"); //$NON-NLS-1$ - if (layoutStyle == null) - return; - - topic.setStructureClass( - parseStructureType(topic, att(layoutStyle, "angle"), //$NON-NLS-1$ - att(layoutStyle, "layout-mode"))); //$NON-NLS-1$ - } - - private static String parseStructureType(ITopic topic, String angle, - String mode) { - if (mode != null && mode.equalsIgnoreCase("Radial")) { //$NON-NLS-1$ - return "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - } else { - if ("0".equals(angle)) //$NON-NLS-1$ - return "org.xmind.ui.logic.right"; //$NON-NLS-1$ - if ("90".equals(angle)) //$NON-NLS-1$ - return "org.xmind.ui.org-chart.down"; //$NON-NLS-1$ - if ("180".equals(angle)) //$NON-NLS-1$ - return "org.xmind.ui.logic.left"; //$NON-NLS-1$ - if ("270".equals(angle)) //$NON-NLS-1$ - return "org.xmind.ui.org-chart.up"; //$NON-NLS-1$ - } - - if (topic.getParent() != null) - return topic.getParent().getStructureClass(); - - return null; - } - - private void loadConnectionStyle(Element styleEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element connectionStyleEle = child(styleEle, - "children-connection-style"); //$NON-NLS-1$ - if (connectionStyleEle == null) - return; - - String type = att(connectionStyleEle, "connection-type"); //$NON-NLS-1$ - registerStyle(topic, Styles.LineClass, parseBranchConnection(type)); - } - - private static String parseBranchConnection(String lineShape) { - return getMapping("branchConnection", lineShape, //$NON-NLS-1$ - "org.xmind.branchConnection.curve"); //$NON-NLS-1$ - } - - private void loadNumbering(Element styleEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - Element numberingEle = child(styleEle, - "children-outline-numbering-style"); //$NON-NLS-1$ - if (numberingEle == null) - return; - - String depthValue = att(numberingEle, "depth"); //$NON-NLS-1$ - if (depthValue == null || "".equals(depthValue)) //$NON-NLS-1$ - return; - - INumbering numbering = topic.getNumbering(); - if ("0".equals(depthValue)) { //$NON-NLS-1$ - numbering.setFormat("org.xmind.numbering.none"); //$NON-NLS-1$ - return; - } - - int depth = Integer.parseInt(depthValue); - depth = depth == -1 ? 10 : depth; - - String format = "org.xmind.numbering.arabic"; //$NON-NLS-1$ - String separator = "org.xmind.numbering.separator.dot"; //$NON-NLS-1$ - String prefix = null; - String suffix = null; - - Element formatArrayEle = child(numberingEle, "format-array"); //$NON-NLS-1$ - if (formatArrayEle != null) { - Element formatEle = child(formatArrayEle, "outline-format"); //$NON-NLS-1$ - if (formatEle != null) { - format = parseNumberFormat(att(formatEle, "style")); //$NON-NLS-1$ - separator = parseNumberSeprator(att(formatEle, "separator")); //$NON-NLS-1$ - prefix = att(formatEle, "prefix"); //$NON-NLS-1$ - suffix = att(formatEle, "suffix"); //$NON-NLS-1$ - } - } - - numbering.setFormat(format); - numbering.setSeparator(separator); - numbering.setDepth(String.valueOf(depth)); - if (prefix != null) - numbering.setPrefix(prefix); - if (suffix != null) - numbering.setSuffix(suffix); - } - - private static String parseNumberFormat(String format) { - return getMapping("numberFormat", format, "org.xmind.numbering.arabic"); //$NON-NLS-1$//$NON-NLS-2$ - } - - private static String parseNumberSeprator(String seprator) { - return getMapping("numberSeprator", seprator, //$NON-NLS-1$ - "org.xmind.numbering.separator.dot"); //$NON-NLS-1$ - } - - private void loadBoundary(Element boundaryEle, ITopic topic) - throws InterruptedException { - checkInterrupted(); - - if (topic.isRoot()) - return; - - IBoundary boundary = getTargetWorkbook().createBoundary(); - if (topic.isAttached()) { - ITopic parent = topic.getParent(); - int index = topic.getIndex(); - boundary.setStartIndex(index); - boundary.setEndIndex(index); - parent.addBoundary(boundary); - } else { - boundary.setMasterBoundary(true); - topic.addBoundary(boundary); - } - - loadBoundaryStyle(boundaryEle, boundary); - } - - private void loadBoundaryStyle(Element boundaryEle, IBoundary boundary) - throws InterruptedException { - checkInterrupted(); - - Element nodeViewEle = child(boundaryEle, "topic-node-view"); //$NON-NLS-1$ - if (nodeViewEle == null) - return; - - Element nodeStyleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ - if (nodeStyleEle == null) - return; - - loadFillStyle(nodeStyleEle, boundary, "#fffce0bf"); //$NON-NLS-1$ - loadLineStyle(nodeStyleEle, boundary); - loadShapeStyle(nodeStyleEle, boundary); - } - - private void loadRelationships(Element relationshipsEle) - throws InterruptedException { - checkInterrupted(); - - Iterator relationshipEles = children(relationshipsEle, - "topic-node"); //$NON-NLS-1$ - - while (relationshipEles.hasNext()) - loadRelationship(relationshipEles.next()); - } - - private void loadRelationship(Element relationshipEle) - throws InterruptedException { - checkInterrupted(); - - Element relDataEle = child(relationshipEle, "link-line-data"); //$NON-NLS-1$ - if (relDataEle == null) - return; - - IRelationship rel = getTargetWorkbook().createRelationship(); - getTargetSheet().addRelationship(rel); - - loadConnections(relDataEle, rel, true); - - Element nodeViewEle = child(relationshipEle, "topic-node-view"); //$NON-NLS-1$ - if (nodeViewEle == null) - return; - - Element styleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ - if (styleEle == null) - return; - - loadLineStyle(styleEle, rel); - } - - private void loadConnections(Element relDataEle, IRelationship rel, - boolean autoRouting) throws InterruptedException { - checkInterrupted(); - - String startOId = att(relDataEle, "start-topic-node-ref"); //$NON-NLS-1$ - String endOId = att(relDataEle, "end-topic-node-ref"); //$NON-NLS-1$ - - String startId = topicIdMap.get(startOId); - String endId = topicIdMap.get(endOId); - - if (startId != null && endId != null) { - rel.setEnd1Id(startId); - rel.setEnd2Id(endId); - } - - // TODO control point -// String isAuto = att(relDataEle, "is-automatic-link-line"); //$NON-NLS-1$ -// if (!Boolean.parseBoolean(isAuto)) { -// Element cpsEle = child(relDataEle, "control-points"); //$NON-NLS-1$ -// if (cpsEle != null) { -// Iterator cpEles = children(cpsEle, "control-point"); //$NON-NLS-1$ -// int index = 0; -// while (cpEles.hasNext()) { -// String loc = att(cpEles.next(), "location"); //$NON-NLS-1$ -// String[] split = loc.split(","); //$NON-NLS-1$ -// Float x = parseFloat(split[0]); -// Float y = parseFloat(split[1]); -// if (x != null && y != null && x.floatValue() != 0 -// && y.floatValue() != 0) { -// rel.getControlPoint(index++).setPosition( -// mm2Dots(x.floatValue()), -// mm2Dots(y.floatValue())); -// } -// } -// -// } -// } - - Element startStyleEle = child(relDataEle, "start-terminator"); //$NON-NLS-1$ - if (startStyleEle != null) - registerStyle(rel, Styles.ArrowBeginClass, - parseRelTerminatorType(att(startStyleEle, "type"))); //$NON-NLS-1$ - - Element endStyleEle = child(relDataEle, "end-terminator");//$NON-NLS-1$ - if (endStyleEle != null) - registerStyle(rel, Styles.ArrowEndClass, - parseRelTerminatorType(att(endStyleEle, "type"))); //$NON-NLS-1$ - } - - private String parseRelTerminatorType(String type) { - return getMapping("arrowShape", type, null); //$NON-NLS-1$ - } - - private static String parseTopicShape(String nmShape) { - return getMapping("topicShape", nmShape, null); //$NON-NLS-1$ - } - - private static String parseCalloutShape(String nmShape) { - return getMapping("calloutShape", nmShape, null); //$NON-NLS-1$ - } - - private static String parseBoundaryShape(String nmShape) { - return getMapping("boundaryShape", nmShape, //$NON-NLS-1$ - "org.xmind.boundaryShape.polygon"); //$NON-NLS-1$ - } - - private void registerStyle(IStyled styleOwner, String key, String value) { - if (value == null) - return; - - IStyle style = styleMap.get(styleOwner); - if (style == null) { - style = getTempStyleSheet().createStyle(styleOwner.getStyleType()); - getTempStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); - styleMap.put(styleOwner, style); - } - if (Styles.TextDecoration.equals(key)) { - String oldValue = style.getProperty(key); - if (oldValue != null && !oldValue.contains(value)) { - boolean underline = oldValue - .contains(Styles.TEXT_DECORATION_UNDERLINE) - || value.contains(Styles.TEXT_DECORATION_UNDERLINE); - boolean strikeout = oldValue - .contains(Styles.TEXT_DECORATION_LINE_THROUGH) - || value.contains(Styles.TEXT_DECORATION_LINE_THROUGH); - value = StyleUtils.toTextDecoration(underline, strikeout); - } - } - style.setProperty(key, value); - } - - private IStyleSheet getTempStyleSheet() { - if (tempStyleSheet == null) { - tempStyleSheet = Core.getStyleSheetBuilder().createStyleSheet(); - ((StyleSheetImpl) tempStyleSheet) - .setManifest(getTargetWorkbook().getManifest()); - } - return tempStyleSheet; - } - - private void arrangeStyles() throws InterruptedException { - IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); - for (Entry en : styleMap.entrySet()) { - checkInterrupted(); - IStyled styleOwner = en.getKey(); - IStyle style = en.getValue(); - IStyle importedStyle = targetStyleSheet.importStyle(style); - if (importedStyle != null) { - styleOwner.setStyleId(importedStyle.getId()); - } - } - } - - private void loadTheme(Element themeEle) throws InterruptedException { - checkInterrupted(); - - loadSheetStyle(themeEle); - loadTopicTheme(themeEle); - loadRelTheme(themeEle); - loadBoundaryTheme(themeEle); - } - - private void loadSheetStyle(Element themeEle) throws InterruptedException { - checkInterrupted(); - - Element styleEle = child(themeEle, "background-style"); //$NON-NLS-1$ - if (styleEle == null) - return; - - ISheet sheet = getTargetSheet(); - - registerStyle(sheet, Styles.LineTapered, Styles.TAPERED); - - Element bgFillEle = child(styleEle, "solid-color"); //$NON-NLS-1$ - if (bgFillEle != null) { - String nmColor = att(bgFillEle, "color"); //$NON-NLS-1$ - if (nmColor != null) { - registerStyle(sheet, Styles.FillColor, - parseColor(realNmColor(nmColor).substring(3))); - } - } - - Element bgImageEle = child(styleEle, "texture-image"); //$NON-NLS-1$ - if (bgImageEle != null) { - IFileEntry entry = getResourceFileEntry(bgImageEle); - if (entry != null && entry.getSize() > 0) { - registerStyle(sheet, Styles.Background, - HyperlinkUtils.toAttachmentURL(entry.getPath())); - registerStyle(sheet, Styles.Opacity, - att(bgImageEle, "opacity")); //$NON-NLS-1$ - } - } - } - - private void loadTopicTheme(Element themeEle) throws InterruptedException { - checkInterrupted(); - - Element rootStyleEle = child(themeEle, "root-topic-style"); //$NON-NLS-1$ - if (rootStyleEle != null) - loadTopicTheme(rootStyleEle, Styles.FAMILY_CENTRAL_TOPIC, true); - - Element floatStyleEle = child(themeEle, "floating-topic-style"); //$NON-NLS-1$ - if (floatStyleEle != null) - loadTopicTheme(floatStyleEle, Styles.FAMILY_FLOATING_TOPIC, false); - - Element calloutStyleEle = child(themeEle, "callout-style"); //$NON-NLS-1$ - if (calloutStyleEle != null) - loadTopicTheme(calloutStyleEle, Styles.FAMILY_CALLOUT_TOPIC, false); - } - - private void loadTopicTheme(Element parentEle, String styleFamily, - boolean withChildren) throws InterruptedException { - checkInterrupted(); - - loadThemeFill(parentEle, IStyle.TOPIC, styleFamily); - loadThemeLineStyle(parentEle, IStyle.TOPIC, styleFamily); - loadThemeShapeStyle(parentEle, IStyle.TOPIC, styleFamily); - loadThemeTextStyle(parentEle, IStyle.TOPIC, styleFamily); - - Element childEle = child(parentEle, "children-default-style"); //$NON-NLS-1$ - if (withChildren && childEle != null) - loadTopicTheme(childEle, Styles.FAMILY_SUB_TOPIC, false); - } - - private void loadThemeFill(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - - Element fillStyleEle = child(parentEle, "fill-style"); //$NON-NLS-1$ - if (fillStyleEle != null) { - String nmColor = getFillValue(fillStyleEle); - if (nmColor != null) { - nmColor = realNmColor(nmColor); - String fillColor = parseColor(nmColor.substring(3)); - registerTheme(type, styleFamily, Styles.FillColor, fillColor); - } - } - } - - private void loadThemeTextStyle(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - Element textEle = child(parentEle, "text-style"); //$NON-NLS-1$ - if (textEle == null) - return; - - String nmColor = att(textEle, "font-color"); //$NON-NLS-1$ - if (nmColor != null) { - nmColor = realNmColor(nmColor); - registerTheme(type, styleFamily, Styles.TextColor, - parseColor(nmColor.substring(3))); - } - - registerTheme(type, styleFamily, Styles.FontSize, - parseFontSize(att(textEle, "font-size"))); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.FontWeight, - Boolean.parseBoolean(att(textEle, "bold")) //$NON-NLS-1$ - ? Styles.FONT_WEIGHT_BOLD : null); - registerTheme(type, styleFamily, Styles.FontStyle, - Boolean.parseBoolean(att(textEle, "italic")) //$NON-NLS-1$ - ? Styles.FONT_STYLE_ITALIC : null); - String textDecoration = StyleUtils.toTextDecoration( - att(textEle, "underline-style") != null, //$NON-NLS-1$ - att(textEle, "strikethrough-style") != null); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.TextDecoration, textDecoration); - - String alignment = att(textEle, "alignment"); //$NON-NLS-1$ - if (alignment != null) - registerTheme(type, styleFamily, Styles.TextAlign, - alignment.toLowerCase()); - - String fontName = att(textEle, "mac-font-name"); //$NON-NLS-1$ - if (fontName == null) - fontName = att(textEle, "windows-font-name"); //$NON-NLS-1$ - - if (fontName != null) { - String availableFontName = FontUtils - .getAAvailableFontNameFor(fontName); - fontName = availableFontName != null ? availableFontName : fontName; - registerTheme(type, styleFamily, Styles.FontFamily, fontName); - } - - } - - private void loadThemeLineStyle(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - - Element lineStyleEle = child(parentEle, "line-style"); //$NON-NLS-1$ - if (lineStyleEle == null) - return; - - String nmColor = att(lineStyleEle, "color"); //$NON-NLS-1$ - if (nmColor != null) { - nmColor = realNmColor(nmColor); - registerTheme(type, styleFamily, Styles.LineColor, nmColor); - } - - String width = parseLineWidth(att(lineStyleEle, "stroke-width")); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.LineWidth, width); - - String stroke = att(lineStyleEle, "draws-stroke"); //$NON-NLS-1$ - if (Boolean.parseBoolean(stroke)) - registerTheme(type, styleFamily, Styles.BorderLineWidth, "0"); //$NON-NLS-1$ - - String linePattern = att(lineStyleEle, "dash"); //$NON-NLS-1$ - registerTheme(type, styleFamily, Styles.LinePattern, linePattern); - } - - private void loadThemeShapeStyle(Element parentEle, String type, - String styleFamily) throws InterruptedException { - checkInterrupted(); - - Element shapeStyleEle = child(parentEle, "shape-style"); //$NON-NLS-1$ - if (shapeStyleEle == null) - return; - - if (IStyle.TOPIC.equals(type)) { - Element topicShapeEle = child(shapeStyleEle, "topic-shape-style"); //$NON-NLS-1$ - if (topicShapeEle != null) { - String shape = att(topicShapeEle, "type"); //$NON-NLS-1$ - if (Styles.FAMILY_CALLOUT_TOPIC.equals(styleFamily)) - registerTheme(type, styleFamily, Styles.CalloutShapeClass, - parseCalloutShape(shape)); - else - registerTheme(type, styleFamily, Styles.ShapeClass, - parseTopicShape(shape)); - } - - } - - if (IStyle.BOUNDARY.equals(type)) { - Element boundaryShapeEle = child(shapeStyleEle, - "boundary-shape-style"); //$NON-NLS-1$ - if (boundaryShapeEle != null) - registerTheme(type, styleFamily, Styles.ShapeClass, - parseBoundaryShape(att(boundaryShapeEle, "type"))); //$NON-NLS-1$ - - } - } - - private void loadRelTheme(Element themeEle) throws InterruptedException { - checkInterrupted(); - - Element relEle = child(themeEle, "link-link-style"); //$NON-NLS-1$ - if (relEle == null) - return; - - loadThemeLineStyle(relEle, IStyle.RELATIONSHIP, - Styles.FAMILY_RELATIONSHIP); - } - - private void loadBoundaryTheme(Element themeEle) - throws InterruptedException { - checkInterrupted(); - - Element boundaryEle = child(themeEle, "boundary-style-1"); //$NON-NLS-1$ - if (boundaryEle == null) - return; - - loadThemeShapeStyle(boundaryEle, IStyle.BOUNDARY, - Styles.FAMILY_BOUNDARY); - loadThemeFill(boundaryEle, IStyle.BOUNDARY, Styles.FAMILY_BOUNDARY); - loadThemeLineStyle(boundaryEle, IStyle.BOUNDARY, - Styles.FAMILY_BOUNDARY); - } - - private void registerTheme(String type, String styleFamily, String styleKey, - String styleValue) throws InterruptedException { - checkInterrupted(); - if (styleFamily == null || styleKey == null || styleValue == null) - return; - - if (theme == null) { - theme = getTempStyleSheet().createStyle(IStyle.THEME); - getTempStyleSheet().addStyle(theme, IStyleSheet.MASTER_STYLES); - } - - IStyle defaultStyle = theme.getDefaultStyle(styleFamily); - if (defaultStyle == null) { - defaultStyle = getTempStyleSheet().createStyle(type); - getTempStyleSheet().addStyle(defaultStyle, - IStyleSheet.AUTOMATIC_STYLES); - } - defaultStyle.setProperty(styleKey, styleValue); - } - - private void generateTheme() throws InterruptedException { - checkInterrupted(); - if (theme != null) { - IStyle importedTheme = getTargetWorkbook().getStyleSheet() - .importStyle(theme); - if (importedTheme != null) { - getTargetSheet().setThemeId(importedTheme.getId()); - } - } - } - - private void recordTopicLink(String OId, ITopic sourceTopic) { - List topics = topicLinkMap.get(OId); - if (topics == null) { - topics = new ArrayList(); - topicLinkMap.put(OId, topics); - } - topics.add(sourceTopic); - } - - private void setTopicLinks() { - for (Entry> en : topicLinkMap.entrySet()) { - String Oid = refIdMap.get(en.getKey()); - String id = topicIdMap.get(Oid); - if (id != null) { - for (ITopic topic : en.getValue()) { - topic.setHyperlink(HyperlinkUtils.toInternalURL(id)); - } - } - } - } - - private String getResourceTitle(Element originEle) - throws InterruptedException { - checkInterrupted(); - - Element resourceEle = findResourceEle(originEle); - if (resourceEle == null) - return null; - - return att(resourceEle, "original-filename"); //$NON-NLS-1$ - } - - private IFileEntry getResourceFileEntry(Element originEle) - throws InterruptedException { - checkInterrupted(); - - Element resourceEle = findResourceEle(originEle); - if (resourceEle == null) - return null; - - String url = att(resourceEle, "url"); //$NON-NLS-1$ - String name = att(resourceEle, "original-filename"); //$NON-NLS-1$ - if (url != null && !"".equals(url)) //$NON-NLS-1$ - return loadAttachment(RESOURCES_FOLDER + url, name); - - return null; - } - - private Element findResourceEle(Element originEle) - throws InterruptedException { - checkInterrupted(); - if (originEle == null) - return null; - - String resourceRef = att(originEle, "resource-ref"); //$NON-NLS-1$ - if (resourceRef == null || "".equals(resourceRef)) //$NON-NLS-1$ - return null; - - Element resourceEle = resourceRefMap.get(resourceRef); - if (resourceEle != null) - return resourceEle; - - Element resourcesEle = child(manifest.getDocumentElement(), - "resources"); //$NON-NLS-1$ - - if (resourcesEle == null) - return null; - - Iterator it = children(resourcesEle, "resource"); //$NON-NLS-1$ - - while (it.hasNext()) { - Element next = it.next(); - if (resourceRef.equals(att(next, "id"))) { //$NON-NLS-1$ - resourceRefMap.put(resourceRef, next); - return next; - } - } - - return null; - } - - @SuppressWarnings({ "deprecation", "resource" }) - private IFileEntry loadAttachment(String url, String proposalName) - throws InterruptedException { - checkInterrupted(); - - if (resourceMap.containsKey(url)) { - String path = resourceMap.get(url); - return path == null ? null - : getTargetWorkbook().getManifest().getFileEntry(path); - } - - InputStream nmEntryStream = tempSource.getEntryStream(url); - - if (nmEntryStream == null) - return null; - - if (proposalName != null) { - if (proposalName.startsWith("*.")) { //$NON-NLS-1$ - String ext = proposalName.substring(1); - String oldName = new File(url).getName(); - proposalName = FileUtils.getNoExtensionFileName(oldName) + ext; - } - } - - MonitoredInputStream in = new MonitoredInputStream(nmEntryStream, - getMonitor()); - - String path = null; - try { - IFileEntry entry = getTargetWorkbook().getManifest() - .createAttachmentFromStream(in, proposalName); - path = entry.getPath(); - } catch (Exception e) { - log(e, "Failed to create attachment from: " + url); //$NON-NLS-1$ - } finally { - try { - in.close(); - } catch (IOException e) { - } - } - - resourceMap.put(url, path); - return getTargetWorkbook().getManifest().getFileEntry(path); - } - - private static ITopicExtensionElement ensureTaskContent(ITopic topic, - ITopicExtensionElement taskContent) { - if (taskContent != null) - return taskContent; - ITopicExtension ext = topic.createExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ - return ext.getContent(); - } - - private Element findThemeEle(String themeRef) throws InterruptedException { - checkInterrupted(); - - if (themeRef == null || "".equals(themeRef)) //$NON-NLS-1$ - return null; - - Element themeEle = themeRefMap.get(themeRef); - if (themeEle != null) - return themeEle; - - if (styleSheet == null) - return null; - - Element styleSheetEle = styleSheet.getDocumentElement(); - if (styleSheetEle == null) - return null; - - Element themesEle = child(styleSheetEle, "themes"); //$NON-NLS-1$ - if (themesEle == null) - return null; - - Iterator it = children(themesEle, "theme"); //$NON-NLS-1$ - while (it.hasNext()) { - Element next = it.next(); - if (themeRef.equals(att(next, "id"))) { //$NON-NLS-1$ - themeRefMap.put(themeRef, next); - return next; - } - } - - return null; - } - - private String findAssign(String ref) throws InterruptedException { - checkInterrupted(); - - if (ref == null || "".equals(ref)) //$NON-NLS-1$ - return null; - - String assign = assignRefMap.get(ref); - if (assign != null) - return assign; - - Element contentEle = content.getDocumentElement(); - - Element resourcesEle = child(contentEle, "project-resources"); //$NON-NLS-1$ - if (resourcesEle == null) - return null; - - Iterator it = children(resourcesEle, "project-resource"); //$NON-NLS-1$ - - while (it.hasNext()) { - Element next = it.next(); - if (ref.equals(att(next, "id"))) { //$NON-NLS-1$ - String name = att(next, "name"); //$NON-NLS-1$ - assignRefMap.put(ref, name); - return name; - } - } - - return null; - } - - private static Element child(Element parentEle, String childTag) { - return children(parentEle, childTag).next(); - } - - private static Iterator children(final Element parentEle, - final String childTag) { - return new Iterator() { - - String tag = DOMUtils.getLocalName(childTag); - - Iterator it = DOMUtils.childElementIter(parentEle); - - Element next = findNext(); - - public void remove() { - } - - private Element findNext() { - while (it.hasNext()) { - Element ele = it.next(); - if (DOMUtils.getLocalName(ele.getTagName()) - .equalsIgnoreCase(tag)) { - return ele; - } - } - return null; - } - - public Element next() { - Element result = next; - next = findNext(); - return result; - } - - public boolean hasNext() { - return next != null; - } - }; - } - - private static String att(Element ele, String attName) { - if (ele.hasAttribute(attName)) - return ele.getAttribute(attName); - - attName = DOMUtils.getLocalName(attName); - NamedNodeMap atts = ele.getAttributes(); - for (int i = 0; i < atts.getLength(); i++) { - Node att = atts.item(i); - if (attName.equalsIgnoreCase( - DOMUtils.getLocalName(att.getNodeName()))) { - return att.getNodeValue(); - } - } - return null; - } - - private static int mm2Dots(float mm) { - return (int) (mm * DPM); - } - - private static String getMapping(String type, String sourceId, - String defaultId) { - if (sourceId != null) { - String destination = getMappings().getDestination(type, sourceId); - if (destination != null) - return destination; - } - return defaultId; - } - - private static ResourceMappingManager getMappings() { - if (mappings == null) - mappings = createMappings(); - - return mappings; - } - - private static ResourceMappingManager createMappings() { - return NovaMindResourceMappingManager.getInstance(); - } - - private static DocumentBuilder getDocumentBuilder() - throws ParserConfigurationException { - return DOMUtils.getDefaultDocumentBuilder(); - } - - public void error(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void fatalError(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void warning(SAXParseException exception) throws SAXException { - log(exception, null); - } - -} +package org.xmind.ui.internal.imports.novamind; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.osgi.util.NLS; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IBoundary; +import org.xmind.core.IFileEntry; +import org.xmind.core.IHtmlNotesContent; +import org.xmind.core.IHyperlinkSpan; +import org.xmind.core.IIdentifiable; +import org.xmind.core.IImage; +import org.xmind.core.INotes; +import org.xmind.core.INumbering; +import org.xmind.core.IParagraph; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISpan; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.Image; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.StyleSheetImpl; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IStorage; +import org.xmind.core.io.ResourceMappingManager; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.io.MonitoredInputStream; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.wizards.MindMapImporter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * @author lyn + */ + +public class NovaMindImporter extends MindMapImporter + implements NMConstants, ErrorHandler { + + private static final Pattern DATE_PATTERN = Pattern.compile( + "((\\d+)-(\\d{1,2})-(\\d{1,2}))T((\\d{1,2}):(\\d{1,2}):(\\d{1,2}))"); //$NON-NLS-1$ + + private static final String TRANSPARENT_VALUE = "0.00"; //$NON-NLS-1$ + + private static final double DPM = 1d; + + private static final String CONTENT_XML = "content.xml"; //$NON-NLS-1$ + + private static final String MANIFEST_XML = "manifest.xml"; //$NON-NLS-1$ + + private static final String STYLE_SHEET_XML = "style-sheet.xml"; //$NON-NLS-1$ + + private static final String SEP = File.separator; + + private static final String RESOURCES_FOLDER = "Resources" + SEP; //$NON-NLS-1$ + + private class NotesImporter { + + IParagraph currentParagraph = null; + + IHtmlNotesContent content; + + public NotesImporter(IHtmlNotesContent content) { + this.content = content; + } + + public void loadFrom(Element notesEle) throws InterruptedException { + checkInterrupted(); + + Element richTextEle = child(notesEle, "rich-text"); //$NON-NLS-1$ + if (richTextEle == null) + return; + + NodeList nl = richTextEle.getChildNodes(); + + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + String nodeName = node.getNodeName(); + if ("text-run".equals(nodeName)) { //$NON-NLS-1$ + loadText(node); + } else if ("hyperlink".equals(nodeName)) { //$NON-NLS-1$ + /// TODO add hyperlink to notes + + NamedNodeMap atts = node.getAttributes(); + Node href = atts.getNamedItem("url"); //$NON-NLS-1$ + IHyperlinkSpan linkSpan = content + .createHyperlinkSpan(href.getTextContent()); + addSpan(node, linkSpan); + + NodeList hnl = node.getChildNodes(); + for (int j = 0; j < hnl.getLength(); j++) { + Node hNode = hnl.item(j); + if (hNode != null + && "text-run".equals(hNode.getNodeName())) { //$NON-NLS-1$ + loadText(hNode); + } + } + } + } + } + + private void loadText(Node node) throws InterruptedException { + NodeList ps = node.getChildNodes(); + for (int pi = 0; pi < ps.getLength(); pi++) { + Node p = ps.item(pi); + if (p.getNodeType() == Node.TEXT_NODE) { + addText(node, p.getTextContent()); + } else if ("p".equals(p.getNodeName())) { //$NON-NLS-1$ + addParagraph(node); + } + } + } + + private void addText(Node node, String text) + throws InterruptedException { + if (text == null || "".equals(text)) //$NON-NLS-1$ + return; + + addSpan(node, content.createTextSpan(text)); + } + + private void addSpan(Node node, ISpan span) + throws InterruptedException { + if (currentParagraph == null) + addParagraph(node); + + currentParagraph.addSpan(span); + loadStyle(node, span); + loadAlign(node, currentParagraph); + } + + private void addParagraph(Node node) throws InterruptedException { + currentParagraph = content.createParagraph(); + content.addParagraph(currentParagraph); + loadAlign(node, currentParagraph); + } + + @SuppressWarnings({ "nls" }) + private void loadStyle(Node node, IStyled host) + throws InterruptedException { + checkInterrupted(); + + NamedNodeMap atts = node.getAttributes(); + + Node nmColorNode = atts.getNamedItem("font-color"); + if (nmColorNode != null) { + String nmColor = nmColorNode.getTextContent(); + nmColor = NovaMindImporter.this.realNmColor(nmColor); + registerStyle(host, Styles.TextColor, + parseColor(nmColor.substring(3))); + } + Node fontSizeNode = atts.getNamedItem("font-size"); + if (fontSizeNode != null) + registerStyle(host, Styles.FontSize, NovaMindImporter + .parseFontSize(fontSizeNode.getTextContent())); + + Node boldNode = atts.getNamedItem("bold"); + if (boldNode != null) + registerStyle(host, Styles.FontWeight, + Boolean.parseBoolean(boldNode.getTextContent()) + ? Styles.FONT_WEIGHT_BOLD : null); + + Node italicNode = atts.getNamedItem("italic"); + if (italicNode != null) + registerStyle(host, Styles.FontStyle, + Boolean.parseBoolean(italicNode.getTextContent()) + ? Styles.FONT_STYLE_ITALIC : null); + + String textDecoration = StyleUtils.toTextDecoration( + atts.getNamedItem("underline-style") != null, + atts.getNamedItem("strikethrough-style") != null); + registerStyle(host, Styles.TextDecoration, textDecoration); + + String fontName = null; + Node macFontNameNode = atts.getNamedItem("mac-font-name"); + if (macFontNameNode != null) + fontName = macFontNameNode.getTextContent(); + + if (fontName == null || "".equals(fontName)) { + Node windowsFontNameNode = atts + .getNamedItem("windows-font-name"); + if (windowsFontNameNode != null) + fontName = windowsFontNameNode.getTextContent(); + } + + if (fontName != null) { + String availableFontName = FontUtils + .getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName + : fontName; + registerStyle(host, Styles.FontFamily, fontName); + } + } + + private void loadAlign(Node node, IStyled host) + throws InterruptedException { + checkInterrupted(); + + NamedNodeMap atts = node.getAttributes(); + + Node alignmentNode = atts.getNamedItem("alignment"); //$NON-NLS-1$ + if (alignmentNode != null) + registerStyle(host, Styles.TextAlign, + alignmentNode.getTextContent().toLowerCase()); + } + + } + + private static ResourceMappingManager mappings = null; + + private IStorage tempStorage; + + private IInputSource tempSource; + + private Document content; + + private Document manifest; + + private Document styleSheet; + + private ISheet targetSheet; + + private Map styleMap = new HashMap(30); + + private IStyle theme = null; + + private IStyleSheet tempStyleSheet = null; + + private Map topicIdMap = new HashMap(30); + + private Map refIdMap = new HashMap(30); + + private Map> topicLinkMap = new HashMap>( + 10); + + private Map resourceRefMap = new HashMap(); + + private Map resourceMap = new HashMap(30); + + private Map themeRefMap = new HashMap(); + + private Map assignRefMap = new HashMap(); + + private NovaMindImporter(String sourcePath) { + super(sourcePath); + } + + public NovaMindImporter(String sourcePath, IWorkbook targetWorkbook) { + super(sourcePath, targetWorkbook); + } + + public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.IMPORT_FROM_NOVA_COUNT); + getMonitor().beginTask(null, 100); + try { + getMonitor() + .subTask(ImportMessages.MindManagerImporter_ReadingContent); + + tempStorage = createTemporaryStorage(); + extractSourceFileToTemporaryStorage(); + tempSource = tempStorage.getInputSource(); + + content = readFile(CONTENT_XML); + manifest = readFile(MANIFEST_XML); + styleSheet = readFile(STYLE_SHEET_XML); + + getMonitor().worked(45); + checkInterrupted(); + + getMonitor().subTask( + ImportMessages.MindManagerImporter_ReadingElements); + loadWorkbook(content.getDocumentElement()); + setTopicLinks(); + getMonitor().worked(45); + + checkInterrupted(); + getMonitor().subTask( + ImportMessages.MindManagerImporter_ArrangingStyles); + arrangeStyles(); + getMonitor().worked(5); + + checkInterrupted(); + getMonitor().subTask( + ImportMessages.MindManagerImporter_GeneratingTheme); + generateTheme(); + getMonitor().worked(5); + getMonitor().done(); + } catch (Exception e) { + throw new InvocationTargetException(e); + } finally { + clearTempStorage(); + } + postBuilded(); + } + + private Document readFile(String name) throws Exception { + InputStream docEntryStream = tempSource.getEntryStream(name); + if (docEntryStream == null) + throw new IOException("No content entry"); //$NON-NLS-1$ + + DocumentBuilder builder = getDocumentBuilder(); + builder.setErrorHandler(this); + InputStream in = new MonitoredInputStream(docEntryStream, getMonitor()); + Document doc; + try { + doc = builder.parse(in); + } finally { + builder.setErrorHandler(null); + try { + in.close(); + } catch (Exception e) { + } + } + return doc; + } + + private IStorage createTemporaryStorage() throws IOException { + String id = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", //$NON-NLS-1$ + System.currentTimeMillis()); + File tempDir = FileUtils.ensureDirectory(new File( + Core.getWorkspace().getTempDir("import/mindmanager"), id)); //$NON-NLS-1$ + return new DirectoryStorage(tempDir); + } + + private void extractSourceFileToTemporaryStorage() + throws IOException, CoreException { + FileInputStream fin = new FileInputStream(getSourcePath()); + try { + ZipInputStream zin = new ZipInputStream(new MonitoredInputStream( + new BufferedInputStream(fin), getMonitor())); + try { + FileUtils.extractZipFile(zin, tempStorage.getOutputTarget()); + } finally { + zin.close(); + } + } finally { + fin.close(); + } + + } + + private void checkInterrupted() throws InterruptedException { + if (getMonitor().isCanceled()) + throw new InterruptedException(); + } + + private void clearTempStorage() { + if (tempStorage != null) { + tempStorage.clear(); + tempStorage = null; + } + } + + private void loadWorkbook(Element docEle) throws InterruptedException { + checkInterrupted(); + + Element workbookEle = child(docEle, "maps"); //$NON-NLS-1$ + if (workbookEle == null) + return; + + Element sheetEle = child(workbookEle, "map"); //$NON-NLS-1$ + if (sheetEle == null) + return; + + loadSheet(sheetEle); + } + + private void loadSheet(Element sheetEle) throws InterruptedException { + checkInterrupted(); + + targetSheet = getTargetWorkbook().createSheet(); + + Element topicEle = child(sheetEle, "topic-node"); //$NON-NLS-1$ + if (topicEle != null) + loadRootTopic(topicEle); + + Element relationshipsEle = child(sheetEle, "link-lines"); //$NON-NLS-1$ + if (relationshipsEle != null) + loadRelationships(relationshipsEle); + + String themeRef = att(sheetEle, "theme-ref"); //$NON-NLS-1$ + Element themeEle = findThemeEle(themeRef); + if (themeEle != null) + loadTheme(themeEle); + + addTargetSheet(targetSheet); + } + + public ISheet getTargetSheet() { + return targetSheet; + } + + private void loadRootTopic(Element topicEle) throws InterruptedException { + checkInterrupted(); + + ITopic rootTopic = getTargetSheet().getRootTopic(); + loadTopic(topicEle, rootTopic); + + Element subTopicsEle = child(topicEle, "sub-topics"); //$NON-NLS-1$ + if (subTopicsEle != null) + loadSubElements(subTopicsEle, rootTopic); + } + + private void loadSubElements(Element topicsEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Iterator subElements = children(topicsEle, "topic-node"); //$NON-NLS-1$ + + while (subElements.hasNext()) { + Element subElement = subElements.next(); + + String type = att(subElement, "type"); //$NON-NLS-1$ + + if ("Boundary".equals(type)) { //$NON-NLS-1$ + loadBoundary(subElement, topic); + } else { + ITopic subTopic = addElement(topic, subElement, type); + + loadTopic(subElement, subTopic); + + Element subTopicsEle = child(subElement, "sub-topics"); //$NON-NLS-1$ + if (subTopicsEle != null) + loadSubElements(subTopicsEle, subTopic); + } + + } + } + + private void loadTopic(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + loadOId(topicEle, topic); + loadTopicContent(topicEle, topic); + + loadTopicNodeStyle(topicEle, topic); + } + + private ITopic addElement(ITopic topic, Element topicEle, String type) { + ITopic subTopic = getTargetWorkbook().createTopic(); + + if ("FloatingTopic".equals(type)) //$NON-NLS-1$ + topic.add(subTopic, ITopic.DETACHED); + else if ("Callout".equals(type)) //$NON-NLS-1$ + topic.add(subTopic, ITopic.CALLOUT); + else + topic.add(subTopic); + + return subTopic; + } + + private void loadOId(Element nmEle, IIdentifiable element) { + String OId = att(nmEle, "id"); //$NON-NLS-1$ + if (OId != null) + topicIdMap.put(OId, element.getId()); + } + + private void loadTopicContent(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + String id = att(topicEle, "id"); //$NON-NLS-1$ + String ref = att(topicEle, "topic-ref"); //$NON-NLS-1$ + refIdMap.put(ref, id); + Element contentEle = findTopicContentEle(ref); + if (contentEle == null) + return; + + loadTitleText(contentEle, topic); + loadNotes(contentEle, topic); + loadHyperlink(contentEle, topic); + loadAttachments(contentEle, topic); + loadImages(contentEle, topic); + loadTask(contentEle, topic); + } + + private Element findTopicContentEle(String refId) + throws InterruptedException { + checkInterrupted(); + + if (refId == null) + return null; + + Element contentEle = content.getDocumentElement(); + + Element topicsEle = child(contentEle, "topics"); //$NON-NLS-1$ + + if (topicsEle == null) + return null; + + Iterator topicEles = children(topicsEle, "topic"); //$NON-NLS-1$ + + while (topicEles.hasNext()) { + Element topic = topicEles.next(); + String id = att(topic, "id"); //$NON-NLS-1$ + + if (refId.equals(id)) + return topic; + } + + return null; + } + + private void loadTitleText(Element contentEle, ITopic topic) + throws InterruptedException { + Element text = child(contentEle, "rich-text"); //$NON-NLS-1$ + if (text == null) + return; + + Element titleRun = child(text, "text-run"); //$NON-NLS-1$ + if (titleRun == null) + return; + + topic.setTitleText(titleRun.getTextContent()); + loadTextStyle(titleRun, topic); + } + + private void loadNotes(Element contentEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element notesEle = child(contentEle, "notes"); //$NON-NLS-1$ + if (notesEle == null) + return; + + IHtmlNotesContent content = (IHtmlNotesContent) getTargetWorkbook() + .createNotesContent(INotes.HTML); + NotesImporter notesImporter = new NotesImporter(content); + notesImporter.loadFrom(notesEle); + topic.getNotes().setContent(INotes.HTML, content); + } + + private void loadHyperlink(Element contentEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element linksEle = child(contentEle, "links"); //$NON-NLS-1$ + if (linksEle == null) + return; + + Iterator it = children(linksEle, "link"); //$NON-NLS-1$ + + while (it.hasNext()) { + Element linkDataEle = it.next(); + String url = att(linkDataEle, "url"); //$NON-NLS-1$ + if (url == null) + continue; + + String name = att(linkDataEle, "display-name"); //$NON-NLS-1$ + if (name == null || "".equals(name)) //$NON-NLS-1$ + name = url; + ITopic linkTopic = getTargetWorkbook().createTopic(); + linkTopic.setTitleText(name); + topic.add(linkTopic); + + if (url.startsWith("novamind://topic/")) { //$NON-NLS-1$ + recordTopicLink(url.replace("novamind://topic/", ""), //$NON-NLS-1$//$NON-NLS-2$ + linkTopic); + continue; + } else if (!HyperlinkUtils.isLinkToWeb(url)) { + url = FilePathParser.toURI(url, false); + } + linkTopic.setHyperlink(url); + + } + } + + private void loadAttachments(Element contentEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + if (manifest == null) + return; + + Element attachmentsEle = child(contentEle, "attachments"); //$NON-NLS-1$ + if (attachmentsEle == null) + return; + + Iterator attachmentEles = children(attachmentsEle, + "attachment"); //$NON-NLS-1$ + + while (attachmentEles.hasNext()) { + Element attDataEle = attachmentEles.next(); + IFileEntry entry = getResourceFileEntry(attDataEle); + if (entry != null) { + ITopic attTopic = getTargetWorkbook().createTopic(); + String title = getResourceTitle(attDataEle); + attTopic.setTitleText(title == null + ? new File(entry.getPath()).getName() : title); + attTopic.setHyperlink( + HyperlinkUtils.toAttachmentURL(entry.getPath())); + topic.add(attTopic, ITopic.ATTACHED); + } + } + } + + private void loadImages(Element contentEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + if (manifest == null) + return; + + loadImage(contentEle, topic, "top-image", IImage.TOP, 0, 64); //$NON-NLS-1$ + loadImage(contentEle, topic, "bottom-image", IImage.BOTTOM, 0, 64); //$NON-NLS-1$ + loadImage(contentEle, topic, "left-image", Image.LEFT, 64, 0); //$NON-NLS-1$ + loadImage(contentEle, topic, "right-image", Image.RIGHT, 64, 0); //$NON-NLS-1$ + } + + private void loadImage(Element contentEle, ITopic topic, String imageAtt, + String alignment, int w, int h) throws InterruptedException { + Element imageEle = child(contentEle, imageAtt); + if (imageEle != null) { + IFileEntry entry = getResourceFileEntry(imageEle); + if (entry != null) { + String title = getResourceTitle(imageEle); + ITopic attTopic = getTargetWorkbook().createTopic(); + attTopic.setTitleText(title == null + ? new File(entry.getPath()).getName() : title); + IImage image = attTopic.getImage(); + image.setSource( + HyperlinkUtils.toAttachmentURL(entry.getPath())); + image.setAlignment(alignment); + image.setSize(w == 0 ? IImage.UNSPECIFIED : w, + h == 0 ? IImage.UNSPECIFIED : h); + topic.add(attTopic); + } + } + } + + private void loadTask(Element contentEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element taskEle = child(contentEle, "project-task"); //$NON-NLS-1$ + if (taskEle == null) + return; + + ITopicExtensionElement taskContent = null; + String priority = att(taskEle, "priority"); //$NON-NLS-1$ + loadMarker(topic, parsePriority(priority)); + + String pc = att(taskEle, "percentage-complete"); //$NON-NLS-1$ + loadMarker(topic, parsePercentage(pc)); + + if (pc != null) { + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("progress"); //$NON-NLS-1$ + ITopicExtensionElement ele = taskContent.createChild("progress"); //$NON-NLS-1$ + ele.setTextContent(pc); + } + + String start = att(taskEle, "start-time"); //$NON-NLS-1$ + if (start != null && !"".equals(start)) { //$NON-NLS-1$ + Matcher m = DATE_PATTERN.matcher(start); + if (m.find()) { + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("start-date"); //$NON-NLS-1$ + ITopicExtensionElement ele = taskContent + .createChild("start-date"); //$NON-NLS-1$ + ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ + } + } + + String end = att(taskEle, "end-time"); //$NON-NLS-1$ + if (end != null) { + Matcher m = DATE_PATTERN.matcher(end); + if (m.find()) { + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("end-date");//$NON-NLS-1$ + ITopicExtensionElement ele = taskContent + .createChild("end-date"); //$NON-NLS-1$ + ele.setTextContent(m.group(1) + " " + m.group(5)); //$NON-NLS-1$ + } + } + + String duration = att(taskEle, "duration"); //$NON-NLS-1$ + String dUnit = att(taskEle, "duration-unit"); //$NON-NLS-1$ + if (duration != null && !"".equals(duration)) { //$NON-NLS-1$ + String durationLabel = null; + if ("Years".equals(dUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Years_label, + duration); + } else if ("Months".equals(dUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Months_label, + duration); + } else if ("Weeks".equals(dUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Weeks_label, + duration); + } else if ("Hours".equals(dUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Hours_label, + duration); + } else if ("Minutes".equals(dUnit)) { //$NON-NLS-1$ + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Minutes_label, + duration); + } else { + durationLabel = NLS.bind( + ImportMessages.NovaMindImporter_Duration_Days_label, + duration); + } + + topic.addLabel( + NLS.bind(ImportMessages.NovaMindImporter_Duration_label, + durationLabel)); + } + + Element resourcesEle = child(taskEle, "assigned-resources"); //$NON-NLS-1$ + if (resourcesEle != null) { + Iterator it = children(resourcesEle, + "project-resource-ref"); //$NON-NLS-1$ + String assigns = ""; //$NON-NLS-1$ + while (it.hasNext()) { + Element next = it.next(); + String ref = next.getTextContent(); + assigns += findAssign(ref) + ","; //$NON-NLS-1$ + } + if (assigns != null && !"".equals(assigns)) { //$NON-NLS-1$ + assigns = assigns.substring(0, assigns.length() - 2); + taskContent = ensureTaskContent(topic, taskContent); + taskContent.deleteChildren("assigned-to");//$NON-NLS-1$ + ITopicExtensionElement ele = taskContent + .createChild("assigned-to"); //$NON-NLS-1$ + ele.setTextContent(assigns); + topic.addLabel( + NLS.bind(ImportMessages.NovaMindImporter_Resource_label, + assigns.replaceAll(",", ";"))); //$NON-NLS-1$//$NON-NLS-2$ + } + } + } + + private void loadMarker(ITopic topic, String markerId) + throws InterruptedException { + checkInterrupted(); + + if (markerId != null) + topic.addMarker(markerId); + } + + private static String parsePriority(String nmPriority) { + if (nmPriority == null) + return null; + + try { + int priority = Integer.parseInt(nmPriority); + switch (priority) { + case 1: + return "priority-1"; //$NON-NLS-1$ + case 2: + return "priority-2"; //$NON-NLS-1$ + case 3: + return "priority-3"; //$NON-NLS-1$ + case 4: + return "priority-4"; //$NON-NLS-1$ + case 5: + return "priority-5"; //$NON-NLS-1$ + case 6: + return "priority-6"; //$NON-NLS-1$ + case 7: + return "priority-7"; //$NON-NLS-1$ + case 8: + return "priority-8"; //$NON-NLS-1$ + case 9: + return "priority-9"; //$NON-NLS-1$ + } + } catch (NumberFormatException e) { + } + + return null; + } + + @SuppressWarnings("nls") + private static String parsePercentage(String nmPercentage) { + if (nmPercentage == null) + return null; + + try { + int pc = Integer.parseInt(nmPercentage); + if (pc < 12) + return "task-start"; + if (pc < 25) + return "task-oct"; + if (pc < 37) + return "task-quarter"; + if (pc < 50) + return "task-3oct"; + if (pc < 62) + return "task-half"; + if (pc < 75) + return "task-5oct"; + if (pc < 87) + return "task-3quar"; + if (pc < 100) + return "task-7oct"; + if (pc == 100) + return "task-done"; + } catch (NumberFormatException e) { + } + return null; + } + + private void loadTextStyle(Element titleEle, IStyled host) + throws InterruptedException { + checkInterrupted(); + + String nmColor = att(titleEle, "font-color"); //$NON-NLS-1$ + if (nmColor != null) { + nmColor = realNmColor(nmColor); + registerStyle(host, Styles.TextColor, + parseColor(nmColor.substring(3))); + } + + registerStyle(host, Styles.FontSize, + parseFontSize(att(titleEle, "font-size"))); //$NON-NLS-1$ + registerStyle(host, Styles.FontWeight, + Boolean.parseBoolean(att(titleEle, "bold")) //$NON-NLS-1$ + ? Styles.FONT_WEIGHT_BOLD : null); + registerStyle(host, Styles.FontStyle, + Boolean.parseBoolean(att(titleEle, "italic")) //$NON-NLS-1$ + ? Styles.FONT_STYLE_ITALIC : null); + String textDecoration = StyleUtils.toTextDecoration( + att(titleEle, "underline-style") != null, //$NON-NLS-1$ + att(titleEle, "strikethrough-style") != null); //$NON-NLS-1$ + registerStyle(host, Styles.TextDecoration, textDecoration); + String alignment = att(titleEle, "alignment"); //$NON-NLS-1$ + if (alignment != null) + registerStyle(host, Styles.TextAlign, alignment.toLowerCase()); + + String fontName = att(titleEle, "mac-font-name"); //$NON-NLS-1$ + if (fontName == null) + fontName = att(titleEle, "windows-font-name"); //$NON-NLS-1$ + + if (fontName != null) { + String availableFontName = FontUtils + .getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName : fontName; + registerStyle(host, Styles.FontFamily, fontName); + } + + } + + private void loadTopicNodeStyle(Element topicEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element nodeViewEle = child(topicEle, "topic-node-view"); //$NON-NLS-1$ + if (nodeViewEle == null) + return; + + loadPosition(nodeViewEle, topic); + + Element nodeStyleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ + if (nodeStyleEle == null) + return; + + loadFillStyle(nodeStyleEle, topic, null); + loadShapeStyle(nodeStyleEle, topic); + loadLineStyle(nodeStyleEle, topic); + loadStructure(nodeStyleEle, topic); + loadConnectionStyle(nodeStyleEle, topic); + loadNumbering(nodeStyleEle, topic); + } + + private void loadPosition(Element nodeViewEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + String location = att(nodeViewEle, "manual-location"); //$NON-NLS-1$ + if ((location == null || "".equals(location)) //$NON-NLS-1$ + && (ITopic.DETACHED.equals(topic.getType()) + || ITopic.CALLOUT.equals(topic.getType()))) + location = att(nodeViewEle, "location"); //$NON-NLS-1$ + + if (location == null || "".equals(location)) //$NON-NLS-1$ + return; + + String[] split = location.split(","); //$NON-NLS-1$ + if (split.length != 2) + return; + + Float x = parseFloat(split[0]); + Float y = parseFloat(split[1]); + if (x != null && y != null && x.floatValue() != 0 + && y.floatValue() != 0) { + topic.setPosition(mm2Dots(x), mm2Dots(y)); + } + } + + private void loadFillStyle(Element nodeStyleEle, IStyled host, + String defaultColor) throws InterruptedException { + checkInterrupted(); + + Element fillStyleEle = child(nodeStyleEle, "fill-style"); //$NON-NLS-1$ + if (fillStyleEle == null) + return; + + String nmColor = getFillValue(fillStyleEle); + if (nmColor == null) { + if (defaultColor == null) + return; + nmColor = defaultColor; + } + + nmColor = realNmColor(nmColor); + + String opacity = parseAlpha(nmColor); + String fillColor = parseColor(nmColor.substring(3)); + if (opacity != null && !opacity.equals(TRANSPARENT_VALUE)) + registerStyle(host, Styles.Opacity, opacity); + + if (fillColor != null) + registerStyle(host, Styles.FillColor, fillColor); + } + + private String realNmColor(String nmColor) { + if (!nmColor.startsWith("#")) //$NON-NLS-1$ + nmColor = getMapping("nmColor", nmColor, "#FFFFF"); //$NON-NLS-1$//$NON-NLS-2$ + return nmColor; + } + + private String getFillValue(Element fillStyleEle) + throws InterruptedException { + checkInterrupted(); + + String fillValue = null; + + Element advancedGradientEle = child(fillStyleEle, "advanced-gradient"); //$NON-NLS-1$ + if (advancedGradientEle != null) { + Element advancedColors = child(advancedGradientEle, "colors"); //$NON-NLS-1$ + if (advancedColors != null) { + Element colorEle = child(advancedColors, "color-stop"); //$NON-NLS-1$ + if (colorEle != null) + fillValue = att(colorEle, "color"); //$NON-NLS-1$ + } + } + + if (fillValue == null) { + Element simpleGradientEle = child(fillStyleEle, "simple-gradient"); //$NON-NLS-1$ + if (simpleGradientEle != null) { + String sColor = att(simpleGradientEle, "start-color"); //$NON-NLS-1$ + String eColor = att(simpleGradientEle, "end-color"); //$NON-NLS-1$ + fillValue = sColor != null ? sColor : eColor; + } + } + + if (fillValue == null) { + Element solidColorEle = child(fillStyleEle, "solid-color"); //$NON-NLS-1$ + if (solidColorEle != null) + fillValue = att(solidColorEle, "color"); //$NON-NLS-1$ + } + + return fillValue; + } + + private String parseAlpha(String color) { + if (color != null && color.startsWith("#")) { //$NON-NLS-1$ + try { + int alpha = Integer.parseInt(color.substring(1, 2), 16); + double opacity = ((double) alpha) * 100 / 255; + return String.format("%.2f", opacity); //$NON-NLS-1$ + } catch (Exception e) { + } + } + + return null; + } + + private static String parseColor(String color) { + if (color != null) { + int r; + int g; + int b; + try { + r = Integer.parseInt(color.substring(0, 2), 16); + g = Integer.parseInt(color.substring(2, 4), 16); + b = Integer.parseInt(color.substring(4, 6), 16); + return ColorUtils.toString(r, g, b); + } catch (Throwable t) { + } + } + return null; + } + + private static String parseFontSize(String size) { + if (size != null) { + try { + double value = Double.parseDouble(size); + size = StyleUtils.addUnitPoint((int) value); + } catch (Exception e) { + } + } + return size; + } + + private void loadShapeStyle(Element nodeStyleEle, IStyled host) + throws InterruptedException { + checkInterrupted(); + + Element shapeStyleEle = child(nodeStyleEle, "shape-style"); //$NON-NLS-1$ + if (shapeStyleEle == null) + return; + + if (host instanceof ITopic) { + Element topicShapeEle = child(shapeStyleEle, "topic-shape-style"); //$NON-NLS-1$ + if (topicShapeEle != null) { + String shape = att(topicShapeEle, "type"); //$NON-NLS-1$ + if (ITopic.CALLOUT.equals(((ITopic) host).getType())) + registerStyle(host, Styles.CalloutShapeClass, + parseCalloutShape(shape)); + else + registerStyle(host, Styles.ShapeClass, + parseTopicShape(shape)); + } + + } + + if (host instanceof IBoundary) { + Element boundaryShapeEle = child(shapeStyleEle, + "boundary-shape-style"); //$NON-NLS-1$ + if (boundaryShapeEle != null) + registerStyle(host, Styles.ShapeClass, + parseBoundaryShape(att(boundaryShapeEle, "type"))); //$NON-NLS-1$ + + } + + } + + private void loadLineStyle(Element nodeStyleEle, IStyled host) + throws InterruptedException { + checkInterrupted(); + + Element lineStyleEle = child(nodeStyleEle, "line-style"); //$NON-NLS-1$ + if (lineStyleEle == null) + return; + + String nmColor = att(lineStyleEle, "color"); //$NON-NLS-1$ + if (nmColor != null) { + nmColor = realNmColor(nmColor); + registerStyle(host, Styles.LineColor, + parseColor(nmColor.substring(3))); + } + + String width = parseLineWidth(att(lineStyleEle, "stroke-width")); //$NON-NLS-1$ + registerStyle(host, Styles.LineWidth, width); + + String stroke = att(lineStyleEle, "draws-stroke"); //$NON-NLS-1$ + if (Boolean.parseBoolean(stroke)) + registerStyle(host, Styles.BorderLineWidth, "0"); //$NON-NLS-1$ + + String linePattern = att(lineStyleEle, "dash"); //$NON-NLS-1$ + registerStyle(host, Styles.LinePattern, parseLinePattern(linePattern)); + } + + private static String parseLinePattern(String linePattern) { + if (linePattern == null) + return Styles.LINE_PATTERN_SOLID; + + char c = linePattern.charAt(0); + + switch (c) { + case 'b': + case 'e': + case 'i': + case 'r': + return Styles.LINE_PATTERN_DASH; + case 'c': + case 'f': + case 'l': + case 's': + case 'y': + return Styles.LINE_PATTERN_DOT; + case 'd': + case 'g': + case 'j': + case 'm': + case 'o': + case 'p': + case 't': + case 'v': + case 'w': + return Styles.LINE_PATTERN_DASH_DOT; + case 'h': + case 'k': + case 'n': + case 'q': + case 'u': + case 'x': + return Styles.LINE_PATTERN_DASH_DOT_DOT; + } + + return Styles.LINE_PATTERN_SOLID; + } + + private static String parseLineWidth(String width) { + if (width == null) + return null; + + Float w = parseFloat(width.replace("pt", "")); //$NON-NLS-1$ //$NON-NLS-2$ + if (w != null) { + if (w <= 2) + return "1"; //$NON-NLS-1$ + if (w <= 4) + return "2"; //$NON-NLS-1$ + if (w <= 6) + return "3"; //$NON-NLS-1$ + if (w <= 8) + return "4"; //$NON-NLS-1$ + return "5"; //$NON-NLS-1$ + } + return null; + } + + private static Float parseFloat(String value) { + if (value != null) { + try { + return Float.valueOf(value); + } catch (Throwable e) { + } + } + return null; + } + + private void loadStructure(Element styleEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element layoutStyle = child(styleEle, "children-layout-style"); //$NON-NLS-1$ + if (layoutStyle == null) + return; + + topic.setStructureClass( + parseStructureType(topic, att(layoutStyle, "angle"), //$NON-NLS-1$ + att(layoutStyle, "layout-mode"))); //$NON-NLS-1$ + } + + private static String parseStructureType(ITopic topic, String angle, + String mode) { + if (mode != null && mode.equalsIgnoreCase("Radial")) { //$NON-NLS-1$ + return "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + } else { + if ("0".equals(angle)) //$NON-NLS-1$ + return "org.xmind.ui.logic.right"; //$NON-NLS-1$ + if ("90".equals(angle)) //$NON-NLS-1$ + return "org.xmind.ui.org-chart.down"; //$NON-NLS-1$ + if ("180".equals(angle)) //$NON-NLS-1$ + return "org.xmind.ui.logic.left"; //$NON-NLS-1$ + if ("270".equals(angle)) //$NON-NLS-1$ + return "org.xmind.ui.org-chart.up"; //$NON-NLS-1$ + } + + if (topic.getParent() != null) + return topic.getParent().getStructureClass(); + + return null; + } + + private void loadConnectionStyle(Element styleEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element connectionStyleEle = child(styleEle, + "children-connection-style"); //$NON-NLS-1$ + if (connectionStyleEle == null) + return; + + String type = att(connectionStyleEle, "connection-type"); //$NON-NLS-1$ + registerStyle(topic, Styles.LineClass, parseBranchConnection(type)); + } + + private static String parseBranchConnection(String lineShape) { + return getMapping("branchConnection", lineShape, //$NON-NLS-1$ + "org.xmind.branchConnection.curve"); //$NON-NLS-1$ + } + + private void loadNumbering(Element styleEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + Element numberingEle = child(styleEle, + "children-outline-numbering-style"); //$NON-NLS-1$ + if (numberingEle == null) + return; + + String depthValue = att(numberingEle, "depth"); //$NON-NLS-1$ + if (depthValue == null || "".equals(depthValue)) //$NON-NLS-1$ + return; + + INumbering numbering = topic.getNumbering(); + if ("0".equals(depthValue)) { //$NON-NLS-1$ + numbering.setFormat("org.xmind.numbering.none"); //$NON-NLS-1$ + return; + } + + int depth = Integer.parseInt(depthValue); + depth = depth == -1 ? 10 : depth; + + String format = "org.xmind.numbering.arabic"; //$NON-NLS-1$ + String separator = "org.xmind.numbering.separator.dot"; //$NON-NLS-1$ + String prefix = null; + String suffix = null; + + Element formatArrayEle = child(numberingEle, "format-array"); //$NON-NLS-1$ + if (formatArrayEle != null) { + Element formatEle = child(formatArrayEle, "outline-format"); //$NON-NLS-1$ + if (formatEle != null) { + format = parseNumberFormat(att(formatEle, "style")); //$NON-NLS-1$ + separator = parseNumberSeprator(att(formatEle, "separator")); //$NON-NLS-1$ + prefix = att(formatEle, "prefix"); //$NON-NLS-1$ + suffix = att(formatEle, "suffix"); //$NON-NLS-1$ + } + } + + numbering.setFormat(format); + numbering.setSeparator(separator); + numbering.setDepth(String.valueOf(depth)); + if (prefix != null) + numbering.setPrefix(prefix); + if (suffix != null) + numbering.setSuffix(suffix); + } + + private static String parseNumberFormat(String format) { + return getMapping("numberFormat", format, "org.xmind.numbering.arabic"); //$NON-NLS-1$//$NON-NLS-2$ + } + + private static String parseNumberSeprator(String seprator) { + return getMapping("numberSeprator", seprator, //$NON-NLS-1$ + "org.xmind.numbering.separator.dot"); //$NON-NLS-1$ + } + + private void loadBoundary(Element boundaryEle, ITopic topic) + throws InterruptedException { + checkInterrupted(); + + if (topic.isRoot()) + return; + + IBoundary boundary = getTargetWorkbook().createBoundary(); + if (topic.isAttached()) { + ITopic parent = topic.getParent(); + int index = topic.getIndex(); + boundary.setStartIndex(index); + boundary.setEndIndex(index); + parent.addBoundary(boundary); + } else { + boundary.setMasterBoundary(true); + topic.addBoundary(boundary); + } + + loadBoundaryStyle(boundaryEle, boundary); + } + + private void loadBoundaryStyle(Element boundaryEle, IBoundary boundary) + throws InterruptedException { + checkInterrupted(); + + Element nodeViewEle = child(boundaryEle, "topic-node-view"); //$NON-NLS-1$ + if (nodeViewEle == null) + return; + + Element nodeStyleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ + if (nodeStyleEle == null) + return; + + loadFillStyle(nodeStyleEle, boundary, "#fffce0bf"); //$NON-NLS-1$ + loadLineStyle(nodeStyleEle, boundary); + loadShapeStyle(nodeStyleEle, boundary); + } + + private void loadRelationships(Element relationshipsEle) + throws InterruptedException { + checkInterrupted(); + + Iterator relationshipEles = children(relationshipsEle, + "topic-node"); //$NON-NLS-1$ + + while (relationshipEles.hasNext()) + loadRelationship(relationshipEles.next()); + } + + private void loadRelationship(Element relationshipEle) + throws InterruptedException { + checkInterrupted(); + + Element relDataEle = child(relationshipEle, "link-line-data"); //$NON-NLS-1$ + if (relDataEle == null) + return; + + IRelationship rel = getTargetWorkbook().createRelationship(); + getTargetSheet().addRelationship(rel); + + loadConnections(relDataEle, rel, true); + + Element nodeViewEle = child(relationshipEle, "topic-node-view"); //$NON-NLS-1$ + if (nodeViewEle == null) + return; + + Element styleEle = child(nodeViewEle, "topic-node-style"); //$NON-NLS-1$ + if (styleEle == null) + return; + + loadLineStyle(styleEle, rel); + } + + private void loadConnections(Element relDataEle, IRelationship rel, + boolean autoRouting) throws InterruptedException { + checkInterrupted(); + + String startOId = att(relDataEle, "start-topic-node-ref"); //$NON-NLS-1$ + String endOId = att(relDataEle, "end-topic-node-ref"); //$NON-NLS-1$ + + String startId = topicIdMap.get(startOId); + String endId = topicIdMap.get(endOId); + + if (startId != null && endId != null) { + rel.setEnd1Id(startId); + rel.setEnd2Id(endId); + } + + // TODO control point +// String isAuto = att(relDataEle, "is-automatic-link-line"); //$NON-NLS-1$ +// if (!Boolean.parseBoolean(isAuto)) { +// Element cpsEle = child(relDataEle, "control-points"); //$NON-NLS-1$ +// if (cpsEle != null) { +// Iterator cpEles = children(cpsEle, "control-point"); //$NON-NLS-1$ +// int index = 0; +// while (cpEles.hasNext()) { +// String loc = att(cpEles.next(), "location"); //$NON-NLS-1$ +// String[] split = loc.split(","); //$NON-NLS-1$ +// Float x = parseFloat(split[0]); +// Float y = parseFloat(split[1]); +// if (x != null && y != null && x.floatValue() != 0 +// && y.floatValue() != 0) { +// rel.getControlPoint(index++).setPosition( +// mm2Dots(x.floatValue()), +// mm2Dots(y.floatValue())); +// } +// } +// +// } +// } + + Element startStyleEle = child(relDataEle, "start-terminator"); //$NON-NLS-1$ + if (startStyleEle != null) + registerStyle(rel, Styles.ArrowBeginClass, + parseRelTerminatorType(att(startStyleEle, "type"))); //$NON-NLS-1$ + + Element endStyleEle = child(relDataEle, "end-terminator");//$NON-NLS-1$ + if (endStyleEle != null) + registerStyle(rel, Styles.ArrowEndClass, + parseRelTerminatorType(att(endStyleEle, "type"))); //$NON-NLS-1$ + } + + private String parseRelTerminatorType(String type) { + return getMapping("arrowShape", type, null); //$NON-NLS-1$ + } + + private static String parseTopicShape(String nmShape) { + return getMapping("topicShape", nmShape, null); //$NON-NLS-1$ + } + + private static String parseCalloutShape(String nmShape) { + return getMapping("calloutShape", nmShape, null); //$NON-NLS-1$ + } + + private static String parseBoundaryShape(String nmShape) { + return getMapping("boundaryShape", nmShape, //$NON-NLS-1$ + "org.xmind.boundaryShape.polygon"); //$NON-NLS-1$ + } + + private void registerStyle(IStyled styleOwner, String key, String value) { + if (value == null) + return; + + IStyle style = styleMap.get(styleOwner); + if (style == null) { + style = getTempStyleSheet().createStyle(styleOwner.getStyleType()); + getTempStyleSheet().addStyle(style, IStyleSheet.NORMAL_STYLES); + styleMap.put(styleOwner, style); + } + if (Styles.TextDecoration.equals(key)) { + String oldValue = style.getProperty(key); + if (oldValue != null && !oldValue.contains(value)) { + boolean underline = oldValue + .contains(Styles.TEXT_DECORATION_UNDERLINE) + || value.contains(Styles.TEXT_DECORATION_UNDERLINE); + boolean strikeout = oldValue + .contains(Styles.TEXT_DECORATION_LINE_THROUGH) + || value.contains(Styles.TEXT_DECORATION_LINE_THROUGH); + value = StyleUtils.toTextDecoration(underline, strikeout); + } + } + style.setProperty(key, value); + } + + private IStyleSheet getTempStyleSheet() { + if (tempStyleSheet == null) { + tempStyleSheet = Core.getStyleSheetBuilder().createStyleSheet(); + ((StyleSheetImpl) tempStyleSheet) + .setManifest(getTargetWorkbook().getManifest()); + } + return tempStyleSheet; + } + + private void arrangeStyles() throws InterruptedException { + IStyleSheet targetStyleSheet = getTargetWorkbook().getStyleSheet(); + for (Entry en : styleMap.entrySet()) { + checkInterrupted(); + IStyled styleOwner = en.getKey(); + IStyle style = en.getValue(); + IStyle importedStyle = targetStyleSheet.importStyle(style); + if (importedStyle != null) { + styleOwner.setStyleId(importedStyle.getId()); + } + } + } + + private void loadTheme(Element themeEle) throws InterruptedException { + checkInterrupted(); + + loadSheetStyle(themeEle); + loadTopicTheme(themeEle); + loadRelTheme(themeEle); + loadBoundaryTheme(themeEle); + } + + private void loadSheetStyle(Element themeEle) throws InterruptedException { + checkInterrupted(); + + Element styleEle = child(themeEle, "background-style"); //$NON-NLS-1$ + if (styleEle == null) + return; + + ISheet sheet = getTargetSheet(); + + registerStyle(sheet, Styles.LineTapered, Styles.TAPERED); + + Element bgFillEle = child(styleEle, "solid-color"); //$NON-NLS-1$ + if (bgFillEle != null) { + String nmColor = att(bgFillEle, "color"); //$NON-NLS-1$ + if (nmColor != null) { + registerStyle(sheet, Styles.FillColor, + parseColor(realNmColor(nmColor).substring(3))); + } + } + + Element bgImageEle = child(styleEle, "texture-image"); //$NON-NLS-1$ + if (bgImageEle != null) { + IFileEntry entry = getResourceFileEntry(bgImageEle); + if (entry != null && entry.getSize() > 0) { + registerStyle(sheet, Styles.Background, + HyperlinkUtils.toAttachmentURL(entry.getPath())); + registerStyle(sheet, Styles.Opacity, + att(bgImageEle, "opacity")); //$NON-NLS-1$ + } + } + } + + private void loadTopicTheme(Element themeEle) throws InterruptedException { + checkInterrupted(); + + Element rootStyleEle = child(themeEle, "root-topic-style"); //$NON-NLS-1$ + if (rootStyleEle != null) + loadTopicTheme(rootStyleEle, Styles.FAMILY_CENTRAL_TOPIC, true); + + Element floatStyleEle = child(themeEle, "floating-topic-style"); //$NON-NLS-1$ + if (floatStyleEle != null) + loadTopicTheme(floatStyleEle, Styles.FAMILY_FLOATING_TOPIC, false); + + Element calloutStyleEle = child(themeEle, "callout-style"); //$NON-NLS-1$ + if (calloutStyleEle != null) + loadTopicTheme(calloutStyleEle, Styles.FAMILY_CALLOUT_TOPIC, false); + } + + private void loadTopicTheme(Element parentEle, String styleFamily, + boolean withChildren) throws InterruptedException { + checkInterrupted(); + + loadThemeFill(parentEle, IStyle.TOPIC, styleFamily); + loadThemeLineStyle(parentEle, IStyle.TOPIC, styleFamily); + loadThemeShapeStyle(parentEle, IStyle.TOPIC, styleFamily); + loadThemeTextStyle(parentEle, IStyle.TOPIC, styleFamily); + + Element childEle = child(parentEle, "children-default-style"); //$NON-NLS-1$ + if (withChildren && childEle != null) + loadTopicTheme(childEle, Styles.FAMILY_SUB_TOPIC, false); + } + + private void loadThemeFill(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + + Element fillStyleEle = child(parentEle, "fill-style"); //$NON-NLS-1$ + if (fillStyleEle != null) { + String nmColor = getFillValue(fillStyleEle); + if (nmColor != null) { + nmColor = realNmColor(nmColor); + String fillColor = parseColor(nmColor.substring(3)); + registerTheme(type, styleFamily, Styles.FillColor, fillColor); + } + } + } + + private void loadThemeTextStyle(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + Element textEle = child(parentEle, "text-style"); //$NON-NLS-1$ + if (textEle == null) + return; + + String nmColor = att(textEle, "font-color"); //$NON-NLS-1$ + if (nmColor != null) { + nmColor = realNmColor(nmColor); + registerTheme(type, styleFamily, Styles.TextColor, + parseColor(nmColor.substring(3))); + } + + registerTheme(type, styleFamily, Styles.FontSize, + parseFontSize(att(textEle, "font-size"))); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.FontWeight, + Boolean.parseBoolean(att(textEle, "bold")) //$NON-NLS-1$ + ? Styles.FONT_WEIGHT_BOLD : null); + registerTheme(type, styleFamily, Styles.FontStyle, + Boolean.parseBoolean(att(textEle, "italic")) //$NON-NLS-1$ + ? Styles.FONT_STYLE_ITALIC : null); + String textDecoration = StyleUtils.toTextDecoration( + att(textEle, "underline-style") != null, //$NON-NLS-1$ + att(textEle, "strikethrough-style") != null); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.TextDecoration, textDecoration); + + String alignment = att(textEle, "alignment"); //$NON-NLS-1$ + if (alignment != null) + registerTheme(type, styleFamily, Styles.TextAlign, + alignment.toLowerCase()); + + String fontName = att(textEle, "mac-font-name"); //$NON-NLS-1$ + if (fontName == null) + fontName = att(textEle, "windows-font-name"); //$NON-NLS-1$ + + if (fontName != null) { + String availableFontName = FontUtils + .getAAvailableFontNameFor(fontName); + fontName = availableFontName != null ? availableFontName : fontName; + registerTheme(type, styleFamily, Styles.FontFamily, fontName); + } + + } + + private void loadThemeLineStyle(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + + Element lineStyleEle = child(parentEle, "line-style"); //$NON-NLS-1$ + if (lineStyleEle == null) + return; + + String nmColor = att(lineStyleEle, "color"); //$NON-NLS-1$ + if (nmColor != null) { + nmColor = realNmColor(nmColor); + registerTheme(type, styleFamily, Styles.LineColor, nmColor); + } + + String width = parseLineWidth(att(lineStyleEle, "stroke-width")); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.LineWidth, width); + + String stroke = att(lineStyleEle, "draws-stroke"); //$NON-NLS-1$ + if (Boolean.parseBoolean(stroke)) + registerTheme(type, styleFamily, Styles.BorderLineWidth, "0"); //$NON-NLS-1$ + + String linePattern = att(lineStyleEle, "dash"); //$NON-NLS-1$ + registerTheme(type, styleFamily, Styles.LinePattern, linePattern); + } + + private void loadThemeShapeStyle(Element parentEle, String type, + String styleFamily) throws InterruptedException { + checkInterrupted(); + + Element shapeStyleEle = child(parentEle, "shape-style"); //$NON-NLS-1$ + if (shapeStyleEle == null) + return; + + if (IStyle.TOPIC.equals(type)) { + Element topicShapeEle = child(shapeStyleEle, "topic-shape-style"); //$NON-NLS-1$ + if (topicShapeEle != null) { + String shape = att(topicShapeEle, "type"); //$NON-NLS-1$ + if (Styles.FAMILY_CALLOUT_TOPIC.equals(styleFamily)) + registerTheme(type, styleFamily, Styles.CalloutShapeClass, + parseCalloutShape(shape)); + else + registerTheme(type, styleFamily, Styles.ShapeClass, + parseTopicShape(shape)); + } + + } + + if (IStyle.BOUNDARY.equals(type)) { + Element boundaryShapeEle = child(shapeStyleEle, + "boundary-shape-style"); //$NON-NLS-1$ + if (boundaryShapeEle != null) + registerTheme(type, styleFamily, Styles.ShapeClass, + parseBoundaryShape(att(boundaryShapeEle, "type"))); //$NON-NLS-1$ + + } + } + + private void loadRelTheme(Element themeEle) throws InterruptedException { + checkInterrupted(); + + Element relEle = child(themeEle, "link-link-style"); //$NON-NLS-1$ + if (relEle == null) + return; + + loadThemeLineStyle(relEle, IStyle.RELATIONSHIP, + Styles.FAMILY_RELATIONSHIP); + } + + private void loadBoundaryTheme(Element themeEle) + throws InterruptedException { + checkInterrupted(); + + Element boundaryEle = child(themeEle, "boundary-style-1"); //$NON-NLS-1$ + if (boundaryEle == null) + return; + + loadThemeShapeStyle(boundaryEle, IStyle.BOUNDARY, + Styles.FAMILY_BOUNDARY); + loadThemeFill(boundaryEle, IStyle.BOUNDARY, Styles.FAMILY_BOUNDARY); + loadThemeLineStyle(boundaryEle, IStyle.BOUNDARY, + Styles.FAMILY_BOUNDARY); + } + + private void registerTheme(String type, String styleFamily, String styleKey, + String styleValue) throws InterruptedException { + checkInterrupted(); + if (styleFamily == null || styleKey == null || styleValue == null) + return; + + if (theme == null) { + theme = getTempStyleSheet().createStyle(IStyle.THEME); + getTempStyleSheet().addStyle(theme, IStyleSheet.MASTER_STYLES); + } + + IStyle defaultStyle = theme.getDefaultStyle(styleFamily); + if (defaultStyle == null) { + defaultStyle = getTempStyleSheet().createStyle(type); + getTempStyleSheet().addStyle(defaultStyle, + IStyleSheet.AUTOMATIC_STYLES); + } + defaultStyle.setProperty(styleKey, styleValue); + } + + private void generateTheme() throws InterruptedException { + checkInterrupted(); + if (theme != null) { + IStyle importedTheme = getTargetWorkbook().getStyleSheet() + .importStyle(theme); + if (importedTheme != null) { + getTargetSheet().setThemeId(importedTheme.getId()); + } + } + } + + private void recordTopicLink(String OId, ITopic sourceTopic) { + List topics = topicLinkMap.get(OId); + if (topics == null) { + topics = new ArrayList(); + topicLinkMap.put(OId, topics); + } + topics.add(sourceTopic); + } + + private void setTopicLinks() { + for (Entry> en : topicLinkMap.entrySet()) { + String Oid = refIdMap.get(en.getKey()); + String id = topicIdMap.get(Oid); + if (id != null) { + for (ITopic topic : en.getValue()) { + topic.setHyperlink(HyperlinkUtils.toInternalURL(id)); + } + } + } + } + + private String getResourceTitle(Element originEle) + throws InterruptedException { + checkInterrupted(); + + Element resourceEle = findResourceEle(originEle); + if (resourceEle == null) + return null; + + return att(resourceEle, "original-filename"); //$NON-NLS-1$ + } + + private IFileEntry getResourceFileEntry(Element originEle) + throws InterruptedException { + checkInterrupted(); + + Element resourceEle = findResourceEle(originEle); + if (resourceEle == null) + return null; + + String url = att(resourceEle, "url"); //$NON-NLS-1$ + String name = att(resourceEle, "original-filename"); //$NON-NLS-1$ + if (url != null && !"".equals(url)) //$NON-NLS-1$ + return loadAttachment(RESOURCES_FOLDER + url, name); + + return null; + } + + private Element findResourceEle(Element originEle) + throws InterruptedException { + checkInterrupted(); + if (originEle == null) + return null; + + String resourceRef = att(originEle, "resource-ref"); //$NON-NLS-1$ + if (resourceRef == null || "".equals(resourceRef)) //$NON-NLS-1$ + return null; + + Element resourceEle = resourceRefMap.get(resourceRef); + if (resourceEle != null) + return resourceEle; + + Element resourcesEle = child(manifest.getDocumentElement(), + "resources"); //$NON-NLS-1$ + + if (resourcesEle == null) + return null; + + Iterator it = children(resourcesEle, "resource"); //$NON-NLS-1$ + + while (it.hasNext()) { + Element next = it.next(); + if (resourceRef.equals(att(next, "id"))) { //$NON-NLS-1$ + resourceRefMap.put(resourceRef, next); + return next; + } + } + + return null; + } + + @SuppressWarnings({ "deprecation", "resource" }) + private IFileEntry loadAttachment(String url, String proposalName) + throws InterruptedException { + checkInterrupted(); + + if (resourceMap.containsKey(url)) { + String path = resourceMap.get(url); + return path == null ? null + : getTargetWorkbook().getManifest().getFileEntry(path); + } + + InputStream nmEntryStream = tempSource.getEntryStream(url); + + if (nmEntryStream == null) + return null; + + if (proposalName != null) { + if (proposalName.startsWith("*.")) { //$NON-NLS-1$ + String ext = proposalName.substring(1); + String oldName = new File(url).getName(); + proposalName = FileUtils.getNoExtensionFileName(oldName) + ext; + } + } + + MonitoredInputStream in = new MonitoredInputStream(nmEntryStream, + getMonitor()); + + String path = null; + try { + IFileEntry entry = getTargetWorkbook().getManifest() + .createAttachmentFromStream(in, proposalName); + path = entry.getPath(); + } catch (Exception e) { + log(e, "Failed to create attachment from: " + url); //$NON-NLS-1$ + } finally { + try { + in.close(); + } catch (IOException e) { + } + } + + resourceMap.put(url, path); + return getTargetWorkbook().getManifest().getFileEntry(path); + } + + private static ITopicExtensionElement ensureTaskContent(ITopic topic, + ITopicExtensionElement taskContent) { + if (taskContent != null) + return taskContent; + ITopicExtension ext = topic.createExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + return ext.getContent(); + } + + private Element findThemeEle(String themeRef) throws InterruptedException { + checkInterrupted(); + + if (themeRef == null || "".equals(themeRef)) //$NON-NLS-1$ + return null; + + Element themeEle = themeRefMap.get(themeRef); + if (themeEle != null) + return themeEle; + + if (styleSheet == null) + return null; + + Element styleSheetEle = styleSheet.getDocumentElement(); + if (styleSheetEle == null) + return null; + + Element themesEle = child(styleSheetEle, "themes"); //$NON-NLS-1$ + if (themesEle == null) + return null; + + Iterator it = children(themesEle, "theme"); //$NON-NLS-1$ + while (it.hasNext()) { + Element next = it.next(); + if (themeRef.equals(att(next, "id"))) { //$NON-NLS-1$ + themeRefMap.put(themeRef, next); + return next; + } + } + + return null; + } + + private String findAssign(String ref) throws InterruptedException { + checkInterrupted(); + + if (ref == null || "".equals(ref)) //$NON-NLS-1$ + return null; + + String assign = assignRefMap.get(ref); + if (assign != null) + return assign; + + Element contentEle = content.getDocumentElement(); + + Element resourcesEle = child(contentEle, "project-resources"); //$NON-NLS-1$ + if (resourcesEle == null) + return null; + + Iterator it = children(resourcesEle, "project-resource"); //$NON-NLS-1$ + + while (it.hasNext()) { + Element next = it.next(); + if (ref.equals(att(next, "id"))) { //$NON-NLS-1$ + String name = att(next, "name"); //$NON-NLS-1$ + assignRefMap.put(ref, name); + return name; + } + } + + return null; + } + + private static Element child(Element parentEle, String childTag) { + return children(parentEle, childTag).next(); + } + + private static Iterator children(final Element parentEle, + final String childTag) { + return new Iterator() { + + String tag = DOMUtils.getLocalName(childTag); + + Iterator it = DOMUtils.childElementIter(parentEle); + + Element next = findNext(); + + public void remove() { + } + + private Element findNext() { + while (it.hasNext()) { + Element ele = it.next(); + if (DOMUtils.getLocalName(ele.getTagName()) + .equalsIgnoreCase(tag)) { + return ele; + } + } + return null; + } + + public Element next() { + Element result = next; + next = findNext(); + return result; + } + + public boolean hasNext() { + return next != null; + } + }; + } + + private static String att(Element ele, String attName) { + if (ele.hasAttribute(attName)) + return ele.getAttribute(attName); + + attName = DOMUtils.getLocalName(attName); + NamedNodeMap atts = ele.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node att = atts.item(i); + if (attName.equalsIgnoreCase( + DOMUtils.getLocalName(att.getNodeName()))) { + return att.getNodeValue(); + } + } + return null; + } + + private static int mm2Dots(float mm) { + return (int) (mm * DPM); + } + + private static String getMapping(String type, String sourceId, + String defaultId) { + if (sourceId != null) { + String destination = getMappings().getDestination(type, sourceId); + if (destination != null) + return destination; + } + return defaultId; + } + + private static ResourceMappingManager getMappings() { + if (mappings == null) + mappings = createMappings(); + + return mappings; + } + + private static ResourceMappingManager createMappings() { + return NovaMindResourceMappingManager.getInstance(); + } + + private static DocumentBuilder getDocumentBuilder() + throws ParserConfigurationException { + return DOMUtils.getDefaultDocumentBuilder(); + } + + public void error(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void fatalError(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void warning(SAXParseException exception) throws SAXException { + log(exception, null); + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindResourceMappingManager.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindResourceMappingManager.java index 9637c3be1..d45f57df8 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindResourceMappingManager.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/NovaMindResourceMappingManager.java @@ -1,26 +1,26 @@ -package org.xmind.ui.internal.imports.novamind; - -import org.xmind.core.io.ResourceMappingManager; - -/** - * @author lyn - */ - -public class NovaMindResourceMappingManager { - - private static ResourceMappingManager instance = null; - - public static ResourceMappingManager getInstance() { - if (instance == null) { - try { - instance = ResourceMappingManager.createInstance( - NovaMindResourceMappingManager.class, "mappings.xml"); //$NON-NLS-1$ - } catch (Exception e) { - instance = ResourceMappingManager - .createEmptyInstance("NovaMind"); //$NON-NLS-1$ - } - } - return instance; - } - -} +package org.xmind.ui.internal.imports.novamind; + +import org.xmind.core.io.ResourceMappingManager; + +/** + * @author lyn + */ + +public class NovaMindResourceMappingManager { + + private static ResourceMappingManager instance = null; + + public static ResourceMappingManager getInstance() { + if (instance == null) { + try { + instance = ResourceMappingManager.createInstance( + NovaMindResourceMappingManager.class, "mappings.xml"); //$NON-NLS-1$ + } catch (Exception e) { + instance = ResourceMappingManager + .createEmptyInstance("NovaMind"); //$NON-NLS-1$ + } + } + return instance; + } + +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/mappings.xml b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/mappings.xml index 60d3e01e5..66ecba8fa 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/mappings.xml +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/novamind/mappings.xml @@ -1,122 +1,122 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlConstants.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlConstants.java index 1d2b66ed3..7b674cc9d 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlConstants.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlConstants.java @@ -1,11 +1,11 @@ -package org.xmind.ui.internal.imports.opml; - -public class OpmlConstants { - - public static final String ATT_URL = "url"; //$NON-NLS-1$ - public static final String TYPE_NOTE = "note"; //$NON-NLS-1$ - public static final String ATT_TEXT = "text"; //$NON-NLS-1$ - public static final String TYPE_HYPERLINK = "link"; //$NON-NLS-1$ - public static final String TAG_BODY = "body"; //$NON-NLS-1$ - public static final String ATT_TYPE = "type"; //$NON-NLS-1$ -} +package org.xmind.ui.internal.imports.opml; + +public class OpmlConstants { + + public static final String ATT_URL = "url"; //$NON-NLS-1$ + public static final String TYPE_NOTE = "note"; //$NON-NLS-1$ + public static final String ATT_TEXT = "text"; //$NON-NLS-1$ + public static final String TYPE_HYPERLINK = "link"; //$NON-NLS-1$ + public static final String TAG_BODY = "body"; //$NON-NLS-1$ + public static final String ATT_TYPE = "type"; //$NON-NLS-1$ +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImportWizard.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImportWizard.java index 1cf260963..cdeaeeae3 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImportWizard.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImportWizard.java @@ -1,76 +1,76 @@ -package org.xmind.ui.internal.imports.opml; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.imports.ImportMessages; -import org.xmind.ui.wizards.AbstractMindMapImportPage; -import org.xmind.ui.wizards.AbstractMindMapImportWizard; -import org.xmind.ui.wizards.MindMapImporter; - -public class OpmlImportWizard extends AbstractMindMapImportWizard { - - private static final String PAGE_ID = "importOPML"; //$NON-NLS-1$ - private static final String DOCUMENT_FILTER = "*.opml"; //$NON-NLS-1$ - private static final String DOCUMENT_EXT = "*.opml"; //$NON-NLS-1$ - - private class OpmlImportPage extends AbstractMindMapImportPage { - - protected OpmlImportPage() { - super(PAGE_ID, ImportMessages.OpmlImportWizard_windowTitle); - } - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 15; - composite.setLayout(layout); - setControl(composite); - - Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - - Control destinationControl = createDestinationControl(composite); - destinationControl.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - updateStatus(); - - parent.getDisplay().asyncExec(new Runnable() { - public void run() { - openBrowseDialog(); - } - }); - } - - protected FileDialog createBrowseDialog() { - FileDialog dialog = super.createBrowseDialog(); - dialog.setFilterExtensions(new String[] { DOCUMENT_FILTER }); - dialog.setFilterNames(new String[] { NLS.bind( - ImportMessages.OpmlImportPage_FilterName, DOCUMENT_EXT) }); - return dialog; - } - - } - - public void addPages() { - addPage(new OpmlImportPage()); - } - - @Override - protected MindMapImporter createImporter(String sourcePath, - IWorkbook targetWorkbook) { - return new OpmlImporter(sourcePath, targetWorkbook); - } - - @Override - protected String getApplicationId() { - return "Opml"; //$NON-NLS-1$ - } -} +package org.xmind.ui.internal.imports.opml; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.IWorkbook; +import org.xmind.ui.internal.imports.ImportMessages; +import org.xmind.ui.wizards.AbstractMindMapImportPage; +import org.xmind.ui.wizards.AbstractMindMapImportWizard; +import org.xmind.ui.wizards.MindMapImporter; + +public class OpmlImportWizard extends AbstractMindMapImportWizard { + + private static final String PAGE_ID = "importOPML"; //$NON-NLS-1$ + private static final String DOCUMENT_FILTER = "*.opml"; //$NON-NLS-1$ + private static final String DOCUMENT_EXT = "*.opml"; //$NON-NLS-1$ + + private class OpmlImportPage extends AbstractMindMapImportPage { + + protected OpmlImportPage() { + super(PAGE_ID, ImportMessages.OpmlImportWizard_windowTitle); + } + + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + composite.setLayout(layout); + setControl(composite); + + Control fileGroup = createFileControls(composite); + fileGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + + Control destinationControl = createDestinationControl(composite); + destinationControl.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + updateStatus(); + + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + openBrowseDialog(); + } + }); + } + + protected FileDialog createBrowseDialog() { + FileDialog dialog = super.createBrowseDialog(); + dialog.setFilterExtensions(new String[] { DOCUMENT_FILTER }); + dialog.setFilterNames(new String[] { NLS.bind( + ImportMessages.OpmlImportPage_FilterName, DOCUMENT_EXT) }); + return dialog; + } + + } + + public void addPages() { + addPage(new OpmlImportPage()); + } + + @Override + protected MindMapImporter createImporter(String sourcePath, + IWorkbook targetWorkbook) { + return new OpmlImporter(sourcePath, targetWorkbook); + } + + @Override + protected String getApplicationId() { + return "Opml"; //$NON-NLS-1$ + } +} diff --git a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImporter.java b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImporter.java index a00ab34d5..68b88748a 100644 --- a/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImporter.java +++ b/bundles/org.xmind.ui.imports/src/org/xmind/ui/internal/imports/opml/OpmlImporter.java @@ -1,182 +1,183 @@ -package org.xmind.ui.internal.imports.opml; - -import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_TEXT; -import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_TYPE; -import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_URL; -import static org.xmind.ui.internal.imports.opml.OpmlConstants.TAG_BODY; -import static org.xmind.ui.internal.imports.opml.OpmlConstants.TYPE_HYPERLINK; -import static org.xmind.ui.internal.imports.opml.OpmlConstants.TYPE_NOTE; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xmind.core.INotes; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.wizards.MindMapImporter; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public class OpmlImporter extends MindMapImporter implements ErrorHandler { - - private ISheet sheet; - - public OpmlImporter(String sourcePath, IWorkbook targetWorkbook) { - super(sourcePath, targetWorkbook); - } - - @Override - public void build() throws InvocationTargetException, InterruptedException { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ImportFromOpmlCount"); //$NON-NLS-1$ - InputStream in = null; - try { - DocumentBuilderFactory factory = DocumentBuilderFactory - .newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setErrorHandler(this); - in = new FileInputStream(getSourcePath()); - Document doc = builder.parse(in); - checkInterrupted(); - Element rootElement = doc.getDocumentElement(); - - loadSheet(rootElement); - - } catch (Throwable e) { - throw new InvocationTargetException(e); - } finally { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - postBuilded(); - } - - private void loadSheet(Element rootElement) throws InterruptedException { - checkInterrupted(); - IWorkbook targetWorkbook = getTargetWorkbook(); - sheet = targetWorkbook.createSheet(); - sheet.setTitleText("sheet1"); //$NON-NLS-1$ - NodeList nodelist = rootElement.getChildNodes(); - Element bodyEle = (Element) nodelist.item(1); - if (TAG_BODY.equals(bodyEle.getTagName())) { - loadAll(bodyEle); - } - addTargetSheet(sheet); - } - - private void loadAll(Element bodyEle) { - NodeList nodelist = bodyEle.getChildNodes(); - if (nodelist.getLength() > 1) - return; - - Node child = nodelist.item(0); - if (child instanceof Element) { - Element rootEle = (Element) child; - ITopic rootTopic = sheet.getRootTopic(); - dealRootTopic(rootEle, rootTopic); - loadTopic(rootEle, rootTopic); - } - } - - private void dealRootTopic(Element ele, ITopic rootTopic) { - rootTopic.setTitleText(att(ele, ATT_TEXT)); - } - - private void loadTopic(Element ele, ITopic parent) { - pushInMap(ele, parent); - if (TYPE_HYPERLINK.equals(att(ele, ATT_TYPE))) - loadHyperLink(ele, parent); - NodeList children = ele.getChildNodes(); - int lenght = children.getLength(); - for (int index = 0; index < lenght; index++) { - Node childNode = children.item(index); - if (childNode instanceof Element) { - Element child = (Element) childNode; - String type = att(child, ATT_TYPE); - if (TYPE_NOTE.equals(type)) - loadNotes(child, parent); - else { - ITopic topic = dealTopic(child, parent); - loadTopic(child, topic); - } - } - } - } - - private ITopic dealTopic(Element ele, ITopic parent) { - ITopic topic = getTargetWorkbook().createTopic(); - topic.setTitleText(att(ele, ATT_TEXT)); - parent.add(topic, ITopic.ATTACHED); - return topic; - } - - private void pushInMap(Element ele, ITopic parent) { - parent.setTitleText(att(ele, ATT_TEXT)); - } - - private String att(Element ele, String attTag) { - if (ele.hasAttribute(attTag)) - return ele.getAttribute(attTag); - return null; - } - - private void loadHyperLink(Element ele, ITopic topic) { - String link = att(ele, ATT_URL); - if (link != null && isLinkToWeb(link)) { - topic.setHyperlink(link); - } - } - - private void loadNotes(Element ele, ITopic parent) { - String text = att(ele, ATT_TEXT); - if (text != null && !text.trim().equals("")) { //$NON-NLS-1$ - IPlainNotesContent notesContent = (IPlainNotesContent) getTargetWorkbook() - .createNotesContent(INotes.PLAIN); - notesContent.setTextContent(text); - parent.getNotes().setContent(INotes.PLAIN, notesContent); - } - } - - private boolean isLinkToWeb(String hyperlink) { - if (hyperlink.contains("www.") || hyperlink.contains(".com") //$NON-NLS-1$//$NON-NLS-2$ - || hyperlink.contains(".cn") || hyperlink.contains(".org") //$NON-NLS-1$//$NON-NLS-2$ - || hyperlink.contains(".cc") || hyperlink.contains(".net") //$NON-NLS-1$//$NON-NLS-2$ - || hyperlink.contains(".ren")) { //$NON-NLS-1$ - return true; - } - return false; - } - - private void checkInterrupted() throws InterruptedException { - if (getMonitor().isCanceled()) - throw new InterruptedException(); - } - - public void warning(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void error(SAXParseException exception) throws SAXException { - log(exception, null); - } - - public void fatalError(SAXParseException exception) throws SAXException { - log(exception, null); - } -} +package org.xmind.ui.internal.imports.opml; + +import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_TEXT; +import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_TYPE; +import static org.xmind.ui.internal.imports.opml.OpmlConstants.ATT_URL; +import static org.xmind.ui.internal.imports.opml.OpmlConstants.TAG_BODY; +import static org.xmind.ui.internal.imports.opml.OpmlConstants.TYPE_HYPERLINK; +import static org.xmind.ui.internal.imports.opml.OpmlConstants.TYPE_NOTE; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xmind.core.INotes; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.wizards.MindMapImporter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class OpmlImporter extends MindMapImporter implements ErrorHandler { + + private ISheet sheet; + + public OpmlImporter(String sourcePath, IWorkbook targetWorkbook) { + super(sourcePath, targetWorkbook); + } + + @Override + public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.IMPORT_FROM_OPML_COUNT); + InputStream in = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setErrorHandler(this); + in = new FileInputStream(getSourcePath()); + Document doc = builder.parse(in); + checkInterrupted(); + Element rootElement = doc.getDocumentElement(); + + loadSheet(rootElement); + + } catch (Throwable e) { + throw new InvocationTargetException(e); + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + postBuilded(); + } + + private void loadSheet(Element rootElement) throws InterruptedException { + checkInterrupted(); + IWorkbook targetWorkbook = getTargetWorkbook(); + sheet = targetWorkbook.createSheet(); + sheet.setTitleText("sheet1"); //$NON-NLS-1$ + NodeList nodelist = rootElement.getChildNodes(); + Element bodyEle = (Element) nodelist.item(1); + if (TAG_BODY.equals(bodyEle.getTagName())) { + loadAll(bodyEle); + } + addTargetSheet(sheet); + } + + private void loadAll(Element bodyEle) { + NodeList nodelist = bodyEle.getChildNodes(); + if (nodelist.getLength() > 1) + return; + + Node child = nodelist.item(0); + if (child instanceof Element) { + Element rootEle = (Element) child; + ITopic rootTopic = sheet.getRootTopic(); + dealRootTopic(rootEle, rootTopic); + loadTopic(rootEle, rootTopic); + } + } + + private void dealRootTopic(Element ele, ITopic rootTopic) { + rootTopic.setTitleText(att(ele, ATT_TEXT)); + } + + private void loadTopic(Element ele, ITopic parent) { + pushInMap(ele, parent); + if (TYPE_HYPERLINK.equals(att(ele, ATT_TYPE))) + loadHyperLink(ele, parent); + NodeList children = ele.getChildNodes(); + int lenght = children.getLength(); + for (int index = 0; index < lenght; index++) { + Node childNode = children.item(index); + if (childNode instanceof Element) { + Element child = (Element) childNode; + String type = att(child, ATT_TYPE); + if (TYPE_NOTE.equals(type)) + loadNotes(child, parent); + else { + ITopic topic = dealTopic(child, parent); + loadTopic(child, topic); + } + } + } + } + + private ITopic dealTopic(Element ele, ITopic parent) { + ITopic topic = getTargetWorkbook().createTopic(); + topic.setTitleText(att(ele, ATT_TEXT)); + parent.add(topic, ITopic.ATTACHED); + return topic; + } + + private void pushInMap(Element ele, ITopic parent) { + parent.setTitleText(att(ele, ATT_TEXT)); + } + + private String att(Element ele, String attTag) { + if (ele.hasAttribute(attTag)) + return ele.getAttribute(attTag); + return null; + } + + private void loadHyperLink(Element ele, ITopic topic) { + String link = att(ele, ATT_URL); + if (link != null && isLinkToWeb(link)) { + topic.setHyperlink(link); + } + } + + private void loadNotes(Element ele, ITopic parent) { + String text = att(ele, ATT_TEXT); + if (text != null && !text.trim().equals("")) { //$NON-NLS-1$ + IPlainNotesContent notesContent = (IPlainNotesContent) getTargetWorkbook() + .createNotesContent(INotes.PLAIN); + notesContent.setTextContent(text); + parent.getNotes().setContent(INotes.PLAIN, notesContent); + } + } + + private boolean isLinkToWeb(String hyperlink) { + if (hyperlink.contains("www.") || hyperlink.contains(".com") //$NON-NLS-1$//$NON-NLS-2$ + || hyperlink.contains(".cn") || hyperlink.contains(".org") //$NON-NLS-1$//$NON-NLS-2$ + || hyperlink.contains(".cc") || hyperlink.contains(".net") //$NON-NLS-1$//$NON-NLS-2$ + || hyperlink.contains(".ren")) { //$NON-NLS-1$ + return true; + } + return false; + } + + private void checkInterrupted() throws InterruptedException { + if (getMonitor().isCanceled()) + throw new InterruptedException(); + } + + public void warning(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void error(SAXParseException exception) throws SAXException { + log(exception, null); + } + + public void fatalError(SAXParseException exception) throws SAXException { + log(exception, null); + } +} diff --git a/bundles/org.xmind.ui.menus/.classpath b/bundles/org.xmind.ui.menus/.classpath index eed015914..3c77224ca 100644 --- a/bundles/org.xmind.ui.menus/.classpath +++ b/bundles/org.xmind.ui.menus/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.menus/.gitignore b/bundles/org.xmind.ui.menus/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.menus/.gitignore +++ b/bundles/org.xmind.ui.menus/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.menus/.project b/bundles/org.xmind.ui.menus/.project index b59754328..5b3c084d6 100644 --- a/bundles/org.xmind.ui.menus/.project +++ b/bundles/org.xmind.ui.menus/.project @@ -1,28 +1,28 @@ - - - org.xmind.ui.menus - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.xmind.ui.menus + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.menus/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.core.prefs index 011bb91b2..6c315b64b 100644 --- a/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.core.prefs @@ -1,310 +1,310 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.ui.prefs index 5ff980f2f..6a418ff47 100644 --- a/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.menus/.settings/org.eclipse.jdt.ui.prefs @@ -1,3 +1,3 @@ -eclipse.preferences.version=1 -formatter_profile=_XMind Code Formatter -formatter_settings_version=12 +eclipse.preferences.version=1 +formatter_profile=_XMind Code Formatter +formatter_settings_version=12 diff --git a/bundles/org.xmind.ui.menus/.settings/org.eclipse.pde.prefs b/bundles/org.xmind.ui.menus/.settings/org.eclipse.pde.prefs index 0d1b69477..47b18cfeb 100644 --- a/bundles/org.xmind.ui.menus/.settings/org.eclipse.pde.prefs +++ b/bundles/org.xmind.ui.menus/.settings/org.eclipse.pde.prefs @@ -1,32 +1,32 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=1 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=1 -compilers.p.build.src.includes=1 -compilers.p.deprecated=1 -compilers.p.discouraged-class=2 -compilers.p.internal=1 -compilers.p.missing-packages=2 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=2 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/bundles/org.xmind.ui.menus/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.menus/META-INF/MANIFEST.MF index 49f933359..7b2ede3c4 100644 --- a/bundles/org.xmind.ui.menus/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.menus/META-INF/MANIFEST.MF @@ -1,18 +1,18 @@ -Manifest-Version: 1.0 -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.e4.ui.model.workbench, - org.eclipse.e4.ui.workbench, - org.xmind.core;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.spelling;bundle-version="[3.7.0,3.8.0)" -Bundle-ActivationPolicy: lazy -Bundle-Version: 3.7.0.qualifier -Bundle-Name: %Bundle-Name -Bundle-Activator: org.xmind.ui.menus.MenusPlugin -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.xmind.ui.menus;singleton:=true -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-Vendor: %Bundle-Vendor - +Manifest-Version: 1.0 +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.e4.ui.model.workbench, + org.eclipse.e4.ui.workbench, + org.xmind.core;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.spelling;bundle-version="[3.7.0,3.8.0)" +Bundle-ActivationPolicy: lazy +Bundle-Version: 3.7.0.qualifier +Bundle-Name: %Bundle-Name +Bundle-Activator: org.xmind.ui.menus.MenusPlugin +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.xmind.ui.menus;singleton:=true +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Vendor: %Bundle-Vendor + diff --git a/bundles/org.xmind.ui.menus/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.ui.menus/OSGI-INF/l10n/bundle.properties index b61864a4c..c48b5f8a3 100644 --- a/bundles/org.xmind.ui.menus/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.ui.menus/OSGI-INF/l10n/bundle.properties @@ -1,261 +1,261 @@ -#Properties file for org.xmind.ui.menus -menu.view.label = &View -menu.command.actualSize.label = &Actual Size -menu.command.zoomOut.label = Zoom &Out -menu.command.zoomIn.label = &Zoom In -menu.command.fitMap.label = &Fit Map -menu.command.fitSelection.label = Fit &Selection -menu.command.drillUp.label = Drill &Up -menu.command.drillDown.label = Drill &Down -menu.command.properties.label = &Properties -menu.command.markers.label = Mar&kers -menu.command.markers.tooltip = Markers -menu.command.Format.tooltip = Format -menu.command.theme.label = &Themes -menu.command.theme.tooltip = Themes -menu.command.editingHistory.label = Editing &History -menu.view.more.label = &More -menu.command.notes.label = &Notes -menu.command.notes.tooltip = Notes -menu.command.outline.label = Out&line -menu.command.outline.tooltip = Outline -menu.comamnd.overview.label = O&verview -menu.command.spelling.label = S&pelling Check -menu.command.blackbox.label = &Black Box -menu.command.lns.label = Local Net&work Sharing -menu.command.web.label = &Web Browser -menu.command.progress.label = &Progress -menu.insert.label = &Insert -menu.command.insertTopic.label = &Topic -menu.command.insertSubtopic.label = &Subtopic -menu.command.insertTopicBefore.Label = Topic B&efore -menu.command.insertParentTopic.label = &Parent Topic -menu.command.insertFloatingTopic.label = &Floating Topic -menu.command.insertFloatingCentralTopic.label = Floating '&Central' Topic -menu.insert.markers.label = Mar&kers -menu.insert.image.label = &Image -menu.command.insertImage.label = From &File... -menu.command.relationship.label = &Relationship -menu.command.boundary.label = &Boundary -menu.command.summary.label = Su&mmary -menu.command.attachment.label = &Attachment -menu.command.newSheet.label = &New Sheet -menu.command.insertSheetFrom.label = New S&heet From Topic -menu.command.newSheetFromTemplate.label=Ne&w Sheet From Template -menu.command.deleteSheet.label = &Delete Sheet -menu.modify.label = &Modify -menu.command.editTitle.label = &Title -menu.command.editLabel.label = &Label -menu.command.editNotes.label = &Notes -menu.command.hyperlink.label = &Hyperlink -menu.command.cancelHyperlink.label = Cancel H&yperlink -menu.command.openHyperlink.label = &Open Hyperlink -menu.command.saveAttachmentAs.label = Save Attach&ment As... -menu.command.saveAudioNoteAs.label = Save Audio Note As... -menu.command.extend.label = &Extend -menu.command.collapse.label = &Collapse -menu.command.extendAll.label = E&xtend All -menu.command.collapseAll.label = Colla&pse All -menu.command.tile.label = T&ile -menu.command.resetPosition.label = &Reset Position -menu.modify.alignment.label = &Align Floating Topic -menu.command.alignmentLeft.label = &Left -menu.command.alignmentCencer.label = &Center -menu.command.alignmentRight.label = &Right -menu.command.alignmentTop.label = &Top -menu.command.alignmentMiddle.label = &Middle -menu.command.alignmentBottom.label = &Bottom -menu.modify.sort.label = &Sort -menu.command.sort.title.label = By &Title -menu.command.sort.priority.label = By &Priority -menu.command.sort.modified.label = By &Modified Time -menu.tools.label = &Tools -menu.command.importWorkbook.label = Import XMind &Workbook -menu.command.inspector.label = Inspector -menu.command.removeAllStyles = Remove All Styles -toolbar.label = Toolbar -toolbar.command.newWorkbook.label = New -toolbar.command.newWorkbook.tooltip = New -toolbar.command.save.label = Save -toolbar.command.insertTopic.label = Topic -toolbar.command.insertTopic.tooltip = Insert A Topic -toolbar.command.boundary.tooltip = Boundary -toolbar.command.summary.tooltip = Summary -toolbar.command.relationship.tooltip = Relationship -toolbar.command.addMarker.label = Markers -toolbar.command.markers.label = Markers -toolbar.command.insertImage.label = Image -toolbar.command.insertImage.tooltip = Image -toolbar.command.attachment.tooltip = Attachment -toolbar.command.editLabel.tooltip = Label -toolbar.command.editNotes.tooltip = Notes -toolbar.command.hyperlink.tooltip = Hyperlink -toolbar.command.drillDown.tooltip = Drill Down -toolbar.command.drillUp.tooltip = Drill Up -toolbar.command.properties.tooltip = Properties -toolbar.command.theme.label = Themes -toolbar.command.theme.tooltip = Themes -toolbar.command.editingHistory.label = Editing History -toolbar.command.search.label = Search -toolbar.command.search.tooltip = Search the whole workbook -toolbar.command.upload.label = Upload -toolbar.command.upload.tooltip = Upload and share via XMind.net -toolbar.command.export.tooltip = Export -toolbar.command.preferences.tooltip = Preferences -toolbar.command.upgrade.label = Upgrade -toolbar.new.command.newWorkbook.label = Blank Map (Default) -toolbar.new.command.newWorkbookWizard.label = From Templates -toolbar.topic.label=Topic -toolbar.topic.tooltip=Topic -toolbar.insert.label=More to Insert -toolbar.insert.tooltip=Insert -toolbar.theme.label=Themes -toolbar.theme.tooltip=Themes -toolbar.marker.label=Markers -toolbar.marker.tooltip=Markers -toolbar.topic.command.insertTopic.label = Topic After (Default) -toolbar.topic.command.insertSubtopic.label = Subtopic -toolbar.topic.command.insertTopicBefore.label = Topic Before -toolbar.topic.command.insertParentTopic.label = Parent Topic -toolbar.image.command.insertImage.label = From File... -toolbar.image.command.insertImage.tooltip = Insert image from local file -popup.command.editTitle.label = &Edit Title -popup.command.insertFloatingTopic.label = &Floating Topic -popup.command.insertFloatingCentralTopic.label = Floating &Central Topic -popup.command.relationship.label = &Relationship -popup.command.boundary.label = &Boundary -popup.command.summary.label = &Summary -popup.command.drillDown.label = Drill Do&wn -popup.insert.label = &Insert -popup.insert.command.insertTopic.label = &Topic -popup.insert.command.isnertSubtopic.label = &Subtopic -popup.insert.command.insertTopicBefore.label = Topic &Before -popup.insert.command.insertParentTopic.label = &Parent Topic -popup.insert.image.label = &Image -popup.insert.image.command.insertIamge.label = From &File... -popup.insert.image.command.insertIamge.tooltip = Insert image from local file -popup.insert.command.relationship.label = &Relationship -popup.insert.command.boundary.label = Boun&dary -popup.insert.command.summary.label = Su&mmary -popup.insert.command.attachment.label = &Attachment -popup.insert.command.editLabel.label = &Label -popup.insert.command.insertSheetFrom.label = &New Sheet From Topic -popup.markers.label = &Markers -popup.command.insertTopic.label = &Topic -popup.sort.label = &Sort -popup.command.editNotes.label = &Notes -popup.command.hyperlink.label = &Hyperlink -popup.command.alignment.label = &Align Floating Topic -popup.command.clearmarkers.label = Clear Markers -popup.command.copyStyle.label = Copy Style -popup.command.pasteStyle.label = Paste Style -popup.command.duplicate.label = Dup&licate -toolbar.command.openWorkbook.tooltip = Open -toolbar.model.label = Model -toolbar.resource.label = Resource -toolbar.drillDown.label = Drill Down -toolbar.export.label = Export -toolbar.preferences.label = Preferences -toolbar.upgrade.label = Upgrade -popup.command.structure.label = Str&ucture -menu.file.command.editingHistory.label = Editing History -popup.command.saveImageAs.label = Save Image As... -popup.command.saveAttachmentAs.label = Save Attachment As... -popup.command.saveAudioNoteAs.label = Save Audio Note As... -menu.command.comments.label = Comments -menu.command.comments.tooltip = Comments -menu.command.editComments.label = Comments -toolbar.command.editComments.tooltip = Comments -popup.command.editComments.label = Comments -menu.edit.command.duplicate.label = Duplica&te -popup.command.cut.label = Cu&t -popup.command.copy.label = &Copy -popup.command.paste.label = &Paste -popup.command.delete.label=&Delete -popup.insert.command.newSheetFromTemplate.label = Ne&w Sheet From Template -popup.command.extendAll.label = &Extend All -popup.command.collapseAll.label = Collapse &All -popup.command.drillUp.label = Drill &Up -popup.command.tile.label = &Tile -popup.command.properties.label = Pr&operties -menu.edit.command.goHome.label = &Go Central -menu.edit.command.selectBrothers.label = Select &Brothers -menu.edit.command.selectChildren.label = &Select Children -menu.file.command.saveSheetAs.label = Sav&e Sheet As... -menu.file.command.saveTemplateAs.label = Save As &Template... -menu.file.command.upload.label = Share o&n XMind.net -menu.file.command.import.label = &Import... -menu.file.command.export.label = Ex&port... -menu.file.command.reduceFileSize.label = Reduce &File Size - -menu.command.insertCallout.label = Callo&ut -toolbar.command.insertCallout.tooltip = Callout -popup.command.insertCallout.label = &Callout -toolbar.command.allmarkers.tooltip = Markers - -menu.insert.marker.more.label = More... -menu.modify.saveImageAs.label = &Save Image As... -menu.window.label = &Window -menu.window.resetPerspective.label = &Reset Perspective -menu.file.newBlankMap.label = New &Blank Map -menu.file.open.label = &Open... -menu.file.openHomeMap.label = Open &Home Map -menu.file.openRecent.label = Open Recent -menu.file.recentMenu.clear.label = Clear This List -menu.file.checkSpelling.label = &Check Spelling -popup.makersMenu.more.label = More... -popup.resetStyle.label = Reset Style -popup.removeMarker.label = Remove From All Topics -toolbar.mindmap.insertCallout.label = Callout -toolbar.mindmap.insertCallout.tooltip = Callout -toolbar.mindmap.relationship.label = Relationship -toolbar.mindmap.relationship.tooltip = Relationship -toolbar.mindmap.boundary.label = Boundary -toolbar.mindmap.boundary.tooltip = Boundary -toolbar.mindmap.summary.label = Summary -toolbar.mindmap.summary.tooltip = Summary -toolbar.mindmap.comment.label = Comments -toolbar.mindmap.comment.tooltip = Comments -toolbar.mindmap.insert.markerMenu.marker.label = &Marker -toolbar.mindmap.insert.markerMenu.more.label = More... -toolbar.mindmap.insert.imageMenu.image.label = &Images -toolbar.mindmap.insert.image.file.label = From &File... -toolbar.mindmap.insert.label.label = &Label -toolbar.mindmap.insert.notes.label = &Notes -toolbar.mindmap.insert.hyperlink.label = &Hyperlink -toolbar.mindmap.insert.attachment.label = &Attachment -toolbar.export.image.label = Image... -Bundle-Vendor = XMind Ltd. -Bundle-Name = Menu/Toolbar Contributions for XMind RCP -menu.cloud.label = XMind Cloud -menu.share.label = Share -toolbar.share.label = Share -popup.newFromTemplate.label = New Sheet From Template -popup.colofurSheet.label = Colorful Tab -command.editNotes.label = &Notes -command.editLabel.label = &Label -command.editComments.label = Comments -command.editHyperlink.label = &Hyperlink -command.insertAttachment.label = &Attachment -command.showFormat.label = Format -command.showResourceManager.label = Resource Manager -command.showResourceManager.tooltip = Show Resource Manager Dialog -command.share.label = Share -command.showProperties.label = Format -command.newFromTemplate.label = New Sheet From Template -menu.cloorfulSheet.label = Colorful Tab -handledtoolitem.label.outline = Outline -handledtoolitem.tooltip.outline = Outline -handledtoolitem.label.format = Format -handledtoolitem.tooltip.format = Format -handledtoolitem.label.image = Image -handledtoolitem.tooltip.image = Image -handledtoolitem.label.themes = Themes -handledtoolitem.tooltip.themes = Themes -handledtoolitem.label.notes = Notes -handledtoolitem.tooltip.notes = Notes -handledtoolitem.label.comments = Comments -handledtoolitem.tooltip.comments = Comments - -handledtoolitem.label.marker = Marker -handledtoolitem.tooltip.marker = Marker +#Properties file for org.xmind.ui.menus +menu.view.label = &View +menu.command.actualSize.label = &Actual Size +menu.command.zoomOut.label = Zoom &Out +menu.command.zoomIn.label = &Zoom In +menu.command.fitMap.label = &Fit Map +menu.command.fitSelection.label = Fit &Selection +menu.command.drillUp.label = Drill &Up +menu.command.drillDown.label = Drill &Down +menu.command.properties.label = &Properties +menu.command.markers.label = Mar&kers +menu.command.markers.tooltip = Markers +menu.command.Format.tooltip = Format +menu.command.theme.label = &Themes +menu.command.theme.tooltip = Themes +menu.command.editingHistory.label = Editing &History +menu.view.more.label = &More +menu.command.notes.label = &Notes +menu.command.notes.tooltip = Notes +menu.command.outline.label = Out&line +menu.command.outline.tooltip = Outline +menu.comamnd.overview.label = O&verview +menu.command.spelling.label = S&pelling Check +menu.command.blackbox.label = &Black Box +menu.command.lns.label = Local Net&work Sharing +menu.command.web.label = &Web Browser +menu.command.progress.label = &Progress +menu.insert.label = &Insert +menu.command.insertTopic.label = &Topic +menu.command.insertSubtopic.label = &Subtopic +menu.command.insertTopicBefore.Label = Topic B&efore +menu.command.insertParentTopic.label = &Parent Topic +menu.command.insertFloatingTopic.label = &Floating Topic +menu.command.insertFloatingCentralTopic.label = Floating '&Central' Topic +menu.insert.markers.label = Mar&kers +menu.insert.image.label = &Image +menu.command.insertImage.label = Image From &File... +menu.command.relationship.label = &Relationship +menu.command.boundary.label = &Boundary +menu.command.summary.label = Su&mmary +menu.command.attachment.label = &Attachment +menu.command.newSheet.label = &New Sheet +menu.command.insertSheetFrom.label = New S&heet From Topic +menu.command.newSheetFromTemplate.label=Ne&w Sheet From Template +menu.command.deleteSheet.label = &Delete Sheet +menu.modify.label = &Modify +menu.command.editTitle.label = &Title +menu.command.editLabel.label = &Label +menu.command.editNotes.label = &Notes +menu.command.hyperlink.label = &Hyperlink +menu.command.cancelHyperlink.label = Cancel H&yperlink +menu.command.openHyperlink.label = &Open Hyperlink +menu.command.saveAttachmentAs.label = Save Attach&ment As... +menu.command.saveAudioNoteAs.label = Save Audio Note As... +menu.command.extend.label = &Extend +menu.command.collapse.label = &Collapse +menu.command.extendAll.label = E&xtend All +menu.command.collapseAll.label = Colla&pse All +menu.command.tile.label = T&ile +menu.command.resetPosition.label = &Reset Position +menu.modify.alignment.label = &Align Floating Topic +menu.command.alignmentLeft.label = &Left +menu.command.alignmentCencer.label = &Center +menu.command.alignmentRight.label = &Right +menu.command.alignmentTop.label = &Top +menu.command.alignmentMiddle.label = &Middle +menu.command.alignmentBottom.label = &Bottom +menu.modify.sort.label = &Sort +menu.command.sort.title.label = By &Title +menu.command.sort.priority.label = By &Priority +menu.command.sort.modified.label = By &Modified Time +menu.tools.label = &Tools +menu.command.importWorkbook.label = Import XMind &Workbook +menu.command.inspector.label = Inspector +menu.command.removeAllStyles = Remove All Styles +toolbar.label = Toolbar +toolbar.command.newWorkbook.label = New +toolbar.command.newWorkbook.tooltip = New +toolbar.command.save.label = Save +toolbar.command.insertTopic.label = Topic +toolbar.command.insertTopic.tooltip = Insert A Topic +toolbar.command.boundary.tooltip = Boundary +toolbar.command.summary.tooltip = Summary +toolbar.command.relationship.tooltip = Relationship +toolbar.command.addMarker.label = Markers +toolbar.command.markers.label = Markers +toolbar.command.insertImage.label = Image +toolbar.command.insertImage.tooltip = Image +toolbar.command.attachment.tooltip = Attachment +toolbar.command.editLabel.tooltip = Label +toolbar.command.editNotes.tooltip = Notes +toolbar.command.hyperlink.tooltip = Hyperlink +toolbar.command.drillDown.tooltip = Drill Down +toolbar.command.drillUp.tooltip = Drill Up +toolbar.command.properties.tooltip = Properties +toolbar.command.theme.label = Themes +toolbar.command.theme.tooltip = Themes +toolbar.command.editingHistory.label = Editing History +toolbar.command.search.label = Search +toolbar.command.search.tooltip = Search the whole workbook +toolbar.command.upload.label = Upload +toolbar.command.upload.tooltip = Upload and share via XMind.net +toolbar.command.export.tooltip = Export +toolbar.command.preferences.tooltip = Preferences +toolbar.command.upgrade.label = Upgrade +toolbar.new.command.newWorkbook.label = Blank Map (Default) +toolbar.new.command.newWorkbookWizard.label = From Templates +toolbar.topic.label=Topic +toolbar.topic.tooltip=Topic +toolbar.insert.label=More to Insert +toolbar.insert.tooltip=Insert +toolbar.theme.label=Themes +toolbar.theme.tooltip=Themes +toolbar.marker.label=Markers +toolbar.marker.tooltip=Markers +toolbar.topic.command.insertTopic.label = Topic After (Default) +toolbar.topic.command.insertSubtopic.label = Subtopic +toolbar.topic.command.insertTopicBefore.label = Topic Before +toolbar.topic.command.insertParentTopic.label = Parent Topic +toolbar.image.command.insertImage.label = From File... +toolbar.image.command.insertImage.tooltip = Insert image from local file +popup.command.editTitle.label = &Edit Title +popup.command.insertFloatingTopic.label = &Floating Topic +popup.command.insertFloatingCentralTopic.label = Floating &Central Topic +popup.command.relationship.label = &Relationship +popup.command.boundary.label = &Boundary +popup.command.summary.label = &Summary +popup.command.drillDown.label = Drill Do&wn +popup.insert.label = &Insert +popup.insert.command.insertTopic.label = &Topic +popup.insert.command.isnertSubtopic.label = &Subtopic +popup.insert.command.insertTopicBefore.label = Topic &Before +popup.insert.command.insertParentTopic.label = &Parent Topic +popup.insert.image.label = &Image +popup.insert.image.command.insertIamge.label = Image From &File... +popup.insert.image.command.insertIamge.tooltip = Insert image from local file +popup.insert.command.relationship.label = &Relationship +popup.insert.command.boundary.label = Boun&dary +popup.insert.command.summary.label = Su&mmary +popup.insert.command.attachment.label = &Attachment +popup.insert.command.editLabel.label = &Label +popup.insert.command.insertSheetFrom.label = &New Sheet From Topic +popup.markers.label = &Markers +popup.command.insertTopic.label = &Topic +popup.sort.label = &Sort +popup.command.editNotes.label = &Notes +popup.command.hyperlink.label = &Hyperlink +popup.command.alignment.label = &Align Floating Topic +popup.command.clearmarkers.label = Clear Markers +popup.command.copyStyle.label = Copy Style +popup.command.pasteStyle.label = Paste Style +popup.command.duplicate.label = Dup&licate +toolbar.command.openWorkbook.tooltip = Open +toolbar.model.label = Model +toolbar.resource.label = Resource +toolbar.drillDown.label = Drill Down +toolbar.export.label = Export +toolbar.preferences.label = Preferences +toolbar.upgrade.label = Upgrade +popup.command.structure.label = Str&ucture +menu.file.command.editingHistory.label = Editing History +popup.command.saveImageAs.label = Save Image As... +popup.command.saveAttachmentAs.label = Save Attachment As... +popup.command.saveAudioNoteAs.label = Save Audio Note As... +menu.command.comments.label = Comments +menu.command.comments.tooltip = Comments +menu.command.editComments.label = Comments +toolbar.command.editComments.tooltip = Comments +popup.command.editComments.label = Comments +menu.edit.command.duplicate.label = Duplica&te +popup.command.cut.label = Cu&t +popup.command.copy.label = &Copy +popup.command.paste.label = &Paste +popup.command.delete.label=&Delete +popup.insert.command.newSheetFromTemplate.label = Ne&w Sheet From Template +popup.command.extendAll.label = &Extend All +popup.command.collapseAll.label = Collapse &All +popup.command.drillUp.label = Drill &Up +popup.command.tile.label = &Tile +popup.command.properties.label = Pr&operties +menu.edit.command.goHome.label = &Go Central +menu.edit.command.selectBrothers.label = Select &Brothers +menu.edit.command.selectChildren.label = &Select Children +menu.file.command.saveSheetAs.label = Sav&e Sheet As... +menu.file.command.saveTemplateAs.label = Save As &Template... +menu.file.command.upload.label = Share o&n XMind.net +menu.file.command.import.label = &Import... +menu.file.command.export.label = Ex&port... +menu.file.command.reduceFileSize.label = Reduce &File Size + +menu.command.insertCallout.label = Callo&ut +toolbar.command.insertCallout.tooltip = Callout +popup.command.insertCallout.label = &Callout +toolbar.command.allmarkers.tooltip = Markers + +menu.insert.marker.more.label = More... +menu.modify.saveImageAs.label = &Save Image As... +menu.window.label = &Window +menu.window.resetPerspective.label = &Reset Perspective +menu.file.newBlankMap.label = New &Blank Map +menu.file.open.label = &Open... +menu.file.openHomeMap.label = Open &Home Map +menu.file.openRecent.label = Open Recent +menu.file.recentMenu.clear.label = Clear This List +menu.file.checkSpelling.label = &Check Spelling +popup.makersMenu.more.label = More... +popup.resetStyle.label = Reset Style +popup.removeMarker.label = Remove From All Topics +toolbar.mindmap.insertCallout.label = Callout +toolbar.mindmap.insertCallout.tooltip = Callout +toolbar.mindmap.relationship.label = Relationship +toolbar.mindmap.relationship.tooltip = Relationship +toolbar.mindmap.boundary.label = Boundary +toolbar.mindmap.boundary.tooltip = Boundary +toolbar.mindmap.summary.label = Summary +toolbar.mindmap.summary.tooltip = Summary +toolbar.mindmap.comment.label = Comments +toolbar.mindmap.comment.tooltip = Comments +toolbar.mindmap.insert.markerMenu.marker.label = &Marker +toolbar.mindmap.insert.markerMenu.more.label = More... +toolbar.mindmap.insert.imageMenu.image.label = &Images +toolbar.mindmap.insert.image.file.label = From &File... +toolbar.mindmap.insert.label.label = &Label +toolbar.mindmap.insert.notes.label = &Notes +toolbar.mindmap.insert.hyperlink.label = &Hyperlink +toolbar.mindmap.insert.attachment.label = &Attachment +toolbar.export.image.label = Image... +Bundle-Vendor = XMind Ltd. +Bundle-Name = Menu/Toolbar Contributions for XMind RCP +menu.cloud.label = XMind Cloud +menu.share.label = Share +toolbar.share.label = Share +popup.newFromTemplate.label = New Sheet From Template +popup.colofurSheet.label = Colorful Tab +command.editNotes.label = &Notes +command.editLabel.label = &Label +command.editComments.label = Comments +command.editHyperlink.label = &Hyperlink +command.insertAttachment.label = &Attachment +command.showFormat.label = Format +command.showResourceManager.label = Resource Manager +command.showResourceManager.tooltip = Show Resource Manager Dialog +command.share.label = Share +command.showProperties.label = Format +command.newFromTemplate.label = New Sheet From Template +menu.cloorfulSheet.label = Colorful Tab +handledtoolitem.label.outline = Outline +handledtoolitem.tooltip.outline = Outline +handledtoolitem.label.format = Format +handledtoolitem.tooltip.format = Format +handledtoolitem.label.image = Image +handledtoolitem.tooltip.image = Image +handledtoolitem.label.themes = Themes +handledtoolitem.tooltip.themes = Themes +handledtoolitem.label.notes = Notes +handledtoolitem.tooltip.notes = Notes +handledtoolitem.label.comments = Comments +handledtoolitem.tooltip.comments = Comments + +handledtoolitem.label.marker = Marker +handledtoolitem.tooltip.marker = Marker diff --git a/bundles/org.xmind.ui.menus/about.html b/bundles/org.xmind.ui.menus/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.ui.menus/about.html +++ b/bundles/org.xmind.ui.menus/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

    License

    - -

    Nov 6, 2008

    - -

    -XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

    - - - + + + + +License + + +

    License

    + +

    Nov 6, 2008

    + +

    +XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

    + + + diff --git a/bundles/org.xmind.ui.menus/build.properties b/bundles/org.xmind.ui.menus/build.properties index 94e2565dc..f35e319e0 100644 --- a/bundles/org.xmind.ui.menus/build.properties +++ b/bundles/org.xmind.ui.menus/build.properties @@ -1,11 +1,11 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - icons/,\ - fragment.e4xmi,\ - OSGI-INF/,\ - about.html,\ - OSGI-INF/l10n/bundle.properties -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/,\ + fragment.e4xmi,\ + OSGI-INF/,\ + about.html,\ + OSGI-INF/l10n/bundle.properties +src.includes = about.html diff --git a/bundles/org.xmind.ui.menus/fragment.e4xmi b/bundles/org.xmind.ui.menus/fragment.e4xmi index 2ff099f7e..ebd8f8943 100644 --- a/bundles/org.xmind.ui.menus/fragment.e4xmi +++ b/bundles/org.xmind.ui.menus/fragment.e4xmi @@ -1,67 +1,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/d/boundary.png b/bundles/org.xmind.ui.menus/icons/toolbar/d/boundary.png index ea9761bf36ff379bc02c24975d2a6f42a1443d51..8898bf0f860293c73501f502da36843ef1b2060a 100644 GIT binary patch delta 1045 zcmV+w1nT?N2e$~2F@Nz%L_t(o3GG&2NK;W5KX<#{&26Te>kpV2p%iISYGTW@q8|IB zQApxngd#1%K!kz+ivcR!+hti+k$=`Wm;R(|qr%*2%eS64 zXiK|)qUYuDsG!5{l^1dUz8#ex&`s3ktB2)q{4>yAmQ`MD`jOgtR!`UUFXc3zjEx)l zyuub`XjLw^8*S1lf?~M+df9QSKzApo6E@Ov4*vFrH!MB!$(~Y?6|L?4_!DM^4sQ;4<_mi-xgfEqS1=c zk`<%gYEVQqoz@^7;~N-o35|4!6bxR)8N}xG3W3r57Dq{Su0D}gBD!QtG-7}q5kqq8 z+#I!_U(O}*nw+kob*S#Bm5&!-4IGeVbav5|l$Att(0@o8IT;v>!w}e6FhK zJz8P1q7Xk!^0z}#myLz=!}=B+Sgw&xfnW1mz6{z1L?VFSkSx%;zWJHrY+XVOqo8*fX~f_eq_AOm z(0>UGqKoZN4plG8{Fdd*2(GVC85J(_fJmMJc$6G!v89-jwQ*l&U8$Lgbi9hDRND+$MvxNiiG*iB7LUNYWu zrzx(FeO(*IX&9^@ax8pbbgz|n&#l>)rDZ}aJ?$GY(u*(l?$hD1){g{sj*fp*z(W_RAQZFlR` zc%wsL-g`6i-f!N#U1kxgwOR&h8Q5PL!2f%@qmOAg_xq=A7JqhiRYlS5JUZwXBN)Ir zYSMV-X6u^Y9Iz7*{?-+yET>epy%m!q=Yty2P~m#godlszE8Gc=*xx$kw*06M~`}%h~qsCc?qA@lFj7v?)kY6xAZ( zJRFQuS#(@x&402XG!P+Zr$EEDvGQMO(7^}UUc;cnC+}_QO(8<3`-5bnOH)T!u&}lV zW^vebBC?Fi_*NED$T0F{0EB30 zWNN0&?q`q!W%-(Vc(GnP)@V<+7$8wzo?T-ca&B(Uu73fA?M`I-X*>?1mxnT&6lft& zLy=N6j?0VzslO~h+3nN0dd*n2>1D$c(C{*`B4^SS!id0$_p z1M;A3W!Km_@x(I)GE{Q3)+s?>j~C`C+=*fpX$xAoB**UA~%i*!M4SNP} zX^ePM`#K`w-gDX1wgW?9v;JPvpD@usap^?`iN=Wg?EE^{Zli8GeeZMz zUClB1eBO2Yuj1G3=&1MJR3lo}?@8QtUC`${H< zWpZ;=*-Us_0NVDS_;v<>@~SFFo;}(Z;%9Fh7Rt3a1UCVO~oiY*(&}QcZG}p>Iq{0L3n#W?pkQQ9uKlBCcP+cBbvB zWGL$3xAqK2_H3>R?fWEk>+WOmI~TPOb~zF5TvaW$t*J(kL4e{X1^|>xIkg5d&s2gS zos7ewcA00Y&!q{dhK`MooEc{+p#AxL^^xA}l7E(GFRX2C@MlLyMCjh7VR6smun74@ z7)!0PbjFzl&!fNlTN~EU#m`>&YVYT{yO+=NdS2^@33?*?v0!ANUvj+s2|ILLQG&x( zMKXb+F|TJ_L9G8y)!t`e4Ye#^Mun^0=M(a28I?tm0-q#esbhq6C^W`^SWZJoQkamQ zWq+p=z2fl69x;?o7`+trYpSB+p4LvWpnmCu8v6FunD^$N7MV}GV;P_Um+;K3D}_+; z`T(ZHNCRBMOV7Z9lE!H6q&@L`gZKdjdidmS(Y5L^(OlnJJc*%qD*l=1{&)w~@1637 z=yQ~451rMG=VeO%Q&+4zhw}1gyzJzaLJh_4!&-F;-f%$x87t(Dg{*>04pZ#vs_F$E zII>Ac@T(cHF;UpSmNesQ)6DLF$%Zxb6kAtyD;5P7dT#US zT-jM)Y{Ncy`>B4_vFzi}mY8>;-D>E@my{aHDkkeUv`TmdJBcC2sInvSSk@&L(94g>+Udk8y0P7IEz%B7v}R=uEq_&3c&>`+?CQb` zWeng40;tMY?95`lpQw~P6y==FWAMXdt(n-5H0;W0WY#e{rFRsFyj)}}dq z@Kqbu&=;tN(h|+jp??TQMFjn6wry+n%bUeG?fi(q)$f#v)5&z2xh-pGjQ%MH%qqIb zNZNs_JdampY@<-%z&O>=(;E+*at$`HHJfj5hjlg7vSR$$fx-T#*3~v#Ut?KWE{BoS zuUNFUYujG4zytYDp_S z&_pwrUhj1*FMiu(Vy25Qm$CiuHS209$7Gyi%Kd*n6+3p{;@}JY!`XKp*?%GP`2ycUtb-dk6c@~zdN+@ zw#LB7PugdN=znt@+0<`40XjcqO2j-RG5Z2VE9W0(cQ)Gi+a{OGm8UgcSn(*r5ns~B zVn^eBsrr0Q%zE!%nMJ=pKHT=rg~80`JHkN#EI(J|Op-%p_5%RXm>PMhRDM#UHhdqd ztZxE)^e*|i;Q19ooG0by^f}|Z=QCF#v^`?`j;EG<_HEvVxwS1-0nR4X2{H&6 zaeZQ*??E}e>I=Nl{zn$pP|Ke3#zjxo|FqL}`BN&b^djyo*_~MQ+{I{rLR5QQ;)drx zNVfeuJ{sGyBJ63q(J$A>z%hkyGu}*Qwhp#qYWo^$7DS~o)ZeAg4_yE7%9wBETye|K z-x|6#lYh;Jy1rKHyP>vF6^%7gPhSlo5Y9r(%RH!T1_5@(>Lwf4P+s?Rs8)Z^K3*8y zNA>spf#VmO{64qGU-1WMBu3*a<6qzlBkqM+h#FlqQNT$|6j*>@Bp8V+gAv(E*Y^6H z+xu;w-rcr$y-&L?d2Z64^PK0LbIUmN9iG0*ZhlpnnJ`0*Zhlpa>`eihv@Z z2q*%Iz2Y)b-WOdWsY;J(y2kGY1sI4VH zsSnPbo9oXOf_%>v``|v_2gmF_7>{y**fv-RtrlFNg8+Q1%_B!O>5Q-D*MPk#K&cN7 zeRQX1DN~4-`=FjXmIxc8G2RDx-{Nbk=z|3gtHj6F$wr5@{#DEuqss4;1`Npx9p@{1 z`q!ia-GBE%dN7wWho}#3;eGJs{bBtu-;=|=#XeZAT$`KgZA>wZ%sbD899BMifD7jI z^)r?RH2H4&&;}!L;;myF_@}YXwmSNtpCZ>&tTdo{kRAWzwM|BBbMZzJcZ3s2y<3iA z;p2>Tj;E*2I88Oj$Hym1x!d}df0#8p0JG+b_^qqH4rogWoqdtnQZ9X4`=UTxk=R^!bXU(MC}q~p$FvqX*6Vtm@A0xi`F1(J#s zbSDp*f{k1QHUpB@AvjE*b-BfDV1k_Ge}i10c0D4PEZ>Y3iVjIXG z7lGne_>)o6Ar)w8LA*Fo_gpKek+hGSH)c!y)dI=w)@<3u@^lOlUNI;7hxQYugYq^l38;!2%%_#jU7g&vC!R@|buZd|se zkc$S;Nv`!#Yb~p;jTVGOK^pwiI?X>|FotwXjyaMPL$RU_G1#djMIG~NDW&ev(&~j3 z#rLMz%*7e&14b~{RS9N%Fjc-n&VLA-^to?c{weD86~?3dTLE1Jd_@(eq^MGXVmFDm z^5*DPHuTK6YYXtQ0?LWSeJ&fPBErdE;Ai<+^W50T^%2jF54nny`y5CE8Zxw{ zoA(MGy^q?)(Hg)za&g4xZ5Yk(eCogG03wbtu^2>!2uk-&* zJ{Z$kw6l@@GM6>NkQzJqC*yjoqTFUJ(x~7TXF*RwEG$V)eG9(| zyKcX}p~o4o%-xM&y8R%bo&PUs1hw$U&M-UJXN2ehSZDur@^SK5@lR9k0GqQG8e93u z$8FN5ttCL6HU9dBwtvWNf7mbf#D@#fpZ?0kfBrL*r2ZR?1lVX_I5-kBg8O;@?d1KJ z4g!gzLbnIvHwRHi3?yP9VV5D-1gNv{OK)$Q=QeuH)at(ndJJul_h0@{!o9|p#B@<59>Nxf|!qV+KKR?F?5obZ&>G8i2o9V>@tq^`?H#S zA)zrdnO$ZZ{eU2tT8RIw=A@jT)%dAJ#VP`dfFhs>C<2OrBA^H;0*Zhlpa>`eia_fL Z{10ufihS*XCFlSE002ovPDHLkV1mDsyG8&2 diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/d/insert.png b/bundles/org.xmind.ui.menus/icons/toolbar/d/insert.png index 58f9b054d69857da52a9f3cad58eaf514588c0b8..b718c827102e27f7c464e7be2aa9c9d230924d81 100644 GIT binary patch delta 206 zcmbQo`i*gdK|R9;PZ!6K2+p??eYp-92)I4wkKLj1t}B}L{NqTQj`WWql$P1fs@ zJ*&|io8qLc7oXs9Xm&n_zTyUh21cF)24;x^3~X)EGkEg055Z&85gg-+dZj#Cl#{a;?l}VX2ijaOl z`ar7u0sjFPCXhb05C}C%>n_In1tFkRabt@R2RR(aUgquY9Ov`yX=ODoZVS!advh~y z->!s&XjbDu<3QuUgLEKTR#m^>e;LQ|VV>vG)hmi3MfhpA+kZWE@u64}TIj2@BER%{ zy>nO1Xf)c-vg|c+O9^$l;2P+|;G|C^-f6en=RUW6Jze-hN5B1U@=D3{K;ST!S!9n? zt#3a+?R*Vw6C`x+!>_HIo7vka$v0b19tqiMnf^Eri1wWebCr#$G!^O9ACYI#_3G-{ z=kLeQF6RlJD}U6un7v3gRwB8%<`;!YRbh1-p;~o46WQN?xm3y7Ja>Iw6dP0`JxI1T zNaTva6ebu^%I1hVCxRo2IA{J=BpyA{8#9W5o+RvBAIoB>RcqT3E;7o^eo30nO+*QJ zgW;*Vz=$|ZLQqw9@w+<1`7ED4CR~r#yt+S>2y?>)R8*rR)&9Q+UdCHfjecX9saI zj0GvQMRLJH>yEw<>6m=SK@!TCqudMeM!f~g61+jga=vKaAfZyq+2wSq2k}5}Bn6s7 zv}!owu`Cun(c6~QhM=RTziGqqc>IR`SFYD~TabiE^j`3_ro3^WaiDSFAvy3LTU;oE TnwxGx00000NkvXXu0mjf7>qKl diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/d/insert@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/d/insert@2x.png index b84bf6abcc54d665f94160a934ada1adb04f6bd6..6e074e4fe1e1794720b7f3b38bbace3b268b1281 100644 GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^AwcZF!3HE-bOL;U6k~CayA#8@b22Z1>=&Lcjv*C{ zZ?6UV9dZyj_Ho;!psZGxj`eDGFMRiOs(+A~cVKpbaP0?{9}5yg`8RNdA&+K(>$aUxhckops;RSI79*^=oHtF5*!7 zDZrI|_hxv0H2?3Ot$eF|BX3Trdd2p1t@Up6d41-^ua{aqv%WJcR5$jul4;St*VkrF z-}F}Q7lYTmPeI#6MOt?szhgPgaPI0=`(|#QRIKlKG5hLCU3;FBo^G4>#eiH9z2Et3 zX579#^G+Xo^v8nptDoA>v6rbDd`92cINkke@LWKFKB1NJCnv@7R zl4XmA|9}QW6d_8N2q92t_z%(`OP1_{G7Zoe35g1XQAh+7fbmD{JKwGMm^VAW-MQJl z+ufPDkYYyiy*KaUH*bDBZ*F~z`QaJx40r}S1D*lTfM>un;C~tL40r}S1D*lTfM>un z;2ChmK*JS~DbD8R=1arj@YZNFI&X?Wd5uQnfQzk_m6e}uaBOn}TL9a97i3Zm@_{Vb z)?=F=+5*_-<7BR`uCCc&t*@`I0m}x*Hurx&p|%@%+VVZ2j-SX(zm#sSjlu_i?<~df z=?%wq8^Hy^nSURyJ+ruVf2|Q20aQqu8KKud`t9PuVgH?=)49;PJl|w2U@nxB6jTa262kHUI-nk*=f^DC?~kJWgF)B|*MI$N(SP|XR<>Ea7K1temTg>nf9EDY z46nB?FEoQW{t|&b8Q_(s02_Rl@hbu2LBvk}+8+i1`}V=z#rymnc2v4n#QETUva91!=LUSoyN!gUc1}A z_tPg=|CkzI!D&tC)%SjRbri>MHZRRLgU;Oek~$yb-t0P<)UtK?*YWlBC*Z}s0UPcf z4jV!6^}{b-{9cEtGsjly?Y>}?oZ1B`v zL){Ib*^%NKrrk|rWJ;wV29iQmJ$+gUesN1@tEagthN@2~#nk15(5yyikmHQ#2e59@ z34z3MhOg>nc$9@2C>DD1c*?S?`P~ru=YL+M)j$K}w4~r%o3XR>8is9CwERLk8nF0r zKbH<%$Xoz7s6ObBMe%iQ*6*QMkbdA@US7u3N`AVv%f9^Pm=nrL6%^nM(bl)F)KM>YI~z_3ty&d`fGoPDU-sG zOOl3;SLRQ$vQIspJiyMPoM=u7#hoNtj+21nPp3rKWXaGc`gyL%AtEt~bZJ8@qILZA zG^+6&7x7rag>*_N3PPcfWLI^>nM%R}X~1xa4@?s|6GF=h5ht0q98NUFtAB*VvPFdy zPVPn9(j2*DD;U6nEV?pKLqWQgX*PsXYpDbjm8iC`?uQQ&SRk+p{v=G@?s)E&P!K>x zs=95_z=E{J2M(ldeM)|D&nN*VDq4-Cssl^4sXF|&QpHqtTih!7PETlhC-T;;b4MXI z&DSfh+46y0pCk<;b?i%wPJbpaMTEN#r-Y_up_Qa8Iwi2>a#Dk$Xn4W{n-T^U4+fI# zwblcWfppgLVHh6m?p6C;)S%9prBKaOyQ>A9olxFh8{6C4%TW}abyeJxz#%fJ_9wBH zU&Axt8So5v20R0v0ndPEz%$?(@CR|pYBr_ zV`F1jUtgaS;ZHrlDfj6q#}G82X~ASNX&n+Clpb|);|7`{V~cH@+qj|ax?Rv|MYCyICx`}Z*T1%{$RxX?u!u=)7bs`S6Hx~9h{VYboi6?jb4L>R7O4jY$_Cm-dF6AT2pU}&|k3mI&hRh)~yjzlPl z+r?Y>uKca|p&ze=U&RmA@8uoK7Q;pW7gLuM1{cf{3-f2by~3ucA7iF(IU=PRgrL7N^`v35|h~c+pBmYy02*u>-Dn~YoQ$)e0BnW`}h z;?~(U78u1ucv6w1l4K}_g~@ApfBZ7;Z-3s$&y{;%puboC33to6178)A#3ClK-3Z!q zo`^E(m6g}?lBRhn&y9@Z#qi5rqFaqkYk?e<#S)8{UK46hM2XF$w^%HyRE_`bLN{Px z+gaa8yp4bnRHW$Buf^X~a(vXpH;F||XRt@7|1?k2(&_1G47W3RlH+P^!aekXCx1Pg z&C;5ErFnf3B?%_Za+{oN@{#pJdT8< zYrT>c#@NEfhT3jfWM7uFGy;8F)P9jkuLSZrQ5@ulT|`0`?{1&Zr$kIS)wE!xT2&u- zJUIXR$DK`OAfrTi{8wz~2biEmZ`^H`M?D002ov JPDHLkV1hs@S787E delta 1202 zcmV;j1Wo(Q3DXIXF@KFoL_t(o3GG)+Xd`79erB4cA(l{zgizvAN(kA-g9j-~7>X1{ z(Pga%s|WEQ6b~XEWKZ6eJuI^Hw(P+LMXYQox(5$Skq|;DB4sIBN-3d+5X!QIp@iA# zbh_{JO}_3VwCSX)vWI>!^Ue1&&-={#_q_w0w{s0V-x@HUm4DvC!or2Y!NDoRFtTzD zd7h^*W3kwww8wJQ_V@Qov$L~1&m!y0M3S4xcD$Jh(*ju!evurq70ne#6)232LU?lo@5H@i0&S!_2vFA`xXW&q$u6nD9lpu3UOfl!nE1 z7eA~8CV%dhsgi?CQYhcaWHL-w+3tPEjYA3WxaDAuCr)a3xMRb;zg*lbweYY78 z(_$Rge|NAWCXWe|(IoIl)^ua4{bEWcrI93CDwQJ9pbTvwD3UIQh)O5Trq*Saw4wnqohSledPA02}B~= z0V0C#u6tp5YMENRekF;w3-Kc|H?E2XNi2LI=x5z`fS){w_yOB># z%x;GQhCxF!AN72xJ;$Dy#O}sAZXAi|pZCkxh!5_X7SLW1!R1SUcM#;gOw{6^7 zb$`&3$lBfWu~PNWeEN<071a}y*d3E63?iAHrCOuW$feV11#@A<#IK(WXBd_>HHBomk|#M5(1gPxD?1)G8b0!pTYoLd zt89$)QmI63_EqNfMU;YAILm2r@$%%PI$4yu+J47%W!`qcsB!4VC|_A!CCUG`aMm(e zK#MSIe0&@%{Z1=Z#&d}Lpm)H3_lsD6<}FY8GWoZ^pNMp75g?sz;n4P1$8 zYOt}ptA6kpIRE?4ohHjZ{JShy zz@%wlNpJ$qf@|y>XU}teUvur)iJe@B4f#md?|aXA&wJkU+<)`&o)3!@LlJ=@0!0Lh z2ow=0B2Yx2h(Hm6=|`Ys`isn7;@-V`{a&wk-stFPEu?DjRF;&K%!tS19_DhnTn5ta zgB`%rhqRt(G;cJdn6K(D_5?Jbai#%Tg8u|MW4oSFye^v9DkKeE1>)K?W+WktrZm&Ggq!$ z>1CHLLW*iYx z2IWZ+01780lk#18(o8|+F$|1$baccZ)7H|`(wRxt>A2L2Ij!B&hw<_$jFp?$ty@=G zUS2MQfq&2?;Yb6}1XkmyLwO581&lP2oB%r$z<2N7mE*^c$1t}3731nTGeZG?l65Ln z83fbqc5mLeaia-lF6CJ5)CAq+0i4ogE7sPWL7@UoN^gN>(+1j-LEO=(g0@h0bF`YR ztdPH~ENM8w(N>y_9EVX^{rVH-&mP#+)6A*H?u$z|w zOoE^fHImn$Mv&ThO;_1$`BhG7CVARGTOiY7*{0%-QnlYvrF4zZGFv$Tam<`3WCB3r zCd!*nI&Gm%w2e0AlQ&mcb4i!0aISLnGwB+^&n)PW(%Jt{xzO7#{lmTD_Xeb?dWk$; zyMIxT2SUzp zjsnV!4zA4?&YzzcpA?{UO4}7A@|J&TQajHy23y>rYX@b}2#F_1LN{%t%~?by6`g9;q*Oe}#9bq9bol5Zv4#Y~2F3%)G)~bVo!~hZe1BJ5 z4?M6mMTu9B&m|w-4a#6R^x(s3859A}{R7%cn=>kzWTc~j@{6Opm(rnTAhq*J8?|zz zc0MVP##kT4fU`9i8N`?gvspy82hNud+kV}5yOQo%!lG2Yw3Rle#!l_cF+jOF4DhND zl1@97YXM3#nX8q}iVr^wGREUZ0)NCLOqsN$#<5)HRcbGTw$f(Wo|r)55%LW901<3N*9PiRz|5qdHq-V* z#;N~ivU^fm;VRW~r=4}8Ql(me(oD*eI9T~8qjBV;@u(cU+9t0a{H{bW%YPf;M5+!a zlu2elQZy2m&zILrMOjsPl3mP9qs_G4d~x6>y9b=V@|u9)?OhFee;u8Ct8Q8FRbI#{s5Ihz@ zV8y?E?&lKqMzFd`jH;$IvbiwNhQj^w7Fr&|oWLCU+OnOptQu~j^)Zq@t)+iS^)lfz zCf)V{P0{rHwshJ|+kY*UQzninO0gtM1-Kl%In*Pba<*3FAf}2xco)va@-gFh)T1RpYpL)c3j2zCnlOn{`tn_z?K-6+33a$YAmUZzXdS8SQ;ilR4~mv zW==TdK549KO0>E}REiF}K207&ZDmd*Pn&7`7#)+0a12nm9)I_F31PfIu(YmY!fbH!I$CZkqWmGYG!@tu@A<^-8MDSzYBA4DbfT)lerK5m?x+p}j+ zKjWtw#;trl%6SWJU|=AjkIheKS}IYV6yf=%7IPNA(Ep(fM~2KL;*+yiVM0pm%e~OF zO*S<=D~GQAQ4U}Gvz+WcE~k4=%DTD@@_b{9l$T*=86h}$O)ldYg!<`T)nU1*L0hiA zXQQ+^7JrM~$d;aOyrV}TIR1F~sa30Ls(9&3L8V2?Yd=o|cucyj7GW$o{{mp&4IUP5 zj&O;&p?;%8u)gO)Anw5miA7+Z-dO)-*|w}T=kh|hWOlB-y${DAZ`q2R66;u(rxmTO zt?rm%)X$kc+nsEcqwH`9O6@%3_}Bq1!8g`8(0@|5R~FZ-kPUOcgl;;5VW3Nbcdkq5 z(_V4SD8b%niIliO@dQKHu^@OtW`E{$==+wQamwqwd^vXS-o2CP?l&psL`d{OCp19^ z?`Pt^rtlVA%B*8`brU!{ujOjXCAIUmbh=V6F8R8=zUfUV_u=qJEoa}h`nLv_R&L%bRvjmJKhyH>^3I=2hI!@l;j~(<+15hYQX7~yL7;84 zk+x1Cns>6}fLiC=$1ZksWL-8{J=E-}c7Hxs>z{*{fZ51gB$)jjtK!b04p1wHEtHfGWt3);x5tsME~}PT*1jfB`0FJa z#=ZN9A#(!@TlqW9Yu0!JwmYGA8Gq#! zOi~6`UgP+#e5Uk-D+L+b^_y(+yeoS8%$X=wWxpuYt!A~6b~_p@gWJxWJsaZ{ZL`&I zg2*ySq!ezK0k3&UP2NU%k4f(`u`(u@$fML;(juNqOxgmrtx#Y>x4BXyEm+VCx6RGX z=Cww%AOfboXQq-hO2${%K+H;>D$PwYAeyZg)@5=%q`S9=$&;5Kso|=5T8j z?v5^9y3}i(I3^Mu{N?rU4!B1ATMg7cnt!WNym)h%7jp5wfmaIW&70@wAAi5N0_yJW z=G^t@|M5#fCFR9j%)sVf6LEV(FbtIPuF+%y{7OOhj&W_yc$)v29w$vhfT# zaNs~0X5Zz!1qXnuDj$E`sKoUc{%eFo0?*CO<7p`2c@xio*rmCA9KfGv2kzV{{&_YV zz`O;=i(6=AylcekG5>de?=a3*w_6+T(7H_OVnuI<=WWJQkKB;-{QD@ouP3t)ukSh#&5>r#nS0MY_kY}P?tAWtgcKqWA`l`F zA`l`FA`l`FA`l|5_y{an{4De5c<9ifnpiBha%N_x1zOFx8kQ_svUGZSI?7a$NF0cfB*g@)JY(l zo13Mrt*sh>l!XOeh+MvWd2)DoSO_ct?%BI{@4w43w!lP-4k(&+RWusyK%sZEwzfvr ztXWePkH;5S3^#c?otBFiFHQ{(4&q%+pG1v5gYIC;ihuDEjVvml-QC>{0P;Y6ef?dV zHf@TrNmqhW=o0?+-g}wx@$ruV>`VLh?PH(2D70vR9zJ|{9ZJ--apT5nH1E0jqJPAQ zBSKD6nH&UAI3PKk&nlA#k?NxxnCb8DpM=iguCA_uAYI#Ga|>qMx@Qml|!%d z08E0Q7cEj&QYXkwS>shVUwYM39;8nn=nHhZJl|B^Dp&ul8s*doHS+)mAoiKXCldw=4&NDeR!aTELUCOI}&&W?srDP;I zEq}3SM6&2Fv1F2OJ{XtBJ{@<)u^=Dm)3s~Y?iw8(?Ld4_kj_HFtQVLoAdIL_IsImZ z=9%9)mXu=y8A)YsEjqAux|9BI)dT2T;~B!GEBjN-Jf63`qO#uP(dl<`1vIZoyN=l8 zrmT1vVb7yhzWjbLm{iYtE&t1Zn8=yR34fk_`qsK)MTEX;7Ph!mK)KPuwfU-h?{)hp z1<23oy@Ev9n_oKIlo?0z!p74gzkD0FB1F@dMzeDKQa}~<(ym&ys*1kS=OX6j6>Swz z?iz8UBhD!jOGO}p0P?%2;F1@(-UL8w(xp%mxW94^H`BHzL>TuE=qr8JU>m$d_kT*u zifZB zv^O*~WYuxy{z3#jt1dY&l5+P+WPcp<&9^S2$>$llRnO#YjacJ*wv?+~<@A}po9PxJ ztKEgzaMEI`)WV&1bzHe-pgbre>XOJ!nPI8SwEXB)T6X;Gh74iyj!pZLC>|4ebOUZ6 z)21mijy}_O$~I^o@4IMr&9&aV)9*A>YM5FX9M4M6;52I9v@A!1`)pfGnty6%Vb1`# z7yHukLQmRB%V({&^@)g+PHp))2d+3u_Rwki9zxs3eacuG(?bCY-0xOGht`QF0``CVVe(FsBz z0lmhWh`jzpt>Pb~mJ8z=AAiJs2PhyK`9Up^h$2U7@GriYl5_uJb(r5Rf0(%YvZhuae0_c*JpRnx__AL`BYRs#9Dp? zACYVES*o?(D~_Y9C?f~&W#;C@jQ7ImGkp*8qnt2nhUR3RrvQJ#lCe}`)9%_3E!u4F zLG!*xCp`*!p8V&$6xA)&p%V4*8to9a#Ijj@Gj~XxB{$^D<9TYY&xOvmsO-BxHVdX< z!?fp1Hv2daefmt_XMYnfOtJdJb&P(X~|8Qs-Dlo0m;e= zQu}2kHWOj$ag}F{%rL*)QWudwe#IR@IBu9kAURS$z8RoH=Ecc;?_gHG@Y|$331Baw z5B3Ado0osGw1voYVuEeF?q*l4i=m`rvPm4Z<1J1MdfLH<`|inmS^5b z%b*AHYE1fn{76FD>fJY`fE6npeV&}0yi!cB)Of3(K=AqF;O6%B=0+a+Qc&rM%H$*i zU?+;OX_%|w+&O7~0l>aGkabLOw~1<8T9T&&#=ze{mVc1;<(@)7evVcoXKB&+Lk08CfHbU=q)6 zfU)cfg1}_5gWc|um2!@Z{7m2ID}B!CSrDuO%JZ4%lZ2<>a-h*k1Ee{!7QkO%hHDr^ zPTZf}6MvUKqpM((FEssP8{i<81J2Bwc1f^JAL%Q7b_4C)tpdu!u6*PFymDpk5kdur z+?3~8h8AoL?Oj)R^~3^A=x3(_`O!!EYWsk$RX~XkRvkS&pXtr-<_TGG_4_cWp~dH= z3G}P?)#r_NBIp}^q_2fF=O1ewQ13hU$@BgF0e?e=>mZvYiQJT(z#_L+jN%(GqUR=* zKK-pNZr|$*p7VJA{CWCz()KrbW?~&s8s*91Q5<$fr#}+}m}W}Oi#p1K^!;JK+MjUr z%`c#wdbI=0Un9=cr)*yI38zLrrjLlSPFAN)rgz?HwZzGQ_U3vlm*k{jN3aps-4|@ z9gsNkQuapRTL42G`ZuT$T98lQ4V=A~lAg!J-#T-q;>Q^)3Mh-L2W~qEs{6TN7EA?f z78_S80$}cCl$f4iqGnD`O-)t&6m!J^Rew;iUf#WB%a-aoeiU0MVEz|S;F zMLQC{D1frO`qRSNwQH+aw6rWrzC%~9&Rn=~;m-SMK`W4Va`-?a&W^5Mzdn}h0#v~g z=kf1;OpW+k4NTsdztt#KJUPq*xp>~eBZVthuC)5&7gs<-Lqiqt?5q1guZti@Zh7tXFmQ9+=$1!XUkA3t}`15Q&fO!gz2e(kmTA=fP`FnT1 xvW4Lx0wDq+0wDq+0wDq+0wDq+0vMG<;J@C@LpoZQffN7$002ovPDHLkV1iLRk@Rg` zEIEB@Cbzw~YRWYdkNTok>PzP_7Y~`o+4}X(HQx>yK|)KV(hBGN0)#M(A%uKQr_--| z`|`WnkBNn1SNG^zHd|o6z29i}1E_f=GLy+bpdFZEu^9M3nVCZ6+sEn4(n*C5e3Sts zG_aU+goxZqjeqh|ceU}so3b3w1r{p3sugHa@>z|eyg))#o|VhxKnS5C)mkXF7Y-!! z|6=Gx2Ab1>F^>mG=rF5Z))Ez#NPP1?PstDa4*EC=0tr=BpGu{moB>>=QVFDt5U3Hi z?TNicbIEz{Ja?`*G_WAz#XJTPL{RhVh5SZy$8E%t@qdXgJD;B93b*b+)`C2$iP}{U zA?=6ZNC?K5JnadG9{6yf?cKwDQ@1NQ=Z7Xd9~Qm5y?8f~w5M8syxrMzbI+im2MJXz zrc$j2axE+%>OI_^gb*{7N=L@YCRC*21_>QzdyT?c$veS7aBwY&$i zp!U~q=AW9-fjnwL*bSR2WFH}f8O82t+m7Luw>-& p*ZukCM*hXXq+^1y2Tqs={sCt{>KN?`|F{4E002ovPDHLkV1m;MT>}6B delta 638 zcmV-^0)hSL1*8R#F@Ii3L_t(o3GG+SN+UrKuI>bNQDimAWkE%ST_3`OXOTd1@ZbXo zvf^nkdsq;b2%dEje265(5Ip(-9{0HT1LDD-cu-an*Y2$vZA`Zrr;-^44`~>>ySje9 zuCA)-2I#e(2i~^_L>%y@eqOE{J6gb9VmQ6^XH7H=jnhjGQ-5e4sT(?>o1{l*7<#e%=0`s=>xRzhSwKsr(y~(O6Gx%TBc(jg<#M}*Zo;7XCB1pJ zDDDkCs80ql&^m$4=kpxaS3JdH(b=Fv9tji2kUV?E?N49-`dH+MrUpp^C5Y?iCj;;U3DR>%k?>Kb&akyHzFzx2t$S8-3tA7H)UUox7wXGC*eo(1C}n*&pJfgpGY48}Jb!*{eB%JDqi?n4)=e^IXvAm6 z)VFJgh3ggk-wy)*|HnUOwzx;n0!k&OQmtCC)(%8Fnp>WP&?!KF_CF-|xFAU{3uvU} zNh!QvNErPva@uZVel!-)NXwHSk^njjD3zy$`FT%OPz<^;Tdmc)3Ks#nyhiss1L(i8NbGu^81u(LJQs&n7_q#emH|tIHJe`Dp0obf%)(zj1 z2r&us6k&NZ1U64}s&MfgU!MZsOMOH@@7#8(GZvtrM87#YdM?Z1^meB}d;C2Qymt@$ Y2UbJZnIh5ICjbBd07*qoM6N<$f}C3@l>h($ diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/d/summary@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/d/summary@2x.png index 29bc5d5f80b02a1856565c6e6ce06a5c3e088cdd..821e6598e82aa8acbff24afdb77f8e7e36f56da5 100644 GIT binary patch delta 1737 zcmV;)1~&PO4CM`wFn7)qJt9&_tMs971%1!6`XKmH3f5v#(rYLQs34|}Tx{AT_h)x! z$N4t*CEN3Inaj;yua_OT`(}5(nQy<}&CJezvqwmjA_5VCh<`vtAR-VEhzLXkA_C1P zK$~weJd5vLIQ*>3?GCV@amuO2izczMCl8*@hG+HumW}%lAMPXO7GE)A`c_IQCmJD) zQO~wZ^vJpN0yT`UPapc~&#*ldX4@;7al^1urU{=^S1i`CJ!vJn<6WFNZy(FN^L*Ie zwii&U-OA6~H-8uI6mJ%CrR@Bzyj%F!b`47-sh)&sQ)l0?%(2cep|;f=S_x`+awvX% zX7QkzFrQ3pv5exp&D?_f=dZxImCw0LsIGlKdSTRHAj6YMM zru0zhO=)y=^l96+4=~1(O0RN_#&liJYnnDTI5_xwrGF|w9XglJx~}&)41Lb&Bb7QT zkCg&-U3dS$z(BIMw^!vguGv;Ln@vtmPQD=&KdP!s`66+li^72Pv<%PaX_{tLbsIdX zbjUl7lWI0h@E>e~?bTR_6{)|Bf^t|=OUYp?XblIAv_xKXP?$%F#K*i00zy}bb^l=KOQ33!cL+R_4&n^ET zqCSEK2$)|k2O9tq+JR4tB&Ankn&zUoLHLeB!{9JTKOc|))(3+Uz?AcTCXh#f|7)+@ zHk9AKeVc%7totCP(!0EHWc=dAi~F0sYyy~uVSkK0NRVh-DbVsd@I!38)g<)huoH}= z4UvGQnB7D7HGB)9yC7%4pM#sQZrU(F0Xz24-EzOdy0kV1P|6)#SrAUWKV}Qox@bvM z+7Lj+qvtGV%!3|Eb?PqU^&SZ}>rzpAmv6;r6HqZ|{F+lJzHG)kOGNaoVxjPYIDH+; zRDUO>0p^jBkq`R&`%~TB-Kwv%W_!6@j!aEWEsAAZ^=Ol*J(PKCNWgp|mN2!&yCsJ( ze%VZJxpZpZseH}G>nv2-Lm}d`4AWnyh#3Xfe&t8aFdh@ZX02!wFzN1$pP!v8z3VZ) zIU)9&T!+1A=jUEJGMc`tdD^wl(j(v0$$ze@y81a300v+zE*I|EuIF$b@38b(!s=p_?_AMrETznbbG+lPUw^M2 zH7tE|Ol&pV1?Cj;woAE|)u_4~lv1F6v?-TcnMVVF(0LpZl|U-X169||=0t>Rt!Pu8 z%)DtPj4iPk+>~I~j{LN%uWxF&Z`fYbKphH7feO3h;%?h=(WWC~gFAT1+YT^GCC8&g zzxsK4tiR?%R7331ZPhfx zUvrBoSl?lF%!GCM8v>|!eiyy7yaglfLff_xCjzQ~0QR0M3ffw&3AC|Vc^jRFO}+5l z*+4*-)~#V9ReG0i)o9ZaM3_Uv?>|a`!n;lVd-fzDSh3c^9X8BxKfY?O!GFhAe8hzD ziszsL=7ki|rsVYW^y=?6l?{ZCQ-lhuICj zwsdyo8}(2^NjWbQZ36XW+i(z4QVP_+MgW5;n8$On66>OrtyfDgaA~#F8Yxo`RQ75R z6iTQU%*(bTs|PTfFy@bVY)8l>bP!}PFH^Tt2W-}gHu-;9 zDtAvVUSZz5doP--Y^vd7)kA*#()4u8MVp95Q$9ieOY_2ddl`NWr9fLT+H~TF6N$MS zHy$+-VkC&y!o>^BcN*@7H5yPlf>J!e5vSxhVpneL)7QVew_aE>_1X$3IP5Xzi2o#Ue=eikVq^NF0AR-VEhzLXkA_5VC fh(JW3)d~CuA@b6`HU8vG00000NkvXXu0mjf^|elA delta 1518 zcmV-zQ2C<1HP(?6MBn0%; z2Qdlgn}{F?3IPR?mip8-6n*YPLGWE4jO0OuJ`_Ad)Tn*1Af*Yk#h6^K7hBpiN$+Ny zZ*RZ5xl1lP$$gtFmsz;`zMc8zo0;G4&hC7(%b4370Y|_QaDN0G0Y|_Qa0DEI{U^Zp zzsl%pJTaLa%uCe@HE@q9&c%9LvN`kTMB7SqwN`p=D4@??Sb2|2_H<4ndFuax&`wT3!FtI=G2m#_C7>zYzRJ;prl ziGI|hkO@ks)6>(><@5P5DP@wQ3(KV-vvCXZh4Yg2cK>fd-4l>z z7*7|Uy}#VNdoOk+4#gSDl~^@#JmyCt3pSA6<$vQCZ32)-mAJXa40Z zN=XV-KYxx64-Y3hIyxxZ80ssR%Oz)LXKO~A{yN)vXJ9frFAK_#g(@Xp95}c9u)U`z z{rmfTEwqAN7?57_5b-I&3}!!iN(9rQVv|trqJcK1Q0Gq3Ch&2jU4F|r&!9g&hZ|na zW`939et!9b{tKDcFuh($3e;~50u1Kr6?5&K=G+Jy%U4Tqjy9%_c7Elx|E_=7^I+&i z=a-(4KkK!oP2W$@JipJwJUv z!8gij^=qU+A=;$xwy}#gJ%9dg-&#SIRy(;Tug#z7y|Pe0zbzg}fyOo3^oYv=bAMH- zMKt}fg#=LoUV%jJ;^{_lnKE0}l1gRGeMMP|KfW5wjIN1D^4w8 zhJPt#OEm;`2m;^$dK4+*bO>>5`X|yA536hf)v8J zLh-Oc3^b~@m*Hqs9J#s=PYfLlU0zJ)RuUh>tKfczJ@)VXneNL`HI?)XjjEA*^?UMC zruE*68bg@iM=5@Dul{VxH5AbP$>q`Fq8p6Myy?-Z>eOF+mhTgSZ*;fu-xh4h?9ry7 zfJ!C0^tYbJfJN1J3XmYZ1ZSK2Wuo)`9$8rxYbc<#daQ30|Fk5$AFqGfal4icReD1K z6{7j7=dJsn*YHA<{=B=e-f}dNx%N@&KPq6(k0am+I0BAW+v7>Z-KNw>_zA*{L%TNT~6`W6zAoFW;>brN%ZYFe-3b3S^SUt?PQW z-EOZXYuz<@p0CQXd~|)W@p&xJ&>p73vwn^QCWKfiuPNx;D zhGym9pk{QWfv*_yoTJytg02^6s6GG>6lA5W)iD}(Djq8A`NW`n^r+XW=@oZlZjL(+ zED5@XgYvP$qJQ~E?Z-`4?_LCo`|o+VOukxTRHze+`F;^->Lu-OHe}Af@gX(-WbMBJ z6&-!^RLpkY!{7DUS-vXno8Noa1G2ciGe?dy;mb7TN5Hvco7b1*Kcq-e!?QMKLk6(0 zx;Z55axJc_4dw84=Ege4a?p(hWk^`GBb?^rgp&CUW_?y2?R$alKTIBIqc2k&U}$V1 zuZD<`!_QBnS0;6$59g2ivMO#a>;}APOX_XxgYEO1x3#(|KPzuRaN0}Jg9@x@`$-a0 z@L-jAA_C3SZq>YJ_8-eivIUDfj delta 623 zcmV-#0+9Wx1e67kFnwX-^k0G+lsJRTvj{#(>)qjeb&1Sw!k#m(K2}|yz zIyDq2(>TdlIK_a<0$Is`8Bi?5P#@-($%r%P zU@#CCUOk+l0Mb~AHndrA=p>q4H8dJghb&Q?L1DAo?Ser8S{wK$#bb=aQ)_1dEcCwJ}G1btJKK?NY<^us>G{66 zm2C3|1AX*-^~bY$^!E7Nrvblr*CUcaqfXZ)c{SEEB$f32C0Y6HWq(?>>NM9qBVG|@ zAUYct1z~b7GFGJ9#8RMgM4ety!~_&MhR;Q=a|+3|EJpsM?7x5;rc%zJ@PYGgnzfhE7n{7yBel7aMw0ib9g*9!>40w`Cva-d z-xcg+?Jlc(f!63)`FMKm2WIAdJOQ#6>fSQAs;`Pb6@mX8fln~5C3V(elkNZj002ov JPDHLkV1j4SBnbcj diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/d/topic@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/d/topic@2x.png index 95cfb68f8e5c616f06cf4e3d320264458388f757..503b14029bb6b91c74bf6e5d6d2605d94d9cc085 100644 GIT binary patch delta 1131 zcmV-x1eE)x3XKVnF@Hx%L_t(|0qvU2Zqq;z$8Fa|RRjoya7CPY;|=--TuS>0yhzTx zOWRy{0n}5k+&K11v8q;zP?g&3Z2WgN>$TS(qfH}?B{JikkKOrY)=4)+kz7JR2nYco zAOwVf5D)@FKnMr{As_^Vz&;U(LoN35^71&2#{yUEY%>r*xS-7*cj4F;4t6EKyo zYD`qUWx<}M69)1G4(NzRE|U7Pq&=URZ#tdQI@oqiFrZYZ3DDHn6q;WF4pQeb+>r~? zFjcB)LmtS=iGM-Co6eA`Lkj9hbS0!K47RTRt{giW3)-RjS*8l5ZoxLCy3H-9Inb6R znB~^>`BSGMht8+s5To-U7fE&5{(6wgQ8!kMsnP0_R zenZBBb*TCxzs#~swT6P_`$v_uZC78Vh;5q3$e-QctM@Kh`ciha2kTHeBD=Y{d9lZL zU4i-hf&neh8(EIXd`0cj9&F3+vdEBg3s7d-0)JG1G814O`sv z9e)WOm6mR7BHVm|ftKBA*T)8K_ld#+#dg=nYlaxQ|(shlEcjfFj#tyV~-nI_41Ap7P2{uSOmhQXQ+I(C&JB$VUAIyKR-p!|< z-maHKg`mqiEVAZ;Saj&feA(?o^#1Gpyf)8(f!%fJnC?I1=*xmc6+`}{?$_w(TS7J$M6yi=yQ6wc+4Voe3!nk$N>6BYXQI(#G_cSLcus})1Xz%cO6?97`X=k1WPSE(u; z%78MU3@8K2fHI&ACw0m2 ze}8#$a`I^iz7Mn42gv0InMX%Qv%|x~Tq(QrG)-02byY!PP=}1h{Q7$K{=Xuv3@_;Q1GX2)=!=uxf!{#$_jIsHc3(|}jZ;hEQMG0NmcD^_kC}paPS7LqfjvjZj zqLVl=N649o^`4dM7!1WN-TZU zDO32^whcCp-Eg0c&<%40m)w@Ym{52gc5NTzAtn*NW+ImPwvAs)xWSN}(9_e?v($Wp zI@kx=^U{B?SX1;N1>4HQLAMbDCv`|Oh^54_(hy@2`7YTB-MF-Ewwc6Ir%X*Eebg!Y z@G1XD8-I7f$nbGt>=a0;kIS|mC3A8PDG@=;dh~9Vq8%!WNa?|b&e~;5nphqiDSGIW zzlx=BV{FAb)chj9n9t{?H4IsOKd5BWcI~T_v0d|s{PUX|^X%$HU&^8WVjYTCWLH;L zf9&hKp@j9}iV^DHH)eT7)>qU+`ipJ(hb*$>+9DxsMf$ed0) zG&7;aeh>Zo_2(D2%e&*MxzF|uV-_yz$zpH%;;VtO*T*?y4 z%A$fTU$mv_qz@7Ud1%8u^)5d!a>RJ)+ka8#5_U{8G#pHrA4{y4RyZA9$BSv;U1b54K`|YOs`tIe~7y{#%q8-XD9B(<;X~P1kLt?~q zh1T>(MvRaBE}pY9fAC=*YhoeT52C*b6EQ}v?D z5*n6+(tTC1MHRYUN`I_`6n#oy7k)s_1!)GKo;<{zXXmS*Vdp%(2^#ZOr@Ff}I95uD zQ0kCUhcCyFIi+r9``2=NGzFnq^(;HvB7X=135N**!5W2cR8e9RKoQNduJ>&SXo07DVL_HHyR#>_WVAIfx!Nr` zGl!=RJGR(KB#VMV@x(!3Hw+z|MXA+rZXl#J^Y@r8(1H{GmW_GRe9=U#t8#5bOjQ{| zbI~9WPYh$wuf1PIdVl$GX-pe#b&;AmbwrFkXUv-Dj(;xDFTJ6KGsc?PI;tRv1{ZCN zu?GX(H$$=|v< zPnsu*f_3}|Gl5qruZ>8ZaMwdfW7sgn)h(+PXsW<*%zL9%Zzx0ZkNX$7vn^R~zWgqp zo+(bSm{QWlx=i*_QVOxb%Q~(RoWN7WU4KBxg@-@hdy1qi^$6OUE~B`uqsDc!L*DP1 z_MD0rZu<)>-42(hy>D&Fbo;oE--2S^7>h%M%5YlYZsoo({}5!nJcPM~b<(?d2 z5cH-Rd7%D2{G!h}{C&B5jA+@>+_Qc60%vCHt3YtcRD0SW+(E8kDZG9n`j>Sq@g4ONe2ES2L1rq WyW2^~+_WM90000X)lX(3jF%7+w#5lvc6 zYzQPAj0X>R^WYyqNK7O#M)6|&3q0smJ}lx_ykH<+h{hNd6XoOu))$%5`PQpIteQ>L}E!=Zx=&T z$TFpLXmOZ&D3(EeOoY4#sCS7t#l?+B&^9alKiuyrCjs^uh zs+0zXu5~KVuz~0cjSDPh96Aw4K>gQNE_+-scByBVJJ_f|l}Abwgn87FF(aRdi!vKA zGy-_@@-f8Yu^cR#RswA&&gRV9O*jH7D=>Piztr7Qt$!EM@GS8p3Z5;tkB=t&vrOdz~7{L}tqBDSmeNdwirm(m0V$v96 zL-DN;q|l~?`%5p|vf~ISdPo@{c|4w8?pO3tqgd14erf>T%|C(hi3z^g(yA==!lz~0 zw(A%u;(vJm>KP>B>$c8R%?*L>(<18zkU;mDjP;lYd?iEkcgwKb4IBf-os1v{`uh!E z*_#HLoSd36N>G%6NpeQ)>{7`vZZRkTDEA^#jH7)0x3g2}a4Aufh!|^>3AP-pF?8HG z1}f^w3N9mxN#B8`xyF@GO828yZ24e&4;&Etkop&j=eKd|uN z2l%}39Flp?Q5Re5>j>NW$~F`L6riy^WZ4Pal{gyB%(4xn8#^DZALsc?^+h5)^_CKd zPEQxK>+#00t*ElJ`sG{7s7YiN(~lazSQ0|>K0nHQ!3f|N1=r(Qn$}pmOz=6U;)u}{ zg@3D~PuFi==v3WD>Sd^KW7YA^!J==ng;BF8cBv&WJu{Po2j>d`YDUZPlQV&r62{9A z`&kc_y9w=VkhQitNjtbl2Db~B+qlAMBuM-rgHWC{a=3vXf|-`#n~kRyEs!nyS&6Yyi!?f ztwg-LC8IX+2Z75brLVuH;Pz~Cd2ys>+l#Y!Iy?T3$JW0hk_3^&hW%d=_K#qhN^tSh naLx3N0~Q}FGEijTA7$V-&t$I$MLfYX00000NkvXXu0mjfrby<{ diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/e/boundary@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/e/boundary@2x.png index 2a85020ffa9578035f86d14d5b36e404110082bf..05999132696d9d8a3a51e7e895cf06b1dc039124 100644 GIT binary patch delta 2736 zcmV;h3QzT;5yTacFnqM^^cCNf^}>MC7~@fl(r7V{vl{bu^k!5j#?>!Dn)Ch zGg@dMo6pS`3A>)(-FsecUfzU{=YQR7RtSe21RMk$1RMk$ z1RMk$1RMk$1RMk$1RMk$1RMk$1f~#ylE*tki}tpzy%>$xp1K%2KKHT9@#Xs>&HwI* z$B(@`(41`iuO#!uPh7cN@q@ONc5T^ZSD>kiQ}lG)=j)H$a$?%e=5vzEiuncWSnw<#^Z5U>E4!#=W4_0 zv;E?(bq8BF1bwc|?^g!>p-i_Wgl53ZfSQ2;u1K8m?YSE7FUfPKo9!kt_DsadZlC#& zwa?peTjumHmU>s-aiFa(;B(LE?iuvOvOK;cn{q`O!G8$Q7yv5(V>HPX$uhVV0n8X( zTupb>xA?5=CZhXT07W1Ce5rfZ&Q)3E-#XrT|CtX5ZVpb1Un8LWKdPE8yjmT)DQf@- zVxCM+HZPsE8{^E}=W+FE(~}bULz+~O(VWo-7x=s8{dk>!?vp3GYhL?n@A|qWS>5;C zn33B*D1U@6jUr$toFU6%6Nj8| z04qoI!R7lq=Dl1S%zNon@0XwXL-ea_N-{dWwkkWnZ$JnyJr`+Hva;1~M%Q&y4=pQ5 z!5-QijTf9aKX_m9cU!()lIQIoh>37zd4^b9ntv`beXe{|nh#Bez?6@t0u>C!$rzg} zazu%-F*y8GJg%|v`rmmV1$$`e_pWSfx_IrWrG=hpFKx&bxtVT1lJ(N#>_sEgNG42U z2`adnV~!!uK^_6Pro%kjG6%5yV&ZuQ9b-w_V$)Kwhf-BW8rJ9J&dwnOu~|kz?O$h{ z9Di4oJ_i}Vunop6v%Nn5k4TgF<+*y%(HDVfQVOJp#M%X0MNzoIGG0-LqbCh9rU~2L z^3&YHE5RJYva))}j*m5rJ-8$iWVI;;SDRr^de*&mu0d?R=>f5D=8f!a$(C4*X%J1An#q zwpR?@H1?AQj& z5?ZjAsA)2EQm=8CnRRsTrFaP~bJ)p6m>cs6e|`P#e*1c;ZGcAmVt%*y<;61brb}-N*kWB{Zz|5ZgDKcU58X#S zRHz%WbDtRdfF6iCk%x0h@eg`q{ppId~W_%#KBYbqN}e} z&Lz8XJl&V$+1W!mX0m;ZS%2>Gu!qg?Yj|^;*tB?ySU97?&?OV}WY2zdT7NX2dQNP; zxqg`Wo;Rw*uFt+QOlKbOhsh^PR3z)nwipA1(tNhIvKYJ0wnu(F^-x|Gz<|JU;4Uv% zM2}gb&s~q>S(G0OarnSjk0paz+yEE|-0I>vX#_hZfaAj7@=7&nX4_jH=TJ@zAGwrG z^^eU%#R;*@W&qPgg(5*!sek?c!pLgmGpP}W0`OTDZY+aa5!Tbc53PDW1$*eh+E5oI zAkU!^C`v{LiWAdwWSKc^bTHY+iVycmSQsCujAP}c?9>#;u(OBSR-s{h8KMy6>NFBm z0uqp5tAw~3!IROlxpdAXNA7`dUN|BvoOROA6xcL0)-+b(O(@0D&41za@>DyA)*Pa9 zC}koq%944|7ZPWhn~cXC$r=PBkaFby34VrNN&y^mG?RpJ!d!DR0EQ{YXD;oOBhSm_ zU`q;I{}Vk_W=0jTs(7n7^me`I?7#l8M&)cUd=RUPwQr_xj)K z#m0)w;?s00FcV`2{!a55(RjLn_M(nq2%^Z&9%|dMDUW(6_J|9AurQZ04VcU7f*lN! z5YK_*!rPiTTv!J0?2lN2DeY8zG81J53#Bc5K+GZkbW_-te}5q(mTiD;JZyaqRr{9! zV?hufXTWu^kfcnMN{TriO_n7`08NJ>dhS>**y_HBhbv`!D5_BInG%M~FK>VbnSo?E z*}M!wK1}2)eZfIbowWE0FEKUz4z#ccxFQA-u~@y~g%s?e`|ln8w>j;k`3oMQCY_z>`FBD(1S-JT@Sz7*3OS>&j8-S37n7v-d)Vqdray$ zd6lQM(SPM+^RO9q(Lj#Dby?XV4(6HcJclMPBVKI+ocfvTGyA&c@2m6&n=W0geDXxc zL*<|Jb?sUm2oI{azy4DkB+W0G2`o3lg=2w(MvD)#rL);ux=i>sC4icDgCC2{nATph zXKl{RU%lIR&&#Kx)wh>qM5`BPg#a*qUBXGj7k|}*jd2yRoNTk~3l1^^n$Qm2&GCB& z;{B@&?fGp}vONy1J_Qnf&UnL|c;W7qf#O4d?5;iee&5R4#n}V57W;yD3!8qqV}Q$> zH3MP>&Y=~YTqh;k(l;ixgK;{e{|e8*tUqD)$fo0000u(iB6ra71U2Z8_TH5j|eIYLsd0Yxb0u60J zX)z}755O0{=?4=NVq$_ZD)`Z$pZy0UjRwRRqsA{rB|Z{0K`;it0Bw*E4Sn6ao-=oT z)48*IxtHDnTCgAdn!CAdn!CAb*e`kRXsCkRXsCkRXsC zkRY&_5bzdLvYhLtx9+qQy~*KX(HqXB#mMALxVoM-1Q~BU48!A>Uv0ZkPaODWz${d{ z{@pOh-o3SddZsw+XS~s3IJJJ;YJX~QgTHL|I^XMUNehq4A`FG3wXB0o1y>T&um6~C zeR=H82gJ6~pMSc?f&-MQ#oK&(V#jpo9SqXp$m~DkyE{LVK0L?x;zpdEg2EG46vs&2xQ_7a|wR7hQ6SR|wcWlPeK2_OCkBcGvN%I@E6PKmg@FxapmV z{7k_cMt>h%M}6=>Z$snmPU?ees1JG~Fw-=*pah7N*s}JPhAmSbtcOertP7rvGMDy{ zS*CU0It7&a-}3~+aqfdH)CXw`2Yb4*L4Gau!GQW803ZZVRlEW$6x5WNe64!6LlLsS z1YA+RFBVG`&D8a9259e_6E8Mq#hI4|mgOq;L4RHu4GF9QwIs2wKttJExB6k=0a@M> zLCnEA@Y)`8tN0QBIt0!DrH|}WXOA`IHngQ>Iy(87H?nkhB|%xYNx7|^&q55TI$V*SyhM{6+?=gysz zc7KQsT9b2)M$Q1``E-I-#Yw;*V?*#L5k?j=)>j*_g?}Y`PRJ~EveP+M@~Knq7EmOE z(gS6=!P|JS3NkhY22ABJ48Hs%W{WG73^VB_W0DSGAdJDeG>?O;Q$TCY2cJ0j>|wAO z3=?#-k|Y4EmPSGh96ly_2K*}mSc&EIaeuriGvDy~fk{s{7pH*g#F>%hQ6WjvNpQ+a zXU-OJKslD=l|6Xq>AP1tdxQ}4OyyuX^Gc5yv>yZxsarsiDJN+1R>HhoR;y)eUb}z+ zwfrr7v^G@bCn-xAOq8Uuk|7ZnR7a?vaSABXF$?4Gi5ueTFPFsRW0fVY%Ux^c4JY{Uo zCu1XsqHHhyrE;#_z)Xpq5T}5e34fYAGG&=uoDzU%$^$PHykuB*?dosZ2X?wb)g-c2 z60hGygUuE z4tAgsgE|CG0o4^knKF-x0K*Fa*qn3ZGbd&t9X*@Nz5@Qb`l}4Wu`A9O6Msje&N?6o z8fQOGS@}=n^9%wvUL-&S4VL7@^_w^2*8n5sD65lrrq}7E#J>224V34?&u&aj9(mXl zxG^<(+s?(k(+UMXW@6o2^5UnTFUc2-DX+#enBAN65`j1nFxNMq#r#$D9>Mz$9V`79 zOK^9zt#S*fnjYJlX@65oyV$mGq-?9-PnHZO+K1lahKyq!869O38D<`={P_I& z$PS7))hTcaC~}c+VXFdAWo%;u1V2!&KG>Ktn@5#GZd1$&%6c<49+2%<&%IMX%Mv%U zvPwk)L9&W~K*xSGBK8rzIdjRU;+1__30l!`ehRmMn(K<=<79Dp!+#ExZ4Ca~TKlG1 zj%uEY4>2x}dC1%XiUfG^TwMSGJX0Fhtu%uyPA{F*rEhrdr#lAc`_Jj6q)>{TmUL=b z9mclP3I~i+Kx@sXT94&8coyJoz-0_Iq4}4AGC$RbL!()ma~on6sea-NP(Pcxb!EKJ z+`FRmk8}}4fQ$yAa)0sw1=MoYp`pKU@nYp*aT+*+#@WnM<_yq6L7aN!quXa**wdKn zTbC8hOH+EQ@s3o*BGUwq3bFN7dxEjp9fS016O}JwunIg=IZ)ngr}R9B)+;j?gr{;g z_@F~r2v3A5F~|qL`a6SQS7$cZx+*JjzNZ0>OlT}v>Uh7zK=R5)5FhJBsOGn0F}gT{P^pWeJu9>uZU9@+iSdkY*; z8=11hVj1tbVi@*pS(%;M)8#*wU+ar5Iy8%_V&5tSXouIndJ9`6Y28Nbhu>dhfZ7P? zMGt6c8FSYS zZ{O}Igfj;-o;XZDAPqL>Qlh^r@bewie^+Nk1NGkrISwxN3cVLNvHiCxGxc;&uyp&H zQvaos&U)K&EW1TS1=frxZ}prG{htA~mM*ORdxZLLFMsvlX*zGeY&-Se&gFDi*8o-e zTLScF^jNb+e0ObHy#DE(iOVNjot(2*&&XcJ!o5fT71VzTm=XF92dnDImi}kSc<6}} zzn^S9Ur(IGH$fmlAVDBOAVDBOAVDBOAVDBOAVDBOAVDBOU~wYwA8M?GNVFtA)c^nh N07*qoL> z6chg;6`JIsL1s553FTjwFxqz;I>C~%F%Qk(=E%2WFqh@`7xO>md zQ~&-(`Ix>)u6VNi4EKh^i?f#nC>_6bDrS4#x;l+x-klx=t0JV+UP!koTz6RGD1W#- z{qO3dZg%T`ZhXG`?6SA1FFtSh$@9#_ff_6rTmEh+^eX5p5GAP`*POYwWEzi3cx@ zU!aHH>$QG?_8T<4crcKd^j1@g7xfdU)Ox5QHX;ZJD(v?ChMje!>oU+kX%k*DyvKX9 zzxmCZ*_pSDb)}nue>(%(uhLsyUcT>gxn>9_u4!7dUa#K+rhnV*{%#n?4w*?^*ORle zv)|zFR5~U~1Vcn@kx0&sj*haiu`%D^;2`Vk>*HK1l?ppMJ7Wh22j_=}hm6QB5%C2g zoauyYM?@2e1Ty$85{dN2VzC~N$8$ZlVKAlGX8J*IeSC z2DHg2&n~h|a#5|akE^TYTCMiHoy;l|#h#@7xIH;J=???~G7#iaH546xgSZLVI4S!H#Qo`h)v@KYSKLK=tFE|8(26ofc@Ku;+zbHLhQ!dt%446AZ}{e1{N@Z%{#RC zQOYP`#0k{Lvm&wsZPPHGAOu_NT)V9j8X56XmpJ;h5+$Ovm!kfGfyUAj;#&HWJ$`%2 z+uD~aYkv&bkKW|C{}c5Q6M+ps8v2Nd`2Bu5X0@mV;9w{b#kJ`5daVIoeJHV`qRty^ z2nJX6iwOWzT)7S$c}R(<3?j18$|uKdZ5(U10ehzsQ4|=syM-)1>t`c=7jLkI$o|*l zr*o2L8n)b@PnK4oN|?YF&pT=9lD@qg0q+)z#eW9_v`;a}RQL`{y|`;VAhP^q!gIqf zI!sA^e&!-TID`p2R9G!VDWimv$Ye6-f{@T0od&eDY&X2t3kYIpytk==N!^qR6eXgx zgvq09mRCWXBnC1Y_{hYCZN<$imRD4`X6ZRmQ2`U!Vopw4i71L*0$kcn(>ViTPKZsh zW`E*h0>A>MYC)|;l#`>P_v`-tMIoPWP(fy>>5_&GB0|d~W&VXifdPx+3$owIRwimz zIrAG^TV?qKZ~{k6CJVblW!}c-W|>0ss+ALPl!>A<>PI@D7gFo%7V#-EK0e+XnRJ-waZ`bD8xZz$y;fuCy}iqQT5kH=(Wl65 z_$^7xA9ulEkOhZ_eW(X;Ekdfa#KlsHWsi@~vyHd=?|hsb8M|wDGw?rU;0K{g;KJgBW@rEa002ovPDHLkV1i3K>7@Vw diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/e/insert@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/e/insert@2x.png index e8ee064159efa30ea2bc359ac9fed236ca32b3bc..4c91b2f561c80e3c147438e288e5fb271901db55 100644 GIT binary patch literal 606 zcmeAS@N?(olHy`uVBq!ia0vp^AwcZF!3HE-bOL;U6k~CayA#8@b22X(7?>nHT^vIy z7~fv=&wFGba=eh;^?(2q^X-@WR_}DxzcTrY)83ttJ|8G<5G=j zOZ0U`^>&%vx~!9|C-%>V%TV$VknWFWxFw!h{ zaq`Bd^EFVdQ&MBb@0Ce*W-~a#s delta 2772 zcmV;_3M=*A1n3ozFnc+kX?d0k6RJENnjnzytmL{bMf@*cS%q`Sa&j7mLMX0O43yS66xS=FP1e zHf)Giu3Q-rJjjg_9Py;d^5n^r=j~+ex0dB(V zlAJHlcv%5Gb?Vf{r%#{$W!<`UTX*l?-Gbqr8m<6Ra0E-TRD*OLD0BFEUMg+t! z0$|M3(Z4?Zv@}~Tzl{a!kN@|85=<;KC-(2(U%<+3{UMMV#ub6f&Md$Z`m%NTT(f8? zLrGbt@Ko@RPd+JO0joQxagtceflnOf<=NT4_J8&D#bC0DBp`D&o4f&Y*{A6f)N_M_ zC5)7x)N}YZ&efU4*1HAh%$~h_3w)j=2+SB|jVS%=u96xLJy8yS%QHuP-lhh~t%%}6 zzT@^##~Aiv%HcfD*eXWh&vgM59ckohzGKIZ4$hf22QqdJX@5Q>2snI@jE9bBntqkc zO@9+6%fiR$bmKXfF)=pAn5DiHd0m|HIdkpWwOh5C*JKOpBDt1}I++^L=L5`t|Yr#i7N6MYM8NefB$TAUIIs8^UXX<___yud;D% zQKt6An;zt%jFmAn_Ueche-#W+zJF=w%i&dgpXoZIz^&u#hyx}`*>TDQ0JG0-Kt@LD zy(p>iw56^9Cmw8z1c&)|)cm@(RyH+7jG3{cI!FlyC;;i(xN&1!Y6lRibwnYv^DGW9 zf=OOL8yF580V8T42`p02R{p4KJgIaXP3q%`qz$q@izmRT`Zd}T9AYlo-G5Rj5EaV` zx?<;5*pcGoZ1n!$9z+-Z`^3a={9tAD+aIrqx?6EyQ6CqVZN;f_^#0k>-1^S8IPtXB z|G`4k-GUqFe8z1!hJUp%_N08V*TDcq0NV;!-B}0?b5IbGzY8#b@xfR${!r2=I`ieD z=GrcLB|}@f4zj z9P(}aLybj&lk#A8{tlVxgGoIW%2=nHVET|hPoG&!FzJ^E3uRgUIV$8=H%*i=!$+Gr z32+LQp;#?fH(`=j2a~aBm?!1DuBih^H8Rie!vALCY?hd^tU_OmOMe+Ho|G{&_AJ|l z%7X#wH>~XOJK)!+^5~qhCbd2xRK`)9brXFP#U$B$Y^1vo8f?g8VxQ(;x-1HoRQwy? z&%SqDoUCx+;DHj$?5g@iU-GM(=lW04mmOnf?7Chm4F)JOV1kq~gINSgrW!02r>VLymvOL#+ioWa_Gh^5FQfV+i5y;R~sT609pF!mLX!NIFw?)6~ zT@`h;G}>_p{71iOw-uWmp`H$|;;H)Zk$lWrjDNMmm>D}yAxic*T%dPM?3YTVQXkB? zd&8_nd7)1K{%|2)p|j>#&37BxRz!a|(o)GUmbYz}qp%zx$Ig2BmePi;(1P2q2^ z*-O${Dh-yQ2ypPuojdayIs%&1=hYcsW;&>dsZ;V7Fabp>phV5iwIiM`$g^OV$pmx< z?IOS_7@+t~{4qCf*}|mEA@%tH0jIeTIB9^T=}X2~88c&-Y^gLDpxjc39U5mxhKDOF zHGy=iwsjbMR)2?U0D-N^+zk;Q+b8M`1nRm{;}3GlOvULkR>mB1J7h3G87StW5API< zlNP)OpyoSLTj$XsQD!iQr>ODNqs$fYq&~0uIjO)V<>A_6tc-b1`voWj1r(hf7#$sL zcrZO(oe=_u)aPBG${tcXAdjif&$FJO(_S}#xoa}|a)16xh>@|P3_ujD1O=3vUD1)_ zSFc_zJgp5-1*3T~@E;i`3_{^w|!J+M^A5-~Jk6gzR|e4Z1-AWhc1Vb$EFA z;n?^%FVl;krQ`{KDEY);@IXfD^RXUVp^b`o=f?o1y*tJcTM;obR+)sN!2#vYVa!YK zetG%wRDV{7t%K-+I>^pQW*wUg@QQ({rk;}aRFVuVV`Gf<*yS7?P{z)k!+0FIdE@5I znY4`Jd`7TIc~D1Gc_vDK;z^BnHU^UOWqd|PnjNzf_KbH;WZ zhfR_C7%Rbz=O(8ly#rB^2@U%A>^U*DZ30991zbXjIcFK@|L66B85B{$7oz2^~Z!a{jUL9vC^=bg~ zWacMhN|?sa$!piHm4-)0zZ)NZ85r*5f13EcS6?k-zh-M^XQzFd=GZZ%5UxG-D&;GWjO*l0yzRX0yzRX0yzRX0yzTp aM&KKF?B@RRt3!DJ0000(VP)Px&c}YY;R9Fe^SIuf#K@=W;VnPvdlUNB-V~x^9m!Sn|DF|6~A?S1T4Z7?b^g$G| z=prT176O$ly9iAT5k#yB6p>K;xoXch-cv^#ujkqyvhcuojx%Sz^Uax=d(TyBC94eF z?F@MSlwPS+3VS@B$Apulwly3M*MaHvdb^~qs8vRz(U*Ka-$MVgvNTZ;q@epmC>4vv zR5Tj(hr?mDv9Y1KbUGc?YPD3O(XeW@nxX}q(ZJ!dgqI>(EEXRT!F)2A^rh2jpWpAF zBx*QBIu$V+_mOS&dg|->`Jhs%42W>4P$-;ECde$;L=O%Qo)XDyCX-o11~nm**i2l| zCE5xa89qKf?vr_x%jG_k7KvOA>(sbcTTeEc={`;){tA+I}LD@agRqLC<#r2C#rR-)nkAMAXh^D!sew(`OPF zMcNRLFP32gi?W)MW>rKK&q+Ljrf&E2g6ICDTdv2TO&eIiw4cFq=ktJwC^;u1k%%85 z7c~HnslgiGc-9DpG1igIO+44|qF5+WqFbS0@E6#pN>4p|`&~EKEU+_n{|B;pQLxdE z1|MEXC=|lfEuQbBMMP=K)^S_;ti67BqrTk?b%U*iwpQGa<3J6Vz;+_YVVD9x8*G-@etm&x@V9k6oX_Vo{XA~=BQxwzm~cUbwNOMEC6r3D*|azSYmLs^4sF^T z+Uz4+&$Tr$fz7T?T0|7}WW8S3Rgflw;M{-?n}uy2=Yj>=uu)L~6WBb}NsEZ0hNSa$ zc7Aa&a00t^Y?e5js1I1cl-8#rqBeoUYPC8*sb&i268g3VU-sd7EjpXPqW_27w@8bL z+F31?Pfq$jj3>aN08Ek>fw|>!xlh?FNwbL2p+4z%Bp)002ovPDHLkV1lL&!Px-`AI}URCodHTi+f^Y3bbF-fl;&*4Eadlx>K*BFB=HEpBdZK0bHu+#1UN3u(s*y?XU(dTVQI zRLB_<;&$)Zv!^IWXC{+T-QC?v2zCxBQ^jIY34v;DZB6C#dG++^(+xS=h3I7=`u^U% zdw)B2?ASj$N$idhdgaQMH-)6*AhN%|UkwircL*U3aq;BI6E#0SUszgNQXp0czIFEO z*}ofd7O_&(369%Zl?loivru%a<=>O#Gy;uP<}>@Zl70={VB53<9qo|YyRuywA7#c-3KEGrq$G@=(xV-TbLx<$M0*(qO0%=G1+kf# zoSgjKWNSOGGBDfTU4JrOzAHWR)WpO@M^8_W0u7+fqr*p_LoD;)gStx~34<&bm&rB} zyt=xoZr;3Eke>RzjH|ym6=MAHVv4H`klEJOcIxEGlMb2nwBz+1UT z>jfeCyEt!uVyqHQV?~&Nq~;`U^R$o&5_rHPbS8p;)OD8AHmE-BC{6aj04!oN>0+a~ zRZ09-onmQ(*&GuP#>`sDL;&+@)eTb)EWiY8z!;`(y|%FsighNIMzYR~bx5f6Ob1XhNa*hR(viB3G9*1u*UP0Z zeX%X%>;7q{$&rx}jPql+Z{L1H%Z{vCB@}Os@S>v&OC$t@;7tVhVKaCV5>}!Oy*=vm zgZ7{^iH`RNz$!0R-eI;4X_Zi1ak2UcJP zb`!2f@~Xud${*ge%W|YxEdYN&JlE?G5TywO%OG`~w(yHokAGkW_HvErzr+*Sle~Nw zz?*gi0jHE~fYQ{Ep8(h}PuG!WI&>T8{zPA_i*n`xGqC&XGGKm4(&eim{sozJLYAF0*sr^Pv43 zRt08Y=Xq55YJ`n@Tv?O98F+J3!X5NsS-M>MG^0LvE2YvxA`a-tJJdhV;4_|s} z#6Q~sW=YomW)8j&b;R}QOR_~Ki`^dpi$qBsBz-m2U9s?I86*?vB1vD1y+5IhHY`J4 zkbm0nGU)ZOtw+)lZK6uH5!DZt9*fv(RF5MBgaoPUPNpx9HoAlz>p^D_kT_6Asn??} z#a?}226p7xNW>D^7k0tPPK|Pp=Y*k+iJY7wH)L=?a!rI8%qy~h8Q3c_Bb-;`2g z1cR44+5<*lwY@>tDxnCiv$ON3g@uJ}cYSAwcIUHz4SPss{Jdowjdem#pFW+Jmkl@O zW@iH*o1)ChHVBxTn*+8RaqM!oPACG#&f%5k&+{_qmvr(-1{;OM0UJt_y`HD*^yinl z4Rrkgrsd`3zktzS&&D}pv*FA0fo<3_K3#bD@L?e@`!f-cPM98`UIrW5QPxvl%O8Nj zAFu$EsNcr5RUGZalH6_BGk5RZD`1N@f_7$ZeZmN8S+^0LbxEA#N~_BtAaTf$<4Nd9 zc*F!2QD@@ZA|Cr@E^fFTA0KzNH9FBDNG@%h4BrpSxa9E_I~RsF{xY1i%&m_Ldgt!l zf^5WyeHU}=gd#qW+EOZ=I&$=AM-ToK^92l>id2j63ghZ0_?`(pQ-+|}$pn(75Q>KQ z(ZYcP2Ra4^2Ab0D!s24d9W!6Aj}|~ElJ{9nZ*S({!GkIHAIEZ`#b0dyo|UE1b6II% za*T7#^uumSPthC2&S7kJmC578plm4|8XB_t;TN8O@L(ZrzWyJ6>BL^Ub}h59u`wa< zBFAL+hLT~R1AC1cNwTg~a(fr>Y>vlCJORbAXs-ub(|f2Nl>g(|zTVzqpKOo8S0fk_ z@V~k9_q0^x$FsPl@%XqRFNfs;BKdgMPb$x`3l1B%q?ci@(f{)EZpM6#gDFOrS6WV^ap0Y6%P=hNx|%Rsmy* zx**165MtuOjnS3S9U--ei3@9tYd5AbX4KZwckVmy-tT)Xx9(cGtpnu&jy}rJ_XY6)+x324L znx?su$)t^#d3kvW(M3cz6pzP0>+I~DxF1^wCfeWM|CAW+6+*ts%1U^>Ud`olp|G$} z@!8neKqL~u{QSJWu&@Amfq*>d>gedWaS*}>B04ZI@QE1f@%enHudmm{qxWp2; zqocZ{!hn!{eb?0g@0Ok%92`upMWcEmk;vZT@syr2eQeBMUt80OVMN6;Im;epPRhpk zwY9ZXbGzLV*;Hsnr^b}KTjZY*eqI?tiNlT4$DU6;mVbGnU=Y`bhXq1EX*Flll54k_ zjQd_+O%2>exJ_CltU_z%q_J$`@1JmG<|2}Y{@Nc`@X^W7k)P)PQ>I3+BxieNdR>O4 zEQ-7=x(pSMAnxwk+FFgo(mOW|?Huo%71gRqM`yjc6SyqQzi7U8Q)aAHG@CpeDqH>g)c@d1GC#)x0kd;RDjzAl(v-j zwx!|CbPtnc@6=_8P@Uf7n9_U1tJa&TQc+&c2(|4+(0pboM`fe9oW;ed&~l{^B%y25 zR}tO{;jH%+Jm##%w{rvdVc|PCY=vm8IE#^m?|;>?#3e`U#dx#!9S#*)N~hB)$E@b! zc)wi$bwBAULKh8EZ65sV2*X%agXWv6)T!=?+0ph?E%C`H?&?K^aG zlYfc~UpO6jpRuJJWr4wOx7mvFi^Q1RrS+{u9P9CQdPq&9WG87;suz%ZQ^o|7*e32? z(h^Ytj;yY(DjXW2ry3uTn#9;74me=f@^OCneSCHE3v49ry;O#AS#JP=n8ePQlSN@E z^pbBwi%UzL<+4kOL9%Z*zK6e7=Wr)>2Y*i9SKuBomkp zPNDAT<9Ms#U1eT3LQg4}BDA3_yfRdlh_aqs5~8evY;yjo<3*sn#V2rFy6L2PcLUC! zxqw@Df5YY9FJgTws^YAOMMOaET)#yg)>RWC|j!A;D zy~Yn`zDphSC6d!GSG{V$0O4>LvvYI2@7h-GGf+9V&z$YYEY0jTTTe?%i&iLSARE1F zrh-!JbBV=b7#YuA=fXK>qBL$4y**V`Rq$0;Yvu;yv)zq!rGQ3YW=5Y&g*zutns^5y%EjqFcOH)i zp0YBH^#DJMYz*;gG>YYw6@7VmnTP&^|G864jLU=iT~4=oI6m~i!{~v30Ti#2(}OHW Rca{JE002ovPDHLkV1gyAi2?us delta 1323 zcmV+`1=RYw3d#zQFnSi0p)J#4G#|=_INx4 znx^$AisH-X^KN3gT&|q-C8Td$Rn^mdeSK4RV{6w$M@B}T5W_=4DA3f@gy!aE#pm-FkDxYLN)J;-g?Nc#=vftz@D?@_Qi`?Ck7RYHMo^LUv-CtdlN{P{v|0 zgu`J?QejlczP4%V|MyByj*X4w*OEysm&+A@RMqIGwCm>l^|dvP7-m!)lXL7*=A>+l zOWobwN?l!@MAitc^yxaKy{UQN^v_9z=X2O!q2Qfo%YV_;vQJNi*v*@m2!#Yfd&+6f z+LFs|rl>v?Xl+HE8E%Uf3G1P?a??*>T%Wpf(Ng;M$)#^Ru05tG;j zL)$2hh=1~&Y;0`AZM%CL(1lnY!t0Kok z`n%~>IpHz#X9nM1x>dv!F9G9wD^(gB8W^FTqLVjuI?7SmD88ENY9q7+5JKmtvp74k zj&)VRvBx~NnzUVPl|#=vu4Jk#RAhd-`k>Us{)9v#EtL`>_-wfeS_j)>YnrZH4so*%zbg_jSN84HrW_m5T<7H4^} zaDQv@ShEA~pgYP@78ty{tyW!TX&aK!ydgV1k(L8gns`coNRT?EPSz&Vf=TQRl&v*K zM8!a2b#+xop|RJWEY}Zl3)UmuQzWKf^mwIgFc&o5VDzd;!4#p4Z^_O!;D{*e$z>tRD#$J8AK5-srQqx_ zZ=v8|-)FCSF&$O$X*i3}oQkZG1u~-H za&2ZtkDD31qM(QT9-Iq$@qjGE-lCEQOdIRD7Kv!YbXrh5B5E4!pPQRQTuL>)(KGVo zZIU{Pu>b8N`}C85bKPR)M5nwPUm_llV{U$)Z~bQ1j^g%Z?=YREnaAxO?CR=LymAJz z(YpjG=H>8p71PTa+UpgmoQy0>r+?E3UAVwfu%rUIB%&n7!rAS12aj}gDEsBFhy7gS zI6cZsLHDe@TZ^EK%U_eW1Aa2Ed?|pv$NW~ z5$=*aY2odPC_lFUx%2z|@YmNXtOs~4vN6P~$t0pHD_S%f<)MG?|J>^8B hb5Gy%!2Rff{{RH!zI39{8jt`0002ovPDHLkV1hGAmpK3c diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/e/share@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/e/share@2x.png index 5ababb70c9bb150ee1cca9175aee84cc59599efd..2475eca0dd993556035dcd2526effe7de837b57a 100644 GIT binary patch delta 3546 zcmV<04JGo?8tEI5F@K{;L_t(|0qt9BY*fb;KD*wv*R0=QWAjRZ;9$qG3khkILJG~R zG!G!DQqm-q@*}Adsj4cK{)v?SY1OFwLH$u$wN0cxRFO6@kVgqh0u=-iR4@>1z>Wii zhmDP~z4m(j*hjx__MY|idKVLXP10mXnmuP{&YU^(&6(%DSAQfEG6-Z4$RLnGAcH^# zfeZo}1TqL*e*|3DzsmGA?%K7>*VEJUomeck((QKFLb4KkK{Oi8WhtbETrO7tY%|i1 zg5Ok8<$ZQEu=B9VU=7Z)$6tE28g54D5R|uu z_-B~{SbtpQo12@%$B!TH0jLi>{P4s3nK#wpx&VrW=P3-m-z{6VED!Tr!rKy+Cjn@H z)iffY{51fKd0Gw}IM5G}pT~mr*Z+G!2__br&C8cB_haQY?IDmljN=KGccud@NnXoZ z{yc8cQV%6%=*O;L&)&U3EMU(~HK++EF*Q5pFxpHL!OjeN$$VAm9cfdsD zQ^^z5UAuSpV==sUDu=&&qQ+cnzO?|oaoe(Ge(om;0zF2(Mk)1cuaX)ba!NV;jh|W6 z&YP(L=_V+}AJv_x4|%j<*=@JwaUQ2_@j}l3P6?oBh?}cv!)4?mJT0FrX2fR+CC&Y> z%Ft7EbI$+DlM;w=`7A>@3a1JdKrNS>W&fvp<-L|2a;Eo`goX#CJg*|IALUY&pI%bp zzIgGXzoDU_>(y6ZJ(x=UWYSXAIT?Mz6Mqm4KD%PYis@Iqvp6 zPVxj)Y}>SJuaPnukF+THaZ&R~?Yt$sY41yNwEK{FX1K+hpC#U0ujCYXB@5?-9)EX- z{Cf82VeaN(ml=QuD_e!p2MO zyvf9mE$zKe-jTM@Iq~GX&^dAaaot9#WKHu(EH@&r{P*`-dK_h^;(+0&t+aWZz$6kJ z1r#8yD=RIHP4oNXfDs5A7-{XaKz}AM6U7fs?-tjz2viXk22w<$BThZj+|tz9C_^K- zAF=B;^6}2({Q+&I%~rA_#8E(b1&6D*eDyw3JD;%F-bg#25J+OIPT_vwLg2i(JXlLD z>~&llHQFC2?#s@R(>VV#{9hI`vSRv#M0jo4o2hwOOZKmz`>qu}6P~NojayXm!nJ{fk z0|*Gx6rf}pZ+pD)NI*SpuHZC z&}Q0>EJuQ4fC8kIvu4dIuz!P@XaGz#4N;Tr^D21bVHPz!I{=X$#yA`qmbXuCm7l%+ zoP@At3J=7uIAZ`V5tIcDhhkDWqe^^PIi|eoA~n3NPV7hukhU_RXOhg=YqUuy!(3FG z=l2sG;}uk;Z8SW=(V)E2xPayw4~^@I$$w70FZGREBskn}((jnN+<$E1y8<1OlaCeM z(h*T1~xoiF^SzWn?#RbnX{ePFSD>= z?;q}y%^z-(v%Q~6G=F=95AP%ziN-hf-Wl@jiXTgnuh<4Qv9#_7s7-+d#p42|RPx7( z;25AVxPTAT7!)|ArZLtq3k>zjFL%8lL+&Aw?5O0HWJ@p{kR7etrMdGsfW1fRo3=&8eN){#b=4I#0&+mFs8ZRD|!|0St1DB*CzkfpJ7vCti&c0pTuJ}xr zsNb?FRR_~%+HNXy;KwmQv0CPOFv%0VR6)~UIrs+|bPq^YE*s7D8b?MCnw}MtkNcYC z*#4uYctyc%d93CMshL>^G2}yUjMNG&S6z0CiDT{tkZ$ilieD+8Hq&;>IT0KK)NV|= z2K3@M*xYqovVV)>`^d5Lf=jY+E_a1o^1~(1$nqP$l~73-382EMJSl^AmeO?fYregV zQQ+W@W2-#ou@E2W+Kpucv=O9dx=%~C7t;ceFpg|d@-ee;yTs@9$xT?H6Wb*ywCk|* z>2R>i*!fiQw3)W2%Da{{#{h*_1o#rdl|o@|A%+)0j(>ZbQsa46S~wCGe>N63gZP!S zIg>}5X}dGp@OFz+ilC>tKNuY2O{!bHWOn{svl_?3mggD|9rfbyNJK^=Bl4F+f0Fk8 zHlxdw1-MERK-&OU{iJq2xqi*JQ`$`1Rd%w}F+ee~AMNk&2Sn+IC|BRdYoC(XAQq#D zK@-C8Pk+Q{7x8&d?bnwCfdGXy1^75h0Siw6@8#ym(u!CmjH9whZSyDSsIoeFy zlgnJ|f5&d@*RNmi!+f-Q-n@BNJQvR`yg_nsf;rySB<`q3!Xsg`f0VFWp1=L4*dje4 zo-D7NzT7HjaJljRCp)Dp)FpEY=1HzM^&2L3kblS%WTg`U)6~?&scO@fEn7}ZBzraa zquqWr(pQk-1;gdbm%H!3?>-;T$YxQ|VM*^IZ}T#)_$^&0q$AiNCAlS1SH5%%U_4^( z{P-=zx6L%b&HFd!t(1puT8o1~iLvBt?-{de;EY^Vdb7;RpK}EZ$7gXtdS~a(K|HQ0 zc7N&(KF0v1xm&kxeY3Wv=7HIB&@dZ-$sVKLqno)f8hi2;No@TJT$pJwe9@5b8__9vA5Q)UHc%aawIr5 zhte9%MXz0GZ|^hnnl^yn2=5hJW{lAraZ(NOh zx9mFgF2LL+ZrpviywKsrxd8k-@aV>lkEnTUU_A_0eP*P9r>(R(p6Sf5qksa0`p(Wy z*FY#_08E&uL!H#lTLPv7z>}J&JgLR|aoqgg%|DQr?%QO}=`IgDLIps<$2<|-0e^ge z^wD|L@XThKild$&Y^1FS^+9{yzSq4i7!6Z-0*bCd*VIysg z3p)4fIG}vajd|&XV~vgd+8|>t8)XI4K=9f?CTp4znE>zyaLwn6d9V;+?}|qvEE^e# ziU*VFJqy1Z?;I-94pZJJ7olym(dlRMrW&gbM+q9}#^c$Bn<^`-7c5x7yMH9(SvuSj z-e>_wK+GIxfv!9$L#q6XI7$8O@XKzs&M7E zhjj86J38c0L&GKPY3ruyt$*gRme{SDBu|6+=J27zhx_>|q45@apyh=LnyMbV40tU| zYIqwZm}%Lh%@u(oW@3SIFllp zMqAYI$Wv8R^GF%41R(QOzV+0pa7#!4|9_d z|49ZkxqKiHkjAE_{(s&;;LH12jpBjECqDd|Sz78_ym+zSmz$gLI?9a$%$8>Kq?r;z zI8L5Cc`|shv-7L*;g+FD)%KpC;PnCgOPo*Lmp@KTqtt)YbLX z`!q2bAikdouQeaf;@$VV3kwT}0B!+ZnsD(Y1b+L;$UyKIgH!kfF>S+S=O#I7a4R zE0pW3d1(L%*<}cc*GsCM|*vLM!`y;kP?xl z&@{xfs@fk-m$Z$V{ELzwRhqPl6g3i+s#aBKRjEHpQ}suJ327UWl0fSOQn%T_K(IrI z5(72{<7LJkd&V>UzWd&pJU?da!G1%wInsOQynD|*_uTKEyMMe*Bu{w+@(AP+$Rm(P zAdf&Efjk0v1TH@UzRO=_<{J0y+gCg=F!1GMGP%L;_g@3eCdd_uM52VHkT&Y``Gz2N zBJB|5{Z&;}dv3bvrYQ424)l=&+S=M$1<+am*4F^iMgTOnXwjmI^73+DSy`C`gF$mZ zN8<6gjE|4Y@PF_ykL0OSr-sl0MJW3s%03N%TU%OM20lt)KQcfM95_(Y)6?@HKzOjG zrY2cmUthjp!2$^c0z&YRZaBeFncPjWSWM2GIV0WO-NR?kp7o*Zwz|5yZEM%A9d+wo zj_Zp(%yF$~uz%;yoj*iWJq7@aSFT(cDlILYRjq795`V|&$cP;7=!gK|C?fWuty{PL z0iBSTmGMg~d|3f~=9y;}PE1TZH)qbAhE=Opm0@_NbyopW=LnXjr7hq}92^*sH{W_I zeBr`{cMA#%Hf`Cm<+MvBXP4@8&MHvDyLa!t0boA6V#SK8#>U1%O*b4v9OD{cM(98) z+e7?PrhfnySN+b;&iJuo#|8lESMRvvj#rtNYq~6eV&VBVhTap+&CO+)-%`<*s@w&j z0anw9fXXuf81uBWx3`A@^1WEFc6{OiC74)fwy#^aE`*iaw1+_IFt!rx=*$F|OJB>{ z@qE#ur4dR_3S(E$_VUXSEMPy*HK?f|F*SR9;(sttCK7u$Y}k+jlU29@nXX!Q2TWH! zojyU`w|{>ai{UM~9RB|48Z*;;djWcOb#rrw`$>Yph|#D~PW#%c`at?nJXEt}r zW@rADYQB8=@+!`mW)7t99MaDDkRaf2 zf`4RW=qOL8uW1v2okvGcTt?%NO`$X(*;7d!_PO+lzR|}tnzK%tyxPv%oMnLf%(-*t zHt1^3NYTwXHB=@iU6ju>99AwhKm^}G?eE9rC;x~@_h3RwgFcCjCuM%AU+!5`BHvkE zWZ6`GEeqbbbZOz~)2AEgBeH+5DqitPK7V^*ly^YAy}ci-U%!4{#(gFu&<5Gm$p#Z# zZTK{fJoe(K{N;_PL}QadX0bxVogc@W_s^B0g7k(iV4vF7)^@(Owsx`CcT}E-J#Qy@ z2Q<(LHUFBI9JAZmX zU0pGKWf?EYQ$YEk1H<^i70Z{0jFXHw8!+W;5J|bYu!p{hQm1S(akA6Sjfnj01)Qd# zSRyHHCu6d=YdozcI~6w=A^J+6(<;p{(NjPHQcF#Bb+R-RvH&9x=>T#&YlBSCr#g;e z@!@dJhQeb>IdC#=*<%5%!-z@Y^M3>SN}sc_m#t2g?qz3=kKpj=tz4sz+$pE5XyX(> zW@uVU$syRCa+s?*fXarb_1_O-)@}iEx>EF&K4)VuTOH2;<-=h<&#bAfwdP59pmQdj zp`3}dvE=4pM^GlWK_?$Wz)fT_k|CY-(w6d69Y~|E^qIbAD1OPwo&m}y?SFhY9OUy% zcLQ7iDNxEyW1&ONgVTg^oih6Ibn~TmVp8NcInJR7_ORC4#GDK>P4Qy3S3= ziSr5R?3<7UgVK6vOn&jwsElL6WIm}lAaZq0fjoRmiTvrcaoKq|{g$W{7%r|XkX_#` zx1thEmJ3EsJ24I`hXZmgwJvey=C|1joLQL|LhPJ~&rgKqw{geYqM?S@9 zOfXMcL%B5IlZs-WJaTif+}s3IQQnGGtI+13<1}G|crO(*5Sv)7gR4 z*3Kj+IrHf=eK#2%oIC^6=}V>t>^YtpOlNt@k6>uGtPGfFaz+&MoDo-B?w4BYxwXjw z?o$HD@}x{1Z{^PX?Aa=hiG7r>bV=$gxl{gMcXoiT!*JgE`Cw}5aN2OnnVRj?amwlR z=`(##mp79%&wl_#R1WbYgsG?w(Uc8UVW^`gvQeG24t=KYvo>TK$gYLi)z%q~L?%U~ z7SkxXy4Ekj43E@QmwazmT<-d7M2_`NSoSp139SdlXk*Nh(d|9|s-T)y#SSnhsmL^{tU%)F@O zGTGOBH`m38+$mF!KGS!1nVDXD1}Gfek1sZ+96FU4$~(Sg?Ntk1ks89Pz5r9g_f`kZ zHYfmKxtTxkUR=JuBP>69Dk3NPxy84LTyL73AWrd>1RMCft_#X< z4~)sqj+i6>NEE>S8;{}+z8^OG&j&UXOB|d2`=1?=_xb@Cs%o6)lizK{Be^mwMij8A zK%%ew*bJ|0_DrRBDS4U4-=$cwb$9LB^|xzQu7CW>qWXFZOacjF<1}J;tulEG+s;Ct zE1zX>^o0}h>sQ8Q_pvzkiun2tx&^?Cx0V4sBnjg^k`iI$4tD2VAz4x5Pu0PEXMMbe zL#D$|b$835j*h?IdFP$Cn{*FOR(E<}h$b)>J$<^TXV^psz#=zbB2T%2m;kc?c)$je zGJhM+gGA0~d+fGidExGm+>T9r5c4l{ITbj;q`q}KAac*sBj%QsX(@tjL*zVI2RMDD z&nZ0*1Wy442(5j6eZG;=QTS^&f==2X8Sa$r2Bkn8a9b~TXFZ~*G@^J%Wc^Qc(qK@`dFSax!O7oACb1r>ko821(c28 z$F6vd932=O&eQry=Yvh5H|+EjoC;eT5X ze59|L?94RXb3pl?8}rgb9Y>DfJ+2K7y`yZCX`o568p&i$Gb&R6er1(U)?Zm5+*Y|M zfH`&@9xBhbS9;S)PFr>X`bHnUekV`!7klOQat7A`$B);uZ(P;Xw4$M*!EEITXR0!d zM!T^D)68);=qi(w-1#xQcVD+XjDN++TKTEPr&HH1^vm{^5(`I`V__GaIB_E0+0}Iv zL;YIV*R{;0HSI z2mDECzb_=ub;iw8e{Q3eVk+3U)M}2=x64sqJG1xfS?PM`9e#kjDHmX}E`KWoDCL0o zIU|PFKfkzUO<5Vg4OJjr5qc2-&|`EepeE#4){a=WtJ#$2=Zvo$Jow4|oRN*@cbEX> z-dEe(Be-X_0C9pzkZ>5_Y;I%)le!9`avEki#vvTW;!33?m6jC z3r&rURZEsENi9^YNWsbE%%uQGd#ZopAtq${SC4ZGQVm0D4-%JH* zri4-4P98sgJks0O_u2UIOF<=f{+c*{-n=Bf*DSBDt~S3WI`yWL`3SD>+&TW9IDGE> z`On_3iEe=SeI}yT{5*?q-#1oPR*nJO3Vbx-<3|Ym_mc;S;PHsy7sN;;l04JXGlbj7 zBJ3;kKhL^><#krScRDANLwHU3vHiU}UAyvWc?9wZTF@L*BL_t(o3GG+SYZFlre{XlQX|QO#*g|^|dl#>zAc!JXsWBv4 zJZP!@Sz0`5mgcLPAoZ*uh$qF19z>y35QAxB_v1a^tevo%&snn#3VDZ}c{B57ewm$_ zw_$9uCK>p*Gr-3I@9yKAOddCFap1K)Dc)|}C|uy2%P6t6D1XL(Ys(GotF!NXb3Hko zN+-|X+gyDW)z?@uilFXPR?kft{Izhz-h<4OG|DNI1hiZ(Z@aF0k>aq^#xRT*nM~#q z%GWEm8oI8feq41^7PmZ<52MB~1JDD=Y&P4|RMi@jQZk_aQoPzQCG@wO#bW3Oa=`@G zC7-R&LhN{f{(nJm`0M~80Hjg@ZLc8T7LLY{G72FeYp?*6pFw{&z6S{?)LE%i3cW%q zL^#`J8%Tbau8)8OG}sJ%{E)?*sriZZOg_aJ322;MFN8SIxN+ip^Ya;n^F0+S2`F^^ z^_3N>&yZcES`C$qknCf^)Mm`R4dHh;0-Ojv$Ekq^dxlq)RlH|$S| zWBRG|uF+Vx^0lD8A5Y3C9LBEi=O`%e1u&$SQV2)F01k==@?@as1&2EV?;QA@dOU}8 z&B{MdO`8k9emc9&d3l=p>PbLh#8kJoLbZm0htbaQq`LmBXA9{V&Sh({M5<4SK>`}* zc+zxks(&{wPEO5#81^HBdJ@n$$CDJ2OPyYu2$lpC#?!UsW&aF>@UKzy&_PiL6xP#P zt-EB@jEcHQK*1?CkIxT?A`icud^*4`s)`I09d~s#e$wH!h$9Cn9vqR9fI{a!tJk|< zAt88o*E3TJCU>svxP;?v6D*~+;3%2<#oJjXy;XurcJpB_+Fub;Mn?s|R=D{^b)YST zH|W+Pu%>SZ^PO)~I5XW%!;ycSQHTvYY| O0000RmefE3L zpP%3R>;ssUnFmg{2gEesm1;i}2%!M*2hchy7jJ&QC;r;Z?SI$^r;IAUy(!0)JE=mvH;IbFv1@qcjD1jS7L%9@KBsd$52~oYm{~*cS3Yk}gkjv=j?y zI2lHp`+uV>pjl=;1`lSvayy;<+qkTk+@-OAQr535FLP~1>~MJmu~mP z)n{sF_mTJ(QAl{nobXNVQ*GMex!wGwvT&e{6gDS+`+r|cwf6h)cv71Ulro+3C;rq7 zK`aq4MR@Yd524%Z(YbF|SX&=9si`R-dFqc7etbNvOYK(8|AhCGc>&_UJzu!N-Fg;K zqL}9TdL-830FvGZ=*fX=6ces=?sGwsZ5GgM=}GBu%jGU^CoOJRKMQEK^fU~{_&yd; zqNkQdR{wCtaV+GjWRz)XX%H z)#ge^H5EfirtbGn{A2;8%zeALnQ99MvYrA5udryZ`_I diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/e/summary@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/e/summary@2x.png index d1772f98a842303dcdde1426f9552d74c433ad69..99e8ff8d04f524a00e7e1402e2c783925b8c235b 100644 GIT binary patch delta 1954 zcmV;T2VMBP4ZIJKFnn52o#o11>|JuXz1(a(lAZSMH-CQfo0-r4c4l^NqiJ!734g={VgfONm_SS*CJ+;d z2`oPWw){;-*W&Q${V#ajyB96!p6=1tzue@%9C?29x9D1}wY;K$4rMbx>9+nb(;2~J zoR__lQ}U9GX;(SpZyd{<`mT2P>QlOUlmDMZPEA`~M$%51-HDW$>P{!u-re8bm0V+Q zW*+;RfbWaCcYiAisK)t^h1=ze`G1NR^HYV(Gr8Gf@m9HHrA$55n@oCK`|O>wFQuY{ zx}t9RdQh)@_2T-{Z26>}vK~*YvF*Zian>n%A05qPKd9GLm0npMT1VyJbI1QOlh#0K z)^Rwwr`2tClNUc#r=~P%s$<%gH*OUD3Jy3-M=_a; zI=(WnihsNYl>rz55^bXG2CB#|SJdeu)BiK+6rt5RA1Hbr^srzYWs3#rmr_EvChmJ~ zD>j4eq54wm2JJM9D_@k*Y0>e3q>M^Gq@;>}BCfb&D8%e*JM#W0Op#DB^vDLQC?zUGQ9v*d2ddo-M*>>z#rVC6y(S}t6l$OfMA{H%A zZGY7O1xG-oe|+s!J~CHb6+k&>Q=aQpJXF`_rY&Q^M^qKgyDES(#{c9lJ$}MJb>`CZ z=Vle~7P6sqmG8vUCV$Z1l#A~BbkJf4dNncJq|ZB_ksvHy+!uqqncG zuX(@xC#C9B4z@HhuX*hnja)9Ljh#P#bAMo9py93jN;Y%GN*GTjy3Is>x|rvTowjV_ zT^#S#7;7`3^p?kokAx}re2~F-wZC#t2pNo56~af*W|Pw<%}Dg@bBfOIb2FvcuDcT{ zJE0?eW$+nI4vXZL#4nmhUY9wikG-NOyxPM?Z z2I~@scO9P5(syn19R6Y9Rx$6Dd6|A1NhEvhH22u{I`t(dmCm7}7ZMu04sqZ600BYD zN~-o-LaoiMq;N@4*S|Ehu3(9wJlS4FZP9Q0j;)uqyiGeNMjJ+2pK#F^ty?q-t%&`1p9ooi@FEYWE|Wr#)eJS;^9zo_} zT7^)>@v6rL@tceUrLlW4a)!%eNgV966CyF8m$FxR|!K( z0bNc5(5(-s3vZP+aG_*gz3u{OR9%js)I)LFGmL}n| zQT9=(hep}aFt!J?nJ?(@_)($D*t$8+*P524n+CHymurse7Ju$x?Bg)Dma4O&fYQcw zi)~w57~S63Tj57I1cykLOHSD|^;bXHlPxS2R+xG#3n=}XNl#3(n&;wm8@kKsVVG<9 zW3OK|OMmmw?(A3?DDCL1D4;qs-lIR35r1?>f9B1ZsZX1R@$;eGBUjpi6xWRj!~|jj oF@cysOduu@6B~#LbUK0m04j^6O|{=$L;wH)07*qoM6N<$g4N5#r2qf` delta 1695 zcmV;Q24MNT54#PJFnTd3=FH4DGrKdB8zIt=5=aT81bNtItcR+H?(`P{OuW8*DXy>8+MO;;S{^bBzIYeg=$><#$mC=;UvfuwK9X zPRozcH14>??J$Y{ln_0xR6lf$IxocCzS;sR<*bzQB7R_A&PyTJLx4)zpr3u@b9FGZ z#h}#Gl8^G~{(s4#KhC!?Dg@WmTvXVe~QEnHa{>=Q#%YVz6$;rtvDCcjPA`ZagKVZ^8 zl@!PNFQ|r}o{*c7Y%Eb$pfEFAJ32aa!^{p>(o)2(%LJJbtF{#>Oap}y>%_W?WCcHJ zGaM!bNUsR&ck+Q^hs+sf>cu)scIq%m?TZpYk}r}*QleD$mlAeZciNC(@Hq`k{+VIrW z)c8JZn-J#EKC{%-vjPqFfkof8N$7CgZD3vUaep`VZt$N1Wgexv1iH4W-;>NJeRp*M z6mFPSOnR$p*S0;Pnt67r*9B0a6u2PDE#uJFErv)Xf^ zYkw)m4m386;PqZ;V^CO^Jl^;aOgi<@NeA0XHr?*vbOc6B@Vi3Nk5&AQb(XqqLPz!? z>qR(tOovXD7{0Z3d#P(Q_gB~Z&S#;0mkKLTY)c3bW}60xvkpHPNcyq7Z-Pzb3nb*$ zHk76ggFt2T97ZAwuN}G3-qiBAWmzKt_J2AhL)l}(laEq-x03Z4svASlaJHcy%(`F> z`WGZcT3reZ4hi}Qh6dgo{d^o7@}TIe0jjFuyo-py7?VQ_a^()>CC7D^P$jJTo(s zxZ9=&Kl-o7+t_?IWFy7I;_1vwVVqH61)A8~Cf9q$WM)fw){JxN>~DF_#&P+A$4jT_ zOWF2iGtQ~k1yFd-9yX!1H8$tWIDe;JA3!6-?rko)dyC|*E?SpBt3y;>?i6TsyvpWg zeak2Hwy7)y#tf`Lp!>#AE4yqccDXL4Wcs`QMa} zB&G&B4q&<4rhI4d#aMyrW(EMGI)bEGifN>WGuE)_bQ}=083RIPFg>XuwwF?PiGg6? zqhSQn)G=+lbOc7QO&x7yCyD7v3G6eJKo%@%?6I+22?j|G71G1Zoc-u5PHh8(7I>x%><7(ti{US_v-8%>6HB9YCstY^yS4lb6C0|K}aewCN9Cf~gzclq= z9q`mXvbo`Pf@Z8j`S0PDmQNOAY(z}~1x^pc3$J&Jm;bWEI4t!IVTo5}UY57F()qQT zUh;$sX6+>W^KAd(NakCz#U*QNhD!TA*cIu2I)f9I5|&z3-aYe+r2M`^YwZ? zPMOQ+6h*O^OeVKn*Viuk2KMOzS(c^OB+D`(r4*35sJ7||rGGSCRbvFbx~_van*?fB z++7%YKys-887MZ;@r`Kf!&NY7RaJ(-`ov-=h)!oE`p{Cu(AUM`|oi!8%M9^On@Ipb$r)7 z^~ZaR^N`1x|DE-}0Zq!$_Tgf#4%5*&n&tUobocgqZ#^JK*Ec2)=ozwy{$O&jr>lK_ z3f^o|L^X{3FiiA*Zm(5F;-khj)!8e|H{PR52i;guM1PWCvB&|=00S>-6zJC#buYwb zWgPB&dPng?4*t3e0$__-s77B+x7ui}qEHjXwe+2`z7XR<$bl=^q_Nh6oH1IPD000_WS(wyeR# RrT_o{00>D%PDHLkV1mW}_{RVM delta 623 zcmV-#0+9W*1e67kFnwX-^k0G+lsJRTvj{#(>)qjeb&1Sw!k#m(K2}|yz zIyDq2(>TdlIK_a<0$Is`8Bi?5P#@-($%r%P zU@#CCUOk+l0Mb~AHndrA=p>q4H8dJghb&Q?L1DAo?Ser8S{wK$#bb=aQ)_1dEcCwJ}G1btJKK?NY<^us>G{66 zm2C3|1AX*-^~bY$^!E7Nrvblr*CUcaqfXZ)c{SEEB$f32C0Y6HWq(?>>NM9qBVG|@ zAUYct1z~b7GFGJ9#8RMgM4ety!~_&MhR;Q=a|+3|EJpsM?7x5;rc%zJ@PYGgnzfhE7n{7yBel7aMw0ib9g*9!>40w`Cva-d z-xcg+?Jlc(f!63)`FMKm2WIAdJOQ#6>fSQAs;`Pb6@mX8fln~5C3V(elkNZj002ov JPDHLkV1j@rBohDt diff --git a/bundles/org.xmind.ui.menus/icons/toolbar/e/topic@2x.png b/bundles/org.xmind.ui.menus/icons/toolbar/e/topic@2x.png index 8e997295022a4475bee5873109557a1f172d67ff..178482588854d30af59bf0e32d4d0e44508c97d6 100644 GIT binary patch delta 1362 zcmV-Y1+Ds}4Dt$)F@G#cL_t(|0qvR1Y8y!q$48@>z~%$;q1fzYulojmhrogZegKgt z^8*-SSjaOZhmd3L3k$~1t|9mk;#f-kOZ^|Ws%JDBtJ5p9)gV=OS9NvQud7EhqpI@a z1e|~qZ~{)i2{-{K-~^n26L11fzzN(X0;5ukJvljfIiJsuu79tuC#B|GXP)tRd_EeD zrUwTHZ`ZN!v$@x2kV_Ak`}_Noy}iA}C3bZ#AMP&ekhdyx895SfkSMG}qA4HFae8_> zdH4SPk#xO~&&H(~P-G@y3S5bCB=If+4qv+H-8ekC_@Rm@xig&fMBa*;1B)L zc%1@YKcW05K=sH;Fg$VqqkREnYlb2Cpik^ob#sJ~ha<6VGB(uFhoa-T3EGqID;v<` z<72MBdvy#bSi}RGY!e;plx+@U9qW{^U-BIsEcJ!8wE5noFB{Nx77+)$%09_ZV+=pE zF{;)kZGRzAhK_G_+R>RE=;7fZPx8`~Yh`d4!RzJHH4qsUfWT~NbEsq1!H#{AZ8Ju6 znys`C^X3rQfv#E<1JdiI7?OOFF#r<(h%j)pT~WL)o@KKM|` z^cf`mQl810u(nQL0~N(GRDNNnA3lEE+ShjjxpkTs0~+2pW_d-{8O;_biXHhah_%QP z9DitL%nsCnW+sr?ooA>6%}gM(JI~O}K#Sdn{`=>Xm-4`VG@H$~>VNsVuFtD_G=2KV z#ohW}9xxyN`uk+(;gd8c?8^>ofk#Q&Slw;f^d<7@@?vuN_opLqljWhKScW1qcOE>F zhw<;Sc07^eO;LCDsEtQ z018%XiwICNhJD(>&C4`jGf7%03v_n1Sb>eN$<}oPwhm0jrg54cJKm@_XqE+9;kZkg z2>={ZNR%W#(_ycnMs2Sk&Gi;@XfeP|GZo&t| zumDG!cr1PNNju*9-=Lix=*qP)LsuG!vM*r5gzPGW3O)Rx4T-YO_=V-*Z%#3I;Lrh| z-#nf_`|a^!7=w$09^%jf+R)!We}8?cp1=B%g+<{E<&ToAebtS6l2V4)JP=hGc4Fn` znDL4KA-lQSwk%M6N?N_3JX#CTdbKHT^|x;q1{!{pde>`!m}YXHncSy_6VTj;_Du-D zc}g*$bzPlbeZ8LS+?QX31b_rXXc|{b20_olIwkts>P;Ui^a*3u<>koNx=X6-dw1`D z`KlgIFE1*2eOGPS>$^%`-;Jlh?8ON<0Vm)DoPZN>0#3jQH~}Z%1e|~q`2P|30UG$O UrgZBA?*IS*07*qoM6N<$f@9T|KL7v# delta 1542 zcmV+h2Ko8&3Z)E?F@N7lL_t(|0qvQ+ZW~7s$9YG^A5DM&VI%|rQn>IV=p9_C&;zJV z6XaRaq~!ysP?auyTo|rXxCjs!g4h^o62<0S=07w4y}b{Lq`2P5!LC5g-pR1PXyd;8P+{&34xUoK_nD|sEC% zAdioaXDN40Hh-X+1S>`^2ovMmn%YJ;0QQ6#`Vu>gVIDx`eDG}=8-uUw_gMqx*`?(L ziloq(EF>=F1sGmmnlP&ldbN*$OxlZC4-jF(pM96=FMZAjlThGP zMIm_yzRjM#l#Cr70gMGH4Yw6A{q|xgS<4DEuAot$5Py-HCmtkpQH2tAh(TZ80Jl{i z#KU;xuT$XdBeeensBSq)hFcC`bj(3cRv40Z{m5Qb-4;e2R$?0}*83PkQ-9tB9ZC0= z4Cv+MCD*@sbxg=DVuw&|qGO+ODqyT*pAz=H*dCxa=4+XXeaKicpt~$0PWUeSQH2hS z5r;Md)qmtAZ6VS2^`8v7VK6z+^Ye4==s>+XxT>9_0d9tU4&!heR9bhw;s%dx8#uYk!PHZ&`tMDG7rp0rn|Fb)rhyq6*}V z2@*E3UO?+^AaKTTNga30Kz-0e>1gn=Kz&{STb@L=%dT#uiM4#>d&Q2 zm*k(0Y!!;ite-woOaR54q#MpP_%Aqkw11I-0+(|Vo^_ai^b?0hwU~%EY_PO&c8e;+ z7bD2}iL5E%uE_^f5(vN~JMAM&G+eMub)aux2N`~XqgKfZsOx=feoBcL@Ki-G8?`D7e^gIcRtQFe$*C2g<`F~du)GJUie9;z;zqxCCR5a$XGUm->{17NXCo51s!! sPzV$Pg+L)t2owT^Kp{{F{7(t|3t3EVBCTJ)+yDRo07*qoM6N<$f_2{GlmGw# diff --git a/bundles/org.xmind.ui.menus/plugin.xml b/bundles/org.xmind.ui.menus/plugin.xml index bf5a8a3ff..ee9b79b6d 100644 --- a/bundles/org.xmind.ui.menus/plugin.xml +++ b/bundles/org.xmind.ui.menus/plugin.xml @@ -1,2235 +1,2230 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.menus/pom.xml b/bundles/org.xmind.ui.menus/pom.xml index 10fe4d372..7440d7bac 100644 --- a/bundles/org.xmind.ui.menus/pom.xml +++ b/bundles/org.xmind.ui.menus/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.menus - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.menus + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.menus/src/org/xmind/ui/menus/MenusPlugin.java b/bundles/org.xmind.ui.menus/src/org/xmind/ui/menus/MenusPlugin.java index 488df8818..9722d5f49 100644 --- a/bundles/org.xmind.ui.menus/src/org/xmind/ui/menus/MenusPlugin.java +++ b/bundles/org.xmind.ui.menus/src/org/xmind/ui/menus/MenusPlugin.java @@ -1,56 +1,56 @@ -package org.xmind.ui.menus; - -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class MenusPlugin extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.ui.menus"; //$NON-NLS-1$ - - // The shared instance - private static MenusPlugin plugin; - - /** - * The constructor - */ - public MenusPlugin() { - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext - * ) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext - * ) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static MenusPlugin getDefault() { - return plugin; - } - -} +package org.xmind.ui.menus; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class MenusPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.ui.menus"; //$NON-NLS-1$ + + // The shared instance + private static MenusPlugin plugin; + + /** + * The constructor + */ + public MenusPlugin() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static MenusPlugin getDefault() { + return plugin; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/.classpath b/bundles/org.xmind.ui.mindmap/.classpath index 195840c83..519409328 100644 --- a/bundles/org.xmind.ui.mindmap/.classpath +++ b/bundles/org.xmind.ui.mindmap/.classpath @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.mindmap/.gitignore b/bundles/org.xmind.ui.mindmap/.gitignore index 3ffab8564..278670924 100644 --- a/bundles/org.xmind.ui.mindmap/.gitignore +++ b/bundles/org.xmind.ui.mindmap/.gitignore @@ -1,15 +1,15 @@ -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Folder containing Maven build results -target/ +.metadata +bin +tmp +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Folder containing Maven build results +target/ diff --git a/bundles/org.xmind.ui.mindmap/.options b/bundles/org.xmind.ui.mindmap/.options index 3de363594..9a6e38d47 100644 --- a/bundles/org.xmind.ui.mindmap/.options +++ b/bundles/org.xmind.ui.mindmap/.options @@ -1,4 +1,4 @@ -# Turn on/off general debugging for this plugin: -org.xmind.ui.mindmap/debug=false -org.xmind.ui.mindmap/debug/autosave=false -org.xmind.ui.mindmap/debug/save/localfile/backup=false +# Turn on/off general debugging for this plugin: +org.xmind.ui.mindmap/debug=false +org.xmind.ui.mindmap/debug/autosave=false +org.xmind.ui.mindmap/debug/save/localfile/backup=false diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.resources.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.resources.prefs index 4824b8026..99f26c020 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.resources.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.runtime.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.runtime.prefs index f8a67de1d..deae05a97 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.runtime.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.core.runtime.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -line.separator=\r\n +eclipse.preferences.version=1 +line.separator=\r\n diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.launching.prefs index dcf51f5a2..3bb235278 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.launching.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.launching.prefs @@ -1,2 +1,2 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=ignore diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.wst.validation.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.wst.validation.prefs index ee03c5911..e4c7c66c8 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.wst.validation.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.wst.validation.prefs @@ -1,9 +1,9 @@ -#Fri Nov 21 20:46:03 CST 2008 -DELEGATES_PREFERENCE=delegateValidatorList -USER_BUILD_PREFERENCE=enabledBuildValidatorList -USER_MANUAL_PREFERENCE=enabledManualValidatorList -USER_PREFERENCE=overrideGlobalPreferencesfalse -eclipse.preferences.version=1 -override=false -suspend=false -vf.version=3 +#Fri Nov 21 20:46:03 CST 2008 +DELEGATES_PREFERENCE=delegateValidatorList +USER_BUILD_PREFERENCE=enabledBuildValidatorList +USER_MANUAL_PREFERENCE=enabledManualValidatorList +USER_PREFERENCE=overrideGlobalPreferencesfalse +eclipse.preferences.version=1 +override=false +suspend=false +vf.version=3 diff --git a/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF index 39e741697..ee1a233ad 100644 --- a/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF @@ -1,84 +1,84 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.xmind.ui.mindmap;singleton:=true -Bundle-Version: 3.7.0.qualifier -Bundle-ClassPath: . -Bundle-Activator: org.xmind.ui.internal.MindMapUIPlugin -Bundle-Vendor: %providerName -Bundle-Localization: plugin -Export-Package: org.xmind.ui, - org.xmind.ui.actions, - org.xmind.ui.blackbox, - org.xmind.ui.branch, - org.xmind.ui.commands, - org.xmind.ui.decorations, - org.xmind.ui.dialogs, - org.xmind.ui.editor, - org.xmind.ui.internal;x-friends:="org.xmind.ui", - org.xmind.ui.internal.actions;x-friends:="org.xmind.ui", - org.xmind.ui.internal.branch;x-friends:="org.xmind.ui", - org.xmind.ui.internal.comments;x-friends:="org.xmind.ui", - org.xmind.ui.internal.decorations;x-friends:="org.xmind.ui", - org.xmind.ui.internal.decorators;x-internal:=true, - org.xmind.ui.internal.dialogs;x-friends:="org.xmind.ui", - org.xmind.ui.internal.dnd;x-friends:="org.xmind.ui", - org.xmind.ui.internal.e4handlers;x-friends:="org.xmind.ui", - org.xmind.ui.internal.e4models, - org.xmind.ui.internal.editor;x-friends:="org.xmind.ui", - org.xmind.ui.internal.editpolicies;x-friends:="org.xmind.ui", - org.xmind.ui.internal.figures;x-internal:=true, - org.xmind.ui.internal.findreplace;x-internal:=true, - org.xmind.ui.internal.graphicalpolicies;x-friends:="org.xmind.ui", - org.xmind.ui.internal.handlers;x-friends:="org.xmind.ui", - org.xmind.ui.internal.layers;x-internal:=true, - org.xmind.ui.internal.layouts;x-internal:=true, - org.xmind.ui.internal.mindmap;x-friends:="org.xmind.ui", - org.xmind.ui.internal.notes;x-friends:="org.xmind.ui", - org.xmind.ui.internal.outline;x-internal:=true, - org.xmind.ui.internal.popover, - org.xmind.ui.internal.prefs;x-friends:="org.xmind.ui", - org.xmind.ui.internal.print;x-internal:=true, - org.xmind.ui.internal.print.multipage;x-internal:=true, - org.xmind.ui.internal.properties;x-friends:="org.xmind.ui", - org.xmind.ui.internal.protocols;x-friends:="org.xmind.ui", - org.xmind.ui.internal.resourcemanager, - org.xmind.ui.internal.spellsupport;x-friends:="org.xmind.ui", - org.xmind.ui.internal.svgsupport;x-internal:=true, - org.xmind.ui.internal.tools;x-friends:="org.xmind.ui", - org.xmind.ui.internal.utils, - org.xmind.ui.internal.views;x-friends:="org.xmind.ui", - org.xmind.ui.internal.wizards;x-friends:="org.xmind.ui", - org.xmind.ui.internal.workbench;x-friends:="org.xmind.ui", - org.xmind.ui.mindmap, - org.xmind.ui.prefs, - org.xmind.ui.properties, - org.xmind.ui.style, - org.xmind.ui.tools, - org.xmind.ui.util, - org.xmind.ui.wizards -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.core.expressions, - org.eclipse.core.filesystem, - org.eclipse.core.resources, - org.apache.commons.codec, - org.xmind.core.runtime;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, - org.xmind.gef.ui;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, - org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.browser;bundle-version="[3.7.0,3.8.0)", - org.xmind.ui.spelling;bundle-version="[3.7.0,3.8.0)", - org.xmind.core.command;bundle-version="[3.7.0,3.8.0)", - org.eclipse.swt, - org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", - org.xmind.core, - org.eclipse.e4.core.commands, - org.eclipse.e4.core.di, - org.eclipse.e4.core.services -Import-Package: javax.annotation;version="1.0.0";resolution:=optional, - javax.inject;version="1.0.0", - org.json -Bundle-ActivationPolicy: lazy -Eclipse-LazyStart: true -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Service-Component: OSGI-INF/serviceManager.xml +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.xmind.ui.mindmap;singleton:=true +Bundle-Version: 3.7.0.qualifier +Bundle-ClassPath: . +Bundle-Activator: org.xmind.ui.internal.MindMapUIPlugin +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Export-Package: org.xmind.ui, + org.xmind.ui.actions, + org.xmind.ui.blackbox, + org.xmind.ui.branch, + org.xmind.ui.commands, + org.xmind.ui.decorations, + org.xmind.ui.dialogs, + org.xmind.ui.editor, + org.xmind.ui.internal;x-friends:="org.xmind.ui", + org.xmind.ui.internal.actions;x-friends:="org.xmind.ui", + org.xmind.ui.internal.branch;x-friends:="org.xmind.ui", + org.xmind.ui.internal.comments;x-friends:="org.xmind.ui", + org.xmind.ui.internal.decorations;x-friends:="org.xmind.ui", + org.xmind.ui.internal.decorators;x-internal:=true, + org.xmind.ui.internal.dialogs;x-friends:="org.xmind.ui", + org.xmind.ui.internal.dnd;x-friends:="org.xmind.ui", + org.xmind.ui.internal.e4handlers;x-friends:="org.xmind.ui", + org.xmind.ui.internal.e4models, + org.xmind.ui.internal.editor;x-friends:="org.xmind.ui", + org.xmind.ui.internal.editpolicies;x-friends:="org.xmind.ui", + org.xmind.ui.internal.figures;x-internal:=true, + org.xmind.ui.internal.findreplace;x-internal:=true, + org.xmind.ui.internal.graphicalpolicies;x-friends:="org.xmind.ui", + org.xmind.ui.internal.handlers;x-friends:="org.xmind.ui", + org.xmind.ui.internal.layers;x-internal:=true, + org.xmind.ui.internal.layouts;x-internal:=true, + org.xmind.ui.internal.mindmap;x-friends:="org.xmind.ui", + org.xmind.ui.internal.notes;x-friends:="org.xmind.ui", + org.xmind.ui.internal.outline;x-internal:=true, + org.xmind.ui.internal.popover, + org.xmind.ui.internal.prefs;x-friends:="org.xmind.ui", + org.xmind.ui.internal.print;x-internal:=true, + org.xmind.ui.internal.print.multipage;x-internal:=true, + org.xmind.ui.internal.properties;x-friends:="org.xmind.ui", + org.xmind.ui.internal.protocols;x-friends:="org.xmind.ui", + org.xmind.ui.internal.resourcemanager, + org.xmind.ui.internal.spellsupport;x-friends:="org.xmind.ui", + org.xmind.ui.internal.svgsupport;x-internal:=true, + org.xmind.ui.internal.tools;x-friends:="org.xmind.ui", + org.xmind.ui.internal.utils, + org.xmind.ui.internal.views;x-friends:="org.xmind.ui", + org.xmind.ui.internal.wizards;x-friends:="org.xmind.ui", + org.xmind.ui.internal.workbench;x-friends:="org.xmind.ui", + org.xmind.ui.mindmap, + org.xmind.ui.prefs, + org.xmind.ui.properties, + org.xmind.ui.style, + org.xmind.ui.tools, + org.xmind.ui.util, + org.xmind.ui.wizards +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.expressions, + org.eclipse.core.filesystem, + org.eclipse.core.resources, + org.apache.commons.codec, + org.xmind.core.runtime;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, + org.xmind.gef.ui;bundle-version="[3.7.0,3.8.0)";visibility:=reexport, + org.xmind.ui.toolkit;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.browser;bundle-version="[3.7.0,3.8.0)", + org.xmind.ui.spelling;bundle-version="[3.7.0,3.8.0)", + org.xmind.core.command;bundle-version="[3.7.0,3.8.0)", + org.eclipse.swt, + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", + org.xmind.core, + org.eclipse.e4.core.commands, + org.eclipse.e4.core.di, + org.eclipse.e4.core.services +Import-Package: javax.annotation;version="1.0.0";resolution:=optional, + javax.inject;version="1.0.0", + org.json +Bundle-ActivationPolicy: lazy +Eclipse-LazyStart: true +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Service-Component: OSGI-INF/serviceManager.xml diff --git a/bundles/org.xmind.ui.mindmap/OSGI-INF/serviceManager.xml b/bundles/org.xmind.ui.mindmap/OSGI-INF/serviceManager.xml index 9a1422f9c..45b4ff594 100644 --- a/bundles/org.xmind.ui.mindmap/OSGI-INF/serviceManager.xml +++ b/bundles/org.xmind.ui.mindmap/OSGI-INF/serviceManager.xml @@ -1,5 +1,5 @@ - - - - - + + + + + diff --git a/bundles/org.xmind.ui.mindmap/about.html b/bundles/org.xmind.ui.mindmap/about.html index 9aac69101..424d7e78e 100644 --- a/bundles/org.xmind.ui.mindmap/about.html +++ b/bundles/org.xmind.ui.mindmap/about.html @@ -1,22 +1,22 @@ - - - - -License - - -

    License

    - -

    Nov 6, 2008

    - -

    -XMind 3 is dual licensed under 2 open source licenses: -the Eclipse Public License v1.0 (EPL), -which is available at http://www.eclipse.org/legal/epl-v10.html , -and the GNU Lesser General Public License v3 (LGPL), -which is available at http://www.gnu.org/licenses/lgpl.html . -

    - - - + + + + +License + + +

    License

    + +

    Nov 6, 2008

    + +

    +XMind 3 is dual licensed under 2 open source licenses: +the Eclipse Public License v1.0 (EPL), +which is available at http://www.eclipse.org/legal/epl-v10.html , +and the GNU Lesser General Public License v3 (LGPL), +which is available at http://www.gnu.org/licenses/lgpl.html . +

    + + + diff --git a/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg b/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg index f793e1169..b2153b30d 100644 --- a/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg +++ b/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg @@ -1,30 +1,30 @@ - - - - Oval 43 Copy 16 - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - + + + + Oval 43 Copy 16 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi b/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi index cef262973..ec0167286 100644 --- a/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi +++ b/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi @@ -1,66 +1,61 @@ - - - - - - DialogPart - - - - - DialogPart - - - - - - DialogPart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + DialogPart + + + + + DialogPart + + + + + DialogPart + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.mindmap/plugin.properties b/bundles/org.xmind.ui.mindmap/plugin.properties index 69f70e4c7..7cf5f4e2c 100644 --- a/bundles/org.xmind.ui.mindmap/plugin.properties +++ b/bundles/org.xmind.ui.mindmap/plugin.properties @@ -1,75 +1,75 @@ -#Properties file for org.xmind.ui.mindmap -providerName = XMind Ltd. -pluginName = XMind MindMap UI - -org.xmind.ui.resourceManager.marker.label=Marker -org.xmind.ui.resourceManager.theme.label=Theme -org.xmind.ui.resourceManager.style.label=Style -org.xmind.ui.resourceManager.template.label=Template - -org.xmind.ui.toolkit.prefPage.section.dnd.label=Drag and Drop -org.xmind.ui.toolkit.prefPage.section.theme.label=Theme -org.xmind.ui.toolkit.prefPage.section.authorInfo.label=Author Info -org.xmind.ui.toolkit.prefPage.section.undo.label=Undo / Redo -org.xmind.ui.toolkit.prefPage.section.position.label=Topic Positioning -org.xmind.ui.toolkit.prefPage.section.others.label=Others - -command.resourceManager.theme.setDefault.label = Set As Default -command.resourceManager.theme.setDefault.tooltip = Set As Default Theme -command.resourceManager.theme.rename.label = Rename -command.resourceManager.theme.duplicate.label = Duplicate -command.resourceManager.theme.delete.label = Delete -command.resourceManager.marker.delete.label = Delete -command.resourceManager.marker.rename.label = Rename -command.resourceManager.template.rename.label = Rename -command.resourceManager.template.duplicate.label = Duplicate -command.resourceManager.template.delete.label = Delete -command.resourceManager.style.edit.label = Edit Style [Pro] -command.resourceManager.style.rename.label = Rename -command.resourceManager.style.duplicate.label = Duplicate -command.resourceManager.style.delete.label = Delete -command.themePart.new.label = New Theme [Pro] -command.themePart.extract.label = Extract Theme [Pro] -command.themePart.extract.tooptip = Extract Current Theme -command.themePart.manage.label = Manage Themes -command.themePart.manage.tooltip = Manage Themes -command.themePart.import.label = Import Themes [Pro] -command.themePart.import.tooltip = Import Themes -command.themePart.export.label = Export Themes [Pro] -command.themePart.export.tooltip = Export Themes -category.resourceManager.name = Resource Manager - -part.resourceManager.label = Resource Manager -part.resourceManager.tooltip = Resource Manager -part.image.label = Image -part.image.tooltop = Image -part.lns.label = Local Network Sharing -part.lns.tooltip = Local Network Sharing -part.outline.label = Outline -part.outline.tooltip = Outline -part.progress.label = Progress -part.progress.tooltip = Progress -part.themes.label = Themes -part.themes.tooltip = Themes -part.markers.label = Markers -part.markers.tooltip = Markers -part.comments.label = Comments -part.comments.tooltip = Comments -part.notes.label = Notes -part.notes.tooltip = Notes -part.format.label = Format -part.format.tooltip = Format - -part.command.showDialogPart.name = Show Dialog Part -part.command.showDialogPart.description = Show dialog for a dialog part -part.command.togglePart.name = Toggle Model Part -part.command.togglePart.description = Toggle Model Part -part.command.showModelPart.name = Show Model Part -part.command.setDefaultTheme = Set As Default Theme -part.command.renameResource.name = Rename Resource -part.command.deleteResource.name = Delete Resource -part.command.editResource.name = Edit Resource -part.command.duplicateResource.name = Duplicate Resource -part.command.showPopover.name = Show Popover -part.command.openLocalFile.name = Open Local File -part.command.openCloseModelPart.name = Toggle Model Part +#Properties file for org.xmind.ui.mindmap +providerName = XMind Ltd. +pluginName = XMind MindMap UI + +org.xmind.ui.resourceManager.marker.label=Marker +org.xmind.ui.resourceManager.theme.label=Theme +org.xmind.ui.resourceManager.style.label=Style +org.xmind.ui.resourceManager.template.label=Template + +org.xmind.ui.toolkit.prefPage.section.dnd.label=Drag and Drop +org.xmind.ui.toolkit.prefPage.section.theme.label=Theme +org.xmind.ui.toolkit.prefPage.section.authorInfo.label=Author Info +org.xmind.ui.toolkit.prefPage.section.undo.label=Undo / Redo +org.xmind.ui.toolkit.prefPage.section.position.label=Topic Positioning +org.xmind.ui.toolkit.prefPage.section.others.label=Others + +command.resourceManager.theme.setDefault.label = Set As Default +command.resourceManager.theme.setDefault.tooltip = Set As Default Theme +command.resourceManager.theme.rename.label = Rename +command.resourceManager.theme.duplicate.label = Duplicate +command.resourceManager.theme.delete.label = Delete +command.resourceManager.marker.delete.label = Delete +command.resourceManager.marker.rename.label = Rename +command.resourceManager.template.rename.label = Rename +command.resourceManager.template.duplicate.label = Duplicate +command.resourceManager.template.delete.label = Delete +command.resourceManager.style.edit.label = Edit Style [Pro] +command.resourceManager.style.rename.label = Rename +command.resourceManager.style.duplicate.label = Duplicate +command.resourceManager.style.delete.label = Delete +command.themePart.new.label = New Theme [Pro] +command.themePart.extract.label = Extract Theme [Pro] +command.themePart.extract.tooptip = Extract Current Theme +command.themePart.manage.label = Manage Themes +command.themePart.manage.tooltip = Manage Themes +command.themePart.import.label = Import Themes [Pro] +command.themePart.import.tooltip = Import Themes +command.themePart.export.label = Export Themes [Pro] +command.themePart.export.tooltip = Export Themes +category.resourceManager.name = Resource Manager + +part.resourceManager.label = Resource Manager +part.resourceManager.tooltip = Resource Manager +part.image.label = Image +part.image.tooltop = Image +part.lns.label = Local Network Sharing +part.lns.tooltip = Local Network Sharing +part.outline.label = Outline +part.outline.tooltip = Outline +part.progress.label = Progress +part.progress.tooltip = Progress +part.themes.label = Themes +part.themes.tooltip = Themes +part.markers.label = Markers +part.markers.tooltip = Markers +part.comments.label = Comments +part.comments.tooltip = Comments +part.notes.label = Notes +part.notes.tooltip = Notes +part.format.label = Format +part.format.tooltip = Format + +part.command.showDialogPart.name = Show Dialog Part +part.command.showDialogPart.description = Show dialog for a dialog part +part.command.togglePart.name = Toggle Model Part +part.command.togglePart.description = Toggle Model Part +part.command.showModelPart.name = Show Model Part +part.command.setDefaultTheme = Set As Default Theme +part.command.renameResource.name = Rename Resource +part.command.deleteResource.name = Delete Resource +part.command.editResource.name = Edit Resource +part.command.duplicateResource.name = Duplicate Resource +part.command.showPopover.name = Show Popover +part.command.openLocalFile.name = Open Local File +part.command.openCloseModelPart.name = Toggle Model Part diff --git a/bundles/org.xmind.ui.mindmap/plugin.xml b/bundles/org.xmind.ui.mindmap/plugin.xml index 14d68098e..a03a6b606 100644 --- a/bundles/org.xmind.ui.mindmap/plugin.xml +++ b/bundles/org.xmind.ui.mindmap/plugin.xml @@ -1,382 +1,377 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - - -
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    diff --git a/bundles/org.xmind.ui.mindmap/pom.xml b/bundles/org.xmind.ui.mindmap/pom.xml index 0d6d74727..9a11cf042 100644 --- a/bundles/org.xmind.ui.mindmap/pom.xml +++ b/bundles/org.xmind.ui.mindmap/pom.xml @@ -1,16 +1,16 @@ - - - 4.0.0 - org.xmind.cathy.plugins - org.xmind.ui.mindmap - 3.7.0-SNAPSHOT - eclipse-plugin - - org.xmind.releng - org.xmind.cathy.releng - 3.7.0-SNAPSHOT - ../../ - - + + + 4.0.0 + org.xmind.cathy.plugins + org.xmind.ui.mindmap + 3.7.0-SNAPSHOT + eclipse-plugin + + org.xmind.releng + org.xmind.cathy.releng + 3.7.0-SNAPSHOT + ../../ + + diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IEditorHistory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IEditorHistory.java index 15688a8ff..40910320f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IEditorHistory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IEditorHistory.java @@ -1,45 +1,45 @@ -package org.xmind.ui; - -import java.net.URI; - -/** - * @deprecated - */ -@Deprecated -public interface IEditorHistory { - - public static interface IEditorHistoryListener { - - void editorHistoryChanged(); - - } - - URI[] getRecentInputURIs(int size); - - URI[] getAllInputURIs(); - - void add(URI inputURI); - - void remove(URI inputURI); - - String getInfo(URI inputURI); - - String getThumbnail(URI inputURI); - - void addThumbnail(URI inputURI, String originThumbnailPath); - - void removeThumbnail(URI inputURI); - - void pin(URI inputURI); - - void unPin(URI inputURI); - - boolean isPin(URI inputURI); - - void clear(); - - void removeEditorHistoryListener(IEditorHistoryListener listener); - - void addEditorHistoryListener(IEditorHistoryListener listener); - -} +package org.xmind.ui; + +import java.net.URI; + +/** + * @deprecated + */ +@Deprecated +public interface IEditorHistory { + + public static interface IEditorHistoryListener { + + void editorHistoryChanged(); + + } + + URI[] getRecentInputURIs(int size); + + URI[] getAllInputURIs(); + + void add(URI inputURI); + + void remove(URI inputURI); + + String getInfo(URI inputURI); + + String getThumbnail(URI inputURI); + + void addThumbnail(URI inputURI, String originThumbnailPath); + + void removeThumbnail(URI inputURI); + + void pin(URI inputURI); + + void unPin(URI inputURI); + + boolean isPin(URI inputURI); + + void clear(); + + void removeEditorHistoryListener(IEditorHistoryListener listener); + + void addEditorHistoryListener(IEditorHistoryListener listener); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveFeedback.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveFeedback.java index 3095c4ccf..af190a627 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveFeedback.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveFeedback.java @@ -1,52 +1,52 @@ -package org.xmind.ui; - -import java.util.Properties; - -/** - * @deprecated - */ -@Deprecated -public interface IPreSaveInteractiveFeedback { - - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_RESULT = "org.xmind.ui.preSaveInteractiveResult"; //$NON-NLS-1$ - - /** - * Custom - */ - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_FEEDBACK_1 = "org.xmind.ui.preSaveInteractive.feedback.1"; //$NON-NLS-1$ - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_FEEDBACK_2 = "org.xmind.ui.preSaveInteractive.feedback.2"; //$NON-NLS-1$ - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_FEEDBACK_3 = "org.xmind.ui.preSaveInteractive.feedback.3"; //$NON-NLS-1$ - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_FEEDBACK_4 = "org.xmind.ui.preSaveInteractive.feedback.4"; //$NON-NLS-1$ - /** - * @deprecated - */ - @Deprecated - String INTERACTIVE_FEEDBACK_5 = "org.xmind.ui.preSaveInteractive.feedback.5"; //$NON-NLS-1$ - - /** - * @deprecated - */ - @Deprecated - Properties interactiveFeedback(); - -} +package org.xmind.ui; + +import java.util.Properties; + +/** + * @deprecated + */ +@Deprecated +public interface IPreSaveInteractiveFeedback { + + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_RESULT = "org.xmind.ui.preSaveInteractiveResult"; //$NON-NLS-1$ + + /** + * Custom + */ + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_FEEDBACK_1 = "org.xmind.ui.preSaveInteractive.feedback.1"; //$NON-NLS-1$ + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_FEEDBACK_2 = "org.xmind.ui.preSaveInteractive.feedback.2"; //$NON-NLS-1$ + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_FEEDBACK_3 = "org.xmind.ui.preSaveInteractive.feedback.3"; //$NON-NLS-1$ + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_FEEDBACK_4 = "org.xmind.ui.preSaveInteractive.feedback.4"; //$NON-NLS-1$ + /** + * @deprecated + */ + @Deprecated + String INTERACTIVE_FEEDBACK_5 = "org.xmind.ui.preSaveInteractive.feedback.5"; //$NON-NLS-1$ + + /** + * @deprecated + */ + @Deprecated + Properties interactiveFeedback(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveProvider.java index 99ed07045..3dbd37746 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveInteractiveProvider.java @@ -1,44 +1,44 @@ -package org.xmind.ui; - -/** - * @deprecated - */ -@Deprecated -public interface IPreSaveInteractiveProvider { - - /** - * Interactive Type - */ - /** - * @deprecated - */ - @Deprecated - int TYPE_PRE_SAVE_AS = 1 << 1; - /** - * @deprecated - */ - @Deprecated - int TYPE_PRE_SAVE = 1 << 2; - - /** - * Returned Instruction - */ - /** - * @deprecated - */ - @Deprecated - String INSTRUCTION_PROMOTE = "org.xmind.ui.preSaveInteractiveProvider.instrction.promote"; //$NON-NLS-1$ - /** - * @deprecated - */ - @Deprecated - String INSTRUCTION_END = "org.xmind.ui.preSaveInteractiveProvider.instrction.end"; //$NON-NLS-1$ - - /** - * @deprecated - */ - @Deprecated - IPreSaveInteractiveFeedback executeInteractive(Object source, - int interactiveType); - -} +package org.xmind.ui; + +/** + * @deprecated + */ +@Deprecated +public interface IPreSaveInteractiveProvider { + + /** + * Interactive Type + */ + /** + * @deprecated + */ + @Deprecated + int TYPE_PRE_SAVE_AS = 1 << 1; + /** + * @deprecated + */ + @Deprecated + int TYPE_PRE_SAVE = 1 << 2; + + /** + * Returned Instruction + */ + /** + * @deprecated + */ + @Deprecated + String INSTRUCTION_PROMOTE = "org.xmind.ui.preSaveInteractiveProvider.instrction.promote"; //$NON-NLS-1$ + /** + * @deprecated + */ + @Deprecated + String INSTRUCTION_END = "org.xmind.ui.preSaveInteractiveProvider.instrction.end"; //$NON-NLS-1$ + + /** + * @deprecated + */ + @Deprecated + IPreSaveInteractiveFeedback executeInteractive(Object source, + int interactiveType); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveListener.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveListener.java index 5d0bf0b54..bb6663645 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveListener.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/IPreSaveListener.java @@ -1,27 +1,27 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui; - -import org.eclipse.ui.IWorkbenchPart; - -/** - * - * @author Frank Shaka - * @deprecated - */ -public interface IPreSaveListener { - - boolean preSave(IWorkbenchPart part); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui; + +import org.eclipse.ui.IWorkbenchPart; + +/** + * + * @author Frank Shaka + * @deprecated + */ +public interface IPreSaveListener { + + boolean preSave(IWorkbenchPart part); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/ISaveablePart3.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/ISaveablePart3.java index 3044af1f2..493bd1f72 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/ISaveablePart3.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/ISaveablePart3.java @@ -1,31 +1,31 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui; - -/** - * - * @author Frank Shaka - * @deprecated - */ -public interface ISaveablePart3 { - - /** - * - * @param listener - */ - void addPreSaveListener(IPreSaveListener listener); - - void removePreSaveListener(IPreSaveListener listener); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui; + +/** + * + * @author Frank Shaka + * @deprecated + */ +public interface ISaveablePart3 { + + /** + * + * @param listener + */ + void addPreSaveListener(IPreSaveListener listener); + + void removePreSaveListener(IPreSaveListener listener); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/actions/MindMapActionFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/actions/MindMapActionFactory.java index 334911688..d9d0dadf3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/actions/MindMapActionFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/actions/MindMapActionFactory.java @@ -1,800 +1,801 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.actions; - -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.LabelRetargetAction; -import org.eclipse.ui.actions.RetargetAction; -import org.eclipse.ui.internal.WorkbenchMessages; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.actions.SaveAsTemplateAction; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -public class MindMapActionFactory { - - @Deprecated - public static final ActionFactory NEW_WORKBOOK = new ActionFactory( - "org.xmind.ui.newWorkbook") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - org.xmind.ui.internal.actions.NewWorkbookAction action = new org.xmind.ui.internal.actions.NewWorkbookAction( - window); - action.setId(getId()); - return action; - } - }; - - @Deprecated - public static final ActionFactory OPEN = new ActionFactory( - "org.xmind.ui.open") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - org.xmind.ui.internal.actions.OpenWorkbookAction action = new org.xmind.ui.internal.actions.OpenWorkbookAction( - window); - action.setId(getId()); - return action; - } - }; - - @Deprecated - public static final ActionFactory SAVE_TEMPLATE = new ActionFactory( - "org.xmind.ui.saveTemplate") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - return new SaveAsTemplateAction(getId(), window); - } - }; - - public static final ActionFactory SELECT_BROTHERS = new ActionFactory( - "org.xmind.ui.selectBrothers") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.SelectBrothers_text); - action.setToolTipText(MindMapMessages.SelectBrothers_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.selectBrothers"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory SELECT_CHILDREN = new ActionFactory( - "org.xmind.ui.selectChildren") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.SelectChildren_text); - action.setToolTipText(MindMapMessages.SelectChildren_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.selectChildren"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory GO_HOME = new ActionFactory( - "org.xmind.ui.selectHome") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.GoToCentral_text); - action.setToolTipText(MindMapMessages.GoToCentral_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.goHome"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory ZOOM_IN = new ActionFactory( - "org.xmind.ui.zoomIn") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.ZoomIn_text); - action.setToolTipText(MindMapMessages.ZoomIn_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.zoomIn"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.ZOOMIN, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.ZOOMIN, false)); - return action; - } - }; - - public static final ActionFactory ZOOM_OUT = new ActionFactory( - "org.xmind.ui.zoomOut") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.ZoomOut_text); - action.setToolTipText(MindMapMessages.ZoomOut_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.zoomOut"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.ZOOMOUT, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.ZOOMOUT, false)); - return action; - } - }; - - public static final ActionFactory ACTUAL_SIZE = new ActionFactory( - "org.xmind.ui.actualSize") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.ActualSize_text); - action.setToolTipText(MindMapMessages.ActualSize_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.actualSize"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.ACTUAL_SIZE, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.ACTUAL_SIZE, false)); - return action; - } - }; - - public static final ActionFactory FIT_MAP = new ActionFactory( - "org.xmind.ui.fitMap") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.FitMap_text); - action.setToolTipText(MindMapMessages.FitMap_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.fitMap"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.FIT_SIZE, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.FIT_SIZE, false)); - return action; - } - }; - - public static final ActionFactory FIT_SELECTION = new ActionFactory( - "org.xmind.ui.fitSelection") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.FitSelection_text); - action.setToolTipText(MindMapMessages.FitSelection_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.fitSelection"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.FIT_SELECTION, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.FIT_SELECTION, false)); - return action; - } - }; - - public static final ActionFactory INSERT_TOPIC = new ActionFactory( - "org.xmind.ui.insertTopic") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.InsertTopic_text); - action.setToolTipText(MindMapMessages.InsertTopic_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.insertTopic"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_AFTER, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_AFTER, false)); - return action; - } - }; - - public static final ActionFactory INSERT_SUBTOPIC = new ActionFactory( - "org.xmind.ui.insertSubtopic") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.InsertSubtopic_text); - action.setToolTipText(MindMapMessages.InsertSubtopic_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.insertSubtopic"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.INSERT_SUB, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_SUB, false)); - return action; - } - }; - - public static final ActionFactory INSERT_TOPIC_BEFORE = new ActionFactory( - "org.xmind.ui.insertTopicBefore") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.InsertTopicBefore_text); - action.setToolTipText(MindMapMessages.InsertTopicBefore_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.insertTopicBefore"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_BEFORE, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_BEFORE, false)); - return action; - } - }; - - public static final ActionFactory INSERT_PARENT_TOPIC = new ActionFactory( - "org.xmind.ui.insertParentTopic") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.InsertParentTopic_text); - action.setToolTipText(MindMapMessages.InsertParentTopic_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.insertParentTopic"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_PARENT, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_PARENT, false)); - return action; - } - }; - -// public static final ActionFactory INSERT_SHEET = new ActionFactory( -// "org.xmind.ui.insertSheet") { //$NON-NLS-1$ -// public IWorkbenchAction create(IWorkbenchWindow window) { -// if (window == null) -// throw new IllegalArgumentException(); -// LabelRetargetAction action = new LabelRetargetAction(getId(), -// "new Sheet"); -// action.setToolTipText("create a new Sheet"); -// action.setActionDefinitionId("org.xmind.ui.command.insertSheet"); -// action.setImageDescriptor(MindMapUI.getImages().get( -// IMindMapImages.SHEET, true)); -// action.setDisabledImageDescriptor(MindMapUI.getImages().get( -// IMindMapImages.SHEET, false)); -// return action; -// } -// }; - - public static final ActionFactory INSERT_FLOATING_TOPIC = new ActionFactory( - "org.xmind.ui.insertFloatingTopic") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertFloatingTopic_text); - action.setToolTipText(MindMapMessages.InsertFloatingTopic_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.insertFloatingTopic"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_FLOATING_MAIN, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_FLOATING_MAIN, false)); - return action; - } - }; - - public static final ActionFactory INSERT_FLOATING_CENTRAL_TOPIC = new ActionFactory( - "org.xmind.ui.insertFloatingCentralTopic") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertFloatingCentralTopic_text); - action.setToolTipText( - MindMapMessages.InsertFloatingCentralTopic_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.insertFloatingCentralTopic"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_FLOATING_CENTRAL, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_FLOATING_CENTRAL, false)); - return action; - } - }; - - public static final ActionFactory EXTEND = new ActionFactory( - "org.xmind.ui.extend") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Extend_text); - action.setToolTipText(MindMapMessages.Extend_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.extend"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory EXTEND_ALL = new ActionFactory( - "org.xmind.ui.extendAll") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.ExtendAll_text); - action.setToolTipText(MindMapMessages.ExtendAll_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.extendAll"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory COLLAPSE = new ActionFactory( - "org.xmind.ui.collapse") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Collapse_text); - action.setToolTipText(MindMapMessages.Collapse_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.collapse"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory COLLAPSE_ALL = new ActionFactory( - "org.xmind.ui.collapseAll") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.CollapseAll_text); - action.setToolTipText(MindMapMessages.CollapseAll_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.collapseAll"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory NEW_SHEET = new ActionFactory( - "org.xmind.ui.newSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.NewSheet_text); - action.setToolTipText(MindMapMessages.NewSheet_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.newSheet"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NEWMAP, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NEWMAP, false)); - return action; - } - }; - - public static final ActionFactory INSERT_SHEET_FROM = new ActionFactory( - "org.xmind.ui.topic.newSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.NEWSheet_from_text); - action.setToolTipText(MindMapMessages.NEWSheet_from_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.insertSheetFrom"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.NEW_SHEET_AS, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.NEW_SHEET_AS, false)); - return action; - } - - }; - - public static final ActionFactory DELETE_SHEET = new ActionFactory( - "org.xmind.ui.deleteSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.DeleteSheet_text); - action.setToolTipText(MindMapMessages.DeleteSheet_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.deleteSheet"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory DELETE_OTHER_SHEET = new ActionFactory( - "org.xmind.ui.deleteOtherSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Delete_OtherSheets_text); - action.setToolTipText(MindMapMessages.Delete_OtherSheets_toolTip); -// action -// .setActionDefinitionId("org.xmind.ui.command.deleteOtherSheet"); //$NON-NLS-1$ - return action; - } - - }; - - public static final ActionFactory MODIFY_HYPERLINK = new ActionFactory( - "org.xmind.ui.modifyHyperlink") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.ModifyHyperlink_text); - action.setToolTipText(MindMapMessages.ModifyHyperlink_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.hyperlink"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.HYPERLINK, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.HYPERLINK, false)); - return action; - } - }; - - public static final ActionFactory CANCEL_HYPERLINK = new ActionFactory( - "org.xmind.ui.cancelHyperlinnk") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.CancelHyperlink_text); - action.setToolTipText(MindMapMessages.CancelHyperlink_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.cancelHyperlink"); //$NON-NLS-1$ - return action; - } - }; -// -// public static final ActionFactory SAVE_ATTACHMENT_AS = new ActionFactory( -// "org.xmind.ui.saveAttachmentAs") { //$NON-NLS-1$ -// public IWorkbenchAction create(IWorkbenchWindow window) { -// RetargetAction action = new RetargetAction(getId(), -// MindMapMessages.SaveAttachment_text); -// action.setToolTipText(MindMapMessages.SaveAttachment_toolTip); -// action.setActionDefinitionId("org.xmind.ui.command.saveAttachmentAs"); //$NON-NLS-1$ -// return action; -// } -// }; -// - public static final ActionFactory OPEN_HYPERLINK = new ActionFactory( - "org.xmind.ui.openHyperlink") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.OpenHyperlink_text); - action.setToolTipText(MindMapMessages.OpenHyperlink_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.openHyperlink"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory INSERT_ATTACHMENT = new ActionFactory( - "org.xmind.ui.insertAttachment") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertAttachment_text); - action.setToolTipText(MindMapMessages.InsertAttachment_toolTip); - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.ATTACHMENT, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.ATTACHMENT, false)); - action.setActionDefinitionId( - "org.xmind.ui.command.insertAttachment"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory CREATE_RELATIONSHIP = new ActionFactory( - "org.xmind.ui.createRelationship") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertRelationship_text); - action.setToolTipText(MindMapMessages.InsertRelationship_toolTip); - action.setActionDefinitionId( - "org.xmind.ui.command.createRelationship"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.RELATIONSHIP, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.RELATIONSHIP, false)); - return action; - } - }; - - public static final ActionFactory CREATE_BOUNDARY = new ActionFactory( - "org.xmind.ui.createBoundary") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertBoundary_text); - action.setToolTipText(MindMapMessages.InsertBoundary_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.createBoundary"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.BOUNDARY, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.BOUNDARY, false)); - return action; - } - }; - - public static final ActionFactory CREATE_SUMMARY = new ActionFactory( - "org.xmind.ui.createSummary") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertSummary_text); - action.setToolTipText(MindMapMessages.InsertSummary_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.createSummary"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.SUMMARY, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.SUMMARY, false)); - return action; - } - }; - - public static final ActionFactory DRILL_DOWN = new ActionFactory( - "org.xmind.ui.drillDown") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.DrillDown_text); - action.setToolTipText(MindMapMessages.DrillDown_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.drillDown"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DRILL_DOWN, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.DRILL_DOWN, false)); - return action; - } - }; - - public static final ActionFactory DRILL_UP = new ActionFactory( - "org.xmind.ui.drillUp") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.DrillUp_text); - action.setToolTipText(MindMapMessages.DrillUp_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.drillUp"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DRILL_UP, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DRILL_UP, false)); - return action; - } - }; - -// public static final ActionFactory SORT_ASALPHA = new ActionFactory( -// "org.xmind.ui.sortAsAlpha") { //$NON-NLS-1$ -// public IWorkbenchAction create(IWorkbenchWindow window) { -// RetargetAction action = new RetargetAction(getId(), -// MindMapMessages.SortAsAlpha_text); -// action.setToolTipText(MindMapMessages.SortAsAlpha_toolTip); -//// action.setActionDefinitionId("org.xmind.ui.command.sortAsAlpha"); //$NON-NLS-1$ -// action.setImageDescriptor(MindMapUI.getImages().get( -// IMindMapImages.ALAPHA, true)); -// action.setDisabledImageDescriptor(MindMapUI.getImages().get( -// IMindMapImages.ALAPHA, false)); -// return action; -// } -// }; -// -// public static final ActionFactory SORT_ASPRIORITY = new ActionFactory( -// "org.xmind.ui.sortAsPriority") { //$NON-NLS-1$ -// public IWorkbenchAction create(IWorkbenchWindow window) { -// RetargetAction action = new RetargetAction(getId(), -// MindMapMessages.SortAsPriority_text); -// action.setToolTipText(MindMapMessages.SortAsPriority_toolTip); -//// action.setActionDefinitionId("org.xmind.ui.command.sortAsPriority"); //$NON-NLS-1$ -// return action; -// } -// }; -// -// public static final ActionFactory SORT_ASDATE = new ActionFactory( -// "org.xmind.ui.sortAsModifyDate") { //$NON-NLS-1$ -// public IWorkbenchAction create(IWorkbenchWindow window) { -// RetargetAction action = new RetargetAction(getId(), -// MindMapMessages.SortAsModifyDate_text); -// action.setToolTipText(MindMapMessages.SortAsModifyDate_toolTip); -// return action; -// } -// }; - - public static final ActionFactory EDIT_TITLE = new ActionFactory( - "org.xmind.ui.editTitle") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.EditTitle_text); - action.setToolTipText(MindMapMessages.EditTitle_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.editTitle"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory EDIT_LABEL = new ActionFactory( - "org.xmind.ui.editLabel") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.EditLabel_text); - action.setToolTipText(MindMapMessages.EditLabel_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.editLabel"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.LABEL, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.LABEL, false)); - return action; - } - }; - - public static final ActionFactory EDIT_NOTES = new ActionFactory( - "org.xmind.ui.editNotes") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.EditNotes_text); - action.setToolTipText(MindMapMessages.EditNotes_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.editNotes"); //$NON-NLS-1$ - action.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NOTES, true)); - action.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NOTES, false)); - return action; - } - }; - - public static final ActionFactory INSERT_IMAGE = new ActionFactory( - "org.xmind.ui.insertImage") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.InsertImage_text); - action.setToolTipText(MindMapMessages.InsertImage_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.insertImage"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_IMAGE, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_IMAGE, false)); - return action; - } - }; - - public static final ActionFactory TRAVERSE = new ActionFactory( - "org.xmind.ui.traverse") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Traverse_text); - action.setToolTipText(MindMapMessages.Traverse_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.traverse"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory FINISH = new ActionFactory( - "org.xmind.ui.finish") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Finish_text); - action.setToolTipText(MindMapMessages.Finish_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.finish"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory TILE = new ActionFactory( - "org.xmind.ui.tile") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.Tile_text); - action.setToolTipText(MindMapMessages.Tile_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.tile"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory RESET_POSITION = new ActionFactory( - "org.xmind.ui.resetPosition") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.ResetPosition_text); - action.setToolTipText(MindMapMessages.ResetPosition_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.resetPosition"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory MOVE_UP = new ActionFactory( - "org.xmind.ui.moveUp") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.MoveUp_text); - action.setToolTipText(MindMapMessages.MoveUp_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.moveUp"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory MOVE_DOWN = new ActionFactory( - "org.xmind.ui.moveDown") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.MoveDown_text); - action.setToolTipText(MindMapMessages.MoveDown_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.moveDown"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory MOVE_LEFT = new ActionFactory( - "org.xmind.ui.moveLeft") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.MoveLeft_text); - action.setToolTipText(MindMapMessages.MoveLeft_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.moveLeft"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory MOVE_RIGHT = new ActionFactory( - "org.xmind.ui.moveRight") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.MoveRight_text); - action.setToolTipText(MindMapMessages.MoveRight_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.moveRight"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory DUPLICATE = new ActionFactory( - "org.xmind.ui.duplicate", "org.xmind.ui.command.duplicate") { //$NON-NLS-1$ //$NON-NLS-2$ - public IWorkbenchAction create(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - LabelRetargetAction action = new LabelRetargetAction(getId(), - MindMapMessages.MindMapActionFactory_Duplicate_text); - action.setToolTipText( - MindMapMessages.MindMapActionFactory_Duplicate_tooltip); - action.setActionDefinitionId(getCommandId()); - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_BEFORE, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_BEFORE, false)); - return action; - } - }; - - public static final ActionFactory NEW_SHEET_FROM_TEMPLATE = new ActionFactory( - "org.xmind.ui.newSheetFromTemplate") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.MindMapActionFactory_NewSheetFromTemplte_text); - action.setToolTipText( - MindMapMessages.MindMapActionFactory_NewSheetFromTemplate_tooltip); - action.setActionDefinitionId( - "org.xmind.ui.command.newSheetFromTemplate"); //$NON-NLS-1$ - action.setImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.NEW_SHEET_FROM_TEMPLATE, true)); - action.setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.NEW_SHEET_FROM_TEMPLATE, false)); - return action; - } - }; - - public static final ActionFactory DUPLICATE_SHEET = new ActionFactory( - "org.xmind.ui.duplicateSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.DuplicateSheet_text); - action.setToolTipText(MindMapMessages.DuplicateSheet_toolTip); - action.setActionDefinitionId("org.xmind.ui.command.duplicateSheet"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory COPY_SHEET = new ActionFactory( - "org.xmind.ui.copySheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.CopySheet_text); - action.setToolTipText(WorkbenchMessages.Workbench_copyToolTip); - action.setActionDefinitionId("org.xmind.ui.command.copySheet"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory PASTE_SHEET = new ActionFactory( - "org.xmind.ui.pasteSheet") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.PasteSheet_text); - action.setToolTipText(WorkbenchMessages.Workbench_pasteToolTip); - action.setActionDefinitionId("org.xmind.ui.command.pasteSheet"); //$NON-NLS-1$ - return action; - } - }; - - public static final ActionFactory REMOVE_ALL_STYLES = new ActionFactory( - "org.xmindl.ui.removeAllStyles") { //$NON-NLS-1$ - public IWorkbenchAction create(IWorkbenchWindow window) { - RetargetAction action = new RetargetAction(getId(), - MindMapMessages.RemoveAllStyles_text); - action.setToolTipText(MindMapMessages.RemoveAllStyles_tooltip); - action.setActionDefinitionId( - "org.xmind.ui.command.removeAllStyles"); //$NON-NLS-1$ - return action; - } - }; -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.actions; + +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.LabelRetargetAction; +import org.eclipse.ui.actions.RetargetAction; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.actions.SaveAsTemplateAction; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +public class MindMapActionFactory { + + @Deprecated + public static final ActionFactory NEW_WORKBOOK = new ActionFactory( + "org.xmind.ui.newWorkbook") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + org.xmind.ui.internal.actions.NewWorkbookAction action = new org.xmind.ui.internal.actions.NewWorkbookAction( + window); + action.setId(getId()); + return action; + } + }; + + @Deprecated + public static final ActionFactory OPEN = new ActionFactory( + "org.xmind.ui.open") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + org.xmind.ui.internal.actions.OpenWorkbookAction action = new org.xmind.ui.internal.actions.OpenWorkbookAction( + window); + action.setId(getId()); + return action; + } + }; + + @Deprecated + public static final ActionFactory SAVE_TEMPLATE = new ActionFactory( + "org.xmind.ui.saveTemplate") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + return new SaveAsTemplateAction(getId(), window); + } + }; + + public static final ActionFactory SELECT_BROTHERS = new ActionFactory( + "org.xmind.ui.selectBrothers") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.SelectBrothers_text); + action.setToolTipText(MindMapMessages.SelectBrothers_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.selectBrothers"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory SELECT_CHILDREN = new ActionFactory( + "org.xmind.ui.selectChildren") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.SelectChildren_text); + action.setToolTipText(MindMapMessages.SelectChildren_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.selectChildren"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory GO_HOME = new ActionFactory( + "org.xmind.ui.selectHome") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.GoToCentral_text); + action.setToolTipText(MindMapMessages.GoToCentral_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.goHome"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory ZOOM_IN = new ActionFactory( + "org.xmind.ui.zoomIn") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.ZoomIn_text); + action.setToolTipText(MindMapMessages.ZoomIn_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.zoomIn"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.ZOOMIN, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.ZOOMIN, false)); + return action; + } + }; + + public static final ActionFactory ZOOM_OUT = new ActionFactory( + "org.xmind.ui.zoomOut") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.ZoomOut_text); + action.setToolTipText(MindMapMessages.ZoomOut_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.zoomOut"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.ZOOMOUT, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.ZOOMOUT, false)); + return action; + } + }; + + public static final ActionFactory ACTUAL_SIZE = new ActionFactory( + "org.xmind.ui.actualSize") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.ActualSize_text); + action.setToolTipText(MindMapMessages.ActualSize_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.actualSize"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.ACTUAL_SIZE, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.ACTUAL_SIZE, false)); + return action; + } + }; + + public static final ActionFactory FIT_MAP = new ActionFactory( + "org.xmind.ui.fitMap") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.FitMap_text); + action.setToolTipText(MindMapMessages.FitMap_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.fitMap"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.FIT_SIZE, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.FIT_SIZE, false)); + return action; + } + }; + + public static final ActionFactory FIT_SELECTION = new ActionFactory( + "org.xmind.ui.fitSelection") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.FitSelection_text); + action.setToolTipText(MindMapMessages.FitSelection_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.fitSelection"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.FIT_SELECTION, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.FIT_SELECTION, false)); + return action; + } + }; + + public static final ActionFactory INSERT_TOPIC = new ActionFactory( + "org.xmind.ui.insertTopic") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.InsertTopic_text); + action.setToolTipText(MindMapMessages.InsertTopic_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.insertTopic"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_AFTER, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_AFTER, false)); + return action; + } + }; + + public static final ActionFactory INSERT_SUBTOPIC = new ActionFactory( + "org.xmind.ui.insertSubtopic") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.InsertSubtopic_text); + action.setToolTipText(MindMapMessages.InsertSubtopic_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.insertSubtopic"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.INSERT_SUB, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_SUB, false)); + return action; + } + }; + + public static final ActionFactory INSERT_TOPIC_BEFORE = new ActionFactory( + "org.xmind.ui.insertTopicBefore") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.InsertTopicBefore_text); + action.setToolTipText(MindMapMessages.InsertTopicBefore_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.insertTopicBefore"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_BEFORE, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_BEFORE, false)); + return action; + } + }; + + public static final ActionFactory INSERT_PARENT_TOPIC = new ActionFactory( + "org.xmind.ui.insertParentTopic") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.InsertParentTopic_text); + action.setToolTipText(MindMapMessages.InsertParentTopic_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.insertParentTopic"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_PARENT, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_PARENT, false)); + return action; + } + }; + +// public static final ActionFactory INSERT_SHEET = new ActionFactory( +// "org.xmind.ui.insertSheet") { //$NON-NLS-1$ +// public IWorkbenchAction create(IWorkbenchWindow window) { +// if (window == null) +// throw new IllegalArgumentException(); +// LabelRetargetAction action = new LabelRetargetAction(getId(), +// "new Sheet"); +// action.setToolTipText("create a new Sheet"); +// action.setActionDefinitionId("org.xmind.ui.command.insertSheet"); +// action.setImageDescriptor(MindMapUI.getImages().get( +// IMindMapImages.SHEET, true)); +// action.setDisabledImageDescriptor(MindMapUI.getImages().get( +// IMindMapImages.SHEET, false)); +// return action; +// } +// }; + + public static final ActionFactory INSERT_FLOATING_TOPIC = new ActionFactory( + "org.xmind.ui.insertFloatingTopic") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertFloatingTopic_text); + action.setToolTipText(MindMapMessages.InsertFloatingTopic_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.insertFloatingTopic"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_FLOATING_MAIN, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_FLOATING_MAIN, false)); + return action; + } + }; + + public static final ActionFactory INSERT_FLOATING_CENTRAL_TOPIC = new ActionFactory( + "org.xmind.ui.insertFloatingCentralTopic") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertFloatingCentralTopic_text); + action.setToolTipText( + MindMapMessages.InsertFloatingCentralTopic_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.insertFloatingCentralTopic"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_FLOATING_CENTRAL, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_FLOATING_CENTRAL, false)); + return action; + } + }; + + public static final ActionFactory EXTEND = new ActionFactory( + "org.xmind.ui.extend") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Extend_text); + action.setToolTipText(MindMapMessages.Extend_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.extend"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory EXTEND_ALL = new ActionFactory( + "org.xmind.ui.extendAll") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.ExtendAll_text); + action.setToolTipText(MindMapMessages.ExtendAll_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.extendAll"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory COLLAPSE = new ActionFactory( + "org.xmind.ui.collapse") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Collapse_text); + action.setToolTipText(MindMapMessages.Collapse_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.collapse"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory COLLAPSE_ALL = new ActionFactory( + "org.xmind.ui.collapseAll") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.CollapseAll_text); + action.setToolTipText(MindMapMessages.CollapseAll_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.collapseAll"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory NEW_SHEET = new ActionFactory( + "org.xmind.ui.newSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.NewSheet_text); + action.setToolTipText(MindMapMessages.NewSheet_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.newSheet"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.NEWMAP, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.NEWMAP, false)); + return action; + } + }; + + public static final ActionFactory INSERT_SHEET_FROM = new ActionFactory( + "org.xmind.ui.topic.newSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.NEWSheet_from_text); + action.setToolTipText(MindMapMessages.NEWSheet_from_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.insertSheetFrom"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.NEW_SHEET_AS, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.NEW_SHEET_AS, false)); + + return action; + } + + }; + + public static final ActionFactory DELETE_SHEET = new ActionFactory( + "org.xmind.ui.deleteSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.DeleteSheet_text); + action.setToolTipText(MindMapMessages.DeleteSheet_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.deleteSheet"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory DELETE_OTHER_SHEET = new ActionFactory( + "org.xmind.ui.deleteOtherSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Delete_OtherSheets_text); + action.setToolTipText(MindMapMessages.Delete_OtherSheets_toolTip); +// action +// .setActionDefinitionId("org.xmind.ui.command.deleteOtherSheet"); //$NON-NLS-1$ + return action; + } + + }; + + public static final ActionFactory MODIFY_HYPERLINK = new ActionFactory( + "org.xmind.ui.modifyHyperlink") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.ModifyHyperlink_text); + action.setToolTipText(MindMapMessages.ModifyHyperlink_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.hyperlink"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.HYPERLINK, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.HYPERLINK, false)); + return action; + } + }; + + public static final ActionFactory CANCEL_HYPERLINK = new ActionFactory( + "org.xmind.ui.cancelHyperlinnk") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.CancelHyperlink_text); + action.setToolTipText(MindMapMessages.CancelHyperlink_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.cancelHyperlink"); //$NON-NLS-1$ + return action; + } + }; +// +// public static final ActionFactory SAVE_ATTACHMENT_AS = new ActionFactory( +// "org.xmind.ui.saveAttachmentAs") { //$NON-NLS-1$ +// public IWorkbenchAction create(IWorkbenchWindow window) { +// RetargetAction action = new RetargetAction(getId(), +// MindMapMessages.SaveAttachment_text); +// action.setToolTipText(MindMapMessages.SaveAttachment_toolTip); +// action.setActionDefinitionId("org.xmind.ui.command.saveAttachmentAs"); //$NON-NLS-1$ +// return action; +// } +// }; +// + public static final ActionFactory OPEN_HYPERLINK = new ActionFactory( + "org.xmind.ui.openHyperlink") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.OpenHyperlink_text); + action.setToolTipText(MindMapMessages.OpenHyperlink_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.openHyperlink"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory INSERT_ATTACHMENT = new ActionFactory( + "org.xmind.ui.insertAttachment") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertAttachment_text); + action.setToolTipText(MindMapMessages.InsertAttachment_toolTip); + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.ATTACHMENT, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.ATTACHMENT, false)); + action.setActionDefinitionId( + "org.xmind.ui.command.insertAttachment"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory CREATE_RELATIONSHIP = new ActionFactory( + "org.xmind.ui.createRelationship") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertRelationship_text); + action.setToolTipText(MindMapMessages.InsertRelationship_toolTip); + action.setActionDefinitionId( + "org.xmind.ui.command.createRelationship"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.RELATIONSHIP, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.RELATIONSHIP, false)); + return action; + } + }; + + public static final ActionFactory CREATE_BOUNDARY = new ActionFactory( + "org.xmind.ui.createBoundary") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertBoundary_text); + action.setToolTipText(MindMapMessages.InsertBoundary_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.createBoundary"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.BOUNDARY, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.BOUNDARY, false)); + return action; + } + }; + + public static final ActionFactory CREATE_SUMMARY = new ActionFactory( + "org.xmind.ui.createSummary") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertSummary_text); + action.setToolTipText(MindMapMessages.InsertSummary_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.createSummary"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.SUMMARY, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.SUMMARY, false)); + return action; + } + }; + + public static final ActionFactory DRILL_DOWN = new ActionFactory( + "org.xmind.ui.drillDown") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.DrillDown_text); + action.setToolTipText(MindMapMessages.DrillDown_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.drillDown"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.DRILL_DOWN, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.DRILL_DOWN, false)); + return action; + } + }; + + public static final ActionFactory DRILL_UP = new ActionFactory( + "org.xmind.ui.drillUp") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.DrillUp_text); + action.setToolTipText(MindMapMessages.DrillUp_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.drillUp"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.DRILL_UP, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.DRILL_UP, false)); + return action; + } + }; + +// public static final ActionFactory SORT_ASALPHA = new ActionFactory( +// "org.xmind.ui.sortAsAlpha") { //$NON-NLS-1$ +// public IWorkbenchAction create(IWorkbenchWindow window) { +// RetargetAction action = new RetargetAction(getId(), +// MindMapMessages.SortAsAlpha_text); +// action.setToolTipText(MindMapMessages.SortAsAlpha_toolTip); +//// action.setActionDefinitionId("org.xmind.ui.command.sortAsAlpha"); //$NON-NLS-1$ +// action.setImageDescriptor(MindMapUI.getImages().get( +// IMindMapImages.ALAPHA, true)); +// action.setDisabledImageDescriptor(MindMapUI.getImages().get( +// IMindMapImages.ALAPHA, false)); +// return action; +// } +// }; +// +// public static final ActionFactory SORT_ASPRIORITY = new ActionFactory( +// "org.xmind.ui.sortAsPriority") { //$NON-NLS-1$ +// public IWorkbenchAction create(IWorkbenchWindow window) { +// RetargetAction action = new RetargetAction(getId(), +// MindMapMessages.SortAsPriority_text); +// action.setToolTipText(MindMapMessages.SortAsPriority_toolTip); +//// action.setActionDefinitionId("org.xmind.ui.command.sortAsPriority"); //$NON-NLS-1$ +// return action; +// } +// }; +// +// public static final ActionFactory SORT_ASDATE = new ActionFactory( +// "org.xmind.ui.sortAsModifyDate") { //$NON-NLS-1$ +// public IWorkbenchAction create(IWorkbenchWindow window) { +// RetargetAction action = new RetargetAction(getId(), +// MindMapMessages.SortAsModifyDate_text); +// action.setToolTipText(MindMapMessages.SortAsModifyDate_toolTip); +// return action; +// } +// }; + + public static final ActionFactory EDIT_TITLE = new ActionFactory( + "org.xmind.ui.editTitle") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.EditTitle_text); + action.setToolTipText(MindMapMessages.EditTitle_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.editTitle"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory EDIT_LABEL = new ActionFactory( + "org.xmind.ui.editLabel") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.EditLabel_text); + action.setToolTipText(MindMapMessages.EditLabel_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.editLabel"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.LABEL, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.LABEL, false)); + return action; + } + }; + + public static final ActionFactory EDIT_NOTES = new ActionFactory( + "org.xmind.ui.editNotes") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.EditNotes_text); + action.setToolTipText(MindMapMessages.EditNotes_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.editNotes"); //$NON-NLS-1$ + action.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.NOTES, true)); + action.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.NOTES, false)); + return action; + } + }; + + public static final ActionFactory INSERT_IMAGE = new ActionFactory( + "org.xmind.ui.insertImage") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.InsertImage_text); + action.setToolTipText(MindMapMessages.InsertImage_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.insertImage"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, false)); + return action; + } + }; + + public static final ActionFactory TRAVERSE = new ActionFactory( + "org.xmind.ui.traverse") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Traverse_text); + action.setToolTipText(MindMapMessages.Traverse_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.traverse"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory FINISH = new ActionFactory( + "org.xmind.ui.finish") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Finish_text); + action.setToolTipText(MindMapMessages.Finish_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.finish"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory TILE = new ActionFactory( + "org.xmind.ui.tile") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.Tile_text); + action.setToolTipText(MindMapMessages.Tile_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.tile"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory RESET_POSITION = new ActionFactory( + "org.xmind.ui.resetPosition") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.ResetPosition_text); + action.setToolTipText(MindMapMessages.ResetPosition_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.resetPosition"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory MOVE_UP = new ActionFactory( + "org.xmind.ui.moveUp") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.MoveUp_text); + action.setToolTipText(MindMapMessages.MoveUp_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.moveUp"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory MOVE_DOWN = new ActionFactory( + "org.xmind.ui.moveDown") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.MoveDown_text); + action.setToolTipText(MindMapMessages.MoveDown_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.moveDown"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory MOVE_LEFT = new ActionFactory( + "org.xmind.ui.moveLeft") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.MoveLeft_text); + action.setToolTipText(MindMapMessages.MoveLeft_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.moveLeft"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory MOVE_RIGHT = new ActionFactory( + "org.xmind.ui.moveRight") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.MoveRight_text); + action.setToolTipText(MindMapMessages.MoveRight_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.moveRight"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory DUPLICATE = new ActionFactory( + "org.xmind.ui.duplicate", "org.xmind.ui.command.duplicate") { //$NON-NLS-1$ //$NON-NLS-2$ + public IWorkbenchAction create(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + LabelRetargetAction action = new LabelRetargetAction(getId(), + MindMapMessages.MindMapActionFactory_Duplicate_text); + action.setToolTipText( + MindMapMessages.MindMapActionFactory_Duplicate_tooltip); + action.setActionDefinitionId(getCommandId()); + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_BEFORE, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_BEFORE, false)); + return action; + } + }; + + public static final ActionFactory NEW_SHEET_FROM_TEMPLATE = new ActionFactory( + "org.xmind.ui.newSheetFromTemplate") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.MindMapActionFactory_NewSheetFromTemplte_text); + action.setToolTipText( + MindMapMessages.MindMapActionFactory_NewSheetFromTemplate_tooltip); + action.setActionDefinitionId( + "org.xmind.ui.command.newSheetFromTemplate"); //$NON-NLS-1$ + action.setImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.NEW_SHEET_FROM_TEMPLATE, true)); + action.setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.NEW_SHEET_FROM_TEMPLATE, false)); + return action; + } + }; + + public static final ActionFactory DUPLICATE_SHEET = new ActionFactory( + "org.xmind.ui.duplicateSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.DuplicateSheet_text); + action.setToolTipText(MindMapMessages.DuplicateSheet_toolTip); + action.setActionDefinitionId("org.xmind.ui.command.duplicateSheet"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory COPY_SHEET = new ActionFactory( + "org.xmind.ui.copySheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.CopySheet_text); + action.setToolTipText(WorkbenchMessages.Workbench_copyToolTip); + action.setActionDefinitionId("org.xmind.ui.command.copySheet"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory PASTE_SHEET = new ActionFactory( + "org.xmind.ui.pasteSheet") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.PasteSheet_text); + action.setToolTipText(WorkbenchMessages.Workbench_pasteToolTip); + action.setActionDefinitionId("org.xmind.ui.command.pasteSheet"); //$NON-NLS-1$ + return action; + } + }; + + public static final ActionFactory REMOVE_ALL_STYLES = new ActionFactory( + "org.xmindl.ui.removeAllStyles") { //$NON-NLS-1$ + public IWorkbenchAction create(IWorkbenchWindow window) { + RetargetAction action = new RetargetAction(getId(), + MindMapMessages.RemoveAllStyles_text); + action.setToolTipText(MindMapMessages.RemoveAllStyles_tooltip); + action.setActionDefinitionId( + "org.xmind.ui.command.removeAllStyles"); //$NON-NLS-1$ + return action; + } + }; +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBox.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBox.java index 4b3176201..2ab7c379a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBox.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBox.java @@ -1,42 +1,42 @@ -package org.xmind.ui.blackbox; - -/** - * @author Jason Wong - */ -public class BlackBox { - - public static final String ID = "org.xmind.ui.blackbox"; //$NON-NLS-1$ - - public static void doBackup(String source) { - BlackBoxManager.getInstance().doBackup(source); - } - - public static IBlackBoxMap findMapBySource(String source) { - return BlackBoxManager.getInstance().findMapBySource(source); - } - - public static IBlackBoxMap findMapByID(String id) { - return BlackBoxManager.getInstance().findMapByID(id); - } - - public static IBlackBoxMap[] getMaps() { - return BlackBoxManager.getInstance().getMaps(); - } - - public static boolean removeMap(IBlackBoxMap map) { - return BlackBoxManager.getInstance().removeMap(map); - } - - public static boolean removeVersion(String source, String timestamp) { - return BlackBoxManager.getInstance().removeVersion(source, timestamp); - } - - public static boolean removeVersion(IBlackBoxMap map, String timestamp) { - return BlackBoxManager.getInstance().removeVersion(map, timestamp); - } - - public static void removeSavedMap(String source) { - BlackBoxManager.getInstance().removeSavedMap(source); - } - -} +package org.xmind.ui.blackbox; + +/** + * @author Jason Wong + */ +public class BlackBox { + + public static final String ID = "org.xmind.ui.blackbox"; //$NON-NLS-1$ + + public static void doBackup(String source) { + BlackBoxManager.getInstance().doBackup(source); + } + + public static IBlackBoxMap findMapBySource(String source) { + return BlackBoxManager.getInstance().findMapBySource(source); + } + + public static IBlackBoxMap findMapByID(String id) { + return BlackBoxManager.getInstance().findMapByID(id); + } + + public static IBlackBoxMap[] getMaps() { + return BlackBoxManager.getInstance().getMaps(); + } + + public static boolean removeMap(IBlackBoxMap map) { + return BlackBoxManager.getInstance().removeMap(map); + } + + public static boolean removeVersion(String source, String timestamp) { + return BlackBoxManager.getInstance().removeVersion(source, timestamp); + } + + public static boolean removeVersion(IBlackBoxMap map, String timestamp) { + return BlackBoxManager.getInstance().removeVersion(map, timestamp); + } + + public static void removeSavedMap(String source) { + BlackBoxManager.getInstance().removeSavedMap(source); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxLibrary.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxLibrary.java index c96d42f42..3b3464219 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxLibrary.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxLibrary.java @@ -1,306 +1,306 @@ -package org.xmind.ui.blackbox; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.event.CoreEventSupport; - -/** - * @author Jason Wong - */ -public class BlackBoxLibrary implements IBlackBoxLibrary, ICoreEventSource { - - private static final String MAP_REMOVE = "mapRemove"; //$NON-NLS-1$ - - private static final String VERSION_ADD = "versionAdd"; //$NON-NLS-1$ - - private static final String VERSION_REMOVE = "versionRemove"; //$NON-NLS-1$ - - private List maps = new ArrayList(); - - private List savedSrcs = new ArrayList(); - - private File blackbox = null; - - private ICoreEventSupport coreEventSupport; - - public BlackBoxLibrary() { - load(); - } - - public synchronized void addVersion(String source, String mapID, - IBlackBoxVersion version) { - IBlackBoxMap map = findMapBySource(source); - if (map == null) { - BlackBoxMap m = new BlackBoxMap(this, mapID); - m.setSource(source); - map = m; - this.maps.add(map); - } - - Set versions = map.getVersions(); - if (versions.size() == 0) { - versions.add(version); - } else if (versions.size() < 3 && !version.isReliable()) { - versions.add(version); - } else { - IBlackBoxVersion trash = null; - trash = findTrashVersion(versions, version.isReliable()); - versions.remove(trash); - versions.add(version); - BlackBoxManager.addTrash(trash); - } - - if (!isSavedMap(source)) { - this.savedSrcs.add(source); - } - - save(map); - fireTargetEvent(VERSION_ADD, version); - } - - public synchronized boolean removeMap(IBlackBoxMap map) { - if (this.maps.remove(map)) { - BlackBoxManager.addTrash(map); - save(map); - fireTargetEvent(MAP_REMOVE, map); - return true; - } else { - return false; - } - } - - public synchronized boolean removeVersion(IBlackBoxMap map, String timestamp) { - Set versions = map.getVersions(); - for (IBlackBoxVersion v : versions) { - if (v.getTimestamp().equals(timestamp)) { - if (versions.remove(v)) { - BlackBoxManager.addTrash(v); - save(map); - if (versions.size() == 0) { - removeMap(map); - fireTargetEvent(MAP_REMOVE, map); - } - fireTargetEvent(VERSION_REMOVE, v); - return true; - } else { - return false; - } - } - } - return false; - } - - public synchronized IBlackBoxMap[] getMaps() { - load(); - return this.maps.toArray(new IBlackBoxMap[this.maps.size()]); - } - - public synchronized IBlackBoxMap findMapBySource(String source) { - for (IBlackBoxMap map : this.maps) { - if (source.equals(map.getSource())) - return map; - } - return null; - } - - public synchronized IBlackBoxMap findMapByID(String id) { - for (IBlackBoxMap map : this.maps) { - if (map.getID().equals(id)) - return map; - } - return null; - } - - public synchronized boolean isSavedMap(String source) { - if (source == null) - return false; - - return this.savedSrcs.contains(source); - } - - public synchronized void removeSavedMap(String source) { - if (!(savedSrcs.size() > 0) || source == null) - return; - if (isSavedMap(source)) { - savedSrcs.remove(source); - } - } - - private void load() { - File blackbox = new File(BlackBoxManager.getBlackboxPath()); - if (!blackbox.exists()) - return; - - maps.clear(); - File[] infos = blackbox.listFiles(); - for (File info : infos) { - String fileName = info.getName(); - String[] parts = fileName.split("\\."); //$NON-NLS-1$s - - if (fileName.contains(BlackBoxManager.FILE_INFO_EXT)) { - try { - loadBackupInfo(info, parts); - } catch (IOException e) { - BlackBoxManager - .log("Error occurred while loading maps.", e); //$NON-NLS-1$ - } - } else if (fileName.contains(BlackBoxManager.FILE_XMIND_EXT)) { - loadMapInfo(info, parts); - } - } - } - - private synchronized void save(IBlackBoxMap map) { - File metaFile = getMetaFile(map.getID()); - if (!metaFile.exists()) { - BufferedWriter writer = null; - try { - writer = new BufferedWriter(new FileWriter(metaFile)); - writer.write(map.getSource()); - writer.flush(); - } catch (IOException e) { - } finally { - try { - if (writer != null) - writer.close(); - } catch (IOException e) { - } - } - } - BlackBoxManager.clearTrashes(); - } - - private File getMetaFile(String mapID) { - if (blackbox == null) { - blackbox = new File(BlackBoxManager.getBlackboxPath()); - } - - File metaFile = new File(blackbox, mapID - + BlackBoxManager.FILE_INFO_EXT); - return metaFile; - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return getCoreEventSupport().registerGlobalListener(type, listener); - } - - private void fireTargetEvent(String eventType, Object target) { - getCoreEventSupport().dispatchTargetChange(this, eventType, target); - } - - public ICoreEventSupport getCoreEventSupport() { - if (coreEventSupport == null) { - coreEventSupport = new CoreEventSupport(); - } - return coreEventSupport; - } - - /** - * If isReliable value is true, returns the last saved the reliable version. - * else returns the older save unreliable version. - * - * @param isReliable - * @return The IBlackBoxVersion will be replaced - */ - private IBlackBoxVersion findTrashVersion(Set versions, - boolean isReliable) { - if (isReliable) { - for (IBlackBoxVersion v : versions) { - if (v.isReliable()) { - return v; - } - } - } - - IBlackBoxVersion trash = null; - for (IBlackBoxVersion v : versions) { - if (v.isReliable()) - continue; - - if (trash == null) { - trash = v; - continue; - } - trash = trash.compareTo(v) > 0 ? v : trash; - } - return trash; - } - - private void loadBackupInfo(File info, String[] parts) throws IOException { - BlackBoxMap map = null; - String mapID = null; - - for (String part : parts) { - if (part.length() == BlackBoxManager.MD5_LENGTH) { - mapID = part; - break; - } - } - if (mapID == null) - return; - - map = (BlackBoxMap) findMapByID(mapID); - if (map == null) { - map = new BlackBoxMap(this, mapID); - maps.add(map); - } - - BufferedReader reader = null; - try { - reader = new BufferedReader(new FileReader(info)); - StringBuffer sb = new StringBuffer(); - while (reader.ready()) { - sb.append(reader.readLine()); - } - String source = sb.toString(); - map.setSource(source); - } finally { - if (reader != null) - reader.close(); - } - } - - private void loadMapInfo(File info, String[] parts) { - BlackBoxMap map = null; - String mapID = null; - boolean reliable = false; - String timestamp = null; - - for (String part : parts) { - if (part.length() == BlackBoxManager.MD5_LENGTH) - mapID = part; - else if (part.length() == 1) - reliable = "a".equals(part) ? true : false; //$NON-NLS-1$ - else if (part.length() == BlackBoxManager.TIMESTAMP_LENGTH) - timestamp = part; - } - if (mapID == null || timestamp == null) - return; - - map = (BlackBoxMap) findMapByID(mapID); - if (map == null) { - map = new BlackBoxMap(this, mapID); - maps.add(map); - } - - Set versions = map.getVersions(); - if (versions.size() < 3) { - BlackBoxVersion v = new BlackBoxVersion(mapID, timestamp, reliable); - v.setFile(info); - versions.add(v); - } - } -} +package org.xmind.ui.blackbox; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.event.CoreEventSupport; + +/** + * @author Jason Wong + */ +public class BlackBoxLibrary implements IBlackBoxLibrary, ICoreEventSource { + + private static final String MAP_REMOVE = "mapRemove"; //$NON-NLS-1$ + + private static final String VERSION_ADD = "versionAdd"; //$NON-NLS-1$ + + private static final String VERSION_REMOVE = "versionRemove"; //$NON-NLS-1$ + + private List maps = new ArrayList(); + + private List savedSrcs = new ArrayList(); + + private File blackbox = null; + + private ICoreEventSupport coreEventSupport; + + public BlackBoxLibrary() { + load(); + } + + public synchronized void addVersion(String source, String mapID, + IBlackBoxVersion version) { + IBlackBoxMap map = findMapBySource(source); + if (map == null) { + BlackBoxMap m = new BlackBoxMap(this, mapID); + m.setSource(source); + map = m; + this.maps.add(map); + } + + Set versions = map.getVersions(); + if (versions.size() == 0) { + versions.add(version); + } else if (versions.size() < 3 && !version.isReliable()) { + versions.add(version); + } else { + IBlackBoxVersion trash = null; + trash = findTrashVersion(versions, version.isReliable()); + versions.remove(trash); + versions.add(version); + BlackBoxManager.addTrash(trash); + } + + if (!isSavedMap(source)) { + this.savedSrcs.add(source); + } + + save(map); + fireTargetEvent(VERSION_ADD, version); + } + + public synchronized boolean removeMap(IBlackBoxMap map) { + if (this.maps.remove(map)) { + BlackBoxManager.addTrash(map); + save(map); + fireTargetEvent(MAP_REMOVE, map); + return true; + } else { + return false; + } + } + + public synchronized boolean removeVersion(IBlackBoxMap map, String timestamp) { + Set versions = map.getVersions(); + for (IBlackBoxVersion v : versions) { + if (v.getTimestamp().equals(timestamp)) { + if (versions.remove(v)) { + BlackBoxManager.addTrash(v); + save(map); + if (versions.size() == 0) { + removeMap(map); + fireTargetEvent(MAP_REMOVE, map); + } + fireTargetEvent(VERSION_REMOVE, v); + return true; + } else { + return false; + } + } + } + return false; + } + + public synchronized IBlackBoxMap[] getMaps() { + load(); + return this.maps.toArray(new IBlackBoxMap[this.maps.size()]); + } + + public synchronized IBlackBoxMap findMapBySource(String source) { + for (IBlackBoxMap map : this.maps) { + if (source.equals(map.getSource())) + return map; + } + return null; + } + + public synchronized IBlackBoxMap findMapByID(String id) { + for (IBlackBoxMap map : this.maps) { + if (map.getID().equals(id)) + return map; + } + return null; + } + + public synchronized boolean isSavedMap(String source) { + if (source == null) + return false; + + return this.savedSrcs.contains(source); + } + + public synchronized void removeSavedMap(String source) { + if (!(savedSrcs.size() > 0) || source == null) + return; + if (isSavedMap(source)) { + savedSrcs.remove(source); + } + } + + private void load() { + File blackbox = new File(BlackBoxManager.getBlackboxPath()); + if (!blackbox.exists()) + return; + + maps.clear(); + File[] infos = blackbox.listFiles(); + for (File info : infos) { + String fileName = info.getName(); + String[] parts = fileName.split("\\."); //$NON-NLS-1$s + + if (fileName.contains(BlackBoxManager.FILE_INFO_EXT)) { + try { + loadBackupInfo(info, parts); + } catch (IOException e) { + BlackBoxManager + .log("Error occurred while loading maps.", e); //$NON-NLS-1$ + } + } else if (fileName.contains(BlackBoxManager.FILE_XMIND_EXT)) { + loadMapInfo(info, parts); + } + } + } + + private synchronized void save(IBlackBoxMap map) { + File metaFile = getMetaFile(map.getID()); + if (!metaFile.exists()) { + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new FileWriter(metaFile)); + writer.write(map.getSource()); + writer.flush(); + } catch (IOException e) { + } finally { + try { + if (writer != null) + writer.close(); + } catch (IOException e) { + } + } + } + BlackBoxManager.clearTrashes(); + } + + private File getMetaFile(String mapID) { + if (blackbox == null) { + blackbox = new File(BlackBoxManager.getBlackboxPath()); + } + + File metaFile = new File(blackbox, mapID + + BlackBoxManager.FILE_INFO_EXT); + return metaFile; + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return getCoreEventSupport().registerGlobalListener(type, listener); + } + + private void fireTargetEvent(String eventType, Object target) { + getCoreEventSupport().dispatchTargetChange(this, eventType, target); + } + + public ICoreEventSupport getCoreEventSupport() { + if (coreEventSupport == null) { + coreEventSupport = new CoreEventSupport(); + } + return coreEventSupport; + } + + /** + * If isReliable value is true, returns the last saved the reliable version. + * else returns the older save unreliable version. + * + * @param isReliable + * @return The IBlackBoxVersion will be replaced + */ + private IBlackBoxVersion findTrashVersion(Set versions, + boolean isReliable) { + if (isReliable) { + for (IBlackBoxVersion v : versions) { + if (v.isReliable()) { + return v; + } + } + } + + IBlackBoxVersion trash = null; + for (IBlackBoxVersion v : versions) { + if (v.isReliable()) + continue; + + if (trash == null) { + trash = v; + continue; + } + trash = trash.compareTo(v) > 0 ? v : trash; + } + return trash; + } + + private void loadBackupInfo(File info, String[] parts) throws IOException { + BlackBoxMap map = null; + String mapID = null; + + for (String part : parts) { + if (part.length() == BlackBoxManager.MD5_LENGTH) { + mapID = part; + break; + } + } + if (mapID == null) + return; + + map = (BlackBoxMap) findMapByID(mapID); + if (map == null) { + map = new BlackBoxMap(this, mapID); + maps.add(map); + } + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(info)); + StringBuffer sb = new StringBuffer(); + while (reader.ready()) { + sb.append(reader.readLine()); + } + String source = sb.toString(); + map.setSource(source); + } finally { + if (reader != null) + reader.close(); + } + } + + private void loadMapInfo(File info, String[] parts) { + BlackBoxMap map = null; + String mapID = null; + boolean reliable = false; + String timestamp = null; + + for (String part : parts) { + if (part.length() == BlackBoxManager.MD5_LENGTH) + mapID = part; + else if (part.length() == 1) + reliable = "a".equals(part) ? true : false; //$NON-NLS-1$ + else if (part.length() == BlackBoxManager.TIMESTAMP_LENGTH) + timestamp = part; + } + if (mapID == null || timestamp == null) + return; + + map = (BlackBoxMap) findMapByID(mapID); + if (map == null) { + map = new BlackBoxMap(this, mapID); + maps.add(map); + } + + Set versions = map.getVersions(); + if (versions.size() < 3) { + BlackBoxVersion v = new BlackBoxVersion(mapID, timestamp, reliable); + v.setFile(info); + versions.add(v); + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxManager.java index d63d09310..7d504643c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxManager.java @@ -1,263 +1,263 @@ -package org.xmind.ui.blackbox; - -import java.io.File; -import java.io.IOException; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.osgi.framework.Bundle; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.prefs.PrefConstants; - -/** - * @author Jason Wong - */ -public class BlackBoxManager { - - private static BlackBoxManager instance = new BlackBoxManager(); - - public static final String FILE_BLACKBOX = "blackbox"; //$NON-NLS-1$ - - public static final String FILE_INFO_EXT = ".xbkinfo"; //$NON-NLS-1$ - - public static final int MD5_LENGTH = 32; - - public static final int TIMESTAMP_LENGTH = 13; - - public static final String FILE_XMIND_EXT = ".xbkmap"; //$NON-NLS-1$ - - private static final String BREAK = "."; //$NON-NLS-1$ - - private static List versionTrashes = new ArrayList(); - - private static List mapTrashes = new ArrayList(); - - private static String pluginPath; - - private static String blackboxPath; - - private IBlackBoxLibrary library; - - private BlackBoxManager() { - } - - public static BlackBoxManager getInstance() { - return instance; - } - - public static void log(String message, Throwable e) { - IStatus status = new Status( - e == null ? IStatus.WARNING : IStatus.ERROR, message, - BlackBox.ID, e); - MindMapUIPlugin.getDefault().getLog().log(status); - } - - public static String getPluginPath() { - if (pluginPath != null) - return pluginPath; - - Bundle bundle = MindMapUIPlugin.getDefault().getBundle(); - String parentFile = Platform.getStateLocation(bundle).toFile() - .getParent(); - pluginPath = new File(parentFile, BlackBox.ID).getAbsolutePath(); - return pluginPath; - } - - public static String getBlackboxPath() { - if (blackboxPath != null && new File(blackboxPath).exists()) - return blackboxPath; - - File blackbox = new File(getPluginPath(), FILE_BLACKBOX); - FileUtils.ensureDirectory(blackbox); - if (blackbox.exists()) - blackboxPath = blackbox.getAbsolutePath(); - return blackboxPath; - } - - public static void addTrash(IBlackBoxVersion version) { - if (version == null) - return; - versionTrashes.add(version); - } - - public static void addTrash(IBlackBoxMap map) { - if (map == null) - return; - mapTrashes.add(map); - } - - public static void clearTrashes() { - if (mapTrashes.size() > 0) { - for (IBlackBoxMap m : mapTrashes) { - Set versions = m.getVersions(); - for (IBlackBoxVersion v : versions) { - if (!versionTrashes.contains(v)) { - versionTrashes.add(v); - } - } - File metaFile = new File(getBlackboxPath(), m.getID() - + FILE_INFO_EXT); - if (metaFile != null && metaFile.exists()) { - metaFile.delete(); - } - } - mapTrashes.clear(); - } - - if (versionTrashes.size() > 0) { - for (IBlackBoxVersion v : versionTrashes) { - File trash = v.getFile(); - if (trash != null && trash.exists()) { - trash.delete(); - } - } - versionTrashes.clear(); - } - } - - public static String convertToMD5(String source) { - if (source == null) - return null; - - String plainText = source; - try { - StringBuffer buf = new StringBuffer(); - MessageDigest md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$ - - md.update(plainText.getBytes()); - byte b[] = md.digest(); - int i; - for (int offset = 0; offset < b.length; offset++) { - i = b[offset]; - if (i < 0) { - i += 256; - } - if (i < 16) { - buf.append("0"); //$NON-NLS-1$ - } - buf.append(Integer.toHexString(i)); - } - return buf.toString(); - } catch (Exception e) { - BlackBoxManager.log("Error occurred while generate map id.", e); //$NON-NLS-1$ - return null; - } - } - - public void doBackup(String source) { - if (!isEnable() || source == null) - return; - - IBlackBoxLibrary library = getLibrary(); - IBlackBoxMap map = library.findMapBySource(source); - String mapID = map == null ? getMapID(source) : map.getID(); - String timestamp = String.valueOf(System.currentTimeMillis()); - boolean isReliable = !getLibrary().isSavedMap(source); - File dest = null; - try { - dest = backup(source, mapID, timestamp, isReliable); - } catch (IOException e) { - BlackBoxManager.log("Error occurred while backup src file.", //$NON-NLS-1$ - e); - return; - } - - if (dest != null) { - BlackBoxVersion version = new BlackBoxVersion(mapID, timestamp, - isReliable); - version.setFile(dest); - library.addVersion(source, mapID, version); - } - } - - public IBlackBoxMap[] getMaps() { - return getLibrary().getMaps(); - } - - public boolean removeMap(IBlackBoxMap map) { - if (map == null) - return false; - return getLibrary().removeMap(map); - } - - public boolean removeVersion(String source, String timestamp) { - return removeVersion(findMapBySource(source), timestamp); - } - - public boolean removeVersion(IBlackBoxMap map, String timestamp) { - if (map == null) - return false; - return getLibrary().removeVersion(map, timestamp); - } - - public IBlackBoxMap findMapBySource(String source) { - if (source != null) - return getLibrary().findMapBySource(source); - return null; - } - - public IBlackBoxMap findMapByID(String id) { - if (id != null) - return getLibrary().findMapByID(id); - return null; - } - - public IBlackBoxLibrary getLibrary() { - if (library == null) - library = new BlackBoxLibrary(); - return library; - } - - public void removeSavedMap(String source) { - if (!isEnable() || source == null) - return; - - getLibrary().removeSavedMap(source); - } - - /** - * @return dest file. - */ - private File backup(String source, String mapID, String timestamp, - boolean isReliable) throws IOException { - File src = new File(source); - if (!src.exists() || mapID == null) - return null; - - String destName = getDestName(mapID, timestamp, isReliable); - File dest = new File(getDestPath(mapID), destName); - if (!dest.exists()) - dest.createNewFile(); - - FileUtils.copy(src, dest); - return dest; - } - - private String getDestName(String mapID, String timestamp, - boolean isReliable) { - if (isReliable) - return mapID + BREAK + "a" + BREAK + timestamp + FILE_XMIND_EXT; //$NON-NLS-1$ - - return mapID + BREAK + "b" + BREAK + timestamp + FILE_XMIND_EXT; //$NON-NLS-1$ - } - - private String getDestPath(String mapID) throws IOException { - return getBlackboxPath(); - } - - private String getMapID(String source) { - return convertToMD5(source); - } - - private boolean isEnable() { - return MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE); - } - -} +package org.xmind.ui.blackbox; + +import java.io.File; +import java.io.IOException; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.Bundle; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; + +/** + * @author Jason Wong + */ +public class BlackBoxManager { + + private static BlackBoxManager instance = new BlackBoxManager(); + + public static final String FILE_BLACKBOX = "blackbox"; //$NON-NLS-1$ + + public static final String FILE_INFO_EXT = ".xbkinfo"; //$NON-NLS-1$ + + public static final int MD5_LENGTH = 32; + + public static final int TIMESTAMP_LENGTH = 13; + + public static final String FILE_XMIND_EXT = ".xbkmap"; //$NON-NLS-1$ + + private static final String BREAK = "."; //$NON-NLS-1$ + + private static List versionTrashes = new ArrayList(); + + private static List mapTrashes = new ArrayList(); + + private static String pluginPath; + + private static String blackboxPath; + + private IBlackBoxLibrary library; + + private BlackBoxManager() { + } + + public static BlackBoxManager getInstance() { + return instance; + } + + public static void log(String message, Throwable e) { + IStatus status = new Status( + e == null ? IStatus.WARNING : IStatus.ERROR, message, + BlackBox.ID, e); + MindMapUIPlugin.getDefault().getLog().log(status); + } + + public static String getPluginPath() { + if (pluginPath != null) + return pluginPath; + + Bundle bundle = MindMapUIPlugin.getDefault().getBundle(); + String parentFile = Platform.getStateLocation(bundle).toFile() + .getParent(); + pluginPath = new File(parentFile, BlackBox.ID).getAbsolutePath(); + return pluginPath; + } + + public static String getBlackboxPath() { + if (blackboxPath != null && new File(blackboxPath).exists()) + return blackboxPath; + + File blackbox = new File(getPluginPath(), FILE_BLACKBOX); + FileUtils.ensureDirectory(blackbox); + if (blackbox.exists()) + blackboxPath = blackbox.getAbsolutePath(); + return blackboxPath; + } + + public static void addTrash(IBlackBoxVersion version) { + if (version == null) + return; + versionTrashes.add(version); + } + + public static void addTrash(IBlackBoxMap map) { + if (map == null) + return; + mapTrashes.add(map); + } + + public static void clearTrashes() { + if (mapTrashes.size() > 0) { + for (IBlackBoxMap m : mapTrashes) { + Set versions = m.getVersions(); + for (IBlackBoxVersion v : versions) { + if (!versionTrashes.contains(v)) { + versionTrashes.add(v); + } + } + File metaFile = new File(getBlackboxPath(), m.getID() + + FILE_INFO_EXT); + if (metaFile != null && metaFile.exists()) { + metaFile.delete(); + } + } + mapTrashes.clear(); + } + + if (versionTrashes.size() > 0) { + for (IBlackBoxVersion v : versionTrashes) { + File trash = v.getFile(); + if (trash != null && trash.exists()) { + trash.delete(); + } + } + versionTrashes.clear(); + } + } + + public static String convertToMD5(String source) { + if (source == null) + return null; + + String plainText = source; + try { + StringBuffer buf = new StringBuffer(); + MessageDigest md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$ + + md.update(plainText.getBytes()); + byte b[] = md.digest(); + int i; + for (int offset = 0; offset < b.length; offset++) { + i = b[offset]; + if (i < 0) { + i += 256; + } + if (i < 16) { + buf.append("0"); //$NON-NLS-1$ + } + buf.append(Integer.toHexString(i)); + } + return buf.toString(); + } catch (Exception e) { + BlackBoxManager.log("Error occurred while generate map id.", e); //$NON-NLS-1$ + return null; + } + } + + public void doBackup(String source) { + if (!isEnable() || source == null) + return; + + IBlackBoxLibrary library = getLibrary(); + IBlackBoxMap map = library.findMapBySource(source); + String mapID = map == null ? getMapID(source) : map.getID(); + String timestamp = String.valueOf(System.currentTimeMillis()); + boolean isReliable = !getLibrary().isSavedMap(source); + File dest = null; + try { + dest = backup(source, mapID, timestamp, isReliable); + } catch (IOException e) { + BlackBoxManager.log("Error occurred while backup src file.", //$NON-NLS-1$ + e); + return; + } + + if (dest != null) { + BlackBoxVersion version = new BlackBoxVersion(mapID, timestamp, + isReliable); + version.setFile(dest); + library.addVersion(source, mapID, version); + } + } + + public IBlackBoxMap[] getMaps() { + return getLibrary().getMaps(); + } + + public boolean removeMap(IBlackBoxMap map) { + if (map == null) + return false; + return getLibrary().removeMap(map); + } + + public boolean removeVersion(String source, String timestamp) { + return removeVersion(findMapBySource(source), timestamp); + } + + public boolean removeVersion(IBlackBoxMap map, String timestamp) { + if (map == null) + return false; + return getLibrary().removeVersion(map, timestamp); + } + + public IBlackBoxMap findMapBySource(String source) { + if (source != null) + return getLibrary().findMapBySource(source); + return null; + } + + public IBlackBoxMap findMapByID(String id) { + if (id != null) + return getLibrary().findMapByID(id); + return null; + } + + public IBlackBoxLibrary getLibrary() { + if (library == null) + library = new BlackBoxLibrary(); + return library; + } + + public void removeSavedMap(String source) { + if (!isEnable() || source == null) + return; + + getLibrary().removeSavedMap(source); + } + + /** + * @return dest file. + */ + private File backup(String source, String mapID, String timestamp, + boolean isReliable) throws IOException { + File src = new File(source); + if (!src.exists() || mapID == null) + return null; + + String destName = getDestName(mapID, timestamp, isReliable); + File dest = new File(getDestPath(mapID), destName); + if (!dest.exists()) + dest.createNewFile(); + + FileUtils.copy(src, dest); + return dest; + } + + private String getDestName(String mapID, String timestamp, + boolean isReliable) { + if (isReliable) + return mapID + BREAK + "a" + BREAK + timestamp + FILE_XMIND_EXT; //$NON-NLS-1$ + + return mapID + BREAK + "b" + BREAK + timestamp + FILE_XMIND_EXT; //$NON-NLS-1$ + } + + private String getDestPath(String mapID) throws IOException { + return getBlackboxPath(); + } + + private String getMapID(String source) { + return convertToMD5(source); + } + + private boolean isEnable() { + return MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxMap.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxMap.java index 9e1243f71..750077ed5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxMap.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxMap.java @@ -1,48 +1,48 @@ -package org.xmind.ui.blackbox; - -import java.util.HashSet; -import java.util.Set; - -/** - * @author Jason Wong - */ -public class BlackBoxMap implements IBlackBoxMap { - - private IBlackBoxLibrary library; - - private String id; - - private Set versions; - - private String source; - - public BlackBoxMap(IBlackBoxLibrary library, String id) { - this.library = library; - this.id = id; - } - - public IBlackBoxLibrary getBlackBoxLibrary() { - return library; - } - - public String getID() { - return id; - } - - public Set getVersions() { - if (versions == null) - versions = new HashSet(); - return versions; - } - - public String getSource() { - if (source == null) - return ""; //$NON-NLS-1$ - return source; - } - - public void setSource(String source) { - this.source = source; - } - -} +package org.xmind.ui.blackbox; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Jason Wong + */ +public class BlackBoxMap implements IBlackBoxMap { + + private IBlackBoxLibrary library; + + private String id; + + private Set versions; + + private String source; + + public BlackBoxMap(IBlackBoxLibrary library, String id) { + this.library = library; + this.id = id; + } + + public IBlackBoxLibrary getBlackBoxLibrary() { + return library; + } + + public String getID() { + return id; + } + + public Set getVersions() { + if (versions == null) + versions = new HashSet(); + return versions; + } + + public String getSource() { + if (source == null) + return ""; //$NON-NLS-1$ + return source; + } + + public void setSource(String source) { + this.source = source; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxVersion.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxVersion.java index 3214803fc..465a2c2e2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxVersion.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/BlackBoxVersion.java @@ -1,58 +1,58 @@ -package org.xmind.ui.blackbox; - -import java.io.File; - -/** - * @author Jason Wong - */ -public class BlackBoxVersion implements IBlackBoxVersion { - - private String mapID; - - private String timestamp; - - private boolean reliable; - - private File file; - - public BlackBoxVersion(String mapID, String timestamp, boolean reliable) { - this.mapID = mapID; - this.timestamp = timestamp; - this.reliable = reliable; - } - - public String getMapID() { - return mapID; - } - - public String getTimestamp() { - return timestamp; - } - - public boolean isReliable() { - return reliable; - } - - public IBlackBoxMap getMap() { - return BlackBoxManager.getInstance().findMapByID(mapID); - } - - public void setFile(File file) { - this.file = file; - } - - public File getFile() { - return file; - } - - public int compareTo(IBlackBoxVersion anotherVersion) { - long timestamp1 = Long.parseLong(this.timestamp); - long timestamp2 = Long.parseLong(anotherVersion.getTimestamp()); - if (timestamp1 == timestamp2) - return 0; - if (timestamp1 > timestamp2) - return 1; - return -1; - } - -} +package org.xmind.ui.blackbox; + +import java.io.File; + +/** + * @author Jason Wong + */ +public class BlackBoxVersion implements IBlackBoxVersion { + + private String mapID; + + private String timestamp; + + private boolean reliable; + + private File file; + + public BlackBoxVersion(String mapID, String timestamp, boolean reliable) { + this.mapID = mapID; + this.timestamp = timestamp; + this.reliable = reliable; + } + + public String getMapID() { + return mapID; + } + + public String getTimestamp() { + return timestamp; + } + + public boolean isReliable() { + return reliable; + } + + public IBlackBoxMap getMap() { + return BlackBoxManager.getInstance().findMapByID(mapID); + } + + public void setFile(File file) { + this.file = file; + } + + public File getFile() { + return file; + } + + public int compareTo(IBlackBoxVersion anotherVersion) { + long timestamp1 = Long.parseLong(this.timestamp); + long timestamp2 = Long.parseLong(anotherVersion.getTimestamp()); + if (timestamp1 == timestamp2) + return 0; + if (timestamp1 > timestamp2) + return 1; + return -1; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxLibrary.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxLibrary.java index 346904d98..019900167 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxLibrary.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxLibrary.java @@ -1,24 +1,24 @@ -package org.xmind.ui.blackbox; - -/** - * @author Jason Wong - */ -public interface IBlackBoxLibrary { - - public IBlackBoxMap[] getMaps(); - - public IBlackBoxMap findMapBySource(String source); - - public IBlackBoxMap findMapByID(String id); - - public void addVersion(String source, String mapID, IBlackBoxVersion version); - - public boolean removeMap(IBlackBoxMap map); - - public boolean removeVersion(IBlackBoxMap map, String timestamp); - - public boolean isSavedMap(String id); - - public void removeSavedMap(String source); - -} +package org.xmind.ui.blackbox; + +/** + * @author Jason Wong + */ +public interface IBlackBoxLibrary { + + public IBlackBoxMap[] getMaps(); + + public IBlackBoxMap findMapBySource(String source); + + public IBlackBoxMap findMapByID(String id); + + public void addVersion(String source, String mapID, IBlackBoxVersion version); + + public boolean removeMap(IBlackBoxMap map); + + public boolean removeVersion(IBlackBoxMap map, String timestamp); + + public boolean isSavedMap(String id); + + public void removeSavedMap(String source); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxMap.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxMap.java index 749f9b806..1e83bd050 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxMap.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxMap.java @@ -1,18 +1,18 @@ -package org.xmind.ui.blackbox; - -import java.util.Set; - -/** - * @author Jason Wong - */ -public interface IBlackBoxMap { - - IBlackBoxLibrary getBlackBoxLibrary(); - - String getID(); - - Set getVersions(); - - String getSource(); - -} +package org.xmind.ui.blackbox; + +import java.util.Set; + +/** + * @author Jason Wong + */ +public interface IBlackBoxMap { + + IBlackBoxLibrary getBlackBoxLibrary(); + + String getID(); + + Set getVersions(); + + String getSource(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxVersion.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxVersion.java index d5c4b6218..9edb9932e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxVersion.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/blackbox/IBlackBoxVersion.java @@ -1,22 +1,22 @@ -package org.xmind.ui.blackbox; - -import java.io.File; - -/** - * @author Jason Wong - */ -public interface IBlackBoxVersion { - - String getMapID(); - - String getTimestamp(); - - boolean isReliable(); - - IBlackBoxMap getMap(); - - File getFile(); - - int compareTo(IBlackBoxVersion anotherVersion); - -} +package org.xmind.ui.blackbox; + +import java.io.File; + +/** + * @author Jason Wong + */ +public interface IBlackBoxVersion { + + String getMapID(); + + String getTimestamp(); + + boolean isReliable(); + + IBlackBoxMap getMap(); + + File getFile(); + + int compareTo(IBlackBoxVersion anotherVersion); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/AbstractBranchStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/AbstractBranchStructure.java index 0b2d9935e..106337fe9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/AbstractBranchStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/AbstractBranchStructure.java @@ -1,1309 +1,1309 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import static org.xmind.ui.style.StyleUtils.getInteger; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IDecoratedFigure; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.IRotatableFigure; -import org.xmind.gef.draw2d.ReferencedLayoutData; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.BoundaryLayoutHelper.BoundaryData; -import org.xmind.ui.decorations.IBranchConnectionDecoration; -import org.xmind.ui.decorations.IBranchConnections2; -import org.xmind.ui.decorations.ISummaryDecoration; -import org.xmind.ui.decorations.ITopicDecoration; -import org.xmind.ui.internal.figures.BoundaryFigure; -import org.xmind.ui.internal.figures.BranchFigure; -import org.xmind.ui.internal.figures.TopicFigure; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.ILabelPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.tools.ParentSearchKey; -import org.xmind.ui.util.MindMapUtils; - -public abstract class AbstractBranchStructure implements IBranchStructure, - IBranchStructureExtension, INavigableBranchStructureExtension, - IInsertableBranchStructureExtension { - - protected static final String CACHE_STRUCTURE_DATA = "org.xmind.ui.branchCache.structureData"; //$NON-NLS-1$ - - protected static final String CACHE_BOUNDARY_LAYOUT_HELPER = "org.xmind.ui.branchCache.boundaryLayoutHelper"; //$NON-NLS-1$ - - protected static class LayoutInfo extends ReferencedLayoutData { - - private ReferencedLayoutData delegate; - - private boolean folded; - - private boolean minimized; - - private Rectangle minArea; - - private boolean hasBoundaryTitles; - - public LayoutInfo(ReferencedLayoutData delegate, boolean folded, - boolean minimized) { - this.delegate = delegate; - this.folded = folded; - this.minimized = minimized; - this.minArea = null; - this.hasBoundaryTitles = false; - } - - public boolean isFolded() { - return folded; - } - - public boolean isMinimized() { - return minimized; - } - - public Rectangle getMinArea() { - return minArea; - } - - public void setMinArea(Rectangle minArea) { - this.minArea = minArea; - } - - public void putMinArea(IFigure figure) { - if (minArea == null) { - delegate.put(figure, delegate.createInitBounds()); - } else { - delegate.put(figure, minArea.getCopy()); - } - } - - public void add(Rectangle blankArea) { - delegate.add(blankArea); - } - - public void addMargins(Insets margin) { - delegate.addMargins(margin); - } - - public void addMargins(int top, int left, int bottom, int right) { - delegate.addMargins(top, left, bottom, right); - } - - public Rectangle createInitBounds() { - return delegate.createInitBounds(); - } - - public Rectangle createInitBounds(Point ref) { - return delegate.createInitBounds(ref); - } - - public Rectangle get(Object figure) { - return delegate.get(figure); - } - - public Rectangle getCheckedClientArea() { - return delegate.getCheckedClientArea(); - } - - public Rectangle getClientArea() { - return delegate.getClientArea(); - } - - public Point getReference() { - return delegate.getReference(); - } - - public void put(IFigure figure, Rectangle preferredBounds) { - delegate.put(figure, preferredBounds); - } - - public void translate(int dx, int dy) { - delegate.translate(dx, dy); - } - - } - - public void fillLayoutData(IBranchPart branch, ReferencedLayoutData data) { - BranchFigure figure = (BranchFigure) branch.getFigure(); - boolean folded = figure.isFolded(); - boolean minimized = figure.isMinimized(); - LayoutInfo info = new LayoutInfo(data, folded, minimized); - fillLayoutInfo(branch, info); - } - - protected void fillLayoutInfo(IBranchPart branch, LayoutInfo info) { - IStyleSelector styleSelector = branch.getBranchPolicy() - .getStyleSelector(branch); - if (styleSelector != null) { - String hideCallout = styleSelector.getStyleValue(branch, - Styles.HideCallout); - if (Boolean.parseBoolean(hideCallout) && MindMapUI.BRANCH_CALLOUT - .equals(branch.getBranchType())) { - branch.getFigure().setVisible(false); - return; - } - } -// if ("org.xmind.ui.spreadsheet".equals(branch.getBranchPolicyId()) //$NON-NLS-1$ -// && MindMapUI.BRANCH_CALLOUT.equals(branch.getBranchType())) { -// branch.getFigure().setVisible(false); -// return; -// } - - fillTopic(branch, info); - fillPlusMinus(branch, info); - fillLabel(branch, info); - fillInformation(branch, info); - - List subBranches = branch.getSubBranches(); - List boundaries = branch.getBoundaries(); - - BoundaryLayoutHelper boundaryLayoutHelper = getBoundaryLayoutHelper( - branch); - -// boundaryLayoutHelper.reset(branch, this, null); - info.hasBoundaryTitles = false; - - ReferencedLayoutData fakeDelegate = info.delegate.copy(); - ReferencedLayoutData realDelegate = info.delegate; - info.delegate = fakeDelegate; - - fillSubBranches(branch, subBranches, info); - fillBoundaries(branch, boundaries, subBranches, info); - info.delegate = realDelegate; - - if (info.hasBoundaryTitles) { - Map cachedBounds = new HashMap(); - for (IBoundaryPart boundary : branch.getBoundaries()) { - cachedBounds.put(boundary.getFigure(), - fakeDelegate.get(boundary.getFigure())); - } - boundaryLayoutHelper.reset(branch, this, cachedBounds); - fillSubBranches(branch, subBranches, info); - fillBoundaries(branch, boundaries, subBranches, info); - } else { - for (IBranchPart subBranch : branch.getSubBranches()) { - info.delegate.put(subBranch.getFigure(), - fakeDelegate.get(subBranch.getFigure())); - } - for (IBoundaryPart boundary : branch.getBoundaries()) { - info.delegate.put(boundary.getFigure(), - fakeDelegate.get(boundary.getFigure())); - } - } - - List calloutBranches = branch.getCalloutBranches(); - fillCalloutBranches(branch, calloutBranches, info); - - List summaries = branch.getSummaries(); - List summaryBranches = new ArrayList( - branch.getSummaryBranches()); - fillSummaries(branch, summaries, summaryBranches, subBranches, info); - fillUnhandledSummaryBranches(branch, summaryBranches, info); - - addExtraSpaces(branch, info); - - boundaryLayoutHelper.reset(branch, this, null); - info.hasBoundaryTitles = false; - - fakeDelegate = info.delegate.copy(); - realDelegate = info.delegate; - info.delegate = fakeDelegate; - info.hasBoundaryTitles = false; - fillOverallBoundary(branch, boundaries, info); - info.delegate = realDelegate; - if (info.hasBoundaryTitles) { - Map cachedBounds = new HashMap(); - for (IBoundaryPart boundary : branch.getBoundaries()) { - cachedBounds.put(boundary.getFigure(), - fakeDelegate.get(boundary.getFigure())); - } - boundaryLayoutHelper.setOverallBoundary(null); - boundaryLayoutHelper.reset(branch, this, cachedBounds); - fillOverallBoundary(branch, boundaries, info); - } else { - for (IBranchPart subBranch : branch.getSubBranches()) { - info.delegate.put(subBranch.getFigure(), - fakeDelegate.get(subBranch.getFigure())); - } - for (IBoundaryPart boundary : branch.getBoundaries()) { - info.delegate.put(boundary.getFigure(), - fakeDelegate.get(boundary.getFigure())); - } - } - - } - - protected void fillCalloutBranches(IBranchPart branch, - List calloutBranches, LayoutInfo info) { - if (calloutBranches.isEmpty()) - return; - - IStyleSelector styleSelector = branch.getBranchPolicy() - .getStyleSelector(branch); - if (styleSelector != null) { - String hideCallout = styleSelector.getStyleValue(branch, - Styles.HideCallout); - if (Boolean.parseBoolean(hideCallout)) { - for (IBranchPart calloutBranch : calloutBranches) { - calloutBranch.getFigure().setVisible(false); - } - IBranchConnections2 calloutConnections = branch - .getCalloutConnections(); - for (int index = 0; index < calloutBranches.size(); index++) { - IDecoration decoration = calloutConnections - .getDecoration(index); - if (decoration instanceof IBranchConnectionDecoration) { - ((IBranchConnectionDecoration) decoration) - .setVisible(branch.getFigure(), false); - } - } - return; - } - } - - if ((info.isFolded() || info.isMinimized()) - && minimizesSubBranchesToOnePoint()) { - if (info.isFolded() && !info.isMinimized()) { - info.setMinArea(info.createInitBounds(calcSubBranchesMinPoint( - branch, calloutBranches, info))); - } - for (IBranchPart calloutBranch : calloutBranches) { - info.putMinArea(calloutBranch.getFigure()); - } - } else { - doFillCalloutBranches(branch, calloutBranches, info); - for (IBranchPart calloutBranch : calloutBranches) { - IFigure calloutBranchFigure = calloutBranch.getFigure(); - if (info.get(calloutBranchFigure) == null) { - info.putMinArea(calloutBranchFigure); - } - } - } - } - - protected void doFillCalloutBranches(IBranchPart branch, - List calloutBranches, LayoutInfo info) { - if (branch.isCentral()) { - for (IBranchPart calloutBranch : calloutBranches) { - calloutBranch.getFigure().setVisible(false); - } - IBranchConnections2 calloutConnections = branch - .getCalloutConnections(); - for (int index = 0; index < calloutBranches.size(); index++) { - IDecoration decoration = calloutConnections - .getDecoration(index); - if (decoration instanceof IBranchConnectionDecoration) { - ((IBranchConnectionDecoration) decoration) - .setVisible(branch.getFigure(), false); - } - } - return; - } - - IBranchPart parentBranch = branch.getParentBranch(); - int orientation = getChildTargetOrientation(parentBranch, branch); - boolean left = PositionConstants.EAST == orientation; - boolean right = PositionConstants.WEST == orientation; - boolean south = PositionConstants.NORTH == orientation; - boolean north = PositionConstants.SOUTH == orientation; - - for (IBranchPart calloutBranch : calloutBranches) { - //changed - Rectangle parentTopicArea = info - .get(branch.getTopicPart().getFigure()); - Rectangle parentBranchArea = info.getCheckedClientArea(); - - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - ITopicPart calloutTopicPart = calloutBranch.getTopicPart(); - if (calloutTopicPart == null) - continue; - IFigure calloutFigure = calloutTopicPart.getFigure(); - Dimension calloutSize = calloutFigure.getPreferredSize(); - - //over parent topic center - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - int offsetX = originPosition ? 0 : position.x; - int offsetY = originPosition - ? -calloutSize.height / 2 - parentTopicArea.height / 2 - 10 - : position.y; - - boolean upDown = offsetY < 0; - - int dummyCalloutX = parentTopicArea.getCenter().x + offsetX - - calloutSize.width / 2; - - if (left) { - //limit left movable boundary - int dx = (dummyCalloutX + calloutSize.width) - - (parentTopicArea.x + parentTopicArea.width); - offsetX = dx > 0 ? offsetX - dx : offsetX; - } else if (right) { - //limit right movable boundary - int dx = dummyCalloutX - parentTopicArea.x; - offsetX = dx < 0 ? offsetX - dx : offsetX; - } - - Point reference = info.getReference(); - Point translated = reference.getTranslated(offsetX, offsetY); - Rectangle bounds = calloutBranchFigure - .getPreferredBounds(translated); - - int subRectX = left || south || north ? parentBranchArea.x - : parentBranchArea.x + parentTopicArea.width; - int subRectY = left || right || north ? parentBranchArea.y - : parentBranchArea.y + parentTopicArea.height; - int subRectWidth = left || right - ? parentBranchArea.width - parentTopicArea.width - : parentBranchArea.width; - int subRectHeight = left || right ? parentBranchArea.height - : parentBranchArea.height - parentTopicArea.height; - Rectangle subRect = new Rectangle(subRectX, subRectY, subRectWidth, - subRectHeight); - boolean touchSub = subRect.touches(bounds); - boolean touchParentTopic = bounds.touches(parentTopicArea); - if (touchSub) { - int y = upDown ? subRect.y - bounds.height - 10 - : subRect.bottom() + 10; - bounds.setY(y); - } else if (touchParentTopic) { - int y = upDown ? parentTopicArea.y - bounds.height - 10 - : parentTopicArea.bottom() + 10; - bounds.setY(y); - } - info.put(calloutBranchFigure, bounds); - } - } - - protected void fillTopic(IBranchPart branch, LayoutInfo info) { - ITopicPart topic = branch.getTopicPart(); - if (topic != null) { - if (info.isMinimized()) { - info.putMinArea(topic.getFigure()); - } else { - doFillTopic(branch, topic, info); - } - } - } - - protected void doFillTopic(IBranchPart branch, ITopicPart topicPart, - LayoutInfo info) { - IFigure fig = topicPart.getFigure(); - if (fig instanceof IReferencedFigure) { - IReferencedFigure refFig = (IReferencedFigure) fig; - Rectangle bounds = refFig.getPreferredBounds(info.getReference()); - info.put(refFig, bounds); - } else { - Dimension size = fig.getPreferredSize(); - Point ref = info.getReference(); - Rectangle r = new Rectangle(ref.x - size.width / 2, - ref.y - size.height / 2, size.width, size.height); - info.put(fig, r); - } - } - - protected void fillPlusMinus(IBranchPart branch, LayoutInfo info) { - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - IFigure pmFigure = plusMinus.getFigure(); - if (info.isMinimized()) { - info.putMinArea(pmFigure); - } else { - doFillPlusMinus(branch, plusMinus, info); - if (info.get(pmFigure) == null) { - info.putMinArea(pmFigure); - } - } - } - } - - protected abstract void doFillPlusMinus(IBranchPart branch, - IPlusMinusPart plusMinus, LayoutInfo info); - - protected void fillLabel(IBranchPart branch, LayoutInfo info) { - ILabelPart label = branch.getLabel(); - if (label != null) { - if (info.isMinimized() || !label.getFigure().isVisible()) { - info.putMinArea(label.getFigure()); - } else { - doFillLabel(branch, label, info); - } - } - } - - protected void doFillLabel(IBranchPart branch, ILabelPart label, - LayoutInfo info) { - IFigure figure = label.getFigure(); - ITopicPart topicPart = branch.getTopicPart(); - Rectangle area; - if (topicPart != null) { - area = info.get(topicPart.getFigure()); - } else { - area = info.createInitBounds(); - } - if (figure instanceof IRotatableFigure) { - IRotatableFigure f = (IRotatableFigure) figure; - double angle = f.getRotationDegrees(); - if (!Geometry.isSameAngleDegree(angle, 0, 0.00001)) { - Point ref = info.getReference(); - PrecisionRotator r = new PrecisionRotator(); - r.setOrigin(ref.x, ref.y); - r.setAngle(angle); - PrecisionRectangle rect = r.r(new PrecisionRectangle(area)); - PrecisionDimension size = f.getNormalPreferredSize(-1, -1); - rect.x += (rect.width - size.width) / 2; - rect.y = rect.bottom() - 2; - rect.width = size.width; - rect.height = size.height; - r.t(rect); - info.put(figure, rect.toDraw2DRectangle()); - return; - } - } - Dimension size = figure.getPreferredSize(); - Rectangle r = new Rectangle(area.x + (area.width - size.width) / 2, - area.bottom() - 2, size.width, size.height); - info.put(figure, r); - } - - protected void fillInformation(IBranchPart branch, LayoutInfo info) { - IInfoPart information = branch.getInfoPart(); - if (information != null) { - if (info.isMinimized() || !information.getFigure().isVisible()) { - info.putMinArea(information.getFigure()); - } else { - doFillInfomation(branch, information, info); - } - } - } - - protected void doFillInfomation(IBranchPart branch, IInfoPart information, - LayoutInfo info) { - IFigure figure = information.getFigure(); - ITopicPart topicPart = branch.getTopicPart(); - Rectangle area; - if (topicPart != null) { - area = info.get(topicPart.getFigure()); - } else { - area = info.createInitBounds(); - } - - Dimension size = figure.getPreferredSize(); - - TopicFigure tf = (TopicFigure) topicPart.getFigure(); - ITopicDecoration decoration = tf.getDecoration(); - String shapeId = decoration.getId(); - int x; - if (Styles.TOPIC_SHAPE_ROUNDEDRECT.equals(shapeId) - || Styles.TOPIC_SHAPE_RECT.equals(shapeId) - || Styles.TOPIC_SHAPE_UNDERLINE.equals(shapeId)) - x = area.x; - else - x = area.x + (area.width - size.width) / 2; - - int y = area.bottom() - 1; - if (!Styles.TOPIC_SHAPE_UNDERLINE.equals(shapeId)) - y -= 1; - - Rectangle r = new Rectangle(x, y, size.width, size.height); - info.put(figure, r); - } - - protected void fillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - if (subBranches.isEmpty()) - return; - if ((info.isFolded() || info.isMinimized()) - && minimizesSubBranchesToOnePoint()) { - if (info.isFolded() && !info.isMinimized()) { - info.setMinArea(info.createInitBounds( - calcSubBranchesMinPoint(branch, subBranches, info))); - } - for (IBranchPart subBranch : subBranches) { - info.putMinArea(subBranch.getFigure()); - } - } else { - doFillSubBranches(branch, subBranches, info); - for (IBranchPart subBranch : subBranches) { - IFigure subBranchFigure = subBranch.getFigure(); - if (info.get(subBranchFigure) == null) { - info.putMinArea(subBranchFigure); - } - } - } - } - - protected abstract void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info); - - protected boolean minimizesSubBranchesToOnePoint() { - return true; - } - - protected Point calcSubBranchesMinPoint(IBranchPart branch, - List subBranches, LayoutInfo info) { - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - Rectangle pmBounds = info.get(plusMinus.getFigure()); - if (pmBounds != null) { - return pmBounds.getCenter(); - } - } - return info.getReference(); - } - - protected void fillBoundaries(IBranchPart branch, - List boundaries, List subBranches, - LayoutInfo info) { - - if (boundaries.isEmpty()) - return; - if (subBranches.isEmpty() || ((info.isFolded() || info.isMinimized()) - && minimizesSubBranchesToOnePoint())) { - for (IBoundaryPart b : boundaries) { - info.putMinArea(b.getFigure()); - } - } else { - doFillBoundaries(branch, boundaries, info); - } - } - - protected void doFillBoundaries(IBranchPart branch, - List boundaries, LayoutInfo info) { - - for (IBoundaryPart boundary : boundaries) { - doFillBoundary(branch, boundary, info); - } - } - - protected void doFillBoundary(IBranchPart branch, IBoundaryPart boundary, - LayoutInfo info) { - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - BoundaryData boundaryData = helper.getBoundaryData(boundary); - - if (boundary.getFigure() != null - && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() - && boundary.getTitle() != null) { - info.hasBoundaryTitles = true; - } - - if (boundaryData.isOverall()) { - if (boundaryData != helper.getOverallBoundary()) { - info.putMinArea(boundary.getFigure()); - } - return; - } - Rectangle area = null; - for (IBranchPart subBranch : boundaryData.getSubBranches()) { - Insets ins = helper.getInnerInsets( - helper.getSubBranchData(subBranch), boundaryData); - Rectangle r2 = info.get(subBranch.getFigure()); - area = Geometry.union(area, r2.getExpanded(ins)); - } - if (area == null) { - info.putMinArea(boundary.getFigure()); - } else { - area = boundaryData.expanded(area); - info.put(boundary.getFigure(), area); - } - } - - protected void fillSummaries(IBranchPart branch, - List summaries, List summaryBranches, - List subBranches, LayoutInfo info) { - if (!summaries.isEmpty()) { - if (subBranches.isEmpty() - || ((info.isFolded() || info.isMinimized()) - && minimizesSubBranchesToOnePoint())) { - for (ISummaryPart s : summaries) { - info.putMinArea(s.getFigure()); - } - } else { - doFillSummaries(branch, summaries, summaryBranches, info); - } - } - } - - private void doFillSummaries(IBranchPart branch, - List summaries, List summaryBranches, - LayoutInfo info) { - for (ISummaryPart summary : summaries) { - doFillSummary(branch, summary, summaryBranches, info); - } - } - - private void doFillSummary(IBranchPart branch, ISummaryPart summary, - List summaryBranches, LayoutInfo info) { - int direction = getSummaryDirection(branch, summary); - Rectangle area = getSummaryArea(branch, summary, direction, info); - if (area != null) { - info.put(summary.getFigure(), area); - } else { - info.putMinArea(summary.getFigure()); - } - IBranchPart conclusionBranch = getConclusionBranch(branch, summary, - summaryBranches); - if (conclusionBranch != null) { - if (area == null) { - info.putMinArea(conclusionBranch.getFigure()); - } else { - Insets ins = getConclusionReferenceDescription(branch, summary, - conclusionBranch); - int x, y; - switch (direction) { - case PositionConstants.NORTH: - x = area.x + area.width / 2; - y = area.y - ins.bottom; - break; - case PositionConstants.SOUTH: - x = area.x + area.width / 2; - y = area.bottom() + ins.top; - break; - case PositionConstants.WEST: - x = area.x - ins.right; - y = area.y + area.height / 2; - break; - default: - x = area.right() + ins.left; - y = area.y + area.height / 2; - } - info.put(conclusionBranch.getFigure(), - Geometry.getExpanded(x, y, ins)); - } - } - } - - private IBranchPart getConclusionBranch(IBranchPart branch, - ISummaryPart summary, List summaryBranches) { - IGraphicalPart part = summary.getNode(); - if (part instanceof ITopicPart) { - IBranchPart conclusionBranch = ((ITopicPart) part).getOwnerBranch(); - if (conclusionBranch != null - && summaryBranches.contains(conclusionBranch)) { - summaryBranches.remove(conclusionBranch); - return conclusionBranch; - } - } - return null; - } - - private Insets getConclusionReferenceDescription(IBranchPart branch, - ISummaryPart summary, IGraphicalPart conclusion) { - IFigure fig = conclusion.getFigure(); - if (fig instanceof IReferencedFigure) - return ((IReferencedFigure) fig).getReferenceDescription(); - Dimension size = fig.getPreferredSize(); - int w = size.width / 2; - int h = size.height / 2; - return new Insets(h, w, size.height - h, size.width - w); - } - - protected Rectangle getSummaryArea(IBranchPart branch, ISummaryPart summary, - int direction, ReferencedLayoutData data) { - Rectangle r = null; - for (IBranchPart subBranch : summary.getEnclosingBranches()) { - r = Geometry.union(r, data.get(subBranch.getFigure())); - } - if (r == null) - return null; - - Rectangle area = data.createInitBounds(); - int width = getPreferredSummaryWidth(summary); - switch (direction) { - case PositionConstants.NORTH: - area.x = r.x; - area.width = r.width; - area.y = r.y - width; - area.height = width; - break; - case PositionConstants.SOUTH: - area.x = r.x; - area.width = r.width; - area.y = r.bottom(); - area.height = width; - break; - case PositionConstants.WEST: - area.x = r.x - width; - area.width = width; - area.y = r.y; - area.height = r.height; - break; - default: - area.x = r.right(); - area.width = width; - area.y = r.y; - area.height = r.height; - } - IStyleSelector ss = StyleUtils.getStyleSelector(summary); - String shape = StyleUtils.getString(summary, ss, Styles.ShapeClass, - null); - int lineWidth = StyleUtils.getInteger(summary, ss, Styles.LineWidth, - shape, 1); - return area.expand(lineWidth, lineWidth); - } - - private int getPreferredSummaryWidth(ISummaryPart summary) { - IFigure figure = summary.getFigure(); - if (figure instanceof IDecoratedFigure) { - IDecoration decoration = ((IDecoratedFigure) figure) - .getDecoration(); - if (decoration instanceof ISummaryDecoration) { - return ((ISummaryDecoration) decoration) - .getPreferredWidth(figure); - } - } - return Styles.DEFAULT_SUMMARY_WIDTH - + Styles.DEFAULT_SUMMARY_SPACING * 2; - } - - protected void fillUnhandledSummaryBranches(IBranchPart branch, - List summaryBranches, LayoutInfo info) { - if (!summaryBranches.isEmpty()) { - for (IBranchPart summaryBranch : summaryBranches) { - info.putMinArea(summaryBranch.getFigure()); - } - } - } - - protected void addExtraSpaces(IBranchPart branch, - ReferencedLayoutData data) { - // may be subclassed - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - return PositionConstants.EAST; - } - - protected void fillOverallBoundary(IBranchPart branch, - List boundaries, LayoutInfo info) { - if (boundaries.isEmpty()) - return; - IBoundaryPart boundary = branch.getBoundaries() - .get(boundaries.size() - 1); - - if (boundary.getFigure() != null - && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() - && boundary.getTitle() != null) { - info.hasBoundaryTitles = true; - } - - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - BoundaryData overallBoundary = helper.getOverallBoundary(); - if (overallBoundary == null) - return; - - if (info.isMinimized()) { - info.putMinArea(overallBoundary.boundaryFigure); - } else { - Rectangle area = info.getCheckedClientArea(); - area = overallBoundary.expanded(area.getCopy()); - info.put(overallBoundary.boundaryFigure, area); - } - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.SOUTH; - } - - public void invalidate(IGraphicalPart part) { - if (part instanceof IBranchPart) { - invalidateBranch((IBranchPart) part); - } - } - - protected void invalidateBranch(IBranchPart branch) { - MindMapUtils.flushCache(branch, CACHE_STRUCTURE_DATA); - MindMapUtils.flushCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER); - ITopicPart topic = branch.getTopicPart(); - if (topic != null) { - IFigure topicFigure = topic.getFigure(); - if (topicFigure != null) { - topicFigure.invalidate(); - } - } - } - - protected BoundaryLayoutHelper getBoundaryLayoutHelper(IBranchPart branch) { - BoundaryLayoutHelper helper = (BoundaryLayoutHelper) MindMapUtils - .getCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER); - if (helper == null) { - helper = new BoundaryLayoutHelper(); - helper.reset(branch, this, null); - MindMapUtils.setCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER, helper); - } - return helper; - } - - protected Dimension getBorderedSize(IBranchPart branch, - IBranchPart subBranch) { - return getBoundaryLayoutHelper(branch).getBorderedSize(subBranch); - } - - protected int getMinorSpacing(IBranchPart branch) { - return getInteger(branch, - branch.getBranchPolicy().getStyleSelector(branch), - Styles.MinorSpacing, 5); - } - - protected int getMajorSpacing(IBranchPart branch) { - return StyleUtils.getMajorSpacing(branch, 5); - } - - protected Object getStructureData(IBranchPart branch) { - Object data = MindMapUtils.getCache(branch, CACHE_STRUCTURE_DATA); - if (!isValidStructureData(branch, data)) { - data = createStructureData(branch); - if (data != null) { - MindMapUtils.setCache(branch, CACHE_STRUCTURE_DATA, data); - } - } - return data; - } - - protected Object createStructureData(IBranchPart branch) { - return null; - } - - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return data != null; - } - -// public void calculateSubBranchInsets(BoundaryData boundary, -// SubBranchData subBranch, Insets insets) { -// } - - /* - * Subclass may extend this method. - * - * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# - * calcSourceOrientation(org.xmind.ui.parts.IBranchPart) - */ - public int getSourceOrientation(IBranchPart branch) { - return PositionConstants.NONE; - } - - /* - * Subclass may extend this method. - * - * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# - * calcChildTargetOrientation(org.xmind.ui.parts.IBranchPart, - * org.xmind.ui.parts.IBranchPart) - */ - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return PositionConstants.NONE; - } - -// /* -// * Subclass may extend this method. -// * -// * @see org.xmind.ui.graphicalpolicies.IBranchStructure#calcChildTargetOrientation(org.xmind.ui.parts.IBranchPart, -// * org.xmind.gef.draw2d.IReferencedFigure) -// */ -// public int calcChildTargetOrientation(IBranchPart branch, -// IReferencedFigure childFigure) { -// return PositionConstants.NONE; -// } - - /* - * Subclass may extend this method. - * - * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# - * calcChildIndex(org.xmind.ui.tools.ParentSearchKey) - */ - public int calcChildIndex(IBranchPart branch, ParentSearchKey key) { - return calcInsIndex(branch, key, false); - } - - /* - * Subclass may extend this method. - * - * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# - * calcChildDistance(org.xmind.ui.parts.IBranchPart, - * org.xmind.ui.tools.ParentSearchKey) - */ - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - return -1; - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return null; - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - return null; - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_BEGINNING.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } else if (GEF.REQ_NAV_END.equals(navReqType)) { - return getSubTopicPart(branch, branch.getSubBranches().size() - 1); - } - return null; - } - - public void calcSequentialNavigation(IBranchPart branch, - IBranchPart startChild, IBranchPart endChild, - List results) { - addSubBranches(branch, startChild.getBranchIndex(), - endChild.getBranchIndex(), results); - } - - public void calcTraversableBranches(IBranchPart branch, - IBranchPart sourceChild, List results) { - addSubBranch(branch, sourceChild.getBranchIndex() + 1, results); - results.add(branch); - addSubBranch(branch, sourceChild.getBranchIndex() - 1, results); - } - - public void calcTraversableChildren(IBranchPart branch, - List results) { - addSubBranches(branch, 0, branch.getSubBranches().size() - 1, results); - } - - protected void addSubBranches(IBranchPart branch, IBranchPart fromChild, - IBranchPart toChild, List results) { - addSubBranches(branch, branch.getSubBranches().indexOf(fromChild), - branch.getSubBranches().indexOf(toChild), results); - } - - protected void addSubBranches(IBranchPart branch, int fromIndex, - int toIndex, List results) { - boolean decreasing = toIndex < fromIndex; - for (int i = fromIndex; decreasing ? i >= toIndex : i <= toIndex;) { - addSubBranch(branch, i, results); - if (decreasing) { - i--; - } else { - i++; - } - } - } - - protected void addSubBranch(IBranchPart branch, int index, - List results) { - if (index < 0 || index >= branch.getSubBranches().size()) - return; - results.add(branch.getSubBranches().get(index)); - } - - protected IBranchPart getSubBranch(IBranchPart branch, int index) { - if (index >= 0 && index < branch.getSubBranches().size()) { - return branch.getSubBranches().get(index); - } - return null; - } - - protected ITopicPart getSubTopicPart(IBranchPart branch, int index) { - IBranchPart subBranch = getSubBranch(branch, index); - if (subBranch != null) - return subBranch.getTopicPart(); - return null; - } - - protected IInsertion getCurrentInsertion(IBranchPart branch) { - return (IInsertion) MindMapUtils.getCache(branch, - IInsertion.CACHE_INSERTION); - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - return 0; - } - - protected Point getChildRef(IBranchPart branch, Point branchRef, - ParentSearchKey key) { - return key.getCursorPos(); - } - - public Point calcInsertionPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - if (child == null) - return calcInsertPosition(branch, child, key); - - if (getOldIndex(branch, child) == -1) { - return calcInsertPosition(branch, child, key); - } else { - return calcMovePosition(branch, child, key); - } - } - - public boolean isBranchMoved(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - int index = calcInsIndex(branch, key, true); - List disables = getDisableBranches(branch); - - return !(disables != null - && (disables.contains(index) || disables.contains(index - 1))); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - return -1; - } - - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - int index = calcInsIndex(branch, key, true); - - int minorSpacing = getMinorSpacing(branch); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - List boundaries = branch.getBoundaries(); - - if (index == 0) { - IBranchPart sub = subBranches.get(0); - Rectangle bounds = sub.getFigure().getBounds(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - Rectangle bBounds = boundary.getFigure().getBounds(); - List enclosingBranches = boundary - .getEnclosingBranches(); - if ((!enclosingBranches.isEmpty()) - && sub.equals(enclosingBranches.get(0))) - bounds = bBounds.contains(bounds) ? bBounds : bounds; - } - } - - int x; - if (key.getCursorPos().x > 0) - x = bounds.x + inventSize.width / 2; - else - x = bounds.right() - inventSize.width / 2; - int y = bounds.y - minorSpacing - insSize.height / 2; - - return new Point(x, y); - } - - if (index == subBranches.size()) { - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getFigure().getBounds(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - Rectangle bBounds = boundary.getFigure().getBounds(); - List enclosingBranches = boundary - .getEnclosingBranches(); - if ((!enclosingBranches.isEmpty()) - && sub.equals(enclosingBranches - .get(enclosingBranches.size() - 1))) - bounds = bBounds.contains(bounds) ? bBounds : bounds; - } - } - - int x; - if (key.getCursorPos().x > 0) - x = bounds.x + inventSize.width / 2; - else - x = bounds.right() - inventSize.width / 2; - int y = bounds.bottom() + minorSpacing + insSize.height / 2; - - return new Point(x, y); - } - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index), key, key.getCursorPos().x > 0); - - } - - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - Dimension inventSize = key.getInvent().getSize(); - - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - int delta = getTopicSize(sub).width / 2 - inventSize.width / 2; - return getFigureLocation(sub.getFigure()).getTranslated( - key.getCursorPos().x < 0 ? delta : -delta, 0); - } - - return calcInsertPosition(branch, child, key); - } - - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int x = getTopicSize(branch).width / 2 + getMajorSpacing(branch) - + key.getInvent().getSize().width / 2; - return getFigureLocation(branch.getFigure()) - .getTranslated(key.getCursorPos().x < 0 ? -x : x, 0); - } - - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { - int minorSpacing = getMinorSpacing(orientation.getParentBranch()); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - Rectangle oriBounds = orientation.getFigure().getBounds(); - Rectangle assBounds = assist.getFigure().getBounds(); - - Rectangle uBounds = oriBounds; - Rectangle dBounds = assBounds; - - List boundaries = orientation.getParentBranch() - .getBoundaries(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - List enclosingBranches = boundary - .getEnclosingBranches(); - Rectangle bBounds = boundary.getFigure().getBounds(); - - if ((!enclosingBranches.isEmpty()) && orientation.equals( - enclosingBranches.get(enclosingBranches.size() - 1))) - uBounds = bBounds.contains(uBounds) ? bBounds : uBounds; - - if ((!enclosingBranches.isEmpty()) - && assist.equals(enclosingBranches.get(0))) - dBounds = bBounds.contains(dBounds) ? bBounds : dBounds; - } - } - - boolean isBefourBounds; - Rectangle bounds; - if (uBounds.equals(oriBounds)) { - bounds = uBounds; - isBefourBounds = false; - } else if (dBounds.equals(assBounds)) { - bounds = dBounds; - isBefourBounds = true; - } else { - if (isRightOrUp) { - if (uBounds.x > dBounds.x) { - bounds = uBounds; - isBefourBounds = false; - } else { - bounds = dBounds; - isBefourBounds = true; - } - } else { - if (uBounds.right() < dBounds.right()) { - bounds = uBounds; - isBefourBounds = false; - } else { - bounds = dBounds; - isBefourBounds = true; - } - } - } - - int x; - if (isRightOrUp) - x = bounds.x + inventSize.width / 2; - else - x = bounds.right() - inventSize.width / 2; - - int y; - if (isBefourBounds) - y = bounds.y - minorSpacing - insSize.height / 2; - else - y = bounds.bottom() + minorSpacing + insSize.height / 2; - - return new Point(x, y); - } - - protected int getOldIndex(IBranchPart branch, IBranchPart child) { - List subBranches = branch.getSubBranches(); - - if (branch.equals(child.getParentBranch())) - return child.getBranchIndex(); - - for (IBranchPart sub : subBranches) { - if (!sub.getFigure().isEnabled()) - return sub.getBranchIndex(); - } - - return -1; - } - - protected Point getFigureLocation(IFigure figure) { - if (figure instanceof IReferencedFigure) - return ((IReferencedFigure) figure).getReference(); - else - return figure.getBounds().getLocation(); - } - - protected Dimension getTopicSize(IBranchPart branch) { - if (branch == null) - return new Dimension(); - return branch.getTopicPart().getFigure().getSize(); - } - - protected List getDisableBranches(IBranchPart branch) { - List subBranches = branch.getSubBranches(); - List disables = null; - - for (int i = 0; i < subBranches.size(); i++) { - IBranchPart sub = subBranches.get(i); - if (!sub.getFigure().isEnabled()) { - if (disables == null) - disables = new ArrayList(); - disables.add(i); - } - } - return disables; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import static org.xmind.ui.style.StyleUtils.getInteger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IDecoratedFigure; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.IRotatableFigure; +import org.xmind.gef.draw2d.ReferencedLayoutData; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.BoundaryLayoutHelper.BoundaryData; +import org.xmind.ui.decorations.IBranchConnectionDecoration; +import org.xmind.ui.decorations.IBranchConnections2; +import org.xmind.ui.decorations.ISummaryDecoration; +import org.xmind.ui.decorations.ITopicDecoration; +import org.xmind.ui.internal.figures.BoundaryFigure; +import org.xmind.ui.internal.figures.BranchFigure; +import org.xmind.ui.internal.figures.TopicFigure; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IInfoPart; +import org.xmind.ui.mindmap.ILabelPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.tools.ParentSearchKey; +import org.xmind.ui.util.MindMapUtils; + +public abstract class AbstractBranchStructure implements IBranchStructure, + IBranchStructureExtension, INavigableBranchStructureExtension, + IInsertableBranchStructureExtension { + + protected static final String CACHE_STRUCTURE_DATA = "org.xmind.ui.branchCache.structureData"; //$NON-NLS-1$ + + protected static final String CACHE_BOUNDARY_LAYOUT_HELPER = "org.xmind.ui.branchCache.boundaryLayoutHelper"; //$NON-NLS-1$ + + protected static class LayoutInfo extends ReferencedLayoutData { + + private ReferencedLayoutData delegate; + + private boolean folded; + + private boolean minimized; + + private Rectangle minArea; + + private boolean hasBoundaryTitles; + + public LayoutInfo(ReferencedLayoutData delegate, boolean folded, + boolean minimized) { + this.delegate = delegate; + this.folded = folded; + this.minimized = minimized; + this.minArea = null; + this.hasBoundaryTitles = false; + } + + public boolean isFolded() { + return folded; + } + + public boolean isMinimized() { + return minimized; + } + + public Rectangle getMinArea() { + return minArea; + } + + public void setMinArea(Rectangle minArea) { + this.minArea = minArea; + } + + public void putMinArea(IFigure figure) { + if (minArea == null) { + delegate.put(figure, delegate.createInitBounds()); + } else { + delegate.put(figure, minArea.getCopy()); + } + } + + public void add(Rectangle blankArea) { + delegate.add(blankArea); + } + + public void addMargins(Insets margin) { + delegate.addMargins(margin); + } + + public void addMargins(int top, int left, int bottom, int right) { + delegate.addMargins(top, left, bottom, right); + } + + public Rectangle createInitBounds() { + return delegate.createInitBounds(); + } + + public Rectangle createInitBounds(Point ref) { + return delegate.createInitBounds(ref); + } + + public Rectangle get(Object figure) { + return delegate.get(figure); + } + + public Rectangle getCheckedClientArea() { + return delegate.getCheckedClientArea(); + } + + public Rectangle getClientArea() { + return delegate.getClientArea(); + } + + public Point getReference() { + return delegate.getReference(); + } + + public void put(IFigure figure, Rectangle preferredBounds) { + delegate.put(figure, preferredBounds); + } + + public void translate(int dx, int dy) { + delegate.translate(dx, dy); + } + + } + + public void fillLayoutData(IBranchPart branch, ReferencedLayoutData data) { + BranchFigure figure = (BranchFigure) branch.getFigure(); + boolean folded = figure.isFolded(); + boolean minimized = figure.isMinimized(); + LayoutInfo info = new LayoutInfo(data, folded, minimized); + fillLayoutInfo(branch, info); + } + + protected void fillLayoutInfo(IBranchPart branch, LayoutInfo info) { + IStyleSelector styleSelector = branch.getBranchPolicy() + .getStyleSelector(branch); + if (styleSelector != null) { + String hideCallout = styleSelector.getStyleValue(branch, + Styles.HideCallout); + if (Boolean.parseBoolean(hideCallout) && MindMapUI.BRANCH_CALLOUT + .equals(branch.getBranchType())) { + branch.getFigure().setVisible(false); + return; + } + } +// if ("org.xmind.ui.spreadsheet".equals(branch.getBranchPolicyId()) //$NON-NLS-1$ +// && MindMapUI.BRANCH_CALLOUT.equals(branch.getBranchType())) { +// branch.getFigure().setVisible(false); +// return; +// } + + fillTopic(branch, info); + fillPlusMinus(branch, info); + fillLabel(branch, info); + fillInformation(branch, info); + + List subBranches = branch.getSubBranches(); + List boundaries = branch.getBoundaries(); + + BoundaryLayoutHelper boundaryLayoutHelper = getBoundaryLayoutHelper( + branch); + +// boundaryLayoutHelper.reset(branch, this, null); + info.hasBoundaryTitles = false; + + ReferencedLayoutData fakeDelegate = info.delegate.copy(); + ReferencedLayoutData realDelegate = info.delegate; + info.delegate = fakeDelegate; + + fillSubBranches(branch, subBranches, info); + fillBoundaries(branch, boundaries, subBranches, info); + info.delegate = realDelegate; + + if (info.hasBoundaryTitles) { + Map cachedBounds = new HashMap(); + for (IBoundaryPart boundary : branch.getBoundaries()) { + cachedBounds.put(boundary.getFigure(), + fakeDelegate.get(boundary.getFigure())); + } + boundaryLayoutHelper.reset(branch, this, cachedBounds); + fillSubBranches(branch, subBranches, info); + fillBoundaries(branch, boundaries, subBranches, info); + } else { + for (IBranchPart subBranch : branch.getSubBranches()) { + info.delegate.put(subBranch.getFigure(), + fakeDelegate.get(subBranch.getFigure())); + } + for (IBoundaryPart boundary : branch.getBoundaries()) { + info.delegate.put(boundary.getFigure(), + fakeDelegate.get(boundary.getFigure())); + } + } + + List calloutBranches = branch.getCalloutBranches(); + fillCalloutBranches(branch, calloutBranches, info); + + List summaries = branch.getSummaries(); + List summaryBranches = new ArrayList( + branch.getSummaryBranches()); + fillSummaries(branch, summaries, summaryBranches, subBranches, info); + fillUnhandledSummaryBranches(branch, summaryBranches, info); + + addExtraSpaces(branch, info); + + boundaryLayoutHelper.reset(branch, this, null); + info.hasBoundaryTitles = false; + + fakeDelegate = info.delegate.copy(); + realDelegate = info.delegate; + info.delegate = fakeDelegate; + info.hasBoundaryTitles = false; + fillOverallBoundary(branch, boundaries, info); + info.delegate = realDelegate; + if (info.hasBoundaryTitles) { + Map cachedBounds = new HashMap(); + for (IBoundaryPart boundary : branch.getBoundaries()) { + cachedBounds.put(boundary.getFigure(), + fakeDelegate.get(boundary.getFigure())); + } + boundaryLayoutHelper.setOverallBoundary(null); + boundaryLayoutHelper.reset(branch, this, cachedBounds); + fillOverallBoundary(branch, boundaries, info); + } else { + for (IBranchPart subBranch : branch.getSubBranches()) { + info.delegate.put(subBranch.getFigure(), + fakeDelegate.get(subBranch.getFigure())); + } + for (IBoundaryPart boundary : branch.getBoundaries()) { + info.delegate.put(boundary.getFigure(), + fakeDelegate.get(boundary.getFigure())); + } + } + + } + + protected void fillCalloutBranches(IBranchPart branch, + List calloutBranches, LayoutInfo info) { + if (calloutBranches.isEmpty()) + return; + + IStyleSelector styleSelector = branch.getBranchPolicy() + .getStyleSelector(branch); + if (styleSelector != null) { + String hideCallout = styleSelector.getStyleValue(branch, + Styles.HideCallout); + if (Boolean.parseBoolean(hideCallout)) { + for (IBranchPart calloutBranch : calloutBranches) { + calloutBranch.getFigure().setVisible(false); + } + IBranchConnections2 calloutConnections = branch + .getCalloutConnections(); + for (int index = 0; index < calloutBranches.size(); index++) { + IDecoration decoration = calloutConnections + .getDecoration(index); + if (decoration instanceof IBranchConnectionDecoration) { + ((IBranchConnectionDecoration) decoration) + .setVisible(branch.getFigure(), false); + } + } + return; + } + } + + if ((info.isFolded() || info.isMinimized()) + && minimizesSubBranchesToOnePoint()) { + if (info.isFolded() && !info.isMinimized()) { + info.setMinArea(info.createInitBounds(calcSubBranchesMinPoint( + branch, calloutBranches, info))); + } + for (IBranchPart calloutBranch : calloutBranches) { + info.putMinArea(calloutBranch.getFigure()); + } + } else { + doFillCalloutBranches(branch, calloutBranches, info); + for (IBranchPart calloutBranch : calloutBranches) { + IFigure calloutBranchFigure = calloutBranch.getFigure(); + if (info.get(calloutBranchFigure) == null) { + info.putMinArea(calloutBranchFigure); + } + } + } + } + + protected void doFillCalloutBranches(IBranchPart branch, + List calloutBranches, LayoutInfo info) { + if (branch.isCentral()) { + for (IBranchPart calloutBranch : calloutBranches) { + calloutBranch.getFigure().setVisible(false); + } + IBranchConnections2 calloutConnections = branch + .getCalloutConnections(); + for (int index = 0; index < calloutBranches.size(); index++) { + IDecoration decoration = calloutConnections + .getDecoration(index); + if (decoration instanceof IBranchConnectionDecoration) { + ((IBranchConnectionDecoration) decoration) + .setVisible(branch.getFigure(), false); + } + } + return; + } + + IBranchPart parentBranch = branch.getParentBranch(); + int orientation = getChildTargetOrientation(parentBranch, branch); + boolean left = PositionConstants.EAST == orientation; + boolean right = PositionConstants.WEST == orientation; + boolean south = PositionConstants.NORTH == orientation; + boolean north = PositionConstants.SOUTH == orientation; + + for (IBranchPart calloutBranch : calloutBranches) { + //changed + Rectangle parentTopicArea = info + .get(branch.getTopicPart().getFigure()); + Rectangle parentBranchArea = info.getCheckedClientArea(); + + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + ITopicPart calloutTopicPart = calloutBranch.getTopicPart(); + if (calloutTopicPart == null) + continue; + IFigure calloutFigure = calloutTopicPart.getFigure(); + Dimension calloutSize = calloutFigure.getPreferredSize(); + + //over parent topic center + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + int offsetX = originPosition ? 0 : position.x; + int offsetY = originPosition + ? -calloutSize.height / 2 - parentTopicArea.height / 2 - 10 + : position.y; + + boolean upDown = offsetY < 0; + + int dummyCalloutX = parentTopicArea.getCenter().x + offsetX + - calloutSize.width / 2; + + if (left) { + //limit left movable boundary + int dx = (dummyCalloutX + calloutSize.width) + - (parentTopicArea.x + parentTopicArea.width); + offsetX = dx > 0 ? offsetX - dx : offsetX; + } else if (right) { + //limit right movable boundary + int dx = dummyCalloutX - parentTopicArea.x; + offsetX = dx < 0 ? offsetX - dx : offsetX; + } + + Point reference = info.getReference(); + Point translated = reference.getTranslated(offsetX, offsetY); + Rectangle bounds = calloutBranchFigure + .getPreferredBounds(translated); + + int subRectX = left || south || north ? parentBranchArea.x + : parentBranchArea.x + parentTopicArea.width; + int subRectY = left || right || north ? parentBranchArea.y + : parentBranchArea.y + parentTopicArea.height; + int subRectWidth = left || right + ? parentBranchArea.width - parentTopicArea.width + : parentBranchArea.width; + int subRectHeight = left || right ? parentBranchArea.height + : parentBranchArea.height - parentTopicArea.height; + Rectangle subRect = new Rectangle(subRectX, subRectY, subRectWidth, + subRectHeight); + boolean touchSub = subRect.touches(bounds); + boolean touchParentTopic = bounds.touches(parentTopicArea); + if (touchSub) { + int y = upDown ? subRect.y - bounds.height - 10 + : subRect.bottom() + 10; + bounds.setY(y); + } else if (touchParentTopic) { + int y = upDown ? parentTopicArea.y - bounds.height - 10 + : parentTopicArea.bottom() + 10; + bounds.setY(y); + } + info.put(calloutBranchFigure, bounds); + } + } + + protected void fillTopic(IBranchPart branch, LayoutInfo info) { + ITopicPart topic = branch.getTopicPart(); + if (topic != null) { + if (info.isMinimized()) { + info.putMinArea(topic.getFigure()); + } else { + doFillTopic(branch, topic, info); + } + } + } + + protected void doFillTopic(IBranchPart branch, ITopicPart topicPart, + LayoutInfo info) { + IFigure fig = topicPart.getFigure(); + if (fig instanceof IReferencedFigure) { + IReferencedFigure refFig = (IReferencedFigure) fig; + Rectangle bounds = refFig.getPreferredBounds(info.getReference()); + info.put(refFig, bounds); + } else { + Dimension size = fig.getPreferredSize(); + Point ref = info.getReference(); + Rectangle r = new Rectangle(ref.x - size.width / 2, + ref.y - size.height / 2, size.width, size.height); + info.put(fig, r); + } + } + + protected void fillPlusMinus(IBranchPart branch, LayoutInfo info) { + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + IFigure pmFigure = plusMinus.getFigure(); + if (info.isMinimized()) { + info.putMinArea(pmFigure); + } else { + doFillPlusMinus(branch, plusMinus, info); + if (info.get(pmFigure) == null) { + info.putMinArea(pmFigure); + } + } + } + } + + protected abstract void doFillPlusMinus(IBranchPart branch, + IPlusMinusPart plusMinus, LayoutInfo info); + + protected void fillLabel(IBranchPart branch, LayoutInfo info) { + ILabelPart label = branch.getLabel(); + if (label != null) { + if (info.isMinimized() || !label.getFigure().isVisible()) { + info.putMinArea(label.getFigure()); + } else { + doFillLabel(branch, label, info); + } + } + } + + protected void doFillLabel(IBranchPart branch, ILabelPart label, + LayoutInfo info) { + IFigure figure = label.getFigure(); + ITopicPart topicPart = branch.getTopicPart(); + Rectangle area; + if (topicPart != null) { + area = info.get(topicPart.getFigure()); + } else { + area = info.createInitBounds(); + } + if (figure instanceof IRotatableFigure) { + IRotatableFigure f = (IRotatableFigure) figure; + double angle = f.getRotationDegrees(); + if (!Geometry.isSameAngleDegree(angle, 0, 0.00001)) { + Point ref = info.getReference(); + PrecisionRotator r = new PrecisionRotator(); + r.setOrigin(ref.x, ref.y); + r.setAngle(angle); + PrecisionRectangle rect = r.r(new PrecisionRectangle(area)); + PrecisionDimension size = f.getNormalPreferredSize(-1, -1); + rect.x += (rect.width - size.width) / 2; + rect.y = rect.bottom() - 2; + rect.width = size.width; + rect.height = size.height; + r.t(rect); + info.put(figure, rect.toDraw2DRectangle()); + return; + } + } + Dimension size = figure.getPreferredSize(); + Rectangle r = new Rectangle(area.x + (area.width - size.width) / 2, + area.bottom() - 2, size.width, size.height); + info.put(figure, r); + } + + protected void fillInformation(IBranchPart branch, LayoutInfo info) { + IInfoPart information = branch.getInfoPart(); + if (information != null) { + if (info.isMinimized() || !information.getFigure().isVisible()) { + info.putMinArea(information.getFigure()); + } else { + doFillInfomation(branch, information, info); + } + } + } + + protected void doFillInfomation(IBranchPart branch, IInfoPart information, + LayoutInfo info) { + IFigure figure = information.getFigure(); + ITopicPart topicPart = branch.getTopicPart(); + Rectangle area; + if (topicPart != null) { + area = info.get(topicPart.getFigure()); + } else { + area = info.createInitBounds(); + } + + Dimension size = figure.getPreferredSize(); + + TopicFigure tf = (TopicFigure) topicPart.getFigure(); + ITopicDecoration decoration = tf.getDecoration(); + String shapeId = decoration.getId(); + int x; + if (Styles.TOPIC_SHAPE_ROUNDEDRECT.equals(shapeId) + || Styles.TOPIC_SHAPE_RECT.equals(shapeId) + || Styles.TOPIC_SHAPE_UNDERLINE.equals(shapeId)) + x = area.x; + else + x = area.x + (area.width - size.width) / 2; + + int y = area.bottom() - 1; + if (!Styles.TOPIC_SHAPE_UNDERLINE.equals(shapeId)) + y -= 1; + + Rectangle r = new Rectangle(x, y, size.width, size.height); + info.put(figure, r); + } + + protected void fillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + if (subBranches.isEmpty()) + return; + if ((info.isFolded() || info.isMinimized()) + && minimizesSubBranchesToOnePoint()) { + if (info.isFolded() && !info.isMinimized()) { + info.setMinArea(info.createInitBounds( + calcSubBranchesMinPoint(branch, subBranches, info))); + } + for (IBranchPart subBranch : subBranches) { + info.putMinArea(subBranch.getFigure()); + } + } else { + doFillSubBranches(branch, subBranches, info); + for (IBranchPart subBranch : subBranches) { + IFigure subBranchFigure = subBranch.getFigure(); + if (info.get(subBranchFigure) == null) { + info.putMinArea(subBranchFigure); + } + } + } + } + + protected abstract void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info); + + protected boolean minimizesSubBranchesToOnePoint() { + return true; + } + + protected Point calcSubBranchesMinPoint(IBranchPart branch, + List subBranches, LayoutInfo info) { + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + Rectangle pmBounds = info.get(plusMinus.getFigure()); + if (pmBounds != null) { + return pmBounds.getCenter(); + } + } + return info.getReference(); + } + + protected void fillBoundaries(IBranchPart branch, + List boundaries, List subBranches, + LayoutInfo info) { + + if (boundaries.isEmpty()) + return; + if (subBranches.isEmpty() || ((info.isFolded() || info.isMinimized()) + && minimizesSubBranchesToOnePoint())) { + for (IBoundaryPart b : boundaries) { + info.putMinArea(b.getFigure()); + } + } else { + doFillBoundaries(branch, boundaries, info); + } + } + + protected void doFillBoundaries(IBranchPart branch, + List boundaries, LayoutInfo info) { + + for (IBoundaryPart boundary : boundaries) { + doFillBoundary(branch, boundary, info); + } + } + + protected void doFillBoundary(IBranchPart branch, IBoundaryPart boundary, + LayoutInfo info) { + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + BoundaryData boundaryData = helper.getBoundaryData(boundary); + + if (boundary.getFigure() != null + && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() + && boundary.getTitle() != null) { + info.hasBoundaryTitles = true; + } + + if (boundaryData.isOverall()) { + if (boundaryData != helper.getOverallBoundary()) { + info.putMinArea(boundary.getFigure()); + } + return; + } + Rectangle area = null; + for (IBranchPart subBranch : boundaryData.getSubBranches()) { + Insets ins = helper.getInnerInsets( + helper.getSubBranchData(subBranch), boundaryData); + Rectangle r2 = info.get(subBranch.getFigure()); + area = Geometry.union(area, r2.getExpanded(ins)); + } + if (area == null) { + info.putMinArea(boundary.getFigure()); + } else { + area = boundaryData.expanded(area); + info.put(boundary.getFigure(), area); + } + } + + protected void fillSummaries(IBranchPart branch, + List summaries, List summaryBranches, + List subBranches, LayoutInfo info) { + if (!summaries.isEmpty()) { + if (subBranches.isEmpty() + || ((info.isFolded() || info.isMinimized()) + && minimizesSubBranchesToOnePoint())) { + for (ISummaryPart s : summaries) { + info.putMinArea(s.getFigure()); + } + } else { + doFillSummaries(branch, summaries, summaryBranches, info); + } + } + } + + private void doFillSummaries(IBranchPart branch, + List summaries, List summaryBranches, + LayoutInfo info) { + for (ISummaryPart summary : summaries) { + doFillSummary(branch, summary, summaryBranches, info); + } + } + + private void doFillSummary(IBranchPart branch, ISummaryPart summary, + List summaryBranches, LayoutInfo info) { + int direction = getSummaryDirection(branch, summary); + Rectangle area = getSummaryArea(branch, summary, direction, info); + if (area != null) { + info.put(summary.getFigure(), area); + } else { + info.putMinArea(summary.getFigure()); + } + IBranchPart conclusionBranch = getConclusionBranch(branch, summary, + summaryBranches); + if (conclusionBranch != null) { + if (area == null) { + info.putMinArea(conclusionBranch.getFigure()); + } else { + Insets ins = getConclusionReferenceDescription(branch, summary, + conclusionBranch); + int x, y; + switch (direction) { + case PositionConstants.NORTH: + x = area.x + area.width / 2; + y = area.y - ins.bottom; + break; + case PositionConstants.SOUTH: + x = area.x + area.width / 2; + y = area.bottom() + ins.top; + break; + case PositionConstants.WEST: + x = area.x - ins.right; + y = area.y + area.height / 2; + break; + default: + x = area.right() + ins.left; + y = area.y + area.height / 2; + } + info.put(conclusionBranch.getFigure(), + Geometry.getExpanded(x, y, ins)); + } + } + } + + private IBranchPart getConclusionBranch(IBranchPart branch, + ISummaryPart summary, List summaryBranches) { + IGraphicalPart part = summary.getNode(); + if (part instanceof ITopicPart) { + IBranchPart conclusionBranch = ((ITopicPart) part).getOwnerBranch(); + if (conclusionBranch != null + && summaryBranches.contains(conclusionBranch)) { + summaryBranches.remove(conclusionBranch); + return conclusionBranch; + } + } + return null; + } + + private Insets getConclusionReferenceDescription(IBranchPart branch, + ISummaryPart summary, IGraphicalPart conclusion) { + IFigure fig = conclusion.getFigure(); + if (fig instanceof IReferencedFigure) + return ((IReferencedFigure) fig).getReferenceDescription(); + Dimension size = fig.getPreferredSize(); + int w = size.width / 2; + int h = size.height / 2; + return new Insets(h, w, size.height - h, size.width - w); + } + + protected Rectangle getSummaryArea(IBranchPart branch, ISummaryPart summary, + int direction, ReferencedLayoutData data) { + Rectangle r = null; + for (IBranchPart subBranch : summary.getEnclosingBranches()) { + r = Geometry.union(r, data.get(subBranch.getFigure())); + } + if (r == null) + return null; + + Rectangle area = data.createInitBounds(); + int width = getPreferredSummaryWidth(summary); + switch (direction) { + case PositionConstants.NORTH: + area.x = r.x; + area.width = r.width; + area.y = r.y - width; + area.height = width; + break; + case PositionConstants.SOUTH: + area.x = r.x; + area.width = r.width; + area.y = r.bottom(); + area.height = width; + break; + case PositionConstants.WEST: + area.x = r.x - width; + area.width = width; + area.y = r.y; + area.height = r.height; + break; + default: + area.x = r.right(); + area.width = width; + area.y = r.y; + area.height = r.height; + } + IStyleSelector ss = StyleUtils.getStyleSelector(summary); + String shape = StyleUtils.getString(summary, ss, Styles.ShapeClass, + null); + int lineWidth = StyleUtils.getInteger(summary, ss, Styles.LineWidth, + shape, 1); + return area.expand(lineWidth, lineWidth); + } + + private int getPreferredSummaryWidth(ISummaryPart summary) { + IFigure figure = summary.getFigure(); + if (figure instanceof IDecoratedFigure) { + IDecoration decoration = ((IDecoratedFigure) figure) + .getDecoration(); + if (decoration instanceof ISummaryDecoration) { + return ((ISummaryDecoration) decoration) + .getPreferredWidth(figure); + } + } + return Styles.DEFAULT_SUMMARY_WIDTH + + Styles.DEFAULT_SUMMARY_SPACING * 2; + } + + protected void fillUnhandledSummaryBranches(IBranchPart branch, + List summaryBranches, LayoutInfo info) { + if (!summaryBranches.isEmpty()) { + for (IBranchPart summaryBranch : summaryBranches) { + info.putMinArea(summaryBranch.getFigure()); + } + } + } + + protected void addExtraSpaces(IBranchPart branch, + ReferencedLayoutData data) { + // may be subclassed + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + return PositionConstants.EAST; + } + + protected void fillOverallBoundary(IBranchPart branch, + List boundaries, LayoutInfo info) { + if (boundaries.isEmpty()) + return; + IBoundaryPart boundary = branch.getBoundaries() + .get(boundaries.size() - 1); + + if (boundary.getFigure() != null + && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() + && boundary.getTitle() != null) { + info.hasBoundaryTitles = true; + } + + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + BoundaryData overallBoundary = helper.getOverallBoundary(); + if (overallBoundary == null) + return; + + if (info.isMinimized()) { + info.putMinArea(overallBoundary.boundaryFigure); + } else { + Rectangle area = info.getCheckedClientArea(); + area = overallBoundary.expanded(area.getCopy()); + info.put(overallBoundary.boundaryFigure, area); + } + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.SOUTH; + } + + public void invalidate(IGraphicalPart part) { + if (part instanceof IBranchPart) { + invalidateBranch((IBranchPart) part); + } + } + + protected void invalidateBranch(IBranchPart branch) { + MindMapUtils.flushCache(branch, CACHE_STRUCTURE_DATA); + MindMapUtils.flushCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER); + ITopicPart topic = branch.getTopicPart(); + if (topic != null) { + IFigure topicFigure = topic.getFigure(); + if (topicFigure != null) { + topicFigure.invalidate(); + } + } + } + + protected BoundaryLayoutHelper getBoundaryLayoutHelper(IBranchPart branch) { + BoundaryLayoutHelper helper = (BoundaryLayoutHelper) MindMapUtils + .getCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER); + if (helper == null) { + helper = new BoundaryLayoutHelper(); + helper.reset(branch, this, null); + MindMapUtils.setCache(branch, CACHE_BOUNDARY_LAYOUT_HELPER, helper); + } + return helper; + } + + protected Dimension getBorderedSize(IBranchPart branch, + IBranchPart subBranch) { + return getBoundaryLayoutHelper(branch).getBorderedSize(subBranch); + } + + protected int getMinorSpacing(IBranchPart branch) { + return getInteger(branch, + branch.getBranchPolicy().getStyleSelector(branch), + Styles.MinorSpacing, 5); + } + + protected int getMajorSpacing(IBranchPart branch) { + return StyleUtils.getMajorSpacing(branch, 5); + } + + protected Object getStructureData(IBranchPart branch) { + Object data = MindMapUtils.getCache(branch, CACHE_STRUCTURE_DATA); + if (!isValidStructureData(branch, data)) { + data = createStructureData(branch); + if (data != null) { + MindMapUtils.setCache(branch, CACHE_STRUCTURE_DATA, data); + } + } + return data; + } + + protected Object createStructureData(IBranchPart branch) { + return null; + } + + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return data != null; + } + +// public void calculateSubBranchInsets(BoundaryData boundary, +// SubBranchData subBranch, Insets insets) { +// } + + /* + * Subclass may extend this method. + * + * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# + * calcSourceOrientation(org.xmind.ui.parts.IBranchPart) + */ + public int getSourceOrientation(IBranchPart branch) { + return PositionConstants.NONE; + } + + /* + * Subclass may extend this method. + * + * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# + * calcChildTargetOrientation(org.xmind.ui.parts.IBranchPart, + * org.xmind.ui.parts.IBranchPart) + */ + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return PositionConstants.NONE; + } + +// /* +// * Subclass may extend this method. +// * +// * @see org.xmind.ui.graphicalpolicies.IBranchStructure#calcChildTargetOrientation(org.xmind.ui.parts.IBranchPart, +// * org.xmind.gef.draw2d.IReferencedFigure) +// */ +// public int calcChildTargetOrientation(IBranchPart branch, +// IReferencedFigure childFigure) { +// return PositionConstants.NONE; +// } + + /* + * Subclass may extend this method. + * + * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# + * calcChildIndex(org.xmind.ui.tools.ParentSearchKey) + */ + public int calcChildIndex(IBranchPart branch, ParentSearchKey key) { + return calcInsIndex(branch, key, false); + } + + /* + * Subclass may extend this method. + * + * @seeorg.xmind.ui.mindmap.graphicalpolicies.IBranchStructure# + * calcChildDistance(org.xmind.ui.parts.IBranchPart, + * org.xmind.ui.tools.ParentSearchKey) + */ + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + return -1; + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return null; + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + return null; + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_BEGINNING.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } else if (GEF.REQ_NAV_END.equals(navReqType)) { + return getSubTopicPart(branch, branch.getSubBranches().size() - 1); + } + return null; + } + + public void calcSequentialNavigation(IBranchPart branch, + IBranchPart startChild, IBranchPart endChild, + List results) { + addSubBranches(branch, startChild.getBranchIndex(), + endChild.getBranchIndex(), results); + } + + public void calcTraversableBranches(IBranchPart branch, + IBranchPart sourceChild, List results) { + addSubBranch(branch, sourceChild.getBranchIndex() + 1, results); + results.add(branch); + addSubBranch(branch, sourceChild.getBranchIndex() - 1, results); + } + + public void calcTraversableChildren(IBranchPart branch, + List results) { + addSubBranches(branch, 0, branch.getSubBranches().size() - 1, results); + } + + protected void addSubBranches(IBranchPart branch, IBranchPart fromChild, + IBranchPart toChild, List results) { + addSubBranches(branch, branch.getSubBranches().indexOf(fromChild), + branch.getSubBranches().indexOf(toChild), results); + } + + protected void addSubBranches(IBranchPart branch, int fromIndex, + int toIndex, List results) { + boolean decreasing = toIndex < fromIndex; + for (int i = fromIndex; decreasing ? i >= toIndex : i <= toIndex;) { + addSubBranch(branch, i, results); + if (decreasing) { + i--; + } else { + i++; + } + } + } + + protected void addSubBranch(IBranchPart branch, int index, + List results) { + if (index < 0 || index >= branch.getSubBranches().size()) + return; + results.add(branch.getSubBranches().get(index)); + } + + protected IBranchPart getSubBranch(IBranchPart branch, int index) { + if (index >= 0 && index < branch.getSubBranches().size()) { + return branch.getSubBranches().get(index); + } + return null; + } + + protected ITopicPart getSubTopicPart(IBranchPart branch, int index) { + IBranchPart subBranch = getSubBranch(branch, index); + if (subBranch != null) + return subBranch.getTopicPart(); + return null; + } + + protected IInsertion getCurrentInsertion(IBranchPart branch) { + return (IInsertion) MindMapUtils.getCache(branch, + IInsertion.CACHE_INSERTION); + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + return 0; + } + + protected Point getChildRef(IBranchPart branch, Point branchRef, + ParentSearchKey key) { + return key.getCursorPos(); + } + + public Point calcInsertionPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + if (child == null) + return calcInsertPosition(branch, child, key); + + if (getOldIndex(branch, child) == -1) { + return calcInsertPosition(branch, child, key); + } else { + return calcMovePosition(branch, child, key); + } + } + + public boolean isBranchMoved(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + int index = calcInsIndex(branch, key, true); + List disables = getDisableBranches(branch); + + return !(disables != null + && (disables.contains(index) || disables.contains(index - 1))); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + return -1; + } + + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + int index = calcInsIndex(branch, key, true); + + int minorSpacing = getMinorSpacing(branch); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + List boundaries = branch.getBoundaries(); + + if (index == 0) { + IBranchPart sub = subBranches.get(0); + Rectangle bounds = sub.getFigure().getBounds(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + Rectangle bBounds = boundary.getFigure().getBounds(); + List enclosingBranches = boundary + .getEnclosingBranches(); + if ((!enclosingBranches.isEmpty()) + && sub.equals(enclosingBranches.get(0))) + bounds = bBounds.contains(bounds) ? bBounds : bounds; + } + } + + int x; + if (key.getCursorPos().x > 0) + x = bounds.x + inventSize.width / 2; + else + x = bounds.right() - inventSize.width / 2; + int y = bounds.y - minorSpacing - insSize.height / 2; + + return new Point(x, y); + } + + if (index == subBranches.size()) { + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getFigure().getBounds(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + Rectangle bBounds = boundary.getFigure().getBounds(); + List enclosingBranches = boundary + .getEnclosingBranches(); + if ((!enclosingBranches.isEmpty()) + && sub.equals(enclosingBranches + .get(enclosingBranches.size() - 1))) + bounds = bBounds.contains(bounds) ? bBounds : bounds; + } + } + + int x; + if (key.getCursorPos().x > 0) + x = bounds.x + inventSize.width / 2; + else + x = bounds.right() - inventSize.width / 2; + int y = bounds.bottom() + minorSpacing + insSize.height / 2; + + return new Point(x, y); + } + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index), key, key.getCursorPos().x > 0); + + } + + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + Dimension inventSize = key.getInvent().getSize(); + + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + int delta = getTopicSize(sub).width / 2 - inventSize.width / 2; + return getFigureLocation(sub.getFigure()).getTranslated( + key.getCursorPos().x < 0 ? delta : -delta, 0); + } + + return calcInsertPosition(branch, child, key); + } + + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int x = getTopicSize(branch).width / 2 + getMajorSpacing(branch) + + key.getInvent().getSize().width / 2; + return getFigureLocation(branch.getFigure()) + .getTranslated(key.getCursorPos().x < 0 ? -x : x, 0); + } + + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { + int minorSpacing = getMinorSpacing(orientation.getParentBranch()); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + Rectangle oriBounds = orientation.getFigure().getBounds(); + Rectangle assBounds = assist.getFigure().getBounds(); + + Rectangle uBounds = oriBounds; + Rectangle dBounds = assBounds; + + List boundaries = orientation.getParentBranch() + .getBoundaries(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + List enclosingBranches = boundary + .getEnclosingBranches(); + Rectangle bBounds = boundary.getFigure().getBounds(); + + if ((!enclosingBranches.isEmpty()) && orientation.equals( + enclosingBranches.get(enclosingBranches.size() - 1))) + uBounds = bBounds.contains(uBounds) ? bBounds : uBounds; + + if ((!enclosingBranches.isEmpty()) + && assist.equals(enclosingBranches.get(0))) + dBounds = bBounds.contains(dBounds) ? bBounds : dBounds; + } + } + + boolean isBefourBounds; + Rectangle bounds; + if (uBounds.equals(oriBounds)) { + bounds = uBounds; + isBefourBounds = false; + } else if (dBounds.equals(assBounds)) { + bounds = dBounds; + isBefourBounds = true; + } else { + if (isRightOrUp) { + if (uBounds.x > dBounds.x) { + bounds = uBounds; + isBefourBounds = false; + } else { + bounds = dBounds; + isBefourBounds = true; + } + } else { + if (uBounds.right() < dBounds.right()) { + bounds = uBounds; + isBefourBounds = false; + } else { + bounds = dBounds; + isBefourBounds = true; + } + } + } + + int x; + if (isRightOrUp) + x = bounds.x + inventSize.width / 2; + else + x = bounds.right() - inventSize.width / 2; + + int y; + if (isBefourBounds) + y = bounds.y - minorSpacing - insSize.height / 2; + else + y = bounds.bottom() + minorSpacing + insSize.height / 2; + + return new Point(x, y); + } + + protected int getOldIndex(IBranchPart branch, IBranchPart child) { + List subBranches = branch.getSubBranches(); + + if (branch.equals(child.getParentBranch())) + return child.getBranchIndex(); + + for (IBranchPart sub : subBranches) { + if (!sub.getFigure().isEnabled()) + return sub.getBranchIndex(); + } + + return -1; + } + + protected Point getFigureLocation(IFigure figure) { + if (figure instanceof IReferencedFigure) + return ((IReferencedFigure) figure).getReference(); + else + return figure.getBounds().getLocation(); + } + + protected Dimension getTopicSize(IBranchPart branch) { + if (branch == null) + return new Dimension(); + return branch.getTopicPart().getFigure().getSize(); + } + + protected List getDisableBranches(IBranchPart branch) { + List subBranches = branch.getSubBranches(); + List disables = null; + + for (int i = 0; i < subBranches.size(); i++) { + IBranchPart sub = subBranches.get(i); + if (!sub.getFigure().isEnabled()) { + if (disables == null) + disables = new ArrayList(); + disables.add(i); + } + } + return disables; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BoundaryLayoutHelper.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BoundaryLayoutHelper.java index 0f5fdf5e7..cd97382d3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BoundaryLayoutHelper.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BoundaryLayoutHelper.java @@ -1,398 +1,398 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.xmind.gef.draw2d.ReferencedLayoutData; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.ui.internal.figures.BoundaryFigure; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; - -public class BoundaryLayoutHelper { - - public static interface ISubBranchInsetsCalculator { - - void calculateSubBranchInsets(BoundaryData boundary, - SubBranchData subBranch, Insets insets); - } - - public static class BoundaryData implements Comparable { - - public IBoundaryPart boundary; - - public IFigure boundaryFigure; - - private Insets prefInsets; - - private List subBranches; - - private Map branchBorders = new HashMap(); - - private int startIndex = -1; - - private int endIndex = -1; - - private int direction; - - private boolean overall; - - public BoundaryData(IBoundaryPart boundary, int direction, - Rectangle prefBoundaryBounds) { - this.boundary = boundary; - this.boundaryFigure = boundary.getFigure(); - this.prefInsets = boundaryFigure.getInsets(); - - if (prefBoundaryBounds != null - && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() - && boundary.getTitle() != null - && boundary.getTitle().getFigure() != null) { - Dimension s = boundary.getTitle().getFigure().getPreferredSize( - prefBoundaryBounds.width, SWT.DEFAULT); - this.prefInsets = new Insets(this.prefInsets); - this.prefInsets.top = Math.max(s.height, this.prefInsets.top); - - this.prefInsets.left += 5; - } -// System.out.println("PrefInsets: " + this.prefInsets); - -// if (boundaryFigure instanceof ITitledFigure) { -// ITextFigure title = ((ITitledFigure) boundaryFigure).getTitle(); -// if (boundary.getBoundary().hasTitle()) { -// Dimension s = title.getPreferredSize(); -// prefInsets.top = Math.max(s.height, prefInsets.top); -// } -// } - this.subBranches = boundary.getEnclosingBranches(); - this.direction = direction; - this.overall = boundary.getBoundary().isMasterBoundary(); - } - - public boolean isOverall() { - return overall; - } - - public int getDirection() { - return direction; - } - - public Insets createInsets() { - return new Insets(prefInsets); - } - - public Rectangle expanded(Rectangle rect) { - return rect.expand(prefInsets); - } - - public List getSubBranches() { - return subBranches; - } - - public void setSubBranchInsets(IBranchPart subBranch, Insets ins) { - branchBorders.put(subBranch, ins); - } - - public Insets getSubBranchInsets(IBranchPart subBranch) { - return branchBorders.get(subBranch); - } - - public boolean isEmpty() { - return subBranches.isEmpty(); - } - - public IBranchPart getFirst() { - return isEmpty() ? null : subBranches.get(0); - } - - public IBranchPart getLast() { - return isEmpty() ? null : subBranches.get(subBranches.size() - 1); - } - - public boolean isFirst(SubBranchData subBranch) { - return isFirst(subBranch.subBranch); - } - - public boolean isLast(SubBranchData subBranch) { - return isLast(subBranch.subBranch); - } - - public boolean isFirst(IBranchPart subBranch) { - return subBranch == getFirst(); - } - - public boolean isLast(IBranchPart subBranch) { - return subBranch == getLast(); - } - - public boolean contains(BoundaryData another) { - return subBranches.containsAll(another.subBranches); - } - - public boolean contains(IBranchPart subBranch) { - return subBranches.contains(subBranch); - } - - public boolean contains(SubBranchData subBranch) { - return contains(subBranch.subBranch); - } - - public int getStartIndex() { - if (startIndex < 0 && !isEmpty()) { - startIndex = getFirst().getBranchIndex(); - } - return startIndex; - } - - public int getEndIndex() { - if (endIndex < 0 && !isEmpty()) { - endIndex = getLast().getBranchIndex(); - } - return endIndex; - } - - public int compareTo(BoundaryData that) { - if (this.isOverall()) - return 100; - if (that.isOverall()) - return -100; - if (this.contains(that)) - return 10; - if (that.contains(this)) - return -10; - if (this.isEmpty()) - return -100; - if (that.isEmpty()) - return 100; - return this.getStartIndex() - that.getStartIndex(); - } - } - - public static class SubBranchData { - - public IBranchPart subBranch; - - public List boundaries = new ArrayList(); - - private Insets insets = null; - - public SubBranchData(IBranchPart subBranch, - BoundaryData[] allBoundaries) { - this.subBranch = subBranch; - for (BoundaryData b : allBoundaries) { - if (b.contains(subBranch)) { - boundaries.add(b); - } - } - } - - public boolean isEmpty() { - return boundaries.isEmpty(); - } - - public Insets getInsets() { - if (insets == null) { - insets = calcInnerInsets(null); - } - return insets; - } - - public Insets calcInnerInsets(BoundaryData boundary) { - Insets insets = null; - BoundaryData last = null; - Insets lastLevelIns = null; - for (BoundaryData b : boundaries) { - if (last != null && boundary != null - && !boundary.contains(last)) { - lastLevelIns = null; - break; - } - - if (b == boundary) - break; - - if (last != null && b.contains(last)) { - insets = Geometry.add(insets, lastLevelIns); - lastLevelIns = null; - } - - last = b; - Insets ins = b.getSubBranchInsets(subBranch); - lastLevelIns = Geometry.union(lastLevelIns, ins); - } - if (lastLevelIns != null) - insets = Geometry.add(insets, lastLevelIns); - return insets == null ? IFigure.NO_INSETS : insets; - } - - } - - private Map boundaries = new HashMap(); - - private Map subBranches = new HashMap(); - - private BoundaryData overallBoundary = null; - - public BoundaryLayoutHelper() { - } - - public void reset(IBranchPart branch, IBranchStructureExtension algorithm, - Map prefBounds) { - boundaries.clear(); - subBranches.clear(); - - for (IBoundaryPart boundary : branch.getBoundaries()) { - BoundaryData boundaryData = new BoundaryData(boundary, - algorithm.getRangeGrowthDirection(branch, boundary), - prefBounds == null ? null - : prefBounds.get(boundary.getFigure())); - boundaries.put(boundary, boundaryData); -// if (boundaryData.isOverall() -// && (overallBoundary == null || MindMapUI.BRANCH_FLOATING -// .equals(branch.getBranchType()))) { -// overallBoundary = boundaryData; -// } - if (boundaryData.isOverall() && getOverallBoundary() == null) { - setOverallBoundary(boundaryData); - } - } - if (!isEmpty()) { - BoundaryData[] allBoundaries = boundaries.values() - .toArray(new BoundaryData[0]); - Arrays.sort(allBoundaries); - for (IBranchPart subBranch : branch.getSubBranches()) { - SubBranchData data = new SubBranchData(subBranch, - allBoundaries); - if (!data.isEmpty()) { - subBranches.put(subBranch, data); - } - } - } - for (IBoundaryPart b : branch.getBoundaries()) { - BoundaryData boundary = getBoundaryData(b); - for (IBranchPart s : boundary.subBranches) { - SubBranchData subBranch = getSubBranchData(s); - boundary.setSubBranchInsets(subBranch.subBranch, - createSubBranchInsets(boundary, subBranch)); - } - } - } - - public BoundaryData getOverallBoundary() { - return overallBoundary; - } - - protected Insets createSubBranchInsets(BoundaryData boundary, - SubBranchData subBranch) { - Insets ins = boundary.createInsets(); - switch (boundary.getDirection()) { - case PositionConstants.EAST: - if (!boundary.isFirst(subBranch)) { - ins.left = 0; - } - if (!boundary.isLast(subBranch)) { - ins.right = 0; - } - break; - case PositionConstants.WEST: - if (!boundary.isFirst(subBranch)) { - ins.right = 0; - } - if (!boundary.isLast(subBranch)) { - ins.left = 0; - } - break; - case PositionConstants.SOUTH: - if (!boundary.isFirst(subBranch)) { - ins.top = 0; - } - if (!boundary.isLast(subBranch)) { - ins.bottom = 0; - } - break; - case PositionConstants.NORTH: - if (!boundary.isFirst(subBranch)) { - ins.bottom = 0; - } - if (!boundary.isLast(subBranch)) { - ins.top = 0; - } - break; - } - - return ins; - } - - public boolean isEmpty() { - return boundaries.isEmpty(); - } - - public boolean hasSubBranch(IBranchPart subBranch) { - return subBranches.containsKey(subBranch); - } - - public SubBranchData getSubBranchData(IBranchPart subBranch) { - return subBranches.get(subBranch); - } - - public BoundaryData getBoundaryData(IBoundaryPart boundary) { - return boundaries.get(boundary); - } - - public Insets getInsets(IBranchPart subBranch) { - SubBranchData data = getSubBranchData(subBranch); - return data != null ? data.getInsets() : IFigure.NO_INSETS; - } - - public Rectangle getBorderedBounds(IBranchPart subBranch, - ReferencedLayoutData data) { - Rectangle r = data.get(subBranch.getFigure()); - if (r != null) { - r = r.getExpanded(getInsets(subBranch)); - } - return r; - } - - public Dimension getBorderedSize(IBranchPart subBranch) { - return getBorderedSize(subBranch, -1, -1); - } - - public Dimension getBorderedSize(IBranchPart subBranch, int wHint, - int hHint) { - Dimension s = subBranch.getFigure().getPreferredSize(wHint, hHint); - Insets ins = getInsets(subBranch); - s = new Dimension(s.width + ins.getWidth(), s.height + ins.getHeight()); - return s; - } - - public Insets getInnerInsets(SubBranchData subBranch, - BoundaryData boundary) { - return subBranch.calcInnerInsets(boundary); - } - - public void setOverallBoundary(BoundaryData overallBoundary) { - this.overallBoundary = overallBoundary; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.xmind.gef.draw2d.ReferencedLayoutData; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.ui.internal.figures.BoundaryFigure; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; + +public class BoundaryLayoutHelper { + + public static interface ISubBranchInsetsCalculator { + + void calculateSubBranchInsets(BoundaryData boundary, + SubBranchData subBranch, Insets insets); + } + + public static class BoundaryData implements Comparable { + + public IBoundaryPart boundary; + + public IFigure boundaryFigure; + + private Insets prefInsets; + + private List subBranches; + + private Map branchBorders = new HashMap(); + + private int startIndex = -1; + + private int endIndex = -1; + + private int direction; + + private boolean overall; + + public BoundaryData(IBoundaryPart boundary, int direction, + Rectangle prefBoundaryBounds) { + this.boundary = boundary; + this.boundaryFigure = boundary.getFigure(); + this.prefInsets = boundaryFigure.getInsets(); + + if (prefBoundaryBounds != null + && ((BoundaryFigure) boundary.getFigure()).isTitleVisible() + && boundary.getTitle() != null + && boundary.getTitle().getFigure() != null) { + Dimension s = boundary.getTitle().getFigure().getPreferredSize( + prefBoundaryBounds.width, SWT.DEFAULT); + this.prefInsets = new Insets(this.prefInsets); + this.prefInsets.top = Math.max(s.height, this.prefInsets.top); + + this.prefInsets.left += 5; + } +// System.out.println("PrefInsets: " + this.prefInsets); + +// if (boundaryFigure instanceof ITitledFigure) { +// ITextFigure title = ((ITitledFigure) boundaryFigure).getTitle(); +// if (boundary.getBoundary().hasTitle()) { +// Dimension s = title.getPreferredSize(); +// prefInsets.top = Math.max(s.height, prefInsets.top); +// } +// } + this.subBranches = boundary.getEnclosingBranches(); + this.direction = direction; + this.overall = boundary.getBoundary().isMasterBoundary(); + } + + public boolean isOverall() { + return overall; + } + + public int getDirection() { + return direction; + } + + public Insets createInsets() { + return new Insets(prefInsets); + } + + public Rectangle expanded(Rectangle rect) { + return rect.expand(prefInsets); + } + + public List getSubBranches() { + return subBranches; + } + + public void setSubBranchInsets(IBranchPart subBranch, Insets ins) { + branchBorders.put(subBranch, ins); + } + + public Insets getSubBranchInsets(IBranchPart subBranch) { + return branchBorders.get(subBranch); + } + + public boolean isEmpty() { + return subBranches.isEmpty(); + } + + public IBranchPart getFirst() { + return isEmpty() ? null : subBranches.get(0); + } + + public IBranchPart getLast() { + return isEmpty() ? null : subBranches.get(subBranches.size() - 1); + } + + public boolean isFirst(SubBranchData subBranch) { + return isFirst(subBranch.subBranch); + } + + public boolean isLast(SubBranchData subBranch) { + return isLast(subBranch.subBranch); + } + + public boolean isFirst(IBranchPart subBranch) { + return subBranch == getFirst(); + } + + public boolean isLast(IBranchPart subBranch) { + return subBranch == getLast(); + } + + public boolean contains(BoundaryData another) { + return subBranches.containsAll(another.subBranches); + } + + public boolean contains(IBranchPart subBranch) { + return subBranches.contains(subBranch); + } + + public boolean contains(SubBranchData subBranch) { + return contains(subBranch.subBranch); + } + + public int getStartIndex() { + if (startIndex < 0 && !isEmpty()) { + startIndex = getFirst().getBranchIndex(); + } + return startIndex; + } + + public int getEndIndex() { + if (endIndex < 0 && !isEmpty()) { + endIndex = getLast().getBranchIndex(); + } + return endIndex; + } + + public int compareTo(BoundaryData that) { + if (this.isOverall()) + return 100; + if (that.isOverall()) + return -100; + if (this.contains(that)) + return 10; + if (that.contains(this)) + return -10; + if (this.isEmpty()) + return -100; + if (that.isEmpty()) + return 100; + return this.getStartIndex() - that.getStartIndex(); + } + } + + public static class SubBranchData { + + public IBranchPart subBranch; + + public List boundaries = new ArrayList(); + + private Insets insets = null; + + public SubBranchData(IBranchPart subBranch, + BoundaryData[] allBoundaries) { + this.subBranch = subBranch; + for (BoundaryData b : allBoundaries) { + if (b.contains(subBranch)) { + boundaries.add(b); + } + } + } + + public boolean isEmpty() { + return boundaries.isEmpty(); + } + + public Insets getInsets() { + if (insets == null) { + insets = calcInnerInsets(null); + } + return insets; + } + + public Insets calcInnerInsets(BoundaryData boundary) { + Insets insets = null; + BoundaryData last = null; + Insets lastLevelIns = null; + for (BoundaryData b : boundaries) { + if (last != null && boundary != null + && !boundary.contains(last)) { + lastLevelIns = null; + break; + } + + if (b == boundary) + break; + + if (last != null && b.contains(last)) { + insets = Geometry.add(insets, lastLevelIns); + lastLevelIns = null; + } + + last = b; + Insets ins = b.getSubBranchInsets(subBranch); + lastLevelIns = Geometry.union(lastLevelIns, ins); + } + if (lastLevelIns != null) + insets = Geometry.add(insets, lastLevelIns); + return insets == null ? IFigure.NO_INSETS : insets; + } + + } + + private Map boundaries = new HashMap(); + + private Map subBranches = new HashMap(); + + private BoundaryData overallBoundary = null; + + public BoundaryLayoutHelper() { + } + + public void reset(IBranchPart branch, IBranchStructureExtension algorithm, + Map prefBounds) { + boundaries.clear(); + subBranches.clear(); + + for (IBoundaryPart boundary : branch.getBoundaries()) { + BoundaryData boundaryData = new BoundaryData(boundary, + algorithm.getRangeGrowthDirection(branch, boundary), + prefBounds == null ? null + : prefBounds.get(boundary.getFigure())); + boundaries.put(boundary, boundaryData); +// if (boundaryData.isOverall() +// && (overallBoundary == null || MindMapUI.BRANCH_FLOATING +// .equals(branch.getBranchType()))) { +// overallBoundary = boundaryData; +// } + if (boundaryData.isOverall() && getOverallBoundary() == null) { + setOverallBoundary(boundaryData); + } + } + if (!isEmpty()) { + BoundaryData[] allBoundaries = boundaries.values() + .toArray(new BoundaryData[0]); + Arrays.sort(allBoundaries); + for (IBranchPart subBranch : branch.getSubBranches()) { + SubBranchData data = new SubBranchData(subBranch, + allBoundaries); + if (!data.isEmpty()) { + subBranches.put(subBranch, data); + } + } + } + for (IBoundaryPart b : branch.getBoundaries()) { + BoundaryData boundary = getBoundaryData(b); + for (IBranchPart s : boundary.subBranches) { + SubBranchData subBranch = getSubBranchData(s); + boundary.setSubBranchInsets(subBranch.subBranch, + createSubBranchInsets(boundary, subBranch)); + } + } + } + + public BoundaryData getOverallBoundary() { + return overallBoundary; + } + + protected Insets createSubBranchInsets(BoundaryData boundary, + SubBranchData subBranch) { + Insets ins = boundary.createInsets(); + switch (boundary.getDirection()) { + case PositionConstants.EAST: + if (!boundary.isFirst(subBranch)) { + ins.left = 0; + } + if (!boundary.isLast(subBranch)) { + ins.right = 0; + } + break; + case PositionConstants.WEST: + if (!boundary.isFirst(subBranch)) { + ins.right = 0; + } + if (!boundary.isLast(subBranch)) { + ins.left = 0; + } + break; + case PositionConstants.SOUTH: + if (!boundary.isFirst(subBranch)) { + ins.top = 0; + } + if (!boundary.isLast(subBranch)) { + ins.bottom = 0; + } + break; + case PositionConstants.NORTH: + if (!boundary.isFirst(subBranch)) { + ins.bottom = 0; + } + if (!boundary.isLast(subBranch)) { + ins.top = 0; + } + break; + } + + return ins; + } + + public boolean isEmpty() { + return boundaries.isEmpty(); + } + + public boolean hasSubBranch(IBranchPart subBranch) { + return subBranches.containsKey(subBranch); + } + + public SubBranchData getSubBranchData(IBranchPart subBranch) { + return subBranches.get(subBranch); + } + + public BoundaryData getBoundaryData(IBoundaryPart boundary) { + return boundaries.get(boundary); + } + + public Insets getInsets(IBranchPart subBranch) { + SubBranchData data = getSubBranchData(subBranch); + return data != null ? data.getInsets() : IFigure.NO_INSETS; + } + + public Rectangle getBorderedBounds(IBranchPart subBranch, + ReferencedLayoutData data) { + Rectangle r = data.get(subBranch.getFigure()); + if (r != null) { + r = r.getExpanded(getInsets(subBranch)); + } + return r; + } + + public Dimension getBorderedSize(IBranchPart subBranch) { + return getBorderedSize(subBranch, -1, -1); + } + + public Dimension getBorderedSize(IBranchPart subBranch, int wHint, + int hHint) { + Dimension s = subBranch.getFigure().getPreferredSize(wHint, hHint); + Insets ins = getInsets(subBranch); + s = new Dimension(s.width + ins.getWidth(), s.height + ins.getHeight()); + return s; + } + + public Insets getInnerInsets(SubBranchData subBranch, + BoundaryData boundary) { + return subBranch.calcInnerInsets(boundary); + } + + public void setOverallBoundary(BoundaryData overallBoundary) { + this.overallBoundary = overallBoundary; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BranchStructureData.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BranchStructureData.java index b939b41b1..a637512f0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BranchStructureData.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/BranchStructureData.java @@ -1,89 +1,89 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import static org.xmind.ui.style.StyleUtils.getInteger; - -import java.util.List; - -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; - -public class BranchStructureData { - - private IBranchPart branch; - - private int majorSpacing = -1; - - private int minorSpacing = -1; - - public BranchStructureData(IBranchPart branch) { - this.branch = branch; - } - - protected IBranchPart getBranch() { - return branch; - } - - protected List getSubBranches() { - return getBranch().getSubBranches(); - } - - protected int getMinorSpacing() { - if (minorSpacing < 0) { - minorSpacing = getInteger(getBranch(), getBranch() - .getBranchPolicy().getStyleSelector(getBranch()), - Styles.MinorSpacing, 5); - } - return minorSpacing; - } - - protected int getMajorSpacing() { - if (majorSpacing < 0) { - majorSpacing = StyleUtils.getMajorSpacing(getBranch(), 5); - } - return majorSpacing; - } - - protected boolean isInSameRangeWithLast(List subBranches, - int index) { - if (index <= 0 || index >= subBranches.size()) - return false; - return isInSameRange(subBranches.get(index - 1), subBranches.get(index)); - } - - protected boolean isInSameRange(IBranchPart child1, IBranchPart child2) { - for (IBoundaryPart boundary : getBranch().getBoundaries()) { - if (containsBoth(boundary, child1, child2)) - return true; - } - for (ISummaryPart summary : getBranch().getSummaries()) { - if (containsBoth(summary, child1, child2)) - return true; - } - return false; - } - - protected boolean containsBoth(IBranchRangePart range, IBranchPart child1, - IBranchPart child2) { - return range.encloses(child1) && range.encloses(child2); -// List branches = range.getEnclosingBranches(); -// return branches.contains(child1) && branches.contains(child2); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import static org.xmind.ui.style.StyleUtils.getInteger; + +import java.util.List; + +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; + +public class BranchStructureData { + + private IBranchPart branch; + + private int majorSpacing = -1; + + private int minorSpacing = -1; + + public BranchStructureData(IBranchPart branch) { + this.branch = branch; + } + + protected IBranchPart getBranch() { + return branch; + } + + protected List getSubBranches() { + return getBranch().getSubBranches(); + } + + protected int getMinorSpacing() { + if (minorSpacing < 0) { + minorSpacing = getInteger(getBranch(), getBranch() + .getBranchPolicy().getStyleSelector(getBranch()), + Styles.MinorSpacing, 5); + } + return minorSpacing; + } + + protected int getMajorSpacing() { + if (majorSpacing < 0) { + majorSpacing = StyleUtils.getMajorSpacing(getBranch(), 5); + } + return majorSpacing; + } + + protected boolean isInSameRangeWithLast(List subBranches, + int index) { + if (index <= 0 || index >= subBranches.size()) + return false; + return isInSameRange(subBranches.get(index - 1), subBranches.get(index)); + } + + protected boolean isInSameRange(IBranchPart child1, IBranchPart child2) { + for (IBoundaryPart boundary : getBranch().getBoundaries()) { + if (containsBoth(boundary, child1, child2)) + return true; + } + for (ISummaryPart summary : getBranch().getSummaries()) { + if (containsBoth(summary, child1, child2)) + return true; + } + return false; + } + + protected boolean containsBoth(IBranchRangePart range, IBranchPart child1, + IBranchPart child2) { + return range.encloses(child1) && range.encloses(child2); +// List branches = range.getEnclosingBranches(); +// return branches.contains(child1) && branches.contains(child2); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchDoubleClickSupport.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchDoubleClickSupport.java index 23ed6c415..5aee1b7de 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchDoubleClickSupport.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchDoubleClickSupport.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.ui.mindmap.IBranchPart; - -public interface IBranchDoubleClickSupport { - - boolean handleDoubleClick(IBranchPart branch, Point pos); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.ui.mindmap.IBranchPart; + +public interface IBranchDoubleClickSupport { + + boolean handleDoubleClick(IBranchPart branch, Point pos); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchMoveSupport.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchMoveSupport.java index ffd9aea99..ac10061d5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchMoveSupport.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchMoveSupport.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.gef.event.MouseDragEvent; -import org.xmind.ui.mindmap.IBranchPart; - -public interface IBranchMoveSupport { - - boolean canMove(IBranchPart branch, MouseDragEvent me); - - String getMoveTool(IBranchPart branch, MouseDragEvent me); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.gef.event.MouseDragEvent; +import org.xmind.ui.mindmap.IBranchPart; + +public interface IBranchMoveSupport { + + boolean canMove(IBranchPart branch, MouseDragEvent me); + + String getMoveTool(IBranchPart branch, MouseDragEvent me); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPolicyAdvisor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPolicyAdvisor.java index 6778f0957..f3448cc5b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPolicyAdvisor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPolicyAdvisor.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.ui.mindmap.IBranchPart; - -public interface IBranchPolicyAdvisor { - - void postActivate(IBranchPart branch, IBranchPolicy policy); - - void postDeactivate(IBranchPart branch, IBranchPolicy policy); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.ui.mindmap.IBranchPart; + +public interface IBranchPolicyAdvisor { + + void postActivate(IBranchPart branch, IBranchPolicy policy); + + void postDeactivate(IBranchPart branch, IBranchPolicy policy); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPropertyTester.java index 5bc86c162..d6f0aaf18 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchPropertyTester.java @@ -1,103 +1,103 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.ui.mindmap.IBranchPart; - -/** - * A branch property tester is responsible for testing policy-specified property - * on a branch. This class is used by
    org.xmind.ui.branchPolicies - * extension point. Clients who extend branchPolicy may take - * advantage of this class to define their own property test mechanism. - *

    - * Example: - *

    - *

    - * Define branch policy and declare property tester in plugin.xml: - * - *

    - * <branchPolicy 
    - *       id="org.example.branchPolicy.example"
    - *       propertyTester="org.example.ExampleBranchPropertyTester">
    - * </branchPolicy>
    - * 
    - * - *

    - *

    - * Implement the tester: - * - *

    - * public class ExampleBranchPolicyPropertyTester implements IBranchPropertyTester {
    - *     public boolean test(IBranchPart branch, String property, Object[] args,
    - *             Object expectedValue) {
    - *         if ("foo".equals(property)) {
    - *             return getFoo(branch).equals(expectedValue);
    - *         }
    - *         Assert.isTrue(false);
    - *         return false;
    - *     }
    - * 
    - *     private String getFoo(IBranchPart branch) {
    - *         return "bar";
    - *     }
    - * }
    - * 
    - * - *

    - * Then use this property tester inside branchPolicy extension: - * - *

    - * <branchPolicy 
    - *       id="org.example.branchPolicy.example"
    - *       propertyTester="org.example.ExampleBranchPropertyTester">
    - *    <additionalStructure
    - *          structureId="org.example.branchStructure.example">
    - *       <enablement>
    - *          <test
    - *                property="org.xmind.ui.branch.property"
    - *                args="foo"
    - *                value="bar">
    - *          </test>
    - *       </enablement>
    - *    </additionalStructure>
    - * </branchPolicy>
    - * 
    - * - * Note that the first argument in the args attribute will be - * considered as the policy-specified property and passed to the branch property - * tester as the property. The following parts of the - * args will be directly passed as the args argument. - * If there's no argument in the args attribute, the evaluation - * will fail by returning FALSE. - *

    - * - * - * @author MANGOSOFT - * - */ -public interface IBranchPropertyTester { - - /** - * Cache key for a {@link IBranchPropertyTester} object on a branch. - *

    - * A branch property tester is cached by branch policy when activated on a - * branch and flushed when deactivated. - *

    - */ - String CACHE_PROPERTY_TESTER = "org.xmind.ui.branchCache.propertyTester"; //$NON-NLS-1$ - - boolean test(IBranchPart branch, String property, Object[] args, - Object expectedValue); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.ui.mindmap.IBranchPart; + +/** + * A branch property tester is responsible for testing policy-specified property + * on a branch. This class is used by org.xmind.ui.branchPolicies + * extension point. Clients who extend branchPolicy may take + * advantage of this class to define their own property test mechanism. + *

    + * Example: + *

    + *

    + * Define branch policy and declare property tester in plugin.xml: + * + *

    + * <branchPolicy 
    + *       id="org.example.branchPolicy.example"
    + *       propertyTester="org.example.ExampleBranchPropertyTester">
    + * </branchPolicy>
    + * 
    + * + *

    + *

    + * Implement the tester: + * + *

    + * public class ExampleBranchPolicyPropertyTester implements IBranchPropertyTester {
    + *     public boolean test(IBranchPart branch, String property, Object[] args,
    + *             Object expectedValue) {
    + *         if ("foo".equals(property)) {
    + *             return getFoo(branch).equals(expectedValue);
    + *         }
    + *         Assert.isTrue(false);
    + *         return false;
    + *     }
    + * 
    + *     private String getFoo(IBranchPart branch) {
    + *         return "bar";
    + *     }
    + * }
    + * 
    + * + *

    + * Then use this property tester inside branchPolicy extension: + * + *

    + * <branchPolicy 
    + *       id="org.example.branchPolicy.example"
    + *       propertyTester="org.example.ExampleBranchPropertyTester">
    + *    <additionalStructure
    + *          structureId="org.example.branchStructure.example">
    + *       <enablement>
    + *          <test
    + *                property="org.xmind.ui.branch.property"
    + *                args="foo"
    + *                value="bar">
    + *          </test>
    + *       </enablement>
    + *    </additionalStructure>
    + * </branchPolicy>
    + * 
    + * + * Note that the first argument in the args attribute will be + * considered as the policy-specified property and passed to the branch property + * tester as the property. The following parts of the + * args will be directly passed as the args argument. + * If there's no argument in the args attribute, the evaluation + * will fail by returning FALSE. + *

    + * + * + * @author MANGOSOFT + * + */ +public interface IBranchPropertyTester { + + /** + * Cache key for a {@link IBranchPropertyTester} object on a branch. + *

    + * A branch property tester is cached by branch policy when activated on a + * branch and flushed when deactivated. + *

    + */ + String CACHE_PROPERTY_TESTER = "org.xmind.ui.branchCache.propertyTester"; //$NON-NLS-1$ + + boolean test(IBranchPart branch, String property, Object[] args, + Object expectedValue); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleSelector.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleSelector.java index 39edf8544..f304d5791 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleSelector.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleSelector.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.ui.mindmap.IBranchPart; - -public interface IBranchStyleSelector extends IStyleSelector { - - void flushStyleCaches(IBranchPart branch); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.ui.mindmap.IBranchPart; + +public interface IBranchStyleSelector extends IStyleSelector { + + void flushStyleCaches(IBranchPart branch); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleValueProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleValueProvider.java index b5611b065..83198d9a9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleValueProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/IBranchStyleValueProvider.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.ui.mindmap.IBranchPart; - -public interface IBranchStyleValueProvider { - - String getValue(IBranchPart branch, String layerName, String key); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.ui.mindmap.IBranchPart; + +public interface IBranchStyleValueProvider { + + String getValue(IBranchPart branch, String layerName, String key); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ICreatableBranchStructureExtension.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ICreatableBranchStructureExtension.java index 1debadb19..7f70ec78a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ICreatableBranchStructureExtension.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ICreatableBranchStructureExtension.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.gef.Request; -import org.xmind.ui.mindmap.IBranchPart; - -public interface ICreatableBranchStructureExtension { - - void decorateCreateRequest(IBranchPart branch, IBranchPart sourceChild, - Request request); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.gef.Request; +import org.xmind.ui.mindmap.IBranchPart; + +public interface ICreatableBranchStructureExtension { + + void decorateCreateRequest(IBranchPart branch, IBranchPart sourceChild, + Request request); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ILockableBranchStructureExtension.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ILockableBranchStructureExtension.java index cfc7d2556..7c0d8d30b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ILockableBranchStructureExtension.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/branch/ILockableBranchStructureExtension.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.branch; - -import org.xmind.ui.mindmap.IBranchPart; - -public interface ILockableBranchStructureExtension { - - void lock(IBranchPart branch); - - void unlock(IBranchPart branch); +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.branch; + +import org.xmind.ui.mindmap.IBranchPart; + +public interface ILockableBranchStructureExtension { + + void lock(IBranchPart branch); + + void unlock(IBranchPart branch); } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddCommentCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddCommentCommand.java index 0bb46d968..d3720ed1d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddCommentCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddCommentCommand.java @@ -1,56 +1,56 @@ -package org.xmind.ui.commands; - -import org.xmind.core.IComment; -import org.xmind.core.IWorkbook; -import org.xmind.gef.command.SourceCommand; - -public class AddCommentCommand extends SourceCommand { - - private String author; - - private long time; - - private String objectId; - - private String content; - - private IWorkbook workbook; - - private IComment comment; - - public AddCommentCommand(String author, long time, String objectId, - String content, IWorkbook workbook) { - super(workbook.getElementById(objectId)); - - this.author = author; - this.time = time; - this.objectId = objectId; - this.content = content; - this.workbook = workbook; - } - - public AddCommentCommand(String author, long time, String objectId, - String content, IWorkbook workbook, IComment comment) { - this(author, time, objectId, content, workbook); - this.comment = comment; - } - - public void redo() { - if (comment == null) { - comment = workbook.getCommentManager().createComment(author, time, - objectId); - } - if (!content.equals(comment.getContent())) { - comment.setContent(content); - } - - workbook.getCommentManager().addComment(comment); - super.redo(); - } - - public void undo() { - workbook.getCommentManager().removeComment(comment); - super.undo(); - } - -} +package org.xmind.ui.commands; + +import org.xmind.core.IComment; +import org.xmind.core.IWorkbook; +import org.xmind.gef.command.SourceCommand; + +public class AddCommentCommand extends SourceCommand { + + private String author; + + private long time; + + private String objectId; + + private String content; + + private IWorkbook workbook; + + private IComment comment; + + public AddCommentCommand(String author, long time, String objectId, + String content, IWorkbook workbook) { + super(workbook.getElementById(objectId)); + + this.author = author; + this.time = time; + this.objectId = objectId; + this.content = content; + this.workbook = workbook; + } + + public AddCommentCommand(String author, long time, String objectId, + String content, IWorkbook workbook, IComment comment) { + this(author, time, objectId, content, workbook); + this.comment = comment; + } + + public void redo() { + if (comment == null) { + comment = workbook.getCommentManager().createComment(author, time, + objectId); + } + if (!content.equals(comment.getContent())) { + comment.setContent(content); + } + + workbook.getCommentManager().addComment(comment); + super.redo(); + } + + public void undo() { + workbook.getCommentManager().removeComment(comment); + super.undo(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddMarkerCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddMarkerCommand.java index 868a7d2f5..bf541ecec 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddMarkerCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddMarkerCommand.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.SourceCommand; - -public class AddMarkerCommand extends SourceCommand { - - private String markerId; - - public AddMarkerCommand(ITopic topic, String newMarkerId) { - super(topic); - Assert.isNotNull(newMarkerId); - this.markerId = newMarkerId; - } - - public AddMarkerCommand(Collection topics, - String newMarkerId) { - super(topics); - Assert.isNotNull(newMarkerId); - this.markerId = newMarkerId; - } - - public AddMarkerCommand(ISourceProvider sourceProvider, - String newMarkerId) { - super(sourceProvider); - Assert.isNotNull(newMarkerId); - this.markerId = newMarkerId; - } - - @Override - public void redo() { - for (Object source : getSources()) { - if (source instanceof ITopic) { - ITopic t = (ITopic) source; - t.addMarker(markerId); - } - } - super.redo(); - } - - @Override - public void undo() { - List sources = getSources(); - for (int i = sources.size() - 1; i >= 0; i--) { - Object source = sources.get(i); - if (source instanceof ITopic) { - ITopic t = (ITopic) source; - t.removeMarker(markerId); - } - } - super.undo(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.SourceCommand; + +public class AddMarkerCommand extends SourceCommand { + + private String markerId; + + public AddMarkerCommand(ITopic topic, String newMarkerId) { + super(topic); + Assert.isNotNull(newMarkerId); + this.markerId = newMarkerId; + } + + public AddMarkerCommand(Collection topics, + String newMarkerId) { + super(topics); + Assert.isNotNull(newMarkerId); + this.markerId = newMarkerId; + } + + public AddMarkerCommand(ISourceProvider sourceProvider, + String newMarkerId) { + super(sourceProvider); + Assert.isNotNull(newMarkerId); + this.markerId = newMarkerId; + } + + @Override + public void redo() { + for (Object source : getSources()) { + if (source instanceof ITopic) { + ITopic t = (ITopic) source; + t.addMarker(markerId); + } + } + super.redo(); + } + + @Override + public void undo() { + List sources = getSources(); + for (int i = sources.size() - 1; i >= 0; i--) { + Object source = sources.get(i); + if (source instanceof ITopic) { + ITopic t = (ITopic) source; + t.removeMarker(markerId); + } + } + super.undo(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CloneTopicCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CloneTopicCommand.java index 76f6c9ac0..c1280b1e9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CloneTopicCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CloneTopicCommand.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.command.CreateCommand; - -public class CloneTopicCommand extends CreateCommand { - - private IWorkbook workbook; - - private ITopic source; - - private ITopic topic; - - public CloneTopicCommand(IWorkbook workbook, ITopic source) { - Assert.isNotNull(workbook); - Assert.isNotNull(source); - this.workbook = workbook; - this.source = source; - } - - protected boolean canCreate() { - if (topic == null) { - topic = workbook.cloneTopic(source); - } - return topic != null; - } - - protected Object create() { - canCreate(); - return topic; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.command.CreateCommand; + +public class CloneTopicCommand extends CreateCommand { + + private IWorkbook workbook; + + private ITopic source; + + private ITopic topic; + + public CloneTopicCommand(IWorkbook workbook, ITopic source) { + Assert.isNotNull(workbook); + Assert.isNotNull(source); + this.workbook = workbook; + this.source = source; + } + + protected boolean canCreate() { + if (topic == null) { + topic = workbook.cloneTopic(source); + } + return topic != null; + } + + protected Object create() { + canCreate(); + return topic; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CommandMessages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CommandMessages.java index 1e92d80a0..f995054d3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CommandMessages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CommandMessages.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import org.eclipse.osgi.util.NLS; - -public class CommandMessages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.ui.commands.messages"; //$NON-NLS-1$ - - public static String Command_AddMarker; - public static String Command_AddResources; - public static String Command_Align; - public static String Command_AlignLeft; - public static String Command_AlignCenter; - public static String Command_AlignRight; - public static String Command_AlignTop; - public static String Command_AlignMiddle; - public static String Command_AlignBottom; - public static String Command_CreateBoundary; - public static String Command_CreateFloatingTopic; - public static String Command_CreateRelationship; - public static String Command_CreateSheet; - public static String Command_CreateSheetFromTopic; - public static String Command_CreateSummary; - public static String Command_CreateTopic; - public static String Command_Collapse; - public static String Command_CollapseAll; - public static String Command_CopyImage; - public static String Command_CopyMarker; - public static String Command_CopyTopic; - public static String Command_Cut; - public static String Command_CutBoundary; - public static String Command_CutRelationship; - public static String Command_CutSheet; - public static String Command_CutTopic; - public static String Command_Delete; - public static String Command_DeleteBoundary; - public static String Command_DeleteMarker; - public static String Command_DeleteRelationship; - public static String Command_DeleteSheet; - public static String Command_DeleteTopic; - public static String Command_Extend; - public static String Command_ExtendAll; - public static String Command_HideLegend; - public static String Command_InsertAttachment; - public static String Command_InsertImage; - public static String Command_ModifyBorderColor; - - public static String Command_ModifyBorderShape; - - public static String Command_ModifyBoundaryRange; - public static String Command_ModifyBoundaryTitle; - public static String Command_ModifyLabels; - public static String Command_ModifyLegendMarkerDescription; - public static String Command_ModifyNotes; - public static String Command_ModifyNumbering; - public static String Command_ModifyPosition; - public static String Command_ModifyRange; - public static String Command_ModifyRelationshipTitle; - public static String Command_ModifySheetTitle; - public static String Command_ModifyStyle; - public static String Command_RemoveStyle; - public static String Command_ModifySummaryRange; - public static String Command_ModifyTitle; - public static String Command_ModifyTitleWidth; - public static String Command_ModifyTopicHyperlink; - public static String Command_ModifyTopicStructure; - public static String Command_ModifyTopicTitle; - public static String Command_MoveImage; - public static String Command_MoveLegend; - public static String Command_MoveMarker; - public static String Command_MoveSheet; - public static String Command_MoveRelationshipControlPoint; - public static String Command_MoveTopic; - public static String Command_ResizeImage; - public static String Command_Paste; - public static String Command_PasteSheet; - public static String Command_PasteTopic; - public static String Command_ReplaceMarker; - public static String Command_ResetPosition; - public static String Command_RetargetRelationship; - public static String Command_ShowLegend; - public static String Command_Tile; - public static String Command_Typing; - public static String Command_ModifyTheme; - public static String Command_ModifyLegendBackgroundColor; - - public static String Command_ShowOrHideInfoItem; - - // Labels of Modify Style Commands: - public static String Command_ModifyBoundaryOpacity; - public static String Command_ModifyBoundaryShape; - public static String Command_ModifyFillColor; - public static String Command_ModifyFont; - public static String Command_ModifyLineColor; - public static String Command_ModifyLineShape; - public static String Command_RemoveWallpaper; - public static String Command_ModifySheetBackgroundColor; - public static String Command_ModifyTextColor; - public static String Command_ModifyTopicShape; - public static String Command_ModifyRelationshipShape; - public static String Command_ModifyBeginArrowShape; - public static String Command_ModifyEndArrowShape; - public static String Command_ModifyWallpaper; - public static String Command_ModifyWallpaperOpacity; - public static String Command_ToggleMultiLineColors; - public static String Command_ToggleTaperedLines; - public static String Command_ToggleGradientColor; - public static String Command_ShowLabels; - public static String Command_ShowNotes; - public static String Command_ShowHyperlink; - public static String Command_ShowTaskInfo; - public static String Command_ModifyYellowBoxBackgroundColor; - - public static String Command_TextAlignLeft; - public static String Command_TextAlignCenter; - public static String Command_TextAlignRight; - - public static String Command_TextManual; - public static String Command_TextUppercase; - public static String Command_TextLowercase; - public static String Command_TextCapitalize; - - public static String Command_SortByTitle; - public static String Command_SortByPriority; - public static String Command_SortByModifiedTime; - public static String Command_Sort; - public static String Command_ModifyWidth; - - public static String Command_TurnOnAutoRevisionSaving; - public static String Command_TurnOffAutoRevisionSaving; - public static String Command_CopySheet; - public static String Command_DuplicateSheet; - - public static String Command_ClearMarkers; - public static String Command_RemoveMarkerFromAllTopics; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, CommandMessages.class); - } - - private CommandMessages() { - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import org.eclipse.osgi.util.NLS; + +public class CommandMessages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.ui.commands.messages"; //$NON-NLS-1$ + + public static String Command_AddMarker; + public static String Command_AddResources; + public static String Command_Align; + public static String Command_AlignLeft; + public static String Command_AlignCenter; + public static String Command_AlignRight; + public static String Command_AlignTop; + public static String Command_AlignMiddle; + public static String Command_AlignBottom; + public static String Command_CreateBoundary; + public static String Command_CreateFloatingTopic; + public static String Command_CreateRelationship; + public static String Command_CreateSheet; + public static String Command_CreateSheetFromTopic; + public static String Command_CreateSummary; + public static String Command_CreateTopic; + public static String Command_Collapse; + public static String Command_CollapseAll; + public static String Command_CopyImage; + public static String Command_CopyMarker; + public static String Command_CopyTopic; + public static String Command_Cut; + public static String Command_CutBoundary; + public static String Command_CutRelationship; + public static String Command_CutSheet; + public static String Command_CutTopic; + public static String Command_Delete; + public static String Command_DeleteBoundary; + public static String Command_DeleteMarker; + public static String Command_DeleteRelationship; + public static String Command_DeleteSheet; + public static String Command_DeleteTopic; + public static String Command_Extend; + public static String Command_ExtendAll; + public static String Command_HideLegend; + public static String Command_InsertAttachment; + public static String Command_InsertImage; + public static String Command_ModifyBorderColor; + + public static String Command_ModifyBorderShape; + + public static String Command_ModifyBoundaryRange; + public static String Command_ModifyBoundaryTitle; + public static String Command_ModifyLabels; + public static String Command_ModifyLegendMarkerDescription; + public static String Command_ModifyNotes; + public static String Command_ModifyNumbering; + public static String Command_ModifyPosition; + public static String Command_ModifyRange; + public static String Command_ModifyRelationshipTitle; + public static String Command_ModifySheetTitle; + public static String Command_ModifyStyle; + public static String Command_RemoveStyle; + public static String Command_ModifySummaryRange; + public static String Command_ModifyTitle; + public static String Command_ModifyTitleWidth; + public static String Command_ModifyTopicHyperlink; + public static String Command_ModifyTopicStructure; + public static String Command_ModifyTopicTitle; + public static String Command_MoveImage; + public static String Command_MoveLegend; + public static String Command_MoveMarker; + public static String Command_MoveSheet; + public static String Command_MoveRelationshipControlPoint; + public static String Command_MoveTopic; + public static String Command_ResizeImage; + public static String Command_Paste; + public static String Command_PasteSheet; + public static String Command_PasteTopic; + public static String Command_ReplaceMarker; + public static String Command_ResetPosition; + public static String Command_RetargetRelationship; + public static String Command_ShowLegend; + public static String Command_Tile; + public static String Command_Typing; + public static String Command_ModifyTheme; + public static String Command_ModifyLegendBackgroundColor; + + public static String Command_ShowOrHideInfoItem; + + // Labels of Modify Style Commands: + public static String Command_ModifyBoundaryOpacity; + public static String Command_ModifyBoundaryShape; + public static String Command_ModifyFillColor; + public static String Command_ModifyFont; + public static String Command_ModifyLineColor; + public static String Command_ModifyLineShape; + public static String Command_RemoveWallpaper; + public static String Command_ModifySheetBackgroundColor; + public static String Command_ModifyTextColor; + public static String Command_ModifyTopicShape; + public static String Command_ModifyRelationshipShape; + public static String Command_ModifyBeginArrowShape; + public static String Command_ModifyEndArrowShape; + public static String Command_ModifyWallpaper; + public static String Command_ModifyWallpaperOpacity; + public static String Command_ToggleMultiLineColors; + public static String Command_ToggleTaperedLines; + public static String Command_ToggleGradientColor; + public static String Command_ShowLabels; + public static String Command_ShowNotes; + public static String Command_ShowHyperlink; + public static String Command_ShowTaskInfo; + public static String Command_ModifyYellowBoxBackgroundColor; + + public static String Command_TextAlignLeft; + public static String Command_TextAlignCenter; + public static String Command_TextAlignRight; + + public static String Command_TextManual; + public static String Command_TextUppercase; + public static String Command_TextLowercase; + public static String Command_TextCapitalize; + + public static String Command_SortByTitle; + public static String Command_SortByPriority; + public static String Command_SortByModifiedTime; + public static String Command_Sort; + public static String Command_ModifyWidth; + + public static String Command_TurnOnAutoRevisionSaving; + public static String Command_TurnOffAutoRevisionSaving; + public static String Command_CopySheet; + public static String Command_DuplicateSheet; + + public static String Command_ClearMarkers; + public static String Command_RemoveMarkerFromAllTopics; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, CommandMessages.class); + } + + private CommandMessages() { + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateBoundaryCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateBoundaryCommand.java index 69d86215d..25b57cb7b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateBoundaryCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateBoundaryCommand.java @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.Assert; import org.xmind.core.IBoundary; import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.command.CreateCommand; import org.xmind.ui.internal.MindMapUIPlugin; @@ -45,7 +46,7 @@ protected Object create() { @Override public void execute() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("InsertBoundaryCount"); //$NON-NLS-1$ + .increase(UserDataConstants.INSERT_BOUNDARY_COUNT); super.execute(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateCommentCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateCommentCommand.java index 49c4e55b5..703ac57dd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateCommentCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateCommentCommand.java @@ -1,21 +1,21 @@ -package org.xmind.ui.commands; - -import org.xmind.gef.command.Command; - -/** - * The undo and redo function of this command is merged with - * ModifyCommentCommand, so it's not provided in here. - * - * @deprecated - */ -@Deprecated -public class CreateCommentCommand extends Command { - - public CreateCommentCommand(Object target) { - } - - public void execute() { - super.execute(); - } - -} +package org.xmind.ui.commands; + +import org.xmind.gef.command.Command; + +/** + * The undo and redo function of this command is merged with + * ModifyCommentCommand, so it's not provided in here. + * + * @deprecated + */ +@Deprecated +public class CreateCommentCommand extends Command { + + public CreateCommentCommand(Object target) { + } + + public void execute() { + super.execute(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSheetCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSheetCommand.java index 8baa229c7..808c86f73 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSheetCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSheetCommand.java @@ -1,81 +1,81 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Arrays; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.ICloneData; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.command.CreateCommand; - -public class CreateSheetCommand extends CreateCommand { - - private IWorkbook parent; - - private int index; - - private ISheet sheet; - - private ITopic topic; - - private ICloneData cloneData; - - public CreateSheetCommand(IWorkbook parent, ITopic topic) { - this(parent, -1); - this.topic = topic; - - } - - public CreateSheetCommand(IWorkbook parent, int index) { - Assert.isNotNull(parent); - Assert.isTrue(index <= parent.getSheets().size()); - this.parent = parent; - this.index = index; - } - - protected boolean canCreate() { - if (sheet == null) { - sheet = parent.createSheet(); - if (topic != null) { - ICloneData clone = parent.clone(Arrays.asList(topic)); - cloneData = clone; - ITopic cloneTopic = (ITopic) clone.get(topic); - sheet.replaceRootTopic(cloneTopic); - } - } - return sheet != null; - } - - protected Object create() { - canCreate(); - return sheet; - } - - public void redo() { - parent.addSheet((ISheet) getSource(), index); - super.redo(); - } - - public void undo() { - parent.removeSheet((ISheet) getSource()); - super.undo(); - } - - public ICloneData getCloneData() { - return cloneData; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Arrays; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ICloneData; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.command.CreateCommand; + +public class CreateSheetCommand extends CreateCommand { + + private IWorkbook parent; + + private int index; + + private ISheet sheet; + + private ITopic topic; + + private ICloneData cloneData; + + public CreateSheetCommand(IWorkbook parent, ITopic topic) { + this(parent, -1); + this.topic = topic; + + } + + public CreateSheetCommand(IWorkbook parent, int index) { + Assert.isNotNull(parent); + Assert.isTrue(index <= parent.getSheets().size()); + this.parent = parent; + this.index = index; + } + + protected boolean canCreate() { + if (sheet == null) { + sheet = parent.createSheet(); + if (topic != null) { + ICloneData clone = parent.clone(Arrays.asList(topic)); + cloneData = clone; + ITopic cloneTopic = (ITopic) clone.get(topic); + sheet.replaceRootTopic(cloneTopic); + } + } + return sheet != null; + } + + protected Object create() { + canCreate(); + return sheet; + } + + public void redo() { + parent.addSheet((ISheet) getSource(), index); + super.redo(); + } + + public void undo() { + parent.removeSheet((ISheet) getSource()); + super.undo(); + } + + public ICloneData getCloneData() { + return cloneData; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSummaryCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSummaryCommand.java index 0f611b6cd..c7e310c5c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSummaryCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateSummaryCommand.java @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.Assert; import org.xmind.core.ISummary; import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.command.CreateCommand; import org.xmind.ui.internal.MindMapUIPlugin; @@ -45,7 +46,7 @@ protected Object create() { @Override public void execute() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("InsertSummaryCount"); //$NON-NLS-1$ + .increase(UserDataConstants.INSERT_SUMMARY_COUNT); super.execute(); } } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateTopicCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateTopicCommand.java index 5afcfe62b..54b862723 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateTopicCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/CreateTopicCommand.java @@ -1,44 +1,44 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.command.CreateCommand; - -public class CreateTopicCommand extends CreateCommand { - - private IWorkbook workbook; - - private ITopic topic; - - public CreateTopicCommand(IWorkbook workbook) { - Assert.isNotNull(workbook); - this.workbook = workbook; - } - - public boolean canCreate() { - if (topic == null) { - topic = workbook.createTopic(); - } - return topic != null; - } - - protected Object create() { - canCreate(); - return topic; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.command.CreateCommand; + +public class CreateTopicCommand extends CreateCommand { + + private IWorkbook workbook; + + private ITopic topic; + + public CreateTopicCommand(IWorkbook workbook) { + Assert.isNotNull(workbook); + this.workbook = workbook; + } + + public boolean canCreate() { + if (topic == null) { + topic = workbook.createTopic(); + } + return topic != null; + } + + protected Object create() { + canCreate(); + return topic; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteCommentCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteCommentCommand.java index 4e4ae028c..e251c1f8c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteCommentCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteCommentCommand.java @@ -1,27 +1,27 @@ -package org.xmind.ui.commands; - -import org.xmind.core.IComment; -import org.xmind.gef.command.SourceCommand; -import org.xmind.ui.internal.MindMapMessages; - -public class DeleteCommentCommand extends SourceCommand { - - private IComment comment; - - public DeleteCommentCommand(Object target, IComment comment) { - super(target); - this.comment = comment; - setLabel(MindMapMessages.DeleteComment_label); - } - - public void redo() { - comment.getOwnedWorkbook().getCommentManager().removeComment(comment); - super.redo(); - } - - public void undo() { - comment.getOwnedWorkbook().getCommentManager().addComment(comment); - super.undo(); - } - -} +package org.xmind.ui.commands; + +import org.xmind.core.IComment; +import org.xmind.gef.command.SourceCommand; +import org.xmind.ui.internal.MindMapMessages; + +public class DeleteCommentCommand extends SourceCommand { + + private IComment comment; + + public DeleteCommentCommand(Object target, IComment comment) { + super(target); + this.comment = comment; + setLabel(MindMapMessages.DeleteComment_label); + } + + public void redo() { + comment.getOwnedWorkbook().getCommentManager().removeComment(comment); + super.redo(); + } + + public void undo() { + comment.getOwnedWorkbook().getCommentManager().addComment(comment); + super.undo(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteMarkerCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteMarkerCommand.java index 899bff8f8..6a48ede9f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteMarkerCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteMarkerCommand.java @@ -1,60 +1,60 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.ITopic; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.gef.GEF; -import org.xmind.gef.command.SourceCommand; -import org.xmind.ui.internal.MindMapMessages; - -public class DeleteMarkerCommand extends SourceCommand { - - private String markerId; - - public DeleteMarkerCommand(ITopic topic, String markerId) { - super(topic); - Assert.isNotNull(markerId); - this.markerId = markerId; - setLabel(MindMapMessages.DeleteMarker_label); - } - - public DeleteMarkerCommand(IMarkerRef markerRef) { - Assert.isNotNull(markerRef); - ITopic topic = markerRef.getParent(); - Assert.isNotNull(topic); - String markerId = markerRef.getMarkerId(); - Assert.isNotNull(markerId); - setSource(topic); - this.markerId = markerId; - setLabel(MindMapMessages.DeleteMarker_label); - } - - public int getType() { - return GEF.CMD_DELETE; - } - - @Override - public void redo() { - ((ITopic) getSource()).removeMarker(markerId); - super.redo(); - } - - @Override - public void undo() { - ((ITopic) getSource()).addMarker(markerId); - super.undo(); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.gef.GEF; +import org.xmind.gef.command.SourceCommand; +import org.xmind.ui.internal.MindMapMessages; + +public class DeleteMarkerCommand extends SourceCommand { + + private String markerId; + + public DeleteMarkerCommand(ITopic topic, String markerId) { + super(topic); + Assert.isNotNull(markerId); + this.markerId = markerId; + setLabel(MindMapMessages.DeleteMarker_label); + } + + public DeleteMarkerCommand(IMarkerRef markerRef) { + Assert.isNotNull(markerRef); + ITopic topic = markerRef.getParent(); + Assert.isNotNull(topic); + String markerId = markerRef.getMarkerId(); + Assert.isNotNull(markerId); + setSource(topic); + this.markerId = markerId; + setLabel(MindMapMessages.DeleteMarker_label); + } + + public int getType() { + return GEF.CMD_DELETE; + } + + @Override + public void redo() { + ((ITopic) getSource()).removeMarker(markerId); + super.redo(); + } + + @Override + public void undo() { + ((ITopic) getSource()).addMarker(markerId); + super.undo(); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteNotesCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteNotesCommand.java index 4b41cbd0e..d7119abd6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteNotesCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/DeleteNotesCommand.java @@ -1,46 +1,46 @@ -package org.xmind.ui.commands; - -import org.xmind.core.INotes; -import org.xmind.core.INotesContent; -import org.xmind.core.ITopic; -import org.xmind.gef.command.SourceCommand; -import org.xmind.ui.internal.MindMapMessages; - -public class DeleteNotesCommand extends SourceCommand { - - private ITopic topic; - - private INotesContent htmlContent; - - private INotesContent plainContent; - - public DeleteNotesCommand(ITopic topic) { - super(topic); - this.topic = topic; - setLabel(MindMapMessages.DeleteNotes_label); - } - - public void redo() { - if (topic == null) { - return; - } - INotes notes = topic.getNotes(); - if (htmlContent == null && plainContent == null) { - htmlContent = notes.getContent(INotes.HTML); - plainContent = notes.getContent(INotes.PLAIN); - } - notes.setContent(INotes.HTML, null); - notes.setContent(INotes.PLAIN, null); - - super.redo(); - } - - public void undo() { - INotes notes = topic.getNotes(); - notes.setContent(INotes.PLAIN, plainContent); - notes.setContent(INotes.HTML, htmlContent); - - super.undo(); - } - -} +package org.xmind.ui.commands; + +import org.xmind.core.INotes; +import org.xmind.core.INotesContent; +import org.xmind.core.ITopic; +import org.xmind.gef.command.SourceCommand; +import org.xmind.ui.internal.MindMapMessages; + +public class DeleteNotesCommand extends SourceCommand { + + private ITopic topic; + + private INotesContent htmlContent; + + private INotesContent plainContent; + + public DeleteNotesCommand(ITopic topic) { + super(topic); + this.topic = topic; + setLabel(MindMapMessages.DeleteNotes_label); + } + + public void redo() { + if (topic == null) { + return; + } + INotes notes = topic.getNotes(); + if (htmlContent == null && plainContent == null) { + htmlContent = notes.getContent(INotes.HTML); + plainContent = notes.getContent(INotes.PLAIN); + } + notes.setContent(INotes.HTML, null); + notes.setContent(INotes.PLAIN, null); + + super.redo(); + } + + public void undo() { + INotes notes = topic.getNotes(); + notes.setContent(INotes.PLAIN, plainContent); + notes.setContent(INotes.HTML, htmlContent); + + super.undo(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/MindMapCommandConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/MindMapCommandConstants.java index 1d5528895..c0e60f5f6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/MindMapCommandConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/MindMapCommandConstants.java @@ -1,33 +1,33 @@ -package org.xmind.ui.commands; - -public class MindMapCommandConstants { - - public static final String ADD_MARKER = "org.xmind.ui.command.addMarker"; //$NON-NLS-1$ - public static final String ADD_MARKER_PARAM_MARKER_ID = "org.xmind.ui.mindmap.markerId"; //$NON-NLS-1$ - - public static final String OPEN_WORKBOOK = "org.xmind.ui.command.openWorkbook"; //$NON-NLS-1$ - public static final String OPEN_WORKBOOK_PARAM_URI = "org.xmind.ui.command.openWorkbook.uri"; //$NON-NLS-1$ - - public static final String ALIGNMENT = "org.xmind.ui.command.alignment"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM = "org.xmind.ui.alignmentParameter"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_TOP = "top"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_MIDDLE = "middle"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_BOTTOM = "bottom"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_LEFT = "left"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_CENTER = "center"; //$NON-NLS-1$ - public static final String ALIGNMENT_PARAM_RIGHT = "right"; //$NON-NLS-1$ - - public static final String SORT = "org.xmind.ui.command.sort"; //$NON-NLS-1$ - public static final String SORT_PARAM = "org.xmind.ui.sortParameter"; //$NON-NLS-1$ - public static final String SORT_PARAM_MODIFIED = "modified"; //$NON-NLS-1$ - public static final String SORT_PARAM_PRIORITY = "priority"; //$NON-NLS-1$ - public static final String SORT_PARAM_TITLE = "title"; //$NON-NLS-1$ - - public static final String COLORFUL_SHEET = "org.xmind.ui.command.colorfulSheet"; //$NON-NLS-1$ - public static final String COLORFUL_SHEET_PARAM_RGB = "org.xmind.ui.command.colorfulSheet.rgbParameter"; //$NON-NLS-1$ - - public static final String SAVE_WORKBOOK_AS = "org.xmind.ui.command.saveWorkbookAs"; //$NON-NLS-1$ - public static final String SAVE_AS_WIZARD_ID_PARAM = "org.xmind.ui.command.saveWorkbookAs.wizardId"; //$NON-NLS-1$ - public static final String SAVE_AS_EXCLUDED_WIZARD_IDS_PARAM = "org.xmind.ui.command.saveWorkbookAs.excludedWizardIds"; //$NON-NLS-1$ - -} +package org.xmind.ui.commands; + +public class MindMapCommandConstants { + + public static final String ADD_MARKER = "org.xmind.ui.command.addMarker"; //$NON-NLS-1$ + public static final String ADD_MARKER_PARAM_MARKER_ID = "org.xmind.ui.mindmap.markerId"; //$NON-NLS-1$ + + public static final String OPEN_WORKBOOK = "org.xmind.ui.command.openWorkbook"; //$NON-NLS-1$ + public static final String OPEN_WORKBOOK_PARAM_URI = "org.xmind.ui.command.openWorkbook.uri"; //$NON-NLS-1$ + + public static final String ALIGNMENT = "org.xmind.ui.command.alignment"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM = "org.xmind.ui.alignmentParameter"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_TOP = "top"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_MIDDLE = "middle"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_BOTTOM = "bottom"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_LEFT = "left"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_CENTER = "center"; //$NON-NLS-1$ + public static final String ALIGNMENT_PARAM_RIGHT = "right"; //$NON-NLS-1$ + + public static final String SORT = "org.xmind.ui.command.sort"; //$NON-NLS-1$ + public static final String SORT_PARAM = "org.xmind.ui.sortParameter"; //$NON-NLS-1$ + public static final String SORT_PARAM_MODIFIED = "modified"; //$NON-NLS-1$ + public static final String SORT_PARAM_PRIORITY = "priority"; //$NON-NLS-1$ + public static final String SORT_PARAM_TITLE = "title"; //$NON-NLS-1$ + + public static final String COLORFUL_SHEET = "org.xmind.ui.command.colorfulSheet"; //$NON-NLS-1$ + public static final String COLORFUL_SHEET_PARAM_RGB = "org.xmind.ui.command.colorfulSheet.rgbParameter"; //$NON-NLS-1$ + + public static final String SAVE_WORKBOOK_AS = "org.xmind.ui.command.saveWorkbookAs"; //$NON-NLS-1$ + public static final String SAVE_AS_WIZARD_ID_PARAM = "org.xmind.ui.command.saveWorkbookAs.wizardId"; //$NON-NLS-1$ + public static final String SAVE_AS_EXCLUDED_WIZARD_IDS_PARAM = "org.xmind.ui.command.saveWorkbookAs.excludedWizardIds"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyCommentCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyCommentCommand.java index f44d679f5..231134996 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyCommentCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyCommentCommand.java @@ -1,39 +1,39 @@ -package org.xmind.ui.commands; - -import org.xmind.core.IComment; -import org.xmind.gef.command.ModifyCommand; -import org.xmind.ui.internal.MindMapMessages; - -public class ModifyCommentCommand extends ModifyCommand { - - private IComment comment; - - public ModifyCommentCommand(Object target, IComment comment, - String newValue) { - super(target, newValue); - this.comment = comment; - super.setLabel(MindMapMessages.ModifyComment_label); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.command.ModifyCommand#getValue(java.lang.Object) - */ - @Override - protected Object getValue(Object source) { - return comment.getContent(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.command.ModifyCommand#setValue(java.lang.Object, - * java.lang.Object) - */ - @Override - protected void setValue(Object source, Object value) { - comment.setContent((String) value); - } - -} +package org.xmind.ui.commands; + +import org.xmind.core.IComment; +import org.xmind.gef.command.ModifyCommand; +import org.xmind.ui.internal.MindMapMessages; + +public class ModifyCommentCommand extends ModifyCommand { + + private IComment comment; + + public ModifyCommentCommand(Object target, IComment comment, + String newValue) { + super(target, newValue); + this.comment = comment; + super.setLabel(MindMapMessages.ModifyComment_label); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.command.ModifyCommand#getValue(java.lang.Object) + */ + @Override + protected Object getValue(Object source) { + return comment.getContent(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.command.ModifyCommand#setValue(java.lang.Object, + * java.lang.Object) + */ + @Override + protected void setValue(Object source, Object value) { + comment.setContent((String) value); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyFoldedCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyFoldedCommand.java index db7dc4fbc..70ffcf1d8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyFoldedCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyFoldedCommand.java @@ -1,134 +1,134 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; -import org.xmind.ui.internal.ModelCacheManager; - -public class ModifyFoldedCommand extends ModifyCommand { - - public ModifyFoldedCommand(ITopic source, boolean newFolded) { - super(source, Boolean.valueOf(newFolded)); - } - - public ModifyFoldedCommand(Collection sources, - boolean newFolded) { - super(sources, Boolean.valueOf(newFolded)); - } - - public ModifyFoldedCommand(ISourceProvider sourceProvider, - boolean newFolded) { - super(sourceProvider, Boolean.valueOf(newFolded)); - } - - protected Object getValue(Object source) { - if (source instanceof ITopic) { - return Boolean.valueOf(((ITopic) source).isFolded()); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITopic && value instanceof Boolean) { - ((ITopic) source).setFolded(((Boolean) value).booleanValue()); - } - } - - @Override - protected void setNewValues() { - List sourcesToChange = filterSameValueSources(getSources(), - false); - List rootParents = filterRootParents(sourcesToChange); - for (Object source : getSources()) { - if (!rootParents.contains(source)) { - ModelCacheManager.getInstance().setCache(source, - ModelCacheManager.MODEL_CACHE_DELAYLAYOUT, - Boolean.TRUE); - setValue(source, getNewValue()); - ModelCacheManager.getInstance().flush(source, - ModelCacheManager.MODEL_CACHE_DELAYLAYOUT); - } - } - - for (Object rootParent : rootParents) { - setValue(rootParent, getNewValue()); - } - } - - @Override - protected void setOldValues() { - List sourcesToChange = filterSameValueSources(getSources(), - true); - List rootParents = filterRootParents(sourcesToChange); - for (Object source : getSources()) { - if (!rootParents.contains(source)) { - ModelCacheManager.getInstance().setCache(source, - ModelCacheManager.MODEL_CACHE_DELAYLAYOUT, - Boolean.TRUE); - setValue(source, getOldValue(source)); - ModelCacheManager.getInstance().flush(source, - ModelCacheManager.MODEL_CACHE_DELAYLAYOUT); - } - } - - for (Object rootParent : rootParents) { - setValue(rootParent, getOldValue(rootParent)); - } - } - - private List filterSameValueSources(List sources, - boolean oldValueOrNewValue) { - ArrayList result = new ArrayList(sources.size()); - for (Object topic : sources) { - if (topic instanceof ITopic) { - Object value = oldValueOrNewValue ? getOldValue(topic) - : getNewValue(); - boolean folded = ((ITopic) topic).isFolded(); - if (value instanceof Boolean && !value.toString() - .equals(Boolean.valueOf(folded).toString())) - result.add(topic); - } - } - return result; - } - - private List filterRootParents(List topics) { - ArrayList result = new ArrayList(topics.size()); - for (Object topic : topics) { - if (topic instanceof ITopic - && !branchContains((ITopic) topic, topics)) { - result.add(topic); - } - } - return result; - } - - private boolean branchContains(ITopic topic, List topics) { - boolean contains = false; - ITopic parent = topic.getParent(); - if (parent != null) { - contains = topics.contains(parent); - if (!contains) { - contains = branchContains(parent, topics); - } - } - return contains; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; +import org.xmind.ui.internal.ModelCacheManager; + +public class ModifyFoldedCommand extends ModifyCommand { + + public ModifyFoldedCommand(ITopic source, boolean newFolded) { + super(source, Boolean.valueOf(newFolded)); + } + + public ModifyFoldedCommand(Collection sources, + boolean newFolded) { + super(sources, Boolean.valueOf(newFolded)); + } + + public ModifyFoldedCommand(ISourceProvider sourceProvider, + boolean newFolded) { + super(sourceProvider, Boolean.valueOf(newFolded)); + } + + protected Object getValue(Object source) { + if (source instanceof ITopic) { + return Boolean.valueOf(((ITopic) source).isFolded()); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITopic && value instanceof Boolean) { + ((ITopic) source).setFolded(((Boolean) value).booleanValue()); + } + } + + @Override + protected void setNewValues() { + List sourcesToChange = filterSameValueSources(getSources(), + false); + List rootParents = filterRootParents(sourcesToChange); + for (Object source : getSources()) { + if (!rootParents.contains(source)) { + ModelCacheManager.getInstance().setCache(source, + ModelCacheManager.MODEL_CACHE_DELAYLAYOUT, + Boolean.TRUE); + setValue(source, getNewValue()); + ModelCacheManager.getInstance().flush(source, + ModelCacheManager.MODEL_CACHE_DELAYLAYOUT); + } + } + + for (Object rootParent : rootParents) { + setValue(rootParent, getNewValue()); + } + } + + @Override + protected void setOldValues() { + List sourcesToChange = filterSameValueSources(getSources(), + true); + List rootParents = filterRootParents(sourcesToChange); + for (Object source : getSources()) { + if (!rootParents.contains(source)) { + ModelCacheManager.getInstance().setCache(source, + ModelCacheManager.MODEL_CACHE_DELAYLAYOUT, + Boolean.TRUE); + setValue(source, getOldValue(source)); + ModelCacheManager.getInstance().flush(source, + ModelCacheManager.MODEL_CACHE_DELAYLAYOUT); + } + } + + for (Object rootParent : rootParents) { + setValue(rootParent, getOldValue(rootParent)); + } + } + + private List filterSameValueSources(List sources, + boolean oldValueOrNewValue) { + ArrayList result = new ArrayList(sources.size()); + for (Object topic : sources) { + if (topic instanceof ITopic) { + Object value = oldValueOrNewValue ? getOldValue(topic) + : getNewValue(); + boolean folded = ((ITopic) topic).isFolded(); + if (value instanceof Boolean && !value.toString() + .equals(Boolean.valueOf(folded).toString())) + result.add(topic); + } + } + return result; + } + + private List filterRootParents(List topics) { + ArrayList result = new ArrayList(topics.size()); + for (Object topic : topics) { + if (topic instanceof ITopic + && !branchContains((ITopic) topic, topics)) { + result.add(topic); + } + } + return result; + } + + private boolean branchContains(ITopic topic, List topics) { + boolean contains = false; + ITopic parent = topic.getParent(); + if (parent != null) { + contains = topics.contains(parent); + if (!contains) { + contains = branchContains(parent, topics); + } + } + return contains; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageAlignmentCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageAlignmentCommand.java index fe75bbbb5..1c6f46dca 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageAlignmentCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageAlignmentCommand.java @@ -1,68 +1,68 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.IImage; -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyImageAlignmentCommand extends ModifyCommand { - - public ModifyImageAlignmentCommand(IImage image, String newAlignment) { - super(image, newAlignment); - } - - public ModifyImageAlignmentCommand(ITopic topic, String newAlignment) { - super(topic, newAlignment); - } - - public ModifyImageAlignmentCommand(Collection images, - String newAlignment) { - super(images, newAlignment); - } - - public ModifyImageAlignmentCommand(ISourceProvider topicOrImageProvider, - String newAlignment) { - super(topicOrImageProvider, newAlignment); - } - - protected Object getValue(Object source) { - IImage image = getImage(source); - if (image != null) - return image.getAlignment(); - return null; - } - - protected void setValue(Object source, Object value) { - IImage image = getImage(source); - if (image != null) { - if (value instanceof String) { - image.setAlignment((String) value); - } else { - image.setAlignment(null); - } - } - } - - private IImage getImage(Object source) { - if (source instanceof IImage) - return (IImage) source; - if (source instanceof ITopic) - return ((ITopic) source).getImage(); - return null; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.IImage; +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyImageAlignmentCommand extends ModifyCommand { + + public ModifyImageAlignmentCommand(IImage image, String newAlignment) { + super(image, newAlignment); + } + + public ModifyImageAlignmentCommand(ITopic topic, String newAlignment) { + super(topic, newAlignment); + } + + public ModifyImageAlignmentCommand(Collection images, + String newAlignment) { + super(images, newAlignment); + } + + public ModifyImageAlignmentCommand(ISourceProvider topicOrImageProvider, + String newAlignment) { + super(topicOrImageProvider, newAlignment); + } + + protected Object getValue(Object source) { + IImage image = getImage(source); + if (image != null) + return image.getAlignment(); + return null; + } + + protected void setValue(Object source, Object value) { + IImage image = getImage(source); + if (image != null) { + if (value instanceof String) { + image.setAlignment((String) value); + } else { + image.setAlignment(null); + } + } + } + + private IImage getImage(Object source) { + if (source instanceof IImage) + return (IImage) source; + if (source instanceof ITopic) + return ((ITopic) source).getImage(); + return null; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSizeCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSizeCommand.java index 7cecdc08a..d4876252d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSizeCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSizeCommand.java @@ -1,73 +1,73 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.IImage; -import org.xmind.core.ITopic; -import org.xmind.core.util.Point; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyImageSizeCommand extends ModifyCommand { - - public ModifyImageSizeCommand(IImage image, int width, int height) { - super(image, new Point(width, height)); - } - - public ModifyImageSizeCommand(ITopic topic, int width, int height) { - super(topic, new Point(width, height)); - } - - public ModifyImageSizeCommand(Collection images, - int width, int height) { - super(images, new Point(width, height)); - } - - public ModifyImageSizeCommand(ISourceProvider topicOrImageProvider, - int width, int height) { - super(topicOrImageProvider, new Point(width, height)); - } - - protected Object getValue(Object source) { - IImage image = getImage(source); - if (image != null) { - int width = image.getWidth(); - int height = image.getHeight(); - return new Point(width, height); - } - return null; - } - - protected void setValue(Object source, Object value) { - IImage image = getImage(source); - if (image != null) { - if (value == null) { - image.setSize(IImage.UNSPECIFIED, IImage.UNSPECIFIED); - } else if (value instanceof Point) { - Point size = (Point) value; - image.setSize(size.x, size.y); - } - } - } - - private IImage getImage(Object source) { - if (source instanceof IImage) - return (IImage) source; - if (source instanceof ITopic) - return ((ITopic) source).getImage(); - return null; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.IImage; +import org.xmind.core.ITopic; +import org.xmind.core.util.Point; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyImageSizeCommand extends ModifyCommand { + + public ModifyImageSizeCommand(IImage image, int width, int height) { + super(image, new Point(width, height)); + } + + public ModifyImageSizeCommand(ITopic topic, int width, int height) { + super(topic, new Point(width, height)); + } + + public ModifyImageSizeCommand(Collection images, + int width, int height) { + super(images, new Point(width, height)); + } + + public ModifyImageSizeCommand(ISourceProvider topicOrImageProvider, + int width, int height) { + super(topicOrImageProvider, new Point(width, height)); + } + + protected Object getValue(Object source) { + IImage image = getImage(source); + if (image != null) { + int width = image.getWidth(); + int height = image.getHeight(); + return new Point(width, height); + } + return null; + } + + protected void setValue(Object source, Object value) { + IImage image = getImage(source); + if (image != null) { + if (value == null) { + image.setSize(IImage.UNSPECIFIED, IImage.UNSPECIFIED); + } else if (value instanceof Point) { + Point size = (Point) value; + image.setSize(size.x, size.y); + } + } + } + + private IImage getImage(Object source) { + if (source instanceof IImage) + return (IImage) source; + if (source instanceof ITopic) + return ((ITopic) source).getImage(); + return null; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSourceCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSourceCommand.java index 6133451b0..97255ccf8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSourceCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyImageSourceCommand.java @@ -1,69 +1,69 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.IImage; -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyImageSourceCommand extends ModifyCommand { - - public ModifyImageSourceCommand(ITopic topic, String newValue) { - super(topic, newValue); - } - - public ModifyImageSourceCommand(IImage image, String newValue) { - super(image, newValue); - } - - public ModifyImageSourceCommand(ISourceProvider topicOrImageProvider, - String newValue) { - super(topicOrImageProvider, newValue); - } - - public ModifyImageSourceCommand(Collection images, - String newValue) { - super(images, newValue); - } - - protected Object getValue(Object source) { - IImage image = getImage(source); - if (image != null) { - return image.getSource(); - } - return null; - } - - protected void setValue(Object source, Object value) { - IImage image = getImage(source); - if (image != null) { - if (value == null) { - image.setSource(null); - } else if (value instanceof String) { - image.setSource((String) value); - } - } - } - - private IImage getImage(Object source) { - if (source instanceof IImage) - return (IImage) source; - if (source instanceof ITopic) - return ((ITopic) source).getImage(); - return null; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.IImage; +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyImageSourceCommand extends ModifyCommand { + + public ModifyImageSourceCommand(ITopic topic, String newValue) { + super(topic, newValue); + } + + public ModifyImageSourceCommand(IImage image, String newValue) { + super(image, newValue); + } + + public ModifyImageSourceCommand(ISourceProvider topicOrImageProvider, + String newValue) { + super(topicOrImageProvider, newValue); + } + + public ModifyImageSourceCommand(Collection images, + String newValue) { + super(images, newValue); + } + + protected Object getValue(Object source) { + IImage image = getImage(source); + if (image != null) { + return image.getSource(); + } + return null; + } + + protected void setValue(Object source, Object value) { + IImage image = getImage(source); + if (image != null) { + if (value == null) { + image.setSource(null); + } else if (value instanceof String) { + image.setSource((String) value); + } + } + } + + private IImage getImage(Object source) { + if (source instanceof IImage) + return (IImage) source; + if (source instanceof ITopic) + return ((ITopic) source).getImage(); + return null; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLabelCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLabelCommand.java index 4ad93d703..dcf11bfc0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLabelCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLabelCommand.java @@ -1,56 +1,56 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.ILabeled; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyLabelCommand extends ModifyCommand { - - public ModifyLabelCommand(Collection sources, - Collection newLabels) { - super(sources, newLabels); - } - - public ModifyLabelCommand(ISourceProvider sourceProvider, - Collection newLabels) { - super(sourceProvider, newLabels); - } - - public ModifyLabelCommand(ILabeled source, Collection newLabels) { - super(source, newLabels); - } - - protected Object getValue(Object source) { - if (source instanceof ILabeled) { - return ((ILabeled) source).getLabels(); - } - return null; - } - - @SuppressWarnings("unchecked") - protected void setValue(Object source, Object value) { - if (source instanceof ILabeled) { - ILabeled labeled = (ILabeled) source; - if (value instanceof Collection) { - Collection labels = (Collection) value; - labeled.setLabels(labels); - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.ILabeled; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyLabelCommand extends ModifyCommand { + + public ModifyLabelCommand(Collection sources, + Collection newLabels) { + super(sources, newLabels); + } + + public ModifyLabelCommand(ISourceProvider sourceProvider, + Collection newLabels) { + super(sourceProvider, newLabels); + } + + public ModifyLabelCommand(ILabeled source, Collection newLabels) { + super(source, newLabels); + } + + protected Object getValue(Object source) { + if (source instanceof ILabeled) { + return ((ILabeled) source).getLabels(); + } + return null; + } + + @SuppressWarnings("unchecked") + protected void setValue(Object source, Object value) { + if (source instanceof ILabeled) { + ILabeled labeled = (ILabeled) source; + if (value instanceof Collection) { + Collection labels = (Collection) value; + labeled.setLabels(labels); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLegendVisibilityCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLegendVisibilityCommand.java index 742e6333b..12ff214fa 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLegendVisibilityCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyLegendVisibilityCommand.java @@ -16,6 +16,7 @@ import java.util.Collection; import org.xmind.core.ILegend; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ISourceProvider; import org.xmind.gef.command.ModifyCommand; import org.xmind.ui.internal.MindMapUIPlugin; @@ -56,7 +57,7 @@ protected void setValue(Object source, Object value) { @Override public void execute() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ShowLegendCount"); //$NON-NLS-1$ + .increase(UserDataConstants.SHOW_LEGEND_COUNT); super.execute(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyMetadataCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyMetadataCommand.java index a142b00fc..542cc8aa3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyMetadataCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyMetadataCommand.java @@ -1,33 +1,33 @@ -package org.xmind.ui.commands; - -import org.xmind.core.IWorkbook; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyMetadataCommand extends ModifyCommand { - - private String keyPath; - - public ModifyMetadataCommand(ISourceProvider workbookProvider, - String keyPath, String newValue) { - super(workbookProvider, newValue); - this.keyPath = keyPath; - } - - public ModifyMetadataCommand(IWorkbook workbook, String keyPath, - String newValue) { - super(workbook, newValue); - this.keyPath = keyPath; - } - - @Override - protected Object getValue(Object source) { - return ((IWorkbook) source).getMeta().getValue(keyPath); - } - - @Override - protected void setValue(Object source, Object value) { - ((IWorkbook) source).getMeta().setValue(keyPath, (String) value); - } - -} +package org.xmind.ui.commands; + +import org.xmind.core.IWorkbook; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyMetadataCommand extends ModifyCommand { + + private String keyPath; + + public ModifyMetadataCommand(ISourceProvider workbookProvider, + String keyPath, String newValue) { + super(workbookProvider, newValue); + this.keyPath = keyPath; + } + + public ModifyMetadataCommand(IWorkbook workbook, String keyPath, + String newValue) { + super(workbook, newValue); + this.keyPath = keyPath; + } + + @Override + protected Object getValue(Object source) { + return ((IWorkbook) source).getMeta().getValue(keyPath); + } + + @Override + protected void setValue(Object source, Object value) { + ((IWorkbook) source).getMeta().setValue(keyPath, (String) value); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNotesCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNotesCommand.java index 5aae9c563..0237ecf15 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNotesCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNotesCommand.java @@ -1,68 +1,68 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.INotesContent; -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyNotesCommand extends ModifyCommand { - - private String format; - - public ModifyNotesCommand(Collection topics, - INotesContent newValue, String format) { - super(topics, newValue); - Assert.isNotNull(format); - this.format = format; - } - - public ModifyNotesCommand(ISourceProvider topicProvider, - INotesContent newValue, String format) { - super(topicProvider, newValue); - Assert.isNotNull(format); - this.format = format; - } - - public ModifyNotesCommand(ITopic topic, INotesContent newValue, - String format) { - super(topic, newValue); - Assert.isNotNull(format); - this.format = format; - } - - protected Object getValue(Object source) { - if (source instanceof ITopic) { - ITopic topic = (ITopic) source; - return topic.getNotes().getContent(format); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITopic) { - ITopic topic = (ITopic) source; - if (value instanceof INotesContent) { - topic.getNotes().setContent(format, (INotesContent) value); - } else if (value == null) { - topic.getNotes().setContent(format, null); - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.INotesContent; +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyNotesCommand extends ModifyCommand { + + private String format; + + public ModifyNotesCommand(Collection topics, + INotesContent newValue, String format) { + super(topics, newValue); + Assert.isNotNull(format); + this.format = format; + } + + public ModifyNotesCommand(ISourceProvider topicProvider, + INotesContent newValue, String format) { + super(topicProvider, newValue); + Assert.isNotNull(format); + this.format = format; + } + + public ModifyNotesCommand(ITopic topic, INotesContent newValue, + String format) { + super(topic, newValue); + Assert.isNotNull(format); + this.format = format; + } + + protected Object getValue(Object source) { + if (source instanceof ITopic) { + ITopic topic = (ITopic) source; + return topic.getNotes().getContent(format); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITopic) { + ITopic topic = (ITopic) source; + if (value instanceof INotesContent) { + topic.getNotes().setContent(format, (INotesContent) value); + } else if (value == null) { + topic.getNotes().setContent(format, null); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNumberingDepthCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNumberingDepthCommand.java index 57bd6bc4b..d7c360fdc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNumberingDepthCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNumberingDepthCommand.java @@ -1,44 +1,44 @@ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyNumberingDepthCommand extends ModifyCommand { - - public ModifyNumberingDepthCommand(ITopic topic, String newDepth) { - super(topic, newDepth); - } - - public ModifyNumberingDepthCommand(Collection topics, - String newDepth) { - super(topics, newDepth); - } - - public ModifyNumberingDepthCommand(ISourceProvider topicProvider, - String newDepth) { - super(topicProvider, newDepth); - } - - @Override - protected Object getValue(Object source) { - if (source instanceof ITopic) - return ((ITopic) source).getNumbering().getComputedDepth(); - return null; - } - - @Override - protected void setValue(Object source, Object value) { - if (source instanceof ITopic) { - ITopic topic = (ITopic) source; - if (value instanceof String) { - topic.getNumbering().setDepth((String) value); - } else if (value == null) { - topic.getNumbering().setDepth(null); - } - } - } - -} +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyNumberingDepthCommand extends ModifyCommand { + + public ModifyNumberingDepthCommand(ITopic topic, String newDepth) { + super(topic, newDepth); + } + + public ModifyNumberingDepthCommand(Collection topics, + String newDepth) { + super(topics, newDepth); + } + + public ModifyNumberingDepthCommand(ISourceProvider topicProvider, + String newDepth) { + super(topicProvider, newDepth); + } + + @Override + protected Object getValue(Object source) { + if (source instanceof ITopic) + return ((ITopic) source).getNumbering().getComputedDepth(); + return null; + } + + @Override + protected void setValue(Object source, Object value) { + if (source instanceof ITopic) { + ITopic topic = (ITopic) source; + if (value instanceof String) { + topic.getNumbering().setDepth((String) value); + } else if (value == null) { + topic.getNumbering().setDepth(null); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyPositionCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyPositionCommand.java index bec0926df..9812652f0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyPositionCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyPositionCommand.java @@ -1,53 +1,53 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.IPositioned; -import org.xmind.core.util.Point; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyPositionCommand extends ModifyCommand { - - public ModifyPositionCommand(IPositioned source, Point newValue) { - super(source, newValue); - } - - public ModifyPositionCommand(Collection sources, - Point newValue) { - super(sources, newValue); - } - - public ModifyPositionCommand(ISourceProvider sourceProvider, Point newValue) { - super(sourceProvider, newValue); - } - - protected Object getValue(Object source) { - if (source instanceof IPositioned) { - IPositioned t = (IPositioned) source; - return t.getPosition(); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof IPositioned - && (value == null || value instanceof Point)) { - ((IPositioned) source).setPosition((Point) value); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.IPositioned; +import org.xmind.core.util.Point; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyPositionCommand extends ModifyCommand { + + public ModifyPositionCommand(IPositioned source, Point newValue) { + super(source, newValue); + } + + public ModifyPositionCommand(Collection sources, + Point newValue) { + super(sources, newValue); + } + + public ModifyPositionCommand(ISourceProvider sourceProvider, Point newValue) { + super(sourceProvider, newValue); + } + + protected Object getValue(Object source) { + if (source instanceof IPositioned) { + IPositioned t = (IPositioned) source; + return t.getPosition(); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof IPositioned + && (value == null || value instanceof Point)) { + ((IPositioned) source).setPosition((Point) value); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyRightNumberOfUnbalancedStructureCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyRightNumberOfUnbalancedStructureCommand.java index ada194344..41a36e510 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyRightNumberOfUnbalancedStructureCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyRightNumberOfUnbalancedStructureCommand.java @@ -1,61 +1,61 @@ -package org.xmind.ui.commands; - -import org.eclipse.core.runtime.Assert; -import org.xmind.core.Core; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.gef.command.SourceCommand; -import org.xmind.ui.internal.branch.UnbalancedData; - -public class ModifyRightNumberOfUnbalancedStructureCommand extends - SourceCommand { - private ITopic topic = null; - private String preNum; - private int postNum; - - public ModifyRightNumberOfUnbalancedStructureCommand(ITopic topic, - String preNum, int postNum) { - Assert.isNotNull(topic); - this.topic = topic; - this.preNum = preNum; - this.postNum = postNum; - } - - public void redo() { - ITopicExtension extension = topic - .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild(UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - element.setTextContent(String.valueOf(postNum)); - fireForceStructureChange(); - super.redo(); - } - - public void undo() { - ITopicExtension extension = topic - .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild(UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - element.setTextContent(preNum); - fireForceStructureChange(); - super.undo(); - } - - private void fireForceStructureChange() { - if (!(topic instanceof ICoreEventSource)) - return; - - ICoreEventSource source = (ICoreEventSource) topic; - String eventType = Core.StructureClass; - String structureClass = topic.getStructureClass(); - source.getCoreEventSupport() - .dispatch( - source, - new CoreEvent(source, eventType, structureClass, - structureClass)); - } - -} +package org.xmind.ui.commands; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.Core; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.gef.command.SourceCommand; +import org.xmind.ui.internal.branch.UnbalancedData; + +public class ModifyRightNumberOfUnbalancedStructureCommand extends + SourceCommand { + private ITopic topic = null; + private String preNum; + private int postNum; + + public ModifyRightNumberOfUnbalancedStructureCommand(ITopic topic, + String preNum, int postNum) { + Assert.isNotNull(topic); + this.topic = topic; + this.preNum = preNum; + this.postNum = postNum; + } + + public void redo() { + ITopicExtension extension = topic + .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild(UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + element.setTextContent(String.valueOf(postNum)); + fireForceStructureChange(); + super.redo(); + } + + public void undo() { + ITopicExtension extension = topic + .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild(UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + element.setTextContent(preNum); + fireForceStructureChange(); + super.undo(); + } + + private void fireForceStructureChange() { + if (!(topic instanceof ICoreEventSource)) + return; + + ICoreEventSource source = (ICoreEventSource) topic; + String eventType = Core.StructureClass; + String structureClass = topic.getStructureClass(); + source.getCoreEventSupport() + .dispatch( + source, + new CoreEvent(source, eventType, structureClass, + structureClass)); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java index 60a193e71..3cb78c737 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java @@ -1,58 +1,58 @@ -package org.xmind.ui.commands; - -import java.util.List; - -import org.xmind.core.ISettingEntry; -import org.xmind.core.ISheet; -import org.xmind.core.ISheetSettings; -import org.xmind.gef.command.ModifyCommand; -import org.xmind.ui.internal.MindMapMessages; - -public class ModifySheetTabColorCommand extends ModifyCommand { - - public ModifySheetTabColorCommand(ISheet source, String rgb) { - super(source, rgb); - setLabel(MindMapMessages.ModifySheetTabColorCommand_label); - } - - @Override - protected Object getValue(Object source) { - if (source instanceof ISheet) { - return getRgb((ISheet) source); - } - return null; - } - - @Override - protected void setValue(Object source, Object value) { - if (source instanceof ISheet && value instanceof String) { - String oldValue = getRgb((ISheet) source); - if (value.equals(oldValue)) { - return; - } - setRgb((ISheet) source, (String) value); - } - } - - private String getRgb(ISheet sheet) { - ISettingEntry entry = findEntry(sheet); - return entry == null ? null - : entry.getAttribute(ISheetSettings.ATTR_RGB); - } - - private void setRgb(ISheet sheet, String rgb) { - ISettingEntry entry = findEntry(sheet); - if (entry == null) { - entry = sheet.getSettings().createEntry(ISheetSettings.TAB_COLOR); - sheet.getSettings().addEntry(entry); - } - entry.setAttribute(ISheetSettings.ATTR_RGB, rgb); - } - - private ISettingEntry findEntry(ISheet sheet) { - List entries = sheet.getSettings() - .getEntries(ISheetSettings.TAB_COLOR); - return entries.size() == 0 ? null : entries.get(0); - } - -} +package org.xmind.ui.commands; + +import java.util.List; + +import org.xmind.core.ISettingEntry; +import org.xmind.core.ISheet; +import org.xmind.core.ISheetSettings; +import org.xmind.gef.command.ModifyCommand; +import org.xmind.ui.internal.MindMapMessages; + +public class ModifySheetTabColorCommand extends ModifyCommand { + + public ModifySheetTabColorCommand(ISheet source, String rgb) { + super(source, rgb); + setLabel(MindMapMessages.ModifySheetTabColorCommand_label); + } + + @Override + protected Object getValue(Object source) { + if (source instanceof ISheet) { + return getRgb((ISheet) source); + } + return null; + } + + @Override + protected void setValue(Object source, Object value) { + if (source instanceof ISheet && value instanceof String) { + String oldValue = getRgb((ISheet) source); + if (value.equals(oldValue)) { + return; + } + setRgb((ISheet) source, (String) value); + } + } + + private String getRgb(ISheet sheet) { + ISettingEntry entry = findEntry(sheet); + return entry == null ? null + : entry.getAttribute(ISheetSettings.ATTR_RGB); + } + + private void setRgb(ISheet sheet, String rgb) { + ISettingEntry entry = findEntry(sheet); + if (entry == null) { + entry = sheet.getSettings().createEntry(ISheetSettings.TAB_COLOR); + sheet.getSettings().addEntry(entry); + } + entry.setAttribute(ISheetSettings.ATTR_RGB, rgb); + } + + private ISettingEntry findEntry(ISheet sheet) { + List entries = sheet.getSettings() + .getEntries(ISheetSettings.TAB_COLOR); + return entries.size() == 0 ? null : entries.get(0); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyStyleCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyStyleCommand.java index afd1859a5..1457de0a4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyStyleCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyStyleCommand.java @@ -1,66 +1,66 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyled; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyStyleCommand extends ModifyCommand { - - public ModifyStyleCommand(IStyled source, String newStyleId) { - super(source, newStyleId); - } - - public ModifyStyleCommand(ISourceProvider sourceProvider, String newStyleId) { - super(sourceProvider, newStyleId); - } - - public ModifyStyleCommand(IStyled source, ISourceProvider newStyleProvider) { - super(source, newStyleProvider); - } - - public ModifyStyleCommand(ISourceProvider sourceProvider, - ISourceProvider newStyleProvider) { - super(sourceProvider, newStyleProvider); - } - - protected Object getValue(Object source) { - if (source instanceof IStyled) { - return ((IStyled) source).getStyleId(); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof IStyled) { - IStyled styledSource = (IStyled) source; - if (value instanceof ISourceProvider) { - Object newStyle = ((ISourceProvider) value).getSource(); - if (newStyle instanceof String) { - value = (String) newStyle; - } else if (newStyle instanceof IStyle) { - value = ((IStyle) newStyle).getId(); - } else if (newStyle instanceof IStyled) { - value = ((IStyled) newStyle).getStyleId(); - } - } - if (value == null || value instanceof String) { - styledSource.setStyleId((String) value); - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyled; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyStyleCommand extends ModifyCommand { + + public ModifyStyleCommand(IStyled source, String newStyleId) { + super(source, newStyleId); + } + + public ModifyStyleCommand(ISourceProvider sourceProvider, String newStyleId) { + super(sourceProvider, newStyleId); + } + + public ModifyStyleCommand(IStyled source, ISourceProvider newStyleProvider) { + super(source, newStyleProvider); + } + + public ModifyStyleCommand(ISourceProvider sourceProvider, + ISourceProvider newStyleProvider) { + super(sourceProvider, newStyleProvider); + } + + protected Object getValue(Object source) { + if (source instanceof IStyled) { + return ((IStyled) source).getStyleId(); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof IStyled) { + IStyled styledSource = (IStyled) source; + if (value instanceof ISourceProvider) { + Object newStyle = ((ISourceProvider) value).getSource(); + if (newStyle instanceof String) { + value = (String) newStyle; + } else if (newStyle instanceof IStyle) { + value = ((IStyle) newStyle).getId(); + } else if (newStyle instanceof IStyled) { + value = ((IStyled) newStyle).getStyleId(); + } + } + if (value == null || value instanceof String) { + styledSource.setStyleId((String) value); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTitleTextCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTitleTextCommand.java index 20601b69c..c92edb044 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTitleTextCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTitleTextCommand.java @@ -1,54 +1,54 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.ITitled; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyTitleTextCommand extends ModifyCommand { - - public ModifyTitleTextCommand(Collection sources, - String newValue) { - super(sources, newValue); - } - - public ModifyTitleTextCommand(ITitled source, String newValue) { - super(source, newValue); - } - - public ModifyTitleTextCommand(ISourceProvider sourceProvider, - String newValue) { - super(sourceProvider, newValue); - } - - protected Object getValue(Object source) { - if (source instanceof ITitled) { - ITitled t = (ITitled) source; - if (t.hasTitle()) - return t.getTitleText(); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITitled - && (value == null || value instanceof String)) { - ((ITitled) source).setTitleText((String) value); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.ITitled; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyTitleTextCommand extends ModifyCommand { + + public ModifyTitleTextCommand(Collection sources, + String newValue) { + super(sources, newValue); + } + + public ModifyTitleTextCommand(ITitled source, String newValue) { + super(source, newValue); + } + + public ModifyTitleTextCommand(ISourceProvider sourceProvider, + String newValue) { + super(sourceProvider, newValue); + } + + protected Object getValue(Object source) { + if (source instanceof ITitled) { + ITitled t = (ITitled) source; + if (t.hasTitle()) + return t.getTitleText(); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITitled + && (value == null || value instanceof String)) { + ((ITitled) source).setTitleText((String) value); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicHyperlinkCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicHyperlinkCommand.java index 631dbcf55..73a88f05c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicHyperlinkCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicHyperlinkCommand.java @@ -1,52 +1,52 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyTopicHyperlinkCommand extends ModifyCommand { - - public ModifyTopicHyperlinkCommand(ITopic source, String newValue) { - super(source, newValue); - } - - public ModifyTopicHyperlinkCommand(Collection sources, - String newValue) { - super(sources, newValue); - } - - public ModifyTopicHyperlinkCommand(ISourceProvider sourceProvider, - String newValue) { - super(sourceProvider, newValue); - } - - protected Object getValue(Object source) { - if (source instanceof ITopic) - return ((ITopic) source).getHyperlink(); - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITopic - && (value == null || value instanceof String)) { - ITopic topic = (ITopic) source; - String href = (String) value; - topic.setHyperlink(href); - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyTopicHyperlinkCommand extends ModifyCommand { + + public ModifyTopicHyperlinkCommand(ITopic source, String newValue) { + super(source, newValue); + } + + public ModifyTopicHyperlinkCommand(Collection sources, + String newValue) { + super(sources, newValue); + } + + public ModifyTopicHyperlinkCommand(ISourceProvider sourceProvider, + String newValue) { + super(sourceProvider, newValue); + } + + protected Object getValue(Object source) { + if (source instanceof ITopic) + return ((ITopic) source).getHyperlink(); + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITopic + && (value == null || value instanceof String)) { + ITopic topic = (ITopic) source; + String href = (String) value; + topic.setHyperlink(href); + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicStructureCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicStructureCommand.java index 8aa4fee51..f92aa7900 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicStructureCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicStructureCommand.java @@ -1,114 +1,115 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.ui.ISourceProvider; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.gef.command.ModifyCommand; -import org.xmind.ui.internal.MindMapUIPlugin; - -public class ModifyTopicStructureCommand extends ModifyCommand { - - private final static String STRUCTUREID_UNBALANCED = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - private final static String EXTENTION_UNBALANCEDSTRUCTURE = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - private final static String EXTENTIONELEMENT_RIGHTNUMBER = "right-number";//$NON-NLS-1$ - private final static String INVALID_RIGHT_NUMBER = "-1"; //$NON-NLS-1$ - - private Map extToRightNum = new HashMap(); - - public ModifyTopicStructureCommand(ITopic source, - String newStructureClass) { - super(source, newStructureClass); - ITopicExtension topicExtension = source - .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); - if (topicExtension != null) { - String rightNum = topicExtension.getContent() - .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) - .getTextContent(); - extToRightNum.put(topicExtension, rightNum); - } - - } - - public ModifyTopicStructureCommand(Collection sources, - String newStructureClass) { - super(sources, newStructureClass); - for (ITopic topic : sources) { - ITopicExtension extension = topic - .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); - if (extension != null) { - String rightNum = extension.getContent() - .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) - .getTextContent(); - extToRightNum.put(extension, rightNum); - } - } - } - - public ModifyTopicStructureCommand(ISourceProvider sourceProvider, - String newStructureClass) { - super(sourceProvider, newStructureClass); - } - - protected Object getValue(Object source) { - if (source instanceof ITopic) { - return ((ITopic) source).getStructureClass(); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITopic) { - ITopic topic = (ITopic) source; - if (value == null || value instanceof String) { - String oldStructure = topic.getStructureClass(); - if (STRUCTUREID_UNBALANCED.equals(oldStructure)) { - ITopicExtension extension = topic - .createExtension(EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement rightNum = extension.getContent() - .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER); - rightNum.setTextContent(INVALID_RIGHT_NUMBER); - - } else if (STRUCTUREID_UNBALANCED.equals(value)) { - ITopicExtension extension = topic - .createExtension(EXTENTION_UNBALANCEDSTRUCTURE); - boolean has = extToRightNum.containsKey(extension); - if (has) { - String rightNum = extToRightNum.get(extension); - extension.getContent() - .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) - .setTextContent(rightNum); - } - } - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("StructureTypeCount:" + value); //$NON-NLS-1$ - topic.setStructureClass((String) value); - } - } - } - - @Override - public void execute() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ModifyStructureCount"); //$NON-NLS-1$ - super.execute(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ui.ISourceProvider; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.gef.command.ModifyCommand; +import org.xmind.ui.internal.MindMapUIPlugin; + +public class ModifyTopicStructureCommand extends ModifyCommand { + + private final static String STRUCTUREID_UNBALANCED = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + private final static String EXTENTION_UNBALANCEDSTRUCTURE = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + private final static String EXTENTIONELEMENT_RIGHTNUMBER = "right-number";//$NON-NLS-1$ + private final static String INVALID_RIGHT_NUMBER = "-1"; //$NON-NLS-1$ + + private Map extToRightNum = new HashMap(); + + public ModifyTopicStructureCommand(ITopic source, + String newStructureClass) { + super(source, newStructureClass); + ITopicExtension topicExtension = source + .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); + if (topicExtension != null) { + String rightNum = topicExtension.getContent() + .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) + .getTextContent(); + extToRightNum.put(topicExtension, rightNum); + } + + } + + public ModifyTopicStructureCommand(Collection sources, + String newStructureClass) { + super(sources, newStructureClass); + for (ITopic topic : sources) { + ITopicExtension extension = topic + .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); + if (extension != null) { + String rightNum = extension.getContent() + .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) + .getTextContent(); + extToRightNum.put(extension, rightNum); + } + } + } + + public ModifyTopicStructureCommand(ISourceProvider sourceProvider, + String newStructureClass) { + super(sourceProvider, newStructureClass); + } + + protected Object getValue(Object source) { + if (source instanceof ITopic) { + return ((ITopic) source).getStructureClass(); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITopic) { + ITopic topic = (ITopic) source; + if (value == null || value instanceof String) { + String oldStructure = topic.getStructureClass(); + if (STRUCTUREID_UNBALANCED.equals(oldStructure)) { + ITopicExtension extension = topic + .createExtension(EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement rightNum = extension.getContent() + .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER); + rightNum.setTextContent(INVALID_RIGHT_NUMBER); + + } else if (STRUCTUREID_UNBALANCED.equals(value)) { + ITopicExtension extension = topic + .createExtension(EXTENTION_UNBALANCEDSTRUCTURE); + boolean has = extToRightNum.containsKey(extension); + if (has) { + String rightNum = extToRightNum.get(extension); + extension.getContent() + .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER) + .setTextContent(rightNum); + } + } + MindMapUIPlugin.getDefault().getUsageDataCollector().increase( + UserDataConstants.STRUCTURE_TYPE_COUNT + value); + topic.setStructureClass((String) value); + } + } + } + + @Override + public void execute() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.MODIFY_STRUCTURE_COUNT); + super.execute(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicTitleWidthCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicTitleWidthCommand.java index d1876b030..e4d0cc9fa 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicTitleWidthCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyTopicTitleWidthCommand.java @@ -1,59 +1,59 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.commands; - -import java.util.Collection; - -import org.xmind.core.ITopic; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.ModifyCommand; - -public class ModifyTopicTitleWidthCommand extends ModifyCommand { - - public ModifyTopicTitleWidthCommand(ITopic topic, int newWidth) { - super(topic, newWidth < 0 ? null : Integer.valueOf(newWidth)); - } - - public ModifyTopicTitleWidthCommand(Collection topics, - int newWidth) { - super(topics, newWidth < 0 ? null : Integer.valueOf(newWidth)); - } - - public ModifyTopicTitleWidthCommand(ISourceProvider topicProvider, - int newWidth) { - super(topicProvider, newWidth < 0 ? null : Integer.valueOf(newWidth)); - } - - protected Object getValue(Object source) { - if (source instanceof ITopic) { - int width = ((ITopic) source).getTitleWidth(); - if (width != ITopic.UNSPECIFIED) - return Integer.valueOf(width); - } - return null; - } - - protected void setValue(Object source, Object value) { - if (source instanceof ITopic) { - ITopic t = (ITopic) source; - if (value == null || value instanceof Integer) { - if (value == null) { - t.setTitleWidth(ITopic.UNSPECIFIED); - } else { - t.setTitleWidth(((Integer) value).intValue()); - } - } - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.commands; + +import java.util.Collection; + +import org.xmind.core.ITopic; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.ModifyCommand; + +public class ModifyTopicTitleWidthCommand extends ModifyCommand { + + public ModifyTopicTitleWidthCommand(ITopic topic, int newWidth) { + super(topic, newWidth < 0 ? null : Integer.valueOf(newWidth)); + } + + public ModifyTopicTitleWidthCommand(Collection topics, + int newWidth) { + super(topics, newWidth < 0 ? null : Integer.valueOf(newWidth)); + } + + public ModifyTopicTitleWidthCommand(ISourceProvider topicProvider, + int newWidth) { + super(topicProvider, newWidth < 0 ? null : Integer.valueOf(newWidth)); + } + + protected Object getValue(Object source) { + if (source instanceof ITopic) { + int width = ((ITopic) source).getTitleWidth(); + if (width != ITopic.UNSPECIFIED) + return Integer.valueOf(width); + } + return null; + } + + protected void setValue(Object source, Object value) { + if (source instanceof ITopic) { + ITopic t = (ITopic) source; + if (value == null || value instanceof Integer) { + if (value == null) { + t.setTitleWidth(ITopic.UNSPECIFIED); + } else { + t.setTitleWidth(((Integer) value).intValue()); + } + } + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/messages.properties index b0c969347..0ea5dfa3c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/messages.properties @@ -1,125 +1,125 @@ -Command_Typing=Typing -Command_Extend=Extend -Command_ExtendAll=Extend All -Command_Collapse=Collapse -Command_CollapseAll=Collapse Al -Command_ModifyTopicTitle=Modify Topic Title -Command_ModifySheetTitle=Modify Sheet Title -Command_ModifyRelationshipTitle=Modify Relationship Title -Command_ModifyTitle=Modify Title -Command_CreateTopic=Create Topic -Command_DeleteTopic=Delete Topic -Command_DeleteRelationship=Delete Relationship -Command_DeleteSheet=Delete Sheet -Command_Delete=Delete -Command_ModifyPosition=Modify Position -Command_CreateFloatingTopic=Create Floating Topic -Command_CreateSheet=Create Sheet -Command_CreateSheetFromTopic=Create Sheet From Topic -Command_MoveSheet=Move Sheet -Command_ModifyTopicHyperlink=Modify Topic Hyperlink -Command_InsertAttachment=Insert Attachment -Command_MoveTopic=Move Topic -Command_CopyTopic=Copy Topic -Command_CutTopic=Cut Topic -Command_CutRelationship=Cut Relationship -Command_CutSheet=Cut Sheet -Command_Cut=Cut -Command_Paste=Paste -Command_PasteTopic=Paste Topic -Command_PasteSheet=Paste Sheet -Command_CreateRelationship=Create Relationship -Command_MoveRelationshipControlPoint=Move Relationship Control Point -Command_RetargetRelationship=Retarget Relationship -Command_AddMarker=Add Marker -Command_DeleteMarker=Remove Marker -Command_CreateBoundary=Create Boundary -Command_DeleteBoundary=Delete Boundary -Command_CutBoundary=Cut Boundary -Command_ModifyBorderColor=Modify Border Color -Command_ModifyBorderShape=Modify Border Shape -Command_ModifyBoundaryTitle=Modify Boundary Title -Command_CreateSummary=Create Summary -Command_ModifyTopicStructure=Modify Topic Structure -Command_ModifyStyle=Modify Style -Command_RemoveStyle=Remove Style -Command_ModifyRange=Modify Range -Command_ModifyBoundaryRange=Modify Boundary Range -Command_ModifySummaryRange=Modify Summary Range -Command_ModifyLabels=Modify Labels -Command_ModifyNotes=Modify Notes -Command_InsertImage=Insert Image -Command_ResizeImage=Resize Image -Command_MoveImage=Move Image -Command_CopyImage=Copy Image -Command_MoveMarker=Move Marker -Command_CopyMarker=Copy Marker -Command_ModifyTitleWidth=Modify Title Width -Command_ShowLegend=Show Legend -Command_HideLegend=Hide Legend -Command_ModifyLegendBackgroundColor=Modify Legend Background Color -Command_ModifyLegendMarkerDescription=Modify Legend Marker Description -Command_MoveLegend=Move Legend -Command_ModifyNumbering=Modify Numbering -Command_Tile=Tile -Command_ReplaceMarker=Replace Marker -Command_ResetPosition=Reset Position -Command_Align=Align -Command_AlignLeft=Align Left -Command_AlignCenter=Align Center (Horizontal) -Command_AlignRight=Align Right -Command_AlignTop=Align Top -Command_AlignMiddle=Align Middle (Vertical) -Command_AlignBottom=Align Bottom -Command_AddResources=Add Resources -Command_ModifyTheme=Modify Theme -Command_ShowOrHideInfoItem=Show/Hide Info Item - -# Modify Style Labels: -Command_ModifyBoundaryOpacity=Modify Boundary Opacity -Command_ModifyBoundaryShape=Modify Boundary Shape -Command_ModifyFont=Modify Font -Command_ModifyTextColor=Modify Text Color -Command_ModifyLineColor=Modify Line Color -Command_ModifyFillColor=Modify Fill Color -Command_ModifyTopicShape=Modify Topic Shape -Command_ModifyLineShape=Modify Line Shape -Command_ModifySheetBackgroundColor=Modify Sheet Background Color -Command_ModifyWallpaperOpacity=Modify Wallpaper Opacity -Command_ModifyWallpaper=Modify Wallpaper -Command_RemoveWallpaper=Remove Wallpaper -Command_ModifyRelationshipShape=Modify Relationship Shape -Command_ModifyBeginArrowShape=Modify Begin Arrow Shape -Command_ModifyEndArrowShape=Modify End Arrow Shape -Command_ToggleMultiLineColors=Toggle Multi-line Colors -Command_ToggleTaperedLines=Toggle Tapered Lines -Command_ToggleGradientColor=Toggle Gradient Color -Command_ShowLabels=Show Label -Command_ShowNotes=Show Notes -Command_ShowHyperlink=Show Hyperlink -Command_ShowTaskInfo=Show Task Info -Command_ModifyYellowBoxBackgroundColor=Modify Information Card Background Color - -Command_TextAlignLeft=Text Align(Left) -Command_TextAlignCenter=Text Align(Center) -Command_TextAlignRight=Text Align(Right) - -Command_TextManual=Text Manual -Command_TextUppercase=Text Uppercase -Command_TextLowercase=Text Lowercase -Command_TextCapitalize=Text Capitalize - -Command_SortByTitle=Sort By Title -Command_SortByPriority=Sort By Priority -Command_SortByModifiedTime=Sort By Modified Time -Command_Sort=Sort -Command_ModifyWidth=Modify Width - -Command_TurnOnAutoRevisionSaving=Turn On Auto Revision Saving -Command_TurnOffAutoRevisionSaving=Turn Off Auto Revision Saving - -Command_CopySheet=Copy Sheet -Command_PasteSheet=Paste Sheet -Command_DuplicateSheet=Duplicate Sheet -Command_ClearMarkers=Clear Markers -Command_RemoveMarkerFromAllTopics=Remove Markers +Command_Typing=Typing +Command_Extend=Extend +Command_ExtendAll=Extend All +Command_Collapse=Collapse +Command_CollapseAll=Collapse Al +Command_ModifyTopicTitle=Modify Topic Title +Command_ModifySheetTitle=Modify Sheet Title +Command_ModifyRelationshipTitle=Modify Relationship Title +Command_ModifyTitle=Modify Title +Command_CreateTopic=Create Topic +Command_DeleteTopic=Delete Topic +Command_DeleteRelationship=Delete Relationship +Command_DeleteSheet=Delete Sheet +Command_Delete=Delete +Command_ModifyPosition=Modify Position +Command_CreateFloatingTopic=Create Floating Topic +Command_CreateSheet=Create Sheet +Command_CreateSheetFromTopic=Create Sheet From Topic +Command_MoveSheet=Move Sheet +Command_ModifyTopicHyperlink=Modify Topic Hyperlink +Command_InsertAttachment=Insert Attachment +Command_MoveTopic=Move Topic +Command_CopyTopic=Copy Topic +Command_CutTopic=Cut Topic +Command_CutRelationship=Cut Relationship +Command_CutSheet=Cut Sheet +Command_Cut=Cut +Command_Paste=Paste +Command_PasteTopic=Paste Topic +Command_PasteSheet=Paste Sheet +Command_CreateRelationship=Create Relationship +Command_MoveRelationshipControlPoint=Move Relationship Control Point +Command_RetargetRelationship=Retarget Relationship +Command_AddMarker=Add Marker +Command_DeleteMarker=Remove Marker +Command_CreateBoundary=Create Boundary +Command_DeleteBoundary=Delete Boundary +Command_CutBoundary=Cut Boundary +Command_ModifyBorderColor=Modify Border Color +Command_ModifyBorderShape=Modify Border Shape +Command_ModifyBoundaryTitle=Modify Boundary Title +Command_CreateSummary=Create Summary +Command_ModifyTopicStructure=Modify Topic Structure +Command_ModifyStyle=Modify Style +Command_RemoveStyle=Remove Style +Command_ModifyRange=Modify Range +Command_ModifyBoundaryRange=Modify Boundary Range +Command_ModifySummaryRange=Modify Summary Range +Command_ModifyLabels=Modify Labels +Command_ModifyNotes=Modify Notes +Command_InsertImage=Insert Image +Command_ResizeImage=Resize Image +Command_MoveImage=Move Image +Command_CopyImage=Copy Image +Command_MoveMarker=Move Marker +Command_CopyMarker=Copy Marker +Command_ModifyTitleWidth=Modify Title Width +Command_ShowLegend=Show Legend +Command_HideLegend=Hide Legend +Command_ModifyLegendBackgroundColor=Modify Legend Background Color +Command_ModifyLegendMarkerDescription=Modify Legend Marker Description +Command_MoveLegend=Move Legend +Command_ModifyNumbering=Modify Numbering +Command_Tile=Tile +Command_ReplaceMarker=Replace Marker +Command_ResetPosition=Reset Position +Command_Align=Align +Command_AlignLeft=Align Left +Command_AlignCenter=Align Center (Horizontal) +Command_AlignRight=Align Right +Command_AlignTop=Align Top +Command_AlignMiddle=Align Middle (Vertical) +Command_AlignBottom=Align Bottom +Command_AddResources=Add Resources +Command_ModifyTheme=Modify Theme +Command_ShowOrHideInfoItem=Show/Hide Info Item + +# Modify Style Labels: +Command_ModifyBoundaryOpacity=Modify Boundary Opacity +Command_ModifyBoundaryShape=Modify Boundary Shape +Command_ModifyFont=Modify Font +Command_ModifyTextColor=Modify Text Color +Command_ModifyLineColor=Modify Line Color +Command_ModifyFillColor=Modify Fill Color +Command_ModifyTopicShape=Modify Topic Shape +Command_ModifyLineShape=Modify Line Shape +Command_ModifySheetBackgroundColor=Modify Sheet Background Color +Command_ModifyWallpaperOpacity=Modify Wallpaper Opacity +Command_ModifyWallpaper=Modify Wallpaper +Command_RemoveWallpaper=Remove Wallpaper +Command_ModifyRelationshipShape=Modify Relationship Shape +Command_ModifyBeginArrowShape=Modify Begin Arrow Shape +Command_ModifyEndArrowShape=Modify End Arrow Shape +Command_ToggleMultiLineColors=Toggle Multi-line Colors +Command_ToggleTaperedLines=Toggle Tapered Lines +Command_ToggleGradientColor=Toggle Gradient Color +Command_ShowLabels=Show Label +Command_ShowNotes=Show Notes +Command_ShowHyperlink=Show Hyperlink +Command_ShowTaskInfo=Show Task Info +Command_ModifyYellowBoxBackgroundColor=Modify Information Card Background Color + +Command_TextAlignLeft=Text Align(Left) +Command_TextAlignCenter=Text Align(Center) +Command_TextAlignRight=Text Align(Right) + +Command_TextManual=Text Manual +Command_TextUppercase=Text Uppercase +Command_TextLowercase=Text Lowercase +Command_TextCapitalize=Text Capitalize + +Command_SortByTitle=Sort By Title +Command_SortByPriority=Sort By Priority +Command_SortByModifiedTime=Sort By Modified Time +Command_Sort=Sort +Command_ModifyWidth=Modify Width + +Command_TurnOnAutoRevisionSaving=Turn On Auto Revision Saving +Command_TurnOffAutoRevisionSaving=Turn Off Auto Revision Saving + +Command_CopySheet=Copy Sheet +Command_PasteSheet=Paste Sheet +Command_DuplicateSheet=Duplicate Sheet +Command_ClearMarkers=Clear Markers +Command_RemoveMarkerFromAllTopics=Remove Markers diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBoundaryDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBoundaryDecoration.java index 09750fdac..cf01dc1a3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBoundaryDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBoundaryDecoration.java @@ -1,139 +1,139 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.decoration.PathShapeDecoration; -import org.xmind.gef.draw2d.graphics.Path; - -public abstract class AbstractBoundaryDecoration extends PathShapeDecoration - implements IBoundaryDecoration, IShadowedDecoration { - - private static final Rectangle CLIP = new Rectangle(); - - protected static final int MARGIN_WIDTH = 10; - - protected static final int MARGIN_HEIGHT = 10; - - protected static final int TITLE_MARGIN = 5; - - protected AbstractBoundaryDecoration() { - super(); - } - - protected AbstractBoundaryDecoration(String id) { - super(id); - } - - public boolean containsPoint(IFigure figure, int x, int y) { - return containsPoint(figure, x, y, true); - } - - protected int getCheckingLineWidth() { - return super.getCheckingLineWidth() * 2 + 4; - } - - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - ITextFigure titleFigure = getTitleFigure(figure); - if (titleFigure != null && titleFigure.isShowing()) { - Rectangle bounds = figure.getBounds(); - Rectangle titleArea = titleFigure.getBounds(); - if (titleArea.intersects(bounds)) { - graphics.pushState(); - try { - paintPathAroundTitle(figure, graphics, path, fill, bounds, - titleArea); - } finally { - graphics.popState(); - } - return; - } - } - super.paintPath(figure, graphics, path, fill); - } - - protected void paintPathAroundTitle(IFigure figure, Graphics graphics, - Path path, boolean fill, Rectangle bounds, Rectangle titleArea) { - int w; - int h; - // clip the top-right part - w = bounds.x + bounds.width - titleArea.x - titleArea.width; - h = titleArea.y + titleArea.height - bounds.y; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(titleArea.x + titleArea.width, bounds.y); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - // clip the bottom part - w = bounds.width; - h = bounds.y + bounds.height - titleArea.y - titleArea.height; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(bounds.x, titleArea.y + titleArea.height); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - } - - protected void paintPathWithClip(IFigure figure, Graphics graphics, - Path path, boolean fill, Rectangle clip) { - graphics.clipRect(clip); - super.paintPath(figure, graphics, path, fill); - graphics.restoreState(); - } - - protected ITextFigure getTitleFigure(IFigure figure) { - if (figure instanceof ITitledFigure) { - return ((ITitledFigure) figure).getTitle(); - } - return null; - } - - protected Rectangle getOutlineBox(IFigure figure) { - Rectangle r = super.getOutlineBox(figure); - ITextFigure titleFigure = getTitleFigure(figure); - if (titleFigure != null && titleFigure.isShowing()) { - r.x += 5; - r.width -= 5; - int height = titleFigure.getPreferredSize().height; - height = Math.min(5, height / 2); - r.y += height; - r.height -= height; - } - return r; - } - - public void paintShadow(IFigure figure, Graphics graphics) { - if (!isVisible()) - return; - checkValidation(figure); - graphics.setAlpha(getAlpha()); - graphics.setBackgroundColor(ColorConstants.black); - graphics.setForegroundColor(ColorConstants.black); - paintFill(figure, graphics); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - return new Insets(MARGIN_HEIGHT, MARGIN_WIDTH, MARGIN_HEIGHT, - MARGIN_WIDTH); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.decoration.PathShapeDecoration; +import org.xmind.gef.draw2d.graphics.Path; + +public abstract class AbstractBoundaryDecoration extends PathShapeDecoration + implements IBoundaryDecoration, IShadowedDecoration { + + private static final Rectangle CLIP = new Rectangle(); + + protected static final int MARGIN_WIDTH = 10; + + protected static final int MARGIN_HEIGHT = 10; + + protected static final int TITLE_MARGIN = 5; + + protected AbstractBoundaryDecoration() { + super(); + } + + protected AbstractBoundaryDecoration(String id) { + super(id); + } + + public boolean containsPoint(IFigure figure, int x, int y) { + return containsPoint(figure, x, y, true); + } + + protected int getCheckingLineWidth() { + return super.getCheckingLineWidth() * 2 + 4; + } + + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + ITextFigure titleFigure = getTitleFigure(figure); + if (titleFigure != null && titleFigure.isShowing()) { + Rectangle bounds = figure.getBounds(); + Rectangle titleArea = titleFigure.getBounds(); + if (titleArea.intersects(bounds)) { + graphics.pushState(); + try { + paintPathAroundTitle(figure, graphics, path, fill, bounds, + titleArea); + } finally { + graphics.popState(); + } + return; + } + } + super.paintPath(figure, graphics, path, fill); + } + + protected void paintPathAroundTitle(IFigure figure, Graphics graphics, + Path path, boolean fill, Rectangle bounds, Rectangle titleArea) { + int w; + int h; + // clip the top-right part + w = bounds.x + bounds.width - titleArea.x - titleArea.width; + h = titleArea.y + titleArea.height - bounds.y; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(titleArea.x + titleArea.width, bounds.y); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + // clip the bottom part + w = bounds.width; + h = bounds.y + bounds.height - titleArea.y - titleArea.height; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(bounds.x, titleArea.y + titleArea.height); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + } + + protected void paintPathWithClip(IFigure figure, Graphics graphics, + Path path, boolean fill, Rectangle clip) { + graphics.clipRect(clip); + super.paintPath(figure, graphics, path, fill); + graphics.restoreState(); + } + + protected ITextFigure getTitleFigure(IFigure figure) { + if (figure instanceof ITitledFigure) { + return ((ITitledFigure) figure).getTitle(); + } + return null; + } + + protected Rectangle getOutlineBox(IFigure figure) { + Rectangle r = super.getOutlineBox(figure); + ITextFigure titleFigure = getTitleFigure(figure); + if (titleFigure != null && titleFigure.isShowing()) { + r.x += 5; + r.width -= 5; + int height = titleFigure.getPreferredSize().height; + height = Math.min(5, height / 2); + r.y += height; + r.height -= height; + } + return r; + } + + public void paintShadow(IFigure figure, Graphics graphics) { + if (!isVisible()) + return; + checkValidation(figure); + graphics.setAlpha(getAlpha()); + graphics.setBackgroundColor(ColorConstants.black); + graphics.setForegroundColor(ColorConstants.black); + paintFill(figure, graphics); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + return new Insets(MARGIN_HEIGHT, MARGIN_WIDTH, MARGIN_HEIGHT, + MARGIN_WIDTH); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBranchConnection.java index 0398f647f..13922bf22 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractBranchConnection.java @@ -1,319 +1,319 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.decoration.PathConnectionDecoration; -import org.xmind.gef.draw2d.geometry.PrecisionLine; -import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.internal.figures.TopicFigure; - -public abstract class AbstractBranchConnection extends PathConnectionDecoration - implements IBranchConnectionDecoration, IShadowedDecoration { - - private int sourceOrientation = PositionConstants.NONE; - - private int targetOrientation = PositionConstants.NONE; - - private int sourceExpansion = 0; - - private int targetExpansion = 0; - - private boolean tapered = false; - - private boolean taperedStateChanged = false; - - protected AbstractBranchConnection() { - super(); - } - - protected AbstractBranchConnection(String id) { - super(id); - } - - public void paintShadow(IFigure figure, Graphics graphics) { - if (!isVisible()) - return; - checkValidation(figure); - graphics.setAlpha(getAlpha()); - graphics.setForegroundColor(ColorConstants.black); - graphics.setLineWidth(getLineWidth()); - graphics.setLineStyle(getLineStyle()); - drawLine(figure, graphics); - } - - protected void reroute(IFigure figure, PrecisionPoint sourcePos, - PrecisionPoint targetPos, boolean validating) { - calculateTerminalPoints(figure, sourcePos, targetPos); - calculateControlPoints(figure, sourcePos, targetPos); - } - - protected void calculateControlPoints(IFigure figure, - PrecisionPoint sourcePos, PrecisionPoint targetPos) { - } - - protected void calculateTerminalPoints(IFigure figure, - PrecisionPoint sourcePos, PrecisionPoint targetPos) { - IAnchor sa = getSourceAnchor(); - IAnchor ta = getTargetAnchor(); - int so = getSourceOrientation(); - int to = getTargetOrientation(); - if (so == PositionConstants.NONE && to == PositionConstants.NONE) { - if (sa != null) { - if (ta != null) { - sourcePos.setLocation(sa.getLocation(ta.getReferencePoint(), - getSourceExpansion())); - } else { - sourcePos.setLocation( - sa.getLocation(0, 0, getSourceExpansion())); - } - } - if (ta != null) { - if (sa != null) { - targetPos.setLocation(ta.getLocation(sa.getReferencePoint(), - getTargetExpansion())); - } else { - targetPos.setLocation( - ta.getLocation(0, 0, getTargetExpansion())); - } - } - } else if (so == PositionConstants.NONE) { - if (ta != null) { - targetPos.setLocation(ta.getLocation(to, getTargetExpansion())); - } - if (sa != null) { - sourcePos.setLocation( - sa.getLocation(targetPos, getSourceExpansion())); -// sourcePos.setLocation(sa.getOwner().getBounds().getCenter()); - } - } else if (to == PositionConstants.NONE) { - if (sa != null) { - sourcePos.setLocation(sa.getLocation(so, getSourceExpansion())); - } - if (ta != null) { - targetPos.setLocation( - ta.getLocation(sourcePos, getTargetExpansion())); - } - } else { - if (sa != null) { - sourcePos.setLocation(sa.getLocation(so, getSourceExpansion())); - } - if (ta != null) { - targetPos.setLocation(ta.getLocation(to, getTargetExpansion())); - } - } - } - - protected void calculateSourceControlPoints(PrecisionPoint c, - PrecisionPoint s1, PrecisionPoint s2, PrecisionPoint c2) { - PrecisionLine line = new PrecisionLine(c, s1, LineType.Ray); - double length = s1.getDistance(s2); - double angle = line.getAngle(); - double sin = Math.sin(angle); - double cos = Math.cos(angle); - c2.setLocation( - s1.getTranslated(length * cos * 0.5f, length * sin * 0.5f)); - } - - public int getSourceOrientation() { - return sourceOrientation; - } - - public int getTargetOrientation() { - return targetOrientation; - } - - public void setSourceOrientation(IFigure figure, int orientation) { - if (orientation == this.sourceOrientation) - return; - - this.sourceOrientation = orientation; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - } - - public void setTargetOrientation(IFigure figure, int orientation) { - if (orientation == this.targetOrientation) - return; - - this.targetOrientation = orientation; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - } - - public int getSourceExpansion() { - return sourceExpansion; - } - - public int getTargetExpansion() { - return targetExpansion; - } - - public void setSourceExpansion(IFigure figure, int expansion) { - if (expansion == this.sourceExpansion) - return; - - this.sourceExpansion = expansion; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - } - - public void setTargetExpansion(IFigure figure, int expansion) { - if (expansion == this.targetExpansion) - return; - - this.targetExpansion = expansion; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - } - - public boolean isTapered() { - return tapered; - } - - public void setTapered(IFigure figure, boolean tapered) { - if (tapered == this.tapered) - return; - - this.tapered = tapered; - if (figure != null) { - repaint(figure); - } - taperedStateChanged = true; - invalidate(); - } - - protected boolean isPositionValid() { - return super.isPositionValid() && !taperedStateChanged; - } - - public void validate(IFigure figure) { - taperedStateChanged = false; - super.validate(figure); - } - - protected boolean usesFill() { - return isTapered(); - } - - protected double getThickLineWidth() { - return getLineWidth() * 5; - } - - protected void calcTaperedPositions(PrecisionPoint p1, PrecisionPoint p2, - double amountFromP1ToP2, PrecisionPoint result1, - PrecisionPoint result2) { - calcTaperedPositions(p1, p2, amountFromP1ToP2, 5, result1, result2); - } - - protected void calcTaperedPositions(PrecisionPoint p1, PrecisionPoint p2, - double amountFromP1ToP2, double thickness, PrecisionPoint result1, - PrecisionPoint result2) { - // Initialize results - result1.setLocation(p1); - result2.setLocation(p2); - - // No more action needed if p1 and p2 are the same location - if (p1.equals(p2)) - return; - - // Move results to the point by the amount between p1 and p2 - result1.move(result2, amountFromP1ToP2); - result2.setLocation(result1); - - // Calculate the line width on that point - double width = getLineWidth() * thickness * (1 - amountFromP1ToP2) - + getLineWidth() * amountFromP1ToP2; - - // Calculate the horizontal and vertical distance from that - // point to actual positions - double dx = p2.x - p1.x; - double dy = p2.y - p1.y; - double d = Math.hypot(dx, dy); - double e = (width / 2) / d; - dx *= e; - dy *= e; - - // Translate results to actual position - result1.translate(-dy, dx); - result2.translate(dy, -dx); - } - -// public int getMinimumMajorSpacing(IFigure figure) { -// return 0; -// } - - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - TopicFigure tf = getTopicFigure(figure); - if (tf != null && (tf.getDecoration().getLineWidth() > 0 - || tf.getDecoration().getFillColor() != null)) { - Rectangle bounds = figure.getBounds(); - Path shape = new Path(Display.getCurrent()); - ITopicDecoration decoration = tf.getDecoration(); - - Rectangle rectangleClip = graphics.getClip(new Rectangle()); - //When get clip from the graphics, there will be a conversion from float to int, with lossing of accuracy. - //So expand 1 pixel first. - rectangleClip.expand(new Insets(1)); - - shape.addRectangle(new Rectangle(bounds).intersect(rectangleClip)); - shape.addPath(decoration.createClippingPath(tf)); - - graphics.pushState(); - try { - graphics.setClip(shape); - super.paintPath(figure, graphics, path, fill); - graphics.restoreState(); - } finally { - graphics.popState(); - shape.close(); - shape.dispose(); - } - return; - } - super.paintPath(figure, graphics, path, fill); - }; - - private TopicFigure getTopicFigure(IFigure parent) { - for (Object obj : parent.getChildren()) { - if (obj instanceof TopicFigure) - return (TopicFigure) obj; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.decoration.PathConnectionDecoration; +import org.xmind.gef.draw2d.geometry.PrecisionLine; +import org.xmind.gef.draw2d.geometry.PrecisionLine.LineType; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.internal.figures.TopicFigure; + +public abstract class AbstractBranchConnection extends PathConnectionDecoration + implements IBranchConnectionDecoration, IShadowedDecoration { + + private int sourceOrientation = PositionConstants.NONE; + + private int targetOrientation = PositionConstants.NONE; + + private int sourceExpansion = 0; + + private int targetExpansion = 0; + + private boolean tapered = false; + + private boolean taperedStateChanged = false; + + protected AbstractBranchConnection() { + super(); + } + + protected AbstractBranchConnection(String id) { + super(id); + } + + public void paintShadow(IFigure figure, Graphics graphics) { + if (!isVisible()) + return; + checkValidation(figure); + graphics.setAlpha(getAlpha()); + graphics.setForegroundColor(ColorConstants.black); + graphics.setLineWidth(getLineWidth()); + graphics.setLineStyle(getLineStyle()); + drawLine(figure, graphics); + } + + protected void reroute(IFigure figure, PrecisionPoint sourcePos, + PrecisionPoint targetPos, boolean validating) { + calculateTerminalPoints(figure, sourcePos, targetPos); + calculateControlPoints(figure, sourcePos, targetPos); + } + + protected void calculateControlPoints(IFigure figure, + PrecisionPoint sourcePos, PrecisionPoint targetPos) { + } + + protected void calculateTerminalPoints(IFigure figure, + PrecisionPoint sourcePos, PrecisionPoint targetPos) { + IAnchor sa = getSourceAnchor(); + IAnchor ta = getTargetAnchor(); + int so = getSourceOrientation(); + int to = getTargetOrientation(); + if (so == PositionConstants.NONE && to == PositionConstants.NONE) { + if (sa != null) { + if (ta != null) { + sourcePos.setLocation(sa.getLocation(ta.getReferencePoint(), + getSourceExpansion())); + } else { + sourcePos.setLocation( + sa.getLocation(0, 0, getSourceExpansion())); + } + } + if (ta != null) { + if (sa != null) { + targetPos.setLocation(ta.getLocation(sa.getReferencePoint(), + getTargetExpansion())); + } else { + targetPos.setLocation( + ta.getLocation(0, 0, getTargetExpansion())); + } + } + } else if (so == PositionConstants.NONE) { + if (ta != null) { + targetPos.setLocation(ta.getLocation(to, getTargetExpansion())); + } + if (sa != null) { + sourcePos.setLocation( + sa.getLocation(targetPos, getSourceExpansion())); +// sourcePos.setLocation(sa.getOwner().getBounds().getCenter()); + } + } else if (to == PositionConstants.NONE) { + if (sa != null) { + sourcePos.setLocation(sa.getLocation(so, getSourceExpansion())); + } + if (ta != null) { + targetPos.setLocation( + ta.getLocation(sourcePos, getTargetExpansion())); + } + } else { + if (sa != null) { + sourcePos.setLocation(sa.getLocation(so, getSourceExpansion())); + } + if (ta != null) { + targetPos.setLocation(ta.getLocation(to, getTargetExpansion())); + } + } + } + + protected void calculateSourceControlPoints(PrecisionPoint c, + PrecisionPoint s1, PrecisionPoint s2, PrecisionPoint c2) { + PrecisionLine line = new PrecisionLine(c, s1, LineType.Ray); + double length = s1.getDistance(s2); + double angle = line.getAngle(); + double sin = Math.sin(angle); + double cos = Math.cos(angle); + c2.setLocation( + s1.getTranslated(length * cos * 0.5f, length * sin * 0.5f)); + } + + public int getSourceOrientation() { + return sourceOrientation; + } + + public int getTargetOrientation() { + return targetOrientation; + } + + public void setSourceOrientation(IFigure figure, int orientation) { + if (orientation == this.sourceOrientation) + return; + + this.sourceOrientation = orientation; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + } + + public void setTargetOrientation(IFigure figure, int orientation) { + if (orientation == this.targetOrientation) + return; + + this.targetOrientation = orientation; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + } + + public int getSourceExpansion() { + return sourceExpansion; + } + + public int getTargetExpansion() { + return targetExpansion; + } + + public void setSourceExpansion(IFigure figure, int expansion) { + if (expansion == this.sourceExpansion) + return; + + this.sourceExpansion = expansion; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + } + + public void setTargetExpansion(IFigure figure, int expansion) { + if (expansion == this.targetExpansion) + return; + + this.targetExpansion = expansion; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + } + + public boolean isTapered() { + return tapered; + } + + public void setTapered(IFigure figure, boolean tapered) { + if (tapered == this.tapered) + return; + + this.tapered = tapered; + if (figure != null) { + repaint(figure); + } + taperedStateChanged = true; + invalidate(); + } + + protected boolean isPositionValid() { + return super.isPositionValid() && !taperedStateChanged; + } + + public void validate(IFigure figure) { + taperedStateChanged = false; + super.validate(figure); + } + + protected boolean usesFill() { + return isTapered(); + } + + protected double getThickLineWidth() { + return getLineWidth() * 5; + } + + protected void calcTaperedPositions(PrecisionPoint p1, PrecisionPoint p2, + double amountFromP1ToP2, PrecisionPoint result1, + PrecisionPoint result2) { + calcTaperedPositions(p1, p2, amountFromP1ToP2, 5, result1, result2); + } + + protected void calcTaperedPositions(PrecisionPoint p1, PrecisionPoint p2, + double amountFromP1ToP2, double thickness, PrecisionPoint result1, + PrecisionPoint result2) { + // Initialize results + result1.setLocation(p1); + result2.setLocation(p2); + + // No more action needed if p1 and p2 are the same location + if (p1.equals(p2)) + return; + + // Move results to the point by the amount between p1 and p2 + result1.move(result2, amountFromP1ToP2); + result2.setLocation(result1); + + // Calculate the line width on that point + double width = getLineWidth() * thickness * (1 - amountFromP1ToP2) + + getLineWidth() * amountFromP1ToP2; + + // Calculate the horizontal and vertical distance from that + // point to actual positions + double dx = p2.x - p1.x; + double dy = p2.y - p1.y; + double d = Math.hypot(dx, dy); + double e = (width / 2) / d; + dx *= e; + dy *= e; + + // Translate results to actual position + result1.translate(-dy, dx); + result2.translate(dy, -dx); + } + +// public int getMinimumMajorSpacing(IFigure figure) { +// return 0; +// } + + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + TopicFigure tf = getTopicFigure(figure); + if (tf != null && (tf.getDecoration().getLineWidth() > 0 + || tf.getDecoration().getFillColor() != null)) { + Rectangle bounds = figure.getBounds(); + Path shape = new Path(Display.getCurrent()); + ITopicDecoration decoration = tf.getDecoration(); + + Rectangle rectangleClip = graphics.getClip(new Rectangle()); + //When get clip from the graphics, there will be a conversion from float to int, with lossing of accuracy. + //So expand 1 pixel first. + rectangleClip.expand(new Insets(1)); + + shape.addRectangle(new Rectangle(bounds).intersect(rectangleClip)); + shape.addPath(decoration.createClippingPath(tf)); + + graphics.pushState(); + try { + graphics.setClip(shape); + super.paintPath(figure, graphics, path, fill); + graphics.restoreState(); + } finally { + graphics.popState(); + shape.close(); + shape.dispose(); + } + return; + } + super.paintPath(figure, graphics, path, fill); + }; + + private TopicFigure getTopicFigure(IFigure parent) { + for (Object obj : parent.getChildren()) { + if (obj instanceof TopicFigure) + return (TopicFigure) obj; + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractCalloutTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractCalloutTopicDecoration.java index 54ab5bf67..78bd25f4f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractCalloutTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractCalloutTopicDecoration.java @@ -1,89 +1,89 @@ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; - -public abstract class AbstractCalloutTopicDecoration extends - AbstractTopicDecoration implements ICalloutTopicDecoration { - - private int fromLineStyle = SWT.LINE_SOLID; - - private String fromLineClass = null; - - private int fromLineWidth = 1; - - private Color fromLineColor = null; - - private Color fromFillColor = null; - - private int fromLineCorner = 0; - - protected AbstractCalloutTopicDecoration() { - super(); - } - - protected AbstractCalloutTopicDecoration(String id) { - super(id); - } - - @Override - protected void paintFill(IFigure figure, Graphics graphics) { - //prevent paint fill - } - - @Override - protected void paintOutline(IFigure figure, Graphics graphics) { - //prevent paint border - } - - public void setFromLineColor(IFigure figure, Color fromLineColor) { - this.fromLineColor = fromLineColor; - } - - public void setFromLineWidth(IFigure figure, int fromLineWidth) { - this.fromLineWidth = fromLineWidth; - } - - public void setFromLineClass(IFigure figure, String fromLineClass) { - this.fromLineClass = fromLineClass; - } - - public void setFromLineStyle(IFigure figure, int fromLinePattern) { - this.fromLineStyle = fromLinePattern; - } - - public void setFromLineCorner(IFigure figure, int fromLineCorner) { - this.fromLineCorner = fromLineCorner; - } - - public void setFromFillColor(IFigure figure, Color fromFillColor) { - this.fromFillColor = fromFillColor; - } - - public Color getFromFillColor() { - return fromFillColor; - } - - public Color getFromLineColor() { - return fromLineColor; - } - - public int getFromLineWidth() { - return fromLineWidth; - } - - public String getFromLineClass() { - return fromLineClass; - } - - public int getFromLineStyle() { - return fromLineStyle; - } - - public int getFromLineCorner() { - return fromLineCorner; - } - -} +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; + +public abstract class AbstractCalloutTopicDecoration extends + AbstractTopicDecoration implements ICalloutTopicDecoration { + + private int fromLineStyle = SWT.LINE_SOLID; + + private String fromLineClass = null; + + private int fromLineWidth = 1; + + private Color fromLineColor = null; + + private Color fromFillColor = null; + + private int fromLineCorner = 0; + + protected AbstractCalloutTopicDecoration() { + super(); + } + + protected AbstractCalloutTopicDecoration(String id) { + super(id); + } + + @Override + protected void paintFill(IFigure figure, Graphics graphics) { + //prevent paint fill + } + + @Override + protected void paintOutline(IFigure figure, Graphics graphics) { + //prevent paint border + } + + public void setFromLineColor(IFigure figure, Color fromLineColor) { + this.fromLineColor = fromLineColor; + } + + public void setFromLineWidth(IFigure figure, int fromLineWidth) { + this.fromLineWidth = fromLineWidth; + } + + public void setFromLineClass(IFigure figure, String fromLineClass) { + this.fromLineClass = fromLineClass; + } + + public void setFromLineStyle(IFigure figure, int fromLinePattern) { + this.fromLineStyle = fromLinePattern; + } + + public void setFromLineCorner(IFigure figure, int fromLineCorner) { + this.fromLineCorner = fromLineCorner; + } + + public void setFromFillColor(IFigure figure, Color fromFillColor) { + this.fromFillColor = fromFillColor; + } + + public Color getFromFillColor() { + return fromFillColor; + } + + public Color getFromLineColor() { + return fromLineColor; + } + + public int getFromLineWidth() { + return fromLineWidth; + } + + public String getFromLineClass() { + return fromLineClass; + } + + public int getFromLineStyle() { + return fromLineStyle; + } + + public int getFromLineCorner() { + return fromLineCorner; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractRelationshipDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractRelationshipDecoration.java index a210dbf16..c9e87b891 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractRelationshipDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractRelationshipDecoration.java @@ -1,473 +1,473 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.decoration.PathConnectionDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.style.Styles; - -public abstract class AbstractRelationshipDecoration - extends PathConnectionDecoration - implements IRelationshipDecoration, IShadowedDecoration { - - private static final Rectangle CLIP = new Rectangle(); - - protected Double sourceCPAngle = null; - - protected Double sourceCPAmount = null; - - protected Double targetCPAngle = null; - - protected Double targetCPAmount = null; - - protected Point relativeSourceCP = null; - - protected Point relativeTargetCP = null; - - private PrecisionPoint sourceCP = null; - - private PrecisionPoint targetCP = null; - - private IArrowDecoration arrow1 = null; - - private IArrowDecoration arrow2 = null; - - private PrecisionPoint titlePos = null; - - protected AbstractRelationshipDecoration() { - } - - protected AbstractRelationshipDecoration(String id) { - super(id); - } - - protected int getLineWidthForChecking() { - return super.getLineWidthForChecking() * 3 + 10; - } - - public void reroute(IFigure figure) { - super.reroute(figure); - updateArrows(figure); - } - - protected void reroute(IFigure figure, PrecisionPoint sourcePos, - PrecisionPoint targetPos, boolean validating) { - PrecisionPoint oldSourceCP = this.sourceCP; - PrecisionPoint oldTargetCP = this.targetCP; - PrecisionPoint oldTitlePos = this.titlePos; - PrecisionPoint newSourceCP = new PrecisionPoint(); - PrecisionPoint newTargetCP = new PrecisionPoint(); - PrecisionPoint newTitlePos = new PrecisionPoint(); - reroute(figure, sourcePos, targetPos, newSourceCP, newTargetCP); - calcTitlePosition(figure, newTitlePos, sourcePos, targetPos, - newSourceCP, newTargetCP); - this.sourceCP = newSourceCP; - this.targetCP = newTargetCP; - this.titlePos = newTitlePos; - if (!validating && figure != null) { - if (!newSourceCP.equals(oldSourceCP) - || !newTargetCP.equals(oldTargetCP) - || !newTitlePos.equals(oldTitlePos)) { - figure.revalidate(); - repaint(figure); - } - } - } - - protected void reroute(IFigure figure, PrecisionPoint sourcePos, - PrecisionPoint targetPos, PrecisionPoint sourceCP, - PrecisionPoint targetCP) { - IAnchor sa = getSourceAnchor(); - IAnchor ta = getTargetAnchor(); -// if (sa != null) -// sourcePos.setLocation(sa.getReferencePoint()); -// if (ta != null) -// targetPos.setLocation(ta.getReferencePoint()); - - PrecisionPoint a1 = null; - PrecisionPoint a2 = null; - if (sa != null) { - if (relativeSourceCP != null) { - sourceCP.setLocation(sa.getReferencePoint()) - .translate(relativeSourceCP.x, relativeSourceCP.y); - sourcePos.setLocation(sa.getLocation(sourceCP, 0)); - } else if (ta != null) { - if (a1 == null) - a1 = sa.getLocation(ta.getReferencePoint(), 0); - sourcePos.setLocation(a1); - if (a2 == null) - a2 = ta.getLocation(sa.getReferencePoint(), 0); - sourceCP.setLocation(a1).move(a2, - Styles.DEF_CONTROL_POINT_AMOUNT); - } - } - - if (ta != null) { - if (relativeTargetCP != null) { - targetCP.setLocation(ta.getReferencePoint()) - .translate(relativeTargetCP.x, relativeTargetCP.y); - targetPos.setLocation(ta.getLocation(targetCP, 0)); - } else if (sa != null) { - if (a2 == null) - a2 = ta.getLocation(sa.getReferencePoint(), 0); - targetPos.setLocation(a2); - if (a1 == null) - a1 = sa.getLocation(ta.getReferencePoint(), 0); - targetCP.setLocation(a2).move(a1, - Styles.DEF_CONTROL_POINT_AMOUNT); - } - } - -// double dx = targetPos.x - sourcePos.x; -// double dy = targetPos.y - sourcePos.y; -// double angle1 = getAngleValue(sourceCPAngle); -// double theta1 = Geometry.getAngle(dx, dy) + angle1; -// sourceCP.setLocation(sourcePos).move(theta1, 100); -// -// double angle2 = getAngleValue(targetCPAngle); -// double theta2 = Geometry.getAngle(-dx, -dy) + angle2; -// targetCP.setLocation(targetPos).move(theta2, 100); -// -// if (sa != null) -// sourcePos.setLocation(sa.getLocation(sourceCP, 0)); -// if (ta != null) -// targetPos.setLocation(ta.getLocation(targetCP, 0)); -// -// dx = targetPos.x - sourcePos.x; -// dy = targetPos.y - sourcePos.y; -// double d = Math.max(Math.hypot(dx, dy), Geometry.MIN_DISTANCE); -// -// double amount1 = getAmountValue(sourceCPAmount); -// sourceCP.setLocation(sourcePos).move(theta1, d * amount1); -// -// double amount2 = getAmountValue(targetCPAmount); -// targetCP.setLocation(targetPos).move(theta2, d * amount2); - } - - protected void updatePosAndCp(IAnchor anchor, PrecisionPoint pos, - PrecisionPoint cp, double angle) { - Point center = anchor.getReferencePoint().toDraw2DPoint(); - Point rotatedCp = Geometry.getRotatedPoint( - new Point(cp.toDraw2DPoint()).translate(-center.x, -center.y), - angle); - cp.setLocation(rotatedCp.translate(center.x, center.y)); - pos.setLocation(anchor.getLocation(cp, 0)); - } - - protected void calcTitlePosition(IFigure figure, PrecisionPoint titlePos, - PrecisionPoint sourcePos, PrecisionPoint targetPos, - PrecisionPoint sourceCP, PrecisionPoint targetCP) { - titlePos.setLocation((sourcePos.x + targetPos.x) / 2, - (sourcePos.y + targetPos.y) / 2); - } - -// private double getAngleValue(Double angle) { -// return angle == null ? Styles.DEF_CONTROL_POINT_ANGLE : angle -// .doubleValue(); -// } -// -// private double getAmountValue(Double amount) { -// return amount == null ? Styles.DEF_CONTROL_POINT_AMOUNT : amount -// .doubleValue(); -// } - - protected boolean isPositionValid() { - return super.isPositionValid() && sourceCP != null && targetCP != null - && titlePos != null; - } - - public PrecisionPoint getSourceControlPoint(IFigure figure) { - checkValidation(figure); - return sourceCP; - } - - public PrecisionPoint getTargetControlPoint(IFigure figure) { - checkValidation(figure); - return targetCP; - } - - public void setRelativeSourceControlPoint(IFigure figure, Point point) { - if (point == this.relativeSourceCP - || (point != null && point.equals(this.relativeSourceCP))) - return; - - this.relativeSourceCP = point; - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - invalidate(); - } - - public void setRelativeTargetControlPoint(IFigure figure, Point point) { - if (point == this.relativeTargetCP - || (point != null && point.equals(this.relativeTargetCP))) - return; - - this.relativeTargetCP = point; - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - invalidate(); - } - - public void setSourceControlPointHint(IFigure figure, Double angle, - Double amount) { - boolean changed = false; - if (angle != this.sourceCPAngle - && (angle == null || !angle.equals(this.sourceCPAngle))) { - changed = true; - this.sourceCPAngle = angle; - } - if (amount != this.sourceCPAmount - && (amount == null || !amount.equals(this.sourceCPAmount))) { - changed = true; - this.sourceCPAmount = amount; - } - if (changed && figure != null) { - figure.revalidate(); - repaint(figure); - } - } - - public void setTargetControlPointHint(IFigure figure, Double angle, - Double amount) { - boolean changed = false; - if (angle != this.targetCPAngle - && (angle == null || !angle.equals(this.targetCPAngle))) { - changed = true; - this.targetCPAngle = angle; - } - if (amount != this.targetCPAmount - && (amount == null || !amount.equals(this.targetCPAmount))) { - changed = true; - this.targetCPAmount = amount; - } - if (changed && figure != null) { - figure.revalidate(); - repaint(figure); - } - } - -// public void setOrthogonalSourceControlPointHint(IFigure figure, -// PrecisionPoint pos) { -// } -// -// public void setOrthogonalTargetControlPointHint(IFigure figure, -// PrecisionPoint pos) { -// } -// -// public Double getPolarSourceControlPointAmountHint() { -// return sourceCPAmount; -// } -// -// public Double getPolarSourceControlPointAngleHint() { -// return sourceCPAngle; -// } - - protected double getSourceAnchorAngle(IFigure figure) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getSourceControlPoint(figure); - return Geometry.getAngle(p2, p1); - } - - protected double getTargetAnchorAngle(IFigure figure) { - PrecisionPoint p1 = getTargetPosition(figure); - PrecisionPoint p2 = getTargetControlPoint(figure); - return Geometry.getAngle(p2, p1); - } - - public IArrowDecoration getArrow1() { - return arrow1; - } - - public IArrowDecoration getArrow2() { - return arrow2; - } - - public void setArrow1(IFigure figure, IArrowDecoration arrow) { - if (arrow == this.arrow1) - return; - - this.arrow1 = arrow; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - } - - public void setArrow2(IFigure figure, IArrowDecoration arrow) { - if (arrow == this.arrow2) - return; - - this.arrow2 = arrow; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - } - - @Override - public void invalidate() { - if (arrow1 != null) - arrow1.invalidate(); - if (arrow2 != null) - arrow2.invalidate(); - super.invalidate(); - } - - public void validate(IFigure figure) { - super.validate(figure); - if (arrow1 != null) - arrow1.validate(figure); - if (arrow2 != null) - arrow2.validate(figure); - } - - public void paint(IFigure figure, Graphics graphics) { - super.paint(figure, graphics); - if (arrow1 != null) - arrow1.paint(figure, graphics); - if (arrow2 != null) - arrow2.paint(figure, graphics); - } - - public Rectangle getPreferredBounds(IFigure figure) { - Rectangle r = super.getPreferredBounds(figure); - if (arrow1 != null) - r = r.getUnion(arrow1.getPreferredBounds(figure)); - if (arrow2 != null) - r = r.getUnion(arrow2.getPreferredBounds(figure)); - return r; - } - - public PrecisionPoint getTitlePosition(IFigure figure) { - checkValidation(figure); - return titlePos; - } - - private void updateArrows(IFigure figure) { - if (arrow1 != null) { - arrow1.setPosition(figure, getSourcePosition(figure)); - arrow1.setAngle(figure, getSourceAnchorAngle(figure)); - arrow1.reshape(figure); - } - if (arrow2 != null) { - arrow2.setPosition(figure, getTargetPosition(figure)); - arrow2.setAngle(figure, getTargetAnchorAngle(figure)); - arrow2.reshape(figure); - } - } - - public void paintShadow(IFigure figure, Graphics graphics) { - if (!isVisible()) - return; - checkValidation(figure); - graphics.setAlpha(getAlpha()); - graphics.setForegroundColor(ColorConstants.black); - graphics.setLineWidth(getLineWidth()); - graphics.setLineStyle(getLineStyle()); - drawLine(figure, graphics); - } - - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - ITextFigure tf = getTitleFigure(figure); - if (tf != null && tf.isShowing()) { - Rectangle bounds = figure.getBounds(); - Rectangle titleArea = tf.getBounds(); - if (titleArea.intersects(bounds)) { - graphics.pushState(); - try { - paintPathAroundTitle(figure, graphics, path, fill, bounds, - titleArea); - } finally { - graphics.popState(); - } - return; - } - } - super.paintPath(figure, graphics, path, fill); - } - - private void paintPathAroundTitle(IFigure figure, Graphics graphics, - Path path, boolean fill, Rectangle bounds, Rectangle titleArea) { - // clip the top part - int w = bounds.width; - int h = titleArea.y - bounds.y; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(bounds.x, bounds.y); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - - // clip the bottom part - w = bounds.width; - h = bounds.y + bounds.height - titleArea.y - titleArea.height; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(bounds.x, titleArea.y + titleArea.height); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - - // clip the left part - w = titleArea.x - bounds.x; - h = titleArea.height; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(bounds.x, titleArea.y); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - - // clip the right part - w = bounds.x + bounds.width - titleArea.x - titleArea.width; - if (w > 0 && h > 0) { - CLIP.setSize(w, h); - CLIP.setLocation(titleArea.x + titleArea.width, titleArea.y); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - - CLIP.setBounds(titleArea); - int alpha = graphics.getAlpha(); - graphics.setAlpha((int) (alpha * 0.1)); - paintPathWithClip(figure, graphics, path, fill, CLIP); - } - - protected void paintPathWithClip(IFigure figure, Graphics graphics, - Path path, boolean fill, Rectangle clip) { - graphics.setClip(clip); - super.paintPath(figure, graphics, path, fill); - graphics.restoreState(); - } - - protected ITextFigure getTitleFigure(IFigure figure) { - if (figure instanceof ITitledFigure) { - return ((ITitledFigure) figure).getTitle(); - } - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.decoration.PathConnectionDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.style.Styles; + +public abstract class AbstractRelationshipDecoration + extends PathConnectionDecoration + implements IRelationshipDecoration, IShadowedDecoration { + + private static final Rectangle CLIP = new Rectangle(); + + protected Double sourceCPAngle = null; + + protected Double sourceCPAmount = null; + + protected Double targetCPAngle = null; + + protected Double targetCPAmount = null; + + protected Point relativeSourceCP = null; + + protected Point relativeTargetCP = null; + + private PrecisionPoint sourceCP = null; + + private PrecisionPoint targetCP = null; + + private IArrowDecoration arrow1 = null; + + private IArrowDecoration arrow2 = null; + + private PrecisionPoint titlePos = null; + + protected AbstractRelationshipDecoration() { + } + + protected AbstractRelationshipDecoration(String id) { + super(id); + } + + protected int getLineWidthForChecking() { + return super.getLineWidthForChecking() * 3 + 10; + } + + public void reroute(IFigure figure) { + super.reroute(figure); + updateArrows(figure); + } + + protected void reroute(IFigure figure, PrecisionPoint sourcePos, + PrecisionPoint targetPos, boolean validating) { + PrecisionPoint oldSourceCP = this.sourceCP; + PrecisionPoint oldTargetCP = this.targetCP; + PrecisionPoint oldTitlePos = this.titlePos; + PrecisionPoint newSourceCP = new PrecisionPoint(); + PrecisionPoint newTargetCP = new PrecisionPoint(); + PrecisionPoint newTitlePos = new PrecisionPoint(); + reroute(figure, sourcePos, targetPos, newSourceCP, newTargetCP); + calcTitlePosition(figure, newTitlePos, sourcePos, targetPos, + newSourceCP, newTargetCP); + this.sourceCP = newSourceCP; + this.targetCP = newTargetCP; + this.titlePos = newTitlePos; + if (!validating && figure != null) { + if (!newSourceCP.equals(oldSourceCP) + || !newTargetCP.equals(oldTargetCP) + || !newTitlePos.equals(oldTitlePos)) { + figure.revalidate(); + repaint(figure); + } + } + } + + protected void reroute(IFigure figure, PrecisionPoint sourcePos, + PrecisionPoint targetPos, PrecisionPoint sourceCP, + PrecisionPoint targetCP) { + IAnchor sa = getSourceAnchor(); + IAnchor ta = getTargetAnchor(); +// if (sa != null) +// sourcePos.setLocation(sa.getReferencePoint()); +// if (ta != null) +// targetPos.setLocation(ta.getReferencePoint()); + + PrecisionPoint a1 = null; + PrecisionPoint a2 = null; + if (sa != null) { + if (relativeSourceCP != null) { + sourceCP.setLocation(sa.getReferencePoint()) + .translate(relativeSourceCP.x, relativeSourceCP.y); + sourcePos.setLocation(sa.getLocation(sourceCP, 0)); + } else if (ta != null) { + if (a1 == null) + a1 = sa.getLocation(ta.getReferencePoint(), 0); + sourcePos.setLocation(a1); + if (a2 == null) + a2 = ta.getLocation(sa.getReferencePoint(), 0); + sourceCP.setLocation(a1).move(a2, + Styles.DEF_CONTROL_POINT_AMOUNT); + } + } + + if (ta != null) { + if (relativeTargetCP != null) { + targetCP.setLocation(ta.getReferencePoint()) + .translate(relativeTargetCP.x, relativeTargetCP.y); + targetPos.setLocation(ta.getLocation(targetCP, 0)); + } else if (sa != null) { + if (a2 == null) + a2 = ta.getLocation(sa.getReferencePoint(), 0); + targetPos.setLocation(a2); + if (a1 == null) + a1 = sa.getLocation(ta.getReferencePoint(), 0); + targetCP.setLocation(a2).move(a1, + Styles.DEF_CONTROL_POINT_AMOUNT); + } + } + +// double dx = targetPos.x - sourcePos.x; +// double dy = targetPos.y - sourcePos.y; +// double angle1 = getAngleValue(sourceCPAngle); +// double theta1 = Geometry.getAngle(dx, dy) + angle1; +// sourceCP.setLocation(sourcePos).move(theta1, 100); +// +// double angle2 = getAngleValue(targetCPAngle); +// double theta2 = Geometry.getAngle(-dx, -dy) + angle2; +// targetCP.setLocation(targetPos).move(theta2, 100); +// +// if (sa != null) +// sourcePos.setLocation(sa.getLocation(sourceCP, 0)); +// if (ta != null) +// targetPos.setLocation(ta.getLocation(targetCP, 0)); +// +// dx = targetPos.x - sourcePos.x; +// dy = targetPos.y - sourcePos.y; +// double d = Math.max(Math.hypot(dx, dy), Geometry.MIN_DISTANCE); +// +// double amount1 = getAmountValue(sourceCPAmount); +// sourceCP.setLocation(sourcePos).move(theta1, d * amount1); +// +// double amount2 = getAmountValue(targetCPAmount); +// targetCP.setLocation(targetPos).move(theta2, d * amount2); + } + + protected void updatePosAndCp(IAnchor anchor, PrecisionPoint pos, + PrecisionPoint cp, double angle) { + Point center = anchor.getReferencePoint().toDraw2DPoint(); + Point rotatedCp = Geometry.getRotatedPoint( + new Point(cp.toDraw2DPoint()).translate(-center.x, -center.y), + angle); + cp.setLocation(rotatedCp.translate(center.x, center.y)); + pos.setLocation(anchor.getLocation(cp, 0)); + } + + protected void calcTitlePosition(IFigure figure, PrecisionPoint titlePos, + PrecisionPoint sourcePos, PrecisionPoint targetPos, + PrecisionPoint sourceCP, PrecisionPoint targetCP) { + titlePos.setLocation((sourcePos.x + targetPos.x) / 2, + (sourcePos.y + targetPos.y) / 2); + } + +// private double getAngleValue(Double angle) { +// return angle == null ? Styles.DEF_CONTROL_POINT_ANGLE : angle +// .doubleValue(); +// } +// +// private double getAmountValue(Double amount) { +// return amount == null ? Styles.DEF_CONTROL_POINT_AMOUNT : amount +// .doubleValue(); +// } + + protected boolean isPositionValid() { + return super.isPositionValid() && sourceCP != null && targetCP != null + && titlePos != null; + } + + public PrecisionPoint getSourceControlPoint(IFigure figure) { + checkValidation(figure); + return sourceCP; + } + + public PrecisionPoint getTargetControlPoint(IFigure figure) { + checkValidation(figure); + return targetCP; + } + + public void setRelativeSourceControlPoint(IFigure figure, Point point) { + if (point == this.relativeSourceCP + || (point != null && point.equals(this.relativeSourceCP))) + return; + + this.relativeSourceCP = point; + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + invalidate(); + } + + public void setRelativeTargetControlPoint(IFigure figure, Point point) { + if (point == this.relativeTargetCP + || (point != null && point.equals(this.relativeTargetCP))) + return; + + this.relativeTargetCP = point; + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + invalidate(); + } + + public void setSourceControlPointHint(IFigure figure, Double angle, + Double amount) { + boolean changed = false; + if (angle != this.sourceCPAngle + && (angle == null || !angle.equals(this.sourceCPAngle))) { + changed = true; + this.sourceCPAngle = angle; + } + if (amount != this.sourceCPAmount + && (amount == null || !amount.equals(this.sourceCPAmount))) { + changed = true; + this.sourceCPAmount = amount; + } + if (changed && figure != null) { + figure.revalidate(); + repaint(figure); + } + } + + public void setTargetControlPointHint(IFigure figure, Double angle, + Double amount) { + boolean changed = false; + if (angle != this.targetCPAngle + && (angle == null || !angle.equals(this.targetCPAngle))) { + changed = true; + this.targetCPAngle = angle; + } + if (amount != this.targetCPAmount + && (amount == null || !amount.equals(this.targetCPAmount))) { + changed = true; + this.targetCPAmount = amount; + } + if (changed && figure != null) { + figure.revalidate(); + repaint(figure); + } + } + +// public void setOrthogonalSourceControlPointHint(IFigure figure, +// PrecisionPoint pos) { +// } +// +// public void setOrthogonalTargetControlPointHint(IFigure figure, +// PrecisionPoint pos) { +// } +// +// public Double getPolarSourceControlPointAmountHint() { +// return sourceCPAmount; +// } +// +// public Double getPolarSourceControlPointAngleHint() { +// return sourceCPAngle; +// } + + protected double getSourceAnchorAngle(IFigure figure) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getSourceControlPoint(figure); + return Geometry.getAngle(p2, p1); + } + + protected double getTargetAnchorAngle(IFigure figure) { + PrecisionPoint p1 = getTargetPosition(figure); + PrecisionPoint p2 = getTargetControlPoint(figure); + return Geometry.getAngle(p2, p1); + } + + public IArrowDecoration getArrow1() { + return arrow1; + } + + public IArrowDecoration getArrow2() { + return arrow2; + } + + public void setArrow1(IFigure figure, IArrowDecoration arrow) { + if (arrow == this.arrow1) + return; + + this.arrow1 = arrow; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + } + + public void setArrow2(IFigure figure, IArrowDecoration arrow) { + if (arrow == this.arrow2) + return; + + this.arrow2 = arrow; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + } + + @Override + public void invalidate() { + if (arrow1 != null) + arrow1.invalidate(); + if (arrow2 != null) + arrow2.invalidate(); + super.invalidate(); + } + + public void validate(IFigure figure) { + super.validate(figure); + if (arrow1 != null) + arrow1.validate(figure); + if (arrow2 != null) + arrow2.validate(figure); + } + + public void paint(IFigure figure, Graphics graphics) { + super.paint(figure, graphics); + if (arrow1 != null) + arrow1.paint(figure, graphics); + if (arrow2 != null) + arrow2.paint(figure, graphics); + } + + public Rectangle getPreferredBounds(IFigure figure) { + Rectangle r = super.getPreferredBounds(figure); + if (arrow1 != null) + r = r.getUnion(arrow1.getPreferredBounds(figure)); + if (arrow2 != null) + r = r.getUnion(arrow2.getPreferredBounds(figure)); + return r; + } + + public PrecisionPoint getTitlePosition(IFigure figure) { + checkValidation(figure); + return titlePos; + } + + private void updateArrows(IFigure figure) { + if (arrow1 != null) { + arrow1.setPosition(figure, getSourcePosition(figure)); + arrow1.setAngle(figure, getSourceAnchorAngle(figure)); + arrow1.reshape(figure); + } + if (arrow2 != null) { + arrow2.setPosition(figure, getTargetPosition(figure)); + arrow2.setAngle(figure, getTargetAnchorAngle(figure)); + arrow2.reshape(figure); + } + } + + public void paintShadow(IFigure figure, Graphics graphics) { + if (!isVisible()) + return; + checkValidation(figure); + graphics.setAlpha(getAlpha()); + graphics.setForegroundColor(ColorConstants.black); + graphics.setLineWidth(getLineWidth()); + graphics.setLineStyle(getLineStyle()); + drawLine(figure, graphics); + } + + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + ITextFigure tf = getTitleFigure(figure); + if (tf != null && tf.isShowing()) { + Rectangle bounds = figure.getBounds(); + Rectangle titleArea = tf.getBounds(); + if (titleArea.intersects(bounds)) { + graphics.pushState(); + try { + paintPathAroundTitle(figure, graphics, path, fill, bounds, + titleArea); + } finally { + graphics.popState(); + } + return; + } + } + super.paintPath(figure, graphics, path, fill); + } + + private void paintPathAroundTitle(IFigure figure, Graphics graphics, + Path path, boolean fill, Rectangle bounds, Rectangle titleArea) { + // clip the top part + int w = bounds.width; + int h = titleArea.y - bounds.y; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(bounds.x, bounds.y); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + + // clip the bottom part + w = bounds.width; + h = bounds.y + bounds.height - titleArea.y - titleArea.height; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(bounds.x, titleArea.y + titleArea.height); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + + // clip the left part + w = titleArea.x - bounds.x; + h = titleArea.height; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(bounds.x, titleArea.y); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + + // clip the right part + w = bounds.x + bounds.width - titleArea.x - titleArea.width; + if (w > 0 && h > 0) { + CLIP.setSize(w, h); + CLIP.setLocation(titleArea.x + titleArea.width, titleArea.y); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + + CLIP.setBounds(titleArea); + int alpha = graphics.getAlpha(); + graphics.setAlpha((int) (alpha * 0.1)); + paintPathWithClip(figure, graphics, path, fill, CLIP); + } + + protected void paintPathWithClip(IFigure figure, Graphics graphics, + Path path, boolean fill, Rectangle clip) { + graphics.setClip(clip); + super.paintPath(figure, graphics, path, fill); + graphics.restoreState(); + } + + protected ITextFigure getTitleFigure(IFigure figure) { + if (figure instanceof ITitledFigure) { + return ((ITitledFigure) figure).getTitle(); + } + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBoundaryDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBoundaryDecoration.java index c45875c8a..3a9748611 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBoundaryDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBoundaryDecoration.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.xmind.gef.draw2d.decoration.IShapeDecorationEx; - -public interface IBoundaryDecoration extends IShapeDecorationEx { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.xmind.gef.draw2d.decoration.IShapeDecorationEx; + +public interface IBoundaryDecoration extends IShapeDecorationEx { + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchConnections2.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchConnections2.java index 92e7806d1..3bb6a830b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchConnections2.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchConnections2.java @@ -1,31 +1,31 @@ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.decoration.ICompoundDecoration; - -public interface IBranchConnections2 extends ICompoundDecoration, - ILineDecoration2 { - - void setSourceOrientation(IFigure figure, int index, int orientation); - - void setSourceExpansion(IFigure figure, int index, int expansion); - - void setTapered(IFigure figure, boolean tapered); - - int getSourceExpansion(int index); - - int getSourceOrientation(int index); - - boolean isTapered(); - - IAnchor getSourceAnchor(int index); - - void setSourceAnchor(IFigure figure, int index, IAnchor anchor); - - void setCornerSize(IFigure figure, int index, int cornerSize); - - int getCornerSize(int index); - - void rerouteAll(IFigure figure); -} +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.decoration.ICompoundDecoration; + +public interface IBranchConnections2 extends ICompoundDecoration, + ILineDecoration2 { + + void setSourceOrientation(IFigure figure, int index, int orientation); + + void setSourceExpansion(IFigure figure, int index, int expansion); + + void setTapered(IFigure figure, boolean tapered); + + int getSourceExpansion(int index); + + int getSourceOrientation(int index); + + boolean isTapered(); + + IAnchor getSourceAnchor(int index); + + void setSourceAnchor(IFigure figure, int index, IAnchor anchor); + + void setCornerSize(IFigure figure, int index, int cornerSize); + + int getCornerSize(int index); + + void rerouteAll(IFigure figure); +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchDecoration.java index ab4c09281..024da5cef 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IBranchDecoration.java @@ -1,24 +1,24 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.decoration.IDecoration; - -public interface IBranchDecoration extends IDecoration { - - void paintAboveChildren(IFigure figure, Graphics graphics); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.decoration.IDecoration; + +public interface IBranchDecoration extends IDecoration { + + void paintAboveChildren(IFigure figure, Graphics graphics); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ICalloutTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ICalloutTopicDecoration.java index a628d77c3..6c0da255f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ICalloutTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ICalloutTopicDecoration.java @@ -1,33 +1,33 @@ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.draw2d.decoration.IDecoration; - -public interface ICalloutTopicDecoration extends IDecoration { - - public void setFromLineColor(IFigure figure, Color fromLineColor); - - public void setFromLineWidth(IFigure figure, int fromLineWidth); - - public void setFromLineClass(IFigure figure, String fromLineClass); - - public void setFromLineStyle(IFigure figure, int fromLinePattern); - - public void setFromLineCorner(IFigure figure, int fromLineCorner); - - public void setFromFillColor(IFigure figure, Color fromFillColor); - - public Color getFromFillColor(); - - public Color getFromLineColor(); - - public int getFromLineWidth(); - - public String getFromLineClass(); - - public int getFromLineStyle(); - - public int getFromLineCorner(); - -} +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.draw2d.decoration.IDecoration; + +public interface ICalloutTopicDecoration extends IDecoration { + + public void setFromLineColor(IFigure figure, Color fromLineColor); + + public void setFromLineWidth(IFigure figure, int fromLineWidth); + + public void setFromLineClass(IFigure figure, String fromLineClass); + + public void setFromLineStyle(IFigure figure, int fromLinePattern); + + public void setFromLineCorner(IFigure figure, int fromLineCorner); + + public void setFromFillColor(IFigure figure, Color fromFillColor); + + public Color getFromFillColor(); + + public Color getFromLineColor(); + + public int getFromLineWidth(); + + public String getFromLineClass(); + + public int getFromLineStyle(); + + public int getFromLineCorner(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationFactory.java index d9ad7a7a0..bba33baf3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationFactory.java @@ -1,23 +1,23 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; - -public interface IDecorationFactory { - - IDecoration createDecoration(String decorationId, IGraphicalPart part); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; + +public interface IDecorationFactory { + + IDecoration createDecoration(String decorationId, IGraphicalPart part); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationManager.java index 029975411..3088212c5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IDecorationManager.java @@ -1,41 +1,41 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import java.util.List; - -public interface IDecorationManager { - - // Decoration Categories: - String CATEGORY_BRANCH_CONNECTIONS = "org.xmind.ui.branchConnections"; //$NON-NLS-1$ - - String CATEGORY_TOPIC_SHAPE = "org.xmind.ui.topicDecorations"; //$NON-NLS-1$ - - String CATEGORY_REL_SHAPE = "org.xmind.ui.relationshipDecorations"; //$NON-NLS-1$ - - String CATEGORY_BOUNDARY_SHAPE = "org.xmind.ui.boundaryDecorations"; //$NON-NLS-1$ - - String CATEGORY_SUMMARY_SHAPE = "org.xmind.ui.summaryDecorations"; //$NON-NLS-1$ - - String CATEGORY_ARROW_SHAPE = "org.xmind.ui.arrowDecorations"; //$NON-NLS-1$ - - String CATEGORY_CALLOUT_SHAPE = "org.xmind.ui.calloutTopicDecorations"; //$NON-NLS-1$ - - String CATEGORY_CALLOUT_BRANCH_CONNECTIONS = "org.xmind.ui.calloutConnections"; //$NON-NLS-1$ - - IDecorationDescriptor getDecorationDescriptor(String decorationId); - - List getDescriptors(String categoryId); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import java.util.List; + +public interface IDecorationManager { + + // Decoration Categories: + String CATEGORY_BRANCH_CONNECTIONS = "org.xmind.ui.branchConnections"; //$NON-NLS-1$ + + String CATEGORY_TOPIC_SHAPE = "org.xmind.ui.topicDecorations"; //$NON-NLS-1$ + + String CATEGORY_REL_SHAPE = "org.xmind.ui.relationshipDecorations"; //$NON-NLS-1$ + + String CATEGORY_BOUNDARY_SHAPE = "org.xmind.ui.boundaryDecorations"; //$NON-NLS-1$ + + String CATEGORY_SUMMARY_SHAPE = "org.xmind.ui.summaryDecorations"; //$NON-NLS-1$ + + String CATEGORY_ARROW_SHAPE = "org.xmind.ui.arrowDecorations"; //$NON-NLS-1$ + + String CATEGORY_CALLOUT_SHAPE = "org.xmind.ui.calloutTopicDecorations"; //$NON-NLS-1$ + + String CATEGORY_CALLOUT_BRANCH_CONNECTIONS = "org.xmind.ui.calloutConnections"; //$NON-NLS-1$ + + IDecorationDescriptor getDecorationDescriptor(String decorationId); + + List getDescriptors(String categoryId); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ILineDecoration2.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ILineDecoration2.java index 2160cadbc..b3061d6cb 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ILineDecoration2.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/ILineDecoration2.java @@ -1,46 +1,46 @@ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.draw2d.decoration.IDecoration; - -public interface ILineDecoration2 extends IDecoration { - - /** - * @return the color - */ - Color getLineColor(int index); - - /** - * - * @return - */ - int getLineStyle(int index); - - /** - * @return the width - */ - int getLineWidth(int index); - - /** - * - * @param figure - * @param color - */ - void setLineColor(IFigure figure, int index, Color color); - - /** - * - * @param figure - * @param width - */ - void setLineWidth(IFigure figure, int index, int width); - - /** - * - * @param figure - * @param style - */ - void setLineStyle(IFigure figure, int index, int style); - -} +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.draw2d.decoration.IDecoration; + +public interface ILineDecoration2 extends IDecoration { + + /** + * @return the color + */ + Color getLineColor(int index); + + /** + * + * @return + */ + int getLineStyle(int index); + + /** + * @return the width + */ + int getLineWidth(int index); + + /** + * + * @param figure + * @param color + */ + void setLineColor(IFigure figure, int index, Color color); + + /** + * + * @param figure + * @param width + */ + void setLineWidth(IFigure figure, int index, int width); + + /** + * + * @param figure + * @param style + */ + void setLineStyle(IFigure figure, int index, int style); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IRelationshipDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IRelationshipDecoration.java index 1223a8052..5fba70649 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IRelationshipDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/IRelationshipDecoration.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.xmind.gef.draw2d.decoration.IConnectionDecorationEx; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; - -public interface IRelationshipDecoration extends IConnectionDecorationEx { - - PrecisionPoint getSourceControlPoint(IFigure figure); - - PrecisionPoint getTargetControlPoint(IFigure figure); - - void setRelativeSourceControlPoint(IFigure figure, Point point); - - void setRelativeTargetControlPoint(IFigure figure, Point point); - - void setSourceControlPointHint(IFigure figure, Double angle, Double amount); - - void setTargetControlPointHint(IFigure figure, Double angle, Double amount); - - IArrowDecoration getArrow1(); //sourceArrow - - void setArrow1(IFigure figure, IArrowDecoration arrow); - - IArrowDecoration getArrow2(); - - void setArrow2(IFigure figure, IArrowDecoration arrow); - - PrecisionPoint getTitlePosition(IFigure figure); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.draw2d.decoration.IConnectionDecorationEx; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; + +public interface IRelationshipDecoration extends IConnectionDecorationEx { + + PrecisionPoint getSourceControlPoint(IFigure figure); + + PrecisionPoint getTargetControlPoint(IFigure figure); + + void setRelativeSourceControlPoint(IFigure figure, Point point); + + void setRelativeTargetControlPoint(IFigure figure, Point point); + + void setSourceControlPointHint(IFigure figure, Double angle, Double amount); + + void setTargetControlPointHint(IFigure figure, Double angle, Double amount); + + IArrowDecoration getArrow1(); //sourceArrow + + void setArrow1(IFigure figure, IArrowDecoration arrow); + + IArrowDecoration getArrow2(); + + void setArrow2(IFigure figure, IArrowDecoration arrow); + + PrecisionPoint getTitlePosition(IFigure figure); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/dialogs/IDialogConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/dialogs/IDialogConstants.java index e02beab36..fd7c42d27 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/dialogs/IDialogConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/dialogs/IDialogConstants.java @@ -1,26 +1,26 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.dialogs; - -import org.xmind.ui.internal.dialogs.DialogMessages; - -public interface IDialogConstants { - - public static final String COMMON_TITLE = DialogMessages.CommonDialogTitle; - - public static final String FILE_DIALOG_FILTER_WORKBOOK = DialogMessages.WorkbookFilterName; - - public static final String FILE_DIALOG_FILTER_TEMPLATE = DialogMessages.TemplateFilterName; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.dialogs; + +import org.xmind.ui.internal.dialogs.DialogMessages; + +public interface IDialogConstants { + + public static final String COMMON_TITLE = DialogMessages.CommonDialogTitle; + + public static final String FILE_DIALOG_FILTER_WORKBOOK = DialogMessages.WorkbookFilterName; + + public static final String FILE_DIALOG_FILTER_TEMPLATE = DialogMessages.TemplateFilterName; + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/EditorHistoryItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/EditorHistoryItem.java index 71b9e7a1a..85e4382b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/EditorHistoryItem.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/EditorHistoryItem.java @@ -1,108 +1,108 @@ -package org.xmind.ui.editor; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.protocols.FilePathParser; - -public class EditorHistoryItem implements IEditorHistoryItem { - - public static final String KEY_NAME = "name"; //$NON-NLS-1$ - public static final String KEY_OPENED_TIME = "openedTime"; //$NON-NLS-1$ - - private static final String defaultName = MindMapMessages.EditorHistoryItem_defaultName; - - private String name; - - private long openedTime; - - public EditorHistoryItem(String name, long openedTime) { - if (name == null || name.trim().equals("")) //$NON-NLS-1$ - this.name = defaultName; - else - this.name = name; - this.openedTime = openedTime; - } - - @Override - public String getName() { - return name; - } - - @Override - public long getOpenedTime() { - return openedTime; - } - - @Override - public String toJson() { - JSONObject json = new JSONObject(); - json.put(KEY_NAME, name); - json.put(KEY_OPENED_TIME, openedTime); - return json.toString(); - } - - public static IEditorHistoryItem readEditorHistoryItem(String uriString, - String json) { - if (null == json || json.trim().equals("")) {//$NON-NLS-1$ - if (null == uriString || uriString.trim().equals("")) //$NON-NLS-1$ - return new EditorHistoryItem(defaultName, - System.currentTimeMillis()); - try { - URI uri = new URI(uriString); - Map labels = new HashMap(); - FilePathParser.calculateFileURILabels(new URI[] { uri }, - labels); - return new EditorHistoryItem(labels.get(uri), - System.currentTimeMillis()); - } catch (URISyntaxException e) { - MindMapUIPlugin.log(e, - "EditorHistoryItem parase uri to file name occur Some error."); //$NON-NLS-1$ - } - return null; - } - try { - /* - * The version of JSONObject is too old , it does not support - * JSONObject.toBean() and JSONObject.fromString(). - */ - JSONObject itemJson = new JSONObject(new JSONTokener(json)); - String jName = itemJson.getString(EditorHistoryItem.KEY_NAME); - long jTime = itemJson.getLong(EditorHistoryItem.KEY_OPENED_TIME); - - IEditorHistoryItem item = new EditorHistoryItem(jName, jTime); - return item; - } catch (JSONException e) { - MindMapUIPlugin.log(e, - "Read Json of EditorHistoryItem occur Some error."); //$NON-NLS-1$ - return new EditorHistoryItem(defaultName, - System.currentTimeMillis()); - } - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof EditorHistoryItem)) - return false; - - EditorHistoryItem that = (EditorHistoryItem) obj; - return this.name == that.name && this.openedTime == that.openedTime; - } - - @Override - public String toString() { - return "EditorHistoryItem : (" + (name = name == null ? " " //$NON-NLS-1$ //$NON-NLS-2$ - : name) + "," + Calendar.getInstance().getTime() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - -} +package org.xmind.ui.editor; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.protocols.FilePathParser; + +public class EditorHistoryItem implements IEditorHistoryItem { + + public static final String KEY_NAME = "name"; //$NON-NLS-1$ + public static final String KEY_OPENED_TIME = "openedTime"; //$NON-NLS-1$ + + private static final String defaultName = MindMapMessages.EditorHistoryItem_defaultName; + + private String name; + + private long openedTime; + + public EditorHistoryItem(String name, long openedTime) { + if (name == null || name.trim().equals("")) //$NON-NLS-1$ + this.name = defaultName; + else + this.name = name; + this.openedTime = openedTime; + } + + @Override + public String getName() { + return name; + } + + @Override + public long getOpenedTime() { + return openedTime; + } + + @Override + public String toJson() { + JSONObject json = new JSONObject(); + json.put(KEY_NAME, name); + json.put(KEY_OPENED_TIME, openedTime); + return json.toString(); + } + + public static IEditorHistoryItem readEditorHistoryItem(String uriString, + String json) { + if (null == json || json.trim().equals("")) {//$NON-NLS-1$ + if (null == uriString || uriString.trim().equals("")) //$NON-NLS-1$ + return new EditorHistoryItem(defaultName, + System.currentTimeMillis()); + try { + URI uri = new URI(uriString); + Map labels = new HashMap(); + FilePathParser.calculateFileURILabels(new URI[] { uri }, + labels); + return new EditorHistoryItem(labels.get(uri), + System.currentTimeMillis()); + } catch (URISyntaxException e) { + MindMapUIPlugin.log(e, + "EditorHistoryItem parase uri to file name occur Some error."); //$NON-NLS-1$ + } + return null; + } + try { + /* + * The version of JSONObject is too old , it does not support + * JSONObject.toBean() and JSONObject.fromString(). + */ + JSONObject itemJson = new JSONObject(new JSONTokener(json)); + String jName = itemJson.getString(EditorHistoryItem.KEY_NAME); + long jTime = itemJson.getLong(EditorHistoryItem.KEY_OPENED_TIME); + + IEditorHistoryItem item = new EditorHistoryItem(jName, jTime); + return item; + } catch (JSONException e) { + MindMapUIPlugin.log(e, + "Read Json of EditorHistoryItem occur Some error."); //$NON-NLS-1$ + return new EditorHistoryItem(defaultName, + System.currentTimeMillis()); + } + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof EditorHistoryItem)) + return false; + + EditorHistoryItem that = (EditorHistoryItem) obj; + return this.name == that.name && this.openedTime == that.openedTime; + } + + @Override + public String toString() { + return "EditorHistoryItem : (" + (name = name == null ? " " //$NON-NLS-1$ //$NON-NLS-2$ + : name) + "," + Calendar.getInstance().getTime() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistory.java index a5c723fbf..50d59beff 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistory.java @@ -1,219 +1,219 @@ -package org.xmind.ui.editor; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -/** - * This class is responsible for maintaining a list of unique editor input URIs. - *

    - * Input URIs in an editor history list can be pinned so that it will - * always stay in the list. Unpinned input URIs will automatically be evicted in - * the FIFO manner when the count of unpinned ones exceeds - * {@link #MAX_UNPINNED_SIZE}. - *

    - *

    - * NOTE that methods of this class are NOT thread-safe. Undefined - * behavior may apply when any two methods are called simultaneously. - *

    - * - * @author Frank Shaka - * @since 3.6 - */ -public interface IEditorHistory { - - /** - * The maximum number of unpinned input URIs an editor history list can - * maintain (value=100). - */ - int MAX_UNPINNED_SIZE = 100; - - /** - * A listener for editor history change events. - * - * @author Frank Shaka - * @since 3.6 - */ - interface IEditorHistoryListener { - - /** - * Called when the contents of this editor history list has changed. - */ - void editorHistoryChanged(); - - } - - /** - * Returns a list of input URIs recently added. The result consists of - * most-recently-added pinned input URIs, least-recently-added pinned input - * URIs, most-recently-added unpinned input URIs and least-recently-added - * unpinned input URIs, in the respective order. No more than - * unpinnedSize unpinned input URIs, or all unpinned - * input URIs if unpinnedSize is negative, will be included in - * the result. - * - * @param unpinnedSize - * a positive number or zero to specify how many unpinned input - * URIs at most are desired, or a negative number for all - * unpinned input URIs - * @return an array or recent input URIs, or an empty array (never - * null) - */ - URI[] getRecentInputURIs(int unpinnedSize); - - /** - * Returns all input URIs currently maintained by this editor history. The - * result consists of most-recently-added pinned input URIs, - * least-recently-added pinned input URIs, most-recently-added unpinned - * input URIs and least-recently-added unpinned input URIs, in the - * respective order. All pinned and unpinned input URIs are returned. - * - * @return an array of all input URIs, or an empty array (never - * null) - */ - URI[] getAllInputURIs(); - - /** - * Returns all pinned input URIs. - * - * @return an array of all pinned input URIs, or an empty array (never - * null) - */ - URI[] getPinnedInputURIs(); - - /** - * Returns unpinned input URIs recently added. No more than - * unpinnedSize unpinned input URIs, or all unpinned - * input URIs if unpinnedSize is negative, will be included in - * the result. - * - * @param unpinnedSize - * a positive number or zero to specify how many unpinned input - * URIs at most are desired, or a negative number for all - * unpinned input URIs - * @return an array or recent input URIs, or an empty array (never - * null) - */ - URI[] getUnpinnedInputURIs(int unpinnedSize); - - /** - * Adds an input URI to this editor history list. If this input URI already - * exists in the list, this pinned/unpinned one will be moved ahead of all - * other pinned/unpinned ones, respectively. Otherwise, the new input URI - * will be inserted ahead of all other unpinned ones. - *

    - * Note that old input URIs may be evicted during the process of this - * operation if the size of the unpinned ones exceed - * {@link #MAX_UNPINNED_SIZE}. - *

    - * - * @param inputURI - * the input URI to add - */ - void add(URI inputURI); - - void add(URI uri, IEditorHistoryItem item); - - IEditorHistoryItem getItem(URI inputURI); - - /** - * Removes an input URI from this editor history list and deletes all its - * attached information. - * - * @param inputURI - * the input URI to remove - */ - void remove(URI inputURI); - - /** - * Removes all unpinned input URIs from this editor history list. - */ - void clear(); - - /** - * Opens a new input stream for the thumbnail image data of a corresponding - * input URI. The client must close the returned stream in case of - * resource leak. - * - * @param inputURI - * the input URI of which thumbnail image data is being read - * @return a new input stream to read the thumbnail image data of the - * specified input URI, or null if no thumbnail image - * has been saved for this input URI - * @throws IOException - * if any I/O exception occurs during opening thumbnail image - * data stream - */ - InputStream loadThumbnailData(URI inputURI) throws IOException; - - /** - * Writes thumbnail image data of a corresponding input URI from specified - * input stream. The client must close the given stream after this - * method returns. - *

    - * Note that calling this method blocks the current thead. - *

    - * - * @param inputURI - * the input URI of which thumbnail image data is being written - * @param thumbnailData - * an input stream for the thumbnail image data of the specified - * input URI - * @throws IOException - * if any I/O exception occurs during saving thumbnail image - * data - */ - void saveThumbnailData(URI inputURI, InputStream thumbnailData) - throws IOException; - - /** - * Marks an input URI as pinned. Pinned input URIs will always stay - * in this editor history list and appears ahead of unpinned input URIs. - * - * @param inputURI - * the input URI to mark - * @see #unPin(URI) - * @see #isPinned(URI) - */ - void pin(URI inputURI); - - /** - * Marks an input URI as unpinned. Unpinned input URIs will be - * automatically evicted if size limit is reached. - * - * @param inputURI - * the input URI to mark - * @see #pin(URI) - * @see #isPinned(URI) - */ - void unPin(URI inputURI); - - /** - * Checks whether an input URI is pinned or not. - * - * @param inputURI - * the input URI to check - * @return true if the specified input URI is pinned, or - * false otherwise - * @see #pin(URI) - * @see #unPin(URI) - */ - boolean isPinned(URI inputURI); - - /** - * Adds a listener to track editor history changes. - * - * @param listener - * the listener to add - */ - void removeEditorHistoryListener(IEditorHistoryListener listener); - - /** - * Removes a listener to stop tracking editor history changes. - * - * @param listener - * the listener to remove - */ - void addEditorHistoryListener(IEditorHistoryListener listener); - -} +package org.xmind.ui.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +/** + * This class is responsible for maintaining a list of unique editor input URIs. + *

    + * Input URIs in an editor history list can be pinned so that it will + * always stay in the list. Unpinned input URIs will automatically be evicted in + * the FIFO manner when the count of unpinned ones exceeds + * {@link #MAX_UNPINNED_SIZE}. + *

    + *

    + * NOTE that methods of this class are NOT thread-safe. Undefined + * behavior may apply when any two methods are called simultaneously. + *

    + * + * @author Frank Shaka + * @since 3.6 + */ +public interface IEditorHistory { + + /** + * The maximum number of unpinned input URIs an editor history list can + * maintain (value=100). + */ + int MAX_UNPINNED_SIZE = 100; + + /** + * A listener for editor history change events. + * + * @author Frank Shaka + * @since 3.6 + */ + interface IEditorHistoryListener { + + /** + * Called when the contents of this editor history list has changed. + */ + void editorHistoryChanged(); + + } + + /** + * Returns a list of input URIs recently added. The result consists of + * most-recently-added pinned input URIs, least-recently-added pinned input + * URIs, most-recently-added unpinned input URIs and least-recently-added + * unpinned input URIs, in the respective order. No more than + * unpinnedSize unpinned input URIs, or all unpinned + * input URIs if unpinnedSize is negative, will be included in + * the result. + * + * @param unpinnedSize + * a positive number or zero to specify how many unpinned input + * URIs at most are desired, or a negative number for all + * unpinned input URIs + * @return an array or recent input URIs, or an empty array (never + * null) + */ + URI[] getRecentInputURIs(int unpinnedSize); + + /** + * Returns all input URIs currently maintained by this editor history. The + * result consists of most-recently-added pinned input URIs, + * least-recently-added pinned input URIs, most-recently-added unpinned + * input URIs and least-recently-added unpinned input URIs, in the + * respective order. All pinned and unpinned input URIs are returned. + * + * @return an array of all input URIs, or an empty array (never + * null) + */ + URI[] getAllInputURIs(); + + /** + * Returns all pinned input URIs. + * + * @return an array of all pinned input URIs, or an empty array (never + * null) + */ + URI[] getPinnedInputURIs(); + + /** + * Returns unpinned input URIs recently added. No more than + * unpinnedSize unpinned input URIs, or all unpinned + * input URIs if unpinnedSize is negative, will be included in + * the result. + * + * @param unpinnedSize + * a positive number or zero to specify how many unpinned input + * URIs at most are desired, or a negative number for all + * unpinned input URIs + * @return an array or recent input URIs, or an empty array (never + * null) + */ + URI[] getUnpinnedInputURIs(int unpinnedSize); + + /** + * Adds an input URI to this editor history list. If this input URI already + * exists in the list, this pinned/unpinned one will be moved ahead of all + * other pinned/unpinned ones, respectively. Otherwise, the new input URI + * will be inserted ahead of all other unpinned ones. + *

    + * Note that old input URIs may be evicted during the process of this + * operation if the size of the unpinned ones exceed + * {@link #MAX_UNPINNED_SIZE}. + *

    + * + * @param inputURI + * the input URI to add + */ + void add(URI inputURI); + + void add(URI uri, IEditorHistoryItem item); + + IEditorHistoryItem getItem(URI inputURI); + + /** + * Removes an input URI from this editor history list and deletes all its + * attached information. + * + * @param inputURI + * the input URI to remove + */ + void remove(URI inputURI); + + /** + * Removes all unpinned input URIs from this editor history list. + */ + void clear(); + + /** + * Opens a new input stream for the thumbnail image data of a corresponding + * input URI. The client must close the returned stream in case of + * resource leak. + * + * @param inputURI + * the input URI of which thumbnail image data is being read + * @return a new input stream to read the thumbnail image data of the + * specified input URI, or null if no thumbnail image + * has been saved for this input URI + * @throws IOException + * if any I/O exception occurs during opening thumbnail image + * data stream + */ + InputStream loadThumbnailData(URI inputURI) throws IOException; + + /** + * Writes thumbnail image data of a corresponding input URI from specified + * input stream. The client must close the given stream after this + * method returns. + *

    + * Note that calling this method blocks the current thead. + *

    + * + * @param inputURI + * the input URI of which thumbnail image data is being written + * @param thumbnailData + * an input stream for the thumbnail image data of the specified + * input URI + * @throws IOException + * if any I/O exception occurs during saving thumbnail image + * data + */ + void saveThumbnailData(URI inputURI, InputStream thumbnailData) + throws IOException; + + /** + * Marks an input URI as pinned. Pinned input URIs will always stay + * in this editor history list and appears ahead of unpinned input URIs. + * + * @param inputURI + * the input URI to mark + * @see #unPin(URI) + * @see #isPinned(URI) + */ + void pin(URI inputURI); + + /** + * Marks an input URI as unpinned. Unpinned input URIs will be + * automatically evicted if size limit is reached. + * + * @param inputURI + * the input URI to mark + * @see #pin(URI) + * @see #isPinned(URI) + */ + void unPin(URI inputURI); + + /** + * Checks whether an input URI is pinned or not. + * + * @param inputURI + * the input URI to check + * @return true if the specified input URI is pinned, or + * false otherwise + * @see #pin(URI) + * @see #unPin(URI) + */ + boolean isPinned(URI inputURI); + + /** + * Adds a listener to track editor history changes. + * + * @param listener + * the listener to add + */ + void removeEditorHistoryListener(IEditorHistoryListener listener); + + /** + * Removes a listener to stop tracking editor history changes. + * + * @param listener + * the listener to remove + */ + void addEditorHistoryListener(IEditorHistoryListener listener); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistoryItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistoryItem.java index f883cd95b..bf14b2685 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistoryItem.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistoryItem.java @@ -1,11 +1,11 @@ -package org.xmind.ui.editor; - -public interface IEditorHistoryItem { - - String getName(); - - long getOpenedTime(); - - String toJson(); - -} +package org.xmind.ui.editor; + +public interface IEditorHistoryItem { + + String getName(); + + long getOpenedTime(); + + String toJson(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/PageTitleTabFolderRenderer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/PageTitleTabFolderRenderer.java index bc03da629..ea9de87ea 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/PageTitleTabFolderRenderer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/PageTitleTabFolderRenderer.java @@ -1,201 +1,201 @@ -package org.xmind.ui.editor; - -import java.util.List; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabFolderRenderer; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.TextLayout; -import org.xmind.core.ISettingEntry; -import org.xmind.core.ISheet; -import org.xmind.core.ISheetSettings; -import org.xmind.ui.internal.editor.MindMapEditor; -import org.xmind.ui.resources.ColorUtils; - -public class PageTitleTabFolderRenderer extends CTabFolderRenderer { - - private static final int FLAGS = 9; - - private static final String ELLIPSIS = "..."; //$NON-NLS-1$ - - private MindMapEditor editor; - - private ResourceManager resources; - - public PageTitleTabFolderRenderer(CTabFolder parent, MindMapEditor editor) { - super(parent); - this.editor = editor; - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - } - - @Override - protected void draw(final int part, int state, Rectangle bounds, GC gc) { - super.draw(part, state, bounds, gc); - - if (0 <= part && part < parent.getItemCount()) { - if (bounds.width == 0 || bounds.height == 0) - return; - if ((state & SWT.SELECTED) != 0) { - drawSelectedItem(part, gc, bounds, state); - } else { - drawUnselectedItem(part, gc, bounds, state); - } - } - } - - private void drawSelectedItem(int index, GC gc, Rectangle bounds, - int state) { - if ((state & SWT.BACKGROUND) != 0) { - drawItemBackground(index, gc, true); - } - if ((state & SWT.FOREGROUND) != 0) { - drawItemText(index, gc); - } - } - - private void drawUnselectedItem(int index, GC gc, Rectangle bounds, - int state) { - CTabItem item = parent.getItem(index); - // Do not draw partial items - if (!item.isShowing()) - return; - - Rectangle clipping = gc.getClipping(); - if (!clipping.intersects(bounds)) - return; - - if ((state & SWT.BACKGROUND) != 0) { - drawItemBackground(index, gc, false); - } - } - - private void drawItemBackground(int index, GC gc, boolean selected) { - Rectangle bounds = parent.getItem(index).getBounds(); - Color gcBackground = gc.getBackground(); - - Color background = getColor(index); - if (background != null && !gcBackground.equals(background)) { - gc.setBackground(background); - - Rectangle paintedArea = selected - ? new Rectangle(bounds.x, bounds.y + bounds.height * 6 / 7, - bounds.width, bounds.height / 7) - : new Rectangle(bounds.x, bounds.y, bounds.width, - bounds.height / 7); - gc.fillRectangle(paintedArea); - - //recovery gc context - gc.setBackground(gcBackground); - } - } - - private void drawItemText(int index, GC gc) { - Color foreground = getColor(index); - if (foreground == null || foreground.equals(gc.getForeground())) { - return; - } - - CTabItem item = parent.getItem(index); - Rectangle bounds = item.getBounds(); - int x = bounds.x; - int y = bounds.y; - int height = bounds.height; - int width = bounds.width; - - Rectangle trim = computeTrim(index, SWT.NONE, 0, 0, 0, 0); - int xDraw = x - trim.x; - - int textWidth = x + width - xDraw - (trim.width + trim.x); - if (textWidth > 0) { - Font gcFont = gc.getFont(); - Color gcForeground = gc.getForeground(); - Color gcBackground = gc.getBackground(); - gc.setFont(item.getFont()); - gc.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - String shortenedText = shortenText2(gc, item.getText(), textWidth); - Point extent = gc.textExtent(shortenedText, FLAGS); - int textY = y + (height - extent.y) / 2; - boolean onBottom = (parent.getStyle() & SWT.BOTTOM) != 0; - textY += onBottom ? -1 : 1; - - gc.setForeground(foreground); - -// gc.setBackground(); - gc.drawText(shortenedText, xDraw, textY, false); - - //recovery gc context - gc.setFont(gcFont); - gc.setForeground(gcForeground); - gc.setBackground(gcBackground); - } - } - - private String shortenText2(GC gc, String text, int width) { - return useEllipses2() ? shortenText2(gc, text, width, ELLIPSIS) - : shortenText2(gc, text, width, ""); //$NON-NLS-1$ - } - - private boolean useEllipses2() { - return parent.getSimple(); - } - - private String shortenText2(GC gc, String text, int width, - String ellipses) { - if (gc.textExtent(text, FLAGS).x <= width) - return text; - int ellipseWidth = gc.textExtent(ellipses, FLAGS).x; - int length = text.length(); - TextLayout layout = new TextLayout(parent.getDisplay()); - layout.setText(text); - int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER); - while (end > 0) { - text = text.substring(0, end); - int l = gc.textExtent(text, FLAGS).x; - if (l + ellipseWidth <= width) { - break; - } - end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER); - } - layout.dispose(); - return end == 0 ? text.substring(0, 1) : text + ellipses; - } - - private Color getColor(int index) { - if (index < 0 || index >= editor.getPages().length) { - return null; - } - - ISheet sheet = editor.getPage(index).getAdapter(ISheet.class); - String rgb = getRgb(sheet); - - if (rgb == null || rgb.equals("")) { //$NON-NLS-1$ - return null; - } - return (Color) resources.get(ColorUtils.toDescriptor(rgb)); - } - - private String getRgb(ISheet sheet) { - ISettingEntry entry = findEntry(sheet); - return entry == null ? null - : entry.getAttribute(ISheetSettings.ATTR_RGB); - } - - private ISettingEntry findEntry(ISheet sheet) { - List entries = sheet.getSettings() - .getEntries(ISheetSettings.TAB_COLOR); - return entries.size() == 0 ? null : entries.get(0); - } - -} +package org.xmind.ui.editor; + +import java.util.List; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolderRenderer; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.TextLayout; +import org.xmind.core.ISettingEntry; +import org.xmind.core.ISheet; +import org.xmind.core.ISheetSettings; +import org.xmind.ui.internal.editor.MindMapEditor; +import org.xmind.ui.resources.ColorUtils; + +public class PageTitleTabFolderRenderer extends CTabFolderRenderer { + + private static final int FLAGS = 9; + + private static final String ELLIPSIS = "..."; //$NON-NLS-1$ + + private MindMapEditor editor; + + private ResourceManager resources; + + public PageTitleTabFolderRenderer(CTabFolder parent, MindMapEditor editor) { + super(parent); + this.editor = editor; + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + } + + @Override + protected void draw(final int part, int state, Rectangle bounds, GC gc) { + super.draw(part, state, bounds, gc); + + if (0 <= part && part < parent.getItemCount()) { + if (bounds.width == 0 || bounds.height == 0) + return; + if ((state & SWT.SELECTED) != 0) { + drawSelectedItem(part, gc, bounds, state); + } else { + drawUnselectedItem(part, gc, bounds, state); + } + } + } + + private void drawSelectedItem(int index, GC gc, Rectangle bounds, + int state) { + if ((state & SWT.BACKGROUND) != 0) { + drawItemBackground(index, gc, true); + } + if ((state & SWT.FOREGROUND) != 0) { + drawItemText(index, gc); + } + } + + private void drawUnselectedItem(int index, GC gc, Rectangle bounds, + int state) { + CTabItem item = parent.getItem(index); + // Do not draw partial items + if (!item.isShowing()) + return; + + Rectangle clipping = gc.getClipping(); + if (!clipping.intersects(bounds)) + return; + + if ((state & SWT.BACKGROUND) != 0) { + drawItemBackground(index, gc, false); + } + } + + private void drawItemBackground(int index, GC gc, boolean selected) { + Rectangle bounds = parent.getItem(index).getBounds(); + Color gcBackground = gc.getBackground(); + + Color background = getColor(index); + if (background != null && !gcBackground.equals(background)) { + gc.setBackground(background); + + Rectangle paintedArea = selected + ? new Rectangle(bounds.x, bounds.y + bounds.height * 6 / 7, + bounds.width, bounds.height / 7) + : new Rectangle(bounds.x, bounds.y, bounds.width, + bounds.height / 7); + gc.fillRectangle(paintedArea); + + //recovery gc context + gc.setBackground(gcBackground); + } + } + + private void drawItemText(int index, GC gc) { + Color foreground = getColor(index); + if (foreground == null || foreground.equals(gc.getForeground())) { + return; + } + + CTabItem item = parent.getItem(index); + Rectangle bounds = item.getBounds(); + int x = bounds.x; + int y = bounds.y; + int height = bounds.height; + int width = bounds.width; + + Rectangle trim = computeTrim(index, SWT.NONE, 0, 0, 0, 0); + int xDraw = x - trim.x; + + int textWidth = x + width - xDraw - (trim.width + trim.x); + if (textWidth > 0) { + Font gcFont = gc.getFont(); + Color gcForeground = gc.getForeground(); + Color gcBackground = gc.getBackground(); + gc.setFont(item.getFont()); + gc.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + String shortenedText = shortenText2(gc, item.getText(), textWidth); + Point extent = gc.textExtent(shortenedText, FLAGS); + int textY = y + (height - extent.y) / 2; + boolean onBottom = (parent.getStyle() & SWT.BOTTOM) != 0; + textY += onBottom ? -1 : 1; + + gc.setForeground(foreground); + +// gc.setBackground(); + gc.drawText(shortenedText, xDraw, textY, false); + + //recovery gc context + gc.setFont(gcFont); + gc.setForeground(gcForeground); + gc.setBackground(gcBackground); + } + } + + private String shortenText2(GC gc, String text, int width) { + return useEllipses2() ? shortenText2(gc, text, width, ELLIPSIS) + : shortenText2(gc, text, width, ""); //$NON-NLS-1$ + } + + private boolean useEllipses2() { + return parent.getSimple(); + } + + private String shortenText2(GC gc, String text, int width, + String ellipses) { + if (gc.textExtent(text, FLAGS).x <= width) + return text; + int ellipseWidth = gc.textExtent(ellipses, FLAGS).x; + int length = text.length(); + TextLayout layout = new TextLayout(parent.getDisplay()); + layout.setText(text); + int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER); + while (end > 0) { + text = text.substring(0, end); + int l = gc.textExtent(text, FLAGS).x; + if (l + ellipseWidth <= width) { + break; + } + end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER); + } + layout.dispose(); + return end == 0 ? text.substring(0, 1) : text + ellipses; + } + + private Color getColor(int index) { + if (index < 0 || index >= editor.getPages().length) { + return null; + } + + ISheet sheet = editor.getPage(index).getAdapter(ISheet.class); + String rgb = getRgb(sheet); + + if (rgb == null || rgb.equals("")) { //$NON-NLS-1$ + return null; + } + return (Color) resources.get(ColorUtils.toDescriptor(rgb)); + } + + private String getRgb(ISheet sheet) { + ISettingEntry entry = findEntry(sheet); + return entry == null ? null + : entry.getAttribute(ISheetSettings.ATTR_RGB); + } + + private ISettingEntry findEntry(ISheet sheet) { + List entries = sheet.getSettings() + .getEntries(ISheetSettings.TAB_COLOR); + return entries.size() == 0 ? null : entries.get(0); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/AttachmentImageDescriptor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/AttachmentImageDescriptor.java index d15ffb0cb..91c692b0b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/AttachmentImageDescriptor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/AttachmentImageDescriptor.java @@ -1,127 +1,127 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWTError; -import org.eclipse.swt.graphics.ImageData; -import org.xmind.core.IFileEntry; -import org.xmind.core.IWorkbook; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class AttachmentImageDescriptor extends ImageDescriptor { - - private static ImageData MISSING_DATA = null; - - private IWorkbook workbook; - - private String path; - - protected AttachmentImageDescriptor(IWorkbook workbook, String path) { - if (workbook == null) - throw new IllegalArgumentException("Workbook is null!"); //$NON-NLS-1$ - if (path == null) - throw new IllegalArgumentException("Path is null!"); //$NON-NLS-1$ - this.workbook = workbook; - this.path = path; - } - - public ImageData getImageData() { - ImageData imageData = null; - InputStream in = getStream(); - if (in != null) { - try { - imageData = new ImageData(in); - } catch (Exception e) { - Logger.log(e, "Failed to get image data from attachment: " //$NON-NLS-1$ - + path + " (" + workbook.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - imageData = getMissingData(); - } catch (SWTError e) { - Logger.log(e, "Failed to get image data from attachment: " //$NON-NLS-1$ - + path + " (" + workbook.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - imageData = getMissingData(); - } catch (OutOfMemoryError e) { - Logger.log(e, "Image too large"); //$NON-NLS-1$ - imageData = getMissingData(); - } finally { - try { - in.close(); - } catch (Exception e) { - } - } - } else { - imageData = getMissingData(); - } - return imageData; - } - - private InputStream getStream() { - IFileEntry entry = workbook.getManifest().getFileEntry(path); - if (entry == null) { - Logger.log("Failed to get file entry by entry path: " + path); //$NON-NLS-1$ - return null; - } - try { - return new BufferedInputStream(entry.openInputStream()); - } catch (IOException e) { - Logger.log("Failed to get input stream from workbook entry: " //$NON-NLS-1$ - + path); - return null; - } - } - - public String toString() { - return "AttachmentImageDescriptor(workbook=" + workbook.toString()//$NON-NLS-1$ - + ",path=" + path + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof AttachmentImageDescriptor)) - return false; - AttachmentImageDescriptor that = (AttachmentImageDescriptor) obj; - return this.workbook.equals(that.workbook) - && this.path.equals(that.path); - } - - public int hashCode() { - return workbook.hashCode() + path.hashCode(); - } - - public static ImageDescriptor createFromEntryPath(IWorkbook workbook, - String path) { - return new AttachmentImageDescriptor(workbook, path); - } - - public static ImageDescriptor createFromEntry(IWorkbook workbook, - IFileEntry entry) { - return new AttachmentImageDescriptor(workbook, entry.getPath()); - } - - private static ImageData getMissingData() { - if (MISSING_DATA == null) { - MISSING_DATA = MindMapUI.getImages() - .get(IMindMapImages.MISSING_IMAGE).getImageData(); - } - return MISSING_DATA; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.graphics.ImageData; +import org.xmind.core.IFileEntry; +import org.xmind.core.IWorkbook; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class AttachmentImageDescriptor extends ImageDescriptor { + + private static ImageData MISSING_DATA = null; + + private IWorkbook workbook; + + private String path; + + protected AttachmentImageDescriptor(IWorkbook workbook, String path) { + if (workbook == null) + throw new IllegalArgumentException("Workbook is null!"); //$NON-NLS-1$ + if (path == null) + throw new IllegalArgumentException("Path is null!"); //$NON-NLS-1$ + this.workbook = workbook; + this.path = path; + } + + public ImageData getImageData() { + ImageData imageData = null; + InputStream in = getStream(); + if (in != null) { + try { + imageData = new ImageData(in); + } catch (Exception e) { + Logger.log(e, "Failed to get image data from attachment: " //$NON-NLS-1$ + + path + " (" + workbook.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + imageData = getMissingData(); + } catch (SWTError e) { + Logger.log(e, "Failed to get image data from attachment: " //$NON-NLS-1$ + + path + " (" + workbook.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + imageData = getMissingData(); + } catch (OutOfMemoryError e) { + Logger.log(e, "Image too large"); //$NON-NLS-1$ + imageData = getMissingData(); + } finally { + try { + in.close(); + } catch (Exception e) { + } + } + } else { + imageData = getMissingData(); + } + return imageData; + } + + private InputStream getStream() { + IFileEntry entry = workbook.getManifest().getFileEntry(path); + if (entry == null) { + Logger.log("Failed to get file entry by entry path: " + path); //$NON-NLS-1$ + return null; + } + try { + return new BufferedInputStream(entry.openInputStream()); + } catch (IOException e) { + Logger.log("Failed to get input stream from workbook entry: " //$NON-NLS-1$ + + path); + return null; + } + } + + public String toString() { + return "AttachmentImageDescriptor(workbook=" + workbook.toString()//$NON-NLS-1$ + + ",path=" + path + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof AttachmentImageDescriptor)) + return false; + AttachmentImageDescriptor that = (AttachmentImageDescriptor) obj; + return this.workbook.equals(that.workbook) + && this.path.equals(that.path); + } + + public int hashCode() { + return workbook.hashCode() + path.hashCode(); + } + + public static ImageDescriptor createFromEntryPath(IWorkbook workbook, + String path) { + return new AttachmentImageDescriptor(workbook, path); + } + + public static ImageDescriptor createFromEntry(IWorkbook workbook, + IFileEntry entry) { + return new AttachmentImageDescriptor(workbook, entry.getPath()); + } + + private static ImageData getMissingData() { + if (MISSING_DATA == null) { + MISSING_DATA = MindMapUI.getImages() + .get(IMindMapImages.MISSING_IMAGE).getImageData(); + } + return MISSING_DATA; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/CategoryManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/CategoryManager.java index d23f41017..60376d4a4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/CategoryManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/CategoryManager.java @@ -1,219 +1,219 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.internal.expressions.Expressions; -import org.xmind.core.ITopic; -import org.xmind.ui.mindmap.ICategoryAnalyzation; -import org.xmind.ui.mindmap.ICategoryManager; -import org.xmind.ui.mindmap.MindMapUI; - -public class CategoryManager implements ICategoryManager { - - protected static class Category { - - static final String DEFAULT_TYPE = "DEFAULTELEMENTTYPE"; //$NON-NLS-1$ - - private String id; - - private String objectClass; - - private String elementType; - - private String name; - -// ElementType(IConfigurationElement element) throws CoreException { -// id = element.getAttribute(ATT_ID); -// objectClass = getClassValue(element, ATT_OBJECTCLASS); -// if (objectClass == null) -// throw new CoreException(new Status(IStatus.ERROR, element -// .getNamespaceIdentifier(), 0, -// "Invalid extension (missing class name): " + id, //$NON-NLS-1$ -// null)); -// name = element.getAttribute(ATT_NAME); -// if (name == null) -// name = ""; //$NON-NLS-1$ -// } - - Category(String id, String objectClass, String elementType, - String name) { - this.id = id; - this.objectClass = objectClass; - this.name = name; - this.elementType = elementType; - } - - public String getElementType() { - return elementType; - } - - public String getId() { - return id; - } - - public String getObjectClazz() { - return objectClass; - } - - public boolean belongsToThisCategory(Object o) { - boolean belongs = Expressions.isInstanceOf(o, objectClass); - if (belongs && o instanceof ITopic) { - belongs = belongs && (((ITopic) o).getType() != null) - && (((ITopic) o).getType().equals(elementType) - || DEFAULT_TYPE.equals(elementType)); - } - return belongs; - } - - public String getName() { - return name; - } - - } - - private List categories = null; - - private String[] categoryIds = null; - - /* package */ CategoryManager() { - } - -// public String getElementType(Object element) { -// ensureLoaded(); -// for (ElementType type : elementTypes) { -// if (type.isThisType(element)) -// return type.getId(); -// } -// return null; -// } - - public ICategoryAnalyzation analyze(Object[] elements) { - return new CategoryAnalyzation(elements, this); - } - - public String[] getAllCategories() { - if (categoryIds == null) { - ensureLoaded(); - int size = categories.size(); - categoryIds = new String[size]; - for (int i = 0; i < size; i++) { - categoryIds[i] = categories.get(i).getId(); - } - } - return categoryIds; - } - - private void ensureLoaded() { - if (categories != null) - return; - lazyLoad(); - if (categories == null) - categories = Collections.emptyList(); - } - - /** - */ - private void lazyLoad() { - register(new Category(MindMapUI.CATEGORY_CALLOUT, - "org.xmind.core.ITopic", ITopic.CALLOUT, //$NON-NLS-1$ - MindMapMessages.Category_Callout)); - register(new Category(MindMapUI.CATEGORY_SUMMARY, - "org.xmind.core.ITopic", ITopic.SUMMARY, //$NON-NLS-1$ - MindMapMessages.Category_Summary)); - register(new Category(MindMapUI.CATEGORY_TOPIC, "org.xmind.core.ITopic", //$NON-NLS-1$ - Category.DEFAULT_TYPE, - MindMapMessages.Category_Topic)); - register(new Category(MindMapUI.CATEGORY_SHEET, "org.xmind.core.ISheet", //$NON-NLS-1$ - Category.DEFAULT_TYPE, - MindMapMessages.Category_Sheet)); - register(new Category(MindMapUI.CATEGORY_BOUNDARY, - "org.xmind.core.IBoundary", Category.DEFAULT_TYPE, //$NON-NLS-1$ - MindMapMessages.Category_Boundary)); - register(new Category(MindMapUI.CATEGORY_RELATIONSHIP, - "org.xmind.core.IRelationship", Category.DEFAULT_TYPE,//$NON-NLS-1$ - MindMapMessages.Category_Relationship)); - register(new Category(MindMapUI.CATEGORY_MARKER, - "org.xmind.core.marker.IMarkerRef", Category.DEFAULT_TYPE, //$NON-NLS-1$ - MindMapMessages.Category_Marker)); - register(new Category(MindMapUI.CATEGORY_IMAGE, "org.xmind.core.IImage", //$NON-NLS-1$ - Category.DEFAULT_TYPE, - MindMapMessages.Category_Image)); -// if (Platform.isRunning()) { -// readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, -// RegistryConstants.EXT_ELEMENT_TYPES); -// } - } - -// protected boolean readElement(IConfigurationElement element) { -// if (RegistryConstants.TAG_ELEMENT_TYPE.equals(element.getName())) { -// readElementType(element); -// return true; -// } -// return false; -// } -// -// private void readElementType(IConfigurationElement element) { -// try { -// ElementType elementType = new ElementType(element); -// register(elementType); -// } catch (CoreException e) { -// Logger.log(e, "Failed to load ElementType: " + element.toString()); //$NON-NLS-1$ -// } -// } - - private void register(Category category) { - if (categories == null) - categories = new ArrayList(); - categories.add(category); - } - - public String getCategoryName(String categoryId) { - ensureLoaded(); - Category category = getCategory(categoryId); - if (category != null) - return category.getName(); - if (MULTIPLE_CATEGORIES.equals(categoryId)) - return MindMapMessages.MultipleObjects; - if (NO_CATEGORY.equals(categoryId)) - return MindMapMessages.NoObject; - if (UNKNOWN_CATEGORY.equals(categoryId)) - return MindMapMessages.UnknownObjects; - return ""; //$NON-NLS-1$ - } - - public boolean belongsToCategory(Object element, String categoryId) { - Category category = getCategory(categoryId); - if (category != null) { - return category.belongsToThisCategory(element); - } - return false; - } - - private Category getCategory(String categoryId) { - if (categoryId == null) - return null; - - ensureLoaded(); - for (Category type : categories) { - if (categoryId.equals(type.getId())) - return type; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.internal.expressions.Expressions; +import org.xmind.core.ITopic; +import org.xmind.ui.mindmap.ICategoryAnalyzation; +import org.xmind.ui.mindmap.ICategoryManager; +import org.xmind.ui.mindmap.MindMapUI; + +public class CategoryManager implements ICategoryManager { + + protected static class Category { + + static final String DEFAULT_TYPE = "DEFAULTELEMENTTYPE"; //$NON-NLS-1$ + + private String id; + + private String objectClass; + + private String elementType; + + private String name; + +// ElementType(IConfigurationElement element) throws CoreException { +// id = element.getAttribute(ATT_ID); +// objectClass = getClassValue(element, ATT_OBJECTCLASS); +// if (objectClass == null) +// throw new CoreException(new Status(IStatus.ERROR, element +// .getNamespaceIdentifier(), 0, +// "Invalid extension (missing class name): " + id, //$NON-NLS-1$ +// null)); +// name = element.getAttribute(ATT_NAME); +// if (name == null) +// name = ""; //$NON-NLS-1$ +// } + + Category(String id, String objectClass, String elementType, + String name) { + this.id = id; + this.objectClass = objectClass; + this.name = name; + this.elementType = elementType; + } + + public String getElementType() { + return elementType; + } + + public String getId() { + return id; + } + + public String getObjectClazz() { + return objectClass; + } + + public boolean belongsToThisCategory(Object o) { + boolean belongs = Expressions.isInstanceOf(o, objectClass); + if (belongs && o instanceof ITopic) { + belongs = belongs && (((ITopic) o).getType() != null) + && (((ITopic) o).getType().equals(elementType) + || DEFAULT_TYPE.equals(elementType)); + } + return belongs; + } + + public String getName() { + return name; + } + + } + + private List categories = null; + + private String[] categoryIds = null; + + /* package */ CategoryManager() { + } + +// public String getElementType(Object element) { +// ensureLoaded(); +// for (ElementType type : elementTypes) { +// if (type.isThisType(element)) +// return type.getId(); +// } +// return null; +// } + + public ICategoryAnalyzation analyze(Object[] elements) { + return new CategoryAnalyzation(elements, this); + } + + public String[] getAllCategories() { + if (categoryIds == null) { + ensureLoaded(); + int size = categories.size(); + categoryIds = new String[size]; + for (int i = 0; i < size; i++) { + categoryIds[i] = categories.get(i).getId(); + } + } + return categoryIds; + } + + private void ensureLoaded() { + if (categories != null) + return; + lazyLoad(); + if (categories == null) + categories = Collections.emptyList(); + } + + /** + */ + private void lazyLoad() { + register(new Category(MindMapUI.CATEGORY_CALLOUT, + "org.xmind.core.ITopic", ITopic.CALLOUT, //$NON-NLS-1$ + MindMapMessages.Category_Callout)); + register(new Category(MindMapUI.CATEGORY_SUMMARY, + "org.xmind.core.ITopic", ITopic.SUMMARY, //$NON-NLS-1$ + MindMapMessages.Category_Summary)); + register(new Category(MindMapUI.CATEGORY_TOPIC, "org.xmind.core.ITopic", //$NON-NLS-1$ + Category.DEFAULT_TYPE, + MindMapMessages.Category_Topic)); + register(new Category(MindMapUI.CATEGORY_SHEET, "org.xmind.core.ISheet", //$NON-NLS-1$ + Category.DEFAULT_TYPE, + MindMapMessages.Category_Sheet)); + register(new Category(MindMapUI.CATEGORY_BOUNDARY, + "org.xmind.core.IBoundary", Category.DEFAULT_TYPE, //$NON-NLS-1$ + MindMapMessages.Category_Boundary)); + register(new Category(MindMapUI.CATEGORY_RELATIONSHIP, + "org.xmind.core.IRelationship", Category.DEFAULT_TYPE,//$NON-NLS-1$ + MindMapMessages.Category_Relationship)); + register(new Category(MindMapUI.CATEGORY_MARKER, + "org.xmind.core.marker.IMarkerRef", Category.DEFAULT_TYPE, //$NON-NLS-1$ + MindMapMessages.Category_Marker)); + register(new Category(MindMapUI.CATEGORY_IMAGE, "org.xmind.core.IImage", //$NON-NLS-1$ + Category.DEFAULT_TYPE, + MindMapMessages.Category_Image)); +// if (Platform.isRunning()) { +// readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, +// RegistryConstants.EXT_ELEMENT_TYPES); +// } + } + +// protected boolean readElement(IConfigurationElement element) { +// if (RegistryConstants.TAG_ELEMENT_TYPE.equals(element.getName())) { +// readElementType(element); +// return true; +// } +// return false; +// } +// +// private void readElementType(IConfigurationElement element) { +// try { +// ElementType elementType = new ElementType(element); +// register(elementType); +// } catch (CoreException e) { +// Logger.log(e, "Failed to load ElementType: " + element.toString()); //$NON-NLS-1$ +// } +// } + + private void register(Category category) { + if (categories == null) + categories = new ArrayList(); + categories.add(category); + } + + public String getCategoryName(String categoryId) { + ensureLoaded(); + Category category = getCategory(categoryId); + if (category != null) + return category.getName(); + if (MULTIPLE_CATEGORIES.equals(categoryId)) + return MindMapMessages.MultipleObjects; + if (NO_CATEGORY.equals(categoryId)) + return MindMapMessages.NoObject; + if (UNKNOWN_CATEGORY.equals(categoryId)) + return MindMapMessages.UnknownObjects; + return ""; //$NON-NLS-1$ + } + + public boolean belongsToCategory(Object element, String categoryId) { + Category category = getCategory(categoryId); + if (category != null) { + return category.belongsToThisCategory(element); + } + return false; + } + + private Category getCategory(String categoryId) { + if (categoryId == null) + return null; + + ensureLoaded(); + for (Category type : categories) { + if (categoryId.equals(type.getId())) + return type; + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ClonedTemplate.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ClonedTemplate.java index 32f0cdf26..565691818 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ClonedTemplate.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ClonedTemplate.java @@ -1,69 +1,69 @@ -package org.xmind.ui.internal; - -import java.net.URI; - -import org.eclipse.core.runtime.Assert; -import org.xmind.ui.internal.editor.ClonedWorkbookRef; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.IWorkbookRef; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class ClonedTemplate implements ITemplate { - - private URI sourceWorkbookURI; - - private String name; - - public ClonedTemplate(URI sourceWorkbookURI, String name) { - super(); - Assert.isNotNull(sourceWorkbookURI); - this.sourceWorkbookURI = sourceWorkbookURI; - this.name = name; - } - - public String getName() { - if (this.name != null) - return this.name; - IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory() - .createWorkbookRef(sourceWorkbookURI, null); - if (sourceWorkbookRef != null) - return sourceWorkbookRef.getName(); - return ""; //$NON-NLS-1$ - } - - @Override - public IWorkbookRef createWorkbookRef() { - return ClonedWorkbookRef - .createFromSourceWorkbookURI(this.sourceWorkbookURI); - } - - public URI getSourceWorkbookURI() { - return this.sourceWorkbookURI; - } - - @Override - public int hashCode() { - int h = 37 ^ sourceWorkbookURI.hashCode(); - if (name != null) { - h = h ^ name.hashCode(); - } - return h; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof ClonedTemplate)) - return false; - ClonedTemplate that = (ClonedTemplate) obj; - return this.sourceWorkbookURI.equals(that.sourceWorkbookURI) - && (this.name == that.name - || (this.name != null && this.name.equals(that.name))); - } - -} +package org.xmind.ui.internal; + +import java.net.URI; + +import org.eclipse.core.runtime.Assert; +import org.xmind.ui.internal.editor.ClonedWorkbookRef; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.IWorkbookRef; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class ClonedTemplate implements ITemplate { + + private URI sourceWorkbookURI; + + private String name; + + public ClonedTemplate(URI sourceWorkbookURI, String name) { + super(); + Assert.isNotNull(sourceWorkbookURI); + this.sourceWorkbookURI = sourceWorkbookURI; + this.name = name; + } + + public String getName() { + if (this.name != null) + return this.name; + IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(sourceWorkbookURI, null); + if (sourceWorkbookRef != null) + return sourceWorkbookRef.getName(); + return ""; //$NON-NLS-1$ + } + + @Override + public IWorkbookRef createWorkbookRef() { + return ClonedWorkbookRef + .createFromSourceWorkbookURI(this.sourceWorkbookURI); + } + + public URI getSourceWorkbookURI() { + return this.sourceWorkbookURI; + } + + @Override + public int hashCode() { + int h = 37 ^ sourceWorkbookURI.hashCode(); + if (name != null) { + h = h ^ name.hashCode(); + } + return h; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof ClonedTemplate)) + return false; + ClonedTemplate that = (ClonedTemplate) obj; + return this.sourceWorkbookURI.equals(that.sourceWorkbookURI) + && (this.name == that.name + || (this.name != null && this.name.equals(that.name))); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java index 5a92783eb..c33a9d417 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java @@ -1,149 +1,149 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.util.Util; -import org.eclipse.ui.actions.CompoundContributionItem; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.ui.commands.MindMapCommandConstants; -import org.xmind.ui.mindmap.MindMapUI; - -public class ColorfulSheetMenu extends CompoundContributionItem - implements IWorkbenchContribution { - - private static final String SHEET_ICON_PATH = "icons/sheet/"; //$NON-NLS-1$ - - private static final List TAB_COLORS_WINDOWS = Arrays.asList( // - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_blue, - "#2188e2", "windows_blue.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_purple, - "#a497fd", "windows_purple.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_red, - "#f58868", "windows_red.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_yellow, - "#fabd65", "windows_yellow.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_green, - "#80df98", "windows_green.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_brown, - "#9e8273", "windows_brown.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_gray, - "#6b7288", "windows_gray.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_none, "", //$NON-NLS-1$ - "windows_none.png")); //$NON-NLS-1$ - - private static final List TAB_COLORS_OTHERS = Arrays.asList( // - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_red, "#ff625c", //$NON-NLS-1$ - "others_red.png"), //$NON-NLS-1$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_orange, - "#f9a646", "others_orange.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_yellow, - "#f5cf4a", "others_yellow.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_green, - "#6dcc50", "others_green.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_blue, - "#4bb8f3", "others_blue.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_purple, - "#d089e1", "others_purple.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_gray, - "#a4a4a8", "others_gray.png"), //$NON-NLS-1$//$NON-NLS-2$ - new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_none, "", //$NON-NLS-1$ - "others_none.png")); //$NON-NLS-1$ - - private static class ColorEntry { - - private String name; - - private String rgb; - - private String iconPath; - - public ColorEntry(String name, String rgb, String iconPath) { - this.name = name; - this.rgb = rgb; - this.iconPath = iconPath; - } - - public String getName() { - return name; - } - - public String getRgb() { - return rgb; - } - - public String getIconPath() { - return iconPath; - } - } - - private IServiceLocator serviceLocator; - - public ColorfulSheetMenu() { - } - - public void initialize(IServiceLocator serviceLocator) { - this.serviceLocator = serviceLocator; - } - - @Override - protected IContributionItem[] getContributionItems() { - List items = new ArrayList(); - - if (serviceLocator != null) { - fillItems(items, getSheetTabColors()); - } - - return items.toArray(new IContributionItem[items.size()]); - } - - private void fillItems(List items, - List colors) { - for (ColorEntry color : colors) { - items.add(makeColorCommandItem(color)); - } - } - - private IContributionItem makeColorCommandItem(final ColorEntry color) { - String id = "colorfulSheet." + color.getName(); //$NON-NLS-1$ - CommandContributionItemParameter parameter = new CommandContributionItemParameter( - serviceLocator, id, MindMapCommandConstants.COLORFUL_SHEET, - CommandContributionItem.STYLE_PUSH); - - parameter.label = color.getName(); - parameter.icon = MindMapUI.getImages().get(color.getIconPath(), - SHEET_ICON_PATH); - - Map params = new HashMap(); - params.put(MindMapCommandConstants.COLORFUL_SHEET_PARAM_RGB, - color.getRgb()); - parameter.parameters = params; - - return new CommandContributionItem(parameter); - } - - private static List getSheetTabColors() { - return Util.isWindows() ? TAB_COLORS_WINDOWS : TAB_COLORS_OTHERS; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.util.Util; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.mindmap.MindMapUI; + +public class ColorfulSheetMenu extends CompoundContributionItem + implements IWorkbenchContribution { + + private static final String SHEET_ICON_PATH = "icons/sheet/"; //$NON-NLS-1$ + + private static final List TAB_COLORS_WINDOWS = Arrays.asList( // + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_blue, + "#2188e2", "windows_blue.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_purple, + "#a497fd", "windows_purple.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_red, + "#f58868", "windows_red.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_yellow, + "#fabd65", "windows_yellow.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_green, + "#80df98", "windows_green.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_brown, + "#9e8273", "windows_brown.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_gray, + "#6b7288", "windows_gray.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_windows_none, "", //$NON-NLS-1$ + "windows_none.png")); //$NON-NLS-1$ + + private static final List TAB_COLORS_OTHERS = Arrays.asList( // + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_red, "#ff625c", //$NON-NLS-1$ + "others_red.png"), //$NON-NLS-1$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_orange, + "#f9a646", "others_orange.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_yellow, + "#f5cf4a", "others_yellow.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_green, + "#6dcc50", "others_green.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_blue, + "#4bb8f3", "others_blue.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_purple, + "#d089e1", "others_purple.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_gray, + "#a4a4a8", "others_gray.png"), //$NON-NLS-1$//$NON-NLS-2$ + new ColorEntry(MindMapMessages.ColorfulSheetMenu_mac_none, "", //$NON-NLS-1$ + "others_none.png")); //$NON-NLS-1$ + + private static class ColorEntry { + + private String name; + + private String rgb; + + private String iconPath; + + public ColorEntry(String name, String rgb, String iconPath) { + this.name = name; + this.rgb = rgb; + this.iconPath = iconPath; + } + + public String getName() { + return name; + } + + public String getRgb() { + return rgb; + } + + public String getIconPath() { + return iconPath; + } + } + + private IServiceLocator serviceLocator; + + public ColorfulSheetMenu() { + } + + public void initialize(IServiceLocator serviceLocator) { + this.serviceLocator = serviceLocator; + } + + @Override + protected IContributionItem[] getContributionItems() { + List items = new ArrayList(); + + if (serviceLocator != null) { + fillItems(items, getSheetTabColors()); + } + + return items.toArray(new IContributionItem[items.size()]); + } + + private void fillItems(List items, + List colors) { + for (ColorEntry color : colors) { + items.add(makeColorCommandItem(color)); + } + } + + private IContributionItem makeColorCommandItem(final ColorEntry color) { + String id = "colorfulSheet." + color.getName(); //$NON-NLS-1$ + CommandContributionItemParameter parameter = new CommandContributionItemParameter( + serviceLocator, id, MindMapCommandConstants.COLORFUL_SHEET, + CommandContributionItem.STYLE_PUSH); + + parameter.label = color.getName(); + parameter.icon = MindMapUI.getImages().get(color.getIconPath(), + SHEET_ICON_PATH); + + Map params = new HashMap(); + params.put(MindMapCommandConstants.COLORFUL_SHEET_PARAM_RGB, + color.getRgb()); + parameter.parameters = params; + + return new CommandContributionItem(parameter); + } + + private static List getSheetTabColors() { + return Util.isWindows() ? TAB_COLORS_WINDOWS : TAB_COLORS_OTHERS; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/DndClientDescriptor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/DndClientDescriptor.java index 3c4b81f30..bbc775209 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/DndClientDescriptor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/DndClientDescriptor.java @@ -1,82 +1,82 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_CLASS; -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_ID; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.xmind.gef.dnd.IDndClient; -import org.xmind.ui.util.Logger; - -public class DndClientDescriptor { - - private IConfigurationElement element; - - private String id; - - private IDndClient dndClient; - - private boolean failed = false; - - public DndClientDescriptor(IConfigurationElement element) - throws CoreException { - this.element = element; - load(); - } - - private void load() throws CoreException { - id = element.getAttribute(ATT_ID); - if (RegistryReader.getClassValue(element, ATT_CLASS) == null) { - throw new CoreException(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), 0, - "Invalid extension (missing class name): " + id, //$NON-NLS-1$ - null)); - } - } - - public String getId() { - return id; - } - - public IDndClient getDndClient() { - if (dndClient == null) { - if (failed) - return null; - try { - dndClient = (IDndClient) element - .createExecutableExtension(ATT_CLASS); - } catch (CoreException e) { - Logger.log(e, "Failed to create DND Client: " //$NON-NLS-1$ - + RegistryReader.getClassValue(element, ATT_CLASS)); - failed = true; - } - } - return dndClient; - } - -// public IDndClient createDndClient() { -// try { -// return (IDndClient) configElement -// .createExecutableExtension(ATT_CLASS); -// } catch (CoreException e) { -// } -// return null; -// } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_CLASS; +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_ID; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.xmind.gef.dnd.IDndClient; +import org.xmind.ui.util.Logger; + +public class DndClientDescriptor { + + private IConfigurationElement element; + + private String id; + + private IDndClient dndClient; + + private boolean failed = false; + + public DndClientDescriptor(IConfigurationElement element) + throws CoreException { + this.element = element; + load(); + } + + private void load() throws CoreException { + id = element.getAttribute(ATT_ID); + if (RegistryReader.getClassValue(element, ATT_CLASS) == null) { + throw new CoreException(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), 0, + "Invalid extension (missing class name): " + id, //$NON-NLS-1$ + null)); + } + } + + public String getId() { + return id; + } + + public IDndClient getDndClient() { + if (dndClient == null) { + if (failed) + return null; + try { + dndClient = (IDndClient) element + .createExecutableExtension(ATT_CLASS); + } catch (CoreException e) { + Logger.log(e, "Failed to create DND Client: " //$NON-NLS-1$ + + RegistryReader.getClassValue(element, ATT_CLASS)); + failed = true; + } + } + return dndClient; + } + +// public IDndClient createDndClient() { +// try { +// return (IDndClient) configElement +// .createExecutableExtension(ATT_CLASS); +// } catch (CoreException e) { +// } +// return null; +// } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistory.java index 47fda395e..570199927 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistory.java @@ -1,291 +1,291 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2015 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.IEditorHistory; - -/** - * - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public class EditorHistory implements IEditorHistory { - - private static final String THUMBNAIL_DIR_NAME = "thumbnailHistory"; //$NON-NLS-1$ - - private static final String PIN = "favor"; //$NON-NLS-1$ - - protected static final int MAX_SIZE = 100; - - private List inputURIs = new ArrayList(); - - private Map inputToInfo = new HashMap(); - - private ListenerList listeners = new ListenerList(); - - protected EditorHistory() { - List historyRepository = EditorHistoryPersistenceService.load(); - for (String inputAndInfo : historyRepository) { - int index = inputAndInfo - .indexOf(EditorHistoryPersistenceService.VALUE_SEPARATOR); - if (index < 0) - continue; - - String input = inputAndInfo.substring(0, index); - String info = inputAndInfo.substring(index - + EditorHistoryPersistenceService.VALUE_SEPARATOR.length()); - - try { - URI inputURI = new URI(input); - inputURIs.add(inputURI); - inputToInfo.put(inputURI, info); - } catch (URISyntaxException e) { - } - - } - - } - - public synchronized URI[] getAllInputURIs() { - return inputURIs.toArray(new URI[inputURIs.size()]); - } - - public synchronized URI[] getRecentInputURIs(int size) { - size = Math.max(0, Math.min(size, inputURIs.size())); - return inputURIs.subList(0, size).toArray(new URI[size]); - } - - public void pin(URI inputURI) { - if (inputURI == null) - return; - - boolean isPin = isPin(inputURI); - String info = getInfo(inputURI); - if (!isPin) { - inputToInfo.put(inputURI, appendPinContent(info)); - } - add(inputURI); - } - - public void unPin(URI inputURI) { - if (inputURI == null) - return; - - boolean isPin = isPin(inputURI); - String thumbnail = getThumbnail(inputURI); - if (isPin) { - inputToInfo.put(inputURI, thumbnail); - } - fireChanged(); - - } - - public boolean isPin(URI inputURI) { - boolean isPin = false; - if (inputURI == null) - return isPin; - - String info = inputToInfo.get(inputURI); - if (info != null) { - isPin = info.contains(PIN); - } - return isPin; - } - - public void add(URI inputURI) { - if (inputURI == null) - return; - - remove(inputURI); - inputURIs.add(0, inputURI); - while (inputURIs.size() > MAX_SIZE) { - inputURIs.remove(inputURIs.size() - 1); - } - - fireChanged(); - } - - public String getInfo(URI inputURI) { - if (inputURI == null) - return null; - return inputToInfo.get(inputURI); - } - - public String getThumbnail(URI inputURI) { - if (inputURI == null) - return null; - String info = inputToInfo.get(inputURI); - String thumbnail = info; - if (info != null) { - int sepPos = info.indexOf(','); - if (sepPos > 0) { - thumbnail = info.substring(0, sepPos); - } - } - return thumbnail; - } - - public void addThumbnail(URI inputURI, String originThumbnailPath) { - if (inputURI == null) - return; - - File originThumbnailFile = new File(originThumbnailPath); - if (!originThumbnailFile.exists()) - return; - - String thumbnailName = UUID.randomUUID().toString() - + originThumbnailFile.getName(); - File thumbnailDir = getThumbnailDir(); - if (thumbnailDir == null) - return; - if (!thumbnailDir.exists()) { - thumbnailDir.mkdirs(); - } - - String thumbnailPath = thumbnailDir.getAbsolutePath() + File.separator - + thumbnailName; - File thumbnailFile = new File(thumbnailPath); - - boolean isPin = isPin(inputURI); - - //remove existed thumbnail - removeThumbnail(inputURI); - - inputToInfo.put(inputURI, - isPin ? appendPinContent(thumbnailPath) : thumbnailPath); - - saveThumbnailFile(originThumbnailFile, thumbnailFile); - - while (inputToInfo.values().size() > MAX_SIZE) { - removeThumbnail(inputURI); - } - fireChanged(); - } - - private String appendPinContent(String source) { - StringBuffer buffer = new StringBuffer(); - buffer.append(source); - buffer.append(","); //$NON-NLS-1$ - buffer.append(PIN); - return buffer.toString(); - } - - private File getThumbnailDir() { - IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); - if (basePath == null) - return null; - IPath filePath = basePath.append(THUMBNAIL_DIR_NAME); - return filePath.toFile(); - } - - private void saveThumbnailFile(File source, File targetFile) { - try { - FileUtils.transfer(new FileInputStream(source), - new FileOutputStream(targetFile), true); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void removeThumbnail(URI inputURI) { - if (inputURI == null) - return; - - String existedThumbnail = getThumbnail(inputURI); - if (existedThumbnail == null) - return; - inputToInfo.remove(inputURI); - File existedThumbnailFile = new File(existedThumbnail); - if (existedThumbnailFile.exists()) - existedThumbnailFile.delete(); - - } - - public synchronized void remove(URI inputURI) { - if (inputURI == null) - return; - - int oldSize = inputURIs.size(); - Iterator iter = inputURIs.iterator(); - while (iter.hasNext()) { - URI oldURI = iter.next(); - if (inputURI.equals(oldURI)) { - iter.remove(); - } - } - if (oldSize != inputURIs.size()) { - fireChanged(); - } - } - - public synchronized void clear() { - int oldSize = inputURIs.size(); - inputURIs.clear(); - if (oldSize != inputURIs.size()) { - fireChanged(); - } - //REMOVE THUMBNAILS - inputToInfo.clear(); - File thumbnailDir = getThumbnailDir(); - if (thumbnailDir != null && thumbnailDir.exists()) { - File[] listFiles = thumbnailDir.listFiles(); - for (File file : listFiles) { - if (file.exists()) - file.delete(); - } - } - - } - - public void addEditorHistoryListener(IEditorHistoryListener listener) { - listeners.add(listener); - } - - public void removeEditorHistoryListener(IEditorHistoryListener listener) { - listeners.remove(listener); - } - - private void fireChanged() { - for (final Object listener : listeners.getListeners()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - ((IEditorHistoryListener) listener).editorHistoryChanged(); - } - }); - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2015 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.IEditorHistory; + +/** + * + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public class EditorHistory implements IEditorHistory { + + private static final String THUMBNAIL_DIR_NAME = "thumbnailHistory"; //$NON-NLS-1$ + + private static final String PIN = "favor"; //$NON-NLS-1$ + + protected static final int MAX_SIZE = 100; + + private List inputURIs = new ArrayList(); + + private Map inputToInfo = new HashMap(); + + private ListenerList listeners = new ListenerList(); + + protected EditorHistory() { + List historyRepository = EditorHistoryPersistenceService.load(); + for (String inputAndInfo : historyRepository) { + int index = inputAndInfo + .indexOf(EditorHistoryPersistenceService.VALUE_SEPARATOR); + if (index < 0) + continue; + + String input = inputAndInfo.substring(0, index); + String info = inputAndInfo.substring(index + + EditorHistoryPersistenceService.VALUE_SEPARATOR.length()); + + try { + URI inputURI = new URI(input); + inputURIs.add(inputURI); + inputToInfo.put(inputURI, info); + } catch (URISyntaxException e) { + } + + } + + } + + public synchronized URI[] getAllInputURIs() { + return inputURIs.toArray(new URI[inputURIs.size()]); + } + + public synchronized URI[] getRecentInputURIs(int size) { + size = Math.max(0, Math.min(size, inputURIs.size())); + return inputURIs.subList(0, size).toArray(new URI[size]); + } + + public void pin(URI inputURI) { + if (inputURI == null) + return; + + boolean isPin = isPin(inputURI); + String info = getInfo(inputURI); + if (!isPin) { + inputToInfo.put(inputURI, appendPinContent(info)); + } + add(inputURI); + } + + public void unPin(URI inputURI) { + if (inputURI == null) + return; + + boolean isPin = isPin(inputURI); + String thumbnail = getThumbnail(inputURI); + if (isPin) { + inputToInfo.put(inputURI, thumbnail); + } + fireChanged(); + + } + + public boolean isPin(URI inputURI) { + boolean isPin = false; + if (inputURI == null) + return isPin; + + String info = inputToInfo.get(inputURI); + if (info != null) { + isPin = info.contains(PIN); + } + return isPin; + } + + public void add(URI inputURI) { + if (inputURI == null) + return; + + remove(inputURI); + inputURIs.add(0, inputURI); + while (inputURIs.size() > MAX_SIZE) { + inputURIs.remove(inputURIs.size() - 1); + } + + fireChanged(); + } + + public String getInfo(URI inputURI) { + if (inputURI == null) + return null; + return inputToInfo.get(inputURI); + } + + public String getThumbnail(URI inputURI) { + if (inputURI == null) + return null; + String info = inputToInfo.get(inputURI); + String thumbnail = info; + if (info != null) { + int sepPos = info.indexOf(','); + if (sepPos > 0) { + thumbnail = info.substring(0, sepPos); + } + } + return thumbnail; + } + + public void addThumbnail(URI inputURI, String originThumbnailPath) { + if (inputURI == null) + return; + + File originThumbnailFile = new File(originThumbnailPath); + if (!originThumbnailFile.exists()) + return; + + String thumbnailName = UUID.randomUUID().toString() + + originThumbnailFile.getName(); + File thumbnailDir = getThumbnailDir(); + if (thumbnailDir == null) + return; + if (!thumbnailDir.exists()) { + thumbnailDir.mkdirs(); + } + + String thumbnailPath = thumbnailDir.getAbsolutePath() + File.separator + + thumbnailName; + File thumbnailFile = new File(thumbnailPath); + + boolean isPin = isPin(inputURI); + + //remove existed thumbnail + removeThumbnail(inputURI); + + inputToInfo.put(inputURI, + isPin ? appendPinContent(thumbnailPath) : thumbnailPath); + + saveThumbnailFile(originThumbnailFile, thumbnailFile); + + while (inputToInfo.values().size() > MAX_SIZE) { + removeThumbnail(inputURI); + } + fireChanged(); + } + + private String appendPinContent(String source) { + StringBuffer buffer = new StringBuffer(); + buffer.append(source); + buffer.append(","); //$NON-NLS-1$ + buffer.append(PIN); + return buffer.toString(); + } + + private File getThumbnailDir() { + IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); + if (basePath == null) + return null; + IPath filePath = basePath.append(THUMBNAIL_DIR_NAME); + return filePath.toFile(); + } + + private void saveThumbnailFile(File source, File targetFile) { + try { + FileUtils.transfer(new FileInputStream(source), + new FileOutputStream(targetFile), true); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void removeThumbnail(URI inputURI) { + if (inputURI == null) + return; + + String existedThumbnail = getThumbnail(inputURI); + if (existedThumbnail == null) + return; + inputToInfo.remove(inputURI); + File existedThumbnailFile = new File(existedThumbnail); + if (existedThumbnailFile.exists()) + existedThumbnailFile.delete(); + + } + + public synchronized void remove(URI inputURI) { + if (inputURI == null) + return; + + int oldSize = inputURIs.size(); + Iterator iter = inputURIs.iterator(); + while (iter.hasNext()) { + URI oldURI = iter.next(); + if (inputURI.equals(oldURI)) { + iter.remove(); + } + } + if (oldSize != inputURIs.size()) { + fireChanged(); + } + } + + public synchronized void clear() { + int oldSize = inputURIs.size(); + inputURIs.clear(); + if (oldSize != inputURIs.size()) { + fireChanged(); + } + //REMOVE THUMBNAILS + inputToInfo.clear(); + File thumbnailDir = getThumbnailDir(); + if (thumbnailDir != null && thumbnailDir.exists()) { + File[] listFiles = thumbnailDir.listFiles(); + for (File file : listFiles) { + if (file.exists()) + file.delete(); + } + } + + } + + public void addEditorHistoryListener(IEditorHistoryListener listener) { + listeners.add(listener); + } + + public void removeEditorHistoryListener(IEditorHistoryListener listener) { + listeners.remove(listener); + } + + private void fireChanged() { + for (final Object listener : listeners.getListeners()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + ((IEditorHistoryListener) listener).editorHistoryChanged(); + } + }); + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistoryPersistenceService.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistoryPersistenceService.java index 593200cf3..922c7a56c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistoryPersistenceService.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EditorHistoryPersistenceService.java @@ -1,232 +1,232 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2015 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchListener; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.IEditorHistory; -import org.xmind.ui.IEditorHistory.IEditorHistoryListener; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -/** - * - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public class EditorHistoryPersistenceService - implements IEditorHistoryListener, IWorkbenchListener { - - public static final String VALUE_SEPARATOR = "#$#"; //$NON-NLS-1$ - - private static final String KEY_PREFIX = "item."; //$NON-NLS-1$ - - private static final String FILE_NAME = "workbookHistory.properties"; //$NON-NLS-1$ - - private Thread thread = null; - - private URI[] contentToSave = null; - - private Object contentNotifier = new Object(); - - private static EditorHistoryPersistenceService INSTANCE = new EditorHistoryPersistenceService(); - - public static EditorHistoryPersistenceService getInstance() { - return INSTANCE; - } - - public void preStartup() { - IWorkbench wb = PlatformUI.getWorkbench(); - wb.addWorkbenchListener(this); - - Thread thread = new Thread(new Runnable() { - public void run() { - runLoop(); - } - }); - thread.setName("EditorHistoryPersistenceThread"); //$NON-NLS-1$ - thread.setPriority(Thread.MIN_PRIORITY); - thread.setDaemon(true); - this.thread = thread; - thread.start(); - - MindMapUI.getEditorHistory().addEditorHistoryListener(this); - - /* - * Manually trigger a save operation on startup, for there might be some - * changes to editor history before this earlyStartup method is called. - * For example, files are opened on startup via double click in Finder. - */ - editorHistoryChanged(); - } - - public void postShutdown(IWorkbench workbench) { - MindMapUI.getEditorHistory().removeEditorHistoryListener(this); - - Thread thread = this.thread; - this.thread = null; - if (thread != null) { - thread.interrupt(); - } - } - - public boolean preShutdown(IWorkbench workbench, boolean forced) { - return true; - } - - public void editorHistoryChanged() { - URI[] inputURIs = MindMapUI.getEditorHistory().getAllInputURIs(); - URI[] content = new URI[inputURIs.length]; - System.arraycopy(inputURIs, 0, content, 0, inputURIs.length); - synchronized (contentNotifier) { - contentToSave = content; - contentNotifier.notifyAll(); - } - } - - private void runLoop() { - try { - synchronized (contentNotifier) { - while (thread != null) { - contentNotifier.wait(); - URI[] content = null; - if (contentToSave != null) { - content = new URI[contentToSave.length]; - System.arraycopy(contentToSave, 0, content, 0, - contentToSave.length); - } - if (content != null) { - save(content); - } - Thread.sleep(0); - } - } - } catch (InterruptedException e) { - // ignore interruptions - } - } - - private static void save(URI[] content) { - Properties repository = new Properties(); - IEditorHistory editorHistory = MindMapUI.getEditorHistory(); - - // Push items - for (int index = 0; index < content.length; index++) { - URI input = content[index]; - String info = editorHistory.getInfo(input); - if (input != null && info != null) { - String key = KEY_PREFIX + index; - repository.setProperty(key, - input.toString() + VALUE_SEPARATOR + info); - - } - } - - // Save to properties file - File file = getHistoryFile(); - if (file != null) { - if (!file.getParentFile().exists()) { - file.getParentFile().mkdirs(); - } - try { - FileWriter writer = new FileWriter(file); - try { - repository.store(writer, - "Generated by org.xmind.ui.internal.editor.EditorHistoryService"); //$NON-NLS-1$ - } finally { - writer.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to save workbook history to " //$NON-NLS-1$ - + file.getAbsolutePath()); - } - } - } - - public static List load() { - Properties repository = new Properties(); - - // Load form properties file - File file = getHistoryFile(); - if (file != null && file.exists()) { - try { - FileReader reader = new FileReader(file); - try { - repository.load(reader); - } finally { - reader.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ - + file.getAbsolutePath()); - } - } - - int count = 0; - List items = new ArrayList(); - // Parse properties - int size = repository.size(); - for (int i = 0; i < size; i++) { - if (count >= EditorHistory.MAX_SIZE) - return items; - - String key = KEY_PREFIX + i; - String value = repository.getProperty(key); - if (value == null) - continue; - items.add(value); - repository.remove(key); - - count++; - } - - //Compatible with the old version - Set oldVersionKeys = repository.keySet(); - for (Object key : oldVersionKeys) { - if (count >= EditorHistory.MAX_SIZE) - return items; - - String input = (String) key; - String info = repository.getProperty(input); - - items.add(input + VALUE_SEPARATOR + info); - count++; - } - - return items; - - } - - private static File getHistoryFile() { - IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); - if (basePath == null) - return null; - IPath filePath = basePath.append(FILE_NAME); - return filePath.toFile(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2015 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.IEditorHistory; +import org.xmind.ui.IEditorHistory.IEditorHistoryListener; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +/** + * + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public class EditorHistoryPersistenceService + implements IEditorHistoryListener, IWorkbenchListener { + + public static final String VALUE_SEPARATOR = "#$#"; //$NON-NLS-1$ + + private static final String KEY_PREFIX = "item."; //$NON-NLS-1$ + + private static final String FILE_NAME = "workbookHistory.properties"; //$NON-NLS-1$ + + private Thread thread = null; + + private URI[] contentToSave = null; + + private Object contentNotifier = new Object(); + + private static EditorHistoryPersistenceService INSTANCE = new EditorHistoryPersistenceService(); + + public static EditorHistoryPersistenceService getInstance() { + return INSTANCE; + } + + public void preStartup() { + IWorkbench wb = PlatformUI.getWorkbench(); + wb.addWorkbenchListener(this); + + Thread thread = new Thread(new Runnable() { + public void run() { + runLoop(); + } + }); + thread.setName("EditorHistoryPersistenceThread"); //$NON-NLS-1$ + thread.setPriority(Thread.MIN_PRIORITY); + thread.setDaemon(true); + this.thread = thread; + thread.start(); + + MindMapUI.getEditorHistory().addEditorHistoryListener(this); + + /* + * Manually trigger a save operation on startup, for there might be some + * changes to editor history before this earlyStartup method is called. + * For example, files are opened on startup via double click in Finder. + */ + editorHistoryChanged(); + } + + public void postShutdown(IWorkbench workbench) { + MindMapUI.getEditorHistory().removeEditorHistoryListener(this); + + Thread thread = this.thread; + this.thread = null; + if (thread != null) { + thread.interrupt(); + } + } + + public boolean preShutdown(IWorkbench workbench, boolean forced) { + return true; + } + + public void editorHistoryChanged() { + URI[] inputURIs = MindMapUI.getEditorHistory().getAllInputURIs(); + URI[] content = new URI[inputURIs.length]; + System.arraycopy(inputURIs, 0, content, 0, inputURIs.length); + synchronized (contentNotifier) { + contentToSave = content; + contentNotifier.notifyAll(); + } + } + + private void runLoop() { + try { + synchronized (contentNotifier) { + while (thread != null) { + contentNotifier.wait(); + URI[] content = null; + if (contentToSave != null) { + content = new URI[contentToSave.length]; + System.arraycopy(contentToSave, 0, content, 0, + contentToSave.length); + } + if (content != null) { + save(content); + } + Thread.sleep(0); + } + } + } catch (InterruptedException e) { + // ignore interruptions + } + } + + private static void save(URI[] content) { + Properties repository = new Properties(); + IEditorHistory editorHistory = MindMapUI.getEditorHistory(); + + // Push items + for (int index = 0; index < content.length; index++) { + URI input = content[index]; + String info = editorHistory.getInfo(input); + if (input != null && info != null) { + String key = KEY_PREFIX + index; + repository.setProperty(key, + input.toString() + VALUE_SEPARATOR + info); + + } + } + + // Save to properties file + File file = getHistoryFile(); + if (file != null) { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + try { + FileWriter writer = new FileWriter(file); + try { + repository.store(writer, + "Generated by org.xmind.ui.internal.editor.EditorHistoryService"); //$NON-NLS-1$ + } finally { + writer.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to save workbook history to " //$NON-NLS-1$ + + file.getAbsolutePath()); + } + } + } + + public static List load() { + Properties repository = new Properties(); + + // Load form properties file + File file = getHistoryFile(); + if (file != null && file.exists()) { + try { + FileReader reader = new FileReader(file); + try { + repository.load(reader); + } finally { + reader.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ + + file.getAbsolutePath()); + } + } + + int count = 0; + List items = new ArrayList(); + // Parse properties + int size = repository.size(); + for (int i = 0; i < size; i++) { + if (count >= EditorHistory.MAX_SIZE) + return items; + + String key = KEY_PREFIX + i; + String value = repository.getProperty(key); + if (value == null) + continue; + items.add(value); + repository.remove(key); + + count++; + } + + //Compatible with the old version + Set oldVersionKeys = repository.keySet(); + for (Object key : oldVersionKeys) { + if (count >= EditorHistory.MAX_SIZE) + return items; + + String input = (String) key; + String info = repository.getProperty(input); + + items.add(input + VALUE_SEPARATOR + info); + count++; + } + + return items; + + } + + private static File getHistoryFile() { + IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); + if (basePath == null) + return null; + IPath filePath = basePath.append(FILE_NAME); + return filePath.toFile(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EmptyControlContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EmptyControlContribution.java index a52f2d381..a86f335f3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EmptyControlContribution.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EmptyControlContribution.java @@ -1,28 +1,28 @@ -package org.xmind.ui.internal; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.menus.WorkbenchWindowControlContribution; - -public class EmptyControlContribution - extends WorkbenchWindowControlContribution { - - public EmptyControlContribution() { - super("org.xmind.ui.emptyControlContribution"); //$NON-NLS-1$ - } - - @Override - protected Control createControl(Composite parent) { - Composite comp = new Composite(parent, SWT.NONE) { - @Override - public Point computeSize(int wHint, int hHint, boolean flushCache) { - return new Point(25, 0); - } - }; - comp.setSize(25, 0); - return comp; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.menus.WorkbenchWindowControlContribution; + +public class EmptyControlContribution + extends WorkbenchWindowControlContribution { + + public EmptyControlContribution() { + super("org.xmind.ui.emptyControlContribution"); //$NON-NLS-1$ + } + + @Override + protected Control createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE) { + @Override + public Point computeSize(int wHint, int hHint, boolean flushCache) { + return new Point(25, 0); + } + }; + comp.setSize(25, 0); + return comp; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/IconTipContributorManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/IconTipContributorManager.java index 2c332dfc6..e7a256ff8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/IconTipContributorManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/IconTipContributorManager.java @@ -1,83 +1,83 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.xmind.ui.mindmap.IIconTipContributor; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class IconTipContributorManager extends RegistryReader { - - private static final IconTipContributorManager instance = new IconTipContributorManager(); - - private List contributors = null; - - private IconTipContributorManager() { - } - - public List getContributors() { - ensureLoaded(); - return contributors; - } - - private void ensureLoaded() { - if (contributors != null) - return; - lazyLoad(); - if (contributors == null) - contributors = Collections.emptyList(); - } - - private void lazyLoad() { - if (Platform.isRunning()) { - readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, - RegistryConstants.EXT_ICONTIPS); - } - } - - protected boolean readElement(IConfigurationElement element) { - String name = element.getName(); - if (RegistryConstants.TAG_ICONTIP.equals(name)) { - readIconTip(element); - return true; - } - return false; - } - - private void readIconTip(IConfigurationElement element) { - IIconTipContributor contributor; - try { - contributor = new IconTipContributorProxy(element); - } catch (CoreException e) { - Logger.log(e, "Failed to load icon tip: " + element); //$NON-NLS-1$ - return; - } - if (contributors == null) - contributors = new ArrayList(); - contributors.add(contributor); - } - - public static IconTipContributorManager getInstance() { - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.xmind.ui.mindmap.IIconTipContributor; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class IconTipContributorManager extends RegistryReader { + + private static final IconTipContributorManager instance = new IconTipContributorManager(); + + private List contributors = null; + + private IconTipContributorManager() { + } + + public List getContributors() { + ensureLoaded(); + return contributors; + } + + private void ensureLoaded() { + if (contributors != null) + return; + lazyLoad(); + if (contributors == null) + contributors = Collections.emptyList(); + } + + private void lazyLoad() { + if (Platform.isRunning()) { + readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, + RegistryConstants.EXT_ICONTIPS); + } + } + + protected boolean readElement(IConfigurationElement element) { + String name = element.getName(); + if (RegistryConstants.TAG_ICONTIP.equals(name)) { + readIconTip(element); + return true; + } + return false; + } + + private void readIconTip(IConfigurationElement element) { + IIconTipContributor contributor; + try { + contributor = new IconTipContributorProxy(element); + } catch (CoreException e) { + Logger.log(e, "Failed to load icon tip: " + element); //$NON-NLS-1$ + return; + } + if (contributors == null) + contributors = new ArrayList(); + contributors.add(contributor); + } + + public static IconTipContributorManager getInstance() { + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ImageActionExtensionManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ImageActionExtensionManager.java index 152d759c8..7edd9f65e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ImageActionExtensionManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ImageActionExtensionManager.java @@ -1,307 +1,307 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IEditorActionDelegate; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class ImageActionExtensionManager extends RegistryReader implements - IWorkbenchRegistryConstants { - - public static class ActionBuilder implements IActionBuilder { - - private IConfigurationElement element; - - private String id; - - private IEditorActionDelegate delegate; - - private boolean delegateFailed = false; - - private ImageDescriptor icon; - - private boolean iconFailed = false; - - private ImageDescriptor disabledIcon; - - private boolean disabledIconFailed = false; - - public ActionBuilder(IConfigurationElement element) - throws CoreException { - this.element = element; - if (getClassValue(element, ATT_CLASS) == null) - throw new CoreException(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), - "Invalid extension (missing class)")); //$NON-NLS-1$ - this.id = element.getAttribute(ATT_ID); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getId() - */ - public String getId() { - return id; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getLabel() - */ - public String getLabel() { - return element.getAttribute(ATT_LABEL); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getDelegate() - */ - public IEditorActionDelegate getDelegate() { - if (delegate == null && !delegateFailed) { - delegate = createDelegate(); - if (delegate == null) - delegateFailed = true; - } - return delegate; - } - - private IEditorActionDelegate createDelegate() { - try { - return (IEditorActionDelegate) element - .createExecutableExtension(ATT_CLASS); - } catch (CoreException e) { - Logger.log(e); - return null; - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getDefinitionId() - */ - public String getDefinitionId() { - return element.getAttribute(ATT_DEFINITION_ID); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getTooltip() - */ - public String getTooltip() { - return element.getAttribute(ATT_TOOLTIP); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getIcon() - */ - public ImageDescriptor getIcon() { - if (icon == null && !iconFailed) { - icon = createIcon(); - if (icon == null) - iconFailed = true; - } - return icon; - } - - private ImageDescriptor createIcon() { - String iconPath = element.getAttribute(ATT_ICON); - if (iconPath != null) { - return AbstractUIPlugin.imageDescriptorFromPlugin(element - .getNamespaceIdentifier(), iconPath); - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IActionBuilder#getDisabledIcon() - */ - public ImageDescriptor getDisabledIcon() { - if (disabledIcon == null && !disabledIconFailed) { - disabledIcon = createDisabledIcon(); - if (disabledIcon == null) - disabledIconFailed = true; - } - return disabledIcon; - } - - private ImageDescriptor createDisabledIcon() { - String iconPath = element.getAttribute(ATT_DISABLEDICON); - if (iconPath != null) { - return AbstractUIPlugin.imageDescriptorFromPlugin(element - .getNamespaceIdentifier(), iconPath); - } - return null; - } - - public IWorkbenchAction createAction(IWorkbenchPage page) { - return new DelegatedAction(this, page); - } - - } - - private static class DelegatedAction extends Action implements - IWorkbenchAction, IPartListener, ISelectionListener { - - private IWorkbenchPage page; - - private IActionBuilder builder; - - private IEditorPart targetEditor; - - public DelegatedAction(IActionBuilder builder, IWorkbenchPage page) { - this.builder = builder; - this.page = page; - setId(builder.getId()); - setText(builder.getLabel()); - setToolTipText(builder.getTooltip()); - setImageDescriptor(builder.getIcon()); - setDisabledImageDescriptor(builder.getDisabledIcon()); - setActionDefinitionId(builder.getDefinitionId()); - page.addPartListener(this); - page.addSelectionListener(this); - } - - public void run() { - IEditorActionDelegate delegate = builder.getDelegate(); - if (delegate != null) - delegate.run(this); - } - - public void dispose() { - page.removeSelectionListener(this); - page.removePartListener(this); - } - - public void partActivated(IWorkbenchPart part) { - if (part instanceof IEditorPart) { - this.targetEditor = (IEditorPart) part; - IEditorActionDelegate delegate = builder.getDelegate(); - if (delegate != null) - delegate.setActiveEditor(this, targetEditor); - } - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - if (part == this.targetEditor) { - IEditorActionDelegate delegate = builder.getDelegate(); - if (delegate != null) - delegate.setActiveEditor(this, null); - } - } - - public void partDeactivated(IWorkbenchPart part) { - } - - public void partOpened(IWorkbenchPart part) { - } - - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - if (part == this.targetEditor) { - IEditorActionDelegate delegate = builder.getDelegate(); - if (delegate != null) - delegate.selectionChanged(this, selection); - } - } - - } - - private static final ImageActionExtensionManager instance = new ImageActionExtensionManager(); - - private List actionBuilders; - - private ImageActionExtensionManager() { - } - - public List getActionBuilders() { - ensureLoaded(); - return actionBuilders; - } - - private void ensureLoaded() { - if (actionBuilders != null) - return; - lazyLoad(); - if (actionBuilders == null) - actionBuilders = Collections.emptyList(); - } - - private void lazyLoad() { - readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, - "imageActions"); //$NON-NLS-1$ - } - - protected boolean readElement(IConfigurationElement element) { - String name = element.getName(); - if (TAG_ACTION.equals(name)) { - readChooser(element); - readElementChildren(element); - return true; - } - return false; - } - - private void readChooser(IConfigurationElement element) { - try { - IActionBuilder actionBuilder = new ActionBuilder(element); - register(actionBuilder); - } catch (CoreException e) { - Logger.log(e); - } - } - - private void register(IActionBuilder actionBuilder) { - if (actionBuilders == null) - actionBuilders = new ArrayList(); - actionBuilders.add(actionBuilder); - } - - public static ImageActionExtensionManager getInstance() { - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorActionDelegate; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class ImageActionExtensionManager extends RegistryReader implements + IWorkbenchRegistryConstants { + + public static class ActionBuilder implements IActionBuilder { + + private IConfigurationElement element; + + private String id; + + private IEditorActionDelegate delegate; + + private boolean delegateFailed = false; + + private ImageDescriptor icon; + + private boolean iconFailed = false; + + private ImageDescriptor disabledIcon; + + private boolean disabledIconFailed = false; + + public ActionBuilder(IConfigurationElement element) + throws CoreException { + this.element = element; + if (getClassValue(element, ATT_CLASS) == null) + throw new CoreException(new Status(IStatus.ERROR, element + .getNamespaceIdentifier(), + "Invalid extension (missing class)")); //$NON-NLS-1$ + this.id = element.getAttribute(ATT_ID); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getId() + */ + public String getId() { + return id; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getLabel() + */ + public String getLabel() { + return element.getAttribute(ATT_LABEL); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getDelegate() + */ + public IEditorActionDelegate getDelegate() { + if (delegate == null && !delegateFailed) { + delegate = createDelegate(); + if (delegate == null) + delegateFailed = true; + } + return delegate; + } + + private IEditorActionDelegate createDelegate() { + try { + return (IEditorActionDelegate) element + .createExecutableExtension(ATT_CLASS); + } catch (CoreException e) { + Logger.log(e); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getDefinitionId() + */ + public String getDefinitionId() { + return element.getAttribute(ATT_DEFINITION_ID); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getTooltip() + */ + public String getTooltip() { + return element.getAttribute(ATT_TOOLTIP); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getIcon() + */ + public ImageDescriptor getIcon() { + if (icon == null && !iconFailed) { + icon = createIcon(); + if (icon == null) + iconFailed = true; + } + return icon; + } + + private ImageDescriptor createIcon() { + String iconPath = element.getAttribute(ATT_ICON); + if (iconPath != null) { + return AbstractUIPlugin.imageDescriptorFromPlugin(element + .getNamespaceIdentifier(), iconPath); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IActionBuilder#getDisabledIcon() + */ + public ImageDescriptor getDisabledIcon() { + if (disabledIcon == null && !disabledIconFailed) { + disabledIcon = createDisabledIcon(); + if (disabledIcon == null) + disabledIconFailed = true; + } + return disabledIcon; + } + + private ImageDescriptor createDisabledIcon() { + String iconPath = element.getAttribute(ATT_DISABLEDICON); + if (iconPath != null) { + return AbstractUIPlugin.imageDescriptorFromPlugin(element + .getNamespaceIdentifier(), iconPath); + } + return null; + } + + public IWorkbenchAction createAction(IWorkbenchPage page) { + return new DelegatedAction(this, page); + } + + } + + private static class DelegatedAction extends Action implements + IWorkbenchAction, IPartListener, ISelectionListener { + + private IWorkbenchPage page; + + private IActionBuilder builder; + + private IEditorPart targetEditor; + + public DelegatedAction(IActionBuilder builder, IWorkbenchPage page) { + this.builder = builder; + this.page = page; + setId(builder.getId()); + setText(builder.getLabel()); + setToolTipText(builder.getTooltip()); + setImageDescriptor(builder.getIcon()); + setDisabledImageDescriptor(builder.getDisabledIcon()); + setActionDefinitionId(builder.getDefinitionId()); + page.addPartListener(this); + page.addSelectionListener(this); + } + + public void run() { + IEditorActionDelegate delegate = builder.getDelegate(); + if (delegate != null) + delegate.run(this); + } + + public void dispose() { + page.removeSelectionListener(this); + page.removePartListener(this); + } + + public void partActivated(IWorkbenchPart part) { + if (part instanceof IEditorPart) { + this.targetEditor = (IEditorPart) part; + IEditorActionDelegate delegate = builder.getDelegate(); + if (delegate != null) + delegate.setActiveEditor(this, targetEditor); + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + if (part == this.targetEditor) { + IEditorActionDelegate delegate = builder.getDelegate(); + if (delegate != null) + delegate.setActiveEditor(this, null); + } + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (part == this.targetEditor) { + IEditorActionDelegate delegate = builder.getDelegate(); + if (delegate != null) + delegate.selectionChanged(this, selection); + } + } + + } + + private static final ImageActionExtensionManager instance = new ImageActionExtensionManager(); + + private List actionBuilders; + + private ImageActionExtensionManager() { + } + + public List getActionBuilders() { + ensureLoaded(); + return actionBuilders; + } + + private void ensureLoaded() { + if (actionBuilders != null) + return; + lazyLoad(); + if (actionBuilders == null) + actionBuilders = Collections.emptyList(); + } + + private void lazyLoad() { + readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, + "imageActions"); //$NON-NLS-1$ + } + + protected boolean readElement(IConfigurationElement element) { + String name = element.getName(); + if (TAG_ACTION.equals(name)) { + readChooser(element); + readElementChildren(element); + return true; + } + return false; + } + + private void readChooser(IConfigurationElement element) { + try { + IActionBuilder actionBuilder = new ActionBuilder(element); + register(actionBuilder); + } catch (CoreException e) { + Logger.log(e); + } + } + + private void register(IActionBuilder actionBuilder) { + if (actionBuilders == null) + actionBuilders = new ArrayList(); + actionBuilders.add(actionBuilder); + } + + public static ImageActionExtensionManager getInstance() { + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorManager.java index 7f9ae7460..ae259e4c7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorManager.java @@ -1,96 +1,96 @@ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.xmind.core.internal.dom.DOMConstants; -import org.xmind.ui.mindmap.IInfoItemContributor; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class InfoItemContributorManager extends RegistryReader { - - private static final InfoItemContributorManager instance = new InfoItemContributorManager(); - - public static final String LABEL_ID = "org.xmind.ui.infoItem.label"; //$NON-NLS-1$ - - public static final String NOTES_ID = "org.xmind.ui.infoItem.notes"; //$NON-NLS-1$ - - public static final String HYPERLINK_ID = "org.xmind.ui.infoItem.hyperlink"; //$NON-NLS-1$ - - public static final String TASKINFO_ID = "org.xmind.ui.infoItem.taskInfo"; //$NON-NLS-1$ - - private List contributors = null; - - private List bothContributors = null; - - private InfoItemContributorManager() { - } - - public List getContributors() { - ensureLoaded(); - return contributors; - } - - public List getBothContributors() { - return bothContributors; - } - - private void ensureLoaded() { - if (contributors != null && bothContributors != null) - return; - lazyLoad(); - if (contributors == null) - contributors = Collections.emptyList(); - if (bothContributors == null) - bothContributors = Collections.emptyList(); - } - - private void lazyLoad() { - if (Platform.isRunning()) { - readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, - RegistryConstants.EXT_INFOITMES); - } - } - - protected boolean readElement(IConfigurationElement element) { - String name = element.getName(); - if (RegistryConstants.TAG_INFOITEM.equals(name)) { - readInfoItem(element); - return true; - } - return false; - } - - private void readInfoItem(IConfigurationElement element) { - IInfoItemContributor contributor; - try { - contributor = new InfoItemContributorProxy(element); - } catch (CoreException e) { - Logger.log(e, "Failed to load info item: " + element); //$NON-NLS-1$ - return; - } - - String modes = contributor.getAvailableModes(); - if (modes.contains(DOMConstants.VAL_ICONMODE) - && modes.contains(DOMConstants.VAL_CARDMODE)) { - if (bothContributors == null) - bothContributors = new ArrayList(); - bothContributors.add(contributor); - } else { - if (contributors == null) - contributors = new ArrayList(); - contributors.add(contributor); - } - } - - public static InfoItemContributorManager getInstance() { - return instance; - } - -} +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.xmind.core.internal.dom.DOMConstants; +import org.xmind.ui.mindmap.IInfoItemContributor; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class InfoItemContributorManager extends RegistryReader { + + private static final InfoItemContributorManager instance = new InfoItemContributorManager(); + + public static final String LABEL_ID = "org.xmind.ui.infoItem.label"; //$NON-NLS-1$ + + public static final String NOTES_ID = "org.xmind.ui.infoItem.notes"; //$NON-NLS-1$ + + public static final String HYPERLINK_ID = "org.xmind.ui.infoItem.hyperlink"; //$NON-NLS-1$ + + public static final String TASKINFO_ID = "org.xmind.ui.infoItem.taskInfo"; //$NON-NLS-1$ + + private List contributors = null; + + private List bothContributors = null; + + private InfoItemContributorManager() { + } + + public List getContributors() { + ensureLoaded(); + return contributors; + } + + public List getBothContributors() { + return bothContributors; + } + + private void ensureLoaded() { + if (contributors != null && bothContributors != null) + return; + lazyLoad(); + if (contributors == null) + contributors = Collections.emptyList(); + if (bothContributors == null) + bothContributors = Collections.emptyList(); + } + + private void lazyLoad() { + if (Platform.isRunning()) { + readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, + RegistryConstants.EXT_INFOITMES); + } + } + + protected boolean readElement(IConfigurationElement element) { + String name = element.getName(); + if (RegistryConstants.TAG_INFOITEM.equals(name)) { + readInfoItem(element); + return true; + } + return false; + } + + private void readInfoItem(IConfigurationElement element) { + IInfoItemContributor contributor; + try { + contributor = new InfoItemContributorProxy(element); + } catch (CoreException e) { + Logger.log(e, "Failed to load info item: " + element); //$NON-NLS-1$ + return; + } + + String modes = contributor.getAvailableModes(); + if (modes.contains(DOMConstants.VAL_ICONMODE) + && modes.contains(DOMConstants.VAL_CARDMODE)) { + if (bothContributors == null) + bothContributors = new ArrayList(); + bothContributors.add(contributor); + } else { + if (contributors == null) + contributors = new ArrayList(); + contributors.add(contributor); + } + } + + public static InfoItemContributorManager getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorProxy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorProxy.java index 5ab671d79..a85fac2bc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorProxy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InfoItemContributorProxy.java @@ -1,228 +1,228 @@ -package org.xmind.ui.internal; - -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_ICON; - -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.xmind.core.ITopic; -import org.xmind.ui.mindmap.IInfoItemContributor; -import org.xmind.ui.mindmap.IInfoItemPart; -import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.util.Logger; - -public class InfoItemContributorProxy implements IInfoItemContributor { - - private static class NullInfoItemContributor implements - IInfoItemContributor { - - private NullInfoItemContributor() { - } - - public IAction createAction(ITopicPart topicPart, ITopic topic) { - return null; - } - - public String getContent(ITopic topic) { - return null; - } - - public void fillContextMenu(IInfoItemPart part) { - } - - public void topicActivated(ITopicPart topicPart) { - } - - public void topicDeactivated(ITopicPart topicPart) { - } - - public void topicActivated(IInfoPart infoPart) { - } - - public void topicDeactivated(IInfoPart infoPart) { - } - - public String getId() { - return null; - } - - public String getDefaultMode() { - return null; - } - - public String getAvailableModes() { - return null; - } - - public String getCardLabel() { - return null; - } - - public boolean isCardModeAvailable(ITopic topic, ITopicPart topicPart) { - return false; - } - - public List getPopupMenuActions(ITopicPart topicPart, - ITopic topic) { - return Collections.emptyList(); - } - - } - - private static final IInfoItemContributor NULL_CONTRIBUTOR = new NullInfoItemContributor(); - - private IConfigurationElement element; - - private String id; - - private ImageDescriptor icon; - - private String label; - - private String tooltip; - - private String defaultMode; - - private String availableModes; - - private String cardLabel; - - private IInfoItemContributor implementation; - - public InfoItemContributorProxy(IConfigurationElement element) - throws CoreException { - this.element = element; - this.id = element.getAttribute(RegistryConstants.ATT_ID); - this.label = element.getAttribute(RegistryConstants.ATT_LABEL); - this.tooltip = element.getAttribute(RegistryConstants.ATT_TOOLTIP); - this.defaultMode = element.getAttribute(RegistryConstants.ATT_MODE); - this.availableModes = element - .getAttribute(RegistryConstants.ATT_AVAILABLEMODES); - this.cardLabel = element.getAttribute(RegistryConstants.ATT_CARD_LABEL); - if (RegistryReader.getClassValue(element, - RegistryConstants.ATT_CONTRIBUTOR_CLASS) == null) { - throw new CoreException(new Status(IStatus.ERROR, - element.getNamespaceIdentifier(), 0, - "Invalid extension (missing class name): " + id, //$NON-NLS-1$ - null)); - } - } - - public IAction createAction(ITopicPart topicPart, ITopic topic) { - IAction action = getImplementation().createAction(topicPart, topic); - if (action != null) { - if (action.getImageDescriptor() == null) { - action.setImageDescriptor(getIcon()); - } - if (action.getText() == null) { - action.setText(getLabel()); - } - if (action.getToolTipText() == null) { - action.setToolTipText(getTooltip()); - } - } - return action; - } - - public String getContent(ITopic topic) { - return getImplementation().getContent(topic); - } - - public ImageDescriptor getIcon() { - if (icon == null) { - icon = createIcon(); - } - return icon; - } - - public String getLabel() { - return label; - } - - public String getTooltip() { - return tooltip; - } - - public String getId() { - return id; - } - - public String getDefaultMode() { - return defaultMode; - } - - public String getAvailableModes() { - return availableModes; - } - - public String getCardLabel() { - return cardLabel; - } - - public boolean isCardModeAvailable(ITopic topic, ITopicPart topicPart) { - return getImplementation().isCardModeAvailable(topic, topicPart); - } - - private ImageDescriptor createIcon() { - String iconName = element.getAttribute(ATT_ICON); - if (iconName != null) { - String plugId = element.getNamespaceIdentifier(); - return AbstractUIPlugin.imageDescriptorFromPlugin(plugId, iconName); - } - return null; - } - - public IInfoItemContributor getImplementation() { - if (implementation == null) { - try { - implementation = (IInfoItemContributor) element - .createExecutableExtension(RegistryConstants.ATT_CONTRIBUTOR_CLASS); - } catch (CoreException e) { - Logger.log( - e, - "Failed to create icon tip contributor from class: " //$NON-NLS-1$ - + RegistryReader - .getClassValue( - element, - RegistryConstants.ATT_CONTRIBUTOR_CLASS)); - implementation = NULL_CONTRIBUTOR; - } - } - return implementation; - } - - public void fillContextMenu(IInfoItemPart part) { - getImplementation().fillContextMenu(part); - } - - public void topicActivated(IInfoPart infoPart) { - getImplementation().topicActivated(infoPart); - } - - public void topicDeactivated(IInfoPart infoPart) { - getImplementation().topicDeactivated(infoPart); - } - - public void topicActivated(ITopicPart topicPart) { - getImplementation().topicActivated(topicPart); - } - - public void topicDeactivated(ITopicPart topicPart) { - getImplementation().topicDeactivated(topicPart); - } - - public List getPopupMenuActions(ITopicPart topicPart, - ITopic topic) { - return getImplementation().getPopupMenuActions(topicPart, topic); - } - -} +package org.xmind.ui.internal; + +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_ICON; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.xmind.core.ITopic; +import org.xmind.ui.mindmap.IInfoItemContributor; +import org.xmind.ui.mindmap.IInfoItemPart; +import org.xmind.ui.mindmap.IInfoPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.util.Logger; + +public class InfoItemContributorProxy implements IInfoItemContributor { + + private static class NullInfoItemContributor implements + IInfoItemContributor { + + private NullInfoItemContributor() { + } + + public IAction createAction(ITopicPart topicPart, ITopic topic) { + return null; + } + + public String getContent(ITopic topic) { + return null; + } + + public void fillContextMenu(IInfoItemPart part) { + } + + public void topicActivated(ITopicPart topicPart) { + } + + public void topicDeactivated(ITopicPart topicPart) { + } + + public void topicActivated(IInfoPart infoPart) { + } + + public void topicDeactivated(IInfoPart infoPart) { + } + + public String getId() { + return null; + } + + public String getDefaultMode() { + return null; + } + + public String getAvailableModes() { + return null; + } + + public String getCardLabel() { + return null; + } + + public boolean isCardModeAvailable(ITopic topic, ITopicPart topicPart) { + return false; + } + + public List getPopupMenuActions(ITopicPart topicPart, + ITopic topic) { + return Collections.emptyList(); + } + + } + + private static final IInfoItemContributor NULL_CONTRIBUTOR = new NullInfoItemContributor(); + + private IConfigurationElement element; + + private String id; + + private ImageDescriptor icon; + + private String label; + + private String tooltip; + + private String defaultMode; + + private String availableModes; + + private String cardLabel; + + private IInfoItemContributor implementation; + + public InfoItemContributorProxy(IConfigurationElement element) + throws CoreException { + this.element = element; + this.id = element.getAttribute(RegistryConstants.ATT_ID); + this.label = element.getAttribute(RegistryConstants.ATT_LABEL); + this.tooltip = element.getAttribute(RegistryConstants.ATT_TOOLTIP); + this.defaultMode = element.getAttribute(RegistryConstants.ATT_MODE); + this.availableModes = element + .getAttribute(RegistryConstants.ATT_AVAILABLEMODES); + this.cardLabel = element.getAttribute(RegistryConstants.ATT_CARD_LABEL); + if (RegistryReader.getClassValue(element, + RegistryConstants.ATT_CONTRIBUTOR_CLASS) == null) { + throw new CoreException(new Status(IStatus.ERROR, + element.getNamespaceIdentifier(), 0, + "Invalid extension (missing class name): " + id, //$NON-NLS-1$ + null)); + } + } + + public IAction createAction(ITopicPart topicPart, ITopic topic) { + IAction action = getImplementation().createAction(topicPart, topic); + if (action != null) { + if (action.getImageDescriptor() == null) { + action.setImageDescriptor(getIcon()); + } + if (action.getText() == null) { + action.setText(getLabel()); + } + if (action.getToolTipText() == null) { + action.setToolTipText(getTooltip()); + } + } + return action; + } + + public String getContent(ITopic topic) { + return getImplementation().getContent(topic); + } + + public ImageDescriptor getIcon() { + if (icon == null) { + icon = createIcon(); + } + return icon; + } + + public String getLabel() { + return label; + } + + public String getTooltip() { + return tooltip; + } + + public String getId() { + return id; + } + + public String getDefaultMode() { + return defaultMode; + } + + public String getAvailableModes() { + return availableModes; + } + + public String getCardLabel() { + return cardLabel; + } + + public boolean isCardModeAvailable(ITopic topic, ITopicPart topicPart) { + return getImplementation().isCardModeAvailable(topic, topicPart); + } + + private ImageDescriptor createIcon() { + String iconName = element.getAttribute(ATT_ICON); + if (iconName != null) { + String plugId = element.getNamespaceIdentifier(); + return AbstractUIPlugin.imageDescriptorFromPlugin(plugId, iconName); + } + return null; + } + + public IInfoItemContributor getImplementation() { + if (implementation == null) { + try { + implementation = (IInfoItemContributor) element + .createExecutableExtension(RegistryConstants.ATT_CONTRIBUTOR_CLASS); + } catch (CoreException e) { + Logger.log( + e, + "Failed to create icon tip contributor from class: " //$NON-NLS-1$ + + RegistryReader + .getClassValue( + element, + RegistryConstants.ATT_CONTRIBUTOR_CLASS)); + implementation = NULL_CONTRIBUTOR; + } + } + return implementation; + } + + public void fillContextMenu(IInfoItemPart part) { + getImplementation().fillContextMenu(part); + } + + public void topicActivated(IInfoPart infoPart) { + getImplementation().topicActivated(infoPart); + } + + public void topicDeactivated(IInfoPart infoPart) { + getImplementation().topicDeactivated(infoPart); + } + + public void topicActivated(ITopicPart topicPart) { + getImplementation().topicActivated(topicPart); + } + + public void topicDeactivated(ITopicPart topicPart) { + getImplementation().topicDeactivated(topicPart); + } + + public List getPopupMenuActions(ITopicPart topicPart, + ITopic topic) { + return getImplementation().getPopupMenuActions(topicPart, topic); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InternalMindMapUI.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InternalMindMapUI.java index e3a3b9a5a..1a93379fc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InternalMindMapUI.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/InternalMindMapUI.java @@ -1,245 +1,245 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import org.eclipse.core.runtime.Platform; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.part.IPartFactory; -import org.xmind.gef.service.IPlaybackProvider; -import org.xmind.ui.IEditorHistory; -import org.xmind.ui.branch.IBranchPolicyManager; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.decorations.IDecorationManager; -import org.xmind.ui.internal.branch.BranchPolicyManager; -import org.xmind.ui.internal.decorations.DecorationManager; -import org.xmind.ui.internal.editor.WorkbookRefManager; -import org.xmind.ui.internal.mindmap.EditorInputFactory; -import org.xmind.ui.internal.protocols.ProtocolManager; -import org.xmind.ui.mindmap.ICategoryManager; -import org.xmind.ui.mindmap.IEditPolicyManager; -import org.xmind.ui.mindmap.IEditorInputFactory; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.INumberFormatManager; -import org.xmind.ui.mindmap.INumberSeparatorManager; -import org.xmind.ui.mindmap.IProtocolManager; -import org.xmind.ui.mindmap.IResourceManager; -import org.xmind.ui.mindmap.IWorkbookRefManager; -import org.xmind.ui.prefs.PrefConstants; - -/** - * - * @author Frank Shaka - */ -@SuppressWarnings("deprecation") -public class InternalMindMapUI { - - private static InternalMindMapUI instance = null; - - private IPartFactory mindMapPartFactory = null; - - private IPartFactory mindMapTreePartFactory = null; - - private IDndSupport mindMapDndSupport = null; - - private IProtocolManager protocolManager = null; - - private IBranchPolicyManager branchPolicyManager = null; - - private IPlaybackProvider playbackProvider = null; - - private IResourceManager resourceManager = null; - - private DecorationManager decorationManager; - - private ICategoryManager categoryManager; - - private IEditPolicyManager editPolicyManager; - - private IMindMapImages images; - - private INumberFormatManager numberFormatManager; - - private INumberSeparatorManager numberSeparatorManager; - - private IEditorHistory editorHistory; - - /** - * @deprecated - */ - @Deprecated - private IWorkbookRefManager workbookRefManager; - - private EditorInputFactory editorInputFactory; - - private InternalMindMapUI() { - } - - public static InternalMindMapUI getDefault() { - if (instance == null) - instance = new InternalMindMapUI(); - return instance; - } - - public IPartFactory getMindMapPartFactory() { - if (mindMapPartFactory == null) - mindMapPartFactory = new MindMapPartFactory(); - return mindMapPartFactory; - } - - public IPartFactory getMindMapTreePartFactory() { - if (mindMapTreePartFactory == null) { - mindMapTreePartFactory = new MindMapTreePartFactory(); - } - return mindMapTreePartFactory; - } - - public IDndSupport getMindMapDndSupport() { - if (mindMapDndSupport == null) { - mindMapDndSupport = new MindMapDndSupport(); - } - return mindMapDndSupport; - } - - public IProtocolManager getProtocolManager() { - if (protocolManager == null) { - protocolManager = new ProtocolManager(); - } - return protocolManager; - } - - public IBranchPolicyManager getBranchPolicyManager() { - if (branchPolicyManager == null) { - branchPolicyManager = new BranchPolicyManager(); - } - return branchPolicyManager; - } - - public IPlaybackProvider getPlaybackProvider() { - if (playbackProvider == null) { - playbackProvider = new MindMapPlaybackProvider(); - } - return playbackProvider; - } - - public boolean isAnimationEnabled() { - if (Platform.isRunning()) { - return MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.ANIMATION_ENABLED); - } - return false; - } - - public boolean isGradientColorEnabled() { - if (Platform.isRunning()) { - return MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.GRADIENT_COLOR); - } - return false; - } - - public boolean isOverlapsAllowed() { - if (Platform.isRunning()) { - return MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.OVERLAPS_ALLOWED); - } - return false; - } - - public boolean isFreePositionMoveAllowed() { - if (Platform.isRunning()) { - return MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.FREE_POSITION_ALLOWED); - } - return false; - } - - public IResourceManager getResourceManager() { - if (resourceManager == null) { - resourceManager = new MindMapResourceManager(); - } - return resourceManager; - } - - public IDecorationManager getDecorationManager() { - if (decorationManager == null) { - decorationManager = new DecorationManager(); - } - return decorationManager; - } - - public IDecorationFactory getMindMapDecorationFactory() { - if (decorationManager == null) { - decorationManager = new DecorationManager(); - } - return decorationManager; - } - - public ICategoryManager getCategoryManager() { - if (categoryManager == null) { - categoryManager = new CategoryManager(); - } - return categoryManager; - } - - public IEditPolicyManager getEditPolicyManager() { - if (editPolicyManager == null) { - editPolicyManager = new EditPolicyManager(); - } - return editPolicyManager; - } - - /** - * @deprecated - */ - @Deprecated - public IWorkbookRefManager getWorkbookRefManager() { - if (workbookRefManager == null) { - workbookRefManager = new WorkbookRefManager(); - } - return workbookRefManager; - } - - public IMindMapImages getImages() { - if (images == null) { - images = new MindMapImages(); - } - return images; - } - - public INumberFormatManager getNumberFormatManager() { - if (numberFormatManager == null) - numberFormatManager = new NumberFormatExtensionManager(); - return numberFormatManager; - } - - public INumberSeparatorManager getNumberSeparatorManager() { - if (numberSeparatorManager == null) - numberSeparatorManager = new NumberSeparatorExtensionManager(); - return numberSeparatorManager; - } - - public synchronized IEditorHistory getEditorHistory() { - if (editorHistory == null) - editorHistory = new EditorHistory(); - return editorHistory; - } - - public IEditorInputFactory getEditorInputFactory() { - if (editorInputFactory == null) { - editorInputFactory = new EditorInputFactory(); - } - return editorInputFactory; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import org.eclipse.core.runtime.Platform; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.part.IPartFactory; +import org.xmind.gef.service.IPlaybackProvider; +import org.xmind.ui.IEditorHistory; +import org.xmind.ui.branch.IBranchPolicyManager; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.decorations.IDecorationManager; +import org.xmind.ui.internal.branch.BranchPolicyManager; +import org.xmind.ui.internal.decorations.DecorationManager; +import org.xmind.ui.internal.editor.WorkbookRefManager; +import org.xmind.ui.internal.mindmap.EditorInputFactory; +import org.xmind.ui.internal.protocols.ProtocolManager; +import org.xmind.ui.mindmap.ICategoryManager; +import org.xmind.ui.mindmap.IEditPolicyManager; +import org.xmind.ui.mindmap.IEditorInputFactory; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.INumberFormatManager; +import org.xmind.ui.mindmap.INumberSeparatorManager; +import org.xmind.ui.mindmap.IProtocolManager; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.IWorkbookRefManager; +import org.xmind.ui.prefs.PrefConstants; + +/** + * + * @author Frank Shaka + */ +@SuppressWarnings("deprecation") +public class InternalMindMapUI { + + private static InternalMindMapUI instance = null; + + private IPartFactory mindMapPartFactory = null; + + private IPartFactory mindMapTreePartFactory = null; + + private IDndSupport mindMapDndSupport = null; + + private IProtocolManager protocolManager = null; + + private IBranchPolicyManager branchPolicyManager = null; + + private IPlaybackProvider playbackProvider = null; + + private IResourceManager resourceManager = null; + + private DecorationManager decorationManager; + + private ICategoryManager categoryManager; + + private IEditPolicyManager editPolicyManager; + + private IMindMapImages images; + + private INumberFormatManager numberFormatManager; + + private INumberSeparatorManager numberSeparatorManager; + + private IEditorHistory editorHistory; + + /** + * @deprecated + */ + @Deprecated + private IWorkbookRefManager workbookRefManager; + + private EditorInputFactory editorInputFactory; + + private InternalMindMapUI() { + } + + public static InternalMindMapUI getDefault() { + if (instance == null) + instance = new InternalMindMapUI(); + return instance; + } + + public IPartFactory getMindMapPartFactory() { + if (mindMapPartFactory == null) + mindMapPartFactory = new MindMapPartFactory(); + return mindMapPartFactory; + } + + public IPartFactory getMindMapTreePartFactory() { + if (mindMapTreePartFactory == null) { + mindMapTreePartFactory = new MindMapTreePartFactory(); + } + return mindMapTreePartFactory; + } + + public IDndSupport getMindMapDndSupport() { + if (mindMapDndSupport == null) { + mindMapDndSupport = new MindMapDndSupport(); + } + return mindMapDndSupport; + } + + public IProtocolManager getProtocolManager() { + if (protocolManager == null) { + protocolManager = new ProtocolManager(); + } + return protocolManager; + } + + public IBranchPolicyManager getBranchPolicyManager() { + if (branchPolicyManager == null) { + branchPolicyManager = new BranchPolicyManager(); + } + return branchPolicyManager; + } + + public IPlaybackProvider getPlaybackProvider() { + if (playbackProvider == null) { + playbackProvider = new MindMapPlaybackProvider(); + } + return playbackProvider; + } + + public boolean isAnimationEnabled() { + if (Platform.isRunning()) { + return MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.ANIMATION_ENABLED); + } + return false; + } + + public boolean isGradientColorEnabled() { + if (Platform.isRunning()) { + return MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.GRADIENT_COLOR); + } + return false; + } + + public boolean isOverlapsAllowed() { + if (Platform.isRunning()) { + return MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.OVERLAPS_ALLOWED); + } + return false; + } + + public boolean isFreePositionMoveAllowed() { + if (Platform.isRunning()) { + return MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.FREE_POSITION_ALLOWED); + } + return false; + } + + public IResourceManager getResourceManager() { + if (resourceManager == null) { + resourceManager = new MindMapResourceManager(); + } + return resourceManager; + } + + public IDecorationManager getDecorationManager() { + if (decorationManager == null) { + decorationManager = new DecorationManager(); + } + return decorationManager; + } + + public IDecorationFactory getMindMapDecorationFactory() { + if (decorationManager == null) { + decorationManager = new DecorationManager(); + } + return decorationManager; + } + + public ICategoryManager getCategoryManager() { + if (categoryManager == null) { + categoryManager = new CategoryManager(); + } + return categoryManager; + } + + public IEditPolicyManager getEditPolicyManager() { + if (editPolicyManager == null) { + editPolicyManager = new EditPolicyManager(); + } + return editPolicyManager; + } + + /** + * @deprecated + */ + @Deprecated + public IWorkbookRefManager getWorkbookRefManager() { + if (workbookRefManager == null) { + workbookRefManager = new WorkbookRefManager(); + } + return workbookRefManager; + } + + public IMindMapImages getImages() { + if (images == null) { + images = new MindMapImages(); + } + return images; + } + + public INumberFormatManager getNumberFormatManager() { + if (numberFormatManager == null) + numberFormatManager = new NumberFormatExtensionManager(); + return numberFormatManager; + } + + public INumberSeparatorManager getNumberSeparatorManager() { + if (numberSeparatorManager == null) + numberSeparatorManager = new NumberSeparatorExtensionManager(); + return numberSeparatorManager; + } + + public synchronized IEditorHistory getEditorHistory() { + if (editorHistory == null) + editorHistory = new EditorHistory(); + return editorHistory; + } + + public IEditorInputFactory getEditorInputFactory() { + if (editorInputFactory == null) { + editorInputFactory = new EditorInputFactory(); + } + return editorInputFactory; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MarkerImpExpUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MarkerImpExpUtils.java index 6d87a22a3..c198723b4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MarkerImpExpUtils.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MarkerImpExpUtils.java @@ -1,115 +1,115 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.zip.ZipOutputStream; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.internal.dom.MarkerResourceProvider; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.internal.zip.ZipStreamOutputTarget; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.io.DirectoryOutputTarget; -import org.xmind.core.io.IInputSource; -import org.xmind.core.io.IOutputTarget; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.ImageFormat; - -public class MarkerImpExpUtils { - - private static class ImageFileFilter implements FileFilter { - - public boolean accept(File pathname) { - if (ImageFormat.findByExtension( - FileUtils.getExtension(pathname.getAbsolutePath()), null) == null) - return false; - - try { - new Image(Display.getCurrent(), pathname.getAbsolutePath()) - .dispose(); - return true; - } catch (Throwable e) { - return false; - } - } - - } - - private MarkerImpExpUtils() { - } - - public static void exportMarkerPackage(List sourceGroups, - String targetPath, boolean fileOrDirectory) throws IOException { - IOutputTarget target; - if (fileOrDirectory) { - target = new ZipStreamOutputTarget(new ZipOutputStream( - new FileOutputStream(targetPath)), true); - } else { - target = new DirectoryOutputTarget(targetPath); - } - - IMarkerSheet targetSheet = Core.getMarkerSheetBuilder() - .createMarkerSheet(new MarkerResourceProvider(null, target)); - for (IMarkerGroup group : sourceGroups) { - targetSheet.importGroup(group); - } - try { - targetSheet.save(target - .getEntryStream(ArchiveConstants.MARKER_SHEET_XML)); - } catch (CoreException e) { - throw new IOException(); - } finally { - if (target instanceof ZipStreamOutputTarget) { - ((ZipStreamOutputTarget) target).close(); - } - } - } - - public static void importMarkerPackage(String sourcePath) - throws IOException { - try { - if (new File(sourcePath).isDirectory()) { - MindMapUI - .getResourceManager() - .getUserMarkerSheet() - .importFrom(createImageFilesInputSource(sourcePath), - new File(sourcePath).getName()); - } else { - MindMapUI.getResourceManager().getUserMarkerSheet() - .importFrom(sourcePath); - } - MindMapUI.getResourceManager().saveUserMarkerSheet(); - } catch (CoreException e) { - throw new IOException(); - } - } - - private static IInputSource createImageFilesInputSource(String sourcePath) { - DirectoryInputSource source = new DirectoryInputSource(sourcePath); - source.setFilter(new ImageFileFilter()); - return source; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.zip.ZipOutputStream; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.internal.dom.MarkerResourceProvider; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.internal.zip.ZipStreamOutputTarget; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.io.DirectoryOutputTarget; +import org.xmind.core.io.IInputSource; +import org.xmind.core.io.IOutputTarget; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.ImageFormat; + +public class MarkerImpExpUtils { + + private static class ImageFileFilter implements FileFilter { + + public boolean accept(File pathname) { + if (ImageFormat.findByExtension( + FileUtils.getExtension(pathname.getAbsolutePath()), null) == null) + return false; + + try { + new Image(Display.getCurrent(), pathname.getAbsolutePath()) + .dispose(); + return true; + } catch (Throwable e) { + return false; + } + } + + } + + private MarkerImpExpUtils() { + } + + public static void exportMarkerPackage(List sourceGroups, + String targetPath, boolean fileOrDirectory) throws IOException { + IOutputTarget target; + if (fileOrDirectory) { + target = new ZipStreamOutputTarget(new ZipOutputStream( + new FileOutputStream(targetPath)), true); + } else { + target = new DirectoryOutputTarget(targetPath); + } + + IMarkerSheet targetSheet = Core.getMarkerSheetBuilder() + .createMarkerSheet(new MarkerResourceProvider(null, target)); + for (IMarkerGroup group : sourceGroups) { + targetSheet.importGroup(group); + } + try { + targetSheet.save(target + .getEntryStream(ArchiveConstants.MARKER_SHEET_XML)); + } catch (CoreException e) { + throw new IOException(); + } finally { + if (target instanceof ZipStreamOutputTarget) { + ((ZipStreamOutputTarget) target).close(); + } + } + } + + public static void importMarkerPackage(String sourcePath) + throws IOException { + try { + if (new File(sourcePath).isDirectory()) { + MindMapUI + .getResourceManager() + .getUserMarkerSheet() + .importFrom(createImageFilesInputSource(sourcePath), + new File(sourcePath).getName()); + } else { + MindMapUI.getResourceManager().getUserMarkerSheet() + .importFrom(sourcePath); + } + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } catch (CoreException e) { + throw new IOException(); + } + } + + private static IInputSource createImageFilesInputSource(String sourcePath) { + DirectoryInputSource source = new DirectoryInputSource(sourcePath); + source.setFilter(new ImageFileFilter()); + return source; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapContributedContentPageFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapContributedContentPageFactory.java index 4e1cd0adf..35ed14575 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapContributedContentPageFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapContributedContentPageFactory.java @@ -1,41 +1,41 @@ -package org.xmind.ui.internal; - -import org.eclipse.swt.SWT; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.part.IPage; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.outline.MindMapOutlinePage; -import org.xmind.ui.internal.properties.MindMapPropertySheetPage; -import org.xmind.ui.internal.views.WorkbookMetadataPage; -import org.xmind.ui.internal.views.WorkbookOverviewPage; -import org.xmind.ui.internal.views.WorkbookRevisionsPage; -import org.xmind.ui.views.IContributedContentPageFactory; - -public class MindMapContributedContentPageFactory - implements IContributedContentPageFactory { - - public static final String INSPECTOR_PAGE_TYPE_OVERVIEW = "org.xmind.ui.views.overview"; //$NON-NLS-1$ - - public static final String INSPECTOR_PAGE_TYPE_REVISIONS = "org.xmind.ui.views.revisions"; //$NON-NLS-1$ - - public static final String INSPECTOR_PAGE_TYPE_METADATA = "org.xmind.ui.views.metadata"; //$NON-NLS-1$ - - public IPage createInspectorPage(String pageType, IWorkbenchPart part) { - if (part instanceof IGraphicalEditor) { - if (INSPECTOR_PAGE_TYPE_OUTLINE.equals(pageType)) - return new MindMapOutlinePage((IGraphicalEditor) part, - SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - if (INSPECTOR_PAGE_TYPE_PROPERTIES.equals(pageType)) - return new MindMapPropertySheetPage((IGraphicalEditor) part); - if (INSPECTOR_PAGE_TYPE_OVERVIEW.equals(pageType)) - return new WorkbookOverviewPage((IGraphicalEditor) part); - if (INSPECTOR_PAGE_TYPE_REVISIONS.equals(pageType)) - return new WorkbookRevisionsPage((IGraphicalEditor) part); - if (INSPECTOR_PAGE_TYPE_METADATA.equals(pageType)) - return new WorkbookMetadataPage((IEditorPart) part); - } - return null; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.swt.SWT; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.IPage; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.outline.MindMapOutlinePage; +import org.xmind.ui.internal.properties.MindMapPropertySheetPage; +import org.xmind.ui.internal.views.WorkbookMetadataPage; +import org.xmind.ui.internal.views.WorkbookOverviewPage; +import org.xmind.ui.internal.views.WorkbookRevisionsPage; +import org.xmind.ui.views.IContributedContentPageFactory; + +public class MindMapContributedContentPageFactory + implements IContributedContentPageFactory { + + public static final String INSPECTOR_PAGE_TYPE_OVERVIEW = "org.xmind.ui.views.overview"; //$NON-NLS-1$ + + public static final String INSPECTOR_PAGE_TYPE_REVISIONS = "org.xmind.ui.views.revisions"; //$NON-NLS-1$ + + public static final String INSPECTOR_PAGE_TYPE_METADATA = "org.xmind.ui.views.metadata"; //$NON-NLS-1$ + + public IPage createInspectorPage(String pageType, IWorkbenchPart part) { + if (part instanceof IGraphicalEditor) { + if (INSPECTOR_PAGE_TYPE_OUTLINE.equals(pageType)) + return new MindMapOutlinePage((IGraphicalEditor) part, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + if (INSPECTOR_PAGE_TYPE_PROPERTIES.equals(pageType)) + return new MindMapPropertySheetPage((IGraphicalEditor) part); + if (INSPECTOR_PAGE_TYPE_OVERVIEW.equals(pageType)) + return new WorkbookOverviewPage((IGraphicalEditor) part); + if (INSPECTOR_PAGE_TYPE_REVISIONS.equals(pageType)) + return new WorkbookRevisionsPage((IGraphicalEditor) part); + if (INSPECTOR_PAGE_TYPE_METADATA.equals(pageType)) + return new WorkbookMetadataPage((IEditorPart) part); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapImages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapImages.java index a05d1e86e..b3eb5a673 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapImages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapImages.java @@ -1,227 +1,227 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.io.File; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.internal.util.BundleUtility; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ImageUtils; - -public class MindMapImages implements IMindMapImages { - - private Map descriptors = new HashMap(); - - private Map cursors = new HashMap(); - - /* package */ MindMapImages() { - } - - public ImageDescriptor get(String fullPath) { - ImageDescriptor descriptor = descriptors.get(fullPath); - if (descriptor == null) { - descriptor = createImageDescriptor(fullPath); - if (descriptor != null) - descriptors.put(fullPath, descriptor); - } - return descriptor; - } - - private ImageDescriptor createImageDescriptor(String path) { - URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, path); - if (url != null) - return ImageDescriptor.createFromURL(url); - return null; - } - - public ImageDescriptor get(String fileName, String mainPath) { - return get(mainPath + fileName); - } - - public ImageDescriptor get(String fileName, boolean enabled) { - String mainPath = enabled ? PATH_E : PATH_D; - return get(fileName, mainPath); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.mindmap.IMindMapImages#getTopicIcon(org.xmind.core.ITopic, - * boolean) - */ - public ImageDescriptor getTopicIcon(ITopic topic, boolean enabled) { - String type = topic.getType(); - if (ITopic.ROOT.equals(type)) { - return get(CENTRAL, enabled); - } - if (ITopic.SUMMARY.equals(type)) { - return get(SUMMARY_TOPIC, enabled); - } - if (ITopic.DETACHED.equals(type)) { - return get(FLOATING, enabled); - } - if (ITopic.CALLOUT.equals(type)) { - return get(CALLOUT, enabled); - } - ITopic parent = topic.getParent(); - if (parent != null && parent.isRoot()) { - return get(MAIN, enabled); - } - return get(TOPIC, enabled); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.mindmap.IMindMapImages#getElementIcon(java.lang.Object) - */ - public ImageDescriptor getElementIcon(Object element, boolean enabled) { - if (element instanceof ITopic) { - ITopic topic = (ITopic) element; - String hyperlink = topic.getHyperlink(); - if (hyperlink != null) { - IAction action = MindMapUI.getProtocolManager() - .createOpenHyperlinkAction(topic, hyperlink); - if (action != null && action.getImageDescriptor() != null) - return action.getImageDescriptor(); - } - return getTopicIcon(topic, enabled); - } else if (element instanceof ISheet) { - return get(SHEET, enabled); - } else if (element instanceof IWorkbook) { - return get(WORKBOOK, enabled); - } else if (element instanceof IBoundary) { - return get(BOUNDARY, enabled); - } else if (element instanceof IRelationship) { - return get(RELATIONSHIP, enabled); - } - return null; - } - - public ImageDescriptor getWizBan(String fileName) { - return get(fileName, PATH_WIZ); - } - - public Cursor getCursor(CursorFactory factory) { - if (factory == null) - return null; - String id = factory.getId(); - if (id == null) - return null; - Cursor cursor = cursors.get(id); - if (cursor == null) { - cursor = factory.createCursor(this); - if (cursor != null) - cursors.put(id, cursor); - } - return cursor; - } - - public Cursor createCursor(String name, int hotX, int hotY) { - ImageDescriptor sourceDesc = get(name + ".bmp", PATH_POINTERS); //$NON-NLS-1$ - if (sourceDesc == null) - return null; - ImageData source = sourceDesc.getImageData(); - if (source == null) - return null; - ImageDescriptor maskDesc = get(name + "_mask.bmp", PATH_POINTERS); //$NON-NLS-1$ - if (maskDesc != null) { - ImageData mask = maskDesc.getImageData(); - if (mask != null) { - return new Cursor(null, source, mask, hotX, hotY); - } - } - return new Cursor(null, source, hotX, hotY); - } - - public ImageDescriptor getFileIcon(String path) { - return getFileIcon(path, false); - } - - public ImageDescriptor getFileIcon(String path, - boolean returnNullIfUnidentifiable) { - String extension = FileUtils.getExtension(path); - if (extension == null || "".equals(extension)) { //$NON-NLS-1$ - if (new File(path).isDirectory()) { - return get(OPEN, true); - } - if (returnNullIfUnidentifiable) - return null; - return get(UNKNOWN_FILE, true); - } - String key = "org.xmind.ui.fileIcon" + extension; //$NON-NLS-1$ - ImageDescriptor image = ImageUtils.getDescriptor(key); - if (image == null) { - image = createFileIcon(extension, new File(path).isDirectory(), - returnNullIfUnidentifiable); - ImageUtils.putImageDescriptor(key, image); - } - return image; - } - - private ImageDescriptor createFileIcon(String fileExtension, - boolean directory, boolean returnNullIfUnidentifiable) { - Program p = Program.findProgram(fileExtension); - if (p != null) { - ImageData data = p.getImageData(); - if (data != null) { - if (Util.isMac()) - return ImageUtils.scaleImage(Display.getCurrent(), - ImageDescriptor.createFromImageData(data), 16, 16); - - //fix bug: icon has black shadow in Windows. - String tempPath = getTempFileIconPath(); - - ImageLoader imageLoader = new ImageLoader(); - imageLoader.data = new ImageData[] { data }; - imageLoader.save(tempPath, SWT.IMAGE_ICO); - - Image image = new Image(Display.getCurrent(), tempPath); - return ImageDescriptor.createFromImage(image); - } - } - if (directory) - return get(OPEN, true); - if (returnNullIfUnidentifiable) - return null; - return get(UNKNOWN_FILE, true); - } - - private String getTempFileIconPath() { - String tempFile = Core.getWorkspace().getTempFile("fileIcons/" //$NON-NLS-1$ - + Core.getIdFactory().createId() + ".ico"); //$NON-NLS-1$ - return tempFile; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.io.File; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.internal.util.BundleUtility; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ImageUtils; + +public class MindMapImages implements IMindMapImages { + + private Map descriptors = new HashMap(); + + private Map cursors = new HashMap(); + + /* package */ MindMapImages() { + } + + public ImageDescriptor get(String fullPath) { + ImageDescriptor descriptor = descriptors.get(fullPath); + if (descriptor == null) { + descriptor = createImageDescriptor(fullPath); + if (descriptor != null) + descriptors.put(fullPath, descriptor); + } + return descriptor; + } + + private ImageDescriptor createImageDescriptor(String path) { + URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, path); + if (url != null) + return ImageDescriptor.createFromURL(url); + return null; + } + + public ImageDescriptor get(String fileName, String mainPath) { + return get(mainPath + fileName); + } + + public ImageDescriptor get(String fileName, boolean enabled) { + String mainPath = enabled ? PATH_E : PATH_D; + return get(fileName, mainPath); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.mindmap.IMindMapImages#getTopicIcon(org.xmind.core.ITopic, + * boolean) + */ + public ImageDescriptor getTopicIcon(ITopic topic, boolean enabled) { + String type = topic.getType(); + if (ITopic.ROOT.equals(type)) { + return get(CENTRAL, enabled); + } + if (ITopic.SUMMARY.equals(type)) { + return get(SUMMARY_TOPIC, enabled); + } + if (ITopic.DETACHED.equals(type)) { + return get(FLOATING, enabled); + } + if (ITopic.CALLOUT.equals(type)) { + return get(CALLOUT, enabled); + } + ITopic parent = topic.getParent(); + if (parent != null && parent.isRoot()) { + return get(MAIN, enabled); + } + return get(TOPIC, enabled); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.mindmap.IMindMapImages#getElementIcon(java.lang.Object) + */ + public ImageDescriptor getElementIcon(Object element, boolean enabled) { + if (element instanceof ITopic) { + ITopic topic = (ITopic) element; + String hyperlink = topic.getHyperlink(); + if (hyperlink != null) { + IAction action = MindMapUI.getProtocolManager() + .createOpenHyperlinkAction(topic, hyperlink); + if (action != null && action.getImageDescriptor() != null) + return action.getImageDescriptor(); + } + return getTopicIcon(topic, enabled); + } else if (element instanceof ISheet) { + return get(SHEET, enabled); + } else if (element instanceof IWorkbook) { + return get(WORKBOOK, enabled); + } else if (element instanceof IBoundary) { + return get(BOUNDARY, enabled); + } else if (element instanceof IRelationship) { + return get(RELATIONSHIP, enabled); + } + return null; + } + + public ImageDescriptor getWizBan(String fileName) { + return get(fileName, PATH_WIZ); + } + + public Cursor getCursor(CursorFactory factory) { + if (factory == null) + return null; + String id = factory.getId(); + if (id == null) + return null; + Cursor cursor = cursors.get(id); + if (cursor == null) { + cursor = factory.createCursor(this); + if (cursor != null) + cursors.put(id, cursor); + } + return cursor; + } + + public Cursor createCursor(String name, int hotX, int hotY) { + ImageDescriptor sourceDesc = get(name + ".bmp", PATH_POINTERS); //$NON-NLS-1$ + if (sourceDesc == null) + return null; + ImageData source = sourceDesc.getImageData(); + if (source == null) + return null; + ImageDescriptor maskDesc = get(name + "_mask.bmp", PATH_POINTERS); //$NON-NLS-1$ + if (maskDesc != null) { + ImageData mask = maskDesc.getImageData(); + if (mask != null) { + return new Cursor(null, source, mask, hotX, hotY); + } + } + return new Cursor(null, source, hotX, hotY); + } + + public ImageDescriptor getFileIcon(String path) { + return getFileIcon(path, false); + } + + public ImageDescriptor getFileIcon(String path, + boolean returnNullIfUnidentifiable) { + String extension = FileUtils.getExtension(path); + if (extension == null || "".equals(extension)) { //$NON-NLS-1$ + if (new File(path).isDirectory()) { + return get(OPEN, true); + } + if (returnNullIfUnidentifiable) + return null; + return get(UNKNOWN_FILE, true); + } + String key = "org.xmind.ui.fileIcon" + extension; //$NON-NLS-1$ + ImageDescriptor image = ImageUtils.getDescriptor(key); + if (image == null) { + image = createFileIcon(extension, new File(path).isDirectory(), + returnNullIfUnidentifiable); + ImageUtils.putImageDescriptor(key, image); + } + return image; + } + + private ImageDescriptor createFileIcon(String fileExtension, + boolean directory, boolean returnNullIfUnidentifiable) { + Program p = Program.findProgram(fileExtension); + if (p != null) { + ImageData data = p.getImageData(); + if (data != null) { + if (Util.isMac()) + return ImageUtils.scaleImage(Display.getCurrent(), + ImageDescriptor.createFromImageData(data), 16, 16); + + //fix bug: icon has black shadow in Windows. + String tempPath = getTempFileIconPath(); + + ImageLoader imageLoader = new ImageLoader(); + imageLoader.data = new ImageData[] { data }; + imageLoader.save(tempPath, SWT.IMAGE_ICO); + + Image image = new Image(Display.getCurrent(), tempPath); + return ImageDescriptor.createFromImage(image); + } + } + if (directory) + return get(OPEN, true); + if (returnNullIfUnidentifiable) + return null; + return get(UNKNOWN_FILE, true); + } + + private String getTempFileIconPath() { + String tempFile = Core.getWorkspace().getTempFile("fileIcons/" //$NON-NLS-1$ + + Core.getIdFactory().createId() + ".ico"); //$NON-NLS-1$ + return tempFile; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapMessages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapMessages.java index 575708e8c..060575cb8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapMessages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapMessages.java @@ -1,778 +1,788 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import org.eclipse.osgi.util.NLS; - -public class MindMapMessages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.ui.internal.messages"; //$NON-NLS-1$ - - public static String TemplateLabelProvider_loadThumbnail_jobName; - - public static String TitleText_CalloutTopic; - - public static String TitleText_CentralTopic; - public static String TitleText_MainTopic; - public static String TitleText_Subtopic; - public static String TitleText_FloatingTopic; - public static String TitleText_Sheet; - public static String TitleText_SummaryTopic; - public static String TitleText_Workbook; - public static String TitleText_Relationship; - public static String TitleText_Boundary; - - public static String ViewMenu; - - public static String InsertMenu; - public static String ModifyComment_label; - - public static String ModifyMenu; - public static String ToolsMenu; - public static String SortMenu; - - public static String TopicProtocol_GoToTopic_text; - public static String MindMapActionFactory_Duplicate_text; - - public static String MindMapActionFactory_Duplicate_tooltip; - - public static String MindMapActionFactory_NewSheetFromTemplate_tooltip; - - public static String MindMapActionFactory_NewSheetFromTemplte_text; - - public static String MindMapMenu; - public static String AlignmentMenu; - - public static String Category_Topic; - public static String Category_Sheet; - public static String Category_Boundary; - public static String Category_Relationship; -// public static String Category_Summary; - public static String Category_Marker; - public static String Category_Image; - public static String MultipleObjects; - public static String NoObject; - public static String UnknownObjects; - - public static String UndoRedoTipsService_Undo; - public static String UndoRedoTipsService_Redo; - - public static String UnexpectedWorkbookLoadFailure_error; - - public static String StatusLine_MultipleItems; - public static String StatusLine_MultipleItemPattern; - public static String StatusLine_OneItemPattern; - public static String StatusLine_OneItemNoTitlePattern; - - public static String NewWorkbookDialog_text; - public static String NewWorkbookDialog_toolTip; - public static String NewWorkbook_text; - public static String NewWorkbook_toolTip; - public static String NewFromTemplate_text; - public static String NewFromTemplate_toolTip; - public static String ActualSize_text; - public static String ActualSize_toolTip; - - public static String AddComment_text; - public static String AddComment_tooltip; - - public static String AddCommentLink_text; - public static String AddCommentLink_tooltip; - - public static String ModifyComment_text; - public static String ModifyComment_tooltip; - - public static String CancelHyperlink_text; - public static String CancelHyperlink_toolTip; - - public static String Category_Callout; - - public static String Category_Summary; - public static String Collapse_text; - public static String Collapse_toolTip; - public static String CollapseAll_text; - public static String CollapseAll_toolTip; - - public static String ColorfulSheetMenu_mac_blue; - - public static String ColorfulSheetMenu_mac_gray; - - public static String ColorfulSheetMenu_mac_green; - - public static String ColorfulSheetMenu_mac_none; - - public static String ColorfulSheetMenu_mac_orange; - - public static String ColorfulSheetMenu_mac_purple; - - public static String ColorfulSheetMenu_mac_red; - - public static String ColorfulSheetMenu_mac_yellow; - - public static String ColorfulSheetMenu_windows_blue; - - public static String ColorfulSheetMenu_windows_brown; - - public static String ColorfulSheetMenu_windows_gray; - - public static String ColorfulSheetMenu_windows_green; - - public static String ColorfulSheetMenu_windows_none; - - public static String ColorfulSheetMenu_windows_purple; - - public static String ColorfulSheetMenu_windows_red; - - public static String ColorfulSheetMenu_windows_yellow; - - public static String Comment_Delete_label; - public static String Comment_Edit_label; - public static String Comment_Reply_label; - public static String Comment_Cancel_text; - public static String Comment_Cancel_tooltip; - public static String Comment_JustNow_text; - public static String Comment_NoComments_text; - public static String Comment_FirstAdd_text; - public static String Comment_SHEET_text; - public static String Comment_Add_text; - public static String Comment_TOPIC_text; - - public static String Comments_FirstAdd_text; - - public static String Comments_lable; - - public static String Comments_NoComments_text; - - public static String Command_InsertImage; - public static String DeleteSheet_text; - public static String DeleteSheet_toolTip; - - public static String DeleteSingleRevisionCommand_label; - - public static String DeleteStyleHandler_DeleteStytles; - - public static String DeleteStyleHandler_DeleteStytlesConfirm; - public static String DeleteStyle_MessageDialog_description; - - public static String DeleteStyle_MessageDialog_styles; - - public static String DeleteStyle_MessageDialog_themes; - - public static String DeleteStyles_MessageDialog_title; - - public static String Delete_OtherSheets_text; - public static String Delete_OtherSheets_toolTip; - - public static String DeleteComment_label; - public static String DeleteComment_text; - public static String DeleteComment_tooltip; - - public static String DeleteMultipleRevisionsCommand_label; - public static String DeleteNotes_label; - public static String DeleteNotes_text; - public static String DeleteNotes_tooltip; - public static String DeleteMarker_label; - public static String DrillDown_text; - public static String DrillDown_toolTip; - public static String DrillUp_text; - public static String DrillUp_toolTip; - public static String EditLabel_text; - public static String EditLabel_toolTip; - public static String EditNotes_text; - public static String EditNotes_toolTip; - public static String Edit_text; - public static String Edit_toolTip; - - public static String EditComments_text; - public static String EditTitle_text; - public static String EditTitle_toolTip; - public static String Extend_text; - public static String Extend_toolTip; - public static String ExtendAll_text; - public static String ExtendAll_toolTip; - - public static String FileProtocol_OpenFile_text; - - public static String FileProtocol_OpenFolder_text; - - public static String Finish_text; - public static String Finish_toolTip; - public static String FitMap_text; - public static String FitMap_toolTip; - public static String FitSelection_text; - public static String FitSelection_toolTip; - public static String InsertAttachment_text; - public static String InsertAttachment_toolTip; - public static String InsertBoundary_text; - public static String InsertBoundary_toolTip; - public static String InsertFloatingTopic_text; - public static String InsertFloatingTopic_toolTip; - public static String InsertFloatingCentralTopic_text; - public static String InsertFloatingCentralTopic_toolTip; - public static String InsertImage_text; - public static String InsertImage_toolTip; - public static String InsertParentTopic_text; - public static String InsertParentTopic_toolTip; - public static String InsertRelationship_text; - public static String InsertRelationship_toolTip; - public static String InsertSubtopic_text; - public static String InsertSubtopic_toolTip; - public static String InsertSummary_text; - public static String InsertSummary_toolTip; - public static String InsertTopic_text; - public static String InsertTopic_toolTip; - public static String InsertTopicBefore_text; - public static String InsertTopicBefore_toolTip; - public static String Markers_text; - public static String ModifyHyperlink_text; - public static String ModifyHyperlink_toolTip; - public static String ModifySheetTabColorCommand_label; - public static String ImportWorkbook_text; - public static String ImportWorkbook_toolTip; - - public static String EncryptDialog_title; - public static String EncryteDialog_label_message; - public static String ErrorDetailDialog_ReportProblem; - - public static String ErrorDetailDialog_title; - public static String Finish_button_text; - public static String EncryptDialogPane_board_message; - public static String EncryptDialogPane_assist_message; - public static String EncryptDialogPane_oldpassword_text; - public static String EncryptDialogPane_password_text; - public static String EncryptDialogPane_newpassword_text; - public static String EncryptDialogPane_confirm_text; - public static String EncryptDialogPane_detailsButton_label; - public static String ErrorDeteilDialog_ReportProblemMessage; - - public static String ErrorDialogPane_summaryBoard_text; - public static String LoadWorkbookJob_retrive_password_message; - public static String LoadWorkbookJob_firstTry_message; - public static String LoadWorkbookJob_moreTry_message; - public static String LoadWorkbookJob_text; - public static String LoadWorkbookJob_errorDialog_GoToBackup_message; - - public static String LoadWorkbookJob_errorDialog_title; - - public static String LoadWorkbookJob_errorDialog_Pre_message; - - public static String LocalFileWorkbookRef_changeDialog_cancel_button; - - public static String LocalFileWorkbookRef_changeDialog_message; - - public static String LocalFileWorkbookRef_changeDialog_title; - - public static String LocalFileWorkbookRef_changeDialog_update_button; - - public static String LocalFileWorkbookRef_removeDialog_delete_button; - - public static String LocalFileWorkbookRef_removeDialog_message; - - public static String LocalFileWorkbookRef_removeDialog_saveAs_button; - - public static String LocalFileWorkbookRef_removeDialog_title; - - public static String MindMapEditor_CompatibilityWarning_dialogTitle; - - public static String MindMapEditor_CompatibilityWarning_Overwrite_button; - - public static String MindMapEditor_CompatibilityWarning_OverwritingHigherVersion_message; - - public static String MindMapEditor_CompatibilityWarning_SaveAs_button; - - public static String MindMapEditor_fileChangedDialog_message_prefix; - - public static String MindMapEditor_fileRemovedDialog_message_prefix; - - public static String MindMapEditor_partInitException_message; - - public static String MindMapEditor_passwordPrompt_message1; - - public static String MindMapEditor_passwordPrompt_message2; - - public static String MindMapEditorInput_default_name; - - public static String MindMapPropertySheetPage_ResetStyle_text; - - public static String NotesHyperlinkDialog_display_text; - public static String NotesHyperlinkDialog_hyperlinkReference_text; - public static String NotesHyperlinkDialog_title; - - public static String InsertHyperlinkAction_text; - public static String InserthyperlinkAction_toolTip; - public static String NEWSheet_from_text; - public static String NEWSheet_from_toolTip; - - public static String ModifyWrapWidth_toolTip0; - public static String NewSheet_text; - public static String NewSheet_toolTip; - public static String NewSheetFromTemplateDialog_button_Choose; - - public static String NewSheetFromTemplateDialog_NewSheetFromTemplteCommand_label; - - public static String NewSheetFromTemplateDialog_text; - - public static String OpenWorkbook_text; - public static String OpenWorkbook_toolTip; - public static String OpenHomeMap_text; - public static String OpenHomeMap_toolTip; - public static String OpenHomeMap_Error_message; - - public static String OpenHomeMapAction_HomeMapMissingMessage; - - public static String OpenHomeMapAction_LaterOperationButton; - public static String OpenHyperlink_text; - public static String OpenHyperlink_toolTip; - public static String RenameSheet_text; - public static String RenameSheet_toolTip; - public static String ResetPosition_text; - public static String ResetPosition_toolTip; - public static String SelectBrothers_text; - public static String SelectBrothers_toolTip; - public static String SelectChildren_text; - public static String SelectChildren_toolTip; - public static String GoToCentral_text; - public static String GoToCentral_toolTip; - public static String SaveAttachment_text; - public static String SaveAttachment_toolTip; - public static String SaveAsTemplate_text; - public static String SaveAsTemplate_toolTip; - public static String SaveAsTemplateHandler_inputDialog_message; - public static String SaveAsTemplateHandler_inputDialog_title; - - public static String SaveSheetAs_text; - public static String SaveSheetAs_toolTip; - public static String ShowAllComments_text; - - public static String ShowAllComments_tooltip; - - public static String ShowAllNotes_text; - - public static String ShowAllNotes_tooltip; - - public static String ShowWorkbook_text; - public static String ShowWorkbook_toolTip; - public static String ShowSheet_text; - public static String ShowSheet_toolTip; - public static String Structure_text; - public static String Tile_text; - public static String Tile_toolTip; - public static String Traverse_text; - public static String Traverse_toolTip; - public static String ZoomIn_text; - public static String ZoomIn_toolTip; - public static String ZoomOut_text; - public static String ZoomOut_toolTip; - public static String InsertImageFromFile_text; - public static String InsertImageFromFile_toolTip; - public static String MoveUp_text; - public static String MoveUp_toolTip; - public static String MoveDown_text; - public static String MoveDown_toolTip; - public static String MoveLeft_text; - public static String MoveLeft_toolTip; - public static String MoveRight_text; - public static String MoveRight_toolTip; - public static String ShowMarkerManager_text; - public static String ShowMarkerManager_toolTip; - - public static String ShowNextTopicComments_text; - - public static String ShowNextTopicComments_tooltip; - - public static String ShowPreTopicComments_text; - - public static String ShowPreTopicComments_tooltip; - - public static String SortByTitle_text; - public static String SortByTitle_toolTip; - public static String SortByPriority_text; - public static String SortByPriority_toolTip; - public static String SortByModifiedTime_text; - public static String SortByModifiedTime_toolTip; - - public static String ImageDownload_jobName; - - public static String ImportMarkers_text; - public static String ImportMarkers_toolTip; - public static String ExportMarkers_text; - public static String ExportMarkers_toolTip; - public static String AlignLeft_text; - public static String AlignLeft_toolTip; - public static String AlignRight_text; - public static String AlignRight_toolTip; - public static String AlignCenter_text; - public static String AlignCenter_toolTip; - public static String AlignTop_text; - public static String AlignTop_toolTip; - public static String AlignBottom_text; - public static String AlignBottom_toolTip; - public static String AlignMiddle_text; - public static String AlignMiddle_toolTip; - - public static String AllMarkersMenu_Markers_More_text; - - public static String AllMarkersMenu_Markers_tooltip; - - public static String AllowOverlaps_text; - - public static String AllowOverlaps_toolTip; - - public static String AllowManualLayout_text; - - public static String AllowManualLayout_toolTip; - - public static String BackgroundWorkbookSaver_SaveWorkbook_taskName; - - public static String BackgroundWorkbookSaver_SavingWorkbook_taskNamePattern; - - public static String BreadCrumb_CurrentCentral_text; - - public static String BreadCrumb_ViewAsCentral_text; - - public static String DownloadImageJob_pattern; - - public static String MarkerView_XMindMarkers_label; - public static String MarkerView_UntitledGroup_name; - - public static String MarkerView_UserMarkers_label; - public static String MarkerView_RecentlyUsed_label; - - public static String StylePropertySectionPart_ShowStyleEditorDialogButton_text; - - public static String StylePropertySectionPart_text; - - public static String StylePropertySectionPart_tooltip; - - public static String StylesViewer_Topic_label; - public static String StylesViewer_Boundary_label; - public static String StylesViewer_Relationship_label; - public static String StylesViewer_Map_label; - public static String StylesViewer_Summary_label; - - public static String ThemesView_LinkWithEditor_text; - public static String ThemesView_LinkWithEditor_toolTip; - - public static String DefaultThemeAction_text; - public static String DefaultThemeAction_toolTip; - - public static String ThemeLabel_LoadTheme; - - public static String ThemeUICore_group_default_name; - - public static String ThemeUICore_group_user_name; - - public static String DefaultTheme_title; - - public static String Legend; - - public static String MarkerParameterNamePattern; - - public static String RecentUsed; - - public static String RevertToRevisionCommand_label; - - public static String RevisionsView_DateColumn_text; - - public static String RevisionsView_DeleteRevisionsAction_text; - - public static String RevisionsView_DeleteRevisionsAction_toolTip; - - public static String RevisionsView_PreviewAction_text; - - public static String RevisionsView_PreviewAction_toolTip; - - public static String RevisionsView_RevertToRevisionAction_text; - - public static String RevisionsView_RevertToRevisionAction_toolTip; - - public static String RevisionsView_TimeColumn_text; - - public static String RevisionPage_ShowDetails_message; - - public static String RevisionView_DateTimeColumn_text; - - public static String RevisionView_VersionColumn_text; - - public static String DefaultOverviewPage_message; - public static String DefaultRevisionsPage_message; - - public static String TryPro_text; - public static String TryPro_toolTip; -// public static String TryPro_UpdateSourceDialog_title; -// public static String TryPro_UpdateSourceDialog_label; -// public static String TryPro_UpdateSourceDialog_Online; -// public static String TryPro_UpdateSourceDialog_LocalFile; -// public static String TryPro_UpdateSourceDialog_jobName; -// public static String TryPro_ErrorDialog_title; -// public static String TryPro_ErrorDialog_message; -// public static String TryPro_InstallDialog_title; - - public static String WorkbookEditorInput_name; - - public static String WorkbookFilterName; - - public static String WorkbookHistoryItem_FileMissingMessage; - - public static String WorkbookImportWizard_ImportWorkbook_Title; - - public static String WorkbookImportWizard_ImportXmindMap_Title; - - public static String WorkbookImportWizard_NeedSaveWorkbookMessage; - - public static String WorkbookImportWizard_NoTargetWorkbookMessage; - - public static String WorkbookSavedIncorrectly_error; - - public static String WorkbookSaver_CreateRevisions_taskName; - - public static String WorkbookSaver_Finalize_taskName; - - public static String WorkbookSaver_PrepareNewSaveTarget_taskName; - - public static String WorkbookSaver_SavePreviewImage_taskName; - - public static String WorkbookSaver_SaveWorkbookContent_taskName; - - public static String FileStoreWorkbookAdapter_FailedToSaveWorkbook_error; - - public static String EditInCommentsView_text; - - public static String EditInCommentsView_tooltip; - - public static String EditInNotesView_text; - public static String EditInNotesView_toolTip; - - public static String OpenAttachment_text; - - public static String NotesView_InsertImage_toolTip; -// public static String NotesView_UndoTyping_text; -// public static String NotesView_UndoTyping_toolTip; -// public static String NotesView_RedoTyping_text; -// public static String NotesView_RedoTyping_toolTip; - - public static String ProtocolManager_OpenHyperlink_pattern; - - public static String WordContext_Label_pattern; - public static String WordContext_Notes_pattern; - - public static String Notes_FindReplaceContextPattern; - public static String EmptyNotes_FindReplaceContextName; - - public static String ReopenWorkbookMenu_text; - public static String ReopenWorkbookMenu_NoItemsPlaceholder_text; - public static String ReopenWorkbookMenu_toolTip; - public static String ReopenWorkbookMenu_ClearListAction_text; - - public static String SaveNewRevision_text; - public static String SaveNewRevision_tooltip; - - public static String SaveWizardDialog_location_text; - - public static String SaveWizardDialog_name_text; - - public static String SaveWizardDialog_okButton_text; - - public static String SaveWizardDialog_shell_title; - - public static String SaveWorkbookAsHandler_doneDialog_cancelButton_text; - - public static String SaveWorkbookAsHandler_doneDialog_message; - - public static String SaveWorkbookAsHandler_doneDialog_okButton_text; - - public static String SaveWorkbookAsHandler_doneDialog_title; - - public static String SaveWorkbookAsHandler_oldName_default; - - public static String SaveWorkbookAsHandler_saveAsDialog_description; - - public static String SaveWorkbookAsHandler_saveAsDialog_title; - - public static String SaveWorkbookAsHandler_warningDialog_description; - - public static String SaveWorkbookAsHandler_warningDialog_title; - - public static String SaveWorkbookAsHandler_saveToOtherDialog_title; - - public static String SaveWorkbookAsHandler_saveToOtherDialog_saveTo_text; - - public static String SaveWorkbookAsHandler_saveToOtherDialog_saveToAnother_text; - - public static String WorkbookRevisionsPage_AutoSaveRevisionsCheck_text; - - public static String DuplicateSheet_text; - public static String DuplicateSheet_toolTip; - public static String CopySheet_text; - public static String PasteSheet_text; - - public static String PasswordProvider_askPassword_message; - - public static String RemoveAllStyles_text; - public static String RemoveAllStyles_tooltip; - - public static String InfoItem_Modify_text; - public static String InfoItem_Delete_text; - public static String InfoItem_SaveAttachment_text; - - public static String Notes_Edit_text; - public static String Notes_Delete_text; - - public static String MultipagePrint_Printing; - public static String MultipagePrint_InvalidMargin_title; - public static String MultipagePrint_InvalidMargin_message; - - public static String MultipageSetupDialog_GeneratePreview; - public static String MultipageSetupDialog_GeneratingPreview; - public static String MultipageSetupDialog_GeneratedPreview; - public static String MultipageSetupDialog_FaildGenerate; - public static String MultipageSetupDialog_PrintDirectly; - public static String MultipageSetupDialog_ImageTooLarge; - public static String MultipageSetupDialog_Content; - public static String MultipageSetupDialog_PageSetup; - public static String MultipageSetupDialog_Collapse_Expand; - public static String MultipageSetupDialog_Orientation; - public static String MultipageSetupDialog_Margin; - public static String MultipageSetupDialog_Header; - public static String MultipageSetupDialog_Footer; - public static String MultipageSetupDialog_Pages; - public static String MultipageSetupDialog_SinglePage; - public static String MultipageSetupDialog_MultiplePages; - public static String MultipageSetupDialog_OptimalPagingEffect; - public static String MultipageSetupDialog_Horizontal; - public static String MultipageSetupDialog_Vertical; - public static String MultipageSetupDialog_ShowDetails; - public static String MultipageSetupDialog_HideDetails; - public static String MultipageSetupDialog_showPlusCheck_text; - public static String MultipageSetupDialog_showMinusCheck_text; - - public static String WorkbookMetadata_ModifyAuthorInfo; - - public static String EditorHistoryItem_defaultName; - - public static String SheetCommentViewer_Insert_button; - public static String SheetCommentViewer_Insert_hyperlink; - - public static String BlackBoxDialog_title; - - public static String ProgressDialog_NullContet_message; - public static String ProgressDialog_ShowSystem_check; - public static String ProgressDialog_RemoveAll_hyperlink; - - public static String WorkbookMetaInspectorDialog_message; - - public static String WorkbookRevisionDialog_title; - public static String WorkbookRevisionDialog_Disable_hyperlink; - - public static String OpenLocalFileHandler_MessageDialog_title; - - public static String LocalImageModelPage_title; - public static String LocalImageModelPage_ImageSection_description; - public static String LocalImageModelPage_Insert_button; - - public static String DecryptionDialog_title; - public static String DecryptionDialog_message; - public static String DecryptionDialog_FileName_label; - public static String DecryptionDialog_FileName_untitled; - public static String DecryptionDialog_Password_label; - public static String DecryptionDialog_WarningLabel_text; - public static String DecryptionDialog_Hint_label; - - public static String EncrptionDialog_ChangePassword_title; - public static String EncryptionDialog_SetPassword_title; - public static String EncryptionDialog_ChangePassword_message; - public static String EncryptionDialog_SetPassword_message; - public static String EncryptionDialog_ButtonBar_Set_button; - public static String EncryptionDialog_HintInput_label; - public static String EncryptionDialog_Warning_NotMatch_label; - public static String EncryptionDialog_Warning_NotCorrect_label; - - public static String MindMapEditor_Warning_FileNotFoundDialog_title; - - public static String MindMapEditorInput_Workbook_Untitled_title; - - public static String OverviewCheck_Overview_ON; - public static String OverviewCheck_Overview_OFF; - - public static String OutlineIndexPart_ShowWorkbookAction_text; - public static String OutlineIndexPart_ShowWorkbookAction_toolTip; - public static String OutlineIndexPart_ShowCurrentSheetAction_text; - public static String OutlineIndexPart_ShowCurrentSheetAction_toolTip; - public static String OutlineIndexPart_DefaultPage_message; - - public static String OutlineType_None; - public static String OutlineType_Markers; - public static String OutlineType_Labels; - public static String OutlineType_StartDate; - public static String OutlineType_EndDate; - public static String OutlineType_Assignee; - - public static String OutlineViewer_StartDate_col; - public static String OutlineViewer_EndData_col; - public static String OutlineViewer_Task_col; - - public static String ThemePrefPage_ThemeEditor_label; - - public static String NumberingProperty_NumberDepthLabelProvider_Inherit_text; - public static String NumberingProperty_NumberDepthLabelProvider_Levels_text; - public static String NumberingProperty_TieredCheck_text; - - public static String PropertiesPart_DefaultPage_message; - - public static String MarkerResourceManagerViewer_AddSection_title; - - public static String ResourceManagerPart_title; - public static String ResourceManagerPart_message; - - public static String StyleResourceManager_Editor_button; - - public static String StyleResourceManagerViewer_Topic; - public static String StyleResourceManagerViewer_Boundary; - public static String StyleResourceManagerViewer_Map; - public static String StyleResourceManagerViewer_Paragraph; - public static String StyleResourceManagerViewer_Relationship; - public static String StyleResourceManagerViewer_Summary; - public static String StyleResourceManagerViewer_Text; - public static String StyleResourceManagerViewer_Theme; - public static String StyleResourceManagerViewer_AddSection_title; - - public static String TemplateResourceManagerPage_Import_button; - public static String TemplateResourceManagerPage_Delete_ConfirmDialog_title; - public static String TemplateResourceManagerPage_Delete_ConfirmDialog_message; - public static String TemplateResourceManagerPage_AddTemplates_label; - public static String TemplateResourceManagerPage_TemplateFilterName_label; - public static String TemplateResourceManagerPage_AddTemplates_tooltip; - - public static String TemplateResourceManagerViewer_SystemGroup_name; - public static String TemplateResourceManagerViewer_UserGroup_name; - - public static String ThemeResourceManagerPage_New_button; - public static String ThemeResourceManagerPage_Edit_button; - - public static String ResourceUtil_Copy_name; - public static String ResourceUtil_Duplicate_name; - - public static String ThemeGroupCore_UserGroup_name; - public static String ThemeGroupCore_DefaultGroup_name; - - public static String ExportPage_Categore_Recent_name; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, MindMapMessages.class); - } - - private MindMapMessages() { - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import org.eclipse.osgi.util.NLS; + +public class MindMapMessages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.ui.internal.messages"; //$NON-NLS-1$ + + public static String TemplateLabelProvider_loadThumbnail_jobName; + + public static String TitleText_CalloutTopic; + + public static String TitleText_CentralTopic; + public static String TitleText_MainTopic; + public static String TitleText_Subtopic; + public static String TitleText_FloatingTopic; + public static String TitleText_Sheet; + public static String TitleText_SummaryTopic; + public static String TitleText_Workbook; + public static String TitleText_Relationship; + public static String TitleText_Boundary; + + public static String ViewMenu; + + public static String InsertMenu; + public static String ModifyComment_label; + + public static String ModifyMenu; + public static String ToolsMenu; + public static String SortMenu; + + public static String TopicProtocol_GoToTopic_text; + public static String MindMapActionFactory_Duplicate_text; + + public static String MindMapActionFactory_Duplicate_tooltip; + + public static String MindMapActionFactory_NewSheetFromTemplate_tooltip; + + public static String MindMapActionFactory_NewSheetFromTemplte_text; + + public static String MindMapMenu; + public static String AlignmentMenu; + + public static String Category_Topic; + public static String Category_Sheet; + public static String Category_Boundary; + public static String Category_Relationship; +// public static String Category_Summary; + public static String Category_Marker; + public static String Category_Image; + public static String MultipleObjects; + public static String NoObject; + public static String UnknownObjects; + + public static String UndoRedoTipsService_Undo; + public static String UndoRedoTipsService_Redo; + + public static String UnexpectedWorkbookLoadFailure_error; + + public static String StatusLine_MultipleItems; + public static String StatusLine_MultipleItemPattern; + public static String StatusLine_OneItemPattern; + public static String StatusLine_OneItemNoTitlePattern; + + public static String NewWorkbookDialog_text; + public static String NewWorkbookDialog_toolTip; + public static String NewWorkbook_text; + public static String NewWorkbook_toolTip; + public static String NewFromTemplate_text; + public static String NewFromTemplate_toolTip; + public static String ActualSize_text; + public static String ActualSize_toolTip; + + public static String AddComment_text; + public static String AddComment_tooltip; + + public static String AddCommentLink_text; + public static String AddCommentLink_tooltip; + + public static String ModifyComment_text; + public static String ModifyComment_tooltip; + + public static String CancelHyperlink_text; + public static String CancelHyperlink_toolTip; + + public static String Category_Callout; + + public static String Category_Summary; + public static String Collapse_text; + public static String Collapse_toolTip; + public static String CollapseAll_text; + public static String CollapseAll_toolTip; + + public static String ColorfulSheetMenu_mac_blue; + + public static String ColorfulSheetMenu_mac_gray; + + public static String ColorfulSheetMenu_mac_green; + + public static String ColorfulSheetMenu_mac_none; + + public static String ColorfulSheetMenu_mac_orange; + + public static String ColorfulSheetMenu_mac_purple; + + public static String ColorfulSheetMenu_mac_red; + + public static String ColorfulSheetMenu_mac_yellow; + + public static String ColorfulSheetMenu_windows_blue; + + public static String ColorfulSheetMenu_windows_brown; + + public static String ColorfulSheetMenu_windows_gray; + + public static String ColorfulSheetMenu_windows_green; + + public static String ColorfulSheetMenu_windows_none; + + public static String ColorfulSheetMenu_windows_purple; + + public static String ColorfulSheetMenu_windows_red; + + public static String ColorfulSheetMenu_windows_yellow; + + public static String Comment_Delete_label; + public static String Comment_Edit_label; + public static String Comment_Reply_label; + public static String Comment_Cancel_text; + public static String Comment_Cancel_tooltip; + public static String Comment_JustNow_text; + public static String Comment_NoComments_text; + public static String Comment_FirstAdd_text; + public static String Comment_SHEET_text; + public static String Comment_Add_text; + public static String Comment_TOPIC_text; + + public static String Comments_FirstAdd_text; + + public static String Comments_lable; + + public static String Comments_NoComments_text; + + public static String Command_InsertImage; + public static String DeleteSheet_text; + public static String DeleteSheet_toolTip; + + public static String DeleteSingleRevisionCommand_label; + + public static String DeleteStyleHandler_DeleteStytles; + + public static String DeleteStyleHandler_DeleteStytlesConfirm; + public static String DeleteStyle_MessageDialog_description; + + public static String DeleteStyle_MessageDialog_styles; + + public static String DeleteStyle_MessageDialog_themes; + + public static String DeleteStyles_MessageDialog_title; + + public static String Delete_OtherSheets_text; + public static String Delete_OtherSheets_toolTip; + + public static String DeleteComment_label; + public static String DeleteComment_text; + public static String DeleteComment_tooltip; + + public static String DeleteMultipleRevisionsCommand_label; + public static String DeleteNotes_label; + public static String DeleteNotes_text; + public static String DeleteNotes_tooltip; + public static String DeleteMarker_label; + public static String DrillDown_text; + public static String DrillDown_toolTip; + public static String DrillUp_text; + public static String DrillUp_toolTip; + public static String EditLabel_text; + public static String EditLabel_toolTip; + public static String EditNotes_text; + public static String EditNotes_toolTip; + public static String Edit_text; + public static String Edit_toolTip; + + public static String EditComments_text; + public static String EditTitle_text; + public static String EditTitle_toolTip; + public static String Extend_text; + public static String Extend_toolTip; + public static String ExtendAll_text; + public static String ExtendAll_toolTip; + + public static String FileProtocol_OpenFile_text; + + public static String FileProtocol_OpenFolder_text; + + public static String Finish_text; + public static String Finish_toolTip; + public static String FitMap_text; + public static String FitMap_toolTip; + public static String FitSelection_text; + public static String FitSelection_toolTip; + public static String InsertAttachment_text; + public static String InsertAttachment_toolTip; + public static String InsertBoundary_text; + public static String InsertBoundary_toolTip; + public static String InsertFloatingTopic_text; + public static String InsertFloatingTopic_toolTip; + public static String InsertFloatingCentralTopic_text; + public static String InsertFloatingCentralTopic_toolTip; + public static String InsertImage_text; + public static String InsertImage_toolTip; + public static String InsertParentTopic_text; + public static String InsertParentTopic_toolTip; + public static String InsertRelationship_text; + public static String InsertRelationship_toolTip; + public static String InsertSubtopic_text; + public static String InsertSubtopic_toolTip; + public static String InsertSummary_text; + public static String InsertSummary_toolTip; + public static String InsertTopic_text; + public static String InsertTopic_toolTip; + public static String InsertTopicBefore_text; + public static String InsertTopicBefore_toolTip; + public static String Markers_text; + public static String ModifyHyperlink_text; + public static String ModifyHyperlink_toolTip; + public static String ModifySheetTabColorCommand_label; + public static String ImportWorkbook_text; + public static String ImportWorkbook_toolTip; + + public static String EncryptDialog_title; + public static String EncryteDialog_label_message; + public static String ErrorDetailDialog_ReportProblem; + + public static String ErrorDetailDialog_title; + public static String Finish_button_text; + public static String EncryptDialogPane_board_message; + public static String EncryptDialogPane_assist_message; + public static String EncryptDialogPane_oldpassword_text; + public static String EncryptDialogPane_password_text; + public static String EncryptDialogPane_newpassword_text; + public static String EncryptDialogPane_confirm_text; + public static String EncryptDialogPane_detailsButton_label; + public static String ErrorDeteilDialog_ReportProblemMessage; + + public static String ErrorDialogPane_summaryBoard_text; + public static String LoadWorkbookJob_retrive_password_message; + public static String LoadWorkbookJob_firstTry_message; + public static String LoadWorkbookJob_moreTry_message; + public static String LoadWorkbookJob_text; + public static String LoadWorkbookJob_errorDialog_GoToBackup_message; + + public static String OpenLocalFileHandler_MessageDialog_title; + + public static String LoadWorkbookJob_errorDialog_title; + + public static String LoadWorkbookJob_errorDialog_Pre_message; + + public static String LocalFileWorkbookRef_changeDialog_cancel_button; + + public static String LocalFileWorkbookRef_changeDialog_message; + + public static String LocalFileWorkbookRef_changeDialog_title; + + public static String LocalFileWorkbookRef_changeDialog_update_button; + + public static String LocalFileWorkbookRef_removeDialog_delete_button; + + public static String LocalFileWorkbookRef_removeDialog_message; + + public static String LocalFileWorkbookRef_removeDialog_saveAs_button; + + public static String LocalFileWorkbookRef_removeDialog_title; + + public static String MindMapEditor_CompatibilityWarning_dialogTitle; + + public static String MindMapEditor_CompatibilityWarning_Overwrite_button; + + public static String MindMapEditor_CompatibilityWarning_OverwritingHigherVersion_message; + + public static String MindMapEditor_CompatibilityWarning_SaveAs_button; + + public static String MindMapEditor_fileChangedDialog_message_prefix; + + public static String MindMapEditor_fileRemovedDialog_message_prefix; + + public static String MindMapEditor_partInitException_message; + + public static String MindMapEditor_passwordPrompt_message1; + + public static String MindMapEditor_passwordPrompt_message2; + + public static String MindMapEditorInput_default_name; + + public static String MindMapPropertySheetPage_ResetStyle_text; + + public static String NotesHyperlinkDialog_display_text; + public static String NotesHyperlinkDialog_hyperlinkReference_text; + public static String NotesHyperlinkDialog_title; + + public static String InsertHyperlinkAction_text; + public static String InserthyperlinkAction_toolTip; + public static String NEWSheet_from_text; + public static String NEWSheet_from_toolTip; + + public static String ModifyWrapWidth_toolTip0; + public static String NewSheet_text; + public static String NewSheet_toolTip; + public static String NewSheetFromTemplateDialog_button_Choose; + + public static String NewSheetFromTemplateDialog_NewSheetFromTemplteCommand_label; + + public static String NewSheetFromTemplateDialog_text; + + public static String OpenWorkbook_text; + public static String OpenWorkbook_toolTip; + public static String OpenHomeMap_text; + public static String OpenHomeMap_toolTip; + public static String OpenHomeMap_Error_message; + + public static String OpenHomeMapAction_HomeMapMissingMessage; + + public static String OpenHomeMapAction_LaterOperationButton; + public static String OpenHyperlink_text; + public static String OpenHyperlink_toolTip; + public static String RenameSheet_text; + public static String RenameSheet_toolTip; + public static String ResetPosition_text; + public static String ResetPosition_toolTip; + public static String SelectBrothers_text; + public static String SelectBrothers_toolTip; + public static String SelectChildren_text; + public static String SelectChildren_toolTip; + public static String GoToCentral_text; + public static String GoToCentral_toolTip; + public static String SaveAttachment_text; + public static String SaveAttachment_toolTip; + public static String SaveAsTemplate_text; + public static String SaveAsTemplate_toolTip; + public static String SaveAsTemplateHandler_inputDialog_message; + public static String SaveAsTemplateHandler_inputDialog_title; + + public static String SaveSheetAs_text; + public static String SaveSheetAs_toolTip; + public static String ShowAllComments_text; + + public static String ShowAllComments_tooltip; + + public static String ShowAllNotes_text; + + public static String ShowAllNotes_tooltip; + + public static String ShowWorkbook_text; + public static String ShowWorkbook_toolTip; + public static String ShowSheet_text; + public static String ShowSheet_toolTip; + public static String Structure_text; + public static String Tile_text; + public static String Tile_toolTip; + public static String Traverse_text; + public static String Traverse_toolTip; + public static String ZoomIn_text; + public static String ZoomIn_toolTip; + public static String ZoomOut_text; + public static String ZoomOut_toolTip; + public static String InsertImageFromFile_text; + public static String InsertImageFromFile_toolTip; + public static String MoveUp_text; + public static String MoveUp_toolTip; + public static String MoveDown_text; + public static String MoveDown_toolTip; + public static String MoveLeft_text; + public static String MoveLeft_toolTip; + public static String MoveRight_text; + public static String MoveRight_toolTip; + public static String ShowMarkerManager_text; + public static String ShowMarkerManager_toolTip; + + public static String ShowNextTopicComments_text; + + public static String ShowNextTopicComments_tooltip; + + public static String ShowPreTopicComments_text; + + public static String ShowPreTopicComments_tooltip; + + public static String SortByTitle_text; + public static String SortByTitle_toolTip; + public static String SortByPriority_text; + public static String SortByPriority_toolTip; + public static String SortByModifiedTime_text; + public static String SortByModifiedTime_toolTip; + + public static String ImageDownload_jobName; + + public static String ImportMarkers_text; + public static String ImportMarkers_toolTip; + public static String ExportMarkers_text; + public static String ExportMarkers_toolTip; + public static String AlignLeft_text; + public static String AlignLeft_toolTip; + public static String AlignRight_text; + public static String AlignRight_toolTip; + public static String AlignCenter_text; + public static String AlignCenter_toolTip; + public static String AlignTop_text; + public static String AlignTop_toolTip; + public static String AlignBottom_text; + public static String AlignBottom_toolTip; + public static String AlignMiddle_text; + public static String AlignMiddle_toolTip; + + public static String AllMarkersMenu_Markers_More_text; + + public static String AllMarkersMenu_Markers_tooltip; + + public static String AllowOverlaps_text; + + public static String AllowOverlaps_toolTip; + + public static String AllowManualLayout_text; + + public static String AllowManualLayout_toolTip; + + public static String BackgroundWorkbookSaver_SaveWorkbook_taskName; + + public static String BackgroundWorkbookSaver_SavingWorkbook_taskNamePattern; + + public static String BreadCrumb_CurrentCentral_text; + + public static String BreadCrumb_ViewAsCentral_text; + + public static String DownloadImageJob_pattern; + + public static String MarkerView_XMindMarkers_label; + public static String MarkerView_UntitledGroup_name; + + public static String MarkerView_UserMarkers_label; + public static String MarkerView_RecentlyUsed_label; + + public static String StylePropertySectionPart_ShowStyleEditorDialogButton_text; + + public static String StylePropertySectionPart_text; + + public static String StylePropertySectionPart_tooltip; + + public static String StylesViewer_Topic_label; + public static String StylesViewer_Boundary_label; + public static String StylesViewer_Relationship_label; + public static String StylesViewer_Map_label; + public static String StylesViewer_Summary_label; + + public static String ThemesView_LinkWithEditor_text; + public static String ThemesView_LinkWithEditor_toolTip; + + public static String DefaultThemeAction_text; + public static String DefaultThemeAction_toolTip; + + public static String ThemeLabel_LoadTheme; + + public static String ThemeUICore_group_default_name; + + public static String ThemeUICore_group_user_name; + + public static String DefaultTheme_title; + + public static String Legend; + + public static String MarkerParameterNamePattern; + + public static String RecentUsed; + + public static String RevertToRevisionCommand_label; + + public static String RevisionsView_DateColumn_text; + + public static String RevisionsView_DeleteRevisionsAction_text; + + public static String RevisionsView_DeleteRevisionsAction_toolTip; + + public static String RevisionsView_PreviewAction_text; + + public static String RevisionsView_PreviewAction_toolTip; + + public static String RevisionsView_RevertToRevisionAction_text; + + public static String RevisionsView_RevertToRevisionAction_toolTip; + + public static String RevisionsView_TimeColumn_text; + + public static String RevisionPage_ShowDetails_message; + + public static String RevisionView_DateTimeColumn_text; + + public static String RevisionView_VersionColumn_text; + + public static String DefaultOverviewPage_message; + public static String DefaultRevisionsPage_message; + + public static String TryPro_text; + public static String TryPro_toolTip; +// public static String TryPro_UpdateSourceDialog_title; +// public static String TryPro_UpdateSourceDialog_label; +// public static String TryPro_UpdateSourceDialog_Online; +// public static String TryPro_UpdateSourceDialog_LocalFile; +// public static String TryPro_UpdateSourceDialog_jobName; +// public static String TryPro_ErrorDialog_title; +// public static String TryPro_ErrorDialog_message; +// public static String TryPro_InstallDialog_title; + + public static String WorkbookEditorInput_name; + + public static String WorkbookFilterName; + + public static String WorkbookHistoryItem_FileMissingMessage; + + public static String WorkbookImportWizard_ImportWorkbook_Title; + + public static String WorkbookImportWizard_ImportXmindMap_Title; + + public static String WorkbookImportWizard_NeedSaveWorkbookMessage; + + public static String WorkbookImportWizard_NoTargetWorkbookMessage; + + public static String WorkbookSavedIncorrectly_error; + + public static String WorkbookSaver_CreateRevisions_taskName; + + public static String WorkbookSaver_Finalize_taskName; + + public static String WorkbookSaver_PrepareNewSaveTarget_taskName; + + public static String WorkbookSaver_SavePreviewImage_taskName; + + public static String WorkbookSaver_SaveWorkbookContent_taskName; + + public static String FileStoreWorkbookAdapter_FailedToSaveWorkbook_error; + + public static String EditInCommentsView_text; + + public static String EditInCommentsView_tooltip; + + public static String EditInNotesView_text; + public static String EditInNotesView_toolTip; + + public static String OpenAttachment_text; + + public static String NotesView_InsertImage_toolTip; +// public static String NotesView_UndoTyping_text; +// public static String NotesView_UndoTyping_toolTip; +// public static String NotesView_RedoTyping_text; +// public static String NotesView_RedoTyping_toolTip; + + public static String ProtocolManager_OpenHyperlink_pattern; + + public static String WordContext_Label_pattern; + public static String WordContext_Notes_pattern; + + public static String Notes_FindReplaceContextPattern; + public static String EmptyNotes_FindReplaceContextName; + + public static String ReopenWorkbookMenu_text; + public static String ReopenWorkbookMenu_NoItemsPlaceholder_text; + public static String ReopenWorkbookMenu_toolTip; + public static String ReopenWorkbookMenu_ClearListAction_text; + + public static String SaveNewRevision_text; + public static String SaveNewRevision_tooltip; + + public static String SaveWizardDialog_location_text; + + public static String SaveWizardDialog_name_text; + + public static String SaveWizardDialog_okButton_text; + + public static String SaveWizardDialog_shell_title; + + public static String SaveWorkbookAsHandler_doneDialog_cancelButton_text; + + public static String SaveWorkbookAsHandler_doneDialog_message; + + public static String SaveWorkbookAsHandler_doneDialog_okButton_text; + + public static String SaveWorkbookAsHandler_doneDialog_title; + + public static String SaveWorkbookAsHandler_oldName_default; + + public static String SaveWorkbookAsHandler_saveAsDialog_description; + + public static String SaveWorkbookAsHandler_saveAsDialog_title; + + public static String SaveWorkbookAsHandler_warningDialog_description; + + public static String SaveWorkbookAsHandler_warningDialog_title; + + public static String SaveWorkbookAsHandler_saveToOtherDialog_title; + + public static String SaveWorkbookAsHandler_saveToOtherDialog_saveTo_text; + + public static String SaveWorkbookAsHandler_saveToOtherDialog_saveToAnother_text; + + public static String WorkbookRevisionsPage_AutoSaveRevisionsCheck_text; + + public static String DuplicateSheet_text; + public static String DuplicateSheet_toolTip; + public static String CopySheet_text; + public static String PasteSheet_text; + + public static String PasswordProvider_askPassword_message; + + public static String RemoveAllStyles_text; + public static String RemoveAllStyles_tooltip; + + public static String InfoItem_Modify_text; + public static String InfoItem_Delete_text; + public static String InfoItem_SaveAttachment_text; + + public static String Notes_Edit_text; + public static String Notes_Delete_text; + + public static String MultipagePrint_Printing; + public static String MultipagePrint_InvalidMargin_title; + public static String MultipagePrint_InvalidMargin_message; + + public static String MultipageSetupDialog_GeneratePreview; + public static String MultipageSetupDialog_GeneratingPreview; + public static String MultipageSetupDialog_GeneratedPreview; + public static String MultipageSetupDialog_FaildGenerate; + public static String MultipageSetupDialog_PrintDirectly; + public static String MultipageSetupDialog_ImageTooLarge; + public static String MultipageSetupDialog_Content; + public static String MultipageSetupDialog_PageSetup; + public static String MultipageSetupDialog_Collapse_Expand; + public static String MultipageSetupDialog_Orientation; + public static String MultipageSetupDialog_Margin; + public static String MultipageSetupDialog_Header; + public static String MultipageSetupDialog_Footer; + public static String MultipageSetupDialog_Pages; + public static String MultipageSetupDialog_SinglePage; + public static String MultipageSetupDialog_MultiplePages; + public static String MultipageSetupDialog_OptimalPagingEffect; + public static String MultipageSetupDialog_Horizontal; + public static String MultipageSetupDialog_Vertical; + public static String MultipageSetupDialog_ShowDetails; + public static String MultipageSetupDialog_HideDetails; + public static String MultipageSetupDialog_showPlusCheck_text; + public static String MultipageSetupDialog_showMinusCheck_text; + + public static String WorkbookMetadata_ModifyAuthorInfo; + + public static String EditorHistoryItem_defaultName; + + public static String SheetCommentViewer_Insert_button; + public static String SheetCommentViewer_Insert_hyperlink; + + public static String BlackBoxDialog_title; + + public static String ProgressDialog_NullContet_message; + public static String ProgressDialog_ShowSystem_check; + public static String ProgressDialog_RemoveAll_hyperlink; + + public static String WorkbookMetaInspectorDialog_message; + + public static String WorkbookRevisionDialog_title; + public static String WorkbookRevisionDialog_Disable_hyperlink; + + public static String LocalImageModelPage_title; + public static String LocalImageModelPage_ImageSection_description; + public static String LocalImageModelPage_Insert_button; + + public static String DecryptionDialog_title; + public static String DecryptionDialog_message; + public static String DecryptionDialog_FileName_label; + public static String DecryptionDialog_FileName_untitled; + public static String DecryptionDialog_Password_label; + public static String DecryptionDialog_WarningLabel_text; + public static String DecryptionDialog_Hint_label; + + public static String EncrptionDialog_ChangePassword_title; + public static String EncryptionDialog_SetPassword_title; + public static String EncryptionDialog_ChangePassword_message; + public static String EncryptionDialog_SetPassword_message; + public static String EncryptionDialog_ButtonBar_Set_button; + public static String EncryptionDialog_HintInput_label; + public static String EncryptionDialog_Warning_NotMatch_label; + public static String EncryptionDialog_Warning_NotCorrect_label; + + public static String MindMapEditor_Warning_FileNotFoundDialog_title; + + public static String MindMapEditorInput_Workbook_Untitled_title; + + public static String OverviewCheck_Overview_ON; + public static String OverviewCheck_Overview_OFF; + + public static String OutlineIndexPart_ShowWorkbookAction_text; + public static String OutlineIndexPart_ShowWorkbookAction_toolTip; + public static String OutlineIndexPart_ShowCurrentSheetAction_text; + public static String OutlineIndexPart_ShowCurrentSheetAction_toolTip; + public static String OutlineIndexPart_DefaultPage_message; + + public static String OutlineType_None; + public static String OutlineType_Markers; + public static String OutlineType_Labels; + public static String OutlineType_StartDate; + public static String OutlineType_EndDate; + public static String OutlineType_Assignee; + + public static String OutlineViewer_StartDate_col; + public static String OutlineViewer_EndData_col; + public static String OutlineViewer_Task_col; + + public static String ThemePrefPage_ThemeEditor_label; + + public static String NumberingProperty_NumberDepthLabelProvider_Inherit_text; + public static String NumberingProperty_NumberDepthLabelProvider_Levels_text; + public static String NumberingProperty_TieredCheck_text; + + public static String PropertiesPart_DefaultPage_message; + + public static String MarkerResourceManagerViewer_AddSection_title; + + public static String ResourceManagerPart_title; + public static String ResourceManagerPart_message; + + public static String StyleResourceManager_Editor_button; + + public static String StyleResourceManagerViewer_Topic; + public static String StyleResourceManagerViewer_Boundary; + public static String StyleResourceManagerViewer_Map; + public static String StyleResourceManagerViewer_Paragraph; + public static String StyleResourceManagerViewer_Relationship; + public static String StyleResourceManagerViewer_Summary; + public static String StyleResourceManagerViewer_Text; + public static String StyleResourceManagerViewer_Theme; + public static String StyleResourceManagerViewer_AddSection_title; + + public static String TemplateResourceManagerPage_Import_button; + public static String TemplateResourceManagerPage_Delete_ConfirmDialog_title; + public static String TemplateResourceManagerPage_Delete_ConfirmDialog_message; + public static String TemplateResourceManagerPage_AddTemplates_label; + public static String TemplateResourceManagerPage_TemplateFilterName_label; + public static String TemplateResourceManagerPage_AddTemplates_tooltip; + + public static String TemplateResourceManagerViewer_SystemGroup_name; + public static String TemplateResourceManagerViewer_UserGroup_name; + + public static String ThemeResourceManagerPage_New_button; + public static String ThemeResourceManagerPage_Edit_button; + + public static String ResourceUtil_Copy_name; + public static String ResourceUtil_Duplicate_name; + + public static String ThemeGroupCore_UserGroup_name; + public static String ThemeGroupCore_DefaultGroup_name; + + public static String ExportPage_Categore_Recent_name; + + public static String MarkerResourceManagerPage_AddGroup; + + public static String MarkerResourceManagerPage_UserGroup; + + public static String FileNotExistDialog_Title; + public static String FileNotExistDialog_Message; + + public static String CloudFileNotExistDialog_Title; + public static String CloudFileNotExistDialog_Message; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MindMapMessages.class); + } + + private MindMapMessages() { + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapResourceManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapResourceManager.java index 697f605db..d8ee7319f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapResourceManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapResourceManager.java @@ -1,1429 +1,1429 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - -import javax.imageio.ImageIO; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.PlatformUI; -import org.osgi.framework.Bundle; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xmind.core.Core; -import org.xmind.core.IAdaptable; -import org.xmind.core.IDeserializer; -import org.xmind.core.IManifest; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.MarkerGroup; -import org.xmind.core.internal.MarkerVariation; -import org.xmind.core.internal.dom.StyleSheetImpl; -import org.xmind.core.internal.event.CoreEventSupport; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.io.BundleResource; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.io.DirectoryOutputTarget; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.marker.AbstractMarkerResource; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerResource; -import org.xmind.core.marker.IMarkerResourceAllocator; -import org.xmind.core.marker.IMarkerResourceProvider; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.marker.IMarkerVariation; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.IPropertiesProvider; -import org.xmind.ui.mindmap.IResourceManager; -import org.xmind.ui.mindmap.IResourceManagerListener; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.ITemplateGroup; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.util.Logger; -import org.xmind.ui.util.ResourceFinder; - -public class MindMapResourceManager implements IResourceManager { - - private static final String DEFAULT_THEME_ID = "xminddefaultthemeid"; //$NON-NLS-1$ - - private static final String PATH_MARKERS = "markers/"; //$NON-NLS-1$ - - private static final String PATH_USER_MARKERS = "markers/"; //$NON-NLS-1$ - - private static final String PATH_STYLES = "styles/"; //$NON-NLS-1$ - - private static final String PATH_STYLES_DIR = "$nl$/styles/"; //$NON-NLS-1$ - - private static final String PATH_USER_STYLES = PATH_STYLES + "userStyles/"; //$NON-NLS-1$ - - private static final String PATH_USER_THEMES = PATH_STYLES + "userThemes/"; //$NON-NLS-1$ - - private static final String MARKER_SHEET_XML = "markerSheet.xml"; //$NON-NLS-1$ - - private static final String MARKER_SHEET = "markerSheet"; //$NON-NLS-1$ - - private static final String DEFAULT_STYLES_XML = "defaultStyles.xml"; //$NON-NLS-1$ - - private static final String STYLES = "styles"; //$NON-NLS-1$ - - private static final String THEMES = "themes"; //$NON-NLS-1$ - - private static final String EXT_PROPERTIES = ".properties"; //$NON-NLS-1$ - - private static final String EXT_XML = ".xml"; //$NON-NLS-1$ - - private static final String SYS_TEMPLATES_DIR = "$nl$/templates/"; //$NON-NLS-1$ - - private static final String SYS_TEMPLATES_XML_PATH = SYS_TEMPLATES_DIR - + "templates.xml"; //$NON-NLS-1$ - - private static final String USER_TEMPLATES_DIR = "templates/"; //$NON-NLS-1$ - - private static class SystemMarkerResourceProvider - implements IMarkerResourceProvider { - - public IMarkerResource getMarkerResource(IMarker marker) { - return new SystemMarkerResource(marker); - } - - public boolean isPermanent() { - return true; - } - - } - - private static class SystemMarkerResource extends AbstractMarkerResource { - - public SystemMarkerResource(IMarker marker) { - super(marker, PATH_MARKERS); - } - - public InputStream getInputStream() { - return getInputStreamForPath(getFullPath(), 100); - } - - @Override - public InputStream openInputStream(int zoom) throws IOException { - return getInputStreamForPath(getFullPath(), zoom); - } - - @Override - public InputStream openInputStream(IMarkerVariation variation, int zoom) - throws IOException { - return getInputStreamForPath(variation.getVariedPath(getFullPath()), - zoom); - } - - private InputStream getInputStreamForPath(String fullPath, int zoom) { - String xfullPath = getxPath(fullPath, zoom); - URL url = find(xfullPath); - if (url == null) - url = find(fullPath); - - if (url == null) - return null; - - try { - return url.openStream(); - } catch (IOException e) { - } - return null; - } - - private String getxPath(String path, int zoom) { - int dot = path.lastIndexOf('.'); - if (dot != -1 && zoom > 100) { - String lead = path.substring(0, dot); - String tail = path.substring(dot); - String x = "@2x"; //$NON-NLS-1$ - return lead + x + tail; - } - return path; - } - - public OutputStream getOutputStream() { - return null; - } - - public InputStream openInputStream() throws IOException { - URL url = find(getFullPath()); - if (url == null) - throw new FileNotFoundException(getFullPath()); - return url.openStream(); - } - - public OutputStream openOutputStream() throws IOException { - throw new FileNotFoundException("System marker is read only."); //$NON-NLS-1$ - } - - @Override - protected void loadVariations(List variations) { - - IMarkerVariation v = new MarkerVariation("@16", 16, 16); //$NON-NLS-1$ - if (find(v.getVariedPath(getFullPath())) != null) - variations.add(v); - - v = new MarkerVariation("@24", 24, 24); //$NON-NLS-1$ - if (find(v.getVariedPath(getFullPath())) != null) - variations.add(v); - - v = new MarkerVariation("@32", 32, 32); //$NON-NLS-1$ - if (find(v.getVariedPath(getFullPath())) != null) - variations.add(v); - } - - @Override - public InputStream getInputStream(IMarkerVariation variation) { - return getInputStreamForPath(variation.getVariedPath(getFullPath()), - 100); - } - - @Override - public InputStream openInputStream(IMarkerVariation variation) - throws IOException { - InputStream stream = getInputStreamForPath( - variation.getVariedPath(getFullPath()), 100); - if (stream == null) - throw new FileNotFoundException(); - return stream; - } - - @Override - public OutputStream getOutputStream(IMarkerVariation variation) { - return null; - } - - @Override - public OutputStream openOutputStream(IMarkerVariation variation) - throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof SystemMarkerResource)) - return false; - return super.equals(obj); - } - } - - private static class UserMarkerResourceProvider - implements IMarkerResourceProvider, IMarkerResourceAllocator { - - public IMarkerResource getMarkerResource(IMarker marker) { - return new UserMarkerResource(marker); - } - - public boolean isPermanent() { - return false; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerResourceAllocator# - * allocateMarkerResourcePath(java.io.InputStream, java.lang.String) - */ - @Override - public String allocateMarkerResource(InputStream source, - String suggestedPath) throws IOException { - String ext = suggestedPath == null ? ".png" //$NON-NLS-1$ - : FileUtils.getExtension(suggestedPath); - String path = Core.getIdFactory().createId() + ext; - File file = new File(Core.getWorkspace() - .getAbsolutePath(PATH_USER_MARKERS + path)); - FileUtils.ensureFileParent(file); - OutputStream target = new FileOutputStream(file); - try { - FileUtils.transfer(source, target, false); - } finally { - target.close(); - } - return path; - } - - } - - private static class UserMarkerResource extends AbstractMarkerResource { - - private final String JPG_FORMAT = "jpg"; //$NON-NLS-1$ - private final String JPEG_FORMAT = "jpeg"; //$NON-NLS-1$ - private final String PNG_FORMAT = "png"; //$NON-NLS-1$ - - public UserMarkerResource(IMarker marker) { - super(marker, PATH_USER_MARKERS); - } - - private File getFile() { - File origin = FileUtils.ensureFileParent(new File( - Core.getWorkspace().getAbsolutePath(getFullPath()))); - String lowerFullPath = getFullPath().toLowerCase(); - if (lowerFullPath.endsWith(JPEG_FORMAT) - || lowerFullPath.endsWith(JPG_FORMAT)) { - try { - String jpg = Core.getWorkspace() - .getAbsolutePath(getFullPath()); - BufferedImage source = ImageIO.read(new File(jpg)); - String png = jpg.substring(0, jpg.lastIndexOf('.') - 1) - + PNG_FORMAT; - File pngFile = new File(png); - ImageIO.write(source, PNG_FORMAT, pngFile); - return pngFile; - } catch (Exception e) { - } - } - - return origin; - } - - public InputStream getInputStream() { - File file = getFile(); - if (file != null) - try { - return new FileInputStream(file); - } catch (FileNotFoundException e) { - } - return null; - } - - public OutputStream getOutputStream() { - File file = getFile(); - if (file != null) - try { - return new FileOutputStream(file); - } catch (FileNotFoundException e) { - } - return null; - } - - public InputStream openInputStream() throws IOException { - return new FileInputStream(getFile()); - } - - public OutputStream openOutputStream() throws IOException { - return new FileOutputStream(getFile()); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof UserMarkerResource)) - return false; - return super.equals(obj); - } - - } - - protected static class RecentMarkerGroup extends MarkerGroup - implements ICoreEventSource { - - public static final RecentMarkerGroup instance = new RecentMarkerGroup(); - - private static final int CAPACITY = 20; - - private List markers = new ArrayList(CAPACITY); - - private ICoreEventSupport eventSupport = new CoreEventSupport(); - - private RecentMarkerGroup() { - } - - public void addMarker(IMarker marker) { - if (markers.contains(marker)) - return; - - while (markers.size() >= CAPACITY) { - markers.remove(markers.size() - 1); - } - markers.add(0, marker); - eventSupport.dispatchTargetChange(this, Core.MarkerAdd, marker); - } - - public T getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return adapter.cast(this); - return super.getAdapter(adapter); - } - - public List getMarkers() { - return markers; - } - - /* - * (non-Javadoc) - * @see org.xmind.core.marker.IMarkerGroup#isEmpty() - */ - @Override - public boolean isEmpty() { - return markers.isEmpty(); - } - - public String getName() { - return MindMapMessages.RecentUsed; - } - - public void setSingleton(boolean singleton) { - } - - public IMarkerSheet getOwnedSheet() { - return null; - } - - public IMarkerSheet getParent() { - return null; - } - - public boolean isSingleton() { - return false; - } - - public boolean isHidden() { - return false; - } - - public void setHidden(boolean hidden) { - - } - - public void removeMarker(IMarker marker) { - if (!markers.contains(marker)) - return; - markers.remove(marker); - eventSupport.dispatchTargetChange(this, Core.MarkerRemove, marker); - } - - public void setName(String name) { - } - - public String getId() { - return "org.xmind.ui.RecentMarkerGroup"; //$NON-NLS-1$ - } - - public Object getRegisterKey() { - return getId(); - } - - public ICoreEventRegistration registerCoreEventListener(String type, - ICoreEventListener listener) { - return eventSupport.registerCoreEventListener(this, type, listener); - } - - public int hashCode() { - return super.hashCode(); - } - - public ICoreEventSupport getCoreEventSupport() { - return eventSupport; - } - - } - - private IMarkerSheet systemMarkerSheet = null; - - private IMarkerSheet userMarkerSheet = null; - - private IMarkerGroup recentMarkerGroup = null; - - private IStyleSheet defaultStyleSheet = null; - - private IStyleSheet systemStyleSheet = null; - - private IWorkbook userStylesContainer = null; - - private IStyle blankTheme = null; - - private IStyle defaultTheme = null; - - private IStyleSheet systemThemeSheet = null; - - private IWorkbook userThemesContainer = null; - - private ITemplate defaultTemplate; - - private ListenerList resourceManagerListeners = new ListenerList(); - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.IMarkerSheetManager#getSystemMarkerSheet() - */ - public IMarkerSheet getSystemMarkerSheet() { - if (systemMarkerSheet == null) { - systemMarkerSheet = createSystemMarkerShet(); - } - return systemMarkerSheet; - } - - private IMarkerSheet createSystemMarkerShet() { - URL url = find(PATH_MARKERS, MARKER_SHEET_XML); - if (url != null) { - try { - IMarkerSheet sheet = Core.getMarkerSheetBuilder() - .loadFromURL(url, new SystemMarkerResourceProvider()); - loadPropertiesFor(sheet, PATH_MARKERS, MARKER_SHEET); - return sheet; - } catch (Exception e) { - Logger.log(e, "Failed to load system marker from: " + url); //$NON-NLS-1$ - } - } - return Core.getMarkerSheetBuilder() - .createMarkerSheet(new SystemMarkerResourceProvider()); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.IMarkerSheetManager#getUserMarkerSheet() - */ - public IMarkerSheet getUserMarkerSheet() { - if (userMarkerSheet == null) { - userMarkerSheet = createUserMarkerSheet(); - initUserMarkerSheet(userMarkerSheet); - } - return userMarkerSheet; - } - - public void saveUserMarkerSheet() { - if (userMarkerSheet != null) { - String path = Core.getWorkspace() - .getAbsolutePath(PATH_USER_MARKERS + MARKER_SHEET_XML); - File file = FileUtils.ensureFileParent(new File(path)); - FileOutputStream out = null; - try { - out = new FileOutputStream(file); - userMarkerSheet.save(out); - } catch (Exception e) { - Logger.log(e); - } finally { - if (out != null) - try { - out.close(); - } catch (IOException e) { - Logger.log(e); - } - } - } - } - - private void initUserMarkerSheet(IMarkerSheet sheet) { - sheet.setParentSheet(getSystemMarkerSheet()); - } - - private IMarkerSheet createUserMarkerSheet() { - String path = Core.getWorkspace() - .getAbsolutePath(PATH_USER_MARKERS + MARKER_SHEET_XML); - if (path != null) { - File file = new File(path); - if (file.exists()) { - try { - return Core.getMarkerSheetBuilder().loadFromFile(file, - new UserMarkerResourceProvider()); - } catch (Exception e) { - Logger.log(e, "Failed to load user marker from: " + file); //$NON-NLS-1$ - } - } - } - return Core.getMarkerSheetBuilder() - .createMarkerSheet(new UserMarkerResourceProvider()); - } - - public IMarkerGroup getRecentMarkerGroup() { - if (recentMarkerGroup == null) { - recentMarkerGroup = new RecentMarkerGroup(); - } - return recentMarkerGroup; - } - - public IStyleSheet getDefaultStyleSheet() { - if (defaultStyleSheet == null) { - defaultStyleSheet = createDefaultStyleSheet(); - } - return defaultStyleSheet; - } - - private IStyleSheet createDefaultStyleSheet() { - URL url = find(PATH_STYLES, DEFAULT_STYLES_XML); - if (url != null) { - try { - return Core.getStyleSheetBuilder().loadFromUrl(url); - } catch (Exception e) { - Logger.log(e, "Failed to load default styles: " + url); //$NON-NLS-1$ - } - } - return Core.getStyleSheetBuilder().createStyleSheet(); - } - - public IStyleSheet getSystemStyleSheet() { - if (systemStyleSheet == null) { - systemStyleSheet = createSystemStyleSheet(); - IManifest manifest = Core.getWorkbookBuilder().createWorkbook() - .getManifest(); - ((StyleSheetImpl) systemStyleSheet).setManifest(manifest); - } - return systemStyleSheet; - } - - private IStyleSheet createSystemStyleSheet() { - URL url = find(PATH_STYLES, STYLES, EXT_XML); - if (url != null) { - try { - IStyleSheet sheet = Core.getStyleSheetBuilder() - .loadFromUrl(url); - loadPropertiesFor(sheet, PATH_STYLES, STYLES); - return sheet; - } catch (Exception e) { - Logger.log(e, "Falied to load saved styles: " + url); //$NON-NLS-1$ - } - } - return Core.getStyleSheetBuilder().createStyleSheet(); - } - - public IStyleSheet getUserStyleSheet() { - if (userStylesContainer == null) { - userStylesContainer = loadResourceContainer(PATH_USER_STYLES); - } - return userStylesContainer.getStyleSheet(); - } - - public void saveUserStyleSheet() { - saveResourceContainer(userStylesContainer, PATH_USER_STYLES); - } - - public IStyle getBlankTheme() { - if (blankTheme == null) { - blankTheme = Core.getStyleSheetBuilder().createStyleSheet() - .createStyle(IStyle.THEME); - blankTheme.setName(MindMapMessages.DefaultTheme_title); - } - return blankTheme; - } - - public IStyle getDefaultTheme() { - if (defaultTheme == null) { - defaultTheme = findDefaultTheme(); - } - return checkDefaultTheme(defaultTheme); - } - - private IStyle checkDefaultTheme(IStyle defaultTheme) { - String defaultId = defaultTheme.getId(); - boolean exist = getSystemThemeSheet().findStyle(defaultId) != null - || getUserThemeSheet().findStyle(defaultId) != null - || getBlankTheme().getId().equals(defaultId); - return exist ? defaultTheme - : getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); - - } - - private IStyle findDefaultTheme() { - if (Platform.isRunning()) { - String defaultId = MindMapUIPlugin.getDefault().getPreferenceStore() - .getString(PrefConstants.DEFUALT_THEME); - if (defaultId != null && !"".equals(defaultId)) { //$NON-NLS-1$ - IStyle theme = getSystemThemeSheet().findStyle(defaultId); - if (theme == null) { -// theme = getUserStyleSheet().findStyle(defaultId); - theme = getUserThemeSheet().findStyle(defaultId); - } - if (theme == null && defaultId.equals(getBlankTheme().getId())) - theme = getBlankTheme(); - - if (theme != null) - return theme; - } - } - return getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); - } - - public void setDefaultTheme(String id) { - IStyle theme = null; - if (id != null && !"".equals(id)) { //$NON-NLS-1$ - theme = getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); - if (!id.equals(theme.getId())) { - theme = getSystemThemeSheet().findStyle(id); - if (theme == null) { - theme = getUserThemeSheet().findStyle(id); - } - if (theme == null && id.equals(getBlankTheme().getId())) { - theme = getBlankTheme(); - } - } - } - if (theme == null) - id = null; - - this.defaultTheme = theme; - MindMapUIPlugin.getDefault().getPreferenceStore() - .setValue(PrefConstants.DEFUALT_THEME, id); - } - - public IStyleSheet getSystemThemeSheet() { - if (systemThemeSheet == null) { - systemThemeSheet = createSystemThemeSheet(); - IManifest manifest = Core.getWorkbookBuilder().createWorkbook() - .getManifest(); - ((StyleSheetImpl) systemThemeSheet).setManifest(manifest); - } - return systemThemeSheet; - } - - private IStyleSheet createSystemThemeSheet() { -// URL url = find(PATH_STYLES, THEMES_XML); - URL url = find(PATH_STYLES_DIR, THEMES, EXT_XML); - if (url != null) { - try { - IStyleSheet sheet = Core.getStyleSheetBuilder() - .loadFromUrl(url); - loadPropertiesFor(sheet, PATH_STYLES, THEMES); - return sheet; - } catch (Exception e) { - Logger.log(e, "Falied to load system themes: " + url); //$NON-NLS-1$ - } - } - return Core.getStyleSheetBuilder().createStyleSheet(); - } - - public IStyleSheet getUserThemeSheet() { - if (userThemesContainer == null) { - userThemesContainer = loadResourceContainer(PATH_USER_THEMES); - } - return userThemesContainer.getStyleSheet(); - } - - public void saveUserThemeSheet() { - saveResourceContainer(userThemesContainer, PATH_USER_THEMES); - } - - /** - * @param sourcePath - * @return - */ - private static IWorkbook loadResourceContainer(String sourcePath) { - IWorkbook container = null; - File file = new File(Core.getWorkspace().getAbsolutePath(sourcePath)); - File tempLoc = new File(Core.getWorkspace().getTempDir(sourcePath)); - FileUtils.ensureDirectory(tempLoc); - DirectoryStorage tempStorage = new DirectoryStorage(tempLoc); - - if (file.exists() && file.isDirectory() - && new File(file, ArchiveConstants.CONTENT_XML).exists()) { - try { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setWorkbookStorage(tempStorage); - deserializer.setInputSource(new DirectoryInputSource(file)); - deserializer.deserialize(null); - container = deserializer.getWorkbook(); - } catch (Exception e) { - Logger.log(e, "Failed to load user styles from: " + file); //$NON-NLS-1$ - } - } - if (container == null) { - container = Core.getWorkbookBuilder().createWorkbook(tempStorage); - } - return container; - } - - private static void saveResourceContainer(IWorkbook workbook, - String targetPath) { - if (workbook == null) - return; - - File file = new File(Core.getWorkspace().getAbsolutePath(targetPath)); - FileUtils.ensureDirectory(file); - try { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setOutputTarget(new DirectoryOutputTarget(file)); - serializer.serialize(null); - } catch (Exception e) { - Logger.log(e); - } - } - - private static URL find(String fullPath) { - Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); - if (bundle != null) { - return FileLocator.find(bundle, new Path(fullPath), null); - } - return null; - } - - private static URL find(String mainPath, String subPath) { - return find(mainPath + subPath); - } - - private static URL find(String mainPath, String prefix, String suffix) { - return ResourceFinder.findResource(MindMapUI.PLUGIN_ID, mainPath, - prefix, suffix); - } - - private static void loadPropertiesFor(IAdaptable resourceManager, - String mainPath, String propertiesFilePrefix) { - IPropertiesProvider propertiesProvider = (IPropertiesProvider) resourceManager - .getAdapter(IPropertiesProvider.class); - if (propertiesProvider == null) - return; - - Properties defaultProperties = new Properties(); - URL defaultPropertiesURL = FileLocator.find( - Platform.getBundle(MindMapUI.PLUGIN_ID), - new Path(mainPath + propertiesFilePrefix + EXT_PROPERTIES), - null); - if (defaultPropertiesURL != null) { - try { - InputStream stream = defaultPropertiesURL.openStream(); - try { - defaultProperties.load(stream); - } finally { - stream.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to load default properties file from: " //$NON-NLS-1$ - + mainPath + propertiesFilePrefix + EXT_PROPERTIES); - } - } - - Properties properties = new Properties(defaultProperties); - URL propertiesURL = find(mainPath, propertiesFilePrefix, - EXT_PROPERTIES); - if (propertiesURL != null) { - try { - InputStream stream = propertiesURL.openStream(); - try { - properties.load(stream); - } finally { - stream.close(); - } - } catch (IOException e) { - Logger.log(e, - "Failed to load locale-specific properties file from: " //$NON-NLS-1$ - + mainPath + propertiesFilePrefix - + EXT_PROPERTIES); - } - } - - propertiesProvider.setProperties(properties); - } - - private static final String SCHEMA_MARKER = "marker"; //$NON-NLS-1$ - private static final String SCHEMA_STYLE = "style"; //$NON-NLS-1$ - private static final String SCHEMA_THEME = "theme"; //$NON-NLS-1$ - private static final String CATEGORY_SYSTEM = "system"; //$NON-NLS-1$ - private static final String CATEGORY_USER = "user"; //$NON-NLS-1$ - private static final String CATEGORY_DEFAULT = "default"; //$NON-NLS-1$ - private static final String GROUP_ANY = "any"; //$NON-NLS-1$ - private static final String ID_BLANK = "blank"; //$NON-NLS-1$ - private static final String ID_DEFAULT = "__default__"; //$NON-NLS-1$ - - /* - * (non-Javadoc) - * @see org.xmind.ui.mindmap.IResourceManager#findResource(java.lang.String) - */ - public Object findResource(String uri) { - if (uri == null) - return null; - - int sep = uri.indexOf(':'); - if (sep < 0) - return null; - - String schema = uri.substring(0, sep); - String path = uri.substring(sep + 1); - String[] segments = path.split("/"); //$NON-NLS-1$ - if (segments.length == 0) - // Not possible to happen: - return null; - - String category = segments[0]; - if (SCHEMA_MARKER.equals(schema)) { - // marker: - IMarkerSheet markerSheet = findMarkerSheet(category); - if (markerSheet == null || segments.length == 1) - return markerSheet; - String groupId = segments[1]; - boolean anyGroup = GROUP_ANY.equals(groupId); - IMarkerGroup markerGroup = anyGroup ? null - : markerSheet.findMarkerGroup(groupId); - if (segments.length == 2) - return markerGroup; - String markerId = segments[2]; - if (markerGroup == null) - return anyGroup ? markerSheet.findMarker(markerId) : null; - return markerGroup.getMarker(markerId); - } else if (SCHEMA_STYLE.equals(schema)) { - // style: - IStyleSheet styleSheet = findStyleSheet(category); - if (styleSheet == null || segments.length == 1) - return styleSheet; - String styleId = segments[1]; - return styleSheet.findStyle(styleId); - } else if (SCHEMA_THEME.equals(schema)) { - // theme: - IStyleSheet themeSheet = findThemeSheet(category); - if (themeSheet == null || segments.length == 1) - return themeSheet; - String styleId = segments[1]; - if (themeSheet == getSystemThemeSheet()) { - if (ID_BLANK.equals(styleId)) - return getBlankTheme(); - if (ID_DEFAULT.equals(styleId)) - return getDefaultTheme(); - } - return themeSheet.findStyle(styleId); - } - - return null; - } - - private IMarkerSheet findMarkerSheet(String category) { - if (CATEGORY_SYSTEM.equals(category)) { - return getSystemMarkerSheet(); - } else if (CATEGORY_USER.equals(category)) { - return getUserMarkerSheet(); - } else { - return null; - } - } - - private IStyleSheet findStyleSheet(String category) { - if (CATEGORY_DEFAULT.equals(category)) - return getDefaultStyleSheet(); - if (CATEGORY_SYSTEM.equals(category)) - return getSystemStyleSheet(); - if (CATEGORY_USER.equals(category)) - return getUserStyleSheet(); - return null; - } - - private IStyleSheet findThemeSheet(String category) { - if (CATEGORY_SYSTEM.equals(category)) - return getSystemThemeSheet(); - if (CATEGORY_USER.equals(category)) - return getUserThemeSheet(); - return null; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.mindmap.IResourceManager#toResourceURI(java.lang.Object) - */ - public String toResourceURI(Object resource) { - if (resource instanceof IMarkerSheet) { - if (resource == getSystemMarkerSheet()) - return "marker:system"; //$NON-NLS-1$ - if (resource == getUserMarkerSheet()) - return "marker:user"; //$NON-NLS-1$ - return null; - } - if (resource instanceof IMarkerGroup) { - IMarkerGroup markerGroup = (IMarkerGroup) resource; - IMarkerSheet markerSheet = markerGroup.getParent(); - if (markerSheet == getSystemMarkerSheet()) - return "marker:system/" + markerGroup.getId(); //$NON-NLS-1$ - if (markerSheet == getUserMarkerSheet()) - return "marker:user/" + markerGroup.getId(); //$NON-NLS-1$ - return null; - } - if (resource instanceof IMarker) { - IMarker marker = (IMarker) resource; - IMarkerGroup markerGroup = marker.getParent(); - if (markerGroup == null) - return null; - IMarkerSheet markerSheet = markerGroup.getParent(); - if (markerSheet == getSystemMarkerSheet()) - return "marker:system/" + markerGroup.getId() + "/" //$NON-NLS-1$ //$NON-NLS-2$ - + marker.getId(); - if (markerSheet == getUserMarkerSheet()) - return "marker:user/" + markerGroup.getId() + "/" //$NON-NLS-1$ //$NON-NLS-2$ - + marker.getId(); - return null; - } - if (resource instanceof IStyleSheet) { - if (resource == getDefaultStyleSheet()) - return "style:default"; //$NON-NLS-1$ - if (resource == getSystemStyleSheet()) - return "style:system"; //$NON-NLS-1$ - if (resource == getUserStyleSheet()) - return "style:user"; //$NON-NLS-1$ - if (resource == getSystemThemeSheet()) - return "theme:system"; //$NON-NLS-1$ - if (resource == getUserThemeSheet()) - return "theme:user"; //$NON-NLS-1$ - } - if (resource instanceof IStyle) { - if (resource == getBlankTheme()) - return "theme:system/blank"; //$NON-NLS-1$ - IStyle style = (IStyle) resource; - IStyleSheet styleSheet = style.getOwnedStyleSheet(); - if (styleSheet == getDefaultStyleSheet()) - return "style:default/" + style.getId(); //$NON-NLS-1$ - if (styleSheet == getSystemStyleSheet()) - return "style:system/" + style.getId(); //$NON-NLS-1$ - if (styleSheet == getUserStyleSheet()) - return "style:user/" + style.getId(); //$NON-NLS-1$ - if (styleSheet == getSystemThemeSheet()) - return "theme:system/" + style.getId(); //$NON-NLS-1$ - if (styleSheet == getUserThemeSheet()) - return "theme:user/" + style.getId(); //$NON-NLS-1$ - } - return null; - } - - public List getSystemTemplates() { - List sysTemplates = new ArrayList(); - loadSystemTemplates(sysTemplates); - return sysTemplates; - } - - public List getSystemTemplateGroups() { - List sysTemplateGroups = new ArrayList(); - loadSystemTemplateGroups(sysTemplateGroups); - return sysTemplateGroups; - } - - private void loadSystemTemplateGroups( - List sysTemplateGroups) { - Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); - if (bundle == null) - return; - - BundleResource listXMLResource = new BundleResource(bundle, - new Path(SYS_TEMPLATES_XML_PATH)).resolve(); - if (listXMLResource == null) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to locate system template xml: " //$NON-NLS-1$ - + bundle.getSymbolicName() + "/" //$NON-NLS-1$ - + SYS_TEMPLATES_XML_PATH)); - return; - } - - URL listXMLURL = listXMLResource.toPlatformURL(); - Element element = getTemplateListElement(listXMLURL); - if (element == null) - return; - - Properties properties = getTemplateListProperties(bundle); - Iterator categoryIt = DOMUtils.childElementIterByTag(element, - "category"); //$NON-NLS-1$ - - while (categoryIt.hasNext()) { - Element categoryEle = categoryIt.next(); - String name = categoryEle.getAttribute("name"); //$NON-NLS-1$ - - if (name.startsWith("%")) { //$NON-NLS-1$ - if (properties != null) { - name = properties.getProperty(name.substring(1)); - } else { - name = null; - } - } - - TemplateGroup templateGroup = new TemplateGroup(name); - - Iterator templateIt = DOMUtils - .childElementIterByTag(categoryEle, "template"); //$NON-NLS-1$ - ArrayList templates = new ArrayList(); - loadTemplates(templates, templateIt); - templateGroup.setTemplates(templates); - sysTemplateGroups.add(templateGroup); - } - } - - private void loadSystemTemplates(List templates) { - Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); - if (bundle == null) - return; - - BundleResource listXMLResource = new BundleResource(bundle, - new Path(SYS_TEMPLATES_XML_PATH)).resolve(); - if (listXMLResource == null) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to locate system template xml: " //$NON-NLS-1$ - + bundle.getSymbolicName() + "/" //$NON-NLS-1$ - + SYS_TEMPLATES_XML_PATH)); - return; - } - - URL listXMLURL = listXMLResource.toPlatformURL(); - Element element = getTemplateListElement(listXMLURL); - if (element == null) - return; - - Iterator it = DOMUtils.childElementIterByTag(element, - "template"); //$NON-NLS-1$ - loadTemplates(templates, it); - } - - private void loadTemplates(List templates, - Iterator it) { - while (it.hasNext()) { - Element templateEle = it.next(); - String resource = templateEle.getAttribute("resource"); //$NON-NLS-1$ - if (resource == null || "".equals(resource)) //$NON-NLS-1$ - continue; - - URI resourceURI; - try { - resourceURI = URIUtil.toURI(new URL(resource)); - } catch (IOException e) { - MindMapUIPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to load system template: " + resource, e)); //$NON-NLS-1$ - continue; - } catch (URISyntaxException e) { - MindMapUIPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to load system template: " + resource, e)); //$NON-NLS-1$ - continue; - } - - if (!resourceURI.isAbsolute()) { - BundleResource templateResource = new BundleResource( - Platform.getBundle(MindMapUI.PLUGIN_ID), - new Path(SYS_TEMPLATES_DIR + resource)).resolve(); - try { - resourceURI = templateResource.toPlatformURL().toURI(); - } catch (URISyntaxException e) { - MindMapUIPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to load system template: " + resource, e)); //$NON-NLS-1$ - continue; - } - } - - String name = templateEle.getAttribute("name"); //$NON-NLS-1$ - - if (name == null || "".equals(name)) { //$NON-NLS-1$ - name = FileUtils.getNoExtensionFileName(resource); - } - templates.add(new ClonedTemplate(resourceURI, name)); - } - } - - private Properties getTemplateListProperties(Bundle bundle) { - URL propURL = ResourceFinder.findResource(bundle, SYS_TEMPLATES_DIR, - "templates", EXT_PROPERTIES); //$NON-NLS-1$ - if (propURL == null) { - MindMapUIPlugin.getDefault().getLog().log(new Status( - IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, - "Failed to find template NLS properties file: " //$NON-NLS-1$ - + bundle.getSymbolicName() + "/" + SYS_TEMPLATES_DIR //$NON-NLS-1$ - + "templates_XX.properties")); //$NON-NLS-1$ - return null; - } - - try { - InputStream is = propURL.openStream(); - try { - Properties properties = new Properties(); - properties.load(is); - return properties; - } finally { - is.close(); - } - } catch (IOException e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, - "Failed to load template NLS properties from " //$NON-NLS-1$ - + propURL.toExternalForm(), - e)); - } - return null; - } - - private Element getTemplateListElement(URL xmlURL) { - xmlURL = FileLocator.find(xmlURL); - try { - InputStream is = xmlURL.openStream(); - if (is != null) { - try { - Document doc = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(is); - if (doc != null) - return doc.getDocumentElement(); - } finally { - is.close(); - } - } - } catch (Throwable e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, - "Failed to load template list from " //$NON-NLS-1$ - + xmlURL.toExternalForm(), - e)); - } - return null; - } - - private File createNonConflictingFile(File rootDir, String fileName) { - int dotIndex = fileName.lastIndexOf('.'); - String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); - String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ - File targetFile = new File(rootDir, fileName); - int i = 1; - while (targetFile.exists()) { - i++; - targetFile = new File(rootDir, - String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ - } - return targetFile; - } - - @Override - public List getUserTemplates() { - List customTemplates = new ArrayList(); - loadUserTemplates(customTemplates); - return customTemplates; - } - - private void loadUserTemplates(List templates) { - loadTemplatesFromDir(templates, getUserTemplatesDir()); - } - - private static File getUserTemplatesDir() { - return new File( - Core.getWorkspace().getAbsolutePath(USER_TEMPLATES_DIR)); - } - - private void loadTemplatesFromDir(List templates, - File templatesDir) { - List list = new ArrayList(); - if (templatesDir != null && templatesDir.isDirectory()) { - for (String fileName : templatesDir.list()) { - if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) - || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { - File file = new File(templatesDir, fileName); - if ((file.isFile() && file.canRead()) - || file.isDirectory()) { - list.add(new ClonedTemplate(file.toURI(), null)); - } - } - } - } - Collections.sort(list, new Comparator() { - public int compare(ITemplate t1, ITemplate t2) { - if (!(t1 instanceof ClonedTemplate) - || !(t2 instanceof ClonedTemplate)) - return 0; - ClonedTemplate ct1 = (ClonedTemplate) t1; - ClonedTemplate ct2 = (ClonedTemplate) t2; - - File f1 = URIUtil.toFile(ct1.getSourceWorkbookURI()); - File f2 = URIUtil.toFile(ct2.getSourceWorkbookURI()); - if (f1 == null || f2 == null || !f1.exists() || !f2.exists()) - return 0; - return (int) (f1.lastModified() - f2.lastModified()); - } - }); - templates.addAll(list); - } - - @Override - public ITemplate addUserTemplateFromWorkbookURI(URI workbookURI) - throws InvocationTargetException { - Assert.isNotNull(workbookURI); - final IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory().createWorkbookRef(workbookURI, null); - if (sourceWorkbookRef == null) - throw new IllegalArgumentException( - "Invalid workbook URI: " + workbookURI); //$NON-NLS-1$ - - final File userTemplateFile = createUserTemplateOutputFile( - sourceWorkbookRef.getName() + MindMapUI.FILE_EXT_TEMPLATE); - final URI templateURI = userTemplateFile.toURI(); - - final IWorkbookRef templateWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory().createWorkbookRef(templateURI, null); - if (templateWorkbookRef == null) - throw new IllegalStateException( - "Failed to obtain workbook ref for local file URI: " //$NON-NLS-1$ - + templateURI); - - IRunnableWithProgress runnable = new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - try { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - sourceWorkbookRef.open(subMonitor.newChild(30)); - try { - templateWorkbookRef.importFrom(subMonitor.newChild(60), - sourceWorkbookRef); - } finally { - subMonitor.setWorkRemaining(10); - sourceWorkbookRef.close(subMonitor.newChild(10)); - } - } finally { - if (monitor != null) - monitor.done(); - } - } - }; - - try { - if (PlatformUI.isWorkbenchRunning()) { - PlatformUI.getWorkbench().getProgressService().run(false, true, - runnable); - } else { - runnable.run(new NullProgressMonitor()); - } - } catch (InterruptedException e) { - // canceled - return null; - } - - ITemplate template = new ClonedTemplate(templateURI, FileUtils - .getNoExtensionFileName(userTemplateFile.getAbsolutePath())); - fireUserTemplateAdded(template); - return template; - } - - private void fireUserTemplateAdded(final ITemplate template) { - for (final Object listener : resourceManagerListeners.getListeners()) { - SafeRunner.run(new SafeRunnable() { - @Override - public void run() throws Exception { - ((IResourceManagerListener) listener) - .userTemplateAdded(template); - } - }); - } - } - - private void fireUserTemplateRemoved(final ITemplate template) { - for (final Object listener : resourceManagerListeners.getListeners()) { - SafeRunner.run(new SafeRunnable() { - @Override - public void run() throws Exception { - ((IResourceManagerListener) listener) - .userTemplateRemoved(template); - } - }); - } - } - - private File createUserTemplateOutputFile(String fileName) { - File dir = getUserTemplatesDir(); - FileUtils.ensureDirectory(dir); - File file = createNonConflictingFile(dir, fileName); - file.mkdirs(); - return file; - } - - @Override - public void removeUserTemplate(ITemplate template) { - URI templateURI = template.getSourceWorkbookURI(); - if (URIUtil.isFileURI(templateURI)) { - File templateFile = URIUtil.toFile(templateURI); - File templatesDir = getUserTemplatesDir(); - if (templatesDir.equals(templateFile.getParentFile())) { - FileUtils.delete(templateFile); - fireUserTemplateRemoved(template); - } - } - } - - @Override - public void addResourceManagerListener(IResourceManagerListener listener) { - resourceManagerListeners.add(listener); - } - - @Override - public void removeResourceManagerListener( - IResourceManagerListener listener) { - resourceManagerListeners.remove(listener); - } - - @Override - public ITemplate getDefaultTemplate() { - return this.defaultTemplate; - } - - @Override - public void setDefaultTemplate(ITemplate defaultTemplate) { - this.defaultTemplate = defaultTemplate; - } - - @Override - public boolean isUserTemplate(ITemplate template) { - URI templateURI = template.getSourceWorkbookURI(); - if (URIUtil.isFileURI(templateURI)) { - File templateFile = URIUtil.toFile(templateURI); - File templatesDir = getUserTemplatesDir(); - return templatesDir.equals(templateFile.getParentFile()); - } - return false; - } - - @Override - public boolean isSystemTemplate(ITemplate template) { - // TODO check source workbook URI to determine system template - boolean isSysTemplate = getSystemTemplates().contains(template); - - List systemTemplateGroups = getSystemTemplateGroups(); - for (ITemplateGroup group : systemTemplateGroups) { - if (group.getTemplates().contains(template)) - return true; - } - - return isSysTemplate; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import javax.imageio.ImageIO; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.IDeserializer; +import org.xmind.core.IManifest; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.MarkerGroup; +import org.xmind.core.internal.MarkerVariation; +import org.xmind.core.internal.dom.StyleSheetImpl; +import org.xmind.core.internal.event.CoreEventSupport; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.io.BundleResource; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.io.DirectoryOutputTarget; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.marker.AbstractMarkerResource; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerResource; +import org.xmind.core.marker.IMarkerResourceAllocator; +import org.xmind.core.marker.IMarkerResourceProvider; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.marker.IMarkerVariation; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.DOMUtils; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.IPropertiesProvider; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.IResourceManagerListener; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.ITemplateGroup; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.util.Logger; +import org.xmind.ui.util.ResourceFinder; + +public class MindMapResourceManager implements IResourceManager { + + private static final String DEFAULT_THEME_ID = "xminddefaultthemeid"; //$NON-NLS-1$ + + private static final String PATH_MARKERS = "markers/"; //$NON-NLS-1$ + + private static final String PATH_USER_MARKERS = "markers/"; //$NON-NLS-1$ + + private static final String PATH_STYLES = "styles/"; //$NON-NLS-1$ + + private static final String PATH_STYLES_DIR = "$nl$/styles/"; //$NON-NLS-1$ + + private static final String PATH_USER_STYLES = PATH_STYLES + "userStyles/"; //$NON-NLS-1$ + + private static final String PATH_USER_THEMES = PATH_STYLES + "userThemes/"; //$NON-NLS-1$ + + private static final String MARKER_SHEET_XML = "markerSheet.xml"; //$NON-NLS-1$ + + private static final String MARKER_SHEET = "markerSheet"; //$NON-NLS-1$ + + private static final String DEFAULT_STYLES_XML = "defaultStyles.xml"; //$NON-NLS-1$ + + private static final String STYLES = "styles"; //$NON-NLS-1$ + + private static final String THEMES = "themes"; //$NON-NLS-1$ + + private static final String EXT_PROPERTIES = ".properties"; //$NON-NLS-1$ + + private static final String EXT_XML = ".xml"; //$NON-NLS-1$ + + private static final String SYS_TEMPLATES_DIR = "$nl$/templates/"; //$NON-NLS-1$ + + private static final String SYS_TEMPLATES_XML_PATH = SYS_TEMPLATES_DIR + + "templates.xml"; //$NON-NLS-1$ + + private static final String USER_TEMPLATES_DIR = "templates/"; //$NON-NLS-1$ + + private static class SystemMarkerResourceProvider + implements IMarkerResourceProvider { + + public IMarkerResource getMarkerResource(IMarker marker) { + return new SystemMarkerResource(marker); + } + + public boolean isPermanent() { + return true; + } + + } + + private static class SystemMarkerResource extends AbstractMarkerResource { + + public SystemMarkerResource(IMarker marker) { + super(marker, PATH_MARKERS); + } + + public InputStream getInputStream() { + return getInputStreamForPath(getFullPath(), 100); + } + + @Override + public InputStream openInputStream(int zoom) throws IOException { + return getInputStreamForPath(getFullPath(), zoom); + } + + @Override + public InputStream openInputStream(IMarkerVariation variation, int zoom) + throws IOException { + return getInputStreamForPath(variation.getVariedPath(getFullPath()), + zoom); + } + + private InputStream getInputStreamForPath(String fullPath, int zoom) { + String xfullPath = getxPath(fullPath, zoom); + URL url = find(xfullPath); + if (url == null) + url = find(fullPath); + + if (url == null) + return null; + + try { + return url.openStream(); + } catch (IOException e) { + } + return null; + } + + private String getxPath(String path, int zoom) { + int dot = path.lastIndexOf('.'); + if (dot != -1 && zoom > 100) { + String lead = path.substring(0, dot); + String tail = path.substring(dot); + String x = "@2x"; //$NON-NLS-1$ + return lead + x + tail; + } + return path; + } + + public OutputStream getOutputStream() { + return null; + } + + public InputStream openInputStream() throws IOException { + URL url = find(getFullPath()); + if (url == null) + throw new FileNotFoundException(getFullPath()); + return url.openStream(); + } + + public OutputStream openOutputStream() throws IOException { + throw new FileNotFoundException("System marker is read only."); //$NON-NLS-1$ + } + + @Override + protected void loadVariations(List variations) { + + IMarkerVariation v = new MarkerVariation("@16", 16, 16); //$NON-NLS-1$ + if (find(v.getVariedPath(getFullPath())) != null) + variations.add(v); + + v = new MarkerVariation("@24", 24, 24); //$NON-NLS-1$ + if (find(v.getVariedPath(getFullPath())) != null) + variations.add(v); + + v = new MarkerVariation("@32", 32, 32); //$NON-NLS-1$ + if (find(v.getVariedPath(getFullPath())) != null) + variations.add(v); + } + + @Override + public InputStream getInputStream(IMarkerVariation variation) { + return getInputStreamForPath(variation.getVariedPath(getFullPath()), + 100); + } + + @Override + public InputStream openInputStream(IMarkerVariation variation) + throws IOException { + InputStream stream = getInputStreamForPath( + variation.getVariedPath(getFullPath()), 100); + if (stream == null) + throw new FileNotFoundException(); + return stream; + } + + @Override + public OutputStream getOutputStream(IMarkerVariation variation) { + return null; + } + + @Override + public OutputStream openOutputStream(IMarkerVariation variation) + throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof SystemMarkerResource)) + return false; + return super.equals(obj); + } + } + + private static class UserMarkerResourceProvider + implements IMarkerResourceProvider, IMarkerResourceAllocator { + + public IMarkerResource getMarkerResource(IMarker marker) { + return new UserMarkerResource(marker); + } + + public boolean isPermanent() { + return false; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerResourceAllocator# + * allocateMarkerResourcePath(java.io.InputStream, java.lang.String) + */ + @Override + public String allocateMarkerResource(InputStream source, + String suggestedPath) throws IOException { + String ext = suggestedPath == null ? ".png" //$NON-NLS-1$ + : FileUtils.getExtension(suggestedPath); + String path = Core.getIdFactory().createId() + ext; + File file = new File(Core.getWorkspace() + .getAbsolutePath(PATH_USER_MARKERS + path)); + FileUtils.ensureFileParent(file); + OutputStream target = new FileOutputStream(file); + try { + FileUtils.transfer(source, target, false); + } finally { + target.close(); + } + return path; + } + + } + + private static class UserMarkerResource extends AbstractMarkerResource { + + private final String JPG_FORMAT = "jpg"; //$NON-NLS-1$ + private final String JPEG_FORMAT = "jpeg"; //$NON-NLS-1$ + private final String PNG_FORMAT = "png"; //$NON-NLS-1$ + + public UserMarkerResource(IMarker marker) { + super(marker, PATH_USER_MARKERS); + } + + private File getFile() { + File origin = FileUtils.ensureFileParent(new File( + Core.getWorkspace().getAbsolutePath(getFullPath()))); + String lowerFullPath = getFullPath().toLowerCase(); + if (lowerFullPath.endsWith(JPEG_FORMAT) + || lowerFullPath.endsWith(JPG_FORMAT)) { + try { + String jpg = Core.getWorkspace() + .getAbsolutePath(getFullPath()); + BufferedImage source = ImageIO.read(new File(jpg)); + String png = jpg.substring(0, jpg.lastIndexOf('.') - 1) + + PNG_FORMAT; + File pngFile = new File(png); + ImageIO.write(source, PNG_FORMAT, pngFile); + return pngFile; + } catch (Exception e) { + } + } + + return origin; + } + + public InputStream getInputStream() { + File file = getFile(); + if (file != null) + try { + return new FileInputStream(file); + } catch (FileNotFoundException e) { + } + return null; + } + + public OutputStream getOutputStream() { + File file = getFile(); + if (file != null) + try { + return new FileOutputStream(file); + } catch (FileNotFoundException e) { + } + return null; + } + + public InputStream openInputStream() throws IOException { + return new FileInputStream(getFile()); + } + + public OutputStream openOutputStream() throws IOException { + return new FileOutputStream(getFile()); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof UserMarkerResource)) + return false; + return super.equals(obj); + } + + } + + protected static class RecentMarkerGroup extends MarkerGroup + implements ICoreEventSource { + + public static final RecentMarkerGroup instance = new RecentMarkerGroup(); + + private static final int CAPACITY = 20; + + private List markers = new ArrayList(CAPACITY); + + private ICoreEventSupport eventSupport = new CoreEventSupport(); + + private RecentMarkerGroup() { + } + + public void addMarker(IMarker marker) { + if (markers.contains(marker)) + return; + + while (markers.size() >= CAPACITY) { + markers.remove(markers.size() - 1); + } + markers.add(0, marker); + eventSupport.dispatchTargetChange(this, Core.MarkerAdd, marker); + } + + public T getAdapter(Class adapter) { + if (adapter == ICoreEventSource.class) + return adapter.cast(this); + return super.getAdapter(adapter); + } + + public List getMarkers() { + return markers; + } + + /* + * (non-Javadoc) + * @see org.xmind.core.marker.IMarkerGroup#isEmpty() + */ + @Override + public boolean isEmpty() { + return markers.isEmpty(); + } + + public String getName() { + return MindMapMessages.RecentUsed; + } + + public void setSingleton(boolean singleton) { + } + + public IMarkerSheet getOwnedSheet() { + return null; + } + + public IMarkerSheet getParent() { + return null; + } + + public boolean isSingleton() { + return false; + } + + public boolean isHidden() { + return false; + } + + public void setHidden(boolean hidden) { + + } + + public void removeMarker(IMarker marker) { + if (!markers.contains(marker)) + return; + markers.remove(marker); + eventSupport.dispatchTargetChange(this, Core.MarkerRemove, marker); + } + + public void setName(String name) { + } + + public String getId() { + return "org.xmind.ui.RecentMarkerGroup"; //$NON-NLS-1$ + } + + public Object getRegisterKey() { + return getId(); + } + + public ICoreEventRegistration registerCoreEventListener(String type, + ICoreEventListener listener) { + return eventSupport.registerCoreEventListener(this, type, listener); + } + + public int hashCode() { + return super.hashCode(); + } + + public ICoreEventSupport getCoreEventSupport() { + return eventSupport; + } + + } + + private IMarkerSheet systemMarkerSheet = null; + + private IMarkerSheet userMarkerSheet = null; + + private IMarkerGroup recentMarkerGroup = null; + + private IStyleSheet defaultStyleSheet = null; + + private IStyleSheet systemStyleSheet = null; + + private IWorkbook userStylesContainer = null; + + private IStyle blankTheme = null; + + private IStyle defaultTheme = null; + + private IStyleSheet systemThemeSheet = null; + + private IWorkbook userThemesContainer = null; + + private ITemplate defaultTemplate; + + private ListenerList resourceManagerListeners = new ListenerList(); + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.IMarkerSheetManager#getSystemMarkerSheet() + */ + public IMarkerSheet getSystemMarkerSheet() { + if (systemMarkerSheet == null) { + systemMarkerSheet = createSystemMarkerShet(); + } + return systemMarkerSheet; + } + + private IMarkerSheet createSystemMarkerShet() { + URL url = find(PATH_MARKERS, MARKER_SHEET_XML); + if (url != null) { + try { + IMarkerSheet sheet = Core.getMarkerSheetBuilder() + .loadFromURL(url, new SystemMarkerResourceProvider()); + loadPropertiesFor(sheet, PATH_MARKERS, MARKER_SHEET); + return sheet; + } catch (Exception e) { + Logger.log(e, "Failed to load system marker from: " + url); //$NON-NLS-1$ + } + } + return Core.getMarkerSheetBuilder() + .createMarkerSheet(new SystemMarkerResourceProvider()); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.IMarkerSheetManager#getUserMarkerSheet() + */ + public IMarkerSheet getUserMarkerSheet() { + if (userMarkerSheet == null) { + userMarkerSheet = createUserMarkerSheet(); + initUserMarkerSheet(userMarkerSheet); + } + return userMarkerSheet; + } + + public void saveUserMarkerSheet() { + if (userMarkerSheet != null) { + String path = Core.getWorkspace() + .getAbsolutePath(PATH_USER_MARKERS + MARKER_SHEET_XML); + File file = FileUtils.ensureFileParent(new File(path)); + FileOutputStream out = null; + try { + out = new FileOutputStream(file); + userMarkerSheet.save(out); + } catch (Exception e) { + Logger.log(e); + } finally { + if (out != null) + try { + out.close(); + } catch (IOException e) { + Logger.log(e); + } + } + } + } + + private void initUserMarkerSheet(IMarkerSheet sheet) { + sheet.setParentSheet(getSystemMarkerSheet()); + } + + private IMarkerSheet createUserMarkerSheet() { + String path = Core.getWorkspace() + .getAbsolutePath(PATH_USER_MARKERS + MARKER_SHEET_XML); + if (path != null) { + File file = new File(path); + if (file.exists()) { + try { + return Core.getMarkerSheetBuilder().loadFromFile(file, + new UserMarkerResourceProvider()); + } catch (Exception e) { + Logger.log(e, "Failed to load user marker from: " + file); //$NON-NLS-1$ + } + } + } + return Core.getMarkerSheetBuilder() + .createMarkerSheet(new UserMarkerResourceProvider()); + } + + public IMarkerGroup getRecentMarkerGroup() { + if (recentMarkerGroup == null) { + recentMarkerGroup = new RecentMarkerGroup(); + } + return recentMarkerGroup; + } + + public IStyleSheet getDefaultStyleSheet() { + if (defaultStyleSheet == null) { + defaultStyleSheet = createDefaultStyleSheet(); + } + return defaultStyleSheet; + } + + private IStyleSheet createDefaultStyleSheet() { + URL url = find(PATH_STYLES, DEFAULT_STYLES_XML); + if (url != null) { + try { + return Core.getStyleSheetBuilder().loadFromUrl(url); + } catch (Exception e) { + Logger.log(e, "Failed to load default styles: " + url); //$NON-NLS-1$ + } + } + return Core.getStyleSheetBuilder().createStyleSheet(); + } + + public IStyleSheet getSystemStyleSheet() { + if (systemStyleSheet == null) { + systemStyleSheet = createSystemStyleSheet(); + IManifest manifest = Core.getWorkbookBuilder().createWorkbook() + .getManifest(); + ((StyleSheetImpl) systemStyleSheet).setManifest(manifest); + } + return systemStyleSheet; + } + + private IStyleSheet createSystemStyleSheet() { + URL url = find(PATH_STYLES, STYLES, EXT_XML); + if (url != null) { + try { + IStyleSheet sheet = Core.getStyleSheetBuilder() + .loadFromUrl(url); + loadPropertiesFor(sheet, PATH_STYLES, STYLES); + return sheet; + } catch (Exception e) { + Logger.log(e, "Falied to load saved styles: " + url); //$NON-NLS-1$ + } + } + return Core.getStyleSheetBuilder().createStyleSheet(); + } + + public IStyleSheet getUserStyleSheet() { + if (userStylesContainer == null) { + userStylesContainer = loadResourceContainer(PATH_USER_STYLES); + } + return userStylesContainer.getStyleSheet(); + } + + public void saveUserStyleSheet() { + saveResourceContainer(userStylesContainer, PATH_USER_STYLES); + } + + public IStyle getBlankTheme() { + if (blankTheme == null) { + blankTheme = Core.getStyleSheetBuilder().createStyleSheet() + .createStyle(IStyle.THEME); + blankTheme.setName(MindMapMessages.DefaultTheme_title); + } + return blankTheme; + } + + public IStyle getDefaultTheme() { + if (defaultTheme == null) { + defaultTheme = findDefaultTheme(); + } + return checkDefaultTheme(defaultTheme); + } + + private IStyle checkDefaultTheme(IStyle defaultTheme) { + String defaultId = defaultTheme.getId(); + boolean exist = getSystemThemeSheet().findStyle(defaultId) != null + || getUserThemeSheet().findStyle(defaultId) != null + || getBlankTheme().getId().equals(defaultId); + return exist ? defaultTheme + : getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); + + } + + private IStyle findDefaultTheme() { + if (Platform.isRunning()) { + String defaultId = MindMapUIPlugin.getDefault().getPreferenceStore() + .getString(PrefConstants.DEFUALT_THEME); + if (defaultId != null && !"".equals(defaultId)) { //$NON-NLS-1$ + IStyle theme = getSystemThemeSheet().findStyle(defaultId); + if (theme == null) { +// theme = getUserStyleSheet().findStyle(defaultId); + theme = getUserThemeSheet().findStyle(defaultId); + } + if (theme == null && defaultId.equals(getBlankTheme().getId())) + theme = getBlankTheme(); + + if (theme != null) + return theme; + } + } + return getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); + } + + public void setDefaultTheme(String id) { + IStyle theme = null; + if (id != null && !"".equals(id)) { //$NON-NLS-1$ + theme = getSystemThemeSheet().findStyle(DEFAULT_THEME_ID); + if (!id.equals(theme.getId())) { + theme = getSystemThemeSheet().findStyle(id); + if (theme == null) { + theme = getUserThemeSheet().findStyle(id); + } + if (theme == null && id.equals(getBlankTheme().getId())) { + theme = getBlankTheme(); + } + } + } + if (theme == null) + id = null; + + this.defaultTheme = theme; + MindMapUIPlugin.getDefault().getPreferenceStore() + .setValue(PrefConstants.DEFUALT_THEME, id); + } + + public IStyleSheet getSystemThemeSheet() { + if (systemThemeSheet == null) { + systemThemeSheet = createSystemThemeSheet(); + IManifest manifest = Core.getWorkbookBuilder().createWorkbook() + .getManifest(); + ((StyleSheetImpl) systemThemeSheet).setManifest(manifest); + } + return systemThemeSheet; + } + + private IStyleSheet createSystemThemeSheet() { +// URL url = find(PATH_STYLES, THEMES_XML); + URL url = find(PATH_STYLES_DIR, THEMES, EXT_XML); + if (url != null) { + try { + IStyleSheet sheet = Core.getStyleSheetBuilder() + .loadFromUrl(url); + loadPropertiesFor(sheet, PATH_STYLES, THEMES); + return sheet; + } catch (Exception e) { + Logger.log(e, "Falied to load system themes: " + url); //$NON-NLS-1$ + } + } + return Core.getStyleSheetBuilder().createStyleSheet(); + } + + public IStyleSheet getUserThemeSheet() { + if (userThemesContainer == null) { + userThemesContainer = loadResourceContainer(PATH_USER_THEMES); + } + return userThemesContainer.getStyleSheet(); + } + + public void saveUserThemeSheet() { + saveResourceContainer(userThemesContainer, PATH_USER_THEMES); + } + + /** + * @param sourcePath + * @return + */ + private static IWorkbook loadResourceContainer(String sourcePath) { + IWorkbook container = null; + File file = new File(Core.getWorkspace().getAbsolutePath(sourcePath)); + File tempLoc = new File(Core.getWorkspace().getTempDir(sourcePath)); + FileUtils.ensureDirectory(tempLoc); + DirectoryStorage tempStorage = new DirectoryStorage(tempLoc); + + if (file.exists() && file.isDirectory() + && new File(file, ArchiveConstants.CONTENT_XML).exists()) { + try { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setWorkbookStorage(tempStorage); + deserializer.setInputSource(new DirectoryInputSource(file)); + deserializer.deserialize(null); + container = deserializer.getWorkbook(); + } catch (Exception e) { + Logger.log(e, "Failed to load user styles from: " + file); //$NON-NLS-1$ + } + } + if (container == null) { + container = Core.getWorkbookBuilder().createWorkbook(tempStorage); + } + return container; + } + + private static void saveResourceContainer(IWorkbook workbook, + String targetPath) { + if (workbook == null) + return; + + File file = new File(Core.getWorkspace().getAbsolutePath(targetPath)); + FileUtils.ensureDirectory(file); + try { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setOutputTarget(new DirectoryOutputTarget(file)); + serializer.serialize(null); + } catch (Exception e) { + Logger.log(e); + } + } + + private static URL find(String fullPath) { + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + if (bundle != null) { + return FileLocator.find(bundle, new Path(fullPath), null); + } + return null; + } + + private static URL find(String mainPath, String subPath) { + return find(mainPath + subPath); + } + + private static URL find(String mainPath, String prefix, String suffix) { + return ResourceFinder.findResource(MindMapUI.PLUGIN_ID, mainPath, + prefix, suffix); + } + + private static void loadPropertiesFor(IAdaptable resourceManager, + String mainPath, String propertiesFilePrefix) { + IPropertiesProvider propertiesProvider = (IPropertiesProvider) resourceManager + .getAdapter(IPropertiesProvider.class); + if (propertiesProvider == null) + return; + + Properties defaultProperties = new Properties(); + URL defaultPropertiesURL = FileLocator.find( + Platform.getBundle(MindMapUI.PLUGIN_ID), + new Path(mainPath + propertiesFilePrefix + EXT_PROPERTIES), + null); + if (defaultPropertiesURL != null) { + try { + InputStream stream = defaultPropertiesURL.openStream(); + try { + defaultProperties.load(stream); + } finally { + stream.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to load default properties file from: " //$NON-NLS-1$ + + mainPath + propertiesFilePrefix + EXT_PROPERTIES); + } + } + + Properties properties = new Properties(defaultProperties); + URL propertiesURL = find(mainPath, propertiesFilePrefix, + EXT_PROPERTIES); + if (propertiesURL != null) { + try { + InputStream stream = propertiesURL.openStream(); + try { + properties.load(stream); + } finally { + stream.close(); + } + } catch (IOException e) { + Logger.log(e, + "Failed to load locale-specific properties file from: " //$NON-NLS-1$ + + mainPath + propertiesFilePrefix + + EXT_PROPERTIES); + } + } + + propertiesProvider.setProperties(properties); + } + + private static final String SCHEMA_MARKER = "marker"; //$NON-NLS-1$ + private static final String SCHEMA_STYLE = "style"; //$NON-NLS-1$ + private static final String SCHEMA_THEME = "theme"; //$NON-NLS-1$ + private static final String CATEGORY_SYSTEM = "system"; //$NON-NLS-1$ + private static final String CATEGORY_USER = "user"; //$NON-NLS-1$ + private static final String CATEGORY_DEFAULT = "default"; //$NON-NLS-1$ + private static final String GROUP_ANY = "any"; //$NON-NLS-1$ + private static final String ID_BLANK = "blank"; //$NON-NLS-1$ + private static final String ID_DEFAULT = "__default__"; //$NON-NLS-1$ + + /* + * (non-Javadoc) + * @see org.xmind.ui.mindmap.IResourceManager#findResource(java.lang.String) + */ + public Object findResource(String uri) { + if (uri == null) + return null; + + int sep = uri.indexOf(':'); + if (sep < 0) + return null; + + String schema = uri.substring(0, sep); + String path = uri.substring(sep + 1); + String[] segments = path.split("/"); //$NON-NLS-1$ + if (segments.length == 0) + // Not possible to happen: + return null; + + String category = segments[0]; + if (SCHEMA_MARKER.equals(schema)) { + // marker: + IMarkerSheet markerSheet = findMarkerSheet(category); + if (markerSheet == null || segments.length == 1) + return markerSheet; + String groupId = segments[1]; + boolean anyGroup = GROUP_ANY.equals(groupId); + IMarkerGroup markerGroup = anyGroup ? null + : markerSheet.findMarkerGroup(groupId); + if (segments.length == 2) + return markerGroup; + String markerId = segments[2]; + if (markerGroup == null) + return anyGroup ? markerSheet.findMarker(markerId) : null; + return markerGroup.getMarker(markerId); + } else if (SCHEMA_STYLE.equals(schema)) { + // style: + IStyleSheet styleSheet = findStyleSheet(category); + if (styleSheet == null || segments.length == 1) + return styleSheet; + String styleId = segments[1]; + return styleSheet.findStyle(styleId); + } else if (SCHEMA_THEME.equals(schema)) { + // theme: + IStyleSheet themeSheet = findThemeSheet(category); + if (themeSheet == null || segments.length == 1) + return themeSheet; + String styleId = segments[1]; + if (themeSheet == getSystemThemeSheet()) { + if (ID_BLANK.equals(styleId)) + return getBlankTheme(); + if (ID_DEFAULT.equals(styleId)) + return getDefaultTheme(); + } + return themeSheet.findStyle(styleId); + } + + return null; + } + + private IMarkerSheet findMarkerSheet(String category) { + if (CATEGORY_SYSTEM.equals(category)) { + return getSystemMarkerSheet(); + } else if (CATEGORY_USER.equals(category)) { + return getUserMarkerSheet(); + } else { + return null; + } + } + + private IStyleSheet findStyleSheet(String category) { + if (CATEGORY_DEFAULT.equals(category)) + return getDefaultStyleSheet(); + if (CATEGORY_SYSTEM.equals(category)) + return getSystemStyleSheet(); + if (CATEGORY_USER.equals(category)) + return getUserStyleSheet(); + return null; + } + + private IStyleSheet findThemeSheet(String category) { + if (CATEGORY_SYSTEM.equals(category)) + return getSystemThemeSheet(); + if (CATEGORY_USER.equals(category)) + return getUserThemeSheet(); + return null; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.mindmap.IResourceManager#toResourceURI(java.lang.Object) + */ + public String toResourceURI(Object resource) { + if (resource instanceof IMarkerSheet) { + if (resource == getSystemMarkerSheet()) + return "marker:system"; //$NON-NLS-1$ + if (resource == getUserMarkerSheet()) + return "marker:user"; //$NON-NLS-1$ + return null; + } + if (resource instanceof IMarkerGroup) { + IMarkerGroup markerGroup = (IMarkerGroup) resource; + IMarkerSheet markerSheet = markerGroup.getParent(); + if (markerSheet == getSystemMarkerSheet()) + return "marker:system/" + markerGroup.getId(); //$NON-NLS-1$ + if (markerSheet == getUserMarkerSheet()) + return "marker:user/" + markerGroup.getId(); //$NON-NLS-1$ + return null; + } + if (resource instanceof IMarker) { + IMarker marker = (IMarker) resource; + IMarkerGroup markerGroup = marker.getParent(); + if (markerGroup == null) + return null; + IMarkerSheet markerSheet = markerGroup.getParent(); + if (markerSheet == getSystemMarkerSheet()) + return "marker:system/" + markerGroup.getId() + "/" //$NON-NLS-1$ //$NON-NLS-2$ + + marker.getId(); + if (markerSheet == getUserMarkerSheet()) + return "marker:user/" + markerGroup.getId() + "/" //$NON-NLS-1$ //$NON-NLS-2$ + + marker.getId(); + return null; + } + if (resource instanceof IStyleSheet) { + if (resource == getDefaultStyleSheet()) + return "style:default"; //$NON-NLS-1$ + if (resource == getSystemStyleSheet()) + return "style:system"; //$NON-NLS-1$ + if (resource == getUserStyleSheet()) + return "style:user"; //$NON-NLS-1$ + if (resource == getSystemThemeSheet()) + return "theme:system"; //$NON-NLS-1$ + if (resource == getUserThemeSheet()) + return "theme:user"; //$NON-NLS-1$ + } + if (resource instanceof IStyle) { + if (resource == getBlankTheme()) + return "theme:system/blank"; //$NON-NLS-1$ + IStyle style = (IStyle) resource; + IStyleSheet styleSheet = style.getOwnedStyleSheet(); + if (styleSheet == getDefaultStyleSheet()) + return "style:default/" + style.getId(); //$NON-NLS-1$ + if (styleSheet == getSystemStyleSheet()) + return "style:system/" + style.getId(); //$NON-NLS-1$ + if (styleSheet == getUserStyleSheet()) + return "style:user/" + style.getId(); //$NON-NLS-1$ + if (styleSheet == getSystemThemeSheet()) + return "theme:system/" + style.getId(); //$NON-NLS-1$ + if (styleSheet == getUserThemeSheet()) + return "theme:user/" + style.getId(); //$NON-NLS-1$ + } + return null; + } + + public List getSystemTemplates() { + List sysTemplates = new ArrayList(); + loadSystemTemplates(sysTemplates); + return sysTemplates; + } + + public List getSystemTemplateGroups() { + List sysTemplateGroups = new ArrayList(); + loadSystemTemplateGroups(sysTemplateGroups); + return sysTemplateGroups; + } + + private void loadSystemTemplateGroups( + List sysTemplateGroups) { + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + if (bundle == null) + return; + + BundleResource listXMLResource = new BundleResource(bundle, + new Path(SYS_TEMPLATES_XML_PATH)).resolve(); + if (listXMLResource == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to locate system template xml: " //$NON-NLS-1$ + + bundle.getSymbolicName() + "/" //$NON-NLS-1$ + + SYS_TEMPLATES_XML_PATH)); + return; + } + + URL listXMLURL = listXMLResource.toPlatformURL(); + Element element = getTemplateListElement(listXMLURL); + if (element == null) + return; + + Properties properties = getTemplateListProperties(bundle); + Iterator categoryIt = DOMUtils.childElementIterByTag(element, + "category"); //$NON-NLS-1$ + + while (categoryIt.hasNext()) { + Element categoryEle = categoryIt.next(); + String name = categoryEle.getAttribute("name"); //$NON-NLS-1$ + + if (name.startsWith("%")) { //$NON-NLS-1$ + if (properties != null) { + name = properties.getProperty(name.substring(1)); + } else { + name = null; + } + } + + TemplateGroup templateGroup = new TemplateGroup(name); + + Iterator templateIt = DOMUtils + .childElementIterByTag(categoryEle, "template"); //$NON-NLS-1$ + ArrayList templates = new ArrayList(); + loadTemplates(templates, templateIt); + templateGroup.setTemplates(templates); + sysTemplateGroups.add(templateGroup); + } + } + + private void loadSystemTemplates(List templates) { + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + if (bundle == null) + return; + + BundleResource listXMLResource = new BundleResource(bundle, + new Path(SYS_TEMPLATES_XML_PATH)).resolve(); + if (listXMLResource == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to locate system template xml: " //$NON-NLS-1$ + + bundle.getSymbolicName() + "/" //$NON-NLS-1$ + + SYS_TEMPLATES_XML_PATH)); + return; + } + + URL listXMLURL = listXMLResource.toPlatformURL(); + Element element = getTemplateListElement(listXMLURL); + if (element == null) + return; + + Iterator it = DOMUtils.childElementIterByTag(element, + "template"); //$NON-NLS-1$ + loadTemplates(templates, it); + } + + private void loadTemplates(List templates, + Iterator it) { + while (it.hasNext()) { + Element templateEle = it.next(); + String resource = templateEle.getAttribute("resource"); //$NON-NLS-1$ + if (resource == null || "".equals(resource)) //$NON-NLS-1$ + continue; + + URI resourceURI; + try { + resourceURI = URIUtil.toURI(new URL(resource)); + } catch (IOException e) { + MindMapUIPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to load system template: " + resource, e)); //$NON-NLS-1$ + continue; + } catch (URISyntaxException e) { + MindMapUIPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to load system template: " + resource, e)); //$NON-NLS-1$ + continue; + } + + if (!resourceURI.isAbsolute()) { + BundleResource templateResource = new BundleResource( + Platform.getBundle(MindMapUI.PLUGIN_ID), + new Path(SYS_TEMPLATES_DIR + resource)).resolve(); + try { + resourceURI = templateResource.toPlatformURL().toURI(); + } catch (URISyntaxException e) { + MindMapUIPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to load system template: " + resource, e)); //$NON-NLS-1$ + continue; + } + } + + String name = templateEle.getAttribute("name"); //$NON-NLS-1$ + + if (name == null || "".equals(name)) { //$NON-NLS-1$ + name = FileUtils.getNoExtensionFileName(resource); + } + templates.add(new ClonedTemplate(resourceURI, name)); + } + } + + private Properties getTemplateListProperties(Bundle bundle) { + URL propURL = ResourceFinder.findResource(bundle, SYS_TEMPLATES_DIR, + "templates", EXT_PROPERTIES); //$NON-NLS-1$ + if (propURL == null) { + MindMapUIPlugin.getDefault().getLog().log(new Status( + IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, + "Failed to find template NLS properties file: " //$NON-NLS-1$ + + bundle.getSymbolicName() + "/" + SYS_TEMPLATES_DIR //$NON-NLS-1$ + + "templates_XX.properties")); //$NON-NLS-1$ + return null; + } + + try { + InputStream is = propURL.openStream(); + try { + Properties properties = new Properties(); + properties.load(is); + return properties; + } finally { + is.close(); + } + } catch (IOException e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, + "Failed to load template NLS properties from " //$NON-NLS-1$ + + propURL.toExternalForm(), + e)); + } + return null; + } + + private Element getTemplateListElement(URL xmlURL) { + xmlURL = FileLocator.find(xmlURL); + try { + InputStream is = xmlURL.openStream(); + if (is != null) { + try { + Document doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(is); + if (doc != null) + return doc.getDocumentElement(); + } finally { + is.close(); + } + } + } catch (Throwable e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, + "Failed to load template list from " //$NON-NLS-1$ + + xmlURL.toExternalForm(), + e)); + } + return null; + } + + private File createNonConflictingFile(File rootDir, String fileName) { + int dotIndex = fileName.lastIndexOf('.'); + String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); + String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ + File targetFile = new File(rootDir, fileName); + int i = 1; + while (targetFile.exists()) { + i++; + targetFile = new File(rootDir, + String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ + } + return targetFile; + } + + @Override + public List getUserTemplates() { + List customTemplates = new ArrayList(); + loadUserTemplates(customTemplates); + return customTemplates; + } + + private void loadUserTemplates(List templates) { + loadTemplatesFromDir(templates, getUserTemplatesDir()); + } + + private static File getUserTemplatesDir() { + return new File( + Core.getWorkspace().getAbsolutePath(USER_TEMPLATES_DIR)); + } + + private void loadTemplatesFromDir(List templates, + File templatesDir) { + List list = new ArrayList(); + if (templatesDir != null && templatesDir.isDirectory()) { + for (String fileName : templatesDir.list()) { + if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) + || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { + File file = new File(templatesDir, fileName); + if ((file.isFile() && file.canRead()) + || file.isDirectory()) { + list.add(new ClonedTemplate(file.toURI(), null)); + } + } + } + } + Collections.sort(list, new Comparator() { + public int compare(ITemplate t1, ITemplate t2) { + if (!(t1 instanceof ClonedTemplate) + || !(t2 instanceof ClonedTemplate)) + return 0; + ClonedTemplate ct1 = (ClonedTemplate) t1; + ClonedTemplate ct2 = (ClonedTemplate) t2; + + File f1 = URIUtil.toFile(ct1.getSourceWorkbookURI()); + File f2 = URIUtil.toFile(ct2.getSourceWorkbookURI()); + if (f1 == null || f2 == null || !f1.exists() || !f2.exists()) + return 0; + return (int) (f1.lastModified() - f2.lastModified()); + } + }); + templates.addAll(list); + } + + @Override + public ITemplate addUserTemplateFromWorkbookURI(URI workbookURI) + throws InvocationTargetException { + Assert.isNotNull(workbookURI); + final IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory().createWorkbookRef(workbookURI, null); + if (sourceWorkbookRef == null) + throw new IllegalArgumentException( + "Invalid workbook URI: " + workbookURI); //$NON-NLS-1$ + + final File userTemplateFile = createUserTemplateOutputFile( + sourceWorkbookRef.getName() + MindMapUI.FILE_EXT_TEMPLATE); + final URI templateURI = userTemplateFile.toURI(); + + final IWorkbookRef templateWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory().createWorkbookRef(templateURI, null); + if (templateWorkbookRef == null) + throw new IllegalStateException( + "Failed to obtain workbook ref for local file URI: " //$NON-NLS-1$ + + templateURI); + + IRunnableWithProgress runnable = new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + try { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + sourceWorkbookRef.open(subMonitor.newChild(30)); + try { + templateWorkbookRef.importFrom(subMonitor.newChild(60), + sourceWorkbookRef); + } finally { + subMonitor.setWorkRemaining(10); + sourceWorkbookRef.close(subMonitor.newChild(10)); + } + } finally { + if (monitor != null) + monitor.done(); + } + } + }; + + try { + if (PlatformUI.isWorkbenchRunning()) { + PlatformUI.getWorkbench().getProgressService().run(false, true, + runnable); + } else { + runnable.run(new NullProgressMonitor()); + } + } catch (InterruptedException e) { + // canceled + return null; + } + + ITemplate template = new ClonedTemplate(templateURI, FileUtils + .getNoExtensionFileName(userTemplateFile.getAbsolutePath())); + fireUserTemplateAdded(template); + return template; + } + + private void fireUserTemplateAdded(final ITemplate template) { + for (final Object listener : resourceManagerListeners.getListeners()) { + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + ((IResourceManagerListener) listener) + .userTemplateAdded(template); + } + }); + } + } + + private void fireUserTemplateRemoved(final ITemplate template) { + for (final Object listener : resourceManagerListeners.getListeners()) { + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + ((IResourceManagerListener) listener) + .userTemplateRemoved(template); + } + }); + } + } + + private File createUserTemplateOutputFile(String fileName) { + File dir = getUserTemplatesDir(); + FileUtils.ensureDirectory(dir); + File file = createNonConflictingFile(dir, fileName); + file.mkdirs(); + return file; + } + + @Override + public void removeUserTemplate(ITemplate template) { + URI templateURI = template.getSourceWorkbookURI(); + if (URIUtil.isFileURI(templateURI)) { + File templateFile = URIUtil.toFile(templateURI); + File templatesDir = getUserTemplatesDir(); + if (templatesDir.equals(templateFile.getParentFile())) { + FileUtils.delete(templateFile); + fireUserTemplateRemoved(template); + } + } + } + + @Override + public void addResourceManagerListener(IResourceManagerListener listener) { + resourceManagerListeners.add(listener); + } + + @Override + public void removeResourceManagerListener( + IResourceManagerListener listener) { + resourceManagerListeners.remove(listener); + } + + @Override + public ITemplate getDefaultTemplate() { + return this.defaultTemplate; + } + + @Override + public void setDefaultTemplate(ITemplate defaultTemplate) { + this.defaultTemplate = defaultTemplate; + } + + @Override + public boolean isUserTemplate(ITemplate template) { + URI templateURI = template.getSourceWorkbookURI(); + if (URIUtil.isFileURI(templateURI)) { + File templateFile = URIUtil.toFile(templateURI); + File templatesDir = getUserTemplatesDir(); + return templatesDir.equals(templateFile.getParentFile()); + } + return false; + } + + @Override + public boolean isSystemTemplate(ITemplate template) { + // TODO check source workbook URI to determine system template + boolean isSysTemplate = getSystemTemplates().contains(template); + + List systemTemplateGroups = getSystemTemplateGroups(); + for (ITemplateGroup group : systemTemplateGroups) { + if (group.getTemplates().contains(template)) + return true; + } + + return isSysTemplate; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapTemplateManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapTemplateManager.java index c524fd93e..72af33ba9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapTemplateManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapTemplateManager.java @@ -1,359 +1,359 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2010 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal; - -/** - * @author Frank Shaka - * @deprecated Use MindMapUI.getResourceManager() - */ -@Deprecated -public class MindMapTemplateManager { - -// private static final MindMapTemplateManager instance = new MindMapTemplateManager(); -// -// private static final String DEFAULT_TEMPLATE_ID = "org.xmind.ui.template.default"; //$NON-NLS-1$ -// -// private static final String TEMPLATES_PATH = "templates"; //$NON-NLS-1$ -// private static final String TEMPLATES_DIR = TEMPLATES_PATH + "/"; //$NON-NLS-1$ -// -// private List listeners = new ArrayList(); -// -// private MindMapTemplateManager() { -// } -// -// public void addTemplateManagerListener(ITemplateManagerListener listener) { -// listeners.add(listener); -// } -// -// public void removeTemplateManagerListener( -// ITemplateManagerListener listener) { -// listeners.remove(listener); -// } -// -// private void fireTemplateAdded(ITemplateDescriptor template) { -// for (Object listener : listeners.toArray()) { -// try { -// ((ITemplateManagerListener) listener).templateAdded(template); -// } catch (Throwable e) { -// Logger.log(e); -// } -// } -// } -// -// private void fireTemplateRemoved(ITemplateDescriptor template) { -// for (Object listener : listeners.toArray()) { -// try { -// ((ITemplateManagerListener) listener).templateRemoved(template); -// } catch (Throwable e) { -// Logger.log(e); -// } -// } -// } -// -// public List importTemplates(String... fileNames) { -// List importedTemplates = new ArrayList( -// fileNames.length); -// for (String fileName : fileNames) { -// ITemplateDescriptor template = importCustomTemplate(fileName); -// if (template != null) { -// importedTemplates.add(template); -// } -// } -// return importedTemplates; -// } -// -// public ITemplateDescriptor importCustomTemplate(IWorkbook workbook, -// String name) { -// if (!name.endsWith(MindMapUI.FILE_EXT_TEMPLATE) -// && !name.endsWith(MindMapUI.FILE_EXT_XMIND)) { -// name = name + MindMapUI.FILE_EXT_TEMPLATE; -// } -// File targetFile = createCustomTemplateOutputFile(name); -// IWorkbookRef wr = MindMapUIPlugin.getDefault().getWorkbookRefFactory() -// .createWorkbookRef(targetFile.toURI(), null); -// if (wr == null) -// return null; -// -// final boolean[] finished = new boolean[1]; -// finished[0] = false; -// wr.importFrom(new PreLoadedWorkbookRef(workbook, null), -// new IEditableOperationCallback() { -// public void handleCompletion(boolean successful, -// IEditableStatus status) { -// finished[0] = true; -// } -// }); -// -// try { -// while (!finished[0]) { -// Thread.sleep(0); -// } -// } catch (InterruptedException e) { -// return null; -// } -// if (!wr.exists()) -// return null; -// -// FileTemplateDescriptor template = new FileTemplateDescriptor( -// targetFile); -// fireTemplateAdded(template); -// return template; -// } -// -// public ITemplateDescriptor importCustomTemplate(String path) { -// File sourceFile = new File(path); -// String fileName = sourceFile.getName(); -// File targetFile = createCustomTemplateOutputFile(fileName); -// try { -// FileUtils.copy(sourceFile, targetFile); -// FileTemplateDescriptor template = new FileTemplateDescriptor( -// targetFile); -// fireTemplateAdded(template); -// return template; -// } catch (IOException e) { -// } -// return null; -// } -// -// private File createCustomTemplateOutputFile(String fileName) { -// String dirPath = getCustomTemplatesLocation(); -// File dir = new File(dirPath); -// FileUtils.ensureDirectory(dir); -// return createNonConflictingFile(dir, fileName); -// } -// -// public boolean removeTemplate(ITemplateDescriptor template) { -// if (template instanceof FileTemplateDescriptor) { -// File file = ((FileTemplateDescriptor) template).getFile(); -// if (file.delete()) { -// fireTemplateRemoved(template); -// return true; -// } -// } -// return false; -// } -// -// public List loadAllTemplates() { -// List templates = new ArrayList(); -// loadDefaultTemplates(templates); -// loadSystemTemplates(templates); -// loadCustomTemplates(templates); -// return templates; -// } -// -// public List loadDefaultTemplates() { -// List templates = new ArrayList(); -// loadDefaultTemplates(templates); -// return templates; -// } -// -// public List loadSystemTemplates() { -// List templates = new ArrayList(); -// loadSystemTemplates(templates); -// return templates; -// } -// -// public List loadCustomTemplates() { -// List templates = new ArrayList(); -// loadCustomTemplates(templates); -// return templates; -// } -// -// private void loadDefaultTemplates(List templates) { -// templates.add(new DefaultTemplateDescriptor(DEFAULT_TEMPLATE_ID, -// WizardMessages.ChooseTemplateWizardPage_BlankMap_title)); -// } -// -// private void loadCustomTemplates(List templates) { -// String templatesDir = getCustomTemplatesLocation(); -// loadTemplatesFromDir(templates, new File(templatesDir)); -// } -// -// private String getCustomTemplatesLocation() { -// return Core.getWorkspace().getAbsolutePath(TEMPLATES_PATH); -// } -// -// private void loadTemplatesFromDir(List templates, -// File templatesDir) { -// List list = new ArrayList(); -// if (templatesDir != null && templatesDir.isDirectory()) { -// for (String fileName : templatesDir.list()) { -// if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) -// || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { -// File file = new File(templatesDir, fileName); -// if (file.isFile() && file.canRead()) { -// list.add(new FileTemplateDescriptor(file)); -// } -// } -// } -// } -// Collections.sort(list, new Comparator() { -// public int compare(ITemplateDescriptor t1, ITemplateDescriptor t2) { -// File f1 = ((FileTemplateDescriptor) t1).getFile(); -// File f2 = ((FileTemplateDescriptor) t2).getFile(); -// return (int) (f1.lastModified() - f2.lastModified()); -// } -// }); -// templates.addAll(list); -// } -// -// private void loadSystemTemplates(List templates) { -// Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); -// if (bundle != null) { -// Element element = getTemplateListElement(bundle); -// if (element != null) { -// java.util.Properties properties = getTemplateListProperties( -// bundle); -// Iterator it = DOMUtils.childElementIterByTag(element, -// "template"); //$NON-NLS-1$ -// while (it.hasNext()) { -// Element templateEle = it.next(); -// String resourcePath = templateEle.getAttribute("resource"); //$NON-NLS-1$ -// if (!"".equals(resourcePath)) { //$NON-NLS-1$ -// if (!resourcePath.startsWith("/")) { //$NON-NLS-1$ -// resourcePath = TEMPLATES_DIR + resourcePath; -// } -// URL url = findTemplateResource(bundle, resourcePath); -// if (url != null) { -// String name = templateEle.getAttribute("name"); //$NON-NLS-1$ -// if (name.startsWith("%")) { //$NON-NLS-1$ -// if (properties != null) { -// name = properties -// .getProperty(name.substring(1)); -// } else { -// name = null; -// } -// } -// if (name == null || "".equals(name)) { //$NON-NLS-1$ -// name = FileUtils -// .getNoExtensionFileName(resourcePath); -// } -// templates.add(new URLTemplateDescriptor(url, name)); -// } -// } -// } -// } -// } -// } -// -// private URL findTemplateResource(Bundle bundle, String resourcePath) { -// return FileLocator.find(bundle, new Path("$nl$/" + resourcePath), null); //$NON-NLS-1$ -// } -// -// private java.util.Properties getTemplateListProperties(Bundle bundle) { -// URL propURL = ResourceFinder.findResource(bundle, TEMPLATES_DIR, -// "templates", ".properties"); //$NON-NLS-1$ //$NON-NLS-2$ -// if (propURL != null) { -// try { -// InputStream is = propURL.openStream(); -// try { -// java.util.Properties properties = new java.util.Properties(); -// properties.load(is); -// return properties; -// } finally { -// is.close(); -// } -// } catch (IOException e) { -// } -// } -// return null; -// } -// -// private Element getTemplateListElement(Bundle bundle) { -// URL xmlURL = FileLocator.find(bundle, -// new Path(TEMPLATES_DIR + "templates.xml"), null); //$NON-NLS-1$ -// if (xmlURL == null) -// return null; -// try { -// InputStream is = xmlURL.openStream(); -// if (is != null) { -// try { -// Document doc = DOMUtils.loadDocument(is); -// if (doc != null) -// return doc.getDocumentElement(); -// } finally { -// is.close(); -// } -// } -// } catch (Throwable e) { -// } -// return null; -// } -// -// protected File createNonConflictingFile(File rootDir, String fileName) { -// int dotIndex = fileName.lastIndexOf('.'); -// String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); -// String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ -// File targetFile = new File(rootDir, fileName); -// int i = 1; -// while (targetFile.exists()) { -// i++; -// targetFile = new File(rootDir, -// String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ -// } -// return targetFile; -// } -// -// public ITemplateDescriptor loadTemplate(String symbolicName) { -// if (symbolicName == null || "".equals(symbolicName)) //$NON-NLS-1$ -// return null; -// if (symbolicName.startsWith("theme:")) { //$NON-NLS-1$ -// IStyle theme = findTheme(symbolicName.substring(6)); -// if (theme != null) { -// return new ThemeTemplateDescriptor(theme); -// } -// return null; -// } else if (symbolicName.startsWith("file:")) { //$NON-NLS-1$ -// String path = symbolicName.substring(5); -// File file = new File(path); -// if (file.isFile() && file.canRead()) { -// return new FileTemplateDescriptor(file); -// } -// return null; -// } else if (symbolicName.startsWith("default:")) { //$NON-NLS-1$ -// String id = symbolicName.substring(8); -// return new DefaultTemplateDescriptor(id, ""); //$NON-NLS-1$ -// } else { -// return loadTemplateFromURL(symbolicName); -// } -// } -// -// private ITemplateDescriptor loadTemplateFromURL(String uri) { -// try { -// URL url = new URL(uri); -// return new URLTemplateDescriptor(url, ""); //$NON-NLS-1$ -// } catch (MalformedURLException e) { -// } -// return null; -// } -// -// private IStyle findTheme(String themeId) { -// IResourceManager resourceManager = MindMapUI.getResourceManager(); -// if ("blank".equals(themeId)) { //$NON-NLS-1$ -// return resourceManager.getBlankTheme(); -// } -// IStyleSheet systemThemeSheet = resourceManager.getSystemThemeSheet(); -// IStyle style = systemThemeSheet.findStyle(themeId); -// if (style != null) -// return style; -// IStyleSheet userThemeSheet = resourceManager.getUserThemeSheet(); -// return userThemeSheet.findStyle(themeId); -// } -// -// public static MindMapTemplateManager getInstance() { -// return instance; -// } -// -} +/* ****************************************************************************** + * Copyright (c) 2006-2010 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal; + +/** + * @author Frank Shaka + * @deprecated Use MindMapUI.getResourceManager() + */ +@Deprecated +public class MindMapTemplateManager { + +// private static final MindMapTemplateManager instance = new MindMapTemplateManager(); +// +// private static final String DEFAULT_TEMPLATE_ID = "org.xmind.ui.template.default"; //$NON-NLS-1$ +// +// private static final String TEMPLATES_PATH = "templates"; //$NON-NLS-1$ +// private static final String TEMPLATES_DIR = TEMPLATES_PATH + "/"; //$NON-NLS-1$ +// +// private List listeners = new ArrayList(); +// +// private MindMapTemplateManager() { +// } +// +// public void addTemplateManagerListener(ITemplateManagerListener listener) { +// listeners.add(listener); +// } +// +// public void removeTemplateManagerListener( +// ITemplateManagerListener listener) { +// listeners.remove(listener); +// } +// +// private void fireTemplateAdded(ITemplateDescriptor template) { +// for (Object listener : listeners.toArray()) { +// try { +// ((ITemplateManagerListener) listener).templateAdded(template); +// } catch (Throwable e) { +// Logger.log(e); +// } +// } +// } +// +// private void fireTemplateRemoved(ITemplateDescriptor template) { +// for (Object listener : listeners.toArray()) { +// try { +// ((ITemplateManagerListener) listener).templateRemoved(template); +// } catch (Throwable e) { +// Logger.log(e); +// } +// } +// } +// +// public List importTemplates(String... fileNames) { +// List importedTemplates = new ArrayList( +// fileNames.length); +// for (String fileName : fileNames) { +// ITemplateDescriptor template = importCustomTemplate(fileName); +// if (template != null) { +// importedTemplates.add(template); +// } +// } +// return importedTemplates; +// } +// +// public ITemplateDescriptor importCustomTemplate(IWorkbook workbook, +// String name) { +// if (!name.endsWith(MindMapUI.FILE_EXT_TEMPLATE) +// && !name.endsWith(MindMapUI.FILE_EXT_XMIND)) { +// name = name + MindMapUI.FILE_EXT_TEMPLATE; +// } +// File targetFile = createCustomTemplateOutputFile(name); +// IWorkbookRef wr = MindMapUIPlugin.getDefault().getWorkbookRefFactory() +// .createWorkbookRef(targetFile.toURI(), null); +// if (wr == null) +// return null; +// +// final boolean[] finished = new boolean[1]; +// finished[0] = false; +// wr.importFrom(new PreLoadedWorkbookRef(workbook, null), +// new IEditableOperationCallback() { +// public void handleCompletion(boolean successful, +// IEditableStatus status) { +// finished[0] = true; +// } +// }); +// +// try { +// while (!finished[0]) { +// Thread.sleep(0); +// } +// } catch (InterruptedException e) { +// return null; +// } +// if (!wr.exists()) +// return null; +// +// FileTemplateDescriptor template = new FileTemplateDescriptor( +// targetFile); +// fireTemplateAdded(template); +// return template; +// } +// +// public ITemplateDescriptor importCustomTemplate(String path) { +// File sourceFile = new File(path); +// String fileName = sourceFile.getName(); +// File targetFile = createCustomTemplateOutputFile(fileName); +// try { +// FileUtils.copy(sourceFile, targetFile); +// FileTemplateDescriptor template = new FileTemplateDescriptor( +// targetFile); +// fireTemplateAdded(template); +// return template; +// } catch (IOException e) { +// } +// return null; +// } +// +// private File createCustomTemplateOutputFile(String fileName) { +// String dirPath = getCustomTemplatesLocation(); +// File dir = new File(dirPath); +// FileUtils.ensureDirectory(dir); +// return createNonConflictingFile(dir, fileName); +// } +// +// public boolean removeTemplate(ITemplateDescriptor template) { +// if (template instanceof FileTemplateDescriptor) { +// File file = ((FileTemplateDescriptor) template).getFile(); +// if (file.delete()) { +// fireTemplateRemoved(template); +// return true; +// } +// } +// return false; +// } +// +// public List loadAllTemplates() { +// List templates = new ArrayList(); +// loadDefaultTemplates(templates); +// loadSystemTemplates(templates); +// loadCustomTemplates(templates); +// return templates; +// } +// +// public List loadDefaultTemplates() { +// List templates = new ArrayList(); +// loadDefaultTemplates(templates); +// return templates; +// } +// +// public List loadSystemTemplates() { +// List templates = new ArrayList(); +// loadSystemTemplates(templates); +// return templates; +// } +// +// public List loadCustomTemplates() { +// List templates = new ArrayList(); +// loadCustomTemplates(templates); +// return templates; +// } +// +// private void loadDefaultTemplates(List templates) { +// templates.add(new DefaultTemplateDescriptor(DEFAULT_TEMPLATE_ID, +// WizardMessages.ChooseTemplateWizardPage_BlankMap_title)); +// } +// +// private void loadCustomTemplates(List templates) { +// String templatesDir = getCustomTemplatesLocation(); +// loadTemplatesFromDir(templates, new File(templatesDir)); +// } +// +// private String getCustomTemplatesLocation() { +// return Core.getWorkspace().getAbsolutePath(TEMPLATES_PATH); +// } +// +// private void loadTemplatesFromDir(List templates, +// File templatesDir) { +// List list = new ArrayList(); +// if (templatesDir != null && templatesDir.isDirectory()) { +// for (String fileName : templatesDir.list()) { +// if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) +// || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { +// File file = new File(templatesDir, fileName); +// if (file.isFile() && file.canRead()) { +// list.add(new FileTemplateDescriptor(file)); +// } +// } +// } +// } +// Collections.sort(list, new Comparator() { +// public int compare(ITemplateDescriptor t1, ITemplateDescriptor t2) { +// File f1 = ((FileTemplateDescriptor) t1).getFile(); +// File f2 = ((FileTemplateDescriptor) t2).getFile(); +// return (int) (f1.lastModified() - f2.lastModified()); +// } +// }); +// templates.addAll(list); +// } +// +// private void loadSystemTemplates(List templates) { +// Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); +// if (bundle != null) { +// Element element = getTemplateListElement(bundle); +// if (element != null) { +// java.util.Properties properties = getTemplateListProperties( +// bundle); +// Iterator it = DOMUtils.childElementIterByTag(element, +// "template"); //$NON-NLS-1$ +// while (it.hasNext()) { +// Element templateEle = it.next(); +// String resourcePath = templateEle.getAttribute("resource"); //$NON-NLS-1$ +// if (!"".equals(resourcePath)) { //$NON-NLS-1$ +// if (!resourcePath.startsWith("/")) { //$NON-NLS-1$ +// resourcePath = TEMPLATES_DIR + resourcePath; +// } +// URL url = findTemplateResource(bundle, resourcePath); +// if (url != null) { +// String name = templateEle.getAttribute("name"); //$NON-NLS-1$ +// if (name.startsWith("%")) { //$NON-NLS-1$ +// if (properties != null) { +// name = properties +// .getProperty(name.substring(1)); +// } else { +// name = null; +// } +// } +// if (name == null || "".equals(name)) { //$NON-NLS-1$ +// name = FileUtils +// .getNoExtensionFileName(resourcePath); +// } +// templates.add(new URLTemplateDescriptor(url, name)); +// } +// } +// } +// } +// } +// } +// +// private URL findTemplateResource(Bundle bundle, String resourcePath) { +// return FileLocator.find(bundle, new Path("$nl$/" + resourcePath), null); //$NON-NLS-1$ +// } +// +// private java.util.Properties getTemplateListProperties(Bundle bundle) { +// URL propURL = ResourceFinder.findResource(bundle, TEMPLATES_DIR, +// "templates", ".properties"); //$NON-NLS-1$ //$NON-NLS-2$ +// if (propURL != null) { +// try { +// InputStream is = propURL.openStream(); +// try { +// java.util.Properties properties = new java.util.Properties(); +// properties.load(is); +// return properties; +// } finally { +// is.close(); +// } +// } catch (IOException e) { +// } +// } +// return null; +// } +// +// private Element getTemplateListElement(Bundle bundle) { +// URL xmlURL = FileLocator.find(bundle, +// new Path(TEMPLATES_DIR + "templates.xml"), null); //$NON-NLS-1$ +// if (xmlURL == null) +// return null; +// try { +// InputStream is = xmlURL.openStream(); +// if (is != null) { +// try { +// Document doc = DOMUtils.loadDocument(is); +// if (doc != null) +// return doc.getDocumentElement(); +// } finally { +// is.close(); +// } +// } +// } catch (Throwable e) { +// } +// return null; +// } +// +// protected File createNonConflictingFile(File rootDir, String fileName) { +// int dotIndex = fileName.lastIndexOf('.'); +// String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); +// String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ +// File targetFile = new File(rootDir, fileName); +// int i = 1; +// while (targetFile.exists()) { +// i++; +// targetFile = new File(rootDir, +// String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ +// } +// return targetFile; +// } +// +// public ITemplateDescriptor loadTemplate(String symbolicName) { +// if (symbolicName == null || "".equals(symbolicName)) //$NON-NLS-1$ +// return null; +// if (symbolicName.startsWith("theme:")) { //$NON-NLS-1$ +// IStyle theme = findTheme(symbolicName.substring(6)); +// if (theme != null) { +// return new ThemeTemplateDescriptor(theme); +// } +// return null; +// } else if (symbolicName.startsWith("file:")) { //$NON-NLS-1$ +// String path = symbolicName.substring(5); +// File file = new File(path); +// if (file.isFile() && file.canRead()) { +// return new FileTemplateDescriptor(file); +// } +// return null; +// } else if (symbolicName.startsWith("default:")) { //$NON-NLS-1$ +// String id = symbolicName.substring(8); +// return new DefaultTemplateDescriptor(id, ""); //$NON-NLS-1$ +// } else { +// return loadTemplateFromURL(symbolicName); +// } +// } +// +// private ITemplateDescriptor loadTemplateFromURL(String uri) { +// try { +// URL url = new URL(uri); +// return new URLTemplateDescriptor(url, ""); //$NON-NLS-1$ +// } catch (MalformedURLException e) { +// } +// return null; +// } +// +// private IStyle findTheme(String themeId) { +// IResourceManager resourceManager = MindMapUI.getResourceManager(); +// if ("blank".equals(themeId)) { //$NON-NLS-1$ +// return resourceManager.getBlankTheme(); +// } +// IStyleSheet systemThemeSheet = resourceManager.getSystemThemeSheet(); +// IStyle style = systemThemeSheet.findStyle(themeId); +// if (style != null) +// return style; +// IStyleSheet userThemeSheet = resourceManager.getUserThemeSheet(); +// return userThemeSheet.findStyle(themeId); +// } +// +// public static MindMapTemplateManager getInstance() { +// return instance; +// } +// +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapUIPlugin.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapUIPlugin.java index 7e8e44a63..161e1e641 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapUIPlugin.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapUIPlugin.java @@ -1,278 +1,278 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; -import org.xmind.core.command.ICommandService; -import org.xmind.core.usagedata.IUsageDataSampler; -import org.xmind.ui.internal.editor.SaveWizardManager; -import org.xmind.ui.internal.editor.WorkbookRefFactoryManager; -import org.xmind.ui.internal.statushandlers.DefaultErrorReporter; -import org.xmind.ui.internal.statushandlers.IErrorReporter; -import org.xmind.ui.mindmap.IWorkbookRefFactory; - -public class MindMapUIPlugin extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "org.xmind.ui.mindmap"; //$NON-NLS-1$ - - public static final String OPTION_LOCAL_FILE_BACKUP = "/debug/save/localfile/backup"; //$NON-NLS-1$ - - // The shared instance. - private static MindMapUIPlugin plugin; - - private BundleContext bundleContext; - - private ServiceTracker commandServiceTracker = null; - - private ServiceTracker debugTracker = null; - - private Set jobs = new HashSet(); - - private WorkbookRefFactoryManager workbookRefFactory = null; - - private SaveWizardManager saveWizardManager = null; - - private ShareOptionRegistry shareOptionRegistry = null; - - private ServiceTracker usageDataTracker; - - private ServiceManager serviceManager = null; - - /** - * The constructor - */ - public MindMapUIPlugin() { - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. - * BundleContext ) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - - bundleContext = context; - - usageDataTracker = new ServiceTracker( - context, IUsageDataSampler.class, null); - usageDataTracker.open(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. - * BundleContext ) - */ - public void stop(BundleContext context) throws Exception { - cancelAllJobs(); - - if (commandServiceTracker != null) { - commandServiceTracker.close(); - commandServiceTracker = null; - } - - if (workbookRefFactory != null) { - workbookRefFactory.dispose(); - workbookRefFactory = null; - } - - if (saveWizardManager != null) { - saveWizardManager.dispose(); - saveWizardManager = null; - } - - usageDataTracker.close(); - usageDataTracker = null; - - bundleContext = null; - - plugin = null; - super.stop(context); - } - - public static void log(Throwable e, String message) { - if (message == null) - message = ""; //$NON-NLS-1$ - MindMapUIPlugin instance = getDefault(); - if (instance != null) { - Platform.getLog(instance.getBundle()) - .log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); - } else { - System.err.println(message); - e.printStackTrace(); - } - } - - public ICommandService getCommandService() { - if (commandServiceTracker == null) { - commandServiceTracker = new ServiceTracker( - getBundle().getBundleContext(), - ICommandService.class.getName(), null); - commandServiceTracker.open(); - } - return commandServiceTracker.getService(); - } - - public IUsageDataSampler getUsageDataCollector() { - IUsageDataSampler service = usageDataTracker == null ? null - : usageDataTracker.getService(); - return service == null ? IUsageDataSampler.NULL : service; - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static MindMapUIPlugin getDefault() { - return plugin; - } - - public IDialogSettings getDialogSettings(String sectionName) { - IDialogSettings ds = getDialogSettings(); - IDialogSettings section = ds.getSection(sectionName); - if (section == null) { - section = ds.addNewSection(sectionName); - } - return section; - } - - private DebugOptions getDebugOptions() { - if (debugTracker == null) { - debugTracker = new ServiceTracker( - getBundle().getBundleContext(), DebugOptions.class, null); - debugTracker.open(); - } - return debugTracker.getService(); - } - - /** - * Returns the debug switch for the specified option. - * - * @param option - * value like "/debug/some/feature" - * @return true if debugging is turned on for this option, or - * false otherwise - */ - public static boolean isDebugging(String option) { - return getDefault().getDebugOptions() - .getBooleanOption(PLUGIN_ID + option, false); - } - - public static T getAdapter(Object obj, Class adapter) { - Assert.isNotNull(adapter); - if (adapter.isInstance(obj)) - return adapter.cast(obj); - - if (obj instanceof IAdaptable) { - T result = ((IAdaptable) obj).getAdapter(adapter); - if (result != null) - return result; - } - - if (!(obj instanceof PlatformObject)) { - T result = Platform.getAdapterManager().getAdapter(obj, adapter); - if (result != null) - return result; - } - - return null; - } - - public void registerJob(Job job) { - jobs.add(job); - job.addJobChangeListener(new JobChangeAdapter() { - public void done(IJobChangeEvent event) { - super.done(event); - jobs.remove(event.getJob()); - } - }); - } - - private void cancelAllJobs() { - Object[] runningJobs = jobs.toArray(); - for (int i = 0; i < runningJobs.length; i++) { - ((Job) runningJobs[i]).cancel(); - } - } - - public synchronized IWorkbookRefFactory getWorkbookRefFactory() { - if (plugin == null) - throw new IllegalStateException( - "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ - if (workbookRefFactory == null) { - workbookRefFactory = new WorkbookRefFactoryManager(); - } - return workbookRefFactory; - } - - public synchronized SaveWizardManager getSaveWizardManager() { - if (plugin == null) - throw new IllegalStateException( - "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ - if (saveWizardManager == null) { - saveWizardManager = new SaveWizardManager(); - } - return saveWizardManager; - } - - public synchronized ShareOptionRegistry getShareOptionRegistry() { - if (plugin == null) - throw new IllegalStateException( - "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ - if (shareOptionRegistry == null) { - shareOptionRegistry = new ShareOptionRegistry(); - } - return shareOptionRegistry; - } - - public Bundle findBundle(long bundleId) { - return bundleContext == null ? null : bundleContext.getBundle(bundleId); - } - - /** - * @return - */ - public IErrorReporter getErrorReporter() { - IErrorReporter service = serviceManager == null ? null - : serviceManager.getErrorReporter(); - return service == null ? DefaultErrorReporter.getInstance() : service; - } - - void setServiceManager(ServiceManager serviceManager) { - this.serviceManager = serviceManager; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; +import org.xmind.core.command.ICommandService; +import org.xmind.core.usagedata.IUsageDataSampler; +import org.xmind.ui.internal.editor.SaveWizardManager; +import org.xmind.ui.internal.editor.WorkbookRefFactoryManager; +import org.xmind.ui.internal.statushandlers.DefaultErrorReporter; +import org.xmind.ui.internal.statushandlers.IErrorReporter; +import org.xmind.ui.mindmap.IWorkbookRefFactory; + +public class MindMapUIPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.xmind.ui.mindmap"; //$NON-NLS-1$ + + public static final String OPTION_LOCAL_FILE_BACKUP = "/debug/save/localfile/backup"; //$NON-NLS-1$ + + // The shared instance. + private static MindMapUIPlugin plugin; + + private BundleContext bundleContext; + + private ServiceTracker commandServiceTracker = null; + + private ServiceTracker debugTracker = null; + + private Set jobs = new HashSet(); + + private WorkbookRefFactoryManager workbookRefFactory = null; + + private SaveWizardManager saveWizardManager = null; + + private ShareOptionRegistry shareOptionRegistry = null; + + private ServiceTracker usageDataTracker; + + private ServiceManager serviceManager = null; + + /** + * The constructor + */ + public MindMapUIPlugin() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. + * BundleContext ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + bundleContext = context; + + usageDataTracker = new ServiceTracker( + context, IUsageDataSampler.class, null); + usageDataTracker.open(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. + * BundleContext ) + */ + public void stop(BundleContext context) throws Exception { + cancelAllJobs(); + + if (commandServiceTracker != null) { + commandServiceTracker.close(); + commandServiceTracker = null; + } + + if (workbookRefFactory != null) { + workbookRefFactory.dispose(); + workbookRefFactory = null; + } + + if (saveWizardManager != null) { + saveWizardManager.dispose(); + saveWizardManager = null; + } + + usageDataTracker.close(); + usageDataTracker = null; + + bundleContext = null; + + plugin = null; + super.stop(context); + } + + public static void log(Throwable e, String message) { + if (message == null) + message = ""; //$NON-NLS-1$ + MindMapUIPlugin instance = getDefault(); + if (instance != null) { + Platform.getLog(instance.getBundle()) + .log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } else { + System.err.println(message); + e.printStackTrace(); + } + } + + public ICommandService getCommandService() { + if (commandServiceTracker == null) { + commandServiceTracker = new ServiceTracker( + getBundle().getBundleContext(), + ICommandService.class.getName(), null); + commandServiceTracker.open(); + } + return commandServiceTracker.getService(); + } + + public IUsageDataSampler getUsageDataCollector() { + IUsageDataSampler service = usageDataTracker == null ? null + : usageDataTracker.getService(); + return service == null ? IUsageDataSampler.NULL : service; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static MindMapUIPlugin getDefault() { + return plugin; + } + + public IDialogSettings getDialogSettings(String sectionName) { + IDialogSettings ds = getDialogSettings(); + IDialogSettings section = ds.getSection(sectionName); + if (section == null) { + section = ds.addNewSection(sectionName); + } + return section; + } + + private DebugOptions getDebugOptions() { + if (debugTracker == null) { + debugTracker = new ServiceTracker( + getBundle().getBundleContext(), DebugOptions.class, null); + debugTracker.open(); + } + return debugTracker.getService(); + } + + /** + * Returns the debug switch for the specified option. + * + * @param option + * value like "/debug/some/feature" + * @return true if debugging is turned on for this option, or + * false otherwise + */ + public static boolean isDebugging(String option) { + return getDefault().getDebugOptions() + .getBooleanOption(PLUGIN_ID + option, false); + } + + public static T getAdapter(Object obj, Class adapter) { + Assert.isNotNull(adapter); + if (adapter.isInstance(obj)) + return adapter.cast(obj); + + if (obj instanceof IAdaptable) { + T result = ((IAdaptable) obj).getAdapter(adapter); + if (result != null) + return result; + } + + if (!(obj instanceof PlatformObject)) { + T result = Platform.getAdapterManager().getAdapter(obj, adapter); + if (result != null) + return result; + } + + return null; + } + + public void registerJob(Job job) { + jobs.add(job); + job.addJobChangeListener(new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + super.done(event); + jobs.remove(event.getJob()); + } + }); + } + + private void cancelAllJobs() { + Object[] runningJobs = jobs.toArray(); + for (int i = 0; i < runningJobs.length; i++) { + ((Job) runningJobs[i]).cancel(); + } + } + + public synchronized IWorkbookRefFactory getWorkbookRefFactory() { + if (plugin == null) + throw new IllegalStateException( + "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ + if (workbookRefFactory == null) { + workbookRefFactory = new WorkbookRefFactoryManager(); + } + return workbookRefFactory; + } + + public synchronized SaveWizardManager getSaveWizardManager() { + if (plugin == null) + throw new IllegalStateException( + "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ + if (saveWizardManager == null) { + saveWizardManager = new SaveWizardManager(); + } + return saveWizardManager; + } + + public synchronized ShareOptionRegistry getShareOptionRegistry() { + if (plugin == null) + throw new IllegalStateException( + "Plugin already stopped: " + PLUGIN_ID); //$NON-NLS-1$ + if (shareOptionRegistry == null) { + shareOptionRegistry = new ShareOptionRegistry(); + } + return shareOptionRegistry; + } + + public Bundle findBundle(long bundleId) { + return bundleContext == null ? null : bundleContext.getBundle(bundleId); + } + + /** + * @return + */ + public IErrorReporter getErrorReporter() { + IErrorReporter service = serviceManager == null ? null + : serviceManager.getErrorReporter(); + return service == null ? DefaultErrorReporter.getInstance() : service; + } + + void setServiceManager(ServiceManager serviceManager) { + this.serviceManager = serviceManager; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapWordContextProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapWordContextProvider.java index 5d9e51ac0..6f7ce7659 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapWordContextProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMapWordContextProvider.java @@ -1,498 +1,498 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.text.IFindReplaceTarget; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.IBoundary; -import org.xmind.core.INotes; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISheetComponent; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.IWordContext; -import org.xmind.ui.IWordContextProvider; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -/** - * @author Frank Shaka - */ -public class MindMapWordContextProvider implements IWordContextProvider { - - private class TopicWordContext implements IWordContext { - - private ITopic topic; - - private static final String TYPE = "topic"; //$NON-NLS-1$ - - public TopicWordContext(ITopic topic) { - this.topic = topic; - } - - public String getContent() { - return topic.getTitleText(); - } - - public ImageDescriptor getIcon() { - return MindMapUI.getImages().getTopicIcon(topic, true); - } - - public String getName() { - return topic.getTitleText(); - } - - public boolean replaceWord(int start, int length, String replacement) { - return replaceText(topic, replaceString(topic.getTitleText(), start, - length, replacement)); - } - - public void reveal() { - revealElement(topic, false); - } - - public void revealWord(int start, int length) { - revealInvalidWord(topic, start, length, GEF.REQ_EDIT); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof TopicWordContext) - if (this.topic != null - && this.topic.equals(((TopicWordContext) obj).topic)) - return true; - return false; - } - - @Override - public int hashCode() { - int result = 17; - result += result * topic.hashCode(); - result += result * TYPE.hashCode(); - return result; - } - - } - - private class LabelWordContext implements IWordContext { - - private ITopic topic; - - private static final String TYPE = "label"; //$NON-NLS-1$ - - public LabelWordContext(ITopic topic) { - super(); - this.topic = topic; - } - - public String getContent() { - return MindMapUtils.getLabelText(topic.getLabels()); - } - - public ImageDescriptor getIcon() { - return MindMapUI.getImages().get(IMindMapImages.LABEL, true); - } - - public String getName() { - return NLS.bind(MindMapMessages.WordContext_Label_pattern, - topic.getTitleText()); - } - - public boolean replaceWord(int start, int length, String replacement) { - return replaceText(topic, - replaceString(MindMapUtils.getLabelText(topic.getLabels()), - start, length, replacement), - MindMapUI.REQ_MODIFY_LABEL); - } - - public void reveal() { - editor.getSite().getSelectionProvider() - .setSelection(new StructuredSelection(topic)); - } - - public void revealWord(int start, int length) { - revealInvalidWord(topic, start, length, MindMapUI.REQ_EDIT_LABEL); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof LabelWordContext) - if (this.topic != null - && this.topic.equals(((LabelWordContext) obj).topic)) - return true; - return false; - } - - @Override - public int hashCode() { - int result = 17; - result += result * topic.hashCode(); - result += result * TYPE.hashCode(); - return result; - } - } - - private class NotesWordContext implements IWordContext { - - private ITopic topic; - - private static final String TYPE = "notes"; //$NON-NLS-1$ - - public NotesWordContext(ITopic topic) { - super(); - this.topic = topic; - } - - public String getContent() { - IPlainNotesContent plainNotesContent = (IPlainNotesContent) topic - .getNotes().getContent(INotes.PLAIN); - if (plainNotesContent == null) - return ""; //$NON-NLS-1$ - return plainNotesContent.getTextContent(); - } - - public ImageDescriptor getIcon() { - return MindMapUI.getImages().get(IMindMapImages.NOTES, true); - } - - public String getName() { - return NLS.bind(MindMapMessages.WordContext_Notes_pattern, - topic.getTitleText()); - } - - public boolean replaceWord(int start, int length, String replacement) { - revealWord(start, length); - - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - MPart part = E4Utils.findPart(window, - IModelConstants.PART_ID_NOTES); - - if (part != null) { - Object obj = part.getObject(); - if (obj instanceof IAdaptable) { - ITextViewer viewer = (ITextViewer) ((IAdaptable) obj) - .getAdapter(ITextViewer.class); - if (viewer != null) { - String toFind = viewer.getTextWidget().getText(start, - start + length - 1); - - IFindReplaceTarget target = (IFindReplaceTarget) ((IAdaptable) obj) - .getAdapter(IFindReplaceTarget.class); - if (target != null) { - int r = target.findAndSelect(start, toFind, true, - true, false); - if (r > -1) { - target.replaceSelection(replacement); - return true; - } - } - } - } - } - return false; - } - - public void reveal() { - revealElement(topic, false); - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - - if (window != null) - E4Utils.showPart( - IModelConstants.COMMAND_SHOW_MODEL_PART, window, - IModelConstants.PART_ID_NOTES, null, - IModelConstants.PART_STACK_ID_RIGHT); - } - }); - } - - public void revealWord(int start, int length) { - reveal(); - - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - MPart part = E4Utils.findPart(window, - IModelConstants.PART_ID_NOTES); - - if (part != null) { - Object obj = part.getObject(); - if (obj instanceof IAdaptable) { - ITextViewer viewer = (ITextViewer) ((IAdaptable) obj) - .getAdapter(ITextViewer.class); - if (viewer != null) { - viewer.setSelectedRange(start, length); - } - } - } - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof NotesWordContext) - if (this.topic != null - && this.topic.equals(((NotesWordContext) obj).topic)) - return true; - return false; - } - - @Override - public int hashCode() { - int result = 17; - result += result * topic.hashCode(); - result += result * TYPE.hashCode(); - return result; - } - } - - private class BoundaryWordContext implements IWordContext { - - private IBoundary boundary; - - public BoundaryWordContext(IBoundary boundary) { - this.boundary = boundary; - } - - public String getContent() { - return boundary.getTitleText(); - } - - public ImageDescriptor getIcon() { - return MindMapUI.getImages().getElementIcon(boundary, true); - } - - public String getName() { - return boundary.getTitleText(); - } - - public boolean replaceWord(int start, int length, String replacement) { - return replaceText(boundary, replaceString(boundary.getTitleText(), - start, length, replacement)); - } - - public void reveal() { - revealElement(boundary, false); - } - - public void revealWord(int start, int length) { - revealInvalidWord(boundary, start, length, GEF.REQ_EDIT); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof BoundaryWordContext) - if (this.boundary != null && this.boundary - .equals(((BoundaryWordContext) obj).boundary)) - return true; - return false; - } - - @Override - public int hashCode() { - return 17 * boundary.hashCode(); - } - - } - - private class RelationshipWordContext implements IWordContext { - - private IRelationship relationship; - - public RelationshipWordContext(IRelationship relationship) { - this.relationship = relationship; - } - - public String getContent() { - return relationship.getTitleText(); - } - - public ImageDescriptor getIcon() { - return MindMapUI.getImages().getElementIcon(relationship, true); - } - - public String getName() { - return relationship.getTitleText(); - } - - public boolean replaceWord(int start, int length, String replacement) { - return replaceText(relationship, replaceString( - relationship.getTitleText(), start, length, replacement)); - } - - public void reveal() { - revealElement(relationship, false); - } - - public void revealWord(int start, int length) { - revealInvalidWord(relationship, start, length, GEF.REQ_EDIT); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof RelationshipWordContext) - if (this.relationship != null && this.relationship - .equals(((RelationshipWordContext) obj).relationship)) - return true; - return false; - } - - @Override - public int hashCode() { - return 17 * relationship.hashCode(); - } - - } - - private IGraphicalEditor editor; - - /** - * - */ - public MindMapWordContextProvider(IGraphicalEditor editor) { - this.editor = editor; - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.IWordContextProvider#getWordContexts() - */ - public List getWordContexts() { - List contexts = new ArrayList(); - IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); - if (workbook != null) { - for (ISheet sheet : workbook.getSheets()) { - getContexts(sheet.getRootTopic(), contexts); - for (IRelationship relationship : sheet.getRelationships()) { - contexts.add(new RelationshipWordContext(relationship)); - } - } - } - return contexts; - } - - private void getContexts(ITopic topic, List contexts) { - contexts.add(new TopicWordContext(topic)); - if (!topic.getLabels().isEmpty()) { - contexts.add(new LabelWordContext(topic)); - } - if (!topic.getNotes().isEmpty()) { - contexts.add(new NotesWordContext(topic)); - } - for (IBoundary boundary : topic.getBoundaries()) { - contexts.add(new BoundaryWordContext(boundary)); - } - for (ITopic child : topic.getAllChildren()) { - getContexts(child, contexts); - } - } - - private void revealElement(Object element, boolean makeActive) { - if (makeActive) { - editor.getSite().getPage().activate(editor); - } - editor.getSite().getSelectionProvider() - .setSelection(new StructuredSelection(element)); - } - - private void revealInvalidWord(ISheetComponent element, int start, - int length, String reqType) { - revealElement(element, true); - IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet()); - if (page != null) { - IGraphicalViewer viewer = page.getViewer(); - EditDomain domain = page.getEditDomain(); - IPart part = viewer.findPart(element); - if (part != null) { - Request request = new Request(reqType).setPrimaryTarget(part) - .setDomain(domain).setViewer(viewer) - .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE) - .setParameter(GEF.PARAM_TEXT_SELECTION, - new TextSelection(start, length)); - domain.handleRequest(request); - } - } - } - - private boolean replaceText(ISheetComponent element, String newText) { - return replaceText(element, newText, GEF.REQ_MODIFY); - } - - private boolean replaceText(ISheetComponent element, String newText, - String reqType) { - revealElement(element, false); - IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet()); - if (page != null) { - IGraphicalViewer viewer = page.getViewer(); - EditDomain domain = page.getEditDomain(); - IPart part = viewer.findPart(element); - if (part != null) { - Request request = new Request(reqType).setPrimaryTarget(part) - .setDomain(domain).setViewer(viewer) - .setParameter(GEF.PARAM_TEXT, newText); - domain.handleRequest(request); - return true; - } - } - return false; - } - - private static String replaceString(String text, int start, int length, - String replacement) { - return text.substring(0, start) + replacement - + text.substring(start + length); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof MindMapWordContextProvider) { - MindMapWordContextProvider provider = (MindMapWordContextProvider) obj; - if (editor != null && editor.equals(provider.editor)) - return true; - } - return false; - } - - @Override - public int hashCode() { - return 17 * editor.hashCode(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.IFindReplaceTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.IBoundary; +import org.xmind.core.INotes; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISheetComponent; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.IWordContext; +import org.xmind.ui.IWordContextProvider; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +/** + * @author Frank Shaka + */ +public class MindMapWordContextProvider implements IWordContextProvider { + + private class TopicWordContext implements IWordContext { + + private ITopic topic; + + private static final String TYPE = "topic"; //$NON-NLS-1$ + + public TopicWordContext(ITopic topic) { + this.topic = topic; + } + + public String getContent() { + return topic.getTitleText(); + } + + public ImageDescriptor getIcon() { + return MindMapUI.getImages().getTopicIcon(topic, true); + } + + public String getName() { + return topic.getTitleText(); + } + + public boolean replaceWord(int start, int length, String replacement) { + return replaceText(topic, replaceString(topic.getTitleText(), start, + length, replacement)); + } + + public void reveal() { + revealElement(topic, false); + } + + public void revealWord(int start, int length) { + revealInvalidWord(topic, start, length, GEF.REQ_EDIT); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TopicWordContext) + if (this.topic != null + && this.topic.equals(((TopicWordContext) obj).topic)) + return true; + return false; + } + + @Override + public int hashCode() { + int result = 17; + result += result * topic.hashCode(); + result += result * TYPE.hashCode(); + return result; + } + + } + + private class LabelWordContext implements IWordContext { + + private ITopic topic; + + private static final String TYPE = "label"; //$NON-NLS-1$ + + public LabelWordContext(ITopic topic) { + super(); + this.topic = topic; + } + + public String getContent() { + return MindMapUtils.getLabelText(topic.getLabels()); + } + + public ImageDescriptor getIcon() { + return MindMapUI.getImages().get(IMindMapImages.LABEL, true); + } + + public String getName() { + return NLS.bind(MindMapMessages.WordContext_Label_pattern, + topic.getTitleText()); + } + + public boolean replaceWord(int start, int length, String replacement) { + return replaceText(topic, + replaceString(MindMapUtils.getLabelText(topic.getLabels()), + start, length, replacement), + MindMapUI.REQ_MODIFY_LABEL); + } + + public void reveal() { + editor.getSite().getSelectionProvider() + .setSelection(new StructuredSelection(topic)); + } + + public void revealWord(int start, int length) { + revealInvalidWord(topic, start, length, MindMapUI.REQ_EDIT_LABEL); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LabelWordContext) + if (this.topic != null + && this.topic.equals(((LabelWordContext) obj).topic)) + return true; + return false; + } + + @Override + public int hashCode() { + int result = 17; + result += result * topic.hashCode(); + result += result * TYPE.hashCode(); + return result; + } + } + + private class NotesWordContext implements IWordContext { + + private ITopic topic; + + private static final String TYPE = "notes"; //$NON-NLS-1$ + + public NotesWordContext(ITopic topic) { + super(); + this.topic = topic; + } + + public String getContent() { + IPlainNotesContent plainNotesContent = (IPlainNotesContent) topic + .getNotes().getContent(INotes.PLAIN); + if (plainNotesContent == null) + return ""; //$NON-NLS-1$ + return plainNotesContent.getTextContent(); + } + + public ImageDescriptor getIcon() { + return MindMapUI.getImages().get(IMindMapImages.NOTES, true); + } + + public String getName() { + return NLS.bind(MindMapMessages.WordContext_Notes_pattern, + topic.getTitleText()); + } + + public boolean replaceWord(int start, int length, String replacement) { + revealWord(start, length); + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + MPart part = E4Utils.findPart(window, + IModelConstants.PART_ID_NOTES); + + if (part != null) { + Object obj = part.getObject(); + if (obj instanceof IAdaptable) { + ITextViewer viewer = (ITextViewer) ((IAdaptable) obj) + .getAdapter(ITextViewer.class); + if (viewer != null) { + String toFind = viewer.getTextWidget().getText(start, + start + length - 1); + + IFindReplaceTarget target = (IFindReplaceTarget) ((IAdaptable) obj) + .getAdapter(IFindReplaceTarget.class); + if (target != null) { + int r = target.findAndSelect(start, toFind, true, + true, false); + if (r > -1) { + target.replaceSelection(replacement); + return true; + } + } + } + } + } + return false; + } + + public void reveal() { + revealElement(topic, false); + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + + if (window != null) + E4Utils.showPart( + IModelConstants.COMMAND_SHOW_MODEL_PART, window, + IModelConstants.PART_ID_NOTES, null, + IModelConstants.PART_STACK_ID_RIGHT); + } + }); + } + + public void revealWord(int start, int length) { + reveal(); + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + MPart part = E4Utils.findPart(window, + IModelConstants.PART_ID_NOTES); + + if (part != null) { + Object obj = part.getObject(); + if (obj instanceof IAdaptable) { + ITextViewer viewer = (ITextViewer) ((IAdaptable) obj) + .getAdapter(ITextViewer.class); + if (viewer != null) { + viewer.setSelectedRange(start, length); + } + } + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof NotesWordContext) + if (this.topic != null + && this.topic.equals(((NotesWordContext) obj).topic)) + return true; + return false; + } + + @Override + public int hashCode() { + int result = 17; + result += result * topic.hashCode(); + result += result * TYPE.hashCode(); + return result; + } + } + + private class BoundaryWordContext implements IWordContext { + + private IBoundary boundary; + + public BoundaryWordContext(IBoundary boundary) { + this.boundary = boundary; + } + + public String getContent() { + return boundary.getTitleText(); + } + + public ImageDescriptor getIcon() { + return MindMapUI.getImages().getElementIcon(boundary, true); + } + + public String getName() { + return boundary.getTitleText(); + } + + public boolean replaceWord(int start, int length, String replacement) { + return replaceText(boundary, replaceString(boundary.getTitleText(), + start, length, replacement)); + } + + public void reveal() { + revealElement(boundary, false); + } + + public void revealWord(int start, int length) { + revealInvalidWord(boundary, start, length, GEF.REQ_EDIT); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BoundaryWordContext) + if (this.boundary != null && this.boundary + .equals(((BoundaryWordContext) obj).boundary)) + return true; + return false; + } + + @Override + public int hashCode() { + return 17 * boundary.hashCode(); + } + + } + + private class RelationshipWordContext implements IWordContext { + + private IRelationship relationship; + + public RelationshipWordContext(IRelationship relationship) { + this.relationship = relationship; + } + + public String getContent() { + return relationship.getTitleText(); + } + + public ImageDescriptor getIcon() { + return MindMapUI.getImages().getElementIcon(relationship, true); + } + + public String getName() { + return relationship.getTitleText(); + } + + public boolean replaceWord(int start, int length, String replacement) { + return replaceText(relationship, replaceString( + relationship.getTitleText(), start, length, replacement)); + } + + public void reveal() { + revealElement(relationship, false); + } + + public void revealWord(int start, int length) { + revealInvalidWord(relationship, start, length, GEF.REQ_EDIT); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RelationshipWordContext) + if (this.relationship != null && this.relationship + .equals(((RelationshipWordContext) obj).relationship)) + return true; + return false; + } + + @Override + public int hashCode() { + return 17 * relationship.hashCode(); + } + + } + + private IGraphicalEditor editor; + + /** + * + */ + public MindMapWordContextProvider(IGraphicalEditor editor) { + this.editor = editor; + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.IWordContextProvider#getWordContexts() + */ + public List getWordContexts() { + List contexts = new ArrayList(); + IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); + if (workbook != null) { + for (ISheet sheet : workbook.getSheets()) { + getContexts(sheet.getRootTopic(), contexts); + for (IRelationship relationship : sheet.getRelationships()) { + contexts.add(new RelationshipWordContext(relationship)); + } + } + } + return contexts; + } + + private void getContexts(ITopic topic, List contexts) { + contexts.add(new TopicWordContext(topic)); + if (!topic.getLabels().isEmpty()) { + contexts.add(new LabelWordContext(topic)); + } + if (!topic.getNotes().isEmpty()) { + contexts.add(new NotesWordContext(topic)); + } + for (IBoundary boundary : topic.getBoundaries()) { + contexts.add(new BoundaryWordContext(boundary)); + } + for (ITopic child : topic.getAllChildren()) { + getContexts(child, contexts); + } + } + + private void revealElement(Object element, boolean makeActive) { + if (makeActive) { + editor.getSite().getPage().activate(editor); + } + editor.getSite().getSelectionProvider() + .setSelection(new StructuredSelection(element)); + } + + private void revealInvalidWord(ISheetComponent element, int start, + int length, String reqType) { + revealElement(element, true); + IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet()); + if (page != null) { + IGraphicalViewer viewer = page.getViewer(); + EditDomain domain = page.getEditDomain(); + IPart part = viewer.findPart(element); + if (part != null) { + Request request = new Request(reqType).setPrimaryTarget(part) + .setDomain(domain).setViewer(viewer) + .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE) + .setParameter(GEF.PARAM_TEXT_SELECTION, + new TextSelection(start, length)); + domain.handleRequest(request); + } + } + } + + private boolean replaceText(ISheetComponent element, String newText) { + return replaceText(element, newText, GEF.REQ_MODIFY); + } + + private boolean replaceText(ISheetComponent element, String newText, + String reqType) { + revealElement(element, false); + IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet()); + if (page != null) { + IGraphicalViewer viewer = page.getViewer(); + EditDomain domain = page.getEditDomain(); + IPart part = viewer.findPart(element); + if (part != null) { + Request request = new Request(reqType).setPrimaryTarget(part) + .setDomain(domain).setViewer(viewer) + .setParameter(GEF.PARAM_TEXT, newText); + domain.handleRequest(request); + return true; + } + } + return false; + } + + private static String replaceString(String text, int start, int length, + String replacement) { + return text.substring(0, start) + replacement + + text.substring(start + length); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MindMapWordContextProvider) { + MindMapWordContextProvider provider = (MindMapWordContextProvider) obj; + if (editor != null && editor.equals(provider.editor)) + return true; + } + return false; + } + + @Override + public int hashCode() { + return 17 * editor.hashCode(); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMappingServiceFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMappingServiceFactory.java index 930d16aa0..cf914110f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMappingServiceFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/MindMappingServiceFactory.java @@ -1,55 +1,55 @@ -package org.xmind.ui.internal; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.ui.services.AbstractServiceFactory; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.internal.editor.EditorHistoryImpl; -import org.xmind.ui.internal.editor.EditorHistoryPersistenceHelper; -import org.xmind.ui.internal.editor.EditorHistoryProxy; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class MindMappingServiceFactory extends AbstractServiceFactory { - - public MindMappingServiceFactory() { - } - - @Override - public Object create(Class serviceInterface, IServiceLocator parentLocator, - IServiceLocator locator) { - if (IEditorHistory.class.equals(serviceInterface)) { - return createEditorHistoryService(IEditorHistory.class, - parentLocator, locator); - } - return null; - } - - private IEditorHistory createEditorHistoryService( - Class serviceInterface, - IServiceLocator parentLocator, IServiceLocator locator) { - IEditorHistory parentService = parentLocator == null ? null - : parentLocator.getService(serviceInterface); - if (parentService == null) { - return createMasterEditorHistory(locator); - } else { - return new EditorHistoryProxy(parentService); - } - } - - /** - * @return - */ - private IEditorHistory createMasterEditorHistory(IServiceLocator locator) { - final IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); - final EditorHistoryPersistenceHelper loader = new EditorHistoryPersistenceHelper( - basePath); - final EditorHistoryImpl service = new EditorHistoryImpl(loader); - loader.setService(service); - return service; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.ui.services.AbstractServiceFactory; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.internal.editor.EditorHistoryImpl; +import org.xmind.ui.internal.editor.EditorHistoryPersistenceHelper; +import org.xmind.ui.internal.editor.EditorHistoryProxy; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class MindMappingServiceFactory extends AbstractServiceFactory { + + public MindMappingServiceFactory() { + } + + @Override + public Object create(Class serviceInterface, IServiceLocator parentLocator, + IServiceLocator locator) { + if (IEditorHistory.class.equals(serviceInterface)) { + return createEditorHistoryService(IEditorHistory.class, + parentLocator, locator); + } + return null; + } + + private IEditorHistory createEditorHistoryService( + Class serviceInterface, + IServiceLocator parentLocator, IServiceLocator locator) { + IEditorHistory parentService = parentLocator == null ? null + : parentLocator.getService(serviceInterface); + if (parentService == null) { + return createMasterEditorHistory(locator); + } else { + return new EditorHistoryProxy(parentService); + } + } + + /** + * @return + */ + private IEditorHistory createMasterEditorHistory(IServiceLocator locator) { + final IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); + final EditorHistoryPersistenceHelper loader = new EditorHistoryPersistenceHelper( + basePath); + final EditorHistoryImpl service = new EditorHistoryImpl(loader); + loader.setService(service); + return service; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ModelCacheManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ModelCacheManager.java index 00ecb171c..a5f0e5697 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ModelCacheManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ModelCacheManager.java @@ -1,72 +1,72 @@ -package org.xmind.ui.internal; - -import java.util.HashMap; -import java.util.Map; - -public final class ModelCacheManager { - - public static final String MODEL_CACHE_DELAYLAYOUT = "org.xmind.ui.delayLayout"; //$NON-NLS-1$ - - private static class ModelKeyWrapper { - private Object model; - private String key; - - public ModelKeyWrapper(Object model, String key) { - this.model = model; - this.key = key; - } - - @Override - public int hashCode() { - return model.hashCode() ^ key.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (obj == this) - return true; - if (!(obj instanceof ModelKeyWrapper)) - return false; - ModelKeyWrapper that = (ModelKeyWrapper) obj; - return this.model.equals(that.model) && this.key.equals(that.key); - } - } - - private static ModelCacheManager INSTANCE; - - private Map caches = null; - - public ModelCacheManager() { - } - - public void flush(Object model, String key) { - if (caches == null || model == null || key == null) - return; - caches.remove(new ModelKeyWrapper(model, key)); - } - - public Object getCache(Object model, String key) { - if (caches == null || model == null || key == null) - return null; - return caches.get(new ModelKeyWrapper(model, key)); - } - - public void setCache(Object model, String key, Object cache) { - if (model == null || key == null) - return; - if (caches == null) - caches = new HashMap(); - if (cache == null) - caches.remove(new ModelKeyWrapper(model, key)); - else - caches.put(new ModelKeyWrapper(model, key), cache); - } - - public static ModelCacheManager getInstance() { - if (INSTANCE == null) - INSTANCE = new ModelCacheManager(); - return INSTANCE; - } -} +package org.xmind.ui.internal; + +import java.util.HashMap; +import java.util.Map; + +public final class ModelCacheManager { + + public static final String MODEL_CACHE_DELAYLAYOUT = "org.xmind.ui.delayLayout"; //$NON-NLS-1$ + + private static class ModelKeyWrapper { + private Object model; + private String key; + + public ModelKeyWrapper(Object model, String key) { + this.model = model; + this.key = key; + } + + @Override + public int hashCode() { + return model.hashCode() ^ key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (obj == this) + return true; + if (!(obj instanceof ModelKeyWrapper)) + return false; + ModelKeyWrapper that = (ModelKeyWrapper) obj; + return this.model.equals(that.model) && this.key.equals(that.key); + } + } + + private static ModelCacheManager INSTANCE; + + private Map caches = null; + + public ModelCacheManager() { + } + + public void flush(Object model, String key) { + if (caches == null || model == null || key == null) + return; + caches.remove(new ModelKeyWrapper(model, key)); + } + + public Object getCache(Object model, String key) { + if (caches == null || model == null || key == null) + return null; + return caches.get(new ModelKeyWrapper(model, key)); + } + + public void setCache(Object model, String key, Object cache) { + if (model == null || key == null) + return; + if (caches == null) + caches = new HashMap(); + if (cache == null) + caches.remove(new ModelKeyWrapper(model, key)); + else + caches.put(new ModelKeyWrapper(model, key), cache); + } + + public static ModelCacheManager getInstance() { + if (INSTANCE == null) + INSTANCE = new ModelCacheManager(); + return INSTANCE; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/NumberFormatExtensionManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/NumberFormatExtensionManager.java index 81977fe9e..39cf3f202 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/NumberFormatExtensionManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/NumberFormatExtensionManager.java @@ -1,234 +1,234 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.xmind.ui.mindmap.INumberFormat; -import org.xmind.ui.mindmap.INumberFormatDescriptor; -import org.xmind.ui.mindmap.INumberFormatManager; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class NumberFormatExtensionManager extends RegistryReader - implements INumberFormatManager { - - private static class NumberFormatProxy - implements INumberFormat, INumberFormatDescriptor { - - private IConfigurationElement element; - - private String id; - - private String name; - - private String description; - - private INumberFormat implementation; - - private boolean failedInitImplementation = false; - - public NumberFormatProxy(IConfigurationElement element) - throws CoreException { - this.element = element; - this.id = element.getAttribute(RegistryConstants.ATT_ID); - this.name = element.getAttribute(RegistryConstants.ATT_NAME); - this.description = element - .getAttribute(RegistryConstants.ATT_DESCRIPTION); - if (getClassValue(element, RegistryConstants.ATT_CLASS) == null) - throw new CoreException(new Status(IStatus.ERROR, - element.getNamespaceIdentifier(), 0, - "Invalid extension (missing class name): " + id, //$NON-NLS-1$ - null)); - } - - private INumberFormat getImplementation() { - if (implementation == null && !failedInitImplementation) { - try { - implementation = (INumberFormat) element - .createExecutableExtension( - RegistryConstants.ATT_CLASS); - } catch (CoreException e) { - Logger.log(e, - "Failed to create number format from class: " //$NON-NLS-1$ - + getClassValue(element, - RegistryConstants.ATT_CLASS)); - failedInitImplementation = true; - } - } - return implementation; - } - - public String getText(int index) { - INumberFormat impl = getImplementation(); - if (impl != null) - return impl.getText(index); - return null; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - } - - private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ - - private static final String SIMPLECHINESEFORMAT = "org.xmind.numbering.simplechinese"; //$NON-NLS-1$ - - private static final String TRADITIONALCHINESEFORMAT = "org.xmind.numbering.traditionalchinese"; //$NON-NLS-1$ - - private Map formats = null; - - private List list = null; - - private Properties configIniProperties; - - /* package */ NumberFormatExtensionManager() { - } - - protected boolean readElement(IConfigurationElement element) { - String name = element.getName(); - if (RegistryConstants.TAG_FORMAT.equals(name)) { - readFormat(element); - return true; - } - return false; - } - - private void readFormat(IConfigurationElement element) { - NumberFormatProxy proxy; - try { - proxy = new NumberFormatProxy(element); - } catch (CoreException e) { - Logger.log(e, "Failed to load numbering format: " + element); //$NON-NLS-1$ - return; - } - String id = proxy.getId(); - if (configIniProperties == null) - configIniProperties = loadProperties(getConfigFile()); - /// "zh_CN", "zh_TW" - if (SIMPLECHINESEFORMAT.equals(id) && !"zh_CN" //$NON-NLS-1$ - .equals(configIniProperties.getProperty(LANGUAGE_OSGI_NL_KEY))) - return; - - if (TRADITIONALCHINESEFORMAT.equals(id) && !"zh_TW" //$NON-NLS-1$ - .equals(configIniProperties.getProperty(LANGUAGE_OSGI_NL_KEY))) - return; - - if (formats == null) - formats = new HashMap(); - formats.put(proxy.getId(), proxy); - if (list == null) - list = new ArrayList(); - list.add(proxy); - } - - private void ensureLoaded() { - if (formats != null && list != null) - return; - lazyLoad(); - if (formats == null) - formats = Collections.emptyMap(); - if (list == null) - list = Collections.emptyList(); - } - - private void lazyLoad() { - readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, - RegistryConstants.EXT_NUMBER_FORMATS); - } - - public INumberFormatDescriptor getDescriptor(String formatId) { - ensureLoaded(); - return formats.get(formatId); - } - - public List getDescriptors() { - ensureLoaded(); - return list; - } - - public INumberFormat getFormat(String formatId) { - ensureLoaded(); - return formats.get(formatId); - } - - public String getNumberText(String formatId, int index) { - INumberFormat format = getFormat(formatId); - if (format != null) - return format.getText(index); - return null; - } - - private Properties loadProperties(File file) { - if (file != null && file.exists() && file.canRead()) { - try { - InputStream stream = new BufferedInputStream( - new FileInputStream(file), 1024); - try { - Properties properties = new Properties(); - properties.load(stream); - return properties; - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - } - } - return null; - } - - private File getConfigFile() { - URL configDir = Platform.getConfigurationLocation().getURL(); - try { - URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ - File file = new File(configIni.getFile()); - return file; - } catch (MalformedURLException e) { - e.printStackTrace(); - } - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.xmind.ui.mindmap.INumberFormat; +import org.xmind.ui.mindmap.INumberFormatDescriptor; +import org.xmind.ui.mindmap.INumberFormatManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class NumberFormatExtensionManager extends RegistryReader + implements INumberFormatManager { + + private static class NumberFormatProxy + implements INumberFormat, INumberFormatDescriptor { + + private IConfigurationElement element; + + private String id; + + private String name; + + private String description; + + private INumberFormat implementation; + + private boolean failedInitImplementation = false; + + public NumberFormatProxy(IConfigurationElement element) + throws CoreException { + this.element = element; + this.id = element.getAttribute(RegistryConstants.ATT_ID); + this.name = element.getAttribute(RegistryConstants.ATT_NAME); + this.description = element + .getAttribute(RegistryConstants.ATT_DESCRIPTION); + if (getClassValue(element, RegistryConstants.ATT_CLASS) == null) + throw new CoreException(new Status(IStatus.ERROR, + element.getNamespaceIdentifier(), 0, + "Invalid extension (missing class name): " + id, //$NON-NLS-1$ + null)); + } + + private INumberFormat getImplementation() { + if (implementation == null && !failedInitImplementation) { + try { + implementation = (INumberFormat) element + .createExecutableExtension( + RegistryConstants.ATT_CLASS); + } catch (CoreException e) { + Logger.log(e, + "Failed to create number format from class: " //$NON-NLS-1$ + + getClassValue(element, + RegistryConstants.ATT_CLASS)); + failedInitImplementation = true; + } + } + return implementation; + } + + public String getText(int index) { + INumberFormat impl = getImplementation(); + if (impl != null) + return impl.getText(index); + return null; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + } + + private static final String LANGUAGE_OSGI_NL_KEY = "osgi.nl"; //$NON-NLS-1$ + + private static final String SIMPLECHINESEFORMAT = "org.xmind.numbering.simplechinese"; //$NON-NLS-1$ + + private static final String TRADITIONALCHINESEFORMAT = "org.xmind.numbering.traditionalchinese"; //$NON-NLS-1$ + + private Map formats = null; + + private List list = null; + + private Properties configIniProperties; + + /* package */ NumberFormatExtensionManager() { + } + + protected boolean readElement(IConfigurationElement element) { + String name = element.getName(); + if (RegistryConstants.TAG_FORMAT.equals(name)) { + readFormat(element); + return true; + } + return false; + } + + private void readFormat(IConfigurationElement element) { + NumberFormatProxy proxy; + try { + proxy = new NumberFormatProxy(element); + } catch (CoreException e) { + Logger.log(e, "Failed to load numbering format: " + element); //$NON-NLS-1$ + return; + } + String id = proxy.getId(); + if (configIniProperties == null) + configIniProperties = loadProperties(getConfigFile()); + /// "zh_CN", "zh_TW" + if (SIMPLECHINESEFORMAT.equals(id) && !"zh_CN" //$NON-NLS-1$ + .equals(configIniProperties.getProperty(LANGUAGE_OSGI_NL_KEY))) + return; + + if (TRADITIONALCHINESEFORMAT.equals(id) && !"zh_TW" //$NON-NLS-1$ + .equals(configIniProperties.getProperty(LANGUAGE_OSGI_NL_KEY))) + return; + + if (formats == null) + formats = new HashMap(); + formats.put(proxy.getId(), proxy); + if (list == null) + list = new ArrayList(); + list.add(proxy); + } + + private void ensureLoaded() { + if (formats != null && list != null) + return; + lazyLoad(); + if (formats == null) + formats = Collections.emptyMap(); + if (list == null) + list = Collections.emptyList(); + } + + private void lazyLoad() { + readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, + RegistryConstants.EXT_NUMBER_FORMATS); + } + + public INumberFormatDescriptor getDescriptor(String formatId) { + ensureLoaded(); + return formats.get(formatId); + } + + public List getDescriptors() { + ensureLoaded(); + return list; + } + + public INumberFormat getFormat(String formatId) { + ensureLoaded(); + return formats.get(formatId); + } + + public String getNumberText(String formatId, int index) { + INumberFormat format = getFormat(formatId); + if (format != null) + return format.getText(index); + return null; + } + + private Properties loadProperties(File file) { + if (file != null && file.exists() && file.canRead()) { + try { + InputStream stream = new BufferedInputStream( + new FileInputStream(file), 1024); + try { + Properties properties = new Properties(); + properties.load(stream); + return properties; + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + } + } + return null; + } + + private File getConfigFile() { + URL configDir = Platform.getConfigurationLocation().getURL(); + try { + URL configIni = new URL(configDir, "config.ini"); //$NON-NLS-1$ + File file = new File(configIni.getFile()); + return file; + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/RegistryConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/RegistryConstants.java index 38802b5d8..fc0d98456 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/RegistryConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/RegistryConstants.java @@ -1,126 +1,126 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; - -public class RegistryConstants implements IWorkbenchRegistryConstants { - - // ==================================== - // Branch Policies Extension Point - // ------------------------------------ - public static final String EXT_BRANCH_POLICIES = "branchPolicies"; //$NON-NLS-1$ - - public static final String TAG_BRANCH_POLICY = "branchPolicy"; //$NON-NLS-1$ - public static final String TAG_STRUCTURE = "structure"; //$NON-NLS-1$ - public static final String TAG_ADDITIONAL_STRUCTURES = "additionalStructures"; //$NON-NLS-1$ - public static final String TAG_ADDITIONAL_STRUCTURE = "additionalStructure"; //$NON-NLS-1$ - public static final String TAG_PROPERTY_TESTER = "propertyTester"; //$NON-NLS-1$ - public static final String TAG_BRANCH_HOOK = "branchHook"; //$NON-NLS-1$ - public static final String TAG_STYLE_SELECTOR = "styleSelector"; //$NON-NLS-1$ - public static final String TAG_OVERRIDED_STYLE = "overridedStyle"; //$NON-NLS-1$ -// public static final String TAG_INHERITED_STYLE = "inheritedStyle"; //$NON-NLS-1$ - public static final String TAG_UNMODIFIABLE_PROPERTIES = "unmodifiableProperties"; //$NON-NLS-1$ - public static final String TAG_UNMODIFIABLE_PROPERTY = "unmodifiableProperty"; //$NON-NLS-1$ - public static final String TAG_STYLE_VALUE_PROVIDER = "styleValueProvider"; //$NON-NLS-1$ - public static final String TAG_LAYER = "layer"; //$NON-NLS-1$ - public static final String TAG_STRUCTURE_CACHES = "structureCaches"; //$NON-NLS-1$ - public static final String TAG_STRUCTURE_CACHE = "structureCache"; //$NON-NLS-1$ - public static final String TAG_OVERRIDE = "override"; //$NON-NLS-1$ - public static final String TAG_ADVISOR = "advisor"; //$NON-NLS-1$ - public static final String TAG_BRANCH_POLICY_CATEGORY = "branchPolicyCategory"; //$NON-NLS-1$ - - public static final String ATT_DEFAULT_STRUCTURE_ID = "defaultStructureId"; //$NON-NLS-1$ - public static final String ATT_STRUCTURE_ID = "structureId"; //$NON-NLS-1$ - public static final String ATT_PROPERTY_TESTER_ID = "propertyTesterId"; //$NON-NLS-1$ - public static final String ATT_LAYER = "layer"; //$NON-NLS-1$ - public static final String ATT_VALUE_PROVIDER_ID = "valueProviderId"; //$NON-NLS-1$ - public static final String ATT_PRIMARY_KEY = "primaryKey"; //$NON-NLS-1$ - public static final String ATT_SECONDARY_KEY = "secondaryKey"; //$NON-NLS-1$ - - // =============================== - // Decorations Extension Point - // ------------------------------- - public static final String EXT_DECORATIONS = "decorations"; //$NON-NLS-1$ - public static final String TAG_DECORATION = "decoration"; //$NON-NLS-1$ - public static final String TAG_FACTORY = "factory"; //$NON-NLS-1$ - public static final String TAG_DEFAULT_VALUE = "defaultValue"; //$NON-NLS-1$ - - // ===================== - // Other - // --------------------- - - public static final String EXT_HYPERLINKPAGE = "hyperlinkPages"; //$NON-NLS-1$ - public static final String TAG_HYPER_PAGE = "page"; //$NON-NLS-1$ - -// public static final String EXT_ELEMENT_TYPES = "elementTypes"; //$NON-NLS-1$ - public static final String EXT_DND_CLIENTS = "dndClients"; //$NON-NLS-1$ - public static final String EXT_PROPERTY_SECTIONS = "propertySections"; //$NON-NLS-1$ - public static final String EXT_EDIT_POLICIES = "editPolicies"; //$NON-NLS-1$ - //public static final String EXT_GLOBAL_CORE_EVENT_HANDLERS = "globalCoreEventHandlers"; //$NON-NLS-1$ - public static final String EXT_ICONTIPS = "iconTips"; //$NON-NLS-1$ - public static final String EXT_NUMBER_FORMATS = "numberFormats"; //$NON-NLS-1$ - public static final String EXT_NUMBER_SEPARATORS = "numberSeparators"; //$NON-NLS-1$ - public static final String EXT_INFOITMES = "infoItems"; //$NON-NLS-1$ - -// public static final String TAG_ELEMENT_TYPE = "elementType"; //$NON-NLS-1$ - public static final String TAG_DND_CLIENT = "dndClient"; //$NON-NLS-1$ - public static final String TAG_SECTION = "section"; //$NON-NLS-1$ -// public static final String TAG_TYPE_OF = "typeOf"; //$NON-NLS-1$ -// public static final String TAG_MEMBER_OF = "memberOf"; //$NON-NLS-1$ - public static final String TAG_EDIT_POLICY = "editPolicy"; //$NON-NLS-1$ - public static final String TAG_ICONTIP = "iconTip"; //$NON-NLS-1$ - public static final String TAG_FORMAT = "format"; //$NON-NLS-1$ - public static final String TAG_SEPARATOR = "separator"; //$NON-NLS-1$ - public static final String TAG_INFOITEM = "infoItem"; //$NON-NLS-1$ - - public static final String ATT_MODE = "defaultMode"; //$NON-NLS-1$ - public static final String ATT_AVAILABLEMODES = "availableModes"; //$NON-NLS-1$ - public static final String ATT_CARD_LABEL = "cardLabel"; //$NON-NLS-1$ - -// public static final String TAG_HANDLER = "handler"; //$NON-NLS-1$ -// public static final String TAG_HANDLER_BINDING = "handlerBinding"; //$NON-NLS-1$ - -// public static final String ATT_ELEMENT_TYPE = "elementType"; //$NON-NLS-1$ -// public static final String ATT_BRANCH_FAMILY = "branchFamily"; //$NON-NLS-1$ -// public static final String ATT_EVENT_TYPE = "eventType"; //$NON-NLS-1$ -// public static final String ATT_HANDLER_ID = "handlerId"; //$NON-NLS-1$ - -// // ================== -// // Branch Families -// // ------------------- -// public static final String BRANCH_FAMILY_CENTRAL = "central"; //$NON-NLS-$ -// public static final String BRANCH_FAMILY_MAIN = "main"; //$NON-NLS-1$ -// public static final String BRANCH_FAMILY_SUB = "sub"; //$NON-NLS-1$ -// public static final String BRANCH_FAMILY_FLOATING = "floating"; //$NON-NLS-1$ -// public static final String BRANCH_FAMILY_ALL = "all"; //$NON-NLS-1$ -// -// public static final Set ALL_BRANCH_FAMILIES = Collections -// .unmodifiableSet(new HashSet(Arrays.asList( -// BRANCH_FAMILY_CENTRAL, BRANCH_FAMILY_FLOATING, -// BRANCH_FAMILY_MAIN, BRANCH_FAMILY_SUB))); - - public static final String EXT_WORKBOOK_REF_FACTORIES = "workbookRefFactories"; //$NON-NLS-1$ - public static final String TAG_AVAILABLE_FOR_URI_SCHEME = "availableForURIScheme"; //$NON-NLS-1$ - public static final String ATT_SCHEME = "scheme"; //$NON-NLS-1$ - - public static final String EXT_SAVE_WIZARDS = "saveWizards"; //$NON-NLS-1$ - public static final String TAG_SAVE_WIZARD = "saveWizard"; //$NON-NLS-1$ - - public static final String EXT_SHARE_OPTIONS = "shareOptions"; //$NON-NLS-1$ - public static final String TAG_OPTION = "option"; //$NON-NLS-1$ - public static final String VAL_CATEGORY_NORMAL = "normal"; //$NON-NLS-1$ - public static final String VAL_CATEGORY_POPULAR = "popular"; //$NON-NLS-1$ - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; + +public class RegistryConstants implements IWorkbenchRegistryConstants { + + // ==================================== + // Branch Policies Extension Point + // ------------------------------------ + public static final String EXT_BRANCH_POLICIES = "branchPolicies"; //$NON-NLS-1$ + + public static final String TAG_BRANCH_POLICY = "branchPolicy"; //$NON-NLS-1$ + public static final String TAG_STRUCTURE = "structure"; //$NON-NLS-1$ + public static final String TAG_ADDITIONAL_STRUCTURES = "additionalStructures"; //$NON-NLS-1$ + public static final String TAG_ADDITIONAL_STRUCTURE = "additionalStructure"; //$NON-NLS-1$ + public static final String TAG_PROPERTY_TESTER = "propertyTester"; //$NON-NLS-1$ + public static final String TAG_BRANCH_HOOK = "branchHook"; //$NON-NLS-1$ + public static final String TAG_STYLE_SELECTOR = "styleSelector"; //$NON-NLS-1$ + public static final String TAG_OVERRIDED_STYLE = "overridedStyle"; //$NON-NLS-1$ +// public static final String TAG_INHERITED_STYLE = "inheritedStyle"; //$NON-NLS-1$ + public static final String TAG_UNMODIFIABLE_PROPERTIES = "unmodifiableProperties"; //$NON-NLS-1$ + public static final String TAG_UNMODIFIABLE_PROPERTY = "unmodifiableProperty"; //$NON-NLS-1$ + public static final String TAG_STYLE_VALUE_PROVIDER = "styleValueProvider"; //$NON-NLS-1$ + public static final String TAG_LAYER = "layer"; //$NON-NLS-1$ + public static final String TAG_STRUCTURE_CACHES = "structureCaches"; //$NON-NLS-1$ + public static final String TAG_STRUCTURE_CACHE = "structureCache"; //$NON-NLS-1$ + public static final String TAG_OVERRIDE = "override"; //$NON-NLS-1$ + public static final String TAG_ADVISOR = "advisor"; //$NON-NLS-1$ + public static final String TAG_BRANCH_POLICY_CATEGORY = "branchPolicyCategory"; //$NON-NLS-1$ + + public static final String ATT_DEFAULT_STRUCTURE_ID = "defaultStructureId"; //$NON-NLS-1$ + public static final String ATT_STRUCTURE_ID = "structureId"; //$NON-NLS-1$ + public static final String ATT_PROPERTY_TESTER_ID = "propertyTesterId"; //$NON-NLS-1$ + public static final String ATT_LAYER = "layer"; //$NON-NLS-1$ + public static final String ATT_VALUE_PROVIDER_ID = "valueProviderId"; //$NON-NLS-1$ + public static final String ATT_PRIMARY_KEY = "primaryKey"; //$NON-NLS-1$ + public static final String ATT_SECONDARY_KEY = "secondaryKey"; //$NON-NLS-1$ + + // =============================== + // Decorations Extension Point + // ------------------------------- + public static final String EXT_DECORATIONS = "decorations"; //$NON-NLS-1$ + public static final String TAG_DECORATION = "decoration"; //$NON-NLS-1$ + public static final String TAG_FACTORY = "factory"; //$NON-NLS-1$ + public static final String TAG_DEFAULT_VALUE = "defaultValue"; //$NON-NLS-1$ + + // ===================== + // Other + // --------------------- + + public static final String EXT_HYPERLINKPAGE = "hyperlinkPages"; //$NON-NLS-1$ + public static final String TAG_HYPER_PAGE = "page"; //$NON-NLS-1$ + +// public static final String EXT_ELEMENT_TYPES = "elementTypes"; //$NON-NLS-1$ + public static final String EXT_DND_CLIENTS = "dndClients"; //$NON-NLS-1$ + public static final String EXT_PROPERTY_SECTIONS = "propertySections"; //$NON-NLS-1$ + public static final String EXT_EDIT_POLICIES = "editPolicies"; //$NON-NLS-1$ + //public static final String EXT_GLOBAL_CORE_EVENT_HANDLERS = "globalCoreEventHandlers"; //$NON-NLS-1$ + public static final String EXT_ICONTIPS = "iconTips"; //$NON-NLS-1$ + public static final String EXT_NUMBER_FORMATS = "numberFormats"; //$NON-NLS-1$ + public static final String EXT_NUMBER_SEPARATORS = "numberSeparators"; //$NON-NLS-1$ + public static final String EXT_INFOITMES = "infoItems"; //$NON-NLS-1$ + +// public static final String TAG_ELEMENT_TYPE = "elementType"; //$NON-NLS-1$ + public static final String TAG_DND_CLIENT = "dndClient"; //$NON-NLS-1$ + public static final String TAG_SECTION = "section"; //$NON-NLS-1$ +// public static final String TAG_TYPE_OF = "typeOf"; //$NON-NLS-1$ +// public static final String TAG_MEMBER_OF = "memberOf"; //$NON-NLS-1$ + public static final String TAG_EDIT_POLICY = "editPolicy"; //$NON-NLS-1$ + public static final String TAG_ICONTIP = "iconTip"; //$NON-NLS-1$ + public static final String TAG_FORMAT = "format"; //$NON-NLS-1$ + public static final String TAG_SEPARATOR = "separator"; //$NON-NLS-1$ + public static final String TAG_INFOITEM = "infoItem"; //$NON-NLS-1$ + + public static final String ATT_MODE = "defaultMode"; //$NON-NLS-1$ + public static final String ATT_AVAILABLEMODES = "availableModes"; //$NON-NLS-1$ + public static final String ATT_CARD_LABEL = "cardLabel"; //$NON-NLS-1$ + +// public static final String TAG_HANDLER = "handler"; //$NON-NLS-1$ +// public static final String TAG_HANDLER_BINDING = "handlerBinding"; //$NON-NLS-1$ + +// public static final String ATT_ELEMENT_TYPE = "elementType"; //$NON-NLS-1$ +// public static final String ATT_BRANCH_FAMILY = "branchFamily"; //$NON-NLS-1$ +// public static final String ATT_EVENT_TYPE = "eventType"; //$NON-NLS-1$ +// public static final String ATT_HANDLER_ID = "handlerId"; //$NON-NLS-1$ + +// // ================== +// // Branch Families +// // ------------------- +// public static final String BRANCH_FAMILY_CENTRAL = "central"; //$NON-NLS-$ +// public static final String BRANCH_FAMILY_MAIN = "main"; //$NON-NLS-1$ +// public static final String BRANCH_FAMILY_SUB = "sub"; //$NON-NLS-1$ +// public static final String BRANCH_FAMILY_FLOATING = "floating"; //$NON-NLS-1$ +// public static final String BRANCH_FAMILY_ALL = "all"; //$NON-NLS-1$ +// +// public static final Set ALL_BRANCH_FAMILIES = Collections +// .unmodifiableSet(new HashSet(Arrays.asList( +// BRANCH_FAMILY_CENTRAL, BRANCH_FAMILY_FLOATING, +// BRANCH_FAMILY_MAIN, BRANCH_FAMILY_SUB))); + + public static final String EXT_WORKBOOK_REF_FACTORIES = "workbookRefFactories"; //$NON-NLS-1$ + public static final String TAG_AVAILABLE_FOR_URI_SCHEME = "availableForURIScheme"; //$NON-NLS-1$ + public static final String ATT_SCHEME = "scheme"; //$NON-NLS-1$ + + public static final String EXT_SAVE_WIZARDS = "saveWizards"; //$NON-NLS-1$ + public static final String TAG_SAVE_WIZARD = "saveWizard"; //$NON-NLS-1$ + + public static final String EXT_SHARE_OPTIONS = "shareOptions"; //$NON-NLS-1$ + public static final String TAG_OPTION = "option"; //$NON-NLS-1$ + public static final String VAL_CATEGORY_NORMAL = "normal"; //$NON-NLS-1$ + public static final String VAL_CATEGORY_POPULAR = "popular"; //$NON-NLS-1$ + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java index da423279e..b2abe079c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java @@ -1,36 +1,36 @@ -package org.xmind.ui.internal; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.menus.WorkbenchWindowControlContribution; -import org.xmind.ui.mindmap.MindMapUI; - -public class SeparatorControlContribution - extends WorkbenchWindowControlContribution { - - private static final String ICON_SPLINE = "line.png"; //$NON-NLS-1$ - - private ResourceManager resources; - - public SeparatorControlContribution() { - super("org.xmind.ui.separatorControlContribution"); //$NON-NLS-1$ - } - - @Override - protected Control createControl(Composite parent) { - Label label = new Label(parent, SWT.NONE); - resources = new LocalResourceManager(JFaceResources.getResources(), - label); - - label.setImage((Image) resources - .get(MindMapUI.getImages().get(ICON_SPLINE, true))); - return label; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.menus.WorkbenchWindowControlContribution; +import org.xmind.ui.mindmap.MindMapUI; + +public class SeparatorControlContribution + extends WorkbenchWindowControlContribution { + + private static final String ICON_SPLINE = "line.png"; //$NON-NLS-1$ + + private ResourceManager resources; + + public SeparatorControlContribution() { + super("org.xmind.ui.separatorControlContribution"); //$NON-NLS-1$ + } + + @Override + protected Control createControl(Composite parent) { + Label label = new Label(parent, SWT.NONE); + resources = new LocalResourceManager(JFaceResources.getResources(), + label); + + label.setImage((Image) resources + .get(MindMapUI.getImages().get(ICON_SPLINE, true))); + return label; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ServiceManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ServiceManager.java index 08070e40c..bc7d36822 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ServiceManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ServiceManager.java @@ -1,51 +1,51 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal; - -import org.xmind.ui.internal.statushandlers.IErrorReporter; - -/** - * @author Frank Shaka - * - */ -public class ServiceManager { - - private IErrorReporter errorReporter; - - public void activate() { - MindMapUIPlugin.getDefault().setServiceManager(this); - } - - public void deactivate() { - MindMapUIPlugin.getDefault().setServiceManager(null); - } - - public void setErrorReporter(IErrorReporter reporter) { - this.errorReporter = reporter; - } - - public void unsetErrorReporter(IErrorReporter reporter) { - if (reporter != this.errorReporter) - return; - this.errorReporter = null; - } - - public IErrorReporter getErrorReporter() { - return errorReporter; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal; + +import org.xmind.ui.internal.statushandlers.IErrorReporter; + +/** + * @author Frank Shaka + * + */ +public class ServiceManager { + + private IErrorReporter errorReporter; + + public void activate() { + MindMapUIPlugin.getDefault().setServiceManager(this); + } + + public void deactivate() { + MindMapUIPlugin.getDefault().setServiceManager(null); + } + + public void setErrorReporter(IErrorReporter reporter) { + this.errorReporter = reporter; + } + + public void unsetErrorReporter(IErrorReporter reporter) { + if (reporter != this.errorReporter) + return; + this.errorReporter = null; + } + + public IErrorReporter getErrorReporter() { + return errorReporter; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOption.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOption.java index e006a94b3..7fd681fa4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOption.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOption.java @@ -1,92 +1,92 @@ -package org.xmind.ui.internal; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; -import org.eclipse.ui.plugin.AbstractUIPlugin; - -/** - * - * @author Shawn Liu - * @since 3.6.50 - */ -public class ShareOption { - - private IConfigurationElement element; - - private String id; - - private String label; - - private String tooltip; - - private String commandId; - - private ImageDescriptor icon; - - private String category; - - public ShareOption(IConfigurationElement element) throws CoreException { - this.element = element; - this.id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); - this.label = element - .getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); - this.tooltip = element - .getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP); - this.category = element - .getAttribute(IWorkbenchRegistryConstants.ATT_CATEGORY); - this.commandId = element - .getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID); - this.icon = null; - - if (id == null || commandId == null) - throw new CoreException( - new Status(IStatus.ERROR, element.getNamespaceIdentifier(), - "Invalid extension element")); //$NON-NLS-1$ - } - - public String getId() { - return id; - } - - public String getLabel() { - return label; - } - - public String getTooltip() { - return tooltip; - } - - /** - * @return the commandId - */ - public String getCommandId() { - return commandId; - } - - public ImageDescriptor getImage() { - if (icon == null) { - icon = createImage(); - } - return icon; - } - - private ImageDescriptor createImage() { - String imageName = element - .getAttribute(IWorkbenchRegistryConstants.ATT_ICON); - if (imageName != null) { - String plugId = element.getNamespaceIdentifier(); - return AbstractUIPlugin.imageDescriptorFromPlugin(plugId, - imageName); - } - return null; - } - - public String getCategory() { - return category; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * + * @author Shawn Liu + * @since 3.6.50 + */ +public class ShareOption { + + private IConfigurationElement element; + + private String id; + + private String label; + + private String tooltip; + + private String commandId; + + private ImageDescriptor icon; + + private String category; + + public ShareOption(IConfigurationElement element) throws CoreException { + this.element = element; + this.id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); + this.label = element + .getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); + this.tooltip = element + .getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP); + this.category = element + .getAttribute(IWorkbenchRegistryConstants.ATT_CATEGORY); + this.commandId = element + .getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID); + this.icon = null; + + if (id == null || commandId == null) + throw new CoreException( + new Status(IStatus.ERROR, element.getNamespaceIdentifier(), + "Invalid extension element")); //$NON-NLS-1$ + } + + public String getId() { + return id; + } + + public String getLabel() { + return label; + } + + public String getTooltip() { + return tooltip; + } + + /** + * @return the commandId + */ + public String getCommandId() { + return commandId; + } + + public ImageDescriptor getImage() { + if (icon == null) { + icon = createImage(); + } + return icon; + } + + private ImageDescriptor createImage() { + String imageName = element + .getAttribute(IWorkbenchRegistryConstants.ATT_ICON); + if (imageName != null) { + String plugId = element.getNamespaceIdentifier(); + return AbstractUIPlugin.imageDescriptorFromPlugin(plugId, + imageName); + } + return null; + } + + public String getCategory() { + return category; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistry.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistry.java index 3ac2bdbe6..1bf733563 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistry.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistry.java @@ -1,98 +1,98 @@ -package org.xmind.ui.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Platform; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -/** - * - * @author Shawn Liu - * @since 3.6.50 - */ -public class ShareOptionRegistry { - - private List options = null; - - ShareOptionRegistry() { - } - - public List getOptions() { - ensureLoaded(); - return Collections.unmodifiableList(options); - } - - /** - * @return - */ - public boolean hasOptions() { - ensureLoaded(); - return !options.isEmpty(); - } - - public ShareOption getOptionById(String id) { - Assert.isLegal(id != null); - ensureLoaded(); - for (ShareOption option : options) { - if (id.equals(option.getId())) { - return option; - } - } - return null; - } - - public List getOptionsByCategory(String category) { - Assert.isLegal(category != null); - ensureLoaded(); - List result = new ArrayList(); - for (ShareOption option : options) { - if (category.equals(option.getCategory())) - result.add(option); - } - return result; - } - - private void ensureLoaded() { - if (options != null) - return; - - lazyLoad(); - - if (options == null) - options = Collections.emptyList(); - } - - private void lazyLoad() { - IExtensionPoint extPoint = Platform.getExtensionRegistry() - .getExtensionPoint(MindMapUI.PLUGIN_ID, - RegistryConstants.EXT_SHARE_OPTIONS); - Assert.isNotNull(extPoint); - for (IConfigurationElement ele : extPoint.getConfigurationElements()) { - if (RegistryConstants.TAG_OPTION.equals(ele.getName())) { - readShareOption(ele); - } - } - } - - private void readShareOption(IConfigurationElement element) { - ShareOption descriptor; - try { - descriptor = new ShareOption(element); - } catch (CoreException e) { - Logger.log(e, "Failed to load share item: " + element); //$NON-NLS-1$ - return; - } - if (options == null) { - options = new ArrayList(); - } - options.add(descriptor); - } - -} +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +/** + * + * @author Shawn Liu + * @since 3.6.50 + */ +public class ShareOptionRegistry { + + private List options = null; + + ShareOptionRegistry() { + } + + public List getOptions() { + ensureLoaded(); + return Collections.unmodifiableList(options); + } + + /** + * @return + */ + public boolean hasOptions() { + ensureLoaded(); + return !options.isEmpty(); + } + + public ShareOption getOptionById(String id) { + Assert.isLegal(id != null); + ensureLoaded(); + for (ShareOption option : options) { + if (id.equals(option.getId())) { + return option; + } + } + return null; + } + + public List getOptionsByCategory(String category) { + Assert.isLegal(category != null); + ensureLoaded(); + List result = new ArrayList(); + for (ShareOption option : options) { + if (category.equals(option.getCategory())) + result.add(option); + } + return result; + } + + private void ensureLoaded() { + if (options != null) + return; + + lazyLoad(); + + if (options == null) + options = Collections.emptyList(); + } + + private void lazyLoad() { + IExtensionPoint extPoint = Platform.getExtensionRegistry() + .getExtensionPoint(MindMapUI.PLUGIN_ID, + RegistryConstants.EXT_SHARE_OPTIONS); + Assert.isNotNull(extPoint); + for (IConfigurationElement ele : extPoint.getConfigurationElements()) { + if (RegistryConstants.TAG_OPTION.equals(ele.getName())) { + readShareOption(ele); + } + } + } + + private void readShareOption(IConfigurationElement element) { + ShareOption descriptor; + try { + descriptor = new ShareOption(element); + } catch (CoreException e) { + Logger.log(e, "Failed to load share item: " + element); //$NON-NLS-1$ + return; + } + if (options == null) { + options = new ArrayList(); + } + options.add(descriptor); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistryPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistryPropertyTester.java index f2f760702..36504a8fa 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistryPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ShareOptionRegistryPropertyTester.java @@ -1,22 +1,22 @@ -package org.xmind.ui.internal; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; - -public class ShareOptionRegistryPropertyTester extends PropertyTester { - - private static final String PROP_HAS_OPTIONS = "hasOptions"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - if (PROP_HAS_OPTIONS.equals(property)) { - return MindMapUIPlugin.getDefault().getShareOptionRegistry() - .hasOptions(); - } - - Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ - - return false; - } - -} +package org.xmind.ui.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; + +public class ShareOptionRegistryPropertyTester extends PropertyTester { + + private static final String PROP_HAS_OPTIONS = "hasOptions"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + if (PROP_HAS_OPTIONS.equals(property)) { + return MindMapUIPlugin.getDefault().getShareOptionRegistry() + .hasOptions(); + } + + Assert.isLegal(false, "Unrecognized property: " + property); //$NON-NLS-1$ + + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/StyleSheetPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/StyleSheetPropertyTester.java index b9f793d0d..c14812f24 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/StyleSheetPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/StyleSheetPropertyTester.java @@ -1,53 +1,53 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.ui.mindmap.MindMapUI; - -public class StyleSheetPropertyTester extends PropertyTester { - - private static final String P_TYPE = "type"; //$NON-NLS-1$ - - private static final String TYPE_DEFAULT = "default"; //$NON-NLS-1$ - - private static final String TYPE_SYSTEM = "system"; //$NON-NLS-1$ - - private static final String TYPE_USER = "user"; //$NON-NLS-1$ - - private static final String TYPE_WORKBOOK = "workbook"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - if (P_TYPE.equals(property)) { - if (receiver == MindMapUI.getResourceManager() - .getDefaultStyleSheet()) - return TYPE_DEFAULT.equals(expectedValue); - if (receiver == MindMapUI.getResourceManager() - .getSystemStyleSheet() - || receiver == MindMapUI.getResourceManager() - .getSystemThemeSheet()) - return TYPE_SYSTEM.equals(expectedValue); - if (receiver == MindMapUI.getResourceManager().getUserStyleSheet() - || receiver == MindMapUI.getResourceManager() - .getUserThemeSheet()) - return TYPE_USER.equals(expectedValue); - return TYPE_WORKBOOK.equals(expectedValue); - } - Assert.isTrue(false); - return false; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.ui.mindmap.MindMapUI; + +public class StyleSheetPropertyTester extends PropertyTester { + + private static final String P_TYPE = "type"; //$NON-NLS-1$ + + private static final String TYPE_DEFAULT = "default"; //$NON-NLS-1$ + + private static final String TYPE_SYSTEM = "system"; //$NON-NLS-1$ + + private static final String TYPE_USER = "user"; //$NON-NLS-1$ + + private static final String TYPE_WORKBOOK = "workbook"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + if (P_TYPE.equals(property)) { + if (receiver == MindMapUI.getResourceManager() + .getDefaultStyleSheet()) + return TYPE_DEFAULT.equals(expectedValue); + if (receiver == MindMapUI.getResourceManager() + .getSystemStyleSheet() + || receiver == MindMapUI.getResourceManager() + .getSystemThemeSheet()) + return TYPE_SYSTEM.equals(expectedValue); + if (receiver == MindMapUI.getResourceManager().getUserStyleSheet() + || receiver == MindMapUI.getResourceManager() + .getUserThemeSheet()) + return TYPE_USER.equals(expectedValue); + return TYPE_WORKBOOK.equals(expectedValue); + } + Assert.isTrue(false); + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateManagerImpl.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateManagerImpl.java index 1c78c3d3c..d40946f85 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateManagerImpl.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateManagerImpl.java @@ -1,270 +1,270 @@ -package org.xmind.ui.internal; - -@Deprecated -public class TemplateManagerImpl { - -// private static final String TEMPLATES_PATH = "templates"; //$NON-NLS-1$ -// private static final String TEMPLATES_DIR = TEMPLATES_PATH + "/"; //$NON-NLS-1$ -// -// private ListenerList listeners = new ListenerList(); -// private ITemplate defaultTemplate; -// -// @Override -// public ITemplate getTemplate(URI templateURI) { -// String path = templateURI.getPath(); -// if (path == null) -// return null; -// -// if (path.equals(ClonedTemplate.URI_PATH)) { -// return ClonedTemplate.create(templateURI); -// } -// -// return null; -// } -// -// @Override -// public List getSystemTemplates() { -// List sysTemplates = new ArrayList(); -// loadSystemTemplates(sysTemplates); -// return sysTemplates; -// } -// -// private void loadSystemTemplates(List templates) { -// Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); -// if (bundle != null) { -// Element element = getTemplateListElement(bundle); -// if (element != null) { -// java.util.Properties properties = getTemplateListProperties( -// bundle); -// Iterator it = DOMUtils.childElementIterByTag(element, -// "template"); //$NON-NLS-1$ -// while (it.hasNext()) { -// Element templateEle = it.next(); -// String resourcePath = templateEle.getAttribute("resource"); //$NON-NLS-1$ -// if (!"".equals(resourcePath)) { //$NON-NLS-1$ -// if (!resourcePath.startsWith("/")) { //$NON-NLS-1$ -// resourcePath = TEMPLATES_DIR + resourcePath; -// } -// URL url = findTemplateResource(bundle, resourcePath); -// if (url != null) { -// URI uri = null; -// try { -// uri = URIUtil.toURI(url); -// } catch (URISyntaxException e) { -// } -// if (uri != null) { -// String name = templateEle.getAttribute("name"); //$NON-NLS-1$ -// if (name.startsWith("%")) { //$NON-NLS-1$ -// if (properties != null) { -// name = properties -// .getProperty(name.substring(1)); -// } else { -// name = null; -// } -// } -// if (name == null || "".equals(name)) { //$NON-NLS-1$ -// name = FileUtils.getNoExtensionFileName( -// resourcePath); -// } -// templates.add(ClonedTemplate -// .createFromSourceWorkbookURI(uri, -// name)); -// } -// } -// } -// } -// } -// } -// } -// -// private URL findTemplateResource(Bundle bundle, String resourcePath) { -// return FileLocator.find(bundle, new Path("$nl$/" + resourcePath), null); //$NON-NLS-1$ -// } -// -// private java.util.Properties getTemplateListProperties(Bundle bundle) { -// URL propURL = ResourceFinder.findResource(bundle, TEMPLATES_DIR, -// "templates", ".properties"); //$NON-NLS-1$ //$NON-NLS-2$ -// if (propURL != null) { -// try { -// InputStream is = propURL.openStream(); -// try { -// java.util.Properties properties = new java.util.Properties(); -// properties.load(is); -// return properties; -// } finally { -// is.close(); -// } -// } catch (IOException e) { -// } -// } -// return null; -// } -// -// private Element getTemplateListElement(Bundle bundle) { -// URL xmlURL = FileLocator.find(bundle, -// new Path(TEMPLATES_DIR + "templates.xml"), null); //$NON-NLS-1$ -// if (xmlURL == null) -// return null; -// try { -// InputStream is = xmlURL.openStream(); -// if (is != null) { -// try { -// Document doc = DOMUtils.loadDocument(is); -// if (doc != null) -// return doc.getDocumentElement(); -// } finally { -// is.close(); -// } -// } -// } catch (Throwable e) { -// } -// return null; -// } -// -// private File createNonConflictingFile(File rootDir, String fileName) { -// int dotIndex = fileName.lastIndexOf('.'); -// String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); -// String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ -// File targetFile = new File(rootDir, fileName); -// int i = 1; -// while (targetFile.exists()) { -// i++; -// targetFile = new File(rootDir, -// String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ -// } -// return targetFile; -// } -// -// @Override -// public List getCustomTemplates() { -// List customTemplates = new ArrayList(); -// loadCustomTemplates(customTemplates); -// return customTemplates; -// } -// -// private void loadCustomTemplates(List templates) { -// loadTemplatesFromDir(templates, getCustomTemplatesDir()); -// } -// -// private static File getCustomTemplatesDir() { -// return new File(Core.getWorkspace().getAbsolutePath(TEMPLATES_PATH)); -// } -// -// private void loadTemplatesFromDir(List templates, -// File templatesDir) { -// List list = new ArrayList(); -// if (templatesDir != null && templatesDir.isDirectory()) { -// for (String fileName : templatesDir.list()) { -// if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) -// || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { -// File file = new File(templatesDir, fileName); -// if (file.isFile() && file.canRead()) { -// list.add(ClonedTemplate.createFromSourceWorkbookURI( -// file.toURI(), fileName)); -// } -// } -// } -// } -// Collections.sort(list, new Comparator() { -// public int compare(ITemplate t1, ITemplate t2) { -// if (!(t1 instanceof ClonedTemplate) -// || !(t2 instanceof ClonedTemplate)) -// return 0; -// ClonedTemplate ct1 = (ClonedTemplate) t1; -// ClonedTemplate ct2 = (ClonedTemplate) t2; -// -// File f1 = URIUtil.toFile(ct1.getSourceWorkbookURI()); -// File f2 = URIUtil.toFile(ct2.getSourceWorkbookURI()); -// if (f1 == null || f2 == null || !f1.exists() || !f2.exists()) -// return 0; -// return (int) (f1.lastModified() - f2.lastModified()); -// } -// }); -// templates.addAll(list); -// } -// -// @Override -// public ITemplate addCustomTemplateFromWorkbookURI(URI workbookURI) -// throws CoreException { -// if (URIUtil.isFileURI(workbookURI)) { -// File sourceFile = URIUtil.toFile(workbookURI); -// String fileName = sourceFile.getName(); -// File targetFile = createCustomTemplateOutputFile(fileName); -// try { -// FileUtils.copy(sourceFile, targetFile); -// ClonedTemplate template = ClonedTemplate -// .createFromSourceWorkbookURI(targetFile.toURI(), -// fileName); -// fireTemplateAdded(template); -// return template; -// } catch (IOException e) { -// } -// -// } -// return null; -// } -// -// private void fireTemplateAdded(ITemplate template) { -// for (Object listener : listeners.getListeners()) { -// try { -// ((ITemplateManagerListener) listener) -// .customTemplateAdded(template); -// } catch (Throwable e) { -// Logger.log(e); -// } -// } -// } -// -// private void fireTemplateRemoved(ITemplate template) { -// for (Object listener : listeners.getListeners()) { -// try { -// ((ITemplateManagerListener) listener) -// .customTemplateRemoved(template); -// } catch (Throwable e) { -// Logger.log(e); -// } -// } -// } -// -// private File createCustomTemplateOutputFile(String fileName) { -// File dir = getCustomTemplatesDir(); -// FileUtils.ensureDirectory(dir); -// return createNonConflictingFile(dir, fileName); -// } -// -// @Override -// public void removeCustomTemplate(ITemplate template) { -// if (template instanceof ISourceWorkbookProvider) { -// URI templateURI = ((ISourceWorkbookProvider) template) -// .getSourceWorkbookURI(); -// if (URIUtil.isFileURI(templateURI)) { -// File file = URIUtil.toFile(templateURI); -// if (file.delete()) { -// fireTemplateRemoved(template); -// } -// } -// } -// } -// -// @Override -// public void addTemplateManagerListener(ITemplateManagerListener listener) { -// listeners.add(listener); -// } -// -// @Override -// public void removeTemplateManagerListener( -// ITemplateManagerListener listener) { -// listeners.remove(listener); -// } -// -// @Override -// public ITemplate getDefaultTemplate() { -// return this.defaultTemplate; -// } -// -// @Override -// public void setDefaultTemplate(ITemplate defaultTemplate) { -// this.defaultTemplate = defaultTemplate; -// } - -} +package org.xmind.ui.internal; + +@Deprecated +public class TemplateManagerImpl { + +// private static final String TEMPLATES_PATH = "templates"; //$NON-NLS-1$ +// private static final String TEMPLATES_DIR = TEMPLATES_PATH + "/"; //$NON-NLS-1$ +// +// private ListenerList listeners = new ListenerList(); +// private ITemplate defaultTemplate; +// +// @Override +// public ITemplate getTemplate(URI templateURI) { +// String path = templateURI.getPath(); +// if (path == null) +// return null; +// +// if (path.equals(ClonedTemplate.URI_PATH)) { +// return ClonedTemplate.create(templateURI); +// } +// +// return null; +// } +// +// @Override +// public List getSystemTemplates() { +// List sysTemplates = new ArrayList(); +// loadSystemTemplates(sysTemplates); +// return sysTemplates; +// } +// +// private void loadSystemTemplates(List templates) { +// Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); +// if (bundle != null) { +// Element element = getTemplateListElement(bundle); +// if (element != null) { +// java.util.Properties properties = getTemplateListProperties( +// bundle); +// Iterator it = DOMUtils.childElementIterByTag(element, +// "template"); //$NON-NLS-1$ +// while (it.hasNext()) { +// Element templateEle = it.next(); +// String resourcePath = templateEle.getAttribute("resource"); //$NON-NLS-1$ +// if (!"".equals(resourcePath)) { //$NON-NLS-1$ +// if (!resourcePath.startsWith("/")) { //$NON-NLS-1$ +// resourcePath = TEMPLATES_DIR + resourcePath; +// } +// URL url = findTemplateResource(bundle, resourcePath); +// if (url != null) { +// URI uri = null; +// try { +// uri = URIUtil.toURI(url); +// } catch (URISyntaxException e) { +// } +// if (uri != null) { +// String name = templateEle.getAttribute("name"); //$NON-NLS-1$ +// if (name.startsWith("%")) { //$NON-NLS-1$ +// if (properties != null) { +// name = properties +// .getProperty(name.substring(1)); +// } else { +// name = null; +// } +// } +// if (name == null || "".equals(name)) { //$NON-NLS-1$ +// name = FileUtils.getNoExtensionFileName( +// resourcePath); +// } +// templates.add(ClonedTemplate +// .createFromSourceWorkbookURI(uri, +// name)); +// } +// } +// } +// } +// } +// } +// } +// +// private URL findTemplateResource(Bundle bundle, String resourcePath) { +// return FileLocator.find(bundle, new Path("$nl$/" + resourcePath), null); //$NON-NLS-1$ +// } +// +// private java.util.Properties getTemplateListProperties(Bundle bundle) { +// URL propURL = ResourceFinder.findResource(bundle, TEMPLATES_DIR, +// "templates", ".properties"); //$NON-NLS-1$ //$NON-NLS-2$ +// if (propURL != null) { +// try { +// InputStream is = propURL.openStream(); +// try { +// java.util.Properties properties = new java.util.Properties(); +// properties.load(is); +// return properties; +// } finally { +// is.close(); +// } +// } catch (IOException e) { +// } +// } +// return null; +// } +// +// private Element getTemplateListElement(Bundle bundle) { +// URL xmlURL = FileLocator.find(bundle, +// new Path(TEMPLATES_DIR + "templates.xml"), null); //$NON-NLS-1$ +// if (xmlURL == null) +// return null; +// try { +// InputStream is = xmlURL.openStream(); +// if (is != null) { +// try { +// Document doc = DOMUtils.loadDocument(is); +// if (doc != null) +// return doc.getDocumentElement(); +// } finally { +// is.close(); +// } +// } +// } catch (Throwable e) { +// } +// return null; +// } +// +// private File createNonConflictingFile(File rootDir, String fileName) { +// int dotIndex = fileName.lastIndexOf('.'); +// String name = dotIndex < 0 ? fileName : fileName.substring(0, dotIndex); +// String ext = dotIndex < 0 ? "" : fileName.substring(dotIndex); //$NON-NLS-1$ +// File targetFile = new File(rootDir, fileName); +// int i = 1; +// while (targetFile.exists()) { +// i++; +// targetFile = new File(rootDir, +// String.format("%s %s%s", name, i, ext)); //$NON-NLS-1$ +// } +// return targetFile; +// } +// +// @Override +// public List getCustomTemplates() { +// List customTemplates = new ArrayList(); +// loadCustomTemplates(customTemplates); +// return customTemplates; +// } +// +// private void loadCustomTemplates(List templates) { +// loadTemplatesFromDir(templates, getCustomTemplatesDir()); +// } +// +// private static File getCustomTemplatesDir() { +// return new File(Core.getWorkspace().getAbsolutePath(TEMPLATES_PATH)); +// } +// +// private void loadTemplatesFromDir(List templates, +// File templatesDir) { +// List list = new ArrayList(); +// if (templatesDir != null && templatesDir.isDirectory()) { +// for (String fileName : templatesDir.list()) { +// if (fileName.endsWith(MindMapUI.FILE_EXT_TEMPLATE) +// || fileName.endsWith(MindMapUI.FILE_EXT_XMIND)) { +// File file = new File(templatesDir, fileName); +// if (file.isFile() && file.canRead()) { +// list.add(ClonedTemplate.createFromSourceWorkbookURI( +// file.toURI(), fileName)); +// } +// } +// } +// } +// Collections.sort(list, new Comparator() { +// public int compare(ITemplate t1, ITemplate t2) { +// if (!(t1 instanceof ClonedTemplate) +// || !(t2 instanceof ClonedTemplate)) +// return 0; +// ClonedTemplate ct1 = (ClonedTemplate) t1; +// ClonedTemplate ct2 = (ClonedTemplate) t2; +// +// File f1 = URIUtil.toFile(ct1.getSourceWorkbookURI()); +// File f2 = URIUtil.toFile(ct2.getSourceWorkbookURI()); +// if (f1 == null || f2 == null || !f1.exists() || !f2.exists()) +// return 0; +// return (int) (f1.lastModified() - f2.lastModified()); +// } +// }); +// templates.addAll(list); +// } +// +// @Override +// public ITemplate addCustomTemplateFromWorkbookURI(URI workbookURI) +// throws CoreException { +// if (URIUtil.isFileURI(workbookURI)) { +// File sourceFile = URIUtil.toFile(workbookURI); +// String fileName = sourceFile.getName(); +// File targetFile = createCustomTemplateOutputFile(fileName); +// try { +// FileUtils.copy(sourceFile, targetFile); +// ClonedTemplate template = ClonedTemplate +// .createFromSourceWorkbookURI(targetFile.toURI(), +// fileName); +// fireTemplateAdded(template); +// return template; +// } catch (IOException e) { +// } +// +// } +// return null; +// } +// +// private void fireTemplateAdded(ITemplate template) { +// for (Object listener : listeners.getListeners()) { +// try { +// ((ITemplateManagerListener) listener) +// .customTemplateAdded(template); +// } catch (Throwable e) { +// Logger.log(e); +// } +// } +// } +// +// private void fireTemplateRemoved(ITemplate template) { +// for (Object listener : listeners.getListeners()) { +// try { +// ((ITemplateManagerListener) listener) +// .customTemplateRemoved(template); +// } catch (Throwable e) { +// Logger.log(e); +// } +// } +// } +// +// private File createCustomTemplateOutputFile(String fileName) { +// File dir = getCustomTemplatesDir(); +// FileUtils.ensureDirectory(dir); +// return createNonConflictingFile(dir, fileName); +// } +// +// @Override +// public void removeCustomTemplate(ITemplate template) { +// if (template instanceof ISourceWorkbookProvider) { +// URI templateURI = ((ISourceWorkbookProvider) template) +// .getSourceWorkbookURI(); +// if (URIUtil.isFileURI(templateURI)) { +// File file = URIUtil.toFile(templateURI); +// if (file.delete()) { +// fireTemplateRemoved(template); +// } +// } +// } +// } +// +// @Override +// public void addTemplateManagerListener(ITemplateManagerListener listener) { +// listeners.add(listener); +// } +// +// @Override +// public void removeTemplateManagerListener( +// ITemplateManagerListener listener) { +// listeners.remove(listener); +// } +// +// @Override +// public ITemplate getDefaultTemplate() { +// return this.defaultTemplate; +// } +// +// @Override +// public void setDefaultTemplate(ITemplate defaultTemplate) { +// this.defaultTemplate = defaultTemplate; +// } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicBranchAdapterFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicBranchAdapterFactory.java index 599b7a69d..641bbad08 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicBranchAdapterFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicBranchAdapterFactory.java @@ -1,62 +1,62 @@ -package org.xmind.ui.internal; - -import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.ITopic; -import org.xmind.gef.IViewer; -import org.xmind.gef.part.IPart; -import org.xmind.ui.mindmap.IBranchPart; - -public class TopicBranchAdapterFactory implements IAdapterFactory { - - private Class[] LIST = new Class[] { IBranchPart.class }; - - public Class[] getAdapterList() { - return LIST; - } - - public T getAdapter(Object adaptableObject, Class adapterType) { - if (adapterType == IBranchPart.class) { - if (adaptableObject instanceof ITopic) { - return adapterType.cast( - findBranchPartInActivePart((ITopic) adaptableObject)); - } - } - return null; - } - - private IBranchPart findBranchPartInActivePart(ITopic topic) { - if (!PlatformUI.isWorkbenchRunning()) - return null; - - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window == null) - return null; - - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return null; - - IWorkbenchPart wp = page.getActivePart(); - if (wp == null) - return null; - - IViewer viewer = wp.getAdapter(IViewer.class); - if (viewer == null) - return null; - - IPart part = viewer.findPart(topic); - if (part == null) - return null; - - if (part instanceof IBranchPart) - return (IBranchPart) part; - - return part.getAdapter(IBranchPart.class); - } - -} +package org.xmind.ui.internal; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.ITopic; +import org.xmind.gef.IViewer; +import org.xmind.gef.part.IPart; +import org.xmind.ui.mindmap.IBranchPart; + +public class TopicBranchAdapterFactory implements IAdapterFactory { + + private Class[] LIST = new Class[] { IBranchPart.class }; + + public Class[] getAdapterList() { + return LIST; + } + + public T getAdapter(Object adaptableObject, Class adapterType) { + if (adapterType == IBranchPart.class) { + if (adaptableObject instanceof ITopic) { + return adapterType.cast( + findBranchPartInActivePart((ITopic) adaptableObject)); + } + } + return null; + } + + private IBranchPart findBranchPartInActivePart(ITopic topic) { + if (!PlatformUI.isWorkbenchRunning()) + return null; + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) + return null; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return null; + + IWorkbenchPart wp = page.getActivePart(); + if (wp == null) + return null; + + IViewer viewer = wp.getAdapter(IViewer.class); + if (viewer == null) + return null; + + IPart part = viewer.findPart(topic); + if (part == null) + return null; + + if (part instanceof IBranchPart) + return (IBranchPart) part; + + return part.getAdapter(IBranchPart.class); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicContextService.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicContextService.java index 2f32c7e94..64e4b2e4f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicContextService.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TopicContextService.java @@ -1,55 +1,55 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal; - -import org.eclipse.core.runtime.IAdaptable; -import org.xmind.gef.IViewer; -import org.xmind.gef.service.AbstractViewerService; - -/** - * @author frankshaka - * - */ -public abstract class TopicContextService extends AbstractViewerService - implements IAdaptable { - - /** - * @param viewer - */ - public TopicContextService(IViewer viewer) { - super(viewer); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#activate() - */ - @Override - protected void activate() { - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.service.AbstractViewerService#deactivate() - */ - @Override - protected void deactivate() { - } - - @SuppressWarnings("unchecked") - public abstract Object getAdapter(Class adapter); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal; + +import org.eclipse.core.runtime.IAdaptable; +import org.xmind.gef.IViewer; +import org.xmind.gef.service.AbstractViewerService; + +/** + * @author frankshaka + * + */ +public abstract class TopicContextService extends AbstractViewerService + implements IAdaptable { + + /** + * @param viewer + */ + public TopicContextService(IViewer viewer) { + super(viewer); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#activate() + */ + @Override + protected void activate() { + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.service.AbstractViewerService#deactivate() + */ + @Override + protected void deactivate() { + } + + @SuppressWarnings("unchecked") + public abstract Object getAdapter(Class adapter); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ActionConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ActionConstants.java index 012132adf..0107e8ee2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ActionConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ActionConstants.java @@ -1,173 +1,173 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -public class ActionConstants { - - private static final String PREFIX = "org.xmind.ui."; //$NON-NLS-1$ - - public static final String M_VIEW = PREFIX + "view"; //$NON-NLS-1$ - - public static final String M_INSERT = PREFIX + "insert"; //$NON-NLS-1$ - - public static final String M_SORT = PREFIX + "sortSubtopics"; //$NON-NLS-1$ - - public static final String M_MODIFY = PREFIX + "modify"; //$NON-NLS-1$ - - public static final String M_TOOLS = PREFIX + "tools"; //$NON-NLS-1$ - - /** - * Group marker for context menu in MindMapEditor. - */ - public static final String CM_ADDITIONS = PREFIX + "additions"; //$NON-NLS-1$ - -// public static final String M_TOPIC = PREFIX + "topic"; //$NON-NLS-1$ -// -// public static final String M_MINDMAP = PREFIX + "mindmap"; //$NON-NLS-1$ - - public static final String VIEW_START = PREFIX + "viewStart"; //$NON-NLS-1$ - - public static final String VIEW_END = PREFIX + "viewEnd"; //$NON-NLS-1$ - - public static final String INSERT_START = PREFIX + "insertStart"; //$NON-NLS-1$ - - public static final String INSERT_END = PREFIX + "insertEnd"; //$NON-NLS-1$ - - public static final String MODIFY_START = PREFIX + "modifyStart"; //$NON-NLS-1$ - - public static final String MODIFY_END = PREFIX + "modifyEnd"; //$NON-NLS-1$ - - public static final String TOOLS_START = PREFIX + "toolsStart"; //$NON-NLS-1$ - - public static final String TOOLS_END = PREFIX + "toolsEnd"; //$NON-NLS-1$ - - public static final String GROUP_HYPERLINK = PREFIX + "hyperlink"; //$NON-NLS-1$ - - public static final String HYPERLINK_EXT = PREFIX + "hyperlink.ext"; //$NON-NLS-1$ - -// public static final String TOPIC_START = PREFIX + "topicStart"; //$NON-NLS-1$ -// -// public static final String TOPIC_END = PREFIX + "topicEnd"; //$NON-NLS-1$ -// -// public static final String MINDMAP_START = PREFIX + "mindmapStart"; //$NON-NLS-1$ -// -// public static final String MINDMAP_END = PREFIX + "mindmapEnd"; //$NON-NLS-1$ - - public static final String INSERT_TOPIC_EXT = PREFIX + "insertTopic.ext"; //$NON-NLS-1$ - - public static final String INSERT_EXT = PREFIX + "insert.ext"; //$NON-NLS-1$ - - public static final String SHEET_EXT = PREFIX + "sheet.ext"; //$NON-NLS-1$ - - public static final String TOPIC_EDIT_EXT = PREFIX + "topic.edit.ext"; //$NON-NLS-1$ - - public static final String DRILL_DOWN_EXT = PREFIX + "drillDown.ext"; //$NON-NLS-1$ - - public static final String EXTEND_EXT = PREFIX + "extend.ext"; //$NON-NLS-1$ - - public static final String POSITION_EXT = PREFIX + "position.ext"; //$NON-NLS-1$ - - public static final String GROUP_FILE = PREFIX + "group.file"; //$NON-NLS-1$ - - public static final String GROUP_UNDO = PREFIX + "group.undo"; //$NON-NLS-1$ - - public static final String GROUP_EDIT = PREFIX + "group.edit"; //$NON-NLS-1$ - - public static final String GROUP_SHEET = PREFIX + "group.sheet"; //$NON-NLS-1$ - - public static final String GROUP_INSERT_TOPIC = PREFIX - + "group.insertTopic"; //$NON-NLS-1$ - - public static final String GROUP_INSERT = PREFIX + "group.insert"; //$NON-NLS-1$ - - public static final String GROUP_TOPIC_EDIT = PREFIX + "group.topic.edit"; //$NON-NLS-1$ - - public static final String GROUP_DRILL_DOWN = PREFIX + "group.drillDown"; //$NON-NLS-1$ - - public static final String GROUP_EXTEND = PREFIX + "group.extend"; //$NON-NLS-1$ - - public static final String GROUP_POSITION = PREFIX + "group.position"; //$NON-NLS-1$ - - public static final String GROUP_ZOOM = PREFIX + "group.zoom"; //$NON-NLS-1$ - - public static final String GROUP_PRESENTATION = PREFIX - + "group.presentation"; //$NON-NLS-1$ - - public static final String GROUP_FILTER = PREFIX + "group.filter"; //$NON-NLS-1$ - - public static final String TOOLBAR_UNDO = PREFIX + "workbench.undo"; //$NON-NLS-1$ - - public static final String TOOLBAR_EDIT = PREFIX + "workbench.edit"; //$NON-NLS-1$ - - public static final String ADD_MARKER_ACTION_ID = PREFIX + "addMarker"; //$NON-NLS-1$ - - public static final String ALIGNMENT_GROUP_ID = PREFIX + "alignment"; //$NON-NLS-1$ - - public static final String ALIGNMENT_START = PREFIX + "alignment.start"; //$NON-NLS-1$ - - public static final String ALIGNMENT_END = PREFIX + "alignment.end"; //$NON-NLS-1$ - - public static final String ALIGNMENT_LEFT_ID = PREFIX + "align_left"; //$NON-NLS-1$ - - public static final String ALIGNMENT_CENTER_ID = PREFIX + "align_center"; //$NON-NLS-1$ - - public static final String ALIGNMENT_RIGHT_ID = PREFIX + "align_right"; //$NON-NLS-1$ - - public static final String ALIGNMENT_TOP_ID = PREFIX + "align_top"; //$NON-NLS-1$ - - public static final String ALIGNMENT_MIDDLE_ID = PREFIX + "align_middle"; //$NON-NLS-1$ - - public static final String ALIGNMENT_BOTTOM_ID = PREFIX + "align_bottom"; //$NON-NLS-1$ - - public static final String SORT_GROUP_ID = PREFIX + "sort"; //$NON-NLS-1$ - - public static final String SORT_EXT = PREFIX + "sort.ext"; //$NON-NLS-1$ - - public static final String SORT_TITLE_ID = PREFIX + "sort_title"; //$NON-NLS-1$ - - public static final String SORT_PRIORITY_ID = PREFIX + "sort_priority"; //$NON-NLS-1$ - - public static final String SORT_MODIFIED_ID = PREFIX + "sort_modified"; //$NON-NLS-1$ - - public static final String MARKER_GROUP_MENU = PREFIX + "markerGroup"; //$NON-NLS-1$ - - public static final String ALL_MARKERS_MENU = PREFIX + "allMarkers"; //$NON-NLS-1$ - - public static final String SAVE_SHEET_AS_ID = PREFIX + "saveSheetAs"; //$NON-NLS-1$ - - public static final String RENAME_SHEET_ID = PREFIX + "renameSheet"; //$NON-NLS-1$ - - public static final String STRUCTURE_MENU = PREFIX + "structureMenu"; //$NON-NLS-1$ - - public static final String INSERT_IMAGE_ID = PREFIX + "insertImage"; //$NON-NLS-1$ - - @Deprecated - public static final String REMOVE_REVISION_ID = PREFIX + "removeRevision"; //$NON-NLS-1$ - - @Deprecated - public static final String REVERT_TO_REVISION_ID = PREFIX - + "revertToRevision"; //$NON-NLS-1$ - - @Deprecated - public static final String PREVIEW_REVISIONS = PREFIX + "previewRevisions"; //$NON-NLS-1$ - - public static final String REOPEN_WORKBOOK_MENU_ID = PREFIX - + "reopenWorkbook"; //$NON-NLS-1$ - - public static final String MINI_ZOOM = PREFIX + "minibar.zoom"; //$NON-NLS-1$ - - public static final String SAVE_IMAGE_AS_ID = PREFIX + "saveImageAs"; //$NON-NLS-1$ - - public static final String SAVE_AUDIO_NOTES_AS_ID = PREFIX + "saveImageAs"; //$NON-NLS-1$ +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +public class ActionConstants { + + private static final String PREFIX = "org.xmind.ui."; //$NON-NLS-1$ + + public static final String M_VIEW = PREFIX + "view"; //$NON-NLS-1$ + + public static final String M_INSERT = PREFIX + "insert"; //$NON-NLS-1$ + + public static final String M_SORT = PREFIX + "sortSubtopics"; //$NON-NLS-1$ + + public static final String M_MODIFY = PREFIX + "modify"; //$NON-NLS-1$ + + public static final String M_TOOLS = PREFIX + "tools"; //$NON-NLS-1$ + + /** + * Group marker for context menu in MindMapEditor. + */ + public static final String CM_ADDITIONS = PREFIX + "additions"; //$NON-NLS-1$ + +// public static final String M_TOPIC = PREFIX + "topic"; //$NON-NLS-1$ +// +// public static final String M_MINDMAP = PREFIX + "mindmap"; //$NON-NLS-1$ + + public static final String VIEW_START = PREFIX + "viewStart"; //$NON-NLS-1$ + + public static final String VIEW_END = PREFIX + "viewEnd"; //$NON-NLS-1$ + + public static final String INSERT_START = PREFIX + "insertStart"; //$NON-NLS-1$ + + public static final String INSERT_END = PREFIX + "insertEnd"; //$NON-NLS-1$ + + public static final String MODIFY_START = PREFIX + "modifyStart"; //$NON-NLS-1$ + + public static final String MODIFY_END = PREFIX + "modifyEnd"; //$NON-NLS-1$ + + public static final String TOOLS_START = PREFIX + "toolsStart"; //$NON-NLS-1$ + + public static final String TOOLS_END = PREFIX + "toolsEnd"; //$NON-NLS-1$ + + public static final String GROUP_HYPERLINK = PREFIX + "hyperlink"; //$NON-NLS-1$ + + public static final String HYPERLINK_EXT = PREFIX + "hyperlink.ext"; //$NON-NLS-1$ + +// public static final String TOPIC_START = PREFIX + "topicStart"; //$NON-NLS-1$ +// +// public static final String TOPIC_END = PREFIX + "topicEnd"; //$NON-NLS-1$ +// +// public static final String MINDMAP_START = PREFIX + "mindmapStart"; //$NON-NLS-1$ +// +// public static final String MINDMAP_END = PREFIX + "mindmapEnd"; //$NON-NLS-1$ + + public static final String INSERT_TOPIC_EXT = PREFIX + "insertTopic.ext"; //$NON-NLS-1$ + + public static final String INSERT_EXT = PREFIX + "insert.ext"; //$NON-NLS-1$ + + public static final String SHEET_EXT = PREFIX + "sheet.ext"; //$NON-NLS-1$ + + public static final String TOPIC_EDIT_EXT = PREFIX + "topic.edit.ext"; //$NON-NLS-1$ + + public static final String DRILL_DOWN_EXT = PREFIX + "drillDown.ext"; //$NON-NLS-1$ + + public static final String EXTEND_EXT = PREFIX + "extend.ext"; //$NON-NLS-1$ + + public static final String POSITION_EXT = PREFIX + "position.ext"; //$NON-NLS-1$ + + public static final String GROUP_FILE = PREFIX + "group.file"; //$NON-NLS-1$ + + public static final String GROUP_UNDO = PREFIX + "group.undo"; //$NON-NLS-1$ + + public static final String GROUP_EDIT = PREFIX + "group.edit"; //$NON-NLS-1$ + + public static final String GROUP_SHEET = PREFIX + "group.sheet"; //$NON-NLS-1$ + + public static final String GROUP_INSERT_TOPIC = PREFIX + + "group.insertTopic"; //$NON-NLS-1$ + + public static final String GROUP_INSERT = PREFIX + "group.insert"; //$NON-NLS-1$ + + public static final String GROUP_TOPIC_EDIT = PREFIX + "group.topic.edit"; //$NON-NLS-1$ + + public static final String GROUP_DRILL_DOWN = PREFIX + "group.drillDown"; //$NON-NLS-1$ + + public static final String GROUP_EXTEND = PREFIX + "group.extend"; //$NON-NLS-1$ + + public static final String GROUP_POSITION = PREFIX + "group.position"; //$NON-NLS-1$ + + public static final String GROUP_ZOOM = PREFIX + "group.zoom"; //$NON-NLS-1$ + + public static final String GROUP_PRESENTATION = PREFIX + + "group.presentation"; //$NON-NLS-1$ + + public static final String GROUP_FILTER = PREFIX + "group.filter"; //$NON-NLS-1$ + + public static final String TOOLBAR_UNDO = PREFIX + "workbench.undo"; //$NON-NLS-1$ + + public static final String TOOLBAR_EDIT = PREFIX + "workbench.edit"; //$NON-NLS-1$ + + public static final String ADD_MARKER_ACTION_ID = PREFIX + "addMarker"; //$NON-NLS-1$ + + public static final String ALIGNMENT_GROUP_ID = PREFIX + "alignment"; //$NON-NLS-1$ + + public static final String ALIGNMENT_START = PREFIX + "alignment.start"; //$NON-NLS-1$ + + public static final String ALIGNMENT_END = PREFIX + "alignment.end"; //$NON-NLS-1$ + + public static final String ALIGNMENT_LEFT_ID = PREFIX + "align_left"; //$NON-NLS-1$ + + public static final String ALIGNMENT_CENTER_ID = PREFIX + "align_center"; //$NON-NLS-1$ + + public static final String ALIGNMENT_RIGHT_ID = PREFIX + "align_right"; //$NON-NLS-1$ + + public static final String ALIGNMENT_TOP_ID = PREFIX + "align_top"; //$NON-NLS-1$ + + public static final String ALIGNMENT_MIDDLE_ID = PREFIX + "align_middle"; //$NON-NLS-1$ + + public static final String ALIGNMENT_BOTTOM_ID = PREFIX + "align_bottom"; //$NON-NLS-1$ + + public static final String SORT_GROUP_ID = PREFIX + "sort"; //$NON-NLS-1$ + + public static final String SORT_EXT = PREFIX + "sort.ext"; //$NON-NLS-1$ + + public static final String SORT_TITLE_ID = PREFIX + "sort_title"; //$NON-NLS-1$ + + public static final String SORT_PRIORITY_ID = PREFIX + "sort_priority"; //$NON-NLS-1$ + + public static final String SORT_MODIFIED_ID = PREFIX + "sort_modified"; //$NON-NLS-1$ + + public static final String MARKER_GROUP_MENU = PREFIX + "markerGroup"; //$NON-NLS-1$ + + public static final String ALL_MARKERS_MENU = PREFIX + "allMarkers"; //$NON-NLS-1$ + + public static final String SAVE_SHEET_AS_ID = PREFIX + "saveSheetAs"; //$NON-NLS-1$ + + public static final String RENAME_SHEET_ID = PREFIX + "renameSheet"; //$NON-NLS-1$ + + public static final String STRUCTURE_MENU = PREFIX + "structureMenu"; //$NON-NLS-1$ + + public static final String INSERT_IMAGE_ID = PREFIX + "insertImage"; //$NON-NLS-1$ + + @Deprecated + public static final String REMOVE_REVISION_ID = PREFIX + "removeRevision"; //$NON-NLS-1$ + + @Deprecated + public static final String REVERT_TO_REVISION_ID = PREFIX + + "revertToRevision"; //$NON-NLS-1$ + + @Deprecated + public static final String PREVIEW_REVISIONS = PREFIX + "previewRevisions"; //$NON-NLS-1$ + + public static final String REOPEN_WORKBOOK_MENU_ID = PREFIX + + "reopenWorkbook"; //$NON-NLS-1$ + + public static final String MINI_ZOOM = PREFIX + "minibar.zoom"; //$NON-NLS-1$ + + public static final String SAVE_IMAGE_AS_ID = PREFIX + "saveImageAs"; //$NON-NLS-1$ + + public static final String SAVE_AUDIO_NOTES_AS_ID = PREFIX + "saveImageAs"; //$NON-NLS-1$ } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AlignmentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AlignmentAction.java index ecc7b006c..838adbad9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AlignmentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AlignmentAction.java @@ -1,58 +1,58 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.ui.actions.RetargetAction; -import org.xmind.ui.internal.MindMapMessages; - -public class AlignmentAction extends RetargetAction { - - public AlignmentAction(int alignment) { - super(null, null); - switch (alignment) { - case PositionConstants.LEFT: - setId(ActionConstants.ALIGNMENT_LEFT_ID); - setText(MindMapMessages.AlignLeft_text); - setToolTipText(MindMapMessages.AlignLeft_toolTip); - break; - case PositionConstants.CENTER: - setId(ActionConstants.ALIGNMENT_CENTER_ID); - setText(MindMapMessages.AlignCenter_text); - setToolTipText(MindMapMessages.AlignCenter_toolTip); - break; - case PositionConstants.RIGHT: - setId(ActionConstants.ALIGNMENT_RIGHT_ID); - setText(MindMapMessages.AlignRight_text); - setToolTipText(MindMapMessages.AlignRight_toolTip); - break; - case PositionConstants.TOP: - setId(ActionConstants.ALIGNMENT_TOP_ID); - setText(MindMapMessages.AlignTop_text); - setToolTipText(MindMapMessages.AlignTop_toolTip); - break; - case PositionConstants.MIDDLE: - setId(ActionConstants.ALIGNMENT_MIDDLE_ID); - setText(MindMapMessages.AlignMiddle_text); - setToolTipText(MindMapMessages.AlignMiddle_toolTip); - break; - case PositionConstants.BOTTOM: - setId(ActionConstants.ALIGNMENT_BOTTOM_ID); - setText(MindMapMessages.AlignBottom_text); - setToolTipText(MindMapMessages.AlignBottom_toolTip); - break; - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.ui.actions.RetargetAction; +import org.xmind.ui.internal.MindMapMessages; + +public class AlignmentAction extends RetargetAction { + + public AlignmentAction(int alignment) { + super(null, null); + switch (alignment) { + case PositionConstants.LEFT: + setId(ActionConstants.ALIGNMENT_LEFT_ID); + setText(MindMapMessages.AlignLeft_text); + setToolTipText(MindMapMessages.AlignLeft_toolTip); + break; + case PositionConstants.CENTER: + setId(ActionConstants.ALIGNMENT_CENTER_ID); + setText(MindMapMessages.AlignCenter_text); + setToolTipText(MindMapMessages.AlignCenter_toolTip); + break; + case PositionConstants.RIGHT: + setId(ActionConstants.ALIGNMENT_RIGHT_ID); + setText(MindMapMessages.AlignRight_text); + setToolTipText(MindMapMessages.AlignRight_toolTip); + break; + case PositionConstants.TOP: + setId(ActionConstants.ALIGNMENT_TOP_ID); + setText(MindMapMessages.AlignTop_text); + setToolTipText(MindMapMessages.AlignTop_toolTip); + break; + case PositionConstants.MIDDLE: + setId(ActionConstants.ALIGNMENT_MIDDLE_ID); + setText(MindMapMessages.AlignMiddle_text); + setToolTipText(MindMapMessages.AlignMiddle_toolTip); + break; + case PositionConstants.BOTTOM: + setId(ActionConstants.ALIGNMENT_BOTTOM_ID); + setText(MindMapMessages.AlignBottom_text); + setToolTipText(MindMapMessages.AlignBottom_toolTip); + break; + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllMarkersMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllMarkersMenu.java index a8ad5df2f..2084efd09 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllMarkersMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllMarkersMenu.java @@ -1,92 +1,92 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.ui.actions.CompoundContributionItem; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.ui.commands.MindMapCommandConstants; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MarkerImageDescriptor; - -public class AllMarkersMenu extends CompoundContributionItem - implements IWorkbenchContribution { - - private IServiceLocator serviceLocator; - - public void initialize(IServiceLocator serviceLocator) { - this.serviceLocator = serviceLocator; - } - - @Override - protected IContributionItem[] getContributionItems() { - List items = new ArrayList(); - - if (serviceLocator != null) { - fillItems(items, - MindMapUI.getResourceManager().getSystemMarkerSheet()); - } - - return items.toArray(new IContributionItem[items.size()]); - } - - private void fillItems(List items, - IMarkerSheet markerSheet) { - for (final IMarkerGroup group : markerSheet.getMarkerGroups()) { - MenuManager groupMenu = new MenuManager(group.getName(), "#" //$NON-NLS-1$ - + group.getId()); - if (!group.isHidden()) { - fillGroup(group, groupMenu); - items.add(groupMenu); - } - } - } - - private void fillGroup(IMarkerGroup group, IMenuManager groupMenu) { - for (IMarker marker : group.getMarkers()) { - if (!marker.isHidden()) { - groupMenu.add(makeMarkerCommandContributionItem(marker)); - } - } - } - - private IContributionItem makeMarkerCommandContributionItem( - IMarker marker) { - CommandContributionItemParameter parameter = new CommandContributionItemParameter( - serviceLocator, "addMarker." + marker.getId(), //$NON-NLS-1$ - MindMapCommandConstants.ADD_MARKER, - CommandContributionItem.STYLE_PUSH); - parameter.label = marker.getName(); - parameter.icon = MarkerImageDescriptor.createFromMarker(marker); - Map params = new HashMap(); - params.put(MindMapCommandConstants.ADD_MARKER_PARAM_MARKER_ID, - marker.getId()); - parameter.parameters = params; - return new CommandContributionItem(parameter); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MarkerImageDescriptor; + +public class AllMarkersMenu extends CompoundContributionItem + implements IWorkbenchContribution { + + private IServiceLocator serviceLocator; + + public void initialize(IServiceLocator serviceLocator) { + this.serviceLocator = serviceLocator; + } + + @Override + protected IContributionItem[] getContributionItems() { + List items = new ArrayList(); + + if (serviceLocator != null) { + fillItems(items, + MindMapUI.getResourceManager().getSystemMarkerSheet()); + } + + return items.toArray(new IContributionItem[items.size()]); + } + + private void fillItems(List items, + IMarkerSheet markerSheet) { + for (final IMarkerGroup group : markerSheet.getMarkerGroups()) { + MenuManager groupMenu = new MenuManager(group.getName(), "#" //$NON-NLS-1$ + + group.getId()); + if (!group.isHidden()) { + fillGroup(group, groupMenu); + items.add(groupMenu); + } + } + } + + private void fillGroup(IMarkerGroup group, IMenuManager groupMenu) { + for (IMarker marker : group.getMarkers()) { + if (!marker.isHidden()) { + groupMenu.add(makeMarkerCommandContributionItem(marker)); + } + } + } + + private IContributionItem makeMarkerCommandContributionItem( + IMarker marker) { + CommandContributionItemParameter parameter = new CommandContributionItemParameter( + serviceLocator, "addMarker." + marker.getId(), //$NON-NLS-1$ + MindMapCommandConstants.ADD_MARKER, + CommandContributionItem.STYLE_PUSH); + parameter.label = marker.getName(); + parameter.icon = MarkerImageDescriptor.createFromMarker(marker); + Map params = new HashMap(); + params.put(MindMapCommandConstants.ADD_MARKER_PARAM_MARKER_ID, + marker.getId()); + parameter.parameters = params; + return new CommandContributionItem(parameter); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutAction.java index 297a5afaa..b71f9bccf 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutAction.java @@ -1,24 +1,25 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.prefs.PrefConstants; - -public class AllowManualLayoutAction extends BooleanPrefAction { - - public AllowManualLayoutAction(IPreferenceStore prefStore) { - super(prefStore, PrefConstants.MANUAL_LAYOUT_ALLOWED); - setId("org.xmind.ui.allowManualLayout"); //$NON-NLS-1$ - setText(MindMapMessages.AllowManualLayout_text); - setToolTipText(MindMapMessages.AllowManualLayout_toolTip); - } - - @Override - public void run() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("AllowFreePositionCount"); //$NON-NLS-1$ - super.run(); - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; + +public class AllowManualLayoutAction extends BooleanPrefAction { + + public AllowManualLayoutAction(IPreferenceStore prefStore) { + super(prefStore, PrefConstants.MANUAL_LAYOUT_ALLOWED); + setId("org.xmind.ui.allowManualLayout"); //$NON-NLS-1$ + setText(MindMapMessages.AllowManualLayout_text); + setToolTipText(MindMapMessages.AllowManualLayout_toolTip); + } + + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.ALLOW_FREE_POSITION_COUNT); + super.run(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutMenu.java index 9b4ff25cf..6644c35f3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutMenu.java @@ -1,83 +1,83 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.ISheet; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.MindMapEditor; - -public class AllowManualLayoutMenu extends ContributionItem - implements IWorkbenchContribution { - - private boolean dirty = true; -// IGraphicalEditorPage page; - IWorkbenchWindow window; - private IMenuListener menuListener = new IMenuListener() { - - public void menuAboutToShow(IMenuManager manager) { - manager.markDirty(); - dirty = true; - } - }; - - @Override - public boolean isDynamic() { - return true; - } - - @Override - public void fill(Menu menu, int index) { - if (getParent() instanceof MenuManager) - ((MenuManager) getParent()).addMenuListener(menuListener); - if (!dirty) - return; - - MenuManager manager = new MenuManager(); - fillMenu(manager); - IContributionItem items[] = manager.getItems(); - if (items.length > 0) { - for (int i = 0; i < items.length; i++) { - items[i].fill(menu, index++); - } - } - dirty = false; - } - - public void fillMenu(MenuManager menuManager) { - IPreferenceStore prefStore = MindMapUIPlugin.getDefault() - .getPreferenceStore(); - AllowManualLayoutAction allowManualLayoutAction = new AllowManualLayoutAction( - prefStore); - IWorkbenchPart part = window.getActivePage().getActivePart(); - if (null == part || !(part instanceof MindMapEditor)) { - allowManualLayoutAction.setEnabled(false); - } else if (part instanceof MindMapEditor) { - IGraphicalEditorPage page = ((MindMapEditor) part) - .getActivePageInstance(); - if (page != null) { - ISheet sheet = page.getAdapter(ISheet.class); - String structureClass = sheet.getRootTopic() - .getStructureClass(); - allowManualLayoutAction.setEnabled(structureClass == null - || structureClass.contains("org.xmind.ui.map")); //$NON-NLS-1$ - } - - } - menuManager.add(allowManualLayoutAction); - } - - @Override - public void initialize(IServiceLocator serviceLocator) { - window = serviceLocator.getService(IWorkbenchWindow.class); - } -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.ISheet; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.editor.MindMapEditor; + +public class AllowManualLayoutMenu extends ContributionItem + implements IWorkbenchContribution { + + private boolean dirty = true; +// IGraphicalEditorPage page; + IWorkbenchWindow window; + private IMenuListener menuListener = new IMenuListener() { + + public void menuAboutToShow(IMenuManager manager) { + manager.markDirty(); + dirty = true; + } + }; + + @Override + public boolean isDynamic() { + return true; + } + + @Override + public void fill(Menu menu, int index) { + if (getParent() instanceof MenuManager) + ((MenuManager) getParent()).addMenuListener(menuListener); + if (!dirty) + return; + + MenuManager manager = new MenuManager(); + fillMenu(manager); + IContributionItem items[] = manager.getItems(); + if (items.length > 0) { + for (int i = 0; i < items.length; i++) { + items[i].fill(menu, index++); + } + } + dirty = false; + } + + public void fillMenu(MenuManager menuManager) { + IPreferenceStore prefStore = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + AllowManualLayoutAction allowManualLayoutAction = new AllowManualLayoutAction( + prefStore); + IWorkbenchPart part = window.getActivePage().getActivePart(); + if (null == part || !(part instanceof MindMapEditor)) { + allowManualLayoutAction.setEnabled(false); + } else if (part instanceof MindMapEditor) { + IGraphicalEditorPage page = ((MindMapEditor) part) + .getActivePageInstance(); + if (page != null) { + ISheet sheet = page.getAdapter(ISheet.class); + String structureClass = sheet.getRootTopic() + .getStructureClass(); + allowManualLayoutAction.setEnabled(structureClass == null + || structureClass.contains("org.xmind.ui.map")); //$NON-NLS-1$ + } + + } + menuManager.add(allowManualLayoutAction); + } + + @Override + public void initialize(IServiceLocator serviceLocator) { + window = serviceLocator.getService(IWorkbenchWindow.class); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsAction.java index ab6645c3b..4c65ede0b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsAction.java @@ -1,37 +1,38 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.prefs.PrefConstants; - -public class AllowOverlapsAction extends BooleanPrefAction { - - public AllowOverlapsAction(IPreferenceStore prefStore) { - super(prefStore, PrefConstants.OVERLAPS_ALLOWED); - setId("org.xmind.ui.allowOverlaps"); //$NON-NLS-1$ - setText(MindMapMessages.AllowOverlaps_text); - setToolTipText(MindMapMessages.AllowOverlaps_toolTip); - } - - @Override - public void run() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("AllowOverlapCount"); //$NON-NLS-1$ - super.run(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; + +public class AllowOverlapsAction extends BooleanPrefAction { + + public AllowOverlapsAction(IPreferenceStore prefStore) { + super(prefStore, PrefConstants.OVERLAPS_ALLOWED); + setId("org.xmind.ui.allowOverlaps"); //$NON-NLS-1$ + setText(MindMapMessages.AllowOverlaps_text); + setToolTipText(MindMapMessages.AllowOverlaps_toolTip); + } + + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.ALLOW_OVERLAP_COUNT); + super.run(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsMenu.java index 7b1990d1f..d6253bfe3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowOverlapsMenu.java @@ -1,92 +1,92 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.ISheet; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.MindMapEditor; - -public class AllowOverlapsMenu extends ContributionItem - implements IWorkbenchContribution { - - private boolean dirty = true; - IWorkbenchWindow window; - - private IMenuListener menuListener = new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - manager.markDirty(); - dirty = true; - } - }; - - public boolean isDirty() { - return dirty; - } - - /** - * Overridden to always return true and force dynamic menu building. - */ - public boolean isDynamic() { - return true; - } - - public void fill(Menu menu, int index) { - - if (getParent() instanceof MenuManager) { - ((MenuManager) getParent()).addMenuListener(menuListener); - } - - if (!dirty) { - return; - } - - MenuManager manager = new MenuManager(); - fillMenu(manager); - IContributionItem items[] = manager.getItems(); - if (items.length > 0) { - for (int i = 0; i < items.length; i++) { - items[i].fill(menu, index++); - } - } - dirty = false; - } - - private void fillMenu(MenuManager manager) { - IPreferenceStore prefStore = MindMapUIPlugin.getDefault() - .getPreferenceStore(); - AllowOverlapsAction allowOverlapsAction = new AllowOverlapsAction( - prefStore); - IWorkbenchPart part = window.getActivePage().getActivePart(); - if (null == part || !(part instanceof MindMapEditor)) { - allowOverlapsAction.setEnabled(false); - } else if (part instanceof MindMapEditor) { - IGraphicalEditorPage page = ((MindMapEditor) part) - .getActivePageInstance(); - if (page != null) { - ISheet sheet = page.getAdapter(ISheet.class); - String structureClass = sheet.getRootTopic() - .getStructureClass(); - allowOverlapsAction.setEnabled(structureClass == null - || structureClass.contains("org.xmind.ui.map")); //$NON-NLS-1$ - } - - } - manager.add(allowOverlapsAction); - } - - @Override - public void initialize(IServiceLocator serviceLocator) { - window = serviceLocator.getService(IWorkbenchWindow.class); - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.ISheet; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.editor.MindMapEditor; + +public class AllowOverlapsMenu extends ContributionItem + implements IWorkbenchContribution { + + private boolean dirty = true; + IWorkbenchWindow window; + + private IMenuListener menuListener = new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + manager.markDirty(); + dirty = true; + } + }; + + public boolean isDirty() { + return dirty; + } + + /** + * Overridden to always return true and force dynamic menu building. + */ + public boolean isDynamic() { + return true; + } + + public void fill(Menu menu, int index) { + + if (getParent() instanceof MenuManager) { + ((MenuManager) getParent()).addMenuListener(menuListener); + } + + if (!dirty) { + return; + } + + MenuManager manager = new MenuManager(); + fillMenu(manager); + IContributionItem items[] = manager.getItems(); + if (items.length > 0) { + for (int i = 0; i < items.length; i++) { + items[i].fill(menu, index++); + } + } + dirty = false; + } + + private void fillMenu(MenuManager manager) { + IPreferenceStore prefStore = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + AllowOverlapsAction allowOverlapsAction = new AllowOverlapsAction( + prefStore); + IWorkbenchPart part = window.getActivePage().getActivePart(); + if (null == part || !(part instanceof MindMapEditor)) { + allowOverlapsAction.setEnabled(false); + } else if (part instanceof MindMapEditor) { + IGraphicalEditorPage page = ((MindMapEditor) part) + .getActivePageInstance(); + if (page != null) { + ISheet sheet = page.getAdapter(ISheet.class); + String structureClass = sheet.getRootTopic() + .getStructureClass(); + allowOverlapsAction.setEnabled(structureClass == null + || structureClass.contains("org.xmind.ui.map")); //$NON-NLS-1$ + } + + } + manager.add(allowOverlapsAction); + } + + @Override + public void initialize(IServiceLocator serviceLocator) { + window = serviceLocator.getService(IWorkbenchWindow.class); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/BaseNewFromTemplateAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/BaseNewFromTemplateAction.java index 583f0c2b2..1ff46b9e3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/BaseNewFromTemplateAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/BaseNewFromTemplateAction.java @@ -1,106 +1,106 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.io.File; -import java.io.InputStream; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.core.Core; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.editor.MME; -import org.xmind.ui.mindmap.MindMapUI; - -public abstract class BaseNewFromTemplateAction extends Action implements - IWorkbenchAction { - - private IWorkbenchWindow window; - - private final IEditorPart[] editorPart = new IEditorPart[1]; - - protected BaseNewFromTemplateAction(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - this.window = window; - } - - public void run() { - if (window == null) - return; - - final IWorkbenchPage page = window.getActivePage(); - if (page == null) - return; - - final InputStream templateStream; - try { - templateStream = getTemplateStream(window.getShell()); - } catch (Exception e) { - notifyTemplateMissing(window.getShell()); - return; - } - - if (templateStream == null) - return; - - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IEditorInput input = MME - .createTemplatedEditorInput(templateStream); - editorPart[0] = page.openEditor(input, - MindMapUI.MINDMAP_EDITOR_ID); - } - }); - } - - public IEditorPart getEditorPart() { - return editorPart[0]; - } - - /** - * @param shell - */ - protected void notifyTemplateMissing(Shell shell) { - MessageDialog.openError(shell, DialogMessages.CommonDialogTitle, NLS - .bind(DialogMessages.TemplateMissing_message, getText())); - } - - protected abstract InputStream getTemplateStream(Shell shell) - throws Exception; - - protected IWorkbook createWorkbookFromTemplate(InputStream is) - throws Exception { - String tempLocation = Core.getWorkspace().getTempFile( - Core.getIdFactory().createId() + MindMapUI.FILE_EXT_XMIND); - FileUtils.ensureDirectory(new File(tempLocation)); - return Core.getWorkbookBuilder().loadFromStream(is, tempLocation); - } - - public void dispose() { - window = null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.io.File; +import java.io.InputStream; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.core.Core; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.mindmap.MindMapUI; + +public abstract class BaseNewFromTemplateAction extends Action implements + IWorkbenchAction { + + private IWorkbenchWindow window; + + private final IEditorPart[] editorPart = new IEditorPart[1]; + + protected BaseNewFromTemplateAction(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + this.window = window; + } + + public void run() { + if (window == null) + return; + + final IWorkbenchPage page = window.getActivePage(); + if (page == null) + return; + + final InputStream templateStream; + try { + templateStream = getTemplateStream(window.getShell()); + } catch (Exception e) { + notifyTemplateMissing(window.getShell()); + return; + } + + if (templateStream == null) + return; + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IEditorInput input = MME + .createTemplatedEditorInput(templateStream); + editorPart[0] = page.openEditor(input, + MindMapUI.MINDMAP_EDITOR_ID); + } + }); + } + + public IEditorPart getEditorPart() { + return editorPart[0]; + } + + /** + * @param shell + */ + protected void notifyTemplateMissing(Shell shell) { + MessageDialog.openError(shell, DialogMessages.CommonDialogTitle, NLS + .bind(DialogMessages.TemplateMissing_message, getText())); + } + + protected abstract InputStream getTemplateStream(Shell shell) + throws Exception; + + protected IWorkbook createWorkbookFromTemplate(InputStream is) + throws Exception { + String tempLocation = Core.getWorkspace().getTempFile( + Core.getIdFactory().createId() + MindMapUI.FILE_EXT_XMIND); + FileUtils.ensureDirectory(new File(tempLocation)); + return Core.getWorkbookBuilder().loadFromStream(is, tempLocation); + } + + public void dispose() { + window = null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CancelHyperlinkAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CancelHyperlinkAction.java index d94267df1..db8726612 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CancelHyperlinkAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CancelHyperlinkAction.java @@ -1,82 +1,82 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.ITopic; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -/** - * @author frankshaka - * - */ -public class CancelHyperlinkAction extends PageAction implements - ISelectionAction { - - /** - * - */ - public CancelHyperlinkAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.CANCEL_HYPERLINK.getId(), page); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - public void run() { - if (isDisposed()) - return; - - sendRequest(new Request(MindMapUI.REQ_MODIFY_HYPERLINK).setParameter( - GEF.PARAM_TEXT, null)); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.gef.ui.actions.ISelectionAction#setSelection(org.eclipse.jface - * .viewers.ISelection) - */ - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection) - && hasModifiableHyperlink(selection)); - } - - /** - * @param selection - * @return - */ - private boolean hasModifiableHyperlink(ISelection selection) { - Object topic = ((IStructuredSelection) selection).getFirstElement(); - if (topic == null || !(topic instanceof ITopic)) - return false; - String hyperlink = ((ITopic) topic).getHyperlink(); - if (hyperlink == null) - return false; - return MindMapUI.getProtocolManager().isHyperlinkModifiable(topic, - hyperlink); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.ITopic; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +/** + * @author frankshaka + * + */ +public class CancelHyperlinkAction extends PageAction implements + ISelectionAction { + + /** + * + */ + public CancelHyperlinkAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.CANCEL_HYPERLINK.getId(), page); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + public void run() { + if (isDisposed()) + return; + + sendRequest(new Request(MindMapUI.REQ_MODIFY_HYPERLINK).setParameter( + GEF.PARAM_TEXT, null)); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.gef.ui.actions.ISelectionAction#setSelection(org.eclipse.jface + * .viewers.ISelection) + */ + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection) + && hasModifiableHyperlink(selection)); + } + + /** + * @param selection + * @return + */ + private boolean hasModifiableHyperlink(ISelection selection) { + Object topic = ((IStructuredSelection) selection).getFirstElement(); + if (topic == null || !(topic instanceof ITopic)) + return false; + String hyperlink = ((ITopic) topic).getHyperlink(); + if (hyperlink == null) + return false; + return MindMapUI.getProtocolManager().isHyperlinkModifiable(topic, + hyperlink); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CollapseAllAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CollapseAllAction.java index 2c880f812..3614ed296 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CollapseAllAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CollapseAllAction.java @@ -1,72 +1,72 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.GEF; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class CollapseAllAction extends RequestAction - implements ISelectionAction { - - public CollapseAllAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.COLLAPSE_ALL.getId(), page, - GEF.REQ_COLLAPSE_ALL); - } - - public void setSelection(ISelection selection) { - //1.select sheet (which root topic has attached children). - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - if (structuredSelection.size() == 1) { - Object obj = structuredSelection.getFirstElement(); - if (obj instanceof ISheet) { - ISheet sheet = (ISheet) obj; - setEnabled(sheet.getRootTopic().getChildren(ITopic.ATTACHED) - .size() != 0); - return; - } - } - } - - //2.select topics (at least one topic has attached children). - if (MindMapUtils.isAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC)) { - boolean enabled = false; - List topics = MindMapUtils.getAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC); - for (Object topic : topics) { - if (((ITopic) topic).getChildren(ITopic.ATTACHED).size() != 0) { - enabled = true; - break; - } - } - setEnabled(enabled); - return; - } - - setEnabled(false); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.GEF; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class CollapseAllAction extends RequestAction + implements ISelectionAction { + + public CollapseAllAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.COLLAPSE_ALL.getId(), page, + GEF.REQ_COLLAPSE_ALL); + } + + public void setSelection(ISelection selection) { + //1.select sheet (which root topic has attached children). + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + if (structuredSelection.size() == 1) { + Object obj = structuredSelection.getFirstElement(); + if (obj instanceof ISheet) { + ISheet sheet = (ISheet) obj; + setEnabled(sheet.getRootTopic().getChildren(ITopic.ATTACHED) + .size() != 0); + return; + } + } + } + + //2.select topics (at least one topic has attached children). + if (MindMapUtils.isAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC)) { + boolean enabled = false; + List topics = MindMapUtils.getAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC); + for (Object topic : topics) { + if (((ITopic) topic).getChildren(ITopic.ATTACHED).size() != 0) { + enabled = true; + break; + } + } + setEnabled(enabled); + return; + } + + setEnabled(false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopiedSheetStorageSupport.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopiedSheetStorageSupport.java index 93ea41df7..9596c95b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopiedSheetStorageSupport.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopiedSheetStorageSupport.java @@ -1,54 +1,54 @@ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; - -public class CopiedSheetStorageSupport { - private static CopiedSheetStorageSupport instance = null; - - private ISheet copiedSheet = null; - - private CopiedSheetStorageSupport() { - } - - public static CopiedSheetStorageSupport getInstance() { - if (instance == null) { - instance = new CopiedSheetStorageSupport(); - } - return instance; - } - - public void setCopiedSheet(ISheet sheet) { - copiedSheet = cloneSheet(sheet); - } - - public ISheet getCopiedSheet(IWorkbook workbook) { - return cloneSheet(workbook, copiedSheet); - } - - public boolean isCopiedSheetExist() { - return copiedSheet != null; - } - - private ISheet cloneSheet(ISheet sheet) { - IWorkbook workbook = Core.getWorkbookBuilder().createWorkbook(); - return cloneSheet(workbook, sheet); - } - - public ISheet cloneSheet(IWorkbook workbook, ISheet sheet) { - if (sheet == null) { - return null; - } - List sheetList = new ArrayList(); - sheetList.add(sheet); - ISheet clonedSheet = (ISheet) workbook.clone(sheetList).getCloneds() - .iterator().next(); - - return clonedSheet; - } - -} +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; + +public class CopiedSheetStorageSupport { + private static CopiedSheetStorageSupport instance = null; + + private ISheet copiedSheet = null; + + private CopiedSheetStorageSupport() { + } + + public static CopiedSheetStorageSupport getInstance() { + if (instance == null) { + instance = new CopiedSheetStorageSupport(); + } + return instance; + } + + public void setCopiedSheet(ISheet sheet) { + copiedSheet = cloneSheet(sheet); + } + + public ISheet getCopiedSheet(IWorkbook workbook) { + return cloneSheet(workbook, copiedSheet); + } + + public boolean isCopiedSheetExist() { + return copiedSheet != null; + } + + private ISheet cloneSheet(ISheet sheet) { + IWorkbook workbook = Core.getWorkbookBuilder().createWorkbook(); + return cloneSheet(workbook, sheet); + } + + public ISheet cloneSheet(IWorkbook workbook, ISheet sheet) { + if (sheet == null) { + return null; + } + List sheetList = new ArrayList(); + sheetList.add(sheet); + ISheet clonedSheet = (ISheet) workbook.clone(sheetList).getCloneds() + .iterator().next(); + + return clonedSheet; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopySheetAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopySheetAction.java index cf015fbe6..3d0bf3ec3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopySheetAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CopySheetAction.java @@ -1,36 +1,36 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.core.ISheet; -import org.xmind.gef.ui.actions.EditorAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; - -public class CopySheetAction extends EditorAction { - - public CopySheetAction(IGraphicalEditor editor) { - super(MindMapActionFactory.COPY_SHEET.getId(), editor); - } - - @Override - public void run() { - if (isDisposed()) - return; - - IGraphicalEditorPage page = getActivePage(); - if (page != null) { - ISheet sheet = (ISheet) page.getAdapter(ISheet.class); - - if (sheet == null) { - Object input = page.getInput(); - if (input instanceof ISheet) { - sheet = (ISheet) input; - } - } - - if (sheet != null) { - CopiedSheetStorageSupport.getInstance().setCopiedSheet(sheet); - } - } - } -} +package org.xmind.ui.internal.actions; + +import org.xmind.core.ISheet; +import org.xmind.gef.ui.actions.EditorAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; + +public class CopySheetAction extends EditorAction { + + public CopySheetAction(IGraphicalEditor editor) { + super(MindMapActionFactory.COPY_SHEET.getId(), editor); + } + + @Override + public void run() { + if (isDisposed()) + return; + + IGraphicalEditorPage page = getActivePage(); + if (page != null) { + ISheet sheet = (ISheet) page.getAdapter(ISheet.class); + + if (sheet == null) { + Object input = page.getInput(); + if (input instanceof ISheet) { + sheet = (ISheet) input; + } + } + + if (sheet != null) { + CopiedSheetStorageSupport.getInstance().setCopiedSheet(sheet); + } + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateCommentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateCommentAction.java index 662cd4933..99ad5848e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateCommentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateCommentAction.java @@ -1,64 +1,64 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.comments.CommentAction; -import org.xmind.ui.internal.comments.ICommentTextViewerContainer; -import org.xmind.ui.mindmap.MindMapUI; - -/** - * @deprecated - * @author Frank Shaka - * - */ -@Deprecated -public class CreateCommentAction extends CommentAction { - - private Object target; - - private ICommentTextViewerContainer container; - - public CreateCommentAction(IGraphicalEditor editor, Object target, - ICommentTextViewerContainer container) { - super(editor); - this.target = target; - this.container = container; - - setId("org.xmind.ui.action.addComment"); //$NON-NLS-1$ - setText(MindMapMessages.AddComment_text); - setImageDescriptor(MindMapUI.getImages().get("new-comment.png", true)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.AddComment_tooltip); - } - - public void run() { -// setEnabled(false); -// control = container.getContentComposite(); -// super.run(); -// final CreateCommentCommand cmd = new CreateCommentCommand(target); -// -// Display.getCurrent().timerExec(50, new Runnable() { -// public void run() { -// -// Display.getCurrent().asyncExec(new Runnable() { -// public void run() { -// cmd.execute(); -// setEnabled(true); -// } -// }); -// } -// }); - } - - @Override - public void selectionChanged(Object selection) { - if (selection instanceof ITopic || selection instanceof ISheet) { - this.target = selection; - setEnabled(true); - } else { - setEnabled(false); - } - } - -} +package org.xmind.ui.internal.actions; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.comments.CommentAction; +import org.xmind.ui.internal.comments.ICommentTextViewerContainer; +import org.xmind.ui.mindmap.MindMapUI; + +/** + * @deprecated + * @author Frank Shaka + * + */ +@Deprecated +public class CreateCommentAction extends CommentAction { + + private Object target; + + private ICommentTextViewerContainer container; + + public CreateCommentAction(IGraphicalEditor editor, Object target, + ICommentTextViewerContainer container) { + super(editor); + this.target = target; + this.container = container; + + setId("org.xmind.ui.action.addComment"); //$NON-NLS-1$ + setText(MindMapMessages.AddComment_text); + setImageDescriptor(MindMapUI.getImages().get("new-comment.png", true)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.AddComment_tooltip); + } + + public void run() { +// setEnabled(false); +// control = container.getContentComposite(); +// super.run(); +// final CreateCommentCommand cmd = new CreateCommentCommand(target); +// +// Display.getCurrent().timerExec(50, new Runnable() { +// public void run() { +// +// Display.getCurrent().asyncExec(new Runnable() { +// public void run() { +// cmd.execute(); +// setEnabled(true); +// } +// }); +// } +// }); + } + + @Override + public void selectionChanged(Object selection) { + if (selection instanceof ITopic || selection instanceof ISheet) { + this.target = selection; + setEnabled(true); + } else { + setEnabled(false); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateRelationshipAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateRelationshipAction.java index a33c20688..dbe0c4700 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateRelationshipAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateRelationshipAction.java @@ -13,12 +13,14 @@ *******************************************************************************/ package org.xmind.ui.internal.actions; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ui.actions.RequestAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.ui.actions.MindMapActionFactory; import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.MindMapUI; +@Deprecated public class CreateRelationshipAction extends RequestAction { public CreateRelationshipAction(IGraphicalEditorPage page) { @@ -29,7 +31,7 @@ public CreateRelationshipAction(IGraphicalEditorPage page) { @Override public void run() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("InsertRelationshipCount"); //$NON-NLS-1$ + .increase(UserDataConstants.INSERT_RELATIONSHIP_COUNT); super.run(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetAction.java index dca3d9669..f95af27d5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetAction.java @@ -1,89 +1,90 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IEditorInput; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.style.IStyle; -import org.xmind.gef.ui.actions.EditorAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.CreateSheetCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.WorkbookEditorInput; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.StyleUtils; - -public class CreateSheetAction extends EditorAction { - - private IGraphicalEditor editor; - - public CreateSheetAction(IGraphicalEditor editor) { - super(MindMapActionFactory.NEW_SHEET.getId(), editor); - } - - public void run() { - if (isDisposed()) - return; - - editor = getEditor(); - if (editor != null) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateSheetCount`"); //$NON-NLS-1$ - - IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); - - if (workbook == null) { - IEditorInput input = editor.getEditorInput(); - if (input instanceof WorkbookEditorInput) { - workbook = ((WorkbookEditorInput) input).getContents(); - } else if (input != null) { - workbook = (IWorkbook) input.getAdapter(IWorkbook.class); - } - } - if (workbook == null) - return; - saveAndRunCreateSheetCommand(workbook); - } - } - - protected void saveAndRunCreateSheetCommand(IWorkbook workbook) { - CreateSheetCommand command = new CreateSheetCommand(workbook, null); - command.setLabel(CommandMessages.Command_CreateSheet); - - saveAndRun(command); - - ISheet sheet = (ISheet) command.getSource(); - if (sheet != null) { - decorateCreatedSheet(sheet); - } - } - - protected void decorateCreatedSheet(ISheet sheet) { - sheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, - sheet.getParent().getSheets().size())); - - sheet.getRootTopic() - .setTitleText(MindMapMessages.TitleText_CentralTopic); - sheet.getRootTopic().setStructureClass("org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ - - IStyle theme = MindMapUI.getResourceManager().getDefaultTheme(); - StyleUtils.setTheme(sheet, theme); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IEditorInput; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.style.IStyle; +import org.xmind.gef.ui.actions.EditorAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.CreateSheetCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.editor.WorkbookEditorInput; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.StyleUtils; + +public class CreateSheetAction extends EditorAction { + + private static final String CREATE_SHEET_COUNT = "CreateSheetCount"; //$NON-NLS-1$ + private IGraphicalEditor editor; + + public CreateSheetAction(IGraphicalEditor editor) { + super(MindMapActionFactory.NEW_SHEET.getId(), editor); + } + + public void run() { + if (isDisposed()) + return; + + editor = getEditor(); + if (editor != null) { + IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); + + if (workbook == null) { + IEditorInput input = editor.getEditorInput(); + if (input instanceof WorkbookEditorInput) { + workbook = ((WorkbookEditorInput) input).getContents(); + } else if (input != null) { + workbook = (IWorkbook) input.getAdapter(IWorkbook.class); + } + } + if (workbook == null) + return; + saveAndRunCreateSheetCommand(workbook); + } + } + + protected void saveAndRunCreateSheetCommand(IWorkbook workbook) { + CreateSheetCommand command = new CreateSheetCommand(workbook, null); + command.setLabel(CommandMessages.Command_CreateSheet); + + saveAndRun(command); + + ISheet sheet = (ISheet) command.getSource(); + if (sheet != null) { + decorateCreatedSheet(sheet); + } + } + + protected void decorateCreatedSheet(ISheet sheet) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(CREATE_SHEET_COUNT); + + sheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, + sheet.getParent().getSheets().size())); + + sheet.getRootTopic() + .setTitleText(MindMapMessages.TitleText_CentralTopic); + sheet.getRootTopic().setStructureClass("org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ + + IStyle theme = MindMapUI.getResourceManager().getDefaultTheme(); + StyleUtils.setTheme(sheet, theme); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetFromTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetFromTopicAction.java index 3945e4174..9cb772127 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetFromTopicAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CreateSheetFromTopicAction.java @@ -14,26 +14,29 @@ package org.xmind.ui.internal.actions; import org.eclipse.jface.viewers.ISelection; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ui.actions.ISelectionAction; import org.xmind.gef.ui.actions.RequestAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.MindMapUtils; /** * @author karelun Huang - * */ -public class CreateSheetFromTopicAction extends RequestAction implements - ISelectionAction { +public class CreateSheetFromTopicAction extends RequestAction + implements ISelectionAction { public CreateSheetFromTopicAction(IGraphicalEditorPage page) { super(MindMapActionFactory.INSERT_SHEET_FROM.getId(), page, MindMapUI.REQ_CREATE_SHEET); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CREATE_SHEET_COUNT); } public void setSelection(ISelection selection) { setEnabled(MindMapUtils.isSingleTopic(selection)); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CutAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CutAction.java index 148809394..98265d709 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CutAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CutAction.java @@ -1,32 +1,32 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class CutAction extends org.xmind.gef.ui.actions.CutAction { - - public CutAction(IGraphicalEditorPage page) { - super(page); - } - - protected boolean canDelete(ISelection selection) { - return !MindMapUtils.hasSuchElements(selection, - MindMapUI.CATEGORY_SHEET) - && !MindMapUtils.hasCentralTopic(selection, getViewer()); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class CutAction extends org.xmind.gef.ui.actions.CutAction { + + public CutAction(IGraphicalEditorPage page) { + super(page); + } + + protected boolean canDelete(ISelection selection) { + return !MindMapUtils.hasSuchElements(selection, + MindMapUI.CATEGORY_SHEET) + && !MindMapUtils.hasCentralTopic(selection, getViewer()); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteCommentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteCommentAction.java index b69403de8..7b7447a6d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteCommentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteCommentAction.java @@ -1,51 +1,51 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.core.IComment; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.commands.DeleteCommentCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.comments.CommentAction; -import org.xmind.ui.mindmap.MindMapUI; - -public class DeleteCommentAction extends CommentAction { - - private IComment comment; - - public DeleteCommentAction(IGraphicalEditor editor) { - super(editor); - - setId("org.xmind.ui.action.deleteComment"); //$NON-NLS-1$ - setText(MindMapMessages.DeleteComment_text); - setImageDescriptor( - MindMapUI.getImages().get("delete-comment.png", true)); //$NON-NLS-1$ - setDisabledImageDescriptor( - MindMapUI.getImages().get("delete-comment.png", false)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.DeleteComment_tooltip); - } - - public void run() { - if (comment == null) - return; - - Object target = comment.getOwnedWorkbook() - .getElementById(comment.getObjectId()); - if (target == null) - return; - - DeleteCommentCommand cmd = new DeleteCommentCommand(target, comment); - ICommandStack commandStack = getCommandStack(); - if (commandStack != null) { - commandStack.execute(cmd); - } else { - cmd.execute(); - } - } - - @Override - public void selectedCommentChanged(IComment comment) { - this.comment = comment; - setEnabled(comment != null); - } - -} +package org.xmind.ui.internal.actions; + +import org.xmind.core.IComment; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.commands.DeleteCommentCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.comments.CommentAction; +import org.xmind.ui.mindmap.MindMapUI; + +public class DeleteCommentAction extends CommentAction { + + private IComment comment; + + public DeleteCommentAction(IGraphicalEditor editor) { + super(editor); + + setId("org.xmind.ui.action.deleteComment"); //$NON-NLS-1$ + setText(MindMapMessages.DeleteComment_text); + setImageDescriptor( + MindMapUI.getImages().get("delete-comment.png", true)); //$NON-NLS-1$ + setDisabledImageDescriptor( + MindMapUI.getImages().get("delete-comment.png", false)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.DeleteComment_tooltip); + } + + public void run() { + if (comment == null) + return; + + Object target = comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()); + if (target == null) + return; + + DeleteCommentCommand cmd = new DeleteCommentCommand(target, comment); + ICommandStack commandStack = getCommandStack(); + if (commandStack != null) { + commandStack.execute(cmd); + } else { + cmd.execute(); + } + } + + @Override + public void selectedCommentChanged(IComment comment) { + this.comment = comment; + setEnabled(comment != null); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteNotesAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteNotesAction.java index 13c1b1956..34756b70c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteNotesAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteNotesAction.java @@ -1,53 +1,53 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.ITopic; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.ui.commands.DeleteNotesCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.notes.SheetNotesViewer; -import org.xmind.ui.mindmap.MindMapUI; - -public class DeleteNotesAction extends Action implements ISelectionAction { - - private SheetNotesViewer viewer; - - private ITopic topic; - - public DeleteNotesAction(SheetNotesViewer viewer) { - this.viewer = viewer; - - setId("org.xmind.ui.action.deleteNotes"); //$NON-NLS-1$ - setText(MindMapMessages.DeleteNotes_text); - setImageDescriptor(MindMapUI.getImages().get("del_notes.gif", true)); //$NON-NLS-1$ - setDisabledImageDescriptor( - MindMapUI.getImages().get("del_notes.gif", false)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.DeleteNotes_tooltip); - } - - public void run() { - if (topic == null || viewer == null) { - return; - } - DeleteNotesCommand cmd = new DeleteNotesCommand(topic); - ICommandStack cs = viewer.getEditor().getCommandStack(); - cs.execute(cmd); - } - - public void setSelection(ISelection selection) { - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (obj instanceof ITopic) { - this.topic = (ITopic) obj; - setEnabled(true); - return; - } - } - this.topic = null; - setEnabled(false); - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.ITopic; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.ui.commands.DeleteNotesCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.notes.SheetNotesViewer; +import org.xmind.ui.mindmap.MindMapUI; + +public class DeleteNotesAction extends Action implements ISelectionAction { + + private SheetNotesViewer viewer; + + private ITopic topic; + + public DeleteNotesAction(SheetNotesViewer viewer) { + this.viewer = viewer; + + setId("org.xmind.ui.action.deleteNotes"); //$NON-NLS-1$ + setText(MindMapMessages.DeleteNotes_text); + setImageDescriptor(MindMapUI.getImages().get("del_notes.gif", true)); //$NON-NLS-1$ + setDisabledImageDescriptor( + MindMapUI.getImages().get("del_notes.gif", false)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.DeleteNotes_tooltip); + } + + public void run() { + if (topic == null || viewer == null) { + return; + } + DeleteNotesCommand cmd = new DeleteNotesCommand(topic); + ICommandStack cs = viewer.getEditor().getCommandStack(); + cs.execute(cmd); + } + + public void setSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof ITopic) { + this.topic = (ITopic) obj; + setEnabled(true); + return; + } + } + this.topic = null; + setEnabled(false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteOtherSheetsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteOtherSheetsAction.java index 6ea4e0277..5cf6471d3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteOtherSheetsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteOtherSheetsAction.java @@ -1,68 +1,68 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.ui.actions.EditorAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteSheetCommand; - -/** - * - * @author Karelun huang - */ -public class DeleteOtherSheetsAction extends EditorAction { - - public DeleteOtherSheetsAction(IGraphicalEditor editor) { - super(MindMapActionFactory.DELETE_OTHER_SHEET.getId(), editor); - - } - - public void run() { - if (isDisposed()) - return; - IGraphicalEditorPage page = getActivePage(); - if (page == null) - return; - ISheet activeSheet = (ISheet) page.getAdapter(ISheet.class); - if (activeSheet == null) { - Object input = page.getInput(); - if (input instanceof ISheet) - activeSheet = (ISheet) input; - } - if (activeSheet != null) { - IWorkbook workbook = activeSheet.getOwnedWorkbook(); - List sheets = workbook.getSheets(); - List commands = new ArrayList(sheets.size() - 1); - for (ISheet sheet : sheets) { - if (activeSheet.equals(sheet)) - continue; - commands.add(new DeleteSheetCommand(sheet)); - } - - saveAndRun(new CompoundCommand(CommandMessages.Command_DeleteSheet, - commands)); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.ui.actions.EditorAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteSheetCommand; + +/** + * + * @author Karelun huang + */ +public class DeleteOtherSheetsAction extends EditorAction { + + public DeleteOtherSheetsAction(IGraphicalEditor editor) { + super(MindMapActionFactory.DELETE_OTHER_SHEET.getId(), editor); + + } + + public void run() { + if (isDisposed()) + return; + IGraphicalEditorPage page = getActivePage(); + if (page == null) + return; + ISheet activeSheet = (ISheet) page.getAdapter(ISheet.class); + if (activeSheet == null) { + Object input = page.getInput(); + if (input instanceof ISheet) + activeSheet = (ISheet) input; + } + if (activeSheet != null) { + IWorkbook workbook = activeSheet.getOwnedWorkbook(); + List sheets = workbook.getSheets(); + List commands = new ArrayList(sheets.size() - 1); + for (ISheet sheet : sheets) { + if (activeSheet.equals(sheet)) + continue; + commands.add(new DeleteSheetCommand(sheet)); + } + + saveAndRun(new CompoundCommand(CommandMessages.Command_DeleteSheet, + commands)); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteSheetAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteSheetAction.java index 873284783..6c25f2c13 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteSheetAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DeleteSheetAction.java @@ -1,66 +1,66 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.xmind.core.ISheet; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.ui.actions.EditorAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteSheetCommand; - -public class DeleteSheetAction extends EditorAction { - - public DeleteSheetAction(IGraphicalEditor editor) { - super(MindMapActionFactory.DELETE_SHEET.getId(), editor); - } - - public void run() { - if (isDisposed()) - return; - - IGraphicalEditorPage page = getActivePage(); - if (page != null) { - ISheet sheet = (ISheet) page.getAdapter(ISheet.class); - - if (sheet == null) { - Object input = page.getInput(); - if (input instanceof ISheet) { - sheet = (ISheet) input; - } - } - - if (sheet != null && sheet.getParent().getSheets().size() > 1) { - saveAndRunDeleteSheetCommand(sheet); - } - } - } - - protected void saveAndRunDeleteSheetCommand(ISheet sheet) { - List commands = new ArrayList(); - DeleteSheetCommand command = new DeleteSheetCommand(sheet); - command.setLabel(CommandMessages.Command_DeleteSheet); - commands.add(command); - - saveAndRun(new CompoundCommand(CommandMessages.Command_DeleteSheet, - commands)); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.core.ISheet; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.ui.actions.EditorAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteSheetCommand; + +public class DeleteSheetAction extends EditorAction { + + public DeleteSheetAction(IGraphicalEditor editor) { + super(MindMapActionFactory.DELETE_SHEET.getId(), editor); + } + + public void run() { + if (isDisposed()) + return; + + IGraphicalEditorPage page = getActivePage(); + if (page != null) { + ISheet sheet = (ISheet) page.getAdapter(ISheet.class); + + if (sheet == null) { + Object input = page.getInput(); + if (input instanceof ISheet) { + sheet = (ISheet) input; + } + } + + if (sheet != null && sheet.getParent().getSheets().size() > 1) { + saveAndRunDeleteSheetCommand(sheet); + } + } + } + + protected void saveAndRunDeleteSheetCommand(ISheet sheet) { + List commands = new ArrayList(); + DeleteSheetCommand command = new DeleteSheetCommand(sheet); + command.setLabel(CommandMessages.Command_DeleteSheet); + commands.add(command); + + saveAndRun(new CompoundCommand(CommandMessages.Command_DeleteSheet, + commands)); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DrillDownAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DrillDownAction.java index ef900e8a3..53e9ab75d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DrillDownAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DrillDownAction.java @@ -1,44 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class DrillDownAction extends RequestAction implements ISelectionAction { - - public DrillDownAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.DRILL_DOWN.getId(), page, - MindMapUI.REQ_DRILLDOWN); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection) - && !MindMapUtils.hasCentralTopic(selection, getViewer())); - } - - @Override - public void run() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("DrillDownCount"); //$NON-NLS-1$ - super.run(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class DrillDownAction extends RequestAction implements ISelectionAction { + + public DrillDownAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.DRILL_DOWN.getId(), page, + MindMapUI.REQ_DRILLDOWN); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection) + && !MindMapUtils.hasCentralTopic(selection, getViewer())); + } + + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.DRILL_DOWN_COUNT); + super.run(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DropDownInsertImageAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DropDownInsertImageAction.java index 207c774e0..a4c38f175 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DropDownInsertImageAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DropDownInsertImageAction.java @@ -1,106 +1,111 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuCreator; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; - -public class DropDownInsertImageAction extends Action implements - IWorkbenchAction, IPropertyChangeListener { - - private class InsertImageMenuCreator implements IMenuCreator { - - private Menu menu; - - public Menu getMenu(Control parent) { - if (menu != null) { - menu.dispose(); - } - - menu = new Menu(parent); - fillMenu(menu); - return menu; - } - - public Menu getMenu(Menu parent) { - if (menu != null) { - menu.dispose(); - } - menu = new Menu(parent); - fillMenu(menu); - return menu; - } - - private void fillMenu(Menu menu) { - for (IWorkbenchAction action : imageActionExtensions) { - ActionContributionItem item = new ActionContributionItem(action); - item.fill(menu, -1); - } - } - - public void dispose() { - if (menu != null) { - menu.dispose(); - menu = null; - } - } - - } - - private IAction sourceAction; - - private List imageActionExtensions; - - public DropDownInsertImageAction(IAction sourceAction, - List imageActionExtensions) { - super(MindMapMessages.InsertImage_text, AS_DROP_DOWN_MENU); - setId("org.xmind.ui.insertImageDropDown"); //$NON-NLS-1$ - this.sourceAction = sourceAction; - this.imageActionExtensions = imageActionExtensions; - setMenuCreator(new InsertImageMenuCreator()); - if (sourceAction != null) - sourceAction.addPropertyChangeListener(this); - setEnabled(sourceAction != null && sourceAction.isEnabled()); - } - - public void run() { - if (sourceAction != null) { - sourceAction.run(); - } - } - - public void dispose() { - if (sourceAction != null) { - sourceAction.removePropertyChangeListener(this); - sourceAction = null; - } - } - - public void propertyChange(PropertyChangeEvent event) { - if (ENABLED.equals(event.getProperty())) { - this.setEnabled(sourceAction != null && sourceAction.isEnabled()); - } - } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; + +public class DropDownInsertImageAction extends Action + implements IWorkbenchAction, IPropertyChangeListener { + + private class InsertImageMenuCreator implements IMenuCreator { + + private Menu menu; + + public Menu getMenu(Control parent) { + if (menu != null) { + menu.dispose(); + } + + menu = new Menu(parent); + fillMenu(menu); + return menu; + } + + public Menu getMenu(Menu parent) { + if (menu != null) { + menu.dispose(); + } + menu = new Menu(parent); + fillMenu(menu); + return menu; + } + + private void fillMenu(Menu menu) { + for (IWorkbenchAction action : imageActionExtensions) { + ActionContributionItem item = new ActionContributionItem( + action); + item.fill(menu, -1); + } + } + + public void dispose() { + if (menu != null) { + menu.dispose(); + menu = null; + } + } + + } + + private IAction sourceAction; + + private List imageActionExtensions; + + public DropDownInsertImageAction(IAction sourceAction, + List imageActionExtensions) { + super(MindMapMessages.InsertImage_text, AS_DROP_DOWN_MENU); + setId("org.xmind.ui.insertImageDropDown"); //$NON-NLS-1$ + this.sourceAction = sourceAction; + this.imageActionExtensions = imageActionExtensions; + setMenuCreator(new InsertImageMenuCreator()); + if (sourceAction != null) + sourceAction.addPropertyChangeListener(this); + setEnabled(sourceAction != null && sourceAction.isEnabled()); + } + + public void run() { + if (sourceAction != null) { + sourceAction.run(); + } + } + + public void dispose() { + if (sourceAction != null) { + sourceAction.removePropertyChangeListener(this); + sourceAction = null; + } + if (imageActionExtensions != null) { + imageActionExtensions.clear(); + imageActionExtensions = null; + } + } + + public void propertyChange(PropertyChangeEvent event) { + if (ENABLED.equals(event.getProperty())) { + this.setEnabled(sourceAction != null && sourceAction.isEnabled()); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DuplicateAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DuplicateAction.java index 515091740..5a113eeb6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DuplicateAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/DuplicateAction.java @@ -1,24 +1,24 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class DuplicateAction extends RequestAction implements ISelectionAction { - - public DuplicateAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.DUPLICATE.getId(), page, - MindMapUI.REQ_DUPLICATE_TOPIC); - setActionDefinitionId(MindMapActionFactory.DUPLICATE.getCommandId()); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection) - && !MindMapUtils.hasCentralTopic(selection, getViewer())); - } - +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class DuplicateAction extends RequestAction implements ISelectionAction { + + public DuplicateAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.DUPLICATE.getId(), page, + MindMapUI.REQ_DUPLICATE_TOPIC); + setActionDefinitionId(MindMapActionFactory.DUPLICATE.getCommandId()); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection) + && !MindMapUtils.hasCentralTopic(selection, getViewer())); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditCommentsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditCommentsAction.java index cabb594c4..4cf04a785 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditCommentsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditCommentsAction.java @@ -1,69 +1,69 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.comments.CommentsPopup; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class EditCommentsAction extends PageAction implements ISelectionAction { - - public EditCommentsAction(IGraphicalEditorPage page) { - super("org.xmind.ui.editComments", page); //$NON-NLS-1$ - setText(MindMapMessages.EditComments_text); - setImageDescriptor( - MindMapUI.getImages().get("menu_modify_comment.png", true)); //$NON-NLS-1$ - } - - public void run() { - IGraphicalEditor editor = getEditor(); - if (editor == null) - return; - - IWorkbenchWindow window = editor.getSite().getWorkbenchWindow(); - if (window == null) - return; - - IGraphicalViewer viewer = getViewer(); - if (viewer == null) - return; - - Control control = viewer.getControl(); - if (control == null || control.isDisposed()) - return; - - ITopicPart topicPart = getSelectionTopicPart(viewer); - if (topicPart == null) - return; - - CommentsPopup popup = new CommentsPopup(window, topicPart, true); - popup.open(); - } - - private ITopicPart getSelectionTopicPart(IGraphicalViewer viewer) { - ISelection selection = viewer.getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - Object o = ss.getFirstElement(); - IPart part = viewer.findPart(o); - if (part instanceof ITopicPart) - return (ITopicPart) part; - } - return null; - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection)); - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.comments.CommentsPopup; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class EditCommentsAction extends PageAction implements ISelectionAction { + + public EditCommentsAction(IGraphicalEditorPage page) { + super("org.xmind.ui.editComments", page); //$NON-NLS-1$ + setText(MindMapMessages.EditComments_text); + setImageDescriptor( + MindMapUI.getImages().get("menu_modify_comment.png", true)); //$NON-NLS-1$ + } + + public void run() { + IGraphicalEditor editor = getEditor(); + if (editor == null) + return; + + IWorkbenchWindow window = editor.getSite().getWorkbenchWindow(); + if (window == null) + return; + + IGraphicalViewer viewer = getViewer(); + if (viewer == null) + return; + + Control control = viewer.getControl(); + if (control == null || control.isDisposed()) + return; + + ITopicPart topicPart = getSelectionTopicPart(viewer); + if (topicPart == null) + return; + + CommentsPopup popup = new CommentsPopup(window, topicPart, true); + popup.open(); + } + + private ITopicPart getSelectionTopicPart(IGraphicalViewer viewer) { + ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object o = ss.getFirstElement(); + IPart part = viewer.findPart(o); + if (part instanceof ITopicPart) + return (ITopicPart) part; + } + return null; + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection)); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditLabelAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditLabelAction.java index 7d88d6f59..e6d6399fd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditLabelAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditLabelAction.java @@ -14,6 +14,7 @@ package org.xmind.ui.internal.actions; import org.eclipse.jface.viewers.ISelection; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ui.actions.ISelectionAction; import org.xmind.gef.ui.actions.RequestAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; @@ -36,7 +37,7 @@ public void setSelection(ISelection selection) { @Override public void run() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("InsertLabelCount"); //$NON-NLS-1$ + .increase(UserDataConstants.INSERT_LABEL_COUNT); super.run(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditNotesAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditNotesAction.java index 0aa5e592c..d91e61b31 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditNotesAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/EditNotesAction.java @@ -1,81 +1,82 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.notes.NotesPopup; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.util.MindMapUtils; - -public class EditNotesAction extends PageAction implements ISelectionAction { - - public EditNotesAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.EDIT_NOTES.getId(), page); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection)); - } - - public void run() { - IGraphicalEditor editor = getEditor(); - if (editor == null) - return; - - IWorkbenchWindow window = editor.getSite().getWorkbenchWindow(); - if (window == null) - return; - - IGraphicalViewer viewer = getViewer(); - if (viewer == null) - return; - - Control control = viewer.getControl(); - if (control == null || control.isDisposed()) - return; - - ITopicPart topicPart = getSelectionTopicPart(viewer); - if (topicPart == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("UseNotesCount"); //$NON-NLS-1$ - NotesPopup popup = new NotesPopup(window, topicPart, true, true); - popup.open(); - } - - private ITopicPart getSelectionTopicPart(IGraphicalViewer viewer) { - ISelection selection = viewer.getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - Object o = ss.getFirstElement(); - IPart part = viewer.findPart(o); - if (part instanceof ITopicPart) - return (ITopicPart) part; - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.notes.NotesPopup; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.util.MindMapUtils; + +public class EditNotesAction extends PageAction implements ISelectionAction { + + public EditNotesAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.EDIT_NOTES.getId(), page); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection)); + } + + public void run() { + IGraphicalEditor editor = getEditor(); + if (editor == null) + return; + + IWorkbenchWindow window = editor.getSite().getWorkbenchWindow(); + if (window == null) + return; + + IGraphicalViewer viewer = getViewer(); + if (viewer == null) + return; + + Control control = viewer.getControl(); + if (control == null || control.isDisposed()) + return; + + ITopicPart topicPart = getSelectionTopicPart(viewer); + if (topicPart == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.USE_NOTES_COUNT); + NotesPopup popup = new NotesPopup(window, topicPart, true, true); + popup.open(); + } + + private ITopicPart getSelectionTopicPart(IGraphicalViewer viewer) { + ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object o = ss.getFirstElement(); + IPart part = viewer.findPart(o); + if (part instanceof ITopicPart) + return (ITopicPart) part; + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ExtendAllAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ExtendAllAction.java index 003c92aed..f469be87a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ExtendAllAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ExtendAllAction.java @@ -1,71 +1,71 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.GEF; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class ExtendAllAction extends RequestAction implements ISelectionAction { - - public ExtendAllAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.EXTEND_ALL.getId(), page, - GEF.REQ_EXTEND_ALL); - } - - public void setSelection(ISelection selection) { - //1.select sheet (which root topic has attached children). - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - if (structuredSelection.size() == 1) { - Object obj = structuredSelection.getFirstElement(); - if (obj instanceof ISheet) { - ISheet sheet = (ISheet) obj; - setEnabled(sheet.getRootTopic().getChildren(ITopic.ATTACHED) - .size() != 0); - return; - } - } - } - - //2.select topics (at least one topic has attached children). - if (MindMapUtils.isAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC)) { - boolean enabled = false; - List topics = MindMapUtils.getAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC); - for (Object topic : topics) { - if (((ITopic) topic).getChildren(ITopic.ATTACHED).size() != 0) { - enabled = true; - break; - } - } - setEnabled(enabled); - return; - } - - setEnabled(false); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.GEF; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class ExtendAllAction extends RequestAction implements ISelectionAction { + + public ExtendAllAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.EXTEND_ALL.getId(), page, + GEF.REQ_EXTEND_ALL); + } + + public void setSelection(ISelection selection) { + //1.select sheet (which root topic has attached children). + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + if (structuredSelection.size() == 1) { + Object obj = structuredSelection.getFirstElement(); + if (obj instanceof ISheet) { + ISheet sheet = (ISheet) obj; + setEnabled(sheet.getRootTopic().getChildren(ITopic.ATTACHED) + .size() != 0); + return; + } + } + } + + //2.select topics (at least one topic has attached children). + if (MindMapUtils.isAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC)) { + boolean enabled = false; + List topics = MindMapUtils.getAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC); + for (Object topic : topics) { + if (((ITopic) topic).getChildren(ITopic.ATTACHED).size() != 0) { + enabled = true; + break; + } + } + setEnabled(enabled); + return; + } + + setEnabled(false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FindReplaceAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FindReplaceAction.java index cfcd7269c..4db1d0337 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FindReplaceAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FindReplaceAction.java @@ -1,54 +1,54 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.findreplace.FindReplaceDialog; - -public class FindReplaceAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - - public FindReplaceAction(IWorkbenchWindow window) { - super(); - this.window = window; - setId(ActionFactory.FIND.getId()); - setActionDefinitionId(ActionFactory.FIND.getCommandId()); - } - - public void run() { - if (window == null) - return; - - FindReplaceDialog dialog = FindReplaceDialog.getInstance(window); - if (dialog != null) { - ISelection selection = window.getSelectionService().getSelection(); - if (selection instanceof ITextSelection) { - dialog.setInitialFindText( - ((ITextSelection) selection).getText()); - } - dialog.open(); - } - } - - public void dispose() { - window = null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.findreplace.FindReplaceDialog; + +public class FindReplaceAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + + public FindReplaceAction(IWorkbenchWindow window) { + super(); + this.window = window; + setId(ActionFactory.FIND.getId()); + setActionDefinitionId(ActionFactory.FIND.getCommandId()); + } + + public void run() { + if (window == null) + return; + + FindReplaceDialog dialog = FindReplaceDialog.getInstance(window); + if (dialog != null) { + ISelection selection = window.getSelectionService().getSelection(); + if (selection instanceof ITextSelection) { + dialog.setInitialFindText( + ((ITextSelection) selection).getText()); + } + dialog.open(); + } + } + + public void dispose() { + window = null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitMapAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitMapAction.java index 6db3fe5e7..c9b97b0f5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitMapAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitMapAction.java @@ -1,15 +1,15 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.gef.GEF; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; - -@Deprecated -public class FitMapAction extends RequestAction { - - public FitMapAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.FIT_MAP.getId(), page, GEF.REQ_FITSIZE); - } - -} +package org.xmind.ui.internal.actions; + +import org.xmind.gef.GEF; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; + +@Deprecated +public class FitMapAction extends RequestAction { + + public FitMapAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.FIT_MAP.getId(), page, GEF.REQ_FITSIZE); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitSelectionAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitSelectionAction.java index 0af5f893a..cd07197fd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitSelectionAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/FitSelectionAction.java @@ -1,16 +1,16 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.gef.GEF; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; - -@Deprecated -public class FitSelectionAction extends RequestAction { - - public FitSelectionAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.FIT_SELECTION.getId(), page, - GEF.REQ_FITSELECTION); - } - -} +package org.xmind.ui.internal.actions; + +import org.xmind.gef.GEF; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; + +@Deprecated +public class FitSelectionAction extends RequestAction { + + public FitSelectionAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.FIT_SELECTION.getId(), page, + GEF.REQ_FITSELECTION); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/GroupMarkers.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/GroupMarkers.java index dc6a90591..1cda0e403 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/GroupMarkers.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/GroupMarkers.java @@ -1,193 +1,193 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.ITopic; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.commands.AddMarkerCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteMarkerCommand; -import org.xmind.ui.util.MarkerImageDescriptor; - -public class GroupMarkers extends ContributionItem { - -// private static final RGB BACKGROUND = new RGB(240, 240, 240); - - private class ReplaceMarkerAction extends Action { - - private ITopic topic; - - private String sourceMarkerId; - - private String targetMarkerId; - - public ReplaceMarkerAction(ITopic topic, String sourceMarkerId, - String targetMarkerId) { - this.topic = topic; - this.sourceMarkerId = sourceMarkerId; - this.targetMarkerId = targetMarkerId; - setText(topic.getOwnedSheet().getLegend() - .getMarkerDescription(targetMarkerId)); - setImageDescriptor( - MarkerImageDescriptor - .createFromMarker( - topic.getOwnedWorkbook().getMarkerSheet() - .findMarker(targetMarkerId), - 16, 16)); - boolean sameMarker = sourceMarkerId.equals(targetMarkerId); - setEnabled(!sameMarker); - setChecked(sameMarker); - } - - public void run() { - if (!isEnabled()) - return; - -// IWorkbookRef wr = MindMapUI.getWorkbookRefManager() -// .findRef(topic.getOwnedWorkbook()); -// if (wr != null) { - IGraphicalEditor page = (IGraphicalEditor) PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage() - .getActiveEditor(); - ICommandStack cs = page.getCommandStack(); - if (cs != null) { - Command cmd = createReplaceMarkerCommand(); - cs.execute(cmd); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources()); - } - } -// } - } - - private void select(List sources) { - if (selectionProvider != null) { - selectionProvider - .setSelection(new StructuredSelection(sources)); - } - } - - private Command createReplaceMarkerCommand() { - return new CompoundCommand(CommandMessages.Command_ReplaceMarker, - new DeleteMarkerCommand(topic, sourceMarkerId), - new AddMarkerCommand(topic, targetMarkerId)); - } - } - - private class DeleteMarkerAction extends Action { - - private ITopic topic; - - private String sourceMarkerId; - - public DeleteMarkerAction(ITopic topic, String sourceMarkerId) { - this.topic = topic; - this.sourceMarkerId = sourceMarkerId; - setText(CommandMessages.Command_Delete); - } - - @Override - public void run() { - IWorkbenchPage page = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage(); - if (page != null) { - IEditorPart editor = page.getActiveEditor(); - if (editor instanceof IGraphicalEditor) { - ICommandStack cs = ((IGraphicalEditor) editor) - .getCommandStack(); - - if (cs != null) { - Command cmd = createRemoveMarkerCommand(); - cs.execute(cmd); - } - } - } - } - - private Command createRemoveMarkerCommand() { - return new CompoundCommand(CommandMessages.Command_DeleteMarker, - new DeleteMarkerCommand(topic, sourceMarkerId)); - } - } - - private ISelectionProvider selectionProvider; - - private IMarkerRef sourceMarkerRef; - - public GroupMarkers() { - setId(ActionConstants.MARKER_GROUP_MENU); - } - - public void setSelectionProvider(ISelectionProvider selectionProvider) { - this.selectionProvider = selectionProvider; - } - - public boolean isVisible() { - return sourceMarkerRef != null; - } - - public void setSourceMarkerRef(IMarkerRef sourceMarkerRef) { - this.sourceMarkerRef = sourceMarkerRef; - } - - public boolean isDynamic() { - return true; - } - - public void fill(Menu menu, int index) { - if (sourceMarkerRef == null) - return; - - ITopic topic = sourceMarkerRef.getParent(); - String sourceMarkerId = sourceMarkerRef.getMarkerId(); - IMarker sourceMarker = topic.getOwnedWorkbook().getMarkerSheet() - .findMarker(sourceMarkerId); - if (sourceMarker != null) { - IMarkerGroup group = sourceMarker.getParent(); - if (group != null && !group.isHidden()) { - for (IMarker marker : group.getMarkers()) { - if (!marker.isHidden()) { - String targetMarkerId = marker.getId(); - new ActionContributionItem(new ReplaceMarkerAction( - topic, sourceMarkerId, targetMarkerId)) - .fill(menu, index++); - } - } - new Separator().fill(menu, index++); - new ActionContributionItem( - new DeleteMarkerAction(topic, sourceMarkerId)) - .fill(menu, index++); - } - } - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.ITopic; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.commands.AddMarkerCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.util.MarkerImageDescriptor; + +public class GroupMarkers extends ContributionItem { + +// private static final RGB BACKGROUND = new RGB(240, 240, 240); + + private class ReplaceMarkerAction extends Action { + + private ITopic topic; + + private String sourceMarkerId; + + private String targetMarkerId; + + public ReplaceMarkerAction(ITopic topic, String sourceMarkerId, + String targetMarkerId) { + this.topic = topic; + this.sourceMarkerId = sourceMarkerId; + this.targetMarkerId = targetMarkerId; + setText(topic.getOwnedSheet().getLegend() + .getMarkerDescription(targetMarkerId)); + setImageDescriptor( + MarkerImageDescriptor + .createFromMarker( + topic.getOwnedWorkbook().getMarkerSheet() + .findMarker(targetMarkerId), + 16, 16)); + boolean sameMarker = sourceMarkerId.equals(targetMarkerId); + setEnabled(!sameMarker); + setChecked(sameMarker); + } + + public void run() { + if (!isEnabled()) + return; + +// IWorkbookRef wr = MindMapUI.getWorkbookRefManager() +// .findRef(topic.getOwnedWorkbook()); +// if (wr != null) { + IGraphicalEditor page = (IGraphicalEditor) PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .getActiveEditor(); + ICommandStack cs = page.getCommandStack(); + if (cs != null) { + Command cmd = createReplaceMarkerCommand(); + cs.execute(cmd); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources()); + } + } +// } + } + + private void select(List sources) { + if (selectionProvider != null) { + selectionProvider + .setSelection(new StructuredSelection(sources)); + } + } + + private Command createReplaceMarkerCommand() { + return new CompoundCommand(CommandMessages.Command_ReplaceMarker, + new DeleteMarkerCommand(topic, sourceMarkerId), + new AddMarkerCommand(topic, targetMarkerId)); + } + } + + private class DeleteMarkerAction extends Action { + + private ITopic topic; + + private String sourceMarkerId; + + public DeleteMarkerAction(ITopic topic, String sourceMarkerId) { + this.topic = topic; + this.sourceMarkerId = sourceMarkerId; + setText(CommandMessages.Command_Delete); + } + + @Override + public void run() { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (page != null) { + IEditorPart editor = page.getActiveEditor(); + if (editor instanceof IGraphicalEditor) { + ICommandStack cs = ((IGraphicalEditor) editor) + .getCommandStack(); + + if (cs != null) { + Command cmd = createRemoveMarkerCommand(); + cs.execute(cmd); + } + } + } + } + + private Command createRemoveMarkerCommand() { + return new CompoundCommand(CommandMessages.Command_DeleteMarker, + new DeleteMarkerCommand(topic, sourceMarkerId)); + } + } + + private ISelectionProvider selectionProvider; + + private IMarkerRef sourceMarkerRef; + + public GroupMarkers() { + setId(ActionConstants.MARKER_GROUP_MENU); + } + + public void setSelectionProvider(ISelectionProvider selectionProvider) { + this.selectionProvider = selectionProvider; + } + + public boolean isVisible() { + return sourceMarkerRef != null; + } + + public void setSourceMarkerRef(IMarkerRef sourceMarkerRef) { + this.sourceMarkerRef = sourceMarkerRef; + } + + public boolean isDynamic() { + return true; + } + + public void fill(Menu menu, int index) { + if (sourceMarkerRef == null) + return; + + ITopic topic = sourceMarkerRef.getParent(); + String sourceMarkerId = sourceMarkerRef.getMarkerId(); + IMarker sourceMarker = topic.getOwnedWorkbook().getMarkerSheet() + .findMarker(sourceMarkerId); + if (sourceMarker != null) { + IMarkerGroup group = sourceMarker.getParent(); + if (group != null && !group.isHidden()) { + for (IMarker marker : group.getMarkers()) { + if (!marker.isHidden()) { + String targetMarkerId = marker.getId(); + new ActionContributionItem(new ReplaceMarkerAction( + topic, sourceMarkerId, targetMarkerId)) + .fill(menu, index++); + } + } + new Separator().fill(menu, index++); + new ActionContributionItem( + new DeleteMarkerAction(topic, sourceMarkerId)) + .fill(menu, index++); + } + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertAttachmentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertAttachmentAction.java index 9d7635ba6..398f6abdc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertAttachmentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertAttachmentAction.java @@ -14,6 +14,7 @@ package org.xmind.ui.internal.actions; import org.eclipse.jface.viewers.ISelection; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ui.actions.ISelectionAction; import org.xmind.gef.ui.actions.RequestAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; @@ -38,7 +39,7 @@ public void setSelection(ISelection selection) { @Override public void run() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("AddAttachmentCount"); //$NON-NLS-1$ + .increase(UserDataConstants.ADD_ATTACHMENT_COUNT); super.run(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertFloatingTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertFloatingTopicAction.java index 4942b23bb..7aa67397c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertFloatingTopicAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertFloatingTopicAction.java @@ -1,55 +1,55 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.xmind.core.Core; -import org.xmind.gef.Request; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.mindmap.MindMapUI; - -/** - * @author frankshaka - * - */ -public class InsertFloatingTopicAction extends PageAction { - - /** - * @param page - */ - public InsertFloatingTopicAction(String id, IGraphicalEditorPage page) { - super(id, page); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - public void run() { - if (isDisposed()) - return; - - if (MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC.getId().equals( - getId())) { - sendRequest(new Request(MindMapUI.REQ_CREATE_FLOAT).setParameter( - MindMapUI.PARAM_PROPERTY_PREFIX + Core.StructureClass, - "org.xmind.ui.map.floating")); //$NON-NLS-1$ - } else { - sendRequest(MindMapUI.REQ_CREATE_FLOAT); - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.xmind.core.Core; +import org.xmind.gef.Request; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.mindmap.MindMapUI; + +/** + * @author frankshaka + * + */ +public class InsertFloatingTopicAction extends PageAction { + + /** + * @param page + */ + public InsertFloatingTopicAction(String id, IGraphicalEditorPage page) { + super(id, page); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + public void run() { + if (isDisposed()) + return; + + if (MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC.getId().equals( + getId())) { + sendRequest(new Request(MindMapUI.REQ_CREATE_FLOAT).setParameter( + MindMapUI.PARAM_PROPERTY_PREFIX + Core.StructureClass, + "org.xmind.ui.map.floating")); //$NON-NLS-1$ + } else { + sendRequest(MindMapUI.REQ_CREATE_FLOAT); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageAction.java index 413c63ceb..2f18f3097 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageAction.java @@ -1,127 +1,127 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.awt.image.BufferedImage; -import java.io.File; - -import javax.imageio.ImageIO; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.xmind.core.ITopic; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.dialogs.DialogUtils; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class InsertImageAction extends PageAction implements ISelectionAction { - - private static final String PNG_FORMAT = "png"; //$NON-NLS-1$ - private static final String JPG_FORMAT = "jpg"; //$NON-NLS-1$ - private static final String JPEG_FORMAT = "jpeg"; //$NON-NLS-1$ - - public InsertImageAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.INSERT_IMAGE.getId(), page); - } - - public void run() { - if (isDisposed()) - return; - - EditDomain domain = getEditDomain(); - if (domain == null) - return; - - IGraphicalViewer viewer = getViewer(); - if (viewer == null) - return; - - Control control = viewer.getControl(); - if (control == null || control.isDisposed()) - return; - - ISelection selection = viewer.getSelection(); - if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) - return; - - Object o = ((IStructuredSelection) selection).getFirstElement(); - IPart part = viewer.findPart(o); - ITopic topic = (ITopic) part.getAdapter(ITopic.class); - if (topic == null) - return; - - IPart topicPart = viewer.findPart(topic); - if (topicPart == null) - return; - - FileDialog dialog = new FileDialog(control.getShell(), SWT.OPEN); - DialogUtils.makeDefaultImageSelectorDialog(dialog, true); - dialog.setText(DialogMessages.SelectImageDialog_title); - String path = dialog.open(); - if (path == null) - return; - - String lowerPath = path.toLowerCase(); - boolean converted = false; - if (lowerPath.endsWith(JPG_FORMAT) || lowerPath.endsWith(JPEG_FORMAT)) { - path = convertJpegToPng(path); - converted = true; - } - insertImage(path, topicPart, viewer, domain); - if (converted) { - FileUtils.delete(new File(path)); - } - } - - protected void insertImage(String path, IPart topicPart, IViewer viewer, - EditDomain domain) { - Request request = new Request(MindMapUI.REQ_ADD_IMAGE); - request.setViewer(viewer); - request.setPrimaryTarget(topicPart); - request.setParameter(GEF.PARAM_PATH, new String[] { path }); - domain.handleRequest(request); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection)); - } - - private final static String convertJpegToPng(String jpg) { - try { - BufferedImage source = ImageIO.read(new File(jpg)); - String png = jpg.substring(0, jpg.lastIndexOf('.') - 1) - + PNG_FORMAT; - ImageIO.write(source, PNG_FORMAT, new File(png)); - return png; - } catch (Exception e) { - return jpg; - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.awt.image.BufferedImage; +import java.io.File; + +import javax.imageio.ImageIO; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.core.ITopic; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class InsertImageAction extends PageAction implements ISelectionAction { + + private static final String PNG_FORMAT = "png"; //$NON-NLS-1$ + private static final String JPG_FORMAT = "jpg"; //$NON-NLS-1$ + private static final String JPEG_FORMAT = "jpeg"; //$NON-NLS-1$ + + public InsertImageAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.INSERT_IMAGE.getId(), page); + } + + public void run() { + if (isDisposed()) + return; + + EditDomain domain = getEditDomain(); + if (domain == null) + return; + + IGraphicalViewer viewer = getViewer(); + if (viewer == null) + return; + + Control control = viewer.getControl(); + if (control == null || control.isDisposed()) + return; + + ISelection selection = viewer.getSelection(); + if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) + return; + + Object o = ((IStructuredSelection) selection).getFirstElement(); + IPart part = viewer.findPart(o); + ITopic topic = (ITopic) part.getAdapter(ITopic.class); + if (topic == null) + return; + + IPart topicPart = viewer.findPart(topic); + if (topicPart == null) + return; + + FileDialog dialog = new FileDialog(control.getShell(), SWT.OPEN); + DialogUtils.makeDefaultImageSelectorDialog(dialog, true); + dialog.setText(DialogMessages.SelectImageDialog_title); + String path = dialog.open(); + if (path == null) + return; + + String lowerPath = path.toLowerCase(); + boolean converted = false; + if (lowerPath.endsWith(JPG_FORMAT) || lowerPath.endsWith(JPEG_FORMAT)) { + path = convertJpegToPng(path); + converted = true; + } + insertImage(path, topicPart, viewer, domain); + if (converted) { + FileUtils.delete(new File(path)); + } + } + + protected void insertImage(String path, IPart topicPart, IViewer viewer, + EditDomain domain) { + Request request = new Request(MindMapUI.REQ_ADD_IMAGE); + request.setViewer(viewer); + request.setPrimaryTarget(topicPart); + request.setParameter(GEF.PARAM_PATH, new String[] { path }); + domain.handleRequest(request); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection)); + } + + private final static String convertJpegToPng(String jpg) { + try { + BufferedImage source = ImageIO.read(new File(jpg)); + String png = jpg.substring(0, jpg.lastIndexOf('.') - 1) + + PNG_FORMAT; + ImageIO.write(source, PNG_FORMAT, new File(png)); + return png; + } catch (Exception e) { + return jpg; + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageMenu.java index 9f8f33bdf..44afebca8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertImageMenu.java @@ -1,91 +1,91 @@ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.ui.internal.IActionBuilder; -import org.xmind.ui.internal.ImageActionExtensionManager; - -public class InsertImageMenu extends ContributionItem implements - IWorkbenchContribution { - - private IWorkbenchWindow window; - protected boolean dirty = true; - - private IMenuListener menuListener = new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - manager.markDirty(); - dirty = true; - } - }; - - public boolean isDirty() { - return dirty; - } - - /** - * Overridden to always return true and force dynamic menu building. - */ - public boolean isDynamic() { - return true; - } - - public void fill(Menu menu, int index) { - if (window == null) - return; - - if (getParent() instanceof MenuManager) { - ((MenuManager) getParent()).addMenuListener(menuListener); - } - - if (!dirty) { - return; - } - - MenuManager manager = new MenuManager(); - fillMenu(manager); - IContributionItem items[] = manager.getItems(); - if (items.length > 0) { - for (int i = 0; i < items.length; i++) { - items[i].fill(menu, index++); - } - } - dirty = false; - } - - private void fillMenu(MenuManager manager) { - List imageActionBuilders = ImageActionExtensionManager - .getInstance().getActionBuilders(); - List imageActionExtensions = new ArrayList( - imageActionBuilders.size()); - - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - for (IActionBuilder builder : imageActionBuilders) { - IWorkbenchAction imageActionExtension = builder - .createAction(page); - imageActionExtensions.add(imageActionExtension); - } - for (IWorkbenchAction action : imageActionExtensions) { - manager.add(action); - } - } - } - - public void initialize(IServiceLocator serviceLocator) { - this.window = (IWorkbenchWindow) serviceLocator - .getService(IWorkbenchWindow.class); - } - -} +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.ui.internal.IActionBuilder; +import org.xmind.ui.internal.ImageActionExtensionManager; + +public class InsertImageMenu extends ContributionItem implements + IWorkbenchContribution { + + private IWorkbenchWindow window; + protected boolean dirty = true; + + private IMenuListener menuListener = new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + manager.markDirty(); + dirty = true; + } + }; + + public boolean isDirty() { + return dirty; + } + + /** + * Overridden to always return true and force dynamic menu building. + */ + public boolean isDynamic() { + return true; + } + + public void fill(Menu menu, int index) { + if (window == null) + return; + + if (getParent() instanceof MenuManager) { + ((MenuManager) getParent()).addMenuListener(menuListener); + } + + if (!dirty) { + return; + } + + MenuManager manager = new MenuManager(); + fillMenu(manager); + IContributionItem items[] = manager.getItems(); + if (items.length > 0) { + for (int i = 0; i < items.length; i++) { + items[i].fill(menu, index++); + } + } + dirty = false; + } + + private void fillMenu(MenuManager manager) { + List imageActionBuilders = ImageActionExtensionManager + .getInstance().getActionBuilders(); + List imageActionExtensions = new ArrayList( + imageActionBuilders.size()); + + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + for (IActionBuilder builder : imageActionBuilders) { + IWorkbenchAction imageActionExtension = builder + .createAction(page); + imageActionExtensions.add(imageActionExtension); + } + for (IWorkbenchAction action : imageActionExtensions) { + manager.add(action); + } + } + } + + public void initialize(IServiceLocator serviceLocator) { + this.window = (IWorkbenchWindow) serviceLocator + .getService(IWorkbenchWindow.class); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertParentTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertParentTopicAction.java index adc8990cd..042fa691f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertParentTopicAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertParentTopicAction.java @@ -1,144 +1,144 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.core.ITopic; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class InsertParentTopicAction extends RequestAction - implements ISelectionAction { - - public InsertParentTopicAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.INSERT_PARENT_TOPIC.getId(), page, - MindMapUI.REQ_CREATE_PARENT); - setText(MindMapMessages.InsertParentTopic_text); - setToolTipText(MindMapMessages.InsertParentTopic_toolTip); - setActionDefinitionId("org.xmind.ui.command.insert.parentTopic"); //$NON-NLS-1$ - setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.INSERT_PARENT, true)); - setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.INSERT_PARENT, false)); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection) - && !MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSummary(selection, getViewer())); - if (MindMapUtils.isSingleTopic(selection)) { - setEnabled(!MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSummary(selection, getViewer())); - } else if (MindMapUtils.isAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC)) { - List topics = getAllTopics(selection); - if (topics == null || topics.size() == 0 - || containsCentralTopic(topics) - || containsSummaryTopic(topics)) { - setEnabled(false); - } else { - setEnabled(isAllBrothers( - MindMapUtils.filterOutDescendents(topics, null))); - } - } - } - - private List getAllTopics(ISelection selection) { - List topics = MindMapUtils.getAllSuchElements(selection, - MindMapUI.CATEGORY_TOPIC); - if (topics == null) { - return null; - } else { - List list = new ArrayList(); - Collections.addAll(list, topics.toArray(new ITopic[0])); - return list; - } - } - - private boolean isAllBrothers(List topics) { - if (topics == null || topics.size() == 0) { - return false; - } - if (topics.size() == 1) { - return true; - } - for (int i = 0; i < topics.size() - 1; i++) { - if (!isBrothers(topics.get(i), topics.get(i + 1))) { - return false; - } - } - - return true; - } - - private boolean isBrothers(ITopic t1, ITopic t2) { - if (t1 == null || t2 == null) { - return false; - } - - return t1.getParent() == t2.getParent(); - } - - public boolean containsCentralTopic(List topics) { - if (topics == null || topics.size() == 0) { - return false; - } - - for (ITopic t : topics) { - if (isCentralTopic(t)) { - return true; - } - } - - return false; - } - - public boolean isCentralTopic(ITopic topic) { - if (topic == null) { - return false; - } - - return topic.getOwnedSheet().getRootTopic() == topic; - } - - private boolean containsSummaryTopic(List topics) { - if (topics == null || topics.isEmpty()) - return false; - - for (ITopic t : topics) { - if (isSummary(t)) - return true; - } - - return false; - } - - private boolean isSummary(ITopic topic) { - if (topic == null) - return false; - - return ITopic.SUMMARY.equals(topic.getType()); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.core.ITopic; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class InsertParentTopicAction extends RequestAction + implements ISelectionAction { + + public InsertParentTopicAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.INSERT_PARENT_TOPIC.getId(), page, + MindMapUI.REQ_CREATE_PARENT); + setText(MindMapMessages.InsertParentTopic_text); + setToolTipText(MindMapMessages.InsertParentTopic_toolTip); + setActionDefinitionId("org.xmind.ui.command.insert.parentTopic"); //$NON-NLS-1$ + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.INSERT_PARENT, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.INSERT_PARENT, false)); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection) + && !MindMapUtils.hasCentralTopic(selection, getViewer()) + && !MindMapUtils.hasSummary(selection, getViewer())); + if (MindMapUtils.isSingleTopic(selection)) { + setEnabled(!MindMapUtils.hasCentralTopic(selection, getViewer()) + && !MindMapUtils.hasSummary(selection, getViewer())); + } else if (MindMapUtils.isAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC)) { + List topics = getAllTopics(selection); + if (topics == null || topics.size() == 0 + || containsCentralTopic(topics) + || containsSummaryTopic(topics)) { + setEnabled(false); + } else { + setEnabled(isAllBrothers( + MindMapUtils.filterOutDescendents(topics, null))); + } + } + } + + private List getAllTopics(ISelection selection) { + List topics = MindMapUtils.getAllSuchElements(selection, + MindMapUI.CATEGORY_TOPIC); + if (topics == null) { + return null; + } else { + List list = new ArrayList(); + Collections.addAll(list, topics.toArray(new ITopic[0])); + return list; + } + } + + private boolean isAllBrothers(List topics) { + if (topics == null || topics.size() == 0) { + return false; + } + if (topics.size() == 1) { + return true; + } + for (int i = 0; i < topics.size() - 1; i++) { + if (!isBrothers(topics.get(i), topics.get(i + 1))) { + return false; + } + } + + return true; + } + + private boolean isBrothers(ITopic t1, ITopic t2) { + if (t1 == null || t2 == null) { + return false; + } + + return t1.getParent() == t2.getParent(); + } + + public boolean containsCentralTopic(List topics) { + if (topics == null || topics.size() == 0) { + return false; + } + + for (ITopic t : topics) { + if (isCentralTopic(t)) { + return true; + } + } + + return false; + } + + public boolean isCentralTopic(ITopic topic) { + if (topic == null) { + return false; + } + + return topic.getOwnedSheet().getRootTopic() == topic; + } + + private boolean containsSummaryTopic(List topics) { + if (topics == null || topics.isEmpty()) + return false; + + for (ITopic t : topics) { + if (isSummary(t)) + return true; + } + + return false; + } + + private boolean isSummary(ITopic topic) { + if (topic == null) + return false; + + return ITopic.SUMMARY.equals(topic.getType()); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertSubtopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertSubtopicAction.java index 41f9bd0e1..230a16155 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertSubtopicAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertSubtopicAction.java @@ -1,44 +1,44 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class InsertSubtopicAction extends RequestAction implements - ISelectionAction { - - public InsertSubtopicAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.INSERT_SUBTOPIC.getId(), page, - MindMapUI.REQ_CREATE_CHILD); - setText(MindMapMessages.InsertSubtopic_text); - setToolTipText(MindMapMessages.InsertSubtopic_toolTip); - setImageDescriptor(MindMapUI.getImages().get(IMindMapImages.INSERT_SUB, - true)); - setDisabledImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.INSERT_SUB, false)); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection)); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class InsertSubtopicAction extends RequestAction implements + ISelectionAction { + + public InsertSubtopicAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.INSERT_SUBTOPIC.getId(), page, + MindMapUI.REQ_CREATE_CHILD); + setText(MindMapMessages.InsertSubtopic_text); + setToolTipText(MindMapMessages.InsertSubtopic_toolTip); + setImageDescriptor(MindMapUI.getImages().get(IMindMapImages.INSERT_SUB, + true)); + setDisabledImageDescriptor(MindMapUI.getImages().get( + IMindMapImages.INSERT_SUB, false)); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection)); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicAction.java index 5970b5f1c..093cce602 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicAction.java @@ -1,58 +1,58 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.GEF; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class InsertTopicAction extends RequestAction implements - ISelectionAction { - - public InsertTopicAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.INSERT_TOPIC.getId(), page, GEF.REQ_CREATE); - setText(MindMapMessages.InsertTopic_text); - setToolTipText(MindMapMessages.InsertTopic_toolTip); - setImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.INSERT_AFTER, true)); - setDisabledImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.INSERT_AFTER, false)); - } - - public void setSelection(ISelection selection) { - setEnabled(isCreatable(selection)); - } - - private boolean isCreatable(ISelection selection) { - return MindMapUtils.isSingleTopic(selection) - || MindMapUtils.matchesSelection(selection, - MindMapUI.CATEGORY_RELATIONSHIP, true); -// return true; -// if (MindMapUtils.matchesSelection(selection, -// MindMapUI.CATEGORY_SUMMARY, true)) { -// ISummary s = (ISummary) ((IStructuredSelection) selection) -// .getFirstElement(); -// return s.getTopicId() == null; -// } -// return false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.GEF; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class InsertTopicAction extends RequestAction implements + ISelectionAction { + + public InsertTopicAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.INSERT_TOPIC.getId(), page, GEF.REQ_CREATE); + setText(MindMapMessages.InsertTopic_text); + setToolTipText(MindMapMessages.InsertTopic_toolTip); + setImageDescriptor(MindMapUI.getImages().get( + IMindMapImages.INSERT_AFTER, true)); + setDisabledImageDescriptor(MindMapUI.getImages().get( + IMindMapImages.INSERT_AFTER, false)); + } + + public void setSelection(ISelection selection) { + setEnabled(isCreatable(selection)); + } + + private boolean isCreatable(ISelection selection) { + return MindMapUtils.isSingleTopic(selection) + || MindMapUtils.matchesSelection(selection, + MindMapUI.CATEGORY_RELATIONSHIP, true); +// return true; +// if (MindMapUtils.matchesSelection(selection, +// MindMapUI.CATEGORY_SUMMARY, true)) { +// ISummary s = (ISummary) ((IStructuredSelection) selection) +// .getFirstElement(); +// return s.getTopicId() == null; +// } +// return false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicBeforeAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicBeforeAction.java index 401203e91..24ba2a8f5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicBeforeAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicBeforeAction.java @@ -1,46 +1,46 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class InsertTopicBeforeAction extends RequestAction - implements ISelectionAction { - - public InsertTopicBeforeAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.INSERT_TOPIC_BEFORE.getId(), page, - MindMapUI.REQ_CREATE_BEFORE); - setText(MindMapMessages.InsertTopicBefore_text); - setToolTipText(MindMapMessages.InsertTopicBefore_toolTip); - setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.INSERT_BEFORE, true)); - setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.INSERT_BEFORE, false)); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection) - && !MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSummary(selection, getViewer())); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class InsertTopicBeforeAction extends RequestAction + implements ISelectionAction { + + public InsertTopicBeforeAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.INSERT_TOPIC_BEFORE.getId(), page, + MindMapUI.REQ_CREATE_BEFORE); + setText(MindMapMessages.InsertTopicBefore_text); + setToolTipText(MindMapMessages.InsertTopicBefore_toolTip); + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.INSERT_BEFORE, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.INSERT_BEFORE, false)); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection) + && !MindMapUtils.hasCentralTopic(selection, getViewer()) + && !MindMapUtils.hasSummary(selection, getViewer())); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/MarkerParameterValues.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/MarkerParameterValues.java index c10311de6..88002e94f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/MarkerParameterValues.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/MarkerParameterValues.java @@ -1,47 +1,47 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.commands.IParameterValues; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.MindMapUI; - -public final class MarkerParameterValues implements IParameterValues { - - public Map getParameterValues() { - Map map = new HashMap(); - IMarkerSheet ms = MindMapUI.getResourceManager().getSystemMarkerSheet(); - for (IMarkerGroup mg : ms.getMarkerGroups()) { - for (IMarker m : mg.getMarkers()) { - map.put(makeName(mg, m), m.getId()); - } - } - return map; - } - - private String makeName(IMarkerGroup group, IMarker marker) { - String markerName = marker.getName(); - String groupName = group.getName(); - return NLS.bind(MindMapMessages.MarkerParameterNamePattern, groupName, - markerName); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.commands.IParameterValues; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.MindMapUI; + +public final class MarkerParameterValues implements IParameterValues { + + public Map getParameterValues() { + Map map = new HashMap(); + IMarkerSheet ms = MindMapUI.getResourceManager().getSystemMarkerSheet(); + for (IMarkerGroup mg : ms.getMarkerGroups()) { + for (IMarker m : mg.getMarkers()) { + map.put(makeName(mg, m), m.getId()); + } + } + return map; + } + + private String makeName(IMarkerGroup group, IMarker marker) { + String markerName = marker.getName(); + String groupName = group.getName(); + return NLS.bind(MindMapMessages.MarkerParameterNamePattern, groupName, + markerName); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ModifyHyperlinkAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ModifyHyperlinkAction.java index ec98983aa..60d837d3b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ModifyHyperlinkAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ModifyHyperlinkAction.java @@ -1,66 +1,66 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.xmind.core.Core; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.dialogs.HyperlinkDialog; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class ModifyHyperlinkAction extends PageAction implements - ISelectionAction { - - public ModifyHyperlinkAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.MODIFY_HYPERLINK.getId(), page); - } - - @Override - public void run() { - if (isDisposed()) - return; - - Shell parentShell = getEditor().getSite().getShell(); - ISelection selection = getPage().getSelectionProvider().getSelection(); - if (selection instanceof IStructuredSelection) { - HyperlinkDialog dialog = new HyperlinkDialog(parentShell, - getEditor(), (IStructuredSelection) selection); - int retCode = dialog.open(); - if (retCode == HyperlinkDialog.OK) { - modifyHyperlink(dialog.getValue()); - } else if (retCode == HyperlinkDialog.REMOVE) { - modifyHyperlink(null); - } - } - } - - private void modifyHyperlink(String newHyperlink) { - sendRequest(new Request(MindMapUI.REQ_MODIFY_HYPERLINK).setParameter( - GEF.PARAM_TEXT, newHyperlink)); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isPropertyModifiable(selection, - Core.TopicHyperlink, getViewer())); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.xmind.core.Core; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.dialogs.HyperlinkDialog; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class ModifyHyperlinkAction extends PageAction implements + ISelectionAction { + + public ModifyHyperlinkAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.MODIFY_HYPERLINK.getId(), page); + } + + @Override + public void run() { + if (isDisposed()) + return; + + Shell parentShell = getEditor().getSite().getShell(); + ISelection selection = getPage().getSelectionProvider().getSelection(); + if (selection instanceof IStructuredSelection) { + HyperlinkDialog dialog = new HyperlinkDialog(parentShell, + getEditor(), (IStructuredSelection) selection); + int retCode = dialog.open(); + if (retCode == HyperlinkDialog.OK) { + modifyHyperlink(dialog.getValue()); + } else if (retCode == HyperlinkDialog.REMOVE) { + modifyHyperlink(null); + } + } + } + + private void modifyHyperlink(String newHyperlink) { + sendRequest(new Request(MindMapUI.REQ_MODIFY_HYPERLINK).setParameter( + GEF.PARAM_TEXT, newHyperlink)); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isPropertyModifiable(selection, + Core.TopicHyperlink, getViewer())); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromMoreTemplateAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromMoreTemplateAction.java index 8b7812e6d..16068d5e7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromMoreTemplateAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromMoreTemplateAction.java @@ -1,55 +1,55 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.mindmap.MindMapUI; - -public class NewFromMoreTemplateAction extends BaseNewFromTemplateAction { - - public NewFromMoreTemplateAction(IWorkbenchWindow window) { - super(window); - setId("org.xmind.ui.newFromTemplate"); //$NON-NLS-1$ - setText(MindMapMessages.NewFromTemplate_text); - setToolTipText(MindMapMessages.NewFromTemplate_toolTip); - setActionDefinitionId("org.xmind.ui.command.newFromTemplate"); //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream - * (org.eclipse.swt.widgets.Shell) - */ - protected InputStream getTemplateStream(Shell shell) throws Exception { - FileDialog dialog = new FileDialog(shell, SWT.OPEN); - dialog.setFilterExtensions( - new String[] { "*" + MindMapUI.FILE_EXT_TEMPLATE }); //$NON-NLS-1$ - dialog.setFilterNames( - new String[] { DialogMessages.TemplateFilterName }); - String path = dialog.open(); - if (path == null) - return null; - return new FileInputStream(path); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.io.FileInputStream; +import java.io.InputStream; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.mindmap.MindMapUI; + +public class NewFromMoreTemplateAction extends BaseNewFromTemplateAction { + + public NewFromMoreTemplateAction(IWorkbenchWindow window) { + super(window); + setId("org.xmind.ui.newFromTemplate"); //$NON-NLS-1$ + setText(MindMapMessages.NewFromTemplate_text); + setToolTipText(MindMapMessages.NewFromTemplate_toolTip); + setActionDefinitionId("org.xmind.ui.command.newFromTemplate"); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream + * (org.eclipse.swt.widgets.Shell) + */ + protected InputStream getTemplateStream(Shell shell) throws Exception { + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + dialog.setFilterExtensions( + new String[] { "*" + MindMapUI.FILE_EXT_TEMPLATE }); //$NON-NLS-1$ + dialog.setFilterNames( + new String[] { DialogMessages.TemplateFilterName }); + String path = dialog.open(); + if (path == null) + return null; + return new FileInputStream(path); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateFileAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateFileAction.java index cd6216a79..498c54e18 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateFileAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateFileAction.java @@ -1,47 +1,47 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.core.util.FileUtils; - -public class NewFromTemplateFileAction extends BaseNewFromTemplateAction { - - private String templateFile; - - public NewFromTemplateFileAction(IWorkbenchWindow window, - String templateFile) { - super(window); - if (templateFile == null) - throw new IllegalArgumentException(); - this.templateFile = templateFile; - setText(FileUtils.getNoExtensionFileName(templateFile)); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream - * (org.eclipse.swt.widgets.Shell) - */ - protected InputStream getTemplateStream(Shell shell) throws Exception { - return new FileInputStream(templateFile); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.io.FileInputStream; +import java.io.InputStream; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.core.util.FileUtils; + +public class NewFromTemplateFileAction extends BaseNewFromTemplateAction { + + private String templateFile; + + public NewFromTemplateFileAction(IWorkbenchWindow window, + String templateFile) { + super(window); + if (templateFile == null) + throw new IllegalArgumentException(); + this.templateFile = templateFile; + setText(FileUtils.getNoExtensionFileName(templateFile)); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream + * (org.eclipse.swt.widgets.Shell) + */ + protected InputStream getTemplateStream(Shell shell) throws Exception { + return new FileInputStream(templateFile); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateURLAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateURLAction.java index 6098cc547..812f06a84 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateURLAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewFromTemplateURLAction.java @@ -1,43 +1,43 @@ -/** - * - */ -package org.xmind.ui.internal.actions; - -import java.io.InputStream; -import java.net.URL; - -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchWindow; - -/** - * @author frankshaka - */ -public class NewFromTemplateURLAction extends BaseNewFromTemplateAction { - - private URL url; - - /** - * @param window - * @param resourcePath - * @param name - */ - public NewFromTemplateURLAction(IWorkbenchWindow window, URL url, - String name) { - super(window); - if (url == null) - throw new IllegalArgumentException(); - this.url = url; - setText(name); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream - * (org.eclipse.swt.widgets.Shell) - */ - protected InputStream getTemplateStream(Shell shell) throws Exception { - return url.openStream(); - } - -} +/** + * + */ +package org.xmind.ui.internal.actions; + +import java.io.InputStream; +import java.net.URL; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; + +/** + * @author frankshaka + */ +public class NewFromTemplateURLAction extends BaseNewFromTemplateAction { + + private URL url; + + /** + * @param window + * @param resourcePath + * @param name + */ + public NewFromTemplateURLAction(IWorkbenchWindow window, URL url, + String name) { + super(window); + if (url == null) + throw new IllegalArgumentException(); + this.url = url; + setText(name); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream + * (org.eclipse.swt.widgets.Shell) + */ + protected InputStream getTemplateStream(Shell shell) throws Exception { + return url.openStream(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookAction.java index 96f208b9b..b034ea71d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookAction.java @@ -1,62 +1,62 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.editor.MME; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -@Deprecated -public class NewWorkbookAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - - public NewWorkbookAction(IWorkbenchWindow window) { - super(MindMapMessages.NewWorkbook_text); - if (window == null) - throw new IllegalArgumentException(); - - this.window = window; - setId("org.xmind.ui.newWorkbook"); //$NON-NLS-1$ - setImageDescriptor(MindMapUI.getImages().get(IMindMapImages.NEW, true)); - setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NEW, false)); - setToolTipText(MindMapMessages.NewWorkbook_toolTip); - setActionDefinitionId("org.xmind.ui.command.newWorkbook"); //$NON-NLS-1$ - } - - public void run() { - if (window == null) - return; - - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - window.getActivePage().openEditor( - MME.createNonExistingEditorInput(), - MindMapUI.MINDMAP_EDITOR_ID); - } - }); - } - - public void dispose() { - window = null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +@Deprecated +public class NewWorkbookAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + + public NewWorkbookAction(IWorkbenchWindow window) { + super(MindMapMessages.NewWorkbook_text); + if (window == null) + throw new IllegalArgumentException(); + + this.window = window; + setId("org.xmind.ui.newWorkbook"); //$NON-NLS-1$ + setImageDescriptor(MindMapUI.getImages().get(IMindMapImages.NEW, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.NEW, false)); + setToolTipText(MindMapMessages.NewWorkbook_toolTip); + setActionDefinitionId("org.xmind.ui.command.newWorkbook"); //$NON-NLS-1$ + } + + public void run() { + if (window == null) + return; + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + window.getActivePage().openEditor( + MME.createNonExistingEditorInput(), + MindMapUI.MINDMAP_EDITOR_ID); + } + }); + } + + public void dispose() { + window = null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookWizardAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookWizardAction.java index 2e2417868..dfa54bf84 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookWizardAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/NewWorkbookWizardAction.java @@ -1,39 +1,39 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; - -public class NewWorkbookWizardAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - - public NewWorkbookWizardAction(IWorkbenchWindow window) { - super(); - this.window = window; - setId("org.xmind.ui.newWorkbookWizard"); //$NON-NLS-1$ - setActionDefinitionId("org.xmind.ui.command.newWorkbookWizard"); //$NON-NLS-1$ - ISharedImages images = window.getWorkbench().getSharedImages(); - setImageDescriptor(images - .getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD)); - setDisabledImageDescriptor(images - .getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD_DISABLED)); - setText(MindMapMessages.NewWorkbookDialog_text); - setToolTipText(MindMapMessages.NewWorkbookDialog_toolTip); - } - - public void run() { - IWorkbenchWindow window = this.window; - if (window == null) - return; - -// NewWorkbookEditor.showIn(window); -// NewWorkbookWizardDialog.openWizard(window, false); - } - - public void dispose() { - this.window = null; - } -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; + +public class NewWorkbookWizardAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + + public NewWorkbookWizardAction(IWorkbenchWindow window) { + super(); + this.window = window; + setId("org.xmind.ui.newWorkbookWizard"); //$NON-NLS-1$ + setActionDefinitionId("org.xmind.ui.command.newWorkbookWizard"); //$NON-NLS-1$ + ISharedImages images = window.getWorkbench().getSharedImages(); + setImageDescriptor(images + .getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD)); + setDisabledImageDescriptor(images + .getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD_DISABLED)); + setText(MindMapMessages.NewWorkbookDialog_text); + setToolTipText(MindMapMessages.NewWorkbookDialog_toolTip); + } + + public void run() { + IWorkbenchWindow window = this.window; + if (window == null) + return; + +// NewWorkbookEditor.showIn(window); +// NewWorkbookWizardDialog.openWizard(window, false); + } + + public void dispose() { + this.window = null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHomeMapAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHomeMapAction.java index d21ccf0be..709a35fa3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHomeMapAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHomeMapAction.java @@ -1,97 +1,97 @@ -package org.xmind.ui.internal.actions; - -import java.io.File; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.util.PrefUtils; - -@Deprecated -public class OpenHomeMapAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - - public OpenHomeMapAction(IWorkbenchWindow window) { - super(MindMapMessages.OpenHomeMap_text); - if (window == null) - throw new IllegalArgumentException(); - this.window = window; - setId("org.xmind.ui.openHomeMap"); //$NON-NLS-1$ - setToolTipText(MindMapMessages.OpenHomeMap_toolTip); - setActionDefinitionId("org.xmind.ui.command.openHomeMap"); //$NON-NLS-1$ - } - - @Override - public void run() { - if (window == null) - return; - - Shell shell = window.getShell(); - final IWorkbenchPage page = window.getActivePage(); - openHomeMap(shell, page); - } - - public void dispose() { - window = null; - } - - public static boolean openHomeMap(final Shell shell, - final IWorkbenchPage page) { - final String path = MindMapUIPlugin.getDefault().getPreferenceStore() - .getString(PrefConstants.HOME_MAP_LOCATION); - if (path == null || "".equals(path)) {//$NON-NLS-1$ - PrefUtils.openPrefDialog(shell, PrefUtils.GENERAL_PREF_PAGE_ID); - return false; - } - if (!new File(path).exists()) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - String dialogMessage = MindMapMessages.OpenHomeMapAction_HomeMapMissingMessage; - String[] dialogButtonLabels = { IDialogConstants.OK_LABEL, - MindMapMessages.OpenHomeMapAction_LaterOperationButton }; - int index = new MessageDialog(shell, - org.xmind.ui.dialogs.IDialogConstants.COMMON_TITLE, - null, dialogMessage, MessageDialog.WARNING, - dialogButtonLabels, 0).open(); - if (index == 0) { - PrefUtils.openPrefDialog(shell, - PrefUtils.GENERAL_PREF_PAGE_ID); - } - } - }); - return false; - } - - final boolean opened[] = new boolean[1]; - opened[0] = false; - String errMessage = NLS - .bind(DialogMessages.FailedToLoadWorkbook_message, path); - SafeRunner.run(new SafeRunnable(errMessage) { - public void run() throws Exception { - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInputForFile(new File(path)); - IEditorPart editor = page.openEditor(input, - MindMapUI.MINDMAP_EDITOR_ID); - opened[0] = editor != null; - } - }); - return opened[0]; - } - -} +package org.xmind.ui.internal.actions; + +import java.io.File; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.util.PrefUtils; + +@Deprecated +public class OpenHomeMapAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + + public OpenHomeMapAction(IWorkbenchWindow window) { + super(MindMapMessages.OpenHomeMap_text); + if (window == null) + throw new IllegalArgumentException(); + this.window = window; + setId("org.xmind.ui.openHomeMap"); //$NON-NLS-1$ + setToolTipText(MindMapMessages.OpenHomeMap_toolTip); + setActionDefinitionId("org.xmind.ui.command.openHomeMap"); //$NON-NLS-1$ + } + + @Override + public void run() { + if (window == null) + return; + + Shell shell = window.getShell(); + final IWorkbenchPage page = window.getActivePage(); + openHomeMap(shell, page); + } + + public void dispose() { + window = null; + } + + public static boolean openHomeMap(final Shell shell, + final IWorkbenchPage page) { + final String path = MindMapUIPlugin.getDefault().getPreferenceStore() + .getString(PrefConstants.HOME_MAP_LOCATION); + if (path == null || "".equals(path)) {//$NON-NLS-1$ + PrefUtils.openPrefDialog(shell, PrefUtils.GENERAL_PREF_PAGE_ID); + return false; + } + if (!new File(path).exists()) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + String dialogMessage = MindMapMessages.OpenHomeMapAction_HomeMapMissingMessage; + String[] dialogButtonLabels = { IDialogConstants.OK_LABEL, + MindMapMessages.OpenHomeMapAction_LaterOperationButton }; + int index = new MessageDialog(shell, + org.xmind.ui.dialogs.IDialogConstants.COMMON_TITLE, + null, dialogMessage, MessageDialog.WARNING, + dialogButtonLabels, 0).open(); + if (index == 0) { + PrefUtils.openPrefDialog(shell, + PrefUtils.GENERAL_PREF_PAGE_ID); + } + } + }); + return false; + } + + final boolean opened[] = new boolean[1]; + opened[0] = false; + String errMessage = NLS + .bind(DialogMessages.FailedToLoadWorkbook_message, path); + SafeRunner.run(new SafeRunnable(errMessage) { + public void run() throws Exception { + IEditorInput input = MindMapUI.getEditorInputFactory() + .createEditorInputForFile(new File(path)); + IEditorPart editor = page.openEditor(input, + MindMapUI.MINDMAP_EDITOR_ID); + opened[0] = editor != null; + } + }); + return opened[0]; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHyperlinkAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHyperlinkAction.java index 7bfe18d26..73897cf86 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHyperlinkAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenHyperlinkAction.java @@ -1,35 +1,35 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapMessages; - -public class OpenHyperlinkAction extends SelectionRetargetAction { - - public OpenHyperlinkAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.OPEN_HYPERLINK.getId(), page); - setText(MindMapMessages.OpenHyperlink_text); - setToolTipText(MindMapMessages.OpenHyperlink_toolTip); - } - - protected String getHandlerId() { - return MindMapActionFactory.OPEN_HYPERLINK.getId(); - } - - protected void runWithNoHandler() { - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapMessages; + +public class OpenHyperlinkAction extends SelectionRetargetAction { + + public OpenHyperlinkAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.OPEN_HYPERLINK.getId(), page); + setText(MindMapMessages.OpenHyperlink_text); + setToolTipText(MindMapMessages.OpenHyperlink_toolTip); + } + + protected String getHandlerId() { + return MindMapActionFactory.OPEN_HYPERLINK.getId(); + } + + protected void runWithNoHandler() { + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenWorkbookAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenWorkbookAction.java index f39a72294..f78274551 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenWorkbookAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/OpenWorkbookAction.java @@ -1,54 +1,54 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.dialogs.OpenWorkbookDialog; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -@Deprecated -public class OpenWorkbookAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - - public OpenWorkbookAction(IWorkbenchWindow window) { - super(MindMapMessages.OpenWorkbook_text); - if (window == null) - throw new IllegalArgumentException(); - this.window = window; - setId("org.xmind.ui.open"); //$NON-NLS-1$ - setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.OPEN, true)); - setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.OPEN, false)); - setToolTipText(MindMapMessages.OpenWorkbook_toolTip); - setActionDefinitionId("org.xmind.ui.command.openWorkbook"); //$NON-NLS-1$ - } - - public void run() { - if (window == null) - return; - - new OpenWorkbookDialog(window).open(); - } - - public void dispose() { - window = null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.dialogs.OpenWorkbookDialog; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +@Deprecated +public class OpenWorkbookAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + + public OpenWorkbookAction(IWorkbenchWindow window) { + super(MindMapMessages.OpenWorkbook_text); + if (window == null) + throw new IllegalArgumentException(); + this.window = window; + setId("org.xmind.ui.open"); //$NON-NLS-1$ + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.OPEN, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.OPEN, false)); + setToolTipText(MindMapMessages.OpenWorkbook_toolTip); + setActionDefinitionId("org.xmind.ui.command.openWorkbook"); //$NON-NLS-1$ + } + + public void run() { + if (window == null) + return; + + new OpenWorkbookDialog(window).open(); + } + + public void dispose() { + window = null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/PasteSheetAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/PasteSheetAction.java index a80756c3b..8864eb3a0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/PasteSheetAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/PasteSheetAction.java @@ -1,41 +1,41 @@ -package org.xmind.ui.internal.actions; - -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.gef.ui.actions.EditorAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.PasteSheetCommand; - -public class PasteSheetAction extends EditorAction { - - public PasteSheetAction(IGraphicalEditor editor) { - super(MindMapActionFactory.PASTE_SHEET.getId(), editor); - } - - @Override - public void run() { - if (isDisposed()) - return; - - IGraphicalEditorPage page = getActivePage(); - if (page != null) { - IWorkbook workbook = ((ISheet) page.getAdapter(ISheet.class)) - .getOwnedWorkbook(); - ISheet copiedSheet = CopiedSheetStorageSupport.getInstance() - .getCopiedSheet(workbook); - if (workbook != null) { - saveAndRunPasteSheetCommand(workbook, copiedSheet); - } - } - } - - protected void saveAndRunPasteSheetCommand(IWorkbook workbook, - ISheet copiedSheet) { - PasteSheetCommand command = new PasteSheetCommand(workbook, copiedSheet); - command.setLabel(CommandMessages.Command_PasteSheet); - saveAndRun(command); - } -} +package org.xmind.ui.internal.actions; + +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.gef.ui.actions.EditorAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.PasteSheetCommand; + +public class PasteSheetAction extends EditorAction { + + public PasteSheetAction(IGraphicalEditor editor) { + super(MindMapActionFactory.PASTE_SHEET.getId(), editor); + } + + @Override + public void run() { + if (isDisposed()) + return; + + IGraphicalEditorPage page = getActivePage(); + if (page != null) { + IWorkbook workbook = ((ISheet) page.getAdapter(ISheet.class)) + .getOwnedWorkbook(); + ISheet copiedSheet = CopiedSheetStorageSupport.getInstance() + .getCopiedSheet(workbook); + if (workbook != null) { + saveAndRunPasteSheetCommand(workbook, copiedSheet); + } + } + } + + protected void saveAndRunPasteSheetCommand(IWorkbook workbook, + ISheet copiedSheet) { + PasteSheetCommand command = new PasteSheetCommand(workbook, copiedSheet); + command.setLabel(CommandMessages.Command_PasteSheet); + saveAndRun(command); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RecentFileListContributionItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RecentFileListContributionItem.java index cfffb1960..97dfcf751 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RecentFileListContributionItem.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RecentFileListContributionItem.java @@ -1,105 +1,98 @@ -package org.xmind.ui.internal.actions; - -import java.io.File; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.ui.actions.CompoundContributionItem; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.ui.commands.MindMapCommandConstants; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.internal.protocols.FilePathParser; - -public class RecentFileListContributionItem extends CompoundContributionItem - implements IWorkbenchContribution { - - private static final int MAX_SIZE = 50; - - private IServiceLocator serviceLocator; - - public RecentFileListContributionItem() { - } - - public RecentFileListContributionItem(String id) { - super(id); - } - - @Override - protected IContributionItem[] getContributionItems() { - List items = new ArrayList(); - - fillItems(items); - - IContributionItem[] itemArray = new IContributionItem[items.size()]; - items.toArray(itemArray); - return itemArray; - } - - private void fillItems(List items) { - if (serviceLocator == null) - return; - - IEditorHistory editorHistory = serviceLocator - .getService(IEditorHistory.class); - if (editorHistory == null) - return; - - URI[] pinnedInputURIs = editorHistory.getPinnedInputURIs(); - int pinnedItensToShow = Math.min(pinnedInputURIs.length, MAX_SIZE); - int unpinnedItemsToShow = WorkbenchPlugin.getDefault() - .getPreferenceStore().getInt(IPreferenceConstants.RECENT_FILES); - URI[] unpinnedInputURIs = editorHistory - .getUnpinnedInputURIs(unpinnedItemsToShow); - unpinnedItemsToShow = Math.min(MAX_SIZE, unpinnedInputURIs.length); - - URI[] inputURIs = new URI[pinnedItensToShow + unpinnedItemsToShow]; - System.arraycopy(pinnedInputURIs, 0, inputURIs, 0, pinnedItensToShow); - System.arraycopy(unpinnedInputURIs, 0, inputURIs, pinnedItensToShow, - Math.min(unpinnedItemsToShow, unpinnedInputURIs.length)); - - Map labels = new HashMap(inputURIs.length); - FilePathParser.calculateFileURILabels(inputURIs, labels); - - for (int index = 0; index < inputURIs.length; index++) { - URI inputURI = inputURIs[index]; - if (inputURI.getScheme().equalsIgnoreCase("file")) //$NON-NLS-1$ - if (new File(inputURI).exists()) { - items.add(makeHistoryCommandItem(inputURI, index, - labels.get(inputURI))); - } - } - } - - private IContributionItem makeHistoryCommandItem(URI item, int index, - String label) { - String indexStr = Integer.toString(index + 1); - String id = "org.xmind.ui.file.recent." + indexStr; //$NON-NLS-1$ - CommandContributionItemParameter parameter = new CommandContributionItemParameter( - serviceLocator, id, MindMapCommandConstants.OPEN_WORKBOOK, - CommandContributionItem.STYLE_PUSH); - - if (label == null) { - label = item.toString(); - } - parameter.label = String.format("&%s %s", indexStr, label); //$NON-NLS-1$ - Map params = new HashMap(); - params.put(MindMapCommandConstants.OPEN_WORKBOOK_PARAM_URI, - item.toString()); - parameter.parameters = params; - return new CommandContributionItem(parameter); - } - - public void initialize(IServiceLocator serviceLocator) { - this.serviceLocator = serviceLocator; - } - -} +package org.xmind.ui.internal.actions; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistoryItem; + +public class RecentFileListContributionItem extends CompoundContributionItem + implements IWorkbenchContribution { + + private static final int MAX_SIZE = 5; + + private IServiceLocator serviceLocator; + + public RecentFileListContributionItem() { + } + + public RecentFileListContributionItem(String id) { + super(id); + } + + @Override + protected IContributionItem[] getContributionItems() { + List items = new ArrayList(); + + fillItems(items); + + IContributionItem[] itemArray = new IContributionItem[items.size()]; + items.toArray(itemArray); + return itemArray; + } + + private void fillItems(List items) { + if (serviceLocator == null) + return; + + IEditorHistory editorHistory = serviceLocator + .getService(IEditorHistory.class); + if (editorHistory == null) + return; + + URI[] pinnedInputURIs = editorHistory.getPinnedInputURIs(); + int pinnedItensToShow = Math.min(pinnedInputURIs.length, MAX_SIZE); + int unpinnedItemsToShow = WorkbenchPlugin.getDefault() + .getPreferenceStore().getInt(IPreferenceConstants.RECENT_FILES); + URI[] unpinnedInputURIs = editorHistory + .getUnpinnedInputURIs(unpinnedItemsToShow); + unpinnedItemsToShow = Math.min(MAX_SIZE, unpinnedInputURIs.length); + + URI[] inputURIs = new URI[pinnedItensToShow + unpinnedItemsToShow]; + System.arraycopy(pinnedInputURIs, 0, inputURIs, 0, pinnedItensToShow); + System.arraycopy(unpinnedInputURIs, 0, inputURIs, pinnedItensToShow, + Math.min(unpinnedItemsToShow, unpinnedInputURIs.length)); + + for (int index = 0; index < inputURIs.length; index++) { + URI inputURI = inputURIs[index]; + IEditorHistoryItem item = editorHistory.getItem(inputURI); + items.add(makeHistoryCommandItem(inputURI, index, item.getName())); + } + } + + private IContributionItem makeHistoryCommandItem(URI item, int index, + String label) { + String indexStr = Integer.toString(index + 1); + String id = "org.xmind.ui.file.recent." + indexStr; //$NON-NLS-1$ + CommandContributionItemParameter parameter = new CommandContributionItemParameter( + serviceLocator, id, MindMapCommandConstants.OPEN_WORKBOOK, + CommandContributionItem.STYLE_PUSH); + + if (label == null) { + label = item.toString(); + } + parameter.label = String.format("&%s %s", indexStr, label); //$NON-NLS-1$ + Map params = new HashMap(); + params.put(MindMapCommandConstants.OPEN_WORKBOOK_PARAM_URI, + item.toString()); + parameter.parameters = params; + return new CommandContributionItem(parameter); + } + + public void initialize(IServiceLocator serviceLocator) { + this.serviceLocator = serviceLocator; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RenameSheetAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RenameSheetAction.java index 04ddfb108..a10316d1c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RenameSheetAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/RenameSheetAction.java @@ -14,11 +14,12 @@ package org.xmind.ui.internal.actions; import org.eclipse.jface.action.Action; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.editor.MindMapPageTitleEditor; -public class RenameSheetAction extends Action { +public class RenameSheetAction extends Action implements IWorkbenchAction { private IGraphicalEditorPage page; @@ -43,4 +44,9 @@ public void run() { } } + @Override + public void dispose() { + page = null; + } + } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReopenWorkbookMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReopenWorkbookMenu.java index 8531d67b3..6dff7c3e5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReopenWorkbookMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReopenWorkbookMenu.java @@ -1,321 +1,321 @@ -package org.xmind.ui.internal.actions; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuCreator; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MenuEvent; -import org.eclipse.swt.events.MenuListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.ToolItem; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.internal.IPreferenceConstants; -import org.eclipse.ui.internal.WorkbenchPlugin; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.editor.WorkbookHistory; -import org.xmind.ui.internal.editor.WorkbookHistoryItem; -import org.xmind.ui.util.Logger; - -/** - * - * @author Frank Shaka - * @deprecated Use {@link RecentFileListContributionItem} instead - */ -public class ReopenWorkbookMenu extends Action implements IWorkbenchAction { - - private static final String MODIFIED_TIME_KEY = "org.xmind.ui.workbookHistory.lastModifiedTime"; //$NON-NLS-1$ - - private class WorkbookHistoryMenuCreator - implements IMenuCreator, MenuListener { - - private Menu menu; - - public void dispose() { - if (menu != null) { - menu.dispose(); - menu = null; - } - } - - public Menu getMenu(Control parent) { - if (menu != null && !menu.isDisposed()) - return menu; - menu = new Menu(parent); - menu.addMenuListener(this); - return menu; - } - - public Menu getMenu(Menu parent) { - if (menu != null && !menu.isDisposed()) - return menu; - menu = new Menu(parent); - menu.addMenuListener(this); - return menu; - } - - public void menuHidden(MenuEvent e) { - } - - public void menuShown(MenuEvent e) { - refreshMenu((Menu) e.widget); - } - - } - - private IWorkbenchWindow window; - - public ReopenWorkbookMenu(IWorkbenchWindow window) { - this(window, ActionConstants.REOPEN_WORKBOOK_MENU_ID); - } - - public ReopenWorkbookMenu(IWorkbenchWindow window, String id) { - super(MindMapMessages.ReopenWorkbookMenu_text); - this.window = window; - setId(id); - setToolTipText(MindMapMessages.ReopenWorkbookMenu_toolTip); - setMenuCreator(new WorkbookHistoryMenuCreator()); - } - - public void dispose() { - this.window = null; - } - - @Override - public void runWithEvent(Event event) { - if (event.widget instanceof ToolItem) { - showDropDownMenu((ToolItem) event.widget, event); - } - } - - private void showDropDownMenu(ToolItem ti, Event e) { - IMenuCreator mc = getMenuCreator(); - if (mc == null) - return; - - Menu m = mc.getMenu(ti.getParent()); - if (m != null) { - // position the menu below the drop down item - Rectangle r = ti.getBounds(); - Point point = ti.getParent() - .toDisplay(new Point(r.x, r.y + r.height)); - m.setLocation(point.x, point.y); // waiting - // for SWT - // 0.42 - m.setVisible(true); - return; // we don't fire the action - } - } - - private void refreshMenu(Menu menu) { - long lastModifiedTime = WorkbookHistory.getInstance() - .getLastModifiedTime(); - Object cachedLastModifiedTime = menu.getData(MODIFIED_TIME_KEY); - if (cachedLastModifiedTime instanceof Long - && ((Long) cachedLastModifiedTime) - .longValue() >= lastModifiedTime) - return; - - rebuildMenu(menu); - menu.setData(MODIFIED_TIME_KEY, Long.valueOf(lastModifiedTime)); - } - - private void rebuildMenu(Menu menu) { - removeAll(menu); - fillMenu(menu); - if (menu.getItemCount() == 0) { - MenuItem placeholder = new MenuItem(menu, SWT.PUSH, 0); - placeholder.setText( - MindMapMessages.ReopenWorkbookMenu_NoItemsPlaceholder_text); - placeholder.setEnabled(false); - } - } - - private void removeAll(Menu menu) { - int total = menu.getItemCount(); - for (int i = total; i > 0; i--) { - menu.getItem(i - 1).dispose(); - } - } - - private void fillMenu(Menu menu) { - if (window == null || window.getActivePage() == null) - return; - - int itemsToShow = WorkbenchPlugin.getDefault().getPreferenceStore() - .getInt(IPreferenceConstants.RECENT_FILES); - if (itemsToShow <= 0) - return; - - WorkbookHistoryItem[] items = WorkbookHistory.getInstance() - .getTopItems(itemsToShow); - if (items.length == 0) - return; - - int index = fillWithItems(menu, 0, items); - if (menu.getItemCount() > 0) { - new MenuItem(menu, SWT.SEPARATOR, index); - ++index; - fillClearItem(menu, index); - } - } - - private int fillWithItems(Menu menu, int index, - WorkbookHistoryItem[] items) { - Object[] paths = getDisambiguatedPaths(items); - for (int i = 0; i < items.length; i++) { - WorkbookHistoryItem item = items[i]; - fillWithItem(menu, index, item, i, paths[i].toString()); - ++index; - } - return index; - } - - private void fillWithItem(Menu menu, int menuItemIndex, - final WorkbookHistoryItem item, int itemIndex, String path) { - MenuItem mi = new MenuItem(menu, SWT.PUSH, menuItemIndex); - mi.setText(path); - mi.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - reopen(item); - } - }); - } - - private int fillClearItem(Menu menu, int index) { - MenuItem mi = new MenuItem(menu, SWT.PUSH, index); - mi.setText(MindMapMessages.ReopenWorkbookMenu_ClearListAction_text); - mi.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - clear(); - } - }); - ++index; - - return index; - } - - private static class FileDissection { - String head; - String neck; - File body; - - public FileDissection(File file) { - this.head = file.getName(); - this.neck = null; - this.body = file.getParentFile(); - } - - public void increaseNeck() { - if (body == null) - return; - String name = body.getName(); - body = body.getParentFile(); - if (neck == null) { - neck = name; - } else { - neck = name + File.separator + neck; - } - } - - public boolean canDisambiguateWith(FileDissection that) { - return that != null && this.head.equals(that.head) - && (this.neck == null || this.neck == that.neck - || (this.neck != null - && this.neck.equals(that.neck))) - && (this.body != null || that.body != null); - } - - @Override - public String toString() { - return neck == null ? head - : String.format("%2$s - %3$s", File.separator, head, neck); //$NON-NLS-1$ - } - } - - private Object[] getDisambiguatedPaths(WorkbookHistoryItem[] items) { - Object[] paths = new Object[items.length]; - List files = new ArrayList( - items.length); - - for (int i = 0; i < items.length; i++) { - WorkbookHistoryItem item = items[i]; - String uri = item.getURI(); - String path = item.getPath(); - if (uri.equals(path)) { - // Workbook loaded from a URL: - paths[i] = uri; - } else { - // Workbook loaded form a local file: - FileDissection file = new FileDissection(new File(path)); - paths[i] = file; - files.add(file); - } - } - - for (int i = 1; i < files.size(); i++) { - FileDissection file1 = files.get(i); - for (int j = 0; j < i; j++) { - FileDissection file2 = files.get(j); - while (file1.canDisambiguateWith(file2)) { - file1.increaseNeck(); - file2.increaseNeck(); - } - } - } - - return paths; - } - - private void reopen(final WorkbookHistoryItem item) { - if (window == null) - return; - - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return; - - if (item.getExistingEditorInput() != null) { - IEditorPart editor = page.findEditor(item.getExistingEditorInput()); - if (editor != null) { - page.activate(editor); - return; - } - } - - try { - item.reopen(page); - } catch (CoreException e) { - Logger.log(e); - } - } - - private void clear() { - if (window == null) - return; - - if (!MessageDialog.openConfirm(window.getShell(), - DialogMessages.ConfirmClearRecentFileListDialog_title, - DialogMessages.ConfirmClearRecentFileListDialog_message)) - return; - - WorkbookHistory.getInstance().clear(); - } - -} +package org.xmind.ui.internal.actions; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MenuListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.editor.WorkbookHistory; +import org.xmind.ui.internal.editor.WorkbookHistoryItem; +import org.xmind.ui.util.Logger; + +/** + * + * @author Frank Shaka + * @deprecated Use {@link RecentFileListContributionItem} instead + */ +public class ReopenWorkbookMenu extends Action implements IWorkbenchAction { + + private static final String MODIFIED_TIME_KEY = "org.xmind.ui.workbookHistory.lastModifiedTime"; //$NON-NLS-1$ + + private class WorkbookHistoryMenuCreator + implements IMenuCreator, MenuListener { + + private Menu menu; + + public void dispose() { + if (menu != null) { + menu.dispose(); + menu = null; + } + } + + public Menu getMenu(Control parent) { + if (menu != null && !menu.isDisposed()) + return menu; + menu = new Menu(parent); + menu.addMenuListener(this); + return menu; + } + + public Menu getMenu(Menu parent) { + if (menu != null && !menu.isDisposed()) + return menu; + menu = new Menu(parent); + menu.addMenuListener(this); + return menu; + } + + public void menuHidden(MenuEvent e) { + } + + public void menuShown(MenuEvent e) { + refreshMenu((Menu) e.widget); + } + + } + + private IWorkbenchWindow window; + + public ReopenWorkbookMenu(IWorkbenchWindow window) { + this(window, ActionConstants.REOPEN_WORKBOOK_MENU_ID); + } + + public ReopenWorkbookMenu(IWorkbenchWindow window, String id) { + super(MindMapMessages.ReopenWorkbookMenu_text); + this.window = window; + setId(id); + setToolTipText(MindMapMessages.ReopenWorkbookMenu_toolTip); + setMenuCreator(new WorkbookHistoryMenuCreator()); + } + + public void dispose() { + this.window = null; + } + + @Override + public void runWithEvent(Event event) { + if (event.widget instanceof ToolItem) { + showDropDownMenu((ToolItem) event.widget, event); + } + } + + private void showDropDownMenu(ToolItem ti, Event e) { + IMenuCreator mc = getMenuCreator(); + if (mc == null) + return; + + Menu m = mc.getMenu(ti.getParent()); + if (m != null) { + // position the menu below the drop down item + Rectangle r = ti.getBounds(); + Point point = ti.getParent() + .toDisplay(new Point(r.x, r.y + r.height)); + m.setLocation(point.x, point.y); // waiting + // for SWT + // 0.42 + m.setVisible(true); + return; // we don't fire the action + } + } + + private void refreshMenu(Menu menu) { + long lastModifiedTime = WorkbookHistory.getInstance() + .getLastModifiedTime(); + Object cachedLastModifiedTime = menu.getData(MODIFIED_TIME_KEY); + if (cachedLastModifiedTime instanceof Long + && ((Long) cachedLastModifiedTime) + .longValue() >= lastModifiedTime) + return; + + rebuildMenu(menu); + menu.setData(MODIFIED_TIME_KEY, Long.valueOf(lastModifiedTime)); + } + + private void rebuildMenu(Menu menu) { + removeAll(menu); + fillMenu(menu); + if (menu.getItemCount() == 0) { + MenuItem placeholder = new MenuItem(menu, SWT.PUSH, 0); + placeholder.setText( + MindMapMessages.ReopenWorkbookMenu_NoItemsPlaceholder_text); + placeholder.setEnabled(false); + } + } + + private void removeAll(Menu menu) { + int total = menu.getItemCount(); + for (int i = total; i > 0; i--) { + menu.getItem(i - 1).dispose(); + } + } + + private void fillMenu(Menu menu) { + if (window == null || window.getActivePage() == null) + return; + + int itemsToShow = WorkbenchPlugin.getDefault().getPreferenceStore() + .getInt(IPreferenceConstants.RECENT_FILES); + if (itemsToShow <= 0) + return; + + WorkbookHistoryItem[] items = WorkbookHistory.getInstance() + .getTopItems(itemsToShow); + if (items.length == 0) + return; + + int index = fillWithItems(menu, 0, items); + if (menu.getItemCount() > 0) { + new MenuItem(menu, SWT.SEPARATOR, index); + ++index; + fillClearItem(menu, index); + } + } + + private int fillWithItems(Menu menu, int index, + WorkbookHistoryItem[] items) { + Object[] paths = getDisambiguatedPaths(items); + for (int i = 0; i < items.length; i++) { + WorkbookHistoryItem item = items[i]; + fillWithItem(menu, index, item, i, paths[i].toString()); + ++index; + } + return index; + } + + private void fillWithItem(Menu menu, int menuItemIndex, + final WorkbookHistoryItem item, int itemIndex, String path) { + MenuItem mi = new MenuItem(menu, SWT.PUSH, menuItemIndex); + mi.setText(path); + mi.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + reopen(item); + } + }); + } + + private int fillClearItem(Menu menu, int index) { + MenuItem mi = new MenuItem(menu, SWT.PUSH, index); + mi.setText(MindMapMessages.ReopenWorkbookMenu_ClearListAction_text); + mi.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + clear(); + } + }); + ++index; + + return index; + } + + private static class FileDissection { + String head; + String neck; + File body; + + public FileDissection(File file) { + this.head = file.getName(); + this.neck = null; + this.body = file.getParentFile(); + } + + public void increaseNeck() { + if (body == null) + return; + String name = body.getName(); + body = body.getParentFile(); + if (neck == null) { + neck = name; + } else { + neck = name + File.separator + neck; + } + } + + public boolean canDisambiguateWith(FileDissection that) { + return that != null && this.head.equals(that.head) + && (this.neck == null || this.neck == that.neck + || (this.neck != null + && this.neck.equals(that.neck))) + && (this.body != null || that.body != null); + } + + @Override + public String toString() { + return neck == null ? head + : String.format("%2$s - %3$s", File.separator, head, neck); //$NON-NLS-1$ + } + } + + private Object[] getDisambiguatedPaths(WorkbookHistoryItem[] items) { + Object[] paths = new Object[items.length]; + List files = new ArrayList( + items.length); + + for (int i = 0; i < items.length; i++) { + WorkbookHistoryItem item = items[i]; + String uri = item.getURI(); + String path = item.getPath(); + if (uri.equals(path)) { + // Workbook loaded from a URL: + paths[i] = uri; + } else { + // Workbook loaded form a local file: + FileDissection file = new FileDissection(new File(path)); + paths[i] = file; + files.add(file); + } + } + + for (int i = 1; i < files.size(); i++) { + FileDissection file1 = files.get(i); + for (int j = 0; j < i; j++) { + FileDissection file2 = files.get(j); + while (file1.canDisambiguateWith(file2)) { + file1.increaseNeck(); + file2.increaseNeck(); + } + } + } + + return paths; + } + + private void reopen(final WorkbookHistoryItem item) { + if (window == null) + return; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return; + + if (item.getExistingEditorInput() != null) { + IEditorPart editor = page.findEditor(item.getExistingEditorInput()); + if (editor != null) { + page.activate(editor); + return; + } + } + + try { + item.reopen(page); + } catch (CoreException e) { + Logger.log(e); + } + } + + private void clear() { + if (window == null) + return; + + if (!MessageDialog.openConfirm(window.getShell(), + DialogMessages.ConfirmClearRecentFileListDialog_title, + DialogMessages.ConfirmClearRecentFileListDialog_message)) + return; + + WorkbookHistory.getInstance().clear(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReplaceMarkerAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReplaceMarkerAction.java index 8c17d4d92..9684f8e53 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReplaceMarkerAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ReplaceMarkerAction.java @@ -1,118 +1,118 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.actions; - -import java.io.IOException; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.xmind.core.ISheet; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.util.CloneHandler; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.ui.commands.AddMarkerCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteMarkerCommand; -import org.xmind.ui.util.MarkerImageDescriptor; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class ReplaceMarkerAction extends ViewerAction { - - private final IMarkerRef sourceMarkerRef; - - private final IMarker targetMarker; - - /** - * - */ - public ReplaceMarkerAction(IGraphicalViewer viewer, - IMarkerRef sourceMarkerRef, IMarker targetMarker) { - super(viewer); - Assert.isNotNull(sourceMarkerRef); - Assert.isNotNull(targetMarker); - this.sourceMarkerRef = sourceMarkerRef; - this.targetMarker = targetMarker; - - ISheet sheet = sourceMarkerRef.getOwnedSheet(); - String text = sheet == null || !sheet.getLegend().getMarkerIds() - .contains(targetMarker.getId()) ? null - : sheet.getLegend() - .getMarkerDescription(targetMarker.getId()); - text = text == null ? targetMarker.getName() : text; - setText(text == null ? "" : text); //$NON-NLS-1$ - setImageDescriptor( - MarkerImageDescriptor.createFromMarker(targetMarker, 16, 16)); - - boolean sameMarker = targetMarker.getId() - .equals(sourceMarkerRef.getMarkerId()); - setChecked(sameMarker); - setEnabled(!sameMarker); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (!isEnabled()) - return; - - SafeRunner.run(new SafeRunnable() { - @Override - public void run() throws Exception { - runSafely(); - } - }); - } - - /** - * @throws IOException - */ - private void runSafely() throws IOException { - IMarker actualTargetMarker = sourceMarkerRef.getOwnedWorkbook() - .getMarkerSheet().findMarker(targetMarker.getId()); - if (actualTargetMarker == null) { - actualTargetMarker = (IMarker) new CloneHandler() - .withMarkerSheets(targetMarker.getOwnedSheet(), - sourceMarkerRef.getOwnedWorkbook().getMarkerSheet()) - .cloneObject(targetMarker); - if (actualTargetMarker == null) - return; - } - - Command command = new CompoundCommand( // - CommandMessages.Command_ReplaceMarker, // - - new DeleteMarkerCommand(sourceMarkerRef), // - new AddMarkerCommand(sourceMarkerRef.getParent(), - actualTargetMarker.getId()) // - - ); - - executeCommand(command); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.actions; + +import java.io.IOException; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.xmind.core.ISheet; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.util.CloneHandler; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.ui.commands.AddMarkerCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.util.MarkerImageDescriptor; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class ReplaceMarkerAction extends ViewerAction { + + private final IMarkerRef sourceMarkerRef; + + private final IMarker targetMarker; + + /** + * + */ + public ReplaceMarkerAction(IGraphicalViewer viewer, + IMarkerRef sourceMarkerRef, IMarker targetMarker) { + super(viewer); + Assert.isNotNull(sourceMarkerRef); + Assert.isNotNull(targetMarker); + this.sourceMarkerRef = sourceMarkerRef; + this.targetMarker = targetMarker; + + ISheet sheet = sourceMarkerRef.getOwnedSheet(); + String text = sheet == null || !sheet.getLegend().getMarkerIds() + .contains(targetMarker.getId()) ? null + : sheet.getLegend() + .getMarkerDescription(targetMarker.getId()); + text = text == null ? targetMarker.getName() : text; + setText(text == null ? "" : text); //$NON-NLS-1$ + setImageDescriptor( + MarkerImageDescriptor.createFromMarker(targetMarker, 16, 16)); + + boolean sameMarker = targetMarker.getId() + .equals(sourceMarkerRef.getMarkerId()); + setChecked(sameMarker); + setEnabled(!sameMarker); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (!isEnabled()) + return; + + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + runSafely(); + } + }); + } + + /** + * @throws IOException + */ + private void runSafely() throws IOException { + IMarker actualTargetMarker = sourceMarkerRef.getOwnedWorkbook() + .getMarkerSheet().findMarker(targetMarker.getId()); + if (actualTargetMarker == null) { + actualTargetMarker = (IMarker) new CloneHandler() + .withMarkerSheets(targetMarker.getOwnedSheet(), + sourceMarkerRef.getOwnedWorkbook().getMarkerSheet()) + .cloneObject(targetMarker); + if (actualTargetMarker == null) + return; + } + + Command command = new CompoundCommand( // + CommandMessages.Command_ReplaceMarker, // + + new DeleteMarkerCommand(sourceMarkerRef), // + new AddMarkerCommand(sourceMarkerRef.getParent(), + actualTargetMarker.getId()) // + + ); + + executeCommand(command); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ResetPositionAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ResetPositionAction.java index c82eb53cb..5401edcfa 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ResetPositionAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ResetPositionAction.java @@ -1,74 +1,75 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.IRelationship; -import org.xmind.core.ITopic; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; - -public class ResetPositionAction extends RequestAction - implements ISelectionAction { - - public ResetPositionAction(IGraphicalEditorPage page) { - super(MindMapActionFactory.RESET_POSITION.getId(), page, - MindMapUI.REQ_RESET_POSITION); - } - - public void setSelection(ISelection selection) { - // TODO Auto-generated method stub - if (selection instanceof IStructuredSelection) { - int num = ((IStructuredSelection) selection).size(); - for (Object o : ((IStructuredSelection) selection).toArray()) { - if (!isResettable(o)) { - num--; - } - } - setEnabled(num > 0); - } - } - - private boolean isResettable(Object o) { - // TODO Auto-generated method stub - if (o instanceof ITopic) { - ITopic t = (ITopic) o; - ITopic central = (ITopic) getViewer().getAdapter(ITopic.class); - if (central != null && central.equals(t.getParent()) - && t.isAttached()) { - if (t.getPosition() != null) - return true; - } - } else if (o instanceof IRelationship) { - IRelationship r = (IRelationship) o; - if (r.getControlPoint(0).getPosition() != null - || r.getControlPoint(1).getPosition() != null) - return true; - } - return false; - } - - @Override - public void run() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ResetPositionCount"); //$NON-NLS-1$ - super.run(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.IRelationship; +import org.xmind.core.ITopic; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; + +public class ResetPositionAction extends RequestAction + implements ISelectionAction { + + public ResetPositionAction(IGraphicalEditorPage page) { + super(MindMapActionFactory.RESET_POSITION.getId(), page, + MindMapUI.REQ_RESET_POSITION); + } + + public void setSelection(ISelection selection) { + // TODO Auto-generated method stub + if (selection instanceof IStructuredSelection) { + int num = ((IStructuredSelection) selection).size(); + for (Object o : ((IStructuredSelection) selection).toArray()) { + if (!isResettable(o)) { + num--; + } + } + setEnabled(num > 0); + } + } + + private boolean isResettable(Object o) { + // TODO Auto-generated method stub + if (o instanceof ITopic) { + ITopic t = (ITopic) o; + ITopic central = (ITopic) getViewer().getAdapter(ITopic.class); + if (central != null && central.equals(t.getParent()) + && t.isAttached()) { + if (t.getPosition() != null) + return true; + } + } else if (o instanceof IRelationship) { + IRelationship r = (IRelationship) o; + if (r.getControlPoint(0).getPosition() != null + || r.getControlPoint(1).getPosition() != null) + return true; + } + return false; + } + + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.RESET_POSITION_COUNT); + super.run(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SaveSheetAsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SaveSheetAsAction.java index 726d5fcf5..733581e8e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SaveSheetAsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SaveSheetAsAction.java @@ -1,116 +1,122 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.Arrays; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISaveablePart; -import org.xmind.core.Core; -import org.xmind.core.ICloneData; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.editor.MME; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.MindMapUI; - -public class SaveSheetAsAction extends Action { - - private IGraphicalEditorPage page; - - public SaveSheetAsAction() { - setId(ActionConstants.SAVE_SHEET_AS_ID); - setText(MindMapMessages.SaveSheetAs_text); - setToolTipText(MindMapMessages.SaveSheetAs_toolTip); - } - - public void setActivePage(IGraphicalEditorPage page) { - this.page = page; - setEnabled(page != null && page.getAdapter(IMindMap.class) != null); - } - - public void run() { - if (page == null) - return; - - IMindMap mindmap = (IMindMap) page.getAdapter(IMindMap.class); - if (mindmap == null) - return; - - ISheet sheet = mindmap.getSheet(); - final IWorkbook newWorkbook = Core.getWorkbookBuilder() - .createWorkbook(MME.createTempStorage()); - try { - newWorkbook.saveTemp(); - } catch (Exception ignore) { - } - ICloneData clone = newWorkbook.clone(Arrays.asList(sheet)); - ISheet newSheet = (ISheet) clone.get(sheet); - initSheet(newSheet); - ITopic newCentralTopic = (ITopic) clone.get(mindmap.getCentralTopic()); - if (newCentralTopic == null) - //TODO should we log this? - return; - - newSheet.replaceRootTopic(newCentralTopic); - newWorkbook.addSheet(newSheet); - newWorkbook.removeSheet(newWorkbook.getPrimarySheet()); - - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - final IEditorPart newEditor = page.getParentEditor().getSite() - .getPage().openEditor( - MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook( - newWorkbook, null), - //new WorkbookEditorInput(newWorkbook, null, true), - MindMapUI.MINDMAP_EDITOR_ID, true); - // Forcely make editor saveable: - if (newWorkbook instanceof ICoreEventSource2) { - ((ICoreEventSource2) newWorkbook) - .registerOnceCoreEventListener( - Core.WorkbookPreSaveOnce, - ICoreEventListener.NULL); - } - if (newEditor != null && newEditor instanceof ISaveablePart) { - Display.getCurrent().timerExec(500, new Runnable() { - public void run() { - ((ISaveablePart) newEditor).doSaveAs(); - } - }); - } - } - }); - - } - - private void initSheet(ISheet sheet) { - initTopic(sheet.getRootTopic()); - } - - private void initTopic(ITopic topic) { - for (ITopic child : topic.getAllChildren()) { - initTopic(child); - } - } -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.Arrays; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISaveablePart; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.core.Core; +import org.xmind.core.ICloneData; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.MindMapUI; + +public class SaveSheetAsAction extends Action implements IWorkbenchAction { + + private IGraphicalEditorPage page; + + public SaveSheetAsAction() { + setId(ActionConstants.SAVE_SHEET_AS_ID); + setText(MindMapMessages.SaveSheetAs_text); + setToolTipText(MindMapMessages.SaveSheetAs_toolTip); + } + + public void setActivePage(IGraphicalEditorPage page) { + this.page = page; + setEnabled(page != null && page.getAdapter(IMindMap.class) != null); + } + + public void run() { + if (page == null) + return; + + IMindMap mindmap = (IMindMap) page.getAdapter(IMindMap.class); + if (mindmap == null) + return; + + ISheet sheet = mindmap.getSheet(); + final IWorkbook newWorkbook = Core.getWorkbookBuilder() + .createWorkbook(MME.createTempStorage()); + try { + newWorkbook.saveTemp(); + } catch (Exception ignore) { + } + ICloneData clone = newWorkbook.clone(Arrays.asList(sheet)); + ISheet newSheet = (ISheet) clone.get(sheet); + initSheet(newSheet); + ITopic newCentralTopic = (ITopic) clone.get(mindmap.getCentralTopic()); + if (newCentralTopic == null) + //TODO should we log this? + return; + + newSheet.replaceRootTopic(newCentralTopic); + newWorkbook.addSheet(newSheet); + newWorkbook.removeSheet(newWorkbook.getPrimarySheet()); + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + final IEditorPart newEditor = page.getParentEditor().getSite() + .getPage().openEditor( + MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook( + newWorkbook, null), + //new WorkbookEditorInput(newWorkbook, null, true), + MindMapUI.MINDMAP_EDITOR_ID, true); + // Forcely make editor saveable: + if (newWorkbook instanceof ICoreEventSource2) { + ((ICoreEventSource2) newWorkbook) + .registerOnceCoreEventListener( + Core.WorkbookPreSaveOnce, + ICoreEventListener.NULL); + } + if (newEditor != null && newEditor instanceof ISaveablePart) { + Display.getCurrent().timerExec(500, new Runnable() { + public void run() { + ((ISaveablePart) newEditor).doSaveAs(); + } + }); + } + } + }); + + } + + private void initSheet(ISheet sheet) { + initTopic(sheet.getRootTopic()); + } + + private void initTopic(ITopic topic) { + for (ITopic child : topic.getAllChildren()) { + initTopic(child); + } + } + + @Override + public void dispose() { + page = null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowAllNotesAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowAllNotesAction.java index 4626903b9..eb81283c6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowAllNotesAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowAllNotesAction.java @@ -1,52 +1,52 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.xmind.core.ISheet; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.e4models.NotesPart; -import org.xmind.ui.mindmap.MindMapUI; - -public class ShowAllNotesAction extends Action { - - private NotesPart notesPart; - - public ShowAllNotesAction(NotesPart notesPart) { - this.notesPart = notesPart; - - setId("org.xmind.ui.action.showAllNotes"); //$NON-NLS-1$ - setText(MindMapMessages.ShowAllNotes_text); - setImageDescriptor( - MindMapUI.getImages().get("menu_window_notes.png", true)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.ShowAllNotes_tooltip); - } - - public void run() { - reveal(); - } - - private void reveal() { - if (notesPart == null) { - return; - } - IGraphicalEditor editor = (IGraphicalEditor) notesPart - .getContributingPart(); - if (editor == null) { - return; - } - editor.getSite().getPage().activate(editor); - - ISheet sheet = (ISheet) editor.getActivePageInstance() - .getAdapter(ISheet.class); - if (sheet != null) { - ISelectionProvider selectionProvider = editor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.setSelection(new StructuredSelection(sheet)); - } - } - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.xmind.core.ISheet; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.NotesPart; +import org.xmind.ui.mindmap.MindMapUI; + +public class ShowAllNotesAction extends Action { + + private NotesPart notesPart; + + public ShowAllNotesAction(NotesPart notesPart) { + this.notesPart = notesPart; + + setId("org.xmind.ui.action.showAllNotes"); //$NON-NLS-1$ + setText(MindMapMessages.ShowAllNotes_text); + setImageDescriptor( + MindMapUI.getImages().get("menu_window_notes.png", true)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.ShowAllNotes_tooltip); + } + + public void run() { + reveal(); + } + + private void reveal() { + if (notesPart == null) { + return; + } + IGraphicalEditor editor = (IGraphicalEditor) notesPart + .getContributingPart(); + if (editor == null) { + return; + } + editor.getSite().getPage().activate(editor); + + ISheet sheet = (ISheet) editor.getActivePageInstance() + .getAdapter(ISheet.class); + if (sheet != null) { + ISelectionProvider selectionProvider = editor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.setSelection(new StructuredSelection(sheet)); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowRevisionsActionDelegate.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowRevisionsActionDelegate.java index 03d4677a8..9ee60f595 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowRevisionsActionDelegate.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowRevisionsActionDelegate.java @@ -1,39 +1,39 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IEditorActionDelegate; -import org.eclipse.ui.IEditorPart; -import org.xmind.ui.internal.utils.CommandUtils; - -@Deprecated -public class ShowRevisionsActionDelegate implements IEditorActionDelegate { - - private IEditorPart editor; - - public ShowRevisionsActionDelegate() { - } - - public void run(IAction action) { - if (editor == null) - return; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - CommandUtils.executeCommand( - "org.xmind.ui.command.editingHistory", //$NON-NLS-1$ - editor.getSite().getWorkbenchWindow()); - } - }); - - } - - public void selectionChanged(IAction action, ISelection selection) { - } - - public void setActiveEditor(IAction action, IEditorPart targetEditor) { - this.editor = targetEditor; - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorActionDelegate; +import org.eclipse.ui.IEditorPart; +import org.xmind.ui.internal.utils.CommandUtils; + +@Deprecated +public class ShowRevisionsActionDelegate implements IEditorActionDelegate { + + private IEditorPart editor; + + public ShowRevisionsActionDelegate() { + } + + public void run(IAction action) { + if (editor == null) + return; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + CommandUtils.executeCommand( + "org.xmind.ui.command.editingHistory", //$NON-NLS-1$ + editor.getSite().getWorkbenchWindow()); + } + }); + + } + + public void selectionChanged(IAction action, ISelection selection) { + } + + public void setActiveEditor(IAction action, IEditorPart targetEditor) { + this.editor = targetEditor; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortAction.java index 6f4401a40..1caee9a99 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortAction.java @@ -1,22 +1,22 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.ui.actions.RetargetAction; -import org.xmind.ui.internal.MindMapMessages; - -public class SortAction extends RetargetAction { - - public SortAction(String id) { - super(id, null); - if (ActionConstants.SORT_TITLE_ID.equals(id)) { - setText(MindMapMessages.SortByTitle_text); - setToolTipText(MindMapMessages.SortByTitle_toolTip); - } else if (ActionConstants.SORT_PRIORITY_ID.equals(id)) { - setText(MindMapMessages.SortByPriority_text); - setToolTipText(MindMapMessages.SortByPriority_toolTip); - } else if (ActionConstants.SORT_MODIFIED_ID.equals(id)) { - setText(MindMapMessages.SortByModifiedTime_text); - setToolTipText(MindMapMessages.SortByModifiedTime_toolTip); - } - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.ui.actions.RetargetAction; +import org.xmind.ui.internal.MindMapMessages; + +public class SortAction extends RetargetAction { + + public SortAction(String id) { + super(id, null); + if (ActionConstants.SORT_TITLE_ID.equals(id)) { + setText(MindMapMessages.SortByTitle_text); + setToolTipText(MindMapMessages.SortByTitle_toolTip); + } else if (ActionConstants.SORT_PRIORITY_ID.equals(id)) { + setText(MindMapMessages.SortByPriority_text); + setToolTipText(MindMapMessages.SortByPriority_toolTip); + } else if (ActionConstants.SORT_MODIFIED_ID.equals(id)) { + setText(MindMapMessages.SortByModifiedTime_text); + setToolTipText(MindMapMessages.SortByModifiedTime_toolTip); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortRequestAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortRequestAction.java index 5f2cec8b9..565f9b5ab 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortRequestAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/SortRequestAction.java @@ -1,33 +1,33 @@ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.viewers.ISelection; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.ui.actions.ISelectionAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.util.MindMapUtils; - -public class SortRequestAction extends RequestAction implements - ISelectionAction { - - public SortRequestAction(IGraphicalEditorPage page, String id) { - super(page, GEF.REQ_SORT); - setId(id); - } - - public void run() { - if (isDisposed()) - return; - Request request = new Request(getRequestType()); - request.setDomain(getEditDomain()); - request.setViewer(getViewer()); - request.setParameter(GEF.PARAM_COMPARAND, getId()); - sendRequest(request); - } - - public void setSelection(ISelection selection) { - setEnabled(MindMapUtils.isSingleTopic(selection)); - } - -} +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.viewers.ISelection; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.ui.actions.ISelectionAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.util.MindMapUtils; + +public class SortRequestAction extends RequestAction implements + ISelectionAction { + + public SortRequestAction(IGraphicalEditorPage page, String id) { + super(page, GEF.REQ_SORT); + setId(id); + } + + public void run() { + if (isDisposed()) + return; + Request request = new Request(getRequestType()); + request.setDomain(getEditDomain()); + request.setViewer(getViewer()); + request.setParameter(GEF.PARAM_COMPARAND, getId()); + sendRequest(request); + } + + public void setSelection(ISelection selection) { + setEnabled(MindMapUtils.isSingleTopic(selection)); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenu.java index 6ff1aebf7..852e3a860 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenu.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.ITopic; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.branch.IBranchPolicyDescriptor; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyTopicStructureCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class StructureMenu extends MenuManager { - - private class StructureAction extends Action { - - private IBranchPolicyDescriptor descriptor; - - public StructureAction(IBranchPolicyDescriptor descriptor) { - this.descriptor = descriptor; - setId("#" + descriptor.getId()); //$NON-NLS-1$ - setText(descriptor.getName()); - setImageDescriptor(descriptor.getIcon()); - } - - public void run() { - if (page == null) - return; - - changeStructureClass(descriptor.getId()); - } - - private void changeStructureClass(String newStructureClass) { - EditDomain domain = page.getEditDomain(); - if (domain == null) - return; - - ICommandStack commandStack = domain.getCommandStack(); - if (commandStack == null) - return; - - List topics = getTopics(); - if (topics != null && !topics.isEmpty()) { - ModifyTopicStructureCommand command = new ModifyTopicStructureCommand( - topics, newStructureClass); - command.setLabel(CommandMessages.Command_ModifyTopicStructure); - commandStack.execute(command); - } - } - - private List getTopics() { - ISelection selection = page.getViewer().getSelection(); - if (selection.isEmpty() - || !(selection instanceof IStructuredSelection)) - return null; - Object[] elements = ((IStructuredSelection) selection).toArray(); - ArrayList list = new ArrayList(elements.length); - for (Object o : elements) { - if (o instanceof ITopic && !list.contains(o)) - list.add((ITopic) o); - } - return list; - } - - } - - private IGraphicalEditorPage page; - - public StructureMenu() { - super(MindMapMessages.Structure_text, ActionConstants.STRUCTURE_MENU); - setRemoveAllWhenShown(true); - addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - fillMenu(); - } - }); - } - - public void setActivePage(IGraphicalEditorPage page) { - this.page = page; - } - - private void fillMenu() { - List descriptors = getCurrentStructures(); - if (descriptors == null) - return; - - for (IBranchPolicyDescriptor descriptor : descriptors) { - addStructureAction(descriptor); - } - } - - private void addStructureAction(IBranchPolicyDescriptor descriptor) { - add(new StructureAction(descriptor)); - } - - private List getCurrentStructures() { - if (page == null) - return null; - List list = null; - IViewer viewer = page.getViewer(); - if (viewer != null) { - ISelection selection = viewer.getSelection(); - if (selection instanceof IStructuredSelection) { - for (Object o : ((IStructuredSelection) selection).toArray()) { - if (o instanceof ITopic) { - IBranchPart branch = MindMapUtils.findBranch(viewer - .findPart(o)); - if (branch != null) { - List applicables = MindMapUI - .getBranchPolicyManager() - .getApplicableBranchPolicyDescriptors( - branch); - if (applicables.isEmpty()) - return null; - if (list == null) { - list = new ArrayList( - applicables); - } else { - list.retainAll(applicables); - } - if (list.isEmpty()) - return null; - } - } - } - } - } - return list; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.ITopic; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.branch.IBranchPolicyDescriptor; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyTopicStructureCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class StructureMenu extends MenuManager { + + private class StructureAction extends Action { + + private IBranchPolicyDescriptor descriptor; + + public StructureAction(IBranchPolicyDescriptor descriptor) { + this.descriptor = descriptor; + setId("#" + descriptor.getId()); //$NON-NLS-1$ + setText(descriptor.getName()); + setImageDescriptor(descriptor.getIcon()); + } + + public void run() { + if (page == null) + return; + + changeStructureClass(descriptor.getId()); + } + + private void changeStructureClass(String newStructureClass) { + EditDomain domain = page.getEditDomain(); + if (domain == null) + return; + + ICommandStack commandStack = domain.getCommandStack(); + if (commandStack == null) + return; + + List topics = getTopics(); + if (topics != null && !topics.isEmpty()) { + ModifyTopicStructureCommand command = new ModifyTopicStructureCommand( + topics, newStructureClass); + command.setLabel(CommandMessages.Command_ModifyTopicStructure); + commandStack.execute(command); + } + } + + private List getTopics() { + ISelection selection = page.getViewer().getSelection(); + if (selection.isEmpty() + || !(selection instanceof IStructuredSelection)) + return null; + Object[] elements = ((IStructuredSelection) selection).toArray(); + ArrayList list = new ArrayList(elements.length); + for (Object o : elements) { + if (o instanceof ITopic && !list.contains(o)) + list.add((ITopic) o); + } + return list; + } + + } + + private IGraphicalEditorPage page; + + public StructureMenu() { + super(MindMapMessages.Structure_text, ActionConstants.STRUCTURE_MENU); + setRemoveAllWhenShown(true); + addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillMenu(); + } + }); + } + + public void setActivePage(IGraphicalEditorPage page) { + this.page = page; + } + + private void fillMenu() { + List descriptors = getCurrentStructures(); + if (descriptors == null) + return; + + for (IBranchPolicyDescriptor descriptor : descriptors) { + addStructureAction(descriptor); + } + } + + private void addStructureAction(IBranchPolicyDescriptor descriptor) { + add(new StructureAction(descriptor)); + } + + private List getCurrentStructures() { + if (page == null) + return null; + List list = null; + IViewer viewer = page.getViewer(); + if (viewer != null) { + ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + for (Object o : ((IStructuredSelection) selection).toArray()) { + if (o instanceof ITopic) { + IBranchPart branch = MindMapUtils.findBranch(viewer + .findPart(o)); + if (branch != null) { + List applicables = MindMapUI + .getBranchPolicyManager() + .getApplicableBranchPolicyDescriptors( + branch); + if (applicables.isEmpty()) + return null; + if (list == null) { + list = new ArrayList( + applicables); + } else { + list.retainAll(applicables); + } + if (list.isEmpty()) + return null; + } + } + } + } + } + return list; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenuDynamic.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenuDynamic.java index 1288fd093..375d45dc8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenuDynamic.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/StructureMenuDynamic.java @@ -1,201 +1,201 @@ -package org.xmind.ui.internal.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.ITopic; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.branch.IBranchPolicyDescriptor; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyTopicStructureCommand; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class StructureMenuDynamic extends ContributionItem implements - IWorkbenchContribution { - - private class StructureAction extends Action { - - private IBranchPolicyDescriptor descriptor; - - public StructureAction(IBranchPolicyDescriptor descriptor) { - this.descriptor = descriptor; - setId("#" + descriptor.getId()); //$NON-NLS-1$ - setText(descriptor.getName()); - setImageDescriptor(descriptor.getIcon()); - } - - public void run() { - if (page == null) - return; - - changeStructureClass(descriptor.getId()); - } - - private void changeStructureClass(String newStructureClass) { - EditDomain domain = page.getEditDomain(); - if (domain == null) - return; - - ICommandStack commandStack = domain.getCommandStack(); - if (commandStack == null) - return; - - List topics = getTopics(); - if (topics != null && !topics.isEmpty()) { - ModifyTopicStructureCommand command = new ModifyTopicStructureCommand( - topics, newStructureClass); - command.setLabel(CommandMessages.Command_ModifyTopicStructure); - commandStack.execute(command); - } - } - - private List getTopics() { - ISelection selection = page.getViewer().getSelection(); - if (selection.isEmpty() - || !(selection instanceof IStructuredSelection)) - return null; - Object[] elements = ((IStructuredSelection) selection).toArray(); - ArrayList list = new ArrayList(elements.length); - for (Object o : elements) { - if (o instanceof ITopic && !list.contains(o)) - list.add((ITopic) o); - } - return list; - } - - } - - private IGraphicalEditorPage page; - - private boolean dirty = true; - - private IMenuListener menuListener = new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - manager.markDirty(); - dirty = true; - } - }; - - public boolean isDirty() { - return dirty; - } - - /** - * Overridden to always return true and force dynamic menu building. - */ - public boolean isDynamic() { - return true; - } - - @Override - public void fill(Menu menu, int index) { - if (page == null) - return; - - if (getParent() instanceof MenuManager) { - ((MenuManager) getParent()).addMenuListener(menuListener); - } - - if (!dirty) { - return; - } - - MenuManager manager = new MenuManager(); - fillMenu(manager); - IContributionItem items[] = manager.getItems(); - if (items.length > 0) { - for (int i = 0; i < items.length; i++) { - items[i].fill(menu, index++); - } - } - dirty = false; - } - - private void fillMenu(IMenuManager menu) { - List descriptors = getCurrentStructures(); - if (descriptors == null) - return; - - for (IBranchPolicyDescriptor descriptor : descriptors) { - addStructureAction(descriptor, menu); - } - } - - private void addStructureAction(IBranchPolicyDescriptor descriptor, - IMenuManager menu) { - menu.add(new StructureAction(descriptor)); - } - - private List getCurrentStructures() { - if (page == null) - return null; - List list = null; - IViewer viewer = page.getViewer(); - if (viewer != null) { - ISelection selection = viewer.getSelection(); - if (selection instanceof IStructuredSelection) { - for (Object o : ((IStructuredSelection) selection).toArray()) { - if (o instanceof ITopic) { - IBranchPart branch = MindMapUtils.findBranch(viewer - .findPart(o)); - if (branch != null) { - List applicables = MindMapUI - .getBranchPolicyManager() - .getApplicableBranchPolicyDescriptors( - branch); - if (applicables.isEmpty()) - return null; - if (list == null) { - list = new ArrayList( - applicables); - } else { - list.retainAll(applicables); - } - if (list.isEmpty()) - return null; - } - } - } - } - } - return list; - } - - public void initialize(IServiceLocator serviceLocator) { - IWorkbenchWindow window = (IWorkbenchWindow) serviceLocator - .getService(IWorkbenchWindow.class); - if (window == null) - return; - - IWorkbenchPage activePage = window.getActivePage(); - if (activePage == null) - return; - - IEditorPart editor = activePage.getActiveEditor(); - if (editor instanceof IGraphicalEditor) { - page = ((IGraphicalEditor) editor).getActivePageInstance(); - } - - } - -} +package org.xmind.ui.internal.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.ITopic; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.branch.IBranchPolicyDescriptor; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyTopicStructureCommand; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class StructureMenuDynamic extends ContributionItem implements + IWorkbenchContribution { + + private class StructureAction extends Action { + + private IBranchPolicyDescriptor descriptor; + + public StructureAction(IBranchPolicyDescriptor descriptor) { + this.descriptor = descriptor; + setId("#" + descriptor.getId()); //$NON-NLS-1$ + setText(descriptor.getName()); + setImageDescriptor(descriptor.getIcon()); + } + + public void run() { + if (page == null) + return; + + changeStructureClass(descriptor.getId()); + } + + private void changeStructureClass(String newStructureClass) { + EditDomain domain = page.getEditDomain(); + if (domain == null) + return; + + ICommandStack commandStack = domain.getCommandStack(); + if (commandStack == null) + return; + + List topics = getTopics(); + if (topics != null && !topics.isEmpty()) { + ModifyTopicStructureCommand command = new ModifyTopicStructureCommand( + topics, newStructureClass); + command.setLabel(CommandMessages.Command_ModifyTopicStructure); + commandStack.execute(command); + } + } + + private List getTopics() { + ISelection selection = page.getViewer().getSelection(); + if (selection.isEmpty() + || !(selection instanceof IStructuredSelection)) + return null; + Object[] elements = ((IStructuredSelection) selection).toArray(); + ArrayList list = new ArrayList(elements.length); + for (Object o : elements) { + if (o instanceof ITopic && !list.contains(o)) + list.add((ITopic) o); + } + return list; + } + + } + + private IGraphicalEditorPage page; + + private boolean dirty = true; + + private IMenuListener menuListener = new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + manager.markDirty(); + dirty = true; + } + }; + + public boolean isDirty() { + return dirty; + } + + /** + * Overridden to always return true and force dynamic menu building. + */ + public boolean isDynamic() { + return true; + } + + @Override + public void fill(Menu menu, int index) { + if (page == null) + return; + + if (getParent() instanceof MenuManager) { + ((MenuManager) getParent()).addMenuListener(menuListener); + } + + if (!dirty) { + return; + } + + MenuManager manager = new MenuManager(); + fillMenu(manager); + IContributionItem items[] = manager.getItems(); + if (items.length > 0) { + for (int i = 0; i < items.length; i++) { + items[i].fill(menu, index++); + } + } + dirty = false; + } + + private void fillMenu(IMenuManager menu) { + List descriptors = getCurrentStructures(); + if (descriptors == null) + return; + + for (IBranchPolicyDescriptor descriptor : descriptors) { + addStructureAction(descriptor, menu); + } + } + + private void addStructureAction(IBranchPolicyDescriptor descriptor, + IMenuManager menu) { + menu.add(new StructureAction(descriptor)); + } + + private List getCurrentStructures() { + if (page == null) + return null; + List list = null; + IViewer viewer = page.getViewer(); + if (viewer != null) { + ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + for (Object o : ((IStructuredSelection) selection).toArray()) { + if (o instanceof ITopic) { + IBranchPart branch = MindMapUtils.findBranch(viewer + .findPart(o)); + if (branch != null) { + List applicables = MindMapUI + .getBranchPolicyManager() + .getApplicableBranchPolicyDescriptors( + branch); + if (applicables.isEmpty()) + return null; + if (list == null) { + list = new ArrayList( + applicables); + } else { + list.retainAll(applicables); + } + if (list.isEmpty()) + return null; + } + } + } + } + } + return list; + } + + public void initialize(IServiceLocator serviceLocator) { + IWorkbenchWindow window = (IWorkbenchWindow) serviceLocator + .getService(IWorkbenchWindow.class); + if (window == null) + return; + + IWorkbenchPage activePage = window.getActivePage(); + if (activePage == null) + return; + + IEditorPart editor = activePage.getActiveEditor(); + if (editor instanceof IGraphicalEditor) { + page = ((IGraphicalEditor) editor).getActivePageInstance(); + } + + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TileAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TileAction.java index 469e658ed..3135eb612 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TileAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TileAction.java @@ -16,6 +16,7 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; +import org.xmind.core.internal.UserDataConstants; import org.xmind.gef.ui.actions.RequestAction; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.ui.actions.MindMapActionFactory; @@ -54,7 +55,7 @@ public void propertyChange(PropertyChangeEvent event) { @Override public void run() { MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("TileCount"); //$NON-NLS-1$ + .increase(UserDataConstants.TILE_COUNT); super.run(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TryProAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TryProAction.java index 420cca778..235ac1c99 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TryProAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/TryProAction.java @@ -1,302 +1,302 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.internal.MindMapMessages; - -/** - * @author briansun - * @deprecated The upgrade functionality has been moved to plugin - * net.xmind.signin. This plugin ( - * org.xmind.ui.mindmap) no longer depends on Eclipse - * update plugins. - */ -public class TryProAction extends Action implements IWorkbenchAction { - - private IWorkbenchWindow window; - -// private static class SpecificFeatureFilter implements IUpdateSearchFilter { -// -// private String featureId; -// -// /** -// * @param featureId -// */ -// public SpecificFeatureFilter(String featureId) { -// this.featureId = featureId; -// } -// -// /** -// * @see org.eclipse.update.search.IUpdateSearchFilter#accept(org.eclipse.update.core.IFeature) -// */ -// public boolean accept(IFeature match) { -// return featureId.equals(match.getVersionedIdentifier() -// .getIdentifier()); -// } -// -// /** -// * @see org.eclipse.update.search.IUpdateSearchFilter#accept(org.eclipse.update.core.IFeatureReference) -// */ -// public boolean accept(IFeatureReference match) { -// try { -// return featureId.equals(match.getVersionedIdentifier() -// .getIdentifier()); -// } catch (CoreException e) { -// return false; -// } -// } -// -// } -// -// private static class UpdateSourceDialog extends Dialog { -// -// private String url; -// -// private Button onlineButton; -// -// private Button localFileButton; -// -// public UpdateSourceDialog(Shell parentShell) { -// super(parentShell); -// setBlockOnOpen(true); -// setShellStyle(SWT.TITLE | SWT.CLOSE); -// } -// -// protected void configureShell(Shell newShell) { -// super.configureShell(newShell); -// newShell.setText(MindMapMessages.TryPro_UpdateSourceDialog_title); -// } -// -// protected Control createDialogArea(Composite parent) { -// Composite composite = (Composite) super.createDialogArea(parent); -// -// Label label = new Label(composite, SWT.NONE); -// label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, -// false)); -// label.setText(MindMapMessages.TryPro_UpdateSourceDialog_label); -// -// onlineButton = new Button(composite, SWT.RADIO); -// onlineButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, -// false)); -// onlineButton -// .setText(MindMapMessages.TryPro_UpdateSourceDialog_Online); -// -// localFileButton = new Button(composite, SWT.RADIO); -// localFileButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, -// true, false)); -// localFileButton -// .setText(MindMapMessages.TryPro_UpdateSourceDialog_LocalFile); -// -// onlineButton.setSelection(true); -// localFileButton.setSelection(false); -// -// return composite; -// } -// -// protected void okPressed() { -// boolean openFileDialog = localFileButton.getSelection(); -// if (openFileDialog) { -// FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN); -// fileDialog.setFilterExtensions(new String[] { "*.*" }); //$NON-NLS-1$ -// fileDialog.setFilterNames(new String[] { NLS.bind("{0} (*.*)", //$NON-NLS-1$ -// DialogMessages.AllFilesFilterName) }); -// String path = fileDialog.open(); -// if (path == null) { -// return; -// } -// this.url = "jar:file:" + path + "!/"; //$NON-NLS-1$ //$NON-NLS-2$ -// } else { -// this.url = "http://www.xmind.net/xmind/updates/xmindpro3/"; //$NON-NLS-1$ -// } -// super.okPressed(); -// } -// -// public String getURL() { -// return url; -// } -// } -// -// private UpdateSearchRequest searchRequest; -// -// private List updates; -// -// private TryProJob job; -// -// private class SearchResultCollector implements IUpdateSearchResultCollector { -// public void accept(IFeature feature) { -// IInstallFeatureOperation operation = OperationsManager -// .getOperationFactory().createInstallOperation(null, -// feature, null, null, null); -// updates.add(operation); -// } -// } -// -// private class TryProJob extends Job { -// -// /** -// * @param name -// */ -// public TryProJob() { -// super(MindMapMessages.TryPro_UpdateSourceDialog_jobName); -// } -// -// /** -// * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) -// */ -// @Override -// protected IStatus run(IProgressMonitor monitor) { -// try { -// searchRequest.performSearch(new SearchResultCollector(), -// monitor); -// return Status.OK_STATUS; -// } catch (OperationCanceledException e) { -// return Status.CANCEL_STATUS; -// } catch (CoreException e) { -// return e.getStatus(); -// } -// } -// -// } - - public TryProAction(IWorkbenchWindow window) { - this("org.xmind.ui.upgradeXMind", window); //$NON-NLS-1$ - } - - /** - * @param id - * @param window - */ - public TryProAction(String id, IWorkbenchWindow window) { - super(MindMapMessages.TryPro_text); - setId(id); - setToolTipText(MindMapMessages.TryPro_toolTip); - if (window == null) - throw new IllegalArgumentException(); - this.window = window; - } - - /** - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - if (window == null) - return; - -// UpdateSourceDialog dialog = new UpdateSourceDialog(window.getShell()); -// int retCode = dialog.open(); -// if (retCode != UpdateSourceDialog.OK) -// return; -// -// String url = dialog.getURL(); -// UpdateSearchScope scope = new UpdateSearchScope(); -// try { -// scope.addSearchSite("XMind Pro", new URL(url), null); //$NON-NLS-1$ -// } catch (MalformedURLException e) { -// Logger.log(e); -// } -// scope.setFeatureProvidedSitesEnabled(false); -// searchRequest = new UpdateSearchRequest(UpdateSearchRequest -// .createDefaultSiteSearchCategory(), scope); -// searchRequest.addFilter(new EnvironmentFilter()); -// searchRequest.addFilter(new BackLevelFilter()); -// searchRequest.addFilter(new SpecificFeatureFilter( -// "org.xmind.meggy.feature")); //$NON-NLS-1$ - -// UpdateJob job = new UpdateJob("Try Pro", searchRequest); -// UpdateManagerUI.openInstaller(window.getShell(), job); - - searchFeature(); - } - - /** - * - */ - private void searchFeature() { -// updates = new ArrayList(); -// job = new TryProJob(); -// job.addJobChangeListener(new JobChangeAdapter() { -// -// /** -// * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent) -// */ -// @Override -// public void done(IJobChangeEvent event) { -// afterSearch(event.getResult()); -// } -// -// }); -// job.schedule(); - } - -// /** -// * @param result -// */ -// private void afterSearch(final IStatus result) { -// if (result == Status.CANCEL_STATUS) -// return; -// final Shell shell = window.getShell(); -// if (result != Status.OK_STATUS) -// shell.getDisplay().syncExec(new Runnable() { -// public void run() { -// UpdateUI.log(result, true); -// } -// }); -// shell.getDisplay().asyncExec(new Runnable() { -// public void run() { -// BusyIndicator.showWhile(shell.getDisplay(), new Runnable() { -// public void run() { -// openInstallWizard(); -// } -// }); -// } -// }); -// } - -// /** -// * -// */ -// private void openInstallWizard() { -// Shell shell = window.getShell(); -// if (InstallWizard2.isRunning()) { -// MessageDialog.openInformation(shell, -// UpdateUIMessages.InstallWizard_isRunningTitle, -// UpdateUIMessages.InstallWizard_isRunningInfo); -// return; -// } -// if (updates == null || updates.isEmpty()) { -// MessageDialog.openInformation(shell, -// MindMapMessages.TryPro_ErrorDialog_title, -// MindMapMessages.TryPro_ErrorDialog_message); -// return; -// } -// InstallWizard2 wizard = new InstallWizard2(searchRequest, updates -// .toArray(new IInstallFeatureOperation[0]), true); -// final WizardDialog dialog = new ResizableInstallWizardDialog(shell, -// wizard, MindMapMessages.TryPro_InstallDialog_title); -// dialog.create(); -// dialog.open(); -// } - - /** - * @see org.eclipse.ui.actions.ActionFactory.IWorkbenchAction#dispose() - */ - public void dispose() { - window = null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.ui.internal.MindMapMessages; + +/** + * @author briansun + * @deprecated The upgrade functionality has been moved to plugin + * net.xmind.signin. This plugin ( + * org.xmind.ui.mindmap) no longer depends on Eclipse + * update plugins. + */ +public class TryProAction extends Action implements IWorkbenchAction { + + private IWorkbenchWindow window; + +// private static class SpecificFeatureFilter implements IUpdateSearchFilter { +// +// private String featureId; +// +// /** +// * @param featureId +// */ +// public SpecificFeatureFilter(String featureId) { +// this.featureId = featureId; +// } +// +// /** +// * @see org.eclipse.update.search.IUpdateSearchFilter#accept(org.eclipse.update.core.IFeature) +// */ +// public boolean accept(IFeature match) { +// return featureId.equals(match.getVersionedIdentifier() +// .getIdentifier()); +// } +// +// /** +// * @see org.eclipse.update.search.IUpdateSearchFilter#accept(org.eclipse.update.core.IFeatureReference) +// */ +// public boolean accept(IFeatureReference match) { +// try { +// return featureId.equals(match.getVersionedIdentifier() +// .getIdentifier()); +// } catch (CoreException e) { +// return false; +// } +// } +// +// } +// +// private static class UpdateSourceDialog extends Dialog { +// +// private String url; +// +// private Button onlineButton; +// +// private Button localFileButton; +// +// public UpdateSourceDialog(Shell parentShell) { +// super(parentShell); +// setBlockOnOpen(true); +// setShellStyle(SWT.TITLE | SWT.CLOSE); +// } +// +// protected void configureShell(Shell newShell) { +// super.configureShell(newShell); +// newShell.setText(MindMapMessages.TryPro_UpdateSourceDialog_title); +// } +// +// protected Control createDialogArea(Composite parent) { +// Composite composite = (Composite) super.createDialogArea(parent); +// +// Label label = new Label(composite, SWT.NONE); +// label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, +// false)); +// label.setText(MindMapMessages.TryPro_UpdateSourceDialog_label); +// +// onlineButton = new Button(composite, SWT.RADIO); +// onlineButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, +// false)); +// onlineButton +// .setText(MindMapMessages.TryPro_UpdateSourceDialog_Online); +// +// localFileButton = new Button(composite, SWT.RADIO); +// localFileButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, +// true, false)); +// localFileButton +// .setText(MindMapMessages.TryPro_UpdateSourceDialog_LocalFile); +// +// onlineButton.setSelection(true); +// localFileButton.setSelection(false); +// +// return composite; +// } +// +// protected void okPressed() { +// boolean openFileDialog = localFileButton.getSelection(); +// if (openFileDialog) { +// FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN); +// fileDialog.setFilterExtensions(new String[] { "*.*" }); //$NON-NLS-1$ +// fileDialog.setFilterNames(new String[] { NLS.bind("{0} (*.*)", //$NON-NLS-1$ +// DialogMessages.AllFilesFilterName) }); +// String path = fileDialog.open(); +// if (path == null) { +// return; +// } +// this.url = "jar:file:" + path + "!/"; //$NON-NLS-1$ //$NON-NLS-2$ +// } else { +// this.url = "http://www.xmind.net/xmind/updates/xmindpro3/"; //$NON-NLS-1$ +// } +// super.okPressed(); +// } +// +// public String getURL() { +// return url; +// } +// } +// +// private UpdateSearchRequest searchRequest; +// +// private List updates; +// +// private TryProJob job; +// +// private class SearchResultCollector implements IUpdateSearchResultCollector { +// public void accept(IFeature feature) { +// IInstallFeatureOperation operation = OperationsManager +// .getOperationFactory().createInstallOperation(null, +// feature, null, null, null); +// updates.add(operation); +// } +// } +// +// private class TryProJob extends Job { +// +// /** +// * @param name +// */ +// public TryProJob() { +// super(MindMapMessages.TryPro_UpdateSourceDialog_jobName); +// } +// +// /** +// * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) +// */ +// @Override +// protected IStatus run(IProgressMonitor monitor) { +// try { +// searchRequest.performSearch(new SearchResultCollector(), +// monitor); +// return Status.OK_STATUS; +// } catch (OperationCanceledException e) { +// return Status.CANCEL_STATUS; +// } catch (CoreException e) { +// return e.getStatus(); +// } +// } +// +// } + + public TryProAction(IWorkbenchWindow window) { + this("org.xmind.ui.upgradeXMind", window); //$NON-NLS-1$ + } + + /** + * @param id + * @param window + */ + public TryProAction(String id, IWorkbenchWindow window) { + super(MindMapMessages.TryPro_text); + setId(id); + setToolTipText(MindMapMessages.TryPro_toolTip); + if (window == null) + throw new IllegalArgumentException(); + this.window = window; + } + + /** + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + if (window == null) + return; + +// UpdateSourceDialog dialog = new UpdateSourceDialog(window.getShell()); +// int retCode = dialog.open(); +// if (retCode != UpdateSourceDialog.OK) +// return; +// +// String url = dialog.getURL(); +// UpdateSearchScope scope = new UpdateSearchScope(); +// try { +// scope.addSearchSite("XMind Pro", new URL(url), null); //$NON-NLS-1$ +// } catch (MalformedURLException e) { +// Logger.log(e); +// } +// scope.setFeatureProvidedSitesEnabled(false); +// searchRequest = new UpdateSearchRequest(UpdateSearchRequest +// .createDefaultSiteSearchCategory(), scope); +// searchRequest.addFilter(new EnvironmentFilter()); +// searchRequest.addFilter(new BackLevelFilter()); +// searchRequest.addFilter(new SpecificFeatureFilter( +// "org.xmind.meggy.feature")); //$NON-NLS-1$ + +// UpdateJob job = new UpdateJob("Try Pro", searchRequest); +// UpdateManagerUI.openInstaller(window.getShell(), job); + + searchFeature(); + } + + /** + * + */ + private void searchFeature() { +// updates = new ArrayList(); +// job = new TryProJob(); +// job.addJobChangeListener(new JobChangeAdapter() { +// +// /** +// * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent) +// */ +// @Override +// public void done(IJobChangeEvent event) { +// afterSearch(event.getResult()); +// } +// +// }); +// job.schedule(); + } + +// /** +// * @param result +// */ +// private void afterSearch(final IStatus result) { +// if (result == Status.CANCEL_STATUS) +// return; +// final Shell shell = window.getShell(); +// if (result != Status.OK_STATUS) +// shell.getDisplay().syncExec(new Runnable() { +// public void run() { +// UpdateUI.log(result, true); +// } +// }); +// shell.getDisplay().asyncExec(new Runnable() { +// public void run() { +// BusyIndicator.showWhile(shell.getDisplay(), new Runnable() { +// public void run() { +// openInstallWizard(); +// } +// }); +// } +// }); +// } + +// /** +// * +// */ +// private void openInstallWizard() { +// Shell shell = window.getShell(); +// if (InstallWizard2.isRunning()) { +// MessageDialog.openInformation(shell, +// UpdateUIMessages.InstallWizard_isRunningTitle, +// UpdateUIMessages.InstallWizard_isRunningInfo); +// return; +// } +// if (updates == null || updates.isEmpty()) { +// MessageDialog.openInformation(shell, +// MindMapMessages.TryPro_ErrorDialog_title, +// MindMapMessages.TryPro_ErrorDialog_message); +// return; +// } +// InstallWizard2 wizard = new InstallWizard2(searchRequest, updates +// .toArray(new IInstallFeatureOperation[0]), true); +// final WizardDialog dialog = new ResizableInstallWizardDialog(shell, +// wizard, MindMapMessages.TryPro_InstallDialog_title); +// dialog.create(); +// dialog.open(); +// } + + /** + * @see org.eclipse.ui.actions.ActionFactory.IWorkbenchAction#dispose() + */ + public void dispose() { + window = null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ViewerAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ViewerAction.java index aa4663c9f..e8e32c4dd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ViewerAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ViewerAction.java @@ -1,64 +1,64 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.actions; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.action.Action; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.ICommandStack; - -/** - * @author Frank Shaka - * - */ -public abstract class ViewerAction extends Action { - - private final IGraphicalViewer viewer; - - /** - * - */ - public ViewerAction(IGraphicalViewer viewer) { - super(); - Assert.isNotNull(viewer); - this.viewer = viewer; - } - - /** - * @return the viewer - */ - protected IGraphicalViewer getViewer() { - return viewer; - } - - protected ICommandStack getCommandStack() { - EditDomain editDomain = viewer.getEditDomain(); - return editDomain == null ? null : editDomain.getCommandStack(); - } - - protected void executeCommand(Command command) { - ICommandStack commandStack = getCommandStack(); - if (commandStack != null) { - commandStack.execute(command); - } else { - command.execute(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.actions; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.action.Action; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.ICommandStack; + +/** + * @author Frank Shaka + * + */ +public abstract class ViewerAction extends Action { + + private final IGraphicalViewer viewer; + + /** + * + */ + public ViewerAction(IGraphicalViewer viewer) { + super(); + Assert.isNotNull(viewer); + this.viewer = viewer; + } + + /** + * @return the viewer + */ + protected IGraphicalViewer getViewer() { + return viewer; + } + + protected ICommandStack getCommandStack() { + EditDomain editDomain = viewer.getEditDomain(); + return editDomain == null ? null : editDomain.getCommandStack(); + } + + protected void executeCommand(Command command) { + ICommandStack commandStack = getCommandStack(); + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchPolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchPolicy.java index 12e8ccd69..c61a036ef 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchPolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchPolicy.java @@ -1,331 +1,331 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.draw2d.PositionConstants; -import org.xmind.core.Core; -import org.xmind.core.ITopic; -import org.xmind.gef.graphicalpolicy.AbstractGraphicalPolicy; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.branch.IBranchStructure; -import org.xmind.ui.branch.IBranchStructureExtension; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ICacheManager; -import org.xmind.ui.mindmap.ICacheValueProvider; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.IToolHelper; -import org.xmind.ui.util.MindMapUtils; - -public abstract class AbstractBranchPolicy extends AbstractGraphicalPolicy - implements IBranchPolicy, ICacheValueProvider { - - protected static final String RIGHT_STRUCTURE_ID = "org.xmind.ui.branchStructure.right"; //$NON-NLS-1$ - - protected static final String DOWN_STRUCTURE_ID = "org.xmind.ui.branchStructure.down"; //$NON-NLS-1$ - - protected static final String UP_STRUCTURE_ID = "org.xmind.ui.branchStructure.up"; //$NON-NLS-1$ - - protected static final String LEFT_STRUCTURE_ID = "org.xmind.ui.branchStructure.left"; //$NON-NLS-1$ - - protected static IBranchStructure left = null; - - protected static IBranchStructure right = null; - - protected static IBranchStructure up = null; - - protected static IBranchStructure down = null; - - protected BranchPolicyManager manager; - - private String id; - - private Set calculationQueue; - - public AbstractBranchPolicy(BranchPolicyManager manager, String id) { - this.manager = manager; - this.id = id; - } - - protected String getPolicyId() { - return id; - } - - public void activate(IGraphicalPart part) { - super.activate(part); - if (part instanceof IBranchPart) { - activateBranch((IBranchPart) part); - } - } - - public void deactivate(IGraphicalPart part) { - if (part instanceof IBranchPart) { - deactivateBranch((IBranchPart) part); - } - super.deactivate(part); - } - - public void postDeactivate(IBranchPart branch) { - } - - protected void activateBranch(IBranchPart branch) { - ICacheManager cm = MindMapUtils.getCacheManager(branch); - if (cm != null) { - cm.setValueProvider(CACHE_STRUCTURE_ID, this); - } - addHook(branch); - flushStructureCache(branch, true, true); - } - - protected void deactivateBranch(IBranchPart branch) { - flushStructureCache(branch, true, true); - removeHook(branch); - ICacheManager cm = MindMapUtils.getCacheManager(branch); - if (cm != null) { - cm.removeValueProvider(CACHE_STRUCTURE_ID); - } - } - - protected void addHook(IBranchPart branch) { - IBranchHook hook = createHook(branch); - if (hook != null) { - hook.hook(branch); - MindMapUtils.setCache(branch, IBranchHook.CACHE_BRANCH_HOOK, hook); - } - } - - protected abstract IBranchHook createHook(IBranchPart branch); - - protected void removeHook(IBranchPart branch) { - IBranchHook hook = (IBranchHook) MindMapUtils.getCache(branch, - IBranchHook.CACHE_BRANCH_HOOK); - if (hook != null) { - MindMapUtils.flushCache(branch, IBranchHook.CACHE_BRANCH_HOOK); - hook.unhook(branch); - } - } - - public void flushStructureCache(IBranchPart branch, boolean ancestors, - boolean descendants) { - flushStructureCache(branch); - if (ancestors) - flushParentStructureCache(branch); - if (descendants) - flushChildrenStructureCache(branch); - } - - protected void flushStructureCache(IBranchPart branch) { - MindMapUtils.flushCache(branch, CACHE_STRUCTURE_ID); - } - - protected void flushParentStructureCache(IBranchPart branch) { - IBranchPart parent = branch.getParentBranch(); - if (parent == null) - return; - String policyId = parent.getBranchPolicyId(); - if (getPolicyId().equals(policyId)) { - parent.getBranchPolicy().flushStructureCache(parent, true, false); - } - } - - protected void flushChildrenStructureCache(IBranchPart branch) { - for (IBranchPart child : branch.getSubBranches()) { - flushChildStructureCache(child); - } - for (IBranchPart child : branch.getCalloutBranches()) { - flushChildStructureCache(child); - } - for (IBranchPart child : branch.getSummaryBranches()) { - flushChildStructureCache(child); - } - } - - protected void flushChildStructureCache(IBranchPart child) { - String policyId = child.getBranchPolicyId(); - if (getPolicyId().equals(policyId)) { - child.getBranchPolicy().flushStructureCache(child, false, true); - } - } - - public IToolHelper getToolHelper(IBranchPart parent, - Class type) { - return null; - } - - public boolean isPropertyModifiable(IBranchPart branch, String propertyKey) { - return isPropertyModifiable(branch, propertyKey, null); - } - - public boolean isPropertyModifiable(IBranchPart branch, String propertyKey, - String secondaryKey) { - boolean modifiable = internalCheckPropertyModifiability(branch, - propertyKey, secondaryKey); - if (modifiable) { - modifiable = !isUnmodifiableProperty(branch, propertyKey, - secondaryKey); - } - return modifiable; - } - - protected abstract boolean isUnmodifiableProperty(IBranchPart branch, - String propertyKey, String secondaryKey); - - protected boolean internalCheckPropertyModifiability(IBranchPart branch, - String propertyKey, String secondaryKey) { - if (Core.TopicFolded.equals(propertyKey)) - return isBranchFoldable(branch); - if (Core.TopicHyperlink.equals(propertyKey)) - return isHyperlinkModifiable(branch); - return true; - } - - protected boolean isHyperlinkModifiable(IBranchPart branch) { - ITopic t = branch.getTopic(); - String uri = t.getHyperlink(); - if (uri != null) { - return MindMapUI.getProtocolManager().isHyperlinkModifiable(t, uri); - } - return true; - } - - protected boolean isBranchFoldable(IBranchPart branch) { - return !branch.isCentral();// && !branch.getSubBranches().isEmpty(); - } - - protected IStyleSelector createDefaultStyleSelector() { - return DefaultBranchStyleSelector.getDefault(); - } - - public IStructure getStructure(IGraphicalPart part) { - IBranchPart branch = (IBranchPart) part; - String structureId = (String) MindMapUtils.getCache(branch, - CACHE_STRUCTURE_ID); - return getStructureAlgorithmById(part, structureId); - } - - private IStructure getStructureAlgorithmById(IGraphicalPart part, - String structureId) { - if (structureId != null) { - IStructureDescriptor structureDescriptor = manager - .getStructureDescriptor(structureId); - if (structureDescriptor != null) - return structureDescriptor.getAlgorithm(); - IBranchStructure sa = getPredefinedStructure(structureId); - if (sa != null) - return sa; - } - return super.getStructure(part); - } - - public Object getValue(IPart part, String key) { - IBranchPart branch = (IBranchPart) part; - if (CACHE_STRUCTURE_ID.equals(key)) { - return calculateStructureAlgorithmId(branch); - } - return null; - } - - protected String calculateStructureAlgorithmId(IBranchPart branch) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null && parent.getSummaryBranches().contains(branch)) { - return calcSummaryBranchStructureType(branch, parent); - } - - if (isCalculatingOn(branch)) - return getDefaultStructureId(); - - startCalculationOn(branch); - - String structureId = calcAdditionalStructureId(branch, parent); - - endCalculationOn(branch); - - if (structureId != null) - return structureId; - - return getDefaultStructureId(); - } - - protected abstract String calcAdditionalStructureId(IBranchPart branch, - IBranchPart parent); - - private String calcSummaryBranchStructureType(IBranchPart branch, - IBranchPart parent) { - ISummaryPart summary = MindMapUtils.findAttachedSummary(parent, branch); - if (summary != null) { - IStructure sa = parent.getBranchPolicy().getStructure(parent); - if (sa instanceof IBranchStructureExtension) { - int direction = ((IBranchStructureExtension) sa) - .getSummaryDirection(parent, summary); - if (direction == PositionConstants.WEST) - return LEFT_STRUCTURE_ID; - if (direction == PositionConstants.NORTH) - return UP_STRUCTURE_ID; - if (direction == PositionConstants.SOUTH) - return DOWN_STRUCTURE_ID; - } - } - return RIGHT_STRUCTURE_ID; - } - - protected boolean isCalculatingOn(IBranchPart branch) { - return calculationQueue != null && calculationQueue.contains(branch); - } - - protected void startCalculationOn(IBranchPart branch) { - if (calculationQueue == null) - calculationQueue = new HashSet(); - calculationQueue.add(branch); - } - - protected void endCalculationOn(IBranchPart branch) { - if (calculationQueue == null) - return; - calculationQueue.remove(branch); - if (calculationQueue.isEmpty()) - calculationQueue = null; - } - - protected IBranchStructure getPredefinedStructure(String structureId) { - if (LEFT_STRUCTURE_ID.equals(structureId)) { - if (left == null) - left = new LeftStructure(); - return left; - } else if (RIGHT_STRUCTURE_ID.equals(structureId)) { - if (right == null) - right = new RightStructure(); - return right; - } else if (UP_STRUCTURE_ID.equals(structureId)) { - if (up == null) - up = new UpStructure(); - return up; - } else if (DOWN_STRUCTURE_ID.equals(structureId)) { - if (down == null) - down = new DownStructure(); - return down; - } - return null; - } - - protected abstract String getDefaultStructureId(); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.draw2d.PositionConstants; +import org.xmind.core.Core; +import org.xmind.core.ITopic; +import org.xmind.gef.graphicalpolicy.AbstractGraphicalPolicy; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.branch.IBranchStructure; +import org.xmind.ui.branch.IBranchStructureExtension; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ICacheManager; +import org.xmind.ui.mindmap.ICacheValueProvider; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.IToolHelper; +import org.xmind.ui.util.MindMapUtils; + +public abstract class AbstractBranchPolicy extends AbstractGraphicalPolicy + implements IBranchPolicy, ICacheValueProvider { + + protected static final String RIGHT_STRUCTURE_ID = "org.xmind.ui.branchStructure.right"; //$NON-NLS-1$ + + protected static final String DOWN_STRUCTURE_ID = "org.xmind.ui.branchStructure.down"; //$NON-NLS-1$ + + protected static final String UP_STRUCTURE_ID = "org.xmind.ui.branchStructure.up"; //$NON-NLS-1$ + + protected static final String LEFT_STRUCTURE_ID = "org.xmind.ui.branchStructure.left"; //$NON-NLS-1$ + + protected static IBranchStructure left = null; + + protected static IBranchStructure right = null; + + protected static IBranchStructure up = null; + + protected static IBranchStructure down = null; + + protected BranchPolicyManager manager; + + private String id; + + private Set calculationQueue; + + public AbstractBranchPolicy(BranchPolicyManager manager, String id) { + this.manager = manager; + this.id = id; + } + + protected String getPolicyId() { + return id; + } + + public void activate(IGraphicalPart part) { + super.activate(part); + if (part instanceof IBranchPart) { + activateBranch((IBranchPart) part); + } + } + + public void deactivate(IGraphicalPart part) { + if (part instanceof IBranchPart) { + deactivateBranch((IBranchPart) part); + } + super.deactivate(part); + } + + public void postDeactivate(IBranchPart branch) { + } + + protected void activateBranch(IBranchPart branch) { + ICacheManager cm = MindMapUtils.getCacheManager(branch); + if (cm != null) { + cm.setValueProvider(CACHE_STRUCTURE_ID, this); + } + addHook(branch); + flushStructureCache(branch, true, true); + } + + protected void deactivateBranch(IBranchPart branch) { + flushStructureCache(branch, true, true); + removeHook(branch); + ICacheManager cm = MindMapUtils.getCacheManager(branch); + if (cm != null) { + cm.removeValueProvider(CACHE_STRUCTURE_ID); + } + } + + protected void addHook(IBranchPart branch) { + IBranchHook hook = createHook(branch); + if (hook != null) { + hook.hook(branch); + MindMapUtils.setCache(branch, IBranchHook.CACHE_BRANCH_HOOK, hook); + } + } + + protected abstract IBranchHook createHook(IBranchPart branch); + + protected void removeHook(IBranchPart branch) { + IBranchHook hook = (IBranchHook) MindMapUtils.getCache(branch, + IBranchHook.CACHE_BRANCH_HOOK); + if (hook != null) { + MindMapUtils.flushCache(branch, IBranchHook.CACHE_BRANCH_HOOK); + hook.unhook(branch); + } + } + + public void flushStructureCache(IBranchPart branch, boolean ancestors, + boolean descendants) { + flushStructureCache(branch); + if (ancestors) + flushParentStructureCache(branch); + if (descendants) + flushChildrenStructureCache(branch); + } + + protected void flushStructureCache(IBranchPart branch) { + MindMapUtils.flushCache(branch, CACHE_STRUCTURE_ID); + } + + protected void flushParentStructureCache(IBranchPart branch) { + IBranchPart parent = branch.getParentBranch(); + if (parent == null) + return; + String policyId = parent.getBranchPolicyId(); + if (getPolicyId().equals(policyId)) { + parent.getBranchPolicy().flushStructureCache(parent, true, false); + } + } + + protected void flushChildrenStructureCache(IBranchPart branch) { + for (IBranchPart child : branch.getSubBranches()) { + flushChildStructureCache(child); + } + for (IBranchPart child : branch.getCalloutBranches()) { + flushChildStructureCache(child); + } + for (IBranchPart child : branch.getSummaryBranches()) { + flushChildStructureCache(child); + } + } + + protected void flushChildStructureCache(IBranchPart child) { + String policyId = child.getBranchPolicyId(); + if (getPolicyId().equals(policyId)) { + child.getBranchPolicy().flushStructureCache(child, false, true); + } + } + + public IToolHelper getToolHelper(IBranchPart parent, + Class type) { + return null; + } + + public boolean isPropertyModifiable(IBranchPart branch, String propertyKey) { + return isPropertyModifiable(branch, propertyKey, null); + } + + public boolean isPropertyModifiable(IBranchPart branch, String propertyKey, + String secondaryKey) { + boolean modifiable = internalCheckPropertyModifiability(branch, + propertyKey, secondaryKey); + if (modifiable) { + modifiable = !isUnmodifiableProperty(branch, propertyKey, + secondaryKey); + } + return modifiable; + } + + protected abstract boolean isUnmodifiableProperty(IBranchPart branch, + String propertyKey, String secondaryKey); + + protected boolean internalCheckPropertyModifiability(IBranchPart branch, + String propertyKey, String secondaryKey) { + if (Core.TopicFolded.equals(propertyKey)) + return isBranchFoldable(branch); + if (Core.TopicHyperlink.equals(propertyKey)) + return isHyperlinkModifiable(branch); + return true; + } + + protected boolean isHyperlinkModifiable(IBranchPart branch) { + ITopic t = branch.getTopic(); + String uri = t.getHyperlink(); + if (uri != null) { + return MindMapUI.getProtocolManager().isHyperlinkModifiable(t, uri); + } + return true; + } + + protected boolean isBranchFoldable(IBranchPart branch) { + return !branch.isCentral();// && !branch.getSubBranches().isEmpty(); + } + + protected IStyleSelector createDefaultStyleSelector() { + return DefaultBranchStyleSelector.getDefault(); + } + + public IStructure getStructure(IGraphicalPart part) { + IBranchPart branch = (IBranchPart) part; + String structureId = (String) MindMapUtils.getCache(branch, + CACHE_STRUCTURE_ID); + return getStructureAlgorithmById(part, structureId); + } + + private IStructure getStructureAlgorithmById(IGraphicalPart part, + String structureId) { + if (structureId != null) { + IStructureDescriptor structureDescriptor = manager + .getStructureDescriptor(structureId); + if (structureDescriptor != null) + return structureDescriptor.getAlgorithm(); + IBranchStructure sa = getPredefinedStructure(structureId); + if (sa != null) + return sa; + } + return super.getStructure(part); + } + + public Object getValue(IPart part, String key) { + IBranchPart branch = (IBranchPart) part; + if (CACHE_STRUCTURE_ID.equals(key)) { + return calculateStructureAlgorithmId(branch); + } + return null; + } + + protected String calculateStructureAlgorithmId(IBranchPart branch) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null && parent.getSummaryBranches().contains(branch)) { + return calcSummaryBranchStructureType(branch, parent); + } + + if (isCalculatingOn(branch)) + return getDefaultStructureId(); + + startCalculationOn(branch); + + String structureId = calcAdditionalStructureId(branch, parent); + + endCalculationOn(branch); + + if (structureId != null) + return structureId; + + return getDefaultStructureId(); + } + + protected abstract String calcAdditionalStructureId(IBranchPart branch, + IBranchPart parent); + + private String calcSummaryBranchStructureType(IBranchPart branch, + IBranchPart parent) { + ISummaryPart summary = MindMapUtils.findAttachedSummary(parent, branch); + if (summary != null) { + IStructure sa = parent.getBranchPolicy().getStructure(parent); + if (sa instanceof IBranchStructureExtension) { + int direction = ((IBranchStructureExtension) sa) + .getSummaryDirection(parent, summary); + if (direction == PositionConstants.WEST) + return LEFT_STRUCTURE_ID; + if (direction == PositionConstants.NORTH) + return UP_STRUCTURE_ID; + if (direction == PositionConstants.SOUTH) + return DOWN_STRUCTURE_ID; + } + } + return RIGHT_STRUCTURE_ID; + } + + protected boolean isCalculatingOn(IBranchPart branch) { + return calculationQueue != null && calculationQueue.contains(branch); + } + + protected void startCalculationOn(IBranchPart branch) { + if (calculationQueue == null) + calculationQueue = new HashSet(); + calculationQueue.add(branch); + } + + protected void endCalculationOn(IBranchPart branch) { + if (calculationQueue == null) + return; + calculationQueue.remove(branch); + if (calculationQueue.isEmpty()) + calculationQueue = null; + } + + protected IBranchStructure getPredefinedStructure(String structureId) { + if (LEFT_STRUCTURE_ID.equals(structureId)) { + if (left == null) + left = new LeftStructure(); + return left; + } else if (RIGHT_STRUCTURE_ID.equals(structureId)) { + if (right == null) + right = new RightStructure(); + return right; + } else if (UP_STRUCTURE_ID.equals(structureId)) { + if (up == null) + up = new UpStructure(); + return up; + } else if (DOWN_STRUCTURE_ID.equals(structureId)) { + if (down == null) + down = new DownStructure(); + return down; + } + return null; + } + + protected abstract String getDefaultStructureId(); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchStyleSelector.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchStyleSelector.java index a2ceabb2c..c38fc6cb9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchStyleSelector.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AbstractBranchStyleSelector.java @@ -1,153 +1,153 @@ -package org.xmind.ui.internal.branch; - -import java.util.HashMap; -import java.util.Map; - -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.graphicalpolicy.IStyleValueProvider; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.branch.IBranchStyleSelector; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.MindMapStyleSelectorBase; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; - -public abstract class AbstractBranchStyleSelector - extends MindMapStyleSelectorBase implements IBranchStyleSelector { - - private Map inheritedStyleKeys; - - protected void registerInheritedStyleKey(String key, String layer) { - if (key == null) - return; - if (inheritedStyleKeys == null) - inheritedStyleKeys = new HashMap(); - inheritedStyleKeys.put(key, layer); - } - - @Override - public String getAutoValue(IGraphicalPart part, String key, - IStyleValueProvider defaultValueProvider) { - String familyName = getFamilyName(part); - if ((Styles.LineColor.equals(key) || Styles.LineWidth.equals(key)) - && (Styles.FAMILY_MAIN_TOPIC.equals(familyName) - || Styles.FAMILY_SUB_TOPIC.equals(familyName) - || Styles.FAMILY_SUMMARY_TOPIC.equals(familyName)) - && part instanceof IBranchPart) { - - String multiColor = Styles.LineColor.equals(key) - ? StyleUtils.getIndexedBranchLineColor((IBranchPart) part) - : null; - - String[] ancestorUserValueAndBranchType = getAncestorUserValueAndBranchType( - part, key); - String ancestorUserValue = ancestorUserValueAndBranchType[0]; - String ancestorBranchType = ancestorUserValueAndBranchType[1]; - - if (isValidValue(part, key, multiColor) - && MindMapUI.BRANCH_CENTRAL.equals(ancestorBranchType)) - return multiColor; - - if (isValidValue(part, key, ancestorUserValue)) - return ancestorUserValue; - if (isValidValue(part, key, multiColor)) - return multiColor; - - } - - return super.getAutoValue(part, key, defaultValueProvider); - } - - private String[] getAncestorUserValueAndBranchType(IGraphicalPart part, - String key) { - String[] ancestorUserValueAndBranchType = new String[2]; - - if (!(part instanceof IBranchPart)) - return ancestorUserValueAndBranchType; - - IBranchPart parentBranchPart = ((IBranchPart) part).getParentBranch(); - if (parentBranchPart == null) - return ancestorUserValueAndBranchType; - - IStyleSelector styleSelector = parentBranchPart.getBranchPolicy() - .getStyleSelector(parentBranchPart); - if (styleSelector == null) - return ancestorUserValueAndBranchType; - - String parentUserValue = styleSelector.getUserValue(parentBranchPart, - key); - if (isValidValue(parentBranchPart, key, parentUserValue)) { - ancestorUserValueAndBranchType[0] = parentUserValue; - ancestorUserValueAndBranchType[1] = parentBranchPart - .getBranchType(); - return ancestorUserValueAndBranchType; - } - - return getAncestorUserValueAndBranchType(parentBranchPart, key); - } - - protected String getThemeStyleValue(IGraphicalPart part, String familyName, - String key) { - if ((Styles.LineColor.equals(key) || Styles.LineWidth.equals(key)) - && (Styles.FAMILY_MAIN_TOPIC.equals(familyName) - || Styles.FAMILY_SUB_TOPIC.equals(familyName) - || Styles.FAMILY_SUMMARY_TOPIC.equals(familyName)) - && part instanceof IBranchPart) { - String value = super.getThemeStyleValue(part, familyName, key); - if (isValidValue(part, key, value)) - return value; - } - if (inheritedStyleKeys != null && inheritedStyleKeys.containsKey(key)) { - if (part instanceof IBranchPart) { - String value = ParentValueProvider - .getValueProvider((IBranchPart) part) - .getParentValue(key); - if (value != null) - return value; - } - } - return super.getThemeStyleValue(part, familyName, key); - } - - protected String getLayeredProperty(IGraphicalPart part, String layerName, - String familyName, String key) { - if (part instanceof IBranchPart && inheritedStyleKeys != null - && layerName.equals(inheritedStyleKeys.get(key))) { - String value = getLayeredProperty(part, - Styles.LAYER_BEFORE_PARENT_VALUE, familyName, key); - if (isValidValue(part, key, value)) { - return getCheckedValue(value); - } - value = ParentValueProvider.getValueProvider((IBranchPart) part) - .getParentValue(key); - if (isValidValue(part, key, value)) - return getCheckedValue(value); - } - return null; - } - - @Override - public String getFamilyName(IGraphicalPart part) { - if (part instanceof IBranchPart) { - IBranchPart branch = (IBranchPart) part; - String branchType = branch.getBranchType(); - if (MindMapUI.BRANCH_CENTRAL.equals(branchType)) - return Styles.FAMILY_CENTRAL_TOPIC; - if (MindMapUI.BRANCH_MAIN.equals(branchType)) - return Styles.FAMILY_MAIN_TOPIC; - if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) - return Styles.FAMILY_CALLOUT_TOPIC; - if (MindMapUI.BRANCH_FLOATING.equals(branchType)) - return Styles.FAMILY_FLOATING_TOPIC; - if (MindMapUI.BRANCH_SUMMARY.equals(branchType)) - return Styles.FAMILY_SUMMARY_TOPIC; - } - return Styles.FAMILY_SUB_TOPIC; - } - - public void flushStyleCaches(IBranchPart branch) { - ParentValueProvider.flush(branch); - } - -} +package org.xmind.ui.internal.branch; + +import java.util.HashMap; +import java.util.Map; + +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.graphicalpolicy.IStyleValueProvider; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.branch.IBranchStyleSelector; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.MindMapStyleSelectorBase; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; + +public abstract class AbstractBranchStyleSelector + extends MindMapStyleSelectorBase implements IBranchStyleSelector { + + private Map inheritedStyleKeys; + + protected void registerInheritedStyleKey(String key, String layer) { + if (key == null) + return; + if (inheritedStyleKeys == null) + inheritedStyleKeys = new HashMap(); + inheritedStyleKeys.put(key, layer); + } + + @Override + public String getAutoValue(IGraphicalPart part, String key, + IStyleValueProvider defaultValueProvider) { + String familyName = getFamilyName(part); + if ((Styles.LineColor.equals(key) || Styles.LineWidth.equals(key)) + && (Styles.FAMILY_MAIN_TOPIC.equals(familyName) + || Styles.FAMILY_SUB_TOPIC.equals(familyName) + || Styles.FAMILY_SUMMARY_TOPIC.equals(familyName)) + && part instanceof IBranchPart) { + + String multiColor = Styles.LineColor.equals(key) + ? StyleUtils.getIndexedBranchLineColor((IBranchPart) part) + : null; + + String[] ancestorUserValueAndBranchType = getAncestorUserValueAndBranchType( + part, key); + String ancestorUserValue = ancestorUserValueAndBranchType[0]; + String ancestorBranchType = ancestorUserValueAndBranchType[1]; + + if (isValidValue(part, key, multiColor) + && MindMapUI.BRANCH_CENTRAL.equals(ancestorBranchType)) + return multiColor; + + if (isValidValue(part, key, ancestorUserValue)) + return ancestorUserValue; + if (isValidValue(part, key, multiColor)) + return multiColor; + + } + + return super.getAutoValue(part, key, defaultValueProvider); + } + + private String[] getAncestorUserValueAndBranchType(IGraphicalPart part, + String key) { + String[] ancestorUserValueAndBranchType = new String[2]; + + if (!(part instanceof IBranchPart)) + return ancestorUserValueAndBranchType; + + IBranchPart parentBranchPart = ((IBranchPart) part).getParentBranch(); + if (parentBranchPart == null) + return ancestorUserValueAndBranchType; + + IStyleSelector styleSelector = parentBranchPart.getBranchPolicy() + .getStyleSelector(parentBranchPart); + if (styleSelector == null) + return ancestorUserValueAndBranchType; + + String parentUserValue = styleSelector.getUserValue(parentBranchPart, + key); + if (isValidValue(parentBranchPart, key, parentUserValue)) { + ancestorUserValueAndBranchType[0] = parentUserValue; + ancestorUserValueAndBranchType[1] = parentBranchPart + .getBranchType(); + return ancestorUserValueAndBranchType; + } + + return getAncestorUserValueAndBranchType(parentBranchPart, key); + } + + protected String getThemeStyleValue(IGraphicalPart part, String familyName, + String key) { + if ((Styles.LineColor.equals(key) || Styles.LineWidth.equals(key)) + && (Styles.FAMILY_MAIN_TOPIC.equals(familyName) + || Styles.FAMILY_SUB_TOPIC.equals(familyName) + || Styles.FAMILY_SUMMARY_TOPIC.equals(familyName)) + && part instanceof IBranchPart) { + String value = super.getThemeStyleValue(part, familyName, key); + if (isValidValue(part, key, value)) + return value; + } + if (inheritedStyleKeys != null && inheritedStyleKeys.containsKey(key)) { + if (part instanceof IBranchPart) { + String value = ParentValueProvider + .getValueProvider((IBranchPart) part) + .getParentValue(key); + if (value != null) + return value; + } + } + return super.getThemeStyleValue(part, familyName, key); + } + + protected String getLayeredProperty(IGraphicalPart part, String layerName, + String familyName, String key) { + if (part instanceof IBranchPart && inheritedStyleKeys != null + && layerName.equals(inheritedStyleKeys.get(key))) { + String value = getLayeredProperty(part, + Styles.LAYER_BEFORE_PARENT_VALUE, familyName, key); + if (isValidValue(part, key, value)) { + return getCheckedValue(value); + } + value = ParentValueProvider.getValueProvider((IBranchPart) part) + .getParentValue(key); + if (isValidValue(part, key, value)) + return getCheckedValue(value); + } + return null; + } + + @Override + public String getFamilyName(IGraphicalPart part) { + if (part instanceof IBranchPart) { + IBranchPart branch = (IBranchPart) part; + String branchType = branch.getBranchType(); + if (MindMapUI.BRANCH_CENTRAL.equals(branchType)) + return Styles.FAMILY_CENTRAL_TOPIC; + if (MindMapUI.BRANCH_MAIN.equals(branchType)) + return Styles.FAMILY_MAIN_TOPIC; + if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) + return Styles.FAMILY_CALLOUT_TOPIC; + if (MindMapUI.BRANCH_FLOATING.equals(branchType)) + return Styles.FAMILY_FLOATING_TOPIC; + if (MindMapUI.BRANCH_SUMMARY.equals(branchType)) + return Styles.FAMILY_SUMMARY_TOPIC; + } + return Styles.FAMILY_SUB_TOPIC; + } + + public void flushStyleCaches(IBranchPart branch) { + ParentValueProvider.flush(branch); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AntiClockwiseRadialStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AntiClockwiseRadialStructure.java index da145c948..604a75105 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AntiClockwiseRadialStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/AntiClockwiseRadialStructure.java @@ -1,425 +1,425 @@ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.tools.ParentSearchKey; -import org.xmind.ui.util.MindMapUtils; - -public class AntiClockwiseRadialStructure extends BaseRadialStructure { - - @Override - public boolean isChildLeft(IBranchPart branch, IBranchPart child) { - if (branch.isCentral()) { - Point pos = (Point) MindMapUtils.getCache(child, - IBranchPart.CACHE_PREF_POSITION); - if (pos != null) { - return RadialUtils.isLeft(0, pos.x); - } - } - if (calculatingBranches.contains(branch)) { - // avoid recursively calling - return false; - } - calculatingBranches.add(branch); - boolean left; - int index = branch.getSubBranches().indexOf(child); - if (index >= 0) { - left = !(index >= getRadialData(branch).getNumRight()); - } else if (branch.getSummaryBranches().contains(child)) { - left = !(isSummaryChildLeft(branch, child)); - } else if (branch.getCalloutBranches().contains(child)) { - left = isChildLeft(branch.getParentBranch(), branch); - } else { - left = RadialUtils.isLeft(getReference(branch).x, - getReference(child).x); - } - calculatingBranches.remove(branch); - return left; - } - - @Override - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - - int[] childrenSpacings = cache.getChildrenSpacings(); - int num = subBranches.size(); - boolean right = false; - RadiationInsertion insertion = getCurrentInsertion(branch); - int insHeight = insertion == null ? 0 : insertion.getSize().height; - - int y = -cache.getRightSumSpacing() / 2; - if (insertion != null && !insertion.right) { - y -= insHeight / 2; - } - - Point ref = info.getReference(); // the Center Topic's location - - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = cache.getLeftSumSpacing() / 2; - if (insertion != null) - if (insertion.right) { - y += insHeight / 2; - } - right = true; - } - - if (insertion != null && i == insertion.getIndex()) { - if (i != numRight || insertion.right) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - if (insertion.right) - y -= insHeight; - else - y += insHeight; - } - } - - IBranchPart subBranch = subBranches.get(i); // to obtain the i st subTopic's bracnch. - Rectangle r; - Dimension offset = getOffset(subBranch); - - IFigure subFigure = subBranch.getFigure(); // the SubTopic's figure - if (offset != null && subFigure instanceof IReferencedFigure) { - Point subRef = ref.getTranslated(offset); - r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); - - } else { - int x = cache.getX(y, right); - Point subRef = ref.getTranslated(x, y); - r = RadialUtils.getPrefBounds(subBranch, subRef, right); - - } - info.put(subFigure, r); - - if (i < numRight) - y += childrenSpacings[i]; - else - y -= childrenSpacings[i]; - - if (insertion != null) { - if ((i == numRight - 1 && insertion.getIndex() == numRight && !insertion.right) - || i == num) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - - y += insHeight; - } - } - } - - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return withDisabled ? 0 : -1; - - if (branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - Point childRef = key.getFigure().getReference(); - Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); - - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - - int[] childrenSpacings = cache.getChildrenSpacings(); - - int num = subBranches.size(); - boolean right = true; - - Dimension insSize = calcInsSize(branch, key); - int insHeight = insSize.height; - boolean insRight = calcInsSide(branch, ref, key); - - int startY = ref.y; - int y = startY - cache.getRightSumSpacing() / 2; - if (!insRight) { - y -= insHeight / 2; - } - - int ret = 0; - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = startY + cache.getLeftSumSpacing() / 2; - if (insRight) { - y += insHeight / 2; - } - //ret = num - 1; - right = false; - } - - IBranchPart subbranch = subBranches.get(i); - IFigure subFigure = subbranch.getFigure(); - Insets refIns = RadialUtils.getRefInsets(subFigure, right); - int hint; - if (i < numRight) { - hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; - } else { - hint = y + refIns.top - (refIns.getHeight() + insHeight) / 2; - } - if (i < numRight) { - if (!insRight && childRef.y <= hint) - return ret; - if (withDisabled || subFigure.isEnabled()) - ret++; - if (i == numRight - 1 && childRef.x < ref.x - && childRef.y >= hint) - return ret; - } else { - if (insRight && childRef.y > hint)//childRef.y >= hint) - return ret; - if (withDisabled || subFigure.isEnabled()) - ret++; -// if (i == numRight && childRef.x > ref.x && childRef.y >= hint) -// return ret; - } - if (i < numRight) - y += childrenSpacings[i]; - else - y -= childrenSpacings[i]; - } - return withDisabled ? num : -1; - } - - public IPart calcChildNavigation(IBranchPart branch, // centre Topic - IBranchPart sourceChild, String navReqType, boolean sequential) { - int numRight = getRadialData(branch).getNumRight(); - int numLeft = getRadialData(branch).getNumLeft(); - int index = sourceChild.getBranchIndex(); - int num = branch.getSubBranches().size(); - - if (GEF.REQ_NAV_UP.equals(navReqType)) { //UP - if (index == 0) - return getSubTopicPart(branch, num - 1); - else if (index == numRight - 1) - return getSubTopicPart(branch, index - 1); - else if (index == numRight) - return getSubTopicPart(branch, index + 1); - else if (index > numRight) { - if (index == num - 1) - return getSubTopicPart(branch, 0); - else - return getSubTopicPart(branch, index + 1); - } else - return getSubTopicPart(branch, index - 1); - - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { // DOWN - if (index == 0) - return getSubTopicPart(branch, index + 1); - else if (index == numRight - 1) - return getSubTopicPart(branch, index + 1); - else if (index == numRight) - return getSubTopicPart(branch, index - 1); - else if (index > numRight) - return getSubTopicPart(branch, index - 1); - else - return getSubTopicPart(branch, index + 1); - - } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - if (index < numRight) - return null; - else - return branch.getTopicPart(); - } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - if (index >= numLeft) - return null; - else - return branch.getTopicPart(); - } - - else if (!sequential) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() >= numFirst) { - return branch.getTopicPart(); - } - } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() < numFirst) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - int num = branch.getSubBranches().size(); - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - if (!branch.getSubBranches().isEmpty()) - return getSubTopicPart(branch, 0); - } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) - return getSubTopicPart(branch, num - 1); - return super.calcNavigation(branch, navReqType); - } - - public Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize(); - } - - public boolean calcInsSide(IBranchPart branch, Point branchRef, - ParentSearchKey key) { - Point childRef = key.getFigure().getReference(); - return childRef.x > branchRef.x; - // if Child on the right of Branch, return true; - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - List enclosingBranches = summary.getEnclosingBranches(); - if (!enclosingBranches.isEmpty()) { - IBranchPart subBranch = enclosingBranches.get(0); - int index = subBranch.getBranchIndex(); - if (index >= 0) { - if (index >= getRadialData(branch).getNumRight()) { - return PositionConstants.EAST; - } - } - } - return PositionConstants.WEST; - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - - Point firstLoc = calcFirstChildPosition(branch, key); - if (subBranches.isEmpty()) - return firstLoc; - - int index = calcInsIndex(branch, key, true); - RadialData cache = getRadialData(branch); - - int subSize = subBranches.size(); - int left = cache.getNumRight(); - int right = subSize - left; - - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - IBranchPart first = subBranches.get(0); - Rectangle fBounds = first.getFigure().getBounds(); - if (index == 0) { - int x = fBounds.right() - inventSize.width / 2; - int y = fBounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == subSize || index == -1) { - if (subSize == 1 && isWithinThreshold(first)) { - if (fBounds.bottom() > 0) { - int x = fBounds.right() - inventSize.width / 2; - int y = fBounds.bottom() - + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } else { - return new Point(firstLoc.x, -firstLoc.y); - } - } - - if (right == 0) - return firstLoc.getNegated(); - - IBranchPart sub = subBranches.get(subSize - 1); - Rectangle bounds = sub.getFigure().getBounds(); - if (right == 1 && bounds.y > 0) - return new Point(-firstLoc.x, firstLoc.y); - - int x = bounds.x + inventSize.width / 2; - int y = bounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == left) { - boolean isLeft = (left == 1 && right == 1) - || isRight(subBranches, child, left); - IBranchPart sub = isLeft ? subBranches.get(index - 1) : subBranches - .get(index); - Rectangle bounds = sub.getFigure().getBounds(); - int x; - if (isLeft) - x = bounds.right() - inventSize.width / 2; - else - x = bounds.x + inventSize.width / 2; - int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - boolean isLeft = index < left; - return calcInventPosition(subBranches.get(isLeft ? index - 1 : index), - subBranches.get(isLeft ? index : index - 1), key, !isLeft); - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - RadialData cache = getRadialData(branch); - - int left = cache.getNumRight(); - - Dimension inventSize = key.getInvent().getSize(); - if (index == oldIndex) { - if (index == left - 1 && key.getCursorPos().x > 0 - && (!subBranches.get(left).getFigure().isEnabled())) - index += 1; - int delta = getTopicSize(subBranches.get(index)).width / 2 - - inventSize.width / 2; - int deltaX = index < left ? delta : -delta; - return getReference(subBranches.get(index)) - .getTranslated(deltaX, 0); - } - return calcInsertPosition(branch, child, key); - } - - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int y = -(getMinorSpacing(branch) * 3 / 4 + 8) * 4; - int x = getRadialData(branch).getX(y, true); - - return getReference(branch).getTranslated(-x, y).getTranslated( - -key.getInvent().getSize().width / 2, 0); - } - -} +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.tools.ParentSearchKey; +import org.xmind.ui.util.MindMapUtils; + +public class AntiClockwiseRadialStructure extends BaseRadialStructure { + + @Override + public boolean isChildLeft(IBranchPart branch, IBranchPart child) { + if (branch.isCentral()) { + Point pos = (Point) MindMapUtils.getCache(child, + IBranchPart.CACHE_PREF_POSITION); + if (pos != null) { + return RadialUtils.isLeft(0, pos.x); + } + } + if (calculatingBranches.contains(branch)) { + // avoid recursively calling + return false; + } + calculatingBranches.add(branch); + boolean left; + int index = branch.getSubBranches().indexOf(child); + if (index >= 0) { + left = !(index >= getRadialData(branch).getNumRight()); + } else if (branch.getSummaryBranches().contains(child)) { + left = !(isSummaryChildLeft(branch, child)); + } else if (branch.getCalloutBranches().contains(child)) { + left = isChildLeft(branch.getParentBranch(), branch); + } else { + left = RadialUtils.isLeft(getReference(branch).x, + getReference(child).x); + } + calculatingBranches.remove(branch); + return left; + } + + @Override + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + + int[] childrenSpacings = cache.getChildrenSpacings(); + int num = subBranches.size(); + boolean right = false; + RadiationInsertion insertion = getCurrentInsertion(branch); + int insHeight = insertion == null ? 0 : insertion.getSize().height; + + int y = -cache.getRightSumSpacing() / 2; + if (insertion != null && !insertion.right) { + y -= insHeight / 2; + } + + Point ref = info.getReference(); // the Center Topic's location + + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = cache.getLeftSumSpacing() / 2; + if (insertion != null) + if (insertion.right) { + y += insHeight / 2; + } + right = true; + } + + if (insertion != null && i == insertion.getIndex()) { + if (i != numRight || insertion.right) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + if (insertion.right) + y -= insHeight; + else + y += insHeight; + } + } + + IBranchPart subBranch = subBranches.get(i); // to obtain the i st subTopic's bracnch. + Rectangle r; + Dimension offset = getOffset(subBranch); + + IFigure subFigure = subBranch.getFigure(); // the SubTopic's figure + if (offset != null && subFigure instanceof IReferencedFigure) { + Point subRef = ref.getTranslated(offset); + r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); + + } else { + int x = cache.getX(y, right); + Point subRef = ref.getTranslated(x, y); + r = RadialUtils.getPrefBounds(subBranch, subRef, right); + + } + info.put(subFigure, r); + + if (i < numRight) + y += childrenSpacings[i]; + else + y -= childrenSpacings[i]; + + if (insertion != null) { + if ((i == numRight - 1 && insertion.getIndex() == numRight && !insertion.right) + || i == num) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + + y += insHeight; + } + } + } + + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return withDisabled ? 0 : -1; + + if (branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + Point childRef = key.getFigure().getReference(); + Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); + + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + + int[] childrenSpacings = cache.getChildrenSpacings(); + + int num = subBranches.size(); + boolean right = true; + + Dimension insSize = calcInsSize(branch, key); + int insHeight = insSize.height; + boolean insRight = calcInsSide(branch, ref, key); + + int startY = ref.y; + int y = startY - cache.getRightSumSpacing() / 2; + if (!insRight) { + y -= insHeight / 2; + } + + int ret = 0; + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = startY + cache.getLeftSumSpacing() / 2; + if (insRight) { + y += insHeight / 2; + } + //ret = num - 1; + right = false; + } + + IBranchPart subbranch = subBranches.get(i); + IFigure subFigure = subbranch.getFigure(); + Insets refIns = RadialUtils.getRefInsets(subFigure, right); + int hint; + if (i < numRight) { + hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; + } else { + hint = y + refIns.top - (refIns.getHeight() + insHeight) / 2; + } + if (i < numRight) { + if (!insRight && childRef.y <= hint) + return ret; + if (withDisabled || subFigure.isEnabled()) + ret++; + if (i == numRight - 1 && childRef.x < ref.x + && childRef.y >= hint) + return ret; + } else { + if (insRight && childRef.y > hint)//childRef.y >= hint) + return ret; + if (withDisabled || subFigure.isEnabled()) + ret++; +// if (i == numRight && childRef.x > ref.x && childRef.y >= hint) +// return ret; + } + if (i < numRight) + y += childrenSpacings[i]; + else + y -= childrenSpacings[i]; + } + return withDisabled ? num : -1; + } + + public IPart calcChildNavigation(IBranchPart branch, // centre Topic + IBranchPart sourceChild, String navReqType, boolean sequential) { + int numRight = getRadialData(branch).getNumRight(); + int numLeft = getRadialData(branch).getNumLeft(); + int index = sourceChild.getBranchIndex(); + int num = branch.getSubBranches().size(); + + if (GEF.REQ_NAV_UP.equals(navReqType)) { //UP + if (index == 0) + return getSubTopicPart(branch, num - 1); + else if (index == numRight - 1) + return getSubTopicPart(branch, index - 1); + else if (index == numRight) + return getSubTopicPart(branch, index + 1); + else if (index > numRight) { + if (index == num - 1) + return getSubTopicPart(branch, 0); + else + return getSubTopicPart(branch, index + 1); + } else + return getSubTopicPart(branch, index - 1); + + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { // DOWN + if (index == 0) + return getSubTopicPart(branch, index + 1); + else if (index == numRight - 1) + return getSubTopicPart(branch, index + 1); + else if (index == numRight) + return getSubTopicPart(branch, index - 1); + else if (index > numRight) + return getSubTopicPart(branch, index - 1); + else + return getSubTopicPart(branch, index + 1); + + } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + if (index < numRight) + return null; + else + return branch.getTopicPart(); + } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + if (index >= numLeft) + return null; + else + return branch.getTopicPart(); + } + + else if (!sequential) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() >= numFirst) { + return branch.getTopicPart(); + } + } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() < numFirst) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + int num = branch.getSubBranches().size(); + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + if (!branch.getSubBranches().isEmpty()) + return getSubTopicPart(branch, 0); + } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) + return getSubTopicPart(branch, num - 1); + return super.calcNavigation(branch, navReqType); + } + + public Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize(); + } + + public boolean calcInsSide(IBranchPart branch, Point branchRef, + ParentSearchKey key) { + Point childRef = key.getFigure().getReference(); + return childRef.x > branchRef.x; + // if Child on the right of Branch, return true; + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + List enclosingBranches = summary.getEnclosingBranches(); + if (!enclosingBranches.isEmpty()) { + IBranchPart subBranch = enclosingBranches.get(0); + int index = subBranch.getBranchIndex(); + if (index >= 0) { + if (index >= getRadialData(branch).getNumRight()) { + return PositionConstants.EAST; + } + } + } + return PositionConstants.WEST; + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + + Point firstLoc = calcFirstChildPosition(branch, key); + if (subBranches.isEmpty()) + return firstLoc; + + int index = calcInsIndex(branch, key, true); + RadialData cache = getRadialData(branch); + + int subSize = subBranches.size(); + int left = cache.getNumRight(); + int right = subSize - left; + + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + IBranchPart first = subBranches.get(0); + Rectangle fBounds = first.getFigure().getBounds(); + if (index == 0) { + int x = fBounds.right() - inventSize.width / 2; + int y = fBounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == subSize || index == -1) { + if (subSize == 1 && isWithinThreshold(first)) { + if (fBounds.bottom() > 0) { + int x = fBounds.right() - inventSize.width / 2; + int y = fBounds.bottom() + + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } else { + return new Point(firstLoc.x, -firstLoc.y); + } + } + + if (right == 0) + return firstLoc.getNegated(); + + IBranchPart sub = subBranches.get(subSize - 1); + Rectangle bounds = sub.getFigure().getBounds(); + if (right == 1 && bounds.y > 0) + return new Point(-firstLoc.x, firstLoc.y); + + int x = bounds.x + inventSize.width / 2; + int y = bounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == left) { + boolean isLeft = (left == 1 && right == 1) + || isRight(subBranches, child, left); + IBranchPart sub = isLeft ? subBranches.get(index - 1) : subBranches + .get(index); + Rectangle bounds = sub.getFigure().getBounds(); + int x; + if (isLeft) + x = bounds.right() - inventSize.width / 2; + else + x = bounds.x + inventSize.width / 2; + int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + boolean isLeft = index < left; + return calcInventPosition(subBranches.get(isLeft ? index - 1 : index), + subBranches.get(isLeft ? index : index - 1), key, !isLeft); + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + RadialData cache = getRadialData(branch); + + int left = cache.getNumRight(); + + Dimension inventSize = key.getInvent().getSize(); + if (index == oldIndex) { + if (index == left - 1 && key.getCursorPos().x > 0 + && (!subBranches.get(left).getFigure().isEnabled())) + index += 1; + int delta = getTopicSize(subBranches.get(index)).width / 2 + - inventSize.width / 2; + int deltaX = index < left ? delta : -delta; + return getReference(subBranches.get(index)) + .getTranslated(deltaX, 0); + } + return calcInsertPosition(branch, child, key); + } + + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int y = -(getMinorSpacing(branch) * 3 / 4 + 8) * 4; + int x = getRadialData(branch).getX(y, true); + + return getReference(branch).getTranslated(-x, y).getTranslated( + -key.getInvent().getSize().width / 2, 0); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BaseRadialStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BaseRadialStructure.java index 45051c0be..f3f052850 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BaseRadialStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BaseRadialStructure.java @@ -1,528 +1,528 @@ -package org.xmind.ui.internal.branch; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.IFreeableBranchStructureExtension; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.ILockableBranchStructureExtension; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.tools.ParentSearchKey; -import org.xmind.ui.util.MindMapUtils; - -public abstract class BaseRadialStructure extends AbstractBranchStructure - implements ILockableBranchStructureExtension, - IFreeableBranchStructureExtension { - - protected static class RadiationInsertion extends Insertion { - - boolean right; - - public RadiationInsertion(IBranchPart parent, int index, Dimension size, - boolean right) { - super(parent, index, size); - this.right = right; - } - - public void pushIn() { - super.pushIn(); - } - - public void pullOut() { - super.pullOut(); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof RadiationInsertion)) - return false; - RadiationInsertion that = (RadiationInsertion) obj; - return super.equals(obj) && this.right == that.right; - } - - } - - public static final String CACHE_NUMBER_RIGHT_BRANCHES = RadialStructure.class - .getName() + ".numberRightBranches"; //$NON-NLS-1$ - public Set calculatingBranches = new HashSet(); - - public BaseRadialStructure() { - super(); - } - - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return super.isValidStructureData(branch, data) - && (data instanceof RadialData); - } - - protected Object createStructureData(IBranchPart branch) { - return new RadialData(branch); - } - - protected RadialData getRadialData(IBranchPart branch) { - return (RadialData) this.getStructureData(branch); - } - - public boolean isChildLeft(IBranchPart branch, IBranchPart child) { - if (branch == null) - return true; - - if (branch.isCentral()) { - Point pos = (Point) MindMapUtils.getCache(child, - IBranchPart.CACHE_PREF_POSITION); - if (pos != null) { - return RadialUtils.isLeft(0, pos.x); - } - } - - if (calculatingBranches.contains(branch)) { - // avoid recursively calling - return false; - } - - calculatingBranches.add(branch); - boolean left; - int index = branch.getSubBranches().indexOf(child); - if (index >= 0) { - left = index >= getRadialData(branch).getNumRight(); - } else if (branch.getSummaryBranches().contains(child)) { - left = isSummaryChildLeft(branch, child); - } else if (branch.getCalloutBranches().contains(child)) { - left = isChildLeft(branch.getParentBranch(), branch); - } else { - left = RadialUtils.isLeft(getReference(branch).x, - getReference(child).x); - } - calculatingBranches.remove(branch); - return left; - } - - public boolean isSummaryChildLeft(IBranchPart branch, IBranchPart child) { - ISummaryPart summary = MindMapUtils.findAttachedSummary(branch, child); - if (summary != null) { - int direction = getSummaryDirection(branch, summary); - return direction == PositionConstants.WEST; - } - return false; - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - List enclosingBranches = summary.getEnclosingBranches(); - if (!enclosingBranches.isEmpty()) { - IBranchPart subBranch = enclosingBranches.get(0); - int index = subBranch.getBranchIndex(); - if (index >= 0) { - if (index >= getRadialData(branch).getNumRight()) { - return PositionConstants.WEST; - } - } - } - return PositionConstants.EAST; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.SOUTH; - } - - public Point getReference(IBranchPart branch) { - ITopicPart topic = branch.getTopicPart(); - if (topic != null) { - return ((IReferencedFigure) topic.getFigure()).getReference(); - } - return ((IReferencedFigure) branch.getFigure()).getReference(); - } - - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - IFigure fig = plusMinus.getFigure(); - Rectangle topicBounds = info.getCheckedClientArea(); - Dimension pmSize = fig.getPreferredSize(); - int pmx = ref.x - pmSize.width / 2; - int pmy = topicBounds.bottom(); - Rectangle pmBounds = new Rectangle(pmx, pmy, pmSize.width, - pmSize.height); - info.put(fig, pmBounds); - } - - protected Dimension getOffset(IBranchPart subBranch) { - Point pos = (Point) MindMapUtils.getCache(subBranch, - IBranchPart.CACHE_PREF_POSITION); - if (pos != null) { - return new Dimension(pos.x, pos.y); - } - return null; - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - if (!branch.getSubBranches().isEmpty()) - return getSubTopicPart(branch, 0); - } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - int numSecond = getRadialData(branch).getNumLeft(); - if (numSecond > 0) { - int numFirst = getRadialData(branch).getNumRight(); - return getSubTopicPart(branch, numFirst); - } - } - return super.calcNavigation(branch, navReqType); - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return isChildLeft(branch, subBranch) ? PositionConstants.EAST - : PositionConstants.WEST; - } - - public int getSourceOrientation(IBranchPart branch) { - return PositionConstants.NONE; - } - - public boolean isChildrenFreeable(IBranchPart branch) { - return branch.isCentral(); - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - Point parentRef = getReference(branch); - Point childRef = key.getFigure().getReference(); - Rectangle childBounds = key.getFigure().getBounds(); - Point childAnc = RadialUtils.isLeft(parentRef.x, childRef.x) - ? childBounds.getRight() : childBounds.getLeft(); - int d = (int) childAnc.getDistance(parentRef); - Dimension ovalSize = getRadialData(branch).getOvalSize(); - int r = Math.max(ovalSize.width, ovalSize.height); - if (d <= r + 50) - return d; - if (d <= r + 300) - return d * d; - return super.calcChildDistance(branch, key); - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - Point ref; - ITopicPart topic = branch.getTopicPart(); - if (topic != null) { - ref = ((IReferencedFigure) topic.getFigure()).getReference(); - } else { - ref = ((IReferencedFigure) branch.getFigure()).getReference(); - } - return new RadiationInsertion(branch, calcInsIndex(branch, key, true), - calcInsSize(branch, key), calcInsSide(branch, ref, key)); - } - - public void lock(IBranchPart branch) { - MindMapUtils.setCache(branch, CACHE_NUMBER_RIGHT_BRANCHES, - getRadialData(branch).getNumRight()); - } - - public void unlock(IBranchPart branch) { - MindMapUtils.flushCache(branch, CACHE_NUMBER_RIGHT_BRANCHES); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return withDisabled ? 0 : -1; - - if (branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - Point childRef = key.getFigure().getReference(); - Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); - - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - int[] childrenSpacings = cache.getChildrenSpacings(); - - int num = subBranches.size(); - boolean right = true; - - Dimension insSize = calcInsSize(branch, key); - int insHeight = insSize.height; - boolean insRight = calcInsSide(branch, ref, key); - - int startY = ref.y; - int y = startY - cache.getRightSumSpacing() / 2; - if (insRight) { - y -= insHeight / 2; - } - - int ret = 0; - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = startY - cache.getLeftSumSpacing() / 2; - if (!insRight) { - y -= insHeight / 2; - } - right = false; - } - - IBranchPart subbranch = subBranches.get(i); - IFigure subFigure = subbranch.getFigure(); - Insets refIns = RadialUtils.getRefInsets(subFigure, right); - int hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; - if (i < numRight) { - if (insRight && childRef.y < hint) - return ret; - if (withDisabled || subFigure.isEnabled()) - ret++; - if (i == numRight - 1 && childRef.x > ref.x - && childRef.y >= hint) - return ret; - } else { - if (!insRight && childRef.y < hint) { - return ret; - } - if (withDisabled || subFigure.isEnabled()) - ret++; - } - y += childrenSpacings[i]; - } - return withDisabled ? num : -1; - } - - private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize(); - } - - private boolean calcInsSide(IBranchPart branch, Point branchRef, - ParentSearchKey key) { - Point childRef = key.getFigure().getReference(); - return childRef.x > branchRef.x; - // if Child on the right of Branch, return true; - } - - protected RadiationInsertion getCurrentInsertion(IBranchPart branch) { - IInsertion insertion = super.getCurrentInsertion(branch); - return insertion instanceof RadiationInsertion - ? (RadiationInsertion) insertion : null; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.SOUTH) - return 1; - if (direction == PositionConstants.NORTH) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - - Point firstLoc = calcFirstChildPosition(branch, key); - if (subBranches.isEmpty()) - return firstLoc; - - int index = calcInsIndex(branch, key, true); - RadialData cache = getRadialData(branch); - - int subSize = subBranches.size(); - int right = cache.getNumRight(); - int left = subSize - right; - - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - IBranchPart first = subBranches.get(0); - Rectangle fBounds = first.getFigure().getBounds(); - if (index == 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == subSize) { - if (subSize == 1 && isWithinThreshold(first)) { - if (fBounds.bottom() > 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.bottom() - + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } else { - return new Point(firstLoc.x, -firstLoc.y); - } - } - - if (left == 0) - return firstLoc.getNegated(); - - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getFigure().getBounds(); - if (left == 1 && bounds.y > 0) - return new Point(-firstLoc.x, firstLoc.y); - - int x = bounds.right() - inventSize.width / 2; - int y = bounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == right) { - boolean isRight = (left == 1 && right == 1) - || isRight(subBranches, child, right); - - IBranchPart sub = isRight ? subBranches.get(index - 1) - : subBranches.get(index); - Rectangle bounds = sub.getFigure().getBounds(); - int x; - if (isRight) - x = bounds.x + inventSize.width / 2; - else - x = bounds.right() - inventSize.width / 2; - int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - boolean isRight = index < right; - - return calcInventPosition(subBranches.get(isRight ? index - 1 : index), - subBranches.get(isRight ? index : index - 1), key, isRight); - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - int right = getRadialData(branch).getNumRight(); - - Dimension inventSize = key.getInvent().getSize(); - if (index == oldIndex) { - if (index == right - 1 && key.getCursorPos().x < 0 - && (!subBranches.get(right).getFigure().isEnabled())) - index += 1; - int delta = getTopicSize(subBranches.get(index)).width / 2 - - inventSize.width / 2; - int deltaX = index < right ? -delta : delta; - return getReference(subBranches.get(index)).getTranslated(deltaX, - 0); - } - return calcInsertPosition(branch, child, key); - } - - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int y = -(getMinorSpacing(branch) * 3 / 4 + 8) * 4; - int x = getRadialData(branch).getX(y, true); - - return getReference(branch).getTranslated(x, y) - .getTranslated(key.getInvent().getSize().width / 2, 0); - } - - protected boolean isWithinThreshold(IBranchPart subBranch) { - // 200 Threshold - return getBranchWeight(subBranch) < (int) (200 * (Math.log(2) + 1)); - } - - protected int getBranchWeight(IBranchPart branch) { - // 10 minorSpacing - if (branch == null) - return 0; - IFigure figure = branch.getFigure(); - if (figure == null) - return 0; - return figure.getPreferredSize().height + (10 * 3 / 4 + 8) * 2; - } - - @Override - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { - Dimension inventSize = key.getInvent().getSize(); - - Rectangle oriBounds = orientation.getFigure().getBounds(); - Rectangle assBounds = assist.getFigure().getBounds(); - - int x; - if (isRightOrUp) - x = (oriBounds.x + assBounds.x) / 2 + inventSize.width / 2; - else - x = (oriBounds.right() + assBounds.right()) / 2 - - inventSize.width / 2; - - int y = (oriBounds.bottom() + assBounds.y) / 2; - - Point loc = new Point(x, y); - - IBranchPart parent = orientation.getParentBranch(); - IFigure figure = parent.getTopicPart().getFigure(); - - Rectangle bounds = figure.getBounds(); - if (isRightOrUp) { - if (bounds.contains(x - inventSize.width / 2, - y - inventSize.height / 2) - || bounds.contains(x - inventSize.width / 2, - y + inventSize.height / 2)) - return loc.getTranslated( - bounds.right() - (loc.x - inventSize.width / 2) - + getMajorSpacing(parent), - 0); - } else { - if (bounds.contains(x + inventSize.width / 2, - y - inventSize.height / 2) - || bounds.contains(x + inventSize.width / 2, - y + inventSize.height / 2)) - return loc.getTranslated((loc.x - inventSize.width / 2) - - bounds.x - getMajorSpacing(parent), 0); - } - - return loc; - } - - protected boolean isRight(List subBranches, IBranchPart child, - int right) { - int rightWeight = 0; - int leftWeight = 0; - for (int i = 0; i < right; i++) - rightWeight += getBranchWeight(subBranches.get(i)); - - for (int i = right; i < subBranches.size(); i++) - leftWeight += getBranchWeight(subBranches.get(i)); - - int insWeight = getBranchWeight(child); - int newRightWeight = rightWeight + insWeight; - - int halfWeight = (rightWeight + leftWeight) / 2; - - return (newRightWeight <= (newRightWeight + leftWeight) / 2) - || (rightWeight <= leftWeight && (newRightWeight - - halfWeight > halfWeight - rightWeight)); - } - +package org.xmind.ui.internal.branch; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.IFreeableBranchStructureExtension; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.ILockableBranchStructureExtension; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.tools.ParentSearchKey; +import org.xmind.ui.util.MindMapUtils; + +public abstract class BaseRadialStructure extends AbstractBranchStructure + implements ILockableBranchStructureExtension, + IFreeableBranchStructureExtension { + + protected static class RadiationInsertion extends Insertion { + + boolean right; + + public RadiationInsertion(IBranchPart parent, int index, Dimension size, + boolean right) { + super(parent, index, size); + this.right = right; + } + + public void pushIn() { + super.pushIn(); + } + + public void pullOut() { + super.pullOut(); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof RadiationInsertion)) + return false; + RadiationInsertion that = (RadiationInsertion) obj; + return super.equals(obj) && this.right == that.right; + } + + } + + public static final String CACHE_NUMBER_RIGHT_BRANCHES = RadialStructure.class + .getName() + ".numberRightBranches"; //$NON-NLS-1$ + public Set calculatingBranches = new HashSet(); + + public BaseRadialStructure() { + super(); + } + + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return super.isValidStructureData(branch, data) + && (data instanceof RadialData); + } + + protected Object createStructureData(IBranchPart branch) { + return new RadialData(branch); + } + + protected RadialData getRadialData(IBranchPart branch) { + return (RadialData) this.getStructureData(branch); + } + + public boolean isChildLeft(IBranchPart branch, IBranchPart child) { + if (branch == null) + return true; + + if (branch.isCentral()) { + Point pos = (Point) MindMapUtils.getCache(child, + IBranchPart.CACHE_PREF_POSITION); + if (pos != null) { + return RadialUtils.isLeft(0, pos.x); + } + } + + if (calculatingBranches.contains(branch)) { + // avoid recursively calling + return false; + } + + calculatingBranches.add(branch); + boolean left; + int index = branch.getSubBranches().indexOf(child); + if (index >= 0) { + left = index >= getRadialData(branch).getNumRight(); + } else if (branch.getSummaryBranches().contains(child)) { + left = isSummaryChildLeft(branch, child); + } else if (branch.getCalloutBranches().contains(child)) { + left = isChildLeft(branch.getParentBranch(), branch); + } else { + left = RadialUtils.isLeft(getReference(branch).x, + getReference(child).x); + } + calculatingBranches.remove(branch); + return left; + } + + public boolean isSummaryChildLeft(IBranchPart branch, IBranchPart child) { + ISummaryPart summary = MindMapUtils.findAttachedSummary(branch, child); + if (summary != null) { + int direction = getSummaryDirection(branch, summary); + return direction == PositionConstants.WEST; + } + return false; + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + List enclosingBranches = summary.getEnclosingBranches(); + if (!enclosingBranches.isEmpty()) { + IBranchPart subBranch = enclosingBranches.get(0); + int index = subBranch.getBranchIndex(); + if (index >= 0) { + if (index >= getRadialData(branch).getNumRight()) { + return PositionConstants.WEST; + } + } + } + return PositionConstants.EAST; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.SOUTH; + } + + public Point getReference(IBranchPart branch) { + ITopicPart topic = branch.getTopicPart(); + if (topic != null) { + return ((IReferencedFigure) topic.getFigure()).getReference(); + } + return ((IReferencedFigure) branch.getFigure()).getReference(); + } + + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + IFigure fig = plusMinus.getFigure(); + Rectangle topicBounds = info.getCheckedClientArea(); + Dimension pmSize = fig.getPreferredSize(); + int pmx = ref.x - pmSize.width / 2; + int pmy = topicBounds.bottom(); + Rectangle pmBounds = new Rectangle(pmx, pmy, pmSize.width, + pmSize.height); + info.put(fig, pmBounds); + } + + protected Dimension getOffset(IBranchPart subBranch) { + Point pos = (Point) MindMapUtils.getCache(subBranch, + IBranchPart.CACHE_PREF_POSITION); + if (pos != null) { + return new Dimension(pos.x, pos.y); + } + return null; + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + if (!branch.getSubBranches().isEmpty()) + return getSubTopicPart(branch, 0); + } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + int numSecond = getRadialData(branch).getNumLeft(); + if (numSecond > 0) { + int numFirst = getRadialData(branch).getNumRight(); + return getSubTopicPart(branch, numFirst); + } + } + return super.calcNavigation(branch, navReqType); + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return isChildLeft(branch, subBranch) ? PositionConstants.EAST + : PositionConstants.WEST; + } + + public int getSourceOrientation(IBranchPart branch) { + return PositionConstants.NONE; + } + + public boolean isChildrenFreeable(IBranchPart branch) { + return branch.isCentral(); + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + Point parentRef = getReference(branch); + Point childRef = key.getFigure().getReference(); + Rectangle childBounds = key.getFigure().getBounds(); + Point childAnc = RadialUtils.isLeft(parentRef.x, childRef.x) + ? childBounds.getRight() : childBounds.getLeft(); + int d = (int) childAnc.getDistance(parentRef); + Dimension ovalSize = getRadialData(branch).getOvalSize(); + int r = Math.max(ovalSize.width, ovalSize.height); + if (d <= r + 50) + return d; + if (d <= r + 300) + return d * d; + return super.calcChildDistance(branch, key); + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + Point ref; + ITopicPart topic = branch.getTopicPart(); + if (topic != null) { + ref = ((IReferencedFigure) topic.getFigure()).getReference(); + } else { + ref = ((IReferencedFigure) branch.getFigure()).getReference(); + } + return new RadiationInsertion(branch, calcInsIndex(branch, key, true), + calcInsSize(branch, key), calcInsSide(branch, ref, key)); + } + + public void lock(IBranchPart branch) { + MindMapUtils.setCache(branch, CACHE_NUMBER_RIGHT_BRANCHES, + getRadialData(branch).getNumRight()); + } + + public void unlock(IBranchPart branch) { + MindMapUtils.flushCache(branch, CACHE_NUMBER_RIGHT_BRANCHES); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return withDisabled ? 0 : -1; + + if (branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + Point childRef = key.getFigure().getReference(); + Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); + + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + int[] childrenSpacings = cache.getChildrenSpacings(); + + int num = subBranches.size(); + boolean right = true; + + Dimension insSize = calcInsSize(branch, key); + int insHeight = insSize.height; + boolean insRight = calcInsSide(branch, ref, key); + + int startY = ref.y; + int y = startY - cache.getRightSumSpacing() / 2; + if (insRight) { + y -= insHeight / 2; + } + + int ret = 0; + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = startY - cache.getLeftSumSpacing() / 2; + if (!insRight) { + y -= insHeight / 2; + } + right = false; + } + + IBranchPart subbranch = subBranches.get(i); + IFigure subFigure = subbranch.getFigure(); + Insets refIns = RadialUtils.getRefInsets(subFigure, right); + int hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; + if (i < numRight) { + if (insRight && childRef.y < hint) + return ret; + if (withDisabled || subFigure.isEnabled()) + ret++; + if (i == numRight - 1 && childRef.x > ref.x + && childRef.y >= hint) + return ret; + } else { + if (!insRight && childRef.y < hint) { + return ret; + } + if (withDisabled || subFigure.isEnabled()) + ret++; + } + y += childrenSpacings[i]; + } + return withDisabled ? num : -1; + } + + private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize(); + } + + private boolean calcInsSide(IBranchPart branch, Point branchRef, + ParentSearchKey key) { + Point childRef = key.getFigure().getReference(); + return childRef.x > branchRef.x; + // if Child on the right of Branch, return true; + } + + protected RadiationInsertion getCurrentInsertion(IBranchPart branch) { + IInsertion insertion = super.getCurrentInsertion(branch); + return insertion instanceof RadiationInsertion + ? (RadiationInsertion) insertion : null; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.SOUTH) + return 1; + if (direction == PositionConstants.NORTH) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + + Point firstLoc = calcFirstChildPosition(branch, key); + if (subBranches.isEmpty()) + return firstLoc; + + int index = calcInsIndex(branch, key, true); + RadialData cache = getRadialData(branch); + + int subSize = subBranches.size(); + int right = cache.getNumRight(); + int left = subSize - right; + + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + IBranchPart first = subBranches.get(0); + Rectangle fBounds = first.getFigure().getBounds(); + if (index == 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == subSize) { + if (subSize == 1 && isWithinThreshold(first)) { + if (fBounds.bottom() > 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.bottom() + + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } else { + return new Point(firstLoc.x, -firstLoc.y); + } + } + + if (left == 0) + return firstLoc.getNegated(); + + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getFigure().getBounds(); + if (left == 1 && bounds.y > 0) + return new Point(-firstLoc.x, firstLoc.y); + + int x = bounds.right() - inventSize.width / 2; + int y = bounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == right) { + boolean isRight = (left == 1 && right == 1) + || isRight(subBranches, child, right); + + IBranchPart sub = isRight ? subBranches.get(index - 1) + : subBranches.get(index); + Rectangle bounds = sub.getFigure().getBounds(); + int x; + if (isRight) + x = bounds.x + inventSize.width / 2; + else + x = bounds.right() - inventSize.width / 2; + int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + boolean isRight = index < right; + + return calcInventPosition(subBranches.get(isRight ? index - 1 : index), + subBranches.get(isRight ? index : index - 1), key, isRight); + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + int right = getRadialData(branch).getNumRight(); + + Dimension inventSize = key.getInvent().getSize(); + if (index == oldIndex) { + if (index == right - 1 && key.getCursorPos().x < 0 + && (!subBranches.get(right).getFigure().isEnabled())) + index += 1; + int delta = getTopicSize(subBranches.get(index)).width / 2 + - inventSize.width / 2; + int deltaX = index < right ? -delta : delta; + return getReference(subBranches.get(index)).getTranslated(deltaX, + 0); + } + return calcInsertPosition(branch, child, key); + } + + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int y = -(getMinorSpacing(branch) * 3 / 4 + 8) * 4; + int x = getRadialData(branch).getX(y, true); + + return getReference(branch).getTranslated(x, y) + .getTranslated(key.getInvent().getSize().width / 2, 0); + } + + protected boolean isWithinThreshold(IBranchPart subBranch) { + // 200 Threshold + return getBranchWeight(subBranch) < (int) (200 * (Math.log(2) + 1)); + } + + protected int getBranchWeight(IBranchPart branch) { + // 10 minorSpacing + if (branch == null) + return 0; + IFigure figure = branch.getFigure(); + if (figure == null) + return 0; + return figure.getPreferredSize().height + (10 * 3 / 4 + 8) * 2; + } + + @Override + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { + Dimension inventSize = key.getInvent().getSize(); + + Rectangle oriBounds = orientation.getFigure().getBounds(); + Rectangle assBounds = assist.getFigure().getBounds(); + + int x; + if (isRightOrUp) + x = (oriBounds.x + assBounds.x) / 2 + inventSize.width / 2; + else + x = (oriBounds.right() + assBounds.right()) / 2 + - inventSize.width / 2; + + int y = (oriBounds.bottom() + assBounds.y) / 2; + + Point loc = new Point(x, y); + + IBranchPart parent = orientation.getParentBranch(); + IFigure figure = parent.getTopicPart().getFigure(); + + Rectangle bounds = figure.getBounds(); + if (isRightOrUp) { + if (bounds.contains(x - inventSize.width / 2, + y - inventSize.height / 2) + || bounds.contains(x - inventSize.width / 2, + y + inventSize.height / 2)) + return loc.getTranslated( + bounds.right() - (loc.x - inventSize.width / 2) + + getMajorSpacing(parent), + 0); + } else { + if (bounds.contains(x + inventSize.width / 2, + y - inventSize.height / 2) + || bounds.contains(x + inventSize.width / 2, + y + inventSize.height / 2)) + return loc.getTranslated((loc.x - inventSize.width / 2) + - bounds.x - getMajorSpacing(parent), 0); + } + + return loc; + } + + protected boolean isRight(List subBranches, IBranchPart child, + int right) { + int rightWeight = 0; + int leftWeight = 0; + for (int i = 0; i < right; i++) + rightWeight += getBranchWeight(subBranches.get(i)); + + for (int i = right; i < subBranches.size(); i++) + leftWeight += getBranchWeight(subBranches.get(i)); + + int insWeight = getBranchWeight(child); + int newRightWeight = rightWeight + insWeight; + + int halfWeight = (rightWeight + leftWeight) / 2; + + return (newRightWeight <= (newRightWeight + leftWeight) / 2) + || (rightWeight <= leftWeight && (newRightWeight + - halfWeight > halfWeight - rightWeight)); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BranchPolicyManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BranchPolicyManager.java index 331ed465b..0f887695a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BranchPolicyManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/BranchPolicyManager.java @@ -1,472 +1,472 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.TAG_ENABLEMENT; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.expressions.EvaluationContext; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.Platform; -import org.eclipse.ui.internal.registry.RegistryReader; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.branch.IBranchPolicyCategoryDescriptor; -import org.xmind.ui.branch.IBranchPolicyDescriptor; -import org.xmind.ui.branch.IBranchPolicyManager; -import org.xmind.ui.branch.IBranchPropertyTester; -import org.xmind.ui.branch.IBranchStyleValueProvider; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -/** - * This class is not intended to be instantiate by clients. Call - * {@link org.xmind.ui.mindmap.MindMapUI#getBranchPolicyManager()} to obtain an - * instance of this class. - * - * @author MANGOSOFT - */ -public class BranchPolicyManager extends RegistryReader implements - IBranchPolicyManager { - - private static final String V_CALLOUT_BRANCHES = "calloutBranches"; //$NON-NLS-1$ - - private static final String DEFAULT_BRANCH_POLICY_ID = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - - private static final String V_PARENT_BRANCH = "parentBranch"; //$NON-NLS-1$ - - private static final String V_SUB_BRANCHES = "subBranches"; //$NON-NLS-1$ - - private static final String V_SUMMARY_BRANCHES = "summaryBranches"; //$NON-NLS-1$ - - private static final String V_BOUNDARIES = "boundaries"; //$NON-NLS-1$ - - private static final String V_SUMMARIES = "summaries"; //$NON-NLS-1$ - - private static final String V_TOPIC = "topic"; //$NON-NLS-1$ - - static IEvaluationContext createBranchEvaluationContext(IBranchPart branch) { - EvaluationContext context = new EvaluationContext(null, branch); - IBranchPart parentBranch = branch.getParentBranch(); - context.addVariable(V_PARENT_BRANCH, - parentBranch == null ? IEvaluationContext.UNDEFINED_VARIABLE - : parentBranch); - context.addVariable(V_SUB_BRANCHES, branch.getSubBranches()); - context.addVariable(V_CALLOUT_BRANCHES, branch.getCalloutBranches()); - context.addVariable(V_SUMMARY_BRANCHES, branch.getSummaryBranches()); - context.addVariable(V_BOUNDARIES, branch.getBoundaries()); - context.addVariable(V_SUMMARIES, branch.getSummaries()); - context.addVariable(V_TOPIC, branch.getTopic()); - return context; - } - - private List policyList = null; - - private Map policyMap = null; - - private Map structureMap = null; - - private Map testerMap = null; - - private Map valueProviderMap = null; - - private IBranchPolicy defaultBranchPolicy = null; - - private List categoryList = null; - - private Map categoryMap = null; - - /** - * This class is not intended to be instantiate by clients. - */ - public BranchPolicyManager() { - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IBranchPolicyRegistry#getDescriptors() - */ - public List getBranchPolicyDescriptors() { - ensureLoaded(); - return policyList; - } - - public List getBranchPolicyCategoryDescriptors() { - ensureLoaded(); - return categoryList; - } - - private Map getPolicyMap() { - ensureLoaded(); - return policyMap; - } - - private Map getStructureMap() { - ensureLoaded(); - return structureMap; - } - - private Map getCategoryMap() { - ensureLoaded(); - return categoryMap; - } - - public IStructureDescriptor getStructureDescriptor(String id) { - if (id != null) { - StructureDescriptor structure = getStructureMap().get(id); - if (structure != null) - return structure; - } - return DefaultStructureDescriptor.getInstance(); - } - - public IBranchPropertyTester getPropertyTester(String id) { - ensureLoaded(); - return testerMap.get(id); - } - - public IBranchStyleValueProvider getValueProvider(String id) { - ensureLoaded(); - return valueProviderMap.get(id); - } - - private BranchPolicy getPolicy(String id) { - return getPolicyMap().get(id); - } - - public IBranchPolicyCategoryDescriptor getBranchPolicyCategoryDescriptor( - String categoryId) { - if (categoryId != null) { - return getCategoryMap().get(categoryId); - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.IBranchPolicyRegistry#getDescriptor(java - * .lang.String) - */ - public IBranchPolicyDescriptor getBranchPolicyDescriptor(String id) { - return getPolicy(id); - } - - public IBranchPolicy getBranchPolicy(String id) { - BranchPolicy policy = getPolicy(id); - if (policy == null) { - policy = getPolicy(DEFAULT_BRANCH_POLICY_ID); - if (policy == null) - return getDefaultBranchPolicy(); - } - return policy; - } - - public IBranchPolicy getDefaultBranchPolicy() { - if (defaultBranchPolicy == null) { - defaultBranchPolicy = new DefaultBranchPolicy(this); - } - return defaultBranchPolicy; - } - - public String calculateBranchPolicyId(IBranchPart branch, - String prefferedPolicyId) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - String parentId = parent.getBranchPolicyId(); - BranchPolicy parentPolicy = getPolicy(parentId); - if (parentPolicy != null - && parentPolicy - .canOverride(createBranchEvaluationContext(branch))) - return parentId; - } - - if (prefferedPolicyId != null) { - BranchPolicy policy = getPolicy(prefferedPolicyId); - if (policy != null && policy.isApplicableTo(branch)) - return prefferedPolicyId; - } - if (parent != null && parent.getSubBranches().contains(branch)) - return parent.getBranchPolicyId(); - if (parent != null && parent.getCalloutBranches().contains(branch)) - return parent.getBranchPolicyId(); - return DEFAULT_BRANCH_POLICY_ID; - } - - public List getApplicableBranchPolicyDescriptors( - IBranchPart branch) { - if (branch == null) - return Collections.emptyList(); - ArrayList list = new ArrayList( - getBranchPolicyDescriptors()); - IEvaluationContext context = createBranchEvaluationContext(branch); - for (Iterator it = list.iterator(); it - .hasNext();) { - if (!((BranchPolicy) it.next()).isApplicableTo(context)) { - it.remove(); - } - } - return list; - } - - private void ensureLoaded() { - if (policyMap == null || policyList == null || structureMap == null - || testerMap == null || valueProviderMap == null - || categoryList == null || categoryMap == null) - lazyLoad(); - if (policyList == null) - policyList = Collections.emptyList(); - if (policyMap == null) - policyMap = Collections.emptyMap(); - if (structureMap == null) - structureMap = Collections.emptyMap(); - if (testerMap == null) - testerMap = Collections.emptyMap(); - if (valueProviderMap == null) - valueProviderMap = Collections.emptyMap(); - if (categoryList == null) - categoryList = Collections.emptyList(); - if (categoryMap == null) - categoryMap = Collections.emptyMap(); - } - - private void lazyLoad() { - if (Platform.isRunning()) { - readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, - RegistryConstants.EXT_BRANCH_POLICIES); - } - } - - protected boolean readElement(IConfigurationElement element) { - String name = element.getName(); - if (RegistryConstants.TAG_BRANCH_POLICY.equals(name)) { - readBranchPolicy(element); - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_STRUCTURE.equals(name)) { - readStructureAlgorithm(element); - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_PROPERTY_TESTER.equals(name)) { - readPropertyTester(element); - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_STYLE_VALUE_PROVIDER.equals(name)) { - readStyleValueProvider(element); - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_ADDITIONAL_STRUCTURES.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_ADDITIONAL_STRUCTURE.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_BRANCH_HOOK.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_STYLE_SELECTOR.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_OVERRIDED_STYLE.equals(name)) { - readElementChildren(element); - return true; -// } else if (RegistryConstants.TAG_INHERITED_STYLE.equals(name)) { -// readElementChildren(element); -// return true; - } else if (RegistryConstants.TAG_UNMODIFIABLE_PROPERTIES.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_UNMODIFIABLE_PROPERTY.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_LAYER.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_STRUCTURE_CACHES.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_STRUCTURE_CACHE.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_OVERRIDE.equals(name)) { - readElementChildren(element); - return true; - } else if (RegistryConstants.TAG_ADVISOR.equals(name)) { - readElementChildren(element); - return true; - } else if (TAG_ENABLEMENT.equals(name)) { - return true; - } else if (RegistryConstants.TAG_BRANCH_POLICY_CATEGORY.equals(name)) { - readBranchPolicyCategory(element); - readElementChildren(element); - return true; - } - return false; - } - - private void readBranchPolicy(IConfigurationElement element) { - try { - BranchPolicy descriptor = new BranchPolicy(this, element); - registerBranchPolicy(descriptor); - } catch (CoreException e) { - Logger.log(e, "Failed to load branch policy: " //$NON-NLS-1$ - + element.toString()); - } - } - - private void readStructureAlgorithm(IConfigurationElement element) { - try { - StructureDescriptor descriptor = new StructureDescriptor(element); - registryStructureAlgorithm(descriptor); - } catch (CoreException e) { - Logger.log(e, "Failed to load structure algorithm: " //$NON-NLS-1$ - + element.toString()); - } - } - - private void readPropertyTester(IConfigurationElement element) { - try { - BranchPropertyTesterProxy proxy = new BranchPropertyTesterProxy( - element); - registerPropertyTester(proxy); - } catch (CoreException e) { - Logger.log(e, "Failed to load branch property tester: " //$NON-NLS-1$ - + element.toString()); - } - } - - private void readStyleValueProvider(IConfigurationElement element) { - try { - ContributedStyleValueProvider valueProvider = new ContributedStyleValueProvider( - element); - registerValueProvider(valueProvider); - } catch (CoreException e) { - Logger.log(e, "Failed to load style value provider: " //$NON-NLS-1$ - + element.toString()); - } - } - - private void readBranchPolicyCategory(IConfigurationElement element) { - try { - BranchPolicyCategoryDescriptor descriptor = new BranchPolicyCategoryDescriptor( - element); - registerBranchPolicyCategory(descriptor); - } catch (CoreException e) { - Logger.log(e, "Failed to load branch policy category: " //$NON-NLS-1$ - + element.toString()); - } - } - - private void registerBranchPolicy(BranchPolicy descriptor) { - if (policyList == null) - policyList = new ArrayList(); - policyList.add(descriptor); - if (policyMap == null) - policyMap = new HashMap(); - policyMap.put(descriptor.getId(), descriptor); - } - - private void registryStructureAlgorithm(StructureDescriptor descriptor) { - if (structureMap == null) - structureMap = new HashMap(); - structureMap.put(descriptor.getId(), descriptor); - } - - private void registerPropertyTester(BranchPropertyTesterProxy tester) { - if (testerMap == null) - testerMap = new HashMap(); - testerMap.put(tester.getId(), tester); - } - - private void registerValueProvider( - ContributedStyleValueProvider valueProvider) { - if (valueProviderMap == null) - valueProviderMap = new HashMap(); - valueProviderMap.put(valueProvider.getId(), valueProvider); - } - - private void registerBranchPolicyCategory( - BranchPolicyCategoryDescriptor descriptor) { - if (categoryList == null) - categoryList = new ArrayList(); - categoryList.add(descriptor); - if (categoryMap == null) - categoryMap = new HashMap(); - categoryMap.put(descriptor.getId(), descriptor); - } - - /** - * Start the registry reading process using the supplied plugin ID and - * extension point. - * - * @param registry - * the registry to read from - * @param pluginId - * the plugin id of the extenion point - * @param extensionPoint - * the extension point id - */ - public void readRegistry(IExtensionRegistry registry, String pluginId, - String extensionPoint) { - IExtensionPoint point = registry.getExtensionPoint(pluginId, - extensionPoint); - if (point == null) { - return; - } - IExtension[] extensions = point.getExtensions(); - if (extensions.length <= 0) - return; - -// Comparator comparer = new Comparator() { -// public int compare(IExtension arg0, IExtension arg1) { -// String s1 = arg0.getNamespaceIdentifier(); -// String s2 = arg1.getNamespaceIdentifier(); -// return s1.compareToIgnoreCase(s2); -// } -// }; -// IExtension myExtension = null; - int i = 0; -// for (; i < extensions.length; i++) { -// IExtension ext = extensions[i]; -// String contributorName = ext.getNamespaceIdentifier(); -// if (contributorName.startsWith("org.xmind.")) { //$NON-NLS-1$ -// myExtension = ext; -// break; -// } -// } -// if (myExtension != null) { -// extensions[i] = extensions[0]; -// extensions[0] = myExtension; -// Arrays.sort(extensions, 1, extensions.length, comparer); -// } else { -// Arrays.sort(extensions, comparer); -// } - for (i = 0; i < extensions.length; i++) { - readExtension(extensions[i]); - } - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.TAG_ENABLEMENT; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.branch.IBranchPolicyCategoryDescriptor; +import org.xmind.ui.branch.IBranchPolicyDescriptor; +import org.xmind.ui.branch.IBranchPolicyManager; +import org.xmind.ui.branch.IBranchPropertyTester; +import org.xmind.ui.branch.IBranchStyleValueProvider; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +/** + * This class is not intended to be instantiate by clients. Call + * {@link org.xmind.ui.mindmap.MindMapUI#getBranchPolicyManager()} to obtain an + * instance of this class. + * + * @author MANGOSOFT + */ +public class BranchPolicyManager extends RegistryReader implements + IBranchPolicyManager { + + private static final String V_CALLOUT_BRANCHES = "calloutBranches"; //$NON-NLS-1$ + + private static final String DEFAULT_BRANCH_POLICY_ID = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + + private static final String V_PARENT_BRANCH = "parentBranch"; //$NON-NLS-1$ + + private static final String V_SUB_BRANCHES = "subBranches"; //$NON-NLS-1$ + + private static final String V_SUMMARY_BRANCHES = "summaryBranches"; //$NON-NLS-1$ + + private static final String V_BOUNDARIES = "boundaries"; //$NON-NLS-1$ + + private static final String V_SUMMARIES = "summaries"; //$NON-NLS-1$ + + private static final String V_TOPIC = "topic"; //$NON-NLS-1$ + + static IEvaluationContext createBranchEvaluationContext(IBranchPart branch) { + EvaluationContext context = new EvaluationContext(null, branch); + IBranchPart parentBranch = branch.getParentBranch(); + context.addVariable(V_PARENT_BRANCH, + parentBranch == null ? IEvaluationContext.UNDEFINED_VARIABLE + : parentBranch); + context.addVariable(V_SUB_BRANCHES, branch.getSubBranches()); + context.addVariable(V_CALLOUT_BRANCHES, branch.getCalloutBranches()); + context.addVariable(V_SUMMARY_BRANCHES, branch.getSummaryBranches()); + context.addVariable(V_BOUNDARIES, branch.getBoundaries()); + context.addVariable(V_SUMMARIES, branch.getSummaries()); + context.addVariable(V_TOPIC, branch.getTopic()); + return context; + } + + private List policyList = null; + + private Map policyMap = null; + + private Map structureMap = null; + + private Map testerMap = null; + + private Map valueProviderMap = null; + + private IBranchPolicy defaultBranchPolicy = null; + + private List categoryList = null; + + private Map categoryMap = null; + + /** + * This class is not intended to be instantiate by clients. + */ + public BranchPolicyManager() { + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IBranchPolicyRegistry#getDescriptors() + */ + public List getBranchPolicyDescriptors() { + ensureLoaded(); + return policyList; + } + + public List getBranchPolicyCategoryDescriptors() { + ensureLoaded(); + return categoryList; + } + + private Map getPolicyMap() { + ensureLoaded(); + return policyMap; + } + + private Map getStructureMap() { + ensureLoaded(); + return structureMap; + } + + private Map getCategoryMap() { + ensureLoaded(); + return categoryMap; + } + + public IStructureDescriptor getStructureDescriptor(String id) { + if (id != null) { + StructureDescriptor structure = getStructureMap().get(id); + if (structure != null) + return structure; + } + return DefaultStructureDescriptor.getInstance(); + } + + public IBranchPropertyTester getPropertyTester(String id) { + ensureLoaded(); + return testerMap.get(id); + } + + public IBranchStyleValueProvider getValueProvider(String id) { + ensureLoaded(); + return valueProviderMap.get(id); + } + + private BranchPolicy getPolicy(String id) { + return getPolicyMap().get(id); + } + + public IBranchPolicyCategoryDescriptor getBranchPolicyCategoryDescriptor( + String categoryId) { + if (categoryId != null) { + return getCategoryMap().get(categoryId); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.IBranchPolicyRegistry#getDescriptor(java + * .lang.String) + */ + public IBranchPolicyDescriptor getBranchPolicyDescriptor(String id) { + return getPolicy(id); + } + + public IBranchPolicy getBranchPolicy(String id) { + BranchPolicy policy = getPolicy(id); + if (policy == null) { + policy = getPolicy(DEFAULT_BRANCH_POLICY_ID); + if (policy == null) + return getDefaultBranchPolicy(); + } + return policy; + } + + public IBranchPolicy getDefaultBranchPolicy() { + if (defaultBranchPolicy == null) { + defaultBranchPolicy = new DefaultBranchPolicy(this); + } + return defaultBranchPolicy; + } + + public String calculateBranchPolicyId(IBranchPart branch, + String prefferedPolicyId) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + String parentId = parent.getBranchPolicyId(); + BranchPolicy parentPolicy = getPolicy(parentId); + if (parentPolicy != null + && parentPolicy + .canOverride(createBranchEvaluationContext(branch))) + return parentId; + } + + if (prefferedPolicyId != null) { + BranchPolicy policy = getPolicy(prefferedPolicyId); + if (policy != null && policy.isApplicableTo(branch)) + return prefferedPolicyId; + } + if (parent != null && parent.getSubBranches().contains(branch)) + return parent.getBranchPolicyId(); + if (parent != null && parent.getCalloutBranches().contains(branch)) + return parent.getBranchPolicyId(); + return DEFAULT_BRANCH_POLICY_ID; + } + + public List getApplicableBranchPolicyDescriptors( + IBranchPart branch) { + if (branch == null) + return Collections.emptyList(); + ArrayList list = new ArrayList( + getBranchPolicyDescriptors()); + IEvaluationContext context = createBranchEvaluationContext(branch); + for (Iterator it = list.iterator(); it + .hasNext();) { + if (!((BranchPolicy) it.next()).isApplicableTo(context)) { + it.remove(); + } + } + return list; + } + + private void ensureLoaded() { + if (policyMap == null || policyList == null || structureMap == null + || testerMap == null || valueProviderMap == null + || categoryList == null || categoryMap == null) + lazyLoad(); + if (policyList == null) + policyList = Collections.emptyList(); + if (policyMap == null) + policyMap = Collections.emptyMap(); + if (structureMap == null) + structureMap = Collections.emptyMap(); + if (testerMap == null) + testerMap = Collections.emptyMap(); + if (valueProviderMap == null) + valueProviderMap = Collections.emptyMap(); + if (categoryList == null) + categoryList = Collections.emptyList(); + if (categoryMap == null) + categoryMap = Collections.emptyMap(); + } + + private void lazyLoad() { + if (Platform.isRunning()) { + readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID, + RegistryConstants.EXT_BRANCH_POLICIES); + } + } + + protected boolean readElement(IConfigurationElement element) { + String name = element.getName(); + if (RegistryConstants.TAG_BRANCH_POLICY.equals(name)) { + readBranchPolicy(element); + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_STRUCTURE.equals(name)) { + readStructureAlgorithm(element); + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_PROPERTY_TESTER.equals(name)) { + readPropertyTester(element); + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_STYLE_VALUE_PROVIDER.equals(name)) { + readStyleValueProvider(element); + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_ADDITIONAL_STRUCTURES.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_ADDITIONAL_STRUCTURE.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_BRANCH_HOOK.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_STYLE_SELECTOR.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_OVERRIDED_STYLE.equals(name)) { + readElementChildren(element); + return true; +// } else if (RegistryConstants.TAG_INHERITED_STYLE.equals(name)) { +// readElementChildren(element); +// return true; + } else if (RegistryConstants.TAG_UNMODIFIABLE_PROPERTIES.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_UNMODIFIABLE_PROPERTY.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_LAYER.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_STRUCTURE_CACHES.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_STRUCTURE_CACHE.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_OVERRIDE.equals(name)) { + readElementChildren(element); + return true; + } else if (RegistryConstants.TAG_ADVISOR.equals(name)) { + readElementChildren(element); + return true; + } else if (TAG_ENABLEMENT.equals(name)) { + return true; + } else if (RegistryConstants.TAG_BRANCH_POLICY_CATEGORY.equals(name)) { + readBranchPolicyCategory(element); + readElementChildren(element); + return true; + } + return false; + } + + private void readBranchPolicy(IConfigurationElement element) { + try { + BranchPolicy descriptor = new BranchPolicy(this, element); + registerBranchPolicy(descriptor); + } catch (CoreException e) { + Logger.log(e, "Failed to load branch policy: " //$NON-NLS-1$ + + element.toString()); + } + } + + private void readStructureAlgorithm(IConfigurationElement element) { + try { + StructureDescriptor descriptor = new StructureDescriptor(element); + registryStructureAlgorithm(descriptor); + } catch (CoreException e) { + Logger.log(e, "Failed to load structure algorithm: " //$NON-NLS-1$ + + element.toString()); + } + } + + private void readPropertyTester(IConfigurationElement element) { + try { + BranchPropertyTesterProxy proxy = new BranchPropertyTesterProxy( + element); + registerPropertyTester(proxy); + } catch (CoreException e) { + Logger.log(e, "Failed to load branch property tester: " //$NON-NLS-1$ + + element.toString()); + } + } + + private void readStyleValueProvider(IConfigurationElement element) { + try { + ContributedStyleValueProvider valueProvider = new ContributedStyleValueProvider( + element); + registerValueProvider(valueProvider); + } catch (CoreException e) { + Logger.log(e, "Failed to load style value provider: " //$NON-NLS-1$ + + element.toString()); + } + } + + private void readBranchPolicyCategory(IConfigurationElement element) { + try { + BranchPolicyCategoryDescriptor descriptor = new BranchPolicyCategoryDescriptor( + element); + registerBranchPolicyCategory(descriptor); + } catch (CoreException e) { + Logger.log(e, "Failed to load branch policy category: " //$NON-NLS-1$ + + element.toString()); + } + } + + private void registerBranchPolicy(BranchPolicy descriptor) { + if (policyList == null) + policyList = new ArrayList(); + policyList.add(descriptor); + if (policyMap == null) + policyMap = new HashMap(); + policyMap.put(descriptor.getId(), descriptor); + } + + private void registryStructureAlgorithm(StructureDescriptor descriptor) { + if (structureMap == null) + structureMap = new HashMap(); + structureMap.put(descriptor.getId(), descriptor); + } + + private void registerPropertyTester(BranchPropertyTesterProxy tester) { + if (testerMap == null) + testerMap = new HashMap(); + testerMap.put(tester.getId(), tester); + } + + private void registerValueProvider( + ContributedStyleValueProvider valueProvider) { + if (valueProviderMap == null) + valueProviderMap = new HashMap(); + valueProviderMap.put(valueProvider.getId(), valueProvider); + } + + private void registerBranchPolicyCategory( + BranchPolicyCategoryDescriptor descriptor) { + if (categoryList == null) + categoryList = new ArrayList(); + categoryList.add(descriptor); + if (categoryMap == null) + categoryMap = new HashMap(); + categoryMap.put(descriptor.getId(), descriptor); + } + + /** + * Start the registry reading process using the supplied plugin ID and + * extension point. + * + * @param registry + * the registry to read from + * @param pluginId + * the plugin id of the extenion point + * @param extensionPoint + * the extension point id + */ + public void readRegistry(IExtensionRegistry registry, String pluginId, + String extensionPoint) { + IExtensionPoint point = registry.getExtensionPoint(pluginId, + extensionPoint); + if (point == null) { + return; + } + IExtension[] extensions = point.getExtensions(); + if (extensions.length <= 0) + return; + +// Comparator comparer = new Comparator() { +// public int compare(IExtension arg0, IExtension arg1) { +// String s1 = arg0.getNamespaceIdentifier(); +// String s2 = arg1.getNamespaceIdentifier(); +// return s1.compareToIgnoreCase(s2); +// } +// }; +// IExtension myExtension = null; + int i = 0; +// for (; i < extensions.length; i++) { +// IExtension ext = extensions[i]; +// String contributorName = ext.getNamespaceIdentifier(); +// if (contributorName.startsWith("org.xmind.")) { //$NON-NLS-1$ +// myExtension = ext; +// break; +// } +// } +// if (myExtension != null) { +// extensions[i] = extensions[0]; +// extensions[0] = myExtension; +// Arrays.sort(extensions, 1, extensions.length, comparer); +// } else { +// Arrays.sort(extensions, comparer); +// } + for (i = 0; i < extensions.length; i++) { + readExtension(extensions[i]); + } + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ClockwiseRadialStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ClockwiseRadialStructure.java index 0e0f7d049..93fc7ca8e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ClockwiseRadialStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ClockwiseRadialStructure.java @@ -1,238 +1,238 @@ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.tools.ParentSearchKey; - -public class ClockwiseRadialStructure extends BaseRadialStructure { - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - - int[] childrenSpacings = cache.getChildrenSpacings(); - int num = subBranches.size(); - boolean right = true; - RadiationInsertion insertion = getCurrentInsertion(branch); - int insHeight = insertion == null ? 0 : insertion.getSize().height; - - int y = -cache.getRightSumSpacing() / 2; - - if (insertion != null && insertion.right) { - y -= insHeight / 2; - } - - Point ref = info.getReference(); - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = cache.getLeftSumSpacing() / 2; - if (insertion != null) { - if (!insertion.right) { - y += insHeight / 2; - } - } - right = false; - } - - if (insertion != null && i == insertion.getIndex()) { - if (i != numRight || !insertion.right) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - if (insertion.right) - y += insHeight; - else - y -= insHeight; - } - } - - IBranchPart subBranch = subBranches.get(i); - Rectangle r; - Dimension offset = getOffset(subBranch); - IFigure subFigure = subBranch.getFigure(); - if (offset != null && subFigure instanceof IReferencedFigure) { - Point subRef = ref.getTranslated(offset); - r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); - } else { - int x = cache.getX(y, right); - Point subRef = ref.getTranslated(x, y); - r = RadialUtils.getPrefBounds(subBranch, subRef, right); - } - info.put(subFigure, r); - - if (i < numRight) - y += childrenSpacings[i]; - else - y -= childrenSpacings[i]; - - if (insertion != null) { - if ((i == numRight - 1 && insertion.getIndex() == numRight && insertion.right) - || i == num) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - y += insHeight; - } - } - } - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - int numRight = getRadialData(branch).getNumRight(); - int index = sourceChild.getBranchIndex(); - int num = branch.getSubBranches().size(); - - if (GEF.REQ_NAV_UP.equals(navReqType)) { //UP - if (index == 0) { - return getSubTopicPart(branch, num - 1); - } else if (index == numRight - 1) - return getSubTopicPart(branch, index - 1); - else if (index == numRight) - return getSubTopicPart(branch, index + 1); - else if (index > numRight) { - if (index == num - 1) - return getSubTopicPart(branch, 0); - else - return getSubTopicPart(branch, index + 1); - } else - return getSubTopicPart(branch, index - 1); - - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { // DOWN - if (index == 0) - return getSubTopicPart(branch, index + 1); - else if (index == numRight - 1) - return getSubTopicPart(branch, index + 1); - else if (index == numRight) - return getSubTopicPart(branch, index - 1); - else if (index > numRight) - return getSubTopicPart(branch, index - 1); - else - return getSubTopicPart(branch, index + 1); - - } else if (!sequential) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() >= numFirst) { - return branch.getTopicPart(); - } - } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() < numFirst) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - @Override - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return withDisabled ? 0 : -1; - - if (branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - Point childRef = key.getFigure().getReference(); - Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); - - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - int[] childrenSpacings = cache.getChildrenSpacings(); - - int num = subBranches.size(); - - boolean right = true; - - Dimension insSize = calcInsSize(branch, key); - int insHeight = insSize.height; - - int startY = ref.y; - int y = startY - cache.getRightSumSpacing() / 2; - - boolean insRight = calcInsSide(branch, ref, key); - if (insRight) { - if (numRight == 0) - return 0; - y -= insHeight / 2; - } - - int ret = 0; - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = startY + cache.getLeftSumSpacing() / 2; - if (!insRight) { - y += insHeight / 2; - } - right = false; - } - - IBranchPart subbranch = subBranches.get(i); //get the i st SubTopicPart - IFigure subFigure = subbranch.getFigure(); //get the i st SubTopicFigure - Insets refIns = RadialUtils.getRefInsets(subFigure, right); -// int hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; - int hint; - if (i < numRight) { - hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; - } else { - hint = y + refIns.top - (refIns.getHeight() + insHeight) / 2; - } - - if (i < numRight) { - if (insRight && childRef.y < hint) - return ret; - if (withDisabled || subFigure.isEnabled()) - ret++; - if (i == numRight - 1 && childRef.x > ref.x - && childRef.y >= hint) - return ret; - } else { // on the left - if (!insRight && childRef.y > hint) - return ret; - if (withDisabled || subFigure.isEnabled()) - ret++; - } - if (i < numRight) - y += childrenSpacings[i]; - else - y -= childrenSpacings[i]; - - } - return withDisabled ? num : -1; - } - - public Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize(); - } - - public boolean calcInsSide(IBranchPart branch, Point branchRef, - ParentSearchKey key) { - Point childRef = key.getFigure().getReference(); - return childRef.x > branchRef.x; - // if Child on the right of Branch, return true; - } - -} +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.tools.ParentSearchKey; + +public class ClockwiseRadialStructure extends BaseRadialStructure { + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + + int[] childrenSpacings = cache.getChildrenSpacings(); + int num = subBranches.size(); + boolean right = true; + RadiationInsertion insertion = getCurrentInsertion(branch); + int insHeight = insertion == null ? 0 : insertion.getSize().height; + + int y = -cache.getRightSumSpacing() / 2; + + if (insertion != null && insertion.right) { + y -= insHeight / 2; + } + + Point ref = info.getReference(); + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = cache.getLeftSumSpacing() / 2; + if (insertion != null) { + if (!insertion.right) { + y += insHeight / 2; + } + } + right = false; + } + + if (insertion != null && i == insertion.getIndex()) { + if (i != numRight || !insertion.right) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + if (insertion.right) + y += insHeight; + else + y -= insHeight; + } + } + + IBranchPart subBranch = subBranches.get(i); + Rectangle r; + Dimension offset = getOffset(subBranch); + IFigure subFigure = subBranch.getFigure(); + if (offset != null && subFigure instanceof IReferencedFigure) { + Point subRef = ref.getTranslated(offset); + r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); + } else { + int x = cache.getX(y, right); + Point subRef = ref.getTranslated(x, y); + r = RadialUtils.getPrefBounds(subBranch, subRef, right); + } + info.put(subFigure, r); + + if (i < numRight) + y += childrenSpacings[i]; + else + y -= childrenSpacings[i]; + + if (insertion != null) { + if ((i == numRight - 1 && insertion.getIndex() == numRight && insertion.right) + || i == num) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + y += insHeight; + } + } + } + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + int numRight = getRadialData(branch).getNumRight(); + int index = sourceChild.getBranchIndex(); + int num = branch.getSubBranches().size(); + + if (GEF.REQ_NAV_UP.equals(navReqType)) { //UP + if (index == 0) { + return getSubTopicPart(branch, num - 1); + } else if (index == numRight - 1) + return getSubTopicPart(branch, index - 1); + else if (index == numRight) + return getSubTopicPart(branch, index + 1); + else if (index > numRight) { + if (index == num - 1) + return getSubTopicPart(branch, 0); + else + return getSubTopicPart(branch, index + 1); + } else + return getSubTopicPart(branch, index - 1); + + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { // DOWN + if (index == 0) + return getSubTopicPart(branch, index + 1); + else if (index == numRight - 1) + return getSubTopicPart(branch, index + 1); + else if (index == numRight) + return getSubTopicPart(branch, index - 1); + else if (index > numRight) + return getSubTopicPart(branch, index - 1); + else + return getSubTopicPart(branch, index + 1); + + } else if (!sequential) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() >= numFirst) { + return branch.getTopicPart(); + } + } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() < numFirst) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + @Override + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return withDisabled ? 0 : -1; + + if (branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + Point childRef = key.getFigure().getReference(); + Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); + + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + int[] childrenSpacings = cache.getChildrenSpacings(); + + int num = subBranches.size(); + + boolean right = true; + + Dimension insSize = calcInsSize(branch, key); + int insHeight = insSize.height; + + int startY = ref.y; + int y = startY - cache.getRightSumSpacing() / 2; + + boolean insRight = calcInsSide(branch, ref, key); + if (insRight) { + if (numRight == 0) + return 0; + y -= insHeight / 2; + } + + int ret = 0; + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = startY + cache.getLeftSumSpacing() / 2; + if (!insRight) { + y += insHeight / 2; + } + right = false; + } + + IBranchPart subbranch = subBranches.get(i); //get the i st SubTopicPart + IFigure subFigure = subbranch.getFigure(); //get the i st SubTopicFigure + Insets refIns = RadialUtils.getRefInsets(subFigure, right); +// int hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; + int hint; + if (i < numRight) { + hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; + } else { + hint = y + refIns.top - (refIns.getHeight() + insHeight) / 2; + } + + if (i < numRight) { + if (insRight && childRef.y < hint) + return ret; + if (withDisabled || subFigure.isEnabled()) + ret++; + if (i == numRight - 1 && childRef.x > ref.x + && childRef.y >= hint) + return ret; + } else { // on the left + if (!insRight && childRef.y > hint) + return ret; + if (withDisabled || subFigure.isEnabled()) + ret++; + } + if (i < numRight) + y += childrenSpacings[i]; + else + y -= childrenSpacings[i]; + + } + return withDisabled ? num : -1; + } + + public Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize(); + } + + public boolean calcInsSide(IBranchPart branch, Point branchRef, + ParentSearchKey key) { + Point childRef = key.getFigure().getReference(); + return childRef.x > branchRef.x; + // if Child on the right of Branch, return true; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ContributedBranchStyleSelector.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ContributedBranchStyleSelector.java index dc5cd7b82..7b2fccb76 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ContributedBranchStyleSelector.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ContributedBranchStyleSelector.java @@ -1,152 +1,152 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.Logger; - -public class ContributedBranchStyleSelector - extends AbstractBranchStyleSelector { - - private BranchPolicyManager manager; - - private IConfigurationElement element; - - private Map> overridedStyles; - - public ContributedBranchStyleSelector(BranchPolicyManager manager, - IConfigurationElement element) { - this.manager = manager; - this.element = element; - loadInheritedStyles(); - } - - private void loadInheritedStyles() { -// IConfigurationElement[] children = element -// .getChildren(RegistryConstants.TAG_INHERITED_STYLE); -// for (IConfigurationElement child : children) { -// String key = child.getAttribute(ATT_KEY); -// if (key != null) { -// registerInheritedStyleKey(key, -// Styles.LAYER_BEFORE_THEME_VALUE); -// } -// } - registerInheritedStyleKey(Styles.LineColor, - Styles.LAYER_BEFORE_THEME_VALUE); - registerInheritedStyleKey(Styles.LineWidth, - Styles.LAYER_BEFORE_THEME_VALUE); - registerInheritedStyleKey(Styles.LinePattern, - Styles.LAYER_BEFORE_DEFAULT_VALUE); - } - - protected String getLayeredProperty(IGraphicalPart part, String layerName, - String familyName, String key) { - String value = super.getLayeredProperty(part, layerName, familyName, - key); - if (isValidValue(part, key, value)) - return getCheckedValue(value); - - if (part instanceof IBranchPart) { - IBranchPart branch = (IBranchPart) part; - List overrideds = getOverridedStyles(key); - if (overrideds != null && !overrideds.isEmpty()) { - value = getOverridedValue(branch, layerName, key, overrideds); - if (value != null) - return value; - } - } - return value; - } - - public String getOverridedValue(IGraphicalPart part, String key, - String layerName) { - String familyName = getFamilyName(part); - return getLayeredProperty(part, layerName, familyName, key); - } - - private String getOverridedValue(IBranchPart branch, String layerName, - String key, List overridedStyles) { - IEvaluationContext context = null; - for (OverridedStyle overridedStyle : overridedStyles) { - if (overridedStyle.isOnLayer(layerName)) { - if (context == null) - context = BranchPolicyManager - .createBranchEvaluationContext(branch); - if (overridedStyle.isApplicableTo(context)) { - String value = overridedStyle.getValue(branch, layerName); - if (value != null) - return value; - } - } - } - return null; - } - - private List getOverridedStyles(String key) { - ensureLoaded(); - return overridedStyles.get(key); - } - - private void ensureLoaded() { - if (overridedStyles != null) - return; - - lazyLoad(); - if (overridedStyles == null) - overridedStyles = Collections.emptyMap(); - } - - private void lazyLoad() { - IConfigurationElement[] children = element - .getChildren(RegistryConstants.TAG_OVERRIDED_STYLE); - for (IConfigurationElement child : children) { - loadOverridedStyle(child); - } - } - - private void loadOverridedStyle(IConfigurationElement element) { - try { - OverridedStyle overridedStyle = new OverridedStyle(manager, - element); - registerOverridedStyle(overridedStyle); - } catch (CoreException e) { - Logger.log(e, "Failed to load overrided style: " + element); //$NON-NLS-1$ - } - } - - private void registerOverridedStyle(OverridedStyle overridedStyle) { - String key = overridedStyle.getKey(); - if (overridedStyles == null) - overridedStyles = new HashMap>(); - List list = overridedStyles.get(key); - if (list == null) { - list = new ArrayList(); - overridedStyles.put(key, list); - } - list.add(overridedStyle); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.Logger; + +public class ContributedBranchStyleSelector + extends AbstractBranchStyleSelector { + + private BranchPolicyManager manager; + + private IConfigurationElement element; + + private Map> overridedStyles; + + public ContributedBranchStyleSelector(BranchPolicyManager manager, + IConfigurationElement element) { + this.manager = manager; + this.element = element; + loadInheritedStyles(); + } + + private void loadInheritedStyles() { +// IConfigurationElement[] children = element +// .getChildren(RegistryConstants.TAG_INHERITED_STYLE); +// for (IConfigurationElement child : children) { +// String key = child.getAttribute(ATT_KEY); +// if (key != null) { +// registerInheritedStyleKey(key, +// Styles.LAYER_BEFORE_THEME_VALUE); +// } +// } + registerInheritedStyleKey(Styles.LineColor, + Styles.LAYER_BEFORE_THEME_VALUE); + registerInheritedStyleKey(Styles.LineWidth, + Styles.LAYER_BEFORE_THEME_VALUE); + registerInheritedStyleKey(Styles.LinePattern, + Styles.LAYER_BEFORE_DEFAULT_VALUE); + } + + protected String getLayeredProperty(IGraphicalPart part, String layerName, + String familyName, String key) { + String value = super.getLayeredProperty(part, layerName, familyName, + key); + if (isValidValue(part, key, value)) + return getCheckedValue(value); + + if (part instanceof IBranchPart) { + IBranchPart branch = (IBranchPart) part; + List overrideds = getOverridedStyles(key); + if (overrideds != null && !overrideds.isEmpty()) { + value = getOverridedValue(branch, layerName, key, overrideds); + if (value != null) + return value; + } + } + return value; + } + + public String getOverridedValue(IGraphicalPart part, String key, + String layerName) { + String familyName = getFamilyName(part); + return getLayeredProperty(part, layerName, familyName, key); + } + + private String getOverridedValue(IBranchPart branch, String layerName, + String key, List overridedStyles) { + IEvaluationContext context = null; + for (OverridedStyle overridedStyle : overridedStyles) { + if (overridedStyle.isOnLayer(layerName)) { + if (context == null) + context = BranchPolicyManager + .createBranchEvaluationContext(branch); + if (overridedStyle.isApplicableTo(context)) { + String value = overridedStyle.getValue(branch, layerName); + if (value != null) + return value; + } + } + } + return null; + } + + private List getOverridedStyles(String key) { + ensureLoaded(); + return overridedStyles.get(key); + } + + private void ensureLoaded() { + if (overridedStyles != null) + return; + + lazyLoad(); + if (overridedStyles == null) + overridedStyles = Collections.emptyMap(); + } + + private void lazyLoad() { + IConfigurationElement[] children = element + .getChildren(RegistryConstants.TAG_OVERRIDED_STYLE); + for (IConfigurationElement child : children) { + loadOverridedStyle(child); + } + } + + private void loadOverridedStyle(IConfigurationElement element) { + try { + OverridedStyle overridedStyle = new OverridedStyle(manager, + element); + registerOverridedStyle(overridedStyle); + } catch (CoreException e) { + Logger.log(e, "Failed to load overrided style: " + element); //$NON-NLS-1$ + } + } + + private void registerOverridedStyle(OverridedStyle overridedStyle) { + String key = overridedStyle.getKey(); + if (overridedStyles == null) + overridedStyles = new HashMap>(); + List list = overridedStyles.get(key); + if (list == null) { + list = new ArrayList(); + overridedStyles.put(key, list); + } + list.add(overridedStyle); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchPolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchPolicy.java index 82ba4ff2e..939107dfb 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchPolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchPolicy.java @@ -1,104 +1,104 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.branch.IBranchStructure; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class DefaultBranchPolicy extends AbstractBranchPolicy { - - protected static final String RADIAL_STRUCTURE_ID = "org.xmind.ui.branchStructure.radial"; //$NON-NLS-1$ - - protected static IBranchStructure radial = null; - - DefaultBranchPolicy(BranchPolicyManager manager) { - super(manager, "org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ - } - - protected IBranchHook createHook(IBranchPart branch) { - return new MapBranchHook(); - } - - protected IBranchStructure getPredefinedStructure(String structureId) { - if (RADIAL_STRUCTURE_ID.equals(structureId)) { - if (radial == null) - radial = new RadialStructure(); - return radial; - } - return super.getPredefinedStructure(structureId); - } - - protected IStructure createDefaultStructureAlgorithm() { - return getPredefinedStructure(getDefaultStructureId()); - } - - protected boolean isUnmodifiableProperty(IBranchPart branch, - String propertyKey, String secondaryKey) { - return false; - } - - protected String calcAdditionalStructureId(IBranchPart branch, - IBranchPart parent) { - if (branch.isCentral()) { - return RADIAL_STRUCTURE_ID; - } - - String branchType = branch.getBranchType(); - if (MindMapUI.BRANCH_FLOATING.equals(branchType)) { - Point p = (Point) MindMapUtils.getCache(branch, - IBranchPart.CACHE_PREF_POSITION); - if (p != null && p.x < 0) - return LEFT_STRUCTURE_ID; - return getDefaultStructureId(); - } - - if (parent == null) - return getDefaultStructureId(); - - if (getPolicyId().equals(parent.getBranchPolicyId())) { - if (MindMapUI.BRANCH_SUB.equals(branchType)) { - String id = (String) MindMapUtils.getCache(parent, - CACHE_STRUCTURE_ID); - return id == null ? getDefaultStructureId() : id; - } - - if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) { - String id = (String) MindMapUtils.getCache(parent, - CACHE_STRUCTURE_ID); - return id == null ? getDefaultStructureId() : id; - } - - if (MindMapUI.BRANCH_MAIN.equals(branchType)) { - IStructure sa = parent.getBranchPolicy().getStructure(parent); - if (sa instanceof RadialStructure) { - RadialStructure rsa = (RadialStructure) sa; - if (rsa.isChildLeft(parent, branch)) - return LEFT_STRUCTURE_ID; - return getDefaultStructureId(); - } - } - } - return null; - } - - protected String getDefaultStructureId() { - return RIGHT_STRUCTURE_ID; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.branch.IBranchStructure; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class DefaultBranchPolicy extends AbstractBranchPolicy { + + protected static final String RADIAL_STRUCTURE_ID = "org.xmind.ui.branchStructure.radial"; //$NON-NLS-1$ + + protected static IBranchStructure radial = null; + + DefaultBranchPolicy(BranchPolicyManager manager) { + super(manager, "org.xmind.ui.map.unbalanced"); //$NON-NLS-1$ + } + + protected IBranchHook createHook(IBranchPart branch) { + return new MapBranchHook(); + } + + protected IBranchStructure getPredefinedStructure(String structureId) { + if (RADIAL_STRUCTURE_ID.equals(structureId)) { + if (radial == null) + radial = new RadialStructure(); + return radial; + } + return super.getPredefinedStructure(structureId); + } + + protected IStructure createDefaultStructureAlgorithm() { + return getPredefinedStructure(getDefaultStructureId()); + } + + protected boolean isUnmodifiableProperty(IBranchPart branch, + String propertyKey, String secondaryKey) { + return false; + } + + protected String calcAdditionalStructureId(IBranchPart branch, + IBranchPart parent) { + if (branch.isCentral()) { + return RADIAL_STRUCTURE_ID; + } + + String branchType = branch.getBranchType(); + if (MindMapUI.BRANCH_FLOATING.equals(branchType)) { + Point p = (Point) MindMapUtils.getCache(branch, + IBranchPart.CACHE_PREF_POSITION); + if (p != null && p.x < 0) + return LEFT_STRUCTURE_ID; + return getDefaultStructureId(); + } + + if (parent == null) + return getDefaultStructureId(); + + if (getPolicyId().equals(parent.getBranchPolicyId())) { + if (MindMapUI.BRANCH_SUB.equals(branchType)) { + String id = (String) MindMapUtils.getCache(parent, + CACHE_STRUCTURE_ID); + return id == null ? getDefaultStructureId() : id; + } + + if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) { + String id = (String) MindMapUtils.getCache(parent, + CACHE_STRUCTURE_ID); + return id == null ? getDefaultStructureId() : id; + } + + if (MindMapUI.BRANCH_MAIN.equals(branchType)) { + IStructure sa = parent.getBranchPolicy().getStructure(parent); + if (sa instanceof RadialStructure) { + RadialStructure rsa = (RadialStructure) sa; + if (rsa.isChildLeft(parent, branch)) + return LEFT_STRUCTURE_ID; + return getDefaultStructureId(); + } + } + } + return null; + } + + protected String getDefaultStructureId() { + return RIGHT_STRUCTURE_ID; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchStyleSelector.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchStyleSelector.java index 645ae2a6c..4a9c8fff2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchStyleSelector.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DefaultBranchStyleSelector.java @@ -1,37 +1,37 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import org.xmind.ui.style.Styles; - -public class DefaultBranchStyleSelector extends AbstractBranchStyleSelector { - - private static DefaultBranchStyleSelector instance = null; - - protected DefaultBranchStyleSelector() { - registerInheritedStyleKey(Styles.LineColor, - Styles.LAYER_BEFORE_DEFAULT_VALUE); - registerInheritedStyleKey(Styles.LineWidth, - Styles.LAYER_BEFORE_DEFAULT_VALUE); - registerInheritedStyleKey(Styles.LinePattern, - Styles.LAYER_BEFORE_DEFAULT_VALUE); - } - - public static DefaultBranchStyleSelector getDefault() { - if (instance == null) - instance = new DefaultBranchStyleSelector(); - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import org.xmind.ui.style.Styles; + +public class DefaultBranchStyleSelector extends AbstractBranchStyleSelector { + + private static DefaultBranchStyleSelector instance = null; + + protected DefaultBranchStyleSelector() { + registerInheritedStyleKey(Styles.LineColor, + Styles.LAYER_BEFORE_DEFAULT_VALUE); + registerInheritedStyleKey(Styles.LineWidth, + Styles.LAYER_BEFORE_DEFAULT_VALUE); + registerInheritedStyleKey(Styles.LinePattern, + Styles.LAYER_BEFORE_DEFAULT_VALUE); + } + + public static DefaultBranchStyleSelector getDefault() { + if (instance == null) + instance = new DefaultBranchStyleSelector(); + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DownStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DownStructure.java index 0837c6ca9..bef880c73 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DownStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/DownStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class DownStructure extends UpDownStructure { - - public DownStructure() { - super(false); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class DownStructure extends UpDownStructure { + + public DownStructure() { + super(false); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/FloatingMapBranchHook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/FloatingMapBranchHook.java index ecb1a8da0..46bf542d1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/FloatingMapBranchHook.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/FloatingMapBranchHook.java @@ -1,194 +1,199 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.part.IPartListener; -import org.xmind.gef.part.PartEvent; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.ICacheValueProvider; -import org.xmind.ui.mindmap.IRangeListener; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.mindmap.RangeEvent; -import org.xmind.ui.util.MindMapUtils; - -public class FloatingMapBranchHook implements IBranchHook, FigureListener, - IPartListener, IRangeListener { - - IBranchPart branch; - -// private List topicListeners = new ArrayList(); -// -// private Map> rangeListeners = new HashMap>(); - - public void hook(IBranchPart branch) { - this.branch = branch; - branch.getFigure().addFigureListener(this); - if (MindMapUI.BRANCH_FLOATING.equals(branch.getBranchType())) { - branch.addPartListener(this); - for (IBoundaryPart b : branch.getBoundaries()) { - b.addRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.addRangeListener(this); - } - -// ITopic topic = branch.getTopic(); -// if (topic instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) topic; -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryRemove, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryRemove, this)); -// } -// for (IBoundary boundary : topic.getBoundaries()) { -// registerRangeListeners(boundary); -// } -// for (ISummary summary : topic.getSummaries()) { -// registerRangeListeners(summary); -// } - } - } - - public void unhook(IBranchPart branch) { - if (MindMapUI.BRANCH_FLOATING.equals(branch.getBranchType())) { - for (IBoundaryPart b : branch.getBoundaries()) { - b.removeRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.removeRangeListener(this); - } - branch.removePartListener(this); - } - branch.getFigure().removeFigureListener(this); -// unregister(topicListeners); -// for (List regs : rangeListeners.values()) { -// unregister(regs); -// } - } - - public void figureMoved(IFigure source) { - if (needUpdate()) { - branch.getBranchPolicy().flushStructureCache(branch, true, true); - findTopBranch(branch, branch.getBranchPolicyId()).treeUpdate(false); - } - } - - private IBranchPart findTopBranch(IBranchPart branch, String policyId) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - String parentId = parent.getBranchPolicyId(); - if (policyId.equals(parentId)) - return findTopBranch(parent, policyId); - } - return branch; - } - - private boolean needUpdate() { - String oldValue = (String) MindMapUtils.getCache(branch, - IBranchPolicy.CACHE_STRUCTURE_ID); - String newValue = calcStructureId(branch); - if (newValue == null) - return false; - return !newValue.equals(oldValue); - } - - private String calcStructureId(IBranchPart branch) { - ICacheValueProvider valueProvider = MindMapUtils - .getCacheManager(branch).getValueProvider( - IBranchPolicy.CACHE_STRUCTURE_ID); - if (valueProvider != null) { - Object value = valueProvider.getValue(branch, - IBranchPolicy.CACHE_STRUCTURE_ID); - if (value instanceof String) { - return (String) value; - } - } - return null; - } - - public void childAdded(PartEvent event) { - if (event.child instanceof IBranchPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - ((IBranchRangePart) event.child).addRangeListener(this); - } - } - - public void childRemoving(PartEvent event) { - if (event.child instanceof IBranchPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - ((IBranchRangePart) event.child).removeRangeListener(this); - } - } - - public void rangeChanged(RangeEvent event) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } - -// private void unregister(List listeners) { -// for (ICoreEventRegistration reg : listeners) { -// reg.unregister(); -// } -// } -// -// public void handleCoreEvent(CoreEvent event) { -// String type = event.getType(); -// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { -// Object range = event.getTarget(); -// registerRangeListeners(range); -// } else if (Core.BoundaryRemove.equals(type) -// || Core.SummaryRemove.equals(type)) { -// Object range = event.getTarget(); -// List list = rangeListeners.remove(range); -// if (list != null) { -// unregister(list); -// } -// } else if (Core.StartIndex.equals(type) || Core.EndIndex.equals(type)) { -// branch.getFigure().invalidate(); -// branch.treeUpdate(true); -// } -// } -// -// private void registerRangeListeners(Object range) { -// if (range instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) range; -// List list = new ArrayList(); -// list.add(source.registerCoreEventListener(Core.StartIndex, this)); -// list.add(source.registerCoreEventListener(Core.EndIndex, this)); -// rangeListeners.put(range, list); -// } -// } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.part.IPartListener2; +import org.xmind.gef.part.PartEvent; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.ICacheValueProvider; +import org.xmind.ui.mindmap.IRangeListener; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.mindmap.RangeEvent; +import org.xmind.ui.util.MindMapUtils; + +public class FloatingMapBranchHook + implements IBranchHook, FigureListener, IPartListener2, IRangeListener { + + IBranchPart branch; + +// private List topicListeners = new ArrayList(); +// +// private Map> rangeListeners = new HashMap>(); + + public void hook(IBranchPart branch) { + this.branch = branch; + branch.getFigure().addFigureListener(this); + if (MindMapUI.BRANCH_FLOATING.equals(branch.getBranchType())) { + branch.addPartListener(this); + for (IBoundaryPart b : branch.getBoundaries()) { + b.addRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.addRangeListener(this); + } + +// ITopic topic = branch.getTopic(); +// if (topic instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) topic; +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryRemove, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryRemove, this)); +// } +// for (IBoundary boundary : topic.getBoundaries()) { +// registerRangeListeners(boundary); +// } +// for (ISummary summary : topic.getSummaries()) { +// registerRangeListeners(summary); +// } + } + } + + public void unhook(IBranchPart branch) { + if (MindMapUI.BRANCH_FLOATING.equals(branch.getBranchType())) { + for (IBoundaryPart b : branch.getBoundaries()) { + b.removeRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.removeRangeListener(this); + } + branch.removePartListener(this); + } + branch.getFigure().removeFigureListener(this); +// unregister(topicListeners); +// for (List regs : rangeListeners.values()) { +// unregister(regs); +// } + } + + public void figureMoved(IFigure source) { + if (needUpdate()) { + branch.getBranchPolicy().flushStructureCache(branch, true, true); + findTopBranch(branch, branch.getBranchPolicyId()).treeUpdate(false); + } + } + + private IBranchPart findTopBranch(IBranchPart branch, String policyId) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + String parentId = parent.getBranchPolicyId(); + if (policyId.equals(parentId)) + return findTopBranch(parent, policyId); + } + return branch; + } + + private boolean needUpdate() { + String oldValue = (String) MindMapUtils.getCache(branch, + IBranchPolicy.CACHE_STRUCTURE_ID); + String newValue = calcStructureId(branch); + if (newValue == null) + return false; + return !newValue.equals(oldValue); + } + + private String calcStructureId(IBranchPart branch) { + ICacheValueProvider valueProvider = MindMapUtils.getCacheManager(branch) + .getValueProvider(IBranchPolicy.CACHE_STRUCTURE_ID); + if (valueProvider != null) { + Object value = valueProvider.getValue(branch, + IBranchPolicy.CACHE_STRUCTURE_ID); + if (value instanceof String) { + return (String) value; + } + } + return null; + } + + public void childAdding(PartEvent event) { + } + + public void childAdded(PartEvent event) { + if (event.child instanceof IBranchPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + ((IBranchRangePart) event.child).addRangeListener(this); + } + } + + public void childRemoving(PartEvent event) { + } + + public void childRemoved(PartEvent event) { + if (event.child instanceof IBranchPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + ((IBranchRangePart) event.child).removeRangeListener(this); + } + } + + public void rangeChanged(RangeEvent event) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } + +// private void unregister(List listeners) { +// for (ICoreEventRegistration reg : listeners) { +// reg.unregister(); +// } +// } +// +// public void handleCoreEvent(CoreEvent event) { +// String type = event.getType(); +// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { +// Object range = event.getTarget(); +// registerRangeListeners(range); +// } else if (Core.BoundaryRemove.equals(type) +// || Core.SummaryRemove.equals(type)) { +// Object range = event.getTarget(); +// List list = rangeListeners.remove(range); +// if (list != null) { +// unregister(list); +// } +// } else if (Core.StartIndex.equals(type) || Core.EndIndex.equals(type)) { +// branch.getFigure().invalidate(); +// branch.treeUpdate(true); +// } +// } +// +// private void registerRangeListeners(Object range) { +// if (range instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) range; +// List list = new ArrayList(); +// list.add(source.registerCoreEventListener(Core.StartIndex, this)); +// list.add(source.registerCoreEventListener(Core.EndIndex, this)); +// rangeListeners.put(range, list); +// } +// } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftRightStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftRightStructure.java index 1a370417e..6ab64bd47 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftRightStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftRightStructure.java @@ -1,367 +1,367 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.HorizontalFlipper; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.internal.mindmap.TopicPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -public class LeftRightStructure extends AbstractBranchStructure { - - private boolean leftwards; - - private ITransformer t = new HorizontalFlipper(); - - protected LeftRightStructure(boolean leftwards) { - this.leftwards = leftwards; - this.t.setEnabled(leftwards); - } - - public boolean isLeftwards() { - return leftwards; - } - - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - t.setOrigin(ref); - int y = ref.y; -// IFigure tf = branch.getTopicPart().getFigure(); -// ITopicDecoration shape = ((TopicFigure) tf).getDecoration(); -// if (Styles.TOPIC_SHAPE_UNDERLINE.equals(shape.getId())) -// y += tf.getPreferredSize().height / 2; - - Rectangle topicBounds = info.getCheckedClientArea(); - topicBounds = t.tr(topicBounds); - int x = topicBounds.right(); - - IFigure pmFigure = plusMinus.getFigure(); - Dimension size = pmFigure.getPreferredSize(); - - Rectangle r = new Rectangle(x, y - size.height / 2, size.width, - size.height); - info.put(pmFigure, t.r(r)); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - int majorSpacing = getMajorSpacing(branch); - int minorSpacing = getMinorSpacing(branch); - - Point ref = info.getReference(); - t.setOrigin(ref); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = t.tr(refBounds); - - int x = refBounds.right() + majorSpacing; - - int num = subBranches.size(); - - int anchorHeight = 0; - TopicPart topicPart = (TopicPart) branch.getTopicPart(); - if (topicPart != null) { - IAnchor anchor = topicPart.getSourceAnchor(null); - anchorHeight = (int) anchor - .getLocation(leftwards ? PositionConstants.EAST - : PositionConstants.WEST, 0) - .getDifference(anchor.getReferencePoint()).height; - } - -// int totalHeight = calcTotalChildrenHeight(branch, minorSpacing, true); -// int top = totalHeight / 2; -// int y = ref.y - top; - int distanceTop = calcDistanceTop(branch, minorSpacing, true); - int y = ref.y + (int) anchorHeight - distanceTop; - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - - for (int i = 0; i < num; i++) { - if (insertion != null && i == insertion.getIndex()) { - Rectangle r = insertion.createRectangle(x, y); - info.add(t.rr(r)); - y += r.height + minorSpacing; - } - IBranchPart subBranch = subBranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - Insets ins = helper.getInsets(subBranch); - ins = t.ti(ins); - - Dimension size = subBranchFigure.getPreferredSize(); - Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, - size.height); - - info.put(subBranchFigure, t.rr(r)); - y += size.height + ins.getHeight() + minorSpacing; - } - - if (insertion != null && num == insertion.getIndex()) { - Dimension insSize = insertion.getSize(); - if (insSize != null) { - Rectangle r = new Rectangle(x, y, insSize.width, - insSize.height); - info.add(t.rr(r)); - - } - } - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (!branch.getSubBranches().isEmpty()) { - if (isLeftwards()) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } else { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } - } - return super.calcNavigation(branch, navReqType); - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (isLeftwards()) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return branch.getTopicPart(); - } - } else { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public int getSourceOrientation(IBranchPart branch) { - if (isLeftwards()) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return calcChildTargetOrientation(); - } - - private int calcChildTargetOrientation() { - if (isLeftwards()) - return PositionConstants.EAST; - return PositionConstants.WEST; - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - IFigure branchFigure = branch.getFigure(); - IReferencedFigure topicFigure = (IReferencedFigure) branch - .getTopicPart().getFigure(); - Point ref = topicFigure.getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Rectangle branchBounds = t.tr(branchFigure.getBounds()); - Rectangle topicBounds = t.tr(topicFigure.getBounds()); - int dx = childRef.x - topicBounds.right(); - if (dx > 0) { - if (childRef.y >= branchBounds.y - && childRef.y < branchBounds.bottom() - && dx < MindMapUI.SEARCH_RANGE) { - return dx; - } - int dy = childRef.y - ref.y; - int d = dy * dy + dx * dx; - return d; - } - return super.calcChildDistance(branch, key); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - IFigure topicFigure = topic.getFigure(); - Point ref = ((IReferencedFigure) topicFigure).getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Dimension insSize = calcInsSize(key.getFigure()); - int insHeight = insSize.height; - int minorSpacing = getMinorSpacing(branch); - int totalChildrenHeight = calcTotalChildrenHeight(branch, minorSpacing, - false); - int totalHeight = totalChildrenHeight + insHeight + minorSpacing; - int startY = ref.y - totalHeight / 2; - return calcInsIndex(branch, startY, childRef, insHeight, minorSpacing, - withDisabled); - } - - private int calcInsIndex(IBranchPart branch, int startY, Point childRef, - int childHeight, int spacing, boolean withDisabled) { - int ret = 0; - int sum = 0; - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - for (IBranchPart subBranch : subBranches) { - IFigure subFigure = subBranch.getFigure(); - int h = getBorderedSize(branch, subBranch).height;//subFigure.getPreferredSize().height; - int hint = startY + sum + (childHeight + h + spacing) / 2; - if (childRef.y < hint) { - return ret; - } - sum += h + spacing; - if (withDisabled || subFigure.isEnabled()) - ret++; - } - return withDisabled ? num : -1; - } - - private Dimension calcInsSize(IReferencedFigure child) { - return child.getSize().scale(0.8); - } - - private int calcDistanceTop(IBranchPart branch, int minorSpacing, - boolean withInsertion) { - int totalAnchorHeight = 0; - int firstDistanceTop = 0; - - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - for (int i = 0; i < num; i++) { - IBranchPart subBranch = subBranches.get(i); - int h = getBorderedSize(branch, subBranch).height; - - TopicPart topicPart = (TopicPart) subBranch.getTopicPart(); - int anchorDistanceTop = 0; - if (topicPart != null) { - IAnchor anchor = topicPart.getTargetAnchor(null); - anchorDistanceTop = (int) anchor.getLocation(leftwards - ? PositionConstants.EAST : PositionConstants.WEST, 0).y - - subBranch.getFigure().getBounds().y; - } - - if (i == 0) { - firstDistanceTop = anchorDistanceTop; - totalAnchorHeight += num == 1 ? 0 : h - anchorDistanceTop; - continue; - } - - totalAnchorHeight += minorSpacing; - if (i == num - 1) { - totalAnchorHeight += anchorDistanceTop; - break; - } - - totalAnchorHeight += h; - } - if (withInsertion) { - IInsertion ins = getCurrentInsertion(branch); - if (ins != null) { - Dimension insSize = ins.getSize(); - if (insSize != null) { - totalAnchorHeight += minorSpacing + insSize.height; - } - } - } - return totalAnchorHeight / 2 + firstDistanceTop; - - } - - private int calcTotalChildrenHeight(IBranchPart branch, int minorSpacing, - boolean withInsertion) { - int totalHeight = 0; - Iterator it = branch.getSubBranches().iterator(); - while (it.hasNext()) { - IBranchPart subBranch = it.next(); - int h = getBorderedSize(branch, subBranch).height; -// System.out.println(h); - totalHeight += h;//subBranch.getFigure().getPreferredSize().height; - if (it.hasNext()) { - totalHeight += minorSpacing; - } - } - if (withInsertion) { - IInsertion ins = getCurrentInsertion(branch); - if (ins != null) { - Dimension insSize = ins.getSize(); - if (insSize != null) { - totalHeight += minorSpacing + insSize.height; - } - } - } - return totalHeight; - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - int newIndex = calcInsIndex(branch, key, true); - Dimension newSize = calcInsSize(key.getFigure()); - return new Insertion(branch, newIndex, newSize); - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - if (leftwards) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.SOUTH; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.SOUTH) - return 1; - if (direction == PositionConstants.NORTH) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.HorizontalFlipper; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.internal.mindmap.TopicPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +public class LeftRightStructure extends AbstractBranchStructure { + + private boolean leftwards; + + private ITransformer t = new HorizontalFlipper(); + + protected LeftRightStructure(boolean leftwards) { + this.leftwards = leftwards; + this.t.setEnabled(leftwards); + } + + public boolean isLeftwards() { + return leftwards; + } + + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + t.setOrigin(ref); + int y = ref.y; +// IFigure tf = branch.getTopicPart().getFigure(); +// ITopicDecoration shape = ((TopicFigure) tf).getDecoration(); +// if (Styles.TOPIC_SHAPE_UNDERLINE.equals(shape.getId())) +// y += tf.getPreferredSize().height / 2; + + Rectangle topicBounds = info.getCheckedClientArea(); + topicBounds = t.tr(topicBounds); + int x = topicBounds.right(); + + IFigure pmFigure = plusMinus.getFigure(); + Dimension size = pmFigure.getPreferredSize(); + + Rectangle r = new Rectangle(x, y - size.height / 2, size.width, + size.height); + info.put(pmFigure, t.r(r)); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + int majorSpacing = getMajorSpacing(branch); + int minorSpacing = getMinorSpacing(branch); + + Point ref = info.getReference(); + t.setOrigin(ref); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = t.tr(refBounds); + + int x = refBounds.right() + majorSpacing; + + int num = subBranches.size(); + + int anchorHeight = 0; + TopicPart topicPart = (TopicPart) branch.getTopicPart(); + if (topicPart != null) { + IAnchor anchor = topicPart.getSourceAnchor(null); + anchorHeight = (int) anchor + .getLocation(leftwards ? PositionConstants.EAST + : PositionConstants.WEST, 0) + .getDifference(anchor.getReferencePoint()).height; + } + +// int totalHeight = calcTotalChildrenHeight(branch, minorSpacing, true); +// int top = totalHeight / 2; +// int y = ref.y - top; + int distanceTop = calcDistanceTop(branch, minorSpacing, true); + int y = ref.y + (int) anchorHeight - distanceTop; + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + + for (int i = 0; i < num; i++) { + if (insertion != null && i == insertion.getIndex()) { + Rectangle r = insertion.createRectangle(x, y); + info.add(t.rr(r)); + y += r.height + minorSpacing; + } + IBranchPart subBranch = subBranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + Insets ins = helper.getInsets(subBranch); + ins = t.ti(ins); + + Dimension size = subBranchFigure.getPreferredSize(); + Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, + size.height); + + info.put(subBranchFigure, t.rr(r)); + y += size.height + ins.getHeight() + minorSpacing; + } + + if (insertion != null && num == insertion.getIndex()) { + Dimension insSize = insertion.getSize(); + if (insSize != null) { + Rectangle r = new Rectangle(x, y, insSize.width, + insSize.height); + info.add(t.rr(r)); + + } + } + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (!branch.getSubBranches().isEmpty()) { + if (isLeftwards()) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } else { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } + } + return super.calcNavigation(branch, navReqType); + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (isLeftwards()) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return branch.getTopicPart(); + } + } else { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public int getSourceOrientation(IBranchPart branch) { + if (isLeftwards()) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return calcChildTargetOrientation(); + } + + private int calcChildTargetOrientation() { + if (isLeftwards()) + return PositionConstants.EAST; + return PositionConstants.WEST; + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + IFigure branchFigure = branch.getFigure(); + IReferencedFigure topicFigure = (IReferencedFigure) branch + .getTopicPart().getFigure(); + Point ref = topicFigure.getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Rectangle branchBounds = t.tr(branchFigure.getBounds()); + Rectangle topicBounds = t.tr(topicFigure.getBounds()); + int dx = childRef.x - topicBounds.right(); + if (dx > 0) { + if (childRef.y >= branchBounds.y + && childRef.y < branchBounds.bottom() + && dx < MindMapUI.SEARCH_RANGE) { + return dx; + } + int dy = childRef.y - ref.y; + int d = dy * dy + dx * dx; + return d; + } + return super.calcChildDistance(branch, key); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + IFigure topicFigure = topic.getFigure(); + Point ref = ((IReferencedFigure) topicFigure).getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Dimension insSize = calcInsSize(key.getFigure()); + int insHeight = insSize.height; + int minorSpacing = getMinorSpacing(branch); + int totalChildrenHeight = calcTotalChildrenHeight(branch, minorSpacing, + false); + int totalHeight = totalChildrenHeight + insHeight + minorSpacing; + int startY = ref.y - totalHeight / 2; + return calcInsIndex(branch, startY, childRef, insHeight, minorSpacing, + withDisabled); + } + + private int calcInsIndex(IBranchPart branch, int startY, Point childRef, + int childHeight, int spacing, boolean withDisabled) { + int ret = 0; + int sum = 0; + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + for (IBranchPart subBranch : subBranches) { + IFigure subFigure = subBranch.getFigure(); + int h = getBorderedSize(branch, subBranch).height;//subFigure.getPreferredSize().height; + int hint = startY + sum + (childHeight + h + spacing) / 2; + if (childRef.y < hint) { + return ret; + } + sum += h + spacing; + if (withDisabled || subFigure.isEnabled()) + ret++; + } + return withDisabled ? num : -1; + } + + private Dimension calcInsSize(IReferencedFigure child) { + return child.getSize().scale(0.8); + } + + private int calcDistanceTop(IBranchPart branch, int minorSpacing, + boolean withInsertion) { + int totalAnchorHeight = 0; + int firstDistanceTop = 0; + + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + for (int i = 0; i < num; i++) { + IBranchPart subBranch = subBranches.get(i); + int h = getBorderedSize(branch, subBranch).height; + + TopicPart topicPart = (TopicPart) subBranch.getTopicPart(); + int anchorDistanceTop = 0; + if (topicPart != null) { + IAnchor anchor = topicPart.getTargetAnchor(null); + anchorDistanceTop = (int) anchor.getLocation(leftwards + ? PositionConstants.EAST : PositionConstants.WEST, 0).y + - subBranch.getFigure().getBounds().y; + } + + if (i == 0) { + firstDistanceTop = anchorDistanceTop; + totalAnchorHeight += num == 1 ? 0 : h - anchorDistanceTop; + continue; + } + + totalAnchorHeight += minorSpacing; + if (i == num - 1) { + totalAnchorHeight += anchorDistanceTop; + break; + } + + totalAnchorHeight += h; + } + if (withInsertion) { + IInsertion ins = getCurrentInsertion(branch); + if (ins != null) { + Dimension insSize = ins.getSize(); + if (insSize != null) { + totalAnchorHeight += minorSpacing + insSize.height; + } + } + } + return totalAnchorHeight / 2 + firstDistanceTop; + + } + + private int calcTotalChildrenHeight(IBranchPart branch, int minorSpacing, + boolean withInsertion) { + int totalHeight = 0; + Iterator it = branch.getSubBranches().iterator(); + while (it.hasNext()) { + IBranchPart subBranch = it.next(); + int h = getBorderedSize(branch, subBranch).height; +// System.out.println(h); + totalHeight += h;//subBranch.getFigure().getPreferredSize().height; + if (it.hasNext()) { + totalHeight += minorSpacing; + } + } + if (withInsertion) { + IInsertion ins = getCurrentInsertion(branch); + if (ins != null) { + Dimension insSize = ins.getSize(); + if (insSize != null) { + totalHeight += minorSpacing + insSize.height; + } + } + } + return totalHeight; + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + int newIndex = calcInsIndex(branch, key, true); + Dimension newSize = calcInsSize(key.getFigure()); + return new Insertion(branch, newIndex, newSize); + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + if (leftwards) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.SOUTH; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.SOUTH) + return 1; + if (direction == PositionConstants.NORTH) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftStructure.java index d99f0614f..908ea7a62 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class LeftStructure extends LeftRightStructure { - - public LeftStructure() { - super(true); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class LeftStructure extends LeftRightStructure { + + public LeftStructure() { + super(true); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftTreeStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftTreeStructure.java index fd3dd9bc2..14ad4199b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftTreeStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/LeftTreeStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class LeftTreeStructure extends TreeStructure { - - public LeftTreeStructure() { - super(true); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class LeftTreeStructure extends TreeStructure { + + public LeftTreeStructure() { + super(true); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchHook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchHook.java index 1f13e863e..517a79c81 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchHook.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchHook.java @@ -1,192 +1,197 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.part.IPartListener; -import org.xmind.gef.part.PartEvent; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.ICacheValueProvider; -import org.xmind.ui.mindmap.IRangeListener; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.RangeEvent; -import org.xmind.ui.util.MindMapUtils; - -public class MapBranchHook implements IBranchHook, FigureListener, - IPartListener, IRangeListener { - - protected IBranchPart branch; - -// private List topicListeners = new ArrayList(); -// -// private Map> rangeListeners = new HashMap>(); - - public void hook(IBranchPart branch) { - this.branch = branch; - branch.getFigure().addFigureListener(this); - if (branch.isCentral()) { - branch.addPartListener(this); - for (IBoundaryPart b : branch.getBoundaries()) { - b.addRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.addRangeListener(this); - } -// ITopic topic = branch.getTopic(); -// if (topic instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) topic; -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.BoundaryRemove, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryAdd, this)); -// topicListeners.add(source.registerCoreEventListener( -// Core.SummaryRemove, this)); -// } -// for (IBoundary boundary : topic.getBoundaries()) { -// registerRangeListeners(boundary); -// } -// for (ISummary summary : topic.getSummaries()) { -// registerRangeListeners(summary); -// } - } - } - - public void unhook(IBranchPart branch) { - if (branch.isCentral()) { - for (IBoundaryPart b : branch.getBoundaries()) { - b.removeRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.removeRangeListener(this); - } - branch.removePartListener(this); - } - branch.getFigure().removeFigureListener(this); -// unregister(topicListeners); -// for (List regs : rangeListeners.values()) { -// unregister(regs); -// } - } - - public void figureMoved(IFigure source) { - if (needUpdate()) { - branch.getBranchPolicy().flushStructureCache(branch, true, true); - findTopBranch(branch, branch.getBranchPolicyId()).treeUpdate(false); - } - } - - private IBranchPart findTopBranch(IBranchPart branch, String policyId) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - String parentId = parent.getBranchPolicyId(); - if (policyId.equals(parentId)) - return findTopBranch(parent, policyId); - } - return branch; - } - - private boolean needUpdate() { - String oldValue = (String) MindMapUtils.getCache(branch, - IBranchPolicy.CACHE_STRUCTURE_ID); - String newValue = calcStructureId(branch); - if (newValue == null) - return false; - return !newValue.equals(oldValue); - } - - private String calcStructureId(IBranchPart branch) { - ICacheValueProvider valueProvider = MindMapUtils - .getCacheManager(branch).getValueProvider( - IBranchPolicy.CACHE_STRUCTURE_ID); - if (valueProvider != null) { - Object value = valueProvider.getValue(branch, - IBranchPolicy.CACHE_STRUCTURE_ID); - if (value instanceof String) { - return (String) value; - } - } - return null; - } - - public void childAdded(PartEvent event) { - if (event.child instanceof IBranchPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - ((IBranchRangePart) event.child).addRangeListener(this); - } - } - - public void childRemoving(PartEvent event) { - if (event.child instanceof IBranchPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - ((IBranchRangePart) event.child).removeRangeListener(this); - } - } - - public void rangeChanged(RangeEvent event) { - branch.getFigure().invalidate(); - branch.treeUpdate(true); - } - -// private void unregister(List listeners) { -// for (ICoreEventRegistration reg : listeners) { -// reg.unregister(); -// } -// } -// -// public void handleCoreEvent(CoreEvent event) { -// String type = event.getType(); -// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { -// Object range = event.getTarget(); -// registerRangeListeners(range); -// } else if (Core.BoundaryRemove.equals(type) -// || Core.SummaryRemove.equals(type)) { -// Object range = event.getTarget(); -// List list = rangeListeners.remove(range); -// if (list != null) { -// unregister(list); -// } -// } else if (Core.StartIndex.equals(type) || Core.EndIndex.equals(type)) { -// branch.getFigure().invalidate(); -// branch.treeUpdate(true); -// } -// } -// -// private void registerRangeListeners(Object range) { -// if (range instanceof ICoreEventSource) { -// ICoreEventSource source = (ICoreEventSource) range; -// List list = new ArrayList(); -// list.add(source.registerCoreEventListener(Core.StartIndex, this)); -// list.add(source.registerCoreEventListener(Core.EndIndex, this)); -// rangeListeners.put(range, list); -// } -// } - -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.part.IPartListener2; +import org.xmind.gef.part.PartEvent; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.ICacheValueProvider; +import org.xmind.ui.mindmap.IRangeListener; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.RangeEvent; +import org.xmind.ui.util.MindMapUtils; + +public class MapBranchHook + implements IBranchHook, FigureListener, IPartListener2, IRangeListener { + + protected IBranchPart branch; + +// private List topicListeners = new ArrayList(); +// +// private Map> rangeListeners = new HashMap>(); + + public void hook(IBranchPart branch) { + this.branch = branch; + branch.getFigure().addFigureListener(this); + if (branch.isCentral()) { + branch.addPartListener(this); + for (IBoundaryPart b : branch.getBoundaries()) { + b.addRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.addRangeListener(this); + } +// ITopic topic = branch.getTopic(); +// if (topic instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) topic; +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.BoundaryRemove, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryAdd, this)); +// topicListeners.add(source.registerCoreEventListener( +// Core.SummaryRemove, this)); +// } +// for (IBoundary boundary : topic.getBoundaries()) { +// registerRangeListeners(boundary); +// } +// for (ISummary summary : topic.getSummaries()) { +// registerRangeListeners(summary); +// } + } + } + + public void unhook(IBranchPart branch) { + if (branch.isCentral()) { + for (IBoundaryPart b : branch.getBoundaries()) { + b.removeRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.removeRangeListener(this); + } + branch.removePartListener(this); + } + branch.getFigure().removeFigureListener(this); +// unregister(topicListeners); +// for (List regs : rangeListeners.values()) { +// unregister(regs); +// } + } + + public void figureMoved(IFigure source) { + if (needUpdate()) { + branch.getBranchPolicy().flushStructureCache(branch, true, true); + findTopBranch(branch, branch.getBranchPolicyId()).treeUpdate(false); + } + } + + private IBranchPart findTopBranch(IBranchPart branch, String policyId) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + String parentId = parent.getBranchPolicyId(); + if (policyId.equals(parentId)) + return findTopBranch(parent, policyId); + } + return branch; + } + + private boolean needUpdate() { + String oldValue = (String) MindMapUtils.getCache(branch, + IBranchPolicy.CACHE_STRUCTURE_ID); + String newValue = calcStructureId(branch); + if (newValue == null) + return false; + return !newValue.equals(oldValue); + } + + private String calcStructureId(IBranchPart branch) { + ICacheValueProvider valueProvider = MindMapUtils.getCacheManager(branch) + .getValueProvider(IBranchPolicy.CACHE_STRUCTURE_ID); + if (valueProvider != null) { + Object value = valueProvider.getValue(branch, + IBranchPolicy.CACHE_STRUCTURE_ID); + if (value instanceof String) { + return (String) value; + } + } + return null; + } + + public void childAdding(PartEvent event) { + } + + public void childAdded(PartEvent event) { + if (event.child instanceof IBranchPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + ((IBranchRangePart) event.child).addRangeListener(this); + } + } + + public void childRemoving(PartEvent event) { + } + + public void childRemoved(PartEvent event) { + if (event.child instanceof IBranchPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + ((IBranchRangePart) event.child).removeRangeListener(this); + } + } + + public void rangeChanged(RangeEvent event) { + branch.getFigure().invalidate(); + branch.treeUpdate(true); + } + +// private void unregister(List listeners) { +// for (ICoreEventRegistration reg : listeners) { +// reg.unregister(); +// } +// } +// +// public void handleCoreEvent(CoreEvent event) { +// String type = event.getType(); +// if (Core.BoundaryAdd.equals(type) || Core.SummaryAdd.equals(type)) { +// Object range = event.getTarget(); +// registerRangeListeners(range); +// } else if (Core.BoundaryRemove.equals(type) +// || Core.SummaryRemove.equals(type)) { +// Object range = event.getTarget(); +// List list = rangeListeners.remove(range); +// if (list != null) { +// unregister(list); +// } +// } else if (Core.StartIndex.equals(type) || Core.EndIndex.equals(type)) { +// branch.getFigure().invalidate(); +// branch.treeUpdate(true); +// } +// } +// +// private void registerRangeListeners(Object range) { +// if (range instanceof ICoreEventSource) { +// ICoreEventSource source = (ICoreEventSource) range; +// List list = new ArrayList(); +// list.add(source.registerCoreEventListener(Core.StartIndex, this)); +// list.add(source.registerCoreEventListener(Core.EndIndex, this)); +// rangeListeners.put(range, list); +// } +// } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchPropertyTester.java index 0c1ca61eb..a4b6d8151 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/MapBranchPropertyTester.java @@ -1,50 +1,50 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.IBranchPolicy; -import org.xmind.ui.branch.IBranchPropertyTester; -import org.xmind.ui.mindmap.IBranchPart; - -public class MapBranchPropertyTester implements IBranchPropertyTester { - - private static final String P_LEFT = "left"; //$NON-NLS-1$ - - public boolean test(IBranchPart branch, String property, Object[] args, - Object expectedValue) { - if (P_LEFT.equals(property)) { - if (expectedValue == null) - return isLeft(branch); - if (expectedValue instanceof Boolean) - return isLeft(branch) == ((Boolean) expectedValue) - .booleanValue(); - } - return false; - } - - private boolean isLeft(IBranchPart branch) { - IBranchPart parentBranch = branch.getParentBranch(); - if (parentBranch != null) { - IBranchPolicy branchPolicy = parentBranch.getBranchPolicy(); - IStructure structure = branchPolicy.getStructure(parentBranch); - if (structure instanceof BaseRadialStructure) { - BaseRadialStructure rs = (BaseRadialStructure) structure; - return rs.isChildLeft(parentBranch, branch); - } - } - return false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.IBranchPolicy; +import org.xmind.ui.branch.IBranchPropertyTester; +import org.xmind.ui.mindmap.IBranchPart; + +public class MapBranchPropertyTester implements IBranchPropertyTester { + + private static final String P_LEFT = "left"; //$NON-NLS-1$ + + public boolean test(IBranchPart branch, String property, Object[] args, + Object expectedValue) { + if (P_LEFT.equals(property)) { + if (expectedValue == null) + return isLeft(branch); + if (expectedValue instanceof Boolean) + return isLeft(branch) == ((Boolean) expectedValue) + .booleanValue(); + } + return false; + } + + private boolean isLeft(IBranchPart branch) { + IBranchPart parentBranch = branch.getParentBranch(); + if (parentBranch != null) { + IBranchPolicy branchPolicy = parentBranch.getBranchPolicy(); + IStructure structure = branchPolicy.getStructure(parentBranch); + if (structure instanceof BaseRadialStructure) { + BaseRadialStructure rs = (BaseRadialStructure) structure; + return rs.isChildLeft(parentBranch, branch); + } + } + return false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/OverridedStyle.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/OverridedStyle.java index 0d07b2d76..582cb0167 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/OverridedStyle.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/OverridedStyle.java @@ -1,158 +1,158 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_KEY; -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_NAME; -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_VALUE; -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.TAG_ENABLEMENT; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.expressions.EvaluationResult; -import org.eclipse.core.expressions.Expression; -import org.eclipse.core.expressions.ExpressionConverter; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.xmind.ui.branch.IBranchStyleValueProvider; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.Logger; - -public class OverridedStyle { - - private BranchPolicyManager manager; - - private IConfigurationElement element; - - private String key; - - private String value; - - private List layers; - - private IBranchStyleValueProvider valueProvider; - - private boolean triedLoadingValueProvider; - - private Expression condition; - - public OverridedStyle(BranchPolicyManager manager, - IConfigurationElement element) throws CoreException { - this.manager = manager; - this.element = element; - this.key = element.getAttribute(ATT_KEY); - if (key == null) - throw new CoreException( - new Status(IStatus.ERROR, element.getNamespaceIdentifier(), - 0, "Invalid extension (missing style key)", //$NON-NLS-1$ - null)); - this.value = element.getAttribute(ATT_VALUE); - initializeLayers(); - initializeEnablement(); - } - - private void initializeLayers() { - IConfigurationElement[] children = element - .getChildren(RegistryConstants.TAG_LAYER); - if (children.length > 0) { - for (IConfigurationElement child : children) { - String layerName = child.getAttribute(ATT_NAME); - if (layerName != null) { - if (layers == null) - layers = new ArrayList(); - layers.add(layerName); - } - } - } - if (layers == null) - layers = Collections.emptyList(); - } - - private void initializeEnablement() { - IConfigurationElement[] children = element.getChildren(TAG_ENABLEMENT); - if (children.length == 0) - return; - - try { - condition = ExpressionConverter.getDefault().perform(children[0]); - } catch (CoreException e) { - Logger.log(e, "Failed to convert expression: " + children[0]); //$NON-NLS-1$ - } - } - - public List getLayers() { - return layers; - } - - public String getKey() { - return key; - } - - public String getDefaultValue() { - return value; - } - - public boolean isOnLayer(String layerName) { - if (layers.isEmpty()) { - return Styles.LAYER_BEFORE_DEFAULT_VALUE.equals(layerName); - } - return layers.contains(layerName); - } - - public boolean isApplicableTo(IBranchPart branch) { - if (condition == null) - return true; - return isApplicableTo( - BranchPolicyManager.createBranchEvaluationContext(branch)); - } - - boolean isApplicableTo(IEvaluationContext context) { - if (condition == null) - return true; - try { - EvaluationResult result = condition.evaluate(context); - return result == EvaluationResult.TRUE; - } catch (CoreException e) { - Logger.log(e, "Evaluation failed: " + context); //$NON-NLS-1$ - } - return false; - } - - public String getValue(IBranchPart branch, String layerName) { - IBranchStyleValueProvider valueProvider = getValueProvider(); - if (valueProvider != null) { - return valueProvider.getValue(branch, layerName, key); - } - return getDefaultValue(); - } - - private IBranchStyleValueProvider getValueProvider() { - if (valueProvider == null && !triedLoadingValueProvider) { - String valueProviderId = element - .getAttribute(RegistryConstants.ATT_VALUE_PROVIDER_ID); - if (valueProviderId != null) { - valueProvider = manager.getValueProvider(valueProviderId); - } - triedLoadingValueProvider = true; - } - return valueProvider; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_KEY; +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_NAME; +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_VALUE; +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.TAG_ENABLEMENT; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.expressions.EvaluationResult; +import org.eclipse.core.expressions.Expression; +import org.eclipse.core.expressions.ExpressionConverter; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.xmind.ui.branch.IBranchStyleValueProvider; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.Logger; + +public class OverridedStyle { + + private BranchPolicyManager manager; + + private IConfigurationElement element; + + private String key; + + private String value; + + private List layers; + + private IBranchStyleValueProvider valueProvider; + + private boolean triedLoadingValueProvider; + + private Expression condition; + + public OverridedStyle(BranchPolicyManager manager, + IConfigurationElement element) throws CoreException { + this.manager = manager; + this.element = element; + this.key = element.getAttribute(ATT_KEY); + if (key == null) + throw new CoreException( + new Status(IStatus.ERROR, element.getNamespaceIdentifier(), + 0, "Invalid extension (missing style key)", //$NON-NLS-1$ + null)); + this.value = element.getAttribute(ATT_VALUE); + initializeLayers(); + initializeEnablement(); + } + + private void initializeLayers() { + IConfigurationElement[] children = element + .getChildren(RegistryConstants.TAG_LAYER); + if (children.length > 0) { + for (IConfigurationElement child : children) { + String layerName = child.getAttribute(ATT_NAME); + if (layerName != null) { + if (layers == null) + layers = new ArrayList(); + layers.add(layerName); + } + } + } + if (layers == null) + layers = Collections.emptyList(); + } + + private void initializeEnablement() { + IConfigurationElement[] children = element.getChildren(TAG_ENABLEMENT); + if (children.length == 0) + return; + + try { + condition = ExpressionConverter.getDefault().perform(children[0]); + } catch (CoreException e) { + Logger.log(e, "Failed to convert expression: " + children[0]); //$NON-NLS-1$ + } + } + + public List getLayers() { + return layers; + } + + public String getKey() { + return key; + } + + public String getDefaultValue() { + return value; + } + + public boolean isOnLayer(String layerName) { + if (layers.isEmpty()) { + return Styles.LAYER_BEFORE_DEFAULT_VALUE.equals(layerName); + } + return layers.contains(layerName); + } + + public boolean isApplicableTo(IBranchPart branch) { + if (condition == null) + return true; + return isApplicableTo( + BranchPolicyManager.createBranchEvaluationContext(branch)); + } + + boolean isApplicableTo(IEvaluationContext context) { + if (condition == null) + return true; + try { + EvaluationResult result = condition.evaluate(context); + return result == EvaluationResult.TRUE; + } catch (CoreException e) { + Logger.log(e, "Evaluation failed: " + context); //$NON-NLS-1$ + } + return false; + } + + public String getValue(IBranchPart branch, String layerName) { + IBranchStyleValueProvider valueProvider = getValueProvider(); + if (valueProvider != null) { + return valueProvider.getValue(branch, layerName, key); + } + return getDefaultValue(); + } + + private IBranchStyleValueProvider getValueProvider() { + if (valueProvider == null && !triedLoadingValueProvider) { + String valueProviderId = element + .getAttribute(RegistryConstants.ATT_VALUE_PROVIDER_ID); + if (valueProviderId != null) { + valueProvider = manager.getValueProvider(valueProviderId); + } + triedLoadingValueProvider = true; + } + return valueProvider; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ParentValueProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ParentValueProvider.java index 29c96e64d..13f9f3d1b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ParentValueProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/ParentValueProvider.java @@ -1,120 +1,120 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.HashSet; -import java.util.Set; - -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ICacheManager; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.MindMapUtils; - -public class ParentValueProvider { - - private static final String CACHE_PARENT_VALUE_PROVIDER = "org.xmind.ui.branchCache.parentValueProvider"; //$NON-NLS-1$ - - private static final String PREFIX = "org.xmind.ui.branchCache.style."; //$NON-NLS-1$ - - private static final String USER_PREFIX = "org.xmind.ui.branchCache.style.user."; //$NON-NLS-1$ - - private IBranchPart branch; - - private Set cachedKeys = null; - - private ParentValueProvider(IBranchPart branch) { - this.branch = branch; - } - - public String getParentValue(String key) { - String cacheKey = PREFIX + key; - String value = (String) MindMapUtils.getCache(branch, cacheKey); - if (value == null) { - value = getParentCachedValue(branch, key, cacheKey); - if (value == null) - value = Styles.NULL; - MindMapUtils.setCache(branch, cacheKey, value); - if (cachedKeys == null) - cachedKeys = new HashSet(); - cachedKeys.add(cacheKey); - } - if (Styles.NULL.equals(value)) - return null; - return value; - } - - private String getParentCachedValue(IBranchPart branch, String key, - String cacheKey) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - ParentValueProvider parentProvider = getValueProvider(parent); - return parentProvider.getCachedValue(parent, key, cacheKey); - } - return null; - } - - private String getCachedValue(IBranchPart branch, String key, - String cacheKey) { - String userCacheKey = USER_PREFIX + key; - String value = (String) MindMapUtils.getCache(branch, userCacheKey); - if (value == null) { - value = getValue(branch, key, cacheKey); - if (value == null) - value = Styles.NULL; - MindMapUtils.setCache(branch, userCacheKey, value); - if (cachedKeys == null) - cachedKeys = new HashSet(); - cachedKeys.add(userCacheKey); - } - if (Styles.NULL.equals(value)) - return null; - return value; - } - - protected String getValue(IBranchPart branch, String key, String cacheKey) { - IStyleSelector ss = branch.getBranchPolicy().getStyleSelector(branch); - String value; - value = ss.getStyleValue(branch, key); - if (value != null) - return value; - return getParentCachedValue(branch, key, cacheKey); - } - - public static ParentValueProvider getValueProvider(IBranchPart branch) { - ParentValueProvider valueProvider = (ParentValueProvider) MindMapUtils - .getCache(branch, CACHE_PARENT_VALUE_PROVIDER); - if (valueProvider == null) { - valueProvider = new ParentValueProvider(branch); - MindMapUtils.setCache(branch, CACHE_PARENT_VALUE_PROVIDER, - valueProvider); - } - return valueProvider; - } - - public static void flush(IBranchPart branch) { - ICacheManager cacheManager = MindMapUtils.getCacheManager(branch); - ParentValueProvider valueProvider = (ParentValueProvider) cacheManager - .getCache(CACHE_PARENT_VALUE_PROVIDER); - if (valueProvider != null) { - if (valueProvider.cachedKeys != null) { - for (String cachedKey : valueProvider.cachedKeys) { - cacheManager.flush(cachedKey); - } - } - } - cacheManager.flush(CACHE_PARENT_VALUE_PROVIDER); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.HashSet; +import java.util.Set; + +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ICacheManager; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.MindMapUtils; + +public class ParentValueProvider { + + private static final String CACHE_PARENT_VALUE_PROVIDER = "org.xmind.ui.branchCache.parentValueProvider"; //$NON-NLS-1$ + + private static final String PREFIX = "org.xmind.ui.branchCache.style."; //$NON-NLS-1$ + + private static final String USER_PREFIX = "org.xmind.ui.branchCache.style.user."; //$NON-NLS-1$ + + private IBranchPart branch; + + private Set cachedKeys = null; + + private ParentValueProvider(IBranchPart branch) { + this.branch = branch; + } + + public String getParentValue(String key) { + String cacheKey = PREFIX + key; + String value = (String) MindMapUtils.getCache(branch, cacheKey); + if (value == null) { + value = getParentCachedValue(branch, key, cacheKey); + if (value == null) + value = Styles.NULL; + MindMapUtils.setCache(branch, cacheKey, value); + if (cachedKeys == null) + cachedKeys = new HashSet(); + cachedKeys.add(cacheKey); + } + if (Styles.NULL.equals(value)) + return null; + return value; + } + + private String getParentCachedValue(IBranchPart branch, String key, + String cacheKey) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + ParentValueProvider parentProvider = getValueProvider(parent); + return parentProvider.getCachedValue(parent, key, cacheKey); + } + return null; + } + + private String getCachedValue(IBranchPart branch, String key, + String cacheKey) { + String userCacheKey = USER_PREFIX + key; + String value = (String) MindMapUtils.getCache(branch, userCacheKey); + if (value == null) { + value = getValue(branch, key, cacheKey); + if (value == null) + value = Styles.NULL; + MindMapUtils.setCache(branch, userCacheKey, value); + if (cachedKeys == null) + cachedKeys = new HashSet(); + cachedKeys.add(userCacheKey); + } + if (Styles.NULL.equals(value)) + return null; + return value; + } + + protected String getValue(IBranchPart branch, String key, String cacheKey) { + IStyleSelector ss = branch.getBranchPolicy().getStyleSelector(branch); + String value; + value = ss.getStyleValue(branch, key); + if (value != null) + return value; + return getParentCachedValue(branch, key, cacheKey); + } + + public static ParentValueProvider getValueProvider(IBranchPart branch) { + ParentValueProvider valueProvider = (ParentValueProvider) MindMapUtils + .getCache(branch, CACHE_PARENT_VALUE_PROVIDER); + if (valueProvider == null) { + valueProvider = new ParentValueProvider(branch); + MindMapUtils.setCache(branch, CACHE_PARENT_VALUE_PROVIDER, + valueProvider); + } + return valueProvider; + } + + public static void flush(IBranchPart branch) { + ICacheManager cacheManager = MindMapUtils.getCacheManager(branch); + ParentValueProvider valueProvider = (ParentValueProvider) cacheManager + .getCache(CACHE_PARENT_VALUE_PROVIDER); + if (valueProvider != null) { + if (valueProvider.cachedKeys != null) { + for (String cachedKey : valueProvider.cachedKeys) { + cacheManager.flush(cachedKey); + } + } + } + cacheManager.flush(CACHE_PARENT_VALUE_PROVIDER); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RadialStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RadialStructure.java index 1822b5656..c58df0719 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RadialStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RadialStructure.java @@ -1,232 +1,232 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.tools.ParentSearchKey; - -public class RadialStructure extends BaseRadialStructure { - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - RadialData cache = getRadialData(branch); - int numRight = cache.getNumRight(); - int[] childrenSpacings = cache.getChildrenSpacings(); - int num = subBranches.size(); - boolean right = true; - RadiationInsertion insertion = getCurrentInsertion(branch); - int insHeight = insertion == null ? 0 : insertion.getSize().height; - - int y = -cache.getRightSumSpacing() / 2; - if (insertion != null && insertion.right) { - y -= insHeight / 2; - } - - Point ref = info.getReference(); - for (int i = 0; i < num; i++) { - if (i == numRight) { - y = -cache.getLeftSumSpacing() / 2; - if (insertion != null && !insertion.right) { - y -= insHeight / 2; - } - right = false; - } - - if (insertion != null && i == insertion.getIndex()) { - if (i != numRight || !insertion.right) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - y += insHeight; - } - } - - IBranchPart subBranch = subBranches.get(i); - Rectangle r; - Dimension offset = getOffset(subBranch); - IFigure subFigure = subBranch.getFigure(); - if (offset != null && subFigure instanceof IReferencedFigure) { - Point subRef = ref.getTranslated(offset); - r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); - } else { - int x = cache.getX(y, right); - Point subRef = ref.getTranslated(x, y); - r = RadialUtils.getPrefBounds(subBranch, subRef, right); - } - info.put(subFigure, r); - y += childrenSpacings[i]; - - if (insertion != null) { - if ((i == numRight - 1 && insertion.getIndex() == numRight && insertion.right) - || i == num) { - Point p = ref.getTranslated(cache.getX(y, right), y); - Rectangle insBounds = RadialUtils.getPrefBounds( - insertion.getSize(), p, right); - info.add(insBounds); - y += insHeight; - } - } - } - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() >= numFirst) { - return branch.getTopicPart(); - } - } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - int numFirst = getRadialData(branch).getNumRight(); - if (sourceChild.getBranchIndex() < numFirst) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - return super.getSummaryDirection(branch, summary); - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - RadialData cache = getRadialData(branch); - - int subSize = subBranches.size(); - int right = cache.getNumRight(); - - Dimension inventSize = key.getInvent().getSize(); - if (index == oldIndex) { - if (subSize > right && index == right - 1 - && key.getCursorPos().x < 0 - && (!subBranches.get(right).getFigure().isEnabled())) - index += 1; - int delta = getTopicSize(subBranches.get(index)).width / 2 - - inventSize.width / 2; - int deltaX = index < right ? -delta : delta; - return getReference(subBranches.get(index)) - .getTranslated(deltaX, 0); - } - return calcInsertPosition(branch, child, key); - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - Point firstLoc = calcFirstChildPosition(branch, key).getTranslated( - key.getInvent().getSize().width / 2, 0); - if (subBranches.isEmpty()) - return firstLoc; - - int index = calcInsIndex(branch, key, true); - RadialData cache = getRadialData(branch); - - int subSize = subBranches.size(); - int right = cache.getNumRight(); - int left = subSize - right; - - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - IBranchPart first = subBranches.get(0); - Rectangle fBounds = first.getFigure().getBounds(); - - if (index == 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == subSize || index == -1) { - if (subSize == 1 && isWithinThreshold(first)) { - if (fBounds.bottom() > 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.bottom() - + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - return new Point(firstLoc.x, -firstLoc.y); - } - - if (left == 0) - return new Point(-firstLoc.x, firstLoc.y); - - IBranchPart sub = subBranches.get(subSize - 1); - Rectangle bounds = sub.getFigure().getBounds(); - if (left == 1 && bounds.bottom() < 0) - return firstLoc.getNegated(); - - int x = bounds.right() - inventSize.width / 2; - int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (index == right) { - boolean isRight = (left == 1 && right == 1) - || isRight(subBranches, child, right); - IBranchPart sub = isRight ? subBranches.get(index - 1) - : subBranches.get(index); - Rectangle bounds = sub.getFigure().getBounds(); - int x; - int y; - if (isRight) { - x = bounds.x + inventSize.width / 2; - y = bounds.bottom() + (insSize.height + inventSize.height) / 2; - } else { - x = bounds.right() - inventSize.width / 2; - y = bounds.y - (insSize.height + inventSize.height) / 2; - } - return new Point(x, y); - } - - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index), key, index < right); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.tools.ParentSearchKey; + +public class RadialStructure extends BaseRadialStructure { + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + RadialData cache = getRadialData(branch); + int numRight = cache.getNumRight(); + int[] childrenSpacings = cache.getChildrenSpacings(); + int num = subBranches.size(); + boolean right = true; + RadiationInsertion insertion = getCurrentInsertion(branch); + int insHeight = insertion == null ? 0 : insertion.getSize().height; + + int y = -cache.getRightSumSpacing() / 2; + if (insertion != null && insertion.right) { + y -= insHeight / 2; + } + + Point ref = info.getReference(); + for (int i = 0; i < num; i++) { + if (i == numRight) { + y = -cache.getLeftSumSpacing() / 2; + if (insertion != null && !insertion.right) { + y -= insHeight / 2; + } + right = false; + } + + if (insertion != null && i == insertion.getIndex()) { + if (i != numRight || !insertion.right) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + y += insHeight; + } + } + + IBranchPart subBranch = subBranches.get(i); + Rectangle r; + Dimension offset = getOffset(subBranch); + IFigure subFigure = subBranch.getFigure(); + if (offset != null && subFigure instanceof IReferencedFigure) { + Point subRef = ref.getTranslated(offset); + r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); + } else { + int x = cache.getX(y, right); + Point subRef = ref.getTranslated(x, y); + r = RadialUtils.getPrefBounds(subBranch, subRef, right); + } + info.put(subFigure, r); + y += childrenSpacings[i]; + + if (insertion != null) { + if ((i == numRight - 1 && insertion.getIndex() == numRight && insertion.right) + || i == num) { + Point p = ref.getTranslated(cache.getX(y, right), y); + Rectangle insBounds = RadialUtils.getPrefBounds( + insertion.getSize(), p, right); + info.add(insBounds); + y += insHeight; + } + } + } + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() >= numFirst) { + return branch.getTopicPart(); + } + } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + int numFirst = getRadialData(branch).getNumRight(); + if (sourceChild.getBranchIndex() < numFirst) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + return super.getSummaryDirection(branch, summary); + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + RadialData cache = getRadialData(branch); + + int subSize = subBranches.size(); + int right = cache.getNumRight(); + + Dimension inventSize = key.getInvent().getSize(); + if (index == oldIndex) { + if (subSize > right && index == right - 1 + && key.getCursorPos().x < 0 + && (!subBranches.get(right).getFigure().isEnabled())) + index += 1; + int delta = getTopicSize(subBranches.get(index)).width / 2 + - inventSize.width / 2; + int deltaX = index < right ? -delta : delta; + return getReference(subBranches.get(index)) + .getTranslated(deltaX, 0); + } + return calcInsertPosition(branch, child, key); + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + Point firstLoc = calcFirstChildPosition(branch, key).getTranslated( + key.getInvent().getSize().width / 2, 0); + if (subBranches.isEmpty()) + return firstLoc; + + int index = calcInsIndex(branch, key, true); + RadialData cache = getRadialData(branch); + + int subSize = subBranches.size(); + int right = cache.getNumRight(); + int left = subSize - right; + + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + IBranchPart first = subBranches.get(0); + Rectangle fBounds = first.getFigure().getBounds(); + + if (index == 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == subSize || index == -1) { + if (subSize == 1 && isWithinThreshold(first)) { + if (fBounds.bottom() > 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.bottom() + + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + return new Point(firstLoc.x, -firstLoc.y); + } + + if (left == 0) + return new Point(-firstLoc.x, firstLoc.y); + + IBranchPart sub = subBranches.get(subSize - 1); + Rectangle bounds = sub.getFigure().getBounds(); + if (left == 1 && bounds.bottom() < 0) + return firstLoc.getNegated(); + + int x = bounds.right() - inventSize.width / 2; + int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (index == right) { + boolean isRight = (left == 1 && right == 1) + || isRight(subBranches, child, right); + IBranchPart sub = isRight ? subBranches.get(index - 1) + : subBranches.get(index); + Rectangle bounds = sub.getFigure().getBounds(); + int x; + int y; + if (isRight) { + x = bounds.x + inventSize.width / 2; + y = bounds.bottom() + (insSize.height + inventSize.height) / 2; + } else { + x = bounds.right() - inventSize.width / 2; + y = bounds.y - (insSize.height + inventSize.height) / 2; + } + return new Point(x, y); + } + + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index), key, index < right); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightStructure.java index d92b78863..4a87fb7af 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class RightStructure extends LeftRightStructure { - - public RightStructure() { - super(false); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class RightStructure extends LeftRightStructure { + + public RightStructure() { + super(false); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightTreeStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightTreeStructure.java index b6e997cf6..bc7ad9c09 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightTreeStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/RightTreeStructure.java @@ -1,21 +1,21 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class RightTreeStructure extends TreeStructure { - public RightTreeStructure() { - super(false); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class RightTreeStructure extends TreeStructure { + public RightTreeStructure() { + super(false); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineBranchHook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineBranchHook.java index c768ba5d3..eaa4edebb 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineBranchHook.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineBranchHook.java @@ -1,90 +1,96 @@ -package org.xmind.ui.internal.branch; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IDecoratedFigure; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IPartListener; -import org.xmind.gef.part.PartEvent; -import org.xmind.ui.branch.IBranchHook; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IRangeListener; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.RangeEvent; - -public class TimelineBranchHook implements IBranchHook, - FigureListener, IPartListener, IRangeListener { - - private IBranchPart branch; - - public void hook(IBranchPart branch) { - this.branch = branch; - - branch.getFigure().addFigureListener(this); - branch.addPartListener(this); - - for (IBoundaryPart b : branch.getBoundaries()) - b.addRangeListener(this); - - for (ISummaryPart s : branch.getSummaries()) - s.addRangeListener(this); - } - - public void unhook(IBranchPart branch) { - for (IBoundaryPart b : branch.getBoundaries()) { - b.removeRangeListener(this); - } - for (ISummaryPart s : branch.getSummaries()) { - s.removeRangeListener(this); - } - branch.removePartListener(this); - branch.getFigure().removeFigureListener(this); - updateSubBranches(branch); - } - - private void updateSubBranches(IBranchPart branch) { - for (IBranchPart subBranch : branch.getSubBranches()) { - flushChildStructureType(subBranch); - subBranch.treeUpdate(false); - } - } - - private void flushChildStructureType(IBranchPart subBranch) { - subBranch.getBranchPolicy().flushStructureCache(subBranch, false, true); - } - - public void rangeChanged(RangeEvent event) { - updateSubBranches(branch); - } - - public void childAdded(PartEvent event) { - if (event.child instanceof IBranchPart) { - updateSubBranches(branch); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - updateSubBranches(branch); - ((IBranchRangePart) event.child).addRangeListener(this); - } - } - - public void childRemoving(PartEvent event) { - if (event.child instanceof IBranchPart) { - updateSubBranches(branch); - } else if (event.child instanceof ISummaryPart - || event.child instanceof IBoundaryPart) { - updateSubBranches(branch); - ((IBranchRangePart) event.child).removeRangeListener(this); - } - } - - public void figureMoved(IFigure source) { - IDecoration decoration = ((IDecoratedFigure) branch.getFigure()) - .getDecoration(); - if (decoration != null) { - decoration.invalidate(); - } - } - -} +package org.xmind.ui.internal.branch; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IDecoratedFigure; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IPartListener2; +import org.xmind.gef.part.PartEvent; +import org.xmind.ui.branch.IBranchHook; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IRangeListener; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.RangeEvent; + +public class TimelineBranchHook + implements IBranchHook, FigureListener, IPartListener2, IRangeListener { + + private IBranchPart branch; + + public void hook(IBranchPart branch) { + this.branch = branch; + + branch.getFigure().addFigureListener(this); + branch.addPartListener(this); + + for (IBoundaryPart b : branch.getBoundaries()) + b.addRangeListener(this); + + for (ISummaryPart s : branch.getSummaries()) + s.addRangeListener(this); + } + + public void unhook(IBranchPart branch) { + for (IBoundaryPart b : branch.getBoundaries()) { + b.removeRangeListener(this); + } + for (ISummaryPart s : branch.getSummaries()) { + s.removeRangeListener(this); + } + branch.removePartListener(this); + branch.getFigure().removeFigureListener(this); + updateSubBranches(branch); + } + + private void updateSubBranches(IBranchPart branch) { + for (IBranchPart subBranch : branch.getSubBranches()) { + flushChildStructureType(subBranch); + subBranch.treeUpdate(false); + } + } + + private void flushChildStructureType(IBranchPart subBranch) { + subBranch.getBranchPolicy().flushStructureCache(subBranch, false, true); + } + + public void rangeChanged(RangeEvent event) { + updateSubBranches(branch); + } + + public void childAdding(PartEvent event) { + } + + public void childAdded(PartEvent event) { + if (event.child instanceof IBranchPart) { + updateSubBranches(branch); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + updateSubBranches(branch); + ((IBranchRangePart) event.child).addRangeListener(this); + } + } + + public void childRemoving(PartEvent event) { + } + + public void childRemoved(PartEvent event) { + if (event.child instanceof IBranchPart) { + updateSubBranches(branch); + } else if (event.child instanceof ISummaryPart + || event.child instanceof IBoundaryPart) { + updateSubBranches(branch); + ((IBranchRangePart) event.child).removeRangeListener(this); + } + } + + public void figureMoved(IFigure source) { + IDecoration decoration = ((IDecoratedFigure) branch.getFigure()) + .getDecoration(); + if (decoration != null) { + decoration.invalidate(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalData.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalData.java index e96124b45..57a3444b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalData.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalData.java @@ -1,48 +1,48 @@ -package org.xmind.ui.internal.branch; - -import java.util.HashSet; -import java.util.Set; - -import org.xmind.ui.branch.BranchStructureData; -import org.xmind.ui.mindmap.IBranchPart; - -public class TimelineHorizontalData extends BranchStructureData { - - private Set upwardBranch = null; - - public TimelineHorizontalData(IBranchPart branch) { - super(branch); - } - - public boolean isUpwardBranch(int index) { - return getUpwardBranch().contains(index); - } - - public Set getUpwardBranch() { - if (upwardBranch == null) - upwardBranch = calcUpwardBranchs(); - return upwardBranch; - } - - private Set calcUpwardBranchs() { - Set set = new HashSet(); - int i = 0; - IBranchPart lastChild = null; - boolean upwards = true; - for (IBranchPart sub : getBranch().getSubBranches()) { - if (lastChild == null) { - set.add(i); - } else { - if (!isInSameRange(lastChild, sub)) - upwards = !upwards; - - if (upwards) - set.add(i); - } - lastChild = sub; - i++; - } - return set; - } - -} +package org.xmind.ui.internal.branch; + +import java.util.HashSet; +import java.util.Set; + +import org.xmind.ui.branch.BranchStructureData; +import org.xmind.ui.mindmap.IBranchPart; + +public class TimelineHorizontalData extends BranchStructureData { + + private Set upwardBranch = null; + + public TimelineHorizontalData(IBranchPart branch) { + super(branch); + } + + public boolean isUpwardBranch(int index) { + return getUpwardBranch().contains(index); + } + + public Set getUpwardBranch() { + if (upwardBranch == null) + upwardBranch = calcUpwardBranchs(); + return upwardBranch; + } + + private Set calcUpwardBranchs() { + Set set = new HashSet(); + int i = 0; + IBranchPart lastChild = null; + boolean upwards = true; + for (IBranchPart sub : getBranch().getSubBranches()) { + if (lastChild == null) { + set.add(i); + } else { + if (!isInSameRange(lastChild, sub)) + upwards = !upwards; + + if (upwards) + set.add(i); + } + lastChild = sub; + i++; + } + return set; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalDownStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalDownStructure.java index fede40eb9..3d5bebf90 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalDownStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalDownStructure.java @@ -1,10 +1,10 @@ -package org.xmind.ui.internal.branch; - -public class TimelineHorizontalDownStructure extends - TimelineHorizontalStructure { - - public TimelineHorizontalDownStructure() { - super(false); - } - -} +package org.xmind.ui.internal.branch; + +public class TimelineHorizontalDownStructure extends + TimelineHorizontalStructure { + + public TimelineHorizontalDownStructure() { + super(false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalHeadStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalHeadStructure.java index 0eae73dde..69c3271b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalHeadStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalHeadStructure.java @@ -1,364 +1,364 @@ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.ReferencedLayoutData; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.draw2d.geometry.VerticalFlipper; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -public class TimelineHorizontalHeadStructure extends AbstractBranchStructure { - - private ITransformer t = new VerticalFlipper(); - - protected void addExtraSpaces(IBranchPart branch, - ReferencedLayoutData data) { - super.addExtraSpaces(branch, data); - } - - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - int y = ref.y; - - Rectangle topicBounds = info.getCheckedClientArea(); - int x = topicBounds.right(); - - IFigure pmFigure = plusMinus.getFigure(); - Dimension size = pmFigure.getPreferredSize(); - Rectangle r = new Rectangle(x, y - size.height / 2, size.width, - size.height); - info.put(pmFigure, r); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - int majorSpacing = getMajorSpacing(branch); - int minorSpacing = getMinorSpacing(branch); - - Point ref = info.getReference(); - t.setOrigin(ref); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = t.tr(refBounds); - - int y = ref.y; - int x = refBounds.right() + majorSpacing; - - int num = subBranches.size(); - - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - - TimelineHorizontalData thd = getCastedData(branch); - - int xUpBefore = x; - int xDownBefore = x; - int xUp = x; - int xDown = x; - for (int i = 0; i < num; i++) { - t.setEnabled(thd.isUpwardBranch(i)); - if (thd.isUpwardBranch(i)) { - x = xUp > xDownBefore + majorSpacing ? xUp - : xDownBefore + majorSpacing; - } else { - x = xDown > xUpBefore + majorSpacing ? xDown - : xUpBefore + majorSpacing; - } - - if (insertion != null && i == insertion.getIndex()) { - Rectangle r = insertion.createRectangle(x, - y - insertion.getSize().height / 2); - info.add(t.rr(r)); - x += r.width + majorSpacing; - } - IBranchPart subBranch = subBranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - Insets ins = helper.getInsets(subBranch); - - Dimension size = subBranchFigure.getPreferredSize(); - IFigure topicFigure = subBranch.getTopicPart().getFigure(); - Dimension topicSize = topicFigure.getSize(); - int infoHeight = 0; - IInfoPart infoPart = subBranch.getInfoPart(); - if (infoPart != null) { - infoHeight = infoPart.getFigure().getSize().height; - } - int dy = topicSize.height == 0 ? size.height / 2 - : thd.isUpwardBranch(i) ? topicSize.height / 2 + infoHeight - : topicSize.height / 2; - Rectangle r = new Rectangle(x + ins.left, y - dy, size.width, - size.height); - info.put(subBranchFigure, t.rr(r)); - - if (thd.isUpwardBranch(i)) { - xUpBefore = x + topicFigure.getPreferredSize().width - + majorSpacing; - xUp = x + size.width + ins.getWidth() + minorSpacing; - } else { - xDownBefore = x + topicFigure.getPreferredSize().width - + majorSpacing; - xDown = x + size.width + ins.getWidth() + minorSpacing; - } - } - - if (insertion != null && num == insertion.getIndex()) { - Dimension insSize = insertion.getSize(); - if (insSize != null) { - Rectangle r = new Rectangle(x, y - insSize.height / 2, - insSize.width, insSize.height); - info.add(t.rr(r)); - } - } - } - - @Override - protected Object createStructureData(IBranchPart branch) { - return new TimelineHorizontalData(branch); - } - - @Override - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return super.isValidStructureData(branch, data) - && (data instanceof TimelineHorizontalData); - } - - private TimelineHorizontalData getCastedData(IBranchPart branch) { - return (TimelineHorizontalData) super.getStructureData(branch); - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (getCastedData(branch) - .isUpwardBranch(sourceChild.getBranchIndex())) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return branch.getTopicPart(); - } - } else { - if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - @Override - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (!branch.getSubBranches().isEmpty()) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) - return getSubTopicPart(branch, 0); - } - - return super.calcNavigation(branch, navReqType); - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - IReferencedFigure topicFigure = (IReferencedFigure) branch - .getTopicPart().getFigure(); - Point ref = topicFigure.getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Rectangle topicBounds = t.tr(topicFigure.getBounds()); - List subBranches = branch.getSubBranches(); - int totalWidth = 0; - if (!subBranches.isEmpty()) { - int fx = subBranches.get(0).getFigure().getBounds().x; - int lx = subBranches.get(subBranches.size() - 1).getFigure() - .getBounds().right(); - int slx = 0; - if (subBranches.size() > 1) - slx = subBranches.get(subBranches.size() - 2).getFigure() - .getBounds().right(); - totalWidth = lx > slx ? lx - fx : slx - lx; - } - int dy = childRef.y - topicBounds.bottom(); - int dx = childRef.x - topicBounds.right(); - if (childRef.y >= topicBounds.y - MindMapUI.SEARCH_RANGE / 2 - && childRef.y < topicBounds.bottom() - + MindMapUI.SEARCH_RANGE / 2) { - if (dx > 0 && dx < totalWidth + MindMapUI.SEARCH_RANGE) { - return dx; - } - int d = dx * dx + dy * dy; - return d; - } - return super.calcChildDistance(branch, key); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - IFigure topicFigure = topic.getFigure(); - Point ref = ((IReferencedFigure) topicFigure).getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - List subBranches = branch.getSubBranches(); - - int x = childRef.x - ref.x; - int ret = 0; - for (IBranchPart sub : subBranches) { - IFigure tf = sub.getTopicPart().getFigure(); - Point tr = ((IReferencedFigure) tf).getReference(); - int d = tr.x - ref.x; - if (x < d) - return ret; - ret++; - } - return withDisabled ? subBranches.size() : -1; - } - - private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize().scale(0.8); - } - - public int getSourceOrientation(IBranchPart branch) { - return PositionConstants.EAST; - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return PositionConstants.WEST; - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return new Insertion(branch, calcInsIndex(branch, key, true), - calcInsSize(branch, key)); - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.EAST; - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - List enclosingBranches = summary.getEnclosingBranches(); - if (!enclosingBranches.isEmpty()) { - IBranchPart sub = enclosingBranches.get(0); - if (getCastedData(branch).isUpwardBranch(sub.getBranchIndex())) - return PositionConstants.NORTH; - return PositionConstants.SOUTH; - } - return PositionConstants.NORTH; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.EAST) - return 1; - if (direction == PositionConstants.WEST) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - int majorSpacing = getMajorSpacing(branch); - int index = calcInsIndex(branch, key, true); - Dimension insSize = key.getFigure().getSize(); - - int y = getFigureLocation(branch.getFigure()).y; - if (index < 2 && index != subBranches.size()) { - IBranchPart sub = subBranches.get(index); - Rectangle bounds = sub.getFigure().getBounds(); - int x = bounds.x - majorSpacing - insSize.width / 2; - return new Point(x, y); - } - - if (index == subBranches.size()) { - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getTopicPart().getFigure().getBounds(); - int x = bounds.right() + majorSpacing + insSize.width / 2; - return new Point(x, y); - } - - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index - 2), key, true); - } - - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - return getFigureLocation(sub.getFigure()).getTranslated(0, 0); - } - - return calcInsertPosition(branch, child, key); - } - - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - Point loc = getFigureLocation(branch.getFigure()); - return loc.getTranslated(branch.getFigure().getPreferredSize().width - + getMajorSpacing(branch), 0); - } - - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { - Dimension insSize = key.getFigure().getSize(); - int minorSpacing = getMinorSpacing(orientation.getParentBranch()); - int majorSpacing = getMajorSpacing(orientation.getParentBranch()); - - int x1 = assist.getFigure().getBounds().right() + minorSpacing; - int x2 = orientation.getTopicPart().getFigure().getBounds().right() - + majorSpacing; - - return new Point( - x1 > x2 ? x1 + insSize.width / 2 : x2 + insSize.width / 2, - getFigureLocation(orientation.getFigure()).y); - } - - public boolean isChildUpwards(IBranchPart branch, IBranchPart child) { - return getCastedData(branch).isUpwardBranch(child.getBranchIndex()); - } -} +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.ReferencedLayoutData; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.draw2d.geometry.VerticalFlipper; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IInfoPart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +public class TimelineHorizontalHeadStructure extends AbstractBranchStructure { + + private ITransformer t = new VerticalFlipper(); + + protected void addExtraSpaces(IBranchPart branch, + ReferencedLayoutData data) { + super.addExtraSpaces(branch, data); + } + + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + int y = ref.y; + + Rectangle topicBounds = info.getCheckedClientArea(); + int x = topicBounds.right(); + + IFigure pmFigure = plusMinus.getFigure(); + Dimension size = pmFigure.getPreferredSize(); + Rectangle r = new Rectangle(x, y - size.height / 2, size.width, + size.height); + info.put(pmFigure, r); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + int majorSpacing = getMajorSpacing(branch); + int minorSpacing = getMinorSpacing(branch); + + Point ref = info.getReference(); + t.setOrigin(ref); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = t.tr(refBounds); + + int y = ref.y; + int x = refBounds.right() + majorSpacing; + + int num = subBranches.size(); + + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + + TimelineHorizontalData thd = getCastedData(branch); + + int xUpBefore = x; + int xDownBefore = x; + int xUp = x; + int xDown = x; + for (int i = 0; i < num; i++) { + t.setEnabled(thd.isUpwardBranch(i)); + if (thd.isUpwardBranch(i)) { + x = xUp > xDownBefore + majorSpacing ? xUp + : xDownBefore + majorSpacing; + } else { + x = xDown > xUpBefore + majorSpacing ? xDown + : xUpBefore + majorSpacing; + } + + if (insertion != null && i == insertion.getIndex()) { + Rectangle r = insertion.createRectangle(x, + y - insertion.getSize().height / 2); + info.add(t.rr(r)); + x += r.width + majorSpacing; + } + IBranchPart subBranch = subBranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + Insets ins = helper.getInsets(subBranch); + + Dimension size = subBranchFigure.getPreferredSize(); + IFigure topicFigure = subBranch.getTopicPart().getFigure(); + Dimension topicSize = topicFigure.getSize(); + int infoHeight = 0; + IInfoPart infoPart = subBranch.getInfoPart(); + if (infoPart != null) { + infoHeight = infoPart.getFigure().getSize().height; + } + int dy = topicSize.height == 0 ? size.height / 2 + : thd.isUpwardBranch(i) ? topicSize.height / 2 + infoHeight + : topicSize.height / 2; + Rectangle r = new Rectangle(x + ins.left, y - dy, size.width, + size.height); + info.put(subBranchFigure, t.rr(r)); + + if (thd.isUpwardBranch(i)) { + xUpBefore = x + topicFigure.getPreferredSize().width + + majorSpacing; + xUp = x + size.width + ins.getWidth() + minorSpacing; + } else { + xDownBefore = x + topicFigure.getPreferredSize().width + + majorSpacing; + xDown = x + size.width + ins.getWidth() + minorSpacing; + } + } + + if (insertion != null && num == insertion.getIndex()) { + Dimension insSize = insertion.getSize(); + if (insSize != null) { + Rectangle r = new Rectangle(x, y - insSize.height / 2, + insSize.width, insSize.height); + info.add(t.rr(r)); + } + } + } + + @Override + protected Object createStructureData(IBranchPart branch) { + return new TimelineHorizontalData(branch); + } + + @Override + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return super.isValidStructureData(branch, data) + && (data instanceof TimelineHorizontalData); + } + + private TimelineHorizontalData getCastedData(IBranchPart branch) { + return (TimelineHorizontalData) super.getStructureData(branch); + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (getCastedData(branch) + .isUpwardBranch(sourceChild.getBranchIndex())) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return branch.getTopicPart(); + } + } else { + if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + @Override + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (!branch.getSubBranches().isEmpty()) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) + return getSubTopicPart(branch, 0); + } + + return super.calcNavigation(branch, navReqType); + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + IReferencedFigure topicFigure = (IReferencedFigure) branch + .getTopicPart().getFigure(); + Point ref = topicFigure.getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Rectangle topicBounds = t.tr(topicFigure.getBounds()); + List subBranches = branch.getSubBranches(); + int totalWidth = 0; + if (!subBranches.isEmpty()) { + int fx = subBranches.get(0).getFigure().getBounds().x; + int lx = subBranches.get(subBranches.size() - 1).getFigure() + .getBounds().right(); + int slx = 0; + if (subBranches.size() > 1) + slx = subBranches.get(subBranches.size() - 2).getFigure() + .getBounds().right(); + totalWidth = lx > slx ? lx - fx : slx - lx; + } + int dy = childRef.y - topicBounds.bottom(); + int dx = childRef.x - topicBounds.right(); + if (childRef.y >= topicBounds.y - MindMapUI.SEARCH_RANGE / 2 + && childRef.y < topicBounds.bottom() + + MindMapUI.SEARCH_RANGE / 2) { + if (dx > 0 && dx < totalWidth + MindMapUI.SEARCH_RANGE) { + return dx; + } + int d = dx * dx + dy * dy; + return d; + } + return super.calcChildDistance(branch, key); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + IFigure topicFigure = topic.getFigure(); + Point ref = ((IReferencedFigure) topicFigure).getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + List subBranches = branch.getSubBranches(); + + int x = childRef.x - ref.x; + int ret = 0; + for (IBranchPart sub : subBranches) { + IFigure tf = sub.getTopicPart().getFigure(); + Point tr = ((IReferencedFigure) tf).getReference(); + int d = tr.x - ref.x; + if (x < d) + return ret; + ret++; + } + return withDisabled ? subBranches.size() : -1; + } + + private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize().scale(0.8); + } + + public int getSourceOrientation(IBranchPart branch) { + return PositionConstants.EAST; + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return PositionConstants.WEST; + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return new Insertion(branch, calcInsIndex(branch, key, true), + calcInsSize(branch, key)); + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.EAST; + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + List enclosingBranches = summary.getEnclosingBranches(); + if (!enclosingBranches.isEmpty()) { + IBranchPart sub = enclosingBranches.get(0); + if (getCastedData(branch).isUpwardBranch(sub.getBranchIndex())) + return PositionConstants.NORTH; + return PositionConstants.SOUTH; + } + return PositionConstants.NORTH; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.EAST) + return 1; + if (direction == PositionConstants.WEST) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + int majorSpacing = getMajorSpacing(branch); + int index = calcInsIndex(branch, key, true); + Dimension insSize = key.getFigure().getSize(); + + int y = getFigureLocation(branch.getFigure()).y; + if (index < 2 && index != subBranches.size()) { + IBranchPart sub = subBranches.get(index); + Rectangle bounds = sub.getFigure().getBounds(); + int x = bounds.x - majorSpacing - insSize.width / 2; + return new Point(x, y); + } + + if (index == subBranches.size()) { + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getTopicPart().getFigure().getBounds(); + int x = bounds.right() + majorSpacing + insSize.width / 2; + return new Point(x, y); + } + + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index - 2), key, true); + } + + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + return getFigureLocation(sub.getFigure()).getTranslated(0, 0); + } + + return calcInsertPosition(branch, child, key); + } + + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + Point loc = getFigureLocation(branch.getFigure()); + return loc.getTranslated(branch.getFigure().getPreferredSize().width + + getMajorSpacing(branch), 0); + } + + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { + Dimension insSize = key.getFigure().getSize(); + int minorSpacing = getMinorSpacing(orientation.getParentBranch()); + int majorSpacing = getMajorSpacing(orientation.getParentBranch()); + + int x1 = assist.getFigure().getBounds().right() + minorSpacing; + int x2 = orientation.getTopicPart().getFigure().getBounds().right() + + majorSpacing; + + return new Point( + x1 > x2 ? x1 + insSize.width / 2 : x2 + insSize.width / 2, + getFigureLocation(orientation.getFigure()).y); + } + + public boolean isChildUpwards(IBranchPart branch, IBranchPart child) { + return getCastedData(branch).isUpwardBranch(child.getBranchIndex()); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalPropertyTester.java index 564f64d74..0370d6174 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalPropertyTester.java @@ -1,36 +1,36 @@ -package org.xmind.ui.internal.branch; - -import org.eclipse.core.runtime.Assert; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.IBranchPropertyTester; -import org.xmind.ui.mindmap.IBranchPart; - -public class TimelineHorizontalPropertyTester implements IBranchPropertyTester { - - private static final String P_UPWARDS = "upwards"; //$NON-NLS-1$ - - public boolean test(IBranchPart branch, String property, Object[] args, - Object expectedValue) { - if (P_UPWARDS.equals(property)) { - if (expectedValue == null) - return isBranchLeftwards(branch); - if (expectedValue instanceof Boolean) - return ((Boolean) expectedValue).booleanValue() == isBranchLeftwards(branch); - } - Assert.isTrue(false); - return false; - } - - private boolean isBranchLeftwards(IBranchPart branch) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - IStructure sa = parent.getBranchPolicy().getStructure(parent); - if (sa instanceof TimelineHorizontalHeadStructure) { - return ((TimelineHorizontalHeadStructure) sa).isChildUpwards( - parent, branch); - } - } - return false; - } - -} +package org.xmind.ui.internal.branch; + +import org.eclipse.core.runtime.Assert; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.IBranchPropertyTester; +import org.xmind.ui.mindmap.IBranchPart; + +public class TimelineHorizontalPropertyTester implements IBranchPropertyTester { + + private static final String P_UPWARDS = "upwards"; //$NON-NLS-1$ + + public boolean test(IBranchPart branch, String property, Object[] args, + Object expectedValue) { + if (P_UPWARDS.equals(property)) { + if (expectedValue == null) + return isBranchLeftwards(branch); + if (expectedValue instanceof Boolean) + return ((Boolean) expectedValue).booleanValue() == isBranchLeftwards(branch); + } + Assert.isTrue(false); + return false; + } + + private boolean isBranchLeftwards(IBranchPart branch) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + IStructure sa = parent.getBranchPolicy().getStructure(parent); + if (sa instanceof TimelineHorizontalHeadStructure) { + return ((TimelineHorizontalHeadStructure) sa).isChildUpwards( + parent, branch); + } + } + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalStructure.java index cda6445a9..11bf28507 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalStructure.java @@ -1,404 +1,404 @@ -package org.xmind.ui.internal.branch; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.draw2d.geometry.HorizontalFlipper; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.decorations.IBranchConnectionDecoration; -import org.xmind.ui.decorations.IBranchConnections2; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -public class TimelineHorizontalStructure extends AbstractBranchStructure { - - private ITransformer t = new HorizontalFlipper(); - - private boolean upwards; - - public TimelineHorizontalStructure(boolean upwards) { - this.upwards = upwards; - } - - @Override - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - t.setOrigin(ref); - - Rectangle topicBounds = info.getCheckedClientArea(); - topicBounds = t.tr(topicBounds); - - IFigure pmFigure = plusMinus.getFigure(); - Dimension size = pmFigure.getPreferredSize(); - int x = ref.x - size.width / 2; - int y = isUpwards(branch) ? topicBounds.y() - size.height - : topicBounds.bottom(); - Rectangle r = new Rectangle(x, y, size.width, size.height); - info.put(pmFigure, r); - } - - @Override - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - int majorSpacing = getMajorSpacing(branch); - int minorSpacing = getMinorSpacing(branch); - Point ref = info.getReference(); - t.setOrigin(ref); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = t.tr(refBounds); - - int x = ref.x + majorSpacing; - - int totalHeight = calcTotalChildrenHeight(branch, minorSpacing, true); - int y = isUpwards(branch) ? refBounds.y() - totalHeight - majorSpacing - : refBounds.bottom() + majorSpacing; - - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - int num = subBranches.size(); - for (int i = 0; i < num; i++) { - if (insertion != null && i == insertion.getIndex()) { - Rectangle r = insertion.createRectangle(x, y); - info.add(r); - y += r.height + minorSpacing; - } - IBranchPart subBranch = subBranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - Insets ins = helper.getInsets(subBranch); - Dimension size = subBranchFigure.getPreferredSize(); - Rectangle r = new Rectangle(x + ins.left, - y + (isUpwards(subBranch) ? ins.bottom : ins.top), - size.width, size.height); - info.put(subBranchFigure, r); - y += size.height + ins.getHeight() + minorSpacing; - } - - if (insertion != null && num == insertion.getIndex()) { - Dimension insSize = insertion.getSize(); - if (insSize != null) { - Rectangle r = new Rectangle(x, y, insSize.width, - insSize.height); - info.add(r); - } - } - - } - - protected void doFillCalloutBranches(IBranchPart branch, - List calloutBranches, LayoutInfo info) { - if (branch.isCentral()) { - for (IBranchPart calloutBranch : calloutBranches) { - calloutBranch.getFigure().setVisible(false); - } - IBranchConnections2 calloutConnections = branch - .getCalloutConnections(); - for (int index = 0; index < calloutBranches.size(); index++) { - IDecoration decoration = calloutConnections - .getDecoration(index); - if (decoration instanceof IBranchConnectionDecoration) { - ((IBranchConnectionDecoration) decoration) - .setVisible(branch.getFigure(), false); - } - } - return; - } - - IBranchPart parentBranch = branch.getParentBranch(); - int orientation = getChildTargetOrientation(parentBranch, branch); - boolean left = PositionConstants.EAST == orientation; - boolean right = PositionConstants.WEST == orientation; - boolean south = PositionConstants.NORTH == orientation; - boolean north = PositionConstants.SOUTH == orientation; - - for (IBranchPart calloutBranch : calloutBranches) { - Rectangle parentTopicArea = info - .get(branch.getTopicPart().getFigure()); - Rectangle parentBranchArea = info.getCheckedClientArea(); - - IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch - .getFigure(); - - ITopicPart calloutPart = calloutBranch.getTopicPart(); - if (calloutPart == null) - continue; - IFigure calloutFigure = calloutPart.getFigure(); - Dimension calloutSize = calloutFigure.getPreferredSize(); - - //over parent topic center - org.xmind.core.util.Point position = calloutBranch.getTopic() - .getPosition(); - if (position == null) - position = new org.xmind.core.util.Point(); - boolean originPosition = position.x == 0 && position.y == 0; - - int offsetX = originPosition ? 0 : position.x; - int offsetY = originPosition - ? -calloutSize.height / 2 - parentTopicArea.height / 2 - 10 - : position.y; - - boolean upDown = offsetY < 0; - - int dummyCalloutX = parentTopicArea.getCenter().x + offsetX - - calloutSize.width / 2; - - if (left) { - //limit left movable boundary - int dx = (dummyCalloutX + calloutSize.width) - - (parentTopicArea.x + parentTopicArea.width); - offsetX = dx > 0 ? offsetX - dx : offsetX; - } else if (right) { - //limit right movable boundary - int dx = dummyCalloutX - parentTopicArea.x; - offsetX = dx < 0 ? offsetX - dx : offsetX; - } - - Point reference = info.getReference(); - Point translated = reference.getTranslated(offsetX, offsetY); - Rectangle bounds = calloutBranchFigure - .getPreferredBounds(translated); - - int subRectX = left || south || north ? parentBranchArea.x - : parentBranchArea.x + parentTopicArea.width; - int subRectY = left || right || north ? parentBranchArea.y - : parentBranchArea.y + parentTopicArea.height; - int subRectWidth = left || right - ? parentBranchArea.width - parentTopicArea.width - : parentBranchArea.width; - int subRectHeight = left || right ? parentBranchArea.height - : parentBranchArea.height - parentTopicArea.height; - Rectangle subRect = new Rectangle(subRectX, subRectY, subRectWidth, - subRectHeight); - boolean touchSub = subRect.touches(bounds); - boolean touchParentTopic = bounds.touches(parentTopicArea); - if (touchSub) { - int y = upDown ? subRect.y - bounds.height - 10 - : subRect.bottom() + 10; - bounds.setY(y); - } else if (touchParentTopic) { - int y = upDown ? parentTopicArea.y - bounds.height - 10 - : parentTopicArea.bottom() + 10; - bounds.setY(y); - } - - int y = isUpwards(branch) - ? Math.min(parentBranchArea.y, - bounds.bottom()) - - calloutBranch.getFigure().getPreferredSize().height - : Math.max(parentBranchArea.bottom(), bounds.y); - bounds.setY(y); - - info.put(calloutBranchFigure, bounds); - } - } - - private int calcTotalChildrenHeight(IBranchPart branch, int minorSpacing, - boolean withInsertion) { - int totalHeight = 0; - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - Iterator it = branch.getSubBranches().iterator(); - while (it.hasNext()) { - IBranchPart subBranch = it.next(); - totalHeight += subBranch.getFigure().getPreferredSize().height - + helper.getInsets(subBranch).getHeight(); - if (it.hasNext()) - totalHeight += minorSpacing; - } - if (withInsertion) { - IInsertion ins = getCurrentInsertion(branch); - if (ins != null) { - Dimension insSize = ins.getSize(); - if (insSize != null) - totalHeight += minorSpacing + insSize.height; - } - } - return totalHeight; - } - - public int getSourceOrientation(IBranchPart branch) { - if (isUpwards(branch)) - return PositionConstants.NORTH; - return PositionConstants.SOUTH; - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return PositionConstants.WEST; - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (!branch.getSubBranches().isEmpty()) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) - return getSubTopicPart(branch, 0); - } - return super.calcNavigation(branch, navReqType); - - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return branch.getTopicPart(); - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - @Override - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - IFigure branchFigure = branch.getFigure(); - IReferencedFigure topicFigure = (IReferencedFigure) branch - .getTopicPart().getFigure(); - Point ref = topicFigure.getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Rectangle branchBounds = t.tr(branchFigure.getBounds()); - Rectangle topicBounds = t.tr(topicFigure.getBounds()); - Rectangle childBounds = t.tr(key.getFigure().getBounds()); - int dx = childRef.x - ref.x; - int dy = isUpwards(branch) ? topicBounds.y() - childRef.y - : childRef.y - topicBounds.bottom(); - if (dy > 0 && childBounds.x <= ref.x) { - if (childRef.x < branchBounds.right() - + MindMapUI.SEARCH_RANGE / 2) { - return Math.abs(dx) + Math.abs(dy); - } - int d = dx * dx + dy * dy; - return d; - } - return super.calcChildDistance(branch, key); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - IFigure topicFigure = topic.getFigure(); - Point ref = ((IReferencedFigure) topicFigure).getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Dimension insSize = calcInsSize(key.getFigure()); - int insHeight = insSize.height; - int minorSpacing = getMinorSpacing(branch); - Rectangle topicBounds = t.t(topicFigure.getBounds()); - int y = 0; - if (isUpwards(branch)) { - y = topicBounds.y(); - if (!branch.getSubBranches().isEmpty()) { - IPlusMinusPart pm = branch.getPlusMinus(); - if (pm != null) - y -= pm.getFigure().getSize().height; - - y -= calcTotalChildrenHeight(branch, minorSpacing, true); - } - } else { - y = topicBounds.bottom(); - if (!branch.getSubBranches().isEmpty()) { - IPlusMinusPart plusMinus = branch.getPlusMinus(); - if (plusMinus != null) { - y += plusMinus.getFigure().getSize().height; - } - } - } - int ret = calcInsIndex(branch, y, childRef, insHeight, minorSpacing, - withDisabled); - return ret; - } - - private int calcInsIndex(IBranchPart branch, int startY, Point childRef, - int insHeight, int spacing, boolean withDisabled) { - int ret = 0; - int sum = 0; - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - for (IBranchPart subBranch : subBranches) { - IFigure subFigure = subBranch.getFigure(); - int h = getBorderedSize(branch, subBranch).height; - int hint = startY + sum + (insHeight + h + spacing) / 2; - if (childRef.y < hint) { - return ret; - } - sum += h + spacing; - if (withDisabled || subFigure.isEnabled()) - ret++; - } - return withDisabled ? num : -1; - } - - private Dimension calcInsSize(IReferencedFigure child) { - return child.getSize().scale(0.8); - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - int newIndex = calcInsIndex(branch, key, true); - Dimension newSize = calcInsSize(key.getFigure()); - return new Insertion(branch, newIndex, newSize); - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - return PositionConstants.EAST; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - if (isUpwards(branch)) - return PositionConstants.NORTH; - return PositionConstants.SOUTH; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.SOUTH) - return 1; - if (direction == PositionConstants.NORTH) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - @Override - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int x = getMajorSpacing(branch) + key.getInvent().getSize().width / 2; - int y = branch.getFigure().getSize().height / 2 - + getMajorSpacing(branch) - + key.getFigure().getSize().height / 2; - return getFigureLocation(branch.getFigure()).getTranslated(x, - isUpwards(branch) ? -y : y); - } - - private boolean isUpwards(IBranchPart branch) { - return upwards; - } - -} +package org.xmind.ui.internal.branch; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.draw2d.geometry.HorizontalFlipper; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.decorations.IBranchConnectionDecoration; +import org.xmind.ui.decorations.IBranchConnections2; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +public class TimelineHorizontalStructure extends AbstractBranchStructure { + + private ITransformer t = new HorizontalFlipper(); + + private boolean upwards; + + public TimelineHorizontalStructure(boolean upwards) { + this.upwards = upwards; + } + + @Override + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + t.setOrigin(ref); + + Rectangle topicBounds = info.getCheckedClientArea(); + topicBounds = t.tr(topicBounds); + + IFigure pmFigure = plusMinus.getFigure(); + Dimension size = pmFigure.getPreferredSize(); + int x = ref.x - size.width / 2; + int y = isUpwards(branch) ? topicBounds.y() - size.height + : topicBounds.bottom(); + Rectangle r = new Rectangle(x, y, size.width, size.height); + info.put(pmFigure, r); + } + + @Override + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + int majorSpacing = getMajorSpacing(branch); + int minorSpacing = getMinorSpacing(branch); + Point ref = info.getReference(); + t.setOrigin(ref); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = t.tr(refBounds); + + int x = ref.x + majorSpacing; + + int totalHeight = calcTotalChildrenHeight(branch, minorSpacing, true); + int y = isUpwards(branch) ? refBounds.y() - totalHeight - majorSpacing + : refBounds.bottom() + majorSpacing; + + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + int num = subBranches.size(); + for (int i = 0; i < num; i++) { + if (insertion != null && i == insertion.getIndex()) { + Rectangle r = insertion.createRectangle(x, y); + info.add(r); + y += r.height + minorSpacing; + } + IBranchPart subBranch = subBranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + Insets ins = helper.getInsets(subBranch); + Dimension size = subBranchFigure.getPreferredSize(); + Rectangle r = new Rectangle(x + ins.left, + y + (isUpwards(subBranch) ? ins.bottom : ins.top), + size.width, size.height); + info.put(subBranchFigure, r); + y += size.height + ins.getHeight() + minorSpacing; + } + + if (insertion != null && num == insertion.getIndex()) { + Dimension insSize = insertion.getSize(); + if (insSize != null) { + Rectangle r = new Rectangle(x, y, insSize.width, + insSize.height); + info.add(r); + } + } + + } + + protected void doFillCalloutBranches(IBranchPart branch, + List calloutBranches, LayoutInfo info) { + if (branch.isCentral()) { + for (IBranchPart calloutBranch : calloutBranches) { + calloutBranch.getFigure().setVisible(false); + } + IBranchConnections2 calloutConnections = branch + .getCalloutConnections(); + for (int index = 0; index < calloutBranches.size(); index++) { + IDecoration decoration = calloutConnections + .getDecoration(index); + if (decoration instanceof IBranchConnectionDecoration) { + ((IBranchConnectionDecoration) decoration) + .setVisible(branch.getFigure(), false); + } + } + return; + } + + IBranchPart parentBranch = branch.getParentBranch(); + int orientation = getChildTargetOrientation(parentBranch, branch); + boolean left = PositionConstants.EAST == orientation; + boolean right = PositionConstants.WEST == orientation; + boolean south = PositionConstants.NORTH == orientation; + boolean north = PositionConstants.SOUTH == orientation; + + for (IBranchPart calloutBranch : calloutBranches) { + Rectangle parentTopicArea = info + .get(branch.getTopicPart().getFigure()); + Rectangle parentBranchArea = info.getCheckedClientArea(); + + IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch + .getFigure(); + + ITopicPart calloutPart = calloutBranch.getTopicPart(); + if (calloutPart == null) + continue; + IFigure calloutFigure = calloutPart.getFigure(); + Dimension calloutSize = calloutFigure.getPreferredSize(); + + //over parent topic center + org.xmind.core.util.Point position = calloutBranch.getTopic() + .getPosition(); + if (position == null) + position = new org.xmind.core.util.Point(); + boolean originPosition = position.x == 0 && position.y == 0; + + int offsetX = originPosition ? 0 : position.x; + int offsetY = originPosition + ? -calloutSize.height / 2 - parentTopicArea.height / 2 - 10 + : position.y; + + boolean upDown = offsetY < 0; + + int dummyCalloutX = parentTopicArea.getCenter().x + offsetX + - calloutSize.width / 2; + + if (left) { + //limit left movable boundary + int dx = (dummyCalloutX + calloutSize.width) + - (parentTopicArea.x + parentTopicArea.width); + offsetX = dx > 0 ? offsetX - dx : offsetX; + } else if (right) { + //limit right movable boundary + int dx = dummyCalloutX - parentTopicArea.x; + offsetX = dx < 0 ? offsetX - dx : offsetX; + } + + Point reference = info.getReference(); + Point translated = reference.getTranslated(offsetX, offsetY); + Rectangle bounds = calloutBranchFigure + .getPreferredBounds(translated); + + int subRectX = left || south || north ? parentBranchArea.x + : parentBranchArea.x + parentTopicArea.width; + int subRectY = left || right || north ? parentBranchArea.y + : parentBranchArea.y + parentTopicArea.height; + int subRectWidth = left || right + ? parentBranchArea.width - parentTopicArea.width + : parentBranchArea.width; + int subRectHeight = left || right ? parentBranchArea.height + : parentBranchArea.height - parentTopicArea.height; + Rectangle subRect = new Rectangle(subRectX, subRectY, subRectWidth, + subRectHeight); + boolean touchSub = subRect.touches(bounds); + boolean touchParentTopic = bounds.touches(parentTopicArea); + if (touchSub) { + int y = upDown ? subRect.y - bounds.height - 10 + : subRect.bottom() + 10; + bounds.setY(y); + } else if (touchParentTopic) { + int y = upDown ? parentTopicArea.y - bounds.height - 10 + : parentTopicArea.bottom() + 10; + bounds.setY(y); + } + + int y = isUpwards(branch) + ? Math.min(parentBranchArea.y, + bounds.bottom()) + - calloutBranch.getFigure().getPreferredSize().height + : Math.max(parentBranchArea.bottom(), bounds.y); + bounds.setY(y); + + info.put(calloutBranchFigure, bounds); + } + } + + private int calcTotalChildrenHeight(IBranchPart branch, int minorSpacing, + boolean withInsertion) { + int totalHeight = 0; + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + Iterator it = branch.getSubBranches().iterator(); + while (it.hasNext()) { + IBranchPart subBranch = it.next(); + totalHeight += subBranch.getFigure().getPreferredSize().height + + helper.getInsets(subBranch).getHeight(); + if (it.hasNext()) + totalHeight += minorSpacing; + } + if (withInsertion) { + IInsertion ins = getCurrentInsertion(branch); + if (ins != null) { + Dimension insSize = ins.getSize(); + if (insSize != null) + totalHeight += minorSpacing + insSize.height; + } + } + return totalHeight; + } + + public int getSourceOrientation(IBranchPart branch) { + if (isUpwards(branch)) + return PositionConstants.NORTH; + return PositionConstants.SOUTH; + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return PositionConstants.WEST; + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (!branch.getSubBranches().isEmpty()) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) + return getSubTopicPart(branch, 0); + } + return super.calcNavigation(branch, navReqType); + + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return branch.getTopicPart(); + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + @Override + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + IFigure branchFigure = branch.getFigure(); + IReferencedFigure topicFigure = (IReferencedFigure) branch + .getTopicPart().getFigure(); + Point ref = topicFigure.getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Rectangle branchBounds = t.tr(branchFigure.getBounds()); + Rectangle topicBounds = t.tr(topicFigure.getBounds()); + Rectangle childBounds = t.tr(key.getFigure().getBounds()); + int dx = childRef.x - ref.x; + int dy = isUpwards(branch) ? topicBounds.y() - childRef.y + : childRef.y - topicBounds.bottom(); + if (dy > 0 && childBounds.x <= ref.x) { + if (childRef.x < branchBounds.right() + + MindMapUI.SEARCH_RANGE / 2) { + return Math.abs(dx) + Math.abs(dy); + } + int d = dx * dx + dy * dy; + return d; + } + return super.calcChildDistance(branch, key); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + IFigure topicFigure = topic.getFigure(); + Point ref = ((IReferencedFigure) topicFigure).getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Dimension insSize = calcInsSize(key.getFigure()); + int insHeight = insSize.height; + int minorSpacing = getMinorSpacing(branch); + Rectangle topicBounds = t.t(topicFigure.getBounds()); + int y = 0; + if (isUpwards(branch)) { + y = topicBounds.y(); + if (!branch.getSubBranches().isEmpty()) { + IPlusMinusPart pm = branch.getPlusMinus(); + if (pm != null) + y -= pm.getFigure().getSize().height; + + y -= calcTotalChildrenHeight(branch, minorSpacing, true); + } + } else { + y = topicBounds.bottom(); + if (!branch.getSubBranches().isEmpty()) { + IPlusMinusPart plusMinus = branch.getPlusMinus(); + if (plusMinus != null) { + y += plusMinus.getFigure().getSize().height; + } + } + } + int ret = calcInsIndex(branch, y, childRef, insHeight, minorSpacing, + withDisabled); + return ret; + } + + private int calcInsIndex(IBranchPart branch, int startY, Point childRef, + int insHeight, int spacing, boolean withDisabled) { + int ret = 0; + int sum = 0; + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + for (IBranchPart subBranch : subBranches) { + IFigure subFigure = subBranch.getFigure(); + int h = getBorderedSize(branch, subBranch).height; + int hint = startY + sum + (insHeight + h + spacing) / 2; + if (childRef.y < hint) { + return ret; + } + sum += h + spacing; + if (withDisabled || subFigure.isEnabled()) + ret++; + } + return withDisabled ? num : -1; + } + + private Dimension calcInsSize(IReferencedFigure child) { + return child.getSize().scale(0.8); + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + int newIndex = calcInsIndex(branch, key, true); + Dimension newSize = calcInsSize(key.getFigure()); + return new Insertion(branch, newIndex, newSize); + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + return PositionConstants.EAST; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + if (isUpwards(branch)) + return PositionConstants.NORTH; + return PositionConstants.SOUTH; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.SOUTH) + return 1; + if (direction == PositionConstants.NORTH) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + @Override + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int x = getMajorSpacing(branch) + key.getInvent().getSize().width / 2; + int y = branch.getFigure().getSize().height / 2 + + getMajorSpacing(branch) + + key.getFigure().getSize().height / 2; + return getFigureLocation(branch.getFigure()).getTranslated(x, + isUpwards(branch) ? -y : y); + } + + private boolean isUpwards(IBranchPart branch) { + return upwards; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalUpStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalUpStructure.java index 1dcdedbaa..c0308d60d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalUpStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineHorizontalUpStructure.java @@ -1,9 +1,9 @@ -package org.xmind.ui.internal.branch; - -public class TimelineHorizontalUpStructure extends TimelineHorizontalStructure { - - public TimelineHorizontalUpStructure() { - super(true); - } - -} +package org.xmind.ui.internal.branch; + +public class TimelineHorizontalUpStructure extends TimelineHorizontalStructure { + + public TimelineHorizontalUpStructure() { + super(true); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalData.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalData.java index 043695402..cbb6bf9ae 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalData.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalData.java @@ -1,48 +1,48 @@ -package org.xmind.ui.internal.branch; - -import java.util.HashSet; -import java.util.Set; - -import org.xmind.ui.branch.BranchStructureData; -import org.xmind.ui.mindmap.IBranchPart; - -public class TimelineVerticalData extends BranchStructureData { - - private Set rightwards = null; - - public TimelineVerticalData(IBranchPart branch) { - super(branch); - } - - public boolean isLeftwardBranch(int index) { - return !getRightwardBranch().contains(index); - } - - public Set getRightwardBranch() { - if (rightwards == null) - rightwards = calcUpwardBranchs(); - return rightwards; - } - - private Set calcUpwardBranchs() { - Set set = new HashSet(); - int i = 0; - IBranchPart lastChild = null; - boolean rightward = true; - for (IBranchPart sub : getBranch().getSubBranches()) { - if (lastChild == null) { - set.add(i); - } else { - if (!isInSameRange(lastChild, sub)) - rightward = !rightward; - - if (rightward) - set.add(i); - } - lastChild = sub; - i++; - } - return set; - } - -} +package org.xmind.ui.internal.branch; + +import java.util.HashSet; +import java.util.Set; + +import org.xmind.ui.branch.BranchStructureData; +import org.xmind.ui.mindmap.IBranchPart; + +public class TimelineVerticalData extends BranchStructureData { + + private Set rightwards = null; + + public TimelineVerticalData(IBranchPart branch) { + super(branch); + } + + public boolean isLeftwardBranch(int index) { + return !getRightwardBranch().contains(index); + } + + public Set getRightwardBranch() { + if (rightwards == null) + rightwards = calcUpwardBranchs(); + return rightwards; + } + + private Set calcUpwardBranchs() { + Set set = new HashSet(); + int i = 0; + IBranchPart lastChild = null; + boolean rightward = true; + for (IBranchPart sub : getBranch().getSubBranches()) { + if (lastChild == null) { + set.add(i); + } else { + if (!isInSameRange(lastChild, sub)) + rightward = !rightward; + + if (rightward) + set.add(i); + } + lastChild = sub; + i++; + } + return set; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalHeadStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalHeadStructure.java index 390252f51..bbc3ddc6e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalHeadStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalHeadStructure.java @@ -1,364 +1,364 @@ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.HorizontalFlipper; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -public class TimelineVerticalHeadStructure extends AbstractBranchStructure { - - private ITransformer t = new HorizontalFlipper(); - - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - int x = ref.x; - - Rectangle topicBounds = info.getCheckedClientArea(); - int y = topicBounds.bottom(); - - IFigure pmFigure = plusMinus.getFigure(); - Dimension size = pmFigure.getPreferredSize(); - Rectangle r = new Rectangle(x - size.width / 2, y, size.width, - size.height); - info.put(pmFigure, r); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - int majorSpacing = getMajorSpacing(branch); - int minorSpacing = getMinorSpacing(branch); - - Point ref = info.getReference(); - t.setOrigin(ref); - TimelineVerticalData tvd = getCastedData(branch); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = t.tr(refBounds); - - int y = refBounds.bottom() + majorSpacing; - - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - int num = subBranches.size(); - - int x = ref.x + majorSpacing; - int yLeftBefore = y; - int yRightBefore = y; - int yLeft = y; - int yRight = y; - for (int i = 0; i < num; i++) { - t.setEnabled(tvd.isLeftwardBranch(i)); - if (tvd.isLeftwardBranch(i)) { - y = yRight > yLeftBefore + majorSpacing ? yRight - : yLeftBefore + majorSpacing; - } else { - y = yLeft > yRightBefore + majorSpacing ? yLeft - : yRightBefore + majorSpacing; - } - - if (insertion != null && i == insertion.getIndex()) { - Rectangle r = insertion.createRectangle(x, y); - info.add(t.rr(r)); - y += r.height + minorSpacing; - } - IBranchPart subBranch = subBranches.get(i); - IFigure subBranchFigure = subBranch.getFigure(); - Insets ins = helper.getInsets(subBranch); - ins = t.ti(ins); - Dimension size = subBranchFigure.getPreferredSize(); - Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, - size.height); - info.put(subBranchFigure, t.rr(r)); - - IFigure topicFigure = subBranch.getTopicPart().getFigure(); - if (tvd.isLeftwardBranch(i)) { - yRightBefore = y + topicFigure.getPreferredSize().height - + majorSpacing; - yRight = y + size.height + ins.getHeight() + minorSpacing; - } else { - yLeftBefore = y + topicFigure.getPreferredSize().height - + majorSpacing; - yLeft = y + size.height + ins.getHeight() + minorSpacing; - } - } - - if (insertion != null && num == insertion.getIndex()) { - Dimension insSize = insertion.getSize(); - if (insSize != null) { - Rectangle r = new Rectangle(x, y, insSize.width, - insSize.height); - info.add(t.rr(r)); - } - } - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (!branch.getSubBranches().isEmpty()) { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } - return super.calcNavigation(branch, navReqType); - } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (getCastedData(branch) - .isLeftwardBranch(sourceChild.getBranchIndex())) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return branch.getTopicPart(); - } - } else { - if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public int getSourceOrientation(IBranchPart branch) { - return PositionConstants.SOUTH; - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return calcChildTargetOrientation(subBranch); - } - - private int calcChildTargetOrientation(IBranchPart subBranch) { - if (subBranch.getParentBranch() != null - && getCastedData(subBranch.getParentBranch()) - .isLeftwardBranch(subBranch.getBranchIndex())) - return PositionConstants.EAST; - return PositionConstants.WEST; - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - IReferencedFigure topicFigure = (IReferencedFigure) branch - .getTopicPart().getFigure(); - Point ref = topicFigure.getReference(); - t.setOrigin(ref); - - Point childRef = t.tp(getChildRef(branch, ref, key)); - Rectangle topicBounds = t.tr(topicFigure.getBounds()); - List subBranches = branch.getSubBranches(); - int totalHeight = 0; - if (!subBranches.isEmpty()) { - int fy = subBranches.get(0).getFigure().getBounds().y; - int ly = subBranches.get(subBranches.size() - 1).getFigure() - .getBounds().bottom(); - int sly = 0; - if (subBranches.size() > 1) - sly = subBranches.get(subBranches.size() - 2).getFigure() - .getBounds().bottom(); - totalHeight = ly > sly ? ly - fy : sly - ly; - } - int dy = childRef.y - topicBounds.bottom(); - int dx = childRef.x - topicBounds.right(); - if (childRef.x >= topicBounds.x - MindMapUI.SEARCH_RANGE / 2 - && childRef.x < topicBounds.right() - + MindMapUI.SEARCH_RANGE / 2) { - if (dy > 0 && dy < totalHeight + MindMapUI.SEARCH_RANGE) { - return dy; - } - int d = dx * dx + dy * dy; - return d; - } - return super.calcChildDistance(branch, key); - } - - protected Object createStructureData(IBranchPart branch) { - return new TimelineVerticalData(branch); - } - - protected boolean isValidStructureData(IBranchPart branch, Object data) { - return super.isValidStructureData(branch, data) - && (data instanceof TimelineVerticalData); - } - - private TimelineVerticalData getCastedData(IBranchPart branch) { - return (TimelineVerticalData) super.getStructureData(branch); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - IFigure topicFigure = topic.getFigure(); - Point ref = ((IReferencedFigure) topicFigure).getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - List subBranches = branch.getSubBranches(); - - int y = childRef.y - ref.y; - int ret = 0; - for (IBranchPart sub : subBranches) { - IFigure tf = sub.getTopicPart().getFigure(); - Point tr = ((IReferencedFigure) tf).getReference(); - int d = tr.y - ref.y; - if (y < d) - return ret; - ret++; - } - return withDisabled ? subBranches.size() : -1; - } - - private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize().scale(0.8); - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return new Insertion(branch, calcInsIndex(branch, key, true), - calcInsSize(branch, key)); - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.NORTH) - return 1; - if (direction == PositionConstants.SOUTH) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - List enclosingBranches = summary.getEnclosingBranches(); - if (!enclosingBranches.isEmpty()) { - IBranchPart sub = enclosingBranches.get(0); - if (getCastedData(branch).isLeftwardBranch(sub.getBranchIndex())) - return PositionConstants.WEST; - return PositionConstants.EAST; - } - return PositionConstants.WEST; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.SOUTH; - } - - public boolean isChildLeftwards(IBranchPart branch, IBranchPart child) { - return getCastedData(branch).isLeftwardBranch(child.getBranchIndex()); - } - - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - TimelineVerticalData tvd = getCastedData(branch); - - int majorSpacing = getMajorSpacing(branch); - int index = calcInsIndex(branch, key, true); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - int x = getFigureLocation(branch.getFigure()).x; - int dx = tvd.isLeftwardBranch(index) - ? majorSpacing + inventSize.width / 2 - : -majorSpacing - inventSize.width / 2; - if (index < 2 && index != subBranches.size()) { - IBranchPart sub = subBranches.get(index); - Rectangle bounds = sub.getFigure().getBounds(); - int y = bounds.y - majorSpacing - insSize.height / 2; - return new Point(x + dx, y); - } - - if (index == subBranches.size()) { - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getTopicPart().getFigure().getBounds(); - return new Point(x + dx, bounds.bottom() + majorSpacing); - } - - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index - 2), key, tvd.isLeftwardBranch(index)); - } - - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - return getFigureLocation(sub.getFigure()).getTranslated(0, 0); - } - - return calcInsertPosition(branch, child, key); - } - - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { - Dimension insSize = key.getFigure().getSize(); - int minorSpacing = getMinorSpacing(orientation.getParentBranch()); - int majorSpacing = getMajorSpacing(orientation.getParentBranch()); - IFigure tf = assist.getTopicPart().getFigure(); - Dimension ts = tf.getSize(); - - int x = getFigureLocation(assist.getFigure()).x - + (isRightOrUp ? (-ts.width + insSize.width) / 2 - : (ts.width - insSize.width) / 2); - - int y1 = assist.getFigure().getBounds().bottom() + minorSpacing; - int y2 = orientation.getTopicPart().getFigure().getBounds().bottom() - + majorSpacing; - - return new Point(x, - y1 > y2 ? y1 + insSize.height / 2 : y2 + insSize.height / 2); - } - - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int x = getMajorSpacing(branch) + key.getInvent().getSize().width / 2; - return getFigureLocation(branch.getFigure()).getTranslated(x, - branch.getFigure().getSize().height / 2 - + getMajorSpacing(branch) - + key.getFigure().getSize().height / 2); - } - -} +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.HorizontalFlipper; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +public class TimelineVerticalHeadStructure extends AbstractBranchStructure { + + private ITransformer t = new HorizontalFlipper(); + + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + int x = ref.x; + + Rectangle topicBounds = info.getCheckedClientArea(); + int y = topicBounds.bottom(); + + IFigure pmFigure = plusMinus.getFigure(); + Dimension size = pmFigure.getPreferredSize(); + Rectangle r = new Rectangle(x - size.width / 2, y, size.width, + size.height); + info.put(pmFigure, r); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + int majorSpacing = getMajorSpacing(branch); + int minorSpacing = getMinorSpacing(branch); + + Point ref = info.getReference(); + t.setOrigin(ref); + TimelineVerticalData tvd = getCastedData(branch); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = t.tr(refBounds); + + int y = refBounds.bottom() + majorSpacing; + + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + int num = subBranches.size(); + + int x = ref.x + majorSpacing; + int yLeftBefore = y; + int yRightBefore = y; + int yLeft = y; + int yRight = y; + for (int i = 0; i < num; i++) { + t.setEnabled(tvd.isLeftwardBranch(i)); + if (tvd.isLeftwardBranch(i)) { + y = yRight > yLeftBefore + majorSpacing ? yRight + : yLeftBefore + majorSpacing; + } else { + y = yLeft > yRightBefore + majorSpacing ? yLeft + : yRightBefore + majorSpacing; + } + + if (insertion != null && i == insertion.getIndex()) { + Rectangle r = insertion.createRectangle(x, y); + info.add(t.rr(r)); + y += r.height + minorSpacing; + } + IBranchPart subBranch = subBranches.get(i); + IFigure subBranchFigure = subBranch.getFigure(); + Insets ins = helper.getInsets(subBranch); + ins = t.ti(ins); + Dimension size = subBranchFigure.getPreferredSize(); + Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, + size.height); + info.put(subBranchFigure, t.rr(r)); + + IFigure topicFigure = subBranch.getTopicPart().getFigure(); + if (tvd.isLeftwardBranch(i)) { + yRightBefore = y + topicFigure.getPreferredSize().height + + majorSpacing; + yRight = y + size.height + ins.getHeight() + minorSpacing; + } else { + yLeftBefore = y + topicFigure.getPreferredSize().height + + majorSpacing; + yLeft = y + size.height + ins.getHeight() + minorSpacing; + } + } + + if (insertion != null && num == insertion.getIndex()) { + Dimension insSize = insertion.getSize(); + if (insSize != null) { + Rectangle r = new Rectangle(x, y, insSize.width, + insSize.height); + info.add(t.rr(r)); + } + } + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (!branch.getSubBranches().isEmpty()) { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } + return super.calcNavigation(branch, navReqType); + } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (getCastedData(branch) + .isLeftwardBranch(sourceChild.getBranchIndex())) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return branch.getTopicPart(); + } + } else { + if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public int getSourceOrientation(IBranchPart branch) { + return PositionConstants.SOUTH; + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return calcChildTargetOrientation(subBranch); + } + + private int calcChildTargetOrientation(IBranchPart subBranch) { + if (subBranch.getParentBranch() != null + && getCastedData(subBranch.getParentBranch()) + .isLeftwardBranch(subBranch.getBranchIndex())) + return PositionConstants.EAST; + return PositionConstants.WEST; + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + IReferencedFigure topicFigure = (IReferencedFigure) branch + .getTopicPart().getFigure(); + Point ref = topicFigure.getReference(); + t.setOrigin(ref); + + Point childRef = t.tp(getChildRef(branch, ref, key)); + Rectangle topicBounds = t.tr(topicFigure.getBounds()); + List subBranches = branch.getSubBranches(); + int totalHeight = 0; + if (!subBranches.isEmpty()) { + int fy = subBranches.get(0).getFigure().getBounds().y; + int ly = subBranches.get(subBranches.size() - 1).getFigure() + .getBounds().bottom(); + int sly = 0; + if (subBranches.size() > 1) + sly = subBranches.get(subBranches.size() - 2).getFigure() + .getBounds().bottom(); + totalHeight = ly > sly ? ly - fy : sly - ly; + } + int dy = childRef.y - topicBounds.bottom(); + int dx = childRef.x - topicBounds.right(); + if (childRef.x >= topicBounds.x - MindMapUI.SEARCH_RANGE / 2 + && childRef.x < topicBounds.right() + + MindMapUI.SEARCH_RANGE / 2) { + if (dy > 0 && dy < totalHeight + MindMapUI.SEARCH_RANGE) { + return dy; + } + int d = dx * dx + dy * dy; + return d; + } + return super.calcChildDistance(branch, key); + } + + protected Object createStructureData(IBranchPart branch) { + return new TimelineVerticalData(branch); + } + + protected boolean isValidStructureData(IBranchPart branch, Object data) { + return super.isValidStructureData(branch, data) + && (data instanceof TimelineVerticalData); + } + + private TimelineVerticalData getCastedData(IBranchPart branch) { + return (TimelineVerticalData) super.getStructureData(branch); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + IFigure topicFigure = topic.getFigure(); + Point ref = ((IReferencedFigure) topicFigure).getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + List subBranches = branch.getSubBranches(); + + int y = childRef.y - ref.y; + int ret = 0; + for (IBranchPart sub : subBranches) { + IFigure tf = sub.getTopicPart().getFigure(); + Point tr = ((IReferencedFigure) tf).getReference(); + int d = tr.y - ref.y; + if (y < d) + return ret; + ret++; + } + return withDisabled ? subBranches.size() : -1; + } + + private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize().scale(0.8); + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return new Insertion(branch, calcInsIndex(branch, key, true), + calcInsSize(branch, key)); + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.NORTH) + return 1; + if (direction == PositionConstants.SOUTH) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + List enclosingBranches = summary.getEnclosingBranches(); + if (!enclosingBranches.isEmpty()) { + IBranchPart sub = enclosingBranches.get(0); + if (getCastedData(branch).isLeftwardBranch(sub.getBranchIndex())) + return PositionConstants.WEST; + return PositionConstants.EAST; + } + return PositionConstants.WEST; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.SOUTH; + } + + public boolean isChildLeftwards(IBranchPart branch, IBranchPart child) { + return getCastedData(branch).isLeftwardBranch(child.getBranchIndex()); + } + + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + TimelineVerticalData tvd = getCastedData(branch); + + int majorSpacing = getMajorSpacing(branch); + int index = calcInsIndex(branch, key, true); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + int x = getFigureLocation(branch.getFigure()).x; + int dx = tvd.isLeftwardBranch(index) + ? majorSpacing + inventSize.width / 2 + : -majorSpacing - inventSize.width / 2; + if (index < 2 && index != subBranches.size()) { + IBranchPart sub = subBranches.get(index); + Rectangle bounds = sub.getFigure().getBounds(); + int y = bounds.y - majorSpacing - insSize.height / 2; + return new Point(x + dx, y); + } + + if (index == subBranches.size()) { + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getTopicPart().getFigure().getBounds(); + return new Point(x + dx, bounds.bottom() + majorSpacing); + } + + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index - 2), key, tvd.isLeftwardBranch(index)); + } + + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + return getFigureLocation(sub.getFigure()).getTranslated(0, 0); + } + + return calcInsertPosition(branch, child, key); + } + + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { + Dimension insSize = key.getFigure().getSize(); + int minorSpacing = getMinorSpacing(orientation.getParentBranch()); + int majorSpacing = getMajorSpacing(orientation.getParentBranch()); + IFigure tf = assist.getTopicPart().getFigure(); + Dimension ts = tf.getSize(); + + int x = getFigureLocation(assist.getFigure()).x + + (isRightOrUp ? (-ts.width + insSize.width) / 2 + : (ts.width - insSize.width) / 2); + + int y1 = assist.getFigure().getBounds().bottom() + minorSpacing; + int y2 = orientation.getTopicPart().getFigure().getBounds().bottom() + + majorSpacing; + + return new Point(x, + y1 > y2 ? y1 + insSize.height / 2 : y2 + insSize.height / 2); + } + + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int x = getMajorSpacing(branch) + key.getInvent().getSize().width / 2; + return getFigureLocation(branch.getFigure()).getTranslated(x, + branch.getFigure().getSize().height / 2 + + getMajorSpacing(branch) + + key.getFigure().getSize().height / 2); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalPropertyTester.java index 115636be5..21f5c3e7e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/TimelineVerticalPropertyTester.java @@ -1,36 +1,36 @@ -package org.xmind.ui.internal.branch; - -import org.eclipse.core.runtime.Assert; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.IBranchPropertyTester; -import org.xmind.ui.mindmap.IBranchPart; - -public class TimelineVerticalPropertyTester implements IBranchPropertyTester { - - private static final String P_LEFTWARDS = "leftwards"; //$NON-NLS-1$ - - public boolean test(IBranchPart branch, String property, Object[] args, - Object expectedValue) { - if (P_LEFTWARDS.equals(property)) { - if (expectedValue == null) - return isBranchLeftwards(branch); - if (expectedValue instanceof Boolean) - return ((Boolean) expectedValue).booleanValue() == isBranchLeftwards(branch); - } - Assert.isTrue(false); - return false; - } - - private boolean isBranchLeftwards(IBranchPart branch) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - IStructure sa = parent.getBranchPolicy().getStructure(parent); - if (sa instanceof TimelineVerticalHeadStructure) { - return ((TimelineVerticalHeadStructure) sa).isChildLeftwards( - parent, branch); - } - } - return false; - } - -} +package org.xmind.ui.internal.branch; + +import org.eclipse.core.runtime.Assert; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.IBranchPropertyTester; +import org.xmind.ui.mindmap.IBranchPart; + +public class TimelineVerticalPropertyTester implements IBranchPropertyTester { + + private static final String P_LEFTWARDS = "leftwards"; //$NON-NLS-1$ + + public boolean test(IBranchPart branch, String property, Object[] args, + Object expectedValue) { + if (P_LEFTWARDS.equals(property)) { + if (expectedValue == null) + return isBranchLeftwards(branch); + if (expectedValue instanceof Boolean) + return ((Boolean) expectedValue).booleanValue() == isBranchLeftwards(branch); + } + Assert.isTrue(false); + return false; + } + + private boolean isBranchLeftwards(IBranchPart branch) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + IStructure sa = parent.getBranchPolicy().getStructure(parent); + if (sa instanceof TimelineVerticalHeadStructure) { + return ((TimelineVerticalHeadStructure) sa).isChildLeftwards( + parent, branch); + } + } + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedData.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedData.java index 991c03dd8..d05214fd9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedData.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedData.java @@ -1,49 +1,49 @@ -package org.xmind.ui.internal.branch; - -import static org.xmind.ui.internal.branch.BaseRadialStructure.CACHE_NUMBER_RIGHT_BRANCHES; - -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.util.MindMapUtils; - -public class UnbalancedData extends RadialData { - - public final static String STRUCTUREID_UNBALANCED = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - public final static String EXTENTION_UNBALANCEDSTRUCTURE = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - public final static String EXTENTIONELEMENT_RIGHTNUMBER = "right-number";//$NON-NLS-1$ - - public UnbalancedData(IBranchPart branch) { - super(branch); - } - - @Override - public int getNumRight() { - IBranchPart branch = getBranch(); - Integer num = (Integer) MindMapUtils.getCache(branch, - CACHE_NUMBER_RIGHT_BRANCHES); - if (num != null) - return num.intValue(); - ITopicExtension extension = branch.getTopic() - .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); - if (extension == null) - return super.getNumRight(); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER); - String rightNum = element.getTextContent(); - if (rightNum != null) { - int value = Integer.valueOf(rightNum).intValue(); - if (value < 0) { - int superRightNum = super.getNumRight(); - element.setTextContent(String.valueOf(superRightNum)); - return superRightNum; - } - return value; - } else { - int superRightNum = super.getNumRight(); - element.setTextContent(String.valueOf(superRightNum)); - return superRightNum; - } - } - -} +package org.xmind.ui.internal.branch; + +import static org.xmind.ui.internal.branch.BaseRadialStructure.CACHE_NUMBER_RIGHT_BRANCHES; + +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.util.MindMapUtils; + +public class UnbalancedData extends RadialData { + + public final static String STRUCTUREID_UNBALANCED = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + public final static String EXTENTION_UNBALANCEDSTRUCTURE = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + public final static String EXTENTIONELEMENT_RIGHTNUMBER = "right-number";//$NON-NLS-1$ + + public UnbalancedData(IBranchPart branch) { + super(branch); + } + + @Override + public int getNumRight() { + IBranchPart branch = getBranch(); + Integer num = (Integer) MindMapUtils.getCache(branch, + CACHE_NUMBER_RIGHT_BRANCHES); + if (num != null) + return num.intValue(); + ITopicExtension extension = branch.getTopic() + .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); + if (extension == null) + return super.getNumRight(); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild(EXTENTIONELEMENT_RIGHTNUMBER); + String rightNum = element.getTextContent(); + if (rightNum != null) { + int value = Integer.valueOf(rightNum).intValue(); + if (value < 0) { + int superRightNum = super.getNumRight(); + element.setTextContent(String.valueOf(superRightNum)); + return superRightNum; + } + return value; + } else { + int superRightNum = super.getNumRight(); + element.setTextContent(String.valueOf(superRightNum)); + return superRightNum; + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedStructure.java index 8336fac78..0e340ce75 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UnbalancedStructure.java @@ -1,179 +1,179 @@ -package org.xmind.ui.internal.branch; - -import java.util.List; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.tools.ParentSearchKey; - -public class UnbalancedStructure extends ClockwiseRadialStructure { - - @Override - protected Object createStructureData(IBranchPart branch) { - return new UnbalancedData(branch); - } - - @Override - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - - int index = calcInsIndex(branch, key, true); - - RadialData cache = getRadialData(branch); - int right = cache.getNumRight(); - int left = cache.getNumLeft(); - - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - if (getReference(key.getFeedback()).x > 0) { - if (right == 0) - return calcFirstChildPosition(branch, key); - - IBranchPart first = subBranches.get(0); - Rectangle fBounds = first.getFigure().getBounds(); - if (index == 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (right == 1) { - if (fBounds.bottom() > 0) { - int x = fBounds.x + inventSize.width / 2; - int y = fBounds.bottom() - + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } else { - Point loc = calcFirstChildPosition(branch, key); - return new Point(loc.x, -loc.y); - } - } - - if (index == right) { - IBranchPart sub = subBranches.get(right - 1); - Rectangle bounds = sub.getFigure().getBounds(); - int x = bounds.x + inventSize.width / 2; - int y = bounds.bottom() + (insSize.height + inventSize.height) - / 2; - return new Point(x, y); - } - - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index), key, true); - } else { - if (left == 0) { - return calcFirstChildPosition(branch, key).getNegated(); - } - - IBranchPart leftFirst = subBranches.get(right); - if (index == right) { - Rectangle lFBounds = leftFirst.getFigure().getBounds(); - int x = lFBounds.right() - inventSize.width / 2; - int y = lFBounds.bottom() - + (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - if (left == 1) { - Rectangle lFBounds = leftFirst.getFigure().getBounds(); - if (lFBounds.y < 0) { - int x = lFBounds.right() - inventSize.width / 2; - int y = lFBounds.y - (insSize.height + inventSize.height) - / 2; - return new Point(x, y); - } else { - Point loc = calcFirstChildPosition(branch, key) - .getNegated(); - return new Point(loc.x, -loc.y); - } - } - - if (index == subBranches.size()) { - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getFigure().getBounds(); - int x = bounds.right() - inventSize.width / 2; - int y = bounds.y - (insSize.height + inventSize.height) / 2; - return new Point(x, y); - } - - return calcInventPosition(subBranches.get(index), - subBranches.get(index - 1), key, false); - } - } - - @Override - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - RadialData cache = getRadialData(branch); - int right = cache.getNumRight(); - int left = subBranches.size() - right; - - int oldIndex = getOldIndex(branch, child); - int index = calcInsIndex(branch, key, true); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - - Dimension inventSize = key.getInvent().getSize(); - if (getReference(key.getFeedback()).x > 0) { - if (right == 0 || subBranches.size() == 1) - return calcFirstChildPosition(branch, key); - if (oldIndex < right) { - if (index == oldIndex) - return getReference(subBranches.get(index)).getTranslated( - -getTopicSize(subBranches.get(index)).width / 2 - + inventSize.width / 2, 0); - - } else { - if (index == right) { - IBranchPart sub = subBranches.get(index - 1); - Point loc = getReference(sub) - .getTranslated( - -getTopicSize(sub).width / 2 - + inventSize.width / 2, 0); - if (right == 1) - return new Point(loc.x, -loc.y); - } - } - } else { - if (left == 0 || subBranches.size() == 1) - return calcFirstChildPosition(branch, key).getNegated(); - - if (oldIndex < right) { - if (index == right - 1) { - IBranchPart sub = subBranches.get(index + 1); - if (!sub.getFigure().isEnabled()) - return getReference(sub).getTranslated( - getTopicSize(sub).width / 2 - inventSize.width - / 2, 0); - - Rectangle bounds = sub.getFigure().getBounds(); - int x = bounds.right() - inventSize.width / 2; - int y = bounds.bottom() - + (key.getFigure().getSize().height + inventSize.height) - / 2; - return new Point(x, y); - } - } else { - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - return getReference(sub).getTranslated( - getTopicSize(sub).width / 2 - inventSize.width / 2, - 0); - } - } - } - return calcInsertPosition(branch, child, key); - } -} +package org.xmind.ui.internal.branch; + +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.tools.ParentSearchKey; + +public class UnbalancedStructure extends ClockwiseRadialStructure { + + @Override + protected Object createStructureData(IBranchPart branch) { + return new UnbalancedData(branch); + } + + @Override + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + + int index = calcInsIndex(branch, key, true); + + RadialData cache = getRadialData(branch); + int right = cache.getNumRight(); + int left = cache.getNumLeft(); + + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + if (getReference(key.getFeedback()).x > 0) { + if (right == 0) + return calcFirstChildPosition(branch, key); + + IBranchPart first = subBranches.get(0); + Rectangle fBounds = first.getFigure().getBounds(); + if (index == 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (right == 1) { + if (fBounds.bottom() > 0) { + int x = fBounds.x + inventSize.width / 2; + int y = fBounds.bottom() + + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } else { + Point loc = calcFirstChildPosition(branch, key); + return new Point(loc.x, -loc.y); + } + } + + if (index == right) { + IBranchPart sub = subBranches.get(right - 1); + Rectangle bounds = sub.getFigure().getBounds(); + int x = bounds.x + inventSize.width / 2; + int y = bounds.bottom() + (insSize.height + inventSize.height) + / 2; + return new Point(x, y); + } + + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index), key, true); + } else { + if (left == 0) { + return calcFirstChildPosition(branch, key).getNegated(); + } + + IBranchPart leftFirst = subBranches.get(right); + if (index == right) { + Rectangle lFBounds = leftFirst.getFigure().getBounds(); + int x = lFBounds.right() - inventSize.width / 2; + int y = lFBounds.bottom() + + (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + if (left == 1) { + Rectangle lFBounds = leftFirst.getFigure().getBounds(); + if (lFBounds.y < 0) { + int x = lFBounds.right() - inventSize.width / 2; + int y = lFBounds.y - (insSize.height + inventSize.height) + / 2; + return new Point(x, y); + } else { + Point loc = calcFirstChildPosition(branch, key) + .getNegated(); + return new Point(loc.x, -loc.y); + } + } + + if (index == subBranches.size()) { + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getFigure().getBounds(); + int x = bounds.right() - inventSize.width / 2; + int y = bounds.y - (insSize.height + inventSize.height) / 2; + return new Point(x, y); + } + + return calcInventPosition(subBranches.get(index), + subBranches.get(index - 1), key, false); + } + } + + @Override + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + RadialData cache = getRadialData(branch); + int right = cache.getNumRight(); + int left = subBranches.size() - right; + + int oldIndex = getOldIndex(branch, child); + int index = calcInsIndex(branch, key, true); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + + Dimension inventSize = key.getInvent().getSize(); + if (getReference(key.getFeedback()).x > 0) { + if (right == 0 || subBranches.size() == 1) + return calcFirstChildPosition(branch, key); + if (oldIndex < right) { + if (index == oldIndex) + return getReference(subBranches.get(index)).getTranslated( + -getTopicSize(subBranches.get(index)).width / 2 + + inventSize.width / 2, 0); + + } else { + if (index == right) { + IBranchPart sub = subBranches.get(index - 1); + Point loc = getReference(sub) + .getTranslated( + -getTopicSize(sub).width / 2 + + inventSize.width / 2, 0); + if (right == 1) + return new Point(loc.x, -loc.y); + } + } + } else { + if (left == 0 || subBranches.size() == 1) + return calcFirstChildPosition(branch, key).getNegated(); + + if (oldIndex < right) { + if (index == right - 1) { + IBranchPart sub = subBranches.get(index + 1); + if (!sub.getFigure().isEnabled()) + return getReference(sub).getTranslated( + getTopicSize(sub).width / 2 - inventSize.width + / 2, 0); + + Rectangle bounds = sub.getFigure().getBounds(); + int x = bounds.right() - inventSize.width / 2; + int y = bounds.bottom() + + (key.getFigure().getSize().height + inventSize.height) + / 2; + return new Point(x, y); + } + } else { + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + return getReference(sub).getTranslated( + getTopicSize(sub).width / 2 - inventSize.width / 2, + 0); + } + } + } + return calcInsertPosition(branch, child, key); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpDownStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpDownStructure.java index c6179ae10..256baad26 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpDownStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpDownStructure.java @@ -1,489 +1,489 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.ITransformer; -import org.xmind.gef.draw2d.geometry.VerticalFlipper; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.AbstractBranchStructure; -import org.xmind.ui.branch.BoundaryLayoutHelper; -import org.xmind.ui.branch.IInsertion; -import org.xmind.ui.branch.Insertion; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IBranchRangePart; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.mindmap.ISummaryPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.tools.ParentSearchKey; - -public class UpDownStructure extends AbstractBranchStructure { - - private boolean upwards; - - private ITransformer t = new VerticalFlipper(); - - public UpDownStructure(boolean upwards) { - this.upwards = upwards; - this.t.setEnabled(upwards); - } - - public boolean isUpwards() { - return upwards; - } - - protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, - LayoutInfo info) { - Point ref = info.getReference(); - t.setOrigin(ref); - int x = ref.x; - - Rectangle topicBounds = info.getCheckedClientArea(); - topicBounds = t.tr(topicBounds); - int y = topicBounds.bottom(); - - IFigure pmFigure = plusMinus.getFigure(); - Dimension size = pmFigure.getPreferredSize(); - Rectangle r = new Rectangle(x - size.width / 2, y, size.width, - size.height); - info.put(pmFigure, t.rr(r)); - } - - protected void doFillSubBranches(IBranchPart branch, - List subBranches, LayoutInfo info) { - - int majorSpacing = getMajorSpacing(branch); - int minorSpacing = getMinorSpacing(branch); - Point ref = info.getReference(); - t.setOrigin(ref); - - Rectangle refBounds = info.getCheckedClientArea(); - refBounds = t.tr(refBounds); - - int y = refBounds.bottom() + majorSpacing; - - int num = subBranches.size(); - int totalWidth = calcTotalChildrenWidth(branch, minorSpacing, true); - - int left = totalWidth / 2; - int x = ref.x - left; - IInsertion insertion = getCurrentInsertion(branch); - BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); - - for (int i = 0; i < num; i++) { - if (insertion != null && i == insertion.getIndex()) { - Rectangle r = insertion.createRectangle(x, y); - info.add(t.rr(r)); - x += r.width + minorSpacing; - } - - IBranchPart subBranchPart = subBranches.get(i); - IFigure subBranchFigure = subBranchPart.getFigure(); - Insets ins = helper.getInsets(subBranchPart); - - Dimension size = subBranchFigure.getPreferredSize(); - Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, - size.height); - info.put(subBranchFigure, t.rr(r)); - x += size.width + ins.getWidth() + minorSpacing; - } - - if (insertion != null && num == insertion.getIndex()) { - Dimension insSize = insertion.getSize(); - if (insSize != null) { - Rectangle r = new Rectangle(x, y, insSize.width, - insSize.height); - info.add(t.rr(r)); - } - } - } - -// public Object calcNavigation(IBranchPart branch, int direction) { -// switch (direction) { -// case PositionConstants.WEST: -// return NAVI_PREV; -// case PositionConstants.EAST: -// return NAVI_NEXT; -// case PositionConstants.NORTH: -// return isUpwards() ? NAVI_CHILD : NAVI_PARENT; -// case PositionConstants.SOUTH: -// return isUpwards() ? NAVI_PARENT : NAVI_CHILD; -// } -// return NAVI_SELF; -// } - - public IPart calcChildNavigation(IBranchPart branch, - IBranchPart sourceChild, String navReqType, boolean sequential) { - if (GEF.REQ_NAV_LEFT.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); - } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { - return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); - } else if (!sequential) { - if (isUpwards()) { - if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return branch.getTopicPart(); - } - } else { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return branch.getTopicPart(); - } - } - } - return super.calcChildNavigation(branch, sourceChild, navReqType, - sequential); - } - - public IPart calcNavigation(IBranchPart branch, String navReqType) { - if (!branch.getSubBranches().isEmpty()) { - if (isUpwards()) { - if (GEF.REQ_NAV_UP.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } else { - if (GEF.REQ_NAV_DOWN.equals(navReqType)) { - return getSubTopicPart(branch, 0); - } - } - } - return super.calcNavigation(branch, navReqType); - } - - public int getSourceOrientation(IBranchPart branch) { - if (isUpwards()) - return PositionConstants.NORTH; - return PositionConstants.SOUTH; - } - - public int getChildTargetOrientation(IBranchPart branch, - IBranchPart subBranch) { - return calcChildTargetOrientation(); - } - -// public int calcChildTargetOrientation(IBranchPart branch, -// IReferencedFigure childFigure) { -// return calcChildTargetOrientation(); -// } - - private int calcChildTargetOrientation() { - if (isUpwards()) - return PositionConstants.SOUTH; - return PositionConstants.NORTH; - } - - public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { - IFigure branchFigure = branch.getFigure(); - IReferencedFigure topicFigure = (IReferencedFigure) branch - .getTopicPart().getFigure(); - Point ref = topicFigure.getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Rectangle branchBounds = t.tr(branchFigure.getBounds()); - Rectangle topicBounds = t.tr(topicFigure.getBounds()); - int dy = childRef.y - topicBounds.bottom(); - if (dy > 0) { - if (childRef.x >= branchBounds.x - && childRef.x < branchBounds.right() - && dy < MindMapUI.SEARCH_RANGE) { - return dy; - } - int dx = childRef.x - ref.x; - int d = dx * dx + dy * dy; - return d; - } - return super.calcChildDistance(branch, key); - } - - protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, - boolean withDisabled) { - if (branch.getSubBranches().isEmpty() || branch.isFolded()) - return withDisabled ? 0 : -1; - - ITopicPart topic = branch.getTopicPart(); - if (topic == null) - return withDisabled ? 0 : -1; - - IFigure topicFigure = topic.getFigure(); - Point ref = ((IReferencedFigure) topicFigure).getReference(); - t.setOrigin(ref); - Point childRef = t.tp(getChildRef(branch, ref, key)); - Dimension insSize = calcInsSize(branch, key); - int insWidth = insSize.width; - int minorSpacing = getMinorSpacing(branch); - int totalChildrenWidth = calcTotalChildrenWidth(branch, minorSpacing, - false); - int totalWidth = totalChildrenWidth + insWidth + minorSpacing; - int x = ref.x - totalWidth / 2; - return calcInsIndex(branch, x, childRef, minorSpacing, insWidth, - withDisabled); - } - - private int calcInsIndex(IBranchPart branch, int x, Point childRef, - int spacing, int childWidth, boolean withDisabled) { - int ret = 0; - int sum = 0; - List subBranches = branch.getSubBranches(); - int num = subBranches.size(); - for (IBranchPart subBranch : subBranches) { - IFigure subFigure = subBranch.getFigure(); - int w = subFigure.getPreferredSize().width; - int hint = x + sum + (childWidth + w + spacing) / 2; - if (childRef.x < hint) { - return ret; - } - sum += w + spacing; - if (withDisabled || subFigure.isEnabled()) - ret++; - } - return withDisabled ? num : -1; - } - - private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { - return key.getFigure().getSize().scale(0.8); - } - - private int calcTotalChildrenWidth(IBranchPart branch, int minorSpacing, - boolean withInsertion) { - int totalWidth = 0; - Iterator it = branch.getSubBranches().iterator(); - while (it.hasNext()) { - IBranchPart subBranch = it.next(); - totalWidth += subBranch.getFigure().getPreferredSize().width; - if (it.hasNext()) { - totalWidth += minorSpacing; - } - } - if (withInsertion) { - IInsertion ins = getCurrentInsertion(branch); - if (ins != null) { - Dimension insSize = ins.getSize(); - if (insSize != null) { - totalWidth += minorSpacing + insSize.width; - } - } - } - return totalWidth; - } - - public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { - return new Insertion(branch, calcInsIndex(branch, key, true), - calcInsSize(branch, key)); - } - - public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { - return upwards ? PositionConstants.NORTH : PositionConstants.SOUTH; - } - - public int getRangeGrowthDirection(IBranchPart branch, - IBranchRangePart range) { - return PositionConstants.EAST; - } - - public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, - int direction) { - if (direction == PositionConstants.EAST) - return 1; - if (direction == PositionConstants.WEST) - return -1; - return super.getQuickMoveOffset(branch, child, direction); - } - - protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - if (subBranches.isEmpty()) - return calcFirstChildPosition(branch, key); - - int minorSpacing = getMinorSpacing(branch); - int index = calcInsIndex(branch, key, true); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - List boundaries = branch.getBoundaries(); - - if (index == 0) { - IBranchPart sub = subBranches.get(0); - Rectangle bounds = sub.getFigure().getBounds(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - Rectangle bBounds = boundary.getFigure().getBounds(); - List enclosingBranches = boundary - .getEnclosingBranches(); - if ((!enclosingBranches.isEmpty()) - && sub.equals(enclosingBranches.get(0))) - bounds = bBounds.contains(bounds) ? bBounds : bounds; - } - } - - int x = bounds.x - minorSpacing - insSize.width / 2; - int y; - if (isUpwards()) - y = bounds.bottom() - inventSize.width / 2; - else - y = bounds.y + inventSize.width / 2; - - return new Point(x, y); - } - - if (index == subBranches.size()) { - IBranchPart sub = subBranches.get(subBranches.size() - 1); - Rectangle bounds = sub.getFigure().getBounds(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - Rectangle bBounds = boundary.getFigure().getBounds(); - List enclosingBranches = boundary - .getEnclosingBranches(); - if ((!enclosingBranches.isEmpty()) - && sub.equals(enclosingBranches - .get(enclosingBranches.size() - 1))) - bounds = bBounds.contains(bounds) ? bBounds : bounds; - } - } - - int x = bounds.right() + minorSpacing + insSize.width / 2; - int y; - if (isUpwards()) - y = bounds.bottom() - inventSize.width / 2; - else - y = bounds.y + inventSize.width / 2; - - return new Point(x, y); - } - return calcInventPosition(subBranches.get(index - 1), - subBranches.get(index), key, isUpwards()); - } - - protected Point calcMovePosition(IBranchPart branch, IBranchPart child, - ParentSearchKey key) { - List subBranches = branch.getSubBranches(); - List disables = getDisableBranches(branch); - - int index = calcInsIndex(branch, key, true); - int oldIndex = getOldIndex(branch, child); - if (disables != null) { - if (disables.contains(index - 1)) { - index--; - oldIndex = index; - } else if (disables.contains(index)) { - oldIndex = index; - } - } - Dimension inventSize = key.getInvent().getSize(); - - if (index == oldIndex) { - IBranchPart sub = subBranches.get(index); - int delta = sub.getTopicPart().getFigure().getSize().height / 2 - - inventSize.height / 2; - return getFigureLocation(sub.getFigure()).getTranslated(0, - isUpwards() ? delta : -delta); - } - - return calcInsertPosition(branch, child, key); - } - - @Override - protected Point calcFirstChildPosition(IBranchPart branch, - ParentSearchKey key) { - int y = branch.getFigure().getSize().height / 2 - + getMajorSpacing(branch) - + key.getInvent().getSize().height / 2; - return getFigureLocation(branch.getFigure()).getTranslated(0, - isUpwards() ? -y : y); - } - - @Override - protected Point calcInventPosition(IBranchPart orientation, - IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { - int minorSpacing = getMinorSpacing(orientation.getParentBranch()); - Dimension insSize = key.getFigure().getSize(); - Dimension inventSize = key.getInvent().getSize(); - - Rectangle oriBounds = orientation.getFigure().getBounds(); - Rectangle assBounds = assist.getFigure().getBounds(); - - Rectangle lBounds = oriBounds; - Rectangle rBounds = assBounds; - - List boundaries = orientation.getParentBranch() - .getBoundaries(); - if (!boundaries.isEmpty()) { - for (IBoundaryPart boundary : boundaries) { - List enclosingBranches = boundary - .getEnclosingBranches(); - Rectangle bBounds = boundary.getFigure().getBounds(); - - if ((!enclosingBranches.isEmpty()) && orientation.equals( - enclosingBranches.get(enclosingBranches.size() - 1))) - lBounds = bBounds.contains(lBounds) ? bBounds : lBounds; - - if ((!enclosingBranches.isEmpty()) - && assist.equals(enclosingBranches.get(0))) - rBounds = bBounds.contains(rBounds) ? bBounds : rBounds; - } - } - - boolean isBefourBounds; - Rectangle bounds; - if (lBounds.equals(oriBounds)) { - bounds = lBounds; - isBefourBounds = false; - } else if (rBounds.equals(assBounds)) { - bounds = rBounds; - isBefourBounds = true; - } else { - if (isRightOrUp) { - if (lBounds.bottom() < rBounds.bottom()) { - bounds = lBounds; - isBefourBounds = false; - } else { - bounds = rBounds; - isBefourBounds = true; - } - } else { - if (lBounds.y > rBounds.y) { - bounds = lBounds; - isBefourBounds = false; - } else { - bounds = rBounds; - isBefourBounds = true; - } - } - } - - int x; - if (isBefourBounds) - x = bounds.x - minorSpacing - insSize.width / 2; - else - x = bounds.right() + minorSpacing + insSize.width / 2; - - int y; - if (isRightOrUp) - y = bounds.bottom() - inventSize.height / 2; - else - y = bounds.y + inventSize.height / 2; - - return new Point(x, y); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.ITransformer; +import org.xmind.gef.draw2d.geometry.VerticalFlipper; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.AbstractBranchStructure; +import org.xmind.ui.branch.BoundaryLayoutHelper; +import org.xmind.ui.branch.IInsertion; +import org.xmind.ui.branch.Insertion; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IBranchRangePart; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.mindmap.ISummaryPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tools.ParentSearchKey; + +public class UpDownStructure extends AbstractBranchStructure { + + private boolean upwards; + + private ITransformer t = new VerticalFlipper(); + + public UpDownStructure(boolean upwards) { + this.upwards = upwards; + this.t.setEnabled(upwards); + } + + public boolean isUpwards() { + return upwards; + } + + protected void doFillPlusMinus(IBranchPart branch, IPlusMinusPart plusMinus, + LayoutInfo info) { + Point ref = info.getReference(); + t.setOrigin(ref); + int x = ref.x; + + Rectangle topicBounds = info.getCheckedClientArea(); + topicBounds = t.tr(topicBounds); + int y = topicBounds.bottom(); + + IFigure pmFigure = plusMinus.getFigure(); + Dimension size = pmFigure.getPreferredSize(); + Rectangle r = new Rectangle(x - size.width / 2, y, size.width, + size.height); + info.put(pmFigure, t.rr(r)); + } + + protected void doFillSubBranches(IBranchPart branch, + List subBranches, LayoutInfo info) { + + int majorSpacing = getMajorSpacing(branch); + int minorSpacing = getMinorSpacing(branch); + Point ref = info.getReference(); + t.setOrigin(ref); + + Rectangle refBounds = info.getCheckedClientArea(); + refBounds = t.tr(refBounds); + + int y = refBounds.bottom() + majorSpacing; + + int num = subBranches.size(); + int totalWidth = calcTotalChildrenWidth(branch, minorSpacing, true); + + int left = totalWidth / 2; + int x = ref.x - left; + IInsertion insertion = getCurrentInsertion(branch); + BoundaryLayoutHelper helper = getBoundaryLayoutHelper(branch); + + for (int i = 0; i < num; i++) { + if (insertion != null && i == insertion.getIndex()) { + Rectangle r = insertion.createRectangle(x, y); + info.add(t.rr(r)); + x += r.width + minorSpacing; + } + + IBranchPart subBranchPart = subBranches.get(i); + IFigure subBranchFigure = subBranchPart.getFigure(); + Insets ins = helper.getInsets(subBranchPart); + + Dimension size = subBranchFigure.getPreferredSize(); + Rectangle r = new Rectangle(x + ins.left, y + ins.top, size.width, + size.height); + info.put(subBranchFigure, t.rr(r)); + x += size.width + ins.getWidth() + minorSpacing; + } + + if (insertion != null && num == insertion.getIndex()) { + Dimension insSize = insertion.getSize(); + if (insSize != null) { + Rectangle r = new Rectangle(x, y, insSize.width, + insSize.height); + info.add(t.rr(r)); + } + } + } + +// public Object calcNavigation(IBranchPart branch, int direction) { +// switch (direction) { +// case PositionConstants.WEST: +// return NAVI_PREV; +// case PositionConstants.EAST: +// return NAVI_NEXT; +// case PositionConstants.NORTH: +// return isUpwards() ? NAVI_CHILD : NAVI_PARENT; +// case PositionConstants.SOUTH: +// return isUpwards() ? NAVI_PARENT : NAVI_CHILD; +// } +// return NAVI_SELF; +// } + + public IPart calcChildNavigation(IBranchPart branch, + IBranchPart sourceChild, String navReqType, boolean sequential) { + if (GEF.REQ_NAV_LEFT.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() - 1); + } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { + return getSubTopicPart(branch, sourceChild.getBranchIndex() + 1); + } else if (!sequential) { + if (isUpwards()) { + if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return branch.getTopicPart(); + } + } else { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return branch.getTopicPart(); + } + } + } + return super.calcChildNavigation(branch, sourceChild, navReqType, + sequential); + } + + public IPart calcNavigation(IBranchPart branch, String navReqType) { + if (!branch.getSubBranches().isEmpty()) { + if (isUpwards()) { + if (GEF.REQ_NAV_UP.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } else { + if (GEF.REQ_NAV_DOWN.equals(navReqType)) { + return getSubTopicPart(branch, 0); + } + } + } + return super.calcNavigation(branch, navReqType); + } + + public int getSourceOrientation(IBranchPart branch) { + if (isUpwards()) + return PositionConstants.NORTH; + return PositionConstants.SOUTH; + } + + public int getChildTargetOrientation(IBranchPart branch, + IBranchPart subBranch) { + return calcChildTargetOrientation(); + } + +// public int calcChildTargetOrientation(IBranchPart branch, +// IReferencedFigure childFigure) { +// return calcChildTargetOrientation(); +// } + + private int calcChildTargetOrientation() { + if (isUpwards()) + return PositionConstants.SOUTH; + return PositionConstants.NORTH; + } + + public int calcChildDistance(IBranchPart branch, ParentSearchKey key) { + IFigure branchFigure = branch.getFigure(); + IReferencedFigure topicFigure = (IReferencedFigure) branch + .getTopicPart().getFigure(); + Point ref = topicFigure.getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Rectangle branchBounds = t.tr(branchFigure.getBounds()); + Rectangle topicBounds = t.tr(topicFigure.getBounds()); + int dy = childRef.y - topicBounds.bottom(); + if (dy > 0) { + if (childRef.x >= branchBounds.x + && childRef.x < branchBounds.right() + && dy < MindMapUI.SEARCH_RANGE) { + return dy; + } + int dx = childRef.x - ref.x; + int d = dx * dx + dy * dy; + return d; + } + return super.calcChildDistance(branch, key); + } + + protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, + boolean withDisabled) { + if (branch.getSubBranches().isEmpty() || branch.isFolded()) + return withDisabled ? 0 : -1; + + ITopicPart topic = branch.getTopicPart(); + if (topic == null) + return withDisabled ? 0 : -1; + + IFigure topicFigure = topic.getFigure(); + Point ref = ((IReferencedFigure) topicFigure).getReference(); + t.setOrigin(ref); + Point childRef = t.tp(getChildRef(branch, ref, key)); + Dimension insSize = calcInsSize(branch, key); + int insWidth = insSize.width; + int minorSpacing = getMinorSpacing(branch); + int totalChildrenWidth = calcTotalChildrenWidth(branch, minorSpacing, + false); + int totalWidth = totalChildrenWidth + insWidth + minorSpacing; + int x = ref.x - totalWidth / 2; + return calcInsIndex(branch, x, childRef, minorSpacing, insWidth, + withDisabled); + } + + private int calcInsIndex(IBranchPart branch, int x, Point childRef, + int spacing, int childWidth, boolean withDisabled) { + int ret = 0; + int sum = 0; + List subBranches = branch.getSubBranches(); + int num = subBranches.size(); + for (IBranchPart subBranch : subBranches) { + IFigure subFigure = subBranch.getFigure(); + int w = subFigure.getPreferredSize().width; + int hint = x + sum + (childWidth + w + spacing) / 2; + if (childRef.x < hint) { + return ret; + } + sum += w + spacing; + if (withDisabled || subFigure.isEnabled()) + ret++; + } + return withDisabled ? num : -1; + } + + private Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { + return key.getFigure().getSize().scale(0.8); + } + + private int calcTotalChildrenWidth(IBranchPart branch, int minorSpacing, + boolean withInsertion) { + int totalWidth = 0; + Iterator it = branch.getSubBranches().iterator(); + while (it.hasNext()) { + IBranchPart subBranch = it.next(); + totalWidth += subBranch.getFigure().getPreferredSize().width; + if (it.hasNext()) { + totalWidth += minorSpacing; + } + } + if (withInsertion) { + IInsertion ins = getCurrentInsertion(branch); + if (ins != null) { + Dimension insSize = ins.getSize(); + if (insSize != null) { + totalWidth += minorSpacing + insSize.width; + } + } + } + return totalWidth; + } + + public IInsertion calcInsertion(IBranchPart branch, ParentSearchKey key) { + return new Insertion(branch, calcInsIndex(branch, key, true), + calcInsSize(branch, key)); + } + + public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { + return upwards ? PositionConstants.NORTH : PositionConstants.SOUTH; + } + + public int getRangeGrowthDirection(IBranchPart branch, + IBranchRangePart range) { + return PositionConstants.EAST; + } + + public int getQuickMoveOffset(IBranchPart branch, IBranchPart child, + int direction) { + if (direction == PositionConstants.EAST) + return 1; + if (direction == PositionConstants.WEST) + return -1; + return super.getQuickMoveOffset(branch, child, direction); + } + + protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + if (subBranches.isEmpty()) + return calcFirstChildPosition(branch, key); + + int minorSpacing = getMinorSpacing(branch); + int index = calcInsIndex(branch, key, true); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + List boundaries = branch.getBoundaries(); + + if (index == 0) { + IBranchPart sub = subBranches.get(0); + Rectangle bounds = sub.getFigure().getBounds(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + Rectangle bBounds = boundary.getFigure().getBounds(); + List enclosingBranches = boundary + .getEnclosingBranches(); + if ((!enclosingBranches.isEmpty()) + && sub.equals(enclosingBranches.get(0))) + bounds = bBounds.contains(bounds) ? bBounds : bounds; + } + } + + int x = bounds.x - minorSpacing - insSize.width / 2; + int y; + if (isUpwards()) + y = bounds.bottom() - inventSize.width / 2; + else + y = bounds.y + inventSize.width / 2; + + return new Point(x, y); + } + + if (index == subBranches.size()) { + IBranchPart sub = subBranches.get(subBranches.size() - 1); + Rectangle bounds = sub.getFigure().getBounds(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + Rectangle bBounds = boundary.getFigure().getBounds(); + List enclosingBranches = boundary + .getEnclosingBranches(); + if ((!enclosingBranches.isEmpty()) + && sub.equals(enclosingBranches + .get(enclosingBranches.size() - 1))) + bounds = bBounds.contains(bounds) ? bBounds : bounds; + } + } + + int x = bounds.right() + minorSpacing + insSize.width / 2; + int y; + if (isUpwards()) + y = bounds.bottom() - inventSize.width / 2; + else + y = bounds.y + inventSize.width / 2; + + return new Point(x, y); + } + return calcInventPosition(subBranches.get(index - 1), + subBranches.get(index), key, isUpwards()); + } + + protected Point calcMovePosition(IBranchPart branch, IBranchPart child, + ParentSearchKey key) { + List subBranches = branch.getSubBranches(); + List disables = getDisableBranches(branch); + + int index = calcInsIndex(branch, key, true); + int oldIndex = getOldIndex(branch, child); + if (disables != null) { + if (disables.contains(index - 1)) { + index--; + oldIndex = index; + } else if (disables.contains(index)) { + oldIndex = index; + } + } + Dimension inventSize = key.getInvent().getSize(); + + if (index == oldIndex) { + IBranchPart sub = subBranches.get(index); + int delta = sub.getTopicPart().getFigure().getSize().height / 2 + - inventSize.height / 2; + return getFigureLocation(sub.getFigure()).getTranslated(0, + isUpwards() ? delta : -delta); + } + + return calcInsertPosition(branch, child, key); + } + + @Override + protected Point calcFirstChildPosition(IBranchPart branch, + ParentSearchKey key) { + int y = branch.getFigure().getSize().height / 2 + + getMajorSpacing(branch) + + key.getInvent().getSize().height / 2; + return getFigureLocation(branch.getFigure()).getTranslated(0, + isUpwards() ? -y : y); + } + + @Override + protected Point calcInventPosition(IBranchPart orientation, + IBranchPart assist, ParentSearchKey key, boolean isRightOrUp) { + int minorSpacing = getMinorSpacing(orientation.getParentBranch()); + Dimension insSize = key.getFigure().getSize(); + Dimension inventSize = key.getInvent().getSize(); + + Rectangle oriBounds = orientation.getFigure().getBounds(); + Rectangle assBounds = assist.getFigure().getBounds(); + + Rectangle lBounds = oriBounds; + Rectangle rBounds = assBounds; + + List boundaries = orientation.getParentBranch() + .getBoundaries(); + if (!boundaries.isEmpty()) { + for (IBoundaryPart boundary : boundaries) { + List enclosingBranches = boundary + .getEnclosingBranches(); + Rectangle bBounds = boundary.getFigure().getBounds(); + + if ((!enclosingBranches.isEmpty()) && orientation.equals( + enclosingBranches.get(enclosingBranches.size() - 1))) + lBounds = bBounds.contains(lBounds) ? bBounds : lBounds; + + if ((!enclosingBranches.isEmpty()) + && assist.equals(enclosingBranches.get(0))) + rBounds = bBounds.contains(rBounds) ? bBounds : rBounds; + } + } + + boolean isBefourBounds; + Rectangle bounds; + if (lBounds.equals(oriBounds)) { + bounds = lBounds; + isBefourBounds = false; + } else if (rBounds.equals(assBounds)) { + bounds = rBounds; + isBefourBounds = true; + } else { + if (isRightOrUp) { + if (lBounds.bottom() < rBounds.bottom()) { + bounds = lBounds; + isBefourBounds = false; + } else { + bounds = rBounds; + isBefourBounds = true; + } + } else { + if (lBounds.y > rBounds.y) { + bounds = lBounds; + isBefourBounds = false; + } else { + bounds = rBounds; + isBefourBounds = true; + } + } + } + + int x; + if (isBefourBounds) + x = bounds.x - minorSpacing - insSize.width / 2; + else + x = bounds.right() + minorSpacing + insSize.width / 2; + + int y; + if (isRightOrUp) + y = bounds.bottom() - inventSize.height / 2; + else + y = bounds.y + inventSize.height / 2; + + return new Point(x, y); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpStructure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpStructure.java index a928a8c3e..b31da364d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpStructure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/branch/UpStructure.java @@ -1,22 +1,22 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.branch; - -public class UpStructure extends UpDownStructure { - - public UpStructure() { - super(true); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.branch; + +public class UpStructure extends UpDownStructure { + + public UpStructure() { + super(true); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentAction.java index 4bb475a4c..9b0c2f49a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentAction.java @@ -1,45 +1,45 @@ -package org.xmind.ui.internal.comments; - -import org.eclipse.jface.action.Action; -import org.eclipse.swt.widgets.Control; -import org.xmind.core.IComment; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; - -public abstract class CommentAction extends Action implements ICommentAction { - - private IGraphicalEditor targetEditor; - - protected Control control; - - public CommentAction(IGraphicalEditor targetEditor) { - this.targetEditor = targetEditor; - } - - @Override - public void run() { - if (control != null) { - control.forceFocus(); - } - super.run(); - } - - public void selectionChanged(Object selection) { - } - - public void selectedCommentChanged(IComment comment) { - } - - public void setTargetEditor(IGraphicalEditor targetEditor) { - this.targetEditor = targetEditor; - } - - protected IGraphicalEditor getTargetEditor() { - return targetEditor; - } - - protected ICommandStack getCommandStack() { - return targetEditor == null ? null : targetEditor.getCommandStack(); - } - -} +package org.xmind.ui.internal.comments; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Control; +import org.xmind.core.IComment; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; + +public abstract class CommentAction extends Action implements ICommentAction { + + private IGraphicalEditor targetEditor; + + protected Control control; + + public CommentAction(IGraphicalEditor targetEditor) { + this.targetEditor = targetEditor; + } + + @Override + public void run() { + if (control != null) { + control.forceFocus(); + } + super.run(); + } + + public void selectionChanged(Object selection) { + } + + public void selectedCommentChanged(IComment comment) { + } + + public void setTargetEditor(IGraphicalEditor targetEditor) { + this.targetEditor = targetEditor; + } + + protected IGraphicalEditor getTargetEditor() { + return targetEditor; + } + + protected ICommandStack getCommandStack() { + return targetEditor == null ? null : targetEditor.getCommandStack(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentTextViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentTextViewer.java index 9d602d419..8b9755cef 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentTextViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentTextViewer.java @@ -1,1319 +1,1326 @@ -package org.xmind.ui.internal.comments; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.text.DefaultTextDoubleClickStrategy; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentExtension3; -import org.eclipse.jface.text.ITextListener; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextViewer; -import org.eclipse.jface.text.TextViewerUndoManager; -import org.eclipse.jface.text.presentation.PresentationReconciler; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CaretEvent; -import org.eclipse.swt.custom.CaretListener; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Caret; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.events.IHyperlinkListener; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.internal.dom.DOMConstants; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.commands.AddCommentCommand; -import org.xmind.ui.commands.DeleteCommentCommand; -import org.xmind.ui.commands.ModifyCommentCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.e4models.CommentsPart; -import org.xmind.ui.internal.spelling.SpellingPlugin; -import org.xmind.ui.internal.spellsupport.SpellingSupport; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.richtext.RichTextDamagerRepairer; -import org.xmind.ui.richtext.RichTextScanner; -import org.xmind.ui.texteditor.ISpellingActivation; -import org.xmind.ui.util.TextFormatter; - -public class CommentTextViewer { - - private static class LessLatencyTextViewer extends TextViewer { - - private LessLatencyTextViewer(Composite parent, int styles) { - super(parent, styles); - } - - @Override - protected int getEmptySelectionChangedEventDelay() { - return 100; - } - } - - private static final int EXTRA_WIDTH = 22; - - private static int DEFAULT_STYLE = SWT.MULTI | SWT.WRAP | SWT.NO_SCROLL; - - private Color originalColor; - - private Color hoverColor; - - private Color selectColor; - - private IComment comment; - - private String objectId; - - private IWorkbook workbook; - - private ICommentsActionBarContributor contributor; - - private ISelectionProvider selectionProvider; - - private ICommentTextViewerContainer container; - - private ISpellingActivation spellingActivation; - - private IPreferenceStore spellingPreferences; - - private boolean editable = (DEFAULT_STYLE & SWT.READ_ONLY) == 0; - - private Composite control; - - private TextViewer textViewer; - - private MenuManager textContextMenuManager; - - private Menu textContextMenu; - - private IDocument document; - - private int textHeight = 17; - - private ICoreEventRegistration saveCommentReg; - - private MouseListener mouseListener; - - private ISelectionChangedListener selectionChangedListener; - - private FocusListener textFocusListener; - - private CaretListener caretListener; - - private ISelectionChangedListener postSelectionChangedListener; - - private IPropertyChangeListener propertyChangeListener; - - private ControlListener controlListener; - - private ITextListener textListener; - - private ModifyListener modifyListener; - - private IGraphicalEditor targetEditor; - - private StyleRange styleRange; - - private Label timeLabel; - - private Control modifyCommentActionBar; - - private boolean isLinkHovering; - - private Listener listener; - - private Menu contextMenu; - - private ResourceManager resources; - - public CommentTextViewer(IComment comment, String objectId, - IWorkbook workbook, ICommentsActionBarContributor contributor, - ISelectionProvider selectionProvider, - ICommentTextViewerContainer container, - IGraphicalEditor targetEditor) { - this.comment = comment; - this.objectId = objectId; - this.workbook = workbook; - this.contributor = contributor; - this.selectionProvider = selectionProvider; - this.container = container; - this.targetEditor = targetEditor; - - resources = new LocalResourceManager(JFaceResources.getResources(), - container.getContentComposite()); - - initColors(); - } - - private void initColors() { - if (container instanceof CommentsPopup) { - originalColor = CommentsPopup.BG_COLOR; - hoverColor = (Color) resources - .get(ColorUtils.toDescriptor("#f0f0f0")); //$NON-NLS-1$ - selectColor = (Color) resources - .get(ColorUtils.toDescriptor("#eaeaea")); //$NON-NLS-1$ - } else if (container instanceof CommentsPart) { - originalColor = (Color) resources - .get(ColorUtils.toDescriptor(CommentsPart.BG_COLOR)); - hoverColor = (Color) resources - .get(ColorUtils.toDescriptor("#f9f9f9")); //$NON-NLS-1$ - selectColor = (Color) resources - .get(ColorUtils.toDescriptor("#f5f5f5")); //$NON-NLS-1$ - } - } - - public Control createControl(Composite parent) { - control = new Composite(parent, SWT.NONE); - control.setBackground(parent.getBackground()); - control.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - - GridLayout layout = new GridLayout(); - layout.marginWidth = 0; - layout.marginHeight = 7; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - control.setLayout(layout); - - createContentArea(control); - - control.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - handleControlDispose(e); - } - }); - - //restore last editing. - if (comment != null && comment == container.getEditingComment()) { - startEditing(); - container.setModified(false); - container.setEditingComment(null); - } - - return control; - } - - private void createContentArea(Composite parent) { - if (comment == null) { - createNullContentArea(parent); - } else { - createNotNullContentArea(parent); - } - } - - private void createNullContentArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 10; - layout.marginHeight = 0; - layout.verticalSpacing = 5; - composite.setLayout(layout); - - Composite marginComposite = new Composite(composite, SWT.NONE); - marginComposite.setBackground(parent.getBackground()); - marginComposite.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 1; - layout2.marginHeight = 1; - marginComposite.setLayout(layout2); - - createNullTextControl(marginComposite); - createAddCommentActionBar(composite); - - marginComposite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ - } - - private void createNullTextControl(Composite parent) { - textViewer = createTextViewer(parent, DEFAULT_STYLE); - initTextViewer(textViewer); - setEditable(true); - - StyledText text = textViewer.getTextWidget(); - text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - text.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - text.setFont(JFaceResources.getDefaultFont()); - - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true); - gridData.horizontalIndent = 0; - gridData.verticalIndent = 0; - gridData.minimumHeight = 110; - - IDocument contentDocument = new Document(null); - setDocument(contentDocument); - - ScrolledComposite sc = container.getScrolledComposite(); - if (sc.getClientArea().width != 0) { - gridData.widthHint = sc.getClientArea().width - EXTRA_WIDTH; - } - text.setLayoutData(gridData); - sc.addControlListener(getControlListener()); - - text.addModifyListener(getModifyListener()); - text.addFocusListener(getFocusListener()); - - text.setFocus(); - } - - private void createAddCommentActionBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - composite.setBackground(parent.getBackground()); - GridLayout layout = new GridLayout(2, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - IAction cancelAddCommentAction = new Action() { - - @Override - public void run() { - resetModified(); - isLinkHovering = false; - container.cancelCreateComment(); - } - }; - - Hyperlink cancelLink = createLink(composite, - MindMapMessages.Comment_Cancel_text, - MindMapMessages.Comment_Cancel_tooltip, cancelAddCommentAction); - cancelLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); - - IAction addCommentAction = new Action() { - - @Override - public void run() { - addComment(); - } - }; - Hyperlink addLink = createLink(composite, - MindMapMessages.AddCommentLink_text, - MindMapMessages.AddCommentLink_tooltip, addCommentAction); - addLink.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, false)); - } - - private Hyperlink createLink(Composite parent, String text, String toolTip, - final IAction action) { - final Hyperlink link = new Hyperlink(parent, SWT.NONE); - link.setBackground(link.getParent().getBackground()); - link.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ - link.setFont((Font) resources.get( - JFaceResources.getDefaultFontDescriptor().increaseHeight(1))); - link.setText(text); - link.setToolTipText(toolTip); - link.setUnderlined(false); - link.addHyperlinkListener(new IHyperlinkListener() { - public void linkEntered(HyperlinkEvent e) { - link.setUnderlined(true); - isLinkHovering = true; - } - - public void linkExited(HyperlinkEvent e) { - link.setUnderlined(false); - isLinkHovering = false; - } - - public void linkActivated(HyperlinkEvent e) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - try { - action.run(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - }); - return link; - } - - private void createNotNullContentArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - composite.setBackground(parent.getBackground()); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 7; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground(parent.getBackground()); - composite2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout4 = new GridLayout(1, false); - layout4.marginWidth = 10 - layout.marginWidth; - layout4.marginHeight = 0; - composite2.setLayout(layout4); - - Composite marginComposite = new Composite(composite2, SWT.NONE); - marginComposite.setBackground(parent.getBackground()); - marginComposite.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 1; - layout2.marginHeight = 1; - marginComposite.setLayout(layout2); - - createNotNullTextControl(marginComposite); - - Composite composite3 = new Composite(parent, SWT.NONE); - composite3.setBackground(parent.getBackground()); - composite3.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout3 = new GridLayout(1, false); - layout3.marginWidth = 10; - layout3.marginHeight = 0; - composite3.setLayout(layout3); - - createTimeLabel(composite3); - createModifyCommentActionBar(composite3); - - modifyCommentActionBar.setVisible(false); - ((GridData) modifyCommentActionBar.getLayoutData()).exclude = true; - - addMouseFilter(); - CommentsUtils.addRecursiveMouseListener(control, getMouseListener(), - null); - addContextMenu(); - selectionProvider - .addSelectionChangedListener(getSelectionChangedListener()); - } - - private void createNotNullTextControl(Composite parent) { - textViewer = createTextViewer(parent, DEFAULT_STYLE); - initTextViewer(textViewer); - setEditable(false); - - StyledText text = textViewer.getTextWidget(); - text.setBackground(parent.getBackground()); - text.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#45464a"))); //$NON-NLS-1$ - text.setFont(JFaceResources.getDefaultFont()); - - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true); - gridData.minimumHeight = 22; - - String author = comment.getAuthor() + " : "; //$NON-NLS-1$ - String commentContent = comment.getContent(); - IDocument contentDocument = new Document(author + commentContent); - setDocument(contentDocument); - - styleRange = new StyleRange(); - styleRange.start = 0; - styleRange.length = author.lastIndexOf(':'); - styleRange.foreground = null; - styleRange.background = null; - styleRange.fontStyle = SWT.BOLD; - text.setStyleRange(styleRange); - - ScrolledComposite sc = container.getScrolledComposite(); - if (sc.getClientArea().width != 0) { - gridData.widthHint = sc.getClientArea().width - EXTRA_WIDTH; - } - text.setLayoutData(gridData); - sc.addControlListener(getControlListener()); - - text.addModifyListener(getModifyListener()); - text.addFocusListener(getFocusListener()); - } - - private void createTimeLabel(Composite parent) { - timeLabel = new Label(parent, SWT.NONE); - timeLabel.setAlignment(SWT.LEFT); - timeLabel.setBackground(parent.getBackground()); - timeLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#999999"))); //$NON-NLS-1$ - timeLabel.setFont((Font) resources.get( - JFaceResources.getDefaultFontDescriptor().increaseHeight(-1))); - - GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); - layoutData.horizontalIndent = 3; - layoutData.verticalIndent = 0; - timeLabel.setLayoutData(layoutData); - - if (comment != container.getLatestCreatedComment()) { - long timeMillisString = comment.getTime(); - String dateString = TextFormatter.formatTimeMillis(timeMillisString, - CommentsConstants.DATE_FORMAT_PATTERN); - String timeString = TextFormatter.formatTimeMillis(timeMillisString, - CommentsConstants.TIME_FORMAT_PATTERN); - timeLabel.setText(dateString + " at " + timeString); //$NON-NLS-1$ - } else { - container.setLatestCreatedComment(null); - timeLabel.setText(MindMapMessages.Comment_JustNow_text); - } - } - - private void createModifyCommentActionBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); - layoutData.verticalIndent = 5; - composite.setLayoutData(layoutData); - - composite.setBackground(parent.getBackground()); - GridLayout layout = new GridLayout(2, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - IAction cancelModifyAction = new Action() { - - @Override - public void run() { - cancelEditing(); - } - }; - Hyperlink cancelLink = createLink(composite, - MindMapMessages.Comment_Cancel_text, - MindMapMessages.Comment_Cancel_tooltip, cancelModifyAction); - cancelLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); - - IAction modifyCommentAction = new Action() { - - @Override - public void run() { - saveComment(); - } - }; - Hyperlink addLink = createLink(composite, - MindMapMessages.ModifyComment_text, - MindMapMessages.ModifyComment_tooltip, modifyCommentAction); - addLink.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, false)); - - modifyCommentActionBar = composite; - } - - //recursion add contextMenu - private void addContextMenu() { - setRecursionContextMenu(control, getContextMenu()); - } - - //recursion remove contextMenu - private void removeContextMenu() { - setRecursionContextMenu(control, null); - } - - private void setRecursionContextMenu(Control control, Menu contextMenu) { - if (control != null && !control.isDisposed()) { - control.setMenu(contextMenu); - } - if (control instanceof Composite) { - Control[] children = ((Composite) control).getChildren(); - for (Control child : children) { - setRecursionContextMenu(child, contextMenu); - } - } - } - - private Menu getContextMenu() { - if (contextMenu == null || contextMenu.isDisposed()) { - MenuManager menuManager = new MenuManager(); - - menuManager.add(new Action(MindMapMessages.Comment_Edit_label) { - @Override - public void run() { - startEditing(); - } - }); - - menuManager.add(new Action(MindMapMessages.Comment_Delete_label) { - @Override - public void run() { - DeleteCommentCommand cmd = new DeleteCommentCommand( - comment.getOwnedWorkbook().getElementById( - comment.getObjectId()), - comment); - ICommandStack cs = targetEditor.getCommandStack(); - cs.execute(cmd); - } - }); - - menuManager.add(new Action(MindMapMessages.Comment_Reply_label) { - @Override - public void run() { - container.createComment(comment.getObjectId()); - } - }); - - contextMenu = menuManager.createContextMenu(control.getShell()); - } - return contextMenu; - } - - private TextViewer createTextViewer(Composite parent, int style) { - return new LessLatencyTextViewer(parent, style); - } - - private void initTextViewer(TextViewer textViewer) { - Control control = textViewer.getTextWidget(); - createContentPopupMenu(control); - textViewer.setTextDoubleClickStrategy( - new DefaultTextDoubleClickStrategy(), - IDocument.DEFAULT_CONTENT_TYPE); - - textViewer.setUndoManager(new TextViewerUndoManager(25)); - textViewer.activatePlugins(); - addHyperlinkListener(textViewer); - } - - private void createContentPopupMenu(Control control) { - textContextMenuManager = new MenuManager(); - textContextMenuManager.setRemoveAllWhenShown(true); - textContextMenuManager.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - fillContextMenu(manager); - } - }); - textContextMenu = textContextMenuManager.createContextMenu(control); - control.setMenu(textContextMenu); - } - - private void fillContextMenu(IMenuManager menu) { - if (contributor != null) - contributor.fillContextMenu(menu); - } - - private void addHyperlinkListener(TextViewer viewer) { - PresentationReconciler reconciler = new PresentationReconciler(); - RichTextDamagerRepairer dr = new RichTextDamagerRepairer( - new RichTextScanner()); - reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); - reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); - reconciler.setDocumentPartitioning( - IDocumentExtension3.DEFAULT_PARTITIONING); - reconciler.install(viewer); - } - - private void addMouseFilter() { - Display.getCurrent().addFilter(SWT.MouseEnter, getListener()); - Display.getCurrent().addFilter(SWT.MouseExit, getListener()); - } - - private void removeMouseFilter() { - Display.getCurrent().removeFilter(SWT.MouseEnter, getListener()); - Display.getCurrent().removeFilter(SWT.MouseExit, getListener()); - } - - private Listener getListener() { - if (listener == null) { - listener = new Listener() { - - public void handleEvent(Event event) { - if (control.isDisposed()) { - removeMouseFilter(); - return; - } - if (event.widget instanceof Control) { - boolean isAncestor = isAncestorOf((Composite) control, - (Control) event.widget); - switch (event.type) { - case SWT.MouseEnter: - if (isAncestor) { - setRecursiveBackgroundColor(control, hoverColor, - null); - control.layout(); - } - break; - case SWT.MouseExit: - if (!isAncestor) { - if (textViewer.getTextWidget() - .isFocusControl()) { - setRecursiveBackgroundColor(control, - originalColor, getTextWidget()); - } else { - setRecursiveBackgroundColor(control, - originalColor, null); - } - control.layout(); - } - break; - } - } - } - }; - } - return listener; - } - - private boolean isAncestorOf(Control composite, Control control) { - if (control == composite) { - return true; - } - Composite parent = control.getParent(); - while (parent != null && parent != composite - && !(parent instanceof Shell)) { - parent = parent.getParent(); - } - return parent == composite; - } - - private void setRecursiveBackgroundColor(Control control, Color background, - Control excludeControl) { - if (control == excludeControl) { - return; - } - control.setBackground(background); - if (control instanceof Composite) { - Control[] children = ((Composite) control).getChildren(); - for (Control child : children) { - setRecursiveBackgroundColor(child, background, excludeControl); - } - } - } - - private MouseListener getMouseListener() { - if (mouseListener == null) { - mouseListener = new MouseAdapter() { - - public void mouseDown(MouseEvent e) { - if (getSelection() instanceof IStructuredSelection - && ((IStructuredSelection) getSelection()) - .getFirstElement() == CommentTextViewer.this) { - if (e.button == 1) { - selectionProvider.removeSelectionChangedListener( - getSelectionChangedListener()); - setSelection(null); - selectionProvider.addSelectionChangedListener( - getSelectionChangedListener()); - - startEditing(); - } - } else { - setSelection(new StructuredSelection( - CommentTextViewer.this)); - } - } - }; - } - - return mouseListener; - } - - private ISelectionChangedListener getSelectionChangedListener() { - if (selectionChangedListener == null) { - selectionChangedListener = new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - ISelection oldSelection = ((CommentsSelectionProvider) selectionProvider) - .getOldSelection(); - if (oldSelection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) oldSelection) - .getFirstElement(); - if (obj == CommentTextViewer.this - && !getTextWidget().isFocusControl()) { - ((CommentTextViewer) obj).commentDeselected(); - } - } - - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection) - .getFirstElement(); - if (obj == CommentTextViewer.this) { - commentSelected(); - } - } - } - }; - } - - return selectionChangedListener; - } - - private void commentSelected() { -// if (container instanceof CommentsView) { -// CommentsUtils.reveal(targetEditor, comment.getOwnedWorkbook() -// .getElementById(comment.getObjectId())); -// } - removeMouseFilter(); - setRecursiveBackgroundColor(control, selectColor, null); - - container.getContentComposite().pack(); - container.getContentComposite().layout(true, true); - } - - private void commentDeselected() { - addMouseFilter(); - - if (textViewer.getTextWidget().isFocusControl()) { - setRecursiveBackgroundColor(control, originalColor, - getTextWidget()); - } else { - setRecursiveBackgroundColor(control, originalColor, null); - } - - container.getContentComposite().pack(); - container.getContentComposite().layout(true, true); - } - - private FocusListener getFocusListener() { - if (textFocusListener == null) { - textFocusListener = new FocusListener() { - - public void focusGained(FocusEvent e) { - textViewer.getTextWidget().setBackground( - e.display.getSystemColor(SWT.COLOR_WHITE)); - - getTextWidget().addCaretListener(getCaretListener()); - getTextViewer().addTextListener(getTextListener()); - getTextViewer().addPostSelectionChangedListener( - getPostSelectionChangedListener()); - - addSpellChecker(textViewer); - showControl(); - updateActions(); - - container.setSelectedComment(comment); - } - - public void focusLost(FocusEvent e) { - textViewer.getTextWidget().setBackground(originalColor); - - getTextWidget().removeCaretListener(getCaretListener()); - getTextViewer().removePostSelectionChangedListener( - getPostSelectionChangedListener()); - setEditable(false); - removeSpellChecker(); - - container.setSelectedComment(null); - - if (!isLinkHovering) { - if (comment == null) { - addComment(); - container.setModified(true); - } else { - boolean modified = saveComment(); - container.setModified(modified); - } - } - } - }; - } - - return textFocusListener; - } - - private void startEditing() { - container.getContentComposite().forceFocus(); - - //store last editing. - if (container.isModified()) { - container.setModified(false); - container.setEditingComment(comment); - return; - } - if (control.isDisposed()) { - return; - } - - removeMouseFilter(); - setRecursiveBackgroundColor(control, originalColor, null); - getTextWidget().setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - - getTextWidget().getParent().setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ - - CommentsUtils.removeRecursiveMouseListener(control, getMouseListener(), - null); - removeContextMenu(); - textViewer.getControl().setMenu(textContextMenu); - - textViewer.getTextWidget().setStyleRange(null); - - String commentContent = comment.getContent(); - IDocument contentDocument = new Document(commentContent); - setDocument(contentDocument); - - timeLabel.setVisible(false); - ((GridData) timeLabel.getLayoutData()).exclude = true; - - modifyCommentActionBar.setVisible(true); - ((GridData) modifyCommentActionBar.getLayoutData()).exclude = false; - - ((GridData) textViewer.getControl() - .getLayoutData()).minimumHeight = 110; - setEditable(true); - - textViewer.getControl().setFocus(); - - container.getContentComposite().pack(); - container.getContentComposite().layout(true, true); - } - - private void cancelEditing() { - setRecursiveBackgroundColor(control, originalColor, null); - getTextWidget().setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#45464a"))); //$NON-NLS-1$ - - CommentsUtils.addRecursiveMouseListener(control, getMouseListener(), - null); - addContextMenu(); - - String author = comment.getAuthor() + " : "; //$NON-NLS-1$ - String commentContent = comment.getContent(); - IDocument contentDocument = new Document(author + commentContent); - setDocument(contentDocument); - - textViewer.getTextWidget().setStyleRange(styleRange); - - resetModified(); - - timeLabel.setVisible(true); - ((GridData) timeLabel.getLayoutData()).exclude = false; - - modifyCommentActionBar.setVisible(false); - ((GridData) modifyCommentActionBar.getLayoutData()).exclude = true; - - ((GridData) textViewer.getControl().getLayoutData()).minimumHeight = 22; - setEditable(false); - addMouseFilter(); - - if (container != null && container.getContentComposite() != null - && !container.getContentComposite().isDisposed()) { - container.getContentComposite().pack(); - container.getContentComposite().layout(true, true); - } - } - - private void showControl() { - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (!container.getScrolledComposite().isDisposed() - && !control.isDisposed()) { - container.getScrolledComposite().showControl(control); - } - } - }); - } - - private void updateActions() { - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (control.isDisposed() || getTextWidget().isDisposed()) { - return; - } - IComment selectedComment = (control.isFocusControl() - || getTextWidget().isFocusControl()) ? comment : null; - contributor.selectedCommentChanged(selectedComment); - } - }); - } - - private void addSpellChecker(ITextViewer textViewer) { - spellingActivation = SpellingSupport.getInstance() - .activateSpelling(textViewer); - spellingPreferences = SpellingPlugin.getDefault().getPreferenceStore(); - if (spellingPreferences != null) { - spellingPreferences - .addPropertyChangeListener(getPropertyChangeListener()); - } - contributor.setSpellingActivation(spellingActivation); - } - - private void removeSpellChecker() { - if (spellingPreferences != null) { - spellingPreferences - .removePropertyChangeListener(getPropertyChangeListener()); - spellingPreferences = null; - } - if (spellingActivation != null) { - spellingActivation.getSpellingSupport() - .deactivateSpelling(spellingActivation); - spellingActivation = null; - } - } - - //for SpellChecker - private IPropertyChangeListener getPropertyChangeListener() { - if (propertyChangeListener == null) { - propertyChangeListener = new IPropertyChangeListener() { - - public void propertyChange(PropertyChangeEvent event) { - if (SpellingPlugin.SPELLING_CHECK_ENABLED - .equals(event.getProperty())) { - if (spellingActivation != null) { - spellingActivation.getSpellingSupport() - .deactivateSpelling(spellingActivation); - spellingActivation = null; - } - if (spellingPreferences.getBoolean( - SpellingPlugin.SPELLING_CHECK_ENABLED)) { - spellingActivation = SpellingSupport.getInstance() - .activateSpelling(textViewer); - } - } - } - }; - } - - return propertyChangeListener; - } - - //sc.setNewOrigin when caret move(editing) - private CaretListener getCaretListener() { - if (caretListener == null) { - caretListener = new CaretListener() { - - public void caretMoved(CaretEvent event) { - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (getTextWidget() == null - || getTextWidget().isDisposed()) { - return; - } - - Caret caret = getTextWidget().getCaret(); - ScrolledComposite sc = container - .getScrolledComposite(); - Rectangle caretBounds = caret.getBounds(); - Rectangle scClientArea = sc.getClientArea(); - int caretToDisplayY = getTextWidget() - .toDisplay(caret.getLocation()).y; - Point scToDisplayPoint = sc.getParent() - .toDisplay(sc.getLocation()); - int scToDisplayY = scToDisplayPoint.y; - Point scOrigin = sc.getOrigin(); - if (caretToDisplayY - + caretBounds.height > scToDisplayY - + scClientArea.height) { - scOrigin.y += (caretToDisplayY - + caretBounds.height) - - (scToDisplayY + scClientArea.height); - sc.setOrigin(scOrigin); - } else if (caretToDisplayY < scToDisplayY) { - scOrigin.y -= scToDisplayY - caretToDisplayY; - sc.setOrigin(scOrigin); - } - } - }); - } - }; - } - - return caretListener; - } - - //update text popup menus' selection - private ISelectionChangedListener getPostSelectionChangedListener() { - if (postSelectionChangedListener == null) { - postSelectionChangedListener = new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - contributor.update(textViewer); - } - }; - } - - return postSelectionChangedListener; - } - - //set text.widthHint -- then pack in CommentsView / CommentsPopup. - private ControlListener getControlListener() { - if (controlListener == null) { - controlListener = new ControlListener() { - - public void controlMoved(ControlEvent e) { - } - - public void controlResized(ControlEvent e) { - if (container == null - || container.getContentComposite().isDisposed()) { - return; - } - Composite contentComposite = container - .getContentComposite(); - StyledText text = getTextWidget(); - if (text != null && !text.isDisposed()) { - ((GridData) text - .getLayoutData()).widthHint = contentComposite - .getParent().getClientArea().width - - EXTRA_WIDTH; - } - } - }; - } - - return controlListener; - } - - //register Core.WorkbookPreSaveOnce when editing -- make workbook dirty. - private ITextListener getTextListener() { - if (textListener == null) { - textListener = new ITextListener() { - - public void textChanged( - org.eclipse.jface.text.TextEvent event) { - activateJob(); - } - }; - } - - return textListener; - } - - //pack contentComposite when styledText be modified. - private ModifyListener getModifyListener() { - if (modifyListener == null) { - modifyListener = new ModifyListener() { - - public void modifyText(ModifyEvent event) { - Composite contentComposite = container - .getContentComposite(); - int realTextlHeight = contentComposite - .computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - if (textHeight != realTextlHeight) { - textHeight = realTextlHeight; - contentComposite.pack(); - } - } - }; - } - - return modifyListener; - } - - private void activateJob() { - if (saveCommentReg != null && saveCommentReg.isValid()) { - return; - } - saveCommentReg = null; - - if (workbook instanceof ICoreEventSource2) { - saveCommentReg = ((ICoreEventSource2) workbook) - .registerOnceCoreEventListener(Core.WorkbookPreSaveOnce, - ICoreEventListener.NULL); - } - } - - private void deactivateJob() { - if (saveCommentReg != null) { - saveCommentReg.unregister(); - saveCommentReg = null; - } - } - - private void resetModified() { - deactivateJob(); - getTextViewer().removeTextListener(getTextListener()); - } - - private void handleControlDispose(DisposeEvent e) { - if (textContextMenuManager != null) { - textContextMenuManager.dispose(); - textContextMenuManager = null; - } - if (textContextMenu != null) { - textContextMenu.dispose(); - textContextMenu = null; - } - if (contextMenu != null) { - contextMenu.dispose(); - contextMenu = null; - } - if (document != null) { - document = null; - } - removeMouseFilter(); - getTextWidget().removeFocusListener(getFocusListener()); - ScrolledComposite sc = container.getScrolledComposite(); - if (sc != null && !sc.isDisposed()) { - sc.removeControlListener(getControlListener()); - } - if (selectionProvider != null) { - selectionProvider.removeSelectionChangedListener( - getSelectionChangedListener()); - } - - getTextWidget().removeModifyListener(getModifyListener()); - } - - private boolean addComment() { - resetModified(); - isLinkHovering = false; - - final IDocument document = (IDocument) textViewer.getInput(); - if (document == null || document.get() == null - || document.get().equals("")) { //$NON-NLS-1$ - Display.getCurrent().asyncExec(new Runnable() { - - @Override - public void run() { - container.cancelCreateComment(); - } - }); - return false; - } - - String author = System.getProperty(DOMConstants.AUTHOR_NAME); - author = (author != null ? author : System.getProperty("user.name")); //$NON-NLS-1$ - long time = System.currentTimeMillis(); - IComment comment = workbook.getCommentManager().createComment(author, - time, objectId); - final AddCommentCommand cmd = new AddCommentCommand(author, time, - objectId, document.get(), workbook, comment); - - container.setLatestCreatedComment(comment); - - final ICommandStack cs = targetEditor.getCommandStack(); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - cs.execute(cmd); - } - }); - return true; - } - - private boolean saveComment() { - resetModified(); - isLinkHovering = false; - - String oldContent = (comment == null ? null : comment.getContent()); - IDocument document = (IDocument) textViewer.getDocument(); - String newContent = document.get(); - if (newContent != null && newContent.equals(oldContent)) { - cancelEditing(); - return false; - } - - final ICommandStack cs = targetEditor.getCommandStack(); - Command command = null; - - if (document == null || document.get() == null - || document.get().equals("")) { //$NON-NLS-1$ - command = new DeleteCommentCommand(comment.getOwnedWorkbook() - .getElementById(comment.getObjectId()), comment); - } else { - command = new ModifyCommentCommand(comment.getOwnedWorkbook() - .getElementById(comment.getObjectId()), comment, - document.get()); - } - - final Command command_0 = command; - Display.getCurrent().asyncExec(new Runnable() { - - @Override - public void run() { - cs.execute(command_0); - } - }); - - return true; - } - - private void setEditable(boolean editable) { - if (editable == this.editable) { - return; - } - this.editable = editable; - updateTextControl(); - } - - private void setDocument(IDocument document) { - this.document = document; - - textViewer.setDocument(document == null ? new Document() : document); - updateTextControl(); - // move the caret to the end of document - if (document != null) { - textViewer.setSelectedRange(document.getLength(), 0); - } - } - - private void updateTextControl() { - textViewer.setEditable(editable); - if (textViewer.getTextWidget() != null - && !textViewer.getTextWidget().isDisposed()) { - textViewer.getTextWidget().setEnabled(editable); - } - } - - public TextViewer getTextViewer() { - return textViewer; - } - - private StyledText getTextWidget() { - return textViewer.getTextWidget(); - } - - private ISelection getSelection() { - return selectionProvider.getSelection(); - } - - private void setSelection(ISelection selection) { - selectionProvider.setSelection(selection); - } - - public void setTargetEditor(IGraphicalEditor targetEditor) { - this.targetEditor = targetEditor; - } - -} +package org.xmind.ui.internal.comments; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.text.DefaultTextDoubleClickStrategy; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.TextViewerUndoManager; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CaretEvent; +import org.eclipse.swt.custom.CaretListener; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Caret; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.events.IHyperlinkListener; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.internal.dom.DOMConstants; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.commands.AddCommentCommand; +import org.xmind.ui.commands.DeleteCommentCommand; +import org.xmind.ui.commands.ModifyCommentCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.CommentsPart; +import org.xmind.ui.internal.spelling.SpellingPlugin; +import org.xmind.ui.internal.spellsupport.SpellingSupport; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.richtext.RichTextDamagerRepairer; +import org.xmind.ui.richtext.RichTextScanner; +import org.xmind.ui.texteditor.ISpellingActivation; +import org.xmind.ui.util.TextFormatter; + +public class CommentTextViewer { + + private static class LessLatencyTextViewer extends TextViewer { + + private LessLatencyTextViewer(Composite parent, int styles) { + super(parent, styles); + } + + @Override + protected int getEmptySelectionChangedEventDelay() { + return 100; + } + } + + private static final int EXTRA_WIDTH = 22; + + private static int DEFAULT_STYLE = SWT.MULTI | SWT.WRAP | SWT.NO_SCROLL; + + private Color originalColor; + + private Color hoverColor; + + private Color selectColor; + + private IComment comment; + + private String objectId; + + private IWorkbook workbook; + + private ICommentsActionBarContributor contributor; + + private ISelectionProvider selectionProvider; + + private ICommentTextViewerContainer container; + + private ISpellingActivation spellingActivation; + + private IPreferenceStore spellingPreferences; + + private boolean editable = (DEFAULT_STYLE & SWT.READ_ONLY) == 0; + + private Composite control; + + private TextViewer textViewer; + + private MenuManager textContextMenuManager; + + private Menu textContextMenu; + + private IDocument document; + + private int textHeight = 17; + + private ICoreEventRegistration saveCommentReg; + + private MouseListener mouseListener; + + private ISelectionChangedListener selectionChangedListener; + + private FocusListener textFocusListener; + + private CaretListener caretListener; + + private ISelectionChangedListener postSelectionChangedListener; + + private IPropertyChangeListener propertyChangeListener; + + private ControlListener controlListener; + + private ITextListener textListener; + + private ModifyListener modifyListener; + + private IGraphicalEditor targetEditor; + + private StyleRange styleRange; + + private Label timeLabel; + + private Control modifyCommentActionBar; + + private boolean isLinkHovering; + + private Listener listener; + + private Menu contextMenu; + + private ResourceManager resources; + + public CommentTextViewer(IComment comment, String objectId, + IWorkbook workbook, ICommentsActionBarContributor contributor, + ISelectionProvider selectionProvider, + ICommentTextViewerContainer container, + IGraphicalEditor targetEditor) { + this.comment = comment; + this.objectId = objectId; + this.workbook = workbook; + this.contributor = contributor; + this.selectionProvider = selectionProvider; + this.container = container; + this.targetEditor = targetEditor; + + resources = new LocalResourceManager(JFaceResources.getResources(), + container.getContentComposite()); + + initColors(); + } + + private void initColors() { + if (container instanceof CommentsPopup) { + originalColor = CommentsPopup.BG_COLOR; + hoverColor = (Color) resources + .get(ColorUtils.toDescriptor("#f0f0f0")); //$NON-NLS-1$ + selectColor = (Color) resources + .get(ColorUtils.toDescriptor("#eaeaea")); //$NON-NLS-1$ + } else if (container instanceof CommentsPart) { + originalColor = (Color) resources + .get(ColorUtils.toDescriptor(CommentsPart.BG_COLOR)); + hoverColor = (Color) resources + .get(ColorUtils.toDescriptor("#f9f9f9")); //$NON-NLS-1$ + selectColor = (Color) resources + .get(ColorUtils.toDescriptor("#f5f5f5")); //$NON-NLS-1$ + } + } + + public Control createControl(Composite parent) { + control = new Composite(parent, SWT.NONE); + control.setBackground(parent.getBackground()); + control.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 7; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + control.setLayout(layout); + + createContentArea(control); + + control.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleControlDispose(e); + } + }); + + //restore last editing. + if (comment != null && comment == container.getEditingComment()) { + startEditing(); + container.setModified(false); + container.setEditingComment(null); + } + + return control; + } + + private void createContentArea(Composite parent) { + if (comment == null) { + createNullContentArea(parent); + } else { + createNotNullContentArea(parent); + } + } + + private void createNullContentArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 10; + layout.marginHeight = 0; + layout.verticalSpacing = 5; + composite.setLayout(layout); + + Composite marginComposite = new Composite(composite, SWT.NONE); + marginComposite.setBackground(parent.getBackground()); + marginComposite.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 1; + layout2.marginHeight = 1; + marginComposite.setLayout(layout2); + + createNullTextControl(marginComposite); + createAddCommentActionBar(composite); + + marginComposite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ + } + + private void createNullTextControl(Composite parent) { + textViewer = createTextViewer(parent, DEFAULT_STYLE); + initTextViewer(textViewer); + setEditable(true); + + StyledText text = textViewer.getTextWidget(); + text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + text.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ + text.setFont(JFaceResources.getDefaultFont()); + + GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true); + gridData.horizontalIndent = 0; + gridData.verticalIndent = 0; + gridData.minimumHeight = 110; + + IDocument contentDocument = new Document(null); + setDocument(contentDocument); + + ScrolledComposite sc = container.getScrolledComposite(); + if (sc.getClientArea().width != 0) { + gridData.widthHint = sc.getClientArea().width - EXTRA_WIDTH; + } + text.setLayoutData(gridData); + sc.addControlListener(getControlListener()); + + text.addModifyListener(getModifyListener()); + text.addFocusListener(getFocusListener()); + + text.setFocus(); + } + + private void createAddCommentActionBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + composite.setBackground(parent.getBackground()); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + IAction cancelAddCommentAction = new Action() { + + @Override + public void run() { + resetModified(); + isLinkHovering = false; + container.cancelCreateComment(); + } + }; + + Hyperlink cancelLink = createLink(composite, + MindMapMessages.Comment_Cancel_text, + MindMapMessages.Comment_Cancel_tooltip, cancelAddCommentAction); + cancelLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); + + IAction addCommentAction = new Action() { + + @Override + public void run() { + addComment(); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.ADD_COMMENT_COUNT); + } + }; + Hyperlink addLink = createLink(composite, + MindMapMessages.AddCommentLink_text, + MindMapMessages.AddCommentLink_tooltip, addCommentAction); + addLink.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, false)); + } + + private Hyperlink createLink(Composite parent, String text, String toolTip, + final IAction action) { + final Hyperlink link = new Hyperlink(parent, SWT.NONE); + link.setBackground(link.getParent().getBackground()); + link.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ + link.setFont((Font) resources.get( + JFaceResources.getDefaultFontDescriptor().increaseHeight(1))); + link.setText(text); + link.setToolTipText(toolTip); + link.setUnderlined(false); + link.addHyperlinkListener(new IHyperlinkListener() { + public void linkEntered(HyperlinkEvent e) { + link.setUnderlined(true); + isLinkHovering = true; + } + + public void linkExited(HyperlinkEvent e) { + link.setUnderlined(false); + isLinkHovering = false; + } + + public void linkActivated(HyperlinkEvent e) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + try { + action.run(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + }); + return link; + } + + private void createNotNullContentArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setBackground(parent.getBackground()); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 7; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(parent.getBackground()); + composite2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout4 = new GridLayout(1, false); + layout4.marginWidth = 10 - layout.marginWidth; + layout4.marginHeight = 0; + composite2.setLayout(layout4); + + Composite marginComposite = new Composite(composite2, SWT.NONE); + marginComposite.setBackground(parent.getBackground()); + marginComposite.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 1; + layout2.marginHeight = 1; + marginComposite.setLayout(layout2); + + createNotNullTextControl(marginComposite); + + Composite composite3 = new Composite(parent, SWT.NONE); + composite3.setBackground(parent.getBackground()); + composite3.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout3 = new GridLayout(1, false); + layout3.marginWidth = 10; + layout3.marginHeight = 0; + composite3.setLayout(layout3); + + createTimeLabel(composite3); + createModifyCommentActionBar(composite3); + + modifyCommentActionBar.setVisible(false); + ((GridData) modifyCommentActionBar.getLayoutData()).exclude = true; + + addMouseFilter(); + CommentsUtils.addRecursiveMouseListener(control, getMouseListener(), + null); + addContextMenu(); + selectionProvider + .addSelectionChangedListener(getSelectionChangedListener()); + } + + private void createNotNullTextControl(Composite parent) { + textViewer = createTextViewer(parent, DEFAULT_STYLE); + initTextViewer(textViewer); + setEditable(false); + + StyledText text = textViewer.getTextWidget(); + text.setBackground(parent.getBackground()); + text.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#45464a"))); //$NON-NLS-1$ + text.setFont(JFaceResources.getDefaultFont()); + + GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true); + gridData.minimumHeight = 22; + + String author = comment.getAuthor() + " : "; //$NON-NLS-1$ + String commentContent = comment.getContent(); + IDocument contentDocument = new Document(author + commentContent); + setDocument(contentDocument); + + styleRange = new StyleRange(); + styleRange.start = 0; + styleRange.length = author.lastIndexOf(':'); + styleRange.foreground = null; + styleRange.background = null; + styleRange.fontStyle = SWT.BOLD; + text.setStyleRange(styleRange); + + ScrolledComposite sc = container.getScrolledComposite(); + if (sc.getClientArea().width != 0) { + gridData.widthHint = sc.getClientArea().width - EXTRA_WIDTH; + } + text.setLayoutData(gridData); + sc.addControlListener(getControlListener()); + + text.addModifyListener(getModifyListener()); + text.addFocusListener(getFocusListener()); + } + + private void createTimeLabel(Composite parent) { + timeLabel = new Label(parent, SWT.NONE); + timeLabel.setAlignment(SWT.LEFT); + timeLabel.setBackground(parent.getBackground()); + timeLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#999999"))); //$NON-NLS-1$ + timeLabel.setFont((Font) resources.get( + JFaceResources.getDefaultFontDescriptor().increaseHeight(-1))); + + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); + layoutData.horizontalIndent = 3; + layoutData.verticalIndent = 0; + timeLabel.setLayoutData(layoutData); + + if (comment != container.getLatestCreatedComment()) { + long timeMillisString = comment.getTime(); + String dateString = TextFormatter.formatTimeMillis(timeMillisString, + CommentsConstants.DATE_FORMAT_PATTERN); + String timeString = TextFormatter.formatTimeMillis(timeMillisString, + CommentsConstants.TIME_FORMAT_PATTERN); + timeLabel.setText(dateString + " at " + timeString); //$NON-NLS-1$ + } else { + container.setLatestCreatedComment(null); + timeLabel.setText(MindMapMessages.Comment_JustNow_text); + } + } + + private void createModifyCommentActionBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); + layoutData.verticalIndent = 5; + composite.setLayoutData(layoutData); + + composite.setBackground(parent.getBackground()); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + IAction cancelModifyAction = new Action() { + + @Override + public void run() { + cancelEditing(); + } + }; + Hyperlink cancelLink = createLink(composite, + MindMapMessages.Comment_Cancel_text, + MindMapMessages.Comment_Cancel_tooltip, cancelModifyAction); + cancelLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); + + IAction modifyCommentAction = new Action() { + + @Override + public void run() { + saveComment(); + } + }; + Hyperlink addLink = createLink(composite, + MindMapMessages.ModifyComment_text, + MindMapMessages.ModifyComment_tooltip, modifyCommentAction); + addLink.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, false)); + + modifyCommentActionBar = composite; + } + + //recursion add contextMenu + private void addContextMenu() { + setRecursionContextMenu(control, getContextMenu()); + } + + //recursion remove contextMenu + private void removeContextMenu() { + setRecursionContextMenu(control, null); + } + + private void setRecursionContextMenu(Control control, Menu contextMenu) { + if (control != null && !control.isDisposed()) { + control.setMenu(contextMenu); + } + if (control instanceof Composite) { + Control[] children = ((Composite) control).getChildren(); + for (Control child : children) { + setRecursionContextMenu(child, contextMenu); + } + } + } + + private Menu getContextMenu() { + if (contextMenu == null || contextMenu.isDisposed()) { + MenuManager menuManager = new MenuManager(); + + menuManager.add(new Action(MindMapMessages.Comment_Edit_label) { + @Override + public void run() { + startEditing(); + } + }); + + menuManager.add(new Action(MindMapMessages.Comment_Delete_label) { + @Override + public void run() { + DeleteCommentCommand cmd = new DeleteCommentCommand( + comment.getOwnedWorkbook().getElementById( + comment.getObjectId()), + comment); + ICommandStack cs = targetEditor.getCommandStack(); + cs.execute(cmd); + } + }); + + menuManager.add(new Action(MindMapMessages.Comment_Reply_label) { + @Override + public void run() { + container.createComment(comment.getObjectId()); + } + }); + + contextMenu = menuManager.createContextMenu(control.getShell()); + } + return contextMenu; + } + + private TextViewer createTextViewer(Composite parent, int style) { + return new LessLatencyTextViewer(parent, style); + } + + private void initTextViewer(TextViewer textViewer) { + Control control = textViewer.getTextWidget(); + createContentPopupMenu(control); + textViewer.setTextDoubleClickStrategy( + new DefaultTextDoubleClickStrategy(), + IDocument.DEFAULT_CONTENT_TYPE); + + textViewer.setUndoManager(new TextViewerUndoManager(25)); + textViewer.activatePlugins(); + addHyperlinkListener(textViewer); + } + + private void createContentPopupMenu(Control control) { + textContextMenuManager = new MenuManager(); + textContextMenuManager.setRemoveAllWhenShown(true); + textContextMenuManager.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + textContextMenu = textContextMenuManager.createContextMenu(control); + control.setMenu(textContextMenu); + } + + private void fillContextMenu(IMenuManager menu) { + if (contributor != null) + contributor.fillContextMenu(menu); + } + + private void addHyperlinkListener(TextViewer viewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + RichTextDamagerRepairer dr = new RichTextDamagerRepairer( + new RichTextScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setDocumentPartitioning( + IDocumentExtension3.DEFAULT_PARTITIONING); + reconciler.install(viewer); + } + + private void addMouseFilter() { + Display.getCurrent().addFilter(SWT.MouseEnter, getListener()); + Display.getCurrent().addFilter(SWT.MouseExit, getListener()); + } + + private void removeMouseFilter() { + Display.getCurrent().removeFilter(SWT.MouseEnter, getListener()); + Display.getCurrent().removeFilter(SWT.MouseExit, getListener()); + } + + private Listener getListener() { + if (listener == null) { + listener = new Listener() { + + public void handleEvent(Event event) { + if (control.isDisposed()) { + removeMouseFilter(); + return; + } + if (event.widget instanceof Control) { + boolean isAncestor = isAncestorOf((Composite) control, + (Control) event.widget); + switch (event.type) { + case SWT.MouseEnter: + if (isAncestor) { + setRecursiveBackgroundColor(control, hoverColor, + null); + control.layout(); + } + break; + case SWT.MouseExit: + if (!isAncestor) { + if (textViewer.getTextWidget() + .isFocusControl()) { + setRecursiveBackgroundColor(control, + originalColor, getTextWidget()); + } else { + setRecursiveBackgroundColor(control, + originalColor, null); + } + control.layout(); + } + break; + } + } + } + }; + } + return listener; + } + + private boolean isAncestorOf(Control composite, Control control) { + if (control == composite) { + return true; + } + Composite parent = control.getParent(); + while (parent != null && parent != composite + && !(parent instanceof Shell)) { + parent = parent.getParent(); + } + return parent == composite; + } + + private void setRecursiveBackgroundColor(Control control, Color background, + Control excludeControl) { + if (control == excludeControl) { + return; + } + control.setBackground(background); + if (control instanceof Composite) { + Control[] children = ((Composite) control).getChildren(); + for (Control child : children) { + setRecursiveBackgroundColor(child, background, excludeControl); + } + } + } + + private MouseListener getMouseListener() { + if (mouseListener == null) { + mouseListener = new MouseAdapter() { + + public void mouseDown(MouseEvent e) { + if (getSelection() instanceof IStructuredSelection + && ((IStructuredSelection) getSelection()) + .getFirstElement() == CommentTextViewer.this) { + if (e.button == 1) { + selectionProvider.removeSelectionChangedListener( + getSelectionChangedListener()); + setSelection(null); + selectionProvider.addSelectionChangedListener( + getSelectionChangedListener()); + + startEditing(); + } + } else { + setSelection(new StructuredSelection( + CommentTextViewer.this)); + } + } + }; + } + + return mouseListener; + } + + private ISelectionChangedListener getSelectionChangedListener() { + if (selectionChangedListener == null) { + selectionChangedListener = new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + ISelection oldSelection = ((CommentsSelectionProvider) selectionProvider) + .getOldSelection(); + if (oldSelection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) oldSelection) + .getFirstElement(); + if (obj == CommentTextViewer.this + && !getTextWidget().isFocusControl()) { + ((CommentTextViewer) obj).commentDeselected(); + } + } + + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + if (obj == CommentTextViewer.this) { + commentSelected(); + } + } + } + }; + } + + return selectionChangedListener; + } + + private void commentSelected() { +// if (container instanceof CommentsView) { +// CommentsUtils.reveal(targetEditor, comment.getOwnedWorkbook() +// .getElementById(comment.getObjectId())); +// } + removeMouseFilter(); + setRecursiveBackgroundColor(control, selectColor, null); + + container.getContentComposite().pack(); + container.getContentComposite().layout(true, true); + } + + private void commentDeselected() { + addMouseFilter(); + + if (textViewer.getTextWidget().isFocusControl()) { + setRecursiveBackgroundColor(control, originalColor, + getTextWidget()); + } else { + setRecursiveBackgroundColor(control, originalColor, null); + } + + container.getContentComposite().pack(); + container.getContentComposite().layout(true, true); + } + + private FocusListener getFocusListener() { + if (textFocusListener == null) { + textFocusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + textViewer.getTextWidget().setBackground( + e.display.getSystemColor(SWT.COLOR_WHITE)); + + getTextWidget().addCaretListener(getCaretListener()); + getTextViewer().addTextListener(getTextListener()); + getTextViewer().addPostSelectionChangedListener( + getPostSelectionChangedListener()); + + addSpellChecker(textViewer); + showControl(); + updateActions(); + + container.setSelectedComment(comment); + } + + public void focusLost(FocusEvent e) { + textViewer.getTextWidget().setBackground(originalColor); + + getTextWidget().removeCaretListener(getCaretListener()); + getTextViewer().removePostSelectionChangedListener( + getPostSelectionChangedListener()); + setEditable(false); + removeSpellChecker(); + + container.setSelectedComment(null); + + if (!isLinkHovering) { + if (comment == null) { + addComment(); + container.setModified(true); + } else { + boolean modified = saveComment(); + container.setModified(modified); + } + } + } + }; + } + + return textFocusListener; + } + + private void startEditing() { + container.getContentComposite().forceFocus(); + + //store last editing. + if (container.isModified()) { + container.setModified(false); + container.setEditingComment(comment); + return; + } + if (control.isDisposed()) { + return; + } + + removeMouseFilter(); + setRecursiveBackgroundColor(control, originalColor, null); + getTextWidget().setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ + + getTextWidget().getParent().setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ + + CommentsUtils.removeRecursiveMouseListener(control, getMouseListener(), + null); + removeContextMenu(); + textViewer.getControl().setMenu(textContextMenu); + + textViewer.getTextWidget().setStyleRange(null); + + String commentContent = comment.getContent(); + IDocument contentDocument = new Document(commentContent); + setDocument(contentDocument); + + timeLabel.setVisible(false); + ((GridData) timeLabel.getLayoutData()).exclude = true; + + modifyCommentActionBar.setVisible(true); + ((GridData) modifyCommentActionBar.getLayoutData()).exclude = false; + + ((GridData) textViewer.getControl() + .getLayoutData()).minimumHeight = 110; + setEditable(true); + + textViewer.getControl().setFocus(); + + container.getContentComposite().pack(); + container.getContentComposite().layout(true, true); + } + + private void cancelEditing() { + setRecursiveBackgroundColor(control, originalColor, null); + getTextWidget().setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#45464a"))); //$NON-NLS-1$ + + CommentsUtils.addRecursiveMouseListener(control, getMouseListener(), + null); + addContextMenu(); + + String author = comment.getAuthor() + " : "; //$NON-NLS-1$ + String commentContent = comment.getContent(); + IDocument contentDocument = new Document(author + commentContent); + setDocument(contentDocument); + + textViewer.getTextWidget().setStyleRange(styleRange); + + resetModified(); + + timeLabel.setVisible(true); + ((GridData) timeLabel.getLayoutData()).exclude = false; + + modifyCommentActionBar.setVisible(false); + ((GridData) modifyCommentActionBar.getLayoutData()).exclude = true; + + ((GridData) textViewer.getControl().getLayoutData()).minimumHeight = 22; + setEditable(false); + addMouseFilter(); + + if (container != null && container.getContentComposite() != null + && !container.getContentComposite().isDisposed()) { + container.getContentComposite().pack(); + container.getContentComposite().layout(true, true); + } + } + + private void showControl() { + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (!container.getScrolledComposite().isDisposed() + && !control.isDisposed()) { + container.getScrolledComposite().showControl(control); + } + } + }); + } + + private void updateActions() { + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (control.isDisposed() || getTextWidget().isDisposed()) { + return; + } + IComment selectedComment = (control.isFocusControl() + || getTextWidget().isFocusControl()) ? comment : null; + contributor.selectedCommentChanged(selectedComment); + } + }); + } + + private void addSpellChecker(ITextViewer textViewer) { + spellingActivation = SpellingSupport.getInstance() + .activateSpelling(textViewer); + spellingPreferences = SpellingPlugin.getDefault().getPreferenceStore(); + if (spellingPreferences != null) { + spellingPreferences + .addPropertyChangeListener(getPropertyChangeListener()); + } + contributor.setSpellingActivation(spellingActivation); + } + + private void removeSpellChecker() { + if (spellingPreferences != null) { + spellingPreferences + .removePropertyChangeListener(getPropertyChangeListener()); + spellingPreferences = null; + } + if (spellingActivation != null) { + spellingActivation.getSpellingSupport() + .deactivateSpelling(spellingActivation); + spellingActivation = null; + } + } + + //for SpellChecker + private IPropertyChangeListener getPropertyChangeListener() { + if (propertyChangeListener == null) { + propertyChangeListener = new IPropertyChangeListener() { + + public void propertyChange(PropertyChangeEvent event) { + if (SpellingPlugin.SPELLING_CHECK_ENABLED + .equals(event.getProperty())) { + if (spellingActivation != null) { + spellingActivation.getSpellingSupport() + .deactivateSpelling(spellingActivation); + spellingActivation = null; + } + if (spellingPreferences.getBoolean( + SpellingPlugin.SPELLING_CHECK_ENABLED)) { + spellingActivation = SpellingSupport.getInstance() + .activateSpelling(textViewer); + } + } + } + }; + } + + return propertyChangeListener; + } + + //sc.setNewOrigin when caret move(editing) + private CaretListener getCaretListener() { + if (caretListener == null) { + caretListener = new CaretListener() { + + public void caretMoved(CaretEvent event) { + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (getTextWidget() == null + || getTextWidget().isDisposed()) { + return; + } + + Caret caret = getTextWidget().getCaret(); + ScrolledComposite sc = container + .getScrolledComposite(); + Rectangle caretBounds = caret.getBounds(); + Rectangle scClientArea = sc.getClientArea(); + int caretToDisplayY = getTextWidget() + .toDisplay(caret.getLocation()).y; + Point scToDisplayPoint = sc.getParent() + .toDisplay(sc.getLocation()); + int scToDisplayY = scToDisplayPoint.y; + Point scOrigin = sc.getOrigin(); + if (caretToDisplayY + + caretBounds.height > scToDisplayY + + scClientArea.height) { + scOrigin.y += (caretToDisplayY + + caretBounds.height) + - (scToDisplayY + scClientArea.height); + sc.setOrigin(scOrigin); + } else if (caretToDisplayY < scToDisplayY) { + scOrigin.y -= scToDisplayY - caretToDisplayY; + sc.setOrigin(scOrigin); + } + } + }); + } + }; + } + + return caretListener; + } + + //update text popup menus' selection + private ISelectionChangedListener getPostSelectionChangedListener() { + if (postSelectionChangedListener == null) { + postSelectionChangedListener = new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + contributor.update(textViewer); + } + }; + } + + return postSelectionChangedListener; + } + + //set text.widthHint -- then pack in CommentsView / CommentsPopup. + private ControlListener getControlListener() { + if (controlListener == null) { + controlListener = new ControlListener() { + + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + if (container == null + || container.getContentComposite().isDisposed()) { + return; + } + Composite contentComposite = container + .getContentComposite(); + StyledText text = getTextWidget(); + if (text != null && !text.isDisposed()) { + ((GridData) text + .getLayoutData()).widthHint = contentComposite + .getParent().getClientArea().width + - EXTRA_WIDTH; + } + } + }; + } + + return controlListener; + } + + //register Core.WorkbookPreSaveOnce when editing -- make workbook dirty. + private ITextListener getTextListener() { + if (textListener == null) { + textListener = new ITextListener() { + + public void textChanged( + org.eclipse.jface.text.TextEvent event) { + activateJob(); + } + }; + } + + return textListener; + } + + //pack contentComposite when styledText be modified. + private ModifyListener getModifyListener() { + if (modifyListener == null) { + modifyListener = new ModifyListener() { + + public void modifyText(ModifyEvent event) { + Composite contentComposite = container + .getContentComposite(); + int realTextlHeight = contentComposite + .computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + if (textHeight != realTextlHeight) { + textHeight = realTextlHeight; + contentComposite.pack(); + } + } + }; + } + + return modifyListener; + } + + private void activateJob() { + if (saveCommentReg != null && saveCommentReg.isValid()) { + return; + } + saveCommentReg = null; + + if (workbook instanceof ICoreEventSource2) { + saveCommentReg = ((ICoreEventSource2) workbook) + .registerOnceCoreEventListener(Core.WorkbookPreSaveOnce, + ICoreEventListener.NULL); + } + } + + private void deactivateJob() { + if (saveCommentReg != null) { + saveCommentReg.unregister(); + saveCommentReg = null; + } + } + + private void resetModified() { + deactivateJob(); + getTextViewer().removeTextListener(getTextListener()); + } + + private void handleControlDispose(DisposeEvent e) { + if (textContextMenuManager != null) { + textContextMenuManager.dispose(); + textContextMenuManager = null; + } + if (textContextMenu != null) { + textContextMenu.dispose(); + textContextMenu = null; + } + if (contextMenu != null) { + contextMenu.dispose(); + contextMenu = null; + } + if (document != null) { + document = null; + } + removeMouseFilter(); + getTextWidget().removeFocusListener(getFocusListener()); + ScrolledComposite sc = container.getScrolledComposite(); + if (sc != null && !sc.isDisposed()) { + sc.removeControlListener(getControlListener()); + } + if (selectionProvider != null) { + selectionProvider.removeSelectionChangedListener( + getSelectionChangedListener()); + } + + getTextWidget().removeModifyListener(getModifyListener()); + } + + private boolean addComment() { + resetModified(); + isLinkHovering = false; + + final IDocument document = (IDocument) textViewer.getInput(); + if (document == null || document.get() == null + || document.get().equals("")) { //$NON-NLS-1$ + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + container.cancelCreateComment(); + } + }); + return false; + } + + String author = System.getProperty(DOMConstants.AUTHOR_NAME); + author = (author != null ? author : System.getProperty("user.name")); //$NON-NLS-1$ + long time = System.currentTimeMillis(); + IComment comment = workbook.getCommentManager().createComment(author, + time, objectId); + final AddCommentCommand cmd = new AddCommentCommand(author, time, + objectId, document.get(), workbook, comment); + + container.setLatestCreatedComment(comment); + + final ICommandStack cs = targetEditor.getCommandStack(); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + cs.execute(cmd); + } + }); + return true; + } + + private boolean saveComment() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.ADD_COMMENT_COUNT); + + resetModified(); + isLinkHovering = false; + + String oldContent = (comment == null ? null : comment.getContent()); + IDocument document = (IDocument) textViewer.getDocument(); + String newContent = document.get(); + if (newContent != null && newContent.equals(oldContent)) { + cancelEditing(); + return false; + } + + final ICommandStack cs = targetEditor.getCommandStack(); + Command command = null; + + if (document == null || document.get() == null + || document.get().equals("")) { //$NON-NLS-1$ + command = new DeleteCommentCommand(comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()), comment); + } else { + command = new ModifyCommentCommand(comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()), comment, + document.get()); + } + + final Command command_0 = command; + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + cs.execute(command_0); + } + }); + + return true; + } + + private void setEditable(boolean editable) { + if (editable == this.editable) { + return; + } + this.editable = editable; + updateTextControl(); + } + + private void setDocument(IDocument document) { + this.document = document; + + textViewer.setDocument(document == null ? new Document() : document); + updateTextControl(); + // move the caret to the end of document + if (document != null) { + textViewer.setSelectedRange(document.getLength(), 0); + } + } + + private void updateTextControl() { + textViewer.setEditable(editable); + if (textViewer.getTextWidget() != null + && !textViewer.getTextWidget().isDisposed()) { + textViewer.getTextWidget().setEnabled(editable); + } + } + + public TextViewer getTextViewer() { + return textViewer; + } + + private StyledText getTextWidget() { + return textViewer.getTextWidget(); + } + + private ISelection getSelection() { + return selectionProvider.getSelection(); + } + + private void setSelection(ISelection selection) { + selectionProvider.setSelection(selection); + } + + public void setTargetEditor(IGraphicalEditor targetEditor) { + this.targetEditor = targetEditor; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsActionBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsActionBarContributor.java index 306ac0047..8d1c4f29f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsActionBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsActionBarContributor.java @@ -1,96 +1,96 @@ -package org.xmind.ui.internal.comments; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.ui.actions.ActionFactory; -import org.xmind.core.IComment; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.texteditor.IMenuContributor; -import org.xmind.ui.texteditor.ISpellingActivation; - -public abstract class CommentsActionBarContributor - implements ICommentsActionBarContributor { - - protected IGraphicalEditor targetEditor; - - private Map actions = new HashMap(); - - private ISpellingActivation spellingActivation; - - public CommentsActionBarContributor(IGraphicalEditor targetEditor) { - this.targetEditor = targetEditor; - } - - protected void makeActions() { - } - - protected void addAction(CommentAction action) { - if (action != null && action.getId() != null) - actions.put(action.getId(), action); - } - - public void setSpellingActivation(ISpellingActivation spellingActivation) { - this.spellingActivation = spellingActivation; - } - - public void fillToolBar(IToolBarManager toolbar) { - } - - public void fillContextMenu(IMenuManager menu) { - menu.add(getContextAction(ActionFactory.UNDO.getId())); - menu.add(getContextAction(ActionFactory.REDO.getId())); - menu.add(new Separator()); - menu.add(getContextAction(ActionFactory.CUT.getId())); - menu.add(getContextAction(ActionFactory.COPY.getId())); - menu.add(getContextAction(ActionFactory.PASTE.getId())); - menu.add(new Separator()); - menu.add(getContextAction(ActionFactory.SELECT_ALL.getId())); - - if (spellingActivation != null) { - IMenuContributor contributor = (IMenuContributor) spellingActivation - .getAdapter(IMenuContributor.class); - if (contributor != null) { - menu.add(new Separator()); - contributor.fillMenu(menu); - } - } - } - - protected abstract IAction getContextAction(String actionId); - - public CommentAction getAction(String id) { - return actions.get(id); - } - - public void selectionChanged(Object selection) { - for (CommentAction action : actions.values()) { - action.selectionChanged(selection); - } - } - - public void selectedCommentChanged(IComment comment) { - for (CommentAction action : actions.values()) { - action.selectedCommentChanged(comment); - } - } - - public void dispose() { - actions.clear(); - } - - public void setTargetEditor(IGraphicalEditor targetEditor) { - if (this.targetEditor != targetEditor) { - this.targetEditor = targetEditor; - for (Entry entry : actions.entrySet()) { - entry.getValue().setTargetEditor(targetEditor); - } - } - } - +package org.xmind.ui.internal.comments; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.actions.ActionFactory; +import org.xmind.core.IComment; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.texteditor.IMenuContributor; +import org.xmind.ui.texteditor.ISpellingActivation; + +public abstract class CommentsActionBarContributor + implements ICommentsActionBarContributor { + + protected IGraphicalEditor targetEditor; + + private Map actions = new HashMap(); + + private ISpellingActivation spellingActivation; + + public CommentsActionBarContributor(IGraphicalEditor targetEditor) { + this.targetEditor = targetEditor; + } + + protected void makeActions() { + } + + protected void addAction(CommentAction action) { + if (action != null && action.getId() != null) + actions.put(action.getId(), action); + } + + public void setSpellingActivation(ISpellingActivation spellingActivation) { + this.spellingActivation = spellingActivation; + } + + public void fillToolBar(IToolBarManager toolbar) { + } + + public void fillContextMenu(IMenuManager menu) { + menu.add(getContextAction(ActionFactory.UNDO.getId())); + menu.add(getContextAction(ActionFactory.REDO.getId())); + menu.add(new Separator()); + menu.add(getContextAction(ActionFactory.CUT.getId())); + menu.add(getContextAction(ActionFactory.COPY.getId())); + menu.add(getContextAction(ActionFactory.PASTE.getId())); + menu.add(new Separator()); + menu.add(getContextAction(ActionFactory.SELECT_ALL.getId())); + + if (spellingActivation != null) { + IMenuContributor contributor = (IMenuContributor) spellingActivation + .getAdapter(IMenuContributor.class); + if (contributor != null) { + menu.add(new Separator()); + contributor.fillMenu(menu); + } + } + } + + protected abstract IAction getContextAction(String actionId); + + public CommentAction getAction(String id) { + return actions.get(id); + } + + public void selectionChanged(Object selection) { + for (CommentAction action : actions.values()) { + action.selectionChanged(selection); + } + } + + public void selectedCommentChanged(IComment comment) { + for (CommentAction action : actions.values()) { + action.selectedCommentChanged(comment); + } + } + + public void dispose() { + actions.clear(); + } + + public void setTargetEditor(IGraphicalEditor targetEditor) { + if (this.targetEditor != targetEditor) { + this.targetEditor = targetEditor; + for (Entry entry : actions.entrySet()) { + entry.getValue().setTargetEditor(targetEditor); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsConstants.java index b6c1d4916..c62c7694f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsConstants.java @@ -1,11 +1,11 @@ -package org.xmind.ui.internal.comments; - -public class CommentsConstants { - - public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd"; //$NON-NLS-1$ - - public static final String TIME_FORMAT_PATTERN = "HH:mm"; //$NON-NLS-1$ - - public static final String COMMENTS_POPUP_SHOWN = "commentsPopupShown"; //$NON-NLS-1$ - -} +package org.xmind.ui.internal.comments; + +public class CommentsConstants { + + public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd"; //$NON-NLS-1$ + + public static final String TIME_FORMAT_PATTERN = "HH:mm"; //$NON-NLS-1$ + + public static final String COMMENTS_POPUP_SHOWN = "commentsPopupShown"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsInfoItemContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsInfoItemContributor.java index 333a78440..f647d0794 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsInfoItemContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsInfoItemContributor.java @@ -1,191 +1,191 @@ -package org.xmind.ui.internal.comments; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.gef.EditDomain; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.actions.IActionRegistry; -import org.xmind.ui.actions.DelegatingAction; -import org.xmind.ui.commands.DeleteCommentCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.AbstractInfoItemContributor; -import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.TextFormatter; - -public class CommentsInfoItemContributor extends AbstractInfoItemContributor { - - private static final String PRESENTATION_VIERWER_CLASS_NAME = "PresentationViewer"; //$NON-NLS-1$ - - private static class ShowCommentsAction extends Action { - - private ITopicPart topicPart; - - public ShowCommentsAction(ITopicPart topicPart) { - super(MindMapMessages.EditComments_text, - MindMapUI.getImages().get("menu_modify_comment.png", true)); //$NON-NLS-1$ - setId("org.xmind.ui.editComments"); //$NON-NLS-1$ - this.topicPart = topicPart; - } - - public void run() { - if (topicPart == null || topicPart.getSite() == null - || topicPart.getSite().getViewer() == null - || topicPart.getSite().getViewer().getClass() - .getSimpleName() - .equals(PRESENTATION_VIERWER_CLASS_NAME)) - return; - - if (!topicPart.getStatus().isActive()) - return; - - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window == null) - return; - - CommentsPopup popup = new CommentsPopup(window, topicPart, false); - popup.open(); - } - } - - public IAction createAction(ITopicPart topicPart, ITopic topic) { - Set comments = new TreeSet(topic.getOwnedWorkbook() - .getCommentManager().getComments(topic.getId())); - if (comments.isEmpty()) - return null; - - IAction action = null; - IActionRegistry actionRegistry = (IActionRegistry) topicPart - .getAdapter(IActionRegistry.class); - if (actionRegistry != null) { - action = actionRegistry.getAction("org.xmind.ui.editComments"); //$NON-NLS-1$ - if (action != null) - action = new DelegatingAction(action); - } - - if (action == null) - action = new ShowCommentsAction(topicPart); - - StringBuilder text = new StringBuilder(); - - Iterator commentIt = comments.iterator(); - while (commentIt.hasNext()) { - IComment comment = commentIt.next(); - String author = comment.getAuthor(); - String content = comment.getContent(); - - long timeMillisString = comment.getTime(); - - text.append(author); - text.append(" : "); //$NON-NLS-1$ - text.append(content); - text.append('\n'); - text.append(TextFormatter.formatTimeMillis(timeMillisString, - CommentsConstants.DATE_FORMAT_PATTERN)); - text.append(' '); - text.append(TextFormatter.formatTimeMillis(timeMillisString, - CommentsConstants.TIME_FORMAT_PATTERN)); - if (commentIt.hasNext()) { - text.append("\n\n"); //$NON-NLS-1$ - } - - if (text.length() > 500) - break; - } - - if (text.length() > 500) { - text.delete(501, text.length()); - text.append("...\n..."); //$NON-NLS-1$ - } - action.setToolTipText(text.toString()); - - return action; - } - - @Override - protected void registerTopicEvent(ITopicPart topicPart, ITopic topic, - ICoreEventRegister register) { - register.register(Core.CommentAdd); - register.register(Core.CommentRemove); - - register.setNextSupport( - topic.getOwnedWorkbook().getAdapter(ICoreEventSupport.class)); - register.register(Core.CommentContent); - } - - private void removeComments(ITopicPart topicPart) { - ITopic topic = topicPart.getTopic(); - Set comments = topic.getOwnedWorkbook().getCommentManager() - .getComments(topic.getId()); - if (comments.isEmpty()) - return; - - List commands = new ArrayList(comments.size()); - for (IComment comment : comments) { - commands.add(new DeleteCommentCommand(topic, comment)); - } - Command command = new CompoundCommand( - MindMapMessages.Comment_Delete_label, commands); - - EditDomain domain = topicPart.getSite().getDomain(); - ICommandStack commandStack = domain == null ? null - : domain.getCommandStack(); - if (commandStack != null) { - commandStack.execute(command); - } else { - command.execute(); - } - } - - @Override - public List getPopupMenuActions(final ITopicPart topicPart, - final ITopic topic) { - List actions = new ArrayList(); - - IAction editCommentsAction = createAction(topicPart, topic); - editCommentsAction.setText(MindMapMessages.ModifyMenu); - editCommentsAction.setImageDescriptor(null); - actions.add(editCommentsAction); - - IAction deleteCommentsAction = new Action( - MindMapMessages.Comment_Delete_label) { - @Override - public void run() { - removeComments(topicPart); - }; - }; - deleteCommentsAction.setId("org.xmind.ui.removeComments"); //$NON-NLS-1$ - deleteCommentsAction.setImageDescriptor(null); - actions.add(deleteCommentsAction); - - return actions; - } - - @Override - protected void handleTopicEvent(IInfoPart infoPart, CoreEvent event) { - } - - @Override - protected void handleTopicEvent(ITopicPart topicPart, CoreEvent event) { - topicPart.refresh(); - } - -} +package org.xmind.ui.internal.comments; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.gef.EditDomain; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.actions.IActionRegistry; +import org.xmind.ui.actions.DelegatingAction; +import org.xmind.ui.commands.DeleteCommentCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.AbstractInfoItemContributor; +import org.xmind.ui.mindmap.IInfoPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.TextFormatter; + +public class CommentsInfoItemContributor extends AbstractInfoItemContributor { + + private static final String PRESENTATION_VIERWER_CLASS_NAME = "PresentationViewer"; //$NON-NLS-1$ + + private static class ShowCommentsAction extends Action { + + private ITopicPart topicPart; + + public ShowCommentsAction(ITopicPart topicPart) { + super(MindMapMessages.EditComments_text, + MindMapUI.getImages().get("menu_modify_comment.png", true)); //$NON-NLS-1$ + setId("org.xmind.ui.editComments"); //$NON-NLS-1$ + this.topicPart = topicPart; + } + + public void run() { + if (topicPart == null || topicPart.getSite() == null + || topicPart.getSite().getViewer() == null + || topicPart.getSite().getViewer().getClass() + .getSimpleName() + .equals(PRESENTATION_VIERWER_CLASS_NAME)) + return; + + if (!topicPart.getStatus().isActive()) + return; + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) + return; + + CommentsPopup popup = new CommentsPopup(window, topicPart, false); + popup.open(); + } + } + + public IAction createAction(ITopicPart topicPart, ITopic topic) { + Set comments = new TreeSet(topic.getOwnedWorkbook() + .getCommentManager().getComments(topic.getId())); + if (comments.isEmpty()) + return null; + + IAction action = null; + IActionRegistry actionRegistry = (IActionRegistry) topicPart + .getAdapter(IActionRegistry.class); + if (actionRegistry != null) { + action = actionRegistry.getAction("org.xmind.ui.editComments"); //$NON-NLS-1$ + if (action != null) + action = new DelegatingAction(action); + } + + if (action == null) + action = new ShowCommentsAction(topicPart); + + StringBuilder text = new StringBuilder(); + + Iterator commentIt = comments.iterator(); + while (commentIt.hasNext()) { + IComment comment = commentIt.next(); + String author = comment.getAuthor(); + String content = comment.getContent(); + + long timeMillisString = comment.getTime(); + + text.append(author); + text.append(" : "); //$NON-NLS-1$ + text.append(content); + text.append('\n'); + text.append(TextFormatter.formatTimeMillis(timeMillisString, + CommentsConstants.DATE_FORMAT_PATTERN)); + text.append(' '); + text.append(TextFormatter.formatTimeMillis(timeMillisString, + CommentsConstants.TIME_FORMAT_PATTERN)); + if (commentIt.hasNext()) { + text.append("\n\n"); //$NON-NLS-1$ + } + + if (text.length() > 500) + break; + } + + if (text.length() > 500) { + text.delete(501, text.length()); + text.append("...\n..."); //$NON-NLS-1$ + } + action.setToolTipText(text.toString()); + + return action; + } + + @Override + protected void registerTopicEvent(ITopicPart topicPart, ITopic topic, + ICoreEventRegister register) { + register.register(Core.CommentAdd); + register.register(Core.CommentRemove); + + register.setNextSupport( + topic.getOwnedWorkbook().getAdapter(ICoreEventSupport.class)); + register.register(Core.CommentContent); + } + + private void removeComments(ITopicPart topicPart) { + ITopic topic = topicPart.getTopic(); + Set comments = topic.getOwnedWorkbook().getCommentManager() + .getComments(topic.getId()); + if (comments.isEmpty()) + return; + + List commands = new ArrayList(comments.size()); + for (IComment comment : comments) { + commands.add(new DeleteCommentCommand(topic, comment)); + } + Command command = new CompoundCommand( + MindMapMessages.Comment_Delete_label, commands); + + EditDomain domain = topicPart.getSite().getDomain(); + ICommandStack commandStack = domain == null ? null + : domain.getCommandStack(); + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + } + + @Override + public List getPopupMenuActions(final ITopicPart topicPart, + final ITopic topic) { + List actions = new ArrayList(); + + IAction editCommentsAction = createAction(topicPart, topic); + editCommentsAction.setText(MindMapMessages.ModifyMenu); + editCommentsAction.setImageDescriptor(null); + actions.add(editCommentsAction); + + IAction deleteCommentsAction = new Action( + MindMapMessages.Comment_Delete_label) { + @Override + public void run() { + removeComments(topicPart); + }; + }; + deleteCommentsAction.setId("org.xmind.ui.removeComments"); //$NON-NLS-1$ + deleteCommentsAction.setImageDescriptor(null); + actions.add(deleteCommentsAction); + + return actions; + } + + @Override + protected void handleTopicEvent(IInfoPart infoPart, CoreEvent event) { + } + + @Override + protected void handleTopicEvent(ITopicPart topicPart, CoreEvent event) { + topicPart.refresh(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java index 756e777ed..e60368a5e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java @@ -1,28 +1,28 @@ -package org.xmind.ui.internal.comments; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.TextViewer; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.e4models.CommentsPart; - -public class CommentsPartActionBarContributor - extends CommentsActionBarContributor { - - private CommentsPart part; - - public CommentsPartActionBarContributor(CommentsPart part, - IGraphicalEditor targetEditor) { - super(targetEditor); - this.part = part; - makeActions(); - } - - protected IAction getContextAction(String actionId) { - return part == null ? null : part.getGlobalAction(actionId); - } - - public void update(TextViewer textViewer) { - part.updateTextActions(textViewer); - } - -} +package org.xmind.ui.internal.comments; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.TextViewer; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.e4models.CommentsPart; + +public class CommentsPartActionBarContributor + extends CommentsActionBarContributor { + + private CommentsPart part; + + public CommentsPartActionBarContributor(CommentsPart part, + IGraphicalEditor targetEditor) { + super(targetEditor); + this.part = part; + makeActions(); + } + + protected IAction getContextAction(String actionId) { + return part == null ? null : part.getGlobalAction(actionId); + } + + public void update(TextViewer textViewer) { + part.updateTextActions(textViewer); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopup.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopup.java index c989c104b..02b2bbfa6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopup.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopup.java @@ -1,813 +1,811 @@ -package org.xmind.ui.internal.comments; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.bindings.Trigger; -import org.eclipse.jface.bindings.TriggerSequence; -import org.eclipse.jface.bindings.keys.KeyStroke; -import org.eclipse.jface.bindings.keys.SWTKeySupport; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.PopupDialog; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.contexts.IContextActivation; -import org.eclipse.ui.contexts.IContextService; -import org.eclipse.ui.keys.IBindingService; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.ZoomManager; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.e4models.CommentsPart; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; - -public class CommentsPopup extends PopupDialog - implements ICoreEventListener, ICommentTextViewerContainer { - - public static final Color BG_COLOR = ColorUtils.getColor("#f5f5f5"); //$NON-NLS-1$ - - private static final String CONTEXT_ID = "org.xmind.ui.context.commentsPopup"; //$NON-NLS-1$ - - private static final String CMD_GOTO_COMMENTS_VIEW = "org.xmind.ui.command.gotoCommentsView"; //$NON-NLS-1$ - - private static final String CMD_COMMIT_COMMENTS = "org.xmind.ui.command.commitComments"; //$NON-NLS-1$ - - private class PopupKeyboardListener implements Listener { - - private List currentSequences = null; - - private DisposeListener disposeListener = new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (!e.display.isDisposed()) { - e.display.removeFilter(SWT.KeyDown, - PopupKeyboardListener.this); - } - } - }; - - private int nextKeyIndex = -1; - - public void hook(Control control) { - control.getDisplay().addFilter(SWT.KeyDown, this); - control.getShell().addDisposeListener(disposeListener); - } - - public void handleEvent(Event event) { - if (event.type == SWT.KeyDown) { - handleKeyDown(event); - } - } - - private void handleKeyDown(Event event) { - if (triggerableCommands.isEmpty()) - return; - - List keys = generateKeyStrokes(event); - if (currentSequences == null) { - nextKeyIndex = -1; - for (TriggerSequence ts : triggerableCommands.keySet()) { - if (matches(keys, ts.getTriggers()[0])) { - if (currentSequences == null) - currentSequences = new ArrayList( - triggerableCommands.size()); - currentSequences.add(ts); - } - } - if (currentSequences == null) - return; - } - - if (nextKeyIndex < 0) - nextKeyIndex = 0; - Iterator it = currentSequences.iterator(); - while (it.hasNext()) { - TriggerSequence ts = it.next(); - Trigger[] triggers = ts.getTriggers(); - if (nextKeyIndex >= triggers.length) { - it.remove(); - } else { - if (matches(keys, triggers[nextKeyIndex])) { - if (nextKeyIndex == triggers.length - 1) { - if (triggerFound(ts)) { - event.doit = false; - } - return; - } - } else { - it.remove(); - } - } - } - if (currentSequences != null && currentSequences.isEmpty()) { - nextKeyIndex++; - } else { - currentSequences = null; - nextKeyIndex = -1; - } - } - - private boolean triggerFound(TriggerSequence triggerSequence) { - currentSequences = null; - nextKeyIndex = -1; - String commandId = triggerableCommands.get(triggerSequence); - if (commandId != null) { - return handleCommand(commandId); - } - return false; - } - - private boolean matches(List keys, Trigger expected) { - for (KeyStroke key : keys) { - if (key.equals(expected)) - return true; - } - return false; - } - - private List generateKeyStrokes(Event event) { - final List keyStrokes = new ArrayList(3); - - /* - * If this is not a keyboard event, then there are no key strokes. - * This can happen if we are listening to focus traversal events. - */ - if ((event.stateMask == 0) && (event.keyCode == 0) - && (event.character == 0)) { - return keyStrokes; - } - - // Add each unique key stroke to the list for consideration. - final int firstAccelerator = SWTKeySupport - .convertEventToUnmodifiedAccelerator(event); - keyStrokes.add(SWTKeySupport - .convertAcceleratorToKeyStroke(firstAccelerator)); - - // We shouldn't allow delete to undergo shift resolution. - if (event.character == SWT.DEL) { - return keyStrokes; - } - - final int secondAccelerator = SWTKeySupport - .convertEventToUnshiftedModifiedAccelerator(event); - if (secondAccelerator != firstAccelerator) { - keyStrokes.add(SWTKeySupport - .convertAcceleratorToKeyStroke(secondAccelerator)); - } - - final int thirdAccelerator = SWTKeySupport - .convertEventToModifiedAccelerator(event); - if ((thirdAccelerator != secondAccelerator) - && (thirdAccelerator != firstAccelerator)) { - keyStrokes.add(SWTKeySupport - .convertAcceleratorToKeyStroke(thirdAccelerator)); - } - - return keyStrokes; - } - } - - @Inject - private EPartService partService; - - private IWorkbenchWindow window; - - private ITopicPart topicPart; - - private ITopic topic; - - private boolean showExtraActions; - - private Control control; - - private CommentsPopupActionBarContributor contributor; - - private ISelectionProvider selectionProvider = new CommentsSelectionProvider(); - - private PopupKeyboardListener popupKeyBoardListener; - - private IBindingService bindingService; - - private IContextService contextService; - - private IContextActivation contextActivation; - - private Map triggerableCommands = new HashMap( - 3); - - private ScrolledComposite sc; - - private Composite contentComposite; - - private TopicCommentsViewer contentViewer; - - private ToolBarManager toolBarManager; - - private ICoreEventRegister eventRegister; - - private ICoreEventRegister globalEventRegister; - - private ControlListener controlListener; - - private IComment latestCreatedComment; - - private IComment selectedComment; - - private IComment editingComment; - - private boolean modified; - - public CommentsPopup(IWorkbenchWindow window, ITopicPart topicPart, - boolean showExtraActions) { - super(window.getShell(), SWT.RESIZE, true, true, true, false, false, - null, null); - this.window = window; - this.topicPart = topicPart; - this.showExtraActions = showExtraActions; - this.topic = topicPart.getTopic(); - } - - @Override - protected Point getDefaultSize() { - return new Point(350, 250); - } - - @Override - protected Color getBackground() { - return BG_COLOR; - } - - @Override - protected Point getInitialLocation(Point initialSize) { - IViewer viewer = topicPart.getSite().getViewer(); - Rectangle bounds = topicPart.getFigure().getBounds().getCopy(); - return calcInitialLocation((IGraphicalViewer) viewer, bounds); - } - - private Point calcInitialLocation(IGraphicalViewer viewer, - Rectangle bounds) { - ZoomManager zoom = viewer.getZoomManager(); - bounds = bounds.scale(zoom.getScale()).expand(1, 1) - .translate(viewer.getScrollPosition().getNegated()); - return viewer.getControl().toDisplay(bounds.x, - bounds.y + bounds.height); - } - - @SuppressWarnings("unchecked") - @Override - protected List getForegroundColorExclusions() { - List list = super.getForegroundColorExclusions(); - collectColorExclusions(control, list); - return list; - } - - @SuppressWarnings("unchecked") - @Override - protected List getBackgroundColorExclusions() { - List list = super.getBackgroundColorExclusions(); - collectColorExclusions(control, list); - return list; - } - - @SuppressWarnings("unchecked") - private void collectColorExclusions(Control control, List list) { - list.add(control); - if (control instanceof Composite) { - for (Control child : ((Composite) control).getChildren()) { - collectColorExclusions(child, list); - } - } - } - - @Override - protected IDialogSettings getDialogSettings() { - return MindMapUIPlugin.getDefault() - .getDialogSettings(MindMapUI.POPUP_DIALOG_SETTINGS_ID); - } - - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - this.control = composite; - composite.setBackground(getBackground()); - composite.setForeground(getForeground()); - - contributor = new CommentsPopupActionBarContributor(this, - getTargetEditor()); - Control control = createControl(composite); - - update(); - popupKeyBoardListener = new PopupKeyboardListener(); - popupKeyBoardListener.hook(control); - setInfoText(null); - - hookTopic(); - registerGlobalEvent(); - initActions(); - - return composite; - } - - private IGraphicalEditor getTargetEditor() { - if (window != null) { - IEditorPart editorPart = window.getActivePage().getActiveEditor(); - if (editorPart instanceof IGraphicalEditor) { - return (IGraphicalEditor) editorPart; - } - } - return null; - } - - private void registerGlobalEvent() { - globalEventRegister = new CoreEventRegister( - topic.getOwnedWorkbook().getAdapter(ICoreEventSupport.class), - this); - globalEventRegister.register(Core.CommentContent); - } - - private void unRegisterGlobalEvent() { - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - globalEventRegister = null; - } - } - - private void hookTopic() { - if (eventRegister == null) { - eventRegister = new CoreEventRegister(topic, this); - } - eventRegister.register(Core.CommentAdd); - eventRegister.register(Core.CommentRemove); - } - - private void unhookTopic() { - if (eventRegister != null) { - eventRegister.unregisterAll(); - eventRegister = null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - final String type = event.getType(); - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - if (!contentComposite.isDisposed()) { - if (Core.CommentAdd.equals(type) - || Core.CommentRemove.equals(type)) { - update(); - } else if (Core.CommentContent.equals(type)) { - IComment comment = (IComment) event.getSource(); - if (comment.isOrphan()) { - return; - } - if (comment.getOwnedWorkbook().getElementById( - comment.getObjectId()) == topic) { - update(); - } - } - } - } - }); - } - - private void initActions() { - contributor.selectionChanged(topic); - } - - @Override - public boolean close() { - unhookTopic(); - unRegisterGlobalEvent(); - if (contextActivation != null && contextService != null) { - contextService.deactivateContext(contextActivation); - contextActivation = null; - } - if (contributor != null) { - contributor.dispose(); - } - if (sc != null && !sc.isDisposed()) { - sc.removeControlListener(getControlListener()); - } - if (getReturnCode() == OK) { - saveComment(); - } - //mark with CommentsView - if (partService != null) { - MPart part = partService.findPart(CommentsPart.PART_ID); - if (part.isVisible()) { - Object object = part.getObject(); - if (object instanceof CommentsPart) { - Control control = ((CommentsPart) object).getControl(); - if (control != null && !control.isDisposed()) { - control.setData(CommentsConstants.COMMENTS_POPUP_SHOWN, - false); - } - } - } - } - return super.close(); - } - - private Control createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(data); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createToolbar(composite); - contentComposite = createContentComposite(composite); - - return composite; - } - - private void createToolbar(Composite parent) { - if (contributor == null) { - return; - } - - Composite composite = new Composite(parent, SWT.NONE); - GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); - gridData.heightHint = 30; - composite.setLayoutData(gridData); - composite.setBackground(ColorUtils.getColor("#e0e0e0")); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setBackground(label.getParent().getBackground()); - GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, true); - layoutData.horizontalIndent = 10; - label.setLayoutData(layoutData); - label.setText(MindMapMessages.Comments_lable); - label.setFont(FontUtils.getBold( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); - - toolBarManager = new ToolBarManager(SWT.FLAT); - contributor.fillToolBar(toolBarManager); - composite.addListener(SWT.Resize, new Listener() { - public void handleEvent(Event event) { - toolBarManager.update(true); - } - }); - - ToolBar toolBar = toolBarManager.createControl(composite); - toolBar.setBackground(toolBar.getParent().getBackground()); - toolBar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true)); - } - - private Composite createContentComposite(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - - sc = new ScrolledComposite(composite, SWT.V_SCROLL); - sc.setBackground(parent.getBackground()); - sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - sc.setExpandHorizontal(true); - - final Composite contentComposite = new Composite(sc, SWT.NONE); - contentComposite.setBackground(parent.getBackground()); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - gridLayout.marginBottom = 29; - contentComposite.setLayout(gridLayout); - - sc.setContent(contentComposite); - sc.getVerticalBar().setIncrement(17); - - sc.addControlListener(getControlListener()); - - return contentComposite; - } - - private ControlListener getControlListener() { - if (controlListener == null) { - controlListener = new ControlListener() { - - public void controlMoved(ControlEvent e) { - } - - public void controlResized(ControlEvent e) { - e.widget.getDisplay().asyncExec(new Runnable() { - - public void run() { - if (contentComposite != null - && !contentComposite.isDisposed()) { - contentComposite.pack(); - } - } - }); - } - }; - } - - return controlListener; - } - - private void update() { - resetSelectedComment(); - updateComments(); - setModified(false); - setEditingComment(null); - } - - private void resetSelectedComment() { - contributor.selectedCommentChanged(null); - } - - private void updateComments() { - selectionProvider.setSelection(null); - contentComposite.setRedraw(false); - resetContent(); - - contentViewer = new TopicCommentsViewer(topic, contributor, - selectionProvider, this, false, getTargetEditor()); - contentViewer.create(contentComposite); - contentComposite.pack(); - contentComposite.setRedraw(true); - } - - private void resetContent() { - Control[] controls = contentComposite.getChildren(); - if (controls != null) { - for (Control control : controls) { - if (control != null && !control.isDisposed()) { - control.dispose(); - control = null; - } - } - } - } - - public int open() { - IWorkbench workbench = window.getWorkbench(); - bindingService = (IBindingService) workbench - .getAdapter(IBindingService.class); - contextService = (IContextService) workbench - .getAdapter(IContextService.class); - if (bindingService != null) { - registerWorkbenchCommands(); - } - int ret = super.open(); - if (ret == OK) { - if (contextService != null) { - contextActivation = contextService.activateContext(CONTEXT_ID); - } - if (bindingService != null) { - registerDialogCommands(); - } - } - //mark with CommentsView - if (partService != null) { - MPart part = partService.findPart(CommentsPart.PART_ID); - if (part.isVisible()) { - Object object = part.getObject(); - if (object instanceof CommentsPart) { - Control control = ((CommentsPart) object).getControl(); - if (control != null && !control.isDisposed()) { - control.setData(CommentsConstants.COMMENTS_POPUP_SHOWN, - true); - } - } - } - } - - return ret; - } - - private void registerWorkbenchCommands() { - registerCommand(IWorkbenchCommandConstants.FILE_SAVE); - registerCommand(IWorkbenchCommandConstants.EDIT_UNDO); - registerCommand(IWorkbenchCommandConstants.EDIT_REDO); - registerCommand(IWorkbenchCommandConstants.EDIT_CUT); - registerCommand(IWorkbenchCommandConstants.EDIT_COPY); - registerCommand(IWorkbenchCommandConstants.EDIT_PASTE); - registerCommand(IWorkbenchCommandConstants.EDIT_SELECT_ALL); - } - - private TriggerSequence registerCommand(String commandId) { - if (bindingService == null) - return null; - TriggerSequence key = bindingService.getBestActiveBindingFor(commandId); - if (key != null) { - triggerableCommands.put(key, commandId); - } - return key; - } - - @Override - protected Control getFocusControl() { - return contentComposite; - } - - private void registerDialogCommands() { - if (showExtraActions) { - registerCommand(CMD_GOTO_COMMENTS_VIEW); - } - registerCommand(CMD_COMMIT_COMMENTS); - for (String commandId : contributor.getTextCommandIds()) { - registerCommand(commandId); - } - } - - private void saveComment() { - if (contentViewer != null) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("AddCommentCount"); //$NON-NLS-1$ - contentViewer.save(); - } - } - - private boolean handleCommand(String commandId) { - if (CMD_GOTO_COMMENTS_VIEW.equals(commandId)) { - if (showExtraActions) { - gotoCommentsView(); - } - return true; - } else if (CMD_COMMIT_COMMENTS.equals(commandId)) { - saveComment(); - return true; - } else if (IWorkbenchCommandConstants.FILE_SAVE.equals(commandId)) { - saveComment(); - return true; - } - IAction action = contributor.getActionHandler(commandId); - if (action != null && action.isEnabled()) { - if (action.getStyle() == IAction.AS_CHECK_BOX) { - action.setChecked(!action.isChecked()); - } - action.run(); - return true; - } - return false; - } - - public void gotoCommentsView() { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (window == null) { - return; - } - close(); - - E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, - window, IModelConstants.PART_ID_COMMENTS, null, - IModelConstants.PART_STACK_ID_RIGHT); - } - }); - } - - public IWorkbenchWindow getWorkbenchWindow() { - return window; - } - - public ITopic getTopic() { - return topic; - } - - public boolean isShowExtraActions() { - return showExtraActions; - } - - public void moveToPreviousTextViewer(CommentTextViewer implementation) { - List implementations = contentViewer - .getImplementations(); - int index = implementations.indexOf(implementation); - if (index <= 0 || index > implementations.size() - 1) { - return; - } - - setSelection(new StructuredSelection(implementations.get(index - 1))); - } - - public void moveToNextTextViewer(CommentTextViewer implementation) { - List implementations = contentViewer - .getImplementations(); - int index = implementations.indexOf(implementation); - if (index < 0 || index >= implementations.size() - 1) { - return; - } - - setSelection(new StructuredSelection(implementations.get(index + 1))); - } - - private void setSelection(ISelection selection) { - selectionProvider.setSelection(selection); - } - - public Composite getContentComposite() { - return contentComposite; - } - - public ScrolledComposite getScrolledComposite() { - return sc; - } - - public void setLatestCreatedComment(IComment latestCreatedComment) { - this.latestCreatedComment = latestCreatedComment; - } - - public IComment getLatestCreatedComment() { - return latestCreatedComment; - } - - public void setSelectedComment(IComment selectedComment) { - this.selectedComment = selectedComment; - } - - public IComment getSelectedComment() { - return selectedComment; - } - - @Override - public void createComment(String objectId) { - contentViewer.createNewComment(); - } - - @Override - public void cancelCreateComment() { - contentViewer.cancelCreateNewComment(); - } - - public void setEditingComment(IComment editingComment) { - this.editingComment = editingComment; - } - - public IComment getEditingComment() { - return editingComment; - } - - public void setModified(boolean modified) { - this.modified = modified; - } - - public boolean isModified() { - return modified; - } - -} +package org.xmind.ui.internal.comments; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.bindings.Trigger; +import org.eclipse.jface.bindings.TriggerSequence; +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.SWTKeySupport; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.PopupDialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.keys.IBindingService; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.ZoomManager; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.CommentsPart; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; + +public class CommentsPopup extends PopupDialog + implements ICoreEventListener, ICommentTextViewerContainer { + + public static final Color BG_COLOR = ColorUtils.getColor("#f5f5f5"); //$NON-NLS-1$ + + private static final String CONTEXT_ID = "org.xmind.ui.context.commentsPopup"; //$NON-NLS-1$ + + private static final String CMD_GOTO_COMMENTS_VIEW = "org.xmind.ui.command.gotoCommentsView"; //$NON-NLS-1$ + + private static final String CMD_COMMIT_COMMENTS = "org.xmind.ui.command.commitComments"; //$NON-NLS-1$ + + private class PopupKeyboardListener implements Listener { + + private List currentSequences = null; + + private DisposeListener disposeListener = new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (!e.display.isDisposed()) { + e.display.removeFilter(SWT.KeyDown, + PopupKeyboardListener.this); + } + } + }; + + private int nextKeyIndex = -1; + + public void hook(Control control) { + control.getDisplay().addFilter(SWT.KeyDown, this); + control.getShell().addDisposeListener(disposeListener); + } + + public void handleEvent(Event event) { + if (event.type == SWT.KeyDown) { + handleKeyDown(event); + } + } + + private void handleKeyDown(Event event) { + if (triggerableCommands.isEmpty()) + return; + + List keys = generateKeyStrokes(event); + if (currentSequences == null) { + nextKeyIndex = -1; + for (TriggerSequence ts : triggerableCommands.keySet()) { + if (matches(keys, ts.getTriggers()[0])) { + if (currentSequences == null) + currentSequences = new ArrayList( + triggerableCommands.size()); + currentSequences.add(ts); + } + } + if (currentSequences == null) + return; + } + + if (nextKeyIndex < 0) + nextKeyIndex = 0; + Iterator it = currentSequences.iterator(); + while (it.hasNext()) { + TriggerSequence ts = it.next(); + Trigger[] triggers = ts.getTriggers(); + if (nextKeyIndex >= triggers.length) { + it.remove(); + } else { + if (matches(keys, triggers[nextKeyIndex])) { + if (nextKeyIndex == triggers.length - 1) { + if (triggerFound(ts)) { + event.doit = false; + } + return; + } + } else { + it.remove(); + } + } + } + if (currentSequences != null && currentSequences.isEmpty()) { + nextKeyIndex++; + } else { + currentSequences = null; + nextKeyIndex = -1; + } + } + + private boolean triggerFound(TriggerSequence triggerSequence) { + currentSequences = null; + nextKeyIndex = -1; + String commandId = triggerableCommands.get(triggerSequence); + if (commandId != null) { + return handleCommand(commandId); + } + return false; + } + + private boolean matches(List keys, Trigger expected) { + for (KeyStroke key : keys) { + if (key.equals(expected)) + return true; + } + return false; + } + + private List generateKeyStrokes(Event event) { + final List keyStrokes = new ArrayList(3); + + /* + * If this is not a keyboard event, then there are no key strokes. + * This can happen if we are listening to focus traversal events. + */ + if ((event.stateMask == 0) && (event.keyCode == 0) + && (event.character == 0)) { + return keyStrokes; + } + + // Add each unique key stroke to the list for consideration. + final int firstAccelerator = SWTKeySupport + .convertEventToUnmodifiedAccelerator(event); + keyStrokes.add(SWTKeySupport + .convertAcceleratorToKeyStroke(firstAccelerator)); + + // We shouldn't allow delete to undergo shift resolution. + if (event.character == SWT.DEL) { + return keyStrokes; + } + + final int secondAccelerator = SWTKeySupport + .convertEventToUnshiftedModifiedAccelerator(event); + if (secondAccelerator != firstAccelerator) { + keyStrokes.add(SWTKeySupport + .convertAcceleratorToKeyStroke(secondAccelerator)); + } + + final int thirdAccelerator = SWTKeySupport + .convertEventToModifiedAccelerator(event); + if ((thirdAccelerator != secondAccelerator) + && (thirdAccelerator != firstAccelerator)) { + keyStrokes.add(SWTKeySupport + .convertAcceleratorToKeyStroke(thirdAccelerator)); + } + + return keyStrokes; + } + } + + @Inject + private EPartService partService; + + private IWorkbenchWindow window; + + private ITopicPart topicPart; + + private ITopic topic; + + private boolean showExtraActions; + + private Control control; + + private CommentsPopupActionBarContributor contributor; + + private ISelectionProvider selectionProvider = new CommentsSelectionProvider(); + + private PopupKeyboardListener popupKeyBoardListener; + + private IBindingService bindingService; + + private IContextService contextService; + + private IContextActivation contextActivation; + + private Map triggerableCommands = new HashMap( + 3); + + private ScrolledComposite sc; + + private Composite contentComposite; + + private TopicCommentsViewer contentViewer; + + private ToolBarManager toolBarManager; + + private ICoreEventRegister eventRegister; + + private ICoreEventRegister globalEventRegister; + + private ControlListener controlListener; + + private IComment latestCreatedComment; + + private IComment selectedComment; + + private IComment editingComment; + + private boolean modified; + + public CommentsPopup(IWorkbenchWindow window, ITopicPart topicPart, + boolean showExtraActions) { + super(window.getShell(), SWT.RESIZE, true, true, true, false, false, + null, null); + this.window = window; + this.topicPart = topicPart; + this.showExtraActions = showExtraActions; + this.topic = topicPart.getTopic(); + } + + @Override + protected Point getDefaultSize() { + return new Point(350, 250); + } + + @Override + protected Color getBackground() { + return BG_COLOR; + } + + @Override + protected Point getInitialLocation(Point initialSize) { + IViewer viewer = topicPart.getSite().getViewer(); + Rectangle bounds = topicPart.getFigure().getBounds().getCopy(); + return calcInitialLocation((IGraphicalViewer) viewer, bounds); + } + + private Point calcInitialLocation(IGraphicalViewer viewer, + Rectangle bounds) { + ZoomManager zoom = viewer.getZoomManager(); + bounds = bounds.scale(zoom.getScale()).expand(1, 1) + .translate(viewer.getScrollPosition().getNegated()); + return viewer.getControl().toDisplay(bounds.x, + bounds.y + bounds.height); + } + + @SuppressWarnings("unchecked") + @Override + protected List getForegroundColorExclusions() { + List list = super.getForegroundColorExclusions(); + collectColorExclusions(control, list); + return list; + } + + @SuppressWarnings("unchecked") + @Override + protected List getBackgroundColorExclusions() { + List list = super.getBackgroundColorExclusions(); + collectColorExclusions(control, list); + return list; + } + + @SuppressWarnings("unchecked") + private void collectColorExclusions(Control control, List list) { + list.add(control); + if (control instanceof Composite) { + for (Control child : ((Composite) control).getChildren()) { + collectColorExclusions(child, list); + } + } + } + + @Override + protected IDialogSettings getDialogSettings() { + return MindMapUIPlugin.getDefault() + .getDialogSettings(MindMapUI.POPUP_DIALOG_SETTINGS_ID); + } + + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + this.control = composite; + composite.setBackground(getBackground()); + composite.setForeground(getForeground()); + + contributor = new CommentsPopupActionBarContributor(this, + getTargetEditor()); + Control control = createControl(composite); + + update(); + popupKeyBoardListener = new PopupKeyboardListener(); + popupKeyBoardListener.hook(control); + setInfoText(null); + + hookTopic(); + registerGlobalEvent(); + initActions(); + + return composite; + } + + private IGraphicalEditor getTargetEditor() { + if (window != null) { + IEditorPart editorPart = window.getActivePage().getActiveEditor(); + if (editorPart instanceof IGraphicalEditor) { + return (IGraphicalEditor) editorPart; + } + } + return null; + } + + private void registerGlobalEvent() { + globalEventRegister = new CoreEventRegister( + topic.getOwnedWorkbook().getAdapter(ICoreEventSupport.class), + this); + globalEventRegister.register(Core.CommentContent); + } + + private void unRegisterGlobalEvent() { + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } + } + + private void hookTopic() { + if (eventRegister == null) { + eventRegister = new CoreEventRegister(topic, this); + } + eventRegister.register(Core.CommentAdd); + eventRegister.register(Core.CommentRemove); + } + + private void unhookTopic() { + if (eventRegister != null) { + eventRegister.unregisterAll(); + eventRegister = null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + final String type = event.getType(); + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + if (!contentComposite.isDisposed()) { + if (Core.CommentAdd.equals(type) + || Core.CommentRemove.equals(type)) { + update(); + } else if (Core.CommentContent.equals(type)) { + IComment comment = (IComment) event.getSource(); + if (comment.isOrphan()) { + return; + } + if (comment.getOwnedWorkbook().getElementById( + comment.getObjectId()) == topic) { + update(); + } + } + } + } + }); + } + + private void initActions() { + contributor.selectionChanged(topic); + } + + @Override + public boolean close() { + unhookTopic(); + unRegisterGlobalEvent(); + if (contextActivation != null && contextService != null) { + contextService.deactivateContext(contextActivation); + contextActivation = null; + } + if (contributor != null) { + contributor.dispose(); + } + if (sc != null && !sc.isDisposed()) { + sc.removeControlListener(getControlListener()); + } + if (getReturnCode() == OK) { + saveComment(); + } + //mark with CommentsView + if (partService != null) { + MPart part = partService.findPart(CommentsPart.PART_ID); + if (part.isVisible()) { + Object object = part.getObject(); + if (object instanceof CommentsPart) { + Control control = ((CommentsPart) object).getControl(); + if (control != null && !control.isDisposed()) { + control.setData(CommentsConstants.COMMENTS_POPUP_SHOWN, + false); + } + } + } + } + return super.close(); + } + + private Control createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(data); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createToolbar(composite); + contentComposite = createContentComposite(composite); + + return composite; + } + + private void createToolbar(Composite parent) { + if (contributor == null) { + return; + } + + Composite composite = new Composite(parent, SWT.NONE); + GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + gridData.heightHint = 30; + composite.setLayoutData(gridData); + composite.setBackground(ColorUtils.getColor("#e0e0e0")); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setBackground(label.getParent().getBackground()); + GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, true); + layoutData.horizontalIndent = 10; + label.setLayoutData(layoutData); + label.setText(MindMapMessages.Comments_lable); + label.setFont(FontUtils.getBold( + FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); + + toolBarManager = new ToolBarManager(SWT.FLAT); + contributor.fillToolBar(toolBarManager); + composite.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event event) { + toolBarManager.update(true); + } + }); + + ToolBar toolBar = toolBarManager.createControl(composite); + toolBar.setBackground(toolBar.getParent().getBackground()); + toolBar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true)); + } + + private Composite createContentComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + sc = new ScrolledComposite(composite, SWT.V_SCROLL); + sc.setBackground(parent.getBackground()); + sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + sc.setExpandHorizontal(true); + + final Composite contentComposite = new Composite(sc, SWT.NONE); + contentComposite.setBackground(parent.getBackground()); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + gridLayout.marginBottom = 29; + contentComposite.setLayout(gridLayout); + + sc.setContent(contentComposite); + sc.getVerticalBar().setIncrement(17); + + sc.addControlListener(getControlListener()); + + return contentComposite; + } + + private ControlListener getControlListener() { + if (controlListener == null) { + controlListener = new ControlListener() { + + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + e.widget.getDisplay().asyncExec(new Runnable() { + + public void run() { + if (contentComposite != null + && !contentComposite.isDisposed()) { + contentComposite.pack(); + } + } + }); + } + }; + } + + return controlListener; + } + + private void update() { + resetSelectedComment(); + updateComments(); + setModified(false); + setEditingComment(null); + } + + private void resetSelectedComment() { + contributor.selectedCommentChanged(null); + } + + private void updateComments() { + selectionProvider.setSelection(null); + contentComposite.setRedraw(false); + resetContent(); + + contentViewer = new TopicCommentsViewer(topic, contributor, + selectionProvider, this, false, getTargetEditor()); + contentViewer.create(contentComposite); + contentComposite.pack(); + contentComposite.setRedraw(true); + } + + private void resetContent() { + Control[] controls = contentComposite.getChildren(); + if (controls != null) { + for (Control control : controls) { + if (control != null && !control.isDisposed()) { + control.dispose(); + control = null; + } + } + } + } + + public int open() { + IWorkbench workbench = window.getWorkbench(); + bindingService = (IBindingService) workbench + .getAdapter(IBindingService.class); + contextService = (IContextService) workbench + .getAdapter(IContextService.class); + if (bindingService != null) { + registerWorkbenchCommands(); + } + int ret = super.open(); + if (ret == OK) { + if (contextService != null) { + contextActivation = contextService.activateContext(CONTEXT_ID); + } + if (bindingService != null) { + registerDialogCommands(); + } + } + //mark with CommentsView + if (partService != null) { + MPart part = partService.findPart(CommentsPart.PART_ID); + if (part.isVisible()) { + Object object = part.getObject(); + if (object instanceof CommentsPart) { + Control control = ((CommentsPart) object).getControl(); + if (control != null && !control.isDisposed()) { + control.setData(CommentsConstants.COMMENTS_POPUP_SHOWN, + true); + } + } + } + } + + return ret; + } + + private void registerWorkbenchCommands() { + registerCommand(IWorkbenchCommandConstants.FILE_SAVE); + registerCommand(IWorkbenchCommandConstants.EDIT_UNDO); + registerCommand(IWorkbenchCommandConstants.EDIT_REDO); + registerCommand(IWorkbenchCommandConstants.EDIT_CUT); + registerCommand(IWorkbenchCommandConstants.EDIT_COPY); + registerCommand(IWorkbenchCommandConstants.EDIT_PASTE); + registerCommand(IWorkbenchCommandConstants.EDIT_SELECT_ALL); + } + + private TriggerSequence registerCommand(String commandId) { + if (bindingService == null) + return null; + TriggerSequence key = bindingService.getBestActiveBindingFor(commandId); + if (key != null) { + triggerableCommands.put(key, commandId); + } + return key; + } + + @Override + protected Control getFocusControl() { + return contentComposite; + } + + private void registerDialogCommands() { + if (showExtraActions) { + registerCommand(CMD_GOTO_COMMENTS_VIEW); + } + registerCommand(CMD_COMMIT_COMMENTS); + for (String commandId : contributor.getTextCommandIds()) { + registerCommand(commandId); + } + } + + private void saveComment() { + if (contentViewer != null) { + contentViewer.save(); + } + } + + private boolean handleCommand(String commandId) { + if (CMD_GOTO_COMMENTS_VIEW.equals(commandId)) { + if (showExtraActions) { + gotoCommentsView(); + } + return true; + } else if (CMD_COMMIT_COMMENTS.equals(commandId)) { + saveComment(); + return true; + } else if (IWorkbenchCommandConstants.FILE_SAVE.equals(commandId)) { + saveComment(); + return true; + } + IAction action = contributor.getActionHandler(commandId); + if (action != null && action.isEnabled()) { + if (action.getStyle() == IAction.AS_CHECK_BOX) { + action.setChecked(!action.isChecked()); + } + action.run(); + return true; + } + return false; + } + + public void gotoCommentsView() { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (window == null) { + return; + } + close(); + + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + window, IModelConstants.PART_ID_COMMENTS, null, + IModelConstants.PART_STACK_ID_RIGHT); + } + }); + } + + public IWorkbenchWindow getWorkbenchWindow() { + return window; + } + + public ITopic getTopic() { + return topic; + } + + public boolean isShowExtraActions() { + return showExtraActions; + } + + public void moveToPreviousTextViewer(CommentTextViewer implementation) { + List implementations = contentViewer + .getImplementations(); + int index = implementations.indexOf(implementation); + if (index <= 0 || index > implementations.size() - 1) { + return; + } + + setSelection(new StructuredSelection(implementations.get(index - 1))); + } + + public void moveToNextTextViewer(CommentTextViewer implementation) { + List implementations = contentViewer + .getImplementations(); + int index = implementations.indexOf(implementation); + if (index < 0 || index >= implementations.size() - 1) { + return; + } + + setSelection(new StructuredSelection(implementations.get(index + 1))); + } + + private void setSelection(ISelection selection) { + selectionProvider.setSelection(selection); + } + + public Composite getContentComposite() { + return contentComposite; + } + + public ScrolledComposite getScrolledComposite() { + return sc; + } + + public void setLatestCreatedComment(IComment latestCreatedComment) { + this.latestCreatedComment = latestCreatedComment; + } + + public IComment getLatestCreatedComment() { + return latestCreatedComment; + } + + public void setSelectedComment(IComment selectedComment) { + this.selectedComment = selectedComment; + } + + public IComment getSelectedComment() { + return selectedComment; + } + + @Override + public void createComment(String objectId) { + contentViewer.createNewComment(); + } + + @Override + public void cancelCreateComment() { + contentViewer.cancelCreateNewComment(); + } + + public void setEditingComment(IComment editingComment) { + this.editingComment = editingComment; + } + + public IComment getEditingComment() { + return editingComment; + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + public boolean isModified() { + return modified; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopupActionBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopupActionBarContributor.java index cf0dc556b..da275f100 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopupActionBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPopupActionBarContributor.java @@ -1,171 +1,171 @@ -package org.xmind.ui.internal.comments; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.TextViewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.MindMapUI; - -public class CommentsPopupActionBarContributor - extends CommentsActionBarContributor { - - private class TextAction extends Action { - - private int op; - - private TextViewer textViewer; - - public TextAction(int op) { - this.op = op; - } - - public void run() { - if (textViewer != null && textViewer.canDoOperation(op)) { - textViewer.doOperation(op); - Composite contentComposite = (Composite) commentsPopup - .getContentComposite(); - contentComposite.pack(); - } - } - - public void update(TextViewer textViewer) { - this.textViewer = textViewer; - setEnabled(textViewer != null && textViewer.canDoOperation(op)); - } - } - - private class GotoCommentsPartAction extends CommentAction { - - public GotoCommentsPartAction(IGraphicalEditor editor) { - super(editor); - setId("org.xmind.ui.action.gotoCommentsView"); //$NON-NLS-1$ - setText(MindMapMessages.EditInCommentsView_text); - setToolTipText(MindMapMessages.EditInCommentsView_tooltip); - setImageDescriptor( - MindMapUI.getImages().get("comments-view-edit.png", true)); //$NON-NLS-1$ - } - - public void run() { - control = commentsPopup.getContentComposite(); - super.run(); - - Display.getCurrent().timerExec(50, new Runnable() { - public void run() { - - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - commentsPopup.gotoCommentsView(); - } - }); - } - }); - } - } - - private CommentsPopup commentsPopup; - - private CommentAction showPreTopicCommentsAction; - - private CommentAction showNextTopicCommentsAction; - - private CommentAction gotoCommentsViewAction; - - private Map textActions = new HashMap( - 10); - - private Map actionHandlers = new HashMap( - 10); - - private Collection textCommandIds = new HashSet(10); - - public CommentsPopupActionBarContributor(CommentsPopup commentsPopup, - IGraphicalEditor targetEditor) { - super(targetEditor); - this.commentsPopup = commentsPopup; - makeActions(); - } - - protected void makeActions() { - if (commentsPopup.isShowExtraActions()) { - showPreTopicCommentsAction = new ShowPreTopicCommentsAction( - targetEditor, commentsPopup); - addAction(showPreTopicCommentsAction); - - showNextTopicCommentsAction = new ShowNextTopicCommentsAction( - targetEditor, commentsPopup); - addAction(showNextTopicCommentsAction); - - gotoCommentsViewAction = new GotoCommentsPartAction(targetEditor); - addAction(gotoCommentsViewAction); - } - - addWorkbenchAction(ActionFactory.UNDO, ITextOperationTarget.UNDO); - addWorkbenchAction(ActionFactory.REDO, ITextOperationTarget.REDO); - addWorkbenchAction(ActionFactory.CUT, ITextOperationTarget.CUT); - addWorkbenchAction(ActionFactory.COPY, ITextOperationTarget.COPY); - addWorkbenchAction(ActionFactory.PASTE, ITextOperationTarget.PASTE); - addWorkbenchAction(ActionFactory.SELECT_ALL, - ITextOperationTarget.SELECT_ALL); - } - - public void fillToolBar(IToolBarManager toolbar) { - if (commentsPopup.isShowExtraActions()) { - toolbar.add(showPreTopicCommentsAction); - toolbar.add(showNextTopicCommentsAction); - toolbar.add(gotoCommentsViewAction); - } - } - - private void addWorkbenchAction(ActionFactory factory, int textOp) { - IWorkbenchAction action = factory - .create(commentsPopup.getWorkbenchWindow()); - TextAction textAction = new TextAction(textOp); - textAction.setId(action.getId()); - textAction.setActionDefinitionId(action.getActionDefinitionId()); - textAction.setText(action.getText()); - textAction.setToolTipText(action.getToolTipText()); - textAction.setDescription(action.getDescription()); - textAction.setImageDescriptor(action.getImageDescriptor()); - textAction.setDisabledImageDescriptor( - action.getDisabledImageDescriptor()); - textAction.setHoverImageDescriptor(action.getHoverImageDescriptor()); - action.dispose(); - actionHandlers.put(action.getActionDefinitionId(), textAction); - textActions.put(textAction.getId(), textAction); - } - - public IAction getActionHandler(String commandId) { - return actionHandlers.get(commandId); - } - - public void update(TextViewer textViewer) { - for (TextAction action : textActions.values()) { - action.update(textViewer); - } - } - - public IAction getTextAction(String actionId) { - return textActions.get(actionId); - } - - public Collection getTextCommandIds() { - return textCommandIds; - } - - protected IAction getContextAction(String actionId) { - return getTextAction(actionId); - } - +package org.xmind.ui.internal.comments; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.MindMapUI; + +public class CommentsPopupActionBarContributor + extends CommentsActionBarContributor { + + private class TextAction extends Action { + + private int op; + + private TextViewer textViewer; + + public TextAction(int op) { + this.op = op; + } + + public void run() { + if (textViewer != null && textViewer.canDoOperation(op)) { + textViewer.doOperation(op); + Composite contentComposite = (Composite) commentsPopup + .getContentComposite(); + contentComposite.pack(); + } + } + + public void update(TextViewer textViewer) { + this.textViewer = textViewer; + setEnabled(textViewer != null && textViewer.canDoOperation(op)); + } + } + + private class GotoCommentsPartAction extends CommentAction { + + public GotoCommentsPartAction(IGraphicalEditor editor) { + super(editor); + setId("org.xmind.ui.action.gotoCommentsView"); //$NON-NLS-1$ + setText(MindMapMessages.EditInCommentsView_text); + setToolTipText(MindMapMessages.EditInCommentsView_tooltip); + setImageDescriptor( + MindMapUI.getImages().get("comments-view-edit.png", true)); //$NON-NLS-1$ + } + + public void run() { + control = commentsPopup.getContentComposite(); + super.run(); + + Display.getCurrent().timerExec(50, new Runnable() { + public void run() { + + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + commentsPopup.gotoCommentsView(); + } + }); + } + }); + } + } + + private CommentsPopup commentsPopup; + + private CommentAction showPreTopicCommentsAction; + + private CommentAction showNextTopicCommentsAction; + + private CommentAction gotoCommentsViewAction; + + private Map textActions = new HashMap( + 10); + + private Map actionHandlers = new HashMap( + 10); + + private Collection textCommandIds = new HashSet(10); + + public CommentsPopupActionBarContributor(CommentsPopup commentsPopup, + IGraphicalEditor targetEditor) { + super(targetEditor); + this.commentsPopup = commentsPopup; + makeActions(); + } + + protected void makeActions() { + if (commentsPopup.isShowExtraActions()) { + showPreTopicCommentsAction = new ShowPreTopicCommentsAction( + targetEditor, commentsPopup); + addAction(showPreTopicCommentsAction); + + showNextTopicCommentsAction = new ShowNextTopicCommentsAction( + targetEditor, commentsPopup); + addAction(showNextTopicCommentsAction); + + gotoCommentsViewAction = new GotoCommentsPartAction(targetEditor); + addAction(gotoCommentsViewAction); + } + + addWorkbenchAction(ActionFactory.UNDO, ITextOperationTarget.UNDO); + addWorkbenchAction(ActionFactory.REDO, ITextOperationTarget.REDO); + addWorkbenchAction(ActionFactory.CUT, ITextOperationTarget.CUT); + addWorkbenchAction(ActionFactory.COPY, ITextOperationTarget.COPY); + addWorkbenchAction(ActionFactory.PASTE, ITextOperationTarget.PASTE); + addWorkbenchAction(ActionFactory.SELECT_ALL, + ITextOperationTarget.SELECT_ALL); + } + + public void fillToolBar(IToolBarManager toolbar) { + if (commentsPopup.isShowExtraActions()) { + toolbar.add(showPreTopicCommentsAction); + toolbar.add(showNextTopicCommentsAction); + toolbar.add(gotoCommentsViewAction); + } + } + + private void addWorkbenchAction(ActionFactory factory, int textOp) { + IWorkbenchAction action = factory + .create(commentsPopup.getWorkbenchWindow()); + TextAction textAction = new TextAction(textOp); + textAction.setId(action.getId()); + textAction.setActionDefinitionId(action.getActionDefinitionId()); + textAction.setText(action.getText()); + textAction.setToolTipText(action.getToolTipText()); + textAction.setDescription(action.getDescription()); + textAction.setImageDescriptor(action.getImageDescriptor()); + textAction.setDisabledImageDescriptor( + action.getDisabledImageDescriptor()); + textAction.setHoverImageDescriptor(action.getHoverImageDescriptor()); + action.dispose(); + actionHandlers.put(action.getActionDefinitionId(), textAction); + textActions.put(textAction.getId(), textAction); + } + + public IAction getActionHandler(String commandId) { + return actionHandlers.get(commandId); + } + + public void update(TextViewer textViewer) { + for (TextAction action : textActions.values()) { + action.update(textViewer); + } + } + + public IAction getTextAction(String actionId) { + return textActions.get(actionId); + } + + public Collection getTextCommandIds() { + return textCommandIds; + } + + protected IAction getContextAction(String actionId) { + return getTextAction(actionId); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsSelectionProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsSelectionProvider.java index 0ca69b9a3..5d9bbfe8a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsSelectionProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsSelectionProvider.java @@ -1,55 +1,55 @@ -package org.xmind.ui.internal.comments; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; - -public class CommentsSelectionProvider implements ISelectionProvider { - - private List selectionChangedListeners = new ArrayList(); - - private ISelection selection; - - //it to be used in commentsView -- findReplaceAction. - private ISelection oldSelection; - - public void addSelectionChangedListener( - ISelectionChangedListener listener) { - selectionChangedListeners.add(listener); - } - - public void removeSelectionChangedListener( - ISelectionChangedListener listener) { - selectionChangedListeners.remove(listener); - } - - public void setSelection(ISelection selection) { - if (this.selection == selection - || (this.selection != null && this.selection.equals(selection))) - return; - - this.oldSelection = this.selection; - this.selection = selection; - fireSelectionChanged(new SelectionChangedEvent(this, getSelection())); - } - - public ISelection getOldSelection() { - return oldSelection == null ? StructuredSelection.EMPTY : oldSelection; - } - - public ISelection getSelection() { - return selection == null ? StructuredSelection.EMPTY : selection; - } - - private void fireSelectionChanged(SelectionChangedEvent event) { - for (Object o : selectionChangedListeners.toArray()) { - ((ISelectionChangedListener) o).selectionChanged(event); - } - } - -} +package org.xmind.ui.internal.comments; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; + +public class CommentsSelectionProvider implements ISelectionProvider { + + private List selectionChangedListeners = new ArrayList(); + + private ISelection selection; + + //it to be used in commentsView -- findReplaceAction. + private ISelection oldSelection; + + public void addSelectionChangedListener( + ISelectionChangedListener listener) { + selectionChangedListeners.add(listener); + } + + public void removeSelectionChangedListener( + ISelectionChangedListener listener) { + selectionChangedListeners.remove(listener); + } + + public void setSelection(ISelection selection) { + if (this.selection == selection + || (this.selection != null && this.selection.equals(selection))) + return; + + this.oldSelection = this.selection; + this.selection = selection; + fireSelectionChanged(new SelectionChangedEvent(this, getSelection())); + } + + public ISelection getOldSelection() { + return oldSelection == null ? StructuredSelection.EMPTY : oldSelection; + } + + public ISelection getSelection() { + return selection == null ? StructuredSelection.EMPTY : selection; + } + + private void fireSelectionChanged(SelectionChangedEvent event) { + for (Object o : selectionChangedListeners.toArray()) { + ((ISelectionChangedListener) o).selectionChanged(event); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsUtils.java index 8e3c4dc54..6d8ed41fc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsUtils.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsUtils.java @@ -1,100 +1,100 @@ -package org.xmind.ui.internal.comments; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.util.MindMapUtils; - -public class CommentsUtils { - - private CommentsUtils() { - } - - public static void collectTopicsWithComments(ITopic topic, - List result) { - if (topic.getOwnedWorkbook().getCommentManager() - .hasComments(topic.getId())) { - result.add(topic); - } - - Iterator childIt = topic.getAllChildrenIterator(); - while (childIt.hasNext()) { - collectTopicsWithComments(childIt.next(), result); - } - } - - /** - * if topics contain topic, return; else insert topic into List at - * the proper position. - * - * @param topics - * @param topic - */ - public static void insertTopic(List topics, ITopic topic) { - if (topics == null || topics.size() == 0 || topics.contains(topic)) { - return; - } - - List allTopics = MindMapUtils - .getAllTopics(topic.getOwnedSheet(), true, true); - int index = allTopics.indexOf(topic); - for (int i = index + 1; i < allTopics.size(); i++) { - ITopic t = allTopics.get(i); - if (topics.contains(t)) { - topics.add(topics.indexOf(t), topic); - return; - } - } - topics.add(topic); - } - - public static void addRecursiveMouseListener(Control c, MouseListener ml, - Control excludeControl) { - if (c == null || c.isDisposed() || ml == null || c == excludeControl) { - return; - } - c.addMouseListener(ml); - if (c instanceof Composite) { - for (final Control cc : ((Composite) c).getChildren()) { - addRecursiveMouseListener(cc, ml, excludeControl); - } - } - } - - public static void removeRecursiveMouseListener(Control c, MouseListener ml, - Control excludeControl) { - if (c == null || c.isDisposed() || ml == null || c == excludeControl) { - return; - } - c.removeMouseListener(ml); - if (c instanceof Composite) { - for (final Control cc : ((Composite) c).getChildren()) { - removeRecursiveMouseListener(cc, ml, excludeControl); - } - } - } - - public static void reveal(IGraphicalEditor editor, Object target) { - if (editor == null) - return; - - editor.getSite().getPage().activate(editor); - - if (target instanceof ITopic || target instanceof ISheet) { - ISelectionProvider selectionProvider = editor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.setSelection(new StructuredSelection(target)); - } - } - } - -} +package org.xmind.ui.internal.comments; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.util.MindMapUtils; + +public class CommentsUtils { + + private CommentsUtils() { + } + + public static void collectTopicsWithComments(ITopic topic, + List result) { + if (topic.getOwnedWorkbook().getCommentManager() + .hasComments(topic.getId())) { + result.add(topic); + } + + Iterator childIt = topic.getAllChildrenIterator(); + while (childIt.hasNext()) { + collectTopicsWithComments(childIt.next(), result); + } + } + + /** + * if topics contain topic, return; else insert topic into List at + * the proper position. + * + * @param topics + * @param topic + */ + public static void insertTopic(List topics, ITopic topic) { + if (topics == null || topics.size() == 0 || topics.contains(topic)) { + return; + } + + List allTopics = MindMapUtils + .getAllTopics(topic.getOwnedSheet(), true, true); + int index = allTopics.indexOf(topic); + for (int i = index + 1; i < allTopics.size(); i++) { + ITopic t = allTopics.get(i); + if (topics.contains(t)) { + topics.add(topics.indexOf(t), topic); + return; + } + } + topics.add(topic); + } + + public static void addRecursiveMouseListener(Control c, MouseListener ml, + Control excludeControl) { + if (c == null || c.isDisposed() || ml == null || c == excludeControl) { + return; + } + c.addMouseListener(ml); + if (c instanceof Composite) { + for (final Control cc : ((Composite) c).getChildren()) { + addRecursiveMouseListener(cc, ml, excludeControl); + } + } + } + + public static void removeRecursiveMouseListener(Control c, MouseListener ml, + Control excludeControl) { + if (c == null || c.isDisposed() || ml == null || c == excludeControl) { + return; + } + c.removeMouseListener(ml); + if (c instanceof Composite) { + for (final Control cc : ((Composite) c).getChildren()) { + removeRecursiveMouseListener(cc, ml, excludeControl); + } + } + } + + public static void reveal(IGraphicalEditor editor, Object target) { + if (editor == null) + return; + + editor.getSite().getPage().activate(editor); + + if (target instanceof ITopic || target instanceof ISheet) { + ISelectionProvider selectionProvider = editor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.setSelection(new StructuredSelection(target)); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentAction.java index 9cb8b0fe7..8915276a1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentAction.java @@ -1,11 +1,11 @@ -package org.xmind.ui.internal.comments; - -import org.xmind.core.IComment; - -public interface ICommentAction { - - void selectionChanged(Object selection); - - void selectedCommentChanged(IComment comment); - -} +package org.xmind.ui.internal.comments; + +import org.xmind.core.IComment; + +public interface ICommentAction { + + void selectionChanged(Object selection); + + void selectedCommentChanged(IComment comment); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentTextViewerContainer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentTextViewerContainer.java index 9139e8f5a..4fa48893c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentTextViewerContainer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentTextViewerContainer.java @@ -1,37 +1,37 @@ -package org.xmind.ui.internal.comments; - -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.widgets.Composite; -import org.xmind.core.IComment; - -public interface ICommentTextViewerContainer { - - void moveToPreviousTextViewer(CommentTextViewer implementation); - - void moveToNextTextViewer(CommentTextViewer implementation); - - Composite getContentComposite(); - - ScrolledComposite getScrolledComposite(); - - void setLatestCreatedComment(IComment latestCreatedComment); - - IComment getLatestCreatedComment(); - - void setSelectedComment(IComment selectedComment); - - IComment getSelectedComment(); - - void createComment(String objectId); - - void cancelCreateComment(); - - void setEditingComment(IComment comment); - - IComment getEditingComment(); - - void setModified(boolean modified); - - boolean isModified(); - -} +package org.xmind.ui.internal.comments; + +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Composite; +import org.xmind.core.IComment; + +public interface ICommentTextViewerContainer { + + void moveToPreviousTextViewer(CommentTextViewer implementation); + + void moveToNextTextViewer(CommentTextViewer implementation); + + Composite getContentComposite(); + + ScrolledComposite getScrolledComposite(); + + void setLatestCreatedComment(IComment latestCreatedComment); + + IComment getLatestCreatedComment(); + + void setSelectedComment(IComment selectedComment); + + IComment getSelectedComment(); + + void createComment(String objectId); + + void cancelCreateComment(); + + void setEditingComment(IComment comment); + + IComment getEditingComment(); + + void setModified(boolean modified); + + boolean isModified(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentsActionBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentsActionBarContributor.java index 8e6e20ee5..944c2cbaf 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentsActionBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ICommentsActionBarContributor.java @@ -1,27 +1,27 @@ -package org.xmind.ui.internal.comments; - -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.text.TextViewer; -import org.xmind.core.IComment; -import org.xmind.ui.texteditor.ISpellingActivation; - -public interface ICommentsActionBarContributor { - - void setSpellingActivation(ISpellingActivation spellingActivation); - - void fillToolBar(IToolBarManager toolbar); - - void fillContextMenu(IMenuManager menu); - - CommentAction getAction(String id); - - void selectionChanged(Object selection); - - void selectedCommentChanged(IComment comment); - - void dispose(); - - void update(TextViewer textViewer); - -} +package org.xmind.ui.internal.comments; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.text.TextViewer; +import org.xmind.core.IComment; +import org.xmind.ui.texteditor.ISpellingActivation; + +public interface ICommentsActionBarContributor { + + void setSpellingActivation(ISpellingActivation spellingActivation); + + void fillToolBar(IToolBarManager toolbar); + + void fillContextMenu(IMenuManager menu); + + CommentAction getAction(String id); + + void selectionChanged(Object selection); + + void selectedCommentChanged(IComment comment); + + void dispose(); + + void update(TextViewer textViewer); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/SheetCommentsViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/SheetCommentsViewer.java index 91212d27b..5264cbca0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/SheetCommentsViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/SheetCommentsViewer.java @@ -1,726 +1,726 @@ -package org.xmind.ui.internal.comments; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.ICommentManager; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.util.TopicIterator; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.e4models.CommentsPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.MindMapUtils; -import org.xmind.ui.util.TextFormatter; - -public class SheetCommentsViewer - implements ICoreEventListener, ISelectionChangedListener { - - private ResourceManager resources; - - private ISheet input; - - private ICommentsActionBarContributor contributor; - - private ISelectionProvider selectionProvider; - - private ICommentTextViewerContainer container; - - private IGraphicalEditor targetEditor; - - private TopicCommentsViewer topicViewer; - - private Label titleLabel; - - private ICoreEventRegister eventRegister; - - private List controls = new ArrayList(); - - private List implementations = new ArrayList(); - - private Map topicViewers = new HashMap(); - - private Composite sheetCommentsComposite; - - private Control newCommentControl; - - private Button insertButton; - - private Hyperlink insertHyperlink; - - private ITopic select; - - private String creatingTargetId; - - private Composite content; - - private Composite parent; - - public SheetCommentsViewer(ISheet input, - ICommentsActionBarContributor contributor, - ISelectionProvider selectionProvider, - ICommentTextViewerContainer container, - IGraphicalEditor targetEditor) { - this.input = input; - this.contributor = contributor; - this.selectionProvider = selectionProvider; - this.container = container; - this.targetEditor = targetEditor; - } - - public void create(Composite parent) { - this.parent = parent; - init(); - createContent(parent, input); - restoreEditing(); - } - - private void init() { - if (controls != null) { - controls.clear(); - } else { - controls = new ArrayList(); - } - if (implementations != null) { - implementations.clear(); - } else { - implementations = new ArrayList(); - } - if (topicViewers != null) { - topicViewers.clear(); - } else { - topicViewers = new HashMap(); - } - } - - private Composite createContent(Composite parent, ISheet sheet) { - Composite composite = new Composite(parent, SWT.NONE); - this.content = composite; - resources = new LocalResourceManager(JFaceResources.getResources(), - composite); - composite.setBackground(composite.getParent().getBackground()); - GridData layoutData = new GridData(GridData.FILL_BOTH); - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - - if (sheet == null || !existComment(sheet)) { - //If have no comment, create null comment content. - container.getScrolledComposite().setExpandVertical(true); - createNullContentArea(composite); - } else { - createAllComments(composite, sheet); - } - - composite.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - handleControlDisposed(e); - } - }); - - return composite; - } - - private void restoreEditing() { - //restore last editing. - final CommentsPart part = (CommentsPart) container; - final String objectId = part.getInsertTarget(); - if (objectId != null) { - Display.getCurrent().asyncExec(new Runnable() { - - @Override - public void run() { - insertComment(objectId); - container.setModified(false); - part.setInsertTarget(null); - } - }); - } - } - - private boolean existComment(ISheet sheet) { - if (sheet == null) { - return false; - } - - if (creatingTargetId != null) { - return true; - } - - ICommentManager commentManager = sheet.getOwnedWorkbook() - .getCommentManager(); - if (commentManager.isEmpty()) { - return false; - } - if (commentManager.hasComments(sheet.getId())) { - return true; - } - - TopicIterator ite = new TopicIterator(sheet.getRootTopic()); - while (ite.hasNext()) { - ITopic topic = ite.next(); - if (commentManager.hasComments(topic.getId())) { - return true; - } - } - return false; - } - - private Control createAllComments(Composite parent, ISheet sheet) { - container.getScrolledComposite().setExpandVertical(false); - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.marginTop = 9; - gridLayout.marginBottom = 29; - gridLayout.verticalSpacing = 18; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - boolean showTopicsComments = createTopicsComments(composite, - sheet.getRootTopic()); - if (showTopicsComments) { - createSeparatorLine(composite); - } - - createSheetComments(composite, sheet); - boolean showSheetComments = sheet.getOwnedWorkbook().getCommentManager() - .getComments(sheet.getId()).size() != 0; - if (showSheetComments) { - createSeparatorLine(composite); - } - - createInsertCommentHyperlink(composite); - - return composite; - } - - /** - * @param parent - * @param sheet - * @return true if create not less than one comment, false otherwise. - */ - private boolean createTopicsComments(Composite parent, ITopic root) { - boolean hasContent = false; - Iterator topicIt = new TopicIterator(root); - while (topicIt.hasNext()) { - ITopic topic = topicIt.next(); - if (topic.getOwnedWorkbook().getCommentManager().hasComments( - topic.getId()) || topic.getId().equals(creatingTargetId)) { - if (hasContent) { - createSeparatorLine(parent); - } - createTopicLabelAndComments(parent, topic); - hasContent = true; - } - } - - return hasContent; - } - - private void createSeparatorLine(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 10; - composite.setLayout(layout); - - Label sep = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); - sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - sep.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - } - - private void createTopicLabelAndComments(Composite parent, ITopic topic) { - topicViewer = new TopicCommentsViewer(topic, contributor, - selectionProvider, container, true, targetEditor); - topicViewer.create(parent); - - if (topicViewer.getControls() != null) { - controls.addAll(topicViewer.getControls()); - } - if (topicViewer.getImplementations() != null) { - implementations.addAll(topicViewer.getImplementations()); - } - topicViewers.put(topic, topicViewer); - } - - private void createSheetComments(Composite parent, ISheet sheet) { - Set comments = new TreeSet(sheet.getOwnedWorkbook() - .getCommentManager().getComments(sheet.getId())); - if (comments.isEmpty()) { - return; - } - - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 5; - composite.setLayout(layout); - this.sheetCommentsComposite = composite; - - createSheetLabel(composite, sheet); - - for (IComment comment : comments) { - createCommentControl(composite, comment); - } - } - - private void createSheetLabel(Composite parent, final ISheet sheet) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 10; - layout.marginHeight = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - titleLabel = new Label(composite, SWT.LEFT | SWT.HORIZONTAL); - titleLabel.setBackground(parent.getBackground()); - titleLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#353535"))); //$NON-NLS-1$ - GridData data = new GridData(SWT.CENTER, SWT.CENTER, true, false); - data.horizontalIndent = 2; - titleLabel.setLayoutData(data); - titleLabel.setFont((Font) resources - .get(FontDescriptor.createFrom(FontUtils.relativeHeight( - titleLabel.getFont().getFontData(), 1)))); - - titleLabel.setText(MindMapMessages.Comment_SHEET_text - + TextFormatter.removeNewLineCharacter(sheet.getTitleText())); - hookSheetTitle(); - - titleLabel.addMouseListener(new MouseAdapter() { - - @Override - public void mouseDown(MouseEvent e) { - CommentsUtils.reveal(targetEditor, sheet); - } - }); - } - - private void createCommentControl(Composite parent, IComment comment) { - CommentTextViewer implementation = new CommentTextViewer(comment, - input.getId(), input.getOwnedWorkbook(), contributor, - selectionProvider, container, targetEditor); - implementation.createControl(parent); - - registerControl(implementation); - registerImplementation(implementation); - } - - private void createNullContentArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(composite.getParent().getBackground()); - GridData layoutData = new GridData(GridData.FILL_BOTH); - - composite.setLayoutData(layoutData); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - createNullContent(composite); - } - - private void createNullContent(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(composite.getParent().getBackground()); - composite.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, true)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 25; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setBackground(label.getParent().getBackground()); - label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label.setImage((Image) resources - .get(MindMapUI.getImages().get("comment-empty-bg.png", true))); //$NON-NLS-1$ - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground(composite2.getParent().getBackground()); - composite2.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 0; - composite2.setLayout(layout2); - - Label label2 = new Label(composite2, SWT.NONE); - label2.setBackground(label2.getParent().getBackground()); - label2.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ - label2.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label2.setText(""); //$NON-NLS-1$ - label2.setFont((Font) resources.get(FontDescriptor.createFrom( - FontUtils.relativeHeight(label2.getFont().getFontData(), 2)))); - - Label label3 = new Label(composite2, SWT.NONE); - label3.setBackground(label3.getParent().getBackground()); - label3.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ - label3.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label3.setText(MindMapMessages.Comment_FirstAdd_text); - label3.setFont((Font) resources.get(FontDescriptor.createFrom( - FontUtils.relativeHeight(label3.getFont().getFontData(), 2)))); - - createInsertButtonSection(composite); - } - - private void createInsertButtonSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(gridData); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.marginTop = 30; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - insertButton = new Button(composite, SWT.PUSH); - insertButton.setBackground(composite.getBackground()); - GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, false); - layoutData.widthHint = 90; - insertButton.setLayoutData(layoutData); - insertButton.setText(MindMapMessages.SheetCommentViewer_Insert_button); - - insertButton.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - insertComment(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - //add selection listener. - if (this.targetEditor != null) { - this.targetEditor.getSite().getSelectionProvider() - .addSelectionChangedListener(this); - setSelection(targetEditor.getSite().getSelectionProvider() - .getSelection()); - } else { - setSelection(null); - } - } - - private void createInsertCommentHyperlink(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - composite.setLayoutData(gridData); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.marginLeft = 15; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - insertHyperlink = new Hyperlink(composite, SWT.NONE); - insertHyperlink.setBackground(composite.getBackground()); - insertHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ - GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, false); - insertHyperlink.setLayoutData(layoutData); - insertHyperlink - .setText(MindMapMessages.SheetCommentViewer_Insert_hyperlink); - - insertHyperlink.addListener(SWT.MouseDown, new Listener() { - - @Override - public void handleEvent(Event event) { - insertComment(); - } - }); - - //add selection listener. - if (this.targetEditor != null) { - this.targetEditor.getSite().getSelectionProvider() - .addSelectionChangedListener(this); - setSelection(targetEditor.getSite().getSelectionProvider() - .getSelection()); - } else { - setSelection(null); - } - } - - private void insertComment() { - if (select == null) { - return; - } - String targetId = select.getId(); - - //store last insert state. - if (container.isModified()) { - container.setModified(false); - ((CommentsPart) container).setInsertTarget(targetId); - return; - } - - insertComment(targetId); - } - - private void insertComment(String targetId) { - creatingTargetId = targetId; - - Composite contentComposite = container.getContentComposite(); - contentComposite.setRedraw(false); - - content.dispose(); - - create(parent); - - createNewComment(targetId); - - contentComposite.pack(); - contentComposite.setRedraw(true); - - creatingTargetId = null; - } - - private void update() { - Composite contentComposite = container.getContentComposite(); - if (contentComposite == null || contentComposite.isDisposed()) { - return; - } - - contentComposite.setRedraw(false); - - content.dispose(); - - create(parent); - - contentComposite.pack(true); - contentComposite.layout(true, true); - contentComposite.setRedraw(true); - } - - private void registerControl(CommentTextViewer control) { - controls.add(control); - } - - private void registerImplementation(CommentTextViewer implementation) { - implementations.add(implementation); - } - - private void hookSheetTitle() { - if (eventRegister == null) { - eventRegister = new CoreEventRegister(input, this); - } - eventRegister.register(Core.TitleText); - } - - private void unhookSheetTitle() { - if (eventRegister != null) { - eventRegister.unregisterAll(); - eventRegister = null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - if (Core.TitleText.equals(event.getType())) { - if (titleLabel != null && !titleLabel.isDisposed()) { - titleLabel.setText(MindMapMessages.Comment_SHEET_text - + TextFormatter.removeNewLineCharacter( - input.getTitleText())); - titleLabel.getParent().layout(true, true); - } - } - } - }); - } - - private void handleControlDisposed(DisposeEvent e) { - unhookSheetTitle(); - if (controls != null) { - controls.clear(); - controls = null; - } - if (implementations != null) { - implementations.clear(); - implementations = null; - } - if (topicViewers != null) { - topicViewers.clear(); - topicViewers = null; - } - } - - public void setTargetEditor(IGraphicalEditor targetEditor) { - if (targetEditor == this.targetEditor) { - return; - } - if (this.targetEditor != null) { - this.targetEditor.getSite().getSelectionProvider() - .removeSelectionChangedListener(this); - } - - this.targetEditor = targetEditor; - - if (this.targetEditor != null) { - this.targetEditor.getSite().getSelectionProvider() - .addSelectionChangedListener(this); - setSelection(targetEditor.getSite().getSelectionProvider() - .getSelection()); - } else { - setSelection(null); - } - - if (topicViewer != null) { - topicViewer.setTargetEditor(targetEditor); - } - if (implementations != null) { - for (CommentTextViewer implementation : implementations) { - implementation.setTargetEditor(targetEditor); - } - } - } - - public List getControls() { - return controls; - } - - public List getImplementations() { - return controls; - } - - public void createNewComment(String objectId) { - if (newCommentControl != null && !newCommentControl.isDisposed()) { - newCommentControl.dispose(); - } - - Object object = input.getOwnedWorkbook().getElementById(objectId); - if (object instanceof ITopic) { - newCommentControl = topicViewers.get((ITopic) object) - .createNewComment(); - } - if (object instanceof ISheet) { - CommentTextViewer implementation = new CommentTextViewer(null, - input.getId(), input.getOwnedWorkbook(), contributor, - selectionProvider, container, targetEditor); - newCommentControl = implementation - .createControl(sheetCommentsComposite); - newCommentControl - .moveAbove((sheetCommentsComposite.getChildren())[0]); - container.getContentComposite().pack(); - - implementation.getTextViewer().getTextWidget().forceFocus(); - } - } - - public void cancelCreateNewComment() { - if (newCommentControl != null && !newCommentControl.isDisposed()) { - newCommentControl.dispose(); - newCommentControl = null; - update(); - } - } - - public void save() { - Control contentComposite = container.getContentComposite(); - if (contentComposite != null && !contentComposite.isDisposed()) { - contentComposite.forceFocus(); - } - } - - @Override - public void selectionChanged(SelectionChangedEvent event) { - setSelection(event.getSelection()); - } - - private void setSelection(ISelection selection) { - boolean isSingleTopic = MindMapUtils.isSingleTopic(selection); - if (isSingleTopic) { - select = (ITopic) MindMapUtils - .getAllSuchElements(selection, MindMapUI.CATEGORY_TOPIC) - .get(0); - } else { - select = null; - } - - if (insertButton != null && !insertButton.isDisposed()) { - insertButton.setEnabled(isSingleTopic); - } - if (insertHyperlink != null && !insertHyperlink.isDisposed()) { - insertHyperlink.setEnabled(isSingleTopic); - } - - container.setModified(false); - } - -} +package org.xmind.ui.internal.comments; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.ICommentManager; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.util.TopicIterator; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.CommentsPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.MindMapUtils; +import org.xmind.ui.util.TextFormatter; + +public class SheetCommentsViewer + implements ICoreEventListener, ISelectionChangedListener { + + private ResourceManager resources; + + private ISheet input; + + private ICommentsActionBarContributor contributor; + + private ISelectionProvider selectionProvider; + + private ICommentTextViewerContainer container; + + private IGraphicalEditor targetEditor; + + private TopicCommentsViewer topicViewer; + + private Label titleLabel; + + private ICoreEventRegister eventRegister; + + private List controls = new ArrayList(); + + private List implementations = new ArrayList(); + + private Map topicViewers = new HashMap(); + + private Composite sheetCommentsComposite; + + private Control newCommentControl; + + private Button insertButton; + + private Hyperlink insertHyperlink; + + private ITopic select; + + private String creatingTargetId; + + private Composite content; + + private Composite parent; + + public SheetCommentsViewer(ISheet input, + ICommentsActionBarContributor contributor, + ISelectionProvider selectionProvider, + ICommentTextViewerContainer container, + IGraphicalEditor targetEditor) { + this.input = input; + this.contributor = contributor; + this.selectionProvider = selectionProvider; + this.container = container; + this.targetEditor = targetEditor; + } + + public void create(Composite parent) { + this.parent = parent; + init(); + createContent(parent, input); + restoreEditing(); + } + + private void init() { + if (controls != null) { + controls.clear(); + } else { + controls = new ArrayList(); + } + if (implementations != null) { + implementations.clear(); + } else { + implementations = new ArrayList(); + } + if (topicViewers != null) { + topicViewers.clear(); + } else { + topicViewers = new HashMap(); + } + } + + private Composite createContent(Composite parent, ISheet sheet) { + Composite composite = new Composite(parent, SWT.NONE); + this.content = composite; + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + composite.setBackground(composite.getParent().getBackground()); + GridData layoutData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + if (sheet == null || !existComment(sheet)) { + //If have no comment, create null comment content. + container.getScrolledComposite().setExpandVertical(true); + createNullContentArea(composite); + } else { + createAllComments(composite, sheet); + } + + composite.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + handleControlDisposed(e); + } + }); + + return composite; + } + + private void restoreEditing() { + //restore last editing. + final CommentsPart part = (CommentsPart) container; + final String objectId = part.getInsertTarget(); + if (objectId != null) { + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + insertComment(objectId); + container.setModified(false); + part.setInsertTarget(null); + } + }); + } + } + + private boolean existComment(ISheet sheet) { + if (sheet == null) { + return false; + } + + if (creatingTargetId != null) { + return true; + } + + ICommentManager commentManager = sheet.getOwnedWorkbook() + .getCommentManager(); + if (commentManager.isEmpty()) { + return false; + } + if (commentManager.hasComments(sheet.getId())) { + return true; + } + + TopicIterator ite = new TopicIterator(sheet.getRootTopic()); + while (ite.hasNext()) { + ITopic topic = ite.next(); + if (commentManager.hasComments(topic.getId())) { + return true; + } + } + return false; + } + + private Control createAllComments(Composite parent, ISheet sheet) { + container.getScrolledComposite().setExpandVertical(false); + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.marginTop = 9; + gridLayout.marginBottom = 29; + gridLayout.verticalSpacing = 18; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + boolean showTopicsComments = createTopicsComments(composite, + sheet.getRootTopic()); + if (showTopicsComments) { + createSeparatorLine(composite); + } + + createSheetComments(composite, sheet); + boolean showSheetComments = sheet.getOwnedWorkbook().getCommentManager() + .getComments(sheet.getId()).size() != 0; + if (showSheetComments) { + createSeparatorLine(composite); + } + + createInsertCommentHyperlink(composite); + + return composite; + } + + /** + * @param parent + * @param sheet + * @return true if create not less than one comment, false otherwise. + */ + private boolean createTopicsComments(Composite parent, ITopic root) { + boolean hasContent = false; + Iterator topicIt = new TopicIterator(root); + while (topicIt.hasNext()) { + ITopic topic = topicIt.next(); + if (topic.getOwnedWorkbook().getCommentManager().hasComments( + topic.getId()) || topic.getId().equals(creatingTargetId)) { + if (hasContent) { + createSeparatorLine(parent); + } + createTopicLabelAndComments(parent, topic); + hasContent = true; + } + } + + return hasContent; + } + + private void createSeparatorLine(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 10; + composite.setLayout(layout); + + Label sep = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + sep.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + } + + private void createTopicLabelAndComments(Composite parent, ITopic topic) { + topicViewer = new TopicCommentsViewer(topic, contributor, + selectionProvider, container, true, targetEditor); + topicViewer.create(parent); + + if (topicViewer.getControls() != null) { + controls.addAll(topicViewer.getControls()); + } + if (topicViewer.getImplementations() != null) { + implementations.addAll(topicViewer.getImplementations()); + } + topicViewers.put(topic, topicViewer); + } + + private void createSheetComments(Composite parent, ISheet sheet) { + Set comments = new TreeSet(sheet.getOwnedWorkbook() + .getCommentManager().getComments(sheet.getId())); + if (comments.isEmpty()) { + return; + } + + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 5; + composite.setLayout(layout); + this.sheetCommentsComposite = composite; + + createSheetLabel(composite, sheet); + + for (IComment comment : comments) { + createCommentControl(composite, comment); + } + } + + private void createSheetLabel(Composite parent, final ISheet sheet) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 10; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + titleLabel = new Label(composite, SWT.LEFT | SWT.HORIZONTAL); + titleLabel.setBackground(parent.getBackground()); + titleLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#353535"))); //$NON-NLS-1$ + GridData data = new GridData(SWT.CENTER, SWT.CENTER, true, false); + data.horizontalIndent = 2; + titleLabel.setLayoutData(data); + titleLabel.setFont((Font) resources + .get(FontDescriptor.createFrom(FontUtils.relativeHeight( + titleLabel.getFont().getFontData(), 1)))); + + titleLabel.setText(MindMapMessages.Comment_SHEET_text + + TextFormatter.removeNewLineCharacter(sheet.getTitleText())); + hookSheetTitle(); + + titleLabel.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + CommentsUtils.reveal(targetEditor, sheet); + } + }); + } + + private void createCommentControl(Composite parent, IComment comment) { + CommentTextViewer implementation = new CommentTextViewer(comment, + input.getId(), input.getOwnedWorkbook(), contributor, + selectionProvider, container, targetEditor); + implementation.createControl(parent); + + registerControl(implementation); + registerImplementation(implementation); + } + + private void createNullContentArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + GridData layoutData = new GridData(GridData.FILL_BOTH); + + composite.setLayoutData(layoutData); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + createNullContent(composite); + } + + private void createNullContent(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + composite.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, true)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 25; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setBackground(label.getParent().getBackground()); + label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); + label.setImage((Image) resources + .get(MindMapUI.getImages().get("comment-empty-bg.png", true))); //$NON-NLS-1$ + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(composite2.getParent().getBackground()); + composite2.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.verticalSpacing = 0; + composite2.setLayout(layout2); + + Label label2 = new Label(composite2, SWT.NONE); + label2.setBackground(label2.getParent().getBackground()); + label2.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ + label2.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + label2.setText(""); //$NON-NLS-1$ + label2.setFont((Font) resources.get(FontDescriptor.createFrom( + FontUtils.relativeHeight(label2.getFont().getFontData(), 2)))); + + Label label3 = new Label(composite2, SWT.NONE); + label3.setBackground(label3.getParent().getBackground()); + label3.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ + label3.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + label3.setText(MindMapMessages.Comment_FirstAdd_text); + label3.setFont((Font) resources.get(FontDescriptor.createFrom( + FontUtils.relativeHeight(label3.getFont().getFontData(), 2)))); + + createInsertButtonSection(composite); + } + + private void createInsertButtonSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.marginTop = 30; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + insertButton = new Button(composite, SWT.PUSH); + insertButton.setBackground(composite.getBackground()); + GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, false); + layoutData.widthHint = 90; + insertButton.setLayoutData(layoutData); + insertButton.setText(MindMapMessages.SheetCommentViewer_Insert_button); + + insertButton.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + insertComment(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + //add selection listener. + if (this.targetEditor != null) { + this.targetEditor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + setSelection(targetEditor.getSite().getSelectionProvider() + .getSelection()); + } else { + setSelection(null); + } + } + + private void createInsertCommentHyperlink(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.marginLeft = 15; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + insertHyperlink = new Hyperlink(composite, SWT.NONE); + insertHyperlink.setBackground(composite.getBackground()); + insertHyperlink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ + GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, false); + insertHyperlink.setLayoutData(layoutData); + insertHyperlink + .setText(MindMapMessages.SheetCommentViewer_Insert_hyperlink); + + insertHyperlink.addListener(SWT.MouseDown, new Listener() { + + @Override + public void handleEvent(Event event) { + insertComment(); + } + }); + + //add selection listener. + if (this.targetEditor != null) { + this.targetEditor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + setSelection(targetEditor.getSite().getSelectionProvider() + .getSelection()); + } else { + setSelection(null); + } + } + + private void insertComment() { + if (select == null) { + return; + } + String targetId = select.getId(); + + //store last insert state. + if (container.isModified()) { + container.setModified(false); + ((CommentsPart) container).setInsertTarget(targetId); + return; + } + + insertComment(targetId); + } + + private void insertComment(String targetId) { + creatingTargetId = targetId; + + Composite contentComposite = container.getContentComposite(); + contentComposite.setRedraw(false); + + content.dispose(); + + create(parent); + + createNewComment(targetId); + + contentComposite.pack(); + contentComposite.setRedraw(true); + + creatingTargetId = null; + } + + private void update() { + Composite contentComposite = container.getContentComposite(); + if (contentComposite == null || contentComposite.isDisposed()) { + return; + } + + contentComposite.setRedraw(false); + + content.dispose(); + + create(parent); + + contentComposite.pack(true); + contentComposite.layout(true, true); + contentComposite.setRedraw(true); + } + + private void registerControl(CommentTextViewer control) { + controls.add(control); + } + + private void registerImplementation(CommentTextViewer implementation) { + implementations.add(implementation); + } + + private void hookSheetTitle() { + if (eventRegister == null) { + eventRegister = new CoreEventRegister(input, this); + } + eventRegister.register(Core.TitleText); + } + + private void unhookSheetTitle() { + if (eventRegister != null) { + eventRegister.unregisterAll(); + eventRegister = null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + if (Core.TitleText.equals(event.getType())) { + if (titleLabel != null && !titleLabel.isDisposed()) { + titleLabel.setText(MindMapMessages.Comment_SHEET_text + + TextFormatter.removeNewLineCharacter( + input.getTitleText())); + titleLabel.getParent().layout(true, true); + } + } + } + }); + } + + private void handleControlDisposed(DisposeEvent e) { + unhookSheetTitle(); + if (controls != null) { + controls.clear(); + controls = null; + } + if (implementations != null) { + implementations.clear(); + implementations = null; + } + if (topicViewers != null) { + topicViewers.clear(); + topicViewers = null; + } + } + + public void setTargetEditor(IGraphicalEditor targetEditor) { + if (targetEditor == this.targetEditor) { + return; + } + if (this.targetEditor != null) { + this.targetEditor.getSite().getSelectionProvider() + .removeSelectionChangedListener(this); + } + + this.targetEditor = targetEditor; + + if (this.targetEditor != null) { + this.targetEditor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + setSelection(targetEditor.getSite().getSelectionProvider() + .getSelection()); + } else { + setSelection(null); + } + + if (topicViewer != null) { + topicViewer.setTargetEditor(targetEditor); + } + if (implementations != null) { + for (CommentTextViewer implementation : implementations) { + implementation.setTargetEditor(targetEditor); + } + } + } + + public List getControls() { + return controls; + } + + public List getImplementations() { + return controls; + } + + public void createNewComment(String objectId) { + if (newCommentControl != null && !newCommentControl.isDisposed()) { + newCommentControl.dispose(); + } + + Object object = input.getOwnedWorkbook().getElementById(objectId); + if (object instanceof ITopic) { + newCommentControl = topicViewers.get((ITopic) object) + .createNewComment(); + } + if (object instanceof ISheet) { + CommentTextViewer implementation = new CommentTextViewer(null, + input.getId(), input.getOwnedWorkbook(), contributor, + selectionProvider, container, targetEditor); + newCommentControl = implementation + .createControl(sheetCommentsComposite); + newCommentControl + .moveAbove((sheetCommentsComposite.getChildren())[0]); + container.getContentComposite().pack(); + + implementation.getTextViewer().getTextWidget().forceFocus(); + } + } + + public void cancelCreateNewComment() { + if (newCommentControl != null && !newCommentControl.isDisposed()) { + newCommentControl.dispose(); + newCommentControl = null; + update(); + } + } + + public void save() { + Control contentComposite = container.getContentComposite(); + if (contentComposite != null && !contentComposite.isDisposed()) { + contentComposite.forceFocus(); + } + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + setSelection(event.getSelection()); + } + + private void setSelection(ISelection selection) { + boolean isSingleTopic = MindMapUtils.isSingleTopic(selection); + if (isSingleTopic) { + select = (ITopic) MindMapUtils + .getAllSuchElements(selection, MindMapUI.CATEGORY_TOPIC) + .get(0); + } else { + select = null; + } + + if (insertButton != null && !insertButton.isDisposed()) { + insertButton.setEnabled(isSingleTopic); + } + if (insertHyperlink != null && !insertHyperlink.isDisposed()) { + insertHyperlink.setEnabled(isSingleTopic); + } + + container.setModified(false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowNextTopicCommentsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowNextTopicCommentsAction.java index 6ea222f77..0ca5678ca 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowNextTopicCommentsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowNextTopicCommentsAction.java @@ -1,90 +1,90 @@ -package org.xmind.ui.internal.comments; - -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.util.TopicIterator; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class ShowNextTopicCommentsAction extends CommentAction { - - private ITopic topic; - - private CommentsPopup dialog; - - public ShowNextTopicCommentsAction(IGraphicalEditor editor, - CommentsPopup dialog) { - super(editor); - this.topic = dialog.getTopic(); - this.dialog = dialog; - - setId("org.xmind.ui.action.showNextTopicComments2"); //$NON-NLS-1$ - setText(MindMapMessages.ShowNextTopicComments_text); - setImageDescriptor(MindMapUI.getImages().get("next-topic.png", true)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.ShowNextTopicComments_tooltip); - } - - public void run() { - if (topic == null) { - return; - } - - ITopic nextTopic = findNextTopicWithComments(topic); - if (nextTopic == null || nextTopic == topic) - return; - - ITopicPart topicPart = MindMapUtils.findTopicPart( - getTargetEditor().getAdapter(IGraphicalViewer.class), - nextTopic); - if (topicPart == null) - return; - - dialog.close(); - - CommentsUtils.reveal(getTargetEditor(), nextTopic); - CommentsPopup popup = new CommentsPopup( - getTargetEditor().getSite().getWorkbenchWindow(), topicPart, - true); - popup.open(); - } - - private ITopic findNextTopicWithComments(ITopic sourceTopic) { - ISheet sheet = sourceTopic.getOwnedSheet(); - if (sheet == null) - return null; - - TopicIterator it = new TopicIterator(sheet.getRootTopic()); - boolean sourceFound = false; - while (it.hasNext()) { - ITopic nextTopic = it.next(); - if (!sourceFound) { - if (nextTopic == sourceTopic) { - sourceFound = true; - } - } else { - if (nextTopic.getOwnedWorkbook().getCommentManager() - .hasComments(nextTopic.getId())) - return nextTopic; - } - } - - if (sourceFound) { - it = new TopicIterator(sheet.getRootTopic()); - while (it.hasNext()) { - ITopic nextTopic = it.next(); - if (nextTopic == sourceTopic) - break; - if (nextTopic.getOwnedWorkbook().getCommentManager() - .hasComments(nextTopic.getId())) - return nextTopic; - } - } - - return null; - } - +package org.xmind.ui.internal.comments; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.util.TopicIterator; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class ShowNextTopicCommentsAction extends CommentAction { + + private ITopic topic; + + private CommentsPopup dialog; + + public ShowNextTopicCommentsAction(IGraphicalEditor editor, + CommentsPopup dialog) { + super(editor); + this.topic = dialog.getTopic(); + this.dialog = dialog; + + setId("org.xmind.ui.action.showNextTopicComments2"); //$NON-NLS-1$ + setText(MindMapMessages.ShowNextTopicComments_text); + setImageDescriptor(MindMapUI.getImages().get("next-topic.png", true)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.ShowNextTopicComments_tooltip); + } + + public void run() { + if (topic == null) { + return; + } + + ITopic nextTopic = findNextTopicWithComments(topic); + if (nextTopic == null || nextTopic == topic) + return; + + ITopicPart topicPart = MindMapUtils.findTopicPart( + getTargetEditor().getAdapter(IGraphicalViewer.class), + nextTopic); + if (topicPart == null) + return; + + dialog.close(); + + CommentsUtils.reveal(getTargetEditor(), nextTopic); + CommentsPopup popup = new CommentsPopup( + getTargetEditor().getSite().getWorkbenchWindow(), topicPart, + true); + popup.open(); + } + + private ITopic findNextTopicWithComments(ITopic sourceTopic) { + ISheet sheet = sourceTopic.getOwnedSheet(); + if (sheet == null) + return null; + + TopicIterator it = new TopicIterator(sheet.getRootTopic()); + boolean sourceFound = false; + while (it.hasNext()) { + ITopic nextTopic = it.next(); + if (!sourceFound) { + if (nextTopic == sourceTopic) { + sourceFound = true; + } + } else { + if (nextTopic.getOwnedWorkbook().getCommentManager() + .hasComments(nextTopic.getId())) + return nextTopic; + } + } + + if (sourceFound) { + it = new TopicIterator(sheet.getRootTopic()); + while (it.hasNext()) { + ITopic nextTopic = it.next(); + if (nextTopic == sourceTopic) + break; + if (nextTopic.getOwnedWorkbook().getCommentManager() + .hasComments(nextTopic.getId())) + return nextTopic; + } + } + + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowPreTopicCommentsAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowPreTopicCommentsAction.java index aaa6ff1b8..e6e233a53 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowPreTopicCommentsAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/ShowPreTopicCommentsAction.java @@ -1,93 +1,93 @@ -package org.xmind.ui.internal.comments; - -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.util.TopicIterator; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class ShowPreTopicCommentsAction extends CommentAction { - - private ITopic topic; - - private CommentsPopup dialog; - - public ShowPreTopicCommentsAction(IGraphicalEditor editor, - CommentsPopup dialog) { - super(editor); - this.topic = dialog.getTopic(); - this.dialog = dialog; - - setId("org.xmind.ui.action.showPreTopicComments2"); //$NON-NLS-1$ - setText(MindMapMessages.ShowPreTopicComments_text); - setImageDescriptor( - MindMapUI.getImages().get("previous-topic.png", true)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.ShowPreTopicComments_tooltip); - } - - public void run() { - if (topic == null) { - return; - } - - ITopic previousTopic = findPreviousTopicWithComments(topic); - if (previousTopic == null || previousTopic == topic) - return; - - ITopicPart topicPart = MindMapUtils.findTopicPart( - getTargetEditor().getAdapter(IGraphicalViewer.class), - previousTopic); - if (topicPart == null) - return; - - dialog.close(); - - CommentsUtils.reveal(getTargetEditor(), previousTopic); - CommentsPopup popup = new CommentsPopup( - getTargetEditor().getSite().getWorkbenchWindow(), topicPart, - true); - popup.open(); - } - - private ITopic findPreviousTopicWithComments(ITopic sourceTopic) { - ISheet sheet = sourceTopic.getOwnedSheet(); - if (sheet == null) - return null; - - TopicIterator it = new TopicIterator(sheet.getRootTopic(), - TopicIterator.REVERSED); - boolean sourceFound = false; - while (it.hasNext()) { - ITopic nextTopic = it.next(); - if (!sourceFound) { - if (nextTopic == sourceTopic) { - sourceFound = true; - } - } else { - if (nextTopic.getOwnedWorkbook().getCommentManager() - .hasComments(nextTopic.getId())) - return nextTopic; - } - } - - if (sourceFound) { - it = new TopicIterator(sheet.getRootTopic(), - TopicIterator.REVERSED); - while (it.hasNext()) { - ITopic nextTopic = it.next(); - if (nextTopic == sourceTopic) - break; - if (nextTopic.getOwnedWorkbook().getCommentManager() - .hasComments(nextTopic.getId())) - return nextTopic; - } - } - - return null; - } - +package org.xmind.ui.internal.comments; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.util.TopicIterator; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class ShowPreTopicCommentsAction extends CommentAction { + + private ITopic topic; + + private CommentsPopup dialog; + + public ShowPreTopicCommentsAction(IGraphicalEditor editor, + CommentsPopup dialog) { + super(editor); + this.topic = dialog.getTopic(); + this.dialog = dialog; + + setId("org.xmind.ui.action.showPreTopicComments2"); //$NON-NLS-1$ + setText(MindMapMessages.ShowPreTopicComments_text); + setImageDescriptor( + MindMapUI.getImages().get("previous-topic.png", true)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.ShowPreTopicComments_tooltip); + } + + public void run() { + if (topic == null) { + return; + } + + ITopic previousTopic = findPreviousTopicWithComments(topic); + if (previousTopic == null || previousTopic == topic) + return; + + ITopicPart topicPart = MindMapUtils.findTopicPart( + getTargetEditor().getAdapter(IGraphicalViewer.class), + previousTopic); + if (topicPart == null) + return; + + dialog.close(); + + CommentsUtils.reveal(getTargetEditor(), previousTopic); + CommentsPopup popup = new CommentsPopup( + getTargetEditor().getSite().getWorkbenchWindow(), topicPart, + true); + popup.open(); + } + + private ITopic findPreviousTopicWithComments(ITopic sourceTopic) { + ISheet sheet = sourceTopic.getOwnedSheet(); + if (sheet == null) + return null; + + TopicIterator it = new TopicIterator(sheet.getRootTopic(), + TopicIterator.REVERSED); + boolean sourceFound = false; + while (it.hasNext()) { + ITopic nextTopic = it.next(); + if (!sourceFound) { + if (nextTopic == sourceTopic) { + sourceFound = true; + } + } else { + if (nextTopic.getOwnedWorkbook().getCommentManager() + .hasComments(nextTopic.getId())) + return nextTopic; + } + } + + if (sourceFound) { + it = new TopicIterator(sheet.getRootTopic(), + TopicIterator.REVERSED); + while (it.hasNext()) { + ITopic nextTopic = it.next(); + if (nextTopic == sourceTopic) + break; + if (nextTopic.getOwnedWorkbook().getCommentManager() + .hasComments(nextTopic.getId())) + return nextTopic; + } + } + + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/TopicCommentsViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/TopicCommentsViewer.java index 77da4bf07..781aa77d7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/TopicCommentsViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/TopicCommentsViewer.java @@ -1,356 +1,356 @@ -package org.xmind.ui.internal.comments; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.TextFormatter; - -public class TopicCommentsViewer implements ICoreEventListener { - - private ITopic input; - - private ICommentsActionBarContributor contributor; - - private ISelectionProvider selectionProvider; - - private ICommentTextViewerContainer container; - - private boolean showTopicLabel; - - private IGraphicalEditor targetEditor; - - private Label titleLabel; - - private ICoreEventRegister eventRegister; - - private List controls = new ArrayList(); - - private List implementations = new ArrayList(); - - private Control addCommentControl; - - private Composite commentsComposite; - - private Control newCommentControl; - - public TopicCommentsViewer(ITopic input, - ICommentsActionBarContributor contributor, - ISelectionProvider selectionProvider, - ICommentTextViewerContainer container, boolean showTopicLabel, - IGraphicalEditor targetEditor) { - this.input = input; - this.contributor = contributor; - this.selectionProvider = selectionProvider; - this.container = container; - this.showTopicLabel = showTopicLabel; - this.targetEditor = targetEditor; - } - - public void create(Composite parent) { - init(); - createControl(input, parent); - } - - private void init() { - if (controls != null) { - controls.clear(); - } - if (implementations != null) { - implementations.clear(); - } - } - - private Control createControl(ITopic topic, Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - if (showTopicLabel) { - createTopicLabel(composite, topic); - } - - if (!showTopicLabel) { - addCommentControl = createAddCommentControl(composite); - } - - commentsComposite = createComments(topic, composite); - - composite.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - handleControlDisposed(e); - } - }); - - return composite; - } - - private void createTopicLabel(Composite parent, final ITopic topic) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 10; - layout.marginHeight = 0; - layout.horizontalSpacing = 0; - layout.marginBottom = 6; - composite.setLayout(layout); - - titleLabel = new Label(composite, SWT.LEFT | SWT.HORIZONTAL); - titleLabel.setBackground(parent.getBackground()); - titleLabel.setForeground(ColorUtils.getColor("#353535")); //$NON-NLS-1$ - GridData data = new GridData(SWT.CENTER, SWT.CENTER, true, false); - data.horizontalIndent = 2; - titleLabel.setLayoutData(data); - - titleLabel.setFont(FontUtils.getBold( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); - - titleLabel.setText(MindMapMessages.Comment_TOPIC_text - + TextFormatter.removeNewLineCharacter(topic.getTitleText())); - hookTopicTitle(); - - titleLabel.addMouseListener(new MouseAdapter() { - - @Override - public void mouseDown(MouseEvent e) { - CommentsUtils.reveal(targetEditor, topic); - } - }); - } - - private Control createAddCommentControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 10; - layout.marginHeight = 0; - layout.marginTop = 10; - layout.marginBottom = 10; - composite.setLayout(layout); - - Composite marginComposite = new Composite(composite, SWT.NONE); - marginComposite - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout layout3 = new GridLayout(1, false); - layout3.marginHeight = 1; - layout3.marginWidth = 1; - marginComposite.setLayout(layout3); - marginComposite.setBackground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ - - Composite roundRectangleComposite = new Composite(marginComposite, - SWT.NONE); - roundRectangleComposite.setForeground(ColorUtils.getColor("#ffffff")); //$NON-NLS-1$ - roundRectangleComposite.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); - layoutData.heightHint = 40; - roundRectangleComposite.setLayoutData(layoutData); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 2; - layout2.marginHeight = 2; - roundRectangleComposite.setLayout(layout2); - - Text text = new Text(roundRectangleComposite, - SWT.LEFT | SWT.SINGLE | SWT.READ_ONLY); - text.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); - text.setBackground(text.getParent().getForeground()); - text.setForeground(ColorUtils.getColor("#aaaaaa")); //$NON-NLS-1$ - - text.setFont(FontUtils.getItalic( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); - text.setText(MindMapMessages.Comment_Add_text); - - text.setEnabled(false); - - roundRectangleComposite.addMouseListener(new MouseAdapter() { - - @Override - public void mouseDown(MouseEvent e) { - createNewComment(); - } - }); - - return composite; - } - - public Control createNewComment() { - if (newCommentControl != null && !newCommentControl.isDisposed()) { - return newCommentControl; - } - - if (addCommentControl != null && !addCommentControl.isDisposed()) { - addCommentControl.setVisible(false); - ((GridData) addCommentControl.getLayoutData()).exclude = true; - } - - CommentTextViewer implementation = new CommentTextViewer(null, - input.getId(), input.getOwnedWorkbook(), contributor, - selectionProvider, container, targetEditor); - newCommentControl = implementation.createControl(commentsComposite); - newCommentControl.moveAbove((commentsComposite.getChildren())[0]); - container.getContentComposite().pack(); - - implementation.getTextViewer().getTextWidget().forceFocus(); - - return newCommentControl; - } - - public void cancelCreateNewComment() { - if (newCommentControl != null && !newCommentControl.isDisposed()) { - newCommentControl.dispose(); - newCommentControl = null; - } - - if (addCommentControl != null && !addCommentControl.isDisposed()) { - addCommentControl.setVisible(true); - ((GridData) addCommentControl.getLayoutData()).exclude = false; - } - - container.getContentComposite().pack(); - } - - private Composite createComments(ITopic topic, Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 3; - composite.setLayout(layout); - - Set comments = new TreeSet(topic.getOwnedWorkbook() - .getCommentManager().getComments(topic.getId())); - for (IComment comment : comments) { - createCommentControl(composite, comment); - } - - return composite; - } - - private void createCommentControl(Composite parent, IComment comment) { - CommentTextViewer implementation = new CommentTextViewer(comment, - input.getId(), input.getOwnedWorkbook(), contributor, - selectionProvider, container, targetEditor); - implementation.createControl(parent); - - registerControl(implementation); - registerImplementation(implementation); - } - - private void registerControl(CommentTextViewer control) { - controls.add(control); - } - - private void registerImplementation(CommentTextViewer implementation) { - implementations.add(implementation); - } - - private void hookTopicTitle() { - if (eventRegister == null) { - eventRegister = new CoreEventRegister(input, this); - } - eventRegister.register(Core.TitleText); - } - - private void unhookTopicTitle() { - if (eventRegister != null) { - eventRegister.unregisterAll(); - eventRegister = null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - if (Core.TitleText.equals(event.getType())) { - if (titleLabel != null && !titleLabel.isDisposed()) { - titleLabel.setText(MindMapMessages.Comment_TOPIC_text - + TextFormatter.removeNewLineCharacter( - input.getTitleText())); - titleLabel.getParent().layout(true, true); - } - } - } - }); - } - - private void handleControlDisposed(DisposeEvent e) { - unhookTopicTitle(); - if (controls != null) { - controls.clear(); - controls = null; - } - if (implementations != null) { - implementations.clear(); - implementations = null; - } - } - - public void setTargetEditor(IGraphicalEditor targetEditor) { - if (this.targetEditor != targetEditor) { - this.targetEditor = targetEditor; - if (implementations != null) { - for (CommentTextViewer implementation : implementations) { - implementation.setTargetEditor(targetEditor); - } - } - } - } - - public List getControls() { - return controls; - } - - public List getImplementations() { - return implementations; - } - - public void save() { - Control contentComposite = container.getContentComposite(); - if (contentComposite != null && !contentComposite.isDisposed()) { - contentComposite.forceFocus(); - } - } - -} +package org.xmind.ui.internal.comments; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.TextFormatter; + +public class TopicCommentsViewer implements ICoreEventListener { + + private ITopic input; + + private ICommentsActionBarContributor contributor; + + private ISelectionProvider selectionProvider; + + private ICommentTextViewerContainer container; + + private boolean showTopicLabel; + + private IGraphicalEditor targetEditor; + + private Label titleLabel; + + private ICoreEventRegister eventRegister; + + private List controls = new ArrayList(); + + private List implementations = new ArrayList(); + + private Control addCommentControl; + + private Composite commentsComposite; + + private Control newCommentControl; + + public TopicCommentsViewer(ITopic input, + ICommentsActionBarContributor contributor, + ISelectionProvider selectionProvider, + ICommentTextViewerContainer container, boolean showTopicLabel, + IGraphicalEditor targetEditor) { + this.input = input; + this.contributor = contributor; + this.selectionProvider = selectionProvider; + this.container = container; + this.showTopicLabel = showTopicLabel; + this.targetEditor = targetEditor; + } + + public void create(Composite parent) { + init(); + createControl(input, parent); + } + + private void init() { + if (controls != null) { + controls.clear(); + } + if (implementations != null) { + implementations.clear(); + } + } + + private Control createControl(ITopic topic, Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + if (showTopicLabel) { + createTopicLabel(composite, topic); + } + + if (!showTopicLabel) { + addCommentControl = createAddCommentControl(composite); + } + + commentsComposite = createComments(topic, composite); + + composite.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + handleControlDisposed(e); + } + }); + + return composite; + } + + private void createTopicLabel(Composite parent, final ITopic topic) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 10; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + layout.marginBottom = 6; + composite.setLayout(layout); + + titleLabel = new Label(composite, SWT.LEFT | SWT.HORIZONTAL); + titleLabel.setBackground(parent.getBackground()); + titleLabel.setForeground(ColorUtils.getColor("#353535")); //$NON-NLS-1$ + GridData data = new GridData(SWT.CENTER, SWT.CENTER, true, false); + data.horizontalIndent = 2; + titleLabel.setLayoutData(data); + + titleLabel.setFont(FontUtils.getBold( + FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); + + titleLabel.setText(MindMapMessages.Comment_TOPIC_text + + TextFormatter.removeNewLineCharacter(topic.getTitleText())); + hookTopicTitle(); + + titleLabel.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + CommentsUtils.reveal(targetEditor, topic); + } + }); + } + + private Control createAddCommentControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 10; + layout.marginHeight = 0; + layout.marginTop = 10; + layout.marginBottom = 10; + composite.setLayout(layout); + + Composite marginComposite = new Composite(composite, SWT.NONE); + marginComposite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout3 = new GridLayout(1, false); + layout3.marginHeight = 1; + layout3.marginWidth = 1; + marginComposite.setLayout(layout3); + marginComposite.setBackground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ + + Composite roundRectangleComposite = new Composite(marginComposite, + SWT.NONE); + roundRectangleComposite.setForeground(ColorUtils.getColor("#ffffff")); //$NON-NLS-1$ + roundRectangleComposite.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); + layoutData.heightHint = 40; + roundRectangleComposite.setLayoutData(layoutData); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 2; + layout2.marginHeight = 2; + roundRectangleComposite.setLayout(layout2); + + Text text = new Text(roundRectangleComposite, + SWT.LEFT | SWT.SINGLE | SWT.READ_ONLY); + text.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + text.setBackground(text.getParent().getForeground()); + text.setForeground(ColorUtils.getColor("#aaaaaa")); //$NON-NLS-1$ + + text.setFont(FontUtils.getItalic( + FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); + text.setText(MindMapMessages.Comment_Add_text); + + text.setEnabled(false); + + roundRectangleComposite.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + createNewComment(); + } + }); + + return composite; + } + + public Control createNewComment() { + if (newCommentControl != null && !newCommentControl.isDisposed()) { + return newCommentControl; + } + + if (addCommentControl != null && !addCommentControl.isDisposed()) { + addCommentControl.setVisible(false); + ((GridData) addCommentControl.getLayoutData()).exclude = true; + } + + CommentTextViewer implementation = new CommentTextViewer(null, + input.getId(), input.getOwnedWorkbook(), contributor, + selectionProvider, container, targetEditor); + newCommentControl = implementation.createControl(commentsComposite); + newCommentControl.moveAbove((commentsComposite.getChildren())[0]); + container.getContentComposite().pack(); + + implementation.getTextViewer().getTextWidget().forceFocus(); + + return newCommentControl; + } + + public void cancelCreateNewComment() { + if (newCommentControl != null && !newCommentControl.isDisposed()) { + newCommentControl.dispose(); + newCommentControl = null; + } + + if (addCommentControl != null && !addCommentControl.isDisposed()) { + addCommentControl.setVisible(true); + ((GridData) addCommentControl.getLayoutData()).exclude = false; + } + + container.getContentComposite().pack(); + } + + private Composite createComments(ITopic topic, Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 3; + composite.setLayout(layout); + + Set comments = new TreeSet(topic.getOwnedWorkbook() + .getCommentManager().getComments(topic.getId())); + for (IComment comment : comments) { + createCommentControl(composite, comment); + } + + return composite; + } + + private void createCommentControl(Composite parent, IComment comment) { + CommentTextViewer implementation = new CommentTextViewer(comment, + input.getId(), input.getOwnedWorkbook(), contributor, + selectionProvider, container, targetEditor); + implementation.createControl(parent); + + registerControl(implementation); + registerImplementation(implementation); + } + + private void registerControl(CommentTextViewer control) { + controls.add(control); + } + + private void registerImplementation(CommentTextViewer implementation) { + implementations.add(implementation); + } + + private void hookTopicTitle() { + if (eventRegister == null) { + eventRegister = new CoreEventRegister(input, this); + } + eventRegister.register(Core.TitleText); + } + + private void unhookTopicTitle() { + if (eventRegister != null) { + eventRegister.unregisterAll(); + eventRegister = null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + if (Core.TitleText.equals(event.getType())) { + if (titleLabel != null && !titleLabel.isDisposed()) { + titleLabel.setText(MindMapMessages.Comment_TOPIC_text + + TextFormatter.removeNewLineCharacter( + input.getTitleText())); + titleLabel.getParent().layout(true, true); + } + } + } + }); + } + + private void handleControlDisposed(DisposeEvent e) { + unhookTopicTitle(); + if (controls != null) { + controls.clear(); + controls = null; + } + if (implementations != null) { + implementations.clear(); + implementations = null; + } + } + + public void setTargetEditor(IGraphicalEditor targetEditor) { + if (this.targetEditor != targetEditor) { + this.targetEditor = targetEditor; + if (implementations != null) { + for (CommentTextViewer implementation : implementations) { + implementation.setTargetEditor(targetEditor); + } + } + } + } + + public List getControls() { + return controls; + } + + public List getImplementations() { + return implementations; + } + + public void save() { + Control contentComposite = container.getContentComposite(); + if (contentComposite != null && !contentComposite.isDisposed()) { + contentComposite.forceFocus(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/AbstractCalloutBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/AbstractCalloutBranchConnection.java index 79d2dbd36..cd95e1f63 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/AbstractCalloutBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/AbstractCalloutBranchConnection.java @@ -1,112 +1,112 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.decoration.IShapeDecoration; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractBranchConnection; - -public abstract class AbstractCalloutBranchConnection - extends AbstractBranchConnection implements IShapeDecoration { - - private boolean gradient = false; - - private Color fillColor = null; - - private int fillAlpha = 0xFF; - - private int lineAlpha = 0xFF; - - public AbstractCalloutBranchConnection() { - super(); - } - - public AbstractCalloutBranchConnection(String id) { - super(id); - } - - protected Rectangle getOutlineBox(Rectangle box) { - Rectangle ret = box.getCopy(); - int w = Math.min(ret.width - 1, - Math.min(ret.height - 1, getLineWidth())); - int half = w - w / 2; - return ret.shrink(half, half).resize(-1, -1); - } - - protected void drawLine(IFigure figure, Graphics graphics) { - Path shape = new Path(Display.getCurrent()); - route(figure, shape); - if (getFillColor() != null) { - Color bg = graphics.getBackgroundColor(); - graphics.setBackgroundColor(getFillColor()); - paintPath(figure, graphics, shape, true); - graphics.setBackgroundColor(bg); - } - if (graphics.getForegroundColor() != null) - paintPath(figure, graphics, shape, false); - shape.dispose(); - } - - @Override - protected boolean usesFill() { - return true; - } - - public int getFillAlpha() { - return fillAlpha; - } - - public Color getFillColor() { - return fillColor; - } - - public int getLineAlpha() { - return lineAlpha; - } - - public boolean isGradient() { - return gradient; - } - - public void setFillAlpha(IFigure figure, int alpha) { - if (alpha == this.fillAlpha) - return; - this.fillAlpha = alpha; - if (figure != null) { - repaint(figure); - } - } - - public void setFillColor(IFigure figure, Color c) { - if (c == this.fillColor || (c != null && c.equals(this.fillColor))) - return; - this.fillColor = c; - if (figure != null) { - repaint(figure); - } - } - - public void setGradient(IFigure figure, boolean gradient) { - gradient = gradient && GEF.IS_PLATFORM_SUPPORT_GRADIENT; - if (gradient == this.gradient) - return; - this.gradient = gradient; - if (figure != null) { - repaint(figure); - } - } - - public void setLineAlpha(IFigure figure, int alpha) { - if (alpha == this.lineAlpha) - return; - this.lineAlpha = alpha; - if (figure != null) { - repaint(figure); - } - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.decoration.IShapeDecoration; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractBranchConnection; + +public abstract class AbstractCalloutBranchConnection + extends AbstractBranchConnection implements IShapeDecoration { + + private boolean gradient = false; + + private Color fillColor = null; + + private int fillAlpha = 0xFF; + + private int lineAlpha = 0xFF; + + public AbstractCalloutBranchConnection() { + super(); + } + + public AbstractCalloutBranchConnection(String id) { + super(id); + } + + protected Rectangle getOutlineBox(Rectangle box) { + Rectangle ret = box.getCopy(); + int w = Math.min(ret.width - 1, + Math.min(ret.height - 1, getLineWidth())); + int half = w - w / 2; + return ret.shrink(half, half).resize(-1, -1); + } + + protected void drawLine(IFigure figure, Graphics graphics) { + Path shape = new Path(Display.getCurrent()); + route(figure, shape); + if (getFillColor() != null) { + Color bg = graphics.getBackgroundColor(); + graphics.setBackgroundColor(getFillColor()); + paintPath(figure, graphics, shape, true); + graphics.setBackgroundColor(bg); + } + if (graphics.getForegroundColor() != null) + paintPath(figure, graphics, shape, false); + shape.dispose(); + } + + @Override + protected boolean usesFill() { + return true; + } + + public int getFillAlpha() { + return fillAlpha; + } + + public Color getFillColor() { + return fillColor; + } + + public int getLineAlpha() { + return lineAlpha; + } + + public boolean isGradient() { + return gradient; + } + + public void setFillAlpha(IFigure figure, int alpha) { + if (alpha == this.fillAlpha) + return; + this.fillAlpha = alpha; + if (figure != null) { + repaint(figure); + } + } + + public void setFillColor(IFigure figure, Color c) { + if (c == this.fillColor || (c != null && c.equals(this.fillColor))) + return; + this.fillColor = c; + if (figure != null) { + repaint(figure); + } + } + + public void setGradient(IFigure figure, boolean gradient) { + gradient = gradient && GEF.IS_PLATFORM_SUPPORT_GRADIENT; + if (gradient == this.gradient) + return; + this.gradient = gradient; + if (figure != null) { + repaint(figure); + } + } + + public void setLineAlpha(IFigure figure, int alpha) { + if (alpha == this.lineAlpha) + return; + this.lineAlpha = alpha; + if (figure != null) { + repaint(figure); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutBranchConnections.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutBranchConnections.java index bec0c56ba..0947f4a32 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutBranchConnections.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutBranchConnections.java @@ -1,301 +1,301 @@ -package org.xmind.ui.internal.decorations; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.decoration.CompoundDecoration; -import org.xmind.gef.draw2d.decoration.IConnectionDecoration; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.draw2d.decoration.ILineDecoration; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.ui.decorations.IBranchConnectionDecoration; -import org.xmind.ui.decorations.IBranchConnections2; - -public class CalloutBranchConnections extends CompoundDecoration - implements IBranchConnections2, IShadowedDecoration { - - private List sourceAnchors = new ArrayList(); - - private List lineColors = new ArrayList(); - - private List lineStyles = new ArrayList(); - - private List lineWidths = new ArrayList(); - - private List sourceOrientations = new ArrayList(); - - private List sourceExpansions = new ArrayList(); - - private List cornerSizes = new ArrayList(); - - private boolean tapered = false; - - private HashMap figureToDecoration = new HashMap(); - - public Color getLineColor(int index) { - if (lineColors.size() <= index) - return null; - return lineColors.get(index); - } - - public int getLineStyle(int index) { - if (lineStyles.size() <= index) - return SWT.LINE_SOLID; - return lineStyles.get(index); - } - - public int getLineWidth(int index) { - if (lineWidths.size() <= index) - return 1; - return lineWidths.get(index); - } - - public void setLineColor(IFigure figure, int index, Color color) { - if (lineColors.size() > index) { - Color oldColor = lineColors.get(index); - if (oldColor == color - || (oldColor != null && oldColor.equals(color))) - return; - lineColors.set(index, color); - } else { - lineColors.add(index, color); - } - if (figure != null) { - repaint(figure); - } - update(figure, index); - } - - public void putFigureToDecoration(IFigure figure, IDecoration decoration) { - figureToDecoration.put(figure, decoration); - } - - public IDecoration getDecoration(IFigure figure) { - return figureToDecoration.get(figure); - } - - private void update(IFigure figure) { - for (IDecoration decoration : getDecorations()) { - if (decoration != null) - update(figure, decoration); - } - } - - @Override - protected void update(IFigure figure, IDecoration decoration) { - super.update(figure, decoration); - updateAnchor(figure, getDecorations().indexOf(decoration)); - updateConnection(figure, decoration); - } - - private void updateConnection(IFigure figure, IDecoration decoration) { - int index = getDecorations().indexOf(decoration); - if (decoration instanceof ICorneredDecoration) { - ((ICorneredDecoration) decoration).setCornerSize(figure, - getCornerSize(index)); - } - if (decoration instanceof ILineDecoration) { - ILineDecoration line = (ILineDecoration) decoration; - - line.setLineColor(figure, getLineColor(index)); - - line.setLineStyle(figure, getLineStyle(index)); - line.setLineWidth(figure, getLineWidth(index)); - } - if (decoration instanceof IBranchConnectionDecoration) { - IBranchConnectionDecoration conn = (IBranchConnectionDecoration) decoration; - conn.setSourceOrientation(figure, getSourceOrientation(index)); - conn.setSourceExpansion(figure, getSourceExpansion(index)); - conn.setTapered(figure, tapered); - } - - } - - private void update(IFigure figure, int index) { - IDecoration decoration = getDecorations().get(index); - super.update(figure, decoration); - updateAnchor(figure, index); - updateConnection(figure, decoration); - } - - public void setLineWidth(IFigure figure, int index, int width) { - if (lineWidths.size() > index) { - Integer lineWidth = lineWidths.get(index); - if (lineWidth.intValue() == width) - return; - lineWidths.set(index, width); - } else { - lineWidths.add(index, width); - } - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - update(figure, index); - - } - - public void setLineStyle(IFigure figure, int index, int style) { - if (lineStyles.size() > index) { - Integer lineStyle = lineStyles.get(index); - if (lineStyle.intValue() == style) - return; - lineStyles.set(index, style); - } else { - lineStyles.add(index, style); - } - if (figure != null) { - repaint(figure); - } - update(figure, index); - } - - public int getCornerSize(int index) { - if (cornerSizes.size() <= index) - return 0; - return cornerSizes.get(index); - } - - public void setCornerSize(IFigure figure, int index, int cornerSize) { - if (cornerSizes.size() > index) { - Integer size = cornerSizes.get(index); - if (size.intValue() == cornerSize) - return; - cornerSizes.set(index, cornerSize); - } else { - cornerSizes.add(index, cornerSize); - } - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - update(figure); - } - - public void paintShadow(IFigure figure, Graphics graphics) { - if (!isVisible()) - return; - checkValidation(figure); - for (IDecoration decoration : getDecorations()) { - if (decoration instanceof IShadowedDecoration) { - ((IShadowedDecoration) decoration).paintShadow(figure, - graphics); - } - } - } - - public void setSourceOrientation(IFigure figure, int index, - int orientation) { - if (sourceOrientations.size() > index) { - Integer oldOrientation = sourceOrientations.get(index); - if (oldOrientation.intValue() == orientation) - return; - sourceOrientations.set(index, orientation); - } else { - sourceOrientations.add(index, orientation); - } - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - update(figure, index); - } - - public void setSourceExpansion(IFigure figure, int index, int expansion) { - if (sourceExpansions.size() > index) { - Integer oldExpansion = sourceExpansions.get(index); - if (oldExpansion.intValue() == expansion) - return; - sourceExpansions.set(index, expansion); - } else { - sourceExpansions.add(index, expansion); - } - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - update(figure, index); - } - - public void setTapered(IFigure figure, boolean tapered) { - if (tapered == this.tapered) - return; - this.tapered = tapered; - if (figure != null) { - figure.revalidate(); - repaint(figure); - } - invalidate(); - update(figure); - } - - public int getSourceExpansion(int index) { - if (sourceExpansions.size() <= index) - return 0; - return sourceExpansions.get(index); - } - - public int getSourceOrientation(int index) { - if (sourceOrientations.size() <= index) - return PositionConstants.NONE; - return sourceOrientations.get(index); - } - - public boolean isTapered() { - return tapered; - } - - public IAnchor getSourceAnchor(int index) { - if (sourceAnchors.size() <= index) - return null; - return sourceAnchors.get(index); - } - - public void setSourceAnchor(IFigure figure, int index, IAnchor anchor) { - if (sourceAnchors.size() > index) { - IAnchor oldAnchor = sourceAnchors.get(index); - if (oldAnchor == anchor - || (oldAnchor != null && oldAnchor.equals(anchor))) - return; - sourceAnchors.set(index, anchor); - } else { - sourceAnchors.add(index, anchor); - } - updateAnchor(figure, index); - - } - - private void updateAnchor(IFigure figure, int index) { - IDecoration decoration = getDecoration(index); - if (decoration instanceof IConnectionDecoration) { - ((IConnectionDecoration) decoration).setSourceAnchor(figure, - getSourceAnchor(index)); - } - - } - - public void rerouteAll(IFigure figure) { - int size = size(); - for (int i = 0; i < size; i++) { - IDecoration decoration = getDecoration(i); - if (decoration instanceof IConnectionDecoration) { - ((IConnectionDecoration) decoration).reroute(figure); - } - } - if (figure != null) { - repaint(figure); - } - } -} +package org.xmind.ui.internal.decorations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.decoration.CompoundDecoration; +import org.xmind.gef.draw2d.decoration.IConnectionDecoration; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.draw2d.decoration.ILineDecoration; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.ui.decorations.IBranchConnectionDecoration; +import org.xmind.ui.decorations.IBranchConnections2; + +public class CalloutBranchConnections extends CompoundDecoration + implements IBranchConnections2, IShadowedDecoration { + + private List sourceAnchors = new ArrayList(); + + private List lineColors = new ArrayList(); + + private List lineStyles = new ArrayList(); + + private List lineWidths = new ArrayList(); + + private List sourceOrientations = new ArrayList(); + + private List sourceExpansions = new ArrayList(); + + private List cornerSizes = new ArrayList(); + + private boolean tapered = false; + + private HashMap figureToDecoration = new HashMap(); + + public Color getLineColor(int index) { + if (lineColors.size() <= index) + return null; + return lineColors.get(index); + } + + public int getLineStyle(int index) { + if (lineStyles.size() <= index) + return SWT.LINE_SOLID; + return lineStyles.get(index); + } + + public int getLineWidth(int index) { + if (lineWidths.size() <= index) + return 1; + return lineWidths.get(index); + } + + public void setLineColor(IFigure figure, int index, Color color) { + if (lineColors.size() > index) { + Color oldColor = lineColors.get(index); + if (oldColor == color + || (oldColor != null && oldColor.equals(color))) + return; + lineColors.set(index, color); + } else { + lineColors.add(index, color); + } + if (figure != null) { + repaint(figure); + } + update(figure, index); + } + + public void putFigureToDecoration(IFigure figure, IDecoration decoration) { + figureToDecoration.put(figure, decoration); + } + + public IDecoration getDecoration(IFigure figure) { + return figureToDecoration.get(figure); + } + + private void update(IFigure figure) { + for (IDecoration decoration : getDecorations()) { + if (decoration != null) + update(figure, decoration); + } + } + + @Override + protected void update(IFigure figure, IDecoration decoration) { + super.update(figure, decoration); + updateAnchor(figure, getDecorations().indexOf(decoration)); + updateConnection(figure, decoration); + } + + private void updateConnection(IFigure figure, IDecoration decoration) { + int index = getDecorations().indexOf(decoration); + if (decoration instanceof ICorneredDecoration) { + ((ICorneredDecoration) decoration).setCornerSize(figure, + getCornerSize(index)); + } + if (decoration instanceof ILineDecoration) { + ILineDecoration line = (ILineDecoration) decoration; + + line.setLineColor(figure, getLineColor(index)); + + line.setLineStyle(figure, getLineStyle(index)); + line.setLineWidth(figure, getLineWidth(index)); + } + if (decoration instanceof IBranchConnectionDecoration) { + IBranchConnectionDecoration conn = (IBranchConnectionDecoration) decoration; + conn.setSourceOrientation(figure, getSourceOrientation(index)); + conn.setSourceExpansion(figure, getSourceExpansion(index)); + conn.setTapered(figure, tapered); + } + + } + + private void update(IFigure figure, int index) { + IDecoration decoration = getDecorations().get(index); + super.update(figure, decoration); + updateAnchor(figure, index); + updateConnection(figure, decoration); + } + + public void setLineWidth(IFigure figure, int index, int width) { + if (lineWidths.size() > index) { + Integer lineWidth = lineWidths.get(index); + if (lineWidth.intValue() == width) + return; + lineWidths.set(index, width); + } else { + lineWidths.add(index, width); + } + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + update(figure, index); + + } + + public void setLineStyle(IFigure figure, int index, int style) { + if (lineStyles.size() > index) { + Integer lineStyle = lineStyles.get(index); + if (lineStyle.intValue() == style) + return; + lineStyles.set(index, style); + } else { + lineStyles.add(index, style); + } + if (figure != null) { + repaint(figure); + } + update(figure, index); + } + + public int getCornerSize(int index) { + if (cornerSizes.size() <= index) + return 0; + return cornerSizes.get(index); + } + + public void setCornerSize(IFigure figure, int index, int cornerSize) { + if (cornerSizes.size() > index) { + Integer size = cornerSizes.get(index); + if (size.intValue() == cornerSize) + return; + cornerSizes.set(index, cornerSize); + } else { + cornerSizes.add(index, cornerSize); + } + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + update(figure); + } + + public void paintShadow(IFigure figure, Graphics graphics) { + if (!isVisible()) + return; + checkValidation(figure); + for (IDecoration decoration : getDecorations()) { + if (decoration instanceof IShadowedDecoration) { + ((IShadowedDecoration) decoration).paintShadow(figure, + graphics); + } + } + } + + public void setSourceOrientation(IFigure figure, int index, + int orientation) { + if (sourceOrientations.size() > index) { + Integer oldOrientation = sourceOrientations.get(index); + if (oldOrientation.intValue() == orientation) + return; + sourceOrientations.set(index, orientation); + } else { + sourceOrientations.add(index, orientation); + } + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + update(figure, index); + } + + public void setSourceExpansion(IFigure figure, int index, int expansion) { + if (sourceExpansions.size() > index) { + Integer oldExpansion = sourceExpansions.get(index); + if (oldExpansion.intValue() == expansion) + return; + sourceExpansions.set(index, expansion); + } else { + sourceExpansions.add(index, expansion); + } + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + update(figure, index); + } + + public void setTapered(IFigure figure, boolean tapered) { + if (tapered == this.tapered) + return; + this.tapered = tapered; + if (figure != null) { + figure.revalidate(); + repaint(figure); + } + invalidate(); + update(figure); + } + + public int getSourceExpansion(int index) { + if (sourceExpansions.size() <= index) + return 0; + return sourceExpansions.get(index); + } + + public int getSourceOrientation(int index) { + if (sourceOrientations.size() <= index) + return PositionConstants.NONE; + return sourceOrientations.get(index); + } + + public boolean isTapered() { + return tapered; + } + + public IAnchor getSourceAnchor(int index) { + if (sourceAnchors.size() <= index) + return null; + return sourceAnchors.get(index); + } + + public void setSourceAnchor(IFigure figure, int index, IAnchor anchor) { + if (sourceAnchors.size() > index) { + IAnchor oldAnchor = sourceAnchors.get(index); + if (oldAnchor == anchor + || (oldAnchor != null && oldAnchor.equals(anchor))) + return; + sourceAnchors.set(index, anchor); + } else { + sourceAnchors.add(index, anchor); + } + updateAnchor(figure, index); + + } + + private void updateAnchor(IFigure figure, int index) { + IDecoration decoration = getDecoration(index); + if (decoration instanceof IConnectionDecoration) { + ((IConnectionDecoration) decoration).setSourceAnchor(figure, + getSourceAnchor(index)); + } + + } + + public void rerouteAll(IFigure figure) { + int size = size(); + for (int i = 0; i < size; i++) { + IDecoration decoration = getDecoration(i); + if (decoration instanceof IConnectionDecoration) { + ((IConnectionDecoration) decoration).reroute(figure); + } + } + if (figure != null) { + repaint(figure); + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutEllipseBalloonDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutEllipseBalloonDecoration.java index b5e300269..530c24485 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutEllipseBalloonDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutEllipseBalloonDecoration.java @@ -1,73 +1,73 @@ -package org.xmind.ui.internal.decorations; - -import static java.lang.Math.max; -import static java.lang.Math.round; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; -import org.xmind.ui.util.NumberUtils; - -public class CalloutEllipseBalloonDecoration extends - AbstractCalloutTopicDecoration { - - private static final double PROPORTION = 1; //1.618d; - - private static final int CORNER_GAP = 2; - - private static final int SHRINKAGE = 10; - - public CalloutEllipseBalloonDecoration() { - super(); - } - - public CalloutEllipseBalloonDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { - shape.addArc(box.x, box.y, box.width, box.height, 0, 360); - shape.close(); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - return Geometry.getChopOvalLocation(refX, refY, figure.getBounds(), - expansion); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - double w = width / 2.0 + CORNER_GAP; - double h = height / 2.0 + CORNER_GAP; - // - // w ^ 2 h ^ 2 - // --------------- + --------------- = 1 - // ( w + l ) ^ 2 ( h + t ) ^ 2 - // - // t / l = k - // ( deprecated: ( h + t ) / ( w + l ) = PROPORTION ) - // - // double t = sqrt( w * w / ( PROPORTION * PROPORTION ) + h * h ) - h; - // double l = ( h + t ) * PROPORTION - w; - double k = PROPORTION; - int a = 1; - double b = 2 * (k * w + h) / k; - double c = 4 * w * h / k; - int d = 0; - double e = -w * w * h * h / (k * k); - double l = NumberUtils.newton(new double[] { a, b, c, d, e }, w / 2); - double t = k * l; - - int prefHeight = (int) round(t); - int prefWidth = (int) round(l); - int minHeight = max(a, prefHeight - SHRINKAGE / 2); - int minWidth = max(a, prefWidth - SHRINKAGE); - return Geometry.add(super.getPreferredInsets(figure, width, height), - minHeight, minWidth, minHeight, minWidth); - } - -} +package org.xmind.ui.internal.decorations; + +import static java.lang.Math.max; +import static java.lang.Math.round; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; +import org.xmind.ui.util.NumberUtils; + +public class CalloutEllipseBalloonDecoration extends + AbstractCalloutTopicDecoration { + + private static final double PROPORTION = 1; //1.618d; + + private static final int CORNER_GAP = 2; + + private static final int SHRINKAGE = 10; + + public CalloutEllipseBalloonDecoration() { + super(); + } + + public CalloutEllipseBalloonDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { + shape.addArc(box.x, box.y, box.width, box.height, 0, 360); + shape.close(); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + return Geometry.getChopOvalLocation(refX, refY, figure.getBounds(), + expansion); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + double w = width / 2.0 + CORNER_GAP; + double h = height / 2.0 + CORNER_GAP; + // + // w ^ 2 h ^ 2 + // --------------- + --------------- = 1 + // ( w + l ) ^ 2 ( h + t ) ^ 2 + // + // t / l = k + // ( deprecated: ( h + t ) / ( w + l ) = PROPORTION ) + // + // double t = sqrt( w * w / ( PROPORTION * PROPORTION ) + h * h ) - h; + // double l = ( h + t ) * PROPORTION - w; + double k = PROPORTION; + int a = 1; + double b = 2 * (k * w + h) / k; + double c = 4 * w * h / k; + int d = 0; + double e = -w * w * h * h / (k * k); + double l = NumberUtils.newton(new double[] { a, b, c, d, e }, w / 2); + double t = k * l; + + int prefHeight = (int) round(t); + int prefWidth = (int) round(l); + int minHeight = max(a, prefHeight - SHRINKAGE / 2); + int minWidth = max(a, prefWidth - SHRINKAGE); + return Geometry.add(super.getPreferredInsets(figure, width, height), + minHeight, minWidth, minHeight, minWidth); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRectangleDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRectangleDecoration.java index c84c893bf..811609447 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRectangleDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRectangleDecoration.java @@ -1,23 +1,23 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; - -public class CalloutRectangleDecoration extends AbstractCalloutTopicDecoration { - - public CalloutRectangleDecoration() { - super(); - } - - public CalloutRectangleDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { - shape.addRectangle(box.x, box.y, box.width, box.height); - shape.close(); - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; + +public class CalloutRectangleDecoration extends AbstractCalloutTopicDecoration { + + public CalloutRectangleDecoration() { + super(); + } + + public CalloutRectangleDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { + shape.addRectangle(box.x, box.y, box.width, box.height); + shape.close(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRoundedRectDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRoundedRectDecoration.java index 2fbb8b637..329e58e80 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRoundedRectDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CalloutRoundedRectDecoration.java @@ -1,61 +1,61 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; - -public class CalloutRoundedRectDecoration extends - AbstractCalloutTopicDecoration implements ICorneredDecoration { - - private static final double M = (1 - Math.sqrt(2) / 2) * 0.8; - - private int cornerSize = 0; - - public CalloutRoundedRectDecoration() { - super(); - } - - public CalloutRoundedRectDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { - float c = getAppliedCornerSize(); - if (c == 0) { - shape.addRectangle(box.x, box.y, box.width, box.height); - } else { - shape.addRoundedRectangle(box, c); - } - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - int c = (int) (M * getAppliedCornerSize()) + getLineWidth(); - return Geometry.union(super.getPreferredInsets(figure, width, height), - c, c, c, c); - } - - public int getCornerSize() { - return cornerSize; - } - - protected int getAppliedCornerSize() { - return getCornerSize();// * getLineWidth(); - } - - public void setCornerSize(IFigure figure, int cornerSize) { - if (cornerSize == this.cornerSize) - return; - - this.cornerSize = cornerSize; - invalidate(); - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractCalloutTopicDecoration; + +public class CalloutRoundedRectDecoration extends + AbstractCalloutTopicDecoration implements ICorneredDecoration { + + private static final double M = (1 - Math.sqrt(2) / 2) * 0.8; + + private int cornerSize = 0; + + public CalloutRoundedRectDecoration() { + super(); + } + + public CalloutRoundedRectDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { + float c = getAppliedCornerSize(); + if (c == 0) { + shape.addRectangle(box.x, box.y, box.width, box.height); + } else { + shape.addRoundedRectangle(box, c); + } + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + int c = (int) (M * getAppliedCornerSize()) + getLineWidth(); + return Geometry.union(super.getPreferredInsets(figure, width, height), + c, c, c, c); + } + + public int getCornerSize() { + return cornerSize; + } + + protected int getAppliedCornerSize() { + return getCornerSize();// * getLineWidth(); + } + + public void setCornerSize(IFigure figure, int cornerSize) { + if (cornerSize == this.cornerSize) + return; + + this.cornerSize = cornerSize; + invalidate(); + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CircleTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CircleTopicDecoration.java index ff6548500..01ebb4a82 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CircleTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CircleTopicDecoration.java @@ -1,46 +1,46 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; - -public class CircleTopicDecoration extends AbstractTopicDecoration { - - public CircleTopicDecoration() { - } - - public CircleTopicDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - if (purpose == CHECK) { - shape.addArc( - box.getExpanded(getLineWidth() / 2, getLineWidth() / 2), 0, - 360); - } else { - shape.addArc(box, 0, 360); - } - shape.close(); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - double diameter = Math.sqrt(width * width + height * height); - int margin = (getTopMargin() + getLeftMargin()) / 2; - return new Insets((int) (diameter - height) / 2 + margin, - (int) (diameter - width) / 2 + margin, - (int) (diameter - height) / 2 + margin, - (int) (diameter - width) / 2 + margin); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - return Geometry.getChopOvalLocation(refX, refY, figure.getBounds(), - expansion); - } -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; + +public class CircleTopicDecoration extends AbstractTopicDecoration { + + public CircleTopicDecoration() { + } + + public CircleTopicDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + if (purpose == CHECK) { + shape.addArc( + box.getExpanded(getLineWidth() / 2, getLineWidth() / 2), 0, + 360); + } else { + shape.addArc(box, 0, 360); + } + shape.close(); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + double diameter = Math.sqrt(width * width + height * height); + int margin = (getTopMargin() + getLeftMargin()) / 2; + return new Insets((int) (diameter - height) / 2 + margin, + (int) (diameter - width) / 2 + margin, + (int) (diameter - height) / 2 + margin, + (int) (diameter - width) / 2 + margin); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + return Geometry.getChopOvalLocation(refX, refY, figure.getBounds(), + expansion); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudDecorationFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudDecorationFactory.java index 8403087e8..fb221cc9c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudDecorationFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudDecorationFactory.java @@ -1,38 +1,38 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.internal.svgsupport.SvgFileLoader; - -public class CloudDecorationFactory - implements IDecorationFactory, IExecutableExtension { - - private String svgFilePath; - - private String path; - - public CloudDecorationFactory() { - } - - public void setInitializationData(IConfigurationElement config, - String propertyName, Object data) throws CoreException { - if (data instanceof String) { - svgFilePath = (String) data; - } - - } - - public IDecoration createDecoration(String id, IGraphicalPart part) { - if (path == null) { - SvgFileLoader loader = SvgFileLoader.getInstance(); - path = loader.loadSvgFile(svgFilePath); - } - - return new CloudTopicDecoration(id, path); - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.internal.svgsupport.SvgFileLoader; + +public class CloudDecorationFactory + implements IDecorationFactory, IExecutableExtension { + + private String svgFilePath; + + private String path; + + public CloudDecorationFactory() { + } + + public void setInitializationData(IConfigurationElement config, + String propertyName, Object data) throws CoreException { + if (data instanceof String) { + svgFilePath = (String) data; + } + + } + + public IDecoration createDecoration(String id, IGraphicalPart part) { + if (path == null) { + SvgFileLoader loader = SvgFileLoader.getInstance(); + path = loader.loadSvgFile(svgFilePath); + } + + return new CloudTopicDecoration(id, path); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudTopicDecoration.java index 6fabab810..835dade2e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudTopicDecoration.java @@ -1,146 +1,146 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.PrecisionDimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; -import org.xmind.ui.internal.svgsupport.SvgPathParser; - -public class CloudTopicDecoration extends AbstractTopicDecoration { - - private static final float scaleLeft = 0.17f; - private static final float scaleRight = 0.16f; - private static final float scaleTop = 0.22f; - private static final float scaleBottom = 0.27f; - - private static final float RATIO = 2.5f; - - private String svgPath; - - public CloudTopicDecoration() { - - } - - public CloudTopicDecoration(String id) { - super(id); - } - - public CloudTopicDecoration(String id, String svgPath) { - super(id); - this.svgPath = svgPath; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - Path path = new Path(Display.getCurrent()); - SvgPathParser parser = SvgPathParser.getInstance(); - - float halfLineWidth = getLineWidth() * 0.5f; - if (purpose == CHECK) { - parser.parseSvgPath(path, box.getCenter().x - halfLineWidth, - box.getCenter().y + halfLineWidth, - box.width + getLineWidth(), box.height + getLineWidth(), - svgPath); - } else { - parser.parseSvgPath(path, box.getCenter().x + 1, - box.getCenter().y + 1, box.width, box.height, svgPath); - } - - shape.addPath(path); - path.close(); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - float scaleWidth = 1 - scaleLeft - scaleRight; - float scaleHeight = 1 - scaleTop - scaleBottom; - Rectangle bounds = figure.getBounds(); - Point tf = bounds.getTopLeft().getTranslated(bounds.width * scaleLeft, - bounds.height * scaleTop); - Rectangle area = new Rectangle(tf.x, tf.y, - (int) (bounds.width * scaleWidth), - (int) (bounds.height * scaleHeight)); - - PrecisionPoint p1 = Geometry.getChopBoxLocation(refX, refY, area, - expansion); - - PrecisionPoint p2 = Geometry.getChopBoxLocation(refX, refY, - getOutlineBox(figure), expansion); - - return calcAnchorLocation(figure, p1, p2); - } - - private PrecisionPoint calcAnchorLocation(IFigure figure, PrecisionPoint p1, - PrecisionPoint p2) { - if (p1.getDistance(p2) < (getLineWidth() == 0 ? 1 : getLineWidth())) - return p2; - - PrecisionPoint p3 = new PrecisionPoint((p1.x + p2.x) / 2, - (p1.y + p2.y) / 2); - if (containsPoint(figure, (float) p3.x, (float) p3.y)) - return calcAnchorLocation(figure, p3, p2); - else - return calcAnchorLocation(figure, p1, p3); - } - - private boolean containsPoint(IFigure figure, float x, float y) { - checkValidation(figure); - GC gc = GraphicsUtils.getAdvanced().getGC(); - gc.setLineWidth(getCheckingLineWidth()); - Path shape = new Path(Display.getCurrent()); - sketch(figure, shape, getOutlineBox(figure), FILL); - boolean ret = shape.contains(x, y, gc, false); - shape.close(); - shape.dispose(); - return ret; - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - float scaleWidth = 1 - scaleLeft - scaleRight; - float scaleHeight = 1 - scaleTop - scaleBottom; - Insets insets = new Insets( - (int) ((height + getTopMargin() + getLineWidth()) / scaleHeight - * scaleTop), - (int) ((width + getLeftMargin() + getLineWidth()) / scaleWidth - * scaleLeft), - (int) ((height + getBottomMargin() + getLineWidth()) - / scaleHeight * scaleBottom), - (int) ((width + getRightMargin() + getLineWidth()) / scaleWidth - * scaleRight)); - - PrecisionDimension dimension = expandWHitAsRatio( - new PrecisionDimension(width + insets.left + insets.right, - height + insets.top + insets.bottom)); - Insets inset = new Insets(); - inset.top = (int) ((dimension.height - height) * scaleTop - / (scaleTop + scaleBottom)); - inset.left = (int) ((dimension.width - width) * scaleLeft - / (scaleLeft + scaleRight)); - inset.bottom = (int) ((dimension.height - height) * scaleBottom - / (scaleTop + scaleBottom)); - inset.right = (int) ((dimension.width - width) * scaleRight - / (scaleLeft + scaleRight)); - return inset; - } - - private PrecisionDimension expandWHitAsRatio( - PrecisionDimension whitDimension) { - PrecisionDimension dimension = whitDimension; - if (whitDimension.width > whitDimension.height * RATIO) { - dimension.height = (int) Math.ceil(whitDimension.width / RATIO); - dimension.width = (int) (dimension.height * RATIO); - } else if (whitDimension.width < whitDimension.height * RATIO) { - dimension.width = (int) Math.ceil(whitDimension.height * RATIO); - } - return dimension; - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PrecisionDimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; +import org.xmind.ui.internal.svgsupport.SvgPathParser; + +public class CloudTopicDecoration extends AbstractTopicDecoration { + + private static final float scaleLeft = 0.17f; + private static final float scaleRight = 0.16f; + private static final float scaleTop = 0.22f; + private static final float scaleBottom = 0.27f; + + private static final float RATIO = 2.5f; + + private String svgPath; + + public CloudTopicDecoration() { + + } + + public CloudTopicDecoration(String id) { + super(id); + } + + public CloudTopicDecoration(String id, String svgPath) { + super(id); + this.svgPath = svgPath; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + Path path = new Path(Display.getCurrent()); + SvgPathParser parser = SvgPathParser.getInstance(); + + float halfLineWidth = getLineWidth() * 0.5f; + if (purpose == CHECK) { + parser.parseSvgPath(path, box.getCenter().x - halfLineWidth, + box.getCenter().y + halfLineWidth, + box.width + getLineWidth(), box.height + getLineWidth(), + svgPath); + } else { + parser.parseSvgPath(path, box.getCenter().x + 1, + box.getCenter().y + 1, box.width, box.height, svgPath); + } + + shape.addPath(path); + path.close(); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + float scaleWidth = 1 - scaleLeft - scaleRight; + float scaleHeight = 1 - scaleTop - scaleBottom; + Rectangle bounds = figure.getBounds(); + Point tf = bounds.getTopLeft().getTranslated(bounds.width * scaleLeft, + bounds.height * scaleTop); + Rectangle area = new Rectangle(tf.x, tf.y, + (int) (bounds.width * scaleWidth), + (int) (bounds.height * scaleHeight)); + + PrecisionPoint p1 = Geometry.getChopBoxLocation(refX, refY, area, + expansion); + + PrecisionPoint p2 = Geometry.getChopBoxLocation(refX, refY, + getOutlineBox(figure), expansion); + + return calcAnchorLocation(figure, p1, p2); + } + + private PrecisionPoint calcAnchorLocation(IFigure figure, PrecisionPoint p1, + PrecisionPoint p2) { + if (p1.getDistance(p2) < (getLineWidth() == 0 ? 1 : getLineWidth())) + return p2; + + PrecisionPoint p3 = new PrecisionPoint((p1.x + p2.x) / 2, + (p1.y + p2.y) / 2); + if (containsPoint(figure, (float) p3.x, (float) p3.y)) + return calcAnchorLocation(figure, p3, p2); + else + return calcAnchorLocation(figure, p1, p3); + } + + private boolean containsPoint(IFigure figure, float x, float y) { + checkValidation(figure); + GC gc = GraphicsUtils.getAdvanced().getGC(); + gc.setLineWidth(getCheckingLineWidth()); + Path shape = new Path(Display.getCurrent()); + sketch(figure, shape, getOutlineBox(figure), FILL); + boolean ret = shape.contains(x, y, gc, false); + shape.close(); + shape.dispose(); + return ret; + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + float scaleWidth = 1 - scaleLeft - scaleRight; + float scaleHeight = 1 - scaleTop - scaleBottom; + Insets insets = new Insets( + (int) ((height + getTopMargin() + getLineWidth()) / scaleHeight + * scaleTop), + (int) ((width + getLeftMargin() + getLineWidth()) / scaleWidth + * scaleLeft), + (int) ((height + getBottomMargin() + getLineWidth()) + / scaleHeight * scaleBottom), + (int) ((width + getRightMargin() + getLineWidth()) / scaleWidth + * scaleRight)); + + PrecisionDimension dimension = expandWHitAsRatio( + new PrecisionDimension(width + insets.left + insets.right, + height + insets.top + insets.bottom)); + Insets inset = new Insets(); + inset.top = (int) ((dimension.height - height) * scaleTop + / (scaleTop + scaleBottom)); + inset.left = (int) ((dimension.width - width) * scaleLeft + / (scaleLeft + scaleRight)); + inset.bottom = (int) ((dimension.height - height) * scaleBottom + / (scaleTop + scaleBottom)); + inset.right = (int) ((dimension.width - width) * scaleRight + / (scaleLeft + scaleRight)); + return inset; + } + + private PrecisionDimension expandWHitAsRatio( + PrecisionDimension whitDimension) { + PrecisionDimension dimension = whitDimension; + if (whitDimension.width > whitDimension.height * RATIO) { + dimension.height = (int) Math.ceil(whitDimension.width / RATIO); + dimension.width = (int) (dimension.height * RATIO); + } else if (whitDimension.width < whitDimension.height * RATIO) { + dimension.width = (int) Math.ceil(whitDimension.height * RATIO); + } + return dimension; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CurvedRelationshipDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CurvedRelationshipDecoration.java index f9f1c50dc..83c2637fc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CurvedRelationshipDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CurvedRelationshipDecoration.java @@ -1,116 +1,116 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractRelationshipDecoration; -import org.xmind.ui.style.Styles; - -public class CurvedRelationshipDecoration - extends AbstractRelationshipDecoration { - - private static final double f1 = 0.125; - - private static final double f2 = 3 * 0.125; - - public CurvedRelationshipDecoration() { - } - - public CurvedRelationshipDecoration(String id) { - super(id); - } - - protected void route(IFigure figure, Path shape) { - PrecisionPoint sp = getSourcePosition(figure); - PrecisionPoint tp = getTargetPosition(figure); - PrecisionPoint cp1 = getSourceControlPoint(figure); - PrecisionPoint cp2 = getTargetControlPoint(figure); - shape.moveTo(sp); - shape.cubicTo(cp1, cp2, tp); - } - - protected void calcTitlePosition(IFigure figure, PrecisionPoint titlePos, - PrecisionPoint sourcePos, PrecisionPoint targetPos, - PrecisionPoint sourceCP, PrecisionPoint targetCP) { - double x = f1 * sourcePos.x + f2 * sourceCP.x + f2 * targetCP.x - + f1 * targetPos.x; - double y = f1 * sourcePos.y + f2 * sourceCP.y + f2 * targetCP.y - + f1 * targetPos.y; - titlePos.setLocation(x, y); - } - - @Override - protected void reroute(IFigure figure, PrecisionPoint sourcePos, - PrecisionPoint targetPos, PrecisionPoint sourceCP, - PrecisionPoint targetCP) { - IAnchor sa = getSourceAnchor(); - IAnchor ta = getTargetAnchor(); - - PrecisionPoint a1 = null; - PrecisionPoint a2 = null; - if (sa != null) { - if (relativeSourceCP != null) { - sourceCP.setLocation(sa.getReferencePoint()) - .translate(relativeSourceCP.x, relativeSourceCP.y); - sourcePos.setLocation(sa.getLocation(sourceCP, 0)); - } else if (ta != null) { - if (a1 == null) - a1 = sa.getLocation(ta.getReferencePoint(), 0); - sourcePos.setLocation(a1); - if (a2 == null) - a2 = ta.getLocation(sa.getReferencePoint(), 0); - sourceCP.setLocation(a1).move(a2, - Styles.DEF_CONTROL_POINT_AMOUNT); - - if (sourceCPAngle != null && sourceCPAngle != 0) { - if (!sa.getOwner().containsPoint(sourceCP.toDraw2DPoint()) - && !sa.getOwner() - .intersects(ta.getOwner().getBounds())) { - updatePosAndCp(sa, sourcePos, sourceCP, sourceCPAngle); - } - } - } - - if (ta != null) { - if (relativeTargetCP != null) { - targetCP.setLocation(ta.getReferencePoint()) - .translate(relativeTargetCP.x, relativeTargetCP.y); - targetPos.setLocation(ta.getLocation(targetCP, 0)); - } else if (sa != null) { - if (a2 == null) - a2 = ta.getLocation(sa.getReferencePoint(), 0); - targetPos.setLocation(a2); - if (a1 == null) - a1 = sa.getLocation(ta.getReferencePoint(), 0); - targetCP.setLocation(a2).move(a1, - Styles.DEF_CONTROL_POINT_AMOUNT); - - if (targetCPAngle != null && targetCPAngle != 0) { - if (!sa.getOwner() - .containsPoint(sourceCP.toDraw2DPoint()) - && !sa.getOwner().intersects( - ta.getOwner().getBounds())) { - updatePosAndCp(ta, targetPos, targetCP, - targetCPAngle); - } - } - } - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractRelationshipDecoration; +import org.xmind.ui.style.Styles; + +public class CurvedRelationshipDecoration + extends AbstractRelationshipDecoration { + + private static final double f1 = 0.125; + + private static final double f2 = 3 * 0.125; + + public CurvedRelationshipDecoration() { + } + + public CurvedRelationshipDecoration(String id) { + super(id); + } + + protected void route(IFigure figure, Path shape) { + PrecisionPoint sp = getSourcePosition(figure); + PrecisionPoint tp = getTargetPosition(figure); + PrecisionPoint cp1 = getSourceControlPoint(figure); + PrecisionPoint cp2 = getTargetControlPoint(figure); + shape.moveTo(sp); + shape.cubicTo(cp1, cp2, tp); + } + + protected void calcTitlePosition(IFigure figure, PrecisionPoint titlePos, + PrecisionPoint sourcePos, PrecisionPoint targetPos, + PrecisionPoint sourceCP, PrecisionPoint targetCP) { + double x = f1 * sourcePos.x + f2 * sourceCP.x + f2 * targetCP.x + + f1 * targetPos.x; + double y = f1 * sourcePos.y + f2 * sourceCP.y + f2 * targetCP.y + + f1 * targetPos.y; + titlePos.setLocation(x, y); + } + + @Override + protected void reroute(IFigure figure, PrecisionPoint sourcePos, + PrecisionPoint targetPos, PrecisionPoint sourceCP, + PrecisionPoint targetCP) { + IAnchor sa = getSourceAnchor(); + IAnchor ta = getTargetAnchor(); + + PrecisionPoint a1 = null; + PrecisionPoint a2 = null; + if (sa != null) { + if (relativeSourceCP != null) { + sourceCP.setLocation(sa.getReferencePoint()) + .translate(relativeSourceCP.x, relativeSourceCP.y); + sourcePos.setLocation(sa.getLocation(sourceCP, 0)); + } else if (ta != null) { + if (a1 == null) + a1 = sa.getLocation(ta.getReferencePoint(), 0); + sourcePos.setLocation(a1); + if (a2 == null) + a2 = ta.getLocation(sa.getReferencePoint(), 0); + sourceCP.setLocation(a1).move(a2, + Styles.DEF_CONTROL_POINT_AMOUNT); + + if (sourceCPAngle != null && sourceCPAngle != 0) { + if (!sa.getOwner().containsPoint(sourceCP.toDraw2DPoint()) + && !sa.getOwner() + .intersects(ta.getOwner().getBounds())) { + updatePosAndCp(sa, sourcePos, sourceCP, sourceCPAngle); + } + } + } + + if (ta != null) { + if (relativeTargetCP != null) { + targetCP.setLocation(ta.getReferencePoint()) + .translate(relativeTargetCP.x, relativeTargetCP.y); + targetPos.setLocation(ta.getLocation(targetCP, 0)); + } else if (sa != null) { + if (a2 == null) + a2 = ta.getLocation(sa.getReferencePoint(), 0); + targetPos.setLocation(a2); + if (a1 == null) + a1 = sa.getLocation(ta.getReferencePoint(), 0); + targetCP.setLocation(a2).move(a1, + Styles.DEF_CONTROL_POINT_AMOUNT); + + if (targetCPAngle != null && targetCPAngle != 0) { + if (!sa.getOwner() + .containsPoint(sourceCP.toDraw2DPoint()) + && !sa.getOwner().intersects( + ta.getOwner().getBounds())) { + updatePosAndCp(ta, targetPos, targetCP, + targetCPAngle); + } + } + } + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/DefaultBranchDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/DefaultBranchDecoration.java index 67b5c7846..719b7badd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/DefaultBranchDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/DefaultBranchDecoration.java @@ -1,88 +1,88 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.draw2d.decoration.AbstractDecoration; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.IBranchConnections; -import org.xmind.ui.decorations.IBranchDecoration; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.style.Styles; - -public class DefaultBranchDecoration extends AbstractDecoration implements - IBranchDecoration, IShadowedDecoration { - - private IBranchPart branch; - - public DefaultBranchDecoration(IBranchPart branch) { - this(branch, Styles.DEF_BRANCH_DECORATION); - } - - public DefaultBranchDecoration(IBranchPart branch, String id) { - super(id); - this.branch = branch; - } - - protected void performPaint(IFigure figure, Graphics graphics) { - paintExpandedLine(graphics, false); - } - - private void paintExpandedLine(Graphics graphics, boolean paintingShadow) { - IBranchConnections connections = branch.getConnections(); - if (connections == null || connections.isEmpty() - || !connections.isVisible()) - return; - - int orientation = connections.getSourceOrientation(); - if (orientation == PositionConstants.NONE) - return; - - IAnchor anc = connections.getSourceAnchor(); - if (anc == null) - return; - - PrecisionPoint p1 = anc.getLocation(orientation, 0); - PrecisionPoint p2 = anc.getLocation(orientation, connections - .getSourceExpansion()); - graphics.setLineStyle(connections.getLineStyle()); - graphics.setLineWidth(connections.getLineWidth()); - if (!paintingShadow) - graphics.setForegroundColor(connections.getLineColor()); - if (graphics.getForegroundColor() == null) - graphics.setForegroundColor(ColorConstants.black); - graphics.setAlpha(connections.getAlpha()); - Path p = new Path(Display.getCurrent()); - p.moveTo(p1); - p.lineTo(p2); - graphics.drawPath(p); - p.dispose(); - } - - public void paintAboveChildren(IFigure figure, Graphics graphics) { - } - - public void paintShadow(IFigure figure, Graphics graphics) { - graphics.setForegroundColor(ColorConstants.black); - paintExpandedLine(graphics, true); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.draw2d.decoration.AbstractDecoration; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.IBranchConnections; +import org.xmind.ui.decorations.IBranchDecoration; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.style.Styles; + +public class DefaultBranchDecoration extends AbstractDecoration implements + IBranchDecoration, IShadowedDecoration { + + private IBranchPart branch; + + public DefaultBranchDecoration(IBranchPart branch) { + this(branch, Styles.DEF_BRANCH_DECORATION); + } + + public DefaultBranchDecoration(IBranchPart branch, String id) { + super(id); + this.branch = branch; + } + + protected void performPaint(IFigure figure, Graphics graphics) { + paintExpandedLine(graphics, false); + } + + private void paintExpandedLine(Graphics graphics, boolean paintingShadow) { + IBranchConnections connections = branch.getConnections(); + if (connections == null || connections.isEmpty() + || !connections.isVisible()) + return; + + int orientation = connections.getSourceOrientation(); + if (orientation == PositionConstants.NONE) + return; + + IAnchor anc = connections.getSourceAnchor(); + if (anc == null) + return; + + PrecisionPoint p1 = anc.getLocation(orientation, 0); + PrecisionPoint p2 = anc.getLocation(orientation, connections + .getSourceExpansion()); + graphics.setLineStyle(connections.getLineStyle()); + graphics.setLineWidth(connections.getLineWidth()); + if (!paintingShadow) + graphics.setForegroundColor(connections.getLineColor()); + if (graphics.getForegroundColor() == null) + graphics.setForegroundColor(ColorConstants.black); + graphics.setAlpha(connections.getAlpha()); + Path p = new Path(Display.getCurrent()); + p.moveTo(p1); + p.lineTo(p2); + graphics.drawPath(p); + p.dispose(); + } + + public void paintAboveChildren(IFigure figure, Graphics graphics) { + } + + public void paintShadow(IFigure figure, Graphics graphics) { + graphics.setForegroundColor(ColorConstants.black); + paintExpandedLine(graphics, true); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseBalloonCalloutBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseBalloonCalloutBranchConnection.java index 954cb5b59..496dc34c5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseBalloonCalloutBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseBalloonCalloutBranchConnection.java @@ -1,37 +1,37 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; - -public class EllipseBalloonCalloutBranchConnection - extends AbstractCalloutBranchConnection { - - private static final float ARCANGLE = 340; - - public EllipseBalloonCalloutBranchConnection() { - super(); - } - - public EllipseBalloonCalloutBranchConnection(String id) { - super(id); - } - - protected void route(IFigure figure, Path shape) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - - Rectangle targetRect = getTargetAnchor().getOwner().getBounds(); - targetRect = getOutlineBox(targetRect); - - double angle = Geometry.getOvalAngle(p2.x, p2.y, targetRect); - double degrees = Math.toDegrees(angle); - - shape.addArc(targetRect, (float) (degrees), ARCANGLE); - shape.lineTo(p1); - shape.close(); - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; + +public class EllipseBalloonCalloutBranchConnection + extends AbstractCalloutBranchConnection { + + private static final float ARCANGLE = 340; + + public EllipseBalloonCalloutBranchConnection() { + super(); + } + + public EllipseBalloonCalloutBranchConnection(String id) { + super(id); + } + + protected void route(IFigure figure, Path shape) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + + Rectangle targetRect = getTargetAnchor().getOwner().getBounds(); + targetRect = getOutlineBox(targetRect); + + double angle = Geometry.getOvalAngle(p2.x, p2.y, targetRect); + double degrees = Math.toDegrees(angle); + + shape.addArc(targetRect, (float) (degrees), ARCANGLE); + shape.lineTo(p1); + shape.close(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseCalloutTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseCalloutTopicDecoration.java index 5bb0b48b4..490be230f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseCalloutTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/EllipseCalloutTopicDecoration.java @@ -1,41 +1,41 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.graphics.Path; - -public class EllipseCalloutTopicDecoration extends EllipseTopicDecoration { - - private static final float STARTANGLE = -130; - - private static final float ARCANGLE = 345; - - public EllipseCalloutTopicDecoration() { - super(); - } - - public EllipseCalloutTopicDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { - shape.addArc(box.x, box.y, box.width, box.height, STARTANGLE, ARCANGLE); - float h = box.height; - shape.lineTo(box.x, box.y + h); - shape.close(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.graphics.Path; + +public class EllipseCalloutTopicDecoration extends EllipseTopicDecoration { + + private static final float STARTANGLE = -130; + + private static final float ARCANGLE = 345; + + public EllipseCalloutTopicDecoration() { + super(); + } + + public EllipseCalloutTopicDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { + shape.addArc(box.x, box.y, box.width, box.height, STARTANGLE, ARCANGLE); + float h = box.height; + shape.lineTo(box.x, box.y + h); + shape.close(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/ParallelogramTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/ParallelogramTopicDecoration.java index 19907c51f..530d25cab 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/ParallelogramTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/ParallelogramTopicDecoration.java @@ -1,80 +1,80 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; - -public class ParallelogramTopicDecoration extends AbstractTopicDecoration { - - private static final float SCALE = 0.5f; - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - if (purpose == CHECK) { - float halfLineWidth = getLineWidth() * 0.5f; - shape.moveTo(box.x + box.height * SCALE - halfLineWidth, - box.y - halfLineWidth); - shape.lineTo(box.x - halfLineWidth, box.bottom() + halfLineWidth); - shape.lineTo(box.right() - box.height * SCALE + halfLineWidth, - box.bottom() + halfLineWidth); - shape.lineTo(box.right() + halfLineWidth, box.y - halfLineWidth); - } else { - float scaledLineWidth = getLineWidth() * SCALE; - shape.moveTo(box.x + box.height * SCALE, box.y); - shape.lineTo(box.x + scaledLineWidth, box.bottom()); - shape.lineTo(box.right() - box.height * SCALE, box.bottom()); - shape.lineTo(box.right() - scaledLineWidth, box.y); - } - shape.close(); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - return new Insets(getTopMargin() + getLineWidth(), - getLeftMargin() + getLineWidth() + Math.round(height * SCALE) - + 1, - getBottomMargin() + getLineWidth(), getRightMargin() - + getLineWidth() + Math.round(height * SCALE) + 1); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - - Rectangle r = getOutlineBox(figure); - double cx = r.x + 0.5f * r.width; - double cy = r.y + 0.5f * r.height; - double dx = refX - cx; - double dy = refY - cy; - - if (dx == 0) - return new PrecisionPoint(refX, - (dy > 0) ? r.bottom() + expansion : r.y - expansion); - if (dy == 0) - return new PrecisionPoint( - (dx > 0) ? r.right() - r.height * SCALE * SCALE + expansion - : r.x + r.height * SCALE * SCALE - expansion, - refY); - - double scale = 0.5f - / Math.max(Math.abs(dx) / r.width, Math.abs(dy) / r.height); - - dx = Math.round(dx *= scale); - dy = Math.round(dy *= scale); - - if (Math.abs(dy) < r.height / 2 || ((dy >= r.height / 2 - && dx > r.width / 2 - r.height / 2) - || (dy <= -r.height / 2 && dx < -r.width / 2 + r.height / 2))) { - dx = (dx > 0) ? dx - (r.height * SCALE + dy) * SCALE - : dx + (r.height * SCALE - dy) * SCALE; - - } - - cx += dx; - cy += dy; - - return new PrecisionPoint(cx, cy); - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; + +public class ParallelogramTopicDecoration extends AbstractTopicDecoration { + + private static final float SCALE = 0.5f; + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + if (purpose == CHECK) { + float halfLineWidth = getLineWidth() * 0.5f; + shape.moveTo(box.x + box.height * SCALE - halfLineWidth, + box.y - halfLineWidth); + shape.lineTo(box.x - halfLineWidth, box.bottom() + halfLineWidth); + shape.lineTo(box.right() - box.height * SCALE + halfLineWidth, + box.bottom() + halfLineWidth); + shape.lineTo(box.right() + halfLineWidth, box.y - halfLineWidth); + } else { + float scaledLineWidth = getLineWidth() * SCALE; + shape.moveTo(box.x + box.height * SCALE, box.y); + shape.lineTo(box.x + scaledLineWidth, box.bottom()); + shape.lineTo(box.right() - box.height * SCALE, box.bottom()); + shape.lineTo(box.right() - scaledLineWidth, box.y); + } + shape.close(); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + return new Insets(getTopMargin() + getLineWidth(), + getLeftMargin() + getLineWidth() + Math.round(height * SCALE) + + 1, + getBottomMargin() + getLineWidth(), getRightMargin() + + getLineWidth() + Math.round(height * SCALE) + 1); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + + Rectangle r = getOutlineBox(figure); + double cx = r.x + 0.5f * r.width; + double cy = r.y + 0.5f * r.height; + double dx = refX - cx; + double dy = refY - cy; + + if (dx == 0) + return new PrecisionPoint(refX, + (dy > 0) ? r.bottom() + expansion : r.y - expansion); + if (dy == 0) + return new PrecisionPoint( + (dx > 0) ? r.right() - r.height * SCALE * SCALE + expansion + : r.x + r.height * SCALE * SCALE - expansion, + refY); + + double scale = 0.5f + / Math.max(Math.abs(dx) / r.width, Math.abs(dy) / r.height); + + dx = Math.round(dx *= scale); + dy = Math.round(dy *= scale); + + if (Math.abs(dy) < r.height / 2 || ((dy >= r.height / 2 + && dx > r.width / 2 - r.height / 2) + || (dy <= -r.height / 2 && dx < -r.width / 2 + r.height / 2))) { + dx = (dx > 0) ? dx - (r.height * SCALE + dy) * SCALE + : dx + (r.height * SCALE - dy) * SCALE; + + } + + cx += dx; + cy += dy; + + return new PrecisionPoint(cx, cy); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecoration.java index d6e90c1d4..ff1c2378f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecoration.java @@ -1,590 +1,590 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.ui.branch.IBranchStructureExtension; -import org.xmind.ui.decorations.AbstractBoundaryDecoration; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; - -public class PolygonBoundaryDecoration extends AbstractBoundaryDecoration { - - private class ValueComparator implements Comparator { - - private Map base; - - public ValueComparator(Map base) { - this.base = base; - } - - public int compare(ITopicPart t1, ITopicPart t2) { - if (base.get(t1) > base.get(t2)) - return 1; - return -1; - } - - } - - private IBoundaryPart boundary; - - public PolygonBoundaryDecoration() { - super(); - } - - public PolygonBoundaryDecoration(String id) { - super(id); - } - - public PolygonBoundaryDecoration(IBoundaryPart boundary, String id) { - super(id); - this.boundary = boundary; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - List points = calcPathPoints(box, boundary); - - if (points.size() > 4) { - shape.moveTo(points.get(0)); - for (int i = 1; i < points.size(); i++) - shape.lineTo(points.get(i)); - shape.lineTo(points.get(0)); - shape.close(); - } else { - shape.addRectangle(box); - } - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - Rectangle bounds = figure.getBounds(); - PrecisionPoint p1 = new PrecisionPoint(bounds.x + bounds.width / 2, - bounds.y + bounds.height / 2); - - PrecisionPoint p2 = Geometry.getChopBoxLocation(refX, refY, - getOutlineBox(figure), expansion); - - return calcAnchorLocation(figure, p1, p2); - } - - private PrecisionPoint calcAnchorLocation(IFigure figure, PrecisionPoint p1, - PrecisionPoint p2) { - if (p1.getDistance(p2) < (getLineWidth() == 0 ? 1 : getLineWidth())) - return p2; - - PrecisionPoint p3 = new PrecisionPoint((p1.x + p2.x) / 2, - (p1.y + p2.y) / 2); - if (containsPoint(figure, (float) p3.x, (float) p3.y)) - return calcAnchorLocation(figure, p3, p2); - else - return calcAnchorLocation(figure, p1, p3); - } - - private boolean containsPoint(IFigure figure, float x, float y) { - checkValidation(figure); - GC gc = GraphicsUtils.getAdvanced().getGC(); - gc.setLineWidth(getCheckingLineWidth()); - Path shape = new Path(Display.getCurrent()); - sketch(figure, shape, getOutlineBox(figure), FILL); - boolean ret = shape.contains(x, y, gc, false); - shape.close(); - shape.dispose(); - return ret; - } - - protected List calcPathPoints(Rectangle box, - IBoundaryPart boundary) { - List enclosingBranches = boundary.getEnclosingBranches(); - IBranchPart branch; - if (!enclosingBranches.isEmpty()) - branch = enclosingBranches.get(0); - else - branch = boundary.getOwnedBranch(); - - int childDirection = calcChildDirection(branch); - - List topics = collectTopics(boundary); - - List points = new ArrayList(); - switch (childDirection) { - case PositionConstants.WEST: - collectPointsWestDire(points, topics, box); - break; - case PositionConstants.EAST: - collcetPointsEastDire(points, topics, box); - break; - case PositionConstants.SOUTH: - collectPointsSouthDire(points, topics, box); - break; - case PositionConstants.NORTH: - collectPointsNorthDire(points, topics, box); - break; - } - - return points; - } - - private void collectPointsWestDire(List points, - List topics, Rectangle box) { - int lineWidth1 = getLineWidth(); - int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; - - Map headMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(headMap, bounds.x); - if (t != null) { - if (bounds.y < t.getFigure().getBounds().y) { - headMap.remove(t); - headMap.put(topic, bounds.x); - } - } else { - headMap.put(topic, bounds.x); - } - } - - List headPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(headMap)) - headPoints.add(topic.getFigure().getBounds().getTopLeft() - .getTranslated(-MARGIN_WIDTH + lineWidth2, - -MARGIN_HEIGHT + lineWidth2)); - - Map tailMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(tailMap, bounds.x); - if (t != null) { - if (bounds.bottom() > t.getFigure().getBounds().bottom()) { - tailMap.remove(t); - tailMap.put(topic, bounds.x); - } - } else { - tailMap.put(topic, bounds.x); - } - } - List tailPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(tailMap)) - tailPoints.add(topic.getFigure().getBounds().getBottomLeft() - .getTranslated(-MARGIN_WIDTH + lineWidth2, - MARGIN_HEIGHT - lineWidth2)); - - Point tr = box.getTopRight(); - Point br = box.getBottomRight(); - - initPoints(points, headPoints.get(0), tr, br, tailPoints.get(0)); - - calcPointsWestOrEast(points, tr, br, headPoints, tailPoints); - - } - - private void collcetPointsEastDire(List points, - List topics, Rectangle box) { - int lineWidth1 = getLineWidth(); - int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; - - Map headMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(headMap, -bounds.right()); - if (t != null) { - if (bounds.y < t.getFigure().getBounds().y) { - headMap.remove(t); - headMap.put(topic, -bounds.right()); - } - } else { - headMap.put(topic, -bounds.right()); - } - } - - List headPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(headMap)) - headPoints.add(topic.getFigure().getBounds().getTopRight() - .getTranslated(MARGIN_WIDTH - lineWidth1, - -MARGIN_HEIGHT + lineWidth2)); - - Map tailMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(tailMap, -bounds.right()); - if (t != null) { - if (bounds.bottom() > t.getFigure().getBounds().bottom()) { - tailMap.remove(t); - tailMap.put(topic, -bounds.right()); - } - } else { - tailMap.put(topic, -bounds.right()); - } - } - - List tailPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(tailMap)) - tailPoints.add(topic.getFigure().getBounds().getBottomRight() - .getTranslated(MARGIN_WIDTH - lineWidth1, MARGIN_HEIGHT - - (lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1))); - - Point tl = box.getTopLeft(); - Point bl = box.getBottomLeft(); - - initPoints(points, headPoints.get(0), tl, bl, tailPoints.get(0)); - - calcPointsWestOrEast(points, tl, bl, headPoints, tailPoints); - } - - private void calcPointsWestOrEast(List points, Point crl1, - Point crl2, List headPoints, List tailPoints) { - int upSize = 2; - if (headPoints.get(0).y > crl1.y) { - for (int i = headPoints.size() - 1; i > 0; i--) { - Point point = headPoints.get(i); - Point firstPoint = points.get(0); - Point secPoint = points.get(1); - if (firstPoint.y == secPoint.y && !firstPoint.equals(secPoint)) - break; - - if (!secPoint.equals(crl1) && secPoint.y == point.y) { - points.remove(1); - points.add(1, point); - } else if (isUpperLine(firstPoint, secPoint, point)) { - points.add(1, point); - upSize++; - } - } - } - for (int i = 1; i < upSize - 1; i++) { - if (!isUpperLine(points.get(i - 1), points.get(i + 1), - points.get(i))) { - points.remove(i--); - upSize--; - if (i > 1) - i--; - } - } - - if (tailPoints.get(0).y < crl2.y) { - for (int i = tailPoints.size() - 1; i > 0; i--) { - Point point = tailPoints.get(i); - Point lastPoint = points.get(points.size() - 1); - Point penPoint = points.get(points.size() - 2); - - if (lastPoint.y == penPoint.y) - break; - - if (!penPoint.equals(crl2) && penPoint.y == point.y) { - points.remove(points.size() - 2); - points.add(points.size() - 1, point); - } else if (!isUpperLine(penPoint, lastPoint, point)) { - points.add(points.size() - 1, point); - } - } - } - for (int i = upSize + 1; i < points.size() - 1; i++) { - if (isUpperLine(points.get(i - 1), points.get(i + 1), - points.get(i))) { - points.remove(i--); - if (i > upSize) - i--; - } - } - } - - private void collectPointsSouthDire(List points, - List topics, Rectangle box) { - int lineWidth1 = getLineWidth(); - int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; - - Map headMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(headMap, -bounds.bottom()); - if (t != null) { - if (bounds.x < t.getFigure().getBounds().x) { - headMap.remove(t); - headMap.put(topic, -bounds.bottom()); - } - } else { - headMap.put(topic, -bounds.bottom()); - } - } - - List headPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(headMap)) - headPoints.add(topic.getFigure().getBounds().getBottomLeft() - .getTranslated(-MARGIN_WIDTH + lineWidth2, - MARGIN_HEIGHT - lineWidth2)); - - Map tailMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(tailMap, -bounds.bottom()); - if (t != null) { - if (bounds.right() > t.getFigure().getBounds().right()) { - tailMap.remove(t); - tailMap.put(topic, -bounds.bottom()); - } - } else { - tailMap.put(topic, -bounds.bottom()); - } - } - - List tailPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(tailMap)) - tailPoints.add(topic.getFigure().getBounds().getBottomRight() - .getTranslated(MARGIN_WIDTH - lineWidth1, - MARGIN_HEIGHT - lineWidth2)); - - Point tl = box.getTopLeft(); - Point tr = box.getTopRight(); - - initPoints(points, headPoints.get(0), tl, tr, tailPoints.get(0)); - - calcPointsSouthOrNorth(points, tl, tr, headPoints, tailPoints); - } - - private void collectPointsNorthDire(List points, - List topics, Rectangle box) { - int lineWidth1 = getLineWidth(); - int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; - Map headMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(headMap, bounds.y); - if (t != null) { - if (bounds.x < t.getFigure().getBounds().x) { - headMap.remove(t); - headMap.put(topic, bounds.y); - } - } else { - headMap.put(topic, bounds.y); - } - } - - List headPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(headMap)) - headPoints.add(topic.getFigure().getBounds().getTopLeft() - .getTranslated(-MARGIN_WIDTH + lineWidth2, - -MARGIN_HEIGHT + lineWidth1)); - - Map tailMap = new HashMap(); - for (ITopicPart topic : topics) { - Rectangle bounds = topic.getFigure().getBounds(); - ITopicPart t = findTopicByValue(tailMap, bounds.y); - if (t != null) { - if (bounds.right() > t.getFigure().getBounds().right()) { - tailMap.remove(t); - tailMap.put(topic, bounds.y); - } - } else { - tailMap.put(topic, bounds.y); - } - } - - List tailPoints = new ArrayList(); - for (ITopicPart topic : sortTopicPart(tailMap)) - tailPoints.add(topic.getFigure().getBounds().getTopRight() - .getTranslated(MARGIN_WIDTH - lineWidth1, - -MARGIN_HEIGHT + lineWidth1)); - - Point bl = box.getBottomLeft(); - Point br = box.getBottomRight(); - - initPoints(points, headPoints.get(0), bl, br, tailPoints.get(0)); - - calcPointsSouthOrNorth(points, bl, br, headPoints, tailPoints); - } - - private void calcPointsSouthOrNorth(List points, Point crl1, - Point crl2, List headPoints, List tailPoints) { - int leftSize = 2; - if (headPoints.get(0).x > crl1.x) { - for (int i = headPoints.size() - 1; i > 0; i--) { - Point point = headPoints.get(i); - Point firstPoint = points.get(0); - Point secPoint = points.get(1); - if (firstPoint.x == secPoint.x) - break; - - if (!(secPoint.equals(crl1)) && secPoint.x == point.x) { - points.remove(1); - points.add(1, point); - } else { - if (isLeftLine(firstPoint, secPoint, point)) { - points.add(1, point); - leftSize++; - } - } - } - } - for (int i = 1; i < leftSize - 1; i++) { - if (!isLeftLine(points.get(i - 1), points.get(i + 1), - points.get(i))) { - points.remove(i--); - leftSize--; - if (i > 1) - i--; - } - } - - if (tailPoints.get(0).x < crl2.x) { - for (int i = tailPoints.size() - 1; i > 0; i--) { - Point point = tailPoints.get(i); - Point lastPoint = points.get(points.size() - 1); - Point penPoint = points.get(points.size() - 2); - - if (lastPoint.x == penPoint.x) - break; - - if (!penPoint.equals(crl2) && penPoint.x == point.x) { - points.remove(points.size() - 2); - points.add(points.size() - 1, point); - } else { - if (!isLeftLine(penPoint, lastPoint, point)) { - points.add(points.size() - 1, point); - } - } - } - } - for (int i = leftSize + 1; i < points.size() - 1; i++) { - if (isLeftLine(points.get(i - 1), points.get(i + 1), - points.get(i))) { - points.remove(i--); - if (i > leftSize) - i--; - } - } - } - - private void initPoints(List points, Point p1, Point p2, Point p3, - Point p4) { - points.add(p1); - points.add(p2); - points.add(p3); - points.add(p4); - } - - private int calcChildDirection(IBranchPart branch) { - IStructure structure = branch.getBranchPolicy().getStructure(branch); - - if (structure instanceof IBranchStructureExtension) - return ((IBranchStructureExtension) structure) - .getChildTargetOrientation(branch.getParentBranch(), - branch); - - return PositionConstants.NONE; - } - - private List collectTopics(IBoundaryPart boundary) { - List topics = new ArrayList(); - - List branches = boundary.getEnclosingBranches(); - if (!branches.isEmpty()) { - for (IBranchPart branch : branches) { - topics.add(branch.getTopicPart()); - addAllTopics(branch, topics); - } - } else { - IBranchPart branch = boundary.getOwnedBranch(); - topics.add(branch.getTopicPart()); - addAllTopics(branch, topics); - } - - return topics; - } - - private void addAllTopics(IBranchPart branch, List topics) { - for (IBranchPart sub : branch.getSubBranches()) { - topics.add(sub.getTopicPart()); - addAllTopics(sub, topics); - } - - for (IBranchPart callout : branch.getCalloutBranches()) { - topics.add(callout.getTopicPart()); - addAllTopics(callout, topics); - } - - for (IBranchPart summary : branch.getSummaryBranches()) { - topics.add(summary.getTopicPart()); - addAllTopics(summary, topics); - } - } - - private boolean isUpperLine(Point p1, Point p2, Point p3) { - if (p1.y < p3.y) - return false; - - float dx1 = Math.abs(p2.x - p1.x); - float dy1 = Math.abs(p2.y - p1.y); - - float dx2 = Math.abs(p3.x - p1.x); - float dy2 = Math.abs(p3.y - p1.y); - - return dy1 / dx1 < dy2 / dx2; - } - - private boolean isLeftLine(Point p1, Point p2, Point p3) { - if (p1.x < p3.x) - return false; - - float dx1 = Math.abs(p2.x - p1.x); - float dy1 = Math.abs(p2.y - p1.y); - - float dx2 = Math.abs(p3.x - p1.x); - float dy2 = Math.abs(p3.y - p1.y); - - return dx1 / dy1 < dx2 / dy2; - } - - private Set sortTopicPart(Map topicMap) { - HashMap map = new HashMap(); - ValueComparator bvc = new ValueComparator(map); - TreeMap sortedMap = new TreeMap( - bvc); - - map.putAll(topicMap); - sortedMap.putAll(map); - - return sortedMap.keySet(); - } - - private ITopicPart findTopicByValue(Map map, - Integer value) { - for (Entry entry : map.entrySet()) { - if (value == entry.getValue() - || (value != null && value.equals(entry.getValue()))) - return entry.getKey(); - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.ui.branch.IBranchStructureExtension; +import org.xmind.ui.decorations.AbstractBoundaryDecoration; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; + +public class PolygonBoundaryDecoration extends AbstractBoundaryDecoration { + + private class ValueComparator implements Comparator { + + private Map base; + + public ValueComparator(Map base) { + this.base = base; + } + + public int compare(ITopicPart t1, ITopicPart t2) { + if (base.get(t1) > base.get(t2)) + return 1; + return -1; + } + + } + + private IBoundaryPart boundary; + + public PolygonBoundaryDecoration() { + super(); + } + + public PolygonBoundaryDecoration(String id) { + super(id); + } + + public PolygonBoundaryDecoration(IBoundaryPart boundary, String id) { + super(id); + this.boundary = boundary; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + List points = calcPathPoints(box, boundary); + + if (points.size() > 4) { + shape.moveTo(points.get(0)); + for (int i = 1; i < points.size(); i++) + shape.lineTo(points.get(i)); + shape.lineTo(points.get(0)); + shape.close(); + } else { + shape.addRectangle(box); + } + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + Rectangle bounds = figure.getBounds(); + PrecisionPoint p1 = new PrecisionPoint(bounds.x + bounds.width / 2, + bounds.y + bounds.height / 2); + + PrecisionPoint p2 = Geometry.getChopBoxLocation(refX, refY, + getOutlineBox(figure), expansion); + + return calcAnchorLocation(figure, p1, p2); + } + + private PrecisionPoint calcAnchorLocation(IFigure figure, PrecisionPoint p1, + PrecisionPoint p2) { + if (p1.getDistance(p2) < (getLineWidth() == 0 ? 1 : getLineWidth())) + return p2; + + PrecisionPoint p3 = new PrecisionPoint((p1.x + p2.x) / 2, + (p1.y + p2.y) / 2); + if (containsPoint(figure, (float) p3.x, (float) p3.y)) + return calcAnchorLocation(figure, p3, p2); + else + return calcAnchorLocation(figure, p1, p3); + } + + private boolean containsPoint(IFigure figure, float x, float y) { + checkValidation(figure); + GC gc = GraphicsUtils.getAdvanced().getGC(); + gc.setLineWidth(getCheckingLineWidth()); + Path shape = new Path(Display.getCurrent()); + sketch(figure, shape, getOutlineBox(figure), FILL); + boolean ret = shape.contains(x, y, gc, false); + shape.close(); + shape.dispose(); + return ret; + } + + protected List calcPathPoints(Rectangle box, + IBoundaryPart boundary) { + List enclosingBranches = boundary.getEnclosingBranches(); + IBranchPart branch; + if (!enclosingBranches.isEmpty()) + branch = enclosingBranches.get(0); + else + branch = boundary.getOwnedBranch(); + + int childDirection = calcChildDirection(branch); + + List topics = collectTopics(boundary); + + List points = new ArrayList(); + switch (childDirection) { + case PositionConstants.WEST: + collectPointsWestDire(points, topics, box); + break; + case PositionConstants.EAST: + collcetPointsEastDire(points, topics, box); + break; + case PositionConstants.SOUTH: + collectPointsSouthDire(points, topics, box); + break; + case PositionConstants.NORTH: + collectPointsNorthDire(points, topics, box); + break; + } + + return points; + } + + private void collectPointsWestDire(List points, + List topics, Rectangle box) { + int lineWidth1 = getLineWidth(); + int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; + + Map headMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(headMap, bounds.x); + if (t != null) { + if (bounds.y < t.getFigure().getBounds().y) { + headMap.remove(t); + headMap.put(topic, bounds.x); + } + } else { + headMap.put(topic, bounds.x); + } + } + + List headPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(headMap)) + headPoints.add(topic.getFigure().getBounds().getTopLeft() + .getTranslated(-MARGIN_WIDTH + lineWidth2, + -MARGIN_HEIGHT + lineWidth2)); + + Map tailMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(tailMap, bounds.x); + if (t != null) { + if (bounds.bottom() > t.getFigure().getBounds().bottom()) { + tailMap.remove(t); + tailMap.put(topic, bounds.x); + } + } else { + tailMap.put(topic, bounds.x); + } + } + List tailPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(tailMap)) + tailPoints.add(topic.getFigure().getBounds().getBottomLeft() + .getTranslated(-MARGIN_WIDTH + lineWidth2, + MARGIN_HEIGHT - lineWidth2)); + + Point tr = box.getTopRight(); + Point br = box.getBottomRight(); + + initPoints(points, headPoints.get(0), tr, br, tailPoints.get(0)); + + calcPointsWestOrEast(points, tr, br, headPoints, tailPoints); + + } + + private void collcetPointsEastDire(List points, + List topics, Rectangle box) { + int lineWidth1 = getLineWidth(); + int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; + + Map headMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(headMap, -bounds.right()); + if (t != null) { + if (bounds.y < t.getFigure().getBounds().y) { + headMap.remove(t); + headMap.put(topic, -bounds.right()); + } + } else { + headMap.put(topic, -bounds.right()); + } + } + + List headPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(headMap)) + headPoints.add(topic.getFigure().getBounds().getTopRight() + .getTranslated(MARGIN_WIDTH - lineWidth1, + -MARGIN_HEIGHT + lineWidth2)); + + Map tailMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(tailMap, -bounds.right()); + if (t != null) { + if (bounds.bottom() > t.getFigure().getBounds().bottom()) { + tailMap.remove(t); + tailMap.put(topic, -bounds.right()); + } + } else { + tailMap.put(topic, -bounds.right()); + } + } + + List tailPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(tailMap)) + tailPoints.add(topic.getFigure().getBounds().getBottomRight() + .getTranslated(MARGIN_WIDTH - lineWidth1, MARGIN_HEIGHT + - (lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1))); + + Point tl = box.getTopLeft(); + Point bl = box.getBottomLeft(); + + initPoints(points, headPoints.get(0), tl, bl, tailPoints.get(0)); + + calcPointsWestOrEast(points, tl, bl, headPoints, tailPoints); + } + + private void calcPointsWestOrEast(List points, Point crl1, + Point crl2, List headPoints, List tailPoints) { + int upSize = 2; + if (headPoints.get(0).y > crl1.y) { + for (int i = headPoints.size() - 1; i > 0; i--) { + Point point = headPoints.get(i); + Point firstPoint = points.get(0); + Point secPoint = points.get(1); + if (firstPoint.y == secPoint.y && !firstPoint.equals(secPoint)) + break; + + if (!secPoint.equals(crl1) && secPoint.y == point.y) { + points.remove(1); + points.add(1, point); + } else if (isUpperLine(firstPoint, secPoint, point)) { + points.add(1, point); + upSize++; + } + } + } + for (int i = 1; i < upSize - 1; i++) { + if (!isUpperLine(points.get(i - 1), points.get(i + 1), + points.get(i))) { + points.remove(i--); + upSize--; + if (i > 1) + i--; + } + } + + if (tailPoints.get(0).y < crl2.y) { + for (int i = tailPoints.size() - 1; i > 0; i--) { + Point point = tailPoints.get(i); + Point lastPoint = points.get(points.size() - 1); + Point penPoint = points.get(points.size() - 2); + + if (lastPoint.y == penPoint.y) + break; + + if (!penPoint.equals(crl2) && penPoint.y == point.y) { + points.remove(points.size() - 2); + points.add(points.size() - 1, point); + } else if (!isUpperLine(penPoint, lastPoint, point)) { + points.add(points.size() - 1, point); + } + } + } + for (int i = upSize + 1; i < points.size() - 1; i++) { + if (isUpperLine(points.get(i - 1), points.get(i + 1), + points.get(i))) { + points.remove(i--); + if (i > upSize) + i--; + } + } + } + + private void collectPointsSouthDire(List points, + List topics, Rectangle box) { + int lineWidth1 = getLineWidth(); + int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; + + Map headMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(headMap, -bounds.bottom()); + if (t != null) { + if (bounds.x < t.getFigure().getBounds().x) { + headMap.remove(t); + headMap.put(topic, -bounds.bottom()); + } + } else { + headMap.put(topic, -bounds.bottom()); + } + } + + List headPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(headMap)) + headPoints.add(topic.getFigure().getBounds().getBottomLeft() + .getTranslated(-MARGIN_WIDTH + lineWidth2, + MARGIN_HEIGHT - lineWidth2)); + + Map tailMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(tailMap, -bounds.bottom()); + if (t != null) { + if (bounds.right() > t.getFigure().getBounds().right()) { + tailMap.remove(t); + tailMap.put(topic, -bounds.bottom()); + } + } else { + tailMap.put(topic, -bounds.bottom()); + } + } + + List tailPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(tailMap)) + tailPoints.add(topic.getFigure().getBounds().getBottomRight() + .getTranslated(MARGIN_WIDTH - lineWidth1, + MARGIN_HEIGHT - lineWidth2)); + + Point tl = box.getTopLeft(); + Point tr = box.getTopRight(); + + initPoints(points, headPoints.get(0), tl, tr, tailPoints.get(0)); + + calcPointsSouthOrNorth(points, tl, tr, headPoints, tailPoints); + } + + private void collectPointsNorthDire(List points, + List topics, Rectangle box) { + int lineWidth1 = getLineWidth(); + int lineWidth2 = lineWidth1 > 1 ? lineWidth1 - 1 : lineWidth1; + Map headMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(headMap, bounds.y); + if (t != null) { + if (bounds.x < t.getFigure().getBounds().x) { + headMap.remove(t); + headMap.put(topic, bounds.y); + } + } else { + headMap.put(topic, bounds.y); + } + } + + List headPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(headMap)) + headPoints.add(topic.getFigure().getBounds().getTopLeft() + .getTranslated(-MARGIN_WIDTH + lineWidth2, + -MARGIN_HEIGHT + lineWidth1)); + + Map tailMap = new HashMap(); + for (ITopicPart topic : topics) { + Rectangle bounds = topic.getFigure().getBounds(); + ITopicPart t = findTopicByValue(tailMap, bounds.y); + if (t != null) { + if (bounds.right() > t.getFigure().getBounds().right()) { + tailMap.remove(t); + tailMap.put(topic, bounds.y); + } + } else { + tailMap.put(topic, bounds.y); + } + } + + List tailPoints = new ArrayList(); + for (ITopicPart topic : sortTopicPart(tailMap)) + tailPoints.add(topic.getFigure().getBounds().getTopRight() + .getTranslated(MARGIN_WIDTH - lineWidth1, + -MARGIN_HEIGHT + lineWidth1)); + + Point bl = box.getBottomLeft(); + Point br = box.getBottomRight(); + + initPoints(points, headPoints.get(0), bl, br, tailPoints.get(0)); + + calcPointsSouthOrNorth(points, bl, br, headPoints, tailPoints); + } + + private void calcPointsSouthOrNorth(List points, Point crl1, + Point crl2, List headPoints, List tailPoints) { + int leftSize = 2; + if (headPoints.get(0).x > crl1.x) { + for (int i = headPoints.size() - 1; i > 0; i--) { + Point point = headPoints.get(i); + Point firstPoint = points.get(0); + Point secPoint = points.get(1); + if (firstPoint.x == secPoint.x) + break; + + if (!(secPoint.equals(crl1)) && secPoint.x == point.x) { + points.remove(1); + points.add(1, point); + } else { + if (isLeftLine(firstPoint, secPoint, point)) { + points.add(1, point); + leftSize++; + } + } + } + } + for (int i = 1; i < leftSize - 1; i++) { + if (!isLeftLine(points.get(i - 1), points.get(i + 1), + points.get(i))) { + points.remove(i--); + leftSize--; + if (i > 1) + i--; + } + } + + if (tailPoints.get(0).x < crl2.x) { + for (int i = tailPoints.size() - 1; i > 0; i--) { + Point point = tailPoints.get(i); + Point lastPoint = points.get(points.size() - 1); + Point penPoint = points.get(points.size() - 2); + + if (lastPoint.x == penPoint.x) + break; + + if (!penPoint.equals(crl2) && penPoint.x == point.x) { + points.remove(points.size() - 2); + points.add(points.size() - 1, point); + } else { + if (!isLeftLine(penPoint, lastPoint, point)) { + points.add(points.size() - 1, point); + } + } + } + } + for (int i = leftSize + 1; i < points.size() - 1; i++) { + if (isLeftLine(points.get(i - 1), points.get(i + 1), + points.get(i))) { + points.remove(i--); + if (i > leftSize) + i--; + } + } + } + + private void initPoints(List points, Point p1, Point p2, Point p3, + Point p4) { + points.add(p1); + points.add(p2); + points.add(p3); + points.add(p4); + } + + private int calcChildDirection(IBranchPart branch) { + IStructure structure = branch.getBranchPolicy().getStructure(branch); + + if (structure instanceof IBranchStructureExtension) + return ((IBranchStructureExtension) structure) + .getChildTargetOrientation(branch.getParentBranch(), + branch); + + return PositionConstants.NONE; + } + + private List collectTopics(IBoundaryPart boundary) { + List topics = new ArrayList(); + + List branches = boundary.getEnclosingBranches(); + if (!branches.isEmpty()) { + for (IBranchPart branch : branches) { + topics.add(branch.getTopicPart()); + addAllTopics(branch, topics); + } + } else { + IBranchPart branch = boundary.getOwnedBranch(); + topics.add(branch.getTopicPart()); + addAllTopics(branch, topics); + } + + return topics; + } + + private void addAllTopics(IBranchPart branch, List topics) { + for (IBranchPart sub : branch.getSubBranches()) { + topics.add(sub.getTopicPart()); + addAllTopics(sub, topics); + } + + for (IBranchPart callout : branch.getCalloutBranches()) { + topics.add(callout.getTopicPart()); + addAllTopics(callout, topics); + } + + for (IBranchPart summary : branch.getSummaryBranches()) { + topics.add(summary.getTopicPart()); + addAllTopics(summary, topics); + } + } + + private boolean isUpperLine(Point p1, Point p2, Point p3) { + if (p1.y < p3.y) + return false; + + float dx1 = Math.abs(p2.x - p1.x); + float dy1 = Math.abs(p2.y - p1.y); + + float dx2 = Math.abs(p3.x - p1.x); + float dy2 = Math.abs(p3.y - p1.y); + + return dy1 / dx1 < dy2 / dx2; + } + + private boolean isLeftLine(Point p1, Point p2, Point p3) { + if (p1.x < p3.x) + return false; + + float dx1 = Math.abs(p2.x - p1.x); + float dy1 = Math.abs(p2.y - p1.y); + + float dx2 = Math.abs(p3.x - p1.x); + float dy2 = Math.abs(p3.y - p1.y); + + return dx1 / dy1 < dx2 / dy2; + } + + private Set sortTopicPart(Map topicMap) { + HashMap map = new HashMap(); + ValueComparator bvc = new ValueComparator(map); + TreeMap sortedMap = new TreeMap( + bvc); + + map.putAll(topicMap); + sortedMap.putAll(map); + + return sortedMap.keySet(); + } + + private ITopicPart findTopicByValue(Map map, + Integer value) { + for (Entry entry : map.entrySet()) { + if (value == entry.getValue() + || (value != null && value.equals(entry.getValue()))) + return entry.getKey(); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecorationFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecorationFactory.java index ccaf69bc9..c32c8fab6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecorationFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/PolygonBoundaryDecorationFactory.java @@ -1,14 +1,14 @@ -package org.xmind.ui.internal.decorations; - -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.mindmap.IBoundaryPart; - -public class PolygonBoundaryDecorationFactory implements IDecorationFactory { - - public IDecoration createDecoration(String id, IGraphicalPart part) { - return new PolygonBoundaryDecoration((IBoundaryPart) part, id); - } - -} +package org.xmind.ui.internal.decorations; + +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.mindmap.IBoundaryPart; + +public class PolygonBoundaryDecorationFactory implements IDecorationFactory { + + public IDecoration createDecoration(String id, IGraphicalPart part) { + return new PolygonBoundaryDecoration((IBoundaryPart) part, id); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RectangleBalloonCalloutBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RectangleBalloonCalloutBranchConnection.java index 8645bc60d..6081a094a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RectangleBalloonCalloutBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RectangleBalloonCalloutBranchConnection.java @@ -1,184 +1,184 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; - -public class RectangleBalloonCalloutBranchConnection - extends AbstractCalloutBranchConnection { - - public static final int OFFSET = 10; - - public RectangleBalloonCalloutBranchConnection() { - super(); - } - - public RectangleBalloonCalloutBranchConnection(String id) { - super(id); - } - - @Override - protected void route(IFigure figure, Path shape) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - - Rectangle targetRect = getTargetAnchor().getOwner().getBounds(); - targetRect = getOutlineBox(targetRect); - - if (getSourceAnchor() != null) { - PrecisionPoint rp = getSourceAnchor().getReferencePoint(); - p2 = Geometry.getChopBoxLocation(rp.x, rp.y, targetRect, 0); - } - - int side = Geometry.getSide(p2.x, p2.y, targetRect); - shape.moveTo(p2); - - if (side == Geometry.SIDE_ONE) { - shape.lineTo(p1); - double delta = p2.x - targetRect.x - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); - shape.lineTo(p3); - shape.lineTo(targetRect.getTopLeft()); - } else { - PrecisionPoint p3 = new PrecisionPoint(targetRect.x, - p2.y - delta); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_TWO) { - double delta = targetRect.getTopRight().x - p2.x - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getTopRight()); - } else { - shape.lineTo(p1); - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getTopRight().x, p2.y - delta); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_THREE) { - double delta = p2.y - targetRect.getTopRight().y - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getTopRight().x, p2.y - OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getTopRight()); - } else { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getTopRight().x + delta, - targetRect.getTopRight().y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_FOUR) { - double delta = targetRect.getBottomRight().y - p2.y - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getTopRight().x, p2.y + OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getBottomRight()); - } else { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getBottomRight().x + delta, - targetRect.getBottomRight().y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_FIVE) { - double delta = targetRect.getBottomRight().x - p2.x - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getBottomRight()); - } else { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getBottomRight().x, - targetRect.getBottomRight().y + delta); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_SIX) { - double delta = p2.x - targetRect.getBottomLeft().x - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getBottomLeft()); - } else { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getBottomLeft().x, - targetRect.getBottomLeft().y + delta); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_SEVEN) { - double delta = targetRect.getBottomLeft().y - p2.y - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y + OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(targetRect.getBottomLeft()); - } else { - PrecisionPoint p3 = new PrecisionPoint( - targetRect.getBottomLeft().x - delta, - targetRect.getBottomLeft().y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(targetRect.getTopLeft()); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_EIGHT) { - shape.lineTo(p1); - double delta = p2.y - targetRect.y - OFFSET; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y - OFFSET); - shape.lineTo(p3); - shape.lineTo(targetRect.getTopLeft()); - } else { - PrecisionPoint p3 = new PrecisionPoint(targetRect.x - delta, - targetRect.y); - shape.lineTo(p3); - } - shape.lineTo(targetRect.getTopRight()); - shape.lineTo(targetRect.getBottomRight()); - shape.lineTo(targetRect.getBottomLeft()); - shape.lineTo(p2); - } - - shape.close(); - - } -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; + +public class RectangleBalloonCalloutBranchConnection + extends AbstractCalloutBranchConnection { + + public static final int OFFSET = 10; + + public RectangleBalloonCalloutBranchConnection() { + super(); + } + + public RectangleBalloonCalloutBranchConnection(String id) { + super(id); + } + + @Override + protected void route(IFigure figure, Path shape) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + + Rectangle targetRect = getTargetAnchor().getOwner().getBounds(); + targetRect = getOutlineBox(targetRect); + + if (getSourceAnchor() != null) { + PrecisionPoint rp = getSourceAnchor().getReferencePoint(); + p2 = Geometry.getChopBoxLocation(rp.x, rp.y, targetRect, 0); + } + + int side = Geometry.getSide(p2.x, p2.y, targetRect); + shape.moveTo(p2); + + if (side == Geometry.SIDE_ONE) { + shape.lineTo(p1); + double delta = p2.x - targetRect.x - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); + shape.lineTo(p3); + shape.lineTo(targetRect.getTopLeft()); + } else { + PrecisionPoint p3 = new PrecisionPoint(targetRect.x, + p2.y - delta); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_TWO) { + double delta = targetRect.getTopRight().x - p2.x - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getTopRight()); + } else { + shape.lineTo(p1); + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getTopRight().x, p2.y - delta); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_THREE) { + double delta = p2.y - targetRect.getTopRight().y - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getTopRight().x, p2.y - OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getTopRight()); + } else { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getTopRight().x + delta, + targetRect.getTopRight().y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_FOUR) { + double delta = targetRect.getBottomRight().y - p2.y - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getTopRight().x, p2.y + OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getBottomRight()); + } else { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getBottomRight().x + delta, + targetRect.getBottomRight().y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_FIVE) { + double delta = targetRect.getBottomRight().x - p2.x - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getBottomRight()); + } else { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getBottomRight().x, + targetRect.getBottomRight().y + delta); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_SIX) { + double delta = p2.x - targetRect.getBottomLeft().x - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getBottomLeft()); + } else { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getBottomLeft().x, + targetRect.getBottomLeft().y + delta); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_SEVEN) { + double delta = targetRect.getBottomLeft().y - p2.y - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y + OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(targetRect.getBottomLeft()); + } else { + PrecisionPoint p3 = new PrecisionPoint( + targetRect.getBottomLeft().x - delta, + targetRect.getBottomLeft().y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(targetRect.getTopLeft()); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_EIGHT) { + shape.lineTo(p1); + double delta = p2.y - targetRect.y - OFFSET; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y - OFFSET); + shape.lineTo(p3); + shape.lineTo(targetRect.getTopLeft()); + } else { + PrecisionPoint p3 = new PrecisionPoint(targetRect.x - delta, + targetRect.y); + shape.lineTo(p3); + } + shape.lineTo(targetRect.getTopRight()); + shape.lineTo(targetRect.getBottomRight()); + shape.lineTo(targetRect.getBottomLeft()); + shape.lineTo(p2); + } + + shape.close(); + + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecoration.java index e182c4964..4808c52ec 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecoration.java @@ -1,139 +1,139 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.mindmap.IBoundaryPart; - -public class RoundedPolygonBoundaryDecoration extends PolygonBoundaryDecoration - implements ICorneredDecoration { - - private static final float CORNER_CONTROL_RATIO = 0.447715f; - - private IBoundaryPart boundary; - - private int cornerSize = 0; - - public RoundedPolygonBoundaryDecoration() { - super(); - } - - public RoundedPolygonBoundaryDecoration(IBoundaryPart boundary, String id) { - super(id); - this.boundary = boundary; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - List points = calcPathPoints(box, boundary); - - int c = getAppliedCornerSize(); - - if (points.size() > 4) { - if (c == 0) { - shape.moveTo(points.get(0)); - for (int i = 1; i < points.size(); i++) - shape.lineTo(points.get(i)); - shape.lineTo(points.get(0)); - shape.close(); - } else { - Point p0 = calcRoundedPoint(points.get(0), - points.get(points.size() - 1), c); - Point p1 = null; - Point c1, c2; - shape.moveTo(p0); - for (int i = 0; i < points.size() - 1; i++) { - p1 = calcRoundedPoint(points.get(i), points.get(i + 1), c); - c1 = calcControlPoint(p0, points.get(i)); - c2 = calcControlPoint(p1, points.get(i)); -// shape.lineTo(p1); - shape.cubicTo(c1, c2, p1); - p0 = calcRoundedPoint(points.get(i + 1), points.get(i), c); - shape.lineTo(p0); - } - p1 = calcRoundedPoint(points.get(points.size() - 1), - points.get(0), c); -// shape.lineTo(p1); - c1 = calcControlPoint(p0, points.get(points.size() - 1)); - c2 = calcControlPoint(p1, points.get(points.size() - 1)); - shape.cubicTo(c1, c2, p1); - p0 = calcRoundedPoint(points.get(0), - points.get(points.size() - 1), c); - shape.lineTo(p0); - shape.close(); - } - } else { - if (c == 0) { - shape.addRectangle(box); - } else { - shape.addRoundedRectangle(box, c); - } - } - } - - private Point calcRoundedPoint(Point p1, Point p2, int corner) { - int dx = p2.x - p1.x; - int dy = p2.y - p1.y; - - if (dx == 0) { - if (dy > 0) - return p1.getTranslated(0, corner); - return p1.getTranslated(0, -corner); - } else if (dy == 0) { - if (dx > 0) - return p1.getTranslated(corner, 0); - return p1.getTranslated(-corner, 0); - } else { - double l = p1.getDistance(p2); - double x = dx / l * corner; - double y = dy / l * corner; - return p1.getTranslated(x, y); - } - } - - private Point calcControlPoint(Point p1, Point p2) { - double dx = p2.x - p1.x; - double dy = p2.y - p1.y; - - return p1.getTranslated(dx * CORNER_CONTROL_RATIO, - dy * CORNER_CONTROL_RATIO); - } - - public int getCornerSize() { - return cornerSize; - } - - private int getAppliedCornerSize() { - return getCornerSize(); - } - - public void setCornerSize(IFigure figure, int cornerSize) { - if (cornerSize == this.cornerSize) - return; - - this.cornerSize = cornerSize; - invalidate(); - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.mindmap.IBoundaryPart; + +public class RoundedPolygonBoundaryDecoration extends PolygonBoundaryDecoration + implements ICorneredDecoration { + + private static final float CORNER_CONTROL_RATIO = 0.447715f; + + private IBoundaryPart boundary; + + private int cornerSize = 0; + + public RoundedPolygonBoundaryDecoration() { + super(); + } + + public RoundedPolygonBoundaryDecoration(IBoundaryPart boundary, String id) { + super(id); + this.boundary = boundary; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + List points = calcPathPoints(box, boundary); + + int c = getAppliedCornerSize(); + + if (points.size() > 4) { + if (c == 0) { + shape.moveTo(points.get(0)); + for (int i = 1; i < points.size(); i++) + shape.lineTo(points.get(i)); + shape.lineTo(points.get(0)); + shape.close(); + } else { + Point p0 = calcRoundedPoint(points.get(0), + points.get(points.size() - 1), c); + Point p1 = null; + Point c1, c2; + shape.moveTo(p0); + for (int i = 0; i < points.size() - 1; i++) { + p1 = calcRoundedPoint(points.get(i), points.get(i + 1), c); + c1 = calcControlPoint(p0, points.get(i)); + c2 = calcControlPoint(p1, points.get(i)); +// shape.lineTo(p1); + shape.cubicTo(c1, c2, p1); + p0 = calcRoundedPoint(points.get(i + 1), points.get(i), c); + shape.lineTo(p0); + } + p1 = calcRoundedPoint(points.get(points.size() - 1), + points.get(0), c); +// shape.lineTo(p1); + c1 = calcControlPoint(p0, points.get(points.size() - 1)); + c2 = calcControlPoint(p1, points.get(points.size() - 1)); + shape.cubicTo(c1, c2, p1); + p0 = calcRoundedPoint(points.get(0), + points.get(points.size() - 1), c); + shape.lineTo(p0); + shape.close(); + } + } else { + if (c == 0) { + shape.addRectangle(box); + } else { + shape.addRoundedRectangle(box, c); + } + } + } + + private Point calcRoundedPoint(Point p1, Point p2, int corner) { + int dx = p2.x - p1.x; + int dy = p2.y - p1.y; + + if (dx == 0) { + if (dy > 0) + return p1.getTranslated(0, corner); + return p1.getTranslated(0, -corner); + } else if (dy == 0) { + if (dx > 0) + return p1.getTranslated(corner, 0); + return p1.getTranslated(-corner, 0); + } else { + double l = p1.getDistance(p2); + double x = dx / l * corner; + double y = dy / l * corner; + return p1.getTranslated(x, y); + } + } + + private Point calcControlPoint(Point p1, Point p2) { + double dx = p2.x - p1.x; + double dy = p2.y - p1.y; + + return p1.getTranslated(dx * CORNER_CONTROL_RATIO, + dy * CORNER_CONTROL_RATIO); + } + + public int getCornerSize() { + return cornerSize; + } + + private int getAppliedCornerSize() { + return getCornerSize(); + } + + public void setCornerSize(IFigure figure, int cornerSize) { + if (cornerSize == this.cornerSize) + return; + + this.cornerSize = cornerSize; + invalidate(); + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecorationFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecorationFactory.java index 8992e0829..7a92d24f8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecorationFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedPolygonBoundaryDecorationFactory.java @@ -1,15 +1,15 @@ -package org.xmind.ui.internal.decorations; - -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.mindmap.IBoundaryPart; - -public class RoundedPolygonBoundaryDecorationFactory - implements IDecorationFactory { - - public IDecoration createDecoration(String id, IGraphicalPart part) { - return new RoundedPolygonBoundaryDecoration((IBoundaryPart) part, id); - } - -} +package org.xmind.ui.internal.decorations; + +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.mindmap.IBoundaryPart; + +public class RoundedPolygonBoundaryDecorationFactory + implements IDecorationFactory { + + public IDecoration createDecoration(String id, IGraphicalPart part) { + return new RoundedPolygonBoundaryDecoration((IBoundaryPart) part, id); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectBalloonCalloutBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectBalloonCalloutBranchConnection.java index 7e6ae6d1d..10acfaa96 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectBalloonCalloutBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectBalloonCalloutBranchConnection.java @@ -1,262 +1,262 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; - -public class RoundedRectBalloonCalloutBranchConnection - extends AbstractCalloutBranchConnection implements ICorneredDecoration { - - public static final int OFFSET = 10; - - private int cornerSize = 0; - - public RoundedRectBalloonCalloutBranchConnection() { - super(); - } - - public RoundedRectBalloonCalloutBranchConnection(String id) { - super(id); - } - - @Override - protected void route(IFigure figure, Path shape) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - - int corner = getCornerSize(); - - Rectangle r = getTargetAnchor().getOwner().getBounds(); - r = getOutlineBox(r); - - if (getSourceAnchor() != null) { - PrecisionPoint rp = getSourceAnchor().getReferencePoint(); - p2 = Geometry.getChopBoxLocation(rp.x, rp.y, r, 0); - } - - int side = Geometry.getSide(p2.x, p2.y, r); - shape.moveTo(p2); - - if (side == Geometry.SIDE_ONE) { - shape.lineTo(p1); - double delta = p2.x - r.x - OFFSET - corner; - if (delta >= 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, r.y); - shape.lineTo(p3); - shape.lineTo(r.x + corner, r.y); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); - } else { - PrecisionPoint p3 = new PrecisionPoint(r.x, r.y - delta); - shape.lineTo(p3); - } - shape.lineTo(r.x, r.y + r.height - corner); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, 180, 90); - shape.lineTo(r.x + r.width - corner, r.y + r.height); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, - 90); - shape.lineTo(r.x + r.width, r.y + corner); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 0, 90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_TWO) { - shape.lineTo(p1); - double delta = r.getTopRight().x - p2.x - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, r.y); - shape.lineTo(p3); - shape.lineTo(r.x + r.width - corner, r.y); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 90, -90); - } else { - PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, - p2.y - delta); - shape.lineTo(p3); - } - shape.lineTo(r.getTopRight().x, r.y + r.height - corner); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, - -90); - shape.lineTo(r.x + corner, r.y + r.height); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, -90, -90); - shape.lineTo(r.x, r.y + corner); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_THREE) { - double delta = p2.y - r.getTopRight().y - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, - p2.y - OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(r.x + r.width, r.y + corner); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 0, 90); - } else { - PrecisionPoint p3 = new PrecisionPoint( - r.getTopRight().x + delta, r.y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(r.x + corner, r.y); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); - shape.lineTo(r.x, r.y + r.height - corner); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, 180, 90); - shape.lineTo(r.x + r.width - corner, r.y + r.height); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, - 90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_FOUR) { - double delta = r.getBottomRight().y - p2.y - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, - p2.y + OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(r.x + r.width, r.y + r.height - corner); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, - -90); - } else { - PrecisionPoint p3 = new PrecisionPoint( - r.getBottomRight().x + delta, r.getBottomRight().y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(r.x + corner, r.y + r.height); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, -90, -90); - shape.lineTo(r.x, r.y + corner); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); - shape.lineTo(r.x + r.width - corner, r.y); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 90, -90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_FIVE) { - double delta = r.getBottomRight().x - p2.x - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(r.x + r.width - corner, r.y + r.height); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, - -90, 90); - } else { - PrecisionPoint p3 = new PrecisionPoint(r.getBottomRight().x, - r.getBottomRight().y + delta); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(r.x + r.width, r.y + corner); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 0, 90); - shape.lineTo(r.x + corner, r.y); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); - shape.lineTo(r.x, r.y + r.height - corner); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, 180, 90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_SIX) { - double delta = p2.x - r.getBottomLeft().x - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(r.x + corner, r.y + r.height); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, -90, -90); - } else { - PrecisionPoint p3 = new PrecisionPoint(r.getBottomLeft().x, - r.getBottomLeft().y + delta); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(r.x, r.y + corner); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); - shape.lineTo(r.x + r.width - corner, r.y); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 90, -90); - shape.lineTo(r.getTopRight().x, r.y + r.height - corner); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, - -90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_SEVEN) { - double delta = r.getBottomLeft().y - p2.y - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y + OFFSET); - shape.lineTo(p1); - shape.lineTo(p3); - shape.lineTo(r.x, r.y + r.height - corner); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, 180, 90); - } else { - PrecisionPoint p3 = new PrecisionPoint( - r.getBottomLeft().x - delta, r.getBottomLeft().y); - shape.lineTo(p1); - shape.lineTo(p3); - } - shape.lineTo(r.x + r.width - corner, r.y + r.height); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, - 90); - shape.lineTo(r.x + r.width, r.y + corner); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 0, 90); - shape.lineTo(r.x + corner, r.y); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); - shape.lineTo(p2); - } else if (side == Geometry.SIDE_EIGHT) { - shape.lineTo(p1); - double delta = p2.y - r.y - OFFSET - corner; - if (delta > 0) { - PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y - OFFSET); - shape.lineTo(p3); - shape.lineTo(r.x, r.y + corner); - shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); - } else { - PrecisionPoint p3 = new PrecisionPoint(r.x - delta, r.y); - shape.lineTo(p3); - } - shape.lineTo(r.x + r.width - corner, r.y); - shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, - 2 * corner, 90, -90); - - shape.lineTo(r.getTopRight().x, r.y + r.height - corner); - shape.addArc(r.x + r.width - 2 * corner, - r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, - -90); - shape.lineTo(r.x + corner, r.y + r.height); - shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, - 2 * corner, -90, -90); - shape.lineTo(p2); - } - shape.close(); - - } - - public int getCornerSize() { - return cornerSize; - } - - public void setCornerSize(IFigure figure, int cornerSize) { - if (cornerSize == this.cornerSize) - return; - - this.cornerSize = cornerSize; - invalidate(); - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; + +public class RoundedRectBalloonCalloutBranchConnection + extends AbstractCalloutBranchConnection implements ICorneredDecoration { + + public static final int OFFSET = 10; + + private int cornerSize = 0; + + public RoundedRectBalloonCalloutBranchConnection() { + super(); + } + + public RoundedRectBalloonCalloutBranchConnection(String id) { + super(id); + } + + @Override + protected void route(IFigure figure, Path shape) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + + int corner = getCornerSize(); + + Rectangle r = getTargetAnchor().getOwner().getBounds(); + r = getOutlineBox(r); + + if (getSourceAnchor() != null) { + PrecisionPoint rp = getSourceAnchor().getReferencePoint(); + p2 = Geometry.getChopBoxLocation(rp.x, rp.y, r, 0); + } + + int side = Geometry.getSide(p2.x, p2.y, r); + shape.moveTo(p2); + + if (side == Geometry.SIDE_ONE) { + shape.lineTo(p1); + double delta = p2.x - r.x - OFFSET - corner; + if (delta >= 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, r.y); + shape.lineTo(p3); + shape.lineTo(r.x + corner, r.y); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); + } else { + PrecisionPoint p3 = new PrecisionPoint(r.x, r.y - delta); + shape.lineTo(p3); + } + shape.lineTo(r.x, r.y + r.height - corner); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, 180, 90); + shape.lineTo(r.x + r.width - corner, r.y + r.height); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, + 90); + shape.lineTo(r.x + r.width, r.y + corner); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 0, 90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_TWO) { + shape.lineTo(p1); + double delta = r.getTopRight().x - p2.x - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, r.y); + shape.lineTo(p3); + shape.lineTo(r.x + r.width - corner, r.y); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 90, -90); + } else { + PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, + p2.y - delta); + shape.lineTo(p3); + } + shape.lineTo(r.getTopRight().x, r.y + r.height - corner); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, + -90); + shape.lineTo(r.x + corner, r.y + r.height); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, -90, -90); + shape.lineTo(r.x, r.y + corner); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_THREE) { + double delta = p2.y - r.getTopRight().y - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, + p2.y - OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(r.x + r.width, r.y + corner); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 0, 90); + } else { + PrecisionPoint p3 = new PrecisionPoint( + r.getTopRight().x + delta, r.y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(r.x + corner, r.y); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); + shape.lineTo(r.x, r.y + r.height - corner); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, 180, 90); + shape.lineTo(r.x + r.width - corner, r.y + r.height); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, + 90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_FOUR) { + double delta = r.getBottomRight().y - p2.y - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, + p2.y + OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(r.x + r.width, r.y + r.height - corner); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, + -90); + } else { + PrecisionPoint p3 = new PrecisionPoint( + r.getBottomRight().x + delta, r.getBottomRight().y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(r.x + corner, r.y + r.height); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, -90, -90); + shape.lineTo(r.x, r.y + corner); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); + shape.lineTo(r.x + r.width - corner, r.y); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 90, -90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_FIVE) { + double delta = r.getBottomRight().x - p2.x - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(r.x + r.width - corner, r.y + r.height); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, + -90, 90); + } else { + PrecisionPoint p3 = new PrecisionPoint(r.getBottomRight().x, + r.getBottomRight().y + delta); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(r.x + r.width, r.y + corner); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 0, 90); + shape.lineTo(r.x + corner, r.y); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); + shape.lineTo(r.x, r.y + r.height - corner); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, 180, 90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_SIX) { + double delta = p2.x - r.getBottomLeft().x - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(r.x + corner, r.y + r.height); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, -90, -90); + } else { + PrecisionPoint p3 = new PrecisionPoint(r.getBottomLeft().x, + r.getBottomLeft().y + delta); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(r.x, r.y + corner); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); + shape.lineTo(r.x + r.width - corner, r.y); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 90, -90); + shape.lineTo(r.getTopRight().x, r.y + r.height - corner); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, + -90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_SEVEN) { + double delta = r.getBottomLeft().y - p2.y - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y + OFFSET); + shape.lineTo(p1); + shape.lineTo(p3); + shape.lineTo(r.x, r.y + r.height - corner); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, 180, 90); + } else { + PrecisionPoint p3 = new PrecisionPoint( + r.getBottomLeft().x - delta, r.getBottomLeft().y); + shape.lineTo(p1); + shape.lineTo(p3); + } + shape.lineTo(r.x + r.width - corner, r.y + r.height); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, + 90); + shape.lineTo(r.x + r.width, r.y + corner); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 0, 90); + shape.lineTo(r.x + corner, r.y); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); + shape.lineTo(p2); + } else if (side == Geometry.SIDE_EIGHT) { + shape.lineTo(p1); + double delta = p2.y - r.y - OFFSET - corner; + if (delta > 0) { + PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y - OFFSET); + shape.lineTo(p3); + shape.lineTo(r.x, r.y + corner); + shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); + } else { + PrecisionPoint p3 = new PrecisionPoint(r.x - delta, r.y); + shape.lineTo(p3); + } + shape.lineTo(r.x + r.width - corner, r.y); + shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, + 2 * corner, 90, -90); + + shape.lineTo(r.getTopRight().x, r.y + r.height - corner); + shape.addArc(r.x + r.width - 2 * corner, + r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, + -90); + shape.lineTo(r.x + corner, r.y + r.height); + shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, + 2 * corner, -90, -90); + shape.lineTo(p2); + } + shape.close(); + + } + + public int getCornerSize() { + return cornerSize; + } + + public void setCornerSize(IFigure figure, int cornerSize) { + if (cornerSize == this.cornerSize) + return; + + this.cornerSize = cornerSize; + invalidate(); + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectCalloutTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectCalloutTopicDecoration.java index 28181b271..7d02d461f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectCalloutTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/RoundedRectCalloutTopicDecoration.java @@ -1,145 +1,145 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; - -public class RoundedRectCalloutTopicDecoration extends AbstractTopicDecoration - implements ICorneredDecoration { - - private static final double M = 1 - Math.sqrt(2) / 2; - - private static final float X = 0.2f; - - private int cornerSize = 0; - - public RoundedRectCalloutTopicDecoration() { - } - - public RoundedRectCalloutTopicDecoration(String id) { - super(id); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - float x = box.x; - float y = box.y; - float width = box.width; - float height = box.height; - - float tailHeight = getTailHeight( - figure.getBounds().height - figure.getInsets().getHeight()); - height -= tailHeight; - - float r = x + width; - float b = y + height; - float x0 = x + width / 2; - float y0 = y + height / 2; - float corner = getAppliedCornerSize(); - - float x1 = Math.min(x + corner, x0); - shape.moveTo(x1, y); - - float y1 = Math.min(y + corner, y0); - float cx1 = x + (x1 - x) / 4; - float cy1 = y + (y1 - y) / 4; - shape.cubicTo(cx1, y, x, cy1, x, y1); - - float y2 = Math.max(b - corner, y0); - shape.lineTo(x, y2); - - float cy2 = b - (b - y2) / 4; - shape.cubicTo(x, cy2, cx1, b, x1, b); - - shape.lineTo(x, b + tailHeight); - shape.lineTo(x + width * X, b); - - float x2 = Math.max(r - corner, x0); - shape.lineTo(x2, b); - - float cx2 = r - (r - x2) / 4; - shape.cubicTo(cx2, b, r, cy2, r, y2); - - shape.lineTo(r, y1); - - shape.cubicTo(r, cy1, cx2, y, x2, y); - -// float y1 = Math.min(y + corner, y0); -// shape.moveTo(x, y1); -// -// float x1 = Math.min(x + corner, x0); -// float cx1 = x + (x1 - x) / 4; -// float cy1 = y + (y1 - y) / 4; -// shape.cubicTo(x, cy1, cx1, y, x1, y); -// -// float x2 = Math.max(r - corner, x0); -// shape.lineTo(x2, y); -// -// float cx2 = r - (r - x2) / 4; -// shape.cubicTo(cx2, y, r, cy1, r, y1); -// -// float y2 = Math.max(b - corner, y0); -// shape.lineTo(r, y2); -// -// float cy2 = b - (b - y2) / 4; -// shape.cubicTo(r, cy2, cx2, b, x2, b); -// -// shape.lineTo(x + width * X, b); -// shape.lineTo(x, b + tailHeight); -// shape.lineTo(x1, b); -// -// shape.cubicTo(cx1, b, x, cy2, x, y2); - - shape.close(); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - int c = (int) (M * getAppliedCornerSize()) + getLineWidth(); - Insets ins = super.getPreferredInsets(figure, width, height); - ins = Geometry.union(ins, c, c, c, c); - ins.bottom += getTailHeight(height); - return ins; - } - - private int getTailHeight(int clientHeight) { - return clientHeight / 3; - } - - public int getCornerSize() { - return cornerSize; - } - - protected int getAppliedCornerSize() { - return getCornerSize();// * getLineWidth(); - } - - public void setCornerSize(IFigure figure, int cornerSize) { - if (cornerSize == this.cornerSize) - return; - - this.cornerSize = cornerSize; - invalidate(); - if (figure != null) { - figure.revalidate(); - figure.repaint(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; + +public class RoundedRectCalloutTopicDecoration extends AbstractTopicDecoration + implements ICorneredDecoration { + + private static final double M = 1 - Math.sqrt(2) / 2; + + private static final float X = 0.2f; + + private int cornerSize = 0; + + public RoundedRectCalloutTopicDecoration() { + } + + public RoundedRectCalloutTopicDecoration(String id) { + super(id); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + float x = box.x; + float y = box.y; + float width = box.width; + float height = box.height; + + float tailHeight = getTailHeight( + figure.getBounds().height - figure.getInsets().getHeight()); + height -= tailHeight; + + float r = x + width; + float b = y + height; + float x0 = x + width / 2; + float y0 = y + height / 2; + float corner = getAppliedCornerSize(); + + float x1 = Math.min(x + corner, x0); + shape.moveTo(x1, y); + + float y1 = Math.min(y + corner, y0); + float cx1 = x + (x1 - x) / 4; + float cy1 = y + (y1 - y) / 4; + shape.cubicTo(cx1, y, x, cy1, x, y1); + + float y2 = Math.max(b - corner, y0); + shape.lineTo(x, y2); + + float cy2 = b - (b - y2) / 4; + shape.cubicTo(x, cy2, cx1, b, x1, b); + + shape.lineTo(x, b + tailHeight); + shape.lineTo(x + width * X, b); + + float x2 = Math.max(r - corner, x0); + shape.lineTo(x2, b); + + float cx2 = r - (r - x2) / 4; + shape.cubicTo(cx2, b, r, cy2, r, y2); + + shape.lineTo(r, y1); + + shape.cubicTo(r, cy1, cx2, y, x2, y); + +// float y1 = Math.min(y + corner, y0); +// shape.moveTo(x, y1); +// +// float x1 = Math.min(x + corner, x0); +// float cx1 = x + (x1 - x) / 4; +// float cy1 = y + (y1 - y) / 4; +// shape.cubicTo(x, cy1, cx1, y, x1, y); +// +// float x2 = Math.max(r - corner, x0); +// shape.lineTo(x2, y); +// +// float cx2 = r - (r - x2) / 4; +// shape.cubicTo(cx2, y, r, cy1, r, y1); +// +// float y2 = Math.max(b - corner, y0); +// shape.lineTo(r, y2); +// +// float cy2 = b - (b - y2) / 4; +// shape.cubicTo(r, cy2, cx2, b, x2, b); +// +// shape.lineTo(x + width * X, b); +// shape.lineTo(x, b + tailHeight); +// shape.lineTo(x1, b); +// +// shape.cubicTo(cx1, b, x, cy2, x, y2); + + shape.close(); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + int c = (int) (M * getAppliedCornerSize()) + getLineWidth(); + Insets ins = super.getPreferredInsets(figure, width, height); + ins = Geometry.union(ins, c, c, c, c); + ins.bottom += getTailHeight(height); + return ins; + } + + private int getTailHeight(int clientHeight) { + return clientHeight / 3; + } + + public int getCornerSize() { + return cornerSize; + } + + protected int getAppliedCornerSize() { + return getCornerSize();// * getLineWidth(); + } + + public void setCornerSize(IFigure figure, int cornerSize) { + if (cornerSize == this.cornerSize) + return; + + this.cornerSize = cornerSize; + invalidate(); + if (figure != null) { + figure.revalidate(); + figure.repaint(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/SegmentedBoundaryDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/SegmentedBoundaryDecoration.java index 4f1e1a16b..451c7c378 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/SegmentedBoundaryDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/SegmentedBoundaryDecoration.java @@ -1,118 +1,118 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractBoundaryDecoration; - -public abstract class SegmentedBoundaryDecoration extends - AbstractBoundaryDecoration { - - private static final float DEFAULT_STEP = 46; - - protected float startX = 0; - - protected float startY = 0; - - protected int numHorizontal = 0; - - protected int numVertical = 0; - - protected float hstep = 0; - - protected float vstep = 0; - - public SegmentedBoundaryDecoration() { - super(); - } - - public SegmentedBoundaryDecoration(String id) { - super(id); - } - - public void validate(IFigure figure) { - super.validate(figure); - Insets ins = figure.getInsets(); - float marginAmount = getMarginAmount(); - float top = ins.top * marginAmount; - float left = ins.left * marginAmount; - float bottom = ins.bottom * marginAmount; - float right = ins.right * marginAmount; - - Rectangle box = getOutlineBox(figure); - float width = box.width - left - right; - float height = box.height - top - bottom; - numHorizontal = Math.max(1, - (int) (width / getPreferredHorizontalStep())); - numVertical = Math.max(1, (int) (height / getPreferredVerticalStep())); - hstep = width / numHorizontal; - vstep = height / numVertical; - startX = left; - startY = top; - } - - protected abstract float getMarginAmount(); - - protected float getPreferredHorizontalStep() { - return DEFAULT_STEP; - } - - protected float getPreferredVerticalStep() { - return DEFAULT_STEP; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { - float x = startX + box.x; - float y = startY + box.y; - float top = box.y; - float left = box.x; - float bottom = box.y + box.height; - float right = box.x + box.width; - - shape.moveTo(x, y); - for (int i = 0; i < numHorizontal; i++) { - sketchTopSegment(figure, shape, x, y, top, i); - x += hstep; - } - for (int i = 0; i < numVertical; i++) { - sketchRightSegment(figure, shape, x, y, right, i); - y += vstep; - } - for (int i = 0; i < numHorizontal; i++) { - sketchBottomSegment(figure, shape, x, y, bottom, i); - x -= hstep; - } - for (int i = 0; i < numVertical; i++) { - sketchLeftSegment(figure, shape, x, y, left, i); - y -= vstep; - } - shape.close(); - } - - protected abstract void sketchTopSegment(IFigure figure, Path shape, - float x, float y, float top, int index); - - protected abstract void sketchRightSegment(IFigure figure, Path shape, - float x, float y, float right, int index); - - protected abstract void sketchBottomSegment(IFigure figure, Path shape, - float x, float y, float bottom, int index); - - protected abstract void sketchLeftSegment(IFigure figure, Path shape, - float x, float y, float left, int index); - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractBoundaryDecoration; + +public abstract class SegmentedBoundaryDecoration extends + AbstractBoundaryDecoration { + + private static final float DEFAULT_STEP = 46; + + protected float startX = 0; + + protected float startY = 0; + + protected int numHorizontal = 0; + + protected int numVertical = 0; + + protected float hstep = 0; + + protected float vstep = 0; + + public SegmentedBoundaryDecoration() { + super(); + } + + public SegmentedBoundaryDecoration(String id) { + super(id); + } + + public void validate(IFigure figure) { + super.validate(figure); + Insets ins = figure.getInsets(); + float marginAmount = getMarginAmount(); + float top = ins.top * marginAmount; + float left = ins.left * marginAmount; + float bottom = ins.bottom * marginAmount; + float right = ins.right * marginAmount; + + Rectangle box = getOutlineBox(figure); + float width = box.width - left - right; + float height = box.height - top - bottom; + numHorizontal = Math.max(1, + (int) (width / getPreferredHorizontalStep())); + numVertical = Math.max(1, (int) (height / getPreferredVerticalStep())); + hstep = width / numHorizontal; + vstep = height / numVertical; + startX = left; + startY = top; + } + + protected abstract float getMarginAmount(); + + protected float getPreferredHorizontalStep() { + return DEFAULT_STEP; + } + + protected float getPreferredVerticalStep() { + return DEFAULT_STEP; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { + float x = startX + box.x; + float y = startY + box.y; + float top = box.y; + float left = box.x; + float bottom = box.y + box.height; + float right = box.x + box.width; + + shape.moveTo(x, y); + for (int i = 0; i < numHorizontal; i++) { + sketchTopSegment(figure, shape, x, y, top, i); + x += hstep; + } + for (int i = 0; i < numVertical; i++) { + sketchRightSegment(figure, shape, x, y, right, i); + y += vstep; + } + for (int i = 0; i < numHorizontal; i++) { + sketchBottomSegment(figure, shape, x, y, bottom, i); + x -= hstep; + } + for (int i = 0; i < numVertical; i++) { + sketchLeftSegment(figure, shape, x, y, left, i); + y -= vstep; + } + shape.close(); + } + + protected abstract void sketchTopSegment(IFigure figure, Path shape, + float x, float y, float top, int index); + + protected abstract void sketchRightSegment(IFigure figure, Path shape, + float x, float y, float right, int index); + + protected abstract void sketchBottomSegment(IFigure figure, Path shape, + float x, float y, float bottom, int index); + + protected abstract void sketchLeftSegment(IFigure figure, Path shape, + float x, float y, float left, int index); + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightBranchConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightBranchConnection.java index 8cb4995c1..684d29c0f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightBranchConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightBranchConnection.java @@ -1,84 +1,84 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractBranchConnection; - -public class StraightBranchConnection extends AbstractBranchConnection { - - private PrecisionPoint s1 = new PrecisionPoint(); - - private PrecisionPoint s2 = new PrecisionPoint(); - - private PrecisionPoint t1 = new PrecisionPoint(); - - private PrecisionPoint t2 = new PrecisionPoint(); - - private PrecisionPoint c1 = new PrecisionPoint(); - - private PrecisionPoint c2 = new PrecisionPoint(); - - private boolean cachedTapered; - - public StraightBranchConnection() { - super(); - } - - public StraightBranchConnection(String id) { - super(id); - } - - protected void route(IFigure figure, Path shape) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - if (isTapered()) { - shape.moveTo(s1); - shape.lineTo(c1); - shape.lineTo(c2); - shape.lineTo(s2); - shape.lineTo(t2); - shape.lineTo(t1); - shape.close(); - } else { - shape.moveTo(p1); - shape.lineTo(p2); - } - } - - public void invalidate() { - super.invalidate(); - cachedTapered = false; - } - - protected boolean isPositionValid() { - return super.isPositionValid() && cachedTapered == isTapered(); - } - - protected void calculateControlPoints(IFigure figure, - PrecisionPoint sourcePos, PrecisionPoint targetPos) { - super.calculateControlPoints(figure, sourcePos, targetPos); - cachedTapered = isTapered(); - if (isTapered()) { - calcTaperedPositions(sourcePos, targetPos, 0, s1, s2); - calcTaperedPositions(sourcePos, targetPos, 1, t1, t2); - - calculateSourceControlPoints(t1, s1, s2, c1); - calculateSourceControlPoints(t2, s2, s1, c2); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractBranchConnection; + +public class StraightBranchConnection extends AbstractBranchConnection { + + private PrecisionPoint s1 = new PrecisionPoint(); + + private PrecisionPoint s2 = new PrecisionPoint(); + + private PrecisionPoint t1 = new PrecisionPoint(); + + private PrecisionPoint t2 = new PrecisionPoint(); + + private PrecisionPoint c1 = new PrecisionPoint(); + + private PrecisionPoint c2 = new PrecisionPoint(); + + private boolean cachedTapered; + + public StraightBranchConnection() { + super(); + } + + public StraightBranchConnection(String id) { + super(id); + } + + protected void route(IFigure figure, Path shape) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + if (isTapered()) { + shape.moveTo(s1); + shape.lineTo(c1); + shape.lineTo(c2); + shape.lineTo(s2); + shape.lineTo(t2); + shape.lineTo(t1); + shape.close(); + } else { + shape.moveTo(p1); + shape.lineTo(p2); + } + } + + public void invalidate() { + super.invalidate(); + cachedTapered = false; + } + + protected boolean isPositionValid() { + return super.isPositionValid() && cachedTapered == isTapered(); + } + + protected void calculateControlPoints(IFigure figure, + PrecisionPoint sourcePos, PrecisionPoint targetPos) { + super.calculateControlPoints(figure, sourcePos, targetPos); + cachedTapered = isTapered(); + if (isTapered()) { + calcTaperedPositions(sourcePos, targetPos, 0, s1, s2); + calcTaperedPositions(sourcePos, targetPos, 1, t1, t2); + + calculateSourceControlPoints(t1, s1, s2, c1); + calculateSourceControlPoints(t2, s2, s1, c2); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightRelationshipDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightRelationshipDecoration.java index 058abbce6..3e22cd745 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightRelationshipDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StraightRelationshipDecoration.java @@ -1,52 +1,52 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractRelationshipDecoration; - -public class StraightRelationshipDecoration extends - AbstractRelationshipDecoration { - - public StraightRelationshipDecoration() { - super(); - } - - public StraightRelationshipDecoration(String id) { - super(id); - } - - protected void route(IFigure figure, Path shape) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - shape.moveTo(p1); - shape.lineTo(p2); - } - - protected double getSourceAnchorAngle(IFigure figure) { - PrecisionPoint p1 = getSourcePosition(figure); - PrecisionPoint p2 = getTargetPosition(figure); - return Geometry.getAngle(p2, p1); - } - - protected double getTargetAnchorAngle(IFigure figure) { - PrecisionPoint p1 = getTargetPosition(figure); - PrecisionPoint p2 = getSourcePosition(figure); - return Geometry.getAngle(p2, p1); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractRelationshipDecoration; + +public class StraightRelationshipDecoration extends + AbstractRelationshipDecoration { + + public StraightRelationshipDecoration() { + super(); + } + + public StraightRelationshipDecoration(String id) { + super(id); + } + + protected void route(IFigure figure, Path shape) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + shape.moveTo(p1); + shape.lineTo(p2); + } + + protected double getSourceAnchorAngle(IFigure figure) { + PrecisionPoint p1 = getSourcePosition(figure); + PrecisionPoint p2 = getTargetPosition(figure); + return Geometry.getAngle(p2, p1); + } + + protected double getTargetAnchorAngle(IFigure figure) { + PrecisionPoint p1 = getTargetPosition(figure); + PrecisionPoint p2 = getSourcePosition(figure); + return Geometry.getAngle(p2, p1); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleDecorationFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleDecorationFactory.java index 408c423ec..08329e394 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleDecorationFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleDecorationFactory.java @@ -1,48 +1,48 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.internal.svgsupport.SvgFileLoader; -import org.xmind.ui.mindmap.IBranchPart; - -public class StrokeCircleDecorationFactory - implements IDecorationFactory, IExecutableExtension { - - private String[] svgFilePaths; - - private String innerPath; - - private String outerPath; - - public StrokeCircleDecorationFactory() { - } - - public void setInitializationData(IConfigurationElement config, - String propertyName, Object data) throws CoreException { - if (data instanceof String) { - String svgFilePath = (String) data; - svgFilePaths = svgFilePath.split(","); //$NON-NLS-1$ - } - - } - - public IDecoration createDecoration(String id, IGraphicalPart part) { - if (innerPath == null) { - SvgFileLoader loader = SvgFileLoader.getInstance(); - innerPath = loader.loadSvgFile(svgFilePaths[0]); - } - - if (outerPath == null && svgFilePaths.length > 1) { - SvgFileLoader loader = SvgFileLoader.getInstance(); - outerPath = loader.loadSvgFile(svgFilePaths[1]); - } - - return new StrokeCircleTopicDecoration(id, (IBranchPart) part, - innerPath, outerPath); - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.internal.svgsupport.SvgFileLoader; +import org.xmind.ui.mindmap.IBranchPart; + +public class StrokeCircleDecorationFactory + implements IDecorationFactory, IExecutableExtension { + + private String[] svgFilePaths; + + private String innerPath; + + private String outerPath; + + public StrokeCircleDecorationFactory() { + } + + public void setInitializationData(IConfigurationElement config, + String propertyName, Object data) throws CoreException { + if (data instanceof String) { + String svgFilePath = (String) data; + svgFilePaths = svgFilePath.split(","); //$NON-NLS-1$ + } + + } + + public IDecoration createDecoration(String id, IGraphicalPart part) { + if (innerPath == null) { + SvgFileLoader loader = SvgFileLoader.getInstance(); + innerPath = loader.loadSvgFile(svgFilePaths[0]); + } + + if (outerPath == null && svgFilePaths.length > 1) { + SvgFileLoader loader = SvgFileLoader.getInstance(); + outerPath = loader.loadSvgFile(svgFilePaths[1]); + } + + return new StrokeCircleTopicDecoration(id, (IBranchPart) part, + innerPath, outerPath); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleTopicDecoration.java index 853674df0..30b71e872 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/StrokeCircleTopicDecoration.java @@ -1,121 +1,121 @@ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; -import org.xmind.ui.internal.svgsupport.SvgPathParser; -import org.xmind.ui.mindmap.IBranchPart; - -public class StrokeCircleTopicDecoration extends AbstractTopicDecoration { - - private static final float scaleLeft = 0.13f; - private static final float scaleRight = 0.13f; - private static final float scaleTop = 0.13f; - private static final float scaleBottom = 0.27f; - - private IBranchPart branch; - - private String innerSvgPath; - - private String outerSvgPath; - - public StrokeCircleTopicDecoration() { - } - - public StrokeCircleTopicDecoration(String id) { - super(id); - } - - public StrokeCircleTopicDecoration(String id, IBranchPart branch, - String innerSvgPath, String outerSvgPath) { - super(id); - this.branch = branch; - this.innerSvgPath = innerSvgPath; - this.outerSvgPath = outerSvgPath; - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - Path innerPath = new Path(Display.getCurrent()); - SvgPathParser parser = SvgPathParser.getInstance(); - - float halfLineWidth = getLineWidth() * 0.5f; - if (purpose == CHECK) { - parser.parseSvgPath(innerPath, box.getCenter().x - halfLineWidth, - box.getCenter().y + halfLineWidth, - box.width + getLineWidth(), box.height + getLineWidth(), - innerSvgPath); - } else { - parser.parseSvgPath(innerPath, box.getCenter().x + 1, - box.getCenter().y + 1, box.width, box.height, innerSvgPath); - } - - innerPath.close(); - shape.addPath(innerPath); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, double refX, - double refY, double expansion) { - if (branch != null && branch.getTopic().isRoot()) { - float scaleWidth = 1 - scaleLeft - scaleRight; - float scaleHeight = 1 - scaleTop - scaleBottom; - Rectangle bounds = figure.getBounds(); - Point tf = bounds.getTopLeft().getTranslated( - bounds.width * scaleLeft, bounds.height * scaleTop); - Rectangle area = new Rectangle(tf.x, tf.y, - (int) (bounds.width * scaleWidth), - (int) (bounds.height * scaleHeight)); - - return Geometry.getChopBoxLocation(refX, refY, area, expansion); - } - - return super.getAnchorLocation(figure, refX, refY, expansion); - } - - public Insets getPreferredInsets(IFigure figure, int width, int height) { - float scaleWidth = 1 - scaleLeft - scaleRight; - float scaleHeight = 1 - scaleTop - scaleBottom; - return new Insets( - (int) ((height + getTopMargin() + getLineWidth()) / scaleHeight - * scaleTop), - (int) ((width + getLeftMargin() + getLineWidth()) / scaleWidth - * scaleLeft), - (int) ((height + getBottomMargin() + getLineWidth()) - / scaleHeight * scaleBottom), - (int) ((width + getRightMargin() + getLineWidth()) / scaleWidth - * scaleRight)); - } - - protected boolean containsPoint(IFigure figure, int x, int y, - boolean outline) { - checkValidation(figure); - boolean ret = figure.getBounds().contains(x, y); - return ret; - } - - protected void paintOutline(IFigure figure, Graphics graphics) { - Rectangle box = getOutlineBox(figure); - if (getLineWidth() != 0 && outerSvgPath != null) { - graphics.setBackgroundColor(graphics.getForegroundColor()); - Path outerPath = new Path(Display.getCurrent()); - SvgPathParser parser = SvgPathParser.getInstance(); - parser.parseSvgPath(outerPath, box.getCenter().x, - box.getCenter().y + 1, box.width, box.height, outerSvgPath); - - graphics.drawPath(outerPath); - graphics.fillPath(outerPath); - - outerPath.close(); - } else { - super.paintOutline(figure, graphics); - } - } - -} +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; +import org.xmind.ui.internal.svgsupport.SvgPathParser; +import org.xmind.ui.mindmap.IBranchPart; + +public class StrokeCircleTopicDecoration extends AbstractTopicDecoration { + + private static final float scaleLeft = 0.13f; + private static final float scaleRight = 0.13f; + private static final float scaleTop = 0.13f; + private static final float scaleBottom = 0.27f; + + private IBranchPart branch; + + private String innerSvgPath; + + private String outerSvgPath; + + public StrokeCircleTopicDecoration() { + } + + public StrokeCircleTopicDecoration(String id) { + super(id); + } + + public StrokeCircleTopicDecoration(String id, IBranchPart branch, + String innerSvgPath, String outerSvgPath) { + super(id); + this.branch = branch; + this.innerSvgPath = innerSvgPath; + this.outerSvgPath = outerSvgPath; + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + Path innerPath = new Path(Display.getCurrent()); + SvgPathParser parser = SvgPathParser.getInstance(); + + float halfLineWidth = getLineWidth() * 0.5f; + if (purpose == CHECK) { + parser.parseSvgPath(innerPath, box.getCenter().x - halfLineWidth, + box.getCenter().y + halfLineWidth, + box.width + getLineWidth(), box.height + getLineWidth(), + innerSvgPath); + } else { + parser.parseSvgPath(innerPath, box.getCenter().x + 1, + box.getCenter().y + 1, box.width, box.height, innerSvgPath); + } + + innerPath.close(); + shape.addPath(innerPath); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, double refX, + double refY, double expansion) { + if (branch != null && branch.getTopic().isRoot()) { + float scaleWidth = 1 - scaleLeft - scaleRight; + float scaleHeight = 1 - scaleTop - scaleBottom; + Rectangle bounds = figure.getBounds(); + Point tf = bounds.getTopLeft().getTranslated( + bounds.width * scaleLeft, bounds.height * scaleTop); + Rectangle area = new Rectangle(tf.x, tf.y, + (int) (bounds.width * scaleWidth), + (int) (bounds.height * scaleHeight)); + + return Geometry.getChopBoxLocation(refX, refY, area, expansion); + } + + return super.getAnchorLocation(figure, refX, refY, expansion); + } + + public Insets getPreferredInsets(IFigure figure, int width, int height) { + float scaleWidth = 1 - scaleLeft - scaleRight; + float scaleHeight = 1 - scaleTop - scaleBottom; + return new Insets( + (int) ((height + getTopMargin() + getLineWidth()) / scaleHeight + * scaleTop), + (int) ((width + getLeftMargin() + getLineWidth()) / scaleWidth + * scaleLeft), + (int) ((height + getBottomMargin() + getLineWidth()) + / scaleHeight * scaleBottom), + (int) ((width + getRightMargin() + getLineWidth()) / scaleWidth + * scaleRight)); + } + + protected boolean containsPoint(IFigure figure, int x, int y, + boolean outline) { + checkValidation(figure); + boolean ret = figure.getBounds().contains(x, y); + return ret; + } + + protected void paintOutline(IFigure figure, Graphics graphics) { + Rectangle box = getOutlineBox(figure); + if (getLineWidth() != 0 && outerSvgPath != null) { + graphics.setBackgroundColor(graphics.getForegroundColor()); + Path outerPath = new Path(Display.getCurrent()); + SvgPathParser parser = SvgPathParser.getInstance(); + parser.parseSvgPath(outerPath, box.getCenter().x, + box.getCenter().y + 1, box.width, box.height, outerSvgPath); + + graphics.drawPath(outerPath); + graphics.fillPath(outerPath); + + outerPath.close(); + } else { + super.paintOutline(figure, graphics); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnection.java index 917906002..c4fd328b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnection.java @@ -1,93 +1,93 @@ -package org.xmind.ui.internal.decorations; - -import java.util.List; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractBranchConnection; -import org.xmind.ui.decorations.ITopicDecoration; -import org.xmind.ui.internal.figures.BranchFigure; -import org.xmind.ui.internal.figures.TopicFigure; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; - -@SuppressWarnings("restriction") -public class TimelineHorizontalConnection extends AbstractBranchConnection { - - private IBranchPart branch; - - public TimelineHorizontalConnection(IBranchPart branch, String id) { - super(id); - this.branch = branch; - } - - @Override - protected void route(IFigure figure, Path shape) { - Point sp = getPosition(branch.getTopicPart()); - List subBranches = branch.getSubBranches(); - Point tp = sp; - if (subBranches != null && !subBranches.isEmpty()) { - IBranchPart lastBranch = subBranches.get(subBranches.size() - 1); - tp = getPosition(lastBranch.getTopicPart()); - } - - if (figure instanceof BranchFigure) { - shape.moveTo(sp); - shape.lineTo(tp.x, sp.y); - } else { - shape.moveTo(getSourcePosition(figure)); - shape.lineTo(getTargetPosition(figure)); - } - } - - private Point getPosition(ITopicPart topic) { - Rectangle bounds = topic.getFigure().getBounds(); - return bounds.getLocation().getTranslated(bounds.width / 2, - bounds.height / 2); - } - - @Override - protected void paintPath(IFigure figure, Graphics graphics, Path path, - boolean fill) { - if (branch != null) { - Rectangle bounds = figure.getBounds(); - Path shape = new Path(Display.getCurrent()); - shape.addRectangle(bounds); - shape.addPath(getDecoration(branch) - .createClippingPath(branch.getTopicPart().getFigure())); - for (IBranchPart sub : branch.getSubBranches()) { - shape.addPath(getDecoration(sub) - .createClippingPath(sub.getTopicPart().getFigure())); - } - graphics.pushState(); - try { - graphics.setClip(shape); -// if (fill) { -// graphics.fillPath(path); -// } else { - if (getLineWidth() > 0) - graphics.drawPath(path); -// } - graphics.restoreState(); - } finally { - graphics.popState(); - shape.close(); - shape.dispose(); - } - return; - - } - - super.paintPath(figure, graphics, path, fill); - } - - private ITopicDecoration getDecoration(IBranchPart branch) { - IFigure figure = branch.getTopicPart().getFigure(); - return ((TopicFigure) figure).getDecoration(); - } - -} +package org.xmind.ui.internal.decorations; + +import java.util.List; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractBranchConnection; +import org.xmind.ui.decorations.ITopicDecoration; +import org.xmind.ui.internal.figures.BranchFigure; +import org.xmind.ui.internal.figures.TopicFigure; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; + +@SuppressWarnings("restriction") +public class TimelineHorizontalConnection extends AbstractBranchConnection { + + private IBranchPart branch; + + public TimelineHorizontalConnection(IBranchPart branch, String id) { + super(id); + this.branch = branch; + } + + @Override + protected void route(IFigure figure, Path shape) { + Point sp = getPosition(branch.getTopicPart()); + List subBranches = branch.getSubBranches(); + Point tp = sp; + if (subBranches != null && !subBranches.isEmpty()) { + IBranchPart lastBranch = subBranches.get(subBranches.size() - 1); + tp = getPosition(lastBranch.getTopicPart()); + } + + if (figure instanceof BranchFigure) { + shape.moveTo(sp); + shape.lineTo(tp.x, sp.y); + } else { + shape.moveTo(getSourcePosition(figure)); + shape.lineTo(getTargetPosition(figure)); + } + } + + private Point getPosition(ITopicPart topic) { + Rectangle bounds = topic.getFigure().getBounds(); + return bounds.getLocation().getTranslated(bounds.width / 2, + bounds.height / 2); + } + + @Override + protected void paintPath(IFigure figure, Graphics graphics, Path path, + boolean fill) { + if (branch != null) { + Rectangle bounds = figure.getBounds(); + Path shape = new Path(Display.getCurrent()); + shape.addRectangle(bounds); + shape.addPath(getDecoration(branch) + .createClippingPath(branch.getTopicPart().getFigure())); + for (IBranchPart sub : branch.getSubBranches()) { + shape.addPath(getDecoration(sub) + .createClippingPath(sub.getTopicPart().getFigure())); + } + graphics.pushState(); + try { + graphics.setClip(shape); +// if (fill) { +// graphics.fillPath(path); +// } else { + if (getLineWidth() > 0) + graphics.drawPath(path); +// } + graphics.restoreState(); + } finally { + graphics.popState(); + shape.close(); + shape.dispose(); + } + return; + + } + + super.paintPath(figure, graphics, path, fill); + } + + private ITopicDecoration getDecoration(IBranchPart branch) { + IFigure figure = branch.getTopicPart().getFigure(); + return ((TopicFigure) figure).getDecoration(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnectionFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnectionFactory.java index 7e7aba8f2..680acfdf8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnectionFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/TimelineHorizontalConnectionFactory.java @@ -1,14 +1,14 @@ -package org.xmind.ui.internal.decorations; - -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IDecorationFactory; -import org.xmind.ui.mindmap.IBranchPart; - -public class TimelineHorizontalConnectionFactory implements IDecorationFactory { - - public IDecoration createDecoration(String id, IGraphicalPart part) { - return new TimelineHorizontalConnection((IBranchPart) part, id); - } - -} +package org.xmind.ui.internal.decorations; + +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IDecorationFactory; +import org.xmind.ui.mindmap.IBranchPart; + +public class TimelineHorizontalConnectionFactory implements IDecorationFactory { + + public IDecoration createDecoration(String id, IGraphicalPart part) { + return new TimelineHorizontalConnection((IBranchPart) part, id); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/UnderlineTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/UnderlineTopicDecoration.java index 52f8875a5..346c3b730 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/UnderlineTopicDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/UnderlineTopicDecoration.java @@ -1,75 +1,75 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorations; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.gef.draw2d.graphics.Path; -import org.xmind.ui.decorations.AbstractTopicDecoration; - -public class UnderlineTopicDecoration extends AbstractTopicDecoration { - - private static PrecisionPoint P = new PrecisionPoint(); - - public UnderlineTopicDecoration() { - super(); - } - - public UnderlineTopicDecoration(String id) { - super(id); - } - - private PrecisionPoint getLeftAnchor(Rectangle rect, double expansion) { - return P.setLocation(rect.x - expansion, rect.y + rect.height + 1); - } - - private PrecisionPoint getRightAnchor(Rectangle rect, double expansion) { - return P.setLocation(rect.x + rect.width + expansion, - rect.y + rect.height + 1); - } - - protected void sketch(IFigure figure, Path shape, Rectangle box, - int purpose) { - if (purpose == OUTLINE) { - shape.moveTo(getLeftAnchor(box, 0)); - shape.lineTo(getRightAnchor(box, 0)); - } else if (purpose == CHECK) { - int halfLineWidth = getLineWidth() / 2; - shape.moveTo(box.x - halfLineWidth, box.y - halfLineWidth); - shape.lineTo(box.x - halfLineWidth, box.bottom() + halfLineWidth); - shape.lineTo(box.right() + halfLineWidth, - box.bottom() + halfLineWidth); - shape.lineTo(box.right() + halfLineWidth, box.y - halfLineWidth); - } else { - shape.moveTo(box.getTopLeft()); - shape.lineTo(box.getBottomLeft()); - shape.lineTo(box.getBottomRight()); - shape.lineTo(box.getTopRight()); - } - shape.close(); - } - - public PrecisionPoint getAnchorLocation(IFigure figure, int orientation, - double expansion) { - if (orientation == PositionConstants.EAST) { - return getRightAnchor(getOutlineBox(figure), expansion).getCopy(); - } else if (orientation == PositionConstants.WEST) { - return getLeftAnchor(getOutlineBox(figure), expansion).getCopy(); - } - return super.getAnchorLocation(figure, orientation, expansion); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorations; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.Path; +import org.xmind.ui.decorations.AbstractTopicDecoration; + +public class UnderlineTopicDecoration extends AbstractTopicDecoration { + + private static PrecisionPoint P = new PrecisionPoint(); + + public UnderlineTopicDecoration() { + super(); + } + + public UnderlineTopicDecoration(String id) { + super(id); + } + + private PrecisionPoint getLeftAnchor(Rectangle rect, double expansion) { + return P.setLocation(rect.x - expansion, rect.y + rect.height + 1); + } + + private PrecisionPoint getRightAnchor(Rectangle rect, double expansion) { + return P.setLocation(rect.x + rect.width + expansion, + rect.y + rect.height + 1); + } + + protected void sketch(IFigure figure, Path shape, Rectangle box, + int purpose) { + if (purpose == OUTLINE) { + shape.moveTo(getLeftAnchor(box, 0)); + shape.lineTo(getRightAnchor(box, 0)); + } else if (purpose == CHECK) { + int halfLineWidth = getLineWidth() / 2; + shape.moveTo(box.x - halfLineWidth, box.y - halfLineWidth); + shape.lineTo(box.x - halfLineWidth, box.bottom() + halfLineWidth); + shape.lineTo(box.right() + halfLineWidth, + box.bottom() + halfLineWidth); + shape.lineTo(box.right() + halfLineWidth, box.y - halfLineWidth); + } else { + shape.moveTo(box.getTopLeft()); + shape.lineTo(box.getBottomLeft()); + shape.lineTo(box.getBottomRight()); + shape.lineTo(box.getTopRight()); + } + shape.close(); + } + + public PrecisionPoint getAnchorLocation(IFigure figure, int orientation, + double expansion) { + if (orientation == PositionConstants.EAST) { + return getRightAnchor(getOutlineBox(figure), expansion).getCopy(); + } else if (orientation == PositionConstants.WEST) { + return getLeftAnchor(getOutlineBox(figure), expansion).getCopy(); + } + return super.getAnchorLocation(figure, orientation, expansion); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/BoundaryTitleTextDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/BoundaryTitleTextDecorator.java index 542c1a765..44946a019 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/BoundaryTitleTextDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/BoundaryTitleTextDecorator.java @@ -1,97 +1,97 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LineBorder; -import org.eclipse.swt.graphics.Color; -import org.xmind.core.ITitled; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; - -public class BoundaryTitleTextDecorator extends TitleTextDecorator { - - private static final BoundaryTitleTextDecorator instance = new BoundaryTitleTextDecorator(); - - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - figure.setBorder(new LineBorder()); - figure.setOpaque(true); - } - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - } - - protected String getUntitledText(IGraphicalPart part, ITitled titled) { - return MindMapMessages.TitleText_Boundary; - } - - @Override - protected void decorateTextFigure(IGraphicalPart ownerPart, - IStyleSelector ss, ITextFigure figure) { - super.decorateTextFigure(ownerPart, ss, figure); - String decorationId = StyleUtils.getString(ownerPart, ss, - Styles.ShapeClass, Styles.BOUNDARY_SHAPE_RECT); - figure.setBackgroundColor(getFillColor(ownerPart, ss, decorationId)); - LineBorder border = (LineBorder) figure.getBorder(); - Color oldLineColor = border.getColor(); - Color newLineColor = getLineColor(ownerPart, ss, decorationId); - if (!newLineColor.equals(oldLineColor)) { - border.setColor(newLineColor); - figure.repaint(); - } - int oldLineWidth = border.getWidth(); - int newLineWidth = getLineWidth(ownerPart, ss, decorationId); - if (newLineWidth != oldLineWidth) { - border.setWidth(newLineWidth); - figure.revalidate(); - figure.repaint(); - } - } - - private int getLineWidth(IGraphicalPart part, IStyleSelector ss, - String decorationId) { - return StyleUtils.getInteger(part, ss, Styles.LineWidth, decorationId, - Styles.DEF_BOUNDARY_LINE_WIDTH); - } - - protected Color getLineColor(IGraphicalPart part, IStyleSelector ss, - String decorationId) { - return StyleUtils.getColor(part, ss, Styles.LineColor, decorationId, - Styles.DEF_BOUNDARY_LINE_COLOR); - } - - protected Color getFillColor(IGraphicalPart part, IStyleSelector ss, - String decorationId) { - return StyleUtils.getColor(part, ss, Styles.FillColor, decorationId, - Styles.DEF_BOUNDARY_FILL_COLOR); - } - - protected IGraphicalPart getOwnerPart(IGraphicalPart part) { - if (part.getParent() instanceof IBoundaryPart) - return (IBoundaryPart) part.getParent(); - return super.getOwnerPart(part); - } - - public static BoundaryTitleTextDecorator getInstance() { - return instance; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LineBorder; +import org.eclipse.swt.graphics.Color; +import org.xmind.core.ITitled; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; + +public class BoundaryTitleTextDecorator extends TitleTextDecorator { + + private static final BoundaryTitleTextDecorator instance = new BoundaryTitleTextDecorator(); + + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + figure.setBorder(new LineBorder()); + figure.setOpaque(true); + } + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + } + + protected String getUntitledText(IGraphicalPart part, ITitled titled) { + return MindMapMessages.TitleText_Boundary; + } + + @Override + protected void decorateTextFigure(IGraphicalPart ownerPart, + IStyleSelector ss, ITextFigure figure) { + super.decorateTextFigure(ownerPart, ss, figure); + String decorationId = StyleUtils.getString(ownerPart, ss, + Styles.ShapeClass, Styles.BOUNDARY_SHAPE_RECT); + figure.setBackgroundColor(getFillColor(ownerPart, ss, decorationId)); + LineBorder border = (LineBorder) figure.getBorder(); + Color oldLineColor = border.getColor(); + Color newLineColor = getLineColor(ownerPart, ss, decorationId); + if (!newLineColor.equals(oldLineColor)) { + border.setColor(newLineColor); + figure.repaint(); + } + int oldLineWidth = border.getWidth(); + int newLineWidth = getLineWidth(ownerPart, ss, decorationId); + if (newLineWidth != oldLineWidth) { + border.setWidth(newLineWidth); + figure.revalidate(); + figure.repaint(); + } + } + + private int getLineWidth(IGraphicalPart part, IStyleSelector ss, + String decorationId) { + return StyleUtils.getInteger(part, ss, Styles.LineWidth, decorationId, + Styles.DEF_BOUNDARY_LINE_WIDTH); + } + + protected Color getLineColor(IGraphicalPart part, IStyleSelector ss, + String decorationId) { + return StyleUtils.getColor(part, ss, Styles.LineColor, decorationId, + Styles.DEF_BOUNDARY_LINE_COLOR); + } + + protected Color getFillColor(IGraphicalPart part, IStyleSelector ss, + String decorationId) { + return StyleUtils.getColor(part, ss, Styles.FillColor, decorationId, + Styles.DEF_BOUNDARY_FILL_COLOR); + } + + protected IGraphicalPart getOwnerPart(IGraphicalPart part) { + if (part.getParent() instanceof IBoundaryPart) + return (IBoundaryPart) part.getParent(); + return super.getOwnerPart(part); + } + + public static BoundaryTitleTextDecorator getInstance() { + return instance; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemContentDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemContentDecorator.java index f8cfc9c51..0ea332197 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemContentDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemContentDecorator.java @@ -1,70 +1,70 @@ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.Util; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.mindmap.InfoItemContentPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.style.Styles; - -public class InfoItemContentDecorator extends Decorator { - - private static final InfoItemContentDecorator instance = new InfoItemContentDecorator(); - - @Override - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - figure.setForegroundColor( - ColorUtils.getColor(Styles.YELLOWBOX_TEXT_COLOR)); - } - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - ITopicPart topicPart = null; - if (part instanceof InfoItemContentPart) { - topicPart = ((InfoItemContentPart) part).getTopicPart(); - if (topicPart != null) { - figure.setFont( - FontUtils.getNewHeight(JFaceResources.getDefaultFont(), - Util.isMac() ? 10 : 8)); - } else { - figure.setFont(JFaceResources.getDefaultFont()); - } - } - if (figure instanceof RotatableWrapLabel) { - RotatableWrapLabel itemFigure = (RotatableWrapLabel) figure; - if (part instanceof InfoItemContentPart) { - itemFigure.setAbbreviated(true); - itemFigure.setSingleLine(true); - if (topicPart != null) { - setPrefWidth(itemFigure, topicPart); - } - InfoItemContentPart item = (InfoItemContentPart) part; - itemFigure.setText(item.getContent()); - } - } - } - - private void setPrefWidth(final RotatableWrapLabel itemFigure, - ITopicPart topicPart) { - final IFigure figure = topicPart.getFigure(); - figure.getUpdateManager().runWithUpdate(new Runnable() { - public void run() { - itemFigure.setPrefWidth(Math.abs((int) (((figure.getSize().width - + figure.getClientArea().width) / 2) * 1.1 - 10))); - } - }); - - } - - public static InfoItemContentDecorator getInstance() { - return instance; - } - -} +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Util; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.mindmap.InfoItemContentPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.style.Styles; + +public class InfoItemContentDecorator extends Decorator { + + private static final InfoItemContentDecorator instance = new InfoItemContentDecorator(); + + @Override + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + figure.setForegroundColor( + ColorUtils.getColor(Styles.YELLOWBOX_TEXT_COLOR)); + } + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + ITopicPart topicPart = null; + if (part instanceof InfoItemContentPart) { + topicPart = ((InfoItemContentPart) part).getTopicPart(); + if (topicPart != null) { + figure.setFont( + FontUtils.getNewHeight(JFaceResources.getDefaultFont(), + Util.isMac() ? 10 : 8)); + } else { + figure.setFont(JFaceResources.getDefaultFont()); + } + } + if (figure instanceof RotatableWrapLabel) { + RotatableWrapLabel itemFigure = (RotatableWrapLabel) figure; + if (part instanceof InfoItemContentPart) { + itemFigure.setAbbreviated(true); + itemFigure.setSingleLine(true); + if (topicPart != null) { + setPrefWidth(itemFigure, topicPart); + } + InfoItemContentPart item = (InfoItemContentPart) part; + itemFigure.setText(item.getContent()); + } + } + } + + private void setPrefWidth(final RotatableWrapLabel itemFigure, + ITopicPart topicPart) { + final IFigure figure = topicPart.getFigure(); + figure.getUpdateManager().runWithUpdate(new Runnable() { + public void run() { + itemFigure.setPrefWidth(Math.abs((int) (((figure.getSize().width + + figure.getClientArea().width) / 2) * 1.1 - 10))); + } + }); + + } + + public static InfoItemContentDecorator getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemIconDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemIconDecorator.java index 9b1c1d4f9..e3e939f94 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemIconDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InfoItemIconDecorator.java @@ -1,42 +1,42 @@ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.graphics.Image; -import org.xmind.gef.draw2d.SizeableImageFigure; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.mindmap.IInfoItemPart; - -public class InfoItemIconDecorator extends Decorator { - - private static final InfoItemIconDecorator instance = new InfoItemIconDecorator(); - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - if (figure instanceof SizeableImageFigure) { - SizeableImageFigure imgFigure = (SizeableImageFigure) figure; - Image image = null; - if (part instanceof IInfoItemPart) { - image = ((IInfoItemPart) part).getImage(); - } else { - image = (Image) part.getAdapter(Image.class); - } - imgFigure.setImage(image); - imgFigure.setPreferredSize(imgFigure.getImageSize()); - } - } - - public void deactivate(IGraphicalPart part, IFigure figure) { - super.deactivate(part, figure); - if (figure instanceof SizeableImageFigure) { - SizeableImageFigure imgFigure = (SizeableImageFigure) figure; - imgFigure.setImage(null); - } - } - - public static InfoItemIconDecorator getInstance() { - return instance; - } - -} +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.graphics.Image; +import org.xmind.gef.draw2d.SizeableImageFigure; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.mindmap.IInfoItemPart; + +public class InfoItemIconDecorator extends Decorator { + + private static final InfoItemIconDecorator instance = new InfoItemIconDecorator(); + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + if (figure instanceof SizeableImageFigure) { + SizeableImageFigure imgFigure = (SizeableImageFigure) figure; + Image image = null; + if (part instanceof IInfoItemPart) { + image = ((IInfoItemPart) part).getImage(); + } else { + image = (Image) part.getAdapter(Image.class); + } + imgFigure.setImage(image); + imgFigure.setPreferredSize(imgFigure.getImageSize()); + } + } + + public void deactivate(IGraphicalPart part, IFigure figure) { + super.deactivate(part, figure); + if (figure instanceof SizeableImageFigure) { + SizeableImageFigure imgFigure = (SizeableImageFigure) figure; + imgFigure.setImage(null); + } + } + + public static InfoItemIconDecorator getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InformationDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InformationDecorator.java index 76fa234c6..c4a6e88c7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InformationDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/InformationDecorator.java @@ -1,92 +1,92 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import static org.xmind.ui.style.StyleUtils.getColor; -import static org.xmind.ui.style.StyleUtils.getStyleSelector; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; -import org.xmind.gef.draw2d.DecoratedShapeFigure; -import org.xmind.gef.draw2d.decoration.IShapeDecorationEx; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.decorations.IInfoDecoration; -import org.xmind.ui.internal.decorations.RectangleInfoDecration; -import org.xmind.ui.internal.mindmap.InfoPart; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.style.Styles; - -public class InformationDecorator extends Decorator { - - private static final InformationDecorator instance = new InformationDecorator(); - - private static final int H_MARGIN = 5; - - private static final int V_MARGIN = 5; - - private static final int LINEWIDTH = 1; - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - if (part instanceof InfoPart) { - figure.setVisible(((InfoPart) part).hasActions()); - } - if (figure instanceof DecoratedShapeFigure) { - DecoratedShapeFigure fig = (DecoratedShapeFigure) figure; - IShapeDecorationEx decoration = fig.getDecoration(); - IInfoDecoration shape = null; - if (decoration instanceof IInfoDecoration) - shape = (IInfoDecoration) decoration; - if (shape == null) - shape = new RectangleInfoDecration(); - shape.setLeftMargin(figure, H_MARGIN); - shape.setTopMargin(figure, V_MARGIN); - shape.setRightMargin(figure, H_MARGIN); - shape.setBottomMargin(figure, V_MARGIN); - shape.setLineColor(figure, - new LocalResourceManager(JFaceResources.getResources()) - .createColor(new RGB(248, 227, 137))); - shape.setFillColor(figure, - getColor(getSheetPart(part), - getStyleSelector(getSheetPart(part)), - Styles.YellowBoxFillColor, shape.getId(), - Styles.DEF_YELLOWBOX_FILL_COLOR)); - shape.setLineAlpha(figure, 255); - shape.setLineWidth(figure, LINEWIDTH); - shape.setLineStyle(figure, SWT.LINE_SOLID); - fig.setDecoration(shape); - } - } - - private ISheetPart getSheetPart(IGraphicalPart part) { - if (part instanceof ISheetPart) - return (ISheetPart) part; - IPart parentPart = part.getParent(); - while (parentPart != null && !(parentPart instanceof ISheetPart)) { - parentPart = parentPart.getParent(); - } - - return (ISheetPart) parentPart; - } - - public static InformationDecorator getInstance() { - return instance; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import static org.xmind.ui.style.StyleUtils.getColor; +import static org.xmind.ui.style.StyleUtils.getStyleSelector; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.xmind.gef.draw2d.DecoratedShapeFigure; +import org.xmind.gef.draw2d.decoration.IShapeDecorationEx; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.decorations.IInfoDecoration; +import org.xmind.ui.internal.decorations.RectangleInfoDecration; +import org.xmind.ui.internal.mindmap.InfoPart; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.style.Styles; + +public class InformationDecorator extends Decorator { + + private static final InformationDecorator instance = new InformationDecorator(); + + private static final int H_MARGIN = 5; + + private static final int V_MARGIN = 5; + + private static final int LINEWIDTH = 1; + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + if (part instanceof InfoPart) { + figure.setVisible(((InfoPart) part).hasActions()); + } + if (figure instanceof DecoratedShapeFigure) { + DecoratedShapeFigure fig = (DecoratedShapeFigure) figure; + IShapeDecorationEx decoration = fig.getDecoration(); + IInfoDecoration shape = null; + if (decoration instanceof IInfoDecoration) + shape = (IInfoDecoration) decoration; + if (shape == null) + shape = new RectangleInfoDecration(); + shape.setLeftMargin(figure, H_MARGIN); + shape.setTopMargin(figure, V_MARGIN); + shape.setRightMargin(figure, H_MARGIN); + shape.setBottomMargin(figure, V_MARGIN); + shape.setLineColor(figure, + new LocalResourceManager(JFaceResources.getResources()) + .createColor(new RGB(248, 227, 137))); + shape.setFillColor(figure, + getColor(getSheetPart(part), + getStyleSelector(getSheetPart(part)), + Styles.YellowBoxFillColor, shape.getId(), + Styles.DEF_YELLOWBOX_FILL_COLOR)); + shape.setLineAlpha(figure, 255); + shape.setLineWidth(figure, LINEWIDTH); + shape.setLineStyle(figure, SWT.LINE_SOLID); + fig.setDecoration(shape); + } + } + + private ISheetPart getSheetPart(IGraphicalPart part) { + if (part instanceof ISheetPart) + return (ISheetPart) part; + IPart parentPart = part.getParent(); + while (parentPart != null && !(parentPart instanceof ISheetPart)) { + parentPart = parentPart.getParent(); + } + + return (ISheetPart) parentPart; + } + + public static InformationDecorator getInstance() { + return instance; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/LegendItemDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/LegendItemDecorator.java index 550d3bb91..f7e4ad870 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/LegendItemDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/LegendItemDecorator.java @@ -1,62 +1,62 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.IFigure; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.Util; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.figures.LegendItemFigure; -import org.xmind.ui.mindmap.ILegendItemPart; -import org.xmind.ui.resources.FontUtils; - -public class LegendItemDecorator extends Decorator { - - private static final LegendItemDecorator instance = new LegendItemDecorator(); - - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - figure.setFont(FontUtils.getNewHeight(JFaceResources.getDefaultFont(), - Util.isMac() ? 10 : 8)); - figure.setForegroundColor(ColorConstants.black); - if (figure instanceof LegendItemFigure) { - ((LegendItemFigure) figure).getIcon().setPreferredSize(15, 15); - } - } - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - if (figure instanceof LegendItemFigure) { - LegendItemFigure itemFigure = (LegendItemFigure) figure; - if (part instanceof ILegendItemPart) { - ILegendItemPart item = (ILegendItemPart) part; - itemFigure.setIconImage(item.getIconImage()); - itemFigure.setSVGData(item.getSVGData()); - itemFigure.setText(item.getDescription()); - } - } - } - - public void deactivate(IGraphicalPart part, IFigure figure) { - if (figure instanceof LegendItemFigure) { - ((LegendItemFigure) figure).setIconImage(null); - ((LegendItemFigure) figure).setSVGData(null); - } - super.deactivate(part, figure); - } - - public static LegendItemDecorator getInstance() { - return instance; - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.IFigure; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Util; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.figures.LegendItemFigure; +import org.xmind.ui.mindmap.ILegendItemPart; +import org.xmind.ui.resources.FontUtils; + +public class LegendItemDecorator extends Decorator { + + private static final LegendItemDecorator instance = new LegendItemDecorator(); + + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + figure.setFont(FontUtils.getNewHeight(JFaceResources.getDefaultFont(), + Util.isMac() ? 10 : 8)); + figure.setForegroundColor(ColorConstants.black); + if (figure instanceof LegendItemFigure) { + ((LegendItemFigure) figure).getIcon().setPreferredSize(15, 15); + } + } + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + if (figure instanceof LegendItemFigure) { + LegendItemFigure itemFigure = (LegendItemFigure) figure; + if (part instanceof ILegendItemPart) { + ILegendItemPart item = (ILegendItemPart) part; + itemFigure.setIconImage(item.getIconImage()); + itemFigure.setSVGData(item.getSVGData()); + itemFigure.setText(item.getDescription()); + } + } + } + + public void deactivate(IGraphicalPart part, IFigure figure) { + if (figure instanceof LegendItemFigure) { + ((LegendItemFigure) figure).setIconImage(null); + ((LegendItemFigure) figure).setSVGData(null); + } + super.deactivate(part, figure); + } + + public static LegendItemDecorator getInstance() { + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/PlusMinusDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/PlusMinusDecorator.java index 2e36dfe54..6f88f7655 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/PlusMinusDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/PlusMinusDecorator.java @@ -1,102 +1,102 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.xmind.core.Core; -import org.xmind.gef.IViewer; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IRootPart; -import org.xmind.gef.util.Properties; -import org.xmind.ui.internal.figures.PlusMinusFigure; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.IPlusMinusPart; -import org.xmind.ui.style.Styles; - -public class PlusMinusDecorator extends Decorator { - - private static final PlusMinusDecorator instance = new PlusMinusDecorator(); - - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - figure.setMinimumSize(IMinimizable.DEFAULT_MIN_SIZE); - figure.setPreferredSize(new Dimension(Styles.PLUS_MINUS_HEIGHT, - Styles.PLUS_MINUS_HEIGHT)); - } - - public void decorate(IGraphicalPart part, IFigure figure) { - if (figure instanceof PlusMinusFigure) { - PlusMinusFigure pmFigure = (PlusMinusFigure) figure; - if (part instanceof IPlusMinusPart) { - IPlusMinusPart pm = (IPlusMinusPart) part; - decorate(pm, pmFigure); - } - } - } - - protected void decorate(IPlusMinusPart pm, PlusMinusFigure figure) { - IBranchPart branch = pm.getOwnerBranch(); - if (branch != null) { - figure.setValue(branch.isFolded()); - figure.setBorderValue(branch.getConnections().getLineColor()); - boolean canFold = branch.isPropertyModifiable(Core.TopicFolded); - if (canFold) { - Properties properties = getProperties(pm); - if (properties != null) { - - boolean isPlus = figure.getValue(); - boolean plusVisible = properties - .getBoolean(IMindMapViewer.PLUS_VISIBLE, true); - boolean minusVisible = properties - .getBoolean(IMindMapViewer.MINUS_VISIBLE, true); - boolean visible = (isPlus && plusVisible) - || (!isPlus && minusVisible); - - figure.setVisible(visible); - } - } else { - figure.setVisible(false); - } - } else { - figure.setValue(false); - } - } - - private Properties getProperties(IPlusMinusPart pm) { - if (pm == null) { - return null; - } - IPart parent = pm.getParent(); - while (parent != null && !(parent instanceof IRootPart)) { - parent = parent.getParent(); - } - if (parent != null) { - IViewer viewer = ((IRootPart) parent).getViewer(); - if (viewer != null) { - return viewer.getProperties(); - } - } - return null; - } - - public static PlusMinusDecorator getInstance() { - return instance; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.xmind.core.Core; +import org.xmind.gef.IViewer; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.part.IRootPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.internal.figures.PlusMinusFigure; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.IPlusMinusPart; +import org.xmind.ui.style.Styles; + +public class PlusMinusDecorator extends Decorator { + + private static final PlusMinusDecorator instance = new PlusMinusDecorator(); + + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + figure.setMinimumSize(IMinimizable.DEFAULT_MIN_SIZE); + figure.setPreferredSize(new Dimension(Styles.PLUS_MINUS_HEIGHT, + Styles.PLUS_MINUS_HEIGHT)); + } + + public void decorate(IGraphicalPart part, IFigure figure) { + if (figure instanceof PlusMinusFigure) { + PlusMinusFigure pmFigure = (PlusMinusFigure) figure; + if (part instanceof IPlusMinusPart) { + IPlusMinusPart pm = (IPlusMinusPart) part; + decorate(pm, pmFigure); + } + } + } + + protected void decorate(IPlusMinusPart pm, PlusMinusFigure figure) { + IBranchPart branch = pm.getOwnerBranch(); + if (branch != null) { + figure.setValue(branch.isFolded()); + figure.setBorderValue(branch.getConnections().getLineColor()); + boolean canFold = branch.isPropertyModifiable(Core.TopicFolded); + if (canFold) { + Properties properties = getProperties(pm); + if (properties != null) { + + boolean isPlus = figure.getValue(); + boolean plusVisible = properties + .getBoolean(IMindMapViewer.PLUS_VISIBLE, true); + boolean minusVisible = properties + .getBoolean(IMindMapViewer.MINUS_VISIBLE, true); + boolean visible = (isPlus && plusVisible) + || (!isPlus && minusVisible); + + figure.setVisible(visible); + } + } else { + figure.setVisible(false); + } + } else { + figure.setValue(false); + } + } + + private Properties getProperties(IPlusMinusPart pm) { + if (pm == null) { + return null; + } + IPart parent = pm.getParent(); + while (parent != null && !(parent instanceof IRootPart)) { + parent = parent.getParent(); + } + if (parent != null) { + IViewer viewer = ((IRootPart) parent).getViewer(); + if (viewer != null) { + return viewer.getProperties(); + } + } + return null; + } + + public static PlusMinusDecorator getInstance() { + return instance; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelTitleTextDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelTitleTextDecorator.java index f1065adec..b75f770d0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelTitleTextDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelTitleTextDecorator.java @@ -1,138 +1,138 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import org.eclipse.draw2d.ColorConstants; -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.graphics.Color; -import org.xmind.core.ITitled; -import org.xmind.gef.IViewer; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.IUseTransparency; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IRelationshipPart; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; - -public class RelTitleTextDecorator extends TitleTextDecorator { - - private static final RelTitleTextDecorator instance = new RelTitleTextDecorator(); - -// private static class RoundedRectBorder extends AbstractBackground { -// -// public void paintBackground(IFigure figure, Graphics graphics, -// Insets insets) { -// Rectangle r = getPaintRectangle(figure, insets); -// Path p = new Path(Display.getCurrent()); -// p.addRoundedRectangle(r, 5); -// if (figure instanceof IUseTransparency) { -// graphics.setAlpha(((IUseTransparency) figure).getSubAlpha()); -// } -// graphics.setBackgroundColor(figure.getBackgroundColor()); -// graphics.fillPath(p); -// p.dispose(); -// } -// -// } - - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - //figure.setBorder(new RoundedRectBorder()); - } - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); -// Rectangle b = getTitleBounds(part, figure); -// if (b != null) { -// figure.setBounds(b); -// } - } - -// private Rectangle getTitleBounds(IGraphicalPart part, IFigure figure) { -// if (part.getParent() instanceof IGraphicalPart) { -// IGraphicalPart parent = (IGraphicalPart) part.getParent(); -// IFigure container = parent.getFigure(); -// if (container instanceof DecoratedConnectionFigure) { -// IConnectionDecorationEx dec = ((DecoratedConnectionFigure) container) -// .getDecoration(); -// if (dec instanceof IRelationshipDecoration) { -// Point p = ((IRelationshipDecoration) dec).getTitlePosition( -// container).toDraw2DPoint(); -// Rectangle r = new Rectangle(); -// if (figure instanceof IReferencedFigure) { -// ((IReferencedFigure) figure).getPreferredBounds(r, p); -// } else { -// Dimension size = figure.getPreferredSize(); -// r.setSize(size); -// r.setLocation(p.x - size.width / 2, p.y - size.height -// / 2); -// } -// return r; -// } -// } -// Dimension titleSize = figure.getPreferredSize(); -// Rectangle relBounds = container.getBounds(); -// return new Rectangle(relBounds.x, relBounds.y, titleSize.width, -// titleSize.height); -// } -// return null; -// } - - protected boolean hasTitle(ITitled titled) { - return super.hasTitle(titled) && !"".equals(titled.getTitleText()); //$NON-NLS-1$ - } - - protected String getUntitledText(IGraphicalPart part, ITitled titled) { - return MindMapMessages.TitleText_Relationship; - } - - protected void decorateTextFigure(IGraphicalPart ownerPart, - IStyleSelector ss, ITextFigure figure) { - super.decorateTextFigure(ownerPart, ss, figure); - figure.setBackgroundColor(getFillColor(ownerPart, ss)); - if (figure instanceof IUseTransparency) { - ((IUseTransparency) figure).setSubAlpha(getAlpha(ownerPart, ss)); - } - } - - protected Color getFillColor(IGraphicalPart part, IStyleSelector ss) { - IViewer viewer = part.getSite().getViewer(); - if (viewer != null) { - ISheetPart sheet = (ISheetPart) viewer.getAdapter(ISheetPart.class); - if (sheet != null) { - IStyleSelector sss = StyleUtils.getStyleSelector(sheet); - return StyleUtils.getColor(sheet, sss, Styles.FillColor, null, - Styles.DEF_REL_TITLE_FILL_COLOR); - } - } - return ColorConstants.white; - } - - protected int getAlpha(IGraphicalPart part, IStyleSelector ss) { - return 0xf0; - } - - protected IGraphicalPart getOwnerPart(IGraphicalPart part) { - if (part.getParent() instanceof IRelationshipPart) - return (IRelationshipPart) part.getParent(); - return super.getOwnerPart(part); - } - - public static RelTitleTextDecorator getInstance() { - return instance; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.graphics.Color; +import org.xmind.core.ITitled; +import org.xmind.gef.IViewer; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.IUseTransparency; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IRelationshipPart; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; + +public class RelTitleTextDecorator extends TitleTextDecorator { + + private static final RelTitleTextDecorator instance = new RelTitleTextDecorator(); + +// private static class RoundedRectBorder extends AbstractBackground { +// +// public void paintBackground(IFigure figure, Graphics graphics, +// Insets insets) { +// Rectangle r = getPaintRectangle(figure, insets); +// Path p = new Path(Display.getCurrent()); +// p.addRoundedRectangle(r, 5); +// if (figure instanceof IUseTransparency) { +// graphics.setAlpha(((IUseTransparency) figure).getSubAlpha()); +// } +// graphics.setBackgroundColor(figure.getBackgroundColor()); +// graphics.fillPath(p); +// p.dispose(); +// } +// +// } + + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + //figure.setBorder(new RoundedRectBorder()); + } + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); +// Rectangle b = getTitleBounds(part, figure); +// if (b != null) { +// figure.setBounds(b); +// } + } + +// private Rectangle getTitleBounds(IGraphicalPart part, IFigure figure) { +// if (part.getParent() instanceof IGraphicalPart) { +// IGraphicalPart parent = (IGraphicalPart) part.getParent(); +// IFigure container = parent.getFigure(); +// if (container instanceof DecoratedConnectionFigure) { +// IConnectionDecorationEx dec = ((DecoratedConnectionFigure) container) +// .getDecoration(); +// if (dec instanceof IRelationshipDecoration) { +// Point p = ((IRelationshipDecoration) dec).getTitlePosition( +// container).toDraw2DPoint(); +// Rectangle r = new Rectangle(); +// if (figure instanceof IReferencedFigure) { +// ((IReferencedFigure) figure).getPreferredBounds(r, p); +// } else { +// Dimension size = figure.getPreferredSize(); +// r.setSize(size); +// r.setLocation(p.x - size.width / 2, p.y - size.height +// / 2); +// } +// return r; +// } +// } +// Dimension titleSize = figure.getPreferredSize(); +// Rectangle relBounds = container.getBounds(); +// return new Rectangle(relBounds.x, relBounds.y, titleSize.width, +// titleSize.height); +// } +// return null; +// } + + protected boolean hasTitle(ITitled titled) { + return super.hasTitle(titled) && !"".equals(titled.getTitleText()); //$NON-NLS-1$ + } + + protected String getUntitledText(IGraphicalPart part, ITitled titled) { + return MindMapMessages.TitleText_Relationship; + } + + protected void decorateTextFigure(IGraphicalPart ownerPart, + IStyleSelector ss, ITextFigure figure) { + super.decorateTextFigure(ownerPart, ss, figure); + figure.setBackgroundColor(getFillColor(ownerPart, ss)); + if (figure instanceof IUseTransparency) { + ((IUseTransparency) figure).setSubAlpha(getAlpha(ownerPart, ss)); + } + } + + protected Color getFillColor(IGraphicalPart part, IStyleSelector ss) { + IViewer viewer = part.getSite().getViewer(); + if (viewer != null) { + ISheetPart sheet = (ISheetPart) viewer.getAdapter(ISheetPart.class); + if (sheet != null) { + IStyleSelector sss = StyleUtils.getStyleSelector(sheet); + return StyleUtils.getColor(sheet, sss, Styles.FillColor, null, + Styles.DEF_REL_TITLE_FILL_COLOR); + } + } + return ColorConstants.white; + } + + protected int getAlpha(IGraphicalPart part, IStyleSelector ss) { + return 0xf0; + } + + protected IGraphicalPart getOwnerPart(IGraphicalPart part) { + if (part.getParent() instanceof IRelationshipPart) + return (IRelationshipPart) part.getParent(); + return super.getOwnerPart(part); + } + + public static RelTitleTextDecorator getInstance() { + return instance; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelationshipDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelationshipDecorator.java index e6f6b0cdd..796ee2f39 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelationshipDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/RelationshipDecorator.java @@ -1,177 +1,177 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import static org.xmind.ui.style.StyleUtils.createArrowDecoration; -import static org.xmind.ui.style.StyleUtils.createRelationshipDecoration; -import static org.xmind.ui.style.StyleUtils.getColor; -import static org.xmind.ui.style.StyleUtils.getInteger; -import static org.xmind.ui.style.StyleUtils.getLineStyle; -import static org.xmind.ui.style.StyleUtils.getString; -import static org.xmind.ui.style.StyleUtils.getStyleSelector; -import static org.xmind.ui.style.StyleUtils.isSameDecoration; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.SWT; -import org.xmind.core.IControlPoint; -import org.xmind.core.IRelationship; -import org.xmind.gef.draw2d.IAnchor; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.decorations.IArrowDecoration; -import org.xmind.ui.decorations.IRelationshipDecoration; -import org.xmind.ui.internal.figures.RelationshipFigure; -import org.xmind.ui.mindmap.INodePart; -import org.xmind.ui.mindmap.IRelationshipPart; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.MindMapUtils; - -public class RelationshipDecorator extends Decorator { - - private static final RelationshipDecorator instance = new RelationshipDecorator(); - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - if (figure instanceof RelationshipFigure) { - decorateRelationship(part, (RelationshipFigure) figure); - } - } - - @Override - public void deactivate(IGraphicalPart part, IFigure figure) { - if (figure instanceof RelationshipFigure) { - RelationshipFigure rf = (RelationshipFigure) figure; - rf.setSourceAnchor(null); - rf.setTargetAnchor(null); - } - super.deactivate(part, figure); - } - - private void decorateRelationship(IGraphicalPart part, - RelationshipFigure figure) { - decorateRelationship(part, getStyleSelector(part), figure); - } - - private void decorateRelationship(IGraphicalPart part, IStyleSelector ss, - RelationshipFigure figure) { - IRelationshipDecoration decoration = figure.getDecoration(); - String newId = getString(part, ss, Styles.ShapeClass, - Styles.REL_SHAPE_STRAIGHT); - if (!isSameDecoration(decoration, newId)) { - decoration = createRelationshipDecoration(part, newId); - figure.setDecoration(decoration); - } - if (decoration != null) { - String decorationId = decoration.getId(); - decoration.setAlpha(figure, 0xff); - decoration.setLineColor(figure, getColor(part, ss, Styles.LineColor, - decorationId, Styles.DEF_REL_LINE_COLOR)); - decoration.setLineStyle(figure, - getLineStyle(part, ss, decorationId, SWT.LINE_DASH)); - decoration.setLineWidth(figure, - getInteger(part, ss, Styles.LineWidth, decorationId, 3)); - - decorateAnchors(part, figure, decoration); - - Object m = MindMapUtils.getRealModel(part); - if (m instanceof IRelationship) { - IRelationship r = (IRelationship) m; - decorateControlPoints(r, figure, decoration); - } - - decorateArrows(part, ss, figure, decoration); - - decoration.setVisible(figure, - decoration.getSourceAnchor() != null - && decoration.getTargetAnchor() != null - && figure.isVisible()); - - decoration.reroute(figure); - figure.setBounds(decoration.getPreferredBounds(figure)); - } - } - - private void decorateAnchors(IGraphicalPart part, RelationshipFigure figure, - IRelationshipDecoration decoration) { - if (part instanceof IRelationshipPart) { - IRelationshipPart rel = (IRelationshipPart) part; - INodePart sourceNode = rel.getSourceNode(); - IAnchor anchor = sourceNode == null ? null - : sourceNode.getSourceAnchor(rel); - figure.setSourceAnchor(anchor); - INodePart targetNode = rel.getTargetNode(); - anchor = targetNode == null ? null - : targetNode.getTargetAnchor(rel); - figure.setTargetAnchor(anchor); - figure.setVisible(sourceNode != null - && sourceNode.getFigure().isShowing() && targetNode != null - && targetNode.getFigure().isShowing()); - } - } - - private void decorateArrows(IGraphicalPart part, IStyleSelector ss, - RelationshipFigure figure, IRelationshipDecoration decoration) { - IArrowDecoration arrow1 = decoration.getArrow1(); - String newArrow1Id = getString(part, ss, Styles.ArrowBeginClass, - Styles.ARROW_SHAPE_DOT); - if (!isSameDecoration(arrow1, newArrow1Id)) { - arrow1 = createArrowDecoration(part, newArrow1Id); - decoration.setArrow1(figure, arrow1); - } - if (arrow1 != null) { - decorateArrow(part, figure, decoration, arrow1); - } - - IArrowDecoration arrow2 = decoration.getArrow2(); - String newArrow2Id = getString(part, ss, Styles.ArrowEndClass, - Styles.ARROW_SHAPE_NORMAL); - if (!isSameDecoration(arrow2, newArrow2Id)) { - arrow2 = createArrowDecoration(part, newArrow2Id); - decoration.setArrow2(figure, arrow2); - } - if (arrow2 != null) { - decorateArrow(part, figure, decoration, arrow2); - } - } - - private void decorateArrow(IGraphicalPart part, RelationshipFigure figure, - IRelationshipDecoration decoration, IArrowDecoration arrow) { - arrow.setColor(figure, decoration.getLineColor()); - arrow.setWidth(figure, decoration.getLineWidth()); - } - - private void decorateControlPoints(IRelationship r, - RelationshipFigure figure, IRelationshipDecoration decoration) { - if (r != null) { - IControlPoint cp0 = r.getControlPoint(0); - decoration.setRelativeSourceControlPoint(figure, - MindMapUtils.toGraphicalPosition(cp0.getPosition())); - Double angle = cp0 == null ? null : cp0.getPolarAngle(); - Double amount = cp0 == null ? null : cp0.getPolarAmount(); - decoration.setSourceControlPointHint(figure, angle, amount); - - IControlPoint cp1 = r.getControlPoint(1); - decoration.setRelativeTargetControlPoint(figure, - MindMapUtils.toGraphicalPosition(cp1.getPosition())); - angle = cp1 == null ? null : cp1.getPolarAngle(); - amount = cp1 == null ? null : cp1.getPolarAmount(); - decoration.setTargetControlPointHint(figure, angle, amount); - } - } - - public static RelationshipDecorator getInstance() { - return instance; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import static org.xmind.ui.style.StyleUtils.createArrowDecoration; +import static org.xmind.ui.style.StyleUtils.createRelationshipDecoration; +import static org.xmind.ui.style.StyleUtils.getColor; +import static org.xmind.ui.style.StyleUtils.getInteger; +import static org.xmind.ui.style.StyleUtils.getLineStyle; +import static org.xmind.ui.style.StyleUtils.getString; +import static org.xmind.ui.style.StyleUtils.getStyleSelector; +import static org.xmind.ui.style.StyleUtils.isSameDecoration; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.SWT; +import org.xmind.core.IControlPoint; +import org.xmind.core.IRelationship; +import org.xmind.gef.draw2d.IAnchor; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.decorations.IArrowDecoration; +import org.xmind.ui.decorations.IRelationshipDecoration; +import org.xmind.ui.internal.figures.RelationshipFigure; +import org.xmind.ui.mindmap.INodePart; +import org.xmind.ui.mindmap.IRelationshipPart; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.MindMapUtils; + +public class RelationshipDecorator extends Decorator { + + private static final RelationshipDecorator instance = new RelationshipDecorator(); + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + if (figure instanceof RelationshipFigure) { + decorateRelationship(part, (RelationshipFigure) figure); + } + } + + @Override + public void deactivate(IGraphicalPart part, IFigure figure) { + if (figure instanceof RelationshipFigure) { + RelationshipFigure rf = (RelationshipFigure) figure; + rf.setSourceAnchor(null); + rf.setTargetAnchor(null); + } + super.deactivate(part, figure); + } + + private void decorateRelationship(IGraphicalPart part, + RelationshipFigure figure) { + decorateRelationship(part, getStyleSelector(part), figure); + } + + private void decorateRelationship(IGraphicalPart part, IStyleSelector ss, + RelationshipFigure figure) { + IRelationshipDecoration decoration = figure.getDecoration(); + String newId = getString(part, ss, Styles.ShapeClass, + Styles.REL_SHAPE_STRAIGHT); + if (!isSameDecoration(decoration, newId)) { + decoration = createRelationshipDecoration(part, newId); + figure.setDecoration(decoration); + } + if (decoration != null) { + String decorationId = decoration.getId(); + decoration.setAlpha(figure, 0xff); + decoration.setLineColor(figure, getColor(part, ss, Styles.LineColor, + decorationId, Styles.DEF_REL_LINE_COLOR)); + decoration.setLineStyle(figure, + getLineStyle(part, ss, decorationId, SWT.LINE_DASH)); + decoration.setLineWidth(figure, + getInteger(part, ss, Styles.LineWidth, decorationId, 3)); + + decorateAnchors(part, figure, decoration); + + Object m = MindMapUtils.getRealModel(part); + if (m instanceof IRelationship) { + IRelationship r = (IRelationship) m; + decorateControlPoints(r, figure, decoration); + } + + decorateArrows(part, ss, figure, decoration); + + decoration.setVisible(figure, + decoration.getSourceAnchor() != null + && decoration.getTargetAnchor() != null + && figure.isVisible()); + + decoration.reroute(figure); + figure.setBounds(decoration.getPreferredBounds(figure)); + } + } + + private void decorateAnchors(IGraphicalPart part, RelationshipFigure figure, + IRelationshipDecoration decoration) { + if (part instanceof IRelationshipPart) { + IRelationshipPart rel = (IRelationshipPart) part; + INodePart sourceNode = rel.getSourceNode(); + IAnchor anchor = sourceNode == null ? null + : sourceNode.getSourceAnchor(rel); + figure.setSourceAnchor(anchor); + INodePart targetNode = rel.getTargetNode(); + anchor = targetNode == null ? null + : targetNode.getTargetAnchor(rel); + figure.setTargetAnchor(anchor); + figure.setVisible(sourceNode != null + && sourceNode.getFigure().isShowing() && targetNode != null + && targetNode.getFigure().isShowing()); + } + } + + private void decorateArrows(IGraphicalPart part, IStyleSelector ss, + RelationshipFigure figure, IRelationshipDecoration decoration) { + IArrowDecoration arrow1 = decoration.getArrow1(); + String newArrow1Id = getString(part, ss, Styles.ArrowBeginClass, + Styles.ARROW_SHAPE_DOT); + if (!isSameDecoration(arrow1, newArrow1Id)) { + arrow1 = createArrowDecoration(part, newArrow1Id); + decoration.setArrow1(figure, arrow1); + } + if (arrow1 != null) { + decorateArrow(part, figure, decoration, arrow1); + } + + IArrowDecoration arrow2 = decoration.getArrow2(); + String newArrow2Id = getString(part, ss, Styles.ArrowEndClass, + Styles.ARROW_SHAPE_NORMAL); + if (!isSameDecoration(arrow2, newArrow2Id)) { + arrow2 = createArrowDecoration(part, newArrow2Id); + decoration.setArrow2(figure, arrow2); + } + if (arrow2 != null) { + decorateArrow(part, figure, decoration, arrow2); + } + } + + private void decorateArrow(IGraphicalPart part, RelationshipFigure figure, + IRelationshipDecoration decoration, IArrowDecoration arrow) { + arrow.setColor(figure, decoration.getLineColor()); + arrow.setWidth(figure, decoration.getLineWidth()); + } + + private void decorateControlPoints(IRelationship r, + RelationshipFigure figure, IRelationshipDecoration decoration) { + if (r != null) { + IControlPoint cp0 = r.getControlPoint(0); + decoration.setRelativeSourceControlPoint(figure, + MindMapUtils.toGraphicalPosition(cp0.getPosition())); + Double angle = cp0 == null ? null : cp0.getPolarAngle(); + Double amount = cp0 == null ? null : cp0.getPolarAmount(); + decoration.setSourceControlPointHint(figure, angle, amount); + + IControlPoint cp1 = r.getControlPoint(1); + decoration.setRelativeTargetControlPoint(figure, + MindMapUtils.toGraphicalPosition(cp1.getPosition())); + angle = cp1 == null ? null : cp1.getPolarAngle(); + amount = cp1 == null ? null : cp1.getPolarAmount(); + decoration.setTargetControlPointHint(figure, angle, amount); + } + } + + public static RelationshipDecorator getInstance() { + return instance; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SheetDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SheetDecorator.java index d40a272d3..a39e77f7a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SheetDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SheetDecorator.java @@ -1,288 +1,290 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.Layer; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.internal.AttachmentImageDescriptor; -import org.xmind.ui.internal.layers.BackgroundLayer; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.MindMapUtils; - -public class SheetDecorator extends Decorator { - - private static final SheetDecorator instance = new SheetDecorator(); - - private static final String CACHE_WALLPAPER_KEY = "org.xmind.ui.cache.wallpaperKey"; //$NON-NLS-1$ - - protected static class WallpaperImageRegistry { - private static class Entry { - - ImageDescriptor imageDescriptor; - - Image image; - - Set hosts; - - public Entry(ImageDescriptor key) { - this.imageDescriptor = key; - } - - public Image getImage(IGraphicalPart host) { - if (hosts == null) - hosts = new HashSet(); - hosts.add(host); - if (image == null) { - image = imageDescriptor.createImage(false); - } - return image; - } - - public void remove(IGraphicalPart host) { - if (hosts != null) - hosts.remove(host); - } - - public boolean isEmpty() { - return hosts == null || hosts.isEmpty(); - } - - public void dispose() { - if (image != null) { - image.dispose(); - image = null; - } - } - - } - - private Map map = new HashMap(); - - public Image getImage(IGraphicalPart host, IStyleSelector ss) { - Object oldKey = MindMapUtils.getCache(host, CACHE_WALLPAPER_KEY); - Object newKey = generateKey(host, ss); - MindMapUtils.setCache(host, CACHE_WALLPAPER_KEY, newKey); - if (oldKey != null && !oldKey.equals(newKey)) { - remove(host, oldKey); - } - if (newKey != null) { - Entry entry = map.get(newKey); - if (entry == null) { - if (newKey instanceof ImageDescriptor) { - entry = new Entry((ImageDescriptor) newKey); - } else if (newKey instanceof String) { - ImageDescriptor entryKey = null; - try { - entryKey = ImageDescriptor.createFromURL(new URL( - (String) newKey)); - } catch (MalformedURLException e) { - entryKey = ImageDescriptor - .getMissingImageDescriptor(); - } - entry = new Entry(entryKey); - } - map.put(newKey, entry); - } - if (entry != null) - return entry.getImage(host); - } - - return null; - } - - private Object generateKey(IGraphicalPart host, IStyleSelector ss) { - String value = ss.getStyleValue(host, Styles.Background); - if (value != null) { - if (HyperlinkUtils.isAttachmentURL(value)) { - String attachmentPath = HyperlinkUtils - .toAttachmentPath(value); - IWorkbook workbook = getWorkbook(host); - return AttachmentImageDescriptor.createFromEntryPath( - workbook, attachmentPath); - } else if (HyperlinkUtils.isInternalAttachmentURL(value)) { - return value; - } - } - return null; - } - - public void removeHost(IGraphicalPart host, IStyleSelector ss) { - Object key = generateKey(host, ss); - if (key != null) { - remove(host, key); - } - } - - private void remove(IGraphicalPart host, Object key) { - Entry entry = map.get(key); - if (entry != null) { - entry.remove(host); - if (entry.isEmpty()) { - map.remove(key); - entry.dispose(); - } - } - } - - private IWorkbook getWorkbook(IGraphicalPart host) { - IViewer viewer = host.getSite().getViewer(); - if (viewer instanceof IMindMapViewer) { - ISheet sheet = ((IMindMapViewer) viewer).getSheet(); - if (sheet != null) - return sheet.getOwnedWorkbook(); - } - return null; - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - } - - private WallpaperImageRegistry imageRegistry = null; - - private Map partToWrapImage = new HashMap(); - - protected SheetDecorator() { - } - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - IStyleSelector ss = StyleUtils.getStyleSelector(part); - decorateSheet(part, ss, figure); - } - - private void decorateSheet(IGraphicalPart part, IStyleSelector ss, - IFigure figure) { - IGraphicalViewer viewer = (IGraphicalViewer) part.getSite().getViewer(); - Layer layer = viewer.getLayer(GEF.LAYER_BACKGROUND); - if (layer != null) { - decorateBackground(part, ss, layer); - } - } - - private void decorateBackground(IGraphicalPart part, IStyleSelector ss, - Layer layer) { - layer.setBackgroundColor(getBackgroundColor(part, ss)); - - if (layer instanceof BackgroundLayer) { - BackgroundLayer bgLayer = (BackgroundLayer) layer; - Pattern newWallpaper = getWallpaper(part, ss); - Pattern oldWallpaper = bgLayer.getWallpaper(); - if (oldWallpaper != null) { - oldWallpaper.dispose(); - } - bgLayer.setWallpaper(newWallpaper); - bgLayer.setSubAlpha(getWallpaperAlpha(part, ss)); - } - } - - private Color getBackgroundColor(IGraphicalPart part, IStyleSelector ss) { - return StyleUtils.getColor(part, ss, Styles.FillColor, null, - Styles.DEF_SHEET_FILL_COLOR); - } - - private int getWallpaperAlpha(IGraphicalPart part, IStyleSelector ss) { - double opacity = StyleUtils.getDouble(part, ss, Styles.Opacity, 0.8); - return (int) Math.round(opacity * 255); - } - - /** - * Create a new wallpaper pattern or return no pattern. - * - * @param part - * @param ss - * @return - */ - private Pattern getWallpaper(IGraphicalPart part, IStyleSelector ss) { - Image image = getWallpaperImage(part, ss); - Image wrapImage = partToWrapImage.get(part); - if (wrapImage != null) { - wrapImage.dispose(); - wrapImage = null; - } - if (image != null) { - Rectangle b = image.getBounds(); - wrapImage = new Image(null, b.width, b.height); - - GC gc = new GC(wrapImage); - gc.setBackground(getBackgroundColor(part, ss)); - gc.fillRectangle(b); - - gc.drawImage(image, b.x, b.y); - gc.dispose(); - } - partToWrapImage.put(part, wrapImage); - - return wrapImage == null ? null : new Pattern(Display.getCurrent(), - wrapImage); - } - - private Image getWallpaperImage(IGraphicalPart part, IStyleSelector ss) { - if (imageRegistry == null) - imageRegistry = new WallpaperImageRegistry(); - return imageRegistry.getImage(part, ss); - } - - public void deactivate(IGraphicalPart part, IFigure figure) { - IGraphicalViewer viewer = (IGraphicalViewer) part.getSite().getViewer(); - Layer layer = viewer.getLayer(GEF.LAYER_BACKGROUND); - if (layer instanceof BackgroundLayer) { - Pattern wallpaper = ((BackgroundLayer) layer).getWallpaper(); - if (wallpaper != null) { - wallpaper.dispose(); - } - ((BackgroundLayer) layer).setWallpaper(null); - } - Image wrapImage = partToWrapImage.get(part); - if (wrapImage != null) { - wrapImage.dispose(); - wrapImage = null; - } - if (imageRegistry != null) { - imageRegistry.removeHost(part, StyleUtils.getStyleSelector(part)); - } - super.deactivate(part, figure); - } - - public static SheetDecorator getInstance() { - return instance; - } -} \ No newline at end of file +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.internal.AttachmentImageDescriptor; +import org.xmind.ui.internal.layers.BackgroundLayer; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.MindMapUtils; + +public class SheetDecorator extends Decorator { + + private static final SheetDecorator instance = new SheetDecorator(); + + private static final String CACHE_WALLPAPER_KEY = "org.xmind.ui.cache.wallpaperKey"; //$NON-NLS-1$ + + protected static class WallpaperImageRegistry { + private static class Entry { + + ImageDescriptor imageDescriptor; + + Image image; + + Set hosts; + + public Entry(ImageDescriptor key) { + this.imageDescriptor = key; + } + + public Image getImage(IGraphicalPart host) { + if (hosts == null) + hosts = new HashSet(); + hosts.add(host); + if (image == null) { + image = imageDescriptor.createImage(false); + } + return image; + } + + public void remove(IGraphicalPart host) { + if (hosts != null) + hosts.remove(host); + } + + public boolean isEmpty() { + return hosts == null || hosts.isEmpty(); + } + + public void dispose() { + if (image != null) { + image.dispose(); + image = null; + } + } + + } + + private Map map = new HashMap(); + + public Image getImage(IGraphicalPart host, IStyleSelector ss) { + Object oldKey = MindMapUtils.getCache(host, CACHE_WALLPAPER_KEY); + Object newKey = generateKey(host, ss); + MindMapUtils.setCache(host, CACHE_WALLPAPER_KEY, newKey); + if (oldKey != null && !oldKey.equals(newKey)) { + remove(host, oldKey); + } + if (newKey != null) { + Entry entry = map.get(newKey); + if (entry == null) { + if (newKey instanceof ImageDescriptor) { + entry = new Entry((ImageDescriptor) newKey); + } else if (newKey instanceof String) { + ImageDescriptor entryKey = null; + try { + entryKey = ImageDescriptor + .createFromURL(new URL((String) newKey)); + } catch (MalformedURLException e) { + entryKey = ImageDescriptor + .getMissingImageDescriptor(); + } + entry = new Entry(entryKey); + } + map.put(newKey, entry); + } + if (entry != null) + return entry.getImage(host); + } + + return null; + } + + private Object generateKey(IGraphicalPart host, IStyleSelector ss) { + String value = ss.getStyleValue(host, Styles.Background); + if (value != null) { + if (HyperlinkUtils.isAttachmentURL(value)) { + String attachmentPath = HyperlinkUtils + .toAttachmentPath(value); + IWorkbook workbook = getWorkbook(host); + return AttachmentImageDescriptor + .createFromEntryPath(workbook, attachmentPath); + } else if (HyperlinkUtils.isInternalAttachmentURL(value)) { + return value; + } + } + return null; + } + + public void removeHost(IGraphicalPart host, IStyleSelector ss) { + Object key = generateKey(host, ss); + if (key != null) { + remove(host, key); + } + } + + private void remove(IGraphicalPart host, Object key) { + Entry entry = map.get(key); + if (entry != null) { + entry.remove(host); + if (entry.isEmpty()) { + map.remove(key); + entry.dispose(); + } + } + } + + private IWorkbook getWorkbook(IGraphicalPart host) { + IViewer viewer = host.getSite().getViewer(); + if (viewer instanceof IMindMapViewer) { + ISheet sheet = ((IMindMapViewer) viewer).getSheet(); + if (sheet != null) + return sheet.getOwnedWorkbook(); + } + return null; + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + } + + private WallpaperImageRegistry imageRegistry = null; + + private Map partToWrapImage = new HashMap(); + + protected SheetDecorator() { + } + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + IStyleSelector ss = StyleUtils.getStyleSelector(part); + decorateSheet(part, ss, figure); + } + + private void decorateSheet(IGraphicalPart part, IStyleSelector ss, + IFigure figure) { + IGraphicalViewer viewer = (IGraphicalViewer) part.getSite().getViewer(); + Layer layer = viewer.getLayer(GEF.LAYER_BACKGROUND); + if (layer != null) { + decorateBackground(part, ss, layer); + } + } + + private void decorateBackground(IGraphicalPart part, IStyleSelector ss, + Layer layer) { + Color backgroundColor = getBackgroundColor(part, ss); + if (backgroundColor != null) + layer.setBackgroundColor(backgroundColor); + + if (layer instanceof BackgroundLayer) { + BackgroundLayer bgLayer = (BackgroundLayer) layer; + Pattern newWallpaper = getWallpaper(part, ss); + Pattern oldWallpaper = bgLayer.getWallpaper(); + if (oldWallpaper != null) { + oldWallpaper.dispose(); + } + bgLayer.setWallpaper(newWallpaper); + bgLayer.setSubAlpha(getWallpaperAlpha(part, ss)); + } + } + + private Color getBackgroundColor(IGraphicalPart part, IStyleSelector ss) { + return StyleUtils.getColor(part, ss, Styles.FillColor, null, + Styles.DEF_SHEET_FILL_COLOR); + } + + private int getWallpaperAlpha(IGraphicalPart part, IStyleSelector ss) { + double opacity = StyleUtils.getDouble(part, ss, Styles.Opacity, 0.8); + return (int) Math.round(opacity * 255); + } + + /** + * Create a new wallpaper pattern or return no pattern. + * + * @param part + * @param ss + * @return + */ + private Pattern getWallpaper(IGraphicalPart part, IStyleSelector ss) { + Image image = getWallpaperImage(part, ss); + Image wrapImage = partToWrapImage.get(part); + if (wrapImage != null) { + wrapImage.dispose(); + wrapImage = null; + } + if (image != null) { + Rectangle b = image.getBounds(); + wrapImage = new Image(null, b.width, b.height); + + GC gc = new GC(wrapImage); + gc.setBackground(getBackgroundColor(part, ss)); + gc.fillRectangle(b); + + gc.drawImage(image, b.x, b.y); + gc.dispose(); + } + partToWrapImage.put(part, wrapImage); + + return wrapImage == null ? null + : new Pattern(Display.getCurrent(), wrapImage); + } + + private Image getWallpaperImage(IGraphicalPart part, IStyleSelector ss) { + if (imageRegistry == null) + imageRegistry = new WallpaperImageRegistry(); + return imageRegistry.getImage(part, ss); + } + + public void deactivate(IGraphicalPart part, IFigure figure) { + IGraphicalViewer viewer = (IGraphicalViewer) part.getSite().getViewer(); + Layer layer = viewer.getLayer(GEF.LAYER_BACKGROUND); + if (layer instanceof BackgroundLayer) { + Pattern wallpaper = ((BackgroundLayer) layer).getWallpaper(); + if (wallpaper != null) { + wallpaper.dispose(); + } + ((BackgroundLayer) layer).setWallpaper(null); + } + Image wrapImage = partToWrapImage.remove(part); + if (wrapImage != null) { + wrapImage.dispose(); + wrapImage = null; + } + if (imageRegistry != null) { + imageRegistry.removeHost(part, StyleUtils.getStyleSelector(part)); + } + super.deactivate(part, figure); + } + + public static SheetDecorator getInstance() { + return instance; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TitleTextDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TitleTextDecorator.java index d928077c8..6d240853d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TitleTextDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TitleTextDecorator.java @@ -1,147 +1,147 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import static org.xmind.ui.style.StyleUtils.getAlign; -import static org.xmind.ui.style.StyleUtils.getCompositeFont; -import static org.xmind.ui.style.StyleUtils.getTextStyle; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.graphics.TextStyle; -import org.xmind.core.ITitled; -import org.xmind.gef.GEF; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.MindMapUtils; - -public class TitleTextDecorator extends Decorator { - - public void activate(IGraphicalPart part, IFigure figure) { - super.activate(part, figure); - figure.setMinimumSize(IMinimizable.DEFAULT_MIN_SIZE); - } - - public void decorate(IGraphicalPart part, IFigure figure) { - if (figure instanceof ITextFigure) { - ITextFigure textFigure = (ITextFigure) figure; - ITitled titled = getTitledModel(part); - String text = getText(part, titled); - if (text != null) - textFigure.setText(text); - textFigure.setVisible(isVisible(part, titled)); - decorateTextFigure(part, textFigure); - decorateTextAlignment(part, textFigure); - decorateTextCase(part, textFigure); - } - } - - private void decorateTextAlignment(IGraphicalPart part, - ITextFigure textFigure) { - // TODO Auto-generated method stub - IGraphicalPart parent = getOwnerPart(part); - if (parent != null) - part = parent; - decorateTextAlignment(part, StyleUtils.getStyleSelector(part), - textFigure); - } - - private void decorateTextAlignment(IGraphicalPart part, IStyleSelector ss, - ITextFigure textFigure) { - // TODO Auto-generated method stub - int align = getAlign(part, ss, null); - if (align != 0) - textFigure.setTextAlignment(align); - else - textFigure.setTextAlignment(PositionConstants.LEFT); - } - - private void decorateTextCase(IGraphicalPart part, ITextFigure textFigure) { - IGraphicalPart parent = getOwnerPart(part); - if (parent != null) - part = parent; - decorateTextCase(part, StyleUtils.getStyleSelector(part), textFigure); - } - - private void decorateTextCase(IGraphicalPart part, IStyleSelector ss, - ITextFigure textFigure) { - int textCase = StyleUtils.getCaseValue(part, ss, Styles.TextCase); - if (textCase != GEF.CASE_EMPTY) - textFigure.setTextCase(textCase); - else - textFigure.setTextCase(GEF.MANUAL); - } - - private ITitled getTitledModel(IGraphicalPart part) { - Object model = MindMapUtils.getRealModel(part); - if (model == null || !(model instanceof ITitled)) { - model = part.getAdapter(ITitled.class); - } - if (model instanceof ITitled) - return (ITitled) model; - return null; - } - - protected String getText(IGraphicalPart part, ITitled titled) { - if (titled != null) { - if (!hasTitle(titled)) - return getUntitledText(part, titled); - return titled.getTitleText(); - } - return null; - } - - protected boolean hasTitle(ITitled titled) { - return titled.hasTitle(); - } - - protected String getUntitledText(IGraphicalPart part, ITitled titled) { - return titled.getTitleText(); - } - - protected boolean isVisible(IGraphicalPart part, ITitled titled) { - return titled != null && hasTitle(titled); - } - - protected void decorateTextFigure(IGraphicalPart part, ITextFigure figure) { - IGraphicalPart parent = getOwnerPart(part); - if (parent != null) - part = parent; - decorateTextFigure(part, StyleUtils.getStyleSelector(part), figure); - } - - protected void decorateTextFigure(IGraphicalPart ownerPart, - IStyleSelector ss, ITextFigure figure) { - TextStyle style = getTextStyle(ownerPart, ss); - if (style != null) { - figure.setStyle(style); - } else { - figure.setFont(getCompositeFont(ownerPart, ss, - JFaceResources.getDefaultFont())); - figure.setForegroundColor(StyleUtils.getColor(ownerPart, ss, - Styles.TextColor, null, Styles.DEF_TEXT_COLOR)); - } - } - - protected IGraphicalPart getOwnerPart(IGraphicalPart part) { - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import static org.xmind.ui.style.StyleUtils.getAlign; +import static org.xmind.ui.style.StyleUtils.getCompositeFont; +import static org.xmind.ui.style.StyleUtils.getTextStyle; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.TextStyle; +import org.xmind.core.ITitled; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.MindMapUtils; + +public class TitleTextDecorator extends Decorator { + + public void activate(IGraphicalPart part, IFigure figure) { + super.activate(part, figure); + figure.setMinimumSize(IMinimizable.DEFAULT_MIN_SIZE); + } + + public void decorate(IGraphicalPart part, IFigure figure) { + if (figure instanceof ITextFigure) { + ITextFigure textFigure = (ITextFigure) figure; + ITitled titled = getTitledModel(part); + String text = getText(part, titled); + if (text != null) + textFigure.setText(text); + textFigure.setVisible(isVisible(part, titled)); + decorateTextFigure(part, textFigure); + decorateTextAlignment(part, textFigure); + decorateTextCase(part, textFigure); + } + } + + private void decorateTextAlignment(IGraphicalPart part, + ITextFigure textFigure) { + // TODO Auto-generated method stub + IGraphicalPart parent = getOwnerPart(part); + if (parent != null) + part = parent; + decorateTextAlignment(part, StyleUtils.getStyleSelector(part), + textFigure); + } + + private void decorateTextAlignment(IGraphicalPart part, IStyleSelector ss, + ITextFigure textFigure) { + // TODO Auto-generated method stub + int align = getAlign(part, ss, null); + if (align != 0) + textFigure.setTextAlignment(align); + else + textFigure.setTextAlignment(PositionConstants.LEFT); + } + + private void decorateTextCase(IGraphicalPart part, ITextFigure textFigure) { + IGraphicalPart parent = getOwnerPart(part); + if (parent != null) + part = parent; + decorateTextCase(part, StyleUtils.getStyleSelector(part), textFigure); + } + + private void decorateTextCase(IGraphicalPart part, IStyleSelector ss, + ITextFigure textFigure) { + int textCase = StyleUtils.getCaseValue(part, ss, Styles.TextCase); + if (textCase != GEF.CASE_EMPTY) + textFigure.setTextCase(textCase); + else + textFigure.setTextCase(GEF.MANUAL); + } + + private ITitled getTitledModel(IGraphicalPart part) { + Object model = MindMapUtils.getRealModel(part); + if (model == null || !(model instanceof ITitled)) { + model = part.getAdapter(ITitled.class); + } + if (model instanceof ITitled) + return (ITitled) model; + return null; + } + + protected String getText(IGraphicalPart part, ITitled titled) { + if (titled != null) { + if (!hasTitle(titled)) + return getUntitledText(part, titled); + return titled.getTitleText(); + } + return null; + } + + protected boolean hasTitle(ITitled titled) { + return titled.hasTitle(); + } + + protected String getUntitledText(IGraphicalPart part, ITitled titled) { + return titled.getTitleText(); + } + + protected boolean isVisible(IGraphicalPart part, ITitled titled) { + return titled != null && hasTitle(titled); + } + + protected void decorateTextFigure(IGraphicalPart part, ITextFigure figure) { + IGraphicalPart parent = getOwnerPart(part); + if (parent != null) + part = parent; + decorateTextFigure(part, StyleUtils.getStyleSelector(part), figure); + } + + protected void decorateTextFigure(IGraphicalPart ownerPart, + IStyleSelector ss, ITextFigure figure) { + TextStyle style = getTextStyle(ownerPart, ss); + if (style != null) { + figure.setStyle(style); + } else { + figure.setFont(getCompositeFont(ownerPart, ss, + JFaceResources.getDefaultFont())); + figure.setForegroundColor(StyleUtils.getColor(ownerPart, ss, + Styles.TextColor, null, Styles.DEF_TEXT_COLOR)); + } + } + + protected IGraphicalPart getOwnerPart(IGraphicalPart part) { + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TopicDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TopicDecorator.java index 2fee86436..736fb5697 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TopicDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/TopicDecorator.java @@ -1,188 +1,188 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.decorators; - -import static org.xmind.ui.style.StyleUtils.createTopicDecoration; -import static org.xmind.ui.style.StyleUtils.getColor; -import static org.xmind.ui.style.StyleUtils.getInteger; -import static org.xmind.ui.style.StyleUtils.getLineStyle; -import static org.xmind.ui.style.StyleUtils.getString; -import static org.xmind.ui.style.StyleUtils.getStyleSelector; -import static org.xmind.ui.style.StyleUtils.isSameDecoration; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.xmind.gef.draw2d.decoration.ICorneredDecoration; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.Decorator; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.decorations.ICalloutTopicDecoration; -import org.xmind.ui.decorations.ITopicDecoration; -import org.xmind.ui.internal.figures.TopicFigure; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.style.StyleUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.MindMapUtils; - -public class TopicDecorator extends Decorator { - - private static final TopicDecorator instance = new TopicDecorator(); - - public void decorate(IGraphicalPart part, IFigure figure) { - super.decorate(part, figure); - if (figure instanceof TopicFigure) { - IGraphicalPart branch = MindMapUtils.findBranch(part); - if (branch != null) - part = branch; - decorateTopic(part, getStyleSelector(part), (TopicFigure) figure); - } - } - - private void decorateTopic(IGraphicalPart part, IStyleSelector ss, - TopicFigure figure) { - ITopicDecoration shape = figure.getDecoration(); - - String defaultShapeId = Styles.TOPIC_SHAPE_ROUNDEDRECT; - String shapeKey = Styles.ShapeClass; - - if (part instanceof IBranchPart) { - String branchType = ((IBranchPart) part).getBranchType(); - if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) { - defaultShapeId = Styles.CALLOUT_TOPIC_SHAPE_BALLOON_ELLIPSE; - shapeKey = Styles.CalloutShapeClass; - } - } - String newShapeId = getString(part, ss, shapeKey, defaultShapeId); - - if (!isSameDecoration(shape, newShapeId)) { - shape = createTopicDecoration(part, newShapeId); - figure.setDecoration(shape); - } - if (shape != null) { - String decorationId = shape.getId(); - shape.setAlpha(figure, 0xff); - shape.setFillAlpha(figure, 0xff); - shape.setLineAlpha(figure, 0xff); - Color fillColor = getColor(part, ss, Styles.FillColor, decorationId, - Styles.DEF_TOPIC_FILL_COLOR); - shape.setFillColor(figure, fillColor); - - shape.setGradient(figure, isGradientColor(part, figure, shape)); - - int fontSize = 0; - if (figure.getTitle() != null) { - fontSize = getInteger(part, ss, Styles.FontSize, 0); - } - - fontSize = fontSize < 56 ? fontSize : 56; - - shape.setLeftMargin(figure, - getInteger(part, ss, Styles.LeftMargin, decorationId, 10) - + (int) (fontSize * 0.5)); - shape.setRightMargin(figure, - getInteger(part, ss, Styles.RightMargin, decorationId, 10) - + (int) (fontSize * 0.5)); - shape.setTopMargin(figure, - getInteger(part, ss, Styles.TopMargin, decorationId, 5) - + (int) (fontSize * 0.1)); - shape.setBottomMargin(figure, - getInteger(part, ss, Styles.BottomMargin, decorationId, 5) - + (int) (fontSize * 0.1)); - - String defaultColor = ColorUtils - .toString(getColor(part, ss, Styles.LineColor, decorationId, - Styles.DEF_TOPIC_LINE_COLOR)); - Color borderLineColor = getColor(part, ss, Styles.BorderLineColor, - decorationId, defaultColor); - shape.setLineColor(figure, borderLineColor); - - int defaultWidth = getInteger(part, ss, Styles.LineWidth, - decorationId, 1); - int borderLineWidth = getInteger(part, ss, Styles.BorderLineWidth, - decorationId, defaultWidth); - shape.setLineWidth(figure, borderLineWidth); - - int lineStyle = getLineStyle(part, ss, decorationId, - SWT.LINE_SOLID); - shape.setLineStyle(figure, lineStyle); - shape.setVisible(figure, true); - - int cornerSize = getInteger(part, ss, Styles.ShapeCorner, - decorationId, 10); - if (shape instanceof ICorneredDecoration) { - ((ICorneredDecoration) shape).setCornerSize(figure, cornerSize); - } - - if (shape instanceof ICalloutTopicDecoration) { - ICalloutTopicDecoration calloutDecoration = (ICalloutTopicDecoration) shape; - String fromLineClass = MindMapUI.getDecorationManager() - .getDecorationDescriptor(decorationId) - .getDefaultValueProvider(Styles.CalloutLineClass) - .getValue(part, Styles.CalloutLineClass); - calloutDecoration.setFromLineClass(figure, getString(part, ss, - Styles.CalloutLineClass, fromLineClass)); - calloutDecoration.setFromLineColor(figure, - getColor(part, ss, Styles.CalloutLineColor, - decorationId, - ColorUtils.toString(borderLineColor))); - String defaultFromFillColor = fillColor == null ? Styles.NONE - : ColorUtils.toString(fillColor); - calloutDecoration.setFromFillColor(figure, - getColor(part, ss, Styles.CalloutFillColor, - decorationId, defaultFromFillColor)); - calloutDecoration.setFromLineStyle(figure, getInteger(part, ss, - Styles.CalloutLinePattern, decorationId, lineStyle)); - calloutDecoration.setFromLineWidth(figure, - getInteger(part, ss, Styles.CalloutLineWidth, - decorationId, borderLineWidth)); - calloutDecoration.setFromLineCorner(figure, getInteger(part, ss, - Styles.CalloutLineCorner, decorationId, cornerSize)); - } - } - - double angle = StyleUtils.getDouble(part, ss, Styles.RotateAngle, 0); - figure.setRotationDegrees(angle); - } - - private boolean isGradientColor(IGraphicalPart part, TopicFigure figure, - ITopicDecoration shape) { - boolean isGraidentColor = false; - - IPart parentPart = part.getParent(); - while (parentPart != null && !(parentPart instanceof ISheetPart)) { - parentPart = parentPart.getParent(); - } - - if (parentPart != null && parentPart instanceof ISheetPart) { - String gradient = getStyleSelector((ISheetPart) parentPart) - .getStyleValue((ISheetPart) parentPart, - Styles.GradientColor); - if (Styles.NONE.equals(gradient)) - isGraidentColor = false; - else if (Styles.GRADIENT.equals(gradient)) - isGraidentColor = true; - } - - return isGraidentColor; - } - - public static TopicDecorator getInstance() { - return instance; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.decorators; + +import static org.xmind.ui.style.StyleUtils.createTopicDecoration; +import static org.xmind.ui.style.StyleUtils.getColor; +import static org.xmind.ui.style.StyleUtils.getInteger; +import static org.xmind.ui.style.StyleUtils.getLineStyle; +import static org.xmind.ui.style.StyleUtils.getString; +import static org.xmind.ui.style.StyleUtils.getStyleSelector; +import static org.xmind.ui.style.StyleUtils.isSameDecoration; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.xmind.gef.draw2d.decoration.ICorneredDecoration; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.Decorator; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.decorations.ICalloutTopicDecoration; +import org.xmind.ui.decorations.ITopicDecoration; +import org.xmind.ui.internal.figures.TopicFigure; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.style.StyleUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.MindMapUtils; + +public class TopicDecorator extends Decorator { + + private static final TopicDecorator instance = new TopicDecorator(); + + public void decorate(IGraphicalPart part, IFigure figure) { + super.decorate(part, figure); + if (figure instanceof TopicFigure) { + IGraphicalPart branch = MindMapUtils.findBranch(part); + if (branch != null) + part = branch; + decorateTopic(part, getStyleSelector(part), (TopicFigure) figure); + } + } + + private void decorateTopic(IGraphicalPart part, IStyleSelector ss, + TopicFigure figure) { + ITopicDecoration shape = figure.getDecoration(); + + String defaultShapeId = Styles.TOPIC_SHAPE_ROUNDEDRECT; + String shapeKey = Styles.ShapeClass; + + if (part instanceof IBranchPart) { + String branchType = ((IBranchPart) part).getBranchType(); + if (MindMapUI.BRANCH_CALLOUT.equals(branchType)) { + defaultShapeId = Styles.CALLOUT_TOPIC_SHAPE_BALLOON_ELLIPSE; + shapeKey = Styles.CalloutShapeClass; + } + } + String newShapeId = getString(part, ss, shapeKey, defaultShapeId); + + if (!isSameDecoration(shape, newShapeId)) { + shape = createTopicDecoration(part, newShapeId); + figure.setDecoration(shape); + } + if (shape != null) { + String decorationId = shape.getId(); + shape.setAlpha(figure, 0xff); + shape.setFillAlpha(figure, 0xff); + shape.setLineAlpha(figure, 0xff); + Color fillColor = getColor(part, ss, Styles.FillColor, decorationId, + Styles.DEF_TOPIC_FILL_COLOR); + shape.setFillColor(figure, fillColor); + + shape.setGradient(figure, isGradientColor(part, figure, shape)); + + int fontSize = 0; + if (figure.getTitle() != null) { + fontSize = getInteger(part, ss, Styles.FontSize, 0); + } + + fontSize = fontSize < 56 ? fontSize : 56; + + shape.setLeftMargin(figure, + getInteger(part, ss, Styles.LeftMargin, decorationId, 10) + + (int) (fontSize * 0.5)); + shape.setRightMargin(figure, + getInteger(part, ss, Styles.RightMargin, decorationId, 10) + + (int) (fontSize * 0.5)); + shape.setTopMargin(figure, + getInteger(part, ss, Styles.TopMargin, decorationId, 5) + + (int) (fontSize * 0.1)); + shape.setBottomMargin(figure, + getInteger(part, ss, Styles.BottomMargin, decorationId, 5) + + (int) (fontSize * 0.1)); + + String defaultColor = ColorUtils + .toString(getColor(part, ss, Styles.LineColor, decorationId, + Styles.DEF_TOPIC_LINE_COLOR)); + Color borderLineColor = getColor(part, ss, Styles.BorderLineColor, + decorationId, defaultColor); + shape.setLineColor(figure, borderLineColor); + + int defaultWidth = getInteger(part, ss, Styles.LineWidth, + decorationId, 1); + int borderLineWidth = getInteger(part, ss, Styles.BorderLineWidth, + decorationId, defaultWidth); + shape.setLineWidth(figure, borderLineWidth); + + int lineStyle = getLineStyle(part, ss, decorationId, + SWT.LINE_SOLID); + shape.setLineStyle(figure, lineStyle); + shape.setVisible(figure, true); + + int cornerSize = getInteger(part, ss, Styles.ShapeCorner, + decorationId, 10); + if (shape instanceof ICorneredDecoration) { + ((ICorneredDecoration) shape).setCornerSize(figure, cornerSize); + } + + if (shape instanceof ICalloutTopicDecoration) { + ICalloutTopicDecoration calloutDecoration = (ICalloutTopicDecoration) shape; + String fromLineClass = MindMapUI.getDecorationManager() + .getDecorationDescriptor(decorationId) + .getDefaultValueProvider(Styles.CalloutLineClass) + .getValue(part, Styles.CalloutLineClass); + calloutDecoration.setFromLineClass(figure, getString(part, ss, + Styles.CalloutLineClass, fromLineClass)); + calloutDecoration.setFromLineColor(figure, + getColor(part, ss, Styles.CalloutLineColor, + decorationId, + ColorUtils.toString(borderLineColor))); + String defaultFromFillColor = fillColor == null ? Styles.NONE + : ColorUtils.toString(fillColor); + calloutDecoration.setFromFillColor(figure, + getColor(part, ss, Styles.CalloutFillColor, + decorationId, defaultFromFillColor)); + calloutDecoration.setFromLineStyle(figure, getInteger(part, ss, + Styles.CalloutLinePattern, decorationId, lineStyle)); + calloutDecoration.setFromLineWidth(figure, + getInteger(part, ss, Styles.CalloutLineWidth, + decorationId, borderLineWidth)); + calloutDecoration.setFromLineCorner(figure, getInteger(part, ss, + Styles.CalloutLineCorner, decorationId, cornerSize)); + } + } + + double angle = StyleUtils.getDouble(part, ss, Styles.RotateAngle, 0); + figure.setRotationDegrees(angle); + } + + private boolean isGradientColor(IGraphicalPart part, TopicFigure figure, + ITopicDecoration shape) { + boolean isGraidentColor = false; + + IPart parentPart = part.getParent(); + while (parentPart != null && !(parentPart instanceof ISheetPart)) { + parentPart = parentPart.getParent(); + } + + if (parentPart != null && parentPart instanceof ISheetPart) { + String gradient = getStyleSelector((ISheetPart) parentPart) + .getStyleValue((ISheetPart) parentPart, + Styles.GradientColor); + if (Styles.NONE.equals(gradient)) + isGraidentColor = false; + else if (Styles.GRADIENT.equals(gradient)) + isGraidentColor = true; + } + + return isGraidentColor; + } + + public static TopicDecorator getInstance() { + return instance; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/BlackBoxDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/BlackBoxDialog.java index 193d5151b..575d12596 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/BlackBoxDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/BlackBoxDialog.java @@ -1,599 +1,599 @@ -package org.xmind.ui.internal.dialogs; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.internal.dialogs.ViewComparator; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.ui.blackbox.BlackBox; -import org.xmind.ui.blackbox.BlackBoxManager; -import org.xmind.ui.blackbox.IBlackBoxMap; -import org.xmind.ui.blackbox.IBlackBoxVersion; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.views.Messages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.FontUtils; - -public class BlackBoxDialog extends Dialog - implements ICoreEventListener, ISelectionChangedListener { - - private static final String MAP_REMOVE = "mapRemove"; //$NON-NLS-1$ - - private static final String VERSION_REMOVE = "versionRemove"; //$NON-NLS-1$ - - private static final String VERSION_ADD = "versionAdd"; //$NON-NLS-1$ - - private static final int DELETE_BUTTON_ID = IDialogConstants.CLIENT_ID + 1; - - private TreeViewer viewer; - - private MenuManager contextMenu; - - private CoreEventRegister coreEventRegister = new CoreEventRegister(this); - - private IAction openAction, deleteAction; - private Button openButton, deleteButton; - private IStructuredSelection currentSelection; - - private static class BlackBoxContentProvider - implements ITreeContentProvider { - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - - public Object[] getElements(Object inputElement) { - return (IBlackBoxMap[]) inputElement; - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof IBlackBoxMap) { - return ((IBlackBoxMap) parentElement).getVersions().toArray(); - } - return null; - } - - public Object getParent(Object element) { - if (element instanceof IBlackBoxVersion) { - return ((IBlackBoxVersion) element).getMap(); - } - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof IBlackBoxMap) { - return !((IBlackBoxMap) element).getVersions().isEmpty(); - } - return false; - } - - } - - private static class BlackBoxLabelProvide extends LabelProvider { - public String getText(Object element) { - if (element instanceof IBlackBoxMap) { - String filePath = ((IBlackBoxMap) element).getSource(); - int index = filePath.lastIndexOf(File.separatorChar); - String fileName = index <= 0 ? filePath - : filePath.substring(index + 1); - index = fileName.lastIndexOf('.'); - String fileNoExtension = index <= 0 ? fileName - : fileName.substring(0, index); - return fileNoExtension; - - } else if (element instanceof IBlackBoxVersion) { - return ((IBlackBoxVersion) element).getTimestamp(); - } - return null; - } - } - - private class VersionsLabelProvider extends ColumnLabelProvider { - @Override - public String getText(Object element) { - if (element instanceof IBlackBoxMap) { - String path = ((IBlackBoxMap) element).getSource(); - int index = path.lastIndexOf(File.separatorChar); - String mapName = index <= 0 ? path : path.substring(index + 1); - if (mapName.contains(".")) //$NON-NLS-1$ - mapName = mapName.substring(0, mapName.lastIndexOf('.')); - return mapName; - } else if (element instanceof IBlackBoxVersion) { - Long timestamp = Long - .valueOf(((IBlackBoxVersion) element).getTimestamp()); - return String.format("%tF %tT", timestamp, timestamp); //$NON-NLS-1$ - } - return null; - } - - @Override - public Image getImage(Object element) { - if (element instanceof IBlackBoxMap) { - ImageDescriptor image = MindMapUI.getImages() - .get(IMindMapImages.XMIND_FILE_ICON); - if (image != null) - return image.createImage(); - } - return null; - } - } - - private class VersionsInfoLabelProvider extends ColumnLabelProvider { - @Override - public String getText(Object element) { - if (element instanceof IBlackBoxMap) { - return ((IBlackBoxMap) element).getSource(); - } else if (element instanceof IBlackBoxVersion) { - - float fileSize = ((float) ((IBlackBoxVersion) element).getFile() - .length()) / 1024; - String fss = String.valueOf(fileSize); - int index = fss.indexOf('.'); - if (index < 0) - return fss + "KB"; //$NON-NLS-1$ - else - return fss.substring(0, index + 2) + "KB"; //$NON-NLS-1$ - } - return null; - } - - } - - private class OpenReversionAction extends Action { - - public OpenReversionAction() { - setEnabled(false); - } - - @Override - public void run() { - handleOpen(currentSelection); - } - - } - - private class DeleteBackupsAction extends Action { - public DeleteBackupsAction() { - setEnabled(false); - } - - @Override - public void run() { - handleDelete(); - } - } - - private class VersionOpenListener implements IDoubleClickListener { - - public void doubleClick(DoubleClickEvent event) { - handleOpen(event.getSelection()); - } - - } - - private class BlackBoxComparator extends ViewComparator { - @Override - public int category(Object element) { - if (element instanceof IBlackBoxMap) { - return 0; - } else if (element instanceof IBlackBoxVersion) { - return 1; - } - return 2; - } - - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - if (e1 != null && e2 != null && e1 instanceof IBlackBoxVersion - && e2 instanceof IBlackBoxVersion) { - - long time1 = Long - .parseLong(((IBlackBoxVersion) e1).getTimestamp()); - long time2 = Long - .parseLong(((IBlackBoxVersion) e2).getTimestamp()); - - return time1 - time2 > 0 ? -1 : 1; - } - - return super.compare(viewer, e1, e2); - } - } - - public BlackBoxDialog(Shell parentShell) { - super(parentShell); - - setShellStyle(SWT.MODELESS | SWT.RESIZE | SWT.DIALOG_TRIM | SWT.MIN - | SWT.MAX); - setBlockOnOpen(false); - - } - - @Override - public void configureShell(Shell shell) { - super.configureShell(shell); - shell.setText(MindMapMessages.BlackBoxDialog_title); - } - - @Override - public Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 14; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - composite.setLayout(gridLayout); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - createDescriptionArea(composite); - createContentArea(composite); - - fillAndRegisterMenu(); - registerCoreEvent(); - - return composite; - } - - @Override - protected Control createButtonBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - // create a layout with spacing and margins appropriate for the font - // size. - GridLayout layout = new GridLayout(); - layout.numColumns = 0; // this is incremented by createButton - layout.makeColumnsEqualWidth = true; - layout.marginWidth = 13; - layout.marginHeight = 23; - layout.horizontalSpacing = 18; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - GridData data = new GridData( - GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); - composite.setLayoutData(data); - composite.setFont(parent.getFont()); - - // Add the buttons to the button bar. - createButtonsForButtonBar(composite); - return composite; - } - - private void createContentArea(Composite parent) { - Composite composite = new Composite(parent, SWT.BORDER); - composite.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - composite.setLayout(gridLayout); - - Control viewerControl = createViewer(composite); - viewerControl - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - } - - private void createDescriptionArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - composite.setBackground(parent.getBackground()); - - GridLayout middleLayerLayout = new GridLayout(1, false); - middleLayerLayout.marginWidth = 0; - middleLayerLayout.marginHeight = 18; - composite.setLayout(middleLayerLayout); - - Label descriptionLabel = new Label(composite, SWT.WRAP); - descriptionLabel - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - descriptionLabel.setBackground(composite.getBackground()); - descriptionLabel.setText(Messages.BlackBoxView_Description_text); - descriptionLabel.setFont( - FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, -1)); - } - - private Control createViewer(Composite parent) { - viewer = new TreeViewer(parent, - SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION); - viewer.getTree().setHeaderVisible(true); - viewer.getTree().setLinesVisible(true); - viewer.setContentProvider(new BlackBoxContentProvider()); - viewer.setLabelProvider(new BlackBoxLabelProvide()); - - viewer.addSelectionChangedListener(this); - - TreeViewerColumn col0 = new TreeViewerColumn(viewer, SWT.LEFT); - col0.getColumn().setText(Messages.BlackBoxView_Versions); - col0.getColumn().setWidth(200); - col0.setLabelProvider(new VersionsLabelProvider()); - - TreeViewerColumn col1 = new TreeViewerColumn(viewer, SWT.LEFT); - col1.getColumn().setText(Messages.BlackBoxView_Info); - col1.getColumn().setWidth(268); - col1.setLabelProvider(new VersionsInfoLabelProvider()); - - viewer.setInput(BlackBox.getMaps()); - - viewer.setAutoExpandLevel(2); - - viewer.setComparator(new BlackBoxComparator()); - - viewer.addDoubleClickListener(new VersionOpenListener()); - - return viewer.getControl(); - } - - private void fillAndRegisterMenu() { - //TODO String is in View, extract to Dialog - openAction = new OpenReversionAction(); - openAction.setText(Messages.BlackBoxView_OpenVersion); - openAction.setToolTipText(Messages.BlackBoxView_OpenVersion); - openAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.OPEN, true)); - openAction.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.OPEN, false)); - - deleteAction = new DeleteBackupsAction(); - deleteAction.setText(Messages.BlackBoxView_DeleteBackups); - deleteAction.setToolTipText(Messages.BlackBoxView_DeleteBackups); - deleteAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, true)); - deleteAction.setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, false)); - - IMenuManager menu = new MenuManager(); - menu.add(openAction); - menu.add(deleteAction); - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - - contextMenu = new MenuManager("#PopupMenu"); //$NON-NLS-1$ - contextMenu.add(openAction); - contextMenu.add(deleteAction); - viewer.getControl() - .setMenu(contextMenu.createContextMenu(viewer.getControl())); - } - - private void registerCoreEvent() { - coreEventRegister - .setNextSourceFrom(BlackBoxManager.getInstance().getLibrary()); - coreEventRegister.register(VERSION_ADD); - coreEventRegister.register(VERSION_REMOVE); - coreEventRegister.register(MAP_REMOVE); - } - - @Override - protected void initializeBounds() { - getShell().setBounds(300, 150, 516, 500); - super.initializeBounds(); - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - openButton = createButton(parent, IDialogConstants.OPEN_ID, - Messages.BlackBoxView_OpenVersion, false); - openButton.setEnabled(false); - deleteButton = createButton(parent, DELETE_BUTTON_ID, - Messages.BlackBoxView_DeleteBackups, false); - deleteButton.setEnabled(false); - - createButton(parent, IDialogConstants.CLOSE_ID, - IDialogConstants.CLOSE_LABEL, true); - } - - @Override - protected void buttonPressed(int buttonId) { - - super.buttonPressed(buttonId); - - if (IDialogConstants.OPEN_ID == buttonId) - handleOpen(currentSelection); - else if (IDialogConstants.CLOSE_ID == buttonId) - handleClose(); - else if (DELETE_BUTTON_ID == buttonId) - handleDelete(); - - } - - private void handleOpen(ISelection selection) { - File reversionFile = null; - IBlackBoxMap map = null; - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - if (ss.size() == 1) { - Object element = ss.getFirstElement(); - if (element instanceof IBlackBoxVersion) { - reversionFile = ((IBlackBoxVersion) element).getFile(); - map = ((IBlackBoxVersion) element).getMap(); - } else if (element instanceof IBlackBoxMap) { - if (viewer.getExpandedState(element)) - viewer.collapseToLevel(element, 2); - else - viewer.expandToLevel(element, 2); - } - } - } - if (reversionFile == null || !reversionFile.exists() || map == null) - return; - handleOpen(reversionFile, map); - } - - private void handleOpen(File reversionFile, IBlackBoxMap map) { - try { - IWorkbook workbook = Core.getWorkbookBuilder() - .loadFromFile(reversionFile); - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInputForPreLoadedWorkbook(workbook, - new File(map.getSource()).getName()); - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() - .openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); - if (workbook instanceof ICoreEventSource2) { - ((ICoreEventSource2) workbook).registerOnceCoreEventListener( - Core.WorkbookPreSaveOnce, ICoreEventListener.NULL); - } - } catch (IOException e1) { - e1.printStackTrace(); - } catch (CoreException e1) { - e1.printStackTrace(); - } catch (PartInitException e) { - e.printStackTrace(); - } - - } - - private void handleDelete() { - - List mapsToDelete = new ArrayList(); - List versionsToDelete = new ArrayList(); - IStructuredSelection selection = (IStructuredSelection) viewer - .getSelection(); - Iterator it = selection.iterator(); - while (it.hasNext()) { - Object element = it.next(); - if (element instanceof IBlackBoxVersion) { - versionsToDelete.add((IBlackBoxVersion) element); - } else if (element instanceof IBlackBoxMap) { - mapsToDelete.add((IBlackBoxMap) element); - } - } - - if (versionsToDelete.isEmpty() && mapsToDelete.isEmpty()) - return; - if (!versionsToDelete.isEmpty()) { - for (IBlackBoxVersion version : versionsToDelete) { - IBlackBoxMap map = version.getMap(); - BlackBox.removeVersion(map, version.getTimestamp()); - } - } - if (!mapsToDelete.isEmpty()) { - for (IBlackBoxMap blackBoxMap : mapsToDelete) { - BlackBox.removeMap(blackBoxMap); - } - } - - } - - private void handleClose() { - close(); - } - - @Override - public boolean close() { - if (contextMenu != null) { - contextMenu.dispose(); - contextMenu = null; - } - - coreEventRegister.unregisterAll(); - - return super.close(); - - } - - public void handleCoreEvent(CoreEvent event) { - final String type = event.getType(); - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - public void run() { - if (VERSION_REMOVE.equals(type)) { - viewer.refresh(true); - } else if (VERSION_ADD.equals(type) - || MAP_REMOVE.equals(type)) { - viewer.setInput(BlackBox.getMaps()); - } - } - }); - } - - public void selectionChanged(SelectionChangedEvent event) { - - openAction.setEnabled(false); - openButton.setEnabled(false); - deleteAction.setEnabled(false); - deleteButton.setEnabled(false); - - if (!(event.getSelection() instanceof IStructuredSelection)) - return; - - currentSelection = (IStructuredSelection) event.getSelection(); - - List selectVersions = new ArrayList(); - List selectMaps = new ArrayList(); - - Iterator it = currentSelection.iterator(); - while (it.hasNext()) { - Object element = it.next(); - if (element instanceof IBlackBoxVersion) { - selectVersions.add((IBlackBoxVersion) element); - } else if (element instanceof IBlackBoxMap) { - selectMaps.add((IBlackBoxMap) element); - } - } - - if (1 == selectVersions.size() && selectMaps.isEmpty()) { - openAction.setEnabled(true); - openButton.setEnabled(true); - } - - if (!selectMaps.isEmpty() || !selectVersions.isEmpty()) { - deleteAction.setEnabled(true); - deleteButton.setEnabled(true); - } - - } - - public void setDamagedFile(File damagedFile) { - if (damagedFile == null) - return; - String source = damagedFile.getAbsolutePath(); - IBlackBoxMap map = BlackBox.findMapBySource(source); - if (map != null) - viewer.setSelection(new StructuredSelection(map), true); - } - -} +package org.xmind.ui.internal.dialogs; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.dialogs.ViewComparator; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.ui.blackbox.BlackBox; +import org.xmind.ui.blackbox.BlackBoxManager; +import org.xmind.ui.blackbox.IBlackBoxMap; +import org.xmind.ui.blackbox.IBlackBoxVersion; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.views.Messages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.FontUtils; + +public class BlackBoxDialog extends Dialog + implements ICoreEventListener, ISelectionChangedListener { + + private static final String MAP_REMOVE = "mapRemove"; //$NON-NLS-1$ + + private static final String VERSION_REMOVE = "versionRemove"; //$NON-NLS-1$ + + private static final String VERSION_ADD = "versionAdd"; //$NON-NLS-1$ + + private static final int DELETE_BUTTON_ID = IDialogConstants.CLIENT_ID + 1; + + private TreeViewer viewer; + + private MenuManager contextMenu; + + private CoreEventRegister coreEventRegister = new CoreEventRegister(this); + + private IAction openAction, deleteAction; + private Button openButton, deleteButton; + private IStructuredSelection currentSelection; + + private static class BlackBoxContentProvider + implements ITreeContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public Object[] getElements(Object inputElement) { + return (IBlackBoxMap[]) inputElement; + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof IBlackBoxMap) { + return ((IBlackBoxMap) parentElement).getVersions().toArray(); + } + return null; + } + + public Object getParent(Object element) { + if (element instanceof IBlackBoxVersion) { + return ((IBlackBoxVersion) element).getMap(); + } + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof IBlackBoxMap) { + return !((IBlackBoxMap) element).getVersions().isEmpty(); + } + return false; + } + + } + + private static class BlackBoxLabelProvide extends LabelProvider { + public String getText(Object element) { + if (element instanceof IBlackBoxMap) { + String filePath = ((IBlackBoxMap) element).getSource(); + int index = filePath.lastIndexOf(File.separatorChar); + String fileName = index <= 0 ? filePath + : filePath.substring(index + 1); + index = fileName.lastIndexOf('.'); + String fileNoExtension = index <= 0 ? fileName + : fileName.substring(0, index); + return fileNoExtension; + + } else if (element instanceof IBlackBoxVersion) { + return ((IBlackBoxVersion) element).getTimestamp(); + } + return null; + } + } + + private class VersionsLabelProvider extends ColumnLabelProvider { + @Override + public String getText(Object element) { + if (element instanceof IBlackBoxMap) { + String path = ((IBlackBoxMap) element).getSource(); + int index = path.lastIndexOf(File.separatorChar); + String mapName = index <= 0 ? path : path.substring(index + 1); + if (mapName.contains(".")) //$NON-NLS-1$ + mapName = mapName.substring(0, mapName.lastIndexOf('.')); + return mapName; + } else if (element instanceof IBlackBoxVersion) { + Long timestamp = Long + .valueOf(((IBlackBoxVersion) element).getTimestamp()); + return String.format("%tF %tT", timestamp, timestamp); //$NON-NLS-1$ + } + return null; + } + + @Override + public Image getImage(Object element) { + if (element instanceof IBlackBoxMap) { + ImageDescriptor image = MindMapUI.getImages() + .get(IMindMapImages.XMIND_FILE_ICON); + if (image != null) + return image.createImage(); + } + return null; + } + } + + private class VersionsInfoLabelProvider extends ColumnLabelProvider { + @Override + public String getText(Object element) { + if (element instanceof IBlackBoxMap) { + return ((IBlackBoxMap) element).getSource(); + } else if (element instanceof IBlackBoxVersion) { + + float fileSize = ((float) ((IBlackBoxVersion) element).getFile() + .length()) / 1024; + String fss = String.valueOf(fileSize); + int index = fss.indexOf('.'); + if (index < 0) + return fss + "KB"; //$NON-NLS-1$ + else + return fss.substring(0, index + 2) + "KB"; //$NON-NLS-1$ + } + return null; + } + + } + + private class OpenReversionAction extends Action { + + public OpenReversionAction() { + setEnabled(false); + } + + @Override + public void run() { + handleOpen(currentSelection); + } + + } + + private class DeleteBackupsAction extends Action { + public DeleteBackupsAction() { + setEnabled(false); + } + + @Override + public void run() { + handleDelete(); + } + } + + private class VersionOpenListener implements IDoubleClickListener { + + public void doubleClick(DoubleClickEvent event) { + handleOpen(event.getSelection()); + } + + } + + private class BlackBoxComparator extends ViewComparator { + @Override + public int category(Object element) { + if (element instanceof IBlackBoxMap) { + return 0; + } else if (element instanceof IBlackBoxVersion) { + return 1; + } + return 2; + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 != null && e2 != null && e1 instanceof IBlackBoxVersion + && e2 instanceof IBlackBoxVersion) { + + long time1 = Long + .parseLong(((IBlackBoxVersion) e1).getTimestamp()); + long time2 = Long + .parseLong(((IBlackBoxVersion) e2).getTimestamp()); + + return time1 - time2 > 0 ? -1 : 1; + } + + return super.compare(viewer, e1, e2); + } + } + + public BlackBoxDialog(Shell parentShell) { + super(parentShell); + + setShellStyle(SWT.MODELESS | SWT.RESIZE | SWT.DIALOG_TRIM | SWT.MIN + | SWT.MAX); + setBlockOnOpen(false); + + } + + @Override + public void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(MindMapMessages.BlackBoxDialog_title); + } + + @Override + public Control createDialogArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 14; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + composite.setLayout(gridLayout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + createDescriptionArea(composite); + createContentArea(composite); + + fillAndRegisterMenu(); + registerCoreEvent(); + + return composite; + } + + @Override + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + // create a layout with spacing and margins appropriate for the font + // size. + GridLayout layout = new GridLayout(); + layout.numColumns = 0; // this is incremented by createButton + layout.makeColumnsEqualWidth = true; + layout.marginWidth = 13; + layout.marginHeight = 23; + layout.horizontalSpacing = 18; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + GridData data = new GridData( + GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); + composite.setLayoutData(data); + composite.setFont(parent.getFont()); + + // Add the buttons to the button bar. + createButtonsForButtonBar(composite); + return composite; + } + + private void createContentArea(Composite parent) { + Composite composite = new Composite(parent, SWT.BORDER); + composite.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + composite.setLayout(gridLayout); + + Control viewerControl = createViewer(composite); + viewerControl + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + private void createDescriptionArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setBackground(parent.getBackground()); + + GridLayout middleLayerLayout = new GridLayout(1, false); + middleLayerLayout.marginWidth = 0; + middleLayerLayout.marginHeight = 18; + composite.setLayout(middleLayerLayout); + + Label descriptionLabel = new Label(composite, SWT.WRAP); + descriptionLabel + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + descriptionLabel.setBackground(composite.getBackground()); + descriptionLabel.setText(Messages.BlackBoxView_Description_text); + descriptionLabel.setFont( + FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, -1)); + } + + private Control createViewer(Composite parent) { + viewer = new TreeViewer(parent, + SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION); + viewer.getTree().setHeaderVisible(true); + viewer.getTree().setLinesVisible(true); + viewer.setContentProvider(new BlackBoxContentProvider()); + viewer.setLabelProvider(new BlackBoxLabelProvide()); + + viewer.addSelectionChangedListener(this); + + TreeViewerColumn col0 = new TreeViewerColumn(viewer, SWT.LEFT); + col0.getColumn().setText(Messages.BlackBoxView_Versions); + col0.getColumn().setWidth(200); + col0.setLabelProvider(new VersionsLabelProvider()); + + TreeViewerColumn col1 = new TreeViewerColumn(viewer, SWT.LEFT); + col1.getColumn().setText(Messages.BlackBoxView_Info); + col1.getColumn().setWidth(268); + col1.setLabelProvider(new VersionsInfoLabelProvider()); + + viewer.setInput(BlackBox.getMaps()); + + viewer.setAutoExpandLevel(2); + + viewer.setComparator(new BlackBoxComparator()); + + viewer.addDoubleClickListener(new VersionOpenListener()); + + return viewer.getControl(); + } + + private void fillAndRegisterMenu() { + //TODO String is in View, extract to Dialog + openAction = new OpenReversionAction(); + openAction.setText(Messages.BlackBoxView_OpenVersion); + openAction.setToolTipText(Messages.BlackBoxView_OpenVersion); + openAction.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.OPEN, true)); + openAction.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.OPEN, false)); + + deleteAction = new DeleteBackupsAction(); + deleteAction.setText(Messages.BlackBoxView_DeleteBackups); + deleteAction.setToolTipText(Messages.BlackBoxView_DeleteBackups); + deleteAction.setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.DELETE, true)); + deleteAction.setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.DELETE, false)); + + IMenuManager menu = new MenuManager(); + menu.add(openAction); + menu.add(deleteAction); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + + contextMenu = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + contextMenu.add(openAction); + contextMenu.add(deleteAction); + viewer.getControl() + .setMenu(contextMenu.createContextMenu(viewer.getControl())); + } + + private void registerCoreEvent() { + coreEventRegister + .setNextSourceFrom(BlackBoxManager.getInstance().getLibrary()); + coreEventRegister.register(VERSION_ADD); + coreEventRegister.register(VERSION_REMOVE); + coreEventRegister.register(MAP_REMOVE); + } + + @Override + protected void initializeBounds() { + getShell().setBounds(300, 150, 516, 500); + super.initializeBounds(); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + openButton = createButton(parent, IDialogConstants.OPEN_ID, + Messages.BlackBoxView_OpenVersion, false); + openButton.setEnabled(false); + deleteButton = createButton(parent, DELETE_BUTTON_ID, + Messages.BlackBoxView_DeleteBackups, false); + deleteButton.setEnabled(false); + + createButton(parent, IDialogConstants.CLOSE_ID, + IDialogConstants.CLOSE_LABEL, true); + } + + @Override + protected void buttonPressed(int buttonId) { + + super.buttonPressed(buttonId); + + if (IDialogConstants.OPEN_ID == buttonId) + handleOpen(currentSelection); + else if (IDialogConstants.CLOSE_ID == buttonId) + handleClose(); + else if (DELETE_BUTTON_ID == buttonId) + handleDelete(); + + } + + private void handleOpen(ISelection selection) { + File reversionFile = null; + IBlackBoxMap map = null; + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + if (ss.size() == 1) { + Object element = ss.getFirstElement(); + if (element instanceof IBlackBoxVersion) { + reversionFile = ((IBlackBoxVersion) element).getFile(); + map = ((IBlackBoxVersion) element).getMap(); + } else if (element instanceof IBlackBoxMap) { + if (viewer.getExpandedState(element)) + viewer.collapseToLevel(element, 2); + else + viewer.expandToLevel(element, 2); + } + } + } + if (reversionFile == null || !reversionFile.exists() || map == null) + return; + handleOpen(reversionFile, map); + } + + private void handleOpen(File reversionFile, IBlackBoxMap map) { + try { + IWorkbook workbook = Core.getWorkbookBuilder() + .loadFromFile(reversionFile); + IEditorInput input = MindMapUI.getEditorInputFactory() + .createEditorInputForPreLoadedWorkbook(workbook, + new File(map.getSource()).getName()); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); + if (workbook instanceof ICoreEventSource2) { + ((ICoreEventSource2) workbook).registerOnceCoreEventListener( + Core.WorkbookPreSaveOnce, ICoreEventListener.NULL); + } + } catch (IOException e1) { + e1.printStackTrace(); + } catch (CoreException e1) { + e1.printStackTrace(); + } catch (PartInitException e) { + e.printStackTrace(); + } + + } + + private void handleDelete() { + + List mapsToDelete = new ArrayList(); + List versionsToDelete = new ArrayList(); + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + Iterator it = selection.iterator(); + while (it.hasNext()) { + Object element = it.next(); + if (element instanceof IBlackBoxVersion) { + versionsToDelete.add((IBlackBoxVersion) element); + } else if (element instanceof IBlackBoxMap) { + mapsToDelete.add((IBlackBoxMap) element); + } + } + + if (versionsToDelete.isEmpty() && mapsToDelete.isEmpty()) + return; + if (!versionsToDelete.isEmpty()) { + for (IBlackBoxVersion version : versionsToDelete) { + IBlackBoxMap map = version.getMap(); + BlackBox.removeVersion(map, version.getTimestamp()); + } + } + if (!mapsToDelete.isEmpty()) { + for (IBlackBoxMap blackBoxMap : mapsToDelete) { + BlackBox.removeMap(blackBoxMap); + } + } + + } + + private void handleClose() { + close(); + } + + @Override + public boolean close() { + if (contextMenu != null) { + contextMenu.dispose(); + contextMenu = null; + } + + coreEventRegister.unregisterAll(); + + return super.close(); + + } + + public void handleCoreEvent(CoreEvent event) { + final String type = event.getType(); + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + public void run() { + if (VERSION_REMOVE.equals(type)) { + viewer.refresh(true); + } else if (VERSION_ADD.equals(type) + || MAP_REMOVE.equals(type)) { + viewer.setInput(BlackBox.getMaps()); + } + } + }); + } + + public void selectionChanged(SelectionChangedEvent event) { + + openAction.setEnabled(false); + openButton.setEnabled(false); + deleteAction.setEnabled(false); + deleteButton.setEnabled(false); + + if (!(event.getSelection() instanceof IStructuredSelection)) + return; + + currentSelection = (IStructuredSelection) event.getSelection(); + + List selectVersions = new ArrayList(); + List selectMaps = new ArrayList(); + + Iterator it = currentSelection.iterator(); + while (it.hasNext()) { + Object element = it.next(); + if (element instanceof IBlackBoxVersion) { + selectVersions.add((IBlackBoxVersion) element); + } else if (element instanceof IBlackBoxMap) { + selectMaps.add((IBlackBoxMap) element); + } + } + + if (1 == selectVersions.size() && selectMaps.isEmpty()) { + openAction.setEnabled(true); + openButton.setEnabled(true); + } + + if (!selectMaps.isEmpty() || !selectVersions.isEmpty()) { + deleteAction.setEnabled(true); + deleteButton.setEnabled(true); + } + + } + + public void setDamagedFile(File damagedFile) { + if (damagedFile == null) + return; + String source = damagedFile.getAbsolutePath(); + IBlackBoxMap map = BlackBox.findMapBySource(source); + if (map != null) + viewer.setSelection(new StructuredSelection(map), true); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogMessages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogMessages.java index ac4a07a92..d4b87f7c6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogMessages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogMessages.java @@ -1,224 +1,224 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dialogs; - -import org.eclipse.osgi.util.NLS; - -/** - * - * @author Frank Shaka - * - */ -public class DialogMessages extends NLS { - - private static final String BUNDLE_NAME = "org.xmind.ui.internal.dialogs.messages"; //$NON-NLS-1$ - - public static String ReduceFileSize_Advise_text; - public static String DeleteEditingHistory_text; - public static String DeletePreviewImage_text; - public static String ReduceFileSize_text; - public static String ReduceAndSave_text; - - public static String CommonDialogTitle; - public static String Open_title; - public static String Save_title; - public static String Error_title; - public static String MultipleErrors_title; - - public static String ErrorOpen_title; - public static String ErrorSave_title; - public static String FailedToLoadWorkbook_message; - public static String FailedToSaveWorkbook_message; - - public static String CompatibilityWarning_title; - public static String CompatibilityWarning_message; - - public static String ConfirmOverwrite_title; - public static String ConfirmOverwrite_message; - - public static String ConfirmRestart_title; - public static String ConfirmRestart_message; - public static String ConfirmRestart_Restart; - public static String ConfirmRestart_Continue; - - public static String ConfirmWorkbookVersion_title; - public static String ConfirmWorkbookVersion_message; - public static String ConfirmWorkbookVersion_SaveAs; - - public static String InfoFileNotExists_title; - public static String InfoFileNotExists_message; - - public static String HyperlinkDialog_title; - public static String HyperlinkDialog_description; - public static String HyperlinkDialog_Remove; - public static String HyperlinkDialog_MultipleTopics_message; - public static String HyperlinkDialog_MultipleTopics_value; - public static String HyperlinkDialog_windowTitle; - - public static String HyperlinkDialog_FailCreatePage_message; - - public static String NotesPopup_GotoNotesView_text; - - public static String SelectImageDialog_title; - - public static String TemplateMissing_message; - - public static String AllFilesFilterName; - public static String WebHyperlinkPage_label; - public static String WebHyperlinkPage_nullHyper_message; - - public static String WorkbookFilterName; - public static String TemplateFilterName; - - public static String TopicHyperlinkPage_label; - public static String OldWorkbookFilterName; - public static String AllSupportedFilesFilterName; - public static String MarkerPackageFilterName; - - public static String PageSetupDialog_Content; - public static String PageSetupDialog_PlusAndMinusIcons; - public static String PageSetupDialog_CurrentMap; - public static String PageSetupDialog_WholeWorkbook; - public static String PageSetupDialog_HideBoth; - public static String PageSetupDialog_ShowBoth; - public static String PageSetupDialog_HideMinusShowPlus; - public static String PageSetupDialog_windowTitle; - public static String PageSetupDialog_title; - public static String PageSetupDialog_description; - public static String PageSetupDialog_PageSetup; - public static String PageSetupDialog_Margins; - - public static String PageSetupDialog_HeaderFooter; - public static String PageSetupDialog_Background; - public static String PageSetupDialog_Border; - public static String PageSetupDialog_Left; - public static String PageSetupDialog_Right; - public static String PageSetupDialog_Top; - public static String PageSetupDialog_Bottom; - public static String PageSetupDialog_Inch; - public static String PageSetupDialog_Millimeter; - public static String PageSetupDialog_Header; - public static String PageSetupDialog_Footer; - public static String PageSetupDialog_AlignLeft_text; - public static String PageSetupDialog_AlignLeft_toolTip; - public static String PageSetupDialog_AlignRight_text; - public static String PageSetupDialog_AlignRight_toolTip; - public static String PageSetupDialog_AlignCenter_text; - public static String PageSetupDialog_AlignCenter_toolTip; - public static String PageSetupDialog_Font_text; - public static String PageSetupDialog_Font_toolTip; - public static String PageSetupDialog_JustForReference; - public static String PageSetupDialog_Orientation; - public static String PageSetupDialog_Landscape; - public static String PageSetupDialog_Portrait; - - public static String FileHyperlinkPage_ChooseFile_text; - - public static String FileHyperlinkPage_ChooseFolder_text; - - public static String FileHyperlinkPage_FileNotExists_message; - public static String FileHyperlinkPage_RelativeWarning_message; - - public static String FileHyperlinkPage_label; - - public static String FileHyperlinkPage_OpenDirectoryDialog_windowTitle; - - public static String FileHyperlinkPage_OpenFileDialog_windowTitle; - - public static String FindReplaceDialog_windowTitle; - public static String FindReplaceDialog_Find_label; - public static String FindReplaceDialog_ReplaceWith_label; - public static String FindReplaceDialog_OptionGroup; - public static String FindReplaceDialog_CaseSensitive; - public static String FindReplaceDialog_WholeWord; - public static String FindReplaceDialog_DirectionGroup; - public static String FindReplaceDialog_Forward; - public static String FindReplaceDialog_Backward; - public static String FindReplaceDialog_ScopeGroup; - public static String FindReplaceDialog_CurrentMap; - public static String FindReplaceDialog_Workbook; - public static String FindReplaceDialog_Find_text; - public static String FindReplaceDialog_FindAll_text; - public static String FindReplaceDialog_Replace_text; - public static String FindReplaceDialog_ReplaceAll_text; - public static String FindReplaceDialog_StringNotFound; - - public static String FileHyperlinkPage_WarningDialog_message; - public static String FileHyperlinkPage_WarningDialog_Title; - public static String FileHyperlinkPage_WarningDialog_OKButton_Label; - public static String FileHyperlinkPage_WarningDialog_CancelButton_Label; - public static String FileHyperlinkPage_HrefGroup_Text; - public static String FileHyperlinkPage_AbsoluteButton_Text; - public static String FileHyperlinkPage_RelativeButton_Text; - - public static String RevisionPreviewDialog_CorruptedRevision_message; - - public static String RevisionPreviewDialog_CurrentRevision_title; - - public static String RevisionPreviewDialog_Revision_titlePattern; - - public static String SortMessageDialog_Messages; - public static String SortMessageDialog_Title; - - public static String NewWorkbookWizardDialog_OpenExistingFile_text; - public static String NewWorkbookWizardDialog_Choose_text; - - public static String TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_windowTitle; - public static String TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_message; - - public static String DND_ExternalFolder; - public static String DND_ExternalFolder_confirmation_with_path; - public static String DND_ExternalFile; - public static String DND_ExternalFile_confirmation_with_path_size; - public static String DND_MultipleExternalFiles; - public static String DND_MultipleExternalFiles_moreFiles_with_number; - public static String DND_MultipleExternalFiles_confirmation_with_fileList; - public static String DND_ConfirmDroppingFileDialog_title_with_type; - public static String DND_ConfirmDroppingFileDialog_LinkButton_text; - public static String DND_ConfirmDroppingFileDialog_CopyButton_text; - public static String DND_ConfirmDroppingFileDialog_RememberCheck_text_with_type; - - public static String ConfirmDeleteTemplateDialog_title; - public static String ConfirmDeleteTemplateDialog_message_with_templateName; - - public static String ConfirmClearRecentFileListDialog_title; - public static String ConfirmClearRecentFileListDialog_message; - - public static String WorkbookMetaInspectorDialog_title; - public static String WorkbookRevisionDialog_title; - public static String workbookRevisionDialog_Title_Label_text; - public static String workbookRevisionDialog_Description_Label_text; - public static String WorkbookRevisionDialog_Preview_Button_label; - public static String WorkbookRevisionDialog_Restore_Button_label; - public static String WorkbookRevisionDialog_Disable_Label_text; - - public static String EnableRevisionDialog_Title_text; - public static String EnableRevisionDialog_Confirm_message; - public static String DisableRevisonDialog_Title_text; - public static String DisableRevisonDialog_Comfirm_message; - - public static String RevisionPreviewDialog_Restore_Label_text; - public static String RevisionPreviewDialog_Previous_Button_label; - public static String RevisionPreviewDialog_Next_Button_label; - - public static String ShareDialog_dialog_title; - - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, DialogMessages.class); - } - - private DialogMessages() { - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dialogs; + +import org.eclipse.osgi.util.NLS; + +/** + * + * @author Frank Shaka + * + */ +public class DialogMessages extends NLS { + + private static final String BUNDLE_NAME = "org.xmind.ui.internal.dialogs.messages"; //$NON-NLS-1$ + + public static String ReduceFileSize_Advise_text; + public static String DeleteEditingHistory_text; + public static String DeletePreviewImage_text; + public static String ReduceFileSize_text; + public static String ReduceAndSave_text; + + public static String CommonDialogTitle; + public static String Open_title; + public static String Save_title; + public static String Error_title; + public static String MultipleErrors_title; + + public static String ErrorOpen_title; + public static String ErrorSave_title; + public static String FailedToLoadWorkbook_message; + public static String FailedToSaveWorkbook_message; + + public static String CompatibilityWarning_title; + public static String CompatibilityWarning_message; + + public static String ConfirmOverwrite_title; + public static String ConfirmOverwrite_message; + + public static String ConfirmRestart_title; + public static String ConfirmRestart_message; + public static String ConfirmRestart_Restart; + public static String ConfirmRestart_Continue; + + public static String ConfirmWorkbookVersion_title; + public static String ConfirmWorkbookVersion_message; + public static String ConfirmWorkbookVersion_SaveAs; + + public static String InfoFileNotExists_title; + public static String InfoFileNotExists_message; + + public static String HyperlinkDialog_title; + public static String HyperlinkDialog_description; + public static String HyperlinkDialog_Remove; + public static String HyperlinkDialog_MultipleTopics_message; + public static String HyperlinkDialog_MultipleTopics_value; + public static String HyperlinkDialog_windowTitle; + + public static String HyperlinkDialog_FailCreatePage_message; + + public static String NotesPopup_GotoNotesView_text; + + public static String SelectImageDialog_title; + + public static String TemplateMissing_message; + + public static String AllFilesFilterName; + public static String WebHyperlinkPage_label; + public static String WebHyperlinkPage_nullHyper_message; + + public static String WorkbookFilterName; + public static String TemplateFilterName; + + public static String TopicHyperlinkPage_label; + public static String OldWorkbookFilterName; + public static String AllSupportedFilesFilterName; + public static String MarkerPackageFilterName; + + public static String PageSetupDialog_Content; + public static String PageSetupDialog_PlusAndMinusIcons; + public static String PageSetupDialog_CurrentMap; + public static String PageSetupDialog_WholeWorkbook; + public static String PageSetupDialog_HideBoth; + public static String PageSetupDialog_ShowBoth; + public static String PageSetupDialog_HideMinusShowPlus; + public static String PageSetupDialog_windowTitle; + public static String PageSetupDialog_title; + public static String PageSetupDialog_description; + public static String PageSetupDialog_PageSetup; + public static String PageSetupDialog_Margins; + + public static String PageSetupDialog_HeaderFooter; + public static String PageSetupDialog_Background; + public static String PageSetupDialog_Border; + public static String PageSetupDialog_Left; + public static String PageSetupDialog_Right; + public static String PageSetupDialog_Top; + public static String PageSetupDialog_Bottom; + public static String PageSetupDialog_Inch; + public static String PageSetupDialog_Millimeter; + public static String PageSetupDialog_Header; + public static String PageSetupDialog_Footer; + public static String PageSetupDialog_AlignLeft_text; + public static String PageSetupDialog_AlignLeft_toolTip; + public static String PageSetupDialog_AlignRight_text; + public static String PageSetupDialog_AlignRight_toolTip; + public static String PageSetupDialog_AlignCenter_text; + public static String PageSetupDialog_AlignCenter_toolTip; + public static String PageSetupDialog_Font_text; + public static String PageSetupDialog_Font_toolTip; + public static String PageSetupDialog_JustForReference; + public static String PageSetupDialog_Orientation; + public static String PageSetupDialog_Landscape; + public static String PageSetupDialog_Portrait; + + public static String FileHyperlinkPage_ChooseFile_text; + + public static String FileHyperlinkPage_ChooseFolder_text; + + public static String FileHyperlinkPage_FileNotExists_message; + public static String FileHyperlinkPage_RelativeWarning_message; + + public static String FileHyperlinkPage_label; + + public static String FileHyperlinkPage_OpenDirectoryDialog_windowTitle; + + public static String FileHyperlinkPage_OpenFileDialog_windowTitle; + + public static String FindReplaceDialog_windowTitle; + public static String FindReplaceDialog_Find_label; + public static String FindReplaceDialog_ReplaceWith_label; + public static String FindReplaceDialog_OptionGroup; + public static String FindReplaceDialog_CaseSensitive; + public static String FindReplaceDialog_WholeWord; + public static String FindReplaceDialog_DirectionGroup; + public static String FindReplaceDialog_Forward; + public static String FindReplaceDialog_Backward; + public static String FindReplaceDialog_ScopeGroup; + public static String FindReplaceDialog_CurrentMap; + public static String FindReplaceDialog_Workbook; + public static String FindReplaceDialog_Find_text; + public static String FindReplaceDialog_FindAll_text; + public static String FindReplaceDialog_Replace_text; + public static String FindReplaceDialog_ReplaceAll_text; + public static String FindReplaceDialog_StringNotFound; + + public static String FileHyperlinkPage_WarningDialog_message; + public static String FileHyperlinkPage_WarningDialog_Title; + public static String FileHyperlinkPage_WarningDialog_OKButton_Label; + public static String FileHyperlinkPage_WarningDialog_CancelButton_Label; + public static String FileHyperlinkPage_HrefGroup_Text; + public static String FileHyperlinkPage_AbsoluteButton_Text; + public static String FileHyperlinkPage_RelativeButton_Text; + + public static String RevisionPreviewDialog_CorruptedRevision_message; + + public static String RevisionPreviewDialog_CurrentRevision_title; + + public static String RevisionPreviewDialog_Revision_titlePattern; + + public static String SortMessageDialog_Messages; + public static String SortMessageDialog_Title; + + public static String NewWorkbookWizardDialog_OpenExistingFile_text; + public static String NewWorkbookWizardDialog_Choose_text; + + public static String TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_windowTitle; + public static String TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_message; + + public static String DND_ExternalFolder; + public static String DND_ExternalFolder_confirmation_with_path; + public static String DND_ExternalFile; + public static String DND_ExternalFile_confirmation_with_path_size; + public static String DND_MultipleExternalFiles; + public static String DND_MultipleExternalFiles_moreFiles_with_number; + public static String DND_MultipleExternalFiles_confirmation_with_fileList; + public static String DND_ConfirmDroppingFileDialog_title_with_type; + public static String DND_ConfirmDroppingFileDialog_LinkButton_text; + public static String DND_ConfirmDroppingFileDialog_CopyButton_text; + public static String DND_ConfirmDroppingFileDialog_RememberCheck_text_with_type; + + public static String ConfirmDeleteTemplateDialog_title; + public static String ConfirmDeleteTemplateDialog_message_with_templateName; + + public static String ConfirmClearRecentFileListDialog_title; + public static String ConfirmClearRecentFileListDialog_message; + + public static String WorkbookMetaInspectorDialog_title; + public static String WorkbookRevisionDialog_title; + public static String workbookRevisionDialog_Title_Label_text; + public static String workbookRevisionDialog_Description_Label_text; + public static String WorkbookRevisionDialog_Preview_Button_label; + public static String WorkbookRevisionDialog_Restore_Button_label; + public static String WorkbookRevisionDialog_Disable_Label_text; + + public static String EnableRevisionDialog_Title_text; + public static String EnableRevisionDialog_Confirm_message; + public static String DisableRevisonDialog_Title_text; + public static String DisableRevisonDialog_Comfirm_message; + + public static String RevisionPreviewDialog_Restore_Label_text; + public static String RevisionPreviewDialog_Previous_Button_label; + public static String RevisionPreviewDialog_Next_Button_label; + + public static String ShareDialog_dialog_title; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, DialogMessages.class); + } + + private DialogMessages() { + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogUtils.java index 9a5ec624f..ce32c44be 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogUtils.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/DialogUtils.java @@ -1,247 +1,247 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dialogs; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.ImageFormat; - -/** - * - * @author Frank Shaka - * - */ -public class DialogUtils { - - private static final String OLD_FILE_EXT = ".xmap"; //$NON-NLS-1$ - - private static final String OPEN_DIALOG_SETTINGS_ID = "org.xmind.ui.openDialog"; //$NON-NLS-1$ - - private static final String FILTER_INDEX = "filterIndex"; //$NON-NLS-1$ - - private static final String FILTER_PATH = "filterPath"; //$NON-NLS-1$ - - private DialogUtils() { - } - - public static void makeDefaultImageSelectorDialog(FileDialog dialog, - boolean withAllFileFilter) { - makeImageSelectorDialog(dialog, withAllFileFilter, - ImageFormat.values()); - } - - public static void makeImageSelectorDialog(FileDialog dialog, - boolean withAllFileFilter, ImageFormat... imageFormats) { - Collection extensions = new ArrayList(); - Collection names = new ArrayList(); - if (withAllFileFilter) { - extensions.add("*.*"); //$NON-NLS-1$ - names.add(NLS.bind("{0} (*.*)", //$NON-NLS-1$ - DialogMessages.AllFilesFilterName)); - } - for (ImageFormat format : imageFormats) { - List exts = format.getExtensions(); - if (!exts.isEmpty()) { - StringBuilder extBuilder = new StringBuilder(exts.size() * 5); - StringBuilder extDescBuilder = new StringBuilder( - exts.size() * 5); - for (String ext : exts) { - String pattern = "*" + ext; //$NON-NLS-1$ - if (extBuilder.length() > 0) - extBuilder.append(";"); //$NON-NLS-1$ - extBuilder.append(pattern); - if (extDescBuilder.length() > 0) - extDescBuilder.append(", "); //$NON-NLS-1$ - extDescBuilder.append(pattern); - } - extensions.add(extBuilder.toString()); - names.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ - format.getDescription(), extDescBuilder.toString())); - } - } - dialog.setFilterExtensions( - extensions.toArray(new String[extensions.size()])); - dialog.setFilterNames(names.toArray(new String[names.size()])); - } - - public static boolean confirmOverwrite(Shell shell, String filePath) { - return MessageDialog.openConfirm(shell, - DialogMessages.ConfirmOverwrite_title, - NLS.bind(DialogMessages.ConfirmOverwrite_message, filePath)); - } - - public static boolean confirmRestart(Shell shell) { - return new MessageDialog(null, DialogMessages.ConfirmRestart_title, - null, DialogMessages.ConfirmRestart_message, - MessageDialog.QUESTION, - new String[] { DialogMessages.ConfirmRestart_Restart, - DialogMessages.ConfirmRestart_Continue }, - 1).open() == MessageDialog.OK; - } - - public static String save(Shell shell, String title, String proposalName, - String[] filterExtensions, String[] filterNames, int filterIndex, - String dirPath) { - FileDialog dialog = new FileDialog(shell, SWT.SAVE); - dialog.setOverwrite(false); - dialog.setText(title == null ? DialogMessages.Save_title : title); - if (proposalName != null) - dialog.setFileName(proposalName); - if (dirPath != null) - dialog.setFilterPath(dirPath); - if (filterExtensions != null) - dialog.setFilterExtensions(filterExtensions); - if (filterNames != null) - dialog.setFilterNames(filterNames); - if (filterIndex >= 0) - dialog.setFilterIndex(filterIndex); - return save(shell, dialog); - } - - public static String save(Shell shell, String proposalName, - String[] filterExtensions, String[] filterNames, int filterIndex, - String dirPath) { - return save(shell, null, proposalName, filterExtensions, filterNames, - filterIndex, dirPath); - } - - public static String save(Shell shell, FileDialog dialog) { - String fileName = dialog.open(); - if (fileName != null) { - int filterIndex = dialog.getFilterIndex(); - if (filterIndex >= 0) { - String extension = dialog.getFilterExtensions()[filterIndex]; - fileName = adaptFileName(fileName, extension); - if (new File(fileName).exists() - && !DialogUtils.confirmOverwrite(shell, fileName)) - return save(shell, dialog); - } - } - return fileName; - } - - private static String adaptFileName(String fileName, String extension) { - if (extension != null && !"".equals(extension)) { //$NON-NLS-1$ - String defaultExt = null; - for (String ext : extension.split(";")) { //$NON-NLS-1$ - ext = ext.trim(); - if (ext.startsWith("*")) //$NON-NLS-1$ - ext = ext.substring(1); - if (defaultExt == null) - defaultExt = ext; - if (fileName.endsWith(ext)) - return fileName; - } - if (defaultExt != null) - return fileName + defaultExt; - } - return fileName; - } - - /** - * - * @param parentShell - * @param style - * SWT.NONE, SWT.MULTI, SWT.SHEET - * @return - */ - public static List openXMindFiles(Shell parentShell, int style) { - FileDialog dialog = new FileDialog(parentShell, SWT.OPEN | style); - - String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ - String xmtExt = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ - String oldExt = "*" + OLD_FILE_EXT; //$NON-NLS-1$ - String allSupportedFileExt = String.format("%s;%s;%s", //$NON-NLS-1$ - xmindExt, xmtExt, oldExt); - String allExt = "*.*"; //$NON-NLS-1$ - - List filterExtensions = new ArrayList( - Arrays.asList(dialog.getFilterExtensions())); - filterExtensions.add(xmindExt); - filterExtensions.add(oldExt); - filterExtensions.add(allSupportedFileExt); - filterExtensions.add(allExt); - dialog.setFilterExtensions( - filterExtensions.toArray(new String[filterExtensions.size()])); - - List filterNames = new ArrayList( - Arrays.asList(dialog.getFilterNames())); - filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ - DialogMessages.WorkbookFilterName, xmindExt)); - filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ - DialogMessages.OldWorkbookFilterName, oldExt)); - filterNames - .add(NLS.bind("{0} ({1}, {2}, {3})", //$NON-NLS-1$ - new Object[] { - DialogMessages.AllSupportedFilesFilterName, - xmindExt, xmtExt, oldExt })); - filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ - DialogMessages.AllFilesFilterName, allExt)); - dialog.setFilterNames( - filterNames.toArray(new String[filterNames.size()])); - - IDialogSettings globalSettings = MindMapUIPlugin.getDefault() - .getDialogSettings(); - IDialogSettings settings = globalSettings - .getSection(OPEN_DIALOG_SETTINGS_ID); - if (settings == null) { - settings = globalSettings.addNewSection(OPEN_DIALOG_SETTINGS_ID); - } - - int filterIndex = 0; - try { - filterIndex = settings.getInt(FILTER_INDEX); - if (filterIndex < 0 || filterIndex > 2) - filterIndex = 0; - } catch (NumberFormatException ignore) { - } - dialog.setFilterIndex(filterIndex); - - String filterPath = settings.get(FILTER_PATH); - if (filterPath != null && !"".equals(filterPath)) { //$NON-NLS-1$ - dialog.setFilterPath(filterPath); - } - - String selection = dialog.open(); - if (selection == null) - return Collections.emptyList(); - - filterIndex = dialog.getFilterIndex(); - settings.put(FILTER_INDEX, filterIndex); - - filterPath = dialog.getFilterPath(); - settings.put(FILTER_PATH, filterPath); - - String[] fileNames = dialog.getFileNames(); - List files = new ArrayList(fileNames.length); - for (int i = 0; i < fileNames.length; i++) { - files.add(new File(filterPath, fileNames[i])); - } - return files; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dialogs; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.ImageFormat; + +/** + * + * @author Frank Shaka + * + */ +public class DialogUtils { + + private static final String OLD_FILE_EXT = ".xmap"; //$NON-NLS-1$ + + private static final String OPEN_DIALOG_SETTINGS_ID = "org.xmind.ui.openDialog"; //$NON-NLS-1$ + + private static final String FILTER_INDEX = "filterIndex"; //$NON-NLS-1$ + + private static final String FILTER_PATH = "filterPath"; //$NON-NLS-1$ + + private DialogUtils() { + } + + public static void makeDefaultImageSelectorDialog(FileDialog dialog, + boolean withAllFileFilter) { + makeImageSelectorDialog(dialog, withAllFileFilter, + ImageFormat.values()); + } + + public static void makeImageSelectorDialog(FileDialog dialog, + boolean withAllFileFilter, ImageFormat... imageFormats) { + Collection extensions = new ArrayList(); + Collection names = new ArrayList(); + if (withAllFileFilter) { + extensions.add("*.*"); //$NON-NLS-1$ + names.add(NLS.bind("{0} (*.*)", //$NON-NLS-1$ + DialogMessages.AllFilesFilterName)); + } + for (ImageFormat format : imageFormats) { + List exts = format.getExtensions(); + if (!exts.isEmpty()) { + StringBuilder extBuilder = new StringBuilder(exts.size() * 5); + StringBuilder extDescBuilder = new StringBuilder( + exts.size() * 5); + for (String ext : exts) { + String pattern = "*" + ext; //$NON-NLS-1$ + if (extBuilder.length() > 0) + extBuilder.append(";"); //$NON-NLS-1$ + extBuilder.append(pattern); + if (extDescBuilder.length() > 0) + extDescBuilder.append(", "); //$NON-NLS-1$ + extDescBuilder.append(pattern); + } + extensions.add(extBuilder.toString()); + names.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ + format.getDescription(), extDescBuilder.toString())); + } + } + dialog.setFilterExtensions( + extensions.toArray(new String[extensions.size()])); + dialog.setFilterNames(names.toArray(new String[names.size()])); + } + + public static boolean confirmOverwrite(Shell shell, String filePath) { + return MessageDialog.openConfirm(shell, + DialogMessages.ConfirmOverwrite_title, + NLS.bind(DialogMessages.ConfirmOverwrite_message, filePath)); + } + + public static boolean confirmRestart(Shell shell) { + return new MessageDialog(null, DialogMessages.ConfirmRestart_title, + null, DialogMessages.ConfirmRestart_message, + MessageDialog.QUESTION, + new String[] { DialogMessages.ConfirmRestart_Restart, + DialogMessages.ConfirmRestart_Continue }, + 1).open() == MessageDialog.OK; + } + + public static String save(Shell shell, String title, String proposalName, + String[] filterExtensions, String[] filterNames, int filterIndex, + String dirPath) { + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setOverwrite(false); + dialog.setText(title == null ? DialogMessages.Save_title : title); + if (proposalName != null) + dialog.setFileName(proposalName); + if (dirPath != null) + dialog.setFilterPath(dirPath); + if (filterExtensions != null) + dialog.setFilterExtensions(filterExtensions); + if (filterNames != null) + dialog.setFilterNames(filterNames); + if (filterIndex >= 0) + dialog.setFilterIndex(filterIndex); + return save(shell, dialog); + } + + public static String save(Shell shell, String proposalName, + String[] filterExtensions, String[] filterNames, int filterIndex, + String dirPath) { + return save(shell, null, proposalName, filterExtensions, filterNames, + filterIndex, dirPath); + } + + public static String save(Shell shell, FileDialog dialog) { + String fileName = dialog.open(); + if (fileName != null) { + int filterIndex = dialog.getFilterIndex(); + if (filterIndex >= 0) { + String extension = dialog.getFilterExtensions()[filterIndex]; + fileName = adaptFileName(fileName, extension); + if (new File(fileName).exists() + && !DialogUtils.confirmOverwrite(shell, fileName)) + return save(shell, dialog); + } + } + return fileName; + } + + private static String adaptFileName(String fileName, String extension) { + if (extension != null && !"".equals(extension)) { //$NON-NLS-1$ + String defaultExt = null; + for (String ext : extension.split(";")) { //$NON-NLS-1$ + ext = ext.trim(); + if (ext.startsWith("*")) //$NON-NLS-1$ + ext = ext.substring(1); + if (defaultExt == null) + defaultExt = ext; + if (fileName.endsWith(ext)) + return fileName; + } + if (defaultExt != null) + return fileName + defaultExt; + } + return fileName; + } + + /** + * + * @param parentShell + * @param style + * SWT.NONE, SWT.MULTI, SWT.SHEET + * @return + */ + public static List openXMindFiles(Shell parentShell, int style) { + FileDialog dialog = new FileDialog(parentShell, SWT.OPEN | style); + + String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ + String xmtExt = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ + String oldExt = "*" + OLD_FILE_EXT; //$NON-NLS-1$ + String allSupportedFileExt = String.format("%s;%s;%s", //$NON-NLS-1$ + xmindExt, xmtExt, oldExt); + String allExt = "*.*"; //$NON-NLS-1$ + + List filterExtensions = new ArrayList( + Arrays.asList(dialog.getFilterExtensions())); + filterExtensions.add(xmindExt); + filterExtensions.add(oldExt); + filterExtensions.add(allSupportedFileExt); + filterExtensions.add(allExt); + dialog.setFilterExtensions( + filterExtensions.toArray(new String[filterExtensions.size()])); + + List filterNames = new ArrayList( + Arrays.asList(dialog.getFilterNames())); + filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ + DialogMessages.WorkbookFilterName, xmindExt)); + filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ + DialogMessages.OldWorkbookFilterName, oldExt)); + filterNames + .add(NLS.bind("{0} ({1}, {2}, {3})", //$NON-NLS-1$ + new Object[] { + DialogMessages.AllSupportedFilesFilterName, + xmindExt, xmtExt, oldExt })); + filterNames.add(NLS.bind("{0} ({1})", //$NON-NLS-1$ + DialogMessages.AllFilesFilterName, allExt)); + dialog.setFilterNames( + filterNames.toArray(new String[filterNames.size()])); + + IDialogSettings globalSettings = MindMapUIPlugin.getDefault() + .getDialogSettings(); + IDialogSettings settings = globalSettings + .getSection(OPEN_DIALOG_SETTINGS_ID); + if (settings == null) { + settings = globalSettings.addNewSection(OPEN_DIALOG_SETTINGS_ID); + } + + int filterIndex = 0; + try { + filterIndex = settings.getInt(FILTER_INDEX); + if (filterIndex < 0 || filterIndex > 2) + filterIndex = 0; + } catch (NumberFormatException ignore) { + } + dialog.setFilterIndex(filterIndex); + + String filterPath = settings.get(FILTER_PATH); + if (filterPath != null && !"".equals(filterPath)) { //$NON-NLS-1$ + dialog.setFilterPath(filterPath); + } + + String selection = dialog.open(); + if (selection == null) + return Collections.emptyList(); + + filterIndex = dialog.getFilterIndex(); + settings.put(FILTER_INDEX, filterIndex); + + filterPath = dialog.getFilterPath(); + settings.put(FILTER_PATH, filterPath); + + String[] fileNames = dialog.getFileNames(); + List files = new ArrayList(fileNames.length); + for (int i = 0; i < fileNames.length; i++) { + files.add(new File(filterPath, fileNames[i])); + } + return files; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/NewSheetFromTemplateDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/NewSheetFromTemplateDialog.java index c9401936f..c5250fe39 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/NewSheetFromTemplateDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/NewSheetFromTemplateDialog.java @@ -1,175 +1,175 @@ -package org.xmind.ui.internal.dialogs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GalleryNavigablePolicy; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.wizards.TemplateLabelProvider; -import org.xmind.ui.mindmap.IResourceManager; -import org.xmind.ui.mindmap.ITemplate; -import org.xmind.ui.mindmap.ITemplateGroup; -import org.xmind.ui.mindmap.MindMapUI; - -public class NewSheetFromTemplateDialog extends Dialog - implements ISelectionChangedListener, IOpenListener { - - private static final int FRAME_WIDTH = 130; - private static final int FRAME_HEIGHT = 90; - - private ITemplate template; - - private Button chooseButton; - - private boolean chooseButtonVisible; - - public NewSheetFromTemplateDialog(Shell parentShell) { - super(parentShell); - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(MindMapMessages.NewSheetFromTemplateDialog_text); - } - - @Override - protected Point getInitialSize() { - return new Point(531, 540); - } - - @Override - protected void setShellStyle(int newShellStyle) { - super.setShellStyle(SWT.MIN | SWT.MAX | SWT.CLOSE | SWT.RESIZE); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.marginHeight = convertVerticalDLUsToPixels( - IDialogConstants.VERTICAL_MARGIN); - layout.marginWidth = convertHorizontalDLUsToPixels( - IDialogConstants.HORIZONTAL_MARGIN); - layout.verticalSpacing = convertVerticalDLUsToPixels( - IDialogConstants.VERTICAL_SPACING); - layout.horizontalSpacing = convertHorizontalDLUsToPixels( - IDialogConstants.HORIZONTAL_SPACING); - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - applyDialogFont(composite); - - Control pageContent = createTemplatesContainer(composite); - pageContent.setVisible(true); - - return composite; - } - - private Control createTemplatesContainer(Composite parent) { - GalleryViewer viewer = new GalleryViewer(); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); - editDomain.installEditPolicy(GalleryViewer.POLICY_NAVIGABLE, - new GalleryNavigablePolicy()); - viewer.setEditDomain(editDomain); - - Properties properties = viewer.getProperties(); - properties.set(GalleryViewer.Wrap, true); - properties.set(GalleryViewer.FlatFrames, true); - properties.set(GalleryViewer.Horizontal, true); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.SolidFrames, true); - properties.set(GalleryViewer.FrameContentSize, - new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); - properties.set(GalleryViewer.ImageConstrained, true); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_TOPLEFT, 10, 10, 10, 10, 10, 10)); -// properties.set(GalleryViewer.Layout, new GridLayout()); - - Control control = viewer.createControl(parent, SWT.BORDER); - control.setLayoutData(new GridData(GridData.FILL_BOTH)); -// createTemplateDndSupport(control, viewer); - viewer.setLabelProvider(new TemplateLabelProvider()); - List templates = loadTemplatesViewerInput(); - this.template = templates.get(0); - viewer.setInput(templates); - - if (templates.size() > 0) { - viewer.setSelection(new StructuredSelection(templates.get(0)), - true); - } - viewer.addSelectionChangedListener(this); - viewer.addOpenListener(this); - - return control; - } - - private List loadTemplatesViewerInput() { - ArrayList templates = new ArrayList(); - IResourceManager resourceManager = MindMapUI.getResourceManager(); -// templates.addAll(resourceManager.getSystemTemplates()); - List groups = resourceManager.getSystemTemplateGroups(); - for (ITemplateGroup group : groups) - templates.addAll(group.getTemplates()); - templates.addAll(resourceManager.getUserTemplates()); - return templates; - } - - public ITemplate getTemplate() { - return template; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - chooseButton = createButton(parent, IDialogConstants.OK_ID, - MindMapMessages.NewSheetFromTemplateDialog_button_Choose, true); - } - - public void open(OpenEvent event) { - okPressed(); - } - - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof StructuredSelection) { - Object selectedObject = ((StructuredSelection) event.getSelection()) - .getFirstElement(); - if (selectedObject instanceof ITemplate) { - template = (ITemplate) selectedObject; - chooseButtonVisible = true; - } else { - chooseButtonVisible = false; - } - chooseButton.setEnabled(chooseButtonVisible); - } - } - -} +package org.xmind.ui.internal.dialogs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GalleryNavigablePolicy; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.wizards.TemplateLabelProvider; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.ITemplateGroup; +import org.xmind.ui.mindmap.MindMapUI; + +public class NewSheetFromTemplateDialog extends Dialog + implements ISelectionChangedListener, IOpenListener { + + private static final int FRAME_WIDTH = 130; + private static final int FRAME_HEIGHT = 90; + + private ITemplate template; + + private Button chooseButton; + + private boolean chooseButtonVisible; + + public NewSheetFromTemplateDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(MindMapMessages.NewSheetFromTemplateDialog_text); + } + + @Override + protected Point getInitialSize() { + return new Point(531, 540); + } + + @Override + protected void setShellStyle(int newShellStyle) { + super.setShellStyle(SWT.MIN | SWT.MAX | SWT.CLOSE | SWT.RESIZE); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_MARGIN); + layout.marginWidth = convertHorizontalDLUsToPixels( + IDialogConstants.HORIZONTAL_MARGIN); + layout.verticalSpacing = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_SPACING); + layout.horizontalSpacing = convertHorizontalDLUsToPixels( + IDialogConstants.HORIZONTAL_SPACING); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + applyDialogFont(composite); + + Control pageContent = createTemplatesContainer(composite); + pageContent.setVisible(true); + + return composite; + } + + private Control createTemplatesContainer(Composite parent) { + GalleryViewer viewer = new GalleryViewer(); + + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + editDomain.installEditPolicy(GalleryViewer.POLICY_NAVIGABLE, + new GalleryNavigablePolicy()); + viewer.setEditDomain(editDomain); + + Properties properties = viewer.getProperties(); + properties.set(GalleryViewer.Wrap, true); + properties.set(GalleryViewer.FlatFrames, true); + properties.set(GalleryViewer.Horizontal, true); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SolidFrames, true); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + properties.set(GalleryViewer.ImageConstrained, true); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_TOPLEFT, 10, 10, 10, 10, 10, 10)); +// properties.set(GalleryViewer.Layout, new GridLayout()); + + Control control = viewer.createControl(parent, SWT.BORDER); + control.setLayoutData(new GridData(GridData.FILL_BOTH)); +// createTemplateDndSupport(control, viewer); + viewer.setLabelProvider(new TemplateLabelProvider()); + List templates = loadTemplatesViewerInput(); + this.template = templates.get(0); + viewer.setInput(templates); + + if (templates.size() > 0) { + viewer.setSelection(new StructuredSelection(templates.get(0)), + true); + } + viewer.addSelectionChangedListener(this); + viewer.addOpenListener(this); + + return control; + } + + private List loadTemplatesViewerInput() { + ArrayList templates = new ArrayList(); + IResourceManager resourceManager = MindMapUI.getResourceManager(); +// templates.addAll(resourceManager.getSystemTemplates()); + List groups = resourceManager.getSystemTemplateGroups(); + for (ITemplateGroup group : groups) + templates.addAll(group.getTemplates()); + templates.addAll(resourceManager.getUserTemplates()); + return templates; + } + + public ITemplate getTemplate() { + return template; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + chooseButton = createButton(parent, IDialogConstants.OK_ID, + MindMapMessages.NewSheetFromTemplateDialog_button_Choose, true); + } + + public void open(OpenEvent event) { + okPressed(); + } + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof StructuredSelection) { + Object selectedObject = ((StructuredSelection) event.getSelection()) + .getFirstElement(); + if (selectedObject instanceof ITemplate) { + template = (ITemplate) selectedObject; + chooseButtonVisible = true; + } else { + chooseButtonVisible = false; + } + chooseButton.setEnabled(chooseButtonVisible); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/OpenWorkbookDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/OpenWorkbookDialog.java index e4942453a..601448a4e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/OpenWorkbookDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/OpenWorkbookDialog.java @@ -1,159 +1,159 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dialogs; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.MME; -import org.xmind.ui.mindmap.MindMapUI; - -@Deprecated -public class OpenWorkbookDialog { - - private static final String OPEN_DIALOG_SETTINGS_ID = "org.xmind.ui.openDialog"; //$NON-NLS-1$ - - private static final String OLD_FILE_EXT = ".xmap"; //$NON-NLS-1$ - - private static final String FILTER_INDEX = "filterIndex"; //$NON-NLS-1$ - - private static final String FILTER_PATH = "filterPath"; //$NON-NLS-1$ - - private IWorkbenchWindow window; - - private IDialogSettings ds; - - public OpenWorkbookDialog(IWorkbenchWindow window) { - if (window == null) - throw new IllegalArgumentException(); - this.window = window; - } - - public IEditorPart[] open() { - if (window == null) - return null; - - FileDialog fd = new FileDialog(window.getShell(), SWT.OPEN | SWT.MULTI); - String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ - String xmtExt = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ - String oldExt = "*" + OLD_FILE_EXT; //$NON-NLS-1$ - String allSupportedFileExt = String.format("%s;%s;%s", //$NON-NLS-1$ - xmindExt, xmtExt, oldExt); - String allExt = "*.*"; //$NON-NLS-1$ - fd.setFilterExtensions( - new String[] { xmindExt, oldExt, allSupportedFileExt, allExt }); - fd.setFilterNames(new String[] { - NLS.bind("{0} ({1})", DialogMessages.WorkbookFilterName, //$NON-NLS-1$ - xmindExt), - NLS.bind("{0} ({1})", DialogMessages.OldWorkbookFilterName, //$NON-NLS-1$ - oldExt), - NLS.bind("{0} ({1}, {2}, {3})", //$NON-NLS-1$ - new Object[] { - DialogMessages.AllSupportedFilesFilterName, - xmindExt, xmtExt, oldExt }), - NLS.bind("{0} ({1})", DialogMessages.AllFilesFilterName, //$NON-NLS-1$ - allExt) }); - fd.setFilterIndex(getFilterIndex()); - String path = getFilterPath(); - if (path != null && !"".equals(path)) { //$NON-NLS-1$ - fd.setFilterPath(path); - } - if (fd.open() == null) - return null; - - path = fd.getFilterPath(); - String[] fileNames = fd.getFileNames(); - setFilterIndex(fd.getFilterIndex()); - setFilterPath(path); - List editors = new ArrayList( - fileNames.length); - for (int i = 0; i < fileNames.length; i++) { - File file = new File(path, fileNames[i]); - if (file.exists()) { - IEditorPart editor = open(file); - if (editor != null) { - editors.add(editor); - } - } - } - if (editors.isEmpty()) - return null; - return editors.toArray(new IEditorPart[editors.size()]); - } - - private void setFilterIndex(int index) { - getDialogSettings().put(FILTER_INDEX, index); - } - - private int getFilterIndex() { - try { - int filterIndex = getDialogSettings().getInt(FILTER_INDEX); - if (filterIndex >= 0 && filterIndex <= 2) - return filterIndex; - } catch (NumberFormatException ignore) { - } - return 0; - } - - private void setFilterPath(String path) { - getDialogSettings().put(FILTER_PATH, path); - } - - private String getFilterPath() { - return getDialogSettings().get(FILTER_PATH); - } - - private IDialogSettings getDialogSettings() { - if (ds == null) { - IDialogSettings global = MindMapUIPlugin.getDefault() - .getDialogSettings(); - ds = global.getSection(OPEN_DIALOG_SETTINGS_ID); - if (ds == null) { - ds = global.addNewSection(OPEN_DIALOG_SETTINGS_ID); - } - } - return ds; - } - - protected IEditorPart open(final File file) { - final IEditorPart[] editor = new IEditorPart[1]; - String errMessage = NLS.bind( - DialogMessages.FailedToLoadWorkbook_message, - file.getAbsolutePath()); - SafeRunner.run(new SafeRunnable(errMessage) { - public void run() throws Exception { - IEditorInput input = MME.createFileEditorInput(file); - editor[0] = window.getActivePage().openEditor(input, - MindMapUI.MINDMAP_EDITOR_ID); - } - }); - return editor[0]; - } - - public void dispose() { - window = null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dialogs; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.mindmap.MindMapUI; + +@Deprecated +public class OpenWorkbookDialog { + + private static final String OPEN_DIALOG_SETTINGS_ID = "org.xmind.ui.openDialog"; //$NON-NLS-1$ + + private static final String OLD_FILE_EXT = ".xmap"; //$NON-NLS-1$ + + private static final String FILTER_INDEX = "filterIndex"; //$NON-NLS-1$ + + private static final String FILTER_PATH = "filterPath"; //$NON-NLS-1$ + + private IWorkbenchWindow window; + + private IDialogSettings ds; + + public OpenWorkbookDialog(IWorkbenchWindow window) { + if (window == null) + throw new IllegalArgumentException(); + this.window = window; + } + + public IEditorPart[] open() { + if (window == null) + return null; + + FileDialog fd = new FileDialog(window.getShell(), SWT.OPEN | SWT.MULTI); + String xmindExt = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ + String xmtExt = "*" + MindMapUI.FILE_EXT_TEMPLATE; //$NON-NLS-1$ + String oldExt = "*" + OLD_FILE_EXT; //$NON-NLS-1$ + String allSupportedFileExt = String.format("%s;%s;%s", //$NON-NLS-1$ + xmindExt, xmtExt, oldExt); + String allExt = "*.*"; //$NON-NLS-1$ + fd.setFilterExtensions( + new String[] { xmindExt, oldExt, allSupportedFileExt, allExt }); + fd.setFilterNames(new String[] { + NLS.bind("{0} ({1})", DialogMessages.WorkbookFilterName, //$NON-NLS-1$ + xmindExt), + NLS.bind("{0} ({1})", DialogMessages.OldWorkbookFilterName, //$NON-NLS-1$ + oldExt), + NLS.bind("{0} ({1}, {2}, {3})", //$NON-NLS-1$ + new Object[] { + DialogMessages.AllSupportedFilesFilterName, + xmindExt, xmtExt, oldExt }), + NLS.bind("{0} ({1})", DialogMessages.AllFilesFilterName, //$NON-NLS-1$ + allExt) }); + fd.setFilterIndex(getFilterIndex()); + String path = getFilterPath(); + if (path != null && !"".equals(path)) { //$NON-NLS-1$ + fd.setFilterPath(path); + } + if (fd.open() == null) + return null; + + path = fd.getFilterPath(); + String[] fileNames = fd.getFileNames(); + setFilterIndex(fd.getFilterIndex()); + setFilterPath(path); + List editors = new ArrayList( + fileNames.length); + for (int i = 0; i < fileNames.length; i++) { + File file = new File(path, fileNames[i]); + if (file.exists()) { + IEditorPart editor = open(file); + if (editor != null) { + editors.add(editor); + } + } + } + if (editors.isEmpty()) + return null; + return editors.toArray(new IEditorPart[editors.size()]); + } + + private void setFilterIndex(int index) { + getDialogSettings().put(FILTER_INDEX, index); + } + + private int getFilterIndex() { + try { + int filterIndex = getDialogSettings().getInt(FILTER_INDEX); + if (filterIndex >= 0 && filterIndex <= 2) + return filterIndex; + } catch (NumberFormatException ignore) { + } + return 0; + } + + private void setFilterPath(String path) { + getDialogSettings().put(FILTER_PATH, path); + } + + private String getFilterPath() { + return getDialogSettings().get(FILTER_PATH); + } + + private IDialogSettings getDialogSettings() { + if (ds == null) { + IDialogSettings global = MindMapUIPlugin.getDefault() + .getDialogSettings(); + ds = global.getSection(OPEN_DIALOG_SETTINGS_ID); + if (ds == null) { + ds = global.addNewSection(OPEN_DIALOG_SETTINGS_ID); + } + } + return ds; + } + + protected IEditorPart open(final File file) { + final IEditorPart[] editor = new IEditorPart[1]; + String errMessage = NLS.bind( + DialogMessages.FailedToLoadWorkbook_message, + file.getAbsolutePath()); + SafeRunner.run(new SafeRunnable(errMessage) { + public void run() throws Exception { + IEditorInput input = MME.createFileEditorInput(file); + editor[0] = window.getActivePage().openEditor(input, + MindMapUI.MINDMAP_EDITOR_ID); + } + }); + return editor[0]; + } + + public void dispose() { + window = null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ProgressDialogPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ProgressDialogPart.java index 1a5f5248c..748ff3217 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ProgressDialogPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ProgressDialogPart.java @@ -1,673 +1,674 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dialogs; - -import java.util.Arrays; -import java.util.Comparator; - -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPreferenceConstants; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.events.IHyperlinkListener; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.internal.IWorkbenchHelpContextIds; -import org.eclipse.ui.internal.WorkbenchImages; -import org.eclipse.ui.internal.progress.DetailedProgressViewer; -import org.eclipse.ui.internal.progress.FinishedJobs; -import org.eclipse.ui.internal.progress.JobInfo; -import org.eclipse.ui.internal.progress.JobTreeElement; -import org.eclipse.ui.internal.progress.ProgressManager; -import org.eclipse.ui.internal.progress.ProgressMessages; -import org.eclipse.ui.internal.progress.ProgressViewerContentProvider; -import org.eclipse.ui.internal.util.PrefUtil; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.e4models.ModelPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; - -public class ProgressDialogPart extends ModelPart { - - @SuppressWarnings("unchecked") - private static class ProgressViewerComparator extends ViewerComparator { - - @Override - @SuppressWarnings("rawtypes") - public int compare(Viewer testViewer, Object e1, Object e2) { - return ((Comparable) e1).compareTo(e2); - } - - @Override - public void sort(final Viewer viewer, Object[] elements) { - /* - * https://bugs.eclipse.org/371354 This ordering is inherently - * unstable, since it relies on modifiable properties of the - * elements: E.g. the default implementation in JobTreeElement - * compares getDisplayString(), many of whose implementations use - * getPercentDone(). JavaSE 7+'s TimSort introduced a breaking - * change: It now throws a new IllegalArgumentException for bad - * comparators. Workaround is to retry a few times. - */ - for (int retries = 3; retries > 0; retries--) { - try { - Arrays.sort(elements, new Comparator() { - - @Override - public int compare(Object a, Object b) { - return ProgressViewerComparator.this.compare(viewer, - a, b); - } - }); - return; // success - } catch (IllegalArgumentException e) { - // retry - } - } - - // One last try that will log and throw TimSort's IAE if it happens: - super.sort(viewer, elements); - } - } - - private class ProgressViewer extends DetailedProgressViewer { - - private Control nullContentArea; - - public ProgressViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - public void add(Object[] elements) { - super.add(elements); - updateForShowingContent(); - } - - @Override - public void remove(Object[] elements) { - super.remove(elements); - updateForShowingContent(); - } - - @Override - protected void inputChanged(Object input, Object oldInput) { - super.inputChanged(input, oldInput); - updateForShowingContent(); - } - - @Override - protected void internalRefresh(Object element) { - super.internalRefresh(element); - updateForShowingContent(); - } - - private void updateForShowingContent() { - Control control = getControl(); - if (control == null || control.isDisposed()) { - return; - } - - if (getContentProvider() == null) { - return; - } - - Object[] elements = ((IStructuredContentProvider) getContentProvider()) - .getElements(getInput()); - if (elements.length != 0) { - //show content viewer - if (nullContentArea != null) { - nullContentArea.setVisible(false); - ((GridData) nullContentArea.getLayoutData()).exclude = true; - } - - control.setVisible(true); - ((GridData) control.getLayoutData()).exclude = false; - - if (removeAllHyperlink != null - && !removeAllHyperlink.isDisposed()) { - removeAllHyperlink.setEnabled(true); - } - - } else { - //show null content area - control.setVisible(false); - ((GridData) control.getLayoutData()).exclude = true; - - if (nullContentArea == null) { - nullContentArea = createNullContentArea( - control.getParent()); - } - nullContentArea.setVisible(true); - ((GridData) nullContentArea.getLayoutData()).exclude = false; - - if (removeAllHyperlink != null - && !removeAllHyperlink.isDisposed()) { - removeAllHyperlink.setEnabled(false); - } - } - - getControl().getParent().layout(); - } - - private Composite createNullContentArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(composite.getParent().getBackground()); - final GridData layoutData = new GridData(GridData.FILL_BOTH); - composite.setLayoutData(layoutData); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - createNullContent(composite); - - return composite; - } - - private void createNullContent(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(composite.getParent().getBackground()); - composite.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, true)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 20; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setBackground(label.getParent().getBackground()); - label.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label.setImage((Image) resources.get(MindMapUI.getImages() - .get("progress_no_operations.png", true))); //$NON-NLS-1$ - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground(composite2.getParent().getBackground()); - composite2.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 0; - composite2.setLayout(layout2); - - Label label2 = new Label(composite2, SWT.NONE); - label2.setBackground(label2.getParent().getBackground()); - label2.setForeground( - resources.createColor(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ - label2.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label2.setText(MindMapMessages.ProgressDialog_NullContet_message); - label2.setFont(resources.createFont( - FontDescriptor.createFrom(FontUtils.relativeHeight( - label2.getFont().getFontData(), 1)))); - } - } - - public static final String CONTEXT_MENU_ID = "org.xmind.ui.ProgressDialog"; //$NON-NLS-1$ - - private ResourceManager resources; - - private DetailedProgressViewer viewer; - - private Control control; - - private Hyperlink removeAllHyperlink; - - private Action clearAllAction; - - private Action cancelAction; - - @Override - protected void createContent(Composite parent) { - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - createContentsSection(composite); - createBottomSection(composite); - - this.control = composite; - } - - private void createContentsSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(); - layout.marginHeight = 1; - layout.marginWidth = 1; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite2.setBackground(parent.getBackground()); - - GridLayout layout2 = new GridLayout(); - layout2.marginHeight = 0; - layout2.marginWidth = 0; - layout2.marginBottom = 0; - layout2.verticalSpacing = 0; - layout2.horizontalSpacing = 0; - composite2.setLayout(layout2); - - createProgressViewerSection(composite2); - createShowOperationsCheck(composite2); - } - - protected void createProgressViewerSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setBackground(parent.getBackground()); - - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.marginBottom = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - createProgressViewer(composite); - } - - private void createProgressViewer(Composite parent) { - viewer = new ProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL); - viewer.setComparator(new ProgressViewerComparator()); - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, - IWorkbenchHelpContextIds.RESPONSIVE_UI); - - initContentProvider(); - createClearAllAction(); - createCancelAction(); - initContextMenu(); - setSelectionProvider(viewer); - } - - private void createShowOperationsCheck(Composite parent) { - Composite border = new Composite(parent, SWT.NONE); - border.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - border.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.marginTop = 1; - layout.marginBottom = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - border.setLayout(layout); - - Composite composite = new Composite(border, SWT.NONE); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - - GridLayout layout2 = new GridLayout(); - layout2.marginHeight = 8; - layout2.marginWidth = 0; - layout2.marginTop = 0; - layout2.marginBottom = 0; - layout2.verticalSpacing = 0; - layout2.horizontalSpacing = 0; - composite.setLayout(layout2); - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2 - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - composite2.setBackground(composite.getBackground()); - - GridLayout layout3 = new GridLayout(2, false); - layout3.marginHeight = 0; - layout3.marginWidth = 15; - layout3.verticalSpacing = 0; - layout3.horizontalSpacing = 0; - composite2.setLayout(layout3); - - final Button showSystemCheck = new Button(composite2, SWT.CHECK); - showSystemCheck.setBackground(composite2.getBackground()); - showSystemCheck - .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); - showSystemCheck - .setText(MindMapMessages.ProgressDialog_ShowSystem_check); - showSystemCheck.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - - //set initial selection - boolean showSystemJobs = PrefUtil.getAPIPreferenceStore() - .getBoolean(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS); - showSystemCheck.setSelection(showSystemJobs); - - showSystemCheck.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - boolean showSystem = showSystemCheck.getSelection(); - PrefUtil.getAPIPreferenceStore().setValue( - IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS, - showSystem); - viewer.refresh(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - } - - private void createBottomSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#f3f3f3"))); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(2, false); - layout.marginHeight = 14; - layout.marginWidth = 0; - layout.marginRight = 13; - layout.marginBottom = 1; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - createRemoveAllHyperlink(composite); - createButtonBar(composite); - } - - private void createRemoveAllHyperlink(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - composite.setBackground(parent.getBackground()); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.marginLeft = 35; - composite.setLayout(layout); - - removeAllHyperlink = new Hyperlink(composite, SWT.NONE); - removeAllHyperlink.setBackground(composite.getBackground()); - removeAllHyperlink - .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); - removeAllHyperlink - .setText(MindMapMessages.ProgressDialog_RemoveAll_hyperlink); - removeAllHyperlink.setUnderlined(false); - removeAllHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#6484fc"))); //$NON-NLS-1$ - removeAllHyperlink.setFont((Font) resources - .get(FontDescriptor.createFrom(FontUtils.relativeHeight( - removeAllHyperlink.getFont().getFontData(), -1)))); - - removeAllHyperlink.addHyperlinkListener(new IHyperlinkListener() { - - public void linkExited(HyperlinkEvent e) { - } - - public void linkEntered(HyperlinkEvent e) { - } - - public void linkActivated(HyperlinkEvent e) { - clearAllAction.run(); - } - }); - - //set hyperlink enabled - Object[] elements = ((IStructuredContentProvider) viewer - .getContentProvider()).getElements(viewer.getInput()); - removeAllHyperlink.setEnabled(elements.length != 0); - } - - private void createButtonBar(Composite parent) { - Composite buttonBar = new Composite(parent, SWT.NONE); - buttonBar.setLayoutData( - new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - buttonBar.setBackground(parent.getBackground()); - - GridLayout layout = new GridLayout(); - layout.numColumns = 0; - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 6; - buttonBar.setLayout(layout); - - createButton(buttonBar, IDialogConstants.CANCEL_ID, - IDialogConstants.CLOSE_LABEL, false); - } - - private Button createButton(Composite parent, int id, String label, - boolean defaultButton) { - // increment the number of columns in the button bar - ((GridLayout) parent.getLayout()).numColumns++; - Button button = new Button(parent, SWT.PUSH); - button.setBackground(parent.getBackground()); - button.setText(label); - button.setFont(JFaceResources.getDialogFont()); - button.setData(Integer.valueOf(id)); - button.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent event) { - buttonPressed(((Integer) event.widget.getData()).intValue()); - } - }); - if (defaultButton) { - Shell shell = parent.getShell(); - if (shell != null) { - shell.setDefaultButton(button); - } - } - setButtonLayoutData(button); - return button; - } - - private void setButtonLayoutData(Button button) { - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); - data.widthHint = 92; - button.setLayoutData(data); - } - - private void buttonPressed(int buttonId) { - if (IDialogConstants.CANCEL_ID == buttonId) { - cancelPressed(); - } - } - - private void cancelPressed() { - close(); - } - - private void close() { - if (control != null && !control.isDisposed()) { - control.getShell().close(); - } - } - - @Override - public void setFocus() { - if (viewer != null) { - viewer.setFocus(); - } - } - - /** - * Sets the content provider for the viewer. - */ - private void initContentProvider() { - ProgressViewerContentProvider provider = new ProgressViewerContentProvider( - viewer, true, true); - viewer.setContentProvider(provider); - viewer.setInput(ProgressManager.getInstance()); - } - - /** - * Initialize the context menu for the receiver. - */ - private void initContextMenu() { - MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ - Menu menu = menuMgr.createContextMenu(viewer.getControl()); - menuMgr.add(cancelAction); - menuMgr.addMenuListener(new IMenuListener() { - - @Override - public void menuAboutToShow(IMenuManager manager) { - JobInfo info = getSelectedInfo(); - if (info == null) { - return; - } - } - }); - menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - viewer.getControl().setMenu(menu); - - //todo: this may have bug. - registerContextMenu(viewer.getControl(), CONTEXT_MENU_ID); - } - - /** - * Get the currently selected job info. Only return it if it is the only - * item selected and it is a JobInfo. - * - * @return JobInfo - */ - private JobInfo getSelectedInfo() { - IStructuredSelection selection = getSelection(); - if (selection != null && selection.size() == 1) { - JobTreeElement element = (JobTreeElement) selection - .getFirstElement(); - if (element instanceof JobInfo) { - return (JobInfo) element; - } - } - return null; - } - - /** - * Return the selected objects. If any of the selections are not JobInfos or - * there is no selection then return null. - * - * @return JobInfo[] or null. - */ - private IStructuredSelection getSelection() { - ESelectionService selectionService = getAdapter( - ESelectionService.class); - if (selectionService != null) { - Object selection = selectionService.getSelection(); - return selection instanceof IStructuredSelection - ? (IStructuredSelection) selection : null; - } - - return null; - } - - /** - * Create the cancel action for the receiver. - */ - private void createCancelAction() { - cancelAction = new Action(ProgressMessages.ProgressView_CancelAction) { - - @Override - public void run() { - viewer.cancelSelection(); - } - }; - } - - /** - * Create the clear all action for the receiver. - */ - private void createClearAllAction() { - clearAllAction = new Action( - ProgressMessages.ProgressView_ClearAllAction) { - - @Override - public void run() { - FinishedJobs.getInstance().clearAll(); - } - }; - clearAllAction.setToolTipText( - ProgressMessages.NewProgressView_RemoveAllJobsToolTip); - ImageDescriptor id = WorkbenchImages - .getWorkbenchImageDescriptor("/elcl16/progress_remall.png"); //$NON-NLS-1$ - if (id != null) { - clearAllAction.setImageDescriptor(id); - } - id = WorkbenchImages - .getWorkbenchImageDescriptor("/dlcl16/progress_remall.png"); //$NON-NLS-1$ - if (id != null) { - clearAllAction.setDisabledImageDescriptor(id); - } - } - - @Override - public T getAdapter(Class adapter) { - if (adapter.isAssignableFrom(DetailedProgressViewer.class)) { - return adapter.cast(viewer); - } - return super.getAdapter(adapter); - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dialogs; + +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.events.IHyperlinkListener; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.internal.IWorkbenchHelpContextIds; +import org.eclipse.ui.internal.WorkbenchImages; +import org.eclipse.ui.internal.progress.DetailedProgressViewer; +import org.eclipse.ui.internal.progress.FinishedJobs; +import org.eclipse.ui.internal.progress.JobInfo; +import org.eclipse.ui.internal.progress.JobTreeElement; +import org.eclipse.ui.internal.progress.ProgressManager; +import org.eclipse.ui.internal.progress.ProgressMessages; +import org.eclipse.ui.internal.progress.ProgressViewerContentProvider; +import org.eclipse.ui.internal.util.PrefUtil; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.ModelPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; + +public class ProgressDialogPart extends ModelPart { + + @SuppressWarnings("unchecked") + private static class ProgressViewerComparator extends ViewerComparator { + + @Override + @SuppressWarnings("rawtypes") + public int compare(Viewer testViewer, Object e1, Object e2) { + return ((Comparable) e1).compareTo(e2); + } + + @Override + public void sort(final Viewer viewer, Object[] elements) { + /* + * https://bugs.eclipse.org/371354 This ordering is inherently + * unstable, since it relies on modifiable properties of the + * elements: E.g. the default implementation in JobTreeElement + * compares getDisplayString(), many of whose implementations use + * getPercentDone(). JavaSE 7+'s TimSort introduced a breaking + * change: It now throws a new IllegalArgumentException for bad + * comparators. Workaround is to retry a few times. + */ + for (int retries = 3; retries > 0; retries--) { + try { + Arrays.sort(elements, new Comparator() { + + @Override + public int compare(Object a, Object b) { + return ProgressViewerComparator.this.compare(viewer, + a, b); + } + }); + return; // success + } catch (IllegalArgumentException e) { + // retry + } + } + + // One last try that will log and throw TimSort's IAE if it happens: + super.sort(viewer, elements); + } + } + + private class ProgressViewer extends DetailedProgressViewer { + + private Control nullContentArea; + + public ProgressViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + public void add(Object[] elements) { + super.add(elements); + updateForShowingContent(); + } + + @Override + public void remove(Object[] elements) { + super.remove(elements); + updateForShowingContent(); + } + + @Override + protected void inputChanged(Object input, Object oldInput) { + super.inputChanged(input, oldInput); + updateForShowingContent(); + } + + @Override + protected void internalRefresh(Object element) { + super.internalRefresh(element); + updateForShowingContent(); + } + + private void updateForShowingContent() { + Control control = getControl(); + if (control == null || control.isDisposed()) { + return; + } + + if (getContentProvider() == null) { + return; + } + + Object[] elements = ((IStructuredContentProvider) getContentProvider()) + .getElements(getInput()); + if (elements.length != 0) { + //show content viewer + if (nullContentArea != null) { + nullContentArea.setVisible(false); + ((GridData) nullContentArea.getLayoutData()).exclude = true; + } + + control.setVisible(true); + ((GridData) control.getLayoutData()).exclude = false; + + if (removeAllHyperlink != null + && !removeAllHyperlink.isDisposed()) { + removeAllHyperlink.setEnabled(true); + } + + } else { + //show null content area + control.setVisible(false); + ((GridData) control.getLayoutData()).exclude = true; + + if (nullContentArea == null) { + nullContentArea = createNullContentArea( + control.getParent()); + } + nullContentArea.setVisible(true); + ((GridData) nullContentArea.getLayoutData()).exclude = false; + + if (removeAllHyperlink != null + && !removeAllHyperlink.isDisposed()) { + removeAllHyperlink.setEnabled(false); + } + } + + getControl().getParent().layout(); + } + + private Composite createNullContentArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + final GridData layoutData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(layoutData); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + createNullContent(composite); + + return composite; + } + + private void createNullContent(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + composite.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, true)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 20; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setBackground(label.getParent().getBackground()); + label.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + label.setImage((Image) resources.get(MindMapUI.getImages() + .get("progress_no_operations.png", true))); //$NON-NLS-1$ + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(composite2.getParent().getBackground()); + composite2.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.verticalSpacing = 0; + composite2.setLayout(layout2); + + Label label2 = new Label(composite2, SWT.NONE); + label2.setBackground(label2.getParent().getBackground()); + label2.setForeground( + resources.createColor(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ + label2.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + label2.setText(MindMapMessages.ProgressDialog_NullContet_message); + label2.setFont(resources.createFont( + FontDescriptor.createFrom(FontUtils.relativeHeight( + label2.getFont().getFontData(), 1)))); + } + } + + public static final String CONTEXT_MENU_ID = "org.xmind.ui.ProgressDialog"; //$NON-NLS-1$ + + private ResourceManager resources; + + private DetailedProgressViewer viewer; + + private Control control; + + private Hyperlink removeAllHyperlink; + + private Action clearAllAction; + + private Action cancelAction; + + @Override + protected void createContent(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + createContentsSection(composite); + createBottomSection(composite); + + this.control = composite; + } + + private void createContentsSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(); + layout.marginHeight = 1; + layout.marginWidth = 1; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite2.setBackground(parent.getBackground()); + + GridLayout layout2 = new GridLayout(); + layout2.marginHeight = 0; + layout2.marginWidth = 0; + layout2.marginBottom = 0; + layout2.verticalSpacing = 0; + layout2.horizontalSpacing = 0; + composite2.setLayout(layout2); + + createProgressViewerSection(composite2); + createShowOperationsCheck(composite2); + } + + protected void createProgressViewerSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setBackground(parent.getBackground()); + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.marginBottom = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + createProgressViewer(composite); + } + + private void createProgressViewer(Composite parent) { + viewer = new ProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL); + viewer.setComparator(new ProgressViewerComparator()); + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, + IWorkbenchHelpContextIds.RESPONSIVE_UI); + + initContentProvider(); + createClearAllAction(); + createCancelAction(); + initContextMenu(); + setSelectionProvider(viewer); + } + + private void createShowOperationsCheck(Composite parent) { + Composite border = new Composite(parent, SWT.NONE); + border.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + border.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.marginTop = 1; + layout.marginBottom = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + border.setLayout(layout); + + Composite composite = new Composite(border, SWT.NONE); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + + GridLayout layout2 = new GridLayout(); + layout2.marginHeight = 8; + layout2.marginWidth = 0; + layout2.marginTop = 0; + layout2.marginBottom = 0; + layout2.verticalSpacing = 0; + layout2.horizontalSpacing = 0; + composite.setLayout(layout2); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2 + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + composite2.setBackground(composite.getBackground()); + + GridLayout layout3 = new GridLayout(2, false); + layout3.marginHeight = 0; + layout3.marginWidth = 15; + layout3.verticalSpacing = 0; + layout3.horizontalSpacing = 0; + composite2.setLayout(layout3); + + final Button showSystemCheck = new Button(composite2, SWT.CHECK); + showSystemCheck.setBackground(composite2.getBackground()); + showSystemCheck + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); + showSystemCheck + .setText(MindMapMessages.ProgressDialog_ShowSystem_check); + showSystemCheck.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ + + //set initial selection + boolean showSystemJobs = PrefUtil.getAPIPreferenceStore() + .getBoolean(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS); + showSystemCheck.setSelection(showSystemJobs); + + showSystemCheck.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + boolean showSystem = showSystemCheck.getSelection(); + PrefUtil.getAPIPreferenceStore().setValue( + IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS, + showSystem); + viewer.refresh(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + + private void createBottomSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#f3f3f3"))); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 14; + layout.marginWidth = 0; + layout.marginRight = 13; + layout.marginBottom = 1; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + createRemoveAllHyperlink(composite); + createButtonBar(composite); + } + + private void createRemoveAllHyperlink(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + composite.setBackground(parent.getBackground()); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.marginLeft = 35; + composite.setLayout(layout); + + removeAllHyperlink = new Hyperlink(composite, SWT.NONE); + removeAllHyperlink.setBackground(composite.getBackground()); + removeAllHyperlink + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); + removeAllHyperlink + .setText(MindMapMessages.ProgressDialog_RemoveAll_hyperlink); + removeAllHyperlink.setUnderlined(false); + removeAllHyperlink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#6484fc"))); //$NON-NLS-1$ + removeAllHyperlink.setFont((Font) resources + .get(FontDescriptor.createFrom(FontUtils.relativeHeight( + removeAllHyperlink.getFont().getFontData(), -1)))); + + removeAllHyperlink.addHyperlinkListener(new IHyperlinkListener() { + + public void linkExited(HyperlinkEvent e) { + } + + public void linkEntered(HyperlinkEvent e) { + } + + public void linkActivated(HyperlinkEvent e) { + clearAllAction.run(); + } + }); + + //set hyperlink enabled + Object[] elements = ((IStructuredContentProvider) viewer + .getContentProvider()).getElements(viewer.getInput()); + removeAllHyperlink.setEnabled(elements.length != 0); + } + + private void createButtonBar(Composite parent) { + Composite buttonBar = new Composite(parent, SWT.NONE); + buttonBar.setLayoutData( + new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + buttonBar.setBackground(parent.getBackground()); + + GridLayout layout = new GridLayout(); + layout.numColumns = 0; + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 6; + buttonBar.setLayout(layout); + + createButton(buttonBar, IDialogConstants.CANCEL_ID, + IDialogConstants.CLOSE_LABEL, false); + } + + private Button createButton(Composite parent, int id, String label, + boolean defaultButton) { + // increment the number of columns in the button bar + ((GridLayout) parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + button.setBackground(parent.getBackground()); + button.setText(label); + button.setFont(JFaceResources.getDialogFont()); + button.setData(Integer.valueOf(id)); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent event) { + buttonPressed(((Integer) event.widget.getData()).intValue()); + } + }); + if (defaultButton) { + Shell shell = parent.getShell(); + if (shell != null) { + shell.setDefaultButton(button); + } + } + setButtonLayoutData(button); + return button; + } + + private void setButtonLayoutData(Button button) { + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + data.widthHint = 92; + button.setLayoutData(data); + } + + private void buttonPressed(int buttonId) { + if (IDialogConstants.CANCEL_ID == buttonId) { + cancelPressed(); + } + } + + private void cancelPressed() { + close(); + } + + private void close() { + if (control != null && !control.isDisposed()) { + control.getShell().close(); + } + } + + @Override + protected void setFocus() { + super.setFocus(); + if (viewer != null) { + viewer.setFocus(); + } + } + + /** + * Sets the content provider for the viewer. + */ + private void initContentProvider() { + ProgressViewerContentProvider provider = new ProgressViewerContentProvider( + viewer, true, true); + viewer.setContentProvider(provider); + viewer.setInput(ProgressManager.getInstance()); + } + + /** + * Initialize the context menu for the receiver. + */ + private void initContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + menuMgr.add(cancelAction); + menuMgr.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager manager) { + JobInfo info = getSelectedInfo(); + if (info == null) { + return; + } + } + }); + menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + viewer.getControl().setMenu(menu); + + //todo: this may have bug. + registerContextMenu(viewer.getControl(), CONTEXT_MENU_ID); + } + + /** + * Get the currently selected job info. Only return it if it is the only + * item selected and it is a JobInfo. + * + * @return JobInfo + */ + private JobInfo getSelectedInfo() { + IStructuredSelection selection = getSelection(); + if (selection != null && selection.size() == 1) { + JobTreeElement element = (JobTreeElement) selection + .getFirstElement(); + if (element instanceof JobInfo) { + return (JobInfo) element; + } + } + return null; + } + + /** + * Return the selected objects. If any of the selections are not JobInfos or + * there is no selection then return null. + * + * @return JobInfo[] or null. + */ + private IStructuredSelection getSelection() { + ESelectionService selectionService = getAdapter( + ESelectionService.class); + if (selectionService != null) { + Object selection = selectionService.getSelection(); + return selection instanceof IStructuredSelection + ? (IStructuredSelection) selection : null; + } + + return null; + } + + /** + * Create the cancel action for the receiver. + */ + private void createCancelAction() { + cancelAction = new Action(ProgressMessages.ProgressView_CancelAction) { + + @Override + public void run() { + viewer.cancelSelection(); + } + }; + } + + /** + * Create the clear all action for the receiver. + */ + private void createClearAllAction() { + clearAllAction = new Action( + ProgressMessages.ProgressView_ClearAllAction) { + + @Override + public void run() { + FinishedJobs.getInstance().clearAll(); + } + }; + clearAllAction.setToolTipText( + ProgressMessages.NewProgressView_RemoveAllJobsToolTip); + ImageDescriptor id = WorkbenchImages + .getWorkbenchImageDescriptor("/elcl16/progress_remall.png"); //$NON-NLS-1$ + if (id != null) { + clearAllAction.setImageDescriptor(id); + } + id = WorkbenchImages + .getWorkbenchImageDescriptor("/dlcl16/progress_remall.png"); //$NON-NLS-1$ + if (id != null) { + clearAllAction.setDisabledImageDescriptor(id); + } + } + + @Override + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(DetailedProgressViewer.class)) { + return adapter.cast(viewer); + } + return super.getAdapter(adapter); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/RevisionPreviewDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/RevisionPreviewDialog.java index 1df62b60b..402eaa17a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/RevisionPreviewDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/RevisionPreviewDialog.java @@ -1,641 +1,641 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.dialogs; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.draw2d.FigureCanvas; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.IFontProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.window.IShellProvider; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.part.PageBook; -import org.xmind.core.IRevision; -import org.xmind.core.ISheet; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.service.IRevealService; -import org.xmind.gef.tool.BrowsingTool; -import org.xmind.gef.tool.ITool; -import org.xmind.ui.gallery.NavigationViewer; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.mindmap.MindMapRevealService; -import org.xmind.ui.internal.mindmap.MindMapViewer; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.MindMap; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.Cancelable; -import org.xmind.ui.util.ICancelable; -import org.xmind.ui.viewers.SWTUtils; - -/** - * @author Frank Shaka - */ -public class RevisionPreviewDialog extends Dialog { - - private class RevisionMindMapViewer extends MindMapViewer { - protected Control internalCreateControl(Composite parent, int style) { - FigureCanvas canvas = new FigureCanvas(parent, style, - getLightweightSystem()); - canvas.setViewport(getViewport()); - return canvas; - } - } - - private static final String USE_STORED_SIZE = "USE_STORED_SIZE"; //$NON-NLS-1$ - - private static final IShellProvider NO_PARENT_SHELL = new IShellProvider() { - public Shell getShell() { - return null; - } - }; - - private class DefaultPreviewTool extends BrowsingTool { - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.tool.AbstractTool#handleKeyDown(org.xmind.gef.event - * .KeyEvent) - */ - @Override - protected boolean handleKeyDown(KeyEvent ke) { - if (SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, - SWT.ARROW_LEFT)) { - asyncExec(new Runnable() { - public void run() { - setIndex(index - 1); - } - }); - } else if (SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, - SWT.ARROW_RIGHT)) { - asyncExec(new Runnable() { - public void run() { - setIndex(index + 1); - } - }); - } - return super.handleKeyDown(ke); - } - - } - - private class ContainerLayout extends Layout { - - /* - * (non-Javadoc) - * @see - * org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets - * .Composite, int, int, boolean) - */ - @Override - protected org.eclipse.swt.graphics.Point computeSize( - Composite composite, int wHint, int hHint, boolean flushCache) { - if (wHint < 0 || hHint < 0) { - Control[] children = composite.getChildren(); - int w = Math.max(0, wHint); - int h = Math.max(0, hHint); - for (int i = 0; i < children.length; i++) { - Control child = children[i]; - Point childSize = child.getSize(); - w = Math.max(w, childSize.x); - h = Math.max(h, childSize.y); - } - return new org.eclipse.swt.graphics.Point(w, h); - } - return new org.eclipse.swt.graphics.Point(wHint, hHint); - } - - /* - * (non-Javadoc) - * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets. - * Composite , boolean) - */ - @Override - protected void layout(Composite composite, boolean flushCache) { - Rectangle area = composite.getClientArea(); - int h = NavigationViewer.BIG_HEIGHT + 20; - pageBook.setBounds(area.x, area.y, area.width, area.height - h); - navBar.getControl().setBounds(area.x, area.y + area.height - h, - area.width, h); - } - - } - - private static class NavigationLabelProvider extends LabelProvider - implements IFontProvider { - - private Font font; - - private Image image = null; - - /** - * - */ - public NavigationLabelProvider() { - this.font = FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, 32); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) - */ - @Override - public String getText(Object element) { - if (element instanceof IRevision) { - IRevision revision = (IRevision) element; - return String.valueOf(revision.getRevisionNumber()); - } - return ""; //$NON-NLS-1$ - } - - @Override - public Image getImage(Object element) { - if (element instanceof ISheet) { - return getSheetImage(); - } - return super.getImage(element); - } - - private Image getSheetImage() { - if (image == null) { - image = MindMapUI.getImages() - .get(IMindMapImages.DEFAULT_THUMBNAIL).createImage(); - } - return image; - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object) - */ - public Font getFont(Object element) { - return font; - } - - @Override - public void dispose() { - if (image != null) { - image.dispose(); - image = null; - } - super.dispose(); - } - } - - private class NavigationSelectionChangedListener - implements ISelectionChangedListener { - - private ICancelable updater = null; - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged - * (org.eclipse.jface.viewers.SelectionChangedEvent) - */ - public void selectionChanged(SelectionChangedEvent event) { - if (updater != null) { - updater.cancel(); - } - final ISelection selection = event.getSelection(); - if (selection.isEmpty()) - return; - updater = new Cancelable() { - @Override - protected void doJob() { - updateSelection(selection); - } - }; - Display.getCurrent().timerExec(150, updater); - } - - private void updateSelection(ISelection selection) { - Object sel = ((IStructuredSelection) selection).getFirstElement(); - if (sel == sourceSheet) { - setIndex(revisions.size()); - } else { - setIndex(revisions.indexOf(sel)); - } - } - - } - - private Shell parentShell; - - private ISheet sourceSheet; - - private List revisions; - - private int index; - - private PageBook pageBook; - - private NavigationViewer navBar = null; - - private Map viewers = new HashMap(); - - private MindMapViewer viewer = null; - - private Control corruptionWarning = null; - - private Rectangle actualBounds = null; - - private Listener widgetListener = new Listener() { - public void handleEvent(Event event) { - if ((event.type == SWT.Traverse - && event.detail == SWT.TRAVERSE_ESCAPE) - || (event.type == SWT.KeyDown - && (SWTUtils.matchKey(event.stateMask, - event.keyCode, 0, SWT.ESC) - || SWTUtils.matchKey(event.stateMask, - event.keyCode, 0, SWT.SPACE)))) { - close(); - } - } - }; - - /** - * @param parentShell - * @param revisions - */ - public RevisionPreviewDialog(Shell parentShell, ISheet sourceSheet, - List revisions, int index) { - super(NO_PARENT_SHELL); - this.parentShell = parentShell; - this.sourceSheet = sourceSheet; - this.revisions = revisions; - this.index = index; - setShellStyle(SWT.DIALOG_TRIM | SWT.MAX | SWT.MIN | SWT.RESIZE - | getDefaultOrientation()); - setBlockOnOpen(false); - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#isResizable() - */ - @Override - protected boolean isResizable() { - return true; - } - - public void update() { - Object selection = getSelection(); - updateShellTitle(selection); - showPreviewViewer(selection); - updateNavBar(selection); - } - - /** - * - */ - private void updateNavBar(Object selection) { - navBar.setSelection(new StructuredSelection(selection)); - navBar.getControl().setFocus(); - hookWidget(navBar.getControl()); - } - - private Object getSelection() { - if (index < 0) - return null; - if (index >= revisions.size()) { - return sourceSheet; - } - return revisions.get(index); - } - - private void updateShellTitle(Object selection) { - String sheetTitle = String.format("\"%s - %s\"", //$NON-NLS-1$ - sourceSheet.getTitleText(), - sourceSheet.getRootTopic().getTitleText()); - String title; - if (selection instanceof IRevision) { - title = NLS.bind( - DialogMessages.RevisionPreviewDialog_Revision_titlePattern, - String.valueOf(((IRevision) selection).getRevisionNumber()), - sheetTitle); - } else { - title = NLS.bind( - DialogMessages.RevisionPreviewDialog_CurrentRevision_title, - sheetTitle); - } - getShell().setText(title); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets - * .Composite) - */ - @Override - protected Control createContents(Composite parent) { - Color background = parent.getDisplay() - .getSystemColor(SWT.COLOR_LIST_BACKGROUND); - parent.setBackground(background); - - Composite container = new Composite(parent, SWT.NONE); - container.setLayout(new ContainerLayout()); - container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - container.setBackground(background); - - pageBook = new PageBook(container, SWT.NONE); - pageBook.setBackground(background); - hookWidget(pageBook); - - createNavigationBar(container); - - return pageBook; - } - - /** - * @param control - */ - private void hookWidget(Control control) { - control.addListener(SWT.Traverse, widgetListener); - control.addListener(SWT.KeyDown, widgetListener); - } - - /** - * @param container - * @return - */ - private void createNavigationBar(Composite parent) { - navBar = new NavigationViewer(); - navBar.setContentProvider(new ArrayContentProvider()); - navBar.setLabelProvider(new NavigationLabelProvider()); - navBar.createControl(parent); - Object[] elements = new Object[revisions.size() + 1]; - revisions.toArray(elements); - elements[elements.length - 1] = sourceSheet; - navBar.setInput(elements); - navBar.addSelectionChangedListener( - new NavigationSelectionChangedListener()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - gridData.heightHint = 0; - gridData.verticalAlignment = 0; - gridData.verticalIndent = 0; - gridData.verticalSpan = 0; - navBar.getControl(); - hookWidget(navBar.getControl()); - } - - private void showPreviewViewer(Object selection) { - if (selection instanceof IRevision) { - IRevision revision = (IRevision) selection; - ISheet sheet = (ISheet) revision.getContent(); - if (sheet == null) { - pageBook.showPage(getCorruptionWarning()); - } else { - viewer = getRevisionViewer(revision, sheet); - pageBook.showPage(viewer.getControl()); - } - } else { - viewer = getRevisionViewer(sourceSheet, sourceSheet); - pageBook.showPage(viewer.getControl()); - } - } - - private Control getCorruptionWarning() { - if (corruptionWarning == null) { - corruptionWarning = createCorruptionWarning(); - } - return corruptionWarning; - } - - /** - * @return - */ - private Control createCorruptionWarning() { - Composite composite = new Composite(pageBook, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 5; - layout.marginHeight = 5; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - label.setText( - DialogMessages.RevisionPreviewDialog_CorruptedRevision_message); - - return composite; - } - - private MindMapViewer getRevisionViewer(Object selection, ISheet sheet) { - MindMapViewer viewer = viewers.get(selection); - if (viewer == null) { - viewer = createViewer(pageBook, sheet); - viewers.put(selection, viewer); - } - return viewer; - } - - public MindMapViewer createViewer(Composite parent, ISheet sheet) { - MindMapViewer viewer = new RevisionMindMapViewer(); - initViewer(viewer); - viewer.createControl(parent); - viewer.getCanvas().setScrollBarVisibility(FigureCanvas.AUTOMATIC); - hookWidget(viewer.getControl()); - viewer.setInput(new MindMap(sheet)); - return viewer; - } - - public void initViewer(MindMapViewer viewer) { - viewer.getProperties().set(IMindMapViewer.VIEWER_CENTERED, true); - viewer.getProperties().set(IMindMapViewer.VIEWER_MARGIN, 50); - viewer.getProperties().set(IMindMapViewer.VIEWER_CORNERED, true); - - IRevealService revealService = new MindMapRevealService(viewer); - viewer.installService(IRevealService.class, revealService); - revealService.setActive(true); - - ITool tool = new DefaultPreviewTool(); - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_DEFAULT, tool); - editDomain.setDefaultTool(GEF.TOOL_DEFAULT); - viewer.setEditDomain(editDomain); - } - - @Override - protected IDialogSettings getDialogBoundsSettings() { - return MindMapUIPlugin.getDefault() - .getDialogSettings("org.xmind.ui.RevisionsDialog"); //$NON-NLS-1$ - } - - protected Point getInitialSize() { - IDialogSettings settings = getDialogBoundsSettings(); - if (settings.getBoolean(USE_STORED_SIZE)) { - return super.getInitialSize(); - } - settings.put(USE_STORED_SIZE, true); - return new Point(720, 620); - } - - private void setIndex(int index) { - index = Math.max(0, Math.min(revisions.size(), index)); - if (index == this.index) - return; - this.index = index; - update(); - } - - private void asyncExec(final Runnable job) { - parentShell.getDisplay().asyncExec(new Runnable() { - public void run() { - if (getShell() == null || getShell().isDisposed()) - return; - job.run(); - } - }); - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.window.Window#open() - */ - @Override - public int open() { - if (getShell() == null || getShell().isDisposed()) { - create(); - } - constrainShellSize(); - - update(); - - // open the window - getShell().open(); - return OK; - } - - public void open(Rectangle sourceBounds) { - if (getShell() == null || getShell().isDisposed()) { - create(); - } - constrainShellSize(); - - Shell shell = getShell(); - actualBounds = shell.getBounds(); - - shell.setRedraw(false); - shell.setBounds(sourceBounds); - shell.setAlpha(0); - shell.setVisible(true); - shell.setActive(); - shell.setFocus(); - - long start = System.currentTimeMillis(); - long end = start + 200; - animateOpening(shell, sourceBounds, start, end); - } - - /** - * @param shell - * @param r1 - * @param r2 - */ - private void animateOpening(final Shell shell, final Rectangle r1, - final long start, final long end) { - if (shell.isDisposed() || actualBounds == null) - return; - - long time = System.currentTimeMillis(); - if (time > end) { - finishOpening(shell); - } else { - double percent = ((double) (time - start)) - / ((double) (end - start)); - int alpha = (int) (255 * percent); - Rectangle r2 = actualBounds; - int x = (int) ((r2.x - r1.x) * percent + r1.x); - int y = (int) ((r2.y - r1.y) * percent + r1.y); - int width = (int) ((r2.width - r1.width) * percent + r1.width); - int height = (int) ((r2.height - r1.height) * percent + r1.height); - shell.setAlpha(alpha); - shell.setBounds(x, y, width, height); - shell.getDisplay().timerExec(5, new Runnable() { - public void run() { - animateOpening(shell, r1, start, end); - } - }); - } - } - - /** - * @param shell - * @param targetBounds - */ - private void finishOpening(Shell shell) { - if (shell.isDisposed() || actualBounds == null) - return; - - shell.setBounds(actualBounds); - shell.setAlpha(255); - shell.setVisible(true); - shell.setActive(); - shell.setFocus(); - update(); - shell.setRedraw(true); - actualBounds = null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#close() - */ - @Override - public boolean close() { - Shell shell = getShell(); - if (shell != null && !shell.isDisposed() && actualBounds != null) { - shell.setBounds(actualBounds); - actualBounds = null; - } - return super.close(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.dialogs; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.part.PageBook; +import org.xmind.core.IRevision; +import org.xmind.core.ISheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.event.KeyEvent; +import org.xmind.gef.service.IRevealService; +import org.xmind.gef.tool.BrowsingTool; +import org.xmind.gef.tool.ITool; +import org.xmind.ui.gallery.NavigationViewer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.mindmap.MindMapRevealService; +import org.xmind.ui.internal.mindmap.MindMapViewer; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.MindMap; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.Cancelable; +import org.xmind.ui.util.ICancelable; +import org.xmind.ui.viewers.SWTUtils; + +/** + * @author Frank Shaka + */ +public class RevisionPreviewDialog extends Dialog { + + private class RevisionMindMapViewer extends MindMapViewer { + protected Control internalCreateControl(Composite parent, int style) { + FigureCanvas canvas = new FigureCanvas(parent, style, + getLightweightSystem()); + canvas.setViewport(getViewport()); + return canvas; + } + } + + private static final String USE_STORED_SIZE = "USE_STORED_SIZE"; //$NON-NLS-1$ + + private static final IShellProvider NO_PARENT_SHELL = new IShellProvider() { + public Shell getShell() { + return null; + } + }; + + private class DefaultPreviewTool extends BrowsingTool { + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.tool.AbstractTool#handleKeyDown(org.xmind.gef.event + * .KeyEvent) + */ + @Override + protected boolean handleKeyDown(KeyEvent ke) { + if (SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, + SWT.ARROW_LEFT)) { + asyncExec(new Runnable() { + public void run() { + setIndex(index - 1); + } + }); + } else if (SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, + SWT.ARROW_RIGHT)) { + asyncExec(new Runnable() { + public void run() { + setIndex(index + 1); + } + }); + } + return super.handleKeyDown(ke); + } + + } + + private class ContainerLayout extends Layout { + + /* + * (non-Javadoc) + * @see + * org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets + * .Composite, int, int, boolean) + */ + @Override + protected org.eclipse.swt.graphics.Point computeSize( + Composite composite, int wHint, int hHint, boolean flushCache) { + if (wHint < 0 || hHint < 0) { + Control[] children = composite.getChildren(); + int w = Math.max(0, wHint); + int h = Math.max(0, hHint); + for (int i = 0; i < children.length; i++) { + Control child = children[i]; + Point childSize = child.getSize(); + w = Math.max(w, childSize.x); + h = Math.max(h, childSize.y); + } + return new org.eclipse.swt.graphics.Point(w, h); + } + return new org.eclipse.swt.graphics.Point(wHint, hHint); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets. + * Composite , boolean) + */ + @Override + protected void layout(Composite composite, boolean flushCache) { + Rectangle area = composite.getClientArea(); + int h = NavigationViewer.BIG_HEIGHT + 20; + pageBook.setBounds(area.x, area.y, area.width, area.height - h); + navBar.getControl().setBounds(area.x, area.y + area.height - h, + area.width, h); + } + + } + + private static class NavigationLabelProvider extends LabelProvider + implements IFontProvider { + + private Font font; + + private Image image = null; + + /** + * + */ + public NavigationLabelProvider() { + this.font = FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, 32); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + if (element instanceof IRevision) { + IRevision revision = (IRevision) element; + return String.valueOf(revision.getRevisionNumber()); + } + return ""; //$NON-NLS-1$ + } + + @Override + public Image getImage(Object element) { + if (element instanceof ISheet) { + return getSheetImage(); + } + return super.getImage(element); + } + + private Image getSheetImage() { + if (image == null) { + image = MindMapUI.getImages() + .get(IMindMapImages.DEFAULT_THUMBNAIL).createImage(); + } + return image; + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object) + */ + public Font getFont(Object element) { + return font; + } + + @Override + public void dispose() { + if (image != null) { + image.dispose(); + image = null; + } + super.dispose(); + } + } + + private class NavigationSelectionChangedListener + implements ISelectionChangedListener { + + private ICancelable updater = null; + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged + * (org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + if (updater != null) { + updater.cancel(); + } + final ISelection selection = event.getSelection(); + if (selection.isEmpty()) + return; + updater = new Cancelable() { + @Override + protected void doJob() { + updateSelection(selection); + } + }; + Display.getCurrent().timerExec(150, updater); + } + + private void updateSelection(ISelection selection) { + Object sel = ((IStructuredSelection) selection).getFirstElement(); + if (sel == sourceSheet) { + setIndex(revisions.size()); + } else { + setIndex(revisions.indexOf(sel)); + } + } + + } + + private Shell parentShell; + + private ISheet sourceSheet; + + private List revisions; + + private int index; + + private PageBook pageBook; + + private NavigationViewer navBar = null; + + private Map viewers = new HashMap(); + + private MindMapViewer viewer = null; + + private Control corruptionWarning = null; + + private Rectangle actualBounds = null; + + private Listener widgetListener = new Listener() { + public void handleEvent(Event event) { + if ((event.type == SWT.Traverse + && event.detail == SWT.TRAVERSE_ESCAPE) + || (event.type == SWT.KeyDown + && (SWTUtils.matchKey(event.stateMask, + event.keyCode, 0, SWT.ESC) + || SWTUtils.matchKey(event.stateMask, + event.keyCode, 0, SWT.SPACE)))) { + close(); + } + } + }; + + /** + * @param parentShell + * @param revisions + */ + public RevisionPreviewDialog(Shell parentShell, ISheet sourceSheet, + List revisions, int index) { + super(NO_PARENT_SHELL); + this.parentShell = parentShell; + this.sourceSheet = sourceSheet; + this.revisions = revisions; + this.index = index; + setShellStyle(SWT.DIALOG_TRIM | SWT.MAX | SWT.MIN | SWT.RESIZE + | getDefaultOrientation()); + setBlockOnOpen(false); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#isResizable() + */ + @Override + protected boolean isResizable() { + return true; + } + + public void update() { + Object selection = getSelection(); + updateShellTitle(selection); + showPreviewViewer(selection); + updateNavBar(selection); + } + + /** + * + */ + private void updateNavBar(Object selection) { + navBar.setSelection(new StructuredSelection(selection)); + navBar.getControl().setFocus(); + hookWidget(navBar.getControl()); + } + + private Object getSelection() { + if (index < 0) + return null; + if (index >= revisions.size()) { + return sourceSheet; + } + return revisions.get(index); + } + + private void updateShellTitle(Object selection) { + String sheetTitle = String.format("\"%s - %s\"", //$NON-NLS-1$ + sourceSheet.getTitleText(), + sourceSheet.getRootTopic().getTitleText()); + String title; + if (selection instanceof IRevision) { + title = NLS.bind( + DialogMessages.RevisionPreviewDialog_Revision_titlePattern, + String.valueOf(((IRevision) selection).getRevisionNumber()), + sheetTitle); + } else { + title = NLS.bind( + DialogMessages.RevisionPreviewDialog_CurrentRevision_title, + sheetTitle); + } + getShell().setText(title); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets + * .Composite) + */ + @Override + protected Control createContents(Composite parent) { + Color background = parent.getDisplay() + .getSystemColor(SWT.COLOR_LIST_BACKGROUND); + parent.setBackground(background); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new ContainerLayout()); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + container.setBackground(background); + + pageBook = new PageBook(container, SWT.NONE); + pageBook.setBackground(background); + hookWidget(pageBook); + + createNavigationBar(container); + + return pageBook; + } + + /** + * @param control + */ + private void hookWidget(Control control) { + control.addListener(SWT.Traverse, widgetListener); + control.addListener(SWT.KeyDown, widgetListener); + } + + /** + * @param container + * @return + */ + private void createNavigationBar(Composite parent) { + navBar = new NavigationViewer(); + navBar.setContentProvider(new ArrayContentProvider()); + navBar.setLabelProvider(new NavigationLabelProvider()); + navBar.createControl(parent); + Object[] elements = new Object[revisions.size() + 1]; + revisions.toArray(elements); + elements[elements.length - 1] = sourceSheet; + navBar.setInput(elements); + navBar.addSelectionChangedListener( + new NavigationSelectionChangedListener()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + gridData.heightHint = 0; + gridData.verticalAlignment = 0; + gridData.verticalIndent = 0; + gridData.verticalSpan = 0; + navBar.getControl(); + hookWidget(navBar.getControl()); + } + + private void showPreviewViewer(Object selection) { + if (selection instanceof IRevision) { + IRevision revision = (IRevision) selection; + ISheet sheet = (ISheet) revision.getContent(); + if (sheet == null) { + pageBook.showPage(getCorruptionWarning()); + } else { + viewer = getRevisionViewer(revision, sheet); + pageBook.showPage(viewer.getControl()); + } + } else { + viewer = getRevisionViewer(sourceSheet, sourceSheet); + pageBook.showPage(viewer.getControl()); + } + } + + private Control getCorruptionWarning() { + if (corruptionWarning == null) { + corruptionWarning = createCorruptionWarning(); + } + return corruptionWarning; + } + + /** + * @return + */ + private Control createCorruptionWarning() { + Composite composite = new Composite(pageBook, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 5; + layout.marginHeight = 5; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + label.setText( + DialogMessages.RevisionPreviewDialog_CorruptedRevision_message); + + return composite; + } + + private MindMapViewer getRevisionViewer(Object selection, ISheet sheet) { + MindMapViewer viewer = viewers.get(selection); + if (viewer == null) { + viewer = createViewer(pageBook, sheet); + viewers.put(selection, viewer); + } + return viewer; + } + + public MindMapViewer createViewer(Composite parent, ISheet sheet) { + MindMapViewer viewer = new RevisionMindMapViewer(); + initViewer(viewer); + viewer.createControl(parent); + viewer.getCanvas().setScrollBarVisibility(FigureCanvas.AUTOMATIC); + hookWidget(viewer.getControl()); + viewer.setInput(new MindMap(sheet)); + return viewer; + } + + public void initViewer(MindMapViewer viewer) { + viewer.getProperties().set(IMindMapViewer.VIEWER_CENTERED, true); + viewer.getProperties().set(IMindMapViewer.VIEWER_MARGIN, 50); + viewer.getProperties().set(IMindMapViewer.VIEWER_CORNERED, true); + + IRevealService revealService = new MindMapRevealService(viewer); + viewer.installService(IRevealService.class, revealService); + revealService.setActive(true); + + ITool tool = new DefaultPreviewTool(); + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_DEFAULT, tool); + editDomain.setDefaultTool(GEF.TOOL_DEFAULT); + viewer.setEditDomain(editDomain); + } + + @Override + protected IDialogSettings getDialogBoundsSettings() { + return MindMapUIPlugin.getDefault() + .getDialogSettings("org.xmind.ui.RevisionsDialog"); //$NON-NLS-1$ + } + + protected Point getInitialSize() { + IDialogSettings settings = getDialogBoundsSettings(); + if (settings.getBoolean(USE_STORED_SIZE)) { + return super.getInitialSize(); + } + settings.put(USE_STORED_SIZE, true); + return new Point(720, 620); + } + + private void setIndex(int index) { + index = Math.max(0, Math.min(revisions.size(), index)); + if (index == this.index) + return; + this.index = index; + update(); + } + + private void asyncExec(final Runnable job) { + parentShell.getDisplay().asyncExec(new Runnable() { + public void run() { + if (getShell() == null || getShell().isDisposed()) + return; + job.run(); + } + }); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.window.Window#open() + */ + @Override + public int open() { + if (getShell() == null || getShell().isDisposed()) { + create(); + } + constrainShellSize(); + + update(); + + // open the window + getShell().open(); + return OK; + } + + public void open(Rectangle sourceBounds) { + if (getShell() == null || getShell().isDisposed()) { + create(); + } + constrainShellSize(); + + Shell shell = getShell(); + actualBounds = shell.getBounds(); + + shell.setRedraw(false); + shell.setBounds(sourceBounds); + shell.setAlpha(0); + shell.setVisible(true); + shell.setActive(); + shell.setFocus(); + + long start = System.currentTimeMillis(); + long end = start + 200; + animateOpening(shell, sourceBounds, start, end); + } + + /** + * @param shell + * @param r1 + * @param r2 + */ + private void animateOpening(final Shell shell, final Rectangle r1, + final long start, final long end) { + if (shell.isDisposed() || actualBounds == null) + return; + + long time = System.currentTimeMillis(); + if (time > end) { + finishOpening(shell); + } else { + double percent = ((double) (time - start)) + / ((double) (end - start)); + int alpha = (int) (255 * percent); + Rectangle r2 = actualBounds; + int x = (int) ((r2.x - r1.x) * percent + r1.x); + int y = (int) ((r2.y - r1.y) * percent + r1.y); + int width = (int) ((r2.width - r1.width) * percent + r1.width); + int height = (int) ((r2.height - r1.height) * percent + r1.height); + shell.setAlpha(alpha); + shell.setBounds(x, y, width, height); + shell.getDisplay().timerExec(5, new Runnable() { + public void run() { + animateOpening(shell, r1, start, end); + } + }); + } + } + + /** + * @param shell + * @param targetBounds + */ + private void finishOpening(Shell shell) { + if (shell.isDisposed() || actualBounds == null) + return; + + shell.setBounds(actualBounds); + shell.setAlpha(255); + shell.setVisible(true); + shell.setActive(); + shell.setFocus(); + update(); + shell.setRedraw(true); + actualBounds = null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#close() + */ + @Override + public boolean close() { + Shell shell = getShell(); + if (shell != null && !shell.isDisposed() && actualBounds != null) { + shell.setBounds(actualBounds); + actualBounds = null; + } + return super.close(); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/SaveWizardDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/SaveWizardDialog.java index f3f1208e3..3cc8c4ccc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/SaveWizardDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/SaveWizardDialog.java @@ -1,202 +1,202 @@ -package org.xmind.ui.internal.dialogs; - -import java.util.List; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.editor.SaveWizardManager.SaveWizardDescriptor; -import org.xmind.ui.wizards.SaveOptions; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class SaveWizardDialog extends Dialog { - - private List wizards; - - private SaveWizardDescriptor targetWizard; - - private SaveOptions targetOptions; - - private boolean prepareForSpace = false; - - private Button defaultButton; - - public SaveWizardDialog(Shell parentShell, - List wizards, - SaveWizardDescriptor targetWizard, SaveOptions targetOptions) { - super(parentShell); - this.wizards = wizards; - this.targetWizard = targetWizard; - this.targetOptions = targetOptions == null ? SaveOptions.getDefault() - : targetOptions; - } - - public SaveWizardDescriptor getTargetWizard() { - return targetWizard; - } - - public SaveOptions getTargetOptions() { - return targetOptions; - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(MindMapMessages.SaveWizardDialog_shell_title); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); - layoutData.widthHint = 360; - layoutData.heightHint = SWT.DEFAULT; - composite.setLayoutData(layoutData); - - createNameField(composite); - createWizardChoiceField(composite); - - return composite; - } - - private void createNameField(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); - layoutData.widthHint = SWT.DEFAULT; - layoutData.heightHint = SWT.DEFAULT; - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 5; - layout.horizontalSpacing = 5; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - label.setText(MindMapMessages.SaveWizardDialog_name_text); - - Text text = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - text.setText(targetOptions.proposalName()); - - text.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - String content = ((Text) e.widget).getText(); - if (content.contains("\r")) { //$NON-NLS-1$ - content = content.replaceAll("\n\r", " "); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - content = content.replaceAll("\n", " "); //$NON-NLS-1$ //$NON-NLS-2$ - } - targetOptions = targetOptions.proposalName(content); - } - }); - - text.addKeyListener(new KeyListener() { - - @Override - public void keyReleased(KeyEvent e) { - if (e.keyCode == SWT.SHIFT) { - prepareForSpace = false; - while (getShell().getDefaultButton() != defaultButton) { - getShell().setDefaultButton(defaultButton); - } - } - } - - @Override - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.SHIFT) { - prepareForSpace = true; - while (getShell().getDefaultButton() != null) - getShell().setDefaultButton(null); - getShell().update(); - } else if (e.keyCode == SWT.CR) { - if (prepareForSpace) { - if (e.widget instanceof Text) { - ((Text) e.widget).insert(" "); //$NON-NLS-1$ - } - } - } - } - }); - } - - private void createWizardChoiceField(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); - layoutData.widthHint = SWT.DEFAULT; - layoutData.heightHint = SWT.DEFAULT; - composite.setLayoutData(layoutData); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 10; - layout.verticalSpacing = 5; - layout.horizontalSpacing = 5; - composite.setLayout(layout); - - Label label = new Label(composite, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); - label.setText(MindMapMessages.SaveWizardDialog_location_text); - - Composite radioGroup = new Composite(composite, SWT.NONE); - GridLayout radioLayout = new GridLayout(1, false); - radioLayout.marginWidth = 0; - radioLayout.marginHeight = 0; - radioLayout.verticalSpacing = 5; - radioLayout.horizontalSpacing = 5; - radioGroup.setLayout(radioLayout); - - for (final SaveWizardDescriptor wizard : wizards) { - Button wizardRadio = new Button(radioGroup, SWT.RADIO); - wizardRadio.setText(wizard.getName()); - wizardRadio.setData(wizard); - wizardRadio.setSelection(wizard.equals(targetWizard)); - wizardRadio.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - targetWizard = (SaveWizardDescriptor) e.widget.getData(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - okPressed(); - } - }); - } - - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - defaultButton = createButton(parent, IDialogConstants.OK_ID, - MindMapMessages.SaveWizardDialog_okButton_text, true); - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - } - -} +package org.xmind.ui.internal.dialogs; + +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.editor.SaveWizardManager.SaveWizardDescriptor; +import org.xmind.ui.wizards.SaveOptions; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class SaveWizardDialog extends Dialog { + + private List wizards; + + private SaveWizardDescriptor targetWizard; + + private SaveOptions targetOptions; + + private boolean prepareForSpace = false; + + private Button defaultButton; + + public SaveWizardDialog(Shell parentShell, + List wizards, + SaveWizardDescriptor targetWizard, SaveOptions targetOptions) { + super(parentShell); + this.wizards = wizards; + this.targetWizard = targetWizard; + this.targetOptions = targetOptions == null ? SaveOptions.getDefault() + : targetOptions; + } + + public SaveWizardDescriptor getTargetWizard() { + return targetWizard; + } + + public SaveOptions getTargetOptions() { + return targetOptions; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(MindMapMessages.SaveWizardDialog_shell_title); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.widthHint = 360; + layoutData.heightHint = SWT.DEFAULT; + composite.setLayoutData(layoutData); + + createNameField(composite); + createWizardChoiceField(composite); + + return composite; + } + + private void createNameField(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + layoutData.widthHint = SWT.DEFAULT; + layoutData.heightHint = SWT.DEFAULT; + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 5; + layout.horizontalSpacing = 5; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + label.setText(MindMapMessages.SaveWizardDialog_name_text); + + Text text = new Text(composite, SWT.SINGLE | SWT.LEAD | SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + text.setText(targetOptions.proposalName()); + + text.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + String content = ((Text) e.widget).getText(); + if (content.contains("\r")) { //$NON-NLS-1$ + content = content.replaceAll("\n\r", " "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + content = content.replaceAll("\n", " "); //$NON-NLS-1$ //$NON-NLS-2$ + } + targetOptions = targetOptions.proposalName(content); + } + }); + + text.addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + if (e.keyCode == SWT.SHIFT) { + prepareForSpace = false; + while (getShell().getDefaultButton() != defaultButton) { + getShell().setDefaultButton(defaultButton); + } + } + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.SHIFT) { + prepareForSpace = true; + while (getShell().getDefaultButton() != null) + getShell().setDefaultButton(null); + getShell().update(); + } else if (e.keyCode == SWT.CR) { + if (prepareForSpace) { + if (e.widget instanceof Text) { + ((Text) e.widget).insert(" "); //$NON-NLS-1$ + } + } + } + } + }); + } + + private void createWizardChoiceField(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.widthHint = SWT.DEFAULT; + layoutData.heightHint = SWT.DEFAULT; + composite.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 10; + layout.verticalSpacing = 5; + layout.horizontalSpacing = 5; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + label.setText(MindMapMessages.SaveWizardDialog_location_text); + + Composite radioGroup = new Composite(composite, SWT.NONE); + GridLayout radioLayout = new GridLayout(1, false); + radioLayout.marginWidth = 0; + radioLayout.marginHeight = 0; + radioLayout.verticalSpacing = 5; + radioLayout.horizontalSpacing = 5; + radioGroup.setLayout(radioLayout); + + for (final SaveWizardDescriptor wizard : wizards) { + Button wizardRadio = new Button(radioGroup, SWT.RADIO); + wizardRadio.setText(wizard.getName()); + wizardRadio.setData(wizard); + wizardRadio.setSelection(wizard.equals(targetWizard)); + wizardRadio.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + targetWizard = (SaveWizardDescriptor) e.widget.getData(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + okPressed(); + } + }); + } + + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + defaultButton = createButton(parent, IDialogConstants.OK_ID, + MindMapMessages.SaveWizardDialog_okButton_text, true); + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ShareDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ShareDialog.java index dd79c5444..e8cbd536f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ShareDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ShareDialog.java @@ -1,269 +1,269 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.dialogs; - -import java.util.List; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.internal.ShareOption; -import org.xmind.ui.internal.ShareOptionRegistry; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; - -/** - * @author Frank Shaka - * @author Shawn Liu - * @since 3.6.50 - */ -public class ShareDialog extends Dialog { - - private static final String ID_KEY = "org.xmind.share.option.id"; //$NON-NLS-1$ - - private static final String COLOR_BACKGROUND = "#FFFFFF"; //$NON-NLS-1$ - private static final String COLOR_SEPARATOR = "#D9D9D9"; //$NON-NLS-1$ - private static final String COLOR_TEXT = "#555555"; //$NON-NLS-1$ - - private ShareOptionRegistry optionRegistry; - - private ShareOption selectedOption; - - private ResourceManager resources; - - private Listener eventHandler = new Listener() { - public void handleEvent(Event event) { - handleWidgetEvent(event); - } - }; - - public ShareDialog(Shell parentShell, ShareOptionRegistry optionRegistry) { - super(parentShell); - this.optionRegistry = optionRegistry; - this.selectedOption = null; - setBlockOnOpen(true); - } - - /** - * @return the selectedOption - */ - public ShareOption getSelectedOption() { - return selectedOption; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#create() - */ - @Override - public void create() { - super.create(); - getShell().setText(DialogMessages.ShareDialog_dialog_title); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets. - * Shell) - */ - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - resources = new LocalResourceManager(JFaceResources.getResources(), - newShell); - } - - @Override - protected Control createButtonBar(Composite parent) { - return null; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setBackground((Color) resources - .get(ColorUtils.toDescriptor(COLOR_BACKGROUND))); - - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - applyDialogFont(composite); - - createTopSection(composite); - createSeparator(composite); - createBottomSection(composite); - - return composite; - } - - private void createTopSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - - GridLayout layout = new GridLayout(3, true); - layout.marginWidth = 31; - layout.marginHeight = 26; - layout.marginTop = 10; - layout.horizontalSpacing = 20; - composite.setLayout(layout); - - List options = optionRegistry - .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_POPULAR); - for (ShareOption option : options) { - createShareItem(composite, option.getLabel(), - (Image) resources.get(option.getImage()), option.getId(), 3, - 8); - } - } - - private void createSeparator(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); - composite.setLayoutData(layoutData); - composite.setBackground(parent.getBackground()); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - composite.setLayout(layout); - - Composite separator = new Composite(composite, SWT.NONE); - GridData layoutData2 = new GridData(SWT.FILL, SWT.CENTER, true, false); - separator.setLayoutData(layoutData2); - layoutData2.heightHint = 1; - separator.setBackground((Color) resources - .get(ColorUtils.toDescriptor(COLOR_SEPARATOR))); - separator.setLayout(new GridLayout()); - } - - private void createBottomSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - - GridLayout layout = new GridLayout(4, true); - layout.marginWidth = 22; - layout.marginHeight = 28; - layout.marginBottom = 16; - layout.horizontalSpacing = 38; - layout.verticalSpacing = 24; - composite.setLayout(layout); - - List options = optionRegistry - .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_NORMAL); - for (ShareOption option : options) { - createShareItem(composite, option.getLabel(), - (Image) resources.get(option.getImage()), option.getId(), 0, - 5); - } - } - - private Control createShareItem(Composite parent, String text, Image image, - String id, int relativeHeight, int verticalSpacing) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - - GridLayout layout = new GridLayout(1, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = verticalSpacing; - composite.setLayout(layout); - - Label imageLabel = new Label(composite, SWT.NONE); - imageLabel.setBackground(composite.getBackground()); - imageLabel - .setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false)); - imageLabel.setImage(image); - - Label textLabel = new Label(composite, SWT.WRAP); - textLabel.setBackground(composite.getBackground()); - - GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, false, false); - layoutData.widthHint = image.getBounds().width + 20; - textLabel.setLayoutData(layoutData); - textLabel.setForeground( - (Color) resources.get(ColorUtils.toDescriptor(COLOR_TEXT))); - textLabel.setAlignment(SWT.CENTER); - textLabel.setFont((Font) resources - .get(FontDescriptor.createFrom(FontUtils.relativeHeight( - textLabel.getFont().getFontData(), relativeHeight)))); - textLabel.setText(text); - - composite.setCursor( - parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - imageLabel.setCursor( - parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - textLabel.setCursor( - parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - - //add mouse down event - composite.setData(ID_KEY, id); - imageLabel.setData(ID_KEY, id); - textLabel.setData(ID_KEY, id); - - hookWidget(composite, SWT.MouseDown); - hookWidget(imageLabel, SWT.MouseDown); - hookWidget(textLabel, SWT.MouseDown); - - return composite; - } - - private void hookWidget(Widget widget, int eventType) { - widget.addListener(eventType, eventHandler); - } - - private void handleWidgetEvent(Event event) { - String id = (String) event.widget.getData(ID_KEY); - if (id == null) - return; - - selectedOption = optionRegistry.getOptionById(id); - if (selectedOption == null) - return; - - okPressed(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.dialogs; + +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.internal.ShareOption; +import org.xmind.ui.internal.ShareOptionRegistry; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; + +/** + * @author Frank Shaka + * @author Shawn Liu + * @since 3.6.50 + */ +public class ShareDialog extends Dialog { + + private static final String ID_KEY = "org.xmind.share.option.id"; //$NON-NLS-1$ + + private static final String COLOR_BACKGROUND = "#FFFFFF"; //$NON-NLS-1$ + private static final String COLOR_SEPARATOR = "#D9D9D9"; //$NON-NLS-1$ + private static final String COLOR_TEXT = "#555555"; //$NON-NLS-1$ + + private ShareOptionRegistry optionRegistry; + + private ShareOption selectedOption; + + private ResourceManager resources; + + private Listener eventHandler = new Listener() { + public void handleEvent(Event event) { + handleWidgetEvent(event); + } + }; + + public ShareDialog(Shell parentShell, ShareOptionRegistry optionRegistry) { + super(parentShell); + this.optionRegistry = optionRegistry; + this.selectedOption = null; + setBlockOnOpen(true); + } + + /** + * @return the selectedOption + */ + public ShareOption getSelectedOption() { + return selectedOption; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#create() + */ + @Override + public void create() { + super.create(); + getShell().setText(DialogMessages.ShareDialog_dialog_title); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets. + * Shell) + */ + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + resources = new LocalResourceManager(JFaceResources.getResources(), + newShell); + } + + @Override + protected Control createButtonBar(Composite parent) { + return null; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setBackground((Color) resources + .get(ColorUtils.toDescriptor(COLOR_BACKGROUND))); + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + applyDialogFont(composite); + + createTopSection(composite); + createSeparator(composite); + createBottomSection(composite); + + return composite; + } + + private void createTopSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + + GridLayout layout = new GridLayout(3, true); + layout.marginWidth = 31; + layout.marginHeight = 26; + layout.marginTop = 10; + layout.horizontalSpacing = 20; + composite.setLayout(layout); + + List options = optionRegistry + .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_POPULAR); + for (ShareOption option : options) { + createShareItem(composite, option.getLabel(), + (Image) resources.get(option.getImage()), option.getId(), 3, + 8); + } + } + + private void createSeparator(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + composite.setLayoutData(layoutData); + composite.setBackground(parent.getBackground()); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + + Composite separator = new Composite(composite, SWT.NONE); + GridData layoutData2 = new GridData(SWT.FILL, SWT.CENTER, true, false); + separator.setLayoutData(layoutData2); + layoutData2.heightHint = 1; + separator.setBackground((Color) resources + .get(ColorUtils.toDescriptor(COLOR_SEPARATOR))); + separator.setLayout(new GridLayout()); + } + + private void createBottomSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + + GridLayout layout = new GridLayout(4, true); + layout.marginWidth = 22; + layout.marginHeight = 28; + layout.marginBottom = 16; + layout.horizontalSpacing = 38; + layout.verticalSpacing = 24; + composite.setLayout(layout); + + List options = optionRegistry + .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_NORMAL); + for (ShareOption option : options) { + createShareItem(composite, option.getLabel(), + (Image) resources.get(option.getImage()), option.getId(), 0, + 5); + } + } + + private Control createShareItem(Composite parent, String text, Image image, + String id, int relativeHeight, int verticalSpacing) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); + composite.setBackground(parent.getBackground()); + composite.setForeground(parent.getForeground()); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = verticalSpacing; + composite.setLayout(layout); + + Label imageLabel = new Label(composite, SWT.NONE); + imageLabel.setBackground(composite.getBackground()); + imageLabel + .setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false)); + imageLabel.setImage(image); + + Label textLabel = new Label(composite, SWT.WRAP); + textLabel.setBackground(composite.getBackground()); + + GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, false, false); + layoutData.widthHint = image.getBounds().width + 20; + textLabel.setLayoutData(layoutData); + textLabel.setForeground( + (Color) resources.get(ColorUtils.toDescriptor(COLOR_TEXT))); + textLabel.setAlignment(SWT.CENTER); + textLabel.setFont((Font) resources + .get(FontDescriptor.createFrom(FontUtils.relativeHeight( + textLabel.getFont().getFontData(), relativeHeight)))); + textLabel.setText(text); + + composite.setCursor( + parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + imageLabel.setCursor( + parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + textLabel.setCursor( + parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + + //add mouse down event + composite.setData(ID_KEY, id); + imageLabel.setData(ID_KEY, id); + textLabel.setData(ID_KEY, id); + + hookWidget(composite, SWT.MouseDown); + hookWidget(imageLabel, SWT.MouseDown); + hookWidget(textLabel, SWT.MouseDown); + + return composite; + } + + private void hookWidget(Widget widget, int eventType) { + widget.addListener(eventType, eventHandler); + } + + private void handleWidgetEvent(Event event) { + String id = (String) event.widget.getData(ID_KEY); + if (id == null) + return; + + selectedOption = optionRegistry.getOptionById(id); + if (selectedOption == null) + return; + + okPressed(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/TopicHyperlinkPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/TopicHyperlinkPage.java index e7152c9fe..36dd95942 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/TopicHyperlinkPage.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/TopicHyperlinkPage.java @@ -1,241 +1,241 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dialogs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.dialogs.FilteredTree; -import org.eclipse.ui.dialogs.PatternFilter; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.ui.dialogs.HyperlinkPage; - -/** - * @author Frank Shaka - */ -public class TopicHyperlinkPage extends HyperlinkPage { - - private class TopicPageContentProvider implements ITreeContentProvider { - public Object[] getElements(Object inputElement) { - if (inputElement instanceof IWorkbook) { - List sheets = ((IWorkbook) inputElement).getSheets(); - List rootTopics = new ArrayList(sheets.size()); - for (ISheet sheet : sheets) { - rootTopics.add(sheet.getRootTopic()); - } - return rootTopics.toArray(); - } - return new Object[0]; - } - - public boolean hasChildren(Object element) { - if (element instanceof ITopic) { - return !((ITopic) element).getAllChildren().isEmpty(); - } - return false; - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof ITopic) { - return ((ITopic) parentElement).getAllChildren().toArray(); - } - return new Object[0]; - } - - public Object getParent(Object element) { - if (element instanceof ITopic) { - ITopic topic = (ITopic) element; - if (topic.isRoot()) - return topic.getOwnedWorkbook(); - return topic.getParent(); - } - return null; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - } - - private class TopicPageLabelProvider extends LabelProvider { - - public String getText(Object element) { - if (element instanceof ITopic) { - ITopic topic = (ITopic) element; - if (topic.isRoot()) { - return topic.getTitleText() + " (" //$NON-NLS-1$ - + topic.getOwnedSheet().getTitleText() + ")"; //$NON-NLS-1$ - } - String titleText = topic.getTitleText(); - return titleText.replaceAll("\\r\\n|\\n|\\r", " "); //$NON-NLS-1$ //$NON-NLS-2$ - } - return super.getText(element); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.viewers.ImageCachedLabelProvider#createImage(java.lang - * .Object) - */ -// protected Image createImage(Object element) { -// ImageDescriptor icon = MindMapUI.getImages().getElementIcon(element, -// true); -// if (icon == null) -// return null; -// return icon.createImage(false); -// } - - } - - private class TopicSelectionListener implements ISelectionChangedListener { - - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - Object element = ss.getFirstElement(); - if (element instanceof ITopic) { - isModifyValue = true; - setValue(HyperlinkUtils.toInternalURL((ITopic) element)); - isModifyValue = false; - setCanFinish(true); - } - } - - } - } - - public Composite composite; - - public IWorkbook workbook; - - public boolean isModifyValue = false; - - public String str; - - private TreeViewer topicViewer; - - public TopicHyperlinkPage() { - } - - public void init(IEditorPart editor, IStructuredSelection selection) { - this.workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); - } - - public void createControl(Composite parent) { - composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(1, false)); - - createLabel(composite); - createTopicViewer(composite); - } - - /** - * @param parent - */ - private void createLabel(Composite parent) { - Label label = new Label(parent, SWT.WRAP); - label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - label.setText(DialogMessages.TopicHyperlinkPage_label); - } - - /** - * @param parent - */ - private void createTopicViewer(Composite parent) { -// topicViewer = new TreeViewer(parent, SWT.SINGLE | SWT.BORDER); - PatternFilter filter = new PatternFilter(); - FilteredTree tree = new FilteredTree(parent, - SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, filter, - true); - topicViewer = tree.getViewer(); - topicViewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - topicViewer.setAutoExpandLevel(2); - - topicViewer.setContentProvider(new TopicPageContentProvider()); - topicViewer.setLabelProvider(new TopicPageLabelProvider()); - if (workbook != null) - topicViewer.setInput(workbook); - - topicViewer.addSelectionChangedListener(new TopicSelectionListener()); - } - - public void setValue(String value) { - super.setValue(value); - if (!isModifyValue) { - if (topicViewer != null && topicViewer.getControl() != null - && !topicViewer.getControl().isDisposed()) { - Object element = getElement(value); - if (element != null) { - topicViewer.setSelection(new StructuredSelection(element), - true); - } else { - topicViewer.setSelection(StructuredSelection.EMPTY); - } - } - } - } - - /** - * @param value - */ - private Object getElement(String value) { - if (value == null) - return null; - if (workbook == null) - return null; - return HyperlinkUtils.findElement(value, workbook); - } - - public void dispose() { - } - - public Control getControl() { - return composite; - } - - public void setFocus() { - if (topicViewer != null) { - Control control = topicViewer.getControl(); - if (control != null && !control.isDisposed()) { - control.setFocus(); - } - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dialogs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.ui.dialogs.HyperlinkPage; + +/** + * @author Frank Shaka + */ +public class TopicHyperlinkPage extends HyperlinkPage { + + private class TopicPageContentProvider implements ITreeContentProvider { + public Object[] getElements(Object inputElement) { + if (inputElement instanceof IWorkbook) { + List sheets = ((IWorkbook) inputElement).getSheets(); + List rootTopics = new ArrayList(sheets.size()); + for (ISheet sheet : sheets) { + rootTopics.add(sheet.getRootTopic()); + } + return rootTopics.toArray(); + } + return new Object[0]; + } + + public boolean hasChildren(Object element) { + if (element instanceof ITopic) { + return !((ITopic) element).getAllChildren().isEmpty(); + } + return false; + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof ITopic) { + return ((ITopic) parentElement).getAllChildren().toArray(); + } + return new Object[0]; + } + + public Object getParent(Object element) { + if (element instanceof ITopic) { + ITopic topic = (ITopic) element; + if (topic.isRoot()) + return topic.getOwnedWorkbook(); + return topic.getParent(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + } + + private class TopicPageLabelProvider extends LabelProvider { + + public String getText(Object element) { + if (element instanceof ITopic) { + ITopic topic = (ITopic) element; + if (topic.isRoot()) { + return topic.getTitleText() + " (" //$NON-NLS-1$ + + topic.getOwnedSheet().getTitleText() + ")"; //$NON-NLS-1$ + } + String titleText = topic.getTitleText(); + return titleText.replaceAll("\\r\\n|\\n|\\r", " "); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.getText(element); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.viewers.ImageCachedLabelProvider#createImage(java.lang + * .Object) + */ +// protected Image createImage(Object element) { +// ImageDescriptor icon = MindMapUI.getImages().getElementIcon(element, +// true); +// if (icon == null) +// return null; +// return icon.createImage(false); +// } + + } + + private class TopicSelectionListener implements ISelectionChangedListener { + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object element = ss.getFirstElement(); + if (element instanceof ITopic) { + isModifyValue = true; + setValue(HyperlinkUtils.toInternalURL((ITopic) element)); + isModifyValue = false; + setCanFinish(true); + } + } + + } + } + + public Composite composite; + + public IWorkbook workbook; + + public boolean isModifyValue = false; + + public String str; + + private TreeViewer topicViewer; + + public TopicHyperlinkPage() { + } + + public void init(IEditorPart editor, IStructuredSelection selection) { + this.workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); + } + + public void createControl(Composite parent) { + composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1, false)); + + createLabel(composite); + createTopicViewer(composite); + } + + /** + * @param parent + */ + private void createLabel(Composite parent) { + Label label = new Label(parent, SWT.WRAP); + label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + label.setText(DialogMessages.TopicHyperlinkPage_label); + } + + /** + * @param parent + */ + private void createTopicViewer(Composite parent) { +// topicViewer = new TreeViewer(parent, SWT.SINGLE | SWT.BORDER); + PatternFilter filter = new PatternFilter(); + FilteredTree tree = new FilteredTree(parent, + SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, filter, + true); + topicViewer = tree.getViewer(); + topicViewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + topicViewer.setAutoExpandLevel(2); + + topicViewer.setContentProvider(new TopicPageContentProvider()); + topicViewer.setLabelProvider(new TopicPageLabelProvider()); + if (workbook != null) + topicViewer.setInput(workbook); + + topicViewer.addSelectionChangedListener(new TopicSelectionListener()); + } + + public void setValue(String value) { + super.setValue(value); + if (!isModifyValue) { + if (topicViewer != null && topicViewer.getControl() != null + && !topicViewer.getControl().isDisposed()) { + Object element = getElement(value); + if (element != null) { + topicViewer.setSelection(new StructuredSelection(element), + true); + } else { + topicViewer.setSelection(StructuredSelection.EMPTY); + } + } + } + } + + /** + * @param value + */ + private Object getElement(String value) { + if (value == null) + return null; + if (workbook == null) + return null; + return HyperlinkUtils.findElement(value, workbook); + } + + public void dispose() { + } + + public Control getControl() { + return composite; + } + + public void setFocus() { + if (topicViewer != null) { + Control control = topicViewer.getControl(); + if (control != null && !control.isDisposed()) { + control.setFocus(); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WallpaperDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WallpaperDialog.java index 90ddef322..a8b3cf0db 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WallpaperDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WallpaperDialog.java @@ -1,932 +1,933 @@ -package org.xmind.ui.internal.dialogs; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.codec.binary.Hex; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.PopupDialog; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTError; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.xmind.core.IFileEntry; -import org.xmind.core.ISheet; -import org.xmind.core.style.IStyle; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.util.Properties; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.gallery.FrameDecorator; -import org.xmind.ui.gallery.FrameFigure; -import org.xmind.ui.gallery.FramePart; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GalleryPartFactory; -import org.xmind.ui.gallery.GallerySelectTool; -import org.xmind.ui.gallery.GalleryViewer; -import org.xmind.ui.gallery.ShadowedLayer; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.properties.PropertyMessages; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.ImageFormat; - -public class WallpaperDialog extends PopupDialog implements IOpenListener { - - private static final String LOCAL_WALLPAPER_DIALOG_PATH = "org.xmind.ui.localWallpaperDialogPath"; //$NON-NLS-1$ - private static final Dimension FRAME_IMAGE_SIZE = new Dimension(64, 64); - - private class WallpaperLabelProvider extends LabelProvider { - - public Image getImage(Object element) { - return getWallpaperPreviewImage(element); - } - } - - private static class WallpaperFrameDecorator extends FrameDecorator { - public static final WallpaperFrameDecorator DEFAULT = new WallpaperFrameDecorator(); - - @Override - public void decorate(IGraphicalPart part, IFigure figure) { - FrameFigure frame = (FrameFigure) part.getFigure(); - ShadowedLayer layer = frame.getContentPane(); - - if (checkWallpaper(part)) { - layer.setBorderWidth(2); - layer.setBorderAlpha(0xFF); - layer.setBorderColor(ColorUtils.getColor("#e05236")); //$NON-NLS-1$ - } else { - layer.setBorderWidth(1); - layer.setBorderAlpha(0x20); - layer.setBorderColor(ColorUtils.getColor("#cccccc")); //$NON-NLS-1$ - } - - super.decorate(part, figure); - } - - private boolean checkWallpaper(IGraphicalPart part) { - String modeMD5 = getModelMD5(part); - String currentMD5 = getCurrentWallpaperMD5(); - return currentMD5 != null && !"".equals(currentMD5) //$NON-NLS-1$ - && currentMD5.equals(modeMD5); - } - - private String getModelMD5(IGraphicalPart part) { - Object model = part.getModel(); - if (model != null && model instanceof String) { - try { - FileInputStream fis = new FileInputStream((String) model); - return getFileMD5(fis); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - } - return ""; //$NON-NLS-1$ - } - - private String getCurrentWallpaperMD5() { - if (mindMapViewer == null) - return ""; //$NON-NLS-1$ - ISheet sheet = (ISheet) mindMapViewer.getAdapter(ISheet.class); - if (sheet != null) { - IStyle style = getStyle(sheet); - if (style != null) { - String url = style.getProperty(Styles.Background); - if (url == null) - return ""; //$NON-NLS-1$ - String path = HyperlinkUtils.toAttachmentPath(url); - IFileEntry fe = sheet.getOwnedWorkbook().getManifest() - .getFileEntry(path); - if (fe != null) { - InputStream is = fe.getInputStream(); - return getFileMD5(is); - } - } - } - - return ""; //$NON-NLS-1$ - } - - private IStyle getStyle(ISheet sheet) { - if (sheet != null) { - String styleId = sheet.getStyleId(); - if (styleId == null) - return null; - return sheet.getOwnedWorkbook().getStyleSheet() - .findStyle(styleId); - } - return null; - } - - private String getFileMD5(InputStream input) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$ - md.reset(); - byte[] bytes = new byte[2048]; - int numBytes; - try { - while ((numBytes = input.read(bytes)) != -1) - md.update(bytes, 0, numBytes); - } catch (IOException e) { - e.printStackTrace(); - } - byte[] digest = md.digest(); - return new String(Hex.encodeHex(digest)); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return ""; //$NON-NLS-1$ - } - } - - private static class WallpaperItemPart extends FramePart { - public WallpaperItemPart(Object model) { - super(model); - setDecorator(WallpaperFrameDecorator.DEFAULT); - } - } - - private static class WallpaperPartFactory extends GalleryPartFactory { - @Override - protected IPart createFramePart(IPart parent, Object model) { - return new WallpaperItemPart(model); - } - } - - private static String WallpapersPath = null; - - private static String PatternPath = null; - - private Control initLocationControl; - - private static IGraphicalViewer mindMapViewer; - - private GalleryViewer patternViewer; - - private GalleryViewer paperViewer; - - private Map wallpaperPreviewImages; - - private Job patternLoader; - - private Job imageLoader; - - private List allPatternImageFiles; - - private List loadedPatternImageFiles; - - private List allImageFiles; - - private List loadedImageFiles; - - private String selectedWallpaperPath; - - public WallpaperDialog(Shell parent, Control initLocationControl) { - super(parent, SWT.RESIZE, true, true, true, false, false, null, null); - this.initLocationControl = initLocationControl; - initLocationControl.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - releaseWallpaperPreviewImages(); - } - }); - } - - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - - createPatternArea(composite); - - createWallpaperArea(composite); - - return composite; - } - - private void createPatternArea(Composite parent) { - Composite top = new Composite(parent, SWT.NONE); - GridLayout topLayout = new GridLayout(); - topLayout.marginLeft = 5; - topLayout.marginRight = 0; - topLayout.marginTop = 0; - topLayout.marginBottom = 1; - top.setLayout(topLayout); - top.setLayoutData( - new GridData(GridData.FILL, GridData.FILL, true, false)); - Label label = new Label(top, SWT.NONE); - label.setText(PropertyMessages.PatternCategory_title); - - patternViewer = new GalleryViewer(); - Properties properties = patternViewer.getProperties(); - properties.set(GalleryViewer.Horizontal, Boolean.TRUE); - properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); - properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_FILL, 1, 1, new Insets(5))); - properties.set(GalleryViewer.FrameContentSize, new Dimension(48, 48)); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); - properties.set(GalleryViewer.HideTitle, Boolean.TRUE); - properties.set(GalleryViewer.SolidFrames, Boolean.FALSE); - - patternViewer.setPartFactory(new WallpaperPartFactory()); - patternViewer.setLabelProvider(new WallpaperLabelProvider()); - patternViewer.addOpenListener(this); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); - patternViewer.setEditDomain(editDomain); - - patternViewer.createControl(parent); - GridData galleryData = new GridData(GridData.FILL, GridData.FILL, true, - true); - galleryData.widthHint = 360; - galleryData.heightHint = 300; - patternViewer.getControl().setLayoutData(galleryData); - - final Display display = parent.getDisplay(); - patternViewer.getControl().setBackground( - display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - if (allPatternImageFiles != null && loadedPatternImageFiles != null - && loadedPatternImageFiles.containsAll(allPatternImageFiles)) { - patternViewer.setInput(loadedPatternImageFiles.toArray()); - } else { - patternViewer.setInput(new Object[0]); - display.asyncExec(new Runnable() { - public void run() { - if (patternViewer.getControl() != null - && !patternViewer.getControl().isDisposed()) { - startLoadingPatternImages(display); - } - } - }); - } - - Composite bottom = new Composite(parent, SWT.NONE); - GridLayout bottomLayout = new GridLayout(); - bottomLayout.marginWidth = 0; - bottomLayout.marginHeight = 0; - bottomLayout.marginBottom = 10; - bottom.setLayout(bottomLayout); - bottom.setLayoutData( - new GridData(GridData.FILL, GridData.FILL, true, false)); - } - - private void createWallpaperArea(Composite parent) { - Composite top = new Composite(parent, SWT.NONE); - GridLayout topLayout = new GridLayout(); - topLayout.marginLeft = 5; - topLayout.marginRight = 0; - topLayout.marginTop = 0; - topLayout.marginBottom = 1; - top.setLayout(topLayout); - top.setLayoutData( - new GridData(GridData.FILL, GridData.FILL, true, false)); - Label label = new Label(top, SWT.NONE); - label.setText(PropertyMessages.WallpaperCategory_title); - - paperViewer = new GalleryViewer(); - Properties properties = paperViewer.getProperties(); - properties.set(GalleryViewer.Horizontal, Boolean.TRUE); - properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); - properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_FILL, 1, 1, new Insets(5))); - properties.set(GalleryViewer.FrameContentSize, new Dimension(48, 48)); - properties.set(GalleryViewer.TitlePlacement, - GalleryViewer.TITLE_BOTTOM); - properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); - properties.set(GalleryViewer.HideTitle, Boolean.TRUE); - properties.set(GalleryViewer.SolidFrames, Boolean.FALSE); - - paperViewer.setPartFactory(new WallpaperPartFactory()); - paperViewer.setLabelProvider(new WallpaperLabelProvider()); - paperViewer.addOpenListener(this); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); - paperViewer.setEditDomain(editDomain); - - paperViewer.createControl(parent); - GridData galleryData = new GridData(GridData.FILL, GridData.FILL, true, - true); - galleryData.widthHint = 360; - galleryData.heightHint = 300; - paperViewer.getControl().setLayoutData(galleryData); - - final Display display = parent.getDisplay(); - paperViewer.getControl().setBackground( - display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - if (allImageFiles != null && loadedImageFiles != null - && loadedImageFiles.containsAll(allImageFiles)) { - paperViewer.setInput(loadedImageFiles.toArray()); - } else { - paperViewer.setInput(new Object[0]); - display.asyncExec(new Runnable() { - public void run() { - if (paperViewer.getControl() != null - && !paperViewer.getControl().isDisposed()) { - startLoadingImages(display); - } - } - }); - } - - Composite bottom = new Composite(parent, SWT.NONE); - GridLayout bottomLayout = new GridLayout(); - bottomLayout.marginWidth = 0; - bottomLayout.marginHeight = 0; - bottom.setLayout(bottomLayout); - bottom.setLayoutData( - new GridData(GridData.FILL, GridData.FILL, true, false)); - - Button chooseFromLocalButton = new Button(bottom, SWT.PUSH); - chooseFromLocalButton.setText(PropertyMessages.LocalImage_text); - chooseFromLocalButton.setLayoutData( - new GridData(GridData.CENTER, GridData.CENTER, true, false)); - chooseFromLocalButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - openLocalImageFileDialog(); - Shell shell = getShell(); - if (shell != null && !shell.isDisposed()) - shell.close(); - close(); - } - }); - - } - - private void startLoadingImages(final Display display) { - if (imageLoader != null) { - imageLoader.cancel(); - imageLoader = null; - } - - imageLoader = new Job(PropertyMessages.LoadWallpapers_jobName) { - - private Runnable refreshJob = null; - - protected IStatus run(IProgressMonitor monitor) { - if (allImageFiles == null) { - collectImageFiles(getWallpapersPath()); - if (allImageFiles == null) { - allImageFiles = Collections.emptyList(); - } - } - - if (allImageFiles.isEmpty()) { - if (loadedImageFiles == null || !loadedImageFiles.isEmpty()) - loadedImageFiles = Collections.emptyList(); - refreshViewer(display); - } else if (loadedImageFiles != null - && loadedImageFiles.containsAll(allImageFiles)) { - refreshViewer(display); - } else { - monitor.beginTask(null, allImageFiles.size()); - if (loadedImageFiles == null) - loadedImageFiles = new ArrayList( - allImageFiles.size()); - long lastRefresh = System.currentTimeMillis(); - for (Object o : allImageFiles.toArray()) { - if (monitor.isCanceled()) { - break; - } - - if (!loadedImageFiles.contains(o)) { - final String path = (String) o; - monitor.subTask(new File(path).getName()); - - Image image = getWallpaperPreviewImage(display, - path); - if (image != null) { - loadedImageFiles.add(path); - } else { - allImageFiles.remove(path); - } - } - - monitor.worked(1); - - if ((System.currentTimeMillis() - lastRefresh) > 50) { - refreshViewer(display); - lastRefresh = System.currentTimeMillis(); - } - - try { - Thread.sleep(1); - } catch (InterruptedException e) { - break; - } - } - } - - if (!monitor.isCanceled()) { - monitor.done(); - } - imageLoader = null; - refreshViewer(display); - return new Status(IStatus.OK, MindMapUIPlugin.PLUGIN_ID, - IStatus.OK, "Wallpaper images loaded.", null); //$NON-NLS-1$ - } - - private void refreshViewer(final Display display) { - if (refreshJob != null) - return; - - refreshJob = new Runnable() { - public void run() { - if (paperViewer != null - && paperViewer.getControl() != null - && !paperViewer.getControl().isDisposed() - && loadedImageFiles != null) { - paperViewer.setInput(loadedImageFiles.toArray()); - paperViewer.getControl().getParent().layout(); - } - refreshJob = null; - } - }; - display.asyncExec(refreshJob); - } - - private void collectImageFiles(String path) { - File file = new File(path); - if (file.isDirectory() && path.equals(getWallpapersPath())) { - for (String name : file.list()) { - collectImageFiles( - new File(file, name).getAbsolutePath()); - } - } else if (file.isFile()) { - String ext = FileUtils.getExtension(path); - ImageFormat format = ImageFormat.findByExtension(ext, null); - if (format != null) { - if (allImageFiles == null) - allImageFiles = new ArrayList(); - allImageFiles.add(path); - } - } - } - }; - imageLoader.schedule(); - } - - private void startLoadingPatternImages(final Display display) { - if (patternLoader != null) { - patternLoader.cancel(); - patternLoader = null; - } - - patternLoader = new Job(PropertyMessages.LoadWallpapers_jobName) { - - private Runnable refreshJob = null; - - protected IStatus run(IProgressMonitor monitor) { - if (allPatternImageFiles == null) { - collectImageFiles(getPatternsPath()); - if (allPatternImageFiles == null) { - allPatternImageFiles = Collections.emptyList(); - } - } - if (allPatternImageFiles.isEmpty()) { - if (loadedPatternImageFiles == null - || !loadedPatternImageFiles.isEmpty()) - loadedPatternImageFiles = Collections.emptyList(); - refreshViewer(display); - } else if (loadedPatternImageFiles != null - && loadedPatternImageFiles - .containsAll(allPatternImageFiles)) { - refreshViewer(display); - } else { - monitor.beginTask(null, allPatternImageFiles.size()); - if (loadedPatternImageFiles == null) - loadedPatternImageFiles = new ArrayList( - allPatternImageFiles.size()); - long lastRefresh = System.currentTimeMillis(); - for (Object o : allPatternImageFiles.toArray()) { - if (monitor.isCanceled()) { - break; - } - - if (!loadedPatternImageFiles.contains(o)) { - final String path = (String) o; - monitor.subTask(new File(path).getName()); - - Image image = getWallpaperPreviewImage(display, - path); - if (image != null) { - loadedPatternImageFiles.add(path); - } else { - allPatternImageFiles.remove(path); - } - } - - monitor.worked(1); - - if ((System.currentTimeMillis() - lastRefresh) > 50) { - refreshViewer(display); - lastRefresh = System.currentTimeMillis(); - } - - try { - Thread.sleep(1); - } catch (InterruptedException e) { - break; - } - } - } - - if (!monitor.isCanceled()) { - monitor.done(); - } - patternLoader = null; - refreshViewer(display); - return new Status(IStatus.OK, MindMapUIPlugin.PLUGIN_ID, - IStatus.OK, "Wallpaper images loaded.", null); //$NON-NLS-1$ - } - - private void refreshViewer(final Display display) { - if (refreshJob != null) - return; - - refreshJob = new Runnable() { - public void run() { - if (patternViewer != null - && patternViewer.getControl() != null - && !patternViewer.getControl().isDisposed() - && loadedPatternImageFiles != null) { - patternViewer.setInput( - loadedPatternImageFiles.toArray()); - patternViewer.getControl().getParent().layout(); - } - refreshJob = null; - } - }; - display.asyncExec(refreshJob); - } - - private void collectImageFiles(String path) { - File file = new File(path); - if (file.isDirectory() && path.equals(getPatternsPath())) { - for (String name : file.list()) { - collectImageFiles( - new File(file, name).getAbsolutePath()); - } - } else if (file.isFile()) { - String ext = FileUtils.getExtension(path); - ImageFormat format = ImageFormat.findByExtension(ext, null); - if (format != null) { - if (allPatternImageFiles == null) - allPatternImageFiles = new ArrayList(); - allPatternImageFiles.add(path); - } - } - } - }; - patternLoader.schedule(); - } - - protected void configureShell(Shell shell) { - super.configureShell(shell); - shell.addListener(SWT.Deactivate, new Listener() { - public void handleEvent(Event event) { - event.display.asyncExec(new Runnable() { - public void run() { - close(); - } - }); - } - }); - shell.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (imageLoader != null) { - imageLoader.cancel(); - imageLoader = null; - } - if (patternLoader != null) { - patternLoader.cancel(); - patternLoader = null; - } - } - }); - } - - public void setMindMapViewer(IGraphicalViewer viewer) { - mindMapViewer = viewer; - } - - @SuppressWarnings("unchecked") - protected List getBackgroundColorExclusions() { - List list = super.getBackgroundColorExclusions(); - if (paperViewer != null) { - list.add(paperViewer.getControl()); - } - - if (patternViewer != null) { - list.add(patternViewer.getControl()); - } - return list; - } - - protected Point getInitialLocation(Point initialSize) { - if (initLocationControl != null && !initLocationControl.isDisposed()) { - Point loc = initLocationControl - .toDisplay(initLocationControl.getLocation()); - return new Point(loc.x, - loc.y + initLocationControl.getBounds().height); - } else if (mindMapViewer != null) { - return new Point(50, 50); - } - return super.getInitialLocation(initialSize); - } - - protected IDialogSettings getDialogSettings() { - return MindMapUIPlugin.getDefault() - .getDialogSettings(MindMapUI.POPUP_DIALOG_SETTINGS_ID); - } - - public void open(OpenEvent event) { - Object o = ((IStructuredSelection) event.getSelection()) - .getFirstElement(); - if (o instanceof String) { - String path = (String) o; - selectedWallpaperPath = path; - Shell shell = getShell(); - if (shell != null && !shell.isDisposed()) - shell.close(); - close(); - changeWallpaper(path); - } - } - - public String getSelectedWallpaperPath() { - return selectedWallpaperPath; - } - - private Image getWallpaperPreviewImage(Object element) { - return getWallpaperPreviewImage(Display.getCurrent(), element); - } - - private Image getWallpaperPreviewImage(Display display, Object element) { - Image image = null; - if (wallpaperPreviewImages != null) { - image = wallpaperPreviewImages.get(element); - } - if (image == null) { - if (element instanceof String) { - String path = (String) element; - try { - image = new Image(display, path); - } catch (IllegalArgumentException e) { - } catch (SWTException e) { - } catch (SWTError e) { - } - if (image != null) { - Image filled = createFilledImage(display, image, - FRAME_IMAGE_SIZE); - if (filled != null) { - image.dispose(); - image = filled; - } - } - } - if (image != null) { - cacheWallpaperPreviewImage(element, image); - } - } - return image; - } - - private void cacheWallpaperPreviewImage(Object element, Image image) { - if (wallpaperPreviewImages == null) - wallpaperPreviewImages = new HashMap(); - wallpaperPreviewImages.put(element, image); - } - - private void releaseWallpaperPreviewImages() { - if (wallpaperPreviewImages != null) { - for (Image image : wallpaperPreviewImages.values()) { - image.dispose(); - } - wallpaperPreviewImages = null; - } - } - - private void openLocalImageFileDialog() { - - FileDialog dialog = new FileDialog(getParentShell(), - SWT.OPEN | SWT.SINGLE); - DialogUtils.makeDefaultImageSelectorDialog(dialog, true); - dialog.setText(PropertyMessages.WallpaperDialog_title); - - IDialogSettings settings = MindMapUIPlugin.getDefault() - .getDialogSettings(); - String filterPath = settings.get(LOCAL_WALLPAPER_DIALOG_PATH); - if (filterPath == null || "".equals(filterPath) //$NON-NLS-1$ - || !new File(filterPath).exists()) { - filterPath = getWallpapersPath(); - } - dialog.setFilterPath(filterPath); - String path = dialog.open(); - if (path == null) - return; - - selectedWallpaperPath = path; - - filterPath = new File(path).getParent(); - settings.put(LOCAL_WALLPAPER_DIALOG_PATH, filterPath); - changeWallpaper(path); - } - - private void changeWallpaper(String path) { - if (mindMapViewer == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ChangeWallpaperCount"); //$NON-NLS-1$ - Request request = new Request(MindMapUI.REQ_MODIFY_STYLE) - .setViewer(mindMapViewer); - request.setParameter(MindMapUI.PARAM_COMMAND_LABEL, - CommandMessages.Command_ModifySheetBackgroundColor); - request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.Background, - path); - int value; - if (isPattern(path)) - value = 10; - else - value = 100; - request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.Opacity, - String.valueOf((double) value * 1.0 / 100)); - request.setTargets(fillParts()); - mindMapViewer.getEditDomain().handleRequest(request); - } - - private boolean isPattern(String path) { - int index; - if (Util.isWin32()) - index = path.lastIndexOf('\\'); - else - index = path.lastIndexOf('/'); - if (index < 7) - return false; - String category = path.substring(index - 7, index); - - if ("pattern".equals(category)) //$NON-NLS-1$ - return true; - - return false; - } - - private List fillParts() { - List parts = new ArrayList(); - Object input = mindMapViewer.getInput(); - if (input instanceof IMindMap) { - ISheet sheet = ((IMindMap) input).getSheet(); - IPart part = mindMapViewer.findPart(sheet); - parts.add(part); - } - return parts; - } - - private static String getWallpapersPath() { - if (WallpapersPath == null) { - WallpapersPath = createWallpapersPath("wallpaper"); //$NON-NLS-1$ - } - return WallpapersPath; - } - - private static String getPatternsPath() { - if (PatternPath == null) - PatternPath = createWallpapersPath("pattern"); //$NON-NLS-1$ - return PatternPath; - } - - private static String createWallpapersPath(String category) { - URL url = FileLocator.find(Platform.getBundle(MindMapUI.PLUGIN_ID), - new Path("wallpaper/" + category), null); //$NON-NLS-1$ - try { - url = FileLocator.toFileURL(url); - } catch (IOException e) { - } - String path = url.getFile(); - if ("".equals(path)) { //$NON-NLS-1$ - path = new File(System.getProperty("user.home"), "Pictures") //$NON-NLS-1$ //$NON-NLS-2$ - .getAbsolutePath(); - } - return path; - } - - private static Image createFilledImage(Display display, Image src, - Dimension size) { - int height = size.height; - int width = size.width; - - ImageData srcData = src.getImageData(); - int srcWidth = srcData.width; - int srcHeight = srcData.height; - - if (srcWidth == width && srcHeight == height) - return null; - - ImageData destData = new ImageData(width, height, srcData.depth, - srcData.palette); - destData.type = srcData.type; - destData.transparentPixel = srcData.transparentPixel; - destData.alpha = srcData.alpha; - - if (srcData.transparentPixel != -1) { - for (int x = 0; x < width; x++) - for (int y = 0; y < height; y++) - destData.setPixel(x, y, srcData.transparentPixel); - } else { - for (int x = 0; x < width; x++) - for (int y = 0; y < height; y++) - destData.setAlpha(x, y, 0); - } - - int[] pixels = new int[srcWidth]; - byte[] alphas = null; - for (int startX = 0; startX < width; startX += srcWidth) { - int length = Math.min(srcWidth, width - startX); - if (length > 0) { - for (int startY = 0; startY < height; startY += srcHeight) { - for (int y = 0; y < srcHeight && startY + y < height; y++) { - srcData.getPixels(0, y, srcWidth, pixels, 0); - destData.setPixels(startX, startY + y, length, pixels, - 0); - if (srcData.alpha == -1 && srcData.alphaData != null) { - if (alphas == null) - alphas = new byte[srcWidth]; - srcData.getAlphas(0, y, srcWidth, alphas, 0); - } else if (srcData.alpha != -1 && alphas == null) { - alphas = new byte[srcWidth]; - for (int i = 0; i < alphas.length; i++) - alphas[i] = (byte) srcData.alpha; - } else if (alphas == null) { - alphas = new byte[srcWidth]; - for (int i = 0; i < alphas.length; i++) - alphas[i] = (byte) 0xff; - } - destData.setAlphas(startX, startY + y, length, alphas, - 0); - } - } - } - } - - Image image = new Image(display, destData); - return image; - } - -} +package org.xmind.ui.internal.dialogs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Hex; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.PopupDialog; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.xmind.core.IFileEntry; +import org.xmind.core.ISheet; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.style.IStyle; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.gallery.FrameDecorator; +import org.xmind.ui.gallery.FrameFigure; +import org.xmind.ui.gallery.FramePart; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GalleryPartFactory; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.gallery.ShadowedLayer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.properties.PropertyMessages; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.ImageFormat; + +public class WallpaperDialog extends PopupDialog implements IOpenListener { + + private static final String LOCAL_WALLPAPER_DIALOG_PATH = "org.xmind.ui.localWallpaperDialogPath"; //$NON-NLS-1$ + private static final Dimension FRAME_IMAGE_SIZE = new Dimension(64, 64); + + private class WallpaperLabelProvider extends LabelProvider { + + public Image getImage(Object element) { + return getWallpaperPreviewImage(element); + } + } + + private static class WallpaperFrameDecorator extends FrameDecorator { + public static final WallpaperFrameDecorator DEFAULT = new WallpaperFrameDecorator(); + + @Override + public void decorate(IGraphicalPart part, IFigure figure) { + FrameFigure frame = (FrameFigure) part.getFigure(); + ShadowedLayer layer = frame.getContentPane(); + + if (checkWallpaper(part)) { + layer.setBorderWidth(2); + layer.setBorderAlpha(0xFF); + layer.setBorderColor(ColorUtils.getColor("#e05236")); //$NON-NLS-1$ + } else { + layer.setBorderWidth(1); + layer.setBorderAlpha(0x20); + layer.setBorderColor(ColorUtils.getColor("#cccccc")); //$NON-NLS-1$ + } + + super.decorate(part, figure); + } + + private boolean checkWallpaper(IGraphicalPart part) { + String modeMD5 = getModelMD5(part); + String currentMD5 = getCurrentWallpaperMD5(); + return currentMD5 != null && !"".equals(currentMD5) //$NON-NLS-1$ + && currentMD5.equals(modeMD5); + } + + private String getModelMD5(IGraphicalPart part) { + Object model = part.getModel(); + if (model != null && model instanceof String) { + try { + FileInputStream fis = new FileInputStream((String) model); + return getFileMD5(fis); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + } + return ""; //$NON-NLS-1$ + } + + private String getCurrentWallpaperMD5() { + if (mindMapViewer == null) + return ""; //$NON-NLS-1$ + ISheet sheet = (ISheet) mindMapViewer.getAdapter(ISheet.class); + if (sheet != null) { + IStyle style = getStyle(sheet); + if (style != null) { + String url = style.getProperty(Styles.Background); + if (url == null) + return ""; //$NON-NLS-1$ + String path = HyperlinkUtils.toAttachmentPath(url); + IFileEntry fe = sheet.getOwnedWorkbook().getManifest() + .getFileEntry(path); + if (fe != null) { + InputStream is = fe.getInputStream(); + return getFileMD5(is); + } + } + } + + return ""; //$NON-NLS-1$ + } + + private IStyle getStyle(ISheet sheet) { + if (sheet != null) { + String styleId = sheet.getStyleId(); + if (styleId == null) + return null; + return sheet.getOwnedWorkbook().getStyleSheet() + .findStyle(styleId); + } + return null; + } + + private String getFileMD5(InputStream input) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$ + md.reset(); + byte[] bytes = new byte[2048]; + int numBytes; + try { + while ((numBytes = input.read(bytes)) != -1) + md.update(bytes, 0, numBytes); + } catch (IOException e) { + e.printStackTrace(); + } + byte[] digest = md.digest(); + return new String(Hex.encodeHex(digest)); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; //$NON-NLS-1$ + } + } + + private static class WallpaperItemPart extends FramePart { + public WallpaperItemPart(Object model) { + super(model); + setDecorator(WallpaperFrameDecorator.DEFAULT); + } + } + + private static class WallpaperPartFactory extends GalleryPartFactory { + @Override + protected IPart createFramePart(IPart parent, Object model) { + return new WallpaperItemPart(model); + } + } + + private static String WallpapersPath = null; + + private static String PatternPath = null; + + private Control initLocationControl; + + private static IGraphicalViewer mindMapViewer; + + private GalleryViewer patternViewer; + + private GalleryViewer paperViewer; + + private Map wallpaperPreviewImages; + + private Job patternLoader; + + private Job imageLoader; + + private List allPatternImageFiles; + + private List loadedPatternImageFiles; + + private List allImageFiles; + + private List loadedImageFiles; + + private String selectedWallpaperPath; + + public WallpaperDialog(Shell parent, Control initLocationControl) { + super(parent, SWT.RESIZE, true, true, true, false, false, null, null); + this.initLocationControl = initLocationControl; + initLocationControl.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + releaseWallpaperPreviewImages(); + } + }); + } + + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + createPatternArea(composite); + + createWallpaperArea(composite); + + return composite; + } + + private void createPatternArea(Composite parent) { + Composite top = new Composite(parent, SWT.NONE); + GridLayout topLayout = new GridLayout(); + topLayout.marginLeft = 5; + topLayout.marginRight = 0; + topLayout.marginTop = 0; + topLayout.marginBottom = 1; + top.setLayout(topLayout); + top.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); + Label label = new Label(top, SWT.NONE); + label.setText(PropertyMessages.PatternCategory_title); + + patternViewer = new GalleryViewer(); + Properties properties = patternViewer.getProperties(); + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); + properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_FILL, 1, 1, new Insets(5))); + properties.set(GalleryViewer.FrameContentSize, new Dimension(48, 48)); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); + properties.set(GalleryViewer.HideTitle, Boolean.TRUE); + properties.set(GalleryViewer.SolidFrames, Boolean.FALSE); + + patternViewer.setPartFactory(new WallpaperPartFactory()); + patternViewer.setLabelProvider(new WallpaperLabelProvider()); + patternViewer.addOpenListener(this); + + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + patternViewer.setEditDomain(editDomain); + + patternViewer.createControl(parent); + GridData galleryData = new GridData(GridData.FILL, GridData.FILL, true, + true); + galleryData.widthHint = 360; + galleryData.heightHint = 300; + patternViewer.getControl().setLayoutData(galleryData); + + final Display display = parent.getDisplay(); + patternViewer.getControl().setBackground( + display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + if (allPatternImageFiles != null && loadedPatternImageFiles != null + && loadedPatternImageFiles.containsAll(allPatternImageFiles)) { + patternViewer.setInput(loadedPatternImageFiles.toArray()); + } else { + patternViewer.setInput(new Object[0]); + display.asyncExec(new Runnable() { + public void run() { + if (patternViewer.getControl() != null + && !patternViewer.getControl().isDisposed()) { + startLoadingPatternImages(display); + } + } + }); + } + + Composite bottom = new Composite(parent, SWT.NONE); + GridLayout bottomLayout = new GridLayout(); + bottomLayout.marginWidth = 0; + bottomLayout.marginHeight = 0; + bottomLayout.marginBottom = 10; + bottom.setLayout(bottomLayout); + bottom.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); + } + + private void createWallpaperArea(Composite parent) { + Composite top = new Composite(parent, SWT.NONE); + GridLayout topLayout = new GridLayout(); + topLayout.marginLeft = 5; + topLayout.marginRight = 0; + topLayout.marginTop = 0; + topLayout.marginBottom = 1; + top.setLayout(topLayout); + top.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); + Label label = new Label(top, SWT.NONE); + label.setText(PropertyMessages.WallpaperCategory_title); + + paperViewer = new GalleryViewer(); + Properties properties = paperViewer.getProperties(); + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); + properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_FILL, 1, 1, new Insets(5))); + properties.set(GalleryViewer.FrameContentSize, new Dimension(48, 48)); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE); + properties.set(GalleryViewer.HideTitle, Boolean.TRUE); + properties.set(GalleryViewer.SolidFrames, Boolean.FALSE); + + paperViewer.setPartFactory(new WallpaperPartFactory()); + paperViewer.setLabelProvider(new WallpaperLabelProvider()); + paperViewer.addOpenListener(this); + + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + paperViewer.setEditDomain(editDomain); + + paperViewer.createControl(parent); + GridData galleryData = new GridData(GridData.FILL, GridData.FILL, true, + true); + galleryData.widthHint = 360; + galleryData.heightHint = 300; + paperViewer.getControl().setLayoutData(galleryData); + + final Display display = parent.getDisplay(); + paperViewer.getControl().setBackground( + display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + if (allImageFiles != null && loadedImageFiles != null + && loadedImageFiles.containsAll(allImageFiles)) { + paperViewer.setInput(loadedImageFiles.toArray()); + } else { + paperViewer.setInput(new Object[0]); + display.asyncExec(new Runnable() { + public void run() { + if (paperViewer.getControl() != null + && !paperViewer.getControl().isDisposed()) { + startLoadingImages(display); + } + } + }); + } + + Composite bottom = new Composite(parent, SWT.NONE); + GridLayout bottomLayout = new GridLayout(); + bottomLayout.marginWidth = 0; + bottomLayout.marginHeight = 0; + bottom.setLayout(bottomLayout); + bottom.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); + + Button chooseFromLocalButton = new Button(bottom, SWT.PUSH); + chooseFromLocalButton.setText(PropertyMessages.LocalImage_text); + chooseFromLocalButton.setLayoutData( + new GridData(GridData.CENTER, GridData.CENTER, true, false)); + chooseFromLocalButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + openLocalImageFileDialog(); + Shell shell = getShell(); + if (shell != null && !shell.isDisposed()) + shell.close(); + close(); + } + }); + + } + + private void startLoadingImages(final Display display) { + if (imageLoader != null) { + imageLoader.cancel(); + imageLoader = null; + } + + imageLoader = new Job(PropertyMessages.LoadWallpapers_jobName) { + + private Runnable refreshJob = null; + + protected IStatus run(IProgressMonitor monitor) { + if (allImageFiles == null) { + collectImageFiles(getWallpapersPath()); + if (allImageFiles == null) { + allImageFiles = Collections.emptyList(); + } + } + + if (allImageFiles.isEmpty()) { + if (loadedImageFiles == null || !loadedImageFiles.isEmpty()) + loadedImageFiles = Collections.emptyList(); + refreshViewer(display); + } else if (loadedImageFiles != null + && loadedImageFiles.containsAll(allImageFiles)) { + refreshViewer(display); + } else { + monitor.beginTask(null, allImageFiles.size()); + if (loadedImageFiles == null) + loadedImageFiles = new ArrayList( + allImageFiles.size()); + long lastRefresh = System.currentTimeMillis(); + for (Object o : allImageFiles.toArray()) { + if (monitor.isCanceled()) { + break; + } + + if (!loadedImageFiles.contains(o)) { + final String path = (String) o; + monitor.subTask(new File(path).getName()); + + Image image = getWallpaperPreviewImage(display, + path); + if (image != null) { + loadedImageFiles.add(path); + } else { + allImageFiles.remove(path); + } + } + + monitor.worked(1); + + if ((System.currentTimeMillis() - lastRefresh) > 50) { + refreshViewer(display); + lastRefresh = System.currentTimeMillis(); + } + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + break; + } + } + } + + if (!monitor.isCanceled()) { + monitor.done(); + } + imageLoader = null; + refreshViewer(display); + return new Status(IStatus.OK, MindMapUIPlugin.PLUGIN_ID, + IStatus.OK, "Wallpaper images loaded.", null); //$NON-NLS-1$ + } + + private void refreshViewer(final Display display) { + if (refreshJob != null) + return; + + refreshJob = new Runnable() { + public void run() { + if (paperViewer != null + && paperViewer.getControl() != null + && !paperViewer.getControl().isDisposed() + && loadedImageFiles != null) { + paperViewer.setInput(loadedImageFiles.toArray()); + paperViewer.getControl().getParent().layout(); + } + refreshJob = null; + } + }; + display.asyncExec(refreshJob); + } + + private void collectImageFiles(String path) { + File file = new File(path); + if (file.isDirectory() && path.equals(getWallpapersPath())) { + for (String name : file.list()) { + collectImageFiles( + new File(file, name).getAbsolutePath()); + } + } else if (file.isFile()) { + String ext = FileUtils.getExtension(path); + ImageFormat format = ImageFormat.findByExtension(ext, null); + if (format != null) { + if (allImageFiles == null) + allImageFiles = new ArrayList(); + allImageFiles.add(path); + } + } + } + }; + imageLoader.schedule(); + } + + private void startLoadingPatternImages(final Display display) { + if (patternLoader != null) { + patternLoader.cancel(); + patternLoader = null; + } + + patternLoader = new Job(PropertyMessages.LoadWallpapers_jobName) { + + private Runnable refreshJob = null; + + protected IStatus run(IProgressMonitor monitor) { + if (allPatternImageFiles == null) { + collectImageFiles(getPatternsPath()); + if (allPatternImageFiles == null) { + allPatternImageFiles = Collections.emptyList(); + } + } + if (allPatternImageFiles.isEmpty()) { + if (loadedPatternImageFiles == null + || !loadedPatternImageFiles.isEmpty()) + loadedPatternImageFiles = Collections.emptyList(); + refreshViewer(display); + } else if (loadedPatternImageFiles != null + && loadedPatternImageFiles + .containsAll(allPatternImageFiles)) { + refreshViewer(display); + } else { + monitor.beginTask(null, allPatternImageFiles.size()); + if (loadedPatternImageFiles == null) + loadedPatternImageFiles = new ArrayList( + allPatternImageFiles.size()); + long lastRefresh = System.currentTimeMillis(); + for (Object o : allPatternImageFiles.toArray()) { + if (monitor.isCanceled()) { + break; + } + + if (!loadedPatternImageFiles.contains(o)) { + final String path = (String) o; + monitor.subTask(new File(path).getName()); + + Image image = getWallpaperPreviewImage(display, + path); + if (image != null) { + loadedPatternImageFiles.add(path); + } else { + allPatternImageFiles.remove(path); + } + } + + monitor.worked(1); + + if ((System.currentTimeMillis() - lastRefresh) > 50) { + refreshViewer(display); + lastRefresh = System.currentTimeMillis(); + } + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + break; + } + } + } + + if (!monitor.isCanceled()) { + monitor.done(); + } + patternLoader = null; + refreshViewer(display); + return new Status(IStatus.OK, MindMapUIPlugin.PLUGIN_ID, + IStatus.OK, "Wallpaper images loaded.", null); //$NON-NLS-1$ + } + + private void refreshViewer(final Display display) { + if (refreshJob != null) + return; + + refreshJob = new Runnable() { + public void run() { + if (patternViewer != null + && patternViewer.getControl() != null + && !patternViewer.getControl().isDisposed() + && loadedPatternImageFiles != null) { + patternViewer.setInput( + loadedPatternImageFiles.toArray()); + patternViewer.getControl().getParent().layout(); + } + refreshJob = null; + } + }; + display.asyncExec(refreshJob); + } + + private void collectImageFiles(String path) { + File file = new File(path); + if (file.isDirectory() && path.equals(getPatternsPath())) { + for (String name : file.list()) { + collectImageFiles( + new File(file, name).getAbsolutePath()); + } + } else if (file.isFile()) { + String ext = FileUtils.getExtension(path); + ImageFormat format = ImageFormat.findByExtension(ext, null); + if (format != null) { + if (allPatternImageFiles == null) + allPatternImageFiles = new ArrayList(); + allPatternImageFiles.add(path); + } + } + } + }; + patternLoader.schedule(); + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.addListener(SWT.Deactivate, new Listener() { + public void handleEvent(Event event) { + event.display.asyncExec(new Runnable() { + public void run() { + close(); + } + }); + } + }); + shell.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (imageLoader != null) { + imageLoader.cancel(); + imageLoader = null; + } + if (patternLoader != null) { + patternLoader.cancel(); + patternLoader = null; + } + } + }); + } + + public void setMindMapViewer(IGraphicalViewer viewer) { + mindMapViewer = viewer; + } + + @SuppressWarnings("unchecked") + protected List getBackgroundColorExclusions() { + List list = super.getBackgroundColorExclusions(); + if (paperViewer != null) { + list.add(paperViewer.getControl()); + } + + if (patternViewer != null) { + list.add(patternViewer.getControl()); + } + return list; + } + + protected Point getInitialLocation(Point initialSize) { + if (initLocationControl != null && !initLocationControl.isDisposed()) { + Point loc = initLocationControl + .toDisplay(initLocationControl.getLocation()); + return new Point(loc.x, + loc.y + initLocationControl.getBounds().height); + } else if (mindMapViewer != null) { + return new Point(50, 50); + } + return super.getInitialLocation(initialSize); + } + + protected IDialogSettings getDialogSettings() { + return MindMapUIPlugin.getDefault() + .getDialogSettings(MindMapUI.POPUP_DIALOG_SETTINGS_ID); + } + + public void open(OpenEvent event) { + Object o = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (o instanceof String) { + String path = (String) o; + selectedWallpaperPath = path; + Shell shell = getShell(); + if (shell != null && !shell.isDisposed()) + shell.close(); + close(); + changeWallpaper(path); + } + } + + public String getSelectedWallpaperPath() { + return selectedWallpaperPath; + } + + private Image getWallpaperPreviewImage(Object element) { + return getWallpaperPreviewImage(Display.getCurrent(), element); + } + + private Image getWallpaperPreviewImage(Display display, Object element) { + Image image = null; + if (wallpaperPreviewImages != null) { + image = wallpaperPreviewImages.get(element); + } + if (image == null) { + if (element instanceof String) { + String path = (String) element; + try { + image = new Image(display, path); + } catch (IllegalArgumentException e) { + } catch (SWTException e) { + } catch (SWTError e) { + } + if (image != null) { + Image filled = createFilledImage(display, image, + FRAME_IMAGE_SIZE); + if (filled != null) { + image.dispose(); + image = filled; + } + } + } + if (image != null) { + cacheWallpaperPreviewImage(element, image); + } + } + return image; + } + + private void cacheWallpaperPreviewImage(Object element, Image image) { + if (wallpaperPreviewImages == null) + wallpaperPreviewImages = new HashMap(); + wallpaperPreviewImages.put(element, image); + } + + private void releaseWallpaperPreviewImages() { + if (wallpaperPreviewImages != null) { + for (Image image : wallpaperPreviewImages.values()) { + image.dispose(); + } + wallpaperPreviewImages = null; + } + } + + private void openLocalImageFileDialog() { + + FileDialog dialog = new FileDialog(getParentShell(), + SWT.OPEN | SWT.SINGLE); + DialogUtils.makeDefaultImageSelectorDialog(dialog, true); + dialog.setText(PropertyMessages.WallpaperDialog_title); + + IDialogSettings settings = MindMapUIPlugin.getDefault() + .getDialogSettings(); + String filterPath = settings.get(LOCAL_WALLPAPER_DIALOG_PATH); + if (filterPath == null || "".equals(filterPath) //$NON-NLS-1$ + || !new File(filterPath).exists()) { + filterPath = getWallpapersPath(); + } + dialog.setFilterPath(filterPath); + String path = dialog.open(); + if (path == null) + return; + + selectedWallpaperPath = path; + + filterPath = new File(path).getParent(); + settings.put(LOCAL_WALLPAPER_DIALOG_PATH, filterPath); + changeWallpaper(path); + } + + private void changeWallpaper(String path) { + if (mindMapViewer == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CHANGE_WALLPAPER_COUNT); + Request request = new Request(MindMapUI.REQ_MODIFY_STYLE) + .setViewer(mindMapViewer); + request.setParameter(MindMapUI.PARAM_COMMAND_LABEL, + CommandMessages.Command_ModifySheetBackgroundColor); + request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.Background, + path); + int value; + if (isPattern(path)) + value = 10; + else + value = 100; + request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.Opacity, + String.valueOf((double) value * 1.0 / 100)); + request.setTargets(fillParts()); + mindMapViewer.getEditDomain().handleRequest(request); + } + + private boolean isPattern(String path) { + int index; + if (Util.isWin32()) + index = path.lastIndexOf('\\'); + else + index = path.lastIndexOf('/'); + if (index < 7) + return false; + String category = path.substring(index - 7, index); + + if ("pattern".equals(category)) //$NON-NLS-1$ + return true; + + return false; + } + + private List fillParts() { + List parts = new ArrayList(); + Object input = mindMapViewer.getInput(); + if (input instanceof IMindMap) { + ISheet sheet = ((IMindMap) input).getSheet(); + IPart part = mindMapViewer.findPart(sheet); + parts.add(part); + } + return parts; + } + + private static String getWallpapersPath() { + if (WallpapersPath == null) { + WallpapersPath = createWallpapersPath("wallpaper"); //$NON-NLS-1$ + } + return WallpapersPath; + } + + private static String getPatternsPath() { + if (PatternPath == null) + PatternPath = createWallpapersPath("pattern"); //$NON-NLS-1$ + return PatternPath; + } + + private static String createWallpapersPath(String category) { + URL url = FileLocator.find(Platform.getBundle(MindMapUI.PLUGIN_ID), + new Path("wallpaper/" + category), null); //$NON-NLS-1$ + try { + url = FileLocator.toFileURL(url); + } catch (IOException e) { + } + String path = url.getFile(); + if ("".equals(path)) { //$NON-NLS-1$ + path = new File(System.getProperty("user.home"), "Pictures") //$NON-NLS-1$ //$NON-NLS-2$ + .getAbsolutePath(); + } + return path; + } + + private static Image createFilledImage(Display display, Image src, + Dimension size) { + int height = size.height; + int width = size.width; + + ImageData srcData = src.getImageData(); + int srcWidth = srcData.width; + int srcHeight = srcData.height; + + if (srcWidth == width && srcHeight == height) + return null; + + ImageData destData = new ImageData(width, height, srcData.depth, + srcData.palette); + destData.type = srcData.type; + destData.transparentPixel = srcData.transparentPixel; + destData.alpha = srcData.alpha; + + if (srcData.transparentPixel != -1) { + for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) + destData.setPixel(x, y, srcData.transparentPixel); + } else { + for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) + destData.setAlpha(x, y, 0); + } + + int[] pixels = new int[srcWidth]; + byte[] alphas = null; + for (int startX = 0; startX < width; startX += srcWidth) { + int length = Math.min(srcWidth, width - startX); + if (length > 0) { + for (int startY = 0; startY < height; startY += srcHeight) { + for (int y = 0; y < srcHeight && startY + y < height; y++) { + srcData.getPixels(0, y, srcWidth, pixels, 0); + destData.setPixels(startX, startY + y, length, pixels, + 0); + if (srcData.alpha == -1 && srcData.alphaData != null) { + if (alphas == null) + alphas = new byte[srcWidth]; + srcData.getAlphas(0, y, srcWidth, alphas, 0); + } else if (srcData.alpha != -1 && alphas == null) { + alphas = new byte[srcWidth]; + for (int i = 0; i < alphas.length; i++) + alphas[i] = (byte) srcData.alpha; + } else if (alphas == null) { + alphas = new byte[srcWidth]; + for (int i = 0; i < alphas.length; i++) + alphas[i] = (byte) 0xff; + } + destData.setAlphas(startX, startY + y, length, alphas, + 0); + } + } + } + } + + Image image = new Image(display, destData); + return image; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookMetaInspectorDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookMetaInspectorDialog.java index b4d1f9040..c4d867087 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookMetaInspectorDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookMetaInspectorDialog.java @@ -1,2273 +1,2273 @@ -package org.xmind.ui.internal.dialogs; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.HyperlinkGroup; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.eclipse.ui.forms.widgets.TableWrapLayout; -import org.eclipse.ui.internal.forms.widgets.FormUtil; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.IFileEntry; -import org.xmind.core.IImage; -import org.xmind.core.IManifest; -import org.xmind.core.IMeta; -import org.xmind.core.IModifiable; -import org.xmind.core.INotes; -import org.xmind.core.INotesContent; -import org.xmind.core.IPlainNotesContent; -import org.xmind.core.IRelationship; -import org.xmind.core.IRevision; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.dom.NumberUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.ModifyMetadataCommand; -import org.xmind.ui.forms.WidgetFactory; -import org.xmind.ui.internal.AttachmentImageDescriptor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.mindmap.ImageDownloader; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.internal.views.Messages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.viewers.FileUtils; -import org.xmind.ui.viewers.IListLayout; -import org.xmind.ui.viewers.IListRenderer; -import org.xmind.ui.viewers.ImageLabel; -import org.xmind.ui.viewers.MListViewer; -import org.xmind.ui.viewers.StraightListLayout; - -public class WorkbookMetaInspectorDialog extends Dialog { - - private static WorkbookMetaInspectorDialog instance; - - private static final int PROP_CONTROL = 1; - - private static final int PROP_CONTENT = 3; - - private static final int PROP_OUTGOING_SELECTION = 4; - - private static final String KEY_WIDGET_FACTORY = WorkbookMetaInspectorDialog.class - .getName() + ".widgetFactory"; //$NON-NLS-1$ - - private WidgetFactory factory; - - private Composite composite; - - private ScrolledForm form; - - private IEditorPart sourceEditor; - - private IWorkbook workbook; - - private CoreEventRegister eventRegister; - - private boolean reflowScheduled = false; - - private List parts = new ArrayList(); - - private Map sections = new HashMap(); - - private WorkbookMetaInspectorDialog(Shell shell) { - super(shell); - setShellStyle( - SWT.RESIZE | SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE); - } - - private static interface IWorkbookMetadataPart { - - // section text - String getTitle(); - - // controls visibility of this part - boolean isVisible(); - - // layout on the parent should be set in this method - void createControl(Composite parent); - - // when triggered upon workbook change, the event is null - // when triggered upon core event, the event is not null - void refresh(IWorkbook workbook, CoreEvent event); - - void addPropertyListener(IPropertyListener listener); - - void removePropertyListener(IPropertyListener listener); - - Control getFocusControl(); - - } - - private static interface IModifiableWorkbookMetadataPart { - Command createModificationCommand(IWorkbook workbook); - } - - protected static class WorkbookMetadata { - - private final Map delegate = new HashMap(); - - public boolean set(String key, Object value) { - Object oldValue = delegate.put(key, value); - return value != oldValue - && (value == null || !value.equals(oldValue)); - } - - public Object get(String key) { - return delegate.get(key); - } - - public boolean delete(String key) { - boolean hadValue = delegate.containsKey(key); - delegate.remove(key); - return hadValue; - } - - public boolean deleteAll() { - boolean hadValues = !delegate.isEmpty(); - delegate.clear(); - return hadValues; - } - - // throws ClassCastException if value is not of Integer - public int getInt(String key) { - Object value = delegate.get(key); - if (value != null) - return ((Integer) value).intValue(); - return 0; - } - - public boolean setInt(String key, int value) { - if (value == 0) - return delete(key); - return set(key, Integer.valueOf(value)); - } - - public boolean increaseInt(String key, int delta) { - int value = getInt(key); - return setInt(key, value + delta); - } - - public boolean decreaseInt(String key, int delta) { - int value = getInt(key); - return setInt(key, value - delta); - } - - public long getLong(String key) { - Object value = delegate.get(key); - if (value != null) - return ((Long) value).longValue(); - return 0; - } - - public boolean setLong(String key, long value) { - if (value == 0) - return delete(key); - return set(key, Long.valueOf(value)); - } - - public boolean increaseLong(String key, long delta) { - long value = getLong(key); - return setLong(key, value + delta); - } - - public boolean decreaseLong(String key, long delta) { - long value = getLong(key); - return setLong(key, value - delta); - } - - // throws ClassCastException if value is not of String - public String getString(String key) { - return (String) delegate.get(key); - } - - public boolean setString(String key, String value) { - if (value == null) - return delete(key); - return set(key, value); - } - - // throws ClassCastException if value is not of Set - @SuppressWarnings("unchecked") - public Set getSet(String key) { - Object value = delegate.get(key); - if (value != null) - return (Set) value; - return Collections.emptySet(); - } - - @SuppressWarnings("unchecked") - public boolean addToSet(String key, Object object) { - boolean changed = false; - @SuppressWarnings("unchecked") - Set set = (Set) delegate.get(key); - if (set == null) { - set = new HashSet(); - delegate.put(key, set); - changed = true; - } - changed |= set.add(object); - return changed; - } - - public boolean removeFromSet(String key, Object object) { - boolean changed = false; - @SuppressWarnings("unchecked") - Set set = (Set) delegate.get(key); - if (set != null) { - changed |= set.remove(object); - if (set.isEmpty()) { - delegate.remove(key); - changed = true; - } - } - return changed; - } - - public int sizeOfSet(String key) { - Set set = (Set) delegate.get(key); - return set == null ? 0 : set.size(); - } - - public boolean containsInSet(String key, Object object) { - Set set = (Set) delegate.get(key); - return set != null && set.contains(object); - } - - public boolean contains(String key) { - return delegate.containsKey(key); - } - - public Collection keys() { - return delegate.keySet(); - } - - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @SuppressWarnings("unchecked") - public WorkbookMetadata copy() { - WorkbookMetadata that = new WorkbookMetadata(); - for (String key : keys()) { - Object value = get(key); - if (value instanceof Set) { - value = new HashSet((Set) value); - } - that.set(key, value); - } - return that; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookMetadata)) - return false; - WorkbookMetadata that = (WorkbookMetadata) obj; - return this.delegate.equals(that.delegate); - } - - @Override - public int hashCode() { - return this.delegate.hashCode(); - } - - @Override - public String toString() { - return this.delegate.toString(); - } - - } - - private static final String METADATA_AUTHOR_EMAIL = "author.email"; //$NON-NLS-1$ - private static final String METADATA_AUTHOR_NAME = "author.name"; //$NON-NLS-1$ - private static final String METADATA_AUTHOR_ORG = "author.org"; //$NON-NLS-1$ - - private static final String METADATA_ESTIMATED_SIZE = "estimatedSize"; //$NON-NLS-1$ - private static final String METADATA_TOPIC_COUNT = "topicCount"; //$NON-NLS-1$ - private static final String METADATA_WORD_COUNT = "wordCount"; //$NON-NLS-1$ - private static final String METADATA_REVISION_COUNT = "revisionCount"; //$NON-NLS-1$ - private static final String METADATA_MODIFICATION_TIME = "modificationTime"; //$NON-NLS-1$ - private static final String METADATA_MODIFIER_NAME = "modifierName"; //$NON-NLS-1$ - private static final String METADATA_CREATION_TIME = "creationTime"; //$NON-NLS-1$ - - private static final String METADATA_ATTACHMENTS = "attachments"; //$NON-NLS-1$ - private static final String METADATA_EXTERNAL_FILES = "externalFiles"; //$NON-NLS-1$ - private static final String METADATA_HYPERLINKS = "hyperlinks"; //$NON-NLS-1$ - private static final String METADATA_IMAGES = "images"; //$NON-NLS-1$ - - private static abstract class AbstractWorkbookMetadataPart - implements IWorkbookMetadataPart { - - private ListenerList listeners = new ListenerList(); - - private Control focusControl = null; - -// private Listener focusControlUpdater = new Listener() { -// public void handleEvent(Event event) { -// focusControl = (Control) event.widget; -// firePropertyChange(PROP_FOCUS_CONTROL); -// } -// }; - - private boolean refreshScheduled = false; - - protected final WorkbookMetadata metadata = new WorkbookMetadata(); - - public boolean isVisible() { - return !metadata.isEmpty(); - } - - public void addPropertyListener(IPropertyListener listener) { - listeners.add(listener); - } - - public void removePropertyListener(IPropertyListener listener) { - listeners.remove(listener); - } - - public Control getFocusControl() { - return focusControl; - } - - protected void firePropertyChange(final int propId) { - final Object source = this; - for (final Object listener : listeners.getListeners()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - ((IPropertyListener) listener).propertyChanged(source, - propId); - } - }); - } - } - - protected void updateText(Text control, String text) { - if (control == null || control.isDisposed()) - return; - - if (text == null) - text = ""; //$NON-NLS-1$ - if (text.equals(control.getText())) - return; - - Point selection = new Point(text.length(), text.length()); - if (control.isFocusControl()) { - selection.x = Math.min(selection.x, control.getSelection().x); - selection.y = Math.min(selection.y, control.getSelection().y); - } - control.setText(text); - if (control.isFocusControl()) { - control.setSelection(selection); - } - firePropertyChange(PROP_CONTROL); - } - - protected abstract void refreshControls(); - - protected void refreshAsynchronously() { - if (refreshScheduled) - return; - - Display display = Display.getCurrent(); - if (display == null) - return; - - display.asyncExec(new Runnable() { - public void run() { - refreshScheduled = false; - refreshControls(); - } - }); - refreshScheduled = true; - } - - } - - private static class WorkbookMetadataListRow extends Composite { - - private ImageLabel imageLabel; - - private Label textLabel; - - private boolean selected; - - private Color background; - - private Listener listener = new Listener() { - public void handleEvent(Event event) { - if (event.type == SWT.MouseDown) { - getParent().setFocus(); - handleMouseDown(event); - } else if (event.type == SWT.MouseDoubleClick) { - handleMouseDoubleClick(event); - } - } - }; - - public WorkbookMetadataListRow(Composite parent, - WidgetFactory factory) { - super(parent, SWT.NO_FOCUS); - selected = false; - background = super.getBackground(); - factory.adapt(this, true, true); - setMenu(parent.getMenu()); - - hookControl(this); - - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 2; - layout.marginHeight = 1; - layout.horizontalSpacing = 2; - layout.verticalSpacing = 0; - setLayout(layout); - - imageLabel = new ImageLabel(this, SWT.NO_FOCUS); - factory.adapt(imageLabel, true, true); - imageLabel.setScaleHint(ImageLabel.SCALE_TO_FIT); - imageLabel.setHorizontalAlignment(SWT.CENTER); - imageLabel.setVerticalAlignment(SWT.CENTER); - GridData imageLayoutData = new GridData(SWT.CENTER, SWT.CENTER, - false, true); - imageLayoutData.exclude = true; - imageLabel.setLayoutData(imageLayoutData); - imageLabel.setVisible(false); - imageLabel.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); - imageLabel.setMenu(getMenu()); - hookControl(imageLabel); - - textLabel = factory.createLabel(this, "", SWT.NO_FOCUS); //$NON-NLS-1$ - textLabel.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, true, true)); - textLabel.setBackground( - parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); - textLabel.setMenu(getMenu()); - hookControl(textLabel); - } - - public void setImageSizeHint(Point hint) { - GridData layoutData = (GridData) imageLabel.getLayoutData(); - layoutData.widthHint = hint.x; - layoutData.heightHint = hint.y; - layout(true); - } - - private void hookControl(Control c) { - c.addListener(SWT.MouseDown, listener); - c.addListener(SWT.MouseDoubleClick, listener); - } - - public void setImage(Image image) { - checkWidget(); - imageLabel.setImage(image); - boolean visible = image != null; - imageLabel.setVisible(visible); - ((GridData) imageLabel.getLayoutData()).exclude = !visible; - layout(true); - } - - public void setText(String text) { - checkWidget(); - textLabel.setText(text); - layout(true); - } - - public boolean getSelection() { - return selected; - } - - public void setSelection(boolean selection) { - checkWidget(); - if (selection == this.selected) - return; - - this.selected = selection; - updateBackground(); - } - - @Override - public Color getBackground() { - return background; - } - - @Override - public void setBackground(Color color) { - checkWidget(); - this.background = color; - updateBackground(); - } - - private void updateBackground() { - if (getSelection()) { - super.setBackground( - getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION)); - } else { - super.setBackground(background); - } - } - - private void handleMouseDown(Event event) { - Control[] siblings = getParent().getChildren(); - for (int i = 0; i < siblings.length; i++) { - Control item = siblings[i]; - if (item instanceof WorkbookMetadataListRow) { - ((WorkbookMetadataListRow) item).setSelection(false); - } - } - setSelection(true); - getParent().notifyListeners(SWT.Selection, new Event()); - } - - private void handleMouseDoubleClick(Event event) { - getParent().notifyListeners(SWT.DefaultSelection, new Event()); - } - - } - - private static class WorkbookMetadataListLabelProvider extends LabelProvider - implements IListRenderer { - - private StraightListLayout layout = new StraightListLayout( - SWT.VERTICAL); - - public IListLayout getListLayout(MListViewer viewer) { - return layout; - } - - public Control createListItemForElement(MListViewer viewer, - Composite parent, Object element) { - WidgetFactory factory = (WidgetFactory) viewer.getControl() - .getData(KEY_WIDGET_FACTORY); - WorkbookMetadataListRow row = new WorkbookMetadataListRow(parent, - factory); - return row; - } - - public void updateListItem(MListViewer viewer, Object element, - Control item) { - WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; - row.setText(getText(element)); - row.setImage(getImage(element)); - } - - public int getListItemState(MListViewer viewer, Control item) { - int state = STATE_NONE; - if (item instanceof WorkbookMetadataListRow) { - WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; - if (row.getSelection()) { - state |= STATE_SELECTED; - } - } - return state; - } - - public void setListItemState(MListViewer viewer, Control item, - int state) { - if (item instanceof WorkbookMetadataListRow) { - WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; - row.setSelection((state & STATE_SELECTED) != 0); - } - } - - } - - private static abstract class AbstractWorkbookMetadataListPart - extends AbstractWorkbookMetadataPart implements IAdaptable { - - private MListViewer viewer; - - protected abstract Object[] getElements(WorkbookMetadata metadata); - - protected abstract String getText(Object element); - - protected abstract Image getImage(Object element, - ResourceManager resourceManager); - - protected Point getImageSizeHint() { - return new Point(SWT.DEFAULT, SWT.DEFAULT); - } - - protected void update(Object element) { - viewer.update(element, null); - firePropertyChange(PROP_CONTROL); - } - - protected MListViewer getViewer() { - return viewer; - } - - public void createControl(final Composite parent) { - WidgetFactory factory = (WidgetFactory) parent - .getData(KEY_WIDGET_FACTORY); - - GridLayout layout = new GridLayout(); - layout.numColumns = 1; - layout.makeColumnsEqualWidth = false; - layout.marginWidth = 2; - layout.marginHeight = 2; - layout.horizontalSpacing = 3; - layout.verticalSpacing = 3; - parent.setLayout(layout); - - viewer = new MListViewer(parent, SWT.NONE); - factory.adapt(viewer.getControl(), true, true); - viewer.getControl().setMenu(parent.getMenu()); - viewer.getControl().setData(KEY_WIDGET_FACTORY, factory); - viewer.getControl().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); -// hookFocusableControl(viewer.getControl()); - - viewer.setContentProvider(createContentProvider()); - viewer.setLabelProvider(createLabelProvider()); - - viewer.setInput(metadata); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - firePropertyChange(PROP_OUTGOING_SELECTION); - } - }); - - final ScrolledComposite scrolledComposite = FormUtil - .getScrolledComposite(parent); - if (scrolledComposite != null) { - viewer.getControl().addListener(SWT.FocusOut, new Listener() { - public void handleEvent(Event event) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - Display display = Display.getCurrent(); - if (display == null || display.isDisposed() - || scrolledComposite.isDisposed()) - return; - - Control focusControl = display - .getFocusControl(); - if (containsControl(scrolledComposite, - focusControl) - && !containsControl(parent, - focusControl)) { - viewer.setSelection( - StructuredSelection.EMPTY); - } - } - }); - } - - private boolean containsControl(Composite composite, - Control c) { - while (c != null) { - if (c == composite) - return true; - c = c.getParent(); - } - return false; - } - }); - } - } - - @Override - protected void refreshControls() { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - - viewer.refresh(); - firePropertyChange(PROP_CONTROL); - } - - protected IContentProvider createContentProvider() { - return new IStructuredContentProvider() { - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - - public void dispose() { - } - - public Object[] getElements(Object inputElement) { - WorkbookMetadata metadata = (WorkbookMetadata) inputElement; - return AbstractWorkbookMetadataListPart.this - .getElements(metadata); - } - }; - } - - private IBaseLabelProvider createLabelProvider() { - return new WorkbookMetadataListLabelProvider() { - - ResourceManager rm = new LocalResourceManager( - JFaceResources.getResources()); - - @Override - public String getText(Object element) { - return AbstractWorkbookMetadataListPart.this - .getText(element); - } - - @Override - public Image getImage(Object element) { - return AbstractWorkbookMetadataListPart.this - .getImage(element, rm); - } - - @Override - public Control createListItemForElement(MListViewer viewer, - Composite parent, Object element) { - Control item = super.createListItemForElement(viewer, - parent, element); - if (item instanceof WorkbookMetadataListRow) { - ((WorkbookMetadataListRow) item) - .setImageSizeHint(getImageSizeHint()); - } - return item; - } - - @Override - public void dispose() { - super.dispose(); - rm.dispose(); - } - }; - } - - public T getAdapter(Class adapter) { - if (adapter == ISelectionProvider.class) - return adapter.cast(viewer); - return null; - } - - } - - private static class TopicViewerComparator extends ViewerComparator { - - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - return Core.getTopicComparator().compare((ITopic) e1, (ITopic) e2); - } - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// Author Info Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private class AuthorInfoPart extends AbstractWorkbookMetadataPart - implements IModifiableWorkbookMetadataPart { - - private Text nameInput; - private Text emailInput; - private Text orgInput; - - private Listener modifyListener = new Listener() { - public void handleEvent(Event event) { - firePropertyChange(PROP_CONTENT); - } - }; - - public boolean isVisible() { - return true; - } - - public String getTitle() { - return Messages.AuthorInfoInspectorSection_title; - } - - public void createControl(Composite parent) { - WidgetFactory factory = (WidgetFactory) parent - .getData(KEY_WIDGET_FACTORY); - - GridLayout layout = new GridLayout(); - layout.marginWidth = 2; - layout.marginHeight = 2; - layout.horizontalSpacing = 5; - layout.verticalSpacing = 3; - layout.numColumns = 2; - parent.setLayout(layout); - - createLabel(parent, factory, - Messages.AuthorInfoInspectorSection_Name); - nameInput = createText(parent, factory); - - createLabel(parent, factory, - Messages.AuthorInfoInspectorSection_Email); - emailInput = createText(parent, factory); - - createLabel(parent, factory, - Messages.AuthorInfoInspectorSection_Organization); - orgInput = createText(parent, factory); - } - - private Label createLabel(Composite parent, WidgetFactory factory, - String text) { - Label label = factory.createLabel(parent, text); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - return label; - } - - private Text createText(Composite parent, WidgetFactory factory) { - Text text = factory.createText(parent, "", SWT.SINGLE); //$NON-NLS-1$ - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - text.addListener(SWT.DefaultSelection, modifyListener); - text.addListener(SWT.FocusOut, modifyListener); - return text; - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - boolean changed = false; - if (workbook == null) { - changed |= metadata.setString(METADATA_AUTHOR_NAME, ""); //$NON-NLS-1$ - changed |= metadata.setString(METADATA_AUTHOR_EMAIL, ""); //$NON-NLS-1$ - changed |= metadata.setString(METADATA_AUTHOR_ORG, ""); //$NON-NLS-1$ - } else if (event == null) { - IMeta meta = workbook.getMeta(); - changed |= metadata.setString(METADATA_AUTHOR_NAME, - meta.getValue(IMeta.AUTHOR_NAME)); - changed |= metadata.setString(METADATA_AUTHOR_EMAIL, - meta.getValue(IMeta.AUTHOR_EMAIL)); - changed |= metadata.setString(METADATA_AUTHOR_ORG, - meta.getValue(IMeta.AUTHOR_ORG)); - } else if (Core.Metadata.equals(event.getType())) { - if (IMeta.AUTHOR_NAME.equals(event.getTarget())) { - changed |= metadata.setString(METADATA_AUTHOR_NAME, - (String) event.getNewValue()); - } else if (IMeta.AUTHOR_EMAIL.equals(event.getTarget())) { - changed |= metadata.setString(METADATA_AUTHOR_EMAIL, - (String) event.getNewValue()); - } else if (IMeta.AUTHOR_ORG.equals(event.getTarget())) { - changed |= metadata.setString(METADATA_AUTHOR_ORG, - (String) event.getNewValue()); - } - } - - if (changed) { - refreshAsynchronously(); - } - } - - @Override - protected void refreshControls() { - String name = metadata.getString(METADATA_AUTHOR_NAME); - if (name == null || "".equals(name)) //$NON-NLS-1$ - name = System.getProperty("user.name"); //$NON-NLS-1$ - updateText(nameInput, name); - updateText(emailInput, metadata.getString(METADATA_AUTHOR_EMAIL)); - updateText(orgInput, metadata.getString(METADATA_AUTHOR_ORG)); - } - - public Command createModificationCommand(IWorkbook workbook) { - String newName = nameInput.getText(); - String newEmail = emailInput.getText(); - String newOrg = orgInput.getText(); - Command command = new CompoundCommand( // - new ModifyMetadataCommand(workbook, IMeta.AUTHOR_NAME, - newName), // - new ModifyMetadataCommand(workbook, IMeta.AUTHOR_EMAIL, - newEmail), // - new ModifyMetadataCommand(workbook, IMeta.AUTHOR_ORG, - newOrg) // - ); - if (!command.canExecute()) - return null; - - command.setLabel(MindMapMessages.WorkbookMetadata_ModifyAuthorInfo); - return command; - } - - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// Summary Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private static final int PRIMARY_BYTES = 5300; - private static final int TOPIC_DEFAULT_BYTES = 160; - - private static class WorkbookSummaryPart - extends AbstractWorkbookMetadataPart { - - private Text estimatedSizeText; - private Text topicCountText; - private Text wordCountText; - private Text revisionCountText; - private Text modificationTimeText; - private Text modifierNameText; - private Text creationTimeText; - - public boolean isVisible() { - return true; - } - - public String getTitle() { - return Messages.FileInfoInspectorSection_title; - } - - public void createControl(Composite parent) { - WidgetFactory factory = (WidgetFactory) parent - .getData(KEY_WIDGET_FACTORY); - - GridLayout layout = new GridLayout(); - layout.marginWidth = 2; - layout.marginHeight = 2; - layout.horizontalSpacing = 5; - layout.verticalSpacing = 3; - layout.numColumns = 2; - parent.setLayout(layout); - - estimatedSizeText = createTextWithLabel(parent, factory, - Messages.FileInfoEstimateSize_label); - - topicCountText = createTextWithLabel(parent, factory, - Messages.FileInfoTopics_label); - - wordCountText = createTextWithLabel(parent, factory, - Messages.FileInfoWords_label); - - revisionCountText = createTextWithLabel(parent, factory, - Messages.FileInfoRevisions_label); - - modificationTimeText = createTextWithLabel(parent, factory, - Messages.FileInfoModifiedTime_label); - - modifierNameText = createTextWithLabel(parent, factory, - Messages.FileInfoModifiedBy_label); - - creationTimeText = createTextWithLabel(parent, factory, - Messages.FileInfoCreatedTime_label); - } - - private Text createTextWithLabel(Composite parent, - WidgetFactory factory, String labelText) { - Label label = factory.createLabel(parent, labelText); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - - Text text = new Text(parent, - SWT.READ_ONLY | SWT.SINGLE | factory.getOrientation()); - factory.adapt(text, true, false); - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return text; - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - WorkbookMetadata oldMetadata = metadata.copy(); - - if (workbook == null) { - metadata.deleteAll(); - } else if (event == null) { - workbookChanged(workbook); - } else if (Core.SheetAdd.equals(event.getType())) { - sheetAdded((ISheet) event.getTarget()); - } else if (Core.SheetRemove.equals(event.getType())) { - sheetRemoved((ISheet) event.getTarget()); - } else if (Core.TopicAdd.equals(event.getType())) { - topicAdded((ITopic) event.getTarget()); - } else if (Core.TopicRemove.equals(event.getType())) { - topicRemoved((ITopic) event.getTarget()); - } else if (Core.TitleText.equals(event.getType())) { - titleTextChanged((String) event.getOldValue(), - (String) event.getNewValue()); - } else if (Core.TopicNotes.equals(event.getType())) { - if (INotes.PLAIN.equals(event.getTarget())) { - notesChanged((INotesContent) event.getOldValue(), - (INotesContent) event.getNewValue()); - } - } else if (Core.FileEntryAdd.equals(event.getType())) { - fileEntryAdded((IFileEntry) event.getTarget()); - } else if (Core.FileEntryRemove.equals(event.getType())) { - fileEntryRemoved((IFileEntry) event.getTarget()); - } else if (Core.RelationshipAdd.equals(event.getType())) { - relationshipAdded((IRelationship) event.getTarget()); - } else if (Core.RelationshipRemove.equals(event.getType())) { - relationshipRemoved((IRelationship) event.getTarget()); - } else if (Core.BoundaryAdd.equals(event.getType())) { - boundaryAdded((IBoundary) event.getTarget()); - } else if (Core.BoundaryRemove.equals(event.getType())) { - boundaryRemoved((IBoundary) event.getTarget()); - } else if (Core.RevisionAdd.equals(event.getType())) { - metadata.increaseInt(METADATA_REVISION_COUNT, 1); - } else if (Core.RevisionRemove.equals(event.getType())) { - metadata.decreaseInt(METADATA_REVISION_COUNT, 1); - } else if (Core.ModifyTime.equals(event.getType()) - || Core.WorkbookSave.equals(event.getType())) { - IModifiable source = (IModifiable) event.getSource(); - metadata.setLong(METADATA_MODIFICATION_TIME, - source.getModifiedTime()); - metadata.setString(METADATA_MODIFIER_NAME, - source.getModifiedBy()); - } - - if (!metadata.equals(oldMetadata)) { - refreshAsynchronously(); - } - } - - @Override - protected void refreshControls() { - updateText(topicCountText, - String.valueOf(metadata.getInt(METADATA_TOPIC_COUNT))); - updateText(wordCountText, - String.valueOf(metadata.getInt(METADATA_WORD_COUNT))); - updateText(estimatedSizeText, FileUtils.fileLengthToString( - metadata.getLong(METADATA_ESTIMATED_SIZE))); - updateText(revisionCountText, - String.valueOf(metadata.getInt(METADATA_REVISION_COUNT))); - updateText(modificationTimeText, NumberUtils - .formatDate(metadata.getLong(METADATA_MODIFICATION_TIME))); - updateText(modifierNameText, - metadata.getString(METADATA_MODIFIER_NAME)); - updateText(creationTimeText, - metadata.getString(METADATA_CREATION_TIME)); - } - - private void workbookChanged(IWorkbook workbook) { - metadata.deleteAll(); - - metadata.setLong(METADATA_MODIFICATION_TIME, - workbook.getModifiedTime()); - String name = workbook.getModifiedBy(); - if (name == null || "".equals(name)) //$NON-NLS-1$ - name = System.getProperty("user.name"); //$NON-NLS-1$ - metadata.setString(METADATA_MODIFIER_NAME, name); - metadata.setString(METADATA_CREATION_TIME, - workbook.getMeta().getValue(IMeta.CREATED_TIME)); - - metadata.setLong(METADATA_ESTIMATED_SIZE, PRIMARY_BYTES); - - for (ISheet sheet : workbook.getSheets()) { - sheetAdded(sheet); - } - Iterator entryIter = workbook.getManifest() - .iterFileEntries(); - while (entryIter.hasNext()) { - fileEntryAdded(entryIter.next()); - } - } - - private void sheetAdded(ISheet sheet) { - titleTextChanged(null, sheet.getTitleText()); - topicAdded(sheet.getRootTopic()); - metadata.increaseInt(METADATA_REVISION_COUNT, - sheet.getOwnedWorkbook().getRevisionRepository() - .getRevisionManager(sheet.getId(), IRevision.SHEET) - .getRevisions().size()); - for (IRelationship r : sheet.getRelationships()) { - relationshipAdded(r); - } - } - - private void sheetRemoved(ISheet sheet) { - for (IRelationship r : sheet.getRelationships()) { - relationshipRemoved(r); - } - - metadata.decreaseInt(METADATA_REVISION_COUNT, - sheet.getOwnedWorkbook().getRevisionRepository() - .getRevisionManager(sheet.getId(), IRevision.SHEET) - .getRevisions().size()); - topicRemoved(sheet.getRootTopic()); - titleTextChanged(sheet.getTitleText(), null); - } - - private void topicAdded(ITopic topic) { - metadata.increaseInt(METADATA_TOPIC_COUNT, 1); - - metadata.increaseLong(METADATA_ESTIMATED_SIZE, TOPIC_DEFAULT_BYTES); - - titleTextChanged(null, topic.getTitleText()); - notesChanged(null, topic.getNotes().getContent(INotes.PLAIN)); - - Iterator childIter = topic.getAllChildrenIterator(); - while (childIter.hasNext()) { - topicAdded(childIter.next()); - } - - for (IBoundary boundary : topic.getBoundaries()) { - boundaryAdded(boundary); - } - } - - private void topicRemoved(ITopic topic) { - for (IBoundary boundary : topic.getBoundaries()) { - boundaryRemoved(boundary); - } - - Iterator childIter = topic.getAllChildrenIterator(); - while (childIter.hasNext()) { - topicRemoved(childIter.next()); - } - - notesChanged(topic.getNotes().getContent(INotes.PLAIN), null); - titleTextChanged(topic.getTitleText(), null); - - metadata.decreaseLong(METADATA_ESTIMATED_SIZE, TOPIC_DEFAULT_BYTES); - - metadata.decreaseInt(METADATA_TOPIC_COUNT, 1); - } - - private void titleTextChanged(String oldTitle, String newTitle) { - if (oldTitle != null) { - metadata.decreaseLong(METADATA_ESTIMATED_SIZE, - oldTitle.length()); - metadata.decreaseInt(METADATA_WORD_COUNT, countWords(oldTitle)); - } - if (newTitle != null) { - metadata.increaseLong(METADATA_ESTIMATED_SIZE, - newTitle.length()); - metadata.increaseInt(METADATA_WORD_COUNT, countWords(newTitle)); - } - } - - private void notesChanged(INotesContent oldNotes, - INotesContent newNotes) { - if (oldNotes instanceof IPlainNotesContent) { - String content = ((IPlainNotesContent) oldNotes) - .getTextContent(); - if (content != null) { - metadata.decreaseInt(METADATA_WORD_COUNT, - countWords(content)); - } - } - - if (newNotes instanceof IPlainNotesContent) { - String content = ((IPlainNotesContent) newNotes) - .getTextContent(); - if (content != null) { - metadata.increaseInt(METADATA_WORD_COUNT, - countWords(content)); - } - } - } - - private void fileEntryAdded(IFileEntry entry) { - metadata.increaseLong(METADATA_ESTIMATED_SIZE, entry.getSize()); - } - - private void fileEntryRemoved(IFileEntry entry) { - metadata.decreaseLong(METADATA_ESTIMATED_SIZE, entry.getSize()); - } - - private void relationshipAdded(IRelationship r) { - titleTextChanged(null, r.getTitleText()); - } - - private void relationshipRemoved(IRelationship r) { - titleTextChanged(r.getTitleText(), null); - } - - private void boundaryAdded(IBoundary b) { - titleTextChanged(null, b.getTitleText()); - } - - private void boundaryRemoved(IBoundary b) { - titleTextChanged(b.getTitleText(), null); - } - - private static int countWords(String s) { - int total = s.length(); - int count = 0; - boolean inWord = false; - char c; - for (int i = 0; i < total; i++) { - c = s.charAt(i); - if (isOneWordCharacter(c)) { - if (inWord) - count++; - count++; - inWord = false; - } else if (Character.isLetter(c) || Character.isDigit(c)) { - inWord = true; - } else { - if (inWord) - count++; - inWord = false; - } - } - if (inWord) - count++; - return count; - } - - private static boolean isOneWordCharacter(char c) { - Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); - if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS - || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS - || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A - || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION - || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION - || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { - return true; - } - return false; - } - - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// Attachments Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private static class AttachmentListPart - extends AbstractWorkbookMetadataListPart { - - public String getTitle() { - return NLS.bind(Messages.AttachmentsInspectorSection_title, - metadata.sizeOfSet(METADATA_ATTACHMENTS)); - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - WorkbookMetadata oldMetadata = metadata.copy(); - Object toUpdate = null; - - if (workbook == null) { - metadata.deleteAll(); - } else if (event == null) { - metadata.deleteAll(); - for (ISheet sheet : workbook.getSheets()) { - topicAdded(sheet.getRootTopic()); - } - } else if (Core.TopicAdd.equals(event.getType())) { - topicAdded((ITopic) event.getTarget()); - } else if (Core.TopicRemove.equals(event.getType())) { - topicRemoved((ITopic) event.getTarget()); - } else if (Core.SheetAdd.equals(event.getType())) { - topicAdded(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.SheetRemove.equals(event.getType())) { - topicRemoved(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.TopicHyperlink.equals(event.getType())) { - ITopic source = (ITopic) event.getSource(); - linkChanged(source, (String) event.getOldValue(), - (String) event.getNewValue()); - if (metadata.containsInSet(METADATA_ATTACHMENTS, source)) { - toUpdate = source; - } - } else if (Core.TitleText.equals(event.getType())) { - Object source = event.getSource(); - if (metadata.containsInSet(METADATA_ATTACHMENTS, source)) { - toUpdate = source; - } - } - - if (!metadata.equals(oldMetadata)) { - refreshAsynchronously(); - } else if (toUpdate != null) { - update(toUpdate); - } - } - - private void topicAdded(ITopic topic) { - linkChanged(topic, null, topic.getHyperlink()); - - Iterator childIter = topic.getAllChildrenIterator(); - while (childIter.hasNext()) { - topicAdded(childIter.next()); - } - } - - private void topicRemoved(ITopic topic) { - Iterator childIter = topic.getAllChildrenIterator(); - while (childIter.hasNext()) { - topicRemoved(childIter.next()); - } - - linkChanged(topic, topic.getHyperlink(), null); - } - - private void linkChanged(ITopic topic, String oldLink, String newLink) { - IFileEntry oldEntry = findFileEntry(topic, oldLink); - if (oldEntry != null) { - metadata.removeFromSet(METADATA_ATTACHMENTS, topic); - } - - IFileEntry newEntry = findFileEntry(topic, newLink); - if (newEntry != null) { - metadata.addToSet(METADATA_ATTACHMENTS, topic); - } - } - - private IFileEntry findFileEntry(ITopic topic, String link) { - if (link == null || !HyperlinkUtils.isAttachmentURL(link)) - return null; - - IManifest manifest = topic.getOwnedWorkbook().getManifest(); - if (manifest == null) - return null; - - return manifest.getFileEntry(HyperlinkUtils.toAttachmentPath(link)); - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - getViewer().setComparator(new TopicViewerComparator()); - } - - @Override - protected Object[] getElements(WorkbookMetadata metadata) { - return metadata.getSet(METADATA_ATTACHMENTS).toArray(); - } - - @Override - protected String getText(Object element) { - if (!(element instanceof ITopic)) - return ""; //$NON-NLS-1$ - - ITopic topic = (ITopic) element; - String fileName = topic.getTitleText(); - IFileEntry entry = findFileEntry(topic, topic.getHyperlink()); - if (entry == null) - return fileName; - - long size = entry.getSize(); - return String.format("%s (%s)", fileName, //$NON-NLS-1$ - FileUtils.fileLengthToString(size)); - } - - @Override - protected Image getImage(Object element, - ResourceManager resourceManager) { - if (!(element instanceof ITopic)) - return null; - - ITopic topic = (ITopic) element; - String fileName = topic.getTitleText(); - ImageDescriptor icon = MindMapUI.getImages().getFileIcon(fileName, - true); - if (icon == null) { - icon = MindMapUI.getImages().get(IMindMapImages.UNKNOWN_FILE, - true); - } - return (Image) resourceManager.get(icon); - } - - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// External Files Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private static class ExternalFileListPart - extends AbstractWorkbookMetadataListPart { - - public String getTitle() { - return NLS.bind(Messages.ExternalFilesInspectorSection_title, - metadata.sizeOfSet(METADATA_EXTERNAL_FILES)); - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - WorkbookMetadata oldMetadata = this.metadata.copy(); - Object toUpdate = null; - - if (workbook == null) { - metadata.deleteAll(); - } else if (event == null) { - metadata.deleteAll(); - workbookChanged(workbook); - } else if (Core.SheetAdd.equals(event.getType())) { - topicAdded(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.SheetRemove.equals(event.getType())) { - topicRemoved(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.TopicAdd.equals(event.getType())) { - topicAdded((ITopic) event.getTarget()); - } else if (Core.TopicRemove.equals(event.getType())) { - topicRemoved((ITopic) event.getTarget()); - } else if (Core.TopicHyperlink.equals(event.getType())) { - ITopic source = (ITopic) event.getSource(); - linkChanged(source, (String) event.getOldValue(), - (String) event.getNewValue()); - if (metadata.containsInSet(METADATA_EXTERNAL_FILES, source)) { - toUpdate = source; - } - } else if (Core.TitleText.equals(event.getType())) { - Object source = event.getSource(); - if (metadata.containsInSet(METADATA_EXTERNAL_FILES, source)) { - toUpdate = source; - } - } - - if (!metadata.equals(oldMetadata)) { - refreshAsynchronously(); - } else if (toUpdate != null) { - update(toUpdate); - } - - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - getViewer().setComparator(new TopicViewerComparator()); - } - - @Override - protected Object[] getElements(WorkbookMetadata metadata) { - return metadata.getSet(METADATA_EXTERNAL_FILES).toArray(); - } - - @Override - protected Image getImage(Object element, - ResourceManager resourceManager) { - if (!(element instanceof ITopic)) - return null; - - ITopic topic = (ITopic) element; - File file = getFile(topic.getHyperlink()); - if (file == null) - return null; - - ImageDescriptor icon = MindMapUI.getImages() - .getFileIcon(file.getAbsolutePath(), true); - if (icon == null) { - icon = MindMapUI.getImages().get(IMindMapImages.UNKNOWN_FILE, - true); - } - return (Image) resourceManager.get(icon); - } - - @Override - protected String getText(Object element) { - if (!(element instanceof ITopic)) - return ""; //$NON-NLS-1$ - - ITopic topic = (ITopic) element; - File file = getFile(topic.getHyperlink()); - if (file == null) - return ""; //$NON-NLS-1$ - - return file.getName(); - } - - private void workbookChanged(IWorkbook workbook) { - for (ISheet sheet : workbook.getSheets()) { - topicAdded(sheet.getRootTopic()); - } - } - - private void topicAdded(ITopic topic) { - linkChanged(topic, null, topic.getHyperlink()); - - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicAdded(childrenIterator.next()); - } - } - - private void topicRemoved(ITopic topic) { - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicRemoved(childrenIterator.next()); - } - - linkChanged(topic, topic.getHyperlink(), null); - } - - private void linkChanged(ITopic topic, String oldLink, String newLink) { - File oldFile = getFile(oldLink); - if (oldFile != null) { - metadata.removeFromSet(METADATA_EXTERNAL_FILES, topic); - } - - File newFile = getFile(newLink); - if (newFile != null) { - metadata.addToSet(METADATA_EXTERNAL_FILES, topic); - } - } - - private File getFile(String link) { - if (!FilePathParser.isFileURI(link)) - return null; - return new File(FilePathParser.toPath(link)); - } - - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// Hyperlinks Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private static class HyperlinkListPart - extends AbstractWorkbookMetadataListPart { - - public String getTitle() { - return NLS.bind(Messages.HyperlinkInspectorSection_title, - metadata.sizeOfSet(METADATA_HYPERLINKS)); - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - WorkbookMetadata oldMetadata = this.metadata.copy(); - Object toUpdate = null; - - if (workbook == null) { - metadata.deleteAll(); - } else if (event == null) { - metadata.deleteAll(); - workbookChanged(workbook); - } else if (Core.SheetAdd.equals(event.getType())) { - topicAdded(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.SheetRemove.equals(event.getType())) { - topicRemoved(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.TopicAdd.equals(event.getType())) { - topicAdded((ITopic) event.getTarget()); - } else if (Core.TopicRemove.equals(event.getType())) { - topicRemoved((ITopic) event.getTarget()); - } else if (Core.TopicHyperlink.equals(event.getType())) { - ITopic source = (ITopic) event.getSource(); - linkChanged(source, (String) event.getOldValue(), - (String) event.getNewValue()); - if (metadata.containsInSet(METADATA_HYPERLINKS, source)) { - toUpdate = source; - } - } else if (Core.TitleText.equals(event.getType())) { - Object source = event.getSource(); - if (metadata.containsInSet(METADATA_HYPERLINKS, source)) { - toUpdate = source; - } - } - - if (!metadata.equals(oldMetadata)) { - refreshAsynchronously(); - } else if (toUpdate != null) { - update(toUpdate); - } - - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - getViewer().setComparator(new TopicViewerComparator()); - } - - @Override - protected Object[] getElements(WorkbookMetadata metadata) { - return metadata.getSet(METADATA_HYPERLINKS).toArray(); - } - - @Override - protected Image getImage(Object element, - ResourceManager resourceManager) { - return null; - } - - @Override - protected String getText(Object element) { - if (!(element instanceof ITopic)) - return ""; //$NON-NLS-1$ - - ITopic topic = (ITopic) element; - return topic.getHyperlink(); - } - - private void workbookChanged(IWorkbook workbook) { - for (ISheet sheet : workbook.getSheets()) { - topicAdded(sheet.getRootTopic()); - } - } - - private void topicAdded(ITopic topic) { - linkChanged(topic, null, topic.getHyperlink()); - - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicAdded(childrenIterator.next()); - } - } - - private void topicRemoved(ITopic topic) { - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicRemoved(childrenIterator.next()); - } - - linkChanged(topic, topic.getHyperlink(), null); - } - - private void linkChanged(ITopic topic, String oldLink, String newLink) { - if (isNormalHyperlink(oldLink)) { - metadata.removeFromSet(METADATA_HYPERLINKS, topic); - } - - if (isNormalHyperlink(newLink)) { - metadata.addToSet(METADATA_HYPERLINKS, topic); - } - } - - private boolean isNormalHyperlink(String link) { - return link != null && !HyperlinkUtils.isAttachmentURL(link) - && !HyperlinkUtils.isInternalURL(link) - && !FilePathParser.isFileURI(link); - } - - } - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - //// Images Section - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - private static class ImageListPart - extends AbstractWorkbookMetadataListPart { - - public String getTitle() { - return NLS.bind(Messages.ImageInspectorSection_title, - metadata.sizeOfSet(METADATA_IMAGES)); - } - - public void refresh(IWorkbook workbook, CoreEvent event) { - WorkbookMetadata oldMetadata = this.metadata.copy(); - Object toUpdate = null; - - if (workbook == null) { - metadata.deleteAll(); - } else if (event == null) { - metadata.deleteAll(); - workbookChanged(workbook); - } else if (Core.SheetAdd.equals(event.getType())) { - topicAdded(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.SheetRemove.equals(event.getTarget())) { - topicRemoved(((ISheet) event.getTarget()).getRootTopic()); - } else if (Core.TopicAdd.equals(event.getType())) { - topicAdded((ITopic) event.getTarget()); - } else if (Core.TopicRemove.equals(event.getType())) { - topicRemoved((ITopic) event.getTarget()); - } else if (Core.ImageSource.equals(event.getType())) { - ITopic source = ((IImage) event.getSource()).getParent(); - imageSourceChanged(source, (String) event.getOldValue(), - (String) event.getNewValue()); - if (metadata.containsInSet(METADATA_IMAGES, source)) { - toUpdate = source; - } - } else if (Core.TitleText.equals(event.getType())) { - Object source = event.getSource(); - if (metadata.containsInSet(METADATA_IMAGES, source)) { - toUpdate = source; - } - } - - if (!metadata.equals(oldMetadata)) { - refreshAsynchronously(); - } else if (toUpdate != null) { - update(toUpdate); - } - } - - @Override - public void createControl(Composite parent) { - super.createControl(parent); - getViewer().setComparator(new TopicViewerComparator()); - } - - @Override - protected Object[] getElements(WorkbookMetadata metadata) { - return metadata.getSet(METADATA_IMAGES).toArray(); - } - - @Override - protected String getText(Object element) { - if (!(element instanceof ITopic)) - return ""; //$NON-NLS-1$ - - ITopic topic = (ITopic) element; - String imageURI = topic.getImage().getSource(); - if (HyperlinkUtils.isAttachmentURL(imageURI)) { - String path = HyperlinkUtils.toAttachmentPath(imageURI); - IFileEntry entry = topic.getOwnedWorkbook().getManifest() - .getFileEntry(path); - if (entry != null) { - return String.format("%s (%s)", topic.getTitleText(), //$NON-NLS-1$ - FileUtils.fileLengthToString(entry.getSize())); - } - } - return topic.getTitleText(); - } - - @Override - protected Image getImage(final Object element, - final ResourceManager resourceManager) { - if (!(element instanceof ITopic)) - return null; - - ITopic topic = (ITopic) element; - String imageURI = topic.getImage().getSource(); - if (HyperlinkUtils.isAttachmentURL(imageURI)) { - String path = HyperlinkUtils.toAttachmentPath(imageURI); - IWorkbook workbook = topic.getOwnedWorkbook(); - IFileEntry entry = workbook.getManifest().getFileEntry(path); - ImageDescriptor descriptor = AttachmentImageDescriptor - .createFromEntry(workbook, entry); - return (Image) resourceManager.get(descriptor); - } else if (FilePathParser.isFileURI(imageURI)) { - String path = FilePathParser.toPath(imageURI); - ImageDescriptor descriptor = ImageDescriptor - .createFromFile(null, path); - return (Image) resourceManager.get(descriptor); - } else { - ImageDescriptor descriptor = ImageDownloader.getInstance() - .getImage(imageURI); - if (descriptor != null) - return (Image) resourceManager.get(descriptor); - ImageDownloader.getInstance().register(imageURI, - new Runnable() { - public void run() { - if (getViewer() == null - || getViewer().getControl() == null - || getViewer().getControl() - .isDisposed()) - return; - - Display display = getViewer().getControl() - .getDisplay(); - if (display == null || display.isDisposed()) - return; - - display.asyncExec(new Runnable() { - public void run() { - update(element); - } - }); - } - }); - } - return null; - } - - @Override - protected Point getImageSizeHint() { - return new Point(32, 32); - } - - private void workbookChanged(IWorkbook workbook) { - for (ISheet sheet : workbook.getSheets()) { - topicAdded(sheet.getRootTopic()); - } - } - - private void topicAdded(ITopic topic) { - imageSourceChanged(topic, null, topic.getImage().getSource()); - - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicAdded(childrenIterator.next()); - } - } - - private void topicRemoved(ITopic topic) { - Iterator childrenIterator = topic.getAllChildrenIterator(); - while (childrenIterator.hasNext()) { - topicRemoved(childrenIterator.next()); - } - - imageSourceChanged(topic, topic.getImage().getSource(), null); - } - - private void imageSourceChanged(ITopic topic, String oldSrc, - String newSrc) { - if (oldSrc != null) { - metadata.removeFromSet(METADATA_IMAGES, topic); - } - if (newSrc != null) { - metadata.addToSet(METADATA_IMAGES, topic); - } - } - - } - - private ICoreEventListener coreEventHandler = new ICoreEventListener() { - public void handleCoreEvent(final CoreEvent event) { - Display display = getDisplay(); - if (display == null) - return; - - display.asyncExec(new Runnable() { - public void run() { - refreshParts(event); - } - }); - } - - private Display getDisplay() { - Display display = Display.getCurrent(); - if (display != null) - return display; - - Control control = getControl(); - if (control == null || control.isDisposed()) - return null; - - return control.getDisplay(); - } - }; - - private IPropertyListener propertyChangeHandler = new IPropertyListener() { - public void propertyChanged(Object source, int propId) { - if (source instanceof IWorkbookMetadataPart) { - if (propId == PROP_CONTROL) { - updateSection((IWorkbookMetadataPart) source); - scheduleReflow(); - } else if (propId == PROP_CONTENT) { - if (source instanceof IModifiableWorkbookMetadataPart) { - executeCommand( - ((IModifiableWorkbookMetadataPart) source) - .createModificationCommand(workbook)); - } - } else if (propId == PROP_OUTGOING_SELECTION) { - revealSelectionInEditor((IWorkbookMetadataPart) source); - } - } - } - }; - - private IPartListener partListenerHandler = new IPartListener() { - - public void partOpened(IWorkbenchPart part) { - } - - public void partDeactivated(IWorkbenchPart part) { - if (part == sourceEditor) { - - } - } - - public void partClosed(IWorkbenchPart part) { - if (part == sourceEditor) { - setSourceEditor(null); - } - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partActivated(IWorkbenchPart part) { - - if (part == sourceEditor || !(part instanceof IEditorPart)) - return; - - if (part instanceof IEditorPart) { - setSourceEditor((IEditorPart) part); - } - } - }; - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(DialogMessages.WorkbookMetaInspectorDialog_title); - newShell.setSize(500, 445); - newShell.setLocation( - Display.getCurrent().getClientArea().width / 2 - - newShell.getShell().getSize().x / 2, - Display.getCurrent().getClientArea().height / 2 - - newShell.getSize().y / 2); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 14; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createDescriptionArea(composite); - - Composite content = new Composite(composite, SWT.BORDER); - this.composite = content; - content.setLayoutData(new GridData(GridData.FILL_BOTH)); - StackLayout stack = new StackLayout(); - content.setLayout(stack); - - factory = new WidgetFactory(parent.getDisplay()); - factory.getHyperlinkGroup() - .setHyperlinkUnderlineMode(HyperlinkGroup.UNDERLINE_HOVER); - form = factory.createScrolledForm(content); - stack.topControl = form; - - final Composite body = form.getBody(); - - TableWrapLayout layout = new TableWrapLayout(); - layout.topMargin = 0; - layout.leftMargin = 0; - layout.rightMargin = 0; - layout.bottomMargin = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 3; - body.setLayout(layout); - createSections(body); - - form.getBody().addListener(SWT.MouseDown, new Listener() { - public void handleEvent(Event event) { - form.getBody().setFocus(); - } - }); - - form.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - handleDispose(); - } - }); - - setWorkbook(sourceEditor == null ? null - : MindMapUIPlugin.getAdapter(sourceEditor, IWorkbook.class)); - return composite; - } - - @Override - protected Control createButtonBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - // create a layout with spacing and margins appropriate for the font - // size. - GridLayout layout = new GridLayout(); - layout.numColumns = 0; // this is incremented by createButton - layout.makeColumnsEqualWidth = true; - layout.marginWidth = 13; - layout.marginHeight = 23; - layout.horizontalSpacing = 18; - layout.verticalSpacing = 0; - composite.setLayout(layout); - - GridData data = new GridData( - GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); - composite.setLayoutData(data); - composite.setFont(parent.getFont()); - - // Add the buttons to the button bar. - createButtonsForButtonBar(composite); - return composite; - } - - private void createDescriptionArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 21; - gridLayout.verticalSpacing = 0; - composite.setLayout(gridLayout); - - Label discriptionLabel = new Label(composite, SWT.WRAP); - GridData discriptionLabelData = new GridData(SWT.FILL, SWT.CENTER, true, - true); - discriptionLabel.setLayoutData(discriptionLabelData); - discriptionLabel.setAlignment(SWT.LEFT); - discriptionLabel - .setText(MindMapMessages.WorkbookMetaInspectorDialog_message); - } - - private void handleDispose() { - setWorkbook(null); - - for (IWorkbookMetadataPart part : parts) { - part.removePropertyListener(propertyChangeHandler); - } - parts.clear(); - sections.clear(); - - if (factory != null) { - factory.dispose(); - factory = null; - } - - form = null; - composite = null; - } - - private void setWorkbook(IWorkbook workbook) { - IWorkbook oldWorkbook = this.workbook; - if (workbook == oldWorkbook) - return; - - this.workbook = workbook; - workbookChanged(workbook, oldWorkbook); - } - - private void workbookChanged(IWorkbook workbook2, IWorkbook oldWorkbook) { - if (eventRegister != null) { - eventRegister.unregisterAll(); - } - - if (getControl() != null && !getControl().isDisposed()) { - for (IWorkbookMetadataPart part : parts) { - part.refresh(workbook, null); - } - scheduleReflow(); - } - - if (workbook != null) { - ICoreEventSupport support = (ICoreEventSupport) workbook - .getAdapter(ICoreEventSupport.class); - if (support != null) { - if (eventRegister == null) { - eventRegister = new CoreEventRegister(coreEventHandler); - } - eventRegister.setNextSupport(support); - registerCoreEventTypes(eventRegister); - } - } - } - - private void registerCoreEventTypes(CoreEventRegister register) { - register.register(Core.Metadata); - register.register(Core.SheetAdd); - register.register(Core.SheetRemove); - register.register(Core.TopicAdd); - register.register(Core.TopicRemove); - register.register(Core.FileEntryAdd); - register.register(Core.FileEntryRemove); - register.register(Core.TopicHyperlink); - register.register(Core.TitleText); - register.register(Core.ImageSource); - register.register(Core.RevisionAdd); - register.register(Core.RevisionRemove); - register.register(Core.ModifyTime); - register.register(Core.WorkbookSave); - register.register(Core.RelationshipAdd); - register.register(Core.RelationshipRemove); - register.register(Core.BoundaryAdd); - register.register(Core.BoundaryRemove); - register.register(Core.TopicNotes); - } - - private void createSections(Composite parent) { - addSection(parent, new AuthorInfoPart()); - addSection(parent, new WorkbookSummaryPart()); - addSection(parent, new AttachmentListPart()); - addSection(parent, new ExternalFileListPart()); - addSection(parent, new HyperlinkListPart()); - addSection(parent, new ImageListPart()); - } - - private void addSection(Composite parent, IWorkbookMetadataPart part) { - Section section = factory.createSection(parent, - Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED - | Section.NO_TITLE_FOCUS_BOX); - section.setText(part.getTitle()); - section.setLayoutData( - new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL)); - section.setTitleBarBackground( - section.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - section.setTitleBarBorderColor( - section.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - Composite client = factory.createComposite(section, SWT.WRAP); - client.setData(KEY_WIDGET_FACTORY, factory); - section.setClient(client); - part.createControl(client); - part.refresh(workbook, null); - part.addPropertyListener(propertyChangeHandler); - parts.add(part); - sections.put(part, section); - - updateSectionVisibility(part, section, part.isVisible()); - } - - private void refreshParts(final CoreEvent event) { - for (IWorkbookMetadataPart part : parts) { - part.refresh(workbook, event); - } - } - - private void updateSectionVisibility(IWorkbookMetadataPart part, - Section section, boolean visible) { - if (visible) { - section.setParent(form.getBody()); - - Section lastVisibleSection = null; - for (IWorkbookMetadataPart p : parts) { - if (p == part) - break; - Section s = sections.get(p); - if (s.getVisible()) { - lastVisibleSection = s; - } else { - section.moveBelow(lastVisibleSection); - } - } - } else { - section.setParent(composite); - } - section.setVisible(visible); - } - - private void revealSelectionInEditor(IWorkbookMetadataPart part) { - ISelectionProvider partSelectionProvider = MindMapUIPlugin - .getAdapter(part, ISelectionProvider.class); - if (partSelectionProvider == null) - return; - - ISelectionProvider editorSelectionProvider = sourceEditor.getSite() - .getSelectionProvider(); - if (editorSelectionProvider == null) - return; - - editorSelectionProvider - .setSelection(partSelectionProvider.getSelection()); - sourceEditor.getSite().getPage().activate(sourceEditor); - } - - private void executeCommand(Command command) { - ICommandStack commandStack = MindMapUIPlugin.getAdapter(sourceEditor, - ICommandStack.class); - if (commandStack != null) { - commandStack.execute(command); - } else { - command.execute(); - } - } - - private synchronized void scheduleReflow() { - if (form == null || form.isDisposed()) - return; - - if (reflowScheduled) - return; - - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - reflowScheduled = false; - - if (form == null || form.isDisposed()) - return; - form.reflow(true); - } - }); - reflowScheduled = true; - } - - private void updateSection(IWorkbookMetadataPart part) { - Section section = sections.get(part); - if (section != null && !section.isDisposed()) { - String title = part.getTitle(); - String oldTitle = section.getText(); - if (!title.equals(oldTitle)) { - section.setText(title); - } - - boolean visible = part.isVisible(); - boolean oldVisible = section.getVisible(); - if (visible != oldVisible) { - updateSectionVisibility(part, section, visible); - } - - scheduleReflow(); - } - } - - private Composite getControl() { - return composite; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.CLOSE_ID, - IDialogConstants.CLOSE_LABEL, true); - } - - @Override - protected void buttonPressed(int buttonId) { - super.buttonPressed(buttonId); - if (IDialogConstants.CLOSE_ID == buttonId) - close(); - } - - public void setSourceEditor(IEditorPart sourceEditor) { - Assert.isNotNull(instance); - this.sourceEditor = sourceEditor; - setWorkbook(sourceEditor == null ? null - : MindMapUIPlugin.getAdapter(sourceEditor, IWorkbook.class)); - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() - .addPartListener(partListenerHandler); - } - - public static WorkbookMetaInspectorDialog getInstance(Shell parentShell) { - if (instance == null) { - instance = new WorkbookMetaInspectorDialog(parentShell); - } - return instance; - } - -} +package org.xmind.ui.internal.dialogs; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.HyperlinkGroup; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.forms.widgets.TableWrapData; +import org.eclipse.ui.forms.widgets.TableWrapLayout; +import org.eclipse.ui.internal.forms.widgets.FormUtil; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.IFileEntry; +import org.xmind.core.IImage; +import org.xmind.core.IManifest; +import org.xmind.core.IMeta; +import org.xmind.core.IModifiable; +import org.xmind.core.INotes; +import org.xmind.core.INotesContent; +import org.xmind.core.IPlainNotesContent; +import org.xmind.core.IRelationship; +import org.xmind.core.IRevision; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.dom.NumberUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.ModifyMetadataCommand; +import org.xmind.ui.forms.WidgetFactory; +import org.xmind.ui.internal.AttachmentImageDescriptor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.mindmap.ImageDownloader; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.internal.views.Messages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.viewers.FileUtils; +import org.xmind.ui.viewers.IListLayout; +import org.xmind.ui.viewers.IListRenderer; +import org.xmind.ui.viewers.ImageLabel; +import org.xmind.ui.viewers.MListViewer; +import org.xmind.ui.viewers.StraightListLayout; + +public class WorkbookMetaInspectorDialog extends Dialog { + + private static WorkbookMetaInspectorDialog instance; + + private static final int PROP_CONTROL = 1; + + private static final int PROP_CONTENT = 3; + + private static final int PROP_OUTGOING_SELECTION = 4; + + private static final String KEY_WIDGET_FACTORY = WorkbookMetaInspectorDialog.class + .getName() + ".widgetFactory"; //$NON-NLS-1$ + + private WidgetFactory factory; + + private Composite composite; + + private ScrolledForm form; + + private IEditorPart sourceEditor; + + private IWorkbook workbook; + + private CoreEventRegister eventRegister; + + private boolean reflowScheduled = false; + + private List parts = new ArrayList(); + + private Map sections = new HashMap(); + + private WorkbookMetaInspectorDialog(Shell shell) { + super(shell); + setShellStyle( + SWT.RESIZE | SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE); + } + + private static interface IWorkbookMetadataPart { + + // section text + String getTitle(); + + // controls visibility of this part + boolean isVisible(); + + // layout on the parent should be set in this method + void createControl(Composite parent); + + // when triggered upon workbook change, the event is null + // when triggered upon core event, the event is not null + void refresh(IWorkbook workbook, CoreEvent event); + + void addPropertyListener(IPropertyListener listener); + + void removePropertyListener(IPropertyListener listener); + + Control getFocusControl(); + + } + + private static interface IModifiableWorkbookMetadataPart { + Command createModificationCommand(IWorkbook workbook); + } + + protected static class WorkbookMetadata { + + private final Map delegate = new HashMap(); + + public boolean set(String key, Object value) { + Object oldValue = delegate.put(key, value); + return value != oldValue + && (value == null || !value.equals(oldValue)); + } + + public Object get(String key) { + return delegate.get(key); + } + + public boolean delete(String key) { + boolean hadValue = delegate.containsKey(key); + delegate.remove(key); + return hadValue; + } + + public boolean deleteAll() { + boolean hadValues = !delegate.isEmpty(); + delegate.clear(); + return hadValues; + } + + // throws ClassCastException if value is not of Integer + public int getInt(String key) { + Object value = delegate.get(key); + if (value != null) + return ((Integer) value).intValue(); + return 0; + } + + public boolean setInt(String key, int value) { + if (value == 0) + return delete(key); + return set(key, Integer.valueOf(value)); + } + + public boolean increaseInt(String key, int delta) { + int value = getInt(key); + return setInt(key, value + delta); + } + + public boolean decreaseInt(String key, int delta) { + int value = getInt(key); + return setInt(key, value - delta); + } + + public long getLong(String key) { + Object value = delegate.get(key); + if (value != null) + return ((Long) value).longValue(); + return 0; + } + + public boolean setLong(String key, long value) { + if (value == 0) + return delete(key); + return set(key, Long.valueOf(value)); + } + + public boolean increaseLong(String key, long delta) { + long value = getLong(key); + return setLong(key, value + delta); + } + + public boolean decreaseLong(String key, long delta) { + long value = getLong(key); + return setLong(key, value - delta); + } + + // throws ClassCastException if value is not of String + public String getString(String key) { + return (String) delegate.get(key); + } + + public boolean setString(String key, String value) { + if (value == null) + return delete(key); + return set(key, value); + } + + // throws ClassCastException if value is not of Set + @SuppressWarnings("unchecked") + public Set getSet(String key) { + Object value = delegate.get(key); + if (value != null) + return (Set) value; + return Collections.emptySet(); + } + + @SuppressWarnings("unchecked") + public boolean addToSet(String key, Object object) { + boolean changed = false; + @SuppressWarnings("unchecked") + Set set = (Set) delegate.get(key); + if (set == null) { + set = new HashSet(); + delegate.put(key, set); + changed = true; + } + changed |= set.add(object); + return changed; + } + + public boolean removeFromSet(String key, Object object) { + boolean changed = false; + @SuppressWarnings("unchecked") + Set set = (Set) delegate.get(key); + if (set != null) { + changed |= set.remove(object); + if (set.isEmpty()) { + delegate.remove(key); + changed = true; + } + } + return changed; + } + + public int sizeOfSet(String key) { + Set set = (Set) delegate.get(key); + return set == null ? 0 : set.size(); + } + + public boolean containsInSet(String key, Object object) { + Set set = (Set) delegate.get(key); + return set != null && set.contains(object); + } + + public boolean contains(String key) { + return delegate.containsKey(key); + } + + public Collection keys() { + return delegate.keySet(); + } + + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @SuppressWarnings("unchecked") + public WorkbookMetadata copy() { + WorkbookMetadata that = new WorkbookMetadata(); + for (String key : keys()) { + Object value = get(key); + if (value instanceof Set) { + value = new HashSet((Set) value); + } + that.set(key, value); + } + return that; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookMetadata)) + return false; + WorkbookMetadata that = (WorkbookMetadata) obj; + return this.delegate.equals(that.delegate); + } + + @Override + public int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public String toString() { + return this.delegate.toString(); + } + + } + + private static final String METADATA_AUTHOR_EMAIL = "author.email"; //$NON-NLS-1$ + private static final String METADATA_AUTHOR_NAME = "author.name"; //$NON-NLS-1$ + private static final String METADATA_AUTHOR_ORG = "author.org"; //$NON-NLS-1$ + + private static final String METADATA_ESTIMATED_SIZE = "estimatedSize"; //$NON-NLS-1$ + private static final String METADATA_TOPIC_COUNT = "topicCount"; //$NON-NLS-1$ + private static final String METADATA_WORD_COUNT = "wordCount"; //$NON-NLS-1$ + private static final String METADATA_REVISION_COUNT = "revisionCount"; //$NON-NLS-1$ + private static final String METADATA_MODIFICATION_TIME = "modificationTime"; //$NON-NLS-1$ + private static final String METADATA_MODIFIER_NAME = "modifierName"; //$NON-NLS-1$ + private static final String METADATA_CREATION_TIME = "creationTime"; //$NON-NLS-1$ + + private static final String METADATA_ATTACHMENTS = "attachments"; //$NON-NLS-1$ + private static final String METADATA_EXTERNAL_FILES = "externalFiles"; //$NON-NLS-1$ + private static final String METADATA_HYPERLINKS = "hyperlinks"; //$NON-NLS-1$ + private static final String METADATA_IMAGES = "images"; //$NON-NLS-1$ + + private static abstract class AbstractWorkbookMetadataPart + implements IWorkbookMetadataPart { + + private ListenerList listeners = new ListenerList(); + + private Control focusControl = null; + +// private Listener focusControlUpdater = new Listener() { +// public void handleEvent(Event event) { +// focusControl = (Control) event.widget; +// firePropertyChange(PROP_FOCUS_CONTROL); +// } +// }; + + private boolean refreshScheduled = false; + + protected final WorkbookMetadata metadata = new WorkbookMetadata(); + + public boolean isVisible() { + return !metadata.isEmpty(); + } + + public void addPropertyListener(IPropertyListener listener) { + listeners.add(listener); + } + + public void removePropertyListener(IPropertyListener listener) { + listeners.remove(listener); + } + + public Control getFocusControl() { + return focusControl; + } + + protected void firePropertyChange(final int propId) { + final Object source = this; + for (final Object listener : listeners.getListeners()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + ((IPropertyListener) listener).propertyChanged(source, + propId); + } + }); + } + } + + protected void updateText(Text control, String text) { + if (control == null || control.isDisposed()) + return; + + if (text == null) + text = ""; //$NON-NLS-1$ + if (text.equals(control.getText())) + return; + + Point selection = new Point(text.length(), text.length()); + if (control.isFocusControl()) { + selection.x = Math.min(selection.x, control.getSelection().x); + selection.y = Math.min(selection.y, control.getSelection().y); + } + control.setText(text); + if (control.isFocusControl()) { + control.setSelection(selection); + } + firePropertyChange(PROP_CONTROL); + } + + protected abstract void refreshControls(); + + protected void refreshAsynchronously() { + if (refreshScheduled) + return; + + Display display = Display.getCurrent(); + if (display == null) + return; + + display.asyncExec(new Runnable() { + public void run() { + refreshScheduled = false; + refreshControls(); + } + }); + refreshScheduled = true; + } + + } + + private static class WorkbookMetadataListRow extends Composite { + + private ImageLabel imageLabel; + + private Label textLabel; + + private boolean selected; + + private Color background; + + private Listener listener = new Listener() { + public void handleEvent(Event event) { + if (event.type == SWT.MouseDown) { + getParent().setFocus(); + handleMouseDown(event); + } else if (event.type == SWT.MouseDoubleClick) { + handleMouseDoubleClick(event); + } + } + }; + + public WorkbookMetadataListRow(Composite parent, + WidgetFactory factory) { + super(parent, SWT.NO_FOCUS); + selected = false; + background = super.getBackground(); + factory.adapt(this, true, true); + setMenu(parent.getMenu()); + + hookControl(this); + + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 2; + layout.marginHeight = 1; + layout.horizontalSpacing = 2; + layout.verticalSpacing = 0; + setLayout(layout); + + imageLabel = new ImageLabel(this, SWT.NO_FOCUS); + factory.adapt(imageLabel, true, true); + imageLabel.setScaleHint(ImageLabel.SCALE_TO_FIT); + imageLabel.setHorizontalAlignment(SWT.CENTER); + imageLabel.setVerticalAlignment(SWT.CENTER); + GridData imageLayoutData = new GridData(SWT.CENTER, SWT.CENTER, + false, true); + imageLayoutData.exclude = true; + imageLabel.setLayoutData(imageLayoutData); + imageLabel.setVisible(false); + imageLabel.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); + imageLabel.setMenu(getMenu()); + hookControl(imageLabel); + + textLabel = factory.createLabel(this, "", SWT.NO_FOCUS); //$NON-NLS-1$ + textLabel.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, true, true)); + textLabel.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); + textLabel.setMenu(getMenu()); + hookControl(textLabel); + } + + public void setImageSizeHint(Point hint) { + GridData layoutData = (GridData) imageLabel.getLayoutData(); + layoutData.widthHint = hint.x; + layoutData.heightHint = hint.y; + layout(true); + } + + private void hookControl(Control c) { + c.addListener(SWT.MouseDown, listener); + c.addListener(SWT.MouseDoubleClick, listener); + } + + public void setImage(Image image) { + checkWidget(); + imageLabel.setImage(image); + boolean visible = image != null; + imageLabel.setVisible(visible); + ((GridData) imageLabel.getLayoutData()).exclude = !visible; + layout(true); + } + + public void setText(String text) { + checkWidget(); + textLabel.setText(text); + layout(true); + } + + public boolean getSelection() { + return selected; + } + + public void setSelection(boolean selection) { + checkWidget(); + if (selection == this.selected) + return; + + this.selected = selection; + updateBackground(); + } + + @Override + public Color getBackground() { + return background; + } + + @Override + public void setBackground(Color color) { + checkWidget(); + this.background = color; + updateBackground(); + } + + private void updateBackground() { + if (getSelection()) { + super.setBackground( + getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION)); + } else { + super.setBackground(background); + } + } + + private void handleMouseDown(Event event) { + Control[] siblings = getParent().getChildren(); + for (int i = 0; i < siblings.length; i++) { + Control item = siblings[i]; + if (item instanceof WorkbookMetadataListRow) { + ((WorkbookMetadataListRow) item).setSelection(false); + } + } + setSelection(true); + getParent().notifyListeners(SWT.Selection, new Event()); + } + + private void handleMouseDoubleClick(Event event) { + getParent().notifyListeners(SWT.DefaultSelection, new Event()); + } + + } + + private static class WorkbookMetadataListLabelProvider extends LabelProvider + implements IListRenderer { + + private StraightListLayout layout = new StraightListLayout( + SWT.VERTICAL); + + public IListLayout getListLayout(MListViewer viewer) { + return layout; + } + + public Control createListItemForElement(MListViewer viewer, + Composite parent, Object element) { + WidgetFactory factory = (WidgetFactory) viewer.getControl() + .getData(KEY_WIDGET_FACTORY); + WorkbookMetadataListRow row = new WorkbookMetadataListRow(parent, + factory); + return row; + } + + public void updateListItem(MListViewer viewer, Object element, + Control item) { + WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; + row.setText(getText(element)); + row.setImage(getImage(element)); + } + + public int getListItemState(MListViewer viewer, Control item) { + int state = STATE_NONE; + if (item instanceof WorkbookMetadataListRow) { + WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; + if (row.getSelection()) { + state |= STATE_SELECTED; + } + } + return state; + } + + public void setListItemState(MListViewer viewer, Control item, + int state) { + if (item instanceof WorkbookMetadataListRow) { + WorkbookMetadataListRow row = (WorkbookMetadataListRow) item; + row.setSelection((state & STATE_SELECTED) != 0); + } + } + + } + + private static abstract class AbstractWorkbookMetadataListPart + extends AbstractWorkbookMetadataPart implements IAdaptable { + + private MListViewer viewer; + + protected abstract Object[] getElements(WorkbookMetadata metadata); + + protected abstract String getText(Object element); + + protected abstract Image getImage(Object element, + ResourceManager resourceManager); + + protected Point getImageSizeHint() { + return new Point(SWT.DEFAULT, SWT.DEFAULT); + } + + protected void update(Object element) { + viewer.update(element, null); + firePropertyChange(PROP_CONTROL); + } + + protected MListViewer getViewer() { + return viewer; + } + + public void createControl(final Composite parent) { + WidgetFactory factory = (WidgetFactory) parent + .getData(KEY_WIDGET_FACTORY); + + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 2; + layout.marginHeight = 2; + layout.horizontalSpacing = 3; + layout.verticalSpacing = 3; + parent.setLayout(layout); + + viewer = new MListViewer(parent, SWT.NONE); + factory.adapt(viewer.getControl(), true, true); + viewer.getControl().setMenu(parent.getMenu()); + viewer.getControl().setData(KEY_WIDGET_FACTORY, factory); + viewer.getControl().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); +// hookFocusableControl(viewer.getControl()); + + viewer.setContentProvider(createContentProvider()); + viewer.setLabelProvider(createLabelProvider()); + + viewer.setInput(metadata); + + viewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + firePropertyChange(PROP_OUTGOING_SELECTION); + } + }); + + final ScrolledComposite scrolledComposite = FormUtil + .getScrolledComposite(parent); + if (scrolledComposite != null) { + viewer.getControl().addListener(SWT.FocusOut, new Listener() { + public void handleEvent(Event event) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + Display display = Display.getCurrent(); + if (display == null || display.isDisposed() + || scrolledComposite.isDisposed()) + return; + + Control focusControl = display + .getFocusControl(); + if (containsControl(scrolledComposite, + focusControl) + && !containsControl(parent, + focusControl)) { + viewer.setSelection( + StructuredSelection.EMPTY); + } + } + }); + } + + private boolean containsControl(Composite composite, + Control c) { + while (c != null) { + if (c == composite) + return true; + c = c.getParent(); + } + return false; + } + }); + } + } + + @Override + protected void refreshControls() { + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + viewer.refresh(); + firePropertyChange(PROP_CONTROL); + } + + protected IContentProvider createContentProvider() { + return new IStructuredContentProvider() { + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public void dispose() { + } + + public Object[] getElements(Object inputElement) { + WorkbookMetadata metadata = (WorkbookMetadata) inputElement; + return AbstractWorkbookMetadataListPart.this + .getElements(metadata); + } + }; + } + + private IBaseLabelProvider createLabelProvider() { + return new WorkbookMetadataListLabelProvider() { + + ResourceManager rm = new LocalResourceManager( + JFaceResources.getResources()); + + @Override + public String getText(Object element) { + return AbstractWorkbookMetadataListPart.this + .getText(element); + } + + @Override + public Image getImage(Object element) { + return AbstractWorkbookMetadataListPart.this + .getImage(element, rm); + } + + @Override + public Control createListItemForElement(MListViewer viewer, + Composite parent, Object element) { + Control item = super.createListItemForElement(viewer, + parent, element); + if (item instanceof WorkbookMetadataListRow) { + ((WorkbookMetadataListRow) item) + .setImageSizeHint(getImageSizeHint()); + } + return item; + } + + @Override + public void dispose() { + super.dispose(); + rm.dispose(); + } + }; + } + + public T getAdapter(Class adapter) { + if (adapter == ISelectionProvider.class) + return adapter.cast(viewer); + return null; + } + + } + + private static class TopicViewerComparator extends ViewerComparator { + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + return Core.getTopicComparator().compare((ITopic) e1, (ITopic) e2); + } + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// Author Info Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private class AuthorInfoPart extends AbstractWorkbookMetadataPart + implements IModifiableWorkbookMetadataPart { + + private Text nameInput; + private Text emailInput; + private Text orgInput; + + private Listener modifyListener = new Listener() { + public void handleEvent(Event event) { + firePropertyChange(PROP_CONTENT); + } + }; + + public boolean isVisible() { + return true; + } + + public String getTitle() { + return Messages.AuthorInfoInspectorSection_title; + } + + public void createControl(Composite parent) { + WidgetFactory factory = (WidgetFactory) parent + .getData(KEY_WIDGET_FACTORY); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 2; + layout.marginHeight = 2; + layout.horizontalSpacing = 5; + layout.verticalSpacing = 3; + layout.numColumns = 2; + parent.setLayout(layout); + + createLabel(parent, factory, + Messages.AuthorInfoInspectorSection_Name); + nameInput = createText(parent, factory); + + createLabel(parent, factory, + Messages.AuthorInfoInspectorSection_Email); + emailInput = createText(parent, factory); + + createLabel(parent, factory, + Messages.AuthorInfoInspectorSection_Organization); + orgInput = createText(parent, factory); + } + + private Label createLabel(Composite parent, WidgetFactory factory, + String text) { + Label label = factory.createLabel(parent, text); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + return label; + } + + private Text createText(Composite parent, WidgetFactory factory) { + Text text = factory.createText(parent, "", SWT.SINGLE); //$NON-NLS-1$ + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + text.addListener(SWT.DefaultSelection, modifyListener); + text.addListener(SWT.FocusOut, modifyListener); + return text; + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + boolean changed = false; + if (workbook == null) { + changed |= metadata.setString(METADATA_AUTHOR_NAME, ""); //$NON-NLS-1$ + changed |= metadata.setString(METADATA_AUTHOR_EMAIL, ""); //$NON-NLS-1$ + changed |= metadata.setString(METADATA_AUTHOR_ORG, ""); //$NON-NLS-1$ + } else if (event == null) { + IMeta meta = workbook.getMeta(); + changed |= metadata.setString(METADATA_AUTHOR_NAME, + meta.getValue(IMeta.AUTHOR_NAME)); + changed |= metadata.setString(METADATA_AUTHOR_EMAIL, + meta.getValue(IMeta.AUTHOR_EMAIL)); + changed |= metadata.setString(METADATA_AUTHOR_ORG, + meta.getValue(IMeta.AUTHOR_ORG)); + } else if (Core.Metadata.equals(event.getType())) { + if (IMeta.AUTHOR_NAME.equals(event.getTarget())) { + changed |= metadata.setString(METADATA_AUTHOR_NAME, + (String) event.getNewValue()); + } else if (IMeta.AUTHOR_EMAIL.equals(event.getTarget())) { + changed |= metadata.setString(METADATA_AUTHOR_EMAIL, + (String) event.getNewValue()); + } else if (IMeta.AUTHOR_ORG.equals(event.getTarget())) { + changed |= metadata.setString(METADATA_AUTHOR_ORG, + (String) event.getNewValue()); + } + } + + if (changed) { + refreshAsynchronously(); + } + } + + @Override + protected void refreshControls() { + String name = metadata.getString(METADATA_AUTHOR_NAME); + if (name == null || "".equals(name)) //$NON-NLS-1$ + name = System.getProperty("user.name"); //$NON-NLS-1$ + updateText(nameInput, name); + updateText(emailInput, metadata.getString(METADATA_AUTHOR_EMAIL)); + updateText(orgInput, metadata.getString(METADATA_AUTHOR_ORG)); + } + + public Command createModificationCommand(IWorkbook workbook) { + String newName = nameInput.getText(); + String newEmail = emailInput.getText(); + String newOrg = orgInput.getText(); + Command command = new CompoundCommand( // + new ModifyMetadataCommand(workbook, IMeta.AUTHOR_NAME, + newName), // + new ModifyMetadataCommand(workbook, IMeta.AUTHOR_EMAIL, + newEmail), // + new ModifyMetadataCommand(workbook, IMeta.AUTHOR_ORG, + newOrg) // + ); + if (!command.canExecute()) + return null; + + command.setLabel(MindMapMessages.WorkbookMetadata_ModifyAuthorInfo); + return command; + } + + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// Summary Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private static final int PRIMARY_BYTES = 5300; + private static final int TOPIC_DEFAULT_BYTES = 160; + + private static class WorkbookSummaryPart + extends AbstractWorkbookMetadataPart { + + private Text estimatedSizeText; + private Text topicCountText; + private Text wordCountText; + private Text revisionCountText; + private Text modificationTimeText; + private Text modifierNameText; + private Text creationTimeText; + + public boolean isVisible() { + return true; + } + + public String getTitle() { + return Messages.FileInfoInspectorSection_title; + } + + public void createControl(Composite parent) { + WidgetFactory factory = (WidgetFactory) parent + .getData(KEY_WIDGET_FACTORY); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 2; + layout.marginHeight = 2; + layout.horizontalSpacing = 5; + layout.verticalSpacing = 3; + layout.numColumns = 2; + parent.setLayout(layout); + + estimatedSizeText = createTextWithLabel(parent, factory, + Messages.FileInfoEstimateSize_label); + + topicCountText = createTextWithLabel(parent, factory, + Messages.FileInfoTopics_label); + + wordCountText = createTextWithLabel(parent, factory, + Messages.FileInfoWords_label); + + revisionCountText = createTextWithLabel(parent, factory, + Messages.FileInfoRevisions_label); + + modificationTimeText = createTextWithLabel(parent, factory, + Messages.FileInfoModifiedTime_label); + + modifierNameText = createTextWithLabel(parent, factory, + Messages.FileInfoModifiedBy_label); + + creationTimeText = createTextWithLabel(parent, factory, + Messages.FileInfoCreatedTime_label); + } + + private Text createTextWithLabel(Composite parent, + WidgetFactory factory, String labelText) { + Label label = factory.createLabel(parent, labelText); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + + Text text = new Text(parent, + SWT.READ_ONLY | SWT.SINGLE | factory.getOrientation()); + factory.adapt(text, true, false); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + WorkbookMetadata oldMetadata = metadata.copy(); + + if (workbook == null) { + metadata.deleteAll(); + } else if (event == null) { + workbookChanged(workbook); + } else if (Core.SheetAdd.equals(event.getType())) { + sheetAdded((ISheet) event.getTarget()); + } else if (Core.SheetRemove.equals(event.getType())) { + sheetRemoved((ISheet) event.getTarget()); + } else if (Core.TopicAdd.equals(event.getType())) { + topicAdded((ITopic) event.getTarget()); + } else if (Core.TopicRemove.equals(event.getType())) { + topicRemoved((ITopic) event.getTarget()); + } else if (Core.TitleText.equals(event.getType())) { + titleTextChanged((String) event.getOldValue(), + (String) event.getNewValue()); + } else if (Core.TopicNotes.equals(event.getType())) { + if (INotes.PLAIN.equals(event.getTarget())) { + notesChanged((INotesContent) event.getOldValue(), + (INotesContent) event.getNewValue()); + } + } else if (Core.FileEntryAdd.equals(event.getType())) { + fileEntryAdded((IFileEntry) event.getTarget()); + } else if (Core.FileEntryRemove.equals(event.getType())) { + fileEntryRemoved((IFileEntry) event.getTarget()); + } else if (Core.RelationshipAdd.equals(event.getType())) { + relationshipAdded((IRelationship) event.getTarget()); + } else if (Core.RelationshipRemove.equals(event.getType())) { + relationshipRemoved((IRelationship) event.getTarget()); + } else if (Core.BoundaryAdd.equals(event.getType())) { + boundaryAdded((IBoundary) event.getTarget()); + } else if (Core.BoundaryRemove.equals(event.getType())) { + boundaryRemoved((IBoundary) event.getTarget()); + } else if (Core.RevisionAdd.equals(event.getType())) { + metadata.increaseInt(METADATA_REVISION_COUNT, 1); + } else if (Core.RevisionRemove.equals(event.getType())) { + metadata.decreaseInt(METADATA_REVISION_COUNT, 1); + } else if (Core.ModifyTime.equals(event.getType()) + || Core.WorkbookSave.equals(event.getType())) { + IModifiable source = (IModifiable) event.getSource(); + metadata.setLong(METADATA_MODIFICATION_TIME, + source.getModifiedTime()); + metadata.setString(METADATA_MODIFIER_NAME, + source.getModifiedBy()); + } + + if (!metadata.equals(oldMetadata)) { + refreshAsynchronously(); + } + } + + @Override + protected void refreshControls() { + updateText(topicCountText, + String.valueOf(metadata.getInt(METADATA_TOPIC_COUNT))); + updateText(wordCountText, + String.valueOf(metadata.getInt(METADATA_WORD_COUNT))); + updateText(estimatedSizeText, FileUtils.fileLengthToString( + metadata.getLong(METADATA_ESTIMATED_SIZE))); + updateText(revisionCountText, + String.valueOf(metadata.getInt(METADATA_REVISION_COUNT))); + updateText(modificationTimeText, NumberUtils + .formatDate(metadata.getLong(METADATA_MODIFICATION_TIME))); + updateText(modifierNameText, + metadata.getString(METADATA_MODIFIER_NAME)); + updateText(creationTimeText, + metadata.getString(METADATA_CREATION_TIME)); + } + + private void workbookChanged(IWorkbook workbook) { + metadata.deleteAll(); + + metadata.setLong(METADATA_MODIFICATION_TIME, + workbook.getModifiedTime()); + String name = workbook.getModifiedBy(); + if (name == null || "".equals(name)) //$NON-NLS-1$ + name = System.getProperty("user.name"); //$NON-NLS-1$ + metadata.setString(METADATA_MODIFIER_NAME, name); + metadata.setString(METADATA_CREATION_TIME, + workbook.getMeta().getValue(IMeta.CREATED_TIME)); + + metadata.setLong(METADATA_ESTIMATED_SIZE, PRIMARY_BYTES); + + for (ISheet sheet : workbook.getSheets()) { + sheetAdded(sheet); + } + Iterator entryIter = workbook.getManifest() + .iterFileEntries(); + while (entryIter.hasNext()) { + fileEntryAdded(entryIter.next()); + } + } + + private void sheetAdded(ISheet sheet) { + titleTextChanged(null, sheet.getTitleText()); + topicAdded(sheet.getRootTopic()); + metadata.increaseInt(METADATA_REVISION_COUNT, + sheet.getOwnedWorkbook().getRevisionRepository() + .getRevisionManager(sheet.getId(), IRevision.SHEET) + .getRevisions().size()); + for (IRelationship r : sheet.getRelationships()) { + relationshipAdded(r); + } + } + + private void sheetRemoved(ISheet sheet) { + for (IRelationship r : sheet.getRelationships()) { + relationshipRemoved(r); + } + + metadata.decreaseInt(METADATA_REVISION_COUNT, + sheet.getOwnedWorkbook().getRevisionRepository() + .getRevisionManager(sheet.getId(), IRevision.SHEET) + .getRevisions().size()); + topicRemoved(sheet.getRootTopic()); + titleTextChanged(sheet.getTitleText(), null); + } + + private void topicAdded(ITopic topic) { + metadata.increaseInt(METADATA_TOPIC_COUNT, 1); + + metadata.increaseLong(METADATA_ESTIMATED_SIZE, TOPIC_DEFAULT_BYTES); + + titleTextChanged(null, topic.getTitleText()); + notesChanged(null, topic.getNotes().getContent(INotes.PLAIN)); + + Iterator childIter = topic.getAllChildrenIterator(); + while (childIter.hasNext()) { + topicAdded(childIter.next()); + } + + for (IBoundary boundary : topic.getBoundaries()) { + boundaryAdded(boundary); + } + } + + private void topicRemoved(ITopic topic) { + for (IBoundary boundary : topic.getBoundaries()) { + boundaryRemoved(boundary); + } + + Iterator childIter = topic.getAllChildrenIterator(); + while (childIter.hasNext()) { + topicRemoved(childIter.next()); + } + + notesChanged(topic.getNotes().getContent(INotes.PLAIN), null); + titleTextChanged(topic.getTitleText(), null); + + metadata.decreaseLong(METADATA_ESTIMATED_SIZE, TOPIC_DEFAULT_BYTES); + + metadata.decreaseInt(METADATA_TOPIC_COUNT, 1); + } + + private void titleTextChanged(String oldTitle, String newTitle) { + if (oldTitle != null) { + metadata.decreaseLong(METADATA_ESTIMATED_SIZE, + oldTitle.length()); + metadata.decreaseInt(METADATA_WORD_COUNT, countWords(oldTitle)); + } + if (newTitle != null) { + metadata.increaseLong(METADATA_ESTIMATED_SIZE, + newTitle.length()); + metadata.increaseInt(METADATA_WORD_COUNT, countWords(newTitle)); + } + } + + private void notesChanged(INotesContent oldNotes, + INotesContent newNotes) { + if (oldNotes instanceof IPlainNotesContent) { + String content = ((IPlainNotesContent) oldNotes) + .getTextContent(); + if (content != null) { + metadata.decreaseInt(METADATA_WORD_COUNT, + countWords(content)); + } + } + + if (newNotes instanceof IPlainNotesContent) { + String content = ((IPlainNotesContent) newNotes) + .getTextContent(); + if (content != null) { + metadata.increaseInt(METADATA_WORD_COUNT, + countWords(content)); + } + } + } + + private void fileEntryAdded(IFileEntry entry) { + metadata.increaseLong(METADATA_ESTIMATED_SIZE, entry.getSize()); + } + + private void fileEntryRemoved(IFileEntry entry) { + metadata.decreaseLong(METADATA_ESTIMATED_SIZE, entry.getSize()); + } + + private void relationshipAdded(IRelationship r) { + titleTextChanged(null, r.getTitleText()); + } + + private void relationshipRemoved(IRelationship r) { + titleTextChanged(r.getTitleText(), null); + } + + private void boundaryAdded(IBoundary b) { + titleTextChanged(null, b.getTitleText()); + } + + private void boundaryRemoved(IBoundary b) { + titleTextChanged(b.getTitleText(), null); + } + + private static int countWords(String s) { + int total = s.length(); + int count = 0; + boolean inWord = false; + char c; + for (int i = 0; i < total; i++) { + c = s.charAt(i); + if (isOneWordCharacter(c)) { + if (inWord) + count++; + count++; + inWord = false; + } else if (Character.isLetter(c) || Character.isDigit(c)) { + inWord = true; + } else { + if (inWord) + count++; + inWord = false; + } + } + if (inWord) + count++; + return count; + } + + private static boolean isOneWordCharacter(char c) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { + return true; + } + return false; + } + + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// Attachments Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private static class AttachmentListPart + extends AbstractWorkbookMetadataListPart { + + public String getTitle() { + return NLS.bind(Messages.AttachmentsInspectorSection_title, + metadata.sizeOfSet(METADATA_ATTACHMENTS)); + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + WorkbookMetadata oldMetadata = metadata.copy(); + Object toUpdate = null; + + if (workbook == null) { + metadata.deleteAll(); + } else if (event == null) { + metadata.deleteAll(); + for (ISheet sheet : workbook.getSheets()) { + topicAdded(sheet.getRootTopic()); + } + } else if (Core.TopicAdd.equals(event.getType())) { + topicAdded((ITopic) event.getTarget()); + } else if (Core.TopicRemove.equals(event.getType())) { + topicRemoved((ITopic) event.getTarget()); + } else if (Core.SheetAdd.equals(event.getType())) { + topicAdded(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.SheetRemove.equals(event.getType())) { + topicRemoved(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.TopicHyperlink.equals(event.getType())) { + ITopic source = (ITopic) event.getSource(); + linkChanged(source, (String) event.getOldValue(), + (String) event.getNewValue()); + if (metadata.containsInSet(METADATA_ATTACHMENTS, source)) { + toUpdate = source; + } + } else if (Core.TitleText.equals(event.getType())) { + Object source = event.getSource(); + if (metadata.containsInSet(METADATA_ATTACHMENTS, source)) { + toUpdate = source; + } + } + + if (!metadata.equals(oldMetadata)) { + refreshAsynchronously(); + } else if (toUpdate != null) { + update(toUpdate); + } + } + + private void topicAdded(ITopic topic) { + linkChanged(topic, null, topic.getHyperlink()); + + Iterator childIter = topic.getAllChildrenIterator(); + while (childIter.hasNext()) { + topicAdded(childIter.next()); + } + } + + private void topicRemoved(ITopic topic) { + Iterator childIter = topic.getAllChildrenIterator(); + while (childIter.hasNext()) { + topicRemoved(childIter.next()); + } + + linkChanged(topic, topic.getHyperlink(), null); + } + + private void linkChanged(ITopic topic, String oldLink, String newLink) { + IFileEntry oldEntry = findFileEntry(topic, oldLink); + if (oldEntry != null) { + metadata.removeFromSet(METADATA_ATTACHMENTS, topic); + } + + IFileEntry newEntry = findFileEntry(topic, newLink); + if (newEntry != null) { + metadata.addToSet(METADATA_ATTACHMENTS, topic); + } + } + + private IFileEntry findFileEntry(ITopic topic, String link) { + if (link == null || !HyperlinkUtils.isAttachmentURL(link)) + return null; + + IManifest manifest = topic.getOwnedWorkbook().getManifest(); + if (manifest == null) + return null; + + return manifest.getFileEntry(HyperlinkUtils.toAttachmentPath(link)); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + getViewer().setComparator(new TopicViewerComparator()); + } + + @Override + protected Object[] getElements(WorkbookMetadata metadata) { + return metadata.getSet(METADATA_ATTACHMENTS).toArray(); + } + + @Override + protected String getText(Object element) { + if (!(element instanceof ITopic)) + return ""; //$NON-NLS-1$ + + ITopic topic = (ITopic) element; + String fileName = topic.getTitleText(); + IFileEntry entry = findFileEntry(topic, topic.getHyperlink()); + if (entry == null) + return fileName; + + long size = entry.getSize(); + return String.format("%s (%s)", fileName, //$NON-NLS-1$ + FileUtils.fileLengthToString(size)); + } + + @Override + protected Image getImage(Object element, + ResourceManager resourceManager) { + if (!(element instanceof ITopic)) + return null; + + ITopic topic = (ITopic) element; + String fileName = topic.getTitleText(); + ImageDescriptor icon = MindMapUI.getImages().getFileIcon(fileName, + true); + if (icon == null) { + icon = MindMapUI.getImages().get(IMindMapImages.UNKNOWN_FILE, + true); + } + return (Image) resourceManager.get(icon); + } + + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// External Files Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private static class ExternalFileListPart + extends AbstractWorkbookMetadataListPart { + + public String getTitle() { + return NLS.bind(Messages.ExternalFilesInspectorSection_title, + metadata.sizeOfSet(METADATA_EXTERNAL_FILES)); + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + WorkbookMetadata oldMetadata = this.metadata.copy(); + Object toUpdate = null; + + if (workbook == null) { + metadata.deleteAll(); + } else if (event == null) { + metadata.deleteAll(); + workbookChanged(workbook); + } else if (Core.SheetAdd.equals(event.getType())) { + topicAdded(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.SheetRemove.equals(event.getType())) { + topicRemoved(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.TopicAdd.equals(event.getType())) { + topicAdded((ITopic) event.getTarget()); + } else if (Core.TopicRemove.equals(event.getType())) { + topicRemoved((ITopic) event.getTarget()); + } else if (Core.TopicHyperlink.equals(event.getType())) { + ITopic source = (ITopic) event.getSource(); + linkChanged(source, (String) event.getOldValue(), + (String) event.getNewValue()); + if (metadata.containsInSet(METADATA_EXTERNAL_FILES, source)) { + toUpdate = source; + } + } else if (Core.TitleText.equals(event.getType())) { + Object source = event.getSource(); + if (metadata.containsInSet(METADATA_EXTERNAL_FILES, source)) { + toUpdate = source; + } + } + + if (!metadata.equals(oldMetadata)) { + refreshAsynchronously(); + } else if (toUpdate != null) { + update(toUpdate); + } + + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + getViewer().setComparator(new TopicViewerComparator()); + } + + @Override + protected Object[] getElements(WorkbookMetadata metadata) { + return metadata.getSet(METADATA_EXTERNAL_FILES).toArray(); + } + + @Override + protected Image getImage(Object element, + ResourceManager resourceManager) { + if (!(element instanceof ITopic)) + return null; + + ITopic topic = (ITopic) element; + File file = getFile(topic.getHyperlink()); + if (file == null) + return null; + + ImageDescriptor icon = MindMapUI.getImages() + .getFileIcon(file.getAbsolutePath(), true); + if (icon == null) { + icon = MindMapUI.getImages().get(IMindMapImages.UNKNOWN_FILE, + true); + } + return (Image) resourceManager.get(icon); + } + + @Override + protected String getText(Object element) { + if (!(element instanceof ITopic)) + return ""; //$NON-NLS-1$ + + ITopic topic = (ITopic) element; + File file = getFile(topic.getHyperlink()); + if (file == null) + return ""; //$NON-NLS-1$ + + return file.getName(); + } + + private void workbookChanged(IWorkbook workbook) { + for (ISheet sheet : workbook.getSheets()) { + topicAdded(sheet.getRootTopic()); + } + } + + private void topicAdded(ITopic topic) { + linkChanged(topic, null, topic.getHyperlink()); + + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicAdded(childrenIterator.next()); + } + } + + private void topicRemoved(ITopic topic) { + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicRemoved(childrenIterator.next()); + } + + linkChanged(topic, topic.getHyperlink(), null); + } + + private void linkChanged(ITopic topic, String oldLink, String newLink) { + File oldFile = getFile(oldLink); + if (oldFile != null) { + metadata.removeFromSet(METADATA_EXTERNAL_FILES, topic); + } + + File newFile = getFile(newLink); + if (newFile != null) { + metadata.addToSet(METADATA_EXTERNAL_FILES, topic); + } + } + + private File getFile(String link) { + if (!FilePathParser.isFileURI(link)) + return null; + return new File(FilePathParser.toPath(link)); + } + + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// Hyperlinks Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private static class HyperlinkListPart + extends AbstractWorkbookMetadataListPart { + + public String getTitle() { + return NLS.bind(Messages.HyperlinkInspectorSection_title, + metadata.sizeOfSet(METADATA_HYPERLINKS)); + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + WorkbookMetadata oldMetadata = this.metadata.copy(); + Object toUpdate = null; + + if (workbook == null) { + metadata.deleteAll(); + } else if (event == null) { + metadata.deleteAll(); + workbookChanged(workbook); + } else if (Core.SheetAdd.equals(event.getType())) { + topicAdded(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.SheetRemove.equals(event.getType())) { + topicRemoved(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.TopicAdd.equals(event.getType())) { + topicAdded((ITopic) event.getTarget()); + } else if (Core.TopicRemove.equals(event.getType())) { + topicRemoved((ITopic) event.getTarget()); + } else if (Core.TopicHyperlink.equals(event.getType())) { + ITopic source = (ITopic) event.getSource(); + linkChanged(source, (String) event.getOldValue(), + (String) event.getNewValue()); + if (metadata.containsInSet(METADATA_HYPERLINKS, source)) { + toUpdate = source; + } + } else if (Core.TitleText.equals(event.getType())) { + Object source = event.getSource(); + if (metadata.containsInSet(METADATA_HYPERLINKS, source)) { + toUpdate = source; + } + } + + if (!metadata.equals(oldMetadata)) { + refreshAsynchronously(); + } else if (toUpdate != null) { + update(toUpdate); + } + + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + getViewer().setComparator(new TopicViewerComparator()); + } + + @Override + protected Object[] getElements(WorkbookMetadata metadata) { + return metadata.getSet(METADATA_HYPERLINKS).toArray(); + } + + @Override + protected Image getImage(Object element, + ResourceManager resourceManager) { + return null; + } + + @Override + protected String getText(Object element) { + if (!(element instanceof ITopic)) + return ""; //$NON-NLS-1$ + + ITopic topic = (ITopic) element; + return topic.getHyperlink(); + } + + private void workbookChanged(IWorkbook workbook) { + for (ISheet sheet : workbook.getSheets()) { + topicAdded(sheet.getRootTopic()); + } + } + + private void topicAdded(ITopic topic) { + linkChanged(topic, null, topic.getHyperlink()); + + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicAdded(childrenIterator.next()); + } + } + + private void topicRemoved(ITopic topic) { + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicRemoved(childrenIterator.next()); + } + + linkChanged(topic, topic.getHyperlink(), null); + } + + private void linkChanged(ITopic topic, String oldLink, String newLink) { + if (isNormalHyperlink(oldLink)) { + metadata.removeFromSet(METADATA_HYPERLINKS, topic); + } + + if (isNormalHyperlink(newLink)) { + metadata.addToSet(METADATA_HYPERLINKS, topic); + } + } + + private boolean isNormalHyperlink(String link) { + return link != null && !HyperlinkUtils.isAttachmentURL(link) + && !HyperlinkUtils.isInternalURL(link) + && !FilePathParser.isFileURI(link); + } + + } + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + //// Images Section + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + private static class ImageListPart + extends AbstractWorkbookMetadataListPart { + + public String getTitle() { + return NLS.bind(Messages.ImageInspectorSection_title, + metadata.sizeOfSet(METADATA_IMAGES)); + } + + public void refresh(IWorkbook workbook, CoreEvent event) { + WorkbookMetadata oldMetadata = this.metadata.copy(); + Object toUpdate = null; + + if (workbook == null) { + metadata.deleteAll(); + } else if (event == null) { + metadata.deleteAll(); + workbookChanged(workbook); + } else if (Core.SheetAdd.equals(event.getType())) { + topicAdded(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.SheetRemove.equals(event.getTarget())) { + topicRemoved(((ISheet) event.getTarget()).getRootTopic()); + } else if (Core.TopicAdd.equals(event.getType())) { + topicAdded((ITopic) event.getTarget()); + } else if (Core.TopicRemove.equals(event.getType())) { + topicRemoved((ITopic) event.getTarget()); + } else if (Core.ImageSource.equals(event.getType())) { + ITopic source = ((IImage) event.getSource()).getParent(); + imageSourceChanged(source, (String) event.getOldValue(), + (String) event.getNewValue()); + if (metadata.containsInSet(METADATA_IMAGES, source)) { + toUpdate = source; + } + } else if (Core.TitleText.equals(event.getType())) { + Object source = event.getSource(); + if (metadata.containsInSet(METADATA_IMAGES, source)) { + toUpdate = source; + } + } + + if (!metadata.equals(oldMetadata)) { + refreshAsynchronously(); + } else if (toUpdate != null) { + update(toUpdate); + } + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + getViewer().setComparator(new TopicViewerComparator()); + } + + @Override + protected Object[] getElements(WorkbookMetadata metadata) { + return metadata.getSet(METADATA_IMAGES).toArray(); + } + + @Override + protected String getText(Object element) { + if (!(element instanceof ITopic)) + return ""; //$NON-NLS-1$ + + ITopic topic = (ITopic) element; + String imageURI = topic.getImage().getSource(); + if (HyperlinkUtils.isAttachmentURL(imageURI)) { + String path = HyperlinkUtils.toAttachmentPath(imageURI); + IFileEntry entry = topic.getOwnedWorkbook().getManifest() + .getFileEntry(path); + if (entry != null) { + return String.format("%s (%s)", topic.getTitleText(), //$NON-NLS-1$ + FileUtils.fileLengthToString(entry.getSize())); + } + } + return topic.getTitleText(); + } + + @Override + protected Image getImage(final Object element, + final ResourceManager resourceManager) { + if (!(element instanceof ITopic)) + return null; + + ITopic topic = (ITopic) element; + String imageURI = topic.getImage().getSource(); + if (HyperlinkUtils.isAttachmentURL(imageURI)) { + String path = HyperlinkUtils.toAttachmentPath(imageURI); + IWorkbook workbook = topic.getOwnedWorkbook(); + IFileEntry entry = workbook.getManifest().getFileEntry(path); + ImageDescriptor descriptor = AttachmentImageDescriptor + .createFromEntry(workbook, entry); + return (Image) resourceManager.get(descriptor); + } else if (FilePathParser.isFileURI(imageURI)) { + String path = FilePathParser.toPath(imageURI); + ImageDescriptor descriptor = ImageDescriptor + .createFromFile(null, path); + return (Image) resourceManager.get(descriptor); + } else { + ImageDescriptor descriptor = ImageDownloader.getInstance() + .getImage(imageURI); + if (descriptor != null) + return (Image) resourceManager.get(descriptor); + ImageDownloader.getInstance().register(imageURI, + new Runnable() { + public void run() { + if (getViewer() == null + || getViewer().getControl() == null + || getViewer().getControl() + .isDisposed()) + return; + + Display display = getViewer().getControl() + .getDisplay(); + if (display == null || display.isDisposed()) + return; + + display.asyncExec(new Runnable() { + public void run() { + update(element); + } + }); + } + }); + } + return null; + } + + @Override + protected Point getImageSizeHint() { + return new Point(32, 32); + } + + private void workbookChanged(IWorkbook workbook) { + for (ISheet sheet : workbook.getSheets()) { + topicAdded(sheet.getRootTopic()); + } + } + + private void topicAdded(ITopic topic) { + imageSourceChanged(topic, null, topic.getImage().getSource()); + + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicAdded(childrenIterator.next()); + } + } + + private void topicRemoved(ITopic topic) { + Iterator childrenIterator = topic.getAllChildrenIterator(); + while (childrenIterator.hasNext()) { + topicRemoved(childrenIterator.next()); + } + + imageSourceChanged(topic, topic.getImage().getSource(), null); + } + + private void imageSourceChanged(ITopic topic, String oldSrc, + String newSrc) { + if (oldSrc != null) { + metadata.removeFromSet(METADATA_IMAGES, topic); + } + if (newSrc != null) { + metadata.addToSet(METADATA_IMAGES, topic); + } + } + + } + + private ICoreEventListener coreEventHandler = new ICoreEventListener() { + public void handleCoreEvent(final CoreEvent event) { + Display display = getDisplay(); + if (display == null) + return; + + display.asyncExec(new Runnable() { + public void run() { + refreshParts(event); + } + }); + } + + private Display getDisplay() { + Display display = Display.getCurrent(); + if (display != null) + return display; + + Control control = getControl(); + if (control == null || control.isDisposed()) + return null; + + return control.getDisplay(); + } + }; + + private IPropertyListener propertyChangeHandler = new IPropertyListener() { + public void propertyChanged(Object source, int propId) { + if (source instanceof IWorkbookMetadataPart) { + if (propId == PROP_CONTROL) { + updateSection((IWorkbookMetadataPart) source); + scheduleReflow(); + } else if (propId == PROP_CONTENT) { + if (source instanceof IModifiableWorkbookMetadataPart) { + executeCommand( + ((IModifiableWorkbookMetadataPart) source) + .createModificationCommand(workbook)); + } + } else if (propId == PROP_OUTGOING_SELECTION) { + revealSelectionInEditor((IWorkbookMetadataPart) source); + } + } + } + }; + + private IPartListener partListenerHandler = new IPartListener() { + + public void partOpened(IWorkbenchPart part) { + } + + public void partDeactivated(IWorkbenchPart part) { + if (part == sourceEditor) { + + } + } + + public void partClosed(IWorkbenchPart part) { + if (part == sourceEditor) { + setSourceEditor(null); + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partActivated(IWorkbenchPart part) { + + if (part == sourceEditor || !(part instanceof IEditorPart)) + return; + + if (part instanceof IEditorPart) { + setSourceEditor((IEditorPart) part); + } + } + }; + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(DialogMessages.WorkbookMetaInspectorDialog_title); + newShell.setSize(500, 445); + newShell.setLocation( + Display.getCurrent().getClientArea().width / 2 + - newShell.getShell().getSize().x / 2, + Display.getCurrent().getClientArea().height / 2 + - newShell.getSize().y / 2); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 14; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createDescriptionArea(composite); + + Composite content = new Composite(composite, SWT.BORDER); + this.composite = content; + content.setLayoutData(new GridData(GridData.FILL_BOTH)); + StackLayout stack = new StackLayout(); + content.setLayout(stack); + + factory = new WidgetFactory(parent.getDisplay()); + factory.getHyperlinkGroup() + .setHyperlinkUnderlineMode(HyperlinkGroup.UNDERLINE_HOVER); + form = factory.createScrolledForm(content); + stack.topControl = form; + + final Composite body = form.getBody(); + + TableWrapLayout layout = new TableWrapLayout(); + layout.topMargin = 0; + layout.leftMargin = 0; + layout.rightMargin = 0; + layout.bottomMargin = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 3; + body.setLayout(layout); + createSections(body); + + form.getBody().addListener(SWT.MouseDown, new Listener() { + public void handleEvent(Event event) { + form.getBody().setFocus(); + } + }); + + form.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + + setWorkbook(sourceEditor == null ? null + : MindMapUIPlugin.getAdapter(sourceEditor, IWorkbook.class)); + return composite; + } + + @Override + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + // create a layout with spacing and margins appropriate for the font + // size. + GridLayout layout = new GridLayout(); + layout.numColumns = 0; // this is incremented by createButton + layout.makeColumnsEqualWidth = true; + layout.marginWidth = 13; + layout.marginHeight = 23; + layout.horizontalSpacing = 18; + layout.verticalSpacing = 0; + composite.setLayout(layout); + + GridData data = new GridData( + GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); + composite.setLayoutData(data); + composite.setFont(parent.getFont()); + + // Add the buttons to the button bar. + createButtonsForButtonBar(composite); + return composite; + } + + private void createDescriptionArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 21; + gridLayout.verticalSpacing = 0; + composite.setLayout(gridLayout); + + Label discriptionLabel = new Label(composite, SWT.WRAP); + GridData discriptionLabelData = new GridData(SWT.FILL, SWT.CENTER, true, + true); + discriptionLabel.setLayoutData(discriptionLabelData); + discriptionLabel.setAlignment(SWT.LEFT); + discriptionLabel + .setText(MindMapMessages.WorkbookMetaInspectorDialog_message); + } + + private void handleDispose() { + setWorkbook(null); + + for (IWorkbookMetadataPart part : parts) { + part.removePropertyListener(propertyChangeHandler); + } + parts.clear(); + sections.clear(); + + if (factory != null) { + factory.dispose(); + factory = null; + } + + form = null; + composite = null; + } + + private void setWorkbook(IWorkbook workbook) { + IWorkbook oldWorkbook = this.workbook; + if (workbook == oldWorkbook) + return; + + this.workbook = workbook; + workbookChanged(workbook, oldWorkbook); + } + + private void workbookChanged(IWorkbook workbook2, IWorkbook oldWorkbook) { + if (eventRegister != null) { + eventRegister.unregisterAll(); + } + + if (getControl() != null && !getControl().isDisposed()) { + for (IWorkbookMetadataPart part : parts) { + part.refresh(workbook, null); + } + scheduleReflow(); + } + + if (workbook != null) { + ICoreEventSupport support = (ICoreEventSupport) workbook + .getAdapter(ICoreEventSupport.class); + if (support != null) { + if (eventRegister == null) { + eventRegister = new CoreEventRegister(coreEventHandler); + } + eventRegister.setNextSupport(support); + registerCoreEventTypes(eventRegister); + } + } + } + + private void registerCoreEventTypes(CoreEventRegister register) { + register.register(Core.Metadata); + register.register(Core.SheetAdd); + register.register(Core.SheetRemove); + register.register(Core.TopicAdd); + register.register(Core.TopicRemove); + register.register(Core.FileEntryAdd); + register.register(Core.FileEntryRemove); + register.register(Core.TopicHyperlink); + register.register(Core.TitleText); + register.register(Core.ImageSource); + register.register(Core.RevisionAdd); + register.register(Core.RevisionRemove); + register.register(Core.ModifyTime); + register.register(Core.WorkbookSave); + register.register(Core.RelationshipAdd); + register.register(Core.RelationshipRemove); + register.register(Core.BoundaryAdd); + register.register(Core.BoundaryRemove); + register.register(Core.TopicNotes); + } + + private void createSections(Composite parent) { + addSection(parent, new AuthorInfoPart()); + addSection(parent, new WorkbookSummaryPart()); + addSection(parent, new AttachmentListPart()); + addSection(parent, new ExternalFileListPart()); + addSection(parent, new HyperlinkListPart()); + addSection(parent, new ImageListPart()); + } + + private void addSection(Composite parent, IWorkbookMetadataPart part) { + Section section = factory.createSection(parent, + Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED + | Section.NO_TITLE_FOCUS_BOX); + section.setText(part.getTitle()); + section.setLayoutData( + new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL)); + section.setTitleBarBackground( + section.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + section.setTitleBarBorderColor( + section.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + Composite client = factory.createComposite(section, SWT.WRAP); + client.setData(KEY_WIDGET_FACTORY, factory); + section.setClient(client); + part.createControl(client); + part.refresh(workbook, null); + part.addPropertyListener(propertyChangeHandler); + parts.add(part); + sections.put(part, section); + + updateSectionVisibility(part, section, part.isVisible()); + } + + private void refreshParts(final CoreEvent event) { + for (IWorkbookMetadataPart part : parts) { + part.refresh(workbook, event); + } + } + + private void updateSectionVisibility(IWorkbookMetadataPart part, + Section section, boolean visible) { + if (visible) { + section.setParent(form.getBody()); + + Section lastVisibleSection = null; + for (IWorkbookMetadataPart p : parts) { + if (p == part) + break; + Section s = sections.get(p); + if (s.getVisible()) { + lastVisibleSection = s; + } else { + section.moveBelow(lastVisibleSection); + } + } + } else { + section.setParent(composite); + } + section.setVisible(visible); + } + + private void revealSelectionInEditor(IWorkbookMetadataPart part) { + ISelectionProvider partSelectionProvider = MindMapUIPlugin + .getAdapter(part, ISelectionProvider.class); + if (partSelectionProvider == null) + return; + + ISelectionProvider editorSelectionProvider = sourceEditor.getSite() + .getSelectionProvider(); + if (editorSelectionProvider == null) + return; + + editorSelectionProvider + .setSelection(partSelectionProvider.getSelection()); + sourceEditor.getSite().getPage().activate(sourceEditor); + } + + private void executeCommand(Command command) { + ICommandStack commandStack = MindMapUIPlugin.getAdapter(sourceEditor, + ICommandStack.class); + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + } + + private synchronized void scheduleReflow() { + if (form == null || form.isDisposed()) + return; + + if (reflowScheduled) + return; + + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + reflowScheduled = false; + + if (form == null || form.isDisposed()) + return; + form.reflow(true); + } + }); + reflowScheduled = true; + } + + private void updateSection(IWorkbookMetadataPart part) { + Section section = sections.get(part); + if (section != null && !section.isDisposed()) { + String title = part.getTitle(); + String oldTitle = section.getText(); + if (!title.equals(oldTitle)) { + section.setText(title); + } + + boolean visible = part.isVisible(); + boolean oldVisible = section.getVisible(); + if (visible != oldVisible) { + updateSectionVisibility(part, section, visible); + } + + scheduleReflow(); + } + } + + private Composite getControl() { + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CLOSE_ID, + IDialogConstants.CLOSE_LABEL, true); + } + + @Override + protected void buttonPressed(int buttonId) { + super.buttonPressed(buttonId); + if (IDialogConstants.CLOSE_ID == buttonId) + close(); + } + + public void setSourceEditor(IEditorPart sourceEditor) { + Assert.isNotNull(instance); + this.sourceEditor = sourceEditor; + setWorkbook(sourceEditor == null ? null + : MindMapUIPlugin.getAdapter(sourceEditor, IWorkbook.class)); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .addPartListener(partListenerHandler); + } + + public static WorkbookMetaInspectorDialog getInstance(Shell parentShell) { + if (instance == null) { + instance = new WorkbookMetaInspectorDialog(parentShell); + } + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookRevisionDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookRevisionDialog.java index 3c9bd6e4d..339a870d9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookRevisionDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookRevisionDialog.java @@ -1,883 +1,883 @@ -package org.xmind.ui.internal.dialogs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.action.GroupMarker; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.jface.window.IShellProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.ISources; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.internal.WorkbenchWindow; -import org.eclipse.ui.menus.IMenuService; -import org.eclipse.ui.services.IEvaluationService; -import org.xmind.core.Core; -import org.xmind.core.IMeta; -import org.xmind.core.IRevision; -import org.xmind.core.IRevisionManager; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.commands.AddSheetCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteSheetCommand; -import org.xmind.ui.commands.ModifyMetadataCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.util.TextFormatter; -import org.xmind.ui.viewers.SWTUtils; - -public class WorkbookRevisionDialog extends Dialog { - - private class CurrentSelectionProviderWrap - implements ISelectionChangedListener { - - private ISelectionProvider selectionProvider = null; - - public void dispose() { - if (selectionProvider != null) { - selectionProvider.removeSelectionChangedListener(this); - selectionProvider = null; - } - } - - public void notifySelectionChanges() { - IWorkbenchWindow parentWindow = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - IEclipseContext context = ((WorkbenchWindow) parentWindow) - .getModel().getContext(); - context.remove(ISources.ACTIVE_CURRENT_SELECTION_NAME); - - if (selectionProvider != null) { - IEvaluationService es = (IEvaluationService) parentWindow - .getWorkbench().getService(IEvaluationService.class); - es.getCurrentState().addVariable( - ISources.ACTIVE_CURRENT_SELECTION_NAME, - selectionProvider.getSelection()); - } - } - - public void setSelectionProvider(ISelectionProvider selectionProvider) { - if (selectionProvider == this.selectionProvider) - return; - - ISelectionProvider oldSelectionProvider = this.selectionProvider; - this.selectionProvider = selectionProvider; - - if (oldSelectionProvider != null) { - oldSelectionProvider.removeSelectionChangedListener(this); - } - if (selectionProvider != null) { - selectionProvider.addSelectionChangedListener(this); - } - - notifySelectionChanges(); - } - - public void selectionChanged(SelectionChangedEvent event) { - notifySelectionChanges(); - } - - } - - public static class RevisionContentProvider - implements IStructuredContentProvider { - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - - public Object[] getElements(Object inputElement) { - return ((IRevisionManager) inputElement).getRevisions().toArray(); - } - - } - - private static class RevisionNumberLabelProvider - extends ColumnLabelProvider { - - @Override - public String getText(Object element) { - IRevision revision = (IRevision) element; - return String.valueOf(revision.getRevisionNumber()); - } - - } - - private static class RevisionDateTimeLabelProvider - extends ColumnLabelProvider { - - @Override - public String getText(Object element) { - IRevision revision = (IRevision) element; - return String.format("%tF", revision.getTimestamp()) + "/" //$NON-NLS-1$ //$NON-NLS-2$ - + String.format("%tT", revision.getTimestamp()); //$NON-NLS-1$ - } - - } - - private static class VersionCloumnSorter extends ViewerSorter { - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - IRevision revision1 = (IRevision) e1; - IRevision revision2 = (IRevision) e2; - - if (revision1.getRevisionNumber() > revision2.getRevisionNumber()) - return -1; - if (revision1.getRevisionNumber() == revision2.getRevisionNumber()) - return 0; - return 1; - } - } - - private class RevisionOpenListener implements IOpenListener { - - public void open(OpenEvent event) { - handleOpen(event.getSelection()); - } - - } - - private static final String KEY_SELECTION_PROVIDER = "org.xmind.ui.WorkbookRevisionDialog.selectionProvider"; //$NON-NLS-1$ - - private static final int PREVIEW_ID = IDialogConstants.CLIENT_ID + 1; - - private static final int RESTORE_ID = IDialogConstants.CLIENT_ID + 2; - - private static final String K_AUTO_SAVE = IMeta.CONFIG_AUTO_REVISION_GENERATION; - - private static final String V_NO = IMeta.V_NO; - - private Shell shell = null; - - private CurrentSelectionProviderWrap currentSelectionProviderWrap = null; - - private IGraphicalEditor sourceEditor; - - private TableViewer viewer; - - private ISheet sheet; - - private MenuManager popupMenuManager; - - private IRevisionManager revisionManager; - - private Button previewBt; - - private boolean previewDialogOpened = false; - - private ResourceManager resources; - - private IPartListener partListenerHandler = new IPartListener() { - - public void partOpened(IWorkbenchPart part) { - - } - - public void partDeactivated(IWorkbenchPart part) { - - } - - public void partClosed(IWorkbenchPart part) { - } - - public void partBroughtToTop(IWorkbenchPart part) { - - } - - public void partActivated(IWorkbenchPart part) { - if (!(part instanceof IGraphicalEditor)) - return; - if (getSourceEditor() != (IGraphicalEditor) part) { - if (part != null) { - setSourceEditor((IGraphicalEditor) part); - } - if (coreEventRegister != null) { - coreEventRegister.unregisterAll(); - } - if (topicEventRegister != null) { - topicEventRegister.unregisterAll(); - } - if (getSheet() != null) - registerCoreEvents(); - update(); - } - } - }; - - private ICoreEventListener coreEventHandler = new ICoreEventListener() { - - public void handleCoreEvent(CoreEvent event) { - String type = event.getType(); - if (Core.RevisionAdd.equals(type) - || Core.RevisionRemove.equals(type)) { - updateTabelViewer(); - } else if (Core.TitleText.equals(type)) { - updateShellTitle(); - } else if (Core.RootTopic.equals(type)) { - topicEventRegister.unregisterAll(); - ITopic rootTopic = sheet.getRootTopic(); - topicEventRegister.setNextSourceFrom(rootTopic); - topicEventRegister.register(Core.TitleText); - } - } - - }; - - private IPageChangedListener pageChangedHandler = new IPageChangedListener() { - - public void pageChanged(PageChangedEvent event) { - IViewer viewer = MindMapUIPlugin.getAdapter(getSourceEditor(), - IViewer.class); - - if (viewer != null && viewer instanceof IMindMapViewer) { - ISheet newSheet = ((IMindMapViewer) viewer).getSheet(); - if (getSheet() != newSheet) { - setSheet(newSheet); - } - if (coreEventRegister != null) { - coreEventRegister.unregisterAll(); - } - if (topicEventRegister != null) { - topicEventRegister.unregisterAll(); - } - registerCoreEvents(); - update(); - } - } - }; - - private ICoreEventRegister coreEventRegister = new CoreEventRegister( - coreEventHandler); - - private ICoreEventRegister topicEventRegister = new CoreEventRegister( - coreEventHandler); - - public WorkbookRevisionDialog(IShellProvider parentShell) { - super(parentShell); - } - - public WorkbookRevisionDialog(Shell shell, IGraphicalEditor sourceEditor) { - super(shell); - setSourceEditor(sourceEditor); - IViewer viewer = MindMapUIPlugin.getAdapter(sourceEditor, - IViewer.class); - if (viewer != null && viewer instanceof IMindMapViewer) { - setSheet(((IMindMapViewer) viewer).getSheet()); - } - setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE); - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - shell = newShell; - newShell.setText(MindMapMessages.WorkbookRevisionDialog_title); - newShell.setSize(520, 500); - newShell.setLocation( - Display.getCurrent().getClientArea().width / 2 - - newShell.getShell().getSize().x / 2, - Display.getCurrent().getClientArea().height / 2 - - newShell.getSize().y / 2); - } - - @Override - public void create() { - super.create(); - registerSourceProvider(); - } - - @Override - protected Control createDialogArea(Composite parent) { - resources = new LocalResourceManager(JFaceResources.getResources(), - parent); - - Composite composite = (Composite) super.createDialogArea(parent); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 14; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createDescriptionArea(composite); - - Control viewerControl = createViewer(composite); - GridData viewerData = new GridData(SWT.FILL, SWT.FILL, true, true); - viewerControl.setLayoutData(viewerData); - - registerCoreEvents(); - viewerControl.setData(KEY_SELECTION_PROVIDER, viewer); - createPopupMenu(viewerControl); - viewerControl.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - handleViewerDispose(); - } - }); - composite.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - handleDisposed(); - } - }); - - return composite; - } - - private void createDescriptionArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 21; - gridLayout.verticalSpacing = 0; - composite.setLayout(gridLayout); - - Label discriptionLabel = new Label(composite, SWT.WRAP); - GridData discriptionLabelData = new GridData(SWT.FILL, SWT.CENTER, true, - true); - discriptionLabel.setLayoutData(discriptionLabelData); - discriptionLabel.setAlignment(SWT.LEFT); - discriptionLabel.setText( - DialogMessages.workbookRevisionDialog_Description_Label_text); - } - - @Override - protected Control createButtonBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 13; - layout.marginHeight = 23; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false); - composite.setLayoutData(data); - composite.setFont(parent.getFont()); - - //create hyperlink area - Composite composite2 = new Composite(composite, SWT.NONE); - composite2 - .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - composite2.setLayout(gridLayout); - - createDisableHyperlink(composite2); - - //create buttonBar - Composite buttonBar = new Composite(composite, SWT.NONE); - // create a layout with spacing and margins appropriate for the font - // size. - GridLayout layout2 = new GridLayout(); - layout2.numColumns = 0; // this is incremented by createButton - layout2.makeColumnsEqualWidth = true; - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.horizontalSpacing = 18; - layout2.verticalSpacing = 0; - buttonBar.setLayout(layout2); - - GridData data2 = new GridData( - GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); - buttonBar.setLayoutData(data2); - buttonBar.setFont(composite.getFont()); - - createButtonsForButtonBar(buttonBar); - - return composite2; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - - previewBt = createButton(parent, PREVIEW_ID, - DialogMessages.WorkbookRevisionDialog_Preview_Button_label, - false); - - previewBt.setEnabled(viewer != null - && !StructuredSelection.EMPTY.equals(viewer.getSelection())); - - createButton(parent, RESTORE_ID, - DialogMessages.WorkbookRevisionDialog_Restore_Button_label, - false); - createButton(parent, IDialogConstants.CLOSE_ID, - IDialogConstants.CLOSE_LABEL, true); - } - - @Override - protected void buttonPressed(int buttonId) { - super.buttonPressed(buttonId); - if (PREVIEW_ID == buttonId) - preview(); - if (RESTORE_ID == buttonId) - restore(); - if (IDialogConstants.CLOSE_ID == buttonId) - close(); - } - - private void asyncExec(Runnable runnable) { - PlatformUI.getWorkbench().getDisplay().asyncExec(runnable); - } - - private void setSourceEditor(IGraphicalEditor editor) { - if (editor == this.sourceEditor) - return; - if (this.sourceEditor != null) { - this.sourceEditor.removePageChangedListener(pageChangedHandler); - } - this.sourceEditor = editor; - if (this.sourceEditor != null) { - this.sourceEditor.addPageChangedListener(pageChangedHandler); - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() - .addPartListener(partListenerHandler); - IGraphicalEditorPage page = this.sourceEditor - .getActivePageInstance(); - if (page != null) { - IGraphicalViewer viewer = page.getViewer(); - if (viewer instanceof IMindMapViewer) { - IMindMapViewer mmv = (IMindMapViewer) viewer; - IMindMap mindMap = mmv.getMindMap(); - setSheet(mindMap.getSheet()); - } - } - } - } - - private IGraphicalEditor getSourceEditor() { - return this.sourceEditor; - } - - private ISheet getSheet() { - return this.sheet; - } - - private void setSheet(ISheet sheet) { - if (this.sheet == sheet) - return; - - this.sheet = sheet; - if (this.sheet != null) { - revisionManager = this.sheet.getOwnedWorkbook() - .getRevisionRepository() - .getRevisionManager(this.sheet.getId(), IRevision.SHEET); - } else { - revisionManager = null; - } - if (viewer != null) { - viewer.setInput(revisionManager); - } - } - - private String getTitleText() { - String text = null; - if (getSheet() == null) { - if (getSourceEditor() != null) { - IGraphicalEditorPage page = getSourceEditor() - .getActivePageInstance(); - if (page != null) { - ISheet sheet2 = (ISheet) page.getInput(); - if (sheet2 != null) - setSheet(sheet2); - } - } - } - if (getSheet() != null) - text = String.format("%s - %s", getSheet().getTitleText(), //$NON-NLS-1$ - getSheet().getRootTopic().getTitleText()); - return TextFormatter.removeNewLineCharacter(text); - } - - private void registerSourceProvider() { - currentSelectionProviderWrap = new CurrentSelectionProviderWrap(); - currentSelectionProviderWrap.notifySelectionChanges(); - - final Listener focusListener = new Listener() { - public void handleEvent(Event event) { - if (currentSelectionProviderWrap == null) - return; - - Widget w = event.widget; - ISelectionProvider selectionProvider = null; - while (w != null) { - selectionProvider = (ISelectionProvider) w - .getData(KEY_SELECTION_PROVIDER); - if (selectionProvider != null) - break; - - if (w instanceof Control) { - w = ((Control) w).getParent(); - } - } - currentSelectionProviderWrap - .setSelectionProvider(selectionProvider); - } - }; - - final Display display = Display.getCurrent(); - display.addFilter(SWT.FocusIn, focusListener); - getShell().addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - display.removeFilter(SWT.FocusIn, focusListener); - } - }); - - } - - private void createPopupMenu(Control viewerControl) { - popupMenuManager = new MenuManager("#popup"); //$NON-NLS-1$ - popupMenuManager.add(new GroupMarker("start")); //$NON-NLS-1$ - popupMenuManager - .add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - popupMenuManager.add(new GroupMarker("end")); //$NON-NLS-1$ - IMenuService menuService = (IMenuService) PlatformUI.getWorkbench() - .getService(IMenuService.class); - menuService.populateContributionManager(popupMenuManager, - "popup:org.xmind.ui.RevisionsView"); //$NON-NLS-1$ - final Menu popupMenu = popupMenuManager - .createContextMenu(viewerControl); - viewerControl.setMenu(popupMenu); - } - - private void handleDisposed() { - if (currentSelectionProviderWrap != null) { - currentSelectionProviderWrap.dispose(); - currentSelectionProviderWrap = null; - } - coreEventRegister.unregisterAll(); - topicEventRegister.unregisterAll(); - viewer = null; - revisionManager = null; - sheet = null; - setSourceEditor((IGraphicalEditor) PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage().getActiveEditor()); - } - - private void handleViewerDispose() { - if (currentSelectionProviderWrap != null) { - currentSelectionProviderWrap.dispose(); - currentSelectionProviderWrap = null; - } - } - - private void registerCoreEvents() { - coreEventRegister.setNextSourceFrom(revisionManager); - coreEventRegister.register(Core.RevisionAdd); - coreEventRegister.register(Core.RevisionRemove); - coreEventRegister.setNextSourceFrom(sheet); - coreEventRegister.register(Core.TitleText); - coreEventRegister.register(Core.RootTopic); - ITopic rootTopic = getSheet().getRootTopic(); - topicEventRegister.setNextSourceFrom(rootTopic); - topicEventRegister.register(Core.TitleText); - } - - private Control createViewer(Composite parent) { - viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL - | SWT.FULL_SELECTION | SWT.BORDER); - viewer.getTable().setHeaderVisible(true); - viewer.getTable().setLinesVisible(true); - viewer.setContentProvider(new RevisionContentProvider()); - - viewer.getControl().setLayoutData(new GridData(GridData.CENTER)); - - TableViewerColumn col0 = new TableViewerColumn(viewer, SWT.LEFT); - col0.getColumn() - .setText(MindMapMessages.RevisionView_VersionColumn_text); - col0.getColumn().setWidth(200); - col0.setLabelProvider(new RevisionNumberLabelProvider()); - - TableViewerColumn col1 = new TableViewerColumn(viewer, SWT.LEFT); - col1.getColumn().setText(MindMapMessages.RevisionsView_DateColumn_text); - col1.getColumn().setWidth(282); - col1.setLabelProvider(new RevisionDateTimeLabelProvider()); - - viewer.setInput(revisionManager); - viewer.setSorter(new VersionCloumnSorter()); - viewer.addOpenListener(new RevisionOpenListener()); - viewer.getTable().addKeyListener(new KeyListener() { - public void keyReleased(KeyEvent e) { - } - - public void keyPressed(KeyEvent e) { - if (SWTUtils.matchKey(e.stateMask, e.keyCode, 0, SWT.SPACE)) { - handleOpen(viewer.getSelection()); - } - } - }); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - if (previewBt != null && !previewBt.isDisposed()) - previewBt.setEnabled(!StructuredSelection.EMPTY - .equals(event.getSelection())); - } - }); - - viewer.getControl().setToolTipText( - MindMapMessages.RevisionPage_ShowDetails_message); - - return viewer.getControl(); - } - - private void handleOpen(ISelection selection) { - if (selection.isEmpty()) - return; - IRevision revision = (IRevision) ((IStructuredSelection) selection) - .getFirstElement(); - viewRevision(revision); - } - - private void viewRevision(IRevision revision) { - if (previewDialogOpened) - return; - List revisions = revisionManager.getRevisions(); - int index = revisions.indexOf(revision); - RevisionPreviewDialog dialog = new RevisionPreviewDialog(shell, sheet, - revisions, index) { - public int open() { - previewDialogOpened = true; - return super.open(); - } - - public boolean close() { - previewDialogOpened = false; - return super.close(); - } - }; - dialog.open(); - } - - private void update() { - updateTabelViewer(); - updateShellTitle(); - } - - private void updateTabelViewer() { - if (viewer != null) { - asyncExec(new Runnable() { - public void run() { - if (viewer != null) { - viewer.setInput(revisionManager); - viewer.refresh(); - createPopupMenu(viewer.getControl()); - } - } - }); - } - } - - private void updateShellTitle() { - asyncExec(new Runnable() { - public void run() { - if (shell != null && !shell.isDisposed()) { - shell.setText(getTitleText()); - } - } - }); - } - - private void createDisableHyperlink(Composite parent) { - final Hyperlink disableLink = new Hyperlink(parent, SWT.SINGLE); - disableLink.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, false)); - disableLink.setText( - MindMapMessages.WorkbookRevisionDialog_Disable_hyperlink); - disableLink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ - boolean isAutoSave = !V_NO.equals( - getSheet().getOwnedWorkbook().getMeta().getValue(K_AUTO_SAVE)); - if (!isAutoSave) { - disableLink.setEnabled(false); - } - disableLink.addHyperlinkListener(new HyperlinkAdapter() { - public void linkActivated(HyperlinkEvent e) { - - Boolean isOk = MessageDialog.openConfirm(shell, - DialogMessages.DisableRevisonDialog_Title_text, - DialogMessages.DisableRevisonDialog_Comfirm_message); - if (isOk) { - disableRevision(); - disableLink.setEnabled(false); - close(); - } - - } - }); - } - - private void disableRevision() { - IWorkbook workbook = getSheet().getOwnedWorkbook(); - Command command = new ModifyMetadataCommand(workbook, K_AUTO_SAVE, - V_NO); - command.setLabel(CommandMessages.Command_TurnOffAutoRevisionSaving); - ICommandStack commandStack = getSourceEditor().getCommandStack(); - if (commandStack != null) { - commandStack.execute(command); - } else { - command.execute(); - } - } - - private void restore() { - revertToRevision(viewer.getSelection(), getSourceEditor()); - } - - private void preview() { - ISelection selection = viewer.getSelection(); - if (selection.isEmpty()) - return; - IRevision revision = (IRevision) ((IStructuredSelection) selection) - .getFirstElement(); - viewRevision(revision); - } - - private void revertToRevision(ISelection selection, IEditorPart editor) { - if (selection == null || selection.isEmpty() - || !(selection instanceof IStructuredSelection)) - return; - - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (!(obj instanceof IRevision)) - return; - - IRevision revision = (IRevision) obj; - if (!IRevision.SHEET.equals(revision.getContentType())) - return; - - IWorkbook workbook = revision.getOwnedWorkbook(); - final ISheet sourceSheet = (ISheet) workbook - .findElement(revision.getResourceId(), null); - - final ISheet targetSheet = (ISheet) workbook - .importElement(revision.getContent()); - if (targetSheet == null) - return; - - // Force update modification info - String title = targetSheet.getTitleText(); - targetSheet.setTitleText("#" + title); //$NON-NLS-1$ - targetSheet.setTitleText(title); - - final int sheetIndex = sourceSheet.getIndex(); - - List commands = new ArrayList(); - ISheet placeholderSheet = workbook.createSheet(); - commands.add(new AddSheetCommand(placeholderSheet, workbook)); - commands.add(new DeleteSheetCommand(sourceSheet)); - commands.add(new AddSheetCommand(targetSheet, workbook, sheetIndex)); - commands.add(new DeleteSheetCommand(placeholderSheet, workbook)); - - // TODO comments delete -// List comments = CommentsUtils -// .getAllCommentsOfSheetAndChildren(sourceSheet); -// for (IComment comment : comments) { -// if (comment.getTarget() instanceof ITopic -// && !containsTopicById(targetSheet.getRootTopic(), -// comment.getTarget().getId())) { -// commands.add(new DeleteCommentCommand(comment)); -// } -// } - - final Command command = new CompoundCommand( - MindMapMessages.RevertToRevisionCommand_label, commands); - final ICommandStack commandStack = editor == null ? null - : MindMapUIPlugin.getAdapter(editor, ICommandStack.class); - - final IRevisionManager manager = revision.getOwnedManager(); - final IRevision latestRevision = manager.getLatestRevision(); - - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - if (latestRevision == null || sourceSheet - .getModifiedTime() > latestRevision.getTimestamp()) { - manager.addRevision(sourceSheet); - } - if (commandStack != null) { - commandStack.execute(command); - } else { - command.execute(); - } - } - }); - } - -} +package org.xmind.ui.internal.dialogs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.ISources; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.internal.WorkbenchWindow; +import org.eclipse.ui.menus.IMenuService; +import org.eclipse.ui.services.IEvaluationService; +import org.xmind.core.Core; +import org.xmind.core.IMeta; +import org.xmind.core.IRevision; +import org.xmind.core.IRevisionManager; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.commands.AddSheetCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteSheetCommand; +import org.xmind.ui.commands.ModifyMetadataCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.TextFormatter; +import org.xmind.ui.viewers.SWTUtils; + +public class WorkbookRevisionDialog extends Dialog { + + private class CurrentSelectionProviderWrap + implements ISelectionChangedListener { + + private ISelectionProvider selectionProvider = null; + + public void dispose() { + if (selectionProvider != null) { + selectionProvider.removeSelectionChangedListener(this); + selectionProvider = null; + } + } + + public void notifySelectionChanges() { + IWorkbenchWindow parentWindow = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + IEclipseContext context = ((WorkbenchWindow) parentWindow) + .getModel().getContext(); + context.remove(ISources.ACTIVE_CURRENT_SELECTION_NAME); + + if (selectionProvider != null) { + IEvaluationService es = (IEvaluationService) parentWindow + .getWorkbench().getService(IEvaluationService.class); + es.getCurrentState().addVariable( + ISources.ACTIVE_CURRENT_SELECTION_NAME, + selectionProvider.getSelection()); + } + } + + public void setSelectionProvider(ISelectionProvider selectionProvider) { + if (selectionProvider == this.selectionProvider) + return; + + ISelectionProvider oldSelectionProvider = this.selectionProvider; + this.selectionProvider = selectionProvider; + + if (oldSelectionProvider != null) { + oldSelectionProvider.removeSelectionChangedListener(this); + } + if (selectionProvider != null) { + selectionProvider.addSelectionChangedListener(this); + } + + notifySelectionChanges(); + } + + public void selectionChanged(SelectionChangedEvent event) { + notifySelectionChanges(); + } + + } + + public static class RevisionContentProvider + implements IStructuredContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public Object[] getElements(Object inputElement) { + return ((IRevisionManager) inputElement).getRevisions().toArray(); + } + + } + + private static class RevisionNumberLabelProvider + extends ColumnLabelProvider { + + @Override + public String getText(Object element) { + IRevision revision = (IRevision) element; + return String.valueOf(revision.getRevisionNumber()); + } + + } + + private static class RevisionDateTimeLabelProvider + extends ColumnLabelProvider { + + @Override + public String getText(Object element) { + IRevision revision = (IRevision) element; + return String.format("%tF", revision.getTimestamp()) + "/" //$NON-NLS-1$ //$NON-NLS-2$ + + String.format("%tT", revision.getTimestamp()); //$NON-NLS-1$ + } + + } + + private static class VersionCloumnSorter extends ViewerSorter { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + IRevision revision1 = (IRevision) e1; + IRevision revision2 = (IRevision) e2; + + if (revision1.getRevisionNumber() > revision2.getRevisionNumber()) + return -1; + if (revision1.getRevisionNumber() == revision2.getRevisionNumber()) + return 0; + return 1; + } + } + + private class RevisionOpenListener implements IOpenListener { + + public void open(OpenEvent event) { + handleOpen(event.getSelection()); + } + + } + + private static final String KEY_SELECTION_PROVIDER = "org.xmind.ui.WorkbookRevisionDialog.selectionProvider"; //$NON-NLS-1$ + + private static final int PREVIEW_ID = IDialogConstants.CLIENT_ID + 1; + + private static final int RESTORE_ID = IDialogConstants.CLIENT_ID + 2; + + private static final String K_AUTO_SAVE = IMeta.CONFIG_AUTO_REVISION_GENERATION; + + private static final String V_NO = IMeta.V_NO; + + private Shell shell = null; + + private CurrentSelectionProviderWrap currentSelectionProviderWrap = null; + + private IGraphicalEditor sourceEditor; + + private TableViewer viewer; + + private ISheet sheet; + + private MenuManager popupMenuManager; + + private IRevisionManager revisionManager; + + private Button previewBt; + + private boolean previewDialogOpened = false; + + private ResourceManager resources; + + private IPartListener partListenerHandler = new IPartListener() { + + public void partOpened(IWorkbenchPart part) { + + } + + public void partDeactivated(IWorkbenchPart part) { + + } + + public void partClosed(IWorkbenchPart part) { + } + + public void partBroughtToTop(IWorkbenchPart part) { + + } + + public void partActivated(IWorkbenchPart part) { + if (!(part instanceof IGraphicalEditor)) + return; + if (getSourceEditor() != (IGraphicalEditor) part) { + if (part != null) { + setSourceEditor((IGraphicalEditor) part); + } + if (coreEventRegister != null) { + coreEventRegister.unregisterAll(); + } + if (topicEventRegister != null) { + topicEventRegister.unregisterAll(); + } + if (getSheet() != null) + registerCoreEvents(); + update(); + } + } + }; + + private ICoreEventListener coreEventHandler = new ICoreEventListener() { + + public void handleCoreEvent(CoreEvent event) { + String type = event.getType(); + if (Core.RevisionAdd.equals(type) + || Core.RevisionRemove.equals(type)) { + updateTabelViewer(); + } else if (Core.TitleText.equals(type)) { + updateShellTitle(); + } else if (Core.RootTopic.equals(type)) { + topicEventRegister.unregisterAll(); + ITopic rootTopic = sheet.getRootTopic(); + topicEventRegister.setNextSourceFrom(rootTopic); + topicEventRegister.register(Core.TitleText); + } + } + + }; + + private IPageChangedListener pageChangedHandler = new IPageChangedListener() { + + public void pageChanged(PageChangedEvent event) { + IViewer viewer = MindMapUIPlugin.getAdapter(getSourceEditor(), + IViewer.class); + + if (viewer != null && viewer instanceof IMindMapViewer) { + ISheet newSheet = ((IMindMapViewer) viewer).getSheet(); + if (getSheet() != newSheet) { + setSheet(newSheet); + } + if (coreEventRegister != null) { + coreEventRegister.unregisterAll(); + } + if (topicEventRegister != null) { + topicEventRegister.unregisterAll(); + } + registerCoreEvents(); + update(); + } + } + }; + + private ICoreEventRegister coreEventRegister = new CoreEventRegister( + coreEventHandler); + + private ICoreEventRegister topicEventRegister = new CoreEventRegister( + coreEventHandler); + + public WorkbookRevisionDialog(IShellProvider parentShell) { + super(parentShell); + } + + public WorkbookRevisionDialog(Shell shell, IGraphicalEditor sourceEditor) { + super(shell); + setSourceEditor(sourceEditor); + IViewer viewer = MindMapUIPlugin.getAdapter(sourceEditor, + IViewer.class); + if (viewer != null && viewer instanceof IMindMapViewer) { + setSheet(((IMindMapViewer) viewer).getSheet()); + } + setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + shell = newShell; + newShell.setText(MindMapMessages.WorkbookRevisionDialog_title); + newShell.setSize(520, 500); + newShell.setLocation( + Display.getCurrent().getClientArea().width / 2 + - newShell.getShell().getSize().x / 2, + Display.getCurrent().getClientArea().height / 2 + - newShell.getSize().y / 2); + } + + @Override + public void create() { + super.create(); + registerSourceProvider(); + } + + @Override + protected Control createDialogArea(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + + Composite composite = (Composite) super.createDialogArea(parent); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 14; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createDescriptionArea(composite); + + Control viewerControl = createViewer(composite); + GridData viewerData = new GridData(SWT.FILL, SWT.FILL, true, true); + viewerControl.setLayoutData(viewerData); + + registerCoreEvents(); + viewerControl.setData(KEY_SELECTION_PROVIDER, viewer); + createPopupMenu(viewerControl); + viewerControl.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + handleViewerDispose(); + } + }); + composite.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + handleDisposed(); + } + }); + + return composite; + } + + private void createDescriptionArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 21; + gridLayout.verticalSpacing = 0; + composite.setLayout(gridLayout); + + Label discriptionLabel = new Label(composite, SWT.WRAP); + GridData discriptionLabelData = new GridData(SWT.FILL, SWT.CENTER, true, + true); + discriptionLabel.setLayoutData(discriptionLabelData); + discriptionLabel.setAlignment(SWT.LEFT); + discriptionLabel.setText( + DialogMessages.workbookRevisionDialog_Description_Label_text); + } + + @Override + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 13; + layout.marginHeight = 23; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false); + composite.setLayoutData(data); + composite.setFont(parent.getFont()); + + //create hyperlink area + Composite composite2 = new Composite(composite, SWT.NONE); + composite2 + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + composite2.setLayout(gridLayout); + + createDisableHyperlink(composite2); + + //create buttonBar + Composite buttonBar = new Composite(composite, SWT.NONE); + // create a layout with spacing and margins appropriate for the font + // size. + GridLayout layout2 = new GridLayout(); + layout2.numColumns = 0; // this is incremented by createButton + layout2.makeColumnsEqualWidth = true; + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.horizontalSpacing = 18; + layout2.verticalSpacing = 0; + buttonBar.setLayout(layout2); + + GridData data2 = new GridData( + GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); + buttonBar.setLayoutData(data2); + buttonBar.setFont(composite.getFont()); + + createButtonsForButtonBar(buttonBar); + + return composite2; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + + previewBt = createButton(parent, PREVIEW_ID, + DialogMessages.WorkbookRevisionDialog_Preview_Button_label, + false); + + previewBt.setEnabled(viewer != null + && !StructuredSelection.EMPTY.equals(viewer.getSelection())); + + createButton(parent, RESTORE_ID, + DialogMessages.WorkbookRevisionDialog_Restore_Button_label, + false); + createButton(parent, IDialogConstants.CLOSE_ID, + IDialogConstants.CLOSE_LABEL, true); + } + + @Override + protected void buttonPressed(int buttonId) { + super.buttonPressed(buttonId); + if (PREVIEW_ID == buttonId) + preview(); + if (RESTORE_ID == buttonId) + restore(); + if (IDialogConstants.CLOSE_ID == buttonId) + close(); + } + + private void asyncExec(Runnable runnable) { + PlatformUI.getWorkbench().getDisplay().asyncExec(runnable); + } + + private void setSourceEditor(IGraphicalEditor editor) { + if (editor == this.sourceEditor) + return; + if (this.sourceEditor != null) { + this.sourceEditor.removePageChangedListener(pageChangedHandler); + } + this.sourceEditor = editor; + if (this.sourceEditor != null) { + this.sourceEditor.addPageChangedListener(pageChangedHandler); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .addPartListener(partListenerHandler); + IGraphicalEditorPage page = this.sourceEditor + .getActivePageInstance(); + if (page != null) { + IGraphicalViewer viewer = page.getViewer(); + if (viewer instanceof IMindMapViewer) { + IMindMapViewer mmv = (IMindMapViewer) viewer; + IMindMap mindMap = mmv.getMindMap(); + setSheet(mindMap.getSheet()); + } + } + } + } + + private IGraphicalEditor getSourceEditor() { + return this.sourceEditor; + } + + private ISheet getSheet() { + return this.sheet; + } + + private void setSheet(ISheet sheet) { + if (this.sheet == sheet) + return; + + this.sheet = sheet; + if (this.sheet != null) { + revisionManager = this.sheet.getOwnedWorkbook() + .getRevisionRepository() + .getRevisionManager(this.sheet.getId(), IRevision.SHEET); + } else { + revisionManager = null; + } + if (viewer != null) { + viewer.setInput(revisionManager); + } + } + + private String getTitleText() { + String text = null; + if (getSheet() == null) { + if (getSourceEditor() != null) { + IGraphicalEditorPage page = getSourceEditor() + .getActivePageInstance(); + if (page != null) { + ISheet sheet2 = (ISheet) page.getInput(); + if (sheet2 != null) + setSheet(sheet2); + } + } + } + if (getSheet() != null) + text = String.format("%s - %s", getSheet().getTitleText(), //$NON-NLS-1$ + getSheet().getRootTopic().getTitleText()); + return TextFormatter.removeNewLineCharacter(text); + } + + private void registerSourceProvider() { + currentSelectionProviderWrap = new CurrentSelectionProviderWrap(); + currentSelectionProviderWrap.notifySelectionChanges(); + + final Listener focusListener = new Listener() { + public void handleEvent(Event event) { + if (currentSelectionProviderWrap == null) + return; + + Widget w = event.widget; + ISelectionProvider selectionProvider = null; + while (w != null) { + selectionProvider = (ISelectionProvider) w + .getData(KEY_SELECTION_PROVIDER); + if (selectionProvider != null) + break; + + if (w instanceof Control) { + w = ((Control) w).getParent(); + } + } + currentSelectionProviderWrap + .setSelectionProvider(selectionProvider); + } + }; + + final Display display = Display.getCurrent(); + display.addFilter(SWT.FocusIn, focusListener); + getShell().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + display.removeFilter(SWT.FocusIn, focusListener); + } + }); + + } + + private void createPopupMenu(Control viewerControl) { + popupMenuManager = new MenuManager("#popup"); //$NON-NLS-1$ + popupMenuManager.add(new GroupMarker("start")); //$NON-NLS-1$ + popupMenuManager + .add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + popupMenuManager.add(new GroupMarker("end")); //$NON-NLS-1$ + IMenuService menuService = (IMenuService) PlatformUI.getWorkbench() + .getService(IMenuService.class); + menuService.populateContributionManager(popupMenuManager, + "popup:org.xmind.ui.RevisionsView"); //$NON-NLS-1$ + final Menu popupMenu = popupMenuManager + .createContextMenu(viewerControl); + viewerControl.setMenu(popupMenu); + } + + private void handleDisposed() { + if (currentSelectionProviderWrap != null) { + currentSelectionProviderWrap.dispose(); + currentSelectionProviderWrap = null; + } + coreEventRegister.unregisterAll(); + topicEventRegister.unregisterAll(); + viewer = null; + revisionManager = null; + sheet = null; + setSourceEditor((IGraphicalEditor) PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getActiveEditor()); + } + + private void handleViewerDispose() { + if (currentSelectionProviderWrap != null) { + currentSelectionProviderWrap.dispose(); + currentSelectionProviderWrap = null; + } + } + + private void registerCoreEvents() { + coreEventRegister.setNextSourceFrom(revisionManager); + coreEventRegister.register(Core.RevisionAdd); + coreEventRegister.register(Core.RevisionRemove); + coreEventRegister.setNextSourceFrom(sheet); + coreEventRegister.register(Core.TitleText); + coreEventRegister.register(Core.RootTopic); + ITopic rootTopic = getSheet().getRootTopic(); + topicEventRegister.setNextSourceFrom(rootTopic); + topicEventRegister.register(Core.TitleText); + } + + private Control createViewer(Composite parent) { + viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.BORDER); + viewer.getTable().setHeaderVisible(true); + viewer.getTable().setLinesVisible(true); + viewer.setContentProvider(new RevisionContentProvider()); + + viewer.getControl().setLayoutData(new GridData(GridData.CENTER)); + + TableViewerColumn col0 = new TableViewerColumn(viewer, SWT.LEFT); + col0.getColumn() + .setText(MindMapMessages.RevisionView_VersionColumn_text); + col0.getColumn().setWidth(200); + col0.setLabelProvider(new RevisionNumberLabelProvider()); + + TableViewerColumn col1 = new TableViewerColumn(viewer, SWT.LEFT); + col1.getColumn().setText(MindMapMessages.RevisionsView_DateColumn_text); + col1.getColumn().setWidth(282); + col1.setLabelProvider(new RevisionDateTimeLabelProvider()); + + viewer.setInput(revisionManager); + viewer.setSorter(new VersionCloumnSorter()); + viewer.addOpenListener(new RevisionOpenListener()); + viewer.getTable().addKeyListener(new KeyListener() { + public void keyReleased(KeyEvent e) { + } + + public void keyPressed(KeyEvent e) { + if (SWTUtils.matchKey(e.stateMask, e.keyCode, 0, SWT.SPACE)) { + handleOpen(viewer.getSelection()); + } + } + }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (previewBt != null && !previewBt.isDisposed()) + previewBt.setEnabled(!StructuredSelection.EMPTY + .equals(event.getSelection())); + } + }); + + viewer.getControl().setToolTipText( + MindMapMessages.RevisionPage_ShowDetails_message); + + return viewer.getControl(); + } + + private void handleOpen(ISelection selection) { + if (selection.isEmpty()) + return; + IRevision revision = (IRevision) ((IStructuredSelection) selection) + .getFirstElement(); + viewRevision(revision); + } + + private void viewRevision(IRevision revision) { + if (previewDialogOpened) + return; + List revisions = revisionManager.getRevisions(); + int index = revisions.indexOf(revision); + RevisionPreviewDialog dialog = new RevisionPreviewDialog(shell, sheet, + revisions, index) { + public int open() { + previewDialogOpened = true; + return super.open(); + } + + public boolean close() { + previewDialogOpened = false; + return super.close(); + } + }; + dialog.open(); + } + + private void update() { + updateTabelViewer(); + updateShellTitle(); + } + + private void updateTabelViewer() { + if (viewer != null) { + asyncExec(new Runnable() { + public void run() { + if (viewer != null) { + viewer.setInput(revisionManager); + viewer.refresh(); + createPopupMenu(viewer.getControl()); + } + } + }); + } + } + + private void updateShellTitle() { + asyncExec(new Runnable() { + public void run() { + if (shell != null && !shell.isDisposed()) { + shell.setText(getTitleText()); + } + } + }); + } + + private void createDisableHyperlink(Composite parent) { + final Hyperlink disableLink = new Hyperlink(parent, SWT.SINGLE); + disableLink.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, false)); + disableLink.setText( + MindMapMessages.WorkbookRevisionDialog_Disable_hyperlink); + disableLink.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ + boolean isAutoSave = !V_NO.equals( + getSheet().getOwnedWorkbook().getMeta().getValue(K_AUTO_SAVE)); + if (!isAutoSave) { + disableLink.setEnabled(false); + } + disableLink.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + + Boolean isOk = MessageDialog.openConfirm(shell, + DialogMessages.DisableRevisonDialog_Title_text, + DialogMessages.DisableRevisonDialog_Comfirm_message); + if (isOk) { + disableRevision(); + disableLink.setEnabled(false); + close(); + } + + } + }); + } + + private void disableRevision() { + IWorkbook workbook = getSheet().getOwnedWorkbook(); + Command command = new ModifyMetadataCommand(workbook, K_AUTO_SAVE, + V_NO); + command.setLabel(CommandMessages.Command_TurnOffAutoRevisionSaving); + ICommandStack commandStack = getSourceEditor().getCommandStack(); + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + } + + private void restore() { + revertToRevision(viewer.getSelection(), getSourceEditor()); + } + + private void preview() { + ISelection selection = viewer.getSelection(); + if (selection.isEmpty()) + return; + IRevision revision = (IRevision) ((IStructuredSelection) selection) + .getFirstElement(); + viewRevision(revision); + } + + private void revertToRevision(ISelection selection, IEditorPart editor) { + if (selection == null || selection.isEmpty() + || !(selection instanceof IStructuredSelection)) + return; + + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (!(obj instanceof IRevision)) + return; + + IRevision revision = (IRevision) obj; + if (!IRevision.SHEET.equals(revision.getContentType())) + return; + + IWorkbook workbook = revision.getOwnedWorkbook(); + final ISheet sourceSheet = (ISheet) workbook + .findElement(revision.getResourceId(), null); + + final ISheet targetSheet = (ISheet) workbook + .importElement(revision.getContent()); + if (targetSheet == null) + return; + + // Force update modification info + String title = targetSheet.getTitleText(); + targetSheet.setTitleText("#" + title); //$NON-NLS-1$ + targetSheet.setTitleText(title); + + final int sheetIndex = sourceSheet.getIndex(); + + List commands = new ArrayList(); + ISheet placeholderSheet = workbook.createSheet(); + commands.add(new AddSheetCommand(placeholderSheet, workbook)); + commands.add(new DeleteSheetCommand(sourceSheet)); + commands.add(new AddSheetCommand(targetSheet, workbook, sheetIndex)); + commands.add(new DeleteSheetCommand(placeholderSheet, workbook)); + + // TODO comments delete +// List comments = CommentsUtils +// .getAllCommentsOfSheetAndChildren(sourceSheet); +// for (IComment comment : comments) { +// if (comment.getTarget() instanceof ITopic +// && !containsTopicById(targetSheet.getRootTopic(), +// comment.getTarget().getId())) { +// commands.add(new DeleteCommentCommand(comment)); +// } +// } + + final Command command = new CompoundCommand( + MindMapMessages.RevertToRevisionCommand_label, commands); + final ICommandStack commandStack = editor == null ? null + : MindMapUIPlugin.getAdapter(editor, ICommandStack.class); + + final IRevisionManager manager = revision.getOwnedManager(); + final IRevision latestRevision = manager.getLatestRevision(); + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + if (latestRevision == null || sourceSheet + .getModifiedTime() > latestRevision.getTimestamp()) { + manager.addRevision(sourceSheet); + } + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/messages.properties index c35e8277b..03a36faad 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/messages.properties @@ -1,176 +1,176 @@ -CommonDialogTitle=XMind -Error_title=XMind - Error -MultipleErrors_title=XMind - Multiple Errors -Open_title=Open -Save_title=Save -ErrorOpen_title=XMind - Open -ErrorSave_title=XMind - Save - -ReduceFileSize_Advise_text=Select the content below to reduce this XMind file size. -DeleteEditingHistory_text=Delete editing history -DeletePreviewImage_text=Delete preview image -ReduceFileSize_text=Reduce File Size -ReduceAndSave_text=Reduce and Save - -WebHyperlinkPage_label=Enter a web location here, or paste one from a web browser: -WebHyperlinkPage_nullHyper_message=Hyperlink is null. -WorkbookFilterName=XMind Workbook -TemplateFilterName=XMind Template -OldWorkbookFilterName=XMIND 2008/2007 Workbook -AllSupportedFilesFilterName=All Supported Files -AllFilesFilterName=All Files -MarkerPackageFilterName=Marker Package - -ConfirmOverwrite_title=XMind - Confirm Overwrite -ConfirmOverwrite_message=The file already exists. Do you want to overwrite it?\n{0} - -ConfirmRestart_title=XMind - Confirm Restart -ConfirmRestart_message=This operation requires restarting to complete. Restart now? -ConfirmRestart_Restart=&Restart -ConfirmRestart_Continue=&Continue - -ConfirmWorkbookVersion_title=XMind - Confirm Workbook Version -ConfirmWorkbookVersion_message=''{0}'' seems to be produced by an old version of XMind. Do you want to save it as a file of the current version?\n\n(If you insist on keeping the file with that old format, try "Export" in "File" menu.) -ConfirmWorkbookVersion_SaveAs=&Save As... - -WorkbookRevisionDialog_title=Editing History ({0}) - -InfoFileNotExists_title=File Not Exists -InfoFileNotExists_message=This file seems not to exist.\r\n\r\n{0}\r\n\r\nStill try to open it? - -FailedToLoadWorkbook_message=Can''t load workbook from file: {0} -FailedToSaveWorkbook_message=Can''t save workbook to file: {0} - -CompatibilityWarning_title=Compatibility Warning -CompatibilityWarning_message=This file is produced by a former version of XMIND. - -HyperlinkDialog_windowTitle=Modify Topic Hyperlink -HyperlinkDialog_title=Modify Hyperlink -HyperlinkDialog_description=Select a type of hyperlink from the left, and fill the content on the right. -HyperlinkDialog_Remove=&Remove -HyperlinkDialog_MultipleTopics_message=Enter hyperlink location (multiple topics): -HyperlinkDialog_MultipleTopics_value=[ Multiple hyperlinks... ] -HyperlinkDialog_FailCreatePage_message=Failed to create this page... -NotesPopup_GotoNotesView_text=Press ''{0}'' to edit in Notes View - -SelectImageDialog_title=Select Image - -TemplateMissing_message=Oops, the template ''{0}'' seems missing.\n\nFor more information about this, please log on to ''www.xmind.net''. - -TopicHyperlinkPage_label=Insert a link to the topic selected below: - -PageSetupDialog_Content=Content -PageSetupDialog_PlusAndMinusIcons=Collapse && Expand Icons -PageSetupDialog_CurrentMap=Current Map -PageSetupDialog_WholeWorkbook=Whole Workbook -PageSetupDialog_HideBoth=Hide '-' and '+' -PageSetupDialog_ShowBoth=Show '-' and '+' -PageSetupDialog_HideMinusShowPlus=Hide '-' show '+' -PageSetupDialog_windowTitle=Page Setup -PageSetupDialog_title=Page Setup For Printing -PageSetupDialog_description=Adjust settings of the page on which the selected map will be printed. -PageSetupDialog_PageSetup=Page Setup -PageSetupDialog_Margins=Margins -PageSetupDialog_HeaderFooter=Header/Footer -PageSetupDialog_Background=Background -PageSetupDialog_Border=Border -PageSetupDialog_Left=Left: -PageSetupDialog_Right=Right: -PageSetupDialog_Top=Top: -PageSetupDialog_Bottom=Bottom: -PageSetupDialog_Inch=Inch -PageSetupDialog_Millimeter=Millimeter -PageSetupDialog_Header=Header: -PageSetupDialog_Footer=Footer: -PageSetupDialog_AlignLeft_text=Left -PageSetupDialog_AlignLeft_toolTip=Left -PageSetupDialog_AlignRight_text=Right -PageSetupDialog_AlignRight_toolTip=Right -PageSetupDialog_AlignCenter_text=Center -PageSetupDialog_AlignCenter_toolTip=Center -PageSetupDialog_Font_text=Font... -PageSetupDialog_Font_toolTip=Choose font from a font dialog -PageSetupDialog_JustForReference=* This preview is just for reference. -PageSetupDialog_Orientation=Orientation -PageSetupDialog_Landscape=Landscape -PageSetupDialog_Portrait=Portrait - -FindReplaceDialog_windowTitle=Find/Replace -FindReplaceDialog_Find_label=&Find: -FindReplaceDialog_ReplaceWith_label=&Replace With: -FindReplaceDialog_OptionGroup=Option -FindReplaceDialog_CaseSensitive=&Case Sensitive -FindReplaceDialog_WholeWord=&Whole Word -FindReplaceDialog_DirectionGroup=Direction -FindReplaceDialog_Forward=F&orward -FindReplaceDialog_Backward=&Backward -FindReplaceDialog_ScopeGroup=Scope -FindReplaceDialog_CurrentMap=Current &Map -FindReplaceDialog_Workbook=&Workbook -FindReplaceDialog_Find_text=Fi&nd -FindReplaceDialog_FindAll_text=Find &All -FindReplaceDialog_Replace_text=Replac&e -FindReplaceDialog_ReplaceAll_text=Re&place All -FindReplaceDialog_StringNotFound=String Not Found - -FileHyperlinkPage_ChooseFile_text=Choose a file -FileHyperlinkPage_ChooseFolder_text=Choose a folder -FileHyperlinkPage_FileNotExists_message=File not exists. -FileHyperlinkPage_RelativeWarning_message=The workbook has to be saved before choosing relative file hyperlink. -FileHyperlinkPage_label=Enter a path representing a folder or a file, or choose one from your local file system: -FileHyperlinkPage_OpenDirectoryDialog_windowTitle=Open -FileHyperlinkPage_OpenFileDialog_windowTitle=Open -FileHyperlinkPage_WarningDialog_message=Please click "OK" to save current file before finishing inserting the relative hyperlink. -FileHyperlinkPage_WarningDialog_Title=Insert Relative Hyperlink -FileHyperlinkPage_WarningDialog_OKButton_Label=OK -FileHyperlinkPage_WarningDialog_CancelButton_Label=Cancel -FileHyperlinkPage_HrefGroup_Text=Hyperlink type -FileHyperlinkPage_AbsoluteButton_Text=Absolute -FileHyperlinkPage_RelativeButton_Text=Relative -RevisionPreviewDialog_CorruptedRevision_message=Oops, this revision seems to have been corrupted. -RevisionPreviewDialog_CurrentRevision_title=Current Sheet - {0} -RevisionPreviewDialog_Revision_titlePattern=Preview( {0} ) -workbookRevisionDialog_Title_Label_text=Editing History -workbookRevisionDialog_Description_Label_text=Help restore the previous versions of the current XMind file. -WorkbookRevisionDialog_Preview_Button_label=Preview -WorkbookRevisionDialog_Restore_Button_label=Restore -WorkbookRevisionDialog_Disable_Label_text=Disable revision on this file -EnableRevisionDialog_Title_text=Enable Revision -EnableRevisionDialog_Confirm_message=The revision feature is turned off. If you would like to use this feature, please click "OK" to turn it on. -DisableRevisonDialog_Title_text=Disable Revision -DisableRevisonDialog_Comfirm_message=Are you sure disable revision on this file? -RevisionPreviewDialog_Restore_Label_text=Restore to Rev #{0} -RevisionPreviewDialog_Previous_Button_label=Previous -RevisionPreviewDialog_Next_Button_label=Next - - -SortMessageDialog_Messages=Fail to perform the 'sort' request, because some topics that are bound together obey the desired order. -SortMessageDialog_Title=Fail to Sort Topics - - -NewWorkbookWizardDialog_OpenExistingFile_text=Open an Existing File... -NewWorkbookWizardDialog_Choose_text=Choose - -TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_windowTitle=XMind - Invalid Topic Hyperlink -TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_message=This topic seems to have been deleted. Do you want to delete this hyperlink as well? - -DND_ExternalFolder=External Folder -DND_ExternalFolder_confirmation_with_path=Do you want to make a link pointing to this folder, or copy all its contents (including all files and sub-folders) into this map?\r\n\r\n{0}\r\n\r\nCAUTION: Copying multiple file contents will enlarge the file size. -DND_ExternalFile=External File -DND_ExternalFile_confirmation_with_path_size=Do you want to make a link pointing to this file, or copy its content into this map?\r\n\r\n{0} ({1}) -DND_MultipleExternalFiles=Multiple External Files -DND_MultipleExternalFiles_moreFiles_with_number=and {0} more... -DND_MultipleExternalFiles_confirmation_with_fileList=Do you want to make links pointing to these files, or copy their contents into this map?\r\n\r\n{0}\r\n\r\nCAUTION: Copying multiple file contents will enlarge the file size. -DND_ConfirmDroppingFileDialog_title_with_type=XMind - Add {0} -DND_ConfirmDroppingFileDialog_LinkButton_text=Link -DND_ConfirmDroppingFileDialog_CopyButton_text=Copy -DND_ConfirmDroppingFileDialog_RememberCheck_text_with_type=Remember my decision for adding ''{0}'' - -ConfirmDeleteTemplateDialog_title=Delete Template -ConfirmDeleteTemplateDialog_message_with_templateName=You are deleting the template ''{0}''? - -ConfirmClearRecentFileListDialog_title=XMind - Clear Recent File List -ConfirmClearRecentFileListDialog_message=Are you sure you want to clear the history of recently opened workbooks? - -WorkbookMetaInspectorDialog_title=Inspector -ShareDialog_dialog_title=Share +CommonDialogTitle=XMind +Error_title=XMind - Error +MultipleErrors_title=XMind - Multiple Errors +Open_title=Open +Save_title=Save +ErrorOpen_title=XMind - Open +ErrorSave_title=XMind - Save + +ReduceFileSize_Advise_text=Select the content below to reduce this XMind file size. +DeleteEditingHistory_text=Delete editing history +DeletePreviewImage_text=Delete preview image +ReduceFileSize_text=Reduce File Size +ReduceAndSave_text=Reduce and Save + +WebHyperlinkPage_label=Enter a web location here, or paste one from a web browser: +WebHyperlinkPage_nullHyper_message=Hyperlink is null. +WorkbookFilterName=XMind Workbook +TemplateFilterName=XMind Template +OldWorkbookFilterName=XMIND 2008/2007 Workbook +AllSupportedFilesFilterName=All Supported Files +AllFilesFilterName=All Files +MarkerPackageFilterName=Marker Package + +ConfirmOverwrite_title=XMind - Confirm Overwrite +ConfirmOverwrite_message=The file already exists. Do you want to overwrite it?\n{0} + +ConfirmRestart_title=XMind - Confirm Restart +ConfirmRestart_message=This operation requires restarting to complete. Restart now? +ConfirmRestart_Restart=&Restart +ConfirmRestart_Continue=&Continue + +ConfirmWorkbookVersion_title=XMind - Confirm Workbook Version +ConfirmWorkbookVersion_message=''{0}'' seems to be produced by an old version of XMind. Do you want to save it as a file of the current version?\n\n(If you insist on keeping the file with that old format, try "Export" in "File" menu.) +ConfirmWorkbookVersion_SaveAs=&Save As... + +WorkbookRevisionDialog_title=Editing History ({0}) + +InfoFileNotExists_title=File Not Exists +InfoFileNotExists_message=This file seems not to exist.\r\n\r\n{0}\r\n\r\nStill try to open it? + +FailedToLoadWorkbook_message=Can''t load workbook from file: {0} +FailedToSaveWorkbook_message=Can''t save workbook to file: {0} + +CompatibilityWarning_title=Compatibility Warning +CompatibilityWarning_message=This file is produced by a former version of XMIND. + +HyperlinkDialog_windowTitle=Modify Topic Hyperlink +HyperlinkDialog_title=Modify Hyperlink +HyperlinkDialog_description=Select a type of hyperlink from the left, and fill the content on the right. +HyperlinkDialog_Remove=&Remove +HyperlinkDialog_MultipleTopics_message=Enter hyperlink location (multiple topics): +HyperlinkDialog_MultipleTopics_value=[ Multiple hyperlinks... ] +HyperlinkDialog_FailCreatePage_message=Failed to create this page... +NotesPopup_GotoNotesView_text=Press ''{0}'' to edit in Notes View + +SelectImageDialog_title=Select Image + +TemplateMissing_message=Oops, the template ''{0}'' seems missing.\n\nFor more information about this, please log on to ''www.xmind.net''. + +TopicHyperlinkPage_label=Insert a link to the topic selected below: + +PageSetupDialog_Content=Content +PageSetupDialog_PlusAndMinusIcons=Collapse && Expand Icons +PageSetupDialog_CurrentMap=Current Map +PageSetupDialog_WholeWorkbook=Whole Workbook +PageSetupDialog_HideBoth=Hide '-' and '+' +PageSetupDialog_ShowBoth=Show '-' and '+' +PageSetupDialog_HideMinusShowPlus=Hide '-' show '+' +PageSetupDialog_windowTitle=Page Setup +PageSetupDialog_title=Page Setup For Printing +PageSetupDialog_description=Adjust settings of the page on which the selected map will be printed. +PageSetupDialog_PageSetup=Page Setup +PageSetupDialog_Margins=Margins +PageSetupDialog_HeaderFooter=Header/Footer +PageSetupDialog_Background=Background +PageSetupDialog_Border=Border +PageSetupDialog_Left=Left: +PageSetupDialog_Right=Right: +PageSetupDialog_Top=Top: +PageSetupDialog_Bottom=Bottom: +PageSetupDialog_Inch=Inch +PageSetupDialog_Millimeter=Millimeter +PageSetupDialog_Header=Header: +PageSetupDialog_Footer=Footer: +PageSetupDialog_AlignLeft_text=Left +PageSetupDialog_AlignLeft_toolTip=Left +PageSetupDialog_AlignRight_text=Right +PageSetupDialog_AlignRight_toolTip=Right +PageSetupDialog_AlignCenter_text=Center +PageSetupDialog_AlignCenter_toolTip=Center +PageSetupDialog_Font_text=Font... +PageSetupDialog_Font_toolTip=Choose font from a font dialog +PageSetupDialog_JustForReference=* This preview is just for reference. +PageSetupDialog_Orientation=Orientation +PageSetupDialog_Landscape=Landscape +PageSetupDialog_Portrait=Portrait + +FindReplaceDialog_windowTitle=Find/Replace +FindReplaceDialog_Find_label=&Find: +FindReplaceDialog_ReplaceWith_label=&Replace With: +FindReplaceDialog_OptionGroup=Option +FindReplaceDialog_CaseSensitive=&Case Sensitive +FindReplaceDialog_WholeWord=&Whole Word +FindReplaceDialog_DirectionGroup=Direction +FindReplaceDialog_Forward=F&orward +FindReplaceDialog_Backward=&Backward +FindReplaceDialog_ScopeGroup=Scope +FindReplaceDialog_CurrentMap=Current &Map +FindReplaceDialog_Workbook=&Workbook +FindReplaceDialog_Find_text=Fi&nd +FindReplaceDialog_FindAll_text=Find &All +FindReplaceDialog_Replace_text=Replac&e +FindReplaceDialog_ReplaceAll_text=Re&place All +FindReplaceDialog_StringNotFound=String Not Found + +FileHyperlinkPage_ChooseFile_text=Choose a file +FileHyperlinkPage_ChooseFolder_text=Choose a folder +FileHyperlinkPage_FileNotExists_message=File not exists. +FileHyperlinkPage_RelativeWarning_message=The workbook has to be saved before choosing relative file hyperlink. +FileHyperlinkPage_label=Enter a path representing a folder or a file, or choose one from your local file system: +FileHyperlinkPage_OpenDirectoryDialog_windowTitle=Open +FileHyperlinkPage_OpenFileDialog_windowTitle=Open +FileHyperlinkPage_WarningDialog_message=Please click "OK" to save current file before finishing inserting the relative hyperlink. +FileHyperlinkPage_WarningDialog_Title=Insert Relative Hyperlink +FileHyperlinkPage_WarningDialog_OKButton_Label=OK +FileHyperlinkPage_WarningDialog_CancelButton_Label=Cancel +FileHyperlinkPage_HrefGroup_Text=Hyperlink type +FileHyperlinkPage_AbsoluteButton_Text=Absolute +FileHyperlinkPage_RelativeButton_Text=Relative +RevisionPreviewDialog_CorruptedRevision_message=Oops, this revision seems to have been corrupted. +RevisionPreviewDialog_CurrentRevision_title=Current Sheet - {0} +RevisionPreviewDialog_Revision_titlePattern=Preview( {0} ) +workbookRevisionDialog_Title_Label_text=Editing History +workbookRevisionDialog_Description_Label_text=Help restore the previous versions of the current XMind file. +WorkbookRevisionDialog_Preview_Button_label=Preview +WorkbookRevisionDialog_Restore_Button_label=Restore +WorkbookRevisionDialog_Disable_Label_text=Disable revision on this file +EnableRevisionDialog_Title_text=Enable Revision +EnableRevisionDialog_Confirm_message=The revision feature is turned off. If you would like to use this feature, please click "OK" to turn it on. +DisableRevisonDialog_Title_text=Disable Revision +DisableRevisonDialog_Comfirm_message=Are you sure disable revision on this file? +RevisionPreviewDialog_Restore_Label_text=Restore to Rev #{0} +RevisionPreviewDialog_Previous_Button_label=Previous +RevisionPreviewDialog_Next_Button_label=Next + + +SortMessageDialog_Messages=Fail to perform the 'sort' request, because some topics that are bound together obey the desired order. +SortMessageDialog_Title=Fail to Sort Topics + + +NewWorkbookWizardDialog_OpenExistingFile_text=Open an Existing File... +NewWorkbookWizardDialog_Choose_text=Choose + +TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_windowTitle=XMind - Invalid Topic Hyperlink +TopicProtocol_ConfirmDeleteInvalidTopicHyperlink_message=This topic seems to have been deleted. Do you want to delete this hyperlink as well? + +DND_ExternalFolder=External Folder +DND_ExternalFolder_confirmation_with_path=Do you want to make a link pointing to this folder, or copy all its contents (including all files and sub-folders) into this map?\r\n\r\n{0}\r\n\r\nCAUTION: Copying multiple file contents will enlarge the file size. +DND_ExternalFile=External File +DND_ExternalFile_confirmation_with_path_size=Do you want to make a link pointing to this file, or copy its content into this map?\r\n\r\n{0} ({1}) +DND_MultipleExternalFiles=Multiple External Files +DND_MultipleExternalFiles_moreFiles_with_number=and {0} more... +DND_MultipleExternalFiles_confirmation_with_fileList=Do you want to make links pointing to these files, or copy their contents into this map?\r\n\r\n{0}\r\n\r\nCAUTION: Copying multiple file contents will enlarge the file size. +DND_ConfirmDroppingFileDialog_title_with_type=XMind - Add {0} +DND_ConfirmDroppingFileDialog_LinkButton_text=Link +DND_ConfirmDroppingFileDialog_CopyButton_text=Copy +DND_ConfirmDroppingFileDialog_RememberCheck_text_with_type=Remember my decision for adding ''{0}'' + +ConfirmDeleteTemplateDialog_title=Delete Template +ConfirmDeleteTemplateDialog_message_with_templateName=You are deleting the template ''{0}''? + +ConfirmClearRecentFileListDialog_title=XMind - Clear Recent File List +ConfirmClearRecentFileListDialog_message=Are you sure you want to clear the history of recently opened workbooks? + +WorkbookMetaInspectorDialog_title=Inspector +ShareDialog_dialog_title=Share diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/ImageDndClient.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/ImageDndClient.java index 82be1afa5..572419718 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/ImageDndClient.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/ImageDndClient.java @@ -1,113 +1,113 @@ -package org.xmind.ui.internal.dnd; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.ImageTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.xmind.core.Core; -import org.xmind.core.IFileEntry; -import org.xmind.core.IImage; -import org.xmind.core.IManifest; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.ui.internal.AttachmentImageDescriptor; -import org.xmind.ui.util.Logger; - -public class ImageDndClient extends MindMapDNDClientBase { - - private ImageTransfer transfer = ImageTransfer.getInstance(); - - public Object getData(Transfer transfer, TransferData data) { - if (transfer == this.transfer) { - return this.transfer.nativeToJava(data); - } - return null; - } - - public Transfer getTransfer() { - return transfer; - } - - public Object toTransferData(Object[] viewerElements, IViewer viewer) { - if (viewerElements != null && viewerElements.length > 0) { - for (Object element : viewerElements) { - if (element instanceof IImage) { - IImage image = (IImage) element; - String source = image.getSource(); - if (source != null) { - if (HyperlinkUtils.isAttachmentURL(source)) { - String path = HyperlinkUtils - .toAttachmentPath(source); - ImageDescriptor imageDescriptor = AttachmentImageDescriptor - .createFromEntryPath( - image.getOwnedWorkbook(), path); - ImageData imageData = imageDescriptor - .getImageData(); - return imageData; - } - } - } - } - } - return null; - } - - @Override - protected Object[] toViewerElements(Object transferData, Request request, - IWorkbook workbook, ITopic targetParent, boolean dropInParent) { - if (transferData instanceof ImageData) { - if (workbook != null) { - ImageData imageData = (ImageData) transferData; - ImageLoader saver = new ImageLoader(); - saver.data = new ImageData[] { imageData }; - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - saver.save(os, SWT.IMAGE_PNG); - } finally { - try { - os.close(); - } catch (IOException e) { - } - } - byte[] imageDataInBytes = os.toByteArray(); - IManifest manifest = workbook.getManifest(); - try { - ByteArrayInputStream is = new ByteArrayInputStream( - imageDataInBytes); - IFileEntry entry; - try { - entry = manifest.createAttachmentFromStream(is, - "temp.png", Core.MEDIA_TYPE_IMAGE_PNG); //$NON-NLS-1$ - } finally { - is.close(); - } - String imageSource = HyperlinkUtils.toAttachmentURL(entry - .getPath()); - if (targetParent != null && dropInParent) { - return new Object[] { createModifyImageCommand( - targetParent, imageSource, IImage.UNSPECIFIED, - IImage.UNSPECIFIED, null) }; - } - ITopic topic = workbook.createTopic(); - topic.getImage().setSource(imageSource); - return new Object[] { topic }; - } catch (IOException e) { - Logger.log(e, - "[ImageDndClient] Failed to create image entry."); //$NON-NLS-1$ - } - } - } - return null; - } - -} +package org.xmind.ui.internal.dnd; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.ImageTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.xmind.core.Core; +import org.xmind.core.IFileEntry; +import org.xmind.core.IImage; +import org.xmind.core.IManifest; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.ui.internal.AttachmentImageDescriptor; +import org.xmind.ui.util.Logger; + +public class ImageDndClient extends MindMapDNDClientBase { + + private ImageTransfer transfer = ImageTransfer.getInstance(); + + public Object getData(Transfer transfer, TransferData data) { + if (transfer == this.transfer) { + return this.transfer.nativeToJava(data); + } + return null; + } + + public Transfer getTransfer() { + return transfer; + } + + public Object toTransferData(Object[] viewerElements, IViewer viewer) { + if (viewerElements != null && viewerElements.length > 0) { + for (Object element : viewerElements) { + if (element instanceof IImage) { + IImage image = (IImage) element; + String source = image.getSource(); + if (source != null) { + if (HyperlinkUtils.isAttachmentURL(source)) { + String path = HyperlinkUtils + .toAttachmentPath(source); + ImageDescriptor imageDescriptor = AttachmentImageDescriptor + .createFromEntryPath( + image.getOwnedWorkbook(), path); + ImageData imageData = imageDescriptor + .getImageData(); + return imageData; + } + } + } + } + } + return null; + } + + @Override + protected Object[] toViewerElements(Object transferData, Request request, + IWorkbook workbook, ITopic targetParent, boolean dropInParent) { + if (transferData instanceof ImageData) { + if (workbook != null) { + ImageData imageData = (ImageData) transferData; + ImageLoader saver = new ImageLoader(); + saver.data = new ImageData[] { imageData }; + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try { + saver.save(os, SWT.IMAGE_PNG); + } finally { + try { + os.close(); + } catch (IOException e) { + } + } + byte[] imageDataInBytes = os.toByteArray(); + IManifest manifest = workbook.getManifest(); + try { + ByteArrayInputStream is = new ByteArrayInputStream( + imageDataInBytes); + IFileEntry entry; + try { + entry = manifest.createAttachmentFromStream(is, + "temp.png", Core.MEDIA_TYPE_IMAGE_PNG); //$NON-NLS-1$ + } finally { + is.close(); + } + String imageSource = HyperlinkUtils.toAttachmentURL(entry + .getPath()); + if (targetParent != null && dropInParent) { + return new Object[] { createModifyImageCommand( + targetParent, imageSource, IImage.UNSPECIFIED, + IImage.UNSPECIFIED, null) }; + } + ITopic topic = workbook.createTopic(); + topic.getImage().setSource(imageSource); + return new Object[] { topic }; + } catch (IOException e) { + Logger.log(e, + "[ImageDndClient] Failed to create image entry."); //$NON-NLS-1$ + } + } + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapDNDClientBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapDNDClientBase.java index ffbfcd2ee..11c2916ac 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapDNDClientBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapDNDClientBase.java @@ -1,379 +1,379 @@ -package org.xmind.ui.internal.dnd; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.dnd.TransferData; -import org.xmind.core.IBoundary; -import org.xmind.core.IImage; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.ITopicRange; -import org.xmind.core.IWorkbook; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.gef.GEF; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.dnd.IDndClient; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.AddBoundaryCommand; -import org.xmind.ui.commands.AddMarkerCommand; -import org.xmind.ui.commands.AddRelationshipCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.DeleteMarkerCommand; -import org.xmind.ui.commands.ModifyFoldedCommand; -import org.xmind.ui.commands.ModifyImageAlignmentCommand; -import org.xmind.ui.commands.ModifyImageSizeCommand; -import org.xmind.ui.commands.ModifyImageSourceCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; -import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; -import org.xmind.ui.internal.branch.UnbalancedData; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.util.MindMapUtils; - -public abstract class MindMapDNDClientBase implements IDndClient { - - /** - * @deprecated - */ - public final Object[] toViewerElements(Object transferData, IViewer viewer, - Object target) { - return null; - } - - public Command makeDNDCommand(Object transferredData, Request request) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return null; - - ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); - if (sheet == null) - return null; - - IWorkbook workbook = sheet.getOwnedWorkbook(); - IPart parent = (IPart) request.getParameter(GEF.PARAM_PARENT); - if (parent != null || request.getTargets().size() == 1) { - boolean dropInParent = request.getTargets().contains(parent); - if (parent == null) { - parent = request.getPrimaryTarget(); - } - ITopic targetParent = findTargetParentTopic(viewer, parent); - return makeDNDCommand(transferredData, request, workbook, - targetParent, dropInParent, - request.getParameter(GEF.PARAM_PARENT) == null); - } else if (!request.getTargets().isEmpty()) { - List commands = new ArrayList(); - for (IPart target : request.getTargets()) { - ITopic targetParent = findTargetParentTopic(viewer, target); - if (targetParent != null) { - commands.add(makeDNDCommand(transferredData, request, - workbook, targetParent, false, false)); - } - } - return new CompoundCommand(commands); - } else { - return null; - } - } - - private ITopic findTargetParentTopic(IViewer viewer, IPart parent) { - Object targetParentModel = MindMapUtils.getRealModel(parent); - ITopic targetParent; - if (targetParentModel == null - || !(targetParentModel instanceof ITopic)) { - targetParent = (ITopic) viewer.getAdapter(ITopic.class); - } else { - targetParent = (ITopic) targetParentModel; - } - return targetParent; - } - - protected Command makeDNDCommand(Object transferData, Request request, - IWorkbook workbook, ITopic targetParent, boolean dropInParent, - boolean floating) { - Object[] elements = toViewerElements(transferData, request, workbook, - targetParent, dropInParent); - if (elements == null || elements.length == 0) - return null; - - List commands = new ArrayList(); - makeDNDCommands(request, workbook, targetParent, elements, commands, - floating, dropInParent); - - return new CompoundCommand(commands); - } - - protected void makeDNDCommands(Request request, IWorkbook workbook, - ITopic targetParent, Object[] elements, List commands, - boolean floating, boolean dropInParent) { - ISheet sheet = (ISheet) request.getTargetViewer() - .getAdapter(ISheet.class); - int index = request.getIntParameter(GEF.PARAM_INDEX, -1); - int sourceIndex = index; - Point position = (Point) request.getParameter(GEF.PARAM_POSITION); - - int countForUnbalacedStructure = 0; - - preAdded(targetParent, commands); - - for (Object element : elements) { - if (element instanceof Command) { - commands.add((Command) element); - } else if (element instanceof ITopic) { - if (targetParent != null) { - ITopic topic = (ITopic) element; - if (floating && position != null) { - topic.setPosition(position.x, position.y); - commands.add(new AddTopicCommand(topic, targetParent, - -1, ITopic.DETACHED)); - } else { - countForUnbalacedStructure = modifyRightNumeberForUnbalancedStructure( - request, targetParent, - countForUnbalacedStructure); - - topic.setPosition(null); - commands.add(new AddTopicCommand(topic, targetParent, - index, ITopic.ATTACHED)); - if (index >= 0) - index++; - } - } - } else if (element instanceof IRelationship) { - if (sheet != null) { - IRelationship relationship = (IRelationship) element; - commands.add( - new AddRelationshipCommand(relationship, sheet)); - } - } else if (element instanceof IBoundary) { - if (targetParent != null) { - IBoundary boundary = (IBoundary) element; - commands.add( - new AddBoundaryCommand(boundary, targetParent)); - } - } else if (element instanceof IMarkerRef - || element instanceof IMarker) { - if (targetParent != null) { - IMarker marker = (element instanceof IMarker) - ? (IMarker) element - : ((IMarkerRef) element).getMarker(); - if (marker != null) { - String markerId = (element instanceof IMarker) - ? ((IMarker) element).getId() - : ((IMarkerRef) element).getMarkerId(); - if (floating && position != null) { - ITopic topic = workbook.createTopic(); - topic.setPosition(position.x, position.y); - commands.add(new AddTopicCommand(topic, - targetParent, -1, ITopic.DETACHED)); - commands.add(new AddMarkerCommand(topic, markerId)); - return; - } else if (!dropInParent) { - ITopic topic = workbook.createTopic(); - commands.add(new AddTopicCommand(topic, - targetParent, index, ITopic.ATTACHED)); - commands.add(new AddMarkerCommand(topic, markerId)); - return; - } - IMarkerGroup group = marker.getParent(); - if (group.isSingleton()) { - for (IMarker m : group.getMarkers()) { - if (targetParent.hasMarker(m.getId())) { - commands.add(new DeleteMarkerCommand( - targetParent, m.getId())); - } - } - } - commands.add( - new AddMarkerCommand(targetParent, markerId)); - } - } - } else if (element instanceof IImage) { - IImage image = (IImage) element; - if (targetParent != null) { - commands.add(new ModifyImageSourceCommand(targetParent, - image.getSource())); - commands.add(new ModifyImageSizeCommand(targetParent, - image.getWidth(), image.getHeight())); - commands.add(new ModifyImageAlignmentCommand(targetParent, - image.getAlignment())); - } - } else if (element instanceof URI) { - URI uri = (URI) element; - if (targetParent != null) { - commands.add(new ModifyTopicHyperlinkCommand(targetParent, - uri.toString())); - } - } - } - - if (countForUnbalacedStructure != 0) { - IViewer viewer = request.getTargetViewer(); - ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - ITopicExtension extension = centralTopic.createExtension( - UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild( - UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - - String preDndRightNum = element.getTextContent(); - if (preDndRightNum == null) - preDndRightNum = String.valueOf(0); - int postDndRightNum = Integer.valueOf(preDndRightNum); - commands.add(new ModifyRightNumberOfUnbalancedStructureCommand( - centralTopic, preDndRightNum, - postDndRightNum + countForUnbalacedStructure)); - } - - postAdded(elements, targetParent, sourceIndex, floating, commands); - } - - private void preAdded(ITopic targetParent, List commands) { - ensureParentUnfolded(targetParent, commands); - } - - private void ensureParentUnfolded(ITopic targetParent, - List commands) { - if (targetParent.isFolded()) { - commands.add(new ModifyFoldedCommand(targetParent, false)); - } - } - - private void postAdded(Object[] elements, ITopic targetParent, - int sourceIndex, boolean floating, List commands) { - - boolean containsTopic = false; - for (Object object : elements) { - if (object instanceof ITopic) { - containsTopic = true; - break; - } - } - - if (containsTopic && !floating) { - if (sourceIndex >= 0) { - modifyRanges(targetParent, sourceIndex, commands); - } - } - } - - private void modifyRanges(ITopic targetParent, int sourceIndex, - List commands) { - modifyRanges(targetParent.getBoundaries(), sourceIndex, commands); - modifyRanges(targetParent.getSummaries(), sourceIndex, commands); - } - - private void modifyRanges(Collection ranges, - int sourceIndex, List commands) { - for (ITopicRange range : ranges) { - int startIndex = range.getStartIndex(); - int endIndex = range.getEndIndex(); - if (startIndex >= 0 && endIndex >= 0) { - if (startIndex >= sourceIndex) { - commands.add(new ModifyRangeCommand(range, startIndex + 1, - true)); - } - if (endIndex >= sourceIndex) { - commands.add( - new ModifyRangeCommand(range, endIndex + 1, false)); - } - } - } - } - - private int modifyRightNumeberForUnbalancedStructure(Request request, - ITopic targetParent, int count) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return count; - - ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - if (centralTopic == targetParent) { - String centralTopicStructure = centralTopic.getStructureClass(); - boolean isUnbalancedStructure = centralTopicStructure == null - || UnbalancedData.STRUCTUREID_UNBALANCED - .equalsIgnoreCase(centralTopicStructure); - - if (isUnbalancedStructure) { - ITopicExtension extension = centralTopic.createExtension( - UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild( - UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - - String preDndRightNum = element.getTextContent(); - if (preDndRightNum == null) - preDndRightNum = String.valueOf(0); - int postDndRightNum = Integer.valueOf(preDndRightNum); - - ITopicPart parentPart = (ITopicPart) request - .getParameter(GEF.PARAM_PARENT); - if (parentPart != null || postDndRightNum <= 2) { - if (parentPart != null) { - Rectangle bounds = parentPart.getFigure().getBounds(); - if (bounds.getCenter() - .getDifference((Point) request.getParameter( - GEF.PARAM_POSITION_ABSOLUTE)).width < 0) { - count++; - } - } else if (postDndRightNum <= 2) { - count++; - } - - } - } - } - return count; - } - - protected Command createModifyImageCommand(ITopic target, String source, - int width, int height, String alignment) { - List commands = new ArrayList(3); - commands.add(new ModifyImageSourceCommand(target, source)); - commands.add(new ModifyImageSizeCommand(target, width, height)); - commands.add(new ModifyImageAlignmentCommand(target, alignment)); - return new CompoundCommand(commands); - } - - /** - * Subclasses may override this method. - * - * @param transferData - * @param request - * @param workbook - * @param targetParent - * @param dropInParent - * TODO - * @return - */ - protected abstract Object[] toViewerElements(Object transferData, - Request request, IWorkbook workbook, ITopic targetParent, - boolean dropInParent); - - public boolean canCopy(TransferData transferData, IViewer viewer, - Point location, IPart target) { - return true; - } - - public boolean canLink(TransferData data, IViewer viewer, Point location, - IPart target) { - return false; - } - - public boolean canMove(TransferData data, IViewer viewer, Point location, - IPart target) { - return true; - } - -} +package org.xmind.ui.internal.dnd; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.dnd.TransferData; +import org.xmind.core.IBoundary; +import org.xmind.core.IImage; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.ITopicRange; +import org.xmind.core.IWorkbook; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.dnd.IDndClient; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.AddBoundaryCommand; +import org.xmind.ui.commands.AddMarkerCommand; +import org.xmind.ui.commands.AddRelationshipCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.commands.ModifyFoldedCommand; +import org.xmind.ui.commands.ModifyImageAlignmentCommand; +import org.xmind.ui.commands.ModifyImageSizeCommand; +import org.xmind.ui.commands.ModifyImageSourceCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; +import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; +import org.xmind.ui.internal.branch.UnbalancedData; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.util.MindMapUtils; + +public abstract class MindMapDNDClientBase implements IDndClient { + + /** + * @deprecated + */ + public final Object[] toViewerElements(Object transferData, IViewer viewer, + Object target) { + return null; + } + + public Command makeDNDCommand(Object transferredData, Request request) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return null; + + ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); + if (sheet == null) + return null; + + IWorkbook workbook = sheet.getOwnedWorkbook(); + IPart parent = (IPart) request.getParameter(GEF.PARAM_PARENT); + if (parent != null || request.getTargets().size() == 1) { + if (parent == null) { + parent = request.getPrimaryTarget(); + } + boolean dropInParent = request.getTargets().contains(parent); + ITopic targetParent = findTargetParentTopic(viewer, parent); + return makeDNDCommand(transferredData, request, workbook, + targetParent, dropInParent, + request.getParameter(GEF.PARAM_PARENT) == null); + } else if (!request.getTargets().isEmpty()) { + List commands = new ArrayList(); + for (IPart target : request.getTargets()) { + ITopic targetParent = findTargetParentTopic(viewer, target); + if (targetParent != null) { + commands.add(makeDNDCommand(transferredData, request, + workbook, targetParent, false, false)); + } + } + return new CompoundCommand(commands); + } else { + return null; + } + } + + private ITopic findTargetParentTopic(IViewer viewer, IPart parent) { + Object targetParentModel = MindMapUtils.getRealModel(parent); + ITopic targetParent; + if (targetParentModel == null + || !(targetParentModel instanceof ITopic)) { + targetParent = (ITopic) viewer.getAdapter(ITopic.class); + } else { + targetParent = (ITopic) targetParentModel; + } + return targetParent; + } + + protected Command makeDNDCommand(Object transferData, Request request, + IWorkbook workbook, ITopic targetParent, boolean dropInParent, + boolean floating) { + Object[] elements = toViewerElements(transferData, request, workbook, + targetParent, dropInParent); + if (elements == null || elements.length == 0) + return null; + + List commands = new ArrayList(); + makeDNDCommands(request, workbook, targetParent, elements, commands, + floating, dropInParent); + + return new CompoundCommand(commands); + } + + protected void makeDNDCommands(Request request, IWorkbook workbook, + ITopic targetParent, Object[] elements, List commands, + boolean floating, boolean dropInParent) { + ISheet sheet = (ISheet) request.getTargetViewer() + .getAdapter(ISheet.class); + int index = request.getIntParameter(GEF.PARAM_INDEX, -1); + int sourceIndex = index; + Point position = (Point) request.getParameter(GEF.PARAM_POSITION); + + int countForUnbalacedStructure = 0; + + preAdded(targetParent, commands); + + for (Object element : elements) { + if (element instanceof Command) { + commands.add((Command) element); + } else if (element instanceof ITopic) { + if (targetParent != null) { + ITopic topic = (ITopic) element; + if (floating && position != null) { + topic.setPosition(position.x, position.y); + commands.add(new AddTopicCommand(topic, targetParent, + -1, ITopic.DETACHED)); + } else { + countForUnbalacedStructure = modifyRightNumeberForUnbalancedStructure( + request, targetParent, + countForUnbalacedStructure); + + topic.setPosition(null); + commands.add(new AddTopicCommand(topic, targetParent, + index, ITopic.ATTACHED)); + if (index >= 0) + index++; + } + } + } else if (element instanceof IRelationship) { + if (sheet != null) { + IRelationship relationship = (IRelationship) element; + commands.add( + new AddRelationshipCommand(relationship, sheet)); + } + } else if (element instanceof IBoundary) { + if (targetParent != null) { + IBoundary boundary = (IBoundary) element; + commands.add( + new AddBoundaryCommand(boundary, targetParent)); + } + } else if (element instanceof IMarkerRef + || element instanceof IMarker) { + if (targetParent != null) { + IMarker marker = (element instanceof IMarker) + ? (IMarker) element + : ((IMarkerRef) element).getMarker(); + if (marker != null) { + String markerId = (element instanceof IMarker) + ? ((IMarker) element).getId() + : ((IMarkerRef) element).getMarkerId(); + if (floating && position != null) { + ITopic topic = workbook.createTopic(); + topic.setPosition(position.x, position.y); + commands.add(new AddTopicCommand(topic, + targetParent, -1, ITopic.DETACHED)); + commands.add(new AddMarkerCommand(topic, markerId)); + return; + } else if (!dropInParent) { + ITopic topic = workbook.createTopic(); + commands.add(new AddTopicCommand(topic, + targetParent, index, ITopic.ATTACHED)); + commands.add(new AddMarkerCommand(topic, markerId)); + return; + } + IMarkerGroup group = marker.getParent(); + if (group.isSingleton()) { + for (IMarker m : group.getMarkers()) { + if (targetParent.hasMarker(m.getId())) { + commands.add(new DeleteMarkerCommand( + targetParent, m.getId())); + } + } + } + commands.add( + new AddMarkerCommand(targetParent, markerId)); + } + } + } else if (element instanceof IImage) { + IImage image = (IImage) element; + if (targetParent != null) { + commands.add(new ModifyImageSourceCommand(targetParent, + image.getSource())); + commands.add(new ModifyImageSizeCommand(targetParent, + image.getWidth(), image.getHeight())); + commands.add(new ModifyImageAlignmentCommand(targetParent, + image.getAlignment())); + } + } else if (element instanceof URI) { + URI uri = (URI) element; + if (targetParent != null) { + commands.add(new ModifyTopicHyperlinkCommand(targetParent, + uri.toString())); + } + } + } + + if (countForUnbalacedStructure != 0) { + IViewer viewer = request.getTargetViewer(); + ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild( + UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + + String preDndRightNum = element.getTextContent(); + if (preDndRightNum == null) + preDndRightNum = String.valueOf(0); + int postDndRightNum = Integer.valueOf(preDndRightNum); + commands.add(new ModifyRightNumberOfUnbalancedStructureCommand( + centralTopic, preDndRightNum, + postDndRightNum + countForUnbalacedStructure)); + } + + postAdded(elements, targetParent, sourceIndex, floating, commands); + } + + private void preAdded(ITopic targetParent, List commands) { + ensureParentUnfolded(targetParent, commands); + } + + private void ensureParentUnfolded(ITopic targetParent, + List commands) { + if (targetParent.isFolded()) { + commands.add(new ModifyFoldedCommand(targetParent, false)); + } + } + + private void postAdded(Object[] elements, ITopic targetParent, + int sourceIndex, boolean floating, List commands) { + + boolean containsTopic = false; + for (Object object : elements) { + if (object instanceof ITopic) { + containsTopic = true; + break; + } + } + + if (containsTopic && !floating) { + if (sourceIndex >= 0) { + modifyRanges(targetParent, sourceIndex, commands); + } + } + } + + private void modifyRanges(ITopic targetParent, int sourceIndex, + List commands) { + modifyRanges(targetParent.getBoundaries(), sourceIndex, commands); + modifyRanges(targetParent.getSummaries(), sourceIndex, commands); + } + + private void modifyRanges(Collection ranges, + int sourceIndex, List commands) { + for (ITopicRange range : ranges) { + int startIndex = range.getStartIndex(); + int endIndex = range.getEndIndex(); + if (startIndex >= 0 && endIndex >= 0) { + if (startIndex >= sourceIndex) { + commands.add(new ModifyRangeCommand(range, startIndex + 1, + true)); + } + if (endIndex >= sourceIndex) { + commands.add( + new ModifyRangeCommand(range, endIndex + 1, false)); + } + } + } + } + + private int modifyRightNumeberForUnbalancedStructure(Request request, + ITopic targetParent, int count) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return count; + + ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); + if (centralTopic == targetParent) { + String centralTopicStructure = centralTopic.getStructureClass(); + boolean isUnbalancedStructure = centralTopicStructure == null + || UnbalancedData.STRUCTUREID_UNBALANCED + .equalsIgnoreCase(centralTopicStructure); + + if (isUnbalancedStructure) { + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild( + UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + + String preDndRightNum = element.getTextContent(); + if (preDndRightNum == null) + preDndRightNum = String.valueOf(0); + int postDndRightNum = Integer.valueOf(preDndRightNum); + + ITopicPart parentPart = (ITopicPart) request + .getParameter(GEF.PARAM_PARENT); + if (parentPart != null || postDndRightNum <= 2) { + if (parentPart != null) { + Rectangle bounds = parentPart.getFigure().getBounds(); + if (bounds.getCenter() + .getDifference((Point) request.getParameter( + GEF.PARAM_POSITION_ABSOLUTE)).width < 0) { + count++; + } + } else if (postDndRightNum <= 2) { + count++; + } + + } + } + } + return count; + } + + protected Command createModifyImageCommand(ITopic target, String source, + int width, int height, String alignment) { + List commands = new ArrayList(3); + commands.add(new ModifyImageSourceCommand(target, source)); + commands.add(new ModifyImageSizeCommand(target, width, height)); + commands.add(new ModifyImageAlignmentCommand(target, alignment)); + return new CompoundCommand(commands); + } + + /** + * Subclasses may override this method. + * + * @param transferData + * @param request + * @param workbook + * @param targetParent + * @param dropInParent + * TODO + * @return + */ + protected abstract Object[] toViewerElements(Object transferData, + Request request, IWorkbook workbook, ITopic targetParent, + boolean dropInParent); + + public boolean canCopy(TransferData transferData, IViewer viewer, + Point location, IPart target) { + return true; + } + + public boolean canLink(TransferData data, IViewer viewer, Point location, + IPart target) { + return false; + } + + public boolean canMove(TransferData data, IViewer viewer, Point location, + IPart target) { + return true; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapElementTransfer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapElementTransfer.java index 1674ac4ff..c01c407b8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapElementTransfer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/MindMapElementTransfer.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dnd; - -import java.io.File; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.swt.dnd.ByteArrayTransfer; -import org.eclipse.swt.dnd.TransferData; -import org.xmind.core.Core; -import org.xmind.core.ICloneData; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.dom.MarkerSheetImpl; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.mindmap.MindMapUI; - -public class MindMapElementTransfer extends ByteArrayTransfer { - - private static final MindMapElementTransfer instance = new MindMapElementTransfer(); - - private static final String TYPE_NAME = "mindmap-element-transfer-format:" //$NON-NLS-1$ - + System.currentTimeMillis() + ":" + instance.hashCode(); //$NON-NLS-1$ - - private static final int TYPE_ID = registerType(TYPE_NAME); - - private Object[] elements = null; - - private IWorkbook tempWorkbook = null; - - private Map cloneMap = new HashMap(); - - protected MindMapElementTransfer() { - } - - public static MindMapElementTransfer getInstance() { - return instance; - } - - protected int[] getTypeIds() { - return new int[] { TYPE_ID }; - } - - protected String[] getTypeNames() { - return new String[] { TYPE_NAME }; - } - - public void javaToNative(Object object, TransferData transferData) { - if (!(object instanceof Object[])) { - setElements(null); - return; - } - - setElements((Object[]) object); - if (getElements() == null) - return; - - byte[] check = TYPE_NAME.getBytes(); - super.javaToNative(check, transferData); - } - - public Object nativeToJava(TransferData transferData) { - Object object = super.nativeToJava(transferData); - return object == null ? null : elements; - } - - boolean checkType(Object object) { - if (!(object instanceof Object[])) - return false; - Object[] eles = (Object[]) object; - return eles.length > 0; - } - - @Override - protected boolean validate(Object object) { - return checkType(object); - } - - public void setElements(Object[] elements) { - this.elements = recreateElements(elements); - } - - public Object[] getElements() { - return elements; - } - - private Object[] recreateElements(Object[] elements) { - tempWorkbook = recreateTempWorkbook(); - if (elements == null || elements.length == 0) - return null; - - ICloneData result = tempWorkbook.clone(Arrays.asList(elements)); - Collection cloneds = result.getCloneds(); - if (!cloneds.isEmpty()) { - for (Object element : elements) { - if (element instanceof IMarkerRef) { - IMarkerRef ref = (IMarkerRef) element; - ((MarkerSheetImpl) tempWorkbook.getMarkerSheet()) - .getElementRegistry().register(ref.getMarker()); - } - } - fillCloneMap(result, elements); - return cloneds.toArray(); - } - return null; - } - - private void fillCloneMap(ICloneData result, Object[] elements) { - if (!cloneMap.isEmpty()) - cloneMap.clear(); - for (Object obj : elements) { - Object cloned = result.get(obj); - cloneMap.put(cloned, obj); - } - } - - public Map getTransferMap() { - return cloneMap; - } - - private IWorkbook recreateTempWorkbook() { - String tempDir = Core.getWorkspace().getTempDir("element_transfer" //$NON-NLS-1$ - + MindMapUI.FILE_EXT_XMIND_TEMP); - File tempLocation = new File(tempDir); - FileUtils.delete(tempLocation); - tempLocation.mkdirs(); - IWorkbook workbook = Core.getWorkbookBuilder() - .createWorkbook(new DirectoryStorage(tempLocation)); - workbook.getMarkerSheet().setParentSheet( - MindMapUI.getResourceManager().getSystemMarkerSheet()); - try { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.serialize(null); - } catch (Exception e) { - } - return workbook; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dnd; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; +import org.xmind.core.Core; +import org.xmind.core.ICloneData; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.dom.MarkerSheetImpl; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.mindmap.MindMapUI; + +public class MindMapElementTransfer extends ByteArrayTransfer { + + private static final MindMapElementTransfer instance = new MindMapElementTransfer(); + + private static final String TYPE_NAME = "mindmap-element-transfer-format:" //$NON-NLS-1$ + + System.currentTimeMillis() + ":" + instance.hashCode(); //$NON-NLS-1$ + + private static final int TYPE_ID = registerType(TYPE_NAME); + + private Object[] elements = null; + + private IWorkbook tempWorkbook = null; + + private Map cloneMap = new HashMap(); + + protected MindMapElementTransfer() { + } + + public static MindMapElementTransfer getInstance() { + return instance; + } + + protected int[] getTypeIds() { + return new int[] { TYPE_ID }; + } + + protected String[] getTypeNames() { + return new String[] { TYPE_NAME }; + } + + public void javaToNative(Object object, TransferData transferData) { + if (!(object instanceof Object[])) { + setElements(null); + return; + } + + setElements((Object[]) object); + if (getElements() == null) + return; + + byte[] check = TYPE_NAME.getBytes(); + super.javaToNative(check, transferData); + } + + public Object nativeToJava(TransferData transferData) { + Object object = super.nativeToJava(transferData); + return object == null ? null : elements; + } + + boolean checkType(Object object) { + if (!(object instanceof Object[])) + return false; + Object[] eles = (Object[]) object; + return eles.length > 0; + } + + @Override + protected boolean validate(Object object) { + return checkType(object); + } + + public void setElements(Object[] elements) { + this.elements = recreateElements(elements); + } + + public Object[] getElements() { + return elements; + } + + private Object[] recreateElements(Object[] elements) { + tempWorkbook = recreateTempWorkbook(); + if (elements == null || elements.length == 0) + return null; + + ICloneData result = tempWorkbook.clone(Arrays.asList(elements)); + Collection cloneds = result.getCloneds(); + if (!cloneds.isEmpty()) { + for (Object element : elements) { + if (element instanceof IMarkerRef) { + IMarkerRef ref = (IMarkerRef) element; + ((MarkerSheetImpl) tempWorkbook.getMarkerSheet()) + .getElementRegistry().register(ref.getMarker()); + } + } + fillCloneMap(result, elements); + return cloneds.toArray(); + } + return null; + } + + private void fillCloneMap(ICloneData result, Object[] elements) { + if (!cloneMap.isEmpty()) + cloneMap.clear(); + for (Object obj : elements) { + Object cloned = result.get(obj); + cloneMap.put(cloned, obj); + } + } + + public Map getTransferMap() { + return cloneMap; + } + + private IWorkbook recreateTempWorkbook() { + String tempDir = Core.getWorkspace().getTempDir("element_transfer" //$NON-NLS-1$ + + MindMapUI.FILE_EXT_XMIND_TEMP); + File tempLocation = new File(tempDir); + FileUtils.delete(tempLocation); + tempLocation.mkdirs(); + IWorkbook workbook = Core.getWorkbookBuilder() + .createWorkbook(new DirectoryStorage(tempLocation)); + workbook.getMarkerSheet().setParentSheet( + MindMapUI.getResourceManager().getSystemMarkerSheet()); + try { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.serialize(null); + } catch (Exception e) { + } + return workbook; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/TextDndClient.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/TextDndClient.java index 5a9a5c91b..a536c1d4c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/TextDndClient.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/TextDndClient.java @@ -1,167 +1,167 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dnd; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.ui.util.MindMapUtils; - -public class TextDndClient extends MindMapDNDClientBase { - - private static final String LINE_DELIMITER = System - .getProperty("line.separator"); //$NON-NLS-1$ - - private TextTransfer transfer = TextTransfer.getInstance(); - - public Object toTransferData(Object[] viewerElements, IViewer viewer) { - StringBuilder sb = new StringBuilder(viewerElements.length * 10); - for (Object element : viewerElements) { - append(sb, element); - } - if (sb.length() == 0) - sb.append(' '); - return sb.toString(); - } - - private void append(StringBuilder sb, Object element) { - if (element instanceof ITopic) { - appendTopic(sb, (ITopic) element); - } else { - String text = toText(element); - if (text != null) { - if (sb.length() > 0) { - sb.append(LINE_DELIMITER); - } - sb.append(text); - } - } - } - - private void appendTopic(StringBuilder sb, ITopic topic) { - appendTopic(sb, topic, 0); - } - - private void appendTopic(StringBuilder sb, ITopic topic, int level) { - if (sb.length() > 0) { - sb.append(LINE_DELIMITER); - } - for (int i = 0; i < level; i++) { - sb.append('\t'); - } - sb.append(topic.getTitleText()); - List children = topic.getAllChildren(); - if (!children.isEmpty()) { - int nextLevel = level + 1; - for (ITopic c : children) { - appendTopic(sb, c, nextLevel); - } - } - } - - private String toText(Object element) { - return MindMapUtils.getText(element, null); - } - - @Override - protected Object[] toViewerElements(Object transferData, Request request, - IWorkbook workbook, ITopic targetParent, boolean dropInParent) { - if (transferData instanceof String) { - String text = (String) transferData; - if (workbook != null) { - return buildeTopics(text, workbook); - } - return new Object[] { text }; - } - return null; - } - - private Object[] buildeTopics(String text, IWorkbook wb) { - String[] lines = text.split("\\r\\n|\\r|\\n"); //$NON-NLS-1$ - ArrayList topics = new ArrayList(lines.length); - HashMap map = new HashMap(); - ITopic lastTopic = null; - int topLevel = -1; - for (String line : lines) { - ITopic topic = wb.createTopic(); - - int level = 0; - for (int i = 0; i < line.length(); i++) { - char c = line.charAt(i); - if (c == '\t') { - level++; - } else { - break; - } - } - String title = line.substring(level); - topic.setTitleText(title); - - if (topLevel < 0 || level <= topLevel || lastTopic == null) { - topLevel = level; - topics.add(topic); - } else { - int lastLevel = map.get(lastTopic); - ITopic parent = null; - if (level > lastLevel) { - parent = lastTopic; - } else { - while (true) { - if (level == lastLevel) { - ITopic tempTopic = lastTopic.getParent(); - if (tempTopic != null) { - parent = tempTopic; - break; - } - } else if (level < lastLevel) { - ITopic tempTopic = lastTopic.getParent(); - if (tempTopic != null) { - lastLevel = map.get(tempTopic); - lastTopic = tempTopic; - } - } else { //if (level>lastLevel) - parent = lastTopic; - break; - } - } - } - if (parent != null) { - parent.add(topic); - } - } - lastTopic = topic; - map.put(topic, level); - } - return topics.toArray(); - } - - public Object getData(Transfer transfer, TransferData data) { - if (transfer == this.transfer) - return this.transfer.nativeToJava(data); - return null; - } - - public Transfer getTransfer() { - return transfer; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dnd; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.ui.util.MindMapUtils; + +public class TextDndClient extends MindMapDNDClientBase { + + private static final String LINE_DELIMITER = System + .getProperty("line.separator"); //$NON-NLS-1$ + + private TextTransfer transfer = TextTransfer.getInstance(); + + public Object toTransferData(Object[] viewerElements, IViewer viewer) { + StringBuilder sb = new StringBuilder(viewerElements.length * 10); + for (Object element : viewerElements) { + append(sb, element); + } + if (sb.length() == 0) + sb.append(' '); + return sb.toString(); + } + + private void append(StringBuilder sb, Object element) { + if (element instanceof ITopic) { + appendTopic(sb, (ITopic) element); + } else { + String text = toText(element); + if (text != null) { + if (sb.length() > 0) { + sb.append(LINE_DELIMITER); + } + sb.append(text); + } + } + } + + private void appendTopic(StringBuilder sb, ITopic topic) { + appendTopic(sb, topic, 0); + } + + private void appendTopic(StringBuilder sb, ITopic topic, int level) { + if (sb.length() > 0) { + sb.append(LINE_DELIMITER); + } + for (int i = 0; i < level; i++) { + sb.append('\t'); + } + sb.append(topic.getTitleText()); + List children = topic.getAllChildren(); + if (!children.isEmpty()) { + int nextLevel = level + 1; + for (ITopic c : children) { + appendTopic(sb, c, nextLevel); + } + } + } + + private String toText(Object element) { + return MindMapUtils.getText(element, null); + } + + @Override + protected Object[] toViewerElements(Object transferData, Request request, + IWorkbook workbook, ITopic targetParent, boolean dropInParent) { + if (transferData instanceof String) { + String text = (String) transferData; + if (workbook != null) { + return buildeTopics(text, workbook); + } + return new Object[] { text }; + } + return null; + } + + private Object[] buildeTopics(String text, IWorkbook wb) { + String[] lines = text.split("\\r\\n|\\r|\\n"); //$NON-NLS-1$ + ArrayList topics = new ArrayList(lines.length); + HashMap map = new HashMap(); + ITopic lastTopic = null; + int topLevel = -1; + for (String line : lines) { + ITopic topic = wb.createTopic(); + + int level = 0; + for (int i = 0; i < line.length(); i++) { + char c = line.charAt(i); + if (c == '\t') { + level++; + } else { + break; + } + } + String title = line.substring(level); + topic.setTitleText(title); + + if (topLevel < 0 || level <= topLevel || lastTopic == null) { + topLevel = level; + topics.add(topic); + } else { + int lastLevel = map.get(lastTopic); + ITopic parent = null; + if (level > lastLevel) { + parent = lastTopic; + } else { + while (true) { + if (level == lastLevel) { + ITopic tempTopic = lastTopic.getParent(); + if (tempTopic != null) { + parent = tempTopic; + break; + } + } else if (level < lastLevel) { + ITopic tempTopic = lastTopic.getParent(); + if (tempTopic != null) { + lastLevel = map.get(tempTopic); + lastTopic = tempTopic; + } + } else { //if (level>lastLevel) + parent = lastTopic; + break; + } + } + } + if (parent != null) { + parent.add(topic); + } + } + lastTopic = topic; + map.put(topic, level); + } + return topics.toArray(); + } + + public Object getData(Transfer transfer, TransferData data) { + if (transfer == this.transfer) + return this.transfer.nativeToJava(data); + return null; + } + + public Transfer getTransfer() { + return transfer; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/URLDndClient.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/URLDndClient.java index b0834fb88..8041f2b6c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/URLDndClient.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/URLDndClient.java @@ -1,95 +1,95 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.dnd; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.dnd.URLTransfer; -import org.xmind.core.IImage; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.ui.util.ImageFormat; -import org.xmind.ui.util.Logger; - -public class URLDndClient extends MindMapDNDClientBase { - - private URLTransfer transfer = URLTransfer.getInstance(); - - public Object getData(Transfer transfer, TransferData data) { - if (transfer == this.transfer) - return this.transfer.nativeToJava(data); - return null; - } - - public Transfer getTransfer() { - return transfer; - } - - public Object toTransferData(Object[] viewerElements, IViewer viewer) { - return null; - } - - @Override - protected Object[] toViewerElements(Object transferData, Request request, - IWorkbook workbook, ITopic targetParent, boolean dropInParent) { - String url = (String) transferData; - if (workbook != null) { - try { - URI uri = new URI(url); - if (targetParent != null && dropInParent) { - if (isImageURL(uri)) { - return new Object[] { createModifyImageCommand( - targetParent, uri.toString(), - IImage.UNSPECIFIED, IImage.UNSPECIFIED, null) }; - } else { - return new Object[] { uri }; - } - } else { - ITopic topic = workbook.createTopic(); - if (isImageURL(uri)) { - topic.getImage().setSource(uri.toString()); - } else { - topic.setTitleText(url); - topic.setHyperlink(url); - } - return new Object[] { topic }; - } - } catch (URISyntaxException e) { - Logger.log("[URLDndClient] Failed to parse invalid URL: " + url); //$NON-NLS-1$ - } - } - return null; - } - - private boolean isImageURL(URI uri) { - String path = uri.getPath(); - if (path == null) - return false; - return ImageFormat.findByExtension(FileUtils.getExtension(path), null) != null; - } - - @Override - public boolean canLink(TransferData data, IViewer viewer, Point location, - IPart target) { - return true; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.dnd; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.dnd.URLTransfer; +import org.xmind.core.IImage; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.ui.util.ImageFormat; +import org.xmind.ui.util.Logger; + +public class URLDndClient extends MindMapDNDClientBase { + + private URLTransfer transfer = URLTransfer.getInstance(); + + public Object getData(Transfer transfer, TransferData data) { + if (transfer == this.transfer) + return this.transfer.nativeToJava(data); + return null; + } + + public Transfer getTransfer() { + return transfer; + } + + public Object toTransferData(Object[] viewerElements, IViewer viewer) { + return null; + } + + @Override + protected Object[] toViewerElements(Object transferData, Request request, + IWorkbook workbook, ITopic targetParent, boolean dropInParent) { + String url = (String) transferData; + if (workbook != null) { + try { + URI uri = new URI(url); + if (targetParent != null && dropInParent) { + if (isImageURL(uri)) { + return new Object[] { createModifyImageCommand( + targetParent, uri.toString(), + IImage.UNSPECIFIED, IImage.UNSPECIFIED, null) }; + } else { + return new Object[] { uri }; + } + } else { + ITopic topic = workbook.createTopic(); + if (isImageURL(uri)) { + topic.getImage().setSource(uri.toString()); + } else { + topic.setTitleText(url); + topic.setHyperlink(url); + } + return new Object[] { topic }; + } + } catch (URISyntaxException e) { + Logger.log("[URLDndClient] Failed to parse invalid URL: " + url); //$NON-NLS-1$ + } + } + return null; + } + + private boolean isImageURL(URI uri) { + String path = uri.getPath(); + if (path == null) + return false; + return ImageFormat.findByExtension(FileUtils.getExtension(path), null) != null; + } + + @Override + public boolean canLink(TransferData data, IViewer viewer, Point location, + IPart target) { + return true; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DeleteResourceHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DeleteResourceHandler.java index 5799171cd..fa6eded59 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DeleteResourceHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DeleteResourceHandler.java @@ -1,29 +1,29 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.xmind.ui.internal.e4models.IContextRunnable; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; - -public class DeleteResourceHandler { - private IContextRunnable deleteRunnable; - - @Execute - public void execute() { - if (deleteRunnable != null) { - deleteRunnable.run(); - } - } - - @CanExecute - public boolean canExecute(IEclipseContext context) { - deleteRunnable = E4Utils.getContextRunnable(context, - IModelConstants.KEY_MODEL_PART_DELETE); - return deleteRunnable != null && deleteRunnable.canExecute(context, - IModelConstants.KEY_MODEL_PART_DELETE); - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class DeleteResourceHandler { + private IContextRunnable deleteRunnable; + + @Execute + public void execute() { + if (deleteRunnable != null) { + deleteRunnable.run(); + } + } + + @CanExecute + public boolean canExecute(IEclipseContext context) { + deleteRunnable = E4Utils.getContextRunnable(context, + IModelConstants.KEY_MODEL_PART_DELETE); + return deleteRunnable != null && deleteRunnable.canExecute(context, + IModelConstants.KEY_MODEL_PART_DELETE); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DialogPartHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DialogPartHandler.java index 9ce011baa..b3215d9ff 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DialogPartHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DialogPartHandler.java @@ -1,148 +1,154 @@ -package org.xmind.ui.internal.e4handlers; - -import java.util.Arrays; -import java.util.List; - -import javax.inject.Named; - -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; -import org.eclipse.e4.ui.model.application.ui.basic.MDialog; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.osgi.framework.FrameworkUtil; -import org.xmind.ui.internal.e4models.IModelConstants; - -public class DialogPartHandler { - - private static final String DIALOG_PREFIX = "DIALOG:"; //$NON-NLS-1$ - - private static final int DEFAULT_DIALOG_Y = 0; - private static final int DEFAULT_DIALOG_X = 0; - private static final int DEFAULT_DIALOG_WIDTH = 800; - private static final int DEFAULT_DIALOG_HEIGHT = 600; - - @Execute - public void run(EPartService ps, MApplication appli, - EModelService modelService, - @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, - @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID) String pageId) { - if (partId == null) - return; - - MPartDescriptor partDescriptor = null; - for (MPartDescriptor mp : appli.getDescriptors()) { - if (partId.equals(mp.getElementId())) { - partDescriptor = mp; - break; - } - } - if (partDescriptor == null) - return; - - List existingDialogs = modelService.findElements(appli, - DIALOG_PREFIX + partId, MDialog.class, null); - boolean dialogExisted = !existingDialogs.isEmpty(); - MDialog dialogModel = dialogExisted ? existingDialogs.get(0) - : createDialog(modelService, partDescriptor, partId); - configDialog(dialogModel, partDescriptor); - - MPart p = ps.findPart(partId); - if (p == null) { - p = ps.createPart(partId); - dialogModel.getChildren().add(p); - dialogModel.setSelectedElement(p); - } - - if (!dialogExisted) { - appli.getChildren().get(0).getWindows().add(dialogModel); - } - - if (pageId != null) { - p.getPersistedState().put( - IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, pageId); - } - - p.setVisible(true); - - modelService.bringToTop(p); - ps.activate(p, true); - - } - - private MDialog createDialog(EModelService modelService, - MPartDescriptor partDescriptor, String partId) { - String contributorURI = "platform:/plugin/" //$NON-NLS-1$ - + FrameworkUtil.getBundle(getClass()).getSymbolicName(); - - MDialog dialogModel = modelService.createModelElement(MDialog.class); - dialogModel.setElementId(DIALOG_PREFIX + partId); - dialogModel.setLabel(partDescriptor.getLocalizedLabel()); - dialogModel.setContributorURI(contributorURI); - - String dialogStyle = partDescriptor.getPersistedState() - .get(IPresentationEngine.STYLE_OVERRIDE_KEY); - dialogModel.getPersistedState() - .put(IPresentationEngine.STYLE_OVERRIDE_KEY, dialogStyle); - return dialogModel; - - } - - private void configDialog(MDialog dialogModel, - MPartDescriptor partDescriptor) { - - String location = dialogModel.getPersistedState() - .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); - if (location == null || location.equals("")) { //$NON-NLS-1$ - location = partDescriptor.getPersistedState() - .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); - } - location = location == null ? "" : location; //$NON-NLS-1$ - String[] locations = location.split(","); //$NON-NLS-1$ - - if (locations.length < 4) { - String[] tempLocations = new String[4]; - for (int i = 0; i < locations.length; i++) - tempLocations[i] = locations[i]; - locations = tempLocations; - } - - int dialogX = getDigitalValue(locations[0], DEFAULT_DIALOG_X); - int dialogY = getDigitalValue(locations[1], DEFAULT_DIALOG_Y); - int dialogW = getDigitalValue(locations[2], DEFAULT_DIALOG_WIDTH); - int dialogH = getDigitalValue(locations[3], DEFAULT_DIALOG_HEIGHT); - - dialogModel.setX(dialogX); - dialogModel.setY(dialogY); - dialogModel.setWidth(dialogW); - dialogModel.setHeight(dialogH); - - dialogModel.getPersistedState() - .put(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, location); - } - - private boolean isNone(String value) { - return value == null || "".equals(value); //$NON-NLS-1$ - } - - private int getDigitalValue(String value, int defaultValue) { - return isNone(value) ? defaultValue : Integer.valueOf(value); - } - - @CanExecute - public boolean canExecute(MApplication app, EModelService modelService) { - List editors = modelService.findElements(app, null, MPart.class, - Arrays.asList(IModelConstants.TAG_EDITOR)); - if (!editors.isEmpty()) { - return true; - } - - return false; - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; +import org.eclipse.e4.ui.model.application.ui.basic.MDialog; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.osgi.framework.FrameworkUtil; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class DialogPartHandler { + + private static final String DIALOG_PREFIX = "DIALOG:"; //$NON-NLS-1$ + private static final String DIALOG_PART_SHARED_LIBRARIES = "org.xmind.ui.dialogPart.sharedLibraries"; //$NON-NLS-1$ + + private static final int DEFAULT_DIALOG_Y = 0; + private static final int DEFAULT_DIALOG_X = 0; + private static final int DEFAULT_DIALOG_WIDTH = 800; + private static final int DEFAULT_DIALOG_HEIGHT = 600; + + @Execute + public void run(EPartService ps, MApplication appli, + EModelService modelService, + @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, + @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID) String pageId) { + if (partId == null) + return; + + MPartDescriptor partDescriptor = null; + for (MPartDescriptor mp : appli.getDescriptors()) { + if (partId.equals(mp.getElementId())) { + partDescriptor = mp; + break; + } + } + if (partDescriptor == null) + return; + + List existingDialogs = modelService.findElements(appli, + DIALOG_PREFIX + partId, MDialog.class, null); + boolean dialogExisted = !existingDialogs.isEmpty(); + MDialog dialogModel = dialogExisted ? existingDialogs.get(0) + : createDialog(modelService, partDescriptor, partId); + configDialog(dialogModel, partDescriptor); + + MPart p = ps.findPart(partId); + if (p == null) { + p = ps.createPart(partId); + dialogModel.getChildren().add(p); + dialogModel.setSelectedElement(p); + } + + if (!dialogExisted) { + appli.getChildren().get(0).getWindows().add(dialogModel); + } + + if (pageId != null) { + p.getPersistedState().put( + IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, pageId); + } + + p.setVisible(true); + + modelService.bringToTop(p); + ps.activate(p, true); + + } + + private MDialog createDialog(EModelService modelService, + MPartDescriptor partDescriptor, String partId) { + String contributorURI = "platform:/plugin/" //$NON-NLS-1$ + + FrameworkUtil.getBundle(getClass()).getSymbolicName(); + + MDialog dialogModel = modelService.createModelElement(MDialog.class); + dialogModel.setElementId(DIALOG_PREFIX + partId); + dialogModel.setLabel(partDescriptor.getLocalizedLabel()); + dialogModel.setContributorURI(contributorURI); + + String dialogStyle = partDescriptor.getPersistedState() + .get(IPresentationEngine.STYLE_OVERRIDE_KEY); + dialogModel.getPersistedState() + .put(IPresentationEngine.STYLE_OVERRIDE_KEY, dialogStyle); + return dialogModel; + + } + + private void configDialog(MDialog dialogModel, + MPartDescriptor partDescriptor) { + + String location = dialogModel.getPersistedState() + .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); + if (location == null || location.equals("")) { //$NON-NLS-1$ + location = partDescriptor.getPersistedState() + .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); + } + location = location == null ? "" : location; //$NON-NLS-1$ + String[] locations = location.split(","); //$NON-NLS-1$ + + if (locations.length < 4) { + String[] tempLocations = new String[4]; + for (int i = 0; i < locations.length; i++) + tempLocations[i] = locations[i]; + locations = tempLocations; + } + + int dialogX = getDigitalValue(locations[0], DEFAULT_DIALOG_X); + int dialogY = getDigitalValue(locations[1], DEFAULT_DIALOG_Y); + int dialogW = getDigitalValue(locations[2], DEFAULT_DIALOG_WIDTH); + int dialogH = getDigitalValue(locations[3], DEFAULT_DIALOG_HEIGHT); + + dialogModel.setX(dialogX); + dialogModel.setY(dialogY); + dialogModel.setWidth(dialogW); + dialogModel.setHeight(dialogH); + + dialogModel.getPersistedState() + .put(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, location); + } + + private boolean isNone(String value) { + return value == null || "".equals(value); //$NON-NLS-1$ + } + + private int getDigitalValue(String value, int defaultValue) { + return isNone(value) ? defaultValue : Integer.valueOf(value); + } + + @CanExecute + public boolean canExecute(MApplication app, EModelService modelService, + @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId) { + if (DIALOG_PART_SHARED_LIBRARIES.equals(partId)) { + return true; + } + + List editors = modelService.findElements(app, null, MPart.class, + Arrays.asList(IModelConstants.TAG_EDITOR)); + if (!editors.isEmpty()) { + return true; + } + + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DuplicateResourceHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DuplicateResourceHandler.java index 71f1e40ca..6fc36ae1c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DuplicateResourceHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DuplicateResourceHandler.java @@ -1,29 +1,29 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.xmind.ui.internal.e4models.IContextRunnable; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; - -public class DuplicateResourceHandler { - private IContextRunnable duplicateRunnable; - - @Execute - public void execute() { - if (duplicateRunnable != null) { - duplicateRunnable.run(); - } - } - - @CanExecute - public boolean canExecute(IEclipseContext context) { - duplicateRunnable = E4Utils.getContextRunnable(context, - IModelConstants.KEY_MODEL_PART_DUPLICATE); - return duplicateRunnable != null && duplicateRunnable - .canExecute(context, IModelConstants.KEY_MODEL_PART_DUPLICATE); - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class DuplicateResourceHandler { + private IContextRunnable duplicateRunnable; + + @Execute + public void execute() { + if (duplicateRunnable != null) { + duplicateRunnable.run(); + } + } + + @CanExecute + public boolean canExecute(IEclipseContext context) { + duplicateRunnable = E4Utils.getContextRunnable(context, + IModelConstants.KEY_MODEL_PART_DUPLICATE); + return duplicateRunnable != null && duplicateRunnable + .canExecute(context, IModelConstants.KEY_MODEL_PART_DUPLICATE); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/EditResourceHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/EditResourceHandler.java index 290db64c0..c0505005f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/EditResourceHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/EditResourceHandler.java @@ -1,29 +1,29 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.xmind.ui.internal.e4models.IContextRunnable; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; - -public class EditResourceHandler { - private IContextRunnable editRunnable; - - @Execute - public void execute() { - if (editRunnable != null) { - editRunnable.run(); - } - } - - @CanExecute - public boolean canExecute(IEclipseContext context) { - editRunnable = E4Utils.getContextRunnable(context, - IModelConstants.KEY_MODEL_PART_EDIT); - return editRunnable != null && editRunnable.canExecute(context, - IModelConstants.KEY_MODEL_PART_EDIT); - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class EditResourceHandler { + private IContextRunnable editRunnable; + + @Execute + public void execute() { + if (editRunnable != null) { + editRunnable.run(); + } + } + + @CanExecute + public boolean canExecute(IEclipseContext context) { + editRunnable = E4Utils.getContextRunnable(context, + IModelConstants.KEY_MODEL_PART_EDIT); + return editRunnable != null && editRunnable.canExecute(context, + IModelConstants.KEY_MODEL_PART_EDIT); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ModelPartHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ModelPartHandler.java index 7c626f2b9..292de7461 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ModelPartHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ModelPartHandler.java @@ -1,91 +1,92 @@ - -package org.xmind.ui.internal.e4handlers; - -import java.util.Arrays; -import java.util.List; - -import javax.inject.Named; - -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.xmind.ui.internal.e4models.IModelConstants; - -public class ModelPartHandler { - - @Execute - public void run(EPartService partService, - @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, - @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID) String pageId, - @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID) String partStackId, - MApplication appli, EModelService modelService) { - if (partId == null) - return; - - MPartDescriptor partDescriptor = null; - for (MPartDescriptor mp : appli.getDescriptors()) { - if (partId.equals(mp.getElementId())) { - partDescriptor = mp; - break; - } - } - if (partDescriptor == null) - return; - - List partStacks = modelService.findElements(appli, - partStackId, MPartStack.class, null); - boolean partStackExisted = !partStacks.isEmpty(); - MPartStack partStack = partStackExisted ? partStacks.get(0) - : createPartStack(modelService, partStackId); - - MPart p = partService.findPart(partId); - - if (p == null) { - p = partService.createPart(partId); - partStack.getChildren().add(p); - partStack.setSelectedElement(p); - } - - if (pageId != null) { - p.getPersistedState().put( - IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, pageId); - } - appli.getContext().set(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID, - partId); - - if (!partStackExisted) { - appli.getChildren().get(0).getChildren().add(p); - } - - p.setVisible(true); - - modelService.bringToTop(p); - partService.activate(p, true); - } - - private MPartStack createPartStack(EModelService modelService, - String partStackId) { - MPartStack partStack = modelService - .createModelElement(MPartStack.class); - partStack.setElementId(partStackId); - partStack.setVisible(true); - return partStack; - } - - @CanExecute - public boolean canExecute(MApplication app, EModelService modelService) { - List editors = modelService.findElements(app, null, MPart.class, - Arrays.asList(IModelConstants.TAG_EDITOR)); - if (!editors.isEmpty()) { - return true; - } - - return false; - } -} + +package org.xmind.ui.internal.e4handlers; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class ModelPartHandler { + + @Execute + public void run(EPartService partService, + @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, + @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID) String pageId, + @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID) String partStackId, + MApplication appli, EModelService modelService) { + if (partId == null) + return; + + MPartDescriptor partDescriptor = null; + for (MPartDescriptor mp : appli.getDescriptors()) { + if (partId.equals(mp.getElementId())) { + partDescriptor = mp; + break; + } + } + if (partDescriptor == null) + return; + + List partStacks = modelService.findElements(appli, + partStackId, MPartStack.class, null); + boolean partStackExisted = !partStacks.isEmpty(); + MPartStack partStack = partStackExisted ? partStacks.get(0) + : createPartStack(modelService, partStackId); + + MPart p = partService.findPart(partId); + + if (p == null) { + p = partService.createPart(partId); + partStack.getChildren().add(p); + partStack.setSelectedElement(p); + } + + if (pageId != null) { + p.getPersistedState().put( + IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, pageId); + } + appli.getContext().set(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID, + partId); + + if (!partStackExisted) { + appli.getChildren().get(0).getChildren().add(p); + } + + partStack.setVisible(true); + p.setVisible(true); + + modelService.bringToTop(p); + partService.activate(p, true); + } + + private MPartStack createPartStack(EModelService modelService, + String partStackId) { + MPartStack partStack = modelService + .createModelElement(MPartStack.class); + partStack.setElementId(partStackId); + partStack.setVisible(true); + return partStack; + } + + @CanExecute + public boolean canExecute(MApplication app, EModelService modelService) { + List editors = modelService.findElements(app, null, MPart.class, + Arrays.asList(IModelConstants.TAG_EDITOR)); + if (!editors.isEmpty()) { + return true; + } + + return false; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/NewDefaultWorkbookHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/NewDefaultWorkbookHandler.java index 7d576ae93..9fc690e2d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/NewDefaultWorkbookHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/NewDefaultWorkbookHandler.java @@ -1,30 +1,32 @@ -package org.xmind.ui.internal.e4handlers; - -import javax.inject.Inject; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; - -public class NewDefaultWorkbookHandler { - - @Inject - public void execute(final IWorkbenchWindow window) { - if (window == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("CreateWorkbookCount"); //$NON-NLS-1$ - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - window.getActivePage().openEditor( - MindMapUI.getEditorInputFactory() - .createDefaultEditorInput(), - MindMapUI.MINDMAP_EDITOR_ID); - } - }); - } - -} +package org.xmind.ui.internal.e4handlers; + +import javax.inject.Inject; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; + +public class NewDefaultWorkbookHandler { + + @Inject + public void execute(final IWorkbenchWindow window) { + if (window == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.CREATE_WORKBOOK_COUNT); + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + window.getActivePage().openEditor( + MindMapUI.getEditorInputFactory() + .createDefaultEditorInput(), + MindMapUI.MINDMAP_EDITOR_ID); + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenHomeMapHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenHomeMapHandler.java index 24e4bca81..b362fd9ec 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenHomeMapHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenHomeMapHandler.java @@ -1,52 +1,52 @@ -package org.xmind.ui.internal.e4handlers; - -import java.io.File; - -import javax.inject.Inject; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.dialogs.IDialogConstants; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.util.PrefUtils; - -public class OpenHomeMapHandler { - - @Inject - public void execute(IWorkbenchWindow window) { - if (window == null) - return; - - String filePath = MindMapUIPlugin.getDefault().getPreferenceStore() - .getString(PrefConstants.HOME_MAP_LOCATION); - String errorMessage = null; - if (filePath == null || "".equals(filePath)) { //$NON-NLS-1$ - errorMessage = MindMapMessages.OpenHomeMap_Error_message; - } else if (!new File(filePath).exists()) { - errorMessage = MindMapMessages.OpenHomeMapAction_HomeMapMissingMessage; - } - - if (errorMessage != null) { - boolean ok = MessageDialog.openConfirm(window.getShell(), - IDialogConstants.COMMON_TITLE, errorMessage); - if (!ok) - return; - - PrefUtils.openPrefDialog(window.getShell(), - PrefUtils.GENERAL_PREF_PAGE_ID); - filePath = MindMapUIPlugin.getDefault().getPreferenceStore() - .getString(PrefConstants.HOME_MAP_LOCATION); - } - - if (filePath == null || "".equals(filePath) //$NON-NLS-1$ - || !new File(filePath).exists()) - return; - - OpenWorkbooksHandler.execute(window, - FilePathParser.toURI(filePath, false)); - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.io.File; + +import javax.inject.Inject; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.ui.dialogs.IDialogConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.util.PrefUtils; + +public class OpenHomeMapHandler { + + @Inject + public void execute(IWorkbenchWindow window) { + if (window == null) + return; + + String filePath = MindMapUIPlugin.getDefault().getPreferenceStore() + .getString(PrefConstants.HOME_MAP_LOCATION); + String errorMessage = null; + if (filePath == null || "".equals(filePath)) { //$NON-NLS-1$ + errorMessage = MindMapMessages.OpenHomeMap_Error_message; + } else if (!new File(filePath).exists()) { + errorMessage = MindMapMessages.OpenHomeMapAction_HomeMapMissingMessage; + } + + if (errorMessage != null) { + boolean ok = MessageDialog.openConfirm(window.getShell(), + IDialogConstants.COMMON_TITLE, errorMessage); + if (!ok) + return; + + PrefUtils.openPrefDialog(window.getShell(), + PrefUtils.GENERAL_PREF_PAGE_ID); + filePath = MindMapUIPlugin.getDefault().getPreferenceStore() + .getString(PrefConstants.HOME_MAP_LOCATION); + } + + if (filePath == null || "".equals(filePath) //$NON-NLS-1$ + || !new File(filePath).exists()) + return; + + OpenWorkbooksHandler.execute(window, + FilePathParser.toURI(filePath, false)); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenLocalFileHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenLocalFileHandler.java deleted file mode 100644 index 36a169443..000000000 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenLocalFileHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.xmind.ui.internal.e4handlers; - -import java.io.File; -import java.net.URI; - -import javax.inject.Named; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.LocalFileWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefFactory; -import org.xmind.ui.mindmap.MindMapUI; - -public class OpenLocalFileHandler { - - private static final String KEY_COMMAND_PARAMTER_URI = "org.xmind.ui.mindmap.commandparameter.openLocalFile.uri"; //$NON-NLS-1$ - - @Execute - public void run(final IWorkbenchWindow window, - final @Named(KEY_COMMAND_PARAMTER_URI) String uri) { - if (uri == null || "".equals(uri)) //$NON-NLS-1$ - return; - - @SuppressWarnings("restriction") - IWorkbookRefFactory factory = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory(); - IWorkbookRef workbookRef = factory.createWorkbookRef(URI.create(uri), - null); - Assert.isTrue(workbookRef instanceof LocalFileWorkbookRef); - - LocalFileWorkbookRef localWorkbookRef = (LocalFileWorkbookRef) workbookRef; - String filePath = localWorkbookRef.getURI().getPath(); - if (!new File(filePath).exists()) { - showMessageDialog( - MindMapMessages.WorkbookHistoryItem_FileMissingMessage); - return; - } - IWorkbenchPage page = window.getActivePage(); - Assert.isTrue(page != null); - - final IEditorInput editorInput = MindMapUI.getEditorInputFactory() - .createEditorInput(workbookRef); - Assert.isTrue(editorInput != null); - try { - page.openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); - } catch (PartInitException e) { - MindMapUIPlugin.log(e, this.getClass().getName() + "--> openEdior"); //$NON-NLS-1$ - e.printStackTrace(); - } - } - - private void showMessageDialog(String message) { - String[] buttonLabels = new String[] { IDialogConstants.CLOSE_LABEL }; - - MessageDialog dialog = new MessageDialog(null, - MindMapMessages.OpenLocalFileHandler_MessageDialog_title, null, - message, MessageDialog.WARNING, buttonLabels, 0); - dialog.open(); - } -} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenPopoverHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenPopoverHandler.java index 77bc967a6..77a2f6e91 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenPopoverHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenPopoverHandler.java @@ -1,86 +1,87 @@ -package org.xmind.ui.internal.e4handlers; - -import java.util.Arrays; -import java.util.List; - -import javax.inject.Inject; - -import org.eclipse.e4.core.contexts.ContextInjectionFactory; -import org.eclipse.e4.core.contexts.EclipseContextFactory; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.services.contributions.IContributionFactory; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.MContribution; -import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.e4models.IModelConstants; - -@SuppressWarnings("restriction") -public class OpenPopoverHandler { - - @Inject - private EModelService modelService; - - @Inject - private IEclipseContext context; - - /** - * Marker only. - */ - @Execute - public void run() { - if (modelService == null || context == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ShowMarkerCount"); //$NON-NLS-1$ - MApplication appModel = context.get(MApplication.class); - MUIElement markerDirectItem = modelService - .find(IModelConstants.TOOLITEM_ID_MARKER_POPOVER, appModel); - - if (markerDirectItem instanceof MContribution) { - MContribution mContri = (MContribution) markerDirectItem; - - IEclipseContext windowContext = modelService - .getContainingContext(markerDirectItem); - IEclipseContext staticContext = EclipseContextFactory - .create("MarkerPopover-Static-Context"); //$NON-NLS-1$ - populateModelInterfaces(markerDirectItem, staticContext, - markerDirectItem.getClass().getInterfaces()); - - Object markerModelObject = mContri.getObject(); - if (markerModelObject == null) { - mContri.setObject(windowContext.get(IContributionFactory.class) - .create(mContri.getContributionURI(), windowContext)); - } - - ContextInjectionFactory.invoke(markerModelObject, Execute.class, - windowContext, staticContext, windowContext); - } - } - - private static void populateModelInterfaces(Object modelObject, - IEclipseContext context, Class[] interfaces) { - for (Class intf : interfaces) { - context.set(intf.getName(), modelObject); - - populateModelInterfaces(modelObject, context, intf.getInterfaces()); - } - } - - @CanExecute - public boolean canExecute(EModelService modelService, MApplication app) { - List editors = modelService.findElements(app, null, MPart.class, - Arrays.asList(IModelConstants.TAG_EDITOR)); - if (!editors.isEmpty()) { - return true; - } - - return false; - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; + +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.EclipseContextFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.services.contributions.IContributionFactory; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.MContribution; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.IModelConstants; + +@SuppressWarnings("restriction") +public class OpenPopoverHandler { + + @Inject + private EModelService modelService; + + @Inject + private IEclipseContext context; + + /** + * Marker only. + */ + @Execute + public void run() { + if (modelService == null || context == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SHOW_MARKER_COUNT); + MApplication appModel = context.get(MApplication.class); + MUIElement markerDirectItem = modelService + .find(IModelConstants.TOOLITEM_ID_MARKER_POPOVER, appModel); + + if (markerDirectItem instanceof MContribution) { + MContribution mContri = (MContribution) markerDirectItem; + + IEclipseContext windowContext = modelService + .getContainingContext(markerDirectItem); + IEclipseContext staticContext = EclipseContextFactory + .create("MarkerPopover-Static-Context"); //$NON-NLS-1$ + populateModelInterfaces(markerDirectItem, staticContext, + markerDirectItem.getClass().getInterfaces()); + + Object markerModelObject = mContri.getObject(); + if (markerModelObject == null) { + mContri.setObject(windowContext.get(IContributionFactory.class) + .create(mContri.getContributionURI(), windowContext)); + } + + ContextInjectionFactory.invoke(markerModelObject, Execute.class, + windowContext, staticContext, windowContext); + } + } + + private static void populateModelInterfaces(Object modelObject, + IEclipseContext context, Class[] interfaces) { + for (Class intf : interfaces) { + context.set(intf.getName(), modelObject); + + populateModelInterfaces(modelObject, context, intf.getInterfaces()); + } + } + + @CanExecute + public boolean canExecute(EModelService modelService, MApplication app) { + List editors = modelService.findElements(app, null, MPart.class, + Arrays.asList(IModelConstants.TAG_EDITOR)); + if (!editors.isEmpty()) { + return true; + } + + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenWorkbooksHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenWorkbooksHandler.java index 53f85bbac..f9e33e745 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenWorkbooksHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenWorkbooksHandler.java @@ -1,89 +1,125 @@ -package org.xmind.ui.internal.e4handlers; - -import java.io.File; -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.inject.Inject; - -import org.eclipse.core.commands.ParameterizedCommand; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.SWT; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.commands.MindMapCommandConstants; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.DialogUtils; -import org.xmind.ui.mindmap.MindMapUI; - -public class OpenWorkbooksHandler { - - private static final List NO_URIS = Collections.emptyList(); - - @Inject - public void execute(final IWorkbenchWindow window, - ParameterizedCommand command) { - String uri = (String) command.getParameterMap() - .get(MindMapCommandConstants.OPEN_WORKBOOK_PARAM_URI); - execute(window, uri); - } - - public static void execute(IWorkbenchWindow window, String uri) { - execute(window, uri == null ? NO_URIS : Arrays.asList(uri)); - } - - public static void execute(IWorkbenchWindow window, List uris) { - if (window == null) - return; - - IWorkbenchPage page = window.getActivePage(); - if (page == null) - return; - - if (uris.isEmpty()) { - List files = DialogUtils.openXMindFiles(window.getShell(), - SWT.MULTI); - uris = new ArrayList(files.size()); - for (File file : files) { - uris.add(file.toURI().toString()); - } - } - - IEditorPart lastEditor = null; - for (String uri : uris) { - if (uri != null) { - IEditorPart editor = openMindMapEditor(page, uri); - if (editor != null) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("OpenWorkbookCount"); //$NON-NLS-1$ - lastEditor = editor; - } - } - } - if (lastEditor != null) { - page.activate(lastEditor); - } - - } - - private static IEditorPart openMindMapEditor(final IWorkbenchPage page, - final String uri) { - final IEditorPart[] editor = new IEditorPart[1]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInput(new URI(uri)); - editor[0] = page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID, - false); - } - }); - return editor[0]; - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; + +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefFactory; +import org.xmind.ui.mindmap.MindMapUI; + +public class OpenWorkbooksHandler { + + private static final List NO_URIS = Collections.emptyList(); + private static final String LOCAL_FILE_SCHEME = "file"; //$NON-NLS-1$ + private static final String SEAWIND_FILE_SCHEME = "seawind"; //$NON-NLS-1$ + + @Inject + public void execute(final IWorkbenchWindow window, + ParameterizedCommand command) { + String uri = (String) command.getParameterMap() + .get(MindMapCommandConstants.OPEN_WORKBOOK_PARAM_URI); + execute(window, uri); + } + + public static void execute(IWorkbenchWindow window, String uri) { + execute(window, uri == null ? NO_URIS : Arrays.asList(uri)); + } + + public static void execute(IWorkbenchWindow window, List uris) { + if (window == null) + return; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) + return; + + if (uris.isEmpty()) { + List files = DialogUtils.openXMindFiles(window.getShell(), + SWT.MULTI); + uris = new ArrayList(files.size()); + for (File file : files) { + uris.add(file.toURI().toString()); + } + } + + IEditorPart lastEditor = null; + for (String uri : uris) { + if (uri != null) { + IEditorPart editor = openMindMapEditor(page, uri); + if (editor != null) { + lastEditor = editor; + } + } + } + if (lastEditor != null) { + page.activate(lastEditor); + } + + } + + private static IEditorPart openMindMapEditor(final IWorkbenchPage page, + final String uri) { + final IEditorPart[] editor = new IEditorPart[1]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + + if (uri == null || "".equals(uri)) //$NON-NLS-1$ + return; + + URI workbookURI = URI.create(uri); + IWorkbookRefFactory factory = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory(); + IWorkbookRef workbookRef = factory + .createWorkbookRef(workbookURI, null); + + if (!workbookRef.exists()) { + showFileNotFoundDialog(workbookURI); + return; + } + + IEditorInput input = MindMapUI.getEditorInputFactory() + .createEditorInput(workbookURI); + editor[0] = page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID, + false); + } + }); + return editor[0]; + } + + private static void showFileNotFoundDialog(URI uri) { + Assert.isNotNull(uri); + String scheme = uri.getScheme(); + if (scheme == null || "".equalsIgnoreCase(scheme)) //$NON-NLS-1$ + return; + + if (LOCAL_FILE_SCHEME.equalsIgnoreCase(scheme)) + MessageDialog.openWarning(null, + MindMapMessages.FileNotExistDialog_Title, + MindMapMessages.FileNotExistDialog_Message); + else if (SEAWIND_FILE_SCHEME.equalsIgnoreCase(scheme)) { + MessageDialog.openWarning(null, + MindMapMessages.CloudFileNotExistDialog_Title, + MindMapMessages.CloudFileNotExistDialog_Message); + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/RenameResourceHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/RenameResourceHandler.java index 8ac554104..0a066c725 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/RenameResourceHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/RenameResourceHandler.java @@ -1,30 +1,30 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.xmind.ui.internal.e4models.IContextRunnable; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.utils.E4Utils; - -public class RenameResourceHandler { - - private IContextRunnable renameRunnable; - - @Execute - public void execute() { - if (renameRunnable != null) { - renameRunnable.run(); - } - } - - @CanExecute - public boolean canExecute(IEclipseContext context) { - renameRunnable = E4Utils.getContextRunnable(context, - IModelConstants.KEY_MODEL_PART_RENAME); - return renameRunnable != null && renameRunnable.canExecute(context, - IModelConstants.KEY_MODEL_PART_RENAME); - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class RenameResourceHandler { + + private IContextRunnable renameRunnable; + + @Execute + public void execute() { + if (renameRunnable != null) { + renameRunnable.run(); + } + } + + @CanExecute + public boolean canExecute(IEclipseContext context) { + renameRunnable = E4Utils.getContextRunnable(context, + IModelConstants.KEY_MODEL_PART_RENAME); + return renameRunnable != null && renameRunnable.canExecute(context, + IModelConstants.KEY_MODEL_PART_RENAME); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SaveWorkbookAsHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SaveWorkbookAsHandler.java index cb1adade4..478c9a9d7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SaveWorkbookAsHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SaveWorkbookAsHandler.java @@ -1,473 +1,473 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.e4handlers; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import javax.inject.Named; - -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableContext; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.viewers.IFilter; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.progress.IProgressService; -import org.eclipse.ui.services.IEvaluationService; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IWorkbook; -import org.xmind.gef.ui.editor.IEditable; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.SaveWizardDialog; -import org.xmind.ui.internal.editor.DecryptionDialog; -import org.xmind.ui.internal.editor.IEncryptable; -import org.xmind.ui.internal.editor.SaveWizardManager.SaveWizardDescriptor; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefFactory; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.wizards.ISaveContext; -import org.xmind.ui.wizards.ISaveWizard; -import org.xmind.ui.wizards.ISaveWizard.SaveWizardNotAvailable; -import org.xmind.ui.wizards.SaveOptions; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class SaveWorkbookAsHandler { - - @Execute - public void execute( - @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, - @Optional IProgressService progressProvider, - final @Optional IServiceLocator serviceLocator) - throws InvocationTargetException { - if (selection instanceof IStructuredSelection) { - selection = ((IStructuredSelection) selection).getFirstElement(); - } - if (selection instanceof IWorkbookRef) { - saveWorkbookAs(new ISaveContext() { - @Override - public Object getContextVariable(String key) { - IEvaluationService service = serviceLocator - .getService(IEvaluationService.class); - Assert.isNotNull(service); - Object variable = service.getCurrentState() - .getVariable(key); - return variable == IEvaluationContext.UNDEFINED_VARIABLE - ? null : variable; - } - - @Override - public T getContextVariable(Class key) { - return serviceLocator.getService(key); - } - }, (IWorkbookRef) selection, progressProvider, null, false); - } - } - - /** - * @param context - * the context where this operation happens - * @param workbookRef - * the source workbook ref to be saved - * @param runner - * an {@link IRunnableContext} to run the job - * @param optionFilter - * null to accept all options at beginning, or an - * {@link IFilter} instance that selects available option ids - * @param onlyToLocal - * is only save to local - * @return a new workbook ref that is filled with contents from the source - * workbook ref - * @throws InvocationTargetException - */ - public static IWorkbookRef saveWorkbookAs(ISaveContext context, - final IWorkbookRef workbookRef, IRunnableContext runner, - IFilter optionFilter, boolean onlyToLocal) - throws InvocationTargetException { - Assert.isLegal(context != null); - - Shell shell = context.getContextVariable(Shell.class); - - // list all available location options - List wizards = MindMapUIPlugin.getDefault() - .getSaveWizardManager().getWizards(); - if (wizards.isEmpty()) { - // no location options available.... - // should not happen? - // no need to extract strings - MessageDialog.openWarning(shell, "Save As", //$NON-NLS-1$ - "No 'Save As' options available in this application. " //$NON-NLS-1$ - + "Please contact the software provider for this issue."); //$NON-NLS-1$ - return null; - } - - // make a new array so that we can remove unavailable ones - wizards = new ArrayList(wizards); - if (optionFilter != null) { - Iterator locationProviderIt = wizards - .iterator(); - while (locationProviderIt.hasNext()) { - SaveWizardDescriptor locationProvider = locationProviderIt - .next(); - if (!optionFilter.select(locationProvider.getId())) { - locationProviderIt.remove(); - } - } - } - - sortLocationProviders(wizards); - - // ensure runnable context available - if (runner == null) { - runner = new ProgressMonitorDialog(shell); - } - - // prepare save options - String oldName = workbookRef.getName(); - if (oldName == null) { - IWorkbook workbook = workbookRef.getWorkbook(); - if (workbook != null) { - oldName = workbook.getPrimarySheet().getRootTopic() - .getTitleText(); - } - if (oldName == null) - oldName = MindMapMessages.SaveWorkbookAsHandler_oldName_default; - } - - while (true) { - if (wizards.isEmpty()) { - // tried out all possible location options.... - // should not happen? - // no need to extract strings - MessageDialog.openError(shell, "Save As", //$NON-NLS-1$ - "No 'Save As' options available now for this workbook. " //$NON-NLS-1$ - + "Please contact the software provider for this issue."); //$NON-NLS-1$ - return null; - } - - SaveOptions options = SaveOptions.getDefault() // - .proposalName(oldName) // - .oldURI(workbookRef.getURI()); - - SaveWizardDescriptor wizard; - if (onlyToLocal || wizards.size() == 1) { - wizard = wizards.get(0); - } else { - String oldWizardId = workbookRef.getSaveWizardId(); - SaveWizardDescriptor defaultWizard = oldWizardId == null ? null - : findSaveWizard(wizards, oldWizardId, false); - if (defaultWizard == null) { - int maxPriority = 0; - for (SaveWizardDescriptor wizardDescriptor : wizards) { - /// sort by priority - /// choose highest priority - /// exclude those whose priority < 0 - int priority = wizardDescriptor.getWizard() - .getPriorityFor(context, options); - if (priority > maxPriority) { - maxPriority = priority; - defaultWizard = wizardDescriptor; - } - if (priority < 0) - wizards.remove(wizardDescriptor); - } - - } - if (defaultWizard == null) { - defaultWizard = wizards.get(0); - } - SaveWizardDialog dialog = new SaveWizardDialog(shell, wizards, - defaultWizard, options); - if (dialog.open() != SaveWizardDialog.OK) - // canceled - return null; - - wizard = dialog.getTargetWizard(); - options = dialog.getTargetOptions(); - } - - ISaveWizard wizardImpl = wizard.getWizard(); - Assert.isNotNull(wizardImpl); - - URI newURI; - try { - newURI = wizardImpl.askForTargetURI(context, options); - } catch (SaveWizardNotAvailable na) { - - wizards.remove(wizard); - - String saveText; - if (wizards.size() == 0) { - MessageDialog.openInformation(shell, "No options", //$NON-NLS-1$ - na.getMessage()); - return null; - } else if (wizards.size() == 1) { - saveText = NLS.bind( - MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_saveTo_text, - wizards.get(0).getName()); - } else { - saveText = MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_saveToAnother_text; - } - - MessageDialog dialog = new MessageDialog( - - shell, - - MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_title, - - null, - - na.getMessage(), - - MessageDialog.CONFIRM, - - new String[] { - - saveText, - - IDialogConstants.CANCEL_LABEL - - }, 0 - - ); - - if (dialog.open() != MessageDialog.OK) - return null; - - continue; - } - if (newURI == null) - // canceled - return null; - - IWorkbookRefFactory workbookRefFactory = MindMapUIPlugin - .getDefault().getWorkbookRefFactory(); - final IWorkbookRef newWorkbookRef = workbookRefFactory - .createWorkbookRef(newURI, null); - Assert.isNotNull(newWorkbookRef); - if (!newWorkbookRef.isInState(IEditable.CLOSED)) { - MessageDialog.openWarning(shell, - MindMapMessages.SaveWorkbookAsHandler_warningDialog_title, - MindMapMessages.SaveWorkbookAsHandler_warningDialog_description); - continue; - } - - newWorkbookRef.setActiveContext(workbookRef.getActiveContext()); - - if (newWorkbookRef.equals(workbookRef)) { - // same location - // just save the old workbook ref - if (!workbookRef.isInState(IWorkbookRef.CLOSED)) { - try { - runner.run(true, true, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, - InterruptedException { - workbookRef.save(monitor); - } - }); - } catch (InterruptedException e) { - // canceled - return null; - } - } - return newWorkbookRef; - } - - if (!newWorkbookRef.canImportFrom(workbookRef)) { - MessageDialog.openError(shell, - MindMapMessages.SaveWorkbookAsHandler_saveAsDialog_title, - MindMapMessages.SaveWorkbookAsHandler_saveAsDialog_description); - wizards.remove(wizard); - continue; - } - - try { - runner.run(true, true, new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) - throws InvocationTargetException, - InterruptedException { - doSaveAs(monitor, workbookRef, newWorkbookRef, 0); - } - }); - } catch (InterruptedException e) { - // canceled - return null; - } - - // should return here in normal cases - return newWorkbookRef; - } - } - - private static void doSaveAs(final IProgressMonitor monitor, - final IWorkbookRef oldWorkbookRef, - final IWorkbookRef newWorkbookRef, int times) { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - try { - oldWorkbookRef.open(subMonitor.newChild(15)); - newWorkbookRef.importFrom(subMonitor.newChild(80), oldWorkbookRef); - } catch (final InvocationTargetException e) { - CoreException coreEx = getCoreException(e); - if (coreEx != null) { - int errType = coreEx.getType(); - if (errType == Core.ERROR_WRONG_PASSWORD) { - openDecryptionDialog(oldWorkbookRef, newWorkbookRef, - monitor, - MindMapMessages.MindMapEditor_passwordPrompt_message2, - times); - return; - } - return; - } - } catch (InterruptedException e) { - return; - } finally { - subMonitor.setWorkRemaining(5); - try { - oldWorkbookRef.close(subMonitor.newChild(5)); - } catch (InvocationTargetException e) { - } catch (InterruptedException e) { - } - } - } - - private static CoreException getCoreException(Throwable e) { - if (e == null) - return null; - if (e instanceof CoreException) - return (CoreException) e; - return getCoreException(e.getCause()); - } - - private static void openDecryptionDialog(final IWorkbookRef oldWorkbookRef, - final IWorkbookRef newWorkbookRef, final IProgressMonitor monitor, - String message, final int times) { - final int nextTime = times + 1; - final IEncryptable encryptable = oldWorkbookRef - .getAdapter(IEncryptable.class); - - Display.getDefault().asyncExec(new Runnable() { - - public void run() { - new DecryptionDialog(Display.getDefault().getActiveShell(), - oldWorkbookRef.getName(), encryptable.getPasswordHint(), - times) { - protected void okPressed() { - super.okPressed(); - - encryptable.setPassword(getPassword()); - doSaveAs(monitor, oldWorkbookRef, newWorkbookRef, - nextTime); - }; - - protected void cancelPressed() { - super.cancelPressed(); - }; - }.open(); - - } - }); - } - - private static void sortLocationProviders(List list) { - IPreferenceStore pref = MindMapUIPlugin.getDefault() - .getPreferenceStore(); - List preferredWizards = new ArrayList(); - List nameSortedWizards = new ArrayList(); - - String[] preferredWizardIds = getPreferredSaveWizardIds(pref); - if (preferredWizardIds != null) { - for (String wizardId : preferredWizardIds) { - SaveWizardDescriptor wizard = findSaveWizard(list, wizardId, - true); - if (wizard != null) { - preferredWizards.add(wizard); - } - } - } - - nameSortedWizards.addAll(list); - if (!nameSortedWizards.isEmpty()) { - Collections.sort(nameSortedWizards, - new Comparator() { - @Override - public int compare(SaveWizardDescriptor w1, - SaveWizardDescriptor w2) { - return w1.getName().compareTo(w2.getName()); - } - }); - } - - list.clear(); - list.addAll(preferredWizards); - list.addAll(nameSortedWizards); - } - - /** - * @param list - * @param id - * @param remove - * @return - */ - private static SaveWizardDescriptor findSaveWizard( - List list, String id, boolean remove) { - Iterator it = list.iterator(); - while (it.hasNext()) { - SaveWizardDescriptor wizard = it.next(); - if (id.equals(wizard.getId())) { - if (remove) - it.remove(); - return wizard; - } - } - return null; - } - - private static String[] getPreferredSaveWizardIds(IPreferenceStore pref) { - String preferredWizardIds = pref.getString(PrefConstants.SAVE_WIZARDS); - if (preferredWizardIds != null && !"".equals(preferredWizardIds)) { //$NON-NLS-1$ - return preferredWizardIds.split(","); //$NON-NLS-1$ - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.e4handlers; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import javax.inject.Named; + +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.IFilter; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.progress.IProgressService; +import org.eclipse.ui.services.IEvaluationService; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IWorkbook; +import org.xmind.gef.ui.editor.IEditable; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.SaveWizardDialog; +import org.xmind.ui.internal.editor.DecryptionDialog; +import org.xmind.ui.internal.editor.IEncryptable; +import org.xmind.ui.internal.editor.SaveWizardManager.SaveWizardDescriptor; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefFactory; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.wizards.ISaveContext; +import org.xmind.ui.wizards.ISaveWizard; +import org.xmind.ui.wizards.ISaveWizard.SaveWizardNotAvailable; +import org.xmind.ui.wizards.SaveOptions; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class SaveWorkbookAsHandler { + + @Execute + public void execute( + @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, + @Optional IProgressService progressProvider, + final @Optional IServiceLocator serviceLocator) + throws InvocationTargetException { + if (selection instanceof IStructuredSelection) { + selection = ((IStructuredSelection) selection).getFirstElement(); + } + if (selection instanceof IWorkbookRef) { + saveWorkbookAs(new ISaveContext() { + @Override + public Object getContextVariable(String key) { + IEvaluationService service = serviceLocator + .getService(IEvaluationService.class); + Assert.isNotNull(service); + Object variable = service.getCurrentState() + .getVariable(key); + return variable == IEvaluationContext.UNDEFINED_VARIABLE + ? null : variable; + } + + @Override + public T getContextVariable(Class key) { + return serviceLocator.getService(key); + } + }, (IWorkbookRef) selection, progressProvider, null, false); + } + } + + /** + * @param context + * the context where this operation happens + * @param workbookRef + * the source workbook ref to be saved + * @param runner + * an {@link IRunnableContext} to run the job + * @param optionFilter + * null to accept all options at beginning, or an + * {@link IFilter} instance that selects available option ids + * @param onlyToLocal + * is only save to local + * @return a new workbook ref that is filled with contents from the source + * workbook ref + * @throws InvocationTargetException + */ + public static IWorkbookRef saveWorkbookAs(ISaveContext context, + final IWorkbookRef workbookRef, IRunnableContext runner, + IFilter optionFilter, boolean onlyToLocal) + throws InvocationTargetException { + Assert.isLegal(context != null); + + Shell shell = context.getContextVariable(Shell.class); + + // list all available location options + List wizards = MindMapUIPlugin.getDefault() + .getSaveWizardManager().getWizards(); + if (wizards.isEmpty()) { + // no location options available.... + // should not happen? + // no need to extract strings + MessageDialog.openWarning(shell, "Save As", //$NON-NLS-1$ + "No 'Save As' options available in this application. " //$NON-NLS-1$ + + "Please contact the software provider for this issue."); //$NON-NLS-1$ + return null; + } + + // make a new array so that we can remove unavailable ones + wizards = new ArrayList(wizards); + if (optionFilter != null) { + Iterator locationProviderIt = wizards + .iterator(); + while (locationProviderIt.hasNext()) { + SaveWizardDescriptor locationProvider = locationProviderIt + .next(); + if (!optionFilter.select(locationProvider.getId())) { + locationProviderIt.remove(); + } + } + } + + sortLocationProviders(wizards); + + // ensure runnable context available + if (runner == null) { + runner = new ProgressMonitorDialog(shell); + } + + // prepare save options + String oldName = workbookRef.getName(); + if (oldName == null) { + IWorkbook workbook = workbookRef.getWorkbook(); + if (workbook != null) { + oldName = workbook.getPrimarySheet().getRootTopic() + .getTitleText(); + } + if (oldName == null) + oldName = MindMapMessages.SaveWorkbookAsHandler_oldName_default; + } + + while (true) { + if (wizards.isEmpty()) { + // tried out all possible location options.... + // should not happen? + // no need to extract strings + MessageDialog.openError(shell, "Save As", //$NON-NLS-1$ + "No 'Save As' options available now for this workbook. " //$NON-NLS-1$ + + "Please contact the software provider for this issue."); //$NON-NLS-1$ + return null; + } + + SaveOptions options = SaveOptions.getDefault() // + .proposalName(oldName) // + .oldURI(workbookRef.getURI()); + + SaveWizardDescriptor wizard; + if (onlyToLocal || wizards.size() == 1) { + wizard = wizards.get(0); + } else { + String oldWizardId = workbookRef.getSaveWizardId(); + SaveWizardDescriptor defaultWizard = oldWizardId == null ? null + : findSaveWizard(wizards, oldWizardId, false); + if (defaultWizard == null) { + int maxPriority = 0; + for (SaveWizardDescriptor wizardDescriptor : wizards) { + /// sort by priority + /// choose highest priority + /// exclude those whose priority < 0 + int priority = wizardDescriptor.getWizard() + .getPriorityFor(context, options); + if (priority > maxPriority) { + maxPriority = priority; + defaultWizard = wizardDescriptor; + } + if (priority < 0) + wizards.remove(wizardDescriptor); + } + + } + if (defaultWizard == null) { + defaultWizard = wizards.get(0); + } + SaveWizardDialog dialog = new SaveWizardDialog(shell, wizards, + defaultWizard, options); + if (dialog.open() != SaveWizardDialog.OK) + // canceled + return null; + + wizard = dialog.getTargetWizard(); + options = dialog.getTargetOptions(); + } + + ISaveWizard wizardImpl = wizard.getWizard(); + Assert.isNotNull(wizardImpl); + + URI newURI; + try { + newURI = wizardImpl.askForTargetURI(context, options); + } catch (SaveWizardNotAvailable na) { + + wizards.remove(wizard); + + String saveText; + if (wizards.size() == 0) { + MessageDialog.openInformation(shell, "No options", //$NON-NLS-1$ + na.getMessage()); + return null; + } else if (wizards.size() == 1) { + saveText = NLS.bind( + MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_saveTo_text, + wizards.get(0).getName()); + } else { + saveText = MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_saveToAnother_text; + } + + MessageDialog dialog = new MessageDialog( + + shell, + + MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_title, + + null, + + na.getMessage(), + + MessageDialog.CONFIRM, + + new String[] { + + saveText, + + IDialogConstants.CANCEL_LABEL + + }, 0 + + ); + + if (dialog.open() != MessageDialog.OK) + return null; + + continue; + } + if (newURI == null) + // canceled + return null; + + IWorkbookRefFactory workbookRefFactory = MindMapUIPlugin + .getDefault().getWorkbookRefFactory(); + final IWorkbookRef newWorkbookRef = workbookRefFactory + .createWorkbookRef(newURI, null); + Assert.isNotNull(newWorkbookRef); + if (!newWorkbookRef.isInState(IEditable.CLOSED)) { + MessageDialog.openWarning(shell, + MindMapMessages.SaveWorkbookAsHandler_warningDialog_title, + MindMapMessages.SaveWorkbookAsHandler_warningDialog_description); + continue; + } + + newWorkbookRef.setActiveContext(workbookRef.getActiveContext()); + + if (newWorkbookRef.equals(workbookRef)) { + // same location + // just save the old workbook ref + if (!workbookRef.isInState(IWorkbookRef.CLOSED)) { + try { + runner.run(true, true, new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, + InterruptedException { + workbookRef.save(monitor); + } + }); + } catch (InterruptedException e) { + // canceled + return null; + } + } + return newWorkbookRef; + } + + if (!newWorkbookRef.canImportFrom(workbookRef)) { + MessageDialog.openError(shell, + MindMapMessages.SaveWorkbookAsHandler_saveAsDialog_title, + MindMapMessages.SaveWorkbookAsHandler_saveAsDialog_description); + wizards.remove(wizard); + continue; + } + + try { + runner.run(true, true, new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) + throws InvocationTargetException, + InterruptedException { + doSaveAs(monitor, workbookRef, newWorkbookRef, 0); + } + }); + } catch (InterruptedException e) { + // canceled + return null; + } + + // should return here in normal cases + return newWorkbookRef; + } + } + + private static void doSaveAs(final IProgressMonitor monitor, + final IWorkbookRef oldWorkbookRef, + final IWorkbookRef newWorkbookRef, int times) { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + try { + oldWorkbookRef.open(subMonitor.newChild(15)); + newWorkbookRef.importFrom(subMonitor.newChild(80), oldWorkbookRef); + } catch (final InvocationTargetException e) { + CoreException coreEx = getCoreException(e); + if (coreEx != null) { + int errType = coreEx.getType(); + if (errType == Core.ERROR_WRONG_PASSWORD) { + openDecryptionDialog(oldWorkbookRef, newWorkbookRef, + monitor, + MindMapMessages.MindMapEditor_passwordPrompt_message2, + times); + return; + } + return; + } + } catch (InterruptedException e) { + return; + } finally { + subMonitor.setWorkRemaining(5); + try { + oldWorkbookRef.close(subMonitor.newChild(5)); + } catch (InvocationTargetException e) { + } catch (InterruptedException e) { + } + } + } + + private static CoreException getCoreException(Throwable e) { + if (e == null) + return null; + if (e instanceof CoreException) + return (CoreException) e; + return getCoreException(e.getCause()); + } + + private static void openDecryptionDialog(final IWorkbookRef oldWorkbookRef, + final IWorkbookRef newWorkbookRef, final IProgressMonitor monitor, + String message, final int times) { + final int nextTime = times + 1; + final IEncryptable encryptable = oldWorkbookRef + .getAdapter(IEncryptable.class); + + Display.getDefault().asyncExec(new Runnable() { + + public void run() { + new DecryptionDialog(Display.getDefault().getActiveShell(), + oldWorkbookRef.getName(), encryptable.getPasswordHint(), + times) { + protected void okPressed() { + super.okPressed(); + + encryptable.setPassword(getPassword()); + doSaveAs(monitor, oldWorkbookRef, newWorkbookRef, + nextTime); + }; + + protected void cancelPressed() { + super.cancelPressed(); + }; + }.open(); + + } + }); + } + + private static void sortLocationProviders(List list) { + IPreferenceStore pref = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + List preferredWizards = new ArrayList(); + List nameSortedWizards = new ArrayList(); + + String[] preferredWizardIds = getPreferredSaveWizardIds(pref); + if (preferredWizardIds != null) { + for (String wizardId : preferredWizardIds) { + SaveWizardDescriptor wizard = findSaveWizard(list, wizardId, + true); + if (wizard != null) { + preferredWizards.add(wizard); + } + } + } + + nameSortedWizards.addAll(list); + if (!nameSortedWizards.isEmpty()) { + Collections.sort(nameSortedWizards, + new Comparator() { + @Override + public int compare(SaveWizardDescriptor w1, + SaveWizardDescriptor w2) { + return w1.getName().compareTo(w2.getName()); + } + }); + } + + list.clear(); + list.addAll(preferredWizards); + list.addAll(nameSortedWizards); + } + + /** + * @param list + * @param id + * @param remove + * @return + */ + private static SaveWizardDescriptor findSaveWizard( + List list, String id, boolean remove) { + Iterator it = list.iterator(); + while (it.hasNext()) { + SaveWizardDescriptor wizard = it.next(); + if (id.equals(wizard.getId())) { + if (remove) + it.remove(); + return wizard; + } + } + return null; + } + + private static String[] getPreferredSaveWizardIds(IPreferenceStore pref) { + String preferredWizardIds = pref.getString(PrefConstants.SAVE_WIZARDS); + if (preferredWizardIds != null && !"".equals(preferredWizardIds)) { //$NON-NLS-1$ + return preferredWizardIds.split(","); //$NON-NLS-1$ + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SetDefaultThemeHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SetDefaultThemeHandler.java index e8700aef9..4bbb4ea68 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SetDefaultThemeHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SetDefaultThemeHandler.java @@ -1,76 +1,76 @@ - -package org.xmind.ui.internal.e4handlers; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.xmind.core.style.IStyle; -import org.xmind.ui.internal.e4models.IModelConstants; -import org.xmind.ui.internal.e4models.IModelPartContext; -import org.xmind.ui.internal.e4models.ThemesPart; -import org.xmind.ui.internal.resourcemanager.ResourceManagerDialogPart; -import org.xmind.ui.internal.resourcemanager.ThemeResourceManagerViewer; -import org.xmind.ui.internal.utils.E4Utils; -import org.xmind.ui.internal.views.CategorizedThemeViewer; -import org.xmind.ui.mindmap.MindMapUI; - -public class SetDefaultThemeHandler { - - private IStyle styleToSetDefault; - - @Execute - public void execute(IEclipseContext context) { - if (styleToSetDefault != null) { - MindMapUI.getResourceManager() - .setDefaultTheme(styleToSetDefault.getId()); - Runnable refreshRunnable = E4Utils.getContextRunnable(context, - IModelConstants.KEY_MODEL_PART_REFRESH_PAGE); - if (refreshRunnable != null) { - refreshRunnable.run(); - } - IEclipseContext parentContext = context.getParent(); - if (parentContext != null) { - IModelPartContext modelContext = parentContext - .get(IModelPartContext.class); - if (modelContext instanceof ResourceManagerDialogPart) { - ResourceManagerDialogPart dialogPart = (ResourceManagerDialogPart) modelContext; - ISelectionProvider selectionProvider = dialogPart - .getAdapter(ISelectionProvider.class); - if (selectionProvider instanceof ThemeResourceManagerViewer) - ((ThemeResourceManagerViewer) selectionProvider) - .selectDefault(); - } - if (modelContext instanceof ThemesPart) { - ThemesPart themesPart = (ThemesPart) modelContext; - ISelectionProvider selectionProvider = themesPart - .getAdapter(ISelectionProvider.class); - if (selectionProvider instanceof CategorizedThemeViewer) { - ((CategorizedThemeViewer) selectionProvider) - .selectDefault(); - } - } - } - styleToSetDefault = null; - } - } - - @CanExecute - public boolean canExecute(IEclipseContext context) { - Object selection = context.get(IServiceConstants.ACTIVE_SELECTION); - if (!(selection instanceof IStructuredSelection) - || ((IStructuredSelection) selection).size() != 1) - return false; - Object ele = ((IStructuredSelection) selection).getFirstElement(); - if (!(ele instanceof IStyle)) - return false; - IStyle style = (IStyle) ele; - if (!IStyle.THEME.equals(style.getType())) - return false; - styleToSetDefault = style; - return true; - } - -} + +package org.xmind.ui.internal.e4handlers; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.xmind.core.style.IStyle; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.e4models.IModelPartContext; +import org.xmind.ui.internal.e4models.ThemesPart; +import org.xmind.ui.internal.resourcemanager.ResourceManagerDialogPart; +import org.xmind.ui.internal.resourcemanager.ThemeResourceManagerViewer; +import org.xmind.ui.internal.utils.E4Utils; +import org.xmind.ui.internal.views.CategorizedThemeViewer; +import org.xmind.ui.mindmap.MindMapUI; + +public class SetDefaultThemeHandler { + + private IStyle styleToSetDefault; + + @Execute + public void execute(IEclipseContext context) { + if (styleToSetDefault != null) { + MindMapUI.getResourceManager() + .setDefaultTheme(styleToSetDefault.getId()); + Runnable refreshRunnable = E4Utils.getContextRunnable(context, + IModelConstants.KEY_MODEL_PART_REFRESH_PAGE); + if (refreshRunnable != null) { + refreshRunnable.run(); + } + IEclipseContext parentContext = context.getParent(); + if (parentContext != null) { + IModelPartContext modelContext = parentContext + .get(IModelPartContext.class); + if (modelContext instanceof ResourceManagerDialogPart) { + ResourceManagerDialogPart dialogPart = (ResourceManagerDialogPart) modelContext; + ISelectionProvider selectionProvider = dialogPart + .getAdapter(ISelectionProvider.class); + if (selectionProvider instanceof ThemeResourceManagerViewer) + ((ThemeResourceManagerViewer) selectionProvider) + .selectDefault(); + } + if (modelContext instanceof ThemesPart) { + ThemesPart themesPart = (ThemesPart) modelContext; + ISelectionProvider selectionProvider = themesPart + .getAdapter(ISelectionProvider.class); + if (selectionProvider instanceof CategorizedThemeViewer) { + ((CategorizedThemeViewer) selectionProvider) + .selectDefault(); + } + } + } + styleToSetDefault = null; + } + } + + @CanExecute + public boolean canExecute(IEclipseContext context) { + Object selection = context.get(IServiceConstants.ACTIVE_SELECTION); + if (!(selection instanceof IStructuredSelection) + || ((IStructuredSelection) selection).size() != 1) + return false; + Object ele = ((IStructuredSelection) selection).getFirstElement(); + if (!(ele instanceof IStyle)) + return false; + IStyle style = (IStyle) ele; + if (!IStyle.THEME.equals(style.getType())) + return false; + styleToSetDefault = style; + return true; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ToggleModelPartHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ToggleModelPartHandler.java index d93f841cb..f86af0781 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ToggleModelPartHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ToggleModelPartHandler.java @@ -1,119 +1,119 @@ -package org.xmind.ui.internal.e4handlers; - -import java.util.Arrays; -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.model.application.ui.menu.MToolItem; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.xmind.ui.internal.e4models.IModelConstants; - -public class ToggleModelPartHandler { - - private static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ - - @Inject - private EModelService modelService; - - @Inject - private MApplication application; - - @Execute - public void run(EPartService partService, - @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, - @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID) String partStackId, - @Optional MToolItem toolItemModel, MApplication appli, - EModelService modelService) { - if (partId == null) { - if (partStackId == null) - partStackId = "org.xmind.ui.stack.right"; //$NON-NLS-1$ - - partId = (String) appli.getContext() - .get(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID); - if (partId == null) { - partId = "org.xmind.ui.modelPart.properties"; //$NON-NLS-1$ - } - } - - MPartDescriptor partDescriptor = null; - for (MPartDescriptor mp : appli.getDescriptors()) { - if (partId.equals(mp.getElementId())) { - partDescriptor = mp; - break; - } - } - if (partDescriptor == null) - return; - - List partStacks = modelService.findElements(appli, - partStackId, MPartStack.class, null); - boolean partStackExisted = !partStacks.isEmpty(); - MPartStack partStack = partStackExisted ? partStacks.get(0) - : createPartStack(modelService, partStackId); - - MPart p = partService.findPart(partId); - if (p == null) { - p = partService.createPart(partId); - partStack.getChildren().add(p); - partStack.setSelectedElement(p); - p.setVisible(false); - } - - if (!partStackExisted) { - appli.getChildren().get(0).getChildren().add(p); - } - - if (!p.isVisible()) { - partStack.setVisible(true); - p.setVisible(true); - partService.activate(p, true); - } else { - p.setVisible(false); - partService.hidePart(p); - } - - appli.getContext().set(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID, - partId); - -// boolean toShow = toolItemModel.isSelected(); -// if (toShow) { -// p.setVisible(true); -// partService.activate(p, true); -// } else { -// p.setVisible(false); -// partService.hidePart(p); -// } - - } - - private MPartStack createPartStack(EModelService modelService, - String partStackId) { - MPartStack partStack = modelService - .createModelElement(MPartStack.class); - partStack.setElementId(partStackId); - partStack.setVisible(true); - return partStack; - } - - @CanExecute - public boolean canExecute() { - List editors = modelService.findElements(application, null, - MPart.class, Arrays.asList(TAG_EDITOR)); - if (!editors.isEmpty()) { - return true; - } - - return false; - } - -} +package org.xmind.ui.internal.e4handlers; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.menu.MToolItem; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class ToggleModelPartHandler { + + private static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ + + @Inject + private EModelService modelService; + + @Inject + private MApplication application; + + @Execute + public void run(EPartService partService, + @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID) String partId, + @Optional @Named(IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID) String partStackId, + @Optional MToolItem toolItemModel, MApplication appli, + EModelService modelService) { + if (partId == null) { + if (partStackId == null) + partStackId = "org.xmind.ui.stack.right"; //$NON-NLS-1$ + + partId = (String) appli.getContext() + .get(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID); + if (partId == null) { + partId = "org.xmind.ui.modelPart.properties"; //$NON-NLS-1$ + } + } + + MPartDescriptor partDescriptor = null; + for (MPartDescriptor mp : appli.getDescriptors()) { + if (partId.equals(mp.getElementId())) { + partDescriptor = mp; + break; + } + } + if (partDescriptor == null) + return; + + List partStacks = modelService.findElements(appli, + partStackId, MPartStack.class, null); + boolean partStackExisted = !partStacks.isEmpty(); + MPartStack partStack = partStackExisted ? partStacks.get(0) + : createPartStack(modelService, partStackId); + + MPart p = partService.findPart(partId); + if (p == null) { + p = partService.createPart(partId); + partStack.getChildren().add(p); + partStack.setSelectedElement(p); + p.setVisible(false); + } + + if (!partStackExisted) { + appli.getChildren().get(0).getChildren().add(p); + } + + if (!p.isVisible()) { + partStack.setVisible(true); + p.setVisible(true); + partService.activate(p, true); + } else { + p.setVisible(false); + partService.hidePart(p); + } + + appli.getContext().set(IModelConstants.KEY_LAST_OPENED_MODEL_PART_ID, + partId); + +// boolean toShow = toolItemModel.isSelected(); +// if (toShow) { +// p.setVisible(true); +// partService.activate(p, true); +// } else { +// p.setVisible(false); +// partService.hidePart(p); +// } + + } + + private MPartStack createPartStack(EModelService modelService, + String partStackId) { + MPartStack partStack = modelService + .createModelElement(MPartStack.class); + partStack.setElementId(partStackId); + partStack.setVisible(true); + return partStack; + } + + @CanExecute + public boolean canExecute() { + List editors = modelService.findElements(application, null, + MPart.class, Arrays.asList(TAG_EDITOR)); + if (!editors.isEmpty()) { + return true; + } + + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/CommentsPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/CommentsPart.java index 9fd574093..6cde77c01 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/CommentsPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/CommentsPart.java @@ -1,771 +1,772 @@ -package org.xmind.ui.internal.e4models; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.inject.Inject; - -import org.eclipse.e4.core.commands.ECommandService; -import org.eclipse.e4.core.commands.EHandlerService; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.EContextService; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextViewer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.internal.E4PartWrapper; -import org.eclipse.ui.part.IContributedContentsView; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.Core; -import org.xmind.core.IComment; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.comments.CommentTextViewer; -import org.xmind.ui.internal.comments.CommentsPartActionBarContributor; -import org.xmind.ui.internal.comments.CommentsSelectionProvider; -import org.xmind.ui.internal.comments.ICommentTextViewerContainer; -import org.xmind.ui.internal.comments.ICommentsActionBarContributor; -import org.xmind.ui.internal.comments.SheetCommentsViewer; -import org.xmind.ui.resources.ColorUtils; - -@SuppressWarnings("restriction") -public class CommentsPart extends ViewModelPart implements - IContributedContentsView, IPartListener, ISelectionChangedListener, - ICoreEventListener, ICommentTextViewerContainer { - - public static final String PART_ID = "org.xmind.ui.modelPart.comment"; //$NON-NLS-1$ - - public static final String BG_COLOR = "#ffffff"; //$NON-NLS-1$ - - private static final String COMMENTS_EDIT_CONTEXT_ID = "org.xmind.ui.context.comments.edit"; //$NON-NLS-1$ - - private static final String INVALID_COLER = "#f0f0f0"; //$NON-NLS-1$ - - private static class EActionHandler { - - private IAction action; - - public EActionHandler(IAction action) { - this.action = action; - } - - @Execute - public void execute() { - if (action.getStyle() == IAction.AS_CHECK_BOX - || action.getStyle() == IAction.AS_RADIO_BUTTON) { - action.setChecked(!action.isChecked()); - } - action.run(); - } - - @CanExecute - public boolean canExecute() { - return action.isEnabled(); - } - } - - private class ContextActivator implements IPartListener { - - public ContextActivator() { - getAdapter(IWorkbenchWindow.class).getActivePage() - .addPartListener(this); - } - - public void partActivated(IWorkbenchPart part) { - MPart modelPart = CommentsPart.this.getAdapter(MPart.class); - Object e4Wrapper = modelPart.getTransientData() - .get(E4PartWrapper.E4_WRAPPER_KEY); - if (part == e4Wrapper) { - activateContext(); - } - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - getAdapter(IWorkbenchWindow.class).getActivePage() - .removePartListener(this); - } - - public void partDeactivated(IWorkbenchPart part) { - MPart modelPart = CommentsPart.this.getAdapter(MPart.class); - Object e4Wrapper = modelPart.getTransientData() - .get(E4PartWrapper.E4_WRAPPER_KEY); - if (part == e4Wrapper) { - deactivateContext(); - } - } - - public void partOpened(IWorkbenchPart part) { - } - - private void activateContext() { - contextService.activateContext(COMMENTS_EDIT_CONTEXT_ID); - } - - private void deactivateContext() { - contextService.deactivateContext(COMMENTS_EDIT_CONTEXT_ID); - } - } - - private class TextAction extends Action { - - private TextViewer textViewer; - - private int op; - - public TextAction(int op) { - this.op = op; - } - - public void run() { - if (textViewer != null && textViewer.canDoOperation(op)) { - textViewer.doOperation(op); - contentComposite.pack(); - } - } - - public void update(TextViewer textViewer) { - this.textViewer = textViewer; - setEnabled(textViewer != null && textViewer.canDoOperation(op)); - } - } - - private class CommitCommentHandler { - - @Execute - public void execute() { - saveComment(); - } - } - - @Inject - private EHandlerService handlerService; - - @Inject - private EContextService contextService; - - private CommentsPartActionBarContributor contributor; - - private ISelectionProvider selectionProvider = new CommentsSelectionProvider(); - - private List textActions = new ArrayList(7); - - private IGraphicalEditor contributingEditor; - - private ICoreEventRegister commentEventRegister; - - private ICoreEventRegister globalEventRegister; - - private Control control; - - private ScrolledComposite sc; - - private Composite contentComposite; - - private SheetCommentsViewer contentViewer; - - private ISheet sheet; - - private ControlListener controlListener; - - private CommitCommentHandler commitCommentHandler = new CommitCommentHandler(); - - private IComment latestCreatedComment; - - private IComment selectedComment; - - private IComment editingComment; - - private boolean modified; - - private String insertTarget; - - private Map handlers = new HashMap(); - - private Map globalActions = new HashMap( - 7); - - @Override - protected Control doCreateContent(Composite parent) { - contributor = new CommentsPartActionBarContributor(this, - contributingEditor); - - control = createControl(parent); - activateHandlers(); - new ContextActivator(); - getAdapter(IWorkbenchWindow.class).getActivePage() - .addPartListener(this); - return control; - } - - private Composite createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor(BG_COLOR))); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - contentComposite = createContentComposite(composite); - - return composite; - } - - private Composite createContentComposite(Composite parent) { - sc = new ScrolledComposite(parent, SWT.V_SCROLL); - sc.setBackground(parent.getBackground()); - sc.setLayoutData(new GridData(GridData.FILL_BOTH)); - sc.setExpandHorizontal(true); - - final Composite composite = new Composite(sc, SWT.NONE); - composite.setBackground(composite.getParent().getBackground()); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - gridLayout.marginBottom = 0; - composite.setLayout(gridLayout); - - sc.setContent(composite); - sc.getVerticalBar().setIncrement(17); - - sc.addControlListener(getControlListener()); - - return composite; - } - - private ControlListener getControlListener() { - if (controlListener == null) { - controlListener = new ControlListener() { - - public void controlMoved(ControlEvent e) { - } - - public void controlResized(ControlEvent e) { - e.widget.getDisplay().asyncExec(new Runnable() { - - public void run() { - if (contentComposite != null - && !contentComposite.isDisposed()) { - contentComposite.pack(); - } - } - }); - } - }; - } - - return controlListener; - } - - private void setInitialInput() { - IEditorPart activeEditor = getAdapter(IWorkbenchWindow.class) - .getActivePage().getActiveEditor(); - if (activeEditor instanceof IGraphicalEditor) { - setContributingEditor((IGraphicalEditor) activeEditor); - } else { - setInput(null); - } - } - - private void setInput(ISheet sheet) { - if (this.sheet == sheet) { - return; - } - this.sheet = sheet; - unhookSheet(); - update(); - hookSheet(); - } - - private void hookSheet() { - if (sheet != null) { - if (commentEventRegister == null) - commentEventRegister = new CoreEventRegister(sheet - .getOwnedWorkbook().getAdapter(ICoreEventSupport.class), - this); - commentEventRegister.register(Core.CommentAdd); - commentEventRegister.register(Core.CommentRemove); - - registerGlobalEvent(); - } - } - - private void unhookSheet() { - if (commentEventRegister != null) { - commentEventRegister.unregisterAll(); - commentEventRegister = null; - } - unRegisterGlobalEvent(); - } - - private void registerGlobalEvent() { - globalEventRegister = new CoreEventRegister( - sheet.getOwnedWorkbook().getAdapter(ICoreEventSupport.class), - this); - globalEventRegister.register(Core.CommentContent); - } - - private void unRegisterGlobalEvent() { - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - globalEventRegister = null; - } - } - - private void update() { - resetSelectedComment(); - updateCompositeEnabled(); - updateComments(); - setModified(false); - setEditingComment(null); - setInsertTarget(null); - } - - private void resetSelectedComment() { - contributor.selectedCommentChanged(null); - } - - private void updateCompositeEnabled() { - sc.setEnabled(sheet != null); - if (sheet == null) { - contentComposite.getParent().setBackground((Color) resources - .get(ColorUtils.toDescriptor(INVALID_COLER))); - contentComposite.setBackground((Color) resources - .get(ColorUtils.toDescriptor(INVALID_COLER))); - } else { - contentComposite.getParent().setBackground(control.getBackground()); - contentComposite.setBackground(control.getBackground()); - } - } - - private void updateComments() { - contentComposite.setRedraw(false); - clearContent(); - selectionProvider.setSelection(null); - - if (sheet != null) { - contentViewer = new SheetCommentsViewer(sheet, contributor, - selectionProvider, this, contributingEditor); - contentViewer.create(contentComposite); - } - contentComposite.pack(true); - contentComposite.layout(true, true); - contentComposite.setRedraw(true); - } - - private void clearContent() { - Control[] controls = contentComposite.getChildren(); - if (controls != null) { - for (Control control : controls) { - if (control != null && !control.isDisposed()) { - control.dispose(); - control = null; - } - } - } - } - - protected boolean postConfiguration(IWorkbenchPart workbenchPart, - MPart part) { - // prevent PartRenderingEngine's limbo shell. - setInitialInput(); - - super.postConfiguration(workbenchPart, part); - IWorkbenchPartSite site = workbenchPart.getSite(); - if (site instanceof IViewSite) { - IActionBars actionBars = ((IViewSite) site).getActionBars(); - if (actionBars == null) { - return false; - } - - IServiceLocator serviceLocator = actionBars.getServiceLocator(); - if (serviceLocator == null) - return false; - IEclipseContext eclipseContext = serviceLocator - .getService(IEclipseContext.class); - eclipseContext.set(ECommandService.class, - serviceLocator.getService(ECommandService.class)); - eclipseContext.set(EHandlerService.class, - serviceLocator.getService(EHandlerService.class)); - - registerGlobalTextActionHandlers(); - return true; - } - return false; - } - - private void registerGlobalTextActionHandlers() { - activateGlobalTextHandler(ActionFactory.UNDO, - ITextOperationTarget.UNDO); - activateGlobalTextHandler(ActionFactory.REDO, - ITextOperationTarget.REDO); - activateGlobalTextHandler(ActionFactory.CUT, ITextOperationTarget.CUT); - activateGlobalTextHandler(ActionFactory.COPY, - ITextOperationTarget.COPY); - activateGlobalTextHandler(ActionFactory.PASTE, - ITextOperationTarget.PASTE); - activateGlobalTextHandler(ActionFactory.SELECT_ALL, - ITextOperationTarget.SELECT_ALL); - } - - private void activateGlobalTextHandler(ActionFactory actionFactory, - int textOp) { - TextAction textAction = new TextAction(textOp); - String commandId = actionFactory.getCommandId(); - textAction.setActionDefinitionId(commandId); - Object handler = new EActionHandler(textAction); - handlerService.activateHandler(commandId, handler); - handlers.put(commandId, handler); - - textAction.setId(actionFactory.getId()); - IWorkbenchAction workbenchAction = actionFactory - .create(getAdapter(IWorkbenchWindow.class)); - textAction.setText(workbenchAction.getText()); - workbenchAction.dispose(); - textActions.add(textAction); - globalActions.put(actionFactory.getId(), textAction); - } - - private void unregisterGlobalTextActionHandlers() { - if (handlerService != null) { - for (Entry entry : handlers.entrySet()) { - handlerService.deactivateHandler(entry.getKey(), - entry.getValue()); - } - handlers.clear(); - } - } - - public IAction getGlobalAction(String actionId) { - return globalActions.get(actionId); - } - - public void updateTextActions(TextViewer textViewer) { - if (textViewer != null) { - for (TextAction action : textActions) { - action.update(textViewer); - } - } - } - - private void activateHandlers() { - handlerService.activateHandler("org.xmind.ui.command.commitComments", //$NON-NLS-1$ - commitCommentHandler); - } - - private void deactivateHandlers() { - handlerService.deactivateHandler("org.xmind.ui.command.commitComments", //$NON-NLS-1$ - commitCommentHandler); - } - - private void saveComment() { - if (contentViewer != null) { - contentViewer.save(); - } - } - - public void setFocus() { - if (control != null && !control.isDisposed()) { - control.setFocus(); - } - } - - private void setContributingEditor(IGraphicalEditor editor) { - if (editor == contributingEditor) { - return; - } - - if (contributingEditor != null) { - ISelectionProvider selectionProvider = contributingEditor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) - selectionProvider.removeSelectionChangedListener(this); - } - - contributingEditor = editor; - - if (contributingEditor != null) { - ISelectionProvider selectionProvider = contributingEditor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.addSelectionChangedListener(this); - } - } - - if (getControl().isDisposed()) { - return; - } - if (contentViewer != null) { - contentViewer.setTargetEditor(contributingEditor); - } - if (contributor != null) { - contributor.setTargetEditor(contributingEditor); - } - - ISheet sheet = getSheet(contributingEditor); - setInput(sheet); - } - - public void partActivated(IWorkbenchPart part) { - if (part instanceof IGraphicalEditor) { - setContributingEditor((IGraphicalEditor) part); - } - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - if (part == this.contributingEditor) { - setContributingEditor(null); - } - } - - public void partDeactivated(IWorkbenchPart part) { - } - - public void partOpened(IWorkbenchPart part) { - } - - public void selectionChanged(SelectionChangedEvent event) { - ISheet sheet = getSheet(contributingEditor); - setInput(sheet); - } - - private ISheet getSheet(IGraphicalEditor editor) { - if (editor != null && editor.getActivePageInstance() != null) { - return (ISheet) editor.getActivePageInstance() - .getAdapter(ISheet.class); - } else { - return null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - final String type = event.getType(); - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - if (!contentComposite.isDisposed()) { - if (Core.CommentAdd.equals(type) - || Core.CommentRemove.equals(type)) { - update(); - } else if (Core.CommentContent.equals(type)) { - IComment comment = (IComment) event.getSource(); - if (comment.isOrphan()) { - return; - } - Object source = comment.getOwnedWorkbook() - .getElementById(comment.getObjectId()); - if ((source instanceof ITopic - && ((ITopic) source).getOwnedSheet() == sheet) - || source instanceof ISheet - && source == sheet) { - update(); - } - } - } - } - }); - } - - public void moveToPreviousTextViewer(CommentTextViewer implementation) { - List implementations = contentViewer - .getImplementations(); - int index = implementations.indexOf(implementation); - if (index <= 0 || index > implementations.size() - 1) { - return; - } - - setSelection(new StructuredSelection(implementations.get(index - 1))); - } - - public void moveToNextTextViewer(CommentTextViewer implementation) { - List implementations = contentViewer - .getImplementations(); - int index = implementations.indexOf(implementation); - if (index < 0 || index >= implementations.size() - 1) { - return; - } - - setSelection(new StructuredSelection(implementations.get(index + 1))); - } - - private void setSelection(ISelection selection) { - selectionProvider.setSelection(selection); - } - - //It can be only used in getAdapter() for findReplaceAction. - private CommentTextViewer getImplementation() { - if (selectionProvider instanceof CommentsSelectionProvider) { - ISelection selection = selectionProvider.getSelection(); - if (selection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) selection) - .getFirstElement(); - if (obj instanceof CommentTextViewer) { - return (CommentTextViewer) obj; - } - } - - ISelection oldSelection = ((CommentsSelectionProvider) selectionProvider) - .getOldSelection(); - if (oldSelection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) oldSelection) - .getFirstElement(); - if (obj instanceof CommentTextViewer) { - return (CommentTextViewer) obj; - } - } - } - - return null; - } - - public Composite getContentComposite() { - return contentComposite; - } - - public ScrolledComposite getScrolledComposite() { - return sc; - } - - public ICommentsActionBarContributor getContributor() { - return contributor; - } - - public void setLatestCreatedComment(IComment latestCreatedComment) { - this.latestCreatedComment = latestCreatedComment; - } - - public IComment getLatestCreatedComment() { - return latestCreatedComment; - } - - public void setSelectedComment(IComment selectedComment) { - this.selectedComment = selectedComment; - } - - public IComment getSelectedComment() { - return selectedComment; - } - - public Control getControl() { - return control; - } - - @Override - public void createComment(String objectId) { - contentViewer.createNewComment(objectId); - } - - @Override - public void cancelCreateComment() { - contentViewer.cancelCreateNewComment(); - } - - public void setEditingComment(IComment editingComment) { - this.editingComment = editingComment; - } - - public IComment getEditingComment() { - return editingComment; - } - - public void setModified(boolean modified) { - this.modified = modified; - } - - public boolean isModified() { - return modified; - } - - public void setInsertTarget(String objectId) { - this.insertTarget = objectId; - } - - public String getInsertTarget() { - return insertTarget; - } - - public IWorkbenchPart getContributingPart() { - return contributingEditor; - } - - public void dispose() { - unhookSheet(); - deactivateHandlers(); - if (contributor != null) { - contributor.dispose(); - } - if (sc != null && !sc.isDisposed()) { - sc.removeControlListener(getControlListener()); - } - getAdapter(IWorkbenchWindow.class).getActivePage() - .removePartListener(this); - setContributingEditor(null); - unregisterGlobalTextActionHandlers(); - - super.dispose(); - - textActions = null; - } - - @Override - public T getAdapter(Class adapter) { - if (adapter == IContributedContentsView.class) { - return adapter.cast(this); - } else if (adapter == ITextViewer.class) { - return adapter.cast(getImplementation() == null ? null - : getImplementation().getTextViewer()); - } - return super.getAdapter(adapter); - } - -} +package org.xmind.ui.internal.e4models; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.inject.Inject; + +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.EContextService; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.internal.E4PartWrapper; +import org.eclipse.ui.part.IContributedContentsView; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.Core; +import org.xmind.core.IComment; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.comments.CommentTextViewer; +import org.xmind.ui.internal.comments.CommentsPartActionBarContributor; +import org.xmind.ui.internal.comments.CommentsSelectionProvider; +import org.xmind.ui.internal.comments.ICommentTextViewerContainer; +import org.xmind.ui.internal.comments.ICommentsActionBarContributor; +import org.xmind.ui.internal.comments.SheetCommentsViewer; +import org.xmind.ui.resources.ColorUtils; + +@SuppressWarnings("restriction") +public class CommentsPart extends ViewModelPart implements + IContributedContentsView, IPartListener, ISelectionChangedListener, + ICoreEventListener, ICommentTextViewerContainer { + + public static final String PART_ID = "org.xmind.ui.modelPart.comment"; //$NON-NLS-1$ + + public static final String BG_COLOR = "#ffffff"; //$NON-NLS-1$ + + private static final String COMMENTS_EDIT_CONTEXT_ID = "org.xmind.ui.context.comments.edit"; //$NON-NLS-1$ + + private static final String INVALID_COLER = "#f0f0f0"; //$NON-NLS-1$ + + private static class EActionHandler { + + private IAction action; + + public EActionHandler(IAction action) { + this.action = action; + } + + @Execute + public void execute() { + if (action.getStyle() == IAction.AS_CHECK_BOX + || action.getStyle() == IAction.AS_RADIO_BUTTON) { + action.setChecked(!action.isChecked()); + } + action.run(); + } + + @CanExecute + public boolean canExecute() { + return action.isEnabled(); + } + } + + private class ContextActivator implements IPartListener { + + public ContextActivator() { + getAdapter(IWorkbenchWindow.class).getActivePage() + .addPartListener(this); + } + + public void partActivated(IWorkbenchPart part) { + MPart modelPart = CommentsPart.this.getAdapter(MPart.class); + Object e4Wrapper = modelPart.getTransientData() + .get(E4PartWrapper.E4_WRAPPER_KEY); + if (part == e4Wrapper) { + activateContext(); + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + getAdapter(IWorkbenchWindow.class).getActivePage() + .removePartListener(this); + } + + public void partDeactivated(IWorkbenchPart part) { + MPart modelPart = CommentsPart.this.getAdapter(MPart.class); + Object e4Wrapper = modelPart.getTransientData() + .get(E4PartWrapper.E4_WRAPPER_KEY); + if (part == e4Wrapper) { + deactivateContext(); + } + } + + public void partOpened(IWorkbenchPart part) { + } + + private void activateContext() { + contextService.activateContext(COMMENTS_EDIT_CONTEXT_ID); + } + + private void deactivateContext() { + contextService.deactivateContext(COMMENTS_EDIT_CONTEXT_ID); + } + } + + private class TextAction extends Action { + + private TextViewer textViewer; + + private int op; + + public TextAction(int op) { + this.op = op; + } + + public void run() { + if (textViewer != null && textViewer.canDoOperation(op)) { + textViewer.doOperation(op); + contentComposite.pack(); + } + } + + public void update(TextViewer textViewer) { + this.textViewer = textViewer; + setEnabled(textViewer != null && textViewer.canDoOperation(op)); + } + } + + private class CommitCommentHandler { + + @Execute + public void execute() { + saveComment(); + } + } + + @Inject + private EHandlerService handlerService; + + @Inject + private EContextService contextService; + + private CommentsPartActionBarContributor contributor; + + private ISelectionProvider selectionProvider = new CommentsSelectionProvider(); + + private List textActions = new ArrayList(7); + + private IGraphicalEditor contributingEditor; + + private ICoreEventRegister commentEventRegister; + + private ICoreEventRegister globalEventRegister; + + private Control control; + + private ScrolledComposite sc; + + private Composite contentComposite; + + private SheetCommentsViewer contentViewer; + + private ISheet sheet; + + private ControlListener controlListener; + + private CommitCommentHandler commitCommentHandler = new CommitCommentHandler(); + + private IComment latestCreatedComment; + + private IComment selectedComment; + + private IComment editingComment; + + private boolean modified; + + private String insertTarget; + + private Map handlers = new HashMap(); + + private Map globalActions = new HashMap( + 7); + + @Override + protected Control doCreateContent(Composite parent) { + contributor = new CommentsPartActionBarContributor(this, + contributingEditor); + + control = createControl(parent); + activateHandlers(); + new ContextActivator(); + getAdapter(IWorkbenchWindow.class).getActivePage() + .addPartListener(this); + return control; + } + + private Composite createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor(BG_COLOR))); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + contentComposite = createContentComposite(composite); + + return composite; + } + + private Composite createContentComposite(Composite parent) { + sc = new ScrolledComposite(parent, SWT.V_SCROLL); + sc.setBackground(parent.getBackground()); + sc.setLayoutData(new GridData(GridData.FILL_BOTH)); + sc.setExpandHorizontal(true); + + final Composite composite = new Composite(sc, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + gridLayout.marginBottom = 0; + composite.setLayout(gridLayout); + + sc.setContent(composite); + sc.getVerticalBar().setIncrement(17); + + sc.addControlListener(getControlListener()); + + return composite; + } + + private ControlListener getControlListener() { + if (controlListener == null) { + controlListener = new ControlListener() { + + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + e.widget.getDisplay().asyncExec(new Runnable() { + + public void run() { + if (contentComposite != null + && !contentComposite.isDisposed()) { + contentComposite.pack(); + } + } + }); + } + }; + } + + return controlListener; + } + + private void setInitialInput() { + IEditorPart activeEditor = getAdapter(IWorkbenchWindow.class) + .getActivePage().getActiveEditor(); + if (activeEditor instanceof IGraphicalEditor) { + setContributingEditor((IGraphicalEditor) activeEditor); + } else { + setInput(null); + } + } + + private void setInput(ISheet sheet) { + if (this.sheet == sheet) { + return; + } + this.sheet = sheet; + unhookSheet(); + update(); + hookSheet(); + } + + private void hookSheet() { + if (sheet != null) { + if (commentEventRegister == null) + commentEventRegister = new CoreEventRegister(sheet + .getOwnedWorkbook().getAdapter(ICoreEventSupport.class), + this); + commentEventRegister.register(Core.CommentAdd); + commentEventRegister.register(Core.CommentRemove); + + registerGlobalEvent(); + } + } + + private void unhookSheet() { + if (commentEventRegister != null) { + commentEventRegister.unregisterAll(); + commentEventRegister = null; + } + unRegisterGlobalEvent(); + } + + private void registerGlobalEvent() { + globalEventRegister = new CoreEventRegister( + sheet.getOwnedWorkbook().getAdapter(ICoreEventSupport.class), + this); + globalEventRegister.register(Core.CommentContent); + } + + private void unRegisterGlobalEvent() { + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } + } + + private void update() { + resetSelectedComment(); + updateCompositeEnabled(); + updateComments(); + setModified(false); + setEditingComment(null); + setInsertTarget(null); + } + + private void resetSelectedComment() { + contributor.selectedCommentChanged(null); + } + + private void updateCompositeEnabled() { + sc.setEnabled(sheet != null); + if (sheet == null) { + contentComposite.getParent().setBackground((Color) resources + .get(ColorUtils.toDescriptor(INVALID_COLER))); + contentComposite.setBackground((Color) resources + .get(ColorUtils.toDescriptor(INVALID_COLER))); + } else { + contentComposite.getParent().setBackground(control.getBackground()); + contentComposite.setBackground(control.getBackground()); + } + } + + private void updateComments() { + contentComposite.setRedraw(false); + clearContent(); + selectionProvider.setSelection(null); + + if (sheet != null) { + contentViewer = new SheetCommentsViewer(sheet, contributor, + selectionProvider, this, contributingEditor); + contentViewer.create(contentComposite); + } + contentComposite.pack(true); + contentComposite.layout(true, true); + contentComposite.setRedraw(true); + } + + private void clearContent() { + Control[] controls = contentComposite.getChildren(); + if (controls != null) { + for (Control control : controls) { + if (control != null && !control.isDisposed()) { + control.dispose(); + control = null; + } + } + } + } + + protected boolean postConfiguration(IWorkbenchPart workbenchPart, + MPart part) { + // prevent PartRenderingEngine's limbo shell. + setInitialInput(); + + super.postConfiguration(workbenchPart, part); + IWorkbenchPartSite site = workbenchPart.getSite(); + if (site instanceof IViewSite) { + IActionBars actionBars = ((IViewSite) site).getActionBars(); + if (actionBars == null) { + return false; + } + + IServiceLocator serviceLocator = actionBars.getServiceLocator(); + if (serviceLocator == null) + return false; + IEclipseContext eclipseContext = serviceLocator + .getService(IEclipseContext.class); + eclipseContext.set(ECommandService.class, + serviceLocator.getService(ECommandService.class)); + eclipseContext.set(EHandlerService.class, + serviceLocator.getService(EHandlerService.class)); + + registerGlobalTextActionHandlers(); + return true; + } + return false; + } + + private void registerGlobalTextActionHandlers() { + activateGlobalTextHandler(ActionFactory.UNDO, + ITextOperationTarget.UNDO); + activateGlobalTextHandler(ActionFactory.REDO, + ITextOperationTarget.REDO); + activateGlobalTextHandler(ActionFactory.CUT, ITextOperationTarget.CUT); + activateGlobalTextHandler(ActionFactory.COPY, + ITextOperationTarget.COPY); + activateGlobalTextHandler(ActionFactory.PASTE, + ITextOperationTarget.PASTE); + activateGlobalTextHandler(ActionFactory.SELECT_ALL, + ITextOperationTarget.SELECT_ALL); + } + + private void activateGlobalTextHandler(ActionFactory actionFactory, + int textOp) { + TextAction textAction = new TextAction(textOp); + String commandId = actionFactory.getCommandId(); + textAction.setActionDefinitionId(commandId); + Object handler = new EActionHandler(textAction); + handlerService.activateHandler(commandId, handler); + handlers.put(commandId, handler); + + textAction.setId(actionFactory.getId()); + IWorkbenchAction workbenchAction = actionFactory + .create(getAdapter(IWorkbenchWindow.class)); + textAction.setText(workbenchAction.getText()); + workbenchAction.dispose(); + textActions.add(textAction); + globalActions.put(actionFactory.getId(), textAction); + } + + private void unregisterGlobalTextActionHandlers() { + if (handlerService != null) { + for (Entry entry : handlers.entrySet()) { + handlerService.deactivateHandler(entry.getKey(), + entry.getValue()); + } + handlers.clear(); + } + } + + public IAction getGlobalAction(String actionId) { + return globalActions.get(actionId); + } + + public void updateTextActions(TextViewer textViewer) { + if (textViewer != null) { + for (TextAction action : textActions) { + action.update(textViewer); + } + } + } + + private void activateHandlers() { + handlerService.activateHandler("org.xmind.ui.command.commitComments", //$NON-NLS-1$ + commitCommentHandler); + } + + private void deactivateHandlers() { + handlerService.deactivateHandler("org.xmind.ui.command.commitComments", //$NON-NLS-1$ + commitCommentHandler); + } + + private void saveComment() { + if (contentViewer != null) { + contentViewer.save(); + } + } + + protected void setFocus() { + super.setFocus(); + if (control != null && !control.isDisposed()) { + control.setFocus(); + } + } + + private void setContributingEditor(IGraphicalEditor editor) { + if (editor == contributingEditor) { + return; + } + + if (contributingEditor != null) { + ISelectionProvider selectionProvider = contributingEditor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) + selectionProvider.removeSelectionChangedListener(this); + } + + contributingEditor = editor; + + if (contributingEditor != null) { + ISelectionProvider selectionProvider = contributingEditor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.addSelectionChangedListener(this); + } + } + + if (getControl().isDisposed()) { + return; + } + if (contentViewer != null) { + contentViewer.setTargetEditor(contributingEditor); + } + if (contributor != null) { + contributor.setTargetEditor(contributingEditor); + } + + ISheet sheet = getSheet(contributingEditor); + setInput(sheet); + } + + public void partActivated(IWorkbenchPart part) { + if (part instanceof IGraphicalEditor) { + setContributingEditor((IGraphicalEditor) part); + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + if (part == this.contributingEditor) { + setContributingEditor(null); + } + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + public void selectionChanged(SelectionChangedEvent event) { + ISheet sheet = getSheet(contributingEditor); + setInput(sheet); + } + + private ISheet getSheet(IGraphicalEditor editor) { + if (editor != null && editor.getActivePageInstance() != null) { + return (ISheet) editor.getActivePageInstance() + .getAdapter(ISheet.class); + } else { + return null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + final String type = event.getType(); + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + if (!contentComposite.isDisposed()) { + if (Core.CommentAdd.equals(type) + || Core.CommentRemove.equals(type)) { + update(); + } else if (Core.CommentContent.equals(type)) { + IComment comment = (IComment) event.getSource(); + if (comment.isOrphan()) { + return; + } + Object source = comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()); + if ((source instanceof ITopic + && ((ITopic) source).getOwnedSheet() == sheet) + || source instanceof ISheet + && source == sheet) { + update(); + } + } + } + } + }); + } + + public void moveToPreviousTextViewer(CommentTextViewer implementation) { + List implementations = contentViewer + .getImplementations(); + int index = implementations.indexOf(implementation); + if (index <= 0 || index > implementations.size() - 1) { + return; + } + + setSelection(new StructuredSelection(implementations.get(index - 1))); + } + + public void moveToNextTextViewer(CommentTextViewer implementation) { + List implementations = contentViewer + .getImplementations(); + int index = implementations.indexOf(implementation); + if (index < 0 || index >= implementations.size() - 1) { + return; + } + + setSelection(new StructuredSelection(implementations.get(index + 1))); + } + + private void setSelection(ISelection selection) { + selectionProvider.setSelection(selection); + } + + //It can be only used in getAdapter() for findReplaceAction. + private CommentTextViewer getImplementation() { + if (selectionProvider instanceof CommentsSelectionProvider) { + ISelection selection = selectionProvider.getSelection(); + if (selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + if (obj instanceof CommentTextViewer) { + return (CommentTextViewer) obj; + } + } + + ISelection oldSelection = ((CommentsSelectionProvider) selectionProvider) + .getOldSelection(); + if (oldSelection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) oldSelection) + .getFirstElement(); + if (obj instanceof CommentTextViewer) { + return (CommentTextViewer) obj; + } + } + } + + return null; + } + + public Composite getContentComposite() { + return contentComposite; + } + + public ScrolledComposite getScrolledComposite() { + return sc; + } + + public ICommentsActionBarContributor getContributor() { + return contributor; + } + + public void setLatestCreatedComment(IComment latestCreatedComment) { + this.latestCreatedComment = latestCreatedComment; + } + + public IComment getLatestCreatedComment() { + return latestCreatedComment; + } + + public void setSelectedComment(IComment selectedComment) { + this.selectedComment = selectedComment; + } + + public IComment getSelectedComment() { + return selectedComment; + } + + public Control getControl() { + return control; + } + + @Override + public void createComment(String objectId) { + contentViewer.createNewComment(objectId); + } + + @Override + public void cancelCreateComment() { + contentViewer.cancelCreateNewComment(); + } + + public void setEditingComment(IComment editingComment) { + this.editingComment = editingComment; + } + + public IComment getEditingComment() { + return editingComment; + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + public boolean isModified() { + return modified; + } + + public void setInsertTarget(String objectId) { + this.insertTarget = objectId; + } + + public String getInsertTarget() { + return insertTarget; + } + + public IWorkbenchPart getContributingPart() { + return contributingEditor; + } + + public void dispose() { + unhookSheet(); + deactivateHandlers(); + if (contributor != null) { + contributor.dispose(); + } + if (sc != null && !sc.isDisposed()) { + sc.removeControlListener(getControlListener()); + } + getAdapter(IWorkbenchWindow.class).getActivePage() + .removePartListener(this); + setContributingEditor(null); + unregisterGlobalTextActionHandlers(); + + super.dispose(); + + textActions = null; + } + + @Override + public T getAdapter(Class adapter) { + if (adapter == IContributedContentsView.class) { + return adapter.cast(this); + } else if (adapter == ITextViewer.class) { + return adapter.cast(getImplementation() == null ? null + : getImplementation().getTextViewer()); + } + return super.getAdapter(adapter); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/IModelConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/IModelConstants.java index 43c8687d1..a1024db9b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/IModelConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/IModelConstants.java @@ -1,88 +1,89 @@ -package org.xmind.ui.internal.e4models; - -public interface IModelConstants { - - /* - * Keys - */ - public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID = "org.xmind.ui.commandParameter.modelPart.partStackId"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID = "org.xmind.ui.commandParameter.modelPart.partId"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID = "org.xmind.ui.commandParameter.modelPart.pageId"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_CURRENT_PAGE_ID = "org.xmind.ui.modelPart.currentPageId"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_REFRESH_PAGE = "org.xmind.ui.modelPart.refreshPage"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_SET_DEFAULT = "org.xmind.ui.modelPart.setDefault"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_DUPLICATE = "org.xmind.ui.modelPart.duplicate"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_RENAME = "org.xmind.ui.modelPart.rename"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_DELETE = "org.xmind.ui.modelPart.delete"; //$NON-NLS-1$ - public static final String KEY_MODEL_PART_EDIT = "org.xmind.ui.modelPart.edit"; //$NON-NLS-1$ - public static final String KEY_LAST_OPENED_MODEL_PART_ID = "org.xmind.ui.modelPart.lastOpened"; //$NON-NLS-1$ - - public static final String KEY_DIALOG_PART_CUSTOM_LOCATION = "org.xmind.ui.dialogPart.customLocation"; //$NON-NLS-1$ - - /* - * Commands - */ - public static final String COMMAND_SHOW_DIALOG_PART = "org.xmind.ui.command.showDialogPart"; //$NON-NLS-1$ - public static final String COMMAND_SHOW_MODEL_PART = "org.xmind.ui.command.showModelPart"; //$NON-NLS-1$ - public static final String COMMAND_SHOW_POPOVER = "org.xmind.ui.command.showPopover"; //$NON-NLS-1$ - - /* - * PartStackIds - */ - public static final String PART_STACK_ID_RIGHT = "org.xmind.ui.stack.right"; //$NON-NLS-1$ - - /* - * PartIds - */ - public static final String PART_ID_IMAGE = "org.xmind.ui.modelPart.image"; //$NON-NLS-1$ - public static final String PART_ID_NOTES = "org.xmind.ui.modelPart.notes"; //$NON-NLS-1$ - public static final String PART_ID_THEMES = "org.xmind.ui.modelPart.themes"; //$NON-NLS-1$ - public static final String PART_ID_OUTLINE = "org.xmind.ui.modelPart.outline"; //$NON-NLS-1$ - public static final String PART_ID_MARKERS = "org.xmind.ui.modelPart.markers"; //$NON-NLS-1$ - public static final String PART_ID_COMMENTS = "org.xmind.ui.modelPart.comments"; //$NON-NLS-1$ - public static final String PART_ID_PROPERTIES = "org.xmind.ui.modelPart.properties"; //$NON-NLS-1$ - public static final String PART_ID_TASKINFO = "org.xmind.ui.modelPart.taskinfo"; //$NON-NLS-1$ - public static final String PART_ID_RESOURCE_MANAGER = "org.xmind.ui.dialogPart.resourceManager"; //$NON-NLS-1$ - public static final String PART_ID_COMPATIBILITY_EDITOR = "org.eclipse.e4.ui.compatibility.editor"; //$NON-NLS-1$ - - /* - * PageIds - */ - public static final String PAGE_ID_RESOURCE_MANAGER_TEMPLATE = "org.xmind.ui.dialogPart.resourceManager.template"; //$NON-NLS-1$ - public static final String PAGE_ID_RESOURCE_MANAGER_CLIPART = "org.xmind.ui.dialogPart.resourceManager.clipArt"; //$NON-NLS-1$ - public static final String PAGE_ID_RESOURCE_MANAGER_MARKER = "org.xmind.ui.dialogPart.resourceManager.marker"; //$NON-NLS-1$ - public static final String PAGE_ID_RESOURCE_MANAGER_THEME = "org.xmind.ui.dialogPart.resourceManager.theme"; //$NON-NLS-1$ - public static final String PAGE_ID_RESOURCE_MANAGER_STYLE = "org.xmind.ui.dialogPart.resourceManager.style"; //$NON-NLS-1$ - - /* - * ViewMenuIds - */ - public static final String VIEWMENU_ID_THEME = "org.xmind.ui.modelPart.theme.viewMenu"; //$NON-NLS-1$ - - /* - * PopupMenuIds - */ - public static final String POPUPMENU_ID_RESOURCEMANAGER_TEMPLATE = "org.xmind.ui.dialogPart.resourceManager.template.popupMenu"; //$NON-NLS-1$ - public static final String POPUPMENU_ID_RESOURCEMANAGER_CLIPART = "org.xmind.ui.dialogPart.resourceManager.clipArt.popupMenu"; //$NON-NLS-1$ - public static final String POPUPMENU_ID_RESOURCEMANAGER_MARKER = "org.xmind.ui.dialogPart.resourceManager.marker.popupMenu"; //$NON-NLS-1$ - public static final String POPUPMENU_ID_RESOURCEMANAGER_THEME = "org.xmind.ui.dialogPart.resourceManager.theme.popupMenu"; //$NON-NLS-1$ - public static final String POPUPMENU_ID_RESOURCEMANAGER_STYLE = "org.xmind.ui.dialogPart.resourceManager.style.popupMenu"; //$NON-NLS-1$ - - /* - * PersistedState Keys - */ - public static final String PERSISTED_STATE_KEY_UNSELECTED_ICONURI = "unselectedIconURI"; //$NON-NLS-1$ - public static final String PERSISTED_STATE_KEY_SELECTED_ICONURI = "selectedIconURI"; //$NON-NLS-1$ - - /* - * tags - */ - public static final String DIRECT_COMMAD_TAG = "DirectCommand"; //$NON-NLS-1$ - public static final String TAG_ACTIVE = "active"; //$NON-NLS-1$ - public static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ - - /* - * Popover toolItem Ids - */ - public static final String TOOLITEM_ID_MARKER_POPOVER = "org.xmind.ui.toolbar.mindmap.marker"; //$NON-NLS-1$ -} +package org.xmind.ui.internal.e4models; + +public interface IModelConstants { + + /* + * Keys + */ + public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID = "org.xmind.ui.commandParameter.modelPart.partStackId"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID = "org.xmind.ui.commandParameter.modelPart.partId"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID = "org.xmind.ui.commandParameter.modelPart.pageId"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_CURRENT_PAGE_ID = "org.xmind.ui.modelPart.currentPageId"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_REFRESH_PAGE = "org.xmind.ui.modelPart.refreshPage"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_SET_DEFAULT = "org.xmind.ui.modelPart.setDefault"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_DUPLICATE = "org.xmind.ui.modelPart.duplicate"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_RENAME = "org.xmind.ui.modelPart.rename"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_DELETE = "org.xmind.ui.modelPart.delete"; //$NON-NLS-1$ + public static final String KEY_MODEL_PART_EDIT = "org.xmind.ui.modelPart.edit"; //$NON-NLS-1$ + public static final String KEY_LAST_OPENED_MODEL_PART_ID = "org.xmind.ui.modelPart.lastOpened"; //$NON-NLS-1$ + + public static final String KEY_DIALOG_PART_CUSTOM_LOCATION = "org.xmind.ui.dialogPart.customLocation"; //$NON-NLS-1$ + + /* + * Commands + */ + public static final String COMMAND_SHOW_DIALOG_PART = "org.xmind.ui.command.showDialogPart"; //$NON-NLS-1$ + public static final String COMMAND_SHOW_MODEL_PART = "org.xmind.ui.command.showModelPart"; //$NON-NLS-1$ + public static final String COMMAND_SHOW_POPOVER = "org.xmind.ui.command.showPopover"; //$NON-NLS-1$ + + /* + * PartStackIds + */ + public static final String PART_STACK_ID_RIGHT = "org.xmind.ui.stack.right"; //$NON-NLS-1$ + + /* + * PartIds + */ + public static final String PART_ID_IMAGE = "org.xmind.ui.modelPart.image"; //$NON-NLS-1$ + public static final String PART_ID_NOTES = "org.xmind.ui.modelPart.notes"; //$NON-NLS-1$ + public static final String PART_ID_THEMES = "org.xmind.ui.modelPart.themes"; //$NON-NLS-1$ + public static final String PART_ID_OUTLINE = "org.xmind.ui.modelPart.outline"; //$NON-NLS-1$ + public static final String PART_ID_MARKERS = "org.xmind.ui.modelPart.markers"; //$NON-NLS-1$ + public static final String PART_ID_COMMENTS = "org.xmind.ui.modelPart.comments"; //$NON-NLS-1$ + public static final String PART_ID_PROPERTIES = "org.xmind.ui.modelPart.properties"; //$NON-NLS-1$ + public static final String PART_ID_TASKINFO = "org.xmind.ui.modelPart.taskinfo"; //$NON-NLS-1$ + public static final String PART_ID_RESOURCE_MANAGER = "org.xmind.ui.dialogPart.resourceManager"; //$NON-NLS-1$ + public static final String PART_ID_COMPATIBILITY_EDITOR = "org.eclipse.e4.ui.compatibility.editor"; //$NON-NLS-1$ + + /* + * PageIds + */ + public static final String PAGE_ID_RESOURCE_MANAGER_TEMPLATE = "org.xmind.ui.dialogPart.resourceManager.template"; //$NON-NLS-1$ + public static final String PAGE_ID_RESOURCE_MANAGER_CLIPART = "org.xmind.ui.dialogPart.resourceManager.clipArt"; //$NON-NLS-1$ + public static final String PAGE_ID_RESOURCE_MANAGER_MARKER = "org.xmind.ui.dialogPart.resourceManager.marker"; //$NON-NLS-1$ + public static final String PAGE_ID_RESOURCE_MANAGER_THEME = "org.xmind.ui.dialogPart.resourceManager.theme"; //$NON-NLS-1$ + public static final String PAGE_ID_RESOURCE_MANAGER_STYLE = "org.xmind.ui.dialogPart.resourceManager.style"; //$NON-NLS-1$ + + /* + * ViewMenuIds + */ + public static final String VIEWMENU_ID_THEME = "org.xmind.ui.modelPart.theme.viewMenu"; //$NON-NLS-1$ + + /* + * PopupMenuIds + */ + public static final String POPUPMENU_ID_RESOURCEMANAGER_TEMPLATE = "org.xmind.ui.dialogPart.resourceManager.template.popupMenu"; //$NON-NLS-1$ + public static final String POPUPMENU_ID_RESOURCEMANAGER_CLIPART = "org.xmind.ui.dialogPart.resourceManager.clipArt.popupMenu"; //$NON-NLS-1$ + public static final String POPUPMENU_ID_RESOURCEMANAGER_MARKER = "org.xmind.ui.dialogPart.resourceManager.marker.popupMenu"; //$NON-NLS-1$ + public static final String POPUPMENU_ID_RESOURCEMANAGER_THEME = "org.xmind.ui.dialogPart.resourceManager.theme.popupMenu"; //$NON-NLS-1$ + public static final String POPUPMENU_ID_RESOURCEMANAGER_STYLE = "org.xmind.ui.dialogPart.resourceManager.style.popupMenu"; //$NON-NLS-1$ + + /* + * PersistedState Keys + */ + public static final String PERSISTED_STATE_KEY_UNSELECTED_ICONURI = "unselectedIconURI"; //$NON-NLS-1$ + public static final String PERSISTED_STATE_KEY_SELECTED_ICONURI = "selectedIconURI"; //$NON-NLS-1$ + + /* + * tags + */ + public static final String DIRECT_COMMAD_TAG = "DirectCommand"; //$NON-NLS-1$ + public static final String TAG_ACTIVE = "active"; //$NON-NLS-1$ + public static final String TAG_EDITOR = "Editor"; //$NON-NLS-1$ + public static final String TAG_X_STACK = "XStack"; //$NON-NLS-1$ + + /* + * Popover toolItem Ids + */ + public static final String TOOLITEM_ID_MARKER_POPOVER = "org.xmind.ui.toolbar.mindmap.marker"; //$NON-NLS-1$ +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ImagePart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ImagePart.java index 5e246f3c1..369b68625 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ImagePart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ImagePart.java @@ -1,10 +1,10 @@ - -package org.xmind.ui.internal.e4models; - -import org.xmind.ui.internal.e4models.MultiPageModelPart; - -public class ImagePart extends MultiPageModelPart { - - public static final String PART_ID = "org.xmind.ui.modelPart.image"; //$NON-NLS-1$ - -} + +package org.xmind.ui.internal.e4models; + +import org.xmind.ui.internal.e4models.MultiPageModelPart; + +public class ImagePart extends MultiPageModelPart { + + public static final String PART_ID = "org.xmind.ui.modelPart.image"; //$NON-NLS-1$ + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageModelPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageModelPage.java index 572e01d7d..7ca6659e7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageModelPage.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageModelPage.java @@ -1,339 +1,339 @@ -package org.xmind.ui.internal.e4models; - -import javax.inject.Inject; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.resource.ColorDescriptor; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.core.ITopic; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.dialogs.DialogUtils; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.MindMapUtils; - -public class LocalImageModelPage extends ModelPage - implements ISelectionChangedListener, IPartListener { - - public static final String PAGE_ID = "org.xmind.ui.modelPart.image.pages.local"; //$NON-NLS-1$ - - private class InsertImageAction extends Action { - - public void run() { - IGraphicalEditorPage page = (getEditor() == null ? null - : getEditor().getActivePageInstance()); - if (page == null || page.isDisposed()) { - return; - } - - EditDomain domain = page.getEditDomain(); - if (domain == null) { - return; - } - - IGraphicalViewer viewer = page.getViewer(); - if (viewer == null) { - return; - } - - Control control = viewer.getControl(); - if (control == null || control.isDisposed()) { - return; - } - - ISelection selection = viewer.getSelection(); - if (selection.isEmpty() - || !(selection instanceof IStructuredSelection)) { - return; - } - - Object o = ((IStructuredSelection) selection).getFirstElement(); - IPart part = viewer.findPart(o); - ITopic topic = (ITopic) part.getAdapter(ITopic.class); - if (topic == null) { - return; - } - - IPart topicPart = viewer.findPart(topic); - if (topicPart == null) { - return; - } - - FileDialog dialog = new FileDialog(control.getShell(), SWT.OPEN); - DialogUtils.makeDefaultImageSelectorDialog(dialog, true); - dialog.setText(DialogMessages.SelectImageDialog_title); - String path = dialog.open(); - if (path == null) { - return; - } - - insertImage(path, topicPart, viewer, domain); - } - - private void insertImage(String path, IPart topicPart, IViewer viewer, - EditDomain domain) { - Request request = new Request(MindMapUI.REQ_ADD_IMAGE); - request.setViewer(viewer); - request.setPrimaryTarget(topicPart); - request.setParameter(GEF.PARAM_PATH, new String[] { path }); - domain.handleRequest(request); - } - } - - @Inject - private IWorkbenchWindow workbenchWindow; - - private ResourceManager resources; - - private Button button; - - private IGraphicalEditor editor; - - @Override - public String getModelPageId() { - return PAGE_ID; - } - - @Override - public String getModelPageTitle() { - return MindMapMessages.LocalImageModelPage_title; - } - - @Override - protected Control doCreateControl(Composite parent) { - Composite container = new Composite(parent, SWT.NONE); - resources = new LocalResourceManager(JFaceResources.getResources(), - container); - container.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - container.setLayoutData(new GridData(GridData.FILL_BOTH)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - container.setLayout(layout); - - createContent(container); - - //add dispose listener - container.addDisposeListener(new DisposeListener() { - - @Override - public void widgetDisposed(DisposeEvent e) { - dispose(); - } - }); - - return container; - } - - private void createContent(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, true)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 60; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - createImageSection(composite); - createButtonSection(composite); - } - - private void createImageSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 20; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - Label image = new Label(composite, SWT.NONE); - image.setBackground(composite.getBackground()); - image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); - image.setImage((Image) resources.get(MindMapUI.getImages() - .get("insert_local_image_page.png", true))); //$NON-NLS-1$ - - Composite composite2 = new Composite(composite, SWT.NONE); - composite2.setBackground(parent.getBackground()); - composite2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout layout2 = new GridLayout(1, false); - layout2.marginWidth = 10; - layout2.marginHeight = 0; - composite2.setLayout(layout2); - - Label text = new Label(composite2, SWT.WRAP); - text.setBackground(composite2.getBackground()); - text.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); - text.setForeground((Color) resources - .get(ColorDescriptor.createFrom(ColorUtils.toRGB("#aaaaaa")))); //$NON-NLS-1$ - text.setAlignment(SWT.CENTER); - text.setFont((Font) resources.get(FontDescriptor.createFrom( - FontUtils.relativeHeight(text.getFont().getFontData(), 2)))); - text.setText( - MindMapMessages.LocalImageModelPage_ImageSection_description); - - } - - private void createButtonSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - - button = new Button(composite, SWT.PUSH); - button.setBackground(composite.getBackground()); - GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, false); - layoutData.widthHint = 90; - button.setLayoutData(layoutData); - button.setText(MindMapMessages.LocalImageModelPage_Insert_button); - - final InsertImageAction insertImageAction = new InsertImageAction(); - - button.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - insertImageAction.run(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - //set button state - setTargetEditor(getEditor()); - workbenchWindow.getActivePage().addPartListener(this); - } - - public void setFocus() { - if (button != null && !button.isDisposed()) { - button.setFocus(); - } - } - - private void setTargetEditor(IGraphicalEditor editor) { - if (editor == this.editor) { - return; - } - - if (this.editor != null) { - this.editor.getSite().getSelectionProvider() - .removeSelectionChangedListener(this); - } - this.editor = editor; - if (this.editor != null) { - this.editor.getSite().getSelectionProvider() - .addSelectionChangedListener(this); - setSelection( - editor.getSite().getSelectionProvider().getSelection()); - } else { - setSelection(null); - } - } - - @Override - public void selectionChanged(SelectionChangedEvent event) { - setSelection(event.getSelection()); - } - - private void setSelection(ISelection selection) { - boolean isEnabled = MindMapUtils.isSingleTopic(selection); - if (button != null && !button.isDisposed()) { - button.setEnabled(isEnabled); - } - } - - @Override - public void partActivated(IWorkbenchPart part) { - if (part instanceof IGraphicalEditor) { - setTargetEditor((IGraphicalEditor) part); - } - } - - @Override - public void partBroughtToTop(IWorkbenchPart part) { - } - - @Override - public void partClosed(IWorkbenchPart part) { - setTargetEditor(null); - } - - @Override - public void partDeactivated(IWorkbenchPart part) { - } - - @Override - public void partOpened(IWorkbenchPart part) { - } - - private void dispose() { - setTargetEditor(null); - workbenchWindow.getActivePage().removePartListener(this); - } - - private IGraphicalEditor getEditor() { - IEditorPart activeEditor = workbenchWindow.getActivePage() - .getActiveEditor(); - if (activeEditor instanceof IGraphicalEditor) { - return (IGraphicalEditor) activeEditor; - } - return null; - } - -} +package org.xmind.ui.internal.e4models; + +import javax.inject.Inject; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.xmind.core.ITopic; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.MindMapUtils; + +public class LocalImageModelPage extends ModelPage + implements ISelectionChangedListener, IPartListener { + + public static final String PAGE_ID = "org.xmind.ui.modelPart.image.pages.local"; //$NON-NLS-1$ + + private class InsertImageAction extends Action { + + public void run() { + IGraphicalEditorPage page = (getEditor() == null ? null + : getEditor().getActivePageInstance()); + if (page == null || page.isDisposed()) { + return; + } + + EditDomain domain = page.getEditDomain(); + if (domain == null) { + return; + } + + IGraphicalViewer viewer = page.getViewer(); + if (viewer == null) { + return; + } + + Control control = viewer.getControl(); + if (control == null || control.isDisposed()) { + return; + } + + ISelection selection = viewer.getSelection(); + if (selection.isEmpty() + || !(selection instanceof IStructuredSelection)) { + return; + } + + Object o = ((IStructuredSelection) selection).getFirstElement(); + IPart part = viewer.findPart(o); + ITopic topic = (ITopic) part.getAdapter(ITopic.class); + if (topic == null) { + return; + } + + IPart topicPart = viewer.findPart(topic); + if (topicPart == null) { + return; + } + + FileDialog dialog = new FileDialog(control.getShell(), SWT.OPEN); + DialogUtils.makeDefaultImageSelectorDialog(dialog, true); + dialog.setText(DialogMessages.SelectImageDialog_title); + String path = dialog.open(); + if (path == null) { + return; + } + + insertImage(path, topicPart, viewer, domain); + } + + private void insertImage(String path, IPart topicPart, IViewer viewer, + EditDomain domain) { + Request request = new Request(MindMapUI.REQ_ADD_IMAGE); + request.setViewer(viewer); + request.setPrimaryTarget(topicPart); + request.setParameter(GEF.PARAM_PATH, new String[] { path }); + domain.handleRequest(request); + } + } + + @Inject + private IWorkbenchWindow workbenchWindow; + + private ResourceManager resources; + + private Button button; + + private IGraphicalEditor editor; + + @Override + public String getModelPageId() { + return PAGE_ID; + } + + @Override + public String getModelPageTitle() { + return MindMapMessages.LocalImageModelPage_title; + } + + @Override + protected Control doCreateControl(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + resources = new LocalResourceManager(JFaceResources.getResources(), + container); + container.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + container.setLayout(layout); + + createContent(container); + + //add dispose listener + container.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); + + return container; + } + + private void createContent(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, true)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 60; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + createImageSection(composite); + createButtonSection(composite); + } + + private void createImageSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 20; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + Label image = new Label(composite, SWT.NONE); + image.setBackground(composite.getBackground()); + image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); + image.setImage((Image) resources.get(MindMapUI.getImages() + .get("insert_local_image_page.png", true))); //$NON-NLS-1$ + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(parent.getBackground()); + composite2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout layout2 = new GridLayout(1, false); + layout2.marginWidth = 10; + layout2.marginHeight = 0; + composite2.setLayout(layout2); + + Label text = new Label(composite2, SWT.WRAP); + text.setBackground(composite2.getBackground()); + text.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); + text.setForeground((Color) resources + .get(ColorDescriptor.createFrom(ColorUtils.toRGB("#aaaaaa")))); //$NON-NLS-1$ + text.setAlignment(SWT.CENTER); + text.setFont((Font) resources.get(FontDescriptor.createFrom( + FontUtils.relativeHeight(text.getFont().getFontData(), 2)))); + text.setText( + MindMapMessages.LocalImageModelPage_ImageSection_description); + + } + + private void createButtonSection(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + + button = new Button(composite, SWT.PUSH); + button.setBackground(composite.getBackground()); + GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, false); + layoutData.widthHint = 90; + button.setLayoutData(layoutData); + button.setText(MindMapMessages.LocalImageModelPage_Insert_button); + + final InsertImageAction insertImageAction = new InsertImageAction(); + + button.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + insertImageAction.run(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + //set button state + setTargetEditor(getEditor()); + workbenchWindow.getActivePage().addPartListener(this); + } + + public void setFocus() { + if (button != null && !button.isDisposed()) { + button.setFocus(); + } + } + + private void setTargetEditor(IGraphicalEditor editor) { + if (editor == this.editor) { + return; + } + + if (this.editor != null) { + this.editor.getSite().getSelectionProvider() + .removeSelectionChangedListener(this); + } + this.editor = editor; + if (this.editor != null) { + this.editor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + setSelection( + editor.getSite().getSelectionProvider().getSelection()); + } else { + setSelection(null); + } + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + setSelection(event.getSelection()); + } + + private void setSelection(ISelection selection) { + boolean isEnabled = MindMapUtils.isSingleTopic(selection); + if (button != null && !button.isDisposed()) { + button.setEnabled(isEnabled); + } + } + + @Override + public void partActivated(IWorkbenchPart part) { + if (part instanceof IGraphicalEditor) { + setTargetEditor((IGraphicalEditor) part); + } + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + } + + @Override + public void partClosed(IWorkbenchPart part) { + setTargetEditor(null); + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + } + + @Override + public void partOpened(IWorkbenchPart part) { + } + + private void dispose() { + setTargetEditor(null); + workbenchWindow.getActivePage().removePartListener(this); + } + + private IGraphicalEditor getEditor() { + IEditorPart activeEditor = workbenchWindow.getActivePage() + .getActiveEditor(); + if (activeEditor instanceof IGraphicalEditor) { + return (IGraphicalEditor) activeEditor; + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageProcessor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageProcessor.java index 62f2e4876..e62e5e706 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageProcessor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageProcessor.java @@ -1,37 +1,37 @@ -package org.xmind.ui.internal.e4models; - -import java.util.Map; - -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; -import org.eclipse.e4.ui.workbench.modeling.EModelService; - -public class LocalImageProcessor { - - private static final String CONTRIBUTION_URI = "bundleclass://org.xmind.ui.mindmap/org.xmind.ui.internal.e4models.LocalImageModelPage"; //$NON-NLS-1$ - - @Execute - public void execute(MApplication application, EModelService modelService) { - MPartDescriptor partDescriptor = null; - for (MPartDescriptor mp : application.getDescriptors()) { - if (ImagePart.PART_ID.equals(mp.getElementId())) { - partDescriptor = mp; - break; - } - } - if (partDescriptor == null) - return; - - // Model Pages - Map persistedState = partDescriptor.getPersistedState(); - String lastUris = persistedState - .get(MultiPageModelPart.PERSISTED_STATE_PAGES_CONTRIBUTIONURI); - String newUris = (lastUris == null || lastUris.equals("")) //$NON-NLS-1$ - ? CONTRIBUTION_URI : lastUris + "," + CONTRIBUTION_URI; //$NON-NLS-1$ - persistedState.put( - MultiPageModelPart.PERSISTED_STATE_PAGES_CONTRIBUTIONURI, - newUris); - } - -} +package org.xmind.ui.internal.e4models; + +import java.util.Map; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; +import org.eclipse.e4.ui.workbench.modeling.EModelService; + +public class LocalImageProcessor { + + private static final String CONTRIBUTION_URI = "bundleclass://org.xmind.ui.mindmap/org.xmind.ui.internal.e4models.LocalImageModelPage"; //$NON-NLS-1$ + + @Execute + public void execute(MApplication application, EModelService modelService) { + MPartDescriptor partDescriptor = null; + for (MPartDescriptor mp : application.getDescriptors()) { + if (ImagePart.PART_ID.equals(mp.getElementId())) { + partDescriptor = mp; + break; + } + } + if (partDescriptor == null) + return; + + // Model Pages + Map persistedState = partDescriptor.getPersistedState(); + String lastUris = persistedState + .get(MultiPageModelPart.PERSISTED_STATE_PAGES_CONTRIBUTIONURI); + String newUris = (lastUris == null || lastUris.equals("")) //$NON-NLS-1$ + ? CONTRIBUTION_URI : lastUris + "," + CONTRIBUTION_URI; //$NON-NLS-1$ + persistedState.put( + MultiPageModelPart.PERSISTED_STATE_PAGES_CONTRIBUTIONURI, + newUris); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/MarkerPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/MarkerPart.java index 3c73e4ca6..04b94bab7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/MarkerPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/MarkerPart.java @@ -1,757 +1,761 @@ -package org.xmind.ui.internal.e4models; - -import static org.xmind.ui.mindmap.MindMapUI.REQ_ADD_MARKER; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DragSource; -import org.eclipse.swt.dnd.DragSourceEvent; -import org.eclipse.swt.dnd.DragSourceListener; -import org.eclipse.swt.dnd.DropTarget; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.DropTargetListener; -import org.eclipse.swt.dnd.FileTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.forms.widgets.ScrolledForm; -import org.eclipse.ui.forms.widgets.Section; -import org.xmind.core.Core; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerResource; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.forms.WidgetFactory; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dnd.MindMapElementTransfer; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; -import org.xmind.ui.util.MarkerImageDescriptor; - -public class MarkerPart extends ViewModelPart { - - private static final String VIEWMENU_ID_FOR_MARKERPART = "org.xmind.ui.modelpart.marker.viewmenu"; //$NON-NLS-1$ - - private WidgetFactory factory; - - private ScrolledForm form; - - private MarkerGroupPart recentPart; - - private MarkerSheetPart systemPart; - - private MarkerSheetPart userPart; - - private Map groupToPart = new HashMap(); - - private Map groupToSection = new HashMap(); - - @Override - protected Control doCreateContent(Composite parent) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("OpenMarkerPartCount"); //$NON-NLS-1$ - - factory = new WidgetFactory(parent.getDisplay()); - form = createForm(parent); - form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - form.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (factory != null) { - factory.dispose(); - factory = null; - } - } - }); - fillFormContent(); - return form; - } - - @Override - protected void init() { - super.init(); - registerViewMenu(VIEWMENU_ID_FOR_MARKERPART); - } - - private ScrolledForm createForm(Composite parent) { - ScrolledForm form = factory.createScrolledForm(parent); - form.setMinWidth(1); - return form; - } - - private void fillFormContent() { - final Composite compositeformbady = form.getBody(); - final GridLayout layout = new GridLayout(1, true); - layout.marginHeight = 3; - layout.marginWidth = 3; - layout.verticalSpacing = 7; - compositeformbady.setLayout(layout); - compositeformbady - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - Control control; - - control = createRecentSection(compositeformbady); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - control = createSystemSection(compositeformbady); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - control = createUserSection(compositeformbady); - control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - form.addListener(SWT.Resize, new Listener() { - public void handleEvent(Event event) { - int width = form.getClientArea().width; - width -= layout.marginLeft + layout.marginRight - + layout.marginWidth * 2; - Control[] controls = compositeformbady.getChildren(); - for (int i = 0; i < controls.length; i++) { - Control c = controls[i]; - ((GridData) c.getLayoutData()).widthHint = width; - } - form.reflow(true); - } - }); - - form.reflow(true); - } - - private Control createRecentSection(Composite composite) { - recentPart = new MarkerGroupPart( - MindMapUI.getResourceManager().getRecentMarkerGroup(), false); - Control con = recentPart.createControl(composite); - return con; - } - - private Control createSystemSection(Composite composite) { - systemPart = new MarkerSheetPart( - MindMapUI.getResourceManager().getSystemMarkerSheet()); - Control con = systemPart.createControl(composite); - return con; - } - - private Control createUserSection(Composite composite) { - userPart = new MarkerSheetPart( - MindMapUI.getResourceManager().getUserMarkerSheet()); - Control con = userPart.createControl(composite); - return con; - } - - private Section createSection(Composite parent, String title, - WidgetFactory factory) { - Section section = factory.createSection(parent, - Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED - | SWT.BORDER | Section.NO_TITLE_FOCUS_BOX); - section.setText(title); -// section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - return section; - } - - public void setFocus() { - if (form != null && !form.isDisposed()) - form.setFocus(); - } - - public void dispose() { - super.dispose(); - factory = null; - form = null; - recentPart = null; - systemPart = null; - userPart = null; - groupToPart.clear(); - groupToSection.clear(); - } - - protected class MarkerGroupPart implements ICoreEventListener { - - private IMarkerGroup group; - - private Section section; - - private boolean hasTitle; - - private ToolBarManager toolbar = null; - - private Control control = null; - - private ICoreEventRegister eventRegister = null; - - public MarkerGroupPart(IMarkerGroup group) { - this(group, true); - } - - public MarkerGroupPart(IMarkerGroup group, boolean hasTitle) { - this.group = group; - this.hasTitle = hasTitle; - } - - public IMarkerGroup getMarkerGroup() { - return group; - } - - public Control createControl(final Composite parent) { - if (control == null) { - section = createSection(parent, group.getName(), factory); - if (toolbar == null) { - toolbar = new ToolBarManager( - SWT.RIGHT | SWT.FLAT | SWT.WRAP); - } - Composite c = factory.createComposite(section, SWT.WRAP); - GridLayout layout = new GridLayout(1, true); - layout.marginHeight = 2; - layout.marginWidth = 2; - layout.verticalSpacing = 2; - c.setLayout(layout); - - if (hasTitle) { - factory.createLabel(c, group.getName()); - } - - final ToolBar tb = toolbar.createControl(c); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); - tb.setLayoutData(data); - addDragSource(tb); - addDropTarget(tb); - - control = section; - section.setClient(c); - - refresh(false); - installListeners(); - control.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - dispose(); - } - }); - } - return control; - } - - private void addDragSource(final ToolBar toolbar) { - final DragSource dragSource = new DragSource(toolbar, - DND.DROP_COPY); - dragSource.setTransfer( - new Transfer[] { MindMapElementTransfer.getInstance() }); - dragSource.addDragListener(new DragSourceListener() { - - ToolItem sourceItem; - - public void dragStart(DragSourceEvent event) { - sourceItem = toolbar.getItem(new Point(event.x, event.y)); - if (sourceItem == null) - event.doit = false; - else { - event.image = sourceItem.getImage(); - } - } - - public void dragSetData(DragSourceEvent event) { - if (sourceItem == null) - return; - - int index = toolbar.indexOf(sourceItem); - List visibleMarkers = new ArrayList(); - for (IMarker marker : group.getMarkers()) - if (!marker.isHidden()) - visibleMarkers.add(marker); - IMarker marker = visibleMarkers.get(index); - event.data = new Object[] { marker }; - } - - public void dragFinished(DragSourceEvent event) { - } - }); - toolbar.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - dragSource.dispose(); - } - }); - } - - private void addDropTarget(final ToolBar toolBar) { - final DropTarget dropTarget = new DropTarget(toolBar, - DND.DROP_COPY | DND.DROP_MOVE); - dropTarget - .setTransfer(new Transfer[] { FileTransfer.getInstance() }); - toolBar.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - dropTarget.dispose(); - } - }); - dropTarget.addDropListener(new DropTargetListener() { - - private Map> dirToMarkerPaths = new HashMap>(); - - public void dropAccept(DropTargetEvent event) { - if (!FileTransfer.getInstance() - .isSupportedType(event.currentDataType)) { - event.detail = DND.DROP_NONE; - } else if (event.detail == DND.DROP_DEFAULT) { - if ((event.operations & DND.DROP_COPY) != 0) { - event.detail = DND.DROP_COPY; - } else if ((event.operations & DND.DROP_MOVE) != 0) { - event.detail = DND.DROP_MOVE; - } - } - } - - public void drop(DropTargetEvent event) { - if (event.data instanceof String[]) { - IMarkerSheet userMarkerSheet = MindMapUI - .getResourceManager().getUserMarkerSheet(); - IMarkerSheet markerSheet = group.getParent(); - for (String path : (String[]) event.data) { - File dir = new File(path); - if (dir.isDirectory()) { - collectDirToMarkers(path, dirToMarkerPaths); - - Set folders = dirToMarkerPaths.keySet(); - for (String folder : folders) { - File tempDir = new File(folder); - if (tempDir.isDirectory()) { - List markerPaths = dirToMarkerPaths - .get(folder); - if (markerPaths != null - && !markerPaths.isEmpty()) { - IMarkerGroup markerGroup = userMarkerSheet - .createMarkerGroup(false); - markerGroup - .setName(tempDir.getName()); - userMarkerSheet.addMarkerGroup( - markerGroup); - for (String markerPath : markerPaths) { - if (imageValid(markerPath)) - createMarker(markerGroup, - markerPath); - } - } - } - } - } else if (dir.isFile() && imageValid(path)) { - if (markerSheet == MindMapUI - .getResourceManager() - .getSystemMarkerSheet()) { - IMarkerGroup markerGroup = userMarkerSheet - .createMarkerGroup(false); - markerGroup.setName( - MindMapMessages.MarkerView_UntitledGroup_name); - userMarkerSheet.addMarkerGroup(markerGroup); - createMarker(markerGroup, path); - } else if (userMarkerSheet == markerSheet) { - createMarker(group, path); - } - } - } - MindMapUI.getResourceManager().saveUserMarkerSheet(); - } - } - - private void collectDirToMarkers(String dirPath, - Map> dirToMarkerPaths) { - File directory = new File(dirPath); - if (directory.isDirectory()) { - List markerPaths = dirToMarkerPaths - .get(dirPath); - if (markerPaths == null) - markerPaths = new LinkedList(); - dirToMarkerPaths.put(dirPath, markerPaths); - - File[] files = directory.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - collectDirToMarkers(file.getAbsolutePath(), - dirToMarkerPaths); - } else if (file.isFile() - && imageValid(file.getAbsolutePath())) { - markerPaths.add(file.getAbsolutePath()); - } - } - } - } - - private void createMarker(IMarkerGroup targetGroup, - String sourcePath) { - String path = Core.getIdFactory().createId() - + FileUtils.getExtension(sourcePath); - IMarker marker = targetGroup.getOwnedSheet() - .createMarker(path); - marker.setName(FileUtils.getFileName(sourcePath)); - IMarkerResource resource = marker.getResource(); - if (resource != null) { - OutputStream os = resource.getOutputStream(); - if (os != null) { - try { - FileInputStream is = new FileInputStream( - sourcePath); - FileUtils.transfer(is, os, true); - } catch (IOException e) { - Logger.log(e); - } - } - } - targetGroup.addMarker(marker); - } - - private boolean imageValid(String sourcePath) { - try { - new Image(Display.getCurrent(), sourcePath).dispose(); - return true; - } catch (Throwable e) { - } - return false; - } - - public void dragOver(DropTargetEvent event) { - dropAccept(event); - } - - public void dragOperationChanged(DropTargetEvent event) { - dropAccept(event); - } - - public void dragLeave(DropTargetEvent event) { - dropAccept(event); - } - - public void dragEnter(DropTargetEvent event) { - dropAccept(event); - } - }); - - } - - private void installListeners() { - eventRegister = new CoreEventRegister(group, this); - eventRegister.register(Core.MarkerAdd); - eventRegister.register(Core.MarkerRemove); - eventRegister.register(Core.Name); - } - - private void uninstallListeners() { - if (eventRegister != null) - eventRegister.unregisterAll(); - } - - public Control getControl() { - return control; - } - - public void refresh(boolean reflow) { - if (toolbar == null || control == null || control.isDisposed()) - return; - section.setText(group.getName()); - - toolbar.removeAll(); - for (IMarker marker : group.getMarkers()) { - if (!group.isHidden() && !marker.isHidden()) - toolbar.add(new MarkerAction(marker)); - } - toolbar.update(false); - - ToolBar tb = toolbar.getControl(); - GridData data = (GridData) tb.getLayoutData(); - data.exclude = toolbar.isEmpty(); - tb.setVisible(!toolbar.isEmpty()); - - if (reflow) - form.reflow(true); - } - - public void dispose() { - uninstallListeners(); - if (toolbar != null) { - toolbar.dispose(); - toolbar = null; - } - if (control != null) { - control.dispose(); - control = null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - if (control == null || control.isDisposed()) - return; - - control.getDisplay().syncExec(new Runnable() { - public void run() { - String type = event.getType(); - if (Core.MarkerAdd.equals(type) - || Core.MarkerRemove.equals(type) - || Core.Name.equals(type)) { - refresh(true); - } - } - }); - } - - } - - protected class MarkerAction extends Action { - - private IMarker marker; - - public MarkerAction(IMarker marker) { - super(); - this.marker = marker; - setImageDescriptor(MarkerImageDescriptor.createFromMarker(marker, - 24, 24, false)); - setToolTipText(marker.getName()); - } - - public IMarker getMarker() { - return marker; - } - - public void run() { - IWorkbenchPage page = getAdapter(IWorkbenchWindow.class) - .getActivePage(); - if (page != null) { - IEditorPart editor = page.getActiveEditor(); - if (editor != null && editor instanceof IGraphicalEditor) { - IGraphicalEditorPage gp = ((IGraphicalEditor) editor) - .getActivePageInstance(); - if (gp != null) { - EditDomain domain = gp.getEditDomain(); - if (domain != null) { - Request req = new Request(REQ_ADD_MARKER) - .setViewer(gp.getViewer()).setDomain(domain) - .setParameter(MindMapUI.PARAM_MARKER_ID, - marker.getId()); - domain.handleRequest(req); - } - IViewer viewer = gp.getViewer(); - if (viewer != null) { - Control control = viewer.getControl(); - if (control != null && !control.isDisposed()) { - control.setFocus(); - } - } - } - } - } - } - } - - protected class MarkerSheetPart implements ICoreEventListener { - - private IMarkerSheet sheet; - - private Composite composite; - - private List groupParts = new ArrayList(); - - private List
    groupSections = new ArrayList
    (); - - private ICoreEventRegister eventRegister = null; - - public MarkerSheetPart(IMarkerSheet sheet) { - this.sheet = sheet; - } - - public Control getControl() { - return composite; - } - - public Control createControl(Composite parent) { - if (composite == null) { - composite = createComposite(parent); - refresh(false); - installListeners(); - composite.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - dispose(); - } - }); - } - return composite; - } - - private Composite createComposite(Composite parent) { - Composite composite = factory.createComposite(parent, SWT.WRAP); - GridLayout layout = new GridLayout(1, true); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.marginBottom = 0; - layout.marginLeft = 0; - layout.marginRight = 0; - layout.marginTop = 0; - layout.verticalSpacing = 7; - composite.setLayout(layout); - - return composite; - } - - public void refresh(boolean reflow) { - if (composite == null || composite.isDisposed()) - return; - - composite.setRedraw(false); - List newGroups = sheet.getMarkerGroups(); - int i; - for (i = 0; i < newGroups.size(); i++) { - IMarkerGroup group = newGroups.get(i); - if (i < groupParts.size()) { - MarkerGroupPart part = groupParts.get(i); - IMarkerGroup g = part.getMarkerGroup(); - if (group.equals(g)) { - continue; - } - } - - MarkerGroupPart part = groupToPart.get(group); - if (part != null) { - if (!newGroups.get(i).isHidden()) { - reorderChild(part, i); - } - } else { - if (!newGroups.get(i).isHidden()) { - part = createChild(group); - addChild(part, i); - } - } - } - - Object[] toTrim = groupParts.toArray(); - for (; i < toTrim.length; i++) { - removeChild((MarkerGroupPart) toTrim[i]); - } - - composite.setRedraw(true); -// form.reflow(true); - if (reflow) - form.reflow(true); - } - - public List getGroupParts() { - return groupParts; - } - - private void reorderChild(MarkerGroupPart part, int index) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("UseMarkersCount"); //$NON-NLS-1$ - - Control c = part.getControl(); - if (c == null) { - c = part.createControl(composite); -// c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - } - groupParts.remove(part); - groupParts.add(index, part); - groupSections.remove(part.section); - groupSections.add(index, part.section); - if (index == 0) { - c.moveAbove(null); - } else { - MarkerGroupPart g = groupParts.get(index - 1); - c.moveAbove(g.getControl()); - } - } - - private MarkerGroupPart createChild(IMarkerGroup group) { - MarkerGroupPart part = new MarkerGroupPart(group, false); - groupToPart.put(group, part); - return part; - } - - private void addChild(MarkerGroupPart part, int index) { - groupParts.add(index, part); - Control c = part.createControl(composite); - groupSections.add(index, part.section); - groupToSection.put(part.group, part.section); - c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - } - - private void removeChild(MarkerGroupPart part) { - groupParts.remove(part); - groupToPart.remove(part.getMarkerGroup()); - groupSections.remove(part.section); - groupToSection.remove(part.getMarkerGroup()); - part.section.dispose(); - part.dispose(); - } - - private void installListeners() { - eventRegister = new CoreEventRegister(sheet, this); - eventRegister.register(Core.MarkerGroupAdd); - eventRegister.register(Core.MarkerGroupRemove); - } - - private void uninstallListeners() { - if (eventRegister != null) - eventRegister.unregisterAll(); - } - - public void dispose() { - uninstallListeners(); - if (composite != null) { - composite.dispose(); - composite = null; - } - for (Object o : groupParts.toArray()) { - MarkerGroupPart groupPart = (MarkerGroupPart) o; - groupToPart.remove(groupPart.getMarkerGroup()); - groupToSection.remove(groupPart.getMarkerGroup()); - groupPart.dispose(); - } - groupParts.clear(); - groupSections.clear(); - } - - public void handleCoreEvent(final CoreEvent event) { - if (composite == null || composite.isDisposed()) - return; - - composite.getDisplay().syncExec(new Runnable() { - public void run() { - String type = event.getType(); - if (Core.MarkerGroupAdd.equals(type) - || Core.MarkerGroupRemove.equals(type)) { - refresh(true); - } - } - }); - } - } - -} +package org.xmind.ui.internal.e4models; + +import static org.xmind.ui.mindmap.MindMapUI.REQ_ADD_MARKER; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.xmind.core.Core; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerResource; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.forms.WidgetFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dnd.MindMapElementTransfer; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; +import org.xmind.ui.util.MarkerImageDescriptor; + +public class MarkerPart extends ViewModelPart { + + private static final String VIEWMENU_ID_FOR_MARKERPART = "org.xmind.ui.modelpart.marker.viewmenu"; //$NON-NLS-1$ + + private WidgetFactory factory; + + private ScrolledForm form; + + private MarkerGroupPart recentPart; + + private MarkerSheetPart systemPart; + + private MarkerSheetPart userPart; + + private Map groupToPart = new HashMap(); + + private Map groupToSection = new HashMap(); + + @Override + protected Control doCreateContent(Composite parent) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SHOW_MARKER_PART_COUNT); + + factory = new WidgetFactory(parent.getDisplay()); + form = createForm(parent); + form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + form.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (factory != null) { + factory.dispose(); + factory = null; + } + } + }); + fillFormContent(); + return form; + } + + @Override + protected void init() { + super.init(); + registerViewMenu(VIEWMENU_ID_FOR_MARKERPART); + } + + private ScrolledForm createForm(Composite parent) { + ScrolledForm form = factory.createScrolledForm(parent); + form.setMinWidth(1); + return form; + } + + private void fillFormContent() { + final Composite compositeformbady = form.getBody(); + final GridLayout layout = new GridLayout(1, true); + layout.marginHeight = 3; + layout.marginWidth = 3; + layout.verticalSpacing = 7; + compositeformbady.setLayout(layout); + compositeformbady + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Control control; + + control = createRecentSection(compositeformbady); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + control = createSystemSection(compositeformbady); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + control = createUserSection(compositeformbady); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + form.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event event) { + int width = form.getClientArea().width; + width -= layout.marginLeft + layout.marginRight + + layout.marginWidth * 2; + Control[] controls = compositeformbady.getChildren(); + for (int i = 0; i < controls.length; i++) { + Control c = controls[i]; + ((GridData) c.getLayoutData()).widthHint = width; + } + form.reflow(true); + } + }); + + form.reflow(true); + } + + private Control createRecentSection(Composite composite) { + recentPart = new MarkerGroupPart( + MindMapUI.getResourceManager().getRecentMarkerGroup(), false); + Control con = recentPart.createControl(composite); + return con; + } + + private Control createSystemSection(Composite composite) { + systemPart = new MarkerSheetPart( + MindMapUI.getResourceManager().getSystemMarkerSheet()); + Control con = systemPart.createControl(composite); + return con; + } + + private Control createUserSection(Composite composite) { + userPart = new MarkerSheetPart( + MindMapUI.getResourceManager().getUserMarkerSheet()); + Control con = userPart.createControl(composite); + return con; + } + + private Section createSection(Composite parent, String title, + WidgetFactory factory) { + Section section = factory.createSection(parent, + Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED + | SWT.BORDER | Section.NO_TITLE_FOCUS_BOX); + section.setText(title); +// section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + return section; + } + + protected void setFocus() { + super.setFocus(); + if (form != null && !form.isDisposed()) + form.setFocus(); + } + + public void dispose() { + super.dispose(); + factory = null; + form = null; + recentPart = null; + systemPart = null; + userPart = null; + groupToPart.clear(); + groupToSection.clear(); + } + + protected class MarkerGroupPart implements ICoreEventListener { + + private IMarkerGroup group; + + private Section section; + + private boolean hasTitle; + + private ToolBarManager toolbar = null; + + private Control control = null; + + private ICoreEventRegister eventRegister = null; + + public MarkerGroupPart(IMarkerGroup group) { + this(group, true); + } + + public MarkerGroupPart(IMarkerGroup group, boolean hasTitle) { + this.group = group; + this.hasTitle = hasTitle; + } + + public IMarkerGroup getMarkerGroup() { + return group; + } + + public Control createControl(final Composite parent) { + if (control == null) { + section = createSection(parent, group.getName(), factory); + if (toolbar == null) { + toolbar = new ToolBarManager( + SWT.RIGHT | SWT.FLAT | SWT.WRAP); + } + Composite c = factory.createComposite(section, SWT.WRAP); + GridLayout layout = new GridLayout(1, true); + layout.marginHeight = 2; + layout.marginWidth = 2; + layout.verticalSpacing = 2; + layout.marginLeft = Util.isMac() ? 17 : 7; + c.setLayout(layout); + + if (hasTitle) { + factory.createLabel(c, group.getName()); + } + + final ToolBar tb = toolbar.createControl(c); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); + tb.setLayoutData(data); + addDragSource(tb); + addDropTarget(tb); + + control = section; + section.setClient(c); + + refresh(false); + installListeners(); + control.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); + } + return control; + } + + private void addDragSource(final ToolBar toolbar) { + final DragSource dragSource = new DragSource(toolbar, + DND.DROP_COPY); + dragSource.setTransfer( + new Transfer[] { MindMapElementTransfer.getInstance() }); + dragSource.addDragListener(new DragSourceListener() { + + ToolItem sourceItem; + + public void dragStart(DragSourceEvent event) { + sourceItem = toolbar.getItem(new Point(event.x, event.y)); + if (sourceItem == null) + event.doit = false; + else { + event.image = sourceItem.getImage(); + } + } + + public void dragSetData(DragSourceEvent event) { + if (sourceItem == null) + return; + + int index = toolbar.indexOf(sourceItem); + List visibleMarkers = new ArrayList(); + for (IMarker marker : group.getMarkers()) + if (!marker.isHidden()) + visibleMarkers.add(marker); + IMarker marker = visibleMarkers.get(index); + event.data = new Object[] { marker }; + } + + public void dragFinished(DragSourceEvent event) { + } + }); + toolbar.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + dragSource.dispose(); + } + }); + } + + private void addDropTarget(final ToolBar toolBar) { + final DropTarget dropTarget = new DropTarget(toolBar, + DND.DROP_COPY | DND.DROP_MOVE); + dropTarget + .setTransfer(new Transfer[] { FileTransfer.getInstance() }); + toolBar.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + dropTarget.dispose(); + } + }); + dropTarget.addDropListener(new DropTargetListener() { + + private Map> dirToMarkerPaths = new HashMap>(); + + public void dropAccept(DropTargetEvent event) { + if (!FileTransfer.getInstance() + .isSupportedType(event.currentDataType)) { + event.detail = DND.DROP_NONE; + } else if (event.detail == DND.DROP_DEFAULT) { + if ((event.operations & DND.DROP_COPY) != 0) { + event.detail = DND.DROP_COPY; + } else if ((event.operations & DND.DROP_MOVE) != 0) { + event.detail = DND.DROP_MOVE; + } + } + } + + public void drop(DropTargetEvent event) { + if (event.data instanceof String[]) { + IMarkerSheet userMarkerSheet = MindMapUI + .getResourceManager().getUserMarkerSheet(); + IMarkerSheet markerSheet = group.getParent(); + for (String path : (String[]) event.data) { + File dir = new File(path); + if (dir.isDirectory()) { + collectDirToMarkers(path, dirToMarkerPaths); + + Set folders = dirToMarkerPaths.keySet(); + for (String folder : folders) { + File tempDir = new File(folder); + if (tempDir.isDirectory()) { + List markerPaths = dirToMarkerPaths + .get(folder); + if (markerPaths != null + && !markerPaths.isEmpty()) { + IMarkerGroup markerGroup = userMarkerSheet + .createMarkerGroup(false); + markerGroup + .setName(tempDir.getName()); + userMarkerSheet.addMarkerGroup( + markerGroup); + for (String markerPath : markerPaths) { + if (imageValid(markerPath)) + createMarker(markerGroup, + markerPath); + } + } + } + } + } else if (dir.isFile() && imageValid(path)) { + if (markerSheet == MindMapUI + .getResourceManager() + .getSystemMarkerSheet()) { + IMarkerGroup markerGroup = userMarkerSheet + .createMarkerGroup(false); + markerGroup.setName( + MindMapMessages.MarkerView_UntitledGroup_name); + userMarkerSheet.addMarkerGroup(markerGroup); + createMarker(markerGroup, path); + } else if (userMarkerSheet == markerSheet) { + createMarker(group, path); + } + } + } + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } + } + + private void collectDirToMarkers(String dirPath, + Map> dirToMarkerPaths) { + File directory = new File(dirPath); + if (directory.isDirectory()) { + List markerPaths = dirToMarkerPaths + .get(dirPath); + if (markerPaths == null) + markerPaths = new LinkedList(); + dirToMarkerPaths.put(dirPath, markerPaths); + + File[] files = directory.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + collectDirToMarkers(file.getAbsolutePath(), + dirToMarkerPaths); + } else if (file.isFile() + && imageValid(file.getAbsolutePath())) { + markerPaths.add(file.getAbsolutePath()); + } + } + } + } + + private void createMarker(IMarkerGroup targetGroup, + String sourcePath) { + String path = Core.getIdFactory().createId() + + FileUtils.getExtension(sourcePath); + IMarker marker = targetGroup.getOwnedSheet() + .createMarker(path); + marker.setName(FileUtils.getFileName(sourcePath)); + IMarkerResource resource = marker.getResource(); + if (resource != null) { + OutputStream os = resource.getOutputStream(); + if (os != null) { + try { + FileInputStream is = new FileInputStream( + sourcePath); + FileUtils.transfer(is, os, true); + } catch (IOException e) { + Logger.log(e); + } + } + } + targetGroup.addMarker(marker); + } + + private boolean imageValid(String sourcePath) { + try { + new Image(Display.getCurrent(), sourcePath).dispose(); + return true; + } catch (Throwable e) { + } + return false; + } + + public void dragOver(DropTargetEvent event) { + dropAccept(event); + } + + public void dragOperationChanged(DropTargetEvent event) { + dropAccept(event); + } + + public void dragLeave(DropTargetEvent event) { + dropAccept(event); + } + + public void dragEnter(DropTargetEvent event) { + dropAccept(event); + } + }); + + } + + private void installListeners() { + eventRegister = new CoreEventRegister(group, this); + eventRegister.register(Core.MarkerAdd); + eventRegister.register(Core.MarkerRemove); + eventRegister.register(Core.Name); + } + + private void uninstallListeners() { + if (eventRegister != null) + eventRegister.unregisterAll(); + } + + public Control getControl() { + return control; + } + + public void refresh(boolean reflow) { + if (toolbar == null || control == null || control.isDisposed()) + return; + section.setText(group.getName()); + + toolbar.removeAll(); + for (IMarker marker : group.getMarkers()) { + if (!group.isHidden() && !marker.isHidden()) + toolbar.add(new MarkerAction(marker)); + } + toolbar.update(false); + + ToolBar tb = toolbar.getControl(); + GridData data = (GridData) tb.getLayoutData(); + data.exclude = toolbar.isEmpty(); + tb.setVisible(!toolbar.isEmpty()); + + if (reflow) + form.reflow(true); + } + + public void dispose() { + uninstallListeners(); + if (toolbar != null) { + toolbar.dispose(); + toolbar = null; + } + if (control != null) { + control.dispose(); + control = null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + if (control == null || control.isDisposed()) + return; + + control.getDisplay().syncExec(new Runnable() { + public void run() { + String type = event.getType(); + if (Core.MarkerAdd.equals(type) + || Core.MarkerRemove.equals(type) + || Core.Name.equals(type)) { + refresh(true); + } + } + }); + } + + } + + protected class MarkerAction extends Action { + + private IMarker marker; + + public MarkerAction(IMarker marker) { + super(); + this.marker = marker; + setImageDescriptor(MarkerImageDescriptor.createFromMarker(marker, + 24, 24, false)); + setToolTipText(marker.getName()); + } + + public IMarker getMarker() { + return marker; + } + + public void run() { + IWorkbenchPage page = getAdapter(IWorkbenchWindow.class) + .getActivePage(); + if (page != null) { + IEditorPart editor = page.getActiveEditor(); + if (editor != null && editor instanceof IGraphicalEditor) { + IGraphicalEditorPage gp = ((IGraphicalEditor) editor) + .getActivePageInstance(); + if (gp != null) { + EditDomain domain = gp.getEditDomain(); + if (domain != null) { + Request req = new Request(REQ_ADD_MARKER) + .setViewer(gp.getViewer()).setDomain(domain) + .setParameter(MindMapUI.PARAM_MARKER_ID, + marker.getId()); + domain.handleRequest(req); +// MindMapUIPlugin.getDefault().getUsageDataCollector() +// .increase( +// UserDataConstants.USE_MARKERS_COUNT); + } + IViewer viewer = gp.getViewer(); + if (viewer != null) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.setFocus(); + } + } + } + } + } + } + } + + protected class MarkerSheetPart implements ICoreEventListener { + + private IMarkerSheet sheet; + + private Composite composite; + + private List groupParts = new ArrayList(); + + private List
    groupSections = new ArrayList
    (); + + private ICoreEventRegister eventRegister = null; + + public MarkerSheetPart(IMarkerSheet sheet) { + this.sheet = sheet; + } + + public Control getControl() { + return composite; + } + + public Control createControl(Composite parent) { + if (composite == null) { + composite = createComposite(parent); + refresh(false); + installListeners(); + composite.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); + } + return composite; + } + + private Composite createComposite(Composite parent) { + Composite composite = factory.createComposite(parent, SWT.WRAP); + GridLayout layout = new GridLayout(1, true); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.marginBottom = 0; + layout.marginLeft = 0; + layout.marginRight = 0; + layout.marginTop = 0; + layout.verticalSpacing = 7; + composite.setLayout(layout); + + return composite; + } + + public void refresh(boolean reflow) { + if (composite == null || composite.isDisposed()) + return; + + composite.setRedraw(false); + List newGroups = sheet.getMarkerGroups(); + int i; + for (i = 0; i < newGroups.size(); i++) { + IMarkerGroup group = newGroups.get(i); + if (i < groupParts.size()) { + MarkerGroupPart part = groupParts.get(i); + IMarkerGroup g = part.getMarkerGroup(); + if (group.equals(g)) { + continue; + } + } + + MarkerGroupPart part = groupToPart.get(group); + if (part != null) { + if (!newGroups.get(i).isHidden()) { + reorderChild(part, i); + } + } else { + if (!newGroups.get(i).isHidden()) { + part = createChild(group); + addChild(part, i); + } + } + } + + Object[] toTrim = groupParts.toArray(); + for (; i < toTrim.length; i++) { + removeChild((MarkerGroupPart) toTrim[i]); + } + + composite.setRedraw(true); +// form.reflow(true); + if (reflow) + form.reflow(true); + } + + public List getGroupParts() { + return groupParts; + } + + private void reorderChild(MarkerGroupPart part, int index) { + Control c = part.getControl(); + if (c == null) { + c = part.createControl(composite); +// c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + } + groupParts.remove(part); + groupParts.add(index, part); + groupSections.remove(part.section); + groupSections.add(index, part.section); + if (index == 0) { + c.moveAbove(null); + } else { + MarkerGroupPart g = groupParts.get(index - 1); + c.moveAbove(g.getControl()); + } + } + + private MarkerGroupPart createChild(IMarkerGroup group) { + MarkerGroupPart part = new MarkerGroupPart(group, false); + groupToPart.put(group, part); + return part; + } + + private void addChild(MarkerGroupPart part, int index) { + groupParts.add(index, part); + Control c = part.createControl(composite); + groupSections.add(index, part.section); + groupToSection.put(part.group, part.section); + c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + } + + private void removeChild(MarkerGroupPart part) { + groupParts.remove(part); + groupToPart.remove(part.getMarkerGroup()); + groupSections.remove(part.section); + groupToSection.remove(part.getMarkerGroup()); + part.section.dispose(); + part.dispose(); + } + + private void installListeners() { + eventRegister = new CoreEventRegister(sheet, this); + eventRegister.register(Core.MarkerGroupAdd); + eventRegister.register(Core.MarkerGroupRemove); + } + + private void uninstallListeners() { + if (eventRegister != null) + eventRegister.unregisterAll(); + } + + public void dispose() { + uninstallListeners(); + if (composite != null) { + composite.dispose(); + composite = null; + } + for (Object o : groupParts.toArray()) { + MarkerGroupPart groupPart = (MarkerGroupPart) o; + groupToPart.remove(groupPart.getMarkerGroup()); + groupToSection.remove(groupPart.getMarkerGroup()); + groupPart.dispose(); + } + groupParts.clear(); + groupSections.clear(); + } + + public void handleCoreEvent(final CoreEvent event) { + if (composite == null || composite.isDisposed()) + return; + + composite.getDisplay().syncExec(new Runnable() { + public void run() { + String type = event.getType(); + if (Core.MarkerGroupAdd.equals(type) + || Core.MarkerGroupRemove.equals(type)) { + refresh(true); + } + } + }); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/NotesPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/NotesPart.java index ef230695f..42b1d91a9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/NotesPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/NotesPart.java @@ -1,1220 +1,1229 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.e4models; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.inject.Inject; - -import org.eclipse.e4.core.commands.ECommandService; -import org.eclipse.e4.core.commands.EHandlerService; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.EContextService; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocumentListener; -import org.eclipse.jface.text.IFindReplaceTarget; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextViewer; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.part.IContributedContentsView; -import org.eclipse.ui.services.IServiceLocator; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.INotes; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.gef.EditDomain; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.part.IPart; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyNotesCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.actions.FindReplaceAction; -import org.xmind.ui.internal.actions.ShowAllNotesAction; -import org.xmind.ui.internal.dialogs.DialogUtils; -import org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider; -import org.xmind.ui.internal.notes.INotesContentViewer; -import org.xmind.ui.internal.notes.NotesFindReplaceOperationProvider; -import org.xmind.ui.internal.notes.RichDocumentNotesAdapter; -import org.xmind.ui.internal.notes.SheetNotesViewer; -import org.xmind.ui.internal.notes.TopicNotesViewer; -import org.xmind.ui.internal.spelling.SpellingPlugin; -import org.xmind.ui.internal.spellsupport.SpellingSupport; -import org.xmind.ui.internal.views.NotesHyperlinkDialog; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.richtext.FullRichTextActionBarContributor; -import org.xmind.ui.richtext.Hyperlink; -import org.xmind.ui.richtext.IRichDocument; -import org.xmind.ui.richtext.IRichDocumentListener; -import org.xmind.ui.richtext.IRichTextAction; -import org.xmind.ui.richtext.IRichTextEditViewer; -import org.xmind.ui.richtext.IRichTextRenderer; -import org.xmind.ui.richtext.ImagePlaceHolder; -import org.xmind.ui.richtext.LineStyle; -import org.xmind.ui.richtext.RichTextEditViewer; -import org.xmind.ui.richtext.RichTextUtils; -import org.xmind.ui.richtext.TextActionConstants; -import org.xmind.ui.texteditor.IMenuContributor; -import org.xmind.ui.texteditor.ISpellingActivation; -import org.xmind.ui.util.Logger; - -@SuppressWarnings("restriction") -public class NotesPart extends ViewModelPart - implements IPartListener, ICoreEventListener, IDocumentListener, - IRichDocumentListener, IContributedContentsView, - ISelectionChangedListener, IPropertyChangeListener { - - private static final String NOTES_EDIT_CONTEXT_ID = "org.xmind.ui.context.notes.edit"; //$NON-NLS-1$ - - private static boolean DEBUG = false; - - private static class EActionHandler { - - private IAction action; - - public EActionHandler(IAction action) { - this.action = action; - } - - @Execute - public void execute() { - if (action.getStyle() == IAction.AS_CHECK_BOX - || action.getStyle() == IAction.AS_RADIO_BUTTON) { - action.setChecked(!action.isChecked()); - } - action.run(); - } - - @CanExecute - public boolean canExecute() { - return action.isEnabled(); - } - } - - private class ContextActivator implements FocusListener, DisposeListener { - - public ContextActivator(Control control) { - control.addFocusListener(this); - control.addDisposeListener(this); - } - - public void focusGained(FocusEvent e) { - activateContext(); - } - - public void focusLost(FocusEvent e) { - deactivateContext(); - } - - public void widgetDisposed(DisposeEvent e) { - deactivateContext(); - } - - private void deactivateContext() { - contextService.deactivateContext(NOTES_EDIT_CONTEXT_ID); - } - - private void activateContext() { - contextService.activateContext(NOTES_EDIT_CONTEXT_ID); - } - } - - private class InsertImageAction extends Action implements IRichTextAction { - - private IRichTextEditViewer viewer; - - public InsertImageAction(IRichTextEditViewer viewer) { - super(MindMapMessages.InsertImage_text, MindMapUI.getImages() - .get(IMindMapImages.INSERT_IMAGE, true)); - this.viewer = viewer; - setToolTipText(MindMapMessages.NotesView_InsertImage_toolTip); - setDisabledImageDescriptor(MindMapUI.getImages() - .get(IMindMapImages.INSERT_IMAGE, false)); - } - - public void run() { - if (!(viewer instanceof RichTextEditViewer) - || viewer.getControl().isDisposed() || adapter == null) - return; - - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("NotesInsertImageCount"); //$NON-NLS-1$ - - String path = getPath(); - if (path == null) - return; - - Image image = adapter.createImageFromFile(path); - if (image == null) - return; - - viewer.getRenderer().insertImage(image); - } - - private String getPath() { - FileDialog fd = new FileDialog(workbenchWindow.getShell(), - SWT.OPEN); - DialogUtils.makeDefaultImageSelectorDialog(fd, true); - return fd.open(); - } - - public void dispose() { - viewer = null; - } - - public void selectionChanged(IRichTextEditViewer viewer, - ISelection selection) { - } - } - - private class InsertHyperlinkAction extends Action - implements IRichTextAction { - - private IRichTextEditViewer viewer; - - public InsertHyperlinkAction(IRichTextEditViewer viewer) { - super(MindMapMessages.InsertHyperlinkAction_text, - MindMapUI.getImages().get("notes_hyperlink.png", true)); //$NON-NLS-1$ - setToolTipText(MindMapMessages.InserthyperlinkAction_toolTip); - setDisabledImageDescriptor( - MindMapUI.getImages().get("notes_hyperlink.png", false)); //$NON-NLS-1$ - this.viewer = viewer; - } - - public void run() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("NotesInsertHyperlinkCount"); //$NON-NLS-1$ - - IRichTextRenderer renderer = viewer.getRenderer(); - ITextSelection selection = (ITextSelection) viewer.getSelection(); - String oldText = selection.getText(); - - int start = selection.getOffset(); - int end = start + selection.getLength(); - - Hyperlink[] oldHyperlinks = renderer.getSelectionHyperlinks(); - String oldHref = null; - Hyperlink oldHyperlink = null; - if (oldHyperlinks.length == 1) { - Hyperlink link = oldHyperlinks[0]; - if (link.start <= selection.getOffset() - && link.end() >= selection.getOffset() - + selection.getLength()) { - // selection within the hyperlink - oldHyperlink = link; - oldHref = link.href; - try { - oldText = viewer.getDocument().get(link.start, - link.length); - start = link.start; - end = start + link.length; - - } catch (BadLocationException e) { - String message = String.format( - "Unexpected hyperlink range: start=%d, length=%d", //$NON-NLS-1$ - link.start, link.length); - Logger.log(e, message); - } - } - } - - ImagePlaceHolder[] images = viewer.getDocument().getImages(); - int temp = -1; - for (int i = 0; i < images.length; i++) { - ImagePlaceHolder image = images[i]; - if (image.offset >= end) - break; - if (image.offset >= start && image.offset <= end) { - temp++; - int offset = image.offset - start; - oldText = oldText.substring(0, offset - temp) - + oldText.substring(offset + 1 - temp); - } - } - - NotesHyperlinkDialog dialog = new NotesHyperlinkDialog( - workbenchWindow.getShell(), oldHref, oldText); - int ret = dialog.open(); - if (ret == NotesHyperlinkDialog.OK) { - String newText = dialog.getDisplayText(); - String newHref = dialog.getHref(); - if (oldHyperlink != null && newText.equals(oldText)) { - if (!oldHyperlink.href.equals(newHref)) { - RichTextUtils.replaceHyperlinkHref(viewer.getDocument(), - oldHyperlink, newHref); - } - } else { - if ("".equals(newText)) { //$NON-NLS-1$ - newText = newHref; - } - renderer.insertHyperlink(newHref, newText); - } - } - } - - public void dispose() { - viewer = null; - } - - public void selectionChanged(IRichTextEditViewer viewer, - ISelection selection) { - } - } - - private class TextAction extends Action { - - private int op; - - public TextAction(int op) { - this.op = op; - } - - public void run() { - if (!(viewer instanceof TopicNotesViewer) - || viewer.getControl().isDisposed()) - return; - - TextViewer textViewer = ((TopicNotesViewer) viewer) - .getImplementation().getTextViewer(); - if (textViewer.canDoOperation(op)) { - textViewer.doOperation(op); - } - } - - public void update(TextViewer textViewer) { - setEnabled(textViewer.canDoOperation(op)); - } - } - - private class NotesPartRichTextActionBarContributor - extends FullRichTextActionBarContributor { - - private IRichTextAction insertImageAction; - private IRichTextAction insertHyperlinkAction; - - private IAction showAllNotesAction; - - protected void makeActions(IRichTextEditViewer viewer) { - super.makeActions(viewer); - - insertImageAction = new InsertImageAction(viewer); - addRichTextAction(insertImageAction); - - insertHyperlinkAction = new InsertHyperlinkAction(viewer); - addRichTextAction(insertHyperlinkAction); - - showAllNotesAction = new ShowAllNotesAction(NotesPart.this); - } - - public void fillMenu(IMenuManager menu) { - } - - public void fillToolBar(IToolBarManager toolbar) { - super.fillToolBar(toolbar); - toolbar.add(new Separator()); - toolbar.add(insertImageAction); - toolbar.add(insertHyperlinkAction); - toolbar.add(showAllNotesAction); - } - - @Override - public void fillContextMenu(IMenuManager menu) { - menu.add(getGlobalAction(ActionFactory.UNDO.getId())); - menu.add(getGlobalAction(ActionFactory.REDO.getId())); - menu.add(new Separator()); - menu.add(getGlobalAction(ActionFactory.CUT.getId())); - menu.add(getGlobalAction(ActionFactory.COPY.getId())); - menu.add(getGlobalAction(ActionFactory.PASTE.getId())); - menu.add(new Separator()); - menu.add(getGlobalAction(ActionFactory.SELECT_ALL.getId())); - menu.add(new Separator()); - super.fillContextMenu(menu); - if (spellingActivation != null) { - IMenuContributor contributor = (IMenuContributor) spellingActivation - .getAdapter(IMenuContributor.class); - if (contributor != null) { - menu.add(new Separator()); - contributor.fillMenu(menu); - } - } - } - - @Override - protected void handleFontSelectionChanged(SelectionChangedEvent event) { - super.handleFontSelectionChanged(event); - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("NotesFontChangeCount"); //$NON-NLS-1$ - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("FontChangeCount"); //$NON-NLS-1$ - } - } - - private class CommitNotesHandler { - - @Execute - public Object execute() { - saveNotes(); - IWorkbenchPage page = workbenchWindow.getActivePage(); - if (page != null && contributingEditor != null - && page == contributingEditor.getSite().getPage()) { - page.activate(contributingEditor); - } - return null; - } - } - - private class SaveNotesJob implements ICoreEventListener { - - public void handleCoreEvent(CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - saveNotes(); - } - }); - } - } - - @Inject - private IWorkbenchWindow workbenchWindow; - - @Inject - private EContextService contextService; - - @Inject - private EHandlerService handlerService; - - private IGraphicalEditor contributingEditor; - - private ISelection currentSelection; - - private ITopicPart currentTopicPart; - - private INotesContentViewer viewer; - - private RichDocumentNotesAdapter adapter; - - private NotesPartRichTextActionBarContributor topicViewerContributor; - - private ICoreEventRegister eventRegister; - - private Map handlers = new HashMap(); - - private ISpellingActivation spellingActivation; - - private boolean savingNotes; - - private NotesFindReplaceOperationProvider notesOperationProvider = null; - - private ICoreEventRegistration saveNotesReg = null; - - private Map globalActions = new HashMap( - 7); - - private List textActions = new ArrayList(7); - - private IWorkbenchAction findReplaceAction; - - private IPreferenceStore spellingPreferences; - - private boolean updating; - - private Composite contentArea; - - private ISelectionChangedListener listener; - - private CommitNotesHandler commitNotesHandler = new CommitNotesHandler(); - - @Override - protected Control doCreateContent(Composite parent) { - contentArea = createComposite(parent); - - topicViewerContributor = new NotesPartRichTextActionBarContributor(); - workbenchWindow.getActivePage().addPartListener(this); - showBootstrapContent(); - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("UseNotesCount"); //$NON-NLS-1$ - return contentArea; - } - - private Composite createComposite(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - composite.setEnabled(false); - - return composite; - } - - protected boolean postConfiguration(IWorkbenchPart workbenchPart, - MPart part) { - super.postConfiguration(workbenchPart, part); - IWorkbenchPartSite site = workbenchPart.getSite(); - if (site instanceof IViewSite) { - IActionBars actionBars = ((IViewSite) site).getActionBars(); - if (actionBars == null) { - return false; - } - IServiceLocator serviceLocator = actionBars.getServiceLocator(); - if (serviceLocator == null) - return false; - IEclipseContext eclipseContext = serviceLocator - .getService(IEclipseContext.class); - eclipseContext.set(ECommandService.class, - serviceLocator.getService(ECommandService.class)); - eclipseContext.set(EHandlerService.class, - serviceLocator.getService(EHandlerService.class)); - - createActions(actionBars); - return true; - } - return false; - } - - private void createActions(IActionBars actionBars) { - registerGlobalTextActionHandlers(); - registerRichTextActionHandlers(); - } - - private void registerGlobalTextActionHandlers() { - activateGlobalTextHandler(ActionFactory.UNDO, - ITextOperationTarget.UNDO); - activateGlobalTextHandler(ActionFactory.REDO, - ITextOperationTarget.REDO); - activateGlobalTextHandler(ActionFactory.CUT, ITextOperationTarget.CUT); - activateGlobalTextHandler(ActionFactory.COPY, - ITextOperationTarget.COPY); - activateGlobalTextHandler(ActionFactory.PASTE, - ITextOperationTarget.PASTE); - activateGlobalTextHandler(ActionFactory.SELECT_ALL, - ITextOperationTarget.SELECT_ALL); - - //activate find action. - findReplaceAction = new FindReplaceAction(workbenchWindow); - findReplaceAction - .setActionDefinitionId(ActionFactory.FIND.getCommandId()); - Object handler = new EActionHandler(findReplaceAction); - handlerService.activateHandler(ActionFactory.FIND.getCommandId(), - handler); - handlers.put(ActionFactory.FIND.getCommandId(), handler); - } - - private void activateGlobalTextHandler(ActionFactory actionFactory, - int textOp) { - TextAction textAction = new TextAction(textOp); - String commandId = actionFactory.getCommandId(); - textAction.setActionDefinitionId(commandId); - Object handler = new EActionHandler(textAction); - handlerService.activateHandler(commandId, handler); - handlers.put(commandId, handler); - - textAction.setId(actionFactory.getId()); - IWorkbenchAction workbenchAction = actionFactory - .create(workbenchWindow); - textAction.setText(workbenchAction.getText()); - workbenchAction.dispose(); - textActions.add(textAction); - globalActions.put(actionFactory.getId(), textAction); - } - - private void registerRichTextActionHandlers() { - activateRichTextHandler(TextActionConstants.FONT_ID, - "org.xmind.ui.command.text.font"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.BOLD_ID, - "org.xmind.ui.command.text.bold"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.ITALIC_ID, - "org.xmind.ui.command.text.italic"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.UNDERLINE_ID, - "org.xmind.ui.command.text.underline"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.LEFT_ALIGN_ID, - "org.xmind.ui.command.text.leftAlign"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.CENTER_ALIGN_ID, - "org.xmind.ui.command.text.centerAlign"); //$NON-NLS-1$ - activateRichTextHandler(TextActionConstants.RIGHT_ALIGN_ID, - "org.xmind.ui.command.text.rightAlign"); //$NON-NLS-1$ - } - - private void activateRichTextHandler(String actionId, String commandId) { - IRichTextAction action = topicViewerContributor - .getRichTextAction(actionId); - if (action != null) { - action.setActionDefinitionId(commandId); - Object handler = new EActionHandler(action); - handlerService.activateHandler(commandId, handler); - handlers.put(commandId, handler); - } - } - - private void unregisterTextActionHandlers() { - if (handlerService != null) { - for (Entry entry : handlers.entrySet()) { - handlerService.deactivateHandler(entry.getKey(), - entry.getValue()); - } - handlers.clear(); - } - } - - private IAction getGlobalAction(String actionId) { - return globalActions == null ? null : globalActions.get(actionId); - } - - private void showBootstrapContent() { - IEditorPart activeEditor = workbenchWindow.getActivePage() - .getActiveEditor(); - if (activeEditor instanceof IGraphicalEditor) { - setContributingEditor((IGraphicalEditor) activeEditor); - } else { - editorSelectionChanged(StructuredSelection.EMPTY); - } - } - - private void setContributingEditor(IGraphicalEditor editor) { - if (editor == contributingEditor) { - return; - } - - if (contributingEditor != null) { - ISelectionProvider selectionProvider = contributingEditor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) - selectionProvider.removeSelectionChangedListener( - getSelectionChangedListener()); - } - - contributingEditor = editor; - - ISelection newSelection = null; - - if (contributingEditor != null) { - ISelectionProvider selectionProvider = contributingEditor.getSite() - .getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.addSelectionChangedListener( - getSelectionChangedListener()); - newSelection = selectionProvider.getSelection(); - } - } - if (newSelection == null) { - newSelection = StructuredSelection.EMPTY; - } - - if (contentArea.isDisposed()) { - return; - } - - editorSelectionChanged(newSelection); - } - - private void editorSelectionChanged(ISelection selection) { - if (selection == currentSelection - || (selection != null && selection.equals(currentSelection))) - return; - - currentSelection = selection; - setCurrentTopicPart(findSelectedTopicPart()); - - if (currentSelection instanceof IStructuredSelection) { - Object obj = ((IStructuredSelection) currentSelection) - .getFirstElement(); - updateViewer(obj); - } else { - updateViewer(null); - } - } - - private void setCurrentTopicPart(ITopicPart topicPart) { - if (topicPart == currentTopicPart) - return; - - unhookTopic(); - saveNotes(); - this.currentTopicPart = topicPart; -// forceRefreshViewer(); - hookTopic(); - } - - private ITopicPart findSelectedTopicPart() { - if (contributingEditor == null) - return null; - - if (currentSelection == null || currentSelection.isEmpty() - || !(currentSelection instanceof IStructuredSelection)) - return null; - - Object o = ((IStructuredSelection) currentSelection).getFirstElement(); - - IGraphicalEditorPage page = contributingEditor.getActivePageInstance(); - if (page == null) - return null; - - IPart part = page.getViewer().findPart(o); - if (part instanceof ITopicPart) - return (ITopicPart) part; - - return null; - } - - private ISelectionChangedListener getSelectionChangedListener() { - if (listener == null) { - listener = new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - editorSelectionChanged(event.getSelection()); - } - }; - } - return listener; - } - - private void hookTopic() { - if (currentTopicPart != null) { - ITopic topic = currentTopicPart.getTopic(); - if (eventRegister == null) - eventRegister = new CoreEventRegister(topic, this); - eventRegister.register(Core.TopicNotes); - if (DEBUG) - System.out.println("Model listeners installed"); //$NON-NLS-1$ - } - } - - private void unhookTopic() { - if (eventRegister != null) { - eventRegister.unregisterAll(); - if (DEBUG) - System.out.println("Model listeners uninstalled"); //$NON-NLS-1$ - eventRegister = null; - } - } - - private void saveNotes() { - if (adapter == null || currentTopicPart == null - || !(viewer instanceof TopicNotesViewer) - || viewer.getControl().isDisposed() - || !((TopicNotesViewer) viewer).hasModified()) { - deactivateJob(); - return; - } - - if (DEBUG) - System.out.println("Start saving notes"); //$NON-NLS-1$ - - savingNotes = true; - ITopic topic = currentTopicPart.getTopic(); - ICommandStack cs = getCommandStack(); - if (cs != null) { - doSaveNotes(topic, cs); - } else { - forceSaveNotes(topic); - } - ((TopicNotesViewer) viewer).resetModified(); - savingNotes = false; - - deactivateJob(); - - if (DEBUG) - System.out.println("End saving notes"); //$NON-NLS-1$ - } - - private ICommandStack getCommandStack() { - EditDomain domain = currentTopicPart.getSite().getViewer() - .getEditDomain(); - if (domain != null) { - return domain.getCommandStack(); - } - return null; - } - - private void doSaveNotes(ITopic topic, ICommandStack cs) { - ModifyNotesCommand modifyHtml = new ModifyNotesCommand(topic, - adapter.makeNewHtmlContent(), INotes.HTML); - ModifyNotesCommand modifyPlain = new ModifyNotesCommand(topic, - adapter.makeNewPlainContent(), INotes.PLAIN); - CompoundCommand cmd = new CompoundCommand(modifyHtml, modifyPlain); - cmd.setLabel(CommandMessages.Command_ModifyNotes); - cs.execute(cmd); - } - - private void forceSaveNotes(ITopic topic) { - INotes notes = topic.getNotes(); - notes.setContent(INotes.HTML, adapter.makeNewHtmlContent()); - notes.setContent(INotes.PLAIN, adapter.makeNewPlainContent()); - } - - public void setFocus() { - if (viewer instanceof TopicNotesViewer) { - ((TopicNotesViewer) viewer).getImplementation().getFocusControl() - .setFocus(); - } else if (viewer instanceof SheetNotesViewer) { - viewer.getControl().setFocus(); - } - } - - private void updateViewer(Object input) { - if (contentArea == null || contentArea.isDisposed()) { - return; - } - contentArea.setRedraw(false); - contentArea.setEnabled(true); - - RichDocumentNotesAdapter oldAdapter = this.adapter; - if (viewer instanceof TopicNotesViewer && input instanceof ITopic) { - unhookDocument(); - this.adapter = createNotesAdapter(); - viewer.setInput(adapter); - hookDocument(); - } else if (viewer instanceof SheetNotesViewer - && (input instanceof ISheet || input instanceof IRelationship - || input instanceof IBoundary)) { - viewer.setInput(input); - ((SheetNotesViewer) viewer).setEditor(contributingEditor); - } else { - if (viewer instanceof TopicNotesViewer) { - removeSpellChecker(); - deactivateHandlers(); - if (((TopicNotesViewer) viewer).getImplementation() != null) { - ((TopicNotesViewer) viewer).getImplementation() - .removePostSelectionChangedListener(this); - } - unhookDocument(); - } - if (viewer instanceof SheetNotesViewer) { - ((SheetNotesViewer) viewer).setEditor(null); - } - if (viewer != null) { - viewer.dispose(); - viewer = null; - } - - if (input instanceof ITopic) { - viewer = new TopicNotesViewer(topicViewerContributor); - viewer.createControl(contentArea); - this.adapter = createNotesAdapter(); - viewer.setInput(adapter); - addSpellChecker(); - activateHandlers(); - ((TopicNotesViewer) viewer).getImplementation() - .addPostSelectionChangedListener(this); - hookDocument(); - - new ContextActivator(((TopicNotesViewer) viewer) - .getImplementation().getFocusControl()); - - } else if (input instanceof ISheet || input instanceof IBoundary - || input instanceof IRelationship) { - viewer = new SheetNotesViewer(contributingEditor); - viewer.createControl(contentArea); - viewer.setInput(input); - } else { - contentArea.setEnabled(false); - } - } - contentArea.setRedraw(true); - contentArea.layout(true, true); - - if (oldAdapter != null) { - oldAdapter.dispose(); - } - update(); - - unregisterTextActionHandlers(); - registerGlobalTextActionHandlers(); - registerRichTextActionHandlers(); - } - - private void hookDocument() { - IRichDocument document = ((TopicNotesViewer) viewer).getImplementation() - .getDocument(); - if (document != null) { - document.addDocumentListener(this); - document.addRichDocumentListener(this); - if (DEBUG) - System.out.println("Document hooked"); //$NON-NLS-1$ - } - } - - private void unhookDocument() { - IRichDocument document = ((TopicNotesViewer) viewer).getImplementation() - .getDocument(); - if (document != null) { - document.removeDocumentListener(this); - document.removeRichDocumentListener(this); - if (DEBUG) - System.out.println("Document unhooked"); //$NON-NLS-1$ - } - } - - private void addSpellChecker() { - spellingActivation = SpellingSupport.getInstance() - .activateSpelling(((TopicNotesViewer) viewer) - .getImplementation().getTextViewer()); - spellingPreferences = SpellingPlugin.getDefault().getPreferenceStore(); - if (spellingPreferences != null) { - spellingPreferences.addPropertyChangeListener(this); - } - } - - private void removeSpellChecker() { - if (spellingPreferences != null) { - spellingPreferences.removePropertyChangeListener(this); - spellingPreferences = null; - } - if (spellingActivation != null) { - spellingActivation.getSpellingSupport() - .deactivateSpelling(spellingActivation); - spellingActivation = null; - } - } - - private void activateHandlers() { - handlerService.activateHandler("org.xmind.ui.command.commitNotes", //$NON-NLS-1$ - commitNotesHandler); - } - - private void deactivateHandlers() { - handlerService.deactivateHandler("org.xmind.ui.command.commitNotes", //$NON-NLS-1$ - commitNotesHandler); - } - - private void update() { - if (updating) - return; - - updating = true; - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - updateJob(); - updateTextActions(); - updating = false; - } - - }); - } - - private void updateJob() { - if (!(viewer instanceof TopicNotesViewer) - || viewer.getControl().isDisposed()) - return; - - if (((TopicNotesViewer) viewer).hasModified()) { - activateJob(); - } else { - deactivateJob(); - } - } - - private void activateJob() { - if (saveNotesReg != null && saveNotesReg.isValid()) - return; - - saveNotesReg = null; - IWorkbook workbook = (IWorkbook) contributingEditor - .getAdapter(IWorkbook.class); - if (workbook instanceof ICoreEventSource2) { - saveNotesReg = ((ICoreEventSource2) workbook) - .registerOnceCoreEventListener(Core.WorkbookPreSaveOnce, - new SaveNotesJob()); - if (DEBUG) - System.out.println("Job acitvated"); //$NON-NLS-1$ - } - } - - private void deactivateJob() { - if (saveNotesReg != null) { - saveNotesReg.unregister(); - saveNotesReg = null; - } - } - - private void updateTextActions() { - if (!(viewer instanceof TopicNotesViewer) - || viewer.getControl().isDisposed() || textActions == null - || textActions.isEmpty()) - return; - TextViewer textViewer = ((TopicNotesViewer) viewer).getImplementation() - .getTextViewer(); - if (textViewer != null) { - for (TextAction action : textActions) { - action.update(textViewer); - } - } - } - - private void forceRefreshViewer() { - RichDocumentNotesAdapter oldAdapter = this.adapter; - if (viewer != null && !viewer.getControl().isDisposed()) { - this.adapter = createNotesAdapter(); - if (DEBUG) - if (adapter != null) - System.out.println("New adapter created"); //$NON-NLS-1$ - unhookDocument(); - viewer.setInput(adapter); - if (adapter != null) { - hookDocument(); - } - } else { - this.adapter = null; - } - if (oldAdapter != null) { - oldAdapter.dispose(); - if (DEBUG) - System.out.println("Old adapter disposed"); //$NON-NLS-1$ - } - update(); - } - - private RichDocumentNotesAdapter createNotesAdapter() { - if (currentTopicPart == null) - return null; - ITopic topic = currentTopicPart.getTopic(); - return new RichDocumentNotesAdapter(topic); - } - - public IWorkbenchPart getContributingPart() { - return contributingEditor; - } - - public void handleCoreEvent(final CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - String eventType = event.getType(); - if (Core.TopicNotes.equals(eventType)) { - handleNotesChanged(); - } - } - }); - } - - private void handleNotesChanged() { - if (savingNotes) - return; - - forceRefreshViewer(); - } - - public void partActivated(IWorkbenchPart part) { - if (DEBUG) - System.out.println("Part activated: " + part); //$NON-NLS-1$ - if (part == this || !(part instanceof IEditorPart)) - return; - - if (part instanceof IGraphicalEditor) { - setContributingEditor((IGraphicalEditor) part); - } - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - if (DEBUG) - System.out.println("Part closed: " + part); //$NON-NLS-1$ - if (part == this.contributingEditor) { - setContributingEditor(null); - } - } - - public void partDeactivated(IWorkbenchPart part) { - if (DEBUG) - System.out.println("Part deactivated: " + part); //$NON-NLS-1$ - if (part == this) { - saveNotes(); - } - } - - public void partOpened(IWorkbenchPart part) { - } - - public void documentAboutToBeChanged(DocumentEvent event) { - } - - public void documentChanged(DocumentEvent event) { - update(); - } - - public void selectionChanged(SelectionChangedEvent event) { - update(); - } - - public void imageChanged(IRichDocument document, - ImagePlaceHolder[] oldImages, ImagePlaceHolder[] newImages) { - update(); - } - - public void lineStyleChanged(IRichDocument document, - LineStyle[] oldLineStyles, LineStyle[] newLineStyles) { - update(); - } - - public void textStyleChanged(IRichDocument document, - StyleRange[] oldTextStyles, StyleRange[] newTextStyles) { - update(); - } - - public void hyperlinkChanged(IRichDocument document, - Hyperlink[] oldHyperlinks, Hyperlink[] newHyperlinks) { - update(); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse - * .jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if (SpellingPlugin.SPELLING_CHECK_ENABLED.equals(event.getProperty())) { - if (spellingActivation != null) { - spellingActivation.getSpellingSupport() - .deactivateSpelling(spellingActivation); - spellingActivation = null; - } - if (spellingPreferences - .getBoolean(SpellingPlugin.SPELLING_CHECK_ENABLED)) { - spellingActivation = SpellingSupport.getInstance() - .activateSpelling(((TopicNotesViewer) viewer) - .getImplementation().getTextViewer()); - } - } - } - - public void dispose() { - deactivateHandlers(); - removeSpellChecker(); - - setCurrentTopicPart(null); - workbenchWindow.getActivePage().removePartListener(this); - setContributingEditor(null); - unregisterTextActionHandlers(); - - handlerService = null; - super.dispose(); - - if (findReplaceAction != null) { - findReplaceAction.dispose(); - findReplaceAction = null; - } - textActions = null; - if (adapter != null) { - adapter.dispose(); - adapter = null; - } - if (viewer != null) { - viewer.dispose(); - viewer = null; - } - } - - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter == IContributedContentsView.class) { - return this; - } else if (adapter == IFindReplaceOperationProvider.class) { - if (notesOperationProvider == null) { - notesOperationProvider = new NotesFindReplaceOperationProvider( - this); - } - return notesOperationProvider; - } else if (adapter == IFindReplaceTarget.class) { - if (viewer instanceof TopicNotesViewer) { - IRichTextEditViewer rtViewer = ((TopicNotesViewer) viewer) - .getImplementation(); - if (rtViewer != null) { - TextViewer textViewer = rtViewer.getTextViewer(); - if (textViewer != null) - return textViewer.getFindReplaceTarget(); - } - } - } else if (adapter == ITextViewer.class) { - if (viewer instanceof TopicNotesViewer) { - IRichTextEditViewer rtViewer = ((TopicNotesViewer) viewer) - .getImplementation(); - if (rtViewer != null) - return rtViewer.getTextViewer(); - } - } else if (adapter == IRichTextEditViewer.class) { - if (viewer instanceof TopicNotesViewer) { - return ((TopicNotesViewer) viewer).getImplementation(); - } - } else if (adapter == ITopicPart.class) { - return currentTopicPart; - } else if (adapter == ITopic.class) { - return currentTopicPart == null ? null - : currentTopicPart.getTopic(); - } - return super.getAdapter(adapter); - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.e4models; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.inject.Inject; + +import org.eclipse.e4.core.commands.ECommandService; +import org.eclipse.e4.core.commands.EHandlerService; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.EContextService; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.IFindReplaceTarget; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.internal.E4PartWrapper; +import org.eclipse.ui.part.IContributedContentsView; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.INotes; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.gef.EditDomain; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.part.IPart; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyNotesCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.actions.FindReplaceAction; +import org.xmind.ui.internal.actions.ShowAllNotesAction; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider; +import org.xmind.ui.internal.notes.INotesContentViewer; +import org.xmind.ui.internal.notes.NotesFindReplaceOperationProvider; +import org.xmind.ui.internal.notes.RichDocumentNotesAdapter; +import org.xmind.ui.internal.notes.SheetNotesViewer; +import org.xmind.ui.internal.notes.TopicNotesViewer; +import org.xmind.ui.internal.spelling.SpellingPlugin; +import org.xmind.ui.internal.spellsupport.SpellingSupport; +import org.xmind.ui.internal.views.NotesHyperlinkDialog; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.richtext.FullRichTextActionBarContributor; +import org.xmind.ui.richtext.Hyperlink; +import org.xmind.ui.richtext.IRichDocument; +import org.xmind.ui.richtext.IRichDocumentListener; +import org.xmind.ui.richtext.IRichTextAction; +import org.xmind.ui.richtext.IRichTextEditViewer; +import org.xmind.ui.richtext.IRichTextRenderer; +import org.xmind.ui.richtext.ImagePlaceHolder; +import org.xmind.ui.richtext.LineStyle; +import org.xmind.ui.richtext.RichTextEditViewer; +import org.xmind.ui.richtext.RichTextUtils; +import org.xmind.ui.richtext.TextActionConstants; +import org.xmind.ui.texteditor.IMenuContributor; +import org.xmind.ui.texteditor.ISpellingActivation; +import org.xmind.ui.util.Logger; + +@SuppressWarnings("restriction") +public class NotesPart extends ViewModelPart + implements IPartListener, ICoreEventListener, IDocumentListener, + IRichDocumentListener, IContributedContentsView, + ISelectionChangedListener, IPropertyChangeListener { + + private static final String NOTES_EDIT_CONTEXT_ID = "org.xmind.ui.context.notes.edit"; //$NON-NLS-1$ + + private static boolean DEBUG = false; + + private static class EActionHandler { + + private IAction action; + + public EActionHandler(IAction action) { + this.action = action; + } + + @Execute + public void execute() { + if (action.getStyle() == IAction.AS_CHECK_BOX + || action.getStyle() == IAction.AS_RADIO_BUTTON) { + action.setChecked(!action.isChecked()); + } + action.run(); + } + + @CanExecute + public boolean canExecute() { + return action.isEnabled(); + } + } + + private class ContextActivator implements FocusListener, DisposeListener { + + public ContextActivator(Control control) { + control.addFocusListener(this); + control.addDisposeListener(this); + } + + public void focusGained(FocusEvent e) { + activateContext(); + } + + public void focusLost(FocusEvent e) { + deactivateContext(); + } + + public void widgetDisposed(DisposeEvent e) { + deactivateContext(); + } + + private void deactivateContext() { + contextService.deactivateContext(NOTES_EDIT_CONTEXT_ID); + } + + private void activateContext() { + contextService.activateContext(NOTES_EDIT_CONTEXT_ID); + } + } + + private class InsertImageAction extends Action implements IRichTextAction { + + private IRichTextEditViewer viewer; + + public InsertImageAction(IRichTextEditViewer viewer) { + super(MindMapMessages.InsertImage_text, MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, true)); + this.viewer = viewer; + setToolTipText(MindMapMessages.NotesView_InsertImage_toolTip); + setDisabledImageDescriptor(MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, false)); + } + + public void run() { + if (!(viewer instanceof RichTextEditViewer) + || viewer.getControl().isDisposed() || adapter == null) + return; + + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.NOTES_INSERT_IMAGE_COUNT); + + String path = getPath(); + if (path == null) + return; + + Image image = adapter.createImageFromFile(path); + if (image == null) + return; + + viewer.getRenderer().insertImage(image); + } + + private String getPath() { + FileDialog fd = new FileDialog(workbenchWindow.getShell(), + SWT.OPEN); + DialogUtils.makeDefaultImageSelectorDialog(fd, true); + return fd.open(); + } + + public void dispose() { + viewer = null; + } + + public void selectionChanged(IRichTextEditViewer viewer, + ISelection selection) { + } + } + + private class InsertHyperlinkAction extends Action + implements IRichTextAction { + + private IRichTextEditViewer viewer; + + public InsertHyperlinkAction(IRichTextEditViewer viewer) { + super(MindMapMessages.InsertHyperlinkAction_text, + MindMapUI.getImages().get("notes_hyperlink.png", true)); //$NON-NLS-1$ + setToolTipText(MindMapMessages.InserthyperlinkAction_toolTip); + setDisabledImageDescriptor( + MindMapUI.getImages().get("notes_hyperlink.png", false)); //$NON-NLS-1$ + this.viewer = viewer; + } + + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.NOTES_INSERT_HYPERLINK_COUNT); + + IRichTextRenderer renderer = viewer.getRenderer(); + ITextSelection selection = (ITextSelection) viewer.getSelection(); + String oldText = selection.getText(); + + int start = selection.getOffset(); + int end = start + selection.getLength(); + + Hyperlink[] oldHyperlinks = renderer.getSelectionHyperlinks(); + String oldHref = null; + Hyperlink oldHyperlink = null; + if (oldHyperlinks.length == 1) { + Hyperlink link = oldHyperlinks[0]; + if (link.start <= selection.getOffset() + && link.end() >= selection.getOffset() + + selection.getLength()) { + // selection within the hyperlink + oldHyperlink = link; + oldHref = link.href; + try { + oldText = viewer.getDocument().get(link.start, + link.length); + start = link.start; + end = start + link.length; + + } catch (BadLocationException e) { + String message = String.format( + "Unexpected hyperlink range: start=%d, length=%d", //$NON-NLS-1$ + link.start, link.length); + Logger.log(e, message); + } + } + } + + ImagePlaceHolder[] images = viewer.getDocument().getImages(); + int temp = -1; + for (int i = 0; i < images.length; i++) { + ImagePlaceHolder image = images[i]; + if (image.offset >= end) + break; + if (image.offset >= start && image.offset <= end) { + temp++; + int offset = image.offset - start; + oldText = oldText.substring(0, offset - temp) + + oldText.substring(offset + 1 - temp); + } + } + + NotesHyperlinkDialog dialog = new NotesHyperlinkDialog( + workbenchWindow.getShell(), oldHref, oldText); + int ret = dialog.open(); + if (ret == NotesHyperlinkDialog.OK) { + String newText = dialog.getDisplayText(); + String newHref = dialog.getHref(); + if (oldHyperlink != null && newText.equals(oldText)) { + if (!oldHyperlink.href.equals(newHref)) { + RichTextUtils.replaceHyperlinkHref(viewer.getDocument(), + oldHyperlink, newHref); + } + } else { + if ("".equals(newText)) { //$NON-NLS-1$ + newText = newHref; + } + renderer.insertHyperlink(newHref, newText); + } + } + } + + public void dispose() { + viewer = null; + } + + public void selectionChanged(IRichTextEditViewer viewer, + ISelection selection) { + } + } + + private class TextAction extends Action { + + private int op; + + public TextAction(int op) { + this.op = op; + } + + public void run() { + if (!(viewer instanceof TopicNotesViewer) + || viewer.getControl().isDisposed()) + return; + + TextViewer textViewer = ((TopicNotesViewer) viewer) + .getImplementation().getTextViewer(); + if (textViewer.canDoOperation(op)) { + textViewer.doOperation(op); + } + } + + public void update(TextViewer textViewer) { + setEnabled(textViewer.canDoOperation(op)); + } + } + + private class NotesPartRichTextActionBarContributor + extends FullRichTextActionBarContributor { + + private IRichTextAction insertImageAction; + private IRichTextAction insertHyperlinkAction; + + private IAction showAllNotesAction; + + protected void makeActions(IRichTextEditViewer viewer) { + super.makeActions(viewer); + + insertImageAction = new InsertImageAction(viewer); + addRichTextAction(insertImageAction); + + insertHyperlinkAction = new InsertHyperlinkAction(viewer); + addRichTextAction(insertHyperlinkAction); + + showAllNotesAction = new ShowAllNotesAction(NotesPart.this); + } + + public void fillMenu(IMenuManager menu) { + } + + public void fillToolBar(IToolBarManager toolbar) { + super.fillToolBar(toolbar); + toolbar.add(new Separator()); + toolbar.add(insertImageAction); + toolbar.add(insertHyperlinkAction); + toolbar.add(showAllNotesAction); + } + + @Override + public void fillContextMenu(IMenuManager menu) { + menu.add(getGlobalAction(ActionFactory.UNDO.getId())); + menu.add(getGlobalAction(ActionFactory.REDO.getId())); + menu.add(new Separator()); + menu.add(getGlobalAction(ActionFactory.CUT.getId())); + menu.add(getGlobalAction(ActionFactory.COPY.getId())); + menu.add(getGlobalAction(ActionFactory.PASTE.getId())); + menu.add(new Separator()); + menu.add(getGlobalAction(ActionFactory.SELECT_ALL.getId())); + menu.add(new Separator()); + super.fillContextMenu(menu); + if (spellingActivation != null) { + IMenuContributor contributor = (IMenuContributor) spellingActivation + .getAdapter(IMenuContributor.class); + if (contributor != null) { + menu.add(new Separator()); + contributor.fillMenu(menu); + } + } + } + + @Override + protected void handleFontSelectionChanged(SelectionChangedEvent event) { + super.handleFontSelectionChanged(event); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.NOTES_FONT_CHANGE_COUNT); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.FONT_CHANGE_ALL_COUNT); + } + } + + private class CommitNotesHandler { + + @Execute + public Object execute() { + saveNotes(); + IWorkbenchPage page = workbenchWindow.getActivePage(); + if (page != null && contributingEditor != null + && page == contributingEditor.getSite().getPage()) { + page.activate(contributingEditor); + } + return null; + } + } + + private class SaveNotesJob implements ICoreEventListener { + + public void handleCoreEvent(CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + saveNotes(); + } + }); + } + } + + @Inject + private IWorkbenchWindow workbenchWindow; + + @Inject + private EContextService contextService; + + @Inject + private EHandlerService handlerService; + + private IGraphicalEditor contributingEditor; + + private ISelection currentSelection; + + private ITopicPart currentTopicPart; + + private INotesContentViewer viewer; + + private RichDocumentNotesAdapter adapter; + + private NotesPartRichTextActionBarContributor topicViewerContributor; + + private ICoreEventRegister eventRegister; + + private Map handlers = new HashMap(); + + private ISpellingActivation spellingActivation; + + private boolean savingNotes; + + private NotesFindReplaceOperationProvider notesOperationProvider = null; + + private ICoreEventRegistration saveNotesReg = null; + + private Map globalActions = new HashMap( + 7); + + private List textActions = new ArrayList(7); + + private IWorkbenchAction findReplaceAction; + + private IPreferenceStore spellingPreferences; + + private boolean updating; + + private Composite contentArea; + + private ISelectionChangedListener listener; + + private CommitNotesHandler commitNotesHandler = new CommitNotesHandler(); + + @Override + protected Control doCreateContent(Composite parent) { + contentArea = createComposite(parent); + + topicViewerContributor = new NotesPartRichTextActionBarContributor(); + workbenchWindow.getActivePage().addPartListener(this); + showBootstrapContent(); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.USE_NOTES_COUNT); + return contentArea; + } + + private Composite createComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + composite.setEnabled(false); + + return composite; + } + + protected boolean postConfiguration(IWorkbenchPart workbenchPart, + MPart part) { + super.postConfiguration(workbenchPart, part); + IWorkbenchPartSite site = workbenchPart.getSite(); + if (site instanceof IViewSite) { + IActionBars actionBars = ((IViewSite) site).getActionBars(); + if (actionBars == null) { + return false; + } + IServiceLocator serviceLocator = actionBars.getServiceLocator(); + if (serviceLocator == null) + return false; + IEclipseContext eclipseContext = serviceLocator + .getService(IEclipseContext.class); + eclipseContext.set(ECommandService.class, + serviceLocator.getService(ECommandService.class)); + eclipseContext.set(EHandlerService.class, + serviceLocator.getService(EHandlerService.class)); + + createActions(actionBars); + return true; + } + return false; + } + + private void createActions(IActionBars actionBars) { + registerGlobalTextActionHandlers(); + registerRichTextActionHandlers(); + } + + private void registerGlobalTextActionHandlers() { + activateGlobalTextHandler(ActionFactory.UNDO, + ITextOperationTarget.UNDO); + activateGlobalTextHandler(ActionFactory.REDO, + ITextOperationTarget.REDO); + activateGlobalTextHandler(ActionFactory.CUT, ITextOperationTarget.CUT); + activateGlobalTextHandler(ActionFactory.COPY, + ITextOperationTarget.COPY); + activateGlobalTextHandler(ActionFactory.PASTE, + ITextOperationTarget.PASTE); + activateGlobalTextHandler(ActionFactory.SELECT_ALL, + ITextOperationTarget.SELECT_ALL); + + //activate find action. + findReplaceAction = new FindReplaceAction(workbenchWindow); + findReplaceAction + .setActionDefinitionId(ActionFactory.FIND.getCommandId()); + Object handler = new EActionHandler(findReplaceAction); + handlerService.activateHandler(ActionFactory.FIND.getCommandId(), + handler); + handlers.put(ActionFactory.FIND.getCommandId(), handler); + } + + private void activateGlobalTextHandler(ActionFactory actionFactory, + int textOp) { + TextAction textAction = new TextAction(textOp); + String commandId = actionFactory.getCommandId(); + textAction.setActionDefinitionId(commandId); + Object handler = new EActionHandler(textAction); + handlerService.activateHandler(commandId, handler); + handlers.put(commandId, handler); + + textAction.setId(actionFactory.getId()); + IWorkbenchAction workbenchAction = actionFactory + .create(workbenchWindow); + textAction.setText(workbenchAction.getText()); + workbenchAction.dispose(); + textActions.add(textAction); + globalActions.put(actionFactory.getId(), textAction); + } + + private void registerRichTextActionHandlers() { + activateRichTextHandler(TextActionConstants.FONT_ID, + "org.xmind.ui.command.text.font"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.BOLD_ID, + "org.xmind.ui.command.text.bold"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.ITALIC_ID, + "org.xmind.ui.command.text.italic"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.UNDERLINE_ID, + "org.xmind.ui.command.text.underline"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.LEFT_ALIGN_ID, + "org.xmind.ui.command.text.leftAlign"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.CENTER_ALIGN_ID, + "org.xmind.ui.command.text.centerAlign"); //$NON-NLS-1$ + activateRichTextHandler(TextActionConstants.RIGHT_ALIGN_ID, + "org.xmind.ui.command.text.rightAlign"); //$NON-NLS-1$ + } + + private void activateRichTextHandler(String actionId, String commandId) { + IRichTextAction action = topicViewerContributor + .getRichTextAction(actionId); + if (action != null) { + action.setActionDefinitionId(commandId); + Object handler = new EActionHandler(action); + handlerService.activateHandler(commandId, handler); + handlers.put(commandId, handler); + } + } + + private void unregisterTextActionHandlers() { + if (handlerService != null) { + for (Entry entry : handlers.entrySet()) { + handlerService.deactivateHandler(entry.getKey(), + entry.getValue()); + } + handlers.clear(); + } + } + + private IAction getGlobalAction(String actionId) { + return globalActions == null ? null : globalActions.get(actionId); + } + + private void showBootstrapContent() { + IEditorPart activeEditor = workbenchWindow.getActivePage() + .getActiveEditor(); + if (activeEditor instanceof IGraphicalEditor) { + setContributingEditor((IGraphicalEditor) activeEditor); + } else { + editorSelectionChanged(StructuredSelection.EMPTY); + } + } + + private void setContributingEditor(IGraphicalEditor editor) { + if (editor == contributingEditor) { + return; + } + + if (contributingEditor != null) { + ISelectionProvider selectionProvider = contributingEditor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) + selectionProvider.removeSelectionChangedListener( + getSelectionChangedListener()); + } + + contributingEditor = editor; + + ISelection newSelection = null; + + if (contributingEditor != null) { + ISelectionProvider selectionProvider = contributingEditor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.addSelectionChangedListener( + getSelectionChangedListener()); + newSelection = selectionProvider.getSelection(); + } + } + if (newSelection == null) { + newSelection = StructuredSelection.EMPTY; + } + + if (contentArea.isDisposed()) { + return; + } + + editorSelectionChanged(newSelection); + } + + private void editorSelectionChanged(ISelection selection) { + if (selection == currentSelection + || (selection != null && selection.equals(currentSelection))) + return; + + currentSelection = selection; + setCurrentTopicPart(findSelectedTopicPart()); + + if (currentSelection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) currentSelection) + .getFirstElement(); + updateViewer(obj); + } else { + updateViewer(null); + } + } + + private void setCurrentTopicPart(ITopicPart topicPart) { + if (topicPart == currentTopicPart) + return; + + unhookTopic(); + saveNotes(); + this.currentTopicPart = topicPart; +// forceRefreshViewer(); + hookTopic(); + } + + private ITopicPart findSelectedTopicPart() { + if (contributingEditor == null) + return null; + + if (currentSelection == null || currentSelection.isEmpty() + || !(currentSelection instanceof IStructuredSelection)) + return null; + + Object o = ((IStructuredSelection) currentSelection).getFirstElement(); + + IGraphicalEditorPage page = contributingEditor.getActivePageInstance(); + if (page == null) + return null; + + IPart part = page.getViewer().findPart(o); + if (part instanceof ITopicPart) + return (ITopicPart) part; + + return null; + } + + private ISelectionChangedListener getSelectionChangedListener() { + if (listener == null) { + listener = new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + editorSelectionChanged(event.getSelection()); + } + }; + } + return listener; + } + + private void hookTopic() { + if (currentTopicPart != null) { + ITopic topic = currentTopicPart.getTopic(); + if (eventRegister == null) + eventRegister = new CoreEventRegister(topic, this); + eventRegister.register(Core.TopicNotes); + if (DEBUG) + System.out.println("Model listeners installed"); //$NON-NLS-1$ + } + } + + private void unhookTopic() { + if (eventRegister != null) { + eventRegister.unregisterAll(); + if (DEBUG) + System.out.println("Model listeners uninstalled"); //$NON-NLS-1$ + eventRegister = null; + } + } + + private void saveNotes() { + if (adapter == null || currentTopicPart == null + || !(viewer instanceof TopicNotesViewer) + || viewer.getControl().isDisposed() + || !((TopicNotesViewer) viewer).hasModified()) { + deactivateJob(); + return; + } + + if (DEBUG) + System.out.println("Start saving notes"); //$NON-NLS-1$ + + savingNotes = true; + ITopic topic = currentTopicPart.getTopic(); + ICommandStack cs = getCommandStack(); + if (cs != null) { + doSaveNotes(topic, cs); + } else { + forceSaveNotes(topic); + } + ((TopicNotesViewer) viewer).resetModified(); + savingNotes = false; + + deactivateJob(); + + if (DEBUG) + System.out.println("End saving notes"); //$NON-NLS-1$ + } + + private ICommandStack getCommandStack() { + EditDomain domain = currentTopicPart.getSite().getViewer() + .getEditDomain(); + if (domain != null) { + return domain.getCommandStack(); + } + return null; + } + + private void doSaveNotes(ITopic topic, ICommandStack cs) { + ModifyNotesCommand modifyHtml = new ModifyNotesCommand(topic, + adapter.makeNewHtmlContent(), INotes.HTML); + ModifyNotesCommand modifyPlain = new ModifyNotesCommand(topic, + adapter.makeNewPlainContent(), INotes.PLAIN); + CompoundCommand cmd = new CompoundCommand(modifyHtml, modifyPlain); + cmd.setLabel(CommandMessages.Command_ModifyNotes); + cs.execute(cmd); + } + + private void forceSaveNotes(ITopic topic) { + INotes notes = topic.getNotes(); + notes.setContent(INotes.HTML, adapter.makeNewHtmlContent()); + notes.setContent(INotes.PLAIN, adapter.makeNewPlainContent()); + } + + protected void setFocus() { + super.setFocus(); + if (viewer instanceof TopicNotesViewer) { + ((TopicNotesViewer) viewer).getImplementation().getFocusControl() + .setFocus(); + } else if (viewer instanceof SheetNotesViewer) { + viewer.getControl().setFocus(); + } + } + + private void updateViewer(Object input) { + if (contentArea == null || contentArea.isDisposed()) { + return; + } + contentArea.setRedraw(false); + contentArea.setEnabled(true); + + RichDocumentNotesAdapter oldAdapter = this.adapter; + if (viewer instanceof TopicNotesViewer && input instanceof ITopic) { + unhookDocument(); + this.adapter = createNotesAdapter(); + viewer.setInput(adapter); + hookDocument(); + } else if (viewer instanceof SheetNotesViewer + && (input instanceof ISheet || input instanceof IRelationship + || input instanceof IBoundary)) { + viewer.setInput(input); + ((SheetNotesViewer) viewer).setEditor(contributingEditor); + } else { + if (viewer instanceof TopicNotesViewer) { + removeSpellChecker(); + deactivateHandlers(); + if (((TopicNotesViewer) viewer).getImplementation() != null) { + ((TopicNotesViewer) viewer).getImplementation() + .removePostSelectionChangedListener(this); + } + unhookDocument(); + } + if (viewer instanceof SheetNotesViewer) { + ((SheetNotesViewer) viewer).setEditor(null); + } + if (viewer != null) { + viewer.dispose(); + viewer = null; + } + + if (input instanceof ITopic) { + viewer = new TopicNotesViewer(topicViewerContributor); + viewer.createControl(contentArea); + this.adapter = createNotesAdapter(); + viewer.setInput(adapter); + addSpellChecker(); + activateHandlers(); + ((TopicNotesViewer) viewer).getImplementation() + .addPostSelectionChangedListener(this); + hookDocument(); + + new ContextActivator(((TopicNotesViewer) viewer) + .getImplementation().getFocusControl()); + + } else if (input instanceof ISheet || input instanceof IBoundary + || input instanceof IRelationship) { + viewer = new SheetNotesViewer(contributingEditor); + viewer.createControl(contentArea); + viewer.setInput(input); + } else { + contentArea.setEnabled(false); + } + } + contentArea.setRedraw(true); + contentArea.layout(true, true); + + if (oldAdapter != null) { + oldAdapter.dispose(); + } + update(); + + unregisterTextActionHandlers(); + registerGlobalTextActionHandlers(); + registerRichTextActionHandlers(); + } + + private void hookDocument() { + IRichDocument document = ((TopicNotesViewer) viewer).getImplementation() + .getDocument(); + if (document != null) { + document.addDocumentListener(this); + document.addRichDocumentListener(this); + if (DEBUG) + System.out.println("Document hooked"); //$NON-NLS-1$ + } + } + + private void unhookDocument() { + IRichDocument document = ((TopicNotesViewer) viewer).getImplementation() + .getDocument(); + if (document != null) { + document.removeDocumentListener(this); + document.removeRichDocumentListener(this); + if (DEBUG) + System.out.println("Document unhooked"); //$NON-NLS-1$ + } + } + + private void addSpellChecker() { + spellingActivation = SpellingSupport.getInstance() + .activateSpelling(((TopicNotesViewer) viewer) + .getImplementation().getTextViewer()); + spellingPreferences = SpellingPlugin.getDefault().getPreferenceStore(); + if (spellingPreferences != null) { + spellingPreferences.addPropertyChangeListener(this); + } + } + + private void removeSpellChecker() { + if (spellingPreferences != null) { + spellingPreferences.removePropertyChangeListener(this); + spellingPreferences = null; + } + if (spellingActivation != null) { + spellingActivation.getSpellingSupport() + .deactivateSpelling(spellingActivation); + spellingActivation = null; + } + } + + private void activateHandlers() { + handlerService.activateHandler("org.xmind.ui.command.commitNotes", //$NON-NLS-1$ + commitNotesHandler); + } + + private void deactivateHandlers() { + handlerService.deactivateHandler("org.xmind.ui.command.commitNotes", //$NON-NLS-1$ + commitNotesHandler); + } + + private void update() { + if (updating) + return; + + updating = true; + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + updateJob(); + updateTextActions(); + updating = false; + } + + }); + } + + private void updateJob() { + if (!(viewer instanceof TopicNotesViewer) + || viewer.getControl().isDisposed()) + return; + + if (((TopicNotesViewer) viewer).hasModified()) { + activateJob(); + } else { + deactivateJob(); + } + } + + private void activateJob() { + if (saveNotesReg != null && saveNotesReg.isValid()) + return; + + saveNotesReg = null; + IWorkbook workbook = (IWorkbook) contributingEditor + .getAdapter(IWorkbook.class); + if (workbook instanceof ICoreEventSource2) { + saveNotesReg = ((ICoreEventSource2) workbook) + .registerOnceCoreEventListener(Core.WorkbookPreSaveOnce, + new SaveNotesJob()); + if (DEBUG) + System.out.println("Job acitvated"); //$NON-NLS-1$ + } + } + + private void deactivateJob() { + if (saveNotesReg != null) { + saveNotesReg.unregister(); + saveNotesReg = null; + } + } + + private void updateTextActions() { + if (!(viewer instanceof TopicNotesViewer) + || viewer.getControl().isDisposed() || textActions == null + || textActions.isEmpty()) + return; + TextViewer textViewer = ((TopicNotesViewer) viewer).getImplementation() + .getTextViewer(); + if (textViewer != null) { + for (TextAction action : textActions) { + action.update(textViewer); + } + } + } + + private void forceRefreshViewer() { + RichDocumentNotesAdapter oldAdapter = this.adapter; + if (viewer != null && !viewer.getControl().isDisposed()) { + this.adapter = createNotesAdapter(); + if (DEBUG) + if (adapter != null) + System.out.println("New adapter created"); //$NON-NLS-1$ + unhookDocument(); + viewer.setInput(adapter); + if (adapter != null) { + hookDocument(); + } + } else { + this.adapter = null; + } + if (oldAdapter != null) { + oldAdapter.dispose(); + if (DEBUG) + System.out.println("Old adapter disposed"); //$NON-NLS-1$ + } + update(); + } + + private RichDocumentNotesAdapter createNotesAdapter() { + if (currentTopicPart == null) + return null; + ITopic topic = currentTopicPart.getTopic(); + return new RichDocumentNotesAdapter(topic); + } + + public IWorkbenchPart getContributingPart() { + return contributingEditor; + } + + public void handleCoreEvent(final CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + String eventType = event.getType(); + if (Core.TopicNotes.equals(eventType)) { + handleNotesChanged(); + } + } + }); + } + + private void handleNotesChanged() { + if (savingNotes) + return; + + forceRefreshViewer(); + } + + public void partActivated(IWorkbenchPart part) { + if (DEBUG) + System.out.println("Part activated: " + part); //$NON-NLS-1$ + MPart modelPart = (MPart) getAdapter(MPart.class); + Object e4Wrapper = modelPart.getTransientData() + .get(E4PartWrapper.E4_WRAPPER_KEY); + if (part == e4Wrapper || !(part instanceof IEditorPart)) + return; + + if (part instanceof IGraphicalEditor) { + setContributingEditor((IGraphicalEditor) part); + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + if (DEBUG) + System.out.println("Part closed: " + part); //$NON-NLS-1$ + if (part == this.contributingEditor) { + setContributingEditor(null); + } + } + + public void partDeactivated(IWorkbenchPart part) { + if (DEBUG) + System.out.println("Part deactivated: " + part); //$NON-NLS-1$ + MPart modelPart = (MPart) getAdapter(MPart.class); + Object e4Wrapper = modelPart.getTransientData() + .get(E4PartWrapper.E4_WRAPPER_KEY); + if (part == e4Wrapper) { + saveNotes(); + } + } + + public void partOpened(IWorkbenchPart part) { + } + + public void documentAboutToBeChanged(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + update(); + } + + public void selectionChanged(SelectionChangedEvent event) { + update(); + } + + public void imageChanged(IRichDocument document, + ImagePlaceHolder[] oldImages, ImagePlaceHolder[] newImages) { + update(); + } + + public void lineStyleChanged(IRichDocument document, + LineStyle[] oldLineStyles, LineStyle[] newLineStyles) { + update(); + } + + public void textStyleChanged(IRichDocument document, + StyleRange[] oldTextStyles, StyleRange[] newTextStyles) { + update(); + } + + public void hyperlinkChanged(IRichDocument document, + Hyperlink[] oldHyperlinks, Hyperlink[] newHyperlinks) { + update(); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse + * .jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + if (SpellingPlugin.SPELLING_CHECK_ENABLED.equals(event.getProperty())) { + if (spellingActivation != null) { + spellingActivation.getSpellingSupport() + .deactivateSpelling(spellingActivation); + spellingActivation = null; + } + if (spellingPreferences + .getBoolean(SpellingPlugin.SPELLING_CHECK_ENABLED)) { + spellingActivation = SpellingSupport.getInstance() + .activateSpelling(((TopicNotesViewer) viewer) + .getImplementation().getTextViewer()); + } + } + } + + public void dispose() { + deactivateHandlers(); + removeSpellChecker(); + + setCurrentTopicPart(null); + workbenchWindow.getActivePage().removePartListener(this); + setContributingEditor(null); + unregisterTextActionHandlers(); + + handlerService = null; + super.dispose(); + + if (findReplaceAction != null) { + findReplaceAction.dispose(); + findReplaceAction = null; + } + textActions = null; + if (adapter != null) { + adapter.dispose(); + adapter = null; + } + if (viewer != null) { + viewer.dispose(); + viewer = null; + } + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter == IContributedContentsView.class) { + return this; + } else if (adapter == IFindReplaceOperationProvider.class) { + if (notesOperationProvider == null) { + notesOperationProvider = new NotesFindReplaceOperationProvider( + this); + } + return notesOperationProvider; + } else if (adapter == IFindReplaceTarget.class) { + if (viewer instanceof TopicNotesViewer) { + IRichTextEditViewer rtViewer = ((TopicNotesViewer) viewer) + .getImplementation(); + if (rtViewer != null) { + TextViewer textViewer = rtViewer.getTextViewer(); + if (textViewer != null) + return textViewer.getFindReplaceTarget(); + } + } + } else if (adapter == ITextViewer.class) { + if (viewer instanceof TopicNotesViewer) { + IRichTextEditViewer rtViewer = ((TopicNotesViewer) viewer) + .getImplementation(); + if (rtViewer != null) + return rtViewer.getTextViewer(); + } + } else if (adapter == IRichTextEditViewer.class) { + if (viewer instanceof TopicNotesViewer) { + return ((TopicNotesViewer) viewer).getImplementation(); + } + } else if (adapter == ITopicPart.class) { + return currentTopicPart; + } else if (adapter == ITopic.class) { + return currentTopicPart == null ? null + : currentTopicPart.getTopic(); + } + return super.getAdapter(adapter); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ProgressProcessor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ProgressProcessor.java index 87aa0f04b..590f0a131 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ProgressProcessor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ProgressProcessor.java @@ -1,145 +1,152 @@ -package org.xmind.ui.internal.e4models; - -import java.util.List; -import java.util.Map; - -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.MApplication; -import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; -import org.eclipse.e4.ui.model.application.ui.basic.MDialog; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; -import org.eclipse.e4.ui.workbench.IPresentationEngine; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.osgi.framework.FrameworkUtil; - -public class ProgressProcessor { - - private static final String DIALOG_PREFIX = "DIALOG:"; //$NON-NLS-1$ - - private static final String CUSTOM_LOCATION_KEY = "customLocation"; //$NON-NLS-1$ - - private static final int DEFAULT_DIALOG_Y = 0; - - private static final int DEFAULT_DIALOG_X = 0; - - private static final int DEFAULT_DIALOG_WIDTH = 600; - - private static final int DEFAULT_DIALOG_HEIGHT = 700; - - @Execute - public void execute(EModelService modelService, MApplication application) { - String partId = "org.eclipse.ui.views.ProgressView"; //$NON-NLS-1$ - String partStackId = "progress"; //$NON-NLS-1$ - - //create dialog model - MPartDescriptor partDescriptor = null; - for (MPartDescriptor mp : application.getDescriptors()) { - if (partId.equals(mp.getElementId())) { - partDescriptor = mp; - break; - } - } - if (partDescriptor == null) { - return; - } - - List existingDialogs = modelService.findElements(application, - DIALOG_PREFIX + partId, MDialog.class, null); - boolean dialogExisted = !existingDialogs.isEmpty(); - MDialog dialogModel = dialogExisted ? existingDialogs.get(0) - : createDialog(modelService, partDescriptor, partId); - dialogModel.setToBeRendered(false); - if (!dialogExisted) { - application.getChildren().get(0).getWindows().add(dialogModel); - } - - //create part stack - List partStacks = modelService.findElements(dialogModel, - partStackId, MPartStack.class, null); - boolean partStackExisted = !partStacks.isEmpty(); - MPartStack partStack = partStackExisted ? partStacks.get(0) - : createPartStack(modelService, partStackId); - if (!partStackExisted) { - dialogModel.getChildren().add(partStack); - } - - //create part - List parts = modelService.findElements(partStack, partId, - MPart.class, null); - boolean partExisted = !parts.isEmpty(); - MPart part = partExisted ? parts.get(0) : null; - if (part == null) { - part = modelService.createModelElement(MPart.class); - part.setElementId(partId); - part.setContributionURI(partDescriptor.getContributionURI()); - partStack.getChildren().add(part); - partStack.setSelectedElement(part); - } - - } - - private MDialog createDialog(EModelService modelService, - MPartDescriptor partDescriptor, String partId) { - String contributorURI = "platform:/plugin/" //$NON-NLS-1$ - + FrameworkUtil.getBundle(getClass()).getSymbolicName(); - - MDialog dialogModel = modelService.createModelElement(MDialog.class); - dialogModel.setElementId(DIALOG_PREFIX + partId); - dialogModel.setLabel(partDescriptor.getLabel()); - dialogModel.setContributorURI(contributorURI); - - String dialogStyle = partDescriptor.getPersistedState() - .get(IPresentationEngine.STYLE_OVERRIDE_KEY); - dialogModel.getPersistedState() - .put(IPresentationEngine.STYLE_OVERRIDE_KEY, dialogStyle); - - configDialog(dialogModel, partDescriptor); - - return dialogModel; - } - - private void configDialog(MDialog dialogModel, - MPartDescriptor partDescriptor) { - Map ps = partDescriptor.getPersistedState(); - String location = ps.get(CUSTOM_LOCATION_KEY); - String[] locations = location.split(","); //$NON-NLS-1$ - - if (locations.length < 4) { - String[] tempLocations = new String[4]; - for (int i = 0; i < locations.length; i++) - tempLocations[i] = locations[i]; - locations = tempLocations; - } - - int dialogX = getDigitalValue(locations[0], DEFAULT_DIALOG_X); - int dialogY = getDigitalValue(locations[1], DEFAULT_DIALOG_Y); - int dialogW = getDigitalValue(locations[2], DEFAULT_DIALOG_WIDTH); - int dialogH = getDigitalValue(locations[3], DEFAULT_DIALOG_HEIGHT); - - dialogModel.setX(dialogX); - dialogModel.setY(dialogY); - dialogModel.setWidth(dialogW); - dialogModel.setHeight(dialogH); - - dialogModel.getPersistedState().put(CUSTOM_LOCATION_KEY, location); - } - - private int getDigitalValue(String value, int defaultValue) { - return isNone(value) ? defaultValue : Integer.valueOf(value); - } - - private boolean isNone(String value) { - return value == null || "".equals(value); //$NON-NLS-1$ - } - - private MPartStack createPartStack(EModelService modelService, - String partStackId) { - MPartStack partStack = modelService - .createModelElement(MPartStack.class); - partStack.setElementId(partStackId); - partStack.setVisible(true); - return partStack; - } - -} +package org.xmind.ui.internal.e4models; + +import java.util.List; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; +import org.eclipse.e4.ui.model.application.ui.basic.MDialog; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.osgi.framework.FrameworkUtil; + +public class ProgressProcessor { + + private static final String DIALOG_PREFIX = "DIALOG:"; //$NON-NLS-1$ + + private static final String CUSTOM_LOCATION_KEY = "customLocation"; //$NON-NLS-1$ + + private static final int DEFAULT_DIALOG_Y = 0; + + private static final int DEFAULT_DIALOG_X = 0; + + private static final int DEFAULT_DIALOG_WIDTH = 600; + + private static final int DEFAULT_DIALOG_HEIGHT = 700; + + @Execute + public void execute(EModelService modelService, MApplication application) { + String partId = "org.eclipse.ui.views.ProgressView"; //$NON-NLS-1$ + String partStackId = "org.xmind.ui.stack.progress"; //$NON-NLS-1$ + + //create dialog model + MPartDescriptor partDescriptor = null; + for (MPartDescriptor mp : application.getDescriptors()) { + if (partId.equals(mp.getElementId())) { + partDescriptor = mp; + break; + } + } + if (partDescriptor == null) { + return; + } + + List existingDialogs = modelService.findElements(application, + DIALOG_PREFIX + partId, MDialog.class, null); + boolean dialogExisted = !existingDialogs.isEmpty(); + MDialog dialogModel = dialogExisted ? existingDialogs.get(0) + : createDialog(modelService, partDescriptor, partId); + dialogModel.setToBeRendered(false); + if (!dialogExisted) { + application.getChildren().get(0).getWindows().add(dialogModel); + } + + //create part stack + List partStacks = modelService.findElements(dialogModel, + partStackId, MPartStack.class, null); + boolean partStackExisted = !partStacks.isEmpty(); + MPartStack partStack = partStackExisted ? partStacks.get(0) + : createPartStack(modelService, partStackId); + if (!partStackExisted) { + dialogModel.getChildren().add(partStack); + } + + //create part + List parts = modelService.findElements(partStack, partId, + MPart.class, null); + boolean partExisted = !parts.isEmpty(); + MPart part = partExisted ? parts.get(0) : null; + if (part == null) { + part = modelService.createModelElement(MPart.class); + part.setElementId(partId); + part.setContributionURI(partDescriptor.getContributionURI()); + partStack.getChildren().add(part); + partStack.setSelectedElement(part); + } + + } + + private MDialog createDialog(EModelService modelService, + MPartDescriptor partDescriptor, String partId) { + String contributorURI = "platform:/plugin/" //$NON-NLS-1$ + + FrameworkUtil.getBundle(getClass()).getSymbolicName(); + + MDialog dialogModel = modelService.createModelElement(MDialog.class); + dialogModel.setElementId(DIALOG_PREFIX + partId); + dialogModel.setLabel(partDescriptor.getLabel()); + dialogModel.setContributorURI(contributorURI); + + String dialogStyle = partDescriptor.getPersistedState() + .get(IPresentationEngine.STYLE_OVERRIDE_KEY); + dialogModel.getPersistedState() + .put(IPresentationEngine.STYLE_OVERRIDE_KEY, dialogStyle); + + configDialog(dialogModel, partDescriptor); + + return dialogModel; + } + + private void configDialog(MDialog dialogModel, + MPartDescriptor partDescriptor) { + + String location = dialogModel.getPersistedState() + .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); + if (location == null || location.equals("")) { //$NON-NLS-1$ + location = partDescriptor.getPersistedState() + .get(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION); + } + location = location == null ? "" : location; //$NON-NLS-1$ + String[] locations = location.split(","); //$NON-NLS-1$ + + if (locations.length < 4) { + String[] tempLocations = new String[4]; + for (int i = 0; i < locations.length; i++) + tempLocations[i] = locations[i]; + locations = tempLocations; + } + + int dialogX = getDigitalValue(locations[0], DEFAULT_DIALOG_X); + int dialogY = getDigitalValue(locations[1], DEFAULT_DIALOG_Y); + int dialogW = getDigitalValue(locations[2], DEFAULT_DIALOG_WIDTH); + int dialogH = getDigitalValue(locations[3], DEFAULT_DIALOG_HEIGHT); + + dialogModel.setX(dialogX); + dialogModel.setY(dialogY); + dialogModel.setWidth(dialogW); + dialogModel.setHeight(dialogH); + + dialogModel.getPersistedState() + .put(IModelConstants.KEY_DIALOG_PART_CUSTOM_LOCATION, location); + } + + private int getDigitalValue(String value, int defaultValue) { + return isNone(value) ? defaultValue : Integer.valueOf(value); + } + + private boolean isNone(String value) { + return value == null || "".equals(value); //$NON-NLS-1$ + } + + private MPartStack createPartStack(EModelService modelService, + String partStackId) { + MPartStack partStack = modelService + .createModelElement(MPartStack.class); + partStack.setElementId(partStackId); + partStack.setVisible(true); + partStack.getTags().add(IModelConstants.TAG_X_STACK); + return partStack; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ThemesPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ThemesPart.java index cdca94e55..79c6d40ff 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ThemesPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ThemesPart.java @@ -1,324 +1,337 @@ -package org.xmind.ui.internal.e4models; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.editor.MindMapEditor; -import org.xmind.ui.internal.utils.ResourceUtils; -import org.xmind.ui.internal.views.CategorizedThemeViewer; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; - -public class ThemesPart extends ViewModelPart - implements ICoreEventListener, IPageChangedListener { - - private CategorizedThemeViewer viewer; - private ICoreEventRegister register = null; - - private IGraphicalEditor sourceEditor; - private ICoreEventRegister topicRegister = null; - private ITopic rootTopic; - - @Override - protected Control doCreateContent(Composite parent) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("ShowThemeCount"); //$NON-NLS-1$ - Composite container = new Composite(parent, SWT.NONE); - container.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ - - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - container.setLayout(layout); - container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - this.registerContextMenu(container, - IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_THEME); - - viewer = new CategorizedThemeViewer(container); - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - this.setSelectionProvider(viewer); - - ICoreEventSupport ces = (ICoreEventSupport) MindMapUI - .getResourceManager().getUserThemeSheet() - .getAdapter(ICoreEventSupport.class); - register = new CoreEventRegister(this); - register.setNextSupport(ces); - register.register(Core.StyleAdd); - register.register(Core.StyleRemove); - register.register(Core.Name); - - return container; - } - - @Override - public void handleCoreEvent(final CoreEvent event) { - if (viewer == null) - return; - - Control c = viewer.getControl(); - if (c == null || c.isDisposed()) - return; - - c.getDisplay().syncExec(new Runnable() { - public void run() { - if (Core.ThemeId.equals(event.getType())) { - } else if (Core.Name.equals(event.getType())) { - viewer.update(new Object[] { event.getSource() }); - } else if (Core.StyleAdd.equals(event.getType())) { - viewer.refresh(); - Object target = event.getTarget(); - viewer.setSelection( - target == null ? StructuredSelection.EMPTY - : new StructuredSelection(target), - true); - } else if (Core.StyleRemove.equals(event.getType())) { - viewer.setInput(viewer.getInput()); - } else if (Core.StructureClass.endsWith(event.getType())) { - viewer.refresh(true); - } - } - }); - } - - @Override - public void dispose() { - if (register != null) { - register.unregisterAll(); - register = null; - } - if (topicRegister != null) { - topicRegister.unregisterAll(); - topicRegister = null; - } - if (sourceEditor != null) { - sourceEditor.removePageChangedListener(this); - sourceEditor = null; - } - super.dispose(); - viewer = null; - } - - @Override - public void init() { - super.init(); - registerRunnables(); - this.registerViewMenu(IModelConstants.VIEWMENU_ID_THEME); - } - - private void registerRunnables() { - IEclipseContext ec = getAdapter(MPart.class).getContext(); - ec.set(IModelConstants.KEY_MODEL_PART_REFRESH_PAGE, - new IContextRunnable() { - @Override - public void run() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.refresh(); - } - } - }); - ec.set(IModelConstants.KEY_MODEL_PART_RENAME, new IContextRunnable() { - @Override - public void run() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - List themes = getSelectedThemes(); - if (themes.size() == 1) - viewer.startEditing(themes.get(0)); - } - } - - @Override - public boolean canExecute(IEclipseContext context, - String contextKey) { - List themes = getSelectedThemes(); - Set systemThemeSets = MindMapUI.getResourceManager() - .getSystemThemeSheet() - .getStyles(IStyleSheet.MASTER_STYLES); - boolean canExecute = themes.size() == 1; - for (IStyle theme : themes) { - canExecute = canExecute && !systemThemeSets.contains(theme); - } - return canExecute; - } - }); - - ec.set(IModelConstants.KEY_MODEL_PART_DUPLICATE, - new IContextRunnable() { - @Override - public void run() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - List themes = getSelectedThemes(); - if (!themes.isEmpty()) { - ResourceUtils.duplicateThemes(themes); - } - } - } - - @Override - public boolean canExecute(IEclipseContext context, - String contextKey) { - List themes = getSelectedThemes(); - boolean canExecute = !themes.isEmpty(); - return canExecute; - } - - }); - - ec.set(IModelConstants.KEY_MODEL_PART_DELETE, new IContextRunnable() { - - @Override - public void run() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - List themes = getSelectedThemes(); - if (!themes.isEmpty() - && ResourceUtils.confirmToDeleteStyles( - viewer.getControl().getShell(), themes)) { - ResourceUtils.deleteStyles(themes); - } - } - } - - @Override - public boolean canExecute(IEclipseContext context, - String contextKey) { - List themes = getSelectedThemes(); - Set systemThemeSets = MindMapUI.getResourceManager() - .getSystemThemeSheet() - .getStyles(IStyleSheet.MASTER_STYLES); - boolean canExecute = !themes.isEmpty(); - for (IStyle theme : themes) { - canExecute = canExecute && !systemThemeSets.contains(theme); - } - return canExecute; - } - }); - - } - - private List getSelectedThemes() { - List styles = new ArrayList(); - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - ISelection selection = viewer.getStructuredSelection(); - if (selection instanceof IStructuredSelection) { - for (Object element : ((IStructuredSelection) selection) - .toList()) { - styles.add((IStyle) element); - } - } - } - return styles; - } - - private ITopic findRootTopic(IGraphicalEditorPage page) { - ISheet sheet = page.getAdapter(ISheet.class); - if (sheet != null) - return sheet.getRootTopic(); - - return null; - } - - private void setRootTopic(ITopic topic) { - if (topic == rootTopic) - return; - - if (topicRegister == null) - topicRegister = new CoreEventRegister(this); - - if (rootTopic != null) - topicRegister.unregisterAll(); - - if (topic != null) { - if (viewer != null) - viewer.refresh(true); - topicRegister.setNextSourceFrom(topic); - topicRegister.register(Core.StructureClass); - } - } - - private void setEditor(IGraphicalEditor editor) { - if (editor == this.sourceEditor) - return; - - if (this.sourceEditor != null) { - this.sourceEditor.removePageChangedListener(this); - } - - this.sourceEditor = editor; - - if (this.sourceEditor != null) { - this.sourceEditor.addPageChangedListener(this); - - IGraphicalEditorPage page = sourceEditor.getActivePageInstance(); - if (page != null) - setRootTopic(findRootTopic(page)); - } - } - - @Override - protected void handlePartActivated(MPart part) { - super.handlePartActivated(part); - final IEditorPart editorPart = part.getContext().get(IEditorPart.class); - if (editorPart instanceof MindMapEditor) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - setEditor((MindMapEditor) editorPart); - } - }); - } - - } - - public void pageChanged(PageChangedEvent event) { - final IGraphicalEditorPage page = (IGraphicalEditorPage) event - .getSelectedPage(); - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (page.isDisposed() || page.getControl() == null - || page.getControl().isDisposed()) - return; - setRootTopic(findRootTopic(page)); - } - }); - } - -} +package org.xmind.ui.internal.e4models; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.editor.MindMapEditor; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.internal.views.CategorizedThemeViewer; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; + +public class ThemesPart extends ViewModelPart + implements ICoreEventListener, IPageChangedListener { + + private CategorizedThemeViewer viewer; + private ICoreEventRegister register = null; + + private IGraphicalEditor sourceEditor; + private ICoreEventRegister topicRegister = null; + private ITopic rootTopic; + + @Override + protected Control doCreateContent(Composite parent) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SHOW_THEME_COUNT); + + Composite container = new Composite(parent, SWT.NONE); + container.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + container.setLayout(layout); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + this.registerContextMenu(container, + IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_THEME); + + viewer = new CategorizedThemeViewer(container) { + @Override + protected void postInit() { + getProperties().set(GalleryViewer.FrameContentSize, + new Dimension(240, 120)); + super.postInit(); + }; + }; + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + gridData.horizontalIndent = Util.isMac() ? 8 : -2; + viewer.getControl().setLayoutData(gridData); + + this.setSelectionProvider(viewer); + + ICoreEventSupport ces = (ICoreEventSupport) MindMapUI + .getResourceManager().getUserThemeSheet() + .getAdapter(ICoreEventSupport.class); + register = new CoreEventRegister(this); + register.setNextSupport(ces); + register.register(Core.StyleAdd); + register.register(Core.StyleRemove); + register.register(Core.Name); + + return container; + } + + @Override + public void handleCoreEvent(final CoreEvent event) { + if (viewer == null) + return; + + Control c = viewer.getControl(); + if (c == null || c.isDisposed()) + return; + + c.getDisplay().syncExec(new Runnable() { + public void run() { + if (Core.ThemeId.equals(event.getType())) { + } else if (Core.Name.equals(event.getType())) { + viewer.update(new Object[] { event.getSource() }); + } else if (Core.StyleAdd.equals(event.getType())) { + viewer.refresh(); + Object target = event.getTarget(); + viewer.setSelection( + target == null ? StructuredSelection.EMPTY + : new StructuredSelection(target), + true); + } else if (Core.StyleRemove.equals(event.getType())) { + viewer.setInput(viewer.getInput()); + } else if (Core.StructureClass.endsWith(event.getType())) { + viewer.refresh(true); + } + } + }); + } + + @Override + public void dispose() { + if (register != null) { + register.unregisterAll(); + register = null; + } + if (topicRegister != null) { + topicRegister.unregisterAll(); + topicRegister = null; + } + if (sourceEditor != null) { + sourceEditor.removePageChangedListener(this); + sourceEditor = null; + } + super.dispose(); + viewer = null; + } + + @Override + public void init() { + super.init(); + registerRunnables(); + this.registerViewMenu(IModelConstants.VIEWMENU_ID_THEME); + } + + private void registerRunnables() { + IEclipseContext ec = getAdapter(MPart.class).getContext(); + ec.set(IModelConstants.KEY_MODEL_PART_REFRESH_PAGE, + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.refresh(); + } + } + }); + ec.set(IModelConstants.KEY_MODEL_PART_RENAME, new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List themes = getSelectedThemes(); + if (themes.size() == 1) + viewer.startEditing(themes.get(0)); + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List themes = getSelectedThemes(); + Set systemThemeSets = MindMapUI.getResourceManager() + .getSystemThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + boolean canExecute = themes.size() == 1; + for (IStyle theme : themes) { + canExecute = canExecute && !systemThemeSets.contains(theme); + } + return canExecute; + } + }); + + ec.set(IModelConstants.KEY_MODEL_PART_DUPLICATE, + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List themes = getSelectedThemes(); + if (!themes.isEmpty()) { + ResourceUtils.duplicateThemes(themes); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List themes = getSelectedThemes(); + boolean canExecute = !themes.isEmpty(); + return canExecute; + } + + }); + + ec.set(IModelConstants.KEY_MODEL_PART_DELETE, new IContextRunnable() { + + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List themes = getSelectedThemes(); + if (!themes.isEmpty() + && ResourceUtils.confirmToDeleteStyles( + viewer.getControl().getShell(), themes)) { + ResourceUtils.deleteStyles(themes); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List themes = getSelectedThemes(); + Set systemThemeSets = MindMapUI.getResourceManager() + .getSystemThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + boolean canExecute = !themes.isEmpty(); + for (IStyle theme : themes) { + canExecute = canExecute && !systemThemeSets.contains(theme); + } + return canExecute; + } + }); + + } + + private List getSelectedThemes() { + List styles = new ArrayList(); + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + ISelection selection = viewer.getStructuredSelection(); + if (selection instanceof IStructuredSelection) { + for (Object element : ((IStructuredSelection) selection) + .toList()) { + styles.add((IStyle) element); + } + } + } + return styles; + } + + private ITopic findRootTopic(IGraphicalEditorPage page) { + ISheet sheet = page.getAdapter(ISheet.class); + if (sheet != null) + return sheet.getRootTopic(); + + return null; + } + + private void setRootTopic(ITopic topic) { + if (topic == rootTopic) + return; + + if (topicRegister == null) + topicRegister = new CoreEventRegister(this); + + if (rootTopic != null) + topicRegister.unregisterAll(); + + if (topic != null) { + if (viewer != null) + viewer.refresh(true); + topicRegister.setNextSourceFrom(topic); + topicRegister.register(Core.StructureClass); + } + } + + private void setEditor(IGraphicalEditor editor) { + if (editor == this.sourceEditor) + return; + + if (this.sourceEditor != null) { + this.sourceEditor.removePageChangedListener(this); + } + + this.sourceEditor = editor; + + if (this.sourceEditor != null) { + this.sourceEditor.addPageChangedListener(this); + + IGraphicalEditorPage page = sourceEditor.getActivePageInstance(); + if (page != null) + setRootTopic(findRootTopic(page)); + } + } + + @Override + protected void handlePartActivated(MPart part) { + super.handlePartActivated(part); + final IEditorPart editorPart = part.getContext().get(IEditorPart.class); + if (editorPart instanceof MindMapEditor) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + setEditor((MindMapEditor) editorPart); + } + }); + } + + } + + public void pageChanged(PageChangedEvent event) { + final IGraphicalEditorPage page = (IGraphicalEditorPage) event + .getSelectedPage(); + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (page.isDisposed() || page.getControl() == null + || page.getControl().isDisposed()) + return; + setRootTopic(findRootTopic(page)); + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AbstractWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AbstractWorkbookRef.java index 80e6de538..7ff4324ac 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AbstractWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AbstractWorkbookRef.java @@ -1,770 +1,779 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IPersistable; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IDeserializer; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.zip.ArchiveConstants; -import org.xmind.core.io.ByteArrayStorage; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IStorage; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.ProgressReporter; -import org.xmind.gef.GEF; -import org.xmind.gef.command.CommandStack; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.ui.editor.Editable; -import org.xmind.gef.ui.editor.IEditingContext; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefListener; -import org.xmind.ui.mindmap.MindMapImageExporter; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.util.ImageFormat; - -/** - * This class implements basic behaviors of {@link IWorkbookRef} by extending - * the {@link Editable} class. - *

    Subclassing Notes

    - *
      - *
    • Each subclass MUST override - * {@link #doLoadWorkbookFromURI(IProgressMonitor, URI) doLoadWorkbookFromURI()} - * , unless it overrides one of {@link #doLoadWorkbook(IProgressMonitor) - * doLoadWorkbook()}, {@link #doOpen(IProgressMonitor) doOpen()} and - * {@link #open(IProgressMonitor) open()} to change the default behavior.
    • - *
    • Each subclass MUST override - * {@link #doSaveWorkbookToURI(IProgressMonitor, IWorkbook, URI) - * doSaveWorkbookToURI()} if it may return true from - * {@link #canSave()}, unless it overrides one of {@link #save(IProgressMonitor) - * save()} and {@link #doSave(IProgressMonitor) doSave()} to change the default - * behavior.
    • - *
    • Each subclass MUST override - * {@link #doImportFrom(IProgressMonitor, IWorkbookRef) doImportFrom()} if it - * may return true from {@link #canImportFrom(IWorkbookRef) - * canImportFrom()}, unless it overrides - * {@link #importFrom(IProgressMonitor, IWorkbookRef) importFrom()} to change - * the default behavior.
    • - *
    - * - * @author Frank Shaka - * @since 3.6.50 - */ -public abstract class AbstractWorkbookRef extends Editable - implements IWorkbookRef, ISchedulingRule, IPropertyChangeListener { - - protected static final int TEMP_SAVING_DELAY = 500; - - protected static final String ATT_TEMP_LOCATION = "tempLocation"; //$NON-NLS-1$ - - private static IEditingContext defaultEditingContext = IEditingContext.NULL; - - private IWorkbook workbook = null; - - private CoreEventRegister globalEventRegister = null; - - private IStorage tempStorage = null; - - private boolean shouldLoadFromTempStorage = false; - - private ICoreEventListener globalEventListener = new ICoreEventListener() { - public void handleCoreEvent(CoreEvent event) { - handleGlobalEvent(event); - } - }; - - private WorkbookRefEncryptable encryptable = null; - - private Job tempSavingJob = null; - private Object tempSavingLock = new Object(); - - private List workbookRefListeners = new ArrayList(); - - protected AbstractWorkbookRef(URI uri, IMemento state) { - super(uri); - - setEncryptable(createEncryptable()); - - setCommandStack(new CommandStack(Math.max(MindMapUIPlugin.getDefault() - .getPreferenceStore().getInt(PrefConstants.UNDO_LIMIT), 1))); - - MindMapUIPlugin.getDefault().getPreferenceStore() - .addPropertyChangeListener(this); - - if (state != null) { - IStorage savedTempStorage = restoreStateForTempStorage(state); - this.shouldLoadFromTempStorage = savedTempStorage != null; - setTempStorage(savedTempStorage); - } - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.mindmap.IWorkbookRef#getSaveWizardId() - */ - @Override - public String getSaveWizardId() { - return null; - } - - public IWorkbook getWorkbook() { - return this.workbook; - } - - protected void setWorkbook(IWorkbook workbook) { - IWorkbook oldWorkbook = this.workbook; - if (workbook == oldWorkbook) - return; - - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - globalEventRegister = null; - } - - if (oldWorkbook != null) { - IMarkerSheet markerSheet = oldWorkbook.getMarkerSheet(); - if (markerSheet != null) { - markerSheet.setParentSheet(null); - } - } - - this.workbook = workbook; - - if (workbook != null) { - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (markerSheet != null) { - markerSheet.setParentSheet( - MindMapUI.getResourceManager().getSystemMarkerSheet()); - } - - if (globalEventRegister == null) { - globalEventRegister = new CoreEventRegister( - globalEventListener); - } - registerGlobalEvents(globalEventRegister, workbook); - } - } - - private void registerGlobalEvents(CoreEventRegister register, - IWorkbook workbook) { - ICoreEventSupport support = (ICoreEventSupport) workbook - .getAdapter(ICoreEventSupport.class); - if (support != null) { - register.setNextSupport(support); - - register.register(Core.MarkerRefAdd); - register.register(Core.PasswordChange); - } - } - - private void handleGlobalEvent(CoreEvent event) { - String type = event.getType(); - if (Core.MarkerRefAdd.equals(type)) { - handleMarkerAdded((String) event.getTarget()); - } else if (Core.PasswordChange.equals(type)) { - scheduleTempSaving(); - } - } - - private void handleMarkerAdded(String markerId) { - IMarkerGroup recentMarkerGroup = MindMapUI.getResourceManager() - .getRecentMarkerGroup(); - - IMarkerSheet systemMarkerSheet = MindMapUI.getResourceManager() - .getSystemMarkerSheet(); - IMarker systemMarker = systemMarkerSheet.findMarker(markerId); - if (systemMarker != null) { - IMarkerGroup group = systemMarker.getParent(); - if (group != null) { - if (group.getParent() != null - && group.getParent().equals(systemMarkerSheet)) { - recentMarkerGroup.addMarker(systemMarker); - } - } - } - IMarkerSheet userMarkerSheet = MindMapUI.getResourceManager() - .getUserMarkerSheet(); - IMarker userMarker = userMarkerSheet.findMarker(markerId); - if (userMarker != null) { - IMarkerGroup group = userMarker.getParent(); - if (group != null) { - if (group.getParent() != null - && group.getParent().equals(userMarkerSheet)) { - recentMarkerGroup.addMarker(userMarker); - } - } - } - - } - - @Override - public T getAdapter(Class adapter) { - if (IWorkbook.class.equals(adapter)) - return adapter.cast(getWorkbook()); - if (IPersistable.class.equals(adapter)) - return adapter.cast(getPersistable()); - if (IEncryptable.class.equals(adapter)) - return adapter.cast(encryptable); - return super.getAdapter(adapter); - } - - protected void setEncryptable(WorkbookRefEncryptable encryptable) { - this.encryptable = encryptable; - } - - protected WorkbookRefEncryptable getEncryptable() { - return encryptable; - } - - protected IEntryStreamNormalizer getEncryptionHandler() { - return encryptable != null ? encryptable.getEncryptor() - : IEntryStreamNormalizer.NULL; - } - - @Override - protected void doOpen(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - IWorkbook workbook = doLoadWorkbook(subMonitor.newChild(90)); - Assert.isTrue(workbook != null); - doSaveWorkbookToTempStorage(subMonitor.newChild(10), workbook); - setWorkbook(workbook); - } - - protected IWorkbook doLoadWorkbook(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - if (shouldLoadFromTempStorage) { - try { - return doLoadWorkbookFromTempStorage(monitor, getTempStorage()); - } finally { - shouldLoadFromTempStorage = false; - } - } - return doLoadWorkbookFromURI(monitor, getURI()); - } - - protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, - IStorage tempStorage) - throws InterruptedException, InvocationTargetException { - try { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.setWorkbookStorage(tempStorage); - deserializer.setWorkbookStorageAsInputSource(); - deserializer.deserialize(new ProgressReporter(monitor)); - return deserializer.getWorkbook(); - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - if (e.getType() == Core.ERROR_CANCELLATION) - throw new InterruptedException(); - throw new InvocationTargetException(e); - } - } - - /** - * Subclasses MUST override this method. - * - * @param monitor - * @param uri - * @return - * @throws InterruptedException - * @throws InvocationTargetException - */ - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - throw new UnsupportedOperationException(); - } - - @Override - protected void doSave(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - IWorkbook workbook = getWorkbook(); - Assert.isTrue(workbook != null); - URI targetURI = getURI(); - Assert.isTrue(targetURI != null); - - ICoreEventSource workbookAsEventSource; - if (workbook instanceof ICoreEventSource) { - workbookAsEventSource = (ICoreEventSource) workbook; - } else { - workbookAsEventSource = null; - } - - if (workbookAsEventSource != null) { - workbookAsEventSource.getCoreEventSupport().dispatch( - workbookAsEventSource, new CoreEvent(workbookAsEventSource, - Core.WorkbookPreSaveOnce, null)); - workbookAsEventSource.getCoreEventSupport().dispatch( - workbookAsEventSource, new CoreEvent(workbookAsEventSource, - Core.WorkbookPreSave, null)); - } - - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - doSaveWorkbookToTempStorage(subMonitor.newChild(20), workbook); - doSaveWorkbookToURI(subMonitor.newChild(80), workbook, targetURI); - - if (workbookAsEventSource != null) { - workbookAsEventSource.getCoreEventSupport().dispatch( - workbookAsEventSource, new CoreEvent(workbookAsEventSource, - Core.WorkbookSave, null)); - } - } - - /// subclasses may override to prevent default behavior or add custom behaviors - protected void doSaveWorkbookToTempStorage(IProgressMonitor monitor, - IWorkbook workbook) - throws InterruptedException, InvocationTargetException { - try { - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.setEntryStreamNormalizer(getEncryptionHandler()); - serializer.serialize(new ProgressReporter(monitor)); - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - if (e.getType() == Core.ERROR_CANCELLATION) - throw new InterruptedException(); - if (e.getType() == Core.ERROR_WRONG_PASSWORD) { - if (getEncryptable() != null) { - getEncryptable().reset(); - } - } - throw new InvocationTargetException(e); - } - } - - /** - * The default implementation does nothing but throws - * UnsupportedOperationException. Subclasses MUST - * override and MUST NOT call - * super.doSaveWorkbookToURI() if true may be - * returned from {@link #canSave()}. - * - * @see #doSave(IProgressMonitor) - * @param monitor - * the progress monitor to use for reporting progress to the - * user. It is the caller's responsibility to call done() on the - * given monitor. Accepts null, indicating that no progress - * should be reported and that the operation cannot be cancelled. - * @param workbook - * the workbook to save (never null) - * @param uri - * the location to save workbook to (never null) - * @exception InvocationTargetException - * if this method must propagate a checked exception, it - * should wrap it inside an - * InvocationTargetException; runtime exceptions - * are automatically wrapped in an - * InvocationTargetException by the calling - * context - * @exception InterruptedException - * if the operation detects a request to cancel, using - * IProgressMonitor.isCanceled(), it should exit - * by throwing InterruptedException - */ - protected void doSaveWorkbookToURI(IProgressMonitor monitor, - IWorkbook workbook, URI uri) - throws InterruptedException, InvocationTargetException { - throw new UnsupportedOperationException(); - } - - @Override - protected void doClose(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - stopTempSaving(); - - IWorkbook workbook = getWorkbook(); - if (workbook != null) { - doUnloadWorkbook(subMonitor.newChild(30), workbook); - doClearTempStorageOnClose(subMonitor.newChild(60), workbook); - } - - if (encryptable != null) { - encryptable.reset(); - } - - subMonitor.setWorkRemaining(10); - subMonitor.newChild(10); - setWorkbook(null); - } - - /// subclasses may override to prevent default behavior or add custom behaviors - protected void doUnloadWorkbook(IProgressMonitor monitor, - IWorkbook workbook) - throws InterruptedException, InvocationTargetException { - // do nothing, subclasses may override - } - - /// subclasses may override to prevent default behavior or add custom behaviors - protected void doClearTempStorageOnClose(IProgressMonitor monitor, - IWorkbook workbook) - throws InterruptedException, InvocationTargetException { - IStorage storage = (IStorage) workbook.getAdapter(IStorage.class); - if (storage != null) { - storage.clear(); - } - } - - protected IStorage getTempStorage() { - if (tempStorage == null) { - IWorkbook workbook = getWorkbook(); - if (workbook != null) { - tempStorage = (IStorage) workbook.getAdapter(IStorage.class); - } - if (tempStorage == null) { - tempStorage = createDefaultTempStorage(); - } - } - return this.tempStorage; - } - - protected IStorage createDefaultTempStorage() { - return MME.createTempStorage(); - } - - protected void setTempStorage(IStorage storage) { - this.tempStorage = storage; - } - - @Override - public boolean canImportFrom(IWorkbookRef source) { - return false; - } - - public void importFrom(IProgressMonitor monitor, final IWorkbookRef source) - throws InterruptedException, InvocationTargetException { - if (!canImportFrom(source)) - throw new IllegalArgumentException( - "Can't import from the given workbook ref"); //$NON-NLS-1$ - if (source.isInState(CLOSED)) - throw new IllegalArgumentException( - "The given workbook ref is closed"); //$NON-NLS-1$ - if (!isInState(CLOSED)) - throw new IllegalStateException( - "Import operation is not allowed when workbook ref is already open"); //$NON-NLS-1$ - if (isInState(OPENING | CLOSING | SAVING)) - throw new IllegalStateException( - "Concurrent open/close/save/import operations are not allowed in a workbook ref"); //$NON-NLS-1$ - - try { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - subMonitor.newChild(5); - addState(SAVING); - try { - doImportFrom(subMonitor.newChild(90), source); - } finally { - subMonitor.newChild(5); - removeState(SAVING); - } - } catch (OperationCanceledException e) { - // interpret cancellation - throw new InterruptedException(); - } - } - - protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) - throws InterruptedException, InvocationTargetException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.mindmap.IWorkbookRef#getPreviewImageData(java.lang.String, - * org.xmind.ui.internal.editor.MindMapPreviewOptions) - */ - @Override - public InputStream getPreviewImageData(String sheetId, - MindMapPreviewOptions options) throws IOException { - if (sheetId == null) - throw new IllegalArgumentException(); - - IWorkbook workbook = getWorkbook(); - - /// check if workbook is encrypted, - /// then no preview image should be available - IFileEntry contentEntry = workbook.getManifest() - .getFileEntry(ArchiveConstants.CONTENT_XML); - if (contentEntry != null && contentEntry.getEncryptionData() != null) - return null; - - if (workbook != null - && sheetId.equals(workbook.getPrimarySheet().getId())) { - IFileEntry previewEntry = workbook.getManifest() - .getFileEntry(MindMapImageExporter - .toThumbnailArchivePath(ImageFormat.PNG)); - if (previewEntry == null) { - previewEntry = workbook.getManifest() - .getFileEntry(MindMapImageExporter - .toThumbnailArchivePath(ImageFormat.JPEG)); - } - - if (previewEntry != null) { - return previewEntry.openInputStream(); - } - } - return null; - } - - protected void saveStateForTempStorage(IMemento state, IWorkbook workbook) { - IStorage storage = (IStorage) workbook.getAdapter(IStorage.class); - if (storage == null) - return; - - if (storage instanceof DirectoryStorage) { - String path = ((DirectoryStorage) storage).getFullPath(); - if (path != null) { - state.putString(ATT_TEMP_LOCATION, path); - } - } else if (storage instanceof ByteArrayStorage) { - // TODO save byte array storage state - } - } - - protected IStorage restoreStateForTempStorage(IMemento state) { - String tempLocation = state.getString(ATT_TEMP_LOCATION); - if (tempLocation != null) - return new DirectoryStorage(new File(tempLocation)); - // TODO restore byte array storage state - return null; - } - - protected IPersistable getPersistable() { - return new IPersistable() { - @Override - public void saveState(IMemento memento) { - AbstractWorkbookRef.this.saveState(memento); - } - }; - } - - protected void saveState(IMemento memento) { - if (isInState(CLOSED | CLOSING)) - return; - - IWorkbook workbook = getWorkbook(); - if (workbook != null) { - saveStateForTempStorage(memento, workbook); - } - } - - @Override - public boolean isDirty() { - return super.isDirty() || (workbook instanceof ICoreEventSource2 - && ((ICoreEventSource2) workbook) - .hasOnceListeners(Core.WorkbookPreSaveOnce)); - } - - protected IMindMapPreviewGenerator findPreviewGenerator() { - return getService(IMindMapPreviewGenerator.class); - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.ui.editor.Editable#getService(java.lang.Class) - */ - @Override - protected T getService(Class serviceType) { - T service = super.getService(serviceType); - if (service == null) { - service = defaultEditingContext.getAdapter(serviceType); - } - return service; - } - - protected WorkbookRefEncryptable createEncryptable() { - return new WorkbookRefEncryptable(this); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core. - * runtime.jobs.ISchedulingRule) - */ - @Override - public boolean contains(ISchedulingRule rule) { - return this.equals(rule); - } - - /* - * (non-Javadoc) - * @see - * org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse. - * core.runtime.jobs.ISchedulingRule) - */ - @Override - public boolean isConflicting(ISchedulingRule rule) { - return this.equals(rule); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.ui.editor.Editable#doHandleCommandStackChange(org.xmind.gef - * .command.CommandStackEvent) - */ - @Override - protected void doHandleCommandStackChange(CommandStackEvent event) { - super.doHandleCommandStackChange(event); - if ((event.getStatus() & GEF.CS_POST_MASK) != 0) { - scheduleTempSaving(); - } - } - - protected void scheduleTempSaving() { - final IWorkbook theWorkbook = getWorkbook(); - if (theWorkbook == null) - return; - - final Object subFamily = this; - Job job = new Job("Saving Workbook To Temporary Storage") { //$NON-NLS-1$ - @Override - protected IStatus run(IProgressMonitor monitor) { - if (monitor != null && monitor.isCanceled()) - return Status.CANCEL_STATUS; - - try { - /// use null progress to indicate non-stoppable task - doSaveWorkbookToTempStorage(null, theWorkbook); - } catch (InterruptedException e) { - /// canceled, ignore exception - } catch (InvocationTargetException e) { - return new Status(IStatus.WARNING, - MindMapUIPlugin.PLUGIN_ID, - "Failed to save workbook to temp location", e); //$NON-NLS-1$ - } - return Status.OK_STATUS; - } - - @Override - public boolean belongsTo(Object family) { - if (subFamily.equals(family)) - return true; - - Object jobFamily = getJobFamily(); - return jobFamily != null && jobFamily.equals(family); - } - }; - job.setSystem(true); - job.setRule(this); - - synchronized (tempSavingLock) { - if (tempSavingJob != null) { - tempSavingJob.cancel(); - tempSavingJob = null; - } - tempSavingJob = job; - } - - scheduleTempSavingJob(job); - } - - /** - * @param job - */ - protected void scheduleTempSavingJob(Job job) { - job.schedule(TEMP_SAVING_DELAY); - } - - protected Object getJobFamily() { - return AbstractWorkbookRef.class; - } - - protected void stopTempSaving() { - synchronized (tempSavingLock) { - if (tempSavingJob != null) { - tempSavingJob.cancel(); - tempSavingJob = null; - } - } - Job.getJobManager().cancel(this); - } - - public static void setDefaultEditingContext(IEditingContext context) { - defaultEditingContext = (context == null) ? IEditingContext.NULL - : context; - } - - public void addWorkbookRefListener( - IWorkbookRefListener workbookRefListener) { - workbookRefListeners.add(workbookRefListener); - } - - public void removeWorkbookRefListener( - IWorkbookRefListener workbookRefListener) { - workbookRefListeners.remove(workbookRefListener); - } - - protected void fileChanged(String title, String message, String[] buttons) { - for (IWorkbookRefListener listener : new ArrayList( - workbookRefListeners)) { - listener.fileChanged(title, message, buttons); - } - } - - protected void fileRemoved(String title, String message, String[] buttons, - boolean forceQuit) { - for (IWorkbookRefListener listener : new ArrayList( - workbookRefListeners)) { - listener.fileRemoved(title, message, buttons, forceQuit); - } - } - - @Override - public boolean activateNotifier() { - return false; - } - - public void propertyChange(PropertyChangeEvent event) { - ICommandStack commandStack = getCommandStack(); - if (commandStack != null) { - if (PrefConstants.UNDO_LIMIT.equals(event.getProperty())) { - int num = 0; - try { - num = Integer.parseInt(event.getNewValue().toString()); - } catch (Exception e) { - } - commandStack.setUndoLimit(Math.max(num, 1)); - } - } - } -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistable; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IDeserializer; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.zip.ArchiveConstants; +import org.xmind.core.io.ByteArrayStorage; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IStorage; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.ProgressReporter; +import org.xmind.gef.GEF; +import org.xmind.gef.command.CommandStack; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.ui.editor.Editable; +import org.xmind.gef.ui.editor.IEditingContext; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefListener; +import org.xmind.ui.mindmap.MindMapImageExporter; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.util.ImageFormat; + +/** + * This class implements basic behaviors of {@link IWorkbookRef} by extending + * the {@link Editable} class. + *

    Subclassing Notes

    + *
      + *
    • Each subclass MUST override + * {@link #doLoadWorkbookFromURI(IProgressMonitor, URI) doLoadWorkbookFromURI()} + * , unless it overrides one of {@link #doLoadWorkbook(IProgressMonitor) + * doLoadWorkbook()}, {@link #doOpen(IProgressMonitor) doOpen()} and + * {@link #open(IProgressMonitor) open()} to change the default behavior.
    • + *
    • Each subclass MUST override + * {@link #doSaveWorkbookToURI(IProgressMonitor, IWorkbook, URI) + * doSaveWorkbookToURI()} if it may return true from + * {@link #canSave()}, unless it overrides one of {@link #save(IProgressMonitor) + * save()} and {@link #doSave(IProgressMonitor) doSave()} to change the default + * behavior.
    • + *
    • Each subclass MUST override + * {@link #doImportFrom(IProgressMonitor, IWorkbookRef) doImportFrom()} if it + * may return true from {@link #canImportFrom(IWorkbookRef) + * canImportFrom()}, unless it overrides + * {@link #importFrom(IProgressMonitor, IWorkbookRef) importFrom()} to change + * the default behavior.
    • + *
    + * + * @author Frank Shaka + * @since 3.6.50 + */ +public abstract class AbstractWorkbookRef extends Editable + implements IWorkbookRef, ISchedulingRule, IPropertyChangeListener { + + protected static final int TEMP_SAVING_DELAY = 500; + + protected static final String ATT_TEMP_LOCATION = "tempLocation"; //$NON-NLS-1$ + + private static IEditingContext defaultEditingContext = IEditingContext.NULL; + + private IWorkbook workbook = null; + + private CoreEventRegister globalEventRegister = null; + + private IStorage tempStorage = null; + + private boolean shouldLoadFromTempStorage = false; + + private ICoreEventListener globalEventListener = new ICoreEventListener() { + public void handleCoreEvent(CoreEvent event) { + handleGlobalEvent(event); + } + }; + + private WorkbookRefEncryptable encryptable = null; + + private Job tempSavingJob = null; + private Object tempSavingLock = new Object(); + + private List workbookRefListeners = new ArrayList(); + + protected AbstractWorkbookRef(URI uri, IMemento state) { + super(uri); + + setEncryptable(createEncryptable()); + + setCommandStack(new CommandStack(Math.max(MindMapUIPlugin.getDefault() + .getPreferenceStore().getInt(PrefConstants.UNDO_LIMIT), 1))); + MindMapUIPlugin.getDefault().getPreferenceStore() + .addPropertyChangeListener(this); + + if (state != null) { + IStorage savedTempStorage = restoreStateForTempStorage(state); + this.shouldLoadFromTempStorage = savedTempStorage != null; + setTempStorage(savedTempStorage); + } + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.mindmap.IWorkbookRef#getSaveWizardId() + */ + @Override + public String getSaveWizardId() { + return null; + } + + public IWorkbook getWorkbook() { + return this.workbook; + } + + protected void setWorkbook(IWorkbook workbook) { + IWorkbook oldWorkbook = this.workbook; + if (workbook == oldWorkbook) + return; + + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } + + if (oldWorkbook != null) { + IMarkerSheet markerSheet = oldWorkbook.getMarkerSheet(); + if (markerSheet != null) { + markerSheet.setParentSheet(null); + } + } + + this.workbook = workbook; + + if (workbook != null) { + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (markerSheet != null) { + markerSheet.setParentSheet( + MindMapUI.getResourceManager().getSystemMarkerSheet()); + } + + if (globalEventRegister == null) { + globalEventRegister = new CoreEventRegister( + globalEventListener); + } + registerGlobalEvents(globalEventRegister, workbook); + } + } + + private void registerGlobalEvents(CoreEventRegister register, + IWorkbook workbook) { + ICoreEventSupport support = (ICoreEventSupport) workbook + .getAdapter(ICoreEventSupport.class); + if (support != null) { + register.setNextSupport(support); + + register.register(Core.MarkerRefAdd); + register.register(Core.PasswordChange); + } + } + + private void handleGlobalEvent(CoreEvent event) { + String type = event.getType(); + if (Core.MarkerRefAdd.equals(type)) { + handleMarkerAdded((String) event.getTarget()); + } else if (Core.PasswordChange.equals(type)) { + scheduleTempSaving(); + } + } + + private void handleMarkerAdded(String markerId) { + IMarkerGroup recentMarkerGroup = MindMapUI.getResourceManager() + .getRecentMarkerGroup(); + + IMarkerSheet systemMarkerSheet = MindMapUI.getResourceManager() + .getSystemMarkerSheet(); + IMarker systemMarker = systemMarkerSheet.findMarker(markerId); + if (systemMarker != null) { + IMarkerGroup group = systemMarker.getParent(); + if (group != null) { + if (group.getParent() != null + && group.getParent().equals(systemMarkerSheet)) { + recentMarkerGroup.addMarker(systemMarker); + } + } + } + IMarkerSheet userMarkerSheet = MindMapUI.getResourceManager() + .getUserMarkerSheet(); + IMarker userMarker = userMarkerSheet.findMarker(markerId); + if (userMarker != null) { + IMarkerGroup group = userMarker.getParent(); + if (group != null) { + if (group.getParent() != null + && group.getParent().equals(userMarkerSheet)) { + recentMarkerGroup.addMarker(userMarker); + } + } + } + + } + + @Override + public T getAdapter(Class adapter) { + if (IWorkbook.class.equals(adapter)) + return adapter.cast(getWorkbook()); + if (IPersistable.class.equals(adapter)) + return adapter.cast(getPersistable()); + if (IEncryptable.class.equals(adapter)) + return adapter.cast(encryptable); + return super.getAdapter(adapter); + } + + protected void setEncryptable(WorkbookRefEncryptable encryptable) { + this.encryptable = encryptable; + } + + protected WorkbookRefEncryptable getEncryptable() { + return encryptable; + } + + protected IEntryStreamNormalizer getEncryptionHandler() { + return encryptable != null ? encryptable.getEncryptor() + : IEntryStreamNormalizer.NULL; + } + + @Override + protected void doOpen(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + IWorkbook workbook = doLoadWorkbook(subMonitor.newChild(90)); + Assert.isTrue(workbook != null); + doSaveWorkbookToTempStorage(subMonitor.newChild(10), workbook); + setWorkbook(workbook); + + MindMapUIPlugin.getDefault().getPreferenceStore() + .removePropertyChangeListener(this); + MindMapUIPlugin.getDefault().getPreferenceStore() + .addPropertyChangeListener(this); + } + + protected IWorkbook doLoadWorkbook(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + if (shouldLoadFromTempStorage) { + try { + return doLoadWorkbookFromTempStorage(monitor, getTempStorage()); + } finally { + shouldLoadFromTempStorage = false; + } + } + return doLoadWorkbookFromURI(monitor, getURI()); + } + + protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, + IStorage tempStorage) + throws InterruptedException, InvocationTargetException { + try { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.setWorkbookStorage(tempStorage); + deserializer.setWorkbookStorageAsInputSource(); + deserializer.deserialize(new ProgressReporter(monitor)); + return deserializer.getWorkbook(); + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + if (e.getType() == Core.ERROR_CANCELLATION) + throw new InterruptedException(); + throw new InvocationTargetException(e); + } + } + + /** + * Subclasses MUST override this method. + * + * @param monitor + * @param uri + * @return + * @throws InterruptedException + * @throws InvocationTargetException + */ + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + throw new UnsupportedOperationException(); + } + + @Override + protected void doSave(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + IWorkbook workbook = getWorkbook(); + Assert.isTrue(workbook != null); + URI targetURI = getURI(); + Assert.isTrue(targetURI != null); + + ICoreEventSource workbookAsEventSource; + if (workbook instanceof ICoreEventSource) { + workbookAsEventSource = (ICoreEventSource) workbook; + } else { + workbookAsEventSource = null; + } + + if (workbookAsEventSource != null) { + workbookAsEventSource.getCoreEventSupport().dispatch( + workbookAsEventSource, new CoreEvent(workbookAsEventSource, + Core.WorkbookPreSaveOnce, null)); + workbookAsEventSource.getCoreEventSupport().dispatch( + workbookAsEventSource, new CoreEvent(workbookAsEventSource, + Core.WorkbookPreSave, null)); + } + + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + doSaveWorkbookToTempStorage(subMonitor.newChild(20), workbook); + doSaveWorkbookToURI(subMonitor.newChild(80), workbook, targetURI); + + if (workbookAsEventSource != null) { + workbookAsEventSource.getCoreEventSupport().dispatch( + workbookAsEventSource, new CoreEvent(workbookAsEventSource, + Core.WorkbookSave, null)); + } + } + + /// subclasses may override to prevent default behavior or add custom behaviors + protected void doSaveWorkbookToTempStorage(IProgressMonitor monitor, + IWorkbook workbook) + throws InterruptedException, InvocationTargetException { + try { + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.setEntryStreamNormalizer(getEncryptionHandler()); + serializer.serialize(new ProgressReporter(monitor)); + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + if (e.getType() == Core.ERROR_CANCELLATION) + throw new InterruptedException(); + if (e.getType() == Core.ERROR_WRONG_PASSWORD) { + if (getEncryptable() != null) { + getEncryptable().reset(); + } + } + throw new InvocationTargetException(e); + } + } + + /** + * The default implementation does nothing but throws + * UnsupportedOperationException. Subclasses MUST + * override and MUST NOT call + * super.doSaveWorkbookToURI() if true may be + * returned from {@link #canSave()}. + * + * @see #doSave(IProgressMonitor) + * @param monitor + * the progress monitor to use for reporting progress to the + * user. It is the caller's responsibility to call done() on the + * given monitor. Accepts null, indicating that no progress + * should be reported and that the operation cannot be cancelled. + * @param workbook + * the workbook to save (never null) + * @param uri + * the location to save workbook to (never null) + * @exception InvocationTargetException + * if this method must propagate a checked exception, it + * should wrap it inside an + * InvocationTargetException; runtime exceptions + * are automatically wrapped in an + * InvocationTargetException by the calling + * context + * @exception InterruptedException + * if the operation detects a request to cancel, using + * IProgressMonitor.isCanceled(), it should exit + * by throwing InterruptedException + */ + protected void doSaveWorkbookToURI(IProgressMonitor monitor, + IWorkbook workbook, URI uri) + throws InterruptedException, InvocationTargetException { + throw new UnsupportedOperationException(); + } + + @Override + protected void doClose(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + stopTempSaving(); + + IWorkbook workbook = getWorkbook(); + if (workbook != null) { + doUnloadWorkbook(subMonitor.newChild(30), workbook); + doClearTempStorageOnClose(subMonitor.newChild(60), workbook); + } + + if (encryptable != null) { + encryptable.reset(); + } + + subMonitor.setWorkRemaining(10); + subMonitor.newChild(10); + setWorkbook(null); + + setCommandStack(new CommandStack(Math.max(MindMapUIPlugin.getDefault() + .getPreferenceStore().getInt(PrefConstants.UNDO_LIMIT), 1))); + MindMapUIPlugin.getDefault().getPreferenceStore() + .removePropertyChangeListener(this); + } + + /// subclasses may override to prevent default behavior or add custom behaviors + protected void doUnloadWorkbook(IProgressMonitor monitor, + IWorkbook workbook) + throws InterruptedException, InvocationTargetException { + // do nothing, subclasses may override + } + + /// subclasses may override to prevent default behavior or add custom behaviors + protected void doClearTempStorageOnClose(IProgressMonitor monitor, + IWorkbook workbook) + throws InterruptedException, InvocationTargetException { + IStorage storage = (IStorage) workbook.getAdapter(IStorage.class); + if (storage != null) { + storage.clear(); + } + } + + protected IStorage getTempStorage() { + if (tempStorage == null) { + IWorkbook workbook = getWorkbook(); + if (workbook != null) { + tempStorage = (IStorage) workbook.getAdapter(IStorage.class); + } + if (tempStorage == null) { + tempStorage = createDefaultTempStorage(); + } + } + return this.tempStorage; + } + + protected IStorage createDefaultTempStorage() { + return MME.createTempStorage(); + } + + protected void setTempStorage(IStorage storage) { + this.tempStorage = storage; + } + + @Override + public boolean canImportFrom(IWorkbookRef source) { + return false; + } + + public void importFrom(IProgressMonitor monitor, final IWorkbookRef source) + throws InterruptedException, InvocationTargetException { + if (!canImportFrom(source)) + throw new IllegalArgumentException( + "Can't import from the given workbook ref"); //$NON-NLS-1$ + if (source.isInState(CLOSED)) + throw new IllegalArgumentException( + "The given workbook ref is closed"); //$NON-NLS-1$ + if (!isInState(CLOSED)) + throw new IllegalStateException( + "Import operation is not allowed when workbook ref is already open"); //$NON-NLS-1$ + if (isInState(OPENING | CLOSING | SAVING)) + throw new IllegalStateException( + "Concurrent open/close/save/import operations are not allowed in a workbook ref"); //$NON-NLS-1$ + + try { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + subMonitor.newChild(5); + addState(SAVING); + try { + doImportFrom(subMonitor.newChild(90), source); + } finally { + subMonitor.newChild(5); + removeState(SAVING); + } + } catch (OperationCanceledException e) { + // interpret cancellation + throw new InterruptedException(); + } + } + + protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) + throws InterruptedException, InvocationTargetException { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.mindmap.IWorkbookRef#getPreviewImageData(java.lang.String, + * org.xmind.ui.internal.editor.MindMapPreviewOptions) + */ + @Override + public InputStream getPreviewImageData(String sheetId, + MindMapPreviewOptions options) throws IOException { + if (sheetId == null) + throw new IllegalArgumentException(); + + IWorkbook workbook = getWorkbook(); + + /// check if workbook is encrypted, + /// then no preview image should be available + IFileEntry contentEntry = workbook.getManifest() + .getFileEntry(ArchiveConstants.CONTENT_XML); + if (contentEntry != null && contentEntry.getEncryptionData() != null) + return null; + + if (workbook != null + && sheetId.equals(workbook.getPrimarySheet().getId())) { + IFileEntry previewEntry = workbook.getManifest() + .getFileEntry(MindMapImageExporter + .toThumbnailArchivePath(ImageFormat.PNG)); + if (previewEntry == null) { + previewEntry = workbook.getManifest() + .getFileEntry(MindMapImageExporter + .toThumbnailArchivePath(ImageFormat.JPEG)); + } + + if (previewEntry != null) { + return previewEntry.openInputStream(); + } + } + return null; + } + + protected void saveStateForTempStorage(IMemento state, IWorkbook workbook) { + IStorage storage = (IStorage) workbook.getAdapter(IStorage.class); + if (storage == null) + return; + + if (storage instanceof DirectoryStorage) { + String path = ((DirectoryStorage) storage).getFullPath(); + if (path != null) { + state.putString(ATT_TEMP_LOCATION, path); + } + } else if (storage instanceof ByteArrayStorage) { + // TODO save byte array storage state + } + } + + protected IStorage restoreStateForTempStorage(IMemento state) { + String tempLocation = state.getString(ATT_TEMP_LOCATION); + if (tempLocation != null) + return new DirectoryStorage(new File(tempLocation)); + // TODO restore byte array storage state + return null; + } + + protected IPersistable getPersistable() { + return new IPersistable() { + @Override + public void saveState(IMemento memento) { + AbstractWorkbookRef.this.saveState(memento); + } + }; + } + + protected void saveState(IMemento memento) { + if (isInState(CLOSED | CLOSING)) + return; + + IWorkbook workbook = getWorkbook(); + if (workbook != null) { + saveStateForTempStorage(memento, workbook); + } + } + + @Override + public boolean isDirty() { + return super.isDirty() || (workbook instanceof ICoreEventSource2 + && ((ICoreEventSource2) workbook) + .hasOnceListeners(Core.WorkbookPreSaveOnce)); + } + + protected IMindMapPreviewGenerator findPreviewGenerator() { + return getService(IMindMapPreviewGenerator.class); + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.ui.editor.Editable#getService(java.lang.Class) + */ + @Override + protected T getService(Class serviceType) { + T service = super.getService(serviceType); + if (service == null) { + service = defaultEditingContext.getAdapter(serviceType); + } + return service; + } + + protected WorkbookRefEncryptable createEncryptable() { + return new WorkbookRefEncryptable(this); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core. + * runtime.jobs.ISchedulingRule) + */ + @Override + public boolean contains(ISchedulingRule rule) { + return this.equals(rule); + } + + /* + * (non-Javadoc) + * @see + * org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse. + * core.runtime.jobs.ISchedulingRule) + */ + @Override + public boolean isConflicting(ISchedulingRule rule) { + return this.equals(rule); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.ui.editor.Editable#doHandleCommandStackChange(org.xmind.gef + * .command.CommandStackEvent) + */ + @Override + protected void doHandleCommandStackChange(CommandStackEvent event) { + super.doHandleCommandStackChange(event); + if ((event.getStatus() & GEF.CS_POST_MASK) != 0) { + scheduleTempSaving(); + } + } + + protected void scheduleTempSaving() { + final IWorkbook theWorkbook = getWorkbook(); + if (theWorkbook == null) + return; + + final Object subFamily = this; + Job job = new Job("Saving Workbook To Temporary Storage") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + if (monitor != null && monitor.isCanceled()) + return Status.CANCEL_STATUS; + + try { + /// use null progress to indicate non-stoppable task + doSaveWorkbookToTempStorage(null, theWorkbook); + } catch (InterruptedException e) { + /// canceled, ignore exception + } catch (InvocationTargetException e) { + return new Status(IStatus.WARNING, + MindMapUIPlugin.PLUGIN_ID, + "Failed to save workbook to temp location", e); //$NON-NLS-1$ + } + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + if (subFamily.equals(family)) + return true; + + Object jobFamily = getJobFamily(); + return jobFamily != null && jobFamily.equals(family); + } + }; + job.setSystem(true); + job.setRule(this); + + synchronized (tempSavingLock) { + if (tempSavingJob != null) { + tempSavingJob.cancel(); + tempSavingJob = null; + } + tempSavingJob = job; + } + + scheduleTempSavingJob(job); + } + + /** + * @param job + */ + protected void scheduleTempSavingJob(Job job) { + job.schedule(TEMP_SAVING_DELAY); + } + + protected Object getJobFamily() { + return AbstractWorkbookRef.class; + } + + protected void stopTempSaving() { + synchronized (tempSavingLock) { + if (tempSavingJob != null) { + tempSavingJob.cancel(); + tempSavingJob = null; + } + } + Job.getJobManager().cancel(this); + } + + public static void setDefaultEditingContext(IEditingContext context) { + defaultEditingContext = (context == null) ? IEditingContext.NULL + : context; + } + + public void addWorkbookRefListener( + IWorkbookRefListener workbookRefListener) { + workbookRefListeners.add(workbookRefListener); + } + + public void removeWorkbookRefListener( + IWorkbookRefListener workbookRefListener) { + workbookRefListeners.remove(workbookRefListener); + } + + protected void fileChanged(String title, String message, String[] buttons) { + for (IWorkbookRefListener listener : new ArrayList( + workbookRefListeners)) { + listener.fileChanged(title, message, buttons); + } + } + + protected void fileRemoved(String title, String message, String[] buttons, + boolean forceQuit) { + for (IWorkbookRefListener listener : new ArrayList( + workbookRefListeners)) { + listener.fileRemoved(title, message, buttons, forceQuit); + } + } + + @Override + public boolean activateNotifier() { + return false; + } + + public void propertyChange(PropertyChangeEvent event) { + ICommandStack commandStack = getCommandStack(); + if (commandStack != null) { + if (PrefConstants.UNDO_LIMIT.equals(event.getProperty())) { + int num = 0; + try { + num = Integer.parseInt(event.getNewValue().toString()); + } catch (Exception e) { + } + commandStack.setUndoLimit(Math.max(num, 1)); + } + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AuthorInfoEditor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AuthorInfoEditor.java index 3e28caeaa..2f65ca7c5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AuthorInfoEditor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/AuthorInfoEditor.java @@ -1,80 +1,80 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.texteditor.MEmbeddedEditor; -import org.xmind.ui.viewers.MButton; - -public class AuthorInfoEditor extends MEmbeddedEditor implements Listener { - - private Text input; - - public AuthorInfoEditor(Composite parent) { - super(parent, MButton.NO_ARROWS); - } - - @Override - protected void createEditor(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout gridLayout = new GridLayout(); - gridLayout.marginWidth = 2; - gridLayout.marginHeight = 2; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 3; - composite.setLayout(gridLayout); - - createInput(composite); - } - - private void createInput(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout gridLayout = new GridLayout(); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 2; - composite.setLayout(gridLayout); - - input = new Text(composite, SWT.SINGLE | SWT.BORDER); - input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - input.addListener(SWT.Traverse, this); - input.addListener(SWT.DefaultSelection, this); - input.addListener(SWT.FocusOut, this); - } - - public Text getInput() { - return input; - } - - public void setInput(Text input) { - this.input = input; - } - - @Override - protected void setEditorFocus() { - input.setFocus(); - input.setSelection(input.getText().length(), input.getText().length()); - } - - public void handleEvent(Event event) { - if (event.type == SWT.Traverse) { - if (event.detail == SWT.TRAVERSE_ESCAPE) { - cancelEditing(); - } - } else if (event.type == SWT.DefaultSelection) { - endEditing(); - } else if (event.type == SWT.FocusOut) { - endEditingWhenFocusOut(); - } - } - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.texteditor.MEmbeddedEditor; +import org.xmind.ui.viewers.MButton; + +public class AuthorInfoEditor extends MEmbeddedEditor implements Listener { + + private Text input; + + public AuthorInfoEditor(Composite parent) { + super(parent, MButton.NO_ARROWS); + } + + @Override + protected void createEditor(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = 2; + gridLayout.marginHeight = 2; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 3; + composite.setLayout(gridLayout); + + createInput(composite); + } + + private void createInput(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 2; + composite.setLayout(gridLayout); + + input = new Text(composite, SWT.SINGLE | SWT.BORDER); + input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + input.addListener(SWT.Traverse, this); + input.addListener(SWT.DefaultSelection, this); + input.addListener(SWT.FocusOut, this); + } + + public Text getInput() { + return input; + } + + public void setInput(Text input) { + this.input = input; + } + + @Override + protected void setEditorFocus() { + input.setFocus(); + input.setSelection(input.getText().length(), input.getText().length()); + } + + public void handleEvent(Event event) { + if (event.type == SWT.Traverse) { + if (event.detail == SWT.TRAVERSE_ESCAPE) { + cancelEditing(); + } + } else if (event.type == SWT.DefaultSelection) { + endEditing(); + } else if (event.type == SWT.FocusOut) { + endEditingWhenFocusOut(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/BackgroundSaveWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/BackgroundSaveWorkbook.java index 2904ba21f..d4776ddbd 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/BackgroundSaveWorkbook.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/BackgroundSaveWorkbook.java @@ -1,176 +1,176 @@ -package org.xmind.ui.internal.editor; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -/** - * - * @author Ren Siu - * @since 3.6.50 - */ -public class BackgroundSaveWorkbook { - - private static final BackgroundSaveWorkbook INSTANCE = new BackgroundSaveWorkbook(); - - private static boolean DEBUGGING = MindMapUIPlugin - .isDebugging("/debug/autosave"); //$NON-NLS-1$ - - private static class DaemonJob extends Job { - - private int intervals; - - /** - * @param name - */ - public DaemonJob(int intervals) { - super("Background Save Workbooks Daemon"); //$NON-NLS-1$ - setSystem(true); - setPriority(LONG); - this.intervals = intervals; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. - * IProgressMonitor) - */ - @Override - protected IStatus run(IProgressMonitor monitor) { - monitor.beginTask(null, 1); - try { - do { - IStatus slept = sleep(monitor); - if (slept != null && !slept.isOK()) - return slept; - - if (DEBUGGING) - System.out.println("AutoSave starts now..."); //$NON-NLS-1$ - - IWorkbenchWindow[] windows = PlatformUI.getWorkbench() - .getWorkbenchWindows(); - for (IWorkbenchWindow ww : windows) { - IWorkbenchPage[] pages = ww.getPages(); - for (IWorkbenchPage wp : pages) { - IEditorReference[] ers = wp.getEditorReferences(); - for (IEditorReference er : ers) { - IEditorInput editorInput = er.getEditorInput(); - if (editorInput == null) - continue; - IWorkbookRef workbookRef = editorInput - .getAdapter(IWorkbookRef.class); - save(monitor, workbookRef); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - } - } - } - - if (DEBUGGING) - System.out.println("AutoSave finishes."); //$NON-NLS-1$ - - } while (!monitor.isCanceled()); - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - return Status.OK_STATUS; - } catch (Throwable e) { - if (e instanceof InterruptedException) - return Status.CANCEL_STATUS; - - if (DEBUGGING) { - System.err.println("AutoSave error:"); //$NON-NLS-1$ - e.printStackTrace(); - } - - String msg = "Background workbook saver daemon ended with unknown error"; //$NON-NLS-1$ - Logger.log(e, msg); - return new Status(IStatus.WARNING, MindMapUI.PLUGIN_ID, - IStatus.ERROR, msg, e); - } - } - - private IStatus sleep(IProgressMonitor monitor) { - int total = intervals; - try { - if (DEBUGGING && total > 5000) { - Thread.sleep(total - 5000); - System.out.println("AutoSave will start in 5 seconds..."); //$NON-NLS-1$ - Thread.sleep(3000); - System.out.println("AutoSave will start in 2 seconds..."); //$NON-NLS-1$ - Thread.sleep(2000); - } else { - if (DEBUGGING) - System.out.println("AutoSave will start in " //$NON-NLS-1$ - + (total / 1000) + " seconds..."); //$NON-NLS-1$ - Thread.sleep(total); - } - } catch (InterruptedException e) { - return Status.CANCEL_STATUS; - } - if (monitor.isCanceled()) - return Status.CANCEL_STATUS; - return Status.OK_STATUS; - } - - private void save(IProgressMonitor monitor, IWorkbookRef workbookRef) - throws InterruptedException, InvocationTargetException { - if (workbookRef.canSave() && workbookRef.isDirty()) { - workbookRef.save(monitor); - } - } - - protected void canceling() { - super.canceling(); - Thread t = getThread(); - if (t != null) - t.interrupt(); - } - - } - - private DaemonJob daemon = null; - - public synchronized void reset(int intervals, boolean enabled) { - stopAll(); - if (enabled) { - daemon = new DaemonJob(intervals); - daemon.schedule(); - } - } - - public synchronized boolean isRunning() { - return daemon != null; - } - - /** - * - */ - public synchronized void stopAll() { - if (daemon != null) { - Thread thread = daemon.getThread(); - daemon.cancel(); - if (thread != null) { - thread.interrupt(); - } - daemon = null; - } - } - - public static BackgroundSaveWorkbook getInstance() { - return INSTANCE; - } - -} +package org.xmind.ui.internal.editor; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +/** + * + * @author Ren Siu + * @since 3.6.50 + */ +public class BackgroundSaveWorkbook { + + private static final BackgroundSaveWorkbook INSTANCE = new BackgroundSaveWorkbook(); + + private static boolean DEBUGGING = MindMapUIPlugin + .isDebugging("/debug/autosave"); //$NON-NLS-1$ + + private static class DaemonJob extends Job { + + private int intervals; + + /** + * @param name + */ + public DaemonJob(int intervals) { + super("Background Save Workbooks Daemon"); //$NON-NLS-1$ + setSystem(true); + setPriority(LONG); + this.intervals = intervals; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. + * IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(null, 1); + try { + do { + IStatus slept = sleep(monitor); + if (slept != null && !slept.isOK()) + return slept; + + if (DEBUGGING) + System.out.println("AutoSave starts now..."); //$NON-NLS-1$ + + IWorkbenchWindow[] windows = PlatformUI.getWorkbench() + .getWorkbenchWindows(); + for (IWorkbenchWindow ww : windows) { + IWorkbenchPage[] pages = ww.getPages(); + for (IWorkbenchPage wp : pages) { + IEditorReference[] ers = wp.getEditorReferences(); + for (IEditorReference er : ers) { + IEditorInput editorInput = er.getEditorInput(); + if (editorInput == null) + continue; + IWorkbookRef workbookRef = editorInput + .getAdapter(IWorkbookRef.class); + save(monitor, workbookRef); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + } + } + } + + if (DEBUGGING) + System.out.println("AutoSave finishes."); //$NON-NLS-1$ + + } while (!monitor.isCanceled()); + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + return Status.OK_STATUS; + } catch (Throwable e) { + if (e instanceof InterruptedException) + return Status.CANCEL_STATUS; + + if (DEBUGGING) { + System.err.println("AutoSave error:"); //$NON-NLS-1$ + e.printStackTrace(); + } + + String msg = "Background workbook saver daemon ended with unknown error"; //$NON-NLS-1$ + Logger.log(e, msg); + return new Status(IStatus.WARNING, MindMapUI.PLUGIN_ID, + IStatus.ERROR, msg, e); + } + } + + private IStatus sleep(IProgressMonitor monitor) { + int total = intervals; + try { + if (DEBUGGING && total > 5000) { + Thread.sleep(total - 5000); + System.out.println("AutoSave will start in 5 seconds..."); //$NON-NLS-1$ + Thread.sleep(3000); + System.out.println("AutoSave will start in 2 seconds..."); //$NON-NLS-1$ + Thread.sleep(2000); + } else { + if (DEBUGGING) + System.out.println("AutoSave will start in " //$NON-NLS-1$ + + (total / 1000) + " seconds..."); //$NON-NLS-1$ + Thread.sleep(total); + } + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } + if (monitor.isCanceled()) + return Status.CANCEL_STATUS; + return Status.OK_STATUS; + } + + private void save(IProgressMonitor monitor, IWorkbookRef workbookRef) + throws InterruptedException, InvocationTargetException { + if (workbookRef.canSave() && workbookRef.isDirty()) { + workbookRef.save(monitor); + } + } + + protected void canceling() { + super.canceling(); + Thread t = getThread(); + if (t != null) + t.interrupt(); + } + + } + + private DaemonJob daemon = null; + + public synchronized void reset(int intervals, boolean enabled) { + stopAll(); + if (enabled) { + daemon = new DaemonJob(intervals); + daemon.schedule(); + } + } + + public synchronized boolean isRunning() { + return daemon != null; + } + + /** + * + */ + public synchronized void stopAll() { + if (daemon != null) { + Thread thread = daemon.getThread(); + daemon.cancel(); + if (thread != null) { + thread.interrupt(); + } + daemon = null; + } + } + + public static BackgroundSaveWorkbook getInstance() { + return INSTANCE; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ClonedWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ClonedWorkbookRef.java index d24ea9cd8..552adf553 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ClonedWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ClonedWorkbookRef.java @@ -1,127 +1,127 @@ -package org.xmind.ui.internal.editor; - -import static org.xmind.ui.internal.editor.TempWorkbookRefFactory.URI_SCHEME; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.ui.IMemento; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.util.CloneHandler; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IWorkbookRef; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class ClonedWorkbookRef extends AbstractWorkbookRef { - - protected static final String URI_PATH = "/clone"; //$NON-NLS-1$ - private static final String PARAM_SOURCE_URI = "sourceURI"; //$NON-NLS-1$ - - private ClonedWorkbookRef(URI uri, IMemento state) { - super(uri, state); - } - - public URI getSourceWorkbookURI() { - return getSourceWorkbookURI(getURI()); - } - - private static URI getSourceWorkbookURI(URI uri) { - String sourceURIString = URIParser.getQueryParameter(uri, - PARAM_SOURCE_URI); - return URI.create(sourceURIString); - } - - @Override - public String getName() { - String path = getSourceWorkbookURI().getPath(); - int suffixIndex = path.lastIndexOf("."); //$NON-NLS-1$ - if (suffixIndex > 0) { - path = path.substring(0, suffixIndex); - } - int nameIndex = path.lastIndexOf("/"); //$NON-NLS-1$ - if (nameIndex > 0 && nameIndex < path.length() - 1) { - path = path.substring(nameIndex + 1); - } - return path; - } - - @Override - public String getDescription() { - return getName(); - } - - @Override - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - subMonitor.newChild(5); - URI sourceWorkbookURI = getSourceWorkbookURI(uri); - IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory() - .createWorkbookRef(sourceWorkbookURI, null); - Assert.isTrue(sourceWorkbookRef != null); - if (monitor.isCanceled()) - throw new InterruptedException(); - - sourceWorkbookRef.open(subMonitor.newChild(20)); - try { - IWorkbook sourceWorkbook = sourceWorkbookRef.getWorkbook(); - Assert.isTrue(sourceWorkbook != null); - return doCloneWorkbook(subMonitor.newChild(70), sourceWorkbook); - } finally { - subMonitor.setWorkRemaining(5); - sourceWorkbookRef.close(subMonitor.newChild(5)); - } - } - - private IWorkbook doCloneWorkbook(IProgressMonitor monitor, - IWorkbook sourceWorkbook) - throws InterruptedException, InvocationTargetException { - try { - IWorkbook workbook = Core.getWorkbookBuilder() - .createWorkbook(getTempStorage()); - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.setEntryStreamNormalizer(getEncryptionHandler()); - serializer.serialize(null); - - new CloneHandler().withWorkbooks(sourceWorkbook, workbook) - .copyWorkbookContents(); - - return workbook; - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - } - - public static IWorkbookRef create(URI uri, IMemento state) { - Assert.isNotNull(uri); - Assert.isLegal(URI_SCHEME.equals(uri.getScheme())); - Assert.isLegal(URI_PATH.equals(uri.getPath())); - return new ClonedWorkbookRef(uri, state); - } - - public static IWorkbookRef createFromSourceWorkbookURI( - URI sourceWorkbookURI) { - Assert.isNotNull(sourceWorkbookURI); - URI uri = URI.create(URI_SCHEME + ":" + URI_PATH); //$NON-NLS-1$ - uri = URIParser.appendQueryParameter(uri, PARAM_SOURCE_URI, - sourceWorkbookURI.toString()); - return new ClonedWorkbookRef(uri, null); - } - -} +package org.xmind.ui.internal.editor; + +import static org.xmind.ui.internal.editor.TempWorkbookRefFactory.URI_SCHEME; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.ui.IMemento; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.util.CloneHandler; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IWorkbookRef; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class ClonedWorkbookRef extends AbstractWorkbookRef { + + protected static final String URI_PATH = "/clone"; //$NON-NLS-1$ + private static final String PARAM_SOURCE_URI = "sourceURI"; //$NON-NLS-1$ + + private ClonedWorkbookRef(URI uri, IMemento state) { + super(uri, state); + } + + public URI getSourceWorkbookURI() { + return getSourceWorkbookURI(getURI()); + } + + private static URI getSourceWorkbookURI(URI uri) { + String sourceURIString = URIParser.getQueryParameter(uri, + PARAM_SOURCE_URI); + return URI.create(sourceURIString); + } + + @Override + public String getName() { + String path = getSourceWorkbookURI().getPath(); + int suffixIndex = path.lastIndexOf("."); //$NON-NLS-1$ + if (suffixIndex > 0) { + path = path.substring(0, suffixIndex); + } + int nameIndex = path.lastIndexOf("/"); //$NON-NLS-1$ + if (nameIndex > 0 && nameIndex < path.length() - 1) { + path = path.substring(nameIndex + 1); + } + return path; + } + + @Override + public String getDescription() { + return getName(); + } + + @Override + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + subMonitor.newChild(5); + URI sourceWorkbookURI = getSourceWorkbookURI(uri); + IWorkbookRef sourceWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(sourceWorkbookURI, null); + Assert.isTrue(sourceWorkbookRef != null); + if (monitor.isCanceled()) + throw new InterruptedException(); + + sourceWorkbookRef.open(subMonitor.newChild(20)); + try { + IWorkbook sourceWorkbook = sourceWorkbookRef.getWorkbook(); + Assert.isTrue(sourceWorkbook != null); + return doCloneWorkbook(subMonitor.newChild(70), sourceWorkbook); + } finally { + subMonitor.setWorkRemaining(5); + sourceWorkbookRef.close(subMonitor.newChild(5)); + } + } + + private IWorkbook doCloneWorkbook(IProgressMonitor monitor, + IWorkbook sourceWorkbook) + throws InterruptedException, InvocationTargetException { + try { + IWorkbook workbook = Core.getWorkbookBuilder() + .createWorkbook(getTempStorage()); + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.setEntryStreamNormalizer(getEncryptionHandler()); + serializer.serialize(null); + + new CloneHandler().withWorkbooks(sourceWorkbook, workbook) + .copyWorkbookContents(); + + return workbook; + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } + } + + public static IWorkbookRef create(URI uri, IMemento state) { + Assert.isNotNull(uri); + Assert.isLegal(URI_SCHEME.equals(uri.getScheme())); + Assert.isLegal(URI_PATH.equals(uri.getPath())); + return new ClonedWorkbookRef(uri, state); + } + + public static IWorkbookRef createFromSourceWorkbookURI( + URI sourceWorkbookURI) { + Assert.isNotNull(sourceWorkbookURI); + URI uri = URI.create(URI_SCHEME + ":" + URI_PATH); //$NON-NLS-1$ + uri = URIParser.appendQueryParameter(uri, PARAM_SOURCE_URI, + sourceWorkbookURI.toString()); + return new ClonedWorkbookRef(uri, null); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/CreatedWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/CreatedWorkbookRef.java index f201f985a..108f68bbb 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/CreatedWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/CreatedWorkbookRef.java @@ -1,103 +1,103 @@ -package org.xmind.ui.internal.editor; - -import static org.xmind.ui.internal.editor.TempWorkbookRefFactory.URI_SCHEME; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.Iterator; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ui.IMemento; -import org.xmind.core.Core; -import org.xmind.core.IWorkbook; -import org.xmind.core.style.IStyle; -import org.xmind.ui.internal.editor.URIParser.QueryParameter; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.mindmap.WorkbookInitializer; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class CreatedWorkbookRef extends AbstractWorkbookRef { - - protected static final String URI_PATH = "/create"; //$NON-NLS-1$ - private static final String PARAM_NAME = "name"; //$NON-NLS-1$ - private static final String PARAM_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ - private static final String PARAM_THEME_URI = "themeURI"; //$NON-NLS-1$ - - private CreatedWorkbookRef(URI uri, IMemento state) { - super(uri, state); - } - - @Override - public String getName() { - String name = URIParser.getQueryParameter(getURI(), PARAM_NAME); - if (name != null) - return name; - - return null; - } - - @Override - public String getDescription() { - return getName(); - } - - @Override - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - IWorkbook workbook = Core.getWorkbookBuilder() - .createWorkbook(getTempStorage()); - toInitializer(getURI()).initWorkbook(workbook); - return workbook; - } - - private static WorkbookInitializer toInitializer(URI uri) { - WorkbookInitializer initializer = WorkbookInitializer.getDefault(); - Iterator it = URIParser.iterateQueryParameters(uri); - while (it.hasNext()) { - QueryParameter p = it.next(); - if (PARAM_STRUCTURE_CLASS.equals(p.name)) { - initializer = initializer.withStructureClass(p.value); - } else if (PARAM_THEME_URI.equals(p.name)) { - Object theme = MindMapUI.getResourceManager() - .findResource(p.value); - if (theme != null && theme instanceof IStyle) { - initializer = initializer.withTheme((IStyle) theme); - } - } - } - return initializer; - } - - public static IWorkbookRef create(URI uri, IMemento state) { - Assert.isNotNull(uri); - Assert.isLegal(URI_SCHEME.equals(uri.getScheme())); - Assert.isLegal(URI_PATH.equals(uri.getPath())); - return new CreatedWorkbookRef(uri, state); - } - - public static IWorkbookRef createFromWorkbookInitializer( - WorkbookInitializer initializer, String name) { - Assert.isNotNull(initializer); - URI uri = URI.create(URI_SCHEME + ":" + URI_PATH); //$NON-NLS-1$ - if (name != null) { - uri = URIParser.appendQueryParameter(uri, PARAM_NAME, name); - } - if (initializer.getStructureClass() != null) { - uri = URIParser.appendQueryParameter(uri, PARAM_STRUCTURE_CLASS, - initializer.getStructureClass()); - } - if (initializer.getTheme() != null) { - uri = URIParser.appendQueryParameter(uri, PARAM_THEME_URI, - MindMapUI.getResourceManager() - .toResourceURI(initializer.getTheme())); - } - return new CreatedWorkbookRef(uri, null); - } - +package org.xmind.ui.internal.editor; + +import static org.xmind.ui.internal.editor.TempWorkbookRefFactory.URI_SCHEME; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.Iterator; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IMemento; +import org.xmind.core.Core; +import org.xmind.core.IWorkbook; +import org.xmind.core.style.IStyle; +import org.xmind.ui.internal.editor.URIParser.QueryParameter; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.mindmap.WorkbookInitializer; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class CreatedWorkbookRef extends AbstractWorkbookRef { + + protected static final String URI_PATH = "/create"; //$NON-NLS-1$ + private static final String PARAM_NAME = "name"; //$NON-NLS-1$ + private static final String PARAM_STRUCTURE_CLASS = "structureClass"; //$NON-NLS-1$ + private static final String PARAM_THEME_URI = "themeURI"; //$NON-NLS-1$ + + private CreatedWorkbookRef(URI uri, IMemento state) { + super(uri, state); + } + + @Override + public String getName() { + String name = URIParser.getQueryParameter(getURI(), PARAM_NAME); + if (name != null) + return name; + + return null; + } + + @Override + public String getDescription() { + return getName(); + } + + @Override + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + IWorkbook workbook = Core.getWorkbookBuilder() + .createWorkbook(getTempStorage()); + toInitializer(getURI()).initWorkbook(workbook); + return workbook; + } + + private static WorkbookInitializer toInitializer(URI uri) { + WorkbookInitializer initializer = WorkbookInitializer.getDefault(); + Iterator it = URIParser.iterateQueryParameters(uri); + while (it.hasNext()) { + QueryParameter p = it.next(); + if (PARAM_STRUCTURE_CLASS.equals(p.name)) { + initializer = initializer.withStructureClass(p.value); + } else if (PARAM_THEME_URI.equals(p.name)) { + Object theme = MindMapUI.getResourceManager() + .findResource(p.value); + if (theme != null && theme instanceof IStyle) { + initializer = initializer.withTheme((IStyle) theme); + } + } + } + return initializer; + } + + public static IWorkbookRef create(URI uri, IMemento state) { + Assert.isNotNull(uri); + Assert.isLegal(URI_SCHEME.equals(uri.getScheme())); + Assert.isLegal(URI_PATH.equals(uri.getPath())); + return new CreatedWorkbookRef(uri, state); + } + + public static IWorkbookRef createFromWorkbookInitializer( + WorkbookInitializer initializer, String name) { + Assert.isNotNull(initializer); + URI uri = URI.create(URI_SCHEME + ":" + URI_PATH); //$NON-NLS-1$ + if (name != null) { + uri = URIParser.appendQueryParameter(uri, PARAM_NAME, name); + } + if (initializer.getStructureClass() != null) { + uri = URIParser.appendQueryParameter(uri, PARAM_STRUCTURE_CLASS, + initializer.getStructureClass()); + } + if (initializer.getTheme() != null) { + uri = URIParser.appendQueryParameter(uri, PARAM_THEME_URI, + MindMapUI.getResourceManager() + .toResourceURI(initializer.getTheme())); + } + return new CreatedWorkbookRef(uri, null); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialog.java index 5adcc85a2..fe8583cff 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialog.java @@ -1,235 +1,241 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.internal.MindMapMessages; - -public class DecryptionDialog extends TitleAreaDialog { - - private String workbookName; - - private String hintMessage; - - private int times; - - private Text passwordInputBox; - - private String password; - - public DecryptionDialog(Shell parent) { - super(parent); - } - - public DecryptionDialog(Shell parent, String workbookName, - String hintMessage) { - this(parent); - this.workbookName = workbookName; - this.hintMessage = hintMessage; - } - - public DecryptionDialog(Shell parent, String workbookMessage, - String hintMessage, int times) { - this(parent, workbookMessage, hintMessage); - this.times = times; - } - - @Override - public void create() { - super.create(); - - setTitle(MindMapMessages.DecryptionDialog_title); - - setTitleImage(null); - - setMessage(MindMapMessages.DecryptionDialog_message); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setFont(parent.getFont()); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 20; - gridLayout.marginHeight = 20; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createContentArea(composite); - - checkOkButton(); - - return composite; - } - - private void createContentArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - area.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - area.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 5; - gridLayout.horizontalSpacing = 3; - area.setLayout(gridLayout); - - createFileNamePart(area); - createPasswordPart(area); - - if ("".equals(hintMessage)) //$NON-NLS-1$ - hintMessage = null; - if ((times > 0 && times < 4) || (times >= 4 && hintMessage == null)) - createErrorMessagePart(area); - - if (times >= 4 && hintMessage != null) - createHintMessagePart(area); - } - - private void createFileNamePart(Composite area) { - Label label = new Label(area, SWT.NONE); - label.setText(MindMapMessages.DecryptionDialog_FileName_label); - label.setLayoutData( - new GridData(SWT.CLIP_CHILDREN, SWT.CENTER, false, false)); - - Label fileName = new Label(area, SWT.NONE); - fileName.setText(workbookName == null - ? MindMapMessages.DecryptionDialog_FileName_untitled - : workbookName); - } - - private void createPasswordPart(Composite area) { - Label label = new Label(area, SWT.NONE); - label.setText(MindMapMessages.DecryptionDialog_Password_label); - label.setLayoutData( - new GridData(SWT.CLIP_CHILDREN, SWT.CENTER, false, false)); - - createPasswordInputBox(area); - } - - private void createErrorMessagePart(Composite area) { - new Label(area, SWT.NONE); - - Label warningLabel = new Label(area, SWT.NONE); - warningLabel - .setText(MindMapMessages.DecryptionDialog_WarningLabel_text); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = 320; - gridData.heightHint = SWT.DEFAULT; - warningLabel.setLayoutData(gridData); - warningLabel.setForeground( - Display.getCurrent().getSystemColor(SWT.COLOR_RED)); - } - - private void createHintMessagePart(Composite parent) { - new Label(parent, SWT.NONE); - - Composite composite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); - GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); - - Label hintLabel = new Label(composite, SWT.NONE); - hintLabel.setText(MindMapMessages.DecryptionDialog_Hint_label); - GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL) - .applyTo(hintLabel); - - Label hintMessageLabel = new Label(composite, SWT.WRAP); - hintMessageLabel.setText(hintMessage); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = 320; - gridData.heightHint = SWT.DEFAULT; - hintMessageLabel.setLayoutData(gridData); - } - - protected void createButtonsForButtonBar(Composite buttonBar) { - createOkButton(buttonBar); - createCloseButton(buttonBar); - } - - private void createOkButton(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, - true); - setOkButtonEnabled(false); - } - - private void createCloseButton(Composite parent) { - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - } - - private void createPasswordInputBox(Composite parent) { - passwordInputBox = new Text(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.minimumWidth = 320; - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - passwordInputBox.setLayoutData(gridData); - - hookText(passwordInputBox); - - Listener inputChangedListener = new Listener() { - public void handleEvent(Event event) { - checkOkButton(); - } - }; - passwordInputBox.addListener(SWT.Modify, inputChangedListener); - } - - protected void okPressed() { - this.password = passwordInputBox.getText(); - setReturnCode(OK); - close(); - } - - private void hookText(final Text text) { - text.addListener(SWT.FocusIn, new Listener() { - public void handleEvent(Event event) { - text.selectAll(); - } - }); - } - - protected String getPassword() { - return password; - } - - private void checkOkButton() { - setOkButtonEnabled(passwordInputBox != null - && !"".equals(passwordInputBox.getText())); //$NON-NLS-1$ - } - - private void setOkButtonEnabled(boolean enabled) { - Button button = getButton(IDialogConstants.OK_ID); - if (button != null && !button.isDisposed()) - button.setEnabled(enabled); - } - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; + +public class DecryptionDialog extends TitleAreaDialog { + + private static final String GET_PASSWORD_HINT_COUNT = "ShowPasswordHintCount"; //$NON-NLS-1$ + + private String workbookName; + + private String hintMessage; + + private int times; + + private Text passwordInputBox; + + private String password; + + public DecryptionDialog(Shell parent) { + super(parent); + } + + public DecryptionDialog(Shell parent, String workbookName, + String hintMessage) { + this(parent); + this.workbookName = workbookName; + this.hintMessage = hintMessage; + } + + public DecryptionDialog(Shell parent, String workbookMessage, + String hintMessage, int times) { + this(parent, workbookMessage, hintMessage); + this.times = times; + } + + @Override + public void create() { + super.create(); + + setTitle(MindMapMessages.DecryptionDialog_title); + + setTitleImage(null); + + setMessage(MindMapMessages.DecryptionDialog_message); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setFont(parent.getFont()); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 20; + gridLayout.marginHeight = 20; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createContentArea(composite); + + checkOkButton(); + + return composite; + } + + private void createContentArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + area.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + area.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 5; + gridLayout.horizontalSpacing = 3; + area.setLayout(gridLayout); + + createFileNamePart(area); + createPasswordPart(area); + + if ("".equals(hintMessage)) //$NON-NLS-1$ + hintMessage = null; + if ((times > 0 && times < 4) || (times >= 4 && hintMessage == null)) + createErrorMessagePart(area); + + if (times >= 4 && hintMessage != null) + createHintMessagePart(area); + } + + private void createFileNamePart(Composite area) { + Label label = new Label(area, SWT.NONE); + label.setText(MindMapMessages.DecryptionDialog_FileName_label); + label.setLayoutData( + new GridData(SWT.CLIP_CHILDREN, SWT.CENTER, false, false)); + + Label fileName = new Label(area, SWT.NONE); + fileName.setText(workbookName == null + ? MindMapMessages.DecryptionDialog_FileName_untitled + : workbookName); + } + + private void createPasswordPart(Composite area) { + Label label = new Label(area, SWT.NONE); + label.setText(MindMapMessages.DecryptionDialog_Password_label); + label.setLayoutData( + new GridData(SWT.CLIP_CHILDREN, SWT.CENTER, false, false)); + + createPasswordInputBox(area); + } + + private void createErrorMessagePart(Composite area) { + new Label(area, SWT.NONE); + + Label warningLabel = new Label(area, SWT.NONE); + warningLabel + .setText(MindMapMessages.DecryptionDialog_WarningLabel_text); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = 320; + gridData.heightHint = SWT.DEFAULT; + warningLabel.setLayoutData(gridData); + warningLabel.setForeground( + Display.getCurrent().getSystemColor(SWT.COLOR_RED)); + } + + private void createHintMessagePart(Composite parent) { + new Label(parent, SWT.NONE); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + + Label hintLabel = new Label(composite, SWT.NONE); + hintLabel.setText(MindMapMessages.DecryptionDialog_Hint_label); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(GET_PASSWORD_HINT_COUNT); + + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL) + .applyTo(hintLabel); + + Label hintMessageLabel = new Label(composite, SWT.WRAP); + hintMessageLabel.setText(hintMessage); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = 320; + gridData.heightHint = SWT.DEFAULT; + hintMessageLabel.setLayoutData(gridData); + } + + protected void createButtonsForButtonBar(Composite buttonBar) { + createOkButton(buttonBar); + createCloseButton(buttonBar); + } + + private void createOkButton(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true); + setOkButtonEnabled(false); + } + + private void createCloseButton(Composite parent) { + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + private void createPasswordInputBox(Composite parent) { + passwordInputBox = new Text(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.minimumWidth = 320; + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + passwordInputBox.setLayoutData(gridData); + + hookText(passwordInputBox); + + Listener inputChangedListener = new Listener() { + public void handleEvent(Event event) { + checkOkButton(); + } + }; + passwordInputBox.addListener(SWT.Modify, inputChangedListener); + } + + protected void okPressed() { + this.password = passwordInputBox.getText(); + setReturnCode(OK); + close(); + } + + private void hookText(final Text text) { + text.addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) { + text.selectAll(); + } + }); + } + + protected String getPassword() { + return password; + } + + private void checkOkButton() { + setOkButtonEnabled(passwordInputBox != null + && !"".equals(passwordInputBox.getText())); //$NON-NLS-1$ + } + + private void setOkButtonEnabled(boolean enabled) { + Button button = getButton(IDialogConstants.OK_ID); + if (button != null && !button.isDisposed()) + button.setEnabled(enabled); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialogPane.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialogPane.java index 2f62e6391..b00201064 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialogPane.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialogPane.java @@ -1,192 +1,192 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -public class DecryptionDialogPane extends DialogPane { - - private Text messageBoard; - - private Text passwordInputBox; - - private Label iconLabel; - - private String password; - - private String message = null; - - private boolean errorOccurred = false; - - @Override - protected Control createDialogContents(Composite parent) { - Composite composite = (Composite) super.createDialogContents(parent); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createMessageArea(composite); - createPasswordInputBox(composite); - return composite; - } - - protected void createButtonsForButtonBar(Composite buttonBar) { - createOkButton(buttonBar); - createCloseButton(buttonBar); - } - - private void createOkButton(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, - true); - } - - private void createCloseButton(Composite parent) { - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - } - - private void createPasswordInputBox(Composite parent) { - passwordInputBox = new Text(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); - applyFont(passwordInputBox); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - passwordInputBox.setLayoutData(gridData); - - hookText(passwordInputBox); - addRefreshDefaultButtonListener(passwordInputBox); - addTriggerDefaultButtonListener(passwordInputBox, SWT.DefaultSelection); - } - - private void createMessageArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - area.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - area.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 10; - area.setLayout(gridLayout); - - createIcon(area); - createMessageBoard(area); - } - - private void createIcon(Composite parent) { - iconLabel = new Label(parent, SWT.NONE); - iconLabel.setBackground(parent.getBackground()); - iconLabel.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - iconLabel.setImage(getImage(iconLabel)); - } - - private Image getImage(Control control) { - if (errorOccurred) - return control.getDisplay().getSystemImage(SWT.ICON_ERROR); - - ImageDescriptor image = MindMapUI.getImages().get(IMindMapImages.UNLOCK, - true); - if (image != null) - return image.createImage(control.getDisplay()); - return null; - } - - private void createMessageBoard(Composite parent) { - messageBoard = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); - messageBoard.setBackground(parent.getBackground()); - applyFont(messageBoard); - - GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - messageBoard.setLayoutData(gridData); - if (message != null) { - messageBoard.setText(message); - } - } - - @Override - protected boolean cancelPressed() { - setReturnCode(CANCEL); - close(); - return true; - } - - protected boolean okPressed() { - this.password = passwordInputBox.getText(); - setReturnCode(OK); - close(); - return true; - } - - public void dispose() { - super.dispose(); - passwordInputBox = null; - messageBoard = null; - } - - public void setFocus() { - if (passwordInputBox != null && !passwordInputBox.isDisposed()) { - passwordInputBox.setFocus(); - } - } - - public void setContent(String message, boolean errorOrWarning) { - this.message = message; - this.errorOccurred = errorOrWarning; - if (messageBoard != null && !messageBoard.isDisposed()) { - messageBoard.setText(message); - } - if (iconLabel != null && !iconLabel.isDisposed()) { - iconLabel.setImage(getImage(iconLabel)); - } - relayout(); - } - - @Override - protected void escapeKeyPressed() { - triggerButton(IDialogConstants.CLOSE_ID); - } - - /** - * @return the password - */ - public String getPassword() { - return password; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +public class DecryptionDialogPane extends DialogPane { + + private Text messageBoard; + + private Text passwordInputBox; + + private Label iconLabel; + + private String password; + + private String message = null; + + private boolean errorOccurred = false; + + @Override + protected Control createDialogContents(Composite parent) { + Composite composite = (Composite) super.createDialogContents(parent); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createMessageArea(composite); + createPasswordInputBox(composite); + return composite; + } + + protected void createButtonsForButtonBar(Composite buttonBar) { + createOkButton(buttonBar); + createCloseButton(buttonBar); + } + + private void createOkButton(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true); + } + + private void createCloseButton(Composite parent) { + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + private void createPasswordInputBox(Composite parent) { + passwordInputBox = new Text(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); + applyFont(passwordInputBox); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + passwordInputBox.setLayoutData(gridData); + + hookText(passwordInputBox); + addRefreshDefaultButtonListener(passwordInputBox); + addTriggerDefaultButtonListener(passwordInputBox, SWT.DefaultSelection); + } + + private void createMessageArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + area.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + area.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 10; + area.setLayout(gridLayout); + + createIcon(area); + createMessageBoard(area); + } + + private void createIcon(Composite parent) { + iconLabel = new Label(parent, SWT.NONE); + iconLabel.setBackground(parent.getBackground()); + iconLabel.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + iconLabel.setImage(getImage(iconLabel)); + } + + private Image getImage(Control control) { + if (errorOccurred) + return control.getDisplay().getSystemImage(SWT.ICON_ERROR); + + ImageDescriptor image = MindMapUI.getImages().get(IMindMapImages.UNLOCK, + true); + if (image != null) + return image.createImage(control.getDisplay()); + return null; + } + + private void createMessageBoard(Composite parent) { + messageBoard = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); + messageBoard.setBackground(parent.getBackground()); + applyFont(messageBoard); + + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + messageBoard.setLayoutData(gridData); + if (message != null) { + messageBoard.setText(message); + } + } + + @Override + protected boolean cancelPressed() { + setReturnCode(CANCEL); + close(); + return true; + } + + protected boolean okPressed() { + this.password = passwordInputBox.getText(); + setReturnCode(OK); + close(); + return true; + } + + public void dispose() { + super.dispose(); + passwordInputBox = null; + messageBoard = null; + } + + public void setFocus() { + if (passwordInputBox != null && !passwordInputBox.isDisposed()) { + passwordInputBox.setFocus(); + } + } + + public void setContent(String message, boolean errorOrWarning) { + this.message = message; + this.errorOccurred = errorOrWarning; + if (messageBoard != null && !messageBoard.isDisposed()) { + messageBoard.setText(message); + } + if (iconLabel != null && !iconLabel.isDisposed()) { + iconLabel.setImage(getImage(iconLabel)); + } + relayout(); + } + + @Override + protected void escapeKeyPressed() { + triggerButton(IDialogConstants.CLOSE_ID); + } + + /** + * @return the password + */ + public String getPassword() { + return password; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultEditorLayout.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultEditorLayout.java index c52152658..ff06b5819 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultEditorLayout.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultEditorLayout.java @@ -1,40 +1,40 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; - -/** - * @author Jason Wong - */ -public class DefaultEditorLayout implements IEditorLayout { - - private Layout layout; - - public DefaultEditorLayout() { - } - - @Override - public void activate(Composite parent) { - layout = new FillLayout(); - parent.setLayout(layout); - - Control[] cs = parent.getChildren(); - if (cs.length > 0) { - Control editorContainer = cs[0]; - editorContainer.setVisible(true); - editorContainer.setLayoutData(null); - } - } - - @Override - public void deactivate(Composite parent) { - } - - @Override - public Layout getSWTLayout() { - return layout; - } - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; + +/** + * @author Jason Wong + */ +public class DefaultEditorLayout implements IEditorLayout { + + private Layout layout; + + public DefaultEditorLayout() { + } + + @Override + public void activate(Composite parent) { + layout = new FillLayout(); + parent.setLayout(layout); + + Control[] cs = parent.getChildren(); + if (cs.length > 0) { + Control editorContainer = cs[0]; + editorContainer.setVisible(true); + editorContainer.setLayoutData(null); + } + } + + @Override + public void deactivate(Composite parent) { + } + + @Override + public Layout getSWTLayout() { + return layout; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultMindMapPreviewGenerator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultMindMapPreviewGenerator.java index 30a380071..7702b119c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultMindMapPreviewGenerator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultMindMapPreviewGenerator.java @@ -1,101 +1,101 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.util.Properties; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.internal.util.BundleUtility; -import org.xmind.core.ISheet; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.image.ResizeConstants; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMap; -import org.xmind.ui.mindmap.MindMapImageExporter; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class DefaultMindMapPreviewGenerator - implements IMindMapPreviewGenerator { - - private final Display display; - - /** - * - */ - public DefaultMindMapPreviewGenerator(Display display) { - this.display = display; - } - - @Override - public Properties generateMindMapPreview(final IWorkbookRef workbookRef, - final ISheet sheet, final OutputStream output, - final MindMapPreviewOptions options) throws IOException { - Assert.isLegal(output != null); - - final Properties properties = new Properties(); - if (sheet == null || MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.PREVIEW_SKIPPED)) { - URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, - IMindMapImages.DEFAULT_THUMBNAIL); - if (url != null) { - InputStream input = url.openStream(); - try { - FileUtils.transfer(input, output, false); - } finally { - input.close(); - } - } - return properties; - } - - final MindMapImageExporter exporter = new MindMapImageExporter(display); - exporter.setSource(new MindMap(sheet), null, - new Insets(MindMapUI.DEFAULT_EXPORT_MARGIN)); - exporter.setResize(ResizeConstants.RESIZE_MAXPIXELS, 1280, 1024); - exporter.setTargetStream(output); - - final Exception[] error = new Exception[1]; - display.syncExec(new Runnable() { - public void run() { - try { - exporter.export(); - } catch (SWTException e) { - error[0] = e; - } - } - }); - if (error[0] != null) - throw new IOException(error[0]); - - return properties; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.Properties; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.internal.util.BundleUtility; +import org.xmind.core.ISheet; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.image.ResizeConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMap; +import org.xmind.ui.mindmap.MindMapImageExporter; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class DefaultMindMapPreviewGenerator + implements IMindMapPreviewGenerator { + + private final Display display; + + /** + * + */ + public DefaultMindMapPreviewGenerator(Display display) { + this.display = display; + } + + @Override + public Properties generateMindMapPreview(final IWorkbookRef workbookRef, + final ISheet sheet, final OutputStream output, + final MindMapPreviewOptions options) throws IOException { + Assert.isLegal(output != null); + + final Properties properties = new Properties(); + if (sheet == null || MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.PREVIEW_SKIPPED)) { + URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, + IMindMapImages.DEFAULT_THUMBNAIL); + if (url != null) { + InputStream input = url.openStream(); + try { + FileUtils.transfer(input, output, false); + } finally { + input.close(); + } + } + return properties; + } + + final MindMapImageExporter exporter = new MindMapImageExporter(display); + exporter.setSource(new MindMap(sheet), null, + new Insets(MindMapUI.DEFAULT_EXPORT_MARGIN)); + exporter.setResize(ResizeConstants.RESIZE_MAXPIXELS, 1280, 1024); + exporter.setTargetStream(output); + + final Exception[] error = new Exception[1]; + display.syncExec(new Runnable() { + public void run() { + try { + exporter.export(); + } catch (SWTException e) { + error[0] = e; + } + } + }); + if (error[0] != null) + throw new IOException(error[0]); + + return properties; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPane.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPane.java index 1ca9b01dd..12a46a7ca 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPane.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPane.java @@ -1,412 +1,412 @@ -package org.xmind.ui.internal.editor; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.part.Page; - -public abstract class DialogPane extends Page implements IDialogPane { - - private static final float CORNER_OFFSET = 20; - - private static final float CORNER_CONTROL_OFFSET = 5; - - private static final String DEFAULT_BUTTON_TRIGGER_EVENT_ID = "DEFAULT_BUTTON_TRIGGER_EVENT_ID"; //$NON-NLS-1$ - - private int returnCode = OK; - - private IDialogPaneContainer paneContainer; - - private Map buttons; - - private int defaultButtonId = -1; - - private Font defaultFont; - - private Composite container; - - private Listener defaultButtonListener; - - private Listener escapeKeyListener; - - public void init(IDialogPaneContainer paneContainer) { - this.paneContainer = paneContainer; - } - - protected IDialogPaneContainer getPaneContainer() { - return paneContainer; - } - - public void createControl(Composite parent) { - this.container = new Composite(parent, SWT.NONE); - container.setBackground(parent.getDisplay().getSystemColor( - SWT.COLOR_LIST_BACKGROUND)); - paintCornersFor(container, parent.getBackground()); - - GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, true, true); - gridData.widthHint = getPreferredWidth(); - gridData.heightHint = SWT.DEFAULT; - container.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 30; - gridLayout.marginHeight = 20; - gridLayout.marginTop = 10; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - container.setLayout(gridLayout); - - Control contents = createDialogContents(container); - GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData2.widthHint = SWT.DEFAULT; - gridData2.heightHint = SWT.DEFAULT; - contents.setLayoutData(gridData2); - - createButtonBar(container); - - container.addListener(SWT.Traverse, getEscapeKeyListener()); - } - - protected int getPreferredWidth() { - return 400; - } - - protected void paintCornersFor(Composite control, final Color background) { - if (background == null) - return; - control.addPaintListener(new PaintListener() { - public void paintControl(PaintEvent e) { - Control c = (Control) e.widget; - Rectangle b = c.getBounds(); - float x1 = 0; - float y1 = 0; - float x2 = x1 + b.width; - float y2 = y1 + b.height; - - Path p = new Path(e.display); - - p.moveTo(x1, y1); - p.lineTo(x1 + CORNER_OFFSET, y1); - p.cubicTo(x1 + CORNER_CONTROL_OFFSET, y1, x1, y1 - + CORNER_CONTROL_OFFSET, x1, y1 + CORNER_OFFSET); - p.close(); - - p.moveTo(x2, y2); - p.lineTo(x2 - CORNER_OFFSET, y2); - p.cubicTo(x2 - CORNER_CONTROL_OFFSET, y2, x2, y2 - - CORNER_CONTROL_OFFSET, x2, y2 - CORNER_OFFSET); - p.close(); - - e.gc.setAntialias(SWT.ON); - e.gc.setBackground(background); - e.gc.fillPath(p); - p.dispose(); - } - }); - } - - protected Control createDialogContents(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - return composite; - } - - protected Composite getContainer() { - return container; - } - - public Control getControl() { - return container; - } - - public abstract void setFocus(); - - public void dispose() { - if (container != null) { - container.dispose(); - container = null; - } - buttons = null; - } - - protected abstract void createButtonsForButtonBar(Composite buttonBar); - - protected boolean buttonPressed(int buttonId) { - if (buttonId == IDialogConstants.OK_ID) { - return okPressed(); - } else if (buttonId == IDialogConstants.CLOSE_ID) { - return closePressed(); - } else if (buttonId == IDialogConstants.CANCEL_ID) { - return cancelPressed(); - } - return false; - } - - /** - * - */ - protected boolean cancelPressed() { - return false; - } - - /** - * - */ - protected boolean closePressed() { - return false; - } - - /** - * - */ - protected boolean okPressed() { - return false; - } - - protected void createButtonBar(Composite parent) { - Composite buttonBar = new Composite(parent, SWT.NONE); - buttonBar.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - buttonBar.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 5; - buttonBar.setLayout(gridLayout); - - createBlankArea(buttonBar); - createButtonsForButtonBar(buttonBar); - adjustButtonWidths(buttonBar); - } - - protected void createBlankArea(Composite buttonBar) { - Label blank = new Label(buttonBar, SWT.NONE); - blank.setBackground(buttonBar.getBackground()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = 1; - blank.setLayoutData(gridData); - } - - protected Button createButton(Composite buttonBar, int id, String label, - boolean defaultButton) { - ((GridLayout) buttonBar.getLayout()).numColumns++; - Button button = new Button(buttonBar, SWT.PUSH); - button.setText(label); - button.setFont(JFaceResources.getDialogFont()); - button.setData(new Integer(id)); - button.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent event) { - int pressId = (Integer) event.widget.getData(); - buttonPressed(pressId); -// buttonPressed(((Integer) event.widget.getData()).intValue()); - } - }); - if (defaultButton) { - this.defaultButtonId = id; - } - if (buttons == null) - buttons = new HashMap(); - buttons.put(new Integer(id), button); - setButtonLayoutData(button); - - return button; - } - - protected Button getButton(int id) { - return buttons == null ? null : buttons.get(id); - } - - protected void setButtonLayoutData(Button button) { - GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - button.setLayoutData(gridData); - } - - private void adjustButtonWidths(Composite buttonBar) { - if (buttons == null) - return; - int maxWidth = 90; - for (Button b : buttons.values()) { - int width = b.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - maxWidth = Math.max(maxWidth, width); - } - for (Button b : buttons.values()) { - ((GridData) b.getLayoutData()).widthHint = maxWidth + 2; - } - } - - protected void addRefreshDefaultButtonListener(final Control focusControl) { - focusControl.addListener(SWT.FocusIn, getDefaultButtonListener()); - focusControl.addListener(SWT.FocusOut, getDefaultButtonListener()); - } - - protected void addTriggerDefaultButtonListener(Control control, - int triggerEvent) { - control.addListener(triggerEvent, getDefaultButtonListener()); - control.setData(DEFAULT_BUTTON_TRIGGER_EVENT_ID, - Integer.valueOf(triggerEvent)); - } - - private Listener getDefaultButtonListener() { - if (defaultButtonListener == null) { - defaultButtonListener = new Listener() { - - private Button savedDefaultButton = null; - - public void handleEvent(Event event) { - Object triggerEvent = event.widget - .getData(DEFAULT_BUTTON_TRIGGER_EVENT_ID); - if (triggerEvent instanceof Integer - && event.type == ((Integer) triggerEvent) - .intValue()) { - triggerDefaultButton(); - return; - } - - if (event.type == SWT.FocusIn) { - changeDefaultButton(); - } else if (event.type == SWT.FocusOut) { - restoreDefaultButton(); - } - } - - private void restoreDefaultButton() { - if (defaultButtonId >= 0) { - Shell shell = container.getShell(); - if (savedDefaultButton != null - && savedDefaultButton.isDisposed()) { - savedDefaultButton = null; - } - shell.setDefaultButton(savedDefaultButton); - } - } - - private void changeDefaultButton() { - if (defaultButtonId >= 0) { - final Shell shell = container.getShell(); - savedDefaultButton = shell.getDefaultButton(); - shell.getDisplay().asyncExec(new Runnable() { - public void run() { - Button button = getButton(defaultButtonId); - if (button != null && !button.isDisposed()) { - shell.setDefaultButton(button); - } - } - }); - } - } - }; - } - return defaultButtonListener; - } - - private Listener getEscapeKeyListener() { - if (escapeKeyListener == null) { - escapeKeyListener = new Listener() { - public void handleEvent(Event event) { - if (isEscapeKeyPressed(event)) { - escapeKeyPressed(); - event.doit = false; - } - } - - private boolean isEscapeKeyPressed(Event event) { - return (event.type == SWT.Traverse && event.detail == SWT.TRAVERSE_ESCAPE) - || (event.type == SWT.KeyDown - && event.keyCode == SWT.ESC && event.stateMask == 0); - } - }; - } - return escapeKeyListener; - } - - protected void escapeKeyPressed() { - triggerButton(IDialogConstants.CANCEL_ID); - } - - protected Button getDefaultButton() { - if (buttons != null && defaultButtonId >= 0) { - return getButton(defaultButtonId); - } - return null; - } - - protected void triggerDefaultButton() { - triggerButton(defaultButtonId); - } - - protected boolean triggerButton(int buttonId) { - if (buttonId >= 0) { - Button button = getButton(buttonId); - if (button != null && !button.isDisposed() && button.isEnabled()) { - return buttonPressed(buttonId); - } - } - return false; - } - - protected void applyFont(Control control) { - if (defaultFont != null) { - control.setFont(defaultFont); - } - } - - protected void hookText(final Text text) { - text.addListener(SWT.FocusIn, new Listener() { - public void handleEvent(Event event) { - text.selectAll(); - } - }); - } - - public void setDefaultFont(Font font) { - this.defaultFont = font; - } - - protected void relayout() { - if (container == null || container.isDisposed()) - return; - container.getParent().layout(true); - } - - public void setReturnCode(int code) { - this.returnCode = code; - } - - public int getReturnCode() { - return returnCode; - } - - protected boolean close() { - return paneContainer.close(); - } - -} +package org.xmind.ui.internal.editor; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.part.Page; + +public abstract class DialogPane extends Page implements IDialogPane { + + private static final float CORNER_OFFSET = 20; + + private static final float CORNER_CONTROL_OFFSET = 5; + + private static final String DEFAULT_BUTTON_TRIGGER_EVENT_ID = "DEFAULT_BUTTON_TRIGGER_EVENT_ID"; //$NON-NLS-1$ + + private int returnCode = OK; + + private IDialogPaneContainer paneContainer; + + private Map buttons; + + private int defaultButtonId = -1; + + private Font defaultFont; + + private Composite container; + + private Listener defaultButtonListener; + + private Listener escapeKeyListener; + + public void init(IDialogPaneContainer paneContainer) { + this.paneContainer = paneContainer; + } + + protected IDialogPaneContainer getPaneContainer() { + return paneContainer; + } + + public void createControl(Composite parent) { + this.container = new Composite(parent, SWT.NONE); + container.setBackground(parent.getDisplay().getSystemColor( + SWT.COLOR_LIST_BACKGROUND)); + paintCornersFor(container, parent.getBackground()); + + GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, true, true); + gridData.widthHint = getPreferredWidth(); + gridData.heightHint = SWT.DEFAULT; + container.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 30; + gridLayout.marginHeight = 20; + gridLayout.marginTop = 10; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + container.setLayout(gridLayout); + + Control contents = createDialogContents(container); + GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData2.widthHint = SWT.DEFAULT; + gridData2.heightHint = SWT.DEFAULT; + contents.setLayoutData(gridData2); + + createButtonBar(container); + + container.addListener(SWT.Traverse, getEscapeKeyListener()); + } + + protected int getPreferredWidth() { + return 400; + } + + protected void paintCornersFor(Composite control, final Color background) { + if (background == null) + return; + control.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + Control c = (Control) e.widget; + Rectangle b = c.getBounds(); + float x1 = 0; + float y1 = 0; + float x2 = x1 + b.width; + float y2 = y1 + b.height; + + Path p = new Path(e.display); + + p.moveTo(x1, y1); + p.lineTo(x1 + CORNER_OFFSET, y1); + p.cubicTo(x1 + CORNER_CONTROL_OFFSET, y1, x1, y1 + + CORNER_CONTROL_OFFSET, x1, y1 + CORNER_OFFSET); + p.close(); + + p.moveTo(x2, y2); + p.lineTo(x2 - CORNER_OFFSET, y2); + p.cubicTo(x2 - CORNER_CONTROL_OFFSET, y2, x2, y2 + - CORNER_CONTROL_OFFSET, x2, y2 - CORNER_OFFSET); + p.close(); + + e.gc.setAntialias(SWT.ON); + e.gc.setBackground(background); + e.gc.fillPath(p); + p.dispose(); + } + }); + } + + protected Control createDialogContents(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getBackground()); + return composite; + } + + protected Composite getContainer() { + return container; + } + + public Control getControl() { + return container; + } + + public abstract void setFocus(); + + public void dispose() { + if (container != null) { + container.dispose(); + container = null; + } + buttons = null; + } + + protected abstract void createButtonsForButtonBar(Composite buttonBar); + + protected boolean buttonPressed(int buttonId) { + if (buttonId == IDialogConstants.OK_ID) { + return okPressed(); + } else if (buttonId == IDialogConstants.CLOSE_ID) { + return closePressed(); + } else if (buttonId == IDialogConstants.CANCEL_ID) { + return cancelPressed(); + } + return false; + } + + /** + * + */ + protected boolean cancelPressed() { + return false; + } + + /** + * + */ + protected boolean closePressed() { + return false; + } + + /** + * + */ + protected boolean okPressed() { + return false; + } + + protected void createButtonBar(Composite parent) { + Composite buttonBar = new Composite(parent, SWT.NONE); + buttonBar.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + buttonBar.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 5; + buttonBar.setLayout(gridLayout); + + createBlankArea(buttonBar); + createButtonsForButtonBar(buttonBar); + adjustButtonWidths(buttonBar); + } + + protected void createBlankArea(Composite buttonBar) { + Label blank = new Label(buttonBar, SWT.NONE); + blank.setBackground(buttonBar.getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = 1; + blank.setLayoutData(gridData); + } + + protected Button createButton(Composite buttonBar, int id, String label, + boolean defaultButton) { + ((GridLayout) buttonBar.getLayout()).numColumns++; + Button button = new Button(buttonBar, SWT.PUSH); + button.setText(label); + button.setFont(JFaceResources.getDialogFont()); + button.setData(new Integer(id)); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + int pressId = (Integer) event.widget.getData(); + buttonPressed(pressId); +// buttonPressed(((Integer) event.widget.getData()).intValue()); + } + }); + if (defaultButton) { + this.defaultButtonId = id; + } + if (buttons == null) + buttons = new HashMap(); + buttons.put(new Integer(id), button); + setButtonLayoutData(button); + + return button; + } + + protected Button getButton(int id) { + return buttons == null ? null : buttons.get(id); + } + + protected void setButtonLayoutData(Button button) { + GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + button.setLayoutData(gridData); + } + + private void adjustButtonWidths(Composite buttonBar) { + if (buttons == null) + return; + int maxWidth = 90; + for (Button b : buttons.values()) { + int width = b.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + maxWidth = Math.max(maxWidth, width); + } + for (Button b : buttons.values()) { + ((GridData) b.getLayoutData()).widthHint = maxWidth + 2; + } + } + + protected void addRefreshDefaultButtonListener(final Control focusControl) { + focusControl.addListener(SWT.FocusIn, getDefaultButtonListener()); + focusControl.addListener(SWT.FocusOut, getDefaultButtonListener()); + } + + protected void addTriggerDefaultButtonListener(Control control, + int triggerEvent) { + control.addListener(triggerEvent, getDefaultButtonListener()); + control.setData(DEFAULT_BUTTON_TRIGGER_EVENT_ID, + Integer.valueOf(triggerEvent)); + } + + private Listener getDefaultButtonListener() { + if (defaultButtonListener == null) { + defaultButtonListener = new Listener() { + + private Button savedDefaultButton = null; + + public void handleEvent(Event event) { + Object triggerEvent = event.widget + .getData(DEFAULT_BUTTON_TRIGGER_EVENT_ID); + if (triggerEvent instanceof Integer + && event.type == ((Integer) triggerEvent) + .intValue()) { + triggerDefaultButton(); + return; + } + + if (event.type == SWT.FocusIn) { + changeDefaultButton(); + } else if (event.type == SWT.FocusOut) { + restoreDefaultButton(); + } + } + + private void restoreDefaultButton() { + if (defaultButtonId >= 0) { + Shell shell = container.getShell(); + if (savedDefaultButton != null + && savedDefaultButton.isDisposed()) { + savedDefaultButton = null; + } + shell.setDefaultButton(savedDefaultButton); + } + } + + private void changeDefaultButton() { + if (defaultButtonId >= 0) { + final Shell shell = container.getShell(); + savedDefaultButton = shell.getDefaultButton(); + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + Button button = getButton(defaultButtonId); + if (button != null && !button.isDisposed()) { + shell.setDefaultButton(button); + } + } + }); + } + } + }; + } + return defaultButtonListener; + } + + private Listener getEscapeKeyListener() { + if (escapeKeyListener == null) { + escapeKeyListener = new Listener() { + public void handleEvent(Event event) { + if (isEscapeKeyPressed(event)) { + escapeKeyPressed(); + event.doit = false; + } + } + + private boolean isEscapeKeyPressed(Event event) { + return (event.type == SWT.Traverse && event.detail == SWT.TRAVERSE_ESCAPE) + || (event.type == SWT.KeyDown + && event.keyCode == SWT.ESC && event.stateMask == 0); + } + }; + } + return escapeKeyListener; + } + + protected void escapeKeyPressed() { + triggerButton(IDialogConstants.CANCEL_ID); + } + + protected Button getDefaultButton() { + if (buttons != null && defaultButtonId >= 0) { + return getButton(defaultButtonId); + } + return null; + } + + protected void triggerDefaultButton() { + triggerButton(defaultButtonId); + } + + protected boolean triggerButton(int buttonId) { + if (buttonId >= 0) { + Button button = getButton(buttonId); + if (button != null && !button.isDisposed() && button.isEnabled()) { + return buttonPressed(buttonId); + } + } + return false; + } + + protected void applyFont(Control control) { + if (defaultFont != null) { + control.setFont(defaultFont); + } + } + + protected void hookText(final Text text) { + text.addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) { + text.selectAll(); + } + }); + } + + public void setDefaultFont(Font font) { + this.defaultFont = font; + } + + protected void relayout() { + if (container == null || container.isDisposed()) + return; + container.getParent().layout(true); + } + + public void setReturnCode(int code) { + this.returnCode = code; + } + + public int getReturnCode() { + return returnCode; + } + + protected boolean close() { + return paneContainer.close(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPaneContainer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPaneContainer.java index b0887862d..8b3b25718 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPaneContainer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DialogPaneContainer.java @@ -1,153 +1,153 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.contexts.IContextActivation; -import org.eclipse.ui.contexts.IContextService; -import org.eclipse.ui.services.IServiceLocator; - -public class DialogPaneContainer implements IDialogPaneContainer { - - private Composite composite; - - private IDialogPane currentPane; - - private IServiceLocator serviceLocator; - - public void init(IServiceLocator serviceLocator) { - this.serviceLocator = serviceLocator; - } - - public Control getControl() { - return composite; - } - - public void createControl(Composite parent) { - composite = new Composite(parent, SWT.NONE); - - Display display = parent.getDisplay(); - final Color background = new Color(display, 0x38, 0x38, 0x38); - composite.setBackground(background); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - composite.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - background.dispose(); - handleDispose(); - } - }); - } - - protected void handleDispose() { - hideCurrentDialog(); - } - - public void open(IDialogPane dialog) { - if (composite == null || composite.isDisposed()) - return; - showDialog(dialog); - } - - protected void showDialog(IDialogPane dialog) { - if (composite == null || composite.isDisposed()) - return; - - doHideCurrentDialog(); - currentPane = dialog; - dialog.init(this); - currentPane.createControl(composite); - currentPane.setFocus(); - composite.layout(true); - - IContextActivation activation = null; - IContextService contextService = serviceLocator == null ? null - : (IContextService) serviceLocator - .getService(IContextService.class); - if (contextService != null) { - activation = contextService - .activateContext("org.xmind.ui.context.backcover"); //$NON-NLS-1$ - } - -// -// -// if (contextService != null && activation != null) { -// contextService.deactivateContext(activation); -// } - } - - protected IDialogPane getCurrentDialog() { - return currentPane; - } - - protected void hideCurrentDialog() { - doHideCurrentDialog(); - if (composite != null && !composite.isDisposed()) { - composite.layout(true); - } - } - - private void doHideCurrentDialog() { - if (currentPane != null) { - Control pageControl = currentPane.getControl(); - currentPane.dispose(); - if (pageControl != null && !pageControl.isDisposed()) { - pageControl.dispose(); - } - currentPane = null; - } - } - - public void dispose() { - close(); - if (composite != null) { - composite.dispose(); - } - } - - public void setFocus() { - if (currentPane != null) { - currentPane.setFocus(); - } else { - composite.setFocus(); - } - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.editor.IDialogPaneContainer#close() - */ - public boolean close() { - hideCurrentDialog(); - return currentPane == null; - } - - public void close(int returnCode) { - if (currentPane != null) { - currentPane.setReturnCode(returnCode); - } - close(); - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.editor.IDialogPaneContainer#isOpen() - */ - public boolean isOpen() { - return currentPane != null; - } - +package org.xmind.ui.internal.editor; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.services.IServiceLocator; + +public class DialogPaneContainer implements IDialogPaneContainer { + + private Composite composite; + + private IDialogPane currentPane; + + private IServiceLocator serviceLocator; + + public void init(IServiceLocator serviceLocator) { + this.serviceLocator = serviceLocator; + } + + public Control getControl() { + return composite; + } + + public void createControl(Composite parent) { + composite = new Composite(parent, SWT.NONE); + + Display display = parent.getDisplay(); + final Color background = new Color(display, 0x38, 0x38, 0x38); + composite.setBackground(background); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + composite.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + background.dispose(); + handleDispose(); + } + }); + } + + protected void handleDispose() { + hideCurrentDialog(); + } + + public void open(IDialogPane dialog) { + if (composite == null || composite.isDisposed()) + return; + showDialog(dialog); + } + + protected void showDialog(IDialogPane dialog) { + if (composite == null || composite.isDisposed()) + return; + + doHideCurrentDialog(); + currentPane = dialog; + dialog.init(this); + currentPane.createControl(composite); + currentPane.setFocus(); + composite.layout(true); + + IContextActivation activation = null; + IContextService contextService = serviceLocator == null ? null + : (IContextService) serviceLocator + .getService(IContextService.class); + if (contextService != null) { + activation = contextService + .activateContext("org.xmind.ui.context.backcover"); //$NON-NLS-1$ + } + +// +// +// if (contextService != null && activation != null) { +// contextService.deactivateContext(activation); +// } + } + + protected IDialogPane getCurrentDialog() { + return currentPane; + } + + protected void hideCurrentDialog() { + doHideCurrentDialog(); + if (composite != null && !composite.isDisposed()) { + composite.layout(true); + } + } + + private void doHideCurrentDialog() { + if (currentPane != null) { + Control pageControl = currentPane.getControl(); + currentPane.dispose(); + if (pageControl != null && !pageControl.isDisposed()) { + pageControl.dispose(); + } + currentPane = null; + } + } + + public void dispose() { + close(); + if (composite != null) { + composite.dispose(); + } + } + + public void setFocus() { + if (currentPane != null) { + currentPane.setFocus(); + } else { + composite.setFocus(); + } + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.editor.IDialogPaneContainer#close() + */ + public boolean close() { + hideCurrentDialog(); + return currentPane == null; + } + + public void close(int returnCode) { + if (currentPane != null) { + currentPane.setReturnCode(returnCode); + } + close(); + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.editor.IDialogPaneContainer#isOpen() + */ + public boolean isOpen() { + return currentPane != null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryImpl.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryImpl.java index fbb03ed78..ce707f68f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryImpl.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryImpl.java @@ -1,301 +1,301 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.services.IDisposable; -import org.xmind.ui.editor.EditorHistoryItem; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistoryItem; -import org.xmind.ui.internal.editor.IEditorHistoryLoader.IEditorHistoryLoaderCallback; - -/** - * @author Ren Siu - * @author Frank Shaka - * @since 3.6.50 - */ -public final class EditorHistoryImpl implements IEditorHistory, IDisposable { - - private final IEditorHistoryLoader loader; - - private final List unpinnedInputURIs; - - private final List pinnedInputURIs; - - private final Map inputToThumbnail; - - private final Map editorHistoryItems; - - private final ListenerList listeners; - - public EditorHistoryImpl(IEditorHistoryLoader loader) { - this.loader = loader; - this.unpinnedInputURIs = new ArrayList(); - this.pinnedInputURIs = new ArrayList(); - this.inputToThumbnail = new HashMap(); - this.listeners = new ListenerList(); - this.editorHistoryItems = new HashMap(); - init(); - } - - private void init() { - loader.load(new IEditorHistoryLoaderCallback() { - - @Override - public void thumbnailURILoaded(URI inputURI, URI thumbnailURI) { - inputToThumbnail.put(inputURI, thumbnailURI); - } - - @Override - public void pinnedInputURILoaded(URI inputURI) { - pinnedInputURIs.add(inputURI); - } - - @Override - public void inputURILoaded(URI inputURI) { - unpinnedInputURIs.add(inputURI); - } - - @Override - public void editorHistoryItemsLoaded(URI inputURI, - IEditorHistoryItem item) { - editorHistoryItems.put(inputURI, item); - } - - }); - while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { - unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); - } - } - - public URI[] getRecentInputURIs(int unpinnedSize) { - if (unpinnedSize < 0) - unpinnedSize = MAX_UNPINNED_SIZE; - - unpinnedSize = Math.max(0, - Math.min(unpinnedSize, unpinnedInputURIs.size())); - ArrayList recentInputURIs = new ArrayList(); - recentInputURIs.addAll(pinnedInputURIs); - recentInputURIs.addAll(unpinnedInputURIs.subList(0, unpinnedSize)); - return recentInputURIs.toArray(new URI[recentInputURIs.size()]); - } - - public URI[] getAllInputURIs() { - int unpinnedSize = Math.max(0, - Math.min(MAX_UNPINNED_SIZE, unpinnedInputURIs.size())); - List allInputURIs = new ArrayList(); - allInputURIs.addAll(pinnedInputURIs); - allInputURIs.addAll(unpinnedInputURIs.subList(0, unpinnedSize)); - return allInputURIs.toArray(new URI[unpinnedSize]); - } - - public URI[] getPinnedInputURIs() { - return pinnedInputURIs.toArray(new URI[pinnedInputURIs.size()]); - } - - public URI[] getUnpinnedInputURIs(int unpinnedSize) { - if (unpinnedSize < 0) - unpinnedSize = MAX_UNPINNED_SIZE; - - unpinnedSize = Math.max(0, - Math.min(unpinnedSize, unpinnedInputURIs.size())); - return unpinnedInputURIs.subList(0, unpinnedSize) - .toArray(new URI[unpinnedSize]); - } - - public void add(URI inputURI) { - if (inputURI == null) - return; - - this.add(inputURI, new EditorHistoryItem(inputURI.getScheme(), - System.currentTimeMillis())); - - boolean pinned = pinnedInputURIs.contains(inputURI); - - remove(inputURI); - - if (pinned) { - pinnedInputURIs.add(0, inputURI); - } else { - unpinnedInputURIs.add(0, inputURI); - while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { - unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); - } - } - fireChanged(); - } - - public void remove(URI inputURI) { - if (inputURI == null) - return; - - int oldPinnedSize = pinnedInputURIs.size(); - Iterator iter = pinnedInputURIs.iterator(); - while (iter.hasNext()) { - URI oldURI = iter.next(); - if (inputURI.equals(oldURI)) { - iter.remove(); - } - } - - int oldUnpinnedSize = unpinnedInputURIs.size(); - Iterator unpinnedIterator = unpinnedInputURIs.iterator(); - while (unpinnedIterator.hasNext()) { - URI oldURI = unpinnedIterator.next(); - if (inputURI.equals(oldURI)) { - unpinnedIterator.remove(); - } - } - - //REMOVE THUMBNAIL - removeThumbnail(inputURI); - - removeEditorHistoryItem(inputURI); - - if (oldPinnedSize != pinnedInputURIs.size() - || oldUnpinnedSize != unpinnedInputURIs.size()) { - fireChanged(); - } - } - - private void removeThumbnail(URI inputURI) { - URI thumbnailURI = inputToThumbnail.get(inputURI); - if (thumbnailURI != null) { - File existedThumbnailFile = new File(thumbnailURI); - if (existedThumbnailFile.exists()) { - existedThumbnailFile.delete(); - } - } - inputToThumbnail.remove(inputURI); - } - - public void clear() { - int oldSize = unpinnedInputURIs.size(); - for (URI unpinnedInputURI : unpinnedInputURIs) { - removeThumbnail(unpinnedInputURI); - removeEditorHistoryItem(unpinnedInputURI); - } - unpinnedInputURIs.clear(); - if (oldSize != unpinnedInputURIs.size()) { - fireChanged(); - } - } - - public InputStream loadThumbnailData(URI inputURI) throws IOException { - URI thumbnailURI = getThumbnail(inputURI); - if (thumbnailURI == null) - return null; - return thumbnailURI.toURL().openStream(); - } - - public void saveThumbnailData(URI inputURI, InputStream thumbnailData) - throws IOException { - //REMOVE EXPIRED THUMBNAIL - removeThumbnail(inputURI); - - URI thumbnailURI = loader.saveThumbnail(thumbnailData); - if (thumbnailURI == null) - return; - - inputToThumbnail.put(inputURI, thumbnailURI); - - fireChanged(); - } - - public URI getThumbnail(URI inputURI) { - return inputToThumbnail.get(inputURI); - } - - @Override - public void add(URI inputURI, IEditorHistoryItem item) { - if (inputURI == null) - return; - - boolean pinned = pinnedInputURIs.contains(inputURI); - remove(inputURI); - - if (pinned) { - pinnedInputURIs.add(0, inputURI); - } else { - unpinnedInputURIs.add(0, inputURI); - while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { - unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); - } - } - - removeEditorHistoryItem(inputURI); - editorHistoryItems.put(inputURI, item); - - fireChanged(); - } - - private void removeEditorHistoryItem(URI inputURI) { - // do remove EditorHistoryItem by uri. - IEditorHistoryItem historyItemUri = editorHistoryItems.get(inputURI); - if (historyItemUri != null) { - historyItemUri = null; - } - editorHistoryItems.remove(inputURI); - } - - @Override - public IEditorHistoryItem getItem(URI inputURI) { - return editorHistoryItems.get(inputURI); - } - - public void pin(URI inputURI) { - unpinnedInputURIs.remove(inputURI); - pinnedInputURIs.remove(inputURI); - pinnedInputURIs.add(0, inputURI); - fireChanged(); - } - - public void unPin(URI inputURI) { - pinnedInputURIs.remove(inputURI); - unpinnedInputURIs.remove(inputURI); - unpinnedInputURIs.add(0, inputURI); - fireChanged(); - } - - public boolean isPinned(URI inputURI) { - return pinnedInputURIs.contains(inputURI); - } - - public void removeEditorHistoryListener(IEditorHistoryListener listener) { - listeners.remove(listener); - } - - public void addEditorHistoryListener(IEditorHistoryListener listener) { - listeners.add(listener); - } - - private void fireChanged() { - for (final Object listener : listeners.getListeners()) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - ((IEditorHistoryListener) listener).editorHistoryChanged(); - } - }); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.services.IDisposable#dispose() - */ - @Override - public void dispose() { - loader.dispose(); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.services.IDisposable; +import org.xmind.ui.editor.EditorHistoryItem; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistoryItem; +import org.xmind.ui.internal.editor.IEditorHistoryLoader.IEditorHistoryLoaderCallback; + +/** + * @author Ren Siu + * @author Frank Shaka + * @since 3.6.50 + */ +public final class EditorHistoryImpl implements IEditorHistory, IDisposable { + + private final IEditorHistoryLoader loader; + + private final List unpinnedInputURIs; + + private final List pinnedInputURIs; + + private final Map inputToThumbnail; + + private final Map editorHistoryItems; + + private final ListenerList listeners; + + public EditorHistoryImpl(IEditorHistoryLoader loader) { + this.loader = loader; + this.unpinnedInputURIs = new ArrayList(); + this.pinnedInputURIs = new ArrayList(); + this.inputToThumbnail = new HashMap(); + this.listeners = new ListenerList(); + this.editorHistoryItems = new HashMap(); + init(); + } + + private void init() { + loader.load(new IEditorHistoryLoaderCallback() { + + @Override + public void thumbnailURILoaded(URI inputURI, URI thumbnailURI) { + inputToThumbnail.put(inputURI, thumbnailURI); + } + + @Override + public void pinnedInputURILoaded(URI inputURI) { + pinnedInputURIs.add(inputURI); + } + + @Override + public void inputURILoaded(URI inputURI) { + unpinnedInputURIs.add(inputURI); + } + + @Override + public void editorHistoryItemsLoaded(URI inputURI, + IEditorHistoryItem item) { + editorHistoryItems.put(inputURI, item); + } + + }); + while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { + unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); + } + } + + public URI[] getRecentInputURIs(int unpinnedSize) { + if (unpinnedSize < 0) + unpinnedSize = MAX_UNPINNED_SIZE; + + unpinnedSize = Math.max(0, + Math.min(unpinnedSize, unpinnedInputURIs.size())); + ArrayList recentInputURIs = new ArrayList(); + recentInputURIs.addAll(pinnedInputURIs); + recentInputURIs.addAll(unpinnedInputURIs.subList(0, unpinnedSize)); + return recentInputURIs.toArray(new URI[recentInputURIs.size()]); + } + + public URI[] getAllInputURIs() { + int unpinnedSize = Math.max(0, + Math.min(MAX_UNPINNED_SIZE, unpinnedInputURIs.size())); + List allInputURIs = new ArrayList(); + allInputURIs.addAll(pinnedInputURIs); + allInputURIs.addAll(unpinnedInputURIs.subList(0, unpinnedSize)); + return allInputURIs.toArray(new URI[unpinnedSize]); + } + + public URI[] getPinnedInputURIs() { + return pinnedInputURIs.toArray(new URI[pinnedInputURIs.size()]); + } + + public URI[] getUnpinnedInputURIs(int unpinnedSize) { + if (unpinnedSize < 0) + unpinnedSize = MAX_UNPINNED_SIZE; + + unpinnedSize = Math.max(0, + Math.min(unpinnedSize, unpinnedInputURIs.size())); + return unpinnedInputURIs.subList(0, unpinnedSize) + .toArray(new URI[unpinnedSize]); + } + + public void add(URI inputURI) { + if (inputURI == null) + return; + + this.add(inputURI, new EditorHistoryItem(inputURI.getScheme(), + System.currentTimeMillis())); + + boolean pinned = pinnedInputURIs.contains(inputURI); + + remove(inputURI); + + if (pinned) { + pinnedInputURIs.add(0, inputURI); + } else { + unpinnedInputURIs.add(0, inputURI); + while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { + unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); + } + } + fireChanged(); + } + + public void remove(URI inputURI) { + if (inputURI == null) + return; + + int oldPinnedSize = pinnedInputURIs.size(); + Iterator iter = pinnedInputURIs.iterator(); + while (iter.hasNext()) { + URI oldURI = iter.next(); + if (inputURI.equals(oldURI)) { + iter.remove(); + } + } + + int oldUnpinnedSize = unpinnedInputURIs.size(); + Iterator unpinnedIterator = unpinnedInputURIs.iterator(); + while (unpinnedIterator.hasNext()) { + URI oldURI = unpinnedIterator.next(); + if (inputURI.equals(oldURI)) { + unpinnedIterator.remove(); + } + } + + //REMOVE THUMBNAIL + removeThumbnail(inputURI); + + removeEditorHistoryItem(inputURI); + + if (oldPinnedSize != pinnedInputURIs.size() + || oldUnpinnedSize != unpinnedInputURIs.size()) { + fireChanged(); + } + } + + private void removeThumbnail(URI inputURI) { + URI thumbnailURI = inputToThumbnail.get(inputURI); + if (thumbnailURI != null) { + File existedThumbnailFile = new File(thumbnailURI); + if (existedThumbnailFile.exists()) { + existedThumbnailFile.delete(); + } + } + inputToThumbnail.remove(inputURI); + } + + public void clear() { + int oldSize = unpinnedInputURIs.size(); + for (URI unpinnedInputURI : unpinnedInputURIs) { + removeThumbnail(unpinnedInputURI); + removeEditorHistoryItem(unpinnedInputURI); + } + unpinnedInputURIs.clear(); + if (oldSize != unpinnedInputURIs.size()) { + fireChanged(); + } + } + + public InputStream loadThumbnailData(URI inputURI) throws IOException { + URI thumbnailURI = getThumbnail(inputURI); + if (thumbnailURI == null) + return null; + return thumbnailURI.toURL().openStream(); + } + + public void saveThumbnailData(URI inputURI, InputStream thumbnailData) + throws IOException { + //REMOVE EXPIRED THUMBNAIL + removeThumbnail(inputURI); + + URI thumbnailURI = loader.saveThumbnail(thumbnailData); + if (thumbnailURI == null) + return; + + inputToThumbnail.put(inputURI, thumbnailURI); + + fireChanged(); + } + + public URI getThumbnail(URI inputURI) { + return inputToThumbnail.get(inputURI); + } + + @Override + public void add(URI inputURI, IEditorHistoryItem item) { + if (inputURI == null) + return; + + boolean pinned = pinnedInputURIs.contains(inputURI); + remove(inputURI); + + if (pinned) { + pinnedInputURIs.add(0, inputURI); + } else { + unpinnedInputURIs.add(0, inputURI); + while (unpinnedInputURIs.size() > MAX_UNPINNED_SIZE) { + unpinnedInputURIs.remove(unpinnedInputURIs.size() - 1); + } + } + + removeEditorHistoryItem(inputURI); + editorHistoryItems.put(inputURI, item); + + fireChanged(); + } + + private void removeEditorHistoryItem(URI inputURI) { + // do remove EditorHistoryItem by uri. + IEditorHistoryItem historyItemUri = editorHistoryItems.get(inputURI); + if (historyItemUri != null) { + historyItemUri = null; + } + editorHistoryItems.remove(inputURI); + } + + @Override + public IEditorHistoryItem getItem(URI inputURI) { + return editorHistoryItems.get(inputURI); + } + + public void pin(URI inputURI) { + unpinnedInputURIs.remove(inputURI); + pinnedInputURIs.remove(inputURI); + pinnedInputURIs.add(0, inputURI); + fireChanged(); + } + + public void unPin(URI inputURI) { + pinnedInputURIs.remove(inputURI); + unpinnedInputURIs.remove(inputURI); + unpinnedInputURIs.add(0, inputURI); + fireChanged(); + } + + public boolean isPinned(URI inputURI) { + return pinnedInputURIs.contains(inputURI); + } + + public void removeEditorHistoryListener(IEditorHistoryListener listener) { + listeners.remove(listener); + } + + public void addEditorHistoryListener(IEditorHistoryListener listener) { + listeners.add(listener); + } + + private void fireChanged() { + for (final Object listener : listeners.getListeners()) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + ((IEditorHistoryListener) listener).editorHistoryChanged(); + } + }); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.services.IDisposable#dispose() + */ + @Override + public void dispose() { + loader.dispose(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryPersistenceHelper.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryPersistenceHelper.java index baca18c1b..72ec95afc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryPersistenceHelper.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryPersistenceHelper.java @@ -1,598 +1,598 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import org.eclipse.core.runtime.IPath; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.editor.EditorHistoryItem; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; -import org.xmind.ui.editor.IEditorHistoryItem; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.util.Logger; - -/** - * @author Ren Siu - * @author Frank Shaka - * @since 3.6.50 - */ -public class EditorHistoryPersistenceHelper - implements IEditorHistoryLoader, IEditorHistoryListener { - - private static final String VALUE_SEPARATOR = "#$#"; //$NON-NLS-1$ - - private static final String KEY_PREFIX = "item."; //$NON-NLS-1$ - - private static final String PINNED_KEY_HISTORY_ITEM_PREFIX = "pinned.editor.history.item."; //$NON-NLS-1$ - - private static final String UNPINNED_KEY_HISTORY_ITEM_PREFIX = "unpinned.editor.history.item."; //$NON-NLS-1$ - - private static final String PINNED_KEY_PREFIX = "pinned.item."; //$NON-NLS-1$ - - private static final String THUMBNAIL_PREFIX = "thumbnail."; //$NON-NLS-1$ - - private static final String OLD_FILE_NAME = "workbookHistory.properties"; //$NON-NLS-1$ - - private static final String FILE_NAME = ".workbookHistory.properties"; //$NON-NLS-1$ - - private static final String THUMBNAIL_DIR_NAME = ".thumbnailHistory"; //$NON-NLS-1$ - - private static final Object END_OF_QUEUE = new Object(); - - private static class EditorHistoryState { - - private final URI[] unpinnedInputURIs; - private final URI[] pinnedInputURIs; - private final Map thumbnailURIs; - private final Map editorHistoryItems; - - /** - * - */ - private EditorHistoryState(EditorHistoryImpl service) { - this.unpinnedInputURIs = service - .getUnpinnedInputURIs(IEditorHistory.MAX_UNPINNED_SIZE); - this.pinnedInputURIs = service.getPinnedInputURIs(); - this.thumbnailURIs = new HashMap(); - this.editorHistoryItems = new HashMap(); - - for (URI uri : pinnedInputURIs) { - URI thumbnailURI = service.getThumbnail(uri); - if (thumbnailURI != null) { - thumbnailURIs.put(uri, thumbnailURI); - } - IEditorHistoryItem item = service.getItem(uri); - if (item != null) - editorHistoryItems.put(uri, item); - } - for (URI uri : unpinnedInputURIs) { - URI thumbnailURI = service.getThumbnail(uri); - if (thumbnailURI != null) { - thumbnailURIs.put(uri, thumbnailURI); - } - IEditorHistoryItem item = service.getItem(uri); - if (item != null) - editorHistoryItems.put(uri, item); - } - } - - /** - * @param service - * @return - */ - public static EditorHistoryState createFrom(EditorHistoryImpl service) { - return new EditorHistoryState(service); - } - - /** - * @return - */ - public URI[] getPinnedInputURIs() { - return pinnedInputURIs; - } - - /** - * @return - */ - public URI[] getUnpinnedInputURIs() { - return unpinnedInputURIs; - } - - /** - * @param input - * @return - */ - public URI getThumbnail(URI input) { - return thumbnailURIs.get(input); - } - - /** - * @param input - * @return - */ - public IEditorHistoryItem getEditorHistoryItem(URI input) { - return editorHistoryItems.get(input); - } - } - - private final IPath basePath; - - private final BlockingQueue stateQueue; - - private Thread thread; - - private EditorHistoryImpl service; - - /** - * - */ - public EditorHistoryPersistenceHelper(IPath basePath) { - this.basePath = basePath; - this.stateQueue = new LinkedBlockingQueue(); - this.thread = null; - this.service = null; - } - - public void setService(EditorHistoryImpl service) { - IEditorHistory oldService = this.service; - if (service == oldService) - return; - - this.service = service; - if (oldService != null) { - oldService.removeEditorHistoryListener(this); - } - if (service != null) { - service.addEditorHistoryListener(this); - } - - if (oldService == null && service != null) { - startThread(); - } else if (oldService != null && service == null) { - stopThread(); - } - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#load(org.xmind.ui. - * internal.editor.IEditorHistoryLoader.IEditorHistoryLoaderCallback) - */ - @Override - public void load(IEditorHistoryLoaderCallback callback) { - Properties historyRepository = load(); - for (int index = 0; index < historyRepository.size(); index++) { - String unpinnedKey = KEY_PREFIX + index; - String pinnedKey = PINNED_KEY_PREFIX + index; - String pinnedThumbnailKey = THUMBNAIL_PREFIX + pinnedKey; - String unpinnedThumbnailKey = THUMBNAIL_PREFIX + unpinnedKey; - String pinedEditorHistoryItemKey = PINNED_KEY_HISTORY_ITEM_PREFIX - + index; - String unPinedEditorHistoryItemKey = UNPINNED_KEY_HISTORY_ITEM_PREFIX - + index; - - String unpinnedInputURI = historyRepository - .getProperty(unpinnedKey); - String pinnedInputURI = historyRepository.getProperty(pinnedKey); - String unpinnedThumbnailURI = historyRepository - .getProperty(unpinnedThumbnailKey); - String pinnedThumbnailURI = historyRepository - .getProperty(pinnedThumbnailKey); - - unpinnedInputURI = fixFileUri(unpinnedInputURI); - pinnedInputURI = fixFileUri(pinnedInputURI); - unpinnedThumbnailURI = fixFileUri(unpinnedThumbnailURI); - pinnedThumbnailURI = fixFileUri(pinnedThumbnailURI); - - String pinedItemJson = historyRepository - .getProperty(pinedEditorHistoryItemKey); - IEditorHistoryItem pinnedItem = EditorHistoryItem - .readEditorHistoryItem(pinnedInputURI, pinedItemJson); - - String unpinedItemJson = historyRepository - .getProperty(unPinedEditorHistoryItemKey); - IEditorHistoryItem unpinedItem = EditorHistoryItem - .readEditorHistoryItem(unpinnedInputURI, unpinedItemJson); - - try { - if (unpinnedInputURI != null) { - URI unpinnedURI = new URI(unpinnedInputURI); - callback.inputURILoaded(unpinnedURI); - - if (unpinedItem != null) - callback.editorHistoryItemsLoaded(unpinnedURI, - unpinedItem); - - if (unpinnedThumbnailURI != null - && !unpinnedInputURI.isEmpty()) { - callback.thumbnailURILoaded(unpinnedURI, - new URI(unpinnedThumbnailURI)); - } - } - } catch (URISyntaxException e) { - } - - try { - if (pinnedInputURI != null) { - URI pinnedURI = new URI(pinnedInputURI); - callback.pinnedInputURILoaded(pinnedURI); - - if (pinnedItem != null) - callback.editorHistoryItemsLoaded(pinnedURI, - pinnedItem); - - if (pinnedThumbnailURI != null - && !pinnedInputURI.isEmpty()) { - callback.thumbnailURILoaded(pinnedURI, - new URI(pinnedThumbnailURI)); - } - } - } catch (URISyntaxException e) { - } - } - - } - - private String fixFileUri(String uri) { - if (uri != null && uri.startsWith("file:")) { //$NON-NLS-1$ - String specialPart = uri.substring(5); - boolean error = specialPart.startsWith("//") //$NON-NLS-1$ - && !specialPart.startsWith("///"); //$NON-NLS-1$ - if (error) { - return "file:" + "/" + specialPart; //$NON-NLS-1$ //$NON-NLS-2$ - } - } else if (uri != null && uri.startsWith("seawind:")) {//$NON-NLS-1$ - String specialPart = uri.substring(8); - boolean error = specialPart.startsWith("//") //$NON-NLS-1$ - && !specialPart.startsWith("///"); //$NON-NLS-1$ - if (error) { - return "seawind:" + "/" + specialPart; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return uri; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.IEditorHistoryLoader#saveThumbnail(java.io. - * InputStream) - */ - @Override - public URI saveThumbnail(InputStream thumbnailData) throws IOException { - File thumbnailDir = getThumbnailDir(); - if (thumbnailDir == null) - return null; - - if (!thumbnailDir.exists()) { - thumbnailDir.mkdirs(); - } - String thumbnailName = UUID.randomUUID().toString(); - File thumbnailFile = new File(thumbnailDir, thumbnailName); - - OutputStream output = new FileOutputStream(thumbnailFile); - try { - FileUtils.transfer(thumbnailData, output, false); - } finally { - output.close(); - } - - return thumbnailFile.toURI(); - } - - private File getThumbnailDir() { - IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); - if (basePath == null) - return null; - IPath filePath = basePath.append(THUMBNAIL_DIR_NAME); - return filePath.toFile(); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#dispose() - */ - @Override - public void dispose() { - setService(null); - } - - private void startThread() { - Thread thread = new Thread(new Runnable() { - public void run() { - runLoop(); - } - }); - thread.setName("EditorHistoryPersistenceThread"); //$NON-NLS-1$ - thread.setPriority(Thread.MIN_PRIORITY); - thread.setDaemon(true); - this.thread = thread; - thread.start(); - - /* - * Manually trigger a save operation on startup, for there might be some - * changes to editor history before this earlyStartup method is called. - * For example, files are opened on startup via double click in Finder. - */ - editorHistoryChanged(); - } - - private void stopThread() { - if (service != null) - service.removeEditorHistoryListener(this); - - stateQueue.offer(END_OF_QUEUE); - - Thread thread = this.thread; - this.thread = null; - if (thread != null) { - thread.interrupt(); - } - } - - public void editorHistoryChanged() { - if (service == null) - return; - - EditorHistoryState state = EditorHistoryState.createFrom(service); - stateQueue.offer(state); - } - - private void runLoop() { - try { - while (thread != null) { - Object state = stateQueue.take(); - if (state == END_OF_QUEUE) - break; - save((EditorHistoryState) state); - Thread.sleep(0); - } - } catch (InterruptedException e) { - // interruption means stop - } - } - - private void save(EditorHistoryState persistable) { - Properties repository = new Properties(); - - URI[] pinnedInputURIs = persistable.getPinnedInputURIs(); - URI[] unpinnedInputURIs = persistable.getUnpinnedInputURIs(); - - //Push pinned items - for (int index = 0; index < pinnedInputURIs.length; index++) { - URI input = pinnedInputURIs[index]; - if (input != null) { - String key = PINNED_KEY_PREFIX + index; - repository.setProperty(key, input.toString()); - - String pinnedEditorHistoryItemKey = PINNED_KEY_HISTORY_ITEM_PREFIX - + index; - IEditorHistoryItem pinnedItem = persistable - .getEditorHistoryItem(input); - if (pinnedItem != null) - repository.setProperty(pinnedEditorHistoryItemKey, - pinnedItem.toJson()); - - URI thumbnail = persistable.getThumbnail(input); - String thumbnailKey = THUMBNAIL_PREFIX + key; - if (thumbnail != null) - repository.setProperty(thumbnailKey, thumbnail.toString()); - } - } - - // Push unpinned items - for (int index = 0; index < unpinnedInputURIs.length; index++) { - URI input = unpinnedInputURIs[index]; - if (input != null) { - String key = KEY_PREFIX + index; - repository.setProperty(key, input.toString()); - - String unpinedEditorHistoryItemKey = UNPINNED_KEY_HISTORY_ITEM_PREFIX - + index; - IEditorHistoryItem unpinnedItem = persistable - .getEditorHistoryItem(input); - if (unpinnedItem != null) - repository.setProperty(unpinedEditorHistoryItemKey, - unpinnedItem.toJson()); - - URI thumbnail = persistable.getThumbnail(input); - String thumbnailKey = THUMBNAIL_PREFIX + key; - if (thumbnail != null) - repository.setProperty(thumbnailKey, thumbnail.toString()); - } - } - - // Save to properties file - File file = getHistoryFile(); - if (file != null) { - if (!file.getParentFile().exists()) { - file.getParentFile().mkdirs(); - } - try { - OutputStreamWriter out = new OutputStreamWriter( - new FileOutputStream(file), "UTF-8"); //$NON-NLS-1$ -// FileWriter writer = new FileWriter(file); - try { - repository.store(out, - "Generated by org.xmind.ui.internal.editor.EditorHistoryService"); //$NON-NLS-1$ - } finally { - out.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to save workbook history to " //$NON-NLS-1$ - + file.getAbsolutePath()); - } - } - - File oldHistoryFile = getOldHistoryFile(); - if (oldHistoryFile != null && oldHistoryFile.exists()) { - oldHistoryFile.delete(); - } - } - - public Properties load() { - Properties repository = new Properties(); - - // Load form properties file - File file = getHistoryFile(); - if (file != null && file.exists()) { - try { - InputStreamReader reader = new InputStreamReader( - new FileInputStream(file), "UTF-8"); //$NON-NLS-1$ -// FileReader reader = new FileReader(file); - try { - repository.load(reader); - } finally { - reader.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ - + file.getAbsolutePath()); - } - } else { - repository = loadOldHistoryRepository(); - } - - return repository; - } - - private Properties loadOldHistoryRepository() { - Properties repository = new Properties(); - - // Load form old properties file - File file = getOldHistoryFile(); - if (file != null && file.exists()) { - try { - FileReader reader = new FileReader(file); - try { - repository.load(reader); - } finally { - reader.close(); - } - } catch (IOException e) { - Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ - + file.getAbsolutePath()); - } - int count = 0; - List items = new ArrayList(); - // Parse properties - int size = repository.size(); - for (int i = 0; i < size; i++) { - if (count >= IEditorHistory.MAX_UNPINNED_SIZE) - break; - - String key = KEY_PREFIX + i; - String value = repository.getProperty(key); - if (value == null) - continue; - items.add(value); - repository.remove(key); - - count++; - } - - //Compatible with the old version - Set oldVersionKeys = repository.keySet(); - for (Object key : oldVersionKeys) { - if (count >= IEditorHistory.MAX_UNPINNED_SIZE) - break; - - String input = (String) key; - String info = repository.getProperty(input); - - items.add(input + VALUE_SEPARATOR + info); - count++; - } - - //Transfer old format into new format - repository = new Properties(); - int countForPinned = 0; - int countForUnpinned = 0; - - for (String inputAndInfo : items) { - int index = inputAndInfo.indexOf(VALUE_SEPARATOR); - if (index < 0) - continue; - - String input = inputAndInfo.substring(0, index); - String info = inputAndInfo - .substring(index + VALUE_SEPARATOR.length()); - if (info == null || info.isEmpty()) - continue; - - String thumbnail = extractThumbnailFromOldInfo(info); - String thumbnailKey = THUMBNAIL_PREFIX; - boolean isPinned = isPinnedBasedOldInfo(info); - if (isPinned) { - String pinnedKey = PINNED_KEY_PREFIX + countForPinned; - thumbnailKey = THUMBNAIL_PREFIX + pinnedKey; - repository.setProperty(pinnedKey, input); - countForPinned++; - } else { - String unpinnedKey = KEY_PREFIX + countForUnpinned; - thumbnailKey = THUMBNAIL_PREFIX + unpinnedKey; - repository.setProperty(unpinnedKey, input); - countForUnpinned++; - } - - if (thumbnail != null && !thumbnail.isEmpty()) { - URI thumbnailURI = new File(thumbnail).toURI(); - repository.setProperty(thumbnailKey, - thumbnailURI.toString()); - } - } - } - - return repository; - - } - - private static String extractThumbnailFromOldInfo(String info) { - String thumbnail = info; - if (info != null) { - int sepPos = info.indexOf(','); - if (sepPos > 0) { - thumbnail = info.substring(0, sepPos); - } - } - return thumbnail; - } - - private static boolean isPinnedBasedOldInfo(String info) { - return info != null && info.endsWith(",favor"); //$NON-NLS-1$ - } - - private File getHistoryFile() { - if (basePath == null) - return null; - IPath filePath = basePath.append(FILE_NAME); - return filePath.toFile(); - } - - private File getOldHistoryFile() { - if (basePath == null) - return null; - IPath filePath = basePath.append(OLD_FILE_NAME); - return filePath.toFile(); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.core.runtime.IPath; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.editor.EditorHistoryItem; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; +import org.xmind.ui.editor.IEditorHistoryItem; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.util.Logger; + +/** + * @author Ren Siu + * @author Frank Shaka + * @since 3.6.50 + */ +public class EditorHistoryPersistenceHelper + implements IEditorHistoryLoader, IEditorHistoryListener { + + private static final String VALUE_SEPARATOR = "#$#"; //$NON-NLS-1$ + + private static final String KEY_PREFIX = "item."; //$NON-NLS-1$ + + private static final String PINNED_KEY_HISTORY_ITEM_PREFIX = "pinned.editor.history.item."; //$NON-NLS-1$ + + private static final String UNPINNED_KEY_HISTORY_ITEM_PREFIX = "unpinned.editor.history.item."; //$NON-NLS-1$ + + private static final String PINNED_KEY_PREFIX = "pinned.item."; //$NON-NLS-1$ + + private static final String THUMBNAIL_PREFIX = "thumbnail."; //$NON-NLS-1$ + + private static final String OLD_FILE_NAME = "workbookHistory.properties"; //$NON-NLS-1$ + + private static final String FILE_NAME = ".workbookHistory.properties"; //$NON-NLS-1$ + + private static final String THUMBNAIL_DIR_NAME = ".thumbnailHistory"; //$NON-NLS-1$ + + private static final Object END_OF_QUEUE = new Object(); + + private static class EditorHistoryState { + + private final URI[] unpinnedInputURIs; + private final URI[] pinnedInputURIs; + private final Map thumbnailURIs; + private final Map editorHistoryItems; + + /** + * + */ + private EditorHistoryState(EditorHistoryImpl service) { + this.unpinnedInputURIs = service + .getUnpinnedInputURIs(IEditorHistory.MAX_UNPINNED_SIZE); + this.pinnedInputURIs = service.getPinnedInputURIs(); + this.thumbnailURIs = new HashMap(); + this.editorHistoryItems = new HashMap(); + + for (URI uri : pinnedInputURIs) { + URI thumbnailURI = service.getThumbnail(uri); + if (thumbnailURI != null) { + thumbnailURIs.put(uri, thumbnailURI); + } + IEditorHistoryItem item = service.getItem(uri); + if (item != null) + editorHistoryItems.put(uri, item); + } + for (URI uri : unpinnedInputURIs) { + URI thumbnailURI = service.getThumbnail(uri); + if (thumbnailURI != null) { + thumbnailURIs.put(uri, thumbnailURI); + } + IEditorHistoryItem item = service.getItem(uri); + if (item != null) + editorHistoryItems.put(uri, item); + } + } + + /** + * @param service + * @return + */ + public static EditorHistoryState createFrom(EditorHistoryImpl service) { + return new EditorHistoryState(service); + } + + /** + * @return + */ + public URI[] getPinnedInputURIs() { + return pinnedInputURIs; + } + + /** + * @return + */ + public URI[] getUnpinnedInputURIs() { + return unpinnedInputURIs; + } + + /** + * @param input + * @return + */ + public URI getThumbnail(URI input) { + return thumbnailURIs.get(input); + } + + /** + * @param input + * @return + */ + public IEditorHistoryItem getEditorHistoryItem(URI input) { + return editorHistoryItems.get(input); + } + } + + private final IPath basePath; + + private final BlockingQueue stateQueue; + + private Thread thread; + + private EditorHistoryImpl service; + + /** + * + */ + public EditorHistoryPersistenceHelper(IPath basePath) { + this.basePath = basePath; + this.stateQueue = new LinkedBlockingQueue(); + this.thread = null; + this.service = null; + } + + public void setService(EditorHistoryImpl service) { + IEditorHistory oldService = this.service; + if (service == oldService) + return; + + this.service = service; + if (oldService != null) { + oldService.removeEditorHistoryListener(this); + } + if (service != null) { + service.addEditorHistoryListener(this); + } + + if (oldService == null && service != null) { + startThread(); + } else if (oldService != null && service == null) { + stopThread(); + } + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#load(org.xmind.ui. + * internal.editor.IEditorHistoryLoader.IEditorHistoryLoaderCallback) + */ + @Override + public void load(IEditorHistoryLoaderCallback callback) { + Properties historyRepository = load(); + for (int index = 0; index < historyRepository.size(); index++) { + String unpinnedKey = KEY_PREFIX + index; + String pinnedKey = PINNED_KEY_PREFIX + index; + String pinnedThumbnailKey = THUMBNAIL_PREFIX + pinnedKey; + String unpinnedThumbnailKey = THUMBNAIL_PREFIX + unpinnedKey; + String pinedEditorHistoryItemKey = PINNED_KEY_HISTORY_ITEM_PREFIX + + index; + String unPinedEditorHistoryItemKey = UNPINNED_KEY_HISTORY_ITEM_PREFIX + + index; + + String unpinnedInputURI = historyRepository + .getProperty(unpinnedKey); + String pinnedInputURI = historyRepository.getProperty(pinnedKey); + String unpinnedThumbnailURI = historyRepository + .getProperty(unpinnedThumbnailKey); + String pinnedThumbnailURI = historyRepository + .getProperty(pinnedThumbnailKey); + + unpinnedInputURI = fixFileUri(unpinnedInputURI); + pinnedInputURI = fixFileUri(pinnedInputURI); + unpinnedThumbnailURI = fixFileUri(unpinnedThumbnailURI); + pinnedThumbnailURI = fixFileUri(pinnedThumbnailURI); + + String pinedItemJson = historyRepository + .getProperty(pinedEditorHistoryItemKey); + IEditorHistoryItem pinnedItem = EditorHistoryItem + .readEditorHistoryItem(pinnedInputURI, pinedItemJson); + + String unpinedItemJson = historyRepository + .getProperty(unPinedEditorHistoryItemKey); + IEditorHistoryItem unpinedItem = EditorHistoryItem + .readEditorHistoryItem(unpinnedInputURI, unpinedItemJson); + + try { + if (unpinnedInputURI != null) { + URI unpinnedURI = new URI(unpinnedInputURI); + callback.inputURILoaded(unpinnedURI); + + if (unpinedItem != null) + callback.editorHistoryItemsLoaded(unpinnedURI, + unpinedItem); + + if (unpinnedThumbnailURI != null + && !unpinnedInputURI.isEmpty()) { + callback.thumbnailURILoaded(unpinnedURI, + new URI(unpinnedThumbnailURI)); + } + } + } catch (URISyntaxException e) { + } + + try { + if (pinnedInputURI != null) { + URI pinnedURI = new URI(pinnedInputURI); + callback.pinnedInputURILoaded(pinnedURI); + + if (pinnedItem != null) + callback.editorHistoryItemsLoaded(pinnedURI, + pinnedItem); + + if (pinnedThumbnailURI != null + && !pinnedInputURI.isEmpty()) { + callback.thumbnailURILoaded(pinnedURI, + new URI(pinnedThumbnailURI)); + } + } + } catch (URISyntaxException e) { + } + } + + } + + private String fixFileUri(String uri) { + if (uri != null && uri.startsWith("file:")) { //$NON-NLS-1$ + String specialPart = uri.substring(5); + boolean error = specialPart.startsWith("//") //$NON-NLS-1$ + && !specialPart.startsWith("///"); //$NON-NLS-1$ + if (error) { + return "file:" + "/" + specialPart; //$NON-NLS-1$ //$NON-NLS-2$ + } + } else if (uri != null && uri.startsWith("seawind:")) {//$NON-NLS-1$ + String specialPart = uri.substring(8); + boolean error = specialPart.startsWith("//") //$NON-NLS-1$ + && !specialPart.startsWith("///"); //$NON-NLS-1$ + if (error) { + return "seawind:" + "/" + specialPart; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + return uri; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.editor.IEditorHistoryLoader#saveThumbnail(java.io. + * InputStream) + */ + @Override + public URI saveThumbnail(InputStream thumbnailData) throws IOException { + File thumbnailDir = getThumbnailDir(); + if (thumbnailDir == null) + return null; + + if (!thumbnailDir.exists()) { + thumbnailDir.mkdirs(); + } + String thumbnailName = UUID.randomUUID().toString(); + File thumbnailFile = new File(thumbnailDir, thumbnailName); + + OutputStream output = new FileOutputStream(thumbnailFile); + try { + FileUtils.transfer(thumbnailData, output, false); + } finally { + output.close(); + } + + return thumbnailFile.toURI(); + } + + private File getThumbnailDir() { + IPath basePath = MindMapUIPlugin.getDefault().getStateLocation(); + if (basePath == null) + return null; + IPath filePath = basePath.append(THUMBNAIL_DIR_NAME); + return filePath.toFile(); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#dispose() + */ + @Override + public void dispose() { + setService(null); + } + + private void startThread() { + Thread thread = new Thread(new Runnable() { + public void run() { + runLoop(); + } + }); + thread.setName("EditorHistoryPersistenceThread"); //$NON-NLS-1$ + thread.setPriority(Thread.MIN_PRIORITY); + thread.setDaemon(true); + this.thread = thread; + thread.start(); + + /* + * Manually trigger a save operation on startup, for there might be some + * changes to editor history before this earlyStartup method is called. + * For example, files are opened on startup via double click in Finder. + */ + editorHistoryChanged(); + } + + private void stopThread() { + if (service != null) + service.removeEditorHistoryListener(this); + + stateQueue.offer(END_OF_QUEUE); + + Thread thread = this.thread; + this.thread = null; + if (thread != null) { + thread.interrupt(); + } + } + + public void editorHistoryChanged() { + if (service == null) + return; + + EditorHistoryState state = EditorHistoryState.createFrom(service); + stateQueue.offer(state); + } + + private void runLoop() { + try { + while (thread != null) { + Object state = stateQueue.take(); + if (state == END_OF_QUEUE) + break; + save((EditorHistoryState) state); + Thread.sleep(0); + } + } catch (InterruptedException e) { + // interruption means stop + } + } + + private void save(EditorHistoryState persistable) { + Properties repository = new Properties(); + + URI[] pinnedInputURIs = persistable.getPinnedInputURIs(); + URI[] unpinnedInputURIs = persistable.getUnpinnedInputURIs(); + + //Push pinned items + for (int index = 0; index < pinnedInputURIs.length; index++) { + URI input = pinnedInputURIs[index]; + if (input != null) { + String key = PINNED_KEY_PREFIX + index; + repository.setProperty(key, input.toString()); + + String pinnedEditorHistoryItemKey = PINNED_KEY_HISTORY_ITEM_PREFIX + + index; + IEditorHistoryItem pinnedItem = persistable + .getEditorHistoryItem(input); + if (pinnedItem != null) + repository.setProperty(pinnedEditorHistoryItemKey, + pinnedItem.toJson()); + + URI thumbnail = persistable.getThumbnail(input); + String thumbnailKey = THUMBNAIL_PREFIX + key; + if (thumbnail != null) + repository.setProperty(thumbnailKey, thumbnail.toString()); + } + } + + // Push unpinned items + for (int index = 0; index < unpinnedInputURIs.length; index++) { + URI input = unpinnedInputURIs[index]; + if (input != null) { + String key = KEY_PREFIX + index; + repository.setProperty(key, input.toString()); + + String unpinedEditorHistoryItemKey = UNPINNED_KEY_HISTORY_ITEM_PREFIX + + index; + IEditorHistoryItem unpinnedItem = persistable + .getEditorHistoryItem(input); + if (unpinnedItem != null) + repository.setProperty(unpinedEditorHistoryItemKey, + unpinnedItem.toJson()); + + URI thumbnail = persistable.getThumbnail(input); + String thumbnailKey = THUMBNAIL_PREFIX + key; + if (thumbnail != null) + repository.setProperty(thumbnailKey, thumbnail.toString()); + } + } + + // Save to properties file + File file = getHistoryFile(); + if (file != null) { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + try { + OutputStreamWriter out = new OutputStreamWriter( + new FileOutputStream(file), "UTF-8"); //$NON-NLS-1$ +// FileWriter writer = new FileWriter(file); + try { + repository.store(out, + "Generated by org.xmind.ui.internal.editor.EditorHistoryService"); //$NON-NLS-1$ + } finally { + out.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to save workbook history to " //$NON-NLS-1$ + + file.getAbsolutePath()); + } + } + + File oldHistoryFile = getOldHistoryFile(); + if (oldHistoryFile != null && oldHistoryFile.exists()) { + oldHistoryFile.delete(); + } + } + + public Properties load() { + Properties repository = new Properties(); + + // Load form properties file + File file = getHistoryFile(); + if (file != null && file.exists()) { + try { + InputStreamReader reader = new InputStreamReader( + new FileInputStream(file), "UTF-8"); //$NON-NLS-1$ +// FileReader reader = new FileReader(file); + try { + repository.load(reader); + } finally { + reader.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ + + file.getAbsolutePath()); + } + } else { + repository = loadOldHistoryRepository(); + } + + return repository; + } + + private Properties loadOldHistoryRepository() { + Properties repository = new Properties(); + + // Load form old properties file + File file = getOldHistoryFile(); + if (file != null && file.exists()) { + try { + FileReader reader = new FileReader(file); + try { + repository.load(reader); + } finally { + reader.close(); + } + } catch (IOException e) { + Logger.log(e, "Failed to load workbook history from " //$NON-NLS-1$ + + file.getAbsolutePath()); + } + int count = 0; + List items = new ArrayList(); + // Parse properties + int size = repository.size(); + for (int i = 0; i < size; i++) { + if (count >= IEditorHistory.MAX_UNPINNED_SIZE) + break; + + String key = KEY_PREFIX + i; + String value = repository.getProperty(key); + if (value == null) + continue; + items.add(value); + repository.remove(key); + + count++; + } + + //Compatible with the old version + Set oldVersionKeys = repository.keySet(); + for (Object key : oldVersionKeys) { + if (count >= IEditorHistory.MAX_UNPINNED_SIZE) + break; + + String input = (String) key; + String info = repository.getProperty(input); + + items.add(input + VALUE_SEPARATOR + info); + count++; + } + + //Transfer old format into new format + repository = new Properties(); + int countForPinned = 0; + int countForUnpinned = 0; + + for (String inputAndInfo : items) { + int index = inputAndInfo.indexOf(VALUE_SEPARATOR); + if (index < 0) + continue; + + String input = inputAndInfo.substring(0, index); + String info = inputAndInfo + .substring(index + VALUE_SEPARATOR.length()); + if (info == null || info.isEmpty()) + continue; + + String thumbnail = extractThumbnailFromOldInfo(info); + String thumbnailKey = THUMBNAIL_PREFIX; + boolean isPinned = isPinnedBasedOldInfo(info); + if (isPinned) { + String pinnedKey = PINNED_KEY_PREFIX + countForPinned; + thumbnailKey = THUMBNAIL_PREFIX + pinnedKey; + repository.setProperty(pinnedKey, input); + countForPinned++; + } else { + String unpinnedKey = KEY_PREFIX + countForUnpinned; + thumbnailKey = THUMBNAIL_PREFIX + unpinnedKey; + repository.setProperty(unpinnedKey, input); + countForUnpinned++; + } + + if (thumbnail != null && !thumbnail.isEmpty()) { + URI thumbnailURI = new File(thumbnail).toURI(); + repository.setProperty(thumbnailKey, + thumbnailURI.toString()); + } + } + } + + return repository; + + } + + private static String extractThumbnailFromOldInfo(String info) { + String thumbnail = info; + if (info != null) { + int sepPos = info.indexOf(','); + if (sepPos > 0) { + thumbnail = info.substring(0, sepPos); + } + } + return thumbnail; + } + + private static boolean isPinnedBasedOldInfo(String info) { + return info != null && info.endsWith(",favor"); //$NON-NLS-1$ + } + + private File getHistoryFile() { + if (basePath == null) + return null; + IPath filePath = basePath.append(FILE_NAME); + return filePath.toFile(); + } + + private File getOldHistoryFile() { + if (basePath == null) + return null; + IPath filePath = basePath.append(OLD_FILE_NAME); + return filePath.toFile(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryProxy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryProxy.java index 4d7d539c4..e8993ceef 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryProxy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorHistoryProxy.java @@ -1,94 +1,94 @@ -package org.xmind.ui.internal.editor; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -import org.eclipse.ui.services.IDisposable; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.IEditorHistoryItem; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class EditorHistoryProxy implements IEditorHistory, IDisposable { - - private IEditorHistory history; - - public EditorHistoryProxy(IEditorHistory history) { - this.history = history; - } - - public URI[] getRecentInputURIs(int unpinnedSize) { - return this.history.getRecentInputURIs(unpinnedSize); - } - - public URI[] getAllInputURIs() { - return this.history.getAllInputURIs(); - } - - public URI[] getPinnedInputURIs() { - return this.history.getPinnedInputURIs(); - } - - public URI[] getUnpinnedInputURIs(int unpinnedSize) { - return this.history.getUnpinnedInputURIs(unpinnedSize); - } - - public void add(URI inputURI) { - this.history.add(inputURI); - } - - public void remove(URI inputURI) { - this.history.remove(inputURI); - } - - public void clear() { - this.history.clear(); - } - - public InputStream loadThumbnailData(URI inputURI) throws IOException { - return this.history.loadThumbnailData(inputURI); - } - - public void saveThumbnailData(URI inputURI, InputStream thumbnailData) - throws IOException { - this.history.saveThumbnailData(inputURI, thumbnailData); - } - - @Override - public void add(URI uri, IEditorHistoryItem item) { - history.add(uri, item); - } - - @Override - public IEditorHistoryItem getItem(URI inputURI) { - return history.getItem(inputURI); - } - - public void pin(URI inputURI) { - this.history.pin(inputURI); - } - - public void unPin(URI inputURI) { - this.history.unPin(inputURI); - } - - public boolean isPinned(URI inputURI) { - return this.history.isPinned(inputURI); - } - - public void removeEditorHistoryListener(IEditorHistoryListener listener) { - this.history.removeEditorHistoryListener(listener); - } - - public void addEditorHistoryListener(IEditorHistoryListener listener) { - this.history.addEditorHistoryListener(listener); - } - - public void dispose() { - this.history = null; - } - -} +package org.xmind.ui.internal.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import org.eclipse.ui.services.IDisposable; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.IEditorHistoryItem; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class EditorHistoryProxy implements IEditorHistory, IDisposable { + + private IEditorHistory history; + + public EditorHistoryProxy(IEditorHistory history) { + this.history = history; + } + + public URI[] getRecentInputURIs(int unpinnedSize) { + return this.history.getRecentInputURIs(unpinnedSize); + } + + public URI[] getAllInputURIs() { + return this.history.getAllInputURIs(); + } + + public URI[] getPinnedInputURIs() { + return this.history.getPinnedInputURIs(); + } + + public URI[] getUnpinnedInputURIs(int unpinnedSize) { + return this.history.getUnpinnedInputURIs(unpinnedSize); + } + + public void add(URI inputURI) { + this.history.add(inputURI); + } + + public void remove(URI inputURI) { + this.history.remove(inputURI); + } + + public void clear() { + this.history.clear(); + } + + public InputStream loadThumbnailData(URI inputURI) throws IOException { + return this.history.loadThumbnailData(inputURI); + } + + public void saveThumbnailData(URI inputURI, InputStream thumbnailData) + throws IOException { + this.history.saveThumbnailData(inputURI, thumbnailData); + } + + @Override + public void add(URI uri, IEditorHistoryItem item) { + history.add(uri, item); + } + + @Override + public IEditorHistoryItem getItem(URI inputURI) { + return history.getItem(inputURI); + } + + public void pin(URI inputURI) { + this.history.pin(inputURI); + } + + public void unPin(URI inputURI) { + this.history.unPin(inputURI); + } + + public boolean isPinned(URI inputURI) { + return this.history.isPinned(inputURI); + } + + public void removeEditorHistoryListener(IEditorHistoryListener listener) { + this.history.removeEditorHistoryListener(listener); + } + + public void addEditorHistoryListener(IEditorHistoryListener listener) { + this.history.addEditorHistoryListener(listener); + } + + public void dispose() { + this.history = null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorInputMonitor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorInputMonitor.java index 5e246205c..a3c4b8e45 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorInputMonitor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorInputMonitor.java @@ -1,144 +1,144 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -/** - * @author Frank Shaka - * - */ -public class EditorInputMonitor { -//implements ShellListener, IPropertyListener { -// -// private IEditorPart editor; -// -// private Shell shell; -// -// private Boolean oldValue = null; -// -// /** -// * -// */ -// public EditorInputMonitor(IEditorPart editor) { -// this.editor = editor; -// this.editor.addPropertyListener(this); -// this.shell = editor.getSite().getShell(); -// if (shell != null && !shell.isDisposed()) { -// shell.addShellListener(this); -// } -// } -// -// public void dispose() { -// editor.removePropertyListener(this); -// if (shell != null) { -// if (!shell.isDisposed()) { -// shell.removeShellListener(this); -// } -// shell = null; -// } -// } -// -// /** -// * -// */ -// private void checkTarget() { -// if (oldValue == null) { -// recordOldValue(); -// } else { -// boolean newValue = willOverwriteTarget(); -// if (oldValue.booleanValue() != newValue) { -// addDirtyMarker(); -// oldValue = Boolean.valueOf(newValue); -// } -// } -// } -// -// private void addDirtyMarker() { -// IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); -// if (workbook instanceof ICoreEventSource2) { -// ((ICoreEventSource2) workbook).registerOnceCoreEventListener( -// Core.WorkbookPreSaveOnce, ICoreEventListener.NULL); -// } -// } -// -// /** -// * -// */ -// private void recordOldValue() { -// oldValue = Boolean.valueOf(willOverwriteTarget()); -// } -// -// private boolean willOverwriteTarget() { -// WorkbookRef ref = (WorkbookRef) editor.getAdapter(IWorkbookRef.class); -// return ref != null && ref.willOverwriteTarget(); -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events -// * .ShellEvent) -// */ -// public void shellActivated(ShellEvent e) { -// checkTarget(); -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events -// * .ShellEvent) -// */ -// public void shellClosed(ShellEvent e) { -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt -// * .events.ShellEvent) -// */ -// public void shellDeactivated(ShellEvent e) { -// recordOldValue(); -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt -// * .events.ShellEvent) -// */ -// public void shellDeiconified(ShellEvent e) { -// } -// -// /* -// * (non-Javadoc) -// * -// * @see -// * org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events -// * .ShellEvent) -// */ -// public void shellIconified(ShellEvent e) { -// } -// -// public void propertyChanged(Object source, int propId) { -// if (propId == IEditorPart.PROP_INPUT) { -// recordOldValue(); -// } -// } -// -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +/** + * @author Frank Shaka + * + */ +public class EditorInputMonitor { +//implements ShellListener, IPropertyListener { +// +// private IEditorPart editor; +// +// private Shell shell; +// +// private Boolean oldValue = null; +// +// /** +// * +// */ +// public EditorInputMonitor(IEditorPart editor) { +// this.editor = editor; +// this.editor.addPropertyListener(this); +// this.shell = editor.getSite().getShell(); +// if (shell != null && !shell.isDisposed()) { +// shell.addShellListener(this); +// } +// } +// +// public void dispose() { +// editor.removePropertyListener(this); +// if (shell != null) { +// if (!shell.isDisposed()) { +// shell.removeShellListener(this); +// } +// shell = null; +// } +// } +// +// /** +// * +// */ +// private void checkTarget() { +// if (oldValue == null) { +// recordOldValue(); +// } else { +// boolean newValue = willOverwriteTarget(); +// if (oldValue.booleanValue() != newValue) { +// addDirtyMarker(); +// oldValue = Boolean.valueOf(newValue); +// } +// } +// } +// +// private void addDirtyMarker() { +// IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); +// if (workbook instanceof ICoreEventSource2) { +// ((ICoreEventSource2) workbook).registerOnceCoreEventListener( +// Core.WorkbookPreSaveOnce, ICoreEventListener.NULL); +// } +// } +// +// /** +// * +// */ +// private void recordOldValue() { +// oldValue = Boolean.valueOf(willOverwriteTarget()); +// } +// +// private boolean willOverwriteTarget() { +// WorkbookRef ref = (WorkbookRef) editor.getAdapter(IWorkbookRef.class); +// return ref != null && ref.willOverwriteTarget(); +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events +// * .ShellEvent) +// */ +// public void shellActivated(ShellEvent e) { +// checkTarget(); +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events +// * .ShellEvent) +// */ +// public void shellClosed(ShellEvent e) { +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt +// * .events.ShellEvent) +// */ +// public void shellDeactivated(ShellEvent e) { +// recordOldValue(); +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt +// * .events.ShellEvent) +// */ +// public void shellDeiconified(ShellEvent e) { +// } +// +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events +// * .ShellEvent) +// */ +// public void shellIconified(ShellEvent e) { +// } +// +// public void propertyChanged(Object source, int propId) { +// if (propId == IEditorPart.PROP_INPUT) { +// recordOldValue(); +// } +// } +// +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorLayoutManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorLayoutManager.java index 60b6e7918..ef52c0c6a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorLayoutManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorLayoutManager.java @@ -1,43 +1,43 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; - -/** - * @author Jason Wong - */ -public class EditorLayoutManager implements IEditorLayoutManager { - - private Composite pageContainer; - - private IEditorLayout currentEditorLayout; - - public EditorLayoutManager(Composite pageContainer) { - this.pageContainer = pageContainer; - } - - @Override - public void setActiveLayout(IEditorLayout editorLayout) { - pageContainer.setRedraw(false); - if (currentEditorLayout != null) - currentEditorLayout.deactivate(pageContainer); - - currentEditorLayout = editorLayout; - currentEditorLayout.activate(pageContainer); - - pageContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT); - pageContainer.layout(); - pageContainer.setRedraw(true); - } - - @Override - public IEditorLayout getActiveLayout() { - return currentEditorLayout; - } - - @Override - public void restoreDefault() { - setActiveLayout(new DefaultEditorLayout()); - } - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; + +/** + * @author Jason Wong + */ +public class EditorLayoutManager implements IEditorLayoutManager { + + private Composite pageContainer; + + private IEditorLayout currentEditorLayout; + + public EditorLayoutManager(Composite pageContainer) { + this.pageContainer = pageContainer; + } + + @Override + public void setActiveLayout(IEditorLayout editorLayout) { + pageContainer.setRedraw(false); + if (currentEditorLayout != null) + currentEditorLayout.deactivate(pageContainer); + + currentEditorLayout = editorLayout; + currentEditorLayout.activate(pageContainer); + + pageContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT); + pageContainer.layout(); + pageContainer.setRedraw(true); + } + + @Override + public IEditorLayout getActiveLayout() { + return currentEditorLayout; + } + + @Override + public void restoreDefault() { + setActiveLayout(new DefaultEditorLayout()); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDailogPane.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDailogPane.java index 9183acb6b..729ea66d3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDailogPane.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDailogPane.java @@ -1,411 +1,411 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -public class EncryptionDailogPane extends DialogPane { - - private Text oldPasswordInputBox; - - private Text newPasswordInputBox; - - private Text verifyNewPasswordInputBox; - - private Label oldPasswordVerificationLabel; - - private Label newPasswordVerificationLabel; - - private Image doneIcon; - - private Image undoneIcon; - - private Image blankIcon; - - private String password; - - private Image getDoneIcon() { - if (getContainer() == null || getContainer().isDisposed()) - return null; - if (doneIcon == null || doneIcon.isDisposed()) { - ImageDescriptor img = MindMapUI.getImages().get(IMindMapImages.DONE, - true); - if (img != null) { - doneIcon = img.createImage(getContainer().getDisplay()); - } - } - return doneIcon; - } - - private Image getUndoneIcon() { - if (getContainer() == null || getContainer().isDisposed()) - return null; - if (undoneIcon == null || undoneIcon.isDisposed()) { - ImageDescriptor img = MindMapUI.getImages().get(IMindMapImages.DONE, - false); - if (img != null) { - undoneIcon = img.createImage(getContainer().getDisplay()); - } - } - return undoneIcon; - } - - private Image getBlankIcon() { - if (getContainer() == null || getContainer().isDisposed()) - return null; - if (blankIcon == null || blankIcon.isDisposed()) { - ImageDescriptor img = MindMapUI.getImages() - .get(IMindMapImages.BLANK); - if (img != null) { - blankIcon = img.createImage(getContainer().getDisplay()); - } - } - return blankIcon; - } - - @Override - public void dispose() { - if (doneIcon != null) { - doneIcon.dispose(); - doneIcon = null; - } - if (blankIcon != null) { - blankIcon.dispose(); - blankIcon = null; - } - super.dispose(); - } - - @Override - protected Control createDialogContents(Composite parent) { - Composite composite = (Composite) super.createDialogContents(parent); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createMessageArea(composite); - createPasswordArea(composite); - - verify(); - - return composite; - } - - private void createMessageArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - area.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - area.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 10; - area.setLayout(gridLayout); - - createMessageIcon(area); - createMessageBoard(area); - } - - private void createMessageIcon(Composite parent) { - Label iconLabel = new Label(parent, SWT.NONE); - iconLabel.setBackground(parent.getBackground()); - iconLabel.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - Image image = getMessageIcon(iconLabel); - iconLabel.setImage(image); - } - - private Image getMessageIcon(Control control) { - if (control == null) - return null; - ImageDescriptor image = MindMapUI.getImages().get(IMindMapImages.LOCK, - true); - if (image != null) - return image.createImage(control.getDisplay()); - return null; - } - - private void createMessageBoard(Composite parent) { - Text messageBoard = new Text(parent, - SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); - messageBoard.setBackground(parent.getBackground()); - applyFont(messageBoard); - - GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - messageBoard.setLayoutData(gridData); - messageBoard.setText(MindMapMessages.EncryptDialogPane_board_message); - } - - private void createPasswordArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - area.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - area.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(3, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 5; - gridLayout.horizontalSpacing = 3; - area.setLayout(gridLayout); - - if (hasPassword()) { - createOldPasswordInputBox(area); - } - - createNewPasswordInputBox(area); - createVerifyPasswordInputBox(area); - - Listener verifyListener = new Listener() { - public void handleEvent(Event event) { - verify(); - } - }; - if (oldPasswordInputBox != null) { - oldPasswordInputBox.addListener(SWT.Modify, verifyListener); - } - newPasswordInputBox.addListener(SWT.Modify, verifyListener); - verifyNewPasswordInputBox.addListener(SWT.Modify, verifyListener); - - } - - private void createOldPasswordInputBox(Composite parent) { - Label assistMessageBox = new Label(parent, SWT.WRAP); - assistMessageBox.setBackground(parent.getBackground()); - assistMessageBox.setLayoutData( - new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - ((GridData) assistMessageBox.getLayoutData()).horizontalSpan = 3; - assistMessageBox - .setText(MindMapMessages.EncryptDialogPane_assist_message); - - Label label = new Label(parent, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - label.setText(MindMapMessages.EncryptDialogPane_oldpassword_text); - label.setBackground(parent.getBackground()); - applyFont(label); - - oldPasswordInputBox = new Text(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); - applyFont(oldPasswordInputBox); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - oldPasswordInputBox.setLayoutData(gridData); - - hookText(oldPasswordInputBox); - addRefreshDefaultButtonListener(oldPasswordInputBox); - addTriggerDefaultButtonListener(oldPasswordInputBox, - SWT.DefaultSelection); - - oldPasswordVerificationLabel = new Label(parent, SWT.NONE); - oldPasswordVerificationLabel.setBackground(parent.getBackground()); - oldPasswordVerificationLabel - .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - oldPasswordVerificationLabel.setImage(getDoneIcon()); - - Label sep = new Label(parent, SWT.NONE); - sep.setBackground(parent.getBackground()); - sep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - ((GridData) sep.getLayoutData()).horizontalSpan = 3; - } - - private void createNewPasswordInputBox(Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - String text; - if (oldPasswordInputBox == null) { - text = MindMapMessages.EncryptDialogPane_password_text; - } else { - text = MindMapMessages.EncryptDialogPane_newpassword_text; - } - label.setText(text); - label.setBackground(parent.getBackground()); - applyFont(label); - - newPasswordInputBox = new Text(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); - applyFont(newPasswordInputBox); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - newPasswordInputBox.setLayoutData(gridData); - - hookText(newPasswordInputBox); - addRefreshDefaultButtonListener(newPasswordInputBox); - addTriggerDefaultButtonListener(newPasswordInputBox, - SWT.DefaultSelection); - - Label blankIcon = new Label(parent, SWT.NONE); - blankIcon.setBackground(parent.getBackground()); - blankIcon - .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - blankIcon.setImage(getBlankIcon()); - } - - private void createVerifyPasswordInputBox(Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setLayoutData( - new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - label.setText(MindMapMessages.EncryptDialogPane_confirm_text); - label.setBackground(parent.getBackground()); - applyFont(label); - - verifyNewPasswordInputBox = new Text(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); - applyFont(verifyNewPasswordInputBox); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - verifyNewPasswordInputBox.setLayoutData(gridData); - - hookText(verifyNewPasswordInputBox); - addRefreshDefaultButtonListener(verifyNewPasswordInputBox); - addTriggerDefaultButtonListener(verifyNewPasswordInputBox, - SWT.DefaultSelection); - - newPasswordVerificationLabel = new Label(parent, SWT.NONE); - newPasswordVerificationLabel.setBackground(parent.getBackground()); - newPasswordVerificationLabel - .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - newPasswordVerificationLabel.setImage(getDoneIcon()); - } - - @Override - protected void createButtonsForButtonBar(Composite buttonBar) { - createButton(buttonBar, IDialogConstants.OK_ID, - IDialogConstants.OK_LABEL, true); - createButton(buttonBar, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - setOKButtonEnabled(false); - } - - private void setOKButtonEnabled(boolean enabled) { - Button button = getButton(IDialogConstants.OK_ID); - if (button != null && !button.isDisposed()) { - button.setEnabled(enabled); - } - } - - private void verify() { - boolean oldPasswordVerified = false; - if (!hasPassword()) { - oldPasswordVerified = !"".equals(newPasswordInputBox.getText()); //$NON-NLS-1$ - } else if (oldPasswordInputBox != null) { - oldPasswordVerified = testsPassword(oldPasswordInputBox.getText()); - oldPasswordVerificationLabel.setImage( - oldPasswordVerified ? getDoneIcon() : getUndoneIcon()); - } - boolean newPasswordVerified = ((oldPasswordInputBox != null // - || !"".equals(newPasswordInputBox.getText()))) //$NON-NLS-1$ - && newPasswordInputBox.getText() - .equals(verifyNewPasswordInputBox.getText()); - newPasswordVerificationLabel.setImage( - newPasswordVerified ? getDoneIcon() : getUndoneIcon()); - setOKButtonEnabled(oldPasswordVerified && newPasswordVerified); - } - - @Override - protected boolean okPressed() { - setPassword(newPasswordInputBox.getText()); - setReturnCode(OK); - close(); -// Display.getCurrent().asyncExec(new Runnable() { -// public void run() { -// if (EncryptionDailogPane.this.editor.parent == null -// || EncryptionDailogPane.this.editor.parent.isDisposed()) -// return; -// -// EncryptionDailogPane.this.editor -// .doSave(new NullProgressMonitor()); -// } -// }); - return true; - } - - protected void setPassword(String newPassword) { - if ("".equals(newPassword)) { //$NON-NLS-1$ - newPassword = null; - } - this.password = newPassword; - } - - @Override - protected boolean cancelPressed() { - setReturnCode(CANCEL); - close(); - return true; - } - -// private void close() { -// editor.backCover.hideEncryptionDialog(); -// editor.hideBackCover(); -// } -// - @Override - public void setFocus() { - if (oldPasswordInputBox != null && !oldPasswordInputBox.isDisposed()) { - oldPasswordInputBox.setFocus(); - } else if (newPasswordInputBox != null - && !newPasswordInputBox.isDisposed()) { - newPasswordInputBox.setFocus(); - } - } - - protected String getPassword() { - return this.password; - } - - protected boolean hasPassword() { - return false; - } - - protected boolean testsPassword(String password) { - return false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +public class EncryptionDailogPane extends DialogPane { + + private Text oldPasswordInputBox; + + private Text newPasswordInputBox; + + private Text verifyNewPasswordInputBox; + + private Label oldPasswordVerificationLabel; + + private Label newPasswordVerificationLabel; + + private Image doneIcon; + + private Image undoneIcon; + + private Image blankIcon; + + private String password; + + private Image getDoneIcon() { + if (getContainer() == null || getContainer().isDisposed()) + return null; + if (doneIcon == null || doneIcon.isDisposed()) { + ImageDescriptor img = MindMapUI.getImages().get(IMindMapImages.DONE, + true); + if (img != null) { + doneIcon = img.createImage(getContainer().getDisplay()); + } + } + return doneIcon; + } + + private Image getUndoneIcon() { + if (getContainer() == null || getContainer().isDisposed()) + return null; + if (undoneIcon == null || undoneIcon.isDisposed()) { + ImageDescriptor img = MindMapUI.getImages().get(IMindMapImages.DONE, + false); + if (img != null) { + undoneIcon = img.createImage(getContainer().getDisplay()); + } + } + return undoneIcon; + } + + private Image getBlankIcon() { + if (getContainer() == null || getContainer().isDisposed()) + return null; + if (blankIcon == null || blankIcon.isDisposed()) { + ImageDescriptor img = MindMapUI.getImages() + .get(IMindMapImages.BLANK); + if (img != null) { + blankIcon = img.createImage(getContainer().getDisplay()); + } + } + return blankIcon; + } + + @Override + public void dispose() { + if (doneIcon != null) { + doneIcon.dispose(); + doneIcon = null; + } + if (blankIcon != null) { + blankIcon.dispose(); + blankIcon = null; + } + super.dispose(); + } + + @Override + protected Control createDialogContents(Composite parent) { + Composite composite = (Composite) super.createDialogContents(parent); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createMessageArea(composite); + createPasswordArea(composite); + + verify(); + + return composite; + } + + private void createMessageArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + area.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + area.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 10; + area.setLayout(gridLayout); + + createMessageIcon(area); + createMessageBoard(area); + } + + private void createMessageIcon(Composite parent) { + Label iconLabel = new Label(parent, SWT.NONE); + iconLabel.setBackground(parent.getBackground()); + iconLabel.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + Image image = getMessageIcon(iconLabel); + iconLabel.setImage(image); + } + + private Image getMessageIcon(Control control) { + if (control == null) + return null; + ImageDescriptor image = MindMapUI.getImages().get(IMindMapImages.LOCK, + true); + if (image != null) + return image.createImage(control.getDisplay()); + return null; + } + + private void createMessageBoard(Composite parent) { + Text messageBoard = new Text(parent, + SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); + messageBoard.setBackground(parent.getBackground()); + applyFont(messageBoard); + + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + messageBoard.setLayoutData(gridData); + messageBoard.setText(MindMapMessages.EncryptDialogPane_board_message); + } + + private void createPasswordArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + area.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + area.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(3, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 5; + gridLayout.horizontalSpacing = 3; + area.setLayout(gridLayout); + + if (hasPassword()) { + createOldPasswordInputBox(area); + } + + createNewPasswordInputBox(area); + createVerifyPasswordInputBox(area); + + Listener verifyListener = new Listener() { + public void handleEvent(Event event) { + verify(); + } + }; + if (oldPasswordInputBox != null) { + oldPasswordInputBox.addListener(SWT.Modify, verifyListener); + } + newPasswordInputBox.addListener(SWT.Modify, verifyListener); + verifyNewPasswordInputBox.addListener(SWT.Modify, verifyListener); + + } + + private void createOldPasswordInputBox(Composite parent) { + Label assistMessageBox = new Label(parent, SWT.WRAP); + assistMessageBox.setBackground(parent.getBackground()); + assistMessageBox.setLayoutData( + new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + ((GridData) assistMessageBox.getLayoutData()).horizontalSpan = 3; + assistMessageBox + .setText(MindMapMessages.EncryptDialogPane_assist_message); + + Label label = new Label(parent, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + label.setText(MindMapMessages.EncryptDialogPane_oldpassword_text); + label.setBackground(parent.getBackground()); + applyFont(label); + + oldPasswordInputBox = new Text(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); + applyFont(oldPasswordInputBox); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + oldPasswordInputBox.setLayoutData(gridData); + + hookText(oldPasswordInputBox); + addRefreshDefaultButtonListener(oldPasswordInputBox); + addTriggerDefaultButtonListener(oldPasswordInputBox, + SWT.DefaultSelection); + + oldPasswordVerificationLabel = new Label(parent, SWT.NONE); + oldPasswordVerificationLabel.setBackground(parent.getBackground()); + oldPasswordVerificationLabel + .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + oldPasswordVerificationLabel.setImage(getDoneIcon()); + + Label sep = new Label(parent, SWT.NONE); + sep.setBackground(parent.getBackground()); + sep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ((GridData) sep.getLayoutData()).horizontalSpan = 3; + } + + private void createNewPasswordInputBox(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + String text; + if (oldPasswordInputBox == null) { + text = MindMapMessages.EncryptDialogPane_password_text; + } else { + text = MindMapMessages.EncryptDialogPane_newpassword_text; + } + label.setText(text); + label.setBackground(parent.getBackground()); + applyFont(label); + + newPasswordInputBox = new Text(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); + applyFont(newPasswordInputBox); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + newPasswordInputBox.setLayoutData(gridData); + + hookText(newPasswordInputBox); + addRefreshDefaultButtonListener(newPasswordInputBox); + addTriggerDefaultButtonListener(newPasswordInputBox, + SWT.DefaultSelection); + + Label blankIcon = new Label(parent, SWT.NONE); + blankIcon.setBackground(parent.getBackground()); + blankIcon + .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + blankIcon.setImage(getBlankIcon()); + } + + private void createVerifyPasswordInputBox(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + label.setText(MindMapMessages.EncryptDialogPane_confirm_text); + label.setBackground(parent.getBackground()); + applyFont(label); + + verifyNewPasswordInputBox = new Text(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE); + applyFont(verifyNewPasswordInputBox); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + verifyNewPasswordInputBox.setLayoutData(gridData); + + hookText(verifyNewPasswordInputBox); + addRefreshDefaultButtonListener(verifyNewPasswordInputBox); + addTriggerDefaultButtonListener(verifyNewPasswordInputBox, + SWT.DefaultSelection); + + newPasswordVerificationLabel = new Label(parent, SWT.NONE); + newPasswordVerificationLabel.setBackground(parent.getBackground()); + newPasswordVerificationLabel + .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + newPasswordVerificationLabel.setImage(getDoneIcon()); + } + + @Override + protected void createButtonsForButtonBar(Composite buttonBar) { + createButton(buttonBar, IDialogConstants.OK_ID, + IDialogConstants.OK_LABEL, true); + createButton(buttonBar, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + setOKButtonEnabled(false); + } + + private void setOKButtonEnabled(boolean enabled) { + Button button = getButton(IDialogConstants.OK_ID); + if (button != null && !button.isDisposed()) { + button.setEnabled(enabled); + } + } + + private void verify() { + boolean oldPasswordVerified = false; + if (!hasPassword()) { + oldPasswordVerified = !"".equals(newPasswordInputBox.getText()); //$NON-NLS-1$ + } else if (oldPasswordInputBox != null) { + oldPasswordVerified = testsPassword(oldPasswordInputBox.getText()); + oldPasswordVerificationLabel.setImage( + oldPasswordVerified ? getDoneIcon() : getUndoneIcon()); + } + boolean newPasswordVerified = ((oldPasswordInputBox != null // + || !"".equals(newPasswordInputBox.getText()))) //$NON-NLS-1$ + && newPasswordInputBox.getText() + .equals(verifyNewPasswordInputBox.getText()); + newPasswordVerificationLabel.setImage( + newPasswordVerified ? getDoneIcon() : getUndoneIcon()); + setOKButtonEnabled(oldPasswordVerified && newPasswordVerified); + } + + @Override + protected boolean okPressed() { + setPassword(newPasswordInputBox.getText()); + setReturnCode(OK); + close(); +// Display.getCurrent().asyncExec(new Runnable() { +// public void run() { +// if (EncryptionDailogPane.this.editor.parent == null +// || EncryptionDailogPane.this.editor.parent.isDisposed()) +// return; +// +// EncryptionDailogPane.this.editor +// .doSave(new NullProgressMonitor()); +// } +// }); + return true; + } + + protected void setPassword(String newPassword) { + if ("".equals(newPassword)) { //$NON-NLS-1$ + newPassword = null; + } + this.password = newPassword; + } + + @Override + protected boolean cancelPressed() { + setReturnCode(CANCEL); + close(); + return true; + } + +// private void close() { +// editor.backCover.hideEncryptionDialog(); +// editor.hideBackCover(); +// } +// + @Override + public void setFocus() { + if (oldPasswordInputBox != null && !oldPasswordInputBox.isDisposed()) { + oldPasswordInputBox.setFocus(); + } else if (newPasswordInputBox != null + && !newPasswordInputBox.isDisposed()) { + newPasswordInputBox.setFocus(); + } + } + + protected String getPassword() { + return this.password; + } + + protected boolean hasPassword() { + return false; + } + + protected boolean testsPassword(String password) { + return false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDialog.java index 44c33aea5..b6befbd64 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDialog.java @@ -1,464 +1,470 @@ -package org.xmind.ui.internal.editor; - -import java.util.Map; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; - -public class EncryptionDialog extends TitleAreaDialog { - - private static final String DEFAULT_BUTTON_TRIGGER_EVENT_ID = "DEFAULT_BUTTON_TRIGGER_EVENT_ID"; //$NON-NLS-1$ - - private int defaultButtonId = -1; - - private Map buttons; - - private Text oldPasswordInputBox; - - private Text newPasswordInputBox; - - private Text verifyNewPasswordInputBox; - - private Text hintPasswordInputBox; - - private Label oldPasswordVerificationLabel; - - private Label newPasswordVerificationLabel; - - private Label warningLabel; - - private Composite container; - - private Image doneIcon; - - private String password; - - private String hintMessage; - - private Listener defaultButtonListener; - - protected EncryptionDialog(Shell parentShell) { - super(parentShell); - } - - private Image getErrorIcon() { - if (getContainer() == null || getContainer().isDisposed()) - return null; - if (doneIcon == null || doneIcon.isDisposed()) { - ImageDescriptor img = MindMapUI.getImages() - .get(IMindMapImages.WARNING_ICON); - if (img != null) { - doneIcon = img.createImage(getContainer().getDisplay()); - } - } - return doneIcon; - } - - @Override - protected Point getInitialSize() { - return new Point(400, 300); - } - - @Override - public void create() { - super.create(); - - setTitle(hasPassword() - ? MindMapMessages.EncrptionDialog_ChangePassword_title - : MindMapMessages.EncryptionDialog_SetPassword_title); - - setTitleImage(null); - - setMessage(hasPassword() - ? MindMapMessages.EncryptionDialog_ChangePassword_message - : MindMapMessages.EncryptionDialog_SetPassword_message); - } - - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - composite.setFont(parent.getFont()); - - this.container = composite; - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 20; - gridLayout.marginHeight = 20; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createPasswordArea(composite); - - checkSetButton(); - - return composite; - } - - private Composite createPasswordArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - area.setBackground(parent.getBackground()); - - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - area.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(3, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 5; - gridLayout.horizontalSpacing = 3; - area.setLayout(gridLayout); - - if (hasPassword()) { - createOldPasswordInputBox(area); - } - - createNewPasswordInputBox(area); - createVerifyPasswordInputBox(area); - createHintPasswordInputBox(area); - - createErrorMessage(area); - - Listener verifyListener = new Listener() { - public void handleEvent(Event event) { - checkSetButton(); - } - }; - if (oldPasswordInputBox != null) { - oldPasswordInputBox.addListener(SWT.Modify, verifyListener); - } - newPasswordInputBox.addListener(SWT.Modify, verifyListener); - verifyNewPasswordInputBox.addListener(SWT.Modify, verifyListener); - - return area; - } - - private void createErrorMessage(Composite parent) { - new Label(parent, SWT.NONE); - - warningLabel = new Label(parent, SWT.NONE); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = 200; - gridData.heightHint = SWT.DEFAULT; - warningLabel.setLayoutData(gridData); - warningLabel.setForeground( - Display.getCurrent().getSystemColor(SWT.COLOR_RED)); - - new Label(parent, SWT.NONE); - } - - private void createOldPasswordInputBox(Composite parent) { - createInputLabel(parent, - MindMapMessages.EncryptDialogPane_oldpassword_text); - - oldPasswordInputBox = createInput(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); - - hookText(oldPasswordInputBox); - addRefreshDefaultButtonListener(oldPasswordInputBox); - addTriggerDefaultButtonListener(oldPasswordInputBox, - SWT.DefaultSelection); - - oldPasswordVerificationLabel = new Label(parent, SWT.NONE); - oldPasswordVerificationLabel.setBackground(parent.getBackground()); - oldPasswordVerificationLabel - .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - oldPasswordVerificationLabel.setImage(getErrorIcon()); - oldPasswordVerificationLabel.setVisible(false); - } - - private void createNewPasswordInputBox(Composite parent) { - String text; - if (oldPasswordInputBox == null) { - text = MindMapMessages.EncryptDialogPane_password_text; - } else { - text = MindMapMessages.EncryptDialogPane_newpassword_text; - } - createInputLabel(parent, text); - - newPasswordInputBox = createInput(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); - - hookText(newPasswordInputBox); - addRefreshDefaultButtonListener(newPasswordInputBox); - addTriggerDefaultButtonListener(newPasswordInputBox, - SWT.DefaultSelection); - - new Label(parent, SWT.NONE); - } - - private void createVerifyPasswordInputBox(Composite parent) { - createInputLabel(parent, - MindMapMessages.EncryptDialogPane_confirm_text); - - verifyNewPasswordInputBox = createInput(parent, - SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); - - hookText(verifyNewPasswordInputBox); - addRefreshDefaultButtonListener(verifyNewPasswordInputBox); - addTriggerDefaultButtonListener(verifyNewPasswordInputBox, - SWT.DefaultSelection); - - newPasswordVerificationLabel = new Label(parent, SWT.NONE); - newPasswordVerificationLabel.setBackground(parent.getBackground()); - newPasswordVerificationLabel - .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - newPasswordVerificationLabel.setImage(getErrorIcon()); - newPasswordVerificationLabel.setVisible(false); - } - - private void createHintPasswordInputBox(Composite parent) { - createInputLabel(parent, NLS.bind( - MindMapMessages.EncryptionDialog_HintInput_label, " \n ")); //$NON-NLS-1$ - - hintPasswordInputBox = createInput(parent, SWT.BORDER | SWT.WRAP, 50); - - new Label(parent, SWT.NONE); - - hookText(hintPasswordInputBox); - } - - private Label createInputLabel(Composite parent, String text) { - Label label = new Label(parent, SWT.NONE); - label.setText(text); - label.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - label.setBackground(parent.getBackground()); - return label; - } - - private Text createInput(Composite parent, int style, int height) { - Text input = new Text(parent, style); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.minimumWidth = 200; - gridData.widthHint = 200; - gridData.heightHint = height; - input.setLayoutData(gridData); - - return input; - } - - private Composite getContainer() { - return container; - } - - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(MindMapMessages.EncryptionDialog_SetPassword_title); - } - - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, - MindMapMessages.EncryptionDialog_ButtonBar_Set_button, true); - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - setSetButtonEnabled(false); - } - - private void setSetButtonEnabled(boolean enabled) { - Button button = getButton(IDialogConstants.OK_ID); - if (button != null && !button.isDisposed()) { - button.setEnabled(enabled); - } - } - - private void checkSetButton() { - if (oldPasswordInputBox == null) { - setSetButtonEnabled(!"".equals(newPasswordInputBox.getText()) //$NON-NLS-1$ - && !"".equals(verifyNewPasswordInputBox.getText())); //$NON-NLS-1$ - } else { - setSetButtonEnabled(!"".equals(oldPasswordInputBox.getText())); //$NON-NLS-1$ - } - } - - protected void addRefreshDefaultButtonListener(final Control focusControl) { - focusControl.addListener(SWT.FocusIn, getDefaultButtonListener()); - focusControl.addListener(SWT.FocusOut, getDefaultButtonListener()); - } - - protected void addTriggerDefaultButtonListener(Control control, - int triggerEvent) { - control.addListener(triggerEvent, getDefaultButtonListener()); - control.setData(DEFAULT_BUTTON_TRIGGER_EVENT_ID, - Integer.valueOf(triggerEvent)); - } - - private Listener getDefaultButtonListener() { - if (defaultButtonListener == null) { - defaultButtonListener = new Listener() { - - private Button savedDefaultButton = null; - - public void handleEvent(Event event) { - Object triggerEvent = event.widget - .getData(DEFAULT_BUTTON_TRIGGER_EVENT_ID); - if (triggerEvent instanceof Integer - && event.type == ((Integer) triggerEvent) - .intValue()) { - triggerDefaultButton(); - return; - } - - if (event.type == SWT.FocusIn) { - changeDefaultButton(); - } else if (event.type == SWT.FocusOut) { - restoreDefaultButton(); - } - } - - private void restoreDefaultButton() { - if (defaultButtonId >= 0) { - Shell shell = container.getShell(); - if (savedDefaultButton != null - && savedDefaultButton.isDisposed()) { - savedDefaultButton = null; - } - shell.setDefaultButton(savedDefaultButton); - } - } - - private void changeDefaultButton() { - if (defaultButtonId >= 0) { - final Shell shell = container.getShell(); - savedDefaultButton = shell.getDefaultButton(); - shell.getDisplay().asyncExec(new Runnable() { - public void run() { - Button button = getButton(defaultButtonId); - if (button != null && !button.isDisposed()) { - shell.setDefaultButton(button); - } - } - }); - } - } - }; - } - return defaultButtonListener; - } - - protected Button getDefaultButton() { - if (buttons != null && defaultButtonId >= 0) { - return getButton(defaultButtonId); - } - return null; - } - - protected void triggerDefaultButton() { - triggerButton(defaultButtonId); - } - - protected void triggerButton(int buttonId) { - if (buttonId >= 0) { - Button button = getButton(buttonId); - if (button != null && !button.isDisposed() && button.isEnabled()) { - buttonPressed(buttonId); - } - } - } - - protected void okPressed() { - if (!verify()) { - warningLabel.setText(verifyOldPassword() - ? MindMapMessages.EncryptionDialog_Warning_NotMatch_label - : MindMapMessages.EncryptionDialog_Warning_NotCorrect_label); - return; - } - setPassword(newPasswordInputBox.getText()); - setHintMessage(hintPasswordInputBox.getText()); - super.okPressed(); - } - - private boolean verifyOldPassword() { - boolean oldPasswordVerified = false; - if (!hasPassword()) { - oldPasswordVerified = !"".equals(newPasswordInputBox.getText()); //$NON-NLS-1$ - } else if (oldPasswordInputBox != null) { - oldPasswordVerified = testsPassword(oldPasswordInputBox.getText()); - oldPasswordVerificationLabel.setVisible(!oldPasswordVerified); - } - newPasswordVerificationLabel.setVisible(oldPasswordVerified); - return oldPasswordVerified; - } - - private boolean verifyNewPassword() { - boolean newPasswordVerified = ((oldPasswordInputBox != null // - || !"".equals(newPasswordInputBox.getText()))) //$NON-NLS-1$ - && newPasswordInputBox.getText() - .equals(verifyNewPasswordInputBox.getText()); - newPasswordVerificationLabel.setVisible(!newPasswordVerified); - return newPasswordVerified; - } - - protected boolean verify() { - return verifyOldPassword() && verifyNewPassword(); - } - - protected void setPassword(String newPassword) { - if (verify()) { - if ("".equals(newPassword)) { //$NON-NLS-1$ - newPassword = null; - } - this.password = newPassword; - } - } - - protected String getPassword() { - return this.password; - } - - protected boolean hasPassword() { - return false; - } - - protected boolean testsPassword(String password) { - return false; - } - - protected void setHintMessage(String hintMessage) { - if (verify()) { - if ("".equals(hintMessage)) //$NON-NLS-1$ - hintMessage = null; - - this.hintMessage = hintMessage; - } - } - - protected String getHintMessage() { - return hintMessage; - } - - private void hookText(final Text text) { - text.addListener(SWT.FocusIn, new Listener() { - public void handleEvent(Event event) { - text.selectAll(); - } - }); - } - -} +package org.xmind.ui.internal.editor; + +import java.util.Map; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +public class EncryptionDialog extends TitleAreaDialog { + + private static final String DEFAULT_BUTTON_TRIGGER_EVENT_ID = "DEFAULT_BUTTON_TRIGGER_EVENT_ID"; //$NON-NLS-1$ + + private int defaultButtonId = -1; + + private Map buttons; + + private Text oldPasswordInputBox; + + private Text newPasswordInputBox; + + private Text verifyNewPasswordInputBox; + + private Text hintPasswordInputBox; + + private Label oldPasswordVerificationLabel; + + private Label newPasswordVerificationLabel; + + private Label warningLabel; + + private Composite container; + + private Image doneIcon; + + private String password; + + private String hintMessage; + + private Listener defaultButtonListener; + + protected EncryptionDialog(Shell parentShell) { + super(parentShell); + } + + private Image getErrorIcon() { + if (getContainer() == null || getContainer().isDisposed()) + return null; + if (doneIcon == null || doneIcon.isDisposed()) { + ImageDescriptor img = MindMapUI.getImages() + .get(IMindMapImages.WARNING_ICON); + if (img != null) { + doneIcon = img.createImage(getContainer().getDisplay()); + } + } + return doneIcon; + } + + @Override + protected Point getInitialSize() { + return new Point(400, 300); + } + + @Override + public void create() { + super.create(); + + setTitle(hasPassword() + ? MindMapMessages.EncrptionDialog_ChangePassword_title + : MindMapMessages.EncryptionDialog_SetPassword_title); + + setTitleImage(null); + + setMessage(hasPassword() + ? MindMapMessages.EncryptionDialog_ChangePassword_message + : MindMapMessages.EncryptionDialog_SetPassword_message); + } + + protected Control createDialogArea(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setFont(parent.getFont()); + + this.container = composite; + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 20; + gridLayout.marginHeight = 20; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createPasswordArea(composite); + + checkSetButton(); + + return composite; + } + + private Composite createPasswordArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + area.setBackground(parent.getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + area.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(3, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 5; + gridLayout.horizontalSpacing = 3; + area.setLayout(gridLayout); + + if (hasPassword()) { + createOldPasswordInputBox(area); + } + + createNewPasswordInputBox(area); + createVerifyPasswordInputBox(area); + createHintPasswordInputBox(area); + + createErrorMessage(area); + + Listener verifyListener = new Listener() { + public void handleEvent(Event event) { + checkSetButton(); + } + }; + if (oldPasswordInputBox != null) { + oldPasswordInputBox.addListener(SWT.Modify, verifyListener); + } + newPasswordInputBox.addListener(SWT.Modify, verifyListener); + verifyNewPasswordInputBox.addListener(SWT.Modify, verifyListener); + + return area; + } + + private void createErrorMessage(Composite parent) { + new Label(parent, SWT.NONE); + + warningLabel = new Label(parent, SWT.NONE); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = 200; + gridData.heightHint = SWT.DEFAULT; + warningLabel.setLayoutData(gridData); + warningLabel.setForeground( + Display.getCurrent().getSystemColor(SWT.COLOR_RED)); + + new Label(parent, SWT.NONE); + } + + private void createOldPasswordInputBox(Composite parent) { + createInputLabel(parent, + MindMapMessages.EncryptDialogPane_oldpassword_text); + + oldPasswordInputBox = createInput(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); + + hookText(oldPasswordInputBox); + addRefreshDefaultButtonListener(oldPasswordInputBox); + addTriggerDefaultButtonListener(oldPasswordInputBox, + SWT.DefaultSelection); + + oldPasswordVerificationLabel = new Label(parent, SWT.NONE); + oldPasswordVerificationLabel.setBackground(parent.getBackground()); + oldPasswordVerificationLabel + .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + oldPasswordVerificationLabel.setImage(getErrorIcon()); + oldPasswordVerificationLabel.setVisible(false); + } + + private void createNewPasswordInputBox(Composite parent) { + String text; + if (oldPasswordInputBox == null) { + text = MindMapMessages.EncryptDialogPane_password_text; + } else { + text = MindMapMessages.EncryptDialogPane_newpassword_text; + } + createInputLabel(parent, text); + + newPasswordInputBox = createInput(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); + + hookText(newPasswordInputBox); + addRefreshDefaultButtonListener(newPasswordInputBox); + addTriggerDefaultButtonListener(newPasswordInputBox, + SWT.DefaultSelection); + + new Label(parent, SWT.NONE); + } + + private void createVerifyPasswordInputBox(Composite parent) { + createInputLabel(parent, + MindMapMessages.EncryptDialogPane_confirm_text); + + verifyNewPasswordInputBox = createInput(parent, + SWT.BORDER | SWT.PASSWORD | SWT.SINGLE, SWT.DEFAULT); + + hookText(verifyNewPasswordInputBox); + addRefreshDefaultButtonListener(verifyNewPasswordInputBox); + addTriggerDefaultButtonListener(verifyNewPasswordInputBox, + SWT.DefaultSelection); + + newPasswordVerificationLabel = new Label(parent, SWT.NONE); + newPasswordVerificationLabel.setBackground(parent.getBackground()); + newPasswordVerificationLabel + .setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + newPasswordVerificationLabel.setImage(getErrorIcon()); + newPasswordVerificationLabel.setVisible(false); + } + + private void createHintPasswordInputBox(Composite parent) { + createInputLabel(parent, NLS.bind( + MindMapMessages.EncryptionDialog_HintInput_label, " \n ")); //$NON-NLS-1$ + + hintPasswordInputBox = createInput(parent, SWT.BORDER | SWT.WRAP, 50); + + new Label(parent, SWT.NONE); + + hookText(hintPasswordInputBox); + } + + private Label createInputLabel(Composite parent, String text) { + Label label = new Label(parent, SWT.NONE); + label.setText(text); + label.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + label.setBackground(parent.getBackground()); + return label; + } + + private Text createInput(Composite parent, int style, int height) { + Text input = new Text(parent, style); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.minimumWidth = 200; + gridData.widthHint = 200; + gridData.heightHint = height; + input.setLayoutData(gridData); + + return input; + } + + private Composite getContainer() { + return container; + } + + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(MindMapMessages.EncryptionDialog_SetPassword_title); + } + + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, + MindMapMessages.EncryptionDialog_ButtonBar_Set_button, true); + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + setSetButtonEnabled(false); + } + + private void setSetButtonEnabled(boolean enabled) { + Button button = getButton(IDialogConstants.OK_ID); + if (button != null && !button.isDisposed()) { + button.setEnabled(enabled); + } + } + + private void checkSetButton() { + if (oldPasswordInputBox == null) { + setSetButtonEnabled(!"".equals(newPasswordInputBox.getText()) //$NON-NLS-1$ + && !"".equals(verifyNewPasswordInputBox.getText())); //$NON-NLS-1$ + } else { + setSetButtonEnabled(!"".equals(oldPasswordInputBox.getText())); //$NON-NLS-1$ + } + } + + protected void addRefreshDefaultButtonListener(final Control focusControl) { + focusControl.addListener(SWT.FocusIn, getDefaultButtonListener()); + focusControl.addListener(SWT.FocusOut, getDefaultButtonListener()); + } + + protected void addTriggerDefaultButtonListener(Control control, + int triggerEvent) { + control.addListener(triggerEvent, getDefaultButtonListener()); + control.setData(DEFAULT_BUTTON_TRIGGER_EVENT_ID, + Integer.valueOf(triggerEvent)); + } + + private Listener getDefaultButtonListener() { + if (defaultButtonListener == null) { + defaultButtonListener = new Listener() { + + private Button savedDefaultButton = null; + + public void handleEvent(Event event) { + Object triggerEvent = event.widget + .getData(DEFAULT_BUTTON_TRIGGER_EVENT_ID); + if (triggerEvent instanceof Integer + && event.type == ((Integer) triggerEvent) + .intValue()) { + triggerDefaultButton(); + return; + } + + if (event.type == SWT.FocusIn) { + changeDefaultButton(); + } else if (event.type == SWT.FocusOut) { + restoreDefaultButton(); + } + } + + private void restoreDefaultButton() { + if (defaultButtonId >= 0) { + Shell shell = container.getShell(); + if (savedDefaultButton != null + && savedDefaultButton.isDisposed()) { + savedDefaultButton = null; + } + shell.setDefaultButton(savedDefaultButton); + } + } + + private void changeDefaultButton() { + if (defaultButtonId >= 0) { + final Shell shell = container.getShell(); + savedDefaultButton = shell.getDefaultButton(); + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + Button button = getButton(defaultButtonId); + if (button != null && !button.isDisposed()) { + shell.setDefaultButton(button); + } + } + }); + } + } + }; + } + return defaultButtonListener; + } + + protected Button getDefaultButton() { + if (buttons != null && defaultButtonId >= 0) { + return getButton(defaultButtonId); + } + return null; + } + + protected void triggerDefaultButton() { + triggerButton(defaultButtonId); + } + + protected void triggerButton(int buttonId) { + if (buttonId >= 0) { + Button button = getButton(buttonId); + if (button != null && !button.isDisposed() && button.isEnabled()) { + buttonPressed(buttonId); + } + } + } + + protected void okPressed() { + if (!verify()) { + warningLabel.setText(verifyOldPassword() + ? MindMapMessages.EncryptionDialog_Warning_NotMatch_label + : MindMapMessages.EncryptionDialog_Warning_NotCorrect_label); + return; + } + setPassword(newPasswordInputBox.getText()); + setHintMessage(hintPasswordInputBox.getText()); + super.okPressed(); + } + + private boolean verifyOldPassword() { + boolean oldPasswordVerified = false; + if (!hasPassword()) { + oldPasswordVerified = !"".equals(newPasswordInputBox.getText()); //$NON-NLS-1$ + } else if (oldPasswordInputBox != null) { + oldPasswordVerified = testsPassword(oldPasswordInputBox.getText()); + oldPasswordVerificationLabel.setVisible(!oldPasswordVerified); + } + newPasswordVerificationLabel.setVisible(oldPasswordVerified); + return oldPasswordVerified; + } + + private boolean verifyNewPassword() { + boolean newPasswordVerified = ((oldPasswordInputBox != null // + || !"".equals(newPasswordInputBox.getText()))) //$NON-NLS-1$ + && newPasswordInputBox.getText() + .equals(verifyNewPasswordInputBox.getText()); + newPasswordVerificationLabel.setVisible(!newPasswordVerified); + return newPasswordVerified; + } + + protected boolean verify() { + return verifyOldPassword() && verifyNewPassword(); + } + + protected void setPassword(String newPassword) { + if (verify()) { + if ("".equals(newPassword)) { //$NON-NLS-1$ + newPassword = null; + } + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SET_PASSWORD_COUNT); + this.password = newPassword; + } + } + + protected String getPassword() { + return this.password; + } + + protected boolean hasPassword() { + return false; + } + + protected boolean testsPassword(String password) { + return false; + } + + protected void setHintMessage(String hintMessage) { + if (verify()) { + if ("".equals(hintMessage)) //$NON-NLS-1$ + hintMessage = null; + + this.hintMessage = hintMessage; + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.SET_PASSWORD_HINT_COUNT); + } + } + + protected String getHintMessage() { + return hintMessage; + } + + private void hookText(final Text text) { + text.addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) { + text.selectAll(); + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialog.java index 015e44fee..51b064fc4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialog.java @@ -1,201 +1,201 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.ErrorSupportProvider; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.statushandlers.StatusDetails; -import org.xmind.ui.internal.statushandlers.StatusHandlerMessages; - -public class ErrorDialog extends Dialog { - - private StatusDetails details; - - private Runnable closeCallback; - - private final ErrorSupportProvider supportProvider; - - public ErrorDialog(Shell parentShell, StatusAdapter error, - ErrorSupportProvider supportProvider) { - super(parentShell); - this.details = new StatusDetails(error); - this.closeCallback = null; - this.supportProvider = supportProvider; - } - - @Override - protected Control createContents(Composite parent) { - Composite composite = new Composite(parent, 0); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - composite.setBackground(parent.getBackground()); - - Control titleArea = createTitleArea(composite); - titleArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - ((GridData) titleArea.getLayoutData()).widthHint = 280; - - applyDialogFont(composite); - // initialize the dialog units - initializeDialogUnits(composite); - // create the dialog area and button bar - dialogArea = createDialogArea(composite); - buttonBar = createButtonBar(composite); - - return composite; - } - - private Control createTitleArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - area.setLayout(layout); - area.setBackground(parent.getBackground()); - - Label titleImageLabel = new Label(area, SWT.NONE); - titleImageLabel.setImage(details.getImage()); - titleImageLabel.setLayoutData( - new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); - titleImageLabel.setBackground(parent.getBackground()); - - Composite messageParent = new Composite(area, SWT.NONE); - messageParent.setLayout(new GridLayout()); - messageParent.setBackground(parent.getBackground()); - - Label messageLabel = new Label(messageParent, SWT.WRAP); - messageLabel.setText(details.getMessage()); - messageLabel - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - messageLabel.setBackground(parent.getBackground()); - - if (supportProvider != null) { - if (supportProvider instanceof AbstractStatusAreaProvider - && ((AbstractStatusAreaProvider) supportProvider) - .validFor(details.getStatusAdapter())) { - ((AbstractStatusAreaProvider) supportProvider) - .createSupportArea(messageParent, - details.getStatusAdapter()); - } else if (supportProvider - .validFor(details.getStatusAdapter().getStatus())) { - supportProvider.createSupportArea(messageParent, - details.getStatusAdapter().getStatus()); - } - } - - return area; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - - Control detailsArea = createDetailsArea(composite); - detailsArea - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - ((GridData) detailsArea.getLayoutData()).widthHint = 400; - ((GridData) detailsArea.getLayoutData()).heightHint = 80; - - return composite; - } - - private Control createDetailsArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - area.setLayout(layout); - - Text detailsText = new Text(area, - SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); - detailsText.setEditable(false); - detailsText.setText(details.getFullText()); - detailsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - return area; - } - - protected void createButtonsForButtonBar(Composite parent) { - parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - createBlankArea(parent); - createButton(parent, IDialogConstants.CANCEL_ID, - StatusHandlerMessages.RuntimeErrorDialog_CloseButton_Text, - true); - } - - private void createBlankArea(Composite parent) { - ((GridLayout) parent.getLayout()).numColumns++; - - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - composite - .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); - composite.setBackground(parent.getBackground()); - - Hyperlink report = new Hyperlink(composite, SWT.LEFT); - report.setText( - StatusHandlerMessages.RuntimeErrorDialog_ReportHyperlink_Text); - report.setUnderlined(true); - report.addHyperlinkListener(new HyperlinkAdapter() { - public void linkActivated(HyperlinkEvent e) { - reportPressed(); - } - }); - report.setBackground(composite.getBackground()); - - } - - private void reportPressed() { - try { - MindMapUIPlugin.getDefault().getErrorReporter().report(details); - } catch (InterruptedException e) { - return; - } - close(); - } - - /** - * @param closeCallback - * the closeCallback to set - */ - public void setCloseCallback(Runnable closeCallback) { - this.closeCallback = closeCallback; - } - - @Override - public boolean close() { - boolean returnValue = super.close(); - - if (closeCallback != null) { - Display.getCurrent().asyncExec(closeCallback); - } - - return returnValue; - } - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorSupportProvider; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.statushandlers.StatusDetails; +import org.xmind.ui.internal.statushandlers.StatusHandlerMessages; + +public class ErrorDialog extends Dialog { + + private StatusDetails details; + + private Runnable closeCallback; + + private final ErrorSupportProvider supportProvider; + + public ErrorDialog(Shell parentShell, StatusAdapter error, + ErrorSupportProvider supportProvider) { + super(parentShell); + this.details = new StatusDetails(error); + this.closeCallback = null; + this.supportProvider = supportProvider; + } + + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, 0); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + composite.setBackground(parent.getBackground()); + + Control titleArea = createTitleArea(composite); + titleArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ((GridData) titleArea.getLayoutData()).widthHint = 280; + + applyDialogFont(composite); + // initialize the dialog units + initializeDialogUnits(composite); + // create the dialog area and button bar + dialogArea = createDialogArea(composite); + buttonBar = createButtonBar(composite); + + return composite; + } + + private Control createTitleArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + area.setLayout(layout); + area.setBackground(parent.getBackground()); + + Label titleImageLabel = new Label(area, SWT.NONE); + titleImageLabel.setImage(details.getImage()); + titleImageLabel.setLayoutData( + new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + titleImageLabel.setBackground(parent.getBackground()); + + Composite messageParent = new Composite(area, SWT.NONE); + messageParent.setLayout(new GridLayout()); + messageParent.setBackground(parent.getBackground()); + + Label messageLabel = new Label(messageParent, SWT.WRAP); + messageLabel.setText(details.getMessage()); + messageLabel + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + messageLabel.setBackground(parent.getBackground()); + + if (supportProvider != null) { + if (supportProvider instanceof AbstractStatusAreaProvider + && ((AbstractStatusAreaProvider) supportProvider) + .validFor(details.getStatusAdapter())) { + ((AbstractStatusAreaProvider) supportProvider) + .createSupportArea(messageParent, + details.getStatusAdapter()); + } else if (supportProvider + .validFor(details.getStatusAdapter().getStatus())) { + supportProvider.createSupportArea(messageParent, + details.getStatusAdapter().getStatus()); + } + } + + return area; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + Control detailsArea = createDetailsArea(composite); + detailsArea + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ((GridData) detailsArea.getLayoutData()).widthHint = 400; + ((GridData) detailsArea.getLayoutData()).heightHint = 80; + + return composite; + } + + private Control createDetailsArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + area.setLayout(layout); + + Text detailsText = new Text(area, + SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + detailsText.setEditable(false); + detailsText.setText(details.getFullText()); + detailsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + return area; + } + + protected void createButtonsForButtonBar(Composite parent) { + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + createBlankArea(parent); + createButton(parent, IDialogConstants.CANCEL_ID, + StatusHandlerMessages.RuntimeErrorDialog_CloseButton_Text, + true); + } + + private void createBlankArea(Composite parent) { + ((GridLayout) parent.getLayout()).numColumns++; + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); + composite.setBackground(parent.getBackground()); + + Hyperlink report = new Hyperlink(composite, SWT.LEFT); + report.setText( + StatusHandlerMessages.RuntimeErrorDialog_ReportHyperlink_Text); + report.setUnderlined(true); + report.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + reportPressed(); + } + }); + report.setBackground(composite.getBackground()); + + } + + private void reportPressed() { + try { + MindMapUIPlugin.getDefault().getErrorReporter().report(details); + } catch (InterruptedException e) { + return; + } + close(); + } + + /** + * @param closeCallback + * the closeCallback to set + */ + public void setCloseCallback(Runnable closeCallback) { + this.closeCallback = closeCallback; + } + + @Override + public boolean close() { + boolean returnValue = super.close(); + + if (closeCallback != null) { + Display.getCurrent().asyncExec(closeCallback); + } + + return returnValue; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane.java index 7fbae08d2..e550d1b6f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane.java @@ -1,150 +1,150 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.eclipse.ui.statushandlers.StatusManager; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.statushandlers.StatusDetails; - -public class ErrorDialogPane extends DialogPane { - - private final StatusAdapter error; - - private final String summary; - - private Text summaryBoard; - - public ErrorDialogPane(StatusAdapter error) { - this.error = error; - Throwable cause = StatusDetails - .getRootCause(error.getStatus().getException()); - if (cause == null) - cause = new UnknownError(); - this.summary = NLS.bind( - MindMapMessages.ErrorDialogPane_summaryBoard_text, - new Object[] { error.getStatus().getMessage(), - cause.getClass().getName(), - cause.getLocalizedMessage() }); - } - - @Override - protected Control createDialogContents(Composite parent) { - Composite composite = (Composite) super.createDialogContents(parent); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - - createSummaryBoard(composite); - return composite; - } - - @Override - protected int getPreferredWidth() { - return 500; - } - - private void createSummaryBoard(Composite parent) { - Composite box = new Composite(parent, SWT.NONE); - box.setBackground(parent.getBackground()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - box.setLayoutData(gridData); - - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 5; - gridLayout.marginHeight = 5; - gridLayout.verticalSpacing = 0; - gridLayout.horizontalSpacing = 10; - box.setLayout(gridLayout); - - createIcon(box); - createSummaryBox(box); - } - - private void createIcon(Composite parent) { - Label iconLabel = new Label(parent, SWT.NONE); - iconLabel.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, true)); - iconLabel.setBackground(parent.getBackground()); - iconLabel.setImage(parent.getDisplay().getSystemImage(SWT.ICON_ERROR)); - } - - private void createSummaryBox(Composite parent) { - summaryBoard = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); - summaryBoard.setBackground(parent.getBackground()); - applyFont(summaryBoard); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); - gridData.widthHint = SWT.DEFAULT; - gridData.heightHint = SWT.DEFAULT; - summaryBoard.setLayoutData(gridData); - if (summary != null) { - summaryBoard.setText(summary); - } - } - - public void dispose() { - super.dispose(); - summaryBoard = null; - } - - public void setFocus() { - if (summaryBoard != null && !summaryBoard.isDisposed()) { - summaryBoard.setFocus(); - } - } - - protected void createButtonsForButtonBar(Composite buttonBar) { - createButton(buttonBar, IDialogConstants.OK_ID, - MindMapMessages.EncryptDialogPane_detailsButton_label, false); - createButton(buttonBar, IDialogConstants.CLOSE_ID, - IDialogConstants.CLOSE_LABEL, false); - getButton(IDialogConstants.OK_ID).setEnabled(error != null); - } - - @Override - protected boolean closePressed() { - setReturnCode(CANCEL); - close(); - return true; - } - - @Override - protected boolean okPressed() { - showDetails(); - return true; - } - - private void showDetails() { - StatusManager.getManager().handle(error, StatusManager.SHOW); - } - - protected void escapeKeyPressed() { - triggerButton(IDialogConstants.CLOSE_ID); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.eclipse.ui.statushandlers.StatusManager; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.statushandlers.StatusDetails; + +public class ErrorDialogPane extends DialogPane { + + private final StatusAdapter error; + + private final String summary; + + private Text summaryBoard; + + public ErrorDialogPane(StatusAdapter error) { + this.error = error; + Throwable cause = StatusDetails + .getRootCause(error.getStatus().getException()); + if (cause == null) + cause = new UnknownError(); + this.summary = NLS.bind( + MindMapMessages.ErrorDialogPane_summaryBoard_text, + new Object[] { error.getStatus().getMessage(), + cause.getClass().getName(), + cause.getLocalizedMessage() }); + } + + @Override + protected Control createDialogContents(Composite parent) { + Composite composite = (Composite) super.createDialogContents(parent); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + + createSummaryBoard(composite); + return composite; + } + + @Override + protected int getPreferredWidth() { + return 500; + } + + private void createSummaryBoard(Composite parent) { + Composite box = new Composite(parent, SWT.NONE); + box.setBackground(parent.getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + box.setLayoutData(gridData); + + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 5; + gridLayout.marginHeight = 5; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 10; + box.setLayout(gridLayout); + + createIcon(box); + createSummaryBox(box); + } + + private void createIcon(Composite parent) { + Label iconLabel = new Label(parent, SWT.NONE); + iconLabel.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, true)); + iconLabel.setBackground(parent.getBackground()); + iconLabel.setImage(parent.getDisplay().getSystemImage(SWT.ICON_ERROR)); + } + + private void createSummaryBox(Composite parent) { + summaryBoard = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); + summaryBoard.setBackground(parent.getBackground()); + applyFont(summaryBoard); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + gridData.widthHint = SWT.DEFAULT; + gridData.heightHint = SWT.DEFAULT; + summaryBoard.setLayoutData(gridData); + if (summary != null) { + summaryBoard.setText(summary); + } + } + + public void dispose() { + super.dispose(); + summaryBoard = null; + } + + public void setFocus() { + if (summaryBoard != null && !summaryBoard.isDisposed()) { + summaryBoard.setFocus(); + } + } + + protected void createButtonsForButtonBar(Composite buttonBar) { + createButton(buttonBar, IDialogConstants.OK_ID, + MindMapMessages.EncryptDialogPane_detailsButton_label, false); + createButton(buttonBar, IDialogConstants.CLOSE_ID, + IDialogConstants.CLOSE_LABEL, false); + getButton(IDialogConstants.OK_ID).setEnabled(error != null); + } + + @Override + protected boolean closePressed() { + setReturnCode(CANCEL); + close(); + return true; + } + + @Override + protected boolean okPressed() { + showDetails(); + return true; + } + + private void showDetails() { + StatusManager.getManager().handle(error, StatusManager.SHOW); + } + + protected void escapeKeyPressed() { + triggerButton(IDialogConstants.CLOSE_ID); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane2.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane2.java index dacbac123..0c88737ed 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane2.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialogPane2.java @@ -1,213 +1,213 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.dialogs.ErrorSupportProvider; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.statushandlers.StatusDetails; -import org.xmind.ui.internal.statushandlers.StatusHandlerMessages; - -public class ErrorDialogPane2 extends DialogPane { - - private final StatusDetails details; - - private final ErrorSupportProvider supportProvider; - - private Composite composite; - - private Runnable closeCallback; - - public ErrorDialogPane2(StatusAdapter error, - ErrorSupportProvider supportProvider) { - this.details = new StatusDetails(error); - this.supportProvider = supportProvider; - this.closeCallback = null; - } - - @Override - protected Control createDialogContents(Composite parent) { - composite = (Composite) super.createDialogContents(parent); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 20; - gridLayout.horizontalSpacing = 0; - composite.setLayout(gridLayout); - composite.setBackground(parent.getBackground()); - - Control titleArea = createTitleArea(composite); - titleArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - ((GridData) titleArea.getLayoutData()).widthHint = 280; - - Control detailsArea = createDetailsArea(composite); - detailsArea - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - ((GridData) detailsArea.getLayoutData()).widthHint = 300; - ((GridData) detailsArea.getLayoutData()).heightHint = 80; - return composite; - } - - @Override - protected int getPreferredWidth() { - return 500; - } - - private Control createTitleArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - area.setLayout(layout); - area.setBackground(parent.getBackground()); - - Label titleImageLabel = new Label(area, SWT.NONE); - titleImageLabel.setImage(details.getImage()); - titleImageLabel.setLayoutData( - new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); - titleImageLabel.setBackground(parent.getBackground()); - - Composite messageParent = new Composite(area, SWT.NONE); - messageParent.setLayout(new GridLayout()); - messageParent.setBackground(parent.getBackground()); - - Label messageLabel = new Label(messageParent, SWT.WRAP); - messageLabel.setText(details.getMessage()); - messageLabel - .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - messageLabel.setBackground(parent.getBackground()); - - if (supportProvider != null) { - if (supportProvider instanceof AbstractStatusAreaProvider - && ((AbstractStatusAreaProvider) supportProvider) - .validFor(details.getStatusAdapter())) { - ((AbstractStatusAreaProvider) supportProvider) - .createSupportArea(messageParent, - details.getStatusAdapter()); - } else if (supportProvider - .validFor(details.getStatusAdapter().getStatus())) { - supportProvider.createSupportArea(messageParent, - details.getStatusAdapter().getStatus()); - } - } - - return area; - } - - private Control createDetailsArea(Composite parent) { - Composite area = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - area.setLayout(layout); - - Text detailsText = new Text(area, - SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); - detailsText.setEditable(false); - detailsText.setText(details.getFullText()); - detailsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - return area; - } - - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.CLOSE_ID, - StatusHandlerMessages.RuntimeErrorDialog_CloseButton_Text, - true); - } - - @Override - protected void createBlankArea(Composite buttonBar) { - Composite composite = new Composite(buttonBar, SWT.NONE); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 0; - layout.horizontalSpacing = 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - composite.setBackground(buttonBar.getBackground()); - - Hyperlink report = new Hyperlink(composite, SWT.LEFT); - report.setText( - StatusHandlerMessages.RuntimeErrorDialog_ReportHyperlink_Text); - report.setUnderlined(true); - report.addHyperlinkListener(new HyperlinkAdapter() { - public void linkActivated(HyperlinkEvent e) { - reportPressed(); - } - }); - report.setBackground(composite.getBackground()); - - } - - private void reportPressed() { - try { - MindMapUIPlugin.getDefault().getErrorReporter().report(details); - } catch (InterruptedException e) { - return; - } - close(); - } - - @Override - protected boolean closePressed() { - setReturnCode(IDialogConstants.CLOSE_ID); - close(); - if (closeCallback != null) { - Display.getCurrent().asyncExec(closeCallback); - } - return true; - } - - /** - * @param closeCallback - * the closeCallback to set - */ - public void setCloseCallback(Runnable closeCallback) { - this.closeCallback = closeCallback; - } - - protected void escapeKeyPressed() { - triggerButton(IDialogConstants.CLOSE_ID); - } - - public void dispose() { - super.dispose(); - composite = null; - } - - public void setFocus() { - if (composite != null && !composite.isDisposed()) { - composite.setFocus(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.dialogs.ErrorSupportProvider; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.statushandlers.StatusDetails; +import org.xmind.ui.internal.statushandlers.StatusHandlerMessages; + +public class ErrorDialogPane2 extends DialogPane { + + private final StatusDetails details; + + private final ErrorSupportProvider supportProvider; + + private Composite composite; + + private Runnable closeCallback; + + public ErrorDialogPane2(StatusAdapter error, + ErrorSupportProvider supportProvider) { + this.details = new StatusDetails(error); + this.supportProvider = supportProvider; + this.closeCallback = null; + } + + @Override + protected Control createDialogContents(Composite parent) { + composite = (Composite) super.createDialogContents(parent); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 20; + gridLayout.horizontalSpacing = 0; + composite.setLayout(gridLayout); + composite.setBackground(parent.getBackground()); + + Control titleArea = createTitleArea(composite); + titleArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ((GridData) titleArea.getLayoutData()).widthHint = 280; + + Control detailsArea = createDetailsArea(composite); + detailsArea + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ((GridData) detailsArea.getLayoutData()).widthHint = 300; + ((GridData) detailsArea.getLayoutData()).heightHint = 80; + return composite; + } + + @Override + protected int getPreferredWidth() { + return 500; + } + + private Control createTitleArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + area.setLayout(layout); + area.setBackground(parent.getBackground()); + + Label titleImageLabel = new Label(area, SWT.NONE); + titleImageLabel.setImage(details.getImage()); + titleImageLabel.setLayoutData( + new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + titleImageLabel.setBackground(parent.getBackground()); + + Composite messageParent = new Composite(area, SWT.NONE); + messageParent.setLayout(new GridLayout()); + messageParent.setBackground(parent.getBackground()); + + Label messageLabel = new Label(messageParent, SWT.WRAP); + messageLabel.setText(details.getMessage()); + messageLabel + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + messageLabel.setBackground(parent.getBackground()); + + if (supportProvider != null) { + if (supportProvider instanceof AbstractStatusAreaProvider + && ((AbstractStatusAreaProvider) supportProvider) + .validFor(details.getStatusAdapter())) { + ((AbstractStatusAreaProvider) supportProvider) + .createSupportArea(messageParent, + details.getStatusAdapter()); + } else if (supportProvider + .validFor(details.getStatusAdapter().getStatus())) { + supportProvider.createSupportArea(messageParent, + details.getStatusAdapter().getStatus()); + } + } + + return area; + } + + private Control createDetailsArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + area.setLayout(layout); + + Text detailsText = new Text(area, + SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + detailsText.setEditable(false); + detailsText.setText(details.getFullText()); + detailsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + return area; + } + + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CLOSE_ID, + StatusHandlerMessages.RuntimeErrorDialog_CloseButton_Text, + true); + } + + @Override + protected void createBlankArea(Composite buttonBar) { + Composite composite = new Composite(buttonBar, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setBackground(buttonBar.getBackground()); + + Hyperlink report = new Hyperlink(composite, SWT.LEFT); + report.setText( + StatusHandlerMessages.RuntimeErrorDialog_ReportHyperlink_Text); + report.setUnderlined(true); + report.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + reportPressed(); + } + }); + report.setBackground(composite.getBackground()); + + } + + private void reportPressed() { + try { + MindMapUIPlugin.getDefault().getErrorReporter().report(details); + } catch (InterruptedException e) { + return; + } + close(); + } + + @Override + protected boolean closePressed() { + setReturnCode(IDialogConstants.CLOSE_ID); + close(); + if (closeCallback != null) { + Display.getCurrent().asyncExec(closeCallback); + } + return true; + } + + /** + * @param closeCallback + * the closeCallback to set + */ + public void setCloseCallback(Runnable closeCallback) { + this.closeCallback = closeCallback; + } + + protected void escapeKeyPressed() { + triggerButton(IDialogConstants.CLOSE_ID); + } + + public void dispose() { + super.dispose(); + composite = null; + } + + public void setFocus() { + if (composite != null && !composite.isDisposed()) { + composite.setFocus(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInput.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInput.java index a0e34a82d..064f4fe47 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInput.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInput.java @@ -1,24 +1,24 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; - -/** - * - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public class FileEditorInput extends MindMapEditorInput { - - /** - * @param file - */ - public FileEditorInput(File file) { - super(file.toURI()); - } - - public File getFile() { - return new File(getURI()); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; + +/** + * + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public class FileEditorInput extends MindMapEditorInput { + + /** + * @param file + */ + public FileEditorInput(File file) { + super(file.toURI()); + } + + public File getFile() { + return new File(getURI()); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInputFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInputFactory.java index 23bec676e..23b9f422e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInputFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/FileEditorInputFactory.java @@ -1,80 +1,80 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.io.File; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.Path; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IElementFactory; -import org.eclipse.ui.IMemento; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -/** - * - * @author Frank Shaka - * @deprecated See {@link MindMapEditorInputFactory} - */ -public class FileEditorInputFactory implements IElementFactory { - - private static final String ID = "org.xmind.ui.WorkbookEditorInputFactory"; //$NON-NLS-1$ - - private static final String TAG_PATH = "path"; //$NON-NLS-1$ - - /** - * For backward compatability with 3.0.0/1 - */ - private static final String TAG_RESOURCE_PATH = "resourcePath"; //$NON-NLS-1$ - - public IAdaptable createElement(IMemento memento) { - String path = memento.getString(TAG_PATH); - if (path != null) { - return MindMapUI.getEditorInputFactory() - .createEditorInputForFile(new File(path)); - } - - // For backward compatability - path = memento.getString(TAG_RESOURCE_PATH); - if (path != null) { - try { - return createResourceFileEditorInput(path); - } catch (CoreException e) { - Logger.log(e); - } - } - return null; - } - - /** - * The 'resource path' is stored by XMind 3.0.0/1 for the sake of - * representing an IFile object and create an old WorkbookEditorInput. Now - * we take into account the creation of IFile and its corresponding editor - * input ONLY when org.eclipse.ui.ide plugin exists in the runtime - * environment. - * - * @throws CoreException - */ - private IEditorInput createResourceFileEditorInput(String resourcePath) - throws CoreException { - IFile file = ResourcesPlugin.getWorkspace().getRoot() - .getFile(new Path(resourcePath)); - return MindMapUI.getEditorInputFactory() - .createEditorInput(file.getLocationURI()); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Path; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +/** + * + * @author Frank Shaka + * @deprecated See {@link MindMapEditorInputFactory} + */ +public class FileEditorInputFactory implements IElementFactory { + + private static final String ID = "org.xmind.ui.WorkbookEditorInputFactory"; //$NON-NLS-1$ + + private static final String TAG_PATH = "path"; //$NON-NLS-1$ + + /** + * For backward compatability with 3.0.0/1 + */ + private static final String TAG_RESOURCE_PATH = "resourcePath"; //$NON-NLS-1$ + + public IAdaptable createElement(IMemento memento) { + String path = memento.getString(TAG_PATH); + if (path != null) { + return MindMapUI.getEditorInputFactory() + .createEditorInputForFile(new File(path)); + } + + // For backward compatability + path = memento.getString(TAG_RESOURCE_PATH); + if (path != null) { + try { + return createResourceFileEditorInput(path); + } catch (CoreException e) { + Logger.log(e); + } + } + return null; + } + + /** + * The 'resource path' is stored by XMind 3.0.0/1 for the sake of + * representing an IFile object and create an old WorkbookEditorInput. Now + * we take into account the creation of IFile and its corresponding editor + * input ONLY when org.eclipse.ui.ide plugin exists in the runtime + * environment. + * + * @throws CoreException + */ + private IEditorInput createResourceFileEditorInput(String resourcePath) + throws CoreException { + IFile file = ResourcesPlugin.getWorkspace().getRoot() + .getFile(new Path(resourcePath)); + return MindMapUI.getEditorInputFactory() + .createEditorInput(file.getLocationURI()); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPane.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPane.java index edba9baa8..099cd217a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPane.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPane.java @@ -1,49 +1,49 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -import org.eclipse.ui.part.IPage; - -/** - * @author Frank Shaka - * - */ -public interface IDialogPane extends IPage { - - /** - * Standard return code constant (value 0) indicating that the window was - * opened. - * - * @see #open - */ - public static final int OK = 0; - - /** - * Standard return code constant (value 1) indicating that the window was - * canceled. - * - * @see #open - */ - public static final int CANCEL = 1; - - int getReturnCode(); - - void setReturnCode(int code); - - void init(IDialogPaneContainer paneContainer); - - void setFocus(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +import org.eclipse.ui.part.IPage; + +/** + * @author Frank Shaka + * + */ +public interface IDialogPane extends IPage { + + /** + * Standard return code constant (value 0) indicating that the window was + * opened. + * + * @see #open + */ + public static final int OK = 0; + + /** + * Standard return code constant (value 1) indicating that the window was + * canceled. + * + * @see #open + */ + public static final int CANCEL = 1; + + int getReturnCode(); + + void setReturnCode(int code); + + void init(IDialogPaneContainer paneContainer); + + void setFocus(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPaneContainer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPaneContainer.java index a4a964f12..fd7f1ec52 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPaneContainer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IDialogPaneContainer.java @@ -1,52 +1,52 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -/** - * @author Frank Shaka - * - */ -public interface IDialogPaneContainer { - - /** - * Opens the dialog with the given dialog pane. - * - * @param pane - * @return - */ - void open(IDialogPane pane); - - /** - * Closes the currently opened dialog. - * - * @return true if the dialog has been successfully closed. - */ - boolean close(); - - /** - * Closes the currently opened dialog and set the return code to the given - * value. - * - * @param returnCode - */ - void close(int returnCode); - - /** - * Returns true if this container is showing. - * - * @return - */ - boolean isOpen(); -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +/** + * @author Frank Shaka + * + */ +public interface IDialogPaneContainer { + + /** + * Opens the dialog with the given dialog pane. + * + * @param pane + * @return + */ + void open(IDialogPane pane); + + /** + * Closes the currently opened dialog. + * + * @return true if the dialog has been successfully closed. + */ + boolean close(); + + /** + * Closes the currently opened dialog and set the return code to the given + * value. + * + * @param returnCode + */ + void close(int returnCode); + + /** + * Returns true if this container is showing. + * + * @return + */ + boolean isOpen(); +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorHistoryLoader.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorHistoryLoader.java index 085fe7893..02bc2301b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorHistoryLoader.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorHistoryLoader.java @@ -1,48 +1,48 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -import org.xmind.ui.editor.IEditorHistoryItem; - -/** - * @author Frank Shaka - */ -public interface IEditorHistoryLoader { - - public interface IEditorHistoryLoaderCallback { - - void inputURILoaded(URI inputURI); - - void pinnedInputURILoaded(URI inputURI); - - void thumbnailURILoaded(URI inputURI, URI thumbnailURI); - - void editorHistoryItemsLoaded(URI inputURI, IEditorHistoryItem item); - - } - - void load(IEditorHistoryLoaderCallback callback); - - URI saveThumbnail(InputStream thumbnailData) throws IOException; - - void dispose(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import org.xmind.ui.editor.IEditorHistoryItem; + +/** + * @author Frank Shaka + */ +public interface IEditorHistoryLoader { + + public interface IEditorHistoryLoaderCallback { + + void inputURILoaded(URI inputURI); + + void pinnedInputURILoaded(URI inputURI); + + void thumbnailURILoaded(URI inputURI, URI thumbnailURI); + + void editorHistoryItemsLoaded(URI inputURI, IEditorHistoryItem item); + + } + + void load(IEditorHistoryLoaderCallback callback); + + URI saveThumbnail(InputStream thumbnailData) throws IOException; + + void dispose(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayout.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayout.java index 17a83d139..99dda9877 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayout.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayout.java @@ -1,17 +1,17 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Layout; - -/** - * @author Jason Wong - */ -public interface IEditorLayout { - - void activate(Composite parent); - - void deactivate(Composite parent); - - Layout getSWTLayout(); - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; + +/** + * @author Jason Wong + */ +public interface IEditorLayout { + + void activate(Composite parent); + + void deactivate(Composite parent); + + Layout getSWTLayout(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayoutManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayoutManager.java index f830690c1..89f8a71b4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayoutManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayoutManager.java @@ -1,14 +1,14 @@ -package org.xmind.ui.internal.editor; - -/** - * @author Jason Wong - */ -public interface IEditorLayoutManager { - - void setActiveLayout(IEditorLayout editorLayout); - - IEditorLayout getActiveLayout(); - - void restoreDefault(); - -} +package org.xmind.ui.internal.editor; + +/** + * @author Jason Wong + */ +public interface IEditorLayoutManager { + + void setActiveLayout(IEditorLayout editorLayout); + + IEditorLayout getActiveLayout(); + + void restoreDefault(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEncryptable.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEncryptable.java index 17811fb66..c96b6cc33 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEncryptable.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEncryptable.java @@ -1,68 +1,68 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -/** - * This interface represents an object that accepts a password to encrypt its - * content. - * - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IEncryptable { - - String getPasswordHint(); - - String getPassword(); - - /** - * Sets the password to be the given one. - * - * @param newPassword - * a {@link String} of the new password, or null to - * indicate that no encryption should be used - */ - void setPassword(String newPassword); - - /** - * Sets the password to be the given one with hint message. - * - * @param hintMessage - * a {@link String} of the password hint message - */ - void setPasswordHint(String hintMessage); - - /** - * Tests whether the given password equals the one this object has. - * - * @param passwordToTest - * a {@link String} of the password to test, or null - * to test if this object has no password - * @return true if the given password equals the one this - * object has, or false otherwise - */ - boolean testsPassword(String passwordToTest); - - /** - * Tests whether this object has a non-null password. - * - * @return true if this object has a password, or - * false otherwise - */ - boolean hasPassword(); - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +/** + * This interface represents an object that accepts a password to encrypt its + * content. + * + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IEncryptable { + + String getPasswordHint(); + + String getPassword(); + + /** + * Sets the password to be the given one. + * + * @param newPassword + * a {@link String} of the new password, or null to + * indicate that no encryption should be used + */ + void setPassword(String newPassword); + + /** + * Sets the password to be the given one with hint message. + * + * @param hintMessage + * a {@link String} of the password hint message + */ + void setPasswordHint(String hintMessage); + + /** + * Tests whether the given password equals the one this object has. + * + * @param passwordToTest + * a {@link String} of the password to test, or null + * to test if this object has no password + * @return true if the given password equals the one this + * object has, or false otherwise + */ + boolean testsPassword(String passwordToTest); + + /** + * Tests whether this object has a non-null password. + * + * @return true if this object has a password, or + * false otherwise + */ + boolean hasPassword(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMESupport.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMESupport.java index 9ef4d270e..c01c03022 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMESupport.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMESupport.java @@ -1,577 +1,577 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Caret; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.IME; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.PartTextSelection; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.mindmap.ITitleTextPart; -import org.xmind.ui.mindmap.MindMapUI; - -public class IMESupport implements ISelectionChangedListener, Listener, - ControlListener, SelectionListener, FigureListener, PaintListener { - - public static final String PROP_IGNORE_KEY_DOWN = "org.xmind.ui.ignoreKeyDown"; //$NON-NLS-1$ - - private static final int DEFAULT_CARET_WIDTH = 2; - - private MindMapEditorPage page; - - private IGraphicalViewer viewer; - - private Canvas canvas; - - private ScrollBar hBar; - - private ScrollBar vBar; - - private IME ime; - - private Caret caret; - - private boolean imeNeedDispose; - - private boolean caretNeedDispose; - - private int caretWidth; - - private int caretHeight; - - private IPart focus; - - private IFigure focusFigure = null; - - private TextLayout composition = null; - - private int compositionLeft = 0; - - private int compositionTop = 0; - - private StringBuilder composedCache = null; - - public IMESupport(MindMapEditorPage page, IGraphicalViewer viewer) { - this.page = page; - this.viewer = viewer; - - this.canvas = viewer.getCanvas(); - this.canvas.addControlListener(this); - this.canvas.addPaintListener(this); - - this.hBar = this.canvas.getHorizontalBar(); - if (this.hBar != null) { - this.hBar.addSelectionListener(this); - } - this.vBar = this.canvas.getVerticalBar(); - if (this.vBar != null) { - this.vBar.addSelectionListener(this); - } - - this.ime = this.canvas.getIME(); - if (this.ime == null) { - this.ime = new IME(this.canvas, SWT.NONE); - this.imeNeedDispose = true; - } else { - this.imeNeedDispose = false; - } - this.ime.addListener(SWT.ImeComposition, this); - - this.caret = this.canvas.getCaret(); - if (this.caret == null) { - this.caret = new Caret(this.canvas, SWT.NONE); - this.caretNeedDispose = true; - } else { - this.caretNeedDispose = false; - } - this.caret.setVisible(false); - this.caretWidth = DEFAULT_CARET_WIDTH; - this.caretHeight = SWT.DEFAULT; - - viewer.addFocusedPartChangedListener(this); - } - - public void dispose() { - deactivateContext(); - if (composition != null) { - composition.dispose(); - composition = null; - } - setFocusFigure(null); - viewer.removeFocusedPartChangedListener(this); - if (ime != null) { - if (!ime.isDisposed()) { - ime.removeListener(SWT.ImeComposition, this); - } - if (imeNeedDispose) { - ime.dispose(); - } - ime = null; - } - if (caret != null) { - if (caretNeedDispose) { - caret.dispose(); - } - caret = null; - } - if (vBar != null && !vBar.isDisposed()) { - vBar.removeSelectionListener(this); - } - if (hBar != null && !hBar.isDisposed()) { - hBar.removeSelectionListener(this); - } - if (canvas != null && !canvas.isDisposed()) { - canvas.removeControlListener(this); - } - } - - public void selectionChanged(SelectionChangedEvent event) { - if (event.getSelection() instanceof IStructuredSelection) { - focus = viewer - .findPart(((IStructuredSelection) event.getSelection()) - .getFirstElement()); - } else if (event.getSelection() instanceof PartTextSelection) { - focus = ((PartTextSelection) event.getSelection()).getPart(); - } else { - focus = null; - } - IFigure figure = null; - if (focus instanceof ITitleTextPart) { - figure = ((ITitleTextPart) focus).getTextFigure(); - } else if (focus != null) { - ITitleTextPart title = (ITitleTextPart) focus - .getAdapter(ITitleTextPart.class); - if (title != null) { - figure = title.getTextFigure(); - } else if (focus instanceof IGraphicalPart) { - figure = ((IGraphicalPart) focus).getFigure(); - } - } - setFocusFigure(figure); - } - - private void setFocusFigure(IFigure figure) { - if (figure != focusFigure) { - if (focusFigure != null) { - focusFigure.removeFigureListener(this); - } - if (figure != null) { - figure.addFigureListener(this); - } - focusFigure = figure; - } - updateCompositionLocation(); - } - - private void updateCompositionLocation() { - if (focusFigure != null) { - Point pos = focusFigure.getBounds().getTopLeft(); - Insets border = focusFigure.getInsets(); - pos.translate(border.left, border.top); - focusFigure.translateToAbsolute(pos); - setCompositionLocation(pos.x, pos.y); - } else if (!canvas.isDisposed()) { - Rectangle r = canvas.getBounds(); - setCompositionLocation(Math.max(0, r.width / 2 - 100), Math.max(0, - Math.min(r.height / 2 + 100, r.height - caretHeight))); - } - } - - private void setCompositionLocation(int x, int y) { - this.compositionLeft = x; - this.compositionTop = y; - updateCaretLocation(); - } - - private void updateCaretLocation() { - if (caret == null || caret.isDisposed()) - return; - - int x = compositionLeft; - int y = compositionTop; - caretWidth = DEFAULT_CARET_WIDTH; - caretHeight = 10; - if (ime.getCompositionOffset() >= 0 && composition != null - && !composition.isDisposed()) { - int cacheLength = composedCache == null ? 0 - : composedCache.length(); - int caretOffset = cacheLength + ime.getCaretOffset(); - org.eclipse.swt.graphics.Point p = composition - .getLocation(caretOffset, false); - x = compositionLeft + p.x; - y = compositionTop + p.y; - if (ime.getWideCaret()) { - Rectangle size = composition.getBounds(cacheLength, - caretOffset); - caretWidth = size.width; - caretHeight = size.height; - } else { - caretWidth = DEFAULT_CARET_WIDTH; - Rectangle size = composition.getBounds(caretOffset, - caretOffset); - caretHeight = size.height; - } - } - caret.setBounds(x, y, caretWidth, caretHeight); - } - - public void handleEvent(Event event) { - if (event.type == SWT.ImeComposition) { -// forwardCompositionEvent(event); - switch (event.detail) { - case SWT.COMPOSITION_CHANGED: - handleCompositionChanged(event); - break; - case SWT.COMPOSITION_SELECTION: - handleCompositionSelection(event); - break; - case SWT.COMPOSITION_OFFSET: - handleCompositionOffset(event); - break; - } - } - } - - public void controlMoved(ControlEvent e) { - updateCompositionLocation(); - } - - public void controlResized(ControlEvent e) { - updateCompositionLocation(); - } - - public void widgetSelected(SelectionEvent e) { - updateCompositionLocation(); - } - - public void widgetDefaultSelected(SelectionEvent e) { - updateCompositionLocation(); - } - - public void figureMoved(IFigure source) { - updateCompositionLocation(); - } - - public void paintControl(PaintEvent e) { - paintComposition(e.gc); - } - - private void handleCompositionChanged(final Event event) { - final String text = event.text; - final int length = text.length(); - if (length == ime.getCommitCount()) { -// try { -// System.out.println("IME completed: " -// + Arrays.toString(text.getBytes("UTF-8"))); -// } catch (UnsupportedEncodingException e) { -// e.printStackTrace(); -// } - if (length > 0) { - if (composedCache == null) { - composedCache = new StringBuilder(); - } - composedCache.append(text); - } - int ignoreCount = viewer.getProperties() - .getInteger(PROP_IGNORE_KEY_DOWN, 0); - viewer.getProperties().set(PROP_IGNORE_KEY_DOWN, - ignoreCount + text.length()); - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (canvas == null || canvas.isDisposed()) - return; - if (ime.getCompositionOffset() < 0) { - if (composedCache != null - && composedCache.length() > 0) { - final EditDomain domain = viewer.getEditDomain(); - Request request = new Request(GEF.REQ_EDIT) - .setPrimaryTarget(focus).setDomain(domain) - .setViewer(viewer) - .setParameter(GEF.PARAM_TEXT, - composedCache.toString()); -//// .setParameter(GEF.PARAM_TEXT_SELECTION, -//// new TextSelection(length, 0)) -//// .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE); - domain.handleRequest(request); - } - composedCache = null; - removeCompositionFeedback(); - } else { - showCompositionFeedback(ime.getText()); - } - } - }); - } else { -// try { -// System.out.println("Edit composition: " -// + Arrays.toString(text.getBytes("UTF-8"))); -// } catch (UnsupportedEncodingException e) { -// e.printStackTrace(); -// } - showCompositionFeedback(text); - } - } - - private void handleCompositionSelection(Event event) { -// System.out.println("IME require selection: " + ime.getCaretOffset()); - event.start = ime.getCompositionOffset() < 0 ? 0 : ime.getCaretOffset(); - event.end = ime.getCompositionOffset() < 0 ? 0 : ime.getCaretOffset(); - event.text = ""; //$NON-NLS-1$ - } - - private void handleCompositionOffset(Event event) { -// System.out.println("IME require offset."); - if (ime.getCompositionOffset() < 0 || composition == null - || composition.isDisposed()) { - event.index = 0; - event.count = 0; - } else { - int x = event.x - compositionLeft; - int y = event.y - compositionTop; - int[] trailing = new int[1]; - int offset = composition.getOffset(x, y, trailing); - event.index = offset; - event.count = trailing[0]; - } - } - - private void showCompositionFeedback(String text) { - if (focusFigure == null) { - removeCompositionFeedback(); - return; - } - if (composition == null || composition.isDisposed()) { - composition = new TextLayout(Display.getCurrent()); - } - composition.setFont(focusFigure.getFont()); - if (composedCache != null) { - text = composedCache.toString() + text; - } - composition.setText(text); - canvas.redraw(); - - updateCaretLocation(); - caret.setVisible(true); - activateContext(); - } - - private void removeCompositionFeedback() { - deactivateContext(); - if (composition != null) { - composition.dispose(); - composition = null; - } - canvas.redraw(); - caret.setVisible(false); - } - - private void activateContext() { - IGraphicalEditor editor = page.getParentEditor(); - if (editor instanceof MindMapEditor) { - ((MindMapEditor) editor) - .changeContext(MindMapUI.CONTEXT_MINDMAP_TEXTEDIT); - } - } - - private void deactivateContext() { - IGraphicalEditor editor = page.getParentEditor(); - if (editor instanceof MindMapEditor) { - ((MindMapEditor) editor) - .changeContext(page.getEditDomain().getActiveTool()); - } - } - - private void paintComposition(GC gc) { - if (composition == null || composition.isDisposed()) - return; - - Color fg = gc.getForeground(); - Color bg = gc.getBackground(); - int lineWidth = gc.getLineWidth(); - int lineStyle = gc.getLineStyle(); - int lineJoin = gc.getLineJoin(); - int lineCap = gc.getLineCap(); - Rectangle clipping = gc.getClipping(); - - gc.setLineWidth(1); - gc.setLineStyle(SWT.LINE_SOLID); - gc.setLineJoin(SWT.JOIN_BEVEL); - gc.setLineCap(SWT.CAP_FLAT); - - Rectangle size = composition.getBounds(); - gc.setClipping(compositionLeft - 2, compositionTop - 2, size.width + 4, - size.height + 4); - - gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - gc.fillRectangle(compositionLeft - 2, compositionTop - 2, - size.width + 4, size.height + 4); - - gc.setForeground( - Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY)); - gc.drawRectangle(compositionLeft - 2, compositionTop - 2, - size.width + 3, size.height + 3); - gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - composition.draw(gc, compositionLeft, compositionTop); - - gc.setClipping(clipping); - gc.setLineCap(lineCap); - gc.setLineJoin(lineJoin); - gc.setLineStyle(lineStyle); - gc.setLineWidth(lineWidth); - gc.setBackground(bg); - gc.setForeground(fg); - } - -// private void forwardCompositionEvent(final Event event) { -// if (focus == null || !focus.hasRole(GEF.ROLE_EDITABLE)) -// return; -// final EditDomain domain = viewer.getEditDomain(); -// Request request = new Request(GEF.REQ_EDIT).setPrimaryTarget(focus) -// .setDomain(domain).setViewer(viewer); -////// .setParameter(GEF.PARAM_TEXT, text) -////// .setParameter(GEF.PARAM_TEXT_SELECTION, -////// new TextSelection(length, 0)) -////// .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE); -// domain.handleRequest(request); -// -// Display.getCurrent().asyncExec(new Runnable() { -// public void run() { -// ITool tool = domain.getActiveTool(); -// if (tool instanceof FloatingTextEditTool) { -// FloatingTextEditor editor = ((FloatingTextEditTool) tool) -// .getEditor(); -// if (editor != null && !editor.isClosed()) { -// IME ime2 = editor.getTextViewer().getTextWidget() -// .getIME(); -// final Event e = new Event(); -// e.button = event.button; -// e.character = event.character; -// e.count = event.count; -// e.data = event.data; -// e.detail = event.detail; -// e.display = event.display; -// e.doit = event.doit; -// e.end = event.end; -// e.gc = event.gc; -// e.height = event.height; -// e.index = event.index; -// e.item = event.item; -// e.keyCode = event.keyCode; -// e.keyLocation = event.keyLocation; -// e.magnification = event.magnification; -// e.rotation = event.rotation; -// e.segments = event.segments; -// e.segmentsChars = event.segmentsChars; -// e.start = event.start; -// e.stateMask = event.stateMask; -// e.text = event.text; -// e.time = event.time; -// e.touches = event.touches; -// e.type = event.type; -// e.widget = ime2; -// e.width = event.width; -// e.x = event.x; -// e.xDirection = event.xDirection; -// e.y = event.y; -// e.yDirection = event.yDirection; -// Display.getCurrent().post(e); -// -// } -// } -// } -// }); -// } - -// public static void main(String[] args) { -// final Display display = new Display(); -// final Shell shell = new Shell(display); -// shell.setBounds(200, 100, 500, 400); -// shell.setLayout(new FillLayout()); -// -// final Canvas canvas = new Canvas(shell, SWT.NONE); -// final IME ime = new IME(canvas, SWT.NONE); -// final Caret caret = new Caret(canvas, SWT.NONE); -// -// caret.setBounds(10, 10, 2, 20); -// -// ime.addListener(SWT.ImeComposition, new Listener() { -// public void handleEvent(Event event) { -// if (event.detail == SWT.COMPOSITION_CHANGED) { -// System.out.println("Composition changed: " + event.text); -// } else if (event.detail == SWT.COMPOSITION_OFFSET) { -// System.out.println("Composition require offset."); -// } else if (event.detail == SWT.COMPOSITION_SELECTION) { -// System.out.println("Composition require selection."); -// } -// } -// }); -// -// Listener canvasListener = new Listener() { -// public void handleEvent(Event event) { -// if (event.type == SWT.Verify) { -// System.out.println("Key verify: " + event.keyCode + ", " -// + event.stateMask); -// } else if (event.type == SWT.KeyDown) { -// System.out.println("Key down: " + event.keyCode + ", " -// + event.stateMask); -// } else if (event.type == SWT.Traverse) { -// System.out.println("Key traverse: " + event.detail); -// } -// } -// }; -// canvas.addListener(SWT.Verify, canvasListener); -// canvas.addListener(SWT.KeyDown, canvasListener); -// canvas.addListener(SWT.Traverse, canvasListener); -// -// shell.open(); -// -// while (!shell.isDisposed()) { -// if (!display.readAndDispatch()) { -// display.sleep(); -// } -// } -// shell.dispose(); -// display.dispose(); -// } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Caret; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.IME; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.PartTextSelection; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.mindmap.ITitleTextPart; +import org.xmind.ui.mindmap.MindMapUI; + +public class IMESupport implements ISelectionChangedListener, Listener, + ControlListener, SelectionListener, FigureListener, PaintListener { + + public static final String PROP_IGNORE_KEY_DOWN = "org.xmind.ui.ignoreKeyDown"; //$NON-NLS-1$ + + private static final int DEFAULT_CARET_WIDTH = 2; + + private MindMapEditorPage page; + + private IGraphicalViewer viewer; + + private Canvas canvas; + + private ScrollBar hBar; + + private ScrollBar vBar; + + private IME ime; + + private Caret caret; + + private boolean imeNeedDispose; + + private boolean caretNeedDispose; + + private int caretWidth; + + private int caretHeight; + + private IPart focus; + + private IFigure focusFigure = null; + + private TextLayout composition = null; + + private int compositionLeft = 0; + + private int compositionTop = 0; + + private StringBuilder composedCache = null; + + public IMESupport(MindMapEditorPage page, IGraphicalViewer viewer) { + this.page = page; + this.viewer = viewer; + + this.canvas = viewer.getCanvas(); + this.canvas.addControlListener(this); + this.canvas.addPaintListener(this); + + this.hBar = this.canvas.getHorizontalBar(); + if (this.hBar != null) { + this.hBar.addSelectionListener(this); + } + this.vBar = this.canvas.getVerticalBar(); + if (this.vBar != null) { + this.vBar.addSelectionListener(this); + } + + this.ime = this.canvas.getIME(); + if (this.ime == null) { + this.ime = new IME(this.canvas, SWT.NONE); + this.imeNeedDispose = true; + } else { + this.imeNeedDispose = false; + } + this.ime.addListener(SWT.ImeComposition, this); + + this.caret = this.canvas.getCaret(); + if (this.caret == null) { + this.caret = new Caret(this.canvas, SWT.NONE); + this.caretNeedDispose = true; + } else { + this.caretNeedDispose = false; + } + this.caret.setVisible(false); + this.caretWidth = DEFAULT_CARET_WIDTH; + this.caretHeight = SWT.DEFAULT; + + viewer.addFocusedPartChangedListener(this); + } + + public void dispose() { + deactivateContext(); + if (composition != null) { + composition.dispose(); + composition = null; + } + setFocusFigure(null); + viewer.removeFocusedPartChangedListener(this); + if (ime != null) { + if (!ime.isDisposed()) { + ime.removeListener(SWT.ImeComposition, this); + } + if (imeNeedDispose) { + ime.dispose(); + } + ime = null; + } + if (caret != null) { + if (caretNeedDispose) { + caret.dispose(); + } + caret = null; + } + if (vBar != null && !vBar.isDisposed()) { + vBar.removeSelectionListener(this); + } + if (hBar != null && !hBar.isDisposed()) { + hBar.removeSelectionListener(this); + } + if (canvas != null && !canvas.isDisposed()) { + canvas.removeControlListener(this); + } + } + + public void selectionChanged(SelectionChangedEvent event) { + if (event.getSelection() instanceof IStructuredSelection) { + focus = viewer + .findPart(((IStructuredSelection) event.getSelection()) + .getFirstElement()); + } else if (event.getSelection() instanceof PartTextSelection) { + focus = ((PartTextSelection) event.getSelection()).getPart(); + } else { + focus = null; + } + IFigure figure = null; + if (focus instanceof ITitleTextPart) { + figure = ((ITitleTextPart) focus).getTextFigure(); + } else if (focus != null) { + ITitleTextPart title = (ITitleTextPart) focus + .getAdapter(ITitleTextPart.class); + if (title != null) { + figure = title.getTextFigure(); + } else if (focus instanceof IGraphicalPart) { + figure = ((IGraphicalPart) focus).getFigure(); + } + } + setFocusFigure(figure); + } + + private void setFocusFigure(IFigure figure) { + if (figure != focusFigure) { + if (focusFigure != null) { + focusFigure.removeFigureListener(this); + } + if (figure != null) { + figure.addFigureListener(this); + } + focusFigure = figure; + } + updateCompositionLocation(); + } + + private void updateCompositionLocation() { + if (focusFigure != null) { + Point pos = focusFigure.getBounds().getTopLeft(); + Insets border = focusFigure.getInsets(); + pos.translate(border.left, border.top); + focusFigure.translateToAbsolute(pos); + setCompositionLocation(pos.x, pos.y); + } else if (!canvas.isDisposed()) { + Rectangle r = canvas.getBounds(); + setCompositionLocation(Math.max(0, r.width / 2 - 100), Math.max(0, + Math.min(r.height / 2 + 100, r.height - caretHeight))); + } + } + + private void setCompositionLocation(int x, int y) { + this.compositionLeft = x; + this.compositionTop = y; + updateCaretLocation(); + } + + private void updateCaretLocation() { + if (caret == null || caret.isDisposed()) + return; + + int x = compositionLeft; + int y = compositionTop; + caretWidth = DEFAULT_CARET_WIDTH; + caretHeight = 10; + if (ime.getCompositionOffset() >= 0 && composition != null + && !composition.isDisposed()) { + int cacheLength = composedCache == null ? 0 + : composedCache.length(); + int caretOffset = cacheLength + ime.getCaretOffset(); + org.eclipse.swt.graphics.Point p = composition + .getLocation(caretOffset, false); + x = compositionLeft + p.x; + y = compositionTop + p.y; + if (ime.getWideCaret()) { + Rectangle size = composition.getBounds(cacheLength, + caretOffset); + caretWidth = size.width; + caretHeight = size.height; + } else { + caretWidth = DEFAULT_CARET_WIDTH; + Rectangle size = composition.getBounds(caretOffset, + caretOffset); + caretHeight = size.height; + } + } + caret.setBounds(x, y, caretWidth, caretHeight); + } + + public void handleEvent(Event event) { + if (event.type == SWT.ImeComposition) { +// forwardCompositionEvent(event); + switch (event.detail) { + case SWT.COMPOSITION_CHANGED: + handleCompositionChanged(event); + break; + case SWT.COMPOSITION_SELECTION: + handleCompositionSelection(event); + break; + case SWT.COMPOSITION_OFFSET: + handleCompositionOffset(event); + break; + } + } + } + + public void controlMoved(ControlEvent e) { + updateCompositionLocation(); + } + + public void controlResized(ControlEvent e) { + updateCompositionLocation(); + } + + public void widgetSelected(SelectionEvent e) { + updateCompositionLocation(); + } + + public void widgetDefaultSelected(SelectionEvent e) { + updateCompositionLocation(); + } + + public void figureMoved(IFigure source) { + updateCompositionLocation(); + } + + public void paintControl(PaintEvent e) { + paintComposition(e.gc); + } + + private void handleCompositionChanged(final Event event) { + final String text = event.text; + final int length = text.length(); + if (length == ime.getCommitCount()) { +// try { +// System.out.println("IME completed: " +// + Arrays.toString(text.getBytes("UTF-8"))); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } + if (length > 0) { + if (composedCache == null) { + composedCache = new StringBuilder(); + } + composedCache.append(text); + } + int ignoreCount = viewer.getProperties() + .getInteger(PROP_IGNORE_KEY_DOWN, 0); + viewer.getProperties().set(PROP_IGNORE_KEY_DOWN, + ignoreCount + text.length()); + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + if (canvas == null || canvas.isDisposed()) + return; + if (ime.getCompositionOffset() < 0) { + if (composedCache != null + && composedCache.length() > 0) { + final EditDomain domain = viewer.getEditDomain(); + Request request = new Request(GEF.REQ_EDIT) + .setPrimaryTarget(focus).setDomain(domain) + .setViewer(viewer) + .setParameter(GEF.PARAM_TEXT, + composedCache.toString()); +//// .setParameter(GEF.PARAM_TEXT_SELECTION, +//// new TextSelection(length, 0)) +//// .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE); + domain.handleRequest(request); + } + composedCache = null; + removeCompositionFeedback(); + } else { + showCompositionFeedback(ime.getText()); + } + } + }); + } else { +// try { +// System.out.println("Edit composition: " +// + Arrays.toString(text.getBytes("UTF-8"))); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } + showCompositionFeedback(text); + } + } + + private void handleCompositionSelection(Event event) { +// System.out.println("IME require selection: " + ime.getCaretOffset()); + event.start = ime.getCompositionOffset() < 0 ? 0 : ime.getCaretOffset(); + event.end = ime.getCompositionOffset() < 0 ? 0 : ime.getCaretOffset(); + event.text = ""; //$NON-NLS-1$ + } + + private void handleCompositionOffset(Event event) { +// System.out.println("IME require offset."); + if (ime.getCompositionOffset() < 0 || composition == null + || composition.isDisposed()) { + event.index = 0; + event.count = 0; + } else { + int x = event.x - compositionLeft; + int y = event.y - compositionTop; + int[] trailing = new int[1]; + int offset = composition.getOffset(x, y, trailing); + event.index = offset; + event.count = trailing[0]; + } + } + + private void showCompositionFeedback(String text) { + if (focusFigure == null) { + removeCompositionFeedback(); + return; + } + if (composition == null || composition.isDisposed()) { + composition = new TextLayout(Display.getCurrent()); + } + composition.setFont(focusFigure.getFont()); + if (composedCache != null) { + text = composedCache.toString() + text; + } + composition.setText(text); + canvas.redraw(); + + updateCaretLocation(); + caret.setVisible(true); + activateContext(); + } + + private void removeCompositionFeedback() { + deactivateContext(); + if (composition != null) { + composition.dispose(); + composition = null; + } + canvas.redraw(); + caret.setVisible(false); + } + + private void activateContext() { + IGraphicalEditor editor = page.getParentEditor(); + if (editor instanceof MindMapEditor) { + ((MindMapEditor) editor) + .changeContext(MindMapUI.CONTEXT_MINDMAP_TEXTEDIT); + } + } + + private void deactivateContext() { + IGraphicalEditor editor = page.getParentEditor(); + if (editor instanceof MindMapEditor) { + ((MindMapEditor) editor) + .changeContext(page.getEditDomain().getActiveTool()); + } + } + + private void paintComposition(GC gc) { + if (composition == null || composition.isDisposed()) + return; + + Color fg = gc.getForeground(); + Color bg = gc.getBackground(); + int lineWidth = gc.getLineWidth(); + int lineStyle = gc.getLineStyle(); + int lineJoin = gc.getLineJoin(); + int lineCap = gc.getLineCap(); + Rectangle clipping = gc.getClipping(); + + gc.setLineWidth(1); + gc.setLineStyle(SWT.LINE_SOLID); + gc.setLineJoin(SWT.JOIN_BEVEL); + gc.setLineCap(SWT.CAP_FLAT); + + Rectangle size = composition.getBounds(); + gc.setClipping(compositionLeft - 2, compositionTop - 2, size.width + 4, + size.height + 4); + + gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(compositionLeft - 2, compositionTop - 2, + size.width + 4, size.height + 4); + + gc.setForeground( + Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY)); + gc.drawRectangle(compositionLeft - 2, compositionTop - 2, + size.width + 3, size.height + 3); + gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + composition.draw(gc, compositionLeft, compositionTop); + + gc.setClipping(clipping); + gc.setLineCap(lineCap); + gc.setLineJoin(lineJoin); + gc.setLineStyle(lineStyle); + gc.setLineWidth(lineWidth); + gc.setBackground(bg); + gc.setForeground(fg); + } + +// private void forwardCompositionEvent(final Event event) { +// if (focus == null || !focus.hasRole(GEF.ROLE_EDITABLE)) +// return; +// final EditDomain domain = viewer.getEditDomain(); +// Request request = new Request(GEF.REQ_EDIT).setPrimaryTarget(focus) +// .setDomain(domain).setViewer(viewer); +////// .setParameter(GEF.PARAM_TEXT, text) +////// .setParameter(GEF.PARAM_TEXT_SELECTION, +////// new TextSelection(length, 0)) +////// .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE); +// domain.handleRequest(request); +// +// Display.getCurrent().asyncExec(new Runnable() { +// public void run() { +// ITool tool = domain.getActiveTool(); +// if (tool instanceof FloatingTextEditTool) { +// FloatingTextEditor editor = ((FloatingTextEditTool) tool) +// .getEditor(); +// if (editor != null && !editor.isClosed()) { +// IME ime2 = editor.getTextViewer().getTextWidget() +// .getIME(); +// final Event e = new Event(); +// e.button = event.button; +// e.character = event.character; +// e.count = event.count; +// e.data = event.data; +// e.detail = event.detail; +// e.display = event.display; +// e.doit = event.doit; +// e.end = event.end; +// e.gc = event.gc; +// e.height = event.height; +// e.index = event.index; +// e.item = event.item; +// e.keyCode = event.keyCode; +// e.keyLocation = event.keyLocation; +// e.magnification = event.magnification; +// e.rotation = event.rotation; +// e.segments = event.segments; +// e.segmentsChars = event.segmentsChars; +// e.start = event.start; +// e.stateMask = event.stateMask; +// e.text = event.text; +// e.time = event.time; +// e.touches = event.touches; +// e.type = event.type; +// e.widget = ime2; +// e.width = event.width; +// e.x = event.x; +// e.xDirection = event.xDirection; +// e.y = event.y; +// e.yDirection = event.yDirection; +// Display.getCurrent().post(e); +// +// } +// } +// } +// }); +// } + +// public static void main(String[] args) { +// final Display display = new Display(); +// final Shell shell = new Shell(display); +// shell.setBounds(200, 100, 500, 400); +// shell.setLayout(new FillLayout()); +// +// final Canvas canvas = new Canvas(shell, SWT.NONE); +// final IME ime = new IME(canvas, SWT.NONE); +// final Caret caret = new Caret(canvas, SWT.NONE); +// +// caret.setBounds(10, 10, 2, 20); +// +// ime.addListener(SWT.ImeComposition, new Listener() { +// public void handleEvent(Event event) { +// if (event.detail == SWT.COMPOSITION_CHANGED) { +// System.out.println("Composition changed: " + event.text); +// } else if (event.detail == SWT.COMPOSITION_OFFSET) { +// System.out.println("Composition require offset."); +// } else if (event.detail == SWT.COMPOSITION_SELECTION) { +// System.out.println("Composition require selection."); +// } +// } +// }); +// +// Listener canvasListener = new Listener() { +// public void handleEvent(Event event) { +// if (event.type == SWT.Verify) { +// System.out.println("Key verify: " + event.keyCode + ", " +// + event.stateMask); +// } else if (event.type == SWT.KeyDown) { +// System.out.println("Key down: " + event.keyCode + ", " +// + event.stateMask); +// } else if (event.type == SWT.Traverse) { +// System.out.println("Key traverse: " + event.detail); +// } +// } +// }; +// canvas.addListener(SWT.Verify, canvasListener); +// canvas.addListener(SWT.KeyDown, canvasListener); +// canvas.addListener(SWT.Traverse, canvasListener); +// +// shell.open(); +// +// while (!shell.isDisposed()) { +// if (!display.readAndDispatch()) { +// display.sleep(); +// } +// } +// shell.dispose(); +// display.dispose(); +// } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMindMapPreviewGenerator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMindMapPreviewGenerator.java index ffe6576cd..b5b0f5569 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMindMapPreviewGenerator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IMindMapPreviewGenerator.java @@ -1,53 +1,53 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Properties; - -import org.xmind.core.IMeta; -import org.xmind.core.ISheet; -import org.xmind.ui.mindmap.IWorkbookRef; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public interface IMindMapPreviewGenerator { - - String PREVIEW_ORIGIN_X = IMeta.ORIGIN_X; - String PREVIEW_ORIGIN_Y = IMeta.ORIGIN_Y; - String PREVIEW_BACKGROUND = IMeta.BACKGROUND_COLOR; - - /** - * Generates a preview image for a specific sheet and stores the result into - * the specified output stream. A key-value map will be returned containing - * properties of the generated preview image. - * - * @param workbookRef - * @param sheet - * @param output - * @param options - * @return - * @throws IOException - */ - Properties generateMindMapPreview(IWorkbookRef workbookRef, ISheet sheet, - OutputStream output, MindMapPreviewOptions options) - throws IOException; - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Properties; + +import org.xmind.core.IMeta; +import org.xmind.core.ISheet; +import org.xmind.ui.mindmap.IWorkbookRef; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public interface IMindMapPreviewGenerator { + + String PREVIEW_ORIGIN_X = IMeta.ORIGIN_X; + String PREVIEW_ORIGIN_Y = IMeta.ORIGIN_Y; + String PREVIEW_BACKGROUND = IMeta.BACKGROUND_COLOR; + + /** + * Generates a preview image for a specific sheet and stores the result into + * the specified output stream. A key-value map will be returned containing + * properties of the generated preview image. + * + * @param workbookRef + * @param sheet + * @param output + * @param options + * @return + * @throws IOException + */ + Properties generateMindMapPreview(IWorkbookRef workbookRef, ISheet sheet, + OutputStream output, MindMapPreviewOptions options) + throws IOException; + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IPasswordProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IPasswordProvider.java index e2fd7b224..054775408 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IPasswordProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IPasswordProvider.java @@ -1,26 +1,26 @@ -package org.xmind.ui.internal.editor; - -import org.xmind.ui.mindmap.IWorkbookRef; - -/** - * This interface is used for retrieving password from the end user. - * - * @author Ren Siu - * @since 3.6.50 - */ -public interface IPasswordProvider { - - /** - * Prompt the end user to enter the password to open the specified workbook. - * - * @param workbookRef - * the {@link IWorkbookRef} that requesting its password - * @param message - * a {@link String} stating the reason of this password request, - * or null to show the default message - * @return a {@link String} of password, or null to indicate - * that the user has canceled the whole open operation - */ - String askForPassword(IWorkbookRef workbookRef, String message); - -} +package org.xmind.ui.internal.editor; + +import org.xmind.ui.mindmap.IWorkbookRef; + +/** + * This interface is used for retrieving password from the end user. + * + * @author Ren Siu + * @since 3.6.50 + */ +public interface IPasswordProvider { + + /** + * Prompt the end user to enter the password to open the specified workbook. + * + * @param workbookRef + * the {@link IWorkbookRef} that requesting its password + * @param message + * a {@link String} stating the reason of this password request, + * or null to show the default message + * @return a {@link String} of password, or null to indicate + * that the user has canceled the whole open operation + */ + String askForPassword(IWorkbookRef workbookRef, String message); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookReferrer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookReferrer.java index 94f45a4fd..75f68cfbc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookReferrer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookReferrer.java @@ -1,39 +1,39 @@ -package org.xmind.ui.internal.editor; - -import java.io.IOException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.xmind.core.CoreException; -import org.xmind.core.IWorkbook; - -/** - * - * @author Frank Shaka - * @since 3.0 - * @deprecated - */ -@Deprecated -public interface IWorkbookReferrer { - -// void setSelection(ISelection selection, boolean reveal, boolean forceFocus); - - /** - * @deprecated - */ - @Deprecated - void savePreivew(IWorkbook workbook, IProgressMonitor monitor) - throws IOException, CoreException; - - /** - * @deprecated - */ - @Deprecated - void postSave(IProgressMonitor monitor); - - /** - * @deprecated - */ - @Deprecated - void postSaveAs(Object newKey, IProgressMonitor monitor); - -} +package org.xmind.ui.internal.editor; + +import java.io.IOException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.xmind.core.CoreException; +import org.xmind.core.IWorkbook; + +/** + * + * @author Frank Shaka + * @since 3.0 + * @deprecated + */ +@Deprecated +public interface IWorkbookReferrer { + +// void setSelection(ISelection selection, boolean reveal, boolean forceFocus); + + /** + * @deprecated + */ + @Deprecated + void savePreivew(IWorkbook workbook, IProgressMonitor monitor) + throws IOException, CoreException; + + /** + * @deprecated + */ + @Deprecated + void postSave(IProgressMonitor monitor); + + /** + * @deprecated + */ + @Deprecated + void postSaveAs(Object newKey, IProgressMonitor monitor); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookSaver.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookSaver.java index 94720ec93..d5b304296 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookSaver.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookSaver.java @@ -1,38 +1,38 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.xmind.core.IWorkbook; - -/** - * - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public interface IWorkbookSaver { - - /** - * Determines whether the target exists and the save operation will - * overwrite it. - * - * @deprecated - * @return true if the target exists and the save operationg - * will overwrite it, or false otherwise - */ - @Deprecated - boolean willOverwriteTarget(); - - /** - * Save the workbook. - * - * @deprecated - * @param monitor - * @param workbook - * @throws CoreException - */ - @Deprecated - void save(IProgressMonitor monitor, IWorkbook workbook) - throws CoreException; - -} +package org.xmind.ui.internal.editor; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.xmind.core.IWorkbook; + +/** + * + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public interface IWorkbookSaver { + + /** + * Determines whether the target exists and the save operation will + * overwrite it. + * + * @deprecated + * @return true if the target exists and the save operationg + * will overwrite it, or false otherwise + */ + @Deprecated + boolean willOverwriteTarget(); + + /** + * Save the workbook. + * + * @deprecated + * @param monitor + * @param workbook + * @throws CoreException + */ + @Deprecated + void save(IProgressMonitor monitor, IWorkbook workbook) + throws CoreException; + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LoadWorkbookJob.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LoadWorkbookJob.java index d71ffe02e..26fc71596 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LoadWorkbookJob.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LoadWorkbookJob.java @@ -1,157 +1,157 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ - -package org.xmind.ui.internal.editor; - -public class LoadWorkbookJob { -// extends Job implements IEncryptionHandler { -// -// private String inputName; -// -// private WorkbookRef workbookRef; -// -// private IDialogPaneContainer dialogContainer; -// -// private Display display; -// -// private String password = null; -// -// private boolean firstTry = true; -// -// private IProgressMonitor progress; -// -// public LoadWorkbookJob(String inputName, WorkbookRef workbookRef, -// IDialogPaneContainer dialogContainer, Display display) { -// super(NLS.bind(MindMapMessages.LoadWorkbookJob_text, inputName)); -// this.inputName = inputName; -// this.workbookRef = workbookRef; -// this.dialogContainer = dialogContainer; -// this.display = display; -// } -// -// @Override -// protected IStatus run(IProgressMonitor monitor) { -// this.progress = monitor; -// monitor.beginTask(null, 100); -// -// if (workbookRef == null) -// return Status.CANCEL_STATUS; -// -// IStorage storage = WorkbookRef.createStorage(); -// boolean wrongPassword; -// Throwable error = null; -// do { -// wrongPassword = false; -// password = null; -// storage.clear(); -// -// if (workbookRef == null) -// return Status.CANCEL_STATUS; -// -// try { -// workbookRef.loadWorkbook(storage, this, monitor); -// } catch (Throwable e) { -// CoreException coreEx = getCoreException(e); -// if (coreEx != null) { -// int errType = coreEx.getType(); -// if (errType == Core.ERROR_CANCELLATION) { -// return Status.CANCEL_STATUS; -// } -// if (errType == Core.ERROR_WRONG_PASSWORD) { -// wrongPassword = true; -// } -// } -// if (!wrongPassword) { -// error = e; -// Logger.log(e); -// } -// } -// firstTry = false; -// } while (wrongPassword); -// -// if (workbookRef.getWorkbook() == null) { -// if (error == null) { -// try { -// throw new FileNotFoundException(inputName); -// } catch (Throwable e) { -// error = e; -// } -// } -// return new Status(IStatus.WARNING, MindMapUI.PLUGIN_ID, -// IStatus.ERROR, -// MindMapMessages.LoadWorkbookJob_errorDialog_title, error); -// } -// -// return Status.OK_STATUS; -// } -// -// private CoreException getCoreException(Throwable e) { -// if (e == null) -// return null; -// if (e instanceof CoreException) -// return (CoreException) e; -// return getCoreException(e.getCause()); -// } -// -// public String retrievePassword() throws CoreException { -// if (password == null) { -// boolean canceled = !doRetrievePassword(); -// if (canceled) { -// throw new CoreException(Core.ERROR_CANCELLATION); -// } -// } -// return password; -// } -// -// @Override -// protected void canceling() { -// super.canceling(); -// display.asyncExec(new Runnable() { -// public void run() { -// dialogContainer.close(IDialogPane.CANCEL); -// } -// }); -// } -// -// private boolean doRetrievePassword() { -// final boolean[] ret = new boolean[1]; -// display.syncExec(new Runnable() { -// public void run() { -// if (progress != null) { -// progress.worked(10); -// progress.subTask(MindMapMessages.LoadWorkbookJob_retrive_password_message); -// } -// -// String message; -// if (firstTry) { -// message = MindMapMessages.LoadWorkbookJob_firstTry_message; -// } else { -// message = MindMapMessages.LoadWorkbookJob_moreTry_message; -// } -// DecryptionDialogPane dialog = new DecryptionDialogPane(); -// dialog.setContent(message, !firstTry); -// int code = dialogContainer.open(dialog); -// if (code == DecryptionDialogPane.OK) { -// password = dialog.getPassword(); -// ret[0] = true; -// } else { -// cancel(); -// ret[0] = false; -// } -// } -// }); -// return ret[0]; -// } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ + +package org.xmind.ui.internal.editor; + +public class LoadWorkbookJob { +// extends Job implements IEncryptionHandler { +// +// private String inputName; +// +// private WorkbookRef workbookRef; +// +// private IDialogPaneContainer dialogContainer; +// +// private Display display; +// +// private String password = null; +// +// private boolean firstTry = true; +// +// private IProgressMonitor progress; +// +// public LoadWorkbookJob(String inputName, WorkbookRef workbookRef, +// IDialogPaneContainer dialogContainer, Display display) { +// super(NLS.bind(MindMapMessages.LoadWorkbookJob_text, inputName)); +// this.inputName = inputName; +// this.workbookRef = workbookRef; +// this.dialogContainer = dialogContainer; +// this.display = display; +// } +// +// @Override +// protected IStatus run(IProgressMonitor monitor) { +// this.progress = monitor; +// monitor.beginTask(null, 100); +// +// if (workbookRef == null) +// return Status.CANCEL_STATUS; +// +// IStorage storage = WorkbookRef.createStorage(); +// boolean wrongPassword; +// Throwable error = null; +// do { +// wrongPassword = false; +// password = null; +// storage.clear(); +// +// if (workbookRef == null) +// return Status.CANCEL_STATUS; +// +// try { +// workbookRef.loadWorkbook(storage, this, monitor); +// } catch (Throwable e) { +// CoreException coreEx = getCoreException(e); +// if (coreEx != null) { +// int errType = coreEx.getType(); +// if (errType == Core.ERROR_CANCELLATION) { +// return Status.CANCEL_STATUS; +// } +// if (errType == Core.ERROR_WRONG_PASSWORD) { +// wrongPassword = true; +// } +// } +// if (!wrongPassword) { +// error = e; +// Logger.log(e); +// } +// } +// firstTry = false; +// } while (wrongPassword); +// +// if (workbookRef.getWorkbook() == null) { +// if (error == null) { +// try { +// throw new FileNotFoundException(inputName); +// } catch (Throwable e) { +// error = e; +// } +// } +// return new Status(IStatus.WARNING, MindMapUI.PLUGIN_ID, +// IStatus.ERROR, +// MindMapMessages.LoadWorkbookJob_errorDialog_title, error); +// } +// +// return Status.OK_STATUS; +// } +// +// private CoreException getCoreException(Throwable e) { +// if (e == null) +// return null; +// if (e instanceof CoreException) +// return (CoreException) e; +// return getCoreException(e.getCause()); +// } +// +// public String retrievePassword() throws CoreException { +// if (password == null) { +// boolean canceled = !doRetrievePassword(); +// if (canceled) { +// throw new CoreException(Core.ERROR_CANCELLATION); +// } +// } +// return password; +// } +// +// @Override +// protected void canceling() { +// super.canceling(); +// display.asyncExec(new Runnable() { +// public void run() { +// dialogContainer.close(IDialogPane.CANCEL); +// } +// }); +// } +// +// private boolean doRetrievePassword() { +// final boolean[] ret = new boolean[1]; +// display.syncExec(new Runnable() { +// public void run() { +// if (progress != null) { +// progress.worked(10); +// progress.subTask(MindMapMessages.LoadWorkbookJob_retrive_password_message); +// } +// +// String message; +// if (firstTry) { +// message = MindMapMessages.LoadWorkbookJob_firstTry_message; +// } else { +// message = MindMapMessages.LoadWorkbookJob_moreTry_message; +// } +// DecryptionDialogPane dialog = new DecryptionDialogPane(); +// dialog.setContent(message, !firstTry); +// int code = dialogContainer.open(dialog); +// if (code == DecryptionDialogPane.OK) { +// password = dialog.getPassword(); +// ret[0] = true; +// } else { +// cancel(); +// ret[0] = false; +// } +// } +// }); +// return ret[0]; +// } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileSaveWizard.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileSaveWizard.java index 2e75ad9fc..bba65cc64 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileSaveWizard.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileSaveWizard.java @@ -1,87 +1,87 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.dialogs.DialogUtils; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.wizards.ISaveContext; -import org.xmind.ui.wizards.ISaveWizard; -import org.xmind.ui.wizards.SaveOptions; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class LocalFileSaveWizard implements ISaveWizard { - - public static final String ID = "org.xmind.ui.saveWizards.localFile"; //$NON-NLS-1$ - - public LocalFileSaveWizard() { - } - - @Override - public URI askForTargetURI(ISaveContext context, SaveOptions options) { - String proposalName = options.proposalName(); - URI oldURI = options.oldURI(); - - // Hide busy cursor - List cursorHiddenShells = new ArrayList(); - Display display = Display.getCurrent(); - Shell[] shells = display.getShells(); - Cursor busyCursor = display.getSystemCursor(SWT.CURSOR_WAIT); - for (Shell shell : shells) { - Cursor cursor = shell.getCursor(); - if (cursor != null && cursor.equals(busyCursor)) { - shell.setCursor(null); - cursorHiddenShells.add(shell); - } - } - - // Show save dialog - String filterExtension = MindMapUI.FILE_EXT_XMIND; - String extensionFullName = "*" + filterExtension; //$NON-NLS-1$ - String filterFullName; - if (Platform.OS_MACOSX.equals(Platform.getOS())) { - filterFullName = NLS.bind("{0} ({1})", //$NON-NLS-1$ - DialogMessages.WorkbookFilterName, extensionFullName); - } else { - filterFullName = DialogMessages.WorkbookFilterName; - } - - String dirPath = null; - if (oldURI != null - && FilePathParser.URI_SCHEME.equals(oldURI.getScheme())) { - dirPath = new File(oldURI).getParent(); - } - - String result = DialogUtils.save(display.getActiveShell(), proposalName, - new String[] { extensionFullName }, - new String[] { filterFullName }, 0, dirPath); - if (result == null) - return null; - - if ("win32".equals(SWT.getPlatform())) { //$NON-NLS-1$ - if (!result.endsWith(filterExtension)) { - result = result + filterExtension; - } - } - return new File(result).toURI(); - } - - public int getPriorityFor(ISaveContext context, SaveOptions options) { - return 50; - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.wizards.ISaveContext; +import org.xmind.ui.wizards.ISaveWizard; +import org.xmind.ui.wizards.SaveOptions; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class LocalFileSaveWizard implements ISaveWizard { + + public static final String ID = "org.xmind.ui.saveWizards.localFile"; //$NON-NLS-1$ + + public LocalFileSaveWizard() { + } + + @Override + public URI askForTargetURI(ISaveContext context, SaveOptions options) { + String proposalName = options.proposalName(); + URI oldURI = options.oldURI(); + + // Hide busy cursor + List cursorHiddenShells = new ArrayList(); + Display display = Display.getCurrent(); + Shell[] shells = display.getShells(); + Cursor busyCursor = display.getSystemCursor(SWT.CURSOR_WAIT); + for (Shell shell : shells) { + Cursor cursor = shell.getCursor(); + if (cursor != null && cursor.equals(busyCursor)) { + shell.setCursor(null); + cursorHiddenShells.add(shell); + } + } + + // Show save dialog + String filterExtension = MindMapUI.FILE_EXT_XMIND; + String extensionFullName = "*" + filterExtension; //$NON-NLS-1$ + String filterFullName; + if (Platform.OS_MACOSX.equals(Platform.getOS())) { + filterFullName = NLS.bind("{0} ({1})", //$NON-NLS-1$ + DialogMessages.WorkbookFilterName, extensionFullName); + } else { + filterFullName = DialogMessages.WorkbookFilterName; + } + + String dirPath = null; + if (oldURI != null + && FilePathParser.URI_SCHEME.equals(oldURI.getScheme())) { + dirPath = new File(oldURI).getParent(); + } + + String result = DialogUtils.save(display.getActiveShell(), proposalName, + new String[] { extensionFullName }, + new String[] { filterFullName }, 0, dirPath); + if (result == null) + return null; + + if ("win32".equals(SWT.getPlatform())) { //$NON-NLS-1$ + if (!result.endsWith(filterExtension)) { + result = result + filterExtension; + } + } + return new File(result).toURI(); + } + + public int getPriorityFor(ISaveContext context, SaveOptions options) { + return 50; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRef.java index a60b881df..8aea32c2e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRef.java @@ -1,745 +1,750 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jface.dialogs.ErrorSupportProvider; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.AbstractHyperlink; -import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IDeserializer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IMeta; -import org.xmind.core.IRevision; -import org.xmind.core.IRevisionManager; -import org.xmind.core.IRevisionRepository; -import org.xmind.core.ISerializer; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.io.DirectoryOutputTarget; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.CloneHandler; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.ProgressReporter; -import org.xmind.ui.blackbox.BlackBox; -import org.xmind.ui.blackbox.IBlackBoxMap; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.BlackBoxDialog; -import org.xmind.ui.internal.handlers.OpenBlackBoxDialogHandler; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.internal.utils.CommandUtils; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapImageExporter; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.ImageFormat; -import org.xmind.ui.util.Logger; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class LocalFileWorkbookRef extends AbstractWorkbookRef { - - private static boolean DEBUG_BACKUP = MindMapUIPlugin - .isDebugging(MindMapUIPlugin.OPTION_LOCAL_FILE_BACKUP); - - private static class LocalFileBackup { - - private final File file; - - private final File tempFile; - - /** - * - */ - public LocalFileBackup(File file) { - this.file = file; - this.tempFile = new File(Core.getWorkspace().getTempFile( - "saving/" + UUID.randomUUID() + MindMapUI.FILE_EXT_XMIND)); //$NON-NLS-1$ - } - - public void makeBackup() { - if (!file.exists() || !file.canRead()) { - tempFile.delete(); - return; - } - - if (DEBUG_BACKUP) { - System.out.println("Making local file backup for: " //$NON-NLS-1$ - + file.getAbsolutePath()); - System.out.println(" to: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ - } - try { - FileUtils.transfer(file, tempFile); - } catch (IOException e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, - MindMapUIPlugin.PLUGIN_ID, - "Failed to make backup of local file: " //$NON-NLS-1$ - + file.getAbsolutePath(), - e)); - } - } - - public void restoreBackup() { - if (!tempFile.exists() || !tempFile.canRead()) { - return; - } - - if (DEBUG_BACKUP) { - System.out.println("Restoring local file backup for: " //$NON-NLS-1$ - + file.getAbsolutePath()); - System.out.println(" from: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ - } - try { - FileUtils.transfer(tempFile, file); - } catch (IOException e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, - MindMapUIPlugin.PLUGIN_ID, - "Failed to restore backup of local file: " //$NON-NLS-1$ - + file.getAbsolutePath(), - e)); - } - } - - public void deleteBackup() { - if (DEBUG_BACKUP) { - System.out.println("Deleting local file backup for: " //$NON-NLS-1$ - + file.getAbsolutePath()); - System.out.println(" at: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ - } - tempFile.delete(); - } - - } - - private class LocalFileErrorSupportProvider - extends AbstractStatusAreaProvider { - - /* - * (non-Javadoc) - * @see org.eclipse.ui.statushandlers.AbstractStatusAreaProvider# - * createSupportArea(org.eclipse.swt.widgets.Composite, - * org.eclipse.ui.statushandlers.StatusAdapter) - */ - @Override - public Control createSupportArea(Composite parent, - StatusAdapter statusAdapter) { - IBlackBoxMap[] blackBoxMaps = BlackBox.getMaps(); - if (!MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE) - || (blackBoxMaps == null || blackBoxMaps.length == 0)) - return null; - Composite hyperParent = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - hyperParent.setLayout(layout); - hyperParent.setBackground(parent.getBackground()); - - Label preLink = new Label(hyperParent, SWT.NONE); - preLink.setText( - MindMapMessages.LoadWorkbookJob_errorDialog_Pre_message); - preLink.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, false, false)); - preLink.setBackground(parent.getBackground()); - - Hyperlink hyperlink = new Hyperlink(hyperParent, SWT.NONE); - hyperlink.setBackground(parent.getBackground()); - hyperlink.setUnderlined(true); - hyperlink.setText( - MindMapMessages.LoadWorkbookJob_errorDialog_GoToBackup_message); - hyperlink.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, true, false)); - hyperlink.addHyperlinkListener(new HyperlinkAdapter() { - @Override - public void linkActivated(HyperlinkEvent e) { - showBlackBoxView(); - } - }); - hyperlink.setFont( - FontUtils.getBoldRelative(JFaceResources.DEFAULT_FONT, 0)); - /* Prevent focus box from being painted: */ - try { - Field fPaintFocus = AbstractHyperlink.class - .getDeclaredField("paintFocus"); //$NON-NLS-1$ - fPaintFocus.setAccessible(true); - fPaintFocus.set(hyperlink, false); - } catch (Throwable e) { - // ignore - } - - return hyperParent; - } - - private void showBlackBoxView() { - final File damagedFile = getFile(); - if (PlatformUI.isWorkbenchRunning()) { - final IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - final IWorkbenchPage page = window.getActivePage(); - if (page != null) { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - CommandUtils.executeCommand( - "org.xmind.ui.dialog.openBlackBoxDialog", //$NON-NLS-1$ - window); - - //set damaged file. - Object data = Display.getCurrent() - .getActiveShell().getData( - OpenBlackBoxDialogHandler.BLACK_BOX_DIALOG_DATA_KEY); - if (data instanceof BlackBoxDialog) { - BlackBoxDialog dialog = (BlackBoxDialog) data; - dialog.setDamagedFile(damagedFile); - } - } - }); - } - } - } - } - - } - - private final LocalFileBackup backup; - - private long timestamp; - - private final ErrorSupportProvider errorSupportProvider; - - protected LocalFileWorkbookRef(URI uri, IMemento memento) { - super(uri, memento); - Assert.isNotNull(uri); - Assert.isLegal(FilePathParser.URI_SCHEME.equals(uri.getScheme()), - "Invalid file URI: " + uri.toString()); //$NON-NLS-1$ - this.backup = new LocalFileBackup(new File(uri)); - this.errorSupportProvider = new LocalFileErrorSupportProvider(); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.AbstractWorkbookRef#getAdapter(java.lang. - * Class) - */ - @Override - public T getAdapter(Class adapter) { - if (ErrorSupportProvider.class.equals(adapter)) { - return adapter.cast(errorSupportProvider); - } - return super.getAdapter(adapter); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.editor.AbstractWorkbookRef#getSaveWizardId() - */ - @Override - public String getSaveWizardId() { - return LocalFileSaveWizard.ID; - } - - private File getFile() { - return new File(getURI()); - } - - @Override - public String getName() { - String name = getFile().getName(); - if (name != null) { - int dotIndex = name.lastIndexOf('.'); - if (dotIndex < 0) - return name; - return name.substring(0, dotIndex); - } - return super.getName(); - } - - @Override - public String getDescription() { - return getFile().getAbsolutePath(); - } - - @Override - public int hashCode() { - return getFile().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof LocalFileWorkbookRef)) - return false; - LocalFileWorkbookRef that = (LocalFileWorkbookRef) obj; - File thisFile = this.getFile(); - File thatFile = that.getFile(); - return thisFile == thatFile - || (thisFile != null && thisFile.equals(thatFile)); - } - - @Override - public String toString() { - return getFile().toString(); - } - - @Override - public boolean canSave() { - return true; - } - - @Override - public boolean canImportFrom(IWorkbookRef source) { - return true; - } - - /* - * (non-Javadoc) - * @see org.xmind.gef.ui.editor.Editable#getModificationTime() - */ - @Override - public long getModificationTime() { - return getFile().lastModified(); - } - - @Override - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - File file = new File(uri); - try { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.setWorkbookStorage(getTempStorage()); - InputStream stream = null; - try { - if (file.isDirectory()) { - deserializer.setInputSource(new DirectoryInputSource(file)); - } else { - stream = new FileInputStream(file); - deserializer.setInputStream(stream); - } - ProgressReporter reporter = new ProgressReporter(monitor); - deserializer.deserializeManifest(reporter); - String passwordHint = deserializer.getManifest() - .getPasswordHint(); - getEncryptable().setPasswordHint(passwordHint); - deserializer.deserialize(reporter); - } finally { - if (stream != null) { - stream.close(); - } - } - return deserializer.getWorkbook(); - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - if (e.getType() == Core.ERROR_CANCELLATION) - throw new InterruptedException(); - if (e.getType() == Core.ERROR_WRONG_PASSWORD) { - if (getEncryptable() != null) { - getEncryptable().reset(); - } - } - throw new InvocationTargetException(e); - } - } - - @Override - protected void doSaveWorkbookToURI(IProgressMonitor monitor, - IWorkbook workbook, URI uri) - throws InterruptedException, InvocationTargetException { - doSaveWorkbookToURIFromSource(monitor, workbook, uri, null, null); - } - - protected void doSaveWorkbookToURIFromSource(IProgressMonitor monitor, - IWorkbook workbook, URI uri, IWorkbookRef source, - IWorkbook sourceWorkbook) - throws InterruptedException, InvocationTargetException { - final Set encryptionIgnoredEntries = new HashSet(); - - boolean previewSaved = false; - - if (source != null) { - try { - InputStream previewData = source.getPreviewImageData( - sourceWorkbook.getPrimarySheet().getId(), null); - if (previewData != null) { - try { - IFileEntry previewEntry = workbook.getManifest() - .createFileEntry(MindMapImageExporter - .toThumbnailArchivePath( - ImageFormat.PNG)); - previewEntry.decreaseReference(); - previewEntry.increaseReference(); - - OutputStream output = previewEntry.openOutputStream(); - try { - FileUtils.transfer(previewData, output, false); - } finally { - output.close(); - } - encryptionIgnoredEntries.add(previewEntry.getPath()); - } finally { - previewData.close(); - } - previewSaved = true; - } - } catch (IOException e) { - Logger.log(e, "Failed to import preview image"); //$NON-NLS-1$ - } - } - - if (!previewSaved) { - savePreviewImage(workbook, encryptionIgnoredEntries); - } - - //save revisions, and then trim them. - try { - saveRevisions(workbook); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - - File file = new File(uri); - - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setEntryStreamNormalizer(getEncryptionHandler()); - serializer.setEncryptionIgnoredEntries(encryptionIgnoredEntries - .toArray(new String[encryptionIgnoredEntries.size()])); - - /// set password hint to manifest - String passwordHint = getEncryptable().getPasswordHint(); - if (passwordHint == null && source != null) { - IEncryptable encryptable = source.getAdapter(IEncryptable.class); - if (encryptable != null) { - passwordHint = encryptable.getPasswordHint(); - } - } - if (passwordHint != null) - workbook.getManifest().setPasswordHint(passwordHint); - try { - OutputStream stream = null; - try { - if (file.isDirectory()) { - backup.deleteBackup(); - serializer.setOutputTarget(new DirectoryOutputTarget(file)); - } else { - backup.makeBackup(); - stream = new FileOutputStream(file); - serializer.setOutputStream(stream); - } - serializer.serialize(new ProgressReporter(monitor)); - - backup.deleteBackup(); - - } finally { - if (stream != null) { - stream.close(); - } - } - } catch (IOException e) { - backup.restoreBackup(); - throw new InvocationTargetException(e); - } catch (CoreException e) { - backup.restoreBackup(); - if (e.getType() == Core.ERROR_CANCELLATION) - throw new InterruptedException(); - if (e.getType() == Core.ERROR_WRONG_PASSWORD) { - if (getEncryptable() != null) { - getEncryptable().reset(); - } - } - throw new InvocationTargetException(e); - } - } - - /** - * @param workbook - * @param encryptionIgnoredEntries - * @throws InvocationTargetException - */ - private void savePreviewImage(IWorkbook workbook, - final Set encryptionIgnoredEntries) - throws InvocationTargetException { - IMindMapPreviewGenerator previewGenerator = findPreviewGenerator(); - if (previewGenerator != null) { - ImageFormat previewFormat = ImageFormat.PNG; - IFileEntry entry = workbook.getManifest().createFileEntry( - MindMapImageExporter.toThumbnailArchivePath(previewFormat), - previewFormat.getMediaType()); - entry.decreaseReference(); - entry.increaseReference(); - - final Properties previewProperties; - try { - OutputStream previewOutput = entry.openOutputStream(); - try { - previewProperties = previewGenerator.generateMindMapPreview( - this, workbook.getPrimarySheet(), previewOutput, - null); - } finally { - previewOutput.close(); - } - } catch (IOException e) { - throw new InvocationTargetException(e); - } - workbook.getMeta().setValue(IMeta.ORIGIN_X, previewProperties - .getProperty(IMindMapPreviewGenerator.PREVIEW_ORIGIN_X)); - workbook.getMeta().setValue(IMeta.ORIGIN_Y, previewProperties - .getProperty(IMindMapPreviewGenerator.PREVIEW_ORIGIN_Y)); - workbook.getMeta().setValue(IMeta.BACKGROUND_COLOR, - previewProperties.getProperty( - IMindMapPreviewGenerator.PREVIEW_BACKGROUND)); - - encryptionIgnoredEntries.add(entry.getPath()); - } - } - - private void saveRevisions(IWorkbook workbook) throws CoreException { - if (!isContentDirty(workbook) || !shouldSaveNewRevisions(workbook)) - return; - - IRevisionRepository repo = workbook.getRevisionRepository(); - for (ISheet sheet : workbook.getSheets()) { - IRevisionManager manager = repo.getRevisionManager(sheet.getId(), - IRevision.SHEET); - IRevision latestRevision = manager.getLatestRevision(); - if (latestRevision == null || sheet.getModifiedTime() == 0 || sheet - .getModifiedTime() > latestRevision.getTimestamp()) { - try { - manager.addRevision(sheet); - } catch (Throwable e) { - throw new CoreException(Core.ERROR_INVALID_ARGUMENT, - "Invalid content for revisions."); //$NON-NLS-1$ - } - } - } - } - - private boolean isContentDirty(IWorkbook workbook) { - if (workbook == null) - return false; - if (getCommandStack() != null && getCommandStack().isDirty()) - return true; - return workbook instanceof ICoreEventSource2 - && ((ICoreEventSource2) workbook) - .hasOnceListeners(Core.WorkbookPreSaveOnce); - } - - private boolean shouldSaveNewRevisions(IWorkbook workbook) { - String value = workbook.getMeta() - .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); - return value == null || IMeta.V_YES.equalsIgnoreCase(value); - } - - @Override - protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) - throws InterruptedException, InvocationTargetException { - SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - - IWorkbook sourceWorkbook = source.getWorkbook(); - Assert.isTrue(sourceWorkbook != null); - URI targetURI = getURI(); - Assert.isTrue(targetURI != null); - - IStorage storage = getTempStorage(); - - IEncryptable sourceEncryptable = source.getAdapter(IEncryptable.class); - if (sourceEncryptable != null && sourceEncryptable.hasPassword() - && sourceEncryptable instanceof WorkbookRefEncryptable) { -// getEncryptable() -// .setEncryptor(((WorkbookRefEncryptable) sourceEncryptable) -// .getEncryptor()); - getEncryptable().setPassword(sourceEncryptable.getPassword()); - getEncryptable() - .setPasswordHint(sourceEncryptable.getPasswordHint()); - } - - doClearTempStorageBeforeImport(subMonitor.newChild(5), storage); - - try { - IWorkbook workbook = doCloneWorkbookForImport( - subMonitor.newChild(40), sourceWorkbook, source.getURI(), - storage); - - doSaveWorkbookToURIFromSource(subMonitor.newChild(50), workbook, - targetURI, source, sourceWorkbook); - - } finally { - subMonitor.setWorkRemaining(5); - doClearTempStorageAfterImport(subMonitor.newChild(5), storage); - } - - } - - protected void doClearTempStorageBeforeImport(IProgressMonitor monitor, - IStorage storage) - throws InterruptedException, InvocationTargetException { - storage.clear(); - } - - protected void doClearTempStorageAfterImport(IProgressMonitor monitor, - IStorage storage) { - storage.clear(); - } - - protected IWorkbook doCloneWorkbookForImport(IProgressMonitor monitor, - IWorkbook sourceWorkbook, URI sourceURI, IStorage storage) - throws InterruptedException, InvocationTargetException { - try { - IWorkbook workbook = Core.getWorkbookBuilder() - .createWorkbook(storage); - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.setEntryStreamNormalizer(getEncryptionHandler()); - serializer.serialize(null); - - new CloneHandler().withWorkbooks(sourceWorkbook, workbook) - .copyWorkbookContents(); - - String oldFilePath; - if (sourceURI != null && FilePathParser.URI_SCHEME - .equals(sourceURI.getScheme())) { - oldFilePath = new File(sourceURI).getAbsolutePath(); - } else { - oldFilePath = null; - } - updateAllRelativeFileHyperlinks(workbook, oldFilePath, - getFile().getAbsolutePath()); - - return workbook; - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - if (e.getType() == Core.ERROR_CANCELLATION) - throw new InterruptedException(); - throw new InvocationTargetException(e); - } - } - - private void updateAllRelativeFileHyperlinks(IWorkbook workbook, - String oldFilePath, String newFilePath) { - String oldBase; - if (oldFilePath == null) { - oldBase = FilePathParser.ABSTRACT_FILE_BASE; - } else { - oldBase = new File(oldFilePath).getParent(); - } - - String newBase = new File(newFilePath).getParent(); - if (oldBase.equals(newBase)) - return; - - List sheets = workbook.getSheets(); - for (ISheet sheet : sheets) { - updateRelativeFileHyperlinks(sheet.getRootTopic(), oldBase, - newBase); - } - } - - private void updateRelativeFileHyperlinks(ITopic topic, String oldBase, - String newBase) { - String hyperlink = topic.getHyperlink(); - if (FilePathParser.isFileURI(hyperlink)) { - String path = FilePathParser.toPath(hyperlink); - if (FilePathParser.isPathRelative(path)) { - String absolutePath = FilePathParser.toAbsolutePath(oldBase, - path); - hyperlink = FilePathParser.toRelativePath(newBase, - absolutePath); - topic.setHyperlink(FilePathParser.toURI(hyperlink, true)); - } - } - List topics = topic.getAllChildren(); - if (topics != null) { - for (ITopic temptopic : topics) { - updateRelativeFileHyperlinks(temptopic, oldBase, newBase); - } - } - } - - @Override - public boolean activateNotifier() { - File file = getFile(); - if (!file.exists()) { - fileRemoved(MindMapMessages.LocalFileWorkbookRef_removeDialog_title, - MindMapMessages.LocalFileWorkbookRef_removeDialog_message, - new String[] { - MindMapMessages.LocalFileWorkbookRef_removeDialog_saveAs_button, - MindMapMessages.LocalFileWorkbookRef_removeDialog_delete_button }, - false); - return true; - } else if (file.lastModified() != timestamp) { - fileChanged(MindMapMessages.LocalFileWorkbookRef_changeDialog_title, - MindMapMessages.LocalFileWorkbookRef_changeDialog_message, - new String[] { - MindMapMessages.LocalFileWorkbookRef_changeDialog_update_button, - MindMapMessages.LocalFileWorkbookRef_changeDialog_cancel_button }); - return true; - } - return false; - } - - @Override - public void open(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - timestamp = getFile().lastModified(); - super.open(monitor); - } - - @Override - public void save(IProgressMonitor monitor) - throws InterruptedException, InvocationTargetException { - super.save(monitor); - timestamp = getFile().lastModified(); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.dialogs.ErrorSupportProvider; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.AbstractHyperlink; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IDeserializer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IMeta; +import org.xmind.core.IRevision; +import org.xmind.core.IRevisionManager; +import org.xmind.core.IRevisionRepository; +import org.xmind.core.ISerializer; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.io.DirectoryOutputTarget; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.CloneHandler; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.ProgressReporter; +import org.xmind.ui.blackbox.BlackBox; +import org.xmind.ui.blackbox.IBlackBoxMap; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.BlackBoxDialog; +import org.xmind.ui.internal.handlers.OpenBlackBoxDialogHandler; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.internal.utils.CommandUtils; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapImageExporter; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.ImageFormat; +import org.xmind.ui.util.Logger; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class LocalFileWorkbookRef extends AbstractWorkbookRef { + + private static boolean DEBUG_BACKUP = MindMapUIPlugin + .isDebugging(MindMapUIPlugin.OPTION_LOCAL_FILE_BACKUP); + + private static class LocalFileBackup { + + private final File file; + + private final File tempFile; + + /** + * + */ + public LocalFileBackup(File file) { + this.file = file; + this.tempFile = new File(Core.getWorkspace().getTempFile( + "saving/" + UUID.randomUUID() + MindMapUI.FILE_EXT_XMIND)); //$NON-NLS-1$ + } + + public void makeBackup() { + if (!file.exists() || !file.canRead()) { + tempFile.delete(); + return; + } + + if (DEBUG_BACKUP) { + System.out.println("Making local file backup for: " //$NON-NLS-1$ + + file.getAbsolutePath()); + System.out.println(" to: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ + } + try { + FileUtils.transfer(file, tempFile); + } catch (IOException e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, + MindMapUIPlugin.PLUGIN_ID, + "Failed to make backup of local file: " //$NON-NLS-1$ + + file.getAbsolutePath(), + e)); + } + } + + public void restoreBackup() { + if (!tempFile.exists() || !tempFile.canRead()) { + return; + } + + if (DEBUG_BACKUP) { + System.out.println("Restoring local file backup for: " //$NON-NLS-1$ + + file.getAbsolutePath()); + System.out.println(" from: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ + } + try { + FileUtils.transfer(tempFile, file); + } catch (IOException e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, + MindMapUIPlugin.PLUGIN_ID, + "Failed to restore backup of local file: " //$NON-NLS-1$ + + file.getAbsolutePath(), + e)); + } + } + + public void deleteBackup() { + if (DEBUG_BACKUP) { + System.out.println("Deleting local file backup for: " //$NON-NLS-1$ + + file.getAbsolutePath()); + System.out.println(" at: " + tempFile.getAbsolutePath()); //$NON-NLS-1$ + } + tempFile.delete(); + } + + } + + private class LocalFileErrorSupportProvider + extends AbstractStatusAreaProvider { + + /* + * (non-Javadoc) + * @see org.eclipse.ui.statushandlers.AbstractStatusAreaProvider# + * createSupportArea(org.eclipse.swt.widgets.Composite, + * org.eclipse.ui.statushandlers.StatusAdapter) + */ + @Override + public Control createSupportArea(Composite parent, + StatusAdapter statusAdapter) { + IBlackBoxMap[] blackBoxMaps = BlackBox.getMaps(); + if (!MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE) + || (blackBoxMaps == null || blackBoxMaps.length == 0)) + return null; + Composite hyperParent = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + hyperParent.setLayout(layout); + hyperParent.setBackground(parent.getBackground()); + + Label preLink = new Label(hyperParent, SWT.NONE); + preLink.setText( + MindMapMessages.LoadWorkbookJob_errorDialog_Pre_message); + preLink.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, false, false)); + preLink.setBackground(parent.getBackground()); + + Hyperlink hyperlink = new Hyperlink(hyperParent, SWT.NONE); + hyperlink.setBackground(parent.getBackground()); + hyperlink.setUnderlined(true); + hyperlink.setText( + MindMapMessages.LoadWorkbookJob_errorDialog_GoToBackup_message); + hyperlink.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, true, false)); + hyperlink.addHyperlinkListener(new HyperlinkAdapter() { + @Override + public void linkActivated(HyperlinkEvent e) { + showBlackBoxView(); + } + }); + hyperlink.setFont( + FontUtils.getBoldRelative(JFaceResources.DEFAULT_FONT, 0)); + /* Prevent focus box from being painted: */ + try { + Field fPaintFocus = AbstractHyperlink.class + .getDeclaredField("paintFocus"); //$NON-NLS-1$ + fPaintFocus.setAccessible(true); + fPaintFocus.set(hyperlink, false); + } catch (Throwable e) { + // ignore + } + + return hyperParent; + } + + private void showBlackBoxView() { + final File damagedFile = getFile(); + if (PlatformUI.isWorkbenchRunning()) { + final IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window != null) { + final IWorkbenchPage page = window.getActivePage(); + if (page != null) { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + CommandUtils.executeCommand( + "org.xmind.ui.dialog.openBlackBoxDialog", //$NON-NLS-1$ + window); + + //set damaged file. + Object data = Display.getCurrent() + .getActiveShell().getData( + OpenBlackBoxDialogHandler.BLACK_BOX_DIALOG_DATA_KEY); + if (data instanceof BlackBoxDialog) { + BlackBoxDialog dialog = (BlackBoxDialog) data; + dialog.setDamagedFile(damagedFile); + } + } + }); + } + } + } + } + + } + + private final LocalFileBackup backup; + + private long timestamp; + + private final ErrorSupportProvider errorSupportProvider; + + protected LocalFileWorkbookRef(URI uri, IMemento memento) { + super(uri, memento); + Assert.isNotNull(uri); + Assert.isLegal(FilePathParser.URI_SCHEME.equals(uri.getScheme()), + "Invalid file URI: " + uri.toString()); //$NON-NLS-1$ + this.backup = new LocalFileBackup(new File(uri)); + this.errorSupportProvider = new LocalFileErrorSupportProvider(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.editor.AbstractWorkbookRef#getAdapter(java.lang. + * Class) + */ + @Override + public T getAdapter(Class adapter) { + if (ErrorSupportProvider.class.equals(adapter)) { + return adapter.cast(errorSupportProvider); + } + return super.getAdapter(adapter); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.editor.AbstractWorkbookRef#getSaveWizardId() + */ + @Override + public String getSaveWizardId() { + return LocalFileSaveWizard.ID; + } + + private File getFile() { + return new File(getURI()); + } + + @Override + public String getName() { + String name = getFile().getName(); + if (name != null) { + int dotIndex = name.lastIndexOf('.'); + if (dotIndex < 0) + return name; + return name.substring(0, dotIndex); + } + return super.getName(); + } + + @Override + public String getDescription() { + return getFile().getAbsolutePath(); + } + + @Override + public int hashCode() { + return getFile().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof LocalFileWorkbookRef)) + return false; + LocalFileWorkbookRef that = (LocalFileWorkbookRef) obj; + File thisFile = this.getFile(); + File thatFile = that.getFile(); + return thisFile == thatFile + || (thisFile != null && thisFile.equals(thatFile)); + } + + @Override + public String toString() { + return getFile().toString(); + } + + @Override + public boolean canSave() { + return true; + } + + @Override + public boolean canImportFrom(IWorkbookRef source) { + return true; + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.ui.editor.Editable#getModificationTime() + */ + @Override + public long getModificationTime() { + return getFile().lastModified(); + } + + @Override + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + File file = new File(uri); + try { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.setWorkbookStorage(getTempStorage()); + InputStream stream = null; + try { + if (file.isDirectory()) { + deserializer.setInputSource(new DirectoryInputSource(file)); + } else { + stream = new FileInputStream(file); + deserializer.setInputStream(stream); + } + ProgressReporter reporter = new ProgressReporter(monitor); + deserializer.deserializeManifest(reporter); + String passwordHint = deserializer.getManifest() + .getPasswordHint(); + getEncryptable().setPasswordHint(passwordHint); + deserializer.deserialize(reporter); + } finally { + if (stream != null) { + stream.close(); + } + } + return deserializer.getWorkbook(); + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + if (e.getType() == Core.ERROR_CANCELLATION) + throw new InterruptedException(); + if (e.getType() == Core.ERROR_WRONG_PASSWORD) { + if (getEncryptable() != null) { + getEncryptable().reset(); + } + } + throw new InvocationTargetException(e); + } + } + + @Override + protected void doSaveWorkbookToURI(IProgressMonitor monitor, + IWorkbook workbook, URI uri) + throws InterruptedException, InvocationTargetException { + doSaveWorkbookToURIFromSource(monitor, workbook, uri, null, null); + } + + protected void doSaveWorkbookToURIFromSource(IProgressMonitor monitor, + IWorkbook workbook, URI uri, IWorkbookRef source, + IWorkbook sourceWorkbook) + throws InterruptedException, InvocationTargetException { + final Set encryptionIgnoredEntries = new HashSet(); + + boolean previewSaved = false; + + if (source != null) { + try { + InputStream previewData = source.getPreviewImageData( + sourceWorkbook.getPrimarySheet().getId(), null); + if (previewData != null) { + try { + IFileEntry previewEntry = workbook.getManifest() + .createFileEntry(MindMapImageExporter + .toThumbnailArchivePath( + ImageFormat.PNG)); + previewEntry.decreaseReference(); + previewEntry.increaseReference(); + + OutputStream output = previewEntry.openOutputStream(); + try { + FileUtils.transfer(previewData, output, false); + } finally { + output.close(); + } + encryptionIgnoredEntries.add(previewEntry.getPath()); + } finally { + previewData.close(); + } + previewSaved = true; + } + } catch (IOException e) { + Logger.log(e, "Failed to import preview image"); //$NON-NLS-1$ + } + } + + if (!previewSaved) { + savePreviewImage(workbook, encryptionIgnoredEntries); + } + + //save revisions, and then trim them. + try { + saveRevisions(workbook); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } + + File file = new File(uri); + + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setEntryStreamNormalizer(getEncryptionHandler()); + serializer.setEncryptionIgnoredEntries(encryptionIgnoredEntries + .toArray(new String[encryptionIgnoredEntries.size()])); + + /// set password hint to manifest + String passwordHint = getEncryptable().getPasswordHint(); + if (passwordHint == null && source != null) { + IEncryptable encryptable = source.getAdapter(IEncryptable.class); + if (encryptable != null) { + passwordHint = encryptable.getPasswordHint(); + } + } + if (passwordHint != null) + workbook.getManifest().setPasswordHint(passwordHint); + try { + OutputStream stream = null; + try { + if (file.isDirectory()) { + backup.deleteBackup(); + serializer.setOutputTarget(new DirectoryOutputTarget(file)); + } else { + backup.makeBackup(); + stream = new FileOutputStream(file); + serializer.setOutputStream(stream); + } + serializer.serialize(new ProgressReporter(monitor)); + + backup.deleteBackup(); + + } finally { + if (stream != null) { + stream.close(); + } + } + } catch (IOException e) { + backup.restoreBackup(); + throw new InvocationTargetException(e); + } catch (CoreException e) { + backup.restoreBackup(); + if (e.getType() == Core.ERROR_CANCELLATION) + throw new InterruptedException(); + if (e.getType() == Core.ERROR_WRONG_PASSWORD) { + if (getEncryptable() != null) { + getEncryptable().reset(); + } + } + throw new InvocationTargetException(e); + } + } + + /** + * @param workbook + * @param encryptionIgnoredEntries + * @throws InvocationTargetException + */ + private void savePreviewImage(IWorkbook workbook, + final Set encryptionIgnoredEntries) + throws InvocationTargetException { + IMindMapPreviewGenerator previewGenerator = findPreviewGenerator(); + if (previewGenerator != null) { + ImageFormat previewFormat = ImageFormat.PNG; + IFileEntry entry = workbook.getManifest().createFileEntry( + MindMapImageExporter.toThumbnailArchivePath(previewFormat), + previewFormat.getMediaType()); + entry.decreaseReference(); + entry.increaseReference(); + + final Properties previewProperties; + try { + OutputStream previewOutput = entry.openOutputStream(); + try { + previewProperties = previewGenerator.generateMindMapPreview( + this, workbook.getPrimarySheet(), previewOutput, + null); + } finally { + previewOutput.close(); + } + } catch (IOException e) { + throw new InvocationTargetException(e); + } + workbook.getMeta().setValue(IMeta.ORIGIN_X, previewProperties + .getProperty(IMindMapPreviewGenerator.PREVIEW_ORIGIN_X)); + workbook.getMeta().setValue(IMeta.ORIGIN_Y, previewProperties + .getProperty(IMindMapPreviewGenerator.PREVIEW_ORIGIN_Y)); + workbook.getMeta().setValue(IMeta.BACKGROUND_COLOR, + previewProperties.getProperty( + IMindMapPreviewGenerator.PREVIEW_BACKGROUND)); + + encryptionIgnoredEntries.add(entry.getPath()); + } + } + + private void saveRevisions(IWorkbook workbook) throws CoreException { + if (!isContentDirty(workbook) || !shouldSaveNewRevisions(workbook)) + return; + + IRevisionRepository repo = workbook.getRevisionRepository(); + for (ISheet sheet : workbook.getSheets()) { + IRevisionManager manager = repo.getRevisionManager(sheet.getId(), + IRevision.SHEET); + IRevision latestRevision = manager.getLatestRevision(); + if (latestRevision == null || sheet.getModifiedTime() == 0 || sheet + .getModifiedTime() > latestRevision.getTimestamp()) { + try { + manager.addRevision(sheet); + } catch (Throwable e) { + throw new CoreException(Core.ERROR_INVALID_ARGUMENT, + "Invalid content for revisions."); //$NON-NLS-1$ + } + } + } + } + + private boolean isContentDirty(IWorkbook workbook) { + if (workbook == null) + return false; + if (getCommandStack() != null && getCommandStack().isDirty()) + return true; + return workbook instanceof ICoreEventSource2 + && ((ICoreEventSource2) workbook) + .hasOnceListeners(Core.WorkbookPreSaveOnce); + } + + private boolean shouldSaveNewRevisions(IWorkbook workbook) { + String value = workbook.getMeta() + .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); + return value == null || IMeta.V_YES.equalsIgnoreCase(value); + } + + @Override + protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) + throws InterruptedException, InvocationTargetException { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + + IWorkbook sourceWorkbook = source.getWorkbook(); + Assert.isTrue(sourceWorkbook != null); + URI targetURI = getURI(); + Assert.isTrue(targetURI != null); + + IStorage storage = getTempStorage(); + + IEncryptable sourceEncryptable = source.getAdapter(IEncryptable.class); + if (sourceEncryptable != null && sourceEncryptable.hasPassword() + && sourceEncryptable instanceof WorkbookRefEncryptable) { +// getEncryptable() +// .setEncryptor(((WorkbookRefEncryptable) sourceEncryptable) +// .getEncryptor()); + getEncryptable().setPassword(sourceEncryptable.getPassword()); + getEncryptable() + .setPasswordHint(sourceEncryptable.getPasswordHint()); + } + + doClearTempStorageBeforeImport(subMonitor.newChild(5), storage); + + try { + IWorkbook workbook = doCloneWorkbookForImport( + subMonitor.newChild(40), sourceWorkbook, source.getURI(), + storage); + + doSaveWorkbookToURIFromSource(subMonitor.newChild(50), workbook, + targetURI, source, sourceWorkbook); + + } finally { + subMonitor.setWorkRemaining(5); + doClearTempStorageAfterImport(subMonitor.newChild(5), storage); + } + + } + + protected void doClearTempStorageBeforeImport(IProgressMonitor monitor, + IStorage storage) + throws InterruptedException, InvocationTargetException { + storage.clear(); + } + + protected void doClearTempStorageAfterImport(IProgressMonitor monitor, + IStorage storage) { + storage.clear(); + } + + protected IWorkbook doCloneWorkbookForImport(IProgressMonitor monitor, + IWorkbook sourceWorkbook, URI sourceURI, IStorage storage) + throws InterruptedException, InvocationTargetException { + try { + IWorkbook workbook = Core.getWorkbookBuilder() + .createWorkbook(storage); + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.setEntryStreamNormalizer(getEncryptionHandler()); + serializer.serialize(null); + + new CloneHandler().withWorkbooks(sourceWorkbook, workbook) + .copyWorkbookContents(); + + String oldFilePath; + if (sourceURI != null && FilePathParser.URI_SCHEME + .equals(sourceURI.getScheme())) { + oldFilePath = new File(sourceURI).getAbsolutePath(); + } else { + oldFilePath = null; + } + updateAllRelativeFileHyperlinks(workbook, oldFilePath, + getFile().getAbsolutePath()); + + return workbook; + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + if (e.getType() == Core.ERROR_CANCELLATION) + throw new InterruptedException(); + throw new InvocationTargetException(e); + } + } + + private void updateAllRelativeFileHyperlinks(IWorkbook workbook, + String oldFilePath, String newFilePath) { + String oldBase; + if (oldFilePath == null) { + oldBase = FilePathParser.ABSTRACT_FILE_BASE; + } else { + oldBase = new File(oldFilePath).getParent(); + } + + String newBase = new File(newFilePath).getParent(); + if (oldBase.equals(newBase)) + return; + + List sheets = workbook.getSheets(); + for (ISheet sheet : sheets) { + updateRelativeFileHyperlinks(sheet.getRootTopic(), oldBase, + newBase); + } + } + + private void updateRelativeFileHyperlinks(ITopic topic, String oldBase, + String newBase) { + String hyperlink = topic.getHyperlink(); + if (FilePathParser.isFileURI(hyperlink)) { + String path = FilePathParser.toPath(hyperlink); + if (FilePathParser.isPathRelative(path)) { + String absolutePath = FilePathParser.toAbsolutePath(oldBase, + path); + hyperlink = FilePathParser.toRelativePath(newBase, + absolutePath); + topic.setHyperlink(FilePathParser.toURI(hyperlink, true)); + } + } + List topics = topic.getAllChildren(); + if (topics != null) { + for (ITopic temptopic : topics) { + updateRelativeFileHyperlinks(temptopic, oldBase, newBase); + } + } + } + + @Override + public boolean activateNotifier() { + File file = getFile(); + if (!file.exists()) { + fileRemoved(MindMapMessages.LocalFileWorkbookRef_removeDialog_title, + MindMapMessages.LocalFileWorkbookRef_removeDialog_message, + new String[] { + MindMapMessages.LocalFileWorkbookRef_removeDialog_saveAs_button, + MindMapMessages.LocalFileWorkbookRef_removeDialog_delete_button }, + false); + return true; + } else if (file.lastModified() != timestamp) { + fileChanged(MindMapMessages.LocalFileWorkbookRef_changeDialog_title, + MindMapMessages.LocalFileWorkbookRef_changeDialog_message, + new String[] { + MindMapMessages.LocalFileWorkbookRef_changeDialog_update_button, + MindMapMessages.LocalFileWorkbookRef_changeDialog_cancel_button }); + return true; + } + return false; + } + + @Override + public void open(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + timestamp = getFile().lastModified(); + super.open(monitor); + } + + @Override + public void save(IProgressMonitor monitor) + throws InterruptedException, InvocationTargetException { + super.save(monitor); + timestamp = getFile().lastModified(); + } + + @Override + public boolean exists() { + return getFile().exists(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRefFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRefFactory.java index f0c1488dc..7fac77543 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRefFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/LocalFileWorkbookRefFactory.java @@ -1,32 +1,32 @@ -package org.xmind.ui.internal.editor; - -import java.net.URI; -import java.util.Map; -import java.util.WeakHashMap; - -import org.eclipse.ui.IMemento; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefFactory; - -public class LocalFileWorkbookRefFactory implements IWorkbookRefFactory { - - private Map reversedCache = new WeakHashMap(); - - public LocalFileWorkbookRefFactory() { - } - - public IWorkbookRef createWorkbookRef(URI uri, IMemento state) { - if (uri == null) - return null; - - for (IWorkbookRef wr : reversedCache.keySet()) { - if (uri.equals(wr.getURI())) - return wr; - } - - IWorkbookRef wr = new LocalFileWorkbookRef(uri, state); - reversedCache.put(wr, uri); - return wr; - } - -} +package org.xmind.ui.internal.editor; + +import java.net.URI; +import java.util.Map; +import java.util.WeakHashMap; + +import org.eclipse.ui.IMemento; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefFactory; + +public class LocalFileWorkbookRefFactory implements IWorkbookRefFactory { + + private Map reversedCache = new WeakHashMap(); + + public LocalFileWorkbookRefFactory() { + } + + public IWorkbookRef createWorkbookRef(URI uri, IMemento state) { + if (uri == null) + return null; + + for (IWorkbookRef wr : reversedCache.keySet()) { + if (uri.equals(wr.getURI())) + return wr; + } + + IWorkbookRef wr = new LocalFileWorkbookRef(uri, state); + reversedCache.put(wr, uri); + return wr; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MME.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MME.java index aaa0fb4d8..b50bbba04 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MME.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MME.java @@ -1,410 +1,410 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.UUID; - -import org.eclipse.core.filesystem.EFS; -import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.xmind.core.Core; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.internal.MarkerImpExpUtils; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.PrefUtils; - -public class MME { - - private static final String SUBDIR_WORKBOOKS = "workbooks/"; //$NON-NLS-1$ - - /** - * - * @param uri - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createEditorInput(URI uri) { - return new MindMapEditorInput(uri); - } - - /** - * - * @param workbookRef - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createEditorInput(IWorkbookRef workbookRef) { - return new MindMapEditorInput(workbookRef); - } - - /** - * - * @param workbook - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createLoadedEditorInput(IWorkbook workbook) { - return new MindMapEditorInput( - PreLoadedWorkbookRef.createFromLoadedWorkbook(workbook, null)); - } - - /** - * - * @param name - * @param workbook - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createLoadedEditorInput(String name, - IWorkbook workbook) { - return new MindMapEditorInput( - PreLoadedWorkbookRef.createFromLoadedWorkbook(workbook, name)); - } - - /** - * - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createNonExistingEditorInput() { - return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); - } - - /** - * @param name - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - @Deprecated - public static IEditorInput createNamedEditorInput(String name) { - return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); - } - - /** - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - @Deprecated - public static IEditorInput createTemplatedEditorInput( - InputStream templateStream) { - return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); - - } - - /** - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - @Deprecated - public static IEditorInput createTemplatedEditorInput(String name, - InputStream templateStream) { - return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); - - } - - /** - * Creates an editor input using the given file. Note that if there's - * Eclipse IDE running, the result will be an - * {@link org.eclipse.ui.ide.FileStoreEditorInput}; otherwise an instance of - * {@link FileEditorInput} will be returned. - * - * @param path - * The absolute path of a file - * @return A new editor input representing the given file - * @throws CoreException - * if the creation failed - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createFileEditorInput(String path) - throws CoreException { - if (path == null) - throw new IllegalArgumentException("Path is null"); //$NON-NLS-1$ - return createFileEditorInput(new File(path)); - } - - /** - * Creates an editor input using the given file. - * - * @param file - * The file - * @return A new editor input representing the given file. - * @throws CoreException - * if the creation failed - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createFileEditorInput(File file) - throws CoreException { - if (file == null) - throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ - return new MindMapEditorInput(file.toURI()); - } - - /** - * Creates an editor input using the given file store. - *

    - * IMPORTANT: This method should ONLY be called when there's Eclipse - * IDE in the runtime environment. - *

    - * - * @param fileStore - * @return - * @throws CoreException - * if the creation failed - * @throws IllegalStateException - * if the Eclipse IDE plugin isn't in the runtime environment - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createFileEditorInput(IFileStore fileStore) - throws CoreException { - if (fileStore == null) - throw new IllegalArgumentException("File store is null"); //$NON-NLS-1$ - return new MindMapEditorInput(fileStore.toURI()); - } - - /** - * Creates an editor input using the given file. - *

    - * IMPORTANT: This method should ONLY be called when there's Eclipse - * IDE in the runtime environment. - *

    - * - * @param file - * The file - * @return A new editor input representing the given file. - * @throws CoreException - * if the creation failed - * @throws IllegalStateException - * if the Eclipse IDE isn't in the runtime environment - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createFileEditorInput(IFile file) - throws CoreException { - if (file == null) - throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ - return new MindMapEditorInput(file.getLocationURI()); - } - - /** - * - * @param uri - * @return - * @deprecated Use {@link MindMapUI#getEditorInputFactory()} - */ - public static IEditorInput createEditorInputFromURI(String uri) { - URI theURI; - try { - theURI = new URI(uri); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - return new MindMapEditorInput(theURI); - } - - public static File getFile(Object input) { - File file = MindMapUIPlugin.getAdapter(input, File.class); - if (file != null) - return file; - - IFileStore fileStore = MindMapUIPlugin.getAdapter(input, - IFileStore.class); - if (fileStore != null) { - URI uri = fileStore.toURI(); - if (FilePathParser.URI_SCHEME.equals(uri.getScheme())) - return new File(uri); - } - - URI uri = MindMapUIPlugin.getAdapter(input, URI.class); - if (uri != null && FilePathParser.URI_SCHEME.equals(uri.getScheme())) { - return new File(uri); - } - return null; - } - - public static IFileStore getFileStore(Object input) { - IFileStore fileStore = MindMapUIPlugin.getAdapter(input, - IFileStore.class); - if (fileStore == null) { - File file = MindMapUIPlugin.getAdapter(input, File.class); - if (file != null) { - try { - fileStore = EFS.getStore(file.toURI()); - } catch (CoreException ignore) { - } - } - } - - if (fileStore == null) { - URI uri = MindMapUIPlugin.getAdapter(input, URI.class); - if (uri != null) { - try { - fileStore = EFS.getStore(uri); - } catch (CoreException ignore) { - } - } - } - - return fileStore; - } - - public static URI getURIFromEditorInput(IEditorInput input) { - URI uri = MindMapUIPlugin.getAdapter(input, URI.class); - if (uri != null) - return uri; - - IWorkbookRef workbookRef = MindMapUIPlugin.getAdapter(input, - IWorkbookRef.class); - if (workbookRef != null) - return workbookRef.getURI(); - - File file = input.getAdapter(File.class); - if (file != null) - return file.toURI(); - - return null; - } - - /** - * Launches a local file at the specified path. - * - * @param window - * @param path - * @param fileName - */ - public static void launch(IWorkbenchWindow window, String path, - String fileName) { - File file = new File(path); - if (!file.exists()) { - if (Display.getCurrent() != null) { - if (!MessageDialog.openConfirm(window.getShell(), - DialogMessages.InfoFileNotExists_title, - NLS.bind(DialogMessages.InfoFileNotExists_message, - path))) { - return; - } - } - } - String extension = FileUtils.getExtension(path); - if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { - if (window != null && Display.getCurrent() != null) { - if (openTemplate(window, path, fileName)) - return; - } - } else if (MindMapUI.FILE_EXT_XMIND.equalsIgnoreCase(extension)) { - if (window != null && Display.getCurrent() != null) { - if (openMindMap(window, path, fileName)) - return; - } - } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE - .equalsIgnoreCase(extension)) { - if (importMarkers(path)) - return; - } - - org.xmind.ui.viewers.FileUtils.launch(file.getAbsolutePath()); - } - - /** - * @param window - * @param path - */ - private static boolean openTemplate(IWorkbenchWindow window, String path, - String fileName) { - return openMindMap(window, path, fileName); - } - - /** - * @param window - * @param path - */ - private static boolean openMindMap(final IWorkbenchWindow window, - final String path, final String fileName) { - String errMessage = NLS - .bind(DialogMessages.FailedToLoadWorkbook_message, path); - final boolean[] ret = new boolean[1]; - SafeRunner.run(new SafeRunnable(errMessage) { - public void run() throws Exception { - window.getActivePage() - .openEditor(MindMapUI.getEditorInputFactory() - .createEditorInputForFile(new File(path)), - MindMapUI.MINDMAP_EDITOR_ID); - ret[0] = true; - } - }); - return ret[0]; - } - - /** - * @param path - */ - private static boolean importMarkers(String path) { - try { - MarkerImpExpUtils.importMarkerPackage(path); - - Display display = Display.getCurrent(); - if (display != null) { - display.asyncExec(new Runnable() { - public void run() { - PrefUtils.openPrefDialog(null, - MarkerManagerPrefPage.ID); - } - }); - } - return true; - } catch (IOException e) { - } - return false; - } - - public static IStorage createTempStorage() { - String tempName = UUID.randomUUID().toString() - + MindMapUI.FILE_EXT_XMIND_TEMP; - String tempDirPath = Core.getWorkspace() - .getTempDir(SUBDIR_WORKBOOKS + tempName); - return new DirectoryStorage(new File(tempDirPath)); - } - - /** - * - * @param workbook - * @param editors - * @return - * @deprecated Use IWorkbookRef instances instead of IWorkbook instances - * where possible within the workbench - */ - @Deprecated - public static IEditorInput getEditorInputWithWorkbookAndEditors( - IWorkbook workbook, IEditorReference[] editors) { - for (IEditorReference ep : editors) { - try { - IEditorInput editorInput = ep.getEditorInput(); - if (editorInput != null && editorInput - .getAdapter(IWorkbook.class) == workbook) { - return editorInput; - } - } catch (PartInitException e) { - e.printStackTrace(); - } - } - return null; - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.xmind.core.Core; +import org.xmind.core.IWorkbook; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.internal.MarkerImpExpUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.PrefUtils; + +public class MME { + + private static final String SUBDIR_WORKBOOKS = "workbooks/"; //$NON-NLS-1$ + + /** + * + * @param uri + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createEditorInput(URI uri) { + return new MindMapEditorInput(uri); + } + + /** + * + * @param workbookRef + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createEditorInput(IWorkbookRef workbookRef) { + return new MindMapEditorInput(workbookRef); + } + + /** + * + * @param workbook + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createLoadedEditorInput(IWorkbook workbook) { + return new MindMapEditorInput( + PreLoadedWorkbookRef.createFromLoadedWorkbook(workbook, null)); + } + + /** + * + * @param name + * @param workbook + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createLoadedEditorInput(String name, + IWorkbook workbook) { + return new MindMapEditorInput( + PreLoadedWorkbookRef.createFromLoadedWorkbook(workbook, name)); + } + + /** + * + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createNonExistingEditorInput() { + return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); + } + + /** + * @param name + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + @Deprecated + public static IEditorInput createNamedEditorInput(String name) { + return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); + } + + /** + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + @Deprecated + public static IEditorInput createTemplatedEditorInput( + InputStream templateStream) { + return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); + + } + + /** + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + @Deprecated + public static IEditorInput createTemplatedEditorInput(String name, + InputStream templateStream) { + return MindMapUI.getEditorInputFactory().createDefaultEditorInput(); + + } + + /** + * Creates an editor input using the given file. Note that if there's + * Eclipse IDE running, the result will be an + * {@link org.eclipse.ui.ide.FileStoreEditorInput}; otherwise an instance of + * {@link FileEditorInput} will be returned. + * + * @param path + * The absolute path of a file + * @return A new editor input representing the given file + * @throws CoreException + * if the creation failed + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createFileEditorInput(String path) + throws CoreException { + if (path == null) + throw new IllegalArgumentException("Path is null"); //$NON-NLS-1$ + return createFileEditorInput(new File(path)); + } + + /** + * Creates an editor input using the given file. + * + * @param file + * The file + * @return A new editor input representing the given file. + * @throws CoreException + * if the creation failed + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createFileEditorInput(File file) + throws CoreException { + if (file == null) + throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ + return new MindMapEditorInput(file.toURI()); + } + + /** + * Creates an editor input using the given file store. + *

    + * IMPORTANT: This method should ONLY be called when there's Eclipse + * IDE in the runtime environment. + *

    + * + * @param fileStore + * @return + * @throws CoreException + * if the creation failed + * @throws IllegalStateException + * if the Eclipse IDE plugin isn't in the runtime environment + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createFileEditorInput(IFileStore fileStore) + throws CoreException { + if (fileStore == null) + throw new IllegalArgumentException("File store is null"); //$NON-NLS-1$ + return new MindMapEditorInput(fileStore.toURI()); + } + + /** + * Creates an editor input using the given file. + *

    + * IMPORTANT: This method should ONLY be called when there's Eclipse + * IDE in the runtime environment. + *

    + * + * @param file + * The file + * @return A new editor input representing the given file. + * @throws CoreException + * if the creation failed + * @throws IllegalStateException + * if the Eclipse IDE isn't in the runtime environment + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createFileEditorInput(IFile file) + throws CoreException { + if (file == null) + throw new IllegalArgumentException("File is null"); //$NON-NLS-1$ + return new MindMapEditorInput(file.getLocationURI()); + } + + /** + * + * @param uri + * @return + * @deprecated Use {@link MindMapUI#getEditorInputFactory()} + */ + public static IEditorInput createEditorInputFromURI(String uri) { + URI theURI; + try { + theURI = new URI(uri); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + return new MindMapEditorInput(theURI); + } + + public static File getFile(Object input) { + File file = MindMapUIPlugin.getAdapter(input, File.class); + if (file != null) + return file; + + IFileStore fileStore = MindMapUIPlugin.getAdapter(input, + IFileStore.class); + if (fileStore != null) { + URI uri = fileStore.toURI(); + if (FilePathParser.URI_SCHEME.equals(uri.getScheme())) + return new File(uri); + } + + URI uri = MindMapUIPlugin.getAdapter(input, URI.class); + if (uri != null && FilePathParser.URI_SCHEME.equals(uri.getScheme())) { + return new File(uri); + } + return null; + } + + public static IFileStore getFileStore(Object input) { + IFileStore fileStore = MindMapUIPlugin.getAdapter(input, + IFileStore.class); + if (fileStore == null) { + File file = MindMapUIPlugin.getAdapter(input, File.class); + if (file != null) { + try { + fileStore = EFS.getStore(file.toURI()); + } catch (CoreException ignore) { + } + } + } + + if (fileStore == null) { + URI uri = MindMapUIPlugin.getAdapter(input, URI.class); + if (uri != null) { + try { + fileStore = EFS.getStore(uri); + } catch (CoreException ignore) { + } + } + } + + return fileStore; + } + + public static URI getURIFromEditorInput(IEditorInput input) { + URI uri = MindMapUIPlugin.getAdapter(input, URI.class); + if (uri != null) + return uri; + + IWorkbookRef workbookRef = MindMapUIPlugin.getAdapter(input, + IWorkbookRef.class); + if (workbookRef != null) + return workbookRef.getURI(); + + File file = input.getAdapter(File.class); + if (file != null) + return file.toURI(); + + return null; + } + + /** + * Launches a local file at the specified path. + * + * @param window + * @param path + * @param fileName + */ + public static void launch(IWorkbenchWindow window, String path, + String fileName) { + File file = new File(path); + if (!file.exists()) { + if (Display.getCurrent() != null) { + if (!MessageDialog.openConfirm(window.getShell(), + DialogMessages.InfoFileNotExists_title, + NLS.bind(DialogMessages.InfoFileNotExists_message, + path))) { + return; + } + } + } + String extension = FileUtils.getExtension(path); + if (MindMapUI.FILE_EXT_TEMPLATE.equalsIgnoreCase(extension)) { + if (window != null && Display.getCurrent() != null) { + if (openTemplate(window, path, fileName)) + return; + } + } else if (MindMapUI.FILE_EXT_XMIND.equalsIgnoreCase(extension)) { + if (window != null && Display.getCurrent() != null) { + if (openMindMap(window, path, fileName)) + return; + } + } else if (MindMapUI.FILE_EXT_MARKER_PACKAGE + .equalsIgnoreCase(extension)) { + if (importMarkers(path)) + return; + } + + org.xmind.ui.viewers.FileUtils.launch(file.getAbsolutePath()); + } + + /** + * @param window + * @param path + */ + private static boolean openTemplate(IWorkbenchWindow window, String path, + String fileName) { + return openMindMap(window, path, fileName); + } + + /** + * @param window + * @param path + */ + private static boolean openMindMap(final IWorkbenchWindow window, + final String path, final String fileName) { + String errMessage = NLS + .bind(DialogMessages.FailedToLoadWorkbook_message, path); + final boolean[] ret = new boolean[1]; + SafeRunner.run(new SafeRunnable(errMessage) { + public void run() throws Exception { + window.getActivePage() + .openEditor(MindMapUI.getEditorInputFactory() + .createEditorInputForFile(new File(path)), + MindMapUI.MINDMAP_EDITOR_ID); + ret[0] = true; + } + }); + return ret[0]; + } + + /** + * @param path + */ + private static boolean importMarkers(String path) { + try { + MarkerImpExpUtils.importMarkerPackage(path); + + Display display = Display.getCurrent(); + if (display != null) { + display.asyncExec(new Runnable() { + public void run() { + PrefUtils.openPrefDialog(null, + MarkerManagerPrefPage.ID); + } + }); + } + return true; + } catch (IOException e) { + } + return false; + } + + public static IStorage createTempStorage() { + String tempName = UUID.randomUUID().toString() + + MindMapUI.FILE_EXT_XMIND_TEMP; + String tempDirPath = Core.getWorkspace() + .getTempDir(SUBDIR_WORKBOOKS + tempName); + return new DirectoryStorage(new File(tempDirPath)); + } + + /** + * + * @param workbook + * @param editors + * @return + * @deprecated Use IWorkbookRef instances instead of IWorkbook instances + * where possible within the workbench + */ + @Deprecated + public static IEditorInput getEditorInputWithWorkbookAndEditors( + IWorkbook workbook, IEditorReference[] editors) { + for (IEditorReference ep : editors) { + try { + IEditorInput editorInput = ep.getEditorInput(); + if (editorInput != null && editorInput + .getAdapter(IWorkbook.class) == workbook) { + return editorInput; + } + } catch (PartInitException e) { + e.printStackTrace(); + } + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapContributor.java index f123c38c5..ba94ca460 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapContributor.java @@ -1,508 +1,512 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.commands.ActionHandler; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.ISelectionService; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.actions.RetargetAction; -import org.eclipse.ui.handlers.IHandlerActivation; -import org.eclipse.ui.handlers.IHandlerService; -import org.xmind.core.INamed; -import org.xmind.core.ISheet; -import org.xmind.core.ITitled; -import org.xmind.core.IWorkbook; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.gef.ui.editor.GraphicalEditorActionBarContributor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.internal.IActionBuilder; -import org.xmind.ui.internal.ImageActionExtensionManager; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.actions.CopiedSheetStorageSupport; -import org.xmind.ui.internal.actions.DropDownInsertImageAction; -import org.xmind.ui.internal.actions.FindReplaceAction; -import org.xmind.ui.internal.actions.RenameSheetAction; -import org.xmind.ui.internal.actions.SaveSheetAsAction; -import org.xmind.ui.mindmap.ICategoryAnalyzation; -import org.xmind.ui.mindmap.ICategoryManager; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class MindMapContributor extends GraphicalEditorActionBarContributor - implements ISelectionListener { - - private IWorkbenchAction selectBrothersAction; - private IWorkbenchAction selectChildrenAction; - private IWorkbenchAction goHomeAction; - - private IWorkbenchAction drillDownAction; - private IWorkbenchAction drillUpAction; - - private IWorkbenchAction insertTopicAction; - private IWorkbenchAction insertSubtopicAction; - private IWorkbenchAction insertTopicBeforeAction; - private IWorkbenchAction insertParentTopicAction; - private IWorkbenchAction insertFloatingTopicAction; - private IWorkbenchAction insertFloatingCentralTopicAction; - - private IWorkbenchAction insertSheetAction; - - private IWorkbenchAction extendAction; - private IWorkbenchAction collapseAction; - private IWorkbenchAction extendAllAction; - private IWorkbenchAction collapseAllAction; - - private IWorkbenchAction modifyHyperlinkAction; - private IWorkbenchAction openHyperlinkAction; - private IWorkbenchAction cancelHyperlinkAction; - - private IWorkbenchAction insertAttachmentAction; - private IWorkbenchAction insertImageAction; - - private IWorkbenchAction newSheetAction; - private IWorkbenchAction deleteSheetAction; - private IWorkbenchAction deleteOtherSheetAction; - - private IWorkbenchAction duplicateSheetAction; - private IWorkbenchAction copySheetAction; - private IWorkbenchAction pasteSheetAction; - - private SaveSheetAsAction saveSheetAsAction; - - private IWorkbenchAction tileAction; - private IWorkbenchAction resetPositionAction; - - private IWorkbenchAction createRelationshipAction; - - private IWorkbenchAction editTitleAction; - private IWorkbenchAction editLabelAction; - private IWorkbenchAction editNotesAction; - - private IWorkbenchAction traverseAction; - private IWorkbenchAction finishAction; - - private IWorkbenchAction findReplaceAction; - - private RenameSheetAction renameSheetAction; - - // Global actions: - private IWorkbenchAction deleteAction; - private IWorkbenchAction copyAction; - private IWorkbenchAction cutAction; - private IWorkbenchAction pasteAction; - private IWorkbenchAction propertiesAction; - - private IWorkbenchAction duplicateAction; - - private DropDownInsertImageAction dropDownInsertImageAction; - - private IWorkbenchAction removeAllStylesAction; - - private IHandlerService handlerService; - - private Map actionHandlerActivations; - - private IGraphicalEditorPage page; - - private ISelectionService selectionService; - - public void init(IActionBars bars, IWorkbenchPage page) { - this.handlerService = (IHandlerService) page.getWorkbenchWindow() - .getService(IHandlerService.class); - if (this.handlerService != null) { - this.actionHandlerActivations = new HashMap( - 33); - } else { - this.actionHandlerActivations = null; - } - - if (selectionService != null) - selectionService.removeSelectionListener(this); - selectionService = page.getWorkbenchWindow().getSelectionService(); - selectionService.addSelectionListener(this); - - super.init(bars, page); - } - - protected void declareGlobalActionIds() { - addGlobalActionId(ActionFactory.UNDO.getId()); - addGlobalActionId(ActionFactory.REDO.getId()); - addGlobalActionId(ActionFactory.SELECT_ALL.getId()); - addGlobalActionId(ActionFactory.PRINT.getId()); - } - - protected void makeActions() { - IWorkbenchWindow window = getPage().getWorkbenchWindow(); - - selectBrothersAction = MindMapActionFactory.SELECT_BROTHERS - .create(window); - addRetargetAction((RetargetAction) selectBrothersAction); - selectChildrenAction = MindMapActionFactory.SELECT_CHILDREN - .create(window); - addRetargetAction((RetargetAction) selectChildrenAction); - goHomeAction = MindMapActionFactory.GO_HOME.create(window); - addRetargetAction((RetargetAction) goHomeAction); - - drillDownAction = MindMapActionFactory.DRILL_DOWN.create(window); - addRetargetAction((RetargetAction) drillDownAction); - drillUpAction = MindMapActionFactory.DRILL_UP.create(window); - addRetargetAction((RetargetAction) drillUpAction); - - insertSheetAction = MindMapActionFactory.INSERT_SHEET_FROM - .create(window); - addRetargetAction((RetargetAction) insertSheetAction); - - insertTopicAction = MindMapActionFactory.INSERT_TOPIC.create(window); - addRetargetAction((RetargetAction) insertTopicAction); - - insertSubtopicAction = MindMapActionFactory.INSERT_SUBTOPIC - .create(window); - addRetargetAction((RetargetAction) insertSubtopicAction); - - insertTopicBeforeAction = MindMapActionFactory.INSERT_TOPIC_BEFORE - .create(window); - addRetargetAction((RetargetAction) insertTopicBeforeAction); - insertParentTopicAction = MindMapActionFactory.INSERT_PARENT_TOPIC - .create(window); - addRetargetAction((RetargetAction) insertParentTopicAction); - insertFloatingTopicAction = MindMapActionFactory.INSERT_FLOATING_TOPIC - .create(window); - addRetargetAction((RetargetAction) insertFloatingTopicAction); - insertFloatingCentralTopicAction = MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC - .create(window); - addRetargetAction((RetargetAction) insertFloatingCentralTopicAction); - - extendAction = MindMapActionFactory.EXTEND.create(window); - addRetargetAction((RetargetAction) extendAction); - collapseAction = MindMapActionFactory.COLLAPSE.create(window); - addRetargetAction((RetargetAction) collapseAction); - extendAllAction = MindMapActionFactory.EXTEND_ALL.create(window); - addRetargetAction((RetargetAction) extendAllAction); - collapseAllAction = MindMapActionFactory.COLLAPSE_ALL.create(window); - addRetargetAction((RetargetAction) collapseAllAction); - - modifyHyperlinkAction = MindMapActionFactory.MODIFY_HYPERLINK - .create(window); - addRetargetAction((RetargetAction) modifyHyperlinkAction); - openHyperlinkAction = MindMapActionFactory.OPEN_HYPERLINK - .create(window); - addRetargetAction((RetargetAction) openHyperlinkAction); - - cancelHyperlinkAction = MindMapActionFactory.CANCEL_HYPERLINK - .create(window); - addRetargetAction((RetargetAction) cancelHyperlinkAction); - - insertAttachmentAction = MindMapActionFactory.INSERT_ATTACHMENT - .create(window); - addRetargetAction((RetargetAction) insertAttachmentAction); - insertImageAction = MindMapActionFactory.INSERT_IMAGE.create(window); - addRetargetAction((RetargetAction) insertImageAction); - newSheetAction = MindMapActionFactory.NEW_SHEET.create(window); - addRetargetAction((RetargetAction) newSheetAction); - deleteSheetAction = MindMapActionFactory.DELETE_SHEET.create(window); - addRetargetAction((RetargetAction) deleteSheetAction); - deleteOtherSheetAction = MindMapActionFactory.DELETE_OTHER_SHEET - .create(window); - addRetargetAction((RetargetAction) deleteOtherSheetAction); - - duplicateSheetAction = MindMapActionFactory.DUPLICATE_SHEET - .create(window); - addRetargetAction((RetargetAction) duplicateSheetAction); - copySheetAction = MindMapActionFactory.COPY_SHEET.create(window); - addRetargetAction((RetargetAction) copySheetAction); - pasteSheetAction = MindMapActionFactory.PASTE_SHEET.create(window); - addRetargetAction((RetargetAction) pasteSheetAction); - - saveSheetAsAction = new SaveSheetAsAction(); - - createRelationshipAction = MindMapActionFactory.CREATE_RELATIONSHIP - .create(window); - addRetargetAction((RetargetAction) createRelationshipAction); - - editTitleAction = MindMapActionFactory.EDIT_TITLE.create(window); - addRetargetAction((RetargetAction) editTitleAction); - - editLabelAction = MindMapActionFactory.EDIT_LABEL.create(window); - addRetargetAction((RetargetAction) editLabelAction); - editNotesAction = MindMapActionFactory.EDIT_NOTES.create(window); - addRetargetAction((RetargetAction) editNotesAction); - - traverseAction = MindMapActionFactory.TRAVERSE.create(window); - addRetargetAction((RetargetAction) traverseAction); - finishAction = MindMapActionFactory.FINISH.create(window); - addRetargetAction((RetargetAction) finishAction); - - removeAllStylesAction = MindMapActionFactory.REMOVE_ALL_STYLES - .create(window); - addRetargetAction((RetargetAction) removeAllStylesAction); - - tileAction = MindMapActionFactory.TILE.create(window); - addRetargetAction((RetargetAction) tileAction); - - resetPositionAction = MindMapActionFactory.RESET_POSITION - .create(window); - addRetargetAction((RetargetAction) resetPositionAction); - - findReplaceAction = new FindReplaceAction(window); - addAction(findReplaceAction); - - renameSheetAction = new RenameSheetAction(); - - deleteAction = ActionFactory.DELETE.create(window); - addRetargetAction((RetargetAction) deleteAction); - copyAction = ActionFactory.COPY.create(window); - addRetargetAction((RetargetAction) copyAction); - cutAction = ActionFactory.CUT.create(window); - addRetargetAction((RetargetAction) cutAction); - pasteAction = ActionFactory.PASTE.create(window); - addRetargetAction((RetargetAction) pasteAction); - propertiesAction = ActionFactory.PROPERTIES.create(window); - addRetargetAction((RetargetAction) propertiesAction); - - duplicateAction = MindMapActionFactory.DUPLICATE.create(window); - addRetargetAction((RetargetAction) duplicateAction); - - addRetargetAction( - (RetargetAction) MindMapActionFactory.MOVE_UP.create(window)); - addRetargetAction( - (RetargetAction) MindMapActionFactory.MOVE_DOWN.create(window)); - addRetargetAction( - (RetargetAction) MindMapActionFactory.MOVE_LEFT.create(window)); - addRetargetAction((RetargetAction) MindMapActionFactory.MOVE_RIGHT - .create(window)); - - List imageActionBuilders = ImageActionExtensionManager - .getInstance().getActionBuilders(); - List imageActionExtensions = new ArrayList( - imageActionBuilders.size()); - for (IActionBuilder builder : imageActionBuilders) { - IWorkbenchAction imageActionExtension = builder - .createAction(getPage()); - imageActionExtensions.add(imageActionExtension); - addAction(imageActionExtension); - } - - if (imageActionExtensions.size() > 0) { - imageActionExtensions.add(0, insertImageAction); - dropDownInsertImageAction = new DropDownInsertImageAction( - insertImageAction, imageActionExtensions); - dropDownInsertImageAction.setText(insertImageAction.getText()); - dropDownInsertImageAction - .setToolTipText(insertImageAction.getToolTipText()); - dropDownInsertImageAction - .setImageDescriptor(insertImageAction.getImageDescriptor()); - dropDownInsertImageAction.setDisabledImageDescriptor( - insertImageAction.getDisabledImageDescriptor()); - insertImageAction.setText(MindMapMessages.InsertImageFromFile_text); - insertImageAction.setToolTipText( - MindMapMessages.InsertImageFromFile_toolTip); - insertImageAction.setImageDescriptor(null); - insertImageAction.setDisabledImageDescriptor(null); - } - } - - public void init(IActionBars bars) { - super.init(bars); - bars.setGlobalActionHandler(ActionFactory.FIND.getId(), - findReplaceAction); - } - - protected void addAction(IAction action) { - super.addAction(action); - activateHandler(action); - } - - protected void activePageChanged(IGraphicalEditorPage page) { - this.page = page; - if (saveSheetAsAction != null) { - saveSheetAsAction.setActivePage(page); - } - if (renameSheetAction != null) { - renameSheetAction.setActivePage(page); - } - } - - protected void activateHandler(IAction action) { - if (handlerService != null && actionHandlerActivations != null) { - String commandId = action.getActionDefinitionId(); - if (commandId != null) { - IHandlerActivation handlerActivation = handlerService - .activateHandler(commandId, new ActionHandler(action)); - actionHandlerActivations.put(action, handlerActivation); - } - } - } - - protected void deactivateHandler(IAction action) { - if (handlerService != null && actionHandlerActivations != null) { - IHandlerActivation activation = actionHandlerActivations - .remove(action); - if (activation != null) { - handlerService.deactivateHandler(activation); - } - } - } - - public void contributeToPagePopupMenu(IMenuManager menu) { - menu.add(renameSheetAction); - menu.add(new Separator()); - - menu.add(copySheetAction); - if (isCopiedSheetAvailable()) { - menu.add(pasteSheetAction); - } - menu.add(duplicateSheetAction); - menu.add(deleteSheetAction); - menu.add(deleteOtherSheetAction); - menu.add(new Separator()); - - menu.add(saveSheetAsAction); - menu.add(new Separator()); - - IAction createSheetAction = getActionRegistry() - .getAction(MindMapActionFactory.NEW_SHEET.getId()); - menu.add(createSheetAction); - menu.add(new Separator(IWorkbenchActionConstants.NEW_EXT)); - - super.contributeToPagePopupMenu(menu); - - //set delete actions state - if (getSheetsCountOfCurrentWorkbook() < 2) { - deleteSheetAction.setEnabled(false); - deleteOtherSheetAction.setEnabled(false); - } else { - deleteSheetAction.setEnabled(true); - deleteOtherSheetAction.setEnabled(true); - } - } - - private int getSheetsCountOfCurrentWorkbook() { - if (page == null || page.isDisposed()) { - return -1; - } - IWorkbook workbook = ((ISheet) page.getAdapter(ISheet.class)) - .getOwnedWorkbook(); - return workbook.getSheets().size(); - } - - public void contributeToSheetCompositePopupMenu(MenuManager menuManager) { - super.contributeToSheetCompositePopupMenu(menuManager); - } - - private boolean isCopiedSheetAvailable() { - return CopiedSheetStorageSupport.getInstance().isCopiedSheetExist(); - } - - public void dispose() { - if (handlerService != null) { - if (getActionRegistry() != null) { - for (IAction action : getActionRegistry().getActions()) { - deactivateHandler(action); - } - } - handlerService = null; - actionHandlerActivations = null; - } - if (selectionService != null) { - selectionService.removeSelectionListener(this); - selectionService = null; - } - super.dispose(); - } - - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - ICategoryManager manager = MindMapUI.getCategoryManager(); - Object[] elements = (selection instanceof IStructuredSelection) - ? ((IStructuredSelection) selection).toArray() : null; - ICategoryAnalyzation categories = elements == null ? null - : manager.analyze(elements); - updateStatusLine(manager, categories); - } - - private void updateStatusLine(ICategoryManager categoryManager, - ICategoryAnalyzation categories) { - IStatusLineManager sl = getActionBars().getStatusLineManager(); - if (sl != null) { - sl.setMessage(getStatusMessage(categoryManager, categories)); - } - } - - private static String getStatusMessage(ICategoryManager categoryManager, - ICategoryAnalyzation categories) { - if (categories == null) - return null; - if (categories.isEmpty()) - return null; - int size = categories.getElements().length; - String m; - if (categories.isMultiple()) { - m = MindMapMessages.StatusLine_MultipleItems; - } else { - String type = categories.getMainCategory(); - if (ICategoryManager.UNKNOWN_CATEGORY.equals(type)) { - m = ""; //$NON-NLS-1$ - } else { - String name = categoryManager.getCategoryName(type); - if (size == 1) { - Object ele = categories.getElements()[0]; - String title = MindMapUtils.trimSingleLine(getTitle(ele)); - if (title != null) { - m = NLS.bind(MindMapMessages.StatusLine_OneItemPattern, - name, title); - } else { - m = NLS.bind( - MindMapMessages.StatusLine_OneItemNoTitlePattern, - name); - } - } else { - m = NLS.bind(MindMapMessages.StatusLine_MultipleItemPattern, - size, name); - } - } - } - return m; - } - - private static String getTitle(Object ele) { - if (ele instanceof ITitled) - return ((ITitled) ele).getTitleText(); - if (ele instanceof INamed) - return ((INamed) ele).getName(); - if (ele instanceof IMarkerRef) - return ((IMarkerRef) ele).getDescription(); - return ""; //$NON-NLS-1$ - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.commands.ActionHandler; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.actions.RetargetAction; +import org.eclipse.ui.handlers.IHandlerActivation; +import org.eclipse.ui.handlers.IHandlerService; +import org.xmind.core.INamed; +import org.xmind.core.ISheet; +import org.xmind.core.ITitled; +import org.xmind.core.IWorkbook; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.gef.ui.editor.GraphicalEditorActionBarContributor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.internal.IActionBuilder; +import org.xmind.ui.internal.ImageActionExtensionManager; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.actions.CopiedSheetStorageSupport; +import org.xmind.ui.internal.actions.DropDownInsertImageAction; +import org.xmind.ui.internal.actions.FindReplaceAction; +import org.xmind.ui.internal.actions.RenameSheetAction; +import org.xmind.ui.internal.actions.SaveSheetAsAction; +import org.xmind.ui.mindmap.ICategoryAnalyzation; +import org.xmind.ui.mindmap.ICategoryManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class MindMapContributor extends GraphicalEditorActionBarContributor + implements ISelectionListener { + + private IWorkbenchAction selectBrothersAction; + private IWorkbenchAction selectChildrenAction; + private IWorkbenchAction goHomeAction; + + private IWorkbenchAction drillDownAction; + private IWorkbenchAction drillUpAction; + + private IWorkbenchAction insertTopicAction; + private IWorkbenchAction insertSubtopicAction; + private IWorkbenchAction insertTopicBeforeAction; + private IWorkbenchAction insertParentTopicAction; + private IWorkbenchAction insertFloatingTopicAction; + private IWorkbenchAction insertFloatingCentralTopicAction; + + private IWorkbenchAction insertSheetAction; + + private IWorkbenchAction extendAction; + private IWorkbenchAction collapseAction; + private IWorkbenchAction extendAllAction; + private IWorkbenchAction collapseAllAction; + + private IWorkbenchAction modifyHyperlinkAction; + private IWorkbenchAction openHyperlinkAction; + private IWorkbenchAction cancelHyperlinkAction; + + private IWorkbenchAction insertAttachmentAction; + private IWorkbenchAction insertImageAction; + + private IWorkbenchAction newSheetAction; + private IWorkbenchAction deleteSheetAction; + private IWorkbenchAction deleteOtherSheetAction; + + private IWorkbenchAction duplicateSheetAction; + private IWorkbenchAction copySheetAction; + private IWorkbenchAction pasteSheetAction; + + private SaveSheetAsAction saveSheetAsAction; + + private IWorkbenchAction tileAction; + private IWorkbenchAction resetPositionAction; + + private IWorkbenchAction createRelationshipAction; + + private IWorkbenchAction editTitleAction; + private IWorkbenchAction editLabelAction; + private IWorkbenchAction editNotesAction; + + private IWorkbenchAction traverseAction; + private IWorkbenchAction finishAction; + + private IWorkbenchAction findReplaceAction; + + private RenameSheetAction renameSheetAction; + + // Global actions: + private IWorkbenchAction deleteAction; + private IWorkbenchAction copyAction; + private IWorkbenchAction cutAction; + private IWorkbenchAction pasteAction; + private IWorkbenchAction propertiesAction; + + private IWorkbenchAction duplicateAction; + + private IWorkbenchAction dropDownInsertImageAction; + + private IWorkbenchAction removeAllStylesAction; + + private IHandlerService handlerService; + + private Map actionHandlerActivations; + + private IGraphicalEditorPage page; + + private ISelectionService selectionService; + + public void init(IActionBars bars, IWorkbenchPage page) { + this.handlerService = (IHandlerService) page.getWorkbenchWindow() + .getService(IHandlerService.class); + if (this.handlerService != null) { + this.actionHandlerActivations = new HashMap( + 33); + } else { + this.actionHandlerActivations = null; + } + + if (selectionService != null) + selectionService.removeSelectionListener(this); + selectionService = page.getWorkbenchWindow().getSelectionService(); + selectionService.addSelectionListener(this); + + super.init(bars, page); + } + + protected void declareGlobalActionIds() { + addGlobalActionId(ActionFactory.UNDO.getId()); + addGlobalActionId(ActionFactory.REDO.getId()); + addGlobalActionId(ActionFactory.SELECT_ALL.getId()); + addGlobalActionId(ActionFactory.PRINT.getId()); + } + + protected void makeActions() { + IWorkbenchWindow window = getPage().getWorkbenchWindow(); + + selectBrothersAction = MindMapActionFactory.SELECT_BROTHERS + .create(window); + addRetargetAction((RetargetAction) selectBrothersAction); + selectChildrenAction = MindMapActionFactory.SELECT_CHILDREN + .create(window); + addRetargetAction((RetargetAction) selectChildrenAction); + goHomeAction = MindMapActionFactory.GO_HOME.create(window); + addRetargetAction((RetargetAction) goHomeAction); + + drillDownAction = MindMapActionFactory.DRILL_DOWN.create(window); + addRetargetAction((RetargetAction) drillDownAction); + drillUpAction = MindMapActionFactory.DRILL_UP.create(window); + addRetargetAction((RetargetAction) drillUpAction); + + insertSheetAction = MindMapActionFactory.INSERT_SHEET_FROM + .create(window); + addRetargetAction((RetargetAction) insertSheetAction); + + insertTopicAction = MindMapActionFactory.INSERT_TOPIC.create(window); + addRetargetAction((RetargetAction) insertTopicAction); + + insertSubtopicAction = MindMapActionFactory.INSERT_SUBTOPIC + .create(window); + addRetargetAction((RetargetAction) insertSubtopicAction); + + insertTopicBeforeAction = MindMapActionFactory.INSERT_TOPIC_BEFORE + .create(window); + addRetargetAction((RetargetAction) insertTopicBeforeAction); + insertParentTopicAction = MindMapActionFactory.INSERT_PARENT_TOPIC + .create(window); + addRetargetAction((RetargetAction) insertParentTopicAction); + insertFloatingTopicAction = MindMapActionFactory.INSERT_FLOATING_TOPIC + .create(window); + addRetargetAction((RetargetAction) insertFloatingTopicAction); + insertFloatingCentralTopicAction = MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC + .create(window); + addRetargetAction((RetargetAction) insertFloatingCentralTopicAction); + + extendAction = MindMapActionFactory.EXTEND.create(window); + addRetargetAction((RetargetAction) extendAction); + collapseAction = MindMapActionFactory.COLLAPSE.create(window); + addRetargetAction((RetargetAction) collapseAction); + extendAllAction = MindMapActionFactory.EXTEND_ALL.create(window); + addRetargetAction((RetargetAction) extendAllAction); + collapseAllAction = MindMapActionFactory.COLLAPSE_ALL.create(window); + addRetargetAction((RetargetAction) collapseAllAction); + + modifyHyperlinkAction = MindMapActionFactory.MODIFY_HYPERLINK + .create(window); + addRetargetAction((RetargetAction) modifyHyperlinkAction); + openHyperlinkAction = MindMapActionFactory.OPEN_HYPERLINK + .create(window); + addRetargetAction((RetargetAction) openHyperlinkAction); + + cancelHyperlinkAction = MindMapActionFactory.CANCEL_HYPERLINK + .create(window); + addRetargetAction((RetargetAction) cancelHyperlinkAction); + + insertAttachmentAction = MindMapActionFactory.INSERT_ATTACHMENT + .create(window); + addRetargetAction((RetargetAction) insertAttachmentAction); + insertImageAction = MindMapActionFactory.INSERT_IMAGE.create(window); + addRetargetAction((RetargetAction) insertImageAction); + newSheetAction = MindMapActionFactory.NEW_SHEET.create(window); + addRetargetAction((RetargetAction) newSheetAction); + deleteSheetAction = MindMapActionFactory.DELETE_SHEET.create(window); + addRetargetAction((RetargetAction) deleteSheetAction); + deleteOtherSheetAction = MindMapActionFactory.DELETE_OTHER_SHEET + .create(window); + addRetargetAction((RetargetAction) deleteOtherSheetAction); + + duplicateSheetAction = MindMapActionFactory.DUPLICATE_SHEET + .create(window); + addRetargetAction((RetargetAction) duplicateSheetAction); + copySheetAction = MindMapActionFactory.COPY_SHEET.create(window); + addRetargetAction((RetargetAction) copySheetAction); + pasteSheetAction = MindMapActionFactory.PASTE_SHEET.create(window); + addRetargetAction((RetargetAction) pasteSheetAction); + + saveSheetAsAction = new SaveSheetAsAction(); + addAction(saveSheetAsAction); + + createRelationshipAction = MindMapActionFactory.CREATE_RELATIONSHIP + .create(window); + addRetargetAction((RetargetAction) createRelationshipAction); + + editTitleAction = MindMapActionFactory.EDIT_TITLE.create(window); + addRetargetAction((RetargetAction) editTitleAction); + + editLabelAction = MindMapActionFactory.EDIT_LABEL.create(window); + addRetargetAction((RetargetAction) editLabelAction); + editNotesAction = MindMapActionFactory.EDIT_NOTES.create(window); + addRetargetAction((RetargetAction) editNotesAction); + + traverseAction = MindMapActionFactory.TRAVERSE.create(window); + addRetargetAction((RetargetAction) traverseAction); + finishAction = MindMapActionFactory.FINISH.create(window); + addRetargetAction((RetargetAction) finishAction); + + removeAllStylesAction = MindMapActionFactory.REMOVE_ALL_STYLES + .create(window); + addRetargetAction((RetargetAction) removeAllStylesAction); + + tileAction = MindMapActionFactory.TILE.create(window); + addRetargetAction((RetargetAction) tileAction); + + resetPositionAction = MindMapActionFactory.RESET_POSITION + .create(window); + addRetargetAction((RetargetAction) resetPositionAction); + + findReplaceAction = new FindReplaceAction(window); + addAction(findReplaceAction); + + renameSheetAction = new RenameSheetAction(); + addAction(renameSheetAction); + + deleteAction = ActionFactory.DELETE.create(window); + addRetargetAction((RetargetAction) deleteAction); + copyAction = ActionFactory.COPY.create(window); + addRetargetAction((RetargetAction) copyAction); + cutAction = ActionFactory.CUT.create(window); + addRetargetAction((RetargetAction) cutAction); + pasteAction = ActionFactory.PASTE.create(window); + addRetargetAction((RetargetAction) pasteAction); + propertiesAction = ActionFactory.PROPERTIES.create(window); + addRetargetAction((RetargetAction) propertiesAction); + + duplicateAction = MindMapActionFactory.DUPLICATE.create(window); + addRetargetAction((RetargetAction) duplicateAction); + + addRetargetAction( + (RetargetAction) MindMapActionFactory.MOVE_UP.create(window)); + addRetargetAction( + (RetargetAction) MindMapActionFactory.MOVE_DOWN.create(window)); + addRetargetAction( + (RetargetAction) MindMapActionFactory.MOVE_LEFT.create(window)); + addRetargetAction((RetargetAction) MindMapActionFactory.MOVE_RIGHT + .create(window)); + + List imageActionBuilders = ImageActionExtensionManager + .getInstance().getActionBuilders(); + List imageActionExtensions = new ArrayList( + imageActionBuilders.size()); + for (IActionBuilder builder : imageActionBuilders) { + IWorkbenchAction imageActionExtension = builder + .createAction(getPage()); + imageActionExtensions.add(imageActionExtension); + addAction(imageActionExtension); + } + + if (imageActionExtensions.size() > 0) { + imageActionExtensions.add(0, insertImageAction); + dropDownInsertImageAction = new DropDownInsertImageAction( + insertImageAction, imageActionExtensions); + addAction(dropDownInsertImageAction); + dropDownInsertImageAction.setText(insertImageAction.getText()); + dropDownInsertImageAction + .setToolTipText(insertImageAction.getToolTipText()); + dropDownInsertImageAction + .setImageDescriptor(insertImageAction.getImageDescriptor()); + dropDownInsertImageAction.setDisabledImageDescriptor( + insertImageAction.getDisabledImageDescriptor()); + insertImageAction.setText(MindMapMessages.InsertImageFromFile_text); + insertImageAction.setToolTipText( + MindMapMessages.InsertImageFromFile_toolTip); + insertImageAction.setImageDescriptor(null); + insertImageAction.setDisabledImageDescriptor(null); + } + } + + public void init(IActionBars bars) { + super.init(bars); + bars.setGlobalActionHandler(ActionFactory.FIND.getId(), + findReplaceAction); + } + + protected void addAction(IAction action) { + super.addAction(action); + activateHandler(action); + } + + protected void activePageChanged(IGraphicalEditorPage page) { + this.page = page; + if (saveSheetAsAction != null) { + saveSheetAsAction.setActivePage(page); + } + if (renameSheetAction != null) { + renameSheetAction.setActivePage(page); + } + } + + protected void activateHandler(IAction action) { + if (handlerService != null && actionHandlerActivations != null) { + String commandId = action.getActionDefinitionId(); + if (commandId != null) { + IHandlerActivation handlerActivation = handlerService + .activateHandler(commandId, new ActionHandler(action)); + actionHandlerActivations.put(action, handlerActivation); + } + } + } + + protected void deactivateHandler(IAction action) { + if (handlerService != null && actionHandlerActivations != null) { + IHandlerActivation activation = actionHandlerActivations + .remove(action); + if (activation != null) { + handlerService.deactivateHandler(activation); + } + } + } + + public void contributeToPagePopupMenu(IMenuManager menu) { + menu.add(renameSheetAction); + menu.add(new Separator()); + + menu.add(copySheetAction); + if (isCopiedSheetAvailable()) { + menu.add(pasteSheetAction); + } + menu.add(duplicateSheetAction); + menu.add(deleteSheetAction); + menu.add(deleteOtherSheetAction); + menu.add(new Separator()); + + menu.add(saveSheetAsAction); + menu.add(new Separator()); + + IAction createSheetAction = getActionRegistry() + .getAction(MindMapActionFactory.NEW_SHEET.getId()); + menu.add(createSheetAction); + menu.add(new Separator(IWorkbenchActionConstants.NEW_EXT)); + + super.contributeToPagePopupMenu(menu); + + //set delete actions state + if (getSheetsCountOfCurrentWorkbook() < 2) { + deleteSheetAction.setEnabled(false); + deleteOtherSheetAction.setEnabled(false); + } else { + deleteSheetAction.setEnabled(true); + deleteOtherSheetAction.setEnabled(true); + } + } + + private int getSheetsCountOfCurrentWorkbook() { + if (page == null || page.isDisposed()) { + return -1; + } + IWorkbook workbook = ((ISheet) page.getAdapter(ISheet.class)) + .getOwnedWorkbook(); + return workbook.getSheets().size(); + } + + public void contributeToSheetCompositePopupMenu(MenuManager menuManager) { + super.contributeToSheetCompositePopupMenu(menuManager); + } + + private boolean isCopiedSheetAvailable() { + return CopiedSheetStorageSupport.getInstance().isCopiedSheetExist(); + } + + public void dispose() { + if (handlerService != null) { + if (getActionRegistry() != null) { + for (IAction action : getActionRegistry().getActions()) { + deactivateHandler(action); + } + } + handlerService = null; + actionHandlerActivations = null; + } + if (selectionService != null) { + selectionService.removeSelectionListener(this); + selectionService = null; + } + page = null; + super.dispose(); + } + + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + ICategoryManager manager = MindMapUI.getCategoryManager(); + Object[] elements = (selection instanceof IStructuredSelection) + ? ((IStructuredSelection) selection).toArray() : null; + ICategoryAnalyzation categories = elements == null ? null + : manager.analyze(elements); + updateStatusLine(manager, categories); + } + + private void updateStatusLine(ICategoryManager categoryManager, + ICategoryAnalyzation categories) { + IStatusLineManager sl = getActionBars().getStatusLineManager(); + if (sl != null) { + sl.setMessage(getStatusMessage(categoryManager, categories)); + } + } + + private static String getStatusMessage(ICategoryManager categoryManager, + ICategoryAnalyzation categories) { + if (categories == null) + return null; + if (categories.isEmpty()) + return null; + int size = categories.getElements().length; + String m; + if (categories.isMultiple()) { + m = MindMapMessages.StatusLine_MultipleItems; + } else { + String type = categories.getMainCategory(); + if (ICategoryManager.UNKNOWN_CATEGORY.equals(type)) { + m = ""; //$NON-NLS-1$ + } else { + String name = categoryManager.getCategoryName(type); + if (size == 1) { + Object ele = categories.getElements()[0]; + String title = MindMapUtils.trimSingleLine(getTitle(ele)); + if (title != null) { + m = NLS.bind(MindMapMessages.StatusLine_OneItemPattern, + name, title); + } else { + m = NLS.bind( + MindMapMessages.StatusLine_OneItemNoTitlePattern, + name); + } + } else { + m = NLS.bind(MindMapMessages.StatusLine_MultipleItemPattern, + size, name); + } + } + } + return m; + } + + private static String getTitle(Object ele) { + if (ele instanceof ITitled) + return ((ITitled) ele).getTitleText(); + if (ele instanceof INamed) + return ((INamed) ele).getName(); + if (ele instanceof IMarkerRef) + return ((IMarkerRef) ele).getDescription(); + return ""; //$NON-NLS-1$ + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditor.java index 368aec062..88c735c74 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditor.java @@ -1,2104 +1,2192 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Properties; - -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.ErrorSupportProvider; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FormAttachment; -import org.eclipse.swt.layout.FormData; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.ISaveablePart2; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.IWindowListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartConstants; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.contexts.IContextActivation; -import org.eclipse.ui.contexts.IContextService; -import org.eclipse.ui.internal.util.BundleUtility; -import org.eclipse.ui.part.PageBook; -import org.eclipse.ui.progress.IProgressService; -import org.eclipse.ui.progress.IWorkbenchSiteProgressService; -import org.eclipse.ui.services.IEvaluationService; -import org.eclipse.ui.statushandlers.IStatusAdapterConstants; -import org.eclipse.ui.statushandlers.StatusAdapter; -import org.eclipse.ui.statushandlers.StatusManager; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.ISheetComponent; -import org.xmind.core.ISheetSettings; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicComponent; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.util.FileUtils; -import org.xmind.gef.EditDomain; -import org.xmind.gef.IEditDomainListener; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.image.ResizeConstants; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.ui.actions.IActionRegistry; -import org.xmind.gef.ui.actions.RedoAction; -import org.xmind.gef.ui.actions.UndoAction; -import org.xmind.gef.ui.editor.GraphicalEditor; -import org.xmind.gef.ui.editor.IEditable; -import org.xmind.gef.ui.editor.IEditingContext; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.gef.ui.editor.IInteractiveMessage; -import org.xmind.ui.IWordContextProvider; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.blackbox.BlackBox; -import org.xmind.ui.commands.ModifyFoldedCommand; -import org.xmind.ui.commands.MoveSheetCommand; -import org.xmind.ui.editor.EditorHistoryItem; -import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.editor.PageTitleTabFolderRenderer; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.MindMapWordContextProvider; -import org.xmind.ui.internal.actions.CopySheetAction; -import org.xmind.ui.internal.actions.CreateSheetAction; -import org.xmind.ui.internal.actions.DeleteOtherSheetsAction; -import org.xmind.ui.internal.actions.DeleteSheetAction; -import org.xmind.ui.internal.actions.DuplicateSheetAction; -import org.xmind.ui.internal.actions.PasteSheetAction; -import org.xmind.ui.internal.actions.ShowPropertiesAction; -import org.xmind.ui.internal.e4handlers.SaveWorkbookAsHandler; -import org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider; -import org.xmind.ui.internal.mindmap.MindMapEditDomain; -import org.xmind.ui.internal.mindmap.MindMapState; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefListener; -import org.xmind.ui.mindmap.MindMap; -import org.xmind.ui.mindmap.MindMapImageExporter; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.tabfolder.IPageMoveListener; -import org.xmind.ui.tabfolder.PageMoveHelper; -import org.xmind.ui.util.Logger; -import org.xmind.ui.wizards.ISaveContext; - -public class MindMapEditor extends GraphicalEditor implements ISaveablePart2, - ICoreEventListener, IPageMoveListener, IPropertyChangeListener, - IMindMapPreviewGenerator, ISaveContext, IWorkbookRefListener { - - private static class EditorStatus { - - private static EditorStatus instance = null; - - private int activeIndex; - - private List zooms; - - private List scrollPositions; - - private List indexPaths; - - private List> topicTypeChains; - - private EditorStatus() { - } - - public void saveStatus(IWorkbookRef workbookRef, int activeIndex, - IGraphicalEditorPage[] pages) { - init(); - if (workbookRef != null) { - IWorkbook workbook = workbookRef.getWorkbook(); - if (workbook != null && pages != null && (pages.length != 0)) { - this.activeIndex = activeIndex; - for (IGraphicalEditorPage page : pages) { - IGraphicalViewer viewer = page.getViewer(); - if (zooms == null) - zooms = new ArrayList(); - double zoom = viewer.getZoomManager().getScale(); - zooms.add(zoom); - - if (scrollPositions == null) - scrollPositions = new ArrayList(); - Point scrollPosition = viewer.getScrollPosition(); - scrollPositions.add(scrollPosition); - - if (indexPaths == null) - indexPaths = new ArrayList(); - if (topicTypeChains == null) - topicTypeChains = new ArrayList>(); - Object focused = viewer.getFocused(); - if (focused == null || !(focused instanceof ITopic)) { - indexPaths.add(""); //$NON-NLS-1$ - topicTypeChains - .add(Collections. emptyList()); - } else { - List typeChain = new ArrayList(); - String indexPath = getTopicIndexPath( - (ITopic) focused, "", typeChain); //$NON-NLS-1$ - indexPaths.add(indexPath); - Collections.reverse(typeChain); - topicTypeChains.add(typeChain); - } - } - } - } - } - - private void init() { - activeIndex = 0; - - if (zooms != null) - zooms.clear(); - - if (scrollPositions != null) - scrollPositions.clear(); - - if (indexPaths != null) - indexPaths.clear(); - - if (topicTypeChains != null) - topicTypeChains.clear(); - } - - private String getTopicIndexPath(ITopic topic, String path, - List typeChain) { - path = topic.getIndex() + "/" + path; //$NON-NLS-1$ - typeChain.add(topic.getType()); - if (topic.getParent() != null - && topic.getParent() instanceof ITopic) - return getTopicIndexPath(topic.getParent(), path, typeChain); - return path; - } - - public int getActiveIndex() { - return activeIndex; - } - - public List getZooms() { - return zooms; - } - - public List getScrollPositions() { - return scrollPositions; - } - - public List getIndexPaths() { - return indexPaths; - } - - public List> getTopicTypeChains() { - return topicTypeChains; - } - - public static EditorStatus getInstance() { - if (instance == null) { - synchronized (EditorStatus.class) { - if (instance == null) - instance = new EditorStatus(); - } - } - return instance; - } - } - - private class MindMapEditorSelectionProvider - extends MultiPageSelectionProvider { - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.tabfolder.DelegatedSelectionProvider#setSelection(org - * .eclipse.jface.viewers.ISelection) - */ - @Override - public void setSelection(ISelection selection) { - if (selection instanceof IStructuredSelection) { - for (Object element : ((IStructuredSelection) selection) - .toList()) { - if (element instanceof ITopicComponent) { - setSelectionAndUnfold(element); - } else if (element instanceof IRelationship) { - IRelationship r = (IRelationship) element; - IRelationshipEnd e1 = r.getEnd1(); - IRelationshipEnd e2 = r.getEnd2(); - if (e1 instanceof ITopicComponent) { - setSelectionAndUnfold(e1); - } - if (e2 instanceof ITopicComponent) { - setSelectionAndUnfold(e2); - - } - } - } - } - - super.setSelection(selection); - } - } - - private IWorkbookRef workbookRef = null; - - private ICoreEventRegister workbookEventRegister = null; - - private ICoreEventRegister globalEventRegister = null; - - private MindMapPageTitleEditor pageTitleEditor = null; - - private PageMoveHelper pageMoveHelper = null; - - private MindMapFindReplaceOperationProvider findReplaceOperationProvider = null; - - private Composite messageContainer = null; - - private PageBook pageBook = null; - - private Composite pageContainer = null; - - private IEditingContext editingContext = new IEditingContext() { - - @Override - public T getAdapter(Class adapter) { - MindMapEditor editor = MindMapEditor.this; - T result; - - result = editor.getSite().getService(adapter); - if (result != null) - return result; - - result = editor.getAdapter(adapter); - if (result != null) - return result; - - result = Platform.getAdapterManager().getAdapter(editor, adapter); - if (result != null) - return result; - - return null; - } - }; - - private IWordContextProvider wordContextProvider = null; - - private boolean skipNextPreviewImage = false; - - private IContextActivation contextActivation = null; - - private IEditorHistory editorHistory = null; - - private boolean passwordTried = false; - - private IWindowListener windowListener; - - private ISelectionListener selectionListener; - - private boolean ignoreFileChanged = false; - - private IEditorLayoutManager layoutManager = null; - - private IContextActivation toolContextActivation = null; - - private IContextService contextService = null; - - public void init(IEditorSite site, IEditorInput input) - throws PartInitException { - this.editorHistory = site.getService(IEditorHistory.class); - this.workbookRef = createWorkbookRefFromInput(input); - if (this.workbookRef == null) - throw new PartInitException( - "Failed to obtain workbook reference from editor input '" //$NON-NLS-1$ - + input.toString() + "'"); //$NON-NLS-1$ - - super.init(site, input); - setMiniBarContributor(new MindMapMiniBarContributor()); - } - - private IWorkbookRef createWorkbookRefFromInput(IEditorInput input) { - IWorkbookRef workbookRef = input.getAdapter(IWorkbookRef.class); - if (workbookRef != null) - return workbookRef; - - URI uri = input.getAdapter(URI.class); - if (uri != null) { - return MindMapUIPlugin.getDefault().getWorkbookRefFactory() - .createWorkbookRef(uri, null); - } - - return null; - } - - protected ISelectionProvider createSelectionProvider() { - return new MindMapEditorSelectionProvider(); - } - - protected ICommandStack createCommandStack() { - if (workbookRef != null) - return workbookRef.getCommandStack(); - return super.createCommandStack(); - } - - protected void disposeCommandStack(ICommandStack commandStack) { - // No need to dispose command stack here, because the workbook reference - // manager will dispose unused command stacks automatically. - } - - private void disposeData() { - if (workbookRef != null && workbookRef.getURI() != null) { - URI uri = workbookRef.getURI(); - if (URIUtil.isFileURI(uri)) { - BlackBox.removeSavedMap(URIUtil.toFile(uri).getAbsolutePath()); - } - } - - final IWorkbookRef theWorkbookRef = this.workbookRef; - if (theWorkbookRef != null) { - theWorkbookRef.removePropertyChangeListener(this); - theWorkbookRef.removeWorkbookRefListener(this); - MindMapState.getInstance().saveState(theWorkbookRef, getPages()); - if (theWorkbookRef.isDirty()) { - theWorkbookRef.discardChanges(); - } - safeRun(null, false, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - theWorkbookRef.close(monitor); - } - }); - IEditingContext activeContext = theWorkbookRef.getActiveContext(); - if (activeContext == this.editingContext) { - theWorkbookRef.setActiveContext(null); - } - } - - deactivateToolContext(); - - uninstallModelListener(); - } - - public void dispose() { - if (contextActivation != null) { - IContextService cs = getSite().getService(IContextService.class); - cs.deactivateContext(contextActivation); - } - disposeData(); - super.dispose(); - deactivateFileNotifier(); - workbookEventRegister = null; - globalEventRegister = null; - pageTitleEditor = null; - pageMoveHelper = null; - findReplaceOperationProvider = null; - workbookRef = null; - pageBook = null; - pageContainer = null; - - // release reference to the workbook reference object - this.workbookRef = null; - layoutManager = null; - } - - @Override - public void createPartControl(Composite parent) { - super.createPartControl(parent); - - Composite container = getContainer(); - if (container instanceof CTabFolder) { - ((CTabFolder) container).setRenderer(new PageTitleTabFolderRenderer( - (CTabFolder) container, this)); - } - - activateFileNotifier(); - } - - protected Composite createContainerParent(Composite parent) { - FormLayout formLayout = new FormLayout(); - parent.setLayout(formLayout); - - messageContainer = new Composite(parent, SWT.BORDER); - FormData messageFormData = new FormData(); - //no correct size data to set form data - messageContainer.setLayoutData(messageFormData); - messageContainer.setVisible(false); - - GridLayout messageLayout = new GridLayout(1, false); - messageLayout.marginWidth = 0; - messageLayout.marginHeight = 0; - messageLayout.horizontalSpacing = 0; - messageLayout.verticalSpacing = 0; - messageContainer.setLayout(messageLayout); - - updateMessages(false); - - pageBook = new PageBook(parent, SWT.NONE); - FormData pageBookData = new FormData(); - pageBookData.left = new FormAttachment(0, 0); - pageBookData.top = new FormAttachment(0, 0); - pageBookData.bottom = new FormAttachment(100, 0); - pageBookData.right = new FormAttachment(100, 0); - pageBook.setLayoutData(pageBookData); - - pageContainer = new Composite(pageBook, SWT.NONE); - layoutManager = new EditorLayoutManager(pageContainer); - layoutManager.setActiveLayout(new DefaultEditorLayout()); - IContextService cs = getSite().getService(IContextService.class); - contextActivation = cs.activateContext(MindMapUI.CONTEXT_MINDMAP); - return pageContainer; - } - - @Override - protected void createEditorContents() { - super.createEditorContents(); - - if (workbookRef != null) { - workbookRef.setActiveContext(editingContext); - workbookRef.addPropertyChangeListener(this); - workbookRef.addWorkbookRefListener(this); - } - - // Make editor actions: - createActions(getActionRegistry()); - - // Update editor pane title: - updateNames(); - - // Add helpers to handle moving pages, editing page title, showing - // page popup preview, creating new page, etc.: - if (getContainer() instanceof CTabFolder) { - final CTabFolder tabFolder = (CTabFolder) getContainer(); - pageMoveHelper = new PageMoveHelper(tabFolder); - pageMoveHelper.addListener(this); - pageTitleEditor = new MindMapPageTitleEditor(tabFolder, this); -// pageTitleEditor.addPageTitleChangedListener(this); -// pageTitleEditor.setContextId(getSite(), -// MindMapUI.CONTEXT_PAGETITLE_EDIT); - new MindMapEditorPagePopupPreviewHelper(this, tabFolder); - - } - - // Let 3rd-party plugins configure this editor: - MindMapEditorConfigurerManager.getInstance().configureEditor(this); - - // Try loading workbook: - if (getWorkbook() != null) { - workbookLoaded(); - } else if (workbookRef != null) { - final IWorkbookRef theWorkbookRef = workbookRef; - Display.getCurrent().asyncExec(new Runnable() { - @Override - public void run() { - loadWorkbook(theWorkbookRef, 0); - } - }); - } - } - - private void loadWorkbook(final IWorkbookRef workbookRef, int times) { - IEncryptable encryptable = workbookRef.getAdapter(IEncryptable.class); - if (encryptable != null && !encryptable.hasPassword()) { - /// make sure setPassword is called to prevent the default password dialog - encryptable.setPassword(null); - } - - IWorkbenchSiteProgressService context = getSite() - .getService(IWorkbenchSiteProgressService.class); - Assert.isTrue(context != null); - try { - context.run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - workbookRef.open(monitor); - } - }); - } catch (final InvocationTargetException e) { - CoreException coreEx = getCoreException(e); - if (coreEx != null) { - int errType = coreEx.getType(); - if (errType == Core.ERROR_WRONG_PASSWORD) { - // password error - String message = passwordTried - ? MindMapMessages.MindMapEditor_passwordPrompt_message1 - : MindMapMessages.MindMapEditor_passwordPrompt_message2; - openDecryptionDialog(workbookRef, message, times); - passwordTried = true; - return; - } - } - - // failed - Throwable cause = e.getTargetException(); - if (cause == null) - cause = e; - - if (cause instanceof FileNotFoundException) { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - MessageDialog.openWarning( - Display.getDefault().getActiveShell(), - MindMapMessages.MindMapEditor_Warning_FileNotFoundDialog_title, - MindMapMessages.WorkbookHistoryItem_FileMissingMessage); - } - }); - asyncClose(); - } else { - showError(cause, - workbookRef.getAdapter(ErrorSupportProvider.class)); - } - return; - } catch (InterruptedException e) { - // canceled - asyncClose(); - return; - } - - workbookLoaded(); - } - - private void openDecryptionDialog(final IWorkbookRef workbookRef, - String message, int times) { - final int nextTime = times + 1; - final IEncryptable encryptable = workbookRef - .getAdapter(IEncryptable.class); - - new DecryptionDialog(Display.getCurrent().getActiveShell(), - workbookRef.getName(), encryptable.getPasswordHint(), times) { - protected void okPressed() { - super.okPressed(); - - encryptable.setPassword(getPassword()); - loadWorkbook(workbookRef, nextTime); - }; - - protected void handleShellCloseEvent() { - super.handleShellCloseEvent(); - asyncClose(); - }; - - protected void cancelPressed() { - super.cancelPressed(); - asyncClose(); - }; - }.open(); - } - - private CoreException getCoreException(Throwable e) { - if (e == null) - return null; - if (e instanceof CoreException) - return (CoreException) e; - return getCoreException(e.getCause()); - } - - private void asyncClose() { - Display.getCurrent().asyncExec(new Runnable() { - - @Override - public void run() { - closeEditor(); - } - }); - } - - private void closeEditor() { - getSite().getPage().closeEditor(this, false); - } - - private void showError(Throwable exception, - ErrorSupportProvider supportProvider) { - StatusAdapter statusAdapter = new StatusAdapter(new Status( - IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - MindMapMessages.LoadWorkbookJob_errorDialog_title, exception)); - statusAdapter.setProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY, - Long.valueOf(System.currentTimeMillis())); - ErrorDialog errorDialog = new ErrorDialog( - Display.getCurrent().getActiveShell(), statusAdapter, - supportProvider); - errorDialog.setCloseCallback(new Runnable() { - @Override - public void run() { - asyncClose(); - } - }); - errorDialog.open(); - } - - protected void createActions(IActionRegistry actionRegistry) { - UndoAction undoAction = new UndoAction(this); - actionRegistry.addAction(undoAction); - addCommandStackAction(undoAction); - - RedoAction redoAction = new RedoAction(this); - actionRegistry.addAction(redoAction); - addCommandStackAction(redoAction); - - CreateSheetAction createSheetAction = new CreateSheetAction(this); - actionRegistry.addAction(createSheetAction); - - DeleteSheetAction deleteSheetAction = new DeleteSheetAction(this); - actionRegistry.addAction(deleteSheetAction); - - DeleteOtherSheetsAction deleteOtherSheetAction = new DeleteOtherSheetsAction( - this); - actionRegistry.addAction(deleteOtherSheetAction); - - DuplicateSheetAction duplicateSheetAction = new DuplicateSheetAction( - this); - actionRegistry.addAction(duplicateSheetAction); - - CopySheetAction copySheetAction = new CopySheetAction(this); - actionRegistry.addAction(copySheetAction); - - PasteSheetAction pasteSheetAction = new PasteSheetAction(this); - actionRegistry.addAction(pasteSheetAction); - - ShowPropertiesAction showPropertiesAction = new ShowPropertiesAction( - getSite().getWorkbenchWindow()); - actionRegistry.addAction(showPropertiesAction); - } - - private void configurePage(IGraphicalEditorPage page) { - MindMapEditorConfigurerManager.getInstance().configurePage(page); - } - - protected void createPages() { - if (getWorkbook() == null) - return; - - for (ISheet sheet : getWorkbook().getSheets()) { - IGraphicalEditorPage page = createSheetPage(sheet, -1); - configurePage(page); - } - if (getPageCount() > 0) { - setActivePage(0); - } - } - - protected IGraphicalEditorPage createSheetPage(ISheet sheet, int index) { - IGraphicalEditorPage page = new MindMapEditorPage(); - page.init(this, sheet); - addPage(page); - if (index >= 0 && index < getPageCount()) { - movePageTo(findPage(page), index); - } - index = findPage(page); - if (getActivePage() != index) { - setActivePage(index); - } - page.updatePageTitle(); - MindMapState.getInstance().loadState(getWorkbookRef(), page); - return page; - } - - protected EditDomain createEditDomain(IGraphicalEditorPage page) { - MindMapEditDomain domain = new MindMapEditDomain(); - domain.addEditDomainListener(new IEditDomainListener() { - - @Override - public void activeToolChanged(ITool oldTool, ITool newTool) { - changeContext(newTool); - } - }); - domain.setCommandStack(getCommandStack()); - return domain; - } - - protected void changeContext(ITool newTool) { - deactivateToolContext(); - activateContext(newTool == null ? null : newTool.getContextId()); - } - - protected void changeContext(String contextId) { - deactivateToolContext(); - activateContext(contextId); - } - - private void activateContext(String contextId) { - if (contextId == null) - return; - contextService = getSite().getService(IContextService.class); - if (contextService != null) { - toolContextActivation = contextService.activateContext(contextId); - } - } - - private void deactivateToolContext() { - if (contextService != null && toolContextActivation != null) { - contextService.deactivateContext(toolContextActivation); - } - contextService = null; - toolContextActivation = null; - } - - private void updateMessages(boolean layout) { - for (Control messageItem : messageContainer.getChildren()) { - messageItem.dispose(); - } - List messages = workbookRef.getMessages(); - if (messages != null && !messages.isEmpty()) { - for (IInteractiveMessage message : new ArrayList( - messages)) { - - Image icon; - Color lineColor; - Color textColor; - int type = message.getMessageType(); - if (type == IInteractiveMessage.WARNING) { - ///TODO use a dedicated icon - icon = null; - lineColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ - textColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ - } else if (type == IInteractiveMessage.ERROR) { - ///TODO use a dedicated icon - icon = null; - lineColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ - textColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ - } else { - ///TODO use a dedicated icon - icon = Display.getCurrent() - .getSystemImage(SWT.ICON_INFORMATION); - lineColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ - textColor = (Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ - } - - String text = message.getMessage(); - if (text == null) { - text = ""; //$NON-NLS-1$ - } - - List actions = message.getActions(); - - final Composite line = new Composite(messageContainer, - SWT.NONE); - line.setBackground(lineColor); - GridData lineData = new GridData(SWT.CENTER, SWT.FILL, true, - false); - lineData.widthHint = 500; - line.setLayoutData(lineData); - line.setLayout(new GridLayout(2, false)); - - Composite leftComposite = new Composite(line, SWT.NONE); - leftComposite.setBackground(line.getBackground()); - GridData lineBodyData = new GridData(SWT.CENTER, SWT.FILL, true, - false); - leftComposite.setLayoutData(lineBodyData); - int numColumns = 0; - GridLayout leftCompositeLayout = new GridLayout(numColumns, - false); - leftCompositeLayout.marginLeft = 16; - leftCompositeLayout.marginHeight = 5; - leftCompositeLayout.horizontalSpacing = 3; - leftCompositeLayout.verticalSpacing = 0; - leftComposite.setLayout(leftCompositeLayout); - - if (icon != null) { - numColumns++; - Label iconLabel = new Label(leftComposite, SWT.NONE); - iconLabel.setBackground(line.getBackground()); - iconLabel.setImage(icon); - iconLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, false, true)); - } - - numColumns++; - Label textLabel = new Label(leftComposite, - SWT.WRAP | SWT.CENTER); - textLabel.setText(text); - textLabel.setBackground(line.getBackground()); - textLabel.setForeground(textColor); - textLabel.setLayoutData( - new GridData(SWT.CENTER, SWT.CENTER, true, true)); - Font textFont = textLabel.getFont(); - if (textFont != null) { - FontData[] fontData = textFont.getFontData(); - FontData[] newFontData = FontUtils.newHeight(fontData, - Util.isMac() ? 12 : 10); - textLabel.setFont((Font) JFaceResources.getResources() - .get(FontDescriptor.createFrom(newFontData))); - } - - if (!actions.isEmpty()) { - numColumns++; - Composite actionBar = new Composite(leftComposite, - SWT.NONE); - actionBar.setBackground(line.getBackground()); - actionBar.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, false, true)); - GridLayout actionLayout = new GridLayout(actions.size(), - false); - actionLayout.marginWidth = 0; - actionLayout.marginHeight = 0; - actionLayout.horizontalSpacing = 3; - actionLayout.verticalSpacing = 0; - actionBar.setLayout(actionLayout); - - for (final IAction action : actions) { - final Button actionButton = new Button(actionBar, - SWT.PUSH); - actionButton.setBackground(actionBar.getBackground()); - actionButton.setLayoutData(new GridData(SWT.FILL, - SWT.CENTER, false, true)); - String actionText = action.getText(); - if (actionText == null) { - actionButton.setText(actionText); - } else { - ImageDescriptor actionImageDescriptor = action - .getImageDescriptor(); - if (actionImageDescriptor != null) { - final Image actionImage = actionImageDescriptor - .createImage(Display.getCurrent()); - actionButton.addDisposeListener( - new DisposeListener() { - - @Override - public void widgetDisposed( - DisposeEvent e) { - actionImage.dispose(); - } - }); - actionButton.setImage(actionImage); - } - } - actionButton.setToolTipText(action.getToolTipText()); - actionButton.addListener(SWT.Selection, new Listener() { - - @Override - public void handleEvent(Event event) { - action.runWithEvent(event); - } - }); - } - } - - leftCompositeLayout.numColumns = numColumns; - - final Label closeImageLabel = new Label(line, SWT.NONE); - closeImageLabel.setBackground(line.getBackground()); - closeImageLabel.setImage((Image) JFaceResources.getResources() - .get(MindMapUI.getImages().get("close.png", true))); //$NON-NLS-1$ - closeImageLabel.setLayoutData( - new GridData(SWT.END, SWT.BEGINNING, false, false)); - closeImageLabel.addMouseListener(new MouseAdapter() { - - @Override - public void mouseDown(MouseEvent e) { - if (messageContainer != null - && !messageContainer.isDisposed()) { - if (line != null && !line.isDisposed()) { - line.dispose(); - } - Control[] children = messageContainer.getChildren(); - if (children == null || children.length == 0) { - messageContainer.setVisible(false); - } - messageContainer.getParent().layout(true); - } - } - }); - closeImageLabel.addMouseTrackListener(new MouseTrackListener() { - - @Override - public void mouseHover(MouseEvent e) { - closeImageLabel.setCursor(Display.getDefault() - .getSystemCursor(SWT.CURSOR_HAND)); - } - - @Override - public void mouseExit(MouseEvent e) { - closeImageLabel.setCursor(null); - } - - @Override - public void mouseEnter(MouseEvent e) { - closeImageLabel.setCursor(Display.getDefault() - .getSystemCursor(SWT.CURSOR_HAND)); - } - }); - } - org.eclipse.swt.graphics.Point size = messageContainer - .computeSize(SWT.DEFAULT, SWT.DEFAULT); - FormData messageFormData = new FormData(); - messageFormData.left = new FormAttachment(50, -size.x / 2); - messageFormData.right = new FormAttachment(50, size.x / 2); - messageFormData.top = new FormAttachment(0, 0); - //can't set bottom -// messageFormData.bottom = new FormAttachment(100, -size.y); - messageContainer.setLayoutData(messageFormData); - messageContainer.setVisible(true); - } - - if (layout) { - messageContainer.getParent().layout(true, true); - } - } - - protected void updateNames() { - setPartName(getEditorInput().getName()); - setTitleToolTip(getEditorInput().getToolTipText()); - } - - public IWorkbookRef getWorkbookRef() { - return workbookRef; - } - - public IWorkbook getWorkbook() { - if (workbookRef == null) - return null; - return workbookRef.getWorkbook(); - } - - @SuppressWarnings("unchecked") - @Override - public T getAdapter(Class adapter) { - if (adapter == IEditorLayoutManager.class) - return (T) layoutManager; - return super.getAdapter(adapter); - } - - @Override - protected T getEditorAdapter(Class adapter) { - if (workbookRef != null) { - T result = workbookRef.getAdapter(adapter); - if (result != null) - return result; - } - - if (adapter == IWorkbookRef.class) { - return adapter.cast(getWorkbookRef()); - } else if (adapter == IWorkbook.class) { - return adapter.cast(getWorkbook()); - } else if (adapter == MindMapPageTitleEditor.class) { - return adapter.cast(pageTitleEditor); - } else if (adapter == PageMoveHelper.class) { - return adapter.cast(pageMoveHelper); - } else if (adapter == IFindReplaceOperationProvider.class) { - if (findReplaceOperationProvider == null) { - findReplaceOperationProvider = new MindMapFindReplaceOperationProvider( - this); - } - return adapter.cast(findReplaceOperationProvider); - } else if (adapter == IWordContextProvider.class) { - if (wordContextProvider == null) { - wordContextProvider = new MindMapWordContextProvider(this); - } - return adapter.cast(wordContextProvider); - } else if (adapter == IDialogPaneContainer.class) { -// return adapter.cast(backCover); - } - return super.getEditorAdapter(adapter); - } - - protected void installModelListener() { - IWorkbook workbook = getWorkbook(); - workbookEventRegister = new CoreEventRegister(workbook, this); - workbookEventRegister.register(Core.SheetAdd); - workbookEventRegister.register(Core.SheetRemove); - workbookEventRegister.register(Core.SheetMove); - workbookEventRegister.register(Core.PasswordChange); - workbookEventRegister.register(Core.WorkbookPreSaveOnce); - - globalEventRegister = new CoreEventRegister( - workbook.getAdapter(ICoreEventSupport.class), this); - globalEventRegister.register(Core.SheetSettings); - } - - protected void uninstallModelListener() { - if (workbookEventRegister != null) { - workbookEventRegister.unregisterAll(); - workbookEventRegister = null; - } - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - globalEventRegister = null; - } - } - - public void handleCoreEvent(final CoreEvent event) { - if (pageBook == null || pageBook.isDisposed() || workbookRef == null) - return; - - pageBook.getDisplay().syncExec(new Runnable() { - - public void run() { - String type = event.getType(); - if (Core.WorkbookPreSaveOnce.equals(type)) { - firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); - firePropertyChange(PROP_INPUT); - } else if (Core.SheetAdd.equals(type)) { - ISheet sheet = (ISheet) event.getTarget(); - int index = event.getIndex(); - IGraphicalEditorPage page = createSheetPage(sheet, index); - configurePage(page); - } else if (Core.SheetRemove.equals(type)) { - ISheet sheet = (ISheet) event.getTarget(); - IGraphicalEditorPage page = findPage(sheet); - if (page != null) { - removePage(page); - } - } else if (Core.SheetMove.equals(type)) { - int oldIndex = event.getIndex(); - int newIndex = ((ISheet) event.getTarget()).getIndex(); - movePageTo(oldIndex, newIndex); - } else if (Core.PasswordChange.equals(type)) { - IWorkbook workbook = getWorkbook(); - if (workbook instanceof ICoreEventSource2) { - ((ICoreEventSource2) workbook) - .registerOnceCoreEventListener( - Core.WorkbookPreSaveOnce, - ICoreEventListener.NULL); - } - } - - //update sheet tab colors - if (Core.SheetSettings.equals(type) - && ISheetSettings.ATTR_RGB.equals(event.getTarget())) { - updateSheetTabColors(); - } - } - }); - } - - private void updateSheetTabColors() { - getContainer().redraw(); - } - - protected void saveAndRun(Command command) { - ICommandStack cs = getCommandStack(); - if (cs != null) - cs.execute(command); - } - - public void pageMoved(int fromIndex, int toIndex) { - IWorkbook workbook = getWorkbook(); - MoveSheetCommand command = new MoveSheetCommand(workbook, fromIndex, - toIndex); - command.setLabel(""); //$NON-NLS-1$ - saveAndRun(command); - } - -// public void pageTitleChanged(int pageIndex, String newValue) { -// /// forbid changing sheet title to empty string -// /// preventing saving errors (e.g. cloud syncing) -// if (newValue == null || "".equals(newValue)) //$NON-NLS-1$ -// return; -// -// IGraphicalEditorPage page = getPage(pageIndex); -// if (page != null) { -// Object pageInput = page.getInput(); -// if (pageInput instanceof ISheet) { -// ModifyTitleTextCommand command = new ModifyTitleTextCommand( -// (ISheet) pageInput, newValue); -// command.setLabel(""); //$NON-NLS-1$ -// saveAndRun(command); -// } -// } -// } - - protected void createSheet() { - IAction action = getActionRegistry() - .getAction(MindMapActionFactory.NEW_SHEET.getId()); - if (action != null && action.isEnabled()) { - action.run(); - } - } - - @Override - public void setFocus() { -// if (workbookRef != null) { -// workbookRef.setPrimaryReferrer(this); -// } - if (workbookRef != null) { - workbookRef.setActiveContext(editingContext); - } -// if (backCover != null && backCover.isOpen()) { -// backCover.setFocus(); -// } else { - super.setFocus(); -// } - } - - public void openEncryptionDialog() { - if (pageBook == null || pageBook.isDisposed()) - return; - - final IWorkbookRef theWorkbookRef = workbookRef; - - new EncryptionDialog(Display.getCurrent().getActiveShell()) { - - @Override - protected boolean hasPassword() { - IEncryptable encryptable = theWorkbookRef - .getAdapter(IEncryptable.class); - return encryptable != null && encryptable.hasPassword(); - } - - @Override - protected boolean testsPassword(String password) { - IEncryptable encryptable = theWorkbookRef - .getAdapter(IEncryptable.class); - return encryptable != null - && encryptable.testsPassword(password); - } - - @Override - protected void okPressed() { - boolean verified = verify(); - - super.okPressed(); - - if (verified) { - IEncryptable encryptable = theWorkbookRef - .getAdapter(IEncryptable.class); - if (encryptable != null) { - encryptable.setPassword(getPassword()); - encryptable.setPasswordHint(getHintMessage()); - } - } - } - }.open(); - } - - public ISelectionProvider getSelectionProvider() { - return getSite().getSelectionProvider(); - } - - public void reveal() { - getSite().getPage().activate(this); - setFocus(); - } - - /** - * @param monitor - * @deprecated - */ - @Deprecated - public void postSave(final IProgressMonitor monitor) { - getSite().getShell().getDisplay().syncExec(new Runnable() { - - public void run() { - postSave(); - } - }); - } - - public void setSelection(ISelection selection, boolean reveal, - boolean forceFocus) { - ISelectionProvider selectionProvider = getSite().getSelectionProvider(); - if (selectionProvider != null) { - selectionProvider.setSelection(selection); - } - if (forceFocus) { - getSite().getPage().activate(this); - Shell shell = getSite().getShell(); - if (shell != null && !shell.isDisposed()) { - shell.setActive(); - } - } else if (reveal) { - getSite().getPage().bringToTop(this); - } - } - - public IGraphicalEditorPage findPage(Object input) { - if (input instanceof IMindMap) { - input = ((IMindMap) input).getSheet(); - } - return super.findPage(input); - } - - private void workbookLoaded() { - passwordTried = false; - if (pageBook == null || pageBook.isDisposed()) - return; - - // TODO - pageBook.showPage(pageContainer); - if (isEditorActive()) - setFocus(); - - Assert.isTrue(getWorkbook() != null); - createPages(); - if (isEditorActive()) { - setFocus(); - } - installModelListener(); - firePropertyChange(PROP_INPUT); - firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); - - recordEditorHistory(); - } - - private boolean isEditorActive() { - return getSite().getPage().getActiveEditor() == this; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.gef.ui.editor.GraphicalEditor#findOwnedInput(org.eclipse.jface - * .viewers.ISelection) - */ - @Override - protected Object findOwnedInput(ISelection selection) { - if (selection instanceof IStructuredSelection) { - Object[] elements = ((IStructuredSelection) selection).toArray(); - for (Object element : elements) { - if (element instanceof ISheetComponent) - return ((ISheetComponent) element).getOwnedSheet(); - if (element instanceof ISheet) - return (ISheet) element; - } - } - return super.findOwnedInput(selection); - } - - public void skipNextPreviewImage() { - this.skipNextPreviewImage = true; - } - - private void setSelectionAndUnfold(Object element) { - List showElementsCommands = new ArrayList(1); - ITopic parent = ((ITopicComponent) element).getParent(); - while (parent != null) { - if (parent.isFolded()) { - showElementsCommands - .add(new ModifyFoldedCommand(parent, false)); - } - parent = parent.getParent(); - } - if (!showElementsCommands.isEmpty()) { - Command command = new CompoundCommand( - showElementsCommands.get(0).getLabel(), - showElementsCommands); - saveAndRun(command); - } - } - - @Override - public boolean isDirty() { - return workbookRef != null && workbookRef.isDirty(); - } - - @Override - public void doSave(IProgressMonitor monitor) { - if (workbookRef == null) - return; - - if (!workbookRef.canSave()) { - doSaveAs(); - return; - } - - safeRun(monitor, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - workbookRef.save(monitor); - if (MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE)) { - URI uri = workbookRef.getURI(); - if (URIUtil.isFileURI(uri)) { - BlackBox.doBackup( - URIUtil.toFile(uri).getAbsolutePath()); - } - } - postSave(); - recordEditorHistory(); - } - }); - } - - private void recordEditorHistory() { - - if (workbookRef.getURI() == null || workbookRef.getName() == null) - return; - URI uri = workbookRef.getURI(); - - //only local file or seawind file can record it history. - if (!uri.getScheme().equalsIgnoreCase("file") //$NON-NLS-1$ - && !uri.getScheme().equalsIgnoreCase("seawind")) //$NON-NLS-1$ - return; - - InputStream input = null; - try { - try { - if (uri.getScheme().equalsIgnoreCase("file")) { //$NON-NLS-1$ - input = getThumbnailStreamForLocal(); - } else - input = getThumbnailStreamFor(workbookRef); - if (input == null) - return; - editorHistory.add(workbookRef.getURI(), new EditorHistoryItem( - workbookRef.getName(), System.currentTimeMillis())); - editorHistory.saveThumbnailData(workbookRef.getURI(), input); - } finally { - if (input != null) - input.close(); - } - } catch (IOException e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Failed to record preview image for editor history", //$NON-NLS-1$ - e)); - } - } - - private InputStream getThumbnailStreamForLocal() throws IOException { - IManifest manifest = getWorkbook().getManifest(); - if (manifest != null) { - IFileEntry thumbnailEntry = manifest - .getFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ - if (thumbnailEntry != null) - return thumbnailEntry.openInputStream(); - } - return null; - } - - private InputStream getThumbnailStreamFor(IWorkbookRef workbookRef) { - if (workbookRef == null) - return null; - - List sheets = workbookRef.getWorkbook().getSheets(); - if (sheets.isEmpty()) - return null; - - ISheet sheet = sheets.get(0); - try { - return workbookRef.getPreviewImageData(sheet.getId(), null); - } catch (IOException e) { - MindMapUIPlugin.log(e, String.format( - "Failed to load preview image for sheet 'workbooks/%s/sheets/%s'", //$NON-NLS-1$ - sheet.getParent().toString(), sheet.getId())); - } catch (SWTException e) { - MindMapUIPlugin.log(e, String.format( - "Failed to load preview image for sheet 'workbooks/%s/sheets/%s'", //$NON-NLS-1$ - sheet.getParent().toString(), sheet.getId())); - } - - return null; - } - - public void doSaveAs() { - doSaveAs(false); - } - - public void doSaveAs(boolean onlyToLocal) { - final IWorkbookRef oldWorkbookRef = this.workbookRef; - if (oldWorkbookRef == null || oldWorkbookRef - .isInState(IWorkbookRef.CLOSED | IWorkbookRef.CLOSING)) - throw new IllegalStateException( - "This mind map editor is already closed."); //$NON-NLS-1$ - - IProgressService runner = getSite().getService(IProgressService.class); - final IWorkbookRef newWorkbookRef; - try { - newWorkbookRef = SaveWorkbookAsHandler.saveWorkbookAs(this, - oldWorkbookRef, runner, null, onlyToLocal); - if (newWorkbookRef == null) - // canceled - return; - if (newWorkbookRef.equals(oldWorkbookRef)) { - // saved to old location - postSave(); - recordEditorHistory(); - return; - } - - try { - runner.run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, - InterruptedException { - newWorkbookRef.open(monitor); - newWorkbookRef.save(monitor); - } - }); - } catch (InterruptedException e) { - // canceled - return; - } - } catch (Exception e) { - StatusManager.getManager().handle(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, e.getMessage(), e), - StatusManager.SHOW); - return; - } - - // TODO save editor state before changing editor input - EditorStatus editorStatus = EditorStatus.getInstance(); - editorStatus.saveStatus(oldWorkbookRef, getActivePage(), getPages()); - - disposeData(); - while (getPageCount() > 0) { - removePage(0); - } - - this.workbookRef = newWorkbookRef; - if (newWorkbookRef != null) { - newWorkbookRef.addPropertyChangeListener(this); - newWorkbookRef.addWorkbookRefListener(this); - } - setInput(MindMapUI.getEditorInputFactory() - .createEditorInput(newWorkbookRef)); - setCommandStack(newWorkbookRef.getCommandStack()); - updateNames(); - - createPages(); - installModelListener(); - - firePropertyChange(PROP_INPUT); - postSave(); - - // TODO restore editor state after changing editor input - setActivePage(editorStatus.getActiveIndex()); - IGraphicalEditorPage[] pages = getPages(); - for (int index = 0; index < pages.length; index++) { - IGraphicalViewer viewer = pages[index].getViewer(); - viewer.getProperties().set( - IMindMapViewer.VIEWER_SELECT_CENTRALTOPIC, Boolean.FALSE); - Double scale = editorStatus.getZooms().get(index); - if (scale != null) - viewer.getZoomManager().setScale(scale); - - String indexPath = index < editorStatus.getIndexPaths().size() - ? editorStatus.getIndexPaths().get(index) : ""; //$NON-NLS-1$ - List topicTypeChain = index < editorStatus - .getTopicTypeChains().size() - ? editorStatus.getTopicTypeChains().get(index) - : Collections. emptyList(); - if (indexPath != null) { - if ("".equals(indexPath)) //$NON-NLS-1$ - viewer.setSelection(StructuredSelection.EMPTY, true); - else { - Object input = viewer.getInput(); - if (input instanceof IMindMap) { - ITopic topic = ((IMindMap) input).getCentralTopic(); - String[] indexes = indexPath.split("/"); //$NON-NLS-1$ - for (int i = 1; i < indexes.length; i++) { - String type = i < topicTypeChain.size() - ? topicTypeChain.get(i) : ITopic.ATTACHED; - if (topic.getChildren(type).size() <= Integer - .parseInt(indexes[i])) { - continue; - } - topic = topic.getChildren(type) - .get(Integer.parseInt(indexes[i])); - } - viewer.setSelection(new StructuredSelection(topic), - true); - } - - } - } - - Point scrollPosition = editorStatus.getScrollPositions().get(index); - if (scrollPosition != null) - viewer.scrollTo(scrollPosition); - } - - recordEditorHistory(); - - //Force update IEclipseContext - IEclipseContext partContext = getSite() - .getService(IEclipseContext.class); - partContext.deactivate(); - partContext.activateBranch(); - } - - private void reload() { - IWorkbookRef oldWorkbookRef = this.workbookRef; - if (oldWorkbookRef == null || oldWorkbookRef - .isInState(IWorkbookRef.CLOSED | IWorkbookRef.CLOSING)) { - throw new IllegalStateException( - "This mind map editor is already closed."); //$NON-NLS-1$ - } - - // save editor state before changing editor input - EditorStatus editorStatus = EditorStatus.getInstance(); - editorStatus.saveStatus(oldWorkbookRef, getActivePage(), getPages()); - - IEditingContext context = oldWorkbookRef.getActiveContext(); - disposeData(); - while (getPageCount() > 0) { - removePage(0); - } - - final IWorkbookRef newWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory() - .createWorkbookRef(oldWorkbookRef.getURI(), null); - if (newWorkbookRef == null) { - return; - } - - try { - IProgressService runner = getSite() - .getService(IProgressService.class); - runner.run(true, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - newWorkbookRef.open(monitor); - } - }); - } catch (InvocationTargetException e) { - e.printStackTrace(); - return; - } catch (InterruptedException e) { - e.printStackTrace(); - return; - } - - this.workbookRef = newWorkbookRef; - if (newWorkbookRef != null) { - newWorkbookRef.setActiveContext(context); - newWorkbookRef.addPropertyChangeListener(this); - newWorkbookRef.addWorkbookRefListener(this); - } - setInput(MindMapUI.getEditorInputFactory() - .createEditorInput(newWorkbookRef)); - setCommandStack(newWorkbookRef.getCommandStack()); - updateNames(); - - createPages(); - installModelListener(); - - firePropertyChange(PROP_INPUT); - firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); - - // restore editor state after changing editor input - setActivePage(editorStatus.getActiveIndex()); - IGraphicalEditorPage[] pages = getPages(); - for (int index = 0; index < pages.length; index++) { - IGraphicalViewer viewer = pages[index].getViewer(); - viewer.getProperties().set( - IMindMapViewer.VIEWER_SELECT_CENTRALTOPIC, Boolean.FALSE); - Double scale = editorStatus.getZooms().size() > index - ? editorStatus.getZooms().get(index) : null; - if (scale != null) - viewer.getZoomManager().setScale(scale); - - String indexPath = editorStatus.getIndexPaths().size() > index - ? editorStatus.getIndexPaths().get(index) : ""; //$NON-NLS-1$ - List topicTypeChain = editorStatus.getTopicTypeChains() - .size() > index - ? editorStatus.getTopicTypeChains().get(index) - : Collections. emptyList(); - if (indexPath != null) { - if ("".equals(indexPath)) //$NON-NLS-1$ - viewer.setSelection(StructuredSelection.EMPTY, true); - else { - Object input = viewer.getInput(); - if (input instanceof IMindMap) { - ITopic topic = ((IMindMap) input).getCentralTopic(); - String[] indexes = indexPath.split("/"); //$NON-NLS-1$ - for (int i = 1; i < indexes.length; i++) { - String type = i < topicTypeChain.size() - ? topicTypeChain.get(i) : ITopic.ATTACHED; - if (topic.getChildren(type).size() <= Integer - .parseInt(indexes[i])) { - continue; - } - topic = topic.getChildren(type) - .get(Integer.parseInt(indexes[i])); - } - viewer.setSelection(new StructuredSelection(topic), - true); - } - - } - } - - Point scrollPosition = editorStatus.getScrollPositions() - .size() > index - ? editorStatus.getScrollPositions().get(index) - : null; - if (scrollPosition != null) - viewer.scrollTo(scrollPosition); - } - } - - private boolean safeRun(final IProgressMonitor monitor, - final boolean promptError, final IRunnableWithProgress runnable) { - final boolean[] successful = new boolean[1]; - successful[0] = false; - SafeRunner.run(new SafeRunnable() { - - @Override - public void run() throws Exception { - if (monitor != null) { - runnable.run(monitor); - } else { - IWorkbenchSiteProgressService context = getSite() - .getService(IWorkbenchSiteProgressService.class); - Assert.isTrue(context != null); - context.run(true, true, runnable); - } - successful[0] = true; - } - - @Override - public void handleException(Throwable e) { - if (e instanceof InterruptedException) - // canceled, no error - return; - - if (e instanceof InvocationTargetException) { - Throwable cause = ((InvocationTargetException) e) - .getTargetException(); - if (cause != null) - e = cause; - } - - if (!promptError) { - // log only - Logger.log(e); - return; - } - - super.handleException(e); - } - }); - - return successful[0]; - } - - @Override - public boolean isSaveAsAllowed() { - return getWorkbook() != null; - } - - public int promptToSaveOnClose() { - //TODO -// if (workbookRef != null && workbookRef.canSave()) { -// NullProgressMonitor monitor = new NullProgressMonitor(); -// doSave(monitor); -// if (monitor.isCanceled()) -// return CANCEL; -// return NO; -// } - return DEFAULT; - } - - @Override - public void propertyChange(PropertyChangeEvent event) { - if (event.getSource() == workbookRef) { - workbookRefPropertyChange(event); - } - } - - protected void workbookRefPropertyChange(PropertyChangeEvent event) { - if (IEditable.PROP_NAME.equals(event.getProperty()) - || IEditable.PROP_DESCRIPTION.equals(event.getProperty())) { - runInUI(new Runnable() { - - @Override - public void run() { - updateNames(); - } - }); - } else if (IEditable.PROP_DIRTY.equals(event.getProperty())) { - runInUI(new Runnable() { - - @Override - public void run() { - firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); - } - }); - } else if (IEditable.PROP_MESSAGES.equals(event.getProperty())) { - runInUI(new Runnable() { - - @Override - public void run() { - updateMessages(true); - } - }); - } - - } - - private void runInUI(final Runnable runnable) { - final Control control = pageContainer; - if (control == null || control.isDisposed()) - return; - final Display display = control.getDisplay(); - if (display == null || display.isDisposed()) - return; - display.asyncExec(runnable); - } - - @Override - public void handleCommandStackEvent(CommandStackEvent event) { - // override to do nothing - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.editor.IMindMapPreviewGenerator# - * generateMindMapPreview(org.xmind.ui.mindmap.IWorkbookRef, - * java.io.OutputStream, org.xmind.ui.internal.editor.MindMapPreviewOptions) - */ - @Override - public Properties generateMindMapPreview(IWorkbookRef workbookRef, - final ISheet sheet, final OutputStream output, - MindMapPreviewOptions options) throws IOException { - Assert.isLegal(output != null); - - final Properties properties = new Properties(); - if (sheet == null - || MindMapUIPlugin.getDefault().getPreferenceStore() - .getBoolean(PrefConstants.PREVIEW_SKIPPED) - || skipNextPreviewImage) { - URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, - IMindMapImages.DEFAULT_THUMBNAIL); - if (url != null) { - InputStream input = url.openStream(); - try { - FileUtils.transfer(input, output, false); - } finally { - input.close(); - } - } - skipNextPreviewImage = false; - return properties; - } - - IEncryptable encryptable = workbookRef.getAdapter(IEncryptable.class); - if (encryptable != null && encryptable.hasPassword()) { - URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, - IMindMapImages.ENCRYPTED_THUMBNAIL); - if (url != null) { - InputStream input = url.openStream(); - try { - FileUtils.transfer(input, output, false); - } finally { - input.close(); - } - } - return properties; - } - - Shell parentShell = getSite().getShell(); - final Display display = parentShell.getDisplay(); - final MindMapImageExporter exporter = new MindMapImageExporter(display); - final Exception[] error = new Exception[1]; - display.syncExec(new Runnable() { - - public void run() { - IGraphicalEditorPage page = findPage(sheet); - if (page != null) { - IGraphicalViewer sourceViewer = page.getViewer(); - IMindMap map = (IMindMap) sourceViewer - .getAdapter(IMindMap.class); - if (map == null || map.getCentralTopic() - .equals(map.getSheet().getRootTopic())) { - exporter.setSourceViewer(sourceViewer, null, null, - new Insets(MindMapUI.DEFAULT_EXPORT_MARGIN)); - } else { - exporter.setSource(new MindMap(sheet), null, - new Insets(MindMapUI.DEFAULT_EXPORT_MARGIN)); - } - } else { - exporter.setSource(new MindMap(sheet), null, - new Insets(MindMapUI.DEFAULT_EXPORT_MARGIN)); - } - exporter.setResize(ResizeConstants.RESIZE_MAXPIXELS, 1280, - 1024); - exporter.setTargetStream(output); - - try { - exporter.export(); - } catch (SWTException e) { - error[0] = e; - return; - } - - org.eclipse.draw2d.geometry.Point origin = exporter - .calcRelativeOrigin(); - - properties.put(PREVIEW_ORIGIN_X, String.valueOf(origin.x)); - properties.put(PREVIEW_ORIGIN_Y, String.valueOf(origin.y)); - properties.put(PREVIEW_BACKGROUND, - exporter.getBackgroundColor()); - } - }); - - if (error[0] != null) { - throw new IOException(error[0]); - } - - return properties; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.wizards.ISaveContext#getContextVariable(java.lang.Class) - */ - @Override - public T getContextVariable(Class key) { - return getSite().getService(key); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.wizards.ISaveContext#getContextVariable(java.lang.String) - */ - @Override - public Object getContextVariable(String key) { - IEvaluationService service = getSite() - .getService(IEvaluationService.class); - Assert.isNotNull(service); - Object variable = service.getCurrentState().getVariable(key); - return variable == IEvaluationContext.UNDEFINED_VARIABLE ? null - : variable; - } - - private void activateFileNotifier() { - getEditorSite().getWorkbenchWindow().getWorkbench() - .addWindowListener(getWindowListener()); - getEditorSite().getPage().addSelectionListener(getEditorSite().getId(), - getSelectionListener()); - } - - private void deactivateFileNotifier() { - getEditorSite().getWorkbenchWindow().getWorkbench() - .removeWindowListener(getWindowListener()); - getEditorSite().getPage().removeSelectionListener( - getEditorSite().getId(), getSelectionListener()); - } - - private IWindowListener getWindowListener() { - if (windowListener == null) { - windowListener = new IWindowListener() { - - @Override - public void windowOpened(IWorkbenchWindow window) { - } - - @Override - public void windowDeactivated(IWorkbenchWindow window) { - } - - @Override - public void windowClosed(IWorkbenchWindow window) { - } - - @Override - public void windowActivated(IWorkbenchWindow window) { - IEditorPart activeEditor = getEditorSite().getPage() - .getActiveEditor(); - if (activeEditor == MindMapEditor.this) { - if (workbookRef != null) { - workbookRef.activateNotifier(); - } - } - } - }; - } - return windowListener; - } - - private ISelectionListener getSelectionListener() { - if (selectionListener == null) { - selectionListener = new ISelectionListener() { - - @Override - public void selectionChanged(IWorkbenchPart part, - ISelection selection) { - if (workbookRef != null) { - workbookRef.activateNotifier(); - } - } - }; - } - return selectionListener; - } - - @Override - public void fileChanged(final String title, final String message, - final String[] buttons) { - if (workbookRef.getState() != IWorkbookRef.NORMAL) { - return; - } - - if (ignoreFileChanged) { - return; - } - - Display.getDefault().asyncExec(new Runnable() { - - @Override - public void run() { - deactivateFileNotifier(); - getEditorSite().getPage().activate(MindMapEditor.this); - if (!isDirty()) { - reload(); - } else { - MessageDialog dialog = new MessageDialog(null, title, null, - NLS.bind( - MindMapMessages.MindMapEditor_fileChangedDialog_message_prefix - + message, - workbookRef.getName()), - MessageDialog.CONFIRM, buttons, 0); - - int code = dialog.open(); - if (code == 0) { - reload(); - } else if (code == 1 || code == -1) { - ignoreFileChanged = true; - } - } - - activateFileNotifier(); - } - }); - } - - @Override - public void fileRemoved(final String title, final String message, - final String[] buttons, boolean forceQuit) { - if (workbookRef.getState() != IWorkbookRef.NORMAL) { - return; - } - - if (forceQuit) { - Display.getDefault().asyncExec(new Runnable() { - - @Override - public void run() { - closeEditor(); - } - }); - return; - } - - Display.getDefault().asyncExec(new Runnable() { - - @Override - public void run() { - deactivateFileNotifier(); - getEditorSite().getPage().activate(MindMapEditor.this); - if (!isDirty()) { - closeEditor(); - } else { - MessageDialog dialog = new MessageDialog(null, title, null, - NLS.bind( - MindMapMessages.MindMapEditor_fileRemovedDialog_message_prefix - + message, - workbookRef.getName()), - MessageDialog.CONFIRM, buttons, 0); - - int code = dialog.open(); - if (code == 0) { - doSaveAs(); - } else if (code == 1 || code == -1) { - closeEditor(); - } - - activateFileNotifier(); - } - } - }); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorSupportProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.ISaveablePart2; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWindowListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.internal.util.BundleUtility; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.progress.IProgressService; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; +import org.eclipse.ui.services.IEvaluationService; +import org.eclipse.ui.statushandlers.IStatusAdapterConstants; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.eclipse.ui.statushandlers.StatusManager; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IFileEntry; +import org.xmind.core.IManifest; +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.ISheetComponent; +import org.xmind.core.ISheetSettings; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicComponent; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.EditDomain; +import org.xmind.gef.IEditDomainListener; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.image.ResizeConstants; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.ui.actions.IActionRegistry; +import org.xmind.gef.ui.actions.RedoAction; +import org.xmind.gef.ui.actions.UndoAction; +import org.xmind.gef.ui.editor.GraphicalEditor; +import org.xmind.gef.ui.editor.IEditable; +import org.xmind.gef.ui.editor.IEditingContext; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.gef.ui.editor.IInteractiveMessage; +import org.xmind.ui.IWordContextProvider; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.blackbox.BlackBox; +import org.xmind.ui.commands.ModifyFoldedCommand; +import org.xmind.ui.commands.MoveSheetCommand; +import org.xmind.ui.editor.EditorHistoryItem; +import org.xmind.ui.editor.IEditorHistory; +import org.xmind.ui.editor.PageTitleTabFolderRenderer; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.MindMapWordContextProvider; +import org.xmind.ui.internal.actions.CopySheetAction; +import org.xmind.ui.internal.actions.CreateSheetAction; +import org.xmind.ui.internal.actions.DeleteOtherSheetsAction; +import org.xmind.ui.internal.actions.DeleteSheetAction; +import org.xmind.ui.internal.actions.DuplicateSheetAction; +import org.xmind.ui.internal.actions.PasteSheetAction; +import org.xmind.ui.internal.actions.ShowPropertiesAction; +import org.xmind.ui.internal.e4handlers.SaveWorkbookAsHandler; +import org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider; +import org.xmind.ui.internal.mindmap.MindMapEditDomain; +import org.xmind.ui.internal.mindmap.MindMapState; +import org.xmind.ui.internal.mindmap.Overview; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefListener; +import org.xmind.ui.mindmap.MindMapImageExporter; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.mindmap.MindMapViewerExportSourceProvider; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.tabfolder.IPageMoveListener; +import org.xmind.ui.tabfolder.PageMoveHelper; +import org.xmind.ui.util.Logger; +import org.xmind.ui.wizards.ISaveContext; + +public class MindMapEditor extends GraphicalEditor implements ISaveablePart2, + ICoreEventListener, IPageMoveListener, IPropertyChangeListener, + IMindMapPreviewGenerator, ISaveContext, IWorkbookRefListener { + + public static final int OVERVIEW_WIDTH = 300; + public static final int OVERVIEW_HEIGHT = 180; + + private static final int DEFAULT_EXPORT_MARGIN = 5; + + private static final int MINIMUM_PREVIEW_WIDTH = 420; + private static final int MAXIMUM_PREVIEW_WIDTH = MINIMUM_PREVIEW_WIDTH * 4; + + private static class EditorStatus { + + private static EditorStatus instance = null; + + private int activeIndex; + + private List zooms; + + private List scrollPositions; + + private List indexPaths; + + private List> topicTypeChains; + + private EditorStatus() { + } + + public void saveStatus(IWorkbookRef workbookRef, int activeIndex, + IGraphicalEditorPage[] pages) { + init(); + if (workbookRef != null) { + IWorkbook workbook = workbookRef.getWorkbook(); + if (workbook != null && pages != null && (pages.length != 0)) { + this.activeIndex = activeIndex; + for (IGraphicalEditorPage page : pages) { + IGraphicalViewer viewer = page.getViewer(); + if (zooms == null) + zooms = new ArrayList(); + double zoom = viewer.getZoomManager().getScale(); + zooms.add(zoom); + + if (scrollPositions == null) + scrollPositions = new ArrayList(); + Point scrollPosition = viewer.getScrollPosition(); + scrollPositions.add(scrollPosition); + + if (indexPaths == null) + indexPaths = new ArrayList(); + if (topicTypeChains == null) + topicTypeChains = new ArrayList>(); + Object focused = viewer.getFocused(); + if (focused == null || !(focused instanceof ITopic)) { + indexPaths.add(""); //$NON-NLS-1$ + topicTypeChains + .add(Collections. emptyList()); + } else { + List typeChain = new ArrayList(); + String indexPath = getTopicIndexPath( + (ITopic) focused, "", typeChain); //$NON-NLS-1$ + indexPaths.add(indexPath); + Collections.reverse(typeChain); + topicTypeChains.add(typeChain); + } + } + } + } + } + + private void init() { + activeIndex = 0; + + if (zooms != null) + zooms.clear(); + + if (scrollPositions != null) + scrollPositions.clear(); + + if (indexPaths != null) + indexPaths.clear(); + + if (topicTypeChains != null) + topicTypeChains.clear(); + } + + private String getTopicIndexPath(ITopic topic, String path, + List typeChain) { + path = topic.getIndex() + "/" + path; //$NON-NLS-1$ + typeChain.add(topic.getType()); + if (topic.getParent() != null + && topic.getParent() instanceof ITopic) + return getTopicIndexPath(topic.getParent(), path, typeChain); + return path; + } + + public int getActiveIndex() { + return activeIndex; + } + + public List getZooms() { + return zooms; + } + + public List getScrollPositions() { + return scrollPositions; + } + + public List getIndexPaths() { + return indexPaths; + } + + public List> getTopicTypeChains() { + return topicTypeChains; + } + + public static EditorStatus getInstance() { + if (instance == null) { + synchronized (EditorStatus.class) { + if (instance == null) + instance = new EditorStatus(); + } + } + return instance; + } + } + + private class MindMapEditorSelectionProvider + extends MultiPageSelectionProvider { + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.tabfolder.DelegatedSelectionProvider#setSelection(org + * .eclipse.jface.viewers.ISelection) + */ + @Override + public void setSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + for (Object element : ((IStructuredSelection) selection) + .toList()) { + if (element instanceof ITopicComponent) { + setSelectionAndUnfold(element); + } else if (element instanceof IRelationship) { + IRelationship r = (IRelationship) element; + IRelationshipEnd e1 = r.getEnd1(); + IRelationshipEnd e2 = r.getEnd2(); + if (e1 instanceof ITopicComponent) { + setSelectionAndUnfold(e1); + } + if (e2 instanceof ITopicComponent) { + setSelectionAndUnfold(e2); + + } + } + } + } + + super.setSelection(selection); + } + } + + private IWorkbookRef workbookRef = null; + + private ICoreEventRegister workbookEventRegister = null; + + private ICoreEventRegister globalEventRegister = null; + + private MindMapPageTitleEditor pageTitleEditor = null; + + private PageMoveHelper pageMoveHelper = null; + + private MindMapFindReplaceOperationProvider findReplaceOperationProvider = null; + + private Composite messageContainer = null; + + private PageBook pageBook = null; + + private Composite pageContainer = null; + + private IEditingContext editingContext = new IEditingContext() { + + @Override + public T getAdapter(Class adapter) { + MindMapEditor editor = MindMapEditor.this; + T result; + + result = editor.getSite().getService(adapter); + if (result != null) + return result; + + result = editor.getAdapter(adapter); + if (result != null) + return result; + + result = Platform.getAdapterManager().getAdapter(editor, adapter); + if (result != null) + return result; + + return null; + } + }; + + private IWordContextProvider wordContextProvider = null; + + private boolean skipNextPreviewImage = false; + + private IContextActivation contextActivation = null; + + private IEditorHistory editorHistory = null; + + private boolean passwordTried = false; + + private IWindowListener windowListener; + + private ISelectionListener selectionListener; + + private boolean ignoreFileChanged = false; + + private IEditorLayoutManager layoutManager = null; + + private IContextActivation toolContextActivation = null; + + private IContextService contextService = null; + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + this.editorHistory = site.getService(IEditorHistory.class); + this.workbookRef = createWorkbookRefFromInput(input); + if (this.workbookRef == null) + throw new PartInitException( + "Failed to obtain workbook reference from editor input '" //$NON-NLS-1$ + + input.toString() + "'"); //$NON-NLS-1$ + + super.init(site, input); + setMiniBarContributor(new MindMapMiniBarContributor()); + } + + private IWorkbookRef createWorkbookRefFromInput(IEditorInput input) { + IWorkbookRef workbookRef = input.getAdapter(IWorkbookRef.class); + if (workbookRef != null) + return workbookRef; + + URI uri = input.getAdapter(URI.class); + if (uri != null) { + return MindMapUIPlugin.getDefault().getWorkbookRefFactory() + .createWorkbookRef(uri, null); + } + + return null; + } + + protected ISelectionProvider createSelectionProvider() { + return new MindMapEditorSelectionProvider(); + } + + protected ICommandStack createCommandStack() { + if (workbookRef != null) + return workbookRef.getCommandStack(); + return super.createCommandStack(); + } + + protected void disposeCommandStack(ICommandStack commandStack) { + // No need to dispose command stack here, because the workbook reference + // manager will dispose unused command stacks automatically. + } + + private void disposeData() { + if (workbookRef != null && workbookRef.getURI() != null) { + URI uri = workbookRef.getURI(); + if (URIUtil.isFileURI(uri)) { + BlackBox.removeSavedMap(URIUtil.toFile(uri).getAbsolutePath()); + } + } + + final IWorkbookRef theWorkbookRef = this.workbookRef; + if (theWorkbookRef != null) { + theWorkbookRef.removePropertyChangeListener(this); + theWorkbookRef.removeWorkbookRefListener(this); + MindMapState.getInstance().saveState(theWorkbookRef, getPages()); + if (theWorkbookRef.isDirty()) { + theWorkbookRef.discardChanges(); + } + safeRun(null, false, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + theWorkbookRef.close(monitor); + } + }); + IEditingContext activeContext = theWorkbookRef.getActiveContext(); + if (activeContext == this.editingContext) { + theWorkbookRef.setActiveContext(null); + } + } + + deactivateToolContext(); + + uninstallModelListener(); + } + + public void dispose() { + if (contextActivation != null) { + IContextService cs = getSite().getService(IContextService.class); + cs.deactivateContext(contextActivation); + } + disposeData(); + super.dispose(); + IEditorInput editorInput = getEditorInput(); + if (editorInput instanceof MindMapEditorInput) { + ((MindMapEditorInput) editorInput).dispose(); + } + deactivateFileNotifier(); + workbookEventRegister = null; + globalEventRegister = null; + pageTitleEditor = null; + pageMoveHelper = null; + findReplaceOperationProvider = null; + workbookRef = null; + pageBook = null; + pageContainer = null; + + // release reference to the workbook reference object + this.workbookRef = null; + layoutManager = null; + } + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + + Composite container = getContainer(); + if (container instanceof CTabFolder) { + ((CTabFolder) container).setRenderer(new PageTitleTabFolderRenderer( + (CTabFolder) container, this)); + } + + activateFileNotifier(); + } + + protected Composite createContainerParent(Composite parent) { + FormLayout formLayout = new FormLayout(); + parent.setLayout(formLayout); + + messageContainer = new Composite(parent, SWT.BORDER); + FormData messageFormData = new FormData(); + //no correct size data to set form data + messageContainer.setLayoutData(messageFormData); + messageContainer.setVisible(false); + + GridLayout messageLayout = new GridLayout(1, false); + messageLayout.marginWidth = 0; + messageLayout.marginHeight = 0; + messageLayout.horizontalSpacing = 0; + messageLayout.verticalSpacing = 0; + messageContainer.setLayout(messageLayout); + + updateMessages(false); + + pageBook = new PageBook(parent, SWT.NONE); + FormData pageBookData = new FormData(); + pageBookData.left = new FormAttachment(0, 0); + pageBookData.top = new FormAttachment(0, 0); + pageBookData.bottom = new FormAttachment(100, 0); + pageBookData.right = new FormAttachment(100, 0); + pageBook.setLayoutData(pageBookData); + + pageContainer = new Composite(pageBook, SWT.NONE); + layoutManager = new EditorLayoutManager(pageContainer); + layoutManager.setActiveLayout(new DefaultEditorLayout()); + IContextService cs = getSite().getService(IContextService.class); + contextActivation = cs.activateContext(MindMapUI.CONTEXT_MINDMAP); + return pageContainer; + } + + @Override + protected void createEditorContents() { + super.createEditorContents(); + + if (workbookRef != null) { + workbookRef.setActiveContext(editingContext); + workbookRef.addPropertyChangeListener(this); + workbookRef.addWorkbookRefListener(this); + } + + // Make editor actions: + createActions(getActionRegistry()); + + // Update editor pane title: + updateNames(); + + // Add helpers to handle moving pages, editing page title, showing + // page popup preview, creating new page, etc.: + if (getContainer() instanceof CTabFolder) { + final CTabFolder tabFolder = (CTabFolder) getContainer(); + pageMoveHelper = new PageMoveHelper(tabFolder); + pageMoveHelper.addListener(this); + pageTitleEditor = new MindMapPageTitleEditor(tabFolder, this); +// pageTitleEditor.addPageTitleChangedListener(this); +// pageTitleEditor.setContextId(getSite(), +// MindMapUI.CONTEXT_PAGETITLE_EDIT); + new MindMapEditorPagePopupPreviewHelper(this, tabFolder); + + } + + // Let 3rd-party plugins configure this editor: + MindMapEditorConfigurerManager.getInstance().configureEditor(this); + + // Try loading workbook: + if (getWorkbook() != null) { + workbookLoaded(); + } else if (workbookRef != null) { + final IWorkbookRef theWorkbookRef = workbookRef; + Display.getCurrent().asyncExec(new Runnable() { + @Override + public void run() { + loadWorkbook(theWorkbookRef, 0); + collectUserData(theWorkbookRef.getURI()); + } + }); + } + } + + private static void collectUserData(URI uri) { + Assert.isNotNull(uri); + String scheme = uri.getScheme(); + if (scheme == null || "".equalsIgnoreCase(scheme)) //$NON-NLS-1$ + return; + if ("file".equalsIgnoreCase(scheme)) { //$NON-NLS-1$ + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.OPEN_LOCAL_WORKBOOK_COUNT); + } else if ("seawind".equalsIgnoreCase(scheme)) { //$NON-NLS-1$ + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.OPEN_CLOUD_WORKBOOK_COUNT); + } + } + + private void loadWorkbook(final IWorkbookRef workbookRef, int times) { + IEncryptable encryptable = workbookRef.getAdapter(IEncryptable.class); + if (encryptable != null && !encryptable.hasPassword()) { + /// make sure setPassword is called to prevent the default password dialog + encryptable.setPassword(null); + } + + IWorkbenchSiteProgressService context = getSite() + .getService(IWorkbenchSiteProgressService.class); + Assert.isTrue(context != null); + try { + context.run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + workbookRef.open(monitor); + } + }); + } catch (final InvocationTargetException e) { + CoreException coreEx = getCoreException(e); + if (coreEx != null) { + int errType = coreEx.getType(); + if (errType == Core.ERROR_WRONG_PASSWORD) { + // password error + String message = passwordTried + ? MindMapMessages.MindMapEditor_passwordPrompt_message1 + : MindMapMessages.MindMapEditor_passwordPrompt_message2; + openDecryptionDialog(workbookRef, message, times); + passwordTried = true; + return; + } + } + + // failed + Throwable cause = e.getTargetException(); + if (cause == null) + cause = e; + + if (cause instanceof FileNotFoundException) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + MessageDialog.openWarning(null, + MindMapMessages.OpenLocalFileHandler_MessageDialog_title, + MindMapMessages.WorkbookHistoryItem_FileMissingMessage); + } + }); + asyncClose(); + } else { + showError(cause, + workbookRef.getAdapter(ErrorSupportProvider.class)); + } + return; + } catch (InterruptedException e) { + // canceled + asyncClose(); + return; + } + + workbookLoaded(); + } + + private void openDecryptionDialog(final IWorkbookRef workbookRef, + String message, int times) { + final int nextTime = times + 1; + final IEncryptable encryptable = workbookRef + .getAdapter(IEncryptable.class); + + new DecryptionDialog(Display.getCurrent().getActiveShell(), + workbookRef.getName(), encryptable.getPasswordHint(), times) { + protected void okPressed() { + super.okPressed(); + + encryptable.setPassword(getPassword()); + loadWorkbook(workbookRef, nextTime); + }; + + protected void handleShellCloseEvent() { + super.handleShellCloseEvent(); + asyncClose(); + }; + + protected void cancelPressed() { + super.cancelPressed(); + asyncClose(); + }; + }.open(); + } + + private CoreException getCoreException(Throwable e) { + if (e == null) + return null; + if (e instanceof CoreException) + return (CoreException) e; + return getCoreException(e.getCause()); + } + + private void asyncClose() { + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + closeEditor(); + } + }); + } + + private void closeEditor() { + getSite().getPage().closeEditor(this, false); + } + + private void showError(Throwable exception, + ErrorSupportProvider supportProvider) { + StatusAdapter statusAdapter = new StatusAdapter(new Status( + IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + MindMapMessages.LoadWorkbookJob_errorDialog_title, exception)); + statusAdapter.setProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY, + Long.valueOf(System.currentTimeMillis())); + ErrorDialog errorDialog = new ErrorDialog( + Display.getCurrent().getActiveShell(), statusAdapter, + supportProvider); + errorDialog.setCloseCallback(new Runnable() { + @Override + public void run() { + asyncClose(); + } + }); + errorDialog.open(); + } + + protected void createActions(IActionRegistry actionRegistry) { + UndoAction undoAction = new UndoAction(this); + actionRegistry.addAction(undoAction); + addCommandStackAction(undoAction); + + RedoAction redoAction = new RedoAction(this); + actionRegistry.addAction(redoAction); + addCommandStackAction(redoAction); + + CreateSheetAction createSheetAction = new CreateSheetAction(this); + actionRegistry.addAction(createSheetAction); + + DeleteSheetAction deleteSheetAction = new DeleteSheetAction(this); + actionRegistry.addAction(deleteSheetAction); + + DeleteOtherSheetsAction deleteOtherSheetAction = new DeleteOtherSheetsAction( + this); + actionRegistry.addAction(deleteOtherSheetAction); + + DuplicateSheetAction duplicateSheetAction = new DuplicateSheetAction( + this); + actionRegistry.addAction(duplicateSheetAction); + + CopySheetAction copySheetAction = new CopySheetAction(this); + actionRegistry.addAction(copySheetAction); + + PasteSheetAction pasteSheetAction = new PasteSheetAction(this); + actionRegistry.addAction(pasteSheetAction); + + ShowPropertiesAction showPropertiesAction = new ShowPropertiesAction( + getSite().getWorkbenchWindow()); + actionRegistry.addAction(showPropertiesAction); + } + + private void configurePage(IGraphicalEditorPage page) { + MindMapEditorConfigurerManager.getInstance().configurePage(page); + } + + protected void createPages() { + if (getWorkbook() == null) + return; + + for (ISheet sheet : getWorkbook().getSheets()) { + IGraphicalEditorPage page = createSheetPage(sheet, -1); + configurePage(page); + } + if (getPageCount() > 0) { + setActivePage(0); + } + } + + private void addOverview() { + final Composite container = getContainer(); + + final Composite overviewControl = createOverview(container); + overviewControl.moveAbove(null); + overviewControl + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + new Overview(overviewControl, this); + + Rectangle containerClientArea = container.getClientArea(); + overviewControl.setBounds(containerClientArea.width - OVERVIEW_WIDTH, + containerClientArea.height - OVERVIEW_HEIGHT, OVERVIEW_WIDTH, + OVERVIEW_HEIGHT); + + container.addControlListener(new ControlAdapter() { + public void controlResized(ControlEvent e) { + Rectangle containerClientArea = container.getClientArea(); + overviewControl.setBounds( + containerClientArea.width - OVERVIEW_WIDTH, + containerClientArea.height - OVERVIEW_HEIGHT, + OVERVIEW_WIDTH, OVERVIEW_HEIGHT); + } + + public void controlMoved(ControlEvent e) { + Rectangle containerClientArea = container.getClientArea(); + overviewControl.setBounds( + containerClientArea.width - OVERVIEW_WIDTH, + containerClientArea.height - OVERVIEW_HEIGHT, + OVERVIEW_WIDTH, OVERVIEW_HEIGHT); + } + }); + + } + + private Composite createOverview(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + composite.setLayout(layout); + return composite; + } + + protected IGraphicalEditorPage createSheetPage(ISheet sheet, int index) { + IGraphicalEditorPage page = new MindMapEditorPage(); + page.init(this, sheet); + addPage(page); + if (index >= 0 && index < getPageCount()) { + movePageTo(findPage(page), index); + } + index = findPage(page); + if (getActivePage() != index) { + setActivePage(index); + } + page.updatePageTitle(); + MindMapState.getInstance().loadState(getWorkbookRef(), page); + return page; + } + + protected EditDomain createEditDomain(IGraphicalEditorPage page) { + MindMapEditDomain domain = new MindMapEditDomain(); + domain.addEditDomainListener(new IEditDomainListener() { + + @Override + public void activeToolChanged(ITool oldTool, ITool newTool) { + changeContext(newTool); + } + }); + domain.setCommandStack(getCommandStack()); + return domain; + } + + protected void changeContext(ITool newTool) { + deactivateToolContext(); + activateContext(newTool == null ? null : newTool.getContextId()); + } + + protected void changeContext(String contextId) { + deactivateToolContext(); + activateContext(contextId); + } + + private void activateContext(String contextId) { + if (contextId == null) + return; + contextService = getSite().getService(IContextService.class); + if (contextService != null) { + toolContextActivation = contextService.activateContext(contextId); + } + } + + private void deactivateToolContext() { + if (contextService != null && toolContextActivation != null) { + contextService.deactivateContext(toolContextActivation); + } + contextService = null; + toolContextActivation = null; + } + + private void updateMessages(boolean layout) { + for (Control messageItem : messageContainer.getChildren()) { + messageItem.dispose(); + } + List messages = workbookRef.getMessages(); + if (messages != null && !messages.isEmpty()) { + for (IInteractiveMessage message : new ArrayList( + messages)) { + + Image icon; + Color lineColor; + Color textColor; + int type = message.getMessageType(); + if (type == IInteractiveMessage.WARNING) { + ///TODO use a dedicated icon + icon = null; + lineColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ + textColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ + } else if (type == IInteractiveMessage.ERROR) { + ///TODO use a dedicated icon + icon = null; + lineColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ + textColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ + } else { + ///TODO use a dedicated icon + icon = Display.getCurrent() + .getSystemImage(SWT.ICON_INFORMATION); + lineColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#fff6ae")); //$NON-NLS-1$ + textColor = (Color) JFaceResources.getResources() + .get(ColorUtils.toDescriptor("#1e1e1e")); //$NON-NLS-1$ + } + + String text = message.getMessage(); + if (text == null) { + text = ""; //$NON-NLS-1$ + } + + List actions = message.getActions(); + + final Composite line = new Composite(messageContainer, + SWT.NONE); + line.setBackground(lineColor); + GridData lineData = new GridData(SWT.CENTER, SWT.FILL, true, + false); + lineData.widthHint = 500; + line.setLayoutData(lineData); + line.setLayout(new GridLayout(2, false)); + + Composite leftComposite = new Composite(line, SWT.NONE); + leftComposite.setBackground(line.getBackground()); + GridData lineBodyData = new GridData(SWT.CENTER, SWT.FILL, true, + false); + leftComposite.setLayoutData(lineBodyData); + int numColumns = 0; + GridLayout leftCompositeLayout = new GridLayout(numColumns, + false); + leftCompositeLayout.marginLeft = 16; + leftCompositeLayout.marginHeight = 5; + leftCompositeLayout.horizontalSpacing = 3; + leftCompositeLayout.verticalSpacing = 0; + leftComposite.setLayout(leftCompositeLayout); + + if (icon != null) { + numColumns++; + Label iconLabel = new Label(leftComposite, SWT.NONE); + iconLabel.setBackground(line.getBackground()); + iconLabel.setImage(icon); + iconLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, false, true)); + } + + numColumns++; + Label textLabel = new Label(leftComposite, + SWT.WRAP | SWT.CENTER); + textLabel.setText(text); + textLabel.setBackground(line.getBackground()); + textLabel.setForeground(textColor); + textLabel.setLayoutData( + new GridData(SWT.CENTER, SWT.CENTER, true, true)); + Font textFont = textLabel.getFont(); + if (textFont != null) { + FontData[] fontData = textFont.getFontData(); + FontData[] newFontData = FontUtils.newHeight(fontData, + Util.isMac() ? 12 : 10); + textLabel.setFont((Font) JFaceResources.getResources() + .get(FontDescriptor.createFrom(newFontData))); + } + + if (!actions.isEmpty()) { + numColumns++; + Composite actionBar = new Composite(leftComposite, + SWT.NONE); + actionBar.setBackground(line.getBackground()); + actionBar.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, false, true)); + GridLayout actionLayout = new GridLayout(actions.size(), + false); + actionLayout.marginWidth = 0; + actionLayout.marginHeight = 0; + actionLayout.horizontalSpacing = 3; + actionLayout.verticalSpacing = 0; + actionBar.setLayout(actionLayout); + + for (final IAction action : actions) { + final Button actionButton = new Button(actionBar, + SWT.PUSH); + actionButton.setBackground(actionBar.getBackground()); + actionButton.setLayoutData(new GridData(SWT.FILL, + SWT.CENTER, false, true)); + String actionText = action.getText(); + if (actionText == null) { + actionButton.setText(actionText); + } else { + ImageDescriptor actionImageDescriptor = action + .getImageDescriptor(); + if (actionImageDescriptor != null) { + final Image actionImage = actionImageDescriptor + .createImage(Display.getCurrent()); + actionButton.addDisposeListener( + new DisposeListener() { + + @Override + public void widgetDisposed( + DisposeEvent e) { + actionImage.dispose(); + } + }); + actionButton.setImage(actionImage); + } + } + actionButton.setToolTipText(action.getToolTipText()); + actionButton.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(Event event) { + action.runWithEvent(event); + } + }); + } + } + + leftCompositeLayout.numColumns = numColumns; + + final Label closeImageLabel = new Label(line, SWT.NONE); + closeImageLabel.setBackground(line.getBackground()); + closeImageLabel.setImage((Image) JFaceResources.getResources() + .get(MindMapUI.getImages().get("close.png", true))); //$NON-NLS-1$ + closeImageLabel.setLayoutData( + new GridData(SWT.END, SWT.BEGINNING, false, false)); + closeImageLabel.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + if (messageContainer != null + && !messageContainer.isDisposed()) { + if (line != null && !line.isDisposed()) { + line.dispose(); + } + Control[] children = messageContainer.getChildren(); + if (children == null || children.length == 0) { + messageContainer.setVisible(false); + } + messageContainer.getParent().layout(true); + } + } + }); + closeImageLabel.addMouseTrackListener(new MouseTrackListener() { + + @Override + public void mouseHover(MouseEvent e) { + closeImageLabel.setCursor(Display.getDefault() + .getSystemCursor(SWT.CURSOR_HAND)); + } + + @Override + public void mouseExit(MouseEvent e) { + closeImageLabel.setCursor(null); + } + + @Override + public void mouseEnter(MouseEvent e) { + closeImageLabel.setCursor(Display.getDefault() + .getSystemCursor(SWT.CURSOR_HAND)); + } + }); + } + org.eclipse.swt.graphics.Point size = messageContainer + .computeSize(SWT.DEFAULT, SWT.DEFAULT); + FormData messageFormData = new FormData(); + messageFormData.left = new FormAttachment(50, -size.x / 2); + messageFormData.right = new FormAttachment(50, size.x / 2); + messageFormData.top = new FormAttachment(0, 0); + //can't set bottom +// messageFormData.bottom = new FormAttachment(100, -size.y); + messageContainer.setLayoutData(messageFormData); + messageContainer.setVisible(true); + } + + if (layout) { + messageContainer.getParent().layout(true, true); + } + } + + protected void updateNames() { + setPartName(getEditorInput().getName()); + setTitleToolTip(getEditorInput().getToolTipText()); + } + + public IWorkbookRef getWorkbookRef() { + return workbookRef; + } + + public IWorkbook getWorkbook() { + if (workbookRef == null) + return null; + return workbookRef.getWorkbook(); + } + + @SuppressWarnings("unchecked") + @Override + public T getAdapter(Class adapter) { + if (adapter == IEditorLayoutManager.class) + return (T) layoutManager; + return super.getAdapter(adapter); + } + + @Override + protected T getEditorAdapter(Class adapter) { + if (workbookRef != null) { + T result = workbookRef.getAdapter(adapter); + if (result != null) + return result; + } + + if (adapter == IWorkbookRef.class) { + return adapter.cast(getWorkbookRef()); + } else if (adapter == IWorkbook.class) { + return adapter.cast(getWorkbook()); + } else if (adapter == MindMapPageTitleEditor.class) { + return adapter.cast(pageTitleEditor); + } else if (adapter == PageMoveHelper.class) { + return adapter.cast(pageMoveHelper); + } else if (adapter == IFindReplaceOperationProvider.class) { + if (findReplaceOperationProvider == null) { + findReplaceOperationProvider = new MindMapFindReplaceOperationProvider( + this); + } + return adapter.cast(findReplaceOperationProvider); + } else if (adapter == IWordContextProvider.class) { + if (wordContextProvider == null) { + wordContextProvider = new MindMapWordContextProvider(this); + } + return adapter.cast(wordContextProvider); + } else if (adapter == IDialogPaneContainer.class) { +// return adapter.cast(backCover); + } + return super.getEditorAdapter(adapter); + } + + protected void installModelListener() { + IWorkbook workbook = getWorkbook(); + workbookEventRegister = new CoreEventRegister(workbook, this); + workbookEventRegister.register(Core.SheetAdd); + workbookEventRegister.register(Core.SheetRemove); + workbookEventRegister.register(Core.SheetMove); + workbookEventRegister.register(Core.PasswordChange); + workbookEventRegister.register(Core.WorkbookPreSaveOnce); + + globalEventRegister = new CoreEventRegister( + workbook.getAdapter(ICoreEventSupport.class), this); + globalEventRegister.register(Core.SheetSettings); + } + + protected void uninstallModelListener() { + if (workbookEventRegister != null) { + workbookEventRegister.unregisterAll(); + workbookEventRegister = null; + } + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } + } + + public void handleCoreEvent(final CoreEvent event) { + if (pageBook == null || pageBook.isDisposed() || workbookRef == null) + return; + + pageBook.getDisplay().syncExec(new Runnable() { + + public void run() { + String type = event.getType(); + if (Core.WorkbookPreSaveOnce.equals(type)) { + firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); + firePropertyChange(PROP_INPUT); + } else if (Core.SheetAdd.equals(type)) { + ISheet sheet = (ISheet) event.getTarget(); + int index = event.getIndex(); + IGraphicalEditorPage page = createSheetPage(sheet, index); + configurePage(page); + } else if (Core.SheetRemove.equals(type)) { + ISheet sheet = (ISheet) event.getTarget(); + IGraphicalEditorPage page = findPage(sheet); + if (page != null) { + removePage(page); + } + } else if (Core.SheetMove.equals(type)) { + int oldIndex = event.getIndex(); + int newIndex = ((ISheet) event.getTarget()).getIndex(); + movePageTo(oldIndex, newIndex); + } else if (Core.PasswordChange.equals(type)) { + IWorkbook workbook = getWorkbook(); + if (workbook instanceof ICoreEventSource2) { + ((ICoreEventSource2) workbook) + .registerOnceCoreEventListener( + Core.WorkbookPreSaveOnce, + ICoreEventListener.NULL); + } + } + + //update sheet tab colors + if (Core.SheetSettings.equals(type) + && ISheetSettings.ATTR_RGB.equals(event.getTarget())) { + updateSheetTabColors(); + } + } + }); + } + + private void updateSheetTabColors() { + getContainer().redraw(); + } + + protected void saveAndRun(Command command) { + ICommandStack cs = getCommandStack(); + if (cs != null) + cs.execute(command); + } + + public void pageMoved(int fromIndex, int toIndex) { + IWorkbook workbook = getWorkbook(); + MoveSheetCommand command = new MoveSheetCommand(workbook, fromIndex, + toIndex); + command.setLabel(""); //$NON-NLS-1$ + saveAndRun(command); + } + +// public void pageTitleChanged(int pageIndex, String newValue) { +// /// forbid changing sheet title to empty string +// /// preventing saving errors (e.g. cloud syncing) +// if (newValue == null || "".equals(newValue)) //$NON-NLS-1$ +// return; +// +// IGraphicalEditorPage page = getPage(pageIndex); +// if (page != null) { +// Object pageInput = page.getInput(); +// if (pageInput instanceof ISheet) { +// ModifyTitleTextCommand command = new ModifyTitleTextCommand( +// (ISheet) pageInput, newValue); +// command.setLabel(""); //$NON-NLS-1$ +// saveAndRun(command); +// } +// } +// } + + protected void createSheet() { + IAction action = getActionRegistry() + .getAction(MindMapActionFactory.NEW_SHEET.getId()); + if (action != null && action.isEnabled()) { + action.run(); + } + } + + @Override + public void setFocus() { +// if (workbookRef != null) { +// workbookRef.setPrimaryReferrer(this); +// } + if (workbookRef != null) { + workbookRef.setActiveContext(editingContext); + } +// if (backCover != null && backCover.isOpen()) { +// backCover.setFocus(); +// } else { + super.setFocus(); +// } + } + + public void openEncryptionDialog() { + if (pageBook == null || pageBook.isDisposed()) + return; + + final IWorkbookRef theWorkbookRef = workbookRef; + + new EncryptionDialog(Display.getCurrent().getActiveShell()) { + + @Override + protected boolean hasPassword() { + IEncryptable encryptable = theWorkbookRef + .getAdapter(IEncryptable.class); + return encryptable != null && encryptable.hasPassword(); + } + + @Override + protected boolean testsPassword(String password) { + IEncryptable encryptable = theWorkbookRef + .getAdapter(IEncryptable.class); + return encryptable != null + && encryptable.testsPassword(password); + } + + @Override + protected void okPressed() { + boolean verified = verify(); + + super.okPressed(); + + if (verified) { + IEncryptable encryptable = theWorkbookRef + .getAdapter(IEncryptable.class); + if (encryptable != null) { + encryptable.setPassword(getPassword()); + encryptable.setPasswordHint(getHintMessage()); + } + } + } + }.open(); + } + + public ISelectionProvider getSelectionProvider() { + return getSite().getSelectionProvider(); + } + + public void reveal() { + getSite().getPage().activate(this); + setFocus(); + } + + /** + * @param monitor + * @deprecated + */ + @Deprecated + public void postSave(final IProgressMonitor monitor) { + getSite().getShell().getDisplay().syncExec(new Runnable() { + + public void run() { + postSave(); + } + }); + } + + public void setSelection(ISelection selection, boolean reveal, + boolean forceFocus) { + ISelectionProvider selectionProvider = getSite().getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.setSelection(selection); + } + if (forceFocus) { + getSite().getPage().activate(this); + Shell shell = getSite().getShell(); + if (shell != null && !shell.isDisposed()) { + shell.setActive(); + } + } else if (reveal) { + getSite().getPage().bringToTop(this); + } + } + + public IGraphicalEditorPage findPage(Object input) { + if (input instanceof IMindMap) { + input = ((IMindMap) input).getSheet(); + } + return super.findPage(input); + } + + private void workbookLoaded() { + passwordTried = false; + if (pageBook == null || pageBook.isDisposed()) + return; + + // TODO + pageBook.showPage(pageContainer); + if (isEditorActive()) + setFocus(); + + Assert.isTrue(getWorkbook() != null); + createPages(); + addOverview(); + if (isEditorActive()) { + setFocus(); + } + installModelListener(); + firePropertyChange(PROP_INPUT); + firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); + + recordEditorHistory(); + } + + private boolean isEditorActive() { + return getSite().getPage().getActiveEditor() == this; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.ui.editor.GraphicalEditor#findOwnedInput(org.eclipse.jface + * .viewers.ISelection) + */ + @Override + protected Object findOwnedInput(ISelection selection) { + if (selection instanceof IStructuredSelection) { + Object[] elements = ((IStructuredSelection) selection).toArray(); + for (Object element : elements) { + if (element instanceof ISheetComponent) + return ((ISheetComponent) element).getOwnedSheet(); + if (element instanceof ISheet) + return (ISheet) element; + } + } + return super.findOwnedInput(selection); + } + + public void skipNextPreviewImage() { + this.skipNextPreviewImage = true; + } + + private void setSelectionAndUnfold(Object element) { + List showElementsCommands = new ArrayList(1); + ITopic parent = ((ITopicComponent) element).getParent(); + while (parent != null) { + if (parent.isFolded()) { + showElementsCommands + .add(new ModifyFoldedCommand(parent, false)); + } + parent = parent.getParent(); + } + if (!showElementsCommands.isEmpty()) { + Command command = new CompoundCommand( + showElementsCommands.get(0).getLabel(), + showElementsCommands); + saveAndRun(command); + } + } + + @Override + public boolean isDirty() { + return workbookRef != null && workbookRef.isDirty(); + } + + @Override + public void doSave(IProgressMonitor monitor) { + if (workbookRef == null) + return; + + if (!workbookRef.canSave()) { + doSaveAs(); + return; + } + + safeRun(monitor, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + workbookRef.save(monitor); + if (MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.AUTO_BACKUP_ENABLE)) { + URI uri = workbookRef.getURI(); + if (URIUtil.isFileURI(uri)) { + BlackBox.doBackup( + URIUtil.toFile(uri).getAbsolutePath()); + } + } + postSave(); + recordEditorHistory(); + } + }); + } + + private void recordEditorHistory() { + + if (workbookRef.getURI() == null || workbookRef.getName() == null) + return; + URI uri = workbookRef.getURI(); + + //only local file or seawind file can record it history. + if (!uri.getScheme().equalsIgnoreCase("file") //$NON-NLS-1$ + && !uri.getScheme().equalsIgnoreCase("seawind")) //$NON-NLS-1$ + return; + + InputStream input = null; + try { + try { + if (uri.getScheme().equalsIgnoreCase("file")) { //$NON-NLS-1$ + input = getThumbnailStreamForLocal(); + } else + input = getThumbnailStreamFor(workbookRef); + if (input == null) + return; + editorHistory.add(workbookRef.getURI(), new EditorHistoryItem( + workbookRef.getName(), System.currentTimeMillis())); + editorHistory.saveThumbnailData(workbookRef.getURI(), input); + } finally { + if (input != null) + input.close(); + } + } catch (IOException e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to record preview image for editor history", //$NON-NLS-1$ + e)); + } + } + + private InputStream getThumbnailStreamForLocal() throws IOException { + IManifest manifest = getWorkbook().getManifest(); + if (manifest != null) { + IFileEntry thumbnailEntry = manifest + .getFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ + if (thumbnailEntry != null) + return thumbnailEntry.openInputStream(); + } + return null; + } + + private InputStream getThumbnailStreamFor(IWorkbookRef workbookRef) { + if (workbookRef == null) + return null; + + List sheets = workbookRef.getWorkbook().getSheets(); + if (sheets.isEmpty()) + return null; + + ISheet sheet = sheets.get(0); + try { + return workbookRef.getPreviewImageData(sheet.getId(), null); + } catch (IOException e) { + MindMapUIPlugin.log(e, String.format( + "Failed to load preview image for sheet 'workbooks/%s/sheets/%s'", //$NON-NLS-1$ + sheet.getParent().toString(), sheet.getId())); + } catch (SWTException e) { + MindMapUIPlugin.log(e, String.format( + "Failed to load preview image for sheet 'workbooks/%s/sheets/%s'", //$NON-NLS-1$ + sheet.getParent().toString(), sheet.getId())); + } + + return null; + } + + public void doSaveAs() { + doSaveAs(false); + } + + public void doSaveAs(boolean onlyToLocal) { + final IWorkbookRef oldWorkbookRef = this.workbookRef; + if (oldWorkbookRef == null || oldWorkbookRef + .isInState(IWorkbookRef.CLOSED | IWorkbookRef.CLOSING)) + throw new IllegalStateException( + "This mind map editor is already closed."); //$NON-NLS-1$ + + IProgressService runner = getSite().getService(IProgressService.class); + final IWorkbookRef newWorkbookRef; + try { + newWorkbookRef = SaveWorkbookAsHandler.saveWorkbookAs(this, + oldWorkbookRef, runner, null, onlyToLocal); + if (newWorkbookRef == null) + // canceled + return; + if (newWorkbookRef.equals(oldWorkbookRef)) { + // saved to old location + postSave(); + recordEditorHistory(); + return; + } + + try { + runner.run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, + InterruptedException { + newWorkbookRef.open(monitor); + newWorkbookRef.save(monitor); + } + }); + } catch (InterruptedException e) { + // canceled + return; + } + } catch (Exception e) { + StatusManager.getManager().handle(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, e.getMessage(), e), + StatusManager.SHOW); + return; + } + + // TODO save editor state before changing editor input + EditorStatus editorStatus = EditorStatus.getInstance(); + editorStatus.saveStatus(oldWorkbookRef, getActivePage(), getPages()); + + disposeData(); + while (getPageCount() > 0) { + removePage(0); + } + + this.workbookRef = newWorkbookRef; + if (newWorkbookRef != null) { + newWorkbookRef.addPropertyChangeListener(this); + newWorkbookRef.addWorkbookRefListener(this); + } + setInput(MindMapUI.getEditorInputFactory() + .createEditorInput(newWorkbookRef)); + setCommandStack(newWorkbookRef.getCommandStack()); + updateNames(); + + createPages(); + installModelListener(); + + firePropertyChange(PROP_INPUT); + postSave(); + + // TODO restore editor state after changing editor input + setActivePage(editorStatus.getActiveIndex()); + IGraphicalEditorPage[] pages = getPages(); + for (int index = 0; index < pages.length; index++) { + IGraphicalViewer viewer = pages[index].getViewer(); + viewer.getProperties().set( + IMindMapViewer.VIEWER_SELECT_CENTRALTOPIC, Boolean.FALSE); + Double scale = editorStatus.getZooms().get(index); + if (scale != null) + viewer.getZoomManager().setScale(scale); + + String indexPath = index < editorStatus.getIndexPaths().size() + ? editorStatus.getIndexPaths().get(index) : ""; //$NON-NLS-1$ + List topicTypeChain = index < editorStatus + .getTopicTypeChains().size() + ? editorStatus.getTopicTypeChains().get(index) + : Collections. emptyList(); + if (indexPath != null) { + if ("".equals(indexPath)) //$NON-NLS-1$ + viewer.setSelection(StructuredSelection.EMPTY, true); + else { + Object input = viewer.getInput(); + if (input instanceof IMindMap) { + ITopic topic = ((IMindMap) input).getCentralTopic(); + String[] indexes = indexPath.split("/"); //$NON-NLS-1$ + for (int i = 1; i < indexes.length; i++) { + String type = i < topicTypeChain.size() + ? topicTypeChain.get(i) : ITopic.ATTACHED; + if (topic.getChildren(type).size() <= Integer + .parseInt(indexes[i])) { + continue; + } + topic = topic.getChildren(type) + .get(Integer.parseInt(indexes[i])); + } + viewer.setSelection(new StructuredSelection(topic), + true); + } + + } + } + + Point scrollPosition = editorStatus.getScrollPositions().get(index); + if (scrollPosition != null) + viewer.scrollTo(scrollPosition); + } + + recordEditorHistory(); + + //Force update IEclipseContext + IEclipseContext partContext = getSite() + .getService(IEclipseContext.class); + partContext.deactivate(); + partContext.activateBranch(); + } + + private void reload() { + IWorkbookRef oldWorkbookRef = this.workbookRef; + if (oldWorkbookRef == null || oldWorkbookRef + .isInState(IWorkbookRef.CLOSED | IWorkbookRef.CLOSING)) { + throw new IllegalStateException( + "This mind map editor is already closed."); //$NON-NLS-1$ + } + + // save editor state before changing editor input + EditorStatus editorStatus = EditorStatus.getInstance(); + editorStatus.saveStatus(oldWorkbookRef, getActivePage(), getPages()); + + IEditingContext context = oldWorkbookRef.getActiveContext(); + disposeData(); + while (getPageCount() > 0) { + removePage(0); + } + + final IWorkbookRef newWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(oldWorkbookRef.getURI(), null); + if (newWorkbookRef == null) { + return; + } + + try { + IProgressService runner = getSite() + .getService(IProgressService.class); + runner.run(true, true, new IRunnableWithProgress() { + + @Override + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + newWorkbookRef.open(monitor); + } + }); + } catch (InvocationTargetException e) { + e.printStackTrace(); + return; + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + this.workbookRef = newWorkbookRef; + if (newWorkbookRef != null) { + newWorkbookRef.setActiveContext(context); + newWorkbookRef.addPropertyChangeListener(this); + newWorkbookRef.addWorkbookRefListener(this); + } + setInput(MindMapUI.getEditorInputFactory() + .createEditorInput(newWorkbookRef)); + setCommandStack(newWorkbookRef.getCommandStack()); + updateNames(); + + createPages(); + installModelListener(); + + firePropertyChange(PROP_INPUT); + firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); + + // restore editor state after changing editor input + setActivePage(editorStatus.getActiveIndex()); + IGraphicalEditorPage[] pages = getPages(); + for (int index = 0; index < pages.length; index++) { + IGraphicalViewer viewer = pages[index].getViewer(); + viewer.getProperties().set( + IMindMapViewer.VIEWER_SELECT_CENTRALTOPIC, Boolean.FALSE); + Double scale = editorStatus.getZooms().size() > index + ? editorStatus.getZooms().get(index) : null; + if (scale != null) + viewer.getZoomManager().setScale(scale); + + String indexPath = editorStatus.getIndexPaths().size() > index + ? editorStatus.getIndexPaths().get(index) : ""; //$NON-NLS-1$ + List topicTypeChain = editorStatus.getTopicTypeChains() + .size() > index + ? editorStatus.getTopicTypeChains().get(index) + : Collections. emptyList(); + if (indexPath != null) { + if ("".equals(indexPath)) //$NON-NLS-1$ + viewer.setSelection(StructuredSelection.EMPTY, true); + else { + Object input = viewer.getInput(); + if (input instanceof IMindMap) { + ITopic topic = ((IMindMap) input).getCentralTopic(); + String[] indexes = indexPath.split("/"); //$NON-NLS-1$ + for (int i = 1; i < indexes.length; i++) { + String type = i < topicTypeChain.size() + ? topicTypeChain.get(i) : ITopic.ATTACHED; + if (topic.getChildren(type).size() <= Integer + .parseInt(indexes[i])) { + continue; + } + topic = topic.getChildren(type) + .get(Integer.parseInt(indexes[i])); + } + viewer.setSelection(new StructuredSelection(topic), + true); + } + + } + } + + Point scrollPosition = editorStatus.getScrollPositions() + .size() > index + ? editorStatus.getScrollPositions().get(index) + : null; + if (scrollPosition != null) + viewer.scrollTo(scrollPosition); + } + } + + private boolean safeRun(final IProgressMonitor monitor, + final boolean promptError, final IRunnableWithProgress runnable) { + final boolean[] successful = new boolean[1]; + successful[0] = false; + SafeRunner.run(new SafeRunnable() { + + @Override + public void run() throws Exception { + if (monitor != null) { + runnable.run(monitor); + } else { + IWorkbenchSiteProgressService context = getSite() + .getService(IWorkbenchSiteProgressService.class); + Assert.isTrue(context != null); + context.run(true, true, runnable); + } + successful[0] = true; + } + + @Override + public void handleException(Throwable e) { + if (e instanceof InterruptedException) + // canceled, no error + return; + + if (e instanceof InvocationTargetException) { + Throwable cause = ((InvocationTargetException) e) + .getTargetException(); + if (cause != null) + e = cause; + } + + if (!promptError) { + // log only + Logger.log(e); + return; + } + + super.handleException(e); + } + }); + + return successful[0]; + } + + @Override + public boolean isSaveAsAllowed() { + return getWorkbook() != null; + } + + public int promptToSaveOnClose() { + //TODO +// if (workbookRef != null && workbookRef.canSave()) { +// NullProgressMonitor monitor = new NullProgressMonitor(); +// doSave(monitor); +// if (monitor.isCanceled()) +// return CANCEL; +// return NO; +// } + return DEFAULT; + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + if (event.getSource() == workbookRef) { + workbookRefPropertyChange(event); + } + } + + protected void workbookRefPropertyChange(PropertyChangeEvent event) { + if (IEditable.PROP_NAME.equals(event.getProperty()) + || IEditable.PROP_DESCRIPTION.equals(event.getProperty())) { + runInUI(new Runnable() { + + @Override + public void run() { + updateNames(); + } + }); + } else if (IEditable.PROP_DIRTY.equals(event.getProperty())) { + runInUI(new Runnable() { + + @Override + public void run() { + firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY); + } + }); + } else if (IEditable.PROP_MESSAGES.equals(event.getProperty())) { + runInUI(new Runnable() { + + @Override + public void run() { + updateMessages(true); + } + }); + } + + } + + private void runInUI(final Runnable runnable) { + final Control control = pageContainer; + if (control == null || control.isDisposed()) + return; + final Display display = control.getDisplay(); + if (display == null || display.isDisposed()) + return; + display.asyncExec(runnable); + } + + @Override + public void handleCommandStackEvent(CommandStackEvent event) { + // override to do nothing + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.editor.IMindMapPreviewGenerator# + * generateMindMapPreview(org.xmind.ui.mindmap.IWorkbookRef, + * java.io.OutputStream, org.xmind.ui.internal.editor.MindMapPreviewOptions) + */ + @Override + public Properties generateMindMapPreview(IWorkbookRef workbookRef, + final ISheet sheet, final OutputStream output, + MindMapPreviewOptions options) throws IOException { + Assert.isLegal(output != null); + + final Properties properties = new Properties(); + if (sheet == null + || MindMapUIPlugin.getDefault().getPreferenceStore() + .getBoolean(PrefConstants.PREVIEW_SKIPPED) + || skipNextPreviewImage) { + URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, + IMindMapImages.DEFAULT_THUMBNAIL); + if (url != null) { + InputStream input = url.openStream(); + try { + FileUtils.transfer(input, output, false); + } finally { + input.close(); + } + } + skipNextPreviewImage = false; + return properties; + } + + IEncryptable encryptable = workbookRef.getAdapter(IEncryptable.class); + if (encryptable != null && encryptable.hasPassword()) { + URL url = BundleUtility.find(MindMapUI.PLUGIN_ID, + IMindMapImages.ENCRYPTED_THUMBNAIL); + if (url != null) { + InputStream input = url.openStream(); + try { + FileUtils.transfer(input, output, false); + } finally { + input.close(); + } + } + return properties; + } + + Shell parentShell = getSite().getShell(); + final Display display = parentShell.getDisplay(); + final MindMapImageExporter exporter = new MindMapImageExporter(display); + final Exception[] error = new Exception[1]; + display.syncExec(new Runnable() { + + public void run() { + IGraphicalEditorPage page = findPage(sheet); + if (page == null) { + page = getActivePageInstance(); + if (page == null) + throw new IllegalArgumentException(); + } +// if (page != null) { + IGraphicalViewer sourceViewer = page.getViewer(); + MindMapViewerExportSourceProvider sourceProvider = new MindMapViewerExportSourceProvider( + sourceViewer, DEFAULT_EXPORT_MARGIN); + org.eclipse.draw2d.geometry.Rectangle sourceArea = sourceProvider + .getSourceArea(); + + int resizeWidth = Math + .max((sourceArea.width % 21 == 0) ? sourceArea.width + : (sourceArea.width + 21 + - sourceArea.width % 21), + (sourceArea.height % 13 == 0) + ? sourceArea.height * 21 / 13 + : (sourceArea.height + 13 + - sourceArea.height % 13) * 21 + / 13); + if (resizeWidth < MINIMUM_PREVIEW_WIDTH) { + resizeWidth = MINIMUM_PREVIEW_WIDTH; + } else if (resizeWidth > MAXIMUM_PREVIEW_WIDTH) { + resizeWidth = MAXIMUM_PREVIEW_WIDTH; + } + int resizeHeight = resizeWidth * 13 / 21; + exporter.setSourceProvider(sourceProvider); + exporter.setResize(ResizeConstants.RESIZE_STRETCH, resizeWidth, + resizeHeight); + exporter.setTargetStream(output); + + try { + exporter.export(); + } catch (SWTException e) { + error[0] = e; + return; + } + + org.eclipse.draw2d.geometry.Point origin = exporter + .calcRelativeOrigin(); + + properties.put(PREVIEW_ORIGIN_X, String.valueOf(origin.x)); + properties.put(PREVIEW_ORIGIN_Y, String.valueOf(origin.y)); + properties.put(PREVIEW_BACKGROUND, + exporter.getBackgroundColor()); + } + }); + + if (error[0] != null) { + throw new IOException(error[0]); + } + + return properties; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.wizards.ISaveContext#getContextVariable(java.lang.Class) + */ + @Override + public T getContextVariable(Class key) { + return getSite().getService(key); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.wizards.ISaveContext#getContextVariable(java.lang.String) + */ + @Override + public Object getContextVariable(String key) { + IEvaluationService service = getSite() + .getService(IEvaluationService.class); + Assert.isNotNull(service); + Object variable = service.getCurrentState().getVariable(key); + return variable == IEvaluationContext.UNDEFINED_VARIABLE ? null + : variable; + } + + private void activateFileNotifier() { + getEditorSite().getWorkbenchWindow().getWorkbench() + .addWindowListener(getWindowListener()); + getEditorSite().getPage().addSelectionListener(getEditorSite().getId(), + getSelectionListener()); + } + + private void deactivateFileNotifier() { + getEditorSite().getWorkbenchWindow().getWorkbench() + .removeWindowListener(getWindowListener()); + getEditorSite().getPage().removeSelectionListener( + getEditorSite().getId(), getSelectionListener()); + } + + private IWindowListener getWindowListener() { + if (windowListener == null) { + windowListener = new IWindowListener() { + + @Override + public void windowOpened(IWorkbenchWindow window) { + } + + @Override + public void windowDeactivated(IWorkbenchWindow window) { + } + + @Override + public void windowClosed(IWorkbenchWindow window) { + } + + @Override + public void windowActivated(IWorkbenchWindow window) { + IEditorPart activeEditor = getEditorSite().getPage() + .getActiveEditor(); + if (activeEditor == MindMapEditor.this) { + if (workbookRef != null) { + workbookRef.activateNotifier(); + } + } + } + }; + } + return windowListener; + } + + private ISelectionListener getSelectionListener() { + if (selectionListener == null) { + selectionListener = new ISelectionListener() { + + @Override + public void selectionChanged(IWorkbenchPart part, + ISelection selection) { + if (workbookRef != null) { + workbookRef.activateNotifier(); + } + } + }; + } + return selectionListener; + } + + @Override + public void fileChanged(final String title, final String message, + final String[] buttons) { + if (workbookRef.getState() != IWorkbookRef.NORMAL) { + return; + } + + if (ignoreFileChanged) { + return; + } + + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + deactivateFileNotifier(); + getEditorSite().getPage().activate(MindMapEditor.this); + if (!isDirty()) { + reload(); + } else { + MessageDialog dialog = new MessageDialog(null, title, null, + NLS.bind( + MindMapMessages.MindMapEditor_fileChangedDialog_message_prefix + + message, + workbookRef.getName()), + MessageDialog.CONFIRM, buttons, 0); + + int code = dialog.open(); + if (code == 0) { + reload(); + } else if (code == 1 || code == -1) { + ignoreFileChanged = true; + } + } + + activateFileNotifier(); + } + }); + } + + @Override + public void fileRemoved(final String title, final String message, + final String[] buttons, boolean forceQuit) { + if (workbookRef.getState() != IWorkbookRef.NORMAL) { + return; + } + + if (forceQuit) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + closeEditor(); + } + }); + return; + } + + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + deactivateFileNotifier(); + getEditorSite().getPage().activate(MindMapEditor.this); + if (!isDirty()) { + closeEditor(); + } else { + MessageDialog dialog = new MessageDialog(null, title, null, + NLS.bind( + MindMapMessages.MindMapEditor_fileRemovedDialog_message_prefix + + message, + workbookRef.getName()), + MessageDialog.CONFIRM, buttons, 0); + + int code = dialog.open(); + if (code == 0) { + doSaveAs(); + } else if (code == 1 || code == -1) { + closeEditor(); + } + + activateFileNotifier(); + } + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInput.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInput.java index 8ec5bffe9..584fac438 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInput.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInput.java @@ -1,159 +1,165 @@ -package org.xmind.ui.internal.editor; - -import java.net.URI; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IPersistableElement; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.MindMapUI; - -public class MindMapEditorInput implements IEditorInput, IPersistableElement { - - private URI uri; - - private IWorkbookRef workbookRef; - - public MindMapEditorInput(URI uri) { - this(uri, null); - Assert.isNotNull(uri); - } - - public MindMapEditorInput(IWorkbookRef workbookRef) { - this(null, workbookRef); - Assert.isNotNull(workbookRef); - } - - private MindMapEditorInput(URI uri, IWorkbookRef workbookRef) { - this.uri = uri; - this.workbookRef = workbookRef; - } - - public IWorkbookRef getWorkbookRef() { - if (workbookRef == null) { - workbookRef = MindMapUIPlugin.getDefault().getWorkbookRefFactory() - .createWorkbookRef(uri, null); - } - return this.workbookRef; - } - - public URI getURI() { - if (uri != null) - return uri; - if (workbookRef != null) - return workbookRef.getURI(); - throw new IllegalStateException("URI and workbookRef are both null"); //$NON-NLS-1$ - } - - public T getAdapter(Class adapter) { - if (URI.class.equals(adapter)) { - return adapter.cast(getURI()); - } else if (IWorkbookRef.class.equals(adapter)) { - return adapter.cast(getWorkbookRef()); - } else if (IWorkbook.class.equals(adapter)) { - IWorkbookRef workbookRef = getWorkbookRef(); - if (workbookRef != null) { - return adapter.cast(workbookRef.getWorkbook()); - } - } - return null; - } - - public boolean exists() { - IWorkbookRef wr = getWorkbookRef(); - if (wr != null) - return wr.exists(); - return false; - } - - public ImageDescriptor getImageDescriptor() { - return MindMapUI.getImages().get(IMindMapImages.XMIND_FILE_ICON); - } - - public String getName() { - IWorkbookRef wr = getWorkbookRef(); - if (wr != null) { - String workbookName = wr.getName(); - if (workbookName == null) - return MindMapMessages.MindMapEditorInput_Workbook_Untitled_title; - return workbookName; - } - - URI uri = getURI(); - if (uri != null) { - String path = uri.getPath(); - if (path != null && path.length() > 0) { - if (path.charAt(path.length() - 1) == '/') { - path = path.substring(0, path.length() - 1); - } - int sep = path.lastIndexOf('/'); - if (sep >= 0) { - return path.substring(sep + 1); - } - } - return path; - } - - return ""; //$NON-NLS-1$ - } - - public IPersistableElement getPersistable() { - IWorkbookRef wr = getWorkbookRef(); - if (wr == null) - return null; - return this; - } - - public String getFactoryId() { - return MindMapEditorInputFactory.ID; - } - - public void saveState(IMemento memento) { - MindMapEditorInputFactory.saveState(this, memento); - } - - public String getToolTipText() { - IWorkbookRef wr = getWorkbookRef(); - if (wr != null) - return wr.getDescription(); - URI uri = getURI(); - if (uri != null) - return uri.toString(); - return ""; //$NON-NLS-1$ - } - - @Override - public int hashCode() { - IWorkbookRef wr = getWorkbookRef(); - if (wr != null) - return wr.hashCode(); - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof MindMapEditorInput)) - return false; - MindMapEditorInput that = (MindMapEditorInput) obj; - IWorkbookRef thisWR = this.getWorkbookRef(); - IWorkbookRef thatWR = that.getWorkbookRef(); - return thisWR == thatWR || (thisWR != null && thisWR.equals(thatWR)); - } - - @Override - public String toString() { - IWorkbookRef wr = getWorkbookRef(); - if (wr != null) - return wr.toString(); - return super.toString(); - } - -} +package org.xmind.ui.internal.editor; + +import java.net.URI; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; +import org.xmind.core.IWorkbook; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; + +public class MindMapEditorInput implements IEditorInput, IPersistableElement { + + private URI uri; + + private IWorkbookRef workbookRef; + + public MindMapEditorInput(URI uri) { + this(uri, MindMapUIPlugin.getDefault().getWorkbookRefFactory() + .createWorkbookRef(uri, null)); + Assert.isNotNull(uri); + } + + public MindMapEditorInput(IWorkbookRef workbookRef) { + this(workbookRef.getURI(), workbookRef); + Assert.isNotNull(workbookRef); + } + + private MindMapEditorInput(URI uri, IWorkbookRef workbookRef) { + this.uri = uri; + this.workbookRef = workbookRef; + } + + public IWorkbookRef getWorkbookRef() { + return this.workbookRef; + } + + public URI getURI() { + if (uri != null) + return uri; + if (workbookRef != null) + return workbookRef.getURI(); + throw new IllegalStateException("URI and workbookRef are both null"); //$NON-NLS-1$ + } + + public void dispose() { + workbookRef = null; + } + + public T getAdapter(Class adapter) { + if (URI.class.equals(adapter)) { + return adapter.cast(getURI()); + } else if (IWorkbookRef.class.equals(adapter)) { + return adapter.cast(getWorkbookRef()); + } else if (IWorkbook.class.equals(adapter)) { + IWorkbookRef workbookRef = getWorkbookRef(); + if (workbookRef != null) { + return adapter.cast(workbookRef.getWorkbook()); + } + } + return null; + } + + public boolean exists() { + IWorkbookRef wr = getWorkbookRef(); + if (wr != null) + return wr.exists(); + return false; + } + + public ImageDescriptor getImageDescriptor() { + return MindMapUI.getImages().get(IMindMapImages.XMIND_FILE_ICON); + } + + public String getName() { + IWorkbookRef wr = getWorkbookRef(); + if (wr != null) { + String workbookName = wr.getName(); + if (workbookName == null) + return MindMapMessages.MindMapEditorInput_Workbook_Untitled_title; + return workbookName; + } + + URI uri = getURI(); + if (uri != null) { + String path = uri.getPath(); + if (path != null && path.length() > 0) { + if (path.charAt(path.length() - 1) == '/') { + path = path.substring(0, path.length() - 1); + } + int sep = path.lastIndexOf('/'); + if (sep >= 0) { + return path.substring(sep + 1); + } + } + return path; + } + + return ""; //$NON-NLS-1$ + } + + public IPersistableElement getPersistable() { + IWorkbookRef wr = getWorkbookRef(); + if (wr == null) + return null; + return this; + } + + public String getFactoryId() { + return MindMapEditorInputFactory.ID; + } + + public void saveState(IMemento memento) { + MindMapEditorInputFactory.saveState(this, memento); + } + + public String getToolTipText() { + IWorkbookRef wr = getWorkbookRef(); + if (wr != null) + return wr.getDescription(); + URI uri = getURI(); + if (uri != null) + return uri.toString(); + return ""; //$NON-NLS-1$ + } + + @Override + public int hashCode() { + IWorkbookRef wr = getWorkbookRef(); + if (wr != null) + return wr.hashCode(); + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof MindMapEditorInput)) + return false; + MindMapEditorInput that = (MindMapEditorInput) obj; + IWorkbookRef thisWR = this.workbookRef; + IWorkbookRef thatWR = that.workbookRef; + URI thisURI = this.uri; + URI thatURI = that.uri; + return (thisURI == thatURI + || (thisURI != null && thisURI.equals(thatURI))) + && (thisWR == thatWR + || (thisWR != null && thisWR.equals(thatWR))); + } + + @Override + public String toString() { + IWorkbookRef wr = getWorkbookRef(); + if (wr != null) + return wr.toString(); + return super.toString(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInputFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInputFactory.java index 89d5c939b..4879848d4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInputFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorInputFactory.java @@ -1,66 +1,66 @@ -package org.xmind.ui.internal.editor; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.IElementFactory; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IPersistable; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.IWorkbookRef; - -public class MindMapEditorInputFactory implements IElementFactory { - - public static final String ID = "org.xmind.ui.MindMapEditorInputFactory"; //$NON-NLS-1$ - - private static final String TAG_URI = "uri"; //$NON-NLS-1$ - private static final String TAG_STATE = "state"; //$NON-NLS-1$ - - public IAdaptable createElement(IMemento memento) { - String uriString = memento.getString(TAG_URI); - if (uriString == null) - return null; - - URI uri; - try { - uri = new URI(uriString); - } catch (URISyntaxException e) { - MindMapUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, "Invalid URI: " + uriString, e)); //$NON-NLS-1$ - return null; - } - - IMemento state = memento.getChild(TAG_STATE); - if (state != null) { - IWorkbookRef workbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory().createWorkbookRef(uri, state); - if (workbookRef != null) { - return new MindMapEditorInput(workbookRef); - } - } - return new MindMapEditorInput(uri); - } - - public static void saveState(MindMapEditorInput input, IMemento memento) { - URI uri = input.getURI(); - if (uri == null) - return; - - String uriString = uri.toString(); - memento.putString(TAG_URI, uriString); - - IWorkbookRef workbookRef = input.getWorkbookRef(); - if (workbookRef != null) { - IPersistable persistable = MindMapUIPlugin.getAdapter(workbookRef, - IPersistable.class); - if (persistable != null) { - IMemento state = memento.createChild(TAG_STATE); - persistable.saveState(state); - } - } - } - -} +package org.xmind.ui.internal.editor; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistable; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class MindMapEditorInputFactory implements IElementFactory { + + public static final String ID = "org.xmind.ui.MindMapEditorInputFactory"; //$NON-NLS-1$ + + private static final String TAG_URI = "uri"; //$NON-NLS-1$ + private static final String TAG_STATE = "state"; //$NON-NLS-1$ + + public IAdaptable createElement(IMemento memento) { + String uriString = memento.getString(TAG_URI); + if (uriString == null) + return null; + + URI uri; + try { + uri = new URI(uriString); + } catch (URISyntaxException e) { + MindMapUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, "Invalid URI: " + uriString, e)); //$NON-NLS-1$ + return null; + } + + IMemento state = memento.getChild(TAG_STATE); + if (state != null) { + IWorkbookRef workbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory().createWorkbookRef(uri, state); + if (workbookRef != null) { + return new MindMapEditorInput(workbookRef); + } + } + return new MindMapEditorInput(uri); + } + + public static void saveState(MindMapEditorInput input, IMemento memento) { + URI uri = input.getURI(); + if (uri == null) + return; + + String uriString = uri.toString(); + memento.putString(TAG_URI, uriString); + + IWorkbookRef workbookRef = input.getWorkbookRef(); + if (workbookRef != null) { + IPersistable persistable = MindMapUIPlugin.getAdapter(workbookRef, + IPersistable.class); + if (persistable != null) { + IMemento state = memento.createChild(TAG_STATE); + persistable.saveState(state); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPage.java index 50f0aff0e..a52a1bc54 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPage.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPage.java @@ -1,748 +1,743 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.draw2d.Layer; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.Core; -import org.xmind.core.ISheet; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegister; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.ISelectionStack; -import org.xmind.gef.SelectionStack; -import org.xmind.gef.draw2d.IRelayeredPane; -import org.xmind.gef.draw2d.ISkylightLayer; -import org.xmind.gef.part.IPart; -import org.xmind.gef.service.CenterPreservationService; -import org.xmind.gef.service.FeedbackService; -import org.xmind.gef.service.IAnimationService; -import org.xmind.gef.service.IFeedbackService; -import org.xmind.gef.service.IImageRegistryService; -import org.xmind.gef.service.IRevealService; -import org.xmind.gef.service.IShadowService; -import org.xmind.gef.service.ImageRegistryService; -import org.xmind.gef.service.ShadowService; -import org.xmind.gef.tool.MoveTool; -import org.xmind.gef.ui.actions.ActionRegistry; -import org.xmind.gef.ui.actions.CopyAction; -import org.xmind.gef.ui.actions.IActionRegistry; -import org.xmind.gef.ui.actions.PasteAction; -import org.xmind.gef.ui.actions.RequestAction; -import org.xmind.gef.ui.actions.SelectAllAction; -import org.xmind.gef.ui.editor.GraphicalEditorPage; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.util.Properties; -import org.xmind.ui.actions.MindMapActionFactory; -import org.xmind.ui.animation.AnimationService; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.TopicContextService; -import org.xmind.ui.internal.actions.ActionConstants; -import org.xmind.ui.internal.actions.ActualSizeAction; -import org.xmind.ui.internal.actions.AlignmentRequestAction; -import org.xmind.ui.internal.actions.CancelHyperlinkAction; -import org.xmind.ui.internal.actions.CollapseAction; -import org.xmind.ui.internal.actions.CollapseAllAction; -import org.xmind.ui.internal.actions.CreateRelationshipAction; -import org.xmind.ui.internal.actions.CreateSheetFromTopicAction; -import org.xmind.ui.internal.actions.CutAction; -import org.xmind.ui.internal.actions.DeleteAction; -import org.xmind.ui.internal.actions.DrillDownAction; -import org.xmind.ui.internal.actions.DrillUpAction; -import org.xmind.ui.internal.actions.DuplicateAction; -import org.xmind.ui.internal.actions.EditCommentsAction; -import org.xmind.ui.internal.actions.EditLabelAction; -import org.xmind.ui.internal.actions.EditNotesAction; -import org.xmind.ui.internal.actions.EditTitleAction; -import org.xmind.ui.internal.actions.ExtendAction; -import org.xmind.ui.internal.actions.ExtendAllAction; -import org.xmind.ui.internal.actions.FinishAction; -import org.xmind.ui.internal.actions.FitMapAction; -import org.xmind.ui.internal.actions.FitSelectionAction; -import org.xmind.ui.internal.actions.InsertAttachmentAction; -import org.xmind.ui.internal.actions.InsertFloatingTopicAction; -import org.xmind.ui.internal.actions.InsertImageAction; -import org.xmind.ui.internal.actions.InsertParentTopicAction; -import org.xmind.ui.internal.actions.InsertSubtopicAction; -import org.xmind.ui.internal.actions.InsertTopicAction; -import org.xmind.ui.internal.actions.InsertTopicBeforeAction; -import org.xmind.ui.internal.actions.ModifyHyperlinkAction; -import org.xmind.ui.internal.actions.OpenHyperlinkAction; -import org.xmind.ui.internal.actions.RemoveAllStylesAction; -import org.xmind.ui.internal.actions.ResetPositionAction; -import org.xmind.ui.internal.actions.SelectBrothersAction; -import org.xmind.ui.internal.actions.SelectChildrenAction; -import org.xmind.ui.internal.actions.SortRequestAction; -import org.xmind.ui.internal.actions.TileAction; -import org.xmind.ui.internal.actions.TraverseAction; -import org.xmind.ui.internal.actions.ZoomInAction; -import org.xmind.ui.internal.actions.ZoomOutAction; -import org.xmind.ui.internal.layers.SkylightLayer; -import org.xmind.ui.internal.mindmap.DrillDownTraceService; -import org.xmind.ui.internal.mindmap.HighlightService; -import org.xmind.ui.internal.mindmap.InfoItemIconPart; -import org.xmind.ui.internal.mindmap.MindMapRevealService; -import org.xmind.ui.internal.mindmap.MindMapTopicContextService; -import org.xmind.ui.internal.mindmap.MindMapViewer; -import org.xmind.ui.internal.mindmap.UndoRedoTipsService; -import org.xmind.ui.internal.print.multipage.PrintMapAction2; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IDrillDownTraceService; -import org.xmind.ui.mindmap.IHighlightService; -import org.xmind.ui.mindmap.IIconTipPart; -import org.xmind.ui.mindmap.IInfoItemPart; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.MindMap; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.util.MindMapUtils; - -@SuppressWarnings("deprecation") -public class MindMapEditorPage extends GraphicalEditorPage - implements ICoreEventListener, IColorProvider, IPropertyChangeListener { - - private ISelectionStack selectionStack = null; - - private ICoreEventRegister eventRegister = null; - - private IPreferenceStore prefStore = null; - - private IShadowService shadowService = null; - - private UndoRedoTipsService undoService = null; - - private IMESupport imeSupport = null; - - public void init(IGraphicalEditor parent, Object input) { - super.init(parent, input); - setPanelContributor(new MindMapEditorPagePanelContributor()); - } - - protected IGraphicalViewer createViewer() { - return new MindMapViewer(); - } - - protected void createViewerControl(final IGraphicalViewer viewer, - Composite parent) { - Control control = ((MindMapViewer) viewer).createControl(parent); - imeSupport = new IMESupport(this, viewer); - - control.addFocusListener(new FocusListener() { - - public void focusLost(FocusEvent e) { - ((MindMapEditor) getParentEditor()) - .changeContext((String) null); - } - - public void focusGained(FocusEvent e) { - ((MindMapEditor) getParentEditor()) - .changeContext(getEditDomain().getActiveTool()); - } - }); - } - - protected void createContentPopupMenu(final Control control) { - super.createContentPopupMenu(control); - - control.addListener(SWT.MenuDetect, new Listener() { - - private Menu oldPopupMenu; - private boolean defaultMenuVisible = true; - private Menu defaultMenu; - - public void handleEvent(Event event) { - Menu menu = control.getMenu(); - - if (menu != null && defaultMenuVisible) - defaultMenu = menu; - - org.eclipse.swt.graphics.Point pos = control.toControl(event.x, - event.y); - IPart part = findIconTipAt(pos.x, pos.y); - - if (part != null) { - - if (oldPopupMenu != null) { - oldPopupMenu.dispose(); - oldPopupMenu = null; - } - - IMenuManager mm = null; - if (part instanceof IIconTipPart) { - mm = ((IIconTipPart) part).getPopupMenu(); - } else { - if (part instanceof IInfoItemPart) - mm = ((IInfoItemPart) part).getPopupMenu(); - } - - if (mm != null) { - Menu newPopupMenu = ((MenuManager) mm) - .createContextMenu(control); - oldPopupMenu = newPopupMenu; - control.setMenu(newPopupMenu); - defaultMenuVisible = false; - } else { - if (defaultMenu != null) - control.setMenu(defaultMenu); - } - return; - } - if (defaultMenu != null) { - control.setMenu(defaultMenu); - } - - } - - private IPart findIconTipAt(int x, int y) { - IPart part = getViewer().findPart(x, y); - if (part instanceof IIconTipPart - || part instanceof InfoItemIconPart) { - } else { - part = null; - } - return (IPart) part; - } - }); - } - - public void updatePageTitle() { - ISheet sheet = getCastedInput(); - String name = sheet.hasTitle() ? sheet.getTitleText() - : sheet.getRootTopic().getTitleText(); - setPageTitle(MindMapUtils.trimSingleLine(name)); - } - - protected void installModelListeners(Object input) { - super.installModelListeners(input); - eventRegister = new CoreEventRegister(input, this); - eventRegister.register(Core.TitleText); - prefStore = MindMapUIPlugin.getDefault().getPreferenceStore(); - if (prefStore != null) { - prefStore.addPropertyChangeListener(this); - } - } - - protected void uninstallModelListeners(Object input) { - if (prefStore != null) { - prefStore.removePropertyChangeListener(this); - prefStore = null; - } - if (eventRegister != null) { - eventRegister.unregisterAll(); - eventRegister = null; - } - super.uninstallModelListeners(input); - } - - public void propertyChange(PropertyChangeEvent event) { - if (PrefConstants.MANUAL_LAYOUT_ALLOWED.equals(event.getProperty())) { - MoveTool moveTool = (MoveTool) getViewer().getEditDomain() - .getTool(MindMapUI.TOOL_MOVE_TOPIC); - if (null != moveTool) { - IPreferenceStore prefStore = MindMapUIPlugin.getDefault() - .getPreferenceStore(); - boolean status = prefStore - .getBoolean(PrefConstants.MANUAL_LAYOUT_ALLOWED); - moveTool.getStatus().setStatus(GEF.ST_FREE_MOVE_MODE, status); - } - } else if (PrefConstants.OVERLAPS_ALLOWED.equals(event.getProperty())) { - ISheetPart sheet = ((IMindMapViewer) getViewer()).getSheetPart(); - if (sheet != null) { - sheet.getFigure().revalidate(); - } - } else if (PrefConstants.SHADOW_ENABLED.equals(event.getProperty())) { - if (shadowService != null) { - Object value = event.getNewValue(); - if (value instanceof String) - value = Boolean.parseBoolean((String) value); - if (value instanceof Boolean) - shadowService.setActive((Boolean) value); - else - shadowService.setActive(false); - } - } else if (PrefConstants.GRADIENT_COLOR.equals(event.getProperty())) { - IBranchPart part = ((IMindMapViewer) getViewer()) - .getCentralBranchPart(); - if (part != null) { - part.treeUpdate(false); - } - } else if (PrefConstants.UNDO_REDO_TIPS_ENABLED - .equals(event.getProperty())) { - if (undoService != null) { - Object value = event.getNewValue(); - if (value instanceof String) - value = Boolean.parseBoolean((String) value); - if (value instanceof Boolean) - undoService.setActive((Boolean) value); - else - undoService.setActive(false); - } - } else if (PrefConstants.UNDO_REDO_TIPS_FADE_DELAY - .equals(event.getProperty())) { - if (undoService != null) { - Object value = event.getNewValue(); - if (value instanceof String) { - value = Integer.parseInt((String) value); - } - if (value instanceof Integer) { - undoService.setDuration(((Integer) value).intValue()); - } else { - undoService - .setDuration(UndoRedoTipsService.DEFAULT_DURATION); - } - } - } - } - - public ISheet getCastedInput() { - return (ISheet) super.getInput(); - } - - protected Object createViewerInput() { - return new MindMap(getCastedInput()); - } - - protected void initViewer(IGraphicalViewer viewer) { - super.initViewer(viewer); - viewer.getZoomManager().setConstraints(MindMapUI.ZOOM_MIN / 100.0d, - MindMapUI.ZOOM_MAX / 100.0d); - - Properties properties = viewer.getProperties(); - properties.set(IMindMapViewer.VIEWER_CENTERED, Boolean.TRUE); - properties.set(IMindMapViewer.VIEWER_CORNERED, Boolean.TRUE); - properties.set(IMindMapViewer.VIEWER_ACTIONS, - new ActionRegistry(getActionRegistry())); - properties.set(IMindMapViewer.VIEWER_MARGIN, - Integer.valueOf(MindMapUI.SHEET_MARGIN)); - - initViewerServices((MindMapViewer) viewer); - } - - protected void configureViewer(IGraphicalViewer viewer) { - super.configureViewer(viewer); - if (selectionStack == null) - selectionStack = createSelectionStack(); - selectionStack.setSelectionProvider(getViewer()); - selectionStack.setCommandStack(getEditDomain().getCommandStack()); - } - - protected ISelectionStack createSelectionStack() { - return new SelectionStack(); - } - - protected void initViewerServices(MindMapViewer viewer) { - CenterPreservationService centerPresercationService = new CenterPreservationService( - viewer); - viewer.installService(CenterPreservationService.class, - centerPresercationService); - centerPresercationService.setActive(true); - - IImageRegistryService imageCacheService = new ImageRegistryService( - viewer); - viewer.installService(IImageRegistryService.class, imageCacheService); - imageCacheService.setActive(true); - - IRevealService revealService = new MindMapRevealService(viewer); - viewer.installService(IRevealService.class, revealService); - revealService.setActive(true); - - IAnimationService animationService = new AnimationService(viewer); - animationService.setPlaybackProvider(MindMapUI.getPlaybackProvider()); - viewer.installService(IAnimationService.class, animationService); - animationService.setActive(true); - - Layer coverLayer = viewer.getLayer(MindMapUI.LAYER_COVER); - Layer skylightLayer = viewer.getLayer(MindMapUI.LAYER_SKYLIGHT); - if (coverLayer instanceof IRelayeredPane - || skylightLayer instanceof ISkylightLayer) { - IHighlightService highlightService = new HighlightService(viewer, - false); - if (coverLayer instanceof IRelayeredPane) - highlightService.setRelayeredPane((IRelayeredPane) coverLayer); - if (skylightLayer instanceof ISkylightLayer) - highlightService - .setHighlightLayer((SkylightLayer) skylightLayer); - viewer.installService(IHighlightService.class, highlightService); - highlightService.setActive(true); - } - - Layer feedbackLayer = viewer.getLayer(GEF.LAYER_FEEDBACK); - if (feedbackLayer != null) { - FeedbackService feedbackService = new FeedbackService(viewer); - viewer.installService(IFeedbackService.class, feedbackService); - feedbackService.setLayer(feedbackLayer); - feedbackService.setSelectionColorProvider(this); - feedbackService - .setSelectionLineWidth(MindMapUI.SELECTION_LINE_WIDTH); - feedbackService - .setSelectionCorner(MindMapUI.SELECTION_ROUNDED_CORNER); - feedbackService.setActive(true); - } - - IDrillDownTraceService traceService = new DrillDownTraceService(viewer); - viewer.installService(IDrillDownTraceService.class, traceService); - traceService.setActive(true); - IAction action = getActionRegistry() - .getAction(MindMapActionFactory.DRILL_UP.getId()); - if (action instanceof DrillUpAction) { - ((DrillUpAction) action).setTraceService(traceService); - } - - Layer shadowLayer = viewer.getLayer(GEF.LAYER_SHADOW); - if (shadowLayer != null) { - shadowService = new ShadowService(viewer); - viewer.installService(IShadowService.class, shadowService); - shadowService.setLayer(shadowLayer); - shadowService.setActive(prefStore != null - && prefStore.getBoolean(PrefConstants.SHADOW_ENABLED)); - } - - Layer undoLayer = viewer.getLayer(MindMapUI.LAYER_UNDO); - if (undoLayer != null) { - undoService = new UndoRedoTipsService(viewer); - viewer.installService(UndoRedoTipsService.class, undoService); - undoService.setLayer(undoLayer); - undoService.setActive(true); - } - - MindMapTopicContextService contextService = new MindMapTopicContextService( - this, viewer); - viewer.installService(TopicContextService.class, contextService); - contextService.setActive(true); - } - - public void setActive(boolean active) { - boolean oldActive = isActive(); - super.setActive(active); - boolean newActive = isActive(); - if (oldActive && !newActive) { - if (getEditDomain() != null) { - getEditDomain().handleRequest(GEF.REQ_CANCEL, getViewer()); - } - } - } - - protected void initPageActions(IActionRegistry actionRegistry) { - super.initPageActions(actionRegistry); - - InsertTopicAction insertTopicAction = new InsertTopicAction(this); - actionRegistry.addAction(insertTopicAction); - addSelectionAction(insertTopicAction); - - InsertSubtopicAction insertSubtopicAction = new InsertSubtopicAction( - this); - actionRegistry.addAction(insertSubtopicAction); - addSelectionAction(insertSubtopicAction); - - InsertTopicBeforeAction insertTopicBeforeAction = new InsertTopicBeforeAction( - this); - actionRegistry.addAction(insertTopicBeforeAction); - addSelectionAction(insertTopicBeforeAction); - - InsertParentTopicAction insertParentTopicAction = new InsertParentTopicAction( - this); - actionRegistry.addAction(insertParentTopicAction); - addSelectionAction(insertParentTopicAction); - - CreateSheetFromTopicAction insertSheetAction = new CreateSheetFromTopicAction( - this); - actionRegistry.addAction(insertSheetAction); - addSelectionAction(insertSheetAction); - - ExtendAction extendAction = new ExtendAction(this); - actionRegistry.addAction(extendAction); - addSelectionAction(extendAction); - - CollapseAction collapseAction = new CollapseAction(this); - actionRegistry.addAction(collapseAction); - addSelectionAction(collapseAction); - - ExtendAllAction extendAllAction = new ExtendAllAction(this); - actionRegistry.addAction(extendAllAction); - addSelectionAction(extendAllAction); - - CollapseAllAction collapseAllAction = new CollapseAllAction(this); - actionRegistry.addAction(collapseAllAction); - addSelectionAction(collapseAllAction); - - ModifyHyperlinkAction modifyHyperlinkAction = new ModifyHyperlinkAction( - this); - actionRegistry.addAction(modifyHyperlinkAction); - addSelectionAction(modifyHyperlinkAction); - - OpenHyperlinkAction openHyperlinkAction = new OpenHyperlinkAction(this); - actionRegistry.addAction(openHyperlinkAction); - addSelectionAction(openHyperlinkAction); - - InsertAttachmentAction insertAttachmentAction = new InsertAttachmentAction( - this); - actionRegistry.addAction(insertAttachmentAction); - addSelectionAction(insertAttachmentAction); - - InsertImageAction insertImageAction = new InsertImageAction(this); - actionRegistry.addAction(insertImageAction); - addSelectionAction(insertImageAction); - - DeleteAction deleteAction = new DeleteAction(this); - actionRegistry.addAction(deleteAction); - addSelectionAction(deleteAction); - - CreateRelationshipAction createRelationshipAction = new CreateRelationshipAction( - this); - actionRegistry.addAction(createRelationshipAction); - - CopyAction copyAction = new CopyAction(this); - actionRegistry.addAction(copyAction); - - CutAction cutAction = new CutAction(this); - actionRegistry.addAction(cutAction); - addSelectionAction(cutAction); - - PasteAction pasteAction = new PasteAction(this); - actionRegistry.addAction(pasteAction); - addSelectionAction(pasteAction); - - ZoomInAction zoomInAction = new ZoomInAction(this); - actionRegistry.addAction(zoomInAction); - - ZoomOutAction zoomOutAction = new ZoomOutAction(this); - actionRegistry.addAction(zoomOutAction); - - ActualSizeAction actualSizeAction = new ActualSizeAction(this); - actionRegistry.addAction(actualSizeAction); - - FitMapAction fitMapAction = new FitMapAction(this); - actionRegistry.addAction(fitMapAction); - - FitSelectionAction fitSelectionAction = new FitSelectionAction(this); - actionRegistry.addAction(fitSelectionAction); - - SelectAllAction selectAllAction = new SelectAllAction(this); - actionRegistry.addAction(selectAllAction); - - SelectBrothersAction selectBrothersAction = new SelectBrothersAction( - this); - actionRegistry.addAction(selectBrothersAction); - addSelectionAction(selectBrothersAction); - - SelectChildrenAction selectChildrenAction = new SelectChildrenAction( - this); - actionRegistry.addAction(selectChildrenAction); - addSelectionAction(selectChildrenAction); - - DrillDownAction drillDownAction = new DrillDownAction(this); - actionRegistry.addAction(drillDownAction); - addSelectionAction(drillDownAction); - - DrillUpAction drillUpAction = new DrillUpAction(this); - actionRegistry.addAction(drillUpAction); - -// CreateBoundaryAction createBoundaryAction = new CreateBoundaryAction( -// this); -// actionRegistry.addAction(createBoundaryAction); -// -// CreateSummaryAction createSummaryAction = new CreateSummaryAction(this); -// actionRegistry.addAction(createSummaryAction); - -// SortAsAlphaAction sortAsAlphaAction = new SortAsAlphaAction(this); -// actionRegistry.addAction(sortAsAlphaAction); -// addSelectionAction(sortAsAlphaAction); -// -// SortAsPriorityAction sortAsPriorityAction = new SortAsPriorityAction( -// this); -// actionRegistry.addAction(sortAsPriorityAction); -// addSelectionAction(sortAsPriorityAction); -// -// SortAsModifyDateAction sortAsModifyDateAction = new SortAsModifyDateAction( -// this); -// actionRegistry.addAction(sortAsModifyDateAction); -// addSelectionAction(sortAsModifyDateAction); - - EditTitleAction editTitleAction = new EditTitleAction(this); - actionRegistry.addAction(editTitleAction); - addSelectionAction(editTitleAction); - - EditLabelAction editLabelAction = new EditLabelAction(this); - actionRegistry.addAction(editLabelAction); - addSelectionAction(editLabelAction); - - EditNotesAction editNotesAction = new EditNotesAction(this); - actionRegistry.addAction(editNotesAction); - addSelectionAction(editNotesAction); - - EditCommentsAction editCommentsAction = new EditCommentsAction(this); - actionRegistry.addAction(editCommentsAction); - addSelectionAction(editCommentsAction); - - TraverseAction raverseAction = new TraverseAction(this); - actionRegistry.addAction(raverseAction); - addSelectionAction(raverseAction); - - DuplicateAction duplicateAction = new DuplicateAction(this); - actionRegistry.addAction(duplicateAction); - addSelectionAction(duplicateAction); - - FinishAction finishAction = new FinishAction( - MindMapActionFactory.FINISH.getId(), this); - actionRegistry.addAction(finishAction); - - TileAction tileAction = new TileAction(this); - actionRegistry.addAction(tileAction); - - ResetPositionAction resetPositionAction = new ResetPositionAction(this); - actionRegistry.addAction(resetPositionAction); - addSelectionAction(resetPositionAction); - - RemoveAllStylesAction removeAllStylesAction = new RemoveAllStylesAction( - this); - actionRegistry.addAction(removeAllStylesAction); - addSelectionAction(removeAllStylesAction); - - actionRegistry.addAction(new RequestAction( - MindMapActionFactory.MOVE_UP.getId(), this, GEF.REQ_MOVE_UP)); - actionRegistry.addAction( - new RequestAction(MindMapActionFactory.MOVE_DOWN.getId(), this, - GEF.REQ_MOVE_DOWN)); - actionRegistry.addAction( - new RequestAction(MindMapActionFactory.MOVE_LEFT.getId(), this, - GEF.REQ_MOVE_LEFT)); - actionRegistry.addAction( - new RequestAction(MindMapActionFactory.MOVE_RIGHT.getId(), this, - GEF.REQ_MOVE_RIGHT)); - actionRegistry.addAction( - new RequestAction(MindMapActionFactory.GO_HOME.getId(), this, - MindMapUI.REQ_SELECT_CENTRAL)); - actionRegistry.addAction(new InsertFloatingTopicAction( - MindMapActionFactory.INSERT_FLOATING_TOPIC.getId(), this)); - actionRegistry.addAction(new InsertFloatingTopicAction( - MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC.getId(), - this)); - - CancelHyperlinkAction cancelHyperlinkAction = new CancelHyperlinkAction( - this); - actionRegistry.addAction(cancelHyperlinkAction); - addSelectionAction(cancelHyperlinkAction); - -// NewSheetFromTemplateDialogAction newSheetFromTemplateAction = new NewSheetFromTemplateDialogAction( -// this); -// actionRegistry.addAction(newSheetFromTemplateAction); -// addSelectionAction(newSheetFromTemplateAction); - - addAlignmentAction(PositionConstants.LEFT, actionRegistry); - addAlignmentAction(PositionConstants.CENTER, actionRegistry); - addAlignmentAction(PositionConstants.RIGHT, actionRegistry); - addAlignmentAction(PositionConstants.TOP, actionRegistry); - addAlignmentAction(PositionConstants.MIDDLE, actionRegistry); - addAlignmentAction(PositionConstants.BOTTOM, actionRegistry); - addSortAction(ActionConstants.SORT_TITLE_ID, actionRegistry); - addSortAction(ActionConstants.SORT_PRIORITY_ID, actionRegistry); - addSortAction(ActionConstants.SORT_MODIFIED_ID, actionRegistry); - - PrintMapAction2 printMapAction = new PrintMapAction2(this); - actionRegistry.addAction(printMapAction); - } - - private void addAlignmentAction(int alignment, - IActionRegistry actionRegistry) { - AlignmentRequestAction action = new AlignmentRequestAction(this, - alignment); - actionRegistry.addAction(action); - addSelectionAction(action); - } - - private void addSortAction(String sortId, IActionRegistry actionRegistry) { - SortRequestAction action = new SortRequestAction(this, sortId); - actionRegistry.addAction(action); - addSelectionAction(action); - } - - public void dispose() { - if (imeSupport != null) { - imeSupport.dispose(); - imeSupport = null; - } - if (selectionStack != null) { - selectionStack.setCommandStack(null); - selectionStack.setSelectionProvider(null); - selectionStack = null; - } - super.dispose(); - } - - public Object getAdapter(Class adapter) { - if (adapter == ISheet.class) - return getCastedInput(); - if (adapter == IMindMap.class) - return getViewer().getInput(); - return super.getAdapter(adapter); - } - - public void handleCoreEvent(final CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - - public void run() { - String type = event.getType(); - if (Core.TitleText.equals(type)) { - updatePageTitle(); - } - } - }); - } - - public Color getBackground(Object element) { - if (IFeedbackService.PreselectionColor.equals(element) - || IFeedbackService.DisabledPreselectionColor.equals(element)) - return ColorUtils.getColor(MindMapUI.FILL_COLOR_PRESELECTION); - return null; - } - - public Color getForeground(Object element) { - if (IFeedbackService.FocusColor.equals(element)) - return ColorUtils.getColor(MindMapUI.LINE_COLOR_FOCUS); - if (IFeedbackService.SelectionColor.equals(element)) - return ColorUtils.getColor(MindMapUI.LINE_COLOR_SELECTION); - if (IFeedbackService.PreselectionColor.equals(element) - || IFeedbackService.DisabledPreselectionColor.equals(element)) - return ColorUtils.getColor(MindMapUI.LINE_COLOR_PRESELECTION); - if (IFeedbackService.DisabledFocusColor.equals(element)) - return ColorUtils.getColor(MindMapUI.LINE_COLOR_FOCUS_DISABLED); - if (IFeedbackService.DisabledSelectionColor.equals(element)) - return ColorUtils.getColor(MindMapUI.LINE_COLOR_SELECTION_DISABLED); - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegister; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ISelectionStack; +import org.xmind.gef.SelectionStack; +import org.xmind.gef.draw2d.IRelayeredPane; +import org.xmind.gef.draw2d.ISkylightLayer; +import org.xmind.gef.part.IPart; +import org.xmind.gef.service.CenterPreservationService; +import org.xmind.gef.service.FeedbackService; +import org.xmind.gef.service.IAnimationService; +import org.xmind.gef.service.IFeedbackService; +import org.xmind.gef.service.IImageRegistryService; +import org.xmind.gef.service.IRevealService; +import org.xmind.gef.service.IShadowService; +import org.xmind.gef.service.ImageRegistryService; +import org.xmind.gef.service.ShadowService; +import org.xmind.gef.tool.MoveTool; +import org.xmind.gef.ui.actions.ActionRegistry; +import org.xmind.gef.ui.actions.CopyAction; +import org.xmind.gef.ui.actions.IActionRegistry; +import org.xmind.gef.ui.actions.PasteAction; +import org.xmind.gef.ui.actions.RequestAction; +import org.xmind.gef.ui.actions.SelectAllAction; +import org.xmind.gef.ui.editor.GraphicalEditorPage; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.util.Properties; +import org.xmind.ui.actions.MindMapActionFactory; +import org.xmind.ui.animation.AnimationService; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.TopicContextService; +import org.xmind.ui.internal.actions.ActionConstants; +import org.xmind.ui.internal.actions.ActualSizeAction; +import org.xmind.ui.internal.actions.AlignmentRequestAction; +import org.xmind.ui.internal.actions.CancelHyperlinkAction; +import org.xmind.ui.internal.actions.CollapseAction; +import org.xmind.ui.internal.actions.CollapseAllAction; +import org.xmind.ui.internal.actions.CreateSheetFromTopicAction; +import org.xmind.ui.internal.actions.CutAction; +import org.xmind.ui.internal.actions.DeleteAction; +import org.xmind.ui.internal.actions.DrillDownAction; +import org.xmind.ui.internal.actions.DrillUpAction; +import org.xmind.ui.internal.actions.DuplicateAction; +import org.xmind.ui.internal.actions.EditCommentsAction; +import org.xmind.ui.internal.actions.EditLabelAction; +import org.xmind.ui.internal.actions.EditNotesAction; +import org.xmind.ui.internal.actions.EditTitleAction; +import org.xmind.ui.internal.actions.ExtendAction; +import org.xmind.ui.internal.actions.ExtendAllAction; +import org.xmind.ui.internal.actions.FinishAction; +import org.xmind.ui.internal.actions.FitMapAction; +import org.xmind.ui.internal.actions.FitSelectionAction; +import org.xmind.ui.internal.actions.InsertAttachmentAction; +import org.xmind.ui.internal.actions.InsertFloatingTopicAction; +import org.xmind.ui.internal.actions.InsertImageAction; +import org.xmind.ui.internal.actions.InsertParentTopicAction; +import org.xmind.ui.internal.actions.InsertSubtopicAction; +import org.xmind.ui.internal.actions.InsertTopicAction; +import org.xmind.ui.internal.actions.InsertTopicBeforeAction; +import org.xmind.ui.internal.actions.ModifyHyperlinkAction; +import org.xmind.ui.internal.actions.OpenHyperlinkAction; +import org.xmind.ui.internal.actions.RemoveAllStylesAction; +import org.xmind.ui.internal.actions.ResetPositionAction; +import org.xmind.ui.internal.actions.SelectBrothersAction; +import org.xmind.ui.internal.actions.SelectChildrenAction; +import org.xmind.ui.internal.actions.SortRequestAction; +import org.xmind.ui.internal.actions.TileAction; +import org.xmind.ui.internal.actions.TraverseAction; +import org.xmind.ui.internal.actions.ZoomInAction; +import org.xmind.ui.internal.actions.ZoomOutAction; +import org.xmind.ui.internal.layers.SkylightLayer; +import org.xmind.ui.internal.mindmap.DrillDownTraceService; +import org.xmind.ui.internal.mindmap.HighlightService; +import org.xmind.ui.internal.mindmap.InfoItemIconPart; +import org.xmind.ui.internal.mindmap.MindMapRevealService; +import org.xmind.ui.internal.mindmap.MindMapTopicContextService; +import org.xmind.ui.internal.mindmap.MindMapViewer; +import org.xmind.ui.internal.mindmap.UndoRedoTipsService; +import org.xmind.ui.internal.print.multipage.PrintMapAction2; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IDrillDownTraceService; +import org.xmind.ui.mindmap.IHighlightService; +import org.xmind.ui.mindmap.IIconTipPart; +import org.xmind.ui.mindmap.IInfoItemPart; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.MindMap; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.MindMapUtils; + +@SuppressWarnings("deprecation") +public class MindMapEditorPage extends GraphicalEditorPage + implements ICoreEventListener, IColorProvider, IPropertyChangeListener { + + private ISelectionStack selectionStack = null; + + private ICoreEventRegister eventRegister = null; + + private IPreferenceStore prefStore = null; + + private IShadowService shadowService = null; + + private UndoRedoTipsService undoService = null; + + private IMESupport imeSupport = null; + + public void init(IGraphicalEditor parent, Object input) { + super.init(parent, input); + setPanelContributor(new MindMapEditorPagePanelContributor()); + } + + protected IGraphicalViewer createViewer() { + return new MindMapViewer(); + } + + protected void createViewerControl(final IGraphicalViewer viewer, + Composite parent) { + Control control = ((MindMapViewer) viewer).createControl(parent); + imeSupport = new IMESupport(this, viewer); + + control.addFocusListener(new FocusListener() { + + public void focusLost(FocusEvent e) { + ((MindMapEditor) getParentEditor()) + .changeContext((String) null); + } + + public void focusGained(FocusEvent e) { + ((MindMapEditor) getParentEditor()) + .changeContext(getEditDomain().getActiveTool()); + } + }); + } + + protected void createContentPopupMenu(final Control control) { + super.createContentPopupMenu(control); + + control.addListener(SWT.MenuDetect, new Listener() { + + private Menu oldPopupMenu; + private boolean defaultMenuVisible = true; + private Menu defaultMenu; + + public void handleEvent(Event event) { + Menu menu = control.getMenu(); + + if (menu != null && defaultMenuVisible) + defaultMenu = menu; + + org.eclipse.swt.graphics.Point pos = control.toControl(event.x, + event.y); + IPart part = findIconTipAt(pos.x, pos.y); + + if (part != null) { + + if (oldPopupMenu != null) { + oldPopupMenu.dispose(); + oldPopupMenu = null; + } + + IMenuManager mm = null; + if (part instanceof IIconTipPart) { + mm = ((IIconTipPart) part).getPopupMenu(); + } else { + if (part instanceof IInfoItemPart) + mm = ((IInfoItemPart) part).getPopupMenu(); + } + + if (mm != null) { + Menu newPopupMenu = ((MenuManager) mm) + .createContextMenu(control); + oldPopupMenu = newPopupMenu; + control.setMenu(newPopupMenu); + defaultMenuVisible = false; + } else { + if (defaultMenu != null) + control.setMenu(defaultMenu); + } + return; + } + if (defaultMenu != null) { + control.setMenu(defaultMenu); + } + + } + + private IPart findIconTipAt(int x, int y) { + IPart part = getViewer().findPart(x, y); + if (part instanceof IIconTipPart + || part instanceof InfoItemIconPart) { + } else { + part = null; + } + return (IPart) part; + } + }); + } + + public void updatePageTitle() { + ISheet sheet = getCastedInput(); + String name = sheet.hasTitle() ? sheet.getTitleText() + : sheet.getRootTopic().getTitleText(); + setPageTitle(MindMapUtils.trimSingleLine(name)); + } + + protected void installModelListeners(Object input) { + super.installModelListeners(input); + eventRegister = new CoreEventRegister(input, this); + eventRegister.register(Core.TitleText); + prefStore = MindMapUIPlugin.getDefault().getPreferenceStore(); + if (prefStore != null) { + prefStore.addPropertyChangeListener(this); + } + } + + protected void uninstallModelListeners(Object input) { + if (prefStore != null) { + prefStore.removePropertyChangeListener(this); + prefStore = null; + } + if (eventRegister != null) { + eventRegister.unregisterAll(); + eventRegister = null; + } + super.uninstallModelListeners(input); + } + + public void propertyChange(PropertyChangeEvent event) { + if (PrefConstants.MANUAL_LAYOUT_ALLOWED.equals(event.getProperty())) { + MoveTool moveTool = (MoveTool) getViewer().getEditDomain() + .getTool(MindMapUI.TOOL_MOVE_TOPIC); + if (null != moveTool) { + IPreferenceStore prefStore = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + boolean status = prefStore + .getBoolean(PrefConstants.MANUAL_LAYOUT_ALLOWED); + moveTool.getStatus().setStatus(GEF.ST_FREE_MOVE_MODE, status); + } + } else if (PrefConstants.OVERLAPS_ALLOWED.equals(event.getProperty())) { + ISheetPart sheet = ((IMindMapViewer) getViewer()).getSheetPart(); + if (sheet != null) { + sheet.getFigure().revalidate(); + } + } else if (PrefConstants.SHADOW_ENABLED.equals(event.getProperty())) { + if (shadowService != null) { + Object value = event.getNewValue(); + if (value instanceof String) + value = Boolean.parseBoolean((String) value); + if (value instanceof Boolean) + shadowService.setActive((Boolean) value); + else + shadowService.setActive(false); + } + } else if (PrefConstants.GRADIENT_COLOR.equals(event.getProperty())) { + IBranchPart part = ((IMindMapViewer) getViewer()) + .getCentralBranchPart(); + if (part != null) { + part.treeUpdate(false); + } + } else if (PrefConstants.UNDO_REDO_TIPS_ENABLED + .equals(event.getProperty())) { + if (undoService != null) { + Object value = event.getNewValue(); + if (value instanceof String) + value = Boolean.parseBoolean((String) value); + if (value instanceof Boolean) + undoService.setActive((Boolean) value); + else + undoService.setActive(false); + } + } else if (PrefConstants.UNDO_REDO_TIPS_FADE_DELAY + .equals(event.getProperty())) { + if (undoService != null) { + Object value = event.getNewValue(); + if (value instanceof String) { + value = Integer.parseInt((String) value); + } + if (value instanceof Integer) { + undoService.setDuration(((Integer) value).intValue()); + } else { + undoService + .setDuration(UndoRedoTipsService.DEFAULT_DURATION); + } + } + } + } + + public ISheet getCastedInput() { + return (ISheet) super.getInput(); + } + + protected Object createViewerInput() { + return new MindMap(getCastedInput()); + } + + protected void initViewer(IGraphicalViewer viewer) { + super.initViewer(viewer); + viewer.getZoomManager().setConstraints(MindMapUI.ZOOM_MIN / 100.0d, + MindMapUI.ZOOM_MAX / 100.0d); + + Properties properties = viewer.getProperties(); + properties.set(IMindMapViewer.VIEWER_CENTERED, Boolean.TRUE); + properties.set(IMindMapViewer.VIEWER_CORNERED, Boolean.TRUE); + properties.set(IMindMapViewer.VIEWER_ACTIONS, + new ActionRegistry(getActionRegistry())); + properties.set(IMindMapViewer.VIEWER_MARGIN, + Integer.valueOf(MindMapUI.SHEET_MARGIN)); + + initViewerServices((MindMapViewer) viewer); + } + + protected void configureViewer(IGraphicalViewer viewer) { + super.configureViewer(viewer); + if (selectionStack == null) + selectionStack = createSelectionStack(); + selectionStack.setSelectionProvider(getViewer()); + selectionStack.setCommandStack(getEditDomain().getCommandStack()); + } + + protected ISelectionStack createSelectionStack() { + return new SelectionStack(); + } + + protected void initViewerServices(MindMapViewer viewer) { + CenterPreservationService centerPresercationService = new CenterPreservationService( + viewer); + viewer.installService(CenterPreservationService.class, + centerPresercationService); + centerPresercationService.setActive(true); + + IImageRegistryService imageCacheService = new ImageRegistryService( + viewer); + viewer.installService(IImageRegistryService.class, imageCacheService); + imageCacheService.setActive(true); + + IRevealService revealService = new MindMapRevealService(viewer); + viewer.installService(IRevealService.class, revealService); + revealService.setActive(true); + + IAnimationService animationService = new AnimationService(viewer); + animationService.setPlaybackProvider(MindMapUI.getPlaybackProvider()); + viewer.installService(IAnimationService.class, animationService); + animationService.setActive(true); + + Layer coverLayer = viewer.getLayer(MindMapUI.LAYER_COVER); + Layer skylightLayer = viewer.getLayer(MindMapUI.LAYER_SKYLIGHT); + if (coverLayer instanceof IRelayeredPane + || skylightLayer instanceof ISkylightLayer) { + IHighlightService highlightService = new HighlightService(viewer, + false); + if (coverLayer instanceof IRelayeredPane) + highlightService.setRelayeredPane((IRelayeredPane) coverLayer); + if (skylightLayer instanceof ISkylightLayer) + highlightService + .setHighlightLayer((SkylightLayer) skylightLayer); + viewer.installService(IHighlightService.class, highlightService); + highlightService.setActive(true); + } + + Layer feedbackLayer = viewer.getLayer(GEF.LAYER_FEEDBACK); + if (feedbackLayer != null) { + FeedbackService feedbackService = new FeedbackService(viewer); + viewer.installService(IFeedbackService.class, feedbackService); + feedbackService.setLayer(feedbackLayer); + feedbackService.setSelectionColorProvider(this); + feedbackService + .setSelectionLineWidth(MindMapUI.SELECTION_LINE_WIDTH); + feedbackService + .setSelectionCorner(MindMapUI.SELECTION_ROUNDED_CORNER); + feedbackService.setActive(true); + } + + IDrillDownTraceService traceService = new DrillDownTraceService(viewer); + viewer.installService(IDrillDownTraceService.class, traceService); + traceService.setActive(true); + IAction action = getActionRegistry() + .getAction(MindMapActionFactory.DRILL_UP.getId()); + if (action instanceof DrillUpAction) { + ((DrillUpAction) action).setTraceService(traceService); + } + + Layer shadowLayer = viewer.getLayer(GEF.LAYER_SHADOW); + if (shadowLayer != null) { + shadowService = new ShadowService(viewer); + viewer.installService(IShadowService.class, shadowService); + shadowService.setLayer(shadowLayer); + shadowService.setActive(prefStore != null + && prefStore.getBoolean(PrefConstants.SHADOW_ENABLED)); + } + + Layer undoLayer = viewer.getLayer(MindMapUI.LAYER_UNDO); + if (undoLayer != null) { + undoService = new UndoRedoTipsService(viewer); + viewer.installService(UndoRedoTipsService.class, undoService); + undoService.setLayer(undoLayer); + undoService.setActive(true); + } + + MindMapTopicContextService contextService = new MindMapTopicContextService( + this, viewer); + viewer.installService(TopicContextService.class, contextService); + contextService.setActive(true); + } + + public void setActive(boolean active) { + boolean oldActive = isActive(); + super.setActive(active); + boolean newActive = isActive(); + if (oldActive && !newActive) { + if (getEditDomain() != null) { + getEditDomain().handleRequest(GEF.REQ_CANCEL, getViewer()); + } + } + } + + protected void initPageActions(IActionRegistry actionRegistry) { + super.initPageActions(actionRegistry); + + InsertTopicAction insertTopicAction = new InsertTopicAction(this); + actionRegistry.addAction(insertTopicAction); + addSelectionAction(insertTopicAction); + + InsertSubtopicAction insertSubtopicAction = new InsertSubtopicAction( + this); + actionRegistry.addAction(insertSubtopicAction); + addSelectionAction(insertSubtopicAction); + + InsertTopicBeforeAction insertTopicBeforeAction = new InsertTopicBeforeAction( + this); + actionRegistry.addAction(insertTopicBeforeAction); + addSelectionAction(insertTopicBeforeAction); + + InsertParentTopicAction insertParentTopicAction = new InsertParentTopicAction( + this); + actionRegistry.addAction(insertParentTopicAction); + addSelectionAction(insertParentTopicAction); + + CreateSheetFromTopicAction insertSheetAction = new CreateSheetFromTopicAction( + this); + actionRegistry.addAction(insertSheetAction); + addSelectionAction(insertSheetAction); + + ExtendAction extendAction = new ExtendAction(this); + actionRegistry.addAction(extendAction); + addSelectionAction(extendAction); + + CollapseAction collapseAction = new CollapseAction(this); + actionRegistry.addAction(collapseAction); + addSelectionAction(collapseAction); + + ExtendAllAction extendAllAction = new ExtendAllAction(this); + actionRegistry.addAction(extendAllAction); + addSelectionAction(extendAllAction); + + CollapseAllAction collapseAllAction = new CollapseAllAction(this); + actionRegistry.addAction(collapseAllAction); + addSelectionAction(collapseAllAction); + + ModifyHyperlinkAction modifyHyperlinkAction = new ModifyHyperlinkAction( + this); + actionRegistry.addAction(modifyHyperlinkAction); + addSelectionAction(modifyHyperlinkAction); + + OpenHyperlinkAction openHyperlinkAction = new OpenHyperlinkAction(this); + actionRegistry.addAction(openHyperlinkAction); + addSelectionAction(openHyperlinkAction); + + InsertAttachmentAction insertAttachmentAction = new InsertAttachmentAction( + this); + actionRegistry.addAction(insertAttachmentAction); + addSelectionAction(insertAttachmentAction); + + InsertImageAction insertImageAction = new InsertImageAction(this); + actionRegistry.addAction(insertImageAction); + addSelectionAction(insertImageAction); + + DeleteAction deleteAction = new DeleteAction(this); + actionRegistry.addAction(deleteAction); + addSelectionAction(deleteAction); + + CopyAction copyAction = new CopyAction(this); + actionRegistry.addAction(copyAction); + + CutAction cutAction = new CutAction(this); + actionRegistry.addAction(cutAction); + addSelectionAction(cutAction); + + PasteAction pasteAction = new PasteAction(this); + actionRegistry.addAction(pasteAction); + addSelectionAction(pasteAction); + + ZoomInAction zoomInAction = new ZoomInAction(this); + actionRegistry.addAction(zoomInAction); + + ZoomOutAction zoomOutAction = new ZoomOutAction(this); + actionRegistry.addAction(zoomOutAction); + + ActualSizeAction actualSizeAction = new ActualSizeAction(this); + actionRegistry.addAction(actualSizeAction); + + FitMapAction fitMapAction = new FitMapAction(this); + actionRegistry.addAction(fitMapAction); + + FitSelectionAction fitSelectionAction = new FitSelectionAction(this); + actionRegistry.addAction(fitSelectionAction); + + SelectAllAction selectAllAction = new SelectAllAction(this); + actionRegistry.addAction(selectAllAction); + + SelectBrothersAction selectBrothersAction = new SelectBrothersAction( + this); + actionRegistry.addAction(selectBrothersAction); + addSelectionAction(selectBrothersAction); + + SelectChildrenAction selectChildrenAction = new SelectChildrenAction( + this); + actionRegistry.addAction(selectChildrenAction); + addSelectionAction(selectChildrenAction); + + DrillDownAction drillDownAction = new DrillDownAction(this); + actionRegistry.addAction(drillDownAction); + addSelectionAction(drillDownAction); + + DrillUpAction drillUpAction = new DrillUpAction(this); + actionRegistry.addAction(drillUpAction); + +// CreateBoundaryAction createBoundaryAction = new CreateBoundaryAction( +// this); +// actionRegistry.addAction(createBoundaryAction); +// +// CreateSummaryAction createSummaryAction = new CreateSummaryAction(this); +// actionRegistry.addAction(createSummaryAction); + +// SortAsAlphaAction sortAsAlphaAction = new SortAsAlphaAction(this); +// actionRegistry.addAction(sortAsAlphaAction); +// addSelectionAction(sortAsAlphaAction); +// +// SortAsPriorityAction sortAsPriorityAction = new SortAsPriorityAction( +// this); +// actionRegistry.addAction(sortAsPriorityAction); +// addSelectionAction(sortAsPriorityAction); +// +// SortAsModifyDateAction sortAsModifyDateAction = new SortAsModifyDateAction( +// this); +// actionRegistry.addAction(sortAsModifyDateAction); +// addSelectionAction(sortAsModifyDateAction); + + EditTitleAction editTitleAction = new EditTitleAction(this); + actionRegistry.addAction(editTitleAction); + addSelectionAction(editTitleAction); + + EditLabelAction editLabelAction = new EditLabelAction(this); + actionRegistry.addAction(editLabelAction); + addSelectionAction(editLabelAction); + + EditNotesAction editNotesAction = new EditNotesAction(this); + actionRegistry.addAction(editNotesAction); + addSelectionAction(editNotesAction); + + EditCommentsAction editCommentsAction = new EditCommentsAction(this); + actionRegistry.addAction(editCommentsAction); + addSelectionAction(editCommentsAction); + + TraverseAction raverseAction = new TraverseAction(this); + actionRegistry.addAction(raverseAction); + addSelectionAction(raverseAction); + + DuplicateAction duplicateAction = new DuplicateAction(this); + actionRegistry.addAction(duplicateAction); + addSelectionAction(duplicateAction); + + FinishAction finishAction = new FinishAction( + MindMapActionFactory.FINISH.getId(), this); + actionRegistry.addAction(finishAction); + + TileAction tileAction = new TileAction(this); + actionRegistry.addAction(tileAction); + + ResetPositionAction resetPositionAction = new ResetPositionAction(this); + actionRegistry.addAction(resetPositionAction); + addSelectionAction(resetPositionAction); + + RemoveAllStylesAction removeAllStylesAction = new RemoveAllStylesAction( + this); + actionRegistry.addAction(removeAllStylesAction); + addSelectionAction(removeAllStylesAction); + + actionRegistry.addAction(new RequestAction( + MindMapActionFactory.MOVE_UP.getId(), this, GEF.REQ_MOVE_UP)); + actionRegistry.addAction( + new RequestAction(MindMapActionFactory.MOVE_DOWN.getId(), this, + GEF.REQ_MOVE_DOWN)); + actionRegistry.addAction( + new RequestAction(MindMapActionFactory.MOVE_LEFT.getId(), this, + GEF.REQ_MOVE_LEFT)); + actionRegistry.addAction( + new RequestAction(MindMapActionFactory.MOVE_RIGHT.getId(), this, + GEF.REQ_MOVE_RIGHT)); + actionRegistry.addAction( + new RequestAction(MindMapActionFactory.GO_HOME.getId(), this, + MindMapUI.REQ_SELECT_CENTRAL)); + actionRegistry.addAction(new InsertFloatingTopicAction( + MindMapActionFactory.INSERT_FLOATING_TOPIC.getId(), this)); + actionRegistry.addAction(new InsertFloatingTopicAction( + MindMapActionFactory.INSERT_FLOATING_CENTRAL_TOPIC.getId(), + this)); + + CancelHyperlinkAction cancelHyperlinkAction = new CancelHyperlinkAction( + this); + actionRegistry.addAction(cancelHyperlinkAction); + addSelectionAction(cancelHyperlinkAction); + +// NewSheetFromTemplateDialogAction newSheetFromTemplateAction = new NewSheetFromTemplateDialogAction( +// this); +// actionRegistry.addAction(newSheetFromTemplateAction); +// addSelectionAction(newSheetFromTemplateAction); + + addAlignmentAction(PositionConstants.LEFT, actionRegistry); + addAlignmentAction(PositionConstants.CENTER, actionRegistry); + addAlignmentAction(PositionConstants.RIGHT, actionRegistry); + addAlignmentAction(PositionConstants.TOP, actionRegistry); + addAlignmentAction(PositionConstants.MIDDLE, actionRegistry); + addAlignmentAction(PositionConstants.BOTTOM, actionRegistry); + addSortAction(ActionConstants.SORT_TITLE_ID, actionRegistry); + addSortAction(ActionConstants.SORT_PRIORITY_ID, actionRegistry); + addSortAction(ActionConstants.SORT_MODIFIED_ID, actionRegistry); + + PrintMapAction2 printMapAction = new PrintMapAction2(this); + actionRegistry.addAction(printMapAction); + } + + private void addAlignmentAction(int alignment, + IActionRegistry actionRegistry) { + AlignmentRequestAction action = new AlignmentRequestAction(this, + alignment); + actionRegistry.addAction(action); + addSelectionAction(action); + } + + private void addSortAction(String sortId, IActionRegistry actionRegistry) { + SortRequestAction action = new SortRequestAction(this, sortId); + actionRegistry.addAction(action); + addSelectionAction(action); + } + + public void dispose() { + if (imeSupport != null) { + imeSupport.dispose(); + imeSupport = null; + } + if (selectionStack != null) { + selectionStack.setCommandStack(null); + selectionStack.setSelectionProvider(null); + selectionStack = null; + } + super.dispose(); + } + + public Object getAdapter(Class adapter) { + if (adapter == ISheet.class) + return getCastedInput(); + if (adapter == IMindMap.class) + return getViewer().getInput(); + return super.getAdapter(adapter); + } + + public void handleCoreEvent(final CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + + public void run() { + String type = event.getType(); + if (Core.TitleText.equals(type)) { + updatePageTitle(); + } + } + }); + } + + public Color getBackground(Object element) { + if (IFeedbackService.PreselectionColor.equals(element) + || IFeedbackService.DisabledPreselectionColor.equals(element)) + return ColorUtils.getColor(MindMapUI.FILL_COLOR_PRESELECTION); + return null; + } + + public Color getForeground(Object element) { + if (IFeedbackService.FocusColor.equals(element)) + return ColorUtils.getColor(MindMapUI.LINE_COLOR_FOCUS); + if (IFeedbackService.SelectionColor.equals(element)) + return ColorUtils.getColor(MindMapUI.LINE_COLOR_SELECTION); + if (IFeedbackService.PreselectionColor.equals(element) + || IFeedbackService.DisabledPreselectionColor.equals(element)) + return ColorUtils.getColor(MindMapUI.LINE_COLOR_PRESELECTION); + if (IFeedbackService.DisabledFocusColor.equals(element)) + return ColorUtils.getColor(MindMapUI.LINE_COLOR_FOCUS_DISABLED); + if (IFeedbackService.DisabledSelectionColor.equals(element)) + return ColorUtils.getColor(MindMapUI.LINE_COLOR_SELECTION_DISABLED); + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePanelContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePanelContributor.java index 6f7967859..8ebc02c5e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePanelContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePanelContributor.java @@ -1,726 +1,726 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.util.Util; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Layout; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.ui.actions.PageAction; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.gef.ui.editor.IPanel; -import org.xmind.gef.ui.editor.PanelContribution; -import org.xmind.gef.ui.editor.PanelContributor; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IDrillDownTraceListener; -import org.xmind.ui.mindmap.IDrillDownTraceService; -import org.xmind.ui.mindmap.IMindMap; -import org.xmind.ui.mindmap.MindMap; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; -import org.xmind.ui.util.MindMapUtils; - -public class MindMapEditorPagePanelContributor extends PanelContributor { - - protected static class CrumbItem implements IPropertyChangeListener { - - private static final int H_MARGIN = 8; - - private static final int V_MARGIN = 2; - - private static final int M = 2; - - private static final int M2 = M + 1; - - private static final int W = M * 2 + 1; - - private static final int W2 = M2 * 2; - - private static final int C2 = W2 * 2 + 1; - - private static final int C = C2 + 1; - - private static final int SPACING = 1; - - private CrumbsBar bar; - - private IAction action; - - private Rectangle bounds; - - private boolean mouseOver; - - private boolean pressed; - - private Image image = null; - - public CrumbItem() { - this(null); - } - - public CrumbItem(IAction action) { - this.action = action; - } - - void setParent(CrumbsBar bar) { - if (bar == this.bar) - return; - if (action != null) { - if (this.bar == null && bar != null) { - action.addPropertyChangeListener(this); - } else if (this.bar != null && bar == null) { - action.removePropertyChangeListener(this); - } - } - this.bar = bar; - } - - public void setMouseOver(boolean mouseOver) { - if (mouseOver == this.mouseOver) - return; - this.mouseOver = mouseOver; - redraw(); - } - - public boolean isMouseOver() { - return mouseOver; - } - - public void setPressed(boolean pressed) { - if (pressed == this.pressed) - return; - this.pressed = pressed; - redraw(); - } - - public boolean isPressed() { - return pressed; - } - - public void setBounds(Rectangle bounds) { - if (bounds == this.bounds - || (bounds != null && bounds.equals(this.bounds))) - return; - this.bounds = bounds; - redraw(); - } - - public Rectangle getBounds() { - if (bounds == null) - bounds = new Rectangle(0, 0, 0, 0); - return bounds; - } - - public boolean isEnabled() { - return action != null && action.isEnabled(); - } - - private void redraw() { - if (barExists()) - bar.redraw(this); - } - - public boolean isSeparator() { - return action == null; - } - - Point getPrefSize() { - if (!barExists()) - return new Point(0, 0); - GC gc = new GC(Display.getCurrent()); - gc.setFont(bar.getFont()); - Point s = gc.textExtent(getText()); - gc.dispose(); - int h = getHMargin(); - int v = getVMargin(); - - Image img = getImage(); - if (img != null) { - Rectangle r = img.getBounds(); - s.x += r.width + SPACING; - s.y = Math.max(s.y, r.height); - } - - s.x += h + h + 1; - s.y += v + v + 1; - return s; - } - - private int getHMargin() { - if (isSeparator()) - return 0; - return H_MARGIN; - } - - private int getVMargin() { - if (isSeparator()) - return 0; - return V_MARGIN; - } - - protected void paint(GC gc) { - gc.setAntialias(SWT.ON); - gc.setLineStyle(SWT.LINE_SOLID); - gc.setLineWidth(1); - - if (pressed || mouseOver) { - if (pressed && mouseOver) { - gc.setBackground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ - } else if (pressed) { - gc.setBackground(ColorUtils.getColor("#707070")); //$NON-NLS-1$ - } else { - gc.setBackground(ColorUtils.getColor("#e0e0e0")); //$NON-NLS-1$ - } - gc.fillRoundRectangle(bounds.x + M2, bounds.y + M2, - bounds.width - W2, bounds.height - W2, C2, C2); - - if (pressed && mouseOver) { - gc.setForeground(ColorUtils.getColor("#909090")); //$NON-NLS-1$ - } else if (pressed) { - gc.setForeground(ColorUtils.getColor("#606060")); //$NON-NLS-1$ - } else { - gc.setForeground(ColorUtils.getColor("#d0d0d0")); //$NON-NLS-1$ - } - gc.drawRoundRectangle(bounds.x + M, bounds.y + M, - bounds.width - W, bounds.height - W, C, C); - } - - int h = getHMargin(); - int v = getVMargin(); - int x = bounds.x + h; - int y = bounds.y + v; - int height = bounds.height - v - v; - - Image img = getImage(); - if (img != null) { - Rectangle r = img.getBounds(); - gc.drawImage(img, x, y + (height - r.height) / 2); - x += r.width + SPACING; - } - - if (isSeparator() || !isEnabled()) { - gc.setForeground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ - } else if (pressed) { - gc.setForeground(ColorUtils.getColor("#f0f0f0")); //$NON-NLS-1$ - } else { - gc.setForeground(ColorUtils.getColor("#000000")); //$NON-NLS-1$ - } - String text = getText(); - Point s = gc.textExtent(text); - gc.drawText(text, x, y + (height - s.y) / 2, true); - } - - protected String getText() { - if (action != null) { - String text = action.getText(); - if (text != null) { - text = MindMapUtils.trimSingleLine(text); - return text; - } - return ""; //$NON-NLS-1$ - } - return ">"; //$NON-NLS-1$ - } - - protected Image getImage() { - if (image == null && barExists()) { - if (action != null) { - ImageDescriptor imgDesc = null; - Display display = bar.getDisplay(); - if (!isEnabled()) { - imgDesc = action.getDisabledImageDescriptor(); - if (imgDesc != null) { - image = imgDesc.createImage(display); - } - if (image == null) { - imgDesc = action.getImageDescriptor(); - if (imgDesc != null) { - Image img = imgDesc.createImage(display); - image = new Image(display, img, - SWT.IMAGE_DISABLE); - img.dispose(); - } - } - } else { - imgDesc = action.getImageDescriptor(); - if (imgDesc != null) { - image = imgDesc.createImage(display); - } - } - } - } - return image; - } - - protected void run() { - if (action != null) - action.run(); - } - - public void update(String id) { - boolean textChange = id == null || IAction.TEXT.equals(id); - boolean tooltipChange = id == null - || IAction.TOOL_TIP_TEXT.equals(id); - boolean enabledChange = id == null || IAction.ENABLED.equals(id); - boolean imageChange = id == null || IAction.IMAGE.equals(id); - boolean needUpdateBar = textChange || imageChange; - - if (barExists()) { - bar.setRedraw(false); - } - - if (enabledChange) { - redraw(); - } - - if (tooltipChange) { - if (action != null && barExists()) - bar.setToolTipText(action.getToolTipText()); - } - - if (imageChange) { - if (image != null) { - image.dispose(); - image = null; - } - } - - if (needUpdateBar) { - if (barExists()) - bar.updateLayout(); - } - - if (barExists()) { - bar.setRedraw(true); - } - } - - public void propertyChange(PropertyChangeEvent event) { - update(event.getProperty()); - } - - public IAction getAction() { - return action; - } - - protected boolean barExists() { - return bar != null && !bar.isDisposed(); - } - - protected void releaseResources() { - if (image != null) { - image.dispose(); - image = null; - } - } - - } - - protected static class CrumbsBar extends Composite { - - private static final int SPACING = 1; - - private class CrumbsBarListener - implements PaintListener, MouseListener, MouseMoveListener, - MouseTrackListener, ControlListener, DisposeListener { - - private CrumbItem sourceItem = null; - - private CrumbItem targetItem = null; - - public void paintControl(PaintEvent e) { - GC gc = e.gc; - if (!Util.isMac()) { - gc.setBackground(e.display - .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - gc.fillRectangle(getBounds()); - } - - Rectangle clipping = gc.getClipping(); - for (CrumbItem item : items) { - if (clipping.intersects(item.getBounds())) { - item.paint(gc); - } - } - } - - public void mouseDoubleClick(MouseEvent e) { - } - - public void mouseDown(MouseEvent e) { - CrumbItem item = findItem(e.x, e.y); - if (item != null && item.isEnabled() && !item.isSeparator()) { - sourceItem = item; - item.setPressed(true); - } - } - - public void mouseUp(MouseEvent e) { - CrumbItem item = findItem(e.x, e.y); - CrumbItem source = sourceItem; - if (sourceItem != null) { - sourceItem.setPressed(false); - sourceItem = null; - } - if (item != null && item == source) { - item.run(); - } - } - - private void receiveTarget(int x, int y) { - CrumbItem item = findItem(x, y); - if (item != targetItem) { - if (targetItem != null && targetItem.isEnabled() - && !targetItem.isSeparator()) { - targetItem.setMouseOver(false); - } - targetItem = item; - if (item != null && item.isEnabled() - && !item.isSeparator()) { - if (sourceItem == null || item == sourceItem) { - item.setMouseOver(true); - } - } - String tooltip = null; - if (targetItem != null) { - IAction action = targetItem.getAction(); - if (action != null) { - tooltip = action.getToolTipText(); - } - } - setToolTipText(tooltip); - } - } - - public void mouseMove(MouseEvent e) { - receiveTarget(e.x, e.y); - } - - public void mouseEnter(MouseEvent e) { - receiveTarget(e.x, e.y); - } - - public void mouseExit(MouseEvent e) { - receiveTarget(e.x, e.y); - } - - public void mouseHover(MouseEvent e) { - receiveTarget(e.x, e.y); - } - - public void controlMoved(ControlEvent e) { - updateLayout(); - } - - public void controlResized(ControlEvent e) { - updateLayout(); - } - - public void widgetDisposed(DisposeEvent e) { - releaseItems(); - } - - } - - private List items = new ArrayList(); - - public CrumbsBar(Composite parent, int style) { - super(parent, style); - CrumbsBarListener eventHandler = new CrumbsBarListener(); - addPaintListener(eventHandler); - addMouseListener(eventHandler); - addMouseMoveListener(eventHandler); - addMouseTrackListener(eventHandler); - addControlListener(eventHandler); - setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, - -1)); - } - - private void releaseItems() { - for (CrumbItem item : items) { - item.releaseResources(); - } - } - - protected void redraw(CrumbItem item) { - checkWidget(); - Rectangle r = item.getBounds(); - redraw(r.x, r.y, r.width, r.height, false); - } - - public void addItem(CrumbItem item) { - checkWidget(); - addItem(item, -1); - } - - public void addItem(CrumbItem item, int index) { - checkWidget(); - items.remove(item); - if (index < 0) - items.add(item); - else - items.add(index, item); - itemAdded(item); - } - - public void removeItem(CrumbItem item) { - checkWidget(); - items.remove(item); - itemRemoved(item); - } - - private void itemAdded(CrumbItem item) { - item.setParent(this); - layout(); - } - - private void itemRemoved(CrumbItem item) { - item.setParent(null); - item.releaseResources(); - layout(); - } - - public void removeAllItems() { - checkWidget(); - setRedraw(false); - CrumbItem[] oldItems = getItems(); - items.clear(); - for (CrumbItem item : oldItems) { - itemRemoved(item); - } - layout(); - setRedraw(true); - } - - public CrumbItem[] getItems() { - checkWidget(); - return items.toArray(new CrumbItem[items.size()]); - } - - public CrumbItem findItem(Point p) { - checkWidget(); - return findItem(p.x, p.y); - } - - public CrumbItem findItem(int x, int y) { - checkWidget(); - for (CrumbItem item : items) { - Rectangle r = item.getBounds(); - if (r.contains(x, y)) - return item; - } - return null; - } - - public void setLayout(Layout layout) { - } - - public void layout(boolean changed) { - updateLayout(); - } - - public void layout(boolean changed, boolean all) { - updateLayout(); - } - - protected void updateLayout() { - checkWidget(); - Point p = new Point(0, 0); - int h = getSize().y; - for (CrumbItem item : items) { - Point s = item.getPrefSize(); - Rectangle r = new Rectangle(p.x, p.y + (h - s.y) / 2, s.x, s.y); - item.setBounds(r); - p.x += s.x + SPACING; - } - redraw(); - } - - public Point computeSize(int wHint, int hHint, boolean changed) { - checkWidget(); - if (wHint >= 0 && hHint >= 0) - return new Point(wHint, hHint); - - Point size = new Point(0, 0); - if (wHint >= 0) { - size.x = wHint; - } - for (CrumbItem item : items) { - Point s = item.getPrefSize(); - if (wHint < 0) { - if (size.x > 0) - size.x += SPACING; - size.x += s.x; - } - size.y = Math.max(size.y, s.y); - } - return size; - } - } - - class Crumbs extends PanelContribution implements IDrillDownTraceListener { - - private class QuickDrillUpAction extends PageAction { - - private ITopic newCentralTopic; - - public QuickDrillUpAction(IGraphicalEditorPage page, ITopic topic) { - super(page); - this.newCentralTopic = topic; - String title = topic.getTitleText(); - setText(title); - setToolTipText(NLS.bind( - MindMapMessages.BreadCrumb_ViewAsCentral_text, title)); - setImageDescriptor(MindMapUtils.getImageDescriptor(topic)); - } - - public void run() { - super.run(); - IGraphicalViewer viewer = getViewer(); - if (viewer != null) { - ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); - if (sheet != null) { - IMindMap newInput = new MindMap(sheet, newCentralTopic); - viewer.setInput(newInput); - if (viewer.getEditDomain() != null) { - viewer.getEditDomain().handleRequest( - MindMapUI.REQ_SELECT_CENTRAL, viewer); - } - } - } - } - - } - - private CrumbsBar bar = null; - - private IDrillDownTraceService service = null; - - public void createControl(Composite parent) { - if (!barExists()) { - bar = new CrumbsBar(parent, SWT.NONE); - } - } - - public Control getControl() { - return bar; - } - - public void update() { - boolean hasNewItems = service != null && service.canDrillUp(); - if (barExists()) { - bar.removeAllItems(); - bar.setRedraw(false); - if (hasNewItems) { - List topics = service.getCentralTopics(); - if (!topics.isEmpty()) { - for (int i = 0; i < topics.size(); i++) { - ITopic t = topics.get(i); - QuickDrillUpAction action = new QuickDrillUpAction( - getPage(), t); - if (i == topics.size() - 1) { - action.setEnabled(false); - action.setImageDescriptor(null); - action.setToolTipText(NLS.bind( - MindMapMessages.BreadCrumb_CurrentCentral_text, - action.newCentralTopic.getTitleText())); - } - - bar.addItem(new CrumbItem(action)); - if (i < topics.size() - 1) { - bar.addItem(new CrumbItem()); - } - } - } - } - bar.setRedraw(true); - setVisible(hasNewItems); - } - } - - private boolean barExists() { - return bar != null && !bar.isDisposed(); - } - - public void traceChanged(IDrillDownTraceService traceService) { - update(); - } - - public void setTraceService(IDrillDownTraceService service) { - if (service == this.service) - return; - - if (this.service != null) { - this.service.removeTraceListener(this); - } - this.service = service; - if (service != null) { - service.addTraceListener(this); - } - update(); - } - - } - - private Crumbs crumbs = null; - - protected void init(IPanel panel) { - super.init(panel); - crumbs = new Crumbs(); - crumbs.setVisible(false); - panel.addContribution(IPanel.TOP, crumbs); - } - - public void setViewer(IGraphicalViewer viewer) { - super.setViewer(viewer); - - IDrillDownTraceService traceService = (IDrillDownTraceService) viewer - .getService(IDrillDownTraceService.class); - crumbs.setTraceService(traceService); - } - - public void dispose() { - crumbs.setTraceService(null); - super.dispose(); - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.Util; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Layout; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ui.actions.PageAction; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.gef.ui.editor.IPanel; +import org.xmind.gef.ui.editor.PanelContribution; +import org.xmind.gef.ui.editor.PanelContributor; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IDrillDownTraceListener; +import org.xmind.ui.mindmap.IDrillDownTraceService; +import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.mindmap.MindMap; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.resources.FontUtils; +import org.xmind.ui.util.MindMapUtils; + +public class MindMapEditorPagePanelContributor extends PanelContributor { + + protected static class CrumbItem implements IPropertyChangeListener { + + private static final int H_MARGIN = 8; + + private static final int V_MARGIN = 2; + + private static final int M = 2; + + private static final int M2 = M + 1; + + private static final int W = M * 2 + 1; + + private static final int W2 = M2 * 2; + + private static final int C2 = W2 * 2 + 1; + + private static final int C = C2 + 1; + + private static final int SPACING = 1; + + private CrumbsBar bar; + + private IAction action; + + private Rectangle bounds; + + private boolean mouseOver; + + private boolean pressed; + + private Image image = null; + + public CrumbItem() { + this(null); + } + + public CrumbItem(IAction action) { + this.action = action; + } + + void setParent(CrumbsBar bar) { + if (bar == this.bar) + return; + if (action != null) { + if (this.bar == null && bar != null) { + action.addPropertyChangeListener(this); + } else if (this.bar != null && bar == null) { + action.removePropertyChangeListener(this); + } + } + this.bar = bar; + } + + public void setMouseOver(boolean mouseOver) { + if (mouseOver == this.mouseOver) + return; + this.mouseOver = mouseOver; + redraw(); + } + + public boolean isMouseOver() { + return mouseOver; + } + + public void setPressed(boolean pressed) { + if (pressed == this.pressed) + return; + this.pressed = pressed; + redraw(); + } + + public boolean isPressed() { + return pressed; + } + + public void setBounds(Rectangle bounds) { + if (bounds == this.bounds + || (bounds != null && bounds.equals(this.bounds))) + return; + this.bounds = bounds; + redraw(); + } + + public Rectangle getBounds() { + if (bounds == null) + bounds = new Rectangle(0, 0, 0, 0); + return bounds; + } + + public boolean isEnabled() { + return action != null && action.isEnabled(); + } + + private void redraw() { + if (barExists()) + bar.redraw(this); + } + + public boolean isSeparator() { + return action == null; + } + + Point getPrefSize() { + if (!barExists()) + return new Point(0, 0); + GC gc = new GC(Display.getCurrent()); + gc.setFont(bar.getFont()); + Point s = gc.textExtent(getText()); + gc.dispose(); + int h = getHMargin(); + int v = getVMargin(); + + Image img = getImage(); + if (img != null) { + Rectangle r = img.getBounds(); + s.x += r.width + SPACING; + s.y = Math.max(s.y, r.height); + } + + s.x += h + h + 1; + s.y += v + v + 1; + return s; + } + + private int getHMargin() { + if (isSeparator()) + return 0; + return H_MARGIN; + } + + private int getVMargin() { + if (isSeparator()) + return 0; + return V_MARGIN; + } + + protected void paint(GC gc) { + gc.setAntialias(SWT.ON); + gc.setLineStyle(SWT.LINE_SOLID); + gc.setLineWidth(1); + + if (pressed || mouseOver) { + if (pressed && mouseOver) { + gc.setBackground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ + } else if (pressed) { + gc.setBackground(ColorUtils.getColor("#707070")); //$NON-NLS-1$ + } else { + gc.setBackground(ColorUtils.getColor("#e0e0e0")); //$NON-NLS-1$ + } + gc.fillRoundRectangle(bounds.x + M2, bounds.y + M2, + bounds.width - W2, bounds.height - W2, C2, C2); + + if (pressed && mouseOver) { + gc.setForeground(ColorUtils.getColor("#909090")); //$NON-NLS-1$ + } else if (pressed) { + gc.setForeground(ColorUtils.getColor("#606060")); //$NON-NLS-1$ + } else { + gc.setForeground(ColorUtils.getColor("#d0d0d0")); //$NON-NLS-1$ + } + gc.drawRoundRectangle(bounds.x + M, bounds.y + M, + bounds.width - W, bounds.height - W, C, C); + } + + int h = getHMargin(); + int v = getVMargin(); + int x = bounds.x + h; + int y = bounds.y + v; + int height = bounds.height - v - v; + + Image img = getImage(); + if (img != null) { + Rectangle r = img.getBounds(); + gc.drawImage(img, x, y + (height - r.height) / 2); + x += r.width + SPACING; + } + + if (isSeparator() || !isEnabled()) { + gc.setForeground(ColorUtils.getColor("#a0a0a0")); //$NON-NLS-1$ + } else if (pressed) { + gc.setForeground(ColorUtils.getColor("#f0f0f0")); //$NON-NLS-1$ + } else { + gc.setForeground(ColorUtils.getColor("#000000")); //$NON-NLS-1$ + } + String text = getText(); + Point s = gc.textExtent(text); + gc.drawText(text, x, y + (height - s.y) / 2, true); + } + + protected String getText() { + if (action != null) { + String text = action.getText(); + if (text != null) { + text = MindMapUtils.trimSingleLine(text); + return text; + } + return ""; //$NON-NLS-1$ + } + return ">"; //$NON-NLS-1$ + } + + protected Image getImage() { + if (image == null && barExists()) { + if (action != null) { + ImageDescriptor imgDesc = null; + Display display = bar.getDisplay(); + if (!isEnabled()) { + imgDesc = action.getDisabledImageDescriptor(); + if (imgDesc != null) { + image = imgDesc.createImage(display); + } + if (image == null) { + imgDesc = action.getImageDescriptor(); + if (imgDesc != null) { + Image img = imgDesc.createImage(display); + image = new Image(display, img, + SWT.IMAGE_DISABLE); + img.dispose(); + } + } + } else { + imgDesc = action.getImageDescriptor(); + if (imgDesc != null) { + image = imgDesc.createImage(display); + } + } + } + } + return image; + } + + protected void run() { + if (action != null) + action.run(); + } + + public void update(String id) { + boolean textChange = id == null || IAction.TEXT.equals(id); + boolean tooltipChange = id == null + || IAction.TOOL_TIP_TEXT.equals(id); + boolean enabledChange = id == null || IAction.ENABLED.equals(id); + boolean imageChange = id == null || IAction.IMAGE.equals(id); + boolean needUpdateBar = textChange || imageChange; + + if (barExists()) { + bar.setRedraw(false); + } + + if (enabledChange) { + redraw(); + } + + if (tooltipChange) { + if (action != null && barExists()) + bar.setToolTipText(action.getToolTipText()); + } + + if (imageChange) { + if (image != null) { + image.dispose(); + image = null; + } + } + + if (needUpdateBar) { + if (barExists()) + bar.updateLayout(); + } + + if (barExists()) { + bar.setRedraw(true); + } + } + + public void propertyChange(PropertyChangeEvent event) { + update(event.getProperty()); + } + + public IAction getAction() { + return action; + } + + protected boolean barExists() { + return bar != null && !bar.isDisposed(); + } + + protected void releaseResources() { + if (image != null) { + image.dispose(); + image = null; + } + } + + } + + protected static class CrumbsBar extends Composite { + + private static final int SPACING = 1; + + private class CrumbsBarListener + implements PaintListener, MouseListener, MouseMoveListener, + MouseTrackListener, ControlListener, DisposeListener { + + private CrumbItem sourceItem = null; + + private CrumbItem targetItem = null; + + public void paintControl(PaintEvent e) { + GC gc = e.gc; + if (!Util.isMac()) { + gc.setBackground(e.display + .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + gc.fillRectangle(getBounds()); + } + + Rectangle clipping = gc.getClipping(); + for (CrumbItem item : items) { + if (clipping.intersects(item.getBounds())) { + item.paint(gc); + } + } + } + + public void mouseDoubleClick(MouseEvent e) { + } + + public void mouseDown(MouseEvent e) { + CrumbItem item = findItem(e.x, e.y); + if (item != null && item.isEnabled() && !item.isSeparator()) { + sourceItem = item; + item.setPressed(true); + } + } + + public void mouseUp(MouseEvent e) { + CrumbItem item = findItem(e.x, e.y); + CrumbItem source = sourceItem; + if (sourceItem != null) { + sourceItem.setPressed(false); + sourceItem = null; + } + if (item != null && item == source) { + item.run(); + } + } + + private void receiveTarget(int x, int y) { + CrumbItem item = findItem(x, y); + if (item != targetItem) { + if (targetItem != null && targetItem.isEnabled() + && !targetItem.isSeparator()) { + targetItem.setMouseOver(false); + } + targetItem = item; + if (item != null && item.isEnabled() + && !item.isSeparator()) { + if (sourceItem == null || item == sourceItem) { + item.setMouseOver(true); + } + } + String tooltip = null; + if (targetItem != null) { + IAction action = targetItem.getAction(); + if (action != null) { + tooltip = action.getToolTipText(); + } + } + setToolTipText(tooltip); + } + } + + public void mouseMove(MouseEvent e) { + receiveTarget(e.x, e.y); + } + + public void mouseEnter(MouseEvent e) { + receiveTarget(e.x, e.y); + } + + public void mouseExit(MouseEvent e) { + receiveTarget(e.x, e.y); + } + + public void mouseHover(MouseEvent e) { + receiveTarget(e.x, e.y); + } + + public void controlMoved(ControlEvent e) { + updateLayout(); + } + + public void controlResized(ControlEvent e) { + updateLayout(); + } + + public void widgetDisposed(DisposeEvent e) { + releaseItems(); + } + + } + + private List items = new ArrayList(); + + public CrumbsBar(Composite parent, int style) { + super(parent, style); + CrumbsBarListener eventHandler = new CrumbsBarListener(); + addPaintListener(eventHandler); + addMouseListener(eventHandler); + addMouseMoveListener(eventHandler); + addMouseTrackListener(eventHandler); + addControlListener(eventHandler); + setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, + -1)); + } + + private void releaseItems() { + for (CrumbItem item : items) { + item.releaseResources(); + } + } + + protected void redraw(CrumbItem item) { + checkWidget(); + Rectangle r = item.getBounds(); + redraw(r.x, r.y, r.width, r.height, false); + } + + public void addItem(CrumbItem item) { + checkWidget(); + addItem(item, -1); + } + + public void addItem(CrumbItem item, int index) { + checkWidget(); + items.remove(item); + if (index < 0) + items.add(item); + else + items.add(index, item); + itemAdded(item); + } + + public void removeItem(CrumbItem item) { + checkWidget(); + items.remove(item); + itemRemoved(item); + } + + private void itemAdded(CrumbItem item) { + item.setParent(this); + layout(); + } + + private void itemRemoved(CrumbItem item) { + item.setParent(null); + item.releaseResources(); + layout(); + } + + public void removeAllItems() { + checkWidget(); + setRedraw(false); + CrumbItem[] oldItems = getItems(); + items.clear(); + for (CrumbItem item : oldItems) { + itemRemoved(item); + } + layout(); + setRedraw(true); + } + + public CrumbItem[] getItems() { + checkWidget(); + return items.toArray(new CrumbItem[items.size()]); + } + + public CrumbItem findItem(Point p) { + checkWidget(); + return findItem(p.x, p.y); + } + + public CrumbItem findItem(int x, int y) { + checkWidget(); + for (CrumbItem item : items) { + Rectangle r = item.getBounds(); + if (r.contains(x, y)) + return item; + } + return null; + } + + public void setLayout(Layout layout) { + } + + public void layout(boolean changed) { + updateLayout(); + } + + public void layout(boolean changed, boolean all) { + updateLayout(); + } + + protected void updateLayout() { + checkWidget(); + Point p = new Point(0, 0); + int h = getSize().y; + for (CrumbItem item : items) { + Point s = item.getPrefSize(); + Rectangle r = new Rectangle(p.x, p.y + (h - s.y) / 2, s.x, s.y); + item.setBounds(r); + p.x += s.x + SPACING; + } + redraw(); + } + + public Point computeSize(int wHint, int hHint, boolean changed) { + checkWidget(); + if (wHint >= 0 && hHint >= 0) + return new Point(wHint, hHint); + + Point size = new Point(0, 0); + if (wHint >= 0) { + size.x = wHint; + } + for (CrumbItem item : items) { + Point s = item.getPrefSize(); + if (wHint < 0) { + if (size.x > 0) + size.x += SPACING; + size.x += s.x; + } + size.y = Math.max(size.y, s.y); + } + return size; + } + } + + class Crumbs extends PanelContribution implements IDrillDownTraceListener { + + private class QuickDrillUpAction extends PageAction { + + private ITopic newCentralTopic; + + public QuickDrillUpAction(IGraphicalEditorPage page, ITopic topic) { + super(page); + this.newCentralTopic = topic; + String title = topic.getTitleText(); + setText(title); + setToolTipText(NLS.bind( + MindMapMessages.BreadCrumb_ViewAsCentral_text, title)); + setImageDescriptor(MindMapUtils.getImageDescriptor(topic)); + } + + public void run() { + super.run(); + IGraphicalViewer viewer = getViewer(); + if (viewer != null) { + ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); + if (sheet != null) { + IMindMap newInput = new MindMap(sheet, newCentralTopic); + viewer.setInput(newInput); + if (viewer.getEditDomain() != null) { + viewer.getEditDomain().handleRequest( + MindMapUI.REQ_SELECT_CENTRAL, viewer); + } + } + } + } + + } + + private CrumbsBar bar = null; + + private IDrillDownTraceService service = null; + + public void createControl(Composite parent) { + if (!barExists()) { + bar = new CrumbsBar(parent, SWT.NONE); + } + } + + public Control getControl() { + return bar; + } + + public void update() { + boolean hasNewItems = service != null && service.canDrillUp(); + if (barExists()) { + bar.removeAllItems(); + bar.setRedraw(false); + if (hasNewItems) { + List topics = service.getCentralTopics(); + if (!topics.isEmpty()) { + for (int i = 0; i < topics.size(); i++) { + ITopic t = topics.get(i); + QuickDrillUpAction action = new QuickDrillUpAction( + getPage(), t); + if (i == topics.size() - 1) { + action.setEnabled(false); + action.setImageDescriptor(null); + action.setToolTipText(NLS.bind( + MindMapMessages.BreadCrumb_CurrentCentral_text, + action.newCentralTopic.getTitleText())); + } + + bar.addItem(new CrumbItem(action)); + if (i < topics.size() - 1) { + bar.addItem(new CrumbItem()); + } + } + } + } + bar.setRedraw(true); + setVisible(hasNewItems); + } + } + + private boolean barExists() { + return bar != null && !bar.isDisposed(); + } + + public void traceChanged(IDrillDownTraceService traceService) { + update(); + } + + public void setTraceService(IDrillDownTraceService service) { + if (service == this.service) + return; + + if (this.service != null) { + this.service.removeTraceListener(this); + } + this.service = service; + if (service != null) { + service.addTraceListener(this); + } + update(); + } + + } + + private Crumbs crumbs = null; + + protected void init(IPanel panel) { + super.init(panel); + crumbs = new Crumbs(); + crumbs.setVisible(false); + panel.addContribution(IPanel.TOP, crumbs); + } + + public void setViewer(IGraphicalViewer viewer) { + super.setViewer(viewer); + + IDrillDownTraceService traceService = (IDrillDownTraceService) viewer + .getService(IDrillDownTraceService.class); + crumbs.setTraceService(traceService); + } + + public void dispose() { + crumbs.setTraceService(null); + super.dispose(); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePopupPreviewHelper.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePopupPreviewHelper.java index 9d3fafafe..56644deb8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePopupPreviewHelper.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapEditorPagePopupPreviewHelper.java @@ -1,60 +1,60 @@ -package org.xmind.ui.internal.editor; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.custom.CTabFolder; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.ui.editor.GraphicalEditorPagePopupPreviewHelper; -import org.xmind.gef.ui.editor.IGraphicalEditor; - -public class MindMapEditorPagePopupPreviewHelper - extends GraphicalEditorPagePopupPreviewHelper { - - private static final int MIN_PREVIEW_WIDTH = 600; - - private static final int MIN_PREVIEW_HEIGHT = 600; - - public MindMapEditorPagePopupPreviewHelper(IGraphicalEditor editor, - CTabFolder tabFolder) { - super(editor, tabFolder); - } - - protected Rectangle calcContentsBounds(IFigure contents, - IGraphicalViewer viewer) { - Rectangle bounds = super.calcContentsBounds(contents, viewer); - int max = Math.max(bounds.width, bounds.height) + 50; - - int newWidth = bounds.width; - if (newWidth < MIN_PREVIEW_WIDTH) { - newWidth = MIN_PREVIEW_WIDTH; - } - if (newWidth < max) { - newWidth = max; - } - - if (newWidth != bounds.width) { - int ex = (newWidth - bounds.width) / 2; - Rectangle b = contents.getBounds(); - int right = bounds.x + bounds.width; - bounds.x = Math.max(b.x, bounds.x - ex); - bounds.width = Math.min(b.x + b.width, right + ex) - bounds.x; - } - - int newHeight = bounds.height; - if (newHeight < MIN_PREVIEW_HEIGHT) { - newHeight = MIN_PREVIEW_HEIGHT; - } - if (newHeight < max) { - newHeight = max; - } - if (newHeight != bounds.height) { - int ex = (newHeight - bounds.height) / 2; - Rectangle b = contents.getBounds(); - int bottom = bounds.y + bounds.height; - bounds.y = Math.max(b.y, bounds.y - ex); - bounds.height = Math.min(b.y + b.height, bottom + ex) - bounds.y; - } - return bounds; - } - +package org.xmind.ui.internal.editor; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.custom.CTabFolder; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ui.editor.GraphicalEditorPagePopupPreviewHelper; +import org.xmind.gef.ui.editor.IGraphicalEditor; + +public class MindMapEditorPagePopupPreviewHelper + extends GraphicalEditorPagePopupPreviewHelper { + + private static final int MIN_PREVIEW_WIDTH = 600; + + private static final int MIN_PREVIEW_HEIGHT = 600; + + public MindMapEditorPagePopupPreviewHelper(IGraphicalEditor editor, + CTabFolder tabFolder) { + super(editor, tabFolder); + } + + protected Rectangle calcContentsBounds(IFigure contents, + IGraphicalViewer viewer) { + Rectangle bounds = super.calcContentsBounds(contents, viewer); + int max = Math.max(bounds.width, bounds.height) + 50; + + int newWidth = bounds.width; + if (newWidth < MIN_PREVIEW_WIDTH) { + newWidth = MIN_PREVIEW_WIDTH; + } + if (newWidth < max) { + newWidth = max; + } + + if (newWidth != bounds.width) { + int ex = (newWidth - bounds.width) / 2; + Rectangle b = contents.getBounds(); + int right = bounds.x + bounds.width; + bounds.x = Math.max(b.x, bounds.x - ex); + bounds.width = Math.min(b.x + b.width, right + ex) - bounds.x; + } + + int newHeight = bounds.height; + if (newHeight < MIN_PREVIEW_HEIGHT) { + newHeight = MIN_PREVIEW_HEIGHT; + } + if (newHeight < max) { + newHeight = max; + } + if (newHeight != bounds.height) { + int ex = (newHeight - bounds.height) / 2; + Rectangle b = contents.getBounds(); + int bottom = bounds.y + bounds.height; + bounds.y = Math.max(b.y, bounds.y - ex); + bounds.height = Math.min(b.y + b.height, bottom + ex) - bounds.y; + } + return bounds; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapFindReplaceOperationProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapFindReplaceOperationProvider.java index 72c172c46..e40f305c0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapFindReplaceOperationProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapFindReplaceOperationProvider.java @@ -1,891 +1,891 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.widgets.Display; -import org.xmind.core.ITitled; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.AbstractTool; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.findreplace.AbstractFindReplaceOperationProvider; -import org.xmind.ui.internal.tools.LabelEditTool; -import org.xmind.ui.mindmap.IBoundaryPart; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ILabelPart; -import org.xmind.ui.mindmap.IRelationshipPart; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.texteditor.FloatingTextEditTool; -import org.xmind.ui.texteditor.FloatingTextEditor; -import org.xmind.ui.tools.TitleEditTool; -import org.xmind.ui.util.MindMapUtils; - -/** - * @author Frank Shaka - */ -public class MindMapFindReplaceOperationProvider extends - AbstractFindReplaceOperationProvider { - - private static final int PROP_TITLE = 1; - - private static final int PROP_LABEL = 2; - -// private static final int PROP_NOTES = 3; - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# - * getContextName() - */ - public String getContextName() { - String title = editor.getTitle(); - IGraphicalEditorPage page = editor.getActivePageInstance(); - String pageTitle = page == null ? null : page.getPageTitle(); - if (pageTitle == null || "".equals(pageTitle)) { //$NON-NLS-1$ - return title; - } - return NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# - * getContextName(int, org.eclipse.swt.graphics.Font) - */ - public String getContextName(int maxWidth, Font font) { - String title = editor.getTitle(); - IGraphicalEditorPage page = editor.getActivePageInstance(); - String pageTitle = page == null ? null : page.getPageTitle(); - if (pageTitle == null || "".equals(pageTitle)) { //$NON-NLS-1$ - return constrainText(title, maxWidth, font); - } - String name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ - if (computeTextWidth(name, font) > maxWidth) { - int halfMaxWidth = (maxWidth - computeTextWidth(" - ", font)) / 2 - 1; //$NON-NLS-1$ - int w1 = computeTextWidth(title, font); - int w2 = computeTextWidth(pageTitle, font); - if (w1 > halfMaxWidth) { - title = constrainText(title, - Math.max(halfMaxWidth, halfMaxWidth * 2 - w2), font); - w1 = computeTextWidth(title, font); - } - name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ - if (computeTextWidth(name, font) > maxWidth) { - pageTitle = constrainText(pageTitle, - Math.max(halfMaxWidth, halfMaxWidth * 2 - w1), font); - } - name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ - } - return name; - } - - private class SearchResult { - - final String toFind; - - IPart part = null; - - int offset = -1; - - int propertyId = 0; - - /** - * @param host - * @param offset - * @param isInNotes - */ - public SearchResult(String toFind) { - super(); - this.toFind = toFind; - } - - public boolean found() { - if (part == null) - return false; -// if (part instanceof ITopicPart) { -// if (propertyId == PROP_NOTES) -// return true; -// } - return offset >= 0; - } - - public boolean sameLocation(SearchResult that) { - if (that == null) - return false; - if (this.part != that.part) - return false; -// if (this.propertyId == PROP_NOTES) -// return that.propertyId == PROP_NOTES; - return this.propertyId == that.propertyId - && this.offset == that.offset; - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (!(obj instanceof SearchResult)) - return false; - SearchResult that = (SearchResult) obj; - return (this.toFind == that.toFind || (this.toFind != null && this.toFind - .equals(that.toFind))) && sameLocation(that); - } - - } - - private IGraphicalEditor editor; - - private SearchResult result = null; - -// private boolean findingInNotes = false; - - /** - * - */ - public MindMapFindReplaceOperationProvider(IGraphicalEditor editor) { - this.editor = editor; - } - - protected IPart getCurrentPart() { - IGraphicalViewer viewer = getActiveViewer(); - if (viewer != null) { - IPart part = viewer.getFocusedPart(); - if (part != null) - return part; - } - return getCurrentCentralTopicPart(); - } - - /** - * @return - */ - private IPart getCurrentCentralTopicPart() { - IGraphicalViewer viewer = getActiveViewer(); - if (viewer != null) - return (ITopicPart) viewer.getAdapter(ITopicPart.class); - return null; - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canFind(java.lang.String) - */ - public boolean canFind(String toFind) { - return getCurrentPart() != null; - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canReplace(java.lang.String, - * java.lang.String) - */ - public boolean canReplace(String toFind, String toReplaceWith) { - return canFind(toFind); - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#findAll(java.lang.String) - */ - @Override - protected boolean findAll(String toFind) { - List result = findAllParts(toFind); - select(result); - return !result.isEmpty(); - } - -// @Override -// public boolean find(String toFind) { -// if (findingInNotes) -// return false; -// return super.find(toFind); -// } - - /** - * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#findNext(java.lang.String) - */ - @Override - protected boolean findNext(String toFind) { - SearchResult start = getStartingLocation(); - SearchResult newResult = new SearchResult(toFind); - findNext(newResult, start); - result = newResult; - return result.found() && select(newResult); - } - - private void findNext(SearchResult result, SearchResult start) { - findNextInProperty(result, start); - SearchResult next = start; - while (!result.found()) { - next = getNextProperty(next); - if (next == null - || (next.part == start.part && next.propertyId == start.propertyId)) - break; - findNextInProperty(result, next); - } - } - - private SearchResult getNextProperty(SearchResult start) { - SearchResult result = new SearchResult(start.toFind); - if (start.part instanceof ITopicPart) { - if (start.propertyId == PROP_TITLE) { - result.part = start.part; - result.propertyId = PROP_LABEL; - } else if (start.propertyId == PROP_LABEL) { -// result.part = start.part; -// result.propertyId = PROP_NOTES; -// } else { - result.part = getNextPart(start.part); - result.propertyId = PROP_TITLE; - } - } else { - result.part = getNextPart(start.part); - result.propertyId = PROP_TITLE; - } - result.offset = getStartingOffset(result); - return result; - } - - private void findNextInProperty(SearchResult result, SearchResult start) { - String text = getPropertyText(start.part, start.propertyId); - if (text != null) { - int offset = indexOf(text, result.toFind, start.offset); - if (offset >= 0) { - result.part = start.part; - result.propertyId = start.propertyId; -// if (start.propertyId != PROP_NOTES) { - result.offset = offset; -// } - } - } - } - - private boolean select(SearchResult result) { - if (result.found()) { - int pageIndex = getPageIndex(result.part); - if (pageIndex >= 0) { - if (pageIndex != editor.getActivePage()) - editor.setActivePage(pageIndex); - IGraphicalEditorPage page = editor.getActivePageInstance(); - if (page != null) { - EditDomain domain = page.getEditDomain(); - IGraphicalViewer viewer = page.getViewer(); - if (result.propertyId == PROP_TITLE) { - editAndSelect(result, domain, viewer, GEF.REQ_EDIT); - } else if (result.propertyId == PROP_LABEL) { - editAndSelect(result, domain, viewer, - MindMapUI.REQ_EDIT_LABEL); -// } else if (result.propertyId == PROP_NOTES) { -// return findInNotes(result, page); - } - return true; - } - } - } - return false; - } - -// private boolean findInNotes(final SearchResult result, -// IGraphicalEditorPage page) { -// page.getEditDomain().handleRequest(GEF.REQ_CANCEL, page.getViewer()); -// page.getViewer() -// .setSelection( -// new StructuredSelection(MindMapUtils -// .getRealModel(result.part)), true); -// final IViewPart[] notesView = new IViewPart[1]; -// SafeRunner.run(new SafeRunnable() { -// public void run() throws Exception { -// notesView[0] = editor.getSite().getPage().showView( -// MindMapUI.VIEW_NOTES); -// } -// }); -// if (notesView[0] != null) { -// ITextViewer textViewer = (ITextViewer) notesView[0] -// .getAdapter(ITextViewer.class); -// if (textViewer != null) { -// textViewer.setSelectedRange(isForward() ? 0 : textViewer -// .getDocument().getLength(), 0); -// } -// IFindReplaceOperationProvider frProvider = (IFindReplaceOperationProvider) notesView[0] -// .getAdapter(IFindReplaceOperationProvider.class); -// if (frProvider != null) { -// findingInNotes = true; -// try { -// return frProvider.find(result.toFind); -// } finally { -// findingInNotes = false; -// } -// } -// } -// return false; -// } - - private void editAndSelect(final SearchResult result, - final EditDomain domain, final IGraphicalViewer viewer, - final String requestType) { - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - Request request = new Request(requestType) - .setPrimaryTarget(result.part) - .setDomain(domain) - .setViewer(getActiveViewer()) - .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE) - .setParameter( - GEF.PARAM_TEXT_SELECTION, - new TextSelection(result.offset, result.toFind - .length())); - domain.handleRequest(request); - } - }); - } - - private SearchResult getStartingLocation() { - SearchResult start = new SearchResult(result == null ? null - : result.toFind); - start.part = getCurrentPart(); - ITool tool = editor.getActivePageInstance().getEditDomain() - .getActiveTool(); - if (tool instanceof LabelEditTool) { - start.propertyId = PROP_LABEL; - start.offset = getStartingOffset((LabelEditTool) tool); - } else if (tool instanceof TitleEditTool) { - start.propertyId = PROP_TITLE; - start.offset = getStartingOffset((TitleEditTool) tool); -// } else if (result != null && result.part == start.part -// && result.propertyId == PROP_NOTES) { -// start.part = getNextPart(start.part); -// start.propertyId = PROP_TITLE; -// start.offset = getStartingOffset(start); - } else { - start.propertyId = PROP_TITLE; - start.offset = getStartingOffset(start); - } - return start; - } - - private int getStartingOffset(FloatingTextEditTool tool) { - ITextSelection selection = tool.getTextSelection(); - if (isForward()) { - return selection.getOffset() + selection.getLength(); - } else { - return selection.getOffset(); - } - } - - private int getStartingOffset(SearchResult result) { - String text = getPropertyText(result.part, result.propertyId); - return text == null ? -1 : getNewOffset(text); - } - - private String getPropertyText(IPart part, int propertyId) { -// if (propertyId == PROP_NOTES) { -// if (part instanceof ITopicPart) { -// INotes notes = ((ITopicPart) part).getTopic().getNotes(); -// INotesContent content = notes.getContent(INotes.PLAIN); -// if (content instanceof IPlainNotesContent) { -// return ((IPlainNotesContent) content).getTextContent(); -// } -// } -// return null; -// } - if (propertyId == PROP_LABEL) { - ILabelPart label = ((ITopicPart) part).getOwnerBranch().getLabel(); - return label == null ? null : label.getLabelText(); - } - - Object model = MindMapUtils.getRealModel(part); - if (model instanceof ITitled && ((ITitled) model).hasTitle()) { - return ((ITitled) model).getTitleText(); - } - - ITitled titled = (ITitled) part.getAdapter(ITitled.class); - if (titled != null && titled.hasTitle()) { - return titled.getTitleText(); - } - - return (String) part.getAdapter(String.class); - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#replaceAll(java.lang.String, - * java.lang.String) - */ - @Override - protected boolean replaceAll(String toFind, String toReplaceWith) { - boolean found = findAll(toFind); - if (found) { - EditDomain domain = getCurrentDomain(); - if (domain == null) { - found = false; - } else { - Boolean ignoreCase = Boolean - .valueOf((getParameter() & PARAM_CASE_SENSITIVE) == 0); - domain.handleRequest(new Request(MindMapUI.REQ_REPLACE_ALL) - .setParameter(GEF.PARAM_TEXT, toFind) - .setParameter(MindMapUI.PARAM_REPLACEMENT, - toReplaceWith) - .setParameter(MindMapUI.PARAM_IGNORE_CASE, ignoreCase) - .setDomain(domain).setViewer(getActiveViewer())); - } - } - return found; - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#replaceNext(java.lang.String, - * java.lang.String) - */ - @Override - protected boolean replaceNext(String toFind, String toReplaceWith) { - EditDomain domain = getCurrentDomain(); - if (domain != null) { - ITool tool = domain.getActiveTool(); - if (tool != null && tool instanceof FloatingTextEditTool) { - FloatingTextEditor textEditor = ((FloatingTextEditTool) tool) - .getEditor(); - if (textEditor != null && !textEditor.isClosed()) { - textEditor.replaceText(toReplaceWith, true); - textEditor.close(true); - } - } - } - return findNext(toFind); - } - - /** - * @param toFind - * @return - */ - protected List findAllParts(String toFind) { - return findAllParts(toFind, getCurrentPart(), null, - new ArrayList()); - } - - protected List findAllParts(String toFind, IPart current, - IPart start, List result) { - if (start == null) - start = current; - String text = getText(current); - int index = indexOf(text, toFind, getNewOffset(text)); - if (index >= 0) { - result.add(current); - } - IPart next = getNextPart(current); - if (next != start) { - result = findAllParts(toFind, next, start, result); - } - return result; - } - - /** - * @param result - */ - protected boolean select(List result) { - if (isEditing(null)) { - getEditTool(null).handleRequest( - new Request(GEF.REQ_FINISH).setViewer(getActiveViewer())); - } - getActiveViewer().setSelection(new StructuredSelection(result), true); -// ITool selectTool = getDefaultTool(); -// if (selectTool == null) -// return false; -// selectTool -// .handleRequest(new Request(GEF.REQ_SELECT).setTargets(result)); - return true; - } - - protected String getText(IPart p) { - if (p == null) - return null; - - if (p instanceof ILabelPart) { - ILabelPart labelPart = (ILabelPart) p; - String text = labelPart.getLabelText(); - return text; - } - - ITitled titled = (ITitled) p.getAdapter(ITitled.class); - if (titled != null && titled.hasTitle()) { - return titled.getTitleText(); - } - return (String) p.getAdapter(String.class); - } - - private int getPageIndex(IPart part) { - Object input = part.getSite().getViewer().getInput(); - IGraphicalEditorPage page = editor.findPage(input); - return page == null ? editor.getActivePage() : page.getIndex(); - } - - private IPart getNextPart(IPart current) { - return isForward() ? getForwardPart(current) : getBackwardPart(current); - } - - /** - * @param current - * @return - */ - private IPart getBackwardPart(IPart current) { - if (!isCentral(current) || !isWorkbook()) { - IPart prev = findPrecedingPart(current); - if (prev != null && prev != current) - return prev; - if (!isWorkbook()) - return current; - } - int pageIndex = getPageIndex(current); - int pageCount = editor.getPageCount(); - if (pageIndex == 0) - pageIndex = pageCount - 1; - else - pageIndex--; - IGraphicalEditorPage page = editor.getPage(pageIndex); - IGraphicalViewer viewer = page.getViewer(); - IPart central = (IPart) viewer.getAdapter(ITopicPart.class); - if (central != null) { - IPart prev = findPrecedingPart(central); - if (prev != null && prev != central) - return prev; - } - return central; - } - - /** - * @param current - * @return - */ - private IPart getForwardPart(IPart current) { - IPart next = findSucceedingPart(current); - if (next != null && next != current - && (!isCentral(next) || !isWorkbook())) - return next; - if (!isWorkbook()) - return current; - int pageIndex = getPageIndex(current); - int pageCount = editor.getPageCount(); - if (pageIndex == pageCount - 1) - pageIndex = 0; - else - pageIndex++; - IGraphicalEditorPage page = editor.getPage(pageIndex); - IGraphicalViewer viewer = page.getViewer(); - return (IPart) viewer.getAdapter(ITopicPart.class); - } - - private IPart findSucceedingPart(IPart current) { - if (current instanceof ITopicPart) { - IPart next = firstBoundary(((ITopicPart) current).getOwnerBranch()); - if (next != null) - return next; - } else if (current instanceof IBoundaryPart) { - IPart next = nextBoundary((IBoundaryPart) current); - if (next != null) - return next; - return findNavNext(((IBoundaryPart) current).getOwnedBranch() - .getTopicPart()); - } else if (current instanceof IRelationshipPart) { - IPart next = nextRelationship((IRelationshipPart) current); - if (next != null) - return next; - return ((IRelationshipPart) current).getOwnerSheet() - .getCentralBranch().getTopicPart(); - } - IPart next = findNavNext(current); - if (current instanceof ITopicPart && isCentral(next)) { - IPart rel = firstRelationship((ISheetPart) current.getSite() - .getViewer().getAdapter(ISheetPart.class)); - if (rel != null) - return rel; - } - return next; - } - - private IPart findPrecedingPart(IPart current) { - if (current instanceof ITopicPart) { - if (isCentral(current)) { - IPart rel = lastRelationship((ISheetPart) current.getSite() - .getViewer().getAdapter(ISheetPart.class)); - if (rel != null) - return rel; - } - IPart prev = findNavPrev(current); - if (prev != current && prev instanceof ITopicPart) { - if (((ITopicPart) current).getOwnerBranch().getParentBranch() == ((ITopicPart) prev) - .getOwnerBranch()) { - IPart prevBoundary = lastBoundary(((ITopicPart) prev) - .getOwnerBranch()); - if (prevBoundary != null) - return prevBoundary; - } - } - return prev; - } else if (current instanceof IBoundaryPart) { - IPart prev = prevBoundary((IBoundaryPart) current); - if (prev != null) - return prev; - return ((IBoundaryPart) current).getOwnedBranch().getTopicPart(); - } else if (current instanceof IRelationshipPart) { - IPart prev = prevRelationship((IRelationshipPart) current); - if (prev != null) - return prev; - return findNavPrev(((IRelationshipPart) current).getOwnerSheet() - .getCentralBranch().getTopicPart()); - } - return null; - } - - private IPart findNavNext(IPart current) { - if (current.hasRole(GEF.ROLE_NAVIGABLE)) { - Request navRequest = new Request(GEF.REQ_NAV_NEXT); - navRequest.setPrimaryTarget(current); - IViewer viewer = current.getSite().getViewer(); - navRequest.setViewer(viewer); - current.handleRequest(navRequest, GEF.ROLE_NAVIGABLE); - Object result = navRequest.getResult(GEF.RESULT_NAVIGATION); - if (result instanceof IPart[]) { - IPart[] parts = (IPart[]) result; - if (parts.length > 0) { - IPart part = parts[0]; - return part; - } - } - } - return null; - } - - private IPart findNavPrev(IPart current) { - if (current.hasRole(GEF.ROLE_NAVIGABLE)) { - Request navRequest = new Request(GEF.REQ_NAV_PREV) - .setPrimaryTarget(current).setViewer( - current.getSite().getViewer()); - current.handleRequest(navRequest, GEF.ROLE_NAVIGABLE); - Object result = navRequest.getResult(GEF.RESULT_NAVIGATION); - if (result instanceof IPart[]) { - IPart[] parts = (IPart[]) result; - if (parts.length > 0) - return parts[0]; - } - } - return null; - } - - private IPart firstBoundary(IBranchPart branch) { - List boundaries = branch.getBoundaries(); - if (boundaries.isEmpty()) - return null; - int start = -1, end = -1; - IBoundaryPart first = null; - for (IBoundaryPart b : boundaries) { - int s = b.getBoundary().getStartIndex(); - int e = b.getBoundary().getEndIndex(); - if (start < 0 || s < start || (s == start && (end < 0 || e > end))) { - start = s; - end = e; - first = b; - } - } - return first; - } - - private IPart lastBoundary(IBranchPart branch) { - List boundaries = branch.getBoundaries(); - if (boundaries.isEmpty()) - return null; - int start = -1, end = -1; - IBoundaryPart last = null; - for (IBoundaryPart b : boundaries) { - int s = b.getBoundary().getStartIndex(); - int e = b.getBoundary().getEndIndex(); - if (start < 0 || s > start || (s == start && (end < 0 || e < end))) { - start = s; - end = e; - last = b; - } - } - return last; - } - - private IPart nextBoundary(IBoundaryPart boundary) { - List boundaries = boundary.getOwnedBranch() - .getBoundaries(); - int start0 = boundary.getBoundary().getStartIndex(); - int end0 = boundary.getBoundary().getEndIndex(); - int start = -1, end = -1; - IBoundaryPart next = null; - for (IBoundaryPart b : boundaries) { - if (b != boundary) { - int s = b.getBoundary().getStartIndex(); - int e = b.getBoundary().getEndIndex(); - if (s > start0 || (s == start0 && e < end0)) { - if (start < 0 || s < start - || (s == start && (end < 0 || e > end))) { - start = s; - end = e; - next = b; - } - } - } - } - return next; - } - - private IPart prevBoundary(IBoundaryPart boundary) { - List boundaries = boundary.getOwnedBranch() - .getBoundaries(); - int start0 = boundary.getBoundary().getStartIndex(); - int end0 = boundary.getBoundary().getEndIndex(); - int start = -1, end = -1; - IBoundaryPart next = null; - for (IBoundaryPart b : boundaries) { - if (b != boundary) { - int s = b.getBoundary().getStartIndex(); - int e = b.getBoundary().getEndIndex(); - if (s < start0 || (s == start0 && e > end0)) { - if (start < 0 || s > start - || (s == start && (end < 0 || e < end))) { - start = s; - end = e; - next = b; - } - } - } - } - return next; - } - - private List getRelationships(ISheetPart sheet) { - if (sheet != null) { - return sheet.getRelationships(); - } - return null; - } - - private IPart firstRelationship(ISheetPart sheet) { - List rels = getRelationships(sheet); - if (rels != null && !rels.isEmpty()) - return rels.get(0); - return null; - } - - private IPart lastRelationship(ISheetPart sheet) { - List rels = getRelationships(sheet); - if (rels != null && !rels.isEmpty()) - return rels.get(rels.size() - 1); - return null; - } - - private IPart nextRelationship(IRelationshipPart rel) { - List rels = getRelationships(rel.getOwnerSheet()); - if (rels != null && !rels.isEmpty()) { - int index = rels.indexOf(rel); - if (index >= 0 && index < rels.size() - 1) - return rels.get(index + 1); - } - return null; - } - - private IPart prevRelationship(IRelationshipPart rel) { - List rels = getRelationships(rel.getOwnerSheet()); - if (rels != null && !rels.isEmpty()) { - int index = rels.indexOf(rel); - if (index > 0) - return rels.get(index - 1); - } - return null; - } - - private boolean isCentral(IPart part) { - return part instanceof ITopicPart - && ((ITopicPart) part).getOwnerBranch().isCentral(); - } - - protected FloatingTextEditor getTextEditor(IPart part) { - ITool editTool = getEditTool(part); - if (editTool instanceof FloatingTextEditTool) { - return ((FloatingTextEditTool) editTool).getEditor(); - } - return null; - } - - protected boolean isEditing(IPart part) { - ITool editTool = getEditTool(part); - return editTool != null - && ((AbstractTool) editTool).getStatus() - .isStatus(GEF.ST_ACTIVE); - } - - protected ITool getEditTool(IPart part) { - EditDomain domain = getCurrentDomain(); - if (part instanceof ILabelPart) { - return domain == null ? null : domain - .getTool(MindMapUI.TOOL_EDIT_LABEL); - } else if (part instanceof IBoundaryPart - || part instanceof IRelationshipPart) { - return domain == null ? null : domain.getTool(GEF.TOOL_EDIT); - } else - return domain == null ? null : domain - .getTool(MindMapUI.TOOL_EDIT_TOPIC_TITLE); - - } - - /** - * @return - */ - protected ITool getDefaultTool() { - EditDomain domain = getCurrentDomain(); - return domain == null ? null : domain.getDefaultTool(); - } - - /** - * @return - */ - protected EditDomain getCurrentDomain() { - IGraphicalEditorPage page = getActivePage(); - return page == null ? null : page.getEditDomain(); - } - - /** - * @return - */ - protected IGraphicalViewer getActiveViewer() { - IGraphicalEditorPage page = getActivePage(); - return page == null ? null : page.getViewer(); - } - - /** - * @return - */ - private IGraphicalEditorPage getActivePage() { - return editor.getActivePageInstance(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.ITitled; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.AbstractTool; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.findreplace.AbstractFindReplaceOperationProvider; +import org.xmind.ui.internal.tools.LabelEditTool; +import org.xmind.ui.mindmap.IBoundaryPart; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ILabelPart; +import org.xmind.ui.mindmap.IRelationshipPart; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.texteditor.FloatingTextEditTool; +import org.xmind.ui.texteditor.FloatingTextEditor; +import org.xmind.ui.tools.TitleEditTool; +import org.xmind.ui.util.MindMapUtils; + +/** + * @author Frank Shaka + */ +public class MindMapFindReplaceOperationProvider extends + AbstractFindReplaceOperationProvider { + + private static final int PROP_TITLE = 1; + + private static final int PROP_LABEL = 2; + +// private static final int PROP_NOTES = 3; + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# + * getContextName() + */ + public String getContextName() { + String title = editor.getTitle(); + IGraphicalEditorPage page = editor.getActivePageInstance(); + String pageTitle = page == null ? null : page.getPageTitle(); + if (pageTitle == null || "".equals(pageTitle)) { //$NON-NLS-1$ + return title; + } + return NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# + * getContextName(int, org.eclipse.swt.graphics.Font) + */ + public String getContextName(int maxWidth, Font font) { + String title = editor.getTitle(); + IGraphicalEditorPage page = editor.getActivePageInstance(); + String pageTitle = page == null ? null : page.getPageTitle(); + if (pageTitle == null || "".equals(pageTitle)) { //$NON-NLS-1$ + return constrainText(title, maxWidth, font); + } + String name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ + if (computeTextWidth(name, font) > maxWidth) { + int halfMaxWidth = (maxWidth - computeTextWidth(" - ", font)) / 2 - 1; //$NON-NLS-1$ + int w1 = computeTextWidth(title, font); + int w2 = computeTextWidth(pageTitle, font); + if (w1 > halfMaxWidth) { + title = constrainText(title, + Math.max(halfMaxWidth, halfMaxWidth * 2 - w2), font); + w1 = computeTextWidth(title, font); + } + name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ + if (computeTextWidth(name, font) > maxWidth) { + pageTitle = constrainText(pageTitle, + Math.max(halfMaxWidth, halfMaxWidth * 2 - w1), font); + } + name = NLS.bind("{0} - {1}", title, pageTitle); //$NON-NLS-1$ + } + return name; + } + + private class SearchResult { + + final String toFind; + + IPart part = null; + + int offset = -1; + + int propertyId = 0; + + /** + * @param host + * @param offset + * @param isInNotes + */ + public SearchResult(String toFind) { + super(); + this.toFind = toFind; + } + + public boolean found() { + if (part == null) + return false; +// if (part instanceof ITopicPart) { +// if (propertyId == PROP_NOTES) +// return true; +// } + return offset >= 0; + } + + public boolean sameLocation(SearchResult that) { + if (that == null) + return false; + if (this.part != that.part) + return false; +// if (this.propertyId == PROP_NOTES) +// return that.propertyId == PROP_NOTES; + return this.propertyId == that.propertyId + && this.offset == that.offset; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (!(obj instanceof SearchResult)) + return false; + SearchResult that = (SearchResult) obj; + return (this.toFind == that.toFind || (this.toFind != null && this.toFind + .equals(that.toFind))) && sameLocation(that); + } + + } + + private IGraphicalEditor editor; + + private SearchResult result = null; + +// private boolean findingInNotes = false; + + /** + * + */ + public MindMapFindReplaceOperationProvider(IGraphicalEditor editor) { + this.editor = editor; + } + + protected IPart getCurrentPart() { + IGraphicalViewer viewer = getActiveViewer(); + if (viewer != null) { + IPart part = viewer.getFocusedPart(); + if (part != null) + return part; + } + return getCurrentCentralTopicPart(); + } + + /** + * @return + */ + private IPart getCurrentCentralTopicPart() { + IGraphicalViewer viewer = getActiveViewer(); + if (viewer != null) + return (ITopicPart) viewer.getAdapter(ITopicPart.class); + return null; + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canFind(java.lang.String) + */ + public boolean canFind(String toFind) { + return getCurrentPart() != null; + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canReplace(java.lang.String, + * java.lang.String) + */ + public boolean canReplace(String toFind, String toReplaceWith) { + return canFind(toFind); + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#findAll(java.lang.String) + */ + @Override + protected boolean findAll(String toFind) { + List result = findAllParts(toFind); + select(result); + return !result.isEmpty(); + } + +// @Override +// public boolean find(String toFind) { +// if (findingInNotes) +// return false; +// return super.find(toFind); +// } + + /** + * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#findNext(java.lang.String) + */ + @Override + protected boolean findNext(String toFind) { + SearchResult start = getStartingLocation(); + SearchResult newResult = new SearchResult(toFind); + findNext(newResult, start); + result = newResult; + return result.found() && select(newResult); + } + + private void findNext(SearchResult result, SearchResult start) { + findNextInProperty(result, start); + SearchResult next = start; + while (!result.found()) { + next = getNextProperty(next); + if (next == null + || (next.part == start.part && next.propertyId == start.propertyId)) + break; + findNextInProperty(result, next); + } + } + + private SearchResult getNextProperty(SearchResult start) { + SearchResult result = new SearchResult(start.toFind); + if (start.part instanceof ITopicPart) { + if (start.propertyId == PROP_TITLE) { + result.part = start.part; + result.propertyId = PROP_LABEL; + } else if (start.propertyId == PROP_LABEL) { +// result.part = start.part; +// result.propertyId = PROP_NOTES; +// } else { + result.part = getNextPart(start.part); + result.propertyId = PROP_TITLE; + } + } else { + result.part = getNextPart(start.part); + result.propertyId = PROP_TITLE; + } + result.offset = getStartingOffset(result); + return result; + } + + private void findNextInProperty(SearchResult result, SearchResult start) { + String text = getPropertyText(start.part, start.propertyId); + if (text != null) { + int offset = indexOf(text, result.toFind, start.offset); + if (offset >= 0) { + result.part = start.part; + result.propertyId = start.propertyId; +// if (start.propertyId != PROP_NOTES) { + result.offset = offset; +// } + } + } + } + + private boolean select(SearchResult result) { + if (result.found()) { + int pageIndex = getPageIndex(result.part); + if (pageIndex >= 0) { + if (pageIndex != editor.getActivePage()) + editor.setActivePage(pageIndex); + IGraphicalEditorPage page = editor.getActivePageInstance(); + if (page != null) { + EditDomain domain = page.getEditDomain(); + IGraphicalViewer viewer = page.getViewer(); + if (result.propertyId == PROP_TITLE) { + editAndSelect(result, domain, viewer, GEF.REQ_EDIT); + } else if (result.propertyId == PROP_LABEL) { + editAndSelect(result, domain, viewer, + MindMapUI.REQ_EDIT_LABEL); +// } else if (result.propertyId == PROP_NOTES) { +// return findInNotes(result, page); + } + return true; + } + } + } + return false; + } + +// private boolean findInNotes(final SearchResult result, +// IGraphicalEditorPage page) { +// page.getEditDomain().handleRequest(GEF.REQ_CANCEL, page.getViewer()); +// page.getViewer() +// .setSelection( +// new StructuredSelection(MindMapUtils +// .getRealModel(result.part)), true); +// final IViewPart[] notesView = new IViewPart[1]; +// SafeRunner.run(new SafeRunnable() { +// public void run() throws Exception { +// notesView[0] = editor.getSite().getPage().showView( +// MindMapUI.VIEW_NOTES); +// } +// }); +// if (notesView[0] != null) { +// ITextViewer textViewer = (ITextViewer) notesView[0] +// .getAdapter(ITextViewer.class); +// if (textViewer != null) { +// textViewer.setSelectedRange(isForward() ? 0 : textViewer +// .getDocument().getLength(), 0); +// } +// IFindReplaceOperationProvider frProvider = (IFindReplaceOperationProvider) notesView[0] +// .getAdapter(IFindReplaceOperationProvider.class); +// if (frProvider != null) { +// findingInNotes = true; +// try { +// return frProvider.find(result.toFind); +// } finally { +// findingInNotes = false; +// } +// } +// } +// return false; +// } + + private void editAndSelect(final SearchResult result, + final EditDomain domain, final IGraphicalViewer viewer, + final String requestType) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + Request request = new Request(requestType) + .setPrimaryTarget(result.part) + .setDomain(domain) + .setViewer(getActiveViewer()) + .setParameter(GEF.PARAM_FOCUS, Boolean.FALSE) + .setParameter( + GEF.PARAM_TEXT_SELECTION, + new TextSelection(result.offset, result.toFind + .length())); + domain.handleRequest(request); + } + }); + } + + private SearchResult getStartingLocation() { + SearchResult start = new SearchResult(result == null ? null + : result.toFind); + start.part = getCurrentPart(); + ITool tool = editor.getActivePageInstance().getEditDomain() + .getActiveTool(); + if (tool instanceof LabelEditTool) { + start.propertyId = PROP_LABEL; + start.offset = getStartingOffset((LabelEditTool) tool); + } else if (tool instanceof TitleEditTool) { + start.propertyId = PROP_TITLE; + start.offset = getStartingOffset((TitleEditTool) tool); +// } else if (result != null && result.part == start.part +// && result.propertyId == PROP_NOTES) { +// start.part = getNextPart(start.part); +// start.propertyId = PROP_TITLE; +// start.offset = getStartingOffset(start); + } else { + start.propertyId = PROP_TITLE; + start.offset = getStartingOffset(start); + } + return start; + } + + private int getStartingOffset(FloatingTextEditTool tool) { + ITextSelection selection = tool.getTextSelection(); + if (isForward()) { + return selection.getOffset() + selection.getLength(); + } else { + return selection.getOffset(); + } + } + + private int getStartingOffset(SearchResult result) { + String text = getPropertyText(result.part, result.propertyId); + return text == null ? -1 : getNewOffset(text); + } + + private String getPropertyText(IPart part, int propertyId) { +// if (propertyId == PROP_NOTES) { +// if (part instanceof ITopicPart) { +// INotes notes = ((ITopicPart) part).getTopic().getNotes(); +// INotesContent content = notes.getContent(INotes.PLAIN); +// if (content instanceof IPlainNotesContent) { +// return ((IPlainNotesContent) content).getTextContent(); +// } +// } +// return null; +// } + if (propertyId == PROP_LABEL) { + ILabelPart label = ((ITopicPart) part).getOwnerBranch().getLabel(); + return label == null ? null : label.getLabelText(); + } + + Object model = MindMapUtils.getRealModel(part); + if (model instanceof ITitled && ((ITitled) model).hasTitle()) { + return ((ITitled) model).getTitleText(); + } + + ITitled titled = (ITitled) part.getAdapter(ITitled.class); + if (titled != null && titled.hasTitle()) { + return titled.getTitleText(); + } + + return (String) part.getAdapter(String.class); + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#replaceAll(java.lang.String, + * java.lang.String) + */ + @Override + protected boolean replaceAll(String toFind, String toReplaceWith) { + boolean found = findAll(toFind); + if (found) { + EditDomain domain = getCurrentDomain(); + if (domain == null) { + found = false; + } else { + Boolean ignoreCase = Boolean + .valueOf((getParameter() & PARAM_CASE_SENSITIVE) == 0); + domain.handleRequest(new Request(MindMapUI.REQ_REPLACE_ALL) + .setParameter(GEF.PARAM_TEXT, toFind) + .setParameter(MindMapUI.PARAM_REPLACEMENT, + toReplaceWith) + .setParameter(MindMapUI.PARAM_IGNORE_CASE, ignoreCase) + .setDomain(domain).setViewer(getActiveViewer())); + } + } + return found; + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.AbstractFindReplaceOperationProvider#replaceNext(java.lang.String, + * java.lang.String) + */ + @Override + protected boolean replaceNext(String toFind, String toReplaceWith) { + EditDomain domain = getCurrentDomain(); + if (domain != null) { + ITool tool = domain.getActiveTool(); + if (tool != null && tool instanceof FloatingTextEditTool) { + FloatingTextEditor textEditor = ((FloatingTextEditTool) tool) + .getEditor(); + if (textEditor != null && !textEditor.isClosed()) { + textEditor.replaceText(toReplaceWith, true); + textEditor.close(true); + } + } + } + return findNext(toFind); + } + + /** + * @param toFind + * @return + */ + protected List findAllParts(String toFind) { + return findAllParts(toFind, getCurrentPart(), null, + new ArrayList()); + } + + protected List findAllParts(String toFind, IPart current, + IPart start, List result) { + if (start == null) + start = current; + String text = getText(current); + int index = indexOf(text, toFind, getNewOffset(text)); + if (index >= 0) { + result.add(current); + } + IPart next = getNextPart(current); + if (next != start) { + result = findAllParts(toFind, next, start, result); + } + return result; + } + + /** + * @param result + */ + protected boolean select(List result) { + if (isEditing(null)) { + getEditTool(null).handleRequest( + new Request(GEF.REQ_FINISH).setViewer(getActiveViewer())); + } + getActiveViewer().setSelection(new StructuredSelection(result), true); +// ITool selectTool = getDefaultTool(); +// if (selectTool == null) +// return false; +// selectTool +// .handleRequest(new Request(GEF.REQ_SELECT).setTargets(result)); + return true; + } + + protected String getText(IPart p) { + if (p == null) + return null; + + if (p instanceof ILabelPart) { + ILabelPart labelPart = (ILabelPart) p; + String text = labelPart.getLabelText(); + return text; + } + + ITitled titled = (ITitled) p.getAdapter(ITitled.class); + if (titled != null && titled.hasTitle()) { + return titled.getTitleText(); + } + return (String) p.getAdapter(String.class); + } + + private int getPageIndex(IPart part) { + Object input = part.getSite().getViewer().getInput(); + IGraphicalEditorPage page = editor.findPage(input); + return page == null ? editor.getActivePage() : page.getIndex(); + } + + private IPart getNextPart(IPart current) { + return isForward() ? getForwardPart(current) : getBackwardPart(current); + } + + /** + * @param current + * @return + */ + private IPart getBackwardPart(IPart current) { + if (!isCentral(current) || !isWorkbook()) { + IPart prev = findPrecedingPart(current); + if (prev != null && prev != current) + return prev; + if (!isWorkbook()) + return current; + } + int pageIndex = getPageIndex(current); + int pageCount = editor.getPageCount(); + if (pageIndex == 0) + pageIndex = pageCount - 1; + else + pageIndex--; + IGraphicalEditorPage page = editor.getPage(pageIndex); + IGraphicalViewer viewer = page.getViewer(); + IPart central = (IPart) viewer.getAdapter(ITopicPart.class); + if (central != null) { + IPart prev = findPrecedingPart(central); + if (prev != null && prev != central) + return prev; + } + return central; + } + + /** + * @param current + * @return + */ + private IPart getForwardPart(IPart current) { + IPart next = findSucceedingPart(current); + if (next != null && next != current + && (!isCentral(next) || !isWorkbook())) + return next; + if (!isWorkbook()) + return current; + int pageIndex = getPageIndex(current); + int pageCount = editor.getPageCount(); + if (pageIndex == pageCount - 1) + pageIndex = 0; + else + pageIndex++; + IGraphicalEditorPage page = editor.getPage(pageIndex); + IGraphicalViewer viewer = page.getViewer(); + return (IPart) viewer.getAdapter(ITopicPart.class); + } + + private IPart findSucceedingPart(IPart current) { + if (current instanceof ITopicPart) { + IPart next = firstBoundary(((ITopicPart) current).getOwnerBranch()); + if (next != null) + return next; + } else if (current instanceof IBoundaryPart) { + IPart next = nextBoundary((IBoundaryPart) current); + if (next != null) + return next; + return findNavNext(((IBoundaryPart) current).getOwnedBranch() + .getTopicPart()); + } else if (current instanceof IRelationshipPart) { + IPart next = nextRelationship((IRelationshipPart) current); + if (next != null) + return next; + return ((IRelationshipPart) current).getOwnerSheet() + .getCentralBranch().getTopicPart(); + } + IPart next = findNavNext(current); + if (current instanceof ITopicPart && isCentral(next)) { + IPart rel = firstRelationship((ISheetPart) current.getSite() + .getViewer().getAdapter(ISheetPart.class)); + if (rel != null) + return rel; + } + return next; + } + + private IPart findPrecedingPart(IPart current) { + if (current instanceof ITopicPart) { + if (isCentral(current)) { + IPart rel = lastRelationship((ISheetPart) current.getSite() + .getViewer().getAdapter(ISheetPart.class)); + if (rel != null) + return rel; + } + IPart prev = findNavPrev(current); + if (prev != current && prev instanceof ITopicPart) { + if (((ITopicPart) current).getOwnerBranch().getParentBranch() == ((ITopicPart) prev) + .getOwnerBranch()) { + IPart prevBoundary = lastBoundary(((ITopicPart) prev) + .getOwnerBranch()); + if (prevBoundary != null) + return prevBoundary; + } + } + return prev; + } else if (current instanceof IBoundaryPart) { + IPart prev = prevBoundary((IBoundaryPart) current); + if (prev != null) + return prev; + return ((IBoundaryPart) current).getOwnedBranch().getTopicPart(); + } else if (current instanceof IRelationshipPart) { + IPart prev = prevRelationship((IRelationshipPart) current); + if (prev != null) + return prev; + return findNavPrev(((IRelationshipPart) current).getOwnerSheet() + .getCentralBranch().getTopicPart()); + } + return null; + } + + private IPart findNavNext(IPart current) { + if (current.hasRole(GEF.ROLE_NAVIGABLE)) { + Request navRequest = new Request(GEF.REQ_NAV_NEXT); + navRequest.setPrimaryTarget(current); + IViewer viewer = current.getSite().getViewer(); + navRequest.setViewer(viewer); + current.handleRequest(navRequest, GEF.ROLE_NAVIGABLE); + Object result = navRequest.getResult(GEF.RESULT_NAVIGATION); + if (result instanceof IPart[]) { + IPart[] parts = (IPart[]) result; + if (parts.length > 0) { + IPart part = parts[0]; + return part; + } + } + } + return null; + } + + private IPart findNavPrev(IPart current) { + if (current.hasRole(GEF.ROLE_NAVIGABLE)) { + Request navRequest = new Request(GEF.REQ_NAV_PREV) + .setPrimaryTarget(current).setViewer( + current.getSite().getViewer()); + current.handleRequest(navRequest, GEF.ROLE_NAVIGABLE); + Object result = navRequest.getResult(GEF.RESULT_NAVIGATION); + if (result instanceof IPart[]) { + IPart[] parts = (IPart[]) result; + if (parts.length > 0) + return parts[0]; + } + } + return null; + } + + private IPart firstBoundary(IBranchPart branch) { + List boundaries = branch.getBoundaries(); + if (boundaries.isEmpty()) + return null; + int start = -1, end = -1; + IBoundaryPart first = null; + for (IBoundaryPart b : boundaries) { + int s = b.getBoundary().getStartIndex(); + int e = b.getBoundary().getEndIndex(); + if (start < 0 || s < start || (s == start && (end < 0 || e > end))) { + start = s; + end = e; + first = b; + } + } + return first; + } + + private IPart lastBoundary(IBranchPart branch) { + List boundaries = branch.getBoundaries(); + if (boundaries.isEmpty()) + return null; + int start = -1, end = -1; + IBoundaryPart last = null; + for (IBoundaryPart b : boundaries) { + int s = b.getBoundary().getStartIndex(); + int e = b.getBoundary().getEndIndex(); + if (start < 0 || s > start || (s == start && (end < 0 || e < end))) { + start = s; + end = e; + last = b; + } + } + return last; + } + + private IPart nextBoundary(IBoundaryPart boundary) { + List boundaries = boundary.getOwnedBranch() + .getBoundaries(); + int start0 = boundary.getBoundary().getStartIndex(); + int end0 = boundary.getBoundary().getEndIndex(); + int start = -1, end = -1; + IBoundaryPart next = null; + for (IBoundaryPart b : boundaries) { + if (b != boundary) { + int s = b.getBoundary().getStartIndex(); + int e = b.getBoundary().getEndIndex(); + if (s > start0 || (s == start0 && e < end0)) { + if (start < 0 || s < start + || (s == start && (end < 0 || e > end))) { + start = s; + end = e; + next = b; + } + } + } + } + return next; + } + + private IPart prevBoundary(IBoundaryPart boundary) { + List boundaries = boundary.getOwnedBranch() + .getBoundaries(); + int start0 = boundary.getBoundary().getStartIndex(); + int end0 = boundary.getBoundary().getEndIndex(); + int start = -1, end = -1; + IBoundaryPart next = null; + for (IBoundaryPart b : boundaries) { + if (b != boundary) { + int s = b.getBoundary().getStartIndex(); + int e = b.getBoundary().getEndIndex(); + if (s < start0 || (s == start0 && e > end0)) { + if (start < 0 || s > start + || (s == start && (end < 0 || e < end))) { + start = s; + end = e; + next = b; + } + } + } + } + return next; + } + + private List getRelationships(ISheetPart sheet) { + if (sheet != null) { + return sheet.getRelationships(); + } + return null; + } + + private IPart firstRelationship(ISheetPart sheet) { + List rels = getRelationships(sheet); + if (rels != null && !rels.isEmpty()) + return rels.get(0); + return null; + } + + private IPart lastRelationship(ISheetPart sheet) { + List rels = getRelationships(sheet); + if (rels != null && !rels.isEmpty()) + return rels.get(rels.size() - 1); + return null; + } + + private IPart nextRelationship(IRelationshipPart rel) { + List rels = getRelationships(rel.getOwnerSheet()); + if (rels != null && !rels.isEmpty()) { + int index = rels.indexOf(rel); + if (index >= 0 && index < rels.size() - 1) + return rels.get(index + 1); + } + return null; + } + + private IPart prevRelationship(IRelationshipPart rel) { + List rels = getRelationships(rel.getOwnerSheet()); + if (rels != null && !rels.isEmpty()) { + int index = rels.indexOf(rel); + if (index > 0) + return rels.get(index - 1); + } + return null; + } + + private boolean isCentral(IPart part) { + return part instanceof ITopicPart + && ((ITopicPart) part).getOwnerBranch().isCentral(); + } + + protected FloatingTextEditor getTextEditor(IPart part) { + ITool editTool = getEditTool(part); + if (editTool instanceof FloatingTextEditTool) { + return ((FloatingTextEditTool) editTool).getEditor(); + } + return null; + } + + protected boolean isEditing(IPart part) { + ITool editTool = getEditTool(part); + return editTool != null + && ((AbstractTool) editTool).getStatus() + .isStatus(GEF.ST_ACTIVE); + } + + protected ITool getEditTool(IPart part) { + EditDomain domain = getCurrentDomain(); + if (part instanceof ILabelPart) { + return domain == null ? null : domain + .getTool(MindMapUI.TOOL_EDIT_LABEL); + } else if (part instanceof IBoundaryPart + || part instanceof IRelationshipPart) { + return domain == null ? null : domain.getTool(GEF.TOOL_EDIT); + } else + return domain == null ? null : domain + .getTool(MindMapUI.TOOL_EDIT_TOPIC_TITLE); + + } + + /** + * @return + */ + protected ITool getDefaultTool() { + EditDomain domain = getCurrentDomain(); + return domain == null ? null : domain.getDefaultTool(); + } + + /** + * @return + */ + protected EditDomain getCurrentDomain() { + IGraphicalEditorPage page = getActivePage(); + return page == null ? null : page.getEditDomain(); + } + + /** + * @return + */ + protected IGraphicalViewer getActiveViewer() { + IGraphicalEditorPage page = getActivePage(); + return page == null ? null : page.getViewer(); + } + + /** + * @return + */ + private IGraphicalEditorPage getActivePage() { + return editor.getActivePageInstance(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapMiniBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapMiniBarContributor.java index 355cc8ae7..f5fc8ba11 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapMiniBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapMiniBarContributor.java @@ -1,59 +1,59 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.xmind.gef.ui.editor.IMiniBar; -import org.xmind.gef.ui.editor.MiniBarContributor; -import org.xmind.ui.internal.actions.ActionConstants; - -public class MindMapMiniBarContributor extends MiniBarContributor { - - private MiniZoomContribution zoomContribution; - - private OverviewCheckContribution overviewCheckContribution; - - protected void init(IMiniBar bar) { - zoomContribution = new MiniZoomContribution(getEditor()); - overviewCheckContribution = new OverviewCheckContribution(); - super.init(bar); - } - - public void contributeToToolBar(IToolBarManager toolBar) { - toolBar.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - toolBar.add(new Separator(ActionConstants.GROUP_FILTER)); - toolBar.add(new Separator(ActionConstants.GROUP_ZOOM)); - if (overviewCheckContribution != null) - toolBar.add(overviewCheckContribution); - toolBar.add(new Separator(ActionConstants.GROUP_ZOOM)); - if (zoomContribution != null) - toolBar.add(zoomContribution); - } - - public void dispose() { - if (zoomContribution != null) { - zoomContribution.dispose(); - zoomContribution = null; - } - - if (overviewCheckContribution != null) { - overviewCheckContribution.dispose(); - overviewCheckContribution = null; - } - super.dispose(); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.xmind.gef.ui.editor.IMiniBar; +import org.xmind.gef.ui.editor.MiniBarContributor; +import org.xmind.ui.internal.actions.ActionConstants; + +public class MindMapMiniBarContributor extends MiniBarContributor { + + private MiniZoomContribution zoomContribution; + + private OverviewCheckContribution overviewCheckContribution; + + protected void init(IMiniBar bar) { + zoomContribution = new MiniZoomContribution(getEditor()); + overviewCheckContribution = new OverviewCheckContribution(); + super.init(bar); + } + + public void contributeToToolBar(IToolBarManager toolBar) { + toolBar.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + toolBar.add(new Separator(ActionConstants.GROUP_FILTER)); + toolBar.add(new Separator(ActionConstants.GROUP_ZOOM)); + if (overviewCheckContribution != null) + toolBar.add(overviewCheckContribution); + toolBar.add(new Separator(ActionConstants.GROUP_ZOOM)); + if (zoomContribution != null) + toolBar.add(zoomContribution); + } + + public void dispose() { + if (zoomContribution != null) { + zoomContribution.dispose(); + zoomContribution = null; + } + + if (overviewCheckContribution != null) { + overviewCheckContribution.dispose(); + overviewCheckContribution = null; + } + super.dispose(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPageTitleEditor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPageTitleEditor.java index 4ab91e35f..08ab72547 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPageTitleEditor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPageTitleEditor.java @@ -1,144 +1,144 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.util.Arrays; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.xmind.core.ISheet; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IGraphicalEditPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.tool.ISourceTool; -import org.xmind.gef.tool.ITool; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.tools.SheetTitleEditTool; -import org.xmind.ui.mindmap.MindMapUI; - -public class MindMapPageTitleEditor { - - private static final int MIN_EDITOR_WIDTH = 50; - - private final CTabFolder tabFolder; - - private final IGraphicalEditor editor; - - public MindMapPageTitleEditor(CTabFolder tabFolder, - MindMapEditor mindmapEditor) { - super(); - this.tabFolder = tabFolder; - this.editor = mindmapEditor; - hookControl(tabFolder); - } - - protected void hookControl(CTabFolder tabFolder) { - Listener eventHandler = new Listener() { - - @Override - public void handleEvent(Event event) { - doHandleEvent(event); - } - }; - tabFolder.addListener(SWT.MouseDoubleClick, eventHandler); - tabFolder.addListener(SWT.MouseDown, eventHandler); - } - - private void doHandleEvent(Event event) { - if (event.type == SWT.MouseDoubleClick) { - startEditing(new Point(event.x, event.y)); - } - if (event.type == SWT.MouseDown) { - if (tabFolder.isFocusControl()) { - startEditing(new Point(event.x, event.y)); - } - } - } - - /** - * @param mouseLocation - */ - private void startEditing(Point mouseLocation) { - if (mouseLocation == null) - return; - - CTabItem item = tabFolder.getItem(mouseLocation); - if (item == null) - return; - - startEditing(tabFolder.indexOf(item)); - } - - /** - * @param pageIndex - */ - public void startEditing(int pageIndex) { - IGraphicalEditorPage page = editor.getPage(pageIndex); - if (page == null) - return; - - IGraphicalViewer viewer = page.getViewer(); - if (viewer == null) - return; - EditDomain editDomain = page.getEditDomain(); - if (editDomain == null) - return; - - ISheet sheet = viewer.getAdapter(ISheet.class); - if (sheet == null) - return; - - IPart part = viewer.findPart(sheet); - if (part == null || !(part instanceof IGraphicalEditPart)) - return; - - IGraphicalEditPart sourcePart = (IGraphicalEditPart) part; - - ITool tool = editDomain.getTool(MindMapUI.TOOL_EDIT_SHEET_TITLE); - if (tool == null) - return; - - if (tool instanceof ISourceTool) { - ((ISourceTool) tool).setSource(sourcePart); - } - - if (tool instanceof SheetTitleEditTool) { - CTabItem item = tabFolder.getItem(pageIndex); - Rectangle itemBounds = item.getBounds(); - Rectangle editorBounds = new Rectangle(itemBounds.x, itemBounds.y, - Math.max(MIN_EDITOR_WIDTH, itemBounds.width), - itemBounds.height); - ((SheetTitleEditTool) tool).setTextEditorParameters(tabFolder, - editorBounds); - } - - editDomain.setActiveTool(MindMapUI.TOOL_EDIT_SHEET_TITLE); - - if (tool != editDomain.getActiveTool()) - return; - - tool.handleRequest(new Request(GEF.REQ_EDIT).setViewer(viewer) - .setTargets(Arrays.asList(sourcePart))); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.util.Arrays; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.xmind.core.ISheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IGraphicalEditPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ISourceTool; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.tools.SheetTitleEditTool; +import org.xmind.ui.mindmap.MindMapUI; + +public class MindMapPageTitleEditor { + + private static final int MIN_EDITOR_WIDTH = 50; + + private final CTabFolder tabFolder; + + private final IGraphicalEditor editor; + + public MindMapPageTitleEditor(CTabFolder tabFolder, + MindMapEditor mindmapEditor) { + super(); + this.tabFolder = tabFolder; + this.editor = mindmapEditor; + hookControl(tabFolder); + } + + protected void hookControl(CTabFolder tabFolder) { + Listener eventHandler = new Listener() { + + @Override + public void handleEvent(Event event) { + doHandleEvent(event); + } + }; + tabFolder.addListener(SWT.MouseDoubleClick, eventHandler); + tabFolder.addListener(SWT.MouseDown, eventHandler); + } + + private void doHandleEvent(Event event) { + if (event.type == SWT.MouseDoubleClick) { + startEditing(new Point(event.x, event.y)); + } + if (event.type == SWT.MouseDown) { + if (tabFolder.isFocusControl()) { + startEditing(new Point(event.x, event.y)); + } + } + } + + /** + * @param mouseLocation + */ + private void startEditing(Point mouseLocation) { + if (mouseLocation == null) + return; + + CTabItem item = tabFolder.getItem(mouseLocation); + if (item == null) + return; + + startEditing(tabFolder.indexOf(item)); + } + + /** + * @param pageIndex + */ + public void startEditing(int pageIndex) { + IGraphicalEditorPage page = editor.getPage(pageIndex); + if (page == null) + return; + + IGraphicalViewer viewer = page.getViewer(); + if (viewer == null) + return; + EditDomain editDomain = page.getEditDomain(); + if (editDomain == null) + return; + + ISheet sheet = viewer.getAdapter(ISheet.class); + if (sheet == null) + return; + + IPart part = viewer.findPart(sheet); + if (part == null || !(part instanceof IGraphicalEditPart)) + return; + + IGraphicalEditPart sourcePart = (IGraphicalEditPart) part; + + ITool tool = editDomain.getTool(MindMapUI.TOOL_EDIT_SHEET_TITLE); + if (tool == null) + return; + + if (tool instanceof ISourceTool) { + ((ISourceTool) tool).setSource(sourcePart); + } + + if (tool instanceof SheetTitleEditTool) { + CTabItem item = tabFolder.getItem(pageIndex); + Rectangle itemBounds = item.getBounds(); + Rectangle editorBounds = new Rectangle(itemBounds.x, itemBounds.y, + Math.max(MIN_EDITOR_WIDTH, itemBounds.width), + itemBounds.height); + ((SheetTitleEditTool) tool).setTextEditorParameters(tabFolder, + editorBounds); + } + + editDomain.setActiveTool(MindMapUI.TOOL_EDIT_SHEET_TITLE); + + if (tool != editDomain.getActiveTool()) + return; + + tool.handleRequest(new Request(GEF.REQ_EDIT).setViewer(viewer) + .setTargets(Arrays.asList(sourcePart))); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPreviewOptions.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPreviewOptions.java index 0d0d8bf13..2cd1199a4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPreviewOptions.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MindMapPreviewOptions.java @@ -1,25 +1,25 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -/** - * @author Frank Shaka - * - */ -public class MindMapPreviewOptions { - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +/** + * @author Frank Shaka + * + */ +public class MindMapPreviewOptions { + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MiniZoomContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MiniZoomContribution.java index 045d645d6..86ffbd67a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MiniZoomContribution.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/MiniZoomContribution.java @@ -1,599 +1,599 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.util.List; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.dialogs.PopupDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; -import org.xmind.gef.IZoomListener; -import org.xmind.gef.Request; -import org.xmind.gef.ZoomManager; -import org.xmind.gef.ZoomObject; -import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.gef.ui.editor.IGraphicalEditorPage; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.actions.ActionConstants; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.viewers.ISliderContentProvider; -import org.xmind.ui.viewers.SliderViewer; - -public class MiniZoomContribution extends ContributionItem - implements IPageChangedListener, IZoomListener { - - protected static final int SLIDER_WIDTH = 88; - - private static class ZoomPopup extends PopupDialog { - - private static final double[] directSelectorInput = { 2.0, 1.5, 1.2, - 1.0, 0.8, 0.5 }; - - private static class ZoomSliderContentProvider - implements ISliderContentProvider { - - private static final int intervalNum = directSelectorInput.length - - 1; - - public double getRatio(Object input, Object value) { - if (value instanceof Double) { - double doubleValue = ((Double) value).doubleValue(); - return transformValueToRatio(doubleValue); - } - return 0; - } - - private double transformValueToRatio(double value) { - if (value > directSelectorInput[0]) - return 1.0; - - if (value < directSelectorInput[intervalNum]) - return 0; - - for (int index = intervalNum; index > 0; index--) { - if (isInternal(value, directSelectorInput[index], - directSelectorInput[index - 1])) { - double minRatio = (intervalNum - index) * 1.0 - / intervalNum; - double maxRatio = minRatio + 1.0 / intervalNum; - return calRatio(value, directSelectorInput[index], - directSelectorInput[index - 1], minRatio, - maxRatio); - } - } - return 0; - } - - private boolean isInternal(double value, double minValue, - double maxValue) { - return value <= maxValue && value >= minValue; - } - - private double calRatio(double value, double minValue, - double maxValue, double minRatio, double maxRatio) { - return minRatio + (value - minValue) / (maxValue - minValue) - * (maxRatio - minRatio); - } - - private double calValue(double ratio, double minRatio, - double maxRatio, double minValue, double maxValue) { - return minValue + (ratio - minRatio) / (maxRatio - minRatio) - * (maxValue - minValue); - } - - public Object getValue(Object input, double ratio) { - return transformRatioToValue(ratio); - } - - private double transformRatioToValue(double ratio) { - if (ratio > 1) - return directSelectorInput[0] * ratio; - - if (ratio < 0) - return 0; - - for (int index = intervalNum; index > 0; index--) { - double minRatio = (intervalNum - index) * 1.0 / intervalNum; - double maxRatio = minRatio + 1.0 / intervalNum; - if (isInternal(ratio, minRatio, maxRatio)) { - return calValue(ratio, minRatio, maxRatio, - directSelectorInput[index], - directSelectorInput[index - 1]); - } - } - return 0.5; - } - - public void inputChanged(Viewer viewer, Object oldInput, - Object newInput) { - } - - public void dispose() { - } - - } - - private static class ZoomSliderLabelProvider extends LabelProvider { - - public String getText(Object element) { - if (element instanceof Double) { - double scale = ((Double) element).doubleValue(); - return String.format("%.0f%%", Double.valueOf(scale * 100)); //$NON-NLS-1$ - } - return super.getText(element); - } - - } - - private Text valueInput; - - private SliderViewer slider; - - private IGraphicalEditorPage page; - - private ZoomManager zoomManager; - - private Point triggerPosition = null; - - private boolean internalModifying = false; - - private Listener directSelectorItemListener = new Listener() { - public void handleEvent(Event event) { - if (event.widget instanceof ToolItem) { - Double value = (Double) ((ToolItem) event.widget).getData(); - confirmValue(value.doubleValue()); - } - } - }; - - public ZoomPopup(Shell parent) { - super(parent, SWT.TOOL, true, false, false, false, false, null, - null); - } - - public void update(IGraphicalEditorPage page, ZoomManager zoomManager, - Point pos) { - this.page = page; - this.zoomManager = zoomManager; - this.triggerPosition = pos; - } - - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - - fillValueInput(composite); - - Composite composite2 = new Composite(composite, SWT.NONE); - GridLayout layout2 = new GridLayout(2, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 0; - layout2.horizontalSpacing = 0; - composite2.setLayout(layout2); - composite2.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - fillDirectSelector(composite2); - fillSlider(composite2); - - return composite; - } - - private void fillValueInput(Composite parent) { - valueInput = new Text(parent, SWT.BORDER | SWT.SINGLE); - valueInput.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - - valueInput.addListener(SWT.Modify, new Listener() { - public void handleEvent(Event event) { - if (internalModifying) - return; - - internalModifying = true; - try { - int intValue = Integer.parseInt(valueInput.getText(), - 10); - updateSlider(intValue / 100.0); - } catch (NumberFormatException e) { - // ignore - } finally { - internalModifying = false; - } - } - }); - Listener inputConfirmListener = new Listener() { - public void handleEvent(Event event) { - if (event.type == SWT.DefaultSelection - || (event.type == SWT.Traverse - && event.detail == SWT.TRAVERSE_RETURN)) { - try { - int intValue = Integer - .parseInt(valueInput.getText(), 10); - confirmValue(intValue / 100.0); - } catch (NumberFormatException e) { - // ignore - } - event.doit = false; - } - } - }; - valueInput.addListener(SWT.DefaultSelection, inputConfirmListener); - valueInput.addListener(SWT.Traverse, inputConfirmListener); - } - - private void fillDirectSelector(Composite parent) { - ToolBar toolbar = new ToolBar(parent, SWT.VERTICAL); - toolbar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - addDirectSelectorItems(toolbar, directSelectorInput); - } - - private void addDirectSelectorItems(ToolBar parent, double[] values) { - for (double value : values) { - addDirectSelectorItem(parent, value); - } - } - - private void addDirectSelectorItem(ToolBar parent, double value) { - ToolItem item = new ToolItem(parent, SWT.PUSH); - item.setText(String.valueOf((int) Math.round(value * 100))); - item.setData(Double.valueOf(value)); - item.addListener(SWT.Selection, directSelectorItemListener); - } - - private void fillSlider(Composite parent) { - slider = new SliderViewer(parent, SWT.VERTICAL); - slider.getControl().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, false, true)); - ((GridData) slider.getControl().getLayoutData()).heightHint = 40; - slider.setContentProvider(new ZoomSliderContentProvider()); - slider.setLabelProvider(new ZoomSliderLabelProvider()); - slider.setInput(this); - slider.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - if (internalModifying) - return; - - internalModifying = true; - try { - Double value = (Double) slider.getSelectionValue(); - updateValueInput(value.doubleValue()); - } catch (NumberFormatException e) { - // ignore - } finally { - internalModifying = false; - } - } - }); - slider.addPostSelectionChangedListener( - new ISelectionChangedListener() { - public void selectionChanged( - SelectionChangedEvent event) { - if (internalModifying) - return; - - Double value = (Double) slider.getSelectionValue(); - if (value != null) { - confirmValue(value.doubleValue()); - } - } - }); - } - - protected Control getFocusControl() { - return valueInput; - } - - protected void adjustBounds() { - internalModifying = true; - try { - double doubleValue = zoomManager.getScale(); - updateValueInput(doubleValue); - updateSlider(doubleValue); - } finally { - internalModifying = false; - } - - getShell().pack(); - Point size = getShell().getSize(); - if (triggerPosition != null) { - getShell().setLocation(triggerPosition.x, - triggerPosition.y - size.y); - } - } - - private void confirmValue(final double newValue) { - close(); - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - if (page == null) - return; - EditDomain domain = page.getEditDomain(); - if (domain == null) - return; - - Request request = new Request(GEF.REQ_ZOOM); - request.setViewer(page.getViewer()); - request.setParameter(GEF.PARAM_ZOOM_SCALE, - Double.valueOf(newValue)); - domain.handleRequest(request); - } - }); - } - - private void updateValueInput(double doubleValue) { - valueInput.setText( - String.valueOf((int) Math.round(doubleValue * 100))); - valueInput.setSelection(valueInput.getText().length()); - } - - private void updateSlider(double doubleValue) { - slider.setSelection( - new StructuredSelection(Double.valueOf(doubleValue))); - } - - @SuppressWarnings("unchecked") - protected List getBackgroundColorExclusions() { - List list = super.getBackgroundColorExclusions(); - list.add(valueInput); - return list; - } - - } - - private ZoomManager zoomManager = null; - - private IGraphicalEditor editor; - - private ToolItem zoomOutItem; - - private ToolItem zoomValueItem; - - private ToolItem zoomInItem; - - private ToolItem zoomDefaultItem; - - private ZoomPopup zoomPopup = null; - - public MiniZoomContribution(IGraphicalEditor editor) { - this(ActionConstants.MINI_ZOOM, editor); - } - - public MiniZoomContribution(String id, IGraphicalEditor editor) { - super(id); - this.editor = editor; - editor.addPageChangedListener(this); - } - - public boolean isDynamic() { - return true; - } - - public void dispose() { - if (zoomOutItem != null) { - zoomOutItem.dispose(); - zoomOutItem = null; - } - if (zoomValueItem != null) { - zoomValueItem.dispose(); - zoomValueItem = null; - } - if (zoomInItem != null) { - zoomInItem.dispose(); - zoomInItem = null; - } - if (zoomDefaultItem != null) { - zoomDefaultItem.dispose(); - zoomDefaultItem = null; - } - setZoomManager(null); - if (editor != null) { - editor.removePageChangedListener(this); - editor = null; - } - super.dispose(); - } - - public void fill(ToolBar parent, int index) { - if (index < 0) { - zoomOutItem = new ToolItem(parent, SWT.PUSH); - zoomValueItem = new ToolItem(parent, SWT.PUSH); - zoomInItem = new ToolItem(parent, SWT.PUSH); - zoomDefaultItem = new ToolItem(parent, SWT.PUSH); - } else { - zoomOutItem = new ToolItem(parent, SWT.PUSH, index++); - zoomValueItem = new ToolItem(parent, SWT.PUSH, index++); - zoomInItem = new ToolItem(parent, SWT.PUSH, index++); - zoomDefaultItem = new ToolItem(parent, SWT.PUSH, index++); - } - - zoomValueItem.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - Rectangle r = zoomValueItem.getBounds(); - showZoomPopup(event, - zoomValueItem.getParent().toDisplay(r.x, r.y)); - } - }); - zoomOutItem.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - sendRequest(GEF.REQ_ZOOMOUT); - } - }); - zoomInItem.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - sendRequest(GEF.REQ_ZOOMIN); - } - }); - zoomDefaultItem.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - sendRequest(GEF.REQ_ACTUALSIZE); - } - }); - - initItemLabel(zoomOutItem, IMindMapImages.ZOOMOUT_SMALL, - MindMapMessages.ZoomOut_toolTip); - initItemLabel(zoomInItem, IMindMapImages.ZOOMIN_SMALL, - MindMapMessages.ZoomIn_toolTip); - initItemLabel(zoomDefaultItem, IMindMapImages.ACTUAL_SIZE_SMALL, - MindMapMessages.ActualSize_toolTip); - - update(null); - } - - private void initItemLabel(final ToolItem item, String iconPath, - String fallbackText) { - Image image = createImage(iconPath, true); - if (image != null) { - item.setImage(image); - item.setDisabledImage(createImage(iconPath, false)); - item.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - Image image = item.getImage(); - if (image != null) { - image.dispose(); - } - image = item.getDisabledImage(); - if (image != null) { - image.dispose(); - } - } - }); - } else { - item.setText(fallbackText); - } - } - - private Image createImage(String iconPath, boolean enabled) { - ImageDescriptor imageDescriptor = MindMapUI.getImages().get(iconPath, - enabled); - return imageDescriptor == null ? null - : imageDescriptor.createImage(false); - } - - public void update() { - update(null); - } - - public void update(String id) { - if (zoomValueItem != null && !zoomValueItem.isDisposed()) { - if (zoomManager == null) { - zoomValueItem.setText("100%"); //$NON-NLS-1$ - } else { - double scale = zoomManager.getScale(); - int s = (int) Math.round(scale * 100); - zoomValueItem.setText(String.format("%d%%", s)); //$NON-NLS-1$ - } - } - } - - private void refresh() { - update(null); - getParent().update(true); - } - - public void pageChanged(PageChangedEvent event) { - setZoomManager(getZoomManager(event.getSelectedPage())); - } - - public void scaleChanged(ZoomObject source, double oldValue, - double newValue) { - refresh(); - } - - private ZoomManager getZoomManager(Object page) { - if (page == null || !(page instanceof IGraphicalEditorPage)) - return null; - - IGraphicalViewer viewer = ((IGraphicalEditorPage) page).getViewer(); - if (viewer == null) - return null; - - return viewer.getZoomManager(); - } - - private void setZoomManager(ZoomManager zoomManager) { - if (zoomManager == this.zoomManager) - return; - - if (this.zoomManager != null) { - this.zoomManager.removeZoomListener(this); - } - this.zoomManager = zoomManager; - if (zoomManager != null) { - zoomManager.addZoomListener(this); - } - refresh(); - } - - private void showZoomPopup(Event event, Point itemLocation) { - if (zoomManager == null) - return; - - if (zoomPopup == null) { - zoomPopup = new ZoomPopup(editor.getSite().getShell()); - } - zoomPopup.update(editor.getActivePageInstance(), zoomManager, - itemLocation); - zoomPopup.open(); - } - - private void sendRequest(final String reqType) { - if (editor == null) - return; - - final IGraphicalEditorPage page = editor.getActivePageInstance(); - if (page == null) - return; - - final EditDomain domain = page.getEditDomain(); - if (domain == null) - return; - - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - domain.handleRequest(reqType, page.getViewer()); - } - }); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.util.List; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.dialogs.PopupDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IZoomListener; +import org.xmind.gef.Request; +import org.xmind.gef.ZoomManager; +import org.xmind.gef.ZoomObject; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.actions.ActionConstants; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.viewers.ISliderContentProvider; +import org.xmind.ui.viewers.SliderViewer; + +public class MiniZoomContribution extends ContributionItem + implements IPageChangedListener, IZoomListener { + + protected static final int SLIDER_WIDTH = 88; + + private static class ZoomPopup extends PopupDialog { + + private static final double[] directSelectorInput = { 2.0, 1.5, 1.2, + 1.0, 0.8, 0.5 }; + + private static class ZoomSliderContentProvider + implements ISliderContentProvider { + + private static final int intervalNum = directSelectorInput.length + - 1; + + public double getRatio(Object input, Object value) { + if (value instanceof Double) { + double doubleValue = ((Double) value).doubleValue(); + return transformValueToRatio(doubleValue); + } + return 0; + } + + private double transformValueToRatio(double value) { + if (value > directSelectorInput[0]) + return 1.0; + + if (value < directSelectorInput[intervalNum]) + return 0; + + for (int index = intervalNum; index > 0; index--) { + if (isInternal(value, directSelectorInput[index], + directSelectorInput[index - 1])) { + double minRatio = (intervalNum - index) * 1.0 + / intervalNum; + double maxRatio = minRatio + 1.0 / intervalNum; + return calRatio(value, directSelectorInput[index], + directSelectorInput[index - 1], minRatio, + maxRatio); + } + } + return 0; + } + + private boolean isInternal(double value, double minValue, + double maxValue) { + return value <= maxValue && value >= minValue; + } + + private double calRatio(double value, double minValue, + double maxValue, double minRatio, double maxRatio) { + return minRatio + (value - minValue) / (maxValue - minValue) + * (maxRatio - minRatio); + } + + private double calValue(double ratio, double minRatio, + double maxRatio, double minValue, double maxValue) { + return minValue + (ratio - minRatio) / (maxRatio - minRatio) + * (maxValue - minValue); + } + + public Object getValue(Object input, double ratio) { + return transformRatioToValue(ratio); + } + + private double transformRatioToValue(double ratio) { + if (ratio > 1) + return directSelectorInput[0] * ratio; + + if (ratio < 0) + return 0; + + for (int index = intervalNum; index > 0; index--) { + double minRatio = (intervalNum - index) * 1.0 / intervalNum; + double maxRatio = minRatio + 1.0 / intervalNum; + if (isInternal(ratio, minRatio, maxRatio)) { + return calValue(ratio, minRatio, maxRatio, + directSelectorInput[index], + directSelectorInput[index - 1]); + } + } + return 0.5; + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public void dispose() { + } + + } + + private static class ZoomSliderLabelProvider extends LabelProvider { + + public String getText(Object element) { + if (element instanceof Double) { + double scale = ((Double) element).doubleValue(); + return String.format("%.0f%%", Double.valueOf(scale * 100)); //$NON-NLS-1$ + } + return super.getText(element); + } + + } + + private Text valueInput; + + private SliderViewer slider; + + private IGraphicalEditorPage page; + + private ZoomManager zoomManager; + + private Point triggerPosition = null; + + private boolean internalModifying = false; + + private Listener directSelectorItemListener = new Listener() { + public void handleEvent(Event event) { + if (event.widget instanceof ToolItem) { + Double value = (Double) ((ToolItem) event.widget).getData(); + confirmValue(value.doubleValue()); + } + } + }; + + public ZoomPopup(Shell parent) { + super(parent, SWT.TOOL, true, false, false, false, false, null, + null); + } + + public void update(IGraphicalEditorPage page, ZoomManager zoomManager, + Point pos) { + this.page = page; + this.zoomManager = zoomManager; + this.triggerPosition = pos; + } + + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + fillValueInput(composite); + + Composite composite2 = new Composite(composite, SWT.NONE); + GridLayout layout2 = new GridLayout(2, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.verticalSpacing = 0; + layout2.horizontalSpacing = 0; + composite2.setLayout(layout2); + composite2.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + fillDirectSelector(composite2); + fillSlider(composite2); + + return composite; + } + + private void fillValueInput(Composite parent) { + valueInput = new Text(parent, SWT.BORDER | SWT.SINGLE); + valueInput.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + + valueInput.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event event) { + if (internalModifying) + return; + + internalModifying = true; + try { + int intValue = Integer.parseInt(valueInput.getText(), + 10); + updateSlider(intValue / 100.0); + } catch (NumberFormatException e) { + // ignore + } finally { + internalModifying = false; + } + } + }); + Listener inputConfirmListener = new Listener() { + public void handleEvent(Event event) { + if (event.type == SWT.DefaultSelection + || (event.type == SWT.Traverse + && event.detail == SWT.TRAVERSE_RETURN)) { + try { + int intValue = Integer + .parseInt(valueInput.getText(), 10); + confirmValue(intValue / 100.0); + } catch (NumberFormatException e) { + // ignore + } + event.doit = false; + } + } + }; + valueInput.addListener(SWT.DefaultSelection, inputConfirmListener); + valueInput.addListener(SWT.Traverse, inputConfirmListener); + } + + private void fillDirectSelector(Composite parent) { + ToolBar toolbar = new ToolBar(parent, SWT.VERTICAL); + toolbar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + addDirectSelectorItems(toolbar, directSelectorInput); + } + + private void addDirectSelectorItems(ToolBar parent, double[] values) { + for (double value : values) { + addDirectSelectorItem(parent, value); + } + } + + private void addDirectSelectorItem(ToolBar parent, double value) { + ToolItem item = new ToolItem(parent, SWT.PUSH); + item.setText(String.valueOf((int) Math.round(value * 100))); + item.setData(Double.valueOf(value)); + item.addListener(SWT.Selection, directSelectorItemListener); + } + + private void fillSlider(Composite parent) { + slider = new SliderViewer(parent, SWT.VERTICAL); + slider.getControl().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, false, true)); + ((GridData) slider.getControl().getLayoutData()).heightHint = 40; + slider.setContentProvider(new ZoomSliderContentProvider()); + slider.setLabelProvider(new ZoomSliderLabelProvider()); + slider.setInput(this); + slider.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + if (internalModifying) + return; + + internalModifying = true; + try { + Double value = (Double) slider.getSelectionValue(); + updateValueInput(value.doubleValue()); + } catch (NumberFormatException e) { + // ignore + } finally { + internalModifying = false; + } + } + }); + slider.addPostSelectionChangedListener( + new ISelectionChangedListener() { + public void selectionChanged( + SelectionChangedEvent event) { + if (internalModifying) + return; + + Double value = (Double) slider.getSelectionValue(); + if (value != null) { + confirmValue(value.doubleValue()); + } + } + }); + } + + protected Control getFocusControl() { + return valueInput; + } + + protected void adjustBounds() { + internalModifying = true; + try { + double doubleValue = zoomManager.getScale(); + updateValueInput(doubleValue); + updateSlider(doubleValue); + } finally { + internalModifying = false; + } + + getShell().pack(); + Point size = getShell().getSize(); + if (triggerPosition != null) { + getShell().setLocation(triggerPosition.x, + triggerPosition.y - size.y); + } + } + + private void confirmValue(final double newValue) { + close(); + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + if (page == null) + return; + EditDomain domain = page.getEditDomain(); + if (domain == null) + return; + + Request request = new Request(GEF.REQ_ZOOM); + request.setViewer(page.getViewer()); + request.setParameter(GEF.PARAM_ZOOM_SCALE, + Double.valueOf(newValue)); + domain.handleRequest(request); + } + }); + } + + private void updateValueInput(double doubleValue) { + valueInput.setText( + String.valueOf((int) Math.round(doubleValue * 100))); + valueInput.setSelection(valueInput.getText().length()); + } + + private void updateSlider(double doubleValue) { + slider.setSelection( + new StructuredSelection(Double.valueOf(doubleValue))); + } + + @SuppressWarnings("unchecked") + protected List getBackgroundColorExclusions() { + List list = super.getBackgroundColorExclusions(); + list.add(valueInput); + return list; + } + + } + + private ZoomManager zoomManager = null; + + private IGraphicalEditor editor; + + private ToolItem zoomOutItem; + + private ToolItem zoomValueItem; + + private ToolItem zoomInItem; + + private ToolItem zoomDefaultItem; + + private ZoomPopup zoomPopup = null; + + public MiniZoomContribution(IGraphicalEditor editor) { + this(ActionConstants.MINI_ZOOM, editor); + } + + public MiniZoomContribution(String id, IGraphicalEditor editor) { + super(id); + this.editor = editor; + editor.addPageChangedListener(this); + } + + public boolean isDynamic() { + return true; + } + + public void dispose() { + if (zoomOutItem != null) { + zoomOutItem.dispose(); + zoomOutItem = null; + } + if (zoomValueItem != null) { + zoomValueItem.dispose(); + zoomValueItem = null; + } + if (zoomInItem != null) { + zoomInItem.dispose(); + zoomInItem = null; + } + if (zoomDefaultItem != null) { + zoomDefaultItem.dispose(); + zoomDefaultItem = null; + } + setZoomManager(null); + if (editor != null) { + editor.removePageChangedListener(this); + editor = null; + } + super.dispose(); + } + + public void fill(ToolBar parent, int index) { + if (index < 0) { + zoomOutItem = new ToolItem(parent, SWT.PUSH); + zoomValueItem = new ToolItem(parent, SWT.PUSH); + zoomInItem = new ToolItem(parent, SWT.PUSH); + zoomDefaultItem = new ToolItem(parent, SWT.PUSH); + } else { + zoomOutItem = new ToolItem(parent, SWT.PUSH, index++); + zoomValueItem = new ToolItem(parent, SWT.PUSH, index++); + zoomInItem = new ToolItem(parent, SWT.PUSH, index++); + zoomDefaultItem = new ToolItem(parent, SWT.PUSH, index++); + } + + zoomValueItem.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + Rectangle r = zoomValueItem.getBounds(); + showZoomPopup(event, + zoomValueItem.getParent().toDisplay(r.x, r.y)); + } + }); + zoomOutItem.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + sendRequest(GEF.REQ_ZOOMOUT); + } + }); + zoomInItem.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + sendRequest(GEF.REQ_ZOOMIN); + } + }); + zoomDefaultItem.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + sendRequest(GEF.REQ_ACTUALSIZE); + } + }); + + initItemLabel(zoomOutItem, IMindMapImages.ZOOMOUT_SMALL, + MindMapMessages.ZoomOut_toolTip); + initItemLabel(zoomInItem, IMindMapImages.ZOOMIN_SMALL, + MindMapMessages.ZoomIn_toolTip); + initItemLabel(zoomDefaultItem, IMindMapImages.ACTUAL_SIZE_SMALL, + MindMapMessages.ActualSize_toolTip); + + update(null); + } + + private void initItemLabel(final ToolItem item, String iconPath, + String fallbackText) { + Image image = createImage(iconPath, true); + if (image != null) { + item.setImage(image); + item.setDisabledImage(createImage(iconPath, false)); + item.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + Image image = item.getImage(); + if (image != null) { + image.dispose(); + } + image = item.getDisabledImage(); + if (image != null) { + image.dispose(); + } + } + }); + } else { + item.setText(fallbackText); + } + } + + private Image createImage(String iconPath, boolean enabled) { + ImageDescriptor imageDescriptor = MindMapUI.getImages().get(iconPath, + enabled); + return imageDescriptor == null ? null + : imageDescriptor.createImage(false); + } + + public void update() { + update(null); + } + + public void update(String id) { + if (zoomValueItem != null && !zoomValueItem.isDisposed()) { + if (zoomManager == null) { + zoomValueItem.setText("100%"); //$NON-NLS-1$ + } else { + double scale = zoomManager.getScale(); + int s = (int) Math.round(scale * 100); + zoomValueItem.setText(String.format("%d%%", s)); //$NON-NLS-1$ + } + } + } + + private void refresh() { + update(null); + getParent().update(true); + } + + public void pageChanged(PageChangedEvent event) { + setZoomManager(getZoomManager(event.getSelectedPage())); + } + + public void scaleChanged(ZoomObject source, double oldValue, + double newValue) { + refresh(); + } + + private ZoomManager getZoomManager(Object page) { + if (page == null || !(page instanceof IGraphicalEditorPage)) + return null; + + IGraphicalViewer viewer = ((IGraphicalEditorPage) page).getViewer(); + if (viewer == null) + return null; + + return viewer.getZoomManager(); + } + + private void setZoomManager(ZoomManager zoomManager) { + if (zoomManager == this.zoomManager) + return; + + if (this.zoomManager != null) { + this.zoomManager.removeZoomListener(this); + } + this.zoomManager = zoomManager; + if (zoomManager != null) { + zoomManager.addZoomListener(this); + } + refresh(); + } + + private void showZoomPopup(Event event, Point itemLocation) { + if (zoomManager == null) + return; + + if (zoomPopup == null) { + zoomPopup = new ZoomPopup(editor.getSite().getShell()); + } + zoomPopup.update(editor.getActivePageInstance(), zoomManager, + itemLocation); + zoomPopup.open(); + } + + private void sendRequest(final String reqType) { + if (editor == null) + return; + + final IGraphicalEditorPage page = editor.getActivePageInstance(); + if (page == null) + return; + + final EditDomain domain = page.getEditDomain(); + if (domain == null) + return; + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + domain.handleRequest(reqType, page.getViewer()); + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/OverviewCheckContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/OverviewCheckContribution.java index 94abd1b96..e21fe6831 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/OverviewCheckContribution.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/OverviewCheckContribution.java @@ -1,148 +1,148 @@ -package org.xmind.ui.internal.editor; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.prefs.PrefConstants; - -public class OverviewCheckContribution extends ContributionItem - implements IPropertyChangeListener, Listener { - - private static final String SHOW_OVERVIEW = "show_overview.png"; //$NON-NLS-1$ - - private static final String HIDE_OVERVIEW = "hide_overview.png"; //$NON-NLS-1$ - - private IPreferenceStore ps; - - private Control control; - - private ToolItem check; - - private ResourceManager resources; - - public OverviewCheckContribution() { - ps = MindMapUIPlugin.getDefault().getPreferenceStore(); - } - - public void fill(ToolBar parent, int index) { - Composite composite = new Composite(parent, SWT.NONE); - - resources = new LocalResourceManager(JFaceResources.getResources(), - composite); - - if (index < 0) - check = new ToolItem(parent, SWT.PUSH); - else - check = new ToolItem(parent, SWT.PUSH, index++); - - check.setImage( - (Image) resources.get(getImageDescriptor(HIDE_OVERVIEW))); - check.setToolTipText(MindMapMessages.OverviewCheck_Overview_ON); - - check.addListener(SWT.Selection, this); - - updateCheck(); - - ps.removePropertyChangeListener(this); - ps.addPropertyChangeListener(this); - - this.control = composite; - } - - private void updateCheck() { - boolean value = getValue(); - - check.setImage((Image) resources.get( - getImageDescriptor(value ? HIDE_OVERVIEW : SHOW_OVERVIEW))); - check.setToolTipText(value ? MindMapMessages.OverviewCheck_Overview_OFF - : MindMapMessages.OverviewCheck_Overview_ON); - } - - private boolean getValue() { - return ps.getBoolean(PrefConstants.SHOW_OVERVIEW); - } - - @Override - public void handleEvent(final Event event) { - if (event.widget == check) { - event.display.timerExec(10, new Runnable() { - public void run() { - changeStatus(!getValue()); - } - }); - } - } - - @Override - public void propertyChange(final PropertyChangeEvent event) { - if (control == null || control.isDisposed()) - return; - - control.getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - update(event.getProperty()); - } - }); - } - - public void update(String id) { - if (check == null || check.isDisposed() || ps == null) - return; - - if (id == null || PrefConstants.SHOW_OVERVIEW.equals(id)) { - updateCheck(); - } - } - - private void changeStatus(boolean value) { - ps.setValue(PrefConstants.SHOW_OVERVIEW, value); - } - - public void dispose() { - if (check != null) { - check.dispose(); - check = null; - } - control = null; - if (ps != null) { - ps.removePropertyChangeListener(this); - ps = null; - } - } - - private ImageDescriptor getImageDescriptor(String path) { - URL url; - try { - url = new URL( - "platform:/plugin/org.xmind.ui.mindmap/$nl$/icons/" + path); //$NON-NLS-1$ - } catch (MalformedURLException e) { - return null; - } - URL locatedURL = FileLocator.find(url); - if (locatedURL != null) - url = locatedURL; - return ImageDescriptor.createFromURL(url); - } - -} +package org.xmind.ui.internal.editor; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; + +public class OverviewCheckContribution extends ContributionItem + implements IPropertyChangeListener, Listener { + + private static final String SHOW_OVERVIEW = "show_overview.png"; //$NON-NLS-1$ + + private static final String HIDE_OVERVIEW = "hide_overview.png"; //$NON-NLS-1$ + + private IPreferenceStore ps; + + private Control control; + + private ToolItem check; + + private ResourceManager resources; + + public OverviewCheckContribution() { + ps = MindMapUIPlugin.getDefault().getPreferenceStore(); + } + + public void fill(ToolBar parent, int index) { + Composite composite = new Composite(parent, SWT.NONE); + + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + + if (index < 0) + check = new ToolItem(parent, SWT.PUSH); + else + check = new ToolItem(parent, SWT.PUSH, index++); + + check.setImage( + (Image) resources.get(getImageDescriptor(HIDE_OVERVIEW))); + check.setToolTipText(MindMapMessages.OverviewCheck_Overview_ON); + + check.addListener(SWT.Selection, this); + + updateCheck(); + + ps.removePropertyChangeListener(this); + ps.addPropertyChangeListener(this); + + this.control = composite; + } + + private void updateCheck() { + boolean value = getValue(); + + check.setImage((Image) resources.get( + getImageDescriptor(value ? HIDE_OVERVIEW : SHOW_OVERVIEW))); + check.setToolTipText(value ? MindMapMessages.OverviewCheck_Overview_OFF + : MindMapMessages.OverviewCheck_Overview_ON); + } + + private boolean getValue() { + return ps.getBoolean(PrefConstants.SHOW_OVERVIEW); + } + + @Override + public void handleEvent(final Event event) { + if (event.widget == check) { + event.display.timerExec(10, new Runnable() { + public void run() { + changeStatus(!getValue()); + } + }); + } + } + + @Override + public void propertyChange(final PropertyChangeEvent event) { + if (control == null || control.isDisposed()) + return; + + control.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + update(event.getProperty()); + } + }); + } + + public void update(String id) { + if (check == null || check.isDisposed() || ps == null) + return; + + if (id == null || PrefConstants.SHOW_OVERVIEW.equals(id)) { + updateCheck(); + } + } + + private void changeStatus(boolean value) { + ps.setValue(PrefConstants.SHOW_OVERVIEW, value); + } + + public void dispose() { + if (check != null) { + check.dispose(); + check = null; + } + control = null; + if (ps != null) { + ps.removePropertyChangeListener(this); + ps = null; + } + } + + private ImageDescriptor getImageDescriptor(String path) { + URL url; + try { + url = new URL( + "platform:/plugin/org.xmind.ui.mindmap/$nl$/icons/" + path); //$NON-NLS-1$ + } catch (MalformedURLException e) { + return null; + } + URL locatedURL = FileLocator.find(url); + if (locatedURL != null) + url = locatedURL; + return ImageDescriptor.createFromURL(url); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/PreLoadedWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/PreLoadedWorkbookRef.java index b17f5dcfb..605c7f8e4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/PreLoadedWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/PreLoadedWorkbookRef.java @@ -1,158 +1,158 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.UUID; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ui.IMemento; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.ISerializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.DirectoryStorage; -import org.xmind.core.io.IStorage; -import org.xmind.core.util.CloneHandler; -import org.xmind.ui.mindmap.IWorkbookRef; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class PreLoadedWorkbookRef extends AbstractWorkbookRef { - - private static final String TAG_NAME = "name"; //$NON-NLS-1$ - - private IWorkbook sourceWorkbook; - - private String name; - - private PreLoadedWorkbookRef(IMemento state, IWorkbook workbook, - String name) { - super(null, state); - this.sourceWorkbook = workbook; - this.name = name; - } - - /** - * Makes a clone of the source workbook to be the content workbook and - * stores its content at the temp storage. - */ - @Override - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - if (sourceWorkbook == null) { - throw new IllegalStateException("No source workbook to load"); //$NON-NLS-1$ - } - try { - /// make a clone workbook from the source workbook as the loaded workbook - IWorkbook workbook = Core.getWorkbookBuilder() - .createWorkbook(getTempStorage()); - - ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); - serializer.setWorkbook(workbook); - serializer.setWorkbookStorageAsOutputTarget(); - serializer.setEntryStreamNormalizer(getEncryptionHandler()); - serializer.serialize(null); - - new CloneHandler().withWorkbooks(sourceWorkbook, workbook) - .copyWorkbookContents(); - return workbook; - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - } - - /** - * Loads the content workbook from the specified storage and makes a clone - * of it to be the source workbook (stored at a temporary location). - */ - @Override - protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, - IStorage tempStorage) - throws InterruptedException, InvocationTargetException { - IWorkbook workbook = super.doLoadWorkbookFromTempStorage(monitor, - tempStorage); - - if (sourceWorkbook == null) { - /// make a clone of the saved workbook as the source workbook - String sourceStoragePath = Core.getWorkspace() - .getTempDir("preloaded/" + UUID.randomUUID().toString()); //$NON-NLS-1$ - File sourceStorageDir = new File(sourceStoragePath); - sourceStorageDir.mkdirs(); - try { - sourceWorkbook = Core.getWorkbookBuilder() - .createWorkbook(new DirectoryStorage(sourceStorageDir)); - new CloneHandler().withWorkbooks(workbook, sourceWorkbook) - .copyWorkbookContents(); - } catch (IOException e) { - throw new InvocationTargetException(e); - } - } - - return workbook; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public int hashCode() { - IWorkbook w = getWorkbook(); - return w == null ? super.hashCode() : w.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof PreLoadedWorkbookRef)) - return false; - PreLoadedWorkbookRef that = (PreLoadedWorkbookRef) obj; - IWorkbook thisWorkbook = this.getWorkbook(); - IWorkbook thatWorkbook = that.getWorkbook(); - return thisWorkbook == thatWorkbook - || (thisWorkbook != null && thisWorkbook.equals(thatWorkbook)); - } - - @Override - public String toString() { - IWorkbook w = getWorkbook(); - return w == null ? super.toString() : w.toString(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.internal.editor.AbstractWorkbookRef#saveState(org.eclipse.ui - * .IMemento) - */ - @Override - protected void saveState(IMemento memento) { - if (name != null) { - memento.putString(TAG_NAME, name); - } - super.saveState(memento); - } - - public static IWorkbookRef createFromSavedState(IMemento state) { - Assert.isLegal(state != null); - return new PreLoadedWorkbookRef(state, null, state.getString(TAG_NAME)); - } - - public static IWorkbookRef createFromLoadedWorkbook(IWorkbook workbook, - String name) { - Assert.isLegal(workbook != null); - return new PreLoadedWorkbookRef(null, workbook, name); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.UUID; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IMemento; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.ISerializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.io.DirectoryStorage; +import org.xmind.core.io.IStorage; +import org.xmind.core.util.CloneHandler; +import org.xmind.ui.mindmap.IWorkbookRef; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class PreLoadedWorkbookRef extends AbstractWorkbookRef { + + private static final String TAG_NAME = "name"; //$NON-NLS-1$ + + private IWorkbook sourceWorkbook; + + private String name; + + private PreLoadedWorkbookRef(IMemento state, IWorkbook workbook, + String name) { + super(null, state); + this.sourceWorkbook = workbook; + this.name = name; + } + + /** + * Makes a clone of the source workbook to be the content workbook and + * stores its content at the temp storage. + */ + @Override + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + if (sourceWorkbook == null) { + throw new IllegalStateException("No source workbook to load"); //$NON-NLS-1$ + } + try { + /// make a clone workbook from the source workbook as the loaded workbook + IWorkbook workbook = Core.getWorkbookBuilder() + .createWorkbook(getTempStorage()); + + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); + serializer.setWorkbook(workbook); + serializer.setWorkbookStorageAsOutputTarget(); + serializer.setEntryStreamNormalizer(getEncryptionHandler()); + serializer.serialize(null); + + new CloneHandler().withWorkbooks(sourceWorkbook, workbook) + .copyWorkbookContents(); + return workbook; + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } + } + + /** + * Loads the content workbook from the specified storage and makes a clone + * of it to be the source workbook (stored at a temporary location). + */ + @Override + protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, + IStorage tempStorage) + throws InterruptedException, InvocationTargetException { + IWorkbook workbook = super.doLoadWorkbookFromTempStorage(monitor, + tempStorage); + + if (sourceWorkbook == null) { + /// make a clone of the saved workbook as the source workbook + String sourceStoragePath = Core.getWorkspace() + .getTempDir("preloaded/" + UUID.randomUUID().toString()); //$NON-NLS-1$ + File sourceStorageDir = new File(sourceStoragePath); + sourceStorageDir.mkdirs(); + try { + sourceWorkbook = Core.getWorkbookBuilder() + .createWorkbook(new DirectoryStorage(sourceStorageDir)); + new CloneHandler().withWorkbooks(workbook, sourceWorkbook) + .copyWorkbookContents(); + } catch (IOException e) { + throw new InvocationTargetException(e); + } + } + + return workbook; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public int hashCode() { + IWorkbook w = getWorkbook(); + return w == null ? super.hashCode() : w.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof PreLoadedWorkbookRef)) + return false; + PreLoadedWorkbookRef that = (PreLoadedWorkbookRef) obj; + IWorkbook thisWorkbook = this.getWorkbook(); + IWorkbook thatWorkbook = that.getWorkbook(); + return thisWorkbook == thatWorkbook + || (thisWorkbook != null && thisWorkbook.equals(thatWorkbook)); + } + + @Override + public String toString() { + IWorkbook w = getWorkbook(); + return w == null ? super.toString() : w.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.internal.editor.AbstractWorkbookRef#saveState(org.eclipse.ui + * .IMemento) + */ + @Override + protected void saveState(IMemento memento) { + if (name != null) { + memento.putString(TAG_NAME, name); + } + super.saveState(memento); + } + + public static IWorkbookRef createFromSavedState(IMemento state) { + Assert.isLegal(state != null); + return new PreLoadedWorkbookRef(state, null, state.getString(TAG_NAME)); + } + + public static IWorkbookRef createFromLoadedWorkbook(IWorkbook workbook, + String name) { + Assert.isLegal(workbook != null); + return new PreLoadedWorkbookRef(null, workbook, name); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ResourceFileOutputStream.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ResourceFileOutputStream.java index 904c02a65..4c3e55cea 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ResourceFileOutputStream.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ResourceFileOutputStream.java @@ -1,80 +1,80 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.xmind.core.Core; -import org.xmind.core.util.FileUtils; - -public class ResourceFileOutputStream extends FilterOutputStream { - - private IFile file; - - private String tempFile; - - private IProgressMonitor monitor; - - public ResourceFileOutputStream(IFile file, IProgressMonitor monitor) - throws IOException { - super(null); - this.tempFile = createTempFile(); - this.file = file; - this.out = new FileOutputStream(tempFile); - this.monitor = monitor; - } - - @Override - public void write(byte[] b) throws IOException { - out.write(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - } - - @Override - public void write(int b) throws IOException { - out.write(b); - } - - @Override - public void close() throws IOException { - try { - super.close(); - try { - transferContents(); - } catch (CoreException e) { - IOException ex = new IOException(e.getMessage()); - ex.initCause(e); - throw ex; - } - } finally { - deleteTempFile(); - } - - } - - private void transferContents() throws IOException, CoreException { - file.setContents(new FileInputStream(tempFile), IResource.KEEP_HISTORY, - monitor); - } - - private void deleteTempFile() { - FileUtils.delete(new File(tempFile)); - } - - private static String createTempFile() throws IOException { - String path = Core.getWorkspace().getTempFile( - Core.getIdFactory().createId()); - return path; - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.xmind.core.Core; +import org.xmind.core.util.FileUtils; + +public class ResourceFileOutputStream extends FilterOutputStream { + + private IFile file; + + private String tempFile; + + private IProgressMonitor monitor; + + public ResourceFileOutputStream(IFile file, IProgressMonitor monitor) + throws IOException { + super(null); + this.tempFile = createTempFile(); + this.file = file; + this.out = new FileOutputStream(tempFile); + this.monitor = monitor; + } + + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + @Override + public void write(int b) throws IOException { + out.write(b); + } + + @Override + public void close() throws IOException { + try { + super.close(); + try { + transferContents(); + } catch (CoreException e) { + IOException ex = new IOException(e.getMessage()); + ex.initCause(e); + throw ex; + } + } finally { + deleteTempFile(); + } + + } + + private void transferContents() throws IOException, CoreException { + file.setContents(new FileInputStream(tempFile), IResource.KEEP_HISTORY, + monitor); + } + + private void deleteTempFile() { + FileUtils.delete(new File(tempFile)); + } + + private static String createTempFile() throws IOException { + String path = Core.getWorkspace().getTempFile( + Core.getIdFactory().createId()); + return path; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveActionUpdater.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveActionUpdater.java index bf2aee841..f4f73fd46 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveActionUpdater.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveActionUpdater.java @@ -1,140 +1,140 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.internal.WorkbenchMessages; -import org.xmind.core.Core; -import org.xmind.core.IMeta; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventRegistration; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.ui.internal.MindMapMessages; - -public class SaveActionUpdater implements IPartListener, IPropertyListener, - ICoreEventListener { - - private IWorkbenchWindow window; - - private IWorkbenchAction action; - - private IEditorPart editor = null; - - private IWorkbook workbook = null; - - private ICoreEventRegistration eventReg = null; - - public SaveActionUpdater(IWorkbenchWindow window, IWorkbenchAction action) { - this.window = window; - this.action = action; - window.getPartService().addPartListener(this); - } - - public void dispose() { - handleEditorChange(null); - if (window != null) { - window.getPartService().removePartListener(this); - window = null; - } - } - - private void handleEditorChange(IEditorPart newEditor) { - IEditorPart oldEditor = this.editor; - this.editor = newEditor; - if (oldEditor != null) { - oldEditor.removePropertyListener(this); - } - if (newEditor != null) { - newEditor.addPropertyListener(this); - } - handleWorkbookChange(newEditor == null ? null : (IWorkbook) newEditor - .getAdapter(IWorkbook.class)); - } - - private void handleWorkbookChange(IWorkbook newWorkbook) { - this.workbook = newWorkbook; - if (eventReg != null) { - eventReg.unregister(); - eventReg = null; - } - if (newWorkbook != null) { - IMeta meta = newWorkbook.getMeta(); - if (meta instanceof ICoreEventSource) { - eventReg = ((ICoreEventSource) meta).registerCoreEventListener( - Core.Metadata, this); - } - } - updateText(); - } - - private void updateText() { - if (workbook != null && isAutoSave(workbook)) { - action.setText(MindMapMessages.SaveNewRevision_text); - } else { - action.setText(WorkbenchMessages.SaveAction_text); - } - } - - private static final boolean isAutoSave(IWorkbook workbook) { - String value = workbook.getMeta().getValue( - IMeta.CONFIG_AUTO_REVISION_GENERATION); - return value == null || IMeta.V_YES.equalsIgnoreCase(value); - } - - public void partActivated(IWorkbenchPart part) { - if (!(part instanceof IEditorPart)) - return; - - handleEditorChange((IEditorPart) part); - } - - public void partBroughtToTop(IWorkbenchPart part) { - } - - public void partClosed(IWorkbenchPart part) { - } - - public void partDeactivated(IWorkbenchPart part) { - } - - public void partOpened(IWorkbenchPart part) { - } - - public void propertyChanged(Object source, int propId) { - if (propId == IEditorPart.PROP_INPUT) { - handleWorkbookChange(editor == null ? null : (IWorkbook) editor - .getAdapter(IWorkbook.class)); - } - } - - public void handleCoreEvent(final CoreEvent event) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - public void run() { - if (IMeta.CONFIG_AUTO_REVISION_GENERATION.equals(event - .getTarget())) { - updateText(); - } - } - }); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.xmind.core.Core; +import org.xmind.core.IMeta; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventRegistration; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.ui.internal.MindMapMessages; + +public class SaveActionUpdater implements IPartListener, IPropertyListener, + ICoreEventListener { + + private IWorkbenchWindow window; + + private IWorkbenchAction action; + + private IEditorPart editor = null; + + private IWorkbook workbook = null; + + private ICoreEventRegistration eventReg = null; + + public SaveActionUpdater(IWorkbenchWindow window, IWorkbenchAction action) { + this.window = window; + this.action = action; + window.getPartService().addPartListener(this); + } + + public void dispose() { + handleEditorChange(null); + if (window != null) { + window.getPartService().removePartListener(this); + window = null; + } + } + + private void handleEditorChange(IEditorPart newEditor) { + IEditorPart oldEditor = this.editor; + this.editor = newEditor; + if (oldEditor != null) { + oldEditor.removePropertyListener(this); + } + if (newEditor != null) { + newEditor.addPropertyListener(this); + } + handleWorkbookChange(newEditor == null ? null : (IWorkbook) newEditor + .getAdapter(IWorkbook.class)); + } + + private void handleWorkbookChange(IWorkbook newWorkbook) { + this.workbook = newWorkbook; + if (eventReg != null) { + eventReg.unregister(); + eventReg = null; + } + if (newWorkbook != null) { + IMeta meta = newWorkbook.getMeta(); + if (meta instanceof ICoreEventSource) { + eventReg = ((ICoreEventSource) meta).registerCoreEventListener( + Core.Metadata, this); + } + } + updateText(); + } + + private void updateText() { + if (workbook != null && isAutoSave(workbook)) { + action.setText(MindMapMessages.SaveNewRevision_text); + } else { + action.setText(WorkbenchMessages.SaveAction_text); + } + } + + private static final boolean isAutoSave(IWorkbook workbook) { + String value = workbook.getMeta().getValue( + IMeta.CONFIG_AUTO_REVISION_GENERATION); + return value == null || IMeta.V_YES.equalsIgnoreCase(value); + } + + public void partActivated(IWorkbenchPart part) { + if (!(part instanceof IEditorPart)) + return; + + handleEditorChange((IEditorPart) part); + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + public void propertyChanged(Object source, int propId) { + if (propId == IEditorPart.PROP_INPUT) { + handleWorkbookChange(editor == null ? null : (IWorkbook) editor + .getAdapter(IWorkbook.class)); + } + } + + public void handleCoreEvent(final CoreEvent event) { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + if (IMeta.CONFIG_AUTO_REVISION_GENERATION.equals(event + .getTarget())) { + updateText(); + } + } + }); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveWizardManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveWizardManager.java index 717a66763..16e1bded2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveWizardManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/SaveWizardManager.java @@ -1,183 +1,183 @@ -package org.xmind.ui.internal.editor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.IRegistryEventListener; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.wizards.ISaveWizard; - -public class SaveWizardManager implements IRegistryEventListener { - - public static class SaveWizardDescriptor { - - private String id; - - private IConfigurationElement element; - - private ISaveWizard wizard = null; - - private SaveWizardDescriptor(String id, IConfigurationElement element) { - this.id = id; - this.element = element; - } - - public String getId() { - return id; - } - - public ISaveWizard getWizard() { - if (wizard == null && element != null) { - try { - wizard = (ISaveWizard) element.createExecutableExtension( - IWorkbenchRegistryConstants.ATT_CLASS); - } catch (CoreException e) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, - "Failed to create save wizard from class: " //$NON-NLS-1$ - + element.getDeclaringExtension() - .getNamespaceIdentifier() - + "/" //$NON-NLS-1$ - + element.getAttribute( - IWorkbenchRegistryConstants.ATT_CLASS), - e)); - return null; - } - } - return wizard; - } - - private void dispose() { - this.element = null; - this.wizard = null; - } - - private boolean isFromExtension(IExtension ext) { - return element != null && ext != null - && ext.equals(element.getDeclaringExtension()); - } - - public String getName() { - String name = element - .getAttribute(IWorkbenchRegistryConstants.ATT_NAME); - return name == null ? "" : name; //$NON-NLS-1$ - } - - } - - private List wizards = null; - - private IExtensionRegistry registry = null; - - public SaveWizardManager() { - } - - public List getWizards() { - ensureLoaded(); - return Collections.unmodifiableList(wizards); - } - - private synchronized void ensureLoaded() { - if (wizards != null) - return; - - wizards = new ArrayList(); - - registry = Platform.getExtensionRegistry(); - IExtensionPoint extPoint = registry.getExtensionPoint( - MindMapUI.PLUGIN_ID, RegistryConstants.EXT_SAVE_WIZARDS); - if (extPoint == null) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, - "Extension point '" + MindMapUI.PLUGIN_ID //$NON-NLS-1$ - + "." + RegistryConstants.EXT_SAVE_WIZARDS //$NON-NLS-1$ - + "' not found.")); //$NON-NLS-1$ - return; - } - - registry.addListener(this, extPoint.getUniqueIdentifier()); - - readExtensions(extPoint.getExtensions()); - } - - private void readExtensions(IExtension[] extensions) { - for (IExtension ext : extensions) { - for (IConfigurationElement element : ext - .getConfigurationElements()) { - if (RegistryConstants.TAG_SAVE_WIZARD - .equals(element.getName())) { - String id = element - .getAttribute(IWorkbenchRegistryConstants.ATT_ID); - String clazz = element.getAttribute( - IWorkbenchRegistryConstants.ATT_CLASS); - if (id == null || id.length() <= 0 || clazz == null - || clazz.length() <= 0) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, - MindMapUIPlugin.PLUGIN_ID, - "Invalid save wizard extension in " //$NON-NLS-1$ - + ext.getUniqueIdentifier())); - continue; - } - wizards.add(new SaveWizardDescriptor(id, element)); - } - } - } - } - - public synchronized void dispose() { - if (wizards != null) { - SaveWizardDescriptor[] ws = wizards - .toArray(new SaveWizardDescriptor[wizards.size()]); - wizards = null; - for (SaveWizardDescriptor w : ws) { - w.dispose(); - } - } - } - - @Override - public void added(IExtension[] extensions) { - readExtensions(extensions); - } - - @Override - public void removed(IExtension[] extensions) { - if (wizards != null) { - for (IExtension ext : extensions) { - SaveWizardDescriptor[] ws = wizards - .toArray(new SaveWizardDescriptor[wizards.size()]); - for (SaveWizardDescriptor w : ws) { - if (w.isFromExtension(ext)) { - wizards.remove(w); - w.dispose(); - } - } - } - } - } - - @Override - public void added(IExtensionPoint[] extensionPoints) { - // do not care about other extension points - } - - @Override - public void removed(IExtensionPoint[] extensionPoints) { - // do not care about other extension points - } - -} +package org.xmind.ui.internal.editor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IRegistryEventListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.wizards.ISaveWizard; + +public class SaveWizardManager implements IRegistryEventListener { + + public static class SaveWizardDescriptor { + + private String id; + + private IConfigurationElement element; + + private ISaveWizard wizard = null; + + private SaveWizardDescriptor(String id, IConfigurationElement element) { + this.id = id; + this.element = element; + } + + public String getId() { + return id; + } + + public ISaveWizard getWizard() { + if (wizard == null && element != null) { + try { + wizard = (ISaveWizard) element.createExecutableExtension( + IWorkbenchRegistryConstants.ATT_CLASS); + } catch (CoreException e) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, + "Failed to create save wizard from class: " //$NON-NLS-1$ + + element.getDeclaringExtension() + .getNamespaceIdentifier() + + "/" //$NON-NLS-1$ + + element.getAttribute( + IWorkbenchRegistryConstants.ATT_CLASS), + e)); + return null; + } + } + return wizard; + } + + private void dispose() { + this.element = null; + this.wizard = null; + } + + private boolean isFromExtension(IExtension ext) { + return element != null && ext != null + && ext.equals(element.getDeclaringExtension()); + } + + public String getName() { + String name = element + .getAttribute(IWorkbenchRegistryConstants.ATT_NAME); + return name == null ? "" : name; //$NON-NLS-1$ + } + + } + + private List wizards = null; + + private IExtensionRegistry registry = null; + + public SaveWizardManager() { + } + + public List getWizards() { + ensureLoaded(); + return Collections.unmodifiableList(wizards); + } + + private synchronized void ensureLoaded() { + if (wizards != null) + return; + + wizards = new ArrayList(); + + registry = Platform.getExtensionRegistry(); + IExtensionPoint extPoint = registry.getExtensionPoint( + MindMapUI.PLUGIN_ID, RegistryConstants.EXT_SAVE_WIZARDS); + if (extPoint == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Extension point '" + MindMapUI.PLUGIN_ID //$NON-NLS-1$ + + "." + RegistryConstants.EXT_SAVE_WIZARDS //$NON-NLS-1$ + + "' not found.")); //$NON-NLS-1$ + return; + } + + registry.addListener(this, extPoint.getUniqueIdentifier()); + + readExtensions(extPoint.getExtensions()); + } + + private void readExtensions(IExtension[] extensions) { + for (IExtension ext : extensions) { + for (IConfigurationElement element : ext + .getConfigurationElements()) { + if (RegistryConstants.TAG_SAVE_WIZARD + .equals(element.getName())) { + String id = element + .getAttribute(IWorkbenchRegistryConstants.ATT_ID); + String clazz = element.getAttribute( + IWorkbenchRegistryConstants.ATT_CLASS); + if (id == null || id.length() <= 0 || clazz == null + || clazz.length() <= 0) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, + MindMapUIPlugin.PLUGIN_ID, + "Invalid save wizard extension in " //$NON-NLS-1$ + + ext.getUniqueIdentifier())); + continue; + } + wizards.add(new SaveWizardDescriptor(id, element)); + } + } + } + } + + public synchronized void dispose() { + if (wizards != null) { + SaveWizardDescriptor[] ws = wizards + .toArray(new SaveWizardDescriptor[wizards.size()]); + wizards = null; + for (SaveWizardDescriptor w : ws) { + w.dispose(); + } + } + } + + @Override + public void added(IExtension[] extensions) { + readExtensions(extensions); + } + + @Override + public void removed(IExtension[] extensions) { + if (wizards != null) { + for (IExtension ext : extensions) { + SaveWizardDescriptor[] ws = wizards + .toArray(new SaveWizardDescriptor[wizards.size()]); + for (SaveWizardDescriptor w : ws) { + if (w.isFromExtension(ext)) { + wizards.remove(w); + w.dispose(); + } + } + } + } + } + + @Override + public void added(IExtensionPoint[] extensionPoints) { + // do not care about other extension points + } + + @Override + public void removed(IExtensionPoint[] extensionPoints) { + // do not care about other extension points + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/TempWorkbookRefFactory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/TempWorkbookRefFactory.java index c960f2da5..5c0976387 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/TempWorkbookRefFactory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/TempWorkbookRefFactory.java @@ -1,32 +1,32 @@ -package org.xmind.ui.internal.editor; - -import java.net.URI; - -import org.eclipse.ui.IMemento; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefFactory; - -public class TempWorkbookRefFactory implements IWorkbookRefFactory { - - public static final String URI_SCHEME = "xmind-temp"; //$NON-NLS-1$ - - public TempWorkbookRefFactory() { - } - - public IWorkbookRef createWorkbookRef(URI uri, IMemento state) { - String path = uri.getPath(); - if (path == null) - return null; - - if (CreatedWorkbookRef.URI_PATH.equals(path)) { - return CreatedWorkbookRef.create(uri, state); - } - - if (ClonedWorkbookRef.URI_PATH.equals(path)) { - return ClonedWorkbookRef.create(uri, state); - } - - return null; - } - -} +package org.xmind.ui.internal.editor; + +import java.net.URI; + +import org.eclipse.ui.IMemento; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefFactory; + +public class TempWorkbookRefFactory implements IWorkbookRefFactory { + + public static final String URI_SCHEME = "xmind-temp"; //$NON-NLS-1$ + + public TempWorkbookRefFactory() { + } + + public IWorkbookRef createWorkbookRef(URI uri, IMemento state) { + String path = uri.getPath(); + if (path == null) + return null; + + if (CreatedWorkbookRef.URI_PATH.equals(path)) { + return CreatedWorkbookRef.create(uri, state); + } + + if (ClonedWorkbookRef.URI_PATH.equals(path)) { + return ClonedWorkbookRef.create(uri, state); + } + + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URIParser.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URIParser.java index d72b0ba89..8a4d6af45 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URIParser.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URIParser.java @@ -1,131 +1,131 @@ -package org.xmind.ui.internal.editor; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Iterator; - -import org.eclipse.core.runtime.Assert; - -public final class URIParser { - - private URIParser() { - throw new AssertionError(); - } - - public static String quote(String str) { - try { - return URLEncoder.encode(str, "UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } - } - - public static String unquote(String str) { - try { - return URLDecoder.decode(str, "UTF-8"); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } - } - - public static final class QueryParameter { - public final String name; - public final String value; - - private QueryParameter(String name, String value) { - this.name = name; - this.value = value; - } - } - - public static Iterator iterateQueryParameters(URI uri) { - final String query = uri.getQuery(); - return new Iterator() { - - int pos = 0; - - QueryParameter next = findNext(); - - public boolean hasNext() { - return next != null; - } - - public QueryParameter next() { - QueryParameter n = this.next; - this.next = findNext(); - return n; - } - - public void remove() { - } - - private QueryParameter findNext() { - if (query == null) - return null; - - String param; - int sep; - if (pos < 0) - return null; - - sep = query.indexOf('&', pos); - if (sep < 0) { - param = query.substring(pos); - pos = -1; - } else { - param = query.substring(pos, sep); - pos = sep + 1; - } - - sep = param.indexOf('='); - if (sep < 0) { - return new QueryParameter(unquote(param.substring(0)), ""); //$NON-NLS-1$ - } else { - return new QueryParameter(unquote(param.substring(0, sep)), - unquote(param.substring(sep + 1))); - } - - } - }; - } - - public static String getQueryParameter(URI uri, String name) { - Assert.isNotNull(uri); - Assert.isNotNull(name); - Iterator it = iterateQueryParameters(uri); - while (it.hasNext()) { - QueryParameter param = it.next(); - if (name.equals(param.name)) - return param.value; - } - return null; - } - - public static URI appendQueryParameter(URI uri, QueryParameter param) { - return appendQueryParameter(uri, param.name, param.value); - } - - public static URI appendQueryParameter(URI uri, String name, String value) { - String query = uri.getQuery(); - if (name != null && name.length() > 0) { - if (query != null && query.length() > 0) { - query = query + "&" + quote(name); //$NON-NLS-1$ - } else { - query = quote(name); - } - if (value != null && value.length() > 0) { - query = query + "=" + quote(value); //$NON-NLS-1$ - } - } - try { - return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), - uri.getPort(), uri.getPath(), query, uri.getFragment()); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } - -} +package org.xmind.ui.internal.editor; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Iterator; + +import org.eclipse.core.runtime.Assert; + +public final class URIParser { + + private URIParser() { + throw new AssertionError(); + } + + public static String quote(String str) { + try { + return URLEncoder.encode(str, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(e); + } + } + + public static String unquote(String str) { + try { + return URLDecoder.decode(str, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(e); + } + } + + public static final class QueryParameter { + public final String name; + public final String value; + + private QueryParameter(String name, String value) { + this.name = name; + this.value = value; + } + } + + public static Iterator iterateQueryParameters(URI uri) { + final String query = uri.getQuery(); + return new Iterator() { + + int pos = 0; + + QueryParameter next = findNext(); + + public boolean hasNext() { + return next != null; + } + + public QueryParameter next() { + QueryParameter n = this.next; + this.next = findNext(); + return n; + } + + public void remove() { + } + + private QueryParameter findNext() { + if (query == null) + return null; + + String param; + int sep; + if (pos < 0) + return null; + + sep = query.indexOf('&', pos); + if (sep < 0) { + param = query.substring(pos); + pos = -1; + } else { + param = query.substring(pos, sep); + pos = sep + 1; + } + + sep = param.indexOf('='); + if (sep < 0) { + return new QueryParameter(unquote(param.substring(0)), ""); //$NON-NLS-1$ + } else { + return new QueryParameter(unquote(param.substring(0, sep)), + unquote(param.substring(sep + 1))); + } + + } + }; + } + + public static String getQueryParameter(URI uri, String name) { + Assert.isNotNull(uri); + Assert.isNotNull(name); + Iterator it = iterateQueryParameters(uri); + while (it.hasNext()) { + QueryParameter param = it.next(); + if (name.equals(param.name)) + return param.value; + } + return null; + } + + public static URI appendQueryParameter(URI uri, QueryParameter param) { + return appendQueryParameter(uri, param.name, param.value); + } + + public static URI appendQueryParameter(URI uri, String name, String value) { + String query = uri.getQuery(); + if (name != null && name.length() > 0) { + if (query != null && query.length() > 0) { + query = query + "&" + quote(name); //$NON-NLS-1$ + } else { + query = quote(name); + } + if (value != null && value.length() > 0) { + query = query + "=" + quote(value); //$NON-NLS-1$ + } + } + try { + return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), + uri.getPort(), uri.getPath(), query, uri.getFragment()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URLWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URLWorkbookRef.java index 906572b74..9c389475a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URLWorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/URLWorkbookRef.java @@ -1,231 +1,231 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URL; -import java.util.Map; -import java.util.WeakHashMap; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.URIUtil; -import org.eclipse.ui.IMemento; -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IDeserializer; -import org.xmind.core.IWorkbook; -import org.xmind.core.io.BundleResource; -import org.xmind.core.io.BundleResourceInputSource; -import org.xmind.core.io.DirectoryInputSource; -import org.xmind.core.util.ProgressReporter; - -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ -public class URLWorkbookRef extends AbstractWorkbookRef { - - private static final String SCHEME_PLATFORM = "platform"; //$NON-NLS-1$ - - private static final String ATT_NAME = "name"; //$NON-NLS-1$ - - private static Map cache = new WeakHashMap(); - - private String name; - - private URLWorkbookRef(URI uri, String name, IMemento state) { - super(uri, state); - Assert.isNotNull(uri); - this.name = name == null - ? (state == null ? null : state.getString(ATT_NAME)) : name; - } - - @Override - public boolean canSave() { - return false; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.gef.ui.editor.Editable#getName() - */ - @Override - public String getName() { - if (name != null) - return name; - return super.getName(); - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.internal.editor.AbstractWorkbookRef#saveState(org.eclipse.ui - * .IMemento) - */ - @Override - protected void saveState(IMemento memento) { - if (name != null) { - memento.putString(ATT_NAME, name); - } - super.saveState(memento); - } - - @Override - public int hashCode() { - return getURI().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof URLWorkbookRef)) - return false; - URLWorkbookRef that = (URLWorkbookRef) obj; - URI thisURI = this.getURI(); - URI thatURI = that.getURI(); - return thisURI == thatURI - || (thisURI != null && thisURI.equals(thatURI)); - } - - @Override - public String toString() { - return getURI().toString(); - } - - public static URLWorkbookRef create(URI uri, IMemento state) { - if (uri == null) - return null; - - if (state != null) - return new URLWorkbookRef(uri, null, state); - - for (URLWorkbookRef wr : cache.keySet()) { - if (uri.equals(wr.getURI())) - return wr; - } - URLWorkbookRef wr = new URLWorkbookRef(uri, null, null); - cache.put(wr, uri); - return wr; - } - - public static URLWorkbookRef create(URI uri, String name) { - if (uri == null) - return null; - - for (URLWorkbookRef wr : cache.keySet()) { - if (uri.equals(wr.getURI())) - return wr; - } - URLWorkbookRef wr = new URLWorkbookRef(uri, name, null); - cache.put(wr, uri); - return wr; - } - - @Override - protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) - throws InterruptedException, InvocationTargetException { - try { - if (URIUtil.isFileURI(uri)) { - return loadFromFileURI(monitor, uri); - } else if (SCHEME_PLATFORM.equalsIgnoreCase(uri.getScheme())) { - return loadFromPlatformURI(monitor, uri); - } else { - return loadFromGenericURI(monitor, uri); - } - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - } - - private IWorkbook loadFromGenericURI(IProgressMonitor monitor, URI uri) - throws IOException, CoreException { - URL url = uri.toURL(); - InputStream stream = url.openStream(); - try { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setWorkbookStorage(getTempStorage()); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.setInputStream(stream); - ProgressReporter reporter = new ProgressReporter(monitor); -// deserializer.deserializeManifest(reporter); -// String passwordHint = deserializer.getManifest().getPasswordHint(); -// getEncryptable().setPasswordHint(passwordHint); - deserializer.deserialize(reporter); - return deserializer.getWorkbook(); - } finally { - stream.close(); - } - } - - private IWorkbook loadFromFileURI(IProgressMonitor monitor, URI uri) - throws IOException, CoreException { - File file = URIUtil.toFile(uri); - if (file.isDirectory()) { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setWorkbookStorage(getTempStorage()); - deserializer.setInputSource(new DirectoryInputSource(file)); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.deserialize(new ProgressReporter(monitor)); - return deserializer.getWorkbook(); - } - return loadFromGenericURI(monitor, uri); - } - - private IWorkbook loadFromPlatformURI(IProgressMonitor monitor, URI uri) - throws IOException, CoreException { - // use decoded path, or the file with '%20' in path will not be found - URL url = new URL(uri.getScheme(), uri.getAuthority(), uri.getPath()); - - BundleResource resource; - try { - resource = new BundleResource(url); - } catch (IllegalArgumentException e) { - resource = null; - } - if (resource != null) { - BundleResource resolvedResource = resource.resolve(); - if (resolvedResource != null - && resolvedResource.getPath().hasTrailingSeparator()) { - // the workbook URI represents a directory - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setWorkbookStorage(getTempStorage()); - deserializer.setInputSource( - new BundleResourceInputSource(resolvedResource)); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.deserialize(new ProgressReporter(monitor)); - return deserializer.getWorkbook(); - } - } - - URL locatedURL = FileLocator.find(url); - if (locatedURL != null) { - url = locatedURL; - } - InputStream stream = url.openStream(); - try { - IDeserializer deserializer = Core.getWorkbookBuilder() - .newDeserializer(); - deserializer.setWorkbookStorage(getTempStorage()); - deserializer.setEntryStreamNormalizer(getEncryptionHandler()); - deserializer.setInputStream(stream); - deserializer.deserialize(new ProgressReporter(monitor)); - return deserializer.getWorkbook(); - } finally { - stream.close(); - } - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URL; +import java.util.Map; +import java.util.WeakHashMap; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.ui.IMemento; +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IDeserializer; +import org.xmind.core.IWorkbook; +import org.xmind.core.io.BundleResource; +import org.xmind.core.io.BundleResourceInputSource; +import org.xmind.core.io.DirectoryInputSource; +import org.xmind.core.util.ProgressReporter; + +/** + * + * @author Frank Shaka + * @since 3.6.50 + */ +public class URLWorkbookRef extends AbstractWorkbookRef { + + private static final String SCHEME_PLATFORM = "platform"; //$NON-NLS-1$ + + private static final String ATT_NAME = "name"; //$NON-NLS-1$ + + private static Map cache = new WeakHashMap(); + + private String name; + + private URLWorkbookRef(URI uri, String name, IMemento state) { + super(uri, state); + Assert.isNotNull(uri); + this.name = name == null + ? (state == null ? null : state.getString(ATT_NAME)) : name; + } + + @Override + public boolean canSave() { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.gef.ui.editor.Editable#getName() + */ + @Override + public String getName() { + if (name != null) + return name; + return super.getName(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.internal.editor.AbstractWorkbookRef#saveState(org.eclipse.ui + * .IMemento) + */ + @Override + protected void saveState(IMemento memento) { + if (name != null) { + memento.putString(ATT_NAME, name); + } + super.saveState(memento); + } + + @Override + public int hashCode() { + return getURI().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof URLWorkbookRef)) + return false; + URLWorkbookRef that = (URLWorkbookRef) obj; + URI thisURI = this.getURI(); + URI thatURI = that.getURI(); + return thisURI == thatURI + || (thisURI != null && thisURI.equals(thatURI)); + } + + @Override + public String toString() { + return getURI().toString(); + } + + public static URLWorkbookRef create(URI uri, IMemento state) { + if (uri == null) + return null; + + if (state != null) + return new URLWorkbookRef(uri, null, state); + + for (URLWorkbookRef wr : cache.keySet()) { + if (uri.equals(wr.getURI())) + return wr; + } + URLWorkbookRef wr = new URLWorkbookRef(uri, null, null); + cache.put(wr, uri); + return wr; + } + + public static URLWorkbookRef create(URI uri, String name) { + if (uri == null) + return null; + + for (URLWorkbookRef wr : cache.keySet()) { + if (uri.equals(wr.getURI())) + return wr; + } + URLWorkbookRef wr = new URLWorkbookRef(uri, name, null); + cache.put(wr, uri); + return wr; + } + + @Override + protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) + throws InterruptedException, InvocationTargetException { + try { + if (URIUtil.isFileURI(uri)) { + return loadFromFileURI(monitor, uri); + } else if (SCHEME_PLATFORM.equalsIgnoreCase(uri.getScheme())) { + return loadFromPlatformURI(monitor, uri); + } else { + return loadFromGenericURI(monitor, uri); + } + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } + } + + private IWorkbook loadFromGenericURI(IProgressMonitor monitor, URI uri) + throws IOException, CoreException { + URL url = uri.toURL(); + InputStream stream = url.openStream(); + try { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setWorkbookStorage(getTempStorage()); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.setInputStream(stream); + ProgressReporter reporter = new ProgressReporter(monitor); +// deserializer.deserializeManifest(reporter); +// String passwordHint = deserializer.getManifest().getPasswordHint(); +// getEncryptable().setPasswordHint(passwordHint); + deserializer.deserialize(reporter); + return deserializer.getWorkbook(); + } finally { + stream.close(); + } + } + + private IWorkbook loadFromFileURI(IProgressMonitor monitor, URI uri) + throws IOException, CoreException { + File file = URIUtil.toFile(uri); + if (file.isDirectory()) { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setWorkbookStorage(getTempStorage()); + deserializer.setInputSource(new DirectoryInputSource(file)); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.deserialize(new ProgressReporter(monitor)); + return deserializer.getWorkbook(); + } + return loadFromGenericURI(monitor, uri); + } + + private IWorkbook loadFromPlatformURI(IProgressMonitor monitor, URI uri) + throws IOException, CoreException { + // use decoded path, or the file with '%20' in path will not be found + URL url = new URL(uri.getScheme(), uri.getAuthority(), uri.getPath()); + + BundleResource resource; + try { + resource = new BundleResource(url); + } catch (IllegalArgumentException e) { + resource = null; + } + if (resource != null) { + BundleResource resolvedResource = resource.resolve(); + if (resolvedResource != null + && resolvedResource.getPath().hasTrailingSeparator()) { + // the workbook URI represents a directory + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setWorkbookStorage(getTempStorage()); + deserializer.setInputSource( + new BundleResourceInputSource(resolvedResource)); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.deserialize(new ProgressReporter(monitor)); + return deserializer.getWorkbook(); + } + } + + URL locatedURL = FileLocator.find(url); + if (locatedURL != null) { + url = locatedURL; + } + InputStream stream = url.openStream(); + try { + IDeserializer deserializer = Core.getWorkbookBuilder() + .newDeserializer(); + deserializer.setWorkbookStorage(getTempStorage()); + deserializer.setEntryStreamNormalizer(getEncryptionHandler()); + deserializer.setInputStream(stream); + deserializer.deserialize(new ProgressReporter(monitor)); + return deserializer.getWorkbook(); + } finally { + stream.close(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookBackupManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookBackupManager.java index d80a115ba..aa97b16a7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookBackupManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookBackupManager.java @@ -1,155 +1,155 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.core.runtime.jobs.ISchedulingRule; - -/** - * @deprecated - */ -@Deprecated -public class WorkbookBackupManager implements ISchedulingRule { - -// private class WorkbookBackupWorker extends Job { -// -// private WorkbookRef ref; -// -// private IWorkbookBackup backup = null; -// -// public WorkbookBackupWorker(WorkbookRef ref) { -// super("WorkbookBackupWorker-" + ref.getKey().toString()); //$NON-NLS-1$ -// this.ref = ref; -// } -// -// public WorkbookRef getRef() { -// return ref; -// } -// -// public IWorkbookBackup getBackup() { -// return backup; -// } -// -// protected IStatus run(IProgressMonitor monitor) { -// try { -// IWorkbookBackupFactory backupper = ref -// .getWorkbookBackupFactory(); -// if (backupper != null) { -// backup = backupper.createWorkbookBackup(monitor, -// backups.get(ref)); -// } -// } catch (Throwable e) { -// return new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, -// "Failed to make backup for workbook: " //$NON-NLS-1$ -// + ref.getKey().toString(), -// e); -// } -// if (monitor.isCanceled()) -// return Status.CANCEL_STATUS; -// return Status.OK_STATUS; -// } -// -// } -// -// private static final WorkbookBackupManager instance = new WorkbookBackupManager(); -// -// private Map backups = new HashMap(); -// -// private Map workers = new HashMap(); -// -// private IJobChangeListener workerListener = new JobChangeAdapter() { -// public void done(IJobChangeEvent event) { -// handleWorkerDone((WorkbookBackupWorker) event.getJob(), -// event.getResult()); -// } -// }; -// -// private WorkbookBackupManager() { -// } -// -// private WorkbookBackupWorker createWorker(WorkbookRef ref) { -// WorkbookBackupWorker worker = new WorkbookBackupWorker(ref); -// worker.setRule(this); -// worker.setSystem(true); -// worker.setPriority(Job.SHORT); -// worker.addJobChangeListener(workerListener); -// workers.put(ref, worker); -// worker.schedule(); -// return worker; -// } -// -// private void handleWorkerDone(WorkbookBackupWorker worker, IStatus result) { -// if (result.isOK()) { -// IWorkbookBackup newBackup = worker.getBackup(); -// IWorkbookBackup oldBackup = backups.put(worker.getRef(), newBackup); -// if (oldBackup != null && !oldBackup.equals(newBackup)) { -// oldBackup.dispose(); -// } -// } -// workers.remove(worker.getRef()); -// } -// -// public synchronized void addWorkbook(WorkbookRef ref) { -// if (backups.containsKey(ref)) -// return; -// -// IWorkbookBackup oldBackup = backups.put(ref, null); -// if (oldBackup != null) { -// oldBackup.dispose(); -// } -// createWorker(ref); -// } -// -// public synchronized void removeWorkbook(WorkbookRef ref) { -// if (!backups.containsKey(ref)) -// return; -// -// IWorkbookBackup backup = backups.remove(ref); -// if (backup != null) { -// backup.dispose(); -// } -// WorkbookBackupWorker worker = workers.remove(ref); -// if (worker != null) { -// worker.cancel(); -// } -// } -// -// public synchronized IWorkbookBackup ensureBackedUp(WorkbookRef ref, -// IProgressMonitor monitor) { -// if (!workers.containsKey(ref)) { -// createWorker(ref); -// } -// try { -// while (workers.containsKey(ref)) { -// if (monitor.isCanceled()) -// break; -// Thread.sleep(1); -// } -// } catch (InterruptedException e) { -// } -// return backups.get(ref); -// } -// -// public static WorkbookBackupManager getInstance() { -// return instance; -// } - - public boolean contains(ISchedulingRule rule) { - return rule == this; - } - - public boolean isConflicting(ISchedulingRule rule) { - return rule == this; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; + +/** + * @deprecated + */ +@Deprecated +public class WorkbookBackupManager implements ISchedulingRule { + +// private class WorkbookBackupWorker extends Job { +// +// private WorkbookRef ref; +// +// private IWorkbookBackup backup = null; +// +// public WorkbookBackupWorker(WorkbookRef ref) { +// super("WorkbookBackupWorker-" + ref.getKey().toString()); //$NON-NLS-1$ +// this.ref = ref; +// } +// +// public WorkbookRef getRef() { +// return ref; +// } +// +// public IWorkbookBackup getBackup() { +// return backup; +// } +// +// protected IStatus run(IProgressMonitor monitor) { +// try { +// IWorkbookBackupFactory backupper = ref +// .getWorkbookBackupFactory(); +// if (backupper != null) { +// backup = backupper.createWorkbookBackup(monitor, +// backups.get(ref)); +// } +// } catch (Throwable e) { +// return new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, +// "Failed to make backup for workbook: " //$NON-NLS-1$ +// + ref.getKey().toString(), +// e); +// } +// if (monitor.isCanceled()) +// return Status.CANCEL_STATUS; +// return Status.OK_STATUS; +// } +// +// } +// +// private static final WorkbookBackupManager instance = new WorkbookBackupManager(); +// +// private Map backups = new HashMap(); +// +// private Map workers = new HashMap(); +// +// private IJobChangeListener workerListener = new JobChangeAdapter() { +// public void done(IJobChangeEvent event) { +// handleWorkerDone((WorkbookBackupWorker) event.getJob(), +// event.getResult()); +// } +// }; +// +// private WorkbookBackupManager() { +// } +// +// private WorkbookBackupWorker createWorker(WorkbookRef ref) { +// WorkbookBackupWorker worker = new WorkbookBackupWorker(ref); +// worker.setRule(this); +// worker.setSystem(true); +// worker.setPriority(Job.SHORT); +// worker.addJobChangeListener(workerListener); +// workers.put(ref, worker); +// worker.schedule(); +// return worker; +// } +// +// private void handleWorkerDone(WorkbookBackupWorker worker, IStatus result) { +// if (result.isOK()) { +// IWorkbookBackup newBackup = worker.getBackup(); +// IWorkbookBackup oldBackup = backups.put(worker.getRef(), newBackup); +// if (oldBackup != null && !oldBackup.equals(newBackup)) { +// oldBackup.dispose(); +// } +// } +// workers.remove(worker.getRef()); +// } +// +// public synchronized void addWorkbook(WorkbookRef ref) { +// if (backups.containsKey(ref)) +// return; +// +// IWorkbookBackup oldBackup = backups.put(ref, null); +// if (oldBackup != null) { +// oldBackup.dispose(); +// } +// createWorker(ref); +// } +// +// public synchronized void removeWorkbook(WorkbookRef ref) { +// if (!backups.containsKey(ref)) +// return; +// +// IWorkbookBackup backup = backups.remove(ref); +// if (backup != null) { +// backup.dispose(); +// } +// WorkbookBackupWorker worker = workers.remove(ref); +// if (worker != null) { +// worker.cancel(); +// } +// } +// +// public synchronized IWorkbookBackup ensureBackedUp(WorkbookRef ref, +// IProgressMonitor monitor) { +// if (!workers.containsKey(ref)) { +// createWorker(ref); +// } +// try { +// while (workers.containsKey(ref)) { +// if (monitor.isCanceled()) +// break; +// Thread.sleep(1); +// } +// } catch (InterruptedException e) { +// } +// return backups.get(ref); +// } +// +// public static WorkbookBackupManager getInstance() { +// return instance; +// } + + public boolean contains(ISchedulingRule rule) { + return rule == this; + } + + public boolean isConflicting(ISchedulingRule rule) { + return rule == this; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookEditorInput.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookEditorInput.java index 5b57a7ae7..754f6ceb8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookEditorInput.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookEditorInput.java @@ -1,100 +1,100 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IPersistableElement; -import org.xmind.core.IWorkbook; -import org.xmind.ui.internal.MindMapMessages; - -/** - * This class is used to represent an existing workbook as an editor input. - * - * @author Frank Shaka - * @deprecated - */ -@Deprecated -public class WorkbookEditorInput implements IEditorInput { - - private static int NUMBER = 0; - - private String name; - - private IWorkbook contents; - - public WorkbookEditorInput(String name, IWorkbook workbook) { - this.contents = workbook; - this.name = name; - } - - /** - * Create an editor input with a loaded workbook. - * - * @param contents - * The loaded workbook - */ - public WorkbookEditorInput(IWorkbook contents) { - this(null, contents); - } - - public boolean exists() { - return false; - } - - public ImageDescriptor getImageDescriptor() { - return null; - } - - public String getName() { - if (name == null) { - ++NUMBER; - name = NLS.bind(MindMapMessages.WorkbookEditorInput_name, NUMBER); - } - return name; - } - - public IPersistableElement getPersistable() { - return null; - } - - public String getToolTipText() { - return getName(); - } - - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter == IWorkbook.class) - return getContents(); - return Platform.getAdapterManager().getAdapter(this, adapter); - } - - public IWorkbook getContents() { - return contents; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof WorkbookEditorInput)) - return false; - WorkbookEditorInput that = (WorkbookEditorInput) obj; - if (this.contents == null || that.contents == null) - return false; - return that.contents.equals(this.contents); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; +import org.xmind.core.IWorkbook; +import org.xmind.ui.internal.MindMapMessages; + +/** + * This class is used to represent an existing workbook as an editor input. + * + * @author Frank Shaka + * @deprecated + */ +@Deprecated +public class WorkbookEditorInput implements IEditorInput { + + private static int NUMBER = 0; + + private String name; + + private IWorkbook contents; + + public WorkbookEditorInput(String name, IWorkbook workbook) { + this.contents = workbook; + this.name = name; + } + + /** + * Create an editor input with a loaded workbook. + * + * @param contents + * The loaded workbook + */ + public WorkbookEditorInput(IWorkbook contents) { + this(null, contents); + } + + public boolean exists() { + return false; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + if (name == null) { + ++NUMBER; + name = NLS.bind(MindMapMessages.WorkbookEditorInput_name, NUMBER); + } + return name; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return getName(); + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter == IWorkbook.class) + return getContents(); + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + public IWorkbook getContents() { + return contents; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof WorkbookEditorInput)) + return false; + WorkbookEditorInput that = (WorkbookEditorInput) obj; + if (this.contents == null || that.contents == null) + return false; + return that.contents.equals(this.contents); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistory.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistory.java index dbc038ec0..006d22356 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistory.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistory.java @@ -1,288 +1,288 @@ -package org.xmind.ui.internal.editor; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IProduct; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.service.datalocation.Location; -import org.eclipse.ui.IEditorInput; -import org.xmind.ui.IEditorHistory; - -/** - * - * @author Frank Shaka - * @deprecated Use {@link IEditorHistory} instead. - */ -@Deprecated -public class WorkbookHistory { - - @Deprecated - public static interface IWorkbookHistoryListener { - - void workbookHistoryUpdated(); - - } - - private static final int MAX_SIZE = 100; - - private static WorkbookHistory instance = null; - - private List items = new ArrayList( - MAX_SIZE); - - private long lastModifiedTime = 0; - - private Thread saveRunner = null; - - private ListenerList listeners = new ListenerList(); - - private WorkbookHistory() { - load(); - } - - public void addWorkbookHistoryListener(IWorkbookHistoryListener listener) { - listeners.add(listener); - } - - public void removeWorkbookHistoryListener( - IWorkbookHistoryListener listener) { - listeners.remove(listener); - } - - /** - * Add editor input to this history. Currently only editor inputs adaptable - * to a File or IFileStore are supported. Other types will be considered - * later. - * - * @param input - * the editor input to add - */ - public void add(IEditorInput input) { - File file = MME.getFile(input); - if (file != null) { - String uri = WorkbookHistoryItem.toURI(file.getAbsolutePath()); - remove(input, uri); - items.add(0, new WorkbookHistoryItem(input, uri, - System.currentTimeMillis())); - while (items.size() > MAX_SIZE) { - items.remove(items.size() - 1); - } - lastModifiedTime = System.currentTimeMillis(); - scheduleSave(); - fireUpdated(); - } - } - - private void remove(IEditorInput input, String uri) { - Iterator it = items.iterator(); - while (it.hasNext()) { - WorkbookHistoryItem item = it.next(); - if ((uri != null && uri.equals(item.getURI())) - || (item.getExistingEditorInput() != null - && item.getExistingEditorInput().equals(input))) { - it.remove(); - } - } - } - - /** - * Removes add traces added by the specified editor input. - * - * @param input - * the editor input to remove - */ - public void remove(IEditorInput input) { - if (input == null) - return; - remove(input, null); - lastModifiedTime = System.currentTimeMillis(); - scheduleSave(); - fireUpdated(); - } - - /** - * Clears all workbook opening traces. - */ - public void clear() { - items.clear(); - lastModifiedTime = System.currentTimeMillis(); - save(); - } - - public WorkbookHistoryItem[] getItems() { - return items.toArray(new WorkbookHistoryItem[items.size()]); - } - - public WorkbookHistoryItem[] getTopItems(int size) { - size = Math.max(0, Math.min(size, items.size())); - return items.subList(0, size).toArray(new WorkbookHistoryItem[size]); - } - - public long getLastModifiedTime() { - return lastModifiedTime; - } - - public boolean load() { - File file = getHistoryFile(); - if (file == null) - return false; - Properties cache = new Properties(); - try { - InputStream stream = new BufferedInputStream( - new FileInputStream(file), 1024); - try { - cache.load(stream); - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - return false; - } - - items.clear(); - - if (!cache.isEmpty()) { - for (int i = 0; i < MAX_SIZE; i++) { - String value = cache.getProperty("item." + i); //$NON-NLS-1$ - if (value != null) { - int sepPos = value.indexOf(','); - if (sepPos > 0) { - try { - long time = Long - .parseLong(value.substring(0, sepPos), 10); - String uri = value.substring(sepPos + 1); - items.add(new WorkbookHistoryItem(null, uri, time)); - } catch (NumberFormatException e) { - } - } - } - } - } - lastModifiedTime = System.currentTimeMillis(); - - return true; - } - - private synchronized void scheduleSave() { - Thread t = saveRunner; - if (t != null) { - t.interrupt(); - } - t = new Thread(new Runnable() { - public void run() { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - return; - } - save(); - } - }); - t.setDaemon(true); - t.setName("Save Workbook History"); //$NON-NLS-1$ - t.start(); - saveRunner = t; - } - - public synchronized boolean save() { - File file = getHistoryFile(); - if (file == null) - return false; - - File dir = file.getParentFile(); - if (!dir.exists() || !dir.isDirectory()) { - if (!dir.mkdirs()) - return false; - if (!dir.exists() || !dir.isDirectory()) - return false; - } - - Properties cache = new Properties(); - for (int i = 0; i < items.size(); i++) { - WorkbookHistoryItem item = items.get(i); - String key = "item." + i; //$NON-NLS-1$ - String value = Long.toString(item.getTime(), 10) + "," //$NON-NLS-1$ - + item.getURI(); - cache.put(key, value); - } - - try { - FileOutputStream stream = new FileOutputStream(file); - try { - cache.store(stream, - "Generated by org.xmind.ui.internal.editor.WorkbookHistory"); //$NON-NLS-1$ - } finally { - try { - stream.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - return false; - } - - return true; - } - - private void fireUpdated() { - if (listeners.isEmpty()) - return; - - Object[] theListeners = listeners.getListeners(); - for (int i = 0; i < theListeners.length; i++) { - final IWorkbookHistoryListener listener = (IWorkbookHistoryListener) theListeners[i]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - listener.workbookHistoryUpdated(); - } - }); - } - } - - private static File getHistoryFile() { - Location instanceLocation = Platform.getInstanceLocation(); - if (instanceLocation == null) - return null; - URL url = instanceLocation.getURL(); - if (url == null) - return null; - try { - url = FileLocator.toFileURL(url); - } catch (IOException e) { - return null; - } - String workspace = url.getFile(); - if (workspace == null || "".equals(workspace)) //$NON-NLS-1$ - return null; - IProduct product = Platform.getProduct(); - if (product != null && "org.xmind.cathy.application".equals(product //$NON-NLS-1$ - .getApplication())) { - return new File(workspace, "workbookhistory.properties"); //$NON-NLS-1$ - } - return new File(new File(workspace, ".xmind"), //$NON-NLS-1$ - "workbookhistory.properties"); //$NON-NLS-1$ - } - - public static WorkbookHistory getInstance() { - if (instance == null) - instance = new WorkbookHistory(); - return instance; - } -} +package org.xmind.ui.internal.editor; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IProduct; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.service.datalocation.Location; +import org.eclipse.ui.IEditorInput; +import org.xmind.ui.IEditorHistory; + +/** + * + * @author Frank Shaka + * @deprecated Use {@link IEditorHistory} instead. + */ +@Deprecated +public class WorkbookHistory { + + @Deprecated + public static interface IWorkbookHistoryListener { + + void workbookHistoryUpdated(); + + } + + private static final int MAX_SIZE = 100; + + private static WorkbookHistory instance = null; + + private List items = new ArrayList( + MAX_SIZE); + + private long lastModifiedTime = 0; + + private Thread saveRunner = null; + + private ListenerList listeners = new ListenerList(); + + private WorkbookHistory() { + load(); + } + + public void addWorkbookHistoryListener(IWorkbookHistoryListener listener) { + listeners.add(listener); + } + + public void removeWorkbookHistoryListener( + IWorkbookHistoryListener listener) { + listeners.remove(listener); + } + + /** + * Add editor input to this history. Currently only editor inputs adaptable + * to a File or IFileStore are supported. Other types will be considered + * later. + * + * @param input + * the editor input to add + */ + public void add(IEditorInput input) { + File file = MME.getFile(input); + if (file != null) { + String uri = WorkbookHistoryItem.toURI(file.getAbsolutePath()); + remove(input, uri); + items.add(0, new WorkbookHistoryItem(input, uri, + System.currentTimeMillis())); + while (items.size() > MAX_SIZE) { + items.remove(items.size() - 1); + } + lastModifiedTime = System.currentTimeMillis(); + scheduleSave(); + fireUpdated(); + } + } + + private void remove(IEditorInput input, String uri) { + Iterator it = items.iterator(); + while (it.hasNext()) { + WorkbookHistoryItem item = it.next(); + if ((uri != null && uri.equals(item.getURI())) + || (item.getExistingEditorInput() != null + && item.getExistingEditorInput().equals(input))) { + it.remove(); + } + } + } + + /** + * Removes add traces added by the specified editor input. + * + * @param input + * the editor input to remove + */ + public void remove(IEditorInput input) { + if (input == null) + return; + remove(input, null); + lastModifiedTime = System.currentTimeMillis(); + scheduleSave(); + fireUpdated(); + } + + /** + * Clears all workbook opening traces. + */ + public void clear() { + items.clear(); + lastModifiedTime = System.currentTimeMillis(); + save(); + } + + public WorkbookHistoryItem[] getItems() { + return items.toArray(new WorkbookHistoryItem[items.size()]); + } + + public WorkbookHistoryItem[] getTopItems(int size) { + size = Math.max(0, Math.min(size, items.size())); + return items.subList(0, size).toArray(new WorkbookHistoryItem[size]); + } + + public long getLastModifiedTime() { + return lastModifiedTime; + } + + public boolean load() { + File file = getHistoryFile(); + if (file == null) + return false; + Properties cache = new Properties(); + try { + InputStream stream = new BufferedInputStream( + new FileInputStream(file), 1024); + try { + cache.load(stream); + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + return false; + } + + items.clear(); + + if (!cache.isEmpty()) { + for (int i = 0; i < MAX_SIZE; i++) { + String value = cache.getProperty("item." + i); //$NON-NLS-1$ + if (value != null) { + int sepPos = value.indexOf(','); + if (sepPos > 0) { + try { + long time = Long + .parseLong(value.substring(0, sepPos), 10); + String uri = value.substring(sepPos + 1); + items.add(new WorkbookHistoryItem(null, uri, time)); + } catch (NumberFormatException e) { + } + } + } + } + } + lastModifiedTime = System.currentTimeMillis(); + + return true; + } + + private synchronized void scheduleSave() { + Thread t = saveRunner; + if (t != null) { + t.interrupt(); + } + t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + return; + } + save(); + } + }); + t.setDaemon(true); + t.setName("Save Workbook History"); //$NON-NLS-1$ + t.start(); + saveRunner = t; + } + + public synchronized boolean save() { + File file = getHistoryFile(); + if (file == null) + return false; + + File dir = file.getParentFile(); + if (!dir.exists() || !dir.isDirectory()) { + if (!dir.mkdirs()) + return false; + if (!dir.exists() || !dir.isDirectory()) + return false; + } + + Properties cache = new Properties(); + for (int i = 0; i < items.size(); i++) { + WorkbookHistoryItem item = items.get(i); + String key = "item." + i; //$NON-NLS-1$ + String value = Long.toString(item.getTime(), 10) + "," //$NON-NLS-1$ + + item.getURI(); + cache.put(key, value); + } + + try { + FileOutputStream stream = new FileOutputStream(file); + try { + cache.store(stream, + "Generated by org.xmind.ui.internal.editor.WorkbookHistory"); //$NON-NLS-1$ + } finally { + try { + stream.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + return false; + } + + return true; + } + + private void fireUpdated() { + if (listeners.isEmpty()) + return; + + Object[] theListeners = listeners.getListeners(); + for (int i = 0; i < theListeners.length; i++) { + final IWorkbookHistoryListener listener = (IWorkbookHistoryListener) theListeners[i]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + listener.workbookHistoryUpdated(); + } + }); + } + } + + private static File getHistoryFile() { + Location instanceLocation = Platform.getInstanceLocation(); + if (instanceLocation == null) + return null; + URL url = instanceLocation.getURL(); + if (url == null) + return null; + try { + url = FileLocator.toFileURL(url); + } catch (IOException e) { + return null; + } + String workspace = url.getFile(); + if (workspace == null || "".equals(workspace)) //$NON-NLS-1$ + return null; + IProduct product = Platform.getProduct(); + if (product != null && "org.xmind.cathy.application".equals(product //$NON-NLS-1$ + .getApplication())) { + return new File(workspace, "workbookhistory.properties"); //$NON-NLS-1$ + } + return new File(new File(workspace, ".xmind"), //$NON-NLS-1$ + "workbookhistory.properties"); //$NON-NLS-1$ + } + + public static WorkbookHistory getInstance() { + if (instance == null) + instance = new WorkbookHistory(); + return instance; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistoryItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistoryItem.java index 107c85071..8d3710ed5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistoryItem.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookHistoryItem.java @@ -1,84 +1,84 @@ -package org.xmind.ui.internal.editor; - -import java.io.File; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchPage; -import org.xmind.ui.IEditorHistory; -import org.xmind.ui.dialogs.IDialogConstants; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.protocols.FilePathParser; -import org.xmind.ui.mindmap.MindMapUI; - -/** - * - * @author Frank Shaka - * @deprecated Use {@link IEditorHistory} instead - */ -public class WorkbookHistoryItem { - - static final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$ - - private IEditorInput input; - - private String uri; - - private long time; - - public WorkbookHistoryItem(IEditorInput input, String uri, long time) { - this.input = input; - this.uri = uri; - this.time = time; - } - - public long getTime() { - return time; - } - - public String getURI() { - return this.uri; - } - - public String getPath() { - if (FilePathParser.isFileURI(uri)) { - return FilePathParser.toPath(uri); - } - return uri; - } - - void setInput(IEditorInput input) { - this.input = input; - } - - public IEditorInput getExistingEditorInput() { - return this.input; - } - - public IEditorInput createNewEditorInput() throws CoreException { - return MME.createFileEditorInput(getPath()); - } - - public void reopen(IWorkbenchPage page) throws CoreException { - if (!new File(getPath()).exists()) { - MessageDialog.openWarning(new Shell(), - IDialogConstants.COMMON_TITLE, - MindMapMessages.WorkbookHistoryItem_FileMissingMessage); - return; - } - page.openEditor(createNewEditorInput(), MindMapUI.MINDMAP_EDITOR_ID, - true); - } - - @Override - public String toString() { - return "{time=" + time + ",uri=" + uri + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - static String toURI(String filePath) { - return FilePathParser.toURI(filePath, false); - } - -} +package org.xmind.ui.internal.editor; + +import java.io.File; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.xmind.ui.IEditorHistory; +import org.xmind.ui.dialogs.IDialogConstants; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.protocols.FilePathParser; +import org.xmind.ui.mindmap.MindMapUI; + +/** + * + * @author Frank Shaka + * @deprecated Use {@link IEditorHistory} instead + */ +public class WorkbookHistoryItem { + + static final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$ + + private IEditorInput input; + + private String uri; + + private long time; + + public WorkbookHistoryItem(IEditorInput input, String uri, long time) { + this.input = input; + this.uri = uri; + this.time = time; + } + + public long getTime() { + return time; + } + + public String getURI() { + return this.uri; + } + + public String getPath() { + if (FilePathParser.isFileURI(uri)) { + return FilePathParser.toPath(uri); + } + return uri; + } + + void setInput(IEditorInput input) { + this.input = input; + } + + public IEditorInput getExistingEditorInput() { + return this.input; + } + + public IEditorInput createNewEditorInput() throws CoreException { + return MME.createFileEditorInput(getPath()); + } + + public void reopen(IWorkbenchPage page) throws CoreException { + if (!new File(getPath()).exists()) { + MessageDialog.openWarning(new Shell(), + IDialogConstants.COMMON_TITLE, + MindMapMessages.WorkbookHistoryItem_FileMissingMessage); + return; + } + page.openEditor(createNewEditorInput(), MindMapUI.MINDMAP_EDITOR_ID, + true); + } + + @Override + public String toString() { + return "{time=" + time + ",uri=" + uri + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + static String toURI(String filePath) { + return FilePathParser.toURI(filePath, false); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRef.java index 486b7637d..519e94c9e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRef.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRef.java @@ -1,521 +1,521 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import java.net.URI; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.xmind.core.Core; -import org.xmind.core.IEncryptionHandler; -import org.xmind.core.IMeta; -import org.xmind.core.IRevision; -import org.xmind.core.IRevisionManager; -import org.xmind.core.IRevisionRepository; -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.CoreEventRegister; -import org.xmind.core.event.ICoreEventListener; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSource2; -import org.xmind.core.event.ICoreEventSupport; -import org.xmind.core.internal.dom.WorkbookImpl; -import org.xmind.core.io.IStorage; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.gef.GEF; -import org.xmind.gef.command.CommandStack; -import org.xmind.gef.command.CommandStackEvent; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.command.ICommandStackListener; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; - -/** - * @author Frank Shaka - * @since 3.0 - * @deprecated - */ -@Deprecated -public class WorkbookRef -// implements IWorkbookRef, IPropertyChangeListener { -{ - -// @Deprecated -// private final WorkbookRefManager manager; - @Deprecated - private URI uri; - @Deprecated - private String name; - @Deprecated - private IWorkbook workbook; - @Deprecated - private ICommandStack commandStack; - @Deprecated - private IAdaptable activeContext; -// @Deprecated -// private IWorkbookRefStatus status; - - @Deprecated - private boolean undoing = false; - -// @Deprecated -// private ListenerList listeners = new ListenerList(); - - @Deprecated - private CoreEventRegister globalEventRegister = null; - - @Deprecated - private ICoreEventListener globalEventListener = new ICoreEventListener() { - public void handleCoreEvent(CoreEvent event) { - handleGlobalEvent(event); - } - }; - - @Deprecated - public WorkbookRef(WorkbookRefManager manager, URI uri, IWorkbook workbook, - String name) { -// this.manager = manager; - this.uri = uri; - this.workbook = workbook; - this.name = name; - this.commandStack = new CommandStack( - Math.max(MindMapUIPlugin.getDefault().getPreferenceStore() - .getInt(PrefConstants.UNDO_LIMIT), 1)); - this.commandStack.addCSListener(new ICommandStackListener() { - public void handleCommandStackEvent(CommandStackEvent event) { - handleCommandStackChange(event); - } - }); -// MindMapUIPlugin.getDefault().getPreferenceStore() -// .addPropertyChangeListener(this); -// int statusCode = workbook == null ? IWorkbookRefStatus.LOADING -// : IWorkbookRefStatus.CLEAN; -// this.status = new WorkbookRefStatus(statusCode, -// IWorkbookRefStatus.INITIAL, -// new Status(IStatus.INFO, MindMapUIPlugin.PLUGIN_ID, null)); - } - - @Deprecated - public URI getURI() { - return this.uri; - } - - @Deprecated - public String getName() { - return this.name; - } - - @Deprecated - public ICommandStack getCommandStack() { - return this.commandStack; - } - - @Deprecated - public IWorkbook getWorkbook() { - return this.workbook; - } - - @Deprecated - public IAdaptable getActiveContext() { - return this.activeContext; - } - -// @Deprecated -// public void addStatusListener(IWorkbookRefStatusListener listener) { -// listeners.add(listener); -// } -// -// @Deprecated -// public void removeListener(IWorkbookRefStatusListener listener) { -// listeners.remove(listener); -// } -// -// public IWorkbookRefStatus getStatus() { -// return status; -// } - - @Deprecated - public void markDirty() { - - } - - @Deprecated - protected void setURI(URI uri) { - this.uri = uri; - } - - @Deprecated - protected void setWorkbook(IWorkbook workbook) { - if (workbook == this.workbook) - return; - - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - } - - this.workbook = workbook; - if (workbook != null) { - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (markerSheet != null) { - markerSheet.setParentSheet( - MindMapUI.getResourceManager().getUserMarkerSheet()); - } - - if (globalEventRegister == null) { - globalEventRegister = new CoreEventRegister( - globalEventListener); - } - registerGlobalEvents(globalEventRegister, workbook); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - @Deprecated - public T getAdapter(Class adapter) { - if (adapter == URI.class) - return adapter.cast(getURI()); - if (adapter == IWorkbook.class) - return adapter.cast(getWorkbook()); - if (adapter == ICommandStack.class) - return adapter.cast(getCommandStack()); - if (activeContext != null) - return activeContext.getAdapter(adapter); - return null; - } - - @Deprecated - public void close() { -// MindMapUIPlugin.getDefault().getPreferenceStore() -// .removePropertyChangeListener(this); - if (commandStack != null) { - commandStack.dispose(); - commandStack = null; - } - if (globalEventRegister != null) { - globalEventRegister.unregisterAll(); - globalEventRegister = null; - } - if (workbook != null) { - closeWorkbook(workbook); - } - workbook = null; - } - - @Deprecated - private void closeWorkbook(IWorkbook workbook) { - ICoreEventSupport support = (ICoreEventSupport) workbook - .getAdapter(ICoreEventSupport.class); - if (support != null) { - support.dispatchTargetChange((ICoreEventSource) workbook, - MindMapUI.WorkbookClose, this); - } - } - - @Deprecated - public boolean isContentDirty() { - if (workbook == null) - return false; - if (getCommandStack() != null && getCommandStack().isDirty()) - return true; - return workbook instanceof ICoreEventSource2 - && ((ICoreEventSource2) workbook) - .hasOnceListeners(Core.WorkbookPreSaveOnce); - } - - @Deprecated - public boolean isDirty() { - return isContentDirty(); - } - - @Deprecated - public void loadWorkbook(IEncryptionHandler encryptionHandler, - IProgressMonitor monitor) throws CoreException { -// synchronized (ioLock) { -// loadWorkbook(createStorage(), encryptionHandler, monitor); -// } - } - - @Deprecated - public void loadWorkbook(IStorage storage, - IEncryptionHandler encryptionHandler, IProgressMonitor monitor) - throws CoreException { -// synchronized (ioLock) { - if (workbook != null) - return; - -// if (workbookLoader == null) -// throw new CoreException( -// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, -// "No workbook loader is set.")); //$NON-NLS-1$ -// -// setWorkbook(workbookLoader.loadWorkbook(storage, encryptionHandler, -// monitor)); -// } - } - - @Deprecated - public void saveWorkbook(IProgressMonitor monitor, - IWorkbookReferrer previewSaver, boolean skipNewRevisions) - throws CoreException { -// synchronized (ioLock) { - monitor.beginTask(null, 100); - if (workbook == null) - throw new CoreException(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, "No workbook to save.")); //$NON-NLS-1$ -// if (workbookSaver == null) -// throw new CoreException( -// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, -// "No workbook saver has been set.")); //$NON-NLS-1$ - - // Leave 1 tick for finalizing work: - int mainWorkTicks = 99; - - if (!skipNewRevisions) { - monitor.subTask( - MindMapMessages.WorkbookSaver_CreateRevisions_taskName); - saveRevisions(monitor); - } - monitor.worked(10); - mainWorkTicks -= 10; - - // Delete old preview: - workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.jpg"); //$NON-NLS-1$ - workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ - if (previewSaver != null) { - monitor.subTask( - MindMapMessages.WorkbookSaver_SavePreviewImage_taskName); -// savePreview(monitor); - } else { -// setPreviewOutdated(true); - } - monitor.worked(10); - mainWorkTicks -= 10; - - monitor.subTask( - MindMapMessages.WorkbookSaver_SaveWorkbookContent_taskName); -// WorkbookBackupManager wbm = WorkbookBackupManager.getInstance(); -// IWorkbookBackup backup = wbm.ensureBackedUp(this, monitor); - try { -// workbookSaver.save(monitor, workbook); - } catch (Throwable e) { -// if (backup != null) { -// backup.restore(monitor); -// } - if (e instanceof CoreException) - throw (CoreException) e; - throw new CoreException(new Status(IStatus.ERROR, - MindMapUI.PLUGIN_ID, e.getLocalizedMessage(), e)); - } -// wbm.removeWorkbook(this); -// wbm.addWorkbook(this); - monitor.worked(mainWorkTicks); - - monitor.subTask(MindMapMessages.WorkbookSaver_Finalize_taskName); -// for (IWorkbookReferrer referrer : getReferrers()) { -// referrer.postSave(monitor); -// } - - monitor.done(); -// } - } - - @Deprecated - public void saveWorkbookAs(Object newKey, IProgressMonitor monitor, - IWorkbookReferrer previewSaver, boolean skipNewRevisions) - throws CoreException { -// synchronized (ioLock) { - monitor.beginTask(null, 100); - if (workbook == null) - throw new CoreException(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, "No workbook to save.")); //$NON-NLS-1$ - - monitor.subTask( - MindMapMessages.WorkbookSaver_PrepareNewSaveTarget_taskName); -// Object oldKey = getKey(); -// setKey(newKey); -// setWorkbookLoader(null); -// setWorkbookSaver(null); -// WorkbookRefInitializer.getInstance().initialize(this, newKey, -// getPrimaryReferrer()); -// if (workbookSaver == null) -// throw new CoreException( -// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, -// "No workbook saver has been set.")); //$NON-NLS-1$ - - // Leave 1 tick for finalizing work: - int mainWorkTicks = 99; - -// WorkbookRefManager.getInstance().changeKey(this, oldKey, newKey); - monitor.worked(10); - mainWorkTicks -= 10; - - if (!skipNewRevisions) { - monitor.subTask( - MindMapMessages.WorkbookSaver_CreateRevisions_taskName); - saveRevisions(monitor); - } - monitor.worked(10); - mainWorkTicks -= 10; - - // Delete old preview: - workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.jpg"); //$NON-NLS-1$ - workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ - if (previewSaver != null) { - monitor.subTask( - MindMapMessages.WorkbookSaver_SavePreviewImage_taskName); -// savePreview(monitor); - } else { -// setPreviewOutdated(true); - } - monitor.worked(10); - mainWorkTicks -= 10; - - monitor.subTask( - MindMapMessages.WorkbookSaver_SaveWorkbookContent_taskName); -// workbookSaver.save(monitor, workbook); - monitor.worked(mainWorkTicks); - -// WorkbookBackupManager.getInstance().removeWorkbook(this); -// WorkbookBackupManager.getInstance().addWorkbook(this); - - monitor.subTask(MindMapMessages.WorkbookSaver_Finalize_taskName); -// for (IWorkbookReferrer referrer : getReferrers()) { -// referrer.postSaveAs(newKey, monitor); -// } - monitor.done(); -// } - } - - @Deprecated - private void saveRevisions(IProgressMonitor monitor) throws CoreException { - if (!isContentDirty() - || ((WorkbookImpl) workbook).isSkipRevisionsWhenSaving() - || !shouldSaveNewRevisions()) - return; - - IRevisionRepository repo = workbook.getRevisionRepository(); - for (ISheet sheet : workbook.getSheets()) { - IRevisionManager manager = repo.getRevisionManager(sheet.getId(), - IRevision.SHEET); - IRevision latestRevision = manager.getLatestRevision(); - if (latestRevision == null || sheet.getModifiedTime() == 0 || sheet - .getModifiedTime() > latestRevision.getTimestamp()) { - try { - manager.addRevision(sheet); - } catch (Throwable e) { - throw new CoreException(new Status(IStatus.ERROR, - MindMapUIPlugin.PLUGIN_ID, null, e)); - } - } - } - } - - @Deprecated - private boolean shouldSaveNewRevisions() { - String value = workbook.getMeta() - .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); - return value == null || IMeta.V_YES.equalsIgnoreCase(value); - } - - @Deprecated - public void propertyChange(PropertyChangeEvent event) { - if (commandStack != null) { - if (PrefConstants.UNDO_LIMIT.equals(event.getProperty())) { - commandStack.setUndoLimit( - Math.max((Integer) event.getNewValue(), 1)); - } - } - } - - @Deprecated - public String toString() { - return uri == null ? (workbook == null ? "UnrecognizedWorkbookRef" //$NON-NLS-1$ - : workbook.toString()) : uri.toString(); - } - - @Deprecated - private void registerGlobalEvents(CoreEventRegister register, - IWorkbook workbook) { - ICoreEventSupport support = (ICoreEventSupport) workbook - .getAdapter(ICoreEventSupport.class); - if (support != null) { - register.setNextSupport(support); - - register.register(Core.MarkerRefAdd); - } - } - - @Deprecated - private void handleGlobalEvent(CoreEvent event) { - String type = event.getType(); - if (Core.MarkerRefAdd.equals(type)) { - handleMarkerAdded((String) event.getTarget()); - } - } - - @Deprecated - private void handleMarkerAdded(String markerId) { - if (undoing) - return; - - IMarker systemMarker = MindMapUI.getResourceManager() - .getSystemMarkerSheet().findMarker(markerId); - if (systemMarker != null) { - IMarkerGroup group = systemMarker.getParent(); - if (group != null) { - if (group.getParent() != null && group.getParent().equals( - MindMapUI.getResourceManager().getSystemMarkerSheet())) - MindMapUI.getResourceManager().getRecentMarkerGroup() - .addMarker(systemMarker); - } - } - IMarker userMarker = MindMapUI.getResourceManager().getUserMarkerSheet() - .findMarker(markerId); - if (userMarker != null) { - IMarkerGroup group = userMarker.getParent(); - if (group != null) { - if (group.getParent() != null && group.getParent().equals( - MindMapUI.getResourceManager().getUserMarkerSheet())) { - - MindMapUI.getResourceManager().getRecentMarkerGroup() - .addMarker(userMarker); - } - } - } - } - - @Deprecated - private void handleCommandStackChange(CommandStackEvent event) { - int status = event.getStatus(); - if ((status & GEF.CS_PRE_UNDO) != 0) { - undoing = true; - } else if ((status & GEF.CS_POST_UNDO) != 0) { - undoing = false; - } - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import java.net.URI; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.xmind.core.Core; +import org.xmind.core.IEncryptionHandler; +import org.xmind.core.IMeta; +import org.xmind.core.IRevision; +import org.xmind.core.IRevisionManager; +import org.xmind.core.IRevisionRepository; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.event.ICoreEventSource2; +import org.xmind.core.event.ICoreEventSupport; +import org.xmind.core.internal.dom.WorkbookImpl; +import org.xmind.core.io.IStorage; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.gef.GEF; +import org.xmind.gef.command.CommandStack; +import org.xmind.gef.command.CommandStackEvent; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.command.ICommandStackListener; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; + +/** + * @author Frank Shaka + * @since 3.0 + * @deprecated + */ +@Deprecated +public class WorkbookRef +// implements IWorkbookRef, IPropertyChangeListener { +{ + +// @Deprecated +// private final WorkbookRefManager manager; + @Deprecated + private URI uri; + @Deprecated + private String name; + @Deprecated + private IWorkbook workbook; + @Deprecated + private ICommandStack commandStack; + @Deprecated + private IAdaptable activeContext; +// @Deprecated +// private IWorkbookRefStatus status; + + @Deprecated + private boolean undoing = false; + +// @Deprecated +// private ListenerList listeners = new ListenerList(); + + @Deprecated + private CoreEventRegister globalEventRegister = null; + + @Deprecated + private ICoreEventListener globalEventListener = new ICoreEventListener() { + public void handleCoreEvent(CoreEvent event) { + handleGlobalEvent(event); + } + }; + + @Deprecated + public WorkbookRef(WorkbookRefManager manager, URI uri, IWorkbook workbook, + String name) { +// this.manager = manager; + this.uri = uri; + this.workbook = workbook; + this.name = name; + this.commandStack = new CommandStack( + Math.max(MindMapUIPlugin.getDefault().getPreferenceStore() + .getInt(PrefConstants.UNDO_LIMIT), 1)); + this.commandStack.addCSListener(new ICommandStackListener() { + public void handleCommandStackEvent(CommandStackEvent event) { + handleCommandStackChange(event); + } + }); +// MindMapUIPlugin.getDefault().getPreferenceStore() +// .addPropertyChangeListener(this); +// int statusCode = workbook == null ? IWorkbookRefStatus.LOADING +// : IWorkbookRefStatus.CLEAN; +// this.status = new WorkbookRefStatus(statusCode, +// IWorkbookRefStatus.INITIAL, +// new Status(IStatus.INFO, MindMapUIPlugin.PLUGIN_ID, null)); + } + + @Deprecated + public URI getURI() { + return this.uri; + } + + @Deprecated + public String getName() { + return this.name; + } + + @Deprecated + public ICommandStack getCommandStack() { + return this.commandStack; + } + + @Deprecated + public IWorkbook getWorkbook() { + return this.workbook; + } + + @Deprecated + public IAdaptable getActiveContext() { + return this.activeContext; + } + +// @Deprecated +// public void addStatusListener(IWorkbookRefStatusListener listener) { +// listeners.add(listener); +// } +// +// @Deprecated +// public void removeListener(IWorkbookRefStatusListener listener) { +// listeners.remove(listener); +// } +// +// public IWorkbookRefStatus getStatus() { +// return status; +// } + + @Deprecated + public void markDirty() { + + } + + @Deprecated + protected void setURI(URI uri) { + this.uri = uri; + } + + @Deprecated + protected void setWorkbook(IWorkbook workbook) { + if (workbook == this.workbook) + return; + + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + } + + this.workbook = workbook; + if (workbook != null) { + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (markerSheet != null) { + markerSheet.setParentSheet( + MindMapUI.getResourceManager().getUserMarkerSheet()); + } + + if (globalEventRegister == null) { + globalEventRegister = new CoreEventRegister( + globalEventListener); + } + registerGlobalEvents(globalEventRegister, workbook); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @Deprecated + public T getAdapter(Class adapter) { + if (adapter == URI.class) + return adapter.cast(getURI()); + if (adapter == IWorkbook.class) + return adapter.cast(getWorkbook()); + if (adapter == ICommandStack.class) + return adapter.cast(getCommandStack()); + if (activeContext != null) + return activeContext.getAdapter(adapter); + return null; + } + + @Deprecated + public void close() { +// MindMapUIPlugin.getDefault().getPreferenceStore() +// .removePropertyChangeListener(this); + if (commandStack != null) { + commandStack.dispose(); + commandStack = null; + } + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } + if (workbook != null) { + closeWorkbook(workbook); + } + workbook = null; + } + + @Deprecated + private void closeWorkbook(IWorkbook workbook) { + ICoreEventSupport support = (ICoreEventSupport) workbook + .getAdapter(ICoreEventSupport.class); + if (support != null) { + support.dispatchTargetChange((ICoreEventSource) workbook, + MindMapUI.WorkbookClose, this); + } + } + + @Deprecated + public boolean isContentDirty() { + if (workbook == null) + return false; + if (getCommandStack() != null && getCommandStack().isDirty()) + return true; + return workbook instanceof ICoreEventSource2 + && ((ICoreEventSource2) workbook) + .hasOnceListeners(Core.WorkbookPreSaveOnce); + } + + @Deprecated + public boolean isDirty() { + return isContentDirty(); + } + + @Deprecated + public void loadWorkbook(IEncryptionHandler encryptionHandler, + IProgressMonitor monitor) throws CoreException { +// synchronized (ioLock) { +// loadWorkbook(createStorage(), encryptionHandler, monitor); +// } + } + + @Deprecated + public void loadWorkbook(IStorage storage, + IEncryptionHandler encryptionHandler, IProgressMonitor monitor) + throws CoreException { +// synchronized (ioLock) { + if (workbook != null) + return; + +// if (workbookLoader == null) +// throw new CoreException( +// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, +// "No workbook loader is set.")); //$NON-NLS-1$ +// +// setWorkbook(workbookLoader.loadWorkbook(storage, encryptionHandler, +// monitor)); +// } + } + + @Deprecated + public void saveWorkbook(IProgressMonitor monitor, + IWorkbookReferrer previewSaver, boolean skipNewRevisions) + throws CoreException { +// synchronized (ioLock) { + monitor.beginTask(null, 100); + if (workbook == null) + throw new CoreException(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, "No workbook to save.")); //$NON-NLS-1$ +// if (workbookSaver == null) +// throw new CoreException( +// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, +// "No workbook saver has been set.")); //$NON-NLS-1$ + + // Leave 1 tick for finalizing work: + int mainWorkTicks = 99; + + if (!skipNewRevisions) { + monitor.subTask( + MindMapMessages.WorkbookSaver_CreateRevisions_taskName); + saveRevisions(monitor); + } + monitor.worked(10); + mainWorkTicks -= 10; + + // Delete old preview: + workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.jpg"); //$NON-NLS-1$ + workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ + if (previewSaver != null) { + monitor.subTask( + MindMapMessages.WorkbookSaver_SavePreviewImage_taskName); +// savePreview(monitor); + } else { +// setPreviewOutdated(true); + } + monitor.worked(10); + mainWorkTicks -= 10; + + monitor.subTask( + MindMapMessages.WorkbookSaver_SaveWorkbookContent_taskName); +// WorkbookBackupManager wbm = WorkbookBackupManager.getInstance(); +// IWorkbookBackup backup = wbm.ensureBackedUp(this, monitor); + try { +// workbookSaver.save(monitor, workbook); + } catch (Throwable e) { +// if (backup != null) { +// backup.restore(monitor); +// } + if (e instanceof CoreException) + throw (CoreException) e; + throw new CoreException(new Status(IStatus.ERROR, + MindMapUI.PLUGIN_ID, e.getLocalizedMessage(), e)); + } +// wbm.removeWorkbook(this); +// wbm.addWorkbook(this); + monitor.worked(mainWorkTicks); + + monitor.subTask(MindMapMessages.WorkbookSaver_Finalize_taskName); +// for (IWorkbookReferrer referrer : getReferrers()) { +// referrer.postSave(monitor); +// } + + monitor.done(); +// } + } + + @Deprecated + public void saveWorkbookAs(Object newKey, IProgressMonitor monitor, + IWorkbookReferrer previewSaver, boolean skipNewRevisions) + throws CoreException { +// synchronized (ioLock) { + monitor.beginTask(null, 100); + if (workbook == null) + throw new CoreException(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, "No workbook to save.")); //$NON-NLS-1$ + + monitor.subTask( + MindMapMessages.WorkbookSaver_PrepareNewSaveTarget_taskName); +// Object oldKey = getKey(); +// setKey(newKey); +// setWorkbookLoader(null); +// setWorkbookSaver(null); +// WorkbookRefInitializer.getInstance().initialize(this, newKey, +// getPrimaryReferrer()); +// if (workbookSaver == null) +// throw new CoreException( +// new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, +// "No workbook saver has been set.")); //$NON-NLS-1$ + + // Leave 1 tick for finalizing work: + int mainWorkTicks = 99; + +// WorkbookRefManager.getInstance().changeKey(this, oldKey, newKey); + monitor.worked(10); + mainWorkTicks -= 10; + + if (!skipNewRevisions) { + monitor.subTask( + MindMapMessages.WorkbookSaver_CreateRevisions_taskName); + saveRevisions(monitor); + } + monitor.worked(10); + mainWorkTicks -= 10; + + // Delete old preview: + workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.jpg"); //$NON-NLS-1$ + workbook.getManifest().deleteFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ + if (previewSaver != null) { + monitor.subTask( + MindMapMessages.WorkbookSaver_SavePreviewImage_taskName); +// savePreview(monitor); + } else { +// setPreviewOutdated(true); + } + monitor.worked(10); + mainWorkTicks -= 10; + + monitor.subTask( + MindMapMessages.WorkbookSaver_SaveWorkbookContent_taskName); +// workbookSaver.save(monitor, workbook); + monitor.worked(mainWorkTicks); + +// WorkbookBackupManager.getInstance().removeWorkbook(this); +// WorkbookBackupManager.getInstance().addWorkbook(this); + + monitor.subTask(MindMapMessages.WorkbookSaver_Finalize_taskName); +// for (IWorkbookReferrer referrer : getReferrers()) { +// referrer.postSaveAs(newKey, monitor); +// } + monitor.done(); +// } + } + + @Deprecated + private void saveRevisions(IProgressMonitor monitor) throws CoreException { + if (!isContentDirty() + || ((WorkbookImpl) workbook).isSkipRevisionsWhenSaving() + || !shouldSaveNewRevisions()) + return; + + IRevisionRepository repo = workbook.getRevisionRepository(); + for (ISheet sheet : workbook.getSheets()) { + IRevisionManager manager = repo.getRevisionManager(sheet.getId(), + IRevision.SHEET); + IRevision latestRevision = manager.getLatestRevision(); + if (latestRevision == null || sheet.getModifiedTime() == 0 || sheet + .getModifiedTime() > latestRevision.getTimestamp()) { + try { + manager.addRevision(sheet); + } catch (Throwable e) { + throw new CoreException(new Status(IStatus.ERROR, + MindMapUIPlugin.PLUGIN_ID, null, e)); + } + } + } + } + + @Deprecated + private boolean shouldSaveNewRevisions() { + String value = workbook.getMeta() + .getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION); + return value == null || IMeta.V_YES.equalsIgnoreCase(value); + } + + @Deprecated + public void propertyChange(PropertyChangeEvent event) { + if (commandStack != null) { + if (PrefConstants.UNDO_LIMIT.equals(event.getProperty())) { + commandStack.setUndoLimit( + Math.max((Integer) event.getNewValue(), 1)); + } + } + } + + @Deprecated + public String toString() { + return uri == null ? (workbook == null ? "UnrecognizedWorkbookRef" //$NON-NLS-1$ + : workbook.toString()) : uri.toString(); + } + + @Deprecated + private void registerGlobalEvents(CoreEventRegister register, + IWorkbook workbook) { + ICoreEventSupport support = (ICoreEventSupport) workbook + .getAdapter(ICoreEventSupport.class); + if (support != null) { + register.setNextSupport(support); + + register.register(Core.MarkerRefAdd); + } + } + + @Deprecated + private void handleGlobalEvent(CoreEvent event) { + String type = event.getType(); + if (Core.MarkerRefAdd.equals(type)) { + handleMarkerAdded((String) event.getTarget()); + } + } + + @Deprecated + private void handleMarkerAdded(String markerId) { + if (undoing) + return; + + IMarker systemMarker = MindMapUI.getResourceManager() + .getSystemMarkerSheet().findMarker(markerId); + if (systemMarker != null) { + IMarkerGroup group = systemMarker.getParent(); + if (group != null) { + if (group.getParent() != null && group.getParent().equals( + MindMapUI.getResourceManager().getSystemMarkerSheet())) + MindMapUI.getResourceManager().getRecentMarkerGroup() + .addMarker(systemMarker); + } + } + IMarker userMarker = MindMapUI.getResourceManager().getUserMarkerSheet() + .findMarker(markerId); + if (userMarker != null) { + IMarkerGroup group = userMarker.getParent(); + if (group != null) { + if (group.getParent() != null && group.getParent().equals( + MindMapUI.getResourceManager().getUserMarkerSheet())) { + + MindMapUI.getResourceManager().getRecentMarkerGroup() + .addMarker(userMarker); + } + } + } + } + + @Deprecated + private void handleCommandStackChange(CommandStackEvent event) { + int status = event.getStatus(); + if ((status & GEF.CS_PRE_UNDO) != 0) { + undoing = true; + } else if ((status & GEF.CS_POST_UNDO) != 0) { + undoing = false; + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefEncryptable.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefEncryptable.java index aa9910442..6295c7c3d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefEncryptable.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefEncryptable.java @@ -1,242 +1,232 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2016 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -/** - * - */ -package org.xmind.ui.internal.editor; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.xmind.core.Core; -import org.xmind.core.CoreException; -import org.xmind.core.IEntryStreamNormalizer; -import org.xmind.core.IFileEntry; -import org.xmind.core.IWorkbook; -import org.xmind.core.event.CoreEvent; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.internal.security.PasswordProtectedNormalizer; -import org.xmind.ui.internal.MindMapUIPlugin; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class WorkbookRefEncryptable implements IEncryptable { - - private static class LazyPasswordBasedEncryptor - implements IEntryStreamNormalizer { - - private final AbstractWorkbookRef workbookRef; - - private IEntryStreamNormalizer delegate; - - /** - * - */ - public LazyPasswordBasedEncryptor(AbstractWorkbookRef workbookRef) { - this.workbookRef = workbookRef; - this.delegate = IEntryStreamNormalizer.NULL; - } - - /** - * @return the delegate - */ - public IEntryStreamNormalizer getDelegate() { - return delegate; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. - * OutputStream, org.xmind.core.IFileEntry) - */ - @Override - public OutputStream normalizeOutputStream(OutputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - return delegate.normalizeOutputStream(stream, fileEntry); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. - * InputStream, org.xmind.core.IFileEntry) - */ - @Override - public InputStream normalizeInputStream(InputStream stream, - IFileEntry fileEntry) throws IOException, CoreException { - if (fileEntry.getEncryptionData() != null - && delegate == IEntryStreamNormalizer.NULL) { - /// encrypted, should ask for password - IPasswordProvider passwordProvider = workbookRef - .getService(IPasswordProvider.class); - if (passwordProvider != null) { - String password = passwordProvider - .askForPassword(workbookRef, null); - if (password == null) - throw new CoreException(Core.ERROR_CANCELLATION); - delegate = createEncryptor(password); - } - } - - return delegate.normalizeInputStream(stream, fileEntry); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof LazyPasswordBasedEncryptor)) - return false; - LazyPasswordBasedEncryptor that = (LazyPasswordBasedEncryptor) obj; - return this.delegate.equals(that.delegate); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return 37 ^ delegate.hashCode(); - } - - } - - private final AbstractWorkbookRef workbookRef; - - private IEntryStreamNormalizer encryptor; - - private String password; - - private String passwordHint; - - /** - * - */ - public WorkbookRefEncryptable(AbstractWorkbookRef workbookRef) { - super(); - this.workbookRef = workbookRef; - this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.IEncryptable#setPassword(java.lang.String) - */ - @Override - public void setPassword(String newPassword) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("TrigSetPasswordCount"); //$NON-NLS-1$ - - IEntryStreamNormalizer oldEncryptor = this.encryptor; - IEntryStreamNormalizer newEncryptor = createEncryptor(newPassword); - if (encryptorEquals(oldEncryptor, newEncryptor)) - return; - - this.encryptor = newEncryptor; - - IWorkbook workbook = workbookRef.getWorkbook(); - if (workbook != null && workbook instanceof ICoreEventSource) { - ICoreEventSource eventSource = (ICoreEventSource) workbook; - eventSource.getCoreEventSupport().dispatch(eventSource, - new CoreEvent(eventSource, Core.PasswordChange, null)); - } - - this.password = newPassword; - } - - public String getPassword() { - return password; - } - - @Override - public void setPasswordHint(String passwordHint) { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("TrigSetPasswordHintCount"); //$NON-NLS-1$ - - this.passwordHint = passwordHint; - } - - public String getPasswordHint() { - MindMapUIPlugin.getDefault().getUsageDataCollector() - .increase("TrigGetPasswordHintCount"); //$NON-NLS-1$ - - return passwordHint; - } - - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.IEncryptable#isPasswordCorrect(java.lang. - * String) - */ - @Override - public boolean testsPassword(String passwordToTest) { - IEntryStreamNormalizer oldEncryptor = this.encryptor; - IEntryStreamNormalizer newEncryptor = createEncryptor(passwordToTest); - return encryptorEquals(oldEncryptor, newEncryptor); - } - - private static boolean encryptorEquals(IEntryStreamNormalizer oldEncryptor, - IEntryStreamNormalizer newEncryptor) { - return oldEncryptor.equals(newEncryptor); - } - - /* - * (non-Javadoc) - * @see org.xmind.ui.internal.editor.IEncryptable#hasPassword() - */ - @Override - public boolean hasPassword() { - IEntryStreamNormalizer e = this.encryptor; - while (e instanceof LazyPasswordBasedEncryptor) { - e = ((LazyPasswordBasedEncryptor) e).getDelegate(); - } - return e != IEntryStreamNormalizer.NULL; - } - - /** - * @return the encryptor - */ - public IEntryStreamNormalizer getEncryptor() { - return encryptor; - } - - protected void setEncryptor(IEntryStreamNormalizer encryptor) { - this.encryptor = encryptor; - } - - public void reset() { - this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); - } - - /** - * @param password - * @return - */ - private static IEntryStreamNormalizer createEncryptor(String password) { - return password == null ? IEntryStreamNormalizer.NULL - : new PasswordProtectedNormalizer(password); - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2016 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.xmind.ui.internal.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.xmind.core.Core; +import org.xmind.core.CoreException; +import org.xmind.core.IEntryStreamNormalizer; +import org.xmind.core.IFileEntry; +import org.xmind.core.IWorkbook; +import org.xmind.core.event.CoreEvent; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.internal.security.PasswordProtectedNormalizer; + +/** + * @author Frank Shaka + * @since 3.6.50 + */ +public class WorkbookRefEncryptable implements IEncryptable { + + private static class LazyPasswordBasedEncryptor + implements IEntryStreamNormalizer { + + private final AbstractWorkbookRef workbookRef; + + private IEntryStreamNormalizer delegate; + + /** + * + */ + public LazyPasswordBasedEncryptor(AbstractWorkbookRef workbookRef) { + this.workbookRef = workbookRef; + this.delegate = IEntryStreamNormalizer.NULL; + } + + /** + * @return the delegate + */ + public IEntryStreamNormalizer getDelegate() { + return delegate; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. + * OutputStream, org.xmind.core.IFileEntry) + */ + @Override + public OutputStream normalizeOutputStream(OutputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + return delegate.normalizeOutputStream(stream, fileEntry); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. + * InputStream, org.xmind.core.IFileEntry) + */ + @Override + public InputStream normalizeInputStream(InputStream stream, + IFileEntry fileEntry) throws IOException, CoreException { + if (fileEntry.getEncryptionData() != null + && delegate == IEntryStreamNormalizer.NULL) { + /// encrypted, should ask for password + IPasswordProvider passwordProvider = workbookRef + .getService(IPasswordProvider.class); + if (passwordProvider != null) { + String password = passwordProvider + .askForPassword(workbookRef, null); + if (password == null) + throw new CoreException(Core.ERROR_CANCELLATION); + delegate = createEncryptor(password); + } + } + + return delegate.normalizeInputStream(stream, fileEntry); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof LazyPasswordBasedEncryptor)) + return false; + LazyPasswordBasedEncryptor that = (LazyPasswordBasedEncryptor) obj; + return this.delegate.equals(that.delegate); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return 37 ^ delegate.hashCode(); + } + + } + + private final AbstractWorkbookRef workbookRef; + + private IEntryStreamNormalizer encryptor; + + private String password; + + private String passwordHint; + + /** + * + */ + public WorkbookRefEncryptable(AbstractWorkbookRef workbookRef) { + super(); + this.workbookRef = workbookRef; + this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.editor.IEncryptable#setPassword(java.lang.String) + */ + @Override + public void setPassword(String newPassword) { + IEntryStreamNormalizer oldEncryptor = this.encryptor; + IEntryStreamNormalizer newEncryptor = createEncryptor(newPassword); + if (encryptorEquals(oldEncryptor, newEncryptor)) + return; + + this.encryptor = newEncryptor; + + IWorkbook workbook = workbookRef.getWorkbook(); + if (workbook != null && workbook instanceof ICoreEventSource) { + ICoreEventSource eventSource = (ICoreEventSource) workbook; + eventSource.getCoreEventSupport().dispatch(eventSource, + new CoreEvent(eventSource, Core.PasswordChange, null)); + } + + this.password = newPassword; + } + + public String getPassword() { + return password; + } + + @Override + public void setPasswordHint(String passwordHint) { + this.passwordHint = passwordHint; + } + + public String getPasswordHint() { + return passwordHint; + } + + /* + * (non-Javadoc) + * @see + * org.xmind.ui.internal.editor.IEncryptable#isPasswordCorrect(java.lang. + * String) + */ + @Override + public boolean testsPassword(String passwordToTest) { + IEntryStreamNormalizer oldEncryptor = this.encryptor; + IEntryStreamNormalizer newEncryptor = createEncryptor(passwordToTest); + return encryptorEquals(oldEncryptor, newEncryptor); + } + + private static boolean encryptorEquals(IEntryStreamNormalizer oldEncryptor, + IEntryStreamNormalizer newEncryptor) { + return oldEncryptor.equals(newEncryptor); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.internal.editor.IEncryptable#hasPassword() + */ + @Override + public boolean hasPassword() { + IEntryStreamNormalizer e = this.encryptor; + while (e instanceof LazyPasswordBasedEncryptor) { + e = ((LazyPasswordBasedEncryptor) e).getDelegate(); + } + return e != IEntryStreamNormalizer.NULL; + } + + /** + * @return the encryptor + */ + public IEntryStreamNormalizer getEncryptor() { + return encryptor; + } + + protected void setEncryptor(IEntryStreamNormalizer encryptor) { + this.encryptor = encryptor; + } + + public void reset() { + this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); + } + + /** + * @param password + * @return + */ + private static IEntryStreamNormalizer createEncryptor(String password) { + return password == null ? IEntryStreamNormalizer.NULL + : new PasswordProtectedNormalizer(password); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefFactoryManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefFactoryManager.java index f5b71fc57..35782adaf 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefFactoryManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefFactoryManager.java @@ -1,195 +1,195 @@ -package org.xmind.ui.internal.editor; - -import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_CLASS; -import static org.xmind.ui.internal.RegistryConstants.ATT_SCHEME; -import static org.xmind.ui.internal.RegistryConstants.EXT_WORKBOOK_REF_FACTORIES; -import static org.xmind.ui.internal.RegistryConstants.TAG_AVAILABLE_FOR_URI_SCHEME; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.IRegistryEventListener; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.ui.IMemento; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.RegistryConstants; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefFactory; -import org.xmind.ui.mindmap.MindMapUI; - -public class WorkbookRefFactoryManager - implements IWorkbookRefFactory, IRegistryEventListener { - - private static class WorkbookRefFactoryDescriptor { - private IConfigurationElement element; - private final Set schemes; - private volatile IWorkbookRefFactory factoryInstance; - - private WorkbookRefFactoryDescriptor(IConfigurationElement element) { - if (element.getAttribute(ATT_CLASS) == null) { - throw new IllegalArgumentException( - "No 'class' attribute on factory element (contributed by " //$NON-NLS-1$ - + element.getContributor().getName() + ")"); //$NON-NLS-1$ - } - this.element = element; - this.schemes = new HashSet(); - for (IConfigurationElement schemeTag : element - .getChildren(TAG_AVAILABLE_FOR_URI_SCHEME)) { - String scheme = schemeTag.getAttribute(ATT_SCHEME); - if (scheme != null) { - this.schemes.add(scheme); - } - } - } - - public synchronized IWorkbookRefFactory getInstance() { - if (this.factoryInstance == null && this.element != null) { - Object ins = null; - try { - ins = this.element.createExecutableExtension(ATT_CLASS); - } catch (CoreException e) { - MindMapUIPlugin.getDefault().getLog().log(e.getStatus()); - } - if (ins != null && ins instanceof IWorkbookRefFactory) { - this.factoryInstance = (IWorkbookRefFactory) ins; - } - } - return this.factoryInstance; - } - - public synchronized void dispose() { - this.schemes.clear(); - this.element = null; - this.factoryInstance = null; - } - - public boolean isAvailableForURIScheme(String scheme) { - return this.schemes.contains(scheme); - } - - public boolean isFromExtension(IExtension ext) { - return element != null && ext != null - && ext.equals(element.getDeclaringExtension()); - } - - } - - private List factories = null; - - private IExtensionRegistry registry = null; - - public WorkbookRefFactoryManager() { - super(); - } - - public synchronized IWorkbookRef createWorkbookRef(URI uri, - IMemento state) { - IWorkbookRefFactory factory = getWorkbookRefFactoryForURI(uri); - if (factory != null) - return factory.createWorkbookRef(uri, state); - return URLWorkbookRef.create(uri, state); - } - - private synchronized IWorkbookRefFactory getWorkbookRefFactoryForURI( - URI uri) { - ensureLoaded(); - String scheme = uri.getScheme(); - for (WorkbookRefFactoryDescriptor factory : factories) { - if (factory.isAvailableForURIScheme(scheme)) { - return factory.getInstance(); - } - } - return null; - } - - private synchronized void ensureLoaded() { - if (factories != null) - return; - - factories = new ArrayList(); - - registry = Platform.getExtensionRegistry(); - if (registry == null) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, - "Extension registry is not available")); //$NON-NLS-1$ - return; - } - - IExtensionPoint extPoint = registry.getExtensionPoint( - MindMapUI.PLUGIN_ID, EXT_WORKBOOK_REF_FACTORIES); - if (extPoint == null) { - MindMapUIPlugin.getDefault().getLog() - .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, - "Extension point '" + MindMapUI.PLUGIN_ID //$NON-NLS-1$ - + "." + EXT_WORKBOOK_REF_FACTORIES //$NON-NLS-1$ - + "' not found.")); //$NON-NLS-1$ - return; - } - - registry.addListener(this, extPoint.getUniqueIdentifier()); - - readExtensions(extPoint.getExtensions()); - } - - private void readExtensions(IExtension[] extensions) { - for (IExtension ext : extensions) { - for (IConfigurationElement element : ext - .getConfigurationElements()) { - if (RegistryConstants.TAG_FACTORY.equals(element.getName())) { - WorkbookRefFactoryDescriptor desc = new WorkbookRefFactoryDescriptor( - element); - factories.add(desc); - } - } - } - } - - public synchronized void dispose() { - if (factories != null) { - for (Object o : factories.toArray()) { - ((WorkbookRefFactoryDescriptor) o).dispose(); - } - factories.clear(); - factories = null; - } - if (registry != null) { - registry.removeListener(this); - registry = null; - } - } - - public void added(IExtension[] extensions) { - readExtensions(extensions); - } - - public void removed(IExtension[] extensions) { - for (IExtension ext : extensions) { - for (Object o : factories.toArray()) { - if (((WorkbookRefFactoryDescriptor) o).isFromExtension(ext)) { - factories.remove(o); - ((WorkbookRefFactoryDescriptor) o).dispose(); - } - } - } - } - - public void added(IExtensionPoint[] extensionPoints) { - // do not care about other extension points - } - - public void removed(IExtensionPoint[] extensionPoints) { - // do not care about other extension points - } - -} +package org.xmind.ui.internal.editor; + +import static org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants.ATT_CLASS; +import static org.xmind.ui.internal.RegistryConstants.ATT_SCHEME; +import static org.xmind.ui.internal.RegistryConstants.EXT_WORKBOOK_REF_FACTORIES; +import static org.xmind.ui.internal.RegistryConstants.TAG_AVAILABLE_FOR_URI_SCHEME; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IRegistryEventListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IMemento; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.RegistryConstants; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefFactory; +import org.xmind.ui.mindmap.MindMapUI; + +public class WorkbookRefFactoryManager + implements IWorkbookRefFactory, IRegistryEventListener { + + private static class WorkbookRefFactoryDescriptor { + private IConfigurationElement element; + private final Set schemes; + private volatile IWorkbookRefFactory factoryInstance; + + private WorkbookRefFactoryDescriptor(IConfigurationElement element) { + if (element.getAttribute(ATT_CLASS) == null) { + throw new IllegalArgumentException( + "No 'class' attribute on factory element (contributed by " //$NON-NLS-1$ + + element.getContributor().getName() + ")"); //$NON-NLS-1$ + } + this.element = element; + this.schemes = new HashSet(); + for (IConfigurationElement schemeTag : element + .getChildren(TAG_AVAILABLE_FOR_URI_SCHEME)) { + String scheme = schemeTag.getAttribute(ATT_SCHEME); + if (scheme != null) { + this.schemes.add(scheme); + } + } + } + + public synchronized IWorkbookRefFactory getInstance() { + if (this.factoryInstance == null && this.element != null) { + Object ins = null; + try { + ins = this.element.createExecutableExtension(ATT_CLASS); + } catch (CoreException e) { + MindMapUIPlugin.getDefault().getLog().log(e.getStatus()); + } + if (ins != null && ins instanceof IWorkbookRefFactory) { + this.factoryInstance = (IWorkbookRefFactory) ins; + } + } + return this.factoryInstance; + } + + public synchronized void dispose() { + this.schemes.clear(); + this.element = null; + this.factoryInstance = null; + } + + public boolean isAvailableForURIScheme(String scheme) { + return this.schemes.contains(scheme); + } + + public boolean isFromExtension(IExtension ext) { + return element != null && ext != null + && ext.equals(element.getDeclaringExtension()); + } + + } + + private List factories = null; + + private IExtensionRegistry registry = null; + + public WorkbookRefFactoryManager() { + super(); + } + + public synchronized IWorkbookRef createWorkbookRef(URI uri, + IMemento state) { + IWorkbookRefFactory factory = getWorkbookRefFactoryForURI(uri); + if (factory != null) + return factory.createWorkbookRef(uri, state); + return URLWorkbookRef.create(uri, state); + } + + private synchronized IWorkbookRefFactory getWorkbookRefFactoryForURI( + URI uri) { + ensureLoaded(); + String scheme = uri.getScheme(); + for (WorkbookRefFactoryDescriptor factory : factories) { + if (factory.isAvailableForURIScheme(scheme)) { + return factory.getInstance(); + } + } + return null; + } + + private synchronized void ensureLoaded() { + if (factories != null) + return; + + factories = new ArrayList(); + + registry = Platform.getExtensionRegistry(); + if (registry == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, + "Extension registry is not available")); //$NON-NLS-1$ + return; + } + + IExtensionPoint extPoint = registry.getExtensionPoint( + MindMapUI.PLUGIN_ID, EXT_WORKBOOK_REF_FACTORIES); + if (extPoint == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, + "Extension point '" + MindMapUI.PLUGIN_ID //$NON-NLS-1$ + + "." + EXT_WORKBOOK_REF_FACTORIES //$NON-NLS-1$ + + "' not found.")); //$NON-NLS-1$ + return; + } + + registry.addListener(this, extPoint.getUniqueIdentifier()); + + readExtensions(extPoint.getExtensions()); + } + + private void readExtensions(IExtension[] extensions) { + for (IExtension ext : extensions) { + for (IConfigurationElement element : ext + .getConfigurationElements()) { + if (RegistryConstants.TAG_FACTORY.equals(element.getName())) { + WorkbookRefFactoryDescriptor desc = new WorkbookRefFactoryDescriptor( + element); + factories.add(desc); + } + } + } + } + + public synchronized void dispose() { + if (factories != null) { + for (Object o : factories.toArray()) { + ((WorkbookRefFactoryDescriptor) o).dispose(); + } + factories.clear(); + factories = null; + } + if (registry != null) { + registry.removeListener(this); + registry = null; + } + } + + public void added(IExtension[] extensions) { + readExtensions(extensions); + } + + public void removed(IExtension[] extensions) { + for (IExtension ext : extensions) { + for (Object o : factories.toArray()) { + if (((WorkbookRefFactoryDescriptor) o).isFromExtension(ext)) { + factories.remove(o); + ((WorkbookRefFactoryDescriptor) o).dispose(); + } + } + } + } + + public void added(IExtensionPoint[] extensionPoints) { + // do not care about other extension points + } + + public void removed(IExtensionPoint[] extensionPoints) { + // do not care about other extension points + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefManager.java index ae3fbc306..a9def2160 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefManager.java @@ -1,52 +1,52 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editor; - -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.xmind.core.IWorkbook; -import org.xmind.ui.mindmap.IWorkbookRef; -import org.xmind.ui.mindmap.IWorkbookRefManager; - -/** - * @deprecated - */ -@Deprecated -public class WorkbookRefManager implements IWorkbookRefManager { - - /** - * @deprecated - */ - @Deprecated - public IWorkbookRef findRef(IWorkbook workbook) { - return null; - } - - /** - * @deprecated - */ - @Deprecated - public IWorkbookRef createRef(IEditorInput editorInput, - IEditorPart editor) { - return null; - } - - /** - * @deprecated - */ - @Deprecated - public void disposeRef(IEditorInput editorInput, IEditorPart editor) { - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editor; + +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.xmind.core.IWorkbook; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.IWorkbookRefManager; + +/** + * @deprecated + */ +@Deprecated +public class WorkbookRefManager implements IWorkbookRefManager { + + /** + * @deprecated + */ + @Deprecated + public IWorkbookRef findRef(IWorkbook workbook) { + return null; + } + + /** + * @deprecated + */ + @Deprecated + public IWorkbookRef createRef(IEditorInput editorInput, + IEditorPart editor) { + return null; + } + + /** + * @deprecated + */ + @Deprecated + public void disposeRef(IEditorInput editorInput, IEditorPart editor) { + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefPropertyTester.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefPropertyTester.java index 6b03e07e7..6fe4d524c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefPropertyTester.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRefPropertyTester.java @@ -1,64 +1,64 @@ -package org.xmind.ui.internal.editor; - -import java.net.URI; -import java.util.regex.Pattern; - -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.core.runtime.Assert; -import org.xmind.gef.ui.editor.Editable; -import org.xmind.ui.mindmap.IWorkbookRef; - -public class WorkbookRefPropertyTester extends PropertyTester { - - private static final String P_URI = "uri"; //$NON-NLS-1$ - - private static final String P_URI_SCHEME = "uriScheme"; //$NON-NLS-1$ - - private static final String P_EXIST = "exist"; //$NON-NLS-1$ - - public WorkbookRefPropertyTester() { - } - - @Override - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { - Assert.isLegal(receiver instanceof IWorkbookRef); - - IWorkbookRef workbookRef = (IWorkbookRef) receiver; - if (P_URI.equals(property)) { - String uriString = workbookRef.getURI().toString(); - if (expectedValue instanceof String - && ((String) expectedValue).startsWith("^")) { //$NON-NLS-1$ - return Pattern.matches((String) expectedValue, uriString); - } - return testStringValue(uriString, expectedValue); - } else if (P_URI_SCHEME.equals(property)) { - URI uri = workbookRef.getURI(); - return testStringValue(uri == null ? null : uri.getScheme(), - expectedValue); - } else if (P_EXIST.equals(property)) { - boolean exists = ((Editable) workbookRef).exists(); - if (expectedValue == null || expectedValue.equals("") //$NON-NLS-1$ - || expectedValue.equals(Boolean.TRUE.toString())) { - return exists; - } else if (expectedValue.equals(Boolean.FALSE.toString())) { - return !exists; - } - } - - Assert.isTrue(false, "Unrecognized property: " + property); //$NON-NLS-1$ - - return false; - } - - private static boolean testStringValue(String actualValue, - Object expectedValue) { - if ("".equals(expectedValue)) //$NON-NLS-1$ - expectedValue = null; - else if (expectedValue != null) - expectedValue = expectedValue.toString(); - return actualValue == expectedValue - || (actualValue != null && actualValue.equals(expectedValue)); - } - -} +package org.xmind.ui.internal.editor; + +import java.net.URI; +import java.util.regex.Pattern; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.xmind.gef.ui.editor.Editable; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class WorkbookRefPropertyTester extends PropertyTester { + + private static final String P_URI = "uri"; //$NON-NLS-1$ + + private static final String P_URI_SCHEME = "uriScheme"; //$NON-NLS-1$ + + private static final String P_EXIST = "exist"; //$NON-NLS-1$ + + public WorkbookRefPropertyTester() { + } + + @Override + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + Assert.isLegal(receiver instanceof IWorkbookRef); + + IWorkbookRef workbookRef = (IWorkbookRef) receiver; + if (P_URI.equals(property)) { + String uriString = workbookRef.getURI().toString(); + if (expectedValue instanceof String + && ((String) expectedValue).startsWith("^")) { //$NON-NLS-1$ + return Pattern.matches((String) expectedValue, uriString); + } + return testStringValue(uriString, expectedValue); + } else if (P_URI_SCHEME.equals(property)) { + URI uri = workbookRef.getURI(); + return testStringValue(uri == null ? null : uri.getScheme(), + expectedValue); + } else if (P_EXIST.equals(property)) { + boolean exists = ((Editable) workbookRef).exists(); + if (expectedValue == null || expectedValue.equals("") //$NON-NLS-1$ + || expectedValue.equals(Boolean.TRUE.toString())) { + return exists; + } else if (expectedValue.equals(Boolean.FALSE.toString())) { + return !exists; + } + } + + Assert.isTrue(false, "Unrecognized property: " + property); //$NON-NLS-1$ + + return false; + } + + private static boolean testStringValue(String actualValue, + Object expectedValue) { + if ("".equals(expectedValue)) //$NON-NLS-1$ + expectedValue = null; + else if (expectedValue != null) + expectedValue = expectedValue.toString(); + return actualValue == expectedValue + || (actualValue != null && actualValue.equals(expectedValue)); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/XMindFileBrowserContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/XMindFileBrowserContribution.java index 6aa8cf4fe..67cf90750 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/XMindFileBrowserContribution.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/XMindFileBrowserContribution.java @@ -1,245 +1,245 @@ -package org.xmind.ui.internal.editor; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.jface.action.IContributionManager; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.xmind.core.command.Command; -import org.xmind.core.command.CommandJob; -import org.xmind.core.command.ICommand; -import org.xmind.core.util.FileUtils; -import org.xmind.ui.browser.IBrowserViewer; -import org.xmind.ui.browser.IBrowserViewerContribution; -import org.xmind.ui.browser.IBrowserViewerContribution2; -import org.xmind.ui.browser.IPropertyChangingListener; -import org.xmind.ui.browser.PropertyChangingEvent; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.io.DownloadJob; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.Logger; - -public class XMindFileBrowserContribution - implements IBrowserViewerContribution, IBrowserViewerContribution2 { - - protected static class XMindFileListener - implements PropertyChangeListener, IPropertyChangingListener { - - private IBrowserViewer viewer; - - public XMindFileListener(IBrowserViewer viewer) { - this.viewer = viewer; - viewer.addPropertyChangeListener(IBrowserViewer.PROPERTY_LOCATION, - this); - } - - /** - * @return the viewer - */ - public IBrowserViewer getViewer() { - return viewer; - } - - /* - * (non-Javadoc) - * - * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. - * PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent evt) { - } - - /* - * (non-Javadoc) - * - * @see - * org.xmind.ui.browser.IPropertyChangingListener#propertyChanging(org - * .xmind.ui.browser.PropertyChangingEvent) - */ - public void propertyChanging(PropertyChangingEvent event) { - if (!IBrowserViewer.PROPERTY_LOCATION - .equals(event.getPropertyName())) - return; - - String location = (String) event.getNewValue(); - if (location == null || "about:blank".equals(location)) //$NON-NLS-1$ - return; - - final ICommand command = Command.parseURI(location); - if (command != null) { - new CommandJob(command, null).schedule(); - } else { - try { - URI uri = new URI(location); - String uriPath = uri.getPath(); - if (uriPath != null - && uriPath.endsWith(MindMapUI.FILE_EXT_XMIND)) { - downloadAndOpen(location, - FileUtils.getFileName(uriPath)); - event.doit = false; - } - } catch (Throwable e) { - Logger.log(e); - } - } - } - - /** - * @param location - * @param url - * @param connection - */ - private void downloadAndOpen(String location, String suggestedName) { - FileDialog dialog = new FileDialog(viewer.getControl().getShell(), - SWT.SAVE | SWT.SINGLE); - String ext = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ - dialog.setFilterExtensions(new String[] { ext }); - dialog.setFilterNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ - DialogMessages.WorkbookFilterName, ext) }); - dialog.setOverwrite(true); - dialog.setText(DialogMessages.Save_title); - dialog.setFileName(suggestedName); - final String path = dialog.open(); - if (path == null) - return; - - FileUtils.delete(new File(path)); - File file = new File(path); - file.getParentFile().mkdirs(); - final String tempPath = path + ".downloading"; //$NON-NLS-1$ - DownloadJob job = new DownloadJob(file.getName(), location, - tempPath); - job.addJobChangeListener(new JobChangeAdapter() { - /* - * (non-Javadoc) - * - * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org. - * eclipse .core.runtime.jobs.IJobChangeEvent) - */ - @Override - public void done(IJobChangeEvent event) { - if (event.getResult().isOK()) { - if (rename(tempPath, path)) { - openFile(path); - } - } - } - - }); - job.schedule(); - } - - private boolean rename(String tempPath, String path) { - File tempFile = new File(tempPath); - if (!tempFile.exists() || !tempFile.canRead()) - return false; - return new File(tempPath).renameTo(new File(path)); - } - - private void openFile(String path) { - final File file = new File(path); - if (!file.exists() || !file.canRead()) - return; - - final IEditorInput[] input = new IEditorInput[1]; - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - input[0] = MindMapUI.getEditorInputFactory() - .createEditorInputForFile(file); - ; - } - }); - if (input[0] == null) - return; - - final IWorkbench workbench = PlatformUI.getWorkbench(); - if (workbench != null) { - Display display = workbench.getDisplay(); - if (display != null && !display.isDisposed()) { - display.asyncExec(new Runnable() { - public void run() { - SafeRunner.run(new SafeRunnable() { - public void run() throws Exception { - openEditor(input[0], workbench); - } - }); - } - }); - } - } - -// IWorkbook contents; -// try { -// contents = Core.getWorkbookBuilder().loadFromPath(path); -// final WorkbookEditorInput input = new WorkbookEditorInput( -// contents, path); -// final IWorkbench workbench = PlatformUI.getWorkbench(); -// if (workbench != null) { -// workbench.getDisplay().asyncExec(new Runnable() { -// public void run() { -// openEditor(input, workbench); -// } -// -// }); -// } -// } catch (Throwable e) { -// Logger.log(e); -// } - } - - /** - * @param input - * @param workbench - */ - private void openEditor(final IEditorInput input, - final IWorkbench workbench) throws Exception { - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window != null) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); - } - } - } - - public void dispose() { - viewer.removePropertyChangeListener(this); - } - - } - - private Map map = new HashMap(); - - public void fillToolBar(IBrowserViewer viewer, - IContributionManager toolBar) { - } - - public void installBrowserListeners(IBrowserViewer viewer) { - XMindFileListener listener = new XMindFileListener(viewer); - map.put(viewer, listener); - } - - public void uninstallBrowserListeners(IBrowserViewer viewer) { - XMindFileListener listener = map.remove(viewer); - if (listener != null) { - listener.dispose(); - } - } - -} +package org.xmind.ui.internal.editor; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.action.IContributionManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.xmind.core.command.Command; +import org.xmind.core.command.CommandJob; +import org.xmind.core.command.ICommand; +import org.xmind.core.util.FileUtils; +import org.xmind.ui.browser.IBrowserViewer; +import org.xmind.ui.browser.IBrowserViewerContribution; +import org.xmind.ui.browser.IBrowserViewerContribution2; +import org.xmind.ui.browser.IPropertyChangingListener; +import org.xmind.ui.browser.PropertyChangingEvent; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.io.DownloadJob; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; + +public class XMindFileBrowserContribution + implements IBrowserViewerContribution, IBrowserViewerContribution2 { + + protected static class XMindFileListener + implements PropertyChangeListener, IPropertyChangingListener { + + private IBrowserViewer viewer; + + public XMindFileListener(IBrowserViewer viewer) { + this.viewer = viewer; + viewer.addPropertyChangeListener(IBrowserViewer.PROPERTY_LOCATION, + this); + } + + /** + * @return the viewer + */ + public IBrowserViewer getViewer() { + return viewer; + } + + /* + * (non-Javadoc) + * + * @seejava.beans.PropertyChangeListener#propertyChange(java.beans. + * PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent evt) { + } + + /* + * (non-Javadoc) + * + * @see + * org.xmind.ui.browser.IPropertyChangingListener#propertyChanging(org + * .xmind.ui.browser.PropertyChangingEvent) + */ + public void propertyChanging(PropertyChangingEvent event) { + if (!IBrowserViewer.PROPERTY_LOCATION + .equals(event.getPropertyName())) + return; + + String location = (String) event.getNewValue(); + if (location == null || "about:blank".equals(location)) //$NON-NLS-1$ + return; + + final ICommand command = Command.parseURI(location); + if (command != null) { + new CommandJob(command, null).schedule(); + } else { + try { + URI uri = new URI(location); + String uriPath = uri.getPath(); + if (uriPath != null + && uriPath.endsWith(MindMapUI.FILE_EXT_XMIND)) { + downloadAndOpen(location, + FileUtils.getFileName(uriPath)); + event.doit = false; + } + } catch (Throwable e) { + Logger.log(e); + } + } + } + + /** + * @param location + * @param url + * @param connection + */ + private void downloadAndOpen(String location, String suggestedName) { + FileDialog dialog = new FileDialog(viewer.getControl().getShell(), + SWT.SAVE | SWT.SINGLE); + String ext = "*" + MindMapUI.FILE_EXT_XMIND; //$NON-NLS-1$ + dialog.setFilterExtensions(new String[] { ext }); + dialog.setFilterNames(new String[] { NLS.bind("{0} ({1})", //$NON-NLS-1$ + DialogMessages.WorkbookFilterName, ext) }); + dialog.setOverwrite(true); + dialog.setText(DialogMessages.Save_title); + dialog.setFileName(suggestedName); + final String path = dialog.open(); + if (path == null) + return; + + FileUtils.delete(new File(path)); + File file = new File(path); + file.getParentFile().mkdirs(); + final String tempPath = path + ".downloading"; //$NON-NLS-1$ + DownloadJob job = new DownloadJob(file.getName(), location, + tempPath); + job.addJobChangeListener(new JobChangeAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org. + * eclipse .core.runtime.jobs.IJobChangeEvent) + */ + @Override + public void done(IJobChangeEvent event) { + if (event.getResult().isOK()) { + if (rename(tempPath, path)) { + openFile(path); + } + } + } + + }); + job.schedule(); + } + + private boolean rename(String tempPath, String path) { + File tempFile = new File(tempPath); + if (!tempFile.exists() || !tempFile.canRead()) + return false; + return new File(tempPath).renameTo(new File(path)); + } + + private void openFile(String path) { + final File file = new File(path); + if (!file.exists() || !file.canRead()) + return; + + final IEditorInput[] input = new IEditorInput[1]; + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + input[0] = MindMapUI.getEditorInputFactory() + .createEditorInputForFile(file); + ; + } + }); + if (input[0] == null) + return; + + final IWorkbench workbench = PlatformUI.getWorkbench(); + if (workbench != null) { + Display display = workbench.getDisplay(); + if (display != null && !display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + openEditor(input[0], workbench); + } + }); + } + }); + } + } + +// IWorkbook contents; +// try { +// contents = Core.getWorkbookBuilder().loadFromPath(path); +// final WorkbookEditorInput input = new WorkbookEditorInput( +// contents, path); +// final IWorkbench workbench = PlatformUI.getWorkbench(); +// if (workbench != null) { +// workbench.getDisplay().asyncExec(new Runnable() { +// public void run() { +// openEditor(input, workbench); +// } +// +// }); +// } +// } catch (Throwable e) { +// Logger.log(e); +// } + } + + /** + * @param input + * @param workbench + */ + private void openEditor(final IEditorInput input, + final IWorkbench workbench) throws Exception { + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + page.openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); + } + } + } + + public void dispose() { + viewer.removePropertyChangeListener(this); + } + + } + + private Map map = new HashMap(); + + public void fillToolBar(IBrowserViewer viewer, + IContributionManager toolBar) { + } + + public void installBrowserListeners(IBrowserViewer viewer) { + XMindFileListener listener = new XMindFileListener(viewer); + map.put(viewer, listener); + } + + public void uninstallBrowserListeners(IBrowserViewer viewer) { + XMindFileListener listener = map.remove(viewer); + if (listener != null) { + listener.dispose(); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateSheetFromTopicCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateSheetFromTopicCommandBuilder.java index b1b0cec3d..f7cb04fe8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateSheetFromTopicCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateSheetFromTopicCommandBuilder.java @@ -1,143 +1,143 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.Set; - -import org.xmind.core.ICloneData; -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.core.internal.dom.WorkbookUtilsImpl; -import org.xmind.core.style.IStyle; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.CreateSheetCommand; -import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.StyleUtils; - -/** - * @author karelun huang - * - */ -public class CreateSheetFromTopicCommandBuilder extends CommandBuilder { - - private ITopic sourceTopic; - - public CreateSheetFromTopicCommandBuilder(IViewer viewer, - ICommandStack commandStack, ITopic sourceTopic) { - super(viewer, commandStack); - this.sourceTopic = sourceTopic; - } - - public void run() { - IWorkbook workbook = sourceTopic.getOwnedWorkbook(); - CreateSheetCommand createCommand = new CreateSheetCommand(workbook, - sourceTopic); - add(createCommand, true); - - ISheet newSheet = (ISheet) createCommand.getSource(); - if (newSheet == null) - return; - - ITopic newCentralTopic = newSheet.getRootTopic(); - String newHyperlink = newCentralTopic.getHyperlink(); - if (newHyperlink == null) { - add(new ModifyTopicHyperlinkCommand(newCentralTopic, - HyperlinkUtils.toInternalURL(sourceTopic)), false); - } - add(new ModifyTopicHyperlinkCommand(sourceTopic, - HyperlinkUtils.toInternalURL(newCentralTopic)), false); - - ISheet sourceSheet = sourceTopic.getOwnedSheet(); - if (sourceSheet != null) { - String themeId = sourceSheet.getThemeId(); - IStyle theme = themeId == null ? null : sourceSheet - .getOwnedWorkbook().getStyleSheet().findStyle(themeId); - if (theme == null) - theme = MindMapUI.getResourceManager().getDefaultTheme(); - StyleUtils.setTheme(newSheet, theme); - } - - ICloneData cloneData = createCommand.getCloneData(); - -// newSheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, -// workbook.getSheets().size())); - newSheet.setTitleText(sourceTopic.getTitleText()); - - String newStructure = newStructure(sourceTopic); - if (newStructure != null) - newCentralTopic.setStructureClass(newStructure); - - Set sourceRelationships = sourceSheet.getRelationships(); - if (sourceRelationships.size() > 0) - cloneRelationships(workbook, newSheet, cloneData, - sourceRelationships); - } - - private void cloneRelationships(IWorkbook workbook, ISheet newSheet, - ICloneData cloneData, Set sourceRelationships) { - Iterator iter = sourceRelationships.iterator(); - while (iter.hasNext()) { - IRelationship r = iter.next(); - cloneRelationship(workbook, newSheet, cloneData, r); - } - } - - private void cloneRelationship(IWorkbook workbook, ISheet newSheet, - ICloneData cloneData, IRelationship sourceRelationship) { - String source1Id = sourceRelationship.getEnd1Id(); - String source2Id = sourceRelationship.getEnd2Id(); - String target1Id = source1Id == null ? null : cloneData.getString( - ICloneData.WORKBOOK_COMPONENTS, source1Id); - String target2Id = source2Id == null ? null : cloneData.getString( - ICloneData.WORKBOOK_COMPONENTS, source2Id); - if (target1Id == null || target2Id == null) - return; - - Object target1 = workbook.getElementById(target1Id); - Object target2 = workbook.getElementById(target2Id); - if (target1 instanceof IRelationshipEnd - && target2 instanceof IRelationshipEnd) { - ICloneData cloned = WorkbookUtilsImpl.clone(workbook, - Arrays.asList(sourceRelationship), cloneData); - IRelationship newRelationship = (IRelationship) cloned - .get(sourceRelationship); - if (newRelationship != null) { - newSheet.addRelationship(newRelationship); - } - } - } - - private String newStructure(ITopic topic) { - String structure = topic.getStructureClass(); - if (structure != null) { - if ("org.xmind.ui.map.floating".equals(structure)) {//$NON-NLS-1$ - structure = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ - } else if ("org.xmind.ui.map.floating.clockwise".equals(structure)) { //$NON-NLS-1$ - structure = "org.xmind.ui.map.clockwise"; //$NON-NLS-1$ - } else if ("org.xmind.ui.map.floating.anticlockwise".equals(structure)) { //$NON-NLS-1$ - structure = "org.xmind.ui.map.anticlockwise"; //$NON-NLS-1$ - } - } - return structure; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Set; + +import org.xmind.core.ICloneData; +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.dom.WorkbookUtilsImpl; +import org.xmind.core.style.IStyle; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.CreateSheetCommand; +import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.StyleUtils; + +/** + * @author karelun huang + * + */ +public class CreateSheetFromTopicCommandBuilder extends CommandBuilder { + + private ITopic sourceTopic; + + public CreateSheetFromTopicCommandBuilder(IViewer viewer, + ICommandStack commandStack, ITopic sourceTopic) { + super(viewer, commandStack); + this.sourceTopic = sourceTopic; + } + + public void run() { + IWorkbook workbook = sourceTopic.getOwnedWorkbook(); + CreateSheetCommand createCommand = new CreateSheetCommand(workbook, + sourceTopic); + add(createCommand, true); + + ISheet newSheet = (ISheet) createCommand.getSource(); + if (newSheet == null) + return; + + ITopic newCentralTopic = newSheet.getRootTopic(); + String newHyperlink = newCentralTopic.getHyperlink(); + if (newHyperlink == null) { + add(new ModifyTopicHyperlinkCommand(newCentralTopic, + HyperlinkUtils.toInternalURL(sourceTopic)), false); + } + add(new ModifyTopicHyperlinkCommand(sourceTopic, + HyperlinkUtils.toInternalURL(newCentralTopic)), false); + + ISheet sourceSheet = sourceTopic.getOwnedSheet(); + if (sourceSheet != null) { + String themeId = sourceSheet.getThemeId(); + IStyle theme = themeId == null ? null : sourceSheet + .getOwnedWorkbook().getStyleSheet().findStyle(themeId); + if (theme == null) + theme = MindMapUI.getResourceManager().getDefaultTheme(); + StyleUtils.setTheme(newSheet, theme); + } + + ICloneData cloneData = createCommand.getCloneData(); + +// newSheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, +// workbook.getSheets().size())); + newSheet.setTitleText(sourceTopic.getTitleText()); + + String newStructure = newStructure(sourceTopic); + if (newStructure != null) + newCentralTopic.setStructureClass(newStructure); + + Set sourceRelationships = sourceSheet.getRelationships(); + if (sourceRelationships.size() > 0) + cloneRelationships(workbook, newSheet, cloneData, + sourceRelationships); + } + + private void cloneRelationships(IWorkbook workbook, ISheet newSheet, + ICloneData cloneData, Set sourceRelationships) { + Iterator iter = sourceRelationships.iterator(); + while (iter.hasNext()) { + IRelationship r = iter.next(); + cloneRelationship(workbook, newSheet, cloneData, r); + } + } + + private void cloneRelationship(IWorkbook workbook, ISheet newSheet, + ICloneData cloneData, IRelationship sourceRelationship) { + String source1Id = sourceRelationship.getEnd1Id(); + String source2Id = sourceRelationship.getEnd2Id(); + String target1Id = source1Id == null ? null : cloneData.getString( + ICloneData.WORKBOOK_COMPONENTS, source1Id); + String target2Id = source2Id == null ? null : cloneData.getString( + ICloneData.WORKBOOK_COMPONENTS, source2Id); + if (target1Id == null || target2Id == null) + return; + + Object target1 = workbook.getElementById(target1Id); + Object target2 = workbook.getElementById(target2Id); + if (target1 instanceof IRelationshipEnd + && target2 instanceof IRelationshipEnd) { + ICloneData cloned = WorkbookUtilsImpl.clone(workbook, + Arrays.asList(sourceRelationship), cloneData); + IRelationship newRelationship = (IRelationship) cloned + .get(sourceRelationship); + if (newRelationship != null) { + newSheet.addRelationship(newRelationship); + } + } + } + + private String newStructure(ITopic topic) { + String structure = topic.getStructureClass(); + if (structure != null) { + if ("org.xmind.ui.map.floating".equals(structure)) {//$NON-NLS-1$ + structure = "org.xmind.ui.map.unbalanced"; //$NON-NLS-1$ + } else if ("org.xmind.ui.map.floating.clockwise".equals(structure)) { //$NON-NLS-1$ + structure = "org.xmind.ui.map.clockwise"; //$NON-NLS-1$ + } else if ("org.xmind.ui.map.floating.anticlockwise".equals(structure)) { //$NON-NLS-1$ + structure = "org.xmind.ui.map.anticlockwise"; //$NON-NLS-1$ + } + } + return structure; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateTopicCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateTopicCommandBuilder.java index 911eaa6fb..f80e85749 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateTopicCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/CreateTopicCommandBuilder.java @@ -1,340 +1,340 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.Collection; -import java.util.List; - -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.osgi.util.NLS; -import org.xmind.core.IBoundary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicRange; -import org.xmind.gef.GEF; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.AddBoundaryCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.CreateTopicCommand; -import org.xmind.ui.commands.DeleteBoundaryCommand; -import org.xmind.ui.commands.DeleteTopicCommand; -import org.xmind.ui.commands.ModifyFoldedCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class CreateTopicCommandBuilder extends CommandBuilder { - - private ITopic sourceTopic; - - private List sources; - - private String createType; - - private ITopic targetParent; - - private String targetType; - - private int targetIndex; - - private int sourceIndex; - - private ITopic createdTopic = null; - - public CreateTopicCommandBuilder(IViewer viewer, CommandBuilder delegate, - ITopic sourceTopic, String createType) { - super(viewer, delegate); - init(sourceTopic, createType); - } - - public CreateTopicCommandBuilder(IViewer viewer, - ICommandStack commandStack, ITopic sourceTopic, String createType) { - super(viewer, commandStack); - init(sourceTopic, createType); - } - - public CreateTopicCommandBuilder(IViewer viewer, - ICommandStack commandStack, ITopic sourceTopic, String createType, - List sources) { - this(viewer, commandStack, sourceTopic, createType); - this.sources = sources; - } - - private void init(ITopic sourceTopic, String createType) { - this.sourceTopic = sourceTopic; - this.createType = createType; - this.sourceIndex = sourceTopic.getIndex(); - if (MindMapUI.REQ_CREATE_CHILD.equals(createType)) { - this.targetParent = sourceTopic; - this.targetType = ITopic.ATTACHED; - this.targetIndex = targetParent.getChildren(targetType).size(); - } else if (MindMapUI.REQ_CREATE_CALLOUT.equals(createType)) { - this.targetParent = sourceTopic; - this.targetType = ITopic.CALLOUT; - this.targetIndex = targetParent.getChildren(targetType).size(); - } else { - this.targetParent = sourceTopic.getParent(); - if (this.targetParent != null) { - if (GEF.REQ_CREATE.equals(createType)) { - this.targetIndex = sourceTopic.getIndex() + 1; - this.targetType = sourceTopic.getType(); - } else if (MindMapUI.REQ_CREATE_BEFORE.equals(createType) - || MindMapUI.REQ_CREATE_PARENT.equals(createType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { - this.targetIndex = sourceTopic.getIndex(); - this.targetType = sourceTopic.getType(); - } else { - this.targetIndex = -1; - this.targetType = null; - } - } else { - this.targetIndex = -1; - this.targetType = null; - } - } - } - - public ITopic getCreatedTopic() { - return createdTopic; - } - - public String getCreateType() { - return createType; - } - - public ITopic getSourceTopic() { - return sourceTopic; - } - - public int getSourceIndex() { - return sourceIndex; - } - - public int getTargetIndex() { - return targetIndex; - } - - public ITopic getTargetParent() { - return targetParent; - } - - public String getTargetType() { - return targetType; - } - - public void createTopic() { - if (!canStart()) - return; - - CreateTopicCommand create = new CreateTopicCommand( - sourceTopic.getOwnedWorkbook()); - add(create, true); - - createdTopic = (ITopic) create.getSource(); - if (createdTopic == null) - return; - - preAdd(); - add(new AddTopicCommand(createdTopic, targetParent, targetIndex, - targetType), true); - postAdded(); - } - - public void createDuplicateTopic() { - if (!canStart()) - return; - - createdTopic = sourceTopic.getOwnedWorkbook().cloneTopic(sourceTopic); - if (createdTopic == null) - return; - - ensureParentUnfolded(); - add(new AddTopicCommand(createdTopic, targetParent, targetIndex, - targetType), true); - postAdded(); - } - - public boolean canStart() { - return super.canStart() && targetParent != null && targetType != null; - } - - private void preAdd() { - ensureParentUnfolded(); - setNewTitle(); - if (ITopic.CALLOUT.equals(targetType)) { - add(new ModifyPositionCommand(createdTopic, - new org.xmind.core.util.Point(0, 0)), false); - } - } - - private void postAdded() { - if (MindMapUI.REQ_CREATE_PARENT.equals(createType)) { - if (sources != null) { - for (ITopic sourceTopic : sources) { - if (ITopic.DETACHED.equals(targetType)) { - add(new ModifyPositionCommand(createdTopic, - sourceTopic.getPosition()), false); - add(new ModifyPositionCommand(sourceTopic, null), false); - } - add(new DeleteTopicCommand(sourceTopic), false); - add(new AddTopicCommand(sourceTopic, createdTopic), false); - moveOverallBoundaries(sourceTopic, createdTopic); - } - } - } else { - if (ITopic.ATTACHED.equals(targetType)) { - if (GEF.REQ_CREATE.equals(createType) - || MindMapUI.REQ_CREATE_BEFORE.equals(createType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { - if (sourceIndex >= 0) - modifyRanges(); - } - } - } - - } - - private void moveOverallBoundaries(ITopic fromTopic, ITopic toTopic) { - IBoundary overallBoundary = null; - for (Object o : fromTopic.getBoundaries().toArray()) { - IBoundary boundary = (IBoundary) o; - if (boundary.isMasterBoundary() && overallBoundary == null) { - overallBoundary = boundary; - } - add(new DeleteBoundaryCommand(boundary), false); - } - - if (overallBoundary != null) { - if (!hasOverallBoundaries(toTopic)) { - add(new AddBoundaryCommand(overallBoundary, toTopic), false); - } - } - } - - private boolean hasOverallBoundaries(ITopic topic) { - for (IBoundary boundary : topic.getBoundaries()) { - if (boundary.isMasterBoundary()) - return true; - } - return false; - } - - private void modifyRanges() { - modifyRanges(targetParent.getBoundaries()); - modifyRanges(targetParent.getSummaries()); - } - - private void modifyRanges(Collection ranges) { - for (ITopicRange range : ranges) { - int startIndex = range.getStartIndex(); - int endIndex = range.getEndIndex(); - if (startIndex >= 0 && endIndex >= 0) { - if (startIndex > sourceIndex) { - add(new ModifyRangeCommand(range, startIndex + 1, true), - false); - } - if (endIndex >= sourceIndex) { - add(new ModifyRangeCommand(range, endIndex + 1, false), - false); - } - } - } - } - - private void setNewTitle() { - add(new ModifyTitleTextCommand(createdTopic, getNewTitle()), false); - } - - private String getNewTitle() { - if (ITopic.DETACHED.equals(targetType)) { - return MindMapMessages.TitleText_FloatingTopic; - } else if (ITopic.CALLOUT.equals(targetType)) { - return MindMapMessages.TitleText_CalloutTopic; - } else { - int size = targetParent.getChildren(targetType).size(); - int newNumber = size + 1; - if (targetParent.isRoot()) { - return NLS.bind(MindMapMessages.TitleText_MainTopic, newNumber); - } else { - return NLS.bind(MindMapMessages.TitleText_Subtopic, newNumber); - } - } - } - - private void ensureParentUnfolded() { - if (targetParent.isFolded()) { - add(new ModifyFoldedCommand(targetParent, false), false); - } - } - - protected void handlePendingCommands() { - super.handlePendingCommands(); - if (ITopic.DETACHED.equals(targetType)) { - if (GEF.REQ_CREATE.equals(createType)) { - setNewPosition(true); - } else if (MindMapUI.REQ_CREATE_BEFORE.equals(createType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { - setNewPosition(false); - } - } - } - - private void setNewPosition(boolean lowerOrUpper) { - Point newPosition = calcNewPosition(lowerOrUpper); - add(new ModifyPositionCommand(createdTopic, - MindMapUtils.toModelPosition(newPosition)), false); - } - - private Point calcNewPosition(boolean lowerOrUpper) { - IPart sourcePart = getViewer().findPart(sourceTopic); - if (sourcePart != null && sourcePart instanceof ITopicPart) { - IBranchPart sourceBranch = ((ITopicPart) sourcePart) - .getOwnerBranch(); - if (sourceBranch != null) { - IPart targetPart = getViewer().findPart(createdTopic); - if (targetPart != null && targetPart instanceof ITopicPart) { - IBranchPart targetBranch = ((ITopicPart) targetPart) - .getOwnerBranch(); - if (targetBranch != null) { - IReferencedFigure sourceFigure = (IReferencedFigure) sourceBranch - .getFigure(); - Point sourcePosition = sourceFigure.getReference(); - Insets sourceIns = sourceFigure - .getReferenceDescription(); - IReferencedFigure targetFigure = (IReferencedFigure) targetBranch - .getFigure(); - Insets targetIns = targetFigure - .getReferenceDescription(); - return new Point(sourcePosition.x, sourcePosition.y - + sourceIns.bottom + targetIns.top + 10); - } - } - } - } - org.xmind.core.util.Point sourcePosition = sourceTopic.getPosition(); - if (sourcePosition != null) - return new Point(sourcePosition.x, sourcePosition.y + 60); - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.osgi.util.NLS; +import org.xmind.core.IBoundary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicRange; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.AddBoundaryCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.CreateTopicCommand; +import org.xmind.ui.commands.DeleteBoundaryCommand; +import org.xmind.ui.commands.DeleteTopicCommand; +import org.xmind.ui.commands.ModifyFoldedCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class CreateTopicCommandBuilder extends CommandBuilder { + + private ITopic sourceTopic; + + private List sources; + + private String createType; + + private ITopic targetParent; + + private String targetType; + + private int targetIndex; + + private int sourceIndex; + + private ITopic createdTopic = null; + + public CreateTopicCommandBuilder(IViewer viewer, CommandBuilder delegate, + ITopic sourceTopic, String createType) { + super(viewer, delegate); + init(sourceTopic, createType); + } + + public CreateTopicCommandBuilder(IViewer viewer, + ICommandStack commandStack, ITopic sourceTopic, String createType) { + super(viewer, commandStack); + init(sourceTopic, createType); + } + + public CreateTopicCommandBuilder(IViewer viewer, + ICommandStack commandStack, ITopic sourceTopic, String createType, + List sources) { + this(viewer, commandStack, sourceTopic, createType); + this.sources = sources; + } + + private void init(ITopic sourceTopic, String createType) { + this.sourceTopic = sourceTopic; + this.createType = createType; + this.sourceIndex = sourceTopic.getIndex(); + if (MindMapUI.REQ_CREATE_CHILD.equals(createType)) { + this.targetParent = sourceTopic; + this.targetType = ITopic.ATTACHED; + this.targetIndex = targetParent.getChildren(targetType).size(); + } else if (MindMapUI.REQ_CREATE_CALLOUT.equals(createType)) { + this.targetParent = sourceTopic; + this.targetType = ITopic.CALLOUT; + this.targetIndex = targetParent.getChildren(targetType).size(); + } else { + this.targetParent = sourceTopic.getParent(); + if (this.targetParent != null) { + if (GEF.REQ_CREATE.equals(createType)) { + this.targetIndex = sourceTopic.getIndex() + 1; + this.targetType = sourceTopic.getType(); + } else if (MindMapUI.REQ_CREATE_BEFORE.equals(createType) + || MindMapUI.REQ_CREATE_PARENT.equals(createType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { + this.targetIndex = sourceTopic.getIndex(); + this.targetType = sourceTopic.getType(); + } else { + this.targetIndex = -1; + this.targetType = null; + } + } else { + this.targetIndex = -1; + this.targetType = null; + } + } + } + + public ITopic getCreatedTopic() { + return createdTopic; + } + + public String getCreateType() { + return createType; + } + + public ITopic getSourceTopic() { + return sourceTopic; + } + + public int getSourceIndex() { + return sourceIndex; + } + + public int getTargetIndex() { + return targetIndex; + } + + public ITopic getTargetParent() { + return targetParent; + } + + public String getTargetType() { + return targetType; + } + + public void createTopic() { + if (!canStart()) + return; + + CreateTopicCommand create = new CreateTopicCommand( + sourceTopic.getOwnedWorkbook()); + add(create, true); + + createdTopic = (ITopic) create.getSource(); + if (createdTopic == null) + return; + + preAdd(); + add(new AddTopicCommand(createdTopic, targetParent, targetIndex, + targetType), true); + postAdded(); + } + + public void createDuplicateTopic() { + if (!canStart()) + return; + + createdTopic = sourceTopic.getOwnedWorkbook().cloneTopic(sourceTopic); + if (createdTopic == null) + return; + + ensureParentUnfolded(); + add(new AddTopicCommand(createdTopic, targetParent, targetIndex, + targetType), true); + postAdded(); + } + + public boolean canStart() { + return super.canStart() && targetParent != null && targetType != null; + } + + private void preAdd() { + ensureParentUnfolded(); + setNewTitle(); + if (ITopic.CALLOUT.equals(targetType)) { + add(new ModifyPositionCommand(createdTopic, + new org.xmind.core.util.Point(0, 0)), false); + } + } + + private void postAdded() { + if (MindMapUI.REQ_CREATE_PARENT.equals(createType)) { + if (sources != null) { + for (ITopic sourceTopic : sources) { + if (ITopic.DETACHED.equals(targetType)) { + add(new ModifyPositionCommand(createdTopic, + sourceTopic.getPosition()), false); + add(new ModifyPositionCommand(sourceTopic, null), false); + } + add(new DeleteTopicCommand(sourceTopic), false); + add(new AddTopicCommand(sourceTopic, createdTopic), false); + moveOverallBoundaries(sourceTopic, createdTopic); + } + } + } else { + if (ITopic.ATTACHED.equals(targetType)) { + if (GEF.REQ_CREATE.equals(createType) + || MindMapUI.REQ_CREATE_BEFORE.equals(createType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { + if (sourceIndex >= 0) + modifyRanges(); + } + } + } + + } + + private void moveOverallBoundaries(ITopic fromTopic, ITopic toTopic) { + IBoundary overallBoundary = null; + for (Object o : fromTopic.getBoundaries().toArray()) { + IBoundary boundary = (IBoundary) o; + if (boundary.isMasterBoundary() && overallBoundary == null) { + overallBoundary = boundary; + } + add(new DeleteBoundaryCommand(boundary), false); + } + + if (overallBoundary != null) { + if (!hasOverallBoundaries(toTopic)) { + add(new AddBoundaryCommand(overallBoundary, toTopic), false); + } + } + } + + private boolean hasOverallBoundaries(ITopic topic) { + for (IBoundary boundary : topic.getBoundaries()) { + if (boundary.isMasterBoundary()) + return true; + } + return false; + } + + private void modifyRanges() { + modifyRanges(targetParent.getBoundaries()); + modifyRanges(targetParent.getSummaries()); + } + + private void modifyRanges(Collection ranges) { + for (ITopicRange range : ranges) { + int startIndex = range.getStartIndex(); + int endIndex = range.getEndIndex(); + if (startIndex >= 0 && endIndex >= 0) { + if (startIndex > sourceIndex) { + add(new ModifyRangeCommand(range, startIndex + 1, true), + false); + } + if (endIndex >= sourceIndex) { + add(new ModifyRangeCommand(range, endIndex + 1, false), + false); + } + } + } + } + + private void setNewTitle() { + add(new ModifyTitleTextCommand(createdTopic, getNewTitle()), false); + } + + private String getNewTitle() { + if (ITopic.DETACHED.equals(targetType)) { + return MindMapMessages.TitleText_FloatingTopic; + } else if (ITopic.CALLOUT.equals(targetType)) { + return MindMapMessages.TitleText_CalloutTopic; + } else { + int size = targetParent.getChildren(targetType).size(); + int newNumber = size + 1; + if (targetParent.isRoot()) { + return NLS.bind(MindMapMessages.TitleText_MainTopic, newNumber); + } else { + return NLS.bind(MindMapMessages.TitleText_Subtopic, newNumber); + } + } + } + + private void ensureParentUnfolded() { + if (targetParent.isFolded()) { + add(new ModifyFoldedCommand(targetParent, false), false); + } + } + + protected void handlePendingCommands() { + super.handlePendingCommands(); + if (ITopic.DETACHED.equals(targetType)) { + if (GEF.REQ_CREATE.equals(createType)) { + setNewPosition(true); + } else if (MindMapUI.REQ_CREATE_BEFORE.equals(createType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(createType)) { + setNewPosition(false); + } + } + } + + private void setNewPosition(boolean lowerOrUpper) { + Point newPosition = calcNewPosition(lowerOrUpper); + add(new ModifyPositionCommand(createdTopic, + MindMapUtils.toModelPosition(newPosition)), false); + } + + private Point calcNewPosition(boolean lowerOrUpper) { + IPart sourcePart = getViewer().findPart(sourceTopic); + if (sourcePart != null && sourcePart instanceof ITopicPart) { + IBranchPart sourceBranch = ((ITopicPart) sourcePart) + .getOwnerBranch(); + if (sourceBranch != null) { + IPart targetPart = getViewer().findPart(createdTopic); + if (targetPart != null && targetPart instanceof ITopicPart) { + IBranchPart targetBranch = ((ITopicPart) targetPart) + .getOwnerBranch(); + if (targetBranch != null) { + IReferencedFigure sourceFigure = (IReferencedFigure) sourceBranch + .getFigure(); + Point sourcePosition = sourceFigure.getReference(); + Insets sourceIns = sourceFigure + .getReferenceDescription(); + IReferencedFigure targetFigure = (IReferencedFigure) targetBranch + .getFigure(); + Insets targetIns = targetFigure + .getReferenceDescription(); + return new Point(sourcePosition.x, sourcePosition.y + + sourceIns.bottom + targetIns.top + 10); + } + } + } + } + org.xmind.core.util.Point sourcePosition = sourceTopic.getPosition(); + if (sourcePosition != null) + return new Point(sourcePosition.x, sourcePosition.y + 60); + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeletablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeletablePolicy.java index a7a99a69f..8a250eec0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeletablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeletablePolicy.java @@ -1,195 +1,195 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.jface.viewers.StructuredSelection; -import org.xmind.core.IRelationship; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicComponent; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.gef.GEF; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.IBranchStructureExtension; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; -import org.xmind.ui.internal.branch.UnbalancedData; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class DeletablePolicy extends MindMapPolicyBase { - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_DELETE.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (GEF.REQ_DELETE.equals(reqType)) { - delete(request); - } - } - - protected void delete(Request request) { - IViewer viewer = request.getTargetViewer(); - List targets = request.getTargets(); - - List elements = getElementsToDelete(targets, viewer); - if (elements == null || elements.isEmpty()) - return; - - IPart toFocus = MindMapUtils.findToFocus(targets, viewer); - - String label = getDeleteLabel(MindMapUI.getCategoryManager() - .analyze(elements.toArray()).getMainCategory()); - - DeleteCommandBuilder builder = new DeleteCommandBuilder(viewer, - request.getTargetCommandStack()); - if (!builder.canStart()) - return; - - ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - if (centralTopic == null) - return; - - String centralTopicStricture = centralTopic.getStructureClass(); - boolean isUnthrowedSideStructure = centralTopicStricture == null - || UnbalancedData.STRUCTUREID_UNBALANCED - .equalsIgnoreCase(centralTopicStricture); - - if (isUnthrowedSideStructure) { - ITopicExtension extension = centralTopic.createExtension( - UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement ee = extension.getContent().getCreatedChild( - UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - String preDeleteRightNum = ee.getTextContent(); - if (preDeleteRightNum == null) - preDeleteRightNum = String.valueOf(0); - int postDeleteRightNum = Integer.valueOf(preDeleteRightNum); - for (IPart topicPart : targets) { - if (topicPart instanceof ITopicPart && !(ITopic.SUMMARY.equals( - ((ITopicPart) topicPart).getTopic().getType()))) { - IBranchPart mainBranch = MindMapUtils.findBranch(topicPart); - if (!mainBranch.isCentral()) { - IBranchPart centralBranch = mainBranch - .getParentBranch(); - if (centralBranch != null - && centralBranch.isCentral()) { - IStructure structure = centralBranch - .getBranchPolicy() - .getStructure(centralBranch); - if ((((IBranchStructureExtension) structure) - .getChildTargetOrientation(centralBranch, - mainBranch) == PositionConstants.WEST)) { - postDeleteRightNum--; - } - } - } - } - } - if (!preDeleteRightNum.equals(postDeleteRightNum)) { - builder.addPendingCommand( - new ModifyRightNumberOfUnbalancedStructureCommand( - centralTopic, preDeleteRightNum, - postDeleteRightNum), - true); - } - } - - builder.start(); - builder.setLabel(label); - - for (Object element : elements) { - builder.delete(element); - } - builder.end(); - -// Command cmd = getDeleteCommand(targets, viewer); -// if (cmd == null) -// return; -// -// saveAndRun(cmd, domain); - - if (toFocus != null) { - select(toFocus, viewer); - - } else { - ITopic topic = (ITopic) viewer.getAdapter(ITopic.class); - if (topic != null) { - select(topic, viewer); - } else { - viewer.setSelection(StructuredSelection.EMPTY, true); - } - } - } - - protected List getElementsToDelete(List targets, - IViewer viewer) { - ITopic rootTopic = (ITopic) viewer.getAdapter(ITopic.class); - List topics = MindMapUtils.getTopics(targets); - topics.remove(rootTopic); - topics = MindMapUtils.filterOutDescendents(topics, rootTopic); - - List others = new ArrayList( - targets.size() - topics.size()); - for (IPart p : targets) { - Object m = MindMapUtils.getRealModel(p); - if (m instanceof IRelationship) { - IRelationship r = (IRelationship) m; - if (!others.contains(r)) { - others.add(r); - } - } else if (m instanceof ITopicComponent && !(m instanceof ITopic)) { - ITopic parent = ((ITopicComponent) m).getParent(); - if (parent != null && !topics.contains(parent) - && !MindMapUtils.isAncestorInList(parent, topics)) { - others.add(m); - } - } - } - if (topics.isEmpty() && others.isEmpty()) - return null; - - ArrayList list = new ArrayList( - topics.size() + others.size()); - list.addAll(topics); - list.addAll(others); - return list; - } - - protected String getDeleteLabel(String type) { - if (MindMapUI.CATEGORY_TOPIC.equals(type)) - return CommandMessages.Command_DeleteTopic; - if (MindMapUI.CATEGORY_RELATIONSHIP.equals(type)) - return CommandMessages.Command_DeleteRelationship; - if (MindMapUI.CATEGORY_MARKER.equals(type)) - return CommandMessages.Command_DeleteMarker; - if (MindMapUI.CATEGORY_SHEET.equals(type)) - return CommandMessages.Command_DeleteSheet; - if (MindMapUI.CATEGORY_BOUNDARY.equals(type)) - return CommandMessages.Command_DeleteBoundary; - return CommandMessages.Command_Delete; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.jface.viewers.StructuredSelection; +import org.xmind.core.IRelationship; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicComponent; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.IBranchStructureExtension; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; +import org.xmind.ui.internal.branch.UnbalancedData; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class DeletablePolicy extends MindMapPolicyBase { + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_DELETE.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (GEF.REQ_DELETE.equals(reqType)) { + delete(request); + } + } + + protected void delete(Request request) { + IViewer viewer = request.getTargetViewer(); + List targets = request.getTargets(); + + List elements = getElementsToDelete(targets, viewer); + if (elements == null || elements.isEmpty()) + return; + + IPart toFocus = MindMapUtils.findToFocus(targets, viewer); + + String label = getDeleteLabel(MindMapUI.getCategoryManager() + .analyze(elements.toArray()).getMainCategory()); + + DeleteCommandBuilder builder = new DeleteCommandBuilder(viewer, + request.getTargetCommandStack()); + if (!builder.canStart()) + return; + + ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); + if (centralTopic == null) + return; + + String centralTopicStricture = centralTopic.getStructureClass(); + boolean isUnthrowedSideStructure = centralTopicStricture == null + || UnbalancedData.STRUCTUREID_UNBALANCED + .equalsIgnoreCase(centralTopicStricture); + + if (isUnthrowedSideStructure) { + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement ee = extension.getContent().getCreatedChild( + UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + String preDeleteRightNum = ee.getTextContent(); + if (preDeleteRightNum == null) + preDeleteRightNum = String.valueOf(0); + int postDeleteRightNum = Integer.valueOf(preDeleteRightNum); + for (IPart topicPart : targets) { + if (topicPart instanceof ITopicPart && !(ITopic.SUMMARY.equals( + ((ITopicPart) topicPart).getTopic().getType()))) { + IBranchPart mainBranch = MindMapUtils.findBranch(topicPart); + if (!mainBranch.isCentral()) { + IBranchPart centralBranch = mainBranch + .getParentBranch(); + if (centralBranch != null + && centralBranch.isCentral()) { + IStructure structure = centralBranch + .getBranchPolicy() + .getStructure(centralBranch); + if ((((IBranchStructureExtension) structure) + .getChildTargetOrientation(centralBranch, + mainBranch) == PositionConstants.WEST)) { + postDeleteRightNum--; + } + } + } + } + } + if (!preDeleteRightNum.equals(postDeleteRightNum)) { + builder.addPendingCommand( + new ModifyRightNumberOfUnbalancedStructureCommand( + centralTopic, preDeleteRightNum, + postDeleteRightNum), + true); + } + } + + builder.start(); + builder.setLabel(label); + + for (Object element : elements) { + builder.delete(element); + } + builder.end(); + +// Command cmd = getDeleteCommand(targets, viewer); +// if (cmd == null) +// return; +// +// saveAndRun(cmd, domain); + + if (toFocus != null) { + select(toFocus, viewer); + + } else { + ITopic topic = (ITopic) viewer.getAdapter(ITopic.class); + if (topic != null) { + select(topic, viewer); + } else { + viewer.setSelection(StructuredSelection.EMPTY, true); + } + } + } + + protected List getElementsToDelete(List targets, + IViewer viewer) { + ITopic rootTopic = (ITopic) viewer.getAdapter(ITopic.class); + List topics = MindMapUtils.getTopics(targets); + topics.remove(rootTopic); + topics = MindMapUtils.filterOutDescendents(topics, rootTopic); + + List others = new ArrayList( + targets.size() - topics.size()); + for (IPart p : targets) { + Object m = MindMapUtils.getRealModel(p); + if (m instanceof IRelationship) { + IRelationship r = (IRelationship) m; + if (!others.contains(r)) { + others.add(r); + } + } else if (m instanceof ITopicComponent && !(m instanceof ITopic)) { + ITopic parent = ((ITopicComponent) m).getParent(); + if (parent != null && !topics.contains(parent) + && !MindMapUtils.isAncestorInList(parent, topics)) { + others.add(m); + } + } + } + if (topics.isEmpty() && others.isEmpty()) + return null; + + ArrayList list = new ArrayList( + topics.size() + others.size()); + list.addAll(topics); + list.addAll(others); + return list; + } + + protected String getDeleteLabel(String type) { + if (MindMapUI.CATEGORY_TOPIC.equals(type)) + return CommandMessages.Command_DeleteTopic; + if (MindMapUI.CATEGORY_RELATIONSHIP.equals(type)) + return CommandMessages.Command_DeleteRelationship; + if (MindMapUI.CATEGORY_MARKER.equals(type)) + return CommandMessages.Command_DeleteMarker; + if (MindMapUI.CATEGORY_SHEET.equals(type)) + return CommandMessages.Command_DeleteSheet; + if (MindMapUI.CATEGORY_BOUNDARY.equals(type)) + return CommandMessages.Command_DeleteBoundary; + return CommandMessages.Command_Delete; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeleteCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeleteCommandBuilder.java index b5b04ee45..3dbb028c0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeleteCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/DeleteCommandBuilder.java @@ -1,369 +1,369 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Stack; - -import org.xmind.core.IBoundary; -import org.xmind.core.IImage; -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicRange; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.DeleteBoundaryCommand; -import org.xmind.ui.commands.DeleteMarkerCommand; -import org.xmind.ui.commands.DeleteRelationshipCommand; -import org.xmind.ui.commands.DeleteSummaryCommand; -import org.xmind.ui.commands.DeleteTopicCommand; -import org.xmind.ui.commands.ModifyImageAlignmentCommand; -import org.xmind.ui.commands.ModifyImageSizeCommand; -import org.xmind.ui.commands.ModifyImageSourceCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.util.MindMapUtils; - -public class DeleteCommandBuilder extends CommandBuilder { - - private static final Collection EMPTY = Collections.emptySet(); - - private Stack deleting = null; - - private Set relationships = null; - - private Map> subRanges = null; - - private Set deleted = null; - -// private ITopicRefCounter topicLinkRef = null; - - public DeleteCommandBuilder(IViewer viewer, CommandBuilder delegate) { - super(viewer, delegate); - } - - public DeleteCommandBuilder(IViewer viewer, ICommandStack commandStack) { - super(viewer, commandStack); - } - - public void delete(Object element) { - if (element instanceof ITopic) { - deleteTopic((ITopic) element, true); - } else if (element instanceof IBoundary) { - deleteBoundary((IBoundary) element, true); - } else if (element instanceof ISummary) { - deleteSummary((ISummary) element, true); - } else if (element instanceof IRelationship) { - deleteRelationship((IRelationship) element, true); - } else if (element instanceof IMarkerRef) { - deleteMarkerRef((IMarkerRef) element, true); - } else if (element instanceof IImage) { - deleteImage((IImage) element, true); - } - } - - protected boolean startDeleting(Object element) { - if (isDeleting(element) || isDeleted(element)) - return false; - - if (deleting == null) - deleting = new Stack(); - deleting.push(element); - return true; - } - - protected boolean isDeleting(Object element) { - return deleting != null && deleting.contains(element); - } - - protected void endDeleting() { - if (deleting != null) { - deleting.pop(); - } - } - - protected void addDeleted(Object element) { - if (deleted == null) - deleted = new HashSet(); - deleted.add(element); - } - - protected void removeDeleted(Object element) { - if (deleted != null) { - deleted.remove(element); - } - } - - protected boolean isDeleted(Object element) { - return deleted != null && deleted.contains(element); - } - - protected Collection getDeleted() { - return deleted == null ? EMPTY : deleted; - } - - protected Collection getDeleting() { - return deleting == null ? EMPTY : deleting; - } - -// protected void deleteTopic(ITopic topic, boolean isCutPrev, -// boolean sourceCollectable) { -//// modifyTopicLinkRef(topic, isCutPrev); -// deleteTopic(topic, sourceCollectable); -// } - - protected void deleteTopic(ITopic topic, boolean sourceCollectable) { - if (!startDeleting(topic)) - return; - - deleteRelsByTopic(topic); - - ITopic parent = topic.getParent(); - if (parent != null) { - String topicType = topic.getType(); - if (ITopic.ATTACHED.equals(topicType)) { - Set ranges = getSubRanges(parent); - deleteTopicInRanges(topic, ranges, parent); - } else if (ITopic.SUMMARY.equals(topicType)) { - ISummary summary = findSummaryBySummaryTopic(topic, parent); - if (summary != null) { - deleteSummary(summary, false); - } - } - } - add(new DeleteTopicCommand(topic), sourceCollectable); - - addDeleted(topic); - endDeleting(); - } - - protected void deleteTopicInRanges(ITopic topic, Set ranges, - ITopic parent) { - if (ranges.isEmpty()) - return; - - int index = topic.getIndex(); - if (index < 0) - return; - - for (Object o : ranges.toArray()) { - ITopicRange range = (ITopicRange) o; - int start = range.getStartIndex(); - int end = range.getEndIndex(); - if (start == end && start == index) { - deleteTopicRange(range); - } else { - if (start > index) { - add(new ModifyRangeCommand(range, start - 1, true), false); - } - if (end >= index) { - add(new ModifyRangeCommand(range, end - 1, false), false); - } - } - } - } - - protected void deleteTopicRange(ITopicRange range) { - if (range instanceof IBoundary) { - deleteBoundary((IBoundary) range, false); - } else if (range instanceof ISummary) { - deleteSummary((ISummary) range, false); - } - } - - protected void deleteRelsByTopic(ITopic topic) { - deleteRelByRelEnd(topic); - for (ITopic child : topic.getAllChildren()) { - deleteRelsByTopic(child); - } - for (IBoundary boundary : topic.getBoundaries()) { - deleteRelByRelEnd(boundary); - } - } - -// private void modifyTopicLinkRef(ITopic topic, boolean isCutPrev) { -// if (topicLinkRef == null) { -// IWorkbook workbook = topic.getOwnedWorkbook(); -// topicLinkRef = (ITopicRefCounter) workbook -// .getAdapter(ITopicRefCounter.class); -// } -// -// String targetId = topic.getId(); -// List linkedTopics = topicLinkRef.getLinkTopics(targetId); -// if (linkedTopics != null && !linkedTopics.isEmpty()) { -// ModifyTopicHyperlinkCommand command = new ModifyTopicHyperlinkCommand( -// linkedTopics, null); -// add(command, false); -// -// if (!isCutPrev) { -//// topicLinkRef.removeTopicLinks(targetId); -// ModifyTopicLinkCommand cmd = new ModifyTopicLinkCommand( -// linkedTopics, null); -// add(cmd, false); -// } -// } -// -// List children = topic.getAllChildren(); -// if (children != null && !children.isEmpty()) { -// for (ITopic child : children) { -// modifyTopicLinkRef(child, isCutPrev); -// } -// } -// } - - protected void deleteRelByRelEnd(IRelationshipEnd end) { - if (hasRelationship()) { - String id = end.getId(); - for (Object o : getRelationships().toArray()) { - IRelationship r = (IRelationship) o; - if (id.equals(r.getEnd1Id()) || id.equals(r.getEnd2Id())) { - deleteRelationship(r, false); - } - } - } - } - - protected boolean hasRelationship() { - return !getRelationships().isEmpty(); - } - - protected Set getRelationships() { - if (relationships == null) { - relationships = new HashSet(); - ISheet sheet = (ISheet) getViewer().getAdapter(ISheet.class); - if (sheet != null) { - relationships.addAll(sheet.getRelationships()); - } - } - return relationships; - } - - protected ISummary findSummaryBySummaryTopic(ITopic topic, ITopic parent) { - return MindMapUtils.findSummaryBySummaryTopic(topic, parent, - getSubRanges(parent)); - } - - protected Set getSubRanges(ITopic parent) { - if (subRanges == null) - subRanges = new HashMap>(); - Set ranges = subRanges.get(parent); - if (ranges == null) { - ranges = new HashSet(); - if (parent != null) { - ranges.addAll(parent.getBoundaries()); - ranges.addAll(parent.getSummaries()); - subRanges.put(parent, ranges); - } - } - return ranges; - } - - protected void removeSubRange(ITopicRange range, ITopic parent) { - if (subRanges != null) { - Set ranges = subRanges.get(parent); - if (ranges != null) { - ranges.remove(range); - } - } - } - - protected void addSubRange(ITopicRange range, ITopic parent) { - if (subRanges == null) - subRanges = new HashMap>(); - Set ranges = subRanges.get(parent); - if (ranges == null) { - ranges = new HashSet(); - } - ranges.add(range); - } - - protected void deleteBoundary(IBoundary boundary, - boolean sourceCollectable) { - if (!startDeleting(boundary)) - return; - - deleteRelByRelEnd(boundary); - - ITopic parent = boundary.getParent(); - add(new DeleteBoundaryCommand(boundary), sourceCollectable); - removeSubRange(boundary, parent); - - endDeleting(); - addDeleted(boundary); - } - - protected void deleteSummary(ISummary summary, boolean sourceCollectable) { - if (!startDeleting(summary)) - return; - - ITopic parent = summary.getParent(); - ITopic summaryTopic = summary.getTopic(); - if (summaryTopic != null) { - deleteTopic(summaryTopic, false); - } - add(new DeleteSummaryCommand(summary), sourceCollectable); - removeSubRange(summary, parent); - - endDeleting(); - addDeleted(summary); - } - - protected void deleteRelationship(IRelationship relationship, - boolean sourceCollectable) { - if (!startDeleting(relationship)) - return; - - add(new DeleteRelationshipCommand(relationship), sourceCollectable); - if (relationships != null) { - relationships.remove(relationship); - } - - endDeleting(); - addDeleted(relationship); - } - - protected void deleteMarkerRef(IMarkerRef markerRef, - boolean sourceCollectable) { - if (!startDeleting(markerRef)) - return; - - add(new DeleteMarkerCommand(markerRef), sourceCollectable); - - endDeleting(); - addDeleted(markerRef); - } - - protected void deleteImage(IImage image, boolean sourceCollectable) { - if (!startDeleting(image)) - return; - - add(new ModifyImageSourceCommand(image, null), sourceCollectable); - add(new ModifyImageAlignmentCommand(image, null), sourceCollectable); - add(new ModifyImageSizeCommand(image, IImage.UNSPECIFIED, - IImage.UNSPECIFIED), sourceCollectable); - - endDeleting(); - addDeleted(image); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.xmind.core.IBoundary; +import org.xmind.core.IImage; +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicRange; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.DeleteBoundaryCommand; +import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.commands.DeleteRelationshipCommand; +import org.xmind.ui.commands.DeleteSummaryCommand; +import org.xmind.ui.commands.DeleteTopicCommand; +import org.xmind.ui.commands.ModifyImageAlignmentCommand; +import org.xmind.ui.commands.ModifyImageSizeCommand; +import org.xmind.ui.commands.ModifyImageSourceCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.util.MindMapUtils; + +public class DeleteCommandBuilder extends CommandBuilder { + + private static final Collection EMPTY = Collections.emptySet(); + + private Stack deleting = null; + + private Set relationships = null; + + private Map> subRanges = null; + + private Set deleted = null; + +// private ITopicRefCounter topicLinkRef = null; + + public DeleteCommandBuilder(IViewer viewer, CommandBuilder delegate) { + super(viewer, delegate); + } + + public DeleteCommandBuilder(IViewer viewer, ICommandStack commandStack) { + super(viewer, commandStack); + } + + public void delete(Object element) { + if (element instanceof ITopic) { + deleteTopic((ITopic) element, true); + } else if (element instanceof IBoundary) { + deleteBoundary((IBoundary) element, true); + } else if (element instanceof ISummary) { + deleteSummary((ISummary) element, true); + } else if (element instanceof IRelationship) { + deleteRelationship((IRelationship) element, true); + } else if (element instanceof IMarkerRef) { + deleteMarkerRef((IMarkerRef) element, true); + } else if (element instanceof IImage) { + deleteImage((IImage) element, true); + } + } + + protected boolean startDeleting(Object element) { + if (isDeleting(element) || isDeleted(element)) + return false; + + if (deleting == null) + deleting = new Stack(); + deleting.push(element); + return true; + } + + protected boolean isDeleting(Object element) { + return deleting != null && deleting.contains(element); + } + + protected void endDeleting() { + if (deleting != null) { + deleting.pop(); + } + } + + protected void addDeleted(Object element) { + if (deleted == null) + deleted = new HashSet(); + deleted.add(element); + } + + protected void removeDeleted(Object element) { + if (deleted != null) { + deleted.remove(element); + } + } + + protected boolean isDeleted(Object element) { + return deleted != null && deleted.contains(element); + } + + protected Collection getDeleted() { + return deleted == null ? EMPTY : deleted; + } + + protected Collection getDeleting() { + return deleting == null ? EMPTY : deleting; + } + +// protected void deleteTopic(ITopic topic, boolean isCutPrev, +// boolean sourceCollectable) { +//// modifyTopicLinkRef(topic, isCutPrev); +// deleteTopic(topic, sourceCollectable); +// } + + protected void deleteTopic(ITopic topic, boolean sourceCollectable) { + if (!startDeleting(topic)) + return; + + deleteRelsByTopic(topic); + + ITopic parent = topic.getParent(); + if (parent != null) { + String topicType = topic.getType(); + if (ITopic.ATTACHED.equals(topicType)) { + Set ranges = getSubRanges(parent); + deleteTopicInRanges(topic, ranges, parent); + } else if (ITopic.SUMMARY.equals(topicType)) { + ISummary summary = findSummaryBySummaryTopic(topic, parent); + if (summary != null) { + deleteSummary(summary, false); + } + } + } + add(new DeleteTopicCommand(topic), sourceCollectable); + + addDeleted(topic); + endDeleting(); + } + + protected void deleteTopicInRanges(ITopic topic, Set ranges, + ITopic parent) { + if (ranges.isEmpty()) + return; + + int index = topic.getIndex(); + if (index < 0) + return; + + for (Object o : ranges.toArray()) { + ITopicRange range = (ITopicRange) o; + int start = range.getStartIndex(); + int end = range.getEndIndex(); + if (start == end && start == index) { + deleteTopicRange(range); + } else { + if (start > index) { + add(new ModifyRangeCommand(range, start - 1, true), false); + } + if (end >= index) { + add(new ModifyRangeCommand(range, end - 1, false), false); + } + } + } + } + + protected void deleteTopicRange(ITopicRange range) { + if (range instanceof IBoundary) { + deleteBoundary((IBoundary) range, false); + } else if (range instanceof ISummary) { + deleteSummary((ISummary) range, false); + } + } + + protected void deleteRelsByTopic(ITopic topic) { + deleteRelByRelEnd(topic); + for (ITopic child : topic.getAllChildren()) { + deleteRelsByTopic(child); + } + for (IBoundary boundary : topic.getBoundaries()) { + deleteRelByRelEnd(boundary); + } + } + +// private void modifyTopicLinkRef(ITopic topic, boolean isCutPrev) { +// if (topicLinkRef == null) { +// IWorkbook workbook = topic.getOwnedWorkbook(); +// topicLinkRef = (ITopicRefCounter) workbook +// .getAdapter(ITopicRefCounter.class); +// } +// +// String targetId = topic.getId(); +// List linkedTopics = topicLinkRef.getLinkTopics(targetId); +// if (linkedTopics != null && !linkedTopics.isEmpty()) { +// ModifyTopicHyperlinkCommand command = new ModifyTopicHyperlinkCommand( +// linkedTopics, null); +// add(command, false); +// +// if (!isCutPrev) { +//// topicLinkRef.removeTopicLinks(targetId); +// ModifyTopicLinkCommand cmd = new ModifyTopicLinkCommand( +// linkedTopics, null); +// add(cmd, false); +// } +// } +// +// List children = topic.getAllChildren(); +// if (children != null && !children.isEmpty()) { +// for (ITopic child : children) { +// modifyTopicLinkRef(child, isCutPrev); +// } +// } +// } + + protected void deleteRelByRelEnd(IRelationshipEnd end) { + if (hasRelationship()) { + String id = end.getId(); + for (Object o : getRelationships().toArray()) { + IRelationship r = (IRelationship) o; + if (id.equals(r.getEnd1Id()) || id.equals(r.getEnd2Id())) { + deleteRelationship(r, false); + } + } + } + } + + protected boolean hasRelationship() { + return !getRelationships().isEmpty(); + } + + protected Set getRelationships() { + if (relationships == null) { + relationships = new HashSet(); + ISheet sheet = (ISheet) getViewer().getAdapter(ISheet.class); + if (sheet != null) { + relationships.addAll(sheet.getRelationships()); + } + } + return relationships; + } + + protected ISummary findSummaryBySummaryTopic(ITopic topic, ITopic parent) { + return MindMapUtils.findSummaryBySummaryTopic(topic, parent, + getSubRanges(parent)); + } + + protected Set getSubRanges(ITopic parent) { + if (subRanges == null) + subRanges = new HashMap>(); + Set ranges = subRanges.get(parent); + if (ranges == null) { + ranges = new HashSet(); + if (parent != null) { + ranges.addAll(parent.getBoundaries()); + ranges.addAll(parent.getSummaries()); + subRanges.put(parent, ranges); + } + } + return ranges; + } + + protected void removeSubRange(ITopicRange range, ITopic parent) { + if (subRanges != null) { + Set ranges = subRanges.get(parent); + if (ranges != null) { + ranges.remove(range); + } + } + } + + protected void addSubRange(ITopicRange range, ITopic parent) { + if (subRanges == null) + subRanges = new HashMap>(); + Set ranges = subRanges.get(parent); + if (ranges == null) { + ranges = new HashSet(); + } + ranges.add(range); + } + + protected void deleteBoundary(IBoundary boundary, + boolean sourceCollectable) { + if (!startDeleting(boundary)) + return; + + deleteRelByRelEnd(boundary); + + ITopic parent = boundary.getParent(); + add(new DeleteBoundaryCommand(boundary), sourceCollectable); + removeSubRange(boundary, parent); + + endDeleting(); + addDeleted(boundary); + } + + protected void deleteSummary(ISummary summary, boolean sourceCollectable) { + if (!startDeleting(summary)) + return; + + ITopic parent = summary.getParent(); + ITopic summaryTopic = summary.getTopic(); + if (summaryTopic != null) { + deleteTopic(summaryTopic, false); + } + add(new DeleteSummaryCommand(summary), sourceCollectable); + removeSubRange(summary, parent); + + endDeleting(); + addDeleted(summary); + } + + protected void deleteRelationship(IRelationship relationship, + boolean sourceCollectable) { + if (!startDeleting(relationship)) + return; + + add(new DeleteRelationshipCommand(relationship), sourceCollectable); + if (relationships != null) { + relationships.remove(relationship); + } + + endDeleting(); + addDeleted(relationship); + } + + protected void deleteMarkerRef(IMarkerRef markerRef, + boolean sourceCollectable) { + if (!startDeleting(markerRef)) + return; + + add(new DeleteMarkerCommand(markerRef), sourceCollectable); + + endDeleting(); + addDeleted(markerRef); + } + + protected void deleteImage(IImage image, boolean sourceCollectable) { + if (!startDeleting(image)) + return; + + add(new ModifyImageSourceCommand(image, null), sourceCollectable); + add(new ModifyImageAlignmentCommand(image, null), sourceCollectable); + add(new ModifyImageSizeCommand(image, IImage.UNSPECIFIED, + IImage.UNSPECIFIED), sourceCollectable); + + endDeleting(); + addDeleted(image); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/EditablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/EditablePolicy.java index eb949236e..ebe5d87b4 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/EditablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/EditablePolicy.java @@ -1,572 +1,572 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.swt.dnd.Clipboard; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.widgets.Display; -import org.xmind.core.Core; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicComponent; -import org.xmind.gef.GEF; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.dnd.DndData; -import org.xmind.gef.dnd.IDndClient; -import org.xmind.gef.dnd.IDndSupport; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class EditablePolicy extends DeletablePolicy { - -// private static final String DEFAULT_DND_CLIENT_ID = MindMapUI.DND_MINDMAP_ELEMENT; - -// private boolean isCutPrev = false; - -// private Map transferMap = null; - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_COPY.equals(requestType) - || GEF.REQ_CUT.equals(requestType) - || GEF.REQ_PASTE.equals(requestType) - || MindMapUI.REQ_REPLACE_ALL.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (GEF.REQ_COPY.equals(reqType)) { - copy(request); - } else if (GEF.REQ_CUT.equals(reqType)) { - cut(request); - } else if (GEF.REQ_PASTE.equals(reqType)) { - paste(request); - } else if (MindMapUI.REQ_REPLACE_ALL.equals(reqType)) { - replaceAll(request); - } else if (!GEF.REQ_DELETE.equals(reqType)) { - super.handle(request); - } - } - - protected void copy(Request request) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return; - - List sources = request.getTargets(); - List models = filter(MindMapUtils.getRealModels(sources), - viewer); - if (models.isEmpty()) - return; - - performCopy(models.toArray(), request.getTargetViewer()); - } - - protected List filter(List elements, IViewer viewer) { - ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); - ITopic root = (ITopic) viewer.getAdapter(ITopic.class); - ArrayList list = new ArrayList(elements.size()); - for (Object o : elements) { - if (!shouldRemove(o, elements, sheet, root, viewer)) - list.add(o); - } - return list; - } - - private boolean shouldRemove(Object element, List elements, - ISheet sheet, ITopic root, IViewer viewer) { - if (element instanceof IRelationship) { - IRelationship r = (IRelationship) element; - for (Object o : elements) { - if (o instanceof ISheet && o.equals(r.getParent())) - return true; - } - } else if (element instanceof ITopicComponent) { - ITopicComponent c = (ITopicComponent) element; - ISheet s = null; - ITopic p = null; - for (Object o : elements) { - if (o instanceof ISheet) { - if (s == null) - s = c.getOwnedSheet(); - if (o.equals(s)) - return true; - } - if (p == null) - p = c.getParent(); - if (o instanceof ITopic && p != null - && MindMapUtils.isDescendentOf(p, (ITopic) o)) - return true; - } - } - return false; - } - - protected void performCopy(Object[] elements, IViewer viewer) { - elements = filterAndSort(elements); - - IDndSupport dndSupport = viewer.getDndSupport(); - if (dndSupport != null) { - String[] ids = dndSupport.getDndClientIds(); - if (ids.length > 0) { - List data = new ArrayList(ids.length); - List transfers = new ArrayList(ids.length); - for (String id : ids) { - IDndClient client = dndSupport.getDndClient(id); - if (client != null) { - Object object = client.toTransferData(elements, viewer); - if (object != null) { - data.add(object); - Transfer transfer = client.getTransfer(); - transfers.add(transfer); - } - } - } - if (!data.isEmpty()) { - Clipboard clipboard = new Clipboard(Display.getCurrent()); - clipboard.setContents(data.toArray(), - transfers.toArray(new Transfer[0])); - clipboard.dispose(); - } - } - } - } - - private Object[] filterAndSort(Object[] elements) { - if (elements == null) { - return null; - } - - List topics = new ArrayList(); - List others = new ArrayList(); - - for (Object element : elements) { - if (element instanceof ITopic) { - topics.add((ITopic) element); - } else { - others.add(element); - } - } - - List filteredTopics = MindMapUtils.filterOutDescendents(topics, - null); - Collections.sort(filteredTopics, Core.getTopicComparator()); - - List all = new ArrayList(filteredTopics); - all.addAll(others); - return all.toArray(); - } - - protected void cut(Request request) { - List sources = request.getTargets(); - List models = MindMapUtils.getRealModels(sources); - if (models.isEmpty()) - return; -// isCutPrev = true; - performCopy(models.toArray(), request.getTargetViewer()); - delete(request); - } - - protected String getDeleteLabel(String type) { - if (MindMapUI.CATEGORY_TOPIC.equals(type)) - return CommandMessages.Command_CutTopic; - if (MindMapUI.CATEGORY_RELATIONSHIP.equals(type)) - return CommandMessages.Command_CutRelationship; - if (MindMapUI.CATEGORY_MARKER.equals(type)) - return CommandMessages.Command_DeleteMarker; - if (MindMapUI.CATEGORY_SHEET.equals(type)) - return CommandMessages.Command_CutSheet; - if (MindMapUI.CATEGORY_BOUNDARY.equals(type)) - return CommandMessages.Command_DeleteBoundary; - return CommandMessages.Command_Cut; - } - - protected void paste(Request request) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return; - - IDndSupport dndSupport = viewer.getDndSupport(); - if (dndSupport == null) - return; - - Clipboard cb = new Clipboard(Display.getCurrent()); - DndData dndData; - try { - dndData = dndSupport.parseData(cb.getAvailableTypes(), cb, false); - } finally { - cb.dispose(); - } - if (dndData == null) - return; - - IDndClient client = dndSupport.getDndClient(dndData.clientId); - if (client == null) - return; - - request.setParameter(GEF.PARAM_DROP_OPERATION, DND.DROP_COPY); - Command command = client.makeDNDCommand(dndData.parsedData, request); - if (command == null) - return; - - command.setLabel(CommandMessages.Command_Paste); - saveAndRun(command, request.getTargetDomain()); - - if (command instanceof ISourceProvider) { - select(((ISourceProvider) command).getSources(), viewer); - } -// -// ISheet targetSheet = (ISheet) viewer.getAdapter(ISheet.class); -// if (targetSheet == null) -// return; -// -// IWorkbook targetWorkbook = targetSheet.getParent(); -// if (targetWorkbook == null) -// return; -// -// IPart target = request.getPrimaryTarget(); -// Object targetModel = target == null ? viewer.getAdapter(ITopic.class) -// : MindMapUtils.getRealModel(target); -// Object[] elements = getElementsFromClipboard(viewer, targetModel); -// if (elements == null || elements.length == 0) -// return; -// -// paste(request, elements, viewer, target, -// MindMapUtils.getRealModels(request.getTargets()).toArray(), -// targetWorkbook); - } - -// protected void paste(Request request, Object[] elements, IViewer viewer, -// IPart targetPart, Object[] targets, IWorkbook targetWorkbook) { -// -// ICloneData result = targetWorkbook.clone(Arrays.asList(elements)); -// if (!result.hasCloned()) -// return; -// -// Collection cloneds = result.getCloneds(); -// ITopic targetTopic; -// if (targets.length > 0 && targets[0] instanceof ITopic) { -// targetTopic = (ITopic) targets[0]; -// } else { -// targetTopic = (ITopic) viewer.getAdapter(ITopic.class); -// } -// ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); -// List cmds = new ArrayList(cloneds.size()); -// for (Object cloned : cloneds) { -// if (cloned instanceof ITopic) { -// if (targetTopic != null) { -// ITopic clonedTopic = (ITopic) cloned; -// AddTopicCommand addTopic = new AddTopicCommand(clonedTopic, -// targetTopic, -1, ITopic.ATTACHED); -// cmds.add(addTopic); -// ModifyPositionCommand resetPosition = new ModifyPositionCommand( -// clonedTopic, null); -// cmds.add(resetPosition); -// } -// } else if (cloned instanceof IRelationship) { -// if (sheet != null) { -// IRelationship clonedRelationship = (IRelationship) cloned; -// AddRelationshipCommand addRel = new AddRelationshipCommand( -// clonedRelationship, sheet); -// cmds.add(addRel); -// } -// } else if (cloned instanceof IMarker -// || cloned instanceof IMarkerRef) { -// if (targetTopic != null) { -// IMarker marker = (cloned instanceof IMarker) ? (IMarker) cloned -// : ((IMarkerRef) cloned).getMarker(); -// if (marker != null) { -// IMarkerGroup group = marker.getParent(); -// if (group.isSingleton()) { -// for (IMarker m : group.getMarkers()) { -// if (targetTopic.hasMarker(m.getId())) { -// cmds.add(new DeleteMarkerCommand( -// targetTopic, m.getId())); -// } -// } -// } -// String markerId = (cloned instanceof IMarker) ? ((IMarker) cloned) -// .getId() : ((IMarkerRef) cloned).getMarkerId(); -// AddMarkerCommand addMarker = new AddMarkerCommand( -// targetTopic, markerId); -// cmds.add(addMarker); -// } -// } -// } else if (cloned instanceof IBoundary) { -// IBoundary b = (IBoundary) cloned; -// List topics = getSiblingTopics(targets); -// if (!topics.isEmpty() && !hasBoundary(topics)) { -// if (topics.get(0).isAttached()) { -// cmds.add(new ModifyTopicRangeCommand(b, topics.get(0), -// topics.get(topics.size() - 1))); -// cmds.add(new AddBoundaryCommand(b, topics.get(0) -// .getParent())); -// } else if (topics.size() == 1 && !topics.get(0).isRoot()) { -// cmds.add(new ModifyBoundaryMasterCommand(b, true)); -// cmds.add(new AddBoundaryCommand(b, topics.get(0))); -// } -// } -// } else if (cloned instanceof IImage) { -// IImage image = (IImage) cloned; -// if (targetTopic != null) { -// cmds.add(new ModifyImageSourceCommand(targetTopic, image -// .getSource())); -// cmds.add(new ModifyImageSizeCommand(targetTopic, image -// .getWidth(), image.getHeight())); -// cmds.add(new ModifyImageAlignmentCommand(targetTopic, image -// .getAlignment())); -// } -// } else if (cloned instanceof URI) { -// URI uri = (URI) cloned; -// if (targetTopic != null) { -// cmds.add(new ModifyTopicHyperlinkCommand(targetTopic, uri -// .toString())); -// } -// } -// } -// -//// if (isCutPrev) -//// modifyTopicLinksRef(elements, targetWorkbook, cmds, result); -// -// if (cmds.isEmpty()) -// return; -// -// CompoundCommand cmd = new CompoundCommand(cmds); -// cmd.setLabel(CommandMessages.Command_Paste); -// saveAndRun(cmd, request.getTargetDomain()); -// select(cmd.getSources(), viewer); -// } - -// private void modifyTopicLinksRef(Object[] elements, -// IWorkbook targetWorkbook, List cmds, ICloneData result) { -// -// ITopicRefCounter topicLinkRef = (ITopicRefCounter) targetWorkbook -// .getAdapter(ITopicRefCounter.class); -// for (Object element : elements) { -// if (element instanceof ITopic) { -// ITopic originTopic = (ITopic) transferMap.get(element); -// ITopic clonedTopic = (ITopic) result.get(element); -// modifyTopicLink(originTopic, clonedTopic, topicLinkRef, cmds); -// } -// } -// } - -// private void modifyTopicLink(ITopic originTopic, ITopic clonedTopic, -// ITopicRefCounter topicLinkRef, List cmds) { - -// String oldHref = originTopic.getId(); -// List topicLinks = topicLinkRef.getLinkTopics(oldHref); -// if (topicLinks != null && !topicLinks.isEmpty()) { -// String newHref = clonedTopic.getId(); -//// ModifyTopicLinkCommand cmd = new ModifyTopicLinkCommand(topicLinks, -//// newHref); -//// cmds.add(cmd); -//// topicLinkRef.modifyTargetLink(oldHref, newHref); -// -// ModifyTopicHyperlinkCommand command = new ModifyTopicHyperlinkCommand( -// topicLinks, "xmind:#" + newHref); //$NON-NLS-1$ -// cmds.add(command); -// } -// -// List children = originTopic.getAllChildren(); -// if (children != null && !children.isEmpty()) { -// for (int i = 0; i < children.size(); i++) { -// ITopic oTopic = children.get(i); -// ITopic eTopic = clonedTopic.getAllChildren().get(i); -// modifyTopicLink(oTopic, eTopic, topicLinkRef, cmds); -// } -// } -// } - -// private List getSiblingTopics(Object[] targets) { -// ITopic start = null; -// ITopic end = null; -// for (Object o : targets) { -// if (o instanceof ITopic) { -// ITopic t = (ITopic) o; -// if (start != null && MindMapUtils.isDescendentOf(start, t)) { -// start = null; -// } -// if (end != null && MindMapUtils.isDescendentOf(end, t)) { -// end = null; -// } -// if (start == null) { -// start = t; -// } else if (t.getParent().equals(start.getParent()) -// && t.getType().equals(start.getType()) -// && t.getIndex() < start.getIndex()) { -// start = t; -// } -// if (end == null) { -// end = t; -// } else if (t.getParent().equals(end.getParent()) -// && t.getType().equals(end.getType()) -// && t.getIndex() > end.getIndex()) { -// end = t; -// } -// } -// } -// if (start == null || end == null) -// return Collections.emptyList(); -// return Arrays.asList(start, end); -// } -// -// private boolean hasBoundary(List topics) { -// if (topics.get(0).isAttached()) { -// int startIndex = topics.get(0).getIndex(); -// int endIndex = topics.get(topics.size() - 1).getIndex(); -// for (IBoundary b : topics.get(0).getParent().getBoundaries()) { -// if (b.getStartIndex() == startIndex -// || b.getEndIndex() == endIndex) -// return true; -// } -// } else if (topics.size() == 1) { -// for (IBoundary b : topics.get(0).getBoundaries()) { -// if (b.isMasterBoundary()) -// return true; -// } -// } -// return false; -// } -// -// protected Object[] getElementsFromClipboard(IViewer viewer, Object target) { -// IDndSupport dndSupport = viewer.getDndSupport(); -// if (dndSupport != null) { -// String[] ids = dndSupport.getDndClientIds(); -// if (ids.length > 0) { -// Clipboard clipboard = new Clipboard(Display.getCurrent()); -// try { -// return getElementsFromClipboard(viewer, target, clipboard, -// dndSupport, ids); -// } finally { -// clipboard.dispose(); -// } -// } -// } -// return null; -// } -// -// protected Object[] getElementsFromClipboard(IViewer viewer, Object target, -// Clipboard clipboard, IDndSupport dndSupport, String[] ids) { -// TransferData[] types = clipboard.getAvailableTypes(); -// IDndClient elementClient = dndSupport -// .getDndClient(DEFAULT_DND_CLIENT_ID); -// if (elementClient != null) { -// Object[] elements = getElementsFromClipboard(viewer, target, -// elementClient, clipboard, types); -// if (elements != null) -// return elements; -// } -// for (String id : ids) { -// if (!DEFAULT_DND_CLIENT_ID.equals(id)) { -// IDndClient client = dndSupport.getDndClient(id); -// Object[] elements = getElementsFromClipboard(viewer, target, -// client, clipboard, types); -// if (elements != null) -// return elements; -// } -// } -// return null; -// } -// -// protected Object[] getElementsFromClipboard(IViewer viewer, Object target, -// IDndClient client, Clipboard clipboard, TransferData[] types) { -// if (client == null) -// return null; -// Transfer transfer = client.getTransfer(); -// if (transfer == null) -// return null; -//// if (transfer instanceof MindMapElementTransfer) { -//// transferMap = ((MindMapElementTransfer) transfer).getTransferMap(); -//// } -// for (TransferData type : types) { -// if (transfer.isSupportedType(type)) { -// Object contents = clipboard.getContents(transfer); -// if (contents != null) -// return client.toViewerElements(contents, viewer, target); -// } -// } -// return null; -// } - - private void replaceAll(Request request) { - String text = (String) request.getParameter(GEF.PARAM_TEXT); - String replacement = (String) request - .getParameter(MindMapUI.PARAM_REPLACEMENT); - if (text == null || replacement == null) - return; - - boolean ignoreCase = Boolean.TRUE - .equals(request.getParameter(MindMapUI.PARAM_IGNORE_CASE)); - List targets = request.getTargets(); - if (targets.isEmpty()) - return; - if (ignoreCase) { - text = text.toLowerCase(); - } - - PropertyCommandBuilder builder = new PropertyCommandBuilder(request); - if (builder.canStart()) { - builder.start(); - - for (IPart target : targets) { - Object model = MindMapUtils.getRealModel(target); - if (model instanceof ITitled) { - ITitled t = (ITitled) model; - String oldText = t.getTitleText(); - if (oldText != null) { - String searchText = ignoreCase ? oldText.toLowerCase() - : oldText; - StringBuilder sb = new StringBuilder( - oldText.length() + replacement.length()); - int start = 0; - int index = searchText.indexOf(text); - while (index >= 0) { - sb.append(oldText.substring(start, index)); - sb.append(replacement); - start = index + text.length(); - index = searchText.indexOf(text, start); - } - if (start < oldText.length()) { - sb.append(oldText.substring(start)); - } - String newText = sb.toString(); - if (!newText.equals(oldText)) { - builder.add(new ModifyTitleTextCommand(t, newText), - true); - } - } - - builder.addSource(t, true); - } - } - - builder.end(); - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.Core; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicComponent; +import org.xmind.gef.GEF; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.dnd.DndData; +import org.xmind.gef.dnd.IDndClient; +import org.xmind.gef.dnd.IDndSupport; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class EditablePolicy extends DeletablePolicy { + +// private static final String DEFAULT_DND_CLIENT_ID = MindMapUI.DND_MINDMAP_ELEMENT; + +// private boolean isCutPrev = false; + +// private Map transferMap = null; + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_COPY.equals(requestType) + || GEF.REQ_CUT.equals(requestType) + || GEF.REQ_PASTE.equals(requestType) + || MindMapUI.REQ_REPLACE_ALL.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (GEF.REQ_COPY.equals(reqType)) { + copy(request); + } else if (GEF.REQ_CUT.equals(reqType)) { + cut(request); + } else if (GEF.REQ_PASTE.equals(reqType)) { + paste(request); + } else if (MindMapUI.REQ_REPLACE_ALL.equals(reqType)) { + replaceAll(request); + } else if (!GEF.REQ_DELETE.equals(reqType)) { + super.handle(request); + } + } + + protected void copy(Request request) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return; + + List sources = request.getTargets(); + List models = filter(MindMapUtils.getRealModels(sources), + viewer); + if (models.isEmpty()) + return; + + performCopy(models.toArray(), request.getTargetViewer()); + } + + protected List filter(List elements, IViewer viewer) { + ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); + ITopic root = (ITopic) viewer.getAdapter(ITopic.class); + ArrayList list = new ArrayList(elements.size()); + for (Object o : elements) { + if (!shouldRemove(o, elements, sheet, root, viewer)) + list.add(o); + } + return list; + } + + private boolean shouldRemove(Object element, List elements, + ISheet sheet, ITopic root, IViewer viewer) { + if (element instanceof IRelationship) { + IRelationship r = (IRelationship) element; + for (Object o : elements) { + if (o instanceof ISheet && o.equals(r.getParent())) + return true; + } + } else if (element instanceof ITopicComponent) { + ITopicComponent c = (ITopicComponent) element; + ISheet s = null; + ITopic p = null; + for (Object o : elements) { + if (o instanceof ISheet) { + if (s == null) + s = c.getOwnedSheet(); + if (o.equals(s)) + return true; + } + if (p == null) + p = c.getParent(); + if (o instanceof ITopic && p != null + && MindMapUtils.isDescendentOf(p, (ITopic) o)) + return true; + } + } + return false; + } + + protected void performCopy(Object[] elements, IViewer viewer) { + elements = filterAndSort(elements); + + IDndSupport dndSupport = viewer.getDndSupport(); + if (dndSupport != null) { + String[] ids = dndSupport.getDndClientIds(); + if (ids.length > 0) { + List data = new ArrayList(ids.length); + List transfers = new ArrayList(ids.length); + for (String id : ids) { + IDndClient client = dndSupport.getDndClient(id); + if (client != null) { + Object object = client.toTransferData(elements, viewer); + if (object != null) { + data.add(object); + Transfer transfer = client.getTransfer(); + transfers.add(transfer); + } + } + } + if (!data.isEmpty()) { + Clipboard clipboard = new Clipboard(Display.getCurrent()); + clipboard.setContents(data.toArray(), + transfers.toArray(new Transfer[0])); + clipboard.dispose(); + } + } + } + } + + private Object[] filterAndSort(Object[] elements) { + if (elements == null) { + return null; + } + + List topics = new ArrayList(); + List others = new ArrayList(); + + for (Object element : elements) { + if (element instanceof ITopic) { + topics.add((ITopic) element); + } else { + others.add(element); + } + } + + List filteredTopics = MindMapUtils.filterOutDescendents(topics, + null); + Collections.sort(filteredTopics, Core.getTopicComparator()); + + List all = new ArrayList(filteredTopics); + all.addAll(others); + return all.toArray(); + } + + protected void cut(Request request) { + List sources = request.getTargets(); + List models = MindMapUtils.getRealModels(sources); + if (models.isEmpty()) + return; +// isCutPrev = true; + performCopy(models.toArray(), request.getTargetViewer()); + delete(request); + } + + protected String getDeleteLabel(String type) { + if (MindMapUI.CATEGORY_TOPIC.equals(type)) + return CommandMessages.Command_CutTopic; + if (MindMapUI.CATEGORY_RELATIONSHIP.equals(type)) + return CommandMessages.Command_CutRelationship; + if (MindMapUI.CATEGORY_MARKER.equals(type)) + return CommandMessages.Command_DeleteMarker; + if (MindMapUI.CATEGORY_SHEET.equals(type)) + return CommandMessages.Command_CutSheet; + if (MindMapUI.CATEGORY_BOUNDARY.equals(type)) + return CommandMessages.Command_DeleteBoundary; + return CommandMessages.Command_Cut; + } + + protected void paste(Request request) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return; + + IDndSupport dndSupport = viewer.getDndSupport(); + if (dndSupport == null) + return; + + Clipboard cb = new Clipboard(Display.getCurrent()); + DndData dndData; + try { + dndData = dndSupport.parseData(cb.getAvailableTypes(), cb, false); + } finally { + cb.dispose(); + } + if (dndData == null) + return; + + IDndClient client = dndSupport.getDndClient(dndData.clientId); + if (client == null) + return; + + request.setParameter(GEF.PARAM_DROP_OPERATION, DND.DROP_COPY); + Command command = client.makeDNDCommand(dndData.parsedData, request); + if (command == null) + return; + + command.setLabel(CommandMessages.Command_Paste); + saveAndRun(command, request.getTargetDomain()); + + if (command instanceof ISourceProvider) { + select(((ISourceProvider) command).getSources(), viewer); + } +// +// ISheet targetSheet = (ISheet) viewer.getAdapter(ISheet.class); +// if (targetSheet == null) +// return; +// +// IWorkbook targetWorkbook = targetSheet.getParent(); +// if (targetWorkbook == null) +// return; +// +// IPart target = request.getPrimaryTarget(); +// Object targetModel = target == null ? viewer.getAdapter(ITopic.class) +// : MindMapUtils.getRealModel(target); +// Object[] elements = getElementsFromClipboard(viewer, targetModel); +// if (elements == null || elements.length == 0) +// return; +// +// paste(request, elements, viewer, target, +// MindMapUtils.getRealModels(request.getTargets()).toArray(), +// targetWorkbook); + } + +// protected void paste(Request request, Object[] elements, IViewer viewer, +// IPart targetPart, Object[] targets, IWorkbook targetWorkbook) { +// +// ICloneData result = targetWorkbook.clone(Arrays.asList(elements)); +// if (!result.hasCloned()) +// return; +// +// Collection cloneds = result.getCloneds(); +// ITopic targetTopic; +// if (targets.length > 0 && targets[0] instanceof ITopic) { +// targetTopic = (ITopic) targets[0]; +// } else { +// targetTopic = (ITopic) viewer.getAdapter(ITopic.class); +// } +// ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); +// List cmds = new ArrayList(cloneds.size()); +// for (Object cloned : cloneds) { +// if (cloned instanceof ITopic) { +// if (targetTopic != null) { +// ITopic clonedTopic = (ITopic) cloned; +// AddTopicCommand addTopic = new AddTopicCommand(clonedTopic, +// targetTopic, -1, ITopic.ATTACHED); +// cmds.add(addTopic); +// ModifyPositionCommand resetPosition = new ModifyPositionCommand( +// clonedTopic, null); +// cmds.add(resetPosition); +// } +// } else if (cloned instanceof IRelationship) { +// if (sheet != null) { +// IRelationship clonedRelationship = (IRelationship) cloned; +// AddRelationshipCommand addRel = new AddRelationshipCommand( +// clonedRelationship, sheet); +// cmds.add(addRel); +// } +// } else if (cloned instanceof IMarker +// || cloned instanceof IMarkerRef) { +// if (targetTopic != null) { +// IMarker marker = (cloned instanceof IMarker) ? (IMarker) cloned +// : ((IMarkerRef) cloned).getMarker(); +// if (marker != null) { +// IMarkerGroup group = marker.getParent(); +// if (group.isSingleton()) { +// for (IMarker m : group.getMarkers()) { +// if (targetTopic.hasMarker(m.getId())) { +// cmds.add(new DeleteMarkerCommand( +// targetTopic, m.getId())); +// } +// } +// } +// String markerId = (cloned instanceof IMarker) ? ((IMarker) cloned) +// .getId() : ((IMarkerRef) cloned).getMarkerId(); +// AddMarkerCommand addMarker = new AddMarkerCommand( +// targetTopic, markerId); +// cmds.add(addMarker); +// } +// } +// } else if (cloned instanceof IBoundary) { +// IBoundary b = (IBoundary) cloned; +// List topics = getSiblingTopics(targets); +// if (!topics.isEmpty() && !hasBoundary(topics)) { +// if (topics.get(0).isAttached()) { +// cmds.add(new ModifyTopicRangeCommand(b, topics.get(0), +// topics.get(topics.size() - 1))); +// cmds.add(new AddBoundaryCommand(b, topics.get(0) +// .getParent())); +// } else if (topics.size() == 1 && !topics.get(0).isRoot()) { +// cmds.add(new ModifyBoundaryMasterCommand(b, true)); +// cmds.add(new AddBoundaryCommand(b, topics.get(0))); +// } +// } +// } else if (cloned instanceof IImage) { +// IImage image = (IImage) cloned; +// if (targetTopic != null) { +// cmds.add(new ModifyImageSourceCommand(targetTopic, image +// .getSource())); +// cmds.add(new ModifyImageSizeCommand(targetTopic, image +// .getWidth(), image.getHeight())); +// cmds.add(new ModifyImageAlignmentCommand(targetTopic, image +// .getAlignment())); +// } +// } else if (cloned instanceof URI) { +// URI uri = (URI) cloned; +// if (targetTopic != null) { +// cmds.add(new ModifyTopicHyperlinkCommand(targetTopic, uri +// .toString())); +// } +// } +// } +// +//// if (isCutPrev) +//// modifyTopicLinksRef(elements, targetWorkbook, cmds, result); +// +// if (cmds.isEmpty()) +// return; +// +// CompoundCommand cmd = new CompoundCommand(cmds); +// cmd.setLabel(CommandMessages.Command_Paste); +// saveAndRun(cmd, request.getTargetDomain()); +// select(cmd.getSources(), viewer); +// } + +// private void modifyTopicLinksRef(Object[] elements, +// IWorkbook targetWorkbook, List cmds, ICloneData result) { +// +// ITopicRefCounter topicLinkRef = (ITopicRefCounter) targetWorkbook +// .getAdapter(ITopicRefCounter.class); +// for (Object element : elements) { +// if (element instanceof ITopic) { +// ITopic originTopic = (ITopic) transferMap.get(element); +// ITopic clonedTopic = (ITopic) result.get(element); +// modifyTopicLink(originTopic, clonedTopic, topicLinkRef, cmds); +// } +// } +// } + +// private void modifyTopicLink(ITopic originTopic, ITopic clonedTopic, +// ITopicRefCounter topicLinkRef, List cmds) { + +// String oldHref = originTopic.getId(); +// List topicLinks = topicLinkRef.getLinkTopics(oldHref); +// if (topicLinks != null && !topicLinks.isEmpty()) { +// String newHref = clonedTopic.getId(); +//// ModifyTopicLinkCommand cmd = new ModifyTopicLinkCommand(topicLinks, +//// newHref); +//// cmds.add(cmd); +//// topicLinkRef.modifyTargetLink(oldHref, newHref); +// +// ModifyTopicHyperlinkCommand command = new ModifyTopicHyperlinkCommand( +// topicLinks, "xmind:#" + newHref); //$NON-NLS-1$ +// cmds.add(command); +// } +// +// List children = originTopic.getAllChildren(); +// if (children != null && !children.isEmpty()) { +// for (int i = 0; i < children.size(); i++) { +// ITopic oTopic = children.get(i); +// ITopic eTopic = clonedTopic.getAllChildren().get(i); +// modifyTopicLink(oTopic, eTopic, topicLinkRef, cmds); +// } +// } +// } + +// private List getSiblingTopics(Object[] targets) { +// ITopic start = null; +// ITopic end = null; +// for (Object o : targets) { +// if (o instanceof ITopic) { +// ITopic t = (ITopic) o; +// if (start != null && MindMapUtils.isDescendentOf(start, t)) { +// start = null; +// } +// if (end != null && MindMapUtils.isDescendentOf(end, t)) { +// end = null; +// } +// if (start == null) { +// start = t; +// } else if (t.getParent().equals(start.getParent()) +// && t.getType().equals(start.getType()) +// && t.getIndex() < start.getIndex()) { +// start = t; +// } +// if (end == null) { +// end = t; +// } else if (t.getParent().equals(end.getParent()) +// && t.getType().equals(end.getType()) +// && t.getIndex() > end.getIndex()) { +// end = t; +// } +// } +// } +// if (start == null || end == null) +// return Collections.emptyList(); +// return Arrays.asList(start, end); +// } +// +// private boolean hasBoundary(List topics) { +// if (topics.get(0).isAttached()) { +// int startIndex = topics.get(0).getIndex(); +// int endIndex = topics.get(topics.size() - 1).getIndex(); +// for (IBoundary b : topics.get(0).getParent().getBoundaries()) { +// if (b.getStartIndex() == startIndex +// || b.getEndIndex() == endIndex) +// return true; +// } +// } else if (topics.size() == 1) { +// for (IBoundary b : topics.get(0).getBoundaries()) { +// if (b.isMasterBoundary()) +// return true; +// } +// } +// return false; +// } +// +// protected Object[] getElementsFromClipboard(IViewer viewer, Object target) { +// IDndSupport dndSupport = viewer.getDndSupport(); +// if (dndSupport != null) { +// String[] ids = dndSupport.getDndClientIds(); +// if (ids.length > 0) { +// Clipboard clipboard = new Clipboard(Display.getCurrent()); +// try { +// return getElementsFromClipboard(viewer, target, clipboard, +// dndSupport, ids); +// } finally { +// clipboard.dispose(); +// } +// } +// } +// return null; +// } +// +// protected Object[] getElementsFromClipboard(IViewer viewer, Object target, +// Clipboard clipboard, IDndSupport dndSupport, String[] ids) { +// TransferData[] types = clipboard.getAvailableTypes(); +// IDndClient elementClient = dndSupport +// .getDndClient(DEFAULT_DND_CLIENT_ID); +// if (elementClient != null) { +// Object[] elements = getElementsFromClipboard(viewer, target, +// elementClient, clipboard, types); +// if (elements != null) +// return elements; +// } +// for (String id : ids) { +// if (!DEFAULT_DND_CLIENT_ID.equals(id)) { +// IDndClient client = dndSupport.getDndClient(id); +// Object[] elements = getElementsFromClipboard(viewer, target, +// client, clipboard, types); +// if (elements != null) +// return elements; +// } +// } +// return null; +// } +// +// protected Object[] getElementsFromClipboard(IViewer viewer, Object target, +// IDndClient client, Clipboard clipboard, TransferData[] types) { +// if (client == null) +// return null; +// Transfer transfer = client.getTransfer(); +// if (transfer == null) +// return null; +//// if (transfer instanceof MindMapElementTransfer) { +//// transferMap = ((MindMapElementTransfer) transfer).getTransferMap(); +//// } +// for (TransferData type : types) { +// if (transfer.isSupportedType(type)) { +// Object contents = clipboard.getContents(transfer); +// if (contents != null) +// return client.toViewerElements(contents, viewer, target); +// } +// } +// return null; +// } + + private void replaceAll(Request request) { + String text = (String) request.getParameter(GEF.PARAM_TEXT); + String replacement = (String) request + .getParameter(MindMapUI.PARAM_REPLACEMENT); + if (text == null || replacement == null) + return; + + boolean ignoreCase = Boolean.TRUE + .equals(request.getParameter(MindMapUI.PARAM_IGNORE_CASE)); + List targets = request.getTargets(); + if (targets.isEmpty()) + return; + if (ignoreCase) { + text = text.toLowerCase(); + } + + PropertyCommandBuilder builder = new PropertyCommandBuilder(request); + if (builder.canStart()) { + builder.start(); + + for (IPart target : targets) { + Object model = MindMapUtils.getRealModel(target); + if (model instanceof ITitled) { + ITitled t = (ITitled) model; + String oldText = t.getTitleText(); + if (oldText != null) { + String searchText = ignoreCase ? oldText.toLowerCase() + : oldText; + StringBuilder sb = new StringBuilder( + oldText.length() + replacement.length()); + int start = 0; + int index = searchText.indexOf(text); + while (index >= 0) { + sb.append(oldText.substring(start, index)); + sb.append(replacement); + start = index + text.length(); + index = searchText.indexOf(text, start); + } + if (start < oldText.length()) { + sb.append(oldText.substring(start)); + } + String newText = sb.toString(); + if (!newText.equals(oldText)) { + builder.add(new ModifyTitleTextCommand(t, newText), + true); + } + } + + builder.addSource(t, true); + } + } + + builder.end(); + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MapPolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MapPolicy.java index 556338c02..59ac9d19c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MapPolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MapPolicy.java @@ -1,144 +1,144 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Point; -import org.xmind.core.ILegend; -import org.xmind.core.IPositioned; -import org.xmind.core.ISheet; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IIntersectionSolver; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyLegendVisibilityCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.internal.layouts.SheetIntersectionSolver; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class MapPolicy extends MindMapPolicyBase { - - public boolean understands(String requestType) { - return super.understands(requestType) - || MindMapUI.REQ_SHOW_LEGEND.equals(requestType) - || MindMapUI.REQ_HIDE_LEGEND.equals(requestType) - || MindMapUI.REQ_TILE.equals(requestType); - } - - public void handle(Request request) { - String type = request.getType(); - if (MindMapUI.REQ_SHOW_LEGEND.equals(type)) { - modifyLegendVisibility(request, true); - } else if (MindMapUI.REQ_HIDE_LEGEND.equals(type)) { - modifyLegendVisibility(request, false); - } else if (MindMapUI.REQ_TILE.equals(type)) { - tile(request); - } - } - - private void tile(Request request) { - ISheetPart sheet = getSheetPart(request); - SheetIntersectionSolver intersectionSolver = new SheetIntersectionSolver(); - Point origin = ((IReferencedFigure) sheet.getFigure()).getOrigin(); - intersectionSolver.setOrigin(origin); - intersectionSolver.recordInitPositions(sheet, false); - intersectionSolver.solve(); - Collection keys = intersectionSolver - .getKeys(IIntersectionSolver.CATEGORY_FREE); - List commands = new ArrayList(keys.size()); - for (Object key : keys) { - if (key instanceof IGraphicalPart) { - IGraphicalPart part = (IGraphicalPart) key; - Object o = MindMapUtils.getRealModel(part); - if (o instanceof IPositioned) { - IPositioned p = (IPositioned) o; - Point pos = intersectionSolver.getSolvedPosition(key); - pos = toRelative(pos, origin); - commands.add(new ModifyPositionCommand(p, MindMapUtils - .toModelPosition(pos))); - } - } - } - - if (commands.isEmpty()) - return; - - CompoundCommand cmd = new CompoundCommand(commands); - cmd.setLabel(CommandMessages.Command_Tile); - saveAndRun(cmd, request.getTargetDomain()); - } - - private Point toRelative(Point pos, Point origin) { - Dimension offset = pos.getDifference(origin); - return new Point(offset.width, offset.height); - } - - private ISheetPart getSheetPart(Request request) { - IPart target = request.getPrimaryTarget(); - if (target instanceof ISheetPart) - return (ISheetPart) target; - IViewer viewer = request.getTargetViewer(); - if (viewer instanceof IMindMapViewer) { - return ((IMindMapViewer) viewer).getSheetPart(); - } - return null; - } - - private void modifyLegendVisibility(Request request, boolean visible) { - ILegend legend = getLegend(request); - if (legend == null) - return; - - PropertyCommandBuilder builder = new PropertyCommandBuilder(request); - if (!builder.canStart()) - return; - - builder.start(); - builder.setLabel(visible ? CommandMessages.Command_ShowLegend - : CommandMessages.Command_HideLegend); - builder.add(new ModifyLegendVisibilityCommand(legend, visible), true); - builder.addSource(legend, false); - builder.end(); - } - - private ILegend getLegend(Request request) { - IPart target = request.getPrimaryTarget(); - if (target != null) { - Object m = MindMapUtils.getRealModel(target); - if (m instanceof ISheet) - return ((ISheet) m).getLegend(); - if (m instanceof ILegend) - return (ILegend) m; - } - IViewer viewer = request.getTargetViewer(); - if (viewer instanceof IMindMapViewer) { - ISheet sheet = ((IMindMapViewer) viewer).getSheet(); - if (sheet != null) - return sheet.getLegend(); - } - return null; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.xmind.core.ILegend; +import org.xmind.core.IPositioned; +import org.xmind.core.ISheet; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IIntersectionSolver; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyLegendVisibilityCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.internal.layouts.SheetIntersectionSolver; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class MapPolicy extends MindMapPolicyBase { + + public boolean understands(String requestType) { + return super.understands(requestType) + || MindMapUI.REQ_SHOW_LEGEND.equals(requestType) + || MindMapUI.REQ_HIDE_LEGEND.equals(requestType) + || MindMapUI.REQ_TILE.equals(requestType); + } + + public void handle(Request request) { + String type = request.getType(); + if (MindMapUI.REQ_SHOW_LEGEND.equals(type)) { + modifyLegendVisibility(request, true); + } else if (MindMapUI.REQ_HIDE_LEGEND.equals(type)) { + modifyLegendVisibility(request, false); + } else if (MindMapUI.REQ_TILE.equals(type)) { + tile(request); + } + } + + private void tile(Request request) { + ISheetPart sheet = getSheetPart(request); + SheetIntersectionSolver intersectionSolver = new SheetIntersectionSolver(); + Point origin = ((IReferencedFigure) sheet.getFigure()).getOrigin(); + intersectionSolver.setOrigin(origin); + intersectionSolver.recordInitPositions(sheet, false); + intersectionSolver.solve(); + Collection keys = intersectionSolver + .getKeys(IIntersectionSolver.CATEGORY_FREE); + List commands = new ArrayList(keys.size()); + for (Object key : keys) { + if (key instanceof IGraphicalPart) { + IGraphicalPart part = (IGraphicalPart) key; + Object o = MindMapUtils.getRealModel(part); + if (o instanceof IPositioned) { + IPositioned p = (IPositioned) o; + Point pos = intersectionSolver.getSolvedPosition(key); + pos = toRelative(pos, origin); + commands.add(new ModifyPositionCommand(p, MindMapUtils + .toModelPosition(pos))); + } + } + } + + if (commands.isEmpty()) + return; + + CompoundCommand cmd = new CompoundCommand(commands); + cmd.setLabel(CommandMessages.Command_Tile); + saveAndRun(cmd, request.getTargetDomain()); + } + + private Point toRelative(Point pos, Point origin) { + Dimension offset = pos.getDifference(origin); + return new Point(offset.width, offset.height); + } + + private ISheetPart getSheetPart(Request request) { + IPart target = request.getPrimaryTarget(); + if (target instanceof ISheetPart) + return (ISheetPart) target; + IViewer viewer = request.getTargetViewer(); + if (viewer instanceof IMindMapViewer) { + return ((IMindMapViewer) viewer).getSheetPart(); + } + return null; + } + + private void modifyLegendVisibility(Request request, boolean visible) { + ILegend legend = getLegend(request); + if (legend == null) + return; + + PropertyCommandBuilder builder = new PropertyCommandBuilder(request); + if (!builder.canStart()) + return; + + builder.start(); + builder.setLabel(visible ? CommandMessages.Command_ShowLegend + : CommandMessages.Command_HideLegend); + builder.add(new ModifyLegendVisibilityCommand(legend, visible), true); + builder.addSource(legend, false); + builder.end(); + } + + private ILegend getLegend(Request request) { + IPart target = request.getPrimaryTarget(); + if (target != null) { + Object m = MindMapUtils.getRealModel(target); + if (m instanceof ISheet) + return ((ISheet) m).getLegend(); + if (m instanceof ILegend) + return (ILegend) m; + } + IViewer viewer = request.getTargetViewer(); + if (viewer instanceof IMindMapViewer) { + ISheet sheet = ((IMindMapViewer) viewer).getSheet(); + if (sheet != null) + return sheet.getLegend(); + } + return null; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapNavigablePolicyBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapNavigablePolicyBase.java index 17fb4c07e..44ab5725e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapNavigablePolicyBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapNavigablePolicyBase.java @@ -1,141 +1,141 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.List; - -import org.eclipse.draw2d.FigureListener; -import org.eclipse.draw2d.IFigure; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.policy.NavigablePolicy; -import org.xmind.ui.util.MindMapUtils; - -public abstract class MindMapNavigablePolicyBase extends NavigablePolicy { - - public static final String CACHE_NAV_OUTGOING = "org.xmind.ui.cache.navigation.outgoing."; //$NON-NLS-1$ - - public static final String CACHE_NAV_INCOMING = "org.xmind.ui.cache.navigation.incoming."; //$NON-NLS-1$ - - protected void findNavParts(Request request, String navType, - List sources, List result) { - IPart navPart = findCachedNavigation(sources, invertNavType(navType)); - if (navPart != null) { - result.add(navPart); - setNavCaches(sources, navPart, navType); - return; - } - navPart = findNewNavParts(request, navType, sources); - setNavCaches(sources, navPart, navType); - if (navPart != null) { - result.add(navPart); - return; - } - super.findNavParts(request, navType, sources, result); - } - - protected abstract IPart findNewNavParts(Request request, String navType, - List sources); - - protected String invertNavType(String navType) { - if (GEF.REQ_NAV_UP.equals(navType)) - return GEF.REQ_NAV_DOWN; - if (GEF.REQ_NAV_DOWN.equals(navType)) - return GEF.REQ_NAV_UP; - if (GEF.REQ_NAV_LEFT.equals(navType)) - return GEF.REQ_NAV_RIGHT; - if (GEF.REQ_NAV_RIGHT.equals(navType)) - return GEF.REQ_NAV_LEFT; - return navType; - } - - private String getCacheKey(String navType, boolean inOrOut) { - String prefix = inOrOut ? CACHE_NAV_INCOMING : CACHE_NAV_OUTGOING; - return prefix + navType.replaceAll("\\s", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - protected IPart findCachedNavigation(List sources, String navType) { - for (IPart source : sources) { - IPart navPart = getCachedNavigation(source, navType); - if (navPart != null) - return navPart; - } - return null; - } - - protected IPart getCachedNavigation(IPart source, String navType) { - String inKey = getCacheKey(navType, true); - IPart target = (IPart) MindMapUtils.getCache(source, inKey); - if (target != null) { - if (target.getStatus().isActive() - && target.hasRole(GEF.ROLE_SELECTABLE) - && source == MindMapUtils.getCache(target, getCacheKey( - navType, false))) { - return target; - } - MindMapUtils.flushCache(source, inKey); - } - return null; - } - - protected void setNavCaches(List sources, IPart target, - String navType) { - if (!sources.isEmpty()) { - setNavCache(sources.get(0), target, navType); - } - for (int i = 1; i < sources.size(); i++) { - setNavCache(sources.get(i), null, navType); - } - } - - protected void setNavCache(final IPart source, final IPart target, - String navType) { - final String outKey = getCacheKey(navType, false); - if (target == null || target == source) { - IPart oldTarget = (IPart) MindMapUtils.getCache(source, outKey); - if (oldTarget != null) { - MindMapUtils.flushCache(oldTarget, getCacheKey(navType, true)); - } - MindMapUtils.flushCache(source, outKey); - } else { - MindMapUtils.setCache(source, outKey, target); - if (source instanceof IGraphicalPart) { - ((IGraphicalPart) source).getFigure().addFigureListener( - new FigureListener() { - public void figureMoved(IFigure fig) { - fig.removeFigureListener(this); - MindMapUtils.flushCache(source, outKey); - } - }); - } - } - - if (target != null) { - final String inKey = getCacheKey(navType, true); - MindMapUtils.setCache(target, inKey, source); - if (target instanceof IGraphicalPart) { - ((IGraphicalPart) target).getFigure().addFigureListener( - new FigureListener() { - public void figureMoved(IFigure fig) { - fig.removeFigureListener(this); - MindMapUtils.flushCache(target, inKey); - } - }); - } - } - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.List; + +import org.eclipse.draw2d.FigureListener; +import org.eclipse.draw2d.IFigure; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.policy.NavigablePolicy; +import org.xmind.ui.util.MindMapUtils; + +public abstract class MindMapNavigablePolicyBase extends NavigablePolicy { + + public static final String CACHE_NAV_OUTGOING = "org.xmind.ui.cache.navigation.outgoing."; //$NON-NLS-1$ + + public static final String CACHE_NAV_INCOMING = "org.xmind.ui.cache.navigation.incoming."; //$NON-NLS-1$ + + protected void findNavParts(Request request, String navType, + List sources, List result) { + IPart navPart = findCachedNavigation(sources, invertNavType(navType)); + if (navPart != null) { + result.add(navPart); + setNavCaches(sources, navPart, navType); + return; + } + navPart = findNewNavParts(request, navType, sources); + setNavCaches(sources, navPart, navType); + if (navPart != null) { + result.add(navPart); + return; + } + super.findNavParts(request, navType, sources, result); + } + + protected abstract IPart findNewNavParts(Request request, String navType, + List sources); + + protected String invertNavType(String navType) { + if (GEF.REQ_NAV_UP.equals(navType)) + return GEF.REQ_NAV_DOWN; + if (GEF.REQ_NAV_DOWN.equals(navType)) + return GEF.REQ_NAV_UP; + if (GEF.REQ_NAV_LEFT.equals(navType)) + return GEF.REQ_NAV_RIGHT; + if (GEF.REQ_NAV_RIGHT.equals(navType)) + return GEF.REQ_NAV_LEFT; + return navType; + } + + private String getCacheKey(String navType, boolean inOrOut) { + String prefix = inOrOut ? CACHE_NAV_INCOMING : CACHE_NAV_OUTGOING; + return prefix + navType.replaceAll("\\s", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + protected IPart findCachedNavigation(List sources, String navType) { + for (IPart source : sources) { + IPart navPart = getCachedNavigation(source, navType); + if (navPart != null) + return navPart; + } + return null; + } + + protected IPart getCachedNavigation(IPart source, String navType) { + String inKey = getCacheKey(navType, true); + IPart target = (IPart) MindMapUtils.getCache(source, inKey); + if (target != null) { + if (target.getStatus().isActive() + && target.hasRole(GEF.ROLE_SELECTABLE) + && source == MindMapUtils.getCache(target, getCacheKey( + navType, false))) { + return target; + } + MindMapUtils.flushCache(source, inKey); + } + return null; + } + + protected void setNavCaches(List sources, IPart target, + String navType) { + if (!sources.isEmpty()) { + setNavCache(sources.get(0), target, navType); + } + for (int i = 1; i < sources.size(); i++) { + setNavCache(sources.get(i), null, navType); + } + } + + protected void setNavCache(final IPart source, final IPart target, + String navType) { + final String outKey = getCacheKey(navType, false); + if (target == null || target == source) { + IPart oldTarget = (IPart) MindMapUtils.getCache(source, outKey); + if (oldTarget != null) { + MindMapUtils.flushCache(oldTarget, getCacheKey(navType, true)); + } + MindMapUtils.flushCache(source, outKey); + } else { + MindMapUtils.setCache(source, outKey, target); + if (source instanceof IGraphicalPart) { + ((IGraphicalPart) source).getFigure().addFigureListener( + new FigureListener() { + public void figureMoved(IFigure fig) { + fig.removeFigureListener(this); + MindMapUtils.flushCache(source, outKey); + } + }); + } + } + + if (target != null) { + final String inKey = getCacheKey(navType, true); + MindMapUtils.setCache(target, inKey, source); + if (target instanceof IGraphicalPart) { + ((IGraphicalPart) target).getFigure().addFigureListener( + new FigureListener() { + public void figureMoved(IFigure fig) { + fig.removeFigureListener(this); + MindMapUtils.flushCache(target, inKey); + } + }); + } + } + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapPolicyBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapPolicyBase.java index 6583ff390..3e0e082dc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapPolicyBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/MindMapPolicyBase.java @@ -1,99 +1,99 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.List; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.part.IPart; -import org.xmind.gef.policy.AbstractEditPolicy; -import org.xmind.gef.service.IAnimationService; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public abstract class MindMapPolicyBase extends AbstractEditPolicy { - - protected static final String EMPTY = ""; //$NON-NLS-1$ - - protected IAnimationService getAnimationService(IViewer viewer) { - return (IAnimationService) viewer.getService(IAnimationService.class); - } - - protected void select(Object element, IViewer viewer) { - ISelection selection = element == null ? StructuredSelection.EMPTY - : new StructuredSelection(element); - - viewer.setSelection(selection, true); - } - - protected void select(List elements, IViewer viewer) { - viewer.setSelection(new StructuredSelection(elements), true); - } - - protected void selectPart(IPart part, IViewer viewer) { - select(MindMapUtils.getRealModel(part), viewer); - } - - protected void selectParts(List parts, IViewer viewer) { - select(MindMapUtils.getRealModels(parts), viewer); - } - - protected boolean isAnimationRequired(Request req) { - return req.isParameter(MindMapUI.PARAM_WITH_ANIMATION); - } - - protected boolean isAnimationEnalbed(IViewer viewer) { - return MindMapUI.isAnimationEnabled() - && viewer.hasService(IAnimationService.class); - } - - protected boolean animateCommand(Command cmd, IViewer viewer) { - if (!isAnimationEnalbed(viewer)) - return false; - IAnimationService anim = getAnimationService(viewer); - if (anim == null) - return false; - anim.stop(); - doAnimateCommand(cmd, anim, viewer); - return true; - } - - protected void doAnimateCommand(final Command cmd, IAnimationService anim, - final IViewer viewer) { - Runnable job = new Runnable() { - public void run() { - createAnimation(cmd, viewer); - } - }; - anim.start(job, createBeforeEffect(cmd, viewer), createAfterEffect(cmd, - viewer)); - } - - protected Runnable createBeforeEffect(Command cmd, IViewer viewer) { - return null; - } - - protected Runnable createAfterEffect(Command cmd, IViewer viewer) { - return null; - } - - protected void createAnimation(Command cmd, IViewer viewer) { - saveAndRun(cmd, viewer.getEditDomain()); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.part.IPart; +import org.xmind.gef.policy.AbstractEditPolicy; +import org.xmind.gef.service.IAnimationService; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public abstract class MindMapPolicyBase extends AbstractEditPolicy { + + protected static final String EMPTY = ""; //$NON-NLS-1$ + + protected IAnimationService getAnimationService(IViewer viewer) { + return (IAnimationService) viewer.getService(IAnimationService.class); + } + + protected void select(Object element, IViewer viewer) { + ISelection selection = element == null ? StructuredSelection.EMPTY + : new StructuredSelection(element); + + viewer.setSelection(selection, true); + } + + protected void select(List elements, IViewer viewer) { + viewer.setSelection(new StructuredSelection(elements), true); + } + + protected void selectPart(IPart part, IViewer viewer) { + select(MindMapUtils.getRealModel(part), viewer); + } + + protected void selectParts(List parts, IViewer viewer) { + select(MindMapUtils.getRealModels(parts), viewer); + } + + protected boolean isAnimationRequired(Request req) { + return req.isParameter(MindMapUI.PARAM_WITH_ANIMATION); + } + + protected boolean isAnimationEnalbed(IViewer viewer) { + return MindMapUI.isAnimationEnabled() + && viewer.hasService(IAnimationService.class); + } + + protected boolean animateCommand(Command cmd, IViewer viewer) { + if (!isAnimationEnalbed(viewer)) + return false; + IAnimationService anim = getAnimationService(viewer); + if (anim == null) + return false; + anim.stop(); + doAnimateCommand(cmd, anim, viewer); + return true; + } + + protected void doAnimateCommand(final Command cmd, IAnimationService anim, + final IViewer viewer) { + Runnable job = new Runnable() { + public void run() { + createAnimation(cmd, viewer); + } + }; + anim.start(job, createBeforeEffect(cmd, viewer), createAfterEffect(cmd, + viewer)); + } + + protected Runnable createBeforeEffect(Command cmd, IViewer viewer) { + return null; + } + + protected Runnable createAfterEffect(Command cmd, IViewer viewer) { + return null; + } + + protected void createAnimation(Command cmd, IViewer viewer) { + saveAndRun(cmd, viewer.getEditDomain()); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifiablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifiablePolicy.java index 65d5d5d80..96ee0552e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifiablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifiablePolicy.java @@ -1,587 +1,587 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.runtime.IAdaptable; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.ILabeled; -import org.xmind.core.IPositioned; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicRange; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.core.util.Point; -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyLabelCommand; -import org.xmind.ui.commands.ModifyNumberPrependingCommand; -import org.xmind.ui.commands.ModifyNumberingDepthCommand; -import org.xmind.ui.commands.ModifyNumberingFormatCommand; -import org.xmind.ui.commands.ModifyNumberingPrefixCommand; -import org.xmind.ui.commands.ModifyNumberingSeparatorCommand; -import org.xmind.ui.commands.ModifyNumberingSuffixCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; -import org.xmind.ui.commands.ModifyTopicRangeCommand; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.IMindMapViewer; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.prefs.PrefConstants; -import org.xmind.ui.util.MindMapUtils; - -public class ModifiablePolicy extends MindMapPolicyBase { - -// private static final String NULL = "$NULL$"; //$NON-NLS-1$ -// -// private static final Map EMPTY_CONTENTS = Collections -// .emptyMap(); - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_MODIFY.equals(requestType) - || MindMapUI.REQ_MODIFY_HYPERLINK.equals(requestType) - || MindMapUI.REQ_MODIFY_STYLE.equals(requestType) - || MindMapUI.REQ_MODIFY_LABEL.equals(requestType) - || MindMapUI.REQ_MODIFY_RANGE.equals(requestType) - || MindMapUI.REQ_MODIFY_NUMBERING.equals(requestType) - || MindMapUI.REQ_RESET_POSITION.equals(requestType) - || MindMapUI.REQ_MODIFY_THEME.equals(requestType) - || MindMapUI.REQ_REMOVE_ALLSTYLES.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (GEF.REQ_MODIFY.equals(reqType)) { - modifyText(request); - } else if (MindMapUI.REQ_MODIFY_HYPERLINK.equals(reqType)) { - modifyHyperlink(request); - } else if (MindMapUI.REQ_MODIFY_STYLE.equals(reqType)) { - modifyStyle(request); - } else if (MindMapUI.REQ_MODIFY_RANGE.equals(reqType)) { - modifyRange(request); - } else if (MindMapUI.REQ_MODIFY_LABEL.equals(reqType)) { - modifyLabel(request); - } else if (MindMapUI.REQ_MODIFY_NUMBERING.equals(reqType)) { - modifyNumbering(request); - } else if (MindMapUI.REQ_RESET_POSITION.equals(reqType)) { - resetPosition(request); - } else if (MindMapUI.REQ_MODIFY_THEME.equals(reqType)) { - modifyTheme(request); - } else if (MindMapUI.REQ_REMOVE_ALLSTYLES.equals(reqType)) { - removeAllStyles(request); - } - } - - private void removeAllStyles(Request request) { - ModifyStyleCommandBuilder builder = new ModifyStyleCommandBuilder( - request); - String commandLabel = (String) request - .getParameter(MindMapUI.PARAM_COMMAND_LABEL); - if (commandLabel == null) - commandLabel = CommandMessages.Command_RemoveStyle; - builder.setLabel(commandLabel); - - if (!builder.canStart()) - return; - - builder.start(); - List sources = getAllSources(request); - for (IStyled source : sources) - builder.removeStyle(source); - builder.end(); - } - - private List getAllSources(Request request) { - List sources = new ArrayList(); - ISheet sheet = (ISheet) request.getTargetViewer() - .getAdapter(ISheet.class); - if (sheet == null) - return sources; - - if (sheet.getStyleId() != null) - sources.add(sheet); - - List topics = MindMapUtils.getAllTopics(sheet, true, true); - - for (ITopic topic : topics) { - if (topic.getStyleId() != null) - sources.add(topic); - - Set boundaries = topic.getBoundaries(); - for (IBoundary boundary : boundaries) { - if (boundary.getStyleId() != null) - sources.add(boundary); - } - - Set summaries = topic.getSummaries(); - for (ISummary summary : summaries) { - if (summary.getStyleId() != null) - sources.add(summary); - } - } - - Set relationships = sheet.getRelationships(); - for (IRelationship relationship : relationships) { - if (relationship.getStyleId() != null) - sources.add(relationship); - } - - return sources; - } - - private void modifyTheme(Request request) { - IPart target = request.getPrimaryTarget(); - if (!(target instanceof ISheetPart)) - return; - - if (!request.hasParameter(MindMapUI.PARAM_RESOURCE)) - return; - - ISheetPart sheetPart = (ISheetPart) target; - ISheet sheet = sheetPart.getSheet(); - Object param = request.getParameter(MindMapUI.PARAM_RESOURCE); - IStyle theme = (IStyle) param; - ModifyThemeCommandBuilder builder = new ModifyThemeCommandBuilder( - request.getTargetViewer(), request.getTargetCommandStack(), - theme); - builder.setLabel(CommandMessages.Command_ModifyTheme); - if (!builder.canStart()) - return; - - builder.start(); - - Object override = request.getParameter(MindMapUI.PARAM_OVERRIDE); - if (PrefConstants.THEME_OVERRIDE.equals(override)) { - List sources = getAllSources(request); - for (IStyled source : sources) - builder.removeStyle(source); - } - - builder.modify(sheet); - builder.end(); - } - - private void resetPosition(Request request) { - - List positionOwners = new ArrayList(); - - List rels = new ArrayList(); - IPart target = request.getPrimaryTarget(); - - if (target == null || target instanceof ISheetPart) { - ISheetPart sheet; - if (target == null) { - sheet = ((IMindMapViewer) request.getTargetViewer()) - .getSheetPart(); - } else { - sheet = (ISheetPart) target; - } - if (sheet != null) { - IBranchPart centralBranch = sheet.getCentralBranch(); - if (centralBranch != null - && MindMapUtils.isSubBranchesFreeable(centralBranch)) { - for (IBranchPart main : centralBranch.getSubBranches()) { - if (MindMapUtils.isBranchFreeable(main)) { - positionOwners.add(main.getTopic()); - } - } - } - } - } else { - List targets = request.getTargets(); - for (IPart p : targets) { - Object o = MindMapUtils.getRealModel(p); - if (o instanceof IPositioned) { - IPositioned positionOwner = (IPositioned) o; - Point position = positionOwner.getPosition(); - if (position != null) -// if (positionOwner.getPosition() != null) - positionOwners.add(positionOwner); - } else if (o instanceof IRelationship) { - rels.add((IRelationship) o); - } - } - } - - if (positionOwners.isEmpty() && rels.isEmpty()) - return; - - List commands = new ArrayList( - positionOwners.size() + rels.size() * 2); - - for (IPositioned p : positionOwners) { - if (!(p instanceof ITopic && !((ITopic) p).isAttached())) { - commands.add(new ModifyPositionCommand(p, null)); - } - } - for (IRelationship r : rels) { - commands.add(new ModifyPositionCommand(r.getControlPoint(0), null)); - commands.add(new ModifyPositionCommand(r.getControlPoint(1), null)); -// commands.add(new ResetRelationshipControlPointCommand(r, 0)); -// commands.add(new ResetRelationshipControlPointCommand(r, 1)); - } - if (commands.isEmpty()) - return; - - CompoundCommand cmd = new CompoundCommand(commands); - cmd.setLabel(CommandMessages.Command_ResetPosition); - saveAndRun(cmd, request.getTargetDomain()); - } - - private void modifyNumbering(Request request) { - List targets = request.getTargets(); - List topics = new ArrayList(targets.size()); - for (IPart p : targets) { - Object o = MindMapUtils.getRealModel(p); - if (o instanceof ITopic) { - ITopic t = ((ITopic) o).getParent(); - if (t == null) - t = (ITopic) o; - if (!topics.contains(t)) { - topics.add(t); - } - } - } - if (topics.isEmpty()) - return; - - List commands = new ArrayList(4); - - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_FORMAT)) { - String newFormat = (String) request - .getParameter(MindMapUI.PARAM_NUMBERING_FORMAT); - commands.add(new ModifyNumberingFormatCommand(topics, newFormat)); - } - - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR)) { - String newSeparator = (String) request - .getParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR); - commands.add( - new ModifyNumberingSeparatorCommand(topics, newSeparator)); - } - - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_PREFIX)) { - String newPrefix = (String) request - .getParameter(MindMapUI.PARAM_NUMBERING_PREFIX); - commands.add(new ModifyNumberingPrefixCommand(topics, newPrefix)); - } - - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_SUFFIX)) { - String newSuffix = (String) request - .getParameter(MindMapUI.PARAM_NUMBERING_SUFFIX); - commands.add(new ModifyNumberingSuffixCommand(topics, newSuffix)); - } - - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_PREPENDING)) { - Boolean newPrepending = (Boolean) request - .getParameter(MindMapUI.PARAM_NUMBERING_PREPENDING); - commands.add( - new ModifyNumberPrependingCommand(topics, newPrepending)); - } - if (request.hasParameter(MindMapUI.PARAM_NUMBERING_DEPTH)) { - String newDepth = (String) request - .getParameter(MindMapUI.PARAM_NUMBERING_DEPTH); - commands.add(new ModifyNumberingDepthCommand(topics, newDepth)); - } - - if (commands.isEmpty()) - return; - - CompoundCommand cmd = new CompoundCommand(commands); - cmd.setLabel(CommandMessages.Command_ModifyNumbering); - saveAndRun(cmd, request.getTargetDomain()); - } - - private void modifyLabel(Request request) { - if (!request.hasParameter(GEF.PARAM_TEXT)) - return; - - String text = (String) request.getParameter(GEF.PARAM_TEXT); - if (text == null) - text = EMPTY; - - Collection labels = MindMapUtils.getLabels(text); - List sources = request.getTargets(); - List cmds = new ArrayList(sources.size()); - for (IPart p : sources) { - Object o = MindMapUtils.getRealModel(p); - if (o instanceof ILabeled) { - cmds.add(new ModifyLabelCommand((ILabeled) o, labels)); - } - } - if (cmds.isEmpty()) - return; - - CompoundCommand cmd = new CompoundCommand(cmds); - cmd.setLabel(CommandMessages.Command_ModifyLabels); - saveAndRun(cmd, request.getTargetDomain()); - select(cmd.getSources(), request.getTargetViewer()); - } - - private void modifyRange(Request request) { - IPart target = request.getPrimaryTarget(); - ITopicRange targetRange = (ITopicRange) target - .getAdapter(ITopicRange.class); - if (targetRange == null) - return; - - Object param = request.getParameter(MindMapUI.PARAM_RANGE); - if (param == null || !(param instanceof Object[])) - return; - - Object[] newRange = (Object[]) param; - if (newRange.length == 0) - return; - - List topics = new ArrayList(newRange.length); - ITopic parent = null; - for (Object o : newRange) { - ITopic t = findTopic(o); - if (t != null && !topics.contains(t)) { - ITopic p = t.getParent(); - if (p != null) { - if (parent == null) { - parent = p; - topics.add(t); - } else if (parent == p) { - topics.add(t); - } - } - } - } - if (topics.isEmpty()) - return; - - Collections.sort(topics, Core.getTopicComparator()); - - ITopic t1 = topics.get(0); - ITopic t2 = topics.get(topics.size() - 1); - int index1 = t1.getIndex(); - int index2 = t2.getIndex(); - - Collection existingRanges = getExistingRanges( - parent, targetRange); - if (existingRanges == null) - return; - - for (ITopicRange r : existingRanges) { - int start = r.getStartIndex(); - int end = r.getEndIndex(); - if (start == index1 && end == index2) - return; - } - - ModifyTopicRangeCommand cmd = new ModifyTopicRangeCommand(targetRange, - t1, t2); - cmd.setLabel(getModifyRangeLabel(targetRange, topics)); - saveAndRun(cmd, request.getTargetDomain()); - select(cmd.getSources(), request.getTargetViewer()); - } - - private Collection getExistingRanges(ITopic parent, - ITopicRange source) { - if (source instanceof IBoundary) - return parent.getBoundaries(); - if (source instanceof ISummary) - return parent.getSummaries(); - return null; - } - - private String getModifyRangeLabel(ITopicRange rangeModel, - List topics) { - if (rangeModel instanceof IBoundary) - return CommandMessages.Command_ModifyBoundaryRange; - if (rangeModel instanceof ISummary) - return CommandMessages.Command_ModifySummaryRange; - return CommandMessages.Command_ModifyRange; - } - - private ITopic findTopic(Object o) { - if (o instanceof ITopic) - return (ITopic) o; - if (o instanceof IPart) { - Object model = MindMapUtils.getRealModel((IPart) o); - if (model instanceof ITopic) - return (ITopic) model; - } - if (o instanceof IAdaptable) { - return (ITopic) ((IAdaptable) o).getAdapter(ITopic.class); - } - return null; - } - - private void modifyStyle(Request request) { - ModifyStyleCommandBuilder builder = new ModifyStyleCommandBuilder( - request); - String commandLabel = (String) request - .getParameter(MindMapUI.PARAM_COMMAND_LABEL); - if (commandLabel == null) - commandLabel = CommandMessages.Command_ModifyStyle; - builder.setLabel(commandLabel); - - if (!builder.canStart()) - return; - - builder.start(); - List targets = request.getTargets(); - for (IPart target : targets) { - IStyled source = getStyleSource(target); - if (source != null) { - builder.modify(source); - } - } - builder.end(); - } - - private IStyled getStyleSource(IPart part) { - IStyled s = (IStyled) part.getAdapter(IStyled.class); - if (s != null) - return s; - Object m = MindMapUtils.getRealModel(part); - return m instanceof IStyled ? (IStyled) m : null; - } - - private void modifyHyperlink(Request request) { - String hyperlink = (String) request.getParameter(GEF.PARAM_TEXT); - List topics = MindMapUtils.getTopics(request.getTargets()); - if (topics.isEmpty()) - return; - -// modifyHyperlinkRef(topics, hyperlink, request); - - ModifyTopicHyperlinkCommand cmd = new ModifyTopicHyperlinkCommand( - topics, hyperlink); - cmd.setLabel(CommandMessages.Command_ModifyTopicHyperlink); - saveAndRun(cmd, request.getTargetDomain()); - } - -// private void modifyHyperlinkRef(List topics, String newHref, -// Request request) { -// String newTargetId = null; -// if (newHref != null && newHref.startsWith("xmind:#")) //$NON-NLS-1$ -// newTargetId = newHref.substring(7); -// -// ModifyTopicLinkCommand command = new ModifyTopicLinkCommand(topics, -// newTargetId); -// saveAndRun(command, request.getTargetDomain()); -// } - -// private void modifyHyperlinkRef(List topics, String newHref, -// Request request) { -//// ITopicHyperlinkRef topicLinkRef = null; -// for (ITopic topic : topics) { -//// if (topicLinkRef == null) { -//// IWorkbook workbook = topic.getOwnedWorkbook(); -//// topicLinkRef = (ITopicHyperlinkRef) workbook -//// .getAdapter(ITopicHyperlinkRef.class); -//// } -// modifyTopicLinkRef(topic, newHref, request); -// } -// } - -// private void modifyTopicLinkRef(ITopic topic, String newHref, -// Request request) { -// String oldHref = topic.getHyperlink(); -// -// String oldTargetId = null; -// if (oldHref != null && oldHref.startsWith("xmind:#")) //$NON-NLS-1$ -// oldTargetId = oldHref.substring(7); -// -// String newTargetId = null; -// if (newHref != null && newHref.startsWith("xmind:#")) //$NON-NLS-1$ -// newTargetId = newHref.substring(7); -//// -//// topicLinkRef.modifyTopicLinks(oldTargetId, newTargetId, topic.getId()); -// //TODO: -// -// ModifyTopicLinkCommand command = new ModifyTopicLinkCommand(topic, -// newTargetId); -// saveAndRun(command, request.getTargetDomain()); -// } - - private void modifyText(Request request) { - if (!request.hasParameter(GEF.PARAM_TEXT)) - return; - - String text = (String) request.getParameter(GEF.PARAM_TEXT); - if (text == null) - text = EMPTY; - - List targets = request.getTargets(); - if (targets.isEmpty()) - return; - - List ts = new ArrayList(targets.size()); - for (IPart p : targets) { - Object m = MindMapUtils.getRealModel(p); - if (m instanceof ITitled && !ts.contains(m)) { - ts.add((ITitled) m); - } - } - - if (ts.isEmpty()) - return; - - PropertyCommandBuilder builder = new PropertyCommandBuilder(request); - builder.setLabel(getModifyTitleTextLabel(ts)); - builder.start(); - builder.add(new ModifyTitleTextCommand(ts, text), true); - builder.addSourcesFromRequest(false); - ITitled titled = ts.get(0); - if (titled instanceof ITopic) { - ITopic topic = (ITopic) titled; - String hyperlink = topic.getHyperlink(); - if (hyperlink == null || hyperlink.isEmpty()) { - if (HyperlinkUtils.isUrlAddress(text)) { - hyperlink = text; - } else if (HyperlinkUtils.isEmailAddress(text)) { - hyperlink = "mailto:" + text; //$NON-NLS-1$ - } - builder.add(new ModifyTopicHyperlinkCommand(topic, hyperlink), - true); - } - } - builder.end(); - } - - private String getModifyTitleTextLabel(List ts) { - Object t = ts.get(0); - if (t instanceof ITopic) { - return CommandMessages.Command_ModifyTopicTitle; - } else if (t instanceof ISheet) { - return CommandMessages.Command_ModifySheetTitle; - } else if (t instanceof IRelationship) { - return CommandMessages.Command_ModifyRelationshipTitle; - } else if (t instanceof IBoundary) { - return CommandMessages.Command_ModifyBoundaryTitle; - } - return CommandMessages.Command_ModifyTitle; - } - -} +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.IAdaptable; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.ILabeled; +import org.xmind.core.IPositioned; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicRange; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.core.util.Point; +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyLabelCommand; +import org.xmind.ui.commands.ModifyNumberPrependingCommand; +import org.xmind.ui.commands.ModifyNumberingDepthCommand; +import org.xmind.ui.commands.ModifyNumberingFormatCommand; +import org.xmind.ui.commands.ModifyNumberingPrefixCommand; +import org.xmind.ui.commands.ModifyNumberingSeparatorCommand; +import org.xmind.ui.commands.ModifyNumberingSuffixCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; +import org.xmind.ui.commands.ModifyTopicRangeCommand; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.IMindMapViewer; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.util.MindMapUtils; + +public class ModifiablePolicy extends MindMapPolicyBase { + +// private static final String NULL = "$NULL$"; //$NON-NLS-1$ +// +// private static final Map EMPTY_CONTENTS = Collections +// .emptyMap(); + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_MODIFY.equals(requestType) + || MindMapUI.REQ_MODIFY_HYPERLINK.equals(requestType) + || MindMapUI.REQ_MODIFY_STYLE.equals(requestType) + || MindMapUI.REQ_MODIFY_LABEL.equals(requestType) + || MindMapUI.REQ_MODIFY_RANGE.equals(requestType) + || MindMapUI.REQ_MODIFY_NUMBERING.equals(requestType) + || MindMapUI.REQ_RESET_POSITION.equals(requestType) + || MindMapUI.REQ_MODIFY_THEME.equals(requestType) + || MindMapUI.REQ_REMOVE_ALLSTYLES.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (GEF.REQ_MODIFY.equals(reqType)) { + modifyText(request); + } else if (MindMapUI.REQ_MODIFY_HYPERLINK.equals(reqType)) { + modifyHyperlink(request); + } else if (MindMapUI.REQ_MODIFY_STYLE.equals(reqType)) { + modifyStyle(request); + } else if (MindMapUI.REQ_MODIFY_RANGE.equals(reqType)) { + modifyRange(request); + } else if (MindMapUI.REQ_MODIFY_LABEL.equals(reqType)) { + modifyLabel(request); + } else if (MindMapUI.REQ_MODIFY_NUMBERING.equals(reqType)) { + modifyNumbering(request); + } else if (MindMapUI.REQ_RESET_POSITION.equals(reqType)) { + resetPosition(request); + } else if (MindMapUI.REQ_MODIFY_THEME.equals(reqType)) { + modifyTheme(request); + } else if (MindMapUI.REQ_REMOVE_ALLSTYLES.equals(reqType)) { + removeAllStyles(request); + } + } + + private void removeAllStyles(Request request) { + ModifyStyleCommandBuilder builder = new ModifyStyleCommandBuilder( + request); + String commandLabel = (String) request + .getParameter(MindMapUI.PARAM_COMMAND_LABEL); + if (commandLabel == null) + commandLabel = CommandMessages.Command_RemoveStyle; + builder.setLabel(commandLabel); + + if (!builder.canStart()) + return; + + builder.start(); + List sources = getAllSources(request); + for (IStyled source : sources) + builder.removeStyle(source); + builder.end(); + } + + private List getAllSources(Request request) { + List sources = new ArrayList(); + ISheet sheet = (ISheet) request.getTargetViewer() + .getAdapter(ISheet.class); + if (sheet == null) + return sources; + + if (sheet.getStyleId() != null) + sources.add(sheet); + + List topics = MindMapUtils.getAllTopics(sheet, true, true); + + for (ITopic topic : topics) { + if (topic.getStyleId() != null) + sources.add(topic); + + Set boundaries = topic.getBoundaries(); + for (IBoundary boundary : boundaries) { + if (boundary.getStyleId() != null) + sources.add(boundary); + } + + Set summaries = topic.getSummaries(); + for (ISummary summary : summaries) { + if (summary.getStyleId() != null) + sources.add(summary); + } + } + + Set relationships = sheet.getRelationships(); + for (IRelationship relationship : relationships) { + if (relationship.getStyleId() != null) + sources.add(relationship); + } + + return sources; + } + + private void modifyTheme(Request request) { + IPart target = request.getPrimaryTarget(); + if (!(target instanceof ISheetPart)) + return; + + if (!request.hasParameter(MindMapUI.PARAM_RESOURCE)) + return; + + ISheetPart sheetPart = (ISheetPart) target; + ISheet sheet = sheetPart.getSheet(); + Object param = request.getParameter(MindMapUI.PARAM_RESOURCE); + IStyle theme = (IStyle) param; + ModifyThemeCommandBuilder builder = new ModifyThemeCommandBuilder( + request.getTargetViewer(), request.getTargetCommandStack(), + theme); + builder.setLabel(CommandMessages.Command_ModifyTheme); + if (!builder.canStart()) + return; + + builder.start(); + + Object override = request.getParameter(MindMapUI.PARAM_OVERRIDE); + if (PrefConstants.THEME_OVERRIDE.equals(override)) { + List sources = getAllSources(request); + for (IStyled source : sources) + builder.removeStyle(source); + } + + builder.modify(sheet); + builder.end(); + } + + private void resetPosition(Request request) { + + List positionOwners = new ArrayList(); + + List rels = new ArrayList(); + IPart target = request.getPrimaryTarget(); + + if (target == null || target instanceof ISheetPart) { + ISheetPart sheet; + if (target == null) { + sheet = ((IMindMapViewer) request.getTargetViewer()) + .getSheetPart(); + } else { + sheet = (ISheetPart) target; + } + if (sheet != null) { + IBranchPart centralBranch = sheet.getCentralBranch(); + if (centralBranch != null + && MindMapUtils.isSubBranchesFreeable(centralBranch)) { + for (IBranchPart main : centralBranch.getSubBranches()) { + if (MindMapUtils.isBranchFreeable(main)) { + positionOwners.add(main.getTopic()); + } + } + } + } + } else { + List targets = request.getTargets(); + for (IPart p : targets) { + Object o = MindMapUtils.getRealModel(p); + if (o instanceof IPositioned) { + IPositioned positionOwner = (IPositioned) o; + Point position = positionOwner.getPosition(); + if (position != null) +// if (positionOwner.getPosition() != null) + positionOwners.add(positionOwner); + } else if (o instanceof IRelationship) { + rels.add((IRelationship) o); + } + } + } + + if (positionOwners.isEmpty() && rels.isEmpty()) + return; + + List commands = new ArrayList( + positionOwners.size() + rels.size() * 2); + + for (IPositioned p : positionOwners) { + if (!(p instanceof ITopic && !((ITopic) p).isAttached())) { + commands.add(new ModifyPositionCommand(p, null)); + } + } + for (IRelationship r : rels) { + commands.add(new ModifyPositionCommand(r.getControlPoint(0), null)); + commands.add(new ModifyPositionCommand(r.getControlPoint(1), null)); +// commands.add(new ResetRelationshipControlPointCommand(r, 0)); +// commands.add(new ResetRelationshipControlPointCommand(r, 1)); + } + if (commands.isEmpty()) + return; + + CompoundCommand cmd = new CompoundCommand(commands); + cmd.setLabel(CommandMessages.Command_ResetPosition); + saveAndRun(cmd, request.getTargetDomain()); + } + + private void modifyNumbering(Request request) { + List targets = request.getTargets(); + List topics = new ArrayList(targets.size()); + for (IPart p : targets) { + Object o = MindMapUtils.getRealModel(p); + if (o instanceof ITopic) { + ITopic t = ((ITopic) o).getParent(); + if (t == null) + t = (ITopic) o; + if (!topics.contains(t)) { + topics.add(t); + } + } + } + if (topics.isEmpty()) + return; + + List commands = new ArrayList(4); + + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_FORMAT)) { + String newFormat = (String) request + .getParameter(MindMapUI.PARAM_NUMBERING_FORMAT); + commands.add(new ModifyNumberingFormatCommand(topics, newFormat)); + } + + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR)) { + String newSeparator = (String) request + .getParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR); + commands.add( + new ModifyNumberingSeparatorCommand(topics, newSeparator)); + } + + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_PREFIX)) { + String newPrefix = (String) request + .getParameter(MindMapUI.PARAM_NUMBERING_PREFIX); + commands.add(new ModifyNumberingPrefixCommand(topics, newPrefix)); + } + + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_SUFFIX)) { + String newSuffix = (String) request + .getParameter(MindMapUI.PARAM_NUMBERING_SUFFIX); + commands.add(new ModifyNumberingSuffixCommand(topics, newSuffix)); + } + + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_PREPENDING)) { + Boolean newPrepending = (Boolean) request + .getParameter(MindMapUI.PARAM_NUMBERING_PREPENDING); + commands.add( + new ModifyNumberPrependingCommand(topics, newPrepending)); + } + if (request.hasParameter(MindMapUI.PARAM_NUMBERING_DEPTH)) { + String newDepth = (String) request + .getParameter(MindMapUI.PARAM_NUMBERING_DEPTH); + commands.add(new ModifyNumberingDepthCommand(topics, newDepth)); + } + + if (commands.isEmpty()) + return; + + CompoundCommand cmd = new CompoundCommand(commands); + cmd.setLabel(CommandMessages.Command_ModifyNumbering); + saveAndRun(cmd, request.getTargetDomain()); + } + + private void modifyLabel(Request request) { + if (!request.hasParameter(GEF.PARAM_TEXT)) + return; + + String text = (String) request.getParameter(GEF.PARAM_TEXT); + if (text == null) + text = EMPTY; + + Collection labels = MindMapUtils.getLabels(text); + List sources = request.getTargets(); + List cmds = new ArrayList(sources.size()); + for (IPart p : sources) { + Object o = MindMapUtils.getRealModel(p); + if (o instanceof ILabeled) { + cmds.add(new ModifyLabelCommand((ILabeled) o, labels)); + } + } + if (cmds.isEmpty()) + return; + + CompoundCommand cmd = new CompoundCommand(cmds); + cmd.setLabel(CommandMessages.Command_ModifyLabels); + saveAndRun(cmd, request.getTargetDomain()); + select(cmd.getSources(), request.getTargetViewer()); + } + + private void modifyRange(Request request) { + IPart target = request.getPrimaryTarget(); + ITopicRange targetRange = (ITopicRange) target + .getAdapter(ITopicRange.class); + if (targetRange == null) + return; + + Object param = request.getParameter(MindMapUI.PARAM_RANGE); + if (param == null || !(param instanceof Object[])) + return; + + Object[] newRange = (Object[]) param; + if (newRange.length == 0) + return; + + List topics = new ArrayList(newRange.length); + ITopic parent = null; + for (Object o : newRange) { + ITopic t = findTopic(o); + if (t != null && !topics.contains(t)) { + ITopic p = t.getParent(); + if (p != null) { + if (parent == null) { + parent = p; + topics.add(t); + } else if (parent == p) { + topics.add(t); + } + } + } + } + if (topics.isEmpty()) + return; + + Collections.sort(topics, Core.getTopicComparator()); + + ITopic t1 = topics.get(0); + ITopic t2 = topics.get(topics.size() - 1); + int index1 = t1.getIndex(); + int index2 = t2.getIndex(); + + Collection existingRanges = getExistingRanges( + parent, targetRange); + if (existingRanges == null) + return; + + for (ITopicRange r : existingRanges) { + int start = r.getStartIndex(); + int end = r.getEndIndex(); + if (start == index1 && end == index2) + return; + } + + ModifyTopicRangeCommand cmd = new ModifyTopicRangeCommand(targetRange, + t1, t2); + cmd.setLabel(getModifyRangeLabel(targetRange, topics)); + saveAndRun(cmd, request.getTargetDomain()); + select(cmd.getSources(), request.getTargetViewer()); + } + + private Collection getExistingRanges(ITopic parent, + ITopicRange source) { + if (source instanceof IBoundary) + return parent.getBoundaries(); + if (source instanceof ISummary) + return parent.getSummaries(); + return null; + } + + private String getModifyRangeLabel(ITopicRange rangeModel, + List topics) { + if (rangeModel instanceof IBoundary) + return CommandMessages.Command_ModifyBoundaryRange; + if (rangeModel instanceof ISummary) + return CommandMessages.Command_ModifySummaryRange; + return CommandMessages.Command_ModifyRange; + } + + private ITopic findTopic(Object o) { + if (o instanceof ITopic) + return (ITopic) o; + if (o instanceof IPart) { + Object model = MindMapUtils.getRealModel((IPart) o); + if (model instanceof ITopic) + return (ITopic) model; + } + if (o instanceof IAdaptable) { + return (ITopic) ((IAdaptable) o).getAdapter(ITopic.class); + } + return null; + } + + private void modifyStyle(Request request) { + ModifyStyleCommandBuilder builder = new ModifyStyleCommandBuilder( + request); + String commandLabel = (String) request + .getParameter(MindMapUI.PARAM_COMMAND_LABEL); + if (commandLabel == null) + commandLabel = CommandMessages.Command_ModifyStyle; + builder.setLabel(commandLabel); + + if (!builder.canStart()) + return; + + builder.start(); + List targets = request.getTargets(); + for (IPart target : targets) { + IStyled source = getStyleSource(target); + if (source != null) { + builder.modify(source); + } + } + builder.end(); + } + + private IStyled getStyleSource(IPart part) { + IStyled s = (IStyled) part.getAdapter(IStyled.class); + if (s != null) + return s; + Object m = MindMapUtils.getRealModel(part); + return m instanceof IStyled ? (IStyled) m : null; + } + + private void modifyHyperlink(Request request) { + String hyperlink = (String) request.getParameter(GEF.PARAM_TEXT); + List topics = MindMapUtils.getTopics(request.getTargets()); + if (topics.isEmpty()) + return; + +// modifyHyperlinkRef(topics, hyperlink, request); + + ModifyTopicHyperlinkCommand cmd = new ModifyTopicHyperlinkCommand( + topics, hyperlink); + cmd.setLabel(CommandMessages.Command_ModifyTopicHyperlink); + saveAndRun(cmd, request.getTargetDomain()); + } + +// private void modifyHyperlinkRef(List topics, String newHref, +// Request request) { +// String newTargetId = null; +// if (newHref != null && newHref.startsWith("xmind:#")) //$NON-NLS-1$ +// newTargetId = newHref.substring(7); +// +// ModifyTopicLinkCommand command = new ModifyTopicLinkCommand(topics, +// newTargetId); +// saveAndRun(command, request.getTargetDomain()); +// } + +// private void modifyHyperlinkRef(List topics, String newHref, +// Request request) { +//// ITopicHyperlinkRef topicLinkRef = null; +// for (ITopic topic : topics) { +//// if (topicLinkRef == null) { +//// IWorkbook workbook = topic.getOwnedWorkbook(); +//// topicLinkRef = (ITopicHyperlinkRef) workbook +//// .getAdapter(ITopicHyperlinkRef.class); +//// } +// modifyTopicLinkRef(topic, newHref, request); +// } +// } + +// private void modifyTopicLinkRef(ITopic topic, String newHref, +// Request request) { +// String oldHref = topic.getHyperlink(); +// +// String oldTargetId = null; +// if (oldHref != null && oldHref.startsWith("xmind:#")) //$NON-NLS-1$ +// oldTargetId = oldHref.substring(7); +// +// String newTargetId = null; +// if (newHref != null && newHref.startsWith("xmind:#")) //$NON-NLS-1$ +// newTargetId = newHref.substring(7); +//// +//// topicLinkRef.modifyTopicLinks(oldTargetId, newTargetId, topic.getId()); +// //TODO: +// +// ModifyTopicLinkCommand command = new ModifyTopicLinkCommand(topic, +// newTargetId); +// saveAndRun(command, request.getTargetDomain()); +// } + + private void modifyText(Request request) { + if (!request.hasParameter(GEF.PARAM_TEXT)) + return; + + String text = (String) request.getParameter(GEF.PARAM_TEXT); + if (text == null) + text = EMPTY; + + List targets = request.getTargets(); + if (targets.isEmpty()) + return; + + List ts = new ArrayList(targets.size()); + for (IPart p : targets) { + Object m = MindMapUtils.getRealModel(p); + if (m instanceof ITitled && !ts.contains(m)) { + ts.add((ITitled) m); + } + } + + if (ts.isEmpty()) + return; + + PropertyCommandBuilder builder = new PropertyCommandBuilder(request); + builder.setLabel(getModifyTitleTextLabel(ts)); + builder.start(); + builder.add(new ModifyTitleTextCommand(ts, text), true); + builder.addSourcesFromRequest(false); + ITitled titled = ts.get(0); + if (titled instanceof ITopic) { + ITopic topic = (ITopic) titled; + String hyperlink = topic.getHyperlink(); + if (hyperlink == null || hyperlink.isEmpty()) { + if (HyperlinkUtils.isUrlAddress(text)) { + hyperlink = text; + } else if (HyperlinkUtils.isEmailAddress(text)) { + hyperlink = "mailto:" + text; //$NON-NLS-1$ + } + builder.add(new ModifyTopicHyperlinkCommand(topic, hyperlink), + true); + } + } + builder.end(); + } + + private String getModifyTitleTextLabel(List ts) { + Object t = ts.get(0); + if (t instanceof ITopic) { + return CommandMessages.Command_ModifyTopicTitle; + } else if (t instanceof ISheet) { + return CommandMessages.Command_ModifySheetTitle; + } else if (t instanceof IRelationship) { + return CommandMessages.Command_ModifyRelationshipTitle; + } else if (t instanceof IBoundary) { + return CommandMessages.Command_ModifyBoundaryTitle; + } + return CommandMessages.Command_ModifyTitle; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyStyleCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyStyleCommandBuilder.java index d5e2ee0cc..a5a8d6435 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyStyleCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyStyleCommandBuilder.java @@ -1,315 +1,315 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; - -import org.xmind.core.IFileEntry; -import org.xmind.core.IWorkbook; -import org.xmind.core.IWorkbookComponent; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.core.util.Property; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.ModifyStyleCommand; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.Styles; - -public class ModifyStyleCommandBuilder extends CommandBuilder { - - private static final String NULL = "$NULL$"; //$NON-NLS-1$ - - private Request request; - - private IStyle sourceStyle; - - private Map idCache = null; - - private Map propertiesCache = new HashMap(); - - private List sources = new ArrayList(); - - public ModifyStyleCommandBuilder(Request request) { - this(request.getTargetViewer(), request.getTargetDomain() - .getCommandStack(), request); - } - - public ModifyStyleCommandBuilder(IViewer viewer, CommandBuilder delegate, - Request request) { - super(viewer, delegate); - init(request); - } - - public ModifyStyleCommandBuilder(IViewer viewer, - ICommandStack commandStack, Request request) { - super(viewer, commandStack); - init(request); - } - - private void init(Request request) { - this.request = request; - Object resource = request.getParameter(MindMapUI.PARAM_RESOURCE); - this.sourceStyle = (resource instanceof IStyle) ? (IStyle) resource - : null; - } - - public List getModifiedSources() { - return sources; - } - - public boolean isSourceModified(IStyled source) { - return sources.contains(source); - } - - public void modify(IStyled source) { - if (isSourceModified(source)) - return; - - String sourceType = getStyleType(source); - if (sourceType == null) - return; - - String sourceStyleId = source.getStyleId(); - String oldStyleId = sourceStyleId; - if (oldStyleId == null) - oldStyleId = NULL + sourceType; - String newStyleId = getCachedId(oldStyleId); - if (newStyleId == null) { - newStyleId = getNewStyleId(source, sourceStyleId, sourceType); - if (newStyleId == null) - newStyleId = NULL + sourceType; - cacheId(oldStyleId, newStyleId); - } - - if (oldStyleId.equals(newStyleId)) - return; - - modifyStyle(source, newStyleId); - sources.add(source); - } - - public void removeStyle(IStyled source) { - if (isSourceModified(source)) - return; - - modifyStyle(source, null); - sources.add(source); - } - - private void modifyStyle(IStyled source, String newStyleId) { - if (NULL.equals(newStyleId)) - newStyleId = null; - add(new ModifyStyleCommand(source, newStyleId), true); - } - - private void cacheId(String oldId, String newId) { - if (idCache == null) - idCache = new HashMap(); - idCache.put(oldId, newId); - } - - private String getCachedId(String oldId) { - if (idCache != null) - return idCache.get(oldId); - return null; - } - - private String getNewStyleId(IStyled source, String sourceStyleId, - String sourceType) { - IStyleSheet styleSheet = getStyleSheet(source); - if (styleSheet == null) - return null; - - IStyle oldStyle = sourceStyleId == null ? null : styleSheet - .findStyle(sourceStyleId); - Properties oldProperties = getProperties(oldStyle); - if (oldProperties == null) { - oldProperties = new Properties(); - } else { - Properties p = new Properties(); - p.putAll(oldProperties); - oldProperties = p; - } - - putValues(source, oldProperties, sourceType); - - if (oldProperties.isEmpty()) - return null; - - IStyle similarStyle = findSimilarStyle(oldProperties, styleSheet); - if (similarStyle != null) - return similarStyle.getId(); - - IStyle newStyle = createStyle(styleSheet, source, oldProperties, - sourceType); - if (newStyle != null) - return newStyle.getId(); - - return null; - } - - private void putValues(IStyled source, Properties oldProperties, - String sourceType) { - if (sourceStyle != null && sourceStyle.getType().equals(sourceType)) { - Iterator sourceProperties = sourceStyle.properties(); - while (sourceProperties.hasNext()) { - Property prop = sourceProperties.next(); - if (prop.value == null) { - oldProperties.remove(prop.key); - } else { - oldProperties.put(prop.key, prop.value); - } - } - } - for (String name : request.getParameterNames()) { - if (name.startsWith(MindMapUI.PARAM_STYLE_PREFIX)) { - String key = name.substring(MindMapUI.PARAM_STYLE_PREFIX - .length()); - String value = (String) request.getParameter(name); - value = evaluate(source, key, value); - if (value == null) { - oldProperties.remove(key); - } else { - oldProperties.put(key, value); - } - } - } - } - - private IStyle findSimilarStyle(Properties sourceProperties, - IStyleSheet styleSheet) { - Set styles = styleSheet.getStyles(IStyleSheet.NORMAL_STYLES); - for (IStyle style : styles) { - Properties contents = getProperties(style); - if (contents.equals(sourceProperties)) - return style; - } - return null; - } - - private IStyle createStyle(IStyleSheet styleSheet, IStyled source, - Properties properties, String sourceType) { - if (sourceType == null) - return null; - - IStyle newStyle = styleSheet.createStyle(sourceType); - for (Entry en : properties.entrySet()) { - newStyle.setProperty((String) en.getKey(), (String) en.getValue()); - } - styleSheet.addStyle(newStyle, IStyleSheet.NORMAL_STYLES); - return newStyle; - } - - private String getStyleType(IStyled source) { - return source == null ? null : source.getStyleType(); -// if (source instanceof ITopic) -// return IStyle.TOPIC; -// if (source instanceof IBoundary) -// return IStyle.BOUNDARY; -// if (source instanceof IRelationship) -// return IStyle.RELATIONSHIP; -// if (source instanceof ISheet) -// return IStyle.MAP; -// if (source instanceof ISummary) -// return IStyle.SUMMARY; -// return null; - } - - private String evaluate(IStyled source, String key, String value) { - if (value != null) { - if (Styles.Background.equals(key)) { - String attachmentURL = getCachedId(value); - if (attachmentURL == null) { - attachmentURL = createAttachmentURL(source, value); - if (attachmentURL != null) { - cacheId(value, attachmentURL); - } - } - if (attachmentURL != null) - value = attachmentURL; - } - } - return value; - } - - private String createAttachmentURL(IStyled source, String value) { - File file = new File(value); - if (!file.exists() || !file.canRead()) - return null; - - IWorkbook workbook = getWorkbook(source); - if (workbook == null) - return null; - - IFileEntry entry; - try { - entry = workbook.getManifest().createAttachmentFromFilePath(value); - } catch (IOException e) { - return null; - } - if (entry == null) - return null; - return HyperlinkUtils.toAttachmentURL(entry.getPath()); - } - - private Properties getProperties(IStyle style) { - if (style == null) - return null; - - String id = style.getId(); - if (propertiesCache == null) - propertiesCache = new HashMap(); - Properties properties = propertiesCache.get(id); - if (properties != null) - return properties; - - properties = new Properties(); - propertiesCache.put(id, properties); - Iterator it = style.properties(); - while (it.hasNext()) { - Property p = it.next(); - properties.put(p.key, p.value); - } - return properties; - } - - private IWorkbook getWorkbook(IStyled styled) { - if (styled instanceof IWorkbookComponent) { - return ((IWorkbookComponent) styled).getOwnedWorkbook(); - } - return null; - } - - private IStyleSheet getStyleSheet(IStyled styled) { - if (styled instanceof IWorkbookComponent) - return ((IWorkbookComponent) styled).getOwnedWorkbook() - .getStyleSheet(); - return null; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; + +import org.xmind.core.IFileEntry; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookComponent; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.core.util.Property; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.ModifyStyleCommand; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.Styles; + +public class ModifyStyleCommandBuilder extends CommandBuilder { + + private static final String NULL = "$NULL$"; //$NON-NLS-1$ + + private Request request; + + private IStyle sourceStyle; + + private Map idCache = null; + + private Map propertiesCache = new HashMap(); + + private List sources = new ArrayList(); + + public ModifyStyleCommandBuilder(Request request) { + this(request.getTargetViewer(), request.getTargetDomain() + .getCommandStack(), request); + } + + public ModifyStyleCommandBuilder(IViewer viewer, CommandBuilder delegate, + Request request) { + super(viewer, delegate); + init(request); + } + + public ModifyStyleCommandBuilder(IViewer viewer, + ICommandStack commandStack, Request request) { + super(viewer, commandStack); + init(request); + } + + private void init(Request request) { + this.request = request; + Object resource = request.getParameter(MindMapUI.PARAM_RESOURCE); + this.sourceStyle = (resource instanceof IStyle) ? (IStyle) resource + : null; + } + + public List getModifiedSources() { + return sources; + } + + public boolean isSourceModified(IStyled source) { + return sources.contains(source); + } + + public void modify(IStyled source) { + if (isSourceModified(source)) + return; + + String sourceType = getStyleType(source); + if (sourceType == null) + return; + + String sourceStyleId = source.getStyleId(); + String oldStyleId = sourceStyleId; + if (oldStyleId == null) + oldStyleId = NULL + sourceType; + String newStyleId = getCachedId(oldStyleId); + if (newStyleId == null) { + newStyleId = getNewStyleId(source, sourceStyleId, sourceType); + if (newStyleId == null) + newStyleId = NULL + sourceType; + cacheId(oldStyleId, newStyleId); + } + + if (oldStyleId.equals(newStyleId)) + return; + + modifyStyle(source, newStyleId); + sources.add(source); + } + + public void removeStyle(IStyled source) { + if (isSourceModified(source)) + return; + + modifyStyle(source, null); + sources.add(source); + } + + private void modifyStyle(IStyled source, String newStyleId) { + if (NULL.equals(newStyleId)) + newStyleId = null; + add(new ModifyStyleCommand(source, newStyleId), true); + } + + private void cacheId(String oldId, String newId) { + if (idCache == null) + idCache = new HashMap(); + idCache.put(oldId, newId); + } + + private String getCachedId(String oldId) { + if (idCache != null) + return idCache.get(oldId); + return null; + } + + private String getNewStyleId(IStyled source, String sourceStyleId, + String sourceType) { + IStyleSheet styleSheet = getStyleSheet(source); + if (styleSheet == null) + return null; + + IStyle oldStyle = sourceStyleId == null ? null : styleSheet + .findStyle(sourceStyleId); + Properties oldProperties = getProperties(oldStyle); + if (oldProperties == null) { + oldProperties = new Properties(); + } else { + Properties p = new Properties(); + p.putAll(oldProperties); + oldProperties = p; + } + + putValues(source, oldProperties, sourceType); + + if (oldProperties.isEmpty()) + return null; + + IStyle similarStyle = findSimilarStyle(oldProperties, styleSheet); + if (similarStyle != null) + return similarStyle.getId(); + + IStyle newStyle = createStyle(styleSheet, source, oldProperties, + sourceType); + if (newStyle != null) + return newStyle.getId(); + + return null; + } + + private void putValues(IStyled source, Properties oldProperties, + String sourceType) { + if (sourceStyle != null && sourceStyle.getType().equals(sourceType)) { + Iterator sourceProperties = sourceStyle.properties(); + while (sourceProperties.hasNext()) { + Property prop = sourceProperties.next(); + if (prop.value == null) { + oldProperties.remove(prop.key); + } else { + oldProperties.put(prop.key, prop.value); + } + } + } + for (String name : request.getParameterNames()) { + if (name.startsWith(MindMapUI.PARAM_STYLE_PREFIX)) { + String key = name.substring(MindMapUI.PARAM_STYLE_PREFIX + .length()); + String value = (String) request.getParameter(name); + value = evaluate(source, key, value); + if (value == null) { + oldProperties.remove(key); + } else { + oldProperties.put(key, value); + } + } + } + } + + private IStyle findSimilarStyle(Properties sourceProperties, + IStyleSheet styleSheet) { + Set styles = styleSheet.getStyles(IStyleSheet.NORMAL_STYLES); + for (IStyle style : styles) { + Properties contents = getProperties(style); + if (contents.equals(sourceProperties)) + return style; + } + return null; + } + + private IStyle createStyle(IStyleSheet styleSheet, IStyled source, + Properties properties, String sourceType) { + if (sourceType == null) + return null; + + IStyle newStyle = styleSheet.createStyle(sourceType); + for (Entry en : properties.entrySet()) { + newStyle.setProperty((String) en.getKey(), (String) en.getValue()); + } + styleSheet.addStyle(newStyle, IStyleSheet.NORMAL_STYLES); + return newStyle; + } + + private String getStyleType(IStyled source) { + return source == null ? null : source.getStyleType(); +// if (source instanceof ITopic) +// return IStyle.TOPIC; +// if (source instanceof IBoundary) +// return IStyle.BOUNDARY; +// if (source instanceof IRelationship) +// return IStyle.RELATIONSHIP; +// if (source instanceof ISheet) +// return IStyle.MAP; +// if (source instanceof ISummary) +// return IStyle.SUMMARY; +// return null; + } + + private String evaluate(IStyled source, String key, String value) { + if (value != null) { + if (Styles.Background.equals(key)) { + String attachmentURL = getCachedId(value); + if (attachmentURL == null) { + attachmentURL = createAttachmentURL(source, value); + if (attachmentURL != null) { + cacheId(value, attachmentURL); + } + } + if (attachmentURL != null) + value = attachmentURL; + } + } + return value; + } + + private String createAttachmentURL(IStyled source, String value) { + File file = new File(value); + if (!file.exists() || !file.canRead()) + return null; + + IWorkbook workbook = getWorkbook(source); + if (workbook == null) + return null; + + IFileEntry entry; + try { + entry = workbook.getManifest().createAttachmentFromFilePath(value); + } catch (IOException e) { + return null; + } + if (entry == null) + return null; + return HyperlinkUtils.toAttachmentURL(entry.getPath()); + } + + private Properties getProperties(IStyle style) { + if (style == null) + return null; + + String id = style.getId(); + if (propertiesCache == null) + propertiesCache = new HashMap(); + Properties properties = propertiesCache.get(id); + if (properties != null) + return properties; + + properties = new Properties(); + propertiesCache.put(id, properties); + Iterator it = style.properties(); + while (it.hasNext()) { + Property p = it.next(); + properties.put(p.key, p.value); + } + return properties; + } + + private IWorkbook getWorkbook(IStyled styled) { + if (styled instanceof IWorkbookComponent) { + return ((IWorkbookComponent) styled).getOwnedWorkbook(); + } + return null; + } + + private IStyleSheet getStyleSheet(IStyled styled) { + if (styled instanceof IWorkbookComponent) + return ((IWorkbookComponent) styled).getOwnedWorkbook() + .getStyleSheet(); + return null; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyThemeCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyThemeCommandBuilder.java index 3f4445d41..ee2413b65 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyThemeCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/ModifyThemeCommandBuilder.java @@ -1,138 +1,138 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.xmind.core.ISheet; -import org.xmind.core.IWorkbook; -import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; -import org.xmind.core.style.IStyled; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.ModifyStyleCommand; -import org.xmind.ui.commands.ModifyThemeCommand; -import org.xmind.ui.mindmap.MindMapUI; - -public class ModifyThemeCommandBuilder extends CommandBuilder { - - private static final String NULL = "$NULL$"; //$NON-NLS-1$ - - private IStyle sourceTheme; - - private Map appliedThemes = null; - - private List sources = new ArrayList(); - - public ModifyThemeCommandBuilder(IViewer viewer, - ICommandStack commandStack, IStyle theme) { - super(viewer, commandStack); - this.sourceTheme = theme; - } - - public ModifyThemeCommandBuilder(IViewer viewer, CommandBuilder delegate, - IStyle theme) { - super(viewer, delegate); - this.sourceTheme = theme; - } - - public IStyle getTheme() { - return sourceTheme; - } - - public void removeStyle(IStyled source) { - if (isSourceModified(source)) - return; - - modifyStyle(source, null); - sources.add(source); - } - - public List getModifiedSources() { - return sources; - } - - public boolean isSourceModified(IStyled source) { - return sources.contains(source); - } - - private void modifyStyle(IStyled source, String newStyleId) { - if (NULL.equals(newStyleId)) - newStyleId = null; - add(new ModifyStyleCommand(source, newStyleId), true); - } - - public void modify(ISheet sheet) { - IStyle appliedTheme = getAppliedTheme(sheet); - if (appliedTheme == null) { - add(new ModifyThemeCommand(sheet, null), true); - } else { - add(new ModifyThemeCommand(sheet, appliedTheme.getId()), true); - } -// ModifyStyleCommandBuilder modifyStyleBuilder = new ModifyStyleCommandBuilder( -// getViewer(), this, createSheetStyleRequest(appliedTheme)); -// modifyStyleBuilder.modify(sheet); - } - -// private Request createSheetStyleRequest(IStyle appliedTheme) { -// Request request = new Request(MindMapUI.REQ_MODIFY_STYLE) -// .setViewer(getViewer()); -// request.setParameter(MindMapUI.PARAM_STYLE_PREFIX -// + Styles.MultiLineColors, -// getMapStyleValue(appliedTheme, Styles.MultiLineColors)); -// request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.LineTapered, -// getMapStyleValue(appliedTheme, Styles.LineTapered)); -// return request; -// } -// -// private String getMapStyleValue(IStyle theme, String key) { -// if (theme == null) -// return null; -// IStyle mapStyle = theme.getDefaultStyle(Styles.FAMILY_MAP); -// if (mapStyle == null) -// return null; -// return mapStyle.getProperty(key); -// } - - private IStyle getAppliedTheme(ISheet sheet) { - if (sourceTheme == null - || sourceTheme.isEmpty() - || MindMapUI.getResourceManager().getBlankTheme() - .equals(sourceTheme)) - return null; - - IWorkbook workbook = sheet.getOwnedWorkbook(); - if (workbook == null) - return sourceTheme; - - if (appliedThemes == null) - appliedThemes = new HashMap(); - if (!appliedThemes.containsKey(workbook)) { - IStyle appliedTheme = createAppliedTheme(workbook); - appliedThemes.put(workbook, appliedTheme); - } - return appliedThemes.get(workbook); - } - - private IStyle createAppliedTheme(IWorkbook workbook) { - IStyleSheet ss = workbook.getStyleSheet(); - return ss.importStyle(sourceTheme); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.style.IStyled; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.ModifyStyleCommand; +import org.xmind.ui.commands.ModifyThemeCommand; +import org.xmind.ui.mindmap.MindMapUI; + +public class ModifyThemeCommandBuilder extends CommandBuilder { + + private static final String NULL = "$NULL$"; //$NON-NLS-1$ + + private IStyle sourceTheme; + + private Map appliedThemes = null; + + private List sources = new ArrayList(); + + public ModifyThemeCommandBuilder(IViewer viewer, + ICommandStack commandStack, IStyle theme) { + super(viewer, commandStack); + this.sourceTheme = theme; + } + + public ModifyThemeCommandBuilder(IViewer viewer, CommandBuilder delegate, + IStyle theme) { + super(viewer, delegate); + this.sourceTheme = theme; + } + + public IStyle getTheme() { + return sourceTheme; + } + + public void removeStyle(IStyled source) { + if (isSourceModified(source)) + return; + + modifyStyle(source, null); + sources.add(source); + } + + public List getModifiedSources() { + return sources; + } + + public boolean isSourceModified(IStyled source) { + return sources.contains(source); + } + + private void modifyStyle(IStyled source, String newStyleId) { + if (NULL.equals(newStyleId)) + newStyleId = null; + add(new ModifyStyleCommand(source, newStyleId), true); + } + + public void modify(ISheet sheet) { + IStyle appliedTheme = getAppliedTheme(sheet); + if (appliedTheme == null) { + add(new ModifyThemeCommand(sheet, null), true); + } else { + add(new ModifyThemeCommand(sheet, appliedTheme.getId()), true); + } +// ModifyStyleCommandBuilder modifyStyleBuilder = new ModifyStyleCommandBuilder( +// getViewer(), this, createSheetStyleRequest(appliedTheme)); +// modifyStyleBuilder.modify(sheet); + } + +// private Request createSheetStyleRequest(IStyle appliedTheme) { +// Request request = new Request(MindMapUI.REQ_MODIFY_STYLE) +// .setViewer(getViewer()); +// request.setParameter(MindMapUI.PARAM_STYLE_PREFIX +// + Styles.MultiLineColors, +// getMapStyleValue(appliedTheme, Styles.MultiLineColors)); +// request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.LineTapered, +// getMapStyleValue(appliedTheme, Styles.LineTapered)); +// return request; +// } +// +// private String getMapStyleValue(IStyle theme, String key) { +// if (theme == null) +// return null; +// IStyle mapStyle = theme.getDefaultStyle(Styles.FAMILY_MAP); +// if (mapStyle == null) +// return null; +// return mapStyle.getProperty(key); +// } + + private IStyle getAppliedTheme(ISheet sheet) { + if (sourceTheme == null + || sourceTheme.isEmpty() + || MindMapUI.getResourceManager().getBlankTheme() + .equals(sourceTheme)) + return null; + + IWorkbook workbook = sheet.getOwnedWorkbook(); + if (workbook == null) + return sourceTheme; + + if (appliedThemes == null) + appliedThemes = new HashMap(); + if (!appliedThemes.containsKey(workbook)) { + IStyle appliedTheme = createAppliedTheme(workbook); + appliedThemes.put(workbook, appliedTheme); + } + return appliedThemes.get(workbook); + } + + private IStyle createAppliedTheme(IWorkbook workbook) { + IStyleSheet ss = workbook.getStyleSheet(); + return ss.importStyle(sourceTheme); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/PropertyCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/PropertyCommandBuilder.java index 608c03578..24f6a4d70 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/PropertyCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/PropertyCommandBuilder.java @@ -1,237 +1,237 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.core.Core; -import org.xmind.core.IPositioned; -import org.xmind.core.ITitled; -import org.xmind.core.ITopic; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.ModifyFoldedCommand; -import org.xmind.ui.commands.ModifyLabelCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.commands.ModifyTopicStructureCommand; -import org.xmind.ui.commands.ModifyTopicTitleWidthCommand; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class PropertyCommandBuilder extends CommandBuilder { - - private static final List EMPTY_SOURCES = Collections.emptyList(); - - private Request request; - - private List sources = null; - - public PropertyCommandBuilder(Request request) { - this(request.getTargetViewer(), request.getTargetCommandStack(), - request); - } - - public PropertyCommandBuilder(IViewer viewer, CommandBuilder delegate, - Request request) { - super(viewer, delegate); - this.request = request; - } - - public PropertyCommandBuilder(IViewer viewer, ICommandStack commandStack, - Request request) { - super(viewer, commandStack); - this.request = request; - } - - public Request getRequest() { - return request; - } - - public void addSourcesFromRequest(boolean collectable) { - addSources(MindMapUtils.getRealModels(request.getTargets()).toArray(), - collectable); - } - - public void addSources(Object[] sources, boolean collectable) { - for (Object source : sources) { - addSource(source, collectable); - } - } - - public void addSource(Object source, boolean collectable) { - boolean commandAdded = false; - for (Entry param : request.getParameters().entrySet()) { - String paramName = param.getKey(); - if (paramName.startsWith(MindMapUI.PARAM_PROPERTY_PREFIX)) { - String propName = paramName - .substring(MindMapUI.PARAM_PROPERTY_PREFIX.length()); - commandAdded |= addPropertyCommand(source, propName, param - .getValue(), collectable); - } - } - if (commandAdded) { - addSource(source); - } - } - - private void addSource(Object source) { - if (sources == null) - sources = new ArrayList(); - sources.add(source); - } - - public boolean isSourceAdded(Object source) { - return sources != null && sources.contains(source); - } - - public List getAddedSources() { - return sources == null ? EMPTY_SOURCES : sources; - } - - private boolean addPropertyCommand(Object source, String propName, - Object value, boolean sourceCollectable) { - if (propName == null || "".equals(propName)) //$NON-NLS-1$ - return false; - - if (Core.TitleText.equals(propName)) { - return modifyTitle(source, value, sourceCollectable); - } else if (Core.TopicFolded.equals(propName)) { - return modifyTopicFolded(source, value, sourceCollectable); - } else if (Core.Labels.equals(propName)) { - return modifyTopicLabels(source, value, sourceCollectable); - } else if (Core.TitleWidth.equals(propName)) { - return modifyTitleWidth(source, value, sourceCollectable); - } else if (Core.Position.equals(propName)) { - return modifyPosition(source, value, sourceCollectable); - } else if (Core.StructureClass.equals(propName)) { - return modifyStructure(source, value, sourceCollectable); - } else { - // TODO add more property handlers when necessary - } - return false; - } - - /** - * @param source - * @param value - * @param sourceCollectable - * @return - */ - private boolean modifyStructure(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof ITopic) { - if (value == null || value instanceof String) { - String structureClass = (String) value; - add(new ModifyTopicStructureCommand((ITopic) source, - structureClass), sourceCollectable); - return true; - } - } - return false; - } - - private boolean modifyPosition(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof IPositioned) { - if (value == null || value instanceof Point) { - Point p = (Point) value; - add(new ModifyPositionCommand((IPositioned) source, - MindMapUtils.toModelPosition(p)), sourceCollectable); - return true; - } - } - return false; - } - - private boolean modifyTitleWidth(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof ITopic) { - if (value == null || value instanceof Integer) { - int width = value == null ? ITopic.UNSPECIFIED - : ((Integer) value).intValue(); - ModifyTopicTitleWidthCommand command = new ModifyTopicTitleWidthCommand( - (ITopic) source, width); - command.setLabel(CommandMessages.Command_ModifyWidth); - add(command, sourceCollectable); - - return true; - } - } - return false; - } - - private boolean modifyTopicLabels(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof ITopic) { - if (value == null || value instanceof String - || value instanceof String[] || value instanceof Collection) { - ArrayList labels = new ArrayList(); - if (value != null) { - if (value instanceof String) { - labels.addAll(MindMapUtils.getLabels((String) value)); - } else if (value instanceof String[]) { - labels.addAll(Arrays.asList((String[]) value)); - } else if (value instanceof Collection) { - for (Object o : (Collection) value) { - if (o instanceof String) { - labels.add((String) o); - } - } - } - } - add(new ModifyLabelCommand((ITopic) source, labels), - sourceCollectable); - return true; - } - } - return false; - } - - private boolean modifyTopicFolded(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof ITopic) { - if (value instanceof Boolean) { - boolean newFolded = ((Boolean) value).booleanValue(); - add(new ModifyFoldedCommand((ITopic) source, newFolded), - sourceCollectable); - return true; - } - } - return false; - } - - private boolean modifyTitle(Object source, Object value, - boolean sourceCollectable) { - if (source instanceof ITitled) { - if (value == null || value instanceof String) { - add( - new ModifyTitleTextCommand((ITitled) source, - (String) value), sourceCollectable); - return true; - } - } - return false; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.core.Core; +import org.xmind.core.IPositioned; +import org.xmind.core.ITitled; +import org.xmind.core.ITopic; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyFoldedCommand; +import org.xmind.ui.commands.ModifyLabelCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.commands.ModifyTopicStructureCommand; +import org.xmind.ui.commands.ModifyTopicTitleWidthCommand; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class PropertyCommandBuilder extends CommandBuilder { + + private static final List EMPTY_SOURCES = Collections.emptyList(); + + private Request request; + + private List sources = null; + + public PropertyCommandBuilder(Request request) { + this(request.getTargetViewer(), request.getTargetCommandStack(), + request); + } + + public PropertyCommandBuilder(IViewer viewer, CommandBuilder delegate, + Request request) { + super(viewer, delegate); + this.request = request; + } + + public PropertyCommandBuilder(IViewer viewer, ICommandStack commandStack, + Request request) { + super(viewer, commandStack); + this.request = request; + } + + public Request getRequest() { + return request; + } + + public void addSourcesFromRequest(boolean collectable) { + addSources(MindMapUtils.getRealModels(request.getTargets()).toArray(), + collectable); + } + + public void addSources(Object[] sources, boolean collectable) { + for (Object source : sources) { + addSource(source, collectable); + } + } + + public void addSource(Object source, boolean collectable) { + boolean commandAdded = false; + for (Entry param : request.getParameters().entrySet()) { + String paramName = param.getKey(); + if (paramName.startsWith(MindMapUI.PARAM_PROPERTY_PREFIX)) { + String propName = paramName + .substring(MindMapUI.PARAM_PROPERTY_PREFIX.length()); + commandAdded |= addPropertyCommand(source, propName, param + .getValue(), collectable); + } + } + if (commandAdded) { + addSource(source); + } + } + + private void addSource(Object source) { + if (sources == null) + sources = new ArrayList(); + sources.add(source); + } + + public boolean isSourceAdded(Object source) { + return sources != null && sources.contains(source); + } + + public List getAddedSources() { + return sources == null ? EMPTY_SOURCES : sources; + } + + private boolean addPropertyCommand(Object source, String propName, + Object value, boolean sourceCollectable) { + if (propName == null || "".equals(propName)) //$NON-NLS-1$ + return false; + + if (Core.TitleText.equals(propName)) { + return modifyTitle(source, value, sourceCollectable); + } else if (Core.TopicFolded.equals(propName)) { + return modifyTopicFolded(source, value, sourceCollectable); + } else if (Core.Labels.equals(propName)) { + return modifyTopicLabels(source, value, sourceCollectable); + } else if (Core.TitleWidth.equals(propName)) { + return modifyTitleWidth(source, value, sourceCollectable); + } else if (Core.Position.equals(propName)) { + return modifyPosition(source, value, sourceCollectable); + } else if (Core.StructureClass.equals(propName)) { + return modifyStructure(source, value, sourceCollectable); + } else { + // TODO add more property handlers when necessary + } + return false; + } + + /** + * @param source + * @param value + * @param sourceCollectable + * @return + */ + private boolean modifyStructure(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof ITopic) { + if (value == null || value instanceof String) { + String structureClass = (String) value; + add(new ModifyTopicStructureCommand((ITopic) source, + structureClass), sourceCollectable); + return true; + } + } + return false; + } + + private boolean modifyPosition(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof IPositioned) { + if (value == null || value instanceof Point) { + Point p = (Point) value; + add(new ModifyPositionCommand((IPositioned) source, + MindMapUtils.toModelPosition(p)), sourceCollectable); + return true; + } + } + return false; + } + + private boolean modifyTitleWidth(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof ITopic) { + if (value == null || value instanceof Integer) { + int width = value == null ? ITopic.UNSPECIFIED + : ((Integer) value).intValue(); + ModifyTopicTitleWidthCommand command = new ModifyTopicTitleWidthCommand( + (ITopic) source, width); + command.setLabel(CommandMessages.Command_ModifyWidth); + add(command, sourceCollectable); + + return true; + } + } + return false; + } + + private boolean modifyTopicLabels(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof ITopic) { + if (value == null || value instanceof String + || value instanceof String[] || value instanceof Collection) { + ArrayList labels = new ArrayList(); + if (value != null) { + if (value instanceof String) { + labels.addAll(MindMapUtils.getLabels((String) value)); + } else if (value instanceof String[]) { + labels.addAll(Arrays.asList((String[]) value)); + } else if (value instanceof Collection) { + for (Object o : (Collection) value) { + if (o instanceof String) { + labels.add((String) o); + } + } + } + } + add(new ModifyLabelCommand((ITopic) source, labels), + sourceCollectable); + return true; + } + } + return false; + } + + private boolean modifyTopicFolded(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof ITopic) { + if (value instanceof Boolean) { + boolean newFolded = ((Boolean) value).booleanValue(); + add(new ModifyFoldedCommand((ITopic) source, newFolded), + sourceCollectable); + return true; + } + } + return false; + } + + private boolean modifyTitle(Object source, Object value, + boolean sourceCollectable) { + if (source instanceof ITitled) { + if (value == null || value instanceof String) { + add( + new ModifyTitleTextCommand((ITitled) source, + (String) value), sourceCollectable); + return true; + } + } + return false; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/RelationshipCreateCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/RelationshipCreateCommandBuilder.java index 605e67fd9..7ce94f72d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/RelationshipCreateCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/RelationshipCreateCommandBuilder.java @@ -1,99 +1,99 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.core.IControlPoint; -import org.xmind.core.IRelationship; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.core.IWorkbook; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.AddRelationshipCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.CreateRelationshipCommand; -import org.xmind.ui.commands.CreateTopicCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyRelationshipEndCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.util.MindMapUtils; - -public class RelationshipCreateCommandBuilder extends CommandBuilder { - - private ISheet parent; - - private IRelationshipEnd end1; - - public RelationshipCreateCommandBuilder(IViewer viewer, - CommandBuilder delegate, ISheet parent, IRelationshipEnd end1) { - super(viewer, delegate); - this.parent = parent; - this.end1 = end1; - } - - public RelationshipCreateCommandBuilder(IViewer viewer, - ICommandStack commandStack, ISheet parent, IRelationshipEnd end1) { - super(viewer, commandStack); - this.parent = parent; - this.end1 = end1; - } - - public void create(IRelationshipEnd end2) { - createRelationship(end2, true); - } - - public void create(Point targetPosition) { - CreateTopicCommand createTopic = new CreateTopicCommand( - parent.getOwnedWorkbook()); - add(createTopic, true); - ITopic end2 = (ITopic) createTopic.getSource(); - add(new ModifyTitleTextCommand(end2, - MindMapMessages.TitleText_FloatingTopic), false); - add(new ModifyPositionCommand(end2, - MindMapUtils.toModelPosition(targetPosition)), false); - ITopic rootTopic = (ITopic) getViewer().getAdapter(ITopic.class); - if (rootTopic == null) - rootTopic = parent.getRootTopic(); - add(new AddTopicCommand(end2, rootTopic, -1, ITopic.DETACHED), false); - createRelationship(end2, false); - } - - private void createRelationship(IRelationshipEnd end2, - boolean relationshipCollectalbe) { - IWorkbook workbook = parent.getOwnedWorkbook(); - CreateRelationshipCommand create = new CreateRelationshipCommand( - workbook); - add(create, relationshipCollectalbe); - IRelationship rel = (IRelationship) create.getSource(); - - IControlPoint cp1 = rel.getControlPoint(0); - IControlPoint cp2 = rel.getControlPoint(1); - - cp1.setPolarAngle(Math.PI / 12); - cp1.setPolarAmount(0.3); - - cp2.setPolarAngle(Math.PI / 12); - cp2.setPolarAmount(0.3); - - add(new ModifyRelationshipEndCommand(rel, end1.getId(), true), false); - add(new ModifyRelationshipEndCommand(rel, end2.getId(), false), false); - add(new AddRelationshipCommand(rel, parent), false); - - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.core.IControlPoint; +import org.xmind.core.IRelationship; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.IWorkbook; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.AddRelationshipCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.CreateRelationshipCommand; +import org.xmind.ui.commands.CreateTopicCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyRelationshipEndCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.util.MindMapUtils; + +public class RelationshipCreateCommandBuilder extends CommandBuilder { + + private ISheet parent; + + private IRelationshipEnd end1; + + public RelationshipCreateCommandBuilder(IViewer viewer, + CommandBuilder delegate, ISheet parent, IRelationshipEnd end1) { + super(viewer, delegate); + this.parent = parent; + this.end1 = end1; + } + + public RelationshipCreateCommandBuilder(IViewer viewer, + ICommandStack commandStack, ISheet parent, IRelationshipEnd end1) { + super(viewer, commandStack); + this.parent = parent; + this.end1 = end1; + } + + public void create(IRelationshipEnd end2) { + createRelationship(end2, true); + } + + public void create(Point targetPosition) { + CreateTopicCommand createTopic = new CreateTopicCommand( + parent.getOwnedWorkbook()); + add(createTopic, true); + ITopic end2 = (ITopic) createTopic.getSource(); + add(new ModifyTitleTextCommand(end2, + MindMapMessages.TitleText_FloatingTopic), false); + add(new ModifyPositionCommand(end2, + MindMapUtils.toModelPosition(targetPosition)), false); + ITopic rootTopic = (ITopic) getViewer().getAdapter(ITopic.class); + if (rootTopic == null) + rootTopic = parent.getRootTopic(); + add(new AddTopicCommand(end2, rootTopic, -1, ITopic.DETACHED), false); + createRelationship(end2, false); + } + + private void createRelationship(IRelationshipEnd end2, + boolean relationshipCollectalbe) { + IWorkbook workbook = parent.getOwnedWorkbook(); + CreateRelationshipCommand create = new CreateRelationshipCommand( + workbook); + add(create, relationshipCollectalbe); + IRelationship rel = (IRelationship) create.getSource(); + + IControlPoint cp1 = rel.getControlPoint(0); + IControlPoint cp2 = rel.getControlPoint(1); + + cp1.setPolarAngle(Math.PI / 12); + cp1.setPolarAmount(0.3); + + cp2.setPolarAngle(Math.PI / 12); + cp2.setPolarAmount(0.3); + + add(new ModifyRelationshipEndCommand(rel, end1.getId(), true), false); + add(new ModifyRelationshipEndCommand(rel, end2.getId(), false), false); + add(new AddRelationshipCommand(rel, parent), false); + + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SheetCreatablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SheetCreatablePolicy.java index ef8d62c6a..da05c2919 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SheetCreatablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SheetCreatablePolicy.java @@ -1,217 +1,217 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import org.eclipse.draw2d.geometry.Point; -import org.xmind.core.IRelationshipEnd; -import org.xmind.core.ISheet; -import org.xmind.core.ITopic; -import org.xmind.gef.GEF; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.CreateTopicCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class SheetCreatablePolicy extends MindMapPolicyBase { - - public boolean understands(String requestType) { - return super.understands(requestType) - || MindMapUI.REQ_CREATE_FLOAT.equals(requestType) - || MindMapUI.REQ_CREATE_RELATIONSHIP.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (MindMapUI.REQ_CREATE_FLOAT.equals(reqType)) { - createFloatingTopic(request); - } else if (MindMapUI.REQ_CREATE_RELATIONSHIP.equals(reqType)) { - createRelationship(request); - } - } - - private void createRelationship(Request request) { - IPart sourceNode = (IPart) request - .getParameter(MindMapUI.PARAM_SOURCE_NODE); - if (sourceNode == null) - return; - - Object m1 = MindMapUtils.getRealModel(sourceNode); - if (!(m1 instanceof IRelationshipEnd)) - return; - - IRelationshipEnd end1 = (IRelationshipEnd) m1; - - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return; - - ISheet parent = (ISheet) viewer.getAdapter(ISheet.class); - if (parent == null) - return; - - RelationshipCreateCommandBuilder builder = new RelationshipCreateCommandBuilder( - viewer, request.getTargetCommandStack(), parent, end1); - if (builder.canStart()) { - builder.start(); - - IPart targetNode = (IPart) request - .getParameter(MindMapUI.PARAM_TARGET_NODE); - if (targetNode != null) { - Object m2 = MindMapUtils.getRealModel(targetNode); - if (m2 instanceof IRelationshipEnd) - builder.create((IRelationshipEnd) m2); - } else { - Point targetPosition = (Point) request - .getParameter(GEF.PARAM_POSITION); - if (targetPosition != null) { - builder.create(targetPosition); - } - } - - builder.end(); - - select(builder.getCommand().getSources(), viewer); - } - -// IRelationshipEnd end2 = null; -// IPart targetNode = (IPart) request -// .getParameter(MindMapUI.PARAM_TARGET_NODE); -// if (targetNode != null) { -// Object m2 = MindMapUtils.getRealModel(targetNode); -// if (m2 instanceof IRelationshipEnd) -// end2 = (IRelationshipEnd) m2; -// } else { -// -// } -// -// if (end2 != null) { -// Command cmd = createCreateRelationship(parent, end1, end2); -// cmd.setLabel(CommandMessages.Command_CreateRelationship); -// if (cmd != null) { -// saveAndRun(cmd, request.getTargetDomain()); -// if (cmd instanceof ISourceProvider) { -// select(((ISourceProvider) cmd).getSources(), viewer); -// } -// } -// } - } - -// private Command createCreateRelationship(ISheet parent, -// IRelationshipEnd end1, IRelationshipEnd end2) { -// IWorkbook workbook = parent.getOwnedWorkbook(); -// if (workbook == null) -// return null; -// CreateRelationshipCommand create = new CreateRelationshipCommand( -// workbook); -// ModifyRelationshipEndCommand setEnd1 = new ModifyRelationshipEndCommand( -// create, end1.getId(), true); -// ModifyRelationshipEndCommand setEnd2 = new ModifyRelationshipEndCommand( -// create, end2.getId(), false); -// AddRelationshipCommand add = new AddRelationshipCommand(create, parent); -// return new CompoundCommand(create, setEnd1, setEnd2, add); -// } - - private void createFloatingTopic(Request request) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return; - - ITopic rootTopic = (ITopic) viewer.getAdapter(ITopic.class); - if (rootTopic == null) - return; - - Point position = (Point) request.getParameter(GEF.PARAM_POSITION); - if (position == null) - return; - - PropertyCommandBuilder builder = new PropertyCommandBuilder(request); - if (!builder.canStart()) - return; - - builder.start(); - builder.setLabel(CommandMessages.Command_CreateFloatingTopic); - CreateTopicCommand create = new CreateTopicCommand( - rootTopic.getOwnedWorkbook()); - builder.add(create, true); - builder.add( - new AddTopicCommand(create, rootTopic, -1, ITopic.DETACHED), - false); - builder.add(new ModifyTitleTextCommand(create, - MindMapMessages.TitleText_FloatingTopic), false); - builder.add( - new ModifyPositionCommand(create, MindMapUtils - .toModelPosition(position)), false); - builder.addSource(create.getSource(), true); - builder.end(); - - select(builder.getCommand().getSources(), viewer); -// saveAndRun(cmd, request.getTargetDomain()); -// -// if (cmd instanceof ISourceProvider) { -// List sources = ((ISourceProvider) cmd).getSources(); -// if (!sources.isEmpty()) { -// select(sources, viewer); -// if (isAnimationRequired(request)) -// animateCommand(cmd, viewer); -// } -// } - } - -// protected void doAnimateCommand(Command cmd, IAnimationService anim, -// IViewer viewer) { -// List creations = ((ISourceProvider) cmd).getSources(); -// final List minimizables = getMinimizables(creations, -// viewer); -// if (minimizables.isEmpty()) -// return; -// for (IMinimizable min : minimizables) { -// min.setMinimized(true); -// } -// ((GraphicalViewer) viewer).getLightweightSystem().getUpdateManager() -// .performValidation(); -// super.doAnimateCommand(cmd, anim, viewer); -// } -// -// protected void createAnimation(Command cmd, IViewer viewer) { -// List creations = ((ISourceProvider) cmd).getSources(); -// final List minimizables = getMinimizables(creations, -// viewer); -// for (IMinimizable min : minimizables) { -// min.setMinimized(false); -// } -// } -// -// private List getMinimizables(List creations, -// IViewer viewer) { -// List list = new ArrayList(creations.size()); -// for (Object o : creations) { -// IPart part = viewer.findPart(o); -// if (part instanceof IGraphicalPart) { -// IFigure figure = ((IGraphicalPart) part).getFigure(); -// if (figure instanceof IMinimizable) { -// list.add((IMinimizable) figure); -// } -// } -// } -// return list; -// } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import org.eclipse.draw2d.geometry.Point; +import org.xmind.core.IRelationshipEnd; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.CreateTopicCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class SheetCreatablePolicy extends MindMapPolicyBase { + + public boolean understands(String requestType) { + return super.understands(requestType) + || MindMapUI.REQ_CREATE_FLOAT.equals(requestType) + || MindMapUI.REQ_CREATE_RELATIONSHIP.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (MindMapUI.REQ_CREATE_FLOAT.equals(reqType)) { + createFloatingTopic(request); + } else if (MindMapUI.REQ_CREATE_RELATIONSHIP.equals(reqType)) { + createRelationship(request); + } + } + + private void createRelationship(Request request) { + IPart sourceNode = (IPart) request + .getParameter(MindMapUI.PARAM_SOURCE_NODE); + if (sourceNode == null) + return; + + Object m1 = MindMapUtils.getRealModel(sourceNode); + if (!(m1 instanceof IRelationshipEnd)) + return; + + IRelationshipEnd end1 = (IRelationshipEnd) m1; + + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return; + + ISheet parent = (ISheet) viewer.getAdapter(ISheet.class); + if (parent == null) + return; + + RelationshipCreateCommandBuilder builder = new RelationshipCreateCommandBuilder( + viewer, request.getTargetCommandStack(), parent, end1); + if (builder.canStart()) { + builder.start(); + + IPart targetNode = (IPart) request + .getParameter(MindMapUI.PARAM_TARGET_NODE); + if (targetNode != null) { + Object m2 = MindMapUtils.getRealModel(targetNode); + if (m2 instanceof IRelationshipEnd) + builder.create((IRelationshipEnd) m2); + } else { + Point targetPosition = (Point) request + .getParameter(GEF.PARAM_POSITION); + if (targetPosition != null) { + builder.create(targetPosition); + } + } + + builder.end(); + + select(builder.getCommand().getSources(), viewer); + } + +// IRelationshipEnd end2 = null; +// IPart targetNode = (IPart) request +// .getParameter(MindMapUI.PARAM_TARGET_NODE); +// if (targetNode != null) { +// Object m2 = MindMapUtils.getRealModel(targetNode); +// if (m2 instanceof IRelationshipEnd) +// end2 = (IRelationshipEnd) m2; +// } else { +// +// } +// +// if (end2 != null) { +// Command cmd = createCreateRelationship(parent, end1, end2); +// cmd.setLabel(CommandMessages.Command_CreateRelationship); +// if (cmd != null) { +// saveAndRun(cmd, request.getTargetDomain()); +// if (cmd instanceof ISourceProvider) { +// select(((ISourceProvider) cmd).getSources(), viewer); +// } +// } +// } + } + +// private Command createCreateRelationship(ISheet parent, +// IRelationshipEnd end1, IRelationshipEnd end2) { +// IWorkbook workbook = parent.getOwnedWorkbook(); +// if (workbook == null) +// return null; +// CreateRelationshipCommand create = new CreateRelationshipCommand( +// workbook); +// ModifyRelationshipEndCommand setEnd1 = new ModifyRelationshipEndCommand( +// create, end1.getId(), true); +// ModifyRelationshipEndCommand setEnd2 = new ModifyRelationshipEndCommand( +// create, end2.getId(), false); +// AddRelationshipCommand add = new AddRelationshipCommand(create, parent); +// return new CompoundCommand(create, setEnd1, setEnd2, add); +// } + + private void createFloatingTopic(Request request) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return; + + ITopic rootTopic = (ITopic) viewer.getAdapter(ITopic.class); + if (rootTopic == null) + return; + + Point position = (Point) request.getParameter(GEF.PARAM_POSITION); + if (position == null) + return; + + PropertyCommandBuilder builder = new PropertyCommandBuilder(request); + if (!builder.canStart()) + return; + + builder.start(); + builder.setLabel(CommandMessages.Command_CreateFloatingTopic); + CreateTopicCommand create = new CreateTopicCommand( + rootTopic.getOwnedWorkbook()); + builder.add(create, true); + builder.add( + new AddTopicCommand(create, rootTopic, -1, ITopic.DETACHED), + false); + builder.add(new ModifyTitleTextCommand(create, + MindMapMessages.TitleText_FloatingTopic), false); + builder.add( + new ModifyPositionCommand(create, MindMapUtils + .toModelPosition(position)), false); + builder.addSource(create.getSource(), true); + builder.end(); + + select(builder.getCommand().getSources(), viewer); +// saveAndRun(cmd, request.getTargetDomain()); +// +// if (cmd instanceof ISourceProvider) { +// List sources = ((ISourceProvider) cmd).getSources(); +// if (!sources.isEmpty()) { +// select(sources, viewer); +// if (isAnimationRequired(request)) +// animateCommand(cmd, viewer); +// } +// } + } + +// protected void doAnimateCommand(Command cmd, IAnimationService anim, +// IViewer viewer) { +// List creations = ((ISourceProvider) cmd).getSources(); +// final List minimizables = getMinimizables(creations, +// viewer); +// if (minimizables.isEmpty()) +// return; +// for (IMinimizable min : minimizables) { +// min.setMinimized(true); +// } +// ((GraphicalViewer) viewer).getLightweightSystem().getUpdateManager() +// .performValidation(); +// super.doAnimateCommand(cmd, anim, viewer); +// } +// +// protected void createAnimation(Command cmd, IViewer viewer) { +// List creations = ((ISourceProvider) cmd).getSources(); +// final List minimizables = getMinimizables(creations, +// viewer); +// for (IMinimizable min : minimizables) { +// min.setMinimized(false); +// } +// } +// +// private List getMinimizables(List creations, +// IViewer viewer) { +// List list = new ArrayList(creations.size()); +// for (Object o : creations) { +// IPart part = viewer.findPart(o); +// if (part instanceof IGraphicalPart) { +// IFigure figure = ((IGraphicalPart) part).getFigure(); +// if (figure instanceof IMinimizable) { +// list.add((IMinimizable) figure); +// } +// } +// } +// return list; +// } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SortTopicCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SortTopicCommandBuilder.java index fdc5ae58d..501fa9156 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SortTopicCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/SortTopicCommandBuilder.java @@ -1,343 +1,343 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.xmind.core.IBoundary; -import org.xmind.core.IRelationship; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicRange; -import org.xmind.core.IWorkbook; -import org.xmind.core.marker.IMarkerRef; -import org.xmind.core.util.Point; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.ui.commands.AddBoundaryCommand; -import org.xmind.ui.commands.AddRelationshipCommand; -import org.xmind.ui.commands.AddSummaryCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.internal.actions.ActionConstants; -import org.xmind.ui.internal.dialogs.DialogMessages; - -/** - * @author Karelun Huang - */ -public class SortTopicCommandBuilder extends DeleteCommandBuilder { - - private class Range { - int startIndex; - int endIndex; - - public Range(int startIndex, int endIndex) { - this.startIndex = startIndex; - this.endIndex = endIndex; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj != this && !(obj instanceof Range)) - return false; - Range that = (Range) obj; - return this.startIndex == that.startIndex - && this.endIndex == that.endIndex; - } - } - - private String type; - - private Map cacheRanges = null; - - private List cacheRelations = null; - - private Map cacheSummaryTopics = null; - - public SortTopicCommandBuilder(IViewer viewer, ICommandStack commandStack) { - super(viewer, commandStack); - } - - public void setSortType(String type) { - this.type = type; - } - - public void sort(ITopic parent) { - List children = new ArrayList( - parent.getChildren(ITopic.ATTACHED)); - if (children.isEmpty()) - return; - cacheRelationships(parent); - cacheTopicRanges(parent); - List topics = resort(children); - if (!canResort(topics)) { - MessageDialog.openWarning(null, - DialogMessages.SortMessageDialog_Title, - DialogMessages.SortMessageDialog_Messages); - return; - } - - for (ITopic topic : children) { - deleteTopic(topic, true); - } - children.clear(); - - for (int i = 0; i < topics.size(); i++) { - ITopic topic = topics.get(i); - addTopic(topic, parent, i); - modifyTopicPosition(topic); - } - topics.clear(); - - addRelationships(parent); - addTopicRanges(parent); - } - - private void modifyTopicPosition(ITopic topic) { - Point position = topic.getPosition(); - if (position == null) - return; - ModifyPositionCommand command = new ModifyPositionCommand(topic, null); - add(command, true); - - } - - private boolean canResort(List topics) { - if (cacheRanges == null) - return true; - for (Entry entry : cacheRanges.entrySet()) { - ITopicRange topicRange = entry.getKey(); - List enTopics = topicRange.getEnclosingTopics(); - if (enTopics.isEmpty() || enTopics.size() == 1) - continue; - List newIndexList = null; - for (ITopic topic : enTopics) { - int index = topics.indexOf(topic); - if (newIndexList == null) - newIndexList = new ArrayList(); - newIndexList.add(index); - } - Collections.sort(newIndexList, new Comparator() { - public int compare(Integer o1, Integer o2) { - return o1 - o2; - } - }); - int flag = -1; - for (int index : newIndexList) { - if (flag == -1) { - flag = index; - continue; - } - if (Math.abs(flag - index) > 1) - return false; - flag = index; - } - int startIndex = newIndexList.get(0); - int endIndex = newIndexList.get(newIndexList.size() - 1); - Range range = entry.getValue(); - range.startIndex = startIndex; - range.endIndex = endIndex; - newIndexList.clear(); - } - return true; - } - - private void cacheRelationships(ITopic topic) { - ISheet sheet = topic.getOwnedSheet(); - Set relations = sheet.getRelationships(); - if (relations.isEmpty()) - return; - Iterator itera = relations.iterator(); - while (itera.hasNext()) { - IRelationship next = itera.next(); - if (canAddInCache(topic, next)) { - if (cacheRelations == null) - cacheRelations = new ArrayList(); - cacheRelations.add(next); - } - } - } - - private boolean canAddInCache(ITopic topic, IRelationship raltionship) { - IWorkbook workbook = topic.getOwnedWorkbook(); - String end1Id = raltionship.getEnd1Id(); - String end2Id = raltionship.getEnd2Id(); - Object obj1 = workbook.getElementById(end1Id); - Object obj2 = workbook.getElementById(end2Id); - return isPosterity(topic, obj1) || isPosterity(topic, obj2); - } - - private boolean isPosterity(ITopic parent, Object obj) { - if (obj instanceof ITopicRange) { - return isPosterityOfRange(parent, (ITopicRange) obj); - } else if (obj instanceof ITopic) { - return isPosterityOfTopic(parent, (ITopic) obj); - } - return false; - } - - private boolean isPosterityOfTopic(ITopic parent, ITopic topic) { - if (topic.isRoot()) - return false; - ITopic parentTopic = topic.getParent(); - if (parentTopic.equals(parent)) - return true; - if (parentTopic.isRoot()) - return false; - return isPosterityOfTopic(parentTopic, topic); - } - - private boolean isPosterityOfRange(ITopic parent, ITopicRange topicRange) { - ITopic parentTopic = topicRange.getParent(); - if (parentTopic.equals(parent)) - return true; - if (parentTopic.isRoot()) - return false; - return isPosterityOfRange(parentTopic, topicRange); - } - - private void addRelationships(ITopic parent) { - if (cacheRelations == null || cacheRelations.isEmpty()) - return; - for (IRelationship relationship : cacheRelations) { - AddRelationshipCommand command = new AddRelationshipCommand( - relationship, parent.getOwnedSheet()); - add(command, true); - } - } - - private void addTopicRanges(ITopic parent) { - if (cacheRanges == null || cacheRanges.isEmpty()) - return; - for (Entry entry : cacheRanges.entrySet()) { - ITopicRange topicRange = entry.getKey(); - Range range = entry.getValue(); - if (topicRange instanceof ISummary) { - ISummary summary = (ISummary) topicRange; - ITopic summaryTopic = cacheSummaryTopics.get(summary); - AddTopicCommand addTopicCommand = new AddTopicCommand( - summaryTopic, parent, -1, ITopic.SUMMARY); - add(addTopicCommand, false); - AddSummaryCommand summaryCommand = new AddSummaryCommand( - summary, parent); - add(summaryCommand, false); - } else if (topicRange instanceof IBoundary) { - IBoundary boundary = (IBoundary) topicRange; - AddBoundaryCommand boundaryCommand = new AddBoundaryCommand( - boundary, parent); - add(boundaryCommand, false); - } - ModifyRangeCommand modifyStart = new ModifyRangeCommand(topicRange, - range.startIndex, true); - add(modifyStart, false); - ModifyRangeCommand modifyend = new ModifyRangeCommand(topicRange, - range.endIndex, false); - add(modifyend, false); - } - } - - private void cacheTopicRanges(ITopic parent) { - if (cacheRanges == null) - cacheRanges = new HashMap(); - if (cacheSummaryTopics == null) - cacheSummaryTopics = new HashMap(); - Set boundaries = parent.getBoundaries(); - if (!boundaries.isEmpty()) { - Iterator itera = boundaries.iterator(); - while (itera.hasNext()) { - IBoundary next = itera.next(); - if (!next.isMasterBoundary()) { - int startIndex = next.getStartIndex(); - int endIndex = next.getEndIndex(); - if (startIndex >= 0 && endIndex >= 0) { - cacheRanges.put(next, new Range(startIndex, endIndex)); - } - } - } - } - Set summaries = parent.getSummaries(); - if (!summaries.isEmpty()) { - Iterator itera = summaries.iterator(); - while (itera.hasNext()) { - ISummary next = itera.next(); - int startIndex = next.getStartIndex(); - int endIndex = next.getEndIndex(); - if (startIndex >= 0 && endIndex >= 0) { - ITopic summaryTopic = next.getTopic(); - cacheRanges.put(next, new Range(startIndex, endIndex)); - cacheSummaryTopics.put(next, summaryTopic); - } - } - } - } - - private void addTopic(ITopic topic, ITopic parent, int toIndex) { - AddTopicCommand command = new AddTopicCommand(topic, parent, toIndex, - ITopic.ATTACHED); - add(command, true); - } - - private List resort(List oldTopics) { - ArrayList newTopics = new ArrayList(oldTopics.size()); - for (ITopic topic : oldTopics) - newTopics.add(topic); - Collections.sort(newTopics, new Comparator() { - public int compare(ITopic o1, ITopic o2) { - if (ActionConstants.SORT_TITLE_ID.equals(type)) { - String text1 = o1.getTitleText(); - String text2 = o2.getTitleText(); - return text1.compareToIgnoreCase(text2); - } else if (ActionConstants.SORT_PRIORITY_ID.equals(type)) { - int p1 = getPriority(o1); - int p2 = getPriority(o2); - return p1 - p2; - } else if (ActionConstants.SORT_MODIFIED_ID.equals(type)) { - long time1 = o1.getModifiedTime(); - long time2 = o2.getModifiedTime(); - long ex = time1 - time2; - return (int) ex; - } - return 0; - } - - }); - return newTopics; - } - - private int getPriority(ITopic topic) { - Iterator itera = topic.getMarkerRefs().iterator(); - while (itera.hasNext()) { - IMarkerRef next = itera.next(); - String markerId = next.getMarkerId(); - if (markerId.startsWith("priority")) { //$NON-NLS-1$ - int index = markerId.indexOf('-'); - String number = markerId.substring(index + 1); - return Integer.parseInt(number); - } - } - return Integer.MAX_VALUE; - } -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.xmind.core.IBoundary; +import org.xmind.core.IRelationship; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicRange; +import org.xmind.core.IWorkbook; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.core.util.Point; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.ui.commands.AddBoundaryCommand; +import org.xmind.ui.commands.AddRelationshipCommand; +import org.xmind.ui.commands.AddSummaryCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.internal.actions.ActionConstants; +import org.xmind.ui.internal.dialogs.DialogMessages; + +/** + * @author Karelun Huang + */ +public class SortTopicCommandBuilder extends DeleteCommandBuilder { + + private class Range { + int startIndex; + int endIndex; + + public Range(int startIndex, int endIndex) { + this.startIndex = startIndex; + this.endIndex = endIndex; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj != this && !(obj instanceof Range)) + return false; + Range that = (Range) obj; + return this.startIndex == that.startIndex + && this.endIndex == that.endIndex; + } + } + + private String type; + + private Map cacheRanges = null; + + private List cacheRelations = null; + + private Map cacheSummaryTopics = null; + + public SortTopicCommandBuilder(IViewer viewer, ICommandStack commandStack) { + super(viewer, commandStack); + } + + public void setSortType(String type) { + this.type = type; + } + + public void sort(ITopic parent) { + List children = new ArrayList( + parent.getChildren(ITopic.ATTACHED)); + if (children.isEmpty()) + return; + cacheRelationships(parent); + cacheTopicRanges(parent); + List topics = resort(children); + if (!canResort(topics)) { + MessageDialog.openWarning(null, + DialogMessages.SortMessageDialog_Title, + DialogMessages.SortMessageDialog_Messages); + return; + } + + for (ITopic topic : children) { + deleteTopic(topic, true); + } + children.clear(); + + for (int i = 0; i < topics.size(); i++) { + ITopic topic = topics.get(i); + addTopic(topic, parent, i); + modifyTopicPosition(topic); + } + topics.clear(); + + addRelationships(parent); + addTopicRanges(parent); + } + + private void modifyTopicPosition(ITopic topic) { + Point position = topic.getPosition(); + if (position == null) + return; + ModifyPositionCommand command = new ModifyPositionCommand(topic, null); + add(command, true); + + } + + private boolean canResort(List topics) { + if (cacheRanges == null) + return true; + for (Entry entry : cacheRanges.entrySet()) { + ITopicRange topicRange = entry.getKey(); + List enTopics = topicRange.getEnclosingTopics(); + if (enTopics.isEmpty() || enTopics.size() == 1) + continue; + List newIndexList = null; + for (ITopic topic : enTopics) { + int index = topics.indexOf(topic); + if (newIndexList == null) + newIndexList = new ArrayList(); + newIndexList.add(index); + } + Collections.sort(newIndexList, new Comparator() { + public int compare(Integer o1, Integer o2) { + return o1 - o2; + } + }); + int flag = -1; + for (int index : newIndexList) { + if (flag == -1) { + flag = index; + continue; + } + if (Math.abs(flag - index) > 1) + return false; + flag = index; + } + int startIndex = newIndexList.get(0); + int endIndex = newIndexList.get(newIndexList.size() - 1); + Range range = entry.getValue(); + range.startIndex = startIndex; + range.endIndex = endIndex; + newIndexList.clear(); + } + return true; + } + + private void cacheRelationships(ITopic topic) { + ISheet sheet = topic.getOwnedSheet(); + Set relations = sheet.getRelationships(); + if (relations.isEmpty()) + return; + Iterator itera = relations.iterator(); + while (itera.hasNext()) { + IRelationship next = itera.next(); + if (canAddInCache(topic, next)) { + if (cacheRelations == null) + cacheRelations = new ArrayList(); + cacheRelations.add(next); + } + } + } + + private boolean canAddInCache(ITopic topic, IRelationship raltionship) { + IWorkbook workbook = topic.getOwnedWorkbook(); + String end1Id = raltionship.getEnd1Id(); + String end2Id = raltionship.getEnd2Id(); + Object obj1 = workbook.getElementById(end1Id); + Object obj2 = workbook.getElementById(end2Id); + return isPosterity(topic, obj1) || isPosterity(topic, obj2); + } + + private boolean isPosterity(ITopic parent, Object obj) { + if (obj instanceof ITopicRange) { + return isPosterityOfRange(parent, (ITopicRange) obj); + } else if (obj instanceof ITopic) { + return isPosterityOfTopic(parent, (ITopic) obj); + } + return false; + } + + private boolean isPosterityOfTopic(ITopic parent, ITopic topic) { + if (topic.isRoot()) + return false; + ITopic parentTopic = topic.getParent(); + if (parentTopic.equals(parent)) + return true; + if (parentTopic.isRoot()) + return false; + return isPosterityOfTopic(parentTopic, topic); + } + + private boolean isPosterityOfRange(ITopic parent, ITopicRange topicRange) { + ITopic parentTopic = topicRange.getParent(); + if (parentTopic.equals(parent)) + return true; + if (parentTopic.isRoot()) + return false; + return isPosterityOfRange(parentTopic, topicRange); + } + + private void addRelationships(ITopic parent) { + if (cacheRelations == null || cacheRelations.isEmpty()) + return; + for (IRelationship relationship : cacheRelations) { + AddRelationshipCommand command = new AddRelationshipCommand( + relationship, parent.getOwnedSheet()); + add(command, true); + } + } + + private void addTopicRanges(ITopic parent) { + if (cacheRanges == null || cacheRanges.isEmpty()) + return; + for (Entry entry : cacheRanges.entrySet()) { + ITopicRange topicRange = entry.getKey(); + Range range = entry.getValue(); + if (topicRange instanceof ISummary) { + ISummary summary = (ISummary) topicRange; + ITopic summaryTopic = cacheSummaryTopics.get(summary); + AddTopicCommand addTopicCommand = new AddTopicCommand( + summaryTopic, parent, -1, ITopic.SUMMARY); + add(addTopicCommand, false); + AddSummaryCommand summaryCommand = new AddSummaryCommand( + summary, parent); + add(summaryCommand, false); + } else if (topicRange instanceof IBoundary) { + IBoundary boundary = (IBoundary) topicRange; + AddBoundaryCommand boundaryCommand = new AddBoundaryCommand( + boundary, parent); + add(boundaryCommand, false); + } + ModifyRangeCommand modifyStart = new ModifyRangeCommand(topicRange, + range.startIndex, true); + add(modifyStart, false); + ModifyRangeCommand modifyend = new ModifyRangeCommand(topicRange, + range.endIndex, false); + add(modifyend, false); + } + } + + private void cacheTopicRanges(ITopic parent) { + if (cacheRanges == null) + cacheRanges = new HashMap(); + if (cacheSummaryTopics == null) + cacheSummaryTopics = new HashMap(); + Set boundaries = parent.getBoundaries(); + if (!boundaries.isEmpty()) { + Iterator itera = boundaries.iterator(); + while (itera.hasNext()) { + IBoundary next = itera.next(); + if (!next.isMasterBoundary()) { + int startIndex = next.getStartIndex(); + int endIndex = next.getEndIndex(); + if (startIndex >= 0 && endIndex >= 0) { + cacheRanges.put(next, new Range(startIndex, endIndex)); + } + } + } + } + Set summaries = parent.getSummaries(); + if (!summaries.isEmpty()) { + Iterator itera = summaries.iterator(); + while (itera.hasNext()) { + ISummary next = itera.next(); + int startIndex = next.getStartIndex(); + int endIndex = next.getEndIndex(); + if (startIndex >= 0 && endIndex >= 0) { + ITopic summaryTopic = next.getTopic(); + cacheRanges.put(next, new Range(startIndex, endIndex)); + cacheSummaryTopics.put(next, summaryTopic); + } + } + } + } + + private void addTopic(ITopic topic, ITopic parent, int toIndex) { + AddTopicCommand command = new AddTopicCommand(topic, parent, toIndex, + ITopic.ATTACHED); + add(command, true); + } + + private List resort(List oldTopics) { + ArrayList newTopics = new ArrayList(oldTopics.size()); + for (ITopic topic : oldTopics) + newTopics.add(topic); + Collections.sort(newTopics, new Comparator() { + public int compare(ITopic o1, ITopic o2) { + if (ActionConstants.SORT_TITLE_ID.equals(type)) { + String text1 = o1.getTitleText(); + String text2 = o2.getTitleText(); + return text1.compareToIgnoreCase(text2); + } else if (ActionConstants.SORT_PRIORITY_ID.equals(type)) { + int p1 = getPriority(o1); + int p2 = getPriority(o2); + return p1 - p2; + } else if (ActionConstants.SORT_MODIFIED_ID.equals(type)) { + long time1 = o1.getModifiedTime(); + long time2 = o2.getModifiedTime(); + long ex = time1 - time2; + return (int) ex; + } + return 0; + } + + }); + return newTopics; + } + + private int getPriority(ITopic topic) { + Iterator itera = topic.getMarkerRefs().iterator(); + while (itera.hasNext()) { + IMarkerRef next = itera.next(); + String markerId = next.getMarkerId(); + if (markerId.startsWith("priority")) { //$NON-NLS-1$ + int index = markerId.indexOf('-'); + String number = markerId.substring(index + 1); + return Integer.parseInt(number); + } + } + return Integer.MAX_VALUE; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicCreatablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicCreatablePolicy.java index 254833615..10bf4ad5c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicCreatablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicCreatablePolicy.java @@ -1,1129 +1,1132 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.internal.DPIUtil; -import org.eclipse.swt.widgets.Display; -import org.xmind.core.Core; -import org.xmind.core.IBoundary; -import org.xmind.core.ICloneData; -import org.xmind.core.IFileEntry; -import org.xmind.core.ISheet; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.IWorkbook; -import org.xmind.core.marker.IMarker; -import org.xmind.core.marker.IMarkerGroup; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.gef.GEF; -import org.xmind.gef.GraphicalViewer; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.draw2d.geometry.Geometry; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.graphicalpolicy.IStyleSelector; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.service.IAnimationService; -import org.xmind.ui.branch.IBranchStructureExtension; -import org.xmind.ui.branch.ICreatableBranchStructureExtension; -import org.xmind.ui.commands.AddBoundaryCommand; -import org.xmind.ui.commands.AddMarkerCommand; -import org.xmind.ui.commands.AddSummaryCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.CreateBoundaryCommand; -import org.xmind.ui.commands.CreateSummaryCommand; -import org.xmind.ui.commands.CreateTopicCommand; -import org.xmind.ui.commands.DeleteMarkerCommand; -import org.xmind.ui.commands.ModifyBoundaryMasterCommand; -import org.xmind.ui.commands.ModifyImageSizeCommand; -import org.xmind.ui.commands.ModifyImageSourceCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; -import org.xmind.ui.commands.ModifySummaryTopicCommand; -import org.xmind.ui.commands.ModifyTitleTextCommand; -import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; -import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.branch.UnbalancedData; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.style.Styles; -import org.xmind.ui.util.ImageFormat; -import org.xmind.ui.util.MindMapUtils; - -public class TopicCreatablePolicy extends MindMapPolicyBase { - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_CREATE.equals(requestType) - || MindMapUI.REQ_CREATE_BEFORE.equals(requestType) - || MindMapUI.REQ_CREATE_CHILD.equals(requestType) - || MindMapUI.REQ_CREATE_PARENT.equals(requestType) - || MindMapUI.REQ_ADD_ATTACHMENT.equals(requestType) - || MindMapUI.REQ_ADD_MARKER.equals(requestType) - || MindMapUI.REQ_CREATE_BOUNDARY.equals(requestType) - || MindMapUI.REQ_CREATE_SUMMARY.equals(requestType) - || MindMapUI.REQ_ADD_IMAGE.equals(requestType) - || MindMapUI.REQ_CREATE_SHEET.equals(requestType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(requestType) - || MindMapUI.REQ_CREATE_CALLOUT.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (GEF.REQ_CREATE.equals(reqType) // - || MindMapUI.REQ_CREATE_CHILD.equals(reqType) // - || MindMapUI.REQ_CREATE_BEFORE.equals(reqType) // - || MindMapUI.REQ_CREATE_PARENT.equals(reqType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType) - || MindMapUI.REQ_CREATE_CALLOUT.equals(reqType)) { - createTopic(request); - } else if (MindMapUI.REQ_ADD_ATTACHMENT.equals(reqType)) { - addAttachments(request); - } else if (MindMapUI.REQ_ADD_MARKER.equals(reqType)) { - addMarker(request); - } else if (MindMapUI.REQ_CREATE_BOUNDARY.equals(reqType)) { - createBoundary(request); - } else if (MindMapUI.REQ_CREATE_SUMMARY.equals(reqType)) { - createSummary(request); - } else if (MindMapUI.REQ_ADD_IMAGE.equals(reqType)) { - addImage(request); - } else if (MindMapUI.REQ_CREATE_SHEET.equals(reqType)) { - createSheetFromTopic(request); - } - } - - private void createSheetFromTopic(Request request) { - List targets = request.getTargets(); - if (targets.isEmpty()) - return; - List topics = MindMapUtils.getTopics(targets); - if (topics.isEmpty()) - return; - - ITopic sourceTopic = topics.get(0); - CreateSheetFromTopicCommandBuilder builder = new CreateSheetFromTopicCommandBuilder( - request.getTargetViewer(), request.getTargetCommandStack(), - sourceTopic); - if (!builder.canStart()) - return; - - builder.start(); - builder.setLabel(CommandMessages.Command_CreateSheetFromTopic); - builder.run(); - builder.end(); - } - - private void createSummary(Request request) { - List targets = request.getTargets(); - Command cmd = createCreateSummaryCommand(request, targets); - if (cmd != null) { - cmd.setLabel(CommandMessages.Command_CreateSummary); - saveAndRun(cmd, request.getTargetDomain()); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources(), - request.getTargetViewer()); - } - } - } - - private Command createCreateSummaryCommand(Request request, - List targets) { - List topics = MindMapUtils.getTopics(targets); - if (topics.isEmpty()) - return null; - Map> map = categorize(topics, true); - List cmds = new ArrayList(map.size() * 3); - for (ITopic parent : map.keySet()) { - Command cmd = createCreateSummariesCommand(parent, map.get(parent)); - if (cmd != null) - cmds.add(cmd); - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createCreateSummariesCommand(ITopic parent, - Collection topics) { - if (topics.isEmpty()) - return null; - List ranges = getRanges(topics); - List cmds = new ArrayList(ranges.size()); - for (Range range : ranges) { - if (!hasSameSummary(parent, range)) { - Command cmd = createCreateSummaryCommand(parent, range); - if (cmd != null) - cmds.add(cmd); - } - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createCreateSummaryCommand(ITopic parent, Range range) { - IWorkbook workbook = parent.getOwnedWorkbook(); - CreateSummaryCommand createSummary = new CreateSummaryCommand(workbook); - ModifyRangeCommand modifyStart = new ModifyRangeCommand(createSummary, - range.start, true); - ModifyRangeCommand modifyEnd = new ModifyRangeCommand(createSummary, - range.end, false); - CreateTopicCommand createSummaryTopic = new CreateTopicCommand( - workbook); - ModifyTitleTextCommand modifyTitle = new ModifyTitleTextCommand( - createSummaryTopic, MindMapMessages.TitleText_SummaryTopic); - ModifySummaryTopicCommand modifySummaryTopic = new ModifySummaryTopicCommand( - createSummary, createSummaryTopic); - AddSummaryCommand addSummary = new AddSummaryCommand(createSummary, - parent); - AddTopicCommand addSummaryTopic = new AddTopicCommand( - createSummaryTopic, parent, -1, ITopic.SUMMARY); - createSummary.setSourceCollectable(false); - modifyStart.setSourceCollectable(false); - modifyEnd.setSourceCollectable(false); - modifySummaryTopic.setSourceCollectable(false); - addSummary.setSourceCollectable(false); - return new CompoundCommand(createSummary, modifyStart, modifyEnd, - createSummaryTopic, modifyTitle, modifySummaryTopic, addSummary, - addSummaryTopic); - } - - private boolean hasSameSummary(ITopic parent, Range range) { - for (ISummary b : parent.getSummaries()) { - int s = b.getStartIndex(); - int e = b.getEndIndex(); - if (s == range.start && e == range.end) - return true; - } - return false; - } - - private void createBoundary(Request request) { - List sources = request.getTargets(); - Command cmd = createCreateBoundariesCommand(request, sources); - if (cmd != null) { - cmd.setLabel(CommandMessages.Command_CreateBoundary); - saveAndRun(cmd, request.getTargetDomain()); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources(), - request.getTargetViewer()); - } - } - } - - private Command createCreateBoundariesCommand(Request request, - List sources) { - List topics = MindMapUtils.getTopics(sources); - if (topics.isEmpty()) - return null; - - Map> map = categorize(topics, false); - List cmds = new ArrayList(map.size() * 2); - for (ITopic parent : map.keySet()) { - Command cmd = createCreateBoundariesCommand(parent, - map.get(parent)); - if (cmd != null) - cmds.add(cmd); - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createCreateBoundariesCommand(ITopic parent, - Collection topics) { - if (topics.isEmpty()) - return null; - List ranges = getRanges(topics); - List cmds = new ArrayList(ranges.size()); - for (Range range : ranges) { - if (!hasSameBoundary(parent, range)) { - Command cmd = createCreateBoundaryCommand(parent, range); - if (cmd != null) - cmds.add(cmd); - } - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private boolean hasSameBoundary(ITopic parent, Range range) { - if (range.overTopic != null) { - for (IBoundary b : range.overTopic.getBoundaries()) { - if (b.isMasterBoundary()) - return true; - } - } - for (IBoundary b : parent.getBoundaries()) { - int s = b.getStartIndex(); - int e = b.getEndIndex(); - if (s == range.start && e == range.end) - return true; - } - return false; - } - - private List getRanges(Collection topics) { - ITopic[] ts = topics.toArray(new ITopic[topics.size()]); - Arrays.sort(ts, Core.getTopicComparator()); - List ranges = new ArrayList(ts.length); - Range r = null; - for (ITopic t : ts) { - String topicType = t.getType(); - if (ITopic.DETACHED.equals(topicType) - || ITopic.CALLOUT.equals(topicType) - || ITopic.SUMMARY.equals(topicType)) { - if (r != null) - ranges.add(r); - r = null; - ranges.add(new Range(t)); - } else { - int i = t.getIndex(); - if (i >= 0) { - if (r == null) { - r = new Range(i); - } else if (i == r.end + 1) { - r.end = i; - } else if (i > r.end + 1) { - ranges.add(r); - r = new Range(i); - } - } - } - } - if (r != null) { - ranges.add(r); - } - return ranges; - } - - private Command createCreateBoundaryCommand(ITopic parent, Range range) { - if (range.overTopic != null) { - CreateBoundaryCommand create = new CreateBoundaryCommand( - range.overTopic.getOwnedWorkbook()); - ModifyBoundaryMasterCommand modify = new ModifyBoundaryMasterCommand( - create, true); - AddBoundaryCommand add = new AddBoundaryCommand(create, - range.overTopic); - return new CompoundCommand(create, modify, add); - } - CreateBoundaryCommand create = new CreateBoundaryCommand( - parent.getOwnedWorkbook()); - ModifyRangeCommand modify1 = new ModifyRangeCommand(create, range.start, - true); - ModifyRangeCommand modify2 = new ModifyRangeCommand(create, range.end, - false); - AddBoundaryCommand add = new AddBoundaryCommand(create, parent); - return new CompoundCommand(create, modify1, modify2, add); - } - - private Map> categorize(List topics, - boolean onlyAttachedTopics) { - Map> map = new HashMap>(); - for (ITopic t : topics) { - ITopic p = t.getParent(); - if (p != null && (!onlyAttachedTopics || t.isAttached()) - && !isAncestorInCollection(p, topics)) { - Collection c = map.get(p); - if (c == null) { - c = new HashSet(); - map.put(p, c); - } - c.add(t); - } - } - return map; - } - - private boolean isAncestorInCollection(ITopic parent, - Collection topics) { - if (parent == null) - return false; - if (topics.contains(parent)) - return true; - return isAncestorInCollection(parent.getParent(), topics); - } - - private void addMarker(Request request) { - List targets = request.getTargets(); - Command cmd = createAddMarkerCommand(request, targets); - if (cmd != null) { - cmd.setLabel(CommandMessages.Command_AddMarker); - saveAndRun(cmd, request.getTargetDomain()); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources(), - request.getTargetViewer()); - } - } - } - - private Command createAddMarkerCommand(Request request, - List targets) { - String[] markerIds = getMarkerIds(request); - if (markerIds == null || markerIds.length == 0) - return null; - - List cmds = new ArrayList(targets.size()); - createAddMarkerCommand(targets, cmds, markerIds); - if (!cmds.isEmpty()) { - return new CompoundCommand(cmds); - } - return null; - } - - private String[] getMarkerIds(Request request) { - Object param = request.getParameter(MindMapUI.PARAM_MARKER_ID); - if (param instanceof String) - return new String[] { (String) param }; - if (param instanceof String[]) - return (String[]) param; - return null; - } - - private void createAddMarkerCommand(List targets, List cmds, - String... markerIds) { - for (IPart source : targets) { - Object m = MindMapUtils.getRealModel(source); - if (m instanceof ITopic) { - ITopic t = (ITopic) m; - for (String markerId : markerIds) { - createAddMarkerCommand(t, markerId, cmds); - } - } - } - } - - private void createAddMarkerCommand(ITopic topic, String newMarkerId, - List cmds) { - if (topic.hasMarker(newMarkerId)) - return; - - IMarker marker = findMarker(topic, newMarkerId); - if (marker != null) { - IMarkerGroup group = marker.getParent(); - IMarkerSheet sheet = marker.getOwnedSheet(); - if (!sheet.isPermanent()) { - IMarkerSheet markerSheet = topic.getOwnedWorkbook() - .getMarkerSheet(); - IMarker existingMarker = markerSheet.findMarker(marker.getId()); - if (existingMarker == null || !markerSheet - .equals(existingMarker.getOwnedSheet())) { - ICloneData cloneData = topic.getOwnedWorkbook() - .clone(Arrays.asList(marker)); - Object cloned = cloneData.get(marker); - if (cloned instanceof IMarker) { - marker = (IMarker) cloned; - group = marker.getParent(); - newMarkerId = marker.getId(); - } - } - } - if (group != null && group.isSingleton()) { - removeSingletonMarkers(topic, newMarkerId, group, cmds); - } - cmds.add(new AddMarkerCommand(topic, newMarkerId)); - } - } - - private IMarker findMarker(ITopic topic, String markerId) { - IWorkbook workbook = topic.getOwnedWorkbook(); - if (workbook != null) { - IMarkerSheet markerSheet = workbook.getMarkerSheet(); - if (markerSheet != null) { - IMarker ownedMarker = markerSheet.findMarker(markerId); - if (ownedMarker == null) { - ownedMarker = MindMapUI.getResourceManager() - .getUserMarkerSheet().findMarker(markerId); - } - return ownedMarker; - } - } - return null; - } - - private void removeSingletonMarkers(ITopic topic, String newMarkerId, - IMarkerGroup group, List cmds) { - for (IMarker m : group.getMarkers()) { - String markerId = m.getId(); - if (!newMarkerId.equals(markerId)) { - if (topic.hasMarker(markerId)) { - cmds.add(new DeleteMarkerCommand(topic, markerId)); - } - } - } - } - - private void addImage(Request request) { - List topics = MindMapUtils.getTopics(request.getTargets()); - if (topics.isEmpty()) - return; - - Command command = createAddImageCommand(request, topics); - if (command != null) { - command.setLabel(CommandMessages.Command_InsertImage); - saveAndRun(command, request.getTargetDomain()); - if (command instanceof ISourceProvider) { - select(((ISourceProvider) command).getSources(), - request.getTargetViewer()); - } - } - } - - private Command createAddImageCommand(Request request, - final List topics) { - String[] paths = getPaths(request); - if (paths == null || paths.length == 0) - return null; - - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return null; - - ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); - if (sheet == null) - return null; - - final IWorkbook workbook = sheet.getOwnedWorkbook(); - final String path = paths[0]; - final List cmds = new ArrayList(paths.length); - String errMsg = NLS.bind("Failed to copy file into this workbook: {0}", //$NON-NLS-1$ - path); - SafeRunner.run(new SafeRunnable(errMsg) { - public void run() throws Exception { - Command cmd = createAddImageCommand(workbook, path, topics); - if (cmd != null) - cmds.add(cmd); - } - }); - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createAddImageCommand(IWorkbook workbook, String path, - List topics) throws Exception { - Dimension size = getImageSize(path); - ImageFormat format = ImageFormat - .findByExtension(FileUtils.getExtension(path), ImageFormat.PNG); - IFileEntry e = workbook.getManifest().createAttachmentFromFilePath(path, - format.getMediaType()); - if (e == null) - return null; - - String entryPath = e.getPath(); - String hyperlink = HyperlinkUtils.toAttachmentURL(entryPath); - - List cmds = new ArrayList(topics.size()); - for (ITopic t : topics) { - Command cmd = createAddImageCommand(t, hyperlink, size); - if (cmd != null) - cmds.add(cmd); - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Dimension getImageSize(String path) { - try { - Image tempImage = new Image(Display.getCurrent(), path); - Rectangle imageBounds = tempImage.getBounds(); - tempImage.dispose(); - boolean needZoom = DPIUtil.getDeviceZoom() > 100; - int width = needZoom ? imageBounds.width / 2 : imageBounds.width; - int height = needZoom ? imageBounds.height / 2 : imageBounds.height; - return Geometry.getScaledConstrainedSize(width, height, - MindMapUI.IMAGE_INIT_WIDTH, MindMapUI.IMAGE_INIT_HEIGHT); - } catch (Throwable e) { - } - return null; - } - - private Command createAddImageCommand(ITopic t, String hyperlink, - Dimension size) { - ModifyImageSourceCommand modifyImageSource = new ModifyImageSourceCommand( - t, hyperlink); - - if (size != null) { - ModifyImageSizeCommand modifySize = new ModifyImageSizeCommand(t, - size.width, size.height); - return new CompoundCommand(modifyImageSource, modifySize); - } else { - return new CompoundCommand(modifyImageSource); - } - } - - private void addAttachments(Request request) { - String[] paths = getPaths(request); - if (paths == null || paths.length == 0) - return; - - List topics = MindMapUtils.getTopics(request.getTargets()); - if (topics.isEmpty()) - return; - - Command cmd = createAddAttachmentCommand(request, topics, paths); - if (cmd != null) { - cmd.setLabel(CommandMessages.Command_InsertAttachment); - saveAndRun(cmd, request.getTargetDomain()); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources(), - request.getTargetViewer()); - } - } - } - - private Command createAddAttachmentCommand(Request request, - final List topics, String[] paths) { - IViewer viewer = request.getTargetViewer(); - if (viewer == null) - return null; - - ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); - if (sheet == null) - return null; - - final IWorkbook workbook = sheet.getOwnedWorkbook(); - final List cmds = new ArrayList(paths.length); - for (final String path : paths) { - String errMsg = NLS - .bind("Failed to copy file into this workbook: {0}", path); //$NON-NLS-1$ - SafeRunner.run(new SafeRunnable(errMsg) { - public void run() throws Exception { - Command cmd = createAddAttachmentCommand(workbook, path, - topics); - if (cmd != null) - cmds.add(cmd); - } - }); - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createAddAttachmentCommand(IWorkbook workbook, String path, - List topics) throws IOException { - IFileEntry e = workbook.getManifest() - .createAttachmentFromFilePath(path); - if (e == null) - return null; - - String hyperlink = HyperlinkUtils.toAttachmentURL(e.getPath()); - String title = new File(path).getName(); - - List cmds = new ArrayList(topics.size()); - for (ITopic t : topics) { - Command cmd = createAddAttachmentCommand(t, title, hyperlink); - if (cmd != null) - cmds.add(cmd); - } - if (cmds.isEmpty()) - return null; - return new CompoundCommand(cmds); - } - - private Command createAddAttachmentCommand(ITopic parent, String title, - String hyperlink) { - CreateTopicCommand create = new CreateTopicCommand( - parent.getOwnedWorkbook()); - - AddTopicCommand insert = new AddTopicCommand(create, parent, -1, - ITopic.ATTACHED); - - ModifyTitleTextCommand setTitle = new ModifyTitleTextCommand(create, - title); - - ModifyTopicHyperlinkCommand setHyperlink = new ModifyTopicHyperlinkCommand( - create, hyperlink); - - return new CompoundCommand(create, insert, setTitle, setHyperlink); - } - - private String[] getPaths(Request request) { - Object param = request.getParameter(GEF.PARAM_PATH); - if (param instanceof String) - return new String[] { (String) param }; - if (param instanceof String[]) - return (String[]) param; - return null; - } - - private void createTopic(Request request) { - IPart source = request.getPrimaryTarget(); - IBranchPart sourceBranch = MindMapUtils.findBranch(source); - if (sourceBranch == null) - return; - - ITopic sourceTopic = sourceBranch.getTopic(); - String reqType = request.getType(); - if (GEF.REQ_CREATE.equals(reqType)) { - if (ITopic.SUMMARY.equals(sourceTopic.getType())) - return; - if (sourceBranch.isCentral()) { - reqType = MindMapUI.REQ_CREATE_CHILD;// - } - } else if (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) - || MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType)) { - if (ITopic.SUMMARY.equals(sourceTopic.getType())) - return; - } else if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { - if (sourceBranch.isCentral()) - return; - } - - IViewer viewer = request.getTargetViewer(); - ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - if (centralTopic == null) - return; - - CreateTopicCommandBuilder builder = null; - List topics = null; - if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { - topics = MindMapUtils.filterOutDescendents( - MindMapUtils.getTopics(request.getTargets()), null); - sort(topics); - - if (!topics.isEmpty()) - sourceTopic = topics.get(0); - - builder = new CreateTopicCommandBuilder(viewer, - request.getTargetCommandStack(), sourceTopic, reqType, - topics); - } else { - builder = new CreateTopicCommandBuilder(viewer, - request.getTargetCommandStack(), sourceTopic, reqType); - } - - if (!builder.canStart()) - return; - - if (ITopic.ATTACHED.equals(builder.getTargetType())) { - IPart parentPart = viewer.findPart(builder.getTargetParent()); - if (parentPart instanceof ITopicPart) { - IBranchPart parentBranch = ((ITopicPart) parentPart) - .getOwnerBranch(); - if (parentBranch != null) { - IBranchPart sourceChild; - if (parentBranch.getSubBranches().contains(sourceBranch)) { - sourceChild = sourceBranch; - } else { - sourceChild = null; - } - - IStructure structure = parentBranch.getBranchPolicy() - .getStructure(parentBranch); - if (structure instanceof ICreatableBranchStructureExtension) { - ((ICreatableBranchStructureExtension) structure) - .decorateCreateRequest(parentBranch, - sourceChild, request); - } - - String centralTopicStructure = centralTopic - .getStructureClass(); - boolean isUnbalancedStructure = centralTopicStructure == null - || UnbalancedData.STRUCTUREID_UNBALANCED - .equalsIgnoreCase(centralTopicStructure); - if (isUnbalancedStructure) { - ITopicExtension extension = centralTopic - .createExtension( - UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild( - UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - String preCreateRightNum = element.getTextContent(); - if (preCreateRightNum == null) - preCreateRightNum = String.valueOf(0); - int postCreateRightNum = Integer - .valueOf(preCreateRightNum).intValue(); - - if (parentBranch.isCentral()) { - - int deletedRightNum = 0; - if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { - if (topics != null && !topics.isEmpty()) { - for (ITopic rightTopic : topics) { - if (rightTopic - .getParent() == centralTopic - && rightTopic - .getIndex() <= postCreateRightNum - - 1) - deletedRightNum++; - } - } - } - - List mainBranches = parentBranch - .getSubBranches(); - int size = mainBranches.size(); - if ((((IBranchStructureExtension) structure) - .getChildTargetOrientation(parentBranch, - sourceBranch) == PositionConstants.WEST - && parentBranch != sourceBranch) - || (parentBranch == sourceBranch - && size <= 2 - && postCreateRightNum == size)) { - postCreateRightNum++; - if (size > 2 - && (mainBranches.indexOf( - sourceBranch) == size - 1) - && !MindMapUI.REQ_CREATE_PARENT - .equals(reqType)) - postCreateRightNum--; - } - - postCreateRightNum = postCreateRightNum - - deletedRightNum; - - if (!preCreateRightNum.equals(postCreateRightNum)) { - ModifyRightNumberOfUnbalancedStructureCommand modifyRightNumberCommand = new ModifyRightNumberOfUnbalancedStructureCommand( - centralTopic, preCreateRightNum, - postCreateRightNum); - builder.addPendingCommand( - modifyRightNumberCommand, false); - //if sourceCollectable is true,the operations of create and move topic - //maybe lead to undo/redo error. - } - } - - } - - } - } - } - - PropertyCommandBuilder builder2 = new PropertyCommandBuilder(viewer, - builder, request); - builder.setLabel(CommandMessages.Command_CreateTopic); - builder.start(); - builder2.start(); - - if (MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType)) { - builder.createDuplicateTopic(); - } else { - builder.createTopic(); - } - - if (builder.getCreatedTopic() != null) { - builder2.addSource(builder.getCreatedTopic(), true); - } - - builder2.end(); - builder.end(); - - Command command = builder.getCommand(); - -// Command cmd = createCreateTopicCommand(request, sourceTopic, -// sourceBranch, request.getTargetViewer()); -// if (cmd == null) -// return; -// -// cmd.setLabel(CommandMessages.Command_CreateTopic); -// saveAndRun(cmd, request.getTargetDomain()); - - if (command instanceof ISourceProvider) { - Object creation = ((ISourceProvider) command).getSource(); - if (creation != null) { - boolean needSelect = true; - if (creation instanceof ITopic) { - ITopicPart topicPart = MindMapUtils - .getTopicPart((ITopic) creation); - IBranchPart branch = MindMapUtils.findBranch(topicPart); - IStyleSelector styleSelector = branch.getBranchPolicy() - .getStyleSelector(branch); - if (styleSelector != null) { - String hideCallout = styleSelector.getStyleValue(branch, - Styles.HideCallout); - needSelect = !(Boolean.parseBoolean(hideCallout) - && ITopic.CALLOUT - .equals(((ITopic) creation).getType())); - } - } - if (needSelect) - select(creation, request.getTargetViewer()); - if (isAnimationRequired(request)) - animateCommand(command, request.getTargetViewer()); - } - } - } - -// private Command createCreateTopicCommand(Request request, -// ITopic sourceTopic, IBranchPart sourceBranch, IViewer viewer) { -// CreateTopicCommand create = new CreateTopicCommand(sourceTopic -// .getOwnedWorkbook()); -// -// String reqType = request.getType(); -// ITopic parent = null; -// Command insert = null; -// int index = -1; -// String topicType = null; -// if (MindMapUI.REQ_CREATE_CHILD.equals(reqType)) { -// parent = sourceTopic; -// topicType = ITopic.ATTACHED; -// insert = new AddTopicCommand(create, parent, -1, topicType); -// index = parent.getChildren(topicType).size(); -// } else { -// parent = sourceTopic.getParent(); -// if (parent != null) { -// if (GEF.REQ_CREATE.equals(reqType)) { -// index = sourceTopic.getIndex() + 1; -// topicType = sourceTopic.getType(); -// insert = new AddTopicCommand(create, parent, index, -// topicType); -// } else if (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) -// || MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { -// index = sourceTopic.getIndex(); -// topicType = sourceTopic.getType(); -// insert = new AddTopicCommand(create, parent, index, -// topicType); -// } -// } -// } -// if (insert == null || topicType == null) -// return null; -// -// List cmds = new ArrayList(5); -// cmds.add(create); -// cmds.add(insert); -// -// if (parent != null && parent.isFolded()) { -// ModifyFoldedCommand extend = new ModifyFoldedCommand(parent, false); -// extend.setSourceCollectable(false); -// cmds.add(extend); -// } -// -// if (topicType != null) { -// Command setTitle = createSetTitleTextCommand(parent, topicType, -// create); -// if (setTitle != null) { -// cmds.add(setTitle); -// } -// } -// -// if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { -// if (ITopic.DETACHED.equals(topicType)) { -// cmds.add(new ModifyPositionCommand(create, sourceTopic -// .getPosition())); -// cmds.add(new ModifyPositionCommand(sourceTopic, null)); -// } -// cmds.add(new DeleteTopicCommand(sourceTopic)); -// cmds.add(new AddTopicCommand(sourceTopic, create)); -// } else { -// if (GEF.REQ_CREATE.equals(reqType)) { -// if (ITopic.DETACHED.equals(topicType)) { -// Point newPosition = calcNewPosition(sourceTopic, viewer); -// cmds.add(new ModifyPositionCommand(create, -// new org.xmind.core.util.Point(newPosition.x, -// newPosition.y))); -// } -// } -// if (parent != null && index >= 0 -// && ITopic.ATTACHED.equals(topicType)) { -// createModifyRangesCommand(reqType, parent, index, sourceTopic, -// cmds); -// } -// } -// -// if (ITopic.ATTACHED.equals(topicType)) { -// IPart parentPart = viewer.findPart(parent); -// IBranchPart parentBranch = MindMapUtils.findBranch(parentPart); -// if (parentBranch != null) { -// IBranchPart sourceChild; -// if (parentBranch.getSubBranches().contains(sourceBranch)) { -// sourceChild = sourceBranch; -// } else { -// sourceChild = null; -// } -// IStructure structure = parentBranch.getBranchPolicy() -// .getStructure(parentBranch); -// if (structure instanceof ICreatableBranchStructureExtension) { -// ((ICreatableBranchStructureExtension) structure) -// .decorateCreateRequest(parentBranch, sourceChild, -// request); -// } -// } -// } -// -// PropertyCommandBuilder builder = new PropertyCommandBuilder(viewer, -// create); -// builder.addFromRequest(request, false); -// if (!builder.isEmpty()) { -// for (Command cmd : builder.getCommands()) { -// cmds.add(cmd); -// } -// } -// -// return new CompoundCommand(cmds); -// } -// -// private Point calcNewPosition(ITopic sourceTopic, IViewer viewer) { -// IPart part = viewer.findPart(sourceTopic); -// if (part instanceof IGraphicalPart) { -// IFigure figure = ((IGraphicalPart) part).getFigure(); -// if (figure instanceof IReferencedFigure) { -// Point ref = ((IReferencedFigure) figure).getReference(); -// return ref.getTranslated(0, -// figure.getPreferredSize().height + 30); -// } -// } -// org.xmind.core.util.Point position = sourceTopic.getPosition(); -// return new Point(position.x, position.y + 60); -// } -// -// private Command createSetTitleTextCommand(ITopic parent, String type, -// ISourceProvider sourceProvider) { -// if (parent == null) -// return null; -// -// String newTitle; -// if (ITopic.DETACHED.equals(type)) { -// newTitle = MindMapMessages.TitleText_FloatingTopic; -// } else { -// int size = parent.getChildren(type).size(); -// int index = size + 1; -// if (parent.isRoot()) { -// newTitle = String.format(MindMapMessages.TitleText_MainTopic, -// index); -// } else { -// newTitle = String.format(MindMapMessages.TitleText_Subtopic, -// index); -// } -// } -// return new ModifyTitleTextCommand(sourceProvider, newTitle); -// } -// -// private void createModifyRangesCommand(String reqType, ITopic parent, -// int index, ITopic sourceTopic, List cmds) { -// int sourceTopicIndex = sourceTopic == null ? -1 : sourceTopic -// .getIndex(); -// fillModifyRangeCommands(parent.getBoundaries(), reqType, -// sourceTopicIndex, parent, index, cmds); -// fillModifyRangeCommands(parent.getSummaries(), reqType, -// sourceTopicIndex, parent, index, cmds); -// } -// -// private void fillModifyRangeCommands(Set ranges, -// String reqType, int sourceTopicIndex, ITopic parent, int index, -// List cmds) { -// for (ITopicRange r : ranges) { -// Command cmd = createModifyRangeCommand(r, reqType, -// sourceTopicIndex, parent, index); -// if (cmd != null) -// cmds.add(cmd); -// } -// } -// -// private Command createModifyRangeCommand(ITopicRange r, String reqType, -// int sourceTopicIndex, ITopic parent, int index) { -// int startIndex = r.getStartIndex(); -// int endIndex = r.getEndIndex(); -// if ((GEF.REQ_CREATE.equals(reqType) && sourceTopicIndex == endIndex) -// || (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) && sourceTopicIndex == startIndex)) { -// ModifyRangeCommand cmd = new ModifyRangeCommand(r, endIndex + 1, -// false); -// cmd.setSourceCollectable(false); -// return cmd; -// } -// -// if (startIndex >= index || endIndex >= index) { -// List subtopics = r.getEnclosingTopics(); -// if (!subtopics.isEmpty()) { -// ITopic start = subtopics.get(0); -// ITopic end = subtopics.get(subtopics.size() - 1); -// return new ModifyTopicRangeCommand(r, start, end); -// } -// } -// return null; -// } - - private void sort(List topics) { - if (topics == null || topics.size() == 0) { - return; - } - - Collections.sort(topics, new Comparator() { - - public int compare(ITopic o1, ITopic o2) { - return o1.getIndex() - o2.getIndex(); - } - }); - } - - protected void doAnimateCommand(Command cmd, IAnimationService anim, - IViewer viewer) { - Object source = ((ISourceProvider) cmd).getSource(); - if (source != null) { - IMinimizable min = getMinimizable(source, viewer); - if (min != null) { - min.setMinimized(true); - ((GraphicalViewer) viewer).getLightweightSystem() - .getUpdateManager().performValidation(); - } - } - - super.doAnimateCommand(cmd, anim, viewer); - } - - protected void createAnimation(Command cmd, IViewer viewer) { - Object source = ((ISourceProvider) cmd).getSource(); - IMinimizable min = getMinimizable(source, viewer); - if (min != null) { - min.setMinimized(false); - } - } - - private IMinimizable getMinimizable(Object o, IViewer viewer) { - IPart part = viewer.findPart(o); - if (part instanceof IGraphicalPart) { - IFigure figure = ((IGraphicalPart) part).getFigure(); - if (figure instanceof IMinimizable) { - return (IMinimizable) figure; - } - } - return null; - } - -} +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.internal.DPIUtil; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.Core; +import org.xmind.core.IBoundary; +import org.xmind.core.ICloneData; +import org.xmind.core.IFileEntry; +import org.xmind.core.ISheet; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.IWorkbook; +import org.xmind.core.internal.UserDataConstants; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.HyperlinkUtils; +import org.xmind.gef.GEF; +import org.xmind.gef.GraphicalViewer; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.draw2d.geometry.Geometry; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.graphicalpolicy.IStyleSelector; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.service.IAnimationService; +import org.xmind.ui.branch.IBranchStructureExtension; +import org.xmind.ui.branch.ICreatableBranchStructureExtension; +import org.xmind.ui.commands.AddBoundaryCommand; +import org.xmind.ui.commands.AddMarkerCommand; +import org.xmind.ui.commands.AddSummaryCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.CreateBoundaryCommand; +import org.xmind.ui.commands.CreateSummaryCommand; +import org.xmind.ui.commands.CreateTopicCommand; +import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.commands.ModifyBoundaryMasterCommand; +import org.xmind.ui.commands.ModifyImageSizeCommand; +import org.xmind.ui.commands.ModifyImageSourceCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; +import org.xmind.ui.commands.ModifySummaryTopicCommand; +import org.xmind.ui.commands.ModifyTitleTextCommand; +import org.xmind.ui.commands.ModifyTopicHyperlinkCommand; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.branch.UnbalancedData; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.ImageFormat; +import org.xmind.ui.util.MindMapUtils; + +public class TopicCreatablePolicy extends MindMapPolicyBase { + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_CREATE.equals(requestType) + || MindMapUI.REQ_CREATE_BEFORE.equals(requestType) + || MindMapUI.REQ_CREATE_CHILD.equals(requestType) + || MindMapUI.REQ_CREATE_PARENT.equals(requestType) + || MindMapUI.REQ_ADD_ATTACHMENT.equals(requestType) + || MindMapUI.REQ_ADD_MARKER.equals(requestType) + || MindMapUI.REQ_CREATE_BOUNDARY.equals(requestType) + || MindMapUI.REQ_CREATE_SUMMARY.equals(requestType) + || MindMapUI.REQ_ADD_IMAGE.equals(requestType) + || MindMapUI.REQ_CREATE_SHEET.equals(requestType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(requestType) + || MindMapUI.REQ_CREATE_CALLOUT.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (GEF.REQ_CREATE.equals(reqType) // + || MindMapUI.REQ_CREATE_CHILD.equals(reqType) // + || MindMapUI.REQ_CREATE_BEFORE.equals(reqType) // + || MindMapUI.REQ_CREATE_PARENT.equals(reqType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType) + || MindMapUI.REQ_CREATE_CALLOUT.equals(reqType)) { + createTopic(request); + } else if (MindMapUI.REQ_ADD_ATTACHMENT.equals(reqType)) { + addAttachments(request); + } else if (MindMapUI.REQ_ADD_MARKER.equals(reqType)) { + addMarker(request); + } else if (MindMapUI.REQ_CREATE_BOUNDARY.equals(reqType)) { + createBoundary(request); + } else if (MindMapUI.REQ_CREATE_SUMMARY.equals(reqType)) { + createSummary(request); + } else if (MindMapUI.REQ_ADD_IMAGE.equals(reqType)) { + addImage(request); + } else if (MindMapUI.REQ_CREATE_SHEET.equals(reqType)) { + createSheetFromTopic(request); + } + } + + private void createSheetFromTopic(Request request) { + List targets = request.getTargets(); + if (targets.isEmpty()) + return; + List topics = MindMapUtils.getTopics(targets); + if (topics.isEmpty()) + return; + + ITopic sourceTopic = topics.get(0); + CreateSheetFromTopicCommandBuilder builder = new CreateSheetFromTopicCommandBuilder( + request.getTargetViewer(), request.getTargetCommandStack(), + sourceTopic); + if (!builder.canStart()) + return; + + builder.start(); + builder.setLabel(CommandMessages.Command_CreateSheetFromTopic); + builder.run(); + builder.end(); + } + + private void createSummary(Request request) { + List targets = request.getTargets(); + Command cmd = createCreateSummaryCommand(request, targets); + if (cmd != null) { + cmd.setLabel(CommandMessages.Command_CreateSummary); + saveAndRun(cmd, request.getTargetDomain()); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources(), + request.getTargetViewer()); + } + } + } + + private Command createCreateSummaryCommand(Request request, + List targets) { + List topics = MindMapUtils.getTopics(targets); + if (topics.isEmpty()) + return null; + Map> map = categorize(topics, true); + List cmds = new ArrayList(map.size() * 3); + for (ITopic parent : map.keySet()) { + Command cmd = createCreateSummariesCommand(parent, map.get(parent)); + if (cmd != null) + cmds.add(cmd); + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createCreateSummariesCommand(ITopic parent, + Collection topics) { + if (topics.isEmpty()) + return null; + List ranges = getRanges(topics); + List cmds = new ArrayList(ranges.size()); + for (Range range : ranges) { + if (!hasSameSummary(parent, range)) { + Command cmd = createCreateSummaryCommand(parent, range); + if (cmd != null) + cmds.add(cmd); + } + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createCreateSummaryCommand(ITopic parent, Range range) { + IWorkbook workbook = parent.getOwnedWorkbook(); + CreateSummaryCommand createSummary = new CreateSummaryCommand(workbook); + ModifyRangeCommand modifyStart = new ModifyRangeCommand(createSummary, + range.start, true); + ModifyRangeCommand modifyEnd = new ModifyRangeCommand(createSummary, + range.end, false); + CreateTopicCommand createSummaryTopic = new CreateTopicCommand( + workbook); + ModifyTitleTextCommand modifyTitle = new ModifyTitleTextCommand( + createSummaryTopic, MindMapMessages.TitleText_SummaryTopic); + ModifySummaryTopicCommand modifySummaryTopic = new ModifySummaryTopicCommand( + createSummary, createSummaryTopic); + AddSummaryCommand addSummary = new AddSummaryCommand(createSummary, + parent); + AddTopicCommand addSummaryTopic = new AddTopicCommand( + createSummaryTopic, parent, -1, ITopic.SUMMARY); + createSummary.setSourceCollectable(false); + modifyStart.setSourceCollectable(false); + modifyEnd.setSourceCollectable(false); + modifySummaryTopic.setSourceCollectable(false); + addSummary.setSourceCollectable(false); + return new CompoundCommand(createSummary, modifyStart, modifyEnd, + createSummaryTopic, modifyTitle, modifySummaryTopic, addSummary, + addSummaryTopic); + } + + private boolean hasSameSummary(ITopic parent, Range range) { + for (ISummary b : parent.getSummaries()) { + int s = b.getStartIndex(); + int e = b.getEndIndex(); + if (s == range.start && e == range.end) + return true; + } + return false; + } + + private void createBoundary(Request request) { + List sources = request.getTargets(); + Command cmd = createCreateBoundariesCommand(request, sources); + if (cmd != null) { + cmd.setLabel(CommandMessages.Command_CreateBoundary); + saveAndRun(cmd, request.getTargetDomain()); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources(), + request.getTargetViewer()); + } + } + } + + private Command createCreateBoundariesCommand(Request request, + List sources) { + List topics = MindMapUtils.getTopics(sources); + if (topics.isEmpty()) + return null; + + Map> map = categorize(topics, false); + List cmds = new ArrayList(map.size() * 2); + for (ITopic parent : map.keySet()) { + Command cmd = createCreateBoundariesCommand(parent, + map.get(parent)); + if (cmd != null) + cmds.add(cmd); + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createCreateBoundariesCommand(ITopic parent, + Collection topics) { + if (topics.isEmpty()) + return null; + List ranges = getRanges(topics); + List cmds = new ArrayList(ranges.size()); + for (Range range : ranges) { + if (!hasSameBoundary(parent, range)) { + Command cmd = createCreateBoundaryCommand(parent, range); + if (cmd != null) + cmds.add(cmd); + } + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private boolean hasSameBoundary(ITopic parent, Range range) { + if (range.overTopic != null) { + for (IBoundary b : range.overTopic.getBoundaries()) { + if (b.isMasterBoundary()) + return true; + } + } + for (IBoundary b : parent.getBoundaries()) { + int s = b.getStartIndex(); + int e = b.getEndIndex(); + if (s == range.start && e == range.end) + return true; + } + return false; + } + + private List getRanges(Collection topics) { + ITopic[] ts = topics.toArray(new ITopic[topics.size()]); + Arrays.sort(ts, Core.getTopicComparator()); + List ranges = new ArrayList(ts.length); + Range r = null; + for (ITopic t : ts) { + String topicType = t.getType(); + if (ITopic.DETACHED.equals(topicType) + || ITopic.CALLOUT.equals(topicType) + || ITopic.SUMMARY.equals(topicType)) { + if (r != null) + ranges.add(r); + r = null; + ranges.add(new Range(t)); + } else { + int i = t.getIndex(); + if (i >= 0) { + if (r == null) { + r = new Range(i); + } else if (i == r.end + 1) { + r.end = i; + } else if (i > r.end + 1) { + ranges.add(r); + r = new Range(i); + } + } + } + } + if (r != null) { + ranges.add(r); + } + return ranges; + } + + private Command createCreateBoundaryCommand(ITopic parent, Range range) { + if (range.overTopic != null) { + CreateBoundaryCommand create = new CreateBoundaryCommand( + range.overTopic.getOwnedWorkbook()); + ModifyBoundaryMasterCommand modify = new ModifyBoundaryMasterCommand( + create, true); + AddBoundaryCommand add = new AddBoundaryCommand(create, + range.overTopic); + return new CompoundCommand(create, modify, add); + } + CreateBoundaryCommand create = new CreateBoundaryCommand( + parent.getOwnedWorkbook()); + ModifyRangeCommand modify1 = new ModifyRangeCommand(create, range.start, + true); + ModifyRangeCommand modify2 = new ModifyRangeCommand(create, range.end, + false); + AddBoundaryCommand add = new AddBoundaryCommand(create, parent); + return new CompoundCommand(create, modify1, modify2, add); + } + + private Map> categorize(List topics, + boolean onlyAttachedTopics) { + Map> map = new HashMap>(); + for (ITopic t : topics) { + ITopic p = t.getParent(); + if (p != null && (!onlyAttachedTopics || t.isAttached()) + && !isAncestorInCollection(p, topics)) { + Collection c = map.get(p); + if (c == null) { + c = new HashSet(); + map.put(p, c); + } + c.add(t); + } + } + return map; + } + + private boolean isAncestorInCollection(ITopic parent, + Collection topics) { + if (parent == null) + return false; + if (topics.contains(parent)) + return true; + return isAncestorInCollection(parent.getParent(), topics); + } + + private void addMarker(Request request) { + List targets = request.getTargets(); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(UserDataConstants.USE_MARKERS_COUNT); + Command cmd = createAddMarkerCommand(request, targets); + if (cmd != null) { + cmd.setLabel(CommandMessages.Command_AddMarker); + saveAndRun(cmd, request.getTargetDomain()); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources(), + request.getTargetViewer()); + } + } + } + + private Command createAddMarkerCommand(Request request, + List targets) { + String[] markerIds = getMarkerIds(request); + if (markerIds == null || markerIds.length == 0) + return null; + + List cmds = new ArrayList(targets.size()); + createAddMarkerCommand(targets, cmds, markerIds); + if (!cmds.isEmpty()) { + return new CompoundCommand(cmds); + } + return null; + } + + private String[] getMarkerIds(Request request) { + Object param = request.getParameter(MindMapUI.PARAM_MARKER_ID); + if (param instanceof String) + return new String[] { (String) param }; + if (param instanceof String[]) + return (String[]) param; + return null; + } + + private void createAddMarkerCommand(List targets, List cmds, + String... markerIds) { + for (IPart source : targets) { + Object m = MindMapUtils.getRealModel(source); + if (m instanceof ITopic) { + ITopic t = (ITopic) m; + for (String markerId : markerIds) { + createAddMarkerCommand(t, markerId, cmds); + } + } + } + } + + private void createAddMarkerCommand(ITopic topic, String newMarkerId, + List cmds) { + if (topic.hasMarker(newMarkerId)) + return; + + IMarker marker = findMarker(topic, newMarkerId); + if (marker != null) { + IMarkerGroup group = marker.getParent(); + IMarkerSheet sheet = marker.getOwnedSheet(); + if (!sheet.isPermanent()) { + IMarkerSheet markerSheet = topic.getOwnedWorkbook() + .getMarkerSheet(); + IMarker existingMarker = markerSheet.findMarker(marker.getId()); + if (existingMarker == null || !markerSheet + .equals(existingMarker.getOwnedSheet())) { + ICloneData cloneData = topic.getOwnedWorkbook() + .clone(Arrays.asList(marker)); + Object cloned = cloneData.get(marker); + if (cloned instanceof IMarker) { + marker = (IMarker) cloned; + group = marker.getParent(); + newMarkerId = marker.getId(); + } + } + } + if (group != null && group.isSingleton()) { + removeSingletonMarkers(topic, newMarkerId, group, cmds); + } + cmds.add(new AddMarkerCommand(topic, newMarkerId)); + } + } + + private IMarker findMarker(ITopic topic, String markerId) { + IWorkbook workbook = topic.getOwnedWorkbook(); + if (workbook != null) { + IMarkerSheet markerSheet = workbook.getMarkerSheet(); + if (markerSheet != null) { + IMarker ownedMarker = markerSheet.findMarker(markerId); + if (ownedMarker == null) { + ownedMarker = MindMapUI.getResourceManager() + .getUserMarkerSheet().findMarker(markerId); + } + return ownedMarker; + } + } + return null; + } + + private void removeSingletonMarkers(ITopic topic, String newMarkerId, + IMarkerGroup group, List cmds) { + for (IMarker m : group.getMarkers()) { + String markerId = m.getId(); + if (!newMarkerId.equals(markerId)) { + if (topic.hasMarker(markerId)) { + cmds.add(new DeleteMarkerCommand(topic, markerId)); + } + } + } + } + + private void addImage(Request request) { + List topics = MindMapUtils.getTopics(request.getTargets()); + if (topics.isEmpty()) + return; + + Command command = createAddImageCommand(request, topics); + if (command != null) { + command.setLabel(CommandMessages.Command_InsertImage); + saveAndRun(command, request.getTargetDomain()); + if (command instanceof ISourceProvider) { + select(((ISourceProvider) command).getSources(), + request.getTargetViewer()); + } + } + } + + private Command createAddImageCommand(Request request, + final List topics) { + String[] paths = getPaths(request); + if (paths == null || paths.length == 0) + return null; + + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return null; + + ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); + if (sheet == null) + return null; + + final IWorkbook workbook = sheet.getOwnedWorkbook(); + final String path = paths[0]; + final List cmds = new ArrayList(paths.length); + String errMsg = NLS.bind("Failed to copy file into this workbook: {0}", //$NON-NLS-1$ + path); + SafeRunner.run(new SafeRunnable(errMsg) { + public void run() throws Exception { + Command cmd = createAddImageCommand(workbook, path, topics); + if (cmd != null) + cmds.add(cmd); + } + }); + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createAddImageCommand(IWorkbook workbook, String path, + List topics) throws Exception { + Dimension size = getImageSize(path); + ImageFormat format = ImageFormat + .findByExtension(FileUtils.getExtension(path), ImageFormat.PNG); + IFileEntry e = workbook.getManifest().createAttachmentFromFilePath(path, + format.getMediaType()); + if (e == null) + return null; + + String entryPath = e.getPath(); + String hyperlink = HyperlinkUtils.toAttachmentURL(entryPath); + + List cmds = new ArrayList(topics.size()); + for (ITopic t : topics) { + Command cmd = createAddImageCommand(t, hyperlink, size); + if (cmd != null) + cmds.add(cmd); + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Dimension getImageSize(String path) { + try { + Image tempImage = new Image(Display.getCurrent(), path); + Rectangle imageBounds = tempImage.getBounds(); + tempImage.dispose(); + boolean needZoom = DPIUtil.getDeviceZoom() > 100; + int width = needZoom ? imageBounds.width / 2 : imageBounds.width; + int height = needZoom ? imageBounds.height / 2 : imageBounds.height; + return Geometry.getScaledConstrainedSize(width, height, + MindMapUI.IMAGE_INIT_WIDTH, MindMapUI.IMAGE_INIT_HEIGHT); + } catch (Throwable e) { + } + return null; + } + + private Command createAddImageCommand(ITopic t, String hyperlink, + Dimension size) { + ModifyImageSourceCommand modifyImageSource = new ModifyImageSourceCommand( + t, hyperlink); + + if (size != null) { + ModifyImageSizeCommand modifySize = new ModifyImageSizeCommand(t, + size.width, size.height); + return new CompoundCommand(modifyImageSource, modifySize); + } else { + return new CompoundCommand(modifyImageSource); + } + } + + private void addAttachments(Request request) { + String[] paths = getPaths(request); + if (paths == null || paths.length == 0) + return; + + List topics = MindMapUtils.getTopics(request.getTargets()); + if (topics.isEmpty()) + return; + + Command cmd = createAddAttachmentCommand(request, topics, paths); + if (cmd != null) { + cmd.setLabel(CommandMessages.Command_InsertAttachment); + saveAndRun(cmd, request.getTargetDomain()); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources(), + request.getTargetViewer()); + } + } + } + + private Command createAddAttachmentCommand(Request request, + final List topics, String[] paths) { + IViewer viewer = request.getTargetViewer(); + if (viewer == null) + return null; + + ISheet sheet = (ISheet) viewer.getAdapter(ISheet.class); + if (sheet == null) + return null; + + final IWorkbook workbook = sheet.getOwnedWorkbook(); + final List cmds = new ArrayList(paths.length); + for (final String path : paths) { + String errMsg = NLS + .bind("Failed to copy file into this workbook: {0}", path); //$NON-NLS-1$ + SafeRunner.run(new SafeRunnable(errMsg) { + public void run() throws Exception { + Command cmd = createAddAttachmentCommand(workbook, path, + topics); + if (cmd != null) + cmds.add(cmd); + } + }); + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createAddAttachmentCommand(IWorkbook workbook, String path, + List topics) throws IOException { + IFileEntry e = workbook.getManifest() + .createAttachmentFromFilePath(path); + if (e == null) + return null; + + String hyperlink = HyperlinkUtils.toAttachmentURL(e.getPath()); + String title = new File(path).getName(); + + List cmds = new ArrayList(topics.size()); + for (ITopic t : topics) { + Command cmd = createAddAttachmentCommand(t, title, hyperlink); + if (cmd != null) + cmds.add(cmd); + } + if (cmds.isEmpty()) + return null; + return new CompoundCommand(cmds); + } + + private Command createAddAttachmentCommand(ITopic parent, String title, + String hyperlink) { + CreateTopicCommand create = new CreateTopicCommand( + parent.getOwnedWorkbook()); + + AddTopicCommand insert = new AddTopicCommand(create, parent, -1, + ITopic.ATTACHED); + + ModifyTitleTextCommand setTitle = new ModifyTitleTextCommand(create, + title); + + ModifyTopicHyperlinkCommand setHyperlink = new ModifyTopicHyperlinkCommand( + create, hyperlink); + + return new CompoundCommand(create, insert, setTitle, setHyperlink); + } + + private String[] getPaths(Request request) { + Object param = request.getParameter(GEF.PARAM_PATH); + if (param instanceof String) + return new String[] { (String) param }; + if (param instanceof String[]) + return (String[]) param; + return null; + } + + private void createTopic(Request request) { + IPart source = request.getPrimaryTarget(); + IBranchPart sourceBranch = MindMapUtils.findBranch(source); + if (sourceBranch == null) + return; + + ITopic sourceTopic = sourceBranch.getTopic(); + String reqType = request.getType(); + if (GEF.REQ_CREATE.equals(reqType)) { + if (ITopic.SUMMARY.equals(sourceTopic.getType())) + return; + if (sourceBranch.isCentral()) { + reqType = MindMapUI.REQ_CREATE_CHILD;// + } + } else if (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) + || MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType)) { + if (ITopic.SUMMARY.equals(sourceTopic.getType())) + return; + } else if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { + if (sourceBranch.isCentral()) + return; + } + + IViewer viewer = request.getTargetViewer(); + ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); + if (centralTopic == null) + return; + + CreateTopicCommandBuilder builder = null; + List topics = null; + if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { + topics = MindMapUtils.filterOutDescendents( + MindMapUtils.getTopics(request.getTargets()), null); + sort(topics); + + if (!topics.isEmpty()) + sourceTopic = topics.get(0); + + builder = new CreateTopicCommandBuilder(viewer, + request.getTargetCommandStack(), sourceTopic, reqType, + topics); + } else { + builder = new CreateTopicCommandBuilder(viewer, + request.getTargetCommandStack(), sourceTopic, reqType); + } + + if (!builder.canStart()) + return; + + if (ITopic.ATTACHED.equals(builder.getTargetType())) { + IPart parentPart = viewer.findPart(builder.getTargetParent()); + if (parentPart instanceof ITopicPart) { + IBranchPart parentBranch = ((ITopicPart) parentPart) + .getOwnerBranch(); + if (parentBranch != null) { + IBranchPart sourceChild; + if (parentBranch.getSubBranches().contains(sourceBranch)) { + sourceChild = sourceBranch; + } else { + sourceChild = null; + } + + IStructure structure = parentBranch.getBranchPolicy() + .getStructure(parentBranch); + if (structure instanceof ICreatableBranchStructureExtension) { + ((ICreatableBranchStructureExtension) structure) + .decorateCreateRequest(parentBranch, + sourceChild, request); + } + + if (parentBranch.isCentral()) { + String centralTopicStructure = centralTopic + .getStructureClass(); + boolean isUnbalancedStructure = centralTopicStructure == null + || UnbalancedData.STRUCTUREID_UNBALANCED + .equalsIgnoreCase( + centralTopicStructure); + if (isUnbalancedStructure) { + ITopicExtension extension = centralTopic + .createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension + .getContent().getCreatedChild( + UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + String preCreateRightNum = element.getTextContent(); + if (preCreateRightNum == null) + preCreateRightNum = String.valueOf(0); + int postCreateRightNum = Integer + .valueOf(preCreateRightNum).intValue(); + + int deletedRightNum = 0; + if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { + if (topics != null && !topics.isEmpty()) { + for (ITopic rightTopic : topics) { + if (rightTopic + .getParent() == centralTopic + && rightTopic + .getIndex() <= postCreateRightNum + - 1) + deletedRightNum++; + } + } + } + + List mainBranches = parentBranch + .getSubBranches(); + int size = mainBranches.size(); + if ((((IBranchStructureExtension) structure) + .getChildTargetOrientation(parentBranch, + sourceBranch) == PositionConstants.WEST + && parentBranch != sourceBranch) + || (parentBranch == sourceBranch + && size <= 2 + && postCreateRightNum == size)) { + postCreateRightNum++; + if (size > 2 + && (mainBranches.indexOf( + sourceBranch) == size - 1) + && !MindMapUI.REQ_CREATE_PARENT + .equals(reqType)) + postCreateRightNum--; + } + + postCreateRightNum = postCreateRightNum + - deletedRightNum; + + if (!preCreateRightNum.equals(postCreateRightNum)) { + ModifyRightNumberOfUnbalancedStructureCommand modifyRightNumberCommand = new ModifyRightNumberOfUnbalancedStructureCommand( + centralTopic, preCreateRightNum, + postCreateRightNum); + builder.addPendingCommand( + modifyRightNumberCommand, false); + //if sourceCollectable is true,the operations of create and move topic + //maybe lead to undo/redo error. + } + } + + } + + } + } + } + + PropertyCommandBuilder builder2 = new PropertyCommandBuilder(viewer, + builder, request); + builder.setLabel(CommandMessages.Command_CreateTopic); + builder.start(); + builder2.start(); + + if (MindMapUI.REQ_DUPLICATE_TOPIC.equals(reqType)) { + builder.createDuplicateTopic(); + } else { + builder.createTopic(); + } + + if (builder.getCreatedTopic() != null) { + builder2.addSource(builder.getCreatedTopic(), true); + } + + builder2.end(); + builder.end(); + + Command command = builder.getCommand(); + +// Command cmd = createCreateTopicCommand(request, sourceTopic, +// sourceBranch, request.getTargetViewer()); +// if (cmd == null) +// return; +// +// cmd.setLabel(CommandMessages.Command_CreateTopic); +// saveAndRun(cmd, request.getTargetDomain()); + + if (command instanceof ISourceProvider) { + Object creation = ((ISourceProvider) command).getSource(); + if (creation != null) { + boolean needSelect = true; + if (creation instanceof ITopic) { + IPart topicPart = viewer.findPart(creation); + IBranchPart branch = MindMapUtils.findBranch(topicPart); + IStyleSelector styleSelector = branch.getBranchPolicy() + .getStyleSelector(branch); + if (styleSelector != null) { + String hideCallout = styleSelector.getStyleValue(branch, + Styles.HideCallout); + needSelect = !(Boolean.parseBoolean(hideCallout) + && ITopic.CALLOUT + .equals(((ITopic) creation).getType())); + } + } + if (needSelect) + select(creation, request.getTargetViewer()); + if (isAnimationRequired(request)) + animateCommand(command, request.getTargetViewer()); + } + } + } + +// private Command createCreateTopicCommand(Request request, +// ITopic sourceTopic, IBranchPart sourceBranch, IViewer viewer) { +// CreateTopicCommand create = new CreateTopicCommand(sourceTopic +// .getOwnedWorkbook()); +// +// String reqType = request.getType(); +// ITopic parent = null; +// Command insert = null; +// int index = -1; +// String topicType = null; +// if (MindMapUI.REQ_CREATE_CHILD.equals(reqType)) { +// parent = sourceTopic; +// topicType = ITopic.ATTACHED; +// insert = new AddTopicCommand(create, parent, -1, topicType); +// index = parent.getChildren(topicType).size(); +// } else { +// parent = sourceTopic.getParent(); +// if (parent != null) { +// if (GEF.REQ_CREATE.equals(reqType)) { +// index = sourceTopic.getIndex() + 1; +// topicType = sourceTopic.getType(); +// insert = new AddTopicCommand(create, parent, index, +// topicType); +// } else if (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) +// || MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { +// index = sourceTopic.getIndex(); +// topicType = sourceTopic.getType(); +// insert = new AddTopicCommand(create, parent, index, +// topicType); +// } +// } +// } +// if (insert == null || topicType == null) +// return null; +// +// List cmds = new ArrayList(5); +// cmds.add(create); +// cmds.add(insert); +// +// if (parent != null && parent.isFolded()) { +// ModifyFoldedCommand extend = new ModifyFoldedCommand(parent, false); +// extend.setSourceCollectable(false); +// cmds.add(extend); +// } +// +// if (topicType != null) { +// Command setTitle = createSetTitleTextCommand(parent, topicType, +// create); +// if (setTitle != null) { +// cmds.add(setTitle); +// } +// } +// +// if (MindMapUI.REQ_CREATE_PARENT.equals(reqType)) { +// if (ITopic.DETACHED.equals(topicType)) { +// cmds.add(new ModifyPositionCommand(create, sourceTopic +// .getPosition())); +// cmds.add(new ModifyPositionCommand(sourceTopic, null)); +// } +// cmds.add(new DeleteTopicCommand(sourceTopic)); +// cmds.add(new AddTopicCommand(sourceTopic, create)); +// } else { +// if (GEF.REQ_CREATE.equals(reqType)) { +// if (ITopic.DETACHED.equals(topicType)) { +// Point newPosition = calcNewPosition(sourceTopic, viewer); +// cmds.add(new ModifyPositionCommand(create, +// new org.xmind.core.util.Point(newPosition.x, +// newPosition.y))); +// } +// } +// if (parent != null && index >= 0 +// && ITopic.ATTACHED.equals(topicType)) { +// createModifyRangesCommand(reqType, parent, index, sourceTopic, +// cmds); +// } +// } +// +// if (ITopic.ATTACHED.equals(topicType)) { +// IPart parentPart = viewer.findPart(parent); +// IBranchPart parentBranch = MindMapUtils.findBranch(parentPart); +// if (parentBranch != null) { +// IBranchPart sourceChild; +// if (parentBranch.getSubBranches().contains(sourceBranch)) { +// sourceChild = sourceBranch; +// } else { +// sourceChild = null; +// } +// IStructure structure = parentBranch.getBranchPolicy() +// .getStructure(parentBranch); +// if (structure instanceof ICreatableBranchStructureExtension) { +// ((ICreatableBranchStructureExtension) structure) +// .decorateCreateRequest(parentBranch, sourceChild, +// request); +// } +// } +// } +// +// PropertyCommandBuilder builder = new PropertyCommandBuilder(viewer, +// create); +// builder.addFromRequest(request, false); +// if (!builder.isEmpty()) { +// for (Command cmd : builder.getCommands()) { +// cmds.add(cmd); +// } +// } +// +// return new CompoundCommand(cmds); +// } +// +// private Point calcNewPosition(ITopic sourceTopic, IViewer viewer) { +// IPart part = viewer.findPart(sourceTopic); +// if (part instanceof IGraphicalPart) { +// IFigure figure = ((IGraphicalPart) part).getFigure(); +// if (figure instanceof IReferencedFigure) { +// Point ref = ((IReferencedFigure) figure).getReference(); +// return ref.getTranslated(0, +// figure.getPreferredSize().height + 30); +// } +// } +// org.xmind.core.util.Point position = sourceTopic.getPosition(); +// return new Point(position.x, position.y + 60); +// } +// +// private Command createSetTitleTextCommand(ITopic parent, String type, +// ISourceProvider sourceProvider) { +// if (parent == null) +// return null; +// +// String newTitle; +// if (ITopic.DETACHED.equals(type)) { +// newTitle = MindMapMessages.TitleText_FloatingTopic; +// } else { +// int size = parent.getChildren(type).size(); +// int index = size + 1; +// if (parent.isRoot()) { +// newTitle = String.format(MindMapMessages.TitleText_MainTopic, +// index); +// } else { +// newTitle = String.format(MindMapMessages.TitleText_Subtopic, +// index); +// } +// } +// return new ModifyTitleTextCommand(sourceProvider, newTitle); +// } +// +// private void createModifyRangesCommand(String reqType, ITopic parent, +// int index, ITopic sourceTopic, List cmds) { +// int sourceTopicIndex = sourceTopic == null ? -1 : sourceTopic +// .getIndex(); +// fillModifyRangeCommands(parent.getBoundaries(), reqType, +// sourceTopicIndex, parent, index, cmds); +// fillModifyRangeCommands(parent.getSummaries(), reqType, +// sourceTopicIndex, parent, index, cmds); +// } +// +// private void fillModifyRangeCommands(Set ranges, +// String reqType, int sourceTopicIndex, ITopic parent, int index, +// List cmds) { +// for (ITopicRange r : ranges) { +// Command cmd = createModifyRangeCommand(r, reqType, +// sourceTopicIndex, parent, index); +// if (cmd != null) +// cmds.add(cmd); +// } +// } +// +// private Command createModifyRangeCommand(ITopicRange r, String reqType, +// int sourceTopicIndex, ITopic parent, int index) { +// int startIndex = r.getStartIndex(); +// int endIndex = r.getEndIndex(); +// if ((GEF.REQ_CREATE.equals(reqType) && sourceTopicIndex == endIndex) +// || (MindMapUI.REQ_CREATE_BEFORE.equals(reqType) && sourceTopicIndex == startIndex)) { +// ModifyRangeCommand cmd = new ModifyRangeCommand(r, endIndex + 1, +// false); +// cmd.setSourceCollectable(false); +// return cmd; +// } +// +// if (startIndex >= index || endIndex >= index) { +// List subtopics = r.getEnclosingTopics(); +// if (!subtopics.isEmpty()) { +// ITopic start = subtopics.get(0); +// ITopic end = subtopics.get(subtopics.size() - 1); +// return new ModifyTopicRangeCommand(r, start, end); +// } +// } +// return null; +// } + + private void sort(List topics) { + if (topics == null || topics.size() == 0) { + return; + } + + Collections.sort(topics, new Comparator() { + + public int compare(ITopic o1, ITopic o2) { + return o1.getIndex() - o2.getIndex(); + } + }); + } + + protected void doAnimateCommand(Command cmd, IAnimationService anim, + IViewer viewer) { + Object source = ((ISourceProvider) cmd).getSource(); + if (source != null) { + IMinimizable min = getMinimizable(source, viewer); + if (min != null) { + min.setMinimized(true); + ((GraphicalViewer) viewer).getLightweightSystem() + .getUpdateManager().performValidation(); + } + } + + super.doAnimateCommand(cmd, anim, viewer); + } + + protected void createAnimation(Command cmd, IViewer viewer) { + Object source = ((ISourceProvider) cmd).getSource(); + IMinimizable min = getMinimizable(source, viewer); + if (min != null) { + min.setMinimized(false); + } + } + + private IMinimizable getMinimizable(Object o, IViewer viewer) { + IPart part = viewer.findPart(o); + if (part instanceof IGraphicalPart) { + IFigure figure = ((IGraphicalPart) part).getFigure(); + if (figure instanceof IMinimizable) { + return (IMinimizable) figure; + } + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMovablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMovablePolicy.java index 58d1067a6..7798614af 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMovablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMovablePolicy.java @@ -1,448 +1,448 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -import org.eclipse.draw2d.PositionConstants; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.core.Core; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicExtension; -import org.xmind.core.ITopicExtensionElement; -import org.xmind.core.ITopicRange; -import org.xmind.gef.GEF; -import org.xmind.gef.ISourceProvider; -import org.xmind.gef.IViewer; -import org.xmind.gef.Request; -import org.xmind.gef.command.Command; -import org.xmind.gef.command.CompoundCommand; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.geometry.IIntersectionSolver; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.IBranchStructureExtension; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.commands.DeleteTopicCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; -import org.xmind.ui.internal.branch.UnbalancedData; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class TopicMovablePolicy extends MindMapPolicyBase { - - public boolean understands(String requestType) { - return super.understands(requestType) - || GEF.REQ_MOVETO.equals(requestType) - || GEF.REQ_COPYTO.equals(requestType) - || GEF.REQ_ALIGN.equals(requestType) - || GEF.REQ_MOVE_UP.equals(requestType) - || GEF.REQ_MOVE_DOWN.equals(requestType) - || GEF.REQ_MOVE_LEFT.equals(requestType) - || GEF.REQ_MOVE_RIGHT.equals(requestType) - || GEF.REQ_SORT.equals(requestType); - } - - public void handle(Request request) { - String requestType = request.getType(); - if (GEF.REQ_MOVETO.equals(requestType) - || GEF.REQ_COPYTO.equals(requestType)) { - moveOrCopyTopics(request); - } else if (GEF.REQ_ALIGN.equals(requestType)) { - alignTopics(request); - } else if (GEF.REQ_SORT.equals(requestType)) { - sortTopics(request); - } else if (GEF.REQ_MOVE_UP.equals(requestType) - || GEF.REQ_MOVE_DOWN.equals(requestType) - || GEF.REQ_MOVE_LEFT.equals(requestType) - || GEF.REQ_MOVE_RIGHT.equals(requestType)) { - quickMove(request, requestType); - } - } - - private void quickMove(Request request, String direction) { - int dir = getDirection(direction); - if (dir < 0) - return; - - IBranchPart parent = null; - List branches = new ArrayList(); - for (IPart p : request.getTargets()) { - IBranchPart branch = MindMapUtils.findBranch(p); - if (branch != null) { - if (!branch.getTopic().isAttached()) - return; - if (parent != null && parent != branch.getParentBranch()) - return; - if (parent == null) - parent = branch.getParentBranch(); - if (parent == null) - return; - branches.add(branch); - } - } - if (parent == null) - return; - - IStructure structure = parent.getBranchPolicy().getStructure(parent); - if (!(structure instanceof IBranchStructureExtension)) - return; - - Collections.sort(branches, new Comparator() { - public int compare(IBranchPart o1, IBranchPart o2) { - return o1.getBranchIndex() - o2.getBranchIndex(); - } - }); - IBranchStructureExtension bse = (IBranchStructureExtension) structure; - List commands = new ArrayList(); - int total = parent.getTopic().getChildren(ITopic.ATTACHED).size(); - for (int i = 0; i < branches.size(); i++) { - IBranchPart child = branches.get(i); - int offset = bse.getQuickMoveOffset(parent, child, dir); - if (offset > 0) { - for (int j = child.getBranchIndex() + 1; j < parent - .getSubBranches().size(); j++) { - IBranchPart b = parent.getSubBranches().get(j); - if (!branches.contains(b)) - break; - offset++; - } - } - ITopic topic = child.getTopic(); - int index = topic.getIndex(); - int newIndex = index + offset; - if (newIndex < 0 || newIndex >= total) - return; - - DeleteTopicCommand c1 = new DeleteTopicCommand(topic); - AddTopicCommand c2 = new AddTopicCommand(topic, parent.getTopic(), - newIndex, ITopic.ATTACHED); - commands.add(c1); - commands.add(c2); - } - if (commands.isEmpty()) - return; - - CompoundCommand command = new CompoundCommand(commands); - command.setLabel(CommandMessages.Command_MoveTopic); - saveAndRun(command, request.getTargetDomain()); - } - - private int getDirection(String direction) { - if (GEF.REQ_MOVE_UP.equals(direction)) - return PositionConstants.NORTH; - if (GEF.REQ_MOVE_DOWN.equals(direction)) - return PositionConstants.SOUTH; - if (GEF.REQ_MOVE_LEFT.equals(direction)) - return PositionConstants.WEST; - if (GEF.REQ_MOVE_RIGHT.equals(direction)) - return PositionConstants.EAST; - return -1; - } - - private void sortTopics(Request request) { - - } - - private void alignTopics(Request request) { - List topics = MindMapUtils.filterOutDescendents( - MindMapUtils.getTopics(request.getTargets()), null); - if (topics.isEmpty()) - return; - - Object param = request.getParameter(GEF.PARAM_ALIGNMENT); - if (param == null || !(param instanceof Integer)) - return; - - int alignment = ((Integer) param).intValue(); - - IViewer viewer = request.getTargetViewer(); - List topicParts = new ArrayList(topics.size()); - for (ITopic topic : topics) { - IPart p = viewer.findPart(topic); - if (p instanceof ITopicPart) { - topicParts.add((ITopicPart) p); - } - } - if (topicParts.isEmpty()) - return; - - TopicAlignmentSolver solver = new TopicAlignmentSolver(alignment); - solver.recordInitPositions(topicParts); - solver.solve(); - - List commands = new ArrayList(topicParts.size()); - for (Object key : solver.getKeys(IIntersectionSolver.CATEGORY_FREE)) { - if (key instanceof ITopicPart) { - ITopicPart topicPart = (ITopicPart) key; - Point pos = solver.getSolvedPosition(key); - pos = getNewPosition(topicPart, pos); - ITopic topic = topicPart.getTopic(); - commands.add(new ModifyPositionCommand(topic, - MindMapUtils.toModelPosition(pos))); - } - } - if (commands.isEmpty()) - return; - - String commandLabel = getAlignCommandLabel(alignment); - CompoundCommand cmd = new CompoundCommand(commands); - cmd.setLabel(commandLabel); - saveAndRun(cmd, request.getTargetDomain()); - } - - private String getAlignCommandLabel(int alignment) { - switch (alignment) { - case PositionConstants.LEFT: - return CommandMessages.Command_AlignLeft; - case PositionConstants.CENTER: - return CommandMessages.Command_AlignCenter; - case PositionConstants.RIGHT: - return CommandMessages.Command_AlignRight; - case PositionConstants.TOP: - return CommandMessages.Command_AlignTop; - case PositionConstants.MIDDLE: - return CommandMessages.Command_AlignMiddle; - case PositionConstants.BOTTOM: - return CommandMessages.Command_AlignBottom; - } - return CommandMessages.Command_Align; - } - - private Point getNewPosition(ITopicPart topicPart, Point pos) { - IBranchPart branch = topicPart.getOwnerBranch(); - if (branch != null) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - Point parentPos = ((IReferencedFigure) parent.getFigure()) - .getReference(); - pos = new Point(pos.x - parentPos.x, pos.y - parentPos.y); - } - } - return pos; - } - - private boolean hasCallout(List topics) { - if (topics == null || topics.isEmpty()) - return false; - - for (ITopic callout : topics) { - if (ITopic.CALLOUT.equals(callout.getType())) - return true; - } - - return false; - } - - private void moveOrCopyTopics(Request request) { - List sources = request.getTargets(); - List topics = MindMapUtils - .filterOutDescendents(MindMapUtils.getTopics(sources), null); - if (topics.isEmpty()) - return; - Collections.sort(topics, Core.getTopicComparator()); - - Point targetPosition = (Point) request.getParameter(GEF.PARAM_POSITION); - ITopicPart parentPart = getTargetParent(request); - boolean copy = Boolean.TRUE - .equals(request.getParameter(MindMapUI.PARAM_COPY)); - - if (targetPosition == null && parentPart == null && !copy) - return; - - boolean relative = Boolean.TRUE - .equals(request.getParameter(GEF.PARAM_POSITION_RELATIVE)); - int targetIndex = request.getIntParameter(GEF.PARAM_INDEX, -1); - - IViewer viewer = request.getTargetViewer(); - ITopic targetParent; - String targetType; - if (parentPart != null) { - targetParent = parentPart.getTopic(); - //can't add itself as child - if (topics.contains(targetParent)) - return; - - if (hasCallout(topics)) { - targetType = ITopic.CALLOUT; - } else { - targetType = ITopic.ATTACHED; - } - } else { - targetParent = (ITopic) viewer.getAdapter(ITopic.class); - targetType = ITopic.DETACHED; - - parentPart = (ITopicPart) viewer.getAdapter(ITopicPart.class); - } - if (targetParent == null - || (!copy && !isValidMoveToNewParent(targetParent, topics))) - // Sorry, NO valid parent topic has been found to add these topics - return; - - TopicMoveCommandBuilder builder = new TopicMoveCommandBuilder(viewer, - request.getTargetCommandStack(), targetParent, targetIndex, - targetType, targetPosition, relative); - - IBranchPart parentBranch = MindMapUtils.findBranch(parentPart); - if (parentBranch == null) - return; - - ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - if (centralTopic == null) - return; - - String centralTopicStructure = centralTopic.getStructureClass(); - boolean isUnbalancedStructure = centralTopicStructure == null - || UnbalancedData.STRUCTUREID_UNBALANCED - .equalsIgnoreCase(centralTopicStructure); - - if (isUnbalancedStructure) { - ITopicExtension extension = centralTopic.createExtension( - UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); - ITopicExtensionElement element = extension.getContent() - .getCreatedChild( - UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); - - String preMoveRightNum = element.getTextContent(); - if (preMoveRightNum == null) - preMoveRightNum = String.valueOf(0); - int postMoveRightNum = Integer.valueOf(preMoveRightNum); - for (IPart selected : sources) { - IBranchPart mainBranch = MindMapUtils.findBranch(selected); - if (mainBranch != null && !mainBranch.isCentral()) { - IBranchPart centralBranch = mainBranch.getParentBranch(); - if (centralBranch != null && centralBranch.isCentral()) { - IStructure structure = centralBranch.getBranchPolicy() - .getStructure(centralBranch); - if ((((IBranchStructureExtension) structure) - .getChildTargetOrientation(centralBranch, - mainBranch) == PositionConstants.WEST)) { - postMoveRightNum--; - } - } - if (parentBranch.isCentral() - && targetType != ITopic.DETACHED) { - Rectangle bounds = parentPart.getFigure().getBounds(); - boolean positionRight = bounds.getCenter() - .getDifference((Point) request.getParameter( - GEF.PARAM_POSITION_ABSOLUTE)).width < 0; - - org.xmind.core.util.Point position = mainBranch - .getTopic().getPosition(); -// boolean topicPosForceRight = position != null && position.x > 0; -// boolean posRight = position == null && positionRight; - - boolean right = position != null ? position.x > 0 - : positionRight; - - if (right) { - postMoveRightNum++; - } - } - } - } - - if (!preMoveRightNum.equals(postMoveRightNum)) { - ModifyRightNumberOfUnbalancedStructureCommand modifyRightNumberCommand = new ModifyRightNumberOfUnbalancedStructureCommand( - centralTopic, preMoveRightNum, postMoveRightNum); - modifyRightNumberCommand - .setLabel(copy ? CommandMessages.Command_CopyTopic - : CommandMessages.Command_MoveTopic); - builder.addPendingCommand(modifyRightNumberCommand, true); - } - } - - PropertyCommandBuilder builder2 = new PropertyCommandBuilder(viewer, - builder, request); - - if (!builder.canStart()) - return; - - builder.setLabel(copy ? CommandMessages.Command_CopyTopic - : CommandMessages.Command_MoveTopic); - builder.start(); - builder2.start(); - if (copy) - builder.copyTopics(topics); - else - builder.moveTopics(topics); - - builder2.addSources(topics.toArray(), true); - - builder2.end(); - builder.end(); -// saveAndRun(cmd, request.getTargetDomain()); - Command cmd = builder.getCommand(); - if (cmd instanceof ISourceProvider) { - select(((ISourceProvider) cmd).getSources(), viewer); - } - } - - private ITopicPart getTargetParent(Request request) { - Object param = request.getParameter(GEF.PARAM_PARENT); - if (param instanceof ITopicPart) - return (ITopicPart) param; - return null; - } - - private boolean isValidMoveToNewParent(ITopic newParent, - List topics) { - if (MindMapUtils.isAncestorInList(newParent, topics)) - return false; - Set ranges = MindMapUtils.findContainedRanges(topics, true, - false); - if (!ranges.isEmpty()) { - for (ITopicRange range : ranges) { - ITopic summaryTopic = ((ISummary) range).getTopic(); - if (summaryTopic != null - && (summaryTopic.equals(newParent) || MindMapUtils - .isDescendentOf(newParent, summaryTopic))) - return false; - } - } - return true; - } - -// private Command createReorganizeCommand(Request request, -// List topics, IViewer viewer, Point position, -// boolean relative, ITopic parent, int index, String type, -// boolean copy) { -// -// TopicMoveCommandBuilder builder = new TopicMoveCommandBuilder(viewer, -// parent, index, type, position, relative, copy); -// for (ITopic t : topics) { -// builder.moveTopic(t); -// } -// PropertyCommandBuilder propCmdBuilder = new PropertyCommandBuilder( -// viewer); -// propCmdBuilder.addFromRequest(request, false); -// if (!propCmdBuilder.isEmpty()) { -// for (Command c : propCmdBuilder.getCommands()) { -// builder.addCommand(c, false); -// } -// } -// return builder.createCommand(); -// } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.core.Core; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.core.ITopicRange; +import org.xmind.gef.GEF; +import org.xmind.gef.ISourceProvider; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.command.Command; +import org.xmind.gef.command.CompoundCommand; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.geometry.IIntersectionSolver; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.IBranchStructureExtension; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.DeleteTopicCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyRightNumberOfUnbalancedStructureCommand; +import org.xmind.ui.internal.branch.UnbalancedData; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class TopicMovablePolicy extends MindMapPolicyBase { + + public boolean understands(String requestType) { + return super.understands(requestType) + || GEF.REQ_MOVETO.equals(requestType) + || GEF.REQ_COPYTO.equals(requestType) + || GEF.REQ_ALIGN.equals(requestType) + || GEF.REQ_MOVE_UP.equals(requestType) + || GEF.REQ_MOVE_DOWN.equals(requestType) + || GEF.REQ_MOVE_LEFT.equals(requestType) + || GEF.REQ_MOVE_RIGHT.equals(requestType) + || GEF.REQ_SORT.equals(requestType); + } + + public void handle(Request request) { + String requestType = request.getType(); + if (GEF.REQ_MOVETO.equals(requestType) + || GEF.REQ_COPYTO.equals(requestType)) { + moveOrCopyTopics(request); + } else if (GEF.REQ_ALIGN.equals(requestType)) { + alignTopics(request); + } else if (GEF.REQ_SORT.equals(requestType)) { + sortTopics(request); + } else if (GEF.REQ_MOVE_UP.equals(requestType) + || GEF.REQ_MOVE_DOWN.equals(requestType) + || GEF.REQ_MOVE_LEFT.equals(requestType) + || GEF.REQ_MOVE_RIGHT.equals(requestType)) { + quickMove(request, requestType); + } + } + + private void quickMove(Request request, String direction) { + int dir = getDirection(direction); + if (dir < 0) + return; + + IBranchPart parent = null; + List branches = new ArrayList(); + for (IPart p : request.getTargets()) { + IBranchPart branch = MindMapUtils.findBranch(p); + if (branch != null) { + if (!branch.getTopic().isAttached()) + return; + if (parent != null && parent != branch.getParentBranch()) + return; + if (parent == null) + parent = branch.getParentBranch(); + if (parent == null) + return; + branches.add(branch); + } + } + if (parent == null) + return; + + IStructure structure = parent.getBranchPolicy().getStructure(parent); + if (!(structure instanceof IBranchStructureExtension)) + return; + + Collections.sort(branches, new Comparator() { + public int compare(IBranchPart o1, IBranchPart o2) { + return o1.getBranchIndex() - o2.getBranchIndex(); + } + }); + IBranchStructureExtension bse = (IBranchStructureExtension) structure; + List commands = new ArrayList(); + int total = parent.getTopic().getChildren(ITopic.ATTACHED).size(); + for (int i = 0; i < branches.size(); i++) { + IBranchPart child = branches.get(i); + int offset = bse.getQuickMoveOffset(parent, child, dir); + if (offset > 0) { + for (int j = child.getBranchIndex() + 1; j < parent + .getSubBranches().size(); j++) { + IBranchPart b = parent.getSubBranches().get(j); + if (!branches.contains(b)) + break; + offset++; + } + } + ITopic topic = child.getTopic(); + int index = topic.getIndex(); + int newIndex = index + offset; + if (newIndex < 0 || newIndex >= total) + return; + + DeleteTopicCommand c1 = new DeleteTopicCommand(topic); + AddTopicCommand c2 = new AddTopicCommand(topic, parent.getTopic(), + newIndex, ITopic.ATTACHED); + commands.add(c1); + commands.add(c2); + } + if (commands.isEmpty()) + return; + + CompoundCommand command = new CompoundCommand(commands); + command.setLabel(CommandMessages.Command_MoveTopic); + saveAndRun(command, request.getTargetDomain()); + } + + private int getDirection(String direction) { + if (GEF.REQ_MOVE_UP.equals(direction)) + return PositionConstants.NORTH; + if (GEF.REQ_MOVE_DOWN.equals(direction)) + return PositionConstants.SOUTH; + if (GEF.REQ_MOVE_LEFT.equals(direction)) + return PositionConstants.WEST; + if (GEF.REQ_MOVE_RIGHT.equals(direction)) + return PositionConstants.EAST; + return -1; + } + + private void sortTopics(Request request) { + + } + + private void alignTopics(Request request) { + List topics = MindMapUtils.filterOutDescendents( + MindMapUtils.getTopics(request.getTargets()), null); + if (topics.isEmpty()) + return; + + Object param = request.getParameter(GEF.PARAM_ALIGNMENT); + if (param == null || !(param instanceof Integer)) + return; + + int alignment = ((Integer) param).intValue(); + + IViewer viewer = request.getTargetViewer(); + List topicParts = new ArrayList(topics.size()); + for (ITopic topic : topics) { + IPart p = viewer.findPart(topic); + if (p instanceof ITopicPart) { + topicParts.add((ITopicPart) p); + } + } + if (topicParts.isEmpty()) + return; + + TopicAlignmentSolver solver = new TopicAlignmentSolver(alignment); + solver.recordInitPositions(topicParts); + solver.solve(); + + List commands = new ArrayList(topicParts.size()); + for (Object key : solver.getKeys(IIntersectionSolver.CATEGORY_FREE)) { + if (key instanceof ITopicPart) { + ITopicPart topicPart = (ITopicPart) key; + Point pos = solver.getSolvedPosition(key); + pos = getNewPosition(topicPart, pos); + ITopic topic = topicPart.getTopic(); + commands.add(new ModifyPositionCommand(topic, + MindMapUtils.toModelPosition(pos))); + } + } + if (commands.isEmpty()) + return; + + String commandLabel = getAlignCommandLabel(alignment); + CompoundCommand cmd = new CompoundCommand(commands); + cmd.setLabel(commandLabel); + saveAndRun(cmd, request.getTargetDomain()); + } + + private String getAlignCommandLabel(int alignment) { + switch (alignment) { + case PositionConstants.LEFT: + return CommandMessages.Command_AlignLeft; + case PositionConstants.CENTER: + return CommandMessages.Command_AlignCenter; + case PositionConstants.RIGHT: + return CommandMessages.Command_AlignRight; + case PositionConstants.TOP: + return CommandMessages.Command_AlignTop; + case PositionConstants.MIDDLE: + return CommandMessages.Command_AlignMiddle; + case PositionConstants.BOTTOM: + return CommandMessages.Command_AlignBottom; + } + return CommandMessages.Command_Align; + } + + private Point getNewPosition(ITopicPart topicPart, Point pos) { + IBranchPart branch = topicPart.getOwnerBranch(); + if (branch != null) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + Point parentPos = ((IReferencedFigure) parent.getFigure()) + .getReference(); + pos = new Point(pos.x - parentPos.x, pos.y - parentPos.y); + } + } + return pos; + } + + private boolean hasCallout(List topics) { + if (topics == null || topics.isEmpty()) + return false; + + for (ITopic callout : topics) { + if (ITopic.CALLOUT.equals(callout.getType())) + return true; + } + + return false; + } + + private void moveOrCopyTopics(Request request) { + List sources = request.getTargets(); + List topics = MindMapUtils + .filterOutDescendents(MindMapUtils.getTopics(sources), null); + if (topics.isEmpty()) + return; + Collections.sort(topics, Core.getTopicComparator()); + + Point targetPosition = (Point) request.getParameter(GEF.PARAM_POSITION); + ITopicPart parentPart = getTargetParent(request); + boolean copy = Boolean.TRUE + .equals(request.getParameter(MindMapUI.PARAM_COPY)); + + if (targetPosition == null && parentPart == null && !copy) + return; + + boolean relative = Boolean.TRUE + .equals(request.getParameter(GEF.PARAM_POSITION_RELATIVE)); + int targetIndex = request.getIntParameter(GEF.PARAM_INDEX, -1); + + IViewer viewer = request.getTargetViewer(); + ITopic targetParent; + String targetType; + if (parentPart != null) { + targetParent = parentPart.getTopic(); + //can't add itself as child + if (topics.contains(targetParent)) + return; + + if (hasCallout(topics)) { + targetType = ITopic.CALLOUT; + } else { + targetType = ITopic.ATTACHED; + } + } else { + targetParent = (ITopic) viewer.getAdapter(ITopic.class); + targetType = ITopic.DETACHED; + + parentPart = (ITopicPart) viewer.getAdapter(ITopicPart.class); + } + if (targetParent == null + || (!copy && !isValidMoveToNewParent(targetParent, topics))) + // Sorry, NO valid parent topic has been found to add these topics + return; + + TopicMoveCommandBuilder builder = new TopicMoveCommandBuilder(viewer, + request.getTargetCommandStack(), targetParent, targetIndex, + targetType, targetPosition, relative); + + IBranchPart parentBranch = MindMapUtils.findBranch(parentPart); + if (parentBranch == null) + return; + + ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); + if (centralTopic == null) + return; + + String centralTopicStructure = centralTopic.getStructureClass(); + boolean isUnbalancedStructure = centralTopicStructure == null + || UnbalancedData.STRUCTUREID_UNBALANCED + .equalsIgnoreCase(centralTopicStructure); + + if (isUnbalancedStructure) { + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtensionElement element = extension.getContent() + .getCreatedChild( + UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); + + String preMoveRightNum = element.getTextContent(); + if (preMoveRightNum == null) + preMoveRightNum = String.valueOf(0); + int postMoveRightNum = Integer.valueOf(preMoveRightNum); + for (IPart selected : sources) { + IBranchPart mainBranch = MindMapUtils.findBranch(selected); + if (mainBranch != null && !mainBranch.isCentral()) { + IBranchPart centralBranch = mainBranch.getParentBranch(); + if (centralBranch != null && centralBranch.isCentral()) { + IStructure structure = centralBranch.getBranchPolicy() + .getStructure(centralBranch); + if ((((IBranchStructureExtension) structure) + .getChildTargetOrientation(centralBranch, + mainBranch) == PositionConstants.WEST)) { + postMoveRightNum--; + } + } + if (parentBranch.isCentral() + && targetType != ITopic.DETACHED) { + Rectangle bounds = parentPart.getFigure().getBounds(); + boolean positionRight = bounds.getCenter() + .getDifference((Point) request.getParameter( + GEF.PARAM_POSITION_ABSOLUTE)).width < 0; + + org.xmind.core.util.Point position = mainBranch + .getTopic().getPosition(); +// boolean topicPosForceRight = position != null && position.x > 0; +// boolean posRight = position == null && positionRight; + + boolean right = position != null ? position.x > 0 + : positionRight; + + if (right) { + postMoveRightNum++; + } + } + } + } + + if (!preMoveRightNum.equals(postMoveRightNum)) { + ModifyRightNumberOfUnbalancedStructureCommand modifyRightNumberCommand = new ModifyRightNumberOfUnbalancedStructureCommand( + centralTopic, preMoveRightNum, postMoveRightNum); + modifyRightNumberCommand + .setLabel(copy ? CommandMessages.Command_CopyTopic + : CommandMessages.Command_MoveTopic); + builder.addPendingCommand(modifyRightNumberCommand, true); + } + } + + PropertyCommandBuilder builder2 = new PropertyCommandBuilder(viewer, + builder, request); + + if (!builder.canStart()) + return; + + builder.setLabel(copy ? CommandMessages.Command_CopyTopic + : CommandMessages.Command_MoveTopic); + builder.start(); + builder2.start(); + if (copy) + builder.copyTopics(topics); + else + builder.moveTopics(topics); + + builder2.addSources(topics.toArray(), true); + + builder2.end(); + builder.end(); +// saveAndRun(cmd, request.getTargetDomain()); + Command cmd = builder.getCommand(); + if (cmd instanceof ISourceProvider) { + select(((ISourceProvider) cmd).getSources(), viewer); + } + } + + private ITopicPart getTargetParent(Request request) { + Object param = request.getParameter(GEF.PARAM_PARENT); + if (param instanceof ITopicPart) + return (ITopicPart) param; + return null; + } + + private boolean isValidMoveToNewParent(ITopic newParent, + List topics) { + if (MindMapUtils.isAncestorInList(newParent, topics)) + return false; + Set ranges = MindMapUtils.findContainedRanges(topics, true, + false); + if (!ranges.isEmpty()) { + for (ITopicRange range : ranges) { + ITopic summaryTopic = ((ISummary) range).getTopic(); + if (summaryTopic != null + && (summaryTopic.equals(newParent) || MindMapUtils + .isDescendentOf(newParent, summaryTopic))) + return false; + } + } + return true; + } + +// private Command createReorganizeCommand(Request request, +// List topics, IViewer viewer, Point position, +// boolean relative, ITopic parent, int index, String type, +// boolean copy) { +// +// TopicMoveCommandBuilder builder = new TopicMoveCommandBuilder(viewer, +// parent, index, type, position, relative, copy); +// for (ITopic t : topics) { +// builder.moveTopic(t); +// } +// PropertyCommandBuilder propCmdBuilder = new PropertyCommandBuilder( +// viewer); +// propCmdBuilder.addFromRequest(request, false); +// if (!propCmdBuilder.isEmpty()) { +// for (Command c : propCmdBuilder.getCommands()) { +// builder.addCommand(c, false); +// } +// } +// return builder.createCommand(); +// } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMoveCommandBuilder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMoveCommandBuilder.java index 62f7f0bb2..ed5bd34bc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMoveCommandBuilder.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicMoveCommandBuilder.java @@ -1,459 +1,459 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Point; -import org.xmind.core.IBoundary; -import org.xmind.core.IRelationship; -import org.xmind.core.ISummary; -import org.xmind.core.ITopic; -import org.xmind.core.ITopicRange; -import org.xmind.gef.IViewer; -import org.xmind.gef.command.ICommandStack; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.part.IGraphicalPart; -import org.xmind.gef.part.IPart; -import org.xmind.ui.commands.AddBoundaryCommand; -import org.xmind.ui.commands.AddSummaryCommand; -import org.xmind.ui.commands.AddTopicCommand; -import org.xmind.ui.commands.CloneTopicCommand; -import org.xmind.ui.commands.CommandBuilder; -import org.xmind.ui.commands.DeleteBoundaryCommand; -import org.xmind.ui.commands.DeleteSummaryCommand; -import org.xmind.ui.commands.DeleteTopicCommand; -import org.xmind.ui.commands.ModifyBoundaryMasterCommand; -import org.xmind.ui.commands.ModifyPositionCommand; -import org.xmind.ui.commands.ModifyRangeCommand; -import org.xmind.ui.util.MindMapUtils; - -public class TopicMoveCommandBuilder extends DeleteCommandBuilder { - - private static class TopicInfo { - public ITopic oldParent; - public int oldIndex; - public String oldType; - public Point newPosition; - public boolean needsReorganize; - } - - private static final List EMPTY_TOPICS = Collections.emptyList(); - - private ITopic targetParent; - - private int targetIndex; - - private String targetType; - - private Point targetPosition; - - private boolean relative; - - private int insertIndex; - - private Set cachedParent = null; - - private Map> oldRangedTopics = null; - - private Set rangesToMove = null; - - public TopicMoveCommandBuilder(IViewer viewer, CommandBuilder delegate, - ITopic targetParent, int targetIndex, String targetType, - Point targetPosition, boolean relative) { - super(viewer, delegate); - init(targetParent, targetIndex, targetType, targetPosition, relative); - } - - public TopicMoveCommandBuilder(IViewer viewer, ICommandStack commandStack, - ITopic targetParent, int targetIndex, String targetType, - Point targetPosition, boolean relative) { - super(viewer, commandStack); - init(targetParent, targetIndex, targetType, targetPosition, relative); - } - - private void init(ITopic targetParent, int targetIndex, String targetType, - Point targetPosition, boolean relative) { - this.targetParent = targetParent; - this.targetIndex = targetIndex; - this.targetType = targetType; - this.targetPosition = targetPosition; - this.relative = relative; - - this.insertIndex = targetIndex; - if (this.insertIndex < 0) { - this.insertIndex = targetParent.getChildren(targetType).size(); - } - } - - public int getTargetIndex() { - return targetIndex; - } - - public ITopic getTargetParent() { - return targetParent; - } - - public Point getTargetPosition() { - return targetPosition; - } - - public String getTargetType() { - return targetType; - } - - public boolean isRelative() { - return relative; - } - - public int getInsertIndex() { - return insertIndex; - } - -// public void moveTopic(ITopic topic) { -// moveTopic(topic, insertIndex); -// insertIndex++; -// } -// -// public void copyTopic(ITopic topic) { -// copyTopic(topic, insertIndex); -// insertIndex++; -// } - - public void copyTopics(List topics) { - for (ITopic topic : topics) { - copyTopic(topic, insertIndex); - insertIndex++; - } - } - - public void moveTopics(List topics) { - Map oldInfo = new HashMap( - topics.size()); - for (ITopic topic : topics) { - TopicInfo info = deleteTopic(topic, insertIndex); - if (!oldInfo.containsKey(topic)) { - oldInfo.put(topic, info); - } - } - for (ITopic topic : topics) { - moveTopic(topic, insertIndex, oldInfo.get(topic)); - insertIndex++; - } - } - - private TopicInfo deleteTopic(ITopic topic, int toIndex) { - TopicInfo info = new TopicInfo(); - info.oldParent = topic.getParent(); - info.oldIndex = topic.getIndex(); - info.oldType = topic.getType(); - info.newPosition = calculateTargetPosition(topic); - info.needsReorganize = needsReorganize(topic, toIndex, info.oldParent, - info.oldIndex, info.oldType); - if (info.needsReorganize) { - if (!isCached(info.oldParent)) { - for (ITopicRange range : getSubRanges(info.oldParent)) { - cacheOldRangedTopics(range, info.oldParent); - } - } - deleteTopic(topic, true); - } - return info; - } - - private void moveTopic(ITopic topic, int toIndex, TopicInfo info) { -// ITopic oldParent = topic.getParent(); -// int oldIndex = topic.getIndex(); -// String oldType = topic.getType(); -// Point toPosition = calculateTargetPosition(topic); -// boolean needsReorganize = needsReorganize(topic, toIndex, oldParent, -// oldIndex, oldType); -// if (needsReorganize) { -// if (!isCached(oldParent)) { -// for (ITopicRange range : getSubRanges(oldParent)) { -// cacheOldRangedTopics(range, oldParent); -// } -// } -// deleteTopic(topic, true); -// } - - add(new ModifyPositionCommand(topic, - MindMapUtils.toModelPosition(info.newPosition)), - !info.needsReorganize); - if (info.needsReorganize) { - addTopic(topic, getTargetParent(), toIndex, getTargetType(), true); - if (rangesToMove != null && !rangesToMove.isEmpty()) { - while (!rangesToMove.isEmpty()) { - ITopicRange range = rangesToMove.iterator().next(); - moveRange(range, range.getParent()); - rangesToMove.remove(range); - } - } - } - } - - private void addTopic(ITopic topic, ITopic toParent, int toIndex, - String toType, boolean topicCollectable) { - add(new AddTopicCommand(topic, toParent, toIndex, toType), - topicCollectable); - if (ITopic.ATTACHED.equals(toType)) { - int topicIndex = topic.getIndex(); - enlargeOldBoundaries(topic, toParent, topicIndex); - moveMasterBoundaries(topic, topicIndex); - } - } - - private void enlargeOldBoundaries(ITopic topic, ITopic parent, int index) { - Set ranges = getSubRanges(parent); - for (ITopicRange range : ranges) { - int startIndex = range.getStartIndex(); - int endIndex = range.getEndIndex(); - if (index <= endIndex) { - add(new ModifyRangeCommand(range, endIndex + 1, false), false); - } - if (index <= startIndex) { - add(new ModifyRangeCommand(range, startIndex + 1, true), false); - } - } - } - - private void moveMasterBoundaries(ITopic topic, int topicIndex) { - IBoundary masterBoundary = null; - for (Object o : getSubRanges(topic).toArray()) { - ITopicRange range = (ITopicRange) o; - if (range instanceof IBoundary) { - IBoundary boundary = (IBoundary) range; - if (boundary.isMasterBoundary() && masterBoundary == null) { - masterBoundary = boundary; - addDeleteRangeCommand(boundary, topic); - } - } - } - - if (masterBoundary != null) { - IBoundary existingSingleBoundary = findSingleBoundary( - getTargetParent(), topicIndex); - if (existingSingleBoundary == null) { - add(new ModifyBoundaryMasterCommand(masterBoundary, false), - false); - add(new ModifyRangeCommand(masterBoundary, topicIndex, true), - false); - add(new ModifyRangeCommand(masterBoundary, topicIndex, false), - false); - addAddRangeCommand(masterBoundary, getTargetParent()); - } - } - } - - private IBoundary findSingleBoundary(ITopic parent, int childIndex) { - for (ITopicRange range : getSubRanges(parent)) { - if (range instanceof IBoundary - && range.getStartIndex() == childIndex - && range.getEndIndex() == childIndex) - return (IBoundary) range; - } - return null; - } - - private IBoundary findMasterBoundary(ITopic parent) { - for (ITopicRange range : getSubRanges(parent)) { - if (range instanceof IBoundary - && ((IBoundary) range).isMasterBoundary()) - return (IBoundary) range; - } - return null; - } - - private void moveRange(ITopicRange range, ITopic oldParent) { - ITopic summaryTopic = null; - if (range instanceof ISummary) { - summaryTopic = ((ISummary) range).getTopic(); - if (summaryTopic != null) { - add(new DeleteTopicCommand(summaryTopic), false); - } - } - addDeleteRangeCommand(range, oldParent); - List rangedTopics = getOldRangedTopics(range); - if (!rangedTopics.isEmpty()) { - if (ITopic.ATTACHED.equals(getTargetType())) { - int startIndex = rangedTopics.get(0).getIndex(); - int endIndex = rangedTopics.get(rangedTopics.size() - 1) - .getIndex(); - add(new ModifyRangeCommand(range, startIndex, true), false); - add(new ModifyRangeCommand(range, endIndex, false), false); - addAddRangeCommand(range, getTargetParent()); - if (summaryTopic != null) { - addTopic(summaryTopic, getTargetParent(), -1, - ITopic.SUMMARY, false); - } - } else if (range instanceof IBoundary && rangedTopics.size() == 1) { - ITopic topic = rangedTopics.get(0); - IBoundary overallBoundary = findMasterBoundary(topic); - if (overallBoundary == null) { - add(new ModifyRangeCommand(range, -1, true), false); - add(new ModifyRangeCommand(range, -1, false), false); - add(new ModifyBoundaryMasterCommand((IBoundary) range, - true), false); - addAddRangeCommand(range, topic); - } - } - } - } - - private void addDeleteRangeCommand(ITopicRange range, ITopic oldParent) { - if (range instanceof IBoundary) { - add(new DeleteBoundaryCommand((IBoundary) range), false); - } else if (range instanceof ISummary) { - add(new DeleteSummaryCommand((ISummary) range), false); - } - removeSubRange(range, oldParent); - } - - private void addAddRangeCommand(ITopicRange range, ITopic newParent) { - if (range instanceof IBoundary) { - add(new AddBoundaryCommand((IBoundary) range, newParent), false); - } else if (range instanceof ISummary) { - add(new AddSummaryCommand((ISummary) range, newParent), false); - } - addSubRange(range, newParent); - } - - protected void deleteBoundary(IBoundary boundary, - boolean sourceCollectable) { - if (rangesToMove == null) - rangesToMove = new HashSet(); - rangesToMove.add(boundary); - } - - protected void deleteSummary(ISummary summary, boolean sourceCollectable) { - if (rangesToMove == null) - rangesToMove = new HashSet(); - rangesToMove.add(summary); - } - - protected void deleteRelationship(IRelationship relationship, - boolean sourceCollectable) { - } - - private Point calculateTargetPosition(ITopic topic) { - Point position = getTargetPosition(); - if (position == null) - return null; - - IPart parentPart = getViewer().findPart(getTargetParent()); - if (parentPart == null) - return null; - - Point parentPosition = getPosition((IGraphicalPart) parentPart); - if (parentPosition == null) - return null; - - if (isRelative()) { - IPart topicPart = getViewer().findPart(topic); - if (topicPart == null) - return null; - - Point oldPosition = getPosition((IGraphicalPart) topicPart); - return toNewPosition(parentPosition, oldPosition, position); - } - return toNewPosition(parentPosition, position); - } - - protected static Point getPosition(IGraphicalPart part) { - IFigure figure = part.getFigure(); - if (figure instanceof IReferencedFigure) { - return ((IReferencedFigure) figure).getReference(); - } - return figure.getBounds().getLocation(); - } - - private static Point toNewPosition(Point parentPosition, Point oldPosition, - Point position) { - int x = oldPosition.x + position.x - parentPosition.x; - int y = oldPosition.y + position.y - parentPosition.y; - return new Point(x, y); - } - - private static Point toNewPosition(Point parentPosition, Point position) { - int x = position.x - parentPosition.x; - int y = position.y - parentPosition.y; - return new Point(x, y); - } - - private boolean needsReorganize(ITopic topic, int toIndex, ITopic oldParent, - int oldIndex, String oldType) { - if (!getTargetParent().equals(oldParent)) - return true; - if (oldType != getTargetType() - && (oldType == null || !oldType.equals(getTargetType()))) - return true; - - if (ITopic.ATTACHED.equals(oldType) - && oldIndex != getValidAttachedIndex(oldParent, toIndex)) - return true; - return false; - } - - private int getValidAttachedIndex(ITopic parent, int index) { - int size = parent.getChildren(ITopic.ATTACHED).size(); - return index >= size ? index - 1 : index; - } - - protected boolean isCached(ITopic parent) { - return cachedParent != null && cachedParent.contains(parent); - } - - protected void cacheOldRangedTopics(ITopicRange range, ITopic parent) { - if (cachedParent == null) { - cachedParent = new HashSet(); - } - cachedParent.add(parent); - if (oldRangedTopics == null) - oldRangedTopics = new HashMap>(); - List list = oldRangedTopics.get(range); - if (list == null) { - list = new ArrayList(range.getEnclosingTopics()); - oldRangedTopics.put(range, list); - } - } - - protected List getOldRangedTopics(ITopicRange range) { - if (oldRangedTopics != null) { - List list = oldRangedTopics.get(range); - if (list != null) - return list; - } - return EMPTY_TOPICS; - } - - private void copyTopic(ITopic topic, int toIndex) { - Point position = calculateTargetPosition(topic); - CloneTopicCommand clone = new CloneTopicCommand( - getTargetParent().getOwnedWorkbook(), topic); - add(clone, true); - ITopic clonedTopic = (ITopic) clone.getSource(); - add(new ModifyPositionCommand(clonedTopic, - MindMapUtils.toModelPosition(position)), false); - addTopic(clonedTopic, getTargetParent(), toIndex, getTargetType(), - true); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.xmind.core.IBoundary; +import org.xmind.core.IRelationship; +import org.xmind.core.ISummary; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicRange; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.ICommandStack; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.ui.commands.AddBoundaryCommand; +import org.xmind.ui.commands.AddSummaryCommand; +import org.xmind.ui.commands.AddTopicCommand; +import org.xmind.ui.commands.CloneTopicCommand; +import org.xmind.ui.commands.CommandBuilder; +import org.xmind.ui.commands.DeleteBoundaryCommand; +import org.xmind.ui.commands.DeleteSummaryCommand; +import org.xmind.ui.commands.DeleteTopicCommand; +import org.xmind.ui.commands.ModifyBoundaryMasterCommand; +import org.xmind.ui.commands.ModifyPositionCommand; +import org.xmind.ui.commands.ModifyRangeCommand; +import org.xmind.ui.util.MindMapUtils; + +public class TopicMoveCommandBuilder extends DeleteCommandBuilder { + + private static class TopicInfo { + public ITopic oldParent; + public int oldIndex; + public String oldType; + public Point newPosition; + public boolean needsReorganize; + } + + private static final List EMPTY_TOPICS = Collections.emptyList(); + + private ITopic targetParent; + + private int targetIndex; + + private String targetType; + + private Point targetPosition; + + private boolean relative; + + private int insertIndex; + + private Set cachedParent = null; + + private Map> oldRangedTopics = null; + + private Set rangesToMove = null; + + public TopicMoveCommandBuilder(IViewer viewer, CommandBuilder delegate, + ITopic targetParent, int targetIndex, String targetType, + Point targetPosition, boolean relative) { + super(viewer, delegate); + init(targetParent, targetIndex, targetType, targetPosition, relative); + } + + public TopicMoveCommandBuilder(IViewer viewer, ICommandStack commandStack, + ITopic targetParent, int targetIndex, String targetType, + Point targetPosition, boolean relative) { + super(viewer, commandStack); + init(targetParent, targetIndex, targetType, targetPosition, relative); + } + + private void init(ITopic targetParent, int targetIndex, String targetType, + Point targetPosition, boolean relative) { + this.targetParent = targetParent; + this.targetIndex = targetIndex; + this.targetType = targetType; + this.targetPosition = targetPosition; + this.relative = relative; + + this.insertIndex = targetIndex; + if (this.insertIndex < 0) { + this.insertIndex = targetParent.getChildren(targetType).size(); + } + } + + public int getTargetIndex() { + return targetIndex; + } + + public ITopic getTargetParent() { + return targetParent; + } + + public Point getTargetPosition() { + return targetPosition; + } + + public String getTargetType() { + return targetType; + } + + public boolean isRelative() { + return relative; + } + + public int getInsertIndex() { + return insertIndex; + } + +// public void moveTopic(ITopic topic) { +// moveTopic(topic, insertIndex); +// insertIndex++; +// } +// +// public void copyTopic(ITopic topic) { +// copyTopic(topic, insertIndex); +// insertIndex++; +// } + + public void copyTopics(List topics) { + for (ITopic topic : topics) { + copyTopic(topic, insertIndex); + insertIndex++; + } + } + + public void moveTopics(List topics) { + Map oldInfo = new HashMap( + topics.size()); + for (ITopic topic : topics) { + TopicInfo info = deleteTopic(topic, insertIndex); + if (!oldInfo.containsKey(topic)) { + oldInfo.put(topic, info); + } + } + for (ITopic topic : topics) { + moveTopic(topic, insertIndex, oldInfo.get(topic)); + insertIndex++; + } + } + + private TopicInfo deleteTopic(ITopic topic, int toIndex) { + TopicInfo info = new TopicInfo(); + info.oldParent = topic.getParent(); + info.oldIndex = topic.getIndex(); + info.oldType = topic.getType(); + info.newPosition = calculateTargetPosition(topic); + info.needsReorganize = needsReorganize(topic, toIndex, info.oldParent, + info.oldIndex, info.oldType); + if (info.needsReorganize) { + if (!isCached(info.oldParent)) { + for (ITopicRange range : getSubRanges(info.oldParent)) { + cacheOldRangedTopics(range, info.oldParent); + } + } + deleteTopic(topic, true); + } + return info; + } + + private void moveTopic(ITopic topic, int toIndex, TopicInfo info) { +// ITopic oldParent = topic.getParent(); +// int oldIndex = topic.getIndex(); +// String oldType = topic.getType(); +// Point toPosition = calculateTargetPosition(topic); +// boolean needsReorganize = needsReorganize(topic, toIndex, oldParent, +// oldIndex, oldType); +// if (needsReorganize) { +// if (!isCached(oldParent)) { +// for (ITopicRange range : getSubRanges(oldParent)) { +// cacheOldRangedTopics(range, oldParent); +// } +// } +// deleteTopic(topic, true); +// } + + add(new ModifyPositionCommand(topic, + MindMapUtils.toModelPosition(info.newPosition)), + !info.needsReorganize); + if (info.needsReorganize) { + addTopic(topic, getTargetParent(), toIndex, getTargetType(), true); + if (rangesToMove != null && !rangesToMove.isEmpty()) { + while (!rangesToMove.isEmpty()) { + ITopicRange range = rangesToMove.iterator().next(); + moveRange(range, range.getParent()); + rangesToMove.remove(range); + } + } + } + } + + private void addTopic(ITopic topic, ITopic toParent, int toIndex, + String toType, boolean topicCollectable) { + add(new AddTopicCommand(topic, toParent, toIndex, toType), + topicCollectable); + if (ITopic.ATTACHED.equals(toType)) { + int topicIndex = topic.getIndex(); + enlargeOldBoundaries(topic, toParent, topicIndex); + moveMasterBoundaries(topic, topicIndex); + } + } + + private void enlargeOldBoundaries(ITopic topic, ITopic parent, int index) { + Set ranges = getSubRanges(parent); + for (ITopicRange range : ranges) { + int startIndex = range.getStartIndex(); + int endIndex = range.getEndIndex(); + if (index <= endIndex) { + add(new ModifyRangeCommand(range, endIndex + 1, false), false); + } + if (index <= startIndex) { + add(new ModifyRangeCommand(range, startIndex + 1, true), false); + } + } + } + + private void moveMasterBoundaries(ITopic topic, int topicIndex) { + IBoundary masterBoundary = null; + for (Object o : getSubRanges(topic).toArray()) { + ITopicRange range = (ITopicRange) o; + if (range instanceof IBoundary) { + IBoundary boundary = (IBoundary) range; + if (boundary.isMasterBoundary() && masterBoundary == null) { + masterBoundary = boundary; + addDeleteRangeCommand(boundary, topic); + } + } + } + + if (masterBoundary != null) { + IBoundary existingSingleBoundary = findSingleBoundary( + getTargetParent(), topicIndex); + if (existingSingleBoundary == null) { + add(new ModifyBoundaryMasterCommand(masterBoundary, false), + false); + add(new ModifyRangeCommand(masterBoundary, topicIndex, true), + false); + add(new ModifyRangeCommand(masterBoundary, topicIndex, false), + false); + addAddRangeCommand(masterBoundary, getTargetParent()); + } + } + } + + private IBoundary findSingleBoundary(ITopic parent, int childIndex) { + for (ITopicRange range : getSubRanges(parent)) { + if (range instanceof IBoundary + && range.getStartIndex() == childIndex + && range.getEndIndex() == childIndex) + return (IBoundary) range; + } + return null; + } + + private IBoundary findMasterBoundary(ITopic parent) { + for (ITopicRange range : getSubRanges(parent)) { + if (range instanceof IBoundary + && ((IBoundary) range).isMasterBoundary()) + return (IBoundary) range; + } + return null; + } + + private void moveRange(ITopicRange range, ITopic oldParent) { + ITopic summaryTopic = null; + if (range instanceof ISummary) { + summaryTopic = ((ISummary) range).getTopic(); + if (summaryTopic != null) { + add(new DeleteTopicCommand(summaryTopic), false); + } + } + addDeleteRangeCommand(range, oldParent); + List rangedTopics = getOldRangedTopics(range); + if (!rangedTopics.isEmpty()) { + if (ITopic.ATTACHED.equals(getTargetType())) { + int startIndex = rangedTopics.get(0).getIndex(); + int endIndex = rangedTopics.get(rangedTopics.size() - 1) + .getIndex(); + add(new ModifyRangeCommand(range, startIndex, true), false); + add(new ModifyRangeCommand(range, endIndex, false), false); + addAddRangeCommand(range, getTargetParent()); + if (summaryTopic != null) { + addTopic(summaryTopic, getTargetParent(), -1, + ITopic.SUMMARY, false); + } + } else if (range instanceof IBoundary && rangedTopics.size() == 1) { + ITopic topic = rangedTopics.get(0); + IBoundary overallBoundary = findMasterBoundary(topic); + if (overallBoundary == null) { + add(new ModifyRangeCommand(range, -1, true), false); + add(new ModifyRangeCommand(range, -1, false), false); + add(new ModifyBoundaryMasterCommand((IBoundary) range, + true), false); + addAddRangeCommand(range, topic); + } + } + } + } + + private void addDeleteRangeCommand(ITopicRange range, ITopic oldParent) { + if (range instanceof IBoundary) { + add(new DeleteBoundaryCommand((IBoundary) range), false); + } else if (range instanceof ISummary) { + add(new DeleteSummaryCommand((ISummary) range), false); + } + removeSubRange(range, oldParent); + } + + private void addAddRangeCommand(ITopicRange range, ITopic newParent) { + if (range instanceof IBoundary) { + add(new AddBoundaryCommand((IBoundary) range, newParent), false); + } else if (range instanceof ISummary) { + add(new AddSummaryCommand((ISummary) range, newParent), false); + } + addSubRange(range, newParent); + } + + protected void deleteBoundary(IBoundary boundary, + boolean sourceCollectable) { + if (rangesToMove == null) + rangesToMove = new HashSet(); + rangesToMove.add(boundary); + } + + protected void deleteSummary(ISummary summary, boolean sourceCollectable) { + if (rangesToMove == null) + rangesToMove = new HashSet(); + rangesToMove.add(summary); + } + + protected void deleteRelationship(IRelationship relationship, + boolean sourceCollectable) { + } + + private Point calculateTargetPosition(ITopic topic) { + Point position = getTargetPosition(); + if (position == null) + return null; + + IPart parentPart = getViewer().findPart(getTargetParent()); + if (parentPart == null) + return null; + + Point parentPosition = getPosition((IGraphicalPart) parentPart); + if (parentPosition == null) + return null; + + if (isRelative()) { + IPart topicPart = getViewer().findPart(topic); + if (topicPart == null) + return null; + + Point oldPosition = getPosition((IGraphicalPart) topicPart); + return toNewPosition(parentPosition, oldPosition, position); + } + return toNewPosition(parentPosition, position); + } + + protected static Point getPosition(IGraphicalPart part) { + IFigure figure = part.getFigure(); + if (figure instanceof IReferencedFigure) { + return ((IReferencedFigure) figure).getReference(); + } + return figure.getBounds().getLocation(); + } + + private static Point toNewPosition(Point parentPosition, Point oldPosition, + Point position) { + int x = oldPosition.x + position.x - parentPosition.x; + int y = oldPosition.y + position.y - parentPosition.y; + return new Point(x, y); + } + + private static Point toNewPosition(Point parentPosition, Point position) { + int x = position.x - parentPosition.x; + int y = position.y - parentPosition.y; + return new Point(x, y); + } + + private boolean needsReorganize(ITopic topic, int toIndex, ITopic oldParent, + int oldIndex, String oldType) { + if (!getTargetParent().equals(oldParent)) + return true; + if (oldType != getTargetType() + && (oldType == null || !oldType.equals(getTargetType()))) + return true; + + if (ITopic.ATTACHED.equals(oldType) + && oldIndex != getValidAttachedIndex(oldParent, toIndex)) + return true; + return false; + } + + private int getValidAttachedIndex(ITopic parent, int index) { + int size = parent.getChildren(ITopic.ATTACHED).size(); + return index >= size ? index - 1 : index; + } + + protected boolean isCached(ITopic parent) { + return cachedParent != null && cachedParent.contains(parent); + } + + protected void cacheOldRangedTopics(ITopicRange range, ITopic parent) { + if (cachedParent == null) { + cachedParent = new HashSet(); + } + cachedParent.add(parent); + if (oldRangedTopics == null) + oldRangedTopics = new HashMap>(); + List list = oldRangedTopics.get(range); + if (list == null) { + list = new ArrayList(range.getEnclosingTopics()); + oldRangedTopics.put(range, list); + } + } + + protected List getOldRangedTopics(ITopicRange range) { + if (oldRangedTopics != null) { + List list = oldRangedTopics.get(range); + if (list != null) + return list; + } + return EMPTY_TOPICS; + } + + private void copyTopic(ITopic topic, int toIndex) { + Point position = calculateTargetPosition(topic); + CloneTopicCommand clone = new CloneTopicCommand( + getTargetParent().getOwnedWorkbook(), topic); + add(clone, true); + ITopic clonedTopic = (ITopic) clone.getSource(); + add(new ModifyPositionCommand(clonedTopic, + MindMapUtils.toModelPosition(position)), false); + addTopic(clonedTopic, getTargetParent(), toIndex, getTargetType(), + true); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicNavigablePolicy.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicNavigablePolicy.java index 59b250c50..00209945b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicNavigablePolicy.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editpolicies/TopicNavigablePolicy.java @@ -1,346 +1,346 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.editpolicies; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.xmind.gef.GEF; -import org.xmind.gef.Request; -import org.xmind.gef.graphicalpolicy.IStructure; -import org.xmind.gef.part.IPart; -import org.xmind.ui.branch.INavigableBranchStructureExtension; -import org.xmind.ui.mindmap.IBranchPart; -import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.mindmap.ITopicPart; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.util.MindMapUtils; - -public class TopicNavigablePolicy extends MindMapNavigablePolicyBase { - - private boolean ignoreCache = true; - - public boolean understands(String requestType) { - return super.understands(requestType) - || MindMapUI.REQ_NAV_CHILD.equals(requestType) - || MindMapUI.REQ_NAV_SIBLING.equals(requestType); - } - - public void handle(Request request) { - String reqType = request.getType(); - if (MindMapUI.REQ_NAV_CHILD.equals(reqType)) { - navChild(request); - } else if (MindMapUI.REQ_NAV_SIBLING.equals(reqType)) { - navSibling(request); - } else { - super.handle(request); - } - } - - private void navChild(Request request) { - IPart source = request.getPrimaryTarget(); - if (source instanceof ITopicPart) { - ITopicPart topicPart = (ITopicPart) source; - IBranchPart branch = topicPart.getOwnerBranch(); - if (branch != null) { - IBranchPart child = findFirstChild(branch); - if (child != null) { - ITopicPart childTopicPart = child.getTopicPart(); - if (childTopicPart != null) - setNavigationResult(request, - Arrays.asList(childTopicPart)); - } - } - } - } - - private void navSibling(Request request) { - IPart source = request.getPrimaryTarget(); - if (source instanceof ITopicPart) { - ITopicPart topicPart = (ITopicPart) source; - IBranchPart branch = topicPart.getOwnerBranch(); - if (branch != null) { - if (branch.isCentral()) { - IBranchPart child = findFirstChild(branch); - if (child != null) { - setNavigationResult(request, - Arrays.asList(child.getTopicPart())); - } - } - IBranchPart sibling = findSucceedingSiblingOrAncestor(branch); - if (sibling != branch) { - setNavigationResult(request, - Arrays.asList(sibling.getTopicPart())); - } - } - } - } - - protected IPart findNewNavParts(Request request, String navType, - List sources) { - ITopicPart topicPart = MindMapUtils.findTopicPart(request - .getPrimaryTarget()); - if (topicPart != null) { - IBranchPart branch = topicPart.getOwnerBranch(); - if (branch != null) { - IPart navPart = findNavPart(branch, navType); - if (navPart != null && navPart.getStatus().isActive()) { - return navPart; - } - } - } - return null; - } - - private IPart findNavPart(IBranchPart branch, String navType) { - IStructure structure = branch.getBranchPolicy().getStructure(branch); - if (structure instanceof INavigableBranchStructureExtension) { - IPart navPart = ((INavigableBranchStructureExtension) structure) - .calcNavigation(branch, navType); - if (navPart == null) { - IBranchPart parent = branch.getParentBranch(); - if (parent != null) { - IStructure parentStructure = parent.getBranchPolicy() - .getStructure(parent); - if (parentStructure instanceof INavigableBranchStructureExtension) { - navPart = ((INavigableBranchStructureExtension) parentStructure) - .calcChildNavigation(parent, branch, navType, - false); - } - } else { - navPart = calcNavThroughFloatingAndCentral(branch, navType); - } - if (navPart == null) { - ignoreCache = true; - navPart = calcNavByPosition(branch, navType); - } - } - return navPart; - } - return null; - } - - protected void setNavCaches(List sources, IPart target, - String navType) { - if (!ignoreCache) { -// super.setNavCaches(sources, target, navType); - } - ignoreCache = false; - } - - private IPart calcNavThroughFloatingAndCentral(IBranchPart branch, - String navType) { - return calcNavByPosition(branch, navType); - } - - private IPart calcNavByPosition(IBranchPart branch, String navType) { - return new PositionSearcher(branch, navType).search(); - } - - protected void findSequentialNavParts(Request request, String navType, - IPart sequenceStart, List sources, List result) { - ITopicPart startTopic = MindMapUtils.findTopicPart(sequenceStart); - if (startTopic != null) { - ITopicPart sourceTopic = MindMapUtils.findTopicPart(request - .getPrimaryTarget()); - if (sourceTopic != null && isSibling(sourceTopic, startTopic)) { - IBranchPart startBranch = startTopic.getOwnerBranch(); - IBranchPart sourceBranch = sourceTopic.getOwnerBranch(); - IBranchPart sourceParentBranch = sourceBranch.getParentBranch(); - if (sourceParentBranch != null) { - IStructure parentStructure = sourceParentBranch - .getBranchPolicy().getStructure(sourceParentBranch); - if (parentStructure instanceof INavigableBranchStructureExtension) { - INavigableBranchStructureExtension ext = (INavigableBranchStructureExtension) parentStructure; - IPart endPart = ext - .calcChildNavigation(sourceParentBranch, - sourceBranch, navType, true); - IBranchPart endBranch = MindMapUtils - .findBranch(endPart); - if (endBranch == null) { - endBranch = sourceBranch; - } - List list = new ArrayList(); - ext.calcSequentialNavigation(sourceParentBranch, - startBranch, endBranch, list); - for (IBranchPart branch : list) { - result.add(branch.getTopicPart()); - } - request.setResult(GEF.RESULT_NEW_FOCUS, - endBranch.getTopicPart()); - } - } else { - addSeqPartsFromFloatingAndCentral(navType, sourceBranch, - startBranch, result); - } - } - if (!result.contains(startTopic)) - result.add(startTopic); - } else { - super.findSequentialNavParts(request, navType, sequenceStart, - sources, result); - } - } - - private void addSeqPartsFromFloatingAndCentral(String navType, - IBranchPart sourceBranch, IBranchPart startBranch, - List result) { - } - - private boolean isSibling(ITopicPart t1, ITopicPart t2) { - IBranchPart b1 = t1.getOwnerBranch(); - IBranchPart b2 = t2.getOwnerBranch(); - if (b1 != null && b2 != null) { - return b1.getParentBranch() == b2.getParentBranch(); - } - return false; - } - - protected IPart findNextOrPrev(IPart source, boolean nextOrPrev) { - if (source != null) - return findNextOrPrevTopic(source, nextOrPrev); - return super.findNextOrPrev(source, nextOrPrev); - } - - private IPart findNextOrPrevTopic(IPart current, boolean nextOrPrev) { - if (current instanceof ITopicPart) { - IBranchPart branch = ((ITopicPart) current).getOwnerBranch(); - if (branch != null) { - IBranchPart result; - if (nextOrPrev) { - result = findFirstChild(branch); - if (result == null) { - result = findSucceedingSiblingOrAncestor(branch); - } - } else { - result = findPrecedingBranch(branch); - } - if (result != null) { - return result.getTopicPart(); - } - } - } - return current; - } - - private IBranchPart findFirstChild(IBranchPart current) { - List subBranches = current.getSubBranches(); - if (!subBranches.isEmpty()) { - return subBranches.get(0); - } - subBranches = current.getSummaryBranches(); - if (!subBranches.isEmpty()) { - return subBranches.get(0); - } - return null; - } - - private IBranchPart findSucceedingSiblingOrAncestor(IBranchPart current) { - IBranchPart parent = current.getParentBranch(); - if (parent != null) { - List branches = parent.getSubBranches(); - int index = branches.indexOf(current); - if (index >= 0 && index < branches.size() - 1) { - return branches.get(index + 1); - } - int lastBranchIndex = branches.size() - 1; - branches = parent.getSummaryBranches(); - if (branches.size() > 0 && index == lastBranchIndex) { - return branches.get(0); - } - index = branches.indexOf(current); - if (index >= 0 && index < branches.size() - 1) { - return branches.get(index + 1); - } - - return findSucceedingSiblingOrAncestor(parent); - } else if (current.getParent() instanceof ISheetPart) { - ISheetPart sheet = (ISheetPart) current.getParent(); - List floatingBranches = sheet.getFloatingBranches(); - if (current == sheet.getCentralBranch()) { - if (!floatingBranches.isEmpty()) { - return floatingBranches.get(0); - } - } else { - int index = floatingBranches.indexOf(current); - if (index >= 0) { - if (index < floatingBranches.size() - 1) { - IBranchPart floatBranch = floatingBranches - .get(index + 1); - return floatBranch; - } - return sheet.getCentralBranch(); - } - } - } - return current; - } - - private IBranchPart findPrecedingBranch(IBranchPart current) { - IBranchPart parent = current.getParentBranch(); - if (parent != null) { - List branches = parent.getSubBranches(); - int index = branches.indexOf(current); - if (index > 0) { - return findLastDescendant(branches.get(index - 1)); - } - - int lastBranchIndex = branches.size() - 1; - branches = parent.getSummaryBranches(); - index = branches.indexOf(current); - if (index == 0) { - return parent.getSubBranches().get(lastBranchIndex); - } - if (index > 0) { - return findLastDescendant(branches.get(index - 1)); - } - return parent; - - } else if (current.getParent() instanceof ISheetPart) { - ISheetPart sheet = ((ISheetPart) current.getParent()); - List floatingBranches = sheet.getFloatingBranches(); - if (current == sheet.getCentralBranch()) { - if (!floatingBranches.isEmpty()) { - IBranchPart lastFloating = floatingBranches - .get(floatingBranches.size() - 1); - return findLastDescendant(lastFloating); - } else { - return findLastDescendant(current); - } - } else if (floatingBranches.contains(current)) { - int index = floatingBranches.indexOf(current); - if (index == 0) { - return findLastDescendant(sheet.getCentralBranch()); - } - return findLastDescendant(floatingBranches.get(index - 1)); - } - } - return current; - } - - private IBranchPart findLastDescendant(IBranchPart branch) { - List summaryBranches = branch.getSummaryBranches(); - if (!summaryBranches.isEmpty()) { - return findLastDescendant(summaryBranches.get(summaryBranches - .size() - 1)); - } - List subBranches = branch.getSubBranches(); - if (!subBranches.isEmpty()) { - return findLastDescendant(subBranches.get(subBranches.size() - 1)); - } - return branch; - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.editpolicies; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.xmind.gef.GEF; +import org.xmind.gef.Request; +import org.xmind.gef.graphicalpolicy.IStructure; +import org.xmind.gef.part.IPart; +import org.xmind.ui.branch.INavigableBranchStructureExtension; +import org.xmind.ui.mindmap.IBranchPart; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; + +public class TopicNavigablePolicy extends MindMapNavigablePolicyBase { + + private boolean ignoreCache = true; + + public boolean understands(String requestType) { + return super.understands(requestType) + || MindMapUI.REQ_NAV_CHILD.equals(requestType) + || MindMapUI.REQ_NAV_SIBLING.equals(requestType); + } + + public void handle(Request request) { + String reqType = request.getType(); + if (MindMapUI.REQ_NAV_CHILD.equals(reqType)) { + navChild(request); + } else if (MindMapUI.REQ_NAV_SIBLING.equals(reqType)) { + navSibling(request); + } else { + super.handle(request); + } + } + + private void navChild(Request request) { + IPart source = request.getPrimaryTarget(); + if (source instanceof ITopicPart) { + ITopicPart topicPart = (ITopicPart) source; + IBranchPart branch = topicPart.getOwnerBranch(); + if (branch != null) { + IBranchPart child = findFirstChild(branch); + if (child != null) { + ITopicPart childTopicPart = child.getTopicPart(); + if (childTopicPart != null) + setNavigationResult(request, + Arrays.asList(childTopicPart)); + } + } + } + } + + private void navSibling(Request request) { + IPart source = request.getPrimaryTarget(); + if (source instanceof ITopicPart) { + ITopicPart topicPart = (ITopicPart) source; + IBranchPart branch = topicPart.getOwnerBranch(); + if (branch != null) { + if (branch.isCentral()) { + IBranchPart child = findFirstChild(branch); + if (child != null) { + setNavigationResult(request, + Arrays.asList(child.getTopicPart())); + } + } + IBranchPart sibling = findSucceedingSiblingOrAncestor(branch); + if (sibling != branch) { + setNavigationResult(request, + Arrays.asList(sibling.getTopicPart())); + } + } + } + } + + protected IPart findNewNavParts(Request request, String navType, + List sources) { + ITopicPart topicPart = MindMapUtils.findTopicPart(request + .getPrimaryTarget()); + if (topicPart != null) { + IBranchPart branch = topicPart.getOwnerBranch(); + if (branch != null) { + IPart navPart = findNavPart(branch, navType); + if (navPart != null && navPart.getStatus().isActive()) { + return navPart; + } + } + } + return null; + } + + private IPart findNavPart(IBranchPart branch, String navType) { + IStructure structure = branch.getBranchPolicy().getStructure(branch); + if (structure instanceof INavigableBranchStructureExtension) { + IPart navPart = ((INavigableBranchStructureExtension) structure) + .calcNavigation(branch, navType); + if (navPart == null) { + IBranchPart parent = branch.getParentBranch(); + if (parent != null) { + IStructure parentStructure = parent.getBranchPolicy() + .getStructure(parent); + if (parentStructure instanceof INavigableBranchStructureExtension) { + navPart = ((INavigableBranchStructureExtension) parentStructure) + .calcChildNavigation(parent, branch, navType, + false); + } + } else { + navPart = calcNavThroughFloatingAndCentral(branch, navType); + } + if (navPart == null) { + ignoreCache = true; + navPart = calcNavByPosition(branch, navType); + } + } + return navPart; + } + return null; + } + + protected void setNavCaches(List sources, IPart target, + String navType) { + if (!ignoreCache) { +// super.setNavCaches(sources, target, navType); + } + ignoreCache = false; + } + + private IPart calcNavThroughFloatingAndCentral(IBranchPart branch, + String navType) { + return calcNavByPosition(branch, navType); + } + + private IPart calcNavByPosition(IBranchPart branch, String navType) { + return new PositionSearcher(branch, navType).search(); + } + + protected void findSequentialNavParts(Request request, String navType, + IPart sequenceStart, List sources, List result) { + ITopicPart startTopic = MindMapUtils.findTopicPart(sequenceStart); + if (startTopic != null) { + ITopicPart sourceTopic = MindMapUtils.findTopicPart(request + .getPrimaryTarget()); + if (sourceTopic != null && isSibling(sourceTopic, startTopic)) { + IBranchPart startBranch = startTopic.getOwnerBranch(); + IBranchPart sourceBranch = sourceTopic.getOwnerBranch(); + IBranchPart sourceParentBranch = sourceBranch.getParentBranch(); + if (sourceParentBranch != null) { + IStructure parentStructure = sourceParentBranch + .getBranchPolicy().getStructure(sourceParentBranch); + if (parentStructure instanceof INavigableBranchStructureExtension) { + INavigableBranchStructureExtension ext = (INavigableBranchStructureExtension) parentStructure; + IPart endPart = ext + .calcChildNavigation(sourceParentBranch, + sourceBranch, navType, true); + IBranchPart endBranch = MindMapUtils + .findBranch(endPart); + if (endBranch == null) { + endBranch = sourceBranch; + } + List list = new ArrayList(); + ext.calcSequentialNavigation(sourceParentBranch, + startBranch, endBranch, list); + for (IBranchPart branch : list) { + result.add(branch.getTopicPart()); + } + request.setResult(GEF.RESULT_NEW_FOCUS, + endBranch.getTopicPart()); + } + } else { + addSeqPartsFromFloatingAndCentral(navType, sourceBranch, + startBranch, result); + } + } + if (!result.contains(startTopic)) + result.add(startTopic); + } else { + super.findSequentialNavParts(request, navType, sequenceStart, + sources, result); + } + } + + private void addSeqPartsFromFloatingAndCentral(String navType, + IBranchPart sourceBranch, IBranchPart startBranch, + List result) { + } + + private boolean isSibling(ITopicPart t1, ITopicPart t2) { + IBranchPart b1 = t1.getOwnerBranch(); + IBranchPart b2 = t2.getOwnerBranch(); + if (b1 != null && b2 != null) { + return b1.getParentBranch() == b2.getParentBranch(); + } + return false; + } + + protected IPart findNextOrPrev(IPart source, boolean nextOrPrev) { + if (source != null) + return findNextOrPrevTopic(source, nextOrPrev); + return super.findNextOrPrev(source, nextOrPrev); + } + + private IPart findNextOrPrevTopic(IPart current, boolean nextOrPrev) { + if (current instanceof ITopicPart) { + IBranchPart branch = ((ITopicPart) current).getOwnerBranch(); + if (branch != null) { + IBranchPart result; + if (nextOrPrev) { + result = findFirstChild(branch); + if (result == null) { + result = findSucceedingSiblingOrAncestor(branch); + } + } else { + result = findPrecedingBranch(branch); + } + if (result != null) { + return result.getTopicPart(); + } + } + } + return current; + } + + private IBranchPart findFirstChild(IBranchPart current) { + List subBranches = current.getSubBranches(); + if (!subBranches.isEmpty()) { + return subBranches.get(0); + } + subBranches = current.getSummaryBranches(); + if (!subBranches.isEmpty()) { + return subBranches.get(0); + } + return null; + } + + private IBranchPart findSucceedingSiblingOrAncestor(IBranchPart current) { + IBranchPart parent = current.getParentBranch(); + if (parent != null) { + List branches = parent.getSubBranches(); + int index = branches.indexOf(current); + if (index >= 0 && index < branches.size() - 1) { + return branches.get(index + 1); + } + int lastBranchIndex = branches.size() - 1; + branches = parent.getSummaryBranches(); + if (branches.size() > 0 && index == lastBranchIndex) { + return branches.get(0); + } + index = branches.indexOf(current); + if (index >= 0 && index < branches.size() - 1) { + return branches.get(index + 1); + } + + return findSucceedingSiblingOrAncestor(parent); + } else if (current.getParent() instanceof ISheetPart) { + ISheetPart sheet = (ISheetPart) current.getParent(); + List floatingBranches = sheet.getFloatingBranches(); + if (current == sheet.getCentralBranch()) { + if (!floatingBranches.isEmpty()) { + return floatingBranches.get(0); + } + } else { + int index = floatingBranches.indexOf(current); + if (index >= 0) { + if (index < floatingBranches.size() - 1) { + IBranchPart floatBranch = floatingBranches + .get(index + 1); + return floatBranch; + } + return sheet.getCentralBranch(); + } + } + } + return current; + } + + private IBranchPart findPrecedingBranch(IBranchPart current) { + IBranchPart parent = current.getParentBranch(); + if (parent != null) { + List branches = parent.getSubBranches(); + int index = branches.indexOf(current); + if (index > 0) { + return findLastDescendant(branches.get(index - 1)); + } + + int lastBranchIndex = branches.size() - 1; + branches = parent.getSummaryBranches(); + index = branches.indexOf(current); + if (index == 0) { + return parent.getSubBranches().get(lastBranchIndex); + } + if (index > 0) { + return findLastDescendant(branches.get(index - 1)); + } + return parent; + + } else if (current.getParent() instanceof ISheetPart) { + ISheetPart sheet = ((ISheetPart) current.getParent()); + List floatingBranches = sheet.getFloatingBranches(); + if (current == sheet.getCentralBranch()) { + if (!floatingBranches.isEmpty()) { + IBranchPart lastFloating = floatingBranches + .get(floatingBranches.size() - 1); + return findLastDescendant(lastFloating); + } else { + return findLastDescendant(current); + } + } else if (floatingBranches.contains(current)) { + int index = floatingBranches.indexOf(current); + if (index == 0) { + return findLastDescendant(sheet.getCentralBranch()); + } + return findLastDescendant(floatingBranches.get(index - 1)); + } + } + return current; + } + + private IBranchPart findLastDescendant(IBranchPart branch) { + List summaryBranches = branch.getSummaryBranches(); + if (!summaryBranches.isEmpty()) { + return findLastDescendant(summaryBranches.get(summaryBranches + .size() - 1)); + } + List subBranches = branch.getSubBranches(); + if (!subBranches.isEmpty()) { + return findLastDescendant(subBranches.get(subBranches.size() - 1)); + } + return branch; + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryFigure.java index 8353d98cb..938e41f9c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryFigure.java @@ -1,127 +1,127 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.swt.SWT; -import org.xmind.gef.draw2d.DecoratedShapeFigure; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.draw2d.IShadowedFigure; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.ui.decorations.IBoundaryDecoration; - -public class BoundaryFigure extends DecoratedShapeFigure - implements ITitledFigure, IMinimizable, IShadowedFigure { - - protected static final int FLAG_MINIMIZED = MAX_FLAG << 1; - - static { - MAX_FLAG = FLAG_MINIMIZED; - } - - private ITextFigure title = null; - - private boolean isTitleVisible = false; - - public ITextFigure getTitle() { - return title; - } - - public boolean isShadowShowing() { - return isShowing(); - } - - public void setTitle(ITextFigure title) { - if (title == this.title) - return; - - this.title = title; - revalidate(); - repaint(); - } - - public boolean isTitleVisible() { - return isTitleVisible; - } - - public void setTitleVisible(boolean isTitleVisible) { - if (isTitleVisible == this.isTitleVisible) - return; - - this.isTitleVisible = isTitleVisible; - revalidate(); - repaint(); - } - - public IBoundaryDecoration getDecoration() { - return (IBoundaryDecoration) super.getDecoration(); - } - - protected Insets calculatePreferredInsets() { - if (isMinimized()) - return NO_INSETS; - Insets ins = super.calculatePreferredInsets(); -// if (isTitleVisible() && title != null) { -// Dimension s = title.getPreferredSize(); -// ins = new Insets(ins); -// ins.top = Math.max(s.height, ins.top); -// ins.left += 5; -// } - return ins; - } - - protected void layout() { - super.layout(); - if (title != null && title.getParent() == this) { - Dimension size = title.getPreferredSize(getBounds().width, - SWT.DEFAULT); - if (size.width > getBounds().width) { - size = new Dimension(getBounds().width, size.height); - } - title.setSize(size); - title.setLocation(getBounds().getLocation()); - } - } - - public boolean isMinimized() { - return getFlag(FLAG_MINIMIZED); - } - - public void setMinimized(boolean minimized) { - if (minimized == isMinimized()) - return; - - setFlag(FLAG_MINIMIZED, minimized); - revalidate(); - repaint(); - } - - public void paintShadow(Graphics graphics) { - if (getDecoration() != null - && getDecoration() instanceof IShadowedDecoration) { - ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); - } - } - - public String toString() { - if (title != null) - return "BoundaryFigure(" + title.getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - return super.toString(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.swt.SWT; +import org.xmind.gef.draw2d.DecoratedShapeFigure; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.draw2d.IShadowedFigure; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.ui.decorations.IBoundaryDecoration; + +public class BoundaryFigure extends DecoratedShapeFigure + implements ITitledFigure, IMinimizable, IShadowedFigure { + + protected static final int FLAG_MINIMIZED = MAX_FLAG << 1; + + static { + MAX_FLAG = FLAG_MINIMIZED; + } + + private ITextFigure title = null; + + private boolean isTitleVisible = false; + + public ITextFigure getTitle() { + return title; + } + + public boolean isShadowShowing() { + return isShowing(); + } + + public void setTitle(ITextFigure title) { + if (title == this.title) + return; + + this.title = title; + revalidate(); + repaint(); + } + + public boolean isTitleVisible() { + return isTitleVisible; + } + + public void setTitleVisible(boolean isTitleVisible) { + if (isTitleVisible == this.isTitleVisible) + return; + + this.isTitleVisible = isTitleVisible; + revalidate(); + repaint(); + } + + public IBoundaryDecoration getDecoration() { + return (IBoundaryDecoration) super.getDecoration(); + } + + protected Insets calculatePreferredInsets() { + if (isMinimized()) + return NO_INSETS; + Insets ins = super.calculatePreferredInsets(); +// if (isTitleVisible() && title != null) { +// Dimension s = title.getPreferredSize(); +// ins = new Insets(ins); +// ins.top = Math.max(s.height, ins.top); +// ins.left += 5; +// } + return ins; + } + + protected void layout() { + super.layout(); + if (title != null && title.getParent() == this) { + Dimension size = title.getPreferredSize(getBounds().width, + SWT.DEFAULT); + if (size.width > getBounds().width) { + size = new Dimension(getBounds().width, size.height); + } + title.setSize(size); + title.setLocation(getBounds().getLocation()); + } + } + + public boolean isMinimized() { + return getFlag(FLAG_MINIMIZED); + } + + public void setMinimized(boolean minimized) { + if (minimized == isMinimized()) + return; + + setFlag(FLAG_MINIMIZED, minimized); + revalidate(); + repaint(); + } + + public void paintShadow(Graphics graphics) { + if (getDecoration() != null + && getDecoration() instanceof IShadowedDecoration) { + ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); + } + } + + public String toString() { + if (title != null) + return "BoundaryFigure(" + title.getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + return super.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryTitleFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryTitleFigure.java index 0dae616c4..a49bc9983 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryTitleFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BoundaryTitleFigure.java @@ -1,169 +1,169 @@ -package org.xmind.ui.internal.figures; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.swt.graphics.Font; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; - -public class BoundaryTitleFigure extends RotatableWrapLabel { - - private static final float PADDING = 1.5f; - - private static final float H_MARGIN = 8.0f; - - private static final float V_MARGIN = 3.0f; - - private static final String NULLSTR = ""; //$NON-NLS-1$ - private static final String ONESPACE = " "; //$NON-NLS-1$ - - private BoundaryFigure boundary; - - private PrecisionRectangle textArea; - - public BoundaryTitleFigure() { - } - - public BoundaryTitleFigure(String text) { - super(text); - } - - public BoundaryTitleFigure(int renderStyle) { - super(renderStyle); - } - - public BoundaryTitleFigure(String text, int renderStyle) { - super(text, renderStyle); - } - - protected void flushCaches() { - super.flushCaches(); - textArea = null; - } - - private int getPreferenceWHint(int wHint) { - if (getBoundary() != null) { - return wHint > getBoundary().getBounds().width - ? getBoundary().getBounds().width : wHint; - } - return wHint; - } - - protected PrecisionRectangle getTextArea(int wHint) { - wHint = getPreferenceWHint(wHint); - receiveWidthCaches(wHint); - if (textArea == null) { - PrecisionDimension size = calculateTextSize(wHint); - textArea = new PrecisionRectangle(); - float h_margin = H_MARGIN; - float v_margin = V_MARGIN; - int height = getFont().getFontData()[0].getHeight(); - if (height > 30) - h_margin = h_margin + 5; - textArea.width = size.width + PADDING * 2 + h_margin; - textArea.height = size.height + PADDING * 2 + v_margin; - textArea.x = -(textArea.width / 2); - textArea.y = -(textArea.height / 2); - } - return textArea; - } - - @Override - protected String calculateAppliedText(double wHint) { - String theText = getText(); - if (wHint <= 5 || theText.length() == 0) - return theText; - Font f = getFont(); - String[] lines = forceSplitText(theText, f, wHint); - return getForceSplitText(lines); - } - - private String[] forceSplitText(String theText, Font f, double wHint) { - wHint = wHint - 5; - List buffer = new ArrayList(); - theText = theText.trim(); - if (getShowLooseTextSize(theText, f).width < wHint) { - buffer.add(theText); - return buffer.toArray(new String[buffer.size()]); - } - String cachedString = NULLSTR; - String appendString = NULLSTR; - String[] lines = theText.split(ONESPACE); - int i = 0; - do { - if (lines[i].equals(NULLSTR)) { - lines[i] = ONESPACE; - } - if (getShowLooseTextSize(lines[i], f).width >= wHint) { - if (cachedString.trim() != NULLSTR) { - buffer.add(cachedString.trim()); - cachedString = NULLSTR; - } - cachedString = truncate(lines[i], buffer, wHint, f); - i++; - continue; - } - appendString = cachedString + lines[i]; - if (getShowLooseTextSize(appendString, f).width >= wHint) { - if (cachedString.trim() != NULLSTR) { - buffer.add(cachedString.trim()); - } - cachedString = lines[i]; - } else { - cachedString = cachedString + lines[i]; - } - cachedString += ONESPACE; - i++; - } while (i < lines.length); - if (cachedString.trim() != NULLSTR) { - buffer.add(cachedString.trim()); - } - return buffer.toArray(new String[buffer.size()]); - } - - private String truncate(String s, List buffer, double wHint, - Font f) { - String token = s; - while (wHint > 0 && !token.equals(NULLSTR)) { - boolean isLastSnip = true; - String current = token; - while (getShowLooseTextSize(current, f).width >= wHint) { - isLastSnip = false; - current = current.substring(0, current.length() - 1); - } - if (getShowLooseTextSize(current, f).width < wHint && !isLastSnip) { - buffer.add(token.substring(0, current.length()).trim()); - token = token.substring(current.length()); - } else - return token; - } - return token; - } - - private String getForceSplitText(String[] lines) { - StringBuffer sb = new StringBuffer(); - for (String line : lines) - sb.append(line + '\n'); - if (sb.charAt(sb.length() - 1) == '\n') - sb.deleteCharAt(sb.length() - 1); - return sb.toString(); - } - - private Dimension getShowLooseTextSize(String s, Font f) { - int textCase = getTextCase(); - s = getShowText(s, textCase); - return getLooseTextSize(s, f); - } - - private BoundaryFigure getBoundary() { - return boundary; - } - - public void setBoundary(IFigure boundary) { - this.boundary = (BoundaryFigure) boundary; - } -} +package org.xmind.ui.internal.figures; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.swt.graphics.Font; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; + +public class BoundaryTitleFigure extends RotatableWrapLabel { + + private static final float PADDING = 1.5f; + + private static final float H_MARGIN = 8.0f; + + private static final float V_MARGIN = 3.0f; + + private static final String NULLSTR = ""; //$NON-NLS-1$ + private static final String ONESPACE = " "; //$NON-NLS-1$ + + private BoundaryFigure boundary; + + private PrecisionRectangle textArea; + + public BoundaryTitleFigure() { + } + + public BoundaryTitleFigure(String text) { + super(text); + } + + public BoundaryTitleFigure(int renderStyle) { + super(renderStyle); + } + + public BoundaryTitleFigure(String text, int renderStyle) { + super(text, renderStyle); + } + + protected void flushCaches() { + super.flushCaches(); + textArea = null; + } + + private int getPreferenceWHint(int wHint) { + if (getBoundary() != null) { + return wHint > getBoundary().getBounds().width + ? getBoundary().getBounds().width : wHint; + } + return wHint; + } + + protected PrecisionRectangle getTextArea(int wHint) { + wHint = getPreferenceWHint(wHint); + receiveWidthCaches(wHint); + if (textArea == null) { + PrecisionDimension size = calculateTextSize(wHint); + textArea = new PrecisionRectangle(); + float h_margin = H_MARGIN; + float v_margin = V_MARGIN; + int height = getFont().getFontData()[0].getHeight(); + if (height > 30) + h_margin = h_margin + 5; + textArea.width = size.width + PADDING * 2 + h_margin; + textArea.height = size.height + PADDING * 2 + v_margin; + textArea.x = -(textArea.width / 2); + textArea.y = -(textArea.height / 2); + } + return textArea; + } + + @Override + protected String calculateAppliedText(double wHint) { + String theText = getText(); + if (wHint <= 5 || theText.length() == 0) + return theText; + Font f = getFont(); + String[] lines = forceSplitText(theText, f, wHint); + return getForceSplitText(lines); + } + + private String[] forceSplitText(String theText, Font f, double wHint) { + wHint = wHint - 5; + List buffer = new ArrayList(); + theText = theText.trim(); + if (getShowLooseTextSize(theText, f).width < wHint) { + buffer.add(theText); + return buffer.toArray(new String[buffer.size()]); + } + String cachedString = NULLSTR; + String appendString = NULLSTR; + String[] lines = theText.split(ONESPACE); + int i = 0; + do { + if (lines[i].equals(NULLSTR)) { + lines[i] = ONESPACE; + } + if (getShowLooseTextSize(lines[i], f).width >= wHint) { + if (cachedString.trim() != NULLSTR) { + buffer.add(cachedString.trim()); + cachedString = NULLSTR; + } + cachedString = truncate(lines[i], buffer, wHint, f); + i++; + continue; + } + appendString = cachedString + lines[i]; + if (getShowLooseTextSize(appendString, f).width >= wHint) { + if (cachedString.trim() != NULLSTR) { + buffer.add(cachedString.trim()); + } + cachedString = lines[i]; + } else { + cachedString = cachedString + lines[i]; + } + cachedString += ONESPACE; + i++; + } while (i < lines.length); + if (cachedString.trim() != NULLSTR) { + buffer.add(cachedString.trim()); + } + return buffer.toArray(new String[buffer.size()]); + } + + private String truncate(String s, List buffer, double wHint, + Font f) { + String token = s; + while (wHint > 0 && !token.equals(NULLSTR)) { + boolean isLastSnip = true; + String current = token; + while (getShowLooseTextSize(current, f).width >= wHint) { + isLastSnip = false; + current = current.substring(0, current.length() - 1); + } + if (getShowLooseTextSize(current, f).width < wHint && !isLastSnip) { + buffer.add(token.substring(0, current.length()).trim()); + token = token.substring(current.length()); + } else + return token; + } + return token; + } + + private String getForceSplitText(String[] lines) { + StringBuffer sb = new StringBuffer(); + for (String line : lines) + sb.append(line + '\n'); + if (sb.charAt(sb.length() - 1) == '\n') + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + + private Dimension getShowLooseTextSize(String s, Font f) { + int textCase = getTextCase(); + s = getShowText(s, textCase); + return getLooseTextSize(s, f); + } + + private BoundaryFigure getBoundary() { + return boundary; + } + + public void setBoundary(IFigure boundary) { + this.boundary = (BoundaryFigure) boundary; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BranchFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BranchFigure.java index b4158f099..141724fa0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BranchFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/BranchFigure.java @@ -1,319 +1,319 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IClippingStrategy; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.xmind.gef.draw2d.IDecoratedFigure; -import org.xmind.gef.draw2d.IDecoratedFigureListener; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.draw2d.IShadowedFigure; -import org.xmind.gef.draw2d.ITransparentableFigure; -import org.xmind.gef.draw2d.ReferencedFigure; -import org.xmind.gef.draw2d.decoration.IDecoration; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.graphics.AlphaGraphics; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.draw2d.graphics.GrayedGraphics; -import org.xmind.ui.decorations.IBranchDecoration; -import org.xmind.ui.internal.decorations.CalloutBranchConnections; - -public class BranchFigure extends ReferencedFigure implements IDecoratedFigure, - IMinimizable, IShadowedFigure, ITransparentableFigure { - - private static final int FLAG_FOLDED = MAX_FLAG << 1; - - private static final int FLAG_MINIMIZED = MAX_FLAG << 2; - - static { - MAX_FLAG = FLAG_MINIMIZED; - } - - private IDecoration connections = null; - - private IDecoration decoration = null; - - private int mainAlpha = 0xff; - - private int alpha = 0xff; - - private IDecoration calloutConnections = null; - - public boolean isFolded() { - return getFlag(FLAG_FOLDED); - } - - public void setFolded(boolean folded) { - if (folded == isFolded()) - return; - setFlag(FLAG_FOLDED, folded); - revalidate(); - repaint(); - } - - public boolean getMinimized() { - return getFlag(FLAG_MINIMIZED); - } - - public boolean isMinimized() { - if (getMinimized()) - return true; - if (getParent() instanceof BranchFigure) { - if (((BranchFigure) getParent()).isFolded()) - return true; - } - if (getParent() != null && getParent() instanceof IMinimizable) - return ((IMinimizable) getParent()).isMinimized(); - return false; - } - - public void setMinimized(boolean minimized) { - if (minimized == isMinimized()) - return; - setFlag(FLAG_MINIMIZED, minimized); - revalidate(); - repaint(); - } - - public IDecoration getConnections() { - return connections; - } - - public void setConnections(IDecoration connections) { - if (connections == this.connections) - return; - this.connections = connections; - revalidate(); - repaint(); - } - - public IDecoration getCalloutConnections() { - return calloutConnections; - } - - public void setCalloutConnections(IDecoration calloutConnections) { - if (calloutConnections == this.calloutConnections) - return; - this.calloutConnections = calloutConnections; - revalidate(); - repaint(); - } - - public IDecoration getDecoration() { - return decoration; - } - - public void setDecoration(IDecoration decoration) { - IDecoration oldDecoration = this.decoration; - if (decoration == oldDecoration) - return; - this.decoration = decoration; - fireDecorationChanged(oldDecoration, decoration); - repaint(); - } - - public void addDecoratedFigureListener(IDecoratedFigureListener listener) { - addListener(IDecoratedFigureListener.class, listener); - } - - public void removeDecoratedFigureListener( - IDecoratedFigureListener listener) { - removeListener(IDecoratedFigureListener.class, listener); - } - - protected void fireDecorationChanged(IDecoration oldDecoration, - IDecoration newDecoration) { - Iterator listeners = getListeners(IDecoratedFigureListener.class); - while (listeners.hasNext()) { - ((IDecoratedFigureListener) listeners.next()) - .decorationChanged(this, oldDecoration, newDecoration); - } - } - - public boolean isShadowShowing() { - return isShowing() && getMainAlpha() > 0; - } - - public int getMainAlpha() { - return mainAlpha; - } - - public int getSubAlpha() { - return alpha; - } - - public void setMainAlpha(int alpha) { - if (alpha == this.mainAlpha) - return; - this.mainAlpha = alpha; - repaint(); - } - - public void setSubAlpha(int alpha) { - if (alpha == this.alpha) - return; - this.alpha = alpha; - repaint(); - } - - public void invalidate() { - if (connections != null) - connections.invalidate(); - if (calloutConnections != null) - calloutConnections.invalidate(); - if (decoration != null) - decoration.invalidate(); - super.invalidate(); - } - - public void setEnabled(boolean value) { - super.setEnabled(value); - repaint(); - } - - public void paint(Graphics graphics) { - GraphicsUtils.fixGradientBugForCarbon(graphics, this); - if (getMainAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getMainAlpha()); - ag.setAlpha(graphics.getAlpha()); - try { - doPaint(ag); - } finally { - ag.dispose(); - } - } else { - doPaint(graphics); - } - } - - private void doPaint(Graphics graphics) { - if (isEnabled()) { - super.paint(graphics); - } else { - GrayedGraphics gg = new GrayedGraphics(graphics); - try { - super.paint(gg); - } finally { - gg.dispose(); - } - } - } - - protected void paintFigure(Graphics graphics) { - if (getSubAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getSubAlpha()); - try { - doPaintFigure(ag); - } finally { - ag.dispose(); - } - } else { - doPaintFigure(graphics); - } - } - - protected void paintChildren(Graphics graphics) { - List children = getChildren(); - for (int i = 0; i < children.size(); i++) { - IFigure child = (IFigure) children.get(i); - if (child.isVisible()) { - if (child instanceof TopicFigure) { - graphics.setAntialias(SWT.ON); - - if (connections != null) { - connections.paint(this, graphics); - } - - decoration.paint(this, graphics); - - IFigure parentFigure = getParent(); - if (parentFigure instanceof BranchFigure) { - CalloutBranchConnections parentCC = (CalloutBranchConnections) ((BranchFigure) parentFigure) - .getCalloutConnections(); - IDecoration calloutConnection = parentCC - .getDecoration(this); - if (calloutConnection != null) - calloutConnection.paint(parentFigure, graphics); - - } - if (this.calloutConnections != null) { - this.calloutConnections.paint(this, graphics); - } - } - // determine clipping areas for child - IClippingStrategy clippingStrategy = getClippingStrategy(); - Rectangle[] clipping = null; - if (clippingStrategy != null) { - clipping = clippingStrategy.getClip(child); - } else { - // default clipping behaviour is to clip at bounds - clipping = new Rectangle[] { child.getBounds() }; - } - // child may now paint inside the clipping areas - for (int j = 0; j < clipping.length; j++) { - if (clipping[j].intersects( - graphics.getClip(Rectangle.SINGLETON))) { - graphics.clipRect(clipping[j]); - child.paint(graphics); - graphics.restoreState(); - } - } - } - } - } - - private void doPaintFigure(Graphics graphics) { - graphics.setAntialias(SWT.ON); - super.paintFigure(graphics); - } - - protected void paintBorder(Graphics graphics) { - super.paintBorder(graphics); - if (decoration != null && decoration instanceof IBranchDecoration) { - ((IBranchDecoration) decoration).paintAboveChildren(this, graphics); - } - } - - public void paintShadow(Graphics graphics) { - if (connections != null && connections instanceof IShadowedDecoration) { - ((IShadowedDecoration) connections).paintShadow(this, graphics); - } - if (calloutConnections != null - && calloutConnections instanceof IShadowedDecoration) { - ((IShadowedDecoration) calloutConnections).paintShadow(this, - graphics); - } - if (decoration != null && decoration instanceof IShadowedDecoration) { - ((IShadowedDecoration) decoration).paintShadow(this, graphics); - } - } - - public String toString() { - for (Object c : getChildren()) { - if (c instanceof TopicFigure) { - return "BranchFigure(" + c.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return super.toString(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IClippingStrategy; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.xmind.gef.draw2d.IDecoratedFigure; +import org.xmind.gef.draw2d.IDecoratedFigureListener; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.draw2d.IShadowedFigure; +import org.xmind.gef.draw2d.ITransparentableFigure; +import org.xmind.gef.draw2d.ReferencedFigure; +import org.xmind.gef.draw2d.decoration.IDecoration; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.graphics.AlphaGraphics; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; +import org.xmind.gef.draw2d.graphics.GrayedGraphics; +import org.xmind.ui.decorations.IBranchDecoration; +import org.xmind.ui.internal.decorations.CalloutBranchConnections; + +public class BranchFigure extends ReferencedFigure implements IDecoratedFigure, + IMinimizable, IShadowedFigure, ITransparentableFigure { + + private static final int FLAG_FOLDED = MAX_FLAG << 1; + + private static final int FLAG_MINIMIZED = MAX_FLAG << 2; + + static { + MAX_FLAG = FLAG_MINIMIZED; + } + + private IDecoration connections = null; + + private IDecoration decoration = null; + + private int mainAlpha = 0xff; + + private int alpha = 0xff; + + private IDecoration calloutConnections = null; + + public boolean isFolded() { + return getFlag(FLAG_FOLDED); + } + + public void setFolded(boolean folded) { + if (folded == isFolded()) + return; + setFlag(FLAG_FOLDED, folded); + revalidate(); + repaint(); + } + + public boolean getMinimized() { + return getFlag(FLAG_MINIMIZED); + } + + public boolean isMinimized() { + if (getMinimized()) + return true; + if (getParent() instanceof BranchFigure) { + if (((BranchFigure) getParent()).isFolded()) + return true; + } + if (getParent() != null && getParent() instanceof IMinimizable) + return ((IMinimizable) getParent()).isMinimized(); + return false; + } + + public void setMinimized(boolean minimized) { + if (minimized == isMinimized()) + return; + setFlag(FLAG_MINIMIZED, minimized); + revalidate(); + repaint(); + } + + public IDecoration getConnections() { + return connections; + } + + public void setConnections(IDecoration connections) { + if (connections == this.connections) + return; + this.connections = connections; + revalidate(); + repaint(); + } + + public IDecoration getCalloutConnections() { + return calloutConnections; + } + + public void setCalloutConnections(IDecoration calloutConnections) { + if (calloutConnections == this.calloutConnections) + return; + this.calloutConnections = calloutConnections; + revalidate(); + repaint(); + } + + public IDecoration getDecoration() { + return decoration; + } + + public void setDecoration(IDecoration decoration) { + IDecoration oldDecoration = this.decoration; + if (decoration == oldDecoration) + return; + this.decoration = decoration; + fireDecorationChanged(oldDecoration, decoration); + repaint(); + } + + public void addDecoratedFigureListener(IDecoratedFigureListener listener) { + addListener(IDecoratedFigureListener.class, listener); + } + + public void removeDecoratedFigureListener( + IDecoratedFigureListener listener) { + removeListener(IDecoratedFigureListener.class, listener); + } + + protected void fireDecorationChanged(IDecoration oldDecoration, + IDecoration newDecoration) { + Iterator listeners = getListeners(IDecoratedFigureListener.class); + while (listeners.hasNext()) { + ((IDecoratedFigureListener) listeners.next()) + .decorationChanged(this, oldDecoration, newDecoration); + } + } + + public boolean isShadowShowing() { + return isShowing() && getMainAlpha() > 0; + } + + public int getMainAlpha() { + return mainAlpha; + } + + public int getSubAlpha() { + return alpha; + } + + public void setMainAlpha(int alpha) { + if (alpha == this.mainAlpha) + return; + this.mainAlpha = alpha; + repaint(); + } + + public void setSubAlpha(int alpha) { + if (alpha == this.alpha) + return; + this.alpha = alpha; + repaint(); + } + + public void invalidate() { + if (connections != null) + connections.invalidate(); + if (calloutConnections != null) + calloutConnections.invalidate(); + if (decoration != null) + decoration.invalidate(); + super.invalidate(); + } + + public void setEnabled(boolean value) { + super.setEnabled(value); + repaint(); + } + + public void paint(Graphics graphics) { + GraphicsUtils.fixGradientBugForCarbon(graphics, this); + if (getMainAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getMainAlpha()); + ag.setAlpha(graphics.getAlpha()); + try { + doPaint(ag); + } finally { + ag.dispose(); + } + } else { + doPaint(graphics); + } + } + + private void doPaint(Graphics graphics) { + if (isEnabled()) { + super.paint(graphics); + } else { + GrayedGraphics gg = new GrayedGraphics(graphics); + try { + super.paint(gg); + } finally { + gg.dispose(); + } + } + } + + protected void paintFigure(Graphics graphics) { + if (getSubAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getSubAlpha()); + try { + doPaintFigure(ag); + } finally { + ag.dispose(); + } + } else { + doPaintFigure(graphics); + } + } + + protected void paintChildren(Graphics graphics) { + List children = getChildren(); + for (int i = 0; i < children.size(); i++) { + IFigure child = (IFigure) children.get(i); + if (child.isVisible()) { + if (child instanceof TopicFigure) { + graphics.setAntialias(SWT.ON); + + if (connections != null) { + connections.paint(this, graphics); + } + + decoration.paint(this, graphics); + + IFigure parentFigure = getParent(); + if (parentFigure instanceof BranchFigure) { + CalloutBranchConnections parentCC = (CalloutBranchConnections) ((BranchFigure) parentFigure) + .getCalloutConnections(); + IDecoration calloutConnection = parentCC + .getDecoration(this); + if (calloutConnection != null) + calloutConnection.paint(parentFigure, graphics); + + } + if (this.calloutConnections != null) { + this.calloutConnections.paint(this, graphics); + } + } + // determine clipping areas for child + IClippingStrategy clippingStrategy = getClippingStrategy(); + Rectangle[] clipping = null; + if (clippingStrategy != null) { + clipping = clippingStrategy.getClip(child); + } else { + // default clipping behaviour is to clip at bounds + clipping = new Rectangle[] { child.getBounds() }; + } + // child may now paint inside the clipping areas + for (int j = 0; j < clipping.length; j++) { + if (clipping[j].intersects( + graphics.getClip(Rectangle.SINGLETON))) { + graphics.clipRect(clipping[j]); + child.paint(graphics); + graphics.restoreState(); + } + } + } + } + } + + private void doPaintFigure(Graphics graphics) { + graphics.setAntialias(SWT.ON); + super.paintFigure(graphics); + } + + protected void paintBorder(Graphics graphics) { + super.paintBorder(graphics); + if (decoration != null && decoration instanceof IBranchDecoration) { + ((IBranchDecoration) decoration).paintAboveChildren(this, graphics); + } + } + + public void paintShadow(Graphics graphics) { + if (connections != null && connections instanceof IShadowedDecoration) { + ((IShadowedDecoration) connections).paintShadow(this, graphics); + } + if (calloutConnections != null + && calloutConnections instanceof IShadowedDecoration) { + ((IShadowedDecoration) calloutConnections).paintShadow(this, + graphics); + } + if (decoration != null && decoration instanceof IShadowedDecoration) { + ((IShadowedDecoration) decoration).paintShadow(this, graphics); + } + } + + public String toString() { + for (Object c : getChildren()) { + if (c instanceof TopicFigure) { + return "BranchFigure(" + c.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + return super.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationFigure.java index fc6870879..e3e974523 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationFigure.java @@ -1,86 +1,86 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Graphics; -import org.xmind.gef.draw2d.DecoratedShapeFigure; -import org.xmind.gef.draw2d.ITransparentableFigure; -import org.xmind.gef.draw2d.graphics.AlphaGraphics; - -public class InformationFigure extends DecoratedShapeFigure implements - ITransparentableFigure { - - private int mainAlpha = 0xff; - - private int subAlpha = 0xff; - - public int getMainAlpha() { - return mainAlpha; - } - - public int getSubAlpha() { - return subAlpha; - } - - public void setMainAlpha(int alpha) { - if (alpha == this.mainAlpha) - return; - this.mainAlpha = alpha; - repaint(); - } - - public void setSubAlpha(int alpha) { - if (alpha == this.subAlpha) - return; - this.subAlpha = alpha; - repaint(); - } - - public void paint(Graphics graphics) { - if (getMainAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getMainAlpha()); - ag.setAlpha(graphics.getAlpha()); - try { - doPaint(ag); - } finally { - ag.dispose(); - } - } else { - doPaint(graphics); - } - } - - private void doPaint(Graphics graphics) { - super.paint(graphics); - } - - protected void paintFigure(Graphics graphics) { - if (getSubAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getSubAlpha()); - try { - doPaintFigure(ag); - } finally { - ag.dispose(); - } - } else { - doPaintFigure(graphics); - } - } - - private void doPaintFigure(Graphics graphics) { - super.paintFigure(graphics); - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Graphics; +import org.xmind.gef.draw2d.DecoratedShapeFigure; +import org.xmind.gef.draw2d.ITransparentableFigure; +import org.xmind.gef.draw2d.graphics.AlphaGraphics; + +public class InformationFigure extends DecoratedShapeFigure implements + ITransparentableFigure { + + private int mainAlpha = 0xff; + + private int subAlpha = 0xff; + + public int getMainAlpha() { + return mainAlpha; + } + + public int getSubAlpha() { + return subAlpha; + } + + public void setMainAlpha(int alpha) { + if (alpha == this.mainAlpha) + return; + this.mainAlpha = alpha; + repaint(); + } + + public void setSubAlpha(int alpha) { + if (alpha == this.subAlpha) + return; + this.subAlpha = alpha; + repaint(); + } + + public void paint(Graphics graphics) { + if (getMainAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getMainAlpha()); + ag.setAlpha(graphics.getAlpha()); + try { + doPaint(ag); + } finally { + ag.dispose(); + } + } else { + doPaint(graphics); + } + } + + private void doPaint(Graphics graphics) { + super.paint(graphics); + } + + protected void paintFigure(Graphics graphics) { + if (getSubAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getSubAlpha()); + try { + doPaintFigure(ag); + } finally { + ag.dispose(); + } + } else { + doPaintFigure(graphics); + } + } + + private void doPaintFigure(Graphics graphics) { + super.paintFigure(graphics); + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationItemFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationItemFigure.java index 0bd4d1e09..a32649826 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationItemFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/InformationItemFigure.java @@ -1,153 +1,153 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.TextStyle; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.draw2d.SizeableImageFigure; - -public class InformationItemFigure extends Figure implements ITitledFigure { - - private static final int SPACING = 7; - - private SizeableImageFigure icon; - - private ITextFigure caption; - - private Dimension cachedPrefSize = null; - - public InformationItemFigure(int textRenderStyle) { - this.icon = new SizeableImageFigure(); - this.icon.setConstrained(true); - this.caption = new RotatableWrapLabel(textRenderStyle); - add(this.icon); - add(this.caption); - } - - public ITextFigure getTitle() { - return caption; - } - - public void setTitle(ITextFigure title) { - } - - public SizeableImageFigure getIcon() { - return icon; - } - - public ITextFigure getCaption() { - return caption; - } - - public Dimension getPreferredSize(int wHint, int hHint) { - if (prefSize != null) - return prefSize; - - if (cachedPrefSize != null) - return cachedPrefSize; - - Dimension s1 = icon.getPreferredSize(); - Dimension s2 = caption.getPreferredSize(); - cachedPrefSize = new Dimension(s1.width + SPACING + s2.width, Math.max( - s1.height, s2.height)); - return cachedPrefSize; - } - - public void invalidate() { - super.invalidate(); - cachedPrefSize = null; - } - - protected void layout() { - Rectangle r = getBounds(); - Dimension s1 = icon.getPreferredSize(); - Dimension s2 = caption.getPreferredSize(); - icon.setBounds(new Rectangle(r.x, r.y + (r.height - s1.height) / 2, - s1.width, s1.height)); - caption.setBounds(new Rectangle(r.x + s1.width + SPACING, r.y - + (r.height - s2.height) / 2, s2.width, s2.height)); - } - - public int getLineSpacing() { - return caption.getLineSpacing(); - } - - public TextStyle getStyle() { - return caption.getStyle(); - } - - public String getText() { - return caption.getText(); - } - - public int getTextAlignment() { - return caption.getTextAlignment(); - } - - public int getTextRenderStyle() { - return ((RotatableWrapLabel) caption).getRenderStyle(); - } - - public void setLineSpacing(int spacing) { - caption.setLineSpacing(spacing); - } - - public void setStyle(TextStyle style) { - caption.setStyle(style); - } - - public void setText(String text) { - caption.setText(text); - } - - public void setTextAlignment(int align) { - caption.setTextAlignment(align); - } - - public void setTextRenderStyle(int textRenderStyle) { - ((RotatableWrapLabel) caption).setRenderStyle(textRenderStyle); - } - - public Image getIconImage() { - return icon.getImage(); - } - - public void setIconImage(Image image) { - icon.setImage(image); - } - - public void setFont(Font f) { - super.setFont(f); - caption.setFont(f); - } - - public void setForegroundColor(Color fg) { - super.setForegroundColor(fg); - caption.setForegroundColor(fg); - } - - public void setBackgroundColor(Color bg) { - super.setBackgroundColor(bg); - caption.setBackgroundColor(bg); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.TextStyle; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.draw2d.SizeableImageFigure; + +public class InformationItemFigure extends Figure implements ITitledFigure { + + private static final int SPACING = 7; + + private SizeableImageFigure icon; + + private ITextFigure caption; + + private Dimension cachedPrefSize = null; + + public InformationItemFigure(int textRenderStyle) { + this.icon = new SizeableImageFigure(); + this.icon.setConstrained(true); + this.caption = new RotatableWrapLabel(textRenderStyle); + add(this.icon); + add(this.caption); + } + + public ITextFigure getTitle() { + return caption; + } + + public void setTitle(ITextFigure title) { + } + + public SizeableImageFigure getIcon() { + return icon; + } + + public ITextFigure getCaption() { + return caption; + } + + public Dimension getPreferredSize(int wHint, int hHint) { + if (prefSize != null) + return prefSize; + + if (cachedPrefSize != null) + return cachedPrefSize; + + Dimension s1 = icon.getPreferredSize(); + Dimension s2 = caption.getPreferredSize(); + cachedPrefSize = new Dimension(s1.width + SPACING + s2.width, Math.max( + s1.height, s2.height)); + return cachedPrefSize; + } + + public void invalidate() { + super.invalidate(); + cachedPrefSize = null; + } + + protected void layout() { + Rectangle r = getBounds(); + Dimension s1 = icon.getPreferredSize(); + Dimension s2 = caption.getPreferredSize(); + icon.setBounds(new Rectangle(r.x, r.y + (r.height - s1.height) / 2, + s1.width, s1.height)); + caption.setBounds(new Rectangle(r.x + s1.width + SPACING, r.y + + (r.height - s2.height) / 2, s2.width, s2.height)); + } + + public int getLineSpacing() { + return caption.getLineSpacing(); + } + + public TextStyle getStyle() { + return caption.getStyle(); + } + + public String getText() { + return caption.getText(); + } + + public int getTextAlignment() { + return caption.getTextAlignment(); + } + + public int getTextRenderStyle() { + return ((RotatableWrapLabel) caption).getRenderStyle(); + } + + public void setLineSpacing(int spacing) { + caption.setLineSpacing(spacing); + } + + public void setStyle(TextStyle style) { + caption.setStyle(style); + } + + public void setText(String text) { + caption.setText(text); + } + + public void setTextAlignment(int align) { + caption.setTextAlignment(align); + } + + public void setTextRenderStyle(int textRenderStyle) { + ((RotatableWrapLabel) caption).setRenderStyle(textRenderStyle); + } + + public Image getIconImage() { + return icon.getImage(); + } + + public void setIconImage(Image image) { + icon.setImage(image); + } + + public void setFont(Font f) { + super.setFont(f); + caption.setFont(f); + } + + public void setForegroundColor(Color fg) { + super.setForegroundColor(fg); + caption.setForegroundColor(fg); + } + + public void setBackgroundColor(Color bg) { + super.setBackgroundColor(bg); + caption.setBackgroundColor(bg); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendItemFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendItemFigure.java index 2a7b71606..c77783677 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendItemFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendItemFigure.java @@ -1,175 +1,175 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.TextStyle; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.ReferencedFigure; -import org.xmind.gef.draw2d.RotatableWrapLabel; -import org.xmind.gef.draw2d.SizeableImageFigure; -import org.xmind.ui.internal.svgsupport.SVGImageData; -import org.xmind.ui.internal.svgsupport.SVGImageFigure; - -public class LegendItemFigure extends Figure implements ITitledFigure { - - private static final int SPACING = 7; - - private SizeableImageFigure icon = null; - - private SVGImageFigure svgIcon = null; - - private ITextFigure caption; - - private Dimension cachedPrefSize = null; - - public LegendItemFigure(int textRenderStyle, - LocalResourceManager resourceManager) { - if (resourceManager != null) { - svgIcon = new SVGImageFigure(); - svgIcon.setManager(resourceManager); - svgIcon.setConstrained(true); - add(svgIcon); - } else { - icon = new SizeableImageFigure(); - icon.setConstrained(true); - add(icon); - } - caption = new RotatableWrapLabel(textRenderStyle); - add(caption); - } - - public ITextFigure getTitle() { - return caption; - } - - public void setTitle(ITextFigure title) { - } - - public ReferencedFigure getIcon() { - return svgIcon != null ? svgIcon : icon; - } - - public ITextFigure getCaption() { - return caption; - } - - public Dimension getPreferredSize(int wHint, int hHint) { - if (prefSize != null) - return prefSize; - - if (cachedPrefSize != null) - return cachedPrefSize; - - Dimension s1 = svgIcon != null ? svgIcon.getPreferredSize() - : icon.getPreferredSize(); - Dimension s2 = caption.getPreferredSize(); - cachedPrefSize = new Dimension(s1.width + SPACING + s2.width, - Math.max(s1.height, s2.height)); - return cachedPrefSize; - } - - public void invalidate() { - super.invalidate(); - cachedPrefSize = null; - } - - protected void layout() { - Rectangle r = getBounds(); - Dimension s1 = svgIcon != null ? svgIcon.getPreferredSize() - : icon.getPreferredSize(); - Dimension s2 = caption.getPreferredSize(); - if (svgIcon != null) - svgIcon.setBounds(new Rectangle(r.x, - r.y + (r.height - s1.height) / 2, s1.width, s1.height)); - else - icon.setBounds(new Rectangle(r.x, r.y + (r.height - s1.height) / 2, - s1.width, s1.height)); - caption.setBounds(new Rectangle(r.x + s1.width + SPACING, - r.y + (r.height - s2.height) / 2, s2.width, s2.height)); - } - - public int getLineSpacing() { - return caption.getLineSpacing(); - } - - public TextStyle getStyle() { - return caption.getStyle(); - } - - public String getText() { - return caption.getText(); - } - - public int getTextAlignment() { - return caption.getTextAlignment(); - } - - public int getTextRenderStyle() { - return ((RotatableWrapLabel) caption).getRenderStyle(); - } - - public void setLineSpacing(int spacing) { - caption.setLineSpacing(spacing); - } - - public void setStyle(TextStyle style) { - caption.setStyle(style); - } - - public void setText(String text) { - caption.setText(text); - } - - public void setTextAlignment(int align) { - caption.setTextAlignment(align); - } - - public void setTextRenderStyle(int textRenderStyle) { - ((RotatableWrapLabel) caption).setRenderStyle(textRenderStyle); - } - - public void setIconImage(Image image) { - if (icon != null) - icon.setImage(image); - } - - public void setSVGData(SVGImageData svgImageData) { - if (svgIcon != null) - svgIcon.setSVGData(svgImageData); - } - - public void setFont(Font f) { - super.setFont(f); - caption.setFont(f); - } - - public void setForegroundColor(Color fg) { - super.setForegroundColor(fg); - caption.setForegroundColor(fg); - } - - public void setBackgroundColor(Color bg) { - super.setBackgroundColor(bg); - caption.setBackgroundColor(bg); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.TextStyle; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.ReferencedFigure; +import org.xmind.gef.draw2d.RotatableWrapLabel; +import org.xmind.gef.draw2d.SizeableImageFigure; +import org.xmind.ui.internal.svgsupport.SVGImageData; +import org.xmind.ui.internal.svgsupport.SVGImageFigure; + +public class LegendItemFigure extends Figure implements ITitledFigure { + + private static final int SPACING = 7; + + private SizeableImageFigure icon = null; + + private SVGImageFigure svgIcon = null; + + private ITextFigure caption; + + private Dimension cachedPrefSize = null; + + public LegendItemFigure(int textRenderStyle, + LocalResourceManager resourceManager) { + if (resourceManager != null) { + svgIcon = new SVGImageFigure(); + svgIcon.setManager(resourceManager); + svgIcon.setConstrained(true); + add(svgIcon); + } else { + icon = new SizeableImageFigure(); + icon.setConstrained(true); + add(icon); + } + caption = new RotatableWrapLabel(textRenderStyle); + add(caption); + } + + public ITextFigure getTitle() { + return caption; + } + + public void setTitle(ITextFigure title) { + } + + public ReferencedFigure getIcon() { + return svgIcon != null ? svgIcon : icon; + } + + public ITextFigure getCaption() { + return caption; + } + + public Dimension getPreferredSize(int wHint, int hHint) { + if (prefSize != null) + return prefSize; + + if (cachedPrefSize != null) + return cachedPrefSize; + + Dimension s1 = svgIcon != null ? svgIcon.getPreferredSize() + : icon.getPreferredSize(); + Dimension s2 = caption.getPreferredSize(); + cachedPrefSize = new Dimension(s1.width + SPACING + s2.width, + Math.max(s1.height, s2.height)); + return cachedPrefSize; + } + + public void invalidate() { + super.invalidate(); + cachedPrefSize = null; + } + + protected void layout() { + Rectangle r = getBounds(); + Dimension s1 = svgIcon != null ? svgIcon.getPreferredSize() + : icon.getPreferredSize(); + Dimension s2 = caption.getPreferredSize(); + if (svgIcon != null) + svgIcon.setBounds(new Rectangle(r.x, + r.y + (r.height - s1.height) / 2, s1.width, s1.height)); + else + icon.setBounds(new Rectangle(r.x, r.y + (r.height - s1.height) / 2, + s1.width, s1.height)); + caption.setBounds(new Rectangle(r.x + s1.width + SPACING, + r.y + (r.height - s2.height) / 2, s2.width, s2.height)); + } + + public int getLineSpacing() { + return caption.getLineSpacing(); + } + + public TextStyle getStyle() { + return caption.getStyle(); + } + + public String getText() { + return caption.getText(); + } + + public int getTextAlignment() { + return caption.getTextAlignment(); + } + + public int getTextRenderStyle() { + return ((RotatableWrapLabel) caption).getRenderStyle(); + } + + public void setLineSpacing(int spacing) { + caption.setLineSpacing(spacing); + } + + public void setStyle(TextStyle style) { + caption.setStyle(style); + } + + public void setText(String text) { + caption.setText(text); + } + + public void setTextAlignment(int align) { + caption.setTextAlignment(align); + } + + public void setTextRenderStyle(int textRenderStyle) { + ((RotatableWrapLabel) caption).setRenderStyle(textRenderStyle); + } + + public void setIconImage(Image image) { + if (icon != null) + icon.setImage(image); + } + + public void setSVGData(SVGImageData svgImageData) { + if (svgIcon != null) + svgIcon.setSVGData(svgImageData); + } + + public void setFont(Font f) { + super.setFont(f); + caption.setFont(f); + } + + public void setForegroundColor(Color fg) { + super.setForegroundColor(fg); + caption.setForegroundColor(fg); + } + + public void setBackgroundColor(Color bg) { + super.setBackgroundColor(bg); + caption.setBackgroundColor(bg); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendSeparatorFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendSeparatorFigure.java index 884148d32..0792ebc28 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendSeparatorFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/LegendSeparatorFigure.java @@ -1,45 +1,45 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.swt.SWT; -import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.style.Styles; - -public class LegendSeparatorFigure extends Figure { - - public LegendSeparatorFigure() { - setForegroundColor(ColorUtils.getColor(Styles.LEGEND_LINE_COLOR)); - } - - public Dimension getPreferredSize(int wHint, int hHint) { - if (wHint < 0) - wHint = 20; - return new Dimension(wHint, 3); - } - - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - graphics.setAntialias(SWT.ON); - Rectangle r = getBounds(); - int y = r.y + r.height / 2; - graphics.setAlpha(0xc0); - graphics.drawLine(r.x, y, r.x + r.width, y); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.style.Styles; + +public class LegendSeparatorFigure extends Figure { + + public LegendSeparatorFigure() { + setForegroundColor(ColorUtils.getColor(Styles.LEGEND_LINE_COLOR)); + } + + public Dimension getPreferredSize(int wHint, int hHint) { + if (wHint < 0) + wHint = 20; + return new Dimension(wHint, 3); + } + + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + graphics.setAntialias(SWT.ON); + Rectangle r = getBounds(); + int y = r.y + r.height / 2; + graphics.setAlpha(0xc0); + graphics.drawLine(r.x, y, r.x + r.width, y); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/RelationshipFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/RelationshipFigure.java index 242d7a507..4966298be 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/RelationshipFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/RelationshipFigure.java @@ -1,121 +1,121 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.xmind.gef.draw2d.DecoratedConnectionFigure; -import org.xmind.gef.draw2d.IReferencedFigure; -import org.xmind.gef.draw2d.IShadowedFigure; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.geometry.PrecisionPoint; -import org.xmind.ui.decorations.IRelationshipDecoration; - -public class RelationshipFigure extends DecoratedConnectionFigure implements - ITitledFigure, IShadowedFigure { - - private ITextFigure title = null; - - private boolean titleVisible = false; - - public ITextFigure getTitle() { - return title; - } - - public void setTitle(ITextFigure title) { - if (title == this.title) - return; - - this.title = title; - revalidate(); - repaint(); - } - - public boolean isTitleVisible() { - return titleVisible; - } - - public void setTitleVisible(boolean titleVisible) { - if (titleVisible == this.titleVisible) - return; - - this.titleVisible = titleVisible; - revalidate(); - repaint(); - } - - protected void layout() { - super.layout(); - if (title != null) { - PrecisionPoint pos = getDecoration().getTitlePosition(this); - Rectangle r2; - if (title instanceof IReferencedFigure) { - r2 = ((IReferencedFigure) title).getPreferredBounds(pos - .toDraw2DPoint()); - } else { - Dimension size = title.getPreferredSize(); - r2 = Rectangle.SINGLETON; - r2.setSize(size); - r2.setLocation((int) (pos.x - size.width / 2.0), - (int) (pos.y - size.height / 2.0)); - } - title.setBounds(r2); - } - } - - public Rectangle getPreferredBounds() { - Rectangle r = super.getPreferredBounds(); - if (title != null) { - PrecisionPoint pos = getDecoration().getTitlePosition(this); - Rectangle r2; - if (title instanceof IReferencedFigure) { - r2 = ((IReferencedFigure) title).getPreferredBounds(pos - .toDraw2DPoint()); - } else { - Dimension size = title.getPreferredSize(); - r2 = Rectangle.SINGLETON; - r2.setSize(size); - r2.setLocation((int) (pos.x - size.width / 2.0), - (int) (pos.y - size.height / 2.0)); - } - r.union(r2); - } - return r; - } - - public IRelationshipDecoration getDecoration() { - return (IRelationshipDecoration) super.getDecoration(); - } - - public boolean isShadowShowing() { - return isShowing(); - } - - public void paintShadow(Graphics graphics) { - if (getDecoration() != null - && getDecoration() instanceof IShadowedDecoration) { - ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); - } - } - - public String toString() { - if (title != null) - return title.getText(); - return super.toString(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; +import org.xmind.gef.draw2d.DecoratedConnectionFigure; +import org.xmind.gef.draw2d.IReferencedFigure; +import org.xmind.gef.draw2d.IShadowedFigure; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.ui.decorations.IRelationshipDecoration; + +public class RelationshipFigure extends DecoratedConnectionFigure implements + ITitledFigure, IShadowedFigure { + + private ITextFigure title = null; + + private boolean titleVisible = false; + + public ITextFigure getTitle() { + return title; + } + + public void setTitle(ITextFigure title) { + if (title == this.title) + return; + + this.title = title; + revalidate(); + repaint(); + } + + public boolean isTitleVisible() { + return titleVisible; + } + + public void setTitleVisible(boolean titleVisible) { + if (titleVisible == this.titleVisible) + return; + + this.titleVisible = titleVisible; + revalidate(); + repaint(); + } + + protected void layout() { + super.layout(); + if (title != null) { + PrecisionPoint pos = getDecoration().getTitlePosition(this); + Rectangle r2; + if (title instanceof IReferencedFigure) { + r2 = ((IReferencedFigure) title).getPreferredBounds(pos + .toDraw2DPoint()); + } else { + Dimension size = title.getPreferredSize(); + r2 = Rectangle.SINGLETON; + r2.setSize(size); + r2.setLocation((int) (pos.x - size.width / 2.0), + (int) (pos.y - size.height / 2.0)); + } + title.setBounds(r2); + } + } + + public Rectangle getPreferredBounds() { + Rectangle r = super.getPreferredBounds(); + if (title != null) { + PrecisionPoint pos = getDecoration().getTitlePosition(this); + Rectangle r2; + if (title instanceof IReferencedFigure) { + r2 = ((IReferencedFigure) title).getPreferredBounds(pos + .toDraw2DPoint()); + } else { + Dimension size = title.getPreferredSize(); + r2 = Rectangle.SINGLETON; + r2.setSize(size); + r2.setLocation((int) (pos.x - size.width / 2.0), + (int) (pos.y - size.height / 2.0)); + } + r.union(r2); + } + return r; + } + + public IRelationshipDecoration getDecoration() { + return (IRelationshipDecoration) super.getDecoration(); + } + + public boolean isShadowShowing() { + return isShowing(); + } + + public void paintShadow(Graphics graphics) { + if (getDecoration() != null + && getDecoration() instanceof IShadowedDecoration) { + ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); + } + } + + public String toString() { + if (title != null) + return title.getText(); + return super.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/SheetFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/SheetFigure.java index 42dad2bdb..95aa204fc 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/SheetFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/SheetFigure.java @@ -1,20 +1,20 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.xmind.gef.draw2d.ReferencedLayer; - -public class SheetFigure extends ReferencedLayer { - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.xmind.gef.draw2d.ReferencedLayer; + +public class SheetFigure extends ReferencedLayer { + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/TopicFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/TopicFigure.java index f7f1ca7d8..c51928183 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/TopicFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/figures/TopicFigure.java @@ -1,285 +1,285 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.figures; - -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.LayoutManager; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Point; -import org.eclipse.swt.SWT; -import org.xmind.gef.draw2d.DecoratedShapeFigure; -import org.xmind.gef.draw2d.IMinimizable; -import org.xmind.gef.draw2d.IReferenceDescriptor; -import org.xmind.gef.draw2d.IRelayerableFigure; -import org.xmind.gef.draw2d.IRotatable; -import org.xmind.gef.draw2d.IRotatableReferenceDescriptor; -import org.xmind.gef.draw2d.IRotatableReferencedFigure; -import org.xmind.gef.draw2d.IRotatableReferencedLayout; -import org.xmind.gef.draw2d.IShadowedFigure; -import org.xmind.gef.draw2d.ITextFigure; -import org.xmind.gef.draw2d.ITitledFigure; -import org.xmind.gef.draw2d.ITransparentableFigure; -import org.xmind.gef.draw2d.decoration.IShadowedDecoration; -import org.xmind.gef.draw2d.geometry.PrecisionDimension; -import org.xmind.gef.draw2d.geometry.PrecisionInsets; -import org.xmind.gef.draw2d.geometry.PrecisionRectangle; -import org.xmind.gef.draw2d.geometry.PrecisionRotator; -import org.xmind.gef.draw2d.graphics.AlphaGraphics; -import org.xmind.gef.draw2d.graphics.GrayedGraphics; -import org.xmind.ui.decorations.ITopicDecoration; - -public class TopicFigure extends DecoratedShapeFigure - implements ITitledFigure, IMinimizable, IShadowedFigure, - IRotatableReferencedFigure, IRelayerableFigure, ITransparentableFigure { - - protected static final int FLAG_MINIMIZED = MAX_FLAG << 1; - protected static final int FLAG_RELAYERED = MAX_FLAG << 2; - - static { - MAX_FLAG = FLAG_RELAYERED; - } - - private ITextFigure title = null; - - private PrecisionRotator rotator = null; - - private int selfAlpha = 0xff; - private int treeAlpha = 0xff; - - public ITextFigure getTitle() { - return title; - } - - public void setTitle(ITextFigure title) { - if (title == this.title) - return; - - this.title = title; - revalidate(); - repaint(); - } - - protected PrecisionRotator r() { - if (rotator == null) - rotator = new PrecisionRotator(); - return rotator; - } - - public ITopicDecoration getDecoration() { - return (ITopicDecoration) super.getDecoration(); - } - - protected Insets calculatePreferredInsets() { - if (isMinimized()) - return NO_INSETS; - return super.calculatePreferredInsets(); - } - - public boolean isMinimized() { - return getFlag(FLAG_MINIMIZED); - } - - public void setMinimized(boolean minimized) { - if (minimized == isMinimized()) - return; - - setFlag(FLAG_MINIMIZED, minimized); - revalidate(); - repaint(); - } - - public boolean isShadowShowing() { - IFigure p = getParent(); - while (p != null) { - if (p instanceof IShadowedFigure - && !((IShadowedFigure) p).isShadowShowing()) - return false; - p = p.getParent(); - } - return isShowing(); - } - - public void paintShadow(Graphics graphics) { - if (getDecoration() != null - && getDecoration() instanceof IShadowedDecoration) { - ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); - } - } - - public String toString() { - if (title != null) - return "TopicFigure(" + title.getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - return super.toString(); - } - - public PrecisionRectangle getNormalPreferredBounds(Point reference) { - PrecisionInsets ins = getNormalReferenceDescription(); - return new PrecisionRectangle(reference.x - ins.left, - reference.y - ins.top, ins.getWidth(), ins.getHeight()); - } - - public PrecisionInsets getNormalReferenceDescription() { - if (getReferenceDescriptor() instanceof IRotatableReferenceDescriptor) { - return ((IRotatableReferenceDescriptor) getReferenceDescriptor()) - .getNormalReferenceDescription(this); - } - return new PrecisionInsets(getReferenceDescription()); - } - - public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { - if (getLayoutManager() instanceof IRotatableReferencedLayout) { - return ((IRotatableReferencedLayout) getLayoutManager()) - .getNormalPreferredSize(this, wHint, hHint); - } - return new PrecisionDimension(getPreferredSize(wHint, hHint)); - } - - public double getRotationDegrees() { - return r().getAngle(); - } - - public void setRotationDegrees(double degrees) { - double oldAngle = getRotationDegrees(); - r().setAngle(degrees); - if (getBorder() instanceof IRotatable) { - ((IRotatable) getBorder()).setRotationDegrees(degrees); - } - if (getLayoutManager() instanceof IRotatable) { - ((IRotatable) getLayoutManager()).setRotationDegrees(degrees); - } - if (getReferenceDescriptor() instanceof IRotatable) { - ((IRotatable) getReferenceDescriptor()).setRotationDegrees(degrees); - } - for (Object child : getChildren()) { - if (child instanceof IRotatable) { - ((IRotatable) child).setRotationDegrees(degrees); - } - } - if (degrees != oldAngle) { - revalidate(); - repaint(); - } - } - - public void add(IFigure figure, Object constraint, int index) { - super.add(figure, constraint, index); - if (figure instanceof IRotatable) { - ((IRotatable) figure).setRotationDegrees(getRotationDegrees()); - } - } - - public void setLayoutManager(LayoutManager manager) { - super.setLayoutManager(manager); - if (manager instanceof IRotatable) { - ((IRotatable) manager).setRotationDegrees(getRotationDegrees()); - } - } - - public void setReferenceDescriptor(IReferenceDescriptor descriptor) { - super.setReferenceDescriptor(descriptor); - if (descriptor instanceof IRotatable) { - ((IRotatable) descriptor).setRotationDegrees(getRotationDegrees()); - } - } - - public boolean isRelayered() { - return getFlag(FLAG_RELAYERED); - } - - public void setRelayered(boolean relayered) { - if (relayered == isRelayered()) - return; - - setFlag(FLAG_RELAYERED, relayered); - repaint(); - } - - public void paintRelayered(Graphics graphics) { - super.paint(graphics); - } - - public void paint(Graphics graphics) { - if (isRelayered()) - return; - - if (getMainAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getMainAlpha()); - ag.setAlpha(graphics.getAlpha()); - try { - doPaint(ag); - } finally { - ag.dispose(); - } - } else { - doPaint(graphics); - } - } - - private void doPaint(Graphics graphics) { - if (isEnabled()) { - super.paint(graphics); - } else { - GrayedGraphics gg = new GrayedGraphics(graphics); - try { - super.paint(gg); - } finally { - gg.dispose(); - } - } - } - - protected void paintFigure(Graphics graphics) { - if (getSubAlpha() < 0xff) { - AlphaGraphics ag = new AlphaGraphics(graphics); - ag.setMainAlpha(getSubAlpha()); - try { - doPaintFigure(ag); - } finally { - ag.dispose(); - } - } else { - doPaintFigure(graphics); - } - } - - private void doPaintFigure(Graphics graphics) { - graphics.setAntialias(SWT.ON); - super.paintFigure(graphics); - } - - public int getMainAlpha() { - return treeAlpha; - } - - public int getSubAlpha() { - return selfAlpha; - } - - public void setMainAlpha(int alpha) { - if (alpha == this.treeAlpha) - return; - this.treeAlpha = alpha; - repaint(); - } - - public void setSubAlpha(int alpha) { - if (alpha == this.selfAlpha) - return; - this.selfAlpha = alpha; - repaint(); - } - +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.figures; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutManager; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.swt.SWT; +import org.xmind.gef.draw2d.DecoratedShapeFigure; +import org.xmind.gef.draw2d.IMinimizable; +import org.xmind.gef.draw2d.IReferenceDescriptor; +import org.xmind.gef.draw2d.IRelayerableFigure; +import org.xmind.gef.draw2d.IRotatable; +import org.xmind.gef.draw2d.IRotatableReferenceDescriptor; +import org.xmind.gef.draw2d.IRotatableReferencedFigure; +import org.xmind.gef.draw2d.IRotatableReferencedLayout; +import org.xmind.gef.draw2d.IShadowedFigure; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.ITitledFigure; +import org.xmind.gef.draw2d.ITransparentableFigure; +import org.xmind.gef.draw2d.decoration.IShadowedDecoration; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionInsets; +import org.xmind.gef.draw2d.geometry.PrecisionRectangle; +import org.xmind.gef.draw2d.geometry.PrecisionRotator; +import org.xmind.gef.draw2d.graphics.AlphaGraphics; +import org.xmind.gef.draw2d.graphics.GrayedGraphics; +import org.xmind.ui.decorations.ITopicDecoration; + +public class TopicFigure extends DecoratedShapeFigure + implements ITitledFigure, IMinimizable, IShadowedFigure, + IRotatableReferencedFigure, IRelayerableFigure, ITransparentableFigure { + + protected static final int FLAG_MINIMIZED = MAX_FLAG << 1; + protected static final int FLAG_RELAYERED = MAX_FLAG << 2; + + static { + MAX_FLAG = FLAG_RELAYERED; + } + + private ITextFigure title = null; + + private PrecisionRotator rotator = null; + + private int selfAlpha = 0xff; + private int treeAlpha = 0xff; + + public ITextFigure getTitle() { + return title; + } + + public void setTitle(ITextFigure title) { + if (title == this.title) + return; + + this.title = title; + revalidate(); + repaint(); + } + + protected PrecisionRotator r() { + if (rotator == null) + rotator = new PrecisionRotator(); + return rotator; + } + + public ITopicDecoration getDecoration() { + return (ITopicDecoration) super.getDecoration(); + } + + protected Insets calculatePreferredInsets() { + if (isMinimized()) + return NO_INSETS; + return super.calculatePreferredInsets(); + } + + public boolean isMinimized() { + return getFlag(FLAG_MINIMIZED); + } + + public void setMinimized(boolean minimized) { + if (minimized == isMinimized()) + return; + + setFlag(FLAG_MINIMIZED, minimized); + revalidate(); + repaint(); + } + + public boolean isShadowShowing() { + IFigure p = getParent(); + while (p != null) { + if (p instanceof IShadowedFigure + && !((IShadowedFigure) p).isShadowShowing()) + return false; + p = p.getParent(); + } + return isShowing(); + } + + public void paintShadow(Graphics graphics) { + if (getDecoration() != null + && getDecoration() instanceof IShadowedDecoration) { + ((IShadowedDecoration) getDecoration()).paintShadow(this, graphics); + } + } + + public String toString() { + if (title != null) + return "TopicFigure(" + title.getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + return super.toString(); + } + + public PrecisionRectangle getNormalPreferredBounds(Point reference) { + PrecisionInsets ins = getNormalReferenceDescription(); + return new PrecisionRectangle(reference.x - ins.left, + reference.y - ins.top, ins.getWidth(), ins.getHeight()); + } + + public PrecisionInsets getNormalReferenceDescription() { + if (getReferenceDescriptor() instanceof IRotatableReferenceDescriptor) { + return ((IRotatableReferenceDescriptor) getReferenceDescriptor()) + .getNormalReferenceDescription(this); + } + return new PrecisionInsets(getReferenceDescription()); + } + + public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) { + if (getLayoutManager() instanceof IRotatableReferencedLayout) { + return ((IRotatableReferencedLayout) getLayoutManager()) + .getNormalPreferredSize(this, wHint, hHint); + } + return new PrecisionDimension(getPreferredSize(wHint, hHint)); + } + + public double getRotationDegrees() { + return r().getAngle(); + } + + public void setRotationDegrees(double degrees) { + double oldAngle = getRotationDegrees(); + r().setAngle(degrees); + if (getBorder() instanceof IRotatable) { + ((IRotatable) getBorder()).setRotationDegrees(degrees); + } + if (getLayoutManager() instanceof IRotatable) { + ((IRotatable) getLayoutManager()).setRotationDegrees(degrees); + } + if (getReferenceDescriptor() instanceof IRotatable) { + ((IRotatable) getReferenceDescriptor()).setRotationDegrees(degrees); + } + for (Object child : getChildren()) { + if (child instanceof IRotatable) { + ((IRotatable) child).setRotationDegrees(degrees); + } + } + if (degrees != oldAngle) { + revalidate(); + repaint(); + } + } + + public void add(IFigure figure, Object constraint, int index) { + super.add(figure, constraint, index); + if (figure instanceof IRotatable) { + ((IRotatable) figure).setRotationDegrees(getRotationDegrees()); + } + } + + public void setLayoutManager(LayoutManager manager) { + super.setLayoutManager(manager); + if (manager instanceof IRotatable) { + ((IRotatable) manager).setRotationDegrees(getRotationDegrees()); + } + } + + public void setReferenceDescriptor(IReferenceDescriptor descriptor) { + super.setReferenceDescriptor(descriptor); + if (descriptor instanceof IRotatable) { + ((IRotatable) descriptor).setRotationDegrees(getRotationDegrees()); + } + } + + public boolean isRelayered() { + return getFlag(FLAG_RELAYERED); + } + + public void setRelayered(boolean relayered) { + if (relayered == isRelayered()) + return; + + setFlag(FLAG_RELAYERED, relayered); + repaint(); + } + + public void paintRelayered(Graphics graphics) { + super.paint(graphics); + } + + public void paint(Graphics graphics) { + if (isRelayered()) + return; + + if (getMainAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getMainAlpha()); + ag.setAlpha(graphics.getAlpha()); + try { + doPaint(ag); + } finally { + ag.dispose(); + } + } else { + doPaint(graphics); + } + } + + private void doPaint(Graphics graphics) { + if (isEnabled()) { + super.paint(graphics); + } else { + GrayedGraphics gg = new GrayedGraphics(graphics); + try { + super.paint(gg); + } finally { + gg.dispose(); + } + } + } + + protected void paintFigure(Graphics graphics) { + if (getSubAlpha() < 0xff) { + AlphaGraphics ag = new AlphaGraphics(graphics); + ag.setMainAlpha(getSubAlpha()); + try { + doPaintFigure(ag); + } finally { + ag.dispose(); + } + } else { + doPaintFigure(graphics); + } + } + + private void doPaintFigure(Graphics graphics) { + graphics.setAntialias(SWT.ON); + super.paintFigure(graphics); + } + + public int getMainAlpha() { + return treeAlpha; + } + + public int getSubAlpha() { + return selfAlpha; + } + + public void setMainAlpha(int alpha) { + if (alpha == this.treeAlpha) + return; + this.treeAlpha = alpha; + repaint(); + } + + public void setSubAlpha(int alpha) { + if (alpha == this.selfAlpha) + return; + this.selfAlpha = alpha; + repaint(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/AbstractFindReplaceOperationProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/AbstractFindReplaceOperationProvider.java index 378642473..535a7e50e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/AbstractFindReplaceOperationProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/AbstractFindReplaceOperationProvider.java @@ -1,187 +1,187 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.findreplace; - -import org.eclipse.swt.graphics.Font; -import org.xmind.gef.draw2d.graphics.GraphicsUtils; - -/** - * @author Frank Shaka - */ -public abstract class AbstractFindReplaceOperationProvider implements - IFindReplaceOperationProvider { - - private int parameter = 0; - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#find(java.lang.String) - */ - public boolean find(String toFind) { - return isAll() ? findAll(toFind) : findNext(toFind); - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#replace(java.lang.String, - * java.lang.String) - */ - public boolean replace(String toFind, String toReplaceWith) { - return isAll() ? replaceAll(toFind, toReplaceWith) : replaceNext( - toFind, toReplaceWith); - } - - protected abstract boolean findAll(String toFind); - - protected abstract boolean findNext(String toFind); - - protected abstract boolean replaceAll(String toFind, String toReplaceWith); - - protected abstract boolean replaceNext(String toFind, String toReplaceWith); - - /** - * @param text - * @param toFind - * @param offset - * @return - */ - protected int indexOf(String text, String toFind, int offset) { - if (text == null) - return -1; - if (!isCaseSensitive()) { - text = text.toLowerCase(); - toFind = toFind.toLowerCase(); - } - int index = isForward() ? text.indexOf(toFind, offset) : text - .lastIndexOf(toFind, offset - toFind.length()); - if (index >= 0 && isWholeWord() - && !isWholeWord(text, index, toFind.length())) { - index = -1; - } - return index; - } - - /** - * @param toFind - * @param selectionText - * @return - */ - protected boolean equals(String toFind, String selectionText) { - return isCaseSensitive() ? toFind.equals(selectionText) : toFind - .equalsIgnoreCase(selectionText); - } - - /** - * @param text - * @return - */ - protected int getNewOffset(String text) { - return isForward() ? 0 : text.length() + 1; - } - - protected boolean isIndexPermitted(int newIndex, int startIndex) { - return isForward() ? newIndex < startIndex : newIndex > startIndex; - } - - protected boolean isWholeWord(String text, int start, int length) { - char pre = start == 0 ? ' ' : text.charAt(start - 1); - char post = start == text.length() - length ? ' ' : text.charAt(start - + length); - return pre == ' ' && post == ' '; - } - - protected boolean isAll() { - return (getParameter() & PARAM_ALL) != 0; - } - - protected boolean isForward() { - return (getParameter() & PARAM_FORWARD) != 0; - } - - protected boolean isCaseSensitive() { - return (getParameter() & PARAM_CASE_SENSITIVE) != 0; - } - - protected boolean isWholeWord() { - return (getParameter() & PARAM_WHOLE_WORD) != 0; - } - - protected boolean isWorkbook() { - return (getParameter() & PARAM_WORKBOOK) != 0; - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canFindAll(java.lang.String) - */ - public boolean canFindAll(String toFind) { - return canFind(toFind) && !isWorkbook(); - } - - /** - * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canReplaceAll(java.lang.String, - * java.lang.String) - */ - public boolean canReplaceAll(String toFind, String toReplaceWith) { - return canReplace(toFind, toReplaceWith) && !isWorkbook(); - } - - public int getParameter() { - return this.parameter; - } - - public void setParameter(int op, boolean value) { - if (value) - this.parameter |= op; - else - this.parameter &= ~op; - } - - public void setParameter(int parameter) { - this.parameter = parameter; - } - - /* - * (non-Javadoc) - * - * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# - * understandsPatameter(int) - */ - public boolean understandsPatameter(int parameter) { - return true; - } - - protected static int computeTextWidth(String text, Font font) { - return GraphicsUtils.getAdvanced().getTextSize(text, font).width; - } - - protected static String constrainText(String text, int maxWidth, Font font) { - if (computeTextWidth(text, font) <= maxWidth) - return text; - - String head = text.substring(0, Math.max(0, text.length() / 2)); - String trail = text.substring(text.length() / 2 + 1); - boolean cutHead = true; - while (head.length() > 0 && trail.length() > 0) { - text = head + "..." + trail; //$NON-NLS-1$ - if (computeTextWidth(text, font) <= maxWidth) - return text; - - if (cutHead) { - head = head.substring(0, head.length() - 1); - } else { - trail = trail.substring(1); - } - cutHead = !cutHead; - } - return text; - } +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. + * + * Contributors: + * XMind Ltd. - initial API and implementation + *******************************************************************************/ +package org.xmind.ui.internal.findreplace; + +import org.eclipse.swt.graphics.Font; +import org.xmind.gef.draw2d.graphics.GraphicsUtils; + +/** + * @author Frank Shaka + */ +public abstract class AbstractFindReplaceOperationProvider implements + IFindReplaceOperationProvider { + + private int parameter = 0; + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#find(java.lang.String) + */ + public boolean find(String toFind) { + return isAll() ? findAll(toFind) : findNext(toFind); + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#replace(java.lang.String, + * java.lang.String) + */ + public boolean replace(String toFind, String toReplaceWith) { + return isAll() ? replaceAll(toFind, toReplaceWith) : replaceNext( + toFind, toReplaceWith); + } + + protected abstract boolean findAll(String toFind); + + protected abstract boolean findNext(String toFind); + + protected abstract boolean replaceAll(String toFind, String toReplaceWith); + + protected abstract boolean replaceNext(String toFind, String toReplaceWith); + + /** + * @param text + * @param toFind + * @param offset + * @return + */ + protected int indexOf(String text, String toFind, int offset) { + if (text == null) + return -1; + if (!isCaseSensitive()) { + text = text.toLowerCase(); + toFind = toFind.toLowerCase(); + } + int index = isForward() ? text.indexOf(toFind, offset) : text + .lastIndexOf(toFind, offset - toFind.length()); + if (index >= 0 && isWholeWord() + && !isWholeWord(text, index, toFind.length())) { + index = -1; + } + return index; + } + + /** + * @param toFind + * @param selectionText + * @return + */ + protected boolean equals(String toFind, String selectionText) { + return isCaseSensitive() ? toFind.equals(selectionText) : toFind + .equalsIgnoreCase(selectionText); + } + + /** + * @param text + * @return + */ + protected int getNewOffset(String text) { + return isForward() ? 0 : text.length() + 1; + } + + protected boolean isIndexPermitted(int newIndex, int startIndex) { + return isForward() ? newIndex < startIndex : newIndex > startIndex; + } + + protected boolean isWholeWord(String text, int start, int length) { + char pre = start == 0 ? ' ' : text.charAt(start - 1); + char post = start == text.length() - length ? ' ' : text.charAt(start + + length); + return pre == ' ' && post == ' '; + } + + protected boolean isAll() { + return (getParameter() & PARAM_ALL) != 0; + } + + protected boolean isForward() { + return (getParameter() & PARAM_FORWARD) != 0; + } + + protected boolean isCaseSensitive() { + return (getParameter() & PARAM_CASE_SENSITIVE) != 0; + } + + protected boolean isWholeWord() { + return (getParameter() & PARAM_WHOLE_WORD) != 0; + } + + protected boolean isWorkbook() { + return (getParameter() & PARAM_WORKBOOK) != 0; + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canFindAll(java.lang.String) + */ + public boolean canFindAll(String toFind) { + return canFind(toFind) && !isWorkbook(); + } + + /** + * @see cn.brainy.ui.mindmap.dialogs.IFindReplaceOperationProvider#canReplaceAll(java.lang.String, + * java.lang.String) + */ + public boolean canReplaceAll(String toFind, String toReplaceWith) { + return canReplace(toFind, toReplaceWith) && !isWorkbook(); + } + + public int getParameter() { + return this.parameter; + } + + public void setParameter(int op, boolean value) { + if (value) + this.parameter |= op; + else + this.parameter &= ~op; + } + + public void setParameter(int parameter) { + this.parameter = parameter; + } + + /* + * (non-Javadoc) + * + * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# + * understandsPatameter(int) + */ + public boolean understandsPatameter(int parameter) { + return true; + } + + protected static int computeTextWidth(String text, Font font) { + return GraphicsUtils.getAdvanced().getTextSize(text, font).width; + } + + protected static String constrainText(String text, int maxWidth, Font font) { + if (computeTextWidth(text, font) <= maxWidth) + return text; + + String head = text.substring(0, Math.max(0, text.length() / 2)); + String trail = text.substring(text.length() / 2 + 1); + boolean cutHead = true; + while (head.length() > 0 && trail.length() > 0) { + text = head + "..." + trail; //$NON-NLS-1$ + if (computeTextWidth(text, font) <= maxWidth) + return text; + + if (cutHead) { + head = head.substring(0, head.length() - 1); + } else { + trail = trail.substring(1); + } + cutHead = !cutHead; + } + return text; + } } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/FindReplaceDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/FindReplaceDialog.java index e6ee25a42..44c95b46e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/FindReplaceDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/findreplace/FindReplaceDialog.java @@ -1,812 +1,812 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation - *******************************************************************************/ -package org.xmind.ui.internal.findreplace; - -import static org.eclipse.jface.dialogs.IDialogConstants.CLIENT_ID; -import static org.eclipse.jface.dialogs.IDialogConstants.CLOSE_ID; -import static org.eclipse.jface.dialogs.IDialogConstants.CLOSE_LABEL; -import static org.eclipse.jface.dialogs.IDialogConstants.HORIZONTAL_SPACING; -import static org.eclipse.jface.dialogs.IDialogConstants.VERTICAL_SPACING; -import static org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider.PARAM_CURRENT_MAP; -import static org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider.PARAM_FORWARD; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.dialogs.DialogMessages; -import org.xmind.ui.resources.FontUtils; - -/** - * @author Frank Shaka - */ -public class FindReplaceDialog extends Dialog implements IPartListener { - - private static final String SETTINGS_SECTION_NAME = "org.xmind.ui.findreplace"; //$NON-NLS-1$ - - private static final String P_PARAMETER = "parameter"; //$NON-NLS-1$ - - private static final String EMPTY = ""; //$NON-NLS-1$ - - private static final String STRING_NOT_FOUND = DialogMessages.FindReplaceDialog_StringNotFound; - - private static Map SINGLETONS = new HashMap(); - - private static final int TEXT_WIDTH = 120; - - private static final int FIND_ID = CLIENT_ID + 1; - private static final int FIND_ALL_ID = CLIENT_ID + 2; - private static final int REPLACE_ID = CLIENT_ID + 3; - private static final int REPLACE_ALL_ID = CLIENT_ID + 4; - - private static List FindHistory = new ArrayList(); - private static List ReplaceHistory = new ArrayList(); - - private class EventHandler implements Listener { - - public void handleEvent(Event event) { - if (event.type == SWT.Modify) { - updateOperationButtons(); - infoLabel.setText(EMPTY); - } else if (event.type == SWT.FocusIn) { - if (event.widget instanceof Combo) { - Combo input = (Combo) event.widget; - input.setSelection(new Point(0, input.getText().length())); - } - } else if (event.type == SWT.Selection) { - Button b = (Button) event.widget; - if (opButtons != null && opButtons.containsValue(b)) { - buttonPressed((Integer) b.getData()); - } else if (paramWidgets != null) { - List